@memberjunction/ai-openai 5.40.2 → 5.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -3,4 +3,5 @@ export * from './models/openAIEmbedding.js';
3
3
  export * from './models/embeddingModels.types.js';
4
4
  export * from './models/tts.js';
5
5
  export * from './models/openAIImage.js';
6
+ export * from './models/openAIRealtime.js';
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,0BAA0B,CAAC;AACzC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,cAAc,CAAC;AAC7B,cAAc,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,0BAA0B,CAAC;AACzC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,cAAc,CAAC;AAC7B,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC"}
package/dist/index.js CHANGED
@@ -3,4 +3,5 @@ export * from './models/openAIEmbedding.js';
3
3
  export * from './models/embeddingModels.types.js';
4
4
  export * from './models/tts.js';
5
5
  export * from './models/openAIImage.js';
6
+ export * from './models/openAIRealtime.js';
6
7
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,0BAA0B,CAAC;AACzC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,cAAc,CAAC;AAC7B,cAAc,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,0BAA0B,CAAC;AACzC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,cAAc,CAAC;AAC7B,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC"}
@@ -0,0 +1,269 @@
1
+ import { BaseRealtimeModel, IRealtimeSession, RealtimeSessionParams, RealtimeToolDefinition, RealtimeTranscript, RealtimeToolCall, RealtimeUsage, RealtimeSessionError, RealtimeVoiceOption } from '@memberjunction/ai';
2
+ import { ClientRealtimeSessionConfig } from '@memberjunction/ai';
3
+ import { OpenAI } from 'openai';
4
+ import type { OpenAIRealtimeError } from 'openai/realtime/index';
5
+ import type { RealtimeClientEvent, RealtimeServerEvent } from 'openai/resources/realtime/realtime';
6
+ import type { ClientSecretCreateParams, ClientSecretCreateResponse } from 'openai/resources/realtime/client-secrets';
7
+ /**
8
+ * Minimal connection surface the {@link OpenAIRealtime} driver depends on.
9
+ *
10
+ * This is the **injectable seam** for testing. It is a structural subset of the SDK's
11
+ * `OpenAIRealtimeWebSocket` (which extends `OpenAIRealtimeEmitter`): the driver only ever
12
+ * uses `on`, `off`, `send`, and `close`. Because the driver creates its connection through the
13
+ * overridable {@link OpenAIRealtime.createConnection} method, unit tests subclass the driver and
14
+ * return a fake connection implementing this interface — no network and no real WebSocket.
15
+ */
16
+ export interface IOpenAIRealtimeConnection {
17
+ /**
18
+ * Registers a listener for a server event type (`'event'` for the catch-all firehose).
19
+ *
20
+ * Return type is `void` because the driver never uses the chained return value, even though the
21
+ * SDK's `EventEmitter` returns `this` for chaining. A void-returning method is assignable from a
22
+ * value-returning one, so a real `OpenAIRealtimeWebSocket` still satisfies this interface.
23
+ */
24
+ on(event: 'event', listener: (event: RealtimeServerEvent) => void): void;
25
+ /**
26
+ * Registers a listener for connection errors. The SDK routes BOTH transport-level failures
27
+ * (socket error, unparseable frame, failed send — `error.error` is undefined) and provider
28
+ * `error` server frames (`error.error` carries the payload) through this channel; the driver
29
+ * classifies fatality from that distinction.
30
+ */
31
+ on(event: 'error', listener: (error: OpenAIRealtimeError) => void): void;
32
+ /** Removes a previously-registered listener. See {@link IOpenAIRealtimeConnection.on} re: return type. */
33
+ off(event: 'event', listener: (event: RealtimeServerEvent) => void): void;
34
+ /** Removes a previously-registered error listener. */
35
+ off(event: 'error', listener: (error: OpenAIRealtimeError) => void): void;
36
+ /** Sends a client event to the realtime API. */
37
+ send(event: RealtimeClientEvent): void;
38
+ /** Closes the underlying socket. */
39
+ close(props?: {
40
+ code: number;
41
+ reason: string;
42
+ }): void;
43
+ /**
44
+ * Optional raw WebSocket surface (present on the real `OpenAIRealtimeWebSocket`, which exposes
45
+ * its underlying `socket`). Used solely to detect UNEXPECTED closure — the SDK emitter has no
46
+ * close event of its own. The driver feature-detects; fakes may omit it.
47
+ */
48
+ socket?: {
49
+ addEventListener(type: 'close', listener: () => void): void;
50
+ };
51
+ }
52
+ /**
53
+ * OpenAI implementation of the {@link BaseRealtimeModel} primitive, backed by OpenAI's
54
+ * Realtime API over a WebSocket (`OpenAIRealtimeWebSocket` from the `openai` SDK, v6.18.0).
55
+ *
56
+ * The driver opens a duplex session, configures it (system prompt + tools + optional initial
57
+ * context), and translates the provider's server-event stream into the modality-agnostic
58
+ * {@link IRealtimeSession} contract.
59
+ *
60
+ * **Tool results** complete the tool-call loop: the returned session implements the Core
61
+ * `IRealtimeSession.SendToolResult` contract method, which the agent layer calls after executing a
62
+ * tool to feed its result back to the model. See {@link OpenAIRealtimeSession.SendToolResult}.
63
+ */
64
+ export declare class OpenAIRealtime extends BaseRealtimeModel {
65
+ private _openAI;
66
+ constructor(apiKey: string);
67
+ /** Read-only accessor for the underlying OpenAI SDK client. */
68
+ get OpenAI(): OpenAI;
69
+ /**
70
+ * Creates the realtime connection for a model. Overridable seam for testing.
71
+ *
72
+ * Production returns a real `OpenAIRealtimeWebSocket`. Unit tests override this to return a
73
+ * fake {@link IOpenAIRealtimeConnection} that emits OpenAI-shaped events and captures sends.
74
+ *
75
+ * @param model The provider realtime model id (e.g. `gpt-realtime`).
76
+ * @returns A connection implementing {@link IOpenAIRealtimeConnection}.
77
+ */
78
+ protected createConnection(model: string): IOpenAIRealtimeConnection;
79
+ /**
80
+ * Opens a duplex realtime session, applies the session config, and returns the live handle.
81
+ *
82
+ * @param params Session configuration (model, system prompt, tools, initial context, config bag).
83
+ * @returns A promise resolving to the {@link IRealtimeSession} handle.
84
+ */
85
+ StartSession(params: RealtimeSessionParams): Promise<IRealtimeSession>;
86
+ /**
87
+ * OpenAI supports the client-direct topology: the server mints a short-lived ephemeral
88
+ * client secret that the browser uses to open its OWN connection to OpenAI's Realtime API,
89
+ * while the server still controls the system prompt + tools via the returned SessionConfig.
90
+ */
91
+ get SupportsClientDirect(): boolean;
92
+ /**
93
+ * The voices the OpenAI Realtime API can speak with — used to populate the dev voice picker so two
94
+ * agents in one room can be given distinct voices. Kept in sync with OpenAI's realtime voice set.
95
+ */
96
+ get SupportedVoices(): RealtimeVoiceOption[];
97
+ /**
98
+ * Mints the ephemeral client secret via OpenAI's Realtime client-secrets API. Overridable
99
+ * seam for testing — unit tests return a fake response so no network call is made.
100
+ *
101
+ * @param body The client-secret create request (carries the realtime session config).
102
+ * @returns The OpenAI client-secret create response (token value + expiry + echoed session).
103
+ */
104
+ protected mintClientSecret(body: ClientSecretCreateParams): Promise<ClientSecretCreateResponse>;
105
+ /**
106
+ * Mints an ephemeral, server-scoped realtime session credential for a browser to open its
107
+ * own provider connection (client-direct topology). The server builds the session config
108
+ * (system prompt + tools + model) so it retains control of behavior even though the browser
109
+ * owns the socket.
110
+ *
111
+ * @param params Session configuration (model, system prompt, tools).
112
+ * @returns The minted {@link ClientRealtimeSessionConfig} the browser authenticates + applies.
113
+ */
114
+ CreateClientSession(params: RealtimeSessionParams): Promise<ClientRealtimeSessionConfig>;
115
+ }
116
+ /**
117
+ * Live {@link IRealtimeSession} backed by an {@link IOpenAIRealtimeConnection}.
118
+ *
119
+ * Holds the registered handlers and the single `'event'` listener that fans the provider's
120
+ * server-event stream out to the contract handlers via {@link OpenAIRealtimeSession.dispatch}.
121
+ */
122
+ export declare class OpenAIRealtimeSession implements IRealtimeSession {
123
+ private connection;
124
+ private outputHandler?;
125
+ private transcriptHandler?;
126
+ private toolCallHandler?;
127
+ private interruptionHandler?;
128
+ private usageHandler?;
129
+ private errorHandler?;
130
+ private closeHandler?;
131
+ private eventListener;
132
+ private errorListener;
133
+ /** Set by {@link Close} so a consumer-initiated teardown never reports an "unexpected" close. */
134
+ private closedByConsumer;
135
+ /**
136
+ * Whether a model response is currently in flight. Minimal response tracking that mirrors the
137
+ * client driver's state machine: set on `response.created` (and eagerly whenever this session
138
+ * sends its own `response.create`, so back-to-back local triggers can't race the server event),
139
+ * cleared on `response.done` — which the API emits for every terminal status, including
140
+ * `cancelled` after barge-in, so the flag can never stick. Consumed by
141
+ * {@link OpenAIRealtimeSession.RequestSpokenUpdate} to skip (not collide with) an active
142
+ * response, since the API rejects overlapping `response.create` requests.
143
+ */
144
+ private responseActive;
145
+ constructor(connection: IOpenAIRealtimeConnection);
146
+ /**
147
+ * Applies the initial session config: system prompt + tools via `session.update`, optional initial
148
+ * context as a user message. Called once by {@link OpenAIRealtime.StartSession}.
149
+ *
150
+ * **Deferred to `session.created`.** When `StartSession` returns, the realtime WebSocket is NOT open yet
151
+ * — sending `session.update` synchronously races the handshake and the instructions (the **system
152
+ * prompt + tools**) are silently dropped, so the model runs with NO prompt (no identity, no companion
153
+ * framing). We therefore wait for the server's `session.created` frame — the first event once the socket
154
+ * is open and the session exists, and the canonical moment to configure a realtime session — exactly the
155
+ * point the browser/client-direct path applies its config. Idempotent (a re-emitted `session.created`
156
+ * can't double-apply); the listener removes itself once it fires.
157
+ *
158
+ * @param params The session parameters.
159
+ */
160
+ applyInitialConfig(params: RealtimeSessionParams): void;
161
+ /** @inheritdoc */
162
+ SendInput(chunk: ArrayBuffer): void;
163
+ /** @inheritdoc */
164
+ RegisterTools(tools: RealtimeToolDefinition[]): Promise<void>;
165
+ /**
166
+ * @inheritdoc
167
+ *
168
+ * Completes the tool-call loop for OpenAI: sends a `conversation.item.create` with a
169
+ * `function_call_output` item carrying the tool output, then a `response.create` so the model
170
+ * continues the turn with the result in context.
171
+ *
172
+ * @param callID The `CallID` from the originating {@link RealtimeToolCall}.
173
+ * @param output The tool's result as a JSON-stringified string.
174
+ */
175
+ SendToolResult(callID: string, output: string): Promise<void>;
176
+ /**
177
+ * @inheritdoc
178
+ *
179
+ * Injects a **system-role** conversation item (`conversation.item.create`) the model can draw
180
+ * on the next time it speaks, WITHOUT a `response.create` — so no spoken reply is forced.
181
+ *
182
+ * NOTE: the role must be `'system'` — gpt-realtime rejects `'developer'` items ("Developer
183
+ * messages are only supported for quicksilver sessions"); same constraint the client-direct
184
+ * driver hit. Item creation is always safe mid-response on OpenAI, so no collision guard is
185
+ * needed here (unlike {@link OpenAIRealtimeSession.RequestSpokenUpdate}).
186
+ *
187
+ * @param text The context note to append to the conversation.
188
+ */
189
+ SendContextNote(text: string): void;
190
+ /**
191
+ * @inheritdoc
192
+ *
193
+ * Triggers ONE short spoken update via `response.create` with per-response `instructions`.
194
+ *
195
+ * **Collision behavior: skip.** The Realtime API rejects a `response.create` while another
196
+ * response is active, so when {@link responseActive} is set the request is dropped — interim
197
+ * updates are disposable by contract (the next update or the final result supersedes them).
198
+ * When sent, the flag is set eagerly (before the server's `response.created` echo) so two
199
+ * back-to-back local triggers can't both fire.
200
+ *
201
+ * @param instructions Instructions for the single spoken update.
202
+ */
203
+ RequestSpokenUpdate(instructions: string): void;
204
+ /** @inheritdoc */
205
+ OnOutput(handler: (chunk: ArrayBuffer) => void): void;
206
+ /** @inheritdoc */
207
+ OnTranscript(handler: (t: RealtimeTranscript) => void): void;
208
+ /** @inheritdoc */
209
+ OnToolCall(handler: (call: RealtimeToolCall) => void): void;
210
+ /** @inheritdoc */
211
+ OnInterruption(handler: () => void): void;
212
+ /** @inheritdoc */
213
+ OnUsage(handler: (u: RealtimeUsage) => void): void;
214
+ /** @inheritdoc */
215
+ OnError(handler: (error: RealtimeSessionError) => void): void;
216
+ /** @inheritdoc */
217
+ OnClose(handler: () => void): void;
218
+ /** @inheritdoc */
219
+ Close(): Promise<void>;
220
+ /**
221
+ * Routes a provider server event to the matching contract handler. Each branch delegates to a
222
+ * small, single-purpose handler to keep this dispatcher flat.
223
+ *
224
+ * @param event The OpenAI realtime server event.
225
+ */
226
+ private dispatch;
227
+ /** Decodes a base64 audio delta and forwards it to the output handler. */
228
+ private handleAudioDelta;
229
+ /** Emits a transcript event to the transcript handler. */
230
+ private emitTranscript;
231
+ /** Forwards a completed function call to the tool-call handler. */
232
+ private handleFunctionCall;
233
+ /**
234
+ * Notifies the interruption handler of TRUE barge-in only: user speech that cut off an
235
+ * ACTIVE model response. A `speech_started` while the model is idle is just the user taking
236
+ * their normal turn — the {@link IRealtimeSession.OnInterruption} contract explicitly excludes
237
+ * it, so the raw frame is gated on {@link responseActive} (the server-bridged topology's proxy
238
+ * for "model output in flight"). The provider cancels its own turn and emits a terminal
239
+ * `response.done`, which clears the flag.
240
+ */
241
+ private handleInterruption;
242
+ /**
243
+ * Classifies an SDK connection error and forwards it to the error handler. The SDK routes
244
+ * BOTH kinds through its `'error'` emitter: provider `error` server frames carry a payload in
245
+ * `error.error` (recoverable — the session stays open, `Fatal: false`) while transport-level
246
+ * failures (socket error, unparseable frame, failed send) have no payload (`Fatal: true` —
247
+ * including the credential/token-expiry case, which surfaces as a transport teardown).
248
+ */
249
+ private handleConnectionError;
250
+ /**
251
+ * Handles the raw socket closing. A consumer-initiated {@link Close} is expected and silent;
252
+ * anything else (provider hangup, network drop, token death) is surfaced as a FATAL error —
253
+ * so consumers finalize instead of idling on a dead socket — followed by the close handler.
254
+ */
255
+ private handleSocketClose;
256
+ /** Translates a response's usage block into a {@link RealtimeUsage} update. */
257
+ private handleResponseDone;
258
+ /** Sends the `session.update` that establishes instructions, input transcription, and tools. */
259
+ private sendSessionUpdate;
260
+ /** Seeds the conversation with initial context as a user text message. */
261
+ private sendInitialContext;
262
+ /** Maps Core tool definitions up to OpenAI's native function-tool schema (shared mapping). */
263
+ private mapTools;
264
+ /** Encodes a raw media frame as base64 for the provider's append event. */
265
+ private encodeBase64;
266
+ /** Decodes a base64 audio delta into a freshly-allocated `ArrayBuffer`. */
267
+ private decodeBase64;
268
+ }
269
+ //# sourceMappingURL=openAIRealtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openAIRealtime.d.ts","sourceRoot":"","sources":["../../src/models/openAIRealtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,489 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { RegisterClass } from '@memberjunction/global';
11
+ import { BaseRealtimeModel, } from '@memberjunction/ai';
12
+ import { OpenAI } from 'openai';
13
+ import { OpenAIRealtimeWebSocket } from 'openai/realtime/websocket';
14
+ /**
15
+ * The ASR model used to transcribe the USER's audio input. Realtime models accept audio
16
+ * natively, so input transcription is a separate pass that must be opted into — without it only
17
+ * assistant-side transcripts flow. Shared by BOTH topologies ({@link OpenAIRealtime.CreateClientSession}
18
+ * for client-direct and {@link OpenAIRealtimeSession.applyInitialConfig} for server-bridged) so the
19
+ * contract's promise of both-role transcripts holds everywhere.
20
+ */
21
+ const OPENAI_INPUT_TRANSCRIPTION_MODEL = 'gpt-4o-mini-transcribe';
22
+ /**
23
+ * Maps Core {@link RealtimeToolDefinition}s up to OpenAI's native function-tool schema.
24
+ *
25
+ * The single mapping used everywhere a tool set is sent to the Realtime API: the live
26
+ * `session.update` path ({@link OpenAIRealtimeSession.mapTools}) and the client-direct
27
+ * ephemeral-secret path ({@link OpenAIRealtime.CreateClientSession}) both call this so the two
28
+ * topologies expose byte-for-byte identical tool schemas.
29
+ *
30
+ * @param tools The Core tool definitions to map.
31
+ * @returns The OpenAI realtime function-tool array.
32
+ */
33
+ function mapRealtimeTools(tools) {
34
+ return tools.map((tool) => ({
35
+ type: 'function',
36
+ name: tool.Name,
37
+ description: tool.Description,
38
+ parameters: tool.ParametersSchema,
39
+ }));
40
+ }
41
+ /**
42
+ * OpenAI implementation of the {@link BaseRealtimeModel} primitive, backed by OpenAI's
43
+ * Realtime API over a WebSocket (`OpenAIRealtimeWebSocket` from the `openai` SDK, v6.18.0).
44
+ *
45
+ * The driver opens a duplex session, configures it (system prompt + tools + optional initial
46
+ * context), and translates the provider's server-event stream into the modality-agnostic
47
+ * {@link IRealtimeSession} contract.
48
+ *
49
+ * **Tool results** complete the tool-call loop: the returned session implements the Core
50
+ * `IRealtimeSession.SendToolResult` contract method, which the agent layer calls after executing a
51
+ * tool to feed its result back to the model. See {@link OpenAIRealtimeSession.SendToolResult}.
52
+ */
53
+ let OpenAIRealtime = class OpenAIRealtime extends BaseRealtimeModel {
54
+ constructor(apiKey) {
55
+ super(apiKey);
56
+ this._openAI = new OpenAI({ apiKey });
57
+ }
58
+ /** Read-only accessor for the underlying OpenAI SDK client. */
59
+ get OpenAI() {
60
+ return this._openAI;
61
+ }
62
+ /**
63
+ * Creates the realtime connection for a model. Overridable seam for testing.
64
+ *
65
+ * Production returns a real `OpenAIRealtimeWebSocket`. Unit tests override this to return a
66
+ * fake {@link IOpenAIRealtimeConnection} that emits OpenAI-shaped events and captures sends.
67
+ *
68
+ * @param model The provider realtime model id (e.g. `gpt-realtime`).
69
+ * @returns A connection implementing {@link IOpenAIRealtimeConnection}.
70
+ */
71
+ createConnection(model) {
72
+ return new OpenAIRealtimeWebSocket({ model }, this._openAI);
73
+ }
74
+ /**
75
+ * Opens a duplex realtime session, applies the session config, and returns the live handle.
76
+ *
77
+ * @param params Session configuration (model, system prompt, tools, initial context, config bag).
78
+ * @returns A promise resolving to the {@link IRealtimeSession} handle.
79
+ */
80
+ async StartSession(params) {
81
+ const connection = this.createConnection(params.Model);
82
+ const session = new OpenAIRealtimeSession(connection);
83
+ session.applyInitialConfig(params);
84
+ return session;
85
+ }
86
+ /**
87
+ * OpenAI supports the client-direct topology: the server mints a short-lived ephemeral
88
+ * client secret that the browser uses to open its OWN connection to OpenAI's Realtime API,
89
+ * while the server still controls the system prompt + tools via the returned SessionConfig.
90
+ */
91
+ get SupportsClientDirect() {
92
+ return true;
93
+ }
94
+ /**
95
+ * The voices the OpenAI Realtime API can speak with — used to populate the dev voice picker so two
96
+ * agents in one room can be given distinct voices. Kept in sync with OpenAI's realtime voice set.
97
+ */
98
+ get SupportedVoices() {
99
+ return [
100
+ { ID: 'alloy', Name: 'Alloy' },
101
+ { ID: 'ash', Name: 'Ash' },
102
+ { ID: 'ballad', Name: 'Ballad' },
103
+ { ID: 'coral', Name: 'Coral' },
104
+ { ID: 'echo', Name: 'Echo' },
105
+ { ID: 'sage', Name: 'Sage' },
106
+ { ID: 'shimmer', Name: 'Shimmer' },
107
+ { ID: 'verse', Name: 'Verse' },
108
+ ];
109
+ }
110
+ /**
111
+ * Mints the ephemeral client secret via OpenAI's Realtime client-secrets API. Overridable
112
+ * seam for testing — unit tests return a fake response so no network call is made.
113
+ *
114
+ * @param body The client-secret create request (carries the realtime session config).
115
+ * @returns The OpenAI client-secret create response (token value + expiry + echoed session).
116
+ */
117
+ async mintClientSecret(body) {
118
+ return this._openAI.realtime.clientSecrets.create(body);
119
+ }
120
+ /**
121
+ * Mints an ephemeral, server-scoped realtime session credential for a browser to open its
122
+ * own provider connection (client-direct topology). The server builds the session config
123
+ * (system prompt + tools + model) so it retains control of behavior even though the browser
124
+ * owns the socket.
125
+ *
126
+ * @param params Session configuration (model, system prompt, tools).
127
+ * @returns The minted {@link ClientRealtimeSessionConfig} the browser authenticates + applies.
128
+ */
129
+ async CreateClientSession(params) {
130
+ const session = {
131
+ type: 'realtime',
132
+ model: params.Model,
133
+ instructions: params.SystemPrompt,
134
+ };
135
+ if (params.Tools && params.Tools.length > 0) {
136
+ session.tools = mapRealtimeTools(params.Tools);
137
+ }
138
+ // Enable transcription of the user's mic input so BOTH sides of the conversation are
139
+ // captured (live captions + persisted ConversationDetail turns). Realtime models accept
140
+ // audio natively, so input transcription is a separate ASR pass that must be opted into.
141
+ // The OUTPUT voice comes from the effective config's per-provider voice (`params.Config.voice`,
142
+ // shaped by GetProviderVoiceSettings) — this is what lets a co-agent's configured voice OR a
143
+ // per-session override actually take effect in the client-direct topology.
144
+ const voice = params.Config?.voice;
145
+ session.audio = {
146
+ input: { transcription: { model: OPENAI_INPUT_TRANSCRIPTION_MODEL } },
147
+ ...(voice && voice.trim().length > 0 ? { output: { voice: voice.trim() } } : {}),
148
+ };
149
+ const response = await this.mintClientSecret({ session });
150
+ return {
151
+ Provider: 'openai',
152
+ Model: params.Model,
153
+ EphemeralToken: response.value,
154
+ ExpiresAt: new Date(response.expires_at * 1000).toISOString(),
155
+ // The provider-native session config the browser applies verbatim (plain JSON).
156
+ SessionConfig: JSON.parse(JSON.stringify(session)),
157
+ };
158
+ }
159
+ };
160
+ OpenAIRealtime = __decorate([
161
+ RegisterClass(BaseRealtimeModel, 'OpenAIRealtime'),
162
+ __metadata("design:paramtypes", [String])
163
+ ], OpenAIRealtime);
164
+ export { OpenAIRealtime };
165
+ /**
166
+ * Live {@link IRealtimeSession} backed by an {@link IOpenAIRealtimeConnection}.
167
+ *
168
+ * Holds the registered handlers and the single `'event'` listener that fans the provider's
169
+ * server-event stream out to the contract handlers via {@link OpenAIRealtimeSession.dispatch}.
170
+ */
171
+ export class OpenAIRealtimeSession {
172
+ constructor(connection) {
173
+ /** Set by {@link Close} so a consumer-initiated teardown never reports an "unexpected" close. */
174
+ this.closedByConsumer = false;
175
+ /**
176
+ * Whether a model response is currently in flight. Minimal response tracking that mirrors the
177
+ * client driver's state machine: set on `response.created` (and eagerly whenever this session
178
+ * sends its own `response.create`, so back-to-back local triggers can't race the server event),
179
+ * cleared on `response.done` — which the API emits for every terminal status, including
180
+ * `cancelled` after barge-in, so the flag can never stick. Consumed by
181
+ * {@link OpenAIRealtimeSession.RequestSpokenUpdate} to skip (not collide with) an active
182
+ * response, since the API rejects overlapping `response.create` requests.
183
+ */
184
+ this.responseActive = false;
185
+ this.connection = connection;
186
+ this.eventListener = (event) => this.dispatch(event);
187
+ this.connection.on('event', this.eventListener);
188
+ this.errorListener = (error) => this.handleConnectionError(error);
189
+ this.connection.on('error', this.errorListener);
190
+ // The SDK emitter has no close event; detect unexpected closure from the raw socket when
191
+ // the connection exposes it (the real OpenAIRealtimeWebSocket does; fakes may omit it).
192
+ this.connection.socket?.addEventListener('close', () => this.handleSocketClose());
193
+ }
194
+ /**
195
+ * Applies the initial session config: system prompt + tools via `session.update`, optional initial
196
+ * context as a user message. Called once by {@link OpenAIRealtime.StartSession}.
197
+ *
198
+ * **Deferred to `session.created`.** When `StartSession` returns, the realtime WebSocket is NOT open yet
199
+ * — sending `session.update` synchronously races the handshake and the instructions (the **system
200
+ * prompt + tools**) are silently dropped, so the model runs with NO prompt (no identity, no companion
201
+ * framing). We therefore wait for the server's `session.created` frame — the first event once the socket
202
+ * is open and the session exists, and the canonical moment to configure a realtime session — exactly the
203
+ * point the browser/client-direct path applies its config. Idempotent (a re-emitted `session.created`
204
+ * can't double-apply); the listener removes itself once it fires.
205
+ *
206
+ * @param params The session parameters.
207
+ */
208
+ applyInitialConfig(params) {
209
+ let applied = false;
210
+ const applyWhenReady = (event) => {
211
+ if (applied || event.type !== 'session.created') {
212
+ return;
213
+ }
214
+ applied = true;
215
+ this.connection.off('event', applyWhenReady);
216
+ this.sendSessionUpdate(params.SystemPrompt, params.Tools, params.Config);
217
+ if (params.InitialContext && params.InitialContext.length > 0) {
218
+ this.sendInitialContext(params.InitialContext);
219
+ }
220
+ };
221
+ this.connection.on('event', applyWhenReady);
222
+ }
223
+ // ---- IRealtimeSession outbound ----
224
+ /** @inheritdoc */
225
+ SendInput(chunk) {
226
+ this.connection.send({
227
+ type: 'input_audio_buffer.append',
228
+ audio: this.encodeBase64(chunk),
229
+ });
230
+ }
231
+ /** @inheritdoc */
232
+ async RegisterTools(tools) {
233
+ this.connection.send({
234
+ type: 'session.update',
235
+ session: { type: 'realtime', tools: this.mapTools(tools) },
236
+ });
237
+ }
238
+ /**
239
+ * @inheritdoc
240
+ *
241
+ * Completes the tool-call loop for OpenAI: sends a `conversation.item.create` with a
242
+ * `function_call_output` item carrying the tool output, then a `response.create` so the model
243
+ * continues the turn with the result in context.
244
+ *
245
+ * @param callID The `CallID` from the originating {@link RealtimeToolCall}.
246
+ * @param output The tool's result as a JSON-stringified string.
247
+ */
248
+ async SendToolResult(callID, output) {
249
+ const item = {
250
+ type: 'function_call_output',
251
+ call_id: callID,
252
+ output,
253
+ };
254
+ this.connection.send({ type: 'conversation.item.create', item });
255
+ this.connection.send({ type: 'response.create' });
256
+ // This deliberately triggers a response — mark it active eagerly so an interim
257
+ // RequestSpokenUpdate arriving before the server's response.created cannot collide.
258
+ this.responseActive = true;
259
+ }
260
+ /**
261
+ * @inheritdoc
262
+ *
263
+ * Injects a **system-role** conversation item (`conversation.item.create`) the model can draw
264
+ * on the next time it speaks, WITHOUT a `response.create` — so no spoken reply is forced.
265
+ *
266
+ * NOTE: the role must be `'system'` — gpt-realtime rejects `'developer'` items ("Developer
267
+ * messages are only supported for quicksilver sessions"); same constraint the client-direct
268
+ * driver hit. Item creation is always safe mid-response on OpenAI, so no collision guard is
269
+ * needed here (unlike {@link OpenAIRealtimeSession.RequestSpokenUpdate}).
270
+ *
271
+ * @param text The context note to append to the conversation.
272
+ */
273
+ SendContextNote(text) {
274
+ const item = {
275
+ type: 'message',
276
+ role: 'system',
277
+ content: [{ type: 'input_text', text }],
278
+ };
279
+ this.connection.send({ type: 'conversation.item.create', item });
280
+ }
281
+ /**
282
+ * @inheritdoc
283
+ *
284
+ * Triggers ONE short spoken update via `response.create` with per-response `instructions`.
285
+ *
286
+ * **Collision behavior: skip.** The Realtime API rejects a `response.create` while another
287
+ * response is active, so when {@link responseActive} is set the request is dropped — interim
288
+ * updates are disposable by contract (the next update or the final result supersedes them).
289
+ * When sent, the flag is set eagerly (before the server's `response.created` echo) so two
290
+ * back-to-back local triggers can't both fire.
291
+ *
292
+ * @param instructions Instructions for the single spoken update.
293
+ */
294
+ RequestSpokenUpdate(instructions) {
295
+ if (this.responseActive) {
296
+ return;
297
+ }
298
+ this.responseActive = true;
299
+ this.connection.send({ type: 'response.create', response: { instructions } });
300
+ }
301
+ // ---- IRealtimeSession handler registration ----
302
+ /** @inheritdoc */
303
+ OnOutput(handler) {
304
+ this.outputHandler = handler;
305
+ }
306
+ /** @inheritdoc */
307
+ OnTranscript(handler) {
308
+ this.transcriptHandler = handler;
309
+ }
310
+ /** @inheritdoc */
311
+ OnToolCall(handler) {
312
+ this.toolCallHandler = handler;
313
+ }
314
+ /** @inheritdoc */
315
+ OnInterruption(handler) {
316
+ this.interruptionHandler = handler;
317
+ }
318
+ /** @inheritdoc */
319
+ OnUsage(handler) {
320
+ this.usageHandler = handler;
321
+ }
322
+ /** @inheritdoc */
323
+ OnError(handler) {
324
+ this.errorHandler = handler;
325
+ }
326
+ /** @inheritdoc */
327
+ OnClose(handler) {
328
+ this.closeHandler = handler;
329
+ }
330
+ /** @inheritdoc */
331
+ async Close() {
332
+ this.closedByConsumer = true;
333
+ this.connection.off('event', this.eventListener);
334
+ this.connection.off('error', this.errorListener);
335
+ this.connection.close();
336
+ }
337
+ // ---- Inbound event translation ----
338
+ /**
339
+ * Routes a provider server event to the matching contract handler. Each branch delegates to a
340
+ * small, single-purpose handler to keep this dispatcher flat.
341
+ *
342
+ * @param event The OpenAI realtime server event.
343
+ */
344
+ dispatch(event) {
345
+ switch (event.type) {
346
+ case 'response.output_audio.delta':
347
+ return this.handleAudioDelta(event.delta);
348
+ case 'response.output_audio_transcript.delta':
349
+ return this.emitTranscript('assistant', event.delta, false);
350
+ case 'response.output_audio_transcript.done':
351
+ return this.emitTranscript('assistant', event.transcript, true);
352
+ case 'conversation.item.input_audio_transcription.delta':
353
+ return this.emitTranscript('user', event.delta ?? '', false);
354
+ case 'conversation.item.input_audio_transcription.completed':
355
+ return this.emitTranscript('user', event.transcript, true);
356
+ case 'response.function_call_arguments.done':
357
+ return this.handleFunctionCall(event.call_id, event.name, event.arguments);
358
+ case 'input_audio_buffer.speech_started':
359
+ return this.handleInterruption();
360
+ case 'response.created':
361
+ // A response is in flight (whether server-VAD-triggered or locally triggered).
362
+ this.responseActive = true;
363
+ return;
364
+ case 'response.done':
365
+ // Emitted for every terminal status (completed, cancelled, failed) — always clears.
366
+ this.responseActive = false;
367
+ return this.handleResponseDone(event.response.usage);
368
+ default:
369
+ return;
370
+ }
371
+ }
372
+ /** Decodes a base64 audio delta and forwards it to the output handler. */
373
+ handleAudioDelta(deltaBase64) {
374
+ this.outputHandler?.(this.decodeBase64(deltaBase64));
375
+ }
376
+ /** Emits a transcript event to the transcript handler. */
377
+ emitTranscript(role, text, isFinal) {
378
+ this.transcriptHandler?.({ Role: role, Text: text, IsFinal: isFinal });
379
+ }
380
+ /** Forwards a completed function call to the tool-call handler. */
381
+ handleFunctionCall(callId, name, args) {
382
+ this.toolCallHandler?.({ CallID: callId, ToolName: name, Arguments: args });
383
+ }
384
+ /**
385
+ * Notifies the interruption handler of TRUE barge-in only: user speech that cut off an
386
+ * ACTIVE model response. A `speech_started` while the model is idle is just the user taking
387
+ * their normal turn — the {@link IRealtimeSession.OnInterruption} contract explicitly excludes
388
+ * it, so the raw frame is gated on {@link responseActive} (the server-bridged topology's proxy
389
+ * for "model output in flight"). The provider cancels its own turn and emits a terminal
390
+ * `response.done`, which clears the flag.
391
+ */
392
+ handleInterruption() {
393
+ if (!this.responseActive) {
394
+ return;
395
+ }
396
+ this.interruptionHandler?.();
397
+ }
398
+ /**
399
+ * Classifies an SDK connection error and forwards it to the error handler. The SDK routes
400
+ * BOTH kinds through its `'error'` emitter: provider `error` server frames carry a payload in
401
+ * `error.error` (recoverable — the session stays open, `Fatal: false`) while transport-level
402
+ * failures (socket error, unparseable frame, failed send) have no payload (`Fatal: true` —
403
+ * including the credential/token-expiry case, which surfaces as a transport teardown).
404
+ */
405
+ handleConnectionError(error) {
406
+ const isProviderFrame = error.error != null;
407
+ this.errorHandler?.({
408
+ Message: error.message,
409
+ Code: error.error?.code ?? undefined,
410
+ Fatal: !isProviderFrame,
411
+ });
412
+ }
413
+ /**
414
+ * Handles the raw socket closing. A consumer-initiated {@link Close} is expected and silent;
415
+ * anything else (provider hangup, network drop, token death) is surfaced as a FATAL error —
416
+ * so consumers finalize instead of idling on a dead socket — followed by the close handler.
417
+ */
418
+ handleSocketClose() {
419
+ if (this.closedByConsumer) {
420
+ return;
421
+ }
422
+ this.errorHandler?.({ Message: 'OpenAI realtime connection closed unexpectedly', Fatal: true });
423
+ this.closeHandler?.();
424
+ }
425
+ /** Translates a response's usage block into a {@link RealtimeUsage} update. */
426
+ handleResponseDone(usage) {
427
+ if (!usage) {
428
+ return;
429
+ }
430
+ this.usageHandler?.({
431
+ InputTokens: usage.input_tokens ?? 0,
432
+ OutputTokens: usage.output_tokens ?? 0,
433
+ });
434
+ }
435
+ // ---- Config helpers ----
436
+ /** Sends the `session.update` that establishes instructions, input transcription, and tools. */
437
+ sendSessionUpdate(systemPrompt, tools, config) {
438
+ // Pull the host-neutral meeting flag OUT of the open Config bag so it is never sent raw to the API.
439
+ // In a multi-agent meeting the BRIDGE (after its turn policy gates on addressing), not the model,
440
+ // decides WHEN to speak — so we disable server-VAD auto-response while KEEPING detection so input
441
+ // transcription and barge-in still work. A 1:1 call (flag absent) keeps the default auto-response.
442
+ const cfg = { ...(config ?? {}) };
443
+ const disableAutoResponse = cfg.disableAutoResponse === true;
444
+ delete cfg.disableAutoResponse;
445
+ const turnDetection = disableAutoResponse
446
+ ? { type: 'server_vad', create_response: false, interrupt_response: true }
447
+ : undefined;
448
+ const session = {
449
+ type: 'realtime',
450
+ instructions: systemPrompt,
451
+ // Opt into USER input transcription — the same opt-in CreateClientSession applies for
452
+ // the client-direct topology — so user-role transcripts flow server-bridged too (the
453
+ // contract promises BOTH roles). The config bag spreads after this so a
454
+ // per-conversation override can still replace the audio block.
455
+ audio: { input: { transcription: { model: OPENAI_INPUT_TRANSCRIPTION_MODEL }, ...(turnDetection ? { turn_detection: turnDetection } : {}) } },
456
+ ...cfg,
457
+ };
458
+ if (tools && tools.length > 0) {
459
+ session.tools = this.mapTools(tools);
460
+ }
461
+ this.connection.send({ type: 'session.update', session });
462
+ }
463
+ /** Seeds the conversation with initial context as a user text message. */
464
+ sendInitialContext(context) {
465
+ const item = {
466
+ type: 'message',
467
+ role: 'user',
468
+ content: [{ type: 'input_text', text: context }],
469
+ };
470
+ this.connection.send({ type: 'conversation.item.create', item });
471
+ }
472
+ /** Maps Core tool definitions up to OpenAI's native function-tool schema (shared mapping). */
473
+ mapTools(tools) {
474
+ return mapRealtimeTools(tools);
475
+ }
476
+ // ---- Encoding helpers ----
477
+ /** Encodes a raw media frame as base64 for the provider's append event. */
478
+ encodeBase64(chunk) {
479
+ return Buffer.from(chunk).toString('base64');
480
+ }
481
+ /** Decodes a base64 audio delta into a freshly-allocated `ArrayBuffer`. */
482
+ decodeBase64(data) {
483
+ const buffer = Buffer.from(data, 'base64');
484
+ const out = new ArrayBuffer(buffer.byteLength);
485
+ new Uint8Array(out).set(buffer);
486
+ return out;
487
+ }
488
+ }
489
+ //# sourceMappingURL=openAIRealtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openAIRealtime.js","sourceRoot":"","sources":["../../src/models/openAIRealtime.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@memberjunction/ai-openai",
3
3
  "type": "module",
4
- "version": "5.40.2",
4
+ "version": "5.42.0",
5
5
  "description": "MemberJunction Wrapper for OpenAI AI Models",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -21,8 +21,8 @@
21
21
  "typescript": "^5.9.3"
22
22
  },
23
23
  "dependencies": {
24
- "@memberjunction/ai": "5.40.2",
25
- "@memberjunction/global": "5.40.2",
24
+ "@memberjunction/ai": "5.42.0",
25
+ "@memberjunction/global": "5.42.0",
26
26
  "openai": "6.18.0"
27
27
  },
28
28
  "repository": {