@ai-sdk/anthropic 4.0.52 → 4.0.53

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.
@@ -483,12 +483,13 @@ const result = streamText({
483
483
  ##### Thinking Binding Controls
484
484
 
485
485
  Fable 5.1 can recover from a thinking-block prefix mismatch by dropping the
486
- mismatched block. Set `blockBinding.prefixMismatchBehavior` to `drop_block`.
487
- You can provide block binding by itself to preserve the model's default
488
- thinking mode, or combine it with adaptive thinking.
486
+ mismatched block. Set `blockBinding.prefixMismatchBehavior` to `drop_block`, or
487
+ set it to `error` to reject the request. You can provide block binding by itself
488
+ to preserve the model's default thinking mode, or combine it with adaptive
489
+ thinking.
489
490
 
490
491
  ```ts highlight="7-11"
491
- const { text } = await generateText({
492
+ const result = await generateText({
492
493
  model: anthropic('claude-fable-5-1'),
493
494
  prompt: 'Continue from this conversation.',
494
495
  providerOptions: {
@@ -501,8 +502,14 @@ const { text } = await generateText({
501
502
  } satisfies AnthropicLanguageModelOptions,
502
503
  },
503
504
  });
505
+
506
+ console.log(result.providerMetadata?.anthropic?.inputTransformations);
504
507
  ```
505
508
 
509
+ Dropped blocks are reported in
510
+ `providerMetadata.anthropic.inputTransformations` with their `type`, `path`, and
511
+ `reason`.
512
+
506
513
  #### Budget-Based Thinking
507
514
 
508
515
  For earlier models (`claude-opus-4-20250514`, `claude-sonnet-4-20250514`, `claude-sonnet-4-5-20250929`),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/anthropic",
3
- "version": "4.0.52",
3
+ "version": "4.0.53",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -35,8 +35,8 @@
35
35
  }
36
36
  },
37
37
  "dependencies": {
38
- "@ai-sdk/provider": "4.0.13",
39
- "@ai-sdk/provider-utils": "5.0.39"
38
+ "@ai-sdk/provider": "4.0.14",
39
+ "@ai-sdk/provider-utils": "5.0.40"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@ai-sdk/test-server": "2.0.1",
@@ -727,6 +727,12 @@ const anthropicMcpToolResultContentSchema = z.union([
727
727
  ),
728
728
  ]);
729
729
 
730
+ const anthropicInputTransformationSchema = z.object({
731
+ type: z.string(),
732
+ path: z.string(),
733
+ reason: z.string(),
734
+ });
735
+
730
736
  // limited version of the schema, focussed on what is needed for the implementation
731
737
  // this approach limits breakages when the API changes and increases efficiency
732
738
  export const anthropicResponseSchema = lazySchema(() =>
@@ -989,6 +995,9 @@ export const anthropicResponseSchema = lazySchema(() =>
989
995
  stop_reason: z.string().nullish(),
990
996
  stop_sequence: z.string().nullish(),
991
997
  stop_details: anthropicStopDetailsSchema.nullish(),
998
+ input_transformations: z
999
+ .array(anthropicInputTransformationSchema)
1000
+ .nullish(),
992
1001
  usage: z.looseObject({
993
1002
  input_tokens: z.number(),
994
1003
  output_tokens: z.number(),
@@ -1088,6 +1097,9 @@ export const anthropicChunkSchema = lazySchema(() =>
1088
1097
  )
1089
1098
  .nullish(),
1090
1099
  stop_reason: z.string().nullish(),
1100
+ input_transformations: z
1101
+ .array(anthropicInputTransformationSchema)
1102
+ .nullish(),
1091
1103
  container: z
1092
1104
  .object({
1093
1105
  expires_at: z.string(),
@@ -1441,6 +1453,9 @@ export const anthropicChunkSchema = lazySchema(() =>
1441
1453
  )
1442
1454
  .nullish(),
1443
1455
  }),
1456
+ input_transformations: z
1457
+ .array(anthropicInputTransformationSchema)
1458
+ .nullish(),
1444
1459
  context_management: z
1445
1460
  .object({
1446
1461
  applied_edits: z.array(
@@ -162,6 +162,20 @@ type AnthropicBatchResultLine = InferSchema<
162
162
 
163
163
  type AnthropicResponse = InferSchema<typeof anthropicResponseSchema>;
164
164
 
165
+ function assertTextBatchRequests(
166
+ requests: BatchV4StartOptions['requests'],
167
+ ): asserts requests is ReadonlyArray<AnthropicBatchRequest> {
168
+ for (const request of requests) {
169
+ const requestType = request.type;
170
+ if (requestType !== 'text') {
171
+ throw new UnsupportedFunctionalityError({
172
+ functionality: `batch request type: ${requestType}`,
173
+ message: `The Anthropic Message Batches API does not support batch requests with type "${requestType}".`,
174
+ });
175
+ }
176
+ }
177
+ }
178
+
165
179
  export class AnthropicBatch implements BatchV4<{
166
180
  readonly text: AnthropicModelId;
167
181
  }> {
@@ -191,6 +205,7 @@ export class AnthropicBatch implements BatchV4<{
191
205
  }: BatchV4StartOptions<{
192
206
  text: AnthropicModelId;
193
207
  }>): Promise<BatchV4StartResult> {
208
+ assertTextBatchRequests(requests);
194
209
  validateRequestIds(requests);
195
210
 
196
211
  const explicitBatchBetas = new Set(
@@ -1080,6 +1095,9 @@ function convertAnthropicMessageMetadata(response: AnthropicResponse) {
1080
1095
  usage: response.usage as JSONObject,
1081
1096
  stopSequence: response.stop_sequence ?? null,
1082
1097
  ...(stopDetails != null ? { stopDetails } : {}),
1098
+ ...(response.input_transformations != null
1099
+ ? { inputTransformations: response.input_transformations }
1100
+ : {}),
1083
1101
  iterations: response.usage.iterations
1084
1102
  ? response.usage.iterations.map(
1085
1103
  iteration =>
@@ -163,7 +163,7 @@ export const anthropicLanguageModelOptions = z.object({
163
163
  */
164
164
  blockBinding: z
165
165
  .object({
166
- prefixMismatchBehavior: z.literal('drop_block'),
166
+ prefixMismatchBehavior: z.enum(['error', 'drop_block']),
167
167
  })
168
168
  .optional(),
169
169
  }),
@@ -179,7 +179,7 @@ export const anthropicLanguageModelOptions = z.object({
179
179
  z.object({
180
180
  type: z.never().optional(),
181
181
  blockBinding: z.object({
182
- prefixMismatchBehavior: z.literal('drop_block'),
182
+ prefixMismatchBehavior: z.enum(['error', 'drop_block']),
183
183
  }),
184
184
  }),
185
185
  ])
@@ -1556,6 +1556,9 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
1556
1556
  usage: response.usage as JSONObject,
1557
1557
  stopSequence: response.stop_sequence ?? null,
1558
1558
  ...(stopDetails != null ? { stopDetails } : {}),
1559
+ ...(response.input_transformations != null
1560
+ ? { inputTransformations: response.input_transformations }
1561
+ : {}),
1559
1562
 
1560
1563
  iterations: response.usage.iterations
1561
1564
  ? response.usage.iterations.map(
@@ -1693,6 +1696,7 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
1693
1696
  let rawUsage: JSONObject | undefined = undefined;
1694
1697
  let stopSequence: string | null = null;
1695
1698
  let stopDetails: AnthropicMessageMetadata['stopDetails'] = undefined;
1699
+ let inputTransformations: AnthropicMessageMetadata['inputTransformations'];
1696
1700
  let container: AnthropicMessageMetadata['container'] | null = null;
1697
1701
  let isJsonResponseFromTool = false;
1698
1702
  let isMessageOpen = false;
@@ -2561,6 +2565,10 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
2561
2565
  ...(value.message.usage as JSONObject),
2562
2566
  };
2563
2567
 
2568
+ if (value.message.input_transformations != null) {
2569
+ inputTransformations = value.message.input_transformations;
2570
+ }
2571
+
2564
2572
  if (value.message.container != null) {
2565
2573
  container = {
2566
2574
  expiresAt: value.message.container.expires_at,
@@ -2689,6 +2697,10 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
2689
2697
  );
2690
2698
  }
2691
2699
 
2700
+ if (value.input_transformations != null) {
2701
+ inputTransformations = value.input_transformations;
2702
+ }
2703
+
2692
2704
  rawUsage = {
2693
2705
  ...rawUsage,
2694
2706
  ...(value.usage as JSONObject),
@@ -2705,6 +2717,9 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
2705
2717
  usage: (rawUsage as JSONObject) ?? null,
2706
2718
  stopSequence,
2707
2719
  ...(stopDetails != null ? { stopDetails } : {}),
2720
+ ...(inputTransformations != null
2721
+ ? { inputTransformations }
2722
+ : {}),
2708
2723
  iterations: usage.iterations
2709
2724
  ? usage.iterations.map(
2710
2725
  iter =>
@@ -50,6 +50,18 @@ export interface AnthropicMessageMetadata {
50
50
  usage: JSONObject;
51
51
  stopSequence: string | null;
52
52
 
53
+ /**
54
+ * Input blocks that Anthropic transformed before inference. This is
55
+ * populated when thinking binding controls drop a mismatched thinking block.
56
+ * Values are intentionally open-ended so new transformation types and
57
+ * reasons remain forward compatible.
58
+ */
59
+ inputTransformations?: Array<{
60
+ type: string;
61
+ path: string;
62
+ reason: string;
63
+ }>;
64
+
53
65
  /**
54
66
  * Details about why the request stopped. Present only when the API returns
55
67
  * a `refusal` stop reason together with a `stop_details` object (a