WebSocket Protocol Reference¶
Echo Agent Gateway exposes one WebSocket for agent sessions and one for Dashboard events.
| Endpoint | Default path | Purpose |
|---|---|---|
| Session | /ws |
Text interaction with the agent |
| Dashboard | /ws/dashboard |
Subscribe to runtime events such as tasks and cron jobs |
The session path is configurable through gateway.ws_path. This page documents only frames accepted or emitted by the current server. Skill, knowledge, and other management operations use the REST API.
Session WebSocket¶
Connection and authentication¶
After the connection is upgraded, send an auth frame within five seconds. The token may be carried by that frame, an upgrade-request header, or the URL query, but the auth frame itself is always required.
{
"type": "auth",
"token": "your-api-token",
"platform": "cli",
"user_id": "alice",
"chat_id": "alice",
"session_key": "cli:alice"
}
| Field | Required | Description |
|---|---|---|
type |
Yes | Must be auth |
token |
By configuration | API or admin token; omit when no tokens are configured |
platform |
No | Client platform; missing or unknown values normalize to ws |
user_id |
By auth mode | User identity |
chat_id |
No | Delivery identity; defaults to user_id |
session_key |
No | Resume a session; ownership is validated by the server |
An upgrade request may instead carry:
The header configured by gateway.auth.token_header is also accepted. The compatibility form ?token= still authenticates, but query values can be retained in access logs, proxy logs, and browser history. Prefer a header or the auth frame in production.
Successful authentication returns:
On failure the server sends an error and closes the socket:
Client frames¶
message¶
Send a plain-text message:
Once queued, the server acknowledges it with an event ID:
accepted means queued, not completed. Empty text is ignored.
interrupt¶
Request cooperative cancellation of the active turn. Include the event_id from its accepted frame when possible so a delayed interrupt cannot affect the next turn.
When queued successfully, the server returns {"type":"accepted"}.
ping¶
The server returns {"type":"pong"}.
Server message frames¶
Agent output uses a common message frame. Stream fragments and completed messages are distinguished by is_final; message_kind and metadata carry generic progress, cognitive-state, and error information.
{
"type": "message",
"event_id": "evt_reply",
"reply_to_id": "evt_abc123",
"channel": "gateway:cli",
"chat_id": "alice",
"text": "Three tasks are complete.",
"is_final": true,
"message_kind": "final",
"edit_message_id": null,
"metadata": {}
}
Common error frames are:
{"type": "error", "error": "authenticate first"}
{"type": "error", "error": "rate limited"}
{"type": "error", "error": "server overloaded"}
{"type": "error", "error": "internal error"}
Dashboard WebSocket¶
After connecting to /ws/dashboard, send an auth frame within five seconds. This endpoint currently reads its token from the frame itself:
The server responds with {"type":"auth_ok"}. Subscribe to event channels afterward:
To unsubscribe:
tasks and cron currently have live event sources. sessions, memory, skills, channels, logs, analytics, and knowledge are reserved subscription names without connected emitters. Unknown names produce subscribe_error.
Broadcasts use a common envelope:
Connection maintenance¶
- The server sends WebSocket control-frame heartbeats at
gateway.ws_heartbeat_seconds, 30 seconds by default. - Clients should reconnect with exponential backoff and jitter.
- Reauthenticate with the original
session_keyto continue using that session. The server has no message-replay protocol. - Reverse-proxy idle timeouts should exceed the heartbeat interval.