Skip to content

Memory System

The memory system provides session management and event storage for agents. It tracks conversation history, tool calls, delegations, and provides a bridge between KAOS events and Pydantic AI message types.

Memory Implementations

ClassDescriptionUse Case
LocalMemoryIn-memory storage with limitsDefault, single-pod
RemoteMemoryCentral memory-service client (short + long-term tiers)MemoryStore-bound agents
NullMemoryNo-op implementationDisabled memory

Configuration

Via Environment Variables

VariableDefaultDescription
MEMORY_ENABLEDtrueEnable/disable all memory operations
MEMORY_CONTEXT_LIMIT6Max history events for context window
MEMORY_MAX_SESSIONS1000Max sessions (LocalMemory)
MEMORY_MAX_SESSION_EVENTS500Max events per session (LocalMemory)
MEMORY_STORE_ENDPOINT-Central memory-service URL (set by the operator when a MemoryStore is bound; selects RemoteMemory)
MEMORY_MAX_READ_SCOPEsessionAutomatic recall scope and maximum level offered by search_memory
MEMORY_TOOLS-Additive explicit tools: all, read, or write

Via Agent CRD

yaml
spec:
  config:
    memory:
      enabled: true
      type: remote            # "remote" (bound MemoryStore) or "local" (pod-local)
      memoryStore: shared-memory
      maxReadScope: user  # Automatic recall scope and search_memory ceiling
      tools: all              # all | read | write
      failureMode: soft       # soft | strict

See the Agent CRD and MemoryStore CRD references for the full memory surface (scopes, tools, client params, storage modes).

Memory tiers

A RemoteMemory agent layers three tiers behind one client:

  • Short-term — a verbatim window of recent turns replayed for conversational continuity (also the local fallback when the store is degraded).
  • Medium-term — a rolling summary/digest of evicted turns (clientParams.rollingSummary).
  • Long-term — semantic, cross-session facts extracted into the bound MemoryStore and recalled by relevance.

LocalMemory keeps only the pod-local short-term window.

Read-Scope Policy

Automatic recall derives one server-owned scope at memory_default_read_scope; post-run writes carry level-less attribution containing every verified identity. A broader read scope changes only the long-term filter: conversational tiers still use the current session_id.

When memory_tools enables reads, the runtime exposes search_memory(query, level) with a level enum limited to memory_read_scopes. Owner identities are never model arguments. save_memory(content) derives level-less attribution from the authenticated run context.

Memory-Enabled Gating

When memory_enabled=False (or MEMORY_ENABLED=false):

  • NullMemory is used — all operations are no-ops
  • No conversation history is maintained between requests
  • Memory endpoints return empty results
  • Useful for stateless agents or performance-critical paths

Pydantic AI Bridge

The memory system bridges KAOS MemoryEvent objects to Pydantic AI ModelMessage types (ModelRequest / ModelResponse). This enables conversation continuity:

Memory Events → _memory_events_to_messages() → Pydantic AI message_history
Pydantic AI run result → _extract_and_persist_events() → Memory Events

Event-to-Message Mapping

KAOS Event TypePydantic AI Type
user_messageModelRequest with UserPromptPart
task_delegation_receivedModelRequest with UserPromptPart
agent_responseModelResponse with TextPart
tool_callModelRequest with ToolReturnPart
tool_resultModelRequest with ToolReturnPart

Context Window

The memory_context_limit controls how many recent events are included in the Pydantic AI message_history. This bounds context size for the LLM.

MemoryEvent Structure

python
@dataclass
class MemoryEvent:
    event_id: str
    timestamp: datetime
    event_type: str
    content: Any
    metadata: Dict[str, Any]

Event Types

TypeDescription
user_messageUser input
task_delegation_receivedDelegation from parent agent
agent_responseFinal agent output
tool_callMCP tool invocation
tool_resultMCP tool result
delegation_requestDelegation to sub-agent
delegation_responseSub-agent response
errorError during processing

Session Management

python
# Create session
session_id = await memory.create_session(app_name="agent", user_id="user123")

# Get or create (idempotent)
session_id = await memory.get_or_create_session(session_id="id", app_name="agent")

# List sessions
sessions = await memory.list_sessions()

# Delete session
await memory.delete_session(session_id)

Event Management

python
# Create and add event
event = memory.create_event("user_message", "Hello!", metadata={"source": "api"})
await memory.add_event(session_id, event)

# Get events
all_events = await memory.get_session_events(session_id)
filtered = await memory.get_session_events(session_id, event_types=["user_message"])

Memory Endpoints

Always available (not behind a debug flag):

GET /memory/events

bash
curl http://localhost:8000/memory/events
curl http://localhost:8000/memory/events?session_id=abc&limit=50

GET /memory/sessions

bash
curl http://localhost:8000/memory/sessions

RemoteMemory

Central memory-service client used when an agent is bound to a MemoryStore. The operator injects MEMORY_STORE_ENDPOINT and the runtime routes short- and long-term memory through the service:

python
from pais.memory import RemoteMemory

memory = RemoteMemory("http://memory-service.namespace:8080")

Uses the same API as LocalMemory; persistence and cross-session recall are handled by the memory service.

Cleanup

LocalMemory uses deques for automatic eviction:

  • Events evicted when max_events_per_session exceeded
  • Sessions evicted (oldest 10%) when max_sessions exceeded

Released under the Apache 2.0 License.