@pipedog/openai 0.0.0-stage → 0.3.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/LICENSE +25 -0
- package/NOTICE +9 -0
- package/dist/_constants.d.ts +4 -0
- package/dist/_constants.js +9 -0
- package/dist/base_llm.d.ts +272 -0
- package/dist/base_llm.js +619 -0
- package/dist/image.d.ts +116 -0
- package/dist/image.js +179 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +12 -0
- package/dist/live/events.d.ts +768 -0
- package/dist/live/events.js +1020 -0
- package/dist/live/index.d.ts +2 -0
- package/dist/live/index.js +8 -0
- package/dist/live/llm.d.ts +566 -0
- package/dist/live/llm.js +1652 -0
- package/dist/llm.d.ts +30 -0
- package/dist/llm.js +50 -0
- package/dist/open_ai_live_adapter.d.ts +94 -0
- package/dist/open_ai_live_adapter.js +192 -0
- package/dist/open_ai_realtime_adapter.d.ts +95 -0
- package/dist/open_ai_realtime_adapter.js +221 -0
- package/dist/open_ai_responses_adapter.d.ts +95 -0
- package/dist/open_ai_responses_adapter.js +358 -0
- package/dist/realtime/events.d.ts +1401 -0
- package/dist/realtime/events.js +1639 -0
- package/dist/realtime/index.d.ts +2 -0
- package/dist/realtime/index.js +8 -0
- package/dist/realtime/llm.d.ts +457 -0
- package/dist/realtime/llm.js +1550 -0
- package/dist/responses/index.d.ts +2 -0
- package/dist/responses/index.js +8 -0
- package/dist/responses/llm.d.ts +448 -0
- package/dist/responses/llm.js +1517 -0
- package/dist/stt.d.ts +409 -0
- package/dist/stt.js +741 -0
- package/dist/tts.d.ts +86 -0
- package/dist/tts.js +238 -0
- package/package.json +56 -4
- package/README.md +0 -3
|
@@ -0,0 +1,1639 @@
|
|
|
1
|
+
// Copyright (c) 2024-2026, Daily
|
|
2
|
+
// Copyright (c) 2026, pipedog contributors
|
|
3
|
+
// SPDX-License-Identifier: BSD-2-Clause
|
|
4
|
+
//
|
|
5
|
+
// Ported from pipecat: src/pipecat/services/openai/realtime/events.py
|
|
6
|
+
/**
|
|
7
|
+
* Event models and data structures for OpenAI Realtime API communication.
|
|
8
|
+
*
|
|
9
|
+
* Porting notes:
|
|
10
|
+
* - Upstream models are pydantic `BaseModel`s. Here each model extends the
|
|
11
|
+
* small `BaseModel` below: fields are camelCase and the constructor takes
|
|
12
|
+
* one options object, while `modelValidate()` reads and `modelDump()` /
|
|
13
|
+
* `toJSON()` write the upstream snake_case wire keys, so the wire format is
|
|
14
|
+
* unchanged. Plain-dict fields (`tracing`, `prompt`, `rate_limits`,
|
|
15
|
+
* `status_details`, `tools` as provider dicts) are passed through untouched.
|
|
16
|
+
* - Validation is reduced to what the services rely on: required fields and
|
|
17
|
+
* the `type` literal of server events raise `ValidationError`; value types
|
|
18
|
+
* are not checked.
|
|
19
|
+
* - `model_copy(update=...)` is `modelCopy({ update })`, with camelCase field
|
|
20
|
+
* names; `SessionProperties.model_fields` is `SessionProperties.modelFields`
|
|
21
|
+
* (camelCase field name to wire key).
|
|
22
|
+
*/
|
|
23
|
+
import { rethrowIfCancelled } from "@pipedog/asyncio";
|
|
24
|
+
import { ToolsSchema } from "@pipedog/core/adapters/schemas/tools_schema";
|
|
25
|
+
import { LLMContext } from "@pipedog/core/processors/aggregators/llm_context";
|
|
26
|
+
import { pyJsonLoads } from "@pipedog/core/utils/py_json";
|
|
27
|
+
import { OPENAI_REALTIME_WHISPER_MODEL, OPENAI_SAMPLE_RATE } from "../_constants.js";
|
|
28
|
+
//
|
|
29
|
+
// Model machinery (pydantic's BaseModel, reduced to what these events need).
|
|
30
|
+
//
|
|
31
|
+
/** Raised when data does not match a model, like pydantic's `ValidationError`. */
|
|
32
|
+
export class ValidationError extends Error {
|
|
33
|
+
name = "ValidationError";
|
|
34
|
+
}
|
|
35
|
+
function camelToSnake(name) {
|
|
36
|
+
return name.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`);
|
|
37
|
+
}
|
|
38
|
+
function snakeToCamel(name) {
|
|
39
|
+
return name.replace(/_([a-z0-9])/g, (_, c) => c.toUpperCase());
|
|
40
|
+
}
|
|
41
|
+
function isPlainObject(value) {
|
|
42
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
43
|
+
return false;
|
|
44
|
+
const proto = Object.getPrototypeOf(value);
|
|
45
|
+
return proto === Object.prototype || proto === null;
|
|
46
|
+
}
|
|
47
|
+
function dumpValue(value, options) {
|
|
48
|
+
if (value instanceof BaseModel)
|
|
49
|
+
return value.modelDump(options);
|
|
50
|
+
if (Array.isArray(value))
|
|
51
|
+
return value.map((v) => dumpValue(v, options));
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
54
|
+
function required(options, name, model) {
|
|
55
|
+
const value = options[name];
|
|
56
|
+
if (value === undefined) {
|
|
57
|
+
throw new ValidationError(`1 validation error for ${model}\n${camelToSnake(name)}\n Field required`);
|
|
58
|
+
}
|
|
59
|
+
return value;
|
|
60
|
+
}
|
|
61
|
+
function literal(value, expected, model) {
|
|
62
|
+
if (value === undefined)
|
|
63
|
+
required({}, "type", model);
|
|
64
|
+
if (value !== expected) {
|
|
65
|
+
throw new ValidationError(`1 validation error for ${model}\ntype\n Input should be '${expected}'`);
|
|
66
|
+
}
|
|
67
|
+
return expected;
|
|
68
|
+
}
|
|
69
|
+
/** A resolver building a model from wire data (or keeping an instance). */
|
|
70
|
+
function model(cls) {
|
|
71
|
+
return (value) => (value === null ? null : cls.modelValidate(value));
|
|
72
|
+
}
|
|
73
|
+
/** A resolver building a list of models from wire data. */
|
|
74
|
+
function listOf(resolve) {
|
|
75
|
+
return (value) => (Array.isArray(value) ? value.map(resolve) : value);
|
|
76
|
+
}
|
|
77
|
+
// Extra fields of models that allow them, kept off the instance so they are
|
|
78
|
+
// not taken for declared fields.
|
|
79
|
+
const modelExtras = new WeakMap();
|
|
80
|
+
/**
|
|
81
|
+
* Base of the models in this module (pydantic's `BaseModel`).
|
|
82
|
+
*
|
|
83
|
+
* Fields are the instance's own properties, in declaration order (base class
|
|
84
|
+
* fields first, as pydantic orders them).
|
|
85
|
+
*/
|
|
86
|
+
export class BaseModel {
|
|
87
|
+
/** Fields holding nested models, by field name: how to build each from wire data. */
|
|
88
|
+
static _nested = {};
|
|
89
|
+
/** Whether keys that match no field are kept (pydantic's `extra="allow"`). */
|
|
90
|
+
static _extraAllowed = false;
|
|
91
|
+
/** Extra fields kept from wire data (pydantic's `model_extra`), by wire key. */
|
|
92
|
+
get modelExtra() {
|
|
93
|
+
return modelExtras.get(this) ?? null;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Validate wire data (snake_case keys) into a model (pydantic's
|
|
97
|
+
* `model_validate`). An instance of the model is returned as is.
|
|
98
|
+
*/
|
|
99
|
+
static modelValidate(data) {
|
|
100
|
+
// biome-ignore lint/complexity/noThisInStatic: polymorphic static, like pydantic's classmethod.
|
|
101
|
+
if (data instanceof this)
|
|
102
|
+
return data;
|
|
103
|
+
// biome-ignore lint/complexity/noThisInStatic: polymorphic static.
|
|
104
|
+
const cls = this;
|
|
105
|
+
if (!isPlainObject(data)) {
|
|
106
|
+
throw new ValidationError(`1 validation error for ${cls.name}\n Input should be a valid dictionary or instance of ${cls.name}`);
|
|
107
|
+
}
|
|
108
|
+
const nested = cls._nested;
|
|
109
|
+
const options = {};
|
|
110
|
+
for (const [key, value] of Object.entries(data)) {
|
|
111
|
+
const name = snakeToCamel(key);
|
|
112
|
+
const resolve = Object.hasOwn(nested, name) ? nested[name] : undefined;
|
|
113
|
+
options[name] = resolve && value !== undefined ? resolve(value) : value;
|
|
114
|
+
}
|
|
115
|
+
const instance = new this(options);
|
|
116
|
+
if (cls._extraAllowed) {
|
|
117
|
+
const extra = {};
|
|
118
|
+
for (const [key, value] of Object.entries(data)) {
|
|
119
|
+
if (!Object.hasOwn(instance, snakeToCamel(key)))
|
|
120
|
+
extra[key] = value;
|
|
121
|
+
}
|
|
122
|
+
if (Object.keys(extra).length > 0)
|
|
123
|
+
modelExtras.set(instance, extra);
|
|
124
|
+
}
|
|
125
|
+
return instance;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Serialize the model to a plain object with the wire (snake_case) keys
|
|
129
|
+
* (pydantic's `model_dump`).
|
|
130
|
+
*/
|
|
131
|
+
modelDump(options = {}) {
|
|
132
|
+
const out = {};
|
|
133
|
+
for (const [name, value] of Object.entries(this)) {
|
|
134
|
+
if (value === undefined)
|
|
135
|
+
continue;
|
|
136
|
+
if (options.excludeNone && value === null)
|
|
137
|
+
continue;
|
|
138
|
+
out[camelToSnake(name)] = dumpValue(value, options);
|
|
139
|
+
}
|
|
140
|
+
const extra = modelExtras.get(this);
|
|
141
|
+
if (extra) {
|
|
142
|
+
for (const [key, value] of Object.entries(extra)) {
|
|
143
|
+
if (options.excludeNone && value === null)
|
|
144
|
+
continue;
|
|
145
|
+
out[key] = value;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return out;
|
|
149
|
+
}
|
|
150
|
+
/** JSON form: the wire dump. */
|
|
151
|
+
toJSON() {
|
|
152
|
+
return this.modelDump();
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Shallow copy of the model, with `update` (camelCase field names) applied
|
|
156
|
+
* (pydantic's `model_copy`).
|
|
157
|
+
*/
|
|
158
|
+
modelCopy(options = {}) {
|
|
159
|
+
const copy = Object.assign(Object.create(Object.getPrototypeOf(this)), this);
|
|
160
|
+
const extra = modelExtras.get(this);
|
|
161
|
+
if (extra)
|
|
162
|
+
modelExtras.set(copy, { ...extra });
|
|
163
|
+
if (options.update)
|
|
164
|
+
Object.assign(copy, options.update);
|
|
165
|
+
return copy;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/** Base class for audio format configuration. */
|
|
169
|
+
export class AudioFormat extends BaseModel {
|
|
170
|
+
type;
|
|
171
|
+
constructor(options) {
|
|
172
|
+
super();
|
|
173
|
+
this.type = required(options, "type", new.target.name);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* PCM audio format configuration.
|
|
178
|
+
*
|
|
179
|
+
* - `type`: audio format type, always "audio/pcm".
|
|
180
|
+
* - `rate`: sample rate, always 24000 for PCM.
|
|
181
|
+
*/
|
|
182
|
+
export class PCMAudioFormat extends AudioFormat {
|
|
183
|
+
rate;
|
|
184
|
+
constructor(options = {}) {
|
|
185
|
+
super({ type: options.type ?? "audio/pcm" });
|
|
186
|
+
this.rate = options.rate ?? OPENAI_SAMPLE_RATE;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* PCMU (G.711 μ-law) audio format configuration.
|
|
191
|
+
*
|
|
192
|
+
* - `type`: audio format type, always "audio/pcmu".
|
|
193
|
+
*/
|
|
194
|
+
export class PCMUAudioFormat extends AudioFormat {
|
|
195
|
+
constructor(options = {}) {
|
|
196
|
+
super({ type: options.type ?? "audio/pcmu" });
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* PCMA (G.711 A-law) audio format configuration.
|
|
201
|
+
*
|
|
202
|
+
* - `type`: audio format type, always "audio/pcma".
|
|
203
|
+
*/
|
|
204
|
+
export class PCMAAudioFormat extends AudioFormat {
|
|
205
|
+
constructor(options = {}) {
|
|
206
|
+
super({ type: options.type ?? "audio/pcma" });
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/** Builds the audio format a wire dict describes, by its `type`. */
|
|
210
|
+
const audioFormat = (value) => {
|
|
211
|
+
if (value === null || value instanceof AudioFormat || !isPlainObject(value))
|
|
212
|
+
return value;
|
|
213
|
+
if (value.type === "audio/pcmu")
|
|
214
|
+
return PCMUAudioFormat.modelValidate(value);
|
|
215
|
+
if (value.type === "audio/pcma")
|
|
216
|
+
return PCMAAudioFormat.modelValidate(value);
|
|
217
|
+
return PCMAudioFormat.modelValidate(value);
|
|
218
|
+
};
|
|
219
|
+
/** Configuration for audio transcription settings. */
|
|
220
|
+
export class InputAudioTranscription extends BaseModel {
|
|
221
|
+
model;
|
|
222
|
+
language;
|
|
223
|
+
prompt;
|
|
224
|
+
/**
|
|
225
|
+
* Initialize InputAudioTranscription.
|
|
226
|
+
*
|
|
227
|
+
* @param options.model Transcription model to use (e.g.
|
|
228
|
+
* "gpt-realtime-whisper", "gpt-4o-transcribe", "whisper-1").
|
|
229
|
+
* @param options.language Optional language code for transcription.
|
|
230
|
+
* @param options.prompt Optional transcription hint text.
|
|
231
|
+
*/
|
|
232
|
+
constructor(options = {}) {
|
|
233
|
+
super();
|
|
234
|
+
this.model = options.model ?? OPENAI_REALTIME_WHISPER_MODEL;
|
|
235
|
+
this.language = options.language ?? null;
|
|
236
|
+
this.prompt = options.prompt ?? null;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Server-side voice activity detection configuration.
|
|
241
|
+
*
|
|
242
|
+
* - `type`: detection type, must be "server_vad".
|
|
243
|
+
* - `threshold`: voice activity detection threshold (0.0-1.0). Defaults to 0.5.
|
|
244
|
+
* - `prefixPaddingMs`: padding before speech starts in milliseconds. Defaults to 300.
|
|
245
|
+
* - `silenceDurationMs`: silence duration to detect speech end in milliseconds.
|
|
246
|
+
* Defaults to 500.
|
|
247
|
+
*/
|
|
248
|
+
export class TurnDetection extends BaseModel {
|
|
249
|
+
type;
|
|
250
|
+
threshold;
|
|
251
|
+
prefixPaddingMs;
|
|
252
|
+
silenceDurationMs;
|
|
253
|
+
constructor(options = {}) {
|
|
254
|
+
super();
|
|
255
|
+
this.type = options.type === undefined ? "server_vad" : options.type;
|
|
256
|
+
this.threshold = options.threshold === undefined ? 0.5 : options.threshold;
|
|
257
|
+
this.prefixPaddingMs = options.prefixPaddingMs === undefined ? 300 : options.prefixPaddingMs;
|
|
258
|
+
this.silenceDurationMs =
|
|
259
|
+
options.silenceDurationMs === undefined ? 500 : options.silenceDurationMs;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Semantic-based turn detection configuration.
|
|
264
|
+
*
|
|
265
|
+
* - `type`: detection type, must be "semantic_vad".
|
|
266
|
+
* - `eagerness`: turn detection eagerness level. Can be "low", "medium",
|
|
267
|
+
* "high", or "auto".
|
|
268
|
+
* - `createResponse`: whether to automatically create responses on turn detection.
|
|
269
|
+
* - `interruptResponse`: whether to interrupt ongoing responses on turn detection.
|
|
270
|
+
*/
|
|
271
|
+
export class SemanticTurnDetection extends BaseModel {
|
|
272
|
+
type;
|
|
273
|
+
eagerness;
|
|
274
|
+
createResponse;
|
|
275
|
+
interruptResponse;
|
|
276
|
+
constructor(options = {}) {
|
|
277
|
+
super();
|
|
278
|
+
this.type = options.type === undefined ? "semantic_vad" : options.type;
|
|
279
|
+
this.eagerness = options.eagerness ?? null;
|
|
280
|
+
this.createResponse = options.createResponse ?? null;
|
|
281
|
+
this.interruptResponse = options.interruptResponse ?? null;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
/** Builds the turn detection a wire value describes: a bool, or a config by its `type`. */
|
|
285
|
+
const turnDetection = (value) => {
|
|
286
|
+
if (typeof value === "boolean" || value === null || !isPlainObject(value))
|
|
287
|
+
return value;
|
|
288
|
+
if (value.type === "semantic_vad")
|
|
289
|
+
return SemanticTurnDetection.modelValidate(value);
|
|
290
|
+
return TurnDetection.modelValidate(value);
|
|
291
|
+
};
|
|
292
|
+
/**
|
|
293
|
+
* Input audio noise reduction configuration.
|
|
294
|
+
*
|
|
295
|
+
* - `type`: noise reduction type for different microphone scenarios.
|
|
296
|
+
*/
|
|
297
|
+
export class InputAudioNoiseReduction extends BaseModel {
|
|
298
|
+
type;
|
|
299
|
+
constructor(options) {
|
|
300
|
+
super();
|
|
301
|
+
this.type = required(options, "type", "InputAudioNoiseReduction");
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Audio input configuration.
|
|
306
|
+
*
|
|
307
|
+
* - `format`: the format of the input audio.
|
|
308
|
+
* - `transcription`: configuration for input audio transcription.
|
|
309
|
+
* - `noiseReduction`: configuration for input audio noise reduction.
|
|
310
|
+
* - `turnDetection`: configuration for turn detection, or false to disable.
|
|
311
|
+
*/
|
|
312
|
+
export class AudioInput extends BaseModel {
|
|
313
|
+
static _nested = {
|
|
314
|
+
format: audioFormat,
|
|
315
|
+
transcription: model(InputAudioTranscription),
|
|
316
|
+
noiseReduction: model(InputAudioNoiseReduction),
|
|
317
|
+
turnDetection,
|
|
318
|
+
};
|
|
319
|
+
format;
|
|
320
|
+
transcription;
|
|
321
|
+
noiseReduction;
|
|
322
|
+
turnDetection;
|
|
323
|
+
constructor(options = {}) {
|
|
324
|
+
super();
|
|
325
|
+
this.format = options.format ?? null;
|
|
326
|
+
this.transcription = options.transcription ?? null;
|
|
327
|
+
this.noiseReduction = options.noiseReduction ?? null;
|
|
328
|
+
this.turnDetection = options.turnDetection ?? null;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Audio output configuration.
|
|
333
|
+
*
|
|
334
|
+
* - `format`: the format of the output audio.
|
|
335
|
+
* - `voice`: the voice the model uses to respond.
|
|
336
|
+
* - `speed`: the speed of the model's spoken response.
|
|
337
|
+
*/
|
|
338
|
+
export class AudioOutput extends BaseModel {
|
|
339
|
+
static _nested = { format: audioFormat };
|
|
340
|
+
format;
|
|
341
|
+
voice;
|
|
342
|
+
speed;
|
|
343
|
+
constructor(options = {}) {
|
|
344
|
+
super();
|
|
345
|
+
this.format = options.format ?? null;
|
|
346
|
+
this.voice = options.voice ?? null;
|
|
347
|
+
this.speed = options.speed ?? null;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Audio configuration for input and output.
|
|
352
|
+
*
|
|
353
|
+
* - `input`: configuration for input audio.
|
|
354
|
+
* - `output`: configuration for output audio.
|
|
355
|
+
*/
|
|
356
|
+
export class AudioConfiguration extends BaseModel {
|
|
357
|
+
static _nested = {
|
|
358
|
+
input: model(AudioInput),
|
|
359
|
+
output: model(AudioOutput),
|
|
360
|
+
};
|
|
361
|
+
input;
|
|
362
|
+
output;
|
|
363
|
+
constructor(options = {}) {
|
|
364
|
+
super();
|
|
365
|
+
this.input = options.input ?? null;
|
|
366
|
+
this.output = options.output ?? null;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Reasoning configuration for reasoning-capable Realtime models (e.g. `gpt-realtime-2`).
|
|
371
|
+
*
|
|
372
|
+
* - `effort`: how much reasoning effort the model should apply. `null` (the
|
|
373
|
+
* default) leaves the field unset and lets the server pick.
|
|
374
|
+
*/
|
|
375
|
+
export class Reasoning extends BaseModel {
|
|
376
|
+
// `| string` for forward compatibility: if OpenAI adds new effort levels,
|
|
377
|
+
// users can pass the new string without waiting for a Pipecat release.
|
|
378
|
+
effort;
|
|
379
|
+
constructor(options = {}) {
|
|
380
|
+
super();
|
|
381
|
+
this.effort = options.effort ?? null;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Configuration properties for an OpenAI Realtime session.
|
|
386
|
+
*
|
|
387
|
+
* - `type`: the type of session, always "realtime".
|
|
388
|
+
* - `object`: object type identifier, always "realtime.session".
|
|
389
|
+
* - `id`: unique identifier for the session.
|
|
390
|
+
* - `model`: the Realtime model used for this session. Note: the model is set
|
|
391
|
+
* at connection time via the service settings and cannot be changed during
|
|
392
|
+
* the session.
|
|
393
|
+
* - `outputModalities`: the set of modalities the model can respond with.
|
|
394
|
+
* - `instructions`: system instructions for the assistant.
|
|
395
|
+
* - `audio`: configuration for input and output audio.
|
|
396
|
+
* - `tools`: available function tools for the assistant.
|
|
397
|
+
* - `toolChoice`: tool usage strategy ("auto", "none", or "required").
|
|
398
|
+
* - `maxOutputTokens`: maximum tokens in response or "inf" for unlimited.
|
|
399
|
+
* - `tracing`: configuration options for tracing.
|
|
400
|
+
* - `prompt`: reference to a prompt template and its variables.
|
|
401
|
+
* - `expiresAt`: session expiration timestamp.
|
|
402
|
+
* - `include`: additional fields to include in server outputs.
|
|
403
|
+
* - `reasoning`: reasoning configuration. Only supported by reasoning-capable
|
|
404
|
+
* Realtime models such as `gpt-realtime-2`.
|
|
405
|
+
*/
|
|
406
|
+
export class SessionProperties extends BaseModel {
|
|
407
|
+
static _nested = {
|
|
408
|
+
audio: model(AudioConfiguration),
|
|
409
|
+
reasoning: model(Reasoning),
|
|
410
|
+
};
|
|
411
|
+
/** The model's fields (pydantic's `model_fields`): camelCase field name to wire key. */
|
|
412
|
+
static modelFields = {
|
|
413
|
+
type: "type",
|
|
414
|
+
object: "object",
|
|
415
|
+
id: "id",
|
|
416
|
+
model: "model",
|
|
417
|
+
outputModalities: "output_modalities",
|
|
418
|
+
instructions: "instructions",
|
|
419
|
+
audio: "audio",
|
|
420
|
+
tools: "tools",
|
|
421
|
+
toolChoice: "tool_choice",
|
|
422
|
+
maxOutputTokens: "max_output_tokens",
|
|
423
|
+
tracing: "tracing",
|
|
424
|
+
prompt: "prompt",
|
|
425
|
+
expiresAt: "expires_at",
|
|
426
|
+
include: "include",
|
|
427
|
+
reasoning: "reasoning",
|
|
428
|
+
};
|
|
429
|
+
type;
|
|
430
|
+
object;
|
|
431
|
+
id;
|
|
432
|
+
model;
|
|
433
|
+
outputModalities;
|
|
434
|
+
instructions;
|
|
435
|
+
audio;
|
|
436
|
+
// Tools provided by the user (via the service constructor or
|
|
437
|
+
// LLMUpdateSettingsFrame) may be a ToolsSchema or a plain list of standard
|
|
438
|
+
// tools (normalized to a ToolsSchema on construction); a list of
|
|
439
|
+
// provider-native tool dicts passes through. ToolsSchema is never
|
|
440
|
+
// serialized/deserialized when talking to the server.
|
|
441
|
+
tools;
|
|
442
|
+
toolChoice;
|
|
443
|
+
maxOutputTokens;
|
|
444
|
+
tracing;
|
|
445
|
+
prompt;
|
|
446
|
+
expiresAt;
|
|
447
|
+
include;
|
|
448
|
+
reasoning;
|
|
449
|
+
constructor(options = {}) {
|
|
450
|
+
super();
|
|
451
|
+
this.type = options.type === undefined ? "realtime" : options.type;
|
|
452
|
+
this.object = options.object ?? null;
|
|
453
|
+
this.id = options.id ?? null;
|
|
454
|
+
this.model = options.model ?? null;
|
|
455
|
+
this.outputModalities = options.outputModalities ?? null;
|
|
456
|
+
this.instructions = options.instructions ?? null;
|
|
457
|
+
this.audio = options.audio ?? null;
|
|
458
|
+
this.tools = SessionProperties._normalizeTools(options.tools ?? null);
|
|
459
|
+
this.toolChoice = options.toolChoice ?? null;
|
|
460
|
+
this.maxOutputTokens = options.maxOutputTokens ?? null;
|
|
461
|
+
this.tracing = options.tracing ?? null;
|
|
462
|
+
this.prompt = options.prompt ?? null;
|
|
463
|
+
this.expiresAt = options.expiresAt ?? null;
|
|
464
|
+
this.include = options.include ?? null;
|
|
465
|
+
this.reasoning = options.reasoning ?? null;
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* Wrap a plain list of standard tools in a `ToolsSchema`.
|
|
469
|
+
*
|
|
470
|
+
* Provider-native tool lists (dicts) pass through unchanged.
|
|
471
|
+
*/
|
|
472
|
+
static _normalizeTools(v) {
|
|
473
|
+
if (Array.isArray(v)) {
|
|
474
|
+
const normalized = LLMContext._normalizeAndValidateTools(v, { allowProviderTools: true });
|
|
475
|
+
return normalized instanceof ToolsSchema || Array.isArray(normalized)
|
|
476
|
+
? normalized
|
|
477
|
+
: null;
|
|
478
|
+
}
|
|
479
|
+
return v;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Content within a conversation item.
|
|
484
|
+
*
|
|
485
|
+
* - `type`: content type (text, audio, input_text, input_audio, input_image,
|
|
486
|
+
* output_text, or output_audio).
|
|
487
|
+
* - `text`: text content for text-based items.
|
|
488
|
+
* - `audio`: base64-encoded audio data for audio items.
|
|
489
|
+
* - `transcript`: transcribed text for audio items.
|
|
490
|
+
* - `imageUrl`: base64-encoded image data as a data URI for input_image items.
|
|
491
|
+
* - `detail`: detail level for image processing ("auto", "low", or "high").
|
|
492
|
+
*/
|
|
493
|
+
export class ItemContent extends BaseModel {
|
|
494
|
+
type;
|
|
495
|
+
text;
|
|
496
|
+
audio; // base64-encoded audio
|
|
497
|
+
transcript;
|
|
498
|
+
imageUrl; // base64-encoded image as data URI
|
|
499
|
+
detail;
|
|
500
|
+
constructor(options) {
|
|
501
|
+
super();
|
|
502
|
+
this.type = required(options, "type", "ItemContent");
|
|
503
|
+
this.text = options.text ?? null;
|
|
504
|
+
this.audio = options.audio ?? null;
|
|
505
|
+
this.transcript = options.transcript ?? null;
|
|
506
|
+
this.imageUrl = options.imageUrl ?? null;
|
|
507
|
+
this.detail = options.detail ?? null;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* A conversation item in the realtime session.
|
|
512
|
+
*
|
|
513
|
+
* - `id`: unique identifier for the item, auto-generated if not provided.
|
|
514
|
+
* - `object`: object type identifier for the realtime API.
|
|
515
|
+
* - `type`: item type (message, function_call, or function_call_output).
|
|
516
|
+
* - `status`: current status of the item.
|
|
517
|
+
* - `role`: speaker role for message items (user, assistant, or system).
|
|
518
|
+
* - `content`: content list for message items.
|
|
519
|
+
* - `callId`: function call identifier for function_call items.
|
|
520
|
+
* - `name`: function name for function_call items.
|
|
521
|
+
* - `arguments`: function arguments as JSON string for function_call items.
|
|
522
|
+
* - `output`: function output as JSON string for function_call_output items.
|
|
523
|
+
*/
|
|
524
|
+
export class ConversationItem extends BaseModel {
|
|
525
|
+
static _nested = {
|
|
526
|
+
content: listOf(model(ItemContent)),
|
|
527
|
+
};
|
|
528
|
+
id;
|
|
529
|
+
object;
|
|
530
|
+
type;
|
|
531
|
+
status;
|
|
532
|
+
// role and content are present for message items
|
|
533
|
+
role;
|
|
534
|
+
content;
|
|
535
|
+
// these four fields are present for function_call items
|
|
536
|
+
callId;
|
|
537
|
+
name;
|
|
538
|
+
arguments;
|
|
539
|
+
output;
|
|
540
|
+
constructor(options) {
|
|
541
|
+
super();
|
|
542
|
+
this.id = options.id ?? crypto.randomUUID().replaceAll("-", "");
|
|
543
|
+
this.object = options.object ?? null;
|
|
544
|
+
this.type = required(options, "type", "ConversationItem");
|
|
545
|
+
this.status = options.status ?? null;
|
|
546
|
+
this.role = options.role ?? null;
|
|
547
|
+
this.content = options.content ?? null;
|
|
548
|
+
this.callId = options.callId ?? null;
|
|
549
|
+
this.name = options.name ?? null;
|
|
550
|
+
this.arguments = options.arguments ?? null;
|
|
551
|
+
this.output = options.output ?? null;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
/**
|
|
555
|
+
* A realtime conversation session.
|
|
556
|
+
*
|
|
557
|
+
* - `id`: unique identifier for the conversation.
|
|
558
|
+
* - `object`: object type identifier, always "realtime.conversation".
|
|
559
|
+
*/
|
|
560
|
+
export class RealtimeConversation extends BaseModel {
|
|
561
|
+
id;
|
|
562
|
+
object;
|
|
563
|
+
constructor(options) {
|
|
564
|
+
super();
|
|
565
|
+
this.id = required(options, "id", "RealtimeConversation");
|
|
566
|
+
this.object = required(options, "object", "RealtimeConversation");
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* Properties for configuring assistant responses.
|
|
571
|
+
*
|
|
572
|
+
* - `outputModalities`: output modalities for the response. Must be either
|
|
573
|
+
* ["text"] or ["audio"]. Defaults to ["audio"].
|
|
574
|
+
* - `instructions`: specific instructions for this response.
|
|
575
|
+
* - `audio`: audio configuration for this response.
|
|
576
|
+
* - `tools`: available tools for this response.
|
|
577
|
+
* - `toolChoice`: tool usage strategy for this response.
|
|
578
|
+
* - `temperature`: sampling temperature for this response.
|
|
579
|
+
* - `maxOutputTokens`: maximum tokens for this response.
|
|
580
|
+
*/
|
|
581
|
+
export class ResponseProperties extends BaseModel {
|
|
582
|
+
static _nested = { audio: model(AudioConfiguration) };
|
|
583
|
+
outputModalities;
|
|
584
|
+
instructions;
|
|
585
|
+
audio;
|
|
586
|
+
tools;
|
|
587
|
+
toolChoice;
|
|
588
|
+
temperature;
|
|
589
|
+
maxOutputTokens;
|
|
590
|
+
constructor(options = {}) {
|
|
591
|
+
super();
|
|
592
|
+
this.outputModalities =
|
|
593
|
+
options.outputModalities === undefined ? ["audio"] : options.outputModalities;
|
|
594
|
+
this.instructions = options.instructions ?? null;
|
|
595
|
+
this.audio = options.audio ?? null;
|
|
596
|
+
this.tools = options.tools ?? null;
|
|
597
|
+
this.toolChoice = options.toolChoice ?? null;
|
|
598
|
+
this.temperature = options.temperature ?? null;
|
|
599
|
+
this.maxOutputTokens = options.maxOutputTokens ?? null;
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* Error information from the realtime API.
|
|
604
|
+
*
|
|
605
|
+
* - `type`: error type identifier.
|
|
606
|
+
* - `code`: specific error code.
|
|
607
|
+
* - `message`: human-readable error message.
|
|
608
|
+
* - `param`: parameter name that caused the error, if applicable.
|
|
609
|
+
* - `eventId`: event ID associated with the error, if applicable.
|
|
610
|
+
*/
|
|
611
|
+
export class RealtimeError extends BaseModel {
|
|
612
|
+
type;
|
|
613
|
+
code;
|
|
614
|
+
message;
|
|
615
|
+
param;
|
|
616
|
+
eventId;
|
|
617
|
+
constructor(options) {
|
|
618
|
+
super();
|
|
619
|
+
this.type = required(options, "type", "RealtimeError");
|
|
620
|
+
this.code = options.code === undefined ? "" : options.code;
|
|
621
|
+
this.message = required(options, "message", "RealtimeError");
|
|
622
|
+
this.param = options.param ?? null;
|
|
623
|
+
this.eventId = options.eventId ?? null;
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* Base class for client events sent to the realtime API.
|
|
628
|
+
*
|
|
629
|
+
* - `eventId`: unique identifier for the event, auto-generated if not provided.
|
|
630
|
+
*/
|
|
631
|
+
export class ClientEvent extends BaseModel {
|
|
632
|
+
eventId;
|
|
633
|
+
constructor(options = {}) {
|
|
634
|
+
super();
|
|
635
|
+
this.eventId = options.eventId ?? crypto.randomUUID();
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
/**
|
|
639
|
+
* Event to update session properties.
|
|
640
|
+
*
|
|
641
|
+
* - `type`: event type, always "session.update".
|
|
642
|
+
* - `session`: updated session properties.
|
|
643
|
+
*/
|
|
644
|
+
export class SessionUpdateEvent extends ClientEvent {
|
|
645
|
+
static _nested = { session: model(SessionProperties) };
|
|
646
|
+
type = "session.update";
|
|
647
|
+
session;
|
|
648
|
+
constructor(options) {
|
|
649
|
+
super(options);
|
|
650
|
+
this.session = required(options, "session", "SessionUpdateEvent");
|
|
651
|
+
}
|
|
652
|
+
/**
|
|
653
|
+
* Serialize the event to a plain object.
|
|
654
|
+
*
|
|
655
|
+
* Handles special serialization for turn_detection where false becomes null.
|
|
656
|
+
*
|
|
657
|
+
* @param options Options passed to the parent `modelDump`.
|
|
658
|
+
* @returns Object representation of the event.
|
|
659
|
+
*/
|
|
660
|
+
modelDump(options = {}) {
|
|
661
|
+
const dump = super.modelDump(options);
|
|
662
|
+
// Handle turn_detection in audio.input so that false becomes null
|
|
663
|
+
if ("audio" in dump.session && dump.session.audio) {
|
|
664
|
+
if ("input" in dump.session.audio && dump.session.audio.input) {
|
|
665
|
+
if ("turn_detection" in dump.session.audio.input) {
|
|
666
|
+
if (dump.session.audio.input.turn_detection === false) {
|
|
667
|
+
dump.session.audio.input.turn_detection = null;
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
return dump;
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
/**
|
|
676
|
+
* Event to append audio data to the input buffer.
|
|
677
|
+
*
|
|
678
|
+
* - `type`: event type, always "input_audio_buffer.append".
|
|
679
|
+
* - `audio`: base64-encoded audio data to append.
|
|
680
|
+
*/
|
|
681
|
+
export class InputAudioBufferAppendEvent extends ClientEvent {
|
|
682
|
+
type = "input_audio_buffer.append";
|
|
683
|
+
audio; // base64-encoded audio
|
|
684
|
+
constructor(options) {
|
|
685
|
+
super(options);
|
|
686
|
+
this.audio = required(options, "audio", "InputAudioBufferAppendEvent");
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
/**
|
|
690
|
+
* Event to commit the current input audio buffer.
|
|
691
|
+
*
|
|
692
|
+
* - `type`: event type, always "input_audio_buffer.commit".
|
|
693
|
+
*/
|
|
694
|
+
export class InputAudioBufferCommitEvent extends ClientEvent {
|
|
695
|
+
type = "input_audio_buffer.commit";
|
|
696
|
+
constructor(options = {}) {
|
|
697
|
+
super(options);
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
/**
|
|
701
|
+
* Event to clear the input audio buffer.
|
|
702
|
+
*
|
|
703
|
+
* - `type`: event type, always "input_audio_buffer.clear".
|
|
704
|
+
*/
|
|
705
|
+
export class InputAudioBufferClearEvent extends ClientEvent {
|
|
706
|
+
type = "input_audio_buffer.clear";
|
|
707
|
+
constructor(options = {}) {
|
|
708
|
+
super(options);
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
/**
|
|
712
|
+
* Event to create a new conversation item.
|
|
713
|
+
*
|
|
714
|
+
* - `type`: event type, always "conversation.item.create".
|
|
715
|
+
* - `previousItemId`: ID of the item to insert after, if any.
|
|
716
|
+
* - `item`: the conversation item to create.
|
|
717
|
+
*/
|
|
718
|
+
export class ConversationItemCreateEvent extends ClientEvent {
|
|
719
|
+
static _nested = { item: model(ConversationItem) };
|
|
720
|
+
type = "conversation.item.create";
|
|
721
|
+
previousItemId;
|
|
722
|
+
item;
|
|
723
|
+
constructor(options) {
|
|
724
|
+
super(options);
|
|
725
|
+
this.previousItemId = options.previousItemId ?? null;
|
|
726
|
+
this.item = required(options, "item", "ConversationItemCreateEvent");
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
/**
|
|
730
|
+
* Event to truncate a conversation item's audio content.
|
|
731
|
+
*
|
|
732
|
+
* - `type`: event type, always "conversation.item.truncate".
|
|
733
|
+
* - `itemId`: ID of the item to truncate.
|
|
734
|
+
* - `contentIndex`: index of the content to truncate within the item.
|
|
735
|
+
* - `audioEndMs`: end time in milliseconds for the truncated audio.
|
|
736
|
+
*/
|
|
737
|
+
export class ConversationItemTruncateEvent extends ClientEvent {
|
|
738
|
+
type = "conversation.item.truncate";
|
|
739
|
+
itemId;
|
|
740
|
+
contentIndex;
|
|
741
|
+
audioEndMs;
|
|
742
|
+
constructor(options) {
|
|
743
|
+
super(options);
|
|
744
|
+
this.itemId = required(options, "itemId", "ConversationItemTruncateEvent");
|
|
745
|
+
this.contentIndex = required(options, "contentIndex", "ConversationItemTruncateEvent");
|
|
746
|
+
this.audioEndMs = required(options, "audioEndMs", "ConversationItemTruncateEvent");
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
/**
|
|
750
|
+
* Event to delete a conversation item.
|
|
751
|
+
*
|
|
752
|
+
* - `type`: event type, always "conversation.item.delete".
|
|
753
|
+
* - `itemId`: ID of the item to delete.
|
|
754
|
+
*/
|
|
755
|
+
export class ConversationItemDeleteEvent extends ClientEvent {
|
|
756
|
+
type = "conversation.item.delete";
|
|
757
|
+
itemId;
|
|
758
|
+
constructor(options) {
|
|
759
|
+
super(options);
|
|
760
|
+
this.itemId = required(options, "itemId", "ConversationItemDeleteEvent");
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
/**
|
|
764
|
+
* Event to retrieve a conversation item by ID.
|
|
765
|
+
*
|
|
766
|
+
* - `type`: event type, always "conversation.item.retrieve".
|
|
767
|
+
* - `itemId`: ID of the item to retrieve.
|
|
768
|
+
*/
|
|
769
|
+
export class ConversationItemRetrieveEvent extends ClientEvent {
|
|
770
|
+
type = "conversation.item.retrieve";
|
|
771
|
+
itemId;
|
|
772
|
+
constructor(options) {
|
|
773
|
+
super(options);
|
|
774
|
+
this.itemId = required(options, "itemId", "ConversationItemRetrieveEvent");
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
/**
|
|
778
|
+
* Event to create a new assistant response.
|
|
779
|
+
*
|
|
780
|
+
* - `type`: event type, always "response.create".
|
|
781
|
+
* - `response`: optional response configuration properties.
|
|
782
|
+
*/
|
|
783
|
+
export class ResponseCreateEvent extends ClientEvent {
|
|
784
|
+
static _nested = { response: model(ResponseProperties) };
|
|
785
|
+
type = "response.create";
|
|
786
|
+
response;
|
|
787
|
+
constructor(options = {}) {
|
|
788
|
+
super(options);
|
|
789
|
+
this.response = options.response ?? null;
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
/**
|
|
793
|
+
* Event to cancel the current assistant response.
|
|
794
|
+
*
|
|
795
|
+
* - `type`: event type, always "response.cancel".
|
|
796
|
+
*/
|
|
797
|
+
export class ResponseCancelEvent extends ClientEvent {
|
|
798
|
+
type = "response.cancel";
|
|
799
|
+
constructor(options = {}) {
|
|
800
|
+
super(options);
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
/**
|
|
804
|
+
* Base class for server events received from the realtime API.
|
|
805
|
+
*
|
|
806
|
+
* - `eventId`: unique identifier for the event.
|
|
807
|
+
* - `type`: type of the server event.
|
|
808
|
+
*/
|
|
809
|
+
export class ServerEvent extends BaseModel {
|
|
810
|
+
eventId;
|
|
811
|
+
type;
|
|
812
|
+
constructor(options) {
|
|
813
|
+
super();
|
|
814
|
+
this.eventId = required(options, "eventId", new.target.name);
|
|
815
|
+
this.type = required(options, "type", new.target.name);
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
/**
|
|
819
|
+
* Event indicating a session has been created.
|
|
820
|
+
*
|
|
821
|
+
* - `type`: event type, always "session.created".
|
|
822
|
+
* - `session`: the created session properties.
|
|
823
|
+
*/
|
|
824
|
+
export class SessionCreatedEvent extends ServerEvent {
|
|
825
|
+
static _nested = { session: model(SessionProperties) };
|
|
826
|
+
session;
|
|
827
|
+
constructor(options) {
|
|
828
|
+
super(options);
|
|
829
|
+
this.type = literal(options.type, "session.created", "SessionCreatedEvent");
|
|
830
|
+
this.session = required(options, "session", "SessionCreatedEvent");
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
/**
|
|
834
|
+
* Event indicating a session has been updated.
|
|
835
|
+
*
|
|
836
|
+
* - `type`: event type, always "session.updated".
|
|
837
|
+
* - `session`: the updated session properties.
|
|
838
|
+
*/
|
|
839
|
+
export class SessionUpdatedEvent extends ServerEvent {
|
|
840
|
+
static _nested = { session: model(SessionProperties) };
|
|
841
|
+
session;
|
|
842
|
+
constructor(options) {
|
|
843
|
+
super(options);
|
|
844
|
+
this.type = literal(options.type, "session.updated", "SessionUpdatedEvent");
|
|
845
|
+
this.session = required(options, "session", "SessionUpdatedEvent");
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
/**
|
|
849
|
+
* Event indicating a conversation has been created.
|
|
850
|
+
*
|
|
851
|
+
* - `type`: event type, always "conversation.created".
|
|
852
|
+
* - `conversation`: the created conversation.
|
|
853
|
+
*/
|
|
854
|
+
export class ConversationCreated extends ServerEvent {
|
|
855
|
+
static _nested = {
|
|
856
|
+
conversation: model(RealtimeConversation),
|
|
857
|
+
};
|
|
858
|
+
conversation;
|
|
859
|
+
constructor(options) {
|
|
860
|
+
super(options);
|
|
861
|
+
this.type = literal(options.type, "conversation.created", "ConversationCreated");
|
|
862
|
+
this.conversation = required(options, "conversation", "ConversationCreated");
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
/**
|
|
866
|
+
* Event indicating a conversation item has been added.
|
|
867
|
+
*
|
|
868
|
+
* - `type`: event type, always "conversation.item.added".
|
|
869
|
+
* - `previousItemId`: ID of the previous item, if any.
|
|
870
|
+
* - `item`: the added conversation item.
|
|
871
|
+
*/
|
|
872
|
+
export class ConversationItemAdded extends ServerEvent {
|
|
873
|
+
static _nested = { item: model(ConversationItem) };
|
|
874
|
+
previousItemId;
|
|
875
|
+
item;
|
|
876
|
+
constructor(options) {
|
|
877
|
+
super(options);
|
|
878
|
+
this.type = literal(options.type, "conversation.item.added", "ConversationItemAdded");
|
|
879
|
+
this.previousItemId = options.previousItemId ?? null;
|
|
880
|
+
this.item = required(options, "item", "ConversationItemAdded");
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
/**
|
|
884
|
+
* Event indicating a conversation item is done processing.
|
|
885
|
+
*
|
|
886
|
+
* - `type`: event type, always "conversation.item.done".
|
|
887
|
+
* - `previousItemId`: ID of the previous item, if any.
|
|
888
|
+
* - `item`: the completed conversation item.
|
|
889
|
+
*/
|
|
890
|
+
export class ConversationItemDone extends ServerEvent {
|
|
891
|
+
static _nested = { item: model(ConversationItem) };
|
|
892
|
+
previousItemId;
|
|
893
|
+
item;
|
|
894
|
+
constructor(options) {
|
|
895
|
+
super(options);
|
|
896
|
+
this.type = literal(options.type, "conversation.item.done", "ConversationItemDone");
|
|
897
|
+
this.previousItemId = options.previousItemId ?? null;
|
|
898
|
+
this.item = required(options, "item", "ConversationItemDone");
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
/**
|
|
902
|
+
* Event containing incremental input audio transcription.
|
|
903
|
+
*
|
|
904
|
+
* - `type`: event type, always "conversation.item.input_audio_transcription.delta".
|
|
905
|
+
* - `itemId`: ID of the conversation item being transcribed.
|
|
906
|
+
* - `contentIndex`: index of the content within the item.
|
|
907
|
+
* - `delta`: incremental transcription text.
|
|
908
|
+
*/
|
|
909
|
+
export class ConversationItemInputAudioTranscriptionDelta extends ServerEvent {
|
|
910
|
+
itemId;
|
|
911
|
+
contentIndex;
|
|
912
|
+
delta;
|
|
913
|
+
constructor(options) {
|
|
914
|
+
super(options);
|
|
915
|
+
const name = "ConversationItemInputAudioTranscriptionDelta";
|
|
916
|
+
this.type = literal(options.type, "conversation.item.input_audio_transcription.delta", name);
|
|
917
|
+
this.itemId = required(options, "itemId", name);
|
|
918
|
+
this.contentIndex = required(options, "contentIndex", name);
|
|
919
|
+
this.delta = required(options, "delta", name);
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
/**
|
|
923
|
+
* Event indicating input audio transcription is complete.
|
|
924
|
+
*
|
|
925
|
+
* - `type`: event type, always "conversation.item.input_audio_transcription.completed".
|
|
926
|
+
* - `itemId`: ID of the conversation item that was transcribed.
|
|
927
|
+
* - `contentIndex`: index of the content within the item.
|
|
928
|
+
* - `transcript`: complete transcription text.
|
|
929
|
+
*/
|
|
930
|
+
export class ConversationItemInputAudioTranscriptionCompleted extends ServerEvent {
|
|
931
|
+
itemId;
|
|
932
|
+
contentIndex;
|
|
933
|
+
transcript;
|
|
934
|
+
constructor(options) {
|
|
935
|
+
super(options);
|
|
936
|
+
const name = "ConversationItemInputAudioTranscriptionCompleted";
|
|
937
|
+
this.type = literal(options.type, "conversation.item.input_audio_transcription.completed", name);
|
|
938
|
+
this.itemId = required(options, "itemId", name);
|
|
939
|
+
this.contentIndex = required(options, "contentIndex", name);
|
|
940
|
+
this.transcript = required(options, "transcript", name);
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
/**
|
|
944
|
+
* Event indicating input audio transcription failed.
|
|
945
|
+
*
|
|
946
|
+
* - `type`: event type, always "conversation.item.input_audio_transcription.failed".
|
|
947
|
+
* - `itemId`: ID of the conversation item that failed transcription.
|
|
948
|
+
* - `contentIndex`: index of the content within the item.
|
|
949
|
+
* - `error`: error details for the transcription failure.
|
|
950
|
+
*/
|
|
951
|
+
export class ConversationItemInputAudioTranscriptionFailed extends ServerEvent {
|
|
952
|
+
static _nested = { error: model(RealtimeError) };
|
|
953
|
+
itemId;
|
|
954
|
+
contentIndex;
|
|
955
|
+
error;
|
|
956
|
+
constructor(options) {
|
|
957
|
+
super(options);
|
|
958
|
+
const name = "ConversationItemInputAudioTranscriptionFailed";
|
|
959
|
+
this.type = literal(options.type, "conversation.item.input_audio_transcription.failed", name);
|
|
960
|
+
this.itemId = required(options, "itemId", name);
|
|
961
|
+
this.contentIndex = required(options, "contentIndex", name);
|
|
962
|
+
this.error = required(options, "error", name);
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
/**
|
|
966
|
+
* Event indicating a conversation item has been truncated.
|
|
967
|
+
*
|
|
968
|
+
* - `type`: event type, always "conversation.item.truncated".
|
|
969
|
+
* - `itemId`: ID of the truncated conversation item.
|
|
970
|
+
* - `contentIndex`: index of the content within the item.
|
|
971
|
+
* - `audioEndMs`: end time in milliseconds for the truncated audio.
|
|
972
|
+
*/
|
|
973
|
+
export class ConversationItemTruncated extends ServerEvent {
|
|
974
|
+
itemId;
|
|
975
|
+
contentIndex;
|
|
976
|
+
audioEndMs;
|
|
977
|
+
constructor(options) {
|
|
978
|
+
super(options);
|
|
979
|
+
const name = "ConversationItemTruncated";
|
|
980
|
+
this.type = literal(options.type, "conversation.item.truncated", name);
|
|
981
|
+
this.itemId = required(options, "itemId", name);
|
|
982
|
+
this.contentIndex = required(options, "contentIndex", name);
|
|
983
|
+
this.audioEndMs = required(options, "audioEndMs", name);
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
/**
|
|
987
|
+
* Event indicating a conversation item has been deleted.
|
|
988
|
+
*
|
|
989
|
+
* - `type`: event type, always "conversation.item.deleted".
|
|
990
|
+
* - `itemId`: ID of the deleted conversation item.
|
|
991
|
+
*/
|
|
992
|
+
export class ConversationItemDeleted extends ServerEvent {
|
|
993
|
+
itemId;
|
|
994
|
+
constructor(options) {
|
|
995
|
+
super(options);
|
|
996
|
+
this.type = literal(options.type, "conversation.item.deleted", "ConversationItemDeleted");
|
|
997
|
+
this.itemId = required(options, "itemId", "ConversationItemDeleted");
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
/**
|
|
1001
|
+
* Event containing a retrieved conversation item.
|
|
1002
|
+
*
|
|
1003
|
+
* - `type`: event type, always "conversation.item.retrieved".
|
|
1004
|
+
* - `item`: the retrieved conversation item.
|
|
1005
|
+
*/
|
|
1006
|
+
export class ConversationItemRetrieved extends ServerEvent {
|
|
1007
|
+
static _nested = { item: model(ConversationItem) };
|
|
1008
|
+
item;
|
|
1009
|
+
constructor(options) {
|
|
1010
|
+
super(options);
|
|
1011
|
+
this.type = literal(options.type, "conversation.item.retrieved", "ConversationItemRetrieved");
|
|
1012
|
+
this.item = required(options, "item", "ConversationItemRetrieved");
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
/**
|
|
1016
|
+
* Event indicating an assistant response has been created.
|
|
1017
|
+
*
|
|
1018
|
+
* - `type`: event type, always "response.created".
|
|
1019
|
+
* - `response`: the created response object.
|
|
1020
|
+
*/
|
|
1021
|
+
export class ResponseCreated extends ServerEvent {
|
|
1022
|
+
// `Response` is declared below; resolved lazily, like upstream's forward reference.
|
|
1023
|
+
static _nested = {
|
|
1024
|
+
response: (value) => (value === null ? null : Response.modelValidate(value)),
|
|
1025
|
+
};
|
|
1026
|
+
response;
|
|
1027
|
+
constructor(options) {
|
|
1028
|
+
super(options);
|
|
1029
|
+
this.type = literal(options.type, "response.created", "ResponseCreated");
|
|
1030
|
+
this.response = required(options, "response", "ResponseCreated");
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
/**
|
|
1034
|
+
* Event indicating an assistant response is complete.
|
|
1035
|
+
*
|
|
1036
|
+
* - `type`: event type, always "response.done".
|
|
1037
|
+
* - `response`: the completed response object.
|
|
1038
|
+
*/
|
|
1039
|
+
export class ResponseDone extends ServerEvent {
|
|
1040
|
+
static _nested = {
|
|
1041
|
+
response: (value) => (value === null ? null : Response.modelValidate(value)),
|
|
1042
|
+
};
|
|
1043
|
+
response;
|
|
1044
|
+
constructor(options) {
|
|
1045
|
+
super(options);
|
|
1046
|
+
this.type = literal(options.type, "response.done", "ResponseDone");
|
|
1047
|
+
this.response = required(options, "response", "ResponseDone");
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
/**
|
|
1051
|
+
* Event indicating an output item has been added to a response.
|
|
1052
|
+
*
|
|
1053
|
+
* - `type`: event type, always "response.output_item.added".
|
|
1054
|
+
* - `responseId`: ID of the response.
|
|
1055
|
+
* - `outputIndex`: index of the output item.
|
|
1056
|
+
* - `item`: the added conversation item.
|
|
1057
|
+
*/
|
|
1058
|
+
export class ResponseOutputItemAdded extends ServerEvent {
|
|
1059
|
+
static _nested = { item: model(ConversationItem) };
|
|
1060
|
+
responseId;
|
|
1061
|
+
outputIndex;
|
|
1062
|
+
item;
|
|
1063
|
+
constructor(options) {
|
|
1064
|
+
super(options);
|
|
1065
|
+
const name = "ResponseOutputItemAdded";
|
|
1066
|
+
this.type = literal(options.type, "response.output_item.added", name);
|
|
1067
|
+
this.responseId = required(options, "responseId", name);
|
|
1068
|
+
this.outputIndex = required(options, "outputIndex", name);
|
|
1069
|
+
this.item = required(options, "item", name);
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
/**
|
|
1073
|
+
* Event indicating an output item is complete.
|
|
1074
|
+
*
|
|
1075
|
+
* - `type`: event type, always "response.output_item.done".
|
|
1076
|
+
* - `responseId`: ID of the response.
|
|
1077
|
+
* - `outputIndex`: index of the output item.
|
|
1078
|
+
* - `item`: the completed conversation item.
|
|
1079
|
+
*/
|
|
1080
|
+
export class ResponseOutputItemDone extends ServerEvent {
|
|
1081
|
+
static _nested = { item: model(ConversationItem) };
|
|
1082
|
+
responseId;
|
|
1083
|
+
outputIndex;
|
|
1084
|
+
item;
|
|
1085
|
+
constructor(options) {
|
|
1086
|
+
super(options);
|
|
1087
|
+
const name = "ResponseOutputItemDone";
|
|
1088
|
+
this.type = literal(options.type, "response.output_item.done", name);
|
|
1089
|
+
this.responseId = required(options, "responseId", name);
|
|
1090
|
+
this.outputIndex = required(options, "outputIndex", name);
|
|
1091
|
+
this.item = required(options, "item", name);
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
/**
|
|
1095
|
+
* Event indicating a content part has been added to a response.
|
|
1096
|
+
*
|
|
1097
|
+
* - `type`: event type, always "response.content_part.added".
|
|
1098
|
+
* - `responseId`: ID of the response.
|
|
1099
|
+
* - `itemId`: ID of the conversation item.
|
|
1100
|
+
* - `outputIndex`: index of the output item.
|
|
1101
|
+
* - `contentIndex`: index of the content part.
|
|
1102
|
+
* - `part`: the added content part.
|
|
1103
|
+
*/
|
|
1104
|
+
export class ResponseContentPartAdded extends ServerEvent {
|
|
1105
|
+
static _nested = { part: model(ItemContent) };
|
|
1106
|
+
responseId;
|
|
1107
|
+
itemId;
|
|
1108
|
+
outputIndex;
|
|
1109
|
+
contentIndex;
|
|
1110
|
+
part;
|
|
1111
|
+
constructor(options) {
|
|
1112
|
+
super(options);
|
|
1113
|
+
const name = "ResponseContentPartAdded";
|
|
1114
|
+
this.type = literal(options.type, "response.content_part.added", name);
|
|
1115
|
+
this.responseId = required(options, "responseId", name);
|
|
1116
|
+
this.itemId = required(options, "itemId", name);
|
|
1117
|
+
this.outputIndex = required(options, "outputIndex", name);
|
|
1118
|
+
this.contentIndex = required(options, "contentIndex", name);
|
|
1119
|
+
this.part = required(options, "part", name);
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
/**
|
|
1123
|
+
* Event indicating a content part is complete.
|
|
1124
|
+
*
|
|
1125
|
+
* - `type`: event type, always "response.content_part.done".
|
|
1126
|
+
* - `responseId`: ID of the response.
|
|
1127
|
+
* - `itemId`: ID of the conversation item.
|
|
1128
|
+
* - `outputIndex`: index of the output item.
|
|
1129
|
+
* - `contentIndex`: index of the content part.
|
|
1130
|
+
* - `part`: the completed content part.
|
|
1131
|
+
*/
|
|
1132
|
+
export class ResponseContentPartDone extends ServerEvent {
|
|
1133
|
+
static _nested = { part: model(ItemContent) };
|
|
1134
|
+
responseId;
|
|
1135
|
+
itemId;
|
|
1136
|
+
outputIndex;
|
|
1137
|
+
contentIndex;
|
|
1138
|
+
part;
|
|
1139
|
+
constructor(options) {
|
|
1140
|
+
super(options);
|
|
1141
|
+
const name = "ResponseContentPartDone";
|
|
1142
|
+
this.type = literal(options.type, "response.content_part.done", name);
|
|
1143
|
+
this.responseId = required(options, "responseId", name);
|
|
1144
|
+
this.itemId = required(options, "itemId", name);
|
|
1145
|
+
this.outputIndex = required(options, "outputIndex", name);
|
|
1146
|
+
this.contentIndex = required(options, "contentIndex", name);
|
|
1147
|
+
this.part = required(options, "part", name);
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
/**
|
|
1151
|
+
* Event containing incremental text from a response.
|
|
1152
|
+
*
|
|
1153
|
+
* - `type`: event type, always "response.output_text.delta".
|
|
1154
|
+
* - `responseId`: ID of the response.
|
|
1155
|
+
* - `itemId`: ID of the conversation item.
|
|
1156
|
+
* - `outputIndex`: index of the output item.
|
|
1157
|
+
* - `contentIndex`: index of the content part.
|
|
1158
|
+
* - `delta`: incremental text content.
|
|
1159
|
+
*/
|
|
1160
|
+
export class ResponseTextDelta extends ServerEvent {
|
|
1161
|
+
responseId;
|
|
1162
|
+
itemId;
|
|
1163
|
+
outputIndex;
|
|
1164
|
+
contentIndex;
|
|
1165
|
+
delta;
|
|
1166
|
+
constructor(options) {
|
|
1167
|
+
super(options);
|
|
1168
|
+
const name = "ResponseTextDelta";
|
|
1169
|
+
this.type = literal(options.type, "response.output_text.delta", name);
|
|
1170
|
+
this.responseId = required(options, "responseId", name);
|
|
1171
|
+
this.itemId = required(options, "itemId", name);
|
|
1172
|
+
this.outputIndex = required(options, "outputIndex", name);
|
|
1173
|
+
this.contentIndex = required(options, "contentIndex", name);
|
|
1174
|
+
this.delta = required(options, "delta", name);
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
/**
|
|
1178
|
+
* Event indicating text content is complete.
|
|
1179
|
+
*
|
|
1180
|
+
* - `type`: event type, always "response.output_text.done".
|
|
1181
|
+
* - `responseId`: ID of the response.
|
|
1182
|
+
* - `itemId`: ID of the conversation item.
|
|
1183
|
+
* - `outputIndex`: index of the output item.
|
|
1184
|
+
* - `contentIndex`: index of the content part.
|
|
1185
|
+
* - `text`: complete text content.
|
|
1186
|
+
*/
|
|
1187
|
+
export class ResponseTextDone extends ServerEvent {
|
|
1188
|
+
responseId;
|
|
1189
|
+
itemId;
|
|
1190
|
+
outputIndex;
|
|
1191
|
+
contentIndex;
|
|
1192
|
+
text;
|
|
1193
|
+
constructor(options) {
|
|
1194
|
+
super(options);
|
|
1195
|
+
const name = "ResponseTextDone";
|
|
1196
|
+
this.type = literal(options.type, "response.output_text.done", name);
|
|
1197
|
+
this.responseId = required(options, "responseId", name);
|
|
1198
|
+
this.itemId = required(options, "itemId", name);
|
|
1199
|
+
this.outputIndex = required(options, "outputIndex", name);
|
|
1200
|
+
this.contentIndex = required(options, "contentIndex", name);
|
|
1201
|
+
this.text = required(options, "text", name);
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
/**
|
|
1205
|
+
* Event containing incremental audio transcript from a response.
|
|
1206
|
+
*
|
|
1207
|
+
* - `type`: event type, always "response.output_audio_transcript.delta".
|
|
1208
|
+
* - `responseId`: ID of the response.
|
|
1209
|
+
* - `itemId`: ID of the conversation item.
|
|
1210
|
+
* - `outputIndex`: index of the output item.
|
|
1211
|
+
* - `contentIndex`: index of the content part.
|
|
1212
|
+
* - `delta`: incremental transcript text.
|
|
1213
|
+
*/
|
|
1214
|
+
export class ResponseAudioTranscriptDelta extends ServerEvent {
|
|
1215
|
+
responseId;
|
|
1216
|
+
itemId;
|
|
1217
|
+
outputIndex;
|
|
1218
|
+
contentIndex;
|
|
1219
|
+
delta;
|
|
1220
|
+
constructor(options) {
|
|
1221
|
+
super(options);
|
|
1222
|
+
const name = "ResponseAudioTranscriptDelta";
|
|
1223
|
+
this.type = literal(options.type, "response.output_audio_transcript.delta", name);
|
|
1224
|
+
this.responseId = required(options, "responseId", name);
|
|
1225
|
+
this.itemId = required(options, "itemId", name);
|
|
1226
|
+
this.outputIndex = required(options, "outputIndex", name);
|
|
1227
|
+
this.contentIndex = required(options, "contentIndex", name);
|
|
1228
|
+
this.delta = required(options, "delta", name);
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
/**
|
|
1232
|
+
* Event indicating audio transcript is complete.
|
|
1233
|
+
*
|
|
1234
|
+
* - `type`: event type, always "response.output_audio_transcript.done".
|
|
1235
|
+
* - `responseId`: ID of the response.
|
|
1236
|
+
* - `itemId`: ID of the conversation item.
|
|
1237
|
+
* - `outputIndex`: index of the output item.
|
|
1238
|
+
* - `contentIndex`: index of the content part.
|
|
1239
|
+
* - `transcript`: complete transcript text.
|
|
1240
|
+
*/
|
|
1241
|
+
export class ResponseAudioTranscriptDone extends ServerEvent {
|
|
1242
|
+
responseId;
|
|
1243
|
+
itemId;
|
|
1244
|
+
outputIndex;
|
|
1245
|
+
contentIndex;
|
|
1246
|
+
transcript;
|
|
1247
|
+
constructor(options) {
|
|
1248
|
+
super(options);
|
|
1249
|
+
const name = "ResponseAudioTranscriptDone";
|
|
1250
|
+
this.type = literal(options.type, "response.output_audio_transcript.done", name);
|
|
1251
|
+
this.responseId = required(options, "responseId", name);
|
|
1252
|
+
this.itemId = required(options, "itemId", name);
|
|
1253
|
+
this.outputIndex = required(options, "outputIndex", name);
|
|
1254
|
+
this.contentIndex = required(options, "contentIndex", name);
|
|
1255
|
+
this.transcript = required(options, "transcript", name);
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
/**
|
|
1259
|
+
* Event containing incremental audio data from a response.
|
|
1260
|
+
*
|
|
1261
|
+
* - `type`: event type, always "response.output_audio.delta".
|
|
1262
|
+
* - `responseId`: ID of the response.
|
|
1263
|
+
* - `itemId`: ID of the conversation item.
|
|
1264
|
+
* - `outputIndex`: index of the output item.
|
|
1265
|
+
* - `contentIndex`: index of the content part.
|
|
1266
|
+
* - `delta`: base64-encoded incremental audio data.
|
|
1267
|
+
*/
|
|
1268
|
+
export class ResponseAudioDelta extends ServerEvent {
|
|
1269
|
+
responseId;
|
|
1270
|
+
itemId;
|
|
1271
|
+
outputIndex;
|
|
1272
|
+
contentIndex;
|
|
1273
|
+
delta; // base64-encoded audio
|
|
1274
|
+
constructor(options) {
|
|
1275
|
+
super(options);
|
|
1276
|
+
const name = "ResponseAudioDelta";
|
|
1277
|
+
this.type = literal(options.type, "response.output_audio.delta", name);
|
|
1278
|
+
this.responseId = required(options, "responseId", name);
|
|
1279
|
+
this.itemId = required(options, "itemId", name);
|
|
1280
|
+
this.outputIndex = required(options, "outputIndex", name);
|
|
1281
|
+
this.contentIndex = required(options, "contentIndex", name);
|
|
1282
|
+
this.delta = required(options, "delta", name);
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
/**
|
|
1286
|
+
* Event indicating audio content is complete.
|
|
1287
|
+
*
|
|
1288
|
+
* - `type`: event type, always "response.output_audio.done".
|
|
1289
|
+
* - `responseId`: ID of the response.
|
|
1290
|
+
* - `itemId`: ID of the conversation item.
|
|
1291
|
+
* - `outputIndex`: index of the output item.
|
|
1292
|
+
* - `contentIndex`: index of the content part.
|
|
1293
|
+
*/
|
|
1294
|
+
export class ResponseAudioDone extends ServerEvent {
|
|
1295
|
+
responseId;
|
|
1296
|
+
itemId;
|
|
1297
|
+
outputIndex;
|
|
1298
|
+
contentIndex;
|
|
1299
|
+
constructor(options) {
|
|
1300
|
+
super(options);
|
|
1301
|
+
const name = "ResponseAudioDone";
|
|
1302
|
+
this.type = literal(options.type, "response.output_audio.done", name);
|
|
1303
|
+
this.responseId = required(options, "responseId", name);
|
|
1304
|
+
this.itemId = required(options, "itemId", name);
|
|
1305
|
+
this.outputIndex = required(options, "outputIndex", name);
|
|
1306
|
+
this.contentIndex = required(options, "contentIndex", name);
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
/**
|
|
1310
|
+
* Event containing incremental function call arguments.
|
|
1311
|
+
*
|
|
1312
|
+
* - `type`: event type, always "response.function_call_arguments.delta".
|
|
1313
|
+
* - `responseId`: ID of the response.
|
|
1314
|
+
* - `itemId`: ID of the conversation item.
|
|
1315
|
+
* - `outputIndex`: index of the output item.
|
|
1316
|
+
* - `callId`: ID of the function call.
|
|
1317
|
+
* - `delta`: incremental function arguments as JSON.
|
|
1318
|
+
*/
|
|
1319
|
+
export class ResponseFunctionCallArgumentsDelta extends ServerEvent {
|
|
1320
|
+
responseId;
|
|
1321
|
+
itemId;
|
|
1322
|
+
outputIndex;
|
|
1323
|
+
callId;
|
|
1324
|
+
delta;
|
|
1325
|
+
constructor(options) {
|
|
1326
|
+
super(options);
|
|
1327
|
+
const name = "ResponseFunctionCallArgumentsDelta";
|
|
1328
|
+
this.type = literal(options.type, "response.function_call_arguments.delta", name);
|
|
1329
|
+
this.responseId = required(options, "responseId", name);
|
|
1330
|
+
this.itemId = required(options, "itemId", name);
|
|
1331
|
+
this.outputIndex = required(options, "outputIndex", name);
|
|
1332
|
+
this.callId = required(options, "callId", name);
|
|
1333
|
+
this.delta = required(options, "delta", name);
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
/**
|
|
1337
|
+
* Event indicating function call arguments are complete.
|
|
1338
|
+
*
|
|
1339
|
+
* - `type`: event type, always "response.function_call_arguments.done".
|
|
1340
|
+
* - `responseId`: ID of the response.
|
|
1341
|
+
* - `itemId`: ID of the conversation item.
|
|
1342
|
+
* - `outputIndex`: index of the output item.
|
|
1343
|
+
* - `callId`: ID of the function call.
|
|
1344
|
+
* - `arguments`: complete function arguments as JSON string.
|
|
1345
|
+
*/
|
|
1346
|
+
export class ResponseFunctionCallArgumentsDone extends ServerEvent {
|
|
1347
|
+
responseId;
|
|
1348
|
+
itemId;
|
|
1349
|
+
outputIndex;
|
|
1350
|
+
callId;
|
|
1351
|
+
arguments;
|
|
1352
|
+
constructor(options) {
|
|
1353
|
+
super(options);
|
|
1354
|
+
const name = "ResponseFunctionCallArgumentsDone";
|
|
1355
|
+
this.type = literal(options.type, "response.function_call_arguments.done", name);
|
|
1356
|
+
this.responseId = required(options, "responseId", name);
|
|
1357
|
+
this.itemId = required(options, "itemId", name);
|
|
1358
|
+
this.outputIndex = required(options, "outputIndex", name);
|
|
1359
|
+
this.callId = required(options, "callId", name);
|
|
1360
|
+
this.arguments = required(options, "arguments", name);
|
|
1361
|
+
}
|
|
1362
|
+
}
|
|
1363
|
+
/**
|
|
1364
|
+
* Event indicating speech has started in the input audio buffer.
|
|
1365
|
+
*
|
|
1366
|
+
* - `type`: event type, always "input_audio_buffer.speech_started".
|
|
1367
|
+
* - `audioStartMs`: start time of speech in milliseconds.
|
|
1368
|
+
* - `itemId`: ID of the associated conversation item.
|
|
1369
|
+
*/
|
|
1370
|
+
export class InputAudioBufferSpeechStarted extends ServerEvent {
|
|
1371
|
+
audioStartMs;
|
|
1372
|
+
itemId;
|
|
1373
|
+
constructor(options) {
|
|
1374
|
+
super(options);
|
|
1375
|
+
const name = "InputAudioBufferSpeechStarted";
|
|
1376
|
+
this.type = literal(options.type, "input_audio_buffer.speech_started", name);
|
|
1377
|
+
this.audioStartMs = required(options, "audioStartMs", name);
|
|
1378
|
+
this.itemId = required(options, "itemId", name);
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
/**
|
|
1382
|
+
* Event indicating speech has stopped in the input audio buffer.
|
|
1383
|
+
*
|
|
1384
|
+
* - `type`: event type, always "input_audio_buffer.speech_stopped".
|
|
1385
|
+
* - `audioEndMs`: end time of speech in milliseconds.
|
|
1386
|
+
* - `itemId`: ID of the associated conversation item.
|
|
1387
|
+
*/
|
|
1388
|
+
export class InputAudioBufferSpeechStopped extends ServerEvent {
|
|
1389
|
+
audioEndMs;
|
|
1390
|
+
itemId;
|
|
1391
|
+
constructor(options) {
|
|
1392
|
+
super(options);
|
|
1393
|
+
const name = "InputAudioBufferSpeechStopped";
|
|
1394
|
+
this.type = literal(options.type, "input_audio_buffer.speech_stopped", name);
|
|
1395
|
+
this.audioEndMs = required(options, "audioEndMs", name);
|
|
1396
|
+
this.itemId = required(options, "itemId", name);
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
/**
|
|
1400
|
+
* Event indicating the input audio buffer has been committed.
|
|
1401
|
+
*
|
|
1402
|
+
* - `type`: event type, always "input_audio_buffer.committed".
|
|
1403
|
+
* - `previousItemId`: ID of the previous item, if any.
|
|
1404
|
+
* - `itemId`: ID of the committed conversation item.
|
|
1405
|
+
*/
|
|
1406
|
+
export class InputAudioBufferCommitted extends ServerEvent {
|
|
1407
|
+
previousItemId;
|
|
1408
|
+
itemId;
|
|
1409
|
+
constructor(options) {
|
|
1410
|
+
super(options);
|
|
1411
|
+
const name = "InputAudioBufferCommitted";
|
|
1412
|
+
this.type = literal(options.type, "input_audio_buffer.committed", name);
|
|
1413
|
+
this.previousItemId = options.previousItemId ?? null;
|
|
1414
|
+
this.itemId = required(options, "itemId", name);
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
/**
|
|
1418
|
+
* Event indicating the input audio buffer has been cleared.
|
|
1419
|
+
*
|
|
1420
|
+
* - `type`: event type, always "input_audio_buffer.cleared".
|
|
1421
|
+
*/
|
|
1422
|
+
export class InputAudioBufferCleared extends ServerEvent {
|
|
1423
|
+
constructor(options) {
|
|
1424
|
+
super(options);
|
|
1425
|
+
this.type = literal(options.type, "input_audio_buffer.cleared", "InputAudioBufferCleared");
|
|
1426
|
+
}
|
|
1427
|
+
}
|
|
1428
|
+
/**
|
|
1429
|
+
* Event indicating an error occurred.
|
|
1430
|
+
*
|
|
1431
|
+
* - `type`: event type, always "error".
|
|
1432
|
+
* - `error`: error details.
|
|
1433
|
+
*/
|
|
1434
|
+
export class ErrorEvent extends ServerEvent {
|
|
1435
|
+
static _nested = { error: model(RealtimeError) };
|
|
1436
|
+
error;
|
|
1437
|
+
constructor(options) {
|
|
1438
|
+
super(options);
|
|
1439
|
+
this.type = literal(options.type, "error", "ErrorEvent");
|
|
1440
|
+
this.error = required(options, "error", "ErrorEvent");
|
|
1441
|
+
}
|
|
1442
|
+
}
|
|
1443
|
+
/**
|
|
1444
|
+
* Event indicating rate limits have been updated.
|
|
1445
|
+
*
|
|
1446
|
+
* - `type`: event type, always "rate_limits.updated".
|
|
1447
|
+
* - `rateLimits`: list of rate limit information.
|
|
1448
|
+
*/
|
|
1449
|
+
export class RateLimitsUpdated extends ServerEvent {
|
|
1450
|
+
rateLimits;
|
|
1451
|
+
constructor(options) {
|
|
1452
|
+
super(options);
|
|
1453
|
+
this.type = literal(options.type, "rate_limits.updated", "RateLimitsUpdated");
|
|
1454
|
+
this.rateLimits = required(options, "rateLimits", "RateLimitsUpdated");
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
1457
|
+
/**
|
|
1458
|
+
* Details about cached tokens.
|
|
1459
|
+
*
|
|
1460
|
+
* - `textTokens`: number of cached text tokens.
|
|
1461
|
+
* - `audioTokens`: number of cached audio tokens.
|
|
1462
|
+
*/
|
|
1463
|
+
export class CachedTokensDetails extends BaseModel {
|
|
1464
|
+
textTokens;
|
|
1465
|
+
audioTokens;
|
|
1466
|
+
constructor(options = {}) {
|
|
1467
|
+
super();
|
|
1468
|
+
this.textTokens = options.textTokens === undefined ? 0 : options.textTokens;
|
|
1469
|
+
this.audioTokens = options.audioTokens === undefined ? 0 : options.audioTokens;
|
|
1470
|
+
}
|
|
1471
|
+
}
|
|
1472
|
+
/**
|
|
1473
|
+
* Detailed token usage information.
|
|
1474
|
+
*
|
|
1475
|
+
* Keys the model doesn't declare are kept (see `modelExtra`).
|
|
1476
|
+
*
|
|
1477
|
+
* - `cachedTokens`: number of cached tokens used. Defaults to 0.
|
|
1478
|
+
* - `textTokens`: number of text tokens used. Defaults to 0.
|
|
1479
|
+
* - `audioTokens`: number of audio tokens used. Defaults to 0.
|
|
1480
|
+
* - `cachedTokensDetails`: detailed breakdown of cached tokens.
|
|
1481
|
+
* - `imageTokens`: number of image tokens used (for input only).
|
|
1482
|
+
*/
|
|
1483
|
+
export class TokenDetails extends BaseModel {
|
|
1484
|
+
static _nested = {
|
|
1485
|
+
cachedTokensDetails: model(CachedTokensDetails),
|
|
1486
|
+
};
|
|
1487
|
+
static _extraAllowed = true;
|
|
1488
|
+
cachedTokens;
|
|
1489
|
+
textTokens;
|
|
1490
|
+
audioTokens;
|
|
1491
|
+
cachedTokensDetails;
|
|
1492
|
+
imageTokens;
|
|
1493
|
+
constructor(options = {}) {
|
|
1494
|
+
super();
|
|
1495
|
+
this.cachedTokens = options.cachedTokens === undefined ? 0 : options.cachedTokens;
|
|
1496
|
+
this.textTokens = options.textTokens === undefined ? 0 : options.textTokens;
|
|
1497
|
+
this.audioTokens = options.audioTokens === undefined ? 0 : options.audioTokens;
|
|
1498
|
+
this.cachedTokensDetails = options.cachedTokensDetails ?? null;
|
|
1499
|
+
this.imageTokens = options.imageTokens === undefined ? 0 : options.imageTokens;
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1502
|
+
/**
|
|
1503
|
+
* Token usage statistics for a response.
|
|
1504
|
+
*
|
|
1505
|
+
* - `totalTokens`: total number of tokens used.
|
|
1506
|
+
* - `inputTokens`: number of input tokens used.
|
|
1507
|
+
* - `outputTokens`: number of output tokens used.
|
|
1508
|
+
* - `inputTokenDetails`: detailed breakdown of input token usage.
|
|
1509
|
+
* - `outputTokenDetails`: detailed breakdown of output token usage.
|
|
1510
|
+
*/
|
|
1511
|
+
export class Usage extends BaseModel {
|
|
1512
|
+
static _nested = {
|
|
1513
|
+
inputTokenDetails: model(TokenDetails),
|
|
1514
|
+
outputTokenDetails: model(TokenDetails),
|
|
1515
|
+
};
|
|
1516
|
+
totalTokens;
|
|
1517
|
+
inputTokens;
|
|
1518
|
+
outputTokens;
|
|
1519
|
+
inputTokenDetails;
|
|
1520
|
+
outputTokenDetails;
|
|
1521
|
+
constructor(options) {
|
|
1522
|
+
super();
|
|
1523
|
+
this.totalTokens = required(options, "totalTokens", "Usage");
|
|
1524
|
+
this.inputTokens = required(options, "inputTokens", "Usage");
|
|
1525
|
+
this.outputTokens = required(options, "outputTokens", "Usage");
|
|
1526
|
+
this.inputTokenDetails = required(options, "inputTokenDetails", "Usage");
|
|
1527
|
+
this.outputTokenDetails = required(options, "outputTokenDetails", "Usage");
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
/**
|
|
1531
|
+
* A complete assistant response.
|
|
1532
|
+
*
|
|
1533
|
+
* - `id`: unique identifier for the response.
|
|
1534
|
+
* - `object`: object type, always "realtime.response".
|
|
1535
|
+
* - `status`: current status of the response.
|
|
1536
|
+
* - `statusDetails`: additional status information.
|
|
1537
|
+
* - `output`: list of conversation items in the response.
|
|
1538
|
+
* - `outputModalities`: the set of modalities the model used to respond.
|
|
1539
|
+
* - `maxOutputTokens`: maximum number of output tokens used.
|
|
1540
|
+
* - `audio`: audio configuration for the response.
|
|
1541
|
+
* - `usage`: token usage statistics for the response.
|
|
1542
|
+
* - `voice`: the voice the model used to respond.
|
|
1543
|
+
* - `temperature`: sampling temperature used for the response.
|
|
1544
|
+
* - `outputAudioFormat`: the format of output audio.
|
|
1545
|
+
*/
|
|
1546
|
+
export class Response extends BaseModel {
|
|
1547
|
+
static _nested = {
|
|
1548
|
+
output: listOf(model(ConversationItem)),
|
|
1549
|
+
audio: model(AudioConfiguration),
|
|
1550
|
+
usage: model(Usage),
|
|
1551
|
+
};
|
|
1552
|
+
id;
|
|
1553
|
+
object;
|
|
1554
|
+
status;
|
|
1555
|
+
statusDetails;
|
|
1556
|
+
output;
|
|
1557
|
+
outputModalities;
|
|
1558
|
+
maxOutputTokens;
|
|
1559
|
+
audio;
|
|
1560
|
+
usage;
|
|
1561
|
+
voice;
|
|
1562
|
+
temperature;
|
|
1563
|
+
outputAudioFormat;
|
|
1564
|
+
constructor(options) {
|
|
1565
|
+
super();
|
|
1566
|
+
this.id = required(options, "id", "Response");
|
|
1567
|
+
this.object = required(options, "object", "Response");
|
|
1568
|
+
this.status = required(options, "status", "Response");
|
|
1569
|
+
this.statusDetails = required(options, "statusDetails", "Response");
|
|
1570
|
+
this.output = required(options, "output", "Response");
|
|
1571
|
+
this.outputModalities = options.outputModalities ?? null;
|
|
1572
|
+
this.maxOutputTokens = options.maxOutputTokens ?? null;
|
|
1573
|
+
this.audio = options.audio ?? null;
|
|
1574
|
+
this.usage = options.usage ?? null;
|
|
1575
|
+
this.voice = options.voice ?? null;
|
|
1576
|
+
this.temperature = options.temperature ?? null;
|
|
1577
|
+
this.outputAudioFormat = options.outputAudioFormat ?? null;
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
const _serverEventTypes = {
|
|
1581
|
+
error: ErrorEvent,
|
|
1582
|
+
"session.created": SessionCreatedEvent,
|
|
1583
|
+
"session.updated": SessionUpdatedEvent,
|
|
1584
|
+
"conversation.created": ConversationCreated,
|
|
1585
|
+
"input_audio_buffer.committed": InputAudioBufferCommitted,
|
|
1586
|
+
"input_audio_buffer.cleared": InputAudioBufferCleared,
|
|
1587
|
+
"input_audio_buffer.speech_started": InputAudioBufferSpeechStarted,
|
|
1588
|
+
"input_audio_buffer.speech_stopped": InputAudioBufferSpeechStopped,
|
|
1589
|
+
"conversation.item.added": ConversationItemAdded,
|
|
1590
|
+
"conversation.item.done": ConversationItemDone,
|
|
1591
|
+
"conversation.item.input_audio_transcription.delta": ConversationItemInputAudioTranscriptionDelta,
|
|
1592
|
+
"conversation.item.input_audio_transcription.completed": ConversationItemInputAudioTranscriptionCompleted,
|
|
1593
|
+
"conversation.item.input_audio_transcription.failed": ConversationItemInputAudioTranscriptionFailed,
|
|
1594
|
+
"conversation.item.truncated": ConversationItemTruncated,
|
|
1595
|
+
"conversation.item.deleted": ConversationItemDeleted,
|
|
1596
|
+
"conversation.item.retrieved": ConversationItemRetrieved,
|
|
1597
|
+
"response.created": ResponseCreated,
|
|
1598
|
+
"response.done": ResponseDone,
|
|
1599
|
+
"response.output_item.added": ResponseOutputItemAdded,
|
|
1600
|
+
"response.output_item.done": ResponseOutputItemDone,
|
|
1601
|
+
"response.content_part.added": ResponseContentPartAdded,
|
|
1602
|
+
"response.content_part.done": ResponseContentPartDone,
|
|
1603
|
+
"response.output_text.delta": ResponseTextDelta,
|
|
1604
|
+
"response.output_text.done": ResponseTextDone,
|
|
1605
|
+
"response.output_audio_transcript.delta": ResponseAudioTranscriptDelta,
|
|
1606
|
+
"response.output_audio_transcript.done": ResponseAudioTranscriptDone,
|
|
1607
|
+
"response.output_audio.delta": ResponseAudioDelta,
|
|
1608
|
+
"response.output_audio.done": ResponseAudioDone,
|
|
1609
|
+
"response.function_call_arguments.delta": ResponseFunctionCallArgumentsDelta,
|
|
1610
|
+
"response.function_call_arguments.done": ResponseFunctionCallArgumentsDone,
|
|
1611
|
+
"rate_limits.updated": RateLimitsUpdated,
|
|
1612
|
+
};
|
|
1613
|
+
/**
|
|
1614
|
+
* Parse a server event from JSON string.
|
|
1615
|
+
*
|
|
1616
|
+
* @param str JSON string (or UTF-8 bytes) containing the server event.
|
|
1617
|
+
* @returns Parsed server event object of the appropriate type.
|
|
1618
|
+
* @throws Error If the event type is unimplemented or parsing fails.
|
|
1619
|
+
*/
|
|
1620
|
+
export function parseServerEvent(str) {
|
|
1621
|
+
const text = typeof str === "string" ? str : new TextDecoder().decode(str);
|
|
1622
|
+
try {
|
|
1623
|
+
const event = pyJsonLoads(text);
|
|
1624
|
+
if (!isPlainObject(event) || !("type" in event)) {
|
|
1625
|
+
// Python's KeyError for the missing key.
|
|
1626
|
+
throw new Error("'type'");
|
|
1627
|
+
}
|
|
1628
|
+
const eventType = event.type;
|
|
1629
|
+
if (typeof eventType !== "string" || !Object.hasOwn(_serverEventTypes, eventType)) {
|
|
1630
|
+
throw new Error(`Unimplemented server event type: ${eventType}`);
|
|
1631
|
+
}
|
|
1632
|
+
return _serverEventTypes[eventType].modelValidate(event);
|
|
1633
|
+
}
|
|
1634
|
+
catch (e) {
|
|
1635
|
+
rethrowIfCancelled(e);
|
|
1636
|
+
throw new Error(`${e instanceof Error ? e.message : String(e)} \n\n${text}`);
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1639
|
+
//# sourceMappingURL=events.js.map
|