@ai-sdk/anthropic 3.0.53 → 3.0.55

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/anthropic",
3
- "version": "3.0.53",
3
+ "version": "3.0.55",
4
4
  "license": "Apache-2.0",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.js",
@@ -238,6 +238,13 @@ export interface AnthropicCodeExecutionToolResultContent {
238
238
  return_code: number;
239
239
  content: Array<{ type: 'code_execution_output'; file_id: string }>;
240
240
  }
241
+ | {
242
+ type: 'encrypted_code_execution_result';
243
+ encrypted_stdout: string;
244
+ stderr: string;
245
+ return_code: number;
246
+ content: Array<{ type: 'code_execution_output'; file_id: string }>;
247
+ }
241
248
  | {
242
249
  type: 'code_execution_tool_result_error';
243
250
  error_code: string;
@@ -416,7 +423,7 @@ export type AnthropicTool =
416
423
  type: 'memory_20250818';
417
424
  }
418
425
  | {
419
- type: 'web_fetch_20250910';
426
+ type: 'web_fetch_20250910' | 'web_fetch_20260209';
420
427
  name: string;
421
428
  max_uses?: number;
422
429
  allowed_domains?: string[];
@@ -426,7 +433,7 @@ export type AnthropicTool =
426
433
  cache_control: AnthropicCacheControl | undefined;
427
434
  }
428
435
  | {
429
- type: 'web_search_20250305';
436
+ type: 'web_search_20250305' | 'web_search_20260209';
430
437
  name: string;
431
438
  max_uses?: number;
432
439
  allowed_domains?: string[];
@@ -622,6 +629,17 @@ export const anthropicMessagesResponseSchema = lazySchema(() =>
622
629
  id: z.string(),
623
630
  name: z.string(),
624
631
  input: z.record(z.string(), z.unknown()).nullish(),
632
+ caller: z
633
+ .union([
634
+ z.object({
635
+ type: z.literal('code_execution_20260120'),
636
+ tool_id: z.string(),
637
+ }),
638
+ z.object({
639
+ type: z.literal('direct'),
640
+ }),
641
+ ])
642
+ .optional(),
625
643
  }),
626
644
  z.object({
627
645
  type: z.literal('mcp_tool_use'),
@@ -712,6 +730,21 @@ export const anthropicMessagesResponseSchema = lazySchema(() =>
712
730
  .optional()
713
731
  .default([]),
714
732
  }),
733
+ z.object({
734
+ type: z.literal('encrypted_code_execution_result'),
735
+ encrypted_stdout: z.string(),
736
+ stderr: z.string(),
737
+ return_code: z.number(),
738
+ content: z
739
+ .array(
740
+ z.object({
741
+ type: z.literal('code_execution_output'),
742
+ file_id: z.string(),
743
+ }),
744
+ )
745
+ .optional()
746
+ .default([]),
747
+ }),
715
748
  z.object({
716
749
  type: z.literal('code_execution_tool_result_error'),
717
750
  error_code: z.string(),
@@ -954,6 +987,17 @@ export const anthropicMessagesChunkSchema = lazySchema(() =>
954
987
  id: z.string(),
955
988
  name: z.string(),
956
989
  input: z.record(z.string(), z.unknown()).nullish(),
990
+ caller: z
991
+ .union([
992
+ z.object({
993
+ type: z.literal('code_execution_20260120'),
994
+ tool_id: z.string(),
995
+ }),
996
+ z.object({
997
+ type: z.literal('direct'),
998
+ }),
999
+ ])
1000
+ .optional(),
957
1001
  }),
958
1002
  z.object({
959
1003
  type: z.literal('mcp_tool_use'),
@@ -1044,6 +1088,21 @@ export const anthropicMessagesChunkSchema = lazySchema(() =>
1044
1088
  .optional()
1045
1089
  .default([]),
1046
1090
  }),
1091
+ z.object({
1092
+ type: z.literal('encrypted_code_execution_result'),
1093
+ encrypted_stdout: z.string(),
1094
+ stderr: z.string(),
1095
+ return_code: z.number(),
1096
+ content: z
1097
+ .array(
1098
+ z.object({
1099
+ type: z.literal('code_execution_output'),
1100
+ file_id: z.string(),
1101
+ }),
1102
+ )
1103
+ .optional()
1104
+ .default([]),
1105
+ }),
1047
1106
  z.object({
1048
1107
  type: z.literal('code_execution_tool_result_error'),
1049
1108
  error_code: z.string(),
@@ -37,6 +37,7 @@ import {
37
37
  anthropicMessagesResponseSchema,
38
38
  AnthropicReasoningMetadata,
39
39
  AnthropicResponseContextManagement,
40
+ AnthropicTool,
40
41
  Citation,
41
42
  } from './anthropic-messages-api';
42
43
  import {
@@ -305,7 +306,9 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
305
306
  'anthropic.bash_20250124': 'bash',
306
307
  'anthropic.memory_20250818': 'memory',
307
308
  'anthropic.web_search_20250305': 'web_search',
309
+ 'anthropic.web_search_20260209': 'web_search',
308
310
  'anthropic.web_fetch_20250910': 'web_fetch',
311
+ 'anthropic.web_fetch_20260209': 'web_fetch',
309
312
  'anthropic.tool_search_regex_20251119': 'tool_search_tool_regex',
310
313
  'anthropic.tool_search_bm25_20251119': 'tool_search_tool_bm25',
311
314
  },
@@ -745,6 +748,10 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
745
748
  ...this.extractCitationDocuments(options.prompt),
746
749
  ];
747
750
 
751
+ const markCodeExecutionDynamic = hasWebTool20260209WithoutCodeExecution(
752
+ args.tools,
753
+ );
754
+
748
755
  const {
749
756
  responseHeaders,
750
757
  value: response,
@@ -898,6 +905,11 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
898
905
  toolName: toolNameMapping.toCustomToolName(part.name),
899
906
  input: JSON.stringify(inputToSerialize),
900
907
  providerExecuted: true,
908
+ // We want this 'code_execution' tool call to be allowed even if the tool is not explicitly provided.
909
+ // Since the validation generally bypasses dynamic tools, we mark this specific tool as dynamic.
910
+ ...(markCodeExecutionDynamic && part.name === 'code_execution'
911
+ ? { dynamic: true }
912
+ : {}),
901
913
  });
902
914
  } else if (
903
915
  part.name === 'tool_search_tool_regex' ||
@@ -1044,6 +1056,19 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
1044
1056
  content: part.content.content ?? [],
1045
1057
  },
1046
1058
  });
1059
+ } else if (part.content.type === 'encrypted_code_execution_result') {
1060
+ content.push({
1061
+ type: 'tool-result',
1062
+ toolCallId: part.tool_use_id,
1063
+ toolName: toolNameMapping.toCustomToolName('code_execution'),
1064
+ result: {
1065
+ type: part.content.type,
1066
+ encrypted_stdout: part.content.encrypted_stdout,
1067
+ stderr: part.content.stderr,
1068
+ return_code: part.content.return_code,
1069
+ content: part.content.content ?? [],
1070
+ },
1071
+ });
1047
1072
  } else if (part.content.type === 'code_execution_tool_result_error') {
1048
1073
  content.push({
1049
1074
  type: 'tool-result',
@@ -1204,6 +1229,10 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
1204
1229
  ...this.extractCitationDocuments(options.prompt),
1205
1230
  ];
1206
1231
 
1232
+ const markCodeExecutionDynamic = hasWebTool20260209WithoutCodeExecution(
1233
+ body.tools,
1234
+ );
1235
+
1207
1236
  const url = this.buildRequestUrl(true);
1208
1237
  const { responseHeaders, value: response } = await postJsonToApi({
1209
1238
  url,
@@ -1438,12 +1467,26 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
1438
1467
  const customToolName =
1439
1468
  toolNameMapping.toCustomToolName(providerToolName);
1440
1469
 
1470
+ // Tools like 'web_fetch_20260209' provide input data here.
1471
+ // Other tools like 'code_execution_20260120' provide input data via deltas.
1472
+ // So we only use this if it's non-empty to avoid conflicts.
1473
+ const finalInput =
1474
+ part.input != null &&
1475
+ typeof part.input === 'object' &&
1476
+ Object.keys(part.input).length > 0
1477
+ ? JSON.stringify(part.input)
1478
+ : '';
1479
+
1441
1480
  contentBlocks[value.index] = {
1442
1481
  type: 'tool-call',
1443
1482
  toolCallId: part.id,
1444
1483
  toolName: customToolName,
1445
- input: '',
1484
+ input: finalInput,
1446
1485
  providerExecuted: true,
1486
+ ...(markCodeExecutionDynamic &&
1487
+ providerToolName === 'code_execution'
1488
+ ? { dynamic: true }
1489
+ : {}),
1447
1490
  firstDelta: true,
1448
1491
  providerToolName: part.name,
1449
1492
  };
@@ -1453,6 +1496,10 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
1453
1496
  id: part.id,
1454
1497
  toolName: customToolName,
1455
1498
  providerExecuted: true,
1499
+ ...(markCodeExecutionDynamic &&
1500
+ providerToolName === 'code_execution'
1501
+ ? { dynamic: true }
1502
+ : {}),
1456
1503
  });
1457
1504
  } else if (
1458
1505
  part.name === 'tool_search_tool_regex' ||
@@ -1588,6 +1635,22 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
1588
1635
  content: part.content.content ?? [],
1589
1636
  },
1590
1637
  });
1638
+ } else if (
1639
+ part.content.type === 'encrypted_code_execution_result'
1640
+ ) {
1641
+ controller.enqueue({
1642
+ type: 'tool-result',
1643
+ toolCallId: part.tool_use_id,
1644
+ toolName:
1645
+ toolNameMapping.toCustomToolName('code_execution'),
1646
+ result: {
1647
+ type: part.content.type,
1648
+ encrypted_stdout: part.content.encrypted_stdout,
1649
+ stderr: part.content.stderr,
1650
+ return_code: part.content.return_code,
1651
+ content: part.content.content ?? [],
1652
+ },
1653
+ });
1591
1654
  } else if (
1592
1655
  part.content.type === 'code_execution_tool_result_error'
1593
1656
  ) {
@@ -1773,6 +1836,10 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
1773
1836
  toolName: contentBlock.toolName,
1774
1837
  input: finalInput,
1775
1838
  providerExecuted: contentBlock.providerExecuted,
1839
+ ...(markCodeExecutionDynamic &&
1840
+ contentBlock.providerToolName === 'code_execution'
1841
+ ? { dynamic: true }
1842
+ : {}),
1776
1843
  ...(contentBlock.caller && {
1777
1844
  providerMetadata: {
1778
1845
  anthropic: {
@@ -2238,6 +2305,31 @@ function getModelCapabilities(modelId: string): {
2238
2305
  }
2239
2306
  }
2240
2307
 
2308
+ function hasWebTool20260209WithoutCodeExecution(
2309
+ tools: AnthropicTool[] | undefined,
2310
+ ): boolean {
2311
+ if (!tools) {
2312
+ return false;
2313
+ }
2314
+ let hasWebTool20260209 = false;
2315
+ let hasCodeExecutionTool = false;
2316
+ for (const tool of tools) {
2317
+ if (
2318
+ 'type' in tool &&
2319
+ (tool.type === 'web_fetch_20260209' ||
2320
+ tool.type === 'web_search_20260209')
2321
+ ) {
2322
+ hasWebTool20260209 = true;
2323
+ continue;
2324
+ }
2325
+ if (tool.name === 'code_execution') {
2326
+ hasCodeExecutionTool = true;
2327
+ break;
2328
+ }
2329
+ }
2330
+ return hasWebTool20260209 && !hasCodeExecutionTool;
2331
+ }
2332
+
2241
2333
  function mapAnthropicResponseContextManagement(
2242
2334
  contextManagement: AnthropicResponseContextManagement | null | undefined,
2243
2335
  ): AnthropicMessageMetadata['contextManagement'] | null {
@@ -6,7 +6,9 @@ import {
6
6
  import { AnthropicTool, AnthropicToolChoice } from './anthropic-messages-api';
7
7
  import { CacheControlValidator } from './get-cache-control';
8
8
  import { textEditor_20250728ArgsSchema } from './tool/text-editor_20250728';
9
+ import { webSearch_20260209ArgsSchema } from './tool/web-search_20260209';
9
10
  import { webSearch_20250305ArgsSchema } from './tool/web-search_20250305';
11
+ import { webFetch_20260209ArgsSchema } from './tool/web-fetch-20260209';
10
12
  import { webFetch_20250910ArgsSchema } from './tool/web-fetch-20250910';
11
13
  import { validateTypes } from '@ai-sdk/provider-utils';
12
14
 
@@ -249,6 +251,24 @@ export async function prepareTools({
249
251
  });
250
252
  break;
251
253
  }
254
+ case 'anthropic.web_fetch_20260209': {
255
+ betas.add('code-execution-web-tools-2026-02-09');
256
+ const args = await validateTypes({
257
+ value: tool.args,
258
+ schema: webFetch_20260209ArgsSchema,
259
+ });
260
+ anthropicTools.push({
261
+ type: 'web_fetch_20260209',
262
+ name: 'web_fetch',
263
+ max_uses: args.maxUses,
264
+ allowed_domains: args.allowedDomains,
265
+ blocked_domains: args.blockedDomains,
266
+ citations: args.citations,
267
+ max_content_tokens: args.maxContentTokens,
268
+ cache_control: undefined,
269
+ });
270
+ break;
271
+ }
252
272
  case 'anthropic.web_search_20250305': {
253
273
  const args = await validateTypes({
254
274
  value: tool.args,
@@ -265,6 +285,23 @@ export async function prepareTools({
265
285
  });
266
286
  break;
267
287
  }
288
+ case 'anthropic.web_search_20260209': {
289
+ betas.add('code-execution-web-tools-2026-02-09');
290
+ const args = await validateTypes({
291
+ value: tool.args,
292
+ schema: webSearch_20260209ArgsSchema,
293
+ });
294
+ anthropicTools.push({
295
+ type: 'web_search_20260209',
296
+ name: 'web_search',
297
+ max_uses: args.maxUses,
298
+ allowed_domains: args.allowedDomains,
299
+ blocked_domains: args.blockedDomains,
300
+ user_location: args.userLocation,
301
+ cache_control: undefined,
302
+ });
303
+ break;
304
+ }
268
305
 
269
306
  case 'anthropic.tool_search_regex_20251119': {
270
307
  betas.add('advanced-tool-use-2025-11-20');
@@ -13,7 +13,9 @@ import { textEditor_20250429 } from './tool/text-editor_20250429';
13
13
  import { textEditor_20250728 } from './tool/text-editor_20250728';
14
14
  import { toolSearchBm25_20251119 } from './tool/tool-search-bm25_20251119';
15
15
  import { toolSearchRegex_20251119 } from './tool/tool-search-regex_20251119';
16
+ import { webFetch_20260209 } from './tool/web-fetch-20260209';
16
17
  import { webFetch_20250910 } from './tool/web-fetch-20250910';
18
+ import { webSearch_20260209 } from './tool/web-search_20260209';
17
19
  import { webSearch_20250305 } from './tool/web-search_20250305';
18
20
 
19
21
  export const anthropicTools = {
@@ -173,6 +175,17 @@ export const anthropicTools = {
173
175
  */
174
176
  webFetch_20250910,
175
177
 
178
+ /**
179
+ * Creates a web fetch tool that gives Claude direct access to real-time web content.
180
+ *
181
+ * @param maxUses - The max_uses parameter limits the number of web fetches performed
182
+ * @param allowedDomains - Only fetch from these domains
183
+ * @param blockedDomains - Never fetch from these domains
184
+ * @param citations - Unlike web search where citations are always enabled, citations are optional for web fetch. Set "citations": {"enabled": true} to enable Claude to cite specific passages from fetched documents.
185
+ * @param maxContentTokens - The max_content_tokens parameter limits the amount of content that will be included in the context.
186
+ */
187
+ webFetch_20260209,
188
+
176
189
  /**
177
190
  * Creates a web search tool that gives Claude direct access to real-time web content.
178
191
  *
@@ -183,6 +196,16 @@ export const anthropicTools = {
183
196
  */
184
197
  webSearch_20250305,
185
198
 
199
+ /**
200
+ * Creates a web search tool that gives Claude direct access to real-time web content.
201
+ *
202
+ * @param maxUses - Maximum number of web searches Claude can perform during the conversation.
203
+ * @param allowedDomains - Optional list of domains that Claude is allowed to search.
204
+ * @param blockedDomains - Optional list of domains that Claude should avoid when searching.
205
+ * @param userLocation - Optional user location information to provide geographically relevant search results.
206
+ */
207
+ webSearch_20260209,
208
+
186
209
  /**
187
210
  * Creates a tool search tool that uses regex patterns to find tools.
188
211
  *
@@ -26,6 +26,7 @@ import { anthropicFilePartProviderOptions } from './anthropic-messages-options';
26
26
  import { CacheControlValidator } from './get-cache-control';
27
27
  import { codeExecution_20250522OutputSchema } from './tool/code-execution_20250522';
28
28
  import { codeExecution_20250825OutputSchema } from './tool/code-execution_20250825';
29
+ import { codeExecution_20260120OutputSchema } from './tool/code-execution_20260120';
29
30
  import { toolSearchRegex_20251119OutputSchema as toolSearchOutputSchema } from './tool/tool-search-regex_20251119';
30
31
  import { webFetch_20250910OutputSchema } from './tool/web-fetch-20250910';
31
32
  import { webSearch_20250305OutputSchema } from './tool/web-search_20250305';
@@ -767,8 +768,9 @@ export async function convertToAnthropicMessagesPrompt({
767
768
  break;
768
769
  }
769
770
 
770
- // to distinguish between code execution 20250522 and 20250825,
771
- // we check if a type property is present in the output.value
771
+ // to distinguish between code execution 20250522, 20250825,
772
+ // and encrypted results (from web_fetch_20260209/web_search_20260209 injection),
773
+ // we check the type property in output.value
772
774
  if (output.value.type === 'code_execution_result') {
773
775
  // code execution 20250522
774
776
  const codeExecutionOutput = await validateTypes({
@@ -788,6 +790,33 @@ export async function convertToAnthropicMessagesPrompt({
788
790
  },
789
791
  cache_control: cacheControl,
790
792
  });
793
+ } else if (
794
+ output.value.type === 'encrypted_code_execution_result'
795
+ ) {
796
+ // code execution 20260120 encrypted result
797
+ const codeExecutionOutput = await validateTypes({
798
+ value: output.value,
799
+ schema: codeExecution_20260120OutputSchema,
800
+ });
801
+
802
+ if (
803
+ codeExecutionOutput.type ===
804
+ 'encrypted_code_execution_result'
805
+ ) {
806
+ anthropicContent.push({
807
+ type: 'code_execution_tool_result',
808
+ tool_use_id: part.toolCallId,
809
+ content: {
810
+ type: codeExecutionOutput.type,
811
+ encrypted_stdout:
812
+ codeExecutionOutput.encrypted_stdout,
813
+ stderr: codeExecutionOutput.stderr,
814
+ return_code: codeExecutionOutput.return_code,
815
+ content: codeExecutionOutput.content ?? [],
816
+ },
817
+ cache_control: cacheControl,
818
+ });
819
+ }
791
820
  } else {
792
821
  // code execution 20250825
793
822
  const codeExecutionOutput = await validateTypes({
@@ -796,7 +825,6 @@ export async function convertToAnthropicMessagesPrompt({
796
825
  });
797
826
 
798
827
  if (codeExecutionOutput.type === 'code_execution_result') {
799
- // Programmatic tool calling result - same format as 20250522
800
828
  anthropicContent.push({
801
829
  type: 'code_execution_tool_result',
802
830
  tool_use_id: part.toolCallId,
@@ -882,6 +910,9 @@ export async function convertToAnthropicMessagesPrompt({
882
910
  break;
883
911
  }
884
912
 
913
+ // ideally we'd switch schema based on the tool version (e.g.
914
+ // web_fetch_20260209 vs web_fetch_20250910), but since both
915
+ // versions share an identical output schema, we use one here.
885
916
  const webFetchOutput = await validateTypes({
886
917
  value: output.value,
887
918
  schema: webFetch_20250910OutputSchema,
@@ -926,6 +957,9 @@ export async function convertToAnthropicMessagesPrompt({
926
957
  break;
927
958
  }
928
959
 
960
+ // ideally we'd switch schema based on the tool version (e.g.
961
+ // web_search_20260209 vs web_search_20250305), but since both
962
+ // versions share an identical output schema, we use one here.
929
963
  const webSearchOutput = await validateTypes({
930
964
  value: output.value,
931
965
  schema: webSearch_20250305OutputSchema,
@@ -23,6 +23,21 @@ export const codeExecution_20260120OutputSchema = lazySchema(() =>
23
23
  .optional()
24
24
  .default([]),
25
25
  }),
26
+ z.object({
27
+ type: z.literal('encrypted_code_execution_result'),
28
+ encrypted_stdout: z.string(),
29
+ stderr: z.string(),
30
+ return_code: z.number(),
31
+ content: z
32
+ .array(
33
+ z.object({
34
+ type: z.literal('code_execution_output'),
35
+ file_id: z.string(),
36
+ }),
37
+ )
38
+ .optional()
39
+ .default([]),
40
+ }),
26
41
  z.object({
27
42
  type: z.literal('bash_code_execution_result'),
28
43
  content: z.array(
@@ -183,6 +198,29 @@ const factory = createProviderToolFactoryWithOutputSchema<
183
198
  */
184
199
  return_code: number;
185
200
 
201
+ /**
202
+ * Output file Id list
203
+ */
204
+ content: Array<{ type: 'code_execution_output'; file_id: string }>;
205
+ }
206
+ | {
207
+ type: 'encrypted_code_execution_result';
208
+
209
+ /**
210
+ * Encrypted output from successful execution
211
+ */
212
+ encrypted_stdout: string;
213
+
214
+ /**
215
+ * Error messages if execution fails
216
+ */
217
+ stderr: string;
218
+
219
+ /**
220
+ * 0 for success, non-zero for failure
221
+ */
222
+ return_code: number;
223
+
186
224
  /**
187
225
  * Output file Id list
188
226
  */
@@ -0,0 +1,145 @@
1
+ import {
2
+ createProviderToolFactoryWithOutputSchema,
3
+ lazySchema,
4
+ zodSchema,
5
+ } from '@ai-sdk/provider-utils';
6
+ import { z } from 'zod/v4';
7
+
8
+ export const webFetch_20260209ArgsSchema = lazySchema(() =>
9
+ zodSchema(
10
+ z.object({
11
+ maxUses: z.number().optional(),
12
+ allowedDomains: z.array(z.string()).optional(),
13
+ blockedDomains: z.array(z.string()).optional(),
14
+ citations: z.object({ enabled: z.boolean() }).optional(),
15
+ maxContentTokens: z.number().optional(),
16
+ }),
17
+ ),
18
+ );
19
+
20
+ export const webFetch_20260209OutputSchema = lazySchema(() =>
21
+ zodSchema(
22
+ z.object({
23
+ type: z.literal('web_fetch_result'),
24
+ url: z.string(),
25
+ content: z.object({
26
+ type: z.literal('document'),
27
+ title: z.string().nullable(),
28
+ citations: z.object({ enabled: z.boolean() }).optional(),
29
+ source: z.union([
30
+ z.object({
31
+ type: z.literal('base64'),
32
+ mediaType: z.literal('application/pdf'),
33
+ data: z.string(),
34
+ }),
35
+ z.object({
36
+ type: z.literal('text'),
37
+ mediaType: z.literal('text/plain'),
38
+ data: z.string(),
39
+ }),
40
+ ]),
41
+ }),
42
+ retrievedAt: z.string().nullable(),
43
+ }),
44
+ ),
45
+ );
46
+
47
+ const webFetch_20260209InputSchema = lazySchema(() =>
48
+ zodSchema(
49
+ z.object({
50
+ url: z.string(),
51
+ }),
52
+ ),
53
+ );
54
+
55
+ const factory = createProviderToolFactoryWithOutputSchema<
56
+ {
57
+ /**
58
+ * The URL to fetch.
59
+ */
60
+ url: string;
61
+ },
62
+ {
63
+ type: 'web_fetch_result';
64
+
65
+ /**
66
+ * Fetched content URL
67
+ */
68
+ url: string;
69
+
70
+ /**
71
+ * Fetched content.
72
+ */
73
+ content: {
74
+ type: 'document';
75
+
76
+ /**
77
+ * Title of the document
78
+ */
79
+ title: string | null;
80
+
81
+ /**
82
+ * Citation configuration for the document
83
+ */
84
+ citations?: { enabled: boolean };
85
+
86
+ source:
87
+ | {
88
+ type: 'base64';
89
+ mediaType: 'application/pdf';
90
+ data: string;
91
+ }
92
+ | {
93
+ type: 'text';
94
+ mediaType: 'text/plain';
95
+ data: string;
96
+ };
97
+ };
98
+
99
+ /**
100
+ * ISO 8601 timestamp when the content was retrieved
101
+ */
102
+ retrievedAt: string | null;
103
+ },
104
+ {
105
+ /**
106
+ * The maxUses parameter limits the number of web fetches performed
107
+ */
108
+ maxUses?: number;
109
+
110
+ /**
111
+ * Only fetch from these domains
112
+ */
113
+ allowedDomains?: string[];
114
+
115
+ /**
116
+ * Never fetch from these domains
117
+ */
118
+ blockedDomains?: string[];
119
+
120
+ /**
121
+ * Unlike web search where citations are always enabled, citations are optional for
122
+ * web fetch. Set "citations": {"enabled": true} to enable Claude to cite specific passages
123
+ * from fetched documents.
124
+ */
125
+ citations?: {
126
+ enabled: boolean;
127
+ };
128
+
129
+ /**
130
+ * The maxContentTokens parameter limits the amount of content that will be included in the context.
131
+ */
132
+ maxContentTokens?: number;
133
+ }
134
+ >({
135
+ id: 'anthropic.web_fetch_20260209',
136
+ inputSchema: webFetch_20260209InputSchema,
137
+ outputSchema: webFetch_20260209OutputSchema,
138
+ supportsDeferredResults: true,
139
+ });
140
+
141
+ export const webFetch_20260209 = (
142
+ args: Parameters<typeof factory>[0] = {}, // default
143
+ ) => {
144
+ return factory(args);
145
+ };