Session state
A durable key-value store the agent writes with tools — available on catalog agents configured in the dashboard, observed by your client as events.
Long, structured conversations need somewhere to keep progress: which intake questions are answered, what stage the call is in, what the caller already confirmed. Session state is a durable key-value store attached to the session — the agent writes it through tools, the server owns it, and your client observes every change as an event.
Because the server owns the state, it survives things your process doesn't control: transport reconnects, upstream model-session rotations, even continuation into a resumed session.
Enable session state
State is written by a server-side tool pair — cosmo.set_state merges keys, cosmo.view_state lets the agent re-read the current state. The tools come with the agent's server-side configuration: catalog agents whose dashboard setup (Realtime agents) tracks structured call progress have them, and every session running such an agent — including sessions your SDK code launches by agent handle — has them too.
There is no way to enable the state tools on an inline, SDK-configured agent: they have no typed kinds, and generic server-tool references are rejected by the wire protocol with a 422 at connect. If your agent's persona lives in SDK code rather than the catalog, it cannot write session state today. The read path below works for any session in which the tools are active.
Observe changes
Every successful write pushes a cosmo.session-state event to the client with the full state, the updated_keys of this write, any warnings, and stage (hoisted from state["stage"] because "what phase is the call in" is the single most common thing UIs need):
session.on('session_state', ({ state, updatedKeys, stage }) => {
setProgress(stage); // drive a stepper, checklist, or CRM panel
console.log('updated:', updatedKeys);
});TypeScript and Python both decode the state event into a typed class — SessionStateWriteEvent in Python. Swift doesn't classify it yet, so there it arrives on the event stream as unknown rather than erroring.
What it's for — and not for
The following table contrasts what belongs in session state with what belongs elsewhere.
| Use session state for | Use something else for |
|---|---|
| call stage / progress tracking | persona and rules → instructions |
| fields collected during the conversation | procedures → skills |
| driving live UI (steppers, checklists) | actions with side effects → tools |
| handing structured results to post-call processing | long-term memory across users → your own store, written by a client tool |
State is per-session. If you need the values after the call, capture the final cosmo.session-state event (or read the recorded artifacts — see Recording and privacy).