pgmem
Concepts

Narrative memory (sagas)

Narrative threads that connect sessions.

A saga is the thread that connects an agent's separate conversations into one ongoing story — a support case, a sales cycle, a project journey. Facts tell you what is true; the saga tells you what's been happening, so a fresh session can pick up the arc instead of just a pile of disconnected facts.

Why it matters

"Can we continue where we left off?" needs more than retrieved facts — it needs the narrative that links them. Three weeks after a first call, the agent should know this is the same opportunity, what's happened across the intervening sessions, and where things stand. The saga (Tier 5) is how that continuity survives across sessions that each start with a fresh execution tree.

The model

A saga is a named narrative, keyed by (name, group_id) (or its uuid), that:

  • links sessions in sequence — each session that belongs to it is appended as the story continues, and
  • carries a rolling summary — an LLM-maintained brief of the arc so far.

It is cross-session memory: it outlives any single conversation and is retrieved into new ones.

How it works

Attach a session to a saga when you create it — by name (created on first use) or by saga_uuid. If the saga already has a summary, it's pinned into the new session, so the very first compile_context is warmed with what happened before:

session = await mem.session.create(
    group_id="acme",
    user_id="customer-123",
    saga="enterprise-opportunity",   # continue/create by (name, group_id)
)
context = await session.compile_context(query="Can we continue where we left off?")
# The saga's narrative is already in context.

At session.end() the session is appended back to its saga, extending the chain. The summary is not auto-generated — you update it explicitly when you want to pay the LLM cost:

await mem.summarize_saga(saga_uuid, group_id)

During a turn, compile_context also recalls other relevant sagas as Tier 5 narrative context (the session's own saga is already pinned). The read surface for sagas — list, get, search — is mem.saga.

Tradeoffs & pitfalls

The saga summary is explicit, not automatic. add_episode and session.end do not regenerate it — call summarize_saga when you want the brief refreshed, so you control when the LLM cost is paid.

  • A saga is the narrative, not the facts. Durable facts still live in the semantic graph (Tier 4); the saga is the connective story over them.
  • Sagas are scoped by group_id (and user, where applicable) — the same tenant boundary as everything else.

On this page