Metadata-Version: 2.4
Name: omni-agent-memory
Version: 0.1.4
Summary: OmniAgentMemory — a namespaced, structured memory service for Claude Code and other agents
Author-email: Luo <luo@evoquake.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/luoluow/omni_agent_memory
Project-URL: Repository, https://github.com/luoluow/omni_agent_memory
Project-URL: Issues, https://github.com/luoluow/omni_agent_memory/issues
Keywords: memory,llm,agents,claude-code,mcp,rag,fastapi
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Operating System :: OS Independent
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Framework :: FastAPI
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: fastapi>=0.110
Requires-Dist: uvicorn[standard]>=0.29
Requires-Dist: openai>=1.30
Requires-Dist: httpx>=0.27
Requires-Dist: pydantic>=2.6
Requires-Dist: mcp>=1.2
Requires-Dist: numpy>=1.24
Dynamic: license-file

# OmniAgentMemory

**A structured, namespaced memory service for Claude Code and other agents.** Agents push
raw conversation turns to `/ingest` and pull context-scoped memory from `/retrieve`. The
work that *builds* memory (extraction, verification, cascade, reconstruction) runs in the
background on a cheap construction model — off the answer model's critical path — while
memory is stored as several **decoupled, single-purpose indices** plus a **dependency-rule
engine**, not one consolidated note.

On the **MeME** benchmark (six memory tasks × two domains, 100 episodes, opus-judged),
OmniAgentMemory scores **84.9%** vs. **73.8%** for Claude Code's built-in consolidate-over-notes
memory (*AutoDream*) — **+11 points**, leading on five of six tasks, with the largest gaps
on **Deletion (+30)**, **Tracking (+17)**, **Absence (+13)**, and **Cascade**. See
[`docs/paper/OmniAgentMemory_vs_AutoDream.md`](docs/paper/OmniAgentMemory_vs_AutoDream.md).

```
   Claude Code ──hooks──▶ omni CLI ─┐
               ──MCP────▶ omni mcp ─┤ HTTP :11435
                                    ▼
                            OmniAgentMemory (FastAPI)
            OmniEngine ──▶ construction model (claude-code/sonnet default ·
                    │        deepseek-chat · or local gemma) — background
                    ▼
            ~/.omni/<client_id>/<namespace>/
              state · history · deletions · rules · pages · raw
```

## Install

```bash
pip install omni-agent-memory      # distribution name; the import/CLI is `omni`
```

## Quickstart — replace AutoDream in Claude Code

```bash
# 1) run the local memory sidecar (FastAPI on 127.0.0.1:11435)
omni serve

# 2) construction model (builds memory in the background, OFF your answer-model latency).
#    DEFAULT = claude-code/sonnet — your existing Claude Code subscription, no extra API key,
#    no metered cost. To override:
#      OMNI_EXTRACT_MODEL=deepseek-chat   # cheap cloud (needs DEEPSEEK_API_KEY)
#      OMNI_EXTRACT_MODEL=gemma4-ctx32k   # fully offline via Ollama (set OMNI_VERIFY_MODEL too)

# 3) wire a repo with one command (idempotent): merges hooks into .claude/settings.json
#    and writes .mcp.json
omni install-hooks --project .
```

That installs the standard Claude Code wiring:

```jsonc
// .claude/settings.json
{ "hooks": {
    "SessionStart":     [{ "hooks": [{ "type": "command", "command": "omni retrieve --session-start" }]}],
    "UserPromptSubmit": [{ "hooks": [{ "type": "command", "command": "omni ingest" }]}],
    "Stop":             [{ "hooks": [{ "type": "command", "command": "omni ingest" }]}]
}}
// .mcp.json
{ "mcpServers": { "omni": { "command": "omni", "args": ["mcp"] } } }
```

**Capture** is deterministic (hooks push every turn to `/ingest`, which returns immediately;
construction runs in the background). **Recall** is a `SessionStart` seed plus the MCP tools
`memory_search(query)` / `memory_note(text)`. Memory is **per-project** by default
(namespace = project dir, client = `claude-code`).

> A hosted **OmniAgentMemory Online Service** (zero local setup; point the same hooks at a managed
> endpoint) is on the roadmap.

## Why structured memory

A long-horizon agent's memory must do more than retrieve similar text — MeME formalizes six
tasks, each a distinct failure mode, and OmniAgentMemory gives each a purpose-built store:

| Task | Needs | OmniAgentMemory store |
|------|-------|------------------|
| **ER** Exact Recall | verbatim fact | `raw/` archive + `state.json` |
| **Agg** Aggregation | combine scattered facts | list entities + pages |
| **Tr** Tracking | full revision history | `history.jsonl` + `chains.json` |
| **Del** Deletion | recognize removals, withhold old value | `deletions.json` tombstones |
| **Cas** Cascade | propagate a stated dependency | `rules.json` + cascade-to-fixpoint |
| **Abs** Absence | admit uncertainty when no replacement | rules with `null` → uncertain |

The **dependency-rule engine** is what most distinguishes it: when the user states *"if my
X changes, my Y becomes Z"* (or *"my Y depends on my X"*), OmniAgentMemory records a rule and, when
the trigger later changes, **deduces** the new value (Cascade) or **flags uncertainty**
(Absence) — answers that a consolidated note cannot preserve. Strip the rule engine out and
Cascade collapses from 88% to 2%.

## Code map

| File | Role |
|------|------|
| `omni/engine.py` | OmniEngine: ingest → background EXTRACT/RELATE → debounced VERIFY → CASCADE → RECONSTRUCT → retrieve |
| `omni/storage.py` | Per-namespace on-disk stores (raw / state / history / deletions / rules / pages / vectors) |
| `omni/server.py` | FastAPI HTTP service + `/ui` inspector |
| `omni/cli.py` | `omni` CLI (hook client + `install-hooks` + `serve`/`mcp`) |
| `omni/mcp_server.py` | MCP stdio server — `memory_search` / `memory_note` |
| `omni/llm.py`, `omni/prompts.py`, `omni/config.py` | model routing, memory-op prompts, env config |

## HTTP API (quick check)

```bash
curl -s localhost:11435/health
curl -s -X POST localhost:11435/ingest  -H 'Content-Type: application/json' \
  -d '{"client_id":"alice","namespace":"proj","turns":[{"role":"user","content":"My medication is Quelmithin."}],"timestamp":"2023/03/17"}'
curl -s -X POST localhost:11435/retrieve -H 'Content-Type: application/json' \
  -d '{"client_id":"alice","namespace":"proj","query":"medication","mode":"search"}'
```

`client_id` is **required** and partitions storage as `~/.omni/<client_id>/<namespace>/`.
A built-in **memory inspector** is at http://127.0.0.1:11435/ — an action log of every
EXTRACT/RELATE/VERIFY call (request, response, applied writes) plus the current snapshot.

## Configuration (env vars)

| Var | Default | Meaning |
|-----|---------|---------|
| `OMNI_STORAGE_ROOT` | `~/.omni` | Storage root (`<client_id>/<namespace>/`) |
| `OMNI_CLIENT_ID` | `claude-code` | Default client id for the CLI/MCP clients |
| `OMNI_HOST` / `OMNI_PORT` | `127.0.0.1` / `11435` | HTTP bind |
| `OMNI_EXTRACT_MODEL` / `OMNI_VERIFY_MODEL` | `claude-code/sonnet` | Construction tier — `claude-code/sonnet` (subscription, default), `deepseek-chat` (cheap cloud), or `gemma4-ctx32k` (local Ollama) |
| `OMNI_ENSEMBLE_MODEL` / `OMNI_RERANK_MODEL` | `claude-code/sonnet` | Ranked ensemble retrieval (`/retrieve?mode=ensemble`) — per-strategy answer + reranker |
| `OMNI_VECTOR_ENABLED` | `1` | Vector sub-paths (needs `nomic-embed-text` via Ollama) |
| `OMNI_VERIFY_DEBOUNCE_SECONDS` | `20` | Idle window before background VERIFY |

Embeddings (only if `OMNI_VECTOR_ENABLED=1`) use `nomic-embed-text` via Ollama:

```bash
ollama pull nomic-embed-text
```

Optional fully-offline construction (instead of the default subscription Sonnet) — a local
Ollama model; note the OpenAI `/v1` path runs Ollama at its default 4096 context, so bake a
large-context variant:

```bash
ollama pull gemma4:e4b
printf 'FROM gemma4:e4b\nPARAMETER num_ctx 32768\n' > /tmp/Modelfile.ctx32k
ollama create gemma4-ctx32k -f /tmp/Modelfile.ctx32k
export OMNI_EXTRACT_MODEL=gemma4-ctx32k OMNI_VERIFY_MODEL=gemma4-ctx32k
```

## Documentation

- [`docs/paper/OmniAgentMemory_vs_AutoDream.md`](docs/paper/OmniAgentMemory_vs_AutoDream.md) — design + benefits vs. Claude Code's AutoDream, with the MeME metrics
- [`docs/paper/OmniAgentMemory.md`](docs/paper/OmniAgentMemory.md) — full design paper

## License

MIT.
