Protocol
Tyrum uses a typed WebSocket protocol between the gateway, clients, and nodes. The protocol is designed to be:
- Typed: messages are validated against contracts.
- Bidirectional: requests/responses plus server-push events.
- Observable: important state changes emit events.
The canonical wire shapes live in @tyrum/schemas (packages/schemas/src/protocol.ts).
The protocol is the primary interface for:
- interactive chat sessions
- workflow execution progress (runs/steps)
- approvals (requested/resolved) and resume control
- node pairing and capability RPC
Transport
- Primary transport is WebSocket for low-latency, long-lived connectivity.
- Heartbeats detect dead connections and enable safe eviction/reconnect.
Deployment notes (reconnect + dedupe)
The protocol works across gateway restarts and multi-instance deployments:
- Reconnect is normal: clients and nodes should tolerate disconnects and reconnect without violating safety invariants.
- Events are at-least-once: events may be delivered more than once (especially across reconnect). Deduplicate using
event_id. - Requests can be retried: when a peer does not observe a response, it may retry by re-sending the request with the same
request_id(subject to each request type’s idempotency contract). - Durable state is the source of truth: important state transitions must be backed by the StateStore and can be re-derived after reconnect; do not assume in-memory ordering guarantees across reconnects.
Protocol revisions
The handshake includes a protocol_rev integer. A connection is accepted only when the peer and gateway agree on a supported revision.
Revisions allow evolving request types and fields without a major-version bump. The gateway may support multiple revisions concurrently, but it must select a single revision per connection and reject unsupported revisions.
The protocol uses run-scoped identifiers (run_id, step_id, attempt_id) and avoids ambiguous plan identifiers.
Message classes
- Handshake: identifies the connecting device and declares capabilities.
- Requests/Responses: peer-initiated actions that return a typed response.
- Events: gateway-emitted notifications (including server-push progress and lifecycle).