nandi/oripublic Fork 0
76d62ac0da1600e1c208017584c3fa22e54feaa3
Commits
Clone
git clone https://git.rickub.com/nandi/ori.git
git clone ssh://git@rickub.com/nandi/ori.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

forked from bots-garden/ori

websocket-protocol.md · 103 lines · 4.3 KBmarkdown Blame HistoryRaw
✨ Workspace panel, selectors, previews, desktop app, sandbox template, resizable file tree, light/dark theme 76d62ac k33g yesterday1# Reference: WebSocket protocol
2
3> Neutral, exhaustive description of the messages exchanged between the browser and the ori backend on `GET /ws`. One JSON object per text frame. ACP payloads are relayed verbatim; their shapes are specified by the [Agent Client Protocol](https://agentclientprotocol.com).
4
5## Connection sequence
6
7On every connection the server sends `hello`, then replays the recorded session history (up to 4096 events), then any permission request still awaiting an answer, then live events as they happen.
8
9## Browser → server messages
10
11### `prompt`
12
13Starts a turn.
14
15| Field | Type | Required | Description |
16| --- | --- | --- | --- |
17| `type` | string | yes | `"prompt"` |
18| `text` | string | yes | The user's message. |
19| `attachments` | array | no | Files mentioned with `@` in the text: `{ "path": "<absolute or root-relative path>", "name": "<label>" }`. |
20
21```json
22{ "type": "prompt", "text": "Explain @src/main.go", "attachments": [ { "path": "/work/src/main.go", "name": "src/main.go" } ] }
23```
24
25The server sends the ACP prompt as a `text` content block followed by one `resource_link` block per attachment (`uri: "file://<absolute path>"`, `name` as given, defaulting to the path). Relative paths are joined to the server's `--cwd`; attachments with an empty `path` are dropped. The `@name` mention stays in the text.
26
27### `cancel`
28
29Interrupts the running turn.
30
31| Field | Type | Required | Description |
32| --- | --- | --- | --- |
33| `type` | string | yes | `"cancel"` |
34
35### `permission_response`
36
37Answers a `permission_request`.
38
39| Field | Type | Required | Description |
40| --- | --- | --- | --- |
41| `type` | string | yes | `"permission_response"` |
42| `requestId` | string | yes | The id from the `permission_request` event. |
43| `optionId` | string | one of the two | The chosen ACP permission option. |
44| `cancelled` | boolean | one of the two | `true` dismisses the request without choosing. |
45
46## Server → browser messages
47
48### `hello`
49
50| Field | Type | Description |
51| --- | --- | --- |
52| `sessionId` | string | The ACP session id, empty if no agent is attached. |
53| `turnActive` | boolean | `true` if a turn is currently running. |
54
55### `user_message`
56
57Echo of the prompt that started a turn; also present in replays.
58
59| Field | Type | Description |
60| --- | --- | --- |
61| `text` | string | The user's message. |
62| `attachments` | array | The `attachments` of the prompt, verbatim (absent when there were none). |
63
64### `turn_started` / `turn_ended`
65
66| Field | Type | Description |
67| --- | --- | --- |
68| `stopReason` | string | `turn_ended` only: the ACP stop reason (`end_turn`, `cancelled`, `refusal`, `max_tokens`, `max_turn_requests`). |
69
70### `session_update`
71
72| Field | Type | Description |
73| --- | --- | --- |
74| `update` | object | One raw ACP `SessionUpdate`, discriminated by its `sessionUpdate` field (`agent_message_chunk`, `agent_thought_chunk`, `tool_call`, `tool_call_update`, `plan`, `available_commands_update`, …). |
75
76The SPA renders message and thought chunks, tool calls and the plan, and keeps the `availableCommands` of the last `available_commands_update` for the composer's `/` selector (the mock agent sends one at session start; the Claude Code adapter sends Claude Code's slash commands). Other kinds are ignored.
77
78```json
79{ "type": "session_update", "update": { "sessionUpdate": "agent_message_chunk", "content": { "type": "text", "text": "Hello" } } }
80```
81
82### `permission_request`
83
84| Field | Type | Description |
85| --- | --- | --- |
86| `requestId` | string | Correlates with `permission_response` and `permission_resolved`. |
87| `request` | object | The raw ACP `RequestPermissionRequest` (`toolCall`, `options`). |
88
89### `permission_resolved`
90
91| Field | Type | Description |
92| --- | --- | --- |
93| `requestId` | string | The request that was answered (by any connected client, or cancelled by the agent). |
94
95### `error`
96
97| Field | Type | Description |
98| --- | --- | --- |
99| `message` | string | Human-readable error (`"a turn is already running"`, `"no agent session"`, `"prompt failed: …"`, `"cancel failed: …"`, `"malformed message: …"`, `"unknown message type …"`). |
100
101## Recorded vs transient events
102
103Events replayed to late-joining clients: `user_message`, `turn_started`, `turn_ended`, `session_update`, `permission_resolved`, plus pending `permission_request`s. Not recorded: `hello` (regenerated per connection) and `error` events emitted outside a turn failure.