Conversation
Add IVS (Interactive Video Service) as an alternative transport to WebRTC. Users select transport via `transport: "ivs"` in connect options — both paths return the same RealTimeClient interface. New files: transport-manager.ts (shared interface), ivs-connection.ts, ivs-manager.ts. Updated client.ts for transport selection, methods.ts to accept the shared interface, and WebRTCManager to implement it. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add transport dropdown (WebRTC/IVS) to the test page. When IVS is selected, the IVS Web Broadcast SDK is loaded from CDN. The chosen transport is passed to client.realtime.connect(). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The bouncer's IVS handler waits for `ivs_joined` as the first client message after sending `ivs_stage_ready`. The message pump (which handles set_image/prompt) only starts after `ivs_joined` is received. Sending set_image before the stage handshake caused the bouncer to read it instead of `ivs_joined`, rejecting with "Expected ivs_joined message". Fix: reorder IVS connection phases so stage setup completes first, then send initial image/prompt once the bouncer's message pump is running. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The IVS SDK's StageStrategy callbacks take (participant) not (stage, participant). This caused TypeError: Cannot read properties of undefined (reading 'isLocal'). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
IVS SDK v1.14.0 does not pass participant to shouldPublishParticipant or shouldSubscribeToParticipant. Use argument-free callbacks instead: - publish: always true (only called for local publish-eligible participants) - subscribe: always AUDIO_VIDEO (subscribe to all remote streams) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
SDK uses pnpm — package-lock.json was generated by mistake. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
| }; | ||
|
|
||
| this.ws?.addEventListener("message", handler); | ||
| }); |
There was a problem hiding this comment.
Race condition: ivs_stage_ready lost during SDK loading
High Severity
In setupIVSStages, await getIVSBroadcastClient() is called first (line 241), and only after it resolves is the addEventListener("message", handler) registered to listen for ivs_stage_ready (line 268). During SDK loading, ws.onmessage is already active and routes messages to handleMessage(), which silently drops ivs_stage_ready (it has no handler for it, as noted in the comment on line 388). If the server sends ivs_stage_ready before the SDK finishes loading, the message is consumed and lost, causing the connection to hang until the "IVS stage ready timeout" fires.
Additional Locations (1)
| emitOrBuffer("error", classifyWebrtcError(error)); | ||
| }, | ||
| customizeOffer: options.customizeOffer as ((offer: RTCSessionDescriptionInit) => Promise<void>) | undefined, | ||
| vp8MinBitrate: 300, |
There was a problem hiding this comment.
WebRTC error classifier misclassifies IVS transport errors
Medium Severity
The onError callback passes IVS transport errors through classifyWebrtcError, which maps unrecognized errors to WEBRTC_SIGNALING_ERROR by default. IVS-specific errors (e.g., from stage setup failures) have nothing to do with WebRTC signaling, producing misleading error codes that could confuse consumers relying on the code field for error handling logic.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add transport-aware subscribe flow so viewers can watch IVS sessions without consuming inference server resources (SFU handles fan-out). - Add optional transport field to subscribe token encoding - Add subscribeIVS path: fetches viewer token from bouncer, creates subscribe-only IVS stage - Export getIVSBroadcastClient and IVSBroadcastModule for reuse Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
| serverPort: number, | ||
| transport?: "webrtc" | "ivs", | ||
| ): string { | ||
| return btoa(JSON.stringify({ sid: sessionId, ip: serverIp, port: serverPort, transport })); |
There was a problem hiding this comment.
Token validation rejects valid IVS subscribe tokens
High Severity
decodeSubscribeToken validates !payload.ip || !payload.port for all tokens, but IVS subscribe tokens don't need ip or port (only sid is used by subscribeIVS). If the IVS server sends server_port: 0 or server_ip: "" in its session_id message (reasonable since these WebRTC-specific fields are irrelevant for IVS), the truthiness check fails (!0 and !"" are both true), throwing "Invalid subscribe token" and completely breaking the IVS subscribe flow.
Additional Locations (1)
| reject(new Error("WebSocket is not open")); | ||
| } | ||
| }); | ||
| } |
There was a problem hiding this comment.
Duplicated connection logic across IVS and WebRTC classes
Medium Severity
IVSConnection and WebRTCConnection contain near-identical implementations of setImageBase64, sendInitialPrompt, send, setState, and common handleMessage logic (error, prompt_ack, set_image_ack, generation_started, generation_tick, generation_ended, session_id handling). These are copied line-for-line with only the message type parameter differing. A shared base class or extracted utility functions would reduce the maintenance burden and risk of divergence during future bug fixes.
Additional Locations (1)
The realtime client's baseUrl is a WebSocket URL (wss://), but the IVS subscribe endpoint is an HTTP GET. Convert the protocol before calling fetch. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>


Summary
Add IVS (Interactive Video Service) as an alternative transport for real-time inference, alongside the existing WebRTC transport. Users select transport via
transport: "ivs"option onrealtime.connect().New files
ivs-connection.ts— Low-level IVS connection using AWS IVS Web Broadcast SDK (publish + subscribe stages)ivs-manager.ts— Manager with retry/reconnect logic (parallel towebrtc-manager.ts)transport-manager.ts— Shared interface implemented by both WebRTC and IVS managersModified files
client.ts—transport?: "webrtc" | "ivs"option on connect, routes to appropriate managermethods.ts— AcceptRealtimeTransportManagerinterface instead ofWebRTCManagerdirectlytypes.ts— AddIvsStageReadyMessage,IvsJoinedMessagemessage typesdiagnostics.ts— Addivs-stage-setupconnection phasewebrtc-connection.ts/webrtc-manager.ts— ImplementRealtimeTransportManagerinterfacepackage.json— Add@aws/ivs-web-broadcastas optional peer dependencyUsage
IVS SDK can be loaded via npm (
@aws/ivs-web-broadcast) or CDN script tag (falls back toglobalThis.IVSBroadcastClient).Test plan
npm test)npx tsc --noEmit)index.html)🤖 Generated with Claude Code
Note
Medium Risk
Adds a new realtime transport path and refactors the connect/subscribe flow to route through transport managers, which can affect connection setup, error handling, and token compatibility. WebRTC remains default, but the new IVS dependency loading and stage setup introduces additional runtime paths to validate.
Overview
Adds IVS (AWS Interactive Video Service) as an alternative to WebRTC for
realtime.connect(), controlled via a newtransport: "webrtc" | "ivs"option (defaulting to WebRTC).Introduces an IVS transport implementation (
IVSConnection/IVSManager) with dynamic loading of@aws/ivs-web-broadcast, updates realtime methods to use a sharedRealtimeTransportManagerinterface, and extends subscribe token encoding/decoding to carry the selected transport (plus an IVS subscribe path).Updates the SDK test page and the React Vite example to allow selecting transport (including loading the IVS SDK from CDN in the test page), and marks
@aws/ivs-web-broadcastas an optional peer dependency.Written by Cursor Bugbot for commit 33ffd89. This will update automatically on new commits. Configure here.