@kaana.ai/contracts 8.6.0 → 8.8.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.
@@ -56,6 +56,7 @@ export declare const inferenceInputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<
56
56
  content: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
57
57
  type: z.ZodLiteral<"text">;
58
58
  text: z.ZodString;
59
+ cacheBreakpoint: z.ZodOptional<z.ZodBoolean>;
59
60
  }, z.core.$strict>, z.ZodObject<{
60
61
  type: z.ZodLiteral<"image">;
61
62
  source: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -71,6 +72,7 @@ export declare const inferenceInputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<
71
72
  high: "high";
72
73
  auto: "auto";
73
74
  }>>;
75
+ cacheBreakpoint: z.ZodOptional<z.ZodBoolean>;
74
76
  }, z.core.$strict>, z.ZodObject<{
75
77
  type: z.ZodLiteral<"audio">;
76
78
  source: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -92,6 +94,7 @@ export declare const inferenceInputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<
92
94
  data: z.ZodString;
93
95
  }, z.core.$strict>], "kind">;
94
96
  filename: z.ZodOptional<z.ZodString>;
97
+ cacheBreakpoint: z.ZodOptional<z.ZodBoolean>;
95
98
  }, z.core.$strict>, z.ZodObject<{
96
99
  type: z.ZodLiteral<"refusal">;
97
100
  text: z.ZodString;
@@ -244,6 +247,7 @@ export declare const inferenceRequestSchema: z.ZodObject<{
244
247
  content: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
245
248
  type: z.ZodLiteral<"text">;
246
249
  text: z.ZodString;
250
+ cacheBreakpoint: z.ZodOptional<z.ZodBoolean>;
247
251
  }, z.core.$strict>, z.ZodObject<{
248
252
  type: z.ZodLiteral<"image">;
249
253
  source: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -259,6 +263,7 @@ export declare const inferenceRequestSchema: z.ZodObject<{
259
263
  high: "high";
260
264
  auto: "auto";
261
265
  }>>;
266
+ cacheBreakpoint: z.ZodOptional<z.ZodBoolean>;
262
267
  }, z.core.$strict>, z.ZodObject<{
263
268
  type: z.ZodLiteral<"audio">;
264
269
  source: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -280,6 +285,7 @@ export declare const inferenceRequestSchema: z.ZodObject<{
280
285
  data: z.ZodString;
281
286
  }, z.core.$strict>], "kind">;
282
287
  filename: z.ZodOptional<z.ZodString>;
288
+ cacheBreakpoint: z.ZodOptional<z.ZodBoolean>;
283
289
  }, z.core.$strict>, z.ZodObject<{
284
290
  type: z.ZodLiteral<"refusal">;
285
291
  text: z.ZodString;
@@ -355,6 +361,7 @@ export declare const inferenceRequestSchema: z.ZodObject<{
355
361
  description: z.ZodOptional<z.ZodString>;
356
362
  parameters: z.ZodRecord<z.ZodString, z.ZodUnknown>;
357
363
  strict: z.ZodOptional<z.ZodBoolean>;
364
+ cacheBreakpoint: z.ZodOptional<z.ZodBoolean>;
358
365
  }, z.core.$strict>>>;
359
366
  toolChoice: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
360
367
  auto: "auto";
@@ -11,12 +11,6 @@
11
11
  *
12
12
  * ## What is refused, and why
13
13
  *
14
- * - **`cache_control`, anywhere** (on a block, a tool, `system` or the
15
- * request). Kaana's usage units have no unit for a cache WRITE (see the
16
- * Anthropic adapter's usage meter): a cache write is billed at a premium
17
- * over input, so honouring the marker while folding the write into
18
- * `input_tokens` would report less than the request cost. The marker is
19
- * refused, by name and path, instead of being dropped.
20
14
  * - **`thinking.display`** and every other `thinking` member this file does
21
15
  * not name.
22
16
  * - **Server tools** (`web_search`, `bash`, `text_editor`, …), `mcp_servers`,
@@ -25,6 +19,26 @@
25
19
  * - **An image `url` source**: nothing fetches an image URL (ADR 0007); a
26
20
  * `base64` source is carried inline under the image rules.
27
21
  *
22
+ * ## `cache_control`: accepted and IGNORED
23
+ *
24
+ * Claude Code puts a `cache_control` marker on every request, so refusing it
25
+ * made the endpoint unusable by its main client. The marker is accepted wherever
26
+ * the dialect puts it (the request, `system`, a tool, a content block) and is
27
+ * NOT honoured: Kaana forwards no cache hint, so no cache write happens and the
28
+ * usage it reports stays exactly what the request cost. The only effect is the
29
+ * one the caller asked for and does not get: no prompt-cache discount on a write
30
+ * (reads that a provider caches on its own are still metered as
31
+ * `cache_read_input_tokens`). A request whose marker was ignored is answered
32
+ * with `Kaana-Ignored-Parameters: cache_control`. Honouring it needs a priced
33
+ * cache-write unit (`cache_write_input_tokens`, contract 8.4.0) that nothing
34
+ * emits yet.
35
+ *
36
+ * The same holds for three more members Claude Code sends: `context_management`,
37
+ * `thinking.display` and `tools[].defer_loading`. Each is a hint or a beta that
38
+ * changes how a provider trims, shows or loads, never what a request means or
39
+ * costs; each present one is named in `Kaana-Ignored-Parameters`. Any other
40
+ * member this file does not name is still refused.
41
+ *
28
42
  * ## Reasoning (contract set 8.6.0, ADR 0009 decision 2)
29
43
  *
30
44
  * `thinking: {type: 'enabled', budget_tokens}` is the contract's
@@ -67,14 +81,17 @@ export declare const anthropicMessagesRequestSchema: z.ZodObject<{
67
81
  max_tokens: z.ZodNumber;
68
82
  messages: z.ZodArray<z.ZodObject<{
69
83
  role: z.ZodEnum<{
84
+ system: "system";
70
85
  user: "user";
71
86
  assistant: "assistant";
72
87
  }>;
73
88
  content: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
74
89
  type: z.ZodLiteral<"text">;
75
90
  text: z.ZodString;
91
+ cache_control: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
76
92
  }, z.core.$strict>, z.ZodObject<{
77
93
  type: z.ZodLiteral<"image">;
94
+ cache_control: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
78
95
  source: z.ZodDiscriminatedUnion<[z.ZodObject<{
79
96
  type: z.ZodLiteral<"base64">;
80
97
  media_type: z.ZodString;
@@ -88,14 +105,17 @@ export declare const anthropicMessagesRequestSchema: z.ZodObject<{
88
105
  id: z.ZodString;
89
106
  name: z.ZodString;
90
107
  input: z.ZodRecord<z.ZodString, z.ZodUnknown>;
108
+ cache_control: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
91
109
  }, z.core.$strict>, z.ZodObject<{
92
110
  type: z.ZodLiteral<"tool_result">;
93
111
  tool_use_id: z.ZodString;
94
112
  content: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
95
113
  type: z.ZodLiteral<"text">;
96
114
  text: z.ZodString;
115
+ cache_control: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
97
116
  }, z.core.$strict>, z.ZodObject<{
98
117
  type: z.ZodLiteral<"image">;
118
+ cache_control: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
99
119
  source: z.ZodDiscriminatedUnion<[z.ZodObject<{
100
120
  type: z.ZodLiteral<"base64">;
101
121
  media_type: z.ZodString;
@@ -106,6 +126,7 @@ export declare const anthropicMessagesRequestSchema: z.ZodObject<{
106
126
  }, z.core.$strict>], "type">;
107
127
  }, z.core.$strict>]>>]>>;
108
128
  is_error: z.ZodOptional<z.ZodBoolean>;
129
+ cache_control: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
109
130
  }, z.core.$strict>, z.ZodObject<{
110
131
  type: z.ZodLiteral<"thinking">;
111
132
  thinking: z.ZodString;
@@ -118,7 +139,9 @@ export declare const anthropicMessagesRequestSchema: z.ZodObject<{
118
139
  system: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodObject<{
119
140
  type: z.ZodLiteral<"text">;
120
141
  text: z.ZodString;
142
+ cache_control: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
121
143
  }, z.core.$strict>>]>>;
144
+ cache_control: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
122
145
  temperature: z.ZodOptional<z.ZodNumber>;
123
146
  top_p: z.ZodOptional<z.ZodNumber>;
124
147
  top_k: z.ZodOptional<z.ZodNumber>;
@@ -130,6 +153,8 @@ export declare const anthropicMessagesRequestSchema: z.ZodObject<{
130
153
  description: z.ZodOptional<z.ZodString>;
131
154
  input_schema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
132
155
  strict: z.ZodOptional<z.ZodBoolean>;
156
+ cache_control: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
157
+ defer_loading: z.ZodOptional<z.ZodBoolean>;
133
158
  }, z.core.$strict>>>;
134
159
  tool_choice: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
135
160
  type: z.ZodLiteral<"auto">;
@@ -145,10 +170,13 @@ export declare const anthropicMessagesRequestSchema: z.ZodObject<{
145
170
  type: z.ZodLiteral<"disabled">;
146
171
  }, z.core.$strict>, z.ZodObject<{
147
172
  type: z.ZodLiteral<"adaptive">;
173
+ display: z.ZodOptional<z.ZodString>;
148
174
  }, z.core.$strict>, z.ZodObject<{
149
175
  type: z.ZodLiteral<"enabled">;
150
176
  budget_tokens: z.ZodNumber;
177
+ display: z.ZodOptional<z.ZodString>;
151
178
  }, z.core.$strict>], "type">>;
179
+ context_management: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
152
180
  output_config: z.ZodOptional<z.ZodObject<{
153
181
  effort: z.ZodOptional<z.ZodEnum<{
154
182
  low: "low";
@@ -173,10 +201,12 @@ export declare const anthropicMessageSchema: z.ZodObject<{
173
201
  }, z.core.$strict>, z.ZodObject<{
174
202
  type: z.ZodLiteral<"text">;
175
203
  text: z.ZodString;
204
+ cache_control: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
176
205
  }, z.core.$strict>, z.ZodObject<{
177
206
  type: z.ZodLiteral<"tool_use">;
178
207
  id: z.ZodString;
179
208
  name: z.ZodString;
209
+ cache_control: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
180
210
  input: z.ZodRecord<z.ZodString, z.ZodUnknown>;
181
211
  }, z.core.$strict>], "type">>;
182
212
  stop_reason: z.ZodEnum<{
@@ -232,10 +262,12 @@ export declare const anthropicStreamEventSchema: z.ZodDiscriminatedUnion<[z.ZodO
232
262
  }, z.core.$strict>, z.ZodObject<{
233
263
  type: z.ZodLiteral<"text">;
234
264
  text: z.ZodString;
265
+ cache_control: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
235
266
  }, z.core.$strict>, z.ZodObject<{
236
267
  type: z.ZodLiteral<"tool_use">;
237
268
  id: z.ZodString;
238
269
  name: z.ZodString;
270
+ cache_control: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
239
271
  input: z.ZodRecord<z.ZodString, z.ZodUnknown>;
240
272
  }, z.core.$strict>], "type">>;
241
273
  stop_reason: z.ZodLiteral<null>;
@@ -260,6 +292,7 @@ export declare const anthropicStreamEventSchema: z.ZodDiscriminatedUnion<[z.ZodO
260
292
  type: z.ZodLiteral<"tool_use">;
261
293
  id: z.ZodString;
262
294
  name: z.ZodString;
295
+ cache_control: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
263
296
  input: z.ZodObject<{}, z.core.$strict>;
264
297
  }, z.core.$strict>], "type">;
265
298
  }, z.core.$strict>, z.ZodObject<{
@@ -11,12 +11,6 @@
11
11
  *
12
12
  * ## What is refused, and why
13
13
  *
14
- * - **`cache_control`, anywhere** (on a block, a tool, `system` or the
15
- * request). Kaana's usage units have no unit for a cache WRITE (see the
16
- * Anthropic adapter's usage meter): a cache write is billed at a premium
17
- * over input, so honouring the marker while folding the write into
18
- * `input_tokens` would report less than the request cost. The marker is
19
- * refused, by name and path, instead of being dropped.
20
14
  * - **`thinking.display`** and every other `thinking` member this file does
21
15
  * not name.
22
16
  * - **Server tools** (`web_search`, `bash`, `text_editor`, …), `mcp_servers`,
@@ -25,6 +19,26 @@
25
19
  * - **An image `url` source**: nothing fetches an image URL (ADR 0007); a
26
20
  * `base64` source is carried inline under the image rules.
27
21
  *
22
+ * ## `cache_control`: accepted and IGNORED
23
+ *
24
+ * Claude Code puts a `cache_control` marker on every request, so refusing it
25
+ * made the endpoint unusable by its main client. The marker is accepted wherever
26
+ * the dialect puts it (the request, `system`, a tool, a content block) and is
27
+ * NOT honoured: Kaana forwards no cache hint, so no cache write happens and the
28
+ * usage it reports stays exactly what the request cost. The only effect is the
29
+ * one the caller asked for and does not get: no prompt-cache discount on a write
30
+ * (reads that a provider caches on its own are still metered as
31
+ * `cache_read_input_tokens`). A request whose marker was ignored is answered
32
+ * with `Kaana-Ignored-Parameters: cache_control`. Honouring it needs a priced
33
+ * cache-write unit (`cache_write_input_tokens`, contract 8.4.0) that nothing
34
+ * emits yet.
35
+ *
36
+ * The same holds for three more members Claude Code sends: `context_management`,
37
+ * `thinking.display` and `tools[].defer_loading`. Each is a hint or a beta that
38
+ * changes how a provider trims, shows or loads, never what a request means or
39
+ * costs; each present one is named in `Kaana-Ignored-Parameters`. Any other
40
+ * member this file does not name is still refused.
41
+ *
28
42
  * ## Reasoning (contract set 8.6.0, ADR 0009 decision 2)
29
43
  *
30
44
  * `thinking: {type: 'enabled', budget_tokens}` is the contract's
@@ -58,10 +72,21 @@ import { maxUtf16Length, minUtf16Length } from '../stringBounds.js';
58
72
  import { reasoningEffortSchema } from './catalogue.js';
59
73
  import { modelTargetSchema } from './responses.js';
60
74
  const nonEmpty = (max) => z.string().check(minUtf16Length(1)).check(maxUtf16Length(max));
61
- const textBlockSchema = z.object({ type: z.literal('text'), text: z.string() }).strict();
75
+ /** Accepted and ignored, whatever members it carries (`type`, `ttl`, `scope`): see "`cache_control`" in the file comment. */
76
+ const cacheControlSchema = z.record(z.string(), z.unknown());
77
+ /** Accepted and ignored: how much reasoning text a client wants shown. */
78
+ const thinkingDisplaySchema = z.string();
79
+ const textBlockSchema = z
80
+ .object({
81
+ type: z.literal('text'),
82
+ text: z.string(),
83
+ cache_control: cacheControlSchema.optional(),
84
+ })
85
+ .strict();
62
86
  const imageBlockSchema = z
63
87
  .object({
64
88
  type: z.literal('image'),
89
+ cache_control: cacheControlSchema.optional(),
65
90
  source: z.discriminatedUnion('type', [
66
91
  z
67
92
  .object({
@@ -96,6 +121,7 @@ const toolUseBlockSchema = z
96
121
  id: nonEmpty(128),
97
122
  name: nonEmpty(128),
98
123
  input: z.record(z.string(), z.unknown()),
124
+ cache_control: cacheControlSchema.optional(),
99
125
  })
100
126
  .strict();
101
127
  const toolResultBlockSchema = z
@@ -110,11 +136,13 @@ const toolResultBlockSchema = z
110
136
  * own content is what the model reads; the flag is not forwarded.
111
137
  */
112
138
  is_error: z.boolean().optional(),
139
+ cache_control: cacheControlSchema.optional(),
113
140
  })
114
141
  .strict();
115
142
  const messageSchema = z
116
143
  .object({
117
- role: z.enum(['user', 'assistant']),
144
+ /** `system` is a mid-conversation instruction Claude Code sends: text blocks only. */
145
+ role: z.enum(['user', 'assistant', 'system']),
118
146
  content: z.union([
119
147
  z.string(),
120
148
  z
@@ -137,7 +165,9 @@ const messageSchema = z
137
165
  const reasoning = block.type === 'thinking' || block.type === 'redacted_thinking';
138
166
  const allowed = message.role === 'assistant'
139
167
  ? block.type === 'text' || block.type === 'tool_use' || reasoning
140
- : block.type !== 'tool_use' && !reasoning;
168
+ : message.role === 'system'
169
+ ? block.type === 'text'
170
+ : block.type !== 'tool_use' && !reasoning;
141
171
  if (!allowed) {
142
172
  ctx.addIssue({
143
173
  code: 'custom',
@@ -154,6 +184,9 @@ const toolSchema = z
154
184
  description: z.string().check(maxUtf16Length(32768)).optional(),
155
185
  input_schema: z.record(z.string(), z.unknown()),
156
186
  strict: z.boolean().optional(),
187
+ cache_control: cacheControlSchema.optional(),
188
+ /** Accepted and ignored: Kaana loads every tool it is sent. */
189
+ defer_loading: z.boolean().optional(),
157
190
  })
158
191
  .strict();
159
192
  const toolChoiceSchema = z.discriminatedUnion('type', [
@@ -170,6 +203,7 @@ export const anthropicMessagesRequestSchema = z
170
203
  max_tokens: z.number().int().positive().safe(),
171
204
  messages: z.array(messageSchema).min(1),
172
205
  system: z.union([z.string(), z.array(textBlockSchema)]).optional(),
206
+ cache_control: cacheControlSchema.optional(),
173
207
  temperature: z.number().min(0).max(1).optional(),
174
208
  top_p: z.number().min(0).max(1).optional(),
175
209
  top_k: z.number().int().positive().safe().optional(),
@@ -185,15 +219,20 @@ export const anthropicMessagesRequestSchema = z
185
219
  thinking: z
186
220
  .discriminatedUnion('type', [
187
221
  z.object({ type: z.literal('disabled') }).strict(),
188
- z.object({ type: z.literal('adaptive') }).strict(),
222
+ z
223
+ .object({ type: z.literal('adaptive'), display: thinkingDisplaySchema.optional() })
224
+ .strict(),
189
225
  z
190
226
  .object({
191
227
  type: z.literal('enabled'),
192
228
  budget_tokens: z.number().int().positive().safe(),
229
+ display: thinkingDisplaySchema.optional(),
193
230
  })
194
231
  .strict(),
195
232
  ])
196
233
  .optional(),
234
+ /** Accepted and ignored (an Anthropic beta Claude Code sends). */
235
+ context_management: z.record(z.string(), z.unknown()).optional(),
197
236
  /** `effort` is the contract's reasoning effort; no other member is carried. */
198
237
  output_config: z.object({ effort: reasoningEffortSchema.optional() }).strict().optional(),
199
238
  /** Accepted and not forwarded or stored. */
@@ -31,6 +31,7 @@ export declare const chatCompletionMessageSchema: z.ZodObject<{
31
31
  content: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
32
32
  type: z.ZodLiteral<"text">;
33
33
  text: z.ZodString;
34
+ cacheBreakpoint: z.ZodOptional<z.ZodBoolean>;
34
35
  }, z.core.$strict>, z.ZodObject<{
35
36
  type: z.ZodLiteral<"image">;
36
37
  source: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -46,6 +47,7 @@ export declare const chatCompletionMessageSchema: z.ZodObject<{
46
47
  high: "high";
47
48
  auto: "auto";
48
49
  }>>;
50
+ cacheBreakpoint: z.ZodOptional<z.ZodBoolean>;
49
51
  }, z.core.$strict>, z.ZodObject<{
50
52
  type: z.ZodLiteral<"audio">;
51
53
  source: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -67,6 +69,7 @@ export declare const chatCompletionMessageSchema: z.ZodObject<{
67
69
  data: z.ZodString;
68
70
  }, z.core.$strict>], "kind">;
69
71
  filename: z.ZodOptional<z.ZodString>;
72
+ cacheBreakpoint: z.ZodOptional<z.ZodBoolean>;
70
73
  }, z.core.$strict>, z.ZodObject<{
71
74
  type: z.ZodLiteral<"refusal">;
72
75
  text: z.ZodString;
@@ -107,6 +110,7 @@ export declare const chatCompletionsRequestSchema: z.ZodObject<{
107
110
  content: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
108
111
  type: z.ZodLiteral<"text">;
109
112
  text: z.ZodString;
113
+ cacheBreakpoint: z.ZodOptional<z.ZodBoolean>;
110
114
  }, z.core.$strict>, z.ZodObject<{
111
115
  type: z.ZodLiteral<"image">;
112
116
  source: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -122,6 +126,7 @@ export declare const chatCompletionsRequestSchema: z.ZodObject<{
122
126
  high: "high";
123
127
  auto: "auto";
124
128
  }>>;
129
+ cacheBreakpoint: z.ZodOptional<z.ZodBoolean>;
125
130
  }, z.core.$strict>, z.ZodObject<{
126
131
  type: z.ZodLiteral<"audio">;
127
132
  source: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -143,6 +148,7 @@ export declare const chatCompletionsRequestSchema: z.ZodObject<{
143
148
  data: z.ZodString;
144
149
  }, z.core.$strict>], "kind">;
145
150
  filename: z.ZodOptional<z.ZodString>;
151
+ cacheBreakpoint: z.ZodOptional<z.ZodBoolean>;
146
152
  }, z.core.$strict>, z.ZodObject<{
147
153
  type: z.ZodLiteral<"refusal">;
148
154
  text: z.ZodString;
@@ -65,6 +65,7 @@ export declare const inferenceContentSourceSchema: z.ZodDiscriminatedUnion<[z.Zo
65
65
  export declare const inferenceContentPartSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
66
66
  type: z.ZodLiteral<"text">;
67
67
  text: z.ZodString;
68
+ cacheBreakpoint: z.ZodOptional<z.ZodBoolean>;
68
69
  }, z.core.$strict>, z.ZodObject<{
69
70
  type: z.ZodLiteral<"image">;
70
71
  source: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -80,6 +81,7 @@ export declare const inferenceContentPartSchema: z.ZodDiscriminatedUnion<[z.ZodO
80
81
  high: "high";
81
82
  auto: "auto";
82
83
  }>>;
84
+ cacheBreakpoint: z.ZodOptional<z.ZodBoolean>;
83
85
  }, z.core.$strict>, z.ZodObject<{
84
86
  type: z.ZodLiteral<"audio">;
85
87
  source: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -101,6 +103,7 @@ export declare const inferenceContentPartSchema: z.ZodDiscriminatedUnion<[z.ZodO
101
103
  data: z.ZodString;
102
104
  }, z.core.$strict>], "kind">;
103
105
  filename: z.ZodOptional<z.ZodString>;
106
+ cacheBreakpoint: z.ZodOptional<z.ZodBoolean>;
104
107
  }, z.core.$strict>, z.ZodObject<{
105
108
  type: z.ZodLiteral<"refusal">;
106
109
  text: z.ZodString;
@@ -202,6 +205,7 @@ export declare const inferenceMessageSchema: z.ZodObject<{
202
205
  content: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
203
206
  type: z.ZodLiteral<"text">;
204
207
  text: z.ZodString;
208
+ cacheBreakpoint: z.ZodOptional<z.ZodBoolean>;
205
209
  }, z.core.$strict>, z.ZodObject<{
206
210
  type: z.ZodLiteral<"image">;
207
211
  source: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -217,6 +221,7 @@ export declare const inferenceMessageSchema: z.ZodObject<{
217
221
  high: "high";
218
222
  auto: "auto";
219
223
  }>>;
224
+ cacheBreakpoint: z.ZodOptional<z.ZodBoolean>;
220
225
  }, z.core.$strict>, z.ZodObject<{
221
226
  type: z.ZodLiteral<"audio">;
222
227
  source: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -238,6 +243,7 @@ export declare const inferenceMessageSchema: z.ZodObject<{
238
243
  data: z.ZodString;
239
244
  }, z.core.$strict>], "kind">;
240
245
  filename: z.ZodOptional<z.ZodString>;
246
+ cacheBreakpoint: z.ZodOptional<z.ZodBoolean>;
241
247
  }, z.core.$strict>, z.ZodObject<{
242
248
  type: z.ZodLiteral<"refusal">;
243
249
  text: z.ZodString;
@@ -275,6 +281,7 @@ export declare const toolDefinitionSchema: z.ZodObject<{
275
281
  description: z.ZodOptional<z.ZodString>;
276
282
  parameters: z.ZodRecord<z.ZodString, z.ZodUnknown>;
277
283
  strict: z.ZodOptional<z.ZodBoolean>;
284
+ cacheBreakpoint: z.ZodOptional<z.ZodBoolean>;
278
285
  }, z.core.$strict>;
279
286
  /** Whether, and which, tool the model must call. */
280
287
  export declare const toolChoiceSchema: z.ZodUnion<readonly [z.ZodEnum<{
@@ -30,6 +30,22 @@ export const inferenceContentSourceSchema = z.discriminatedUnion('kind', [
30
30
  })
31
31
  .strict(),
32
32
  ]);
33
+ /**
34
+ * A prompt-cache breakpoint (contract set 8.8.0): the prompt up to and including
35
+ * the part, system message or tool that carries it is to be cached by a provider
36
+ * that can express it. `true` is Anthropic's `cache_control: {type: "ephemeral"}`
37
+ * with the default 5-minute lifetime and nothing else: there is no lifetime
38
+ * field, because the one cache-write unit cannot price a longer one.
39
+ *
40
+ * It is a hint with no effect on the answer. A route that cannot express it
41
+ * ignores it and still succeeds; Kaana's executor sends it only to a route whose
42
+ * granted price version prices `cache_write_input_tokens`, so a cache write is
43
+ * never provoked that the customer is not charged for at its own rate. A provider
44
+ * that allows fewer breakpoints than are marked receives the earliest ones in
45
+ * prompt order (tools, then system, then messages). `false` is the same as absent.
46
+ * Only a part whose type a provider caches (`text`, `image`, `file`) carries it.
47
+ */
48
+ const cacheBreakpointSchema = z.boolean().optional();
33
49
  /**
34
50
  * One part of a message's content. A message is always a list of parts.
35
51
  *
@@ -73,13 +89,20 @@ export const inferenceContentSourceSchema = z.discriminatedUnion('kind', [
73
89
  * the continuation is lost, the conversation is not.
74
90
  */
75
91
  export const inferenceContentPartSchema = z.discriminatedUnion('type', [
76
- z.object({ type: z.literal('text'), text: z.string() }).strict(),
92
+ z
93
+ .object({
94
+ type: z.literal('text'),
95
+ text: z.string(),
96
+ cacheBreakpoint: cacheBreakpointSchema,
97
+ })
98
+ .strict(),
77
99
  z
78
100
  .object({
79
101
  type: z.literal('image'),
80
102
  source: inferenceContentSourceSchema,
81
103
  /** Provider-independent hint; providers that ignore it are unaffected. */
82
104
  detail: z.enum(['auto', 'low', 'high']).optional(),
105
+ cacheBreakpoint: cacheBreakpointSchema,
83
106
  })
84
107
  .strict(),
85
108
  z.object({ type: z.literal('audio'), source: inferenceContentSourceSchema }).strict(),
@@ -88,6 +111,7 @@ export const inferenceContentPartSchema = z.discriminatedUnion('type', [
88
111
  type: z.literal('file'),
89
112
  source: inferenceContentSourceSchema,
90
113
  filename: z.string().check(maxUtf16Length(255)).optional(),
114
+ cacheBreakpoint: cacheBreakpointSchema,
91
115
  })
92
116
  .strict(),
93
117
  /**
@@ -324,6 +348,8 @@ export const toolDefinitionSchema = z
324
348
  parameters: z.record(z.string(), z.unknown()),
325
349
  /** Ask the provider to enforce the schema, where it supports enforcement. */
326
350
  strict: z.boolean().optional(),
351
+ /** A prompt-cache breakpoint after this tool ({@link cacheBreakpointSchema}). */
352
+ cacheBreakpoint: cacheBreakpointSchema,
327
353
  })
328
354
  .strict();
329
355
  /** Whether, and which, tool the model must call. */
@@ -135,7 +135,10 @@ export const realtimeTranslationSchema = z
135
135
  * A function tool a session may call: the chat tool without `strict`, which no
136
136
  * realtime provider's session schema has (contract set 5.0.0).
137
137
  */
138
- export const realtimeToolDefinitionSchema = toolDefinitionSchema.omit({ strict: true });
138
+ export const realtimeToolDefinitionSchema = toolDefinitionSchema.omit({
139
+ strict: true,
140
+ cacheBreakpoint: true,
141
+ });
139
142
  /**
140
143
  * A session's full configuration, as signed at open and as echoed back by
141
144
  * `session.created` and `session.updated`.
@@ -53,6 +53,7 @@ export declare const responsesRequestSchema: z.ZodObject<{
53
53
  content: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
54
54
  type: z.ZodLiteral<"text">;
55
55
  text: z.ZodString;
56
+ cacheBreakpoint: z.ZodOptional<z.ZodBoolean>;
56
57
  }, z.core.$strict>, z.ZodObject<{
57
58
  type: z.ZodLiteral<"image">;
58
59
  source: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -68,6 +69,7 @@ export declare const responsesRequestSchema: z.ZodObject<{
68
69
  high: "high";
69
70
  auto: "auto";
70
71
  }>>;
72
+ cacheBreakpoint: z.ZodOptional<z.ZodBoolean>;
71
73
  }, z.core.$strict>, z.ZodObject<{
72
74
  type: z.ZodLiteral<"audio">;
73
75
  source: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -89,6 +91,7 @@ export declare const responsesRequestSchema: z.ZodObject<{
89
91
  data: z.ZodString;
90
92
  }, z.core.$strict>], "kind">;
91
93
  filename: z.ZodOptional<z.ZodString>;
94
+ cacheBreakpoint: z.ZodOptional<z.ZodBoolean>;
92
95
  }, z.core.$strict>, z.ZodObject<{
93
96
  type: z.ZodLiteral<"refusal">;
94
97
  text: z.ZodString;
@@ -120,6 +123,7 @@ export declare const responsesRequestSchema: z.ZodObject<{
120
123
  description: z.ZodOptional<z.ZodString>;
121
124
  parameters: z.ZodRecord<z.ZodString, z.ZodUnknown>;
122
125
  strict: z.ZodOptional<z.ZodBoolean>;
126
+ cacheBreakpoint: z.ZodOptional<z.ZodBoolean>;
123
127
  }, z.core.$strict>>>;
124
128
  toolChoice: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
125
129
  auto: "auto";
@@ -207,6 +211,7 @@ export declare const responseSchema: z.ZodObject<{
207
211
  content: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
208
212
  type: z.ZodLiteral<"text">;
209
213
  text: z.ZodString;
214
+ cacheBreakpoint: z.ZodOptional<z.ZodBoolean>;
210
215
  }, z.core.$strict>, z.ZodObject<{
211
216
  type: z.ZodLiteral<"image">;
212
217
  source: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -222,6 +227,7 @@ export declare const responseSchema: z.ZodObject<{
222
227
  high: "high";
223
228
  auto: "auto";
224
229
  }>>;
230
+ cacheBreakpoint: z.ZodOptional<z.ZodBoolean>;
225
231
  }, z.core.$strict>, z.ZodObject<{
226
232
  type: z.ZodLiteral<"audio">;
227
233
  source: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -243,6 +249,7 @@ export declare const responseSchema: z.ZodObject<{
243
249
  data: z.ZodString;
244
250
  }, z.core.$strict>], "kind">;
245
251
  filename: z.ZodOptional<z.ZodString>;
252
+ cacheBreakpoint: z.ZodOptional<z.ZodBoolean>;
246
253
  }, z.core.$strict>, z.ZodObject<{
247
254
  type: z.ZodLiteral<"refusal">;
248
255
  text: z.ZodString;
@@ -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.6.0";
103
+ export declare const INFERENCE_CONTRACT_VERSION = "8.8.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:
@@ -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.6.0';
103
+ export const INFERENCE_CONTRACT_VERSION = '8.8.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:
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.6.0",
5
+ "version": "8.8.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": [
@@ -1312,6 +1312,13 @@
1312
1312
  },
1313
1313
  "text": {
1314
1314
  "type": "string"
1315
+ },
1316
+ "cache_control": {
1317
+ "type": "object",
1318
+ "propertyNames": {
1319
+ "type": "string"
1320
+ },
1321
+ "additionalProperties": {}
1315
1322
  }
1316
1323
  },
1317
1324
  "required": [
@@ -1343,6 +1350,13 @@
1343
1350
  "type": "string"
1344
1351
  },
1345
1352
  "additionalProperties": {}
1353
+ },
1354
+ "cache_control": {
1355
+ "type": "object",
1356
+ "propertyNames": {
1357
+ "type": "string"
1358
+ },
1359
+ "additionalProperties": {}
1346
1360
  }
1347
1361
  },
1348
1362
  "required": [
@@ -1428,7 +1442,8 @@
1428
1442
  "type": "string",
1429
1443
  "enum": [
1430
1444
  "user",
1431
- "assistant"
1445
+ "assistant",
1446
+ "system"
1432
1447
  ]
1433
1448
  },
1434
1449
  "content": {
@@ -1450,6 +1465,13 @@
1450
1465
  },
1451
1466
  "text": {
1452
1467
  "type": "string"
1468
+ },
1469
+ "cache_control": {
1470
+ "type": "object",
1471
+ "propertyNames": {
1472
+ "type": "string"
1473
+ },
1474
+ "additionalProperties": {}
1453
1475
  }
1454
1476
  },
1455
1477
  "required": [
@@ -1465,6 +1487,13 @@
1465
1487
  "type": "string",
1466
1488
  "const": "image"
1467
1489
  },
1490
+ "cache_control": {
1491
+ "type": "object",
1492
+ "propertyNames": {
1493
+ "type": "string"
1494
+ },
1495
+ "additionalProperties": {}
1496
+ },
1468
1497
  "source": {
1469
1498
  "oneOf": [
1470
1499
  {
@@ -1542,6 +1571,13 @@
1542
1571
  "type": "string"
1543
1572
  },
1544
1573
  "additionalProperties": {}
1574
+ },
1575
+ "cache_control": {
1576
+ "type": "object",
1577
+ "propertyNames": {
1578
+ "type": "string"
1579
+ },
1580
+ "additionalProperties": {}
1545
1581
  }
1546
1582
  },
1547
1583
  "required": [
@@ -1582,6 +1618,13 @@
1582
1618
  },
1583
1619
  "text": {
1584
1620
  "type": "string"
1621
+ },
1622
+ "cache_control": {
1623
+ "type": "object",
1624
+ "propertyNames": {
1625
+ "type": "string"
1626
+ },
1627
+ "additionalProperties": {}
1585
1628
  }
1586
1629
  },
1587
1630
  "required": [
@@ -1597,6 +1640,13 @@
1597
1640
  "type": "string",
1598
1641
  "const": "image"
1599
1642
  },
1643
+ "cache_control": {
1644
+ "type": "object",
1645
+ "propertyNames": {
1646
+ "type": "string"
1647
+ },
1648
+ "additionalProperties": {}
1649
+ },
1600
1650
  "source": {
1601
1651
  "oneOf": [
1602
1652
  {
@@ -1658,6 +1708,13 @@
1658
1708
  },
1659
1709
  "is_error": {
1660
1710
  "type": "boolean"
1711
+ },
1712
+ "cache_control": {
1713
+ "type": "object",
1714
+ "propertyNames": {
1715
+ "type": "string"
1716
+ },
1717
+ "additionalProperties": {}
1661
1718
  }
1662
1719
  },
1663
1720
  "required": [
@@ -1735,6 +1792,13 @@
1735
1792
  },
1736
1793
  "text": {
1737
1794
  "type": "string"
1795
+ },
1796
+ "cache_control": {
1797
+ "type": "object",
1798
+ "propertyNames": {
1799
+ "type": "string"
1800
+ },
1801
+ "additionalProperties": {}
1738
1802
  }
1739
1803
  },
1740
1804
  "required": [
@@ -1746,6 +1810,13 @@
1746
1810
  }
1747
1811
  ]
1748
1812
  },
1813
+ "cache_control": {
1814
+ "type": "object",
1815
+ "propertyNames": {
1816
+ "type": "string"
1817
+ },
1818
+ "additionalProperties": {}
1819
+ },
1749
1820
  "temperature": {
1750
1821
  "type": "number",
1751
1822
  "minimum": 0,
@@ -1801,6 +1872,16 @@
1801
1872
  },
1802
1873
  "strict": {
1803
1874
  "type": "boolean"
1875
+ },
1876
+ "cache_control": {
1877
+ "type": "object",
1878
+ "propertyNames": {
1879
+ "type": "string"
1880
+ },
1881
+ "additionalProperties": {}
1882
+ },
1883
+ "defer_loading": {
1884
+ "type": "boolean"
1804
1885
  }
1805
1886
  },
1806
1887
  "required": [
@@ -1893,6 +1974,9 @@
1893
1974
  "type": {
1894
1975
  "type": "string",
1895
1976
  "const": "adaptive"
1977
+ },
1978
+ "display": {
1979
+ "type": "string"
1896
1980
  }
1897
1981
  },
1898
1982
  "required": [
@@ -1911,6 +1995,9 @@
1911
1995
  "type": "integer",
1912
1996
  "exclusiveMinimum": 0,
1913
1997
  "maximum": 9007199254740991
1998
+ },
1999
+ "display": {
2000
+ "type": "string"
1914
2001
  }
1915
2002
  },
1916
2003
  "required": [
@@ -1921,6 +2008,13 @@
1921
2008
  }
1922
2009
  ]
1923
2010
  },
2011
+ "context_management": {
2012
+ "type": "object",
2013
+ "propertyNames": {
2014
+ "type": "string"
2015
+ },
2016
+ "additionalProperties": {}
2017
+ },
1924
2018
  "output_config": {
1925
2019
  "type": "object",
1926
2020
  "properties": {
@@ -2021,6 +2115,13 @@
2021
2115
  },
2022
2116
  "text": {
2023
2117
  "type": "string"
2118
+ },
2119
+ "cache_control": {
2120
+ "type": "object",
2121
+ "propertyNames": {
2122
+ "type": "string"
2123
+ },
2124
+ "additionalProperties": {}
2024
2125
  }
2025
2126
  },
2026
2127
  "required": [
@@ -2052,6 +2153,13 @@
2052
2153
  "type": "string"
2053
2154
  },
2054
2155
  "additionalProperties": {}
2156
+ },
2157
+ "cache_control": {
2158
+ "type": "object",
2159
+ "propertyNames": {
2160
+ "type": "string"
2161
+ },
2162
+ "additionalProperties": {}
2055
2163
  }
2056
2164
  },
2057
2165
  "required": [
@@ -2194,6 +2302,13 @@
2194
2302
  "type": "object",
2195
2303
  "properties": {},
2196
2304
  "additionalProperties": false
2305
+ },
2306
+ "cache_control": {
2307
+ "type": "object",
2308
+ "propertyNames": {
2309
+ "type": "string"
2310
+ },
2311
+ "additionalProperties": {}
2197
2312
  }
2198
2313
  },
2199
2314
  "required": [
@@ -3964,6 +4079,9 @@
3964
4079
  },
3965
4080
  "text": {
3966
4081
  "type": "string"
4082
+ },
4083
+ "cacheBreakpoint": {
4084
+ "type": "boolean"
3967
4085
  }
3968
4086
  },
3969
4087
  "required": [
@@ -3989,6 +4107,9 @@
3989
4107
  "low",
3990
4108
  "high"
3991
4109
  ]
4110
+ },
4111
+ "cacheBreakpoint": {
4112
+ "type": "boolean"
3992
4113
  }
3993
4114
  },
3994
4115
  "required": [
@@ -4027,6 +4148,9 @@
4027
4148
  "filename": {
4028
4149
  "type": "string",
4029
4150
  "maxLength": 255
4151
+ },
4152
+ "cacheBreakpoint": {
4153
+ "type": "boolean"
4030
4154
  }
4031
4155
  },
4032
4156
  "required": [
@@ -8193,6 +8317,9 @@
8193
8317
  },
8194
8318
  "strict": {
8195
8319
  "type": "boolean"
8320
+ },
8321
+ "cacheBreakpoint": {
8322
+ "type": "boolean"
8196
8323
  }
8197
8324
  },
8198
8325
  "required": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaana.ai/contracts",
3
- "version": "8.6.0",
3
+ "version": "8.8.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,