@ai-sdk/anthropic 2.0.79 → 2.0.81

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.
@@ -2,7 +2,7 @@ import { LanguageModelV2, JSONSchema7, SharedV2ProviderMetadata, LanguageModelV2
2
2
  import * as _ai_sdk_provider_utils from '@ai-sdk/provider-utils';
3
3
  import { Resolvable, FetchFunction } from '@ai-sdk/provider-utils';
4
4
 
5
- type AnthropicMessagesModelId = 'claude-3-5-haiku-20241022' | 'claude-3-5-haiku-latest' | 'claude-3-7-sonnet-20250219' | 'claude-3-7-sonnet-latest' | 'claude-3-haiku-20240307' | 'claude-haiku-4-5-20251001' | 'claude-haiku-4-5' | 'claude-opus-4-0' | 'claude-opus-4-1-20250805' | 'claude-opus-4-1' | 'claude-opus-4-20250514' | 'claude-opus-4-5' | 'claude-opus-4-5-20251101' | 'claude-sonnet-4-0' | 'claude-sonnet-4-20250514' | 'claude-sonnet-4-5-20250929' | 'claude-sonnet-4-5' | 'claude-sonnet-4-6' | 'claude-opus-4-6' | 'claude-opus-4-7' | (string & {});
5
+ type AnthropicMessagesModelId = 'claude-3-5-haiku-20241022' | 'claude-3-5-haiku-latest' | 'claude-3-7-sonnet-20250219' | 'claude-3-7-sonnet-latest' | 'claude-3-haiku-20240307' | 'claude-haiku-4-5-20251001' | 'claude-haiku-4-5' | 'claude-opus-4-0' | 'claude-opus-4-1-20250805' | 'claude-opus-4-1' | 'claude-opus-4-20250514' | 'claude-opus-4-5' | 'claude-opus-4-5-20251101' | 'claude-sonnet-4-0' | 'claude-sonnet-4-20250514' | 'claude-sonnet-4-5-20250929' | 'claude-sonnet-4-5' | 'claude-sonnet-4-6' | 'claude-opus-4-6' | 'claude-opus-4-7' | 'claude-opus-4-8' | 'claude-fable-5' | (string & {});
6
6
 
7
7
  type AnthropicMessagesConfig = {
8
8
  provider: string;
@@ -2,7 +2,7 @@ import { LanguageModelV2, JSONSchema7, SharedV2ProviderMetadata, LanguageModelV2
2
2
  import * as _ai_sdk_provider_utils from '@ai-sdk/provider-utils';
3
3
  import { Resolvable, FetchFunction } from '@ai-sdk/provider-utils';
4
4
 
5
- type AnthropicMessagesModelId = 'claude-3-5-haiku-20241022' | 'claude-3-5-haiku-latest' | 'claude-3-7-sonnet-20250219' | 'claude-3-7-sonnet-latest' | 'claude-3-haiku-20240307' | 'claude-haiku-4-5-20251001' | 'claude-haiku-4-5' | 'claude-opus-4-0' | 'claude-opus-4-1-20250805' | 'claude-opus-4-1' | 'claude-opus-4-20250514' | 'claude-opus-4-5' | 'claude-opus-4-5-20251101' | 'claude-sonnet-4-0' | 'claude-sonnet-4-20250514' | 'claude-sonnet-4-5-20250929' | 'claude-sonnet-4-5' | 'claude-sonnet-4-6' | 'claude-opus-4-6' | 'claude-opus-4-7' | (string & {});
5
+ type AnthropicMessagesModelId = 'claude-3-5-haiku-20241022' | 'claude-3-5-haiku-latest' | 'claude-3-7-sonnet-20250219' | 'claude-3-7-sonnet-latest' | 'claude-3-haiku-20240307' | 'claude-haiku-4-5-20251001' | 'claude-haiku-4-5' | 'claude-opus-4-0' | 'claude-opus-4-1-20250805' | 'claude-opus-4-1' | 'claude-opus-4-20250514' | 'claude-opus-4-5' | 'claude-opus-4-5-20251101' | 'claude-sonnet-4-0' | 'claude-sonnet-4-20250514' | 'claude-sonnet-4-5-20250929' | 'claude-sonnet-4-5' | 'claude-sonnet-4-6' | 'claude-opus-4-6' | 'claude-opus-4-7' | 'claude-opus-4-8' | 'claude-fable-5' | (string & {});
6
6
 
7
7
  type AnthropicMessagesConfig = {
8
8
  provider: string;
@@ -52,6 +52,12 @@ var anthropicFailedResponseHandler = (0, import_provider_utils.createJsonErrorRe
52
52
  // src/anthropic-messages-api.ts
53
53
  var import_provider_utils2 = require("@ai-sdk/provider-utils");
54
54
  var import_v42 = require("zod/v4");
55
+ var anthropicStopDetailsSchema = import_v42.z.object({
56
+ type: import_v42.z.string(),
57
+ category: import_v42.z.string().nullish(),
58
+ explanation: import_v42.z.string().nullish(),
59
+ recommended_model: import_v42.z.string().nullish()
60
+ });
55
61
  var anthropicMessagesResponseSchema = (0, import_provider_utils2.lazySchema)(
56
62
  () => (0, import_provider_utils2.zodSchema)(
57
63
  import_v42.z.object({
@@ -239,11 +245,18 @@ var anthropicMessagesResponseSchema = (0, import_provider_utils2.lazySchema)(
239
245
  old_start: import_v42.z.number().nullable()
240
246
  })
241
247
  ])
248
+ }),
249
+ // Server-side fallback marker. Parsed so the response validates, but
250
+ // dropped from the content output (the AI SDK has no model-hop
251
+ // primitive). The hop remains observable via usage.iterations.
252
+ import_v42.z.object({
253
+ type: import_v42.z.literal("fallback")
242
254
  })
243
255
  ])
244
256
  ),
245
257
  stop_reason: import_v42.z.string().nullish(),
246
258
  stop_sequence: import_v42.z.string().nullish(),
259
+ stop_details: anthropicStopDetailsSchema.nullish(),
247
260
  usage: import_v42.z.looseObject({
248
261
  input_tokens: import_v42.z.number(),
249
262
  output_tokens: import_v42.z.number(),
@@ -251,9 +264,17 @@ var anthropicMessagesResponseSchema = (0, import_provider_utils2.lazySchema)(
251
264
  cache_read_input_tokens: import_v42.z.number().nullish(),
252
265
  iterations: import_v42.z.array(
253
266
  import_v42.z.object({
254
- type: import_v42.z.union([import_v42.z.literal("compaction"), import_v42.z.literal("message")]),
267
+ type: import_v42.z.union([
268
+ import_v42.z.literal("compaction"),
269
+ import_v42.z.literal("message"),
270
+ import_v42.z.literal("advisor_message"),
271
+ import_v42.z.literal("fallback_message")
272
+ ]),
273
+ model: import_v42.z.string().nullish(),
255
274
  input_tokens: import_v42.z.number(),
256
- output_tokens: import_v42.z.number()
275
+ output_tokens: import_v42.z.number(),
276
+ cache_creation_input_tokens: import_v42.z.number().nullish(),
277
+ cache_read_input_tokens: import_v42.z.number().nullish()
257
278
  })
258
279
  ).nullish()
259
280
  }),
@@ -459,6 +480,11 @@ var anthropicMessagesChunkSchema = (0, import_provider_utils2.lazySchema)(
459
480
  old_start: import_v42.z.number().nullable()
460
481
  })
461
482
  ])
483
+ }),
484
+ // Server-side fallback marker; dropped from content output (see the
485
+ // response schema). The hop remains observable via usage.iterations.
486
+ import_v42.z.object({
487
+ type: import_v42.z.literal("fallback")
462
488
  })
463
489
  ])
464
490
  }),
@@ -532,6 +558,7 @@ var anthropicMessagesChunkSchema = (0, import_provider_utils2.lazySchema)(
532
558
  delta: import_v42.z.object({
533
559
  stop_reason: import_v42.z.string().nullish(),
534
560
  stop_sequence: import_v42.z.string().nullish(),
561
+ stop_details: anthropicStopDetailsSchema.nullish(),
535
562
  container: import_v42.z.object({
536
563
  expires_at: import_v42.z.string(),
537
564
  id: import_v42.z.string(),
@@ -554,9 +581,17 @@ var anthropicMessagesChunkSchema = (0, import_provider_utils2.lazySchema)(
554
581
  cache_read_input_tokens: import_v42.z.number().nullish(),
555
582
  iterations: import_v42.z.array(
556
583
  import_v42.z.object({
557
- type: import_v42.z.union([import_v42.z.literal("compaction"), import_v42.z.literal("message")]),
584
+ type: import_v42.z.union([
585
+ import_v42.z.literal("compaction"),
586
+ import_v42.z.literal("message"),
587
+ import_v42.z.literal("advisor_message"),
588
+ import_v42.z.literal("fallback_message")
589
+ ]),
590
+ model: import_v42.z.string().nullish(),
558
591
  input_tokens: import_v42.z.number(),
559
- output_tokens: import_v42.z.number()
592
+ output_tokens: import_v42.z.number(),
593
+ cache_creation_input_tokens: import_v42.z.number().nullish(),
594
+ cache_read_input_tokens: import_v42.z.number().nullish()
560
595
  })
561
596
  ).nullish()
562
597
  }),
@@ -731,6 +766,31 @@ var anthropicProviderOptions = import_v43.z.object({
731
766
  * See https://platform.claude.com/docs/en/build-with-claude/data-residency
732
767
  */
733
768
  inferenceGeo: import_v43.z.enum(["us", "global"]).optional(),
769
+ /**
770
+ * Server-side fallback chain.
771
+ *
772
+ * When the primary model's safety classifiers block a turn, the API
773
+ * automatically retries it on the next model in the chain, server-side. A
774
+ * `content-filter` finish reason means the entire chain refused.
775
+ *
776
+ * Each entry is merged into the request as a direct request to that entry's
777
+ * model, so it must be formatted accordingly: `model` is required, and an
778
+ * entry may additionally override `max_tokens`, `thinking`, `output_config`,
779
+ * and `speed` for that attempt only (`speed` additionally requires the speed
780
+ * beta). The value is passed through to the API as-is.
781
+ *
782
+ * The required `server-side-fallback-2026-06-01` beta is added automatically
783
+ * when this option is set.
784
+ */
785
+ fallbacks: import_v43.z.array(
786
+ import_v43.z.object({
787
+ model: import_v43.z.string(),
788
+ max_tokens: import_v43.z.number().int().optional(),
789
+ thinking: import_v43.z.record(import_v43.z.string(), import_v43.z.unknown()).optional(),
790
+ output_config: import_v43.z.record(import_v43.z.string(), import_v43.z.unknown()).optional(),
791
+ speed: import_v43.z.enum(["fast", "standard"]).optional()
792
+ })
793
+ ).optional(),
734
794
  /**
735
795
  * Context management configuration for automatic context window management.
736
796
  * Enables features like automatic compaction and clearing of tool uses/thinking blocks.
@@ -1401,19 +1461,20 @@ async function convertToAnthropicMessagesPrompt({
1401
1461
  const type = block.type;
1402
1462
  switch (type) {
1403
1463
  case "system": {
1404
- if (system != null) {
1405
- throw new import_provider2.UnsupportedFunctionalityError({
1406
- functionality: "Multiple system messages that are separated by user/assistant messages"
1407
- });
1408
- }
1409
- system = block.messages.map(({ content, providerOptions }) => ({
1464
+ const content = block.messages.map(({ content: content2, providerOptions }) => ({
1410
1465
  type: "text",
1411
- text: content,
1466
+ text: content2,
1412
1467
  cache_control: validator.getCacheControl(providerOptions, {
1413
1468
  type: "system message",
1414
1469
  canCache: true
1415
1470
  })
1416
1471
  }));
1472
+ if (system == null) {
1473
+ system = content;
1474
+ } else {
1475
+ messages.push({ role: "system", content });
1476
+ betas.add("mid-conversation-system-2026-04-07");
1477
+ }
1417
1478
  break;
1418
1479
  }
1419
1480
  case "user": {
@@ -2290,6 +2351,9 @@ var AnthropicMessagesLanguageModel = class {
2290
2351
  ...(anthropicOptions == null ? void 0 : anthropicOptions.inferenceGeo) && {
2291
2352
  inference_geo: anthropicOptions.inferenceGeo
2292
2353
  },
2354
+ ...(anthropicOptions == null ? void 0 : anthropicOptions.fallbacks) && anthropicOptions.fallbacks.length > 0 && {
2355
+ fallbacks: anthropicOptions.fallbacks
2356
+ },
2293
2357
  ...(anthropicOptions == null ? void 0 : anthropicOptions.cacheControl) && {
2294
2358
  cache_control: anthropicOptions.cacheControl
2295
2359
  },
@@ -2432,6 +2496,9 @@ var AnthropicMessagesLanguageModel = class {
2432
2496
  if ((anthropicOptions == null ? void 0 : anthropicOptions.speed) === "fast") {
2433
2497
  betas.add("fast-mode-2026-02-01");
2434
2498
  }
2499
+ if ((anthropicOptions == null ? void 0 : anthropicOptions.fallbacks) && anthropicOptions.fallbacks.length > 0) {
2500
+ betas.add("server-side-fallback-2026-06-01");
2501
+ }
2435
2502
  if (useStructuredOutput) {
2436
2503
  betas.add("structured-outputs-2025-11-13");
2437
2504
  }
@@ -2531,7 +2598,7 @@ var AnthropicMessagesLanguageModel = class {
2531
2598
  });
2532
2599
  }
2533
2600
  async doGenerate(options) {
2534
- var _a, _b, _c, _d, _e, _f, _g, _h;
2601
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
2535
2602
  const { args, warnings, betas, usesJsonResponseTool } = await this.getArgs({
2536
2603
  ...options,
2537
2604
  userSuppliedBetas: await this.getBetasFromHeaders(options.headers)
@@ -2771,11 +2838,20 @@ var AnthropicMessagesLanguageModel = class {
2771
2838
  });
2772
2839
  break;
2773
2840
  }
2841
+ // Server-side fallback marker: the AI SDK has no content primitive for
2842
+ // a model hop, so drop it. The hop is still observable via
2843
+ // usage.iterations.
2844
+ case "fallback": {
2845
+ break;
2846
+ }
2774
2847
  }
2775
2848
  }
2776
2849
  let inputTokens;
2777
2850
  let outputTokens;
2778
- if (response.usage.iterations && response.usage.iterations.length > 0) {
2851
+ const servedByFallback = (_b = response.usage.iterations) == null ? void 0 : _b.some(
2852
+ (iter) => iter.type === "fallback_message"
2853
+ );
2854
+ if (response.usage.iterations && response.usage.iterations.length > 0 && !servedByFallback) {
2779
2855
  const totals = response.usage.iterations.reduce(
2780
2856
  (acc, iter) => ({
2781
2857
  input: acc.input + iter.input_tokens,
@@ -2789,6 +2865,7 @@ var AnthropicMessagesLanguageModel = class {
2789
2865
  inputTokens = response.usage.input_tokens;
2790
2866
  outputTokens = response.usage.output_tokens;
2791
2867
  }
2868
+ const stopDetails = mapAnthropicStopDetails(response.stop_details);
2792
2869
  return {
2793
2870
  content,
2794
2871
  finishReason: mapAnthropicStopReason({
@@ -2799,12 +2876,12 @@ var AnthropicMessagesLanguageModel = class {
2799
2876
  inputTokens,
2800
2877
  outputTokens,
2801
2878
  totalTokens: inputTokens + outputTokens,
2802
- cachedInputTokens: (_b = response.usage.cache_read_input_tokens) != null ? _b : void 0
2879
+ cachedInputTokens: (_c = response.usage.cache_read_input_tokens) != null ? _c : void 0
2803
2880
  },
2804
2881
  request: { body: args },
2805
2882
  response: {
2806
- id: (_c = response.id) != null ? _c : void 0,
2807
- modelId: (_d = response.model) != null ? _d : void 0,
2883
+ id: (_d = response.id) != null ? _d : void 0,
2884
+ modelId: (_e = response.model) != null ? _e : void 0,
2808
2885
  headers: responseHeaders,
2809
2886
  body: rawResponse
2810
2887
  },
@@ -2812,21 +2889,23 @@ var AnthropicMessagesLanguageModel = class {
2812
2889
  providerMetadata: {
2813
2890
  anthropic: {
2814
2891
  usage: response.usage,
2815
- cacheCreationInputTokens: (_e = response.usage.cache_creation_input_tokens) != null ? _e : null,
2816
- stopSequence: (_f = response.stop_sequence) != null ? _f : null,
2892
+ cacheCreationInputTokens: (_f = response.usage.cache_creation_input_tokens) != null ? _f : null,
2893
+ stopSequence: (_g = response.stop_sequence) != null ? _g : null,
2894
+ ...stopDetails != null ? { stopDetails } : {},
2817
2895
  iterations: response.usage.iterations ? response.usage.iterations.map((iter) => ({
2818
2896
  type: iter.type,
2897
+ ...iter.model != null ? { model: iter.model } : {},
2819
2898
  inputTokens: iter.input_tokens,
2820
2899
  outputTokens: iter.output_tokens
2821
2900
  })) : null,
2822
2901
  container: response.container ? {
2823
2902
  expiresAt: response.container.expires_at,
2824
2903
  id: response.container.id,
2825
- skills: (_h = (_g = response.container.skills) == null ? void 0 : _g.map((skill) => ({
2904
+ skills: (_i = (_h = response.container.skills) == null ? void 0 : _h.map((skill) => ({
2826
2905
  type: skill.type,
2827
2906
  skillId: skill.skill_id,
2828
2907
  version: skill.version
2829
- }))) != null ? _h : null
2908
+ }))) != null ? _i : null
2830
2909
  } : null,
2831
2910
  contextManagement: response.context_management ? {
2832
2911
  appliedEdits: response.context_management.applied_edits.map(
@@ -2887,6 +2966,7 @@ var AnthropicMessagesLanguageModel = class {
2887
2966
  let rawUsage = void 0;
2888
2967
  let cacheCreationInputTokens = null;
2889
2968
  let stopSequence = null;
2969
+ let stopDetails = void 0;
2890
2970
  let container = null;
2891
2971
  let iterations = null;
2892
2972
  let contextManagement = null;
@@ -2898,7 +2978,7 @@ var AnthropicMessagesLanguageModel = class {
2898
2978
  controller.enqueue({ type: "stream-start", warnings });
2899
2979
  },
2900
2980
  transform(chunk, controller) {
2901
- var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j;
2981
+ var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k;
2902
2982
  if (options.includeRawChunks) {
2903
2983
  controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
2904
2984
  }
@@ -2913,6 +2993,9 @@ var AnthropicMessagesLanguageModel = class {
2913
2993
  }
2914
2994
  case "content_block_start": {
2915
2995
  const contentBlockType = value.content_block.type;
2996
+ if (contentBlockType === "fallback") {
2997
+ return;
2998
+ }
2916
2999
  blockType = contentBlockType;
2917
3000
  switch (contentBlockType) {
2918
3001
  case "text": {
@@ -3305,7 +3388,10 @@ var AnthropicMessagesLanguageModel = class {
3305
3388
  if (value.usage.iterations != null) {
3306
3389
  iterations = value.usage.iterations;
3307
3390
  }
3308
- if (value.usage.iterations && value.usage.iterations.length > 0) {
3391
+ const servedByFallback = (_f = value.usage.iterations) == null ? void 0 : _f.some(
3392
+ (iter) => iter.type === "fallback_message"
3393
+ );
3394
+ if (value.usage.iterations && value.usage.iterations.length > 0 && !servedByFallback) {
3309
3395
  const totals = value.usage.iterations.reduce(
3310
3396
  (acc, iter) => ({
3311
3397
  input: acc.input + iter.input_tokens,
@@ -3321,20 +3407,21 @@ var AnthropicMessagesLanguageModel = class {
3321
3407
  }
3322
3408
  usage.outputTokens = value.usage.output_tokens;
3323
3409
  }
3324
- usage.totalTokens = ((_f = usage.inputTokens) != null ? _f : 0) + ((_g = usage.outputTokens) != null ? _g : 0);
3410
+ usage.totalTokens = ((_g = usage.inputTokens) != null ? _g : 0) + ((_h = usage.outputTokens) != null ? _h : 0);
3325
3411
  finishReason = mapAnthropicStopReason({
3326
3412
  finishReason: value.delta.stop_reason,
3327
3413
  isJsonResponseFromTool: usesJsonResponseTool
3328
3414
  });
3329
- stopSequence = (_h = value.delta.stop_sequence) != null ? _h : null;
3415
+ stopDetails = mapAnthropicStopDetails(value.delta.stop_details);
3416
+ stopSequence = (_i = value.delta.stop_sequence) != null ? _i : null;
3330
3417
  container = value.delta.container != null ? {
3331
3418
  expiresAt: value.delta.container.expires_at,
3332
3419
  id: value.delta.container.id,
3333
- skills: (_j = (_i = value.delta.container.skills) == null ? void 0 : _i.map((skill) => ({
3420
+ skills: (_k = (_j = value.delta.container.skills) == null ? void 0 : _j.map((skill) => ({
3334
3421
  type: skill.type,
3335
3422
  skillId: skill.skill_id,
3336
3423
  version: skill.version
3337
- }))) != null ? _j : null
3424
+ }))) != null ? _k : null
3338
3425
  } : null;
3339
3426
  if (value.context_management != null) {
3340
3427
  contextManagement = {
@@ -3379,8 +3466,10 @@ var AnthropicMessagesLanguageModel = class {
3379
3466
  usage: rawUsage != null ? rawUsage : null,
3380
3467
  cacheCreationInputTokens,
3381
3468
  stopSequence,
3469
+ ...stopDetails != null ? { stopDetails } : {},
3382
3470
  iterations: iterations ? iterations.map((iter) => ({
3383
3471
  type: iter.type,
3472
+ ...iter.model != null ? { model: iter.model } : {},
3384
3473
  inputTokens: iter.input_tokens,
3385
3474
  outputTokens: iter.output_tokens
3386
3475
  })) : null,
@@ -3436,7 +3525,7 @@ var AnthropicMessagesLanguageModel = class {
3436
3525
  }
3437
3526
  };
3438
3527
  function getModelCapabilities(modelId) {
3439
- if (modelId.includes("claude-opus-4-7")) {
3528
+ if (modelId.includes("claude-opus-4-8") || modelId.includes("claude-opus-4-7") || modelId.includes("claude-fable-5")) {
3440
3529
  return {
3441
3530
  maxOutputTokens: 128e3,
3442
3531
  supportsStructuredOutput: true,
@@ -3501,6 +3590,17 @@ function getModelCapabilities(modelId) {
3501
3590
  };
3502
3591
  }
3503
3592
  }
3593
+ function mapAnthropicStopDetails(stopDetails) {
3594
+ if (stopDetails == null) {
3595
+ return void 0;
3596
+ }
3597
+ return {
3598
+ type: stopDetails.type,
3599
+ ...stopDetails.category != null ? { category: stopDetails.category } : {},
3600
+ ...stopDetails.explanation != null ? { explanation: stopDetails.explanation } : {},
3601
+ ...stopDetails.recommended_model != null ? { recommendedModel: stopDetails.recommended_model } : {}
3602
+ };
3603
+ }
3504
3604
 
3505
3605
  // src/tool/bash_20241022.ts
3506
3606
  var import_provider_utils11 = require("@ai-sdk/provider-utils");