Skip to content

Latest commit

 

History

140 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

raven

Epistemological memory for AI agents — a knowledge graph where every belief carries a derivation chain back to ground-truth observations, confidence is derived from graph structure rather than asserted, and beliefs are tested, violated, or confirmed as new evidence lands.

raven is the successor to pantainos-memory (Cloudflare Workers + D1 + Vectorize, TypeScript), rebuilt as a Python MCP service on Postgres + pgvector with pluggable embeddings. The v1 implementation is preserved on the v1-cloudflare-archive branch.

How it works

The core loop: remembering is cheap, believing is earned. Writing to memory just records raw text; a background worker later reads the surrounding graph and proposes how the new memory connects to what's already known — and a single gate function is the only thing allowed to mutate the graph.

flowchart TD
    A[agent calls <b>remember</b>] --> B[persist raw text + embed<br/><i>no graph decisions yet</i>]
    B --> Q[(job queue)]
    Q --> W[enrichment worker claims job,<br/>builds context pack from the graph]
    W --> LLM[agent proposes ops<br/>observe · derive · link · predict · verdict · merge]
    LLM --> G{<b>apply_proposal</b><br/>the only writer}
    G -->|valid| KG[(knowledge graph)]
    G -->|reject| Q
    KG --> R[<b>recall</b> / ask / surprising<br/>beliefs + derived confidence]
Loading

Proposals use a closed vocabulary — an op can say "this thought derives from those observations" but can never assert a number. Confidence, counters, and centrality are all computed in code from the graph's edges.

Which brings up the trust question — not all memories are equal:

flowchart TD
    R[reality<br/>market data · news · tools · humans]
    R -->|source| O["<b>observations</b><br/>ground truth, frozen once written<br/>trust ≈ source quality"]
    O -->|derive| T["<b>thoughts</b><br/>derived from other memories<br/>trust inherited via edges"]
    T -->|derive| T
    T -->|+ deadline| P["<b>predictions</b><br/>resolve correct/incorrect on deadline<br/>→ track record per source"]
    T -->|dream lane| F["<b>framings</b><br/>perspectives & theses<br/>synthesized over clusters"]
    E[new evidence] -->|confirms / violates| T
    T -.->|violations cascade<br/>to downstream beliefs| T
Loading

So when an agent recalls, it doesn't just get similar text back — it gets beliefs with a pedigree: what each one is derived from, how much of its foundation still stands, and how well its sources have scored before.

Design

v2 rebuilds the write path around loose ingest + one apply gate:

  • remember is loose ingest — persist the raw text, embed it, enqueue an enrichment job. No graph decisions at write time.
  • A queue-driven enrichment worker claims jobs (SKIP LOCKED, with park/fail/dead lanes), builds a codified context pack from the surrounding graph, and runs an agent that proposes mutations.
  • The gate is the only writer. Proposals use a closed op vocabulary (gate/ops.py); only gate/apply.py:apply_proposal turns them into graph mutations. Every number — confidence, counters, centrality — is derived in code from edges; no op can name one, and tests/test_vocabulary.py asserts that property mechanically.
  • Everything is tenanted. Composite PKs and hash partitioning make untenanted queries physically impossible.

A dream lane consolidates further: a gardener enqueues reframe clusters and a dreamer worker synthesizes higher-level framings from them.

Stack

  • Python, FastMCP — streamable-http on port 3005
  • Postgres + pgvector (asyncpg)
  • Embeddings via a pluggable EmbeddingProvider: Ollama (default), TEI, or any hosted OpenAI-compatible API
  • LLM judge + enrichment runner are pluggable; a deterministic FixtureRunner backs the zero-LLM end-to-end tests

Layout

raven/
├── PLAN.md                  # migration plan
├── backend/
│   ├── src/raven/
│   │   ├── mcp_server.py    # FastMCP + tool registration
│   │   ├── gate/            # op vocabulary + the single apply gate
│   │   ├── workers/         # enrich, exposure, dispatch, dreamer
│   │   ├── db/              # pool, tenancy, migrations, repo/
│   │   ├── embeddings/      # provider protocol + ollama/tei/hosted
│   │   ├── services/ usecases/ tools/
│   ├── migrations/          # append-only, numbered SQL
│   └── tests/               # need a real pgvector Postgres (see below)
└── infra/

Running locally

docker run -d --name memory-pg -p 5432:5432 \
  -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=raven \
  pgvector/pgvector:pg16

cd backend
uv sync
POSTGRES_URL=postgres://postgres:postgres@localhost:5432/raven \
  uv run raven-migrate
POSTGRES_URL=postgres://postgres:postgres@localhost:5432/raven \
  uv run raven

Embeddings default to an Ollama endpoint (EMBED_URL, EMBED_MODEL=embeddinggemma); see CLAUDE.md for the full env table and hosted-provider fallback.

Tests

docker run -d --name memtest-pg -p 5433:5432 \
  -e POSTGRES_PASSWORD=testpass -e POSTGRES_DB=memtest \
  pgvector/pgvector:pg16

cd backend
POSTGRES_TEST_URL=postgres://postgres:testpass@127.0.0.1:5433/memtest \
  uv run pytest tests/ -q

Tests skip without a reachable pgvector Postgres. The acceptance test (tests/test_e2e_t1.py) runs remember → worker → enriched graph end-to-end with zero LLM calls.

History

  • v1 — pantainos-memory: Cloudflare Workers + D1 + Vectorize. Archived on v1-cloudflare-archive.
  • v2 (this) — Postgres + pgvector, loose ingest + gated writes. Canonical design doc: pantainos-memory-v2-proposal.md in the cassandra-stack architecture docs.

About

raven — epistemological memory for AI agents. Knowledge graph with derivation chains, gated writes, and confidence earned from evidence. Python + Postgres/pgvector MCP service; successor to pantainos-memory.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages