@kaana.ai/contracts 8.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.
@@ -5,6 +5,7 @@
5
5
  * Moved from `@oxy.so/contracts` 4.12.0 (`src/inference/catalogue.ts`) by Kaana ADR 0002.
6
6
  */
7
7
  import { z } from 'zod';
8
+ import { maxUtf16Length, minUtf16Length } from '../stringBounds.js';
8
9
  import { cataloguePublisherSummarySchema, inferenceDataPolicySchema, modelCapabilitiesSchema, modelDeprecationSchema, modelEvaluationResultSchema, modelLicenseSchema, modelPowerClassSchema, modelProvenanceSchema, modelSafetyMetadataSchema, modelSchema, powerLevelSchema, reasoningEffortSchema, } from '../public/catalogue.js';
9
10
  import { inferenceDateSchema, inferenceHttpsUrlSchema, inferenceRegionSchema, inferenceTimestampSchema, modelIdSchema, modelReferenceSchema, modelRevisionLabelSchema, modelSlugSchema, publisherSlugSchema, RESERVED_ALIA_PUBLISHER, sha256DigestSchema, } from '../public/identifiers.js';
10
11
  import { priceSnapshotSchema } from '../public/money.js';
@@ -34,10 +35,10 @@ export const commercialPermissionSchema = z.enum([
34
35
  export const modelPublisherSchema = z.object({
35
36
  /** See `version.ts`: served on its own by the catalogue, so it is versioned. */
36
37
  schemaVersion: z.literal(1),
37
- publisherId: z.string().min(1).max(128),
38
+ publisherId: z.string().check(minUtf16Length(1)).check(maxUtf16Length(128)),
38
39
  slug: publisherSlugSchema,
39
- displayName: z.string().min(1).max(200),
40
- description: z.string().max(2000).optional(),
40
+ displayName: z.string().check(minUtf16Length(1)).check(maxUtf16Length(200)),
41
+ description: z.string().check(maxUtf16Length(2000)).optional(),
41
42
  websiteUrl: inferenceHttpsUrlSchema.optional(),
42
43
  });
43
44
  /**
@@ -54,8 +55,8 @@ export const catalogueModelSchema = z
54
55
  modelId: modelIdSchema,
55
56
  publisher: publisherSlugSchema,
56
57
  slug: modelSlugSchema,
57
- displayName: z.string().min(1).max(200),
58
- description: z.string().max(4000).optional(),
58
+ displayName: z.string().check(minUtf16Length(1)).check(maxUtf16Length(200)),
59
+ description: z.string().check(maxUtf16Length(4000)).optional(),
59
60
  capabilities: modelCapabilitiesSchema,
60
61
  license: modelLicenseSchema,
61
62
  provenance: modelProvenanceSchema,
@@ -98,7 +99,7 @@ export const modelRevisionSchema = z
98
99
  .object({
99
100
  /** See `version.ts`: served on its own by the catalogue, so it is versioned. */
100
101
  schemaVersion: z.literal(1),
101
- revisionId: z.string().min(1).max(128),
102
+ revisionId: z.string().check(minUtf16Length(1)).check(maxUtf16Length(128)),
102
103
  modelId: modelIdSchema,
103
104
  revision: modelRevisionLabelSchema,
104
105
  reference: modelReferenceSchema,
@@ -123,9 +124,9 @@ export const modelRevisionSchema = z
123
124
  export const inferenceProviderSchema = z.object({
124
125
  /** See `version.ts`: served on its own by the catalogue, so it is versioned. */
125
126
  schemaVersion: z.literal(1),
126
- providerId: z.string().min(1).max(128),
127
+ providerId: z.string().check(minUtf16Length(1)).check(maxUtf16Length(128)),
127
128
  slug: inferenceProviderSlugSchema,
128
- displayName: z.string().min(1).max(200),
129
+ displayName: z.string().check(minUtf16Length(1)).check(maxUtf16Length(200)),
129
130
  /**
130
131
  * `customer_byok` means the customer's own upstream account is billed
131
132
  * directly by the provider and Oxy charges only its platform fee.
@@ -165,7 +166,7 @@ export const modelDeploymentSchema = z
165
166
  /** Reserved capacity for one enterprise account rather than shared. */
166
167
  dedicatedCapacity: z.boolean(),
167
168
  /** The price version customers are charged under on this route. */
168
- priceVersionId: z.string().min(1).max(128).optional(),
169
+ priceVersionId: z.string().check(minUtf16Length(1)).check(maxUtf16Length(128)).optional(),
169
170
  })
170
171
  .superRefine((deployment, ctx) => {
171
172
  if (!deployment.modelReference.includes('@')) {
@@ -268,8 +269,8 @@ export const routingProfileSchema = z.object({
268
269
  schemaVersion: z.literal(1),
269
270
  routingProfileId: routingProfileIdSchema,
270
271
  slug: routingProfileSlugSchema,
271
- displayName: z.string().min(1).max(200),
272
- description: z.string().max(2000).optional(),
272
+ displayName: z.string().check(minUtf16Length(1)).check(maxUtf16Length(200)),
273
+ description: z.string().check(maxUtf16Length(2000)).optional(),
273
274
  /** What the profile optimises for when several candidates qualify. */
274
275
  optimiseFor: z.enum(['price', 'latency', 'throughput', 'quality', 'balanced']),
275
276
  candidates: z.array(routingProfileCandidateSchema).min(1),
@@ -300,7 +301,7 @@ export const routingProfileSchema = z.object({
300
301
  export const catalogueServingProviderSummarySchema = z
301
302
  .object({
302
303
  slug: inferenceProviderSlugSchema,
303
- displayName: z.string().min(1).max(200),
304
+ displayName: z.string().check(minUtf16Length(1)).check(maxUtf16Length(200)),
304
305
  regions: z.array(inferenceRegionSchema).default([]),
305
306
  dataPolicy: inferenceDataPolicySchema,
306
307
  })
@@ -317,8 +318,8 @@ export const modelCatalogueEntrySchema = z.object({
317
318
  schemaVersion: z.literal(3),
318
319
  modelId: modelIdSchema,
319
320
  publisher: cataloguePublisherSummarySchema,
320
- displayName: z.string().min(1).max(200),
321
- description: z.string().max(4000).optional(),
321
+ displayName: z.string().check(minUtf16Length(1)).check(maxUtf16Length(200)),
322
+ description: z.string().check(maxUtf16Length(4000)).optional(),
322
323
  currentRevision: modelRevisionLabelSchema,
323
324
  /** Revisions a customer may pin today, newest first. */
324
325
  availableRevisions: z.array(modelRevisionLabelSchema).min(1),
@@ -6,6 +6,7 @@
6
6
  * validation and custody metadata) stay in `@oxy.so/contracts`.
7
7
  */
8
8
  import { z } from 'zod';
9
+ import { maxUtf16Length, minUtf16Length } from '../stringBounds.js';
9
10
  import { inferenceEnvironmentSchema, oxyApplicationIdSchema, PADDED_BASE64_PATTERN, } from '../public/identifiers.js';
10
11
  import { deploymentIdSchema, inferenceProviderSlugSchema } from './identifiers.js';
11
12
  /** Opaque reference minted by Kaana. It is not a KMS/Vault/SSM locator. */
@@ -28,7 +29,7 @@ export const kaanaCredentialIdentitySchema = z
28
29
  .strict();
29
30
  const kaanaCredentialOperationActorSchema = z
30
31
  .string()
31
- .min(1)
32
+ .check(minUtf16Length(1))
32
33
  .refine((value) => new TextEncoder().encode(value).byteLength <= 256 &&
33
34
  value === value.trim() &&
34
35
  !/[\r\n]/.test(value), {
@@ -70,8 +71,8 @@ function isVisibleASCIIProviderCredential(value) {
70
71
  }
71
72
  const kaanaCredentialSecretBase64Schema = z
72
73
  .string()
73
- .min(1)
74
- .max(8192)
74
+ .check(minUtf16Length(1))
75
+ .check(maxUtf16Length(8192))
75
76
  .regex(PADDED_BASE64_PATTERN)
76
77
  .refine(isVisibleASCIIProviderCredential, {
77
78
  message: 'a decoded provider credential is 1-4096 visible ASCII bytes',
@@ -4,6 +4,7 @@
4
4
  * Moved from `@oxy.so/contracts` 4.12.0 (`src/inference/embeddings.ts`) by Kaana ADR 0002.
5
5
  */
6
6
  import { z } from 'zod';
7
+ import { maxUtf16Length, minUtf16Length } from '../stringBounds.js';
7
8
  import { inferenceErrorSchema } from './errors.js';
8
9
  export const embeddingVectorSchema = z
9
10
  .object({
@@ -24,8 +25,8 @@ export const embeddingUsageSchema = z
24
25
  export const embeddingSuccessSchema = z
25
26
  .object({
26
27
  schemaVersion: z.literal(1),
27
- requestId: z.string().min(1).max(128),
28
- model: z.string().min(1).max(255),
28
+ requestId: z.string().check(minUtf16Length(1)).check(maxUtf16Length(128)),
29
+ model: z.string().check(minUtf16Length(1)).check(maxUtf16Length(255)),
29
30
  dimension: z.number().int().positive().max(1024),
30
31
  data: z.array(embeddingVectorSchema).min(1).max(2048),
31
32
  usage: embeddingUsageSchema,
@@ -52,7 +53,7 @@ export const embeddingSuccessSchema = z
52
53
  export const embeddingFailureSchema = z
53
54
  .object({
54
55
  schemaVersion: z.literal(1),
55
- requestId: z.string().min(1).max(128),
56
+ requestId: z.string().check(minUtf16Length(1)).check(maxUtf16Length(128)),
56
57
  error: inferenceErrorSchema,
57
58
  })
58
59
  .strict();
@@ -5,6 +5,7 @@
5
5
  * Moved from `@oxy.so/contracts` 4.12.0 (`src/inference/errors.ts`) by Kaana ADR 0002.
6
6
  */
7
7
  import { z } from 'zod';
8
+ import { maxUtf16Length } from '../stringBounds.js';
8
9
  import { publicErrorSchema, safeErrorTextSchema, upstreamErrorCategorySchema, } from '../public/errors.js';
9
10
  import { requestIdSchema } from '../public/identifiers.js';
10
11
  import { inferenceProviderSlugSchema } from './identifiers.js';
@@ -120,7 +121,7 @@ export const providerErrorPassthroughSchema = z
120
121
  /** The upstream HTTP status, when the upstream spoke HTTP. */
121
122
  status: z.number().int().min(100).max(599).optional(),
122
123
  /** The upstream's own error code, verbatim and uninterpreted. */
123
- code: z.string().max(128).optional(),
124
+ code: z.string().check(maxUtf16Length(128)).optional(),
124
125
  /** The upstream's message, subject to the same credential refusal. */
125
126
  message: safeErrorTextSchema.optional(),
126
127
  })
@@ -143,7 +144,7 @@ export const inferenceErrorSchema = z
143
144
  /** How long to wait before retrying. Only meaningful when `retryable`. */
144
145
  retryAfterMs: z.number().int().nonnegative().safe().optional(),
145
146
  /** The request field at fault, for `invalid_request`. */
146
- param: z.string().max(128).optional(),
147
+ param: z.string().check(maxUtf16Length(128)).optional(),
147
148
  /** Present only when an upstream provider was reached and failed. */
148
149
  upstreamCategory: upstreamErrorCategorySchema.optional(),
149
150
  providerError: providerErrorPassthroughSchema.optional(),
@@ -18,6 +18,7 @@
18
18
  * operation, decisions included, is an ordinary grant of ordered steps.
19
19
  */
20
20
  import { z } from 'zod';
21
+ import { maxUtf16Length, minUtf16Length } from '../stringBounds.js';
21
22
  import { powerLevelSchema, realtimeSessionKindSchema } from '../public/catalogue.js';
22
23
  import { generationRecordSchema } from '../public/generations.js';
23
24
  import { delegatedUserIdSchema, generationIdSchema, idempotencyKeySchema, inferenceEnvironmentSchema, inferenceRegionSchema, inferenceTimestampSchema, modelIdSchema, modelRevisionLabelSchema, oxyApplicationIdSchema, oxyCredentialIdSchema, requestIdSchema, } from '../public/identifiers.js';
@@ -113,7 +114,7 @@ export const grantRequestFactsSchema = z
113
114
  realtimeSessionKind: realtimeSessionKindSchema.optional(),
114
115
  })
115
116
  .strict();
116
- const credentialSchema = z.string().min(1).max(8192);
117
+ const credentialSchema = z.string().check(minUtf16Length(1)).check(maxUtf16Length(8192));
117
118
  /**
118
119
  * `POST /internal/kaana/v1/authorizations` for an inference request. Kaana
119
120
  * authenticates as a workload (Oxy ADR 0026); `credential` is the caller's
@@ -137,8 +138,8 @@ export const inferenceAuthorizationRequestSchema = z
137
138
  client: z
138
139
  .object({
139
140
  /** The public path, e.g. `/v1/responses`. */
140
- endpoint: z.string().min(1).max(256),
141
- clientRequestId: z.string().min(1).max(128).optional(),
141
+ endpoint: z.string().check(minUtf16Length(1)).check(maxUtf16Length(256)),
142
+ clientRequestId: z.string().check(minUtf16Length(1)).check(maxUtf16Length(128)).optional(),
142
143
  receivedAt: inferenceTimestampSchema,
143
144
  labels: requestLabelsSchema.optional(),
144
145
  })
@@ -227,7 +228,7 @@ export const grantPrincipalSchema = z
227
228
  export const admittedModelLineSchema = z
228
229
  .object({
229
230
  modelLine: modelIdSchema,
230
- priceVersionId: z.string().min(1).max(128),
231
+ priceVersionId: z.string().check(minUtf16Length(1)).check(maxUtf16Length(128)),
231
232
  })
232
233
  .strict();
233
234
  /**
@@ -250,7 +251,9 @@ export const grantStepLimitsSchema = z
250
251
  deniedRegions: z.array(inferenceRegionSchema).default([]),
251
252
  requireZeroDataRetention: z.boolean(),
252
253
  prohibitTrainingOnCustomerData: z.boolean(),
253
- allowedLicenseIds: z.array(z.string().min(1).max(128)).default([]),
254
+ allowedLicenseIds: z
255
+ .array(z.string().check(minUtf16Length(1)).check(maxUtf16Length(128)))
256
+ .default([]),
254
257
  requireCommercialUseRights: z.boolean(),
255
258
  /**
256
259
  * Whether Kaana may fail over, inside this step, between providers (and
@@ -320,7 +323,7 @@ const customerProviderCredentialBinding = authorizedRouteSchema.options[0].shape
320
323
  export const grantSchema = z
321
324
  .object({
322
325
  schemaVersion: z.literal(1),
323
- grantId: z.string().min(1).max(128),
326
+ grantId: z.string().check(minUtf16Length(1)).check(maxUtf16Length(128)),
324
327
  requestId: requestIdSchema,
325
328
  operation: grantOperationSchema,
326
329
  issuedAt: inferenceTimestampSchema,
@@ -334,14 +337,14 @@ export const grantSchema = z
334
337
  economics: z
335
338
  .object({
336
339
  treatment: inferenceEconomicTreatmentSchema,
337
- policyVersion: z.string().min(1).max(128),
338
- relationshipId: z.string().min(1).max(128).optional(),
340
+ policyVersion: z.string().check(minUtf16Length(1)).check(maxUtf16Length(128)),
341
+ relationshipId: z.string().check(minUtf16Length(1)).check(maxUtf16Length(128)).optional(),
339
342
  })
340
343
  .strict(),
341
344
  /** The hold. Absent for `internal_metered`, which holds nothing. */
342
345
  reservation: z
343
346
  .object({
344
- reservationId: z.string().min(1).max(128),
347
+ reservationId: z.string().check(minUtf16Length(1)).check(maxUtf16Length(128)),
345
348
  /** The most the hold covers. Shown, never spent by Kaana. */
346
349
  ceiling: moneySchema,
347
350
  /** `promotional-only`: the hold draws on promotional credit alone. */
@@ -351,7 +354,7 @@ export const grantSchema = z
351
354
  .optional(),
352
355
  /** The capacity slot an internal relationship claimed (e.g. `alia-kaana`). */
353
356
  capacity: z
354
- .object({ meteredUsageId: z.string().min(1).max(128) })
357
+ .object({ meteredUsageId: z.string().check(minUtf16Length(1)).check(maxUtf16Length(128)) })
355
358
  .strict()
356
359
  .optional(),
357
360
  steps: z.array(grantStepSchema).min(1).max(8),
@@ -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
@@ -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) => {
@@ -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()
@@ -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();
@@ -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),