セッション
SnaSession と RuntimeSession に分かれる 2 層のセッションモデル。
SnaSession はアプリが扱う永続セッションです。安定した id、ラベル、 cwd、meta を持ちます。RuntimeSession はそのセッションにマウントされる 具体的なランタイム設定です: provider、model、permission mode、MCP サーバ、 hooks。SnaSession 1 つは生涯の中で複数の RuntimeSession を持てます。 runtime chain は、そのセッションに適用されたランタイム設定の順序付き 記録です。
なぜ 2 層か
ユーザーが Claude Code でチャットを始め、スレッド途中で Codex に切り替え、 その後 reasoning レベルを上げた場合、SnaSession は 1 つですが RuntimeSession は 3 つになります。各ブロックのアトリビューションは正確に 保たれ、replay 時には各ランタイムのネイティブ履歴を過去ターンを失わずに 再構築できます。
通常の継続フローは、同じ SnaSession にとどまります。次のターンも
agent.send で送るだけです。SNA がアクティブなランタイムの会話/thread
を維持するため、アプリ側で毎ターン履歴をロードし直したり、
プロンプトキャッシュを設定したりする必要はありません。resume は、
停止したプロセス、明示的な復旧、正規化履歴の再投入が必要なランタイム境界で
使う経路です。
ライフサイクル
POST /agent/sessions → SnaSession 作成 (プロセスなし)
POST /agent/start → 初期 RuntimeSession マウント、プロセス spawn
POST /agent/send → メッセージ送信、イベントストリーム
POST /agent/set-model → インプレース上書き または 新 RuntimeSession
PATCH /agent/session → {cwd, model, permissionMode} 統一 mutator
POST /agent/resume → ランタイムネイティブ履歴を再構築、respawn
POST /agent/restart → 同じ設定で respawn (そのまま保持)
POST /agent/kill → プロセスを止める (セッションレコードは残る)
DELETE /agent/sessions/:id → セッション、履歴、runtime chain、保留中の権限を削除削除は取り消せません。実行中のプロセスがあれば先に停止し、保留中の権限要求は 拒否として処理します。保存済みのチャット/ランタイムレコードも削除され、その後同じ セッションへの呼び出しは no-session または no-active-session エラーを返します。
PATCH 意味論
PATCH /agent/session は統一 mutator。サーバはアクティブな
ランタイムアダプタの applyPatch() フック経由で各フィールドを適用します。
このフックがインプレース適用と respawn-with-history-replay のどちら
を取るかを決めます。
| フィールド | claude-code | codex | opencode | grok / cursor |
|---|---|---|---|---|
model | インプレース | per-turn 上書き | インプレース | respawn + replay |
permissionMode | インプレース | per-turn 上書き | インプレース | インプレース (SNA gate) |
cwd | respawn + replay | インプレース (per-thread cwd) | respawn | respawn + replay |
レスポンスの applied フィールドでどの経路を通ったか分かるため、
クライアントは必要な時だけ "reloading…" のような表示を出せます。
なぜ重要か
ほとんどの「エージェントプラットフォーム」抽象では、設定を変えるたびに セッションを作り直すことになります。SNA は設定をセッションレコードの 一級の軸として扱うため、下層のランタイム設定が変わっても UX は続きます。