Engram
Give your model a memory, local or cloud. One process, one SQLite file, zero code changes.
The built-in observatory at
/engram/ui: memories orbit by activation, reinforced ones fall inward, decaying ones drift out.
Click a memory and its hebbian web stays lit, dossier alongside; hover any mote for its status, activation, and title.
Engram is a transparent proxy that sits between any client and Ollama. It recalls relevant memories from past sessions and injects them before the model answers (~22 ms overhead, no LLM on the request path), then summarizes each exchange in the background - using the same small model you're chatting with.
┌─────────────────────────────┐
client ──────► │ engramd :11435 │ ──────► ollama :11434
(curl, │ recall → inject → forward │
openclaw, │ response tee → episode log │
hermes) │ idle-time summarizer │
└──────────┬──────────────────┘
└── engram.db (SQLite: FTS5 + vectors + queue)
Install
pip install engram-proxy # or: uvx --from engram-proxy engram up
ollama pull qwen3:1.7b qwen3-embedding:0.6b
Quick start
engram up
# in another terminal - stock ollama, now with memory:
export OLLAMA_HOST=127.0.0.1:11435
ollama run qwen3:1.7b "I'm Sam. My cat is Miso and I'm badly allergic to peanuts."
# ... later, in a NEW session:
ollama run qwen3:1.7b "Ordering Thai tonight - anything I should avoid?"
Requires Ollama with qwen3:1.7b (summarizer) and qwen3-embedding:0.6b
(retrieval) - ollama pull qwen3:1.7b qwen3-embedding:0.6b, ~2 GB total.
Field-tested defaults: sub-1B summarizers garble facts, so qwen3:1.7b is the
default; without it, summaries fall back to extractive, which also preserves
facts. Set
ENGRAM_SUMMARIZER_MODEL / ENGRAM_EMBED_MODEL to override
(nomic-embed-text is ~3x faster to embed but measurably worse at admission).
CLI
engram up run the proxy (default :11435 -> :11434)
engram list recent traces (title + gist + access stats)
engram recall "query" dry-run recall with per-candidate scores
engram why explain the last injection, score by score
engram stats store counts, queue depth, degraded recalls
engram bench measure embed + recall latency on your machine
Numbers and methodology: BENCHMARKS.md.
Design in one paragraph
Every exchange becomes an episode (verbatim, SHA-deduped). A write-behind
worker - running only when the GPU is idle - asks qwen3:1.7b for two plain
lines (TITLE: / GIST:; never JSON, with a deterministic extractive fallback)
and embeds the gist (qwen3-embedding, Matryoshka-truncated to 256d). Recall is
hybrid BM25 + dense with admission on raw thresholds (unrelated turns
inject nothing) - exact search below 50k memories, a pure-numpy IVF index past
it (~86ms p95 at 250k traces, still embed-bound) - ranked by relevance + ACT-R activation
B = ln(Σ w·t^-0.5) - frequent-and-recent memories surface first, unused ones
sink, and injection itself reinforces at only 0.15 weight (capped per session)
so the rich-get-richer loop stays closed. Idle-time consolidation maintains a user profile and topic summaries;
silent memories resurrect on strong cues. Injection is budgeted for small
models: ≤2 gists + 2 titles, ≤350 tokens, placed first in the system message.
Failures fail open: a slow or broken pipeline degrades to a plain proxy.
Full architecture spec: see the published design document.
For coding agents
The repo ships an agent-consumable skill at skills/engram-integration/SKILL.md
(standard SKILL.md format: Claude Code, OpenClaw, and Hermes all read it).
Point your agent at it, or just say "integrate engram into my setup", and it
walks the full recipe: preflight, install, per-client wiring, verification,
and the gotchas that cost us real debugging time.
Cloud models
Engram can give a cloud model the same memory, with background work staying local and free:
# route Anthropic-protocol traffic (/v1/messages) to a cloud endpoint;
# OpenAI/Ollama routes keep hitting local Ollama
ENGRAM_ANTHROPIC_UPSTREAM=https://api.minimax.io .venv/bin/python -m engram up
# point your client's Anthropic base_url at Engram, e.g. Hermes Agent + MiniMax:
# MINIMAX_BASE_URL=http://127.0.0.1:11435/anthropic
Auth headers pass through untouched; embeddings and summarization always run
on local Ollama (ENGRAM_SERVICES, default http://127.0.0.1:11434), so the
only added cloud cost is the injected block itself (≤350 tokens, ~1% of a
typical agent prompt). Big-prompt injection rides the newest message, so
provider prompt caches - and their cache-read discounts - survive.
Endpoints
POST /api/chat- Ollama-native NDJSON, memory-enabledPOST /v1/chat/completions- OpenAI-compatible SSE, memory-enabledPOST [/prefix]/v1/messages- Anthropic Messages (local or cloud upstream), memory-enabled- everything else (
/api/generate,/api/tags,/api/show,/v1/models, embeddings) - byte passthrough GET /engram/stats,GET /engram/why- local introspection- header
X-Engram: offbypasses memory per-request;X-Engram-Sessionpins session identity
Metadata
Release files for engram-proxy 0.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| engram_proxy-0.5.0.tar.gz | 74.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| engram_proxy-0.5.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 143.3 kB
Release files / engram_proxy-0.5.0.tar.gz
| Download URL | engram_proxy-0.5.0.tar.gz |
|---|---|
| Size | 74.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
62469c580b96ed3d545056d1dc7d433de37c896c4777af6b321dfada7ce85537
|
|
BLAKE2b-256 checksum How to use checksums |
a6c40097199b0833f1b4c32294418026871e65f98412ce97bb0b9018d97c1a58
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.7
|
Release files / engram_proxy-0.5.0-py3-none-any.whl
| Download URL | engram_proxy-0.5.0-py3-none-any.whl |
|---|---|
| Size | 69.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b812e73187115087db5479cafb52c70028239066ddc8489c1181b3ef29d316bc
|
|
BLAKE2b-256 checksum How to use checksums |
50401c2c71a507f581e5545f45bf672827d5466e70b487c12a3d3dcba6aadc5d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.7
|