Memory for AI agents,
in the Postgres you already run.
pgmem gives long-running agents durable, temporal memory — and keeps what they're doing now cleanly apart from what should outlive it. No new datastore. No vector service. Just Postgres.
session = await mem.session.create(group_id="acme", user_id="u_123")
# read memory → build the prompt (the only work on the turn)
ctx = await session.compile_context(query=user_text)
reply = await your_model(ctx.messages)
# write memory → after you've replied
await session.add_turn(role="assistant", content=reply)
await session.compact_async() # summarize off the turnThe memory layer for agents that have to remember, reason, and continue.
Runs in your Postgres
Schema, vectors, and full-text in the database you already operate. No graph DB, no memory service to sync.
Execution state vs memory
The hard boundary that stops an old session's half-finished reasoning from resurfacing as fact.
A five-tier model
Working, execution, episodic, semantic, and narrative memory — each with a clear job and lifetime.
Bi-temporal & auditable
Corrections add history instead of erasing it. Ask what’s true now, or what the agent knew back then.
Built for voice
Only retrieval rides the response path. Formation, compaction, and promotion all run off the turn.
Bring your own model
Adapters for OpenAI, Anthropic, and Ollama — or implement two small protocols for anything else.
Six levels of memory, grouped by what they are.
That grouping is the whole idea — it decides whether something is reused, retrieved, or fetched fresh. Get it right and stale memory simply can't happen.
Explore the five-tier model# observe an event the agent owns
await session.observe(
subject=SubjectRef(kind="customer", identifier=user_id),
predicate="billing.plan", value="annual",
authority=Authority.user, evidence=[turn_evidence],
)
# fetch state someone else owns — never store it
sub = await stripe.subscriptions.retrieve(id)
ctx = await session.compile_context(
query=q, injected_context=[sub.status],
)Read memory. Reply. Write memory.
Only compile_context runs on the response path — pure indexed reads, no LLM call. Everything heavy happens after you've replied, so a voice agent never pauses to think about its memory.
Give your agent a memory that lasts.
Install the SDK, apply the schema to your Postgres, and run your first memory-backed agent in minutes.