@ai-sdk/anthropic 4.0.58 → 4.0.60
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 +18 -0
- package/dist/index.d.ts +77 -2
- package/dist/index.js +1005 -556
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +99 -2
- package/dist/internal/index.js +955 -507
- package/dist/internal/index.js.map +1 -1
- package/docs/05-anthropic.mdx +176 -14
- package/package.json +1 -1
- package/src/anthropic-api.ts +46 -0
- package/src/anthropic-batch.ts +3 -0
- package/src/anthropic-language-model-options.ts +32 -3
- package/src/anthropic-language-model.ts +315 -5
- package/src/anthropic-message-metadata.ts +14 -0
- package/src/anthropic-prepare-tools.ts +76 -0
- package/src/anthropic-tools.ts +25 -0
- package/src/convert-to-anthropic-prompt.ts +74 -1
- package/src/tool/computer-toolset_20260801.ts +165 -0
|
@@ -195,6 +195,48 @@ function getAnthropicCallerMetadata(
|
|
|
195
195
|
: { providerMetadata: { anthropic: { caller: callerInfo } } };
|
|
196
196
|
}
|
|
197
197
|
|
|
198
|
+
/**
|
|
199
|
+
* Maps the custom tool names of toolset tools (e.g. the computer toolset) to
|
|
200
|
+
* the toolset name that the Anthropic API uses in `toolset_name`.
|
|
201
|
+
*/
|
|
202
|
+
function getAnthropicToolsetNames(
|
|
203
|
+
tools: LanguageModelV4CallOptions['tools'],
|
|
204
|
+
): Record<string, string> {
|
|
205
|
+
const toolsetNames: Record<string, string> = {};
|
|
206
|
+
|
|
207
|
+
for (const tool of tools ?? []) {
|
|
208
|
+
if (
|
|
209
|
+
tool.type === 'provider' &&
|
|
210
|
+
tool.id === 'anthropic.computer_toolset_20260801'
|
|
211
|
+
) {
|
|
212
|
+
toolsetNames[tool.name] = 'computer';
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return toolsetNames;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Toolset member calls (e.g. `left_click` from the computer toolset) are
|
|
221
|
+
* exposed as a single tool call on the toolset tool. The member name is
|
|
222
|
+
* injected as the `action` property, matching the input shape of the older
|
|
223
|
+
* computer tool versions.
|
|
224
|
+
*/
|
|
225
|
+
function toToolsetMemberInput({
|
|
226
|
+
memberName,
|
|
227
|
+
input,
|
|
228
|
+
}: {
|
|
229
|
+
memberName: string;
|
|
230
|
+
input: unknown;
|
|
231
|
+
}): JSONObject {
|
|
232
|
+
return {
|
|
233
|
+
action: memberName,
|
|
234
|
+
...(typeof input === 'object' && input !== null && !Array.isArray(input)
|
|
235
|
+
? (input as JSONObject)
|
|
236
|
+
: {}),
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
|
|
198
240
|
function getProviderOptionsName(provider: string): string {
|
|
199
241
|
const dotIndex = provider.indexOf('.');
|
|
200
242
|
return dotIndex === -1 ? provider : provider.substring(0, dotIndex);
|
|
@@ -362,6 +404,8 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
362
404
|
rejectsSamplingParameters,
|
|
363
405
|
supportsXhighEffort,
|
|
364
406
|
rejectsThinkingDisabledAboveHighEffort,
|
|
407
|
+
rejectsThinkingDisabled,
|
|
408
|
+
rejectsForcedToolUse,
|
|
365
409
|
isKnownModel,
|
|
366
410
|
} = getModelCapabilities(modelId);
|
|
367
411
|
|
|
@@ -414,10 +458,30 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
414
458
|
|
|
415
459
|
const structureOutputMode =
|
|
416
460
|
anthropicOptions?.structuredOutputMode ?? 'auto';
|
|
417
|
-
|
|
461
|
+
let useStructuredOutput =
|
|
418
462
|
structureOutputMode === 'outputFormat' ||
|
|
419
463
|
(structureOutputMode === 'auto' && supportsStructuredOutput);
|
|
420
464
|
|
|
465
|
+
// The JSON response tool relies on forced tool use, which some models
|
|
466
|
+
// reject (e.g. Opus 5.5, Fable 5.1). Fall back to native structured
|
|
467
|
+
// outputs when the model supports them.
|
|
468
|
+
if (
|
|
469
|
+
!useStructuredOutput &&
|
|
470
|
+
rejectsForcedToolUse &&
|
|
471
|
+
supportsStructuredOutput &&
|
|
472
|
+
responseFormat?.type === 'json' &&
|
|
473
|
+
responseFormat.schema != null
|
|
474
|
+
) {
|
|
475
|
+
warnings.push({
|
|
476
|
+
type: 'unsupported',
|
|
477
|
+
feature: 'providerOptions.anthropic.structuredOutputMode',
|
|
478
|
+
details:
|
|
479
|
+
`structuredOutputMode 'jsonTool' is not supported by ${modelId} because it rejects forced tool use. ` +
|
|
480
|
+
`Using 'outputFormat' instead.`,
|
|
481
|
+
});
|
|
482
|
+
useStructuredOutput = true;
|
|
483
|
+
}
|
|
484
|
+
|
|
421
485
|
const jsonResponseTool: LanguageModelV4FunctionTool | undefined =
|
|
422
486
|
responseFormat?.type === 'json' &&
|
|
423
487
|
responseFormat.schema != null &&
|
|
@@ -456,6 +520,8 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
456
520
|
'anthropic.code_execution_20260120': 'code_execution',
|
|
457
521
|
'anthropic.computer_20241022': 'computer',
|
|
458
522
|
'anthropic.computer_20250124': 'computer',
|
|
523
|
+
'anthropic.computer_20251124': 'computer',
|
|
524
|
+
'anthropic.computer_toolset_20260801': 'computer',
|
|
459
525
|
'anthropic.text_editor_20241022': 'str_replace_editor',
|
|
460
526
|
'anthropic.text_editor_20250124': 'str_replace_editor',
|
|
461
527
|
'anthropic.text_editor_20250429': 'str_replace_based_edit_tool',
|
|
@@ -475,12 +541,15 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
475
541
|
},
|
|
476
542
|
});
|
|
477
543
|
|
|
544
|
+
const toolsetNames = getAnthropicToolsetNames(tools);
|
|
545
|
+
|
|
478
546
|
const { prompt: messagesPrompt, betas } = await convertToAnthropicPrompt({
|
|
479
547
|
prompt,
|
|
480
548
|
sendReasoning: anthropicOptions?.sendReasoning ?? true,
|
|
481
549
|
warnings,
|
|
482
550
|
cacheControlValidator,
|
|
483
551
|
toolNameMapping,
|
|
552
|
+
toolsetNames,
|
|
484
553
|
});
|
|
485
554
|
|
|
486
555
|
/*
|
|
@@ -490,8 +559,10 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
490
559
|
if (isCustomReasoning(reasoning) && anthropicOptions?.effort == null) {
|
|
491
560
|
const reasoningConfig = resolveAnthropicReasoningConfig({
|
|
492
561
|
reasoning,
|
|
562
|
+
modelId,
|
|
493
563
|
supportsAdaptiveThinking,
|
|
494
564
|
supportsXhighEffort,
|
|
565
|
+
rejectsThinkingDisabled,
|
|
495
566
|
maxOutputTokensForModel,
|
|
496
567
|
warnings,
|
|
497
568
|
});
|
|
@@ -508,6 +579,33 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
508
579
|
}
|
|
509
580
|
}
|
|
510
581
|
|
|
582
|
+
// Some models always run adaptive thinking and reject `disabled` and
|
|
583
|
+
// budget-based `enabled` thinking with a 400. Drop the unsupported
|
|
584
|
+
// setting and keep the request adaptive so it still succeeds.
|
|
585
|
+
if (rejectsThinkingDisabled && anthropicOptions?.thinking != null) {
|
|
586
|
+
const thinking = anthropicOptions.thinking;
|
|
587
|
+
|
|
588
|
+
if (thinking.type === 'disabled') {
|
|
589
|
+
warnings.push({
|
|
590
|
+
type: 'unsupported',
|
|
591
|
+
feature: 'providerOptions.anthropic.thinking',
|
|
592
|
+
details:
|
|
593
|
+
`thinking cannot be disabled for ${modelId}; it always uses adaptive thinking. ` +
|
|
594
|
+
`The thinking setting has been removed. Lower 'effort' to reduce thinking.`,
|
|
595
|
+
});
|
|
596
|
+
anthropicOptions.thinking = undefined;
|
|
597
|
+
} else if (thinking.type === 'enabled') {
|
|
598
|
+
warnings.push({
|
|
599
|
+
type: 'unsupported',
|
|
600
|
+
feature: 'providerOptions.anthropic.thinking',
|
|
601
|
+
details:
|
|
602
|
+
`budget-based thinking is not supported by ${modelId}; it always uses adaptive thinking. ` +
|
|
603
|
+
`Using adaptive thinking instead. Use 'effort' to control how much the model thinks.`,
|
|
604
|
+
});
|
|
605
|
+
anthropicOptions.thinking = { type: 'adaptive' };
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
|
|
511
609
|
// Newer models only allow disabling thinking at effort levels up to and
|
|
512
610
|
// including `high`; at `xhigh` and `max` the API returns a 400. Lower
|
|
513
611
|
// the effort to `high` to preserve the explicit request to run without
|
|
@@ -671,6 +769,16 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
671
769
|
system: messagesPrompt.system,
|
|
672
770
|
messages: messagesPrompt.messages,
|
|
673
771
|
|
|
772
|
+
...(anthropicOptions?.safeguards &&
|
|
773
|
+
anthropicOptions.safeguards.length > 0 && {
|
|
774
|
+
safeguards: anthropicOptions.safeguards.map(safeguard => ({
|
|
775
|
+
type: safeguard.type,
|
|
776
|
+
...(safeguard.classifierContext !== undefined && {
|
|
777
|
+
classifier_context: safeguard.classifierContext,
|
|
778
|
+
}),
|
|
779
|
+
})),
|
|
780
|
+
}),
|
|
781
|
+
|
|
674
782
|
...(contextManagement && {
|
|
675
783
|
context_management: {
|
|
676
784
|
edits: contextManagement.edits
|
|
@@ -810,6 +918,13 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
810
918
|
betas.add('mcp-client-2025-04-04');
|
|
811
919
|
}
|
|
812
920
|
|
|
921
|
+
if (
|
|
922
|
+
anthropicOptions?.safeguards &&
|
|
923
|
+
anthropicOptions.safeguards.length > 0
|
|
924
|
+
) {
|
|
925
|
+
betas.add('dangerous-tool-use-2026-09-03');
|
|
926
|
+
}
|
|
927
|
+
|
|
813
928
|
if (contextManagement) {
|
|
814
929
|
betas.add('context-management-2025-06-27');
|
|
815
930
|
|
|
@@ -886,6 +1001,7 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
886
1001
|
supportsStructuredOutput: false,
|
|
887
1002
|
supportsStrictTools,
|
|
888
1003
|
defaultEagerInputStreaming,
|
|
1004
|
+
rejectsForcedToolUse,
|
|
889
1005
|
}
|
|
890
1006
|
: {
|
|
891
1007
|
tools: tools ?? [],
|
|
@@ -895,6 +1011,7 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
895
1011
|
supportsStructuredOutput,
|
|
896
1012
|
supportsStrictTools,
|
|
897
1013
|
defaultEagerInputStreaming,
|
|
1014
|
+
rejectsForcedToolUse,
|
|
898
1015
|
},
|
|
899
1016
|
);
|
|
900
1017
|
|
|
@@ -1167,6 +1284,27 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
1167
1284
|
type: 'text',
|
|
1168
1285
|
text: JSON.stringify(part.input),
|
|
1169
1286
|
});
|
|
1287
|
+
} else if (part.toolset_name != null) {
|
|
1288
|
+
// toolset member calls (e.g. the computer toolset) are mapped to
|
|
1289
|
+
// the toolset tool with the member name as the `action`:
|
|
1290
|
+
content.push({
|
|
1291
|
+
type: 'tool-call',
|
|
1292
|
+
toolCallId: part.id,
|
|
1293
|
+
toolName: toolNameMapping.toCustomToolName(part.toolset_name),
|
|
1294
|
+
input: JSON.stringify(
|
|
1295
|
+
toToolsetMemberInput({
|
|
1296
|
+
memberName: part.name,
|
|
1297
|
+
input: part.input,
|
|
1298
|
+
}),
|
|
1299
|
+
),
|
|
1300
|
+
providerMetadata: {
|
|
1301
|
+
anthropic: {
|
|
1302
|
+
toolsetName: part.toolset_name,
|
|
1303
|
+
...getAnthropicCallerMetadata(part.caller).providerMetadata
|
|
1304
|
+
?.anthropic,
|
|
1305
|
+
},
|
|
1306
|
+
},
|
|
1307
|
+
});
|
|
1170
1308
|
} else {
|
|
1171
1309
|
content.push({
|
|
1172
1310
|
type: 'tool-call',
|
|
@@ -1560,6 +1698,9 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
1560
1698
|
...(response.input_transformations != null
|
|
1561
1699
|
? { inputTransformations: response.input_transformations }
|
|
1562
1700
|
: {}),
|
|
1701
|
+
...(response.safeguard_results != null
|
|
1702
|
+
? { safeguardResults: response.safeguard_results }
|
|
1703
|
+
: {}),
|
|
1563
1704
|
|
|
1564
1705
|
iterations: response.usage.iterations
|
|
1565
1706
|
? response.usage.iterations.map(
|
|
@@ -1676,6 +1817,12 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
1676
1817
|
firstDelta: boolean;
|
|
1677
1818
|
providerToolName?: string;
|
|
1678
1819
|
providerToolInputType?: string;
|
|
1820
|
+
/**
|
|
1821
|
+
* Set for toolset member calls (e.g. the computer toolset). The raw
|
|
1822
|
+
* member input is accumulated and emitted as a single delta with the
|
|
1823
|
+
* member name injected as `action` when the block completes.
|
|
1824
|
+
*/
|
|
1825
|
+
toolset?: { name: string; memberName: string };
|
|
1679
1826
|
caller?: {
|
|
1680
1827
|
type:
|
|
1681
1828
|
| 'code_execution_20250825'
|
|
@@ -1697,6 +1844,7 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
1697
1844
|
let stopSequence: string | null = null;
|
|
1698
1845
|
let stopDetails: AnthropicMessageMetadata['stopDetails'] = undefined;
|
|
1699
1846
|
let inputTransformations: AnthropicMessageMetadata['inputTransformations'];
|
|
1847
|
+
let safeguardResults: AnthropicMessageMetadata['safeguardResults'];
|
|
1700
1848
|
let container: AnthropicMessageMetadata['container'] | null = null;
|
|
1701
1849
|
let isJsonResponseFromTool = false;
|
|
1702
1850
|
let isMessageOpen = false;
|
|
@@ -1841,6 +1989,34 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
1841
1989
|
type: 'text-start',
|
|
1842
1990
|
id: String(value.index),
|
|
1843
1991
|
});
|
|
1992
|
+
} else if (part.toolset_name != null) {
|
|
1993
|
+
const callerInfo = getAnthropicCallerInfo(part.caller);
|
|
1994
|
+
const customToolName = toolNameMapping.toCustomToolName(
|
|
1995
|
+
part.toolset_name,
|
|
1996
|
+
);
|
|
1997
|
+
const hasNonEmptyInput =
|
|
1998
|
+
part.input && Object.keys(part.input).length > 0;
|
|
1999
|
+
|
|
2000
|
+
// toolset member input is accumulated and emitted when the
|
|
2001
|
+
// block completes (see content_block_stop):
|
|
2002
|
+
contentBlocks[value.index] = {
|
|
2003
|
+
type: 'tool-call',
|
|
2004
|
+
toolCallId: part.id,
|
|
2005
|
+
toolName: customToolName,
|
|
2006
|
+
input: hasNonEmptyInput ? JSON.stringify(part.input) : '',
|
|
2007
|
+
firstDelta: true,
|
|
2008
|
+
toolset: {
|
|
2009
|
+
name: part.toolset_name,
|
|
2010
|
+
memberName: part.name,
|
|
2011
|
+
},
|
|
2012
|
+
...(callerInfo && { caller: callerInfo }),
|
|
2013
|
+
};
|
|
2014
|
+
|
|
2015
|
+
controller.enqueue({
|
|
2016
|
+
type: 'tool-input-start',
|
|
2017
|
+
id: part.id,
|
|
2018
|
+
toolName: customToolName,
|
|
2019
|
+
});
|
|
1844
2020
|
} else {
|
|
1845
2021
|
const callerInfo = getAnthropicCallerInfo(part.caller);
|
|
1846
2022
|
|
|
@@ -2331,6 +2507,37 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
2331
2507
|
usesJsonResponseTool && contentBlock.toolName === 'json';
|
|
2332
2508
|
|
|
2333
2509
|
if (!isJsonResponseTool) {
|
|
2510
|
+
// toolset member calls: emit the accumulated input with
|
|
2511
|
+
// the member name injected as `action` in one delta.
|
|
2512
|
+
if (contentBlock.toolset != null) {
|
|
2513
|
+
let memberInput: unknown = {};
|
|
2514
|
+
try {
|
|
2515
|
+
memberInput =
|
|
2516
|
+
contentBlock.input === ''
|
|
2517
|
+
? {}
|
|
2518
|
+
: secureJsonParse(contentBlock.input);
|
|
2519
|
+
} catch {
|
|
2520
|
+
// ignore parse errors, fall back to the raw input
|
|
2521
|
+
memberInput = undefined;
|
|
2522
|
+
}
|
|
2523
|
+
|
|
2524
|
+
contentBlock.input =
|
|
2525
|
+
memberInput === undefined
|
|
2526
|
+
? contentBlock.input
|
|
2527
|
+
: JSON.stringify(
|
|
2528
|
+
toToolsetMemberInput({
|
|
2529
|
+
memberName: contentBlock.toolset.memberName,
|
|
2530
|
+
input: memberInput,
|
|
2531
|
+
}),
|
|
2532
|
+
);
|
|
2533
|
+
|
|
2534
|
+
controller.enqueue({
|
|
2535
|
+
type: 'tool-input-delta',
|
|
2536
|
+
id: contentBlock.toolCallId,
|
|
2537
|
+
delta: contentBlock.input,
|
|
2538
|
+
});
|
|
2539
|
+
}
|
|
2540
|
+
|
|
2334
2541
|
controller.enqueue({
|
|
2335
2542
|
type: 'tool-input-end',
|
|
2336
2543
|
id: contentBlock.toolCallId,
|
|
@@ -2373,10 +2580,15 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
2373
2580
|
contentBlock.providerToolName === 'code_execution'
|
|
2374
2581
|
? { dynamic: true }
|
|
2375
2582
|
: {}),
|
|
2376
|
-
...(contentBlock.caller && {
|
|
2583
|
+
...((contentBlock.caller || contentBlock.toolset) && {
|
|
2377
2584
|
providerMetadata: {
|
|
2378
2585
|
anthropic: {
|
|
2379
|
-
|
|
2586
|
+
...(contentBlock.toolset && {
|
|
2587
|
+
toolsetName: contentBlock.toolset.name,
|
|
2588
|
+
}),
|
|
2589
|
+
...(contentBlock.caller && {
|
|
2590
|
+
caller: contentBlock.caller,
|
|
2591
|
+
}),
|
|
2380
2592
|
},
|
|
2381
2593
|
},
|
|
2382
2594
|
}),
|
|
@@ -2478,6 +2690,13 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
2478
2690
|
return;
|
|
2479
2691
|
}
|
|
2480
2692
|
|
|
2693
|
+
// toolset member input is emitted as a single delta once
|
|
2694
|
+
// the block is complete (the member name is injected):
|
|
2695
|
+
if (contentBlock.toolset != null) {
|
|
2696
|
+
contentBlock.input += delta;
|
|
2697
|
+
return;
|
|
2698
|
+
}
|
|
2699
|
+
|
|
2481
2700
|
// for the code execution 20250825, we need to add
|
|
2482
2701
|
// the type to the delta and change the tool name.
|
|
2483
2702
|
if (
|
|
@@ -2701,6 +2920,12 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
2701
2920
|
inputTransformations = value.input_transformations;
|
|
2702
2921
|
}
|
|
2703
2922
|
|
|
2923
|
+
// Earlier deltas may carry null while the classifier is still
|
|
2924
|
+
// running; the last non-null value is the final verdict.
|
|
2925
|
+
if (value.delta.safeguard_results != null) {
|
|
2926
|
+
safeguardResults = value.delta.safeguard_results;
|
|
2927
|
+
}
|
|
2928
|
+
|
|
2704
2929
|
rawUsage = {
|
|
2705
2930
|
...rawUsage,
|
|
2706
2931
|
...(value.usage as JSONObject),
|
|
@@ -2720,6 +2945,7 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
2720
2945
|
...(inputTransformations != null
|
|
2721
2946
|
? { inputTransformations }
|
|
2722
2947
|
: {}),
|
|
2948
|
+
...(safeguardResults != null ? { safeguardResults } : {}),
|
|
2723
2949
|
iterations: usage.iterations
|
|
2724
2950
|
? usage.iterations.map(
|
|
2725
2951
|
iter =>
|
|
@@ -2844,9 +3070,30 @@ export function getModelCapabilities(modelId: string): {
|
|
|
2844
3070
|
rejectsSamplingParameters: boolean;
|
|
2845
3071
|
supportsXhighEffort: boolean;
|
|
2846
3072
|
rejectsThinkingDisabledAboveHighEffort: boolean;
|
|
3073
|
+
/**
|
|
3074
|
+
* Thinking is always adaptive: `thinking.type` `disabled` and `enabled`
|
|
3075
|
+
* are rejected with a 400.
|
|
3076
|
+
*/
|
|
3077
|
+
rejectsThinkingDisabled: boolean;
|
|
3078
|
+
/**
|
|
3079
|
+
* Forced tool use (`tool_choice` `any` or a named tool) is rejected with a 400.
|
|
3080
|
+
*/
|
|
3081
|
+
rejectsForcedToolUse: boolean;
|
|
2847
3082
|
isKnownModel: boolean;
|
|
2848
3083
|
} {
|
|
2849
|
-
if (modelId.includes('claude-opus-5')) {
|
|
3084
|
+
if (modelId.includes('claude-opus-5-5')) {
|
|
3085
|
+
return {
|
|
3086
|
+
maxOutputTokens: 128000,
|
|
3087
|
+
supportsStructuredOutput: true,
|
|
3088
|
+
supportsAdaptiveThinking: true,
|
|
3089
|
+
rejectsSamplingParameters: true,
|
|
3090
|
+
supportsXhighEffort: true,
|
|
3091
|
+
rejectsThinkingDisabledAboveHighEffort: true,
|
|
3092
|
+
rejectsThinkingDisabled: true,
|
|
3093
|
+
rejectsForcedToolUse: true,
|
|
3094
|
+
isKnownModel: true,
|
|
3095
|
+
};
|
|
3096
|
+
} else if (modelId.includes('claude-opus-5')) {
|
|
2850
3097
|
return {
|
|
2851
3098
|
maxOutputTokens: 128000,
|
|
2852
3099
|
supportsStructuredOutput: true,
|
|
@@ -2854,12 +3101,37 @@ export function getModelCapabilities(modelId: string): {
|
|
|
2854
3101
|
rejectsSamplingParameters: true,
|
|
2855
3102
|
supportsXhighEffort: true,
|
|
2856
3103
|
rejectsThinkingDisabledAboveHighEffort: true,
|
|
3104
|
+
rejectsThinkingDisabled: false,
|
|
3105
|
+
rejectsForcedToolUse: false,
|
|
3106
|
+
isKnownModel: true,
|
|
3107
|
+
};
|
|
3108
|
+
} else if (modelId.includes('claude-fable-5-1')) {
|
|
3109
|
+
return {
|
|
3110
|
+
maxOutputTokens: 128000,
|
|
3111
|
+
supportsStructuredOutput: true,
|
|
3112
|
+
supportsAdaptiveThinking: true,
|
|
3113
|
+
rejectsSamplingParameters: true,
|
|
3114
|
+
supportsXhighEffort: true,
|
|
3115
|
+
rejectsThinkingDisabledAboveHighEffort: false,
|
|
3116
|
+
rejectsThinkingDisabled: true,
|
|
3117
|
+
rejectsForcedToolUse: true,
|
|
3118
|
+
isKnownModel: true,
|
|
3119
|
+
};
|
|
3120
|
+
} else if (modelId.includes('claude-fable-5')) {
|
|
3121
|
+
return {
|
|
3122
|
+
maxOutputTokens: 128000,
|
|
3123
|
+
supportsStructuredOutput: true,
|
|
3124
|
+
supportsAdaptiveThinking: true,
|
|
3125
|
+
rejectsSamplingParameters: true,
|
|
3126
|
+
supportsXhighEffort: true,
|
|
3127
|
+
rejectsThinkingDisabledAboveHighEffort: false,
|
|
3128
|
+
rejectsThinkingDisabled: true,
|
|
3129
|
+
rejectsForcedToolUse: false,
|
|
2857
3130
|
isKnownModel: true,
|
|
2858
3131
|
};
|
|
2859
3132
|
} else if (
|
|
2860
3133
|
modelId.includes('claude-opus-4-8') ||
|
|
2861
3134
|
modelId.includes('claude-opus-4-7') ||
|
|
2862
|
-
modelId.includes('claude-fable-5') ||
|
|
2863
3135
|
modelId.includes('claude-sonnet-5')
|
|
2864
3136
|
) {
|
|
2865
3137
|
return {
|
|
@@ -2869,6 +3141,8 @@ export function getModelCapabilities(modelId: string): {
|
|
|
2869
3141
|
rejectsSamplingParameters: true,
|
|
2870
3142
|
supportsXhighEffort: true,
|
|
2871
3143
|
rejectsThinkingDisabledAboveHighEffort: false,
|
|
3144
|
+
rejectsThinkingDisabled: false,
|
|
3145
|
+
rejectsForcedToolUse: false,
|
|
2872
3146
|
isKnownModel: true,
|
|
2873
3147
|
};
|
|
2874
3148
|
} else if (
|
|
@@ -2882,6 +3156,8 @@ export function getModelCapabilities(modelId: string): {
|
|
|
2882
3156
|
rejectsSamplingParameters: false,
|
|
2883
3157
|
supportsXhighEffort: false,
|
|
2884
3158
|
rejectsThinkingDisabledAboveHighEffort: false,
|
|
3159
|
+
rejectsThinkingDisabled: false,
|
|
3160
|
+
rejectsForcedToolUse: false,
|
|
2885
3161
|
isKnownModel: true,
|
|
2886
3162
|
};
|
|
2887
3163
|
} else if (
|
|
@@ -2896,6 +3172,8 @@ export function getModelCapabilities(modelId: string): {
|
|
|
2896
3172
|
rejectsSamplingParameters: false,
|
|
2897
3173
|
supportsXhighEffort: false,
|
|
2898
3174
|
rejectsThinkingDisabledAboveHighEffort: false,
|
|
3175
|
+
rejectsThinkingDisabled: false,
|
|
3176
|
+
rejectsForcedToolUse: false,
|
|
2899
3177
|
isKnownModel: true,
|
|
2900
3178
|
};
|
|
2901
3179
|
} else if (modelId.includes('claude-opus-4-1')) {
|
|
@@ -2906,6 +3184,8 @@ export function getModelCapabilities(modelId: string): {
|
|
|
2906
3184
|
rejectsSamplingParameters: false,
|
|
2907
3185
|
supportsXhighEffort: false,
|
|
2908
3186
|
rejectsThinkingDisabledAboveHighEffort: false,
|
|
3187
|
+
rejectsThinkingDisabled: false,
|
|
3188
|
+
rejectsForcedToolUse: false,
|
|
2909
3189
|
isKnownModel: true,
|
|
2910
3190
|
};
|
|
2911
3191
|
} else if (/claude-sonnet-4(?:-|@)/.test(modelId)) {
|
|
@@ -2916,6 +3196,8 @@ export function getModelCapabilities(modelId: string): {
|
|
|
2916
3196
|
rejectsSamplingParameters: false,
|
|
2917
3197
|
supportsXhighEffort: false,
|
|
2918
3198
|
rejectsThinkingDisabledAboveHighEffort: false,
|
|
3199
|
+
rejectsThinkingDisabled: false,
|
|
3200
|
+
rejectsForcedToolUse: false,
|
|
2919
3201
|
isKnownModel: true,
|
|
2920
3202
|
};
|
|
2921
3203
|
} else if (/claude-opus-4(?:-|@)/.test(modelId)) {
|
|
@@ -2926,6 +3208,8 @@ export function getModelCapabilities(modelId: string): {
|
|
|
2926
3208
|
rejectsSamplingParameters: false,
|
|
2927
3209
|
supportsXhighEffort: false,
|
|
2928
3210
|
rejectsThinkingDisabledAboveHighEffort: false,
|
|
3211
|
+
rejectsThinkingDisabled: false,
|
|
3212
|
+
rejectsForcedToolUse: false,
|
|
2929
3213
|
isKnownModel: true,
|
|
2930
3214
|
};
|
|
2931
3215
|
} else if (modelId.includes('claude-3-haiku')) {
|
|
@@ -2936,6 +3220,8 @@ export function getModelCapabilities(modelId: string): {
|
|
|
2936
3220
|
rejectsSamplingParameters: false,
|
|
2937
3221
|
supportsXhighEffort: false,
|
|
2938
3222
|
rejectsThinkingDisabledAboveHighEffort: false,
|
|
3223
|
+
rejectsThinkingDisabled: false,
|
|
3224
|
+
rejectsForcedToolUse: false,
|
|
2939
3225
|
isKnownModel: true,
|
|
2940
3226
|
};
|
|
2941
3227
|
} else if (
|
|
@@ -2948,6 +3234,8 @@ export function getModelCapabilities(modelId: string): {
|
|
|
2948
3234
|
rejectsSamplingParameters: false,
|
|
2949
3235
|
supportsXhighEffort: false,
|
|
2950
3236
|
rejectsThinkingDisabledAboveHighEffort: false,
|
|
3237
|
+
rejectsThinkingDisabled: false,
|
|
3238
|
+
rejectsForcedToolUse: false,
|
|
2951
3239
|
isKnownModel: false,
|
|
2952
3240
|
};
|
|
2953
3241
|
} else if (modelId.includes('claude-')) {
|
|
@@ -2961,6 +3249,8 @@ export function getModelCapabilities(modelId: string): {
|
|
|
2961
3249
|
rejectsSamplingParameters: true,
|
|
2962
3250
|
supportsXhighEffort: true,
|
|
2963
3251
|
rejectsThinkingDisabledAboveHighEffort: true,
|
|
3252
|
+
rejectsThinkingDisabled: false,
|
|
3253
|
+
rejectsForcedToolUse: false,
|
|
2964
3254
|
isKnownModel: false,
|
|
2965
3255
|
};
|
|
2966
3256
|
} else {
|
|
@@ -2973,6 +3263,8 @@ export function getModelCapabilities(modelId: string): {
|
|
|
2973
3263
|
rejectsSamplingParameters: false,
|
|
2974
3264
|
supportsXhighEffort: false,
|
|
2975
3265
|
rejectsThinkingDisabledAboveHighEffort: false,
|
|
3266
|
+
rejectsThinkingDisabled: false,
|
|
3267
|
+
rejectsForcedToolUse: false,
|
|
2976
3268
|
isKnownModel: false,
|
|
2977
3269
|
};
|
|
2978
3270
|
}
|
|
@@ -3012,14 +3304,18 @@ export function hasDynamicFilteringWebToolWithoutCodeExecution(
|
|
|
3012
3304
|
|
|
3013
3305
|
function resolveAnthropicReasoningConfig({
|
|
3014
3306
|
reasoning,
|
|
3307
|
+
modelId,
|
|
3015
3308
|
supportsAdaptiveThinking,
|
|
3016
3309
|
supportsXhighEffort,
|
|
3310
|
+
rejectsThinkingDisabled,
|
|
3017
3311
|
maxOutputTokensForModel,
|
|
3018
3312
|
warnings,
|
|
3019
3313
|
}: {
|
|
3020
3314
|
reasoning: LanguageModelV4CallOptions['reasoning'];
|
|
3315
|
+
modelId: string;
|
|
3021
3316
|
supportsAdaptiveThinking: boolean;
|
|
3022
3317
|
supportsXhighEffort: boolean;
|
|
3318
|
+
rejectsThinkingDisabled: boolean;
|
|
3023
3319
|
maxOutputTokensForModel: number;
|
|
3024
3320
|
warnings: SharedV4Warning[];
|
|
3025
3321
|
}): Pick<AnthropicLanguageModelOptions, 'thinking' | 'effort'> | undefined {
|
|
@@ -3028,6 +3324,20 @@ function resolveAnthropicReasoningConfig({
|
|
|
3028
3324
|
}
|
|
3029
3325
|
|
|
3030
3326
|
if (reasoning === 'none') {
|
|
3327
|
+
// Models that always run adaptive thinking cannot disable it. Use low
|
|
3328
|
+
// effort to keep thinking short instead of sending a request that the
|
|
3329
|
+
// API would reject.
|
|
3330
|
+
if (rejectsThinkingDisabled) {
|
|
3331
|
+
warnings.push({
|
|
3332
|
+
type: 'compatibility',
|
|
3333
|
+
feature: 'reasoning',
|
|
3334
|
+
details:
|
|
3335
|
+
`reasoning 'none' is not supported by ${modelId}; it always uses adaptive thinking. ` +
|
|
3336
|
+
`Using effort 'low' to minimize thinking instead.`,
|
|
3337
|
+
});
|
|
3338
|
+
return { effort: 'low' };
|
|
3339
|
+
}
|
|
3340
|
+
|
|
3031
3341
|
return { thinking: { type: 'disabled' } };
|
|
3032
3342
|
}
|
|
3033
3343
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { JSONObject } from '@ai-sdk/provider';
|
|
2
|
+
import type { AnthropicSafeguardResult } from './anthropic-api';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Represents a single iteration in the usage breakdown.
|
|
@@ -62,6 +63,19 @@ export interface AnthropicMessageMetadata {
|
|
|
62
63
|
reason: string;
|
|
63
64
|
}>;
|
|
64
65
|
|
|
66
|
+
/**
|
|
67
|
+
* Verdicts of the server-side safeguards requested with
|
|
68
|
+
* `providerOptions.anthropic.safeguards`, one entry per requested safeguard.
|
|
69
|
+
* For `dangerous_tool_use`, `status.type` is `'available'` when the
|
|
70
|
+
* classifier ran and `status.tool_uses` maps each tool call id to its
|
|
71
|
+
* verdict (`type: 'evaluated'` with an `outcome` of `'not_flagged'` or
|
|
72
|
+
* `'flagged'` plus an `explanation`, `'skipped'`, or `'unavailable'`).
|
|
73
|
+
*
|
|
74
|
+
* Kept in the API's wire shape (snake_case), since consumers such as Claude
|
|
75
|
+
* Code read the verdicts verbatim.
|
|
76
|
+
*/
|
|
77
|
+
safeguardResults?: AnthropicSafeguardResult[];
|
|
78
|
+
|
|
65
79
|
/**
|
|
66
80
|
* Details about why the request stopped. Present only when the API returns
|
|
67
81
|
* a `refusal` stop reason together with a `stop_details` object (a
|