WebSocket プロトコル
Request/response op、push チャネル、再接続ルールを整理します。
WebSocket はライブチャネルです。push イベント (assistant delta、ツール 呼び出し、権限要求) と、HTTP API が露出するのと同じ制御 op を、 呼び出しごとの HTTP オーバーヘッドなしで運びます。
エンドポイント
ws://<host>:<port>/wsクライアントは一度接続して、その単一接続上にすべてのセッションを 多重化します。
認証
WebSocket upgrade は保護された HTTP ルートと同じトークンを要求します。
Browser client は任意の upgrade header を設定できないため、TypeScript
client はトークンを ws://<host>:<port>/ws?token=<authToken> として送ります。
Native client は upgrade request に Authorization: Bearer <authToken> または
X-SNA-Token を使うこともできます。
サーバに origin allowlist がある場合、browser WebSocket 接続は許可された
Origin から来る必要があります。トークン失敗は upgrade を 401 で閉じ、
origin 失敗は 403 で閉じます。
ワイヤ形
すべてのメッセージは type と payload を持つ JSON オブジェクトです。
// Client → server
{ "id": "rpc-7", "type": "agent.send", "payload": { "session": "abc", "message": "hi" } }
// Server → client (reply)
{ "id": "rpc-7", "type": "agent.send", "status": "ok", "data": { "queued": true } }
// Server → client (push, id なし)
{ "type": "agent.event", "data": { "session": "abc", "event": { "type": "assistant_delta", "delta": "Hello" } } }id フィールドはクライアントが選ぶ相関トークンです。request/response
ペアには付き、push メッセージには付きません。
制御 op
すべての HTTP ルートには対応する WS op があります:
| WS type | HTTP 等価 |
|---|---|
agent.start | POST /agent/start |
agent.send | POST /agent/send |
agent.interrupt | POST /agent/interrupt |
agent.set-model | POST /agent/set-model |
agent.set-permission-mode | POST /agent/set-permission-mode |
agent.restart | POST /agent/restart |
agent.resume | POST /agent/resume |
agent.kill | POST /agent/kill |
agent.run-once | POST /agent/run-once |
agent.completion | POST /agent/completion |
agent.status | GET /agent/status |
sessions.list | GET /agent/sessions |
sessions.create | POST /agent/sessions |
sessions.update | PATCH /agent/sessions/:id |
sessions.remove | DELETE /agent/sessions/:id |
permission.subscribe | (push チャネル; HTTP 等価なし) |
permission.respond | POST /agent/permission-respond |
Push チャネル
2 つのチャネルは push 専用です:
agent.event: 購読中の全セッションが出す全AgentEventごとに 発生します。agent.subscribeで購読し、agent.unsubscribeで解除します。permission.request: どのセッションがpermission_neededを emit しても発生します。permission.subscribeで購読します。
再接続
接続が切れたらクライアントは再接続して再購読する必要があります。切断中
にバッファされたイベントはセッションごとの ring buffer (デフォルト
1000 件) に残ります。新規 agent.subscribe に ?since=<cursor> を渡せば
replay されます。
なぜ HTTP と WS の両方か
- 順序と ACK には HTTP。 ミューテーションには推論しやすい request/response の契約が必要です。HTTP はこの契約を自然に提供します。
- fanout には WS. 単一接続が N 個のセッションのイベント + 権限 要求を配ります。N 本の SSE ストリームを開くよりはるかに効率的です。
TypeScript クライアントはすべてのミューテーションに HTTP、push
チャネルに WS を使います。片方だけでも動きます (http: true, ws: false は
短命スクリプト用; ws: true, http: false は HTTP が使えない
クライアント用) が、実際のアプリでは両方使う構成が最も自然です。