pgmem
Reference

PgMem

The PgMem composition root and its top-level methods.

PgMem is the single composition root: it owns the connection pool and the provider seams, and exposes the graph-ingestion / search surface plus the session and saga namespaces. Construct it once at startup and reuse it.

Construction

mem = await PgMem.create(dsn, embedder=..., llm=...)
# equivalent to:
mem = await PgMem(dsn, embedder=..., llm=...).connect()
# also usable as an async context manager:
async with PgMem(dsn) as mem:
    ...
ParameterTypeDefaultDescription
dsnstrPostgres connection string.
embedderEmbedder | NoneNoneRequired for the semantic graph (Tier 4) and community building. Must be 1536-dim.
llmLLMClient | NoneNonePowers pgmem's internal LLM work (extraction, compaction summaries, saga briefs).
cross_encoderCrossEncoder | NoneNoneOptional reranker; selects the cross-encoder search recipe.
claim_policyClaimPolicy | NoneNoneGoverns claim formation, conflicts, and live-state routing.
tokenizerTokenizer | NoneNoneOverrides the compiler's token counter.
configPgMemConfig | NoneNoneThe full configuration object.

Flat keyword overrides (min_size, max_size, ingest_config, search_config, fulltext_backend, fulltext_language) are also accepted; an explicit kwarg wins over the same field inside config. Providers are not part of config — they are injected directly so config stays pure, loggable data.

Namespaces

AttributeTypeWhat it is
mem.sessionSessionManagerMint session handles — see the Session API.
mem.sagaSagaManagerRead narrative memory: list / get / search.
mem.storeGraphStoreLow-level repositories (advanced/escape hatch).

Methods

async def search(query, group_ids, *, config=None, center_node_uuid=None,
                 bfs_origins=None) -> SearchResults

Hybrid search over the Tier 4 graph (vector + full-text + graph traversal + fusion). config overrides the recipe selected at construction. This is raw graph retrieval — for building a turn's prompt use compile_context instead.

add_episode

async def add_episode(content, group_id, *, name="", source=EpisodeType.message,
                      reference_time=None, entity_types=None, edge_types=None, ...,
                      saga=None, external_facts=None) -> AddEpisodeResult

Extract entities + edges from content and persist them to the graph. Pass external_facts=[ExternalFact(...)] to assert verbatim events with provenance (no LLM extraction) — see Events vs state. Requires an embedder and llm. add_episode_with_metrics(...) is the same call returning a (result, PipelineMetrics) tuple.

add_episode_bulk

async def add_episode_bulk(bulk_episodes, group_id, *, saga=None, ...,
                           external_facts=None) -> AddBulkEpisodeResult

Batch ingestion: per-episode parallel extraction, cross-batch dedup, two transactions. Needs pool.max_size >= 2.

summarize_saga

async def summarize_saga(saga_uuid, group_id) -> SagaNode

Regenerate a saga's narrative brief via the LLM. Explicit — add_episode / session.end never trigger it. group_id is required for tenant isolation.

build_communities

async def build_communities(group_ids=None, *, config=None)
    -> tuple[list[CommunityNode], list[CommunityEdge]]

Wipe-and-rebuild community detection over the named groups (group_ids must be scoped — there is no "all groups"). Requires embedder + llm. Tune with CommunityConfig.

Lifecycle & maintenance

MethodSignaturePurpose
connect() -> PgMemOpen the pool (or use PgMem.create).
close() -> NoneClose the pool.
capabilities() -> dictReport detected DB capabilities (e.g. BM25).
clear_group(group_ids) -> NoneDelete all data for the given tenants.
clear_all() -> NoneDelete everything (tests/dev).
transaction() -> async ctxBorrow a raw connection (advanced).

Notes

add_episode, add_episode_bulk, build_communities, and summarize_saga require both an embedder and an llm, and they do real LLM/embedding work — keep them off the response path. The session/turn/memory/context surface works with no providers at all.

On this page