Skip to main content
This guide accompanies software-agent-sdk #5013. The API is unreleased. Publish this guide with the SDK release containing that change.
Use ConversationEventStream when your browser application already manages conversation state and needs event frames and connection lifecycle callbacks. The TypeScript client lives in clients/typescript in the software-agent-sdk repository. It owns the wire protocol for both local and Docker conversations; your application owns rendering and workflow decisions. The existing WebSocketCallbackClient uses this same transport and remains the typed-event interface used by RemoteConversation; no migration is needed for its callers.

Subscribe To Events

Import the transport from the secondary clients entrypoint. Supply the Agent Server base URL, conversation ID, and session credential from your connection configuration. Keep any reverse-proxy path prefix in the base URL.
The example assumes your application supplies the connection values, handleEvent, and renderConnectionState. Call send only after the connection is open, such as from a user action enabled by state.isConnected. Authentication is the first frame sent after the socket opens, before onOpen is called. Credentials never appear in the URL. Passing credentials in URL user information or a session_api_key query parameter is rejected.

Replay And Connection State

After loading history over REST, use queryParams: { resend_mode: 'since', after_timestamp: lastTimestamp } to replay from a known timestamp. Deduplicate events in application state because replay can overlap existing history. The transport delivers frames through onMessage and retains no history. onStateChange reports isConnected, isReconnecting, attemptCount, and error. onOpen, onClose, and onError expose connection lifecycle events. Reconnects use exponential backoff from one second to a 30-second base delay, plus up to 30% jitter. A successful connection resets the attempt counter. Stalled handshakes close after 10 seconds. updateOptions refreshes callbacks and future authentication without reconnecting. Call reconnect() to replace the connection immediately and reset its retry budget. stop() cancels both handshake and reconnect timers and closes the socket. Late events from replaced sockets cannot change the active connection. send() throws while disconnected. Applications that queue messages while a conversation starts can fall back to ConversationClient.sendEvent over REST. The transport uses a Web-standard global WebSocket when started and has no Node-specific imports. Environments without that API may supply createWebSocket: (url) => socket; the typed callback client retains its existing Node WebSocket adapter.