@opengeni/sdk 0.52.1 → 1.0.1

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.
Files changed (56) hide show
  1. package/README.md +67 -7
  2. package/dist/artifacts.js +5 -5
  3. package/dist/{chunk-FRJFNDIR.js → chunk-4DV37UUA.js} +6 -2
  4. package/dist/chunk-4DV37UUA.js.map +1 -0
  5. package/dist/{chunk-KIHGPM7H.js → chunk-A5DC5WEM.js} +288 -45
  6. package/dist/chunk-A5DC5WEM.js.map +1 -0
  7. package/dist/{chunk-V5F253OG.js → chunk-GU6JF75T.js} +6 -3
  8. package/dist/chunk-GU6JF75T.js.map +1 -0
  9. package/dist/{chunk-MZWTWOX6.js → chunk-ST5DDKJP.js} +327 -1
  10. package/dist/chunk-ST5DDKJP.js.map +1 -0
  11. package/dist/{chunk-FHI4DFIG.js → chunk-TYZ4JL4J.js} +2 -2
  12. package/dist/{chunk-ILQZR5N6.js → chunk-YGH5P47G.js} +693 -34
  13. package/dist/chunk-YGH5P47G.js.map +1 -0
  14. package/dist/{chunk-DXDL7EEW.js → chunk-YKZME56C.js} +197 -113
  15. package/dist/chunk-YKZME56C.js.map +1 -0
  16. package/dist/client.d.ts +108 -18
  17. package/dist/codex-realtime-controller.d.ts +5 -0
  18. package/dist/codex-realtime-controller.js +2 -2
  19. package/dist/codex-realtime-v3.d.ts +13 -2
  20. package/dist/core.js +7 -7
  21. package/dist/desktop.d.ts +8 -0
  22. package/dist/editable-artifacts.js +4 -4
  23. package/dist/gateway-realtime-transport.d.ts +1 -0
  24. package/dist/gateway-realtime-transport.js +5 -3
  25. package/dist/index.d.ts +6 -2
  26. package/dist/index.js +68 -34
  27. package/dist/index.js.map +1 -1
  28. package/dist/interaction-revision-stream.d.ts +11 -0
  29. package/dist/interaction.d.ts +604 -5
  30. package/dist/interaction.js +27 -1
  31. package/dist/realtime.d.ts +3 -3
  32. package/dist/realtime.js +11 -7
  33. package/dist/realtime.js.map +1 -1
  34. package/dist/types.d.ts +283 -69
  35. package/dist/workspace-live-stream.d.ts +14 -0
  36. package/package.json +2 -2
  37. package/src/client.ts +863 -62
  38. package/src/codex-realtime-controller.ts +239 -12
  39. package/src/codex-realtime-lifecycle.ts +1 -0
  40. package/src/codex-realtime-v3.ts +162 -31
  41. package/src/desktop.ts +11 -1
  42. package/src/errors.ts +16 -2
  43. package/src/gateway-realtime-transport.ts +252 -109
  44. package/src/index.ts +42 -13
  45. package/src/interaction-revision-stream.ts +117 -0
  46. package/src/interaction.ts +1049 -5
  47. package/src/realtime.ts +14 -4
  48. package/src/types.ts +353 -72
  49. package/src/workspace-live-stream.ts +137 -0
  50. package/dist/chunk-DXDL7EEW.js.map +0 -1
  51. package/dist/chunk-FRJFNDIR.js.map +0 -1
  52. package/dist/chunk-ILQZR5N6.js.map +0 -1
  53. package/dist/chunk-KIHGPM7H.js.map +0 -1
  54. package/dist/chunk-MZWTWOX6.js.map +0 -1
  55. package/dist/chunk-V5F253OG.js.map +0 -1
  56. /package/dist/{chunk-FHI4DFIG.js.map → chunk-TYZ4JL4J.js.map} +0 -0
package/src/errors.ts CHANGED
@@ -41,7 +41,9 @@ export class OpenGeniApiError extends Error {
41
41
  this.retryable = options.retryable ?? decoded?.retryable ?? retryableApiStatus(status);
42
42
  this.correlationId = correlationId;
43
43
  this.outcomeUnknown =
44
- options.outcomeUnknown ?? (gatewayFailure && !!options.mutation && !decoded);
44
+ options.outcomeUnknown ??
45
+ decoded?.outcomeUnknown ??
46
+ (gatewayFailure && !!options.mutation && !decoded);
45
47
  this.body = !fromResponse || decoded ? body : "";
46
48
  this.details = decoded?.details;
47
49
  }
@@ -52,6 +54,7 @@ function decodeApiErrorBody(body: string): {
52
54
  message: string | undefined;
53
55
  requestId: string | undefined;
54
56
  retryable: boolean | undefined;
57
+ outcomeUnknown: boolean | undefined;
55
58
  details: Record<string, unknown> | undefined;
56
59
  } | null {
57
60
  if (!body) return null;
@@ -67,13 +70,24 @@ function decodeApiErrorBody(body: string): {
67
70
  const message = boundedApiField(nested.message);
68
71
  const requestId = boundedCorrelationId(nested.requestId);
69
72
  const retryable = typeof nested.retryable === "boolean" ? nested.retryable : undefined;
73
+ const outcomeUnknown =
74
+ typeof nested.outcomeUnknown === "boolean" ? nested.outcomeUnknown : undefined;
70
75
  const details = boundedApiDetails(nested.details);
71
- if (!code && !message && !requestId && retryable === undefined && !details) return null;
76
+ if (
77
+ !code &&
78
+ !message &&
79
+ !requestId &&
80
+ retryable === undefined &&
81
+ outcomeUnknown === undefined &&
82
+ !details
83
+ )
84
+ return null;
72
85
  return {
73
86
  code,
74
87
  message,
75
88
  requestId,
76
89
  retryable,
90
+ outcomeUnknown,
77
91
  details,
78
92
  };
79
93
  } catch {
@@ -9,14 +9,33 @@ type GatewayServerEvent = Record<string, unknown> & { type: string };
9
9
 
10
10
  const AUDIO_SAMPLE_RATE = 24_000;
11
11
  const DELEGATION_TOOL = "delegate_to_session";
12
+ type RealtimeDialect = "gateway" | "xai";
12
13
 
13
14
  export function createGatewayRealtimeTransportStarter(): RealtimeControllerTransportStarter {
15
+ return createWebsocketRealtimeTransportStarter("gateway");
16
+ }
17
+
18
+ export function createXaiSubscriptionRealtimeTransportStarter(): RealtimeControllerTransportStarter {
19
+ return createWebsocketRealtimeTransportStarter("xai");
20
+ }
21
+
22
+ function createWebsocketRealtimeTransportStarter(
23
+ dialect: RealtimeDialect,
24
+ ): RealtimeControllerTransportStarter {
14
25
  return async (input) => {
15
26
  const client = input.client as CodexRealtimeControllerClient;
16
- if (!client.negotiateGatewayRealtime) {
17
- throw new Error("The OpenGeni client does not support AI Gateway realtime");
27
+ const negotiate =
28
+ dialect === "xai"
29
+ ? client.negotiateXaiSubscriptionRealtime?.bind(client)
30
+ : client.negotiateGatewayRealtime?.bind(client);
31
+ if (!negotiate) {
32
+ throw new Error(
33
+ dialect === "xai"
34
+ ? "The OpenGeni client does not support connected SuperGrok realtime"
35
+ : "The OpenGeni client does not support AI Gateway realtime",
36
+ );
18
37
  }
19
- const answer = await client.negotiateGatewayRealtime(
38
+ const answer = await negotiate(
20
39
  input.workspaceId,
21
40
  input.sessionId,
22
41
  {
@@ -32,16 +51,22 @@ export function createGatewayRealtimeTransportStarter(): RealtimeControllerTrans
32
51
  );
33
52
  throwIfAborted(input.signal);
34
53
 
35
- const websocket = new WebSocket(answer.url, [
36
- "ai-gateway-realtime.v1",
37
- `ai-gateway-auth.${answer.token}`,
38
- ]);
54
+ const websocket = new WebSocket(
55
+ answer.url,
56
+ dialect === "xai"
57
+ ? [`xai-client-secret.${answer.token}`]
58
+ : ["ai-gateway-realtime.v1", `ai-gateway-auth.${answer.token}`],
59
+ );
39
60
  const channel = new GatewayRealtimeDataChannel((payload) =>
40
- handleBridgeOutbound(websocket, payload),
61
+ handleBridgeOutbound(websocket, payload, dialect),
41
62
  );
42
63
  input.onEventsCreated(channel.asRtcDataChannel());
43
64
  const audio = new GatewayRealtimeAudio({
44
- onAudio: (encoded) => send(websocket, { type: "input-audio-append", audio: encoded }),
65
+ onAudio: (encoded) =>
66
+ send(websocket, {
67
+ type: dialect === "xai" ? "input_audio_buffer.append" : "input-audio-append",
68
+ audio: encoded,
69
+ }),
45
70
  onAudibleOutputState: input.onAudibleOutputState,
46
71
  });
47
72
  let stopped = false;
@@ -62,8 +87,9 @@ export function createGatewayRealtimeTransportStarter(): RealtimeControllerTrans
62
87
  return;
63
88
  }
64
89
  if (!isRecord(parsed) || typeof parsed.type !== "string") return;
65
- handleGatewayEvent({
90
+ handleRealtimeEvent({
66
91
  event: parsed as GatewayServerEvent,
92
+ dialect,
67
93
  channel,
68
94
  websocket,
69
95
  audio,
@@ -84,56 +110,6 @@ export function createGatewayRealtimeTransportStarter(): RealtimeControllerTrans
84
110
  websocket.addEventListener("close", onClose);
85
111
  websocket.addEventListener("error", onError);
86
112
 
87
- await waitForWebSocketOpen(websocket, input.signal);
88
- channel.open();
89
- send(websocket, {
90
- type: "session-update",
91
- config: {
92
- instructions: answer.instructions,
93
- outputModalities: ["audio"],
94
- inputAudioFormat: { type: "audio/pcm", rate: AUDIO_SAMPLE_RATE },
95
- outputAudioFormat: { type: "audio/pcm", rate: AUDIO_SAMPLE_RATE },
96
- inputAudioTranscription: {},
97
- outputAudioTranscription: {},
98
- turnDetection: {
99
- type: "server-vad",
100
- prefixPaddingMs: 300,
101
- silenceDurationMs: 500,
102
- },
103
- tools: [
104
- {
105
- type: "function",
106
- name: DELEGATION_TOOL,
107
- description:
108
- "Pass execution work, actions, and session tasks to the underlying session agent. Include the complete standalone request and relevant conversational context.",
109
- parameters: {
110
- type: "object",
111
- properties: {
112
- request: {
113
- type: "string",
114
- description: "Complete standalone task for the session agent",
115
- },
116
- },
117
- required: ["request"],
118
- additionalProperties: false,
119
- },
120
- },
121
- ],
122
- },
123
- });
124
- for (const item of answer.initialItems) {
125
- send(websocket, {
126
- type: "conversation-item-create",
127
- item: {
128
- type: "text-message",
129
- role: "user",
130
- text: `<session_initial_item role="${item.role}">\n${item.text}\n</session_initial_item>`,
131
- },
132
- });
133
- }
134
- await audio.startCapture(input.media);
135
- input.onConnectionHealth("connected");
136
-
137
113
  const stop = (): void => {
138
114
  if (stopped) return;
139
115
  stopped = true;
@@ -153,6 +129,41 @@ export function createGatewayRealtimeTransportStarter(): RealtimeControllerTrans
153
129
  };
154
130
  input.signal.addEventListener("abort", stop, { once: true });
155
131
 
132
+ try {
133
+ await waitForWebSocketOpen(websocket, input.signal);
134
+ channel.open();
135
+ send(
136
+ websocket,
137
+ dialect === "xai"
138
+ ? xaiSessionUpdate(answer.instructions)
139
+ : gatewaySessionUpdate(answer.instructions),
140
+ );
141
+ for (const item of answer.initialItems) {
142
+ const text = `<session_initial_item role="${item.role}">\n${item.text}\n</session_initial_item>`;
143
+ send(
144
+ websocket,
145
+ dialect === "xai"
146
+ ? {
147
+ type: "conversation.item.create",
148
+ item: {
149
+ type: "message",
150
+ role: "user",
151
+ content: [{ type: "input_text", text }],
152
+ },
153
+ }
154
+ : {
155
+ type: "conversation-item-create",
156
+ item: { type: "text-message", role: "user", text },
157
+ },
158
+ );
159
+ }
160
+ await audio.startCapture(input.media);
161
+ input.onConnectionHealth("connected");
162
+ } catch (error) {
163
+ stop();
164
+ throw error;
165
+ }
166
+
156
167
  return {
157
168
  peerConnection: null as unknown as RTCPeerConnection,
158
169
  events: channel.asRtcDataChannel(),
@@ -174,8 +185,73 @@ export function createGatewayRealtimeTransportStarter(): RealtimeControllerTrans
174
185
  };
175
186
  }
176
187
 
177
- function handleGatewayEvent(input: {
188
+ function delegationTool(): Record<string, unknown> {
189
+ return {
190
+ type: "function",
191
+ name: DELEGATION_TOOL,
192
+ description:
193
+ "Pass execution work, actions, and session tasks to the underlying session agent. Include the complete standalone request and relevant conversational context.",
194
+ parameters: {
195
+ type: "object",
196
+ properties: {
197
+ request: {
198
+ type: "string",
199
+ description: "Complete standalone task for the session agent",
200
+ },
201
+ },
202
+ required: ["request"],
203
+ additionalProperties: false,
204
+ },
205
+ };
206
+ }
207
+
208
+ function gatewaySessionUpdate(instructions: string): GatewayClientEvent {
209
+ return {
210
+ type: "session-update",
211
+ config: {
212
+ instructions,
213
+ outputModalities: ["audio"],
214
+ inputAudioFormat: { type: "audio/pcm", rate: AUDIO_SAMPLE_RATE },
215
+ outputAudioFormat: { type: "audio/pcm", rate: AUDIO_SAMPLE_RATE },
216
+ inputAudioTranscription: {},
217
+ outputAudioTranscription: {},
218
+ turnDetection: {
219
+ type: "server-vad",
220
+ prefixPaddingMs: 300,
221
+ silenceDurationMs: 500,
222
+ },
223
+ tools: [delegationTool()],
224
+ },
225
+ };
226
+ }
227
+
228
+ function xaiSessionUpdate(instructions: string): GatewayClientEvent {
229
+ return {
230
+ type: "session.update",
231
+ session: {
232
+ instructions,
233
+ voice: "eve",
234
+ reasoning: { effort: "high" },
235
+ turn_detection: {
236
+ type: "server_vad",
237
+ prefix_padding_ms: 300,
238
+ silence_duration_ms: 500,
239
+ },
240
+ audio: {
241
+ input: {
242
+ format: { type: "audio/pcm", rate: AUDIO_SAMPLE_RATE },
243
+ transcription: { model: "grok-transcribe" },
244
+ },
245
+ output: { format: { type: "audio/pcm", rate: AUDIO_SAMPLE_RATE } },
246
+ },
247
+ tools: [delegationTool()],
248
+ },
249
+ };
250
+ }
251
+
252
+ function handleRealtimeEvent(input: {
178
253
  event: GatewayServerEvent;
254
+ dialect: RealtimeDialect;
179
255
  channel: GatewayRealtimeDataChannel;
180
256
  websocket: WebSocket;
181
257
  audio: GatewayRealtimeAudio;
@@ -185,8 +261,10 @@ function handleGatewayEvent(input: {
185
261
  }): void {
186
262
  const event = input.event;
187
263
  const eventId = providerEventId(event);
188
- if (event.type === "session-created") {
189
- const sessionId = stringValue(event.sessionId) ?? `gateway-${crypto.randomUUID()}`;
264
+ if (event.type === "session-created" || event.type === "session.created") {
265
+ const session = isRecord(event.session) ? event.session : null;
266
+ const sessionId =
267
+ stringValue(event.sessionId) ?? stringValue(session?.id) ?? `realtime-${crypto.randomUUID()}`;
190
268
  input.channel.providerEvent({
191
269
  type: "session.started",
192
270
  event_id: eventId,
@@ -194,23 +272,36 @@ function handleGatewayEvent(input: {
194
272
  });
195
273
  return;
196
274
  }
197
- if (event.type === "speech-started") {
275
+ if (event.type === "speech-started" || event.type === "input_audio_buffer.speech_started") {
198
276
  const itemId = input.getCurrentOutputItemId();
199
277
  if (itemId && input.audio.isPlaying()) {
200
278
  const audioEndMs = input.audio.playbackOffsetMs();
201
279
  input.audio.stopPlayback();
202
- send(input.websocket, {
203
- type: "conversation-item-truncate",
204
- itemId,
205
- contentIndex: 0,
206
- audioEndMs: Math.max(0, Math.round(audioEndMs)),
207
- });
280
+ send(
281
+ input.websocket,
282
+ input.dialect === "xai"
283
+ ? {
284
+ type: "conversation.item.truncate",
285
+ item_id: itemId,
286
+ content_index: 0,
287
+ audio_end_ms: Math.max(0, Math.round(audioEndMs)),
288
+ }
289
+ : {
290
+ type: "conversation-item-truncate",
291
+ itemId,
292
+ contentIndex: 0,
293
+ audioEndMs: Math.max(0, Math.round(audioEndMs)),
294
+ },
295
+ );
208
296
  }
209
297
  return;
210
298
  }
211
- if (event.type === "input-transcription-completed") {
299
+ if (
300
+ event.type === "input-transcription-completed" ||
301
+ event.type === "conversation.item.input_audio_transcription.completed"
302
+ ) {
212
303
  const transcript = stringValue(event.transcript) ?? "";
213
- const itemId = stringValue(event.itemId) ?? crypto.randomUUID();
304
+ const itemId = stringValue(event.itemId) ?? stringValue(event.item_id) ?? crypto.randomUUID();
214
305
  if (transcript.trim()) {
215
306
  input.channel.providerEvent({
216
307
  type: "turn.done",
@@ -220,17 +311,27 @@ function handleGatewayEvent(input: {
220
311
  }
221
312
  return;
222
313
  }
223
- if (event.type === "audio-delta") {
314
+ if (
315
+ event.type === "audio-delta" ||
316
+ event.type === "response.output_audio.delta" ||
317
+ event.type === "response.audio.delta"
318
+ ) {
224
319
  const delta = stringValue(event.delta);
225
320
  if (!delta) return;
226
- const itemId = stringValue(event.itemId);
321
+ const itemId = stringValue(event.itemId) ?? stringValue(event.item_id);
227
322
  if (itemId) input.setCurrentOutputItemId(itemId);
228
323
  input.audio.play(delta);
229
324
  input.channel.providerEvent({ type: "output_audio.delta", event_id: eventId, audio: delta });
230
325
  return;
231
326
  }
232
- if (event.type === "audio-transcript-done" || event.type === "text-done") {
233
- const itemId = stringValue(event.itemId) ?? crypto.randomUUID();
327
+ if (
328
+ event.type === "audio-transcript-done" ||
329
+ event.type === "text-done" ||
330
+ event.type === "response.output_audio_transcript.done" ||
331
+ event.type === "response.audio_transcript.done" ||
332
+ event.type === "response.output_text.done"
333
+ ) {
334
+ const itemId = stringValue(event.itemId) ?? stringValue(event.item_id) ?? crypto.randomUUID();
234
335
  const transcript = stringValue(event.transcript) ?? stringValue(event.text) ?? "";
235
336
  if (transcript.trim() && !input.finalizedAssistantItems.has(itemId)) {
236
337
  input.finalizedAssistantItems.add(itemId);
@@ -242,21 +343,27 @@ function handleGatewayEvent(input: {
242
343
  }
243
344
  return;
244
345
  }
245
- if (event.type === "audio-done") return;
246
- if (event.type === "function-call-arguments-done") {
247
- const callId = stringValue(event.callId) ?? stringValue(event.itemId) ?? crypto.randomUUID();
346
+ if (event.type === "audio-done" || event.type === "response.output_audio.done") return;
347
+ if (
348
+ event.type === "function-call-arguments-done" ||
349
+ event.type === "response.function_call_arguments.done"
350
+ ) {
351
+ const callId =
352
+ stringValue(event.callId) ??
353
+ stringValue(event.call_id) ??
354
+ stringValue(event.itemId) ??
355
+ stringValue(event.item_id) ??
356
+ crypto.randomUUID();
248
357
  const name = stringValue(event.name);
249
358
  if (name !== DELEGATION_TOOL) {
250
- send(input.websocket, {
251
- type: "conversation-item-create",
252
- item: {
253
- type: "function-call-output",
254
- callId,
255
- name,
256
- output: JSON.stringify({ error: "Unsupported realtime tool" }),
257
- },
258
- });
259
- send(input.websocket, { type: "response-create" });
359
+ sendFunctionOutput(
360
+ input.websocket,
361
+ input.dialect,
362
+ callId,
363
+ name,
364
+ JSON.stringify({ error: "Unsupported realtime tool" }),
365
+ );
366
+ sendResponseCreate(input.websocket, input.dialect);
260
367
  return;
261
368
  }
262
369
  const request = delegationRequest(stringValue(event.arguments) ?? "");
@@ -273,10 +380,12 @@ function handleGatewayEvent(input: {
273
380
  return;
274
381
  }
275
382
  if (event.type === "error") {
383
+ const nested = isRecord(event.error) ? event.error : null;
276
384
  input.channel.providerEvent({
277
385
  type: "error",
278
386
  event_id: eventId,
279
- message: stringValue(event.message) ?? "AI Gateway realtime provider error",
387
+ message:
388
+ stringValue(event.message) ?? stringValue(nested?.message) ?? "Realtime provider error",
280
389
  });
281
390
  }
282
391
  }
@@ -335,6 +444,7 @@ class GatewayRealtimeDataChannel extends EventTarget {
335
444
  function handleBridgeOutbound(
336
445
  websocket: WebSocket,
337
446
  messages: Array<Record<string, unknown>>,
447
+ dialect: RealtimeDialect,
338
448
  ): void {
339
449
  const groups = new Map<
340
450
  string,
@@ -361,16 +471,14 @@ function handleBridgeOutbound(
361
471
  }
362
472
  for (const group of groups.values()) {
363
473
  if (group.type === "delegation.context.append" && group.id && group.channel === "speakable") {
364
- send(websocket, {
365
- type: "conversation-item-create",
366
- item: {
367
- type: "function-call-output",
368
- callId: group.id,
369
- name: DELEGATION_TOOL,
370
- output: JSON.stringify({ result: group.text }),
371
- },
372
- });
373
- send(websocket, { type: "response-create" });
474
+ sendFunctionOutput(
475
+ websocket,
476
+ dialect,
477
+ group.id,
478
+ DELEGATION_TOOL,
479
+ JSON.stringify({ result: group.text }),
480
+ );
481
+ sendResponseCreate(websocket, dialect);
374
482
  continue;
375
483
  }
376
484
  const wrapper =
@@ -379,18 +487,52 @@ function handleBridgeOutbound(
379
487
  ? "execution_progress"
380
488
  : "execution_result"
381
489
  : "session_update";
382
- send(websocket, {
383
- type: "conversation-item-create",
384
- item: {
385
- type: "text-message",
386
- role: "user",
387
- text: `<${wrapper}>\n${group.text}\n</${wrapper}>`,
388
- },
389
- });
390
- if (group.channel === "speakable") send(websocket, { type: "response-create" });
490
+ const text = `<${wrapper}>\n${group.text}\n</${wrapper}>`;
491
+ send(
492
+ websocket,
493
+ dialect === "xai"
494
+ ? {
495
+ type: "conversation.item.create",
496
+ item: {
497
+ type: "message",
498
+ role: "user",
499
+ content: [{ type: "input_text", text }],
500
+ },
501
+ }
502
+ : {
503
+ type: "conversation-item-create",
504
+ item: { type: "text-message", role: "user", text },
505
+ },
506
+ );
507
+ if (group.channel === "speakable") sendResponseCreate(websocket, dialect);
391
508
  }
392
509
  }
393
510
 
511
+ function sendFunctionOutput(
512
+ websocket: WebSocket,
513
+ dialect: RealtimeDialect,
514
+ callId: string,
515
+ name: string | null,
516
+ output: string,
517
+ ): void {
518
+ send(
519
+ websocket,
520
+ dialect === "xai"
521
+ ? {
522
+ type: "conversation.item.create",
523
+ item: { type: "function_call_output", call_id: callId, output },
524
+ }
525
+ : {
526
+ type: "conversation-item-create",
527
+ item: { type: "function-call-output", callId, name, output },
528
+ },
529
+ );
530
+ }
531
+
532
+ function sendResponseCreate(websocket: WebSocket, dialect: RealtimeDialect): void {
533
+ send(websocket, { type: dialect === "xai" ? "response.create" : "response-create" });
534
+ }
535
+
394
536
  class GatewayRealtimeAudio {
395
537
  private captureContext: AudioContext | null = null;
396
538
  private captureSource: MediaStreamAudioSourceNode | null = null;
@@ -560,6 +702,7 @@ function providerEventId(event: Record<string, unknown>): string {
560
702
  const raw = isRecord(event.raw) ? event.raw : null;
561
703
  return (
562
704
  stringValue(event.eventId) ??
705
+ stringValue(event.event_id) ??
563
706
  stringValue(raw?.event_id) ??
564
707
  stringValue(raw?.id) ??
565
708
  crypto.randomUUID()
package/src/index.ts CHANGED
@@ -96,7 +96,10 @@ export type {
96
96
  CreateCodexRealtimeControllerOptions,
97
97
  RealtimeControllerTransportStarter,
98
98
  } from "./codex-realtime-controller";
99
- export { createGatewayRealtimeTransportStarter } from "./gateway-realtime-transport";
99
+ export {
100
+ createGatewayRealtimeTransportStarter,
101
+ createXaiSubscriptionRealtimeTransportStarter,
102
+ } from "./gateway-realtime-transport";
100
103
  export { projectSessionRealtimeLifecycle } from "./codex-realtime-lifecycle";
101
104
  export type { SessionRealtimeLifecycleProjection } from "./codex-realtime-lifecycle";
102
105
  // Provider-neutral Browser/Computer resource client + bounded frame protocol.
@@ -130,6 +133,14 @@ export type {
130
133
  } from "./stream";
131
134
  export { streamWorkspaceControlEvents } from "./workspace-control-stream";
132
135
  export type { WorkspaceControlStreamTransport } from "./workspace-control-stream";
136
+ export { streamWorkspaceInteractionRevisions } from "./interaction-revision-stream";
137
+ export type { WorkspaceInteractionRevisionStreamTransport } from "./interaction-revision-stream";
138
+ export { parseWorkspaceLiveEvent, streamWorkspaceLiveEvents } from "./workspace-live-stream";
139
+ export type {
140
+ WorkspaceLiveEvent,
141
+ WorkspaceLiveStreamOptions,
142
+ WorkspaceLiveStreamTransport,
143
+ } from "./workspace-live-stream";
133
144
  export type {
134
145
  CreateWorkspaceArtifactRequest,
135
146
  PublishWorkspaceArtifactVersionRequest,
@@ -317,6 +328,8 @@ export type {
317
328
  BillingEntitlementsResponse,
318
329
  BillingMode,
319
330
  BillingSummary,
331
+ ListManagedOrganizationMembershipsResponse,
332
+ ManagedOrganizationMembership,
320
333
  BillingUsageResponse,
321
334
  InsightsRange,
322
335
  InsightsBillingPath,
@@ -394,6 +407,14 @@ export type {
394
407
  CodexConnectionStatus,
395
408
  CodexConnectStart,
396
409
  CodexConnectPoll,
410
+ SuperGrokAccount,
411
+ SuperGrokAccountsResponse,
412
+ SuperGrokAccountScope,
413
+ SuperGrokAllocatorUpdate,
414
+ SuperGrokConnectionStatus,
415
+ SuperGrokConnectPoll,
416
+ SuperGrokConnectStart,
417
+ SuperGrokRotationSettings,
397
418
  CodexFleetConfidence,
398
419
  CodexFleetCacheState,
399
420
  CodexFleetDecisionEventPayload,
@@ -449,7 +470,10 @@ export type {
449
470
  CreateWorkspaceRequest,
450
471
  DiscoverMcpCapabilitiesResponse,
451
472
  InstallSkillRequest,
473
+ InstallLibrarySkillRequest,
452
474
  InstalledSkill,
475
+ InstalledSkillSummary,
476
+ ListInstalledSkillsResponse,
453
477
  Document,
454
478
  DocumentAuthorityKind,
455
479
  DocumentBase,
@@ -792,6 +816,10 @@ export type {
792
816
  VariableSet,
793
817
  VariableSetSecret,
794
818
  VariableSetVariableMetadata,
819
+ Channel,
820
+ CreateChannelRequest,
821
+ UpdateChannelRequest,
822
+ UpdateSessionChannelRequest,
795
823
  Rig,
796
824
  RigVersion,
797
825
  RigCheck,
@@ -811,30 +839,31 @@ export type {
811
839
  PreviewSkillImportRequest,
812
840
  ApiIntegrationAuthPreview,
813
841
  ApiIntegrationInstallationSummary,
814
- ApiIntegrationPresetSummary,
842
+ IntegrationDefinitionSummary,
815
843
  ApiIntegrationPreview,
816
844
  ApiIntegrationOAuthStartRequest,
817
845
  ApiIntegrationProtocol,
818
- ApiIntegrationSource,
846
+ IntegrationSource,
819
847
  ApiIntegrationToolPreview,
820
848
  ApiIntegrationUninstallPreview,
821
- IntegrationFeatureBindingSummary,
822
- IntegrationFeatureDefinitionSummary,
823
- IntegrationFeatureKind,
824
- IntegrationFeatureMutationResult,
825
- IntegrationFeatureRemovalResult,
826
- IntegrationFeatureStatus,
827
- IntegrationInstanceFeaturesResponse,
849
+ IntegrationFacetBindingSummary,
850
+ IntegrationFacetDefinitionSummary,
851
+ IntegrationFacetKind,
852
+ IntegrationFacetMutationResult,
853
+ IntegrationFacetRemovalResult,
854
+ IntegrationFacetStatus,
855
+ IntegrationInstanceFacetsResponse,
828
856
  InstallApiIntegrationRequest,
829
857
  InstalledApiIntegration,
830
- ListApiIntegrationPresetsResponse,
858
+ ListIntegrationDefinitionsResponse,
831
859
  ListApiIntegrationsResponse,
832
860
  PreviewApiIntegrationRequest,
833
- MutateIntegrationFeatureRequest,
834
- UpsertIntegrationFeatureRequest,
861
+ MutateIntegrationFacetRequest,
862
+ UpsertIntegrationFacetRequest,
835
863
  SkillImportFileSummary,
836
864
  SkillImportPreview,
837
865
  SkillImportSource,
866
+ SkillInstallationSource,
838
867
  SkillUninstallPreview,
839
868
  UninstallSkillRequest,
840
869
  UninstallSkillResult,