@oxy.so/contracts 4.11.0-oxy-one.0 → 4.12.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.
Files changed (111) hide show
  1. package/dist/cjs/.tsbuildinfo +1 -1
  2. package/dist/cjs/accountGraph.js +5 -3
  3. package/dist/cjs/agency.js +178 -96
  4. package/dist/cjs/agentKeys.js +80 -26
  5. package/dist/cjs/capabilityBindings.js +2 -2
  6. package/dist/cjs/capabilityInvocation.js +3 -1
  7. package/dist/cjs/commonsSignIn.js +2 -2
  8. package/dist/cjs/deviceSession.js +5 -1
  9. package/dist/cjs/email/messages.js +70 -4
  10. package/dist/cjs/emailAgentContext.js +16 -8
  11. package/dist/cjs/externalIdentity.js +30 -12
  12. package/dist/cjs/identity.js +14 -6
  13. package/dist/cjs/identityLink.js +7 -2
  14. package/dist/cjs/identityProof.js +2 -1
  15. package/dist/cjs/index.js +12 -8
  16. package/dist/cjs/inference/catalogue.js +2 -12
  17. package/dist/cjs/inference/decisions.js +102 -83
  18. package/dist/cjs/inference/economics.js +15 -5
  19. package/dist/cjs/inference/embeddings.js +44 -6
  20. package/dist/cjs/inference/identifiers.js +14 -1
  21. package/dist/cjs/inference/inbox.js +33 -2
  22. package/dist/cjs/inference/providerConnection.js +21 -6
  23. package/dist/cjs/inference/realtime.js +114 -107
  24. package/dist/cjs/inference/routingPolicy.js +17 -0
  25. package/dist/cjs/inference/scopedExecution.js +12 -12
  26. package/dist/cjs/inference/usage.js +10 -9
  27. package/dist/cjs/inference/version.js +1 -1
  28. package/dist/cjs/notifications.js +25 -5
  29. package/dist/cjs/oauth.js +30 -14
  30. package/dist/cjs/oxyRecordTypes.js +2 -2
  31. package/dist/cjs/products/access.js +146 -57
  32. package/dist/cjs/products/billing.js +71 -17
  33. package/dist/cjs/products/checkout.js +24 -6
  34. package/dist/cjs/products/plans.js +22 -7
  35. package/dist/cjs/recommendations.js +4 -6
  36. package/dist/cjs/reputation.js +3 -6
  37. package/dist/cjs/sessionStatus.js +1 -6
  38. package/dist/cjs/signIn.js +17 -4
  39. package/dist/cjs/transparency.js +3 -1
  40. package/dist/cjs/updates.js +2 -4
  41. package/dist/cjs/userResponse.js +27 -7
  42. package/dist/cjs/username.js +3 -1
  43. package/dist/esm/.tsbuildinfo +1 -1
  44. package/dist/esm/accountGraph.js +5 -3
  45. package/dist/esm/agency.js +178 -96
  46. package/dist/esm/agentKeys.js +80 -26
  47. package/dist/esm/capabilityBindings.js +2 -2
  48. package/dist/esm/capabilityInvocation.js +3 -1
  49. package/dist/esm/commonsSignIn.js +2 -2
  50. package/dist/esm/deviceSession.js +5 -1
  51. package/dist/esm/email/messages.js +69 -3
  52. package/dist/esm/emailAgentContext.js +16 -8
  53. package/dist/esm/externalIdentity.js +30 -12
  54. package/dist/esm/identity.js +14 -6
  55. package/dist/esm/identityLink.js +7 -2
  56. package/dist/esm/identityProof.js +2 -1
  57. package/dist/esm/index.js +10 -8
  58. package/dist/esm/inference/aliaModelRelease.js +1 -1
  59. package/dist/esm/inference/catalogue.js +3 -13
  60. package/dist/esm/inference/decisions.js +108 -89
  61. package/dist/esm/inference/economics.js +16 -6
  62. package/dist/esm/inference/embeddings.js +44 -6
  63. package/dist/esm/inference/identifiers.js +13 -0
  64. package/dist/esm/inference/inbox.js +32 -1
  65. package/dist/esm/inference/providerConnection.js +21 -6
  66. package/dist/esm/inference/realtime.js +123 -116
  67. package/dist/esm/inference/routingPolicy.js +18 -1
  68. package/dist/esm/inference/scopedExecution.js +15 -15
  69. package/dist/esm/inference/usage.js +11 -10
  70. package/dist/esm/inference/version.js +1 -1
  71. package/dist/esm/notifications.js +25 -5
  72. package/dist/esm/oauth.js +30 -14
  73. package/dist/esm/oxyRecordTypes.js +2 -2
  74. package/dist/esm/products/access.js +146 -57
  75. package/dist/esm/products/billing.js +71 -17
  76. package/dist/esm/products/checkout.js +24 -6
  77. package/dist/esm/products/plans.js +22 -7
  78. package/dist/esm/recommendations.js +4 -6
  79. package/dist/esm/reputation.js +3 -6
  80. package/dist/esm/sessionStatus.js +1 -6
  81. package/dist/esm/signIn.js +17 -4
  82. package/dist/esm/transparency.js +3 -1
  83. package/dist/esm/updates.js +2 -4
  84. package/dist/esm/userResponse.js +27 -7
  85. package/dist/esm/username.js +3 -1
  86. package/dist/types/.tsbuildinfo +1 -1
  87. package/dist/types/accountGraph.d.ts +1 -1
  88. package/dist/types/accountSubject.d.ts +4 -4
  89. package/dist/types/commonsSignIn.d.ts +2 -2
  90. package/dist/types/email/messages.d.ts +208 -2
  91. package/dist/types/identity.d.ts +1 -1
  92. package/dist/types/index.d.ts +10 -10
  93. package/dist/types/inference/accountBilling.d.ts +2 -2
  94. package/dist/types/inference/decisions.d.ts +21 -1
  95. package/dist/types/inference/identifiers.d.ts +14 -0
  96. package/dist/types/inference/inbox.d.ts +129 -5
  97. package/dist/types/inference/realtime.d.ts +19 -1
  98. package/dist/types/inference/request.d.ts +54 -0
  99. package/dist/types/inference/routingPolicy.d.ts +10 -0
  100. package/dist/types/inference/scopedExecution.d.ts +1 -1
  101. package/dist/types/inference/usage.d.ts +12 -0
  102. package/dist/types/inference/version.d.ts +1 -1
  103. package/dist/types/moderationReputation.d.ts +1 -1
  104. package/dist/types/oxyRecordTypes.d.ts +2 -2
  105. package/dist/types/products/access.d.ts +102 -102
  106. package/dist/types/products/checkout.d.ts +3 -3
  107. package/dist/types/products/plans.d.ts +40 -40
  108. package/dist/types/reputation.d.ts +4 -4
  109. package/dist/types/updates.d.ts +1 -1
  110. package/dist/types/userResponse.d.ts +22 -23
  111. package/package.json +1 -2
@@ -83,15 +83,15 @@
83
83
  *
84
84
  * Decided in: OxyHQ/Kaana#90.
85
85
  */
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";
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(["text", "audio"]);
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("type", [
155
- z.object({ type: z.literal("none") }).strict(),
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("server_vad"),
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("semantic_vad"),
169
- eagerness: z.enum(["low", "medium", "high", "auto"]),
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: "a session update changes at least one field",
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(["limits", "idleTimeoutMs"], "an idle timeout cannot outlast the session");
301
+ issue(['limits', 'idleTimeoutMs'], 'an idle timeout cannot outlast the session');
306
302
  }
307
- const producesAudio = config.outputModalities?.includes("audio") === true;
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 "conversation":
306
+ case 'conversation':
311
307
  if (config.outputModalities === undefined) {
312
- issue(["config", "outputModalities"], "a conversation names what its responses produce");
308
+ issue(['config', 'outputModalities'], 'a conversation names what its responses produce');
313
309
  }
314
- if (producesAudio && (config.voice === undefined || config.outputAudioFormat === undefined)) {
315
- issue(["config"], "spoken responses need a voice and an output audio format");
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(["config", "translation"], "only a translation session translates");
315
+ issue(['config', 'translation'], 'only a translation session translates');
319
316
  }
320
317
  break;
321
- case "transcription":
318
+ case 'transcription':
322
319
  if (config.inputAudioTranscription === undefined) {
323
- issue(["config", "inputAudioTranscription"], "a transcription session transcribes its input");
320
+ issue(['config', 'inputAudioTranscription'], 'a transcription session transcribes its input');
324
321
  }
325
- for (const field of ["outputModalities", "voice", "outputAudioFormat", "translation", "tools", "toolChoice", "maxOutputTokens"]) {
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(["config", field], "a transcription session never responds");
332
+ issue(['config', field], 'a transcription session never responds');
328
333
  }
329
334
  }
330
- if (config.turnDetection.type !== "none" && (config.turnDetection.createResponse || config.turnDetection.interruptResponse)) {
331
- issue(["config", "turnDetection"], "a transcription session has no response to create or interrupt");
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 "translation":
340
+ case 'translation':
335
341
  if (config.translation === undefined || config.outputAudioFormat === undefined) {
336
- issue(["config"], "a translation session names its target language and output audio format");
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(["config", "tools"], "a translation session calls no tools");
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(["config", "toolChoice"], "a tool choice requires at least one tool definition");
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(["config", "tools"], "tool names must be unique within one session");
355
+ issue(['config', 'tools'], 'tool names must be unique within one session');
350
356
  }
351
357
  }
352
- if (config.outputModalities !== undefined && new Set(config.outputModalities).size !== config.outputModalities.length) {
353
- issue(["config", "outputModalities"], "each output modality is named at most once");
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 !== "same_model" || modelLineOf(route.modelReference) !== line) {
362
- issue(["authorizedRoutes", index], "every route of a session serves the model it named");
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(["authorizedRoutes", index, "modelReference"], "a pinned session is served on exactly the revision it pinned");
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(["authorizedRoutes"], "each deployment appears at most once in the authorized route list");
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("type", [
384
- z.object({ type: z.literal("input_text"), text: z.string().max(1048576) }).strict(),
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("input_audio"),
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("output_text"), text: z.string() }).strict(),
400
+ z.object({ type: z.literal('output_text'), text: z.string() }).strict(),
394
401
  z
395
402
  .object({
396
- type: z.literal("output_audio"),
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(["input_text", "input_audio"]);
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("type", [
417
+ .discriminatedUnion('type', [
411
418
  z
412
419
  .object({
413
- type: z.literal("message"),
420
+ type: z.literal('message'),
414
421
  itemId: realtimeItemIdSchema.optional(),
415
- role: z.enum(["system", "user", "assistant"]),
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("function_call"),
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("function_call_output"),
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 !== "message")
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 === "assistant" ? isInput : !isInput) {
451
+ if (item.role === 'assistant' ? isInput : !isInput) {
445
452
  ctx.addIssue({
446
453
  code: z.ZodIssueCode.custom,
447
- path: ["content", index, "type"],
454
+ path: ['content', index, 'type'],
448
455
  message: `a ${item.role} message cannot carry ${part.type}`,
449
456
  });
450
457
  }
451
- if (item.role === "system" && part.type !== "input_text") {
458
+ if (item.role === 'system' && part.type !== 'input_text') {
452
459
  ctx.addIssue({
453
460
  code: z.ZodIssueCode.custom,
454
- path: ["content", index, "type"],
455
- message: "a system message is text",
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("session.update"),
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("conversation.item.create"),
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("conversation.item.delete"),
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("conversation.item.truncate"),
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("input_audio.append"),
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("input_audio.commit"),
522
+ type: z.literal('input_audio.commit'),
516
523
  });
517
524
  export const realtimeInputAudioClearCommandSchema = z.object({
518
525
  ...commandBase,
519
- type: z.literal("input_audio.clear"),
526
+ type: z.literal('input_audio.clear'),
520
527
  });
521
528
  export const realtimeResponseCreateCommandSchema = z.object({
522
529
  ...commandBase,
523
- type: z.literal("response.create"),
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("response.cancel"),
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("session.resume"),
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("session.close"),
550
+ type: z.literal('session.close'),
544
551
  });
545
552
  /** Every command a client can send. */
546
- export const realtimeClientCommandSchema = z.discriminatedUnion("type", [
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("session.created"),
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("session.updated"),
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("session.resumed"),
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("command.accepted"),
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("conversation.item.added"),
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("conversation.item.done"),
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("conversation.item.deleted"),
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("conversation.item.truncated"),
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("input_audio.speech_started"),
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("input_audio.speech_stopped"),
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("input_audio.committed"),
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("input_audio.cleared"),
664
+ type: z.literal('input_audio.cleared'),
658
665
  });
659
666
  export const realtimeResponseCreatedEventSchema = z.object({
660
667
  ...eventBase,
661
- type: z.literal("response.created"),
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("output_audio.delta"),
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("output_audio.done"),
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(["input_audio", "output_audio"]);
692
+ export const realtimeTranscriptSourceSchema = z.enum(['input_audio', 'output_audio']);
686
693
  export const realtimeTranscriptDeltaEventSchema = z.object({
687
694
  ...eventBase,
688
- type: z.literal("transcript.delta"),
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("transcript.done"),
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("text.delta"),
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("tool_call"),
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
- "completed",
728
- "cancelled",
729
- "incomplete",
730
- "failed",
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("response.done"),
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("error"),
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
- "client_closed",
760
- "max_duration",
761
- "idle_timeout",
762
- "limit_exceeded",
763
- "resume_expired",
764
- "upstream_closed",
765
- "upstream_error",
766
- "no_route_available",
767
- "server_shutdown",
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("session.closed"),
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("type", [
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 !== "response.done" && event.type !== "session.closed")
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: ["units"],
819
- message: "each unit is reported at most once",
825
+ path: ['units'],
826
+ message: 'each unit is reported at most once',
820
827
  });
821
828
  }
822
829
  });
@@ -32,7 +32,7 @@
32
32
  * docs/adr/0017-authorized-routes-in-the-envelope.md, issue #972 workstream 6.
33
33
  */
34
34
  import { z } from "zod";
35
- import { deploymentIdSchema, inferenceProviderSlugSchema, inferenceRegionSchema, inferenceTimestampSchema, modelReferenceSchema, oxyAccountIdSchema, oxyApplicationIdSchema, routingProfileIdSchema, } from "./identifiers.js";
35
+ import { deploymentIdSchema, inferenceProviderSlugSchema, inferenceFundingTierSchema, inferenceRegionSchema, inferenceTimestampSchema, modelReferenceSchema, oxyAccountIdSchema, oxyApplicationIdSchema, routingProfileIdSchema, } from "./identifiers.js";
36
36
  import { kaanaCredentialHandleSchema } from "./providerConnection.js";
37
37
  import { exactDecimalSchema, currencyCodeSchema, unitPriceSchema, } from "./money.js";
38
38
  /**
@@ -291,6 +291,16 @@ const authorizedRouteFields = {
291
291
  modelReference: modelReferenceSchema,
292
292
  provider: inferenceProviderSlugSchema,
293
293
  regions: z.array(inferenceRegionSchema),
294
+ /**
295
+ * The dearest funding tier the data plane may spend on this route. Absent
296
+ * means no ceiling. Present, the data plane walks only provider keys whose
297
+ * STATED tier is at or below it — a key whose economics nobody stated is
298
+ * never admitted — and refuses the route rather than fall through to a
299
+ * dearer key. It is how Oxy authorizes a route only while credit funds it
300
+ * (Alia Pro and Ultra spend credits only, ADR 0038). Meaningless with a
301
+ * customer credential, which the provider bills to the customer.
302
+ */
303
+ maxFundingTier: inferenceFundingTierSchema.optional(),
294
304
  /**
295
305
  * Exact customer credential binding. Absence means a platform credential;
296
306
  * presence names the immutable Kaana generation this route may use.
@@ -345,6 +355,13 @@ export const authorizedRouteSchema = z
345
355
  .strict(),
346
356
  ])
347
357
  .superRefine((route, ctx) => {
358
+ if (route.maxFundingTier !== undefined && route.customerProviderCredential !== undefined) {
359
+ ctx.addIssue({
360
+ code: z.ZodIssueCode.custom,
361
+ path: ['maxFundingTier'],
362
+ message: 'a funding ceiling bounds platform keys; a customer credential is billed to the customer',
363
+ });
364
+ }
348
365
  // Same rule as `modelDeploymentSchema`: a route serves specific weights. An
349
366
  // unpinned entry would leave the data plane choosing a revision, which is
350
367
  // the one substitution the customer never authorized by naming a model.