annaanna
Core Concepts

Memory System

Overview

The memory system is plugin-based. A memory.Provider interface in pkg/memory/ defines the contract, and concrete implementations live in plugins/memory/. Two built-in plugins ship with anna:

PluginPackageDefaultDescription
LCMplugins/memory/lcm/YesLossless Context Management — DAG of summaries, compaction, search, explore
Simpleplugins/memory/simple/NoSliding-window — keeps last N messages within token budget, no summaries

Switching Plugins

Memory plugins are managed like other plugins. In the admin panel or via anna plugin:

anna plugin disable memory/lcm
anna plugin enable memory/simple

Only one memory plugin should be enabled at a time. Both use the same underlying ctx_messages table, so switching preserves stored messages.

Provider Interface

The core Provider interface (pkg/memory/provider.go) has 5 methods:

MethodDescription
Bootstrap(ctx, session)Ensures a conversation record exists for the session
Append(ctx, session, msgs)Persists messages and appends context items
Assemble(ctx, session, budget, freshTail)Builds context within token budget, returns []ai.Message
Stats(ctx, session)Returns session statistics (token count, message count)
Close()Releases resources

Optional Capabilities

Providers can implement additional interfaces detected via type assertion:

InterfaceMethodsDescription
CompactorNeedsCompaction, CompactContext window compaction
SearcherSearchFull-text search across messages and summaries
ExplorerDescribe, ExpandInspect and drill into summaries
ProfileStoreGetProfile, SetProfilePer-user-per-agent persistent notes
SessionManagerSaveInfo, LoadInfo, ListInfo, LoadHistorySession metadata and history management
ReviewSourceListUnreviewed, BuildReviewContext, MarkReviewedSelf-improvement review data

The LCM plugin implements all 7 interfaces. The Simple plugin implements Provider, ProfileStore, and SessionManager.

Tool Auto-Generation

memory.BuildTool(provider) inspects the provider's capabilities and generates a tools.Tool with matching actions:

ActionRequiresDescription
status(always)Show session stats (tokens, messages)
searchSearcherSearch messages and summaries by pattern
describeExplorerInspect a summary's metadata and lineage
expandExplorerDrill into compacted summaries
profile_getProfileStoreRead persistent per-user notes
profile_updateProfileStoreUpdate persistent per-user notes

The tool's JSON schema, description, and dispatch all adapt dynamically. A provider with fewer capabilities produces a tool with fewer actions.

LCM Plugin

Architecture

ai.Message (user/assistant/tool_result)
        |
        v
  +----------+     Append     +-----------+
  | Provider  | ------------> | SQLite DB |
  +----------+                +-----+-----+
     |    |                          |
     |    | Compact                  |  Tables:
     |    v                          |    ctx_conversations
     | +------------------+          |    ctx_messages
     | | CompactionEngine | <--------+    ctx_summaries
     | +------------------+          |    ctx_items
     |                               |    ctx_summary_messages
     |  Assemble (budget)            |    ctx_summary_parents
     v                               |
  +------------+                     |
  | Assembler  | <-------------------+
  +------------+
        |
        v
  []ai.Message (fresh tail + summaries within token budget)
        |
        v
  LLM context window

Compaction

Compaction reduces the context window by summarizing older messages and summaries.

Modes:

ModeBehavior
IncrementalSingle leaf pass + one condensed pass. Runs automatically when context exceeds threshold.
FullRepeats leaf + condensed passes until no more compaction is possible (up to 10 iterations).

Passes:

  1. Leaf pass — Groups contiguous runs of message context items outside the fresh tail. Groups of 10+ messages are summarized into a leaf summary (depth 0).
  2. Condensed pass — Groups contiguous runs of summary context items at the same depth. Groups of 2+ summaries are condensed into a condensed summary at depth+1.

Summarization escalation:

  1. Normal mode — Preserves key decisions, rationale, constraints. Target: input_tokens/3.
  2. Aggressive mode — Keeps only durable facts. Triggered when normal exceeds 150% of target.
  3. Deterministic fallback — Truncates at sentence boundary. Triggered when aggressive still exceeds 150%.

Context Assembly

  1. Separate context items into fresh tail (last N message items, default 20) and older items.
  2. Resolve fresh tail items to ai.Messages — always included regardless of budget.
  3. Fill remaining budget with older items, newest first.
  4. Return older events (chronological) + tail events.

Concurrency

  • Per-session mutexAppend and Compact acquire a per-session lock to prevent concurrent mutations.
  • Conversation ID cache — Immutable sessionID -> convID mapping cached after first lookup.

Simple Plugin

The Simple plugin uses a sliding-window approach:

  1. Append stores messages in ctx_messages (same schema as LCM).
  2. Assemble returns the last N messages that fit within the token budget, always honoring freshTail.
  3. No summaries, no compaction, no search, no explore.

This is suitable for short-lived conversations or resource-constrained environments.

Database

  • Location: ~/.anna/anna.db
  • Driver: modernc.org/sqlite (pure Go, no CGO)
  • Mode: WAL, foreign keys enabled
  • Migrations: Atlas-generated, embedded via MigrationsFS, auto-applied on startup.

Schema:

TablePurpose
ctx_conversationsOne per session (session_id -> id mapping), includes agent/user ID
ctx_messagesRaw messages with role, content, token_count, sequential seq
ctx_summariesSummary DAG nodes: kind, depth, content, token stats, time range
ctx_itemsOrdered context window: points to message or summary
ctx_summary_messagesLinks leaf summaries to source messages
ctx_summary_parentsLinks condensed summaries to parent summaries (DAG edges)
ctx_agent_memoryPer-user-per-agent persistent notes (used by ProfileStore)

Configuration Defaults

ConstantValueDescription
DefaultFreshTail20Messages protected from compaction
DefaultContextThreshold0.75Fraction of budget that triggers compaction
DefaultLeafChunkSize10Minimum messages per leaf summary

Identity & User Memory

3-Layer System Prompt

LayerDefault sourceFile overrideDescription
BasicBuilt-in system instructionsSYSTEM.md in agent workspaceCore behavioral instructions for the LLM
Agent soulsettings_agents.system_promptSOUL.md in agent workspaceAgent identity, personality, and tone
User memoryctx_agent_memory.content(none — always from DB)Per-user-per-agent notes, injected via ProfileStore

User Memory

User memory is stored in ctx_agent_memory, keyed by (user_id, agent_id). The agent updates it via the memory tool's profile_update action and reads it via profile_get.

Agent Workspaces

Each agent has its own workspace at $ANNA_HOME/workspaces/{agent_id}/ for file overrides, skills, and per-agent data.

On this page