@ai-sdk/anthropic 4.0.0-beta.5 → 4.0.0-beta.67

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 (56) hide show
  1. package/CHANGELOG.md +500 -4
  2. package/README.md +2 -0
  3. package/dist/index.d.ts +265 -68
  4. package/dist/index.js +2636 -1427
  5. package/dist/index.js.map +1 -1
  6. package/dist/internal/index.d.ts +234 -62
  7. package/dist/internal/index.js +2605 -1413
  8. package/dist/internal/index.js.map +1 -1
  9. package/docs/05-anthropic.mdx +303 -20
  10. package/package.json +16 -17
  11. package/src/{anthropic-messages-api.ts → anthropic-api.ts} +158 -17
  12. package/src/anthropic-error.ts +1 -1
  13. package/src/anthropic-files.ts +95 -0
  14. package/src/{anthropic-messages-options.ts → anthropic-language-model-options.ts} +104 -11
  15. package/src/{anthropic-messages-language-model.ts → anthropic-language-model.ts} +494 -96
  16. package/src/anthropic-message-metadata.ts +69 -9
  17. package/src/anthropic-prepare-tools.ts +31 -7
  18. package/src/anthropic-provider.ts +42 -13
  19. package/src/anthropic-tools.ts +31 -0
  20. package/src/convert-anthropic-usage.ts +109 -0
  21. package/src/{convert-to-anthropic-messages-prompt.ts → convert-to-anthropic-prompt.ts} +376 -198
  22. package/src/forward-anthropic-container-id-from-last-step.ts +2 -2
  23. package/src/get-cache-control.ts +5 -2
  24. package/src/index.ts +1 -1
  25. package/src/internal/index.ts +13 -2
  26. package/src/map-anthropic-stop-reason.ts +1 -1
  27. package/src/sanitize-json-schema.ts +203 -0
  28. package/src/skills/anthropic-skills-api.ts +44 -0
  29. package/src/skills/anthropic-skills.ts +132 -0
  30. package/src/tool/advisor_20260301.ts +128 -0
  31. package/src/tool/bash_20241022.ts +84 -13
  32. package/src/tool/bash_20250124.ts +84 -13
  33. package/src/tool/code-execution_20250522.ts +2 -2
  34. package/src/tool/code-execution_20250825.ts +2 -2
  35. package/src/tool/code-execution_20260120.ts +2 -2
  36. package/src/tool/computer_20241022.ts +2 -2
  37. package/src/tool/computer_20250124.ts +2 -2
  38. package/src/tool/computer_20251124.ts +2 -2
  39. package/src/tool/memory_20250818.ts +2 -2
  40. package/src/tool/text-editor_20241022.ts +2 -2
  41. package/src/tool/text-editor_20250124.ts +2 -2
  42. package/src/tool/text-editor_20250429.ts +2 -2
  43. package/src/tool/text-editor_20250728.ts +6 -3
  44. package/src/tool/tool-search-bm25_20251119.ts +2 -2
  45. package/src/tool/tool-search-regex_20251119.ts +2 -2
  46. package/src/tool/web-fetch-20250910.ts +2 -2
  47. package/src/tool/web-fetch-20260209.ts +2 -2
  48. package/src/tool/web-search_20250305.ts +2 -2
  49. package/src/tool/web-search_20260209.ts +2 -2
  50. package/dist/index.d.mts +0 -1090
  51. package/dist/index.mjs +0 -5244
  52. package/dist/index.mjs.map +0 -1
  53. package/dist/internal/index.d.mts +0 -969
  54. package/dist/internal/index.mjs +0 -5136
  55. package/dist/internal/index.mjs.map +0 -1
  56. package/src/convert-anthropic-messages-usage.ts +0 -73
@@ -1,25 +1,38 @@
1
- import { JSONSchema7 } from '@ai-sdk/provider';
2
- import { InferSchema, lazySchema, zodSchema } from '@ai-sdk/provider-utils';
1
+ import type { JSONSchema7 } from '@ai-sdk/provider';
2
+ import {
3
+ lazySchema,
4
+ zodSchema,
5
+ type InferSchema,
6
+ } from '@ai-sdk/provider-utils';
3
7
  import { z } from 'zod/v4';
4
8
 
5
- export type AnthropicMessagesPrompt = {
9
+ export type AnthropicPrompt = {
6
10
  system: Array<AnthropicTextContent> | undefined;
7
11
  messages: AnthropicMessage[];
8
12
  };
9
13
 
10
- export type AnthropicMessage = AnthropicUserMessage | AnthropicAssistantMessage;
14
+ export type AnthropicMessage =
15
+ | AnthropicUserMessage
16
+ | AnthropicAssistantMessage
17
+ | AnthropicSystemMessage;
11
18
 
12
19
  export type AnthropicCacheControl = {
13
20
  type: 'ephemeral';
14
21
  ttl?: '5m' | '1h';
15
22
  };
16
23
 
24
+ export interface AnthropicSystemMessage {
25
+ role: 'system';
26
+ content: Array<AnthropicTextContent>;
27
+ }
28
+
17
29
  export interface AnthropicUserMessage {
18
30
  role: 'user';
19
31
  content: Array<
20
32
  | AnthropicTextContent
21
33
  | AnthropicImageContent
22
34
  | AnthropicDocumentContent
35
+ | AnthropicContainerUploadContent
23
36
  | AnthropicToolResultContent
24
37
  >;
25
38
  }
@@ -38,6 +51,7 @@ export interface AnthropicAssistantMessage {
38
51
  | AnthropicToolSearchToolResultContent
39
52
  | AnthropicBashCodeExecutionToolResultContent
40
53
  | AnthropicTextEditorCodeExecutionToolResultContent
54
+ | AnthropicAdvisorToolResultContent
41
55
  | AnthropicMcpToolUseContent
42
56
  | AnthropicMcpToolResultContent
43
57
  | AnthropicCompactionContent
@@ -87,6 +101,10 @@ type AnthropicContentSource =
87
101
  type: 'text';
88
102
  media_type: 'text/plain';
89
103
  data: string;
104
+ }
105
+ | {
106
+ type: 'file';
107
+ file_id: string;
90
108
  };
91
109
 
92
110
  export interface AnthropicImageContent {
@@ -104,6 +122,12 @@ export interface AnthropicDocumentContent {
104
122
  cache_control: AnthropicCacheControl | undefined;
105
123
  }
106
124
 
125
+ export interface AnthropicContainerUploadContent {
126
+ type: 'container_upload';
127
+ file_id: string;
128
+ cache_control?: never;
129
+ }
130
+
107
131
  /**
108
132
  * The caller information for programmatic tool calling.
109
133
  * Present when a tool is called from within code execution.
@@ -147,7 +171,9 @@ export interface AnthropicServerToolUseContent {
147
171
  | 'text_editor_code_execution'
148
172
  // tool search:
149
173
  | 'tool_search_tool_regex'
150
- | 'tool_search_tool_bm25';
174
+ | 'tool_search_tool_bm25'
175
+ // advisor:
176
+ | 'advisor';
151
177
  input: unknown;
152
178
  cache_control: AnthropicCacheControl | undefined;
153
179
  }
@@ -198,13 +224,18 @@ export interface AnthropicToolResultContent {
198
224
  export interface AnthropicWebSearchToolResultContent {
199
225
  type: 'web_search_tool_result';
200
226
  tool_use_id: string;
201
- content: Array<{
202
- url: string;
203
- title: string | null;
204
- page_age: string | null;
205
- encrypted_content: string;
206
- type: string;
207
- }>;
227
+ content:
228
+ | Array<{
229
+ url: string;
230
+ title: string | null;
231
+ page_age: string | null;
232
+ encrypted_content: string;
233
+ type: string;
234
+ }>
235
+ | {
236
+ type: 'web_search_tool_result_error';
237
+ error_code: string;
238
+ };
208
239
  cache_control: AnthropicCacheControl | undefined;
209
240
  }
210
241
 
@@ -306,6 +337,30 @@ export interface AnthropicBashCodeExecutionToolResultContent {
306
337
  cache_control: AnthropicCacheControl | undefined;
307
338
  }
308
339
 
340
+ export interface AnthropicAdvisorToolResultContent {
341
+ type: 'advisor_tool_result';
342
+ tool_use_id: string;
343
+ content:
344
+ | {
345
+ type: 'advisor_result';
346
+ text: string;
347
+ }
348
+ | {
349
+ type: 'advisor_redacted_result';
350
+ encrypted_content: string;
351
+ }
352
+ | {
353
+ type: 'advisor_tool_result_error';
354
+ /**
355
+ * Available options: `max_uses_exceeded`, `too_many_requests`,
356
+ * `overloaded`, `prompt_too_long`, `execution_time_exceeded`,
357
+ * `unavailable`.
358
+ */
359
+ error_code: string;
360
+ };
361
+ cache_control: AnthropicCacheControl | undefined;
362
+ }
363
+
309
364
  export interface AnthropicWebFetchToolResultContent {
310
365
  type: 'web_fetch_tool_result';
311
366
  tool_use_id: string;
@@ -455,6 +510,16 @@ export type AnthropicTool =
455
510
  | {
456
511
  type: 'tool_search_tool_bm25_20251119';
457
512
  name: string;
513
+ }
514
+ | {
515
+ type: 'advisor_20260301';
516
+ name: 'advisor';
517
+ model: string;
518
+ max_uses?: number;
519
+ caching?: {
520
+ type: 'ephemeral';
521
+ ttl: '5m' | '1h';
522
+ };
458
523
  };
459
524
 
460
525
  export type AnthropicSpeed = 'fast' | 'standard';
@@ -547,9 +612,18 @@ export type AnthropicResponseContextManagement = {
547
612
  applied_edits: AnthropicResponseContextManagementEdit[];
548
613
  };
549
614
 
615
+ const anthropicStopDetailsSchema = z.object({
616
+ type: z.string(),
617
+ category: z.string().nullish(),
618
+ explanation: z.string().nullish(),
619
+ recommended_model: z.string().nullish(),
620
+ });
621
+
622
+ export type AnthropicStopDetails = z.infer<typeof anthropicStopDetailsSchema>;
623
+
550
624
  // limited version of the schema, focussed on what is needed for the implementation
551
625
  // this approach limits breakages when the API changes and increases efficiency
552
- export const anthropicMessagesResponseSchema = lazySchema(() =>
626
+ export const anthropicResponseSchema = lazySchema(() =>
553
627
  zodSchema(
554
628
  z.object({
555
629
  type: z.literal('message'),
@@ -828,10 +902,36 @@ export const anthropicMessagesResponseSchema = lazySchema(() =>
828
902
  }),
829
903
  ]),
830
904
  }),
905
+ // advisor results for advisor_20260301:
906
+ z.object({
907
+ type: z.literal('advisor_tool_result'),
908
+ tool_use_id: z.string(),
909
+ content: z.discriminatedUnion('type', [
910
+ z.object({
911
+ type: z.literal('advisor_result'),
912
+ text: z.string(),
913
+ }),
914
+ z.object({
915
+ type: z.literal('advisor_redacted_result'),
916
+ encrypted_content: z.string(),
917
+ }),
918
+ z.object({
919
+ type: z.literal('advisor_tool_result_error'),
920
+ error_code: z.string(),
921
+ }),
922
+ ]),
923
+ }),
924
+ // Server-side fallback marker. Parsed so the response validates, but
925
+ // dropped from the content output (the AI SDK has no model-hop
926
+ // primitive). The hop remains observable via usage.iterations.
927
+ z.object({
928
+ type: z.literal('fallback'),
929
+ }),
831
930
  ]),
832
931
  ),
833
932
  stop_reason: z.string().nullish(),
834
933
  stop_sequence: z.string().nullish(),
934
+ stop_details: anthropicStopDetailsSchema.nullish(),
835
935
  usage: z.looseObject({
836
936
  input_tokens: z.number(),
837
937
  output_tokens: z.number(),
@@ -840,9 +940,17 @@ export const anthropicMessagesResponseSchema = lazySchema(() =>
840
940
  iterations: z
841
941
  .array(
842
942
  z.object({
843
- type: z.union([z.literal('compaction'), z.literal('message')]),
943
+ type: z.union([
944
+ z.literal('compaction'),
945
+ z.literal('message'),
946
+ z.literal('advisor_message'),
947
+ z.literal('fallback_message'),
948
+ ]),
949
+ model: z.string().nullish(),
844
950
  input_tokens: z.number(),
845
951
  output_tokens: z.number(),
952
+ cache_creation_input_tokens: z.number().nullish(),
953
+ cache_read_input_tokens: z.number().nullish(),
846
954
  }),
847
955
  )
848
956
  .nullish(),
@@ -889,7 +997,7 @@ export const anthropicMessagesResponseSchema = lazySchema(() =>
889
997
 
890
998
  // limited version of the schema, focused on what is needed for the implementation
891
999
  // this approach limits breakages when the API changes and increases efficiency
892
- export const anthropicMessagesChunkSchema = lazySchema(() =>
1000
+ export const anthropicChunkSchema = lazySchema(() =>
893
1001
  zodSchema(
894
1002
  z.discriminatedUnion('type', [
895
1003
  z.object({
@@ -1186,6 +1294,30 @@ export const anthropicMessagesChunkSchema = lazySchema(() =>
1186
1294
  }),
1187
1295
  ]),
1188
1296
  }),
1297
+ // advisor results for advisor_20260301:
1298
+ z.object({
1299
+ type: z.literal('advisor_tool_result'),
1300
+ tool_use_id: z.string(),
1301
+ content: z.discriminatedUnion('type', [
1302
+ z.object({
1303
+ type: z.literal('advisor_result'),
1304
+ text: z.string(),
1305
+ }),
1306
+ z.object({
1307
+ type: z.literal('advisor_redacted_result'),
1308
+ encrypted_content: z.string(),
1309
+ }),
1310
+ z.object({
1311
+ type: z.literal('advisor_tool_result_error'),
1312
+ error_code: z.string(),
1313
+ }),
1314
+ ]),
1315
+ }),
1316
+ // Server-side fallback marker; dropped from content output (see the
1317
+ // response schema). The hop remains observable via usage.iterations.
1318
+ z.object({
1319
+ type: z.literal('fallback'),
1320
+ }),
1189
1321
  ]),
1190
1322
  }),
1191
1323
  z.object({
@@ -1258,6 +1390,7 @@ export const anthropicMessagesChunkSchema = lazySchema(() =>
1258
1390
  delta: z.object({
1259
1391
  stop_reason: z.string().nullish(),
1260
1392
  stop_sequence: z.string().nullish(),
1393
+ stop_details: anthropicStopDetailsSchema.nullish(),
1261
1394
  container: z
1262
1395
  .object({
1263
1396
  expires_at: z.string(),
@@ -1285,9 +1418,17 @@ export const anthropicMessagesChunkSchema = lazySchema(() =>
1285
1418
  iterations: z
1286
1419
  .array(
1287
1420
  z.object({
1288
- type: z.union([z.literal('compaction'), z.literal('message')]),
1421
+ type: z.union([
1422
+ z.literal('compaction'),
1423
+ z.literal('message'),
1424
+ z.literal('advisor_message'),
1425
+ z.literal('fallback_message'),
1426
+ ]),
1427
+ model: z.string().nullish(),
1289
1428
  input_tokens: z.number(),
1290
1429
  output_tokens: z.number(),
1430
+ cache_creation_input_tokens: z.number().nullish(),
1431
+ cache_read_input_tokens: z.number().nullish(),
1291
1432
  }),
1292
1433
  )
1293
1434
  .nullish(),
@@ -1338,7 +1479,7 @@ export type AnthropicReasoningMetadata = InferSchema<
1338
1479
  >;
1339
1480
 
1340
1481
  export type Citation = NonNullable<
1341
- (InferSchema<typeof anthropicMessagesResponseSchema>['content'][number] & {
1482
+ (InferSchema<typeof anthropicResponseSchema>['content'][number] & {
1342
1483
  type: 'text';
1343
1484
  })['citations']
1344
1485
  >[number];
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  createJsonErrorResponseHandler,
3
- InferSchema,
4
3
  lazySchema,
5
4
  zodSchema,
5
+ type InferSchema,
6
6
  } from '@ai-sdk/provider-utils';
7
7
  import { z } from 'zod/v4';
8
8
 
@@ -0,0 +1,95 @@
1
+ import type {
2
+ FilesV4,
3
+ FilesV4UploadFileCallOptions,
4
+ FilesV4UploadFileResult,
5
+ } from '@ai-sdk/provider';
6
+ import {
7
+ combineHeaders,
8
+ convertInlineFileDataToUint8Array,
9
+ createJsonResponseHandler,
10
+ lazySchema,
11
+ postFormDataToApi,
12
+ zodSchema,
13
+ type FetchFunction,
14
+ } from '@ai-sdk/provider-utils';
15
+ import { z } from 'zod/v4';
16
+ import { anthropicFailedResponseHandler } from './anthropic-error';
17
+
18
+ const anthropicUploadFileResponseSchema = lazySchema(() =>
19
+ zodSchema(
20
+ z.object({
21
+ id: z.string(),
22
+ type: z.literal('file'),
23
+ filename: z.string(),
24
+ mime_type: z.string(),
25
+ size_bytes: z.number(),
26
+ created_at: z.string(),
27
+ downloadable: z.boolean().nullish(),
28
+ }),
29
+ ),
30
+ );
31
+
32
+ interface AnthropicFilesConfig {
33
+ provider: string;
34
+ baseURL: string;
35
+ headers: () => Record<string, string | undefined>;
36
+ fetch?: FetchFunction;
37
+ }
38
+
39
+ export class AnthropicFiles implements FilesV4 {
40
+ readonly specificationVersion = 'v4';
41
+
42
+ get provider(): string {
43
+ return this.config.provider;
44
+ }
45
+
46
+ constructor(private readonly config: AnthropicFilesConfig) {}
47
+
48
+ async uploadFile({
49
+ data,
50
+ mediaType,
51
+ filename,
52
+ }: FilesV4UploadFileCallOptions): Promise<FilesV4UploadFileResult> {
53
+ const fileBytes = convertInlineFileDataToUint8Array(data);
54
+
55
+ const blob = new Blob([fileBytes], { type: mediaType });
56
+
57
+ const formData = new FormData();
58
+ if (filename != null) {
59
+ formData.append('file', blob, filename);
60
+ } else {
61
+ formData.append('file', blob);
62
+ }
63
+
64
+ const { value: response } = await postFormDataToApi({
65
+ url: `${this.config.baseURL}/files`,
66
+ headers: combineHeaders(this.config.headers(), {
67
+ 'anthropic-beta': 'files-api-2025-04-14',
68
+ }),
69
+ formData,
70
+ failedResponseHandler: anthropicFailedResponseHandler,
71
+ successfulResponseHandler: createJsonResponseHandler(
72
+ anthropicUploadFileResponseSchema,
73
+ ),
74
+ fetch: this.config.fetch,
75
+ });
76
+
77
+ return {
78
+ warnings: [],
79
+ providerReference: { anthropic: response.id },
80
+ mediaType: response.mime_type ?? mediaType,
81
+ filename: response.filename ?? filename,
82
+ providerMetadata: {
83
+ anthropic: {
84
+ filename: response.filename,
85
+ mimeType: response.mime_type,
86
+ sizeBytes: response.size_bytes,
87
+ createdAt: response.created_at,
88
+ ...(response.downloadable != null
89
+ ? { downloadable: response.downloadable }
90
+ : {}),
91
+ },
92
+ },
93
+ };
94
+ }
95
+ }
@@ -1,7 +1,7 @@
1
1
  import { z } from 'zod/v4';
2
2
 
3
3
  // https://docs.claude.com/en/docs/about-claude/models/overview
4
- export type AnthropicMessagesModelId =
4
+ export type AnthropicModelId =
5
5
  | 'claude-3-haiku-20240307'
6
6
  | 'claude-haiku-4-5-20251001'
7
7
  | 'claude-haiku-4-5'
@@ -17,6 +17,9 @@ export type AnthropicMessagesModelId =
17
17
  | 'claude-sonnet-4-5'
18
18
  | 'claude-sonnet-4-6'
19
19
  | 'claude-opus-4-6'
20
+ | 'claude-opus-4-7'
21
+ | 'claude-opus-4-8'
22
+ | 'claude-fable-5'
20
23
  | (string & {});
21
24
 
22
25
  /**
@@ -24,6 +27,12 @@ export type AnthropicMessagesModelId =
24
27
  * These options apply to individual file parts (documents).
25
28
  */
26
29
  export const anthropicFilePartProviderOptions = z.object({
30
+ /**
31
+ * Upload this file into the code execution container instead of sending it as
32
+ * a normal document or image content block.
33
+ */
34
+ containerUpload: z.boolean().optional(),
35
+
27
36
  /**
28
37
  * Citation configuration for this document.
29
38
  * When enabled, this document will generate citations in the response.
@@ -83,6 +92,12 @@ export const anthropicLanguageModelOptions = z.object({
83
92
  z.object({
84
93
  /** for Sonnet 4.6, Opus 4.6, and newer models */
85
94
  type: z.literal('adaptive'),
95
+ /**
96
+ * Controls whether thinking content is included in the response.
97
+ * - `"omitted"`: Thinking blocks are present but text is empty (default for Opus 4.7+).
98
+ * - `"summarized"`: Thinking content is returned. Required to see reasoning output.
99
+ */
100
+ display: z.enum(['omitted', 'summarized']).optional(),
86
101
  }),
87
102
  z.object({
88
103
  /** for models before Opus 4.6, except Sonnet 4.6 still supports it */
@@ -112,6 +127,23 @@ export const anthropicLanguageModelOptions = z.object({
112
127
  })
113
128
  .optional(),
114
129
 
130
+ /**
131
+ * Metadata to include with the request.
132
+ *
133
+ * See https://platform.claude.com/docs/en/api/messages/create for details.
134
+ */
135
+ metadata: z
136
+ .object({
137
+ /**
138
+ * An external identifier for the user associated with the request.
139
+ *
140
+ * Should be a UUID, hash value, or other opaque identifier.
141
+ * Must not contain PII (name, email, phone number, etc.).
142
+ */
143
+ userId: z.string().optional(),
144
+ })
145
+ .optional(),
146
+
115
147
  /**
116
148
  * MCP servers to be utilized in this request.
117
149
  */
@@ -142,21 +174,29 @@ export const anthropicLanguageModelOptions = z.object({
142
174
  id: z.string().optional(),
143
175
  skills: z
144
176
  .array(
145
- z.object({
146
- type: z.union([z.literal('anthropic'), z.literal('custom')]),
147
- skillId: z.string(),
148
- version: z.string().optional(),
149
- }),
177
+ z.discriminatedUnion('type', [
178
+ z.object({
179
+ type: z.literal('anthropic'),
180
+ skillId: z.string(),
181
+ version: z.string().optional(),
182
+ }),
183
+ z.object({
184
+ type: z.literal('custom'),
185
+ providerReference: z.record(z.string(), z.string()),
186
+ version: z.string().optional(),
187
+ }),
188
+ ]),
150
189
  )
151
190
  .optional(),
152
191
  })
153
192
  .optional(),
154
193
 
155
194
  /**
156
- * Whether to enable tool streaming (and structured output streaming).
157
- *
158
- * When set to false, the model will return all tool calls and results
159
- * at once after a delay.
195
+ * Whether to enable fine-grained (eager) streaming of tool call inputs
196
+ * and structured outputs for every function tool in the request. When
197
+ * true (the default), each function tool receives a default of
198
+ * `eager_input_streaming: true` unless it explicitly sets
199
+ * `providerOptions.anthropic.eagerInputStreaming`.
160
200
  *
161
201
  * @default true
162
202
  */
@@ -165,7 +205,22 @@ export const anthropicLanguageModelOptions = z.object({
165
205
  /**
166
206
  * @default 'high'
167
207
  */
168
- effort: z.enum(['low', 'medium', 'high', 'max']).optional(),
208
+ effort: z.enum(['low', 'medium', 'high', 'xhigh', 'max']).optional(),
209
+
210
+ /**
211
+ * Task budget for agentic turns. Informs the model of the total token budget
212
+ * available for the current task, allowing it to prioritize work and wind down
213
+ * gracefully as the budget is consumed.
214
+ *
215
+ * Advisory only — does not enforce a hard token limit.
216
+ */
217
+ taskBudget: z
218
+ .object({
219
+ type: z.literal('tokens'),
220
+ total: z.number().int().min(20000),
221
+ remaining: z.number().int().min(0).optional(),
222
+ })
223
+ .optional(),
169
224
 
170
225
  /**
171
226
  * Enable fast mode for faster inference (2.5x faster output token speeds).
@@ -173,6 +228,44 @@ export const anthropicLanguageModelOptions = z.object({
173
228
  */
174
229
  speed: z.enum(['fast', 'standard']).optional(),
175
230
 
231
+ /**
232
+ * Controls where model inference runs for this request.
233
+ *
234
+ * - `"global"`: Inference may run in any available geography (default).
235
+ * - `"us"`: Inference runs only in US-based infrastructure.
236
+ *
237
+ * See https://platform.claude.com/docs/en/build-with-claude/data-residency
238
+ */
239
+ inferenceGeo: z.enum(['us', 'global']).optional(),
240
+
241
+ /**
242
+ * Server-side fallback chain.
243
+ *
244
+ * When the primary model's safety classifiers block a turn, the API
245
+ * automatically retries it on the next model in the chain, server-side. A
246
+ * `content-filter` finish reason means the entire chain refused.
247
+ *
248
+ * Each entry is merged into the request as a direct request to that entry's
249
+ * model, so it must be formatted accordingly: `model` is required, and an
250
+ * entry may additionally override `max_tokens`, `thinking`, `output_config`,
251
+ * and `speed` for that attempt only (`speed` additionally requires the speed
252
+ * beta). The value is passed through to the API as-is.
253
+ *
254
+ * The required `server-side-fallback-2026-06-01` beta is added automatically
255
+ * when this option is set.
256
+ */
257
+ fallbacks: z
258
+ .array(
259
+ z.object({
260
+ model: z.string(),
261
+ max_tokens: z.number().int().optional(),
262
+ thinking: z.record(z.string(), z.unknown()).optional(),
263
+ output_config: z.record(z.string(), z.unknown()).optional(),
264
+ speed: z.enum(['fast', 'standard']).optional(),
265
+ }),
266
+ )
267
+ .optional(),
268
+
176
269
  /**
177
270
  * A set of beta features to enable.
178
271
  * Allow a provider to receive the full `betas` set if it needs it.