@ai-sdk/anthropic 4.0.0-beta.3 → 4.0.0-beta.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 +236 -4
- package/README.md +2 -0
- package/dist/index.d.ts +60 -34
- package/dist/index.js +1757 -1226
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +72 -36
- package/dist/internal/index.js +1516 -1211
- 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 +223 -13
- package/src/anthropic-messages-options.ts +67 -10
- package/src/anthropic-prepare-tools.ts +27 -6
- 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,14 +711,16 @@ 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
|
}
|
|
598
721
|
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
betas.add('fine-grained-tool-streaming-2025-05-14');
|
|
602
|
-
}
|
|
722
|
+
const defaultEagerInputStreaming =
|
|
723
|
+
stream && (anthropicOptions?.toolStreaming ?? true);
|
|
603
724
|
|
|
604
725
|
const {
|
|
605
726
|
tools: anthropicTools,
|
|
@@ -614,6 +735,8 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
|
|
|
614
735
|
disableParallelToolUse: true,
|
|
615
736
|
cacheControlValidator,
|
|
616
737
|
supportsStructuredOutput: false,
|
|
738
|
+
supportsStrictTools,
|
|
739
|
+
defaultEagerInputStreaming,
|
|
617
740
|
}
|
|
618
741
|
: {
|
|
619
742
|
tools: tools ?? [],
|
|
@@ -621,6 +744,8 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV4 {
|
|
|
621
744
|
disableParallelToolUse: anthropicOptions?.disableParallelToolUse,
|
|
622
745
|
cacheControlValidator,
|
|
623
746
|
supportsStructuredOutput,
|
|
747
|
+
supportsStrictTools,
|
|
748
|
+
defaultEagerInputStreaming,
|
|
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,21 +166,29 @@ 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
|
})
|
|
153
184
|
.optional(),
|
|
154
185
|
|
|
155
186
|
/**
|
|
156
|
-
* Whether to enable
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
187
|
+
* Whether to enable fine-grained (eager) streaming of tool call inputs
|
|
188
|
+
* and structured outputs for every function tool in the request. When
|
|
189
|
+
* true (the default), each function tool receives a default of
|
|
190
|
+
* `eager_input_streaming: true` unless it explicitly sets
|
|
191
|
+
* `providerOptions.anthropic.eagerInputStreaming`.
|
|
160
192
|
*
|
|
161
193
|
* @default true
|
|
162
194
|
*/
|
|
@@ -165,7 +197,22 @@ export const anthropicLanguageModelOptions = z.object({
|
|
|
165
197
|
/**
|
|
166
198
|
* @default 'high'
|
|
167
199
|
*/
|
|
168
|
-
effort: z.enum(['low', 'medium', 'high', 'max']).optional(),
|
|
200
|
+
effort: z.enum(['low', 'medium', 'high', 'xhigh', 'max']).optional(),
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Task budget for agentic turns. Informs the model of the total token budget
|
|
204
|
+
* available for the current task, allowing it to prioritize work and wind down
|
|
205
|
+
* gracefully as the budget is consumed.
|
|
206
|
+
*
|
|
207
|
+
* Advisory only — does not enforce a hard token limit.
|
|
208
|
+
*/
|
|
209
|
+
taskBudget: z
|
|
210
|
+
.object({
|
|
211
|
+
type: z.literal('tokens'),
|
|
212
|
+
total: z.number().int().min(20000),
|
|
213
|
+
remaining: z.number().int().min(0).optional(),
|
|
214
|
+
})
|
|
215
|
+
.optional(),
|
|
169
216
|
|
|
170
217
|
/**
|
|
171
218
|
* Enable fast mode for faster inference (2.5x faster output token speeds).
|
|
@@ -173,6 +220,16 @@ export const anthropicLanguageModelOptions = z.object({
|
|
|
173
220
|
*/
|
|
174
221
|
speed: z.enum(['fast', 'standard']).optional(),
|
|
175
222
|
|
|
223
|
+
/**
|
|
224
|
+
* Controls where model inference runs for this request.
|
|
225
|
+
*
|
|
226
|
+
* - `"global"`: Inference may run in any available geography (default).
|
|
227
|
+
* - `"us"`: Inference runs only in US-based infrastructure.
|
|
228
|
+
*
|
|
229
|
+
* See https://platform.claude.com/docs/en/build-with-claude/data-residency
|
|
230
|
+
*/
|
|
231
|
+
inferenceGeo: z.enum(['us', 'global']).optional(),
|
|
232
|
+
|
|
176
233
|
/**
|
|
177
234
|
* A set of beta features to enable.
|
|
178
235
|
* Allow a provider to receive the full `betas` set if it needs it.
|
|
@@ -26,6 +26,8 @@ export async function prepareTools({
|
|
|
26
26
|
disableParallelToolUse,
|
|
27
27
|
cacheControlValidator,
|
|
28
28
|
supportsStructuredOutput,
|
|
29
|
+
supportsStrictTools,
|
|
30
|
+
defaultEagerInputStreaming = false,
|
|
29
31
|
}: {
|
|
30
32
|
tools: LanguageModelV4CallOptions['tools'];
|
|
31
33
|
toolChoice: LanguageModelV4CallOptions['toolChoice'] | undefined;
|
|
@@ -33,9 +35,20 @@ export async function prepareTools({
|
|
|
33
35
|
cacheControlValidator?: CacheControlValidator;
|
|
34
36
|
|
|
35
37
|
/**
|
|
36
|
-
* Whether the model supports structured output.
|
|
38
|
+
* Whether the model supports native structured output response format.
|
|
37
39
|
*/
|
|
38
40
|
supportsStructuredOutput: boolean;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Whether the model supports strict mode on tool definitions.
|
|
44
|
+
*/
|
|
45
|
+
supportsStrictTools: boolean;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Default for `eager_input_streaming` on function tools that do not set
|
|
49
|
+
* it explicitly. Driven by the model-level `toolStreaming` option.
|
|
50
|
+
*/
|
|
51
|
+
defaultEagerInputStreaming?: boolean;
|
|
39
52
|
}): Promise<{
|
|
40
53
|
tools: Array<AnthropicTool> | undefined;
|
|
41
54
|
toolChoice: AnthropicToolChoice | undefined;
|
|
@@ -67,18 +80,28 @@ export async function prepareTools({
|
|
|
67
80
|
const anthropicOptions = tool.providerOptions?.anthropic as
|
|
68
81
|
| AnthropicToolOptions
|
|
69
82
|
| undefined;
|
|
70
|
-
// eager_input_streaming is only supported on custom (function) tools
|
|
71
|
-
|
|
83
|
+
// eager_input_streaming is only supported on custom (function) tools.
|
|
84
|
+
// Fall back to the model-level default when the tool doesn't set it.
|
|
85
|
+
const eagerInputStreaming =
|
|
86
|
+
anthropicOptions?.eagerInputStreaming ?? defaultEagerInputStreaming;
|
|
72
87
|
const deferLoading = anthropicOptions?.deferLoading;
|
|
73
88
|
const allowedCallers = anthropicOptions?.allowedCallers;
|
|
74
89
|
|
|
90
|
+
if (!supportsStrictTools && tool.strict != null) {
|
|
91
|
+
toolWarnings.push({
|
|
92
|
+
type: 'unsupported',
|
|
93
|
+
feature: 'strict',
|
|
94
|
+
details: `Tool '${tool.name}' has strict: ${tool.strict}, but strict mode is not supported by this provider. The strict property will be ignored.`,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
75
98
|
anthropicTools.push({
|
|
76
99
|
name: tool.name,
|
|
77
100
|
description: tool.description,
|
|
78
101
|
input_schema: tool.inputSchema,
|
|
79
102
|
cache_control: cacheControl,
|
|
80
103
|
...(eagerInputStreaming ? { eager_input_streaming: true } : {}),
|
|
81
|
-
...(
|
|
104
|
+
...(supportsStrictTools === true && tool.strict != null
|
|
82
105
|
? { strict: tool.strict }
|
|
83
106
|
: {}),
|
|
84
107
|
...(deferLoading != null ? { defer_loading: deferLoading } : {}),
|
|
@@ -308,7 +331,6 @@ export async function prepareTools({
|
|
|
308
331
|
}
|
|
309
332
|
|
|
310
333
|
case 'anthropic.tool_search_regex_20251119': {
|
|
311
|
-
betas.add('advanced-tool-use-2025-11-20');
|
|
312
334
|
anthropicTools.push({
|
|
313
335
|
type: 'tool_search_tool_regex_20251119',
|
|
314
336
|
name: 'tool_search_tool_regex',
|
|
@@ -317,7 +339,6 @@ export async function prepareTools({
|
|
|
317
339
|
}
|
|
318
340
|
|
|
319
341
|
case 'anthropic.tool_search_bm25_20251119': {
|
|
320
|
-
betas.add('advanced-tool-use-2025-11-20');
|
|
321
342
|
anthropicTools.push({
|
|
322
343
|
type: 'tool_search_tool_bm25_20251119',
|
|
323
344
|
name: 'tool_search_tool_bm25',
|