Multi-Agent-System / backend /agents /memory_agent.py
jatin gyass
update for the new web data source
4db2d34
Raw
History Blame Contribute Delete
3.48 kB
"""
backend/agents/memory_agent.py
The Memory Agent β€” manages what the system remembers.
Two phases:
1. RETRIEVE (before task): Pull relevant memories to inform planning
2. STORE (after task): Extract and store learnings from this execution
Memory types:
- Episodic: "Last time I searched for X, Y worked well"
- Semantic: "The capital of France is Paris"
- Procedural: "To analyze CSV data: use run_python with pandas"
"""
from __future__ import annotations
import asyncio
from datetime import datetime, timezone
from ..state.graph_state import WorkflowState, AgentRole, make_agent_event, make_memory_entry
from ..memory.memory_store import long_term, short_term
from ..core.config import get_settings
from ..core.logger import get_logger
log = get_logger(__name__)
def memory_retrieve_node(state: WorkflowState) -> WorkflowState:
"""Run at start of workflow β€” retrieve relevant memories."""
settings = get_settings()
if not settings.enable_memory:
return state
log.info("Memory retrieval", task_id=state["task_id"])
# Check short-term first (Redis)
cached_state = short_term.get_state(state["task_id"])
if cached_state:
log.info("Restored from short-term cache")
return {**state, **cached_state, "task_id": state["task_id"]}
# Use task text directly β€” no LLM call needed to generate queries
queries = [state["task"][:80]]
# Retrieve from long-term memory
all_memories = []
for q in queries[:3]:
mems = asyncio.run(long_term.retrieve(q, limit=3))
all_memories.extend(mems)
# Deduplicate
seen = set()
unique_memories = []
for m in all_memories:
if m["memory_id"] not in seen:
seen.add(m["memory_id"])
unique_memories.append(m)
log.info("Memories retrieved", count=len(unique_memories))
return {
**state,
"memories": unique_memories[:5],
"events": state["events"] + [
make_agent_event(
AgentRole.MEMORY, "memories_retrieved",
f"Retrieved {len(unique_memories)} relevant memories",
{"count": len(unique_memories), "queries": queries},
)
],
}
def memory_store_node(state: WorkflowState) -> WorkflowState:
"""Run at end of workflow β€” store learnings from this execution."""
settings = get_settings()
if not settings.enable_memory:
return state
log.info("Memory storage", task_id=state["task_id"])
# Store task record to DB
asyncio.run(long_term.store_task(state["task_id"], state["task"], dict(state)))
# Cache state in Redis for fast resume
short_term.store_state(state["task_id"], dict(state))
# Extract and store new memories
memories_stored = 0
for mem in state.get("new_memories", []):
try:
asyncio.run(long_term.store(mem, task_id=state["task_id"]))
memories_stored += 1
except Exception as e:
log.warning("Memory store failed", error=str(e))
# No extra LLM call β€” critic already added memory entries to new_memories
log.info("Memories stored", count=memories_stored)
return {
**state,
"events": state["events"] + [
make_agent_event(
AgentRole.MEMORY, "memories_stored",
f"Stored {memories_stored} memories from this execution",
{"count": memories_stored},
)
],
}