SNA

Sessions

SnaSession plus RuntimeSession chain. The two-layer session model.

A SnaSession is the persistent thing the consumer app knows about (stable id, label, cwd, meta). A RuntimeSession is one specific runtime configuration mounted on that session: provider, model, permission mode, MCP servers, hooks. A SnaSession can mount many RuntimeSessions over its lifetime; the runtime chain is the ordered history of every config the session has worn.

Why two layers

If a user starts a chat on Claude Code, switches to Codex mid-thread, then bumps the reasoning level, that's three distinct RuntimeSessions on one SnaSession. Attribution stays honest per row, and replay can rebuild each runtime's native history without losing prior turns.

The usual continuation path stays on the same SnaSession: call agent.send again. SNA keeps the active runtime conversation/thread attached, so the app does not reload history or configure prompt caching on each turn. resume is for stopped processes, explicit recovery, or a runtime boundary that needs canonical replay.

Lifecycle

POST /agent/sessions      → create SnaSession (no process)
POST /agent/start         → mount initial RuntimeSession, spawn process
POST /agent/send          → send message, events flow
POST /agent/set-model     → in-place override OR new RuntimeSession
PATCH /agent/session      → unified mutator for {cwd, model, permissionMode}
POST /agent/resume        → rebuild runtime-native history, respawn
POST /agent/restart       → respawn with same config (kept verbatim)
POST /agent/kill          → tear down process (session record stays)
DELETE /agent/sessions/:id → drop session, history, runtime chain, pending permission

Deletion is final. If a process is alive, SNA stops it first; any pending permission request is resolved as denied, persisted chat/runtime rows are deleted, and later calls for that session return no-session or no-active-session errors.

PATCH semantics

PATCH /agent/session is the unified mutator. The server applies each field through the active runtime adapter's applyPatch() hook, which decides in-place vs respawn-with-history-replay:

Fieldclaude-codecodexopencodegrok / cursor
modelin-placeper-turn overridein-placerespawn + replay
permissionModein-placeper-turn overridein-placein-place (SNA gate)
cwdrespawn + replayin-place (per-thread cwd)respawnrespawn + replay

The response's applied field tells you which path was taken so clients can show a "reloading…" affordance only when needed.

Why this matters

Most "agent platform" abstractions force the user to tear down a session to change anything. SNA treats config as a first-class axis of the session record, so the UX can stay continuous even as the underlying runtime configuration mutates.

On this page