Durable Ecto/Postgres persistence adapter — the opt-in alternative to the default
ephemeral Agentix.Persistence.ETS. Passes the same Agentix.PersistenceConformance
suite, so callers cannot tell the two apart.
Wiring
config :agentix, :persistence, {Agentix.Persistence.Ecto, repo: MyApp.Repo}The host owns the Repo and runs the migration (mix agentix.gen.migration, then
mix ecto.migrate). Agentix.Persistence.adapter/0 drops the opts, so the adapter
reads its :repo straight from the application env.
jsonb key form
Postgres jsonb round-trips as string-keyed maps. The ETS adapter keeps the
atom-keyed maps it is handed, and the conformance suite pins an atom form for the two
places Agentix semantically needs atoms — a tool result (%{ok: …}) and the
fsm_state cache. This adapter decodes exactly those known shapes back to atoms on
read; free-form blobs (event.content, tool args, summary content, conversation
settings) stay string-keyed, which is their canonical persisted form (Codec output).
Expiry
schedule_expiry/3 / cancel_expiry/2 are backed by Oban, so a scheduled expiry lives
in the database and survives the agent being killed (a per-agent timer would not). The
agent arms one on every suspension alongside its in-process timer and cancels it on
resolution, so a pending HITL call still expires after a crash. Oban is an optional
dependency of this adapter only; if it is absent, durable expiry degrades to a no-op
(with a one-time warning) and the in-process timeout still applies.