pgmem
Getting Started

Quickstart

Create a session, observe a claim, compile context, and end.

In a few lines you'll connect to pgmem, store a durable memory, and watch it come back in the context compiled for the next turn. This uses only the session layer, so it runs against a plain Postgres — no embedder or LLM required.

Prerequisites

  • pgmem installed: the SDK added and the schema applied to your database.
  • Your database connection string available as $DATABASE_URL.

Walk through it

Connect

PgMem.create connects and returns the client. With no providers it still gives you the full session layer (turns, memory, compaction, context).

import asyncio
import os

from pgmem import Authority, Evidence, PgMem, SubjectRef

DSN = os.environ["DATABASE_URL"]   # e.g. postgresql://user:pass@host:5432/db

async def main():
    mem = await PgMem.create(DSN)

Create a session

One session per conversation. It starts with a fresh execution tree; memory is retrieved into it.

    session = await mem.session.create(group_id="acme", user_id="customer-123")
    await session.add_turn(
        role="user",
        content="I'm evaluating the enterprise plan for a July rollout.",
    )

Observe a claim

Record an evidence-backed event the agent may retain. The claim policy uses its authority, evidence, and confidence to decide its lifecycle.

    claim, decision = await session.observe(
        subject=SubjectRef(kind="customer", identifier="customer-123"),
        predicate="rollout.target_month",
        value="July",
        authority=Authority.user,
        confidence=1.0,
        evidence=[Evidence(kind="user_turn", reference="turn-1", authority=Authority.user)],
    )

Compile context

Ask for the context the model should see. compile_context does pure indexed reads under a budget and returns ready-to-send messages plus provenance.

    context = await session.compile_context(query="July rollout")
    for message in context.messages:
        print(f"[{message.role}] {message.content}")
    print("recalled:", [claim.predicate for claim in context.recalled_claims])

The claim you stored comes back in recalled_claims (and as a Memory: line in messages). Episodic recall is full-text, so the query has to share terms with the fact — "July rollout" matches "Customer is targeting a July rollout."

End the session

Sealing the session preserves its state for audit and queues refresh of derived claim projections.

    await session.end()
    await mem.close()

asyncio.run(main())

Verify

Run the script. You should see the user turn, the claim in recalled_claims, and a structured memory line in the compiled messages. A future session can retrieve the active claim within the same scope.

What you just did

You exercised Tiers 1–3: a turn (working memory), a ledger claim (episodic memory), and the context compiler assembling them. You did not touch the semantic graph (Tier 4) — that needs an embedder and LLM.

Next

On this page