@chenpu17/cc-gw 0.5.0 → 0.5.2
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 +95 -2
- package/package.json +3 -2
- package/src/cli/dist/index.js +20 -2
- package/src/server/dist/index.js +251 -121
- package/src/web/dist/assets/{About-DK242vw9.js → About-BkGxQ3Pv.js} +2 -2
- package/src/web/dist/assets/{ApiKeys-BGROxK6-.js → ApiKeys-GdImp523.js} +1 -1
- package/src/web/dist/assets/{Button-Bnnxe9ep.js → Button-BkhovQFd.js} +1 -1
- package/src/web/dist/assets/{Dashboard-B7zokimB.js → Dashboard-DxSNZwZc.js} +1 -1
- package/src/web/dist/assets/{FormField-BzT4FGj8.js → FormField-C-bAE13W.js} +1 -1
- package/src/web/dist/assets/{Help-CJooSMdJ.js → Help-Bj3HXV4H.js} +1 -1
- package/src/web/dist/assets/{Input-B-P-J4xQ.js → Input-B6cOxhbI.js} +1 -1
- package/src/web/dist/assets/{Login-B9RgxiYX.js → Login-Btsbo17f.js} +1 -1
- package/src/web/dist/assets/Logs-72HRZmFi.js +1 -0
- package/src/web/dist/assets/{ModelManagement-dDhNa_5z.js → ModelManagement-cuAzyPgP.js} +1 -1
- package/src/web/dist/assets/{PageSection-Dzvd3cKD.js → PageSection-Bq4tdag3.js} +1 -1
- package/src/web/dist/assets/Settings-DPvX1pD_.js +11 -0
- package/src/web/dist/assets/{StatusBadge-CAkVtC--.js → StatusBadge-P00M_NBZ.js} +1 -1
- package/src/web/dist/assets/{copy-D6cuJHzh.js → copy-D321KBhI.js} +1 -1
- package/src/web/dist/assets/{index-Cm-hZvRJ.js → index-BLBh7aj6.js} +1 -1
- package/src/web/dist/assets/index-DEa23YLm.css +1 -0
- package/src/web/dist/assets/{index-agm-2asf.js → index-DP6DzFEd.js} +30 -30
- package/src/web/dist/assets/{info-CfAuBePJ.js → info-CADQNr0Q.js} +1 -1
- package/src/web/dist/assets/{useApiQuery-ns68sM2H.js → useApiQuery-C5jmZPyb.js} +1 -1
- package/src/web/dist/index.html +2 -2
- package/src/web/dist/assets/Logs-CsJCTftU.js +0 -1
- package/src/web/dist/assets/Settings-BcMQ79b0.js +0 -1
- package/src/web/dist/assets/index-BFd07aus.css +0 -1
package/src/server/dist/index.js
CHANGED
|
@@ -9921,6 +9921,7 @@ var LOG_LEVELS = /* @__PURE__ */ new Set([
|
|
|
9921
9921
|
var HOME_OVERRIDE = process.env.CC_GW_HOME;
|
|
9922
9922
|
var HOME_DIR = path.resolve(HOME_OVERRIDE ?? path.join(os.homedir(), ".cc-gw"));
|
|
9923
9923
|
var CONFIG_PATH = path.join(HOME_DIR, "config.json");
|
|
9924
|
+
var CERTS_DIR = path.join(HOME_DIR, "certs");
|
|
9924
9925
|
var TypedEmitter = class extends EventEmitter {
|
|
9925
9926
|
on(event, listener) {
|
|
9926
9927
|
return super.on(event, listener);
|
|
@@ -9973,6 +9974,42 @@ function sanitizeModelRoutes(input) {
|
|
|
9973
9974
|
}
|
|
9974
9975
|
return sanitized;
|
|
9975
9976
|
}
|
|
9977
|
+
function migrateProtocolConfig(data) {
|
|
9978
|
+
if (data.http || data.https) {
|
|
9979
|
+
return;
|
|
9980
|
+
}
|
|
9981
|
+
const port = typeof data.port === "number" ? data.port : 4100;
|
|
9982
|
+
const host = typeof data.host === "string" ? data.host : "127.0.0.1";
|
|
9983
|
+
data.http = {
|
|
9984
|
+
enabled: true,
|
|
9985
|
+
port,
|
|
9986
|
+
host
|
|
9987
|
+
};
|
|
9988
|
+
const hasLegacyHttpsConfig = typeof data.httpsPort === "number" || typeof data.keyPath === "string" && data.keyPath || typeof data.certPath === "string" && data.certPath;
|
|
9989
|
+
data.https = {
|
|
9990
|
+
enabled: hasLegacyHttpsConfig ? true : false,
|
|
9991
|
+
port: typeof data.httpsPort === "number" ? data.httpsPort : 4443,
|
|
9992
|
+
host: typeof data.httpsHost === "string" ? data.httpsHost : host,
|
|
9993
|
+
keyPath: typeof data.keyPath === "string" ? data.keyPath : path.join(CERTS_DIR, "key.pem"),
|
|
9994
|
+
certPath: typeof data.certPath === "string" ? data.certPath : path.join(CERTS_DIR, "cert.pem"),
|
|
9995
|
+
caPath: typeof data.caPath === "string" ? data.caPath : ""
|
|
9996
|
+
};
|
|
9997
|
+
data.port = port;
|
|
9998
|
+
data.host = host;
|
|
9999
|
+
}
|
|
10000
|
+
function validateProtocolConfig(data) {
|
|
10001
|
+
const httpEnabled = data.http?.enabled === true;
|
|
10002
|
+
const httpsEnabled = data.https?.enabled === true;
|
|
10003
|
+
if (!httpEnabled && !httpsEnabled) {
|
|
10004
|
+
throw new Error("\u81F3\u5C11\u9700\u8981\u542F\u7528 HTTP \u6216 HTTPS \u534F\u8BAE");
|
|
10005
|
+
}
|
|
10006
|
+
if (httpsEnabled) {
|
|
10007
|
+
const https = data.https;
|
|
10008
|
+
if (!https.keyPath || !https.certPath) {
|
|
10009
|
+
throw new Error("HTTPS \u5DF2\u542F\u7528\u4F46\u7F3A\u5C11\u8BC1\u4E66\u8DEF\u5F84\u914D\u7F6E");
|
|
10010
|
+
}
|
|
10011
|
+
}
|
|
10012
|
+
}
|
|
9976
10013
|
function sanitizeWebAuth(input) {
|
|
9977
10014
|
if (!input || typeof input !== "object") {
|
|
9978
10015
|
return {
|
|
@@ -10021,8 +10058,10 @@ function resolveEndpointRouting(source, fallback) {
|
|
|
10021
10058
|
}
|
|
10022
10059
|
function parseConfig(raw) {
|
|
10023
10060
|
const data = JSON.parse(raw);
|
|
10061
|
+
migrateProtocolConfig(data);
|
|
10062
|
+
validateProtocolConfig(data);
|
|
10024
10063
|
if (typeof data.port !== "number") {
|
|
10025
|
-
|
|
10064
|
+
data.port = data.http?.port ?? 4100;
|
|
10026
10065
|
}
|
|
10027
10066
|
if (!Array.isArray(data.providers)) {
|
|
10028
10067
|
data.providers = [];
|
|
@@ -12132,8 +12171,8 @@ async function registerMessagesRoute(app) {
|
|
|
12132
12171
|
if (providerType === "anthropic") {
|
|
12133
12172
|
providerBody = cloneOriginalPayload(payload);
|
|
12134
12173
|
providerBody.model = target.modelId;
|
|
12135
|
-
if (
|
|
12136
|
-
providerBody.stream =
|
|
12174
|
+
if (Object.prototype.hasOwnProperty.call(payload, "stream")) {
|
|
12175
|
+
providerBody.stream = Boolean(payload.stream);
|
|
12137
12176
|
}
|
|
12138
12177
|
const collected = {};
|
|
12139
12178
|
const skip = /* @__PURE__ */ new Set(["content-length", "host", "connection", "transfer-encoding"]);
|
|
@@ -12253,8 +12292,8 @@ async function registerMessagesRoute(app) {
|
|
|
12253
12292
|
if (providerType === "anthropic") {
|
|
12254
12293
|
let inputTokens2 = json.usage?.input_tokens ?? 0;
|
|
12255
12294
|
let outputTokens2 = json.usage?.output_tokens ?? 0;
|
|
12256
|
-
const
|
|
12257
|
-
const
|
|
12295
|
+
const cached3 = resolveCachedTokens(json.usage);
|
|
12296
|
+
const cachedTokens3 = cached3.read + cached3.creation;
|
|
12258
12297
|
if (!inputTokens2) {
|
|
12259
12298
|
inputTokens2 = target.tokenEstimate || estimateTokens(normalized, target.modelId);
|
|
12260
12299
|
}
|
|
@@ -12265,13 +12304,15 @@ async function registerMessagesRoute(app) {
|
|
|
12265
12304
|
logUsage("non_stream.anthropic", {
|
|
12266
12305
|
input: inputTokens2,
|
|
12267
12306
|
output: outputTokens2,
|
|
12268
|
-
cached:
|
|
12307
|
+
cached: cachedTokens3
|
|
12269
12308
|
});
|
|
12270
12309
|
const latencyMs2 = Date.now() - requestStart;
|
|
12271
12310
|
await updateLogTokens(logId, {
|
|
12272
12311
|
inputTokens: inputTokens2,
|
|
12273
12312
|
outputTokens: outputTokens2,
|
|
12274
|
-
cachedTokens:
|
|
12313
|
+
cachedTokens: cachedTokens3,
|
|
12314
|
+
cacheReadTokens: cached3.read,
|
|
12315
|
+
cacheCreationTokens: cached3.creation,
|
|
12275
12316
|
ttftMs: latencyMs2,
|
|
12276
12317
|
tpotMs: computeTpot(latencyMs2, outputTokens2, { streaming: false })
|
|
12277
12318
|
});
|
|
@@ -12280,9 +12321,9 @@ async function registerMessagesRoute(app) {
|
|
|
12280
12321
|
requests: 1,
|
|
12281
12322
|
inputTokens: inputTokens2,
|
|
12282
12323
|
outputTokens: outputTokens2,
|
|
12283
|
-
cachedTokens:
|
|
12284
|
-
cacheReadTokens:
|
|
12285
|
-
cacheCreationTokens:
|
|
12324
|
+
cachedTokens: cachedTokens3,
|
|
12325
|
+
cacheReadTokens: cached3.read,
|
|
12326
|
+
cacheCreationTokens: cached3.creation,
|
|
12286
12327
|
latencyMs: latencyMs2
|
|
12287
12328
|
});
|
|
12288
12329
|
if (storeResponsePayloads) {
|
|
@@ -12303,8 +12344,8 @@ async function registerMessagesRoute(app) {
|
|
|
12303
12344
|
const claudeResponse = buildClaudeResponse(json, target.modelId);
|
|
12304
12345
|
let inputTokens = json.usage?.prompt_tokens ?? 0;
|
|
12305
12346
|
let outputTokens = json.usage?.completion_tokens ?? 0;
|
|
12306
|
-
const
|
|
12307
|
-
const
|
|
12347
|
+
const cached2 = resolveCachedTokens(json.usage);
|
|
12348
|
+
const cachedTokens2 = cached2.read + cached2.creation;
|
|
12308
12349
|
if (!inputTokens) {
|
|
12309
12350
|
inputTokens = target.tokenEstimate || estimateTokens(normalized, target.modelId);
|
|
12310
12351
|
}
|
|
@@ -12315,13 +12356,15 @@ async function registerMessagesRoute(app) {
|
|
|
12315
12356
|
logUsage("non_stream.openai", {
|
|
12316
12357
|
input: inputTokens,
|
|
12317
12358
|
output: outputTokens,
|
|
12318
|
-
cached:
|
|
12359
|
+
cached: cachedTokens2
|
|
12319
12360
|
});
|
|
12320
12361
|
const latencyMs = Date.now() - requestStart;
|
|
12321
12362
|
await updateLogTokens(logId, {
|
|
12322
12363
|
inputTokens,
|
|
12323
12364
|
outputTokens,
|
|
12324
|
-
cachedTokens,
|
|
12365
|
+
cachedTokens: cachedTokens2,
|
|
12366
|
+
cacheReadTokens: cached2.read,
|
|
12367
|
+
cacheCreationTokens: cached2.creation,
|
|
12325
12368
|
ttftMs: latencyMs,
|
|
12326
12369
|
tpotMs: computeTpot(latencyMs, outputTokens, { streaming: false })
|
|
12327
12370
|
});
|
|
@@ -12330,9 +12373,9 @@ async function registerMessagesRoute(app) {
|
|
|
12330
12373
|
requests: 1,
|
|
12331
12374
|
inputTokens,
|
|
12332
12375
|
outputTokens,
|
|
12333
|
-
cachedTokens,
|
|
12334
|
-
cacheReadTokens:
|
|
12335
|
-
cacheCreationTokens:
|
|
12376
|
+
cachedTokens: cachedTokens2,
|
|
12377
|
+
cacheReadTokens: cached2.read,
|
|
12378
|
+
cacheCreationTokens: cached2.creation,
|
|
12336
12379
|
latencyMs
|
|
12337
12380
|
});
|
|
12338
12381
|
if (storeResponsePayloads) {
|
|
@@ -12369,6 +12412,8 @@ async function registerMessagesRoute(app) {
|
|
|
12369
12412
|
let usagePrompt2 = 0;
|
|
12370
12413
|
let usageCompletion2 = 0;
|
|
12371
12414
|
let usageCached2 = null;
|
|
12415
|
+
let usageCacheRead2 = 0;
|
|
12416
|
+
let usageCacheCreation2 = 0;
|
|
12372
12417
|
let accumulatedContent2 = "";
|
|
12373
12418
|
let firstTokenAt2 = null;
|
|
12374
12419
|
let lastUsagePayload = null;
|
|
@@ -12504,6 +12549,8 @@ async function registerMessagesRoute(app) {
|
|
|
12504
12549
|
usagePrompt2 = payload2.usage.input_tokens ?? usagePrompt2;
|
|
12505
12550
|
usageCompletion2 = payload2.usage.output_tokens ?? usageCompletion2;
|
|
12506
12551
|
const maybeCached = resolveCachedTokens(payload2.usage);
|
|
12552
|
+
usageCacheRead2 = maybeCached.read;
|
|
12553
|
+
usageCacheCreation2 = maybeCached.creation;
|
|
12507
12554
|
usageCached2 = maybeCached.read + maybeCached.creation;
|
|
12508
12555
|
lastUsagePayload = payload2.usage;
|
|
12509
12556
|
}
|
|
@@ -12531,6 +12578,8 @@ async function registerMessagesRoute(app) {
|
|
|
12531
12578
|
usagePrompt2 = payload2.usage.input_tokens ?? usagePrompt2;
|
|
12532
12579
|
usageCompletion2 = payload2.usage.output_tokens ?? usageCompletion2;
|
|
12533
12580
|
const maybeCached = resolveCachedTokens(payload2.usage);
|
|
12581
|
+
usageCacheRead2 = maybeCached.read;
|
|
12582
|
+
usageCacheCreation2 = maybeCached.creation;
|
|
12534
12583
|
usageCached2 = maybeCached.read + maybeCached.creation;
|
|
12535
12584
|
lastUsagePayload = payload2.usage;
|
|
12536
12585
|
}
|
|
@@ -12583,9 +12632,11 @@ async function registerMessagesRoute(app) {
|
|
|
12583
12632
|
}
|
|
12584
12633
|
const totalLatencyMs = Date.now() - requestStart;
|
|
12585
12634
|
const ttftMs = firstTokenAt2 ? firstTokenAt2 - requestStart : null;
|
|
12586
|
-
const cached = resolveCachedTokens(lastUsagePayload);
|
|
12587
12635
|
if (usageCached2 === null) {
|
|
12588
|
-
|
|
12636
|
+
const cached2 = resolveCachedTokens(lastUsagePayload);
|
|
12637
|
+
usageCacheRead2 = cached2.read;
|
|
12638
|
+
usageCacheCreation2 = cached2.creation;
|
|
12639
|
+
usageCached2 = cached2.read + cached2.creation;
|
|
12589
12640
|
}
|
|
12590
12641
|
logUsage("stream.anthropic.final", {
|
|
12591
12642
|
input: usagePrompt2,
|
|
@@ -12596,8 +12647,8 @@ async function registerMessagesRoute(app) {
|
|
|
12596
12647
|
inputTokens: usagePrompt2,
|
|
12597
12648
|
outputTokens: usageCompletion2,
|
|
12598
12649
|
cachedTokens: usageCached2,
|
|
12599
|
-
cacheReadTokens:
|
|
12600
|
-
cacheCreationTokens:
|
|
12650
|
+
cacheReadTokens: usageCacheRead2,
|
|
12651
|
+
cacheCreationTokens: usageCacheCreation2,
|
|
12601
12652
|
ttftMs,
|
|
12602
12653
|
tpotMs: computeTpot(totalLatencyMs, usageCompletion2, {
|
|
12603
12654
|
streaming: true,
|
|
@@ -12610,8 +12661,8 @@ async function registerMessagesRoute(app) {
|
|
|
12610
12661
|
inputTokens: usagePrompt2,
|
|
12611
12662
|
outputTokens: usageCompletion2,
|
|
12612
12663
|
cachedTokens: usageCached2,
|
|
12613
|
-
cacheReadTokens:
|
|
12614
|
-
cacheCreationTokens:
|
|
12664
|
+
cacheReadTokens: usageCacheRead2,
|
|
12665
|
+
cacheCreationTokens: usageCacheCreation2,
|
|
12615
12666
|
latencyMs: totalLatencyMs
|
|
12616
12667
|
});
|
|
12617
12668
|
if (storeResponsePayloads) {
|
|
@@ -12688,6 +12739,8 @@ async function registerMessagesRoute(app) {
|
|
|
12688
12739
|
let usagePrompt = 0;
|
|
12689
12740
|
let usageCompletion = 0;
|
|
12690
12741
|
let usageCached = null;
|
|
12742
|
+
let usageCacheRead = 0;
|
|
12743
|
+
let usageCacheCreation = 0;
|
|
12691
12744
|
let accumulatedContent = "";
|
|
12692
12745
|
let completed = false;
|
|
12693
12746
|
let firstTokenAt = null;
|
|
@@ -12828,9 +12881,10 @@ data: ${JSON.stringify(data)}
|
|
|
12828
12881
|
if (usagePayload) {
|
|
12829
12882
|
usagePrompt = usagePayload.prompt_tokens ?? usagePrompt;
|
|
12830
12883
|
usageCompletion = usagePayload.completion_tokens ?? usageCompletion;
|
|
12831
|
-
|
|
12832
|
-
|
|
12833
|
-
|
|
12884
|
+
const maybeCached = resolveCachedTokens(usagePayload);
|
|
12885
|
+
usageCacheRead = maybeCached.read;
|
|
12886
|
+
usageCacheCreation = maybeCached.creation;
|
|
12887
|
+
usageCached = maybeCached.read + maybeCached.creation;
|
|
12834
12888
|
}
|
|
12835
12889
|
if (choice.delta?.tool_calls) {
|
|
12836
12890
|
request.log.debug({ event: "debug.tool_call_delta", delta: choice.delta?.tool_calls }, "tool call delta received");
|
|
@@ -12937,8 +12991,8 @@ data: ${JSON.stringify(data)}
|
|
|
12937
12991
|
inputTokens: fallbackPrompt,
|
|
12938
12992
|
outputTokens: fallbackCompletion,
|
|
12939
12993
|
cachedTokens: usageCached,
|
|
12940
|
-
cacheReadTokens:
|
|
12941
|
-
cacheCreationTokens:
|
|
12994
|
+
cacheReadTokens: usageCacheRead,
|
|
12995
|
+
cacheCreationTokens: usageCacheCreation,
|
|
12942
12996
|
ttftMs,
|
|
12943
12997
|
tpotMs: computeTpot(totalLatencyMs, fallbackCompletion, {
|
|
12944
12998
|
streaming: true,
|
|
@@ -12951,8 +13005,8 @@ data: ${JSON.stringify(data)}
|
|
|
12951
13005
|
inputTokens: fallbackPrompt,
|
|
12952
13006
|
outputTokens: fallbackCompletion,
|
|
12953
13007
|
cachedTokens: usageCached ?? 0,
|
|
12954
|
-
cacheReadTokens:
|
|
12955
|
-
cacheCreationTokens:
|
|
13008
|
+
cacheReadTokens: usageCacheRead,
|
|
13009
|
+
cacheCreationTokens: usageCacheCreation,
|
|
12956
13010
|
latencyMs: totalLatencyMs
|
|
12957
13011
|
});
|
|
12958
13012
|
if (storeResponsePayloads) {
|
|
@@ -13791,7 +13845,9 @@ async function registerOpenAiRoutes(app) {
|
|
|
13791
13845
|
overrideTools: Array.isArray(payload.tools) ? payload.tools : void 0
|
|
13792
13846
|
});
|
|
13793
13847
|
providerBody.model = target.modelId;
|
|
13794
|
-
|
|
13848
|
+
if (Object.prototype.hasOwnProperty.call(payload, "stream")) {
|
|
13849
|
+
providerBody.stream = Boolean(payload.stream);
|
|
13850
|
+
}
|
|
13795
13851
|
const rawHeaders = request.raw?.headers ?? request.headers;
|
|
13796
13852
|
const forwarded = collectAnthropicForwardHeaders(rawHeaders);
|
|
13797
13853
|
providerHeaders = filterForwardedAnthropicHeaders(forwarded);
|
|
@@ -13830,7 +13886,9 @@ async function registerOpenAiRoutes(app) {
|
|
|
13830
13886
|
} else {
|
|
13831
13887
|
providerBody = { ...payload };
|
|
13832
13888
|
providerBody.model = target.modelId;
|
|
13833
|
-
|
|
13889
|
+
if (Object.prototype.hasOwnProperty.call(payload, "stream")) {
|
|
13890
|
+
providerBody.stream = Boolean(payload.stream);
|
|
13891
|
+
}
|
|
13834
13892
|
if (providerBody.max_output_tokens == null && typeof providerBody.max_tokens === "number") {
|
|
13835
13893
|
providerBody.max_output_tokens = providerBody.max_tokens;
|
|
13836
13894
|
}
|
|
@@ -13896,20 +13954,20 @@ async function registerOpenAiRoutes(app) {
|
|
|
13896
13954
|
if (!Number.isFinite(inputTokens3) || inputTokens3 <= 0) {
|
|
13897
13955
|
inputTokens3 = target.tokenEstimate ?? estimateTokens(normalized, target.modelId);
|
|
13898
13956
|
}
|
|
13899
|
-
const
|
|
13900
|
-
const
|
|
13957
|
+
const cached3 = resolveCachedTokens2(usagePayload2);
|
|
13958
|
+
const cachedTokens3 = cached3.read + cached3.creation;
|
|
13901
13959
|
const latencyMs3 = Date.now() - requestStart;
|
|
13902
13960
|
const openAIResponse = buildOpenAIResponseFromClaude(parsed, target.modelId, converted, {
|
|
13903
13961
|
inputTokens: inputTokens3,
|
|
13904
13962
|
outputTokens: outputTokens3,
|
|
13905
|
-
cachedTokens:
|
|
13963
|
+
cachedTokens: cachedTokens3
|
|
13906
13964
|
});
|
|
13907
13965
|
await updateLogTokens(logId, {
|
|
13908
13966
|
inputTokens: inputTokens3,
|
|
13909
13967
|
outputTokens: outputTokens3,
|
|
13910
|
-
cachedTokens:
|
|
13911
|
-
cacheReadTokens:
|
|
13912
|
-
cacheCreationTokens:
|
|
13968
|
+
cachedTokens: cachedTokens3,
|
|
13969
|
+
cacheReadTokens: cached3.read,
|
|
13970
|
+
cacheCreationTokens: cached3.creation,
|
|
13913
13971
|
ttftMs: latencyMs3,
|
|
13914
13972
|
tpotMs: computeTpot2(latencyMs3, outputTokens3, { streaming: false })
|
|
13915
13973
|
});
|
|
@@ -13918,9 +13976,9 @@ async function registerOpenAiRoutes(app) {
|
|
|
13918
13976
|
requests: 1,
|
|
13919
13977
|
inputTokens: inputTokens3,
|
|
13920
13978
|
outputTokens: outputTokens3,
|
|
13921
|
-
cachedTokens:
|
|
13922
|
-
cacheReadTokens:
|
|
13923
|
-
cacheCreationTokens:
|
|
13979
|
+
cachedTokens: cachedTokens3,
|
|
13980
|
+
cacheReadTokens: cached3.read,
|
|
13981
|
+
cacheCreationTokens: cached3.creation,
|
|
13924
13982
|
latencyMs: latencyMs3
|
|
13925
13983
|
});
|
|
13926
13984
|
if (storeResponsePayloads) {
|
|
@@ -13955,15 +14013,15 @@ async function registerOpenAiRoutes(app) {
|
|
|
13955
14013
|
return 0;
|
|
13956
14014
|
})();
|
|
13957
14015
|
const outputTokens2 = baseOutputTokens + reasoningTokens2;
|
|
13958
|
-
const
|
|
13959
|
-
const
|
|
14016
|
+
const cached2 = resolveCachedTokens2(usagePayload);
|
|
14017
|
+
const cachedTokens2 = cached2.read + cached2.creation;
|
|
13960
14018
|
const latencyMs2 = Date.now() - requestStart;
|
|
13961
14019
|
await updateLogTokens(logId, {
|
|
13962
14020
|
inputTokens: inputTokens2,
|
|
13963
14021
|
outputTokens: outputTokens2,
|
|
13964
|
-
cachedTokens:
|
|
13965
|
-
cacheReadTokens:
|
|
13966
|
-
cacheCreationTokens:
|
|
14022
|
+
cachedTokens: cachedTokens2,
|
|
14023
|
+
cacheReadTokens: cached2.read,
|
|
14024
|
+
cacheCreationTokens: cached2.creation,
|
|
13967
14025
|
ttftMs: usagePayload?.first_token_latency_ms ?? latencyMs2,
|
|
13968
14026
|
tpotMs: usagePayload?.tokens_per_second ? computeTpot2(latencyMs2, outputTokens2, { streaming: false, reasoningTokens: reasoningTokens2 }) : null
|
|
13969
14027
|
});
|
|
@@ -13972,6 +14030,9 @@ async function registerOpenAiRoutes(app) {
|
|
|
13972
14030
|
requests: 1,
|
|
13973
14031
|
inputTokens: inputTokens2,
|
|
13974
14032
|
outputTokens: outputTokens2,
|
|
14033
|
+
cachedTokens: cachedTokens2,
|
|
14034
|
+
cacheReadTokens: cached2.read,
|
|
14035
|
+
cacheCreationTokens: cached2.creation,
|
|
13975
14036
|
latencyMs: latencyMs2
|
|
13976
14037
|
});
|
|
13977
14038
|
await finalize(200, null);
|
|
@@ -14353,8 +14414,8 @@ async function registerOpenAiRoutes(app) {
|
|
|
14353
14414
|
inputTokens: finalPromptTokens,
|
|
14354
14415
|
outputTokens: finalCompletionTokens,
|
|
14355
14416
|
cachedTokens: finalCachedTokens ?? null,
|
|
14356
|
-
cacheReadTokens:
|
|
14357
|
-
cacheCreationTokens:
|
|
14417
|
+
cacheReadTokens: finalCachedResult.read,
|
|
14418
|
+
cacheCreationTokens: finalCachedResult.creation,
|
|
14358
14419
|
ttftMs,
|
|
14359
14420
|
tpotMs: computeTpot2(totalLatencyMs, finalCompletionTokens, {
|
|
14360
14421
|
streaming: true,
|
|
@@ -14520,12 +14581,16 @@ async function registerOpenAiRoutes(app) {
|
|
|
14520
14581
|
const textOutputTokens = usageCompletion ?? 0;
|
|
14521
14582
|
const reasoningTokens = usageReasoning ?? 0;
|
|
14522
14583
|
const outputTokens = textOutputTokens + reasoningTokens;
|
|
14584
|
+
const hasCacheStats = usageCached != null;
|
|
14585
|
+
const resolvedCachedTokens = hasCacheStats ? usageCached : null;
|
|
14586
|
+
const resolvedCacheRead = hasCacheStats ? usageCacheRead : null;
|
|
14587
|
+
const resolvedCacheCreation = hasCacheStats ? usageCacheCreation : null;
|
|
14523
14588
|
await updateLogTokens(logId, {
|
|
14524
14589
|
inputTokens,
|
|
14525
14590
|
outputTokens,
|
|
14526
|
-
cachedTokens:
|
|
14527
|
-
cacheReadTokens:
|
|
14528
|
-
cacheCreationTokens:
|
|
14591
|
+
cachedTokens: resolvedCachedTokens,
|
|
14592
|
+
cacheReadTokens: resolvedCacheRead,
|
|
14593
|
+
cacheCreationTokens: resolvedCacheCreation,
|
|
14529
14594
|
ttftMs: firstTokenAt ? firstTokenAt - requestStart : null,
|
|
14530
14595
|
tpotMs: computeTpot2(latencyMs, outputTokens, {
|
|
14531
14596
|
streaming: true,
|
|
@@ -14538,6 +14603,9 @@ async function registerOpenAiRoutes(app) {
|
|
|
14538
14603
|
requests: 1,
|
|
14539
14604
|
inputTokens,
|
|
14540
14605
|
outputTokens,
|
|
14606
|
+
cachedTokens: resolvedCachedTokens ?? 0,
|
|
14607
|
+
cacheReadTokens: resolvedCacheRead ?? 0,
|
|
14608
|
+
cacheCreationTokens: resolvedCacheCreation ?? 0,
|
|
14541
14609
|
latencyMs
|
|
14542
14610
|
});
|
|
14543
14611
|
await finalize(200, null);
|
|
@@ -14669,7 +14737,9 @@ async function registerOpenAiRoutes(app) {
|
|
|
14669
14737
|
overrideTools
|
|
14670
14738
|
});
|
|
14671
14739
|
providerBody.model = target.modelId;
|
|
14672
|
-
|
|
14740
|
+
if (Object.prototype.hasOwnProperty.call(payload, "stream")) {
|
|
14741
|
+
providerBody.stream = Boolean(payload.stream);
|
|
14742
|
+
}
|
|
14673
14743
|
const rawHeaders = request.raw?.headers ?? request.headers;
|
|
14674
14744
|
const forwarded = collectAnthropicForwardHeaders(rawHeaders);
|
|
14675
14745
|
providerHeaders = filterForwardedAnthropicHeaders(forwarded);
|
|
@@ -14713,7 +14783,9 @@ async function registerOpenAiRoutes(app) {
|
|
|
14713
14783
|
overrideTools
|
|
14714
14784
|
});
|
|
14715
14785
|
providerBody.model = target.modelId;
|
|
14716
|
-
|
|
14786
|
+
if (Object.prototype.hasOwnProperty.call(payload, "stream")) {
|
|
14787
|
+
providerBody.stream = Boolean(payload.stream);
|
|
14788
|
+
}
|
|
14717
14789
|
if (Array.isArray(payload.functions) && !providerBody.functions) {
|
|
14718
14790
|
providerBody.functions = payload.functions;
|
|
14719
14791
|
}
|
|
@@ -14783,15 +14855,15 @@ async function registerOpenAiRoutes(app) {
|
|
|
14783
14855
|
inputTokens: inputTokens3,
|
|
14784
14856
|
outputTokens: outputTokens3
|
|
14785
14857
|
});
|
|
14786
|
-
const
|
|
14787
|
-
const
|
|
14858
|
+
const cached3 = resolveCachedTokens2(usagePayload2);
|
|
14859
|
+
const cachedTokens3 = cached3.read + cached3.creation;
|
|
14788
14860
|
const latencyMs3 = Date.now() - requestStart;
|
|
14789
14861
|
await updateLogTokens(logId, {
|
|
14790
14862
|
inputTokens: inputTokens3,
|
|
14791
14863
|
outputTokens: outputTokens3,
|
|
14792
|
-
cachedTokens:
|
|
14793
|
-
cacheReadTokens:
|
|
14794
|
-
cacheCreationTokens:
|
|
14864
|
+
cachedTokens: cachedTokens3,
|
|
14865
|
+
cacheReadTokens: cached3.read,
|
|
14866
|
+
cacheCreationTokens: cached3.creation,
|
|
14795
14867
|
ttftMs: latencyMs3,
|
|
14796
14868
|
tpotMs: computeTpot2(latencyMs3, outputTokens3, { streaming: false })
|
|
14797
14869
|
});
|
|
@@ -14800,9 +14872,9 @@ async function registerOpenAiRoutes(app) {
|
|
|
14800
14872
|
requests: 1,
|
|
14801
14873
|
inputTokens: inputTokens3,
|
|
14802
14874
|
outputTokens: outputTokens3,
|
|
14803
|
-
cachedTokens:
|
|
14804
|
-
cacheReadTokens:
|
|
14805
|
-
cacheCreationTokens:
|
|
14875
|
+
cachedTokens: cachedTokens3,
|
|
14876
|
+
cacheReadTokens: cached3.read,
|
|
14877
|
+
cacheCreationTokens: cached3.creation,
|
|
14806
14878
|
latencyMs: latencyMs3
|
|
14807
14879
|
});
|
|
14808
14880
|
if (storeResponsePayloads) {
|
|
@@ -14832,15 +14904,15 @@ async function registerOpenAiRoutes(app) {
|
|
|
14832
14904
|
})(),
|
|
14833
14905
|
target.modelId
|
|
14834
14906
|
);
|
|
14835
|
-
const
|
|
14836
|
-
const
|
|
14907
|
+
const cached2 = resolveCachedTokens2(usagePayload);
|
|
14908
|
+
const cachedTokens2 = cached2.read + cached2.creation;
|
|
14837
14909
|
const latencyMs2 = Date.now() - requestStart;
|
|
14838
14910
|
await updateLogTokens(logId, {
|
|
14839
14911
|
inputTokens: inputTokens2,
|
|
14840
14912
|
outputTokens: outputTokens2,
|
|
14841
|
-
cachedTokens:
|
|
14842
|
-
cacheReadTokens:
|
|
14843
|
-
cacheCreationTokens:
|
|
14913
|
+
cachedTokens: cachedTokens2,
|
|
14914
|
+
cacheReadTokens: cached2.read,
|
|
14915
|
+
cacheCreationTokens: cached2.creation,
|
|
14844
14916
|
ttftMs: usagePayload?.first_token_latency_ms ?? latencyMs2,
|
|
14845
14917
|
tpotMs: usagePayload?.tokens_per_second ? computeTpot2(latencyMs2, outputTokens2, { streaming: false }) : null
|
|
14846
14918
|
});
|
|
@@ -14849,6 +14921,9 @@ async function registerOpenAiRoutes(app) {
|
|
|
14849
14921
|
requests: 1,
|
|
14850
14922
|
inputTokens: inputTokens2,
|
|
14851
14923
|
outputTokens: outputTokens2,
|
|
14924
|
+
cachedTokens: cachedTokens2,
|
|
14925
|
+
cacheReadTokens: cached2.read,
|
|
14926
|
+
cacheCreationTokens: cached2.creation,
|
|
14852
14927
|
latencyMs: latencyMs2
|
|
14853
14928
|
});
|
|
14854
14929
|
await finalize(200, null);
|
|
@@ -15273,8 +15348,8 @@ async function registerOpenAiRoutes(app) {
|
|
|
15273
15348
|
inputTokens: finalPromptTokens,
|
|
15274
15349
|
outputTokens: finalCompletionTokens,
|
|
15275
15350
|
cachedTokens: finalCachedTokens ?? null,
|
|
15276
|
-
cacheReadTokens:
|
|
15277
|
-
cacheCreationTokens:
|
|
15351
|
+
cacheReadTokens: finalCachedResult.read,
|
|
15352
|
+
cacheCreationTokens: finalCachedResult.creation,
|
|
15278
15353
|
ttftMs,
|
|
15279
15354
|
tpotMs: computeTpot2(totalLatencyMs, finalCompletionTokens, {
|
|
15280
15355
|
streaming: true,
|
|
@@ -15415,12 +15490,16 @@ async function registerOpenAiRoutes(app) {
|
|
|
15415
15490
|
const latencyMs = Date.now() - requestStart;
|
|
15416
15491
|
const inputTokens = usagePrompt ?? usageCompletion ?? target.tokenEstimate ?? estimateTokens(normalized, target.modelId);
|
|
15417
15492
|
const outputTokens = usageCompletion ?? 0;
|
|
15493
|
+
const hasCacheStats = usageCached != null;
|
|
15494
|
+
const resolvedCachedTokens = hasCacheStats ? usageCached : null;
|
|
15495
|
+
const resolvedCacheRead = hasCacheStats ? usageCacheRead : null;
|
|
15496
|
+
const resolvedCacheCreation = hasCacheStats ? usageCacheCreation : null;
|
|
15418
15497
|
await updateLogTokens(logId, {
|
|
15419
15498
|
inputTokens,
|
|
15420
15499
|
outputTokens,
|
|
15421
|
-
cachedTokens:
|
|
15422
|
-
cacheReadTokens:
|
|
15423
|
-
cacheCreationTokens:
|
|
15500
|
+
cachedTokens: resolvedCachedTokens,
|
|
15501
|
+
cacheReadTokens: resolvedCacheRead,
|
|
15502
|
+
cacheCreationTokens: resolvedCacheCreation,
|
|
15424
15503
|
ttftMs: firstTokenAt ? firstTokenAt - requestStart : null,
|
|
15425
15504
|
tpotMs: computeTpot2(latencyMs, outputTokens, {
|
|
15426
15505
|
streaming: true,
|
|
@@ -15432,6 +15511,9 @@ async function registerOpenAiRoutes(app) {
|
|
|
15432
15511
|
requests: 1,
|
|
15433
15512
|
inputTokens,
|
|
15434
15513
|
outputTokens,
|
|
15514
|
+
cachedTokens: resolvedCachedTokens ?? 0,
|
|
15515
|
+
cacheReadTokens: resolvedCacheRead ?? 0,
|
|
15516
|
+
cacheCreationTokens: resolvedCacheCreation ?? 0,
|
|
15435
15517
|
latencyMs
|
|
15436
15518
|
});
|
|
15437
15519
|
await finalize(200, null);
|
|
@@ -15597,7 +15679,7 @@ async function queryLogs(options = {}) {
|
|
|
15597
15679
|
const items = await getAll(
|
|
15598
15680
|
`SELECT id, timestamp, session_id, endpoint, provider, model, client_model,
|
|
15599
15681
|
stream, latency_ms, status_code, input_tokens, output_tokens,
|
|
15600
|
-
cached_tokens, ttft_ms, tpot_ms, error, api_key_id, api_key_name, api_key_value
|
|
15682
|
+
cached_tokens, cache_read_tokens, cache_creation_tokens, ttft_ms, tpot_ms, error, api_key_id, api_key_name, api_key_value
|
|
15601
15683
|
FROM request_logs
|
|
15602
15684
|
${whereClause}
|
|
15603
15685
|
ORDER BY timestamp DESC
|
|
@@ -15613,7 +15695,7 @@ async function getLogDetail(id) {
|
|
|
15613
15695
|
const record = await getOne(
|
|
15614
15696
|
`SELECT id, timestamp, session_id, endpoint, provider, model, client_model,
|
|
15615
15697
|
stream, latency_ms, status_code, input_tokens, output_tokens,
|
|
15616
|
-
cached_tokens, ttft_ms, tpot_ms, error, api_key_id, api_key_name, api_key_value
|
|
15698
|
+
cached_tokens, cache_read_tokens, cache_creation_tokens, ttft_ms, tpot_ms, error, api_key_id, api_key_name, api_key_value
|
|
15617
15699
|
FROM request_logs
|
|
15618
15700
|
WHERE id = ?`,
|
|
15619
15701
|
[id]
|
|
@@ -15663,6 +15745,8 @@ async function exportLogs(options = {}) {
|
|
|
15663
15745
|
l.input_tokens,
|
|
15664
15746
|
l.output_tokens,
|
|
15665
15747
|
l.cached_tokens,
|
|
15748
|
+
l.cache_read_tokens,
|
|
15749
|
+
l.cache_creation_tokens,
|
|
15666
15750
|
l.ttft_ms,
|
|
15667
15751
|
l.tpot_ms,
|
|
15668
15752
|
l.error,
|
|
@@ -17521,8 +17605,8 @@ async function handleAnthropicProtocol(request, reply, endpoint, endpointId, app
|
|
|
17521
17605
|
if (providerType === "anthropic") {
|
|
17522
17606
|
providerBody = cloneOriginalPayload2(payload);
|
|
17523
17607
|
providerBody.model = target.modelId;
|
|
17524
|
-
if (
|
|
17525
|
-
providerBody.stream =
|
|
17608
|
+
if (Object.prototype.hasOwnProperty.call(payload, "stream")) {
|
|
17609
|
+
providerBody.stream = Boolean(payload.stream);
|
|
17526
17610
|
}
|
|
17527
17611
|
const collected = {};
|
|
17528
17612
|
const skip = /* @__PURE__ */ new Set(["content-length", "host", "connection", "transfer-encoding"]);
|
|
@@ -17575,15 +17659,15 @@ async function handleAnthropicProtocol(request, reply, endpoint, endpointId, app
|
|
|
17575
17659
|
const json = await new Response(upstream.body).json();
|
|
17576
17660
|
const inputTokens = json.usage?.input_tokens ?? estimateTokens(normalized, target.modelId);
|
|
17577
17661
|
const outputTokens = json.usage?.output_tokens ?? 0;
|
|
17578
|
-
const
|
|
17579
|
-
const
|
|
17662
|
+
const cached2 = resolveCachedTokens3(json.usage);
|
|
17663
|
+
const cachedTokens2 = cached2.read + cached2.creation;
|
|
17580
17664
|
const latencyMs = Date.now() - requestStart;
|
|
17581
17665
|
await updateLogTokens(logId, {
|
|
17582
17666
|
inputTokens,
|
|
17583
17667
|
outputTokens,
|
|
17584
|
-
cachedTokens:
|
|
17585
|
-
cacheReadTokens:
|
|
17586
|
-
cacheCreationTokens:
|
|
17668
|
+
cachedTokens: cachedTokens2,
|
|
17669
|
+
cacheReadTokens: cached2.read,
|
|
17670
|
+
cacheCreationTokens: cached2.creation,
|
|
17587
17671
|
ttftMs: latencyMs,
|
|
17588
17672
|
tpotMs: computeTpot3(latencyMs, outputTokens, { streaming: false })
|
|
17589
17673
|
});
|
|
@@ -17592,9 +17676,9 @@ async function handleAnthropicProtocol(request, reply, endpoint, endpointId, app
|
|
|
17592
17676
|
requests: 1,
|
|
17593
17677
|
inputTokens,
|
|
17594
17678
|
outputTokens,
|
|
17595
|
-
cachedTokens:
|
|
17596
|
-
cacheReadTokens:
|
|
17597
|
-
cacheCreationTokens:
|
|
17679
|
+
cachedTokens: cachedTokens2,
|
|
17680
|
+
cacheReadTokens: cached2.read,
|
|
17681
|
+
cacheCreationTokens: cached2.creation,
|
|
17598
17682
|
latencyMs
|
|
17599
17683
|
});
|
|
17600
17684
|
if (storeResponsePayloads) {
|
|
@@ -17652,10 +17736,10 @@ async function handleAnthropicProtocol(request, reply, endpoint, endpointId, app
|
|
|
17652
17736
|
if (parsed?.usage) {
|
|
17653
17737
|
usagePrompt = parsed.usage.input_tokens ?? usagePrompt;
|
|
17654
17738
|
usageCompletion = parsed.usage.output_tokens ?? usageCompletion;
|
|
17655
|
-
const
|
|
17656
|
-
usageCacheRead =
|
|
17657
|
-
usageCacheCreation =
|
|
17658
|
-
usageCached =
|
|
17739
|
+
const cached2 = resolveCachedTokens3(parsed.usage);
|
|
17740
|
+
usageCacheRead = cached2.read;
|
|
17741
|
+
usageCacheCreation = cached2.creation;
|
|
17742
|
+
usageCached = cached2.read + cached2.creation;
|
|
17659
17743
|
}
|
|
17660
17744
|
if (!firstTokenAt && (parsed?.type === "content_block_delta" || parsed?.delta?.text)) {
|
|
17661
17745
|
firstTokenAt = Date.now();
|
|
@@ -17851,7 +17935,9 @@ async function handleOpenAIChatProtocol(request, reply, endpoint, endpointId, ap
|
|
|
17851
17935
|
});
|
|
17852
17936
|
}
|
|
17853
17937
|
providerBody.model = target.modelId;
|
|
17854
|
-
|
|
17938
|
+
if (Object.prototype.hasOwnProperty.call(payload, "stream")) {
|
|
17939
|
+
providerBody.stream = Boolean(payload.stream);
|
|
17940
|
+
}
|
|
17855
17941
|
const upstream = await connector.send({
|
|
17856
17942
|
model: target.modelId,
|
|
17857
17943
|
body: providerBody,
|
|
@@ -17875,15 +17961,15 @@ async function handleOpenAIChatProtocol(request, reply, endpoint, endpointId, ap
|
|
|
17875
17961
|
const usagePayload = json?.usage ?? null;
|
|
17876
17962
|
const inputTokens2 = usagePayload?.prompt_tokens ?? usagePayload?.input_tokens ?? target.tokenEstimate ?? estimateTokens(normalized, target.modelId);
|
|
17877
17963
|
const outputTokens2 = usagePayload?.completion_tokens ?? usagePayload?.output_tokens ?? estimateTextTokens(json?.choices?.[0]?.message?.content ?? "", target.modelId);
|
|
17878
|
-
const
|
|
17879
|
-
const
|
|
17964
|
+
const cached2 = resolveCachedTokens3(usagePayload);
|
|
17965
|
+
const cachedTokens2 = cached2.read + cached2.creation;
|
|
17880
17966
|
const latencyMs2 = Date.now() - requestStart;
|
|
17881
17967
|
await updateLogTokens(logId, {
|
|
17882
17968
|
inputTokens: inputTokens2,
|
|
17883
17969
|
outputTokens: outputTokens2,
|
|
17884
|
-
cachedTokens:
|
|
17885
|
-
cacheReadTokens:
|
|
17886
|
-
cacheCreationTokens:
|
|
17970
|
+
cachedTokens: cachedTokens2,
|
|
17971
|
+
cacheReadTokens: cached2.read,
|
|
17972
|
+
cacheCreationTokens: cached2.creation,
|
|
17887
17973
|
ttftMs: latencyMs2,
|
|
17888
17974
|
tpotMs: computeTpot3(latencyMs2, outputTokens2, { streaming: false })
|
|
17889
17975
|
});
|
|
@@ -17892,9 +17978,9 @@ async function handleOpenAIChatProtocol(request, reply, endpoint, endpointId, ap
|
|
|
17892
17978
|
requests: 1,
|
|
17893
17979
|
inputTokens: inputTokens2,
|
|
17894
17980
|
outputTokens: outputTokens2,
|
|
17895
|
-
cachedTokens:
|
|
17896
|
-
cacheReadTokens:
|
|
17897
|
-
cacheCreationTokens:
|
|
17981
|
+
cachedTokens: cachedTokens2,
|
|
17982
|
+
cacheReadTokens: cached2.read,
|
|
17983
|
+
cacheCreationTokens: cached2.creation,
|
|
17898
17984
|
latencyMs: latencyMs2
|
|
17899
17985
|
});
|
|
17900
17986
|
if (storeResponsePayloads) {
|
|
@@ -18142,7 +18228,9 @@ async function handleOpenAIResponsesProtocol(request, reply, endpoint, endpointI
|
|
|
18142
18228
|
});
|
|
18143
18229
|
}
|
|
18144
18230
|
providerBody.model = target.modelId;
|
|
18145
|
-
|
|
18231
|
+
if (Object.prototype.hasOwnProperty.call(payload, "stream")) {
|
|
18232
|
+
providerBody.stream = Boolean(payload.stream);
|
|
18233
|
+
}
|
|
18146
18234
|
const upstream = await connector.send({
|
|
18147
18235
|
model: target.modelId,
|
|
18148
18236
|
body: providerBody,
|
|
@@ -18167,15 +18255,15 @@ async function handleOpenAIResponsesProtocol(request, reply, endpoint, endpointI
|
|
|
18167
18255
|
const inputTokens2 = usagePayload?.prompt_tokens ?? usagePayload?.input_tokens ?? target.tokenEstimate ?? estimateTokens(normalized, target.modelId);
|
|
18168
18256
|
const content = json?.response?.body?.content ?? json?.choices?.[0]?.message?.content ?? "";
|
|
18169
18257
|
const outputTokens2 = usagePayload?.completion_tokens ?? usagePayload?.output_tokens ?? estimateTextTokens(content, target.modelId);
|
|
18170
|
-
const
|
|
18171
|
-
const
|
|
18258
|
+
const cached2 = resolveCachedTokens3(usagePayload);
|
|
18259
|
+
const cachedTokens2 = cached2.read + cached2.creation;
|
|
18172
18260
|
const latencyMs2 = Date.now() - requestStart;
|
|
18173
18261
|
await updateLogTokens(logId, {
|
|
18174
18262
|
inputTokens: inputTokens2,
|
|
18175
18263
|
outputTokens: outputTokens2,
|
|
18176
|
-
cachedTokens:
|
|
18177
|
-
cacheReadTokens:
|
|
18178
|
-
cacheCreationTokens:
|
|
18264
|
+
cachedTokens: cachedTokens2,
|
|
18265
|
+
cacheReadTokens: cached2.read,
|
|
18266
|
+
cacheCreationTokens: cached2.creation,
|
|
18179
18267
|
ttftMs: latencyMs2,
|
|
18180
18268
|
tpotMs: computeTpot3(latencyMs2, outputTokens2, { streaming: false })
|
|
18181
18269
|
});
|
|
@@ -18184,9 +18272,9 @@ async function handleOpenAIResponsesProtocol(request, reply, endpoint, endpointI
|
|
|
18184
18272
|
requests: 1,
|
|
18185
18273
|
inputTokens: inputTokens2,
|
|
18186
18274
|
outputTokens: outputTokens2,
|
|
18187
|
-
cachedTokens:
|
|
18188
|
-
cacheReadTokens:
|
|
18189
|
-
cacheCreationTokens:
|
|
18275
|
+
cachedTokens: cachedTokens2,
|
|
18276
|
+
cacheReadTokens: cached2.read,
|
|
18277
|
+
cacheCreationTokens: cached2.creation,
|
|
18190
18278
|
latencyMs: latencyMs2
|
|
18191
18279
|
});
|
|
18192
18280
|
if (storeResponsePayloads) {
|
|
@@ -18316,11 +18404,11 @@ function startMaintenanceTimers() {
|
|
|
18316
18404
|
scheduleCleanup();
|
|
18317
18405
|
}
|
|
18318
18406
|
function scheduleCleanup() {
|
|
18319
|
-
const run2 = () => {
|
|
18407
|
+
const run2 = async () => {
|
|
18320
18408
|
try {
|
|
18321
18409
|
const retentionDays = getConfig().logRetentionDays ?? 30;
|
|
18322
18410
|
const cutoff = Date.now() - retentionDays * DAY_MS;
|
|
18323
|
-
const deleted = cleanupLogsBefore(cutoff);
|
|
18411
|
+
const deleted = await cleanupLogsBefore(cutoff);
|
|
18324
18412
|
if (deleted > 0) {
|
|
18325
18413
|
console.info(`[maintenance] cleaned ${deleted} old log entries`);
|
|
18326
18414
|
}
|
|
@@ -18451,17 +18539,30 @@ async function syncCustomEndpoints(app, config) {
|
|
|
18451
18539
|
);
|
|
18452
18540
|
}
|
|
18453
18541
|
}
|
|
18454
|
-
async function createServer() {
|
|
18542
|
+
async function createServer(protocol = "http") {
|
|
18455
18543
|
const config = cachedConfig2 ?? loadConfig();
|
|
18456
18544
|
const requestLogEnabled = config.requestLogging !== false;
|
|
18457
18545
|
const responseLogEnabled = config.responseLogging !== false;
|
|
18458
18546
|
const bodyLimit = typeof config.bodyLimit === "number" && Number.isFinite(config.bodyLimit) && config.bodyLimit > 0 ? config.bodyLimit : 10 * 1024 * 1024;
|
|
18547
|
+
let httpsOptions;
|
|
18548
|
+
if (protocol === "https" && config.https?.enabled) {
|
|
18549
|
+
const { keyPath, certPath, caPath } = config.https;
|
|
18550
|
+
if (!fs4.existsSync(keyPath) || !fs4.existsSync(certPath)) {
|
|
18551
|
+
throw new Error(`HTTPS \u8BC1\u4E66\u6587\u4EF6\u4E0D\u5B58\u5728: ${keyPath}, ${certPath}`);
|
|
18552
|
+
}
|
|
18553
|
+
httpsOptions = {
|
|
18554
|
+
key: fs4.readFileSync(keyPath),
|
|
18555
|
+
cert: fs4.readFileSync(certPath),
|
|
18556
|
+
ca: caPath ? fs4.readFileSync(caPath) : void 0
|
|
18557
|
+
};
|
|
18558
|
+
}
|
|
18459
18559
|
const app = Fastify({
|
|
18460
18560
|
logger: {
|
|
18461
18561
|
level: config.logLevel ?? "info"
|
|
18462
18562
|
},
|
|
18463
18563
|
disableRequestLogging: true,
|
|
18464
|
-
bodyLimit
|
|
18564
|
+
bodyLimit,
|
|
18565
|
+
https: httpsOptions
|
|
18465
18566
|
});
|
|
18466
18567
|
app.addHook("onRequest", async (request, reply) => {
|
|
18467
18568
|
const authConfig = (cachedConfig2 ?? getConfig()).webAuth;
|
|
@@ -18602,25 +18703,54 @@ async function createServer() {
|
|
|
18602
18703
|
return app;
|
|
18603
18704
|
}
|
|
18604
18705
|
async function startServer(options = {}) {
|
|
18605
|
-
const
|
|
18606
|
-
const
|
|
18607
|
-
|
|
18608
|
-
|
|
18609
|
-
|
|
18610
|
-
|
|
18611
|
-
|
|
18612
|
-
|
|
18613
|
-
|
|
18706
|
+
const config = cachedConfig2 ?? loadConfig();
|
|
18707
|
+
const result = {};
|
|
18708
|
+
if (config.http?.enabled !== false) {
|
|
18709
|
+
const httpApp = await createServer("http");
|
|
18710
|
+
const httpPort = options.port ?? (process2.env.PORT ? Number.parseInt(process2.env.PORT, 10) : config.http?.port ?? config.port ?? DEFAULT_PORT);
|
|
18711
|
+
const httpHost = options.host ?? process2.env.HOST ?? config.http?.host ?? config.host ?? DEFAULT_HOST;
|
|
18712
|
+
await httpApp.listen({ port: httpPort, host: httpHost });
|
|
18713
|
+
httpApp.log.info(`HTTP server started at http://${httpHost}:${httpPort}`);
|
|
18714
|
+
result.http = httpApp;
|
|
18715
|
+
}
|
|
18716
|
+
if (config.https?.enabled === true) {
|
|
18717
|
+
try {
|
|
18718
|
+
const httpsApp = await createServer("https");
|
|
18719
|
+
const httpsPort = config.https.port;
|
|
18720
|
+
const httpsHost = config.https.host ?? config.host ?? DEFAULT_HOST;
|
|
18721
|
+
await httpsApp.listen({ port: httpsPort, host: httpsHost });
|
|
18722
|
+
httpsApp.log.info(`HTTPS server started at https://${httpsHost}:${httpsPort}`);
|
|
18723
|
+
result.https = httpsApp;
|
|
18724
|
+
} catch (error) {
|
|
18725
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
18726
|
+
console.error(`HTTPS server\u542F\u52A8\u5931\u8D25: ${errorMessage}`);
|
|
18727
|
+
if (!result.http) {
|
|
18728
|
+
throw error;
|
|
18729
|
+
}
|
|
18730
|
+
console.warn("\u4EC5 HTTP \u670D\u52A1\u5668\u542F\u52A8\u6210\u529F,HTTPS \u670D\u52A1\u5668\u542F\u52A8\u5931\u8D25");
|
|
18731
|
+
}
|
|
18732
|
+
}
|
|
18733
|
+
if (!result.http && !result.https) {
|
|
18734
|
+
throw new Error("HTTP \u548C HTTPS \u670D\u52A1\u5668\u5747\u672A\u542F\u52A8");
|
|
18735
|
+
}
|
|
18736
|
+
return result;
|
|
18614
18737
|
}
|
|
18615
18738
|
async function main() {
|
|
18616
18739
|
try {
|
|
18617
|
-
const
|
|
18740
|
+
const servers = await startServer();
|
|
18618
18741
|
const shutdown = async () => {
|
|
18619
18742
|
try {
|
|
18620
|
-
|
|
18743
|
+
const closePromises = [];
|
|
18744
|
+
if (servers.http) {
|
|
18745
|
+
closePromises.push(servers.http.close());
|
|
18746
|
+
}
|
|
18747
|
+
if (servers.https) {
|
|
18748
|
+
closePromises.push(servers.https.close());
|
|
18749
|
+
}
|
|
18750
|
+
await Promise.all(closePromises);
|
|
18621
18751
|
process2.exit(0);
|
|
18622
18752
|
} catch (err) {
|
|
18623
|
-
|
|
18753
|
+
console.error("\u5173\u95ED\u670D\u52A1\u5931\u8D25:", err);
|
|
18624
18754
|
process2.exit(1);
|
|
18625
18755
|
}
|
|
18626
18756
|
};
|