@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.
@@ -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-sonnet-5-5` additionally support `xhigh` for maximum reasoning effort.
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,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/anthropic",
3
- "version": "3.0.126",
3
+ "version": "3.0.128",
4
4
  "license": "Apache-2.0",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.js",
@@ -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` and
492
- // budget-based `enabled` thinking with a 400. Drop the unsupported
493
- // setting and keep the request adaptive so it still succeeds.
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(