# 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": "", "name": "" }`. | ```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://"`, `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.