Skip to content

Commit d73eca4

Browse files
a1anfanclaude
andauthored
Add webRtc.iceTransportPolicy session option for WebRTC connections (#934)
* Add rtcConfig session option for WebRTC connections Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Use as const in rtcConfig test Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Replace rtcConfig with webRtc.iceTransportPolicy option Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent fa2d76e commit d73eca4

4 files changed

Lines changed: 49 additions & 1 deletion

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@elevenlabs/client": minor
3+
---
4+
5+
Add an optional `webRtc.iceTransportPolicy` session option for WebRTC connections. Set to `"relay"` to restrict ICE to TURN relay candidates, for networks that drop direct UDP flows, without patching the global `RTCPeerConnection`.

packages/client/src/utils/BaseConnection.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@ export type BaseSessionConfig = {
3131
origin?: string;
3232
authorization?: string;
3333
livekitUrl?: string;
34+
webRtc?: {
35+
/**
36+
* ICE transport policy for the WebRTC connection. Set to "relay" to only
37+
* use TURN relay candidates, e.g. on networks that drop direct UDP flows.
38+
* Defaults to "all".
39+
*/
40+
iceTransportPolicy?: "all" | "relay";
41+
};
3442
overrides?: {
3543
agent?: {
3644
prompt?: ConversationConfigOverrideAgentPrompt;

packages/client/src/utils/WebRTCConnection.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,38 @@ describe("WebRTCConnection", () => {
133133
connection.close();
134134
});
135135

136+
it("passes webRtc.iceTransportPolicy through to room.connect", async () => {
137+
const mockRoom = new Room() as any;
138+
(mockRoom.on as ReturnType<typeof vi.fn>).mockImplementation(
139+
(event: string, callback: () => void) => {
140+
if (event === "connected") {
141+
queueMicrotask(callback);
142+
}
143+
}
144+
);
145+
(mockRoom.once as ReturnType<typeof vi.fn>).mockImplementation(
146+
(event: string, callback: () => void) => {
147+
if (event === "signalConnected") {
148+
queueMicrotask(callback);
149+
}
150+
}
151+
);
152+
153+
const connection = await WebRTCConnection.create({
154+
conversationToken: "test-token",
155+
connectionType: "webrtc",
156+
webRtc: { iceTransportPolicy: "relay" },
157+
});
158+
159+
expect(mockRoom.connect).toHaveBeenCalledWith(
160+
expect.any(String),
161+
"test-token",
162+
{ rtcConfig: { iceTransportPolicy: "relay" } }
163+
);
164+
165+
connection.close();
166+
});
167+
136168
it("reconnects input analyser after unmuting", async () => {
137169
const mockRoom = new Room() as any;
138170

packages/client/src/utils/WebRTCConnection.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,10 @@ export class WebRTCConnection extends BaseConnection {
323323
});
324324

325325
// Connect to the LiveKit room
326-
await room.connect(livekitUrl, conversationToken);
326+
const iceTransportPolicy = config.webRtc?.iceTransportPolicy;
327+
await room.connect(livekitUrl, conversationToken, {
328+
rtcConfig: iceTransportPolicy ? { iceTransportPolicy } : undefined,
329+
});
327330

328331
// Wait for the Connected event to ensure isConnected is true
329332
await new Promise<void>(resolve => {

0 commit comments

Comments
 (0)