@ai-sdk/anthropic 4.0.0-beta.4 → 4.0.0-beta.41

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.
Files changed (53) hide show
  1. package/CHANGELOG.md +305 -4
  2. package/README.md +2 -0
  3. package/dist/index.d.ts +83 -58
  4. package/dist/index.js +2043 -1356
  5. package/dist/index.js.map +1 -1
  6. package/dist/internal/index.d.ts +85 -58
  7. package/dist/internal/index.js +1804 -1342
  8. package/dist/internal/index.js.map +1 -1
  9. package/docs/05-anthropic.mdx +116 -13
  10. package/package.json +14 -15
  11. package/src/{anthropic-messages-api.ts → anthropic-api.ts} +14 -6
  12. package/src/anthropic-error.ts +1 -1
  13. package/src/anthropic-files.ts +95 -0
  14. package/src/{anthropic-messages-language-model.ts → anthropic-language-model.ts} +263 -78
  15. package/src/anthropic-message-metadata.ts +1 -4
  16. package/src/{anthropic-messages-options.ts → anthropic-options.ts} +68 -11
  17. package/src/anthropic-prepare-tools.ts +14 -7
  18. package/src/anthropic-provider.ts +42 -13
  19. package/src/{convert-anthropic-messages-usage.ts → convert-anthropic-usage.ts} +4 -4
  20. package/src/{convert-to-anthropic-messages-prompt.ts → convert-to-anthropic-prompt.ts} +190 -149
  21. package/src/forward-anthropic-container-id-from-last-step.ts +2 -2
  22. package/src/get-cache-control.ts +5 -2
  23. package/src/index.ts +1 -1
  24. package/src/internal/index.ts +11 -2
  25. package/src/map-anthropic-stop-reason.ts +1 -1
  26. package/src/sanitize-json-schema.ts +203 -0
  27. package/src/skills/anthropic-skills-api.ts +44 -0
  28. package/src/skills/anthropic-skills.ts +132 -0
  29. package/src/tool/bash_20241022.ts +2 -2
  30. package/src/tool/bash_20250124.ts +2 -2
  31. package/src/tool/code-execution_20250522.ts +2 -2
  32. package/src/tool/code-execution_20250825.ts +2 -2
  33. package/src/tool/code-execution_20260120.ts +2 -2
  34. package/src/tool/computer_20241022.ts +2 -2
  35. package/src/tool/computer_20250124.ts +2 -2
  36. package/src/tool/computer_20251124.ts +2 -2
  37. package/src/tool/memory_20250818.ts +2 -2
  38. package/src/tool/text-editor_20241022.ts +2 -2
  39. package/src/tool/text-editor_20250124.ts +2 -2
  40. package/src/tool/text-editor_20250429.ts +2 -2
  41. package/src/tool/text-editor_20250728.ts +6 -3
  42. package/src/tool/tool-search-bm25_20251119.ts +2 -2
  43. package/src/tool/tool-search-regex_20251119.ts +2 -2
  44. package/src/tool/web-fetch-20250910.ts +2 -2
  45. package/src/tool/web-fetch-20260209.ts +2 -2
  46. package/src/tool/web-search_20250305.ts +2 -2
  47. package/src/tool/web-search_20260209.ts +2 -2
  48. package/dist/index.d.mts +0 -1090
  49. package/dist/index.mjs +0 -5244
  50. package/dist/index.mjs.map +0 -1
  51. package/dist/internal/index.d.mts +0 -969
  52. package/dist/internal/index.mjs +0 -5136
  53. package/dist/internal/index.mjs.map +0 -1
@@ -1,57 +1,66 @@
1
1
  import {
2
2
  APICallError,
3
- JSONObject,
4
- LanguageModelV4,
5
- LanguageModelV4CallOptions,
6
- LanguageModelV4Content,
7
- LanguageModelV4FinishReason,
8
- LanguageModelV4FunctionTool,
9
- LanguageModelV4GenerateResult,
10
- LanguageModelV4Prompt,
11
- LanguageModelV4Source,
12
- LanguageModelV4StreamPart,
13
- LanguageModelV4StreamResult,
14
- LanguageModelV4ToolCall,
15
- SharedV4ProviderMetadata,
16
- SharedV4Warning,
3
+ type JSONObject,
4
+ type LanguageModelV4,
5
+ type LanguageModelV4CallOptions,
6
+ type LanguageModelV4Content,
7
+ type LanguageModelV4FinishReason,
8
+ type LanguageModelV4FunctionTool,
9
+ type LanguageModelV4GenerateResult,
10
+ type LanguageModelV4Prompt,
11
+ type LanguageModelV4Source,
12
+ type LanguageModelV4StreamPart,
13
+ type LanguageModelV4StreamResult,
14
+ type LanguageModelV4ToolCall,
15
+ type SharedV4ProviderMetadata,
16
+ type SharedV4Warning,
17
17
  } from '@ai-sdk/provider';
18
18
  import {
19
19
  combineHeaders,
20
20
  createEventSourceResponseHandler,
21
21
  createJsonResponseHandler,
22
22
  createToolNameMapping,
23
- FetchFunction,
24
23
  generateId,
25
- InferSchema,
24
+ isCustomReasoning,
25
+ mapReasoningToProviderBudget,
26
+ mapReasoningToProviderEffort,
26
27
  parseProviderOptions,
27
- ParseResult,
28
28
  postJsonToApi,
29
- Resolvable,
30
29
  resolve,
30
+ resolveProviderReference,
31
+ serializeModelOptions,
32
+ WORKFLOW_SERIALIZE,
33
+ WORKFLOW_DESERIALIZE,
34
+ type FetchFunction,
35
+ type InferSchema,
36
+ type ParseResult,
37
+ type Resolvable,
31
38
  } from '@ai-sdk/provider-utils';
32
39
  import { anthropicFailedResponseHandler } from './anthropic-error';
33
- import { AnthropicMessageMetadata } from './anthropic-message-metadata';
40
+ import type { AnthropicMessageMetadata } from './anthropic-message-metadata';
34
41
  import {
35
- AnthropicContainer,
36
- anthropicMessagesChunkSchema,
37
- anthropicMessagesResponseSchema,
38
- AnthropicReasoningMetadata,
39
- AnthropicResponseContextManagement,
40
- AnthropicTool,
41
- Citation,
42
- } from './anthropic-messages-api';
42
+ anthropicChunkSchema,
43
+ anthropicResponseSchema,
44
+ type AnthropicContainer,
45
+ type AnthropicReasoningMetadata,
46
+ type AnthropicResponseContextManagement,
47
+ type AnthropicTool,
48
+ type Citation,
49
+ } from './anthropic-api';
43
50
  import {
44
- AnthropicMessagesModelId,
45
51
  anthropicLanguageModelOptions,
46
- } from './anthropic-messages-options';
52
+ type AnthropicModelId,
53
+ type AnthropicLanguageModelOptions,
54
+ } from './anthropic-options';
47
55
  import { prepareTools } from './anthropic-prepare-tools';
48
56
  import {
49
- AnthropicMessagesUsage,
50
- convertAnthropicMessagesUsage,
51
- } from './convert-anthropic-messages-usage';
52
- import { convertToAnthropicMessagesPrompt } from './convert-to-anthropic-messages-prompt';
57
+ convertAnthropicUsage,
58
+ type AnthropicUsage,
59
+ } from './convert-anthropic-usage';
60
+ import { convertToAnthropicPrompt } from './convert-to-anthropic-prompt';
53
61
  import { CacheControlValidator } from './get-cache-control';
54
62
  import { mapAnthropicStopReason } from './map-anthropic-stop-reason';
63
+ import { sanitizeJsonSchema } from './sanitize-json-schema';
55
64
 
56
65
  function createCitationSource(
57
66
  citation: Citation,
@@ -112,10 +121,10 @@ function createCitationSource(
112
121
  };
113
122
  }
114
123
 
115
- type AnthropicMessagesConfig = {
124
+ type AnthropicLanguageModelConfig = {
116
125
  provider: string;
117
126
  baseURL: string;
118
- headers: Resolvable<Record<string, string | undefined>>;
127
+ headers?: Resolvable<Record<string, string | undefined>>;
119
128
  fetch?: FetchFunction;
120
129
  buildRequestUrl?: (baseURL: string, isStreaming: boolean) => string;
121
130
  transformRequestBody?: (
@@ -137,18 +146,29 @@ type AnthropicMessagesConfig = {
137
146
  supportsStrictTools?: boolean;
138
147
  };
139
148
 
140
- export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
149
+ export class AnthropicLanguageModel implements LanguageModelV4 {
141
150
  readonly specificationVersion = 'v4';
142
151
 
143
- readonly modelId: AnthropicMessagesModelId;
152
+ readonly modelId: AnthropicModelId;
144
153
 
145
- private readonly config: AnthropicMessagesConfig;
154
+ private readonly config: AnthropicLanguageModelConfig;
146
155
  private readonly generateId: () => string;
147
156
 
148
- constructor(
149
- modelId: AnthropicMessagesModelId,
150
- config: AnthropicMessagesConfig,
151
- ) {
157
+ static [WORKFLOW_SERIALIZE](model: AnthropicLanguageModel) {
158
+ return serializeModelOptions({
159
+ modelId: model.modelId,
160
+ config: model.config,
161
+ });
162
+ }
163
+
164
+ static [WORKFLOW_DESERIALIZE](options: {
165
+ modelId: AnthropicModelId;
166
+ config: AnthropicLanguageModelConfig;
167
+ }) {
168
+ return new AnthropicLanguageModel(options.modelId, options.config);
169
+ }
170
+
171
+ constructor(modelId: AnthropicModelId, config: AnthropicLanguageModelConfig) {
152
172
  this.modelId = modelId;
153
173
  this.config = config;
154
174
  this.generateId = config.generateId ?? generateId;
@@ -190,6 +210,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
190
210
  seed,
191
211
  tools,
192
212
  toolChoice,
213
+ reasoning,
193
214
  providerOptions,
194
215
  stream,
195
216
  }: LanguageModelV4CallOptions & {
@@ -269,9 +290,41 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
269
290
  const {
270
291
  maxOutputTokens: maxOutputTokensForModel,
271
292
  supportsStructuredOutput: modelSupportsStructuredOutput,
293
+ supportsAdaptiveThinking,
294
+ rejectsSamplingParameters,
295
+ supportsXhighEffort,
272
296
  isKnownModel,
273
297
  } = getModelCapabilities(this.modelId);
274
298
 
299
+ if (rejectsSamplingParameters) {
300
+ if (temperature != null) {
301
+ warnings.push({
302
+ type: 'unsupported',
303
+ feature: 'temperature',
304
+ details: `temperature is not supported by ${this.modelId} and will be ignored`,
305
+ });
306
+ temperature = undefined;
307
+ }
308
+ if (topK != null) {
309
+ warnings.push({
310
+ type: 'unsupported',
311
+ feature: 'topK',
312
+ details: `topK is not supported by ${this.modelId} and will be ignored`,
313
+ });
314
+ topK = undefined;
315
+ }
316
+ if (topP != null) {
317
+ warnings.push({
318
+ type: 'unsupported',
319
+ feature: 'topP',
320
+ details: `topP is not supported by ${this.modelId} and will be ignored`,
321
+ });
322
+ topP = undefined;
323
+ }
324
+ }
325
+
326
+ const isAnthropicModel = isKnownModel || this.modelId.startsWith('claude-');
327
+
275
328
  const supportsStructuredOutput =
276
329
  (this.config.supportsNativeStructuredOutput ?? true) &&
277
330
  modelSupportsStructuredOutput;
@@ -327,14 +380,38 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
327
380
  },
328
381
  });
329
382
 
330
- const { prompt: messagesPrompt, betas } =
331
- await convertToAnthropicMessagesPrompt({
332
- prompt,
333
- sendReasoning: anthropicOptions?.sendReasoning ?? true,
383
+ const { prompt: messagesPrompt, betas } = await convertToAnthropicPrompt({
384
+ prompt,
385
+ sendReasoning: anthropicOptions?.sendReasoning ?? true,
386
+ warnings,
387
+ cacheControlValidator,
388
+ toolNameMapping,
389
+ });
390
+
391
+ /*
392
+ * Map top-level `reasoning` to Anthropic thinking/effort when provider
393
+ * options don't already specify them. Provider options always take precedence.
394
+ */
395
+ if (isCustomReasoning(reasoning) && anthropicOptions?.effort == null) {
396
+ const reasoningConfig = resolveAnthropicReasoningConfig({
397
+ reasoning,
398
+ supportsAdaptiveThinking,
399
+ supportsXhighEffort,
400
+ maxOutputTokensForModel,
334
401
  warnings,
335
- cacheControlValidator,
336
- toolNameMapping,
337
402
  });
403
+ if (reasoningConfig != null) {
404
+ if (anthropicOptions.thinking == null) {
405
+ anthropicOptions.thinking = reasoningConfig.thinking;
406
+ }
407
+ if (
408
+ reasoningConfig.effort != null &&
409
+ anthropicOptions.thinking?.type !== 'disabled'
410
+ ) {
411
+ anthropicOptions.effort = reasoningConfig.effort;
412
+ }
413
+ }
414
+ }
338
415
 
339
416
  const thinkingType = anthropicOptions?.thinking?.type;
340
417
  const isThinking =
@@ -343,6 +420,10 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
343
420
  thinkingType === 'enabled'
344
421
  ? anthropicOptions?.thinking?.budgetTokens
345
422
  : undefined;
423
+ const thinkingDisplay =
424
+ thinkingType === 'adaptive'
425
+ ? anthropicOptions?.thinking?.display
426
+ : undefined;
346
427
 
347
428
  const maxTokens = maxOutputTokens ?? maxOutputTokensForModel;
348
429
 
@@ -362,9 +443,11 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
362
443
  thinking: {
363
444
  type: thinkingType,
364
445
  ...(thinkingBudget != null && { budget_tokens: thinkingBudget }),
446
+ ...(thinkingDisplay != null && { display: thinkingDisplay }),
365
447
  },
366
448
  }),
367
449
  ...((anthropicOptions?.effort ||
450
+ anthropicOptions?.taskBudget ||
368
451
  (useStructuredOutput &&
369
452
  responseFormat?.type === 'json' &&
370
453
  responseFormat.schema != null)) && {
@@ -372,12 +455,21 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
372
455
  ...(anthropicOptions?.effort && {
373
456
  effort: anthropicOptions.effort,
374
457
  }),
458
+ ...(anthropicOptions?.taskBudget && {
459
+ task_budget: {
460
+ type: anthropicOptions.taskBudget.type,
461
+ total: anthropicOptions.taskBudget.total,
462
+ ...(anthropicOptions.taskBudget.remaining != null && {
463
+ remaining: anthropicOptions.taskBudget.remaining,
464
+ }),
465
+ },
466
+ }),
375
467
  ...(useStructuredOutput &&
376
468
  responseFormat?.type === 'json' &&
377
469
  responseFormat.schema != null && {
378
470
  format: {
379
471
  type: 'json_schema',
380
- schema: responseFormat.schema,
472
+ schema: sanitizeJsonSchema(responseFormat.schema),
381
473
  },
382
474
  }),
383
475
  },
@@ -385,9 +477,15 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
385
477
  ...(anthropicOptions?.speed && {
386
478
  speed: anthropicOptions.speed,
387
479
  }),
480
+ ...(anthropicOptions?.inferenceGeo && {
481
+ inference_geo: anthropicOptions.inferenceGeo,
482
+ }),
388
483
  ...(anthropicOptions?.cacheControl && {
389
484
  cache_control: anthropicOptions.cacheControl,
390
485
  }),
486
+ ...(anthropicOptions?.metadata?.userId != null && {
487
+ metadata: { user_id: anthropicOptions.metadata.userId },
488
+ }),
391
489
 
392
490
  // mcp servers:
393
491
  ...(anthropicOptions?.mcpServers &&
@@ -416,7 +514,13 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
416
514
  id: anthropicOptions.container.id,
417
515
  skills: anthropicOptions.container.skills.map(skill => ({
418
516
  type: skill.type,
419
- skill_id: skill.skillId,
517
+ skill_id:
518
+ skill.type === 'custom'
519
+ ? resolveProviderReference({
520
+ reference: skill.providerReference,
521
+ provider: 'anthropic',
522
+ })
523
+ : skill.skillId,
420
524
  version: skill.version,
421
525
  })),
422
526
  } satisfies AnthropicContainer)
@@ -532,8 +636,10 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
532
636
  // adjust max tokens to account for thinking:
533
637
  baseArgs.max_tokens = maxTokens + (thinkingBudget ?? 0);
534
638
  } else {
535
- // Only check temperature/topP mutual exclusivity when thinking is not enabled
536
- if (topP != null && temperature != null) {
639
+ // Only check temperature/topP mutual exclusivity for known Anthropic models
640
+ // when thinking is not enabled. Non-Anthropic models using the Anthropic-compatible
641
+ // API (e.g. Minimax) may require both parameters to be set.
642
+ if (isAnthropicModel && topP != null && temperature != null) {
537
643
  warnings.push({
538
644
  type: 'unsupported',
539
645
  feature: 'topP',
@@ -602,14 +708,16 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
602
708
  betas.add('effort-2025-11-24');
603
709
  }
604
710
 
711
+ if (anthropicOptions?.taskBudget) {
712
+ betas.add('task-budgets-2026-03-13');
713
+ }
714
+
605
715
  if (anthropicOptions?.speed === 'fast') {
606
716
  betas.add('fast-mode-2026-02-01');
607
717
  }
608
718
 
609
- // only when streaming: enable fine-grained tool streaming
610
- if (stream && (anthropicOptions?.toolStreaming ?? true)) {
611
- betas.add('fine-grained-tool-streaming-2025-05-14');
612
- }
719
+ const defaultEagerInputStreaming =
720
+ stream && (anthropicOptions?.toolStreaming ?? true);
613
721
 
614
722
  const {
615
723
  tools: anthropicTools,
@@ -625,6 +733,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
625
733
  cacheControlValidator,
626
734
  supportsStructuredOutput: false,
627
735
  supportsStrictTools,
736
+ defaultEagerInputStreaming,
628
737
  }
629
738
  : {
630
739
  tools: tools ?? [],
@@ -633,6 +742,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
633
742
  cacheControlValidator,
634
743
  supportsStructuredOutput,
635
744
  supportsStrictTools,
745
+ defaultEagerInputStreaming,
636
746
  },
637
747
  );
638
748
 
@@ -668,7 +778,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
668
778
  headers: Record<string, string | undefined> | undefined;
669
779
  }) {
670
780
  return combineHeaders(
671
- await resolve(this.config.headers),
781
+ this.config.headers ? await resolve(this.config.headers) : undefined,
672
782
  headers,
673
783
  betas.size > 0 ? { 'anthropic-beta': Array.from(betas).join(',') } : {},
674
784
  );
@@ -677,9 +787,11 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
677
787
  private async getBetasFromHeaders(
678
788
  requestHeaders: Record<string, string | undefined> | undefined,
679
789
  ) {
680
- const configHeaders = await resolve(this.config.headers);
790
+ const configHeaders = this.config.headers
791
+ ? await resolve(this.config.headers)
792
+ : undefined;
681
793
 
682
- const configBetaHeader = configHeaders['anthropic-beta'] ?? '';
794
+ const configBetaHeader = configHeaders?.['anthropic-beta'] ?? '';
683
795
  const requestBetaHeader = requestHeaders?.['anthropic-beta'] ?? '';
684
796
 
685
797
  return new Set(
@@ -785,7 +897,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
785
897
  body: this.transformRequestBody(args, betas),
786
898
  failedResponseHandler: anthropicFailedResponseHandler,
787
899
  successfulResponseHandler: createJsonResponseHandler(
788
- anthropicMessagesResponseSchema,
900
+ anthropicResponseSchema,
789
901
  ),
790
902
  abortSignal: options.abortSignal,
791
903
  fetch: this.config.fetch,
@@ -1176,7 +1288,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
1176
1288
  }),
1177
1289
  raw: response.stop_reason ?? undefined,
1178
1290
  },
1179
- usage: convertAnthropicMessagesUsage({ usage: response.usage }),
1291
+ usage: convertAnthropicUsage({ usage: response.usage }),
1180
1292
  request: { body: args },
1181
1293
  response: {
1182
1294
  id: response.id ?? undefined,
@@ -1188,8 +1300,6 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
1188
1300
  providerMetadata: (() => {
1189
1301
  const anthropicMetadata = {
1190
1302
  usage: response.usage as JSONObject,
1191
- cacheCreationInputTokens:
1192
- response.usage.cache_creation_input_tokens ?? null,
1193
1303
  stopSequence: response.stop_sequence ?? null,
1194
1304
 
1195
1305
  iterations: response.usage.iterations
@@ -1233,6 +1343,8 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
1233
1343
  async doStream(
1234
1344
  options: LanguageModelV4CallOptions,
1235
1345
  ): Promise<LanguageModelV4StreamResult> {
1346
+ 'use step';
1347
+
1236
1348
  const {
1237
1349
  args: body,
1238
1350
  warnings,
@@ -1262,9 +1374,8 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
1262
1374
  headers: await this.getHeaders({ betas, headers: options.headers }),
1263
1375
  body: this.transformRequestBody(body, betas),
1264
1376
  failedResponseHandler: anthropicFailedResponseHandler,
1265
- successfulResponseHandler: createEventSourceResponseHandler(
1266
- anthropicMessagesChunkSchema,
1267
- ),
1377
+ successfulResponseHandler:
1378
+ createEventSourceResponseHandler(anthropicChunkSchema),
1268
1379
  abortSignal: options.abortSignal,
1269
1380
  fetch: this.config.fetch,
1270
1381
  });
@@ -1273,7 +1384,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
1273
1384
  unified: 'other',
1274
1385
  raw: undefined,
1275
1386
  };
1276
- const usage: AnthropicMessagesUsage = {
1387
+ const usage: AnthropicUsage = {
1277
1388
  input_tokens: 0,
1278
1389
  output_tokens: 0,
1279
1390
  cache_creation_input_tokens: 0,
@@ -1308,7 +1419,6 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
1308
1419
  | AnthropicMessageMetadata['contextManagement']
1309
1420
  | null = null;
1310
1421
  let rawUsage: JSONObject | undefined = undefined;
1311
- let cacheCreationInputTokens: number | null = null;
1312
1422
  let stopSequence: string | null = null;
1313
1423
  let container: AnthropicMessageMetadata['container'] | null = null;
1314
1424
  let isJsonResponseFromTool = false;
@@ -1334,7 +1444,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
1334
1444
 
1335
1445
  const transformedStream = response.pipeThrough(
1336
1446
  new TransformStream<
1337
- ParseResult<InferSchema<typeof anthropicMessagesChunkSchema>>,
1447
+ ParseResult<InferSchema<typeof anthropicChunkSchema>>,
1338
1448
  LanguageModelV4StreamPart
1339
1449
  >({
1340
1450
  start(controller) {
@@ -2028,9 +2138,6 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
2028
2138
  ...(value.message.usage as JSONObject),
2029
2139
  };
2030
2140
 
2031
- cacheCreationInputTokens =
2032
- value.message.usage.cache_creation_input_tokens ?? null;
2033
-
2034
2141
  if (value.message.container != null) {
2035
2142
  container = {
2036
2143
  expiresAt: value.message.container.expires_at,
@@ -2128,8 +2235,6 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
2128
2235
  if (value.usage.cache_creation_input_tokens != null) {
2129
2236
  usage.cache_creation_input_tokens =
2130
2237
  value.usage.cache_creation_input_tokens;
2131
- cacheCreationInputTokens =
2132
- value.usage.cache_creation_input_tokens;
2133
2238
  }
2134
2239
  if (value.usage.iterations != null) {
2135
2240
  usage.iterations = value.usage.iterations;
@@ -2175,7 +2280,6 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
2175
2280
  case 'message_stop': {
2176
2281
  const anthropicMetadata = {
2177
2282
  usage: (rawUsage as JSONObject) ?? null,
2178
- cacheCreationInputTokens,
2179
2283
  stopSequence,
2180
2284
  iterations: usage.iterations
2181
2285
  ? usage.iterations.map(iter => ({
@@ -2202,7 +2306,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
2202
2306
  controller.enqueue({
2203
2307
  type: 'finish',
2204
2308
  finishReason,
2205
- usage: convertAnthropicMessagesUsage({ usage, rawUsage }),
2309
+ usage: convertAnthropicUsage({ usage, rawUsage }),
2206
2310
  providerMetadata,
2207
2311
  });
2208
2312
  return;
@@ -2271,18 +2375,33 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
2271
2375
  * @see https://docs.claude.com/en/docs/about-claude/models/overview#model-comparison-table
2272
2376
  * @see https://platform.claude.com/docs/en/build-with-claude/structured-outputs
2273
2377
  */
2274
- function getModelCapabilities(modelId: string): {
2378
+ export function getModelCapabilities(modelId: string): {
2275
2379
  maxOutputTokens: number;
2276
2380
  supportsStructuredOutput: boolean;
2381
+ supportsAdaptiveThinking: boolean;
2382
+ rejectsSamplingParameters: boolean;
2383
+ supportsXhighEffort: boolean;
2277
2384
  isKnownModel: boolean;
2278
2385
  } {
2279
- if (
2386
+ if (modelId.includes('claude-opus-4-7')) {
2387
+ return {
2388
+ maxOutputTokens: 128000,
2389
+ supportsStructuredOutput: true,
2390
+ supportsAdaptiveThinking: true,
2391
+ rejectsSamplingParameters: true,
2392
+ supportsXhighEffort: true,
2393
+ isKnownModel: true,
2394
+ };
2395
+ } else if (
2280
2396
  modelId.includes('claude-sonnet-4-6') ||
2281
2397
  modelId.includes('claude-opus-4-6')
2282
2398
  ) {
2283
2399
  return {
2284
2400
  maxOutputTokens: 128000,
2285
2401
  supportsStructuredOutput: true,
2402
+ supportsAdaptiveThinking: true,
2403
+ rejectsSamplingParameters: false,
2404
+ supportsXhighEffort: false,
2286
2405
  isKnownModel: true,
2287
2406
  };
2288
2407
  } else if (
@@ -2293,36 +2412,54 @@ function getModelCapabilities(modelId: string): {
2293
2412
  return {
2294
2413
  maxOutputTokens: 64000,
2295
2414
  supportsStructuredOutput: true,
2415
+ supportsAdaptiveThinking: false,
2416
+ rejectsSamplingParameters: false,
2417
+ supportsXhighEffort: false,
2296
2418
  isKnownModel: true,
2297
2419
  };
2298
2420
  } else if (modelId.includes('claude-opus-4-1')) {
2299
2421
  return {
2300
2422
  maxOutputTokens: 32000,
2301
2423
  supportsStructuredOutput: true,
2424
+ supportsAdaptiveThinking: false,
2425
+ rejectsSamplingParameters: false,
2426
+ supportsXhighEffort: false,
2302
2427
  isKnownModel: true,
2303
2428
  };
2304
2429
  } else if (modelId.includes('claude-sonnet-4-')) {
2305
2430
  return {
2306
2431
  maxOutputTokens: 64000,
2307
2432
  supportsStructuredOutput: false,
2433
+ supportsAdaptiveThinking: false,
2434
+ rejectsSamplingParameters: false,
2435
+ supportsXhighEffort: false,
2308
2436
  isKnownModel: true,
2309
2437
  };
2310
2438
  } else if (modelId.includes('claude-opus-4-')) {
2311
2439
  return {
2312
2440
  maxOutputTokens: 32000,
2313
2441
  supportsStructuredOutput: false,
2442
+ supportsAdaptiveThinking: false,
2443
+ rejectsSamplingParameters: false,
2444
+ supportsXhighEffort: false,
2314
2445
  isKnownModel: true,
2315
2446
  };
2316
2447
  } else if (modelId.includes('claude-3-haiku')) {
2317
2448
  return {
2318
2449
  maxOutputTokens: 4096,
2319
2450
  supportsStructuredOutput: false,
2451
+ supportsAdaptiveThinking: false,
2452
+ rejectsSamplingParameters: false,
2453
+ supportsXhighEffort: false,
2320
2454
  isKnownModel: true,
2321
2455
  };
2322
2456
  } else {
2323
2457
  return {
2324
2458
  maxOutputTokens: 4096,
2325
2459
  supportsStructuredOutput: false,
2460
+ supportsAdaptiveThinking: false,
2461
+ rejectsSamplingParameters: false,
2462
+ supportsXhighEffort: false,
2326
2463
  isKnownModel: false,
2327
2464
  };
2328
2465
  }
@@ -2353,6 +2490,54 @@ function hasWebTool20260209WithoutCodeExecution(
2353
2490
  return hasWebTool20260209 && !hasCodeExecutionTool;
2354
2491
  }
2355
2492
 
2493
+ function resolveAnthropicReasoningConfig({
2494
+ reasoning,
2495
+ supportsAdaptiveThinking,
2496
+ supportsXhighEffort,
2497
+ maxOutputTokensForModel,
2498
+ warnings,
2499
+ }: {
2500
+ reasoning: LanguageModelV4CallOptions['reasoning'];
2501
+ supportsAdaptiveThinking: boolean;
2502
+ supportsXhighEffort: boolean;
2503
+ maxOutputTokensForModel: number;
2504
+ warnings: SharedV4Warning[];
2505
+ }): Pick<AnthropicLanguageModelOptions, 'thinking' | 'effort'> | undefined {
2506
+ if (!isCustomReasoning(reasoning)) {
2507
+ return undefined;
2508
+ }
2509
+
2510
+ if (reasoning === 'none') {
2511
+ return { thinking: { type: 'disabled' } };
2512
+ }
2513
+
2514
+ if (supportsAdaptiveThinking) {
2515
+ const effort = mapReasoningToProviderEffort({
2516
+ reasoning,
2517
+ effortMap: {
2518
+ minimal: 'low' as const,
2519
+ low: 'low' as const,
2520
+ medium: 'medium' as const,
2521
+ high: 'high' as const,
2522
+ xhigh: supportsXhighEffort ? ('xhigh' as const) : ('max' as const),
2523
+ },
2524
+ warnings,
2525
+ });
2526
+ return { thinking: { type: 'adaptive' }, effort };
2527
+ }
2528
+
2529
+ const budgetTokens = mapReasoningToProviderBudget({
2530
+ reasoning,
2531
+ maxOutputTokens: maxOutputTokensForModel,
2532
+ maxReasoningBudget: maxOutputTokensForModel,
2533
+ warnings,
2534
+ });
2535
+ if (budgetTokens == null) {
2536
+ return undefined;
2537
+ }
2538
+ return { thinking: { type: 'enabled', budgetTokens } };
2539
+ }
2540
+
2356
2541
  function mapAnthropicResponseContextManagement(
2357
2542
  contextManagement: AnthropicResponseContextManagement | null | undefined,
2358
2543
  ): AnthropicMessageMetadata['contextManagement'] | null {
@@ -1,4 +1,4 @@
1
- import { JSONObject } from '@ai-sdk/provider';
1
+ import type { JSONObject } from '@ai-sdk/provider';
2
2
 
3
3
  /**
4
4
  * Represents a single iteration in the usage breakdown.
@@ -21,9 +21,6 @@ export interface AnthropicUsageIteration {
21
21
 
22
22
  export interface AnthropicMessageMetadata {
23
23
  usage: JSONObject;
24
- // TODO remove cacheCreationInputTokens in AI SDK 6
25
- // (use value in usage object instead)
26
- cacheCreationInputTokens: number | null;
27
24
  stopSequence: string | null;
28
25
 
29
26
  /**