Skip to content

WebSocket

Connect to the incubator WebSocket at ws://localhost:8080/ws for real-time event push.

const ws = new WebSocket('ws://localhost:8080/ws');
ws.onopen = () => console.log('Connected');
ws.onmessage = (e) => {
const msg = JSON.parse(e.data);
handleMessage(msg);
};

Published events from any agent.

{
"type": "event",
"id": 42,
"event_type": "task.complete",
"data": { "task": "auth-module" },
"agent_id": "worker-1",
"timestamp": "2026-02-15T10:30:00Z"
}
{
"type": "state_changed",
"key": "current_phase",
"value": "review",
"agent_id": "worker-1"
}

Response to a dance_call.

{
"type": "dance_result",
"callId": "call-123",
"result": { "success": true, "move": "e2-e4" }
}

Pushed every 10 seconds with telemetry snapshot.

{
"type": "metrics",
"data": {
"totalTokens": 15000,
"totalCost": 0.45,
"agentCount": 3,
"eventCounts": { "llm_call": 42, "tool_call": 18, "guard_scan": 60 }
}
}

Sent after initial event replay completes on connection.

{ "type": "replay_done" }

Control state changes (halt, pause, resume).

{
"type": "control",
"command": "halt",
"reason": "Budget exceeded"
}
{
"type": "publish",
"event": "task.started",
"data": { "task": "auth-module" }
}

Call a dance tool handler.

{
"type": "dance_call",
"tool": "make_move",
"args": { "from": "e2", "to": "e4" },
"agentId": "player-1",
"role": "white",
"callId": "call-123"
}

The callId is returned in the dance_result response for correlation.

Clear all state, events, and claims. Used to restart games/protocols.

{ "type": "reset" }

On connection, the server replays all events since since=0 (configurable). After replay, a replay_done message is sent. Register your message handler before the WebSocket open event resolves to avoid missing events.

const ws = new WebSocket('ws://localhost:8080/ws');
// Register handler BEFORE open fires
ws.onmessage = (e) => {
const msg = JSON.parse(e.data);
if (msg.type === 'replay_done') {
console.log('Caught up with all events');
}
};
  • Drive UI state from WS events, not REST polling. Polling re-renders destroy active DOM elements.
  • Use per-agent event types like turn.player_2 so only the relevant agent wakes.
  • Register handlers before connection to catch replay events.
  • Poll REST as backup only (30s+ interval, silent updates).