@fairyhunter13/ai-anthropic 3.0.58-fork.2 → 3.0.58-fork.21
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/CHANGELOG.md +101 -4
- package/dist/index.d.mts +85 -6
- package/dist/index.d.ts +85 -6
- package/dist/index.js +696 -376
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +671 -347
- package/dist/index.mjs.map +1 -1
- package/dist/internal/index.d.mts +124 -14
- package/dist/internal/index.d.ts +124 -14
- package/dist/internal/index.js +690 -368
- package/dist/internal/index.js.map +1 -1
- package/dist/internal/index.mjs +670 -345
- package/dist/internal/index.mjs.map +1 -1
- package/docs/05-anthropic.mdx +53 -6
- package/package.json +7 -7
- package/src/anthropic-messages-api.ts +31 -7
- package/src/anthropic-messages-language-model.ts +272 -36
- package/src/anthropic-messages-options.ts +24 -0
- package/src/anthropic-prepare-tools.ts +50 -14
- package/src/anthropic-provider.ts +8 -8
- package/src/anthropic-tools.ts +18 -0
- package/src/convert-anthropic-messages-usage.ts +2 -2
- package/src/convert-to-anthropic-messages-prompt.ts +47 -27
- package/src/get-cache-control.ts +5 -5
- package/src/internal/index.ts +4 -1
- package/src/map-anthropic-stop-reason.ts +2 -2
- package/src/tool/web-fetch-20260309.ts +182 -0
- package/src/tool/web-search_20260209.ts +17 -0
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
APICallError,
|
|
3
3
|
JSONObject,
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
4
|
+
LanguageModelV4,
|
|
5
|
+
LanguageModelV4CallOptions,
|
|
6
|
+
LanguageModelV4Content,
|
|
7
|
+
LanguageModelV4FinishReason,
|
|
8
|
+
LanguageModelV4FunctionTool,
|
|
9
|
+
LanguageModelV4GenerateResult,
|
|
10
|
+
LanguageModelV4Prompt,
|
|
11
|
+
LanguageModelV4Source,
|
|
12
|
+
LanguageModelV4StreamPart,
|
|
13
|
+
LanguageModelV4StreamResult,
|
|
14
|
+
LanguageModelV4ToolCall,
|
|
15
|
+
SharedV4ProviderMetadata,
|
|
16
|
+
SharedV4Warning,
|
|
17
17
|
} from '@ai-sdk/provider';
|
|
18
18
|
import {
|
|
19
19
|
combineHeaders,
|
|
@@ -29,6 +29,87 @@ import {
|
|
|
29
29
|
Resolvable,
|
|
30
30
|
resolve,
|
|
31
31
|
} from '@ai-sdk/provider-utils';
|
|
32
|
+
|
|
33
|
+
// Inlined from @ai-sdk/provider-utils (4.x) — not available in 3.x provider-utils
|
|
34
|
+
type ReasoningLevel = Exclude<
|
|
35
|
+
LanguageModelV4CallOptions['reasoning'],
|
|
36
|
+
'none' | 'provider-default' | undefined
|
|
37
|
+
>;
|
|
38
|
+
|
|
39
|
+
function isCustomReasoning(
|
|
40
|
+
reasoning: LanguageModelV4CallOptions['reasoning'],
|
|
41
|
+
): reasoning is Exclude<
|
|
42
|
+
LanguageModelV4CallOptions['reasoning'],
|
|
43
|
+
'provider-default' | undefined
|
|
44
|
+
> {
|
|
45
|
+
return reasoning !== undefined && reasoning !== 'provider-default';
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function mapReasoningToProviderEffort<T extends string>({
|
|
49
|
+
reasoning,
|
|
50
|
+
effortMap,
|
|
51
|
+
warnings,
|
|
52
|
+
}: {
|
|
53
|
+
reasoning: ReasoningLevel;
|
|
54
|
+
effortMap: Partial<Record<ReasoningLevel, T>>;
|
|
55
|
+
warnings: SharedV4Warning[];
|
|
56
|
+
}): T | undefined {
|
|
57
|
+
const mapped = effortMap[reasoning];
|
|
58
|
+
if (mapped == null) {
|
|
59
|
+
warnings.push({
|
|
60
|
+
type: 'unsupported',
|
|
61
|
+
feature: 'reasoning',
|
|
62
|
+
details: `reasoning "${reasoning}" is not supported by this model.`,
|
|
63
|
+
});
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
if (mapped !== reasoning) {
|
|
67
|
+
warnings.push({
|
|
68
|
+
type: 'compatibility',
|
|
69
|
+
feature: 'reasoning',
|
|
70
|
+
details: `reasoning "${reasoning}" is not directly supported by this model. mapped to effort "${mapped}".`,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
return mapped;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const DEFAULT_REASONING_BUDGET_PERCENTAGES: Record<ReasoningLevel, number> = {
|
|
77
|
+
minimal: 0.02,
|
|
78
|
+
low: 0.1,
|
|
79
|
+
medium: 0.3,
|
|
80
|
+
high: 0.6,
|
|
81
|
+
xhigh: 0.9,
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
function mapReasoningToProviderBudget({
|
|
85
|
+
reasoning,
|
|
86
|
+
maxOutputTokens,
|
|
87
|
+
maxReasoningBudget,
|
|
88
|
+
minReasoningBudget = 1024,
|
|
89
|
+
budgetPercentages = DEFAULT_REASONING_BUDGET_PERCENTAGES,
|
|
90
|
+
warnings,
|
|
91
|
+
}: {
|
|
92
|
+
reasoning: ReasoningLevel;
|
|
93
|
+
maxOutputTokens: number;
|
|
94
|
+
maxReasoningBudget: number;
|
|
95
|
+
minReasoningBudget?: number;
|
|
96
|
+
budgetPercentages?: Partial<Record<ReasoningLevel, number>>;
|
|
97
|
+
warnings: SharedV4Warning[];
|
|
98
|
+
}): number | undefined {
|
|
99
|
+
const pct = budgetPercentages[reasoning];
|
|
100
|
+
if (pct == null) {
|
|
101
|
+
warnings.push({
|
|
102
|
+
type: 'unsupported',
|
|
103
|
+
feature: 'reasoning',
|
|
104
|
+
details: `reasoning "${reasoning}" is not supported by this model.`,
|
|
105
|
+
});
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
return Math.min(
|
|
109
|
+
maxReasoningBudget,
|
|
110
|
+
Math.max(minReasoningBudget, Math.round(maxOutputTokens * pct)),
|
|
111
|
+
);
|
|
112
|
+
}
|
|
32
113
|
import { anthropicFailedResponseHandler } from './anthropic-error';
|
|
33
114
|
import { AnthropicMessageMetadata } from './anthropic-message-metadata';
|
|
34
115
|
import {
|
|
@@ -42,6 +123,7 @@ import {
|
|
|
42
123
|
} from './anthropic-messages-api';
|
|
43
124
|
import {
|
|
44
125
|
AnthropicMessagesModelId,
|
|
126
|
+
AnthropicLanguageModelOptions,
|
|
45
127
|
anthropicLanguageModelOptions,
|
|
46
128
|
} from './anthropic-messages-options';
|
|
47
129
|
import { prepareTools } from './anthropic-prepare-tools';
|
|
@@ -61,7 +143,7 @@ function createCitationSource(
|
|
|
61
143
|
mediaType: string;
|
|
62
144
|
}>,
|
|
63
145
|
generateId: () => string,
|
|
64
|
-
):
|
|
146
|
+
): LanguageModelV4Source | undefined {
|
|
65
147
|
if (citation.type === 'web_search_result_location') {
|
|
66
148
|
return {
|
|
67
149
|
type: 'source' as const,
|
|
@@ -74,7 +156,7 @@ function createCitationSource(
|
|
|
74
156
|
citedText: citation.cited_text,
|
|
75
157
|
encryptedIndex: citation.encrypted_index,
|
|
76
158
|
},
|
|
77
|
-
} satisfies
|
|
159
|
+
} satisfies SharedV4ProviderMetadata,
|
|
78
160
|
};
|
|
79
161
|
}
|
|
80
162
|
|
|
@@ -108,7 +190,7 @@ function createCitationSource(
|
|
|
108
190
|
startCharIndex: citation.start_char_index,
|
|
109
191
|
endCharIndex: citation.end_char_index,
|
|
110
192
|
},
|
|
111
|
-
} satisfies
|
|
193
|
+
} satisfies SharedV4ProviderMetadata,
|
|
112
194
|
};
|
|
113
195
|
}
|
|
114
196
|
|
|
@@ -122,17 +204,23 @@ type AnthropicMessagesConfig = {
|
|
|
122
204
|
args: Record<string, any>,
|
|
123
205
|
betas: Set<string>,
|
|
124
206
|
) => Record<string, any>;
|
|
125
|
-
supportedUrls?: () =>
|
|
207
|
+
supportedUrls?: () => LanguageModelV4['supportedUrls'];
|
|
126
208
|
generateId?: () => string;
|
|
127
209
|
|
|
128
210
|
/**
|
|
129
211
|
* When false, the model will use JSON tool fallback for structured outputs.
|
|
130
212
|
*/
|
|
131
213
|
supportsNativeStructuredOutput?: boolean;
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* When false, `strict` on tool definitions will be ignored and a warning emitted.
|
|
217
|
+
* Defaults to true.
|
|
218
|
+
*/
|
|
219
|
+
supportsStrictTools?: boolean;
|
|
132
220
|
};
|
|
133
221
|
|
|
134
|
-
export class AnthropicMessagesLanguageModel implements
|
|
135
|
-
readonly specificationVersion = '
|
|
222
|
+
export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
|
|
223
|
+
readonly specificationVersion = 'v4';
|
|
136
224
|
|
|
137
225
|
readonly modelId: AnthropicMessagesModelId;
|
|
138
226
|
|
|
@@ -184,13 +272,14 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
184
272
|
seed,
|
|
185
273
|
tools,
|
|
186
274
|
toolChoice,
|
|
275
|
+
reasoning,
|
|
187
276
|
providerOptions,
|
|
188
277
|
stream,
|
|
189
|
-
}:
|
|
278
|
+
}: LanguageModelV4CallOptions & {
|
|
190
279
|
stream: boolean;
|
|
191
280
|
userSuppliedBetas: Set<string>;
|
|
192
281
|
}) {
|
|
193
|
-
const warnings:
|
|
282
|
+
const warnings: SharedV4Warning[] = [];
|
|
194
283
|
|
|
195
284
|
if (frequencyPenalty != null) {
|
|
196
285
|
warnings.push({ type: 'unsupported', feature: 'frequencyPenalty' });
|
|
@@ -263,6 +352,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
263
352
|
const {
|
|
264
353
|
maxOutputTokens: maxOutputTokensForModel,
|
|
265
354
|
supportsStructuredOutput: modelSupportsStructuredOutput,
|
|
355
|
+
supportsAdaptiveThinking,
|
|
266
356
|
isKnownModel,
|
|
267
357
|
} = getModelCapabilities(this.modelId);
|
|
268
358
|
|
|
@@ -270,13 +360,17 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
270
360
|
(this.config.supportsNativeStructuredOutput ?? true) &&
|
|
271
361
|
modelSupportsStructuredOutput;
|
|
272
362
|
|
|
363
|
+
const supportsStrictTools =
|
|
364
|
+
(this.config.supportsStrictTools ?? true) &&
|
|
365
|
+
modelSupportsStructuredOutput;
|
|
366
|
+
|
|
273
367
|
const structureOutputMode =
|
|
274
368
|
anthropicOptions?.structuredOutputMode ?? 'auto';
|
|
275
369
|
const useStructuredOutput =
|
|
276
370
|
structureOutputMode === 'outputFormat' ||
|
|
277
371
|
(structureOutputMode === 'auto' && supportsStructuredOutput);
|
|
278
372
|
|
|
279
|
-
const jsonResponseTool:
|
|
373
|
+
const jsonResponseTool: LanguageModelV4FunctionTool | undefined =
|
|
280
374
|
responseFormat?.type === 'json' &&
|
|
281
375
|
responseFormat.schema != null &&
|
|
282
376
|
!useStructuredOutput
|
|
@@ -311,6 +405,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
311
405
|
'anthropic.web_search_20250305': 'web_search',
|
|
312
406
|
'anthropic.web_search_20260209': 'web_search',
|
|
313
407
|
'anthropic.web_fetch_20250910': 'web_fetch',
|
|
408
|
+
'anthropic.web_fetch_20260309': 'web_fetch',
|
|
314
409
|
'anthropic.web_fetch_20260209': 'web_fetch',
|
|
315
410
|
'anthropic.tool_search_regex_20251119': 'tool_search_tool_regex',
|
|
316
411
|
'anthropic.tool_search_bm25_20251119': 'tool_search_tool_bm25',
|
|
@@ -326,6 +421,29 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
326
421
|
toolNameMapping,
|
|
327
422
|
});
|
|
328
423
|
|
|
424
|
+
/*
|
|
425
|
+
* Map top-level `reasoning` to Anthropic thinking/effort when provider
|
|
426
|
+
* options don't already specify them. Provider options always take precedence.
|
|
427
|
+
*/
|
|
428
|
+
if (
|
|
429
|
+
isCustomReasoning(reasoning) &&
|
|
430
|
+
anthropicOptions?.thinking == null &&
|
|
431
|
+
anthropicOptions?.effort == null
|
|
432
|
+
) {
|
|
433
|
+
const reasoningConfig = resolveAnthropicReasoningConfig({
|
|
434
|
+
reasoning,
|
|
435
|
+
supportsAdaptiveThinking,
|
|
436
|
+
maxOutputTokensForModel,
|
|
437
|
+
warnings,
|
|
438
|
+
});
|
|
439
|
+
if (reasoningConfig != null) {
|
|
440
|
+
anthropicOptions.thinking = reasoningConfig.thinking;
|
|
441
|
+
if (reasoningConfig.effort != null) {
|
|
442
|
+
anthropicOptions.effort = reasoningConfig.effort;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
329
447
|
// Handle assistant prefill: append a partial assistant message
|
|
330
448
|
if (anthropicOptions?.prefill) {
|
|
331
449
|
const lastMessage =
|
|
@@ -405,9 +523,22 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
405
523
|
...(anthropicOptions?.speed && {
|
|
406
524
|
speed: anthropicOptions.speed,
|
|
407
525
|
}),
|
|
526
|
+
...(anthropicOptions?.metadata && {
|
|
527
|
+
metadata: {
|
|
528
|
+
...(anthropicOptions.metadata.userId && {
|
|
529
|
+
user_id: anthropicOptions.metadata.userId,
|
|
530
|
+
}),
|
|
531
|
+
},
|
|
532
|
+
}),
|
|
533
|
+
...(anthropicOptions?.serviceTier && {
|
|
534
|
+
service_tier: anthropicOptions.serviceTier,
|
|
535
|
+
}),
|
|
408
536
|
...(anthropicOptions?.cacheControl && {
|
|
409
537
|
cache_control: anthropicOptions.cacheControl,
|
|
410
538
|
}),
|
|
539
|
+
...(anthropicOptions?.metadata?.userId != null && {
|
|
540
|
+
metadata: { user_id: anthropicOptions.metadata.userId },
|
|
541
|
+
}),
|
|
411
542
|
|
|
412
543
|
// mcp servers:
|
|
413
544
|
...(anthropicOptions?.mcpServers &&
|
|
@@ -599,7 +730,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
599
730
|
anthropicOptions.container.skills &&
|
|
600
731
|
anthropicOptions.container.skills.length > 0
|
|
601
732
|
) {
|
|
602
|
-
|
|
733
|
+
// code-execution-2025-08-25 is GA — no beta header needed
|
|
603
734
|
betas.add('skills-2025-10-02');
|
|
604
735
|
betas.add('files-api-2025-04-14');
|
|
605
736
|
|
|
@@ -644,6 +775,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
644
775
|
disableParallelToolUse: true,
|
|
645
776
|
cacheControlValidator,
|
|
646
777
|
supportsStructuredOutput: false,
|
|
778
|
+
supportsStrictTools,
|
|
647
779
|
}
|
|
648
780
|
: {
|
|
649
781
|
tools: tools ?? [],
|
|
@@ -651,6 +783,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
651
783
|
disableParallelToolUse: anthropicOptions?.disableParallelToolUse,
|
|
652
784
|
cacheControlValidator,
|
|
653
785
|
supportsStructuredOutput,
|
|
786
|
+
supportsStrictTools,
|
|
654
787
|
},
|
|
655
788
|
);
|
|
656
789
|
|
|
@@ -724,7 +857,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
724
857
|
return this.config.transformRequestBody?.(args, betas) ?? args;
|
|
725
858
|
}
|
|
726
859
|
|
|
727
|
-
private extractCitationDocuments(prompt:
|
|
860
|
+
private extractCitationDocuments(prompt: LanguageModelV4Prompt): Array<{
|
|
728
861
|
title: string;
|
|
729
862
|
filename?: string;
|
|
730
863
|
mediaType: string;
|
|
@@ -768,8 +901,8 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
768
901
|
}
|
|
769
902
|
|
|
770
903
|
async doGenerate(
|
|
771
|
-
options:
|
|
772
|
-
): Promise<
|
|
904
|
+
options: LanguageModelV4CallOptions,
|
|
905
|
+
): Promise<LanguageModelV4GenerateResult> {
|
|
773
906
|
const {
|
|
774
907
|
args,
|
|
775
908
|
warnings,
|
|
@@ -809,8 +942,8 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
809
942
|
fetch: this.config.fetch,
|
|
810
943
|
});
|
|
811
944
|
|
|
812
|
-
const content: Array<
|
|
813
|
-
const mcpToolCalls: Record<string,
|
|
945
|
+
const content: Array<LanguageModelV4Content> = [];
|
|
946
|
+
const mcpToolCalls: Record<string, LanguageModelV4ToolCall> = {};
|
|
814
947
|
const serverToolCalls: Record<string, string> = {}; // tool_use_id -> provider tool name
|
|
815
948
|
let isJsonResponseFromTool = false;
|
|
816
949
|
|
|
@@ -1084,6 +1217,20 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
1084
1217
|
|
|
1085
1218
|
// code execution 20250522:
|
|
1086
1219
|
case 'code_execution_tool_result': {
|
|
1220
|
+
// When code_execution was not explicitly requested (markCodeExecutionDynamic),
|
|
1221
|
+
// intercept ALL results and return a clear error telling the model to use
|
|
1222
|
+
// web_search/web_fetch as direct tool calls instead of wrapping them in Python.
|
|
1223
|
+
if (markCodeExecutionDynamic) {
|
|
1224
|
+
content.push({
|
|
1225
|
+
type: 'tool-result',
|
|
1226
|
+
toolCallId: part.tool_use_id,
|
|
1227
|
+
toolName: toolNameMapping.toCustomToolName('code_execution'),
|
|
1228
|
+
isError: true,
|
|
1229
|
+
result:
|
|
1230
|
+
'STOP: code_execution is disabled. Do NOT wrap web_search or web_fetch in Python code. Call web_search and web_fetch as DIRECT tool calls — they are standalone tools, not Python functions.',
|
|
1231
|
+
});
|
|
1232
|
+
break;
|
|
1233
|
+
}
|
|
1087
1234
|
if (part.content.type === 'code_execution_result') {
|
|
1088
1235
|
content.push({
|
|
1089
1236
|
type: 'tool-result',
|
|
@@ -1128,6 +1275,17 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
1128
1275
|
// code execution 20250825:
|
|
1129
1276
|
case 'bash_code_execution_tool_result':
|
|
1130
1277
|
case 'text_editor_code_execution_tool_result': {
|
|
1278
|
+
if (markCodeExecutionDynamic) {
|
|
1279
|
+
content.push({
|
|
1280
|
+
type: 'tool-result',
|
|
1281
|
+
toolCallId: part.tool_use_id,
|
|
1282
|
+
toolName: toolNameMapping.toCustomToolName('code_execution'),
|
|
1283
|
+
isError: true,
|
|
1284
|
+
result:
|
|
1285
|
+
'STOP: code_execution is disabled. Do NOT wrap web_search or web_fetch in Python code. Call web_search and web_fetch as DIRECT tool calls — they are standalone tools, not Python functions.',
|
|
1286
|
+
});
|
|
1287
|
+
break;
|
|
1288
|
+
}
|
|
1131
1289
|
content.push({
|
|
1132
1290
|
type: 'tool-result',
|
|
1133
1291
|
toolCallId: part.tool_use_id,
|
|
@@ -1235,7 +1393,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
1235
1393
|
) ?? null,
|
|
1236
1394
|
} satisfies AnthropicMessageMetadata;
|
|
1237
1395
|
|
|
1238
|
-
const providerMetadata:
|
|
1396
|
+
const providerMetadata: SharedV4ProviderMetadata = {
|
|
1239
1397
|
anthropic: anthropicMetadata,
|
|
1240
1398
|
};
|
|
1241
1399
|
|
|
@@ -1249,8 +1407,8 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
1249
1407
|
}
|
|
1250
1408
|
|
|
1251
1409
|
async doStream(
|
|
1252
|
-
options:
|
|
1253
|
-
): Promise<
|
|
1410
|
+
options: LanguageModelV4CallOptions,
|
|
1411
|
+
): Promise<LanguageModelV4StreamResult> {
|
|
1254
1412
|
const {
|
|
1255
1413
|
args: body,
|
|
1256
1414
|
warnings,
|
|
@@ -1287,7 +1445,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
1287
1445
|
fetch: this.config.fetch,
|
|
1288
1446
|
});
|
|
1289
1447
|
|
|
1290
|
-
let finishReason:
|
|
1448
|
+
let finishReason: LanguageModelV4FinishReason = {
|
|
1291
1449
|
unified: 'other',
|
|
1292
1450
|
raw: undefined,
|
|
1293
1451
|
};
|
|
@@ -1319,7 +1477,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
1319
1477
|
}
|
|
1320
1478
|
| { type: 'text' | 'reasoning' }
|
|
1321
1479
|
> = {};
|
|
1322
|
-
const mcpToolCalls: Record<string,
|
|
1480
|
+
const mcpToolCalls: Record<string, LanguageModelV4ToolCall> = {};
|
|
1323
1481
|
const serverToolCalls: Record<string, string> = {}; // tool_use_id -> provider tool name
|
|
1324
1482
|
|
|
1325
1483
|
let contextManagement:
|
|
@@ -1353,7 +1511,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
1353
1511
|
const transformedStream = response.pipeThrough(
|
|
1354
1512
|
new TransformStream<
|
|
1355
1513
|
ParseResult<InferSchema<typeof anthropicMessagesChunkSchema>>,
|
|
1356
|
-
|
|
1514
|
+
LanguageModelV4StreamPart
|
|
1357
1515
|
>({
|
|
1358
1516
|
start(controller) {
|
|
1359
1517
|
controller.enqueue({ type: 'stream-start', warnings });
|
|
@@ -1662,6 +1820,18 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
1662
1820
|
|
|
1663
1821
|
// code execution 20250522:
|
|
1664
1822
|
case 'code_execution_tool_result': {
|
|
1823
|
+
if (markCodeExecutionDynamic) {
|
|
1824
|
+
controller.enqueue({
|
|
1825
|
+
type: 'tool-result',
|
|
1826
|
+
toolCallId: part.tool_use_id,
|
|
1827
|
+
toolName:
|
|
1828
|
+
toolNameMapping.toCustomToolName('code_execution'),
|
|
1829
|
+
isError: true,
|
|
1830
|
+
result:
|
|
1831
|
+
'STOP: code_execution is disabled. Do NOT wrap web_search or web_fetch in Python code. Call web_search and web_fetch as DIRECT tool calls — they are standalone tools, not Python functions.',
|
|
1832
|
+
});
|
|
1833
|
+
return;
|
|
1834
|
+
}
|
|
1665
1835
|
if (part.content.type === 'code_execution_result') {
|
|
1666
1836
|
controller.enqueue({
|
|
1667
1837
|
type: 'tool-result',
|
|
@@ -1714,6 +1884,18 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
1714
1884
|
// code execution 20250825:
|
|
1715
1885
|
case 'bash_code_execution_tool_result':
|
|
1716
1886
|
case 'text_editor_code_execution_tool_result': {
|
|
1887
|
+
if (markCodeExecutionDynamic) {
|
|
1888
|
+
controller.enqueue({
|
|
1889
|
+
type: 'tool-result',
|
|
1890
|
+
toolCallId: part.tool_use_id,
|
|
1891
|
+
toolName:
|
|
1892
|
+
toolNameMapping.toCustomToolName('code_execution'),
|
|
1893
|
+
isError: true,
|
|
1894
|
+
result:
|
|
1895
|
+
'STOP: code_execution is disabled. Do NOT wrap web_search or web_fetch in Python code. Call web_search and web_fetch as DIRECT tool calls — they are standalone tools, not Python functions.',
|
|
1896
|
+
});
|
|
1897
|
+
return;
|
|
1898
|
+
}
|
|
1717
1899
|
controller.enqueue({
|
|
1718
1900
|
type: 'tool-result',
|
|
1719
1901
|
toolCallId: part.tool_use_id,
|
|
@@ -2206,7 +2388,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
2206
2388
|
contextManagement,
|
|
2207
2389
|
} satisfies AnthropicMessageMetadata;
|
|
2208
2390
|
|
|
2209
|
-
const providerMetadata:
|
|
2391
|
+
const providerMetadata: SharedV4ProviderMetadata = {
|
|
2210
2392
|
anthropic: anthropicMetadata,
|
|
2211
2393
|
};
|
|
2212
2394
|
|
|
@@ -2289,9 +2471,10 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
2289
2471
|
* @see https://docs.claude.com/en/docs/about-claude/models/overview#model-comparison-table
|
|
2290
2472
|
* @see https://platform.claude.com/docs/en/build-with-claude/structured-outputs
|
|
2291
2473
|
*/
|
|
2292
|
-
function getModelCapabilities(modelId: string): {
|
|
2474
|
+
export function getModelCapabilities(modelId: string): {
|
|
2293
2475
|
maxOutputTokens: number;
|
|
2294
2476
|
supportsStructuredOutput: boolean;
|
|
2477
|
+
supportsAdaptiveThinking: boolean;
|
|
2295
2478
|
isKnownModel: boolean;
|
|
2296
2479
|
} {
|
|
2297
2480
|
if (
|
|
@@ -2301,6 +2484,7 @@ function getModelCapabilities(modelId: string): {
|
|
|
2301
2484
|
return {
|
|
2302
2485
|
maxOutputTokens: 128000,
|
|
2303
2486
|
supportsStructuredOutput: true,
|
|
2487
|
+
supportsAdaptiveThinking: true,
|
|
2304
2488
|
isKnownModel: true,
|
|
2305
2489
|
};
|
|
2306
2490
|
} else if (
|
|
@@ -2311,36 +2495,42 @@ function getModelCapabilities(modelId: string): {
|
|
|
2311
2495
|
return {
|
|
2312
2496
|
maxOutputTokens: 64000,
|
|
2313
2497
|
supportsStructuredOutput: true,
|
|
2498
|
+
supportsAdaptiveThinking: false,
|
|
2314
2499
|
isKnownModel: true,
|
|
2315
2500
|
};
|
|
2316
2501
|
} else if (modelId.includes('claude-opus-4-1')) {
|
|
2317
2502
|
return {
|
|
2318
2503
|
maxOutputTokens: 32000,
|
|
2319
2504
|
supportsStructuredOutput: true,
|
|
2505
|
+
supportsAdaptiveThinking: false,
|
|
2320
2506
|
isKnownModel: true,
|
|
2321
2507
|
};
|
|
2322
2508
|
} else if (modelId.includes('claude-sonnet-4-')) {
|
|
2323
2509
|
return {
|
|
2324
2510
|
maxOutputTokens: 64000,
|
|
2325
2511
|
supportsStructuredOutput: false,
|
|
2512
|
+
supportsAdaptiveThinking: false,
|
|
2326
2513
|
isKnownModel: true,
|
|
2327
2514
|
};
|
|
2328
2515
|
} else if (modelId.includes('claude-opus-4-')) {
|
|
2329
2516
|
return {
|
|
2330
2517
|
maxOutputTokens: 32000,
|
|
2331
2518
|
supportsStructuredOutput: false,
|
|
2519
|
+
supportsAdaptiveThinking: false,
|
|
2332
2520
|
isKnownModel: true,
|
|
2333
2521
|
};
|
|
2334
2522
|
} else if (modelId.includes('claude-3-haiku')) {
|
|
2335
2523
|
return {
|
|
2336
2524
|
maxOutputTokens: 4096,
|
|
2337
2525
|
supportsStructuredOutput: false,
|
|
2526
|
+
supportsAdaptiveThinking: false,
|
|
2338
2527
|
isKnownModel: true,
|
|
2339
2528
|
};
|
|
2340
2529
|
} else {
|
|
2341
2530
|
return {
|
|
2342
2531
|
maxOutputTokens: 4096,
|
|
2343
2532
|
supportsStructuredOutput: false,
|
|
2533
|
+
supportsAdaptiveThinking: false,
|
|
2344
2534
|
isKnownModel: false,
|
|
2345
2535
|
};
|
|
2346
2536
|
}
|
|
@@ -2371,6 +2561,52 @@ function hasWebTool20260209WithoutCodeExecution(
|
|
|
2371
2561
|
return hasWebTool20260209 && !hasCodeExecutionTool;
|
|
2372
2562
|
}
|
|
2373
2563
|
|
|
2564
|
+
function resolveAnthropicReasoningConfig({
|
|
2565
|
+
reasoning,
|
|
2566
|
+
supportsAdaptiveThinking,
|
|
2567
|
+
maxOutputTokensForModel,
|
|
2568
|
+
warnings,
|
|
2569
|
+
}: {
|
|
2570
|
+
reasoning: LanguageModelV4CallOptions['reasoning'];
|
|
2571
|
+
supportsAdaptiveThinking: boolean;
|
|
2572
|
+
maxOutputTokensForModel: number;
|
|
2573
|
+
warnings: SharedV4Warning[];
|
|
2574
|
+
}): Pick<AnthropicLanguageModelOptions, 'thinking' | 'effort'> | undefined {
|
|
2575
|
+
if (!isCustomReasoning(reasoning)) {
|
|
2576
|
+
return undefined;
|
|
2577
|
+
}
|
|
2578
|
+
|
|
2579
|
+
if (reasoning === 'none') {
|
|
2580
|
+
return { thinking: { type: 'disabled' } };
|
|
2581
|
+
}
|
|
2582
|
+
|
|
2583
|
+
if (supportsAdaptiveThinking) {
|
|
2584
|
+
const effort = mapReasoningToProviderEffort({
|
|
2585
|
+
reasoning,
|
|
2586
|
+
effortMap: {
|
|
2587
|
+
minimal: 'low' as const,
|
|
2588
|
+
low: 'low' as const,
|
|
2589
|
+
medium: 'medium' as const,
|
|
2590
|
+
high: 'high' as const,
|
|
2591
|
+
xhigh: 'max' as const,
|
|
2592
|
+
},
|
|
2593
|
+
warnings,
|
|
2594
|
+
});
|
|
2595
|
+
return { thinking: { type: 'adaptive' }, effort };
|
|
2596
|
+
}
|
|
2597
|
+
|
|
2598
|
+
const budgetTokens = mapReasoningToProviderBudget({
|
|
2599
|
+
reasoning,
|
|
2600
|
+
maxOutputTokens: maxOutputTokensForModel,
|
|
2601
|
+
maxReasoningBudget: maxOutputTokensForModel,
|
|
2602
|
+
warnings,
|
|
2603
|
+
});
|
|
2604
|
+
if (budgetTokens == null) {
|
|
2605
|
+
return undefined;
|
|
2606
|
+
}
|
|
2607
|
+
return { thinking: { type: 'enabled', budgetTokens } };
|
|
2608
|
+
}
|
|
2609
|
+
|
|
2374
2610
|
function mapAnthropicResponseContextManagement(
|
|
2375
2611
|
contextManagement: AnthropicResponseContextManagement | null | undefined,
|
|
2376
2612
|
): AnthropicMessageMetadata['contextManagement'] | null {
|
|
@@ -124,6 +124,23 @@ export const anthropicLanguageModelOptions = z.object({
|
|
|
124
124
|
})
|
|
125
125
|
.optional(),
|
|
126
126
|
|
|
127
|
+
/**
|
|
128
|
+
* Metadata to include with the request.
|
|
129
|
+
*
|
|
130
|
+
* See https://platform.claude.com/docs/en/api/messages/create for details.
|
|
131
|
+
*/
|
|
132
|
+
metadata: z
|
|
133
|
+
.object({
|
|
134
|
+
/**
|
|
135
|
+
* An external identifier for the user associated with the request.
|
|
136
|
+
*
|
|
137
|
+
* Should be a UUID, hash value, or other opaque identifier.
|
|
138
|
+
* Must not contain PII (name, email, phone number, etc.).
|
|
139
|
+
*/
|
|
140
|
+
userId: z.string().optional(),
|
|
141
|
+
})
|
|
142
|
+
.optional(),
|
|
143
|
+
|
|
127
144
|
/**
|
|
128
145
|
* MCP servers to be utilized in this request.
|
|
129
146
|
*/
|
|
@@ -200,6 +217,13 @@ export const anthropicLanguageModelOptions = z.object({
|
|
|
200
217
|
*/
|
|
201
218
|
prefill: z.string().optional(),
|
|
202
219
|
|
|
220
|
+
/**
|
|
221
|
+
* Service tier selection.
|
|
222
|
+
* - 'auto': Allow Anthropic to pick standard or priority based on availability.
|
|
223
|
+
* See https://docs.anthropic.com/en/api/messages
|
|
224
|
+
*/
|
|
225
|
+
serviceTier: z.enum(['auto']).optional(),
|
|
226
|
+
|
|
203
227
|
contextManagement: z
|
|
204
228
|
.object({
|
|
205
229
|
edits: z.array(
|