Sagents.Session (Sagents v0.8.0-rc.7)
Copy MarkdownSession lifecycle for conversation-centric agents. Owns the procedural work of: router consult, factory invocation, state seeding, supervisor config, subscriber wiring.
Configuration
Session functions take a config map with the following keys:
:factory_router- module implementingSagents.FactoryRouter.:agent_persistence- module implementingSagents.AgentPersistence.:display_message_persistence- module implementingSagents.DisplayMessagePersistence.:pubsub-{Phoenix.PubSub, name}tuple.:presence_module- Phoenix Presence module.:inactivity_timeout- milliseconds before agent stops on idle.:agent_id_fun- 1-arity function mappingconversation_id→agent_idstring.
Factory contract
Factories implement Sagents.Factory.create_agent/2 taking
(agent_id, config) and returning {:ok, agent, session_opts}. The
router supplies config verbatim — by convention a typed struct from
a paired *Config module. The library recognizes these keys in
session_opts:
:fresh_state_attrs- map seeded intoSagents.State.new!/1on fresh state only (ignored when persisted state is restored). Use this to pre-populate todos, scratchpad data, or any other initial state. For seeding todos:{:ok, agent, fresh_state_attrs: %{todos: my_todos}}:supervisor_opts- keyword list merged into the supervisor_config passed toSagents.AgentsDynamicSupervisor.start_agent_sync/1. Use this for per-factoryAgentSupervisor/AgentServerconfiguration such as:message_preprocessoror any other supervisor-level opt. The library does NOT inspect the contents — keys are forwarded verbatim, so factories can pass anything the supervisor accepts (including future additions) without requiring a library change.
All other keys in session_opts are app-internal; the library plumbs
them through but does not inspect them.
Summary
Functions
Ensure the agent session for state.conversation_id is running and
that the calling process is subscribed to its events.
Whether an agent session is currently running for conversation_id.
Starts (or returns the existing) agent session for a conversation.
Stop the agent session for a conversation. No-op if nothing is running.
Types
Functions
@spec ensure_running(config(), state_map :: map(), opts :: keyword()) :: {:ok, %{sagents_subs: map(), agent_id: String.t()}} | {:error, term()}
Ensure the agent session for state.conversation_id is running and
that the calling process is subscribed to its events.
state is the host's process-level map (LiveView socket assigns,
GenServer state, etc.). Required keys:
:conversation_id:current_scope
Optional keys:
:sagents_subs(defaults to%{}) — existingSagents.Subscribersubs map.
Per-request data destined for the FactoryConfig flows through opts,
not the state map:
:request_opts— keyword list forwarded verbatim to the router as its third argument. The router converts this to a map and passes it to your*Config.from_inputs/1. Use this for per-call fields like:timezone,:tool_context, or anything else your Config consumes.
Returns {:ok, %{sagents_subs: new_subs, agent_id: agent_id}} for the
caller to merge back into its state map.
Whether an agent session is currently running for conversation_id.
@spec start(config(), conversation_id :: term(), opts :: keyword()) :: {:ok, session_info()} | {:error, term()}
Starts (or returns the existing) agent session for a conversation.
Idempotent: if an agent is already running for conversation_id, returns
the existing session info without consulting the router or factory again.
Options
:scope— Phoenix scope (forwarded to factory + persistence).:request_opts— keyword list passed to the router as the third argument. Routers commonly forward this verbatim intofactory_opts.:initial_subscribers— list of{channel, pid}tuples seeded as subscribers before the agent'sinit/1returns. Use to atomically start-and-subscribe.
Stop the agent session for a conversation. No-op if nothing is running.