jeffs-brain/memory
Cross-language memory library for LLM agents. Three SDKs (TypeScript, Go, Python) that all implement the same spec so a brain created by one SDK reads and writes cleanly through another.
Local-first, hosted-optional. Apache-2.0.
SDK matrix
All three SDKs implement the full spec wire surface. The shared HTTP conformance suite sits at 28/29 green across SDKs. Cross-SDK evaluation parity today is the shared daemon surface in exactly three scenarios: ask-basic, ask-augmented, and search-retrieve-only.
Parity caveats
- The Postgres + pgvector adapter (
@jeffs-brain/memory-postgres) is TypeScript-only today. Go and Python use SQLite-backed stores. - Python has no native LongMemEval runner. Full LME replay, judge wiring, and agentic loops live in the Go and TypeScript SDKs; Python is exercised through the shared daemon scenarios only.
Evaluation parity
The shared runner covers those daemon scenarios only. It forwards retrieval mode unchanged and defaults to auto, so each SDK daemon resolves auto to hybrid when embeddings are available or bm25 otherwise. Full LongMemEval replay, replay ingest, and agentic loops stay in the native SDK runners; Go provides the reference memory eval lme run --ingest-mode=replay path. See eval/README.md for the shared verification flow and artefact layout.
Shared daemon scenarios
These are the only cross-SDK daemon scenarios the shared harness verifies:
Parity expectation is explicit:
- The same scenario request body is accepted by the TypeScript, Go, and Python daemons.
ask-basicandask-augmentedexpose the same SSE contract:retrieve,answer_delta*,citation*,done.search-retrieve-onlyexposes the same JSON retrieval contract and is scored from returned retrieval content only.questionDateis forwarded forask-augmentedandsearch-retrieve-onlywhen the dataset row provides it.candidateKandrerankTopNare forwarded onsearch-retrieve-onlywhen the runner flags are non-zero.modeis forwarded unchanged by the runner; each daemon resolvesautolocally.- The native tri-SDK LongMemEval replay run pins
search-retrieve-onlyto replay memory only via actor-side retrieval filters:--actor-scope memory --actor-project <brain-id>. That keeps global memory plus the eval brain's project memory in scope while excluding raw transcript rows. - Model wording can differ. Parity is about protocol, retrieval, and prompt-path behaviour, not byte-identical answers.
What we test
ask-basic: the basic/askrequest and SSE response path, includingretrieve,answer_delta,citation, anddone.ask-augmented: the augmented/askprompt path, includingreaderMode=augmented, temporal anchor forwarding, and the same SSE contract.search-retrieve-only: the/searchJSON contract only. The scorer consumes the returned retrieval content, not a daemon-generated answer.
How we run and compare it
- SDK-local tests pin the scenario contract inside each implementation.
- The shared runner in
eval/runner.pystarts one SDK daemon at a time, runs one scenario per invocation, and writes<output>/<YYYY-MM-DD>/<sdk>.json. - The replay-backed tri-SDK workflow in
eval/scripts/run_tri_lme.shextracts once with Go, starts all three daemons against the same brain, and benchmarkssearch-retrieve-onlyonly. Retrieval happens inside each daemon via/search; the shared augmented reader and judge stay in the Go runner process.
Use a separate --output root per scenario when comparing SDKs on the same day. The runner writes one <sdk>.json per output root and date, so reusing the same output root for a second scenario overwrites the earlier JSON for that SDK.
Verification workflow
- Run the SDK-local regression tests that pin the scenario contract in each implementation.
- Run the shared runner against
ts,go, andpyfor the same scenario. - Inspect the generated run artefacts under
eval/results/for transport, citations, and answer or retrieval-blob shape.
To compare one scenario across all three SDKs, run the shared runner from eval/ once per SDK:
cd eval
uv sync
# Fast offline parity check using a seeded reference brain
for sdk in ts go py; do
uv run python runner.py \
--sdk "$sdk" \
--dataset datasets/smoke.jsonl \
--scorer exact \
--scenario search-retrieve-only \
--mode bm25 \
--brain eval \
--seed-reference-brain \
--output results/smoke-search
done
# Corpus-grounded parity checks, using a populated `eval` brain
for sdk in ts go py; do
OPENAI_API_KEY=sk-... uv run python runner.py \
--sdk "$sdk" \
--dataset datasets/lme.jsonl \
--scorer judge \
--scenario ask-augmented \
--brain eval \
--output results/ask-augmented
done
for sdk in ts go py; do
OPENAI_API_KEY=sk-... uv run python runner.py \
--sdk "$sdk" \
--dataset datasets/lme.jsonl \
--scorer judge \
--scenario search-retrieve-only \
--brain eval \
--output results/search-retrieve-only
done
Compare eval/results/<scenario>/<YYYY-MM-DD>/ts.json, go.json, and py.json for the shared runner, or eval/results/tri-lme-<timestamp>/result-*.json for replay-backed tri-SDK retrieval parity.
Per-SDK regression commands for those scenarios live in the SDK READMEs below.
Quick start
TypeScript
npm i -g @jeffs-brain/memory
memory init
memory ingest ./docs
memory search "question"
Full walkthrough: docs.jeffsbrain.com/getting-started/typescript/.
Go
go install github.com/jeffs-brain/memory/go/cmd/[email protected]
memory version
memory serve --addr 127.0.0.1:18841
Full walkthrough: docs.jeffsbrain.com/getting-started/go/.
Python
pip install jeffs-brain-memory
# or: uv add jeffs-brain-memory
memory init
memory ingest ./docs
memory search "question"
Full walkthrough: docs.jeffsbrain.com/getting-started/python/.
MCP quick start
One command wires jeffs-brain into Claude Code, Claude Desktop, Cursor, Windsurf, and Zed:
npx @jeffs-brain/install
Or register a single host manually against any SDK's MCP wrapper:
# TypeScript
claude mcp add jeffs-brain -- npx -y @jeffs-brain/memory-mcp
# Go
claude mcp add jeffs-brain -- memory-mcp
# Python
claude mcp add jeffs-brain -- uvx jeffs-brain-memory-mcp
Each wrapper exposes the same 11 memory_* tools defined in spec/MCP-TOOLS.md.
Algorithm surface
Every SDK implements the full pipeline:
- Hybrid retrieval: BM25 (SQLite FTS5 or Postgres tsvector) plus vector (sqlite-vec or pgvector) fused with Reciprocal Rank Fusion at
k=60. - Retry ladder: five-rung fallback from quoted to bare-word to single-strongest-term to trigram fuzzy to refresh-and-retry.
- Intent reweight: detected query intent shifts RRF weights between lexical and semantic.
- Cross-encoder rerank: LLM-backed or HTTP-backed reranker over the top candidates (Go ships both modes; TS ships the LLM path).
- Query distill: optional LLM rewrite of noisy input to clean retrieval query. Shipping in Go and TS (opt-in).
- Memory stages: extract, reflect, consolidate, recall with global and project-scoped buffers.
- Knowledge base: markdown, URL, file, and PDF ingest with frontmatter, wikilinks, and compile passes.
- Cross-SDK eval parity:
memory serveis exercised inask-basic,ask-augmented, andsearch-retrieve-only. - Native LongMemEval runners: full replay ingest, judge wiring, and agentic loops are outside the cross-SDK harness.
- Authorisation: every SDK ships a
Providercontract, an in-process RBAC adapter (workspace -> brain -> collection -> document hierarchy withadmin/writer/readerroles anddeny:<role>overrides), aStorewrapper that runs a check on every read/write/delete, and a sibling OpenFGA HTTP adapter. The shared FGA model lives atspec/openfga/.
Repo layout
spec/
openfga/ Canonical OpenFGA authorisation model shared by every SDK adapter
... Language-neutral protocol, storage, algorithms, query DSL, MCP tool contract
sdks/
ts/
memory/ Core TS SDK: store, retrieval, ingestion, query DSL, CLI, acl primitives
memory-postgres/ Postgres + pgvector adapter
memory-openfga/ OpenFGA authorisation adapter
go/
acl/ Authorisation contract, in-process RBAC, Store wrapper
aclopenfga/ OpenFGA HTTP adapter
... Full Go SDK: store/fs|git|mem|http, search, query, retrieval, memory, knowledge, eval/lme, cmd/memory, cmd/memory-mcp
py/
src/jeffs_brain_memory/
acl/ Authorisation contract, in-process RBAC, Store wrapper
acl_openfga/ OpenFGA HTTP adapter
... Full Python SDK: store, search, query, retrieval, rerank, memory, knowledge, ingest, llm, http daemon
mcp/
ts/ @jeffs-brain/memory-mcp (npm)
py/ jeffs-brain-memory-mcp (PyPI)
install/ @jeffs-brain/install, one-shot multi-agent installer
examples/ ts/hello-world and go/hello-world ready-to-run
docs/ Astro Starlight documentation site, Cloudflare Pages ready
eval/ Cross-SDK conformance and evaluation runner (--sdk ts|go|py)
The Go MCP wrapper ships from go/cmd/memory-mcp/. The mcp/go/ folder is reserved for future extraction.
Documentation
Full docs site: docs.jeffsbrain.com.
Topic guides:
- Stores - filesystem, git, in-memory, HTTP, and Postgres backends
- Knowledge - markdown, URL, file, and PDF ingest with frontmatter and wikilinks
- Retrieval - hybrid BM25 plus vector, RRF, retry ladder, intent reweight, rerank
- Memory lifecycle - extract, reflect, consolidate, recall
- Authorisation - in-process RBAC and OpenFGA adapter
- Configuration reference -
memory.config.json, env vars, CLI flags
Links
spec/- protocol, storage, algorithms, MCP tools, query DSL, conformance harnessdocs/- public documentation site (Astro Starlight, Cloudflare Pages)examples/- runnable hello-world per languageeval/- cross-SDK evaluation runner, datasets, and verification workflowinstall/-@jeffs-brain/installorchestratorCONTRIBUTING.md- dev setup, commit style, DCO, PR processSECURITY.md- vulnerability reportingCODE_OF_CONDUCT.md- community standardsNOTICE- bundled third-party components
Licence
Apache-2.0. See LICENSE.