@ai-sdk/anthropic 4.0.0-beta.3 → 4.0.0-beta.31
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 +230 -4
- package/README.md +2 -0
- package/dist/index.d.ts +60 -34
- package/dist/index.js +1747 -1218
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +67 -36
- package/dist/internal/index.js +1506 -1203
- package/dist/internal/index.js.map +1 -1
- package/docs/05-anthropic.mdx +105 -4
- package/package.json +9 -12
- package/src/anthropic-files.ts +96 -0
- package/src/anthropic-messages-api.ts +4 -0
- package/src/anthropic-messages-language-model.ts +219 -9
- package/src/anthropic-messages-options.ts +62 -6
- package/src/anthropic-prepare-tools.ts +16 -4
- package/src/anthropic-provider.ts +30 -1
- package/src/convert-to-anthropic-messages-prompt.ts +42 -20
- package/src/internal/index.ts +4 -1
- package/src/skills/anthropic-skills-api.ts +44 -0
- package/src/skills/anthropic-skills.ts +136 -0
- package/dist/index.d.mts +0 -1090
- package/dist/index.mjs +0 -5233
- package/dist/index.mjs.map +0 -1
- package/dist/internal/index.d.mts +0 -960
- package/dist/internal/index.mjs +0 -5125
- package/dist/internal/index.mjs.map +0 -1
|
@@ -23,11 +23,18 @@ 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,
|
|
35
|
+
serializeModelOptions,
|
|
36
|
+
WORKFLOW_SERIALIZE,
|
|
37
|
+
WORKFLOW_DESERIALIZE,
|
|
31
38
|
} from '@ai-sdk/provider-utils';
|
|
32
39
|
import { anthropicFailedResponseHandler } from './anthropic-error';
|
|
33
40
|
import { AnthropicMessageMetadata } from './anthropic-message-metadata';
|
|
@@ -42,6 +49,7 @@ import {
|
|
|
42
49
|
} from './anthropic-messages-api';
|
|
43
50
|
import {
|
|
44
51
|
AnthropicMessagesModelId,
|
|
52
|
+
AnthropicLanguageModelOptions,
|
|
45
53
|
anthropicLanguageModelOptions,
|
|
46
54
|
} from './anthropic-messages-options';
|
|
47
55
|
import { prepareTools } from './anthropic-prepare-tools';
|
|
@@ -115,7 +123,7 @@ function createCitationSource(
|
|
|
115
123
|
type AnthropicMessagesConfig = {
|
|
116
124
|
provider: string;
|
|
117
125
|
baseURL: string;
|
|
118
|
-
headers
|
|
126
|
+
headers?: Resolvable<Record<string, string | undefined>>;
|
|
119
127
|
fetch?: FetchFunction;
|
|
120
128
|
buildRequestUrl?: (baseURL: string, isStreaming: boolean) => string;
|
|
121
129
|
transformRequestBody?: (
|
|
@@ -129,6 +137,12 @@ type AnthropicMessagesConfig = {
|
|
|
129
137
|
* When false, the model will use JSON tool fallback for structured outputs.
|
|
130
138
|
*/
|
|
131
139
|
supportsNativeStructuredOutput?: boolean;
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* When false, `strict` on tool definitions will be ignored and a warning emitted.
|
|
143
|
+
* Defaults to true.
|
|
144
|
+
*/
|
|
145
|
+
supportsStrictTools?: boolean;
|
|
132
146
|
};
|
|
133
147
|
|
|
134
148
|
export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
|
|
@@ -139,6 +153,20 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
|
|
|
139
153
|
private readonly config: AnthropicMessagesConfig;
|
|
140
154
|
private readonly generateId: () => string;
|
|
141
155
|
|
|
156
|
+
static [WORKFLOW_SERIALIZE](model: AnthropicMessagesLanguageModel) {
|
|
157
|
+
return serializeModelOptions({
|
|
158
|
+
modelId: model.modelId,
|
|
159
|
+
config: model.config,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
static [WORKFLOW_DESERIALIZE](options: {
|
|
164
|
+
modelId: AnthropicMessagesModelId;
|
|
165
|
+
config: AnthropicMessagesConfig;
|
|
166
|
+
}) {
|
|
167
|
+
return new AnthropicMessagesLanguageModel(options.modelId, options.config);
|
|
168
|
+
}
|
|
169
|
+
|
|
142
170
|
constructor(
|
|
143
171
|
modelId: AnthropicMessagesModelId,
|
|
144
172
|
config: AnthropicMessagesConfig,
|
|
@@ -184,6 +212,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
|
|
|
184
212
|
seed,
|
|
185
213
|
tools,
|
|
186
214
|
toolChoice,
|
|
215
|
+
reasoning,
|
|
187
216
|
providerOptions,
|
|
188
217
|
stream,
|
|
189
218
|
}: LanguageModelV4CallOptions & {
|
|
@@ -263,13 +292,49 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
|
|
|
263
292
|
const {
|
|
264
293
|
maxOutputTokens: maxOutputTokensForModel,
|
|
265
294
|
supportsStructuredOutput: modelSupportsStructuredOutput,
|
|
295
|
+
supportsAdaptiveThinking,
|
|
296
|
+
rejectsSamplingParameters,
|
|
297
|
+
supportsXhighEffort,
|
|
266
298
|
isKnownModel,
|
|
267
299
|
} = getModelCapabilities(this.modelId);
|
|
268
300
|
|
|
301
|
+
if (rejectsSamplingParameters) {
|
|
302
|
+
if (temperature != null) {
|
|
303
|
+
warnings.push({
|
|
304
|
+
type: 'unsupported',
|
|
305
|
+
feature: 'temperature',
|
|
306
|
+
details: `temperature is not supported by ${this.modelId} and will be ignored`,
|
|
307
|
+
});
|
|
308
|
+
temperature = undefined;
|
|
309
|
+
}
|
|
310
|
+
if (topK != null) {
|
|
311
|
+
warnings.push({
|
|
312
|
+
type: 'unsupported',
|
|
313
|
+
feature: 'topK',
|
|
314
|
+
details: `topK is not supported by ${this.modelId} and will be ignored`,
|
|
315
|
+
});
|
|
316
|
+
topK = undefined;
|
|
317
|
+
}
|
|
318
|
+
if (topP != null) {
|
|
319
|
+
warnings.push({
|
|
320
|
+
type: 'unsupported',
|
|
321
|
+
feature: 'topP',
|
|
322
|
+
details: `topP is not supported by ${this.modelId} and will be ignored`,
|
|
323
|
+
});
|
|
324
|
+
topP = undefined;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
const isAnthropicModel = isKnownModel || this.modelId.startsWith('claude-');
|
|
329
|
+
|
|
269
330
|
const supportsStructuredOutput =
|
|
270
331
|
(this.config.supportsNativeStructuredOutput ?? true) &&
|
|
271
332
|
modelSupportsStructuredOutput;
|
|
272
333
|
|
|
334
|
+
const supportsStrictTools =
|
|
335
|
+
(this.config.supportsStrictTools ?? true) &&
|
|
336
|
+
modelSupportsStructuredOutput;
|
|
337
|
+
|
|
273
338
|
const structureOutputMode =
|
|
274
339
|
anthropicOptions?.structuredOutputMode ?? 'auto';
|
|
275
340
|
const useStructuredOutput =
|
|
@@ -326,6 +391,31 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
|
|
|
326
391
|
toolNameMapping,
|
|
327
392
|
});
|
|
328
393
|
|
|
394
|
+
/*
|
|
395
|
+
* Map top-level `reasoning` to Anthropic thinking/effort when provider
|
|
396
|
+
* options don't already specify them. Provider options always take precedence.
|
|
397
|
+
*/
|
|
398
|
+
if (isCustomReasoning(reasoning) && anthropicOptions?.effort == null) {
|
|
399
|
+
const reasoningConfig = resolveAnthropicReasoningConfig({
|
|
400
|
+
reasoning,
|
|
401
|
+
supportsAdaptiveThinking,
|
|
402
|
+
supportsXhighEffort,
|
|
403
|
+
maxOutputTokensForModel,
|
|
404
|
+
warnings,
|
|
405
|
+
});
|
|
406
|
+
if (reasoningConfig != null) {
|
|
407
|
+
if (anthropicOptions.thinking == null) {
|
|
408
|
+
anthropicOptions.thinking = reasoningConfig.thinking;
|
|
409
|
+
}
|
|
410
|
+
if (
|
|
411
|
+
reasoningConfig.effort != null &&
|
|
412
|
+
anthropicOptions.thinking?.type !== 'disabled'
|
|
413
|
+
) {
|
|
414
|
+
anthropicOptions.effort = reasoningConfig.effort;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
329
419
|
const thinkingType = anthropicOptions?.thinking?.type;
|
|
330
420
|
const isThinking =
|
|
331
421
|
thinkingType === 'enabled' || thinkingType === 'adaptive';
|
|
@@ -333,6 +423,10 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
|
|
|
333
423
|
thinkingType === 'enabled'
|
|
334
424
|
? anthropicOptions?.thinking?.budgetTokens
|
|
335
425
|
: undefined;
|
|
426
|
+
const thinkingDisplay =
|
|
427
|
+
thinkingType === 'adaptive'
|
|
428
|
+
? anthropicOptions?.thinking?.display
|
|
429
|
+
: undefined;
|
|
336
430
|
|
|
337
431
|
const maxTokens = maxOutputTokens ?? maxOutputTokensForModel;
|
|
338
432
|
|
|
@@ -352,9 +446,11 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
|
|
|
352
446
|
thinking: {
|
|
353
447
|
type: thinkingType,
|
|
354
448
|
...(thinkingBudget != null && { budget_tokens: thinkingBudget }),
|
|
449
|
+
...(thinkingDisplay != null && { display: thinkingDisplay }),
|
|
355
450
|
},
|
|
356
451
|
}),
|
|
357
452
|
...((anthropicOptions?.effort ||
|
|
453
|
+
anthropicOptions?.taskBudget ||
|
|
358
454
|
(useStructuredOutput &&
|
|
359
455
|
responseFormat?.type === 'json' &&
|
|
360
456
|
responseFormat.schema != null)) && {
|
|
@@ -362,6 +458,15 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
|
|
|
362
458
|
...(anthropicOptions?.effort && {
|
|
363
459
|
effort: anthropicOptions.effort,
|
|
364
460
|
}),
|
|
461
|
+
...(anthropicOptions?.taskBudget && {
|
|
462
|
+
task_budget: {
|
|
463
|
+
type: anthropicOptions.taskBudget.type,
|
|
464
|
+
total: anthropicOptions.taskBudget.total,
|
|
465
|
+
...(anthropicOptions.taskBudget.remaining != null && {
|
|
466
|
+
remaining: anthropicOptions.taskBudget.remaining,
|
|
467
|
+
}),
|
|
468
|
+
},
|
|
469
|
+
}),
|
|
365
470
|
...(useStructuredOutput &&
|
|
366
471
|
responseFormat?.type === 'json' &&
|
|
367
472
|
responseFormat.schema != null && {
|
|
@@ -375,9 +480,15 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
|
|
|
375
480
|
...(anthropicOptions?.speed && {
|
|
376
481
|
speed: anthropicOptions.speed,
|
|
377
482
|
}),
|
|
483
|
+
...(anthropicOptions?.inferenceGeo && {
|
|
484
|
+
inference_geo: anthropicOptions.inferenceGeo,
|
|
485
|
+
}),
|
|
378
486
|
...(anthropicOptions?.cacheControl && {
|
|
379
487
|
cache_control: anthropicOptions.cacheControl,
|
|
380
488
|
}),
|
|
489
|
+
...(anthropicOptions?.metadata?.userId != null && {
|
|
490
|
+
metadata: { user_id: anthropicOptions.metadata.userId },
|
|
491
|
+
}),
|
|
381
492
|
|
|
382
493
|
// mcp servers:
|
|
383
494
|
...(anthropicOptions?.mcpServers &&
|
|
@@ -406,7 +517,13 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
|
|
|
406
517
|
id: anthropicOptions.container.id,
|
|
407
518
|
skills: anthropicOptions.container.skills.map(skill => ({
|
|
408
519
|
type: skill.type,
|
|
409
|
-
skill_id:
|
|
520
|
+
skill_id:
|
|
521
|
+
skill.type === 'custom'
|
|
522
|
+
? resolveProviderReference({
|
|
523
|
+
reference: skill.providerReference,
|
|
524
|
+
provider: 'anthropic',
|
|
525
|
+
})
|
|
526
|
+
: skill.skillId,
|
|
410
527
|
version: skill.version,
|
|
411
528
|
})),
|
|
412
529
|
} satisfies AnthropicContainer)
|
|
@@ -522,8 +639,10 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
|
|
|
522
639
|
// adjust max tokens to account for thinking:
|
|
523
640
|
baseArgs.max_tokens = maxTokens + (thinkingBudget ?? 0);
|
|
524
641
|
} else {
|
|
525
|
-
// Only check temperature/topP mutual exclusivity
|
|
526
|
-
|
|
642
|
+
// Only check temperature/topP mutual exclusivity for known Anthropic models
|
|
643
|
+
// when thinking is not enabled. Non-Anthropic models using the Anthropic-compatible
|
|
644
|
+
// API (e.g. Minimax) may require both parameters to be set.
|
|
645
|
+
if (isAnthropicModel && topP != null && temperature != null) {
|
|
527
646
|
warnings.push({
|
|
528
647
|
type: 'unsupported',
|
|
529
648
|
feature: 'topP',
|
|
@@ -592,6 +711,10 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
|
|
|
592
711
|
betas.add('effort-2025-11-24');
|
|
593
712
|
}
|
|
594
713
|
|
|
714
|
+
if (anthropicOptions?.taskBudget) {
|
|
715
|
+
betas.add('task-budgets-2026-03-13');
|
|
716
|
+
}
|
|
717
|
+
|
|
595
718
|
if (anthropicOptions?.speed === 'fast') {
|
|
596
719
|
betas.add('fast-mode-2026-02-01');
|
|
597
720
|
}
|
|
@@ -614,6 +737,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
|
|
|
614
737
|
disableParallelToolUse: true,
|
|
615
738
|
cacheControlValidator,
|
|
616
739
|
supportsStructuredOutput: false,
|
|
740
|
+
supportsStrictTools,
|
|
617
741
|
}
|
|
618
742
|
: {
|
|
619
743
|
tools: tools ?? [],
|
|
@@ -621,6 +745,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
|
|
|
621
745
|
disableParallelToolUse: anthropicOptions?.disableParallelToolUse,
|
|
622
746
|
cacheControlValidator,
|
|
623
747
|
supportsStructuredOutput,
|
|
748
|
+
supportsStrictTools,
|
|
624
749
|
},
|
|
625
750
|
);
|
|
626
751
|
|
|
@@ -656,7 +781,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
|
|
|
656
781
|
headers: Record<string, string | undefined> | undefined;
|
|
657
782
|
}) {
|
|
658
783
|
return combineHeaders(
|
|
659
|
-
await resolve(this.config.headers),
|
|
784
|
+
this.config.headers ? await resolve(this.config.headers) : undefined,
|
|
660
785
|
headers,
|
|
661
786
|
betas.size > 0 ? { 'anthropic-beta': Array.from(betas).join(',') } : {},
|
|
662
787
|
);
|
|
@@ -665,9 +790,11 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
|
|
|
665
790
|
private async getBetasFromHeaders(
|
|
666
791
|
requestHeaders: Record<string, string | undefined> | undefined,
|
|
667
792
|
) {
|
|
668
|
-
const configHeaders =
|
|
793
|
+
const configHeaders = this.config.headers
|
|
794
|
+
? await resolve(this.config.headers)
|
|
795
|
+
: undefined;
|
|
669
796
|
|
|
670
|
-
const configBetaHeader = configHeaders['anthropic-beta'] ?? '';
|
|
797
|
+
const configBetaHeader = configHeaders?.['anthropic-beta'] ?? '';
|
|
671
798
|
const requestBetaHeader = requestHeaders?.['anthropic-beta'] ?? '';
|
|
672
799
|
|
|
673
800
|
return new Set(
|
|
@@ -1221,6 +1348,8 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
|
|
|
1221
1348
|
async doStream(
|
|
1222
1349
|
options: LanguageModelV4CallOptions,
|
|
1223
1350
|
): Promise<LanguageModelV4StreamResult> {
|
|
1351
|
+
'use step';
|
|
1352
|
+
|
|
1224
1353
|
const {
|
|
1225
1354
|
args: body,
|
|
1226
1355
|
warnings,
|
|
@@ -2259,18 +2388,33 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
|
|
|
2259
2388
|
* @see https://docs.claude.com/en/docs/about-claude/models/overview#model-comparison-table
|
|
2260
2389
|
* @see https://platform.claude.com/docs/en/build-with-claude/structured-outputs
|
|
2261
2390
|
*/
|
|
2262
|
-
function getModelCapabilities(modelId: string): {
|
|
2391
|
+
export function getModelCapabilities(modelId: string): {
|
|
2263
2392
|
maxOutputTokens: number;
|
|
2264
2393
|
supportsStructuredOutput: boolean;
|
|
2394
|
+
supportsAdaptiveThinking: boolean;
|
|
2395
|
+
rejectsSamplingParameters: boolean;
|
|
2396
|
+
supportsXhighEffort: boolean;
|
|
2265
2397
|
isKnownModel: boolean;
|
|
2266
2398
|
} {
|
|
2267
|
-
if (
|
|
2399
|
+
if (modelId.includes('claude-opus-4-7')) {
|
|
2400
|
+
return {
|
|
2401
|
+
maxOutputTokens: 128000,
|
|
2402
|
+
supportsStructuredOutput: true,
|
|
2403
|
+
supportsAdaptiveThinking: true,
|
|
2404
|
+
rejectsSamplingParameters: true,
|
|
2405
|
+
supportsXhighEffort: true,
|
|
2406
|
+
isKnownModel: true,
|
|
2407
|
+
};
|
|
2408
|
+
} else if (
|
|
2268
2409
|
modelId.includes('claude-sonnet-4-6') ||
|
|
2269
2410
|
modelId.includes('claude-opus-4-6')
|
|
2270
2411
|
) {
|
|
2271
2412
|
return {
|
|
2272
2413
|
maxOutputTokens: 128000,
|
|
2273
2414
|
supportsStructuredOutput: true,
|
|
2415
|
+
supportsAdaptiveThinking: true,
|
|
2416
|
+
rejectsSamplingParameters: false,
|
|
2417
|
+
supportsXhighEffort: false,
|
|
2274
2418
|
isKnownModel: true,
|
|
2275
2419
|
};
|
|
2276
2420
|
} else if (
|
|
@@ -2281,36 +2425,54 @@ function getModelCapabilities(modelId: string): {
|
|
|
2281
2425
|
return {
|
|
2282
2426
|
maxOutputTokens: 64000,
|
|
2283
2427
|
supportsStructuredOutput: true,
|
|
2428
|
+
supportsAdaptiveThinking: false,
|
|
2429
|
+
rejectsSamplingParameters: false,
|
|
2430
|
+
supportsXhighEffort: false,
|
|
2284
2431
|
isKnownModel: true,
|
|
2285
2432
|
};
|
|
2286
2433
|
} else if (modelId.includes('claude-opus-4-1')) {
|
|
2287
2434
|
return {
|
|
2288
2435
|
maxOutputTokens: 32000,
|
|
2289
2436
|
supportsStructuredOutput: true,
|
|
2437
|
+
supportsAdaptiveThinking: false,
|
|
2438
|
+
rejectsSamplingParameters: false,
|
|
2439
|
+
supportsXhighEffort: false,
|
|
2290
2440
|
isKnownModel: true,
|
|
2291
2441
|
};
|
|
2292
2442
|
} else if (modelId.includes('claude-sonnet-4-')) {
|
|
2293
2443
|
return {
|
|
2294
2444
|
maxOutputTokens: 64000,
|
|
2295
2445
|
supportsStructuredOutput: false,
|
|
2446
|
+
supportsAdaptiveThinking: false,
|
|
2447
|
+
rejectsSamplingParameters: false,
|
|
2448
|
+
supportsXhighEffort: false,
|
|
2296
2449
|
isKnownModel: true,
|
|
2297
2450
|
};
|
|
2298
2451
|
} else if (modelId.includes('claude-opus-4-')) {
|
|
2299
2452
|
return {
|
|
2300
2453
|
maxOutputTokens: 32000,
|
|
2301
2454
|
supportsStructuredOutput: false,
|
|
2455
|
+
supportsAdaptiveThinking: false,
|
|
2456
|
+
rejectsSamplingParameters: false,
|
|
2457
|
+
supportsXhighEffort: false,
|
|
2302
2458
|
isKnownModel: true,
|
|
2303
2459
|
};
|
|
2304
2460
|
} else if (modelId.includes('claude-3-haiku')) {
|
|
2305
2461
|
return {
|
|
2306
2462
|
maxOutputTokens: 4096,
|
|
2307
2463
|
supportsStructuredOutput: false,
|
|
2464
|
+
supportsAdaptiveThinking: false,
|
|
2465
|
+
rejectsSamplingParameters: false,
|
|
2466
|
+
supportsXhighEffort: false,
|
|
2308
2467
|
isKnownModel: true,
|
|
2309
2468
|
};
|
|
2310
2469
|
} else {
|
|
2311
2470
|
return {
|
|
2312
2471
|
maxOutputTokens: 4096,
|
|
2313
2472
|
supportsStructuredOutput: false,
|
|
2473
|
+
supportsAdaptiveThinking: false,
|
|
2474
|
+
rejectsSamplingParameters: false,
|
|
2475
|
+
supportsXhighEffort: false,
|
|
2314
2476
|
isKnownModel: false,
|
|
2315
2477
|
};
|
|
2316
2478
|
}
|
|
@@ -2341,6 +2503,54 @@ function hasWebTool20260209WithoutCodeExecution(
|
|
|
2341
2503
|
return hasWebTool20260209 && !hasCodeExecutionTool;
|
|
2342
2504
|
}
|
|
2343
2505
|
|
|
2506
|
+
function resolveAnthropicReasoningConfig({
|
|
2507
|
+
reasoning,
|
|
2508
|
+
supportsAdaptiveThinking,
|
|
2509
|
+
supportsXhighEffort,
|
|
2510
|
+
maxOutputTokensForModel,
|
|
2511
|
+
warnings,
|
|
2512
|
+
}: {
|
|
2513
|
+
reasoning: LanguageModelV4CallOptions['reasoning'];
|
|
2514
|
+
supportsAdaptiveThinking: boolean;
|
|
2515
|
+
supportsXhighEffort: boolean;
|
|
2516
|
+
maxOutputTokensForModel: number;
|
|
2517
|
+
warnings: SharedV4Warning[];
|
|
2518
|
+
}): Pick<AnthropicLanguageModelOptions, 'thinking' | 'effort'> | undefined {
|
|
2519
|
+
if (!isCustomReasoning(reasoning)) {
|
|
2520
|
+
return undefined;
|
|
2521
|
+
}
|
|
2522
|
+
|
|
2523
|
+
if (reasoning === 'none') {
|
|
2524
|
+
return { thinking: { type: 'disabled' } };
|
|
2525
|
+
}
|
|
2526
|
+
|
|
2527
|
+
if (supportsAdaptiveThinking) {
|
|
2528
|
+
const effort = mapReasoningToProviderEffort({
|
|
2529
|
+
reasoning,
|
|
2530
|
+
effortMap: {
|
|
2531
|
+
minimal: 'low' as const,
|
|
2532
|
+
low: 'low' as const,
|
|
2533
|
+
medium: 'medium' as const,
|
|
2534
|
+
high: 'high' as const,
|
|
2535
|
+
xhigh: supportsXhighEffort ? ('xhigh' as const) : ('max' as const),
|
|
2536
|
+
},
|
|
2537
|
+
warnings,
|
|
2538
|
+
});
|
|
2539
|
+
return { thinking: { type: 'adaptive' }, effort };
|
|
2540
|
+
}
|
|
2541
|
+
|
|
2542
|
+
const budgetTokens = mapReasoningToProviderBudget({
|
|
2543
|
+
reasoning,
|
|
2544
|
+
maxOutputTokens: maxOutputTokensForModel,
|
|
2545
|
+
maxReasoningBudget: maxOutputTokensForModel,
|
|
2546
|
+
warnings,
|
|
2547
|
+
});
|
|
2548
|
+
if (budgetTokens == null) {
|
|
2549
|
+
return undefined;
|
|
2550
|
+
}
|
|
2551
|
+
return { thinking: { type: 'enabled', budgetTokens } };
|
|
2552
|
+
}
|
|
2553
|
+
|
|
2344
2554
|
function mapAnthropicResponseContextManagement(
|
|
2345
2555
|
contextManagement: AnthropicResponseContextManagement | null | undefined,
|
|
2346
2556
|
): AnthropicMessageMetadata['contextManagement'] | null {
|
|
@@ -17,6 +17,7 @@ export type AnthropicMessagesModelId =
|
|
|
17
17
|
| 'claude-sonnet-4-5'
|
|
18
18
|
| 'claude-sonnet-4-6'
|
|
19
19
|
| 'claude-opus-4-6'
|
|
20
|
+
| 'claude-opus-4-7'
|
|
20
21
|
| (string & {});
|
|
21
22
|
|
|
22
23
|
/**
|
|
@@ -83,6 +84,12 @@ export const anthropicLanguageModelOptions = z.object({
|
|
|
83
84
|
z.object({
|
|
84
85
|
/** for Sonnet 4.6, Opus 4.6, and newer models */
|
|
85
86
|
type: z.literal('adaptive'),
|
|
87
|
+
/**
|
|
88
|
+
* Controls whether thinking content is included in the response.
|
|
89
|
+
* - `"omitted"`: Thinking blocks are present but text is empty (default for Opus 4.7+).
|
|
90
|
+
* - `"summarized"`: Thinking content is returned. Required to see reasoning output.
|
|
91
|
+
*/
|
|
92
|
+
display: z.enum(['omitted', 'summarized']).optional(),
|
|
86
93
|
}),
|
|
87
94
|
z.object({
|
|
88
95
|
/** for models before Opus 4.6, except Sonnet 4.6 still supports it */
|
|
@@ -112,6 +119,23 @@ export const anthropicLanguageModelOptions = z.object({
|
|
|
112
119
|
})
|
|
113
120
|
.optional(),
|
|
114
121
|
|
|
122
|
+
/**
|
|
123
|
+
* Metadata to include with the request.
|
|
124
|
+
*
|
|
125
|
+
* See https://platform.claude.com/docs/en/api/messages/create for details.
|
|
126
|
+
*/
|
|
127
|
+
metadata: z
|
|
128
|
+
.object({
|
|
129
|
+
/**
|
|
130
|
+
* An external identifier for the user associated with the request.
|
|
131
|
+
*
|
|
132
|
+
* Should be a UUID, hash value, or other opaque identifier.
|
|
133
|
+
* Must not contain PII (name, email, phone number, etc.).
|
|
134
|
+
*/
|
|
135
|
+
userId: z.string().optional(),
|
|
136
|
+
})
|
|
137
|
+
.optional(),
|
|
138
|
+
|
|
115
139
|
/**
|
|
116
140
|
* MCP servers to be utilized in this request.
|
|
117
141
|
*/
|
|
@@ -142,11 +166,18 @@ export const anthropicLanguageModelOptions = z.object({
|
|
|
142
166
|
id: z.string().optional(),
|
|
143
167
|
skills: z
|
|
144
168
|
.array(
|
|
145
|
-
z.
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
169
|
+
z.discriminatedUnion('type', [
|
|
170
|
+
z.object({
|
|
171
|
+
type: z.literal('anthropic'),
|
|
172
|
+
skillId: z.string(),
|
|
173
|
+
version: z.string().optional(),
|
|
174
|
+
}),
|
|
175
|
+
z.object({
|
|
176
|
+
type: z.literal('custom'),
|
|
177
|
+
providerReference: z.record(z.string(), z.string()),
|
|
178
|
+
version: z.string().optional(),
|
|
179
|
+
}),
|
|
180
|
+
]),
|
|
150
181
|
)
|
|
151
182
|
.optional(),
|
|
152
183
|
})
|
|
@@ -165,7 +196,22 @@ export const anthropicLanguageModelOptions = z.object({
|
|
|
165
196
|
/**
|
|
166
197
|
* @default 'high'
|
|
167
198
|
*/
|
|
168
|
-
effort: z.enum(['low', 'medium', 'high', 'max']).optional(),
|
|
199
|
+
effort: z.enum(['low', 'medium', 'high', 'xhigh', 'max']).optional(),
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Task budget for agentic turns. Informs the model of the total token budget
|
|
203
|
+
* available for the current task, allowing it to prioritize work and wind down
|
|
204
|
+
* gracefully as the budget is consumed.
|
|
205
|
+
*
|
|
206
|
+
* Advisory only — does not enforce a hard token limit.
|
|
207
|
+
*/
|
|
208
|
+
taskBudget: z
|
|
209
|
+
.object({
|
|
210
|
+
type: z.literal('tokens'),
|
|
211
|
+
total: z.number().int().min(20000),
|
|
212
|
+
remaining: z.number().int().min(0).optional(),
|
|
213
|
+
})
|
|
214
|
+
.optional(),
|
|
169
215
|
|
|
170
216
|
/**
|
|
171
217
|
* Enable fast mode for faster inference (2.5x faster output token speeds).
|
|
@@ -173,6 +219,16 @@ export const anthropicLanguageModelOptions = z.object({
|
|
|
173
219
|
*/
|
|
174
220
|
speed: z.enum(['fast', 'standard']).optional(),
|
|
175
221
|
|
|
222
|
+
/**
|
|
223
|
+
* Controls where model inference runs for this request.
|
|
224
|
+
*
|
|
225
|
+
* - `"global"`: Inference may run in any available geography (default).
|
|
226
|
+
* - `"us"`: Inference runs only in US-based infrastructure.
|
|
227
|
+
*
|
|
228
|
+
* See https://platform.claude.com/docs/en/build-with-claude/data-residency
|
|
229
|
+
*/
|
|
230
|
+
inferenceGeo: z.enum(['us', 'global']).optional(),
|
|
231
|
+
|
|
176
232
|
/**
|
|
177
233
|
* A set of beta features to enable.
|
|
178
234
|
* Allow a provider to receive the full `betas` set if it needs it.
|
|
@@ -26,6 +26,7 @@ export async function prepareTools({
|
|
|
26
26
|
disableParallelToolUse,
|
|
27
27
|
cacheControlValidator,
|
|
28
28
|
supportsStructuredOutput,
|
|
29
|
+
supportsStrictTools,
|
|
29
30
|
}: {
|
|
30
31
|
tools: LanguageModelV4CallOptions['tools'];
|
|
31
32
|
toolChoice: LanguageModelV4CallOptions['toolChoice'] | undefined;
|
|
@@ -33,9 +34,14 @@ export async function prepareTools({
|
|
|
33
34
|
cacheControlValidator?: CacheControlValidator;
|
|
34
35
|
|
|
35
36
|
/**
|
|
36
|
-
* Whether the model supports structured output.
|
|
37
|
+
* Whether the model supports native structured output response format.
|
|
37
38
|
*/
|
|
38
39
|
supportsStructuredOutput: boolean;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Whether the model supports strict mode on tool definitions.
|
|
43
|
+
*/
|
|
44
|
+
supportsStrictTools: boolean;
|
|
39
45
|
}): Promise<{
|
|
40
46
|
tools: Array<AnthropicTool> | undefined;
|
|
41
47
|
toolChoice: AnthropicToolChoice | undefined;
|
|
@@ -72,13 +78,21 @@ export async function prepareTools({
|
|
|
72
78
|
const deferLoading = anthropicOptions?.deferLoading;
|
|
73
79
|
const allowedCallers = anthropicOptions?.allowedCallers;
|
|
74
80
|
|
|
81
|
+
if (!supportsStrictTools && tool.strict != null) {
|
|
82
|
+
toolWarnings.push({
|
|
83
|
+
type: 'unsupported',
|
|
84
|
+
feature: 'strict',
|
|
85
|
+
details: `Tool '${tool.name}' has strict: ${tool.strict}, but strict mode is not supported by this provider. The strict property will be ignored.`,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
75
89
|
anthropicTools.push({
|
|
76
90
|
name: tool.name,
|
|
77
91
|
description: tool.description,
|
|
78
92
|
input_schema: tool.inputSchema,
|
|
79
93
|
cache_control: cacheControl,
|
|
80
94
|
...(eagerInputStreaming ? { eager_input_streaming: true } : {}),
|
|
81
|
-
...(
|
|
95
|
+
...(supportsStrictTools === true && tool.strict != null
|
|
82
96
|
? { strict: tool.strict }
|
|
83
97
|
: {}),
|
|
84
98
|
...(deferLoading != null ? { defer_loading: deferLoading } : {}),
|
|
@@ -308,7 +322,6 @@ export async function prepareTools({
|
|
|
308
322
|
}
|
|
309
323
|
|
|
310
324
|
case 'anthropic.tool_search_regex_20251119': {
|
|
311
|
-
betas.add('advanced-tool-use-2025-11-20');
|
|
312
325
|
anthropicTools.push({
|
|
313
326
|
type: 'tool_search_tool_regex_20251119',
|
|
314
327
|
name: 'tool_search_tool_regex',
|
|
@@ -317,7 +330,6 @@ export async function prepareTools({
|
|
|
317
330
|
}
|
|
318
331
|
|
|
319
332
|
case 'anthropic.tool_search_bm25_20251119': {
|
|
320
|
-
betas.add('advanced-tool-use-2025-11-20');
|
|
321
333
|
anthropicTools.push({
|
|
322
334
|
type: 'tool_search_tool_bm25_20251119',
|
|
323
335
|
name: 'tool_search_tool_bm25',
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
|
+
FilesV4,
|
|
2
3
|
InvalidArgumentError,
|
|
3
4
|
LanguageModelV4,
|
|
4
5
|
NoSuchModelError,
|
|
5
6
|
ProviderV4,
|
|
7
|
+
SkillsV4,
|
|
6
8
|
} from '@ai-sdk/provider';
|
|
7
9
|
import {
|
|
8
10
|
FetchFunction,
|
|
@@ -12,10 +14,12 @@ import {
|
|
|
12
14
|
withoutTrailingSlash,
|
|
13
15
|
withUserAgentSuffix,
|
|
14
16
|
} from '@ai-sdk/provider-utils';
|
|
15
|
-
import {
|
|
17
|
+
import { AnthropicFiles } from './anthropic-files';
|
|
16
18
|
import { AnthropicMessagesLanguageModel } from './anthropic-messages-language-model';
|
|
17
19
|
import { AnthropicMessagesModelId } from './anthropic-messages-options';
|
|
18
20
|
import { anthropicTools } from './anthropic-tools';
|
|
21
|
+
import { AnthropicSkills } from './skills/anthropic-skills';
|
|
22
|
+
import { VERSION } from './version';
|
|
19
23
|
|
|
20
24
|
export interface AnthropicProvider extends ProviderV4 {
|
|
21
25
|
/**
|
|
@@ -37,6 +41,13 @@ export interface AnthropicProvider extends ProviderV4 {
|
|
|
37
41
|
*/
|
|
38
42
|
textEmbeddingModel(modelId: string): never;
|
|
39
43
|
|
|
44
|
+
files(): FilesV4;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Returns a SkillsV4 interface for uploading skills to Anthropic.
|
|
48
|
+
*/
|
|
49
|
+
skills(): SkillsV4;
|
|
50
|
+
|
|
40
51
|
/**
|
|
41
52
|
* Anthropic-specific computer use tool.
|
|
42
53
|
*/
|
|
@@ -143,6 +154,14 @@ export function createAnthropic(
|
|
|
143
154
|
}),
|
|
144
155
|
});
|
|
145
156
|
|
|
157
|
+
const createSkills = () =>
|
|
158
|
+
new AnthropicSkills({
|
|
159
|
+
provider: `${providerName.replace('.messages', '')}.skills`,
|
|
160
|
+
baseURL,
|
|
161
|
+
headers: getHeaders,
|
|
162
|
+
fetch: options.fetch,
|
|
163
|
+
});
|
|
164
|
+
|
|
146
165
|
const provider = function (modelId: AnthropicMessagesModelId) {
|
|
147
166
|
if (new.target) {
|
|
148
167
|
throw new Error(
|
|
@@ -166,6 +185,16 @@ export function createAnthropic(
|
|
|
166
185
|
throw new NoSuchModelError({ modelId, modelType: 'imageModel' });
|
|
167
186
|
};
|
|
168
187
|
|
|
188
|
+
provider.files = () =>
|
|
189
|
+
new AnthropicFiles({
|
|
190
|
+
provider: providerName,
|
|
191
|
+
baseURL,
|
|
192
|
+
headers: getHeaders,
|
|
193
|
+
fetch: options.fetch,
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
provider.skills = createSkills;
|
|
197
|
+
|
|
169
198
|
provider.tools = anthropicTools;
|
|
170
199
|
|
|
171
200
|
return provider;
|