@kaana.ai/contracts 0.0.0-stage → 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +673 -0
- package/NOTICE +21 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +29 -0
- package/dist/internal/attribution.d.ts +116 -0
- package/dist/internal/attribution.js +82 -0
- package/dist/internal/canonical.d.ts +31 -0
- package/dist/internal/canonical.js +57 -0
- package/dist/internal/catalogue.d.ts +1059 -0
- package/dist/internal/catalogue.js +389 -0
- package/dist/internal/credentialControl.d.ts +329 -0
- package/dist/internal/credentialControl.js +256 -0
- package/dist/internal/decisions.d.ts +245 -0
- package/dist/internal/decisions.js +69 -0
- package/dist/internal/economics.d.ts +27 -0
- package/dist/internal/economics.js +26 -0
- package/dist/internal/embeddings.d.ts +164 -0
- package/dist/internal/embeddings.js +59 -0
- package/dist/internal/errors.d.ts +185 -0
- package/dist/internal/errors.js +211 -0
- package/dist/internal/grant.d.ts +699 -0
- package/dist/internal/grant.js +445 -0
- package/dist/internal/identifiers.d.ts +63 -0
- package/dist/internal/identifiers.js +65 -0
- package/dist/internal/privateAutoExecution.d.ts +158 -0
- package/dist/internal/privateAutoExecution.js +188 -0
- package/dist/internal/realtime.d.ts +1005 -0
- package/dist/internal/realtime.js +187 -0
- package/dist/internal/request.d.ts +1079 -0
- package/dist/internal/request.js +404 -0
- package/dist/internal/routing.d.ts +90 -0
- package/dist/internal/routing.js +139 -0
- package/dist/internal/scopedExecution.d.ts +74 -0
- package/dist/internal/scopedExecution.js +61 -0
- package/dist/internal/settlement.d.ts +205 -0
- package/dist/internal/settlement.js +71 -0
- package/dist/internal/streamEvents.d.ts +422 -0
- package/dist/internal/streamEvents.js +171 -0
- package/dist/internal/usage.d.ts +127 -0
- package/dist/internal/usage.js +109 -0
- package/dist/internal.d.ts +30 -0
- package/dist/internal.js +30 -0
- package/dist/public/audio.d.ts +347 -0
- package/dist/public/audio.js +236 -0
- package/dist/public/audioFormats.d.ts +64 -0
- package/dist/public/audioFormats.js +60 -0
- package/dist/public/catalogue.d.ts +914 -0
- package/dist/public/catalogue.js +516 -0
- package/dist/public/chatCompletions.d.ts +381 -0
- package/dist/public/chatCompletions.js +321 -0
- package/dist/public/decisions.d.ts +182 -0
- package/dist/public/decisions.js +257 -0
- package/dist/public/embeddings.d.ts +34 -0
- package/dist/public/embeddings.js +66 -0
- package/dist/public/errors.d.ts +195 -0
- package/dist/public/errors.js +274 -0
- package/dist/public/generations.d.ts +330 -0
- package/dist/public/generations.js +121 -0
- package/dist/public/identifiers.d.ts +139 -0
- package/dist/public/identifiers.js +160 -0
- package/dist/public/images.d.ts +36 -0
- package/dist/public/images.js +36 -0
- package/dist/public/messages.d.ts +297 -0
- package/dist/public/messages.js +251 -0
- package/dist/public/money.d.ts +308 -0
- package/dist/public/money.js +237 -0
- package/dist/public/policy.d.ts +19 -0
- package/dist/public/policy.js +20 -0
- package/dist/public/realtime.d.ts +2006 -0
- package/dist/public/realtime.js +797 -0
- package/dist/public/responses.d.ts +253 -0
- package/dist/public/responses.js +95 -0
- package/dist/public/streamEvents.d.ts +372 -0
- package/dist/public/streamEvents.js +157 -0
- package/dist/public/version.d.ts +184 -0
- package/dist/public/version.js +184 -0
- package/openapi.json +6967 -0
- package/package.json +44 -4
- package/README.md +0 -3
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The operational catalogue Oxy and Kaana share: deployments, providers and
|
|
3
|
+
* routing profiles. None of it is public: it names who serves a route.
|
|
4
|
+
*
|
|
5
|
+
* Moved from `@oxy.so/contracts` 4.12.0 (`src/inference/catalogue.ts`) by Kaana ADR 0002.
|
|
6
|
+
*/
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
import { cataloguePublisherSummarySchema, inferenceDataPolicySchema, modelCapabilitiesSchema, modelDeprecationSchema, modelEvaluationResultSchema, modelLicenseSchema, modelPowerClassSchema, modelProvenanceSchema, modelSafetyMetadataSchema, modelSchema, powerLevelSchema, reasoningEffortSchema, } from '../public/catalogue.js';
|
|
9
|
+
import { inferenceDateSchema, inferenceHttpsUrlSchema, inferenceRegionSchema, inferenceTimestampSchema, modelIdSchema, modelReferenceSchema, modelRevisionLabelSchema, modelSlugSchema, publisherSlugSchema, RESERVED_ALIA_PUBLISHER, sha256DigestSchema, } from '../public/identifiers.js';
|
|
10
|
+
import { priceSnapshotSchema } from '../public/money.js';
|
|
11
|
+
import { deploymentIdSchema, inferenceProviderSlugSchema, routingProfileIdSchema, routingProfileSlugSchema, } from './identifiers.js';
|
|
12
|
+
import { scopedExecutionAudienceSchema } from './scopedExecution.js';
|
|
13
|
+
/**
|
|
14
|
+
* Who a route may be served to. Availability to an official Oxy product never
|
|
15
|
+
* implies permission to resell the same provider/model publicly, which is why
|
|
16
|
+
* this is an explicit scope on the route rather than a boolean derived from
|
|
17
|
+
* "it works".
|
|
18
|
+
*/
|
|
19
|
+
export const availabilityScopeSchema = z.enum([
|
|
20
|
+
'platform_internal',
|
|
21
|
+
'public_payg',
|
|
22
|
+
'enterprise',
|
|
23
|
+
'byok_only',
|
|
24
|
+
'oxy_hosted',
|
|
25
|
+
]);
|
|
26
|
+
/** The commercial basis on which Oxy may serve a route. */
|
|
27
|
+
export const commercialPermissionSchema = z.enum([
|
|
28
|
+
'standard_application_use',
|
|
29
|
+
'public_resale_approved',
|
|
30
|
+
'wholesale_contract',
|
|
31
|
+
'customer_byok',
|
|
32
|
+
'open_weight_hosting',
|
|
33
|
+
]);
|
|
34
|
+
/** Who released a model. Never a provider, and never a routing profile. */
|
|
35
|
+
export const modelPublisherSchema = z.object({
|
|
36
|
+
/** See `version.ts`: served on its own by the catalogue, so it is versioned. */
|
|
37
|
+
schemaVersion: z.literal(1),
|
|
38
|
+
publisherId: z.string().min(1).max(128),
|
|
39
|
+
slug: publisherSlugSchema,
|
|
40
|
+
displayName: z.string().min(1).max(200),
|
|
41
|
+
description: z.string().max(2000).optional(),
|
|
42
|
+
websiteUrl: inferenceHttpsUrlSchema.optional(),
|
|
43
|
+
});
|
|
44
|
+
/**
|
|
45
|
+
* A model: the long-lived product identity `<publisher>/<model>`.
|
|
46
|
+
*
|
|
47
|
+
* Carries no provider, no region, no price and no availability — those belong
|
|
48
|
+
* to a DEPLOYMENT, because the same model is served on several routes whose
|
|
49
|
+
* answers to those questions differ.
|
|
50
|
+
*/
|
|
51
|
+
export const catalogueModelSchema = z
|
|
52
|
+
.object({
|
|
53
|
+
/** See `version.ts`: served on its own by the catalogue, so it is versioned. */
|
|
54
|
+
schemaVersion: z.literal(1),
|
|
55
|
+
modelId: modelIdSchema,
|
|
56
|
+
publisher: publisherSlugSchema,
|
|
57
|
+
slug: modelSlugSchema,
|
|
58
|
+
displayName: z.string().min(1).max(200),
|
|
59
|
+
description: z.string().max(4000).optional(),
|
|
60
|
+
capabilities: modelCapabilitiesSchema,
|
|
61
|
+
license: modelLicenseSchema,
|
|
62
|
+
provenance: modelProvenanceSchema,
|
|
63
|
+
knowledgeCutoff: inferenceDateSchema.optional(),
|
|
64
|
+
releasedOn: inferenceDateSchema.optional(),
|
|
65
|
+
/** The revision served when a caller names the model without pinning one. */
|
|
66
|
+
currentRevision: modelRevisionLabelSchema,
|
|
67
|
+
deprecation: modelDeprecationSchema,
|
|
68
|
+
})
|
|
69
|
+
.superRefine((model, ctx) => {
|
|
70
|
+
if (model.modelId !== `${model.publisher}/${model.slug}`) {
|
|
71
|
+
ctx.addIssue({
|
|
72
|
+
code: 'custom',
|
|
73
|
+
path: ['modelId'],
|
|
74
|
+
message: 'modelId must be exactly <publisher>/<model>',
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
// `alia/*` is reserved for models Alia actually owns or derived. A provider
|
|
78
|
+
// alias published under it would make an Oxy-branded model id mean nothing,
|
|
79
|
+
// and would put an Oxy name on somebody else's weights and license.
|
|
80
|
+
if (model.publisher === RESERVED_ALIA_PUBLISHER &&
|
|
81
|
+
model.provenance.releaseKind !== 'first_party_original' &&
|
|
82
|
+
model.provenance.releaseKind !== 'first_party_derived') {
|
|
83
|
+
ctx.addIssue({
|
|
84
|
+
code: 'custom',
|
|
85
|
+
path: ['provenance', 'releaseKind'],
|
|
86
|
+
message: `the ${RESERVED_ALIA_PUBLISHER}/* namespace is reserved for first-party releases`,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
/**
|
|
91
|
+
* An immutable revision of a model.
|
|
92
|
+
*
|
|
93
|
+
* `reference` is the exact string a customer pins (`<publisher>/<model>@<revision>`)
|
|
94
|
+
* and is checked against its parts, so a record cannot claim a reference that
|
|
95
|
+
* resolves elsewhere. Evaluation and safety metadata hang here rather than on
|
|
96
|
+
* the model, because they describe specific weights.
|
|
97
|
+
*/
|
|
98
|
+
export const modelRevisionSchema = z
|
|
99
|
+
.object({
|
|
100
|
+
/** See `version.ts`: served on its own by the catalogue, so it is versioned. */
|
|
101
|
+
schemaVersion: z.literal(1),
|
|
102
|
+
revisionId: z.string().min(1).max(128),
|
|
103
|
+
modelId: modelIdSchema,
|
|
104
|
+
revision: modelRevisionLabelSchema,
|
|
105
|
+
reference: modelReferenceSchema,
|
|
106
|
+
releasedAt: inferenceTimestampSchema,
|
|
107
|
+
retiredAt: inferenceTimestampSchema.optional(),
|
|
108
|
+
/** Digest of the served artifact, where Oxy hosts the weights itself. */
|
|
109
|
+
artifactDigest: sha256DigestSchema.optional(),
|
|
110
|
+
modelCardUrl: inferenceHttpsUrlSchema.optional(),
|
|
111
|
+
evaluations: z.array(modelEvaluationResultSchema).default([]),
|
|
112
|
+
safety: modelSafetyMetadataSchema.optional(),
|
|
113
|
+
})
|
|
114
|
+
.superRefine((revision, ctx) => {
|
|
115
|
+
if (revision.reference !== `${revision.modelId}@${revision.revision}`) {
|
|
116
|
+
ctx.addIssue({
|
|
117
|
+
code: 'custom',
|
|
118
|
+
path: ['reference'],
|
|
119
|
+
message: 'reference must be exactly <modelId>@<revision>',
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
/** Who runs the weights for a route. */
|
|
124
|
+
export const inferenceProviderSchema = z.object({
|
|
125
|
+
/** See `version.ts`: served on its own by the catalogue, so it is versioned. */
|
|
126
|
+
schemaVersion: z.literal(1),
|
|
127
|
+
providerId: z.string().min(1).max(128),
|
|
128
|
+
slug: inferenceProviderSlugSchema,
|
|
129
|
+
displayName: z.string().min(1).max(200),
|
|
130
|
+
/**
|
|
131
|
+
* `customer_byok` means the customer's own upstream account is billed
|
|
132
|
+
* directly by the provider and Oxy charges only its platform fee.
|
|
133
|
+
*/
|
|
134
|
+
kind: z.enum(['third_party', 'oxy_hosted', 'customer_byok']),
|
|
135
|
+
websiteUrl: inferenceHttpsUrlSchema.optional(),
|
|
136
|
+
statusPageUrl: inferenceHttpsUrlSchema.optional(),
|
|
137
|
+
regions: z.array(inferenceRegionSchema).default([]),
|
|
138
|
+
dataPolicy: inferenceDataPolicySchema,
|
|
139
|
+
});
|
|
140
|
+
/**
|
|
141
|
+
* One concrete servable route: a revision, on a provider, with its attested
|
|
142
|
+
* regions, data policy, availability scope and commercial permission.
|
|
143
|
+
*
|
|
144
|
+
* `regions: []` means the provider supplied no location attestation. It never
|
|
145
|
+
* means global availability: Oxy excludes that route whenever a request carries
|
|
146
|
+
* any explicit regional control, while an unconstrained request may still use it.
|
|
147
|
+
*
|
|
148
|
+
* This is the object a routing policy filters and a route switch names — never
|
|
149
|
+
* a model. Two deployments of the SAME revision are what same-model failover
|
|
150
|
+
* moves between; moving to a deployment of a different revision or model is a
|
|
151
|
+
* cross-model fallback and needs explicit authorization.
|
|
152
|
+
*/
|
|
153
|
+
export const modelDeploymentSchema = z
|
|
154
|
+
.object({
|
|
155
|
+
/** See `version.ts`: exchanged with the data plane on its own. */
|
|
156
|
+
schemaVersion: z.literal(2),
|
|
157
|
+
deploymentId: deploymentIdSchema,
|
|
158
|
+
/** Restrictive audience; never an eligibility approval. */
|
|
159
|
+
scopedExecution: scopedExecutionAudienceSchema.optional(),
|
|
160
|
+
provider: inferenceProviderSlugSchema,
|
|
161
|
+
/** Always revision-pinned: a deployment serves specific weights. */
|
|
162
|
+
modelReference: modelReferenceSchema,
|
|
163
|
+
regions: z.array(inferenceRegionSchema),
|
|
164
|
+
dataPolicy: inferenceDataPolicySchema,
|
|
165
|
+
availabilityScope: availabilityScopeSchema,
|
|
166
|
+
commercialPermission: commercialPermissionSchema,
|
|
167
|
+
status: z.enum(['active', 'degraded', 'disabled', 'retired']),
|
|
168
|
+
/** Reserved capacity for one enterprise account rather than shared. */
|
|
169
|
+
dedicatedCapacity: z.boolean(),
|
|
170
|
+
/** The price version customers are charged under on this route. */
|
|
171
|
+
priceVersionId: z.string().min(1).max(128).optional(),
|
|
172
|
+
})
|
|
173
|
+
.superRefine((deployment, ctx) => {
|
|
174
|
+
if (!deployment.modelReference.includes('@')) {
|
|
175
|
+
ctx.addIssue({
|
|
176
|
+
code: 'custom',
|
|
177
|
+
path: ['modelReference'],
|
|
178
|
+
message: 'a deployment must pin an immutable revision (<publisher>/<model>@<revision>)',
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
// A technically callable route is not automatically publicly resellable.
|
|
182
|
+
// Publishing one to pay-as-you-go customers requires a permission state that
|
|
183
|
+
// says somebody reviewed the right to resell it, not merely that it answers.
|
|
184
|
+
if (deployment.availabilityScope === 'public_payg' &&
|
|
185
|
+
deployment.commercialPermission !== 'public_resale_approved' &&
|
|
186
|
+
deployment.commercialPermission !== 'wholesale_contract' &&
|
|
187
|
+
deployment.commercialPermission !== 'open_weight_hosting') {
|
|
188
|
+
ctx.addIssue({
|
|
189
|
+
code: 'custom',
|
|
190
|
+
path: ['commercialPermission'],
|
|
191
|
+
message: 'a public pay-as-you-go route requires an approved resale permission',
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
if (deployment.availabilityScope === 'byok_only' &&
|
|
195
|
+
deployment.commercialPermission !== 'customer_byok') {
|
|
196
|
+
ctx.addIssue({
|
|
197
|
+
code: 'custom',
|
|
198
|
+
path: ['commercialPermission'],
|
|
199
|
+
message: 'a BYOK-only route is served under the customer’s own provider terms',
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
// This public field is the upstream/model price Oxy charges. A BYOK route
|
|
203
|
+
// bills the customer upstream and keeps that field absent; Oxy's separately
|
|
204
|
+
// reviewed platform-fee version is internal billing configuration and never
|
|
205
|
+
// reuses this provider-price slot.
|
|
206
|
+
if (deployment.priceVersionId !== undefined && deployment.availabilityScope === 'byok_only') {
|
|
207
|
+
ctx.addIssue({
|
|
208
|
+
code: 'custom',
|
|
209
|
+
path: ['priceVersionId'],
|
|
210
|
+
message: 'a BYOK-only route has no customer model price; the platform fee is separate',
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
/**
|
|
215
|
+
* The commercial facts Kaana publishes about ONE deployment on the descriptors
|
|
216
|
+
* it serves to Oxy (`POST /internal/v1/deployments/query` and
|
|
217
|
+
* `/internal/v1/models/query`), from the reviewed file
|
|
218
|
+
* `configs/deployment-commercial.json`. A deployment that is not sold carries
|
|
219
|
+
* no `commercial` at all, which is why the member is optional on the
|
|
220
|
+
* descriptor. New in contract set 4.4.0.
|
|
221
|
+
*
|
|
222
|
+
* `customer_byok` is the commercial basis of a `byok_only` route and of no
|
|
223
|
+
* other: the two say the same thing and may not disagree.
|
|
224
|
+
*/
|
|
225
|
+
export const deploymentCommercialSchema = z
|
|
226
|
+
.object({
|
|
227
|
+
availabilityScope: availabilityScopeSchema,
|
|
228
|
+
commercialPermission: commercialPermissionSchema,
|
|
229
|
+
/** Reserved capacity for one enterprise account; absent means shared. */
|
|
230
|
+
dedicatedCapacity: z.boolean().optional(),
|
|
231
|
+
})
|
|
232
|
+
.strict()
|
|
233
|
+
.superRefine((commercial, ctx) => {
|
|
234
|
+
const byokScope = commercial.availabilityScope === 'byok_only';
|
|
235
|
+
const byokPermission = commercial.commercialPermission === 'customer_byok';
|
|
236
|
+
if (byokScope !== byokPermission) {
|
|
237
|
+
ctx.addIssue({
|
|
238
|
+
code: 'custom',
|
|
239
|
+
path: ['commercialPermission'],
|
|
240
|
+
message: 'customer_byok is the permission of a byok_only route, and only of it',
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
if (commercial.availabilityScope === 'public_payg' &&
|
|
244
|
+
commercial.commercialPermission !== 'public_resale_approved' &&
|
|
245
|
+
commercial.commercialPermission !== 'wholesale_contract' &&
|
|
246
|
+
commercial.commercialPermission !== 'open_weight_hosting') {
|
|
247
|
+
ctx.addIssue({
|
|
248
|
+
code: 'custom',
|
|
249
|
+
path: ['commercialPermission'],
|
|
250
|
+
message: 'a public pay-as-you-go route requires an approved resale permission',
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
/** One candidate a profile may resolve to, and how strongly it is preferred. */
|
|
255
|
+
export const routingProfileCandidateSchema = z
|
|
256
|
+
.object({
|
|
257
|
+
modelReference: modelReferenceSchema,
|
|
258
|
+
/** Lower sorts first. Ties are broken by the profile's optimisation target. */
|
|
259
|
+
priority: z.number().int().nonnegative().max(1000),
|
|
260
|
+
})
|
|
261
|
+
.strict();
|
|
262
|
+
/**
|
|
263
|
+
* A named strategy for choosing among routes — `auto`, `fast`, `quality`.
|
|
264
|
+
*
|
|
265
|
+
* Not a model: it has no publisher, no revision, no license and no weights, and
|
|
266
|
+
* its slug cannot be written as `<publisher>/<model>`. A request that names a
|
|
267
|
+
* profile is asking Oxy to choose; a request that names a model is not, which is
|
|
268
|
+
* the distinction the "never silently substituted" invariant rests on.
|
|
269
|
+
*/
|
|
270
|
+
export const routingProfileSchema = z.object({
|
|
271
|
+
/** See `version.ts`: served on its own by the catalogue, so it is versioned. */
|
|
272
|
+
schemaVersion: z.literal(1),
|
|
273
|
+
routingProfileId: routingProfileIdSchema,
|
|
274
|
+
slug: routingProfileSlugSchema,
|
|
275
|
+
displayName: z.string().min(1).max(200),
|
|
276
|
+
description: z.string().max(2000).optional(),
|
|
277
|
+
/** What the profile optimises for when several candidates qualify. */
|
|
278
|
+
optimiseFor: z.enum(['price', 'latency', 'throughput', 'quality', 'balanced']),
|
|
279
|
+
candidates: z.array(routingProfileCandidateSchema).min(1),
|
|
280
|
+
/** A product preset (Alia's "fast" toggle) rather than a customer's own profile. */
|
|
281
|
+
isProductPreset: z.boolean(),
|
|
282
|
+
/**
|
|
283
|
+
* Present when this profile IS a power level (contract set 3.4.0). Its
|
|
284
|
+
* `candidates` are then the currently servable models of the level's class,
|
|
285
|
+
* and may change between reads; cross-model failover among them is
|
|
286
|
+
* authorized by the profile and reported with a `route_switch` event.
|
|
287
|
+
*/
|
|
288
|
+
powerLevel: powerLevelSchema.optional(),
|
|
289
|
+
/**
|
|
290
|
+
* The reasoning effort a power level asks for when the request names none,
|
|
291
|
+
* clamped to the nearest effort the chosen model accepts (the lowest at or
|
|
292
|
+
* above it, else the highest). Absent: the level asks for no reasoning, sent
|
|
293
|
+
* as the least effort a reasoning model accepts.
|
|
294
|
+
*/
|
|
295
|
+
reasoningEffort: reasoningEffortSchema.optional(),
|
|
296
|
+
});
|
|
297
|
+
/**
|
|
298
|
+
* A serving provider as a customer may see it: who ran the request and where.
|
|
299
|
+
*
|
|
300
|
+
* Deliberately has no deployment id, no route id, no health score and no
|
|
301
|
+
* upstream cost — the customer-safe half of the serving boundary, so that
|
|
302
|
+
* exposing attribution can never leak operational topology.
|
|
303
|
+
*/
|
|
304
|
+
export const catalogueServingProviderSummarySchema = z
|
|
305
|
+
.object({
|
|
306
|
+
slug: inferenceProviderSlugSchema,
|
|
307
|
+
displayName: z.string().min(1).max(200),
|
|
308
|
+
regions: z.array(inferenceRegionSchema).default([]),
|
|
309
|
+
dataPolicy: inferenceDataPolicySchema,
|
|
310
|
+
})
|
|
311
|
+
.strict();
|
|
312
|
+
/**
|
|
313
|
+
* One entry of the customer-facing catalogue (`GET /v1/models`).
|
|
314
|
+
*
|
|
315
|
+
* A projection, not a container: it repeats the customer-facing fields instead
|
|
316
|
+
* of embedding the operational descriptors, so no internal identifier can reach
|
|
317
|
+
* a customer by being nested one level deeper than anybody looked.
|
|
318
|
+
*/
|
|
319
|
+
export const modelCatalogueEntrySchema = z.object({
|
|
320
|
+
/** See `version.ts`: this is the public catalogue response shape. */
|
|
321
|
+
schemaVersion: z.literal(3),
|
|
322
|
+
modelId: modelIdSchema,
|
|
323
|
+
publisher: cataloguePublisherSummarySchema,
|
|
324
|
+
displayName: z.string().min(1).max(200),
|
|
325
|
+
description: z.string().max(4000).optional(),
|
|
326
|
+
currentRevision: modelRevisionLabelSchema,
|
|
327
|
+
/** Revisions a customer may pin today, newest first. */
|
|
328
|
+
availableRevisions: z.array(modelRevisionLabelSchema).min(1),
|
|
329
|
+
capabilities: modelCapabilitiesSchema,
|
|
330
|
+
license: modelLicenseSchema,
|
|
331
|
+
provenance: modelProvenanceSchema,
|
|
332
|
+
knowledgeCutoff: inferenceDateSchema.optional(),
|
|
333
|
+
releasedOn: inferenceDateSchema.optional(),
|
|
334
|
+
/**
|
|
335
|
+
* When the upstream provider first published this model, as that provider
|
|
336
|
+
* reports it. Present only when a provider reported it; never an Oxy or Kaana
|
|
337
|
+
* observation time. Lets a picker order models newest first.
|
|
338
|
+
*/
|
|
339
|
+
releasedAt: inferenceTimestampSchema.optional(),
|
|
340
|
+
regions: z.array(inferenceRegionSchema).default([]),
|
|
341
|
+
servingProviders: z.array(catalogueServingProviderSummarySchema).default([]),
|
|
342
|
+
dataPolicy: inferenceDataPolicySchema,
|
|
343
|
+
/** Absent for routes a customer cannot buy per-unit (BYOK-only, internal). */
|
|
344
|
+
pricing: priceSnapshotSchema.optional(),
|
|
345
|
+
/** Present only when every visible deployment shares one scope. */
|
|
346
|
+
availabilityScope: availabilityScopeSchema.optional(),
|
|
347
|
+
/** Present only when every visible deployment shares one permission basis. */
|
|
348
|
+
commercialPermission: commercialPermissionSchema.optional(),
|
|
349
|
+
deprecation: modelDeprecationSchema,
|
|
350
|
+
evaluations: z.array(modelEvaluationResultSchema).default([]),
|
|
351
|
+
safety: modelSafetyMetadataSchema.optional(),
|
|
352
|
+
modelCardUrl: inferenceHttpsUrlSchema.optional(),
|
|
353
|
+
/**
|
|
354
|
+
* The reviewed power class this model serves in, when one has been reviewed
|
|
355
|
+
* (contract set 3.4.0). Absent means the model is callable by name only and
|
|
356
|
+
* no power level chooses it.
|
|
357
|
+
*/
|
|
358
|
+
powerClass: modelPowerClassSchema.optional(),
|
|
359
|
+
});
|
|
360
|
+
/**
|
|
361
|
+
* One model as Kaana DECLARES it in `configs/public-catalogue.json` (Kaana ADR
|
|
362
|
+
* 0002, amendment 2026-10-15): the public `modelSchema` without the three
|
|
363
|
+
* fields Kaana fills from its inventory when it serves `GET /v1/models`
|
|
364
|
+
* (`schemaVersion`, `currentRevision`, `availableRevisions`), plus the audience
|
|
365
|
+
* allowed to see it.
|
|
366
|
+
*
|
|
367
|
+
* Strict on purpose. A declared model carries no serving provider, no
|
|
368
|
+
* availability scope and no commercial permission: those are properties of a
|
|
369
|
+
* route, decided by the signed inventory and by Oxy's grant, and a file that
|
|
370
|
+
* named them would publish an operator on the customer surface.
|
|
371
|
+
*/
|
|
372
|
+
export const declaredModelSchema = modelSchema
|
|
373
|
+
.omit({ schemaVersion: true, currentRevision: true, availableRevisions: true })
|
|
374
|
+
.extend({ audience: z.enum(['public', 'platform_internal']) })
|
|
375
|
+
.strict();
|
|
376
|
+
/**
|
|
377
|
+
* The declared catalogue: identity, publisher, licence, provenance, data
|
|
378
|
+
* policy, capabilities, voices and the LIST PRICE per unit of every model
|
|
379
|
+
* Kaana may serve. Kaana is its only source of truth. It is the file
|
|
380
|
+
* `configs/public-catalogue.json`, and the `declaredCatalogue` member of the
|
|
381
|
+
* signed `GET /internal/v1/models` response (contract set 4.3.0), from which
|
|
382
|
+
* Oxy reads the price it rates a grant at. New in contract set 4.3.0.
|
|
383
|
+
*/
|
|
384
|
+
export const declaredCatalogueSchema = z
|
|
385
|
+
.object({
|
|
386
|
+
schemaVersion: z.literal(1),
|
|
387
|
+
models: z.array(declaredModelSchema),
|
|
388
|
+
})
|
|
389
|
+
.strict();
|