symfonic.agent.checkpointer¶
checkpointer ¶
Checkpointer factory layer (v7.1.1).
Owns LangGraph checkpointer construction and lifecycle. The agent
Runtime invokes one of these factories during __init__ and
holds the returned BaseCheckpointSaver. No knowledge of
memory-layer internals (e.g. MemoryLayer._graph.backend._pool)
leaks across this boundary.
Architectural note (7.1.1 — Item 2 carryover close):
-
PostgresPoolManager(asyncpg) is used by the graph/vector backends for high-throughput tenant-scoped SQL. asyncpg connections are NOT compatible withlanggraph-checkpoint-postgres, whose_ainternal.get_connectionaccepts onlypsycopg.AsyncConnectionorpsycopg_pool.AsyncConnectionPool. -
PostgresCheckpointerFactorytherefore owns its ownpsycopg_pool.AsyncConnectionPool, built from the same DSN the asyncpg pool uses. The two pools share a database but cannot share connections — this is a deliberate dual-pool design, not a hack.
CheckpointerFactory ¶
Bases: Protocol
Constructs and owns a LangGraph checkpointer.
Implementations own their own connection lifecycle. The agent
Runtime instantiates the factory once, calls build_saver_sync
to obtain the saver for graph.compile(checkpointer=...), then
calls astart() once before the first real invocation. No
knowledge of memory-layer internals leaks across this boundary.
MemoryCheckpointerFactory ¶
Returns a MemorySaver (in-process, non-durable).
Use for unit tests and local development where pause/resume durability
is not required. astart and close are no-ops.
Source code in src/symfonic/agent/checkpointer/factory.py
MongoCheckpointerFactory ¶
MongoCheckpointerFactory(
uri: str,
database: str = "symfonic",
*,
checkpoint_collection_name: str = "checkpoints",
writes_collection_name: str = "checkpoint_writes",
)
Returns a MongoDBSaver backed by a pymongo.MongoClient.
The durable checkpointer for Mongo-backed deployments. Before this
factory existed, a Mongo graph backend had no matching checkpointer, so
the engine fell through to an ephemeral MemorySaver — checkpoints
(interactive resume, durable transcript) died on restart.
Like PostgresCheckpointerFactory's dual-pool design, this owns a
connection distinct from the graph/vector backend: MongoGraphBackend
uses motor's AsyncIOMotorClient for tenant I/O, while
langgraph-checkpoint-mongodb's MongoDBSaver requires a synchronous
pymongo.MongoClient. Its async methods (aput / aget_tuple /
alist) offload the blocking pymongo calls to a thread pool, so it drives
the async graph without blocking the event loop. The two clients share a
database; they do not share connections.
Lifecycle:
build_saver_syncconstructs the client withconnect=False(defers all network I/O and server monitoring) and wraps it inMongoDBSaver— no I/O.astartis a no-op:MongoDBSaverneeds nosetup()(its collections/indexes are created lazily on first write).closecloses the client.
Raises:
| Type | Description |
|---|---|
SymfonicAgentError(code='bad_config')
|
when no URI is provided. |
ImportError
|
when |
Source code in src/symfonic/agent/checkpointer/factory.py
PostgresCheckpointerFactory ¶
Returns an AsyncPostgresSaver backed by psycopg_pool.
Builds and owns its own AsyncConnectionPool. This pool is
DISTINCT from PostgresPoolManager (which is asyncpg-backed and
used for graph/vector I/O); the two pools share a database but do
not share connections.
Lifecycle:
build_saver_syncconstructs the pool withopen=Falseand wraps it inAsyncPostgresSaver— no I/O.astartopens the pool and runssaver.setup()(idempotent CREATE-IF-NOT-EXISTS DDL).closecloses the pool.
Raises:
| Type | Description |
|---|---|
SymfonicAgentError(code='bad_config')
|
when no DSN is provided. |
ImportError
|
when |
Source code in src/symfonic/agent/checkpointer/factory.py
astart
async
¶
Open the pool and run AsyncPostgresSaver.setup() once.
Source code in src/symfonic/agent/checkpointer/factory.py
SqliteCheckpointerFactory ¶
Returns an AsyncSqliteSaver backed by aiosqlite.
Accepts a filesystem path (":memory:" also valid). Holds the
underlying aiosqlite.Connection so close() can release it.
Requires the ask-user extra (aiosqlite +
langgraph-checkpoint-sqlite). A missing dependency raises an
ImportError that explicitly names the extra.