@ai-sdk/anthropic 3.0.80 → 3.0.82

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.
@@ -42,6 +42,12 @@ import {
42
42
  zodSchema as zodSchema2
43
43
  } from "@ai-sdk/provider-utils";
44
44
  import { z as z2 } from "zod/v4";
45
+ var anthropicStopDetailsSchema = z2.object({
46
+ type: z2.string(),
47
+ category: z2.string().nullish(),
48
+ explanation: z2.string().nullish(),
49
+ recommended_model: z2.string().nullish()
50
+ });
45
51
  var anthropicMessagesResponseSchema = lazySchema2(
46
52
  () => zodSchema2(
47
53
  z2.object({
@@ -327,34 +333,37 @@ var anthropicMessagesResponseSchema = lazySchema2(
327
333
  error_code: z2.string()
328
334
  })
329
335
  ])
336
+ }),
337
+ // Server-side fallback marker. Parsed so the response validates, but
338
+ // dropped from the content output (the AI SDK has no model-hop
339
+ // primitive). The hop remains observable via usage.iterations.
340
+ z2.object({
341
+ type: z2.literal("fallback")
330
342
  })
331
343
  ])
332
344
  ),
333
345
  stop_reason: z2.string().nullish(),
334
346
  stop_sequence: z2.string().nullish(),
347
+ stop_details: anthropicStopDetailsSchema.nullish(),
335
348
  usage: z2.looseObject({
336
349
  input_tokens: z2.number(),
337
350
  output_tokens: z2.number(),
338
351
  cache_creation_input_tokens: z2.number().nullish(),
339
352
  cache_read_input_tokens: z2.number().nullish(),
340
353
  iterations: z2.array(
341
- z2.union([
342
- z2.object({
343
- type: z2.union([z2.literal("compaction"), z2.literal("message")]),
344
- input_tokens: z2.number(),
345
- output_tokens: z2.number(),
346
- cache_creation_input_tokens: z2.number().nullish(),
347
- cache_read_input_tokens: z2.number().nullish()
348
- }),
349
- z2.object({
350
- type: z2.literal("advisor_message"),
351
- model: z2.string(),
352
- input_tokens: z2.number(),
353
- output_tokens: z2.number(),
354
- cache_creation_input_tokens: z2.number().nullish(),
355
- cache_read_input_tokens: z2.number().nullish()
356
- })
357
- ])
354
+ z2.object({
355
+ type: z2.union([
356
+ z2.literal("compaction"),
357
+ z2.literal("message"),
358
+ z2.literal("advisor_message"),
359
+ z2.literal("fallback_message")
360
+ ]),
361
+ model: z2.string().nullish(),
362
+ input_tokens: z2.number(),
363
+ output_tokens: z2.number(),
364
+ cache_creation_input_tokens: z2.number().nullish(),
365
+ cache_read_input_tokens: z2.number().nullish()
366
+ })
358
367
  ).nullish()
359
368
  }),
360
369
  container: z2.object({
@@ -689,6 +698,11 @@ var anthropicMessagesChunkSchema = lazySchema2(
689
698
  error_code: z2.string()
690
699
  })
691
700
  ])
701
+ }),
702
+ // Server-side fallback marker; dropped from content output (see the
703
+ // response schema). The hop remains observable via usage.iterations.
704
+ z2.object({
705
+ type: z2.literal("fallback")
692
706
  })
693
707
  ])
694
708
  }),
@@ -762,6 +776,7 @@ var anthropicMessagesChunkSchema = lazySchema2(
762
776
  delta: z2.object({
763
777
  stop_reason: z2.string().nullish(),
764
778
  stop_sequence: z2.string().nullish(),
779
+ stop_details: anthropicStopDetailsSchema.nullish(),
765
780
  container: z2.object({
766
781
  expires_at: z2.string(),
767
782
  id: z2.string(),
@@ -783,26 +798,19 @@ var anthropicMessagesChunkSchema = lazySchema2(
783
798
  cache_creation_input_tokens: z2.number().nullish(),
784
799
  cache_read_input_tokens: z2.number().nullish(),
785
800
  iterations: z2.array(
786
- z2.union([
787
- z2.object({
788
- type: z2.union([
789
- z2.literal("compaction"),
790
- z2.literal("message")
791
- ]),
792
- input_tokens: z2.number(),
793
- output_tokens: z2.number(),
794
- cache_creation_input_tokens: z2.number().nullish(),
795
- cache_read_input_tokens: z2.number().nullish()
796
- }),
797
- z2.object({
798
- type: z2.literal("advisor_message"),
799
- model: z2.string(),
800
- input_tokens: z2.number(),
801
- output_tokens: z2.number(),
802
- cache_creation_input_tokens: z2.number().nullish(),
803
- cache_read_input_tokens: z2.number().nullish()
804
- })
805
- ])
801
+ z2.object({
802
+ type: z2.union([
803
+ z2.literal("compaction"),
804
+ z2.literal("message"),
805
+ z2.literal("advisor_message"),
806
+ z2.literal("fallback_message")
807
+ ]),
808
+ model: z2.string().nullish(),
809
+ input_tokens: z2.number(),
810
+ output_tokens: z2.number(),
811
+ cache_creation_input_tokens: z2.number().nullish(),
812
+ cache_read_input_tokens: z2.number().nullish()
813
+ })
806
814
  ).nullish()
807
815
  }),
808
816
  context_management: z2.object({
@@ -1006,6 +1014,31 @@ var anthropicLanguageModelOptions = z3.object({
1006
1014
  * See https://platform.claude.com/docs/en/build-with-claude/data-residency
1007
1015
  */
1008
1016
  inferenceGeo: z3.enum(["us", "global"]).optional(),
1017
+ /**
1018
+ * Server-side fallback chain.
1019
+ *
1020
+ * When the primary model's safety classifiers block a turn, the API
1021
+ * automatically retries it on the next model in the chain, server-side. A
1022
+ * `content-filter` finish reason means the entire chain refused.
1023
+ *
1024
+ * Each entry is merged into the request as a direct request to that entry's
1025
+ * model, so it must be formatted accordingly: `model` is required, and an
1026
+ * entry may additionally override `max_tokens`, `thinking`, `output_config`,
1027
+ * and `speed` for that attempt only (`speed` additionally requires the speed
1028
+ * beta). The value is passed through to the API as-is.
1029
+ *
1030
+ * The required `server-side-fallback-2026-06-01` beta is added automatically
1031
+ * when this option is set.
1032
+ */
1033
+ fallbacks: z3.array(
1034
+ z3.object({
1035
+ model: z3.string(),
1036
+ max_tokens: z3.number().int().optional(),
1037
+ thinking: z3.record(z3.string(), z3.unknown()).optional(),
1038
+ output_config: z3.record(z3.string(), z3.unknown()).optional(),
1039
+ speed: z3.enum(["fast", "standard"]).optional()
1040
+ })
1041
+ ).optional(),
1009
1042
  /**
1010
1043
  * A set of beta features to enable.
1011
1044
  * Allow a provider to receive the full `betas` set if it needs it.
@@ -1786,12 +1819,15 @@ function convertAnthropicMessagesUsage({
1786
1819
  usage,
1787
1820
  rawUsage
1788
1821
  }) {
1789
- var _a, _b;
1822
+ var _a, _b, _c;
1790
1823
  const cacheCreationTokens = (_a = usage.cache_creation_input_tokens) != null ? _a : 0;
1791
1824
  const cacheReadTokens = (_b = usage.cache_read_input_tokens) != null ? _b : 0;
1792
1825
  let inputTokens;
1793
1826
  let outputTokens;
1794
- if (usage.iterations && usage.iterations.length > 0) {
1827
+ const servedByFallback = (_c = usage.iterations) == null ? void 0 : _c.some(
1828
+ (iter) => iter.type === "fallback_message"
1829
+ );
1830
+ if (usage.iterations && usage.iterations.length > 0 && !servedByFallback) {
1795
1831
  const executorIterations = usage.iterations.filter(
1796
1832
  (iter) => iter.type === "compaction" || iter.type === "message"
1797
1833
  );
@@ -2243,19 +2279,20 @@ async function convertToAnthropicMessagesPrompt({
2243
2279
  const type = block.type;
2244
2280
  switch (type) {
2245
2281
  case "system": {
2246
- if (system != null) {
2247
- throw new UnsupportedFunctionalityError2({
2248
- functionality: "Multiple system messages that are separated by user/assistant messages"
2249
- });
2250
- }
2251
- system = block.messages.map(({ content, providerOptions }) => ({
2282
+ const content = block.messages.map(({ content: content2, providerOptions }) => ({
2252
2283
  type: "text",
2253
- text: content,
2284
+ text: content2,
2254
2285
  cache_control: validator.getCacheControl(providerOptions, {
2255
2286
  type: "system message",
2256
2287
  canCache: true
2257
2288
  })
2258
2289
  }));
2290
+ if (system == null) {
2291
+ system = content;
2292
+ } else {
2293
+ messages.push({ role: "system", content });
2294
+ betas.add("mid-conversation-system-2026-04-07");
2295
+ }
2259
2296
  break;
2260
2297
  }
2261
2298
  case "user": {
@@ -3485,6 +3522,9 @@ var AnthropicMessagesLanguageModel = class {
3485
3522
  ...(anthropicOptions == null ? void 0 : anthropicOptions.inferenceGeo) && {
3486
3523
  inference_geo: anthropicOptions.inferenceGeo
3487
3524
  },
3525
+ ...(anthropicOptions == null ? void 0 : anthropicOptions.fallbacks) && anthropicOptions.fallbacks.length > 0 && {
3526
+ fallbacks: anthropicOptions.fallbacks
3527
+ },
3488
3528
  ...(anthropicOptions == null ? void 0 : anthropicOptions.cacheControl) && {
3489
3529
  cache_control: anthropicOptions.cacheControl
3490
3530
  },
@@ -3661,6 +3701,9 @@ var AnthropicMessagesLanguageModel = class {
3661
3701
  if ((anthropicOptions == null ? void 0 : anthropicOptions.speed) === "fast") {
3662
3702
  betas.add("fast-mode-2026-02-01");
3663
3703
  }
3704
+ if ((anthropicOptions == null ? void 0 : anthropicOptions.fallbacks) && anthropicOptions.fallbacks.length > 0) {
3705
+ betas.add("server-side-fallback-2026-06-01");
3706
+ }
3664
3707
  const defaultEagerInputStreaming = stream && ((_i = anthropicOptions == null ? void 0 : anthropicOptions.toolStreaming) != null ? _i : true);
3665
3708
  const {
3666
3709
  tools: anthropicTools2,
@@ -4183,6 +4226,12 @@ var AnthropicMessagesLanguageModel = class {
4183
4226
  }
4184
4227
  break;
4185
4228
  }
4229
+ // Server-side fallback marker: the AI SDK has no content primitive for
4230
+ // a model hop, so drop it. The hop is still observable via
4231
+ // usage.iterations.
4232
+ case "fallback": {
4233
+ break;
4234
+ }
4186
4235
  }
4187
4236
  }
4188
4237
  return {
@@ -4205,24 +4254,16 @@ var AnthropicMessagesLanguageModel = class {
4205
4254
  warnings,
4206
4255
  providerMetadata: (() => {
4207
4256
  var _a2, _b2, _c2, _d2, _e2;
4257
+ const stopDetails = mapAnthropicStopDetails(response.stop_details);
4208
4258
  const anthropicMetadata = {
4209
4259
  usage: response.usage,
4210
4260
  cacheCreationInputTokens: (_a2 = response.usage.cache_creation_input_tokens) != null ? _a2 : null,
4211
4261
  stopSequence: (_b2 = response.stop_sequence) != null ? _b2 : null,
4262
+ ...stopDetails != null ? { stopDetails } : {},
4212
4263
  iterations: response.usage.iterations ? response.usage.iterations.map(
4213
- (iter) => iter.type === "advisor_message" ? {
4214
- type: iter.type,
4215
- model: iter.model,
4216
- inputTokens: iter.input_tokens,
4217
- outputTokens: iter.output_tokens,
4218
- ...iter.cache_creation_input_tokens ? {
4219
- cacheCreationInputTokens: iter.cache_creation_input_tokens
4220
- } : {},
4221
- ...iter.cache_read_input_tokens ? {
4222
- cacheReadInputTokens: iter.cache_read_input_tokens
4223
- } : {}
4224
- } : {
4264
+ (iter) => ({
4225
4265
  type: iter.type,
4266
+ ...iter.model != null ? { model: iter.model } : {},
4226
4267
  inputTokens: iter.input_tokens,
4227
4268
  outputTokens: iter.output_tokens,
4228
4269
  ...iter.cache_creation_input_tokens ? {
@@ -4231,7 +4272,7 @@ var AnthropicMessagesLanguageModel = class {
4231
4272
  ...iter.cache_read_input_tokens ? {
4232
4273
  cacheReadInputTokens: iter.cache_read_input_tokens
4233
4274
  } : {}
4234
- }
4275
+ })
4235
4276
  ) : null,
4236
4277
  container: response.container ? {
4237
4278
  expiresAt: response.container.expires_at,
@@ -4307,6 +4348,7 @@ var AnthropicMessagesLanguageModel = class {
4307
4348
  let rawUsage = void 0;
4308
4349
  let cacheCreationInputTokens = null;
4309
4350
  let stopSequence = null;
4351
+ let stopDetails = void 0;
4310
4352
  let container = null;
4311
4353
  let isJsonResponseFromTool = false;
4312
4354
  let blockType = void 0;
@@ -4333,6 +4375,9 @@ var AnthropicMessagesLanguageModel = class {
4333
4375
  case "content_block_start": {
4334
4376
  const part = value.content_block;
4335
4377
  const contentBlockType = part.type;
4378
+ if (contentBlockType === "fallback") {
4379
+ return;
4380
+ }
4336
4381
  blockType = contentBlockType;
4337
4382
  switch (contentBlockType) {
4338
4383
  case "text": {
@@ -5006,6 +5051,7 @@ var AnthropicMessagesLanguageModel = class {
5006
5051
  raw: (_k = value.delta.stop_reason) != null ? _k : void 0
5007
5052
  };
5008
5053
  stopSequence = (_l = value.delta.stop_sequence) != null ? _l : null;
5054
+ stopDetails = mapAnthropicStopDetails(value.delta.stop_details);
5009
5055
  container = value.delta.container != null ? {
5010
5056
  expiresAt: value.delta.container.expires_at,
5011
5057
  id: value.delta.container.id,
@@ -5031,20 +5077,11 @@ var AnthropicMessagesLanguageModel = class {
5031
5077
  usage: rawUsage != null ? rawUsage : null,
5032
5078
  cacheCreationInputTokens,
5033
5079
  stopSequence,
5080
+ ...stopDetails != null ? { stopDetails } : {},
5034
5081
  iterations: usage.iterations ? usage.iterations.map(
5035
- (iter) => iter.type === "advisor_message" ? {
5036
- type: iter.type,
5037
- model: iter.model,
5038
- inputTokens: iter.input_tokens,
5039
- outputTokens: iter.output_tokens,
5040
- ...iter.cache_creation_input_tokens ? {
5041
- cacheCreationInputTokens: iter.cache_creation_input_tokens
5042
- } : {},
5043
- ...iter.cache_read_input_tokens ? {
5044
- cacheReadInputTokens: iter.cache_read_input_tokens
5045
- } : {}
5046
- } : {
5082
+ (iter) => ({
5047
5083
  type: iter.type,
5084
+ ...iter.model != null ? { model: iter.model } : {},
5048
5085
  inputTokens: iter.input_tokens,
5049
5086
  outputTokens: iter.output_tokens,
5050
5087
  ...iter.cache_creation_input_tokens ? {
@@ -5053,7 +5090,7 @@ var AnthropicMessagesLanguageModel = class {
5053
5090
  ...iter.cache_read_input_tokens ? {
5054
5091
  cacheReadInputTokens: iter.cache_read_input_tokens
5055
5092
  } : {}
5056
- }
5093
+ })
5057
5094
  ) : null,
5058
5095
  container,
5059
5096
  contextManagement
@@ -5117,7 +5154,7 @@ var AnthropicMessagesLanguageModel = class {
5117
5154
  }
5118
5155
  };
5119
5156
  function getModelCapabilities(modelId) {
5120
- if (modelId.includes("claude-opus-4-7")) {
5157
+ if (modelId.includes("claude-opus-4-8") || modelId.includes("claude-opus-4-7") || modelId.includes("claude-fable-5")) {
5121
5158
  return {
5122
5159
  maxOutputTokens: 128e3,
5123
5160
  supportsStructuredOutput: true,
@@ -5218,6 +5255,17 @@ function mapAnthropicResponseContextManagement(contextManagement) {
5218
5255
  }).filter((edit) => edit !== void 0)
5219
5256
  } : null;
5220
5257
  }
5258
+ function mapAnthropicStopDetails(stopDetails) {
5259
+ if (stopDetails == null) {
5260
+ return void 0;
5261
+ }
5262
+ return {
5263
+ type: stopDetails.type,
5264
+ ...stopDetails.category != null ? { category: stopDetails.category } : {},
5265
+ ...stopDetails.explanation != null ? { explanation: stopDetails.explanation } : {},
5266
+ ...stopDetails.recommended_model != null ? { recommendedModel: stopDetails.recommended_model } : {}
5267
+ };
5268
+ }
5221
5269
 
5222
5270
  // src/tool/bash_20241022.ts
5223
5271
  import {
@@ -5575,7 +5623,7 @@ var anthropicTools = {
5575
5623
  * Supported executor models: Claude Haiku 4.5, Sonnet 4.6, Opus 4.6,
5576
5624
  * Opus 4.7. The advisor must be at least as capable as the executor.
5577
5625
  *
5578
- * @param model - The advisor model ID (required), e.g. `"claude-opus-4-7"`.
5626
+ * @param model - The advisor model ID (required), e.g. `"claude-opus-4-8"`.
5579
5627
  * @param maxUses - Maximum advisor calls per request (per-request cap).
5580
5628
  * @param caching - Enables prompt caching for the advisor's transcript
5581
5629
  * across calls within a conversation. Worthwhile from ~3 advisor calls