Implement WebSocketClient for receiving real-time plan update events from a CleverAgents server via WebSocket connection: - Plan update subscription with reconnect/exponential backoff - Event schema for plan status, progress, and log stream updates - Heartbeat/ping handling that resets reconnect counter - Resume from last event ID on reconnect - Event version negotiation - Event de-duplication by event_id via LRU-bounded EventDeduplicator - Ordered delivery guarantees with thread-safe callback dispatch - Configurable reconnect backoff parameters (base, max, max_reconnects) - ConnectionState model tracking lifecycle state - websockets library added to pyproject.toml dependencies - Behave scenarios (16 scenarios, 62 steps) - Robot Framework smoke tests - ASV benchmark for message handling baseline - Reference documentation at docs/reference/server_websocket.md ISSUES CLOSED: #337
1.9 KiB
Server WebSocket Client
The WebSocketClient receives real-time plan update events from a
CleverAgents server over a WebSocket connection. It supports automatic
reconnection with exponential backoff, heartbeat handling, resume from
last event ID, and event de-duplication.
Event Types
| Event type | Description |
|---|---|
plan.status |
Plan lifecycle status change (e.g. running → completed) |
plan.progress |
Progress percentage or phase update |
plan.log |
Log stream entry from the server |
heartbeat |
Server heartbeat ping (resets reconnect counter) |
Reconnect Policy
When the connection drops the client reconnects automatically using exponential backoff. Parameters are configurable:
| Parameter | Default | Description |
|---|---|---|
backoff_base |
1.0 |
Base delay in seconds |
backoff_max |
30.0 |
Maximum delay in seconds |
max_reconnects |
10 |
Maximum reconnect attempts before giving up |
Successful heartbeat reception resets the reconnect attempt counter.
Resume from Last Event ID
On reconnect the client sends the last received event_id to the
server so that missed events can be replayed. This ensures no updates
are lost during transient disconnections.
Event De-duplication
The EventDeduplicator tracks recently seen event_id values in an
LRU-bounded set. Duplicate events (same event_id received more than
once) are silently dropped.
Event Version Negotiation
The client sends its supported event schema version at connection time.
If the server returns an incompatible version the connection is rejected
with a ServerVersionMismatchError.
Usage
from cleveragents.client.ws_client import WebSocketClient
ws = WebSocketClient(
base_url="wss://server.example.com",
api_token="tok_...",
)
def on_event(event):
print(event["event_type"], event.get("data"))
ws.subscribe("PLAN001", on_event)
# Later:
ws.close()