@kaana.ai/contracts 7.0.0 → 8.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/internal/attribution.d.ts +32 -23
  2. package/dist/internal/attribution.js +14 -12
  3. package/dist/internal/catalogue.d.ts +3 -4
  4. package/dist/internal/catalogue.js +18 -18
  5. package/dist/internal/credentialControl.js +4 -3
  6. package/dist/internal/decisions.d.ts +30 -4
  7. package/dist/internal/embeddings.js +4 -3
  8. package/dist/internal/errors.js +3 -2
  9. package/dist/internal/grant.d.ts +36 -9
  10. package/dist/internal/grant.js +34 -15
  11. package/dist/internal/identifiers.js +13 -5
  12. package/dist/internal/realtime.d.ts +15 -2
  13. package/dist/internal/realtime.js +4 -3
  14. package/dist/internal/request.d.ts +15 -2
  15. package/dist/internal/request.js +4 -3
  16. package/dist/internal/routing.js +2 -1
  17. package/dist/internal/settlement.d.ts +30 -4
  18. package/dist/internal/settlement.js +7 -6
  19. package/dist/internal/usage.d.ts +15 -2
  20. package/dist/public/audio.js +12 -7
  21. package/dist/public/audioFormats.js +2 -1
  22. package/dist/public/catalogue.js +18 -13
  23. package/dist/public/chatCompletions.js +26 -23
  24. package/dist/public/decisions.js +4 -3
  25. package/dist/public/embeddings.js +7 -3
  26. package/dist/public/errors.js +4 -3
  27. package/dist/public/generations.js +5 -4
  28. package/dist/public/identifiers.js +20 -14
  29. package/dist/public/images.js +8 -7
  30. package/dist/public/messages.js +31 -17
  31. package/dist/public/money.js +2 -1
  32. package/dist/public/policy.js +2 -1
  33. package/dist/public/realtime.js +30 -20
  34. package/dist/public/responses.js +10 -3
  35. package/dist/public/streamEvents.js +9 -4
  36. package/dist/public/version.d.ts +1 -1
  37. package/dist/public/version.js +1 -1
  38. package/dist/stringBounds.d.ts +11 -0
  39. package/dist/stringBounds.js +61 -0
  40. package/dist/timestampCheck.d.ts +3 -0
  41. package/dist/timestampCheck.js +18 -0
  42. package/openapi.json +7 -15
  43. package/package.json +3 -4
@@ -5,6 +5,7 @@
5
5
  * Moved from `@oxy.so/contracts` 4.12.0 (`src/inference/identifiers.ts`) by Kaana ADR 0002.
6
6
  */
7
7
  import { z } from 'zod';
8
+ import { maxUtf16Length, minUtf16Length } from '../stringBounds.js';
8
9
  /**
9
10
  * An Oxy account id — the account that owns the workload and is financially
10
11
  * responsible for it.
@@ -16,7 +17,11 @@ import { z } from 'zod';
16
17
  * of a header, a JWT claim or a request body — is not assignable to it; the
17
18
  * only way to obtain one is to parse a value through this schema.
18
19
  */
19
- export const oxyAccountIdSchema = z.string().min(1).max(64).brand();
20
+ export const oxyAccountIdSchema = z
21
+ .string()
22
+ .check(minUtf16Length(1))
23
+ .check(maxUtf16Length(64))
24
+ .brand();
20
25
  /** One path segment of a canonical model id: a lowercase, URL-safe slug. */
21
26
  const SLUG_PATTERN = '[a-z0-9](?:[a-z0-9._-]*[a-z0-9])?';
22
27
  /**
@@ -29,7 +34,7 @@ const SLUG_PATTERN = '[a-z0-9](?:[a-z0-9._-]*[a-z0-9])?';
29
34
  */
30
35
  export const routingProfileSlugSchema = z
31
36
  .string()
32
- .max(64)
37
+ .check(maxUtf16Length(64))
33
38
  .regex(new RegExp(`^${SLUG_PATTERN}$`), 'routing profile must be a lowercase URL-safe slug');
34
39
  /**
35
40
  * The opaque PostgreSQL identity of one routing profile.
@@ -37,11 +42,14 @@ export const routingProfileSlugSchema = z
37
42
  * No trim, case-folding or format heuristic: callers selecting by id must name
38
43
  * the exact stored bytes. The database lookup is the authority for existence.
39
44
  */
40
- export const routingProfileIdSchema = z.string().min(1).max(128);
45
+ export const routingProfileIdSchema = z
46
+ .string()
47
+ .check(minUtf16Length(1))
48
+ .check(maxUtf16Length(128));
41
49
  /** An inference provider slug, e.g. `openai`, `bedrock`, `oxy-hosted`. */
42
50
  export const inferenceProviderSlugSchema = z
43
51
  .string()
44
- .max(64)
52
+ .check(maxUtf16Length(64))
45
53
  .regex(new RegExp(`^${SLUG_PATTERN}$`), 'provider must be a lowercase URL-safe slug');
46
54
  /**
47
55
  * A deployment/endpoint id. Opaque to customers: which concrete endpoint served
@@ -49,7 +57,7 @@ export const inferenceProviderSlugSchema = z
49
57
  * subset of it is ever attributed back (see the catalogue's serving-boundary
50
58
  * rules).
51
59
  */
52
- export const deploymentIdSchema = z.string().min(1).max(128);
60
+ export const deploymentIdSchema = z.string().check(minUtf16Length(1)).check(maxUtf16Length(128));
53
61
  /**
54
62
  * The economic tier of the provider capacity that funds a request, in the
55
63
  * order Kaana spends it: `free` (costs nothing), `credit` (a promotional or
@@ -21,7 +21,8 @@ export declare const realtimeClientMetadataSchema: z.ZodObject<{
21
21
  export declare const realtimeSessionRequestSchema: z.ZodObject<{
22
22
  schemaVersion: z.ZodLiteral<1>;
23
23
  attribution: z.ZodObject<{
24
- principal: z.ZodObject<{
24
+ principal: z.ZodDiscriminatedUnion<[z.ZodObject<{
25
+ authority: z.ZodLiteral<"first_party">;
25
26
  billing: z.ZodObject<{
26
27
  accountId: z.core.$ZodBranded<z.ZodString, "OxyAccountId", "out">;
27
28
  }, z.core.$strict>;
@@ -32,6 +33,8 @@ export declare const realtimeSessionRequestSchema: z.ZodObject<{
32
33
  staging: "staging";
33
34
  production: "production";
34
35
  }>;
36
+ }, z.core.$strict>, z.ZodObject<{
37
+ authority: z.ZodOptional<z.ZodLiteral<"external">>;
35
38
  inferenceScopes: z.ZodArray<z.ZodEnum<{
36
39
  "inference:invoke": "inference:invoke";
37
40
  "inference:models:read": "inference:models:read";
@@ -41,7 +44,17 @@ export declare const realtimeSessionRequestSchema: z.ZodObject<{
41
44
  "inference:providers:read": "inference:providers:read";
42
45
  "inference:providers:write": "inference:providers:write";
43
46
  }>>;
44
- }, z.core.$strip>;
47
+ billing: z.ZodObject<{
48
+ accountId: z.core.$ZodBranded<z.ZodString, "OxyAccountId", "out">;
49
+ }, z.core.$strict>;
50
+ applicationId: z.ZodString;
51
+ credentialId: z.ZodString;
52
+ environment: z.ZodEnum<{
53
+ development: "development";
54
+ staging: "staging";
55
+ production: "production";
56
+ }>;
57
+ }, z.core.$strict>], "authority">;
45
58
  userId: z.ZodOptional<z.core.$ZodBranded<z.ZodString, "DelegatedUserId", "out">>;
46
59
  requestId: z.ZodString;
47
60
  generationId: z.ZodOptional<z.ZodString>;
@@ -5,6 +5,7 @@
5
5
  * Moved from `@oxy.so/contracts` 4.12.0 (`src/inference/realtime.ts`) by Kaana ADR 0002.
6
6
  */
7
7
  import { z } from 'zod';
8
+ import { maxUtf16Length, minUtf16Length } from '../stringBounds.js';
8
9
  import { realtimeSessionKindSchema, realtimeSessionTransportSchema } from '../public/catalogue.js';
9
10
  import { inferenceTimestampSchema, modelReferenceSchema, requestIdSchema, } from '../public/identifiers.js';
10
11
  import { usageQuantitySchema, usageSourceSchema } from '../public/money.js';
@@ -23,10 +24,10 @@ const sequenceSchema = z.number().int().nonnegative().safe();
23
24
  export const realtimeClientMetadataSchema = z
24
25
  .object({
25
26
  /** The public path, e.g. `/v1/realtime`. */
26
- endpoint: z.string().min(1).max(256),
27
- clientSessionId: z.string().min(1).max(128).optional(),
27
+ endpoint: z.string().check(minUtf16Length(1)).check(maxUtf16Length(256)),
28
+ clientSessionId: z.string().check(minUtf16Length(1)).check(maxUtf16Length(128)).optional(),
28
29
  receivedAt: inferenceTimestampSchema,
29
- labels: z.record(z.string(), z.string().max(256)).optional(),
30
+ labels: z.record(z.string(), z.string().check(maxUtf16Length(256))).optional(),
30
31
  })
31
32
  .strict();
32
33
  const modelLineOf = (reference) => {
@@ -144,7 +144,8 @@ export declare const clientRequestMetadataSchema: z.ZodObject<{
144
144
  export declare const inferenceRequestSchema: z.ZodObject<{
145
145
  schemaVersion: z.ZodLiteral<2>;
146
146
  attribution: z.ZodObject<{
147
- principal: z.ZodObject<{
147
+ principal: z.ZodDiscriminatedUnion<[z.ZodObject<{
148
+ authority: z.ZodLiteral<"first_party">;
148
149
  billing: z.ZodObject<{
149
150
  accountId: z.core.$ZodBranded<z.ZodString, "OxyAccountId", "out">;
150
151
  }, z.core.$strict>;
@@ -155,6 +156,8 @@ export declare const inferenceRequestSchema: z.ZodObject<{
155
156
  staging: "staging";
156
157
  production: "production";
157
158
  }>;
159
+ }, z.core.$strict>, z.ZodObject<{
160
+ authority: z.ZodOptional<z.ZodLiteral<"external">>;
158
161
  inferenceScopes: z.ZodArray<z.ZodEnum<{
159
162
  "inference:invoke": "inference:invoke";
160
163
  "inference:models:read": "inference:models:read";
@@ -164,7 +167,17 @@ export declare const inferenceRequestSchema: z.ZodObject<{
164
167
  "inference:providers:read": "inference:providers:read";
165
168
  "inference:providers:write": "inference:providers:write";
166
169
  }>>;
167
- }, z.core.$strip>;
170
+ billing: z.ZodObject<{
171
+ accountId: z.core.$ZodBranded<z.ZodString, "OxyAccountId", "out">;
172
+ }, z.core.$strict>;
173
+ applicationId: z.ZodString;
174
+ credentialId: z.ZodString;
175
+ environment: z.ZodEnum<{
176
+ development: "development";
177
+ staging: "staging";
178
+ production: "production";
179
+ }>;
180
+ }, z.core.$strict>], "authority">;
168
181
  userId: z.ZodOptional<z.core.$ZodBranded<z.ZodString, "DelegatedUserId", "out">>;
169
182
  requestId: z.ZodString;
170
183
  generationId: z.ZodOptional<z.ZodString>;
@@ -4,6 +4,7 @@
4
4
  * Moved from `@oxy.so/contracts` 4.12.0 (`src/inference/request.ts`) by Kaana ADR 0002.
5
5
  */
6
6
  import { z } from 'zod';
7
+ import { maxUtf16Length, minUtf16Length } from '../stringBounds.js';
7
8
  import { inferenceApiFormatSchema, inferenceModalitySchema } from '../public/catalogue.js';
8
9
  import { decisionInputSchema } from '../public/decisions.js';
9
10
  import { idempotencyKeySchema, inferenceTimestampSchema } from '../public/identifiers.js';
@@ -53,11 +54,11 @@ export const clientRequestMetadataSchema = z
53
54
  /** The public dialect the customer called. The response is rendered in it. */
54
55
  apiFormat: inferenceApiFormatSchema,
55
56
  /** The public path, e.g. `/v1/responses`. */
56
- endpoint: z.string().min(1).max(256),
57
+ endpoint: z.string().check(minUtf16Length(1)).check(maxUtf16Length(256)),
57
58
  /** The customer's own correlation id, when they sent one. */
58
- clientRequestId: z.string().min(1).max(128).optional(),
59
+ clientRequestId: z.string().check(minUtf16Length(1)).check(maxUtf16Length(128)).optional(),
59
60
  receivedAt: inferenceTimestampSchema,
60
- labels: z.record(z.string(), z.string().max(256)).optional(),
61
+ labels: z.record(z.string(), z.string().check(maxUtf16Length(256))).optional(),
61
62
  })
62
63
  .strict();
63
64
  /**
@@ -6,6 +6,7 @@
6
6
  * controls) stays in `@oxy.so/contracts`: it is a Console resource.
7
7
  */
8
8
  import { z } from 'zod';
9
+ import { maxUtf16Length, minUtf16Length } from '../stringBounds.js';
9
10
  import { inferenceRegionSchema, modelReferenceSchema } from '../public/identifiers.js';
10
11
  import { kaanaCredentialHandleSchema } from './credentialControl.js';
11
12
  import { deploymentIdSchema, inferenceFundingTierSchema, inferenceProviderSlugSchema, oxyAccountIdSchema, routingProfileIdSchema, } from './identifiers.js';
@@ -74,7 +75,7 @@ const authorizedRouteFields = {
74
75
  credentialHandle: kaanaCredentialHandleSchema,
75
76
  credentialRevision: z.number().int().positive().safe(),
76
77
  ownerAccountId: oxyAccountIdSchema,
77
- connectionId: z.string().min(1).max(128),
78
+ connectionId: z.string().check(minUtf16Length(1)).check(maxUtf16Length(128)),
78
79
  environment: z.enum(['development', 'staging', 'production']),
79
80
  })
80
81
  .strict()
@@ -30,7 +30,8 @@ export declare const settlementSchema: z.ZodObject<{
30
30
  requestId: z.ZodString;
31
31
  generationId: z.ZodOptional<z.ZodString>;
32
32
  attribution: z.ZodObject<{
33
- principal: z.ZodObject<{
33
+ principal: z.ZodDiscriminatedUnion<[z.ZodObject<{
34
+ authority: z.ZodLiteral<"first_party">;
34
35
  billing: z.ZodObject<{
35
36
  accountId: z.core.$ZodBranded<z.ZodString, "OxyAccountId", "out">;
36
37
  }, z.core.$strict>;
@@ -41,6 +42,8 @@ export declare const settlementSchema: z.ZodObject<{
41
42
  staging: "staging";
42
43
  production: "production";
43
44
  }>;
45
+ }, z.core.$strict>, z.ZodObject<{
46
+ authority: z.ZodOptional<z.ZodLiteral<"external">>;
44
47
  inferenceScopes: z.ZodArray<z.ZodEnum<{
45
48
  "inference:invoke": "inference:invoke";
46
49
  "inference:models:read": "inference:models:read";
@@ -50,7 +53,17 @@ export declare const settlementSchema: z.ZodObject<{
50
53
  "inference:providers:read": "inference:providers:read";
51
54
  "inference:providers:write": "inference:providers:write";
52
55
  }>>;
53
- }, z.core.$strip>;
56
+ billing: z.ZodObject<{
57
+ accountId: z.core.$ZodBranded<z.ZodString, "OxyAccountId", "out">;
58
+ }, z.core.$strict>;
59
+ applicationId: z.ZodString;
60
+ credentialId: z.ZodString;
61
+ environment: z.ZodEnum<{
62
+ development: "development";
63
+ staging: "staging";
64
+ production: "production";
65
+ }>;
66
+ }, z.core.$strict>], "authority">;
54
67
  userId: z.ZodOptional<z.core.$ZodBranded<z.ZodString, "DelegatedUserId", "out">>;
55
68
  requestId: z.ZodString;
56
69
  generationId: z.ZodOptional<z.ZodString>;
@@ -141,7 +154,8 @@ export declare const settlementPageSchema: z.ZodObject<{
141
154
  requestId: z.ZodString;
142
155
  generationId: z.ZodOptional<z.ZodString>;
143
156
  attribution: z.ZodObject<{
144
- principal: z.ZodObject<{
157
+ principal: z.ZodDiscriminatedUnion<[z.ZodObject<{
158
+ authority: z.ZodLiteral<"first_party">;
145
159
  billing: z.ZodObject<{
146
160
  accountId: z.core.$ZodBranded<z.ZodString, "OxyAccountId", "out">;
147
161
  }, z.core.$strict>;
@@ -152,6 +166,8 @@ export declare const settlementPageSchema: z.ZodObject<{
152
166
  staging: "staging";
153
167
  production: "production";
154
168
  }>;
169
+ }, z.core.$strict>, z.ZodObject<{
170
+ authority: z.ZodOptional<z.ZodLiteral<"external">>;
155
171
  inferenceScopes: z.ZodArray<z.ZodEnum<{
156
172
  "inference:invoke": "inference:invoke";
157
173
  "inference:models:read": "inference:models:read";
@@ -161,7 +177,17 @@ export declare const settlementPageSchema: z.ZodObject<{
161
177
  "inference:providers:read": "inference:providers:read";
162
178
  "inference:providers:write": "inference:providers:write";
163
179
  }>>;
164
- }, z.core.$strip>;
180
+ billing: z.ZodObject<{
181
+ accountId: z.core.$ZodBranded<z.ZodString, "OxyAccountId", "out">;
182
+ }, z.core.$strict>;
183
+ applicationId: z.ZodString;
184
+ credentialId: z.ZodString;
185
+ environment: z.ZodEnum<{
186
+ development: "development";
187
+ staging: "staging";
188
+ production: "production";
189
+ }>;
190
+ }, z.core.$strict>], "authority">;
165
191
  userId: z.ZodOptional<z.core.$ZodBranded<z.ZodString, "DelegatedUserId", "out">>;
166
192
  requestId: z.ZodString;
167
193
  generationId: z.ZodOptional<z.ZodString>;
@@ -14,6 +14,7 @@
14
14
  * New in contract set 4.0.0.
15
15
  */
16
16
  import { z } from 'zod';
17
+ import { maxUtf16Length, minUtf16Length } from '../stringBounds.js';
17
18
  import { inferenceTimestampSchema, requestIdSchema } from '../public/identifiers.js';
18
19
  import { normalizedUsageReportSchema } from './usage.js';
19
20
  /** The signature domain of a settlement, under Kaana's own settlement key. */
@@ -23,14 +24,14 @@ export const settlementSchema = z
23
24
  .object({
24
25
  schemaVersion: z.literal(1),
25
26
  /** The outbox row; stable across redeliveries. */
26
- settlementId: z.string().min(1).max(128),
27
+ settlementId: z.string().check(minUtf16Length(1)).check(maxUtf16Length(128)),
27
28
  /** The idempotency key of the settlement: one grant settles once. */
28
- grantId: z.string().min(1).max(128),
29
+ grantId: z.string().check(minUtf16Length(1)).check(maxUtf16Length(128)),
29
30
  requestId: requestIdSchema,
30
31
  /** The grant's hold, when it had one. */
31
- reservationId: z.string().min(1).max(128).optional(),
32
+ reservationId: z.string().check(minUtf16Length(1)).check(maxUtf16Length(128)).optional(),
32
33
  /** The grant's capacity slot, when it claimed one; settling releases it. */
33
- meteredUsageId: z.string().min(1).max(128).optional(),
34
+ meteredUsageId: z.string().check(minUtf16Length(1)).check(maxUtf16Length(128)).optional(),
34
35
  /** The step that served, by position in the grant. Absent when nothing was served. */
35
36
  servedStep: z.number().int().nonnegative().max(7).optional(),
36
37
  report: normalizedUsageReportSchema,
@@ -57,7 +58,7 @@ export const settlementSchema = z
57
58
  export const settlementAcknowledgementSchema = z
58
59
  .object({
59
60
  schemaVersion: z.literal(1),
60
- settlementId: z.string().min(1).max(128),
61
+ settlementId: z.string().check(minUtf16Length(1)).check(maxUtf16Length(128)),
61
62
  status: z.enum(['settled', 'duplicate']),
62
63
  })
63
64
  .strict();
@@ -83,6 +84,6 @@ export const settlementPageSchema = z
83
84
  .object({
84
85
  data: z.array(settlementSchema),
85
86
  /** Absent on the last page. */
86
- nextCursor: z.string().min(1).max(512).optional(),
87
+ nextCursor: z.string().check(minUtf16Length(1)).check(maxUtf16Length(512)).optional(),
87
88
  })
88
89
  .strict();
@@ -54,7 +54,8 @@ export declare const normalizedUsageReportSchema: z.ZodObject<{
54
54
  requestId: z.ZodString;
55
55
  generationId: z.ZodOptional<z.ZodString>;
56
56
  attribution: z.ZodObject<{
57
- principal: z.ZodObject<{
57
+ principal: z.ZodDiscriminatedUnion<[z.ZodObject<{
58
+ authority: z.ZodLiteral<"first_party">;
58
59
  billing: z.ZodObject<{
59
60
  accountId: z.core.$ZodBranded<z.ZodString, "OxyAccountId", "out">;
60
61
  }, z.core.$strict>;
@@ -65,6 +66,8 @@ export declare const normalizedUsageReportSchema: z.ZodObject<{
65
66
  staging: "staging";
66
67
  production: "production";
67
68
  }>;
69
+ }, z.core.$strict>, z.ZodObject<{
70
+ authority: z.ZodOptional<z.ZodLiteral<"external">>;
68
71
  inferenceScopes: z.ZodArray<z.ZodEnum<{
69
72
  "inference:invoke": "inference:invoke";
70
73
  "inference:models:read": "inference:models:read";
@@ -74,7 +77,17 @@ export declare const normalizedUsageReportSchema: z.ZodObject<{
74
77
  "inference:providers:read": "inference:providers:read";
75
78
  "inference:providers:write": "inference:providers:write";
76
79
  }>>;
77
- }, z.core.$strip>;
80
+ billing: z.ZodObject<{
81
+ accountId: z.core.$ZodBranded<z.ZodString, "OxyAccountId", "out">;
82
+ }, z.core.$strict>;
83
+ applicationId: z.ZodString;
84
+ credentialId: z.ZodString;
85
+ environment: z.ZodEnum<{
86
+ development: "development";
87
+ staging: "staging";
88
+ production: "production";
89
+ }>;
90
+ }, z.core.$strict>], "authority">;
78
91
  userId: z.ZodOptional<z.core.$ZodBranded<z.ZodString, "DelegatedUserId", "out">>;
79
92
  requestId: z.ZodString;
80
93
  generationId: z.ZodOptional<z.ZodString>;
@@ -8,6 +8,7 @@
8
8
  * (decision 9) and transcription are new in contract set 4.0.0.
9
9
  */
10
10
  import { z } from 'zod';
11
+ import { maxUtf16Length, minUtf16Length } from '../stringBounds.js';
11
12
  import { audioInputMediaTypeSchema, languageTagSchema, speechFormatSchema, speechMediaType, } from './audioFormats.js';
12
13
  import { publicErrorSchema } from './errors.js';
13
14
  import { modelReferenceSchema, PADDED_BASE64_PATTERN, requestIdSchema } from './identifiers.js';
@@ -43,8 +44,8 @@ export const speechRequestSchema = z
43
44
  .object({
44
45
  model: modelReferenceSchema,
45
46
  /** Bounded so one request cannot drive the hold arbitrarily high. */
46
- input: z.string().min(1).max(MAX_SPEECH_INPUT_CHARACTERS),
47
- voice: z.string().min(1).max(64),
47
+ input: z.string().check(minUtf16Length(1)).check(maxUtf16Length(MAX_SPEECH_INPUT_CHARACTERS)),
48
+ voice: z.string().check(minUtf16Length(1)).check(maxUtf16Length(64)),
48
49
  /** Absent means `mp3`. */
49
50
  response_format: speechFormatSchema.optional(),
50
51
  /** The contract's outer bound; each model publishes its own range. */
@@ -53,7 +54,7 @@ export const speechRequestSchema = z
53
54
  /** Only with `stream: true`. Absent means `audio`. */
54
55
  stream_format: speechStreamFormatSchema.optional(),
55
56
  /** OpenAI's end-user attribution field: the delegated user id, attribution only. */
56
- user: z.string().min(1).max(64).optional(),
57
+ user: z.string().check(minUtf16Length(1)).check(maxUtf16Length(64)).optional(),
57
58
  })
58
59
  .strict()
59
60
  .superRefine((request, ctx) => {
@@ -79,7 +80,11 @@ export const speechAudioDeltaEventSchema = z
79
80
  .object({
80
81
  type: z.literal('speech.audio.delta'),
81
82
  /** Standard padded base64 of at most 49 152 bytes of audio. */
82
- audio: z.string().min(4).max(65_536).regex(PADDED_BASE64_PATTERN),
83
+ audio: z
84
+ .string()
85
+ .check(minUtf16Length(4))
86
+ .check(maxUtf16Length(65_536))
87
+ .regex(PADDED_BASE64_PATTERN),
83
88
  })
84
89
  .strict();
85
90
  /** The last event of a successful stream: what served it and what it consumed. */
@@ -169,7 +174,7 @@ export const transcriptionRequestSchema = z
169
174
  * A hint — vocabulary or context that helps the model, never an
170
175
  * instruction — used where the model takes one.
171
176
  */
172
- prompt: z.string().max(4096).optional(),
177
+ prompt: z.string().check(maxUtf16Length(4096)).optional(),
173
178
  })
174
179
  .strict();
175
180
  /**
@@ -198,8 +203,8 @@ export const transcriptionJsonRequestSchema = transcriptionRequestSchema
198
203
  mediaType: audioInputMediaTypeSchema,
199
204
  data: z
200
205
  .string()
201
- .min(4)
202
- .max(MAX_TRANSCRIPTION_AUDIO_BASE64_LENGTH)
206
+ .check(minUtf16Length(4))
207
+ .check(maxUtf16Length(MAX_TRANSCRIPTION_AUDIO_BASE64_LENGTH))
203
208
  .regex(PADDED_BASE64_PATTERN),
204
209
  })
205
210
  .strict(),
@@ -6,6 +6,7 @@
6
6
  * New in contract set 4.0.0 (Kaana ADR 0002, decisions 8 and 9).
7
7
  */
8
8
  import { z } from 'zod';
9
+ import { maxUtf16Length } from '../stringBounds.js';
9
10
  import { inferenceAudioMediaTypeSchema } from './streamEvents.js';
10
11
  /**
11
12
  * A BCP 47 language tag (`en`, `es-ES`, `zh-Hant-TW`), as voices, models and
@@ -14,7 +15,7 @@ import { inferenceAudioMediaTypeSchema } from './streamEvents.js';
14
15
  */
15
16
  export const languageTagSchema = z
16
17
  .string()
17
- .max(35)
18
+ .check(maxUtf16Length(35))
18
19
  .regex(/^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$/, 'must be a BCP 47 language tag');
19
20
  /** The formats a speech request names in `response_format`. */
20
21
  export const speechFormatSchema = z.enum(['mp3', 'opus', 'aac', 'flac', 'wav', 'pcm']);
@@ -4,6 +4,7 @@
4
4
  * Moved from `@oxy.so/contracts` 4.12.0 (`src/inference/catalogue.ts`) by Kaana ADR 0002.
5
5
  */
6
6
  import { z } from 'zod';
7
+ import { maxUtf16Length, minUtf16Length } from '../stringBounds.js';
7
8
  import { inferenceDateSchema, inferenceHttpsUrlSchema, inferenceRegionSchema, inferenceTimestampSchema, modelIdSchema, modelReferenceSchema, modelRevisionLabelSchema, publisherSlugSchema, } from './identifiers.js';
8
9
  import { audioInputMediaTypeSchema, languageTagSchema, realtimeAudioFormatSchema, } from './audioFormats.js';
9
10
  import { moneySchema, priceSnapshotSchema } from './money.js';
@@ -223,8 +224,8 @@ export const modelCapabilitiesSchema = z
223
224
  export const modelLicenseSchema = z
224
225
  .object({
225
226
  /** SPDX identifier where one exists, otherwise the publisher's own name. */
226
- licenseId: z.string().min(1).max(128),
227
- displayName: z.string().min(1).max(200),
227
+ licenseId: z.string().check(minUtf16Length(1)).check(maxUtf16Length(128)),
228
+ displayName: z.string().check(minUtf16Length(1)).check(maxUtf16Length(200)),
228
229
  url: inferenceHttpsUrlSchema.optional(),
229
230
  commercialUseAllowed: z.boolean(),
230
231
  requiresAttribution: z.boolean(),
@@ -248,7 +249,7 @@ export const modelProvenanceSchema = z
248
249
  ]),
249
250
  /** The model this one was derived/fine-tuned from, where there is one. */
250
251
  baseModelId: modelIdSchema.optional(),
251
- trainingOrganization: z.string().min(1).max(200).optional(),
252
+ trainingOrganization: z.string().check(minUtf16Length(1)).check(maxUtf16Length(200)).optional(),
252
253
  })
253
254
  .strict();
254
255
  /**
@@ -265,7 +266,9 @@ export const inferenceDataPolicySchema = z
265
266
  trainsOnCustomerData: z.boolean(),
266
267
  zeroDataRetentionAvailable: z.boolean(),
267
268
  /** Named subprocessors a payload may pass through, for compliance review. */
268
- subprocessors: z.array(z.string().min(1).max(200)).default([]),
269
+ subprocessors: z
270
+ .array(z.string().check(minUtf16Length(1)).check(maxUtf16Length(200)))
271
+ .default([]),
269
272
  policyUrl: inferenceHttpsUrlSchema.optional(),
270
273
  })
271
274
  .strict()
@@ -309,10 +312,10 @@ export const modelDeprecationSchema = z
309
312
  /** One published evaluation result for a revision. */
310
313
  export const modelEvaluationResultSchema = z
311
314
  .object({
312
- suite: z.string().min(1).max(128),
313
- metric: z.string().min(1).max(128),
315
+ suite: z.string().check(minUtf16Length(1)).check(maxUtf16Length(128)),
316
+ metric: z.string().check(minUtf16Length(1)).check(maxUtf16Length(128)),
314
317
  /** Kept as a string: an eval score is published text, not arithmetic. */
315
- score: z.string().min(1).max(64),
318
+ score: z.string().check(minUtf16Length(1)).check(maxUtf16Length(64)),
316
319
  evaluatedAt: inferenceTimestampSchema.optional(),
317
320
  reportUrl: inferenceHttpsUrlSchema.optional(),
318
321
  })
@@ -325,7 +328,9 @@ export const modelSafetyMetadataSchema = z
325
328
  .object({
326
329
  safetyCardUrl: inferenceHttpsUrlSchema.optional(),
327
330
  contentFilteringDefault: z.enum(['none', 'provider_default', 'strict']),
328
- knownLimitations: z.array(z.string().min(1).max(500)).default([]),
331
+ knownLimitations: z
332
+ .array(z.string().check(minUtf16Length(1)).check(maxUtf16Length(500)))
333
+ .default([]),
329
334
  /** Content-provenance marking the modality requires, where it requires one. */
330
335
  provenanceMarking: z.enum(['none', 'visible_watermark', 'invisible_watermark', 'c2pa']),
331
336
  })
@@ -334,7 +339,7 @@ export const modelSafetyMetadataSchema = z
334
339
  export const cataloguePublisherSummarySchema = z
335
340
  .object({
336
341
  slug: publisherSlugSchema,
337
- displayName: z.string().min(1).max(200),
342
+ displayName: z.string().check(minUtf16Length(1)).check(maxUtf16Length(200)),
338
343
  websiteUrl: inferenceHttpsUrlSchema.optional(),
339
344
  })
340
345
  .strict();
@@ -345,8 +350,8 @@ export const cataloguePublisherSummarySchema = z
345
350
  export const voiceSchema = z
346
351
  .object({
347
352
  /** What a speech request names in `voice`. */
348
- id: z.string().min(1).max(64),
349
- name: z.string().min(1).max(200),
353
+ id: z.string().check(minUtf16Length(1)).check(maxUtf16Length(64)),
354
+ name: z.string().check(minUtf16Length(1)).check(maxUtf16Length(200)),
350
355
  /** The languages this voice speaks; each is one of the model's `languages`. */
351
356
  languages: z.array(languageTagSchema),
352
357
  gender: z.enum(['female', 'male', 'neutral']).optional(),
@@ -455,8 +460,8 @@ export const modelSchema = z.object({
455
460
  schemaVersion: z.literal(1),
456
461
  modelId: modelIdSchema,
457
462
  publisher: cataloguePublisherSummarySchema,
458
- displayName: z.string().min(1).max(200),
459
- description: z.string().max(4000).optional(),
463
+ displayName: z.string().check(minUtf16Length(1)).check(maxUtf16Length(200)),
464
+ description: z.string().check(maxUtf16Length(4000)).optional(),
460
465
  currentRevision: modelRevisionLabelSchema,
461
466
  /** Revisions a customer may pin today, newest first. */
462
467
  availableRevisions: z.array(modelRevisionLabelSchema).min(1),