@kaana.ai/contracts 0.0.0-stage → 4.3.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 (79) hide show
  1. package/LICENSE +673 -0
  2. package/NOTICE +21 -0
  3. package/dist/index.d.ts +29 -0
  4. package/dist/index.js +29 -0
  5. package/dist/internal/attribution.d.ts +116 -0
  6. package/dist/internal/attribution.js +82 -0
  7. package/dist/internal/canonical.d.ts +31 -0
  8. package/dist/internal/canonical.js +57 -0
  9. package/dist/internal/catalogue.d.ts +1030 -0
  10. package/dist/internal/catalogue.js +349 -0
  11. package/dist/internal/credentialControl.d.ts +329 -0
  12. package/dist/internal/credentialControl.js +256 -0
  13. package/dist/internal/decisions.d.ts +245 -0
  14. package/dist/internal/decisions.js +69 -0
  15. package/dist/internal/economics.d.ts +27 -0
  16. package/dist/internal/economics.js +26 -0
  17. package/dist/internal/embeddings.d.ts +164 -0
  18. package/dist/internal/embeddings.js +59 -0
  19. package/dist/internal/errors.d.ts +185 -0
  20. package/dist/internal/errors.js +211 -0
  21. package/dist/internal/grant.d.ts +696 -0
  22. package/dist/internal/grant.js +437 -0
  23. package/dist/internal/identifiers.d.ts +63 -0
  24. package/dist/internal/identifiers.js +65 -0
  25. package/dist/internal/privateAutoExecution.d.ts +158 -0
  26. package/dist/internal/privateAutoExecution.js +188 -0
  27. package/dist/internal/realtime.d.ts +1005 -0
  28. package/dist/internal/realtime.js +187 -0
  29. package/dist/internal/request.d.ts +1079 -0
  30. package/dist/internal/request.js +404 -0
  31. package/dist/internal/routing.d.ts +90 -0
  32. package/dist/internal/routing.js +139 -0
  33. package/dist/internal/scopedExecution.d.ts +74 -0
  34. package/dist/internal/scopedExecution.js +61 -0
  35. package/dist/internal/settlement.d.ts +205 -0
  36. package/dist/internal/settlement.js +71 -0
  37. package/dist/internal/streamEvents.d.ts +422 -0
  38. package/dist/internal/streamEvents.js +171 -0
  39. package/dist/internal/usage.d.ts +127 -0
  40. package/dist/internal/usage.js +109 -0
  41. package/dist/internal.d.ts +30 -0
  42. package/dist/internal.js +30 -0
  43. package/dist/public/audio.d.ts +347 -0
  44. package/dist/public/audio.js +236 -0
  45. package/dist/public/audioFormats.d.ts +64 -0
  46. package/dist/public/audioFormats.js +60 -0
  47. package/dist/public/catalogue.d.ts +914 -0
  48. package/dist/public/catalogue.js +516 -0
  49. package/dist/public/chatCompletions.d.ts +381 -0
  50. package/dist/public/chatCompletions.js +321 -0
  51. package/dist/public/decisions.d.ts +182 -0
  52. package/dist/public/decisions.js +257 -0
  53. package/dist/public/embeddings.d.ts +34 -0
  54. package/dist/public/embeddings.js +66 -0
  55. package/dist/public/errors.d.ts +195 -0
  56. package/dist/public/errors.js +274 -0
  57. package/dist/public/generations.d.ts +330 -0
  58. package/dist/public/generations.js +121 -0
  59. package/dist/public/identifiers.d.ts +139 -0
  60. package/dist/public/identifiers.js +160 -0
  61. package/dist/public/images.d.ts +36 -0
  62. package/dist/public/images.js +36 -0
  63. package/dist/public/messages.d.ts +297 -0
  64. package/dist/public/messages.js +251 -0
  65. package/dist/public/money.d.ts +308 -0
  66. package/dist/public/money.js +237 -0
  67. package/dist/public/policy.d.ts +19 -0
  68. package/dist/public/policy.js +20 -0
  69. package/dist/public/realtime.d.ts +2006 -0
  70. package/dist/public/realtime.js +797 -0
  71. package/dist/public/responses.d.ts +253 -0
  72. package/dist/public/responses.js +95 -0
  73. package/dist/public/streamEvents.d.ts +372 -0
  74. package/dist/public/streamEvents.js +157 -0
  75. package/dist/public/version.d.ts +177 -0
  76. package/dist/public/version.js +177 -0
  77. package/openapi.json +6967 -0
  78. package/package.json +44 -4
  79. package/README.md +0 -3
@@ -0,0 +1,256 @@
1
+ /**
2
+ * Signed customer-provider credential control (BYOK custody in Kaana).
3
+ *
4
+ * Moved from `@oxy.so/contracts` 4.12.0 (`src/inference/providerConnection.ts`) by Kaana ADR 0002.
5
+ * The Console connection records (`providerConnectionSchema` and its
6
+ * validation and custody metadata) stay in `@oxy.so/contracts`.
7
+ */
8
+ import { z } from 'zod';
9
+ import { inferenceEnvironmentSchema, oxyApplicationIdSchema, PADDED_BASE64_PATTERN, } from '../public/identifiers.js';
10
+ import { deploymentIdSchema, inferenceProviderSlugSchema } from './identifiers.js';
11
+ /** Opaque reference minted by Kaana. It is not a KMS/Vault/SSM locator. */
12
+ export const kaanaCredentialHandleSchema = z
13
+ .string()
14
+ .regex(/^kcred_[a-z2-7]{26}$/, 'a Kaana credential handle is kcred_ plus 26 base32 characters');
15
+ /** Oxy-minted, case-sensitive replay identity for one exact Kaana mutation. */
16
+ export const kaanaCredentialOperationIdSchema = z
17
+ .string()
18
+ .regex(/^[A-Za-z0-9_-]{1,128}$/, 'a Kaana credential operation id is 1-128 opaque characters');
19
+ export const kaanaCredentialOperationActionSchema = z.enum(['create', 'rotate', 'revoke']);
20
+ /** Exact immutable Oxy identity repeated by both mutation and reconciliation. */
21
+ export const kaanaCredentialIdentitySchema = z
22
+ .object({
23
+ provider: inferenceProviderSlugSchema,
24
+ ownerAccountId: z.string().regex(/^[A-Za-z0-9_-]{1,64}$/),
25
+ connectionId: z.string().regex(/^[A-Za-z0-9_-]{1,128}$/),
26
+ environment: inferenceEnvironmentSchema,
27
+ })
28
+ .strict();
29
+ const kaanaCredentialOperationActorSchema = z
30
+ .string()
31
+ .min(1)
32
+ .refine((value) => new TextEncoder().encode(value).byteLength <= 256 &&
33
+ value === value.trim() &&
34
+ !/[\r\n]/.test(value), {
35
+ message: 'a credential operation actor is one trimmed line of at most 256 bytes',
36
+ });
37
+ const base64Alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
38
+ /**
39
+ * Decode only enough of a strict base64 value to prove every output byte is
40
+ * visible ASCII. Keeping this implementation local avoids a Node Buffer or
41
+ * browser atob dependency in the universal contracts package.
42
+ */
43
+ function isVisibleASCIIProviderCredential(value) {
44
+ const padding = value.endsWith('==') ? 2 : value.endsWith('=') ? 1 : 0;
45
+ const decodedLength = (value.length / 4) * 3 - padding;
46
+ if (decodedLength < 1 || decodedLength > 4096)
47
+ return false;
48
+ for (let offset = 0, output = 0; offset < value.length; offset += 4, output += 3) {
49
+ const first = base64Alphabet.indexOf(value[offset] ?? '');
50
+ const second = base64Alphabet.indexOf(value[offset + 1] ?? '');
51
+ const third = value[offset + 2] === '=' ? 0 : base64Alphabet.indexOf(value[offset + 2] ?? '');
52
+ const fourth = value[offset + 3] === '=' ? 0 : base64Alphabet.indexOf(value[offset + 3] ?? '');
53
+ if (first < 0 || second < 0 || third < 0 || fourth < 0)
54
+ return false;
55
+ const finalQuartet = offset + 4 === value.length;
56
+ if (finalQuartet &&
57
+ ((padding === 2 && (second & 0x0f) !== 0) || (padding === 1 && (third & 0x03) !== 0))) {
58
+ return false;
59
+ }
60
+ const packed = (first << 18) | (second << 12) | (third << 6) | fourth;
61
+ const bytes = [(packed >> 16) & 0xff, (packed >> 8) & 0xff, packed & 0xff];
62
+ const count = Math.min(3, decodedLength - output);
63
+ for (let index = 0; index < count; index += 1) {
64
+ const byte = bytes[index];
65
+ if (byte === undefined || byte < 0x21 || byte > 0x7e)
66
+ return false;
67
+ }
68
+ }
69
+ return true;
70
+ }
71
+ const kaanaCredentialSecretBase64Schema = z
72
+ .string()
73
+ .min(1)
74
+ .max(8192)
75
+ .regex(PADDED_BASE64_PATTERN)
76
+ .refine(isVisibleASCIIProviderCredential, {
77
+ message: 'a decoded provider credential is 1-4096 visible ASCII bytes',
78
+ });
79
+ export const kaanaCredentialCreateMutationSchema = kaanaCredentialIdentitySchema
80
+ .extend({
81
+ schemaVersion: z.literal(1),
82
+ action: z.literal('create'),
83
+ operationId: kaanaCredentialOperationIdSchema,
84
+ operationActor: kaanaCredentialOperationActorSchema,
85
+ secretBase64: kaanaCredentialSecretBase64Schema,
86
+ })
87
+ .strict();
88
+ export const kaanaCredentialRotateMutationSchema = kaanaCredentialIdentitySchema
89
+ .extend({
90
+ schemaVersion: z.literal(1),
91
+ action: z.literal('rotate'),
92
+ operationId: kaanaCredentialOperationIdSchema,
93
+ operationActor: kaanaCredentialOperationActorSchema,
94
+ credentialHandle: kaanaCredentialHandleSchema,
95
+ expectedRevision: z
96
+ .number()
97
+ .int()
98
+ .positive()
99
+ .max(Number.MAX_SAFE_INTEGER - 1),
100
+ secretBase64: kaanaCredentialSecretBase64Schema,
101
+ })
102
+ .strict();
103
+ export const kaanaCredentialRevokeMutationSchema = kaanaCredentialIdentitySchema
104
+ .extend({
105
+ schemaVersion: z.literal(1),
106
+ action: z.literal('revoke'),
107
+ operationId: kaanaCredentialOperationIdSchema,
108
+ operationActor: kaanaCredentialOperationActorSchema,
109
+ credentialHandle: kaanaCredentialHandleSchema,
110
+ expectedRevision: z
111
+ .number()
112
+ .int()
113
+ .positive()
114
+ .max(Number.MAX_SAFE_INTEGER - 1),
115
+ })
116
+ .strict();
117
+ export const kaanaCredentialMutationSchema = z.discriminatedUnion('action', [
118
+ kaanaCredentialCreateMutationSchema,
119
+ kaanaCredentialRotateMutationSchema,
120
+ kaanaCredentialRevokeMutationSchema,
121
+ ]);
122
+ export const kaanaCredentialCreateOutcomeRequestSchema = kaanaCredentialIdentitySchema
123
+ .extend({
124
+ schemaVersion: z.literal(1),
125
+ action: z.literal('create'),
126
+ operationId: kaanaCredentialOperationIdSchema,
127
+ })
128
+ .strict();
129
+ export const kaanaCredentialRotateOutcomeRequestSchema = kaanaCredentialIdentitySchema
130
+ .extend({
131
+ schemaVersion: z.literal(1),
132
+ action: z.literal('rotate'),
133
+ operationId: kaanaCredentialOperationIdSchema,
134
+ credentialHandle: kaanaCredentialHandleSchema,
135
+ expectedRevision: z
136
+ .number()
137
+ .int()
138
+ .positive()
139
+ .max(Number.MAX_SAFE_INTEGER - 1),
140
+ })
141
+ .strict();
142
+ export const kaanaCredentialRevokeOutcomeRequestSchema = kaanaCredentialIdentitySchema
143
+ .extend({
144
+ schemaVersion: z.literal(1),
145
+ action: z.literal('revoke'),
146
+ operationId: kaanaCredentialOperationIdSchema,
147
+ credentialHandle: kaanaCredentialHandleSchema,
148
+ expectedRevision: z
149
+ .number()
150
+ .int()
151
+ .positive()
152
+ .max(Number.MAX_SAFE_INTEGER - 1),
153
+ })
154
+ .strict();
155
+ export const kaanaCredentialOutcomeRequestSchema = z.discriminatedUnion('action', [
156
+ kaanaCredentialCreateOutcomeRequestSchema,
157
+ kaanaCredentialRotateOutcomeRequestSchema,
158
+ kaanaCredentialRevokeOutcomeRequestSchema,
159
+ ]);
160
+ export const kaanaCredentialAppliedOutcomeSchema = z
161
+ .object({
162
+ schemaVersion: z.literal(1),
163
+ operationId: kaanaCredentialOperationIdSchema,
164
+ action: kaanaCredentialOperationActionSchema,
165
+ status: z.literal('applied'),
166
+ credentialHandle: kaanaCredentialHandleSchema,
167
+ revision: z.number().int().positive().safe(),
168
+ })
169
+ .strict();
170
+ export const kaanaCredentialConflictOutcomeSchema = z
171
+ .object({
172
+ schemaVersion: z.literal(1),
173
+ operationId: kaanaCredentialOperationIdSchema,
174
+ action: kaanaCredentialOperationActionSchema,
175
+ status: z.literal('conflict'),
176
+ })
177
+ .strict();
178
+ export const kaanaCredentialOutcomeSchema = z.discriminatedUnion('status', [
179
+ kaanaCredentialAppliedOutcomeSchema,
180
+ kaanaCredentialConflictOutcomeSchema,
181
+ ]);
182
+ /**
183
+ * One separately authenticated check of a quarantined BYOK generation.
184
+ *
185
+ * This is deliberately not an inference request. It carries no prompt, user
186
+ * response, routing policy or billing principal, and it can select only one
187
+ * exact Kaana deployment plus one exact credential generation.
188
+ */
189
+ export const kaanaCredentialValidationTaskSchema = kaanaCredentialIdentitySchema
190
+ .extend({
191
+ schemaVersion: z.literal(1),
192
+ operationId: kaanaCredentialOperationIdSchema,
193
+ applicationId: oxyApplicationIdSchema,
194
+ credentialHandle: kaanaCredentialHandleSchema,
195
+ credentialRevision: z.number().int().positive().safe(),
196
+ deploymentId: deploymentIdSchema,
197
+ })
198
+ .strict();
199
+ export const kaanaCredentialValidationOutcomeStateSchema = z.enum([
200
+ 'pending',
201
+ 'valid',
202
+ 'invalid',
203
+ 'inconclusive',
204
+ ]);
205
+ export const kaanaCredentialValidationFailureCodeSchema = z.enum([
206
+ 'unauthorized',
207
+ 'forbidden',
208
+ 'not_found',
209
+ 'rate_limited',
210
+ 'network',
211
+ 'unknown',
212
+ ]);
213
+ /**
214
+ * Durable result for one exact validation operation. `inconclusive` is a
215
+ * terminal answer about the attempt, never evidence that the credential is
216
+ * invalid; Oxy leaves the generation quarantined and may start a new exact
217
+ * operation. Kaana reports terminal outcomes through its service principal.
218
+ */
219
+ export const kaanaCredentialValidationOutcomeSchema = kaanaCredentialValidationTaskSchema
220
+ .extend({
221
+ state: kaanaCredentialValidationOutcomeStateSchema,
222
+ failureCode: kaanaCredentialValidationFailureCodeSchema.optional(),
223
+ })
224
+ .strict()
225
+ .superRefine((outcome, ctx) => {
226
+ if ((outcome.state === 'pending' || outcome.state === 'valid') &&
227
+ outcome.failureCode !== undefined) {
228
+ ctx.addIssue({
229
+ code: 'custom',
230
+ path: ['failureCode'],
231
+ message: 'a valid credential validation carries no failure code',
232
+ });
233
+ }
234
+ if ((outcome.state === 'invalid' || outcome.state === 'inconclusive') &&
235
+ outcome.failureCode === undefined) {
236
+ ctx.addIssue({
237
+ code: 'custom',
238
+ path: ['failureCode'],
239
+ message: 'a failed credential validation must state its closed failure code',
240
+ });
241
+ }
242
+ if (outcome.state === 'invalid' && outcome.failureCode !== 'unauthorized') {
243
+ ctx.addIssue({
244
+ code: 'custom',
245
+ path: ['failureCode'],
246
+ message: 'only a provider authentication refusal proves invalidity',
247
+ });
248
+ }
249
+ if (outcome.state === 'inconclusive' && outcome.failureCode === 'unauthorized') {
250
+ ctx.addIssue({
251
+ code: 'custom',
252
+ path: ['failureCode'],
253
+ message: 'an explicit authentication refusal is invalid, not inconclusive',
254
+ });
255
+ }
256
+ });
@@ -0,0 +1,245 @@
1
+ /**
2
+ * Kaana's typed decisions result and failure on the signed lane.
3
+ *
4
+ * Moved from `@oxy.so/contracts` 4.12.0 (`src/inference/decisions.ts`) by Kaana ADR 0002.
5
+ */
6
+ import { z } from 'zod';
7
+ export declare const decisionResultSchema: z.ZodObject<{
8
+ usage: z.ZodObject<{
9
+ schemaVersion: z.ZodLiteral<2>;
10
+ requestId: z.ZodString;
11
+ generationId: z.ZodOptional<z.ZodString>;
12
+ attribution: z.ZodObject<{
13
+ principal: z.ZodObject<{
14
+ billing: z.ZodObject<{
15
+ accountId: z.core.$ZodBranded<z.ZodString, "OxyAccountId", "out">;
16
+ }, z.core.$strict>;
17
+ applicationId: z.ZodString;
18
+ credentialId: z.ZodString;
19
+ environment: z.ZodEnum<{
20
+ development: "development";
21
+ staging: "staging";
22
+ production: "production";
23
+ }>;
24
+ inferenceScopes: z.ZodArray<z.ZodEnum<{
25
+ "inference:invoke": "inference:invoke";
26
+ "inference:models:read": "inference:models:read";
27
+ "inference:usage:read": "inference:usage:read";
28
+ "inference:routing:read": "inference:routing:read";
29
+ "inference:routing:write": "inference:routing:write";
30
+ "inference:providers:read": "inference:providers:read";
31
+ "inference:providers:write": "inference:providers:write";
32
+ }>>;
33
+ }, z.core.$strip>;
34
+ userId: z.ZodOptional<z.core.$ZodBranded<z.ZodString, "DelegatedUserId", "out">>;
35
+ requestId: z.ZodString;
36
+ generationId: z.ZodOptional<z.ZodString>;
37
+ }, z.core.$strip>;
38
+ outcome: z.ZodEnum<{
39
+ cancelled: "cancelled";
40
+ completed: "completed";
41
+ partial: "partial";
42
+ failed: "failed";
43
+ }>;
44
+ units: z.ZodArray<z.ZodObject<{
45
+ unit: z.ZodEnum<{
46
+ input_tokens: "input_tokens";
47
+ cached_input_tokens: "cached_input_tokens";
48
+ output_tokens: "output_tokens";
49
+ reasoning_tokens: "reasoning_tokens";
50
+ requests: "requests";
51
+ images: "images";
52
+ audio_input_milliseconds: "audio_input_milliseconds";
53
+ audio_output_milliseconds: "audio_output_milliseconds";
54
+ video_milliseconds: "video_milliseconds";
55
+ characters: "characters";
56
+ embeddings: "embeddings";
57
+ audio_input_tokens: "audio_input_tokens";
58
+ cached_audio_input_tokens: "cached_audio_input_tokens";
59
+ audio_output_tokens: "audio_output_tokens";
60
+ session_milliseconds: "session_milliseconds";
61
+ input_transcription_milliseconds: "input_transcription_milliseconds";
62
+ }>;
63
+ quantity: z.ZodNumber;
64
+ }, z.core.$strict>>;
65
+ usageSource: z.ZodEnum<{
66
+ provider_reported: "provider_reported";
67
+ oxy_measured: "oxy_measured";
68
+ estimated: "estimated";
69
+ }>;
70
+ resolvedModelReference: z.ZodString;
71
+ servingProvider: z.ZodString;
72
+ deploymentId: z.ZodString;
73
+ routeSwitches: z.ZodNumber;
74
+ fundingTier: z.ZodOptional<z.ZodEnum<{
75
+ free: "free";
76
+ credit: "credit";
77
+ paid: "paid";
78
+ }>>;
79
+ startedAt: z.ZodString;
80
+ completedAt: z.ZodString;
81
+ timeToFirstTokenMs: z.ZodOptional<z.ZodNumber>;
82
+ }, z.core.$strip>;
83
+ schemaVersion: z.ZodLiteral<1>;
84
+ requestId: z.ZodString;
85
+ model: z.ZodString;
86
+ data: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
87
+ id: z.ZodString;
88
+ kind: z.ZodLiteral<"choice">;
89
+ reply: z.ZodString;
90
+ confidence: z.ZodNumber;
91
+ probabilities: z.ZodArray<z.ZodNumber>;
92
+ }, z.core.$strict>, z.ZodObject<{
93
+ id: z.ZodString;
94
+ kind: z.ZodLiteral<"score">;
95
+ reply: z.ZodNumber;
96
+ confidence: z.ZodNumber;
97
+ mean: z.ZodNumber;
98
+ distribution: z.ZodArray<z.ZodNumber>;
99
+ }, z.core.$strict>, z.ZodObject<{
100
+ id: z.ZodString;
101
+ kind: z.ZodLiteral<"noul">;
102
+ probability: z.ZodNumber;
103
+ }, z.core.$strict>], "kind">>;
104
+ }, z.core.$strict>;
105
+ /**
106
+ * Kaana's typed decisions failure. `usage` is present only when the provider
107
+ * measured something before failing; its absence means nothing was measured,
108
+ * never that the cost was zero. A failure carrying usage did execute.
109
+ */
110
+ export declare const decisionFailureSchema: z.ZodObject<{
111
+ schemaVersion: z.ZodLiteral<1>;
112
+ requestId: z.ZodString;
113
+ error: z.ZodObject<{
114
+ schemaVersion: z.ZodLiteral<1>;
115
+ code: z.ZodEnum<{
116
+ invalid_request: "invalid_request";
117
+ authentication_failed: "authentication_failed";
118
+ permission_denied: "permission_denied";
119
+ insufficient_scope: "insufficient_scope";
120
+ model_not_found: "model_not_found";
121
+ unsupported_modality: "unsupported_modality";
122
+ context_length_exceeded: "context_length_exceeded";
123
+ request_too_large: "request_too_large";
124
+ output_limit_exceeded: "output_limit_exceeded";
125
+ idempotency_conflict: "idempotency_conflict";
126
+ insufficient_balance: "insufficient_balance";
127
+ spending_limit_exceeded: "spending_limit_exceeded";
128
+ quota_exceeded: "quota_exceeded";
129
+ byok_credential_invalid: "byok_credential_invalid";
130
+ policy_violation: "policy_violation";
131
+ commercial_permission_denied: "commercial_permission_denied";
132
+ no_route_available: "no_route_available";
133
+ upstream_content_filtered: "upstream_content_filtered";
134
+ cancelled: "cancelled";
135
+ rate_limited: "rate_limited";
136
+ provider_error: "provider_error";
137
+ provider_timeout: "provider_timeout";
138
+ provider_overloaded: "provider_overloaded";
139
+ service_unavailable: "service_unavailable";
140
+ internal_error: "internal_error";
141
+ deployment_unavailable: "deployment_unavailable";
142
+ provider_credential_invalid: "provider_credential_invalid";
143
+ provider_billing_refused: "provider_billing_refused";
144
+ }>;
145
+ message: z.ZodString;
146
+ retryable: z.ZodBoolean;
147
+ requestId: z.ZodString;
148
+ retryAfterMs: z.ZodOptional<z.ZodNumber>;
149
+ param: z.ZodOptional<z.ZodString>;
150
+ upstreamCategory: z.ZodOptional<z.ZodEnum<{
151
+ rate_limit: "rate_limit";
152
+ quota: "quota";
153
+ timeout: "timeout";
154
+ overloaded: "overloaded";
155
+ server_error: "server_error";
156
+ content_filter: "content_filter";
157
+ invalid_request: "invalid_request";
158
+ authentication: "authentication";
159
+ unknown: "unknown";
160
+ }>>;
161
+ providerError: z.ZodOptional<z.ZodObject<{
162
+ provider: z.ZodString;
163
+ status: z.ZodOptional<z.ZodNumber>;
164
+ code: z.ZodOptional<z.ZodString>;
165
+ message: z.ZodOptional<z.ZodString>;
166
+ }, z.core.$strict>>;
167
+ }, z.core.$strip>;
168
+ usage: z.ZodOptional<z.ZodObject<{
169
+ schemaVersion: z.ZodLiteral<2>;
170
+ requestId: z.ZodString;
171
+ generationId: z.ZodOptional<z.ZodString>;
172
+ attribution: z.ZodObject<{
173
+ principal: z.ZodObject<{
174
+ billing: z.ZodObject<{
175
+ accountId: z.core.$ZodBranded<z.ZodString, "OxyAccountId", "out">;
176
+ }, z.core.$strict>;
177
+ applicationId: z.ZodString;
178
+ credentialId: z.ZodString;
179
+ environment: z.ZodEnum<{
180
+ development: "development";
181
+ staging: "staging";
182
+ production: "production";
183
+ }>;
184
+ inferenceScopes: z.ZodArray<z.ZodEnum<{
185
+ "inference:invoke": "inference:invoke";
186
+ "inference:models:read": "inference:models:read";
187
+ "inference:usage:read": "inference:usage:read";
188
+ "inference:routing:read": "inference:routing:read";
189
+ "inference:routing:write": "inference:routing:write";
190
+ "inference:providers:read": "inference:providers:read";
191
+ "inference:providers:write": "inference:providers:write";
192
+ }>>;
193
+ }, z.core.$strip>;
194
+ userId: z.ZodOptional<z.core.$ZodBranded<z.ZodString, "DelegatedUserId", "out">>;
195
+ requestId: z.ZodString;
196
+ generationId: z.ZodOptional<z.ZodString>;
197
+ }, z.core.$strip>;
198
+ outcome: z.ZodEnum<{
199
+ cancelled: "cancelled";
200
+ completed: "completed";
201
+ partial: "partial";
202
+ failed: "failed";
203
+ }>;
204
+ units: z.ZodArray<z.ZodObject<{
205
+ unit: z.ZodEnum<{
206
+ input_tokens: "input_tokens";
207
+ cached_input_tokens: "cached_input_tokens";
208
+ output_tokens: "output_tokens";
209
+ reasoning_tokens: "reasoning_tokens";
210
+ requests: "requests";
211
+ images: "images";
212
+ audio_input_milliseconds: "audio_input_milliseconds";
213
+ audio_output_milliseconds: "audio_output_milliseconds";
214
+ video_milliseconds: "video_milliseconds";
215
+ characters: "characters";
216
+ embeddings: "embeddings";
217
+ audio_input_tokens: "audio_input_tokens";
218
+ cached_audio_input_tokens: "cached_audio_input_tokens";
219
+ audio_output_tokens: "audio_output_tokens";
220
+ session_milliseconds: "session_milliseconds";
221
+ input_transcription_milliseconds: "input_transcription_milliseconds";
222
+ }>;
223
+ quantity: z.ZodNumber;
224
+ }, z.core.$strict>>;
225
+ usageSource: z.ZodEnum<{
226
+ provider_reported: "provider_reported";
227
+ oxy_measured: "oxy_measured";
228
+ estimated: "estimated";
229
+ }>;
230
+ resolvedModelReference: z.ZodString;
231
+ servingProvider: z.ZodString;
232
+ deploymentId: z.ZodString;
233
+ routeSwitches: z.ZodNumber;
234
+ fundingTier: z.ZodOptional<z.ZodEnum<{
235
+ free: "free";
236
+ credit: "credit";
237
+ paid: "paid";
238
+ }>>;
239
+ startedAt: z.ZodString;
240
+ completedAt: z.ZodString;
241
+ timeToFirstTokenMs: z.ZodOptional<z.ZodNumber>;
242
+ }, z.core.$strip>>;
243
+ }, z.core.$strict>;
244
+ export type DecisionResult = z.infer<typeof decisionResultSchema>;
245
+ export type DecisionFailure = z.infer<typeof decisionFailureSchema>;
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Kaana's typed decisions result and failure on the signed lane.
3
+ *
4
+ * Moved from `@oxy.so/contracts` 4.12.0 (`src/inference/decisions.ts`) by Kaana ADR 0002.
5
+ */
6
+ import { z } from 'zod';
7
+ import { decisionAnswerSchema } from '../public/decisions.js';
8
+ import { modelReferenceSchema, requestIdSchema } from '../public/identifiers.js';
9
+ import { inferenceErrorSchema } from './errors.js';
10
+ import { normalizedUsageReportSchema } from './usage.js';
11
+ const resultFields = {
12
+ schemaVersion: z.literal(1),
13
+ requestId: requestIdSchema,
14
+ model: modelReferenceSchema.refine((model) => model.includes('@'), 'Decisions require an immutable model revision.'),
15
+ data: z.array(decisionAnswerSchema).min(1).max(255),
16
+ };
17
+ function uniqueAnswers(result, ctx) {
18
+ if (new Set(result.data.map((answer) => answer.id)).size !== result.data.length)
19
+ ctx.addIssue({
20
+ code: 'custom',
21
+ path: ['data'],
22
+ message: 'Answer IDs must be unique.',
23
+ });
24
+ }
25
+ export const decisionResultSchema = z
26
+ .object({ ...resultFields, usage: normalizedUsageReportSchema })
27
+ .strict()
28
+ .superRefine(uniqueAnswers)
29
+ .superRefine((result, ctx) => {
30
+ if (result.usage.requestId !== result.requestId ||
31
+ result.usage.resolvedModelReference !== result.model ||
32
+ result.usage.outcome !== 'completed') {
33
+ ctx.addIssue({
34
+ code: 'custom',
35
+ path: ['usage'],
36
+ message: 'Decision usage must describe this completed request and immutable model.',
37
+ });
38
+ }
39
+ });
40
+ /**
41
+ * Kaana's typed decisions failure. `usage` is present only when the provider
42
+ * measured something before failing; its absence means nothing was measured,
43
+ * never that the cost was zero. A failure carrying usage did execute.
44
+ */
45
+ export const decisionFailureSchema = z
46
+ .object({
47
+ schemaVersion: z.literal(1),
48
+ requestId: requestIdSchema,
49
+ error: inferenceErrorSchema,
50
+ usage: normalizedUsageReportSchema.optional(),
51
+ })
52
+ .strict()
53
+ .superRefine((failure, ctx) => {
54
+ if (failure.error.requestId !== failure.requestId) {
55
+ ctx.addIssue({
56
+ code: 'custom',
57
+ path: ['error', 'requestId'],
58
+ message: 'The error must answer this request.',
59
+ });
60
+ }
61
+ if (failure.usage !== undefined &&
62
+ (failure.usage.requestId !== failure.requestId || failure.usage.outcome === 'completed')) {
63
+ ctx.addIssue({
64
+ code: 'custom',
65
+ path: ['usage'],
66
+ message: 'Failure usage must describe this request and an incomplete outcome.',
67
+ });
68
+ }
69
+ });
@@ -0,0 +1,27 @@
1
+ /**
2
+ * How a grant is treated economically.
3
+ *
4
+ * The treatment is decided by Oxy from the AUTHENTICATED application, its
5
+ * environment and lane, against a versioned policy; nothing a caller sends can
6
+ * select it, so it appears only on the signed grant, never on a public request.
7
+ *
8
+ * Moved from `@oxy.so/contracts` 4.12.0 (`src/inference/economics.ts`) by Kaana
9
+ * ADR 0002, which adds `platform_fee_only` (decision 4: a BYOK request, billed
10
+ * by the provider to the customer, on which Oxy charges only its fee; until now
11
+ * a receipt flag). Cost-centre usage and the metered generation read model stay
12
+ * in `@oxy.so/contracts`.
13
+ */
14
+ import { z } from 'zod';
15
+ /**
16
+ * - `commercial` — the default: reserve, settle, refund.
17
+ * - `internal_metered` — a product relationship Oxy configured (Alia on Kaana,
18
+ * the Jev classifier): no hold and no receipt, usage still recorded.
19
+ * - `platform_fee_only` — BYOK: the provider bills the customer's own account.
20
+ */
21
+ export declare const INFERENCE_ECONOMIC_TREATMENTS: readonly ["commercial", "internal_metered", "platform_fee_only"];
22
+ export declare const inferenceEconomicTreatmentSchema: z.ZodEnum<{
23
+ commercial: "commercial";
24
+ internal_metered: "internal_metered";
25
+ platform_fee_only: "platform_fee_only";
26
+ }>;
27
+ export type InferenceEconomicTreatment = z.infer<typeof inferenceEconomicTreatmentSchema>;
@@ -0,0 +1,26 @@
1
+ /**
2
+ * How a grant is treated economically.
3
+ *
4
+ * The treatment is decided by Oxy from the AUTHENTICATED application, its
5
+ * environment and lane, against a versioned policy; nothing a caller sends can
6
+ * select it, so it appears only on the signed grant, never on a public request.
7
+ *
8
+ * Moved from `@oxy.so/contracts` 4.12.0 (`src/inference/economics.ts`) by Kaana
9
+ * ADR 0002, which adds `platform_fee_only` (decision 4: a BYOK request, billed
10
+ * by the provider to the customer, on which Oxy charges only its fee; until now
11
+ * a receipt flag). Cost-centre usage and the metered generation read model stay
12
+ * in `@oxy.so/contracts`.
13
+ */
14
+ import { z } from 'zod';
15
+ /**
16
+ * - `commercial` — the default: reserve, settle, refund.
17
+ * - `internal_metered` — a product relationship Oxy configured (Alia on Kaana,
18
+ * the Jev classifier): no hold and no receipt, usage still recorded.
19
+ * - `platform_fee_only` — BYOK: the provider bills the customer's own account.
20
+ */
21
+ export const INFERENCE_ECONOMIC_TREATMENTS = [
22
+ 'commercial',
23
+ 'internal_metered',
24
+ 'platform_fee_only',
25
+ ];
26
+ export const inferenceEconomicTreatmentSchema = z.enum(INFERENCE_ECONOMIC_TREATMENTS);