symfonic.agent.middleware.pause_token_store_backends¶
pause_token_store_backends ¶
Database-backed pause-token stores: Postgres and Mongo, plus their DDL.
Split out of :mod:symfonic.agent.middleware.pause_token_store (336 lines
against the 300-line budget). What stayed behind is the PauseTokenStore
protocol and the in-process fallback -- the part with no datastore in it. What
moved here is everything that talks to one: the table and index DDL, the
forward-compatible migration, and the two production implementations that own
them.
pause_token_store re-exports every name below, so from
symfonic.agent.middleware.pause_token_store import PostgresPauseTokenStore
and its siblings are unchanged.
MongoPauseTokenStore ¶
MongoDB-backed atomic store using a unique _id insert.
The Mongo counterpart to :class:PostgresPauseTokenStore. Single-use
redemption is enforced by using the token jti as the document _id:
the first insert_one wins; a concurrent replay hits the unique-_id
constraint and raises DuplicateKeyError -> False. The check is
atomic at the document level, so exactly one caller sees True.
Reuses the graph backend's async motor database (MongoGraphBackend._db)
rather than opening a parallel client — the store only needs one small
collection alongside the tenant graph collections. The checkpointer, by
contrast, needs its own sync pymongo client (see
MongoCheckpointerFactory); this store stays fully async on motor.
Raises:
| Type | Description |
|---|---|
ImportError
|
when |
Source code in src/symfonic/agent/middleware/pause_token_store_backends.py
consume
async
¶
Atomic single-use redemption via unique _id insert.
- First caller:
insert_onesucceeds -> True. - Replay caller: duplicate
_id->DuplicateKeyError-> False.
Source code in src/symfonic/agent/middleware/pause_token_store_backends.py
ensure_schema
async
¶
No-op: single-use is enforced by the unique _id (jti).
Provided for parity with :class:PostgresPauseTokenStore so callers
can invoke it uniformly. Mongo needs no DDL — the _id index is
implicit and unique.
Source code in src/symfonic/agent/middleware/pause_token_store_backends.py
PostgresPauseTokenStore ¶
Postgres-backed atomic store using INSERT ... ON CONFLICT DO NOTHING.
Construction takes the same PostgresPoolManager already used by the
semantic-memory backend so we re-use the existing asyncpg pool rather
than opening a parallel connection. ensure_schema() must be awaited
once at agent boot before the first consume call.
Raises:
| Type | Description |
|---|---|
ImportError
|
when |
Source code in src/symfonic/agent/middleware/pause_token_store_backends.py
consume
async
¶
Atomic single-use redemption.
The query semantics
INSERT ... ON CONFLICT (jti) DO NOTHING RETURNING jti
- First caller: row inserted,
RETURNINGyields the jti -> True. - Replay caller:
ON CONFLICT DO NOTHINGsuppresses the insert,RETURNINGyields nothing -> False.
The check is atomic at the row level; concurrent inserts of the
same jti are serialised by the PRIMARY KEY constraint -- exactly
one wins, the rest see ON CONFLICT.
name defaults to "ask_user" so unchanged callers keep
their semantics. Roadmap Item 9 generic interrupts populate it
with the registered interrupt name (e.g. "approval_required").
Source code in src/symfonic/agent/middleware/pause_token_store_backends.py
ensure_schema
async
¶
Create the consumed-tokens table + index (idempotent).
Called automatically before the first consume if it has not
already run; explicit invocation at agent boot is also supported
for callers that want to surface DDL errors eagerly.