@core-ai/anthropic 0.16.0 → 0.18.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 +176 -22
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -2,18 +2,181 @@
|
|
|
2
2
|
import Anthropic from "@anthropic-ai/sdk";
|
|
3
3
|
|
|
4
4
|
// src/chat-adapter.ts
|
|
5
|
-
import { APIError, APIUserAbortError } from "@anthropic-ai/sdk";
|
|
6
5
|
import {
|
|
7
|
-
AbortedError,
|
|
8
6
|
asObject,
|
|
9
7
|
clampReasoningEffort,
|
|
10
8
|
getProviderMetadata,
|
|
11
|
-
ProviderError,
|
|
12
9
|
ValidationError,
|
|
13
10
|
safeParseJsonObject,
|
|
14
11
|
zodSchemaToJsonSchema
|
|
15
12
|
} from "@core-ai/core-ai";
|
|
16
13
|
|
|
14
|
+
// src/anthropic-error.ts
|
|
15
|
+
import { APIError, APIUserAbortError } from "@anthropic-ai/sdk";
|
|
16
|
+
import {
|
|
17
|
+
AbortedError,
|
|
18
|
+
ContextLengthExceededError,
|
|
19
|
+
ModelOverloadedError,
|
|
20
|
+
ProviderError,
|
|
21
|
+
RateLimitError,
|
|
22
|
+
ServiceUnavailableError,
|
|
23
|
+
asRecord,
|
|
24
|
+
getErrorMessage,
|
|
25
|
+
getHttpStatusCode,
|
|
26
|
+
getRetryAfterSecondsFromError,
|
|
27
|
+
getString,
|
|
28
|
+
isAbortErrorByName,
|
|
29
|
+
isRateLimitStatus,
|
|
30
|
+
isTransientUnavailableStatus
|
|
31
|
+
} from "@core-ai/core-ai";
|
|
32
|
+
var OVERLOAD_MESSAGE_ELIGIBLE_STATUS_CODES = /* @__PURE__ */ new Set([
|
|
33
|
+
500,
|
|
34
|
+
502,
|
|
35
|
+
503,
|
|
36
|
+
504,
|
|
37
|
+
529
|
|
38
|
+
]);
|
|
39
|
+
function wrapAnthropicError(error, provider = "anthropic") {
|
|
40
|
+
if (isAnthropicAbortError(error)) {
|
|
41
|
+
return new AbortedError(error, provider);
|
|
42
|
+
}
|
|
43
|
+
const message = getErrorMessage(error);
|
|
44
|
+
const statusCode = error instanceof APIError ? error.status : getHttpStatusCode(error, ["status"]);
|
|
45
|
+
const providerMessage = getAnthropicErrorMessage(error);
|
|
46
|
+
const errorType = getAnthropicErrorType(error);
|
|
47
|
+
const options = { statusCode, cause: error };
|
|
48
|
+
const contextLength = getContextLengthDetails(providerMessage, errorType);
|
|
49
|
+
if (contextLength) {
|
|
50
|
+
return new ContextLengthExceededError(message, provider, {
|
|
51
|
+
...options,
|
|
52
|
+
...contextLength
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
if (isAnthropicOverloaded(errorType, providerMessage, message, statusCode)) {
|
|
56
|
+
return new ModelOverloadedError(message, provider, options);
|
|
57
|
+
}
|
|
58
|
+
if (isAnthropicRateLimit(error, statusCode, errorType)) {
|
|
59
|
+
return new RateLimitError(message, provider, {
|
|
60
|
+
...options,
|
|
61
|
+
retryAfterSeconds: getRetryAfterSecondsFromError(error)
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
if (isUnavailableStatus(error) || isTransientUnavailableStatus(statusCode)) {
|
|
65
|
+
return new ServiceUnavailableError(message, provider, options);
|
|
66
|
+
}
|
|
67
|
+
return new ProviderError(message, provider, options);
|
|
68
|
+
}
|
|
69
|
+
function isAnthropicAbortError(error) {
|
|
70
|
+
return error instanceof APIUserAbortError || isAbortErrorByName(error);
|
|
71
|
+
}
|
|
72
|
+
function isAnthropicOverloaded(errorType, providerMessage, message, statusCode) {
|
|
73
|
+
return statusCode === 529 || errorType === "overloaded_error" || indicatesAnthropicOverload(
|
|
74
|
+
`${providerMessage ?? ""} ${message}`,
|
|
75
|
+
statusCode
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
function indicatesAnthropicOverload(text, statusCode) {
|
|
79
|
+
if (statusCode !== void 0 && !OVERLOAD_MESSAGE_ELIGIBLE_STATUS_CODES.has(statusCode)) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
return /\boverloaded\b/i.test(text);
|
|
83
|
+
}
|
|
84
|
+
function isAnthropicRateLimit(error, statusCode, errorType) {
|
|
85
|
+
return isRateLimitStatus(statusCode) || errorType === "rate_limit_error" || isResourceExhaustedError(error);
|
|
86
|
+
}
|
|
87
|
+
function getContextLengthDetails(providerMessage, errorType) {
|
|
88
|
+
if (errorType === "rate_limit_error" || !providerMessage) {
|
|
89
|
+
return void 0;
|
|
90
|
+
}
|
|
91
|
+
if (!/prompt is too long/i.test(providerMessage)) {
|
|
92
|
+
const inputTokensMatch = providerMessage.match(
|
|
93
|
+
/Input tokens exceed the context limit of (\d+)/i
|
|
94
|
+
);
|
|
95
|
+
if (inputTokensMatch?.[1]) {
|
|
96
|
+
return { maxTokens: parseInt(inputTokensMatch[1], 10) };
|
|
97
|
+
}
|
|
98
|
+
return void 0;
|
|
99
|
+
}
|
|
100
|
+
const withMaximum = providerMessage.match(
|
|
101
|
+
/prompt is too long: (\d+) tokens > (\d+) maximum/i
|
|
102
|
+
);
|
|
103
|
+
if (withMaximum) {
|
|
104
|
+
const actualTokens = withMaximum[1];
|
|
105
|
+
const maxTokens = withMaximum[2];
|
|
106
|
+
if (actualTokens !== void 0 && maxTokens !== void 0) {
|
|
107
|
+
return {
|
|
108
|
+
maxTokens: parseInt(maxTokens, 10),
|
|
109
|
+
actualTokens: parseInt(actualTokens, 10)
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
const withoutMaximum = providerMessage.match(
|
|
114
|
+
/prompt is too long: (\d+) tokens > (\d+)/i
|
|
115
|
+
);
|
|
116
|
+
if (withoutMaximum) {
|
|
117
|
+
const actualTokens = withoutMaximum[1];
|
|
118
|
+
const maxTokens = withoutMaximum[2];
|
|
119
|
+
if (actualTokens !== void 0 && maxTokens !== void 0) {
|
|
120
|
+
return {
|
|
121
|
+
maxTokens: parseInt(maxTokens, 10),
|
|
122
|
+
actualTokens: parseInt(actualTokens, 10)
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return {};
|
|
127
|
+
}
|
|
128
|
+
function isResourceExhaustedError(error) {
|
|
129
|
+
const body = getNestedGoogleApiErrorBody(error);
|
|
130
|
+
if (!body) {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
const code = typeof body.code === "number" ? body.code : Number(body.code);
|
|
134
|
+
return code === 429 || body.status?.toUpperCase() === "RESOURCE_EXHAUSTED";
|
|
135
|
+
}
|
|
136
|
+
function isUnavailableStatus(error) {
|
|
137
|
+
const body = getNestedGoogleApiErrorBody(error);
|
|
138
|
+
return body?.status?.toUpperCase() === "UNAVAILABLE";
|
|
139
|
+
}
|
|
140
|
+
function getNestedGoogleApiErrorBody(error) {
|
|
141
|
+
const record = asRecord(error);
|
|
142
|
+
const outer = asRecord(record?.error);
|
|
143
|
+
if (!outer) {
|
|
144
|
+
return void 0;
|
|
145
|
+
}
|
|
146
|
+
const inner = asRecord(outer.error);
|
|
147
|
+
if (inner && ("code" in inner || "status" in inner)) {
|
|
148
|
+
return inner;
|
|
149
|
+
}
|
|
150
|
+
if ("code" in outer || "status" in outer) {
|
|
151
|
+
return outer;
|
|
152
|
+
}
|
|
153
|
+
return void 0;
|
|
154
|
+
}
|
|
155
|
+
function getAnthropicErrorMessage(error) {
|
|
156
|
+
if (error instanceof APIError) {
|
|
157
|
+
const nested = asRecord(error.error);
|
|
158
|
+
return getString(nested, "message") ?? error.message;
|
|
159
|
+
}
|
|
160
|
+
const record = asRecord(error);
|
|
161
|
+
const outer = asRecord(record?.error);
|
|
162
|
+
const inner = asRecord(outer?.error);
|
|
163
|
+
return getString(inner, "message") ?? getString(outer, "message") ?? getString(record, "message");
|
|
164
|
+
}
|
|
165
|
+
function getAnthropicErrorType(error) {
|
|
166
|
+
if (error instanceof APIError) {
|
|
167
|
+
if (typeof error.type === "string") {
|
|
168
|
+
return error.type;
|
|
169
|
+
}
|
|
170
|
+
if (typeof error.error === "object" && error.error) {
|
|
171
|
+
return getString(asRecord(error.error), "type");
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
const record = asRecord(error);
|
|
175
|
+
const outer = asRecord(record?.error);
|
|
176
|
+
const inner = asRecord(outer?.error);
|
|
177
|
+
return getString(inner, "type") ?? getString(outer, "type");
|
|
178
|
+
}
|
|
179
|
+
|
|
17
180
|
// src/model-capabilities.ts
|
|
18
181
|
import {
|
|
19
182
|
stripModelDateSuffix
|
|
@@ -34,9 +197,10 @@ var MAX_EFFORTS = [
|
|
|
34
197
|
function createCapabilities(supportedEfforts) {
|
|
35
198
|
return {
|
|
36
199
|
reasoning: {
|
|
37
|
-
|
|
200
|
+
mode: "optional",
|
|
38
201
|
supportedEfforts,
|
|
39
|
-
restrictsSamplingParams: true
|
|
202
|
+
restrictsSamplingParams: true,
|
|
203
|
+
supportedToolChoices: ["auto", "none"]
|
|
40
204
|
}
|
|
41
205
|
};
|
|
42
206
|
}
|
|
@@ -46,6 +210,7 @@ var ADAPTIVE_MAX_EFFORT_MODELS = /* @__PURE__ */ new Set([
|
|
|
46
210
|
"claude-fable-5",
|
|
47
211
|
"claude-mythos-5",
|
|
48
212
|
"claude-mythos-preview",
|
|
213
|
+
"claude-opus-5",
|
|
49
214
|
"claude-opus-4-8",
|
|
50
215
|
"claude-opus-4-7",
|
|
51
216
|
"claude-opus-4-6",
|
|
@@ -72,6 +237,7 @@ var ALWAYS_RESTRICTED_SAMPLING_MODELS = /* @__PURE__ */ new Set([
|
|
|
72
237
|
"claude-fable-5",
|
|
73
238
|
"claude-mythos-5",
|
|
74
239
|
"claude-mythos-preview",
|
|
240
|
+
"claude-opus-5",
|
|
75
241
|
"claude-opus-4-8",
|
|
76
242
|
"claude-opus-4-7",
|
|
77
243
|
"claude-sonnet-5"
|
|
@@ -477,6 +643,7 @@ function validateAnthropicReasoningConfig(modelId, maxTokens, options, anthropic
|
|
|
477
643
|
provider
|
|
478
644
|
);
|
|
479
645
|
}
|
|
646
|
+
const capabilities = getAnthropicModelCapabilities(modelId);
|
|
480
647
|
if (options.temperature !== void 0 && (!alwaysRestrictsSampling || options.temperature !== 1)) {
|
|
481
648
|
throw new ValidationError(
|
|
482
649
|
`Anthropic model "${modelId}" does not support temperature when reasoning is enabled`,
|
|
@@ -491,9 +658,10 @@ function validateAnthropicReasoningConfig(modelId, maxTokens, options, anthropic
|
|
|
491
658
|
provider
|
|
492
659
|
);
|
|
493
660
|
}
|
|
494
|
-
|
|
661
|
+
const toolChoiceMode = typeof options.toolChoice === "object" ? options.toolChoice.type : options.toolChoice;
|
|
662
|
+
if (toolChoiceMode !== void 0 && !capabilities.reasoning.supportedToolChoices.includes(toolChoiceMode)) {
|
|
495
663
|
throw new ValidationError(
|
|
496
|
-
`Anthropic model "${modelId}"
|
|
664
|
+
`Anthropic model "${modelId}" does not support toolChoice "${toolChoiceMode}" when reasoning is enabled`,
|
|
497
665
|
void 0,
|
|
498
666
|
provider
|
|
499
667
|
);
|
|
@@ -840,20 +1008,6 @@ function extractThinkingText(value) {
|
|
|
840
1008
|
return typeof text === "string" ? [text] : [];
|
|
841
1009
|
}).join("");
|
|
842
1010
|
}
|
|
843
|
-
function wrapError(error, provider = DEFAULT_PROVIDER_ID) {
|
|
844
|
-
if (error instanceof APIUserAbortError || error instanceof Error && error.name === "AbortError") {
|
|
845
|
-
return new AbortedError(error, provider);
|
|
846
|
-
}
|
|
847
|
-
if (error instanceof APIError) {
|
|
848
|
-
return new ProviderError(error.message, provider, error.status, error);
|
|
849
|
-
}
|
|
850
|
-
return new ProviderError(
|
|
851
|
-
error instanceof Error ? error.message : String(error),
|
|
852
|
-
provider,
|
|
853
|
-
void 0,
|
|
854
|
-
error
|
|
855
|
-
);
|
|
856
|
-
}
|
|
857
1011
|
|
|
858
1012
|
// src/chat-model.ts
|
|
859
1013
|
import {
|
|
@@ -878,7 +1032,7 @@ function createAnthropicChatModel(client, modelId, modelOptions = {}) {
|
|
|
878
1032
|
signal
|
|
879
1033
|
});
|
|
880
1034
|
} catch (error) {
|
|
881
|
-
throw
|
|
1035
|
+
throw wrapAnthropicError(error, provider);
|
|
882
1036
|
}
|
|
883
1037
|
}
|
|
884
1038
|
async function generateChat(options) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@core-ai/anthropic",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "Anthropic provider package for @core-ai/core-ai",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Omnifact (https://omnifact.ai)",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@anthropic-ai/sdk": "^0.110.0",
|
|
48
|
-
"@core-ai/core-ai": "^0.
|
|
48
|
+
"@core-ai/core-ai": "^0.18.0"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
51
|
"zod": "^4.0.0"
|