Skip to content

Memory System ​

The memory system provides session management and event storage for agents. It tracks conversation history, tool calls, delegations, and enables debugging.

Memory Implementations ​

KAOS provides two memory implementations:

ClassDescriptionUse Case
LocalMemoryFull in-memory storage with limitsDefault, full functionality
NullMemoryNo-op implementationDisabled memory, stateless agents

LocalMemory Class ​

python
class LocalMemory:
    def __init__(
        self,
        max_sessions: int = 1000,
        max_events_per_session: int = 500
    )

Parameters ​

ParameterDefaultDescription
max_sessions1000Maximum sessions before oldest are evicted
max_events_per_session500Maximum events per session (uses deque for O(1) eviction)

NullMemory Class ​

No-op implementation for when memory is disabled:

python
class NullMemory:
    """All operations succeed silently without storing data."""

Use when:

  • Building stateless agents
  • Resource-constrained environments
  • Testing without memory overhead

Configuration ​

Via Environment Variables ​

VariableDefaultDescription
MEMORY_ENABLEDtrueEnable/disable memory
MEMORY_TYPElocalMemory type (only local supported)
MEMORY_CONTEXT_LIMIT6Messages for delegation context
MEMORY_MAX_SESSIONS1000Max sessions to keep
MEMORY_MAX_SESSION_EVENTS500Max events per session

Via Agent CRD ​

yaml
spec:
  config:
    memory:
      enabled: true
      type: local
      contextLimit: 6
      maxSessions: 1000
      maxSessionEvents: 500

Session Management ​

Create Session ​

python
session_id = await memory.create_session(
    app_name="agent",
    user_id="user123",
    session_id="custom-id"  # Optional
)

Get or Create Session ​

Useful when session ID is provided by client:

python
session_id = await memory.get_or_create_session(
    session_id="provided-id",
    app_name="agent",
    user_id="user"
)

List Sessions ​

python
all_sessions = await memory.list_sessions()
user_sessions = await memory.list_sessions(user_id="user123")

Delete Session ​

python
deleted = await memory.delete_session(session_id)

Event Management ​

MemoryEvent Structure ​

python
@dataclass
class MemoryEvent:
    event_id: str           # Unique event identifier
    timestamp: datetime     # When event occurred
    event_type: str         # Category of event
    content: Any            # Event data
    metadata: Dict[str, Any]  # Additional context

Event Types ​

TypeDescriptionContent Example
user_messageUser input"What is 2+2?"
agent_responseFinal agent output"The answer is 4"
tool_callTool invocation request{"tool": "calc", "arguments": {...}}
tool_resultTool execution result{"tool": "calc", "result": 4}
delegation_requestSub-agent delegation{"agent": "worker", "task": "..."}
delegation_responseSub-agent response{"agent": "worker", "response": "..."}
errorError occurred"Connection failed"

Create Event ​

python
event = memory.create_event(
    event_type="user_message",
    content="Hello!",
    metadata={"source": "api"}
)

Add Event to Session ​

python
success = await memory.add_event(session_id, event)

Get Session Events ​

python
# All events
all_events = await memory.get_session_events(session_id)

# Filtered by type
messages = await memory.get_session_events(
    session_id,
    event_types=["user_message", "agent_response"]
)

Conversation Context ​

Build context string from conversation history:

python
context = await memory.build_conversation_context(
    session_id,
    max_events=20  # Last 20 messages
)
# Returns:
# "User: Hello!\nAssistant: Hi there!\nUser: How are you?"

Cleanup ​

Manual Cleanup ​

python
# Remove sessions older than 24 hours
cleaned = await memory.cleanup_old_sessions(max_age_hours=24)
print(f"Cleaned {cleaned} sessions")

Automatic Cleanup ​

LocalMemory uses a deque (double-ended queue) for event storage:

  • Events are automatically evicted when max_events_per_session is exceeded
  • Session cleanup removes oldest 10% when max_sessions is exceeded
  • O(1) append and eviction operations

Statistics ​

python
stats = await memory.get_memory_stats()
# Returns:
# {
#     "total_sessions": 42,
#     "total_events": 1337,
#     "avg_events_per_session": 31
# }

Serialization ​

Event to Dictionary ​

python
event_dict = event.to_dict()
# {
#     "event_id": "event_abc123",
#     "timestamp": "2024-12-31T12:00:00",
#     "event_type": "user_message",
#     "content": "Hello!",
#     "metadata": {}
# }

Event from Dictionary ​

python
event = MemoryEvent.from_dict(event_dict)

Session to Dictionary ​

python
session = await memory.get_session(session_id)
session_dict = session.to_dict()

Integration with Agent ​

The Agent class automatically logs events:

python
# In Agent.process_message()
user_event = self.memory.create_event("user_message", message)
await self.memory.add_event(session_id, user_event)

# After tool call
tool_event = self.memory.create_event("tool_call", tool_call)
await self.memory.add_event(session_id, tool_event)

# After final response
response_event = self.memory.create_event("agent_response", content)
await self.memory.add_event(session_id, response_event)

Memory Endpoints ​

Memory endpoints are always enabled and available for debugging and the UI:

GET /memory/events ​

List events with optional filtering:

bash
# Get last 100 events (default)
curl http://localhost:8000/memory/events

# Get last 50 events
curl http://localhost:8000/memory/events?limit=50

# Get events for specific session
curl http://localhost:8000/memory/events?session_id=session_abc123

# Combine filters
curl http://localhost:8000/memory/events?session_id=session_abc123&limit=20

Query Parameters:

ParameterDefaultMaxDescription
limit1001000Maximum events to return
session_id--Filter to specific session

Response:

json
{
  "agent": "my-agent",
  "events": [
    {
      "event_id": "event_abc123",
      "timestamp": "2024-12-31T12:00:00",
      "event_type": "user_message",
      "content": "Hello!"
    }
  ],
  "total": 1
}

GET /memory/sessions ​

List all session IDs:

bash
curl http://localhost:8000/memory/sessions
json
{
  "agent": "my-agent",
  "sessions": ["session_abc123", "session_def456"],
  "total": 2
}

Limitations ​

  1. In-Memory Only: Data is lost on pod restart
  2. Per-Pod Storage: No sharing between replicas
  3. No Persistence: Not backed by external storage

For production use cases requiring persistence, consider:

  • Redis-backed memory (future enhancement)
  • PostgreSQL storage (future enhancement)
  • External session service

Released under the Apache 2.0 License.