Concept · Session memory
Typed sections, per-section budgets, an append-only audit trail.
The agent runtime keeps its working state in named sections rather than one flat conversation buffer. Each section declares its own token budget, its own rule for what to drop when full, and how it survives across restarts. A separate audit section is append-only and hash-chained, so every read of every other section leaves a tamper-evident trace. That structure is what lets a deal-room corpus, a chatty user log, an immutable role definition, and a privileged set of findings live in one session without bleeding into each other.
Why typed sections
A flat conversation buffer fails legal work in three places. Privilege boundaries collapse when every message lives in one undifferentiated stream. Cost ceilings can't be enforced when every kind of content pays the same per-token rate against one shared budget. Audit trails are unreliable when there is nothing typed to audit against.
Typed sections fix all three. Cross-tenant queries can be refused at the schema layer rather than a runtime check. Per-section token budgets let a deal-room of parsed contracts ride for free in the documents section while the chatty user-message section pays its own rate. The audit section is append-only and hash-chained, so every read of every other section leaves a verifiable trace that cannot be silently rewritten.
The sections, grouped by mutability
Each section declares a token budget, a rule for what to drop when full, and how it survives across restarts. The full-text search index built on top of the searchable sections uses BM25 — implemented in the retrieval module.
Eviction, summarization, persistence
When a section runs over budget, the rule it declared at startup decides what happens — first-in-first-out, last-in-first-out, least-recently-accessed, least-frequently-accessed, lowest-priority-first, refuse the write outright, or never evict at all because the section is bounded by design. The documents section never evicts so a thousand-PDF deal-room fits; the user-message section drops the oldest items first to stay in the model's context window.
Each section also declares how it survives a restart — gone at process exit, written to disk in full at commit time, or appended event-by-event to a JSONL file. The audit section is always the appended-event mode and always hash-chained; configuration cannot quietly make it forgetful.
A typed stream of memory-change events rides the same wire as the runtime exposes elsewhere — server-sent events for browsers, JSONL for log replay, WebSocket dictionaries for ops dashboards, plain REST for blocking clients. The same change record reaches each consumer; nothing has to be special-cased per channel.
What it looks like in code
A buy-side associate has loaded twenty contracts into the deal-room session and asked the agent to surface every change-of-control trigger. The findings, the parsed contracts, and the audit trail all live in named sections of the same memory.
from kaos_agents.memory import ( DEFAULT_SECTIONS, MemoryType, SessionMemory,)from kaos_agents.memory.search import search_memory
memory = SessionMemory(session_id="acme-buyside-2026")
# Each section declares its own eviction policypolicies = {cfg.memory_type: cfg.eviction_policy for cfg in DEFAULT_SECTIONS}print(policies[MemoryType.MESSAGES]) # fifoprint(policies[MemoryType.DOCUMENTS]) # none — fits the 20-contract deal-room
# Add a parsed contract and a finding the agent surfacedmemory.add(MemoryType.DOCUMENTS, msa_acme_text, tags=("contract", "acme"))memory.add( MemoryType.FINDINGS, "Acme MSA section 12.3 grants Acme a termination right on change of control.", tags=("change-of-control",),)
# BM25 over the searchable sections (MESSAGES, ACTIONS, DOCUMENTS, FINDINGS)hits = search_memory(memory, "change of control termination right", top_k=5)for hit in hits: print(hit.section, hit.item_id, hit.content[:80])
# Every section is append-only; each item carries a timestamp — the audit trailfor item in memory.get(MemoryType.FINDINGS): print(item.added_at, item.content[:120])Read next
The agentic page covers the runner that drives the memory turn-by-turn. The recipes concept shows how a matching plan loads into the plan-examples section at session start.
On learn-kaos: memory-as-context-assembly · memory-sections.