1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
# Référence : protocole WebSocket
> Description neutre et exhaustive des messages échangés entre le navigateur et le backend ori sur `GET /ws`. Un objet JSON par trame texte. Les payloads ACP sont relayés tels quels ; leurs formes sont spécifiées par l'[Agent Client Protocol](https://agentclientprotocol.com).
## Séquence de connexion
À chaque connexion, le serveur envoie `hello`, puis rejoue l'historique enregistré de la session (jusqu'à 4096 événements), puis toute demande de permission encore en attente de réponse, puis les événements au fil de l'eau.
## Messages navigateur → serveur
### `prompt`
Démarre un tour.
| Champ | Type | Requis | Description |
| --- | --- | --- | --- |
| `type` | chaîne | oui | `"prompt"` |
| `text` | chaîne | oui | Le message de l'utilisateur. |
| `attachments` | tableau | non | Fichiers mentionnés avec `@` dans le texte : `{ "path": "<chemin absolu ou relatif à la racine>", "name": "<libellé>" }`. |
```json
{ "type": "prompt", "text": "Explique @src/main.go", "attachments": [ { "path": "/travail/src/main.go", "name": "src/main.go" } ] }
```
Le serveur envoie le prompt ACP sous forme d'un bloc de contenu `text` suivi d'un bloc `resource_link` par pièce jointe (`uri: "file://<chemin absolu>"`, `name` tel que fourni, par défaut le chemin). Les chemins relatifs sont joints au `--cwd` du serveur ; les pièces jointes au `path` vide sont écartées. La mention `@name` reste dans le texte.
### `cancel`
Interrompt le tour en cours.
| Champ | Type | Requis | Description |
| --- | --- | --- | --- |
| `type` | chaîne | oui | `"cancel"` |
### `permission_response`
Répond à une `permission_request`.
| Champ | Type | Requis | Description |
| --- | --- | --- | --- |
| `type` | chaîne | oui | `"permission_response"` |
| `requestId` | chaîne | oui | L'identifiant reçu dans l'événement `permission_request`. |
| `optionId` | chaîne | l'un des deux | L'option de permission ACP choisie. |
| `cancelled` | booléen | l'un des deux | `true` écarte la demande sans choisir. |
## Messages serveur → navigateur
### `hello`
| Champ | Type | Description |
| --- | --- | --- |
| `sessionId` | chaîne | L'identifiant de session ACP, vide si aucun agent n'est attaché. |
| `turnActive` | booléen | `true` si un tour est en cours. |
### `user_message`
Écho du prompt qui a démarré un tour ; présent aussi dans les rejeux.
| Champ | Type | Description |
| --- | --- | --- |
| `text` | chaîne | Le message de l'utilisateur. |
| `attachments` | tableau | Les `attachments` du prompt, tels quels (absent s'il n'y en avait pas). |
### `turn_started` / `turn_ended`
| Champ | Type | Description |
| --- | --- | --- |
| `stopReason` | chaîne | `turn_ended` uniquement : la raison d'arrêt ACP (`end_turn`, `cancelled`, `refusal`, `max_tokens`, `max_turn_requests`). |
### `session_update`
| Champ | Type | Description |
| --- | --- | --- |
| `update` | objet | Une `SessionUpdate` ACP brute, discriminée par son champ `sessionUpdate` (`agent_message_chunk`, `agent_thought_chunk`, `tool_call`, `tool_call_update`, `plan`, `available_commands_update`, …). |
La SPA rend les fragments de message et de réflexion, les tool calls et le plan, et conserve les `availableCommands` du dernier `available_commands_update` pour le sélecteur `/` du composer (l'agent mock en envoie un à l'ouverture de session ; l'adaptateur Claude Code envoie les commandes slash de Claude Code). Les autres genres sont ignorés.
```json
{ "type": "session_update", "update": { "sessionUpdate": "agent_message_chunk", "content": { "type": "text", "text": "Bonjour" } } }
```
### `permission_request`
| Champ | Type | Description |
| --- | --- | --- |
| `requestId` | chaîne | Corrèle avec `permission_response` et `permission_resolved`. |
| `request` | objet | La `RequestPermissionRequest` ACP brute (`toolCall`, `options`). |
### `permission_resolved`
| Champ | Type | Description |
| --- | --- | --- |
| `requestId` | chaîne | La demande qui a reçu une réponse (d'un des clients connectés, ou annulée par l'agent). |
### `error`
| Champ | Type | Description |
| --- | --- | --- |
| `message` | chaîne | Erreur lisible (`"a turn is already running"`, `"no agent session"`, `"prompt failed: …"`, `"cancel failed: …"`, `"malformed message: …"`, `"unknown message type …"`). |
## Événements enregistrés vs transitoires
Événements rejoués aux clients qui arrivent en cours de session : `user_message`, `turn_started`, `turn_ended`, `session_update`, `permission_resolved`, plus les `permission_request` en attente. Non enregistrés : `hello` (régénéré à chaque connexion) et les événements `error` émis hors échec d'un tour.
|