Skip to content

Conversation

@L-u-k-e
Copy link
Collaborator

@L-u-k-e L-u-k-e commented Jan 18, 2026

Summary

There are really three sets of changes in this PR. I'll document them all separately and also try to leave diff comments to call out changes.

PLEASE REVIEW, BUT DO NOT MERGE. I will coordinate the merge after it's approved. Thank you.


1. fix: ID related tool call failures

(and also refactor agent type checks across agent.py)

There is code in agent.py which dynamically determines whether to add memory ID's to the retrieved memories that are injected into the system prompts that are sent to sub agents. For example:

        if (
            self.agent_state.name == "episodic_memory_agent"
            or "episodic" not in retrieved_memories
        ):
             # retrieve memories....
           
             # Use agent_type instead of name to handle both standalone and meta-agent child agents
              from mirix.schemas.agent import AgentType

              if (
                  self.agent_state.agent_type == AgentType.episodic_memory_agent
                  or self.agent_state.agent_type == AgentType.reflexion_agent
              ):
                  episodic_memory += f"[Event ID: {event.id}] Timestamp: {event.occurred_at.strftime('%Y-%m-%d %H:%M:%S')} - {event.summary} (Details: {len(event.details)} Characters)\n"
              else:
                  episodic_memory += f"[{idx}] Timestamp: {event.occurred_at.strftime('%Y-%m-%d %H:%M:%S')} - {event.summary} (Details: {len(event.details)} Characters)\n"

The intent of the above code is as follows:

  1. A sub agent will re-fetch memories associated with its own memory type on every (re)invocation, but will cache memories and not-refetch them if they are not its own memory type. (The premise, I suppose, is that it's not very important to have up to date memories related to other memory types. The agent is primarily concerned with its own type.

  2. It should display the ID values for its own type of memories because it may need to update/merge/delete them, but it does not need to display ID values for other types because it is not responsible for maintaining other types of memories and so it would be pointless to include them.

However, the implementation of this logic had some bugs, which have been addressed in this PR.

  • The Agent Type comparison was not working because the ORM was wrapping the string values and causing the equality check to fail.

  • The specific way that the code was written was causing ID values to leak into other sub agents. For example, if the episodic memory agent ran first, it would cache the values with ID's and that would end up being used in the semantic agent.

This PR fixes the issues above and basically makes it so that the code will function as intended. ID's will correctly be displayed for all memories that match the type of the sub agent being invoked (and only for that type). I also refactored the agent type checking functionality to a shared utility and modified code across agent.py to use it. This should fix some other miscellaneous bugs as well.

--

2. fix: "clear history" related issues

There were multiple issues with the code that was responsible for clearing message history. This PR fixes that section of code so that message history is reliably cleared when it should be and reliably left in tact when it should not be.

Note: the current system behavior can be confusing because of the way that the code is written. Currently, since the CLEAR_MESSAGE_HISTORY flag is true by default, message history will be cleared after every agent's successful invocation. (meta and sub agent's alike). However, there is code that runs AFTER the clear message history code (unmodified in this PR), which puts the current input message back in the message_id's list after the system message.

The affect on overall system behavior is as follows (The meta and the sub agents behave the same in the following regard):

An agent will always see:

  1. the system prompt with memories added to it
  2. a summary of the most recently edited memory item matching its type (only if sub agent)
  3. the most recently processed set of saved messages
  4. the set of input messages

So, every agent sees BOTH the set of messages that it is processing AND whatever set of messages it processed during it's last successful invocation.

I don't know if that is by design or not, the code does not make it clear that this is how things work, so I wonder if it's by accident, but I'm ok with the behavior currently.


chore: add configuration points

  1. It's now possible to configure MAX_CHAINING_STEPS via an environment variable (was previously a constant)
  2. It's also now possible to turn off meta agent chaining entirely via a new CHAINING_FOR_META_AGENT environment variable

L-u-k-e and others added 3 commits January 17, 2026 16:49
* feat: make MAX_CHAINING_STEPS configurable

* feat: make it possible to turn off meta agent chaining

* fix: fix more agent name/type checks (#31)

* fix: fix more agent name/type checks

* fix: make sure to trigger clear_message_history (#32)
@L-u-k-e L-u-k-e changed the title fix: fix ID related tool call failures fix & feat: Fix ID related tool call failures, fix "clear history" related issues, add configuration points Jan 20, 2026
@L-u-k-e L-u-k-e changed the title fix & feat: Fix ID related tool call failures, fix "clear history" related issues, add configuration points fix: fix ID related tool call failures; fix: fix "clear history" related issues; chore: add configuration points Jan 20, 2026
@L-u-k-e L-u-k-e changed the title fix: fix ID related tool call failures; fix: fix "clear history" related issues; chore: add configuration points various fixes and chores Jan 20, 2026
@L-u-k-e L-u-k-e changed the title various fixes and chores feat: various fixes and chores Jan 20, 2026
)
self.message_manager.delete_detached_messages_for_agent(
agent_id=self.agent_state.id, actor=self.actor
)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

above this line are the changes to fix the clear history behavior

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original thought was trying to treat chat agent, meta agent and reflexion agent differently. The updated logic is different. But, let's commit this change and verify whether this logic is better.

)

if self.agent_state.name == "reflexion_agent":
if self.agent_state.is_type(AgentType.reflexion_agent):
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you'll see lots of changes like this in this PR.

Agent name is the incorrect way to check agent type. Agent names get prefixed with the client id, like: sales-batch-ingest_semantic_memory_agent. So checks like this do not work.

As noted in the PR summary, it's also incorrect to do a direct comparison with Agent.type (annoyingly so) because of some ORM type wrapping.

I added a utility to correctly check type and updated a bunch of code to use the uitility

elif chaining is not None:
effective_chaining = chaining
else:
effective_chaining = self.chaining
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a new env var CHAINING_FOR_META_AGENT. We set it to false in ECMS. Combined with CHAINING_FOR_MEMORY_AGENTS = false. This cuts down on cost and processing time. The meta agent will always run exactly once, and sub agents will run at most once.

Copy link
Owner

@LiaoJianhe LiaoJianhe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a comment on the changes for cleaning up historical messages. But, I think we can merge the change and verify whether the changed logic is better and cleaner. Other changes are good to me.

@L-u-k-e L-u-k-e merged commit be6d4af into lp/ops-2026-01-15 Jan 20, 2026
L-u-k-e added a commit that referenced this pull request Jan 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants