@kaana.ai/contracts 8.10.0 → 8.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -26,6 +26,7 @@ export * from './public/money.js';
26
26
  export * from './public/policy.js';
27
27
  export * from './public/providerPreferences.js';
28
28
  export * from './public/realtime.js';
29
+ export * from './public/rerank.js';
29
30
  export * from './public/responses.js';
30
31
  export * from './public/streamEvents.js';
31
32
  export * from './public/version.js';
package/dist/index.js CHANGED
@@ -26,6 +26,7 @@ export * from './public/money.js';
26
26
  export * from './public/policy.js';
27
27
  export * from './public/providerPreferences.js';
28
28
  export * from './public/realtime.js';
29
+ export * from './public/rerank.js';
29
30
  export * from './public/responses.js';
30
31
  export * from './public/streamEvents.js';
31
32
  export * from './public/version.js';
@@ -314,10 +314,10 @@ export declare const routingProfileSchema: z.ZodObject<{
314
314
  displayName: z.ZodString;
315
315
  description: z.ZodOptional<z.ZodString>;
316
316
  optimiseFor: z.ZodEnum<{
317
+ quality: "quality";
317
318
  price: "price";
318
319
  latency: "latency";
319
320
  throughput: "throughput";
320
- quality: "quality";
321
321
  balanced: "balanced";
322
322
  }>;
323
323
  candidates: z.ZodArray<z.ZodObject<{
@@ -40,6 +40,7 @@ export declare const grantOperationSchema: z.ZodEnum<{
40
40
  images_generations: "images_generations";
41
41
  audio_transcriptions: "audio_transcriptions";
42
42
  audio_speech: "audio_speech";
43
+ rerank: "rerank";
43
44
  realtime_session: "realtime_session";
44
45
  }>;
45
46
  /**
@@ -101,6 +102,7 @@ export declare const inferenceAuthorizationRequestSchema: z.ZodObject<{
101
102
  images_generations: "images_generations";
102
103
  audio_transcriptions: "audio_transcriptions";
103
104
  audio_speech: "audio_speech";
105
+ rerank: "rerank";
104
106
  realtime_session: "realtime_session";
105
107
  }>;
106
108
  target: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -181,6 +183,7 @@ export declare const authorizationRequestSchema: z.ZodDiscriminatedUnion<[z.ZodO
181
183
  images_generations: "images_generations";
182
184
  audio_transcriptions: "audio_transcriptions";
183
185
  audio_speech: "audio_speech";
186
+ rerank: "rerank";
184
187
  realtime_session: "realtime_session";
185
188
  }>;
186
189
  target: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -383,6 +386,7 @@ export declare const grantSchema: z.ZodObject<{
383
386
  images_generations: "images_generations";
384
387
  audio_transcriptions: "audio_transcriptions";
385
388
  audio_speech: "audio_speech";
389
+ rerank: "rerank";
386
390
  realtime_session: "realtime_session";
387
391
  }>;
388
392
  issuedAt: z.ZodString;
@@ -65,6 +65,7 @@ export const grantOperationSchema = z.enum([
65
65
  'images_generations',
66
66
  'decisions',
67
67
  'realtime_session',
68
+ 'rerank',
68
69
  ]);
69
70
  /**
70
71
  * What the caller asked to be served: a model line, optionally pinned to a
@@ -341,6 +341,16 @@ export declare const inferenceRequestSchema: z.ZodObject<{
341
341
  }>;
342
342
  speed: z.ZodOptional<z.ZodNumber>;
343
343
  }, z.core.$strict>>;
344
+ image: z.ZodOptional<z.ZodObject<{
345
+ n: z.ZodOptional<z.ZodNumber>;
346
+ size: z.ZodOptional<z.ZodString>;
347
+ quality: z.ZodOptional<z.ZodString>;
348
+ style: z.ZodOptional<z.ZodString>;
349
+ responseFormat: z.ZodOptional<z.ZodEnum<{
350
+ url: "url";
351
+ b64_json: "b64_json";
352
+ }>>;
353
+ }, z.core.$strict>>;
344
354
  transcription: z.ZodOptional<z.ZodObject<{
345
355
  language: z.ZodOptional<z.ZodString>;
346
356
  prompt: z.ZodOptional<z.ZodString>;
@@ -8,7 +8,7 @@ import { maxUtf16Length, minUtf16Length } from '../stringBounds.js';
8
8
  import { inferenceApiFormatSchema, inferenceModalitySchema } from '../public/catalogue.js';
9
9
  import { decisionInputSchema } from '../public/decisions.js';
10
10
  import { idempotencyKeySchema, inferenceTimestampSchema } from '../public/identifiers.js';
11
- import { inferenceAudioOutputParametersSchema, inferenceMessageSchema, inferenceReasoningSchema, inferenceSpeechParametersSchema, inferenceTranscriptionParametersSchema, responseFormatSchema, samplingParametersSchema, toolChoiceSchema, toolDefinitionSchema, } from '../public/messages.js';
11
+ import { inferenceAudioOutputParametersSchema, inferenceMessageSchema, inferenceReasoningSchema, inferenceImageParametersSchema, inferenceSpeechParametersSchema, inferenceTranscriptionParametersSchema, responseFormatSchema, samplingParametersSchema, toolChoiceSchema, toolDefinitionSchema, } from '../public/messages.js';
12
12
  import { routingPolicyReferenceSchema } from '../public/policy.js';
13
13
  import { inferenceAttributionSchema } from './attribution.js';
14
14
  import { authorizedRouteSchema, routingTargetSchema } from './routing.js';
@@ -93,6 +93,8 @@ const inferenceRequestObjectSchema = z.object({
93
93
  /** Absent means the route's own default reasoning behaviour. */
94
94
  reasoning: inferenceReasoningSchema.optional(),
95
95
  speech: inferenceSpeechParametersSchema.optional(),
96
+ /** Text-to-image controls. Contract set 8.12.0. */
97
+ image: inferenceImageParametersSchema.optional(),
96
98
  /** File transcription parameters. Contract set 4.5.0. */
97
99
  transcription: inferenceTranscriptionParametersSchema.optional(),
98
100
  /** Spoken output from a conversational model. Contract set 3.2.0. */
@@ -168,6 +170,7 @@ export const inferenceRequestSchema = inferenceRequestObjectSchema.superRefine((
168
170
  request.responseFormat !== undefined ||
169
171
  request.reasoning !== undefined ||
170
172
  request.speech !== undefined ||
173
+ request.image !== undefined ||
171
174
  request.transcription !== undefined ||
172
175
  request.audioOutput !== undefined) {
173
176
  ctx.addIssue({
@@ -196,6 +199,16 @@ export const inferenceRequestSchema = inferenceRequestObjectSchema.superRefine((
196
199
  message: 'speech parameters require the audio_speech API format',
197
200
  });
198
201
  }
202
+ if (request.image !== undefined &&
203
+ (request.client.apiFormat !== 'images_generations' ||
204
+ request.modality !== 'image' ||
205
+ request.input.format !== 'text')) {
206
+ ctx.addIssue({
207
+ code: 'custom',
208
+ path: ['image'],
209
+ message: 'image parameters require the images_generations API format with image modality and text input',
210
+ });
211
+ }
199
212
  if (request.transcription !== undefined &&
200
213
  (request.client.apiFormat !== 'audio_transcriptions' ||
201
214
  request.modality !== 'audio' ||
@@ -343,6 +343,24 @@ export declare const inferenceSpeechParametersSchema: z.ZodObject<{
343
343
  }>;
344
344
  speed: z.ZodOptional<z.ZodNumber>;
345
345
  }, z.core.$strict>;
346
+ /**
347
+ * Parameters for text-to-image (contract set 8.12.0), preserved in the request.
348
+ * Each is the caller's own control, forwarded as named: an adapter whose
349
+ * provider takes none of them refuses the request rather than dropping it.
350
+ * `n` is how many images; `size`, `quality` and `style` are the provider's own
351
+ * vocabulary (each size/quality class is its own model reference in the
352
+ * catalogue, so none of them widens a hold).
353
+ */
354
+ export declare const inferenceImageParametersSchema: z.ZodObject<{
355
+ n: z.ZodOptional<z.ZodNumber>;
356
+ size: z.ZodOptional<z.ZodString>;
357
+ quality: z.ZodOptional<z.ZodString>;
358
+ style: z.ZodOptional<z.ZodString>;
359
+ responseFormat: z.ZodOptional<z.ZodEnum<{
360
+ url: "url";
361
+ b64_json: "b64_json";
362
+ }>>;
363
+ }, z.core.$strict>;
346
364
  /**
347
365
  * Parameters for a file transcription, preserved in the signed request
348
366
  * (contract set 4.5.0). `language` is the caller's statement of what is spoken,
@@ -386,6 +404,7 @@ export declare const inferenceAudioOutputParametersSchema: z.ZodObject<{
386
404
  * Moved from the Oxy edge (`packages/api/src/schemas/inferenceEdge.schemas.ts`).
387
405
  */
388
406
  export declare const requestLabelsSchema: z.ZodRecord<z.ZodString, z.ZodString>;
407
+ export type InferenceImageParameters = z.infer<typeof inferenceImageParametersSchema>;
389
408
  export type InferenceSpeechParameters = z.infer<typeof inferenceSpeechParametersSchema>;
390
409
  export type InferenceTranscriptionParameters = z.infer<typeof inferenceTranscriptionParametersSchema>;
391
410
  export type InferenceAudioOutputParameters = z.infer<typeof inferenceAudioOutputParametersSchema>;
@@ -412,6 +412,23 @@ export const inferenceSpeechParametersSchema = z
412
412
  speed: z.number().min(0.25).max(4).optional(),
413
413
  })
414
414
  .strict();
415
+ /**
416
+ * Parameters for text-to-image (contract set 8.12.0), preserved in the request.
417
+ * Each is the caller's own control, forwarded as named: an adapter whose
418
+ * provider takes none of them refuses the request rather than dropping it.
419
+ * `n` is how many images; `size`, `quality` and `style` are the provider's own
420
+ * vocabulary (each size/quality class is its own model reference in the
421
+ * catalogue, so none of them widens a hold).
422
+ */
423
+ export const inferenceImageParametersSchema = z
424
+ .object({
425
+ n: z.number().int().min(1).max(10).optional(),
426
+ size: z.string().check(minUtf16Length(1)).check(maxUtf16Length(32)).optional(),
427
+ quality: z.string().check(minUtf16Length(1)).check(maxUtf16Length(32)).optional(),
428
+ style: z.string().check(minUtf16Length(1)).check(maxUtf16Length(32)).optional(),
429
+ responseFormat: z.enum(['url', 'b64_json']).optional(),
430
+ })
431
+ .strict();
415
432
  /**
416
433
  * Parameters for a file transcription, preserved in the signed request
417
434
  * (contract set 4.5.0). `language` is the caller's statement of what is spoken,
@@ -0,0 +1,38 @@
1
+ /**
2
+ * `POST /v1/rerank` — rank documents by relevance to a query.
3
+ *
4
+ * New in contract set 8.11.0, CONTRACT ONLY: these shapes and the `rerank` grant
5
+ * operation are declared so Oxy can support the operation before Kaana serves
6
+ * it. Kaana does not serve the route yet and emits no `rerank` operation.
7
+ *
8
+ * Version 1 takes string documents only. The response carries a relevance score
9
+ * per document and the token usage; it never carries an amount.
10
+ */
11
+ import { z } from 'zod';
12
+ /** The most documents one rerank request may carry. */
13
+ export declare const MAX_RERANK_DOCUMENTS = 1000;
14
+ export declare const rerankRequestSchema: z.ZodObject<{
15
+ model: z.ZodString;
16
+ query: z.ZodString;
17
+ documents: z.ZodArray<z.ZodString>;
18
+ top_n: z.ZodOptional<z.ZodNumber>;
19
+ return_documents: z.ZodOptional<z.ZodBoolean>;
20
+ user: z.ZodOptional<z.ZodString>;
21
+ }, z.core.$strict>;
22
+ export declare const rerankResponseSchema: z.ZodObject<{
23
+ id: z.ZodString;
24
+ model: z.ZodString;
25
+ results: z.ZodArray<z.ZodObject<{
26
+ index: z.ZodNumber;
27
+ relevance_score: z.ZodNumber;
28
+ document: z.ZodOptional<z.ZodObject<{
29
+ text: z.ZodString;
30
+ }, z.core.$strict>>;
31
+ }, z.core.$strict>>;
32
+ usage: z.ZodObject<{
33
+ prompt_tokens: z.ZodNumber;
34
+ total_tokens: z.ZodNumber;
35
+ }, z.core.$strict>;
36
+ }, z.core.$strict>;
37
+ export type RerankRequest = z.infer<typeof rerankRequestSchema>;
38
+ export type RerankResponse = z.infer<typeof rerankResponseSchema>;
@@ -0,0 +1,63 @@
1
+ /**
2
+ * `POST /v1/rerank` — rank documents by relevance to a query.
3
+ *
4
+ * New in contract set 8.11.0, CONTRACT ONLY: these shapes and the `rerank` grant
5
+ * operation are declared so Oxy can support the operation before Kaana serves
6
+ * it. Kaana does not serve the route yet and emits no `rerank` operation.
7
+ *
8
+ * Version 1 takes string documents only. The response carries a relevance score
9
+ * per document and the token usage; it never carries an amount.
10
+ */
11
+ import { z } from 'zod';
12
+ import { maxUtf16Length, minUtf16Length } from '../stringBounds.js';
13
+ import { generationIdSchema, modelReferenceSchema } from './identifiers.js';
14
+ /** The most documents one rerank request may carry. */
15
+ export const MAX_RERANK_DOCUMENTS = 1000;
16
+ export const rerankRequestSchema = z
17
+ .object({
18
+ /** `publisher/model` or `publisher/model@revision`. */
19
+ model: modelReferenceSchema,
20
+ query: z.string().check(minUtf16Length(1)),
21
+ /** String documents only. */
22
+ documents: z
23
+ .array(z.string().check(minUtf16Length(1)))
24
+ .min(1)
25
+ .max(MAX_RERANK_DOCUMENTS),
26
+ /** How many of the most relevant documents to return; all when absent. */
27
+ top_n: z.number().int().min(1).optional(),
28
+ /** Echo each ranked document's text in its result. */
29
+ return_documents: z.boolean().optional(),
30
+ /** The delegated end-user id, attribution only (as on `/v1/embeddings`). */
31
+ user: z.string().check(minUtf16Length(1)).check(maxUtf16Length(64)).optional(),
32
+ })
33
+ .strict();
34
+ export const rerankResponseSchema = z
35
+ .object({
36
+ id: generationIdSchema,
37
+ /** The revision that produced the scores. */
38
+ model: modelReferenceSchema,
39
+ /** Most relevant first. */
40
+ results: z
41
+ .array(z
42
+ .object({
43
+ /** The position of the document in the request's `documents`. */
44
+ index: z.number().int().nonnegative(),
45
+ relevance_score: z.number(),
46
+ document: z.object({ text: z.string() }).strict().optional(),
47
+ })
48
+ .strict())
49
+ .max(MAX_RERANK_DOCUMENTS),
50
+ usage: z
51
+ .object({
52
+ prompt_tokens: z.number().int().nonnegative(),
53
+ total_tokens: z.number().int().nonnegative(),
54
+ })
55
+ .strict(),
56
+ })
57
+ .strict()
58
+ .superRefine((response, ctx) => {
59
+ const indexes = response.results.map((result) => result.index);
60
+ if (new Set(indexes).size !== indexes.length) {
61
+ ctx.addIssue({ code: 'custom', path: ['results'], message: 'result indexes must be unique' });
62
+ }
63
+ });
@@ -100,7 +100,7 @@
100
100
  * change to, say, the catalogue reject every in-flight inference request; the
101
101
  * per-shape `schemaVersion` is what a message is validated against.
102
102
  */
103
- export declare const INFERENCE_CONTRACT_VERSION = "8.10.0";
103
+ export declare const INFERENCE_CONTRACT_VERSION = "8.12.0";
104
104
  /**
105
105
  * Contract set 4.0.0 (Kaana ADR 0002) is the first published as
106
106
  * `@kaana.ai/contracts`. MAJOR because the set changed hands and split in two:
@@ -236,6 +236,18 @@ export declare const INFERENCE_CONTRACT_VERSION = "8.10.0";
236
236
  * Both read the declared list price of a model line, in USD per million tokens.
237
237
  * Public request members only: the signed grant and envelope are unchanged and
238
238
  * no response carries an amount.
239
+ *
240
+ * Contract set 8.11.0 is additive and CONTRACT ONLY: the `rerank` grant
241
+ * operation (`grantOperationSchema`, last member) and the public `POST /v1/rerank`
242
+ * shapes (`rerankRequestSchema`, `rerankResponseSchema`). Kaana emits no `rerank`
243
+ * operation and serves no route yet; Oxy supports the operation first.
244
+ *
245
+ * Contract set 8.12.0 is additive: the signed envelope's optional `image`
246
+ * member (`inferenceImageParametersSchema`: `n`, `size`, `quality`, `style`,
247
+ * `responseFormat`), which carries a text-to-image request's controls to the
248
+ * adapter instead of dropping them. It is valid only with the
249
+ * `images_generations` API format, image modality and text input. Nothing in
250
+ * 8.11.0 changes and the public request and response shapes are unchanged.
239
251
  */
240
252
  /** The public API's one origin and version. */
241
253
  export declare const KAANA_API_BASE_URL = "https://kaana.ai/v1";
@@ -100,7 +100,7 @@
100
100
  * change to, say, the catalogue reject every in-flight inference request; the
101
101
  * per-shape `schemaVersion` is what a message is validated against.
102
102
  */
103
- export const INFERENCE_CONTRACT_VERSION = '8.10.0';
103
+ export const INFERENCE_CONTRACT_VERSION = '8.12.0';
104
104
  /**
105
105
  * Contract set 4.0.0 (Kaana ADR 0002) is the first published as
106
106
  * `@kaana.ai/contracts`. MAJOR because the set changed hands and split in two:
@@ -236,6 +236,18 @@ export const INFERENCE_CONTRACT_VERSION = '8.10.0';
236
236
  * Both read the declared list price of a model line, in USD per million tokens.
237
237
  * Public request members only: the signed grant and envelope are unchanged and
238
238
  * no response carries an amount.
239
+ *
240
+ * Contract set 8.11.0 is additive and CONTRACT ONLY: the `rerank` grant
241
+ * operation (`grantOperationSchema`, last member) and the public `POST /v1/rerank`
242
+ * shapes (`rerankRequestSchema`, `rerankResponseSchema`). Kaana emits no `rerank`
243
+ * operation and serves no route yet; Oxy supports the operation first.
244
+ *
245
+ * Contract set 8.12.0 is additive: the signed envelope's optional `image`
246
+ * member (`inferenceImageParametersSchema`: `n`, `size`, `quality`, `style`,
247
+ * `responseFormat`), which carries a text-to-image request's controls to the
248
+ * adapter instead of dropping them. It is valid only with the
249
+ * `images_generations` API format, image modality and text input. Nothing in
250
+ * 8.11.0 changes and the public request and response shapes are unchanged.
239
251
  */
240
252
  /** The public API's one origin and version. */
241
253
  export const KAANA_API_BASE_URL = 'https://kaana.ai/v1';
package/openapi.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "openapi": "3.1.0",
3
3
  "info": {
4
4
  "title": "Kaana API",
5
- "version": "8.10.0",
5
+ "version": "8.12.0",
6
6
  "description": "Kaana inference API. Generated from @kaana.ai/contracts; the Zod source is the authority. Accounts, applications, oxy_sk_ keys, limits and billing are managed in Oxy Console: https://console.oxy.so"
7
7
  },
8
8
  "servers": [
@@ -4311,6 +4311,39 @@
4311
4311
  "maxLength": 2048,
4312
4312
  "pattern": "^https:\\/\\/[^\\s]+$"
4313
4313
  },
4314
+ "InferenceImageParameters": {
4315
+ "type": "object",
4316
+ "properties": {
4317
+ "n": {
4318
+ "type": "integer",
4319
+ "minimum": 1,
4320
+ "maximum": 10
4321
+ },
4322
+ "size": {
4323
+ "type": "string",
4324
+ "minLength": 1,
4325
+ "maxLength": 32
4326
+ },
4327
+ "quality": {
4328
+ "type": "string",
4329
+ "minLength": 1,
4330
+ "maxLength": 32
4331
+ },
4332
+ "style": {
4333
+ "type": "string",
4334
+ "minLength": 1,
4335
+ "maxLength": 32
4336
+ },
4337
+ "responseFormat": {
4338
+ "type": "string",
4339
+ "enum": [
4340
+ "url",
4341
+ "b64_json"
4342
+ ]
4343
+ }
4344
+ },
4345
+ "additionalProperties": false
4346
+ },
4314
4347
  "InferenceMessageRole": {
4315
4348
  "type": "string",
4316
4349
  "enum": [
@@ -7718,6 +7751,118 @@
7718
7751
  "maxLength": 256
7719
7752
  }
7720
7753
  },
7754
+ "RerankRequest": {
7755
+ "type": "object",
7756
+ "properties": {
7757
+ "model": {
7758
+ "$ref": "#/components/schemas/ModelReference"
7759
+ },
7760
+ "query": {
7761
+ "type": "string",
7762
+ "minLength": 1
7763
+ },
7764
+ "documents": {
7765
+ "minItems": 1,
7766
+ "maxItems": 1000,
7767
+ "type": "array",
7768
+ "items": {
7769
+ "type": "string",
7770
+ "minLength": 1
7771
+ }
7772
+ },
7773
+ "top_n": {
7774
+ "type": "integer",
7775
+ "minimum": 1,
7776
+ "maximum": 9007199254740991
7777
+ },
7778
+ "return_documents": {
7779
+ "type": "boolean"
7780
+ },
7781
+ "user": {
7782
+ "type": "string",
7783
+ "minLength": 1,
7784
+ "maxLength": 64
7785
+ }
7786
+ },
7787
+ "required": [
7788
+ "model",
7789
+ "query",
7790
+ "documents"
7791
+ ],
7792
+ "additionalProperties": false
7793
+ },
7794
+ "RerankResponse": {
7795
+ "type": "object",
7796
+ "properties": {
7797
+ "id": {
7798
+ "$ref": "#/components/schemas/GenerationId"
7799
+ },
7800
+ "model": {
7801
+ "$ref": "#/components/schemas/ModelReference"
7802
+ },
7803
+ "results": {
7804
+ "maxItems": 1000,
7805
+ "type": "array",
7806
+ "items": {
7807
+ "type": "object",
7808
+ "properties": {
7809
+ "index": {
7810
+ "type": "integer",
7811
+ "minimum": 0,
7812
+ "maximum": 9007199254740991
7813
+ },
7814
+ "relevance_score": {
7815
+ "type": "number"
7816
+ },
7817
+ "document": {
7818
+ "type": "object",
7819
+ "properties": {
7820
+ "text": {
7821
+ "type": "string"
7822
+ }
7823
+ },
7824
+ "required": [
7825
+ "text"
7826
+ ],
7827
+ "additionalProperties": false
7828
+ }
7829
+ },
7830
+ "required": [
7831
+ "index",
7832
+ "relevance_score"
7833
+ ],
7834
+ "additionalProperties": false
7835
+ }
7836
+ },
7837
+ "usage": {
7838
+ "type": "object",
7839
+ "properties": {
7840
+ "prompt_tokens": {
7841
+ "type": "integer",
7842
+ "minimum": 0,
7843
+ "maximum": 9007199254740991
7844
+ },
7845
+ "total_tokens": {
7846
+ "type": "integer",
7847
+ "minimum": 0,
7848
+ "maximum": 9007199254740991
7849
+ }
7850
+ },
7851
+ "required": [
7852
+ "prompt_tokens",
7853
+ "total_tokens"
7854
+ ],
7855
+ "additionalProperties": false
7856
+ }
7857
+ },
7858
+ "required": [
7859
+ "id",
7860
+ "model",
7861
+ "results",
7862
+ "usage"
7863
+ ],
7864
+ "additionalProperties": false
7865
+ },
7721
7866
  "ResponseFormat": {
7722
7867
  "oneOf": [
7723
7868
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaana.ai/contracts",
3
- "version": "8.10.0",
3
+ "version": "8.12.0",
4
4
  "description": "Kaana inference contract: the Zod schemas of the public API at https://kaana.ai/v1 and, under /internal, of the Oxy-Kaana grant, settlement and signed lane.",
5
5
  "type": "module",
6
6
  "sideEffects": false,