@core-ai/anthropic 0.13.0 → 0.14.0
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/dist/index.js +138 -39
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -15,6 +15,7 @@ import { APIError, APIUserAbortError } from "@anthropic-ai/sdk";
|
|
|
15
15
|
import {
|
|
16
16
|
AbortedError,
|
|
17
17
|
asObject,
|
|
18
|
+
clampReasoningEffort,
|
|
18
19
|
getProviderMetadata,
|
|
19
20
|
ProviderError,
|
|
20
21
|
ValidationError,
|
|
@@ -69,6 +70,21 @@ var MANUAL_THINKING_MODELS = /* @__PURE__ */ new Set([
|
|
|
69
70
|
"claude-haiku-4-5",
|
|
70
71
|
"claude-sonnet-3-7"
|
|
71
72
|
]);
|
|
73
|
+
var MANUAL_INTERLEAVED_THINKING_MODELS = /* @__PURE__ */ new Set([
|
|
74
|
+
"claude-opus-4-5",
|
|
75
|
+
"claude-sonnet-4-5",
|
|
76
|
+
"claude-opus-4-1",
|
|
77
|
+
"claude-opus-4",
|
|
78
|
+
"claude-sonnet-4"
|
|
79
|
+
]);
|
|
80
|
+
var ALWAYS_RESTRICTED_SAMPLING_MODELS = /* @__PURE__ */ new Set([
|
|
81
|
+
"claude-fable-5",
|
|
82
|
+
"claude-mythos-5",
|
|
83
|
+
"claude-mythos-preview",
|
|
84
|
+
"claude-opus-4-8",
|
|
85
|
+
"claude-opus-4-7",
|
|
86
|
+
"claude-sonnet-5"
|
|
87
|
+
]);
|
|
72
88
|
var ANTHROPIC_ADAPTIVE_EFFORT_MAP = {
|
|
73
89
|
minimal: "low",
|
|
74
90
|
low: "low",
|
|
@@ -97,14 +113,21 @@ function getAnthropicThinkingMode(modelId) {
|
|
|
97
113
|
function supportsAnthropicMaxEffort(modelId) {
|
|
98
114
|
return ADAPTIVE_MAX_EFFORT_MODELS.has(normalizeModelId(modelId));
|
|
99
115
|
}
|
|
116
|
+
function requiresAnthropicInterleavedThinkingBeta(modelId) {
|
|
117
|
+
return MANUAL_INTERLEAVED_THINKING_MODELS.has(normalizeModelId(modelId));
|
|
118
|
+
}
|
|
119
|
+
function restrictsAnthropicSamplingParamsAlways(modelId) {
|
|
120
|
+
return ALWAYS_RESTRICTED_SAMPLING_MODELS.has(normalizeModelId(modelId));
|
|
121
|
+
}
|
|
100
122
|
function toAnthropicAdaptiveEffort(effort, supportsMaxEffort) {
|
|
101
123
|
if (effort === "max") {
|
|
102
124
|
return supportsMaxEffort ? "max" : "high";
|
|
103
125
|
}
|
|
104
126
|
return ANTHROPIC_ADAPTIVE_EFFORT_MAP[effort];
|
|
105
127
|
}
|
|
106
|
-
function toAnthropicManualBudget(effort) {
|
|
107
|
-
|
|
128
|
+
function toAnthropicManualBudget(effort, maxTokens) {
|
|
129
|
+
const targetBudget = ANTHROPIC_MANUAL_BUDGET_MAP[effort];
|
|
130
|
+
return maxTokens === void 0 ? targetBudget : Math.min(targetBudget, maxTokens - 1);
|
|
108
131
|
}
|
|
109
132
|
|
|
110
133
|
// src/provider-options.ts
|
|
@@ -198,18 +221,17 @@ function convertMessages(messages) {
|
|
|
198
221
|
});
|
|
199
222
|
continue;
|
|
200
223
|
}
|
|
201
|
-
if (
|
|
224
|
+
if (typeof signature === "string") {
|
|
225
|
+
contentBlocks.push({
|
|
226
|
+
type: "thinking",
|
|
227
|
+
thinking: part.text,
|
|
228
|
+
signature
|
|
229
|
+
});
|
|
202
230
|
continue;
|
|
203
231
|
}
|
|
204
|
-
if (
|
|
232
|
+
if (part.text.length > 0) {
|
|
205
233
|
contentBlocks.push({ type: "text", text: part.text });
|
|
206
|
-
continue;
|
|
207
234
|
}
|
|
208
|
-
contentBlocks.push({
|
|
209
|
-
type: "thinking",
|
|
210
|
-
thinking: part.text,
|
|
211
|
-
signature
|
|
212
|
-
});
|
|
213
235
|
}
|
|
214
236
|
convertedMessages.push({
|
|
215
237
|
role: "assistant",
|
|
@@ -395,13 +417,23 @@ function createStreamRequest(modelId, defaultMaxTokens, options) {
|
|
|
395
417
|
return mapAnthropicProviderOptionsToRequest(baseRequest, anthropicOptions);
|
|
396
418
|
}
|
|
397
419
|
function createRequestBase(modelId, defaultMaxTokens, options, anthropicOptions) {
|
|
398
|
-
|
|
420
|
+
const maxTokens = options.maxTokens ?? defaultMaxTokens;
|
|
421
|
+
validateAnthropicReasoningConfig(
|
|
422
|
+
modelId,
|
|
423
|
+
maxTokens,
|
|
424
|
+
options,
|
|
425
|
+
anthropicOptions
|
|
426
|
+
);
|
|
399
427
|
const converted = convertMessages(options.messages);
|
|
400
|
-
const reasoningFields = mapReasoningToRequestFields(
|
|
428
|
+
const reasoningFields = mapReasoningToRequestFields(
|
|
429
|
+
modelId,
|
|
430
|
+
maxTokens,
|
|
431
|
+
options
|
|
432
|
+
);
|
|
401
433
|
return {
|
|
402
434
|
model: modelId,
|
|
403
435
|
messages: converted.messages,
|
|
404
|
-
max_tokens:
|
|
436
|
+
max_tokens: maxTokens,
|
|
405
437
|
...converted.system ? { system: converted.system } : {},
|
|
406
438
|
...options.tools && Object.keys(options.tools).length > 0 ? { tools: convertTools(options.tools) } : {},
|
|
407
439
|
...options.toolChoice ? { tool_choice: convertToolChoice(options.toolChoice) } : {},
|
|
@@ -415,11 +447,40 @@ function mapSamplingToRequestFields(options) {
|
|
|
415
447
|
...options.topP !== void 0 ? { top_p: options.topP } : {}
|
|
416
448
|
};
|
|
417
449
|
}
|
|
418
|
-
function validateAnthropicReasoningConfig(modelId, options, anthropicOptions) {
|
|
450
|
+
function validateAnthropicReasoningConfig(modelId, maxTokens, options, anthropicOptions) {
|
|
451
|
+
const alwaysRestrictsSampling = restrictsAnthropicSamplingParamsAlways(modelId);
|
|
452
|
+
if (alwaysRestrictsSampling && options.temperature !== void 0 && options.temperature !== 1) {
|
|
453
|
+
throw new ValidationError(
|
|
454
|
+
`Anthropic model "${modelId}" only supports the default temperature of 1`,
|
|
455
|
+
void 0,
|
|
456
|
+
"anthropic"
|
|
457
|
+
);
|
|
458
|
+
}
|
|
459
|
+
if (alwaysRestrictsSampling && options.topP !== void 0 && options.topP !== 1) {
|
|
460
|
+
throw new ValidationError(
|
|
461
|
+
`Anthropic model "${modelId}" only supports the default topP of 1`,
|
|
462
|
+
void 0,
|
|
463
|
+
"anthropic"
|
|
464
|
+
);
|
|
465
|
+
}
|
|
466
|
+
if (alwaysRestrictsSampling && anthropicOptions?.topK !== void 0) {
|
|
467
|
+
throw new ValidationError(
|
|
468
|
+
`Anthropic model "${modelId}" does not support top_k`,
|
|
469
|
+
void 0,
|
|
470
|
+
"anthropic"
|
|
471
|
+
);
|
|
472
|
+
}
|
|
419
473
|
if (!options.reasoning) {
|
|
420
474
|
return;
|
|
421
475
|
}
|
|
422
|
-
if (
|
|
476
|
+
if (getAnthropicThinkingMode(modelId) === "manual" && maxTokens <= 1024) {
|
|
477
|
+
throw new ValidationError(
|
|
478
|
+
`Anthropic model "${modelId}" requires maxTokens greater than 1024 when reasoning is enabled`,
|
|
479
|
+
void 0,
|
|
480
|
+
"anthropic"
|
|
481
|
+
);
|
|
482
|
+
}
|
|
483
|
+
if (options.temperature !== void 0 && (!alwaysRestrictsSampling || options.temperature !== 1)) {
|
|
423
484
|
throw new ValidationError(
|
|
424
485
|
`Anthropic model "${modelId}" does not support temperature when reasoning is enabled`,
|
|
425
486
|
void 0,
|
|
@@ -448,20 +509,25 @@ function validateAnthropicReasoningConfig(modelId, options, anthropicOptions) {
|
|
|
448
509
|
);
|
|
449
510
|
}
|
|
450
511
|
}
|
|
451
|
-
function mapReasoningToRequestFields(modelId, options) {
|
|
512
|
+
function mapReasoningToRequestFields(modelId, maxTokens, options) {
|
|
452
513
|
if (!options.reasoning) {
|
|
453
514
|
return {};
|
|
454
515
|
}
|
|
455
516
|
const thinkingMode = getAnthropicThinkingMode(modelId);
|
|
517
|
+
const capabilities = getAnthropicModelCapabilities(modelId);
|
|
518
|
+
const effort = clampReasoningEffort(
|
|
519
|
+
options.reasoning.effort,
|
|
520
|
+
capabilities.reasoning.supportedEfforts
|
|
521
|
+
);
|
|
456
522
|
const baseFields = {};
|
|
457
|
-
if (options.tools && Object.keys(options.tools).length > 0) {
|
|
458
|
-
baseFields["betas"] = ["interleaved-thinking-2025-05-14"];
|
|
459
|
-
}
|
|
460
523
|
if (thinkingMode === "adaptive") {
|
|
461
|
-
baseFields["thinking"] = {
|
|
524
|
+
baseFields["thinking"] = {
|
|
525
|
+
type: "adaptive",
|
|
526
|
+
display: "summarized"
|
|
527
|
+
};
|
|
462
528
|
baseFields["output_config"] = {
|
|
463
529
|
effort: toAnthropicAdaptiveEffort(
|
|
464
|
-
|
|
530
|
+
effort,
|
|
465
531
|
supportsAnthropicMaxEffort(modelId)
|
|
466
532
|
)
|
|
467
533
|
};
|
|
@@ -469,10 +535,22 @@ function mapReasoningToRequestFields(modelId, options) {
|
|
|
469
535
|
}
|
|
470
536
|
baseFields["thinking"] = {
|
|
471
537
|
type: "enabled",
|
|
472
|
-
budget_tokens: toAnthropicManualBudget(
|
|
538
|
+
budget_tokens: toAnthropicManualBudget(effort, maxTokens),
|
|
539
|
+
display: "summarized"
|
|
473
540
|
};
|
|
474
541
|
return baseFields;
|
|
475
542
|
}
|
|
543
|
+
function getAnthropicRequestBetas(modelId, options) {
|
|
544
|
+
const providerOptions = parseAnthropicGenerateProviderOptions(
|
|
545
|
+
options.providerOptions
|
|
546
|
+
);
|
|
547
|
+
const configuredBetas = providerOptions?.betas ?? [];
|
|
548
|
+
const shouldEnableInterleavedThinking = options.reasoning !== void 0 && options.tools !== void 0 && Object.keys(options.tools).length > 0 && requiresAnthropicInterleavedThinkingBeta(modelId);
|
|
549
|
+
return uniqueStrings([
|
|
550
|
+
...configuredBetas,
|
|
551
|
+
...shouldEnableInterleavedThinking ? ["interleaved-thinking-2025-05-14"] : []
|
|
552
|
+
]);
|
|
553
|
+
}
|
|
476
554
|
function mapAnthropicProviderOptionsToRequest(baseRequest, providerOptions) {
|
|
477
555
|
if (!providerOptions) {
|
|
478
556
|
return baseRequest;
|
|
@@ -484,17 +562,12 @@ function mapAnthropicProviderOptionsToRequest(baseRequest, providerOptions) {
|
|
|
484
562
|
...baseOutputConfig,
|
|
485
563
|
...providerOptions.outputConfig ?? {}
|
|
486
564
|
};
|
|
487
|
-
const mergedBetas = [
|
|
488
|
-
...asStringArray(baseRequest.betas),
|
|
489
|
-
...providerOptions.betas ?? []
|
|
490
|
-
];
|
|
491
565
|
const mergedRequest = {
|
|
492
566
|
...baseRequest,
|
|
493
567
|
...providerOptions.cacheControl ? { cache_control: providerOptions.cacheControl } : {},
|
|
494
568
|
...providerOptions.topK !== void 0 ? { top_k: providerOptions.topK } : {},
|
|
495
569
|
...providerOptions.stopSequences ? { stop_sequences: providerOptions.stopSequences } : {},
|
|
496
|
-
...Object.keys(mergedOutputConfig).length > 0 ? { output_config: mergedOutputConfig } : {}
|
|
497
|
-
...mergedBetas.length > 0 ? { betas: uniqueStrings(mergedBetas) } : {}
|
|
570
|
+
...Object.keys(mergedOutputConfig).length > 0 ? { output_config: mergedOutputConfig } : {}
|
|
498
571
|
};
|
|
499
572
|
return mergedRequest;
|
|
500
573
|
}
|
|
@@ -563,7 +636,7 @@ function mapGenerateResponse(response) {
|
|
|
563
636
|
cacheReadTokens,
|
|
564
637
|
cacheWriteTokens
|
|
565
638
|
},
|
|
566
|
-
outputTokenDetails:
|
|
639
|
+
outputTokenDetails: mapAnthropicOutputTokenDetails(response.usage)
|
|
567
640
|
}
|
|
568
641
|
};
|
|
569
642
|
}
|
|
@@ -594,7 +667,9 @@ async function* transformStream(stream) {
|
|
|
594
667
|
cacheReadTokens,
|
|
595
668
|
cacheWriteTokens
|
|
596
669
|
},
|
|
597
|
-
outputTokenDetails:
|
|
670
|
+
outputTokenDetails: mapAnthropicOutputTokenDetails(
|
|
671
|
+
event.message.usage
|
|
672
|
+
)
|
|
598
673
|
};
|
|
599
674
|
continue;
|
|
600
675
|
}
|
|
@@ -606,6 +681,12 @@ async function* transformStream(stream) {
|
|
|
606
681
|
};
|
|
607
682
|
continue;
|
|
608
683
|
}
|
|
684
|
+
if (event.content_block.type === "text") {
|
|
685
|
+
yield {
|
|
686
|
+
type: "text-start"
|
|
687
|
+
};
|
|
688
|
+
continue;
|
|
689
|
+
}
|
|
609
690
|
if (event.content_block.type === "tool_use") {
|
|
610
691
|
const block = event.content_block;
|
|
611
692
|
const initialArguments = block.input && typeof block.input === "object" ? Object.keys(block.input).length > 0 ? JSON.stringify(block.input) : "" : "";
|
|
@@ -663,6 +744,13 @@ async function* transformStream(stream) {
|
|
|
663
744
|
continue;
|
|
664
745
|
}
|
|
665
746
|
if (event.type === "content_block_stop") {
|
|
747
|
+
if (contentBlockTypeByIndex.get(event.index) === "text") {
|
|
748
|
+
contentBlockTypeByIndex.delete(event.index);
|
|
749
|
+
yield {
|
|
750
|
+
type: "text-end"
|
|
751
|
+
};
|
|
752
|
+
continue;
|
|
753
|
+
}
|
|
666
754
|
if (contentBlockTypeByIndex.get(event.index) === "thinking") {
|
|
667
755
|
const signature = reasoningSignatureByIndex.get(event.index);
|
|
668
756
|
reasoningSignatureByIndex.delete(event.index);
|
|
@@ -703,7 +791,10 @@ async function* transformStream(stream) {
|
|
|
703
791
|
cacheReadTokens,
|
|
704
792
|
cacheWriteTokens
|
|
705
793
|
},
|
|
706
|
-
outputTokenDetails: {
|
|
794
|
+
outputTokenDetails: {
|
|
795
|
+
...usage.outputTokenDetails,
|
|
796
|
+
...mapAnthropicOutputTokenDetails(event.usage)
|
|
797
|
+
}
|
|
707
798
|
};
|
|
708
799
|
continue;
|
|
709
800
|
}
|
|
@@ -729,11 +820,10 @@ function mapStopReason(reason) {
|
|
|
729
820
|
}
|
|
730
821
|
return "unknown";
|
|
731
822
|
}
|
|
732
|
-
function
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
}
|
|
736
|
-
return value.filter((item) => typeof item === "string");
|
|
823
|
+
function mapAnthropicOutputTokenDetails(usage) {
|
|
824
|
+
const outputTokenDetails = asObject(asObject(usage).output_tokens_details);
|
|
825
|
+
const reasoningTokens = outputTokenDetails.thinking_tokens;
|
|
826
|
+
return typeof reasoningTokens === "number" ? { reasoningTokens } : {};
|
|
737
827
|
}
|
|
738
828
|
function uniqueStrings(values) {
|
|
739
829
|
return [...new Set(values)];
|
|
@@ -776,9 +866,14 @@ function wrapError(error) {
|
|
|
776
866
|
// src/chat-model.ts
|
|
777
867
|
function createAnthropicChatModel(client, modelId, defaultMaxTokens) {
|
|
778
868
|
const provider = "anthropic";
|
|
779
|
-
async function callAnthropicMessagesApi(request, signal) {
|
|
869
|
+
async function callAnthropicMessagesApi(request, betas, signal) {
|
|
780
870
|
try {
|
|
781
871
|
return await client.messages.create(request, {
|
|
872
|
+
...betas.length > 0 ? {
|
|
873
|
+
headers: {
|
|
874
|
+
"anthropic-beta": betas.join(",")
|
|
875
|
+
}
|
|
876
|
+
} : {},
|
|
782
877
|
signal
|
|
783
878
|
});
|
|
784
879
|
} catch (error) {
|
|
@@ -791,14 +886,18 @@ function createAnthropicChatModel(client, modelId, defaultMaxTokens) {
|
|
|
791
886
|
defaultMaxTokens,
|
|
792
887
|
options
|
|
793
888
|
);
|
|
794
|
-
const response = await callAnthropicMessagesApi(request, options.signal);
|
|
889
|
+
const response = await callAnthropicMessagesApi(request, getAnthropicRequestBetas(modelId, options), options.signal);
|
|
795
890
|
return mapGenerateResponse(response);
|
|
796
891
|
}
|
|
797
892
|
async function streamChat(options) {
|
|
798
893
|
const request = createStreamRequest(modelId, defaultMaxTokens, options);
|
|
799
894
|
return createChatStream(
|
|
800
895
|
async () => transformStream(
|
|
801
|
-
await callAnthropicMessagesApi(
|
|
896
|
+
await callAnthropicMessagesApi(
|
|
897
|
+
request,
|
|
898
|
+
getAnthropicRequestBetas(modelId, options),
|
|
899
|
+
options.signal
|
|
900
|
+
)
|
|
802
901
|
),
|
|
803
902
|
{ signal: options.signal }
|
|
804
903
|
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@core-ai/anthropic",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "Anthropic provider package for @core-ai/core-ai",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Omnifact (https://omnifact.ai)",
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
"test:watch": "vitest"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@
|
|
48
|
-
"@
|
|
47
|
+
"@anthropic-ai/sdk": "^0.110.0",
|
|
48
|
+
"@core-ai/core-ai": "^0.14.0"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
51
|
"zod": "^4.0.0"
|