Skip to Content

Memory & State

Manage persistent memory and conversational state across agent sessions.

Overview

The isA Agent SDK provides multiple layers of memory to give agents context awareness:

  • Session memory — conversational context within a single session
  • Checkpointing — durable state that survives restarts
  • Working memory — short-lived context for active tasks
  • Long-term memory — factual, episodic, semantic, and procedural memory stored via MCP

Session Memory

Within a session, agents automatically maintain conversational context using the ISAAgentClient:

from isa_agent_sdk import ISAAgentClient async with ISAAgentClient() as client: await client.query("My name is Alice") async for msg in client.receive(): print(msg.content) # Agent remembers the context await client.query("What's my name?") async for msg in client.receive(): print(msg.content) # "Your name is Alice"

Session memory persists for the lifetime of the client connection. For multi-turn conversations, use ISAAgentClient instead of the stateless query() function.

Checkpointing (Durable State)

For long-running tasks, checkpointing saves execution state so agents can resume after interruptions:

from isa_agent_sdk import query, ISAAgentOptions, ExecutionMode options = ISAAgentOptions( execution_mode=ExecutionMode.COLLABORATIVE, session_id="data-processing-001" ) async for msg in query("Process all CSV files in /data", options=options): if msg.is_checkpoint: # Agent paused — respond to continue await msg.respond({"continue": True}) elif msg.is_text: print(msg.content, end="")

Resume later from the saved checkpoint:

from isa_agent_sdk import resume async for msg in resume("data-processing-001"): print(msg.content)

The checkpointer backend is configurable:

BackendConfigDescription
RedisCHECKPOINTER_BACKEND=redisRecommended for production
FilesystemCHECKPOINTER_BACKEND=filesystemLocal development fallback

Checkpointing documentation

Working Memory

Working memory stores short-lived context for the current task. It is automatically managed by the agent during execution and cleared when the task completes.

# Working memory is used internally by the agent # Access it programmatically via MCP tools: from isa_agent_sdk import execute_tool # Store context for current task await execute_tool("store_working_memory", { "key": "current_analysis", "content": "User wants a performance report for Q1", "ttl_minutes": 60 }) # Retrieve active working memories memories = await execute_tool("get_active_working_memories", {})

Long-Term Memory (MCP)

For persistent knowledge that spans sessions, the SDK integrates with the isA MCP memory service:

MemoryStack Helpers

Recent SDK builds expose MemoryStack helpers for listing stored memories and retrieving aggregate health/statistics data:

from isa_agent_sdk.stack.memory_stack import MemoryStack memory = MemoryStack() await memory.start() items = await memory.list_memories(user_id="user_123", limit=20) stats = await memory.get_stats(user_id="user_123") await memory.stop()

Use list_memories for inspection and debugging. Use get_stats when dashboards or health checks need summarized memory counts, backend state, or capacity signals.

Factual Memory

Store facts about users, projects, or domains:

await execute_tool("store_factual_memory", { "subject": "user-123", "predicate": "prefers", "object": "dark mode", "confidence": 0.95 }) # Search by subject facts = await execute_tool("search_facts_by_subject", { "subject": "user-123" })

Episodic Memory

Record events and interactions:

await execute_tool("store_episodic_memory", { "event_type": "code_review", "description": "Reviewed auth module - found 3 security issues", "metadata": {"module": "auth", "issues_found": 3} })

Semantic Memory

Store conceptual knowledge:

await execute_tool("store_semantic_memory", { "concept": "rate_limiting", "category": "security_patterns", "description": "Token bucket algorithm with Redis backend", "related_concepts": ["throttling", "api_gateway"] })

Procedural Memory

Store how-to knowledge:

await execute_tool("store_procedural_memory", { "task": "deploy_to_kubernetes", "steps": [ "Build Docker image", "Push to registry", "Apply K8s manifests", "Run health checks" ], "preconditions": ["Docker installed", "kubectl configured"] })

Searching Memories

# General search across all memory types results = await execute_tool("search_memories", { "query": "user preferences for UI", "memory_types": ["factual", "episodic"], "limit": 10 }) # Get memory statistics stats = await execute_tool("get_memory_statistics", {})

Memory in Steward Mode

When using the agent as a Steward, memory is used automatically to:

  • Remember user preferences and habits
  • Track task history and completion patterns
  • Store calendar context for scheduling
  • Maintain trigger conditions and alert history

Tiered Memory Architecture

Sprint 3 (PR #528) replaced the flat summary string with a three-tier in-process memory model. The tiers mirror how humans consolidate experience: active context, recent episodes, and compressed long-term knowledge.

┌─────────────────────────────────────────────────────┐ │ Agent State (LangGraph) │ │ │ │ ┌─────────────────┐ │ │ │ Working Memory │ ← current task context │ │ │ (messages[]) │ cleared when task ends │ │ └────────┬────────┘ │ │ │ summarize on overflow │ │ ▼ │ │ ┌─────────────────┐ │ │ │ Episodic Memory │ ← summary_chain[] │ │ │ (recent sessions│ one entry per episode │ │ │ as summaries) │ rolling, incremental │ │ └────────┬────────┘ │ │ │ meta-compaction when threshold reached │ │ ▼ │ │ ┌─────────────────┐ │ │ │ Semantic Memory │ ← compressed knowledge │ │ │ (long-term, │ persists across sessions │ │ │ compressed) │ stored via MCP │ │ └─────────────────┘ │ └─────────────────────────────────────────────────────┘

Memory Tiers

TierScopeBacking FieldLifecycle
WorkingCurrent taskmessages[]Cleared on task completion
EpisodicRecent session historysummary_chain[]Rolling summaries, pruned by threshold
SemanticLong-term compressed knowledgeMCP memory servicePersists across sessions

New State Fields

Three new fields were added to the agent state schema:

FieldTypeDescription
summary_chainlist[str]Ordered list of episode summaries. Each entry is a compressed narrative of one past episode.
last_summary_indexintPointer into the message log marking where the last incremental summary was taken. Used by rolling summarization to avoid re-summarizing already-processed messages.
meta_compaction_thresholdintNumber of entries in summary_chain that triggers meta-compaction. When the chain exceeds this value, all episodes are compressed into a single semantic memory entry and the chain is reset. Default: 10.

Rolling Summarization

Previous versions performed batch summarization — the full message history was compressed in one pass whenever context grew too large. Sprint 3 (PR #522) replaced this with progressive rolling summarization:

  1. After each exchange, new messages since last_summary_index are summarized into a new episode entry.
  2. The summary is appended to summary_chain.
  3. last_summary_index advances to the current end of the message log.
  4. Only the delta is processed, keeping summarization fast and predictable.

Meta-Compaction

When summary_chain exceeds meta_compaction_threshold, meta-compaction fires:

  1. All entries in summary_chain are compressed into a single semantic memory artifact.
  2. The artifact is written to the MCP semantic memory store (see Long-Term Memory).
  3. summary_chain is reset to an empty list.
  4. last_summary_index is set to the current end of the message log.

This prevents summary_chain from growing indefinitely while preserving durable knowledge in semantic memory.

Configuration Example

from isa_agent_sdk import ISAAgentOptions options = ISAAgentOptions( session_id="research-session-001", # How many episode summaries to accumulate before compacting # into semantic memory. Lower values reduce memory footprint; # higher values preserve more short-term episodic detail. meta_compaction_threshold=10, )

To inspect the current state of the memory tiers during a session:

from isa_agent_sdk import get_session_state state = await get_session_state("research-session-001") # Episodic tier print(f"Episodes in chain: {len(state['summary_chain'])}") print(f"Last summary index: {state['last_summary_index']}") print(f"Compaction threshold: {state['meta_compaction_threshold']}") # Print each episode summary for i, episode in enumerate(state["summary_chain"]): print(f"\n--- Episode {i + 1} ---") print(episode)

Best Practices

  1. Use session memory for conversational context — it’s automatic with ISAAgentClient
  2. Use checkpointing for tasks that may take a long time or need to survive restarts
  3. Use long-term memory for knowledge that should persist across sessions
  4. Set TTLs on working memory to avoid stale context accumulating
  5. Use factual memory for structured facts (user preferences, project metadata)
  6. Use episodic memory for event logs (reviews, deployments, decisions)
  7. Tune meta_compaction_threshold based on session length — increase for long research sessions, decrease for short interactive tasks to keep memory lean