@openclaw/ai 2026.7.2-beta.7 → 2026.7.34
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/README.md +5 -6
- package/dist/{anthropic-CH4UUnZr.mjs → anthropic-Bcdbq-l5.mjs} +467 -100
- package/dist/{api-registry-DlMgPR39.d.mts → api-registry-BXYnCOIR.d.mts} +2 -1
- package/dist/{azure-openai-responses-CImcwB83.mjs → azure-openai-responses-2xhpNPWg.mjs} +13 -11
- package/dist/{azure-openai-responses-client-compat-C7K7QfUE.mjs → azure-openai-responses-client-compat-a_O_GVQV.mjs} +2 -23
- package/dist/{env-api-keys-DrgeBuva.mjs → env-api-keys-CtMlqaQ4.mjs} +4 -5
- package/dist/{event-stream-YjaPW20U.d.mts → event-stream-0nZeBKl2.d.mts} +1 -1
- package/dist/{event-stream-D8n2uFee.mjs → event-stream-ReMmOTzX.mjs} +6 -14
- package/dist/event-stream.d.mts +1 -1
- package/dist/event-stream.mjs +1 -1
- package/dist/{github-copilot-headers-NCJtz9i0.mjs → github-copilot-headers-BsH5cqGj.mjs} +12 -1
- package/dist/{google-CtSg0iTS.mjs → google-C6P31moq.mjs} +5 -5
- package/dist/{google-shared-DNBz5rcD.mjs → google-shared-BeyXFAcf.mjs} +26 -34
- package/dist/{google-vertex-31f1uS9L.mjs → google-vertex--9_gT74B.mjs} +19 -6
- package/dist/host-4t713IeR.mjs +37 -0
- package/dist/{anthropic-SrGtwsJu.d.mts → index-CGDEoorl.d.mts} +2 -6
- package/dist/index.d.mts +50 -7
- package/dist/index.mjs +5 -5
- package/dist/internal/anthropic.d.mts +61 -21
- package/dist/internal/anthropic.mjs +4 -5
- package/dist/internal/openai.d.mts +89 -98
- package/dist/internal/openai.mjs +6 -8
- package/dist/internal/runtime.d.mts +34 -13
- package/dist/internal/runtime.mjs +14 -26
- package/dist/internal/shared.d.mts +9 -26
- package/dist/internal/shared.mjs +2 -6
- package/dist/{json-parse-BvXNt1-7.mjs → json-parse-DzNSIQBq.mjs} +6 -4
- package/dist/{llm-request-activity-BjtkplhG.mjs → llm-request-activity-CehVkZP-.mjs} +19 -1
- package/dist/{mistral-CWmpvWYh.mjs → mistral-CBm3OQWD.mjs} +39 -141
- package/dist/model-utils-Cn9KAz3z.mjs +69 -0
- package/dist/{openai-chatgpt-responses-B84Ibtrd.mjs → openai-chatgpt-responses-M2RVpycr.mjs} +154 -101
- package/dist/{openai-completions-DsOxhOD1.mjs → openai-completions-BUlMEeBc.mjs} +295 -81
- package/dist/{openai-responses-BT7A3sLu.mjs → openai-responses-DW61C22l.mjs} +9 -14
- package/dist/openai-responses-shared-BhYsVkwW.mjs +1949 -0
- package/dist/{openai-tool-projection-OhX64DoP.mjs → openai-tool-projection-g4HuxD26.mjs} +20 -31
- package/dist/providers.d.mts +2 -3
- package/dist/providers.mjs +10 -11
- package/dist/reasoning-tag-text-partitioner-axhAdUwg.mjs +394 -0
- package/dist/{src-QkygScBs.mjs → src-CjOfhrH3.mjs} +6 -17
- package/dist/{stream-first-event-timeout-BBys9hSb.mjs → stream-first-event-timeout-RjWszj8c.mjs} +22 -2
- package/dist/transform-messages-DoWx35pj.mjs +509 -0
- package/dist/{types-bzp5k29J.d.mts → types-DRgdPqaZ.d.mts} +0 -19
- package/dist/types.d.mts +5 -5
- package/dist/types.mjs +4 -4
- package/dist/{validation-B-j7cOYp.d.mts → validation-BDMWOr8d.d.mts} +1 -1
- package/dist/{validation-DAa_yFOM.mjs → validation-FrchoOlv.mjs} +7 -2
- package/dist/validation.d.mts +1 -1
- package/dist/validation.mjs +1 -1
- package/npm-shrinkwrap.json +645 -0
- package/package.json +11 -36
- package/dist/anthropic-usage-DWU-x8MI.mjs +0 -459
- package/dist/cache-retention-0x979a5V.mjs +0 -12
- package/dist/deferred-event-buffer-DAvyP7qA.mjs +0 -19
- package/dist/error-coercion-DgxlWC0n.mjs +0 -15
- package/dist/host-B9GUmcra.d.mts +0 -173
- package/dist/host-Dog2WQiR.mjs +0 -369
- package/dist/index-BVVgDSdq.d.mts +0 -1
- package/dist/internal/retry-after.d.mts +0 -5
- package/dist/internal/retry-after.mjs +0 -101
- package/dist/number-coercion-DvG7SNMg.mjs +0 -129
- package/dist/openai-completions-compat-DBWjXoMZ.d.mts +0 -43
- package/dist/openai-prompt-cache-2uo_1OR1.d.mts +0 -7
- package/dist/openai-prompt-cache-mZTCdRPo.mjs +0 -12
- package/dist/openai-reasoning-compat-YgeLncHw.mjs +0 -396
- package/dist/openai-responses-shared-pXl6Wd8S.mjs +0 -392
- package/dist/openai-responses-stream-internal-Cw5txaGW.mjs +0 -2964
- package/dist/prompt-cache-stability-Cwcjv_fx.d.mts +0 -13
- package/dist/provider-error-CAEvRjry.mjs +0 -47
- package/dist/provider-options-D8bB3z9b.d.mts +0 -144
- package/dist/reasoning-tag-text-partitioner-CGDyLWUR.mjs +0 -12209
- package/dist/simple-options-9lhRrN73.mjs +0 -50
- package/dist/stream-first-event-timeout-DvDeSucC.d.mts +0 -29
- package/dist/tls-certificate-errors-DXSpluKI.mjs +0 -93
- package/dist/tool-result-text-CTpIRbYd.mjs +0 -225
- package/dist/transform-messages-C8mBqZxF.mjs +0 -2
- package/dist/transport-stream-shared-D81p90xq.mjs +0 -297
- package/dist/transports.d.mts +0 -573
- package/dist/transports.mjs +0 -4110
|
@@ -1,23 +1,331 @@
|
|
|
1
|
-
import { n as getEnvApiKey, r as __exportAll } from "./env-api-keys-
|
|
2
|
-
import { d as resolveClaudeSonnet5ModelIdentity,
|
|
3
|
-
import { t as AssistantMessageEventStream } from "./event-stream-
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { t as
|
|
7
|
-
import { a as isImageWithMediaPayload, d as stripSystemPromptCacheBoundary, n as extractToolResultBlockText, r as extractToolResultText, t as describeToolResultMediaPlaceholder, u as splitSystemPromptCacheBoundary } from "./tool-result-text-CTpIRbYd.mjs";
|
|
8
|
-
import { _ as omitFoundryBearerCredentialHeaders, a as projectAnthropicTools, b as normalizeAnthropicInlineContent, c as ANTHROPIC_OMITTED_REASONING_TEXT, d as ANTHROPIC_SERVER_SIDE_FALLBACK_BETA, g as applyAnthropicRefusal, h as resolveAnthropicFallbackServingModelCost, i as readLastAnthropicIterationUsage, l as findActiveAnthropicToolTurnAssistantIndex, m as readAnthropicFallbackBoundary, n as readAnthropicPromptUsageSnapshot, o as reconcileAnthropicToolChoice, p as applyAnthropicFallbackBoundary, r as readAnthropicUsageTokenCount, s as resolveOriginalAnthropicToolName, t as readAnthropicCacheWriteUsage, u as ANTHROPIC_SERVER_SIDE_FALLBACKS, v as usesFoundryBearerAuth, x as resolveAnthropicImageMediaType, y as createAnthropicInlineImageBudget } from "./anthropic-usage-DWU-x8MI.mjs";
|
|
9
|
-
import { c as calculateCost, l as clampThinkingLevel } from "./number-coercion-DvG7SNMg.mjs";
|
|
10
|
-
import { t as createDeferredEventBuffer } from "./deferred-event-buffer-DAvyP7qA.mjs";
|
|
11
|
-
import { n as parseStreamingJson, t as parseJsonWithRepair } from "./json-parse-BvXNt1-7.mjs";
|
|
12
|
-
import { t as notifyLlmRequestActivity } from "./llm-request-activity-BjtkplhG.mjs";
|
|
13
|
-
import { d as transportAbortError } from "./transport-stream-shared-D81p90xq.mjs";
|
|
1
|
+
import { n as getEnvApiKey, r as __exportAll } from "./env-api-keys-CtMlqaQ4.mjs";
|
|
2
|
+
import { d as resolveClaudeSonnet5ModelIdentity, f as supportsClaudeAdaptiveThinking, l as resolveClaudeNativeThinkingLevelMap, m as supportsClaudeNativeXhighEffort, p as supportsClaudeNativeMaxEffort, u as resolveClaudeOpus5ModelIdentity } from "./src-CjOfhrH3.mjs";
|
|
3
|
+
import { t as AssistantMessageEventStream } from "./event-stream-ReMmOTzX.mjs";
|
|
4
|
+
import { n as getAiTransportHost, r as resolveAiTransportHeaderSentinels } from "./host-4t713IeR.mjs";
|
|
5
|
+
import { n as calculateCost, r as clampThinkingLevel } from "./model-utils-Cn9KAz3z.mjs";
|
|
6
|
+
import { r as createDeferredEventBuffer, t as notifyLlmRequestActivity } from "./llm-request-activity-CehVkZP-.mjs";
|
|
14
7
|
import { t as headersToRecord } from "./headers-B_e4-1J0.mjs";
|
|
15
|
-
import { t as
|
|
16
|
-
import {
|
|
17
|
-
import { n as buildBaseOptions, r as
|
|
18
|
-
import "./
|
|
8
|
+
import { n as parseStreamingJson, t as parseJsonWithRepair } from "./json-parse-DzNSIQBq.mjs";
|
|
9
|
+
import { t as sanitizeSurrogates } from "./sanitize-unicode-DT5o51ur.mjs";
|
|
10
|
+
import { a as adjustMaxTokensForThinking, b as stripSystemPromptCacheBoundary, c as isRecord, d as prepareClaudeNoPrefillRequestContext, f as requiresClaudeAdaptiveThinking, h as usesClaudeStreamingRefusalContract, i as extractToolResultText, l as applyClaudeRequestContract, m as usesClaudeFable5MessagesContract, n as describeToolResultMediaPlaceholder, o as buildBaseOptions, r as extractToolResultBlockText, t as transformMessages, y as splitSystemPromptCacheBoundary } from "./transform-messages-DoWx35pj.mjs";
|
|
11
|
+
import { t as projectRuntimeToolInputSchema } from "./tool-schema-json-projection-BwNu3nDi.mjs";
|
|
12
|
+
import { a as resolveCacheRetention, i as resolveCloudflareBaseUrl, n as hasCopilotVisionInput, t as buildCopilotDynamicHeaders } from "./github-copilot-headers-BsH5cqGj.mjs";
|
|
19
13
|
import Anthropic from "@anthropic-ai/sdk";
|
|
20
|
-
|
|
14
|
+
//#region packages/ai/src/providers/anthropic-auth-headers.ts
|
|
15
|
+
function usesFoundryBearerAuth(model) {
|
|
16
|
+
return model.provider === "microsoft-foundry" && (model.authHeader === true || hasBearerAuthorizationHeader(model.headers));
|
|
17
|
+
}
|
|
18
|
+
function hasBearerAuthorizationHeader(headers) {
|
|
19
|
+
if (!headers) return false;
|
|
20
|
+
return Object.entries(headers).some(([key, value]) => key.toLowerCase() === "authorization" && /^bearer\s+\S+/i.test(value.trim()));
|
|
21
|
+
}
|
|
22
|
+
function omitFoundryBearerCredentialHeaders(headers) {
|
|
23
|
+
if (!headers) return;
|
|
24
|
+
const next = {};
|
|
25
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
26
|
+
const lower = key.toLowerCase();
|
|
27
|
+
if (lower === "authorization" || lower === "x-api-key" || lower === "api-key") continue;
|
|
28
|
+
next[key] = value;
|
|
29
|
+
}
|
|
30
|
+
return Object.keys(next).length > 0 ? next : void 0;
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
//#region packages/ai/src/providers/anthropic-refusal.ts
|
|
34
|
+
function readNullableString(value) {
|
|
35
|
+
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
36
|
+
}
|
|
37
|
+
function readAnthropicRefusalDetails(value) {
|
|
38
|
+
if (!value || typeof value !== "object") return {
|
|
39
|
+
category: null,
|
|
40
|
+
explanation: null
|
|
41
|
+
};
|
|
42
|
+
const details = value;
|
|
43
|
+
return {
|
|
44
|
+
category: readNullableString(details.category),
|
|
45
|
+
explanation: readNullableString(details.explanation)
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function formatAnthropicRefusalMessage(details) {
|
|
49
|
+
return `Anthropic refusal${details.category ? ` (category: ${details.category})` : ""}${details.explanation ? `: ${details.explanation}` : "."}`;
|
|
50
|
+
}
|
|
51
|
+
function applyAnthropicRefusal(output, stopDetails, provider) {
|
|
52
|
+
const details = readAnthropicRefusalDetails(stopDetails);
|
|
53
|
+
output.stopReason = "error";
|
|
54
|
+
output.errorMessage = formatAnthropicRefusalMessage(details);
|
|
55
|
+
output.diagnostics = [...output.diagnostics ?? [], {
|
|
56
|
+
type: "provider_refusal",
|
|
57
|
+
timestamp: Date.now(),
|
|
58
|
+
details: {
|
|
59
|
+
provider,
|
|
60
|
+
category: details.category,
|
|
61
|
+
explanation: details.explanation
|
|
62
|
+
}
|
|
63
|
+
}];
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
66
|
+
//#region packages/ai/src/providers/anthropic-server-fallback.ts
|
|
67
|
+
/** Anthropic beta that re-serves safety refusals on an allowed fallback model. */
|
|
68
|
+
const ANTHROPIC_SERVER_SIDE_FALLBACK_BETA = "server-side-fallback-2026-06-01";
|
|
69
|
+
const CLAUDE_FABLE_5_FALLBACK_MODEL = "claude-opus-4-8";
|
|
70
|
+
const CLAUDE_FABLE_5_FALLBACK_MODEL_COST = {
|
|
71
|
+
input: 5,
|
|
72
|
+
output: 25,
|
|
73
|
+
cacheRead: .5,
|
|
74
|
+
cacheWrite: 6.25
|
|
75
|
+
};
|
|
76
|
+
function buildAnthropicServerSideFallbacks() {
|
|
77
|
+
return [{ model: CLAUDE_FABLE_5_FALLBACK_MODEL }];
|
|
78
|
+
}
|
|
79
|
+
function readBoundaryModel(value) {
|
|
80
|
+
if (!value || typeof value !== "object") return null;
|
|
81
|
+
const model = value.model;
|
|
82
|
+
return typeof model === "string" && model.trim() ? model : null;
|
|
83
|
+
}
|
|
84
|
+
/** Reads a `fallback` content block marking where one model's output gives way to the next. */
|
|
85
|
+
function readAnthropicFallbackBoundary(block) {
|
|
86
|
+
if (!block || typeof block !== "object") return null;
|
|
87
|
+
const record = block;
|
|
88
|
+
if (record.type !== "fallback") return null;
|
|
89
|
+
return {
|
|
90
|
+
fromModel: readBoundaryModel(record.from),
|
|
91
|
+
toModel: readBoundaryModel(record.to)
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Drops pre-fallback thinking/tool calls while preserving the text prefix that
|
|
96
|
+
* the serving model continued. Dropped tool calls must never execute or replay.
|
|
97
|
+
*/
|
|
98
|
+
function applyAnthropicFallbackBoundary(params) {
|
|
99
|
+
const { output, boundary } = params;
|
|
100
|
+
const survivors = output.content.filter((block) => block.type === "text");
|
|
101
|
+
for (const survivor of survivors) delete survivor.textSignature;
|
|
102
|
+
output.content.splice(0, output.content.length, ...survivors);
|
|
103
|
+
if (boundary.toModel) output.responseModel = boundary.toModel;
|
|
104
|
+
output.diagnostics = [...output.diagnostics ?? [], {
|
|
105
|
+
type: "provider_fallback",
|
|
106
|
+
timestamp: Date.now(),
|
|
107
|
+
details: {
|
|
108
|
+
provider: params.provider,
|
|
109
|
+
fromModel: boundary.fromModel,
|
|
110
|
+
toModel: boundary.toModel
|
|
111
|
+
}
|
|
112
|
+
}];
|
|
113
|
+
}
|
|
114
|
+
//#endregion
|
|
115
|
+
//#region packages/ai/src/providers/anthropic-thinking-replay.ts
|
|
116
|
+
const ANTHROPIC_OMITTED_REASONING_TEXT = "[assistant reasoning omitted]";
|
|
117
|
+
function asReplayMessage(value) {
|
|
118
|
+
return value && typeof value === "object" ? value : void 0;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Anthropic tool results continue the preceding assistant turn. Preserve that
|
|
122
|
+
* turn's signed thinking even when the next request disables new thinking.
|
|
123
|
+
*/
|
|
124
|
+
function findActiveAnthropicToolTurnAssistantIndex(messages) {
|
|
125
|
+
const toolResultIds = /* @__PURE__ */ new Set();
|
|
126
|
+
let index = messages.length - 1;
|
|
127
|
+
while (index >= 0) {
|
|
128
|
+
const message = asReplayMessage(messages[index]);
|
|
129
|
+
if (message?.role !== "toolResult") break;
|
|
130
|
+
if (typeof message.toolCallId === "string") toolResultIds.add(message.toolCallId);
|
|
131
|
+
index -= 1;
|
|
132
|
+
}
|
|
133
|
+
if (toolResultIds.size === 0) return -1;
|
|
134
|
+
const assistant = asReplayMessage(messages[index]);
|
|
135
|
+
if (assistant?.role !== "assistant" || !Array.isArray(assistant.content)) return -1;
|
|
136
|
+
const toolCallIds = /* @__PURE__ */ new Set();
|
|
137
|
+
for (const block of assistant.content) {
|
|
138
|
+
if (!block || typeof block !== "object") continue;
|
|
139
|
+
const record = block;
|
|
140
|
+
if ((record.type === "toolCall" || record.type === "tool_use" || record.type === "function_call") && typeof record.id === "string") toolCallIds.add(record.id);
|
|
141
|
+
}
|
|
142
|
+
return [...toolResultIds].every((toolCallId) => toolCallIds.has(toolCallId)) ? index : -1;
|
|
143
|
+
}
|
|
144
|
+
//#endregion
|
|
145
|
+
//#region packages/ai/src/providers/anthropic-tool-projection.ts
|
|
146
|
+
function isProviderSupportedViolation(violation) {
|
|
147
|
+
return violation.endsWith(".$dynamicRef") || violation.endsWith(".$dynamicAnchor");
|
|
148
|
+
}
|
|
149
|
+
const schemaValueKeywords = /* @__PURE__ */ new Set([
|
|
150
|
+
"additionalProperties",
|
|
151
|
+
"contains",
|
|
152
|
+
"contentSchema",
|
|
153
|
+
"else",
|
|
154
|
+
"if",
|
|
155
|
+
"items",
|
|
156
|
+
"not",
|
|
157
|
+
"propertyNames",
|
|
158
|
+
"then",
|
|
159
|
+
"unevaluatedItems",
|
|
160
|
+
"unevaluatedProperties"
|
|
161
|
+
]);
|
|
162
|
+
const schemaArrayKeywords = /* @__PURE__ */ new Set([
|
|
163
|
+
"allOf",
|
|
164
|
+
"anyOf",
|
|
165
|
+
"oneOf",
|
|
166
|
+
"prefixItems"
|
|
167
|
+
]);
|
|
168
|
+
const schemaMapKeywords = /* @__PURE__ */ new Set([
|
|
169
|
+
"$defs",
|
|
170
|
+
"definitions",
|
|
171
|
+
"dependencies",
|
|
172
|
+
"dependentSchemas",
|
|
173
|
+
"patternProperties",
|
|
174
|
+
"properties"
|
|
175
|
+
]);
|
|
176
|
+
function normalizeAnthropicJsonSchema(schema) {
|
|
177
|
+
if (!isRecord(schema)) return schema;
|
|
178
|
+
let changed = false;
|
|
179
|
+
const normalized = { ...schema };
|
|
180
|
+
for (const [key, value] of Object.entries(schema)) {
|
|
181
|
+
if (schemaValueKeywords.has(key) && !Array.isArray(value)) {
|
|
182
|
+
const next = normalizeAnthropicJsonSchema(value);
|
|
183
|
+
normalized[key] = next;
|
|
184
|
+
changed ||= next !== value;
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
if (schemaArrayKeywords.has(key) && Array.isArray(value)) {
|
|
188
|
+
const next = value.map(normalizeAnthropicJsonSchema);
|
|
189
|
+
normalized[key] = next;
|
|
190
|
+
changed ||= next.some((entry, index) => entry !== value[index]);
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
if (schemaMapKeywords.has(key) && isRecord(value)) {
|
|
194
|
+
const next = Object.fromEntries(Object.entries(value).map(([entryKey, entryValue]) => [entryKey, normalizeAnthropicJsonSchema(entryValue)]));
|
|
195
|
+
normalized[key] = next;
|
|
196
|
+
changed ||= Object.entries(value).some(([entryKey, entryValue]) => next[entryKey] !== entryValue);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (Array.isArray(schema.items)) {
|
|
200
|
+
normalized.prefixItems = schema.items.map(normalizeAnthropicJsonSchema);
|
|
201
|
+
const additionalItems = schema.additionalItems;
|
|
202
|
+
if (typeof additionalItems === "boolean" || isRecord(additionalItems)) normalized.items = normalizeAnthropicJsonSchema(additionalItems);
|
|
203
|
+
else delete normalized.items;
|
|
204
|
+
delete normalized.additionalItems;
|
|
205
|
+
changed = true;
|
|
206
|
+
}
|
|
207
|
+
return changed ? normalized : schema;
|
|
208
|
+
}
|
|
209
|
+
/** Snapshots direct/custom tool descriptors before Anthropic payload construction. */
|
|
210
|
+
function projectAnthropicTools(tools, toWireName) {
|
|
211
|
+
const projectedTools = [];
|
|
212
|
+
const unavailableOriginalNames = /* @__PURE__ */ new Set();
|
|
213
|
+
for (const tool of tools) {
|
|
214
|
+
let projectedTool;
|
|
215
|
+
let originalName;
|
|
216
|
+
try {
|
|
217
|
+
const name = tool.name;
|
|
218
|
+
originalName = name;
|
|
219
|
+
if (!name) continue;
|
|
220
|
+
const schemaProjection = projectRuntimeToolInputSchema(tool.parameters, `${name}.parameters`);
|
|
221
|
+
if (!isRecord(schemaProjection.schema) || schemaProjection.violations.some((violation) => !isProviderSupportedViolation(violation))) {
|
|
222
|
+
unavailableOriginalNames.add(name);
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
const anthropicSchema = normalizeAnthropicJsonSchema(schemaProjection.schema);
|
|
226
|
+
if (!isRecord(anthropicSchema)) {
|
|
227
|
+
unavailableOriginalNames.add(name);
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
const properties = anthropicSchema.properties;
|
|
231
|
+
const required = anthropicSchema.required;
|
|
232
|
+
if (properties !== void 0 && properties !== null && !isRecord(properties) || required !== void 0 && required !== null && (!Array.isArray(required) || required.some((entry) => typeof entry !== "string"))) {
|
|
233
|
+
unavailableOriginalNames.add(name);
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
let description;
|
|
237
|
+
try {
|
|
238
|
+
description = typeof tool.description === "string" ? tool.description : void 0;
|
|
239
|
+
} catch {}
|
|
240
|
+
projectedTool = {
|
|
241
|
+
originalName: name,
|
|
242
|
+
wireName: toWireName(name),
|
|
243
|
+
...description ? { description } : {},
|
|
244
|
+
inputSchema: {
|
|
245
|
+
type: "object",
|
|
246
|
+
properties: properties ?? {},
|
|
247
|
+
required: required ?? []
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
} catch {
|
|
251
|
+
if (originalName) unavailableOriginalNames.add(originalName);
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
const conflictingTool = projectedTools.find((entry) => entry.wireName === projectedTool.wireName);
|
|
255
|
+
if (conflictingTool && conflictingTool.originalName !== projectedTool.originalName) throw new Error(`Anthropic tool names "${conflictingTool.originalName}" and "${projectedTool.originalName}" both map to "${projectedTool.wireName}"`);
|
|
256
|
+
projectedTools.push(projectedTool);
|
|
257
|
+
}
|
|
258
|
+
return {
|
|
259
|
+
inputToolCount: tools.length,
|
|
260
|
+
unavailableOriginalNames,
|
|
261
|
+
tools: projectedTools
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
/** Keeps forced Anthropic tool choices aligned with the projected wire names. */
|
|
265
|
+
function reconcileAnthropicToolChoice(choice, projection) {
|
|
266
|
+
if (projection.inputToolCount === 0) return choice;
|
|
267
|
+
if (choice.type === "tool") {
|
|
268
|
+
const requestedName = choice.name;
|
|
269
|
+
const originalMatch = projection.tools.find((tool) => tool.originalName === requestedName);
|
|
270
|
+
if (originalMatch) return {
|
|
271
|
+
...choice,
|
|
272
|
+
name: originalMatch.wireName
|
|
273
|
+
};
|
|
274
|
+
if (projection.unavailableOriginalNames.has(requestedName)) throw new Error(`Anthropic tool_choice requested unavailable tool "${requestedName}" after schema conversion`);
|
|
275
|
+
const matchedTool = projection.tools.find((tool) => tool.wireName === requestedName);
|
|
276
|
+
if (!matchedTool) throw new Error(`Anthropic tool_choice requested unavailable tool "${requestedName}" after schema conversion`);
|
|
277
|
+
return {
|
|
278
|
+
...choice,
|
|
279
|
+
name: matchedTool.wireName
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
if (projection.tools.length === 0) {
|
|
283
|
+
if (choice.type === "auto") return;
|
|
284
|
+
if (choice.type === "any") throw new Error("Anthropic tool_choice requires a tool, but no tools survived schema conversion");
|
|
285
|
+
}
|
|
286
|
+
return choice;
|
|
287
|
+
}
|
|
288
|
+
/** Maps Claude Code wire names without trusting every direct/custom descriptor. */
|
|
289
|
+
function resolveOriginalAnthropicToolName(name, projection) {
|
|
290
|
+
return projection?.tools.find((tool) => tool.wireName === name)?.originalName ?? name;
|
|
291
|
+
}
|
|
292
|
+
//#endregion
|
|
293
|
+
//#region packages/ai/src/providers/anthropic-usage.ts
|
|
294
|
+
function readAnthropicUsageTokenCount(value) {
|
|
295
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : void 0;
|
|
296
|
+
}
|
|
297
|
+
function readAnthropicPromptUsageSnapshot(usage) {
|
|
298
|
+
const input = readAnthropicUsageTokenCount(usage.input_tokens);
|
|
299
|
+
const cacheRead = usage.cache_read_input_tokens == null ? 0 : readAnthropicUsageTokenCount(usage.cache_read_input_tokens);
|
|
300
|
+
const cacheWrite = usage.cache_creation_input_tokens == null ? 0 : readAnthropicUsageTokenCount(usage.cache_creation_input_tokens);
|
|
301
|
+
if (input === void 0 || cacheRead === void 0 || cacheWrite === void 0) return;
|
|
302
|
+
return {
|
|
303
|
+
input,
|
|
304
|
+
cacheRead,
|
|
305
|
+
cacheWrite
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
function readLastAnthropicIterationUsage(usage) {
|
|
309
|
+
if (usage.iterations == null) return { state: "absent" };
|
|
310
|
+
if (!Array.isArray(usage.iterations) || usage.iterations.length === 0) return { state: "invalid" };
|
|
311
|
+
const iteration = usage.iterations.at(-1);
|
|
312
|
+
if (!iteration || typeof iteration !== "object" || Array.isArray(iteration)) return { state: "invalid" };
|
|
313
|
+
const record = iteration;
|
|
314
|
+
const input = readAnthropicUsageTokenCount(record.input_tokens);
|
|
315
|
+
const cacheRead = readAnthropicUsageTokenCount(record.cache_read_input_tokens);
|
|
316
|
+
const cacheWrite = readAnthropicUsageTokenCount(record.cache_creation_input_tokens);
|
|
317
|
+
const outputTokens = readAnthropicUsageTokenCount(record.output_tokens);
|
|
318
|
+
if (input === void 0 || cacheRead === void 0 || cacheWrite === void 0 || outputTokens === void 0) return { state: "invalid" };
|
|
319
|
+
const contextPromptTokens = input + cacheRead + cacheWrite;
|
|
320
|
+
return {
|
|
321
|
+
state: "valid",
|
|
322
|
+
usage: {
|
|
323
|
+
contextPromptTokens,
|
|
324
|
+
totalTokens: contextPromptTokens + outputTokens
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
//#endregion
|
|
21
329
|
//#region packages/ai/src/providers/anthropic.ts
|
|
22
330
|
var anthropic_exports = /* @__PURE__ */ __exportAll({
|
|
23
331
|
streamAnthropic: () => streamAnthropic,
|
|
@@ -62,16 +370,16 @@ const toClaudeCodeName = (name) => ccToolLookup.get(name.toLowerCase()) ?? name;
|
|
|
62
370
|
/**
|
|
63
371
|
* Convert content blocks to Anthropic API format
|
|
64
372
|
*/
|
|
65
|
-
|
|
373
|
+
function convertContentBlocks(content, isError) {
|
|
66
374
|
const text = extractToolResultText(content);
|
|
67
375
|
const mediaPlaceholder = describeToolResultMediaPlaceholder(content);
|
|
68
|
-
if (!content.some(
|
|
376
|
+
if (!(Array.isArray(content) && content.some((item) => item && typeof item === "object" && item.type === "image"))) {
|
|
69
377
|
const sanitized = sanitizeSurrogates(text);
|
|
70
378
|
return sanitized.trim().length > 0 ? sanitized : mediaPlaceholder ?? (isError ? EMPTY_ERROR_TOOL_RESULT_TEXT : "");
|
|
71
379
|
}
|
|
72
380
|
const blocks = [];
|
|
73
381
|
let hasTextBlock = false;
|
|
74
|
-
for (const block of content) {
|
|
382
|
+
for (const block of Array.isArray(content) ? content : []) {
|
|
75
383
|
if (!block || typeof block !== "object") continue;
|
|
76
384
|
const record = block;
|
|
77
385
|
const blockText = extractToolResultBlockText(block);
|
|
@@ -82,19 +390,13 @@ async function convertContentBlocks(content, isError, imageBudget) {
|
|
|
82
390
|
});
|
|
83
391
|
hasTextBlock = true;
|
|
84
392
|
}
|
|
85
|
-
if (
|
|
86
|
-
const [normalizedImage] = await normalizeAnthropicInlineContent([{
|
|
87
|
-
type: "image",
|
|
88
|
-
data: typeof record.data === "string" ? record.data : "",
|
|
89
|
-
mimeType: typeof record.mimeType === "string" ? record.mimeType : "image/jpeg"
|
|
90
|
-
}], imageBudget);
|
|
91
|
-
if (normalizedImage?.type !== "image") continue;
|
|
393
|
+
if (record.type !== "image") continue;
|
|
92
394
|
blocks.push({
|
|
93
395
|
type: "image",
|
|
94
396
|
source: {
|
|
95
397
|
type: "base64",
|
|
96
|
-
media_type:
|
|
97
|
-
data:
|
|
398
|
+
media_type: typeof record.mimeType === "string" ? record.mimeType : "image/jpeg",
|
|
399
|
+
data: typeof record.data === "string" ? record.data : ""
|
|
98
400
|
}
|
|
99
401
|
});
|
|
100
402
|
}
|
|
@@ -114,8 +416,7 @@ function getAnthropicCompat(model) {
|
|
|
114
416
|
supportsEagerToolInputStreaming: model.compat?.supportsEagerToolInputStreaming ?? !isFireworks,
|
|
115
417
|
supportsLongCacheRetention: model.compat?.supportsLongCacheRetention ?? !isFireworks,
|
|
116
418
|
sendSessionAffinityHeaders: model.compat?.sendSessionAffinityHeaders ?? (isFireworks || isCloudflareAiGatewayAnthropic),
|
|
117
|
-
supportsCacheControlOnTools: model.compat?.supportsCacheControlOnTools ?? !isFireworks
|
|
118
|
-
allowEmptySignature: model.compat?.allowEmptySignature ?? false
|
|
419
|
+
supportsCacheControlOnTools: model.compat?.supportsCacheControlOnTools ?? !isFireworks
|
|
119
420
|
};
|
|
120
421
|
}
|
|
121
422
|
function mergeHeaders(...headerSources) {
|
|
@@ -131,11 +432,93 @@ const ANTHROPIC_MESSAGE_EVENTS = /* @__PURE__ */ new Set([
|
|
|
131
432
|
"content_block_delta",
|
|
132
433
|
"content_block_stop"
|
|
133
434
|
]);
|
|
134
|
-
|
|
435
|
+
function flushSseEvent(state) {
|
|
436
|
+
if (!state.event && state.data.length === 0) return null;
|
|
437
|
+
const event = {
|
|
438
|
+
event: state.event,
|
|
439
|
+
data: state.data.join("\n"),
|
|
440
|
+
raw: [...state.raw]
|
|
441
|
+
};
|
|
442
|
+
state.event = null;
|
|
443
|
+
state.data = [];
|
|
444
|
+
state.raw = [];
|
|
445
|
+
return event;
|
|
446
|
+
}
|
|
447
|
+
function decodeSseLine(line, state) {
|
|
448
|
+
if (line === "") return flushSseEvent(state);
|
|
449
|
+
state.raw.push(line);
|
|
450
|
+
if (line.startsWith(":")) return null;
|
|
451
|
+
const delimiterIndex = line.indexOf(":");
|
|
452
|
+
const fieldName = delimiterIndex === -1 ? line : line.slice(0, delimiterIndex);
|
|
453
|
+
let value = delimiterIndex === -1 ? "" : line.slice(delimiterIndex + 1);
|
|
454
|
+
if (value.startsWith(" ")) value = value.slice(1);
|
|
455
|
+
if (fieldName === "event") state.event = value;
|
|
456
|
+
else if (fieldName === "data") state.data.push(value);
|
|
457
|
+
return null;
|
|
458
|
+
}
|
|
459
|
+
function nextLineBreakIndex(text) {
|
|
460
|
+
const carriageReturnIndex = text.indexOf("\r");
|
|
461
|
+
const newlineIndex = text.indexOf("\n");
|
|
462
|
+
if (carriageReturnIndex === -1) return newlineIndex;
|
|
463
|
+
if (newlineIndex === -1) return carriageReturnIndex;
|
|
464
|
+
return Math.min(carriageReturnIndex, newlineIndex);
|
|
465
|
+
}
|
|
466
|
+
function consumeLine(text) {
|
|
467
|
+
const lineBreakIndex = nextLineBreakIndex(text);
|
|
468
|
+
if (lineBreakIndex === -1) return null;
|
|
469
|
+
let nextIndex = lineBreakIndex + 1;
|
|
470
|
+
if (text[lineBreakIndex] === "\r" && text[nextIndex] === "\n") nextIndex += 1;
|
|
471
|
+
return {
|
|
472
|
+
line: text.slice(0, lineBreakIndex),
|
|
473
|
+
rest: text.slice(nextIndex)
|
|
474
|
+
};
|
|
475
|
+
}
|
|
476
|
+
async function* iterateSseMessages(body, signal) {
|
|
477
|
+
const reader = body.getReader();
|
|
478
|
+
const decoder = new TextDecoder();
|
|
479
|
+
const state = {
|
|
480
|
+
event: null,
|
|
481
|
+
data: [],
|
|
482
|
+
raw: []
|
|
483
|
+
};
|
|
484
|
+
let buffer = "";
|
|
485
|
+
try {
|
|
486
|
+
while (true) {
|
|
487
|
+
if (signal?.aborted) throw new Error("Request was aborted");
|
|
488
|
+
const { value, done } = await reader.read();
|
|
489
|
+
if (done) break;
|
|
490
|
+
buffer += decoder.decode(value, { stream: true });
|
|
491
|
+
let consumed = consumeLine(buffer);
|
|
492
|
+
while (consumed) {
|
|
493
|
+
buffer = consumed.rest;
|
|
494
|
+
const event = decodeSseLine(consumed.line, state);
|
|
495
|
+
if (event) yield event;
|
|
496
|
+
consumed = consumeLine(buffer);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
buffer += decoder.decode();
|
|
500
|
+
let consumed = consumeLine(buffer);
|
|
501
|
+
while (consumed) {
|
|
502
|
+
buffer = consumed.rest;
|
|
503
|
+
const event = decodeSseLine(consumed.line, state);
|
|
504
|
+
if (event) yield event;
|
|
505
|
+
consumed = consumeLine(buffer);
|
|
506
|
+
}
|
|
507
|
+
if (buffer.length > 0) {
|
|
508
|
+
const event = decodeSseLine(buffer, state);
|
|
509
|
+
if (event) yield event;
|
|
510
|
+
}
|
|
511
|
+
const trailingEvent = flushSseEvent(state);
|
|
512
|
+
if (trailingEvent) yield trailingEvent;
|
|
513
|
+
} finally {
|
|
514
|
+
reader.releaseLock();
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
async function* iterateAnthropicEvents(response, signal, requireMessageStop = false) {
|
|
135
518
|
if (!response.body) throw new Error("Attempted to iterate over an Anthropic response with no body");
|
|
136
519
|
let sawMessageStart = false;
|
|
137
520
|
let sawMessageEnd = false;
|
|
138
|
-
for await (const sse of
|
|
521
|
+
for await (const sse of iterateSseMessages(response.body, signal)) {
|
|
139
522
|
if (sse.event === "error") throw new Error(sse.data);
|
|
140
523
|
if (!ANTHROPIC_MESSAGE_EVENTS.has(sse.event ?? "")) continue;
|
|
141
524
|
try {
|
|
@@ -205,7 +588,7 @@ const streamAnthropic = (model, context, options) => {
|
|
|
205
588
|
isOAuth = created.isOAuthToken;
|
|
206
589
|
serverSideFallback = created.serverSideFallback;
|
|
207
590
|
}
|
|
208
|
-
const builtParams =
|
|
591
|
+
const builtParams = buildParams(model, requestContext, isOAuth, requestOptions, serverSideFallback);
|
|
209
592
|
let params = builtParams.params;
|
|
210
593
|
const toolProjection = builtParams.toolProjection;
|
|
211
594
|
const nextParams = await requestOptions?.onPayload?.(params, model);
|
|
@@ -214,7 +597,7 @@ const streamAnthropic = (model, context, options) => {
|
|
|
214
597
|
const sdkRequestOptions = {
|
|
215
598
|
...requestOptions?.signal ? { signal: requestOptions.signal } : {},
|
|
216
599
|
...requestOptions?.timeoutMs !== void 0 ? { timeout: requestOptions.timeoutMs } : {},
|
|
217
|
-
maxRetries: requestOptions
|
|
600
|
+
...requestOptions?.maxRetries !== void 0 ? { maxRetries: requestOptions.maxRetries } : {}
|
|
218
601
|
};
|
|
219
602
|
const response = await client.messages.create({
|
|
220
603
|
...params,
|
|
@@ -226,7 +609,7 @@ const streamAnthropic = (model, context, options) => {
|
|
|
226
609
|
}, model);
|
|
227
610
|
const blocks = output.content;
|
|
228
611
|
const blockIndexes = /* @__PURE__ */ new Map();
|
|
229
|
-
for await (const event of iterateAnthropicEvents(response, refusalBuffer !== void 0)) if (event.type === "message_start") {
|
|
612
|
+
for await (const event of iterateAnthropicEvents(response, requestOptions?.signal, refusalBuffer !== void 0)) if (event.type === "message_start") {
|
|
230
613
|
output.responseId = event.message.id;
|
|
231
614
|
output.responseModel = event.message.model;
|
|
232
615
|
const promptUsage = readAnthropicPromptUsageSnapshot(event.message.usage);
|
|
@@ -240,8 +623,6 @@ const streamAnthropic = (model, context, options) => {
|
|
|
240
623
|
if (cacheReadTokens !== void 0) output.usage.cacheRead = cacheReadTokens;
|
|
241
624
|
const cacheWriteTokens = event.message.usage.cache_creation_input_tokens == null ? 0 : readAnthropicUsageTokenCount(event.message.usage.cache_creation_input_tokens);
|
|
242
625
|
if (cacheWriteTokens !== void 0) output.usage.cacheWrite = cacheWriteTokens;
|
|
243
|
-
const cacheWriteUsage = readAnthropicCacheWriteUsage(event.message.usage);
|
|
244
|
-
if (cacheWriteUsage.cacheWrite1h !== void 0) output.usage.cacheWrite1h = cacheWriteUsage.cacheWrite1h;
|
|
245
626
|
output.usage.totalTokens = output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;
|
|
246
627
|
if (messageStartPromptUsage && outputTokens !== void 0) output.usage.contextUsage = {
|
|
247
628
|
state: "available",
|
|
@@ -265,18 +646,15 @@ const streamAnthropic = (model, context, options) => {
|
|
|
265
646
|
});
|
|
266
647
|
costModel = {
|
|
267
648
|
...model,
|
|
268
|
-
cost:
|
|
269
|
-
requestedModelId: model.id,
|
|
270
|
-
servingModelId: fallbackBoundary.toModel,
|
|
271
|
-
requestedCost: model.cost
|
|
272
|
-
})
|
|
649
|
+
cost: CLAUDE_FABLE_5_FALLBACK_MODEL_COST
|
|
273
650
|
};
|
|
274
651
|
calculateCost(costModel, output.usage);
|
|
275
652
|
eventSink.push({
|
|
276
653
|
type: "start",
|
|
277
654
|
partial: output
|
|
278
655
|
});
|
|
279
|
-
for (
|
|
656
|
+
for (let i = 0; i < blocks.length; i += 1) {
|
|
657
|
+
const block = blocks[i];
|
|
280
658
|
if (block.type !== "text") continue;
|
|
281
659
|
delete block.index;
|
|
282
660
|
eventSink.push({
|
|
@@ -434,37 +812,33 @@ const streamAnthropic = (model, context, options) => {
|
|
|
434
812
|
} else if (event.type === "message_delta") {
|
|
435
813
|
if (event.delta.stop_reason) if (event.delta.stop_reason === "refusal") applyAnthropicRefusal(output, event.delta.stop_details, model.provider);
|
|
436
814
|
else output.stopReason = mapStopReason(event.delta.stop_reason);
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
815
|
+
const inputTokens = readAnthropicUsageTokenCount(event.usage.input_tokens);
|
|
816
|
+
if (inputTokens !== void 0) output.usage.input = inputTokens;
|
|
817
|
+
const outputTokens = readAnthropicUsageTokenCount(event.usage.output_tokens);
|
|
818
|
+
if (outputTokens !== void 0) output.usage.output = outputTokens;
|
|
819
|
+
const cacheReadTokens = readAnthropicUsageTokenCount(event.usage.cache_read_input_tokens);
|
|
820
|
+
if (cacheReadTokens !== void 0) output.usage.cacheRead = cacheReadTokens;
|
|
821
|
+
const cacheWriteTokens = readAnthropicUsageTokenCount(event.usage.cache_creation_input_tokens);
|
|
822
|
+
if (cacheWriteTokens !== void 0) output.usage.cacheWrite = cacheWriteTokens;
|
|
823
|
+
output.usage.totalTokens = output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;
|
|
824
|
+
const iterationUsage = readLastAnthropicIterationUsage(event.usage);
|
|
825
|
+
if (iterationUsage.state === "valid") output.usage.contextUsage = {
|
|
826
|
+
state: "available",
|
|
827
|
+
promptTokens: iterationUsage.usage.contextPromptTokens,
|
|
828
|
+
totalTokens: iterationUsage.usage.totalTokens
|
|
829
|
+
};
|
|
830
|
+
else if (iterationUsage.state === "invalid") output.usage.contextUsage = { state: "unavailable" };
|
|
831
|
+
else if (outputTokens !== void 0 && (messageStartPromptUsage !== void 0 || inputTokens !== void 0 && cacheReadTokens !== void 0 && cacheWriteTokens !== void 0)) {
|
|
832
|
+
const promptTokens = output.usage.input + output.usage.cacheRead + output.usage.cacheWrite;
|
|
833
|
+
output.usage.contextUsage = {
|
|
451
834
|
state: "available",
|
|
452
|
-
promptTokens
|
|
453
|
-
totalTokens:
|
|
835
|
+
promptTokens,
|
|
836
|
+
totalTokens: promptTokens + output.usage.output
|
|
454
837
|
};
|
|
455
|
-
|
|
456
|
-
else if (outputTokens !== void 0 && (messageStartPromptUsage !== void 0 || inputTokens !== void 0 && cacheReadTokens !== void 0 && cacheWriteTokens !== void 0)) {
|
|
457
|
-
const promptTokens = output.usage.input + output.usage.cacheRead + output.usage.cacheWrite;
|
|
458
|
-
output.usage.contextUsage = {
|
|
459
|
-
state: "available",
|
|
460
|
-
promptTokens,
|
|
461
|
-
totalTokens: promptTokens + output.usage.output
|
|
462
|
-
};
|
|
463
|
-
} else output.usage.contextUsage = { state: "unavailable" };
|
|
464
|
-
}
|
|
838
|
+
} else output.usage.contextUsage = { state: "unavailable" };
|
|
465
839
|
calculateCost(costModel, output.usage);
|
|
466
840
|
}
|
|
467
|
-
if (requestOptions?.signal?.aborted) throw
|
|
841
|
+
if (requestOptions?.signal?.aborted) throw new Error("Request was aborted");
|
|
468
842
|
if (output.stopReason === "aborted" || output.stopReason === "error") throw new Error(output.errorMessage ?? "An unknown error occurred");
|
|
469
843
|
refusalBuffer?.flush();
|
|
470
844
|
stream.push({
|
|
@@ -483,7 +857,7 @@ const streamAnthropic = (model, context, options) => {
|
|
|
483
857
|
output.content = [];
|
|
484
858
|
}
|
|
485
859
|
output.stopReason = requestOptions?.signal?.aborted ? "aborted" : "error";
|
|
486
|
-
output.errorMessage =
|
|
860
|
+
output.errorMessage = error instanceof Error ? error.message : JSON.stringify(error);
|
|
487
861
|
stream.push({
|
|
488
862
|
type: "error",
|
|
489
863
|
reason: output.stopReason,
|
|
@@ -550,7 +924,6 @@ const streamSimpleAnthropic = (model, context, options) => {
|
|
|
550
924
|
if (!apiKey) throw new Error(`No API key for provider: ${model.provider}`);
|
|
551
925
|
const base = {
|
|
552
926
|
...buildBaseOptions(model, options, apiKey),
|
|
553
|
-
maxTokens: clampMaxTokensToModel(model, options?.maxTokens ?? model.maxTokens),
|
|
554
927
|
toolChoice: options?.toolChoice
|
|
555
928
|
};
|
|
556
929
|
const mandatoryAdaptiveThinking = requiresClaudeAdaptiveThinking(model);
|
|
@@ -559,7 +932,7 @@ const streamSimpleAnthropic = (model, context, options) => {
|
|
|
559
932
|
thinkingEnabled: false
|
|
560
933
|
});
|
|
561
934
|
const reasoning = options?.reasoning === "off" ? mandatoryAdaptiveThinking ? "low" : "high" : options?.reasoning;
|
|
562
|
-
if (
|
|
935
|
+
if (resolveClaudeSonnet5ModelIdentity(model) || resolveClaudeOpus5ModelIdentity(model)) return streamAnthropic(model, context, {
|
|
563
936
|
...base,
|
|
564
937
|
thinkingEnabled: true,
|
|
565
938
|
effort: mapThinkingLevelToEffort(model, reasoning ?? "high")
|
|
@@ -578,11 +951,10 @@ const streamSimpleAnthropic = (model, context, options) => {
|
|
|
578
951
|
});
|
|
579
952
|
}
|
|
580
953
|
const adjusted = adjustMaxTokensForThinking(base.maxTokens, model.maxTokens, reasoning, options?.thinkingBudgets);
|
|
581
|
-
const thinkingEnabled = adjusted.thinkingBudget >=
|
|
582
|
-
const maxTokens = thinkingEnabled ? adjusted.maxTokens : clampMaxTokensToModel(model, options?.maxTokens ?? model.maxTokens);
|
|
954
|
+
const thinkingEnabled = adjusted.thinkingBudget >= 1024;
|
|
583
955
|
return streamAnthropic(model, context, {
|
|
584
956
|
...base,
|
|
585
|
-
maxTokens,
|
|
957
|
+
maxTokens: adjusted.maxTokens,
|
|
586
958
|
thinkingEnabled,
|
|
587
959
|
thinkingBudgetTokens: thinkingEnabled ? adjusted.thinkingBudget : void 0
|
|
588
960
|
});
|
|
@@ -604,7 +976,7 @@ function isAnthropicPublicEndpoint(baseUrl) {
|
|
|
604
976
|
* identity) requests are excluded until the beta is verified there.
|
|
605
977
|
*/
|
|
606
978
|
function supportsAnthropicServerSideFallback(model) {
|
|
607
|
-
if (!usesClaudeFable5MessagesContract(model)
|
|
979
|
+
if (!usesClaudeFable5MessagesContract(model) || model.provider !== "anthropic") return false;
|
|
608
980
|
return isAnthropicPublicEndpoint(model.baseUrl);
|
|
609
981
|
}
|
|
610
982
|
function createClient(model, apiKey, thinkingEnabled, interleavedThinking, useFineGrainedToolStreamingBeta, optionsHeaders, dynamicHeaders, sessionId) {
|
|
@@ -708,13 +1080,13 @@ function createClient(model, apiKey, thinkingEnabled, interleavedThinking, useFi
|
|
|
708
1080
|
serverSideFallback
|
|
709
1081
|
};
|
|
710
1082
|
}
|
|
711
|
-
|
|
1083
|
+
function buildParams(model, context, isOAuthTokenResult, options, serverSideFallback = false) {
|
|
712
1084
|
const mandatoryAdaptiveThinking = requiresClaudeAdaptiveThinking(model);
|
|
713
1085
|
const replayThinkingEnabled = mandatoryAdaptiveThinking || options?.thinkingEnabled === true;
|
|
714
1086
|
const { cacheControl } = getCacheControl(model, options?.cacheRetention);
|
|
715
1087
|
const system = buildAnthropicSystemBlocks(context.systemPrompt, isOAuthTokenResult, cacheControl);
|
|
716
|
-
const compat = getAnthropicCompat(model);
|
|
717
|
-
const convertedTools = context.tools ? convertTools(context.tools, isOAuthTokenResult, compat.supportsEagerToolInputStreaming, compat.supportsCacheControlOnTools ? cacheControl : void 0) : void 0;
|
|
1088
|
+
const compat = context.tools ? getAnthropicCompat(model) : void 0;
|
|
1089
|
+
const convertedTools = context.tools && compat ? convertTools(context.tools, isOAuthTokenResult, compat.supportsEagerToolInputStreaming, compat.supportsCacheControlOnTools ? cacheControl : void 0) : void 0;
|
|
718
1090
|
const tools = convertedTools?.tools;
|
|
719
1091
|
const toolProjection = convertedTools?.projection;
|
|
720
1092
|
const systemCacheControlCount = countNativeCacheControlMarkers(system);
|
|
@@ -722,12 +1094,12 @@ async function buildParams(model, context, isOAuthTokenResult, options, serverSi
|
|
|
722
1094
|
const messageCacheControlLimit = Math.max(0, ANTHROPIC_CACHE_CONTROL_LIMIT - systemCacheControlCount - toolCacheControlCount);
|
|
723
1095
|
const params = {
|
|
724
1096
|
model: model.id,
|
|
725
|
-
messages:
|
|
1097
|
+
messages: convertMessages(context.messages, model, isOAuthTokenResult, cacheControl, messageCacheControlLimit, replayThinkingEnabled),
|
|
726
1098
|
max_tokens: options?.maxTokens ?? model.maxTokens,
|
|
727
1099
|
stream: true
|
|
728
1100
|
};
|
|
729
1101
|
if (system) params.system = system;
|
|
730
|
-
if (serverSideFallback) params.fallbacks =
|
|
1102
|
+
if (serverSideFallback) params.fallbacks = buildAnthropicServerSideFallbacks();
|
|
731
1103
|
if (options?.temperature !== void 0 && !options?.thinkingEnabled && !supportsNativeXhighEffort(model)) params.temperature = options.temperature;
|
|
732
1104
|
if (options?.stop !== void 0 && options.stop.length > 0) params.stop_sequences = options.stop;
|
|
733
1105
|
if (tools && tools.length > 0) params.tools = tools;
|
|
@@ -765,15 +1137,13 @@ async function buildParams(model, context, isOAuthTokenResult, options, serverSi
|
|
|
765
1137
|
function normalizeToolCallId(id) {
|
|
766
1138
|
return id.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 64);
|
|
767
1139
|
}
|
|
768
|
-
|
|
1140
|
+
function convertMessages(messages, model, isOAuthTokenValue, cacheControl, messageCacheControlLimit = 4, replayThinkingEnabled = true) {
|
|
769
1141
|
const params = [];
|
|
770
|
-
const imageBudget = createAnthropicInlineImageBudget();
|
|
771
1142
|
const cacheBreakpointOptOutParamIndexes = /* @__PURE__ */ new Set();
|
|
772
1143
|
const transformedMessages = transformMessages(messages, model, normalizeToolCallId);
|
|
773
1144
|
const activeToolTurnAssistantIndex = replayThinkingEnabled ? -1 : findActiveAnthropicToolTurnAssistantIndex(transformedMessages);
|
|
774
1145
|
for (let i = 0; i < transformedMessages.length; i++) {
|
|
775
1146
|
const msg = transformedMessages[i];
|
|
776
|
-
if (!msg) continue;
|
|
777
1147
|
if (msg.role === "user") {
|
|
778
1148
|
const isRuntimeContextCarrier = msg.runtimeContextCarrier === true;
|
|
779
1149
|
if (typeof msg.content === "string") {
|
|
@@ -785,7 +1155,7 @@ async function convertMessages(messages, model, isOAuthTokenValue, cacheControl,
|
|
|
785
1155
|
});
|
|
786
1156
|
}
|
|
787
1157
|
} else {
|
|
788
|
-
const filteredBlocks =
|
|
1158
|
+
const filteredBlocks = msg.content.map((item) => {
|
|
789
1159
|
if (item.type === "text") return {
|
|
790
1160
|
type: "text",
|
|
791
1161
|
text: sanitizeSurrogates(item.text)
|
|
@@ -794,7 +1164,7 @@ async function convertMessages(messages, model, isOAuthTokenValue, cacheControl,
|
|
|
794
1164
|
type: "image",
|
|
795
1165
|
source: {
|
|
796
1166
|
type: "base64",
|
|
797
|
-
media_type:
|
|
1167
|
+
media_type: item.mimeType,
|
|
798
1168
|
data: item.data
|
|
799
1169
|
}
|
|
800
1170
|
};
|
|
@@ -824,7 +1194,6 @@ async function convertMessages(messages, model, isOAuthTokenValue, cacheControl,
|
|
|
824
1194
|
continue;
|
|
825
1195
|
}
|
|
826
1196
|
if (block.redacted) {
|
|
827
|
-
if (!block.thinkingSignature) throw new Error("redacted thinking block is missing its opaque signature");
|
|
828
1197
|
blocks.push({
|
|
829
1198
|
type: "redacted_thinking",
|
|
830
1199
|
data: block.thinkingSignature
|
|
@@ -834,7 +1203,7 @@ async function convertMessages(messages, model, isOAuthTokenValue, cacheControl,
|
|
|
834
1203
|
const thinkingSignature = block.thinkingSignature?.trim();
|
|
835
1204
|
const hasNativeThinkingSignature = Boolean(thinkingSignature) && thinkingSignature !== "reasoning_content";
|
|
836
1205
|
if (block.thinking.trim().length === 0 && !hasNativeThinkingSignature) continue;
|
|
837
|
-
if (!thinkingSignature
|
|
1206
|
+
if (!thinkingSignature) blocks.push({
|
|
838
1207
|
type: "text",
|
|
839
1208
|
text: sanitizeSurrogates(block.thinking)
|
|
840
1209
|
});
|
|
@@ -843,7 +1212,7 @@ async function convertMessages(messages, model, isOAuthTokenValue, cacheControl,
|
|
|
843
1212
|
blocks.push({
|
|
844
1213
|
type: "thinking",
|
|
845
1214
|
thinking: block.thinking,
|
|
846
|
-
signature: thinkingSignature
|
|
1215
|
+
signature: thinkingSignature
|
|
847
1216
|
});
|
|
848
1217
|
}
|
|
849
1218
|
} else if (block.type === "toolCall") blocks.push({
|
|
@@ -866,17 +1235,16 @@ async function convertMessages(messages, model, isOAuthTokenValue, cacheControl,
|
|
|
866
1235
|
toolResults.push({
|
|
867
1236
|
type: "tool_result",
|
|
868
1237
|
tool_use_id: msg.toolCallId,
|
|
869
|
-
content:
|
|
1238
|
+
content: convertContentBlocks(msg.content, msg.isError),
|
|
870
1239
|
is_error: msg.isError
|
|
871
1240
|
});
|
|
872
1241
|
let j = i + 1;
|
|
873
|
-
while (j < transformedMessages.length) {
|
|
874
|
-
const nextMsg = transformedMessages
|
|
875
|
-
if (nextMsg?.role !== "toolResult") break;
|
|
1242
|
+
while (j < transformedMessages.length && transformedMessages[j].role === "toolResult") {
|
|
1243
|
+
const nextMsg = transformedMessages[j];
|
|
876
1244
|
toolResults.push({
|
|
877
1245
|
type: "tool_result",
|
|
878
1246
|
tool_use_id: nextMsg.toolCallId,
|
|
879
|
-
content:
|
|
1247
|
+
content: convertContentBlocks(nextMsg.content, nextMsg.isError),
|
|
880
1248
|
is_error: nextMsg.isError
|
|
881
1249
|
});
|
|
882
1250
|
j++;
|
|
@@ -892,11 +1260,10 @@ async function convertMessages(messages, model, isOAuthTokenValue, cacheControl,
|
|
|
892
1260
|
let fallbackToolResult;
|
|
893
1261
|
for (let i = params.length - 1; i >= 0; i--) {
|
|
894
1262
|
const message = params[i];
|
|
895
|
-
if (
|
|
1263
|
+
if (message.role !== "user" || cacheBreakpointOptOutParamIndexes.has(i)) continue;
|
|
896
1264
|
if (Array.isArray(message.content)) {
|
|
897
1265
|
for (let j = message.content.length - 1; j >= 0; j--) {
|
|
898
1266
|
const block = message.content[j];
|
|
899
|
-
if (!block) continue;
|
|
900
1267
|
if (block.type === "text" || block.type === "image") {
|
|
901
1268
|
if (fallbackToolResult && messageCacheControlLimit === 1) {
|
|
902
1269
|
applyContentBlockCacheControl(fallbackToolResult, cacheControl);
|
|
@@ -1013,4 +1380,4 @@ function mapStopReason(reason) {
|
|
|
1013
1380
|
}
|
|
1014
1381
|
}
|
|
1015
1382
|
//#endregion
|
|
1016
|
-
export { streamAnthropic as n, streamSimpleAnthropic as r, anthropic_exports as t };
|
|
1383
|
+
export { readAnthropicFallbackBoundary as _, readAnthropicUsageTokenCount as a, usesFoundryBearerAuth as b, reconcileAnthropicToolChoice as c, findActiveAnthropicToolTurnAssistantIndex as d, ANTHROPIC_SERVER_SIDE_FALLBACK_BETA as f, buildAnthropicServerSideFallbacks as g, applyAnthropicFallbackBoundary as h, readAnthropicPromptUsageSnapshot as i, resolveOriginalAnthropicToolName as l, CLAUDE_FABLE_5_FALLBACK_MODEL_COST as m, streamAnthropic as n, readLastAnthropicIterationUsage as o, CLAUDE_FABLE_5_FALLBACK_MODEL as p, streamSimpleAnthropic as r, projectAnthropicTools as s, anthropic_exports as t, ANTHROPIC_OMITTED_REASONING_TEXT as u, applyAnthropicRefusal as v, omitFoundryBearerCredentialHeaders as y };
|