@ai-sdk/anthropic 4.0.30 → 4.0.32
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 +14 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +69 -14
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +8 -0
- package/dist/internal/index.js +68 -13
- package/dist/internal/index.js.map +1 -1
- package/docs/05-anthropic.mdx +7 -1
- package/package.json +2 -2
- package/src/anthropic-api.ts +7 -0
- package/src/anthropic-language-model.ts +44 -0
- package/src/anthropic-prepare-tools.ts +3 -0
- package/src/anthropic-tools.ts +2 -0
- package/src/convert-to-anthropic-prompt.ts +6 -0
- package/src/tool/advisor_20260301.ts +26 -0
package/docs/05-anthropic.mdx
CHANGED
|
@@ -1059,13 +1059,15 @@ import { generateText } from 'ai';
|
|
|
1059
1059
|
|
|
1060
1060
|
const result = await generateText({
|
|
1061
1061
|
model: anthropic('claude-sonnet-4-6'),
|
|
1062
|
-
system:
|
|
1062
|
+
system:
|
|
1063
|
+
'You have access to an `advisor` tool backed by a stronger reviewer model.',
|
|
1063
1064
|
prompt:
|
|
1064
1065
|
'Build a concurrent worker pool in Go with graceful shutdown. Outline the design first.',
|
|
1065
1066
|
tools: {
|
|
1066
1067
|
advisor: anthropic.tools.advisor_20260301({
|
|
1067
1068
|
model: 'claude-opus-4-8',
|
|
1068
1069
|
maxUses: 3,
|
|
1070
|
+
maxTokens: 2048,
|
|
1069
1071
|
}),
|
|
1070
1072
|
},
|
|
1071
1073
|
});
|
|
@@ -1088,6 +1090,10 @@ The advisor tool supports the following configuration options:
|
|
|
1088
1090
|
|
|
1089
1091
|
Optional. Maximum number of advisor calls allowed in a single request. Once the executor reaches this cap, further advisor calls return an `advisor_tool_result_error` with `errorCode: 'max_uses_exceeded'`, and the executor continues without further advice.
|
|
1090
1092
|
|
|
1093
|
+
- **maxTokens** _number_
|
|
1094
|
+
|
|
1095
|
+
Optional. Maximum number of tokens the advisor can generate per call, including thinking and text. The minimum is `1024`, and Anthropic recommends starting with `2048`. This limit applies independently to each advisor call and is separate from the request-level `maxOutputTokens`, which controls executor output. Values above the selected advisor model's output limit result in an Anthropic `400` error. When configured, successful advisor results include `stopReason`; check for `stopReason === 'max_tokens'` to detect truncated advice. The field is available on both plaintext and redacted advisor result variants and is preserved across follow-up turns.
|
|
1096
|
+
|
|
1091
1097
|
- **caching** _object_
|
|
1092
1098
|
|
|
1093
1099
|
Optional. Enables prompt caching for the advisor's own transcript across calls within a conversation. Use `{ type: 'ephemeral', ttl: '5m' | '1h' }`. This is most useful for longer agent loops where you expect at least three advisor calls.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/anthropic",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.32",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@ai-sdk/provider": "4.0.5",
|
|
39
|
-
"@ai-sdk/provider-utils": "5.0.
|
|
39
|
+
"@ai-sdk/provider-utils": "5.0.22"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@types/node": "22.19.19",
|
package/src/anthropic-api.ts
CHANGED
|
@@ -358,10 +358,12 @@ export interface AnthropicAdvisorToolResultContent {
|
|
|
358
358
|
| {
|
|
359
359
|
type: 'advisor_result';
|
|
360
360
|
text: string;
|
|
361
|
+
stop_reason?: string;
|
|
361
362
|
}
|
|
362
363
|
| {
|
|
363
364
|
type: 'advisor_redacted_result';
|
|
364
365
|
encrypted_content: string;
|
|
366
|
+
stop_reason?: string;
|
|
365
367
|
}
|
|
366
368
|
| {
|
|
367
369
|
type: 'advisor_tool_result_error';
|
|
@@ -530,6 +532,7 @@ export type AnthropicTool =
|
|
|
530
532
|
name: 'advisor';
|
|
531
533
|
model: string;
|
|
532
534
|
max_uses?: number;
|
|
535
|
+
max_tokens?: number;
|
|
533
536
|
caching?: {
|
|
534
537
|
type: 'ephemeral';
|
|
535
538
|
ttl: '5m' | '1h';
|
|
@@ -924,10 +927,12 @@ export const anthropicResponseSchema = lazySchema(() =>
|
|
|
924
927
|
z.object({
|
|
925
928
|
type: z.literal('advisor_result'),
|
|
926
929
|
text: z.string(),
|
|
930
|
+
stop_reason: z.string().nullish(),
|
|
927
931
|
}),
|
|
928
932
|
z.object({
|
|
929
933
|
type: z.literal('advisor_redacted_result'),
|
|
930
934
|
encrypted_content: z.string(),
|
|
935
|
+
stop_reason: z.string().nullish(),
|
|
931
936
|
}),
|
|
932
937
|
z.object({
|
|
933
938
|
type: z.literal('advisor_tool_result_error'),
|
|
@@ -1321,10 +1326,12 @@ export const anthropicChunkSchema = lazySchema(() =>
|
|
|
1321
1326
|
z.object({
|
|
1322
1327
|
type: z.literal('advisor_result'),
|
|
1323
1328
|
text: z.string(),
|
|
1329
|
+
stop_reason: z.string().nullish(),
|
|
1324
1330
|
}),
|
|
1325
1331
|
z.object({
|
|
1326
1332
|
type: z.literal('advisor_redacted_result'),
|
|
1327
1333
|
encrypted_content: z.string(),
|
|
1334
|
+
stop_reason: z.string().nullish(),
|
|
1328
1335
|
}),
|
|
1329
1336
|
z.object({
|
|
1330
1337
|
type: z.literal('advisor_tool_result_error'),
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
APICallError,
|
|
3
|
+
InvalidResponseDataError,
|
|
3
4
|
type JSONObject,
|
|
4
5
|
type LanguageModelV4,
|
|
5
6
|
type LanguageModelV4CallOptions,
|
|
@@ -1388,6 +1389,9 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
1388
1389
|
result: {
|
|
1389
1390
|
type: 'advisor_result',
|
|
1390
1391
|
text: part.content.text,
|
|
1392
|
+
...(part.content.stop_reason != null && {
|
|
1393
|
+
stopReason: part.content.stop_reason,
|
|
1394
|
+
}),
|
|
1391
1395
|
},
|
|
1392
1396
|
});
|
|
1393
1397
|
} else if (part.content.type === 'advisor_redacted_result') {
|
|
@@ -1398,6 +1402,9 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
1398
1402
|
result: {
|
|
1399
1403
|
type: 'advisor_redacted_result',
|
|
1400
1404
|
encryptedContent: part.content.encrypted_content,
|
|
1405
|
+
...(part.content.stop_reason != null && {
|
|
1406
|
+
stopReason: part.content.stop_reason,
|
|
1407
|
+
}),
|
|
1401
1408
|
},
|
|
1402
1409
|
});
|
|
1403
1410
|
} else {
|
|
@@ -1588,6 +1595,9 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
1588
1595
|
let stopDetails: AnthropicMessageMetadata['stopDetails'] = undefined;
|
|
1589
1596
|
let container: AnthropicMessageMetadata['container'] | null = null;
|
|
1590
1597
|
let isJsonResponseFromTool = false;
|
|
1598
|
+
let isMessageOpen = false;
|
|
1599
|
+
let activeMessageId: string | null | undefined;
|
|
1600
|
+
let hasInvalidMessageSequence = false;
|
|
1591
1601
|
|
|
1592
1602
|
let blockType:
|
|
1593
1603
|
| 'text'
|
|
@@ -1619,6 +1629,10 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
1619
1629
|
},
|
|
1620
1630
|
|
|
1621
1631
|
transform(chunk, controller) {
|
|
1632
|
+
if (hasInvalidMessageSequence) {
|
|
1633
|
+
return;
|
|
1634
|
+
}
|
|
1635
|
+
|
|
1622
1636
|
if (options.includeRawChunks) {
|
|
1623
1637
|
controller.enqueue({ type: 'raw', rawValue: chunk.rawValue });
|
|
1624
1638
|
}
|
|
@@ -2097,6 +2111,9 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
2097
2111
|
result: {
|
|
2098
2112
|
type: 'advisor_result',
|
|
2099
2113
|
text: part.content.text,
|
|
2114
|
+
...(part.content.stop_reason != null && {
|
|
2115
|
+
stopReason: part.content.stop_reason,
|
|
2116
|
+
}),
|
|
2100
2117
|
},
|
|
2101
2118
|
});
|
|
2102
2119
|
} else if (part.content.type === 'advisor_redacted_result') {
|
|
@@ -2107,6 +2124,9 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
2107
2124
|
result: {
|
|
2108
2125
|
type: 'advisor_redacted_result',
|
|
2109
2126
|
encryptedContent: part.content.encrypted_content,
|
|
2127
|
+
...(part.content.stop_reason != null && {
|
|
2128
|
+
stopReason: part.content.stop_reason,
|
|
2129
|
+
}),
|
|
2110
2130
|
},
|
|
2111
2131
|
});
|
|
2112
2132
|
} else {
|
|
@@ -2405,6 +2425,27 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
2405
2425
|
}
|
|
2406
2426
|
|
|
2407
2427
|
case 'message_start': {
|
|
2428
|
+
if (isMessageOpen) {
|
|
2429
|
+
if (activeMessageId === value.message.id) {
|
|
2430
|
+
return;
|
|
2431
|
+
}
|
|
2432
|
+
|
|
2433
|
+
hasInvalidMessageSequence = true;
|
|
2434
|
+
controller.enqueue({
|
|
2435
|
+
type: 'error',
|
|
2436
|
+
error: new InvalidResponseDataError({
|
|
2437
|
+
data: value,
|
|
2438
|
+
message:
|
|
2439
|
+
`Received message_start for message ${JSON.stringify(value.message.id)} ` +
|
|
2440
|
+
`while message ${JSON.stringify(activeMessageId)} is still open.`,
|
|
2441
|
+
}),
|
|
2442
|
+
});
|
|
2443
|
+
return;
|
|
2444
|
+
}
|
|
2445
|
+
|
|
2446
|
+
isMessageOpen = true;
|
|
2447
|
+
activeMessageId = value.message.id;
|
|
2448
|
+
|
|
2408
2449
|
usage.input_tokens = value.message.usage.input_tokens;
|
|
2409
2450
|
usage.cache_read_input_tokens =
|
|
2410
2451
|
value.message.usage.cache_read_input_tokens ?? 0;
|
|
@@ -2559,6 +2600,9 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
2559
2600
|
}
|
|
2560
2601
|
|
|
2561
2602
|
case 'message_stop': {
|
|
2603
|
+
isMessageOpen = false;
|
|
2604
|
+
activeMessageId = undefined;
|
|
2605
|
+
|
|
2562
2606
|
const anthropicMetadata = {
|
|
2563
2607
|
usage: (rawUsage as JSONObject) ?? null,
|
|
2564
2608
|
stopSequence,
|
|
@@ -358,6 +358,9 @@ export async function prepareTools({
|
|
|
358
358
|
name: 'advisor',
|
|
359
359
|
model: args.model,
|
|
360
360
|
...(args.maxUses !== undefined && { max_uses: args.maxUses }),
|
|
361
|
+
...(args.maxTokens !== undefined && {
|
|
362
|
+
max_tokens: args.maxTokens,
|
|
363
|
+
}),
|
|
361
364
|
...(args.caching !== undefined && { caching: args.caching }),
|
|
362
365
|
});
|
|
363
366
|
break;
|
package/src/anthropic-tools.ts
CHANGED
|
@@ -44,6 +44,8 @@ export const anthropicTools = {
|
|
|
44
44
|
*
|
|
45
45
|
* @param model - The advisor model ID (required), e.g. `"claude-opus-4-8"`.
|
|
46
46
|
* @param maxUses - Maximum advisor calls per request (per-request cap).
|
|
47
|
+
* @param maxTokens - Maximum advisor output tokens per call, including
|
|
48
|
+
* thinking and text. Minimum 1024; Anthropic recommends starting with 2048.
|
|
47
49
|
* @param caching - Enables prompt caching for the advisor's transcript
|
|
48
50
|
* across calls within a conversation. Worthwhile from ~3 advisor calls
|
|
49
51
|
* per conversation.
|
|
@@ -1243,6 +1243,9 @@ export async function convertToAnthropicPrompt({
|
|
|
1243
1243
|
content: {
|
|
1244
1244
|
type: 'advisor_result',
|
|
1245
1245
|
text: advisorOutput.text,
|
|
1246
|
+
...(advisorOutput.stopReason !== undefined && {
|
|
1247
|
+
stop_reason: advisorOutput.stopReason,
|
|
1248
|
+
}),
|
|
1246
1249
|
},
|
|
1247
1250
|
cache_control: cacheControl,
|
|
1248
1251
|
});
|
|
@@ -1253,6 +1256,9 @@ export async function convertToAnthropicPrompt({
|
|
|
1253
1256
|
content: {
|
|
1254
1257
|
type: 'advisor_redacted_result',
|
|
1255
1258
|
encrypted_content: advisorOutput.encryptedContent,
|
|
1259
|
+
...(advisorOutput.stopReason !== undefined && {
|
|
1260
|
+
stop_reason: advisorOutput.stopReason,
|
|
1261
|
+
}),
|
|
1256
1262
|
},
|
|
1257
1263
|
cache_control: cacheControl,
|
|
1258
1264
|
});
|
|
@@ -10,6 +10,7 @@ export const advisor_20260301ArgsSchema = lazySchema(() =>
|
|
|
10
10
|
z.object({
|
|
11
11
|
model: z.string(),
|
|
12
12
|
maxUses: z.number().optional(),
|
|
13
|
+
maxTokens: z.number().int().min(1024).optional(),
|
|
13
14
|
caching: z
|
|
14
15
|
.object({
|
|
15
16
|
type: z.literal('ephemeral'),
|
|
@@ -26,10 +27,12 @@ export const advisor_20260301OutputSchema = lazySchema(() =>
|
|
|
26
27
|
z.object({
|
|
27
28
|
type: z.literal('advisor_result'),
|
|
28
29
|
text: z.string(),
|
|
30
|
+
stopReason: z.string().optional(),
|
|
29
31
|
}),
|
|
30
32
|
z.object({
|
|
31
33
|
type: z.literal('advisor_redacted_result'),
|
|
32
34
|
encryptedContent: z.string(),
|
|
35
|
+
stopReason: z.string().optional(),
|
|
33
36
|
}),
|
|
34
37
|
z.object({
|
|
35
38
|
type: z.literal('advisor_tool_result_error'),
|
|
@@ -54,6 +57,12 @@ const factory = createProviderExecutedToolFactory<
|
|
|
54
57
|
* Plaintext advice from the advisor model.
|
|
55
58
|
*/
|
|
56
59
|
text: string;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* The advisor sub-inference stop reason when `maxTokens` is configured.
|
|
63
|
+
* A value of `"max_tokens"` indicates that the advice was truncated.
|
|
64
|
+
*/
|
|
65
|
+
stopReason?: string;
|
|
57
66
|
}
|
|
58
67
|
| {
|
|
59
68
|
type: 'advisor_redacted_result';
|
|
@@ -64,6 +73,12 @@ const factory = createProviderExecutedToolFactory<
|
|
|
64
73
|
* advice into the executor's prompt.
|
|
65
74
|
*/
|
|
66
75
|
encryptedContent: string;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* The advisor sub-inference stop reason when `maxTokens` is configured.
|
|
79
|
+
* A value of `"max_tokens"` indicates that the advice was truncated.
|
|
80
|
+
*/
|
|
81
|
+
stopReason?: string;
|
|
67
82
|
}
|
|
68
83
|
| {
|
|
69
84
|
type: 'advisor_tool_result_error';
|
|
@@ -99,6 +114,17 @@ const factory = createProviderExecutedToolFactory<
|
|
|
99
114
|
*/
|
|
100
115
|
maxUses?: number;
|
|
101
116
|
|
|
117
|
+
/**
|
|
118
|
+
* Maximum number of tokens the advisor can generate per call, including
|
|
119
|
+
* thinking and text. This is independent of the executor's request-level
|
|
120
|
+
* `maxOutputTokens`.
|
|
121
|
+
*
|
|
122
|
+
* The minimum value is 1024. Anthropic recommends starting with 2048.
|
|
123
|
+
* Values above the selected advisor model's output limit return a
|
|
124
|
+
* `400 invalid_request_error` from the API.
|
|
125
|
+
*/
|
|
126
|
+
maxTokens?: number;
|
|
127
|
+
|
|
102
128
|
/**
|
|
103
129
|
* Enables prompt caching for the advisor's own transcript across calls
|
|
104
130
|
* within a conversation. Unlike `cache_control` on content blocks, this
|