Skip to content

Commit 39aa7e5

Browse files
ryanlchanRyan Chan
authored andcommitted
feat: remove registerGlobals and use shim-based createAudioElement
- Remove registerGlobals() call from React Native shim - Add createAudioElement() function to all shims (browser, RN, node, workers) - Update openaiRealtimeWebRtc.ts to use shimmed createAudioElement - Prevents global scope pollution in React Native environments Addresses maintainer feedback preferring approach 2 from PR openai#193
1 parent 7617703 commit 39aa7e5

File tree

6 files changed

+55
-21
lines changed

6 files changed

+55
-21
lines changed

.tool-versions

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
nodejs 22.14.0

packages/agents-realtime/src/openaiRealtimeWebRtc.ts

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
isBrowserEnvironment,
55
mediaDevices as shimMediaDevices,
66
RTCPeerConnection as RTCPeerConnectionCtor,
7+
createAudioElement,
78
} from '@openai/agents-realtime/_shims';
89
import {
910
RealtimeTransportLayer,
@@ -25,23 +26,23 @@ import { HEADERS } from './utils';
2526
*/
2627
export type WebRTCState =
2728
| {
28-
status: 'disconnected';
29-
peerConnection: undefined;
30-
dataChannel: undefined;
31-
callId: string | undefined;
32-
}
29+
status: 'disconnected';
30+
peerConnection: undefined;
31+
dataChannel: undefined;
32+
callId: string | undefined;
33+
}
3334
| {
34-
status: 'connecting';
35-
peerConnection: RTCPeerConnection;
36-
dataChannel: RTCDataChannel;
37-
callId: string | undefined;
38-
}
35+
status: 'connecting';
36+
peerConnection: RTCPeerConnection;
37+
dataChannel: RTCDataChannel;
38+
callId: string | undefined;
39+
}
3940
| {
40-
status: 'connected';
41-
peerConnection: RTCPeerConnection;
42-
dataChannel: RTCDataChannel;
43-
callId: string | undefined;
44-
};
41+
status: 'connected';
42+
peerConnection: RTCPeerConnection;
43+
dataChannel: RTCDataChannel;
44+
callId: string | undefined;
45+
};
4546

4647
/**
4748
* The options for the OpenAI Realtime WebRTC transport layer.
@@ -88,8 +89,7 @@ export type OpenAIRealtimeWebRTCOptions = {
8889
*/
8990
export class OpenAIRealtimeWebRTC
9091
extends OpenAIRealtimeBase
91-
implements RealtimeTransportLayer
92-
{
92+
implements RealtimeTransportLayer {
9393
#url: string;
9494
#state: WebRTCState = {
9595
status: 'disconnected',
@@ -260,7 +260,7 @@ export class OpenAIRealtimeWebRTC
260260
// set up audio playback
261261
if (isBrowserEnvironment()) {
262262
const audioElement =
263-
this.options.audioElement ?? document.createElement('audio');
263+
this.options.audioElement ?? createAudioElement();
264264
audioElement.autoplay = true;
265265
peerConnection.ontrack = (event) => {
266266
audioElement.srcObject = event.streams[0];

packages/agents-realtime/src/shims/shims-browser.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,10 @@ export const RTCSessionDescription = globalThis.RTCSessionDescription;
1212
export const MediaStream = globalThis.MediaStream;
1313
export const MediaStreamTrack = globalThis.MediaStreamTrack;
1414
export const mediaDevices = navigator.mediaDevices;
15+
16+
/**
17+
* Creates an audio element for browser environments.
18+
*/
19+
export const createAudioElement = (): HTMLAudioElement => {
20+
return document.createElement('audio');
21+
};

packages/agents-realtime/src/shims/shims-node.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,11 @@ export const MediaStream =
1515
export const MediaStreamTrack =
1616
undefined as unknown as typeof globalThis.MediaStreamTrack;
1717
export const mediaDevices = undefined as unknown as MediaDevices;
18+
19+
/**
20+
* Creates an audio element for Node environments.
21+
* Returns undefined as Node.js doesn't support audio playback.
22+
*/
23+
export const createAudioElement = (): HTMLAudioElement => {
24+
return undefined as unknown as HTMLAudioElement;
25+
};

packages/agents-realtime/src/shims/shims-react-native.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,8 @@ import {
55
MediaStream,
66
MediaStreamTrack,
77
mediaDevices,
8-
registerGlobals,
98
} from 'react-native-webrtc';
109

11-
registerGlobals();
12-
1310
export const WebSocket = global.WebSocket;
1411
export const isBrowserEnvironment = (): boolean => false;
1512
export const useWebSocketProtocols = true;
@@ -22,3 +19,16 @@ export {
2219
MediaStreamTrack,
2320
mediaDevices,
2421
};
22+
23+
/**
24+
* Creates an audio element for React Native.
25+
* Returns a mock object with the minimal interface needed for audio playback.
26+
*/
27+
export const createAudioElement = (): HTMLAudioElement => {
28+
// React Native doesn't use HTML audio elements.
29+
// Audio playback is handled through the RTCPeerConnection's ontrack event.
30+
return {
31+
autoplay: true,
32+
srcObject: null,
33+
} as unknown as HTMLAudioElement;
34+
};

packages/agents-realtime/src/shims/shims-workerd.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,11 @@ export const MediaStream =
1515
export const MediaStreamTrack =
1616
undefined as unknown as typeof globalThis.MediaStreamTrack;
1717
export const mediaDevices = undefined as unknown as MediaDevices;
18+
19+
/**
20+
* Creates an audio element for Cloudflare Workers.
21+
* Returns undefined as Workers don't support audio playback.
22+
*/
23+
export const createAudioElement = (): HTMLAudioElement => {
24+
return undefined as unknown as HTMLAudioElement;
25+
};

0 commit comments

Comments
 (0)