Protocol
WebSocket protocol overview — message envelopes, request/response pairs, and error handling.
The daemon communicates with clients over a WebSocket connection at /ws. All messages are JSON objects validated with Zod schemas. Each message has a type field that identifies its kind.
Connection Lifecycle
- Client opens a WebSocket to
ws://host:port/ws. - The daemon assigns a
clientIdand tracks the connection. - Client sends JSON messages (requests). Daemon replies with JSON messages (responses/events).
- On disconnect, the daemon removes the client from all subscriptions.
A health check is available at GET /health, returning { status, uptime, activeRuns, connectedClients }.
Message Envelopes
Every message extends a base envelope.
Client Messages
All client-to-daemon messages include an optional requestId. When provided, the daemon echoes it back on the response so the client can correlate request/response pairs.
{
"type": "ping",
"requestId": "abc-123"
}Daemon Messages
All daemon-to-client messages include a ts field (ISO-8601 timestamp) and an optional requestId echoed from the triggering request.
{
"type": "pong",
"requestId": "abc-123",
"ts": "2025-01-15T10:30:00.000Z"
}Message Pairs Summary
| Client Request | Daemon Response | Pattern |
|---|---|---|
ping | pong | Request/Reply |
prepare_run | run_prepared | Request/Reply |
start_run | strategy_started, strategy_completed, strategy_error | Fire-and-forget + async events |
continue_run | strategy_started, strategy_completed, strategy_error | Fire-and-forget + async events |
stop_run | strategy_error (code: CANCELLED) | Fire-and-forget |
list_strategies | strategy_list | Request/Reply |
list_providers | provider_list | Request/Reply |
get_available_models | available_models | Request/Reply |
subscribe | error (only on failure) | Silent success |
unsubscribe | (none) | Silent |
user_input | error (only if no pending request) | Silent success |
steer_run | steer_queued (or error if not steerable) | Fire-and-forget + async event |
During strategy execution, subscribers receive observation events: step_started, step_completed, agent_output, agent_streaming, and request_input.
Error Handling
The daemon sends an error message for protocol-level failures. Every error includes a machine-readable code and a human-readable message:
{
"type": "error",
"code": "VALIDATION_ERROR",
"message": "Missing required field: strategyPath",
"ts": "2025-01-15T10:30:00.000Z"
}Error Codes
| Code | When |
|---|---|
PARSE_ERROR | Invalid JSON received on the WebSocket |
VALIDATION_ERROR | JSON is valid but fails schema validation |
INTERNAL_ERROR | Unhandled exception in a handler |
NO_PENDING_INPUT | user_input sent but no agent is waiting for input |
SUBSCRIBE_ERROR | subscribe failed (run not found or client not registered) |
EXECUTION_ERROR | Strategy file not found, parse error, or model resolution failure |
PREPARE_FAILED | Strategy or run systems could not be prepared |
START_FAILED | The requested run is unknown or was already started |
CANCELLED | Run was explicitly stopped via stop_run |
RUN_NOT_STEERABLE | steer_run sent for a run that is not found or has already finished |