billion-context 0.1.74 → 0.1.75-pr.485.304
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/agent/omp.js +13 -0
- package/dist/agent/omp.js.map +1 -1
- package/dist/agent/pi.js +13 -0
- package/dist/agent/pi.js.map +1 -1
- package/dist/index.js +616 -311
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -48008,12 +48008,22 @@ import path3 from "path";
|
|
|
48008
48008
|
// src/fetch-util.ts
|
|
48009
48009
|
var MAX_REQUEST_BYTES = 100 * 1024 * 1024;
|
|
48010
48010
|
var UPSTREAM_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
48011
|
+
var liveUpstreamTimers = /* @__PURE__ */ new Set();
|
|
48011
48012
|
async function fetchWithTimeout(url, opts, timeoutMs = UPSTREAM_TIMEOUT_MS, externalSignal) {
|
|
48012
48013
|
const controller = new AbortController();
|
|
48013
|
-
|
|
48014
|
+
const armTimer = () => {
|
|
48015
|
+
const t = setTimeout(() => {
|
|
48016
|
+
liveUpstreamTimers.delete(t);
|
|
48017
|
+
controller.abort();
|
|
48018
|
+
}, timeoutMs);
|
|
48019
|
+
liveUpstreamTimers.add(t);
|
|
48020
|
+
return t;
|
|
48021
|
+
};
|
|
48022
|
+
let timer2 = armTimer();
|
|
48014
48023
|
const rearm = () => {
|
|
48015
48024
|
clearTimeout(timer2);
|
|
48016
|
-
|
|
48025
|
+
liveUpstreamTimers.delete(timer2);
|
|
48026
|
+
timer2 = armTimer();
|
|
48017
48027
|
};
|
|
48018
48028
|
let onExternalAbort = null;
|
|
48019
48029
|
if (externalSignal) {
|
|
@@ -48025,6 +48035,7 @@ async function fetchWithTimeout(url, opts, timeoutMs = UPSTREAM_TIMEOUT_MS, exte
|
|
|
48025
48035
|
}
|
|
48026
48036
|
const cleanup = () => {
|
|
48027
48037
|
clearTimeout(timer2);
|
|
48038
|
+
liveUpstreamTimers.delete(timer2);
|
|
48028
48039
|
if (onExternalAbort && externalSignal) externalSignal.removeEventListener("abort", onExternalAbort);
|
|
48029
48040
|
};
|
|
48030
48041
|
try {
|
|
@@ -50106,6 +50117,58 @@ function reconcileNativeCompactionBoundary(session) {
|
|
|
50106
50117
|
markDirty(session);
|
|
50107
50118
|
return true;
|
|
50108
50119
|
}
|
|
50120
|
+
function markCompactionBoundary(session) {
|
|
50121
|
+
session.metadata.compactionBoundary = {
|
|
50122
|
+
at: Date.now(),
|
|
50123
|
+
pending: true
|
|
50124
|
+
};
|
|
50125
|
+
markDirty(session);
|
|
50126
|
+
}
|
|
50127
|
+
function readPreCompactionArchive(session) {
|
|
50128
|
+
const raw = session.metadata.preCompactionArchive;
|
|
50129
|
+
if (raw && typeof raw === "object" && !Array.isArray(raw)) {
|
|
50130
|
+
return raw;
|
|
50131
|
+
}
|
|
50132
|
+
return {};
|
|
50133
|
+
}
|
|
50134
|
+
function preCompactionArchiveOf(session) {
|
|
50135
|
+
return readPreCompactionArchive(session);
|
|
50136
|
+
}
|
|
50137
|
+
function applyCompactionArchive(session, activeBefore, liveRawIds, log2) {
|
|
50138
|
+
const boundary = session.metadata.compactionBoundary;
|
|
50139
|
+
if (!boundary || typeof boundary !== "object" || !boundary.pending) {
|
|
50140
|
+
return;
|
|
50141
|
+
}
|
|
50142
|
+
const activeAfter = new Set(session.state.blocks.filter((b2) => b2.active).map((b2) => b2.blockId));
|
|
50143
|
+
const deactivated = [...activeBefore].filter((id) => !activeAfter.has(id));
|
|
50144
|
+
if (deactivated.length > 0) {
|
|
50145
|
+
const archive = readPreCompactionArchive(session);
|
|
50146
|
+
const at2 = Date.now();
|
|
50147
|
+
for (const id of deactivated) {
|
|
50148
|
+
archive[id] = { at: at2, reason: "content replaced by client native compaction summary" };
|
|
50149
|
+
}
|
|
50150
|
+
session.metadata.preCompactionArchive = archive;
|
|
50151
|
+
}
|
|
50152
|
+
const { byRaw, byRef } = session.state.messageRefs;
|
|
50153
|
+
const prunedByRaw = {};
|
|
50154
|
+
for (const [rawId, ref] of Object.entries(byRaw)) {
|
|
50155
|
+
if (liveRawIds.has(rawId)) prunedByRaw[rawId] = ref;
|
|
50156
|
+
}
|
|
50157
|
+
const prunedByRef = {};
|
|
50158
|
+
for (const [ref, rawId] of Object.entries(byRef)) {
|
|
50159
|
+
if (liveRawIds.has(rawId)) prunedByRef[ref] = rawId;
|
|
50160
|
+
}
|
|
50161
|
+
session.state.messageRefs.byRaw = prunedByRaw;
|
|
50162
|
+
session.state.messageRefs.byRef = prunedByRef;
|
|
50163
|
+
session.metadata.compactionBoundary = {
|
|
50164
|
+
...boundary,
|
|
50165
|
+
pending: false,
|
|
50166
|
+
archivedAt: Date.now(),
|
|
50167
|
+
archivedBlocks: deactivated
|
|
50168
|
+
};
|
|
50169
|
+
markDirty(session);
|
|
50170
|
+
log2("info", `[${session.id}] native compaction boundary: archived ${deactivated.length} pre-compaction block(s)${deactivated.length > 0 ? ` (${deactivated.join(", ")})` : ""}; pruned ref maps to ${prunedByRaw.length} live raw id(s)`);
|
|
50171
|
+
}
|
|
50109
50172
|
function evictOldest() {
|
|
50110
50173
|
let oldestId;
|
|
50111
50174
|
let oldestSeen = Infinity;
|
|
@@ -50182,6 +50245,10 @@ function resolveDecompress(args, ctx) {
|
|
|
50182
50245
|
const blockId = rawBlockId.trim();
|
|
50183
50246
|
const block = ctx.core.decompress(blockId, ctx.session.state);
|
|
50184
50247
|
if (!block) return `[Block ${blockId} not found]`;
|
|
50248
|
+
const archived = preCompactionArchiveOf(ctx.session);
|
|
50249
|
+
if (archived[blockId] !== void 0) {
|
|
50250
|
+
return `[decompress FAILED: block ${blockId} is a pre-compaction archive \u2014 its content was in the history BEFORE the client's native compaction and is no longer reachable (replaced by the client's compaction summary). decompress is unavailable for archived blocks.]`;
|
|
50251
|
+
}
|
|
50185
50252
|
const full = args.full === true;
|
|
50186
50253
|
const cached = ctx.session.blockContents.get(blockId);
|
|
50187
50254
|
let body;
|
|
@@ -51427,6 +51494,8 @@ function handleAcpStatus(args, ctx) {
|
|
|
51427
51494
|
const nudge = ctx.nudge;
|
|
51428
51495
|
const ranges = nudge?.compressibleRanges ?? [];
|
|
51429
51496
|
const protectedRanges = nudge?.protectedRanges ?? [];
|
|
51497
|
+
const archive = preCompactionArchiveOf(ctx.session);
|
|
51498
|
+
const archivedIds = Object.keys(archive);
|
|
51430
51499
|
const extra = [];
|
|
51431
51500
|
if (nudge) {
|
|
51432
51501
|
extra.push("");
|
|
@@ -51436,6 +51505,13 @@ function handleAcpStatus(args, ctx) {
|
|
|
51436
51505
|
extra.push("");
|
|
51437
51506
|
extra.push(formatRanges(ranges, protectedRanges));
|
|
51438
51507
|
}
|
|
51508
|
+
if (archivedIds.length > 0) {
|
|
51509
|
+
extra.push("");
|
|
51510
|
+
extra.push(`PRE-COMPACTION ARCHIVE \u2014 ${archivedIds.length} block(s): content was replaced by the client's native compaction summary, so it is no longer in the session history and decompress is unavailable.`);
|
|
51511
|
+
for (const id of archivedIds) {
|
|
51512
|
+
extra.push(` ${id} \u2014 ${archive[id].reason}`);
|
|
51513
|
+
}
|
|
51514
|
+
}
|
|
51439
51515
|
return extra.length > 0 ? `${base}
|
|
51440
51516
|
${extra.join("\n")}` : base;
|
|
51441
51517
|
}
|
|
@@ -54239,6 +54315,32 @@ function handlePluginRegister(payload, res) {
|
|
|
54239
54315
|
queuePluginRegister(conversationId2, agent, parsed.identity === true);
|
|
54240
54316
|
res.end(JSON.stringify({ ok: true, conversationId: conversationId2, agent }));
|
|
54241
54317
|
}
|
|
54318
|
+
function handlePluginCompact(payload, res) {
|
|
54319
|
+
let parsed;
|
|
54320
|
+
try {
|
|
54321
|
+
parsed = JSON.parse(payload);
|
|
54322
|
+
} catch {
|
|
54323
|
+
res.writeHead(400, { "content-type": "application/json" });
|
|
54324
|
+
res.end(JSON.stringify({ ok: false, error: "invalid JSON body" }));
|
|
54325
|
+
return;
|
|
54326
|
+
}
|
|
54327
|
+
const conversationId2 = typeof parsed.conversationId === "string" ? parsed.conversationId.trim() : "";
|
|
54328
|
+
if (!conversationId2) {
|
|
54329
|
+
res.writeHead(400, { "content-type": "application/json" });
|
|
54330
|
+
res.end(JSON.stringify({ ok: false, error: "conversationId is required" }));
|
|
54331
|
+
return;
|
|
54332
|
+
}
|
|
54333
|
+
const entry = conversations.get(conversationId2);
|
|
54334
|
+
const session = entry ? peekSession(entry.sessionId) : void 0;
|
|
54335
|
+
if (!entry || !session) {
|
|
54336
|
+
res.writeHead(404, { "content-type": "application/json" });
|
|
54337
|
+
res.end(JSON.stringify({ ok: false, error: "unknown plugin conversation (no model request has arrived with this conversation id yet)" }));
|
|
54338
|
+
return;
|
|
54339
|
+
}
|
|
54340
|
+
markCompactionBoundary(session);
|
|
54341
|
+
entry.lastSeen = Date.now();
|
|
54342
|
+
res.end(JSON.stringify({ ok: true, conversationId: conversationId2 }));
|
|
54343
|
+
}
|
|
54242
54344
|
function handlePluginManifest(res) {
|
|
54243
54345
|
res.writeHead(200, { "content-type": "application/json" });
|
|
54244
54346
|
res.end(JSON.stringify({
|
|
@@ -54472,6 +54574,12 @@ data: ${JSON.stringify({ type: "content_block_delta", index, delta: { type: delt
|
|
|
54472
54574
|
return new Promise((r) => res.once("drain", () => r()));
|
|
54473
54575
|
}
|
|
54474
54576
|
};
|
|
54577
|
+
const settleUsage = () => {
|
|
54578
|
+
if (session && (acc.inputTokens !== void 0 || acc.outputTokens !== void 0 || acc.cachedTokens !== void 0)) {
|
|
54579
|
+
applyUsageSample(session, acc, protocol);
|
|
54580
|
+
markDirty(session);
|
|
54581
|
+
}
|
|
54582
|
+
};
|
|
54475
54583
|
const pushField = (field, index, text) => {
|
|
54476
54584
|
const s3 = filterFor(field, index);
|
|
54477
54585
|
const clean = s3.filter.push(text);
|
|
@@ -54577,10 +54685,14 @@ data: ${JSON.stringify({ type: "content_block_delta", index, delta: { type: delt
|
|
|
54577
54685
|
}
|
|
54578
54686
|
const rest = flushTails();
|
|
54579
54687
|
if (rest.length > 0 && !res.destroyed && !res.writableEnded) await write(rest);
|
|
54580
|
-
|
|
54581
|
-
|
|
54582
|
-
|
|
54688
|
+
settleUsage();
|
|
54689
|
+
} catch (e) {
|
|
54690
|
+
settleUsage();
|
|
54691
|
+
if (res.destroyed || res.writableEnded) {
|
|
54692
|
+
log2?.("client aborted mid-stream");
|
|
54693
|
+
return;
|
|
54583
54694
|
}
|
|
54695
|
+
throw e;
|
|
54584
54696
|
} finally {
|
|
54585
54697
|
reader.releaseLock();
|
|
54586
54698
|
res.end();
|
|
@@ -54614,6 +54726,12 @@ async function pipePluginResponsesWithStrip(stream2, res, session, log2) {
|
|
|
54614
54726
|
return new Promise((r) => res.once("drain", () => r()));
|
|
54615
54727
|
}
|
|
54616
54728
|
};
|
|
54729
|
+
const settleUsage = () => {
|
|
54730
|
+
if (session && (acc.inputTokens !== void 0 || acc.outputTokens !== void 0 || acc.cachedTokens !== void 0)) {
|
|
54731
|
+
applyUsageSample(session, acc, "responses");
|
|
54732
|
+
markDirty(session);
|
|
54733
|
+
}
|
|
54734
|
+
};
|
|
54617
54735
|
let lastDeltaMeta = null;
|
|
54618
54736
|
const flushTail = (after) => {
|
|
54619
54737
|
const tail = tagFilter.flush();
|
|
@@ -54686,10 +54804,14 @@ async function pipePluginResponsesWithStrip(stream2, res, session, log2) {
|
|
|
54686
54804
|
const rest = flushTail("");
|
|
54687
54805
|
if (rest.length > 0) await write(rest);
|
|
54688
54806
|
}
|
|
54689
|
-
|
|
54690
|
-
|
|
54691
|
-
|
|
54807
|
+
settleUsage();
|
|
54808
|
+
} catch (e) {
|
|
54809
|
+
settleUsage();
|
|
54810
|
+
if (res.destroyed || res.writableEnded) {
|
|
54811
|
+
log2?.("client aborted mid-stream");
|
|
54812
|
+
return;
|
|
54692
54813
|
}
|
|
54814
|
+
throw e;
|
|
54693
54815
|
} finally {
|
|
54694
54816
|
reader.releaseLock();
|
|
54695
54817
|
res.end();
|
|
@@ -54715,10 +54837,16 @@ function rebuildEvent(rawEvent, ev) {
|
|
|
54715
54837
|
async function pipePluginJson(stream2, res, session, protocol) {
|
|
54716
54838
|
const reader = stream2.getReader();
|
|
54717
54839
|
const chunks = [];
|
|
54718
|
-
|
|
54719
|
-
|
|
54720
|
-
|
|
54721
|
-
|
|
54840
|
+
try {
|
|
54841
|
+
for (; ; ) {
|
|
54842
|
+
const { done, value } = await reader.read();
|
|
54843
|
+
if (done) break;
|
|
54844
|
+
if (value && value.length > 0) chunks.push(Buffer.from(value));
|
|
54845
|
+
}
|
|
54846
|
+
} catch (e) {
|
|
54847
|
+
if (!res.writableEnded) res.end();
|
|
54848
|
+
if (res.destroyed || res.writableEnded) return;
|
|
54849
|
+
throw e;
|
|
54722
54850
|
}
|
|
54723
54851
|
reader.releaseLock();
|
|
54724
54852
|
const text = Buffer.concat(chunks).toString("utf8");
|
|
@@ -56369,7 +56497,10 @@ async function startServer(opts) {
|
|
|
56369
56497
|
await handle(req, res, opts, core, config, log2, instanceId, instanceStartedAt);
|
|
56370
56498
|
} catch (err2) {
|
|
56371
56499
|
const msg = String(err2);
|
|
56372
|
-
|
|
56500
|
+
const e = err2;
|
|
56501
|
+
const clientAbort = (e?.name === "AbortError" || /abort/i.test(String(e?.message ?? ""))) && (res.destroyed || res.writableEnded);
|
|
56502
|
+
if (clientAbort) log2("info", `client aborted mid-stream: ${msg}`);
|
|
56503
|
+
else log2("error", msg);
|
|
56373
56504
|
if (!res.headersSent) {
|
|
56374
56505
|
const status = msg.includes("exceeds") ? 413 : 502;
|
|
56375
56506
|
res.writeHead(status, { "content-type": "application/json" });
|
|
@@ -56665,6 +56796,17 @@ async function handle(req, res, opts, core, config, log2, instanceId, instanceSt
|
|
|
56665
56796
|
return;
|
|
56666
56797
|
}
|
|
56667
56798
|
}
|
|
56799
|
+
if (req.method === "POST" && req.url === "/__bili/plugin/compact") {
|
|
56800
|
+
try {
|
|
56801
|
+
const body = await readBody(req);
|
|
56802
|
+
handlePluginCompact(body.toString("utf8"), res);
|
|
56803
|
+
return;
|
|
56804
|
+
} catch (err2) {
|
|
56805
|
+
res.writeHead(err2 instanceof BodyTooLargeError ? 413 : 400, { "content-type": "application/json" });
|
|
56806
|
+
res.end(JSON.stringify({ ok: false, error: String(err2) }));
|
|
56807
|
+
return;
|
|
56808
|
+
}
|
|
56809
|
+
}
|
|
56668
56810
|
if (isAdminPath) {
|
|
56669
56811
|
res.writeHead(404, { "content-type": "application/json" });
|
|
56670
56812
|
res.end(JSON.stringify({ error: { type: "not_found", message: "no such management endpoint" } }));
|
|
@@ -56894,6 +57036,7 @@ ${bodyBuffer.toString("utf8")}`);
|
|
|
56894
57036
|
nativeFromFallback = false;
|
|
56895
57037
|
log2("info", `[${session.id}] self-healed context window: ${resolved} \u2192 ${learnedLimit} (learned from an upstream overflow)`);
|
|
56896
57038
|
}
|
|
57039
|
+
const nativeWindow = reqConfig.modelContextLimit;
|
|
56897
57040
|
if (shouldReserveOutputHeadroom(protocol)) {
|
|
56898
57041
|
const p2 = parsed;
|
|
56899
57042
|
const rawMax = p2.max_tokens ?? p2.max_completion_tokens ?? p2.max_output_tokens;
|
|
@@ -56908,7 +57051,7 @@ ${bodyBuffer.toString("utf8")}`);
|
|
|
56908
57051
|
acquireInFlight(session);
|
|
56909
57052
|
try {
|
|
56910
57053
|
await withSessionLock(session, async () => {
|
|
56911
|
-
const runPrepare = () => countTokens ? prepareCountTokens(parsed, core, reqConfig, log2, session) : protocol === "anthropic" ? prepareAnthropic(parsed, req, opts, core, reqConfig, reqPrompts, log2, session, pluginMode) : protocol === "openai" ? prepareOpenai(parsed, req, opts, core, reqConfig, reqPrompts, log2, session, pluginMode) : responsesCompact ? prepareResponsesCompact(bodyBuffer, parsed, session, req, core, reqConfig, log2) : prepareResponses(parsed, req, opts, core, reqConfig, reqPrompts, log2, session, responsesIdentity, pluginMode, upstreamOrigin);
|
|
57054
|
+
const runPrepare = () => countTokens ? prepareCountTokens(parsed, core, reqConfig, log2, session) : protocol === "anthropic" ? prepareAnthropic(parsed, req, opts, core, reqConfig, reqPrompts, log2, session, pluginMode) : protocol === "openai" ? prepareOpenai(parsed, req, opts, core, reqConfig, reqPrompts, log2, session, pluginMode, nativeWindow) : responsesCompact ? prepareResponsesCompact(bodyBuffer, parsed, session, req, core, reqConfig, log2) : prepareResponses(parsed, req, opts, core, reqConfig, reqPrompts, log2, session, responsesIdentity, pluginMode, upstreamOrigin, nativeWindow);
|
|
56912
57055
|
prepared = runPrepare();
|
|
56913
57056
|
if (!countTokens && !responsesCompact) {
|
|
56914
57057
|
const outcome = await preflightCompressIfNeeded(
|
|
@@ -56992,7 +57135,7 @@ function diagNudge(turn, sessionId, tokenCount, limit, model, willInject) {
|
|
|
56992
57135
|
const interval = b2["nudgeGrowthTokens"] ?? 0;
|
|
56993
57136
|
const pendingT1 = b2["pendingT1"] ?? 0;
|
|
56994
57137
|
const ref = b2["growthReference"] ?? 0;
|
|
56995
|
-
const inject =
|
|
57138
|
+
const inject = willInject ? n.shouldInject ? `INJECT T${n.tier ?? "?"}` : `INJECT-ESC T${n.tier ?? "?"}` : n.shouldInject ? `ARMED-SUPPRESSED T${n.tier ?? "?"}` : "idle";
|
|
56996
57139
|
const modelTag = model ? ` model=${model}` : "";
|
|
56997
57140
|
return `[${sessionId}] nudge ${inject}: usage=${pct2} (${tokenCount}/${limit}), growth=${growth}/${floor} (ref=${ref}, interval=${interval}), pendingT1=${pendingT1}/${interval}${modelTag}, reason="${n.reason.slice(0, 120)}"`;
|
|
56998
57141
|
}
|
|
@@ -57016,6 +57159,7 @@ function prepareAnthropic(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
57016
57159
|
originalMessages = msgs;
|
|
57017
57160
|
extractSystem(parsed.system);
|
|
57018
57161
|
const tokenCount = session.stats.lastInputTokens;
|
|
57162
|
+
const activeBefore = new Set(session.state.blocks.filter((b2) => b2.active).map((b2) => b2.blockId));
|
|
57019
57163
|
const turn = core.processTurn({ messages: msgs, state: session.state, config, tokenCount, renderTags: "text-only" });
|
|
57020
57164
|
session.state = turn.state;
|
|
57021
57165
|
session.stats.compressCreditTokens = 0;
|
|
@@ -57027,9 +57171,10 @@ function prepareAnthropic(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
57027
57171
|
if (t) session.meta.title = t;
|
|
57028
57172
|
}
|
|
57029
57173
|
log2("info", diagTagSummary(turn.messages, sessionId, "text-only"));
|
|
57030
|
-
const willInjectNudge = opts.compress.injectNudge && !!turn.nudge
|
|
57174
|
+
const willInjectNudge = opts.compress.injectNudge && !!turn.nudge && (turn.nudge.shouldInject || emergencyNudge(turn.nudge));
|
|
57031
57175
|
log2("info", diagNudge(turn, sessionId, tokenCount, config.modelContextLimit, parsed.model, willInjectNudge));
|
|
57032
57176
|
processedMessages = stripKernelSummaries(turn.messages, turn.state);
|
|
57177
|
+
applyCompactionArchive(session, activeBefore, new Set(msgs.map((m2) => m2.id)), log2);
|
|
57033
57178
|
reapOrphanBlocks(session, msgs, deactivateBlock);
|
|
57034
57179
|
rebuiltMessages = coreToAnthropic(processedMessages, cacheControls);
|
|
57035
57180
|
systemOut = injectSystem(parsed, opts, prompts);
|
|
@@ -57055,7 +57200,36 @@ function prepareAnthropic(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
57055
57200
|
delete rebuilt.prompt_cache_key;
|
|
57056
57201
|
return { body: JSON.stringify(rebuilt), session, processedMessages, originalMessages, anthropicSystem: parsed.system, protocol: "anthropic", stream: stream2, compressInjected: injectTools, pluginMode, nudge, prompts, renderTags: "text-only" };
|
|
57057
57202
|
}
|
|
57058
|
-
|
|
57203
|
+
var OUTPUT_CLAMP_MARGIN_PCT = 0.05;
|
|
57204
|
+
var OUTPUT_CLAMP_MIN_MARGIN = 2048;
|
|
57205
|
+
var OUTPUT_CLAMP_FLOOR = 1024;
|
|
57206
|
+
var EMERGENCY_NUDGE_ESCALATION_PCT = 0.7;
|
|
57207
|
+
function estimateInputTokens(processedMessages, systemText, tools, lastInputTokens) {
|
|
57208
|
+
const est = estimateCoreMessages(processedMessages) + defaultCountTokens(systemText ?? "") + defaultCountTokens(JSON.stringify(tools ?? []));
|
|
57209
|
+
return Math.max(lastInputTokens > 0 ? lastInputTokens : 0, est);
|
|
57210
|
+
}
|
|
57211
|
+
function clampOutputBudget(requested, inputEstimate, nativeWindow) {
|
|
57212
|
+
const margin = Math.max(OUTPUT_CLAMP_MIN_MARGIN, Math.ceil(inputEstimate * OUTPUT_CLAMP_MARGIN_PCT));
|
|
57213
|
+
const cap = nativeWindow - inputEstimate - margin;
|
|
57214
|
+
if (cap < OUTPUT_CLAMP_FLOOR || cap >= requested) return void 0;
|
|
57215
|
+
return cap;
|
|
57216
|
+
}
|
|
57217
|
+
function emergencyNudge(nudge, escalationPct = EMERGENCY_NUDGE_ESCALATION_PCT) {
|
|
57218
|
+
if (!nudge || nudge.shouldInject) return false;
|
|
57219
|
+
if (nudge.compressibleRanges.length === 0) return false;
|
|
57220
|
+
return nudge.contextUsage >= escalationPct;
|
|
57221
|
+
}
|
|
57222
|
+
function clampOutgoingOutput(rebuilt, field, ctx, sessionId, log2) {
|
|
57223
|
+
const raw = rebuilt[field];
|
|
57224
|
+
if (typeof raw !== "number") return;
|
|
57225
|
+
const inputEstimate = estimateInputTokens(ctx.processedMessages, ctx.systemText, ctx.tools, ctx.lastInputTokens);
|
|
57226
|
+
const capped = clampOutputBudget(raw, inputEstimate, ctx.nativeWindow);
|
|
57227
|
+
if (capped !== void 0) {
|
|
57228
|
+
rebuilt[field] = capped;
|
|
57229
|
+
log2("info", `[${sessionId}] output budget clamped ${raw} -> ${capped} (input~${inputEstimate}, window=${ctx.nativeWindow}); prevents input+output overflow (#453)`);
|
|
57230
|
+
}
|
|
57231
|
+
}
|
|
57232
|
+
function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session, pluginMode, nativeWindow) {
|
|
57059
57233
|
const sessionId = session.id;
|
|
57060
57234
|
const stream2 = parsed.stream === true;
|
|
57061
57235
|
++session.stats.requests;
|
|
@@ -57074,6 +57248,7 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session,
|
|
|
57074
57248
|
openaiSystemText = systemText;
|
|
57075
57249
|
originalMessages = msgs;
|
|
57076
57250
|
const tokenCount = session.stats.lastInputTokens;
|
|
57251
|
+
const activeBefore = new Set(session.state.blocks.filter((b2) => b2.active).map((b2) => b2.blockId));
|
|
57077
57252
|
const turn = core.processTurn({ messages: msgs, state: session.state, config, tokenCount, renderTags: "text-only" });
|
|
57078
57253
|
session.state = turn.state;
|
|
57079
57254
|
session.stats.compressCreditTokens = 0;
|
|
@@ -57085,9 +57260,10 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session,
|
|
|
57085
57260
|
if (t) session.meta.title = t;
|
|
57086
57261
|
}
|
|
57087
57262
|
log2("info", diagTagSummary(turn.messages, sessionId, "text-only"));
|
|
57088
|
-
const willInjectNudge = opts.compress.injectNudge && !!turn.nudge
|
|
57263
|
+
const willInjectNudge = opts.compress.injectNudge && !!turn.nudge && shouldInject && (turn.nudge.shouldInject || emergencyNudge(turn.nudge));
|
|
57089
57264
|
log2("info", diagNudge(turn, sessionId, tokenCount, config.modelContextLimit, parsed.model, willInjectNudge));
|
|
57090
57265
|
processedMessages = stripKernelSummaries(turn.messages, turn.state);
|
|
57266
|
+
applyCompactionArchive(session, activeBefore, new Set(msgs.map((m2) => m2.id)), log2);
|
|
57091
57267
|
reapOrphanBlocks(session, msgs, deactivateBlock);
|
|
57092
57268
|
rebuiltMessages = systemToUser(coreToOpenai(processedMessages));
|
|
57093
57269
|
const sysParts = [];
|
|
@@ -57111,6 +57287,7 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session,
|
|
|
57111
57287
|
processedMessages = [];
|
|
57112
57288
|
}
|
|
57113
57289
|
const rebuilt = { ...parsed, messages: rebuiltMessages, tools: toolsOut };
|
|
57290
|
+
clampOutgoingOutput(rebuilt, typeof parsed.max_completion_tokens === "number" ? "max_completion_tokens" : "max_tokens", { systemText: openaiSystemText, tools: toolsOut, processedMessages, lastInputTokens: session.stats.lastInputTokens, nativeWindow }, sessionId, log2);
|
|
57114
57291
|
delete rebuilt.prompt_cache_retention;
|
|
57115
57292
|
if (stream2 && rebuilt.stream_options === void 0) {
|
|
57116
57293
|
rebuilt.stream_options = { include_usage: true };
|
|
@@ -57119,7 +57296,7 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session,
|
|
|
57119
57296
|
markDirty(session);
|
|
57120
57297
|
return { body: JSON.stringify(rebuilt), session, processedMessages, originalMessages, protocol: "openai", stream: stream2, compressInjected: injectTools, pluginMode, nudge, prompts, openaiSystemText, renderTags: "text-only" };
|
|
57121
57298
|
}
|
|
57122
|
-
function prepareResponses(parsed, req, opts, core, config, prompts, log2, session, identity, pluginMode, upstreamOrigin) {
|
|
57299
|
+
function prepareResponses(parsed, req, opts, core, config, prompts, log2, session, identity, pluginMode, upstreamOrigin, nativeWindow) {
|
|
57123
57300
|
const sessionId = session.id;
|
|
57124
57301
|
const stream2 = parsed.stream === true;
|
|
57125
57302
|
++session.stats.requests;
|
|
@@ -57176,7 +57353,7 @@ function prepareResponses(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
57176
57353
|
if (t) session.meta.title = t;
|
|
57177
57354
|
}
|
|
57178
57355
|
log2("info", diagTagSummary(turn.messages, sessionId, "text-only"));
|
|
57179
|
-
const willInjectNudge = opts.compress.injectNudge && !!turn.nudge
|
|
57356
|
+
const willInjectNudge = opts.compress.injectNudge && !!turn.nudge && shouldInject && !isCompactionTrigger && (turn.nudge.shouldInject || emergencyNudge(turn.nudge));
|
|
57180
57357
|
log2("info", diagNudge(turn, sessionId, tokenCount, config.modelContextLimit, parsed.model, willInjectNudge));
|
|
57181
57358
|
processedMessages = stripKernelSummaries(turn.messages, turn.state);
|
|
57182
57359
|
reapOrphanBlocks(session, msgs, deactivateBlock);
|
|
@@ -57227,6 +57404,9 @@ function prepareResponses(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
57227
57404
|
log2("info", `[${sessionId}] codex compact intercepted (trigger); forged SSE with ${summaries.length} block summary(s), upstream not contacted`);
|
|
57228
57405
|
}
|
|
57229
57406
|
const rebuilt = { ...parsed, input: rebuiltInput, tools: toolsOut };
|
|
57407
|
+
if (!isCompactionTrigger) {
|
|
57408
|
+
clampOutgoingOutput(rebuilt, "max_output_tokens", { systemText: (responsesProjection?.systemParts ?? []).join("\n"), tools: toolsOut, processedMessages, lastInputTokens: session.stats.lastInputTokens, nativeWindow }, sessionId, log2);
|
|
57409
|
+
}
|
|
57230
57410
|
const promptCacheKey = resolvePromptCacheKey(
|
|
57231
57411
|
rebuilt.prompt_cache_key,
|
|
57232
57412
|
identity,
|
|
@@ -57709,187 +57889,191 @@ ${hdrText}
|
|
|
57709
57889
|
return;
|
|
57710
57890
|
}
|
|
57711
57891
|
if (prepared?.pluginMode) {
|
|
57712
|
-
|
|
57713
|
-
if (prepared.
|
|
57714
|
-
|
|
57892
|
+
try {
|
|
57893
|
+
if (prepared.stream) {
|
|
57894
|
+
if (prepared.protocol === "responses") {
|
|
57895
|
+
await pipePluginResponsesWithStrip(upstream.body, res, prepared.session, (msg) => log2("info", `[${prepared.session.id}] ${msg}`));
|
|
57896
|
+
} else {
|
|
57897
|
+
await pipePluginChatWithStrip(upstream.body, res, prepared.protocol, prepared.session, (msg) => log2("info", `[${prepared.session.id}] ${msg}`));
|
|
57898
|
+
}
|
|
57715
57899
|
} else {
|
|
57716
|
-
await
|
|
57900
|
+
await pipePluginJson(upstream.body, res, prepared.session, prepared.protocol);
|
|
57717
57901
|
}
|
|
57718
|
-
}
|
|
57719
|
-
|
|
57902
|
+
} finally {
|
|
57903
|
+
clearUpstreamTimer();
|
|
57720
57904
|
}
|
|
57721
|
-
clearUpstreamTimer();
|
|
57722
57905
|
return;
|
|
57723
57906
|
}
|
|
57724
57907
|
let responseBody = upstream.body;
|
|
57725
|
-
|
|
57726
|
-
|
|
57727
|
-
|
|
57728
|
-
|
|
57729
|
-
|
|
57730
|
-
|
|
57731
|
-
|
|
57732
|
-
|
|
57733
|
-
|
|
57734
|
-
|
|
57735
|
-
|
|
57736
|
-
|
|
57737
|
-
|
|
57738
|
-
|
|
57739
|
-
|
|
57740
|
-
if (prepared
|
|
57741
|
-
|
|
57742
|
-
|
|
57743
|
-
|
|
57744
|
-
|
|
57745
|
-
|
|
57746
|
-
|
|
57747
|
-
|
|
57748
|
-
|
|
57749
|
-
|
|
57750
|
-
|
|
57751
|
-
|
|
57752
|
-
|
|
57753
|
-
|
|
57754
|
-
|
|
57755
|
-
|
|
57756
|
-
|
|
57757
|
-
|
|
57758
|
-
|
|
57759
|
-
|
|
57760
|
-
|
|
57761
|
-
|
|
57908
|
+
try {
|
|
57909
|
+
if (prepared !== null && prepared.stream && maxFakeCompletionRetries() > 0) {
|
|
57910
|
+
const resolvedBuf = await resolveFakeCompletion(upstream.body, {
|
|
57911
|
+
protocol: prepared.protocol,
|
|
57912
|
+
body,
|
|
57913
|
+
upstreamUrl,
|
|
57914
|
+
reqHeaders: buildForwardHeaders(headers),
|
|
57915
|
+
proxyUrl,
|
|
57916
|
+
signal: clientAbort.signal,
|
|
57917
|
+
session: prepared.session,
|
|
57918
|
+
log: log2
|
|
57919
|
+
});
|
|
57920
|
+
responseBody = bufferToStream(resolvedBuf);
|
|
57921
|
+
}
|
|
57922
|
+
const useRewriter = prepared !== null && prepared.compressInjected && prepared.processedMessages.length > 0;
|
|
57923
|
+
if (!useRewriter || prepared === null) {
|
|
57924
|
+
if (prepared && prepared.resetAfterSuccess) {
|
|
57925
|
+
const [toClient, toObserve] = responseBody.tee();
|
|
57926
|
+
const observed = observeResponsesTerminalState(toObserve, prepared.stream);
|
|
57927
|
+
const tagLog = (msg) => log2("info", `[${prepared.session.id}] ${msg}`);
|
|
57928
|
+
if ((upstream.headers.get("content-type") ?? "").includes("text/event-stream")) {
|
|
57929
|
+
await pipePluginResponsesWithStrip(toClient, res, void 0, tagLog);
|
|
57930
|
+
} else {
|
|
57931
|
+
await pipeThrough(toClient, res);
|
|
57932
|
+
}
|
|
57933
|
+
const terminal = await observed;
|
|
57934
|
+
if (terminal === "completed") {
|
|
57935
|
+
markNativeCompactionBoundary(prepared.session);
|
|
57936
|
+
log2("info", `[${prepared.session.id}] native Responses compact completed; rebase scheduled for next Responses turn`);
|
|
57937
|
+
} else {
|
|
57938
|
+
log2("warn", `[${prepared.session.id}] native compact response terminal=${terminal}; rebase NOT scheduled`);
|
|
57939
|
+
}
|
|
57940
|
+
} else if (prepared && prepared.stream && (upstream.headers.get("content-type") ?? "").includes("text/event-stream")) {
|
|
57941
|
+
const p2 = prepared;
|
|
57942
|
+
const tagLog = (msg) => log2("info", `[${p2.session.id}] ${msg}`);
|
|
57943
|
+
if (p2.protocol === "responses") {
|
|
57944
|
+
await pipePluginResponsesWithStrip(responseBody, res, void 0, tagLog);
|
|
57945
|
+
} else {
|
|
57946
|
+
await pipePluginChatWithStrip(responseBody, res, p2.protocol, void 0, tagLog);
|
|
57947
|
+
}
|
|
57948
|
+
} else if (prepared && (upstream.headers.get("content-type") ?? "").includes("application/json")) {
|
|
57949
|
+
await pipePluginJson(responseBody, res, void 0, prepared.protocol);
|
|
57762
57950
|
} else {
|
|
57763
|
-
await
|
|
57951
|
+
await pipeThrough(responseBody, res);
|
|
57764
57952
|
}
|
|
57765
|
-
|
|
57766
|
-
} else if (prepared && (upstream.headers.get("content-type") ?? "").includes("application/json")) {
|
|
57767
|
-
await pipePluginJson(responseBody, res, void 0, prepared.protocol);
|
|
57768
|
-
clearUpstreamTimer();
|
|
57769
|
-
} else {
|
|
57770
|
-
await pipeThrough(responseBody, res);
|
|
57771
|
-
clearUpstreamTimer();
|
|
57772
|
-
}
|
|
57773
|
-
return;
|
|
57774
|
-
}
|
|
57775
|
-
const ctx = {
|
|
57776
|
-
core,
|
|
57777
|
-
config,
|
|
57778
|
-
messages: prepared.originalMessages,
|
|
57779
|
-
session: prepared.session,
|
|
57780
|
-
log: (msg) => log2("info", `[${prepared.session.id}] ${msg}`),
|
|
57781
|
-
debug: opts.debug
|
|
57782
|
-
};
|
|
57783
|
-
if (prepared.stream) {
|
|
57784
|
-
let streamToRead = responseBody;
|
|
57785
|
-
let dumpRaw;
|
|
57786
|
-
if (opts.dumpSse) {
|
|
57787
|
-
const [a, b2] = responseBody.tee();
|
|
57788
|
-
streamToRead = a;
|
|
57789
|
-
dumpRaw = dumpStreamToFile(b2, opts.dumpSse, `${Date.now()}-${safeSessionId(prepared.session.id)}-raw.sse`);
|
|
57953
|
+
return;
|
|
57790
57954
|
}
|
|
57791
|
-
|
|
57792
|
-
|
|
57793
|
-
|
|
57794
|
-
|
|
57795
|
-
|
|
57796
|
-
|
|
57797
|
-
|
|
57798
|
-
|
|
57799
|
-
|
|
57800
|
-
|
|
57801
|
-
|
|
57802
|
-
|
|
57803
|
-
|
|
57804
|
-
|
|
57805
|
-
prepared.session.
|
|
57806
|
-
const records = current.filter((m2) => typeof m2.id === "string" && m2.id.startsWith("acp_loop_"));
|
|
57807
|
-
return stripKernelSummaries([...turn.messages, ...records], turn.state);
|
|
57808
|
-
};
|
|
57809
|
-
const loop = runCompressLoop(
|
|
57810
|
-
streamToRead,
|
|
57811
|
-
{ core, config, messages: prepared.processedMessages.length > 0 ? prepared.processedMessages : prepared.originalMessages, compressMessages: prepared.originalMessages, session: prepared.session, log: ctx.log, proxyUrl, protocol: prepared.protocol, textProtocol, debug: opts.debug, nudge: prepared.nudge, refreshFolded },
|
|
57812
|
-
parsedReq,
|
|
57813
|
-
{ url: upstreamUrl, headers: reqHeaders },
|
|
57814
|
-
adapter,
|
|
57815
|
-
systemPrompt,
|
|
57816
|
-
clientAbort.signal
|
|
57817
|
-
);
|
|
57818
|
-
let protocolFragmentWarned = false;
|
|
57819
|
-
for await (const chunk of loop) {
|
|
57820
|
-
if (res.destroyed || res.writableEnded) break;
|
|
57821
|
-
{
|
|
57822
|
-
const s3 = chunk.toString("utf8");
|
|
57823
|
-
if (s3.includes("<acp ") || s3.includes("</acp")) {
|
|
57824
|
-
log2("warn", `[${prepared.session.id}] tag echo: ${prepared.protocol} response stream contains <acp tag`);
|
|
57825
|
-
} else if (!protocolFragmentWarned && containsToolCallXmlFragment(s3)) {
|
|
57826
|
-
protocolFragmentWarned = true;
|
|
57827
|
-
log2("warn", `[${prepared.session.id}] tag echo: ${prepared.protocol} response stream contains tool-call XML fragment (possible tag echo; not stripped)`);
|
|
57828
|
-
}
|
|
57829
|
-
}
|
|
57830
|
-
res.write(chunk);
|
|
57831
|
-
if (res.writableNeedDrain) {
|
|
57832
|
-
await Promise.race([
|
|
57833
|
-
new Promise((r) => res.once("drain", () => r())),
|
|
57834
|
-
new Promise((r) => res.once("close", () => r()))
|
|
57835
|
-
]);
|
|
57836
|
-
}
|
|
57837
|
-
if (res.destroyed || res.writableEnded) break;
|
|
57955
|
+
const ctx = {
|
|
57956
|
+
core,
|
|
57957
|
+
config,
|
|
57958
|
+
messages: prepared.originalMessages,
|
|
57959
|
+
session: prepared.session,
|
|
57960
|
+
log: (msg) => log2("info", `[${prepared.session.id}] ${msg}`),
|
|
57961
|
+
debug: opts.debug
|
|
57962
|
+
};
|
|
57963
|
+
if (prepared.stream) {
|
|
57964
|
+
let streamToRead = responseBody;
|
|
57965
|
+
let dumpRaw;
|
|
57966
|
+
if (opts.dumpSse) {
|
|
57967
|
+
const [a, b2] = responseBody.tee();
|
|
57968
|
+
streamToRead = a;
|
|
57969
|
+
dumpRaw = dumpStreamToFile(b2, opts.dumpSse, `${Date.now()}-${safeSessionId(prepared.session.id)}-raw.sse`);
|
|
57838
57970
|
}
|
|
57839
|
-
res.end();
|
|
57840
|
-
} catch (e) {
|
|
57841
|
-
emitStreamError(res, prepared.protocol, e?.message ?? String(e), (m2) => log2("error", `[${prepared.session.id}] ${m2}`));
|
|
57842
|
-
} finally {
|
|
57843
|
-
clearUpstreamTimer();
|
|
57844
|
-
if (dumpRaw) await dumpRaw;
|
|
57845
|
-
}
|
|
57846
|
-
} else {
|
|
57847
|
-
try {
|
|
57848
|
-
const buf = await upstream.arrayBuffer();
|
|
57849
|
-
const text = Buffer.from(buf).toString("utf8");
|
|
57850
57971
|
try {
|
|
57851
|
-
|
|
57852
|
-
|
|
57853
|
-
|
|
57854
|
-
|
|
57855
|
-
|
|
57856
|
-
|
|
57857
|
-
|
|
57858
|
-
|
|
57859
|
-
|
|
57860
|
-
|
|
57861
|
-
|
|
57862
|
-
|
|
57863
|
-
|
|
57864
|
-
|
|
57865
|
-
|
|
57866
|
-
|
|
57867
|
-
|
|
57868
|
-
|
|
57869
|
-
|
|
57870
|
-
|
|
57871
|
-
|
|
57872
|
-
|
|
57972
|
+
const parsedReq = JSON.parse(typeof body === "string" ? body : body.toString("utf8"));
|
|
57973
|
+
const reqHeaders = buildForwardHeaders(headers);
|
|
57974
|
+
const textProtocol = prepared.protocol === "responses" && !!prepared.responsesTextProtocol;
|
|
57975
|
+
const systemPrompt = textProtocol ? buildCompressHybridSystemPrompt(prepared.prompts ?? defaultPrompts) : buildCompressSystemPrompt(prepared.prompts ?? defaultPrompts);
|
|
57976
|
+
const adapter = pickAdapter(prepared.protocol, parsedReq, textProtocol, prepared.responsesProjection, prepared.anthropicSystem, prepared.openaiSystemText);
|
|
57977
|
+
const refreshFolded = (current) => {
|
|
57978
|
+
const turn = core.processTurn({
|
|
57979
|
+
messages: prepared.originalMessages,
|
|
57980
|
+
state: prepared.session.state,
|
|
57981
|
+
config,
|
|
57982
|
+
tokenCount: prepared.session.stats.lastInputTokens,
|
|
57983
|
+
renderTags: prepared.renderTags ?? "text-only"
|
|
57984
|
+
});
|
|
57985
|
+
prepared.session.state = turn.state;
|
|
57986
|
+
const records = current.filter((m2) => typeof m2.id === "string" && m2.id.startsWith("acp_loop_"));
|
|
57987
|
+
return stripKernelSummaries([...turn.messages, ...records], turn.state);
|
|
57988
|
+
};
|
|
57989
|
+
const loop = runCompressLoop(
|
|
57990
|
+
streamToRead,
|
|
57991
|
+
{ core, config, messages: prepared.processedMessages.length > 0 ? prepared.processedMessages : prepared.originalMessages, compressMessages: prepared.originalMessages, session: prepared.session, log: ctx.log, proxyUrl, protocol: prepared.protocol, textProtocol, debug: opts.debug, nudge: prepared.nudge, refreshFolded },
|
|
57992
|
+
parsedReq,
|
|
57993
|
+
{ url: upstreamUrl, headers: reqHeaders },
|
|
57994
|
+
adapter,
|
|
57995
|
+
systemPrompt,
|
|
57996
|
+
clientAbort.signal
|
|
57997
|
+
);
|
|
57998
|
+
let protocolFragmentWarned = false;
|
|
57999
|
+
for await (const chunk of loop) {
|
|
58000
|
+
if (res.destroyed || res.writableEnded) break;
|
|
58001
|
+
{
|
|
58002
|
+
const s3 = chunk.toString("utf8");
|
|
58003
|
+
if (s3.includes("<acp ") || s3.includes("</acp")) {
|
|
58004
|
+
log2("warn", `[${prepared.session.id}] tag echo: ${prepared.protocol} response stream contains <acp tag`);
|
|
58005
|
+
} else if (!protocolFragmentWarned && containsToolCallXmlFragment(s3)) {
|
|
58006
|
+
protocolFragmentWarned = true;
|
|
58007
|
+
log2("warn", `[${prepared.session.id}] tag echo: ${prepared.protocol} response stream contains tool-call XML fragment (possible tag echo; not stripped)`);
|
|
58008
|
+
}
|
|
58009
|
+
}
|
|
58010
|
+
res.write(chunk);
|
|
58011
|
+
if (res.writableNeedDrain) {
|
|
58012
|
+
await Promise.race([
|
|
58013
|
+
new Promise((r) => res.once("drain", () => r())),
|
|
58014
|
+
new Promise((r) => res.once("close", () => r()))
|
|
58015
|
+
]);
|
|
57873
58016
|
}
|
|
57874
|
-
|
|
57875
|
-
if (typeof out === "number") prepared.session.stats.outputTokens += out;
|
|
58017
|
+
if (res.destroyed || res.writableEnded) break;
|
|
57876
58018
|
}
|
|
57877
|
-
|
|
57878
|
-
|
|
57879
|
-
|
|
57880
|
-
|
|
57881
|
-
|
|
57882
|
-
|
|
58019
|
+
res.end();
|
|
58020
|
+
} catch (e) {
|
|
58021
|
+
emitStreamError(res, prepared.protocol, e?.message ?? String(e), (m2) => log2("error", `[${prepared.session.id}] ${m2}`));
|
|
58022
|
+
} finally {
|
|
58023
|
+
clearUpstreamTimer();
|
|
58024
|
+
if (dumpRaw) await dumpRaw;
|
|
58025
|
+
markDirty(prepared.session);
|
|
58026
|
+
}
|
|
58027
|
+
} else {
|
|
58028
|
+
try {
|
|
58029
|
+
const buf = await upstream.arrayBuffer();
|
|
58030
|
+
const text = Buffer.from(buf).toString("utf8");
|
|
58031
|
+
try {
|
|
58032
|
+
let json = JSON.parse(text);
|
|
58033
|
+
if (prepared.protocol === "responses" && prepared.responsesTextProtocol) {
|
|
58034
|
+
const requestBody = JSON.parse(typeof body === "string" ? body : body.toString("utf8"));
|
|
58035
|
+
const requestHeaders = buildForwardHeaders(headers);
|
|
58036
|
+
json = await compressLoopResponsesJson(
|
|
58037
|
+
json,
|
|
58038
|
+
{ core, config, messages: prepared.originalMessages, session: prepared.session, log: ctx.log, proxyUrl, textProtocol: true },
|
|
58039
|
+
requestBody,
|
|
58040
|
+
{ url: upstreamUrl, headers: requestHeaders }
|
|
58041
|
+
);
|
|
58042
|
+
}
|
|
58043
|
+
const u2 = json.usage ?? {};
|
|
58044
|
+
const { total, cached } = usageTotals(prepared.protocol, u2);
|
|
58045
|
+
if (typeof total === "number") {
|
|
58046
|
+
prepared.session.stats.inputTokens += total;
|
|
58047
|
+
prepared.session.stats.lastInputTokens = Math.max(
|
|
58048
|
+
0,
|
|
58049
|
+
total - (prepared.session.stats.compressCreditTokens ?? 0)
|
|
58050
|
+
);
|
|
58051
|
+
if (typeof cached === "number") {
|
|
58052
|
+
prepared.session.stats.cachedTokens += cached;
|
|
58053
|
+
prepared.session.stats.cacheSamples += 1;
|
|
58054
|
+
}
|
|
58055
|
+
const out = u2.completion_tokens ?? u2.output_tokens;
|
|
58056
|
+
if (typeof out === "number") prepared.session.stats.outputTokens += out;
|
|
58057
|
+
}
|
|
58058
|
+
if (prepared.protocol === "openai") {
|
|
58059
|
+
rewriteOpenaiJsonResponse(json, ctx);
|
|
58060
|
+
} else if (prepared.protocol === "responses") {
|
|
58061
|
+
rewriteResponsesJsonResponse(json, ctx);
|
|
58062
|
+
} else {
|
|
58063
|
+
rewriteJsonResponse(json, ctx);
|
|
58064
|
+
}
|
|
58065
|
+
res.end(JSON.stringify(json));
|
|
58066
|
+
} catch {
|
|
58067
|
+
res.end(text);
|
|
57883
58068
|
}
|
|
57884
|
-
|
|
57885
|
-
|
|
57886
|
-
|
|
58069
|
+
} finally {
|
|
58070
|
+
clearUpstreamTimer();
|
|
58071
|
+
markDirty(prepared.session);
|
|
57887
58072
|
}
|
|
57888
|
-
} finally {
|
|
57889
|
-
clearUpstreamTimer();
|
|
57890
58073
|
}
|
|
58074
|
+
} finally {
|
|
58075
|
+
clearUpstreamTimer();
|
|
57891
58076
|
}
|
|
57892
|
-
markDirty(prepared.session);
|
|
57893
58077
|
}
|
|
57894
58078
|
async function readStreamToBuffer(stream2, maxBytes = 1 << 20) {
|
|
57895
58079
|
const reader = stream2.getReader();
|
|
@@ -62333,19 +62517,20 @@ function livePidHoldsOverlay(overlay) {
|
|
|
62333
62517
|
function linkOverlayEntry(realHome, overlay, entry) {
|
|
62334
62518
|
const target = path14.join(realHome, entry);
|
|
62335
62519
|
const link = path14.join(overlay, entry);
|
|
62336
|
-
try {
|
|
62337
|
-
fs11.symlinkSync(target, link);
|
|
62338
|
-
return true;
|
|
62339
|
-
} catch (err2) {
|
|
62340
|
-
const code = err2.code;
|
|
62341
|
-
if (code !== "EPERM" && code !== "EACCES" && code !== "EINVAL") return false;
|
|
62342
|
-
}
|
|
62343
62520
|
let st2;
|
|
62344
62521
|
try {
|
|
62345
62522
|
st2 = fs11.lstatSync(target);
|
|
62346
62523
|
} catch {
|
|
62347
62524
|
return false;
|
|
62348
62525
|
}
|
|
62526
|
+
const kind = st2.isDirectory() ? process.platform === "win32" ? "junction" : "dir" : "file";
|
|
62527
|
+
try {
|
|
62528
|
+
fs11.symlinkSync(target, link, kind);
|
|
62529
|
+
return true;
|
|
62530
|
+
} catch (err2) {
|
|
62531
|
+
const code = err2.code;
|
|
62532
|
+
if (code !== "EPERM" && code !== "EACCES" && code !== "EINVAL") return false;
|
|
62533
|
+
}
|
|
62349
62534
|
if (st2.isDirectory()) {
|
|
62350
62535
|
try {
|
|
62351
62536
|
fs11.symlinkSync(target, link, "junction");
|
|
@@ -62376,17 +62561,39 @@ function isWriteThroughHardlink(overlayPath, realPath, st2) {
|
|
|
62376
62561
|
}
|
|
62377
62562
|
}
|
|
62378
62563
|
function sqliteSetMembers(base) {
|
|
62379
|
-
return [base, `${base}-wal`, `${base}-shm`];
|
|
62564
|
+
return [base, `${base}-wal`, `${base}-shm`, `${base}-journal`];
|
|
62565
|
+
}
|
|
62566
|
+
function freeConflictName(dst) {
|
|
62567
|
+
let candidate = `${dst}.bili-conflict`;
|
|
62568
|
+
let n = 1;
|
|
62569
|
+
while (n < 1e5) {
|
|
62570
|
+
try {
|
|
62571
|
+
fs11.lstatSync(candidate);
|
|
62572
|
+
candidate = `${dst}.bili-conflict.${n}`;
|
|
62573
|
+
n += 1;
|
|
62574
|
+
} catch {
|
|
62575
|
+
return candidate;
|
|
62576
|
+
}
|
|
62577
|
+
}
|
|
62578
|
+
return candidate;
|
|
62380
62579
|
}
|
|
62381
62580
|
function mergeSqliteSet(overlay, realHome, base) {
|
|
62382
|
-
const members = sqliteSetMembers(base)
|
|
62581
|
+
const members = sqliteSetMembers(base);
|
|
62582
|
+
const statFile = (dir, m2) => {
|
|
62383
62583
|
try {
|
|
62384
|
-
|
|
62584
|
+
const st2 = fs11.lstatSync(path14.join(dir, m2));
|
|
62585
|
+
return st2.isFile() ? st2 : void 0;
|
|
62385
62586
|
} catch {
|
|
62386
|
-
return
|
|
62587
|
+
return void 0;
|
|
62387
62588
|
}
|
|
62388
|
-
}
|
|
62389
|
-
|
|
62589
|
+
};
|
|
62590
|
+
const oMain = statFile(overlay, base);
|
|
62591
|
+
const rMain = statFile(realHome, base);
|
|
62592
|
+
let winner;
|
|
62593
|
+
if (oMain && rMain) winner = rMain.mtimeMs >= oMain.mtimeMs ? "real" : "overlay";
|
|
62594
|
+
else if (oMain) winner = "overlay";
|
|
62595
|
+
else if (rMain) winner = "real";
|
|
62596
|
+
else winner = "orphan";
|
|
62390
62597
|
const undo = [];
|
|
62391
62598
|
const rollback = () => {
|
|
62392
62599
|
for (const step of undo.reverse()) {
|
|
@@ -62397,46 +62604,39 @@ function mergeSqliteSet(overlay, realHome, base) {
|
|
|
62397
62604
|
}
|
|
62398
62605
|
undo.length = 0;
|
|
62399
62606
|
};
|
|
62607
|
+
const movePreserving = (src, dst) => {
|
|
62608
|
+
let dstStat;
|
|
62609
|
+
try {
|
|
62610
|
+
dstStat = fs11.lstatSync(dst);
|
|
62611
|
+
} catch {
|
|
62612
|
+
}
|
|
62613
|
+
if (dstStat) {
|
|
62614
|
+
if (dstStat.isDirectory()) throw new Error("target is a directory");
|
|
62615
|
+
const conflict = freeConflictName(dst);
|
|
62616
|
+
fs11.renameSync(dst, conflict);
|
|
62617
|
+
undo.push(() => fs11.renameSync(conflict, dst));
|
|
62618
|
+
}
|
|
62619
|
+
fs11.renameSync(src, dst);
|
|
62620
|
+
undo.push(() => fs11.renameSync(dst, src));
|
|
62621
|
+
};
|
|
62622
|
+
const preserveAsConflict = (src, name) => {
|
|
62623
|
+
const conflict = freeConflictName(path14.join(realHome, name));
|
|
62624
|
+
fs11.renameSync(src, conflict);
|
|
62625
|
+
undo.push(() => fs11.renameSync(conflict, src));
|
|
62626
|
+
};
|
|
62400
62627
|
try {
|
|
62401
62628
|
for (const m2 of members) {
|
|
62402
|
-
const
|
|
62403
|
-
const
|
|
62404
|
-
|
|
62405
|
-
|
|
62406
|
-
|
|
62407
|
-
}
|
|
62408
|
-
|
|
62409
|
-
|
|
62410
|
-
|
|
62411
|
-
|
|
62412
|
-
}
|
|
62413
|
-
const srcStat = fs11.lstatSync(src);
|
|
62414
|
-
if (dstStat && dstStat.mtimeMs >= srcStat.mtimeMs) {
|
|
62415
|
-
try {
|
|
62416
|
-
fs11.renameSync(src, `${dst}.bili-conflict`);
|
|
62417
|
-
} catch {
|
|
62418
|
-
rollback();
|
|
62419
|
-
return false;
|
|
62420
|
-
}
|
|
62421
|
-
undo.push(() => fs11.renameSync(`${dst}.bili-conflict`, src));
|
|
62422
|
-
continue;
|
|
62423
|
-
}
|
|
62424
|
-
if (dstStat) {
|
|
62425
|
-
try {
|
|
62426
|
-
fs11.renameSync(dst, `${dst}.bili-conflict`);
|
|
62427
|
-
} catch {
|
|
62428
|
-
rollback();
|
|
62429
|
-
return false;
|
|
62430
|
-
}
|
|
62431
|
-
undo.push(() => fs11.renameSync(`${dst}.bili-conflict`, dst));
|
|
62432
|
-
}
|
|
62433
|
-
try {
|
|
62434
|
-
fs11.renameSync(src, dst);
|
|
62435
|
-
} catch {
|
|
62436
|
-
rollback();
|
|
62437
|
-
return false;
|
|
62629
|
+
const o = statFile(overlay, m2);
|
|
62630
|
+
const r = statFile(realHome, m2);
|
|
62631
|
+
if (winner === "overlay") {
|
|
62632
|
+
if (o) movePreserving(path14.join(overlay, m2), path14.join(realHome, m2));
|
|
62633
|
+
else if (r) preserveAsConflict(path14.join(realHome, m2), m2);
|
|
62634
|
+
} else if (winner === "real") {
|
|
62635
|
+
if (o) preserveAsConflict(path14.join(overlay, m2), m2);
|
|
62636
|
+
} else {
|
|
62637
|
+
if (o) preserveAsConflict(path14.join(overlay, m2), m2);
|
|
62638
|
+
else if (r) preserveAsConflict(path14.join(realHome, m2), m2);
|
|
62438
62639
|
}
|
|
62439
|
-
undo.push(() => fs11.renameSync(dst, src));
|
|
62440
62640
|
}
|
|
62441
62641
|
return true;
|
|
62442
62642
|
} catch {
|
|
@@ -62445,6 +62645,8 @@ function mergeSqliteSet(overlay, realHome, base) {
|
|
|
62445
62645
|
}
|
|
62446
62646
|
}
|
|
62447
62647
|
function refreshOverlayHome(realHome, overlay, generatedFile) {
|
|
62648
|
+
const generatedFiles = new Set(Array.isArray(generatedFile) ? generatedFile : [generatedFile]);
|
|
62649
|
+
const isGeneratedDraft = (name) => [...generatedFiles].some((g2) => name.startsWith(`.${g2}.`) && name.endsWith(".tmp"));
|
|
62448
62650
|
try {
|
|
62449
62651
|
fs11.mkdirSync(overlay, { recursive: true });
|
|
62450
62652
|
} catch {
|
|
@@ -62475,7 +62677,7 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
|
|
|
62475
62677
|
}
|
|
62476
62678
|
const dbSets = [];
|
|
62477
62679
|
for (const entry of overlayEntries) {
|
|
62478
|
-
if (!entry.endsWith(".db") || entry
|
|
62680
|
+
if (!entry.endsWith(".db") || generatedFiles.has(entry)) continue;
|
|
62479
62681
|
const members = sqliteSetMembers(entry);
|
|
62480
62682
|
if (!members.some((m2) => m2 !== entry && overlayEntries.includes(m2))) continue;
|
|
62481
62683
|
let mainSt;
|
|
@@ -62493,9 +62695,9 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
|
|
|
62493
62695
|
}
|
|
62494
62696
|
}
|
|
62495
62697
|
for (const entry of overlayEntries) {
|
|
62496
|
-
if (entry
|
|
62698
|
+
if (generatedFiles.has(entry)) continue;
|
|
62497
62699
|
const overlayPath = path14.join(overlay, entry);
|
|
62498
|
-
if (
|
|
62700
|
+
if (isGeneratedDraft(entry)) {
|
|
62499
62701
|
try {
|
|
62500
62702
|
fs11.unlinkSync(overlayPath);
|
|
62501
62703
|
} catch {
|
|
@@ -62529,7 +62731,7 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
|
|
|
62529
62731
|
fs11.unlinkSync(overlayPath);
|
|
62530
62732
|
} catch {
|
|
62531
62733
|
}
|
|
62532
|
-
} else if (mergeOverlayEntry(overlayPath, realPath,
|
|
62734
|
+
} else if (mergeOverlayEntry(overlayPath, realPath, generatedFiles)) {
|
|
62533
62735
|
try {
|
|
62534
62736
|
fs11.rmSync(overlayPath, { recursive: true, force: true });
|
|
62535
62737
|
} catch {
|
|
@@ -62551,7 +62753,7 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
|
|
|
62551
62753
|
let total = 0;
|
|
62552
62754
|
const linkFailures = [];
|
|
62553
62755
|
for (const entry of realEntries) {
|
|
62554
|
-
if (entry
|
|
62756
|
+
if (generatedFiles.has(entry)) continue;
|
|
62555
62757
|
total += 1;
|
|
62556
62758
|
const overlayPath = path14.join(overlay, entry);
|
|
62557
62759
|
let present = false;
|
|
@@ -62585,7 +62787,7 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
|
|
|
62585
62787
|
}
|
|
62586
62788
|
return true;
|
|
62587
62789
|
}
|
|
62588
|
-
function mergeOverlayEntry(src, dst,
|
|
62790
|
+
function mergeOverlayEntry(src, dst, excludedNames) {
|
|
62589
62791
|
let st2;
|
|
62590
62792
|
try {
|
|
62591
62793
|
st2 = fs11.lstatSync(src);
|
|
@@ -62600,7 +62802,7 @@ function mergeOverlayEntry(src, dst, excludedName) {
|
|
|
62600
62802
|
if (st2.isDirectory()) {
|
|
62601
62803
|
if (dstStat && !dstStat.isDirectory()) {
|
|
62602
62804
|
try {
|
|
62603
|
-
fs11.renameSync(dst,
|
|
62805
|
+
fs11.renameSync(dst, freeConflictName(dst));
|
|
62604
62806
|
dstStat = void 0;
|
|
62605
62807
|
} catch {
|
|
62606
62808
|
return false;
|
|
@@ -62619,14 +62821,14 @@ function mergeOverlayEntry(src, dst, excludedName) {
|
|
|
62619
62821
|
}
|
|
62620
62822
|
let ok = true;
|
|
62621
62823
|
for (const entry of entries) {
|
|
62622
|
-
if (
|
|
62623
|
-
if (!mergeOverlayEntry(path14.join(src, entry), path14.join(dst, entry),
|
|
62824
|
+
if (excludedNames?.has(entry)) continue;
|
|
62825
|
+
if (!mergeOverlayEntry(path14.join(src, entry), path14.join(dst, entry), excludedNames)) ok = false;
|
|
62624
62826
|
}
|
|
62625
62827
|
return ok;
|
|
62626
62828
|
}
|
|
62627
62829
|
if (dstStat && dstStat.isDirectory()) {
|
|
62628
62830
|
try {
|
|
62629
|
-
fs11.renameSync(src,
|
|
62831
|
+
fs11.renameSync(src, freeConflictName(dst));
|
|
62630
62832
|
return true;
|
|
62631
62833
|
} catch {
|
|
62632
62834
|
return false;
|
|
@@ -62649,7 +62851,7 @@ function mergeOverlayEntry(src, dst, excludedName) {
|
|
|
62649
62851
|
}
|
|
62650
62852
|
if (dstStat && dstStat.mtimeMs >= st2.mtimeMs) {
|
|
62651
62853
|
try {
|
|
62652
|
-
fs11.renameSync(src,
|
|
62854
|
+
fs11.renameSync(src, freeConflictName(dst));
|
|
62653
62855
|
return true;
|
|
62654
62856
|
} catch {
|
|
62655
62857
|
return false;
|
|
@@ -62657,7 +62859,7 @@ function mergeOverlayEntry(src, dst, excludedName) {
|
|
|
62657
62859
|
}
|
|
62658
62860
|
if (dstStat) {
|
|
62659
62861
|
try {
|
|
62660
|
-
fs11.renameSync(dst,
|
|
62862
|
+
fs11.renameSync(dst, freeConflictName(dst));
|
|
62661
62863
|
} catch {
|
|
62662
62864
|
return false;
|
|
62663
62865
|
}
|
|
@@ -62692,45 +62894,58 @@ function writeOverlayFileAtomic(overlay, fileName, contents) {
|
|
|
62692
62894
|
}
|
|
62693
62895
|
}
|
|
62694
62896
|
}
|
|
62695
|
-
function
|
|
62696
|
-
|
|
62697
|
-
const modelsPath = path14.join(piHome, "models.json");
|
|
62698
|
-
let txt;
|
|
62897
|
+
function writePiCompactionDisabledSettings(piHome, overlay) {
|
|
62898
|
+
let settings = {};
|
|
62699
62899
|
try {
|
|
62700
|
-
|
|
62900
|
+
const parsed = JSON.parse(fs11.readFileSync(path14.join(piHome, "settings.json"), "utf8"));
|
|
62901
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
62902
|
+
settings = parsed;
|
|
62903
|
+
}
|
|
62701
62904
|
} catch {
|
|
62702
|
-
return void 0;
|
|
62703
62905
|
}
|
|
62704
|
-
|
|
62906
|
+
const compactionRaw = settings.compaction;
|
|
62907
|
+
const compaction = compactionRaw && typeof compactionRaw === "object" && !Array.isArray(compactionRaw) ? { ...compactionRaw } : {};
|
|
62908
|
+
compaction.enabled = false;
|
|
62909
|
+
settings.compaction = compaction;
|
|
62910
|
+
writeOverlayFileAtomic(overlay, "settings.json", JSON.stringify(settings, null, 2));
|
|
62911
|
+
}
|
|
62912
|
+
function preparePiHttpRewrite(piHome, origin, httpRewrites, httpsRewrites) {
|
|
62913
|
+
if (!fs11.existsSync(piHome)) return void 0;
|
|
62914
|
+
const overlay = `${piHome}-bili`;
|
|
62915
|
+
const generated = ["settings.json"];
|
|
62916
|
+
let modelsRoot;
|
|
62705
62917
|
try {
|
|
62706
|
-
parsed = JSON.parse(
|
|
62918
|
+
const parsed = JSON.parse(fs11.readFileSync(path14.join(piHome, "models.json"), "utf8"));
|
|
62919
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
62920
|
+
modelsRoot = parsed;
|
|
62921
|
+
generated.push("models.json");
|
|
62922
|
+
}
|
|
62707
62923
|
} catch {
|
|
62708
|
-
return void 0;
|
|
62709
62924
|
}
|
|
62710
|
-
if (!
|
|
62711
|
-
|
|
62712
|
-
|
|
62713
|
-
|
|
62714
|
-
|
|
62715
|
-
|
|
62716
|
-
|
|
62717
|
-
|
|
62718
|
-
|
|
62719
|
-
|
|
62720
|
-
|
|
62925
|
+
if (!refreshOverlayHome(piHome, overlay, generated)) return void 0;
|
|
62926
|
+
if (modelsRoot) {
|
|
62927
|
+
const providersVal = modelsRoot.providers;
|
|
62928
|
+
if (providersVal && typeof providersVal === "object" && !Array.isArray(providersVal)) {
|
|
62929
|
+
const providers = providersVal;
|
|
62930
|
+
for (const r of httpRewrites) {
|
|
62931
|
+
const prov = providers[r.key];
|
|
62932
|
+
if (prov && typeof prov === "object" && !Array.isArray(prov)) {
|
|
62933
|
+
const p2 = prov;
|
|
62934
|
+
const existing = typeof p2.baseUrl === "string" ? p2.baseUrl : r.realUpstream;
|
|
62935
|
+
p2.baseUrl = wrapUpstream(origin, unwrapUpstream2(existing));
|
|
62936
|
+
}
|
|
62721
62937
|
}
|
|
62722
|
-
|
|
62723
|
-
|
|
62724
|
-
|
|
62725
|
-
|
|
62726
|
-
|
|
62727
|
-
|
|
62938
|
+
for (const r of httpsRewrites) {
|
|
62939
|
+
const prov = providers[r.key];
|
|
62940
|
+
if (prov && typeof prov === "object" && !Array.isArray(prov)) {
|
|
62941
|
+
const p2 = prov;
|
|
62942
|
+
p2.baseUrl = r.realUpstream;
|
|
62943
|
+
}
|
|
62728
62944
|
}
|
|
62729
62945
|
}
|
|
62946
|
+
writeOverlayFileAtomic(overlay, "models.json", JSON.stringify(modelsRoot));
|
|
62730
62947
|
}
|
|
62731
|
-
|
|
62732
|
-
if (!refreshOverlayHome(piHome, overlay, "models.json")) return void 0;
|
|
62733
|
-
writeOverlayFileAtomic(overlay, "models.json", JSON.stringify(root));
|
|
62948
|
+
writePiCompactionDisabledSettings(piHome, overlay);
|
|
62734
62949
|
return overlay;
|
|
62735
62950
|
}
|
|
62736
62951
|
function atomicWriteTextFile(filePath, contents) {
|
|
@@ -62781,55 +62996,145 @@ function unpackDeadProxyUrlsInFile(filePath, livePorts) {
|
|
|
62781
62996
|
}
|
|
62782
62997
|
return changed;
|
|
62783
62998
|
}
|
|
62999
|
+
function mergeOmpCompactionDisabledYaml(text) {
|
|
63000
|
+
const lines = text.split(/\r?\n/);
|
|
63001
|
+
let compactionLine = -1;
|
|
63002
|
+
for (let i = 0; i < lines.length; i++) {
|
|
63003
|
+
const rawLine = lines[i];
|
|
63004
|
+
const trimmed = rawLine.trim();
|
|
63005
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
63006
|
+
const indent = rawLine.length - rawLine.trimStart().length;
|
|
63007
|
+
if (indent === 0 && /^compaction:\s*(#.*)?$/.test(trimmed)) {
|
|
63008
|
+
compactionLine = i;
|
|
63009
|
+
break;
|
|
63010
|
+
}
|
|
63011
|
+
}
|
|
63012
|
+
if (compactionLine === -1) {
|
|
63013
|
+
const base = text === "" || text.endsWith("\n") ? text : `${text}
|
|
63014
|
+
`;
|
|
63015
|
+
return `${base}compaction:
|
|
63016
|
+
enabled: false
|
|
63017
|
+
`;
|
|
63018
|
+
}
|
|
63019
|
+
for (let i = compactionLine + 1; i < lines.length; i++) {
|
|
63020
|
+
const rawLine = lines[i];
|
|
63021
|
+
const trimmed = rawLine.trim();
|
|
63022
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
63023
|
+
const indent = rawLine.length - rawLine.trimStart().length;
|
|
63024
|
+
if (indent === 0) break;
|
|
63025
|
+
if (/^enabled:/.test(trimmed)) {
|
|
63026
|
+
const leading = rawLine.slice(0, rawLine.length - rawLine.trimStart().length);
|
|
63027
|
+
const commentMatch = /\s+#.*$/.exec(rawLine);
|
|
63028
|
+
const comment = commentMatch ? commentMatch[0] : "";
|
|
63029
|
+
lines[i] = `${leading}enabled: false${comment}`;
|
|
63030
|
+
return lines.join("\n");
|
|
63031
|
+
}
|
|
63032
|
+
}
|
|
63033
|
+
let childIndent = 2;
|
|
63034
|
+
for (let i = compactionLine + 1; i < lines.length; i++) {
|
|
63035
|
+
const rawLine = lines[i];
|
|
63036
|
+
const trimmed = rawLine.trim();
|
|
63037
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
63038
|
+
const indent = rawLine.length - rawLine.trimStart().length;
|
|
63039
|
+
if (indent === 0) break;
|
|
63040
|
+
childIndent = indent;
|
|
63041
|
+
break;
|
|
63042
|
+
}
|
|
63043
|
+
lines.splice(compactionLine + 1, 0, `${" ".repeat(childIndent)}enabled: false`);
|
|
63044
|
+
return lines.join("\n");
|
|
63045
|
+
}
|
|
63046
|
+
function writeOmpCompactionDisabledConfig(ompHome, overlay) {
|
|
63047
|
+
let base;
|
|
63048
|
+
let baseIsJson = false;
|
|
63049
|
+
for (const name of ["config.yml", "config.yaml"]) {
|
|
63050
|
+
try {
|
|
63051
|
+
base = fs11.readFileSync(path14.join(ompHome, name), "utf8");
|
|
63052
|
+
break;
|
|
63053
|
+
} catch {
|
|
63054
|
+
}
|
|
63055
|
+
}
|
|
63056
|
+
if (base === void 0) {
|
|
63057
|
+
try {
|
|
63058
|
+
base = fs11.readFileSync(path14.join(ompHome, "settings.json"), "utf8");
|
|
63059
|
+
baseIsJson = true;
|
|
63060
|
+
} catch {
|
|
63061
|
+
}
|
|
63062
|
+
}
|
|
63063
|
+
let merged;
|
|
63064
|
+
if (base === void 0) {
|
|
63065
|
+
merged = "compaction:\n enabled: false\n";
|
|
63066
|
+
} else if (baseIsJson) {
|
|
63067
|
+
let settings = {};
|
|
63068
|
+
try {
|
|
63069
|
+
const parsed = JSON.parse(base);
|
|
63070
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
63071
|
+
settings = parsed;
|
|
63072
|
+
}
|
|
63073
|
+
} catch {
|
|
63074
|
+
}
|
|
63075
|
+
const compactionRaw = settings.compaction;
|
|
63076
|
+
const compaction = compactionRaw && typeof compactionRaw === "object" && !Array.isArray(compactionRaw) ? { ...compactionRaw } : {};
|
|
63077
|
+
compaction.enabled = false;
|
|
63078
|
+
settings.compaction = compaction;
|
|
63079
|
+
merged = JSON.stringify(settings, null, 2);
|
|
63080
|
+
} else {
|
|
63081
|
+
merged = mergeOmpCompactionDisabledYaml(base);
|
|
63082
|
+
}
|
|
63083
|
+
writeOverlayFileAtomic(overlay, "config.yml", merged);
|
|
63084
|
+
}
|
|
62784
63085
|
function prepareOmpHttpRewrite(ompHome, origin, httpRewrites, httpsRewrites) {
|
|
63086
|
+
if (!fs11.existsSync(ompHome)) return void 0;
|
|
63087
|
+
const overlay = `${ompHome}-bili`;
|
|
63088
|
+
const generated = ["config.yml"];
|
|
62785
63089
|
const modelsPath = path14.join(ompHome, "models.yml");
|
|
62786
63090
|
const unpacked = unpackDeadProxyUrlsInFile(modelsPath, liveProxyPorts());
|
|
62787
63091
|
if (unpacked > 0) {
|
|
62788
63092
|
console.error(`bili: unpacked ${unpacked} dead proxy URL(s) from the real ${modelsPath}`);
|
|
62789
63093
|
}
|
|
62790
|
-
|
|
62791
|
-
let txt;
|
|
63094
|
+
let modelsText;
|
|
62792
63095
|
try {
|
|
62793
|
-
|
|
63096
|
+
modelsText = fs11.readFileSync(modelsPath, "utf8");
|
|
63097
|
+
generated.push("models.yml");
|
|
62794
63098
|
} catch {
|
|
62795
|
-
return void 0;
|
|
62796
63099
|
}
|
|
62797
|
-
|
|
62798
|
-
|
|
62799
|
-
|
|
62800
|
-
|
|
62801
|
-
|
|
62802
|
-
|
|
62803
|
-
|
|
62804
|
-
|
|
62805
|
-
|
|
62806
|
-
|
|
62807
|
-
|
|
62808
|
-
|
|
62809
|
-
|
|
62810
|
-
|
|
62811
|
-
|
|
62812
|
-
|
|
62813
|
-
|
|
62814
|
-
|
|
62815
|
-
|
|
62816
|
-
|
|
62817
|
-
|
|
62818
|
-
|
|
62819
|
-
if (
|
|
62820
|
-
const
|
|
62821
|
-
if (
|
|
62822
|
-
const
|
|
62823
|
-
|
|
62824
|
-
|
|
62825
|
-
|
|
63100
|
+
if (!refreshOverlayHome(ompHome, overlay, generated)) return void 0;
|
|
63101
|
+
if (modelsText !== void 0) {
|
|
63102
|
+
const httpMap = new Map(httpRewrites.map((r) => [r.key, wrapUpstream(origin, r.realUpstream)]));
|
|
63103
|
+
const httpsMap = new Map(httpsRewrites.map((r) => [r.key, r.realUpstream]));
|
|
63104
|
+
const lines = modelsText.split(/\r?\n/);
|
|
63105
|
+
let providersIndent = -1;
|
|
63106
|
+
let providerIndent = -1;
|
|
63107
|
+
let currentProvider = null;
|
|
63108
|
+
for (let i = 0; i < lines.length; i++) {
|
|
63109
|
+
const rawLine = lines[i];
|
|
63110
|
+
const trimmed = rawLine.trim();
|
|
63111
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
63112
|
+
const indent = rawLine.length - rawLine.trimStart().length;
|
|
63113
|
+
if (providersIndent === -1) {
|
|
63114
|
+
if (/^providers:\s*(#.*)?$/.test(trimmed)) providersIndent = indent;
|
|
63115
|
+
continue;
|
|
63116
|
+
}
|
|
63117
|
+
if (indent <= providersIndent) break;
|
|
63118
|
+
if (providerIndent === -1) providerIndent = indent;
|
|
63119
|
+
if (indent === providerIndent) {
|
|
63120
|
+
const m2 = /^([A-Za-z0-9_.-]+):/.exec(trimmed);
|
|
63121
|
+
currentProvider = m2 ? m2[1] : null;
|
|
63122
|
+
} else if (indent > providerIndent && currentProvider) {
|
|
63123
|
+
const baseMatch = /^(baseUrl:\s*)(\S+)/.exec(trimmed);
|
|
63124
|
+
if (baseMatch) {
|
|
63125
|
+
const target = httpMap.get(currentProvider) ?? httpsMap.get(currentProvider);
|
|
63126
|
+
if (target) {
|
|
63127
|
+
const leading = rawLine.slice(0, rawLine.length - rawLine.trimStart().length);
|
|
63128
|
+
const commentMatch = /\s+#.*$/.exec(rawLine);
|
|
63129
|
+
const comment = commentMatch ? commentMatch[0] : "";
|
|
63130
|
+
lines[i] = `${leading}baseUrl: ${target}${comment}`;
|
|
63131
|
+
}
|
|
62826
63132
|
}
|
|
62827
63133
|
}
|
|
62828
63134
|
}
|
|
63135
|
+
writeOverlayFileAtomic(overlay, "models.yml", lines.join("\n"));
|
|
62829
63136
|
}
|
|
62830
|
-
|
|
62831
|
-
if (!refreshOverlayHome(ompHome, overlay, "models.yml")) return void 0;
|
|
62832
|
-
writeOverlayFileAtomic(overlay, "models.yml", lines.join("\n"));
|
|
63137
|
+
writeOmpCompactionDisabledConfig(ompHome, overlay);
|
|
62833
63138
|
return overlay;
|
|
62834
63139
|
}
|
|
62835
63140
|
function prepareHermesHome(hermesHome, origin, rewrites) {
|