@kenkaiiii/gg-ai 5.68.1 → 5.70.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.cjs +306 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +67 -1
- package/dist/index.d.ts +67 -1
- package/dist/index.js +301 -24
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -35,14 +35,17 @@ __export(index_exports, {
|
|
|
35
35
|
ProviderError: () => ProviderError,
|
|
36
36
|
REDACTION_MARKER: () => REDACTED,
|
|
37
37
|
StreamResult: () => StreamResult,
|
|
38
|
+
TOOL_CALL_NAME_RULES: () => TOOL_CALL_NAME_RULES,
|
|
38
39
|
clampProviderContextImages: () => clampProviderContextImages,
|
|
39
40
|
classifyProviderError: () => classifyProviderError,
|
|
41
|
+
dropInvalidToolCalls: () => dropInvalidToolCalls,
|
|
40
42
|
environmentSecrets: () => environmentSecrets,
|
|
41
43
|
formatError: () => formatError,
|
|
42
44
|
formatErrorForDisplay: () => formatErrorForDisplay,
|
|
43
45
|
hasLoneSurrogate: () => hasLoneSurrogate,
|
|
44
46
|
isHardBillingMessage: () => isHardBillingMessage,
|
|
45
47
|
isUsageLimitError: () => isUsageLimitError,
|
|
48
|
+
isValidToolCallName: () => isValidToolCallName,
|
|
46
49
|
localWireModelId: () => localWireModelId,
|
|
47
50
|
palsuAssistantMessage: () => palsuAssistantMessage,
|
|
48
51
|
palsuText: () => palsuText,
|
|
@@ -61,7 +64,8 @@ __export(index_exports, {
|
|
|
61
64
|
stream: () => stream,
|
|
62
65
|
toAnthropicMessages: () => toAnthropicMessages,
|
|
63
66
|
toOpenAIMessages: () => toOpenAIMessages,
|
|
64
|
-
toWellFormedText: () => toWellFormedText
|
|
67
|
+
toWellFormedText: () => toWellFormedText,
|
|
68
|
+
toolCallNameRuleFor: () => toolCallNameRuleFor
|
|
65
69
|
});
|
|
66
70
|
module.exports = __toCommonJS(index_exports);
|
|
67
71
|
|
|
@@ -515,7 +519,11 @@ function zodToJsonSchema(schema) {
|
|
|
515
519
|
return normalized;
|
|
516
520
|
}
|
|
517
521
|
function resolveToolSchema(tool) {
|
|
518
|
-
|
|
522
|
+
const schema = tool.rawInputSchema ?? zodToJsonSchema(tool.parameters);
|
|
523
|
+
if (schema.type === "object" && schema.properties === void 0) {
|
|
524
|
+
return { ...schema, properties: {} };
|
|
525
|
+
}
|
|
526
|
+
return schema;
|
|
519
527
|
}
|
|
520
528
|
function normalizeRootForAnthropic(schema) {
|
|
521
529
|
const branches = schema.oneOf ?? schema.anyOf;
|
|
@@ -722,6 +730,10 @@ var ANTHROPIC_INPUT_BLOCK_TYPES = /* @__PURE__ */ new Set([
|
|
|
722
730
|
"connector_text",
|
|
723
731
|
"container_upload",
|
|
724
732
|
"document",
|
|
733
|
+
// Server-side refusal fallback marker. Only reaches the wire when the request
|
|
734
|
+
// carries the server-side-fallback beta; otherwise applyServerFallbackReplay
|
|
735
|
+
// strips it first (see toAnthropicMessages' `fallbackBlocks` option).
|
|
736
|
+
"fallback",
|
|
725
737
|
"image",
|
|
726
738
|
"mid_conv_system",
|
|
727
739
|
"redacted_thinking",
|
|
@@ -743,6 +755,42 @@ function isPositionSensitiveThinking(part) {
|
|
|
743
755
|
if (part.type === "thinking") return hasValidThinkingSignature(part);
|
|
744
756
|
return isRawThinking(part);
|
|
745
757
|
}
|
|
758
|
+
function isServerFallbackBlock(part) {
|
|
759
|
+
return part.type === "raw" && part.data.type === "fallback";
|
|
760
|
+
}
|
|
761
|
+
function applyServerFallbackReplay(content, keepMarkers, droppedToolCallIds) {
|
|
762
|
+
let lastFallbackIdx = -1;
|
|
763
|
+
content.forEach((part, idx) => {
|
|
764
|
+
if (isServerFallbackBlock(part)) lastFallbackIdx = idx;
|
|
765
|
+
});
|
|
766
|
+
if (lastFallbackIdx === -1) return content;
|
|
767
|
+
const resultIds = /* @__PURE__ */ new Set();
|
|
768
|
+
for (const part of content) {
|
|
769
|
+
if (part.type === "server_tool_result") resultIds.add(part.toolUseId);
|
|
770
|
+
else if (part.type === "raw" && typeof part.data.tool_use_id === "string")
|
|
771
|
+
resultIds.add(part.data.tool_use_id);
|
|
772
|
+
}
|
|
773
|
+
const out = [];
|
|
774
|
+
content.forEach((part, idx) => {
|
|
775
|
+
if (isServerFallbackBlock(part)) {
|
|
776
|
+
if (keepMarkers) out.push(part);
|
|
777
|
+
return;
|
|
778
|
+
}
|
|
779
|
+
if (idx < lastFallbackIdx) {
|
|
780
|
+
if (part.type === "thinking" || isRawThinking(part)) return;
|
|
781
|
+
if (part.type === "raw" && part.data.type === "connector_text") return;
|
|
782
|
+
if (part.type === "tool_call") {
|
|
783
|
+
droppedToolCallIds?.add(part.id);
|
|
784
|
+
return;
|
|
785
|
+
}
|
|
786
|
+
if (part.type === "server_tool_call" && !resultIds.has(part.id)) return;
|
|
787
|
+
if (part.type === "raw" && part.data.type === "server_tool_use" && !resultIds.has(String(part.data.id)))
|
|
788
|
+
return;
|
|
789
|
+
}
|
|
790
|
+
out.push(part);
|
|
791
|
+
});
|
|
792
|
+
return out.every(isServerFallbackBlock) ? [] : out;
|
|
793
|
+
}
|
|
746
794
|
function toAnthropicAssistantPart(part, idMap) {
|
|
747
795
|
if (part.type === "text") return { type: "text", text: part.text };
|
|
748
796
|
if (part.type === "thinking") {
|
|
@@ -854,6 +902,144 @@ function clampProviderContextImages(messages, provider, supportsImages) {
|
|
|
854
902
|
return message;
|
|
855
903
|
});
|
|
856
904
|
}
|
|
905
|
+
var TOOL_CALL_NAME_RULES = {
|
|
906
|
+
// Anthropic Messages API: tool / tool_use name `^[a-zA-Z0-9_-]{1,128}$`.
|
|
907
|
+
anthropic: { id: "anthropic", maxLength: 128, pattern: /^[a-zA-Z0-9_-]{1,128}$/ },
|
|
908
|
+
// OpenAI Chat Completions: function name a-z A-Z 0-9 _ -, max length 64.
|
|
909
|
+
"openai-chat": { id: "openai-chat", maxLength: 64, pattern: /^[a-zA-Z0-9_-]{1,64}$/ },
|
|
910
|
+
// OpenAI Responses (Codex): same charset; replayed `input[N].name` over 128
|
|
911
|
+
// chars is rejected with `string_above_max_length`.
|
|
912
|
+
"openai-responses": {
|
|
913
|
+
id: "openai-responses",
|
|
914
|
+
maxLength: 128,
|
|
915
|
+
pattern: /^[a-zA-Z0-9_-]{1,128}$/
|
|
916
|
+
},
|
|
917
|
+
// Gemini FunctionDeclaration name: starts with a letter or underscore, then
|
|
918
|
+
// a-z A-Z 0-9 _ . : -, max length 128.
|
|
919
|
+
gemini: { id: "gemini", maxLength: 128, pattern: /^[a-zA-Z_][a-zA-Z0-9_.:-]{0,127}$/ },
|
|
920
|
+
// OpenAI-compatible third parties (GLM, Kimi, DeepSeek, OpenRouter, xAI,
|
|
921
|
+
// local servers, MiniMax, …) don't share one documented charset, so only
|
|
922
|
+
// reject what no declared tool name can contain: blank, >128 chars, or any
|
|
923
|
+
// whitespace / control character (the signature of invocation text).
|
|
924
|
+
generic: { id: "generic", maxLength: 128 }
|
|
925
|
+
};
|
|
926
|
+
var TOOL_NAME_FORBIDDEN_CHARS = /[\s\p{Cc}]/u;
|
|
927
|
+
function isValidToolCallName(name, rule) {
|
|
928
|
+
if (typeof name !== "string" || name.trim().length === 0) return false;
|
|
929
|
+
if (name.length > rule.maxLength) return false;
|
|
930
|
+
if (TOOL_NAME_FORBIDDEN_CHARS.test(name)) return false;
|
|
931
|
+
return rule.pattern ? rule.pattern.test(name) : true;
|
|
932
|
+
}
|
|
933
|
+
function isDefaultOrHost(baseUrl, host) {
|
|
934
|
+
if (!baseUrl) return true;
|
|
935
|
+
try {
|
|
936
|
+
return new URL(baseUrl).hostname === host;
|
|
937
|
+
} catch {
|
|
938
|
+
return false;
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
function toolCallNameRuleFor(provider, options) {
|
|
942
|
+
switch (provider) {
|
|
943
|
+
case "anthropic":
|
|
944
|
+
return TOOL_CALL_NAME_RULES.anthropic;
|
|
945
|
+
case "openai":
|
|
946
|
+
if (options?.accountId) return TOOL_CALL_NAME_RULES["openai-responses"];
|
|
947
|
+
return isDefaultOrHost(options?.baseUrl, "api.openai.com") ? TOOL_CALL_NAME_RULES["openai-chat"] : TOOL_CALL_NAME_RULES.generic;
|
|
948
|
+
case "gemini":
|
|
949
|
+
return TOOL_CALL_NAME_RULES.gemini;
|
|
950
|
+
default:
|
|
951
|
+
return TOOL_CALL_NAME_RULES.generic;
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
function isValidToolCallId(id) {
|
|
955
|
+
return typeof id === "string" && id.trim().length > 0;
|
|
956
|
+
}
|
|
957
|
+
function isRawReasoning(part) {
|
|
958
|
+
return part.type === "raw" && part.data.type === "reasoning";
|
|
959
|
+
}
|
|
960
|
+
function isDanglingReasoning(parts, idx) {
|
|
961
|
+
for (let i = idx + 1; i < parts.length; i++) {
|
|
962
|
+
const next = parts[i];
|
|
963
|
+
if (isRawReasoning(next)) return true;
|
|
964
|
+
if (next.type === "text" || next.type === "tool_call") return false;
|
|
965
|
+
}
|
|
966
|
+
return true;
|
|
967
|
+
}
|
|
968
|
+
function hasReplayableAssistantContent(parts) {
|
|
969
|
+
return parts.some((part) => {
|
|
970
|
+
if (part.type === "text") return part.text.length > 0;
|
|
971
|
+
if (part.type === "thinking") return false;
|
|
972
|
+
if (part.type === "raw") {
|
|
973
|
+
const t = part.data.type;
|
|
974
|
+
return !(t === "thinking" || t === "redacted_thinking" || t === "reasoning" || t === "fallback");
|
|
975
|
+
}
|
|
976
|
+
return true;
|
|
977
|
+
});
|
|
978
|
+
}
|
|
979
|
+
function dropInvalidToolCalls(messages, rule) {
|
|
980
|
+
const isInvalid = (part) => part.type === "tool_call" && (!isValidToolCallName(part.name, rule) || !isValidToolCallId(part.id));
|
|
981
|
+
const hasInvalid = messages.some(
|
|
982
|
+
(m) => m.role === "assistant" && Array.isArray(m.content) && m.content.some(isInvalid)
|
|
983
|
+
);
|
|
984
|
+
if (!hasInvalid) return messages;
|
|
985
|
+
const out = [];
|
|
986
|
+
let pending = /* @__PURE__ */ new Map();
|
|
987
|
+
let prunedAssistant = null;
|
|
988
|
+
for (const msg of messages) {
|
|
989
|
+
if (msg.role === "user" || msg.role === "system") {
|
|
990
|
+
if (msg.role === "user") pending = /* @__PURE__ */ new Map();
|
|
991
|
+
out.push(msg);
|
|
992
|
+
continue;
|
|
993
|
+
}
|
|
994
|
+
if (msg.role === "assistant") {
|
|
995
|
+
pending = /* @__PURE__ */ new Map();
|
|
996
|
+
if (typeof msg.content === "string") {
|
|
997
|
+
out.push(msg);
|
|
998
|
+
continue;
|
|
999
|
+
}
|
|
1000
|
+
const original = msg.content;
|
|
1001
|
+
let dropped = false;
|
|
1002
|
+
const kept = [];
|
|
1003
|
+
for (const part of original) {
|
|
1004
|
+
if (part.type === "tool_call") {
|
|
1005
|
+
const keep = !isInvalid(part);
|
|
1006
|
+
const queue = pending.get(part.id) ?? [];
|
|
1007
|
+
queue.push(keep);
|
|
1008
|
+
pending.set(part.id, queue);
|
|
1009
|
+
if (!keep) {
|
|
1010
|
+
dropped = true;
|
|
1011
|
+
continue;
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
kept.push(part);
|
|
1015
|
+
}
|
|
1016
|
+
if (!dropped) {
|
|
1017
|
+
out.push(msg);
|
|
1018
|
+
continue;
|
|
1019
|
+
}
|
|
1020
|
+
const content = kept.filter(
|
|
1021
|
+
(part, idx) => !isRawReasoning(part) || !isDanglingReasoning(kept, idx) || isDanglingReasoning(original, original.indexOf(part))
|
|
1022
|
+
);
|
|
1023
|
+
if (hasReplayableAssistantContent(content)) {
|
|
1024
|
+
const pruned = { ...msg, content };
|
|
1025
|
+
out.push(pruned);
|
|
1026
|
+
prunedAssistant = pruned;
|
|
1027
|
+
}
|
|
1028
|
+
continue;
|
|
1029
|
+
}
|
|
1030
|
+
let changed = false;
|
|
1031
|
+
const results = msg.content.filter((result) => {
|
|
1032
|
+
const queue = pending.get(result.toolCallId);
|
|
1033
|
+
const keep = queue && queue.length > 0 ? queue.shift() : true;
|
|
1034
|
+
if (!keep) changed = true;
|
|
1035
|
+
return keep;
|
|
1036
|
+
});
|
|
1037
|
+
if (!changed) out.push(msg);
|
|
1038
|
+
else if (results.length > 0) out.push({ ...msg, content: results });
|
|
1039
|
+
}
|
|
1040
|
+
if (prunedAssistant && out[out.length - 1] === prunedAssistant) out.pop();
|
|
1041
|
+
return out;
|
|
1042
|
+
}
|
|
857
1043
|
var NON_VISION_USER_IMAGE_PLACEHOLDER = "(image omitted: model does not support images)";
|
|
858
1044
|
var NON_VISION_TOOL_IMAGE_PLACEHOLDER = "(tool image omitted: model does not support images)";
|
|
859
1045
|
var NON_VIDEO_USER_PLACEHOLDER = "(video omitted: model does not support video)";
|
|
@@ -960,10 +1146,12 @@ function remapAnthropicToolCallId(id, idMap) {
|
|
|
960
1146
|
idMap.set(id, mapped);
|
|
961
1147
|
return mapped;
|
|
962
1148
|
}
|
|
963
|
-
function toAnthropicMessages(messages, cacheControl) {
|
|
1149
|
+
function toAnthropicMessages(messages, cacheControl, options) {
|
|
964
1150
|
let systemText;
|
|
965
1151
|
const out = [];
|
|
966
1152
|
const idMap = /* @__PURE__ */ new Map();
|
|
1153
|
+
const keepFallbackBlocks = options?.fallbackBlocks === true;
|
|
1154
|
+
const droppedToolCallIds = /* @__PURE__ */ new Set();
|
|
967
1155
|
const trajectoryStartIdx = messages.reduce(
|
|
968
1156
|
(last, m, i) => m.role === "user" ? i : last,
|
|
969
1157
|
-1
|
|
@@ -1009,17 +1197,23 @@ function toAnthropicMessages(messages, cacheControl) {
|
|
|
1009
1197
|
}
|
|
1010
1198
|
if (msg.role === "assistant") {
|
|
1011
1199
|
if (typeof msg.content === "string" && msg.content === "") continue;
|
|
1012
|
-
const content = typeof msg.content === "string" ? msg.content : toAnthropicAssistantContent(
|
|
1200
|
+
const content = typeof msg.content === "string" ? msg.content : toAnthropicAssistantContent(
|
|
1201
|
+
applyServerFallbackReplay(msg.content, keepFallbackBlocks, droppedToolCallIds),
|
|
1202
|
+
msgIdx > trajectoryStartIdx,
|
|
1203
|
+
idMap
|
|
1204
|
+
);
|
|
1013
1205
|
if (Array.isArray(content) && content.length === 0) continue;
|
|
1014
1206
|
out.push({ role: "assistant", content });
|
|
1015
1207
|
continue;
|
|
1016
1208
|
}
|
|
1017
1209
|
if (msg.role === "tool") {
|
|
1210
|
+
const results = droppedToolCallIds.size ? msg.content.filter((r) => !droppedToolCallIds.has(r.toolCallId)) : msg.content;
|
|
1211
|
+
if (results.length === 0) continue;
|
|
1018
1212
|
out.push({
|
|
1019
1213
|
role: "user",
|
|
1020
1214
|
// Cast covers the video block (used by the Anthropic-compatible MiniMax
|
|
1021
1215
|
// API), which isn't in the first-party Anthropic tool_result types.
|
|
1022
|
-
content:
|
|
1216
|
+
content: results.map((result) => ({
|
|
1023
1217
|
type: "tool_result",
|
|
1024
1218
|
tool_use_id: remapAnthropicToolCallId(result.toolCallId, idMap),
|
|
1025
1219
|
content: toAnthropicToolResultContent(result.content),
|
|
@@ -1359,6 +1553,48 @@ function fineGrainedToolStreamingEnabled() {
|
|
|
1359
1553
|
const v = raw.trim().toLowerCase();
|
|
1360
1554
|
return v === "1" || v === "true" || v === "yes" || v === "on";
|
|
1361
1555
|
}
|
|
1556
|
+
var SERVER_FALLBACK_BETA = "server-side-fallback-2026-07-01";
|
|
1557
|
+
var anthropicServerFallback = {
|
|
1558
|
+
disabled: /* @__PURE__ */ new Set(),
|
|
1559
|
+
reset() {
|
|
1560
|
+
this.disabled.clear();
|
|
1561
|
+
}
|
|
1562
|
+
};
|
|
1563
|
+
function serverFallbackKey(options) {
|
|
1564
|
+
const auth = options.apiKey?.startsWith("sk-ant-oat") ? "oauth" : "key";
|
|
1565
|
+
return `${options.baseUrl ?? process.env.ANTHROPIC_BASE_URL ?? ""}|${auth}`;
|
|
1566
|
+
}
|
|
1567
|
+
function isDirectAnthropicApi(baseUrl) {
|
|
1568
|
+
const effective = baseUrl ?? process.env.ANTHROPIC_BASE_URL;
|
|
1569
|
+
if (!effective) return true;
|
|
1570
|
+
try {
|
|
1571
|
+
const url = new URL(effective);
|
|
1572
|
+
return url.protocol === "https:" && url.hostname === "api.anthropic.com";
|
|
1573
|
+
} catch {
|
|
1574
|
+
return false;
|
|
1575
|
+
}
|
|
1576
|
+
}
|
|
1577
|
+
function isServerFallbackRejection(err) {
|
|
1578
|
+
const status = err?.status;
|
|
1579
|
+
if (status !== 400) return false;
|
|
1580
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1581
|
+
return /fallbacks|server-side-fallback/i.test(message);
|
|
1582
|
+
}
|
|
1583
|
+
function sumUsageIterations(usage) {
|
|
1584
|
+
const iterations = usage?.iterations;
|
|
1585
|
+
if (!Array.isArray(iterations) || iterations.length === 0) return null;
|
|
1586
|
+
const num = (v) => typeof v === "number" && Number.isFinite(v) ? v : 0;
|
|
1587
|
+
const totals = { inputTokens: 0, outputTokens: 0, cacheRead: 0, cacheWrite: 0 };
|
|
1588
|
+
for (const it of iterations) {
|
|
1589
|
+
if (!it || typeof it !== "object") continue;
|
|
1590
|
+
const rec = it;
|
|
1591
|
+
totals.inputTokens += num(rec.input_tokens);
|
|
1592
|
+
totals.outputTokens += num(rec.output_tokens);
|
|
1593
|
+
totals.cacheRead += num(rec.cache_read_input_tokens);
|
|
1594
|
+
totals.cacheWrite += num(rec.cache_creation_input_tokens);
|
|
1595
|
+
}
|
|
1596
|
+
return totals;
|
|
1597
|
+
}
|
|
1362
1598
|
function createClient(options) {
|
|
1363
1599
|
const isOAuth = options.apiKey?.startsWith("sk-ant-oat");
|
|
1364
1600
|
const userAgent = isOAuth ? options.userAgent ?? "claude-cli/2.1.75 (external, cli)" : "";
|
|
@@ -1455,7 +1691,11 @@ async function* runStream(options) {
|
|
|
1455
1691
|
const supportsFirstPartyToolExtras = !options.baseUrl || options.baseUrl.includes("api.anthropic.com");
|
|
1456
1692
|
const downgradedImages = downgradeUnsupportedImages(options.messages, options.supportsImages);
|
|
1457
1693
|
const downgradedMessages = downgradeUnsupportedVideos(downgradedImages, options.supportsVideo);
|
|
1458
|
-
const
|
|
1694
|
+
const fallbackKey = serverFallbackKey(options);
|
|
1695
|
+
const useServerFallback = options.provider !== "minimax" && isDirectAnthropicApi(options.baseUrl) && !anthropicServerFallback.disabled.has(fallbackKey);
|
|
1696
|
+
const { system: rawSystem, messages } = toAnthropicMessages(downgradedMessages, cacheControl, {
|
|
1697
|
+
fallbackBlocks: useServerFallback
|
|
1698
|
+
});
|
|
1459
1699
|
const system = isOAuth ? [
|
|
1460
1700
|
{
|
|
1461
1701
|
type: "text",
|
|
@@ -1525,6 +1765,7 @@ async function* runStream(options) {
|
|
|
1525
1765
|
];
|
|
1526
1766
|
return contextEdits.length ? { context_management: { edits: contextEdits } } : {};
|
|
1527
1767
|
})(),
|
|
1768
|
+
...useServerFallback ? { fallbacks: "default" } : {},
|
|
1528
1769
|
stream: useStreaming
|
|
1529
1770
|
};
|
|
1530
1771
|
const hasAdaptiveThinking = isAdaptiveThinkingModel(options.model);
|
|
@@ -1541,20 +1782,41 @@ async function* runStream(options) {
|
|
|
1541
1782
|
// it Anthropic silently ignores ttl:"1h" and falls back to the 5-min default,
|
|
1542
1783
|
// so a pre-warmed cache expires before the user's first turn. cacheControl.ttl
|
|
1543
1784
|
// is only "1h" on the first-party endpoint (see toAnthropicCacheControl).
|
|
1544
|
-
...cacheControl?.ttl === "1h" ? ["extended-cache-ttl-2025-04-11"] : []
|
|
1785
|
+
...cacheControl?.ttl === "1h" ? ["extended-cache-ttl-2025-04-11"] : [],
|
|
1786
|
+
...useServerFallback ? [SERVER_FALLBACK_BETA] : []
|
|
1545
1787
|
];
|
|
1546
|
-
const
|
|
1788
|
+
const toRequestOptions = (betas) => ({
|
|
1547
1789
|
signal: options.signal ?? void 0,
|
|
1548
|
-
...
|
|
1790
|
+
...betas.length ? { headers: { "anthropic-beta": betas.join(",") } } : {}
|
|
1791
|
+
});
|
|
1792
|
+
const requestOptions = toRequestOptions(betaHeaders);
|
|
1793
|
+
const send = async (create) => {
|
|
1794
|
+
try {
|
|
1795
|
+
return await create(params, requestOptions);
|
|
1796
|
+
} catch (err) {
|
|
1797
|
+
if (!useServerFallback || !isServerFallbackRejection(err)) throw err;
|
|
1798
|
+
anthropicServerFallback.disabled.add(fallbackKey);
|
|
1799
|
+
const { fallbacks: _dropped, ...rest } = params;
|
|
1800
|
+
const retryParams = {
|
|
1801
|
+
...rest,
|
|
1802
|
+
messages: toAnthropicMessages(downgradedMessages, cacheControl, { fallbackBlocks: false }).messages
|
|
1803
|
+
};
|
|
1804
|
+
return create(
|
|
1805
|
+
retryParams,
|
|
1806
|
+
toRequestOptions(betaHeaders.filter((b) => b !== SERVER_FALLBACK_BETA))
|
|
1807
|
+
);
|
|
1808
|
+
}
|
|
1549
1809
|
};
|
|
1550
1810
|
if (!useStreaming) {
|
|
1551
1811
|
try {
|
|
1552
1812
|
const nonStreamingClient = client.withOptions({
|
|
1553
1813
|
timeout: NON_STREAMING_REQUEST_TIMEOUT_MS
|
|
1554
1814
|
});
|
|
1555
|
-
const message = await
|
|
1556
|
-
|
|
1557
|
-
|
|
1815
|
+
const message = await send(
|
|
1816
|
+
(p, o) => nonStreamingClient.messages.create(
|
|
1817
|
+
{ ...p, stream: false },
|
|
1818
|
+
o
|
|
1819
|
+
)
|
|
1558
1820
|
);
|
|
1559
1821
|
yield* synthesizeEventsFromMessage(message);
|
|
1560
1822
|
return messageToResponse(message);
|
|
@@ -1572,9 +1834,8 @@ async function* runStream(options) {
|
|
|
1572
1834
|
const keepalive = { type: "keepalive" };
|
|
1573
1835
|
let receivedAnyEvent = false;
|
|
1574
1836
|
try {
|
|
1575
|
-
const stream2 = await
|
|
1576
|
-
|
|
1577
|
-
requestOptions
|
|
1837
|
+
const stream2 = await send(
|
|
1838
|
+
(p, o) => client.messages.create(p, o)
|
|
1578
1839
|
);
|
|
1579
1840
|
for await (const event of stream2) {
|
|
1580
1841
|
receivedAnyEvent = true;
|
|
@@ -1752,6 +2013,13 @@ async function* runStream(options) {
|
|
|
1752
2013
|
if (usage?.output_tokens != null) {
|
|
1753
2014
|
outputTokens = usage.output_tokens;
|
|
1754
2015
|
}
|
|
2016
|
+
const totals = sumUsageIterations(usage);
|
|
2017
|
+
if (totals) {
|
|
2018
|
+
inputTokens = totals.inputTokens;
|
|
2019
|
+
outputTokens = totals.outputTokens;
|
|
2020
|
+
cacheRead = totals.cacheRead;
|
|
2021
|
+
cacheWrite = totals.cacheWrite;
|
|
2022
|
+
}
|
|
1755
2023
|
yield keepalive;
|
|
1756
2024
|
break;
|
|
1757
2025
|
}
|
|
@@ -1881,10 +2149,11 @@ function messageToResponse(message) {
|
|
|
1881
2149
|
}
|
|
1882
2150
|
}
|
|
1883
2151
|
const usage = message.usage;
|
|
1884
|
-
const
|
|
1885
|
-
const
|
|
1886
|
-
const
|
|
1887
|
-
const
|
|
2152
|
+
const totals = sumUsageIterations(usage);
|
|
2153
|
+
const inputTokens = totals?.inputTokens ?? usage.input_tokens ?? 0;
|
|
2154
|
+
const outputTokens = totals?.outputTokens ?? usage.output_tokens ?? 0;
|
|
2155
|
+
const cacheRead = totals?.cacheRead ?? usage.cache_read_input_tokens;
|
|
2156
|
+
const cacheWrite = totals?.cacheWrite ?? usage.cache_creation_input_tokens;
|
|
1888
2157
|
return {
|
|
1889
2158
|
message: {
|
|
1890
2159
|
role: "assistant",
|
|
@@ -4092,15 +4361,23 @@ function stream(options) {
|
|
|
4092
4361
|
throw new VideoUnsupportedError();
|
|
4093
4362
|
}
|
|
4094
4363
|
const wireMessages = stripMessageProvenance(options.messages);
|
|
4095
|
-
const
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
options.
|
|
4364
|
+
const sanitized = sanitizeMessagesForWire(wireMessages);
|
|
4365
|
+
const replayable = dropInvalidToolCalls(
|
|
4366
|
+
sanitized,
|
|
4367
|
+
toolCallNameRuleFor(options.provider, {
|
|
4368
|
+
accountId: options.accountId,
|
|
4369
|
+
baseUrl: options.baseUrl
|
|
4370
|
+
})
|
|
4099
4371
|
);
|
|
4372
|
+
const messages = clampProviderContextImages(replayable, options.provider, options.supportsImages);
|
|
4100
4373
|
if (options.onContextPrepared) {
|
|
4101
4374
|
try {
|
|
4102
4375
|
options.onContextPrepared(
|
|
4103
|
-
observePreparedContext(
|
|
4376
|
+
observePreparedContext(
|
|
4377
|
+
replayable === sanitized ? wireMessages : replayable,
|
|
4378
|
+
messages,
|
|
4379
|
+
options.tools ?? []
|
|
4380
|
+
)
|
|
4104
4381
|
);
|
|
4105
4382
|
} catch {
|
|
4106
4383
|
}
|
|
@@ -4516,14 +4793,17 @@ function registerPalsuProvider(config) {
|
|
|
4516
4793
|
ProviderError,
|
|
4517
4794
|
REDACTION_MARKER,
|
|
4518
4795
|
StreamResult,
|
|
4796
|
+
TOOL_CALL_NAME_RULES,
|
|
4519
4797
|
clampProviderContextImages,
|
|
4520
4798
|
classifyProviderError,
|
|
4799
|
+
dropInvalidToolCalls,
|
|
4521
4800
|
environmentSecrets,
|
|
4522
4801
|
formatError,
|
|
4523
4802
|
formatErrorForDisplay,
|
|
4524
4803
|
hasLoneSurrogate,
|
|
4525
4804
|
isHardBillingMessage,
|
|
4526
4805
|
isUsageLimitError,
|
|
4806
|
+
isValidToolCallName,
|
|
4527
4807
|
localWireModelId,
|
|
4528
4808
|
palsuAssistantMessage,
|
|
4529
4809
|
palsuText,
|
|
@@ -4542,6 +4822,7 @@ function registerPalsuProvider(config) {
|
|
|
4542
4822
|
stream,
|
|
4543
4823
|
toAnthropicMessages,
|
|
4544
4824
|
toOpenAIMessages,
|
|
4545
|
-
toWellFormedText
|
|
4825
|
+
toWellFormedText,
|
|
4826
|
+
toolCallNameRuleFor
|
|
4546
4827
|
});
|
|
4547
4828
|
//# sourceMappingURL=index.cjs.map
|