diff --git a/.changeset/fuzzy-seas-fix.md b/.changeset/fuzzy-seas-fix.md new file mode 100644 index 00000000..00a8c787 --- /dev/null +++ b/.changeset/fuzzy-seas-fix.md @@ -0,0 +1,5 @@ +--- +'@openai/agents-realtime': patch +--- + +fix: #633 fix a bug where tracingDisabled in realtime config does not work diff --git a/packages/agents-realtime/src/openaiRealtimeBase.ts b/packages/agents-realtime/src/openaiRealtimeBase.ts index 27e093ab..a7144de2 100644 --- a/packages/agents-realtime/src/openaiRealtimeBase.ts +++ b/packages/agents-realtime/src/openaiRealtimeBase.ts @@ -672,7 +672,7 @@ export abstract class OpenAIRealtimeBase * * @param tracingConfig - The tracing config to set. We don't support 'auto' here as the SDK will always configure a Workflow Name unless it exists */ - protected _updateTracingConfig(tracingConfig: RealtimeTracingConfig) { + protected _updateTracingConfig(tracingConfig: RealtimeTracingConfig | null) { if (typeof this.#tracingConfig === 'undefined') { // treating it as default value this.#tracingConfig = null; diff --git a/packages/agents-realtime/src/openaiRealtimeWebRtc.ts b/packages/agents-realtime/src/openaiRealtimeWebRtc.ts index 19d5279b..b822e965 100644 --- a/packages/agents-realtime/src/openaiRealtimeWebRtc.ts +++ b/packages/agents-realtime/src/openaiRealtimeWebRtc.ts @@ -245,7 +245,11 @@ export class OpenAIRealtimeWebRTC if (parsed.type === 'session.created') { this._tracingConfig = parsed.session.tracing; // Trying to turn on tracing after the session is created - this._updateTracingConfig(userSessionConfig.tracing ?? 'auto'); + const tracingConfig = + typeof userSessionConfig.tracing === 'undefined' + ? 'auto' + : userSessionConfig.tracing; + this._updateTracingConfig(tracingConfig); } }); diff --git a/packages/agents-realtime/src/openaiRealtimeWebsocket.ts b/packages/agents-realtime/src/openaiRealtimeWebsocket.ts index d8715a41..3ee85c1c 100644 --- a/packages/agents-realtime/src/openaiRealtimeWebsocket.ts +++ b/packages/agents-realtime/src/openaiRealtimeWebsocket.ts @@ -308,7 +308,11 @@ export class OpenAIRealtimeWebSocket } else if (parsed.type === 'session.created') { this._tracingConfig = parsed.session.tracing; // Trying to turn on tracing after the session is created - this._updateTracingConfig(sessionConfig.tracing ?? 'auto'); + const tracingConfig = + typeof sessionConfig.tracing === 'undefined' + ? 'auto' + : sessionConfig.tracing; + this._updateTracingConfig(tracingConfig); } }); diff --git a/packages/agents-realtime/src/realtimeSession.ts b/packages/agents-realtime/src/realtimeSession.ts index f697e952..6815b38c 100644 --- a/packages/agents-realtime/src/realtimeSession.ts +++ b/packages/agents-realtime/src/realtimeSession.ts @@ -350,6 +350,8 @@ export class RealtimeSession< this.#context, ); + // Realtime expects tracing to be explicitly null to disable it; leaving the previous config + // in place would otherwise continue emitting spans. const tracingConfig: RealtimeTracingConfig | null = this.options .tracingDisabled ? null diff --git a/packages/agents-realtime/test/openaiRealtimeWebsocket.test.ts b/packages/agents-realtime/test/openaiRealtimeWebsocket.test.ts index fa5216ec..c978ad70 100644 --- a/packages/agents-realtime/test/openaiRealtimeWebsocket.test.ts +++ b/packages/agents-realtime/test/openaiRealtimeWebsocket.test.ts @@ -194,6 +194,37 @@ describe('OpenAIRealtimeWebSocket', () => { expect(() => ws.mute(true)).toThrow('Mute is not supported'); }); + it('disables tracing when initial config sets tracing to null', async () => { + const updateSpy = vi.spyOn( + OpenAIRealtimeBase.prototype as any, + '_updateTracingConfig', + ); + const ws = new OpenAIRealtimeWebSocket(); + const connectPromise = ws.connect({ + apiKey: 'ek', + model: 'm', + initialSessionConfig: { + tracing: null, + }, + }); + await vi.runAllTimersAsync(); + await connectPromise; + + lastFakeSocket!.emit('message', { + data: JSON.stringify({ + type: 'session.created', + event_id: 'evt_1', + session: { + tracing: 'auto', + }, + }), + }); + + expect(updateSpy).toHaveBeenCalled(); + const lastCall = updateSpy.mock.calls.at(-1); + expect(lastCall?.[0]).toBeNull(); + }); + it('sendAudio only sends when connected', async () => { const baseSpy = vi.spyOn(OpenAIRealtimeBase.prototype, 'sendAudio'); const ws = new OpenAIRealtimeWebSocket();