@ai-sdk/anthropic 3.0.69 → 3.0.71

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.
@@ -122,10 +122,14 @@ The following optional provider options are available for Anthropic models:
122
122
  If you are experiencing issues with the model handling requests involving
123
123
  reasoning content, you can set this to `false` to omit them from the request.
124
124
 
125
- - `effort` _"high" | "medium" | "low"_
125
+ - `effort` _"low" | "medium" | "high" | "xhigh" | "max"_
126
126
 
127
127
  Optional. See [Effort section](#effort) for more details.
128
128
 
129
+ - `taskBudget` _object_
130
+
131
+ Optional. See [Task Budgets section](#task-budgets) for more details.
132
+
129
133
  - `speed` _"fast" | "standard"_
130
134
 
131
135
  Optional. See [Fast Mode section](#fast-mode) for more details.
@@ -187,7 +191,7 @@ const result = streamText({
187
191
 
188
192
  ### Effort
189
193
 
190
- 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).
194
+ 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` additionally supports `xhigh` for maximum reasoning effort.
191
195
 
192
196
  ```ts highlight="8-10"
193
197
  import { anthropic, AnthropicLanguageModelOptions } from '@ai-sdk/anthropic';
@@ -228,6 +232,46 @@ const { text } = await generateText({
228
232
 
229
233
  The `speed` option accepts `'fast'` or `'standard'` (default behavior).
230
234
 
235
+ ### Task Budgets
236
+
237
+ `claude-opus-4-7` supports a `taskBudget` option that informs the model of the total token budget available for an agentic turn. The model uses this information to prioritize work, plan ahead, and wind down gracefully as the budget is consumed.
238
+
239
+ Task budgets are advisory — they do not enforce a hard token limit. The model will attempt to stay within budget, but actual usage may vary.
240
+
241
+ ```ts highlight="8-13"
242
+ import { anthropic, AnthropicLanguageModelOptions } from '@ai-sdk/anthropic';
243
+ import { generateText } from 'ai';
244
+
245
+ const { text } = await generateText({
246
+ model: anthropic('claude-opus-4-7'),
247
+ prompt: 'Research the pros and cons of Rust vs Go for building CLI tools.',
248
+ providerOptions: {
249
+ anthropic: {
250
+ taskBudget: {
251
+ type: 'tokens',
252
+ total: 400000,
253
+ },
254
+ } satisfies AnthropicLanguageModelOptions,
255
+ },
256
+ });
257
+ ```
258
+
259
+ For long-running agents that compact and restart context, you can carry the remaining budget forward using the `remaining` field:
260
+
261
+ ```ts
262
+ taskBudget: {
263
+ type: 'tokens',
264
+ total: 400000,
265
+ remaining: 215000, // budget left after prior compacted-away contexts
266
+ }
267
+ ```
268
+
269
+ The `taskBudget` object accepts:
270
+
271
+ - `type` _"tokens"_ - Budget type. Currently only `"tokens"` is supported.
272
+ - `total` _number_ - Total task budget for the agentic turn. Minimum 20,000.
273
+ - `remaining` _number_ - Budget left after prior compacted-away contexts. Must be between 0 and `total`. Defaults to `total` if omitted.
274
+
231
275
  ### Data Residency
232
276
 
233
277
  Anthropic supports an [`inferenceGeo` option](https://platform.claude.com/docs/en/build-with-claude/data-residency) that controls where model inference runs for a request.
@@ -292,6 +336,31 @@ const { text } = await generateText({
292
336
  });
293
337
  ```
294
338
 
339
+ ##### Thinking Display (Opus 4.7+)
340
+
341
+ Starting with `claude-opus-4-7`, thinking content is omitted from the response by default — thinking blocks are present in the stream but their text is empty. To receive reasoning output, set `display: 'summarized'`:
342
+
343
+ ```ts highlight="5"
344
+ const { text, reasoningText } = await generateText({
345
+ model: anthropic('claude-opus-4-7'),
346
+ providerOptions: {
347
+ anthropic: {
348
+ thinking: { type: 'adaptive', display: 'summarized' },
349
+ } satisfies AnthropicLanguageModelOptions,
350
+ },
351
+ prompt: 'How many people will live in the world in 2040?',
352
+ });
353
+
354
+ console.log(reasoningText); // reasoning text (empty without display: 'summarized')
355
+ console.log(text);
356
+ ```
357
+
358
+ <Note>
359
+ If you stream reasoning to users with `claude-opus-4-7`, the default `"omitted"` display will
360
+ cause a long pause before output begins. Set `display: "summarized"` to restore visible
361
+ progress during thinking.
362
+ </Note>
363
+
295
364
  #### Budget-Based Thinking
296
365
 
297
366
  For earlier models (`claude-opus-4-20250514`, `claude-sonnet-4-20250514`, `claude-sonnet-4-5-20250929`),
@@ -1376,6 +1445,7 @@ and the `mediaType` should be set to `'application/pdf'`.
1376
1445
 
1377
1446
  | Model | Image Input | Object Generation | Tool Usage | Computer Use | Web Search | Tool Search | Compaction |
1378
1447
  | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- |
1448
+ | `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} /> |
1379
1449
  | `claude-opus-4-6` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
1380
1450
  | `claude-sonnet-4-6` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | |
1381
1451
  | `claude-opus-4-5` | <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.69",
3
+ "version": "3.0.71",
4
4
  "license": "Apache-2.0",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.js",
@@ -269,9 +269,37 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
269
269
  const {
270
270
  maxOutputTokens: maxOutputTokensForModel,
271
271
  supportsStructuredOutput: modelSupportsStructuredOutput,
272
+ rejectsSamplingParameters,
272
273
  isKnownModel,
273
274
  } = getModelCapabilities(this.modelId);
274
275
 
276
+ if (rejectsSamplingParameters) {
277
+ if (temperature != null) {
278
+ warnings.push({
279
+ type: 'unsupported',
280
+ feature: 'temperature',
281
+ details: `temperature is not supported by ${this.modelId} and will be ignored`,
282
+ });
283
+ temperature = undefined;
284
+ }
285
+ if (topK != null) {
286
+ warnings.push({
287
+ type: 'unsupported',
288
+ feature: 'topK',
289
+ details: `topK is not supported by ${this.modelId} and will be ignored`,
290
+ });
291
+ topK = undefined;
292
+ }
293
+ if (topP != null) {
294
+ warnings.push({
295
+ type: 'unsupported',
296
+ feature: 'topP',
297
+ details: `topP is not supported by ${this.modelId} and will be ignored`,
298
+ });
299
+ topP = undefined;
300
+ }
301
+ }
302
+
275
303
  const isAnthropicModel = isKnownModel || this.modelId.startsWith('claude-');
276
304
 
277
305
  const supportsStructuredOutput =
@@ -345,6 +373,10 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
345
373
  thinkingType === 'enabled'
346
374
  ? anthropicOptions?.thinking?.budgetTokens
347
375
  : undefined;
376
+ const thinkingDisplay =
377
+ thinkingType === 'adaptive'
378
+ ? anthropicOptions?.thinking?.display
379
+ : undefined;
348
380
 
349
381
  const maxTokens = maxOutputTokens ?? maxOutputTokensForModel;
350
382
 
@@ -364,9 +396,11 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
364
396
  thinking: {
365
397
  type: thinkingType,
366
398
  ...(thinkingBudget != null && { budget_tokens: thinkingBudget }),
399
+ ...(thinkingDisplay != null && { display: thinkingDisplay }),
367
400
  },
368
401
  }),
369
402
  ...((anthropicOptions?.effort ||
403
+ anthropicOptions?.taskBudget ||
370
404
  (useStructuredOutput &&
371
405
  responseFormat?.type === 'json' &&
372
406
  responseFormat.schema != null)) && {
@@ -374,6 +408,15 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
374
408
  ...(anthropicOptions?.effort && {
375
409
  effort: anthropicOptions.effort,
376
410
  }),
411
+ ...(anthropicOptions?.taskBudget && {
412
+ task_budget: {
413
+ type: anthropicOptions.taskBudget.type,
414
+ total: anthropicOptions.taskBudget.total,
415
+ ...(anthropicOptions.taskBudget.remaining != null && {
416
+ remaining: anthropicOptions.taskBudget.remaining,
417
+ }),
418
+ },
419
+ }),
377
420
  ...(useStructuredOutput &&
378
421
  responseFormat?.type === 'json' &&
379
422
  responseFormat.schema != null && {
@@ -612,14 +655,16 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
612
655
  betas.add('effort-2025-11-24');
613
656
  }
614
657
 
658
+ if (anthropicOptions?.taskBudget) {
659
+ betas.add('task-budgets-2026-03-13');
660
+ }
661
+
615
662
  if (anthropicOptions?.speed === 'fast') {
616
663
  betas.add('fast-mode-2026-02-01');
617
664
  }
618
665
 
619
- // only when streaming: enable fine-grained tool streaming
620
- if (stream && (anthropicOptions?.toolStreaming ?? true)) {
621
- betas.add('fine-grained-tool-streaming-2025-05-14');
622
- }
666
+ const defaultEagerInputStreaming =
667
+ stream && (anthropicOptions?.toolStreaming ?? true);
623
668
 
624
669
  const {
625
670
  tools: anthropicTools,
@@ -635,6 +680,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
635
680
  cacheControlValidator,
636
681
  supportsStructuredOutput: false,
637
682
  supportsStrictTools,
683
+ defaultEagerInputStreaming,
638
684
  }
639
685
  : {
640
686
  tools: tools ?? [],
@@ -643,6 +689,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
643
689
  cacheControlValidator,
644
690
  supportsStructuredOutput,
645
691
  supportsStrictTools,
692
+ defaultEagerInputStreaming,
646
693
  },
647
694
  );
648
695
 
@@ -2284,15 +2331,24 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
2284
2331
  function getModelCapabilities(modelId: string): {
2285
2332
  maxOutputTokens: number;
2286
2333
  supportsStructuredOutput: boolean;
2334
+ rejectsSamplingParameters: boolean;
2287
2335
  isKnownModel: boolean;
2288
2336
  } {
2289
- if (
2337
+ if (modelId.includes('claude-opus-4-7')) {
2338
+ return {
2339
+ maxOutputTokens: 128000,
2340
+ supportsStructuredOutput: true,
2341
+ rejectsSamplingParameters: true,
2342
+ isKnownModel: true,
2343
+ };
2344
+ } else if (
2290
2345
  modelId.includes('claude-sonnet-4-6') ||
2291
2346
  modelId.includes('claude-opus-4-6')
2292
2347
  ) {
2293
2348
  return {
2294
2349
  maxOutputTokens: 128000,
2295
2350
  supportsStructuredOutput: true,
2351
+ rejectsSamplingParameters: false,
2296
2352
  isKnownModel: true,
2297
2353
  };
2298
2354
  } else if (
@@ -2303,36 +2359,42 @@ function getModelCapabilities(modelId: string): {
2303
2359
  return {
2304
2360
  maxOutputTokens: 64000,
2305
2361
  supportsStructuredOutput: true,
2362
+ rejectsSamplingParameters: false,
2306
2363
  isKnownModel: true,
2307
2364
  };
2308
2365
  } else if (modelId.includes('claude-opus-4-1')) {
2309
2366
  return {
2310
2367
  maxOutputTokens: 32000,
2311
2368
  supportsStructuredOutput: true,
2369
+ rejectsSamplingParameters: false,
2312
2370
  isKnownModel: true,
2313
2371
  };
2314
2372
  } else if (modelId.includes('claude-sonnet-4-')) {
2315
2373
  return {
2316
2374
  maxOutputTokens: 64000,
2317
2375
  supportsStructuredOutput: false,
2376
+ rejectsSamplingParameters: false,
2318
2377
  isKnownModel: true,
2319
2378
  };
2320
2379
  } else if (modelId.includes('claude-opus-4-')) {
2321
2380
  return {
2322
2381
  maxOutputTokens: 32000,
2323
2382
  supportsStructuredOutput: false,
2383
+ rejectsSamplingParameters: false,
2324
2384
  isKnownModel: true,
2325
2385
  };
2326
2386
  } else if (modelId.includes('claude-3-haiku')) {
2327
2387
  return {
2328
2388
  maxOutputTokens: 4096,
2329
2389
  supportsStructuredOutput: false,
2390
+ rejectsSamplingParameters: false,
2330
2391
  isKnownModel: true,
2331
2392
  };
2332
2393
  } else {
2333
2394
  return {
2334
2395
  maxOutputTokens: 4096,
2335
2396
  supportsStructuredOutput: false,
2397
+ rejectsSamplingParameters: false,
2336
2398
  isKnownModel: false,
2337
2399
  };
2338
2400
  }
@@ -17,6 +17,7 @@ export type AnthropicMessagesModelId =
17
17
  | 'claude-sonnet-4-5'
18
18
  | 'claude-sonnet-4-6'
19
19
  | 'claude-opus-4-6'
20
+ | 'claude-opus-4-7'
20
21
  | (string & {});
21
22
 
22
23
  /**
@@ -83,6 +84,12 @@ export const anthropicLanguageModelOptions = z.object({
83
84
  z.object({
84
85
  /** for Sonnet 4.6, Opus 4.6, and newer models */
85
86
  type: z.literal('adaptive'),
87
+ /**
88
+ * Controls whether thinking content is included in the response.
89
+ * - `"omitted"`: Thinking blocks are present but text is empty (default for Opus 4.7+).
90
+ * - `"summarized"`: Thinking content is returned. Required to see reasoning output.
91
+ */
92
+ display: z.enum(['omitted', 'summarized']).optional(),
86
93
  }),
87
94
  z.object({
88
95
  /** for models before Opus 4.6, except Sonnet 4.6 still supports it */
@@ -170,10 +177,11 @@ export const anthropicLanguageModelOptions = z.object({
170
177
  .optional(),
171
178
 
172
179
  /**
173
- * Whether to enable tool streaming (and structured output streaming).
174
- *
175
- * When set to false, the model will return all tool calls and results
176
- * at once after a delay.
180
+ * Whether to enable fine-grained (eager) streaming of tool call inputs
181
+ * and structured outputs for every function tool in the request. When
182
+ * true (the default), each function tool receives a default of
183
+ * `eager_input_streaming: true` unless it explicitly sets
184
+ * `providerOptions.anthropic.eagerInputStreaming`.
177
185
  *
178
186
  * @default true
179
187
  */
@@ -182,7 +190,22 @@ export const anthropicLanguageModelOptions = z.object({
182
190
  /**
183
191
  * @default 'high'
184
192
  */
185
- effort: z.enum(['low', 'medium', 'high', 'max']).optional(),
193
+ effort: z.enum(['low', 'medium', 'high', 'xhigh', 'max']).optional(),
194
+
195
+ /**
196
+ * Task budget for agentic turns. Informs the model of the total token budget
197
+ * available for the current task, allowing it to prioritize work and wind down
198
+ * gracefully as the budget is consumed.
199
+ *
200
+ * Advisory only — does not enforce a hard token limit.
201
+ */
202
+ taskBudget: z
203
+ .object({
204
+ type: z.literal('tokens'),
205
+ total: z.number().int().min(20000),
206
+ remaining: z.number().int().min(0).optional(),
207
+ })
208
+ .optional(),
186
209
 
187
210
  /**
188
211
  * Enable fast mode for faster inference (2.5x faster output token speeds).
@@ -27,6 +27,7 @@ export async function prepareTools({
27
27
  cacheControlValidator,
28
28
  supportsStructuredOutput,
29
29
  supportsStrictTools,
30
+ defaultEagerInputStreaming = false,
30
31
  }: {
31
32
  tools: LanguageModelV3CallOptions['tools'];
32
33
  toolChoice: LanguageModelV3CallOptions['toolChoice'] | undefined;
@@ -42,6 +43,12 @@ export async function prepareTools({
42
43
  * Whether the model supports strict mode on tool definitions.
43
44
  */
44
45
  supportsStrictTools: boolean;
46
+
47
+ /**
48
+ * Default for `eager_input_streaming` on function tools that do not set
49
+ * it explicitly. Driven by the model-level `toolStreaming` option.
50
+ */
51
+ defaultEagerInputStreaming?: boolean;
45
52
  }): Promise<{
46
53
  tools: Array<AnthropicTool> | undefined;
47
54
  toolChoice: AnthropicToolChoice | undefined;
@@ -73,8 +80,10 @@ export async function prepareTools({
73
80
  const anthropicOptions = tool.providerOptions?.anthropic as
74
81
  | AnthropicToolOptions
75
82
  | undefined;
76
- // eager_input_streaming is only supported on custom (function) tools
77
- const eagerInputStreaming = anthropicOptions?.eagerInputStreaming;
83
+ // eager_input_streaming is only supported on custom (function) tools.
84
+ // Fall back to the model-level default when the tool doesn't set it.
85
+ const eagerInputStreaming =
86
+ anthropicOptions?.eagerInputStreaming ?? defaultEagerInputStreaming;
78
87
  const deferLoading = anthropicOptions?.deferLoading;
79
88
  const allowedCallers = anthropicOptions?.allowedCallers;
80
89