@ai-sdk/anthropic 3.0.126 → 3.0.128
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 +17 -0
- package/dist/index.d.mts +31 -2
- package/dist/index.d.ts +31 -2
- package/dist/index.js +86 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +86 -8
- package/dist/index.mjs.map +1 -1
- package/dist/internal/index.d.mts +6 -1
- package/dist/internal/index.d.ts +6 -1
- package/dist/internal/index.js +85 -7
- package/dist/internal/index.js.map +1 -1
- package/dist/internal/index.mjs +85 -7
- package/dist/internal/index.mjs.map +1 -1
- package/docs/05-anthropic.mdx +65 -2
- package/package.json +1 -1
- package/src/anthropic-message-metadata.ts +14 -0
- package/src/anthropic-messages-api.ts +23 -0
- package/src/anthropic-messages-language-model.ts +86 -12
- package/src/anthropic-messages-options.ts +20 -0
package/docs/05-anthropic.mdx
CHANGED
|
@@ -200,9 +200,18 @@ verify that a tool call was made.
|
|
|
200
200
|
|
|
201
201
|
### Effort
|
|
202
202
|
|
|
203
|
-
Anthropic introduced an `effort` option with `claude-opus-4-5` that affects thinking, text responses, and function calls. Effort defaults to `high` and you can set it to `medium` or `low` to save tokens and to lower time-to-last-token latency (TTLT). `claude-opus-4-7`, `claude-opus-4-8`, `claude-opus-5`, `claude-opus-5-5`, `claude-fable-5`, `claude-fable-5-1`, `claude-sonnet-5`, and `claude-
|
|
203
|
+
Anthropic introduced an `effort` option with `claude-opus-4-5` that affects thinking, text responses, and function calls. Effort defaults to `high` and you can set it to `medium` or `low` to save tokens and to lower time-to-last-token latency (TTLT). `claude-opus-4-7`, `claude-opus-4-8`, `claude-opus-5`, `claude-opus-5-5`, `claude-fable-5`, `claude-fable-5-1`, `claude-sonnet-5`, `claude-sonnet-5-5`, and `claude-haiku-5-5` additionally support `xhigh` for maximum reasoning effort.
|
|
204
204
|
|
|
205
|
-
On `claude-opus-5`, thinking can only be disabled at effort levels up to and including `high`. When you combine `thinking: { type: 'disabled' }` with `effort: 'xhigh'` or `effort: 'max'`, the AI SDK lowers the effort to `high` and emits a warning instead of sending a request that the API would reject.
|
|
205
|
+
On `claude-opus-5` and `claude-haiku-5-5`, thinking can only be disabled at effort levels up to and including `high`. When you combine `thinking: { type: 'disabled' }` with `effort: 'xhigh'` or `effort: 'max'`, the AI SDK lowers the effort to `high` and emits a warning instead of sending a request that the API would reject.
|
|
206
|
+
|
|
207
|
+
`claude-haiku-5-5` is the first Haiku model with effort levels and supports all
|
|
208
|
+
five of them. It uses adaptive thinking and does not support thinking token
|
|
209
|
+
budgets: the AI SDK converts `thinking: { type: 'enabled', budgetTokens }` to
|
|
210
|
+
`{ type: 'adaptive' }` and emits a warning. Use `effort` to control how much it
|
|
211
|
+
thinks. Unlike `claude-sonnet-5-5`, thinking can still be turned off with
|
|
212
|
+
`thinking: { type: 'disabled' }`, but only at `low`, `medium`, and `high` effort.
|
|
213
|
+
Start at `medium` effort and test other levels rather than carrying over the
|
|
214
|
+
settings you used on `claude-haiku-4-5`.
|
|
206
215
|
|
|
207
216
|
On `claude-opus-5-5`, thinking is always adaptive and cannot be disabled, so
|
|
208
217
|
`effort` is the main control for latency and cost. The API default effort for
|
|
@@ -325,6 +334,8 @@ The `inferenceGeo` option accepts `'us'` (US-only infrastructure) or `'global'`
|
|
|
325
334
|
|
|
326
335
|
Claude Fable 5 has safeguards that limit its performance in certain areas like cybersecurity, biology, and chemistry, and automated safety checks are run on every request.
|
|
327
336
|
|
|
337
|
+
Claude Haiku 5.5 has the same biology safeguards as Claude Sonnet 5 and 5.5, plus safeguards that prevent cyber misuse.
|
|
338
|
+
|
|
328
339
|
Claude Sonnet 5.5 also has safety classifiers enabled, including for cybersecurity, biology, and reasoning extraction. Requests that ask the model to reproduce its internal reasoning in the response text can be declined with the `reasoning_extraction` category; use `thinking: { type: 'adaptive', display: 'summarized' }` and read the reasoning parts instead.
|
|
329
340
|
|
|
330
341
|
When one of these checks blocks a request, the API does not answer it. Instead it returns a classifier block: a `200` response with a `refusal` stop reason and an optional `stop_details` object describing the category that triggered the block. The AI SDK surfaces this as a `content-filter` finish reason, with the details available on `providerMetadata.anthropic.stopDetails`.
|
|
@@ -399,6 +410,57 @@ const servedByFallback = iterations?.some(
|
|
|
399
410
|
console.log('Served by fallback:', servedByFallback);
|
|
400
411
|
```
|
|
401
412
|
|
|
413
|
+
### Dangerous Tool Use Safeguard
|
|
414
|
+
|
|
415
|
+
The `safeguards` option asks the API to run additional server-side checks as part of the request. The `dangerous_tool_use` safeguard classifies every `tool_use` block in the response for dangerous actions, such as destructive shell commands or data exfiltration, and returns a verdict per tool call. This is the check that Claude Code's auto mode relies on. The `dangerous-tool-use-2026-09-03` beta header is added for you.
|
|
416
|
+
|
|
417
|
+
```ts highlight="9-16"
|
|
418
|
+
import { anthropic, AnthropicLanguageModelOptions } from '@ai-sdk/anthropic';
|
|
419
|
+
import { generateText, tool } from 'ai';
|
|
420
|
+
import { z } from 'zod';
|
|
421
|
+
|
|
422
|
+
const result = await generateText({
|
|
423
|
+
model: anthropic('claude-sonnet-4-5'),
|
|
424
|
+
prompt: 'Use the bash tool to run: echo hello',
|
|
425
|
+
tools: { bash: tool({ inputSchema: z.object({ command: z.string() }) }) },
|
|
426
|
+
providerOptions: {
|
|
427
|
+
anthropic: {
|
|
428
|
+
safeguards: [
|
|
429
|
+
{
|
|
430
|
+
type: 'dangerous_tool_use',
|
|
431
|
+
classifierContext: { v: 1, permission_mode: 'auto' },
|
|
432
|
+
},
|
|
433
|
+
],
|
|
434
|
+
} satisfies AnthropicLanguageModelOptions,
|
|
435
|
+
},
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
console.log(result.providerMetadata?.anthropic?.safeguardResults);
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
The verdicts are available on `providerMetadata.anthropic.safeguardResults`, one entry per requested safeguard, in the API's wire shape:
|
|
442
|
+
|
|
443
|
+
```json
|
|
444
|
+
[
|
|
445
|
+
{
|
|
446
|
+
"type": "dangerous_tool_use",
|
|
447
|
+
"status": {
|
|
448
|
+
"type": "available",
|
|
449
|
+
"tool_uses": {
|
|
450
|
+
"toolu_01Ti4QpUfhLV6QqCTFVY8C7w": {
|
|
451
|
+
"type": "evaluated",
|
|
452
|
+
"outcome": "not_flagged"
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
]
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
`status.type` is `available` when the classifier ran; `unsupported` means the API key is not enabled for the beta. Inside `status.tool_uses`, each tool call id maps to `evaluated` (with an `outcome` of `not_flagged` or `flagged`, the latter with an `explanation` such as `[Data Exfiltration]`), `skipped`, or `unavailable` (a transient classifier failure). When streaming, the verdicts arrive on the final `message_delta` event and are exposed on the `finish` part's provider metadata.
|
|
461
|
+
|
|
462
|
+
Anthropic's platform reference does not document the beta yet; the feature is described from the client side in the Claude Code [auto mode classifier](https://code.claude.com/docs/en/auto-mode-classifier-billing) and [gateway compatibility](https://code.claude.com/docs/en/llm-gateway-protocol#feature-pass-through) guides.
|
|
463
|
+
|
|
402
464
|
### Reasoning
|
|
403
465
|
|
|
404
466
|
Anthropic models support extended thinking, where Claude shows its reasoning process before providing a final answer.
|
|
@@ -1961,6 +2023,7 @@ and the `mediaType` should be set to `'application/pdf'`.
|
|
|
1961
2023
|
| `claude-opus-5` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
|
1962
2024
|
| `claude-sonnet-5-5` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
|
1963
2025
|
| `claude-sonnet-5` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
|
2026
|
+
| `claude-haiku-5-5` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
|
1964
2027
|
| `claude-fable-5` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
|
1965
2028
|
| `claude-opus-4-8` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
|
1966
2029
|
| `claude-opus-4-7` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
package/package.json
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { JSONObject } from '@ai-sdk/provider';
|
|
2
|
+
import type { AnthropicSafeguardResult } from './anthropic-messages-api';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Represents a single iteration in the usage breakdown.
|
|
@@ -65,6 +66,19 @@ export interface AnthropicMessageMetadata {
|
|
|
65
66
|
reason: string;
|
|
66
67
|
}>;
|
|
67
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Verdicts of the server-side safeguards requested with
|
|
71
|
+
* `providerOptions.anthropic.safeguards`, one entry per requested safeguard.
|
|
72
|
+
* For `dangerous_tool_use`, `status.type` is `'available'` when the
|
|
73
|
+
* classifier ran and `status.tool_uses` maps each tool call id to its
|
|
74
|
+
* verdict (`type: 'evaluated'` with an `outcome` of `'not_flagged'` or
|
|
75
|
+
* `'flagged'` plus an `explanation`, `'skipped'`, or `'unavailable'`).
|
|
76
|
+
*
|
|
77
|
+
* Kept in the API's wire shape (snake_case), since consumers such as Claude
|
|
78
|
+
* Code read the verdicts verbatim.
|
|
79
|
+
*/
|
|
80
|
+
safeguardResults?: AnthropicSafeguardResult[];
|
|
81
|
+
|
|
68
82
|
/**
|
|
69
83
|
* Details about why the request stopped. Present only when the API returns
|
|
70
84
|
* a `refusal` stop reason together with a `stop_details` object (a
|
|
@@ -649,6 +649,27 @@ const anthropicStopDetailsSchema = z.object({
|
|
|
649
649
|
|
|
650
650
|
export type AnthropicStopDetails = z.infer<typeof anthropicStopDetailsSchema>;
|
|
651
651
|
|
|
652
|
+
const anthropicSafeguardResultSchema = z.object({
|
|
653
|
+
type: z.string(),
|
|
654
|
+
status: z.object({
|
|
655
|
+
type: z.string(),
|
|
656
|
+
tool_uses: z
|
|
657
|
+
.record(
|
|
658
|
+
z.string(),
|
|
659
|
+
z.object({
|
|
660
|
+
type: z.string(),
|
|
661
|
+
outcome: z.string().nullish(),
|
|
662
|
+
explanation: z.string().nullish(),
|
|
663
|
+
}),
|
|
664
|
+
)
|
|
665
|
+
.nullish(),
|
|
666
|
+
}),
|
|
667
|
+
});
|
|
668
|
+
|
|
669
|
+
export type AnthropicSafeguardResult = z.infer<
|
|
670
|
+
typeof anthropicSafeguardResultSchema
|
|
671
|
+
>;
|
|
672
|
+
|
|
652
673
|
const anthropicToolCallCallerSchema = z.union([
|
|
653
674
|
z.object({
|
|
654
675
|
type: z.literal('code_execution_20250825'),
|
|
@@ -963,6 +984,7 @@ export const anthropicMessagesResponseSchema = lazySchema(() =>
|
|
|
963
984
|
input_transformations: z
|
|
964
985
|
.array(anthropicInputTransformationSchema)
|
|
965
986
|
.nullish(),
|
|
987
|
+
safeguard_results: z.array(anthropicSafeguardResultSchema).nullish(),
|
|
966
988
|
usage: z.looseObject({
|
|
967
989
|
input_tokens: z.number(),
|
|
968
990
|
output_tokens: z.number(),
|
|
@@ -1397,6 +1419,7 @@ export const anthropicMessagesChunkSchema = lazySchema(() =>
|
|
|
1397
1419
|
stop_reason: z.string().nullish(),
|
|
1398
1420
|
stop_sequence: z.string().nullish(),
|
|
1399
1421
|
stop_details: anthropicStopDetailsSchema.nullish(),
|
|
1422
|
+
safeguard_results: z.array(anthropicSafeguardResultSchema).nullish(),
|
|
1400
1423
|
container: z
|
|
1401
1424
|
.object({
|
|
1402
1425
|
expires_at: z.string(),
|
|
@@ -340,6 +340,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
340
340
|
rejectsSamplingParameters,
|
|
341
341
|
rejectsThinkingDisabledAboveHighEffort,
|
|
342
342
|
rejectsThinkingDisabled,
|
|
343
|
+
rejectsBudgetThinking,
|
|
343
344
|
rejectsForcedToolUse,
|
|
344
345
|
supportsBetweenToolsThinking,
|
|
345
346
|
isKnownModel,
|
|
@@ -488,9 +489,9 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
488
489
|
toolsetNames,
|
|
489
490
|
});
|
|
490
491
|
|
|
491
|
-
// Some models always run adaptive thinking and reject `disabled`
|
|
492
|
-
//
|
|
493
|
-
//
|
|
492
|
+
// Some models always run adaptive thinking and reject `disabled` thinking
|
|
493
|
+
// with a 400. Drop the unsupported setting and keep the request adaptive
|
|
494
|
+
// so it still succeeds.
|
|
494
495
|
if (rejectsThinkingDisabled && anthropicOptions?.thinking != null) {
|
|
495
496
|
const requestedThinking = anthropicOptions.thinking;
|
|
496
497
|
const requestedType =
|
|
@@ -514,18 +515,30 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
514
515
|
`The thinking setting has been removed. Lower 'effort' to reduce thinking.`,
|
|
515
516
|
});
|
|
516
517
|
anthropicOptions.thinking = undefined;
|
|
517
|
-
} else if (requestedType === 'enabled') {
|
|
518
|
-
warnings.push({
|
|
519
|
-
type: 'unsupported',
|
|
520
|
-
feature: 'providerOptions.anthropic.thinking',
|
|
521
|
-
details:
|
|
522
|
-
`budget-based thinking is not supported by ${this.modelId}; it always uses adaptive thinking. ` +
|
|
523
|
-
`Using adaptive thinking instead. Use 'effort' to control how much the model thinks.`,
|
|
524
|
-
});
|
|
525
|
-
anthropicOptions.thinking = { type: 'adaptive' };
|
|
526
518
|
}
|
|
527
519
|
}
|
|
528
520
|
|
|
521
|
+
// Models that only support adaptive thinking reject budget-based thinking
|
|
522
|
+
// with a 400. Use adaptive thinking instead and let `effort` control how
|
|
523
|
+
// much the model thinks.
|
|
524
|
+
if (
|
|
525
|
+
rejectsBudgetThinking &&
|
|
526
|
+
anthropicOptions?.thinking != null &&
|
|
527
|
+
'type' in anthropicOptions.thinking &&
|
|
528
|
+
anthropicOptions.thinking.type === 'enabled'
|
|
529
|
+
) {
|
|
530
|
+
warnings.push({
|
|
531
|
+
type: 'unsupported',
|
|
532
|
+
feature: 'providerOptions.anthropic.thinking',
|
|
533
|
+
details: rejectsThinkingDisabled
|
|
534
|
+
? `budget-based thinking is not supported by ${this.modelId}; it always uses adaptive thinking. ` +
|
|
535
|
+
`Using adaptive thinking instead. Use 'effort' to control how much the model thinks.`
|
|
536
|
+
: `budget-based thinking is not supported by ${this.modelId}. ` +
|
|
537
|
+
`Using adaptive thinking instead. Use 'effort' to control how much the model thinks.`,
|
|
538
|
+
});
|
|
539
|
+
anthropicOptions.thinking = { type: 'adaptive' };
|
|
540
|
+
}
|
|
541
|
+
|
|
529
542
|
const thinking = anthropicOptions?.thinking;
|
|
530
543
|
const thinkingType =
|
|
531
544
|
thinking != null && 'type' in thinking ? thinking.type : undefined;
|
|
@@ -702,6 +715,16 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
702
715
|
system: messagesPrompt.system,
|
|
703
716
|
messages: messagesPrompt.messages,
|
|
704
717
|
|
|
718
|
+
...(anthropicOptions?.safeguards &&
|
|
719
|
+
anthropicOptions.safeguards.length > 0 && {
|
|
720
|
+
safeguards: anthropicOptions.safeguards.map(safeguard => ({
|
|
721
|
+
type: safeguard.type,
|
|
722
|
+
...(safeguard.classifierContext !== undefined && {
|
|
723
|
+
classifier_context: safeguard.classifierContext,
|
|
724
|
+
}),
|
|
725
|
+
})),
|
|
726
|
+
}),
|
|
727
|
+
|
|
705
728
|
...(contextManagement && {
|
|
706
729
|
context_management: {
|
|
707
730
|
edits: contextManagement.edits
|
|
@@ -841,6 +864,13 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
841
864
|
betas.add('mcp-client-2025-04-04');
|
|
842
865
|
}
|
|
843
866
|
|
|
867
|
+
if (
|
|
868
|
+
anthropicOptions?.safeguards &&
|
|
869
|
+
anthropicOptions.safeguards.length > 0
|
|
870
|
+
) {
|
|
871
|
+
betas.add('dangerous-tool-use-2026-09-03');
|
|
872
|
+
}
|
|
873
|
+
|
|
844
874
|
if (contextManagement) {
|
|
845
875
|
betas.add('context-management-2025-06-27');
|
|
846
876
|
|
|
@@ -1588,6 +1618,9 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
1588
1618
|
...(response.input_transformations != null
|
|
1589
1619
|
? { inputTransformations: response.input_transformations }
|
|
1590
1620
|
: {}),
|
|
1621
|
+
...(response.safeguard_results != null
|
|
1622
|
+
? { safeguardResults: response.safeguard_results }
|
|
1623
|
+
: {}),
|
|
1591
1624
|
|
|
1592
1625
|
iterations: response.usage.iterations
|
|
1593
1626
|
? response.usage.iterations.map(
|
|
@@ -1732,6 +1765,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
1732
1765
|
let stopSequence: string | null = null;
|
|
1733
1766
|
let stopDetails: AnthropicMessageMetadata['stopDetails'] = undefined;
|
|
1734
1767
|
let inputTransformations: AnthropicMessageMetadata['inputTransformations'];
|
|
1768
|
+
let safeguardResults: AnthropicMessageMetadata['safeguardResults'];
|
|
1735
1769
|
let container: AnthropicMessageMetadata['container'] | null = null;
|
|
1736
1770
|
let isJsonResponseFromTool = false;
|
|
1737
1771
|
let isMessageOpen = false;
|
|
@@ -2802,6 +2836,12 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
2802
2836
|
inputTransformations = value.input_transformations;
|
|
2803
2837
|
}
|
|
2804
2838
|
|
|
2839
|
+
// Earlier deltas may carry null while the classifier is still
|
|
2840
|
+
// running; the last non-null value is the final verdict.
|
|
2841
|
+
if (value.delta.safeguard_results != null) {
|
|
2842
|
+
safeguardResults = value.delta.safeguard_results;
|
|
2843
|
+
}
|
|
2844
|
+
|
|
2805
2845
|
rawUsage = {
|
|
2806
2846
|
...rawUsage,
|
|
2807
2847
|
...(value.usage as JSONObject),
|
|
@@ -2822,6 +2862,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
2822
2862
|
...(inputTransformations != null
|
|
2823
2863
|
? { inputTransformations }
|
|
2824
2864
|
: {}),
|
|
2865
|
+
...(safeguardResults != null ? { safeguardResults } : {}),
|
|
2825
2866
|
iterations: usage.iterations
|
|
2826
2867
|
? usage.iterations.map(
|
|
2827
2868
|
iter =>
|
|
@@ -2942,6 +2983,11 @@ export function getModelCapabilities(modelId: string): {
|
|
|
2942
2983
|
* are rejected with a 400.
|
|
2943
2984
|
*/
|
|
2944
2985
|
rejectsThinkingDisabled: boolean;
|
|
2986
|
+
/**
|
|
2987
|
+
* Budget-based thinking (`thinking.type` `enabled` with `budget_tokens`) is
|
|
2988
|
+
* rejected with a 400. Only adaptive thinking is supported.
|
|
2989
|
+
*/
|
|
2990
|
+
rejectsBudgetThinking: boolean;
|
|
2945
2991
|
/**
|
|
2946
2992
|
* Forced tool use (`tool_choice` `any` or a named tool) is rejected with a 400.
|
|
2947
2993
|
*/
|
|
@@ -2960,6 +3006,7 @@ export function getModelCapabilities(modelId: string): {
|
|
|
2960
3006
|
rejectsSamplingParameters: true,
|
|
2961
3007
|
rejectsThinkingDisabledAboveHighEffort: true,
|
|
2962
3008
|
rejectsThinkingDisabled: true,
|
|
3009
|
+
rejectsBudgetThinking: true,
|
|
2963
3010
|
rejectsForcedToolUse: true,
|
|
2964
3011
|
supportsBetweenToolsThinking: true,
|
|
2965
3012
|
isKnownModel: true,
|
|
@@ -2971,10 +3018,24 @@ export function getModelCapabilities(modelId: string): {
|
|
|
2971
3018
|
rejectsSamplingParameters: true,
|
|
2972
3019
|
rejectsThinkingDisabledAboveHighEffort: true,
|
|
2973
3020
|
rejectsThinkingDisabled: true,
|
|
3021
|
+
rejectsBudgetThinking: true,
|
|
2974
3022
|
rejectsForcedToolUse: true,
|
|
2975
3023
|
supportsBetweenToolsThinking: false,
|
|
2976
3024
|
isKnownModel: true,
|
|
2977
3025
|
};
|
|
3026
|
+
} else if (modelId.includes('claude-haiku-5-5')) {
|
|
3027
|
+
// Thinking can be turned off, but only up to `high` effort.
|
|
3028
|
+
return {
|
|
3029
|
+
maxOutputTokens: 128000,
|
|
3030
|
+
supportsStructuredOutput: true,
|
|
3031
|
+
rejectsSamplingParameters: true,
|
|
3032
|
+
rejectsThinkingDisabledAboveHighEffort: true,
|
|
3033
|
+
rejectsThinkingDisabled: false,
|
|
3034
|
+
rejectsBudgetThinking: true,
|
|
3035
|
+
rejectsForcedToolUse: false,
|
|
3036
|
+
supportsBetweenToolsThinking: false,
|
|
3037
|
+
isKnownModel: true,
|
|
3038
|
+
};
|
|
2978
3039
|
} else if (modelId.includes('claude-opus-5')) {
|
|
2979
3040
|
return {
|
|
2980
3041
|
maxOutputTokens: 128000,
|
|
@@ -2982,6 +3043,7 @@ export function getModelCapabilities(modelId: string): {
|
|
|
2982
3043
|
rejectsSamplingParameters: true,
|
|
2983
3044
|
rejectsThinkingDisabledAboveHighEffort: true,
|
|
2984
3045
|
rejectsThinkingDisabled: false,
|
|
3046
|
+
rejectsBudgetThinking: false,
|
|
2985
3047
|
rejectsForcedToolUse: false,
|
|
2986
3048
|
supportsBetweenToolsThinking: false,
|
|
2987
3049
|
isKnownModel: true,
|
|
@@ -2993,6 +3055,7 @@ export function getModelCapabilities(modelId: string): {
|
|
|
2993
3055
|
rejectsSamplingParameters: true,
|
|
2994
3056
|
rejectsThinkingDisabledAboveHighEffort: false,
|
|
2995
3057
|
rejectsThinkingDisabled: true,
|
|
3058
|
+
rejectsBudgetThinking: true,
|
|
2996
3059
|
rejectsForcedToolUse: true,
|
|
2997
3060
|
supportsBetweenToolsThinking: false,
|
|
2998
3061
|
isKnownModel: true,
|
|
@@ -3004,6 +3067,7 @@ export function getModelCapabilities(modelId: string): {
|
|
|
3004
3067
|
rejectsSamplingParameters: true,
|
|
3005
3068
|
rejectsThinkingDisabledAboveHighEffort: false,
|
|
3006
3069
|
rejectsThinkingDisabled: true,
|
|
3070
|
+
rejectsBudgetThinking: true,
|
|
3007
3071
|
rejectsForcedToolUse: false,
|
|
3008
3072
|
supportsBetweenToolsThinking: false,
|
|
3009
3073
|
isKnownModel: true,
|
|
@@ -3019,6 +3083,7 @@ export function getModelCapabilities(modelId: string): {
|
|
|
3019
3083
|
rejectsSamplingParameters: true,
|
|
3020
3084
|
rejectsThinkingDisabledAboveHighEffort: false,
|
|
3021
3085
|
rejectsThinkingDisabled: false,
|
|
3086
|
+
rejectsBudgetThinking: false,
|
|
3022
3087
|
rejectsForcedToolUse: false,
|
|
3023
3088
|
supportsBetweenToolsThinking: false,
|
|
3024
3089
|
isKnownModel: true,
|
|
@@ -3033,6 +3098,7 @@ export function getModelCapabilities(modelId: string): {
|
|
|
3033
3098
|
rejectsSamplingParameters: false,
|
|
3034
3099
|
rejectsThinkingDisabledAboveHighEffort: false,
|
|
3035
3100
|
rejectsThinkingDisabled: false,
|
|
3101
|
+
rejectsBudgetThinking: false,
|
|
3036
3102
|
rejectsForcedToolUse: false,
|
|
3037
3103
|
supportsBetweenToolsThinking: false,
|
|
3038
3104
|
isKnownModel: true,
|
|
@@ -3048,6 +3114,7 @@ export function getModelCapabilities(modelId: string): {
|
|
|
3048
3114
|
rejectsSamplingParameters: false,
|
|
3049
3115
|
rejectsThinkingDisabledAboveHighEffort: false,
|
|
3050
3116
|
rejectsThinkingDisabled: false,
|
|
3117
|
+
rejectsBudgetThinking: false,
|
|
3051
3118
|
rejectsForcedToolUse: false,
|
|
3052
3119
|
supportsBetweenToolsThinking: false,
|
|
3053
3120
|
isKnownModel: true,
|
|
@@ -3059,6 +3126,7 @@ export function getModelCapabilities(modelId: string): {
|
|
|
3059
3126
|
rejectsSamplingParameters: false,
|
|
3060
3127
|
rejectsThinkingDisabledAboveHighEffort: false,
|
|
3061
3128
|
rejectsThinkingDisabled: false,
|
|
3129
|
+
rejectsBudgetThinking: false,
|
|
3062
3130
|
rejectsForcedToolUse: false,
|
|
3063
3131
|
supportsBetweenToolsThinking: false,
|
|
3064
3132
|
isKnownModel: true,
|
|
@@ -3070,6 +3138,7 @@ export function getModelCapabilities(modelId: string): {
|
|
|
3070
3138
|
rejectsSamplingParameters: false,
|
|
3071
3139
|
rejectsThinkingDisabledAboveHighEffort: false,
|
|
3072
3140
|
rejectsThinkingDisabled: false,
|
|
3141
|
+
rejectsBudgetThinking: false,
|
|
3073
3142
|
rejectsForcedToolUse: false,
|
|
3074
3143
|
supportsBetweenToolsThinking: false,
|
|
3075
3144
|
isKnownModel: true,
|
|
@@ -3081,6 +3150,7 @@ export function getModelCapabilities(modelId: string): {
|
|
|
3081
3150
|
rejectsSamplingParameters: false,
|
|
3082
3151
|
rejectsThinkingDisabledAboveHighEffort: false,
|
|
3083
3152
|
rejectsThinkingDisabled: false,
|
|
3153
|
+
rejectsBudgetThinking: false,
|
|
3084
3154
|
rejectsForcedToolUse: false,
|
|
3085
3155
|
supportsBetweenToolsThinking: false,
|
|
3086
3156
|
isKnownModel: true,
|
|
@@ -3092,6 +3162,7 @@ export function getModelCapabilities(modelId: string): {
|
|
|
3092
3162
|
rejectsSamplingParameters: false,
|
|
3093
3163
|
rejectsThinkingDisabledAboveHighEffort: false,
|
|
3094
3164
|
rejectsThinkingDisabled: false,
|
|
3165
|
+
rejectsBudgetThinking: false,
|
|
3095
3166
|
rejectsForcedToolUse: false,
|
|
3096
3167
|
supportsBetweenToolsThinking: false,
|
|
3097
3168
|
isKnownModel: true,
|
|
@@ -3105,6 +3176,7 @@ export function getModelCapabilities(modelId: string): {
|
|
|
3105
3176
|
rejectsSamplingParameters: false,
|
|
3106
3177
|
rejectsThinkingDisabledAboveHighEffort: false,
|
|
3107
3178
|
rejectsThinkingDisabled: false,
|
|
3179
|
+
rejectsBudgetThinking: false,
|
|
3108
3180
|
rejectsForcedToolUse: false,
|
|
3109
3181
|
supportsBetweenToolsThinking: false,
|
|
3110
3182
|
isKnownModel: false,
|
|
@@ -3119,6 +3191,7 @@ export function getModelCapabilities(modelId: string): {
|
|
|
3119
3191
|
rejectsSamplingParameters: true,
|
|
3120
3192
|
rejectsThinkingDisabledAboveHighEffort: true,
|
|
3121
3193
|
rejectsThinkingDisabled: false,
|
|
3194
|
+
rejectsBudgetThinking: false,
|
|
3122
3195
|
rejectsForcedToolUse: false,
|
|
3123
3196
|
supportsBetweenToolsThinking: false,
|
|
3124
3197
|
isKnownModel: false,
|
|
@@ -3132,6 +3205,7 @@ export function getModelCapabilities(modelId: string): {
|
|
|
3132
3205
|
rejectsSamplingParameters: false,
|
|
3133
3206
|
rejectsThinkingDisabledAboveHighEffort: false,
|
|
3134
3207
|
rejectsThinkingDisabled: false,
|
|
3208
|
+
rejectsBudgetThinking: false,
|
|
3135
3209
|
rejectsForcedToolUse: false,
|
|
3136
3210
|
supportsBetweenToolsThinking: false,
|
|
3137
3211
|
isKnownModel: false,
|
|
@@ -5,6 +5,7 @@ export type AnthropicMessagesModelId =
|
|
|
5
5
|
| 'claude-3-haiku-20240307'
|
|
6
6
|
| 'claude-haiku-4-5-20251001'
|
|
7
7
|
| 'claude-haiku-4-5'
|
|
8
|
+
| 'claude-haiku-5-5'
|
|
8
9
|
| 'claude-opus-4-0'
|
|
9
10
|
| 'claude-opus-4-20250514'
|
|
10
11
|
| 'claude-opus-4-1-20250805'
|
|
@@ -364,6 +365,25 @@ export const anthropicLanguageModelOptions = z.object({
|
|
|
364
365
|
*/
|
|
365
366
|
anthropicBeta: z.array(z.string()).optional(),
|
|
366
367
|
|
|
368
|
+
/**
|
|
369
|
+
* Server-side safeguards to run as part of the request.
|
|
370
|
+
*
|
|
371
|
+
* `dangerous_tool_use` asks the API to classify every `tool_use` block in
|
|
372
|
+
* the response for dangerous actions (the check Claude Code's auto mode
|
|
373
|
+
* relies on). The per-call verdicts are returned in
|
|
374
|
+
* `providerMetadata.anthropic.safeguardResults`, keyed by tool call id.
|
|
375
|
+
* `classifierContext` is passed through to the API as `classifier_context`.
|
|
376
|
+
* The `dangerous-tool-use-2026-09-03` beta is added automatically.
|
|
377
|
+
*/
|
|
378
|
+
safeguards: z
|
|
379
|
+
.array(
|
|
380
|
+
z.object({
|
|
381
|
+
type: z.literal('dangerous_tool_use'),
|
|
382
|
+
classifierContext: z.record(z.string(), z.unknown()).optional(),
|
|
383
|
+
}),
|
|
384
|
+
)
|
|
385
|
+
.optional(),
|
|
386
|
+
|
|
367
387
|
contextManagement: z
|
|
368
388
|
.object({
|
|
369
389
|
edits: z.array(
|