@ai-sdk/anthropic 4.0.0-beta.2 → 4.0.0-beta.21
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 +148 -4
- package/README.md +2 -0
- package/dist/index.d.mts +50 -38
- package/dist/index.d.ts +50 -38
- package/dist/index.js +1403 -1075
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1440 -1091
- package/dist/index.mjs.map +1 -1
- package/dist/internal/index.d.mts +64 -43
- package/dist/internal/index.d.ts +64 -43
- package/dist/internal/index.js +143 -25
- package/dist/internal/index.js.map +1 -1
- package/dist/internal/index.mjs +146 -23
- package/dist/internal/index.mjs.map +1 -1
- package/docs/05-anthropic.mdx +53 -6
- package/package.json +3 -5
- package/src/anthropic-files.ts +106 -0
- package/src/anthropic-messages-api.ts +4 -0
- package/src/anthropic-messages-language-model.ts +147 -38
- package/src/anthropic-messages-options.ts +29 -5
- package/src/anthropic-prepare-tools.ts +22 -10
- package/src/anthropic-provider.ts +38 -9
- package/src/convert-anthropic-messages-usage.ts +2 -2
- package/src/convert-to-anthropic-messages-prompt.ts +40 -18
- package/src/get-cache-control.ts +5 -5
- package/src/internal/index.ts +4 -1
- package/src/map-anthropic-stop-reason.ts +2 -2
- package/src/skills/anthropic-skills-api.ts +44 -0
- package/src/skills/anthropic-skills.ts +136 -0
package/docs/05-anthropic.mdx
CHANGED
|
@@ -146,6 +146,12 @@ The following optional provider options are available for Anthropic models:
|
|
|
146
146
|
- `"jsonTool"`: Use a special `"json"` tool to specify the structured output format.
|
|
147
147
|
- `"auto"`: Use `"outputFormat"` when supported, otherwise fall back to `"jsonTool"` (default).
|
|
148
148
|
|
|
149
|
+
- `metadata` _object_
|
|
150
|
+
|
|
151
|
+
Optional. Metadata to include with the request. See the [Anthropic API documentation](https://platform.claude.com/docs/en/api/messages/create) for details.
|
|
152
|
+
|
|
153
|
+
- `userId` _string_ - An external identifier for the end-user. Should be a UUID, hash, or other opaque identifier. Must not contain PII.
|
|
154
|
+
|
|
149
155
|
### Structured Outputs and Tool Input Streaming
|
|
150
156
|
|
|
151
157
|
Tool call streaming is enabled by default. You can opt out by setting the
|
|
@@ -220,17 +226,58 @@ The `speed` option accepts `'fast'` or `'standard'` (default behavior).
|
|
|
220
226
|
|
|
221
227
|
### Reasoning
|
|
222
228
|
|
|
223
|
-
Anthropic
|
|
229
|
+
Anthropic models support extended thinking, where Claude shows its reasoning process before providing a final answer.
|
|
224
230
|
|
|
225
|
-
|
|
226
|
-
|
|
231
|
+
#### Adaptive Thinking
|
|
232
|
+
|
|
233
|
+
For newer models (`claude-sonnet-4-6`, `claude-opus-4-6`, and later), use adaptive thinking.
|
|
234
|
+
Claude automatically determines how much reasoning to use based on the complexity of the prompt.
|
|
227
235
|
|
|
228
236
|
```ts highlight="4,8-10"
|
|
229
237
|
import { anthropic, AnthropicLanguageModelOptions } from '@ai-sdk/anthropic';
|
|
230
238
|
import { generateText } from 'ai';
|
|
231
239
|
|
|
232
240
|
const { text, reasoningText, reasoning } = await generateText({
|
|
233
|
-
model: anthropic('claude-opus-4-
|
|
241
|
+
model: anthropic('claude-opus-4-6'),
|
|
242
|
+
prompt: 'How many people will live in the world in 2040?',
|
|
243
|
+
providerOptions: {
|
|
244
|
+
anthropic: {
|
|
245
|
+
thinking: { type: 'adaptive' },
|
|
246
|
+
} satisfies AnthropicLanguageModelOptions,
|
|
247
|
+
},
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
console.log(reasoningText); // reasoning text
|
|
251
|
+
console.log(reasoning); // reasoning details including redacted reasoning
|
|
252
|
+
console.log(text); // text response
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
You can combine adaptive thinking with the `effort` option to control how much reasoning Claude uses:
|
|
256
|
+
|
|
257
|
+
```ts highlight="6-8"
|
|
258
|
+
const { text } = await generateText({
|
|
259
|
+
model: anthropic('claude-opus-4-6'),
|
|
260
|
+
prompt: 'Invent a new holiday and describe its traditions.',
|
|
261
|
+
providerOptions: {
|
|
262
|
+
anthropic: {
|
|
263
|
+
thinking: { type: 'adaptive' },
|
|
264
|
+
effort: 'max', // 'low' | 'medium' | 'high' | 'max'
|
|
265
|
+
} satisfies AnthropicLanguageModelOptions,
|
|
266
|
+
},
|
|
267
|
+
});
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
#### Budget-Based Thinking
|
|
271
|
+
|
|
272
|
+
For earlier models (`claude-opus-4-20250514`, `claude-sonnet-4-20250514`, `claude-sonnet-4-5-20250929`),
|
|
273
|
+
use `type: 'enabled'` with an explicit token budget:
|
|
274
|
+
|
|
275
|
+
```ts highlight="4,8-10"
|
|
276
|
+
import { anthropic, AnthropicLanguageModelOptions } from '@ai-sdk/anthropic';
|
|
277
|
+
import { generateText } from 'ai';
|
|
278
|
+
|
|
279
|
+
const { text, reasoningText, reasoning } = await generateText({
|
|
280
|
+
model: anthropic('claude-sonnet-4-5-20250929'),
|
|
234
281
|
prompt: 'How many people will live in the world in 2040?',
|
|
235
282
|
providerOptions: {
|
|
236
283
|
anthropic: {
|
|
@@ -1114,12 +1161,12 @@ import {
|
|
|
1114
1161
|
anthropic,
|
|
1115
1162
|
forwardAnthropicContainerIdFromLastStep,
|
|
1116
1163
|
} from '@ai-sdk/anthropic';
|
|
1117
|
-
import { generateText, tool,
|
|
1164
|
+
import { generateText, tool, isStepCount } from 'ai';
|
|
1118
1165
|
import { z } from 'zod';
|
|
1119
1166
|
|
|
1120
1167
|
const result = await generateText({
|
|
1121
1168
|
model: anthropic('claude-sonnet-4-5'),
|
|
1122
|
-
stopWhen:
|
|
1169
|
+
stopWhen: isStepCount(10),
|
|
1123
1170
|
prompt:
|
|
1124
1171
|
'Get the weather for Tokyo, Sydney, and London, then calculate the average temperature.',
|
|
1125
1172
|
tools: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/anthropic",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.21",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
}
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@ai-sdk/provider": "4.0.0-beta.
|
|
40
|
-
"@ai-sdk/provider-utils": "5.0.0-beta.
|
|
39
|
+
"@ai-sdk/provider": "4.0.0-beta.8",
|
|
40
|
+
"@ai-sdk/provider-utils": "5.0.0-beta.14"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/node": "20.17.24",
|
|
@@ -71,9 +71,7 @@
|
|
|
71
71
|
"build": "pnpm clean && tsup --tsconfig tsconfig.build.json",
|
|
72
72
|
"build:watch": "pnpm clean && tsup --watch --tsconfig tsconfig.build.json",
|
|
73
73
|
"clean": "del-cli dist docs *.tsbuildinfo",
|
|
74
|
-
"lint": "eslint \"./**/*.ts*\"",
|
|
75
74
|
"type-check": "tsc --build",
|
|
76
|
-
"prettier-check": "prettier --check \"./**/*.ts*\"",
|
|
77
75
|
"test": "pnpm test:node && pnpm test:edge",
|
|
78
76
|
"test:update": "pnpm test:node -u",
|
|
79
77
|
"test:watch": "vitest --config vitest.node.config.js",
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FilesV4,
|
|
3
|
+
FilesV4UploadFileCallOptions,
|
|
4
|
+
FilesV4UploadFileResult,
|
|
5
|
+
} from '@ai-sdk/provider';
|
|
6
|
+
import {
|
|
7
|
+
combineHeaders,
|
|
8
|
+
convertBase64ToUint8Array,
|
|
9
|
+
createJsonResponseHandler,
|
|
10
|
+
FetchFunction,
|
|
11
|
+
lazySchema,
|
|
12
|
+
parseProviderOptions,
|
|
13
|
+
postFormDataToApi,
|
|
14
|
+
zodSchema,
|
|
15
|
+
} from '@ai-sdk/provider-utils';
|
|
16
|
+
import { z } from 'zod/v4';
|
|
17
|
+
import { anthropicFailedResponseHandler } from './anthropic-error';
|
|
18
|
+
|
|
19
|
+
const anthropicUploadFileProviderOptions = z.object({});
|
|
20
|
+
|
|
21
|
+
const anthropicUploadFileResponseSchema = lazySchema(() =>
|
|
22
|
+
zodSchema(
|
|
23
|
+
z.object({
|
|
24
|
+
id: z.string(),
|
|
25
|
+
type: z.literal('file'),
|
|
26
|
+
filename: z.string(),
|
|
27
|
+
mime_type: z.string(),
|
|
28
|
+
size_bytes: z.number(),
|
|
29
|
+
created_at: z.string(),
|
|
30
|
+
downloadable: z.boolean().nullish(),
|
|
31
|
+
}),
|
|
32
|
+
),
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
interface AnthropicFilesConfig {
|
|
36
|
+
provider: string;
|
|
37
|
+
baseURL: string;
|
|
38
|
+
headers: () => Record<string, string | undefined>;
|
|
39
|
+
fetch?: FetchFunction;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export class AnthropicFiles implements FilesV4 {
|
|
43
|
+
readonly specificationVersion = 'v4';
|
|
44
|
+
|
|
45
|
+
get provider(): string {
|
|
46
|
+
return this.config.provider;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
constructor(private readonly config: AnthropicFilesConfig) {}
|
|
50
|
+
|
|
51
|
+
async uploadFile({
|
|
52
|
+
data,
|
|
53
|
+
mediaType,
|
|
54
|
+
filename,
|
|
55
|
+
providerOptions,
|
|
56
|
+
}: FilesV4UploadFileCallOptions): Promise<FilesV4UploadFileResult> {
|
|
57
|
+
const anthropicOptions = await parseProviderOptions({
|
|
58
|
+
provider: 'anthropic',
|
|
59
|
+
providerOptions,
|
|
60
|
+
schema: zodSchema(anthropicUploadFileProviderOptions),
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const fileBytes =
|
|
64
|
+
data instanceof Uint8Array ? data : convertBase64ToUint8Array(data);
|
|
65
|
+
|
|
66
|
+
const blob = new Blob([fileBytes], { type: mediaType });
|
|
67
|
+
|
|
68
|
+
const formData = new FormData();
|
|
69
|
+
if (filename != null) {
|
|
70
|
+
formData.append('file', blob, filename);
|
|
71
|
+
} else {
|
|
72
|
+
formData.append('file', blob);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const { value: response } = await postFormDataToApi({
|
|
76
|
+
url: `${this.config.baseURL}/files`,
|
|
77
|
+
headers: combineHeaders(this.config.headers(), {
|
|
78
|
+
'anthropic-beta': 'files-api-2025-04-14',
|
|
79
|
+
}),
|
|
80
|
+
formData,
|
|
81
|
+
failedResponseHandler: anthropicFailedResponseHandler,
|
|
82
|
+
successfulResponseHandler: createJsonResponseHandler(
|
|
83
|
+
anthropicUploadFileResponseSchema,
|
|
84
|
+
),
|
|
85
|
+
fetch: this.config.fetch,
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
warnings: [],
|
|
90
|
+
providerReference: { anthropic: response.id },
|
|
91
|
+
mediaType: response.mime_type ?? mediaType,
|
|
92
|
+
filename: response.filename ?? filename,
|
|
93
|
+
providerMetadata: {
|
|
94
|
+
anthropic: {
|
|
95
|
+
filename: response.filename,
|
|
96
|
+
mimeType: response.mime_type,
|
|
97
|
+
sizeBytes: response.size_bytes,
|
|
98
|
+
createdAt: response.created_at,
|
|
99
|
+
...(response.downloadable != null
|
|
100
|
+
? { downloadable: response.downloadable }
|
|
101
|
+
: {}),
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
APICallError,
|
|
3
3
|
JSONObject,
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
4
|
+
LanguageModelV4,
|
|
5
|
+
LanguageModelV4CallOptions,
|
|
6
|
+
LanguageModelV4Content,
|
|
7
|
+
LanguageModelV4FinishReason,
|
|
8
|
+
LanguageModelV4FunctionTool,
|
|
9
|
+
LanguageModelV4GenerateResult,
|
|
10
|
+
LanguageModelV4Prompt,
|
|
11
|
+
LanguageModelV4Source,
|
|
12
|
+
LanguageModelV4StreamPart,
|
|
13
|
+
LanguageModelV4StreamResult,
|
|
14
|
+
LanguageModelV4ToolCall,
|
|
15
|
+
SharedV4ProviderMetadata,
|
|
16
|
+
SharedV4Warning,
|
|
17
17
|
} from '@ai-sdk/provider';
|
|
18
18
|
import {
|
|
19
19
|
combineHeaders,
|
|
@@ -23,11 +23,15 @@ import {
|
|
|
23
23
|
FetchFunction,
|
|
24
24
|
generateId,
|
|
25
25
|
InferSchema,
|
|
26
|
+
isCustomReasoning,
|
|
27
|
+
mapReasoningToProviderBudget,
|
|
28
|
+
mapReasoningToProviderEffort,
|
|
26
29
|
parseProviderOptions,
|
|
27
30
|
ParseResult,
|
|
28
31
|
postJsonToApi,
|
|
29
32
|
Resolvable,
|
|
30
33
|
resolve,
|
|
34
|
+
resolveProviderReference,
|
|
31
35
|
} from '@ai-sdk/provider-utils';
|
|
32
36
|
import { anthropicFailedResponseHandler } from './anthropic-error';
|
|
33
37
|
import { AnthropicMessageMetadata } from './anthropic-message-metadata';
|
|
@@ -42,6 +46,7 @@ import {
|
|
|
42
46
|
} from './anthropic-messages-api';
|
|
43
47
|
import {
|
|
44
48
|
AnthropicMessagesModelId,
|
|
49
|
+
AnthropicLanguageModelOptions,
|
|
45
50
|
anthropicLanguageModelOptions,
|
|
46
51
|
} from './anthropic-messages-options';
|
|
47
52
|
import { prepareTools } from './anthropic-prepare-tools';
|
|
@@ -61,7 +66,7 @@ function createCitationSource(
|
|
|
61
66
|
mediaType: string;
|
|
62
67
|
}>,
|
|
63
68
|
generateId: () => string,
|
|
64
|
-
):
|
|
69
|
+
): LanguageModelV4Source | undefined {
|
|
65
70
|
if (citation.type === 'web_search_result_location') {
|
|
66
71
|
return {
|
|
67
72
|
type: 'source' as const,
|
|
@@ -74,7 +79,7 @@ function createCitationSource(
|
|
|
74
79
|
citedText: citation.cited_text,
|
|
75
80
|
encryptedIndex: citation.encrypted_index,
|
|
76
81
|
},
|
|
77
|
-
} satisfies
|
|
82
|
+
} satisfies SharedV4ProviderMetadata,
|
|
78
83
|
};
|
|
79
84
|
}
|
|
80
85
|
|
|
@@ -108,7 +113,7 @@ function createCitationSource(
|
|
|
108
113
|
startCharIndex: citation.start_char_index,
|
|
109
114
|
endCharIndex: citation.end_char_index,
|
|
110
115
|
},
|
|
111
|
-
} satisfies
|
|
116
|
+
} satisfies SharedV4ProviderMetadata,
|
|
112
117
|
};
|
|
113
118
|
}
|
|
114
119
|
|
|
@@ -122,17 +127,23 @@ type AnthropicMessagesConfig = {
|
|
|
122
127
|
args: Record<string, any>,
|
|
123
128
|
betas: Set<string>,
|
|
124
129
|
) => Record<string, any>;
|
|
125
|
-
supportedUrls?: () =>
|
|
130
|
+
supportedUrls?: () => LanguageModelV4['supportedUrls'];
|
|
126
131
|
generateId?: () => string;
|
|
127
132
|
|
|
128
133
|
/**
|
|
129
134
|
* When false, the model will use JSON tool fallback for structured outputs.
|
|
130
135
|
*/
|
|
131
136
|
supportsNativeStructuredOutput?: boolean;
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* When false, `strict` on tool definitions will be ignored and a warning emitted.
|
|
140
|
+
* Defaults to true.
|
|
141
|
+
*/
|
|
142
|
+
supportsStrictTools?: boolean;
|
|
132
143
|
};
|
|
133
144
|
|
|
134
|
-
export class AnthropicMessagesLanguageModel implements
|
|
135
|
-
readonly specificationVersion = '
|
|
145
|
+
export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
|
|
146
|
+
readonly specificationVersion = 'v4';
|
|
136
147
|
|
|
137
148
|
readonly modelId: AnthropicMessagesModelId;
|
|
138
149
|
|
|
@@ -184,13 +195,14 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
184
195
|
seed,
|
|
185
196
|
tools,
|
|
186
197
|
toolChoice,
|
|
198
|
+
reasoning,
|
|
187
199
|
providerOptions,
|
|
188
200
|
stream,
|
|
189
|
-
}:
|
|
201
|
+
}: LanguageModelV4CallOptions & {
|
|
190
202
|
stream: boolean;
|
|
191
203
|
userSuppliedBetas: Set<string>;
|
|
192
204
|
}) {
|
|
193
|
-
const warnings:
|
|
205
|
+
const warnings: SharedV4Warning[] = [];
|
|
194
206
|
|
|
195
207
|
if (frequencyPenalty != null) {
|
|
196
208
|
warnings.push({ type: 'unsupported', feature: 'frequencyPenalty' });
|
|
@@ -263,20 +275,27 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
263
275
|
const {
|
|
264
276
|
maxOutputTokens: maxOutputTokensForModel,
|
|
265
277
|
supportsStructuredOutput: modelSupportsStructuredOutput,
|
|
278
|
+
supportsAdaptiveThinking,
|
|
266
279
|
isKnownModel,
|
|
267
280
|
} = getModelCapabilities(this.modelId);
|
|
268
281
|
|
|
282
|
+
const isAnthropicModel = isKnownModel || this.modelId.startsWith('claude-');
|
|
283
|
+
|
|
269
284
|
const supportsStructuredOutput =
|
|
270
285
|
(this.config.supportsNativeStructuredOutput ?? true) &&
|
|
271
286
|
modelSupportsStructuredOutput;
|
|
272
287
|
|
|
288
|
+
const supportsStrictTools =
|
|
289
|
+
(this.config.supportsStrictTools ?? true) &&
|
|
290
|
+
modelSupportsStructuredOutput;
|
|
291
|
+
|
|
273
292
|
const structureOutputMode =
|
|
274
293
|
anthropicOptions?.structuredOutputMode ?? 'auto';
|
|
275
294
|
const useStructuredOutput =
|
|
276
295
|
structureOutputMode === 'outputFormat' ||
|
|
277
296
|
(structureOutputMode === 'auto' && supportsStructuredOutput);
|
|
278
297
|
|
|
279
|
-
const jsonResponseTool:
|
|
298
|
+
const jsonResponseTool: LanguageModelV4FunctionTool | undefined =
|
|
280
299
|
responseFormat?.type === 'json' &&
|
|
281
300
|
responseFormat.schema != null &&
|
|
282
301
|
!useStructuredOutput
|
|
@@ -326,6 +345,29 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
326
345
|
toolNameMapping,
|
|
327
346
|
});
|
|
328
347
|
|
|
348
|
+
/*
|
|
349
|
+
* Map top-level `reasoning` to Anthropic thinking/effort when provider
|
|
350
|
+
* options don't already specify them. Provider options always take precedence.
|
|
351
|
+
*/
|
|
352
|
+
if (
|
|
353
|
+
isCustomReasoning(reasoning) &&
|
|
354
|
+
anthropicOptions?.thinking == null &&
|
|
355
|
+
anthropicOptions?.effort == null
|
|
356
|
+
) {
|
|
357
|
+
const reasoningConfig = resolveAnthropicReasoningConfig({
|
|
358
|
+
reasoning,
|
|
359
|
+
supportsAdaptiveThinking,
|
|
360
|
+
maxOutputTokensForModel,
|
|
361
|
+
warnings,
|
|
362
|
+
});
|
|
363
|
+
if (reasoningConfig != null) {
|
|
364
|
+
anthropicOptions.thinking = reasoningConfig.thinking;
|
|
365
|
+
if (reasoningConfig.effort != null) {
|
|
366
|
+
anthropicOptions.effort = reasoningConfig.effort;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
329
371
|
const thinkingType = anthropicOptions?.thinking?.type;
|
|
330
372
|
const isThinking =
|
|
331
373
|
thinkingType === 'enabled' || thinkingType === 'adaptive';
|
|
@@ -378,6 +420,9 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
378
420
|
...(anthropicOptions?.cacheControl && {
|
|
379
421
|
cache_control: anthropicOptions.cacheControl,
|
|
380
422
|
}),
|
|
423
|
+
...(anthropicOptions?.metadata?.userId != null && {
|
|
424
|
+
metadata: { user_id: anthropicOptions.metadata.userId },
|
|
425
|
+
}),
|
|
381
426
|
|
|
382
427
|
// mcp servers:
|
|
383
428
|
...(anthropicOptions?.mcpServers &&
|
|
@@ -406,7 +451,13 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
406
451
|
id: anthropicOptions.container.id,
|
|
407
452
|
skills: anthropicOptions.container.skills.map(skill => ({
|
|
408
453
|
type: skill.type,
|
|
409
|
-
skill_id:
|
|
454
|
+
skill_id:
|
|
455
|
+
skill.type === 'custom'
|
|
456
|
+
? resolveProviderReference({
|
|
457
|
+
reference: skill.providerReference,
|
|
458
|
+
provider: 'anthropic',
|
|
459
|
+
})
|
|
460
|
+
: skill.skillId,
|
|
410
461
|
version: skill.version,
|
|
411
462
|
})),
|
|
412
463
|
} satisfies AnthropicContainer)
|
|
@@ -522,8 +573,10 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
522
573
|
// adjust max tokens to account for thinking:
|
|
523
574
|
baseArgs.max_tokens = maxTokens + (thinkingBudget ?? 0);
|
|
524
575
|
} else {
|
|
525
|
-
// Only check temperature/topP mutual exclusivity
|
|
526
|
-
|
|
576
|
+
// Only check temperature/topP mutual exclusivity for known Anthropic models
|
|
577
|
+
// when thinking is not enabled. Non-Anthropic models using the Anthropic-compatible
|
|
578
|
+
// API (e.g. Minimax) may require both parameters to be set.
|
|
579
|
+
if (isAnthropicModel && topP != null && temperature != null) {
|
|
527
580
|
warnings.push({
|
|
528
581
|
type: 'unsupported',
|
|
529
582
|
feature: 'topP',
|
|
@@ -614,6 +667,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
614
667
|
disableParallelToolUse: true,
|
|
615
668
|
cacheControlValidator,
|
|
616
669
|
supportsStructuredOutput: false,
|
|
670
|
+
supportsStrictTools,
|
|
617
671
|
}
|
|
618
672
|
: {
|
|
619
673
|
tools: tools ?? [],
|
|
@@ -621,6 +675,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
621
675
|
disableParallelToolUse: anthropicOptions?.disableParallelToolUse,
|
|
622
676
|
cacheControlValidator,
|
|
623
677
|
supportsStructuredOutput,
|
|
678
|
+
supportsStrictTools,
|
|
624
679
|
},
|
|
625
680
|
);
|
|
626
681
|
|
|
@@ -694,7 +749,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
694
749
|
return this.config.transformRequestBody?.(args, betas) ?? args;
|
|
695
750
|
}
|
|
696
751
|
|
|
697
|
-
private extractCitationDocuments(prompt:
|
|
752
|
+
private extractCitationDocuments(prompt: LanguageModelV4Prompt): Array<{
|
|
698
753
|
title: string;
|
|
699
754
|
filename?: string;
|
|
700
755
|
mediaType: string;
|
|
@@ -738,8 +793,8 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
738
793
|
}
|
|
739
794
|
|
|
740
795
|
async doGenerate(
|
|
741
|
-
options:
|
|
742
|
-
): Promise<
|
|
796
|
+
options: LanguageModelV4CallOptions,
|
|
797
|
+
): Promise<LanguageModelV4GenerateResult> {
|
|
743
798
|
const {
|
|
744
799
|
args,
|
|
745
800
|
warnings,
|
|
@@ -779,8 +834,8 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
779
834
|
fetch: this.config.fetch,
|
|
780
835
|
});
|
|
781
836
|
|
|
782
|
-
const content: Array<
|
|
783
|
-
const mcpToolCalls: Record<string,
|
|
837
|
+
const content: Array<LanguageModelV4Content> = [];
|
|
838
|
+
const mcpToolCalls: Record<string, LanguageModelV4ToolCall> = {};
|
|
784
839
|
const serverToolCalls: Record<string, string> = {}; // tool_use_id -> provider tool name
|
|
785
840
|
let isJsonResponseFromTool = false;
|
|
786
841
|
|
|
@@ -1205,7 +1260,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
1205
1260
|
) ?? null,
|
|
1206
1261
|
} satisfies AnthropicMessageMetadata;
|
|
1207
1262
|
|
|
1208
|
-
const providerMetadata:
|
|
1263
|
+
const providerMetadata: SharedV4ProviderMetadata = {
|
|
1209
1264
|
anthropic: anthropicMetadata,
|
|
1210
1265
|
};
|
|
1211
1266
|
|
|
@@ -1219,8 +1274,8 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
1219
1274
|
}
|
|
1220
1275
|
|
|
1221
1276
|
async doStream(
|
|
1222
|
-
options:
|
|
1223
|
-
): Promise<
|
|
1277
|
+
options: LanguageModelV4CallOptions,
|
|
1278
|
+
): Promise<LanguageModelV4StreamResult> {
|
|
1224
1279
|
const {
|
|
1225
1280
|
args: body,
|
|
1226
1281
|
warnings,
|
|
@@ -1257,7 +1312,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
1257
1312
|
fetch: this.config.fetch,
|
|
1258
1313
|
});
|
|
1259
1314
|
|
|
1260
|
-
let finishReason:
|
|
1315
|
+
let finishReason: LanguageModelV4FinishReason = {
|
|
1261
1316
|
unified: 'other',
|
|
1262
1317
|
raw: undefined,
|
|
1263
1318
|
};
|
|
@@ -1289,7 +1344,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
1289
1344
|
}
|
|
1290
1345
|
| { type: 'text' | 'reasoning' }
|
|
1291
1346
|
> = {};
|
|
1292
|
-
const mcpToolCalls: Record<string,
|
|
1347
|
+
const mcpToolCalls: Record<string, LanguageModelV4ToolCall> = {};
|
|
1293
1348
|
const serverToolCalls: Record<string, string> = {}; // tool_use_id -> provider tool name
|
|
1294
1349
|
|
|
1295
1350
|
let contextManagement:
|
|
@@ -1323,7 +1378,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
1323
1378
|
const transformedStream = response.pipeThrough(
|
|
1324
1379
|
new TransformStream<
|
|
1325
1380
|
ParseResult<InferSchema<typeof anthropicMessagesChunkSchema>>,
|
|
1326
|
-
|
|
1381
|
+
LanguageModelV4StreamPart
|
|
1327
1382
|
>({
|
|
1328
1383
|
start(controller) {
|
|
1329
1384
|
controller.enqueue({ type: 'stream-start', warnings });
|
|
@@ -2176,7 +2231,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
2176
2231
|
contextManagement,
|
|
2177
2232
|
} satisfies AnthropicMessageMetadata;
|
|
2178
2233
|
|
|
2179
|
-
const providerMetadata:
|
|
2234
|
+
const providerMetadata: SharedV4ProviderMetadata = {
|
|
2180
2235
|
anthropic: anthropicMetadata,
|
|
2181
2236
|
};
|
|
2182
2237
|
|
|
@@ -2259,9 +2314,10 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
|
|
|
2259
2314
|
* @see https://docs.claude.com/en/docs/about-claude/models/overview#model-comparison-table
|
|
2260
2315
|
* @see https://platform.claude.com/docs/en/build-with-claude/structured-outputs
|
|
2261
2316
|
*/
|
|
2262
|
-
function getModelCapabilities(modelId: string): {
|
|
2317
|
+
export function getModelCapabilities(modelId: string): {
|
|
2263
2318
|
maxOutputTokens: number;
|
|
2264
2319
|
supportsStructuredOutput: boolean;
|
|
2320
|
+
supportsAdaptiveThinking: boolean;
|
|
2265
2321
|
isKnownModel: boolean;
|
|
2266
2322
|
} {
|
|
2267
2323
|
if (
|
|
@@ -2271,6 +2327,7 @@ function getModelCapabilities(modelId: string): {
|
|
|
2271
2327
|
return {
|
|
2272
2328
|
maxOutputTokens: 128000,
|
|
2273
2329
|
supportsStructuredOutput: true,
|
|
2330
|
+
supportsAdaptiveThinking: true,
|
|
2274
2331
|
isKnownModel: true,
|
|
2275
2332
|
};
|
|
2276
2333
|
} else if (
|
|
@@ -2281,36 +2338,42 @@ function getModelCapabilities(modelId: string): {
|
|
|
2281
2338
|
return {
|
|
2282
2339
|
maxOutputTokens: 64000,
|
|
2283
2340
|
supportsStructuredOutput: true,
|
|
2341
|
+
supportsAdaptiveThinking: false,
|
|
2284
2342
|
isKnownModel: true,
|
|
2285
2343
|
};
|
|
2286
2344
|
} else if (modelId.includes('claude-opus-4-1')) {
|
|
2287
2345
|
return {
|
|
2288
2346
|
maxOutputTokens: 32000,
|
|
2289
2347
|
supportsStructuredOutput: true,
|
|
2348
|
+
supportsAdaptiveThinking: false,
|
|
2290
2349
|
isKnownModel: true,
|
|
2291
2350
|
};
|
|
2292
2351
|
} else if (modelId.includes('claude-sonnet-4-')) {
|
|
2293
2352
|
return {
|
|
2294
2353
|
maxOutputTokens: 64000,
|
|
2295
2354
|
supportsStructuredOutput: false,
|
|
2355
|
+
supportsAdaptiveThinking: false,
|
|
2296
2356
|
isKnownModel: true,
|
|
2297
2357
|
};
|
|
2298
2358
|
} else if (modelId.includes('claude-opus-4-')) {
|
|
2299
2359
|
return {
|
|
2300
2360
|
maxOutputTokens: 32000,
|
|
2301
2361
|
supportsStructuredOutput: false,
|
|
2362
|
+
supportsAdaptiveThinking: false,
|
|
2302
2363
|
isKnownModel: true,
|
|
2303
2364
|
};
|
|
2304
2365
|
} else if (modelId.includes('claude-3-haiku')) {
|
|
2305
2366
|
return {
|
|
2306
2367
|
maxOutputTokens: 4096,
|
|
2307
2368
|
supportsStructuredOutput: false,
|
|
2369
|
+
supportsAdaptiveThinking: false,
|
|
2308
2370
|
isKnownModel: true,
|
|
2309
2371
|
};
|
|
2310
2372
|
} else {
|
|
2311
2373
|
return {
|
|
2312
2374
|
maxOutputTokens: 4096,
|
|
2313
2375
|
supportsStructuredOutput: false,
|
|
2376
|
+
supportsAdaptiveThinking: false,
|
|
2314
2377
|
isKnownModel: false,
|
|
2315
2378
|
};
|
|
2316
2379
|
}
|
|
@@ -2341,6 +2404,52 @@ function hasWebTool20260209WithoutCodeExecution(
|
|
|
2341
2404
|
return hasWebTool20260209 && !hasCodeExecutionTool;
|
|
2342
2405
|
}
|
|
2343
2406
|
|
|
2407
|
+
function resolveAnthropicReasoningConfig({
|
|
2408
|
+
reasoning,
|
|
2409
|
+
supportsAdaptiveThinking,
|
|
2410
|
+
maxOutputTokensForModel,
|
|
2411
|
+
warnings,
|
|
2412
|
+
}: {
|
|
2413
|
+
reasoning: LanguageModelV4CallOptions['reasoning'];
|
|
2414
|
+
supportsAdaptiveThinking: boolean;
|
|
2415
|
+
maxOutputTokensForModel: number;
|
|
2416
|
+
warnings: SharedV4Warning[];
|
|
2417
|
+
}): Pick<AnthropicLanguageModelOptions, 'thinking' | 'effort'> | undefined {
|
|
2418
|
+
if (!isCustomReasoning(reasoning)) {
|
|
2419
|
+
return undefined;
|
|
2420
|
+
}
|
|
2421
|
+
|
|
2422
|
+
if (reasoning === 'none') {
|
|
2423
|
+
return { thinking: { type: 'disabled' } };
|
|
2424
|
+
}
|
|
2425
|
+
|
|
2426
|
+
if (supportsAdaptiveThinking) {
|
|
2427
|
+
const effort = mapReasoningToProviderEffort({
|
|
2428
|
+
reasoning,
|
|
2429
|
+
effortMap: {
|
|
2430
|
+
minimal: 'low' as const,
|
|
2431
|
+
low: 'low' as const,
|
|
2432
|
+
medium: 'medium' as const,
|
|
2433
|
+
high: 'high' as const,
|
|
2434
|
+
xhigh: 'max' as const,
|
|
2435
|
+
},
|
|
2436
|
+
warnings,
|
|
2437
|
+
});
|
|
2438
|
+
return { thinking: { type: 'adaptive' }, effort };
|
|
2439
|
+
}
|
|
2440
|
+
|
|
2441
|
+
const budgetTokens = mapReasoningToProviderBudget({
|
|
2442
|
+
reasoning,
|
|
2443
|
+
maxOutputTokens: maxOutputTokensForModel,
|
|
2444
|
+
maxReasoningBudget: maxOutputTokensForModel,
|
|
2445
|
+
warnings,
|
|
2446
|
+
});
|
|
2447
|
+
if (budgetTokens == null) {
|
|
2448
|
+
return undefined;
|
|
2449
|
+
}
|
|
2450
|
+
return { thinking: { type: 'enabled', budgetTokens } };
|
|
2451
|
+
}
|
|
2452
|
+
|
|
2344
2453
|
function mapAnthropicResponseContextManagement(
|
|
2345
2454
|
contextManagement: AnthropicResponseContextManagement | null | undefined,
|
|
2346
2455
|
): AnthropicMessageMetadata['contextManagement'] | null {
|