@oxy.so/contracts 4.10.0 → 4.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/.tsbuildinfo +1 -1
- package/dist/cjs/accountGraph.js +5 -3
- package/dist/cjs/agency.js +178 -96
- package/dist/cjs/agentKeys.js +80 -26
- package/dist/cjs/capabilityBindings.js +2 -2
- package/dist/cjs/capabilityInvocation.js +3 -1
- package/dist/cjs/commonsSignIn.js +2 -2
- package/dist/cjs/deviceSession.js +5 -1
- package/dist/cjs/email/messages.js +70 -4
- package/dist/cjs/emailAgentContext.js +16 -8
- package/dist/cjs/externalIdentity.js +30 -12
- package/dist/cjs/identity.js +14 -6
- package/dist/cjs/identityLink.js +7 -2
- package/dist/cjs/identityProof.js +2 -1
- package/dist/cjs/index.js +23 -15
- package/dist/cjs/inference/catalogue.js +2 -12
- package/dist/cjs/inference/decisions.js +102 -83
- package/dist/cjs/inference/economics.js +15 -5
- package/dist/cjs/inference/embeddings.js +44 -6
- package/dist/cjs/inference/inbox.js +33 -2
- package/dist/cjs/inference/providerConnection.js +21 -6
- package/dist/cjs/inference/realtime.js +114 -107
- package/dist/cjs/inference/scopedExecution.js +12 -12
- package/dist/cjs/inference/usage.js +2 -9
- package/dist/cjs/notifications.js +25 -5
- package/dist/cjs/oauth.js +30 -14
- package/dist/cjs/oxyRecordTypes.js +2 -2
- package/dist/cjs/products/access.js +161 -41
- package/dist/cjs/products/billing.js +71 -17
- package/dist/cjs/products/checkout.js +35 -0
- package/dist/cjs/products/plans.js +38 -0
- package/dist/cjs/recommendations.js +4 -6
- package/dist/cjs/reputation.js +3 -6
- package/dist/cjs/sessionStatus.js +1 -6
- package/dist/cjs/signIn.js +17 -4
- package/dist/cjs/transparency.js +3 -1
- package/dist/cjs/updates.js +2 -4
- package/dist/cjs/userResponse.js +32 -9
- package/dist/cjs/username.js +3 -1
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/accountGraph.js +5 -3
- package/dist/esm/agency.js +178 -96
- package/dist/esm/agentKeys.js +80 -26
- package/dist/esm/capabilityBindings.js +2 -2
- package/dist/esm/capabilityInvocation.js +3 -1
- package/dist/esm/commonsSignIn.js +2 -2
- package/dist/esm/deviceSession.js +5 -1
- package/dist/esm/email/messages.js +69 -3
- package/dist/esm/emailAgentContext.js +16 -8
- package/dist/esm/externalIdentity.js +30 -12
- package/dist/esm/identity.js +14 -6
- package/dist/esm/identityLink.js +7 -2
- package/dist/esm/identityProof.js +2 -1
- package/dist/esm/index.js +10 -8
- package/dist/esm/inference/aliaModelRelease.js +1 -1
- package/dist/esm/inference/catalogue.js +3 -13
- package/dist/esm/inference/decisions.js +108 -89
- package/dist/esm/inference/economics.js +16 -6
- package/dist/esm/inference/embeddings.js +44 -6
- package/dist/esm/inference/inbox.js +32 -1
- package/dist/esm/inference/providerConnection.js +21 -6
- package/dist/esm/inference/realtime.js +123 -116
- package/dist/esm/inference/scopedExecution.js +15 -15
- package/dist/esm/inference/usage.js +2 -9
- package/dist/esm/notifications.js +25 -5
- package/dist/esm/oauth.js +30 -14
- package/dist/esm/oxyRecordTypes.js +2 -2
- package/dist/esm/products/access.js +160 -40
- package/dist/esm/products/billing.js +71 -17
- package/dist/esm/products/checkout.js +32 -0
- package/dist/esm/products/plans.js +35 -0
- package/dist/esm/recommendations.js +4 -6
- package/dist/esm/reputation.js +3 -6
- package/dist/esm/sessionStatus.js +1 -6
- package/dist/esm/signIn.js +17 -4
- package/dist/esm/transparency.js +3 -1
- package/dist/esm/updates.js +2 -4
- package/dist/esm/userResponse.js +28 -5
- package/dist/esm/username.js +3 -1
- package/dist/types/.tsbuildinfo +1 -1
- package/dist/types/accountGraph.d.ts +1 -1
- package/dist/types/commonsSignIn.d.ts +2 -2
- package/dist/types/email/messages.d.ts +208 -2
- package/dist/types/externalIdentity.d.ts +90 -0
- package/dist/types/identity.d.ts +1 -1
- package/dist/types/index.d.ts +12 -10
- package/dist/types/inference/decisions.d.ts +1 -1
- package/dist/types/inference/inbox.d.ts +129 -5
- package/dist/types/inference/realtime.d.ts +1 -1
- package/dist/types/inference/scopedExecution.d.ts +1 -1
- package/dist/types/moderationReputation.d.ts +1 -1
- package/dist/types/oxyRecordTypes.d.ts +2 -2
- package/dist/types/products/access.d.ts +405 -0
- package/dist/types/products/billing.d.ts +3 -0
- package/dist/types/products/checkout.d.ts +60 -0
- package/dist/types/products/plans.d.ts +319 -0
- package/dist/types/reputation.d.ts +4 -4
- package/dist/types/updates.d.ts +1 -1
- package/dist/types/userResponse.d.ts +388 -23
- package/package.json +1 -2
|
@@ -83,15 +83,15 @@
|
|
|
83
83
|
*
|
|
84
84
|
* Decided in: OxyHQ/Kaana#90.
|
|
85
85
|
*/
|
|
86
|
-
import { z } from
|
|
87
|
-
import { inferenceAttributionSchema } from
|
|
88
|
-
import { realtimeSessionKindSchema, realtimeSessionTransportSchema
|
|
89
|
-
import { inferenceErrorSchema } from
|
|
90
|
-
import { deploymentIdSchema, inferenceProviderSlugSchema, inferenceTimestampSchema, modelReferenceSchema, PADDED_BASE64_PATTERN, requestIdSchema, } from
|
|
91
|
-
import { usageQuantitySchema, usageSourceSchema } from
|
|
92
|
-
import { toolChoiceSchema, toolDefinitionSchema } from
|
|
93
|
-
import { authorizedRouteSchema, routingPolicyReferenceSchema
|
|
94
|
-
import { inferenceFinishReasonSchema } from
|
|
86
|
+
import { z } from 'zod';
|
|
87
|
+
import { inferenceAttributionSchema } from './attribution.js';
|
|
88
|
+
import { realtimeSessionKindSchema, realtimeSessionTransportSchema } from './catalogue.js';
|
|
89
|
+
import { inferenceErrorSchema } from './errors.js';
|
|
90
|
+
import { deploymentIdSchema, inferenceProviderSlugSchema, inferenceTimestampSchema, modelReferenceSchema, PADDED_BASE64_PATTERN, requestIdSchema, } from './identifiers.js';
|
|
91
|
+
import { usageQuantitySchema, usageSourceSchema } from './money.js';
|
|
92
|
+
import { toolChoiceSchema, toolDefinitionSchema } from './request.js';
|
|
93
|
+
import { authorizedRouteSchema, routingPolicyReferenceSchema } from './routingPolicy.js';
|
|
94
|
+
import { inferenceFinishReasonSchema } from './streamEvents.js';
|
|
95
95
|
/* -------------------------------------------------------------------------- */
|
|
96
96
|
/* Bounds */
|
|
97
97
|
/* -------------------------------------------------------------------------- */
|
|
@@ -125,13 +125,9 @@ export const realtimeResponseIdSchema = z.string().min(1).max(128);
|
|
|
125
125
|
* The audio encodings a session carries, in both directions. Named by what they
|
|
126
126
|
* ARE (sample format, rate) because a realtime stream has no container to say so.
|
|
127
127
|
*/
|
|
128
|
-
export const realtimeAudioFormatSchema = z.enum([
|
|
129
|
-
"pcm16_24khz",
|
|
130
|
-
"g711_ulaw",
|
|
131
|
-
"g711_alaw",
|
|
132
|
-
]);
|
|
128
|
+
export const realtimeAudioFormatSchema = z.enum(['pcm16_24khz', 'g711_ulaw', 'g711_alaw']);
|
|
133
129
|
/** What a session's responses produce. */
|
|
134
|
-
export const realtimeOutputModalitySchema = z.enum([
|
|
130
|
+
export const realtimeOutputModalitySchema = z.enum(['text', 'audio']);
|
|
135
131
|
const audioFrameSchema = z
|
|
136
132
|
.string()
|
|
137
133
|
.min(4)
|
|
@@ -151,11 +147,11 @@ const milliseconds = z.number().int().nonnegative().safe();
|
|
|
151
147
|
* off, are the two behaviours a caller most needs to have chosen, and a default
|
|
152
148
|
* would choose them silently — and differently per provider.
|
|
153
149
|
*/
|
|
154
|
-
export const realtimeTurnDetectionSchema = z.discriminatedUnion(
|
|
155
|
-
z.object({ type: z.literal(
|
|
150
|
+
export const realtimeTurnDetectionSchema = z.discriminatedUnion('type', [
|
|
151
|
+
z.object({ type: z.literal('none') }).strict(),
|
|
156
152
|
z
|
|
157
153
|
.object({
|
|
158
|
-
type: z.literal(
|
|
154
|
+
type: z.literal('server_vad'),
|
|
159
155
|
threshold: z.number().min(0).max(1).optional(),
|
|
160
156
|
prefixPaddingMs: z.number().int().min(0).max(5000).optional(),
|
|
161
157
|
silenceDurationMs: z.number().int().min(0).max(10000).optional(),
|
|
@@ -165,8 +161,8 @@ export const realtimeTurnDetectionSchema = z.discriminatedUnion("type", [
|
|
|
165
161
|
.strict(),
|
|
166
162
|
z
|
|
167
163
|
.object({
|
|
168
|
-
type: z.literal(
|
|
169
|
-
eagerness: z.enum([
|
|
164
|
+
type: z.literal('semantic_vad'),
|
|
165
|
+
eagerness: z.enum(['low', 'medium', 'high', 'auto']),
|
|
170
166
|
createResponse: z.boolean(),
|
|
171
167
|
interruptResponse: z.boolean(),
|
|
172
168
|
})
|
|
@@ -241,7 +237,7 @@ export const realtimeSessionConfigUpdateSchema = z
|
|
|
241
237
|
if (Object.keys(update).length === 0) {
|
|
242
238
|
ctx.addIssue({
|
|
243
239
|
code: z.ZodIssueCode.custom,
|
|
244
|
-
message:
|
|
240
|
+
message: 'a session update changes at least one field',
|
|
245
241
|
});
|
|
246
242
|
}
|
|
247
243
|
});
|
|
@@ -277,7 +273,7 @@ export const realtimeClientMetadataSchema = z
|
|
|
277
273
|
/* The session request */
|
|
278
274
|
/* -------------------------------------------------------------------------- */
|
|
279
275
|
const modelLineOf = (reference) => {
|
|
280
|
-
const at = reference.indexOf(
|
|
276
|
+
const at = reference.indexOf('@');
|
|
281
277
|
return at === -1 ? reference : reference.slice(0, at);
|
|
282
278
|
};
|
|
283
279
|
/**
|
|
@@ -302,72 +298,83 @@ export const realtimeSessionRequestSchema = z
|
|
|
302
298
|
const { config } = request;
|
|
303
299
|
const issue = (path, message) => ctx.addIssue({ code: z.ZodIssueCode.custom, path, message });
|
|
304
300
|
if (request.limits.idleTimeoutMs > request.limits.maxDurationMs) {
|
|
305
|
-
issue([
|
|
301
|
+
issue(['limits', 'idleTimeoutMs'], 'an idle timeout cannot outlast the session');
|
|
306
302
|
}
|
|
307
|
-
const producesAudio = config.outputModalities?.includes(
|
|
303
|
+
const producesAudio = config.outputModalities?.includes('audio') === true;
|
|
308
304
|
const hasTools = config.tools !== undefined && config.tools.length > 0;
|
|
309
305
|
switch (request.kind) {
|
|
310
|
-
case
|
|
306
|
+
case 'conversation':
|
|
311
307
|
if (config.outputModalities === undefined) {
|
|
312
|
-
issue([
|
|
308
|
+
issue(['config', 'outputModalities'], 'a conversation names what its responses produce');
|
|
313
309
|
}
|
|
314
|
-
if (producesAudio &&
|
|
315
|
-
|
|
310
|
+
if (producesAudio &&
|
|
311
|
+
(config.voice === undefined || config.outputAudioFormat === undefined)) {
|
|
312
|
+
issue(['config'], 'spoken responses need a voice and an output audio format');
|
|
316
313
|
}
|
|
317
314
|
if (config.translation !== undefined) {
|
|
318
|
-
issue([
|
|
315
|
+
issue(['config', 'translation'], 'only a translation session translates');
|
|
319
316
|
}
|
|
320
317
|
break;
|
|
321
|
-
case
|
|
318
|
+
case 'transcription':
|
|
322
319
|
if (config.inputAudioTranscription === undefined) {
|
|
323
|
-
issue([
|
|
320
|
+
issue(['config', 'inputAudioTranscription'], 'a transcription session transcribes its input');
|
|
324
321
|
}
|
|
325
|
-
for (const field of [
|
|
322
|
+
for (const field of [
|
|
323
|
+
'outputModalities',
|
|
324
|
+
'voice',
|
|
325
|
+
'outputAudioFormat',
|
|
326
|
+
'translation',
|
|
327
|
+
'tools',
|
|
328
|
+
'toolChoice',
|
|
329
|
+
'maxOutputTokens',
|
|
330
|
+
]) {
|
|
326
331
|
if (config[field] !== undefined) {
|
|
327
|
-
issue([
|
|
332
|
+
issue(['config', field], 'a transcription session never responds');
|
|
328
333
|
}
|
|
329
334
|
}
|
|
330
|
-
if (config.turnDetection.type !==
|
|
331
|
-
|
|
335
|
+
if (config.turnDetection.type !== 'none' &&
|
|
336
|
+
(config.turnDetection.createResponse || config.turnDetection.interruptResponse)) {
|
|
337
|
+
issue(['config', 'turnDetection'], 'a transcription session has no response to create or interrupt');
|
|
332
338
|
}
|
|
333
339
|
break;
|
|
334
|
-
case
|
|
340
|
+
case 'translation':
|
|
335
341
|
if (config.translation === undefined || config.outputAudioFormat === undefined) {
|
|
336
|
-
issue([
|
|
342
|
+
issue(['config'], 'a translation session names its target language and output audio format');
|
|
337
343
|
}
|
|
338
344
|
if (config.tools !== undefined || config.toolChoice !== undefined) {
|
|
339
|
-
issue([
|
|
345
|
+
issue(['config', 'tools'], 'a translation session calls no tools');
|
|
340
346
|
}
|
|
341
347
|
break;
|
|
342
348
|
}
|
|
343
349
|
if (config.toolChoice !== undefined && !hasTools) {
|
|
344
|
-
issue([
|
|
350
|
+
issue(['config', 'toolChoice'], 'a tool choice requires at least one tool definition');
|
|
345
351
|
}
|
|
346
352
|
if (config.tools !== undefined) {
|
|
347
353
|
const names = config.tools.map((tool) => tool.name);
|
|
348
354
|
if (new Set(names).size !== names.length) {
|
|
349
|
-
issue([
|
|
355
|
+
issue(['config', 'tools'], 'tool names must be unique within one session');
|
|
350
356
|
}
|
|
351
357
|
}
|
|
352
|
-
if (config.outputModalities !== undefined &&
|
|
353
|
-
|
|
358
|
+
if (config.outputModalities !== undefined &&
|
|
359
|
+
new Set(config.outputModalities).size !== config.outputModalities.length) {
|
|
360
|
+
issue(['config', 'outputModalities'], 'each output modality is named at most once');
|
|
354
361
|
}
|
|
355
362
|
// A session is never substituted: the conversation it holds belongs to one
|
|
356
363
|
// model, so every route serves the line the caller named, and a pinned
|
|
357
364
|
// request is served on exactly the revision it pinned.
|
|
358
365
|
const line = modelLineOf(request.modelReference);
|
|
359
|
-
const pinned = request.modelReference.includes(
|
|
366
|
+
const pinned = request.modelReference.includes('@');
|
|
360
367
|
for (const [index, route] of request.authorizedRoutes.entries()) {
|
|
361
|
-
if (route.substitution !==
|
|
362
|
-
issue([
|
|
368
|
+
if (route.substitution !== 'same_model' || modelLineOf(route.modelReference) !== line) {
|
|
369
|
+
issue(['authorizedRoutes', index], 'every route of a session serves the model it named');
|
|
363
370
|
}
|
|
364
371
|
if (pinned && route.modelReference !== request.modelReference) {
|
|
365
|
-
issue([
|
|
372
|
+
issue(['authorizedRoutes', index, 'modelReference'], 'a pinned session is served on exactly the revision it pinned');
|
|
366
373
|
}
|
|
367
374
|
}
|
|
368
375
|
const deployments = request.authorizedRoutes.map((route) => route.deploymentId);
|
|
369
376
|
if (new Set(deployments).size !== deployments.length) {
|
|
370
|
-
issue([
|
|
377
|
+
issue(['authorizedRoutes'], 'each deployment appears at most once in the authorized route list');
|
|
371
378
|
}
|
|
372
379
|
});
|
|
373
380
|
/* -------------------------------------------------------------------------- */
|
|
@@ -380,26 +387,26 @@ export const realtimeSessionRequestSchema = z
|
|
|
380
387
|
* never does — spoken output arrives as `output_audio.delta` events, and an
|
|
381
388
|
* item echoing it carries only the format and, once known, the transcript.
|
|
382
389
|
*/
|
|
383
|
-
export const realtimeContentPartSchema = z.discriminatedUnion(
|
|
384
|
-
z.object({ type: z.literal(
|
|
390
|
+
export const realtimeContentPartSchema = z.discriminatedUnion('type', [
|
|
391
|
+
z.object({ type: z.literal('input_text'), text: z.string().max(1048576) }).strict(),
|
|
385
392
|
z
|
|
386
393
|
.object({
|
|
387
|
-
type: z.literal(
|
|
394
|
+
type: z.literal('input_audio'),
|
|
388
395
|
format: realtimeAudioFormatSchema,
|
|
389
396
|
data: audioFrameSchema.optional(),
|
|
390
397
|
transcript: z.string().optional(),
|
|
391
398
|
})
|
|
392
399
|
.strict(),
|
|
393
|
-
z.object({ type: z.literal(
|
|
400
|
+
z.object({ type: z.literal('output_text'), text: z.string() }).strict(),
|
|
394
401
|
z
|
|
395
402
|
.object({
|
|
396
|
-
type: z.literal(
|
|
403
|
+
type: z.literal('output_audio'),
|
|
397
404
|
format: realtimeAudioFormatSchema,
|
|
398
405
|
transcript: z.string().optional(),
|
|
399
406
|
})
|
|
400
407
|
.strict(),
|
|
401
408
|
]);
|
|
402
|
-
const INPUT_PARTS = new Set([
|
|
409
|
+
const INPUT_PARTS = new Set(['input_text', 'input_audio']);
|
|
403
410
|
/**
|
|
404
411
|
* One item of the conversation a session holds.
|
|
405
412
|
*
|
|
@@ -407,18 +414,18 @@ const INPUT_PARTS = new Set(["input_text", "input_audio"]);
|
|
|
407
414
|
* is always stated by the server on the events that carry an item.
|
|
408
415
|
*/
|
|
409
416
|
export const realtimeConversationItemSchema = z
|
|
410
|
-
.discriminatedUnion(
|
|
417
|
+
.discriminatedUnion('type', [
|
|
411
418
|
z
|
|
412
419
|
.object({
|
|
413
|
-
type: z.literal(
|
|
420
|
+
type: z.literal('message'),
|
|
414
421
|
itemId: realtimeItemIdSchema.optional(),
|
|
415
|
-
role: z.enum([
|
|
422
|
+
role: z.enum(['system', 'user', 'assistant']),
|
|
416
423
|
content: z.array(realtimeContentPartSchema).min(1).max(64),
|
|
417
424
|
})
|
|
418
425
|
.strict(),
|
|
419
426
|
z
|
|
420
427
|
.object({
|
|
421
|
-
type: z.literal(
|
|
428
|
+
type: z.literal('function_call'),
|
|
422
429
|
itemId: realtimeItemIdSchema.optional(),
|
|
423
430
|
callId: z.string().min(1).max(128),
|
|
424
431
|
name: z.string().min(1).max(128),
|
|
@@ -427,7 +434,7 @@ export const realtimeConversationItemSchema = z
|
|
|
427
434
|
.strict(),
|
|
428
435
|
z
|
|
429
436
|
.object({
|
|
430
|
-
type: z.literal(
|
|
437
|
+
type: z.literal('function_call_output'),
|
|
431
438
|
itemId: realtimeItemIdSchema.optional(),
|
|
432
439
|
callId: z.string().min(1).max(128),
|
|
433
440
|
output: z.string().max(1048576),
|
|
@@ -435,24 +442,24 @@ export const realtimeConversationItemSchema = z
|
|
|
435
442
|
.strict(),
|
|
436
443
|
])
|
|
437
444
|
.superRefine((item, ctx) => {
|
|
438
|
-
if (item.type !==
|
|
445
|
+
if (item.type !== 'message')
|
|
439
446
|
return;
|
|
440
447
|
for (const [index, part] of item.content.entries()) {
|
|
441
448
|
const isInput = INPUT_PARTS.has(part.type);
|
|
442
449
|
// A user or system turn is input; an assistant turn is output. A part on
|
|
443
450
|
// the wrong side is one every provider would silently ignore.
|
|
444
|
-
if (item.role ===
|
|
451
|
+
if (item.role === 'assistant' ? isInput : !isInput) {
|
|
445
452
|
ctx.addIssue({
|
|
446
453
|
code: z.ZodIssueCode.custom,
|
|
447
|
-
path: [
|
|
454
|
+
path: ['content', index, 'type'],
|
|
448
455
|
message: `a ${item.role} message cannot carry ${part.type}`,
|
|
449
456
|
});
|
|
450
457
|
}
|
|
451
|
-
if (item.role ===
|
|
458
|
+
if (item.role === 'system' && part.type !== 'input_text') {
|
|
452
459
|
ctx.addIssue({
|
|
453
460
|
code: z.ZodIssueCode.custom,
|
|
454
|
-
path: [
|
|
455
|
-
message:
|
|
461
|
+
path: ['content', index, 'type'],
|
|
462
|
+
message: 'a system message is text',
|
|
456
463
|
});
|
|
457
464
|
}
|
|
458
465
|
}
|
|
@@ -477,19 +484,19 @@ const commandBase = {
|
|
|
477
484
|
};
|
|
478
485
|
export const realtimeSessionUpdateCommandSchema = z.object({
|
|
479
486
|
...commandBase,
|
|
480
|
-
type: z.literal(
|
|
487
|
+
type: z.literal('session.update'),
|
|
481
488
|
config: realtimeSessionConfigUpdateSchema,
|
|
482
489
|
});
|
|
483
490
|
export const realtimeItemCreateCommandSchema = z.object({
|
|
484
491
|
...commandBase,
|
|
485
|
-
type: z.literal(
|
|
492
|
+
type: z.literal('conversation.item.create'),
|
|
486
493
|
/** Insert after this item; absent appends. */
|
|
487
494
|
previousItemId: realtimeItemIdSchema.optional(),
|
|
488
495
|
item: realtimeConversationItemSchema,
|
|
489
496
|
});
|
|
490
497
|
export const realtimeItemDeleteCommandSchema = z.object({
|
|
491
498
|
...commandBase,
|
|
492
|
-
type: z.literal(
|
|
499
|
+
type: z.literal('conversation.item.delete'),
|
|
493
500
|
itemId: realtimeItemIdSchema,
|
|
494
501
|
});
|
|
495
502
|
/**
|
|
@@ -499,33 +506,33 @@ export const realtimeItemDeleteCommandSchema = z.object({
|
|
|
499
506
|
*/
|
|
500
507
|
export const realtimeItemTruncateCommandSchema = z.object({
|
|
501
508
|
...commandBase,
|
|
502
|
-
type: z.literal(
|
|
509
|
+
type: z.literal('conversation.item.truncate'),
|
|
503
510
|
itemId: realtimeItemIdSchema,
|
|
504
511
|
contentIndex: z.number().int().nonnegative().safe(),
|
|
505
512
|
audioEndMs: milliseconds,
|
|
506
513
|
});
|
|
507
514
|
export const realtimeInputAudioAppendCommandSchema = z.object({
|
|
508
515
|
...commandBase,
|
|
509
|
-
type: z.literal(
|
|
516
|
+
type: z.literal('input_audio.append'),
|
|
510
517
|
/** One bounded frame in the session's `inputAudioFormat`. */
|
|
511
518
|
data: audioFrameSchema,
|
|
512
519
|
});
|
|
513
520
|
export const realtimeInputAudioCommitCommandSchema = z.object({
|
|
514
521
|
...commandBase,
|
|
515
|
-
type: z.literal(
|
|
522
|
+
type: z.literal('input_audio.commit'),
|
|
516
523
|
});
|
|
517
524
|
export const realtimeInputAudioClearCommandSchema = z.object({
|
|
518
525
|
...commandBase,
|
|
519
|
-
type: z.literal(
|
|
526
|
+
type: z.literal('input_audio.clear'),
|
|
520
527
|
});
|
|
521
528
|
export const realtimeResponseCreateCommandSchema = z.object({
|
|
522
529
|
...commandBase,
|
|
523
|
-
type: z.literal(
|
|
530
|
+
type: z.literal('response.create'),
|
|
524
531
|
response: realtimeResponseParametersSchema.optional(),
|
|
525
532
|
});
|
|
526
533
|
export const realtimeResponseCancelCommandSchema = z.object({
|
|
527
534
|
...commandBase,
|
|
528
|
-
type: z.literal(
|
|
535
|
+
type: z.literal('response.cancel'),
|
|
529
536
|
/** Absent cancels the response in progress, if any. */
|
|
530
537
|
responseId: realtimeResponseIdSchema.optional(),
|
|
531
538
|
});
|
|
@@ -535,15 +542,15 @@ export const realtimeResponseCancelCommandSchema = z.object({
|
|
|
535
542
|
*/
|
|
536
543
|
export const realtimeSessionResumeCommandSchema = z.object({
|
|
537
544
|
...commandBase,
|
|
538
|
-
type: z.literal(
|
|
545
|
+
type: z.literal('session.resume'),
|
|
539
546
|
afterSequence: z.number().int().min(-1).safe(),
|
|
540
547
|
});
|
|
541
548
|
export const realtimeSessionCloseCommandSchema = z.object({
|
|
542
549
|
...commandBase,
|
|
543
|
-
type: z.literal(
|
|
550
|
+
type: z.literal('session.close'),
|
|
544
551
|
});
|
|
545
552
|
/** Every command a client can send. */
|
|
546
|
-
export const realtimeClientCommandSchema = z.discriminatedUnion(
|
|
553
|
+
export const realtimeClientCommandSchema = z.discriminatedUnion('type', [
|
|
547
554
|
realtimeSessionUpdateCommandSchema,
|
|
548
555
|
realtimeItemCreateCommandSchema,
|
|
549
556
|
realtimeItemDeleteCommandSchema,
|
|
@@ -576,7 +583,7 @@ const eventBase = {
|
|
|
576
583
|
*/
|
|
577
584
|
export const realtimeSessionCreatedEventSchema = z.object({
|
|
578
585
|
...eventBase,
|
|
579
|
-
type: z.literal(
|
|
586
|
+
type: z.literal('session.created'),
|
|
580
587
|
resolvedModelReference: modelReferenceSchema,
|
|
581
588
|
servingProvider: inferenceProviderSlugSchema,
|
|
582
589
|
deploymentId: deploymentIdSchema,
|
|
@@ -589,42 +596,42 @@ export const realtimeSessionCreatedEventSchema = z.object({
|
|
|
589
596
|
});
|
|
590
597
|
export const realtimeSessionUpdatedEventSchema = z.object({
|
|
591
598
|
...eventBase,
|
|
592
|
-
type: z.literal(
|
|
599
|
+
type: z.literal('session.updated'),
|
|
593
600
|
config: realtimeSessionConfigSchema,
|
|
594
601
|
});
|
|
595
602
|
export const realtimeSessionResumedEventSchema = z.object({
|
|
596
603
|
...eventBase,
|
|
597
|
-
type: z.literal(
|
|
604
|
+
type: z.literal('session.resumed'),
|
|
598
605
|
afterSequence: z.number().int().min(-1).safe(),
|
|
599
606
|
});
|
|
600
607
|
/** Sent before a command is applied. `duplicate` means it was not applied again. */
|
|
601
608
|
export const realtimeCommandAcceptedEventSchema = z.object({
|
|
602
609
|
...eventBase,
|
|
603
|
-
type: z.literal(
|
|
610
|
+
type: z.literal('command.accepted'),
|
|
604
611
|
commandId: realtimeCommandIdSchema,
|
|
605
612
|
duplicate: z.boolean(),
|
|
606
613
|
});
|
|
607
614
|
export const realtimeItemAddedEventSchema = z.object({
|
|
608
615
|
...eventBase,
|
|
609
|
-
type: z.literal(
|
|
616
|
+
type: z.literal('conversation.item.added'),
|
|
610
617
|
itemId: realtimeItemIdSchema,
|
|
611
618
|
previousItemId: realtimeItemIdSchema.optional(),
|
|
612
619
|
item: realtimeConversationItemSchema,
|
|
613
620
|
});
|
|
614
621
|
export const realtimeItemDoneEventSchema = z.object({
|
|
615
622
|
...eventBase,
|
|
616
|
-
type: z.literal(
|
|
623
|
+
type: z.literal('conversation.item.done'),
|
|
617
624
|
itemId: realtimeItemIdSchema,
|
|
618
625
|
item: realtimeConversationItemSchema,
|
|
619
626
|
});
|
|
620
627
|
export const realtimeItemDeletedEventSchema = z.object({
|
|
621
628
|
...eventBase,
|
|
622
|
-
type: z.literal(
|
|
629
|
+
type: z.literal('conversation.item.deleted'),
|
|
623
630
|
itemId: realtimeItemIdSchema,
|
|
624
631
|
});
|
|
625
632
|
export const realtimeItemTruncatedEventSchema = z.object({
|
|
626
633
|
...eventBase,
|
|
627
|
-
type: z.literal(
|
|
634
|
+
type: z.literal('conversation.item.truncated'),
|
|
628
635
|
itemId: realtimeItemIdSchema,
|
|
629
636
|
contentIndex: z.number().int().nonnegative().safe(),
|
|
630
637
|
audioEndMs: milliseconds,
|
|
@@ -636,35 +643,35 @@ export const realtimeItemTruncatedEventSchema = z.object({
|
|
|
636
643
|
*/
|
|
637
644
|
export const realtimeSpeechStartedEventSchema = z.object({
|
|
638
645
|
...eventBase,
|
|
639
|
-
type: z.literal(
|
|
646
|
+
type: z.literal('input_audio.speech_started'),
|
|
640
647
|
itemId: realtimeItemIdSchema,
|
|
641
648
|
audioStartMs: milliseconds,
|
|
642
649
|
});
|
|
643
650
|
export const realtimeSpeechStoppedEventSchema = z.object({
|
|
644
651
|
...eventBase,
|
|
645
|
-
type: z.literal(
|
|
652
|
+
type: z.literal('input_audio.speech_stopped'),
|
|
646
653
|
itemId: realtimeItemIdSchema,
|
|
647
654
|
audioEndMs: milliseconds,
|
|
648
655
|
});
|
|
649
656
|
export const realtimeInputAudioCommittedEventSchema = z.object({
|
|
650
657
|
...eventBase,
|
|
651
|
-
type: z.literal(
|
|
658
|
+
type: z.literal('input_audio.committed'),
|
|
652
659
|
itemId: realtimeItemIdSchema,
|
|
653
660
|
previousItemId: realtimeItemIdSchema.optional(),
|
|
654
661
|
});
|
|
655
662
|
export const realtimeInputAudioClearedEventSchema = z.object({
|
|
656
663
|
...eventBase,
|
|
657
|
-
type: z.literal(
|
|
664
|
+
type: z.literal('input_audio.cleared'),
|
|
658
665
|
});
|
|
659
666
|
export const realtimeResponseCreatedEventSchema = z.object({
|
|
660
667
|
...eventBase,
|
|
661
|
-
type: z.literal(
|
|
668
|
+
type: z.literal('response.created'),
|
|
662
669
|
responseId: realtimeResponseIdSchema,
|
|
663
670
|
});
|
|
664
671
|
/** One bounded frame of spoken output, in the session's `outputAudioFormat`. */
|
|
665
672
|
export const realtimeOutputAudioDeltaEventSchema = z.object({
|
|
666
673
|
...eventBase,
|
|
667
|
-
type: z.literal(
|
|
674
|
+
type: z.literal('output_audio.delta'),
|
|
668
675
|
responseId: realtimeResponseIdSchema,
|
|
669
676
|
itemId: realtimeItemIdSchema,
|
|
670
677
|
contentIndex: z.number().int().nonnegative().safe(),
|
|
@@ -673,7 +680,7 @@ export const realtimeOutputAudioDeltaEventSchema = z.object({
|
|
|
673
680
|
});
|
|
674
681
|
export const realtimeOutputAudioDoneEventSchema = z.object({
|
|
675
682
|
...eventBase,
|
|
676
|
-
type: z.literal(
|
|
683
|
+
type: z.literal('output_audio.done'),
|
|
677
684
|
responseId: realtimeResponseIdSchema,
|
|
678
685
|
itemId: realtimeItemIdSchema,
|
|
679
686
|
contentIndex: z.number().int().nonnegative().safe(),
|
|
@@ -682,10 +689,10 @@ export const realtimeOutputAudioDoneEventSchema = z.object({
|
|
|
682
689
|
* Which audio a transcript describes: the caller's (`input_audio`) or the
|
|
683
690
|
* model's own speech (`output_audio`). Neither is answer text.
|
|
684
691
|
*/
|
|
685
|
-
export const realtimeTranscriptSourceSchema = z.enum([
|
|
692
|
+
export const realtimeTranscriptSourceSchema = z.enum(['input_audio', 'output_audio']);
|
|
686
693
|
export const realtimeTranscriptDeltaEventSchema = z.object({
|
|
687
694
|
...eventBase,
|
|
688
|
-
type: z.literal(
|
|
695
|
+
type: z.literal('transcript.delta'),
|
|
689
696
|
source: realtimeTranscriptSourceSchema,
|
|
690
697
|
itemId: realtimeItemIdSchema,
|
|
691
698
|
contentIndex: z.number().int().nonnegative().safe(),
|
|
@@ -695,7 +702,7 @@ export const realtimeTranscriptDeltaEventSchema = z.object({
|
|
|
695
702
|
});
|
|
696
703
|
export const realtimeTranscriptDoneEventSchema = z.object({
|
|
697
704
|
...eventBase,
|
|
698
|
-
type: z.literal(
|
|
705
|
+
type: z.literal('transcript.done'),
|
|
699
706
|
source: realtimeTranscriptSourceSchema,
|
|
700
707
|
itemId: realtimeItemIdSchema,
|
|
701
708
|
contentIndex: z.number().int().nonnegative().safe(),
|
|
@@ -705,7 +712,7 @@ export const realtimeTranscriptDoneEventSchema = z.object({
|
|
|
705
712
|
/** Written output of a response (`outputModalities` including `text`). */
|
|
706
713
|
export const realtimeTextDeltaEventSchema = z.object({
|
|
707
714
|
...eventBase,
|
|
708
|
-
type: z.literal(
|
|
715
|
+
type: z.literal('text.delta'),
|
|
709
716
|
responseId: realtimeResponseIdSchema,
|
|
710
717
|
itemId: realtimeItemIdSchema,
|
|
711
718
|
contentIndex: z.number().int().nonnegative().safe(),
|
|
@@ -714,7 +721,7 @@ export const realtimeTextDeltaEventSchema = z.object({
|
|
|
714
721
|
/** A tool call being streamed; same accumulation rules as the one-shot event. */
|
|
715
722
|
export const realtimeToolCallEventSchema = z.object({
|
|
716
723
|
...eventBase,
|
|
717
|
-
type: z.literal(
|
|
724
|
+
type: z.literal('tool_call'),
|
|
718
725
|
responseId: realtimeResponseIdSchema,
|
|
719
726
|
itemId: realtimeItemIdSchema,
|
|
720
727
|
toolCallId: z.string().min(1).max(128),
|
|
@@ -724,10 +731,10 @@ export const realtimeToolCallEventSchema = z.object({
|
|
|
724
731
|
});
|
|
725
732
|
/** How a response ended. */
|
|
726
733
|
export const realtimeResponseStatusSchema = z.enum([
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
734
|
+
'completed',
|
|
735
|
+
'cancelled',
|
|
736
|
+
'incomplete',
|
|
737
|
+
'failed',
|
|
731
738
|
]);
|
|
732
739
|
/**
|
|
733
740
|
* A response ended, with the units it consumed — measurement evidence, as on
|
|
@@ -736,7 +743,7 @@ export const realtimeResponseStatusSchema = z.enum([
|
|
|
736
743
|
*/
|
|
737
744
|
export const realtimeResponseDoneEventSchema = z.object({
|
|
738
745
|
...eventBase,
|
|
739
|
-
type: z.literal(
|
|
746
|
+
type: z.literal('response.done'),
|
|
740
747
|
responseId: realtimeResponseIdSchema,
|
|
741
748
|
status: realtimeResponseStatusSchema,
|
|
742
749
|
finishReason: inferenceFinishReasonSchema.optional(),
|
|
@@ -750,21 +757,21 @@ export const realtimeResponseDoneEventSchema = z.object({
|
|
|
750
757
|
*/
|
|
751
758
|
export const realtimeErrorEventSchema = z.object({
|
|
752
759
|
...eventBase,
|
|
753
|
-
type: z.literal(
|
|
760
|
+
type: z.literal('error'),
|
|
754
761
|
fatal: z.boolean(),
|
|
755
762
|
error: inferenceErrorSchema,
|
|
756
763
|
});
|
|
757
764
|
/** Why a session ended. */
|
|
758
765
|
export const realtimeSessionCloseReasonSchema = z.enum([
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
766
|
+
'client_closed',
|
|
767
|
+
'max_duration',
|
|
768
|
+
'idle_timeout',
|
|
769
|
+
'limit_exceeded',
|
|
770
|
+
'resume_expired',
|
|
771
|
+
'upstream_closed',
|
|
772
|
+
'upstream_error',
|
|
773
|
+
'no_route_available',
|
|
774
|
+
'server_shutdown',
|
|
768
775
|
]);
|
|
769
776
|
/**
|
|
770
777
|
* The terminal event. Carries the session's total units; `deploymentId` is
|
|
@@ -772,7 +779,7 @@ export const realtimeSessionCloseReasonSchema = z.enum([
|
|
|
772
779
|
*/
|
|
773
780
|
export const realtimeSessionClosedEventSchema = z.object({
|
|
774
781
|
...eventBase,
|
|
775
|
-
type: z.literal(
|
|
782
|
+
type: z.literal('session.closed'),
|
|
776
783
|
reason: realtimeSessionCloseReasonSchema,
|
|
777
784
|
deploymentId: deploymentIdSchema.optional(),
|
|
778
785
|
units: z.array(usageQuantitySchema),
|
|
@@ -781,7 +788,7 @@ export const realtimeSessionClosedEventSchema = z.object({
|
|
|
781
788
|
});
|
|
782
789
|
/** Every event a session can emit. */
|
|
783
790
|
export const realtimeServerEventSchema = z
|
|
784
|
-
.discriminatedUnion(
|
|
791
|
+
.discriminatedUnion('type', [
|
|
785
792
|
realtimeSessionCreatedEventSchema,
|
|
786
793
|
realtimeSessionUpdatedEventSchema,
|
|
787
794
|
realtimeSessionResumedEventSchema,
|
|
@@ -809,14 +816,14 @@ export const realtimeServerEventSchema = z
|
|
|
809
816
|
// Each unit is reported once, as a total — the rule every usage record in
|
|
810
817
|
// this contract holds. Checked on the union because a discriminated union's
|
|
811
818
|
// options must stay plain objects.
|
|
812
|
-
if (event.type !==
|
|
819
|
+
if (event.type !== 'response.done' && event.type !== 'session.closed')
|
|
813
820
|
return;
|
|
814
821
|
const units = event.units.map((quantity) => quantity.unit);
|
|
815
822
|
if (new Set(units).size !== units.length) {
|
|
816
823
|
ctx.addIssue({
|
|
817
824
|
code: z.ZodIssueCode.custom,
|
|
818
|
-
path: [
|
|
819
|
-
message:
|
|
825
|
+
path: ['units'],
|
|
826
|
+
message: 'each unit is reported at most once',
|
|
820
827
|
});
|
|
821
828
|
}
|
|
822
829
|
});
|