Files
roboco/docs/api/websockets.md
T
Renn F 2fb63fed1f docs: add the user-facing MkDocs documentation site
Build a complete user-facing documentation site (MkDocs Material) under docs/, served at roboco.dev/docs via a new gh-pages deploy workflow.

- Sections: Get Started, The Company, the Tour, Operating the Panel, Choosing & Running Models, Cost & Observability, Optional Subsystems, Configure & Deploy, API Reference, Troubleshooting & Security (55 pages).
- mkdocs.yml (Material theme; excludes the agent-facing rag/ corpus, internal scratch, and orphaned stub trees) and .github/workflows/docs.yml (mkdocs gh-deploy to gh-pages).
- Retire the stale root usage.md and deployment.md to redirect stubs into the site.
- Fix the docs tooling: add the pymarkdownlnt dependency + .pymarkdown.json, run serve-docs/lint-docs/fix-docs under the docs extra, add a build-docs strict gate.
- Fix the roboco console-script entry point (cli, not the un-awaited async main).
- README: correct the project-structure tree (optimal.py, alembic) and link the docs site.
2026-06-22 15:53:00 +02:00

4.3 KiB

WebSockets

RoboCo pushes live updates over WebSocket endpoints under /ws, served by the orchestrator (roboco/api/websocket.py) and routed through nginx alongside the REST API. A single in-process ConnectionManager holds per-resource connection sets and broadcasts events to them. The panel consumes all of these through its useWebSocket("/<endpoint>", …) hook — you rarely connect to them directly, but they're the same streams an integrator can subscribe to.

The endpoints

There are four per-resource streams plus one operator-wide stream:

Endpoint Stream Auth
/ws/channels/{channel_id} Live messages in a team channel agent_id query param, validated against the DB + channel access
/ws/agents/{agent_id} An agent's output and lifecycle events viewer_id/agent_id query param, validated against the DB
/ws/sessions/{session_id} Messages in a communication session agent_id query param, validated
/ws/notifications/{agent_id} An agent's notifications agent_id query param, validated
/ws/system Operator/system-wide stream — no per-agent keying Unauthenticated, read-only

All sockets support a ping/pong keepalive: send {"type": "ping"} and you'll get a pong back.

!!! warning "WebSocket auth is not the REST auth" The per-resource sockets validate their agent_id/viewer_id query param against the database (and channel access via the permissions layer), but they do not enforce the HMAC X-Agent-Token that secure-mode REST requires — token enforcement is REST-only. /ws/system is intentionally fully unauthenticated. None of the streams carry a control surface or secrets, so they're read-only by design, but the orchestrator port should be treated as trusted-network-only until WebSocket auth lands. See Authentication and Security.

How events reach the sockets

Server-side events are published to an in-process StreamEventBus. The bridge in roboco/api/websocket_bridge.py subscribes to it and registers a _handle_* forwarder per event type, mapping each EventType to the right socket broadcast.

flowchart LR
    S[Service / orchestrator] -->|publish EventType| B[StreamEventBus]
    B --> WB[websocket_bridge _handle_*]
    WB --> R[/ws/channels, /ws/agents, /ws/sessions, /ws/notifications/]
    WB --> SYS[/ws/system/]
    R --> P[Panel useWebSocket hook]
    SYS --> P

To add a new live event you define an EventType, publish it to the bus, add a _handle_* forwarder in websocket_bridge, and consume it on the panel via the same hook — you never stand up a parallel endpoint.

Event types

Event Arrives on What it carries
RATE_LIMIT_HIT /ws/system A provider just hit a rate limit / overload and was parked. Drives the panel's amber rate-limit banner.
RATE_LIMIT_LIFTED /ws/system A parked provider recovered; queued work resumes. Clears the banner.
USAGE_SNAPSHOT /ws/system A fresh token-usage/cost snapshot. Drives the live "Token Usage & Cost" dashboard.
NOTIFICATION_SENT / NOTIFICATION_ACKED /ws/notifications/{agent_id} A notification was sent to or acknowledged by an agent.
SESSION_CREATED / SESSION_CLOSED / SESSION_TIMEOUT /ws/sessions/{session_id} Communication-session lifecycle.
AGENT_SPAWNED / AGENT_STOPPED / AGENT_WAITING / AGENT_RESUMED / AGENT_ERROR /ws/agents/{agent_id} Agent runtime lifecycle transitions.

Each forwarded message is a JSON object with a type field (the event-type name above) merged with the event's data.

REST fallbacks

The two operator dashboards that ride /ws/system fall back to HTTP polling when the socket is down, so the panel keeps working without the stream:

Live event HTTP fallback
RATE_LIMIT_HIT / RATE_LIMIT_LIFTED GET /api/system/rate-limits
USAGE_SNAPSHOT GET /api/usage/summary?period=24h|7d|30d

See Cost & usage and Health & metrics for what the panel does with these.

Next

  • REST API — the /api/* route map and the error envelope.
  • Authentication — the WebSocket-auth caveat in full.