@ai-sdk/anthropic 4.0.51 → 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.
- package/CHANGELOG.md +23 -0
- package/dist/index.d.ts +19 -2
- package/dist/index.js +98 -19
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +6 -1
- package/dist/internal/index.js +19 -2
- package/dist/internal/index.js.map +1 -1
- package/docs/05-anthropic.mdx +11 -4
- package/package.json +3 -3
- package/src/anthropic-api.ts +15 -0
- package/src/anthropic-batch.ts +98 -16
- package/src/anthropic-language-model-options.ts +2 -2
- package/src/anthropic-language-model.ts +15 -0
- package/src/anthropic-message-metadata.ts +12 -0
package/docs/05-anthropic.mdx
CHANGED
|
@@ -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
|
|
488
|
-
thinking mode, or combine it with adaptive
|
|
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
|
|
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.
|
|
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.
|
|
39
|
-
"@ai-sdk/provider-utils": "5.0.
|
|
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",
|
package/src/anthropic-api.ts
CHANGED
|
@@ -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(
|
package/src/anthropic-batch.ts
CHANGED
|
@@ -3,7 +3,10 @@ import {
|
|
|
3
3
|
InvalidResponseDataError,
|
|
4
4
|
UnsupportedFunctionalityError,
|
|
5
5
|
type Experimental_BatchV4 as BatchV4,
|
|
6
|
+
type Experimental_BatchV4CancelResult as BatchV4CancelResult,
|
|
6
7
|
type Experimental_BatchV4ItemResult as BatchV4ItemResult,
|
|
8
|
+
type Experimental_BatchV4ListOptions as BatchV4ListOptions,
|
|
9
|
+
type Experimental_BatchV4ListResult as BatchV4ListResult,
|
|
7
10
|
type Experimental_BatchV4OperationOptions as BatchV4OperationOptions,
|
|
8
11
|
type Experimental_BatchV4StartResult as BatchV4StartResult,
|
|
9
12
|
type Experimental_BatchV4Status as BatchV4Status,
|
|
@@ -64,25 +67,36 @@ const anthropicBatchProviderOptionsSchema = anthropicLanguageModelOptions.pick({
|
|
|
64
67
|
|
|
65
68
|
type AnthropicBatchRequest = TextBatchV4Request<AnthropicModelId>;
|
|
66
69
|
|
|
70
|
+
const anthropicBatchResponseZodSchema = () =>
|
|
71
|
+
z.object({
|
|
72
|
+
id: z.string(),
|
|
73
|
+
type: z.literal('message_batch'),
|
|
74
|
+
processing_status: z.string(),
|
|
75
|
+
request_counts: z.object({
|
|
76
|
+
processing: z.number(),
|
|
77
|
+
succeeded: z.number(),
|
|
78
|
+
errored: z.number(),
|
|
79
|
+
canceled: z.number(),
|
|
80
|
+
expired: z.number(),
|
|
81
|
+
}),
|
|
82
|
+
created_at: z.string(),
|
|
83
|
+
expires_at: z.string(),
|
|
84
|
+
archived_at: z.string().nullish(),
|
|
85
|
+
cancel_initiated_at: z.string().nullish(),
|
|
86
|
+
ended_at: z.string().nullish(),
|
|
87
|
+
results_url: z.string().nullish(),
|
|
88
|
+
});
|
|
89
|
+
|
|
67
90
|
const anthropicBatchResponseSchema = lazySchema(() =>
|
|
91
|
+
zodSchema(anthropicBatchResponseZodSchema()),
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
const anthropicBatchListResponseSchema = lazySchema(() =>
|
|
68
95
|
zodSchema(
|
|
69
96
|
z.object({
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
request_counts: z.object({
|
|
74
|
-
processing: z.number(),
|
|
75
|
-
succeeded: z.number(),
|
|
76
|
-
errored: z.number(),
|
|
77
|
-
canceled: z.number(),
|
|
78
|
-
expired: z.number(),
|
|
79
|
-
}),
|
|
80
|
-
created_at: z.string(),
|
|
81
|
-
expires_at: z.string(),
|
|
82
|
-
archived_at: z.string().nullish(),
|
|
83
|
-
cancel_initiated_at: z.string().nullish(),
|
|
84
|
-
ended_at: z.string().nullish(),
|
|
85
|
-
results_url: z.string().nullish(),
|
|
97
|
+
data: z.array(anthropicBatchResponseZodSchema()),
|
|
98
|
+
has_more: z.boolean(),
|
|
99
|
+
last_id: z.string().nullish(),
|
|
86
100
|
}),
|
|
87
101
|
),
|
|
88
102
|
);
|
|
@@ -148,6 +162,20 @@ type AnthropicBatchResultLine = InferSchema<
|
|
|
148
162
|
|
|
149
163
|
type AnthropicResponse = InferSchema<typeof anthropicResponseSchema>;
|
|
150
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
|
+
|
|
151
179
|
export class AnthropicBatch implements BatchV4<{
|
|
152
180
|
readonly text: AnthropicModelId;
|
|
153
181
|
}> {
|
|
@@ -177,6 +205,7 @@ export class AnthropicBatch implements BatchV4<{
|
|
|
177
205
|
}: BatchV4StartOptions<{
|
|
178
206
|
text: AnthropicModelId;
|
|
179
207
|
}>): Promise<BatchV4StartResult> {
|
|
208
|
+
assertTextBatchRequests(requests);
|
|
180
209
|
validateRequestIds(requests);
|
|
181
210
|
|
|
182
211
|
const explicitBatchBetas = new Set(
|
|
@@ -295,6 +324,56 @@ export class AnthropicBatch implements BatchV4<{
|
|
|
295
324
|
return convertAnthropicBatchStatus(await this.retrieveBatch(options));
|
|
296
325
|
}
|
|
297
326
|
|
|
327
|
+
async doCancelBatch(
|
|
328
|
+
options: BatchV4OperationOptions,
|
|
329
|
+
): Promise<BatchV4CancelResult> {
|
|
330
|
+
await postJsonToApi({
|
|
331
|
+
url: this.getBatchUrl(`/${encodeURIComponent(options.batchId)}/cancel`),
|
|
332
|
+
headers: await this.getBatchHeaders(options.headers),
|
|
333
|
+
body: {},
|
|
334
|
+
failedResponseHandler: anthropicFailedResponseHandler,
|
|
335
|
+
successfulResponseHandler: createJsonResponseHandler(
|
|
336
|
+
anthropicBatchResponseSchema,
|
|
337
|
+
),
|
|
338
|
+
abortSignal: options.abortSignal,
|
|
339
|
+
fetch: this.options.config.fetch,
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
return {};
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
async doListBatches(options: BatchV4ListOptions): Promise<BatchV4ListResult> {
|
|
346
|
+
const url = new URL(this.getBatchUrl(''));
|
|
347
|
+
if (options.limit != null) {
|
|
348
|
+
url.searchParams.set('limit', String(options.limit));
|
|
349
|
+
}
|
|
350
|
+
if (options.cursor != null) {
|
|
351
|
+
url.searchParams.set('after_id', options.cursor);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
const { value: page } = await getFromApi({
|
|
355
|
+
url: url.toString(),
|
|
356
|
+
validateUrl: false,
|
|
357
|
+
headers: await this.getBatchHeaders(options.headers),
|
|
358
|
+
failedResponseHandler: anthropicFailedResponseHandler,
|
|
359
|
+
successfulResponseHandler: createJsonResponseHandler(
|
|
360
|
+
anthropicBatchListResponseSchema,
|
|
361
|
+
),
|
|
362
|
+
abortSignal: options.abortSignal,
|
|
363
|
+
fetch: this.options.config.fetch,
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
return {
|
|
367
|
+
batches: page.data.map(batch => ({
|
|
368
|
+
batchId: batch.id,
|
|
369
|
+
...convertAnthropicBatchStatus(batch),
|
|
370
|
+
})),
|
|
371
|
+
...(page.has_more && page.last_id != null
|
|
372
|
+
? { nextCursor: page.last_id }
|
|
373
|
+
: {}),
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
|
|
298
377
|
async doGetBatchResults(
|
|
299
378
|
options: BatchV4OperationOptions,
|
|
300
379
|
): Promise<ReadableStream<BatchV4ItemResult>> {
|
|
@@ -1016,6 +1095,9 @@ function convertAnthropicMessageMetadata(response: AnthropicResponse) {
|
|
|
1016
1095
|
usage: response.usage as JSONObject,
|
|
1017
1096
|
stopSequence: response.stop_sequence ?? null,
|
|
1018
1097
|
...(stopDetails != null ? { stopDetails } : {}),
|
|
1098
|
+
...(response.input_transformations != null
|
|
1099
|
+
? { inputTransformations: response.input_transformations }
|
|
1100
|
+
: {}),
|
|
1019
1101
|
iterations: response.usage.iterations
|
|
1020
1102
|
? response.usage.iterations.map(
|
|
1021
1103
|
iteration =>
|
|
@@ -163,7 +163,7 @@ export const anthropicLanguageModelOptions = z.object({
|
|
|
163
163
|
*/
|
|
164
164
|
blockBinding: z
|
|
165
165
|
.object({
|
|
166
|
-
prefixMismatchBehavior: z.
|
|
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.
|
|
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
|