diff --git a/.changeset/change-peer-connection.md b/.changeset/change-peer-connection.md new file mode 100644 index 00000000..9304b710 --- /dev/null +++ b/.changeset/change-peer-connection.md @@ -0,0 +1,6 @@ +--- +'@openai/agents-realtime': patch +--- + +Add `changePeerConnection` option to `OpenAIRealtimeWebRTC` allowing interception +and replacement of the created `RTCPeerConnection` before the offer is made. diff --git a/packages/agents-realtime/src/openaiRealtimeWebRtc.ts b/packages/agents-realtime/src/openaiRealtimeWebRtc.ts index 678640f6..a844d0c2 100644 --- a/packages/agents-realtime/src/openaiRealtimeWebRtc.ts +++ b/packages/agents-realtime/src/openaiRealtimeWebRtc.ts @@ -61,6 +61,14 @@ export type OpenAIRealtimeWebRTCOptions = { * @see https://platform.openai.com/docs/guides/realtime#creating-an-ephemeral-token */ useInsecureApiKey?: boolean; + /** + * Optional hook invoked with the freshly created peer connection. Returning a + * different connection will override the one created by the transport layer. + * This is called right before the offer is created and can be asynchronous. + */ + changePeerConnection?: ( + peerConnection: RTCPeerConnection, + ) => RTCPeerConnection | Promise; } & OpenAIRealtimeBaseOptions; /** @@ -158,7 +166,7 @@ export class OpenAIRealtimeWebRTC const connectionUrl = new URL(baseUrl); - const peerConnection = new RTCPeerConnection(); + let peerConnection: RTCPeerConnection = new RTCPeerConnection(); const dataChannel = peerConnection.createDataChannel('oai-events'); this.#state = { @@ -226,6 +234,12 @@ export class OpenAIRealtimeWebRTC })); peerConnection.addTrack(stream.getAudioTracks()[0]); + if (this.options.changePeerConnection) { + peerConnection = + await this.options.changePeerConnection(peerConnection); + this.#state = { ...this.#state, peerConnection }; + } + const offer = await peerConnection.createOffer(); await peerConnection.setLocalDescription(offer); diff --git a/packages/agents-realtime/test/openaiRealtimeWebRtc.test.ts b/packages/agents-realtime/test/openaiRealtimeWebRtc.test.ts index 1a742dc9..a87e310a 100644 --- a/packages/agents-realtime/test/openaiRealtimeWebRtc.test.ts +++ b/packages/agents-realtime/test/openaiRealtimeWebRtc.test.ts @@ -195,4 +195,14 @@ describe('OpenAIRealtimeWebRTC.interrupt', () => { const rtc = new OpenAIRealtimeWebRTC(); expect(() => rtc.sendEvent({ type: 'test' } as any)).toThrow(); }); + + it('allows overriding the peer connection', async () => { + class NewPeerConnection extends FakeRTCPeerConnection {} + const custom = new NewPeerConnection(); + const rtc = new OpenAIRealtimeWebRTC({ + changePeerConnection: async () => custom as any, + }); + await rtc.connect({ apiKey: 'ek_test' }); + expect(rtc.connectionState.peerConnection).toBe(custom as any); + }); });