anygate 0.5.4 → 0.5.6
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/{chunk-E2MV3GDX.js → chunk-ZEO4BR64.js} +234 -36
- package/dist/chunk-ZEO4BR64.js.map +1 -0
- package/dist/cli.js +75 -3
- package/dist/cli.js.map +1 -1
- package/dist/{command-GJYPBC6E.js → command-PW7KW3PP.js} +5 -3
- package/dist/command-PW7KW3PP.js.map +1 -0
- package/dist/ui/dist/assets/index-CfL9bOYD.css +1 -0
- package/dist/ui/dist/assets/index-Ck-e8hv_.js +5 -0
- package/dist/ui/dist/index.html +2 -2
- package/package.json +1 -1
- package/dist/chunk-E2MV3GDX.js.map +0 -1
- package/dist/command-GJYPBC6E.js.map +0 -1
- package/dist/ui/dist/assets/index-BXZwvwW9.css +0 -1
- package/dist/ui/dist/assets/index-CRD31gqp.js +0 -5
|
@@ -10,7 +10,7 @@ import { join } from "path";
|
|
|
10
10
|
// package.json
|
|
11
11
|
var package_default = {
|
|
12
12
|
name: "anygate",
|
|
13
|
-
version: "0.5.
|
|
13
|
+
version: "0.5.6",
|
|
14
14
|
publishConfig: {
|
|
15
15
|
access: "public"
|
|
16
16
|
},
|
|
@@ -3780,6 +3780,41 @@ function findModelsDevModel(providerId, modelId, cache = loadModelsDevCache()) {
|
|
|
3780
3780
|
}
|
|
3781
3781
|
return null;
|
|
3782
3782
|
}
|
|
3783
|
+
var MULTIMODAL_FAMILIES = [
|
|
3784
|
+
/nvidia.*nemotron/i,
|
|
3785
|
+
/^gpt-/i,
|
|
3786
|
+
/^o[0-9]/i,
|
|
3787
|
+
// o1, o3, o4, o-series
|
|
3788
|
+
/gpt-5/i,
|
|
3789
|
+
/gemini/i,
|
|
3790
|
+
/claude/i,
|
|
3791
|
+
/sonnet/i,
|
|
3792
|
+
/opus/i,
|
|
3793
|
+
/haiku/i,
|
|
3794
|
+
/llama.*vision/i,
|
|
3795
|
+
/(vision|multimodal)/i,
|
|
3796
|
+
/qwen.*vl/i,
|
|
3797
|
+
/qwen2?-vl/i,
|
|
3798
|
+
/deepseek.*vl/i,
|
|
3799
|
+
/mistral.*(vision|pixtral)/i,
|
|
3800
|
+
/pixtral/i,
|
|
3801
|
+
/grok.*vision/i,
|
|
3802
|
+
/(command|cohere).*vision/i
|
|
3803
|
+
];
|
|
3804
|
+
function familyMatchesMultimodal(family, modelId) {
|
|
3805
|
+
const hay = `${family} ${modelId}`;
|
|
3806
|
+
return MULTIMODAL_FAMILIES.some((re) => re.test(hay));
|
|
3807
|
+
}
|
|
3808
|
+
function resolveInputTypes(family, providerId, modelId, cache = loadModelsDevCache()) {
|
|
3809
|
+
const entry = findModelsDevModel(providerId, modelId, cache);
|
|
3810
|
+
const baseInput = entry?.modalities?.input && entry.modalities.input.length > 0 ? [...entry.modalities.input] : null;
|
|
3811
|
+
if (baseInput && baseInput.every((t) => t === "text") && !familyMatchesMultimodal(family, modelId)) {
|
|
3812
|
+
return ["text"];
|
|
3813
|
+
}
|
|
3814
|
+
const result = new Set(baseInput ?? ["text"]);
|
|
3815
|
+
if (familyMatchesMultimodal(family, modelId)) result.add("image");
|
|
3816
|
+
return [...result];
|
|
3817
|
+
}
|
|
3783
3818
|
function shouldHideByModelsDevCapabilities(entry) {
|
|
3784
3819
|
const output = entry.modalities?.output;
|
|
3785
3820
|
if (output && output.length > 0 && !output.includes("text")) return true;
|
|
@@ -3981,7 +4016,7 @@ function maskGatewayModelId(aliasId) {
|
|
|
3981
4016
|
// src/gateway/models.ts
|
|
3982
4017
|
var CREATED_AT_ISO = "2025-01-01T00:00:00Z";
|
|
3983
4018
|
var CREATED_AT_UNIX = 1735689600;
|
|
3984
|
-
function formatAnthropicModelEntry(id, displayName, contextWindow) {
|
|
4019
|
+
function formatAnthropicModelEntry(id, displayName, contextWindow, inputTypes) {
|
|
3985
4020
|
const maxInput = resolveContextWindow(id, contextWindow);
|
|
3986
4021
|
return {
|
|
3987
4022
|
id,
|
|
@@ -3989,12 +4024,13 @@ function formatAnthropicModelEntry(id, displayName, contextWindow) {
|
|
|
3989
4024
|
display_name: displayName,
|
|
3990
4025
|
created_at: CREATED_AT_ISO,
|
|
3991
4026
|
context_window: maxInput,
|
|
3992
|
-
max_input_tokens: maxInput
|
|
4027
|
+
max_input_tokens: maxInput,
|
|
4028
|
+
input_types: inputTypes ?? ["text"]
|
|
3993
4029
|
};
|
|
3994
4030
|
}
|
|
3995
4031
|
function formatAnthropicModelList(entries) {
|
|
3996
4032
|
return {
|
|
3997
|
-
data: entries.map((entry) => formatAnthropicModelEntry(entry.id, entry.name, entry.contextWindow)),
|
|
4033
|
+
data: entries.map((entry) => formatAnthropicModelEntry(entry.id, entry.name, entry.contextWindow, entry.inputTypes)),
|
|
3998
4034
|
has_more: false,
|
|
3999
4035
|
first_id: entries[0]?.id ?? null,
|
|
4000
4036
|
last_id: entries.at(-1)?.id ?? null
|
|
@@ -4022,7 +4058,8 @@ function formatGatewayAnthropicModels(models, opts) {
|
|
|
4022
4058
|
models.map((model) => ({
|
|
4023
4059
|
id: exposedGatewayAliasId(model, opts),
|
|
4024
4060
|
name: gatewayDisplayName(model, opts),
|
|
4025
|
-
contextWindow: model.contextWindow
|
|
4061
|
+
contextWindow: model.contextWindow,
|
|
4062
|
+
inputTypes: model.supportedParameters?.includes("image") ? ["text", "image"] : ["text"]
|
|
4026
4063
|
}))
|
|
4027
4064
|
);
|
|
4028
4065
|
}
|
|
@@ -4782,8 +4819,8 @@ function getUsage(chunk) {
|
|
|
4782
4819
|
const u = resp?.usageMetadata;
|
|
4783
4820
|
if (!u) return null;
|
|
4784
4821
|
return {
|
|
4785
|
-
|
|
4786
|
-
|
|
4822
|
+
inputTokens: u.promptTokenCount ?? 0,
|
|
4823
|
+
outputTokens: u.candidatesTokenCount ?? 0
|
|
4787
4824
|
};
|
|
4788
4825
|
}
|
|
4789
4826
|
function partThoughtSignature(part) {
|
|
@@ -4842,7 +4879,7 @@ async function streamCloudCodeToAnthropic(res, upstreamRes, model, log7) {
|
|
|
4842
4879
|
textBlockOpen: false,
|
|
4843
4880
|
pendingThoughtSignature: void 0,
|
|
4844
4881
|
toolCalls: [],
|
|
4845
|
-
usage: {
|
|
4882
|
+
usage: { inputTokens: 0, outputTokens: 0 },
|
|
4846
4883
|
emittedTextChars: 0,
|
|
4847
4884
|
suppressedThoughtChars: 0
|
|
4848
4885
|
};
|
|
@@ -4869,7 +4906,7 @@ async function streamCloudCodeToAnthropic(res, upstreamRes, model, log7) {
|
|
|
4869
4906
|
writeEvent(res, "message_delta", { type: "message_delta", delta: { stop_reason: "end_turn", stop_sequence: null }, usage: { output_tokens: 0 } });
|
|
4870
4907
|
writeEvent(res, "message_stop", { type: "message_stop" });
|
|
4871
4908
|
res.end();
|
|
4872
|
-
return;
|
|
4909
|
+
return state.usage;
|
|
4873
4910
|
}
|
|
4874
4911
|
const reader = upstreamRes.body.getReader();
|
|
4875
4912
|
const decoder = new TextDecoder();
|
|
@@ -4919,7 +4956,7 @@ async function streamCloudCodeToAnthropic(res, upstreamRes, model, log7) {
|
|
|
4919
4956
|
finalStopReason = mapStopReason(finishReason);
|
|
4920
4957
|
log7?.(() => {
|
|
4921
4958
|
const toolNames = state.toolCalls.map((tc) => tc.name).filter(Boolean).join(",");
|
|
4922
|
-
return `cloud-code stream finish=${finishReason} mapped=${finalStopReason} ${summarizeParts(parts)} emittedTextChars=${state.emittedTextChars} suppressedThoughtChars=${state.suppressedThoughtChars} queuedToolCalls=${state.toolCalls.length} queuedToolNames=${toolNames || "-"} outputTokens=${state.usage.
|
|
4959
|
+
return `cloud-code stream finish=${finishReason} mapped=${finalStopReason} ${summarizeParts(parts)} emittedTextChars=${state.emittedTextChars} suppressedThoughtChars=${state.suppressedThoughtChars} queuedToolCalls=${state.toolCalls.length} queuedToolNames=${toolNames || "-"} outputTokens=${state.usage.outputTokens}`;
|
|
4923
4960
|
});
|
|
4924
4961
|
if (state.textBlockOpen) {
|
|
4925
4962
|
closeBlock(res, state);
|
|
@@ -4951,11 +4988,11 @@ async function streamCloudCodeToAnthropic(res, upstreamRes, model, log7) {
|
|
|
4951
4988
|
writeEvent(res, "message_delta", {
|
|
4952
4989
|
type: "message_delta",
|
|
4953
4990
|
delta: { stop_reason: anthropicStopReason, stop_sequence: null },
|
|
4954
|
-
usage: { output_tokens: state.usage.
|
|
4991
|
+
usage: { output_tokens: state.usage.outputTokens }
|
|
4955
4992
|
});
|
|
4956
4993
|
writeEvent(res, "message_stop", { type: "message_stop" });
|
|
4957
4994
|
res.end();
|
|
4958
|
-
return;
|
|
4995
|
+
return state.usage;
|
|
4959
4996
|
}
|
|
4960
4997
|
}
|
|
4961
4998
|
}
|
|
@@ -4969,10 +5006,11 @@ async function streamCloudCodeToAnthropic(res, upstreamRes, model, log7) {
|
|
|
4969
5006
|
writeEvent(res, "message_delta", {
|
|
4970
5007
|
type: "message_delta",
|
|
4971
5008
|
delta: { stop_reason: finalStopReason, stop_sequence: null },
|
|
4972
|
-
usage: { output_tokens: state.usage.
|
|
5009
|
+
usage: { output_tokens: state.usage.outputTokens }
|
|
4973
5010
|
});
|
|
4974
5011
|
writeEvent(res, "message_stop", { type: "message_stop" });
|
|
4975
5012
|
res.end();
|
|
5013
|
+
return state.usage;
|
|
4976
5014
|
}
|
|
4977
5015
|
async function collectCloudCodeToAnthropic(upstreamRes, model, log7) {
|
|
4978
5016
|
const text4 = await upstreamRes.text();
|
|
@@ -4988,8 +5026,8 @@ async function collectCloudCodeToAnthropic(upstreamRes, model, log7) {
|
|
|
4988
5026
|
if (!chunk) continue;
|
|
4989
5027
|
const usage = getUsage(chunk);
|
|
4990
5028
|
if (usage) {
|
|
4991
|
-
inputTokens = usage.
|
|
4992
|
-
outputTokens = usage.
|
|
5029
|
+
inputTokens = usage.inputTokens;
|
|
5030
|
+
outputTokens = usage.outputTokens;
|
|
4993
5031
|
}
|
|
4994
5032
|
const candidate = getCandidate(chunk);
|
|
4995
5033
|
if (!candidate) continue;
|
|
@@ -5033,7 +5071,9 @@ async function collectCloudCodeToAnthropic(upstreamRes, model, log7) {
|
|
|
5033
5071
|
model,
|
|
5034
5072
|
stop_reason: stopReason,
|
|
5035
5073
|
stop_sequence: null,
|
|
5036
|
-
usage: { input_tokens: inputTokens, output_tokens: outputTokens }
|
|
5074
|
+
usage: { input_tokens: inputTokens, output_tokens: outputTokens },
|
|
5075
|
+
inputTokens,
|
|
5076
|
+
outputTokens
|
|
5037
5077
|
};
|
|
5038
5078
|
}
|
|
5039
5079
|
|
|
@@ -5100,6 +5140,94 @@ function resolveUpstreamTools(tools, messages) {
|
|
|
5100
5140
|
return upstream;
|
|
5101
5141
|
}
|
|
5102
5142
|
|
|
5143
|
+
// src/gateway/context-fit.ts
|
|
5144
|
+
var CHARS_PER_TOKEN = 4;
|
|
5145
|
+
var RESERVE_TOKENS = 256;
|
|
5146
|
+
function estimateTokens(text4) {
|
|
5147
|
+
return Math.ceil(text4.length / CHARS_PER_TOKEN);
|
|
5148
|
+
}
|
|
5149
|
+
function messageTokens(msg) {
|
|
5150
|
+
if (typeof msg.content === "string") return estimateTokens(msg.content);
|
|
5151
|
+
let total = 0;
|
|
5152
|
+
for (const block of msg.content) {
|
|
5153
|
+
if (typeof block.text === "string") {
|
|
5154
|
+
total += estimateTokens(block.text);
|
|
5155
|
+
}
|
|
5156
|
+
if (block.source?.data) {
|
|
5157
|
+
total += Math.max(512, estimateTokens(block.source.data));
|
|
5158
|
+
}
|
|
5159
|
+
if (typeof block.input === "object" && block.input !== null) {
|
|
5160
|
+
try {
|
|
5161
|
+
total += estimateTokens(JSON.stringify(block.input));
|
|
5162
|
+
} catch {
|
|
5163
|
+
}
|
|
5164
|
+
}
|
|
5165
|
+
}
|
|
5166
|
+
return total;
|
|
5167
|
+
}
|
|
5168
|
+
function estimateContextTokens(system, messages) {
|
|
5169
|
+
let total = estimateTokens(system ?? "");
|
|
5170
|
+
for (const msg of messages) total += messageTokens(msg);
|
|
5171
|
+
return total;
|
|
5172
|
+
}
|
|
5173
|
+
function fitContextWindow(messages, system, contextWindow, maxOutputTokens) {
|
|
5174
|
+
const systemTokens = estimateTokens(system ?? "");
|
|
5175
|
+
const budget = contextWindow - maxOutputTokens - RESERVE_TOKENS;
|
|
5176
|
+
if (budget <= 0) {
|
|
5177
|
+
return { system, messages, trimmed: false, dropped: 0 };
|
|
5178
|
+
}
|
|
5179
|
+
const usable = budget - systemTokens;
|
|
5180
|
+
if (usable <= 0) {
|
|
5181
|
+
return { system, messages, trimmed: false, dropped: 0 };
|
|
5182
|
+
}
|
|
5183
|
+
const kept = [];
|
|
5184
|
+
let used = 0;
|
|
5185
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
5186
|
+
const msg = messages[i];
|
|
5187
|
+
const cost = messageTokens(msg);
|
|
5188
|
+
if (used + cost > usable && kept.length > 0) break;
|
|
5189
|
+
kept.unshift(msg);
|
|
5190
|
+
used += cost;
|
|
5191
|
+
}
|
|
5192
|
+
const toolUseIds = /* @__PURE__ */ new Set();
|
|
5193
|
+
const toolResultIds = /* @__PURE__ */ new Set();
|
|
5194
|
+
for (const msg of kept) {
|
|
5195
|
+
if (!Array.isArray(msg.content)) continue;
|
|
5196
|
+
for (const b of msg.content) {
|
|
5197
|
+
if (b.type === "tool_use" && b.id) toolUseIds.add(b.id);
|
|
5198
|
+
if (b.type === "tool_result" && b.tool_use_id) toolResultIds.add(b.tool_use_id);
|
|
5199
|
+
}
|
|
5200
|
+
}
|
|
5201
|
+
const orphanResult = kept.filter((msg) => {
|
|
5202
|
+
if (!Array.isArray(msg.content)) return false;
|
|
5203
|
+
return msg.content.some((b) => b.type === "tool_result" && b.tool_use_id && !toolUseIds.has(b.tool_use_id));
|
|
5204
|
+
});
|
|
5205
|
+
const orphanUse = kept.filter((msg) => {
|
|
5206
|
+
if (!Array.isArray(msg.content)) return false;
|
|
5207
|
+
return msg.content.some((b) => b.type === "tool_use" && b.id && !toolResultIds.has(b.id));
|
|
5208
|
+
});
|
|
5209
|
+
let trimmedMessages = kept;
|
|
5210
|
+
if (orphanResult.length || orphanUse.length) {
|
|
5211
|
+
const dropIds = /* @__PURE__ */ new Set();
|
|
5212
|
+
for (const msg of [...orphanResult, ...orphanUse]) {
|
|
5213
|
+
for (const b of msg.content) {
|
|
5214
|
+
if (b.id) dropIds.add(b.id);
|
|
5215
|
+
if (b.tool_use_id) dropIds.add(b.tool_use_id);
|
|
5216
|
+
}
|
|
5217
|
+
}
|
|
5218
|
+
trimmedMessages = trimmedMessages.filter(
|
|
5219
|
+
(msg) => !msg.content || !Array.isArray(msg.content) || !msg.content.some((b) => b.id && dropIds.has(b.id) || b.tool_use_id && dropIds.has(b.tool_use_id))
|
|
5220
|
+
);
|
|
5221
|
+
}
|
|
5222
|
+
const dropped = messages.length - trimmedMessages.length;
|
|
5223
|
+
return {
|
|
5224
|
+
system,
|
|
5225
|
+
messages: trimmedMessages,
|
|
5226
|
+
trimmed: dropped > 0,
|
|
5227
|
+
dropped
|
|
5228
|
+
};
|
|
5229
|
+
}
|
|
5230
|
+
|
|
5103
5231
|
// src/gateway/sdk-adapter.ts
|
|
5104
5232
|
function anthropicEffortFromRequest(body) {
|
|
5105
5233
|
const effort = body.output_config?.effort;
|
|
@@ -5237,11 +5365,32 @@ function translateToolChoice(tc) {
|
|
|
5237
5365
|
return void 0;
|
|
5238
5366
|
}
|
|
5239
5367
|
function translateRequest2(body, npm, options) {
|
|
5240
|
-
|
|
5368
|
+
let messages = body.messages ?? [];
|
|
5241
5369
|
annotateToolNames(messages);
|
|
5242
5370
|
const baseSystem = systemToString(body.system);
|
|
5243
5371
|
const inlineParts = inlineSystemText(messages);
|
|
5244
5372
|
const systemText = [baseSystem, ...inlineParts].filter((s) => s && s.trim()).join("\n\n") || (options?.openAiOAuth ? "You are a coding assistant." : void 0);
|
|
5373
|
+
let trimmedSystem = systemText;
|
|
5374
|
+
let maxOutput = options?.openAiOAuth ? void 0 : body.max_tokens;
|
|
5375
|
+
if (options?.contextWindow && options.contextWindow > 0) {
|
|
5376
|
+
const { system: fittedSystem, messages: fittedMessages, trimmed } = fitContextWindow(
|
|
5377
|
+
messages,
|
|
5378
|
+
systemText,
|
|
5379
|
+
options.contextWindow,
|
|
5380
|
+
typeof maxOutput === "number" ? maxOutput : 0
|
|
5381
|
+
);
|
|
5382
|
+
if (trimmed) {
|
|
5383
|
+
messages = fittedMessages;
|
|
5384
|
+
annotateToolNames(messages);
|
|
5385
|
+
const fittedInline = inlineSystemText(messages);
|
|
5386
|
+
trimmedSystem = [fittedSystem, ...fittedInline].filter((s) => s && s.trim()).join("\n\n") || (options?.openAiOAuth ? "You are a coding assistant." : void 0);
|
|
5387
|
+
if (typeof maxOutput === "number") {
|
|
5388
|
+
const fittedInputTokens = estimateContextTokens(fittedSystem ?? "", fittedMessages);
|
|
5389
|
+
const headroom = options.contextWindow - fittedInputTokens - 256;
|
|
5390
|
+
if (headroom > 0 && maxOutput > headroom) maxOutput = headroom;
|
|
5391
|
+
}
|
|
5392
|
+
}
|
|
5393
|
+
}
|
|
5245
5394
|
let upstreamTools = resolveUpstreamTools(
|
|
5246
5395
|
body.tools,
|
|
5247
5396
|
messages
|
|
@@ -5260,11 +5409,11 @@ function translateRequest2(body, npm, options) {
|
|
|
5260
5409
|
});
|
|
5261
5410
|
}
|
|
5262
5411
|
return {
|
|
5263
|
-
system: options?.openAiOAuth ? void 0 :
|
|
5412
|
+
system: options?.openAiOAuth ? void 0 : trimmedSystem,
|
|
5264
5413
|
messages: translateMessages(messages, npm),
|
|
5265
5414
|
tools: translateTools3(upstreamTools.length ? upstreamTools : void 0),
|
|
5266
5415
|
toolChoice: translateToolChoice(body.tool_choice),
|
|
5267
|
-
maxOutputTokens: options?.openAiOAuth ? void 0 :
|
|
5416
|
+
maxOutputTokens: options?.openAiOAuth ? void 0 : maxOutput,
|
|
5268
5417
|
temperature: body.temperature,
|
|
5269
5418
|
providerOptions
|
|
5270
5419
|
};
|
|
@@ -5472,6 +5621,9 @@ async function generateAnthropicResponse(model, params, modelId, options) {
|
|
|
5472
5621
|
import { appendFileSync as appendFileSync2, openSync as openSync2, writeSync as writeSync2, closeSync as closeSync2, readFileSync as readFileSync9, existsSync as existsSync9 } from "fs";
|
|
5473
5622
|
import { join as join9 } from "path";
|
|
5474
5623
|
var ANALYTICS_FILE = "analytics.jsonl";
|
|
5624
|
+
function normalizeModelKey(modelId) {
|
|
5625
|
+
return modelId.toLowerCase().replace(/\//g, ":").replace(/\s*\([^)]*\)\s*$/g, "").replace(/\s+/g, " ").trim();
|
|
5626
|
+
}
|
|
5475
5627
|
function analyticsPath() {
|
|
5476
5628
|
return join9(getAppHome(), ANALYTICS_FILE);
|
|
5477
5629
|
}
|
|
@@ -5576,21 +5728,27 @@ function aggregateAnalytics(range) {
|
|
|
5576
5728
|
const hour = Number(e.ts.slice(11, 13));
|
|
5577
5729
|
if (Number.isFinite(hour) && hour >= 0 && hour < 24) hourCounts[hour] += 1;
|
|
5578
5730
|
const provider = e.providerId ?? e.npm?.replace(/^@/, "").replace(/\//g, "-") ?? "unknown";
|
|
5579
|
-
const key = `${provider}|${e.modelId}`;
|
|
5580
|
-
const m = modelMap.get(key) ?? { provider, model: e.modelId, app: e.app, inputTokens: 0, outputTokens: 0 };
|
|
5731
|
+
const key = `${provider}|${normalizeModelKey(e.modelId)}`;
|
|
5732
|
+
const m = modelMap.get(key) ?? { provider, model: e.modelId, app: e.app, apps: /* @__PURE__ */ new Set(), inputTokens: 0, outputTokens: 0 };
|
|
5733
|
+
if (!/\s/.test(m.model) && /\s/.test(e.modelId)) m.model = e.modelId;
|
|
5581
5734
|
m.inputTokens += e.inputTokens;
|
|
5582
5735
|
m.outputTokens += e.outputTokens;
|
|
5736
|
+
m.apps.add(e.app);
|
|
5583
5737
|
modelMap.set(key, m);
|
|
5584
5738
|
}
|
|
5585
|
-
const busiestDay = Math.max(1, ...[...
|
|
5739
|
+
const busiestDay = Math.max(1, ...[...tokensByDay.values()]);
|
|
5586
5740
|
const heatmap = [];
|
|
5587
5741
|
for (let i = rangeDays(range) - 1; i >= 0; i--) {
|
|
5588
5742
|
const d = new Date(today);
|
|
5589
5743
|
d.setUTCDate(today.getUTCDate() - i);
|
|
5590
5744
|
const date = d.toISOString().slice(0, 10);
|
|
5591
|
-
const
|
|
5592
|
-
|
|
5593
|
-
|
|
5745
|
+
const tokens = tokensByDay.get(date) ?? 0;
|
|
5746
|
+
let intensity = 0;
|
|
5747
|
+
if (tokens > 0) {
|
|
5748
|
+
const pct = tokens / busiestDay;
|
|
5749
|
+
intensity = Math.max(1, Math.min(4, Math.round(1 + pct * 3)));
|
|
5750
|
+
}
|
|
5751
|
+
heatmap.push({ date, count: tokens, intensity });
|
|
5594
5752
|
}
|
|
5595
5753
|
const dailyTokens = [];
|
|
5596
5754
|
for (let i = rangeDays(range) - 1; i >= 0; i--) {
|
|
@@ -5625,12 +5783,14 @@ function aggregateAnalytics(range) {
|
|
|
5625
5783
|
}
|
|
5626
5784
|
const models = [...modelMap.entries()].map(([, m], idx) => {
|
|
5627
5785
|
const share = totalTokens > 0 ? (m.inputTokens + m.outputTokens) / totalTokens : 0;
|
|
5786
|
+
const apps = [...m.apps];
|
|
5628
5787
|
return {
|
|
5629
5788
|
provider: m.provider,
|
|
5630
5789
|
model: m.model,
|
|
5631
5790
|
tier: "",
|
|
5632
5791
|
// source tier isn't tracked in the log; UI shows it from catalog elsewhere
|
|
5633
|
-
app: m.app,
|
|
5792
|
+
app: apps[0] ?? m.app,
|
|
5793
|
+
apps,
|
|
5634
5794
|
inputTokens: m.inputTokens,
|
|
5635
5795
|
outputTokens: m.outputTokens,
|
|
5636
5796
|
share,
|
|
@@ -5684,6 +5844,10 @@ function makeProxyLog(debug, logPath) {
|
|
|
5684
5844
|
appendSecureLog(path, line);
|
|
5685
5845
|
};
|
|
5686
5846
|
}
|
|
5847
|
+
var quietErrorLogPath = getProxyDebugLogPath();
|
|
5848
|
+
function quietErrorLog(line) {
|
|
5849
|
+
appendSecureLog(quietErrorLogPath, `[quiet-error] ${line}`);
|
|
5850
|
+
}
|
|
5687
5851
|
function anthropicError(res, status, message) {
|
|
5688
5852
|
sendJson(res, status, {
|
|
5689
5853
|
type: "error",
|
|
@@ -5693,7 +5857,8 @@ function anthropicError(res, status, message) {
|
|
|
5693
5857
|
function aliasModelId(realId, providerId) {
|
|
5694
5858
|
if (realId.startsWith("claude-")) return realId;
|
|
5695
5859
|
const sanitized = providerId.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
5696
|
-
|
|
5860
|
+
const safeRealId = realId.replace(/[\/\s:()]+/g, "-");
|
|
5861
|
+
return `anthropic-${sanitized}__${safeRealId}`;
|
|
5697
5862
|
}
|
|
5698
5863
|
function lookupRoute(byAlias, id) {
|
|
5699
5864
|
for (const key of routeLookupIds(id)) {
|
|
@@ -5721,7 +5886,7 @@ function startProxyCatalog(routes, defaultAliasId, debug = false) {
|
|
|
5721
5886
|
process.on("uncaughtException", onException);
|
|
5722
5887
|
const modelsPayload = JSON.stringify(
|
|
5723
5888
|
formatAnthropicModelList(
|
|
5724
|
-
routes.map((r) => ({ id: r.aliasId, name: r.displayName, contextWindow: r.contextWindow }))
|
|
5889
|
+
routes.map((r) => ({ id: r.aliasId, name: r.displayName, contextWindow: r.contextWindow, inputTypes: r.inputTypes }))
|
|
5725
5890
|
)
|
|
5726
5891
|
);
|
|
5727
5892
|
const server = createServer(async (req, res) => {
|
|
@@ -5738,8 +5903,9 @@ function startProxyCatalog(routes, defaultAliasId, debug = false) {
|
|
|
5738
5903
|
const route = lookupRoute(byAlias, id);
|
|
5739
5904
|
if (route) {
|
|
5740
5905
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
5741
|
-
res.end(JSON.stringify(formatAnthropicModelEntry(route.aliasId, route.displayName, route.contextWindow)));
|
|
5906
|
+
res.end(JSON.stringify(formatAnthropicModelEntry(route.aliasId, route.displayName, route.contextWindow, route.inputTypes)));
|
|
5742
5907
|
} else {
|
|
5908
|
+
quietErrorLog(`GET /v1/models/${id} - model not found`);
|
|
5743
5909
|
res.writeHead(404, { "Content-Type": "application/json" });
|
|
5744
5910
|
res.end(JSON.stringify({ error: { type: "not_found_error", message: `Model '${id}' not found` } }));
|
|
5745
5911
|
}
|
|
@@ -5766,6 +5932,9 @@ function startProxyCatalog(routes, defaultAliasId, debug = false) {
|
|
|
5766
5932
|
const originalModel = anthropicBody.model;
|
|
5767
5933
|
const clientWantsStream = Boolean(anthropicBody.stream);
|
|
5768
5934
|
const route = lookupRoute(byAlias, originalModel) ?? defaultRoute;
|
|
5935
|
+
if (route === defaultRoute && originalModel !== defaultRoute.aliasId) {
|
|
5936
|
+
quietErrorLog(`POST /v1/messages - model alias '${originalModel}' not found, falling back to default route '${defaultRoute.aliasId}'`);
|
|
5937
|
+
}
|
|
5769
5938
|
const apiKey = route.apiKey;
|
|
5770
5939
|
const upstreamUrl = route.upstreamUrl;
|
|
5771
5940
|
plog(
|
|
@@ -5831,7 +6000,8 @@ function startProxyCatalog(routes, defaultAliasId, debug = false) {
|
|
|
5831
6000
|
reasoning: route.reasoning,
|
|
5832
6001
|
interleavedReasoningField: route.interleavedReasoningField,
|
|
5833
6002
|
upstreamModelId: route.realModelId
|
|
5834
|
-
}
|
|
6003
|
+
},
|
|
6004
|
+
contextWindow: route.contextWindow
|
|
5835
6005
|
});
|
|
5836
6006
|
plog(
|
|
5837
6007
|
() => `sdk: npm=${route.npm} model=${route.realModelId}, stream=${clientWantsStream}, tools=${anthropicBody.tools?.length ?? 0}, msgs=${params.messages.length}`
|
|
@@ -5939,12 +6109,22 @@ data: ${JSON.stringify({ type: "error", error: { type: errorType, message } })}
|
|
|
5939
6109
|
anthropicError(res, upstream.status >= 500 ? 502 : upstream.status, errBody);
|
|
5940
6110
|
return;
|
|
5941
6111
|
}
|
|
6112
|
+
let usage = { inputTokens: 0, outputTokens: 0 };
|
|
5942
6113
|
if (clientWantsStream) {
|
|
5943
|
-
await streamCloudCodeToAnthropic(res, upstream, route.realModelId, plog);
|
|
6114
|
+
usage = await streamCloudCodeToAnthropic(res, upstream, route.realModelId, plog);
|
|
5944
6115
|
} else {
|
|
5945
6116
|
const response = await collectCloudCodeToAnthropic(upstream, route.realModelId, plog);
|
|
6117
|
+
usage = { inputTokens: response.inputTokens ?? 0, outputTokens: response.outputTokens ?? 0 };
|
|
5946
6118
|
sendJson(res, 200, response);
|
|
5947
6119
|
}
|
|
6120
|
+
recordUsage({
|
|
6121
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6122
|
+
modelId: route.realModelId,
|
|
6123
|
+
providerId: route.providerId,
|
|
6124
|
+
app: route.app ?? "Antigravity",
|
|
6125
|
+
inputTokens: usage.inputTokens,
|
|
6126
|
+
outputTokens: usage.outputTokens
|
|
6127
|
+
});
|
|
5948
6128
|
} catch (err) {
|
|
5949
6129
|
const message = err instanceof Error ? err.message : String(err);
|
|
5950
6130
|
plog(() => `cloud-code fetch error: ${message}`);
|
|
@@ -6841,7 +7021,8 @@ function localModelToRoute(lp, model) {
|
|
|
6841
7021
|
reasoning: model.reasoning,
|
|
6842
7022
|
interleavedReasoningField: model.interleavedReasoningField,
|
|
6843
7023
|
useResponsesLite: model.useResponsesLite,
|
|
6844
|
-
preferWebSockets: model.preferWebSockets
|
|
7024
|
+
preferWebSockets: model.preferWebSockets,
|
|
7025
|
+
inputTypes: resolveInputTypes(model.family, lp.id, model.id)
|
|
6845
7026
|
};
|
|
6846
7027
|
}
|
|
6847
7028
|
function makeRouteResolver(localProviders) {
|
|
@@ -7517,7 +7698,8 @@ async function handleAnthropicMessages(req, res, options, modelCache, plog) {
|
|
|
7517
7698
|
interleavedReasoningField: model.interleavedReasoningField,
|
|
7518
7699
|
upstreamModelId: upstreamModelId(model)
|
|
7519
7700
|
},
|
|
7520
|
-
maxTools: npmMaxTools
|
|
7701
|
+
maxTools: npmMaxTools,
|
|
7702
|
+
contextWindow: model.contextWindow ?? resolveContextWindow(model.id)
|
|
7521
7703
|
});
|
|
7522
7704
|
const clientWantsStream = Boolean(body.stream);
|
|
7523
7705
|
const responseModelId = getResponseModelId(body.model, model, options);
|
|
@@ -7559,7 +7741,14 @@ async function handleAnthropicMessages(req, res, options, modelCache, plog) {
|
|
|
7559
7741
|
if (!res.headersSent) {
|
|
7560
7742
|
const status = upstreamHttpStatus(err);
|
|
7561
7743
|
sendJson(res, status === 500 ? 502 : status, { error: { message } });
|
|
7562
|
-
} else
|
|
7744
|
+
} else {
|
|
7745
|
+
const errorType = anthropicErrorType(upstreamHttpStatus(err));
|
|
7746
|
+
res.write(`event: error
|
|
7747
|
+
data: ${JSON.stringify({ type: "error", error: { type: errorType, message } })}
|
|
7748
|
+
|
|
7749
|
+
`);
|
|
7750
|
+
res.end();
|
|
7751
|
+
}
|
|
7563
7752
|
}
|
|
7564
7753
|
return;
|
|
7565
7754
|
}
|
|
@@ -7632,7 +7821,14 @@ async function handleOpenAIChatCompletions(req, res, options, modelCache, plog)
|
|
|
7632
7821
|
if (!res.headersSent) {
|
|
7633
7822
|
const status = upstreamHttpStatus(err);
|
|
7634
7823
|
sendJson(res, status === 500 ? 502 : status, { error: { message } });
|
|
7635
|
-
} else
|
|
7824
|
+
} else {
|
|
7825
|
+
const errorType = anthropicErrorType(upstreamHttpStatus(err));
|
|
7826
|
+
res.write(`event: error
|
|
7827
|
+
data: ${JSON.stringify({ type: "error", error: { type: errorType, message } })}
|
|
7828
|
+
|
|
7829
|
+
`);
|
|
7830
|
+
res.end();
|
|
7831
|
+
}
|
|
7636
7832
|
}
|
|
7637
7833
|
}
|
|
7638
7834
|
function lookupModel(res, catalog, modelId) {
|
|
@@ -10721,6 +10917,7 @@ export {
|
|
|
10721
10917
|
isFreeStatus,
|
|
10722
10918
|
freeStatusLabel,
|
|
10723
10919
|
refreshModelsDevCacheAsync,
|
|
10920
|
+
resolveInputTypes,
|
|
10724
10921
|
shouldHideModel,
|
|
10725
10922
|
cachedModelToLocal,
|
|
10726
10923
|
readBody,
|
|
@@ -10749,6 +10946,7 @@ export {
|
|
|
10749
10946
|
encodeToolUseId,
|
|
10750
10947
|
serializeToolResultContent,
|
|
10751
10948
|
translateRequest,
|
|
10949
|
+
recordUsage,
|
|
10752
10950
|
aggregateAnalytics,
|
|
10753
10951
|
aliasModelId,
|
|
10754
10952
|
startProxyCatalog,
|
|
@@ -10817,4 +11015,4 @@ export {
|
|
|
10817
11015
|
quitClaudeAppGracefully,
|
|
10818
11016
|
launchOrRestartClaudeApp
|
|
10819
11017
|
};
|
|
10820
|
-
//# sourceMappingURL=chunk-
|
|
11018
|
+
//# sourceMappingURL=chunk-ZEO4BR64.js.map
|