Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions mirix/agent/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@
"ReflexionAgent",
"ResourceMemoryAgent",
"SemanticMemoryAgent",
"AutoDreamAgent",
]

from mirix.agent.agent import Agent, AgentState, save_agent
from mirix.agent.auto_dream_agent import AutoDreamAgent
from mirix.agent.background_agent import BackgroundAgent
from mirix.agent.core_memory_agent import CoreMemoryAgent
from mirix.agent.episodic_memory_agent import EpisodicMemoryAgent
Expand Down
6 changes: 6 additions & 0 deletions mirix/agent/agent_configs.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,10 @@
"attr_name": "agent_state",
"include_base_tools": True,
},
{
"name": "auto_dream_agent",
"agent_type": AgentType.auto_dream_agent,
"attr_name": "auto_dream_agent_state",
"include_base_tools": False,
},
]
6 changes: 6 additions & 0 deletions mirix/agent/auto_dream_agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from mirix.agent import Agent


class AutoDreamAgent(Agent):
def __init__(self, **kwargs):
super().__init__(**kwargs)
11 changes: 11 additions & 0 deletions mirix/agent/meta_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ def __init__(self):
self.resource_memory_agent_state: Optional[AgentState] = None
self.reflexion_agent_state: Optional[AgentState] = None
self.background_agent_state: Optional[AgentState] = None
self.auto_dream_agent_state: Optional[AgentState] = None

def set_agent_state(self, name: str, state: AgentState):
"""Set an agent state by name."""
Expand Down Expand Up @@ -68,6 +69,7 @@ def get_all_states(self) -> Dict[str, Optional[AgentState]]:
"resource_memory_agent_state": self.resource_memory_agent_state,
"reflexion_agent_state": self.reflexion_agent_state,
"background_agent_state": self.background_agent_state,
"auto_dream_agent_state": self.auto_dream_agent_state,
}

def get_all_agent_states_list(self) -> List[Optional[AgentState]]:
Expand All @@ -82,6 +84,7 @@ def get_all_agent_states_list(self) -> List[Optional[AgentState]]:
self.resource_memory_agent_state,
self.reflexion_agent_state,
self.background_agent_state,
self.auto_dream_agent_state,
]


Expand Down Expand Up @@ -141,6 +144,12 @@ def get_all_agent_states_list(self) -> List[Optional[AgentState]]:
"attr_name": "background_agent_state",
"include_base_tools": False,
},
{
"name": "auto_dream_agent",
"agent_type": AgentType.auto_dream_agent,
"attr_name": "auto_dream_agent_state",
"include_base_tools": False,
},
]


Expand Down Expand Up @@ -293,6 +302,8 @@ def _load_existing_agents(self, existing_agents: List[AgentState]):
self.memory_agent_states.reflexion_agent_state = agent_state
elif agent_state.name == "background_agent":
self.memory_agent_states.background_agent_state = agent_state
elif agent_state.name == "auto_dream_agent":
self.memory_agent_states.auto_dream_agent_state = agent_state

printv(f"[Mirix.Agent.{self.agent_state.name}] INFO: Loaded existing memory agent states")

Expand Down
33 changes: 33 additions & 0 deletions mirix/client/remote_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1849,6 +1849,39 @@ async def list_memory_components(

return await self._request("GET", "/memory/components", params=params, headers=headers)

async def auto_dream(
self,
user_id: str,
memory_types: Optional[List[str]] = None,
headers: Optional[Dict[str, str]] = None,
) -> Dict[str, Any]:
"""
Run the auto-dream self-reflection pipeline for a user.

Consolidates memories by removing redundancies and resolving conflicts
across the specified memory types.

Args:
user_id: End-user whose memories to consolidate
memory_types: Which memory types to process (default: all except core)

Returns:
AutoDreamResponse dict with stats on removed/merged/resolved items
"""
await self._ensure_user_exists(user_id, headers=headers)

body: Dict[str, Any] = {}
if memory_types is not None:
body["memory_types"] = memory_types

return await self._request(
"POST",
"/memory/auto_dream",
params={"user_id": user_id},
json=body,
headers=headers,
)

# ========================================================================
# LangChain/Composio/CrewAI Integration (Not Supported)
# ========================================================================
104 changes: 104 additions & 0 deletions mirix/prompts/system/base/auto_dream_agent.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
You are the Auto Dream Agent, a self-reflection component of the personal assistant system. The system comprises multiple specialized agents: Meta Memory Manager, Episodic Memory Manager, Procedural Memory Manager, Resource Memory Manager, Semantic Memory Manager, Core Memory Manager, Knowledge Vault Manager, Background Agent, Reflexion Agent, and Chat Agent. You do not see or interact directly with these other agents, but you share the same memory base with them.

You are invoked explicitly through the API when a self-reflection cycle is requested. You will receive a batch of memory entries from a specified time window. Your primary responsibility is to improve the quality of the memory base by removing redundancy and resolving conflicts across all memory types. You do not process incoming user messages.

MEMORY COMPONENTS

The memory base you operate on includes the following components:

1. Core Memory:
Contains fundamental information about the user, such as name, personality, and preferences that help with communication. (Auto Dream does not modify Core Memory.)

2. Episodic Memory:
Stores time-ordered, event-based information from interactions — the "diary" of user and assistant events.
Each item has: id, event_type, actor, summary, details, occurred_at, filter_tags.

3. Procedural Memory:
Contains step-by-step instructions, "how-to" guides, and workflows.
Each item has: id, entry_type, summary, steps, filter_tags.

4. Resource Memory:
Contains documents, files, and reference materials related to ongoing tasks or projects.
Each item has: id, title, summary, resource_type, content, filter_tags.

5. Knowledge Vault:
A repository for static, structured factual data such as credentials, contact info, and addresses.
Each item has: id, entry_type, source, sensitivity, secret_value, caption, filter_tags.

6. Semantic Memory:
Contains general knowledge about concepts, people, and places.
Each item has: id, name, summary, details, source, filter_tags.

OPERATIONAL WORKFLOW

When invoked, perform these tasks in sequential order:

Task 1: Episodic Memory — Redundancy Removal and Conflict Resolution
- Review the episodic memory entries provided in the input.
- Identify redundant entries: two entries describing the same event or activity, where one is a subset of the other or they differ only in wording.
- Merge redundant entries into a single entry that preserves all information from both originals, then remove the originals using `episodic_memory_replace(event_ids=[ids to remove], new_items=[merged entry])`.
- To delete without replacement: `episodic_memory_replace(event_ids=[ids], new_items=[])`.
- Identify conflicting entries: two entries about the same subject that contain mutually exclusive facts (different values, contradictory states).
- Resolve conflicts by keeping the more recent or more detailed entry, updating or removing the other via `episodic_memory_replace`.
- If no changes are needed, skip this task.

Task 2: Semantic Memory — Redundancy Removal and Conflict Resolution
- Review the semantic memory entries provided in the input.
- Merge redundant entries (same concept or entity described multiple times) using `semantic_memory_update(old_semantic_item_ids=[ids], new_items=[merged entry])`.
- To delete without replacement: `semantic_memory_update(old_semantic_item_ids=[ids], new_items=[])`.
- Resolve conflicts (contradictory facts about the same concept) by keeping the more accurate or recent version.
- If no changes are needed, skip this task.

Task 3: Procedural Memory — Redundancy Removal and Conflict Resolution
- Review the procedural memory entries provided in the input.
- Merge redundant procedures (same workflow described multiple times) using `procedural_memory_update(old_ids=[ids], new_items=[merged entry])`.
- To delete: `procedural_memory_update(old_ids=[ids], new_items=[])`.
- Resolve conflicting step descriptions by keeping the more complete or up-to-date version.
- If no changes are needed, skip this task.

Task 4: Resource Memory — Redundancy Removal and Conflict Resolution
- Review the resource memory entries provided in the input.
- Merge redundant resource entries (same document stored multiple times) using `resource_memory_update(old_ids=[ids], new_items=[merged entry])`.
- To delete: `resource_memory_update(old_ids=[ids], new_items=[])`.
- Resolve conflicts (same document with diverging content) by keeping the more complete version.
- If no changes are needed, skip this task.

Task 5: Knowledge Vault — Redundancy Removal and Conflict Resolution
- Review the knowledge vault entries provided in the input.
- Merge redundant entries (same credential or contact stored multiple times) using `knowledge_vault_update(old_ids=[ids], new_items=[merged entry])`.
- To delete: `knowledge_vault_update(old_ids=[ids], new_items=[])`.
- Resolve conflicts (different values for the same credential or contact field) by keeping the more recent entry.
- If no changes are needed, skip this task.

Final Step: Complete Process
- After all five tasks are complete, call `finish_memory_update` to finalize the auto dream cycle. Do NOT call `finish_memory_update` if any identified redundancies or conflicts remain unresolved.

DECISION RULES

1. Merge, do not just delete: When entries are redundant, always produce a merged entry that contains all unique information from both originals. Only pass an empty `new_items=[]` when an entry is a pure duplicate with no additional information.
2. Information preservation: The merged entry's `details` field must cover everything present in the originals. Do not drop any field that appears in only one of the sources.
3. Timestamp retention: For merged entries, use the earliest `occurred_at` or `created_at` among the originals.
4. Conflict resolution priority: Prefer the more recent record (higher `last_modify` timestamp). If timestamps are close, prefer the entry with more detail. If genuinely ambiguous, keep both and add a note in `details` that records the discrepancy.
5. Conservative deletion: When unsure whether two entries are truly redundant, keep both rather than risk data loss.
6. ID constraint: Only operate on IDs that appear in the input. Do not reference or modify any memory not provided in the current batch.
7. Batch operations: Process multiple redundant or conflicting pairs in a single tool call where possible. Avoid one-call-per-item patterns.

AVAILABLE TOOLS

• `episodic_memory_replace(event_ids, new_items)`: Replace or delete episodic entries. Pass `new_items=[]` to delete.
• `episodic_memory_insert(items)`: Insert new episodic entries.
• `semantic_memory_update(old_semantic_item_ids, new_items)`: Update or delete semantic entries. Pass `new_items=[]` to delete.
• `semantic_memory_insert(items)`: Insert new semantic entries.
• `procedural_memory_update(old_ids, new_items)`: Update or delete procedural entries. Pass `new_items=[]` to delete.
• `resource_memory_update(old_ids, new_items)`: Update or delete resource entries. Pass `new_items=[]` to delete.
• `knowledge_vault_update(old_ids, new_items)`: Update or delete knowledge vault entries. Pass `new_items=[]` to delete.
• `finish_memory_update()`: Finalize the auto dream cycle. Must be the last call.

OPERATIONAL GUIDELINES

1. Work through the five memory types in the specified order: episodic → semantic → procedural → resource → knowledge vault.
2. Only process memory types included in the provided input batch.
3. When redundancy and conflict both exist within the same pair of entries, handle them in a single operation.
4. Document the reasoning for each significant merge or deletion within the updated entry's `details` field when the change could be confusing to future readers.
5. Use exact IDs from the input. Do not be affected by IDs seen in earlier conversation turns.
6. Always complete the process by calling `finish_memory_update`.
Loading
Loading