> ## Documentation Index
> Fetch the complete documentation index at: https://agent-memory.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# How it works

> The engine, memory worker, and viewer behind agentmemory capture, hybrid recall, keyless graph extraction, and session distillation.

One process hosts three parts: a bundled engine (state store, streams, HTTP triggers), a memory worker that registers every `mem::*` function against it, and the viewer. Agent integrations talk to the REST surface or the MCP server; both dispatch to the same worker functions.

```mermaid theme={"dark"}
flowchart LR
  subgraph agents [Agent integrations]
    hooks[Hooks<br/>Claude Code, OpenCode, Codex, Droid...]
    mcp[MCP clients<br/>Cursor, Gemini CLI, Zed...]
  end

  subgraph engine [Engine :3111 / :3112]
    rest[REST triggers<br/>api::*]
    state[(State store<br/>~/.agentmemory)]
    streams[Streams<br/>mem-live]
  end

  subgraph worker [Memory worker]
    observe[mem::observe]
    compress[mem::compress]
    search[mem::search<br/>mem::smart-search]
    remember[mem::remember]
    lessons[mem::lesson-save<br/>mem::lesson-recall]
    idx[[BM25 + vector index]]
  end

  viewer[Viewer :3113]

  hooks -->|POST /agentmemory/observe| rest
  mcp -->|memory_save, memory_recall| rest
  rest --> observe --> compress --> idx
  rest --> remember --> idx
  rest --> search --> idx
  rest --> lessons
  observe --> state
  remember --> state
  compress --> streams
  streams --> viewer
  viewer -->|proxied /agentmemory/*| rest
```

## Capture

Integrations post every prompt and tool call to `POST /agentmemory/observe`. `mem::observe` stamps session, project, agent id, and an origin channel (user, agent, tool, import, shared), then hands the record to compression. Without an LLM key `mem::compress` falls back to synthetic compression (heuristic title, files, narrative); with a key the model writes richer facts and concepts. Compressed observations enter the BM25 index immediately and the vector index when embeddings are available, and stream to the viewer over `mem-live`.

## Recall

`mem::search` and `mem::smart-search` fuse three streams per query: BM25 keyword, vector similarity, and graph adjacency. Weights normalize per item over the streams that matched it, cross-stream agreement earns a small bonus, and ties resolve deterministically. Session diversity caps stop one session from filling a page. Superseded memory versions never surface; the version chain stays in the store.

When context injection is on (`AGENTMEMORY_INJECT_CONTEXT=true`), `mem::context` assembles the session-start block in a fixed order: pinned memory slots first, then the project profile (top concepts, key files, conventions, common errors), then up to 10 lessons ranked by confidence with project-scoped ones boosted over global ones, then summaries of the most recent sessions in the same project. Blocks are packed against the token budget (`TOKEN_BUDGET`, default 2000); whatever doesn't fit is dropped whole rather than truncated mid-block.

## Distillation

Session end triggers the slow path:

```mermaid theme={"dark"}
flowchart TD
  stop[session/end] --> ev[event::session::stopped]
  ev --> summarize[mem::summarize<br/>session summary]
  summarize --> pipe[mem::consolidate-pipeline]
  pipe --> semantic[semantic facts]
  pipe --> procedural[procedures from repeated patterns]
  pipe --> decay[decay sweep<br/>unreinforced records lose strength]
  ev --> reflect[mem::slot-reflect]
  ev --> graphx[mem::graph-extract<br/>entities and relations]
  summarize --> crystal[mem::crystallize<br/>one digest per session]
```

Consolidation runs when its flag and an LLM provider key are set. Graph extraction runs unconditionally at session end: a deterministic structural pass turns files and concepts into nodes and links co-occurrences within an observation as `related_to` edges, so the graph populates with zero LLM keys. `GRAPH_EXTRACTION_ENABLED=true` plus a provider key layers an additional LLM pass on top that adds typed relations. Everything above the distillation line works keyless. Crystals outlive their raw observations, which retention sweeps eventually prune.

## Runtime surfaces

| Port  | Surface                                                  |
| ----- | -------------------------------------------------------- |
| 3111  | REST API, `api::*` triggers                              |
| 3112  | Streams WebSocket, powers the viewer live badge          |
| 3113  | Viewer (proxies REST, serves the dashboard)              |
| 49134 | Engine WebSocket the worker registers against (internal) |

The worker registers 264 functions in total; the families are listed in the [REST API reference](/docs/rest-api) and the [MCP tool reference](/docs/mcp-tools).
