billion-context 0.1.110 → 0.1.111-pr.748.622
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +351 -152
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -49414,7 +49414,7 @@ function rejectLegacyRoute(key, value) {
|
|
|
49414
49414
|
|
|
49415
49415
|
// src/server.ts
|
|
49416
49416
|
import http from "http";
|
|
49417
|
-
import
|
|
49417
|
+
import fs9 from "fs";
|
|
49418
49418
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
49419
49419
|
|
|
49420
49420
|
// src/compress-settings.ts
|
|
@@ -54348,6 +54348,66 @@ ${icon} [ACP] ${inner}
|
|
|
54348
54348
|
`;
|
|
54349
54349
|
}
|
|
54350
54350
|
|
|
54351
|
+
// src/tool-pair-order.ts
|
|
54352
|
+
var CALL_TYPES = /* @__PURE__ */ new Set(["function_call", "custom_tool_call"]);
|
|
54353
|
+
var OUTPUT_TYPES = /* @__PURE__ */ new Set(["function_call_output", "custom_tool_call_output"]);
|
|
54354
|
+
function isCall(type) {
|
|
54355
|
+
return type !== void 0 && CALL_TYPES.has(type);
|
|
54356
|
+
}
|
|
54357
|
+
function isOutput(type) {
|
|
54358
|
+
return type !== void 0 && OUTPUT_TYPES.has(type);
|
|
54359
|
+
}
|
|
54360
|
+
function idOf(item) {
|
|
54361
|
+
return typeof item.call_id === "string" ? item.call_id : "";
|
|
54362
|
+
}
|
|
54363
|
+
function hoistTrappedToolItems(items) {
|
|
54364
|
+
const n = items.length;
|
|
54365
|
+
if (n < 3) return items;
|
|
54366
|
+
const callPos = /* @__PURE__ */ new Map();
|
|
54367
|
+
const outPos = /* @__PURE__ */ new Map();
|
|
54368
|
+
for (let i = 0; i < n; i++) {
|
|
54369
|
+
const id = idOf(items[i]);
|
|
54370
|
+
if (!id) continue;
|
|
54371
|
+
const t = items[i].type;
|
|
54372
|
+
if (isCall(t) && !callPos.has(id)) callPos.set(id, i);
|
|
54373
|
+
else if (isOutput(t) && !outPos.has(id)) outPos.set(id, i);
|
|
54374
|
+
}
|
|
54375
|
+
if (callPos.size === 0) return items;
|
|
54376
|
+
const hoistBefore = new Array(n).fill(null);
|
|
54377
|
+
let anyTrapped = false;
|
|
54378
|
+
for (let p2 = 0; p2 < n; p2++) {
|
|
54379
|
+
const t = items[p2].type;
|
|
54380
|
+
if (isCall(t) || isOutput(t)) continue;
|
|
54381
|
+
let target = -1;
|
|
54382
|
+
for (const [id, c] of callPos) {
|
|
54383
|
+
const o = outPos.get(id);
|
|
54384
|
+
if (o === void 0 || !(c < p2 && o > p2)) continue;
|
|
54385
|
+
if (target === -1 || c < target) target = c;
|
|
54386
|
+
}
|
|
54387
|
+
if (target >= 0) {
|
|
54388
|
+
hoistBefore[p2] = target;
|
|
54389
|
+
anyTrapped = true;
|
|
54390
|
+
}
|
|
54391
|
+
}
|
|
54392
|
+
if (!anyTrapped) return items;
|
|
54393
|
+
const pendingByTarget = /* @__PURE__ */ new Map();
|
|
54394
|
+
for (let p2 = 0; p2 < n; p2++) {
|
|
54395
|
+
const target = hoistBefore[p2];
|
|
54396
|
+
if (target === null) continue;
|
|
54397
|
+
const batch = pendingByTarget.get(target);
|
|
54398
|
+
if (batch) batch.push(items[p2]);
|
|
54399
|
+
else pendingByTarget.set(target, [items[p2]]);
|
|
54400
|
+
}
|
|
54401
|
+
const result = [];
|
|
54402
|
+
for (let p2 = 0; p2 < n; p2++) {
|
|
54403
|
+
if (hoistBefore[p2] !== null) continue;
|
|
54404
|
+
const batch = pendingByTarget.get(p2);
|
|
54405
|
+
if (batch) result.push(...batch);
|
|
54406
|
+
result.push(items[p2]);
|
|
54407
|
+
}
|
|
54408
|
+
return result;
|
|
54409
|
+
}
|
|
54410
|
+
|
|
54351
54411
|
// src/weak-overflow.ts
|
|
54352
54412
|
var MIN_USAGE = 0.9;
|
|
54353
54413
|
var WINDOW_MS = 15 * 60 * 1e3;
|
|
@@ -54489,6 +54549,79 @@ function warnCacheCollapse(session, input, cached) {
|
|
|
54489
54549
|
);
|
|
54490
54550
|
}
|
|
54491
54551
|
|
|
54552
|
+
// src/error-dump.ts
|
|
54553
|
+
import fs4 from "fs";
|
|
54554
|
+
var DEFAULT_MAX_BYTES = 2 * 1024 * 1024;
|
|
54555
|
+
var failCount = 0;
|
|
54556
|
+
var lastFailLog = 0;
|
|
54557
|
+
function warnDumpFailure(err2) {
|
|
54558
|
+
failCount++;
|
|
54559
|
+
const now = Date.now();
|
|
54560
|
+
if (failCount === 1 || now - lastFailLog >= 6e4) {
|
|
54561
|
+
lastFailLog = now;
|
|
54562
|
+
const msg = err2 instanceof Error ? err2.message : String(err2);
|
|
54563
|
+
log("warn", `[dump] rejected-body dump failed (total ${failCount}x): ${msg}`);
|
|
54564
|
+
}
|
|
54565
|
+
}
|
|
54566
|
+
function dumpRejectedBody(status, sessionId, body) {
|
|
54567
|
+
if (process.env.BILI_DUMP_4XX !== "1") return null;
|
|
54568
|
+
const raw = typeof body === "string" ? body : body.toString("utf8");
|
|
54569
|
+
if (!raw) return null;
|
|
54570
|
+
try {
|
|
54571
|
+
const cap = Math.max(1024, Number(process.env.BILI_DUMP_4XX_MAX_BYTES) || DEFAULT_MAX_BYTES);
|
|
54572
|
+
let text;
|
|
54573
|
+
let marker = "";
|
|
54574
|
+
if (raw.length > cap) {
|
|
54575
|
+
text = raw.slice(0, cap);
|
|
54576
|
+
marker = `
|
|
54577
|
+
[truncated: ${raw.length - cap} more character(s)]
|
|
54578
|
+
`;
|
|
54579
|
+
} else {
|
|
54580
|
+
try {
|
|
54581
|
+
text = JSON.stringify(JSON.parse(raw), null, 2);
|
|
54582
|
+
} catch {
|
|
54583
|
+
text = raw;
|
|
54584
|
+
}
|
|
54585
|
+
}
|
|
54586
|
+
const dir = process.env.ACP_DUMP_DIR || `${stateDir()}/dumps`;
|
|
54587
|
+
fs4.mkdirSync(dir, { recursive: true });
|
|
54588
|
+
const sid = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
54589
|
+
const out = `${dir}/err-${Date.now()}-${sid}-${status}.json`;
|
|
54590
|
+
fs4.writeFileSync(out, `${text}${marker}`);
|
|
54591
|
+
log("info", `[dump] upstream ${status} rejected body written to ${out}`);
|
|
54592
|
+
return out;
|
|
54593
|
+
} catch (err2) {
|
|
54594
|
+
warnDumpFailure(err2);
|
|
54595
|
+
return null;
|
|
54596
|
+
}
|
|
54597
|
+
}
|
|
54598
|
+
|
|
54599
|
+
// src/strict-echo.ts
|
|
54600
|
+
function isStrictReasoningEcho(session, upstreamOrigin) {
|
|
54601
|
+
if (session.metadata.strictReasoningEcho === true) return true;
|
|
54602
|
+
return upstreamOrigin !== void 0 && /deepseek/i.test(upstreamOrigin);
|
|
54603
|
+
}
|
|
54604
|
+
function normalizeStrictEchoReasoning(messages, enabled, log2, sessionId) {
|
|
54605
|
+
if (!enabled) return messages;
|
|
54606
|
+
let patched = 0;
|
|
54607
|
+
const out = messages.map((m2) => {
|
|
54608
|
+
if (m2.role !== "assistant") return m2;
|
|
54609
|
+
if (!Array.isArray(m2.tool_calls) || m2.tool_calls.length === 0) return m2;
|
|
54610
|
+
if (typeof m2.reasoning_content === "string") return m2;
|
|
54611
|
+
patched++;
|
|
54612
|
+
return { ...m2, reasoning_content: "" };
|
|
54613
|
+
});
|
|
54614
|
+
if (patched > 0) {
|
|
54615
|
+
log2("info", `[${sessionId}] strict-echo: injected blank reasoning_content on ${patched} assistant tool-call message(s) (#762)`);
|
|
54616
|
+
}
|
|
54617
|
+
return patched > 0 ? out : messages;
|
|
54618
|
+
}
|
|
54619
|
+
function normalizeStrictEchoBody(body, enabled, log2, sessionId) {
|
|
54620
|
+
if (!enabled || !Array.isArray(body.messages)) return body;
|
|
54621
|
+
const patched = normalizeStrictEchoReasoning(body.messages, true, log2, sessionId);
|
|
54622
|
+
return patched === body.messages ? body : { ...body, messages: patched };
|
|
54623
|
+
}
|
|
54624
|
+
|
|
54492
54625
|
// src/util.ts
|
|
54493
54626
|
import { createHash as createHash5 } from "crypto";
|
|
54494
54627
|
function hashId2(s3) {
|
|
@@ -54603,6 +54736,7 @@ function shouldReserveOutputHeadroom(protocol) {
|
|
|
54603
54736
|
|
|
54604
54737
|
// src/loop/core.ts
|
|
54605
54738
|
var MAX_LOOP_ROUNDS = 10;
|
|
54739
|
+
var DEGENERATE_RETRY_NUDGE = "[billion-context] Your previous response ended with no visible text and no tool call. Continue now: take your next concrete action.";
|
|
54606
54740
|
function isLoopThinking(m2) {
|
|
54607
54741
|
return m2.contentType === "reasoning" && typeof m2.id === "string" && m2.id.startsWith("acp_loop_");
|
|
54608
54742
|
}
|
|
@@ -54672,6 +54806,7 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
|
|
|
54672
54806
|
const coreMessages = [...ctx.messages];
|
|
54673
54807
|
let degradedRetried = false;
|
|
54674
54808
|
let truncationRetried = false;
|
|
54809
|
+
let degenerateRetried = false;
|
|
54675
54810
|
const fetchUpstream = (body) => fetchWithRetry(
|
|
54676
54811
|
requestOptions.url,
|
|
54677
54812
|
{
|
|
@@ -54689,6 +54824,12 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
|
|
|
54689
54824
|
}
|
|
54690
54825
|
);
|
|
54691
54826
|
const failedSignatures = /* @__PURE__ */ new Set();
|
|
54827
|
+
let strictEchoOrigin;
|
|
54828
|
+
try {
|
|
54829
|
+
strictEchoOrigin = new URL(requestOptions.url).origin;
|
|
54830
|
+
} catch {
|
|
54831
|
+
strictEchoOrigin = void 0;
|
|
54832
|
+
}
|
|
54692
54833
|
try {
|
|
54693
54834
|
for (let round = 1; round <= MAX_LOOP_ROUNDS; round++) {
|
|
54694
54835
|
if (signal?.aborted) break;
|
|
@@ -54702,6 +54843,7 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
|
|
|
54702
54843
|
let sawDone = false;
|
|
54703
54844
|
let suppressCompletion = false;
|
|
54704
54845
|
let truncatedDone = false;
|
|
54846
|
+
let sawThinking = false;
|
|
54705
54847
|
let forwardedAny = false;
|
|
54706
54848
|
const fwd = (chunk) => {
|
|
54707
54849
|
forwardedAny = true;
|
|
@@ -54718,6 +54860,7 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
|
|
|
54718
54860
|
sawDone = false;
|
|
54719
54861
|
suppressCompletion = false;
|
|
54720
54862
|
truncatedDone = false;
|
|
54863
|
+
sawThinking = false;
|
|
54721
54864
|
forwardedAny = false;
|
|
54722
54865
|
for await (const ev of adapter.parseStream(currentUpstream, round)) {
|
|
54723
54866
|
if (signal?.aborted) break;
|
|
@@ -54759,6 +54902,7 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
|
|
|
54759
54902
|
finishReason = ev.finishReason;
|
|
54760
54903
|
suppressCompletion = ev.suppressCompletion === true;
|
|
54761
54904
|
truncatedDone = ev.truncated === true;
|
|
54905
|
+
sawThinking = ev.thinking === true;
|
|
54762
54906
|
} else if (ev.kind === "meta") {
|
|
54763
54907
|
if (round === 1 || !ev.firstRoundOnly) {
|
|
54764
54908
|
yield fwd(ev.chunk);
|
|
@@ -54787,6 +54931,37 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
|
|
|
54787
54931
|
}
|
|
54788
54932
|
}
|
|
54789
54933
|
}
|
|
54934
|
+
if (!degenerateRetried && sawDone && sawThinking && !truncatedDone && !suppressCompletion && typeof finishReason === "string" && finishReason !== "failed" && finishReason !== "incomplete" && finishReason !== "error" && assistantText.length === 0 && calls.length === 0 && !forwardedAny && !signal?.aborted) {
|
|
54935
|
+
degenerateRetried = true;
|
|
54936
|
+
ctx.log(`[acp-loop] round ${round}: degenerate terminal turn (completed, zero text/tool calls) invisible to client; retrying once with continuation nudge (#732)`);
|
|
54937
|
+
log("warn", `[acp-loop] degenerate-turn auto-retry round ${round} (session ${ctx.session.id})`);
|
|
54938
|
+
const nudge = {
|
|
54939
|
+
id: `acp_degenerate_retry_r${round}`,
|
|
54940
|
+
role: "user",
|
|
54941
|
+
contentType: "text",
|
|
54942
|
+
text: DEGENERATE_RETRY_NUDGE
|
|
54943
|
+
};
|
|
54944
|
+
try {
|
|
54945
|
+
const retryBody = adapter.buildRequest([...coreMessages, nudge], systemPrompt, requestBody);
|
|
54946
|
+
const respResult2 = await fetchUpstream(retryBody);
|
|
54947
|
+
if (!respResult2.response.body) {
|
|
54948
|
+
respResult2.clearTimer();
|
|
54949
|
+
throw new UpstreamHttpError(respResult2.response.status, "(empty response body)", 1);
|
|
54950
|
+
}
|
|
54951
|
+
currentUpstream = respResult2.response.body;
|
|
54952
|
+
roundBody = retryBody;
|
|
54953
|
+
if (activeClearTimer) activeClearTimer();
|
|
54954
|
+
activeClearTimer = respResult2.clearTimer;
|
|
54955
|
+
continue;
|
|
54956
|
+
} catch (e) {
|
|
54957
|
+
if (e instanceof UpstreamHttpError) {
|
|
54958
|
+
ctx.log(`[acp-loop] round ${round}: degenerate retry failed (upstream error ${e.status}: ${e.body.slice(0, 200)}); passing the empty turn through`);
|
|
54959
|
+
} else {
|
|
54960
|
+
ctx.log(`[acp-loop] round ${round}: degenerate retry failed (${e instanceof Error ? e.message : String(e)}); passing the empty turn through`);
|
|
54961
|
+
}
|
|
54962
|
+
log("warn", `[acp-loop] degenerate-turn auto-retry failed round ${round}: ${e instanceof Error ? e.message : String(e)}`);
|
|
54963
|
+
}
|
|
54964
|
+
}
|
|
54790
54965
|
break;
|
|
54791
54966
|
}
|
|
54792
54967
|
if (usage.inputTokens !== void 0 || usage.outputTokens !== void 0 || usage.cachedTokens !== void 0) {
|
|
@@ -54964,13 +55139,14 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
|
|
|
54964
55139
|
ctx.log(`[acp-loop] round ${round}: proxy tool executed; re-requesting so the model sees the result`);
|
|
54965
55140
|
if (signal?.aborted) break;
|
|
54966
55141
|
let newBody = adapter.buildRequest(coreMessages, systemPrompt, requestBody);
|
|
55142
|
+
newBody = normalizeStrictEchoBody(newBody, isStrictReasoningEcho(ctx.session, strictEchoOrigin), (level, msg) => log(level, `[acp-loop] ${msg}`), ctx.session.id ?? "unknown");
|
|
54967
55143
|
if (process.env.ACP_DUMP_BODY === "1") {
|
|
54968
55144
|
try {
|
|
54969
|
-
const
|
|
55145
|
+
const fs14 = await import("fs");
|
|
54970
55146
|
const dumpDir = process.env.ACP_DUMP_DIR || `${process.env.HOME}/.local/state/billion-context/dumps`;
|
|
54971
|
-
|
|
55147
|
+
fs14.mkdirSync(dumpDir, { recursive: true });
|
|
54972
55148
|
const sid = ctx.session.id ?? "unknown";
|
|
54973
|
-
|
|
55149
|
+
fs14.writeFileSync(`${dumpDir}/req-${Date.now()}-${sid}-REREQUEST.json`, JSON.stringify(newBody, null, 2));
|
|
54974
55150
|
} catch {
|
|
54975
55151
|
}
|
|
54976
55152
|
}
|
|
@@ -54998,6 +55174,9 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
|
|
|
54998
55174
|
ctx.log(`[acp-loop] 400 mentions reasoning_content \u2014 learned strict reasoning echo for this session; #651 reasoning-drop disabled (#684)`);
|
|
54999
55175
|
log("warn", `[acp-loop] learned strictReasoningEcho (session ${ctx.session.id}); reasoning-drop disabled (#684)`);
|
|
55000
55176
|
}
|
|
55177
|
+
if (e.status >= 400 && e.status < 500) {
|
|
55178
|
+
dumpRejectedBody(e.status, ctx.session.id ?? "unknown", JSON.stringify(newBody));
|
|
55179
|
+
}
|
|
55001
55180
|
const suffix = e.attempts > 1 ? ` after ${e.attempts} attempt(s)` : "";
|
|
55002
55181
|
ctx.log(`[acp-proxy: compress loop upstream error ${e.status}${suffix}: ${e.body.slice(0, 200)}]`);
|
|
55003
55182
|
log("error", `[acp-loop] upstream error ${e.status}${suffix}: ${e.body.slice(0, 200)}`);
|
|
@@ -55297,6 +55476,7 @@ data: ${JSON.stringify({ type: "response.created", response: { id: createdRespId
|
|
|
55297
55476
|
} else {
|
|
55298
55477
|
inputItems = coreToResponses(coreMessages, customToolCallIds);
|
|
55299
55478
|
}
|
|
55479
|
+
inputItems = hoistTrappedToolItems(inputItems);
|
|
55300
55480
|
const devParts = projection && projection.systemParts.length > 0 ? [...projection.systemParts, systemPrompt] : [systemPrompt];
|
|
55301
55481
|
const withDev = injectResponsesDeveloperMessage(inputItems, devParts.join("\n\n---\n\n"));
|
|
55302
55482
|
const rebuilt = { ...requestBody, input: withDev };
|
|
@@ -55477,7 +55657,7 @@ data: ${JSON.stringify({ type: "response.created", response: { id: createdRespId
|
|
|
55477
55657
|
cachedTokens: typeof pd?.cached_tokens === "number" ? pd.cached_tokens : void 0
|
|
55478
55658
|
};
|
|
55479
55659
|
maybeWarnDegenerate("completed");
|
|
55480
|
-
yield { kind: "done", finishReason: "completed" };
|
|
55660
|
+
yield { kind: "done", finishReason: "completed", thinking: sawReasoning };
|
|
55481
55661
|
} else if (type === "response.incomplete") {
|
|
55482
55662
|
yield* flushFilter();
|
|
55483
55663
|
terminalKind = "incomplete";
|
|
@@ -55867,7 +56047,7 @@ function createOpenaiAdapter(requestBody, clientSystem, absorbName) {
|
|
|
55867
56047
|
yield { kind: "meta", chunk: Buffer.from(eventStr + "\n\n", "utf8") };
|
|
55868
56048
|
}
|
|
55869
56049
|
maybeWarnDegenerate("stop");
|
|
55870
|
-
yield { kind: "done", finishReason: "stop", ...sawRealToolCall ? { suppressCompletion: true } : {} };
|
|
56050
|
+
yield { kind: "done", finishReason: "stop", thinking: sawReasoning, ...sawRealToolCall ? { suppressCompletion: true } : {} };
|
|
55871
56051
|
continue;
|
|
55872
56052
|
}
|
|
55873
56053
|
let parsed;
|
|
@@ -55913,13 +56093,14 @@ function createOpenaiAdapter(requestBody, clientSystem, absorbName) {
|
|
|
55913
56093
|
const chunk = rawBuf;
|
|
55914
56094
|
yield { kind: "meta", chunk };
|
|
55915
56095
|
maybeWarnDegenerate(finishReason);
|
|
55916
|
-
yield { kind: "done", finishReason, suppressCompletion: true };
|
|
56096
|
+
yield { kind: "done", finishReason, suppressCompletion: true, thinking: sawReasoning };
|
|
55917
56097
|
continue;
|
|
55918
56098
|
} else {
|
|
55919
56099
|
maybeWarnDegenerate(finishReason);
|
|
55920
56100
|
yield {
|
|
55921
56101
|
kind: "done",
|
|
55922
|
-
finishReason: hadToolCalls && finishReason === "stop" ? "tool_calls" : finishReason
|
|
56102
|
+
finishReason: hadToolCalls && finishReason === "stop" ? "tool_calls" : finishReason,
|
|
56103
|
+
thinking: sawReasoning
|
|
55923
56104
|
};
|
|
55924
56105
|
}
|
|
55925
56106
|
}
|
|
@@ -56340,7 +56521,7 @@ ${systemPrompt}` : systemPrompt;
|
|
|
56340
56521
|
};
|
|
56341
56522
|
}
|
|
56342
56523
|
maybeWarnDegenerate(stopReason);
|
|
56343
|
-
yield { kind: "done", finishReason: stopReason };
|
|
56524
|
+
yield { kind: "done", finishReason: stopReason, thinking: sawThinking };
|
|
56344
56525
|
} else if (type === "message_stop") {
|
|
56345
56526
|
if (lastTextIndex !== null) {
|
|
56346
56527
|
const tail = tagFilter.flush();
|
|
@@ -56359,7 +56540,7 @@ ${systemPrompt}` : systemPrompt;
|
|
|
56359
56540
|
};
|
|
56360
56541
|
}
|
|
56361
56542
|
maybeWarnDegenerate(stopReason);
|
|
56362
|
-
yield { kind: "done", finishReason: stopReason ?? "end_turn" };
|
|
56543
|
+
yield { kind: "done", finishReason: stopReason ?? "end_turn", thinking: sawThinking };
|
|
56363
56544
|
} else if (round === 1) {
|
|
56364
56545
|
yield { kind: "meta", chunk: rawBuf, firstRoundOnly: true };
|
|
56365
56546
|
}
|
|
@@ -56530,7 +56711,16 @@ function surfaceReadonlyJson(current, proxyCalls, ctx) {
|
|
|
56530
56711
|
}
|
|
56531
56712
|
if (markers.length === 0) return current;
|
|
56532
56713
|
const out = Array.isArray(current.output) ? [...current.output] : [];
|
|
56533
|
-
|
|
56714
|
+
const markerItem = { type: "message", id: `msg_acp_ro_${Date.now()}_${markers.length}`, role: "assistant", content: [{ type: "output_text", text: markers.join("\n") }] };
|
|
56715
|
+
let insertAt = out.length;
|
|
56716
|
+
for (let i = 0; i < out.length; i++) {
|
|
56717
|
+
const t = out[i]?.type;
|
|
56718
|
+
if (t === "function_call" || t === "custom_tool_call") {
|
|
56719
|
+
insertAt = i;
|
|
56720
|
+
break;
|
|
56721
|
+
}
|
|
56722
|
+
}
|
|
56723
|
+
out.splice(insertAt, 0, markerItem);
|
|
56534
56724
|
return { ...current, output: out };
|
|
56535
56725
|
}
|
|
56536
56726
|
async function compressLoopResponsesJson(initialResponse, ctx, requestBody, requestOptions) {
|
|
@@ -56565,7 +56755,7 @@ async function compressLoopResponsesJson(initialResponse, ctx, requestBody, requ
|
|
|
56565
56755
|
ctx.log(`[acp-proxy: responses JSON ${call.name} \u2192 ${result2.slice(0, 120).replace(/\n/g, " ")}]`);
|
|
56566
56756
|
inputItems.push({ type: "message", role: "developer", content: buildVisibilityMarker(call.name, result2) });
|
|
56567
56757
|
}
|
|
56568
|
-
requestBody.input = inputItems;
|
|
56758
|
+
requestBody.input = hoistTrappedToolItems(inputItems);
|
|
56569
56759
|
const result = await fetchWithRetry(requestOptions.url, {
|
|
56570
56760
|
method: "POST",
|
|
56571
56761
|
headers: requestOptions.headers,
|
|
@@ -57760,7 +57950,7 @@ var PrefixAffinityResolver = class {
|
|
|
57760
57950
|
var prefixAffinity = new PrefixAffinityResolver();
|
|
57761
57951
|
|
|
57762
57952
|
// src/affinity-persist.ts
|
|
57763
|
-
import
|
|
57953
|
+
import fs5 from "fs";
|
|
57764
57954
|
import path11 from "path";
|
|
57765
57955
|
var PERSIST_DEBOUNCE_MS = 5e3;
|
|
57766
57956
|
function affinityFile() {
|
|
@@ -57775,9 +57965,9 @@ function writeSnapshot() {
|
|
|
57775
57965
|
const file = affinityFile();
|
|
57776
57966
|
const snapshot = { version: 1, entries: prefixAffinity.exportSnapshot() };
|
|
57777
57967
|
const tmp = `${file}.tmp`;
|
|
57778
|
-
|
|
57779
|
-
|
|
57780
|
-
|
|
57968
|
+
fs5.mkdirSync(path11.dirname(file), { recursive: true });
|
|
57969
|
+
fs5.writeFileSync(tmp, JSON.stringify(snapshot));
|
|
57970
|
+
fs5.renameSync(tmp, file);
|
|
57781
57971
|
} catch (e) {
|
|
57782
57972
|
log("warn", `[prefix-affinity] persist failed (${e instanceof Error ? e.message : String(e)}); affinity survives in memory`);
|
|
57783
57973
|
} finally {
|
|
@@ -57802,8 +57992,8 @@ function flushPrefixAffinity() {
|
|
|
57802
57992
|
function hydratePrefixAffinity() {
|
|
57803
57993
|
try {
|
|
57804
57994
|
const file = affinityFile();
|
|
57805
|
-
if (!
|
|
57806
|
-
const parsed = JSON.parse(
|
|
57995
|
+
if (!fs5.existsSync(file)) return;
|
|
57996
|
+
const parsed = JSON.parse(fs5.readFileSync(file, "utf8"));
|
|
57807
57997
|
const imported = prefixAffinity.importSnapshot(parsed.entries);
|
|
57808
57998
|
if (imported > 0) log("info", `[prefix-affinity] hydrated ${imported} chain(s) from ${path11.basename(file)} \u2014 anonymous sessions reattach across restarts`);
|
|
57809
57999
|
} catch (e) {
|
|
@@ -57954,13 +58144,13 @@ function buildStatusPanel(input) {
|
|
|
57954
58144
|
|
|
57955
58145
|
// src/plugin.ts
|
|
57956
58146
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
57957
|
-
import
|
|
58147
|
+
import fs6 from "fs";
|
|
57958
58148
|
import path12 from "path";
|
|
57959
58149
|
var PROXY_VERSION = (() => {
|
|
57960
58150
|
try {
|
|
57961
58151
|
const here = fileURLToPath3(import.meta.url);
|
|
57962
58152
|
const pkg = path12.join(path12.dirname(here), "..", "package.json");
|
|
57963
|
-
return JSON.parse(
|
|
58153
|
+
return JSON.parse(fs6.readFileSync(pkg, "utf8")).version ?? "dev";
|
|
57964
58154
|
} catch {
|
|
57965
58155
|
return "dev";
|
|
57966
58156
|
}
|
|
@@ -57973,7 +58163,7 @@ var VERSION2 = (() => {
|
|
|
57973
58163
|
try {
|
|
57974
58164
|
const here = fileURLToPath3(import.meta.url);
|
|
57975
58165
|
const pkg = path12.join(path12.dirname(here), "..", "package.json");
|
|
57976
|
-
return JSON.parse(
|
|
58166
|
+
return JSON.parse(fs6.readFileSync(pkg, "utf8")).version ?? "dev";
|
|
57977
58167
|
} catch {
|
|
57978
58168
|
return "dev";
|
|
57979
58169
|
}
|
|
@@ -58010,11 +58200,11 @@ function writeConversationsFile() {
|
|
|
58010
58200
|
try {
|
|
58011
58201
|
const obj = {};
|
|
58012
58202
|
for (const [k2, v2] of conversations) obj[k2] = v2;
|
|
58013
|
-
|
|
58203
|
+
fs6.mkdirSync(stateDir(), { recursive: true });
|
|
58014
58204
|
const filePath = conversationsFile();
|
|
58015
58205
|
const draft = `${filePath}.${process.pid}.bili-tmp`;
|
|
58016
|
-
|
|
58017
|
-
|
|
58206
|
+
fs6.writeFileSync(draft, JSON.stringify(obj));
|
|
58207
|
+
fs6.renameSync(draft, filePath);
|
|
58018
58208
|
conversationsDirty = false;
|
|
58019
58209
|
} catch {
|
|
58020
58210
|
}
|
|
@@ -58036,7 +58226,7 @@ function flushConversations() {
|
|
|
58036
58226
|
function loadConversations() {
|
|
58037
58227
|
let raw;
|
|
58038
58228
|
try {
|
|
58039
|
-
raw =
|
|
58229
|
+
raw = fs6.readFileSync(conversationsFile(), "utf8");
|
|
58040
58230
|
} catch {
|
|
58041
58231
|
return;
|
|
58042
58232
|
}
|
|
@@ -58049,7 +58239,7 @@ function loadConversations() {
|
|
|
58049
58239
|
}
|
|
58050
58240
|
} catch {
|
|
58051
58241
|
try {
|
|
58052
|
-
|
|
58242
|
+
fs6.renameSync(conversationsFile(), `${conversationsFile()}.corrupt-${Date.now()}`);
|
|
58053
58243
|
} catch {
|
|
58054
58244
|
}
|
|
58055
58245
|
log("warn", "[plugin] plugin-conversations.json is corrupt \u2014 backed up beside the original, starting an empty routing table");
|
|
@@ -58892,12 +59082,12 @@ async function pipePluginJson(stream2, res, session, protocol) {
|
|
|
58892
59082
|
import tls3 from "tls";
|
|
58893
59083
|
|
|
58894
59084
|
// src/discover.ts
|
|
58895
|
-
import
|
|
59085
|
+
import fs8 from "fs";
|
|
58896
59086
|
import os2 from "os";
|
|
58897
59087
|
import path14 from "path";
|
|
58898
59088
|
|
|
58899
59089
|
// src/client-config.ts
|
|
58900
|
-
import
|
|
59090
|
+
import fs7 from "fs";
|
|
58901
59091
|
import os from "os";
|
|
58902
59092
|
import path13 from "path";
|
|
58903
59093
|
function toModelWindow(id, contextWindow) {
|
|
@@ -58918,7 +59108,7 @@ function qoderIsCnSite(env = process.env) {
|
|
|
58918
59108
|
const cnDir = path13.join(h, ".qoder-cn");
|
|
58919
59109
|
const intlDir = path13.join(h, ".qoder");
|
|
58920
59110
|
try {
|
|
58921
|
-
if (
|
|
59111
|
+
if (fs7.existsSync(cnDir) && !fs7.existsSync(intlDir)) return true;
|
|
58922
59112
|
} catch {
|
|
58923
59113
|
}
|
|
58924
59114
|
return false;
|
|
@@ -58957,7 +59147,7 @@ function nonEmpty2(s3) {
|
|
|
58957
59147
|
}
|
|
58958
59148
|
function readJsonObject(filePath) {
|
|
58959
59149
|
try {
|
|
58960
|
-
const txt =
|
|
59150
|
+
const txt = fs7.readFileSync(filePath, "utf8");
|
|
58961
59151
|
const parsed = JSON.parse(txt);
|
|
58962
59152
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
58963
59153
|
} catch {
|
|
@@ -59031,7 +59221,7 @@ function parseCodebuddyModelsJson(obj) {
|
|
|
59031
59221
|
}
|
|
59032
59222
|
function readJsonFile(filePath) {
|
|
59033
59223
|
try {
|
|
59034
|
-
return JSON.parse(
|
|
59224
|
+
return JSON.parse(fs7.readFileSync(filePath, "utf8"));
|
|
59035
59225
|
} catch {
|
|
59036
59226
|
return null;
|
|
59037
59227
|
}
|
|
@@ -59093,7 +59283,7 @@ function parseDshSettingsYaml(text) {
|
|
|
59093
59283
|
function readDshConfig(dshHome) {
|
|
59094
59284
|
let text;
|
|
59095
59285
|
try {
|
|
59096
|
-
text =
|
|
59286
|
+
text = fs7.readFileSync(path13.join(dshHome, "settings.yaml"), "utf8");
|
|
59097
59287
|
} catch {
|
|
59098
59288
|
return { baseUrls: [] };
|
|
59099
59289
|
}
|
|
@@ -59195,7 +59385,7 @@ function readCodexConfig(codexHome) {
|
|
|
59195
59385
|
const cfgPath = path13.join(codexHome, "config.toml");
|
|
59196
59386
|
let text;
|
|
59197
59387
|
try {
|
|
59198
|
-
text =
|
|
59388
|
+
text = fs7.readFileSync(cfgPath, "utf8");
|
|
59199
59389
|
} catch {
|
|
59200
59390
|
return { providers: {} };
|
|
59201
59391
|
}
|
|
@@ -59279,7 +59469,7 @@ function readKimiConfig(kimiHome, env = process.env) {
|
|
|
59279
59469
|
const cfgPath = path13.join(kimiHome, "config.toml");
|
|
59280
59470
|
let text;
|
|
59281
59471
|
try {
|
|
59282
|
-
text =
|
|
59472
|
+
text = fs7.readFileSync(cfgPath, "utf8");
|
|
59283
59473
|
} catch {
|
|
59284
59474
|
return { providers: {} };
|
|
59285
59475
|
}
|
|
@@ -59380,7 +59570,7 @@ function readOmpConfig(ompHome) {
|
|
|
59380
59570
|
const cfgPath = path13.join(ompHome, "models.yml");
|
|
59381
59571
|
let text;
|
|
59382
59572
|
try {
|
|
59383
|
-
text =
|
|
59573
|
+
text = fs7.readFileSync(cfgPath, "utf8");
|
|
59384
59574
|
} catch {
|
|
59385
59575
|
return { providers: {} };
|
|
59386
59576
|
}
|
|
@@ -59461,7 +59651,7 @@ function readHermesConfig(hermesHome) {
|
|
|
59461
59651
|
const cfgPath = path13.join(hermesHome, "config.yaml");
|
|
59462
59652
|
let text;
|
|
59463
59653
|
try {
|
|
59464
|
-
text =
|
|
59654
|
+
text = fs7.readFileSync(cfgPath, "utf8");
|
|
59465
59655
|
} catch {
|
|
59466
59656
|
return { providers: {} };
|
|
59467
59657
|
}
|
|
@@ -59475,7 +59665,7 @@ function resolveOpencodeConfigFile(env) {
|
|
|
59475
59665
|
function readOpencodeConfig(file) {
|
|
59476
59666
|
let text;
|
|
59477
59667
|
try {
|
|
59478
|
-
text =
|
|
59668
|
+
text = fs7.readFileSync(file, "utf8");
|
|
59479
59669
|
} catch {
|
|
59480
59670
|
return { providers: {} };
|
|
59481
59671
|
}
|
|
@@ -59535,7 +59725,7 @@ function readZcodeConfig(zcodeHome) {
|
|
|
59535
59725
|
const cfgPath = path13.join(zcodeHome, "v2", "config.json");
|
|
59536
59726
|
let txt;
|
|
59537
59727
|
try {
|
|
59538
|
-
txt =
|
|
59728
|
+
txt = fs7.readFileSync(cfgPath, "utf8");
|
|
59539
59729
|
} catch {
|
|
59540
59730
|
return { providers: {} };
|
|
59541
59731
|
}
|
|
@@ -59661,7 +59851,7 @@ function readMtimes(paths) {
|
|
|
59661
59851
|
const mtimes = /* @__PURE__ */ new Map();
|
|
59662
59852
|
for (const p2 of paths) {
|
|
59663
59853
|
try {
|
|
59664
|
-
const st2 =
|
|
59854
|
+
const st2 = fs8.statSync(p2);
|
|
59665
59855
|
mtimes.set(p2, st2.mtimeMs);
|
|
59666
59856
|
} catch {
|
|
59667
59857
|
}
|
|
@@ -60882,7 +61072,7 @@ Content-Length: ${Buffer.byteLength(body)}\r
|
|
|
60882
61072
|
const originHost = opts.host === "0.0.0.0" || opts.host === "::" || opts.host === "localhost" ? "127.0.0.1" : opts.host.includes(":") && !opts.host.startsWith("[") ? `[${opts.host}]` : opts.host;
|
|
60883
61073
|
const origin = `http://${originHost}:${actualPort}`;
|
|
60884
61074
|
try {
|
|
60885
|
-
|
|
61075
|
+
fs9.mkdirSync(stateDir(), { recursive: true });
|
|
60886
61076
|
hydratePrefixAffinity();
|
|
60887
61077
|
atomicWriteInstanceFile({
|
|
60888
61078
|
origin,
|
|
@@ -61303,14 +61493,14 @@ async function handle(req, res, opts, core, config, log2, instanceId, instanceSt
|
|
|
61303
61493
|
try {
|
|
61304
61494
|
const rawDir = process.env.ACP_RAW_DUMP_DIR || `${stateDir()}/raw`;
|
|
61305
61495
|
try {
|
|
61306
|
-
|
|
61496
|
+
fs9.mkdirSync(rawDir, { recursive: true });
|
|
61307
61497
|
} catch {
|
|
61308
61498
|
}
|
|
61309
61499
|
const hdrs = maskHeadersForLog(
|
|
61310
61500
|
Object.fromEntries(Object.entries(req.headers).map(([k2, v2]) => [k2, Array.isArray(v2) ? v2.join(",") : String(v2)]))
|
|
61311
61501
|
);
|
|
61312
61502
|
const hdrText = Object.entries(hdrs).map(([k2, v2]) => `${k2}: ${v2}`).join("\n");
|
|
61313
|
-
|
|
61503
|
+
fs9.writeFileSync(`${rawDir}/${Date.now()}-INCOMING.txt`, `${req.method} ${maskUrlsInText(req.url ?? "")}
|
|
61314
61504
|
${hdrText}
|
|
61315
61505
|
|
|
61316
61506
|
${bodyBuffer.toString("utf8")}`);
|
|
@@ -61654,17 +61844,13 @@ function withReasoningDrop(msgs, reasoning, log2, sessionId, strictEcho) {
|
|
|
61654
61844
|
}
|
|
61655
61845
|
return out;
|
|
61656
61846
|
}
|
|
61657
|
-
function isStrictReasoningEcho(session, upstreamOrigin) {
|
|
61658
|
-
if (session.metadata.strictReasoningEcho === true) return true;
|
|
61659
|
-
return upstreamOrigin !== void 0 && /deepseek/i.test(upstreamOrigin);
|
|
61660
|
-
}
|
|
61661
61847
|
function warnReasoningPairs(wireMessages, log2, sessionId) {
|
|
61662
61848
|
let withRc = 0;
|
|
61663
61849
|
let split = 0;
|
|
61664
61850
|
for (const m2 of wireMessages) {
|
|
61665
61851
|
const msg = m2;
|
|
61666
61852
|
if (msg?.role !== "assistant") continue;
|
|
61667
|
-
const hasRc = typeof msg.reasoning_content === "string"
|
|
61853
|
+
const hasRc = typeof msg.reasoning_content === "string";
|
|
61668
61854
|
if (hasRc) withRc++;
|
|
61669
61855
|
else if (Array.isArray(msg.tool_calls) && msg.tool_calls.length > 0) split++;
|
|
61670
61856
|
}
|
|
@@ -61844,9 +62030,9 @@ function prepareAnthropic(parsed, req, opts, core, config, prompts, surface, log
|
|
|
61844
62030
|
applyCompactionArchive(session, activeBefore, new Set(msgs.map((m2) => m2.id)), log2);
|
|
61845
62031
|
reapOrphanBlocks(session, msgs, deactivateBlock);
|
|
61846
62032
|
rebuiltMessages = coreToAnthropic(processedMessages, cacheControls);
|
|
61847
|
-
systemOut = injectSystem(parsed, opts, prompts, loopConfig);
|
|
62033
|
+
systemOut = injectSystem(parsed, opts, prompts, loopConfig, surface);
|
|
61848
62034
|
if (injectTools) {
|
|
61849
|
-
toolsOut = injectTool(parsed.tools, absorbActive ? ABSORB_TOOL : void 0);
|
|
62035
|
+
toolsOut = injectTool(parsed.tools, absorbActive ? ABSORB_TOOL : void 0, surface?.toolPrompts);
|
|
61850
62036
|
}
|
|
61851
62037
|
if (willInjectNudge && turn.nudge) {
|
|
61852
62038
|
try {
|
|
@@ -61976,7 +62162,7 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, surface, log2,
|
|
|
61976
62162
|
rebuiltMessages = injectOpenaiSystem(rebuiltMessages, sysParts);
|
|
61977
62163
|
openaiOutboundSystem = sysParts.join("\n\n");
|
|
61978
62164
|
if (injectTools) {
|
|
61979
|
-
toolsOut = injectOpenaiTool(parsed.tools, absorbActive ? ABSORB_TOOL_OPENAI : void 0);
|
|
62165
|
+
toolsOut = injectOpenaiTool(parsed.tools, absorbActive ? ABSORB_TOOL_OPENAI : void 0, surface?.toolPrompts);
|
|
61980
62166
|
}
|
|
61981
62167
|
if (willInjectNudge && turn.nudge) {
|
|
61982
62168
|
try {
|
|
@@ -61991,6 +62177,7 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, surface, log2,
|
|
|
61991
62177
|
log2("warn", `[${sessionId}] kernel transform failed, forwarding unchanged: ${String(err2)}`);
|
|
61992
62178
|
processedMessages = [];
|
|
61993
62179
|
}
|
|
62180
|
+
rebuiltMessages = normalizeStrictEchoReasoning(rebuiltMessages, isStrictReasoningEcho(session, upstreamOrigin), log2, sessionId);
|
|
61994
62181
|
const rebuilt = { ...parsed, messages: rebuiltMessages, tools: toolsOut };
|
|
61995
62182
|
warnReasoningPairs(rebuiltMessages, log2, sessionId);
|
|
61996
62183
|
clampOutgoingOutput(rebuilt, typeof parsed.max_completion_tokens === "number" ? "max_completion_tokens" : "max_tokens", { systemText: openaiSystemText, tools: toolsOut, processedMessages, lastInputTokens: session.stats.lastInputTokens, nativeWindow, imageTokens: imageTokensInParsedBody("openai", rebuilt, imageBillingFor(opts, billingUpstream ?? upstreamOrigin)) }, sessionId, log2);
|
|
@@ -62077,6 +62264,7 @@ function prepareResponses(parsed, req, opts, core, config, prompts, surface, log
|
|
|
62077
62264
|
processedMessages = repairResponsesAssistantOrdering(stripReasoning(stripKernelSummaries(turn.messages, turn.state)), originalMessages);
|
|
62078
62265
|
reapOrphanBlocks(session, msgs, deactivateBlock);
|
|
62079
62266
|
rebuiltInput = patchResponsesInput(projection, processedMessages);
|
|
62267
|
+
if (Array.isArray(rebuiltInput)) rebuiltInput = hoistTrappedToolItems(rebuiltInput);
|
|
62080
62268
|
const forgedSummaries = echoReplaced ? [] : session.metadata.codexForgedSummaries ?? [];
|
|
62081
62269
|
if (shouldInject && !isCompactionTrigger && !process.env.ACP_NO_COMPRESS_PROMPT) {
|
|
62082
62270
|
const prompt = withMarkerIntegrityNote(responsesTextProtocol ? buildCompressHybridSystemPrompt(prompts, surface?.promptSections) : buildCompressSystemPrompt(prompts, surface?.promptSections));
|
|
@@ -62086,7 +62274,7 @@ function prepareResponses(parsed, req, opts, core, config, prompts, surface, log
|
|
|
62086
62274
|
responsesDevContent = devContent;
|
|
62087
62275
|
rebuiltInput = injectResponsesDeveloperMessage(rebuiltInput, devContent);
|
|
62088
62276
|
if (!process.env.ACP_NO_INJECT_TOOL && injectTools) {
|
|
62089
|
-
toolsOut = responsesTextProtocol ? injectResponsesTool(parsed.tools, ACP_READONLY_TOOLS_RESPONSES) : injectResponsesTool(parsed.tools, absorbActive ? [...ACP_TOOLS_RESPONSES, ABSORB_TOOL_RESPONSES] : ACP_TOOLS_RESPONSES);
|
|
62277
|
+
toolsOut = responsesTextProtocol ? injectResponsesTool(parsed.tools, ACP_READONLY_TOOLS_RESPONSES, surface?.toolPrompts) : injectResponsesTool(parsed.tools, absorbActive ? [...ACP_TOOLS_RESPONSES, ABSORB_TOOL_RESPONSES] : ACP_TOOLS_RESPONSES, surface?.toolPrompts);
|
|
62090
62278
|
}
|
|
62091
62279
|
} else if (projection.systemParts.length > 0 || forgedSummaries.length > 0) {
|
|
62092
62280
|
const devContent = [...projection.systemParts, ...forgedSummaries].join("\n\n---\n\n");
|
|
@@ -62242,11 +62430,12 @@ function prepareResponsesCompact(body, parsed, session, req, core, config, log2)
|
|
|
62242
62430
|
}
|
|
62243
62431
|
const viewed = applyAbsorbView(turn.messages, turn.state, compactConfig, session.stats.lastInputTokens);
|
|
62244
62432
|
const processed = repairResponsesAssistantOrdering(stripKernelSummaries(viewed, turn.state), projection.msgs);
|
|
62245
|
-
|
|
62433
|
+
let output = patchResponsesInput(projection, processed);
|
|
62246
62434
|
if (typeof output === "string") {
|
|
62247
62435
|
session.state = prevState;
|
|
62248
62436
|
return base;
|
|
62249
62437
|
}
|
|
62438
|
+
output = hoistTrappedToolItems(output);
|
|
62250
62439
|
snapshotMessages(session, projection.msgs);
|
|
62251
62440
|
markDirty(session);
|
|
62252
62441
|
log2("info", `[${session.id}] codex compact intercepted (endpoint); forged history with ${output.length} item(s), upstream not contacted`);
|
|
@@ -62600,16 +62789,16 @@ async function forward(req, res, opts, body, prepared, core, config, log2, route
|
|
|
62600
62789
|
if (bodyDumpEnabled() && process.env.ACP_DUMP_REQ !== "0") {
|
|
62601
62790
|
const dumpDir = process.env.ACP_DUMP_DIR || `${stateDir()}/dumps`;
|
|
62602
62791
|
try {
|
|
62603
|
-
|
|
62792
|
+
fs9.mkdirSync(dumpDir, { recursive: true });
|
|
62604
62793
|
} catch {
|
|
62605
62794
|
}
|
|
62606
62795
|
const sid = prepared?.session.id ?? "unknown";
|
|
62607
62796
|
const out = `${dumpDir}/req-${Date.now()}-${safeSessionId(sid)}.json`;
|
|
62608
62797
|
try {
|
|
62609
62798
|
const pretty = JSON.stringify(JSON.parse(wireBody), null, 2);
|
|
62610
|
-
|
|
62799
|
+
fs9.writeFileSync(out, pretty);
|
|
62611
62800
|
} catch {
|
|
62612
|
-
|
|
62801
|
+
fs9.writeFileSync(out, wireBody);
|
|
62613
62802
|
}
|
|
62614
62803
|
log2("info", `[debug] forwarded body written to ${out}`);
|
|
62615
62804
|
}
|
|
@@ -62629,7 +62818,7 @@ async function forward(req, res, opts, body, prepared, core, config, log2, route
|
|
|
62629
62818
|
const rawBase = bodyDumpEnabled() ? (() => {
|
|
62630
62819
|
try {
|
|
62631
62820
|
const rawDir = process.env.ACP_RAW_DUMP_DIR || `${stateDir()}/raw`;
|
|
62632
|
-
|
|
62821
|
+
fs9.mkdirSync(rawDir, { recursive: true });
|
|
62633
62822
|
return `${rawDir}/${Date.now()}-${safeSessionId(prepared?.session.id)}`;
|
|
62634
62823
|
} catch {
|
|
62635
62824
|
return "";
|
|
@@ -62640,7 +62829,7 @@ async function forward(req, res, opts, body, prepared, core, config, log2, route
|
|
|
62640
62829
|
const hdrText = Object.entries(maskHeadersForLog(headers)).map(([k2, v2]) => `${k2}: ${v2}`).join("\n");
|
|
62641
62830
|
const bodyText = req.method === "GET" || req.method === "HEAD" ? "" : typeof wireBody === "string" ? wireBody : Buffer.from(wireBody).toString("utf8");
|
|
62642
62831
|
const reqPath = `${rawBase}-REQ.txt`;
|
|
62643
|
-
|
|
62832
|
+
fs9.writeFileSync(reqPath, `${req.method ?? "POST"} ${maskUrlForLog(upstreamUrl)}
|
|
62644
62833
|
${hdrText}
|
|
62645
62834
|
|
|
62646
62835
|
${bodyText}`);
|
|
@@ -62752,7 +62941,7 @@ ${bodyText}`);
|
|
|
62752
62941
|
try {
|
|
62753
62942
|
const hdrText = Object.entries(maskHeadersForLog(respHeaders)).map(([k2, v2]) => `${k2}: ${v2}`).join("\n");
|
|
62754
62943
|
const resPath = `${rawBase}-RES.txt`;
|
|
62755
|
-
|
|
62944
|
+
fs9.writeFileSync(resPath, `${upstream.status}
|
|
62756
62945
|
${hdrText}
|
|
62757
62946
|
`);
|
|
62758
62947
|
log2("info", `[debug] RAW response dump: ${resPath}`);
|
|
@@ -62811,6 +63000,13 @@ ${hdrText}
|
|
|
62811
63000
|
}
|
|
62812
63001
|
markDirty(s3);
|
|
62813
63002
|
}
|
|
63003
|
+
if (upstream.status === 400 && /reasoning_content/i.test(errBody.toString("utf8"))) {
|
|
63004
|
+
if (s3.metadata.strictReasoningEcho !== true) {
|
|
63005
|
+
s3.metadata.strictReasoningEcho = true;
|
|
63006
|
+
markDirty(s3);
|
|
63007
|
+
log2("warn", `[${s3.id}] upstream 400 mentions reasoning_content \u2014 learned strictReasoningEcho for this session (#684/#762); reasoning-drop disabled`);
|
|
63008
|
+
}
|
|
63009
|
+
}
|
|
62814
63010
|
}
|
|
62815
63011
|
if (prepared?.session && upstream.status >= 500) {
|
|
62816
63012
|
armFailureShrink(prepared, log2, `upstream ${upstream.status}`);
|
|
@@ -62823,6 +63019,9 @@ ${hdrText}
|
|
|
62823
63019
|
if (bodyText.length > 600) snippet += " \u2026";
|
|
62824
63020
|
if (!snippet) snippet = "(no body)";
|
|
62825
63021
|
log("warn", `[${errSid}] \u2190 upstream ${upstream.status}${reqIdText}: ${snippet}`);
|
|
63022
|
+
if (upstream.status >= 400 && upstream.status < 500) {
|
|
63023
|
+
dumpRejectedBody(upstream.status, errSid, wireBody);
|
|
63024
|
+
}
|
|
62826
63025
|
if (res.headersSent) {
|
|
62827
63026
|
if (prepared?.stream) {
|
|
62828
63027
|
emitStreamError(res, prepared.protocol, `upstream HTTP ${upstream.status}: ${snippet}`, (m2) => log("info", m2));
|
|
@@ -65227,7 +65426,7 @@ var hr = /* @__PURE__ */ Symbol("entry");
|
|
|
65227
65426
|
var cs = /* @__PURE__ */ Symbol("entryOpt");
|
|
65228
65427
|
var ui = /* @__PURE__ */ Symbol("writeEntryClass");
|
|
65229
65428
|
var lr = /* @__PURE__ */ Symbol("write");
|
|
65230
|
-
var
|
|
65429
|
+
var fs10 = /* @__PURE__ */ Symbol("ondrain");
|
|
65231
65430
|
var wt = class extends A {
|
|
65232
65431
|
sync = false;
|
|
65233
65432
|
opt;
|
|
@@ -65261,8 +65460,8 @@ var wt = class extends A {
|
|
|
65261
65460
|
if ((t.gzip ? 1 : 0) + (t.brotli ? 1 : 0) + (t.zstd ? 1 : 0) > 1) throw new TypeError("gzip, brotli, zstd are mutually exclusive");
|
|
65262
65461
|
if (t.gzip && (typeof t.gzip != "object" && (t.gzip = {}), this.portable && (t.gzip.portable = true), this.zip = new ze(t.gzip)), t.brotli && (typeof t.brotli != "object" && (t.brotli = {}), this.zip = new We(t.brotli)), t.zstd && (typeof t.zstd != "object" && (t.zstd = {}), this.zip = new Ye(t.zstd)), !this.zip) throw new Error("impossible");
|
|
65263
65462
|
let e = this.zip;
|
|
65264
|
-
e.on("data", (i) => super.write(i)), e.on("end", () => super.end()), e.on("drain", () => this[
|
|
65265
|
-
} else this.on("drain", this[
|
|
65463
|
+
e.on("data", (i) => super.write(i)), e.on("end", () => super.end()), e.on("drain", () => this[fs10]()), this.on("resume", () => e.resume());
|
|
65464
|
+
} else this.on("drain", this[fs10]);
|
|
65266
65465
|
this.noDirRecurse = !!t.noDirRecurse, this.follow = !!t.follow, this.noMtime = !!t.noMtime, t.mtime && (this.mtime = t.mtime), this.filter = typeof t.filter == "function" ? t.filter : () => true, this[W] = new hi(), this[G] = 0, this.jobs = Number(t.jobs) || 4, this[Ee] = false, this[me] = false;
|
|
65267
65466
|
}
|
|
65268
65467
|
[lr](t) {
|
|
@@ -65375,7 +65574,7 @@ var wt = class extends A {
|
|
|
65375
65574
|
this.emit("error", e);
|
|
65376
65575
|
}
|
|
65377
65576
|
}
|
|
65378
|
-
[
|
|
65577
|
+
[fs10]() {
|
|
65379
65578
|
this[Et] && this[Et].entry && this[Et].entry.resume();
|
|
65380
65579
|
}
|
|
65381
65580
|
[di](t) {
|
|
@@ -66733,14 +66932,14 @@ function startAutoUpdate(opts) {
|
|
|
66733
66932
|
}
|
|
66734
66933
|
|
|
66735
66934
|
// src/mcp.ts
|
|
66736
|
-
import
|
|
66935
|
+
import fs11 from "fs";
|
|
66737
66936
|
import path16 from "path";
|
|
66738
66937
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
66739
66938
|
var VERSION3 = (() => {
|
|
66740
66939
|
try {
|
|
66741
66940
|
const here = fileURLToPath5(import.meta.url);
|
|
66742
66941
|
const pkg = path16.join(path16.dirname(here), "..", "package.json");
|
|
66743
|
-
return JSON.parse(
|
|
66942
|
+
return JSON.parse(fs11.readFileSync(pkg, "utf8")).version ?? "dev";
|
|
66744
66943
|
} catch {
|
|
66745
66944
|
return "dev";
|
|
66746
66945
|
}
|
|
@@ -66945,7 +67144,7 @@ if (process.argv[1] && /(?:^|[\\/])mcp\.(?:ts|js)$/.test(process.argv[1])) {
|
|
|
66945
67144
|
}
|
|
66946
67145
|
|
|
66947
67146
|
// src/plugin-install.ts
|
|
66948
|
-
import
|
|
67147
|
+
import fs12 from "fs";
|
|
66949
67148
|
import path17 from "path";
|
|
66950
67149
|
import os4 from "os";
|
|
66951
67150
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
@@ -66973,14 +67172,14 @@ function homeFile(rel2, envOverride) {
|
|
|
66973
67172
|
return path17.join(base, rel2);
|
|
66974
67173
|
}
|
|
66975
67174
|
function backupOnce(file) {
|
|
66976
|
-
if (
|
|
66977
|
-
|
|
67175
|
+
if (fs12.existsSync(file) && !fs12.existsSync(`${file}.bili-bak`)) {
|
|
67176
|
+
fs12.copyFileSync(file, `${file}.bili-bak`);
|
|
66978
67177
|
}
|
|
66979
67178
|
}
|
|
66980
67179
|
function readJson(file) {
|
|
66981
67180
|
let text;
|
|
66982
67181
|
try {
|
|
66983
|
-
text =
|
|
67182
|
+
text = fs12.readFileSync(file, "utf8");
|
|
66984
67183
|
} catch (err2) {
|
|
66985
67184
|
if (err2.code === "ENOENT") return {};
|
|
66986
67185
|
throw err2;
|
|
@@ -66997,12 +67196,12 @@ function readJson(file) {
|
|
|
66997
67196
|
return parsed;
|
|
66998
67197
|
}
|
|
66999
67198
|
function writeJson(file, data) {
|
|
67000
|
-
|
|
67199
|
+
fs12.mkdirSync(path17.dirname(file), { recursive: true });
|
|
67001
67200
|
backupOnce(file);
|
|
67002
|
-
|
|
67201
|
+
fs12.writeFileSync(file, JSON.stringify(data, null, 2) + "\n");
|
|
67003
67202
|
}
|
|
67004
67203
|
function requireDistFile(file) {
|
|
67005
|
-
if (!
|
|
67204
|
+
if (!fs12.existsSync(file)) {
|
|
67006
67205
|
process.stderr.write(`bili plugin: warning: ${file} does not exist yet (run \`npm run build\` in ${selfPackageRoot()}) \u2014 the entry will be dead until built
|
|
67007
67206
|
`);
|
|
67008
67207
|
}
|
|
@@ -67090,13 +67289,13 @@ function ompBlockLoaded(text) {
|
|
|
67090
67289
|
const lines = text.split("\n");
|
|
67091
67290
|
return ompExtensionItemLines(text).some((i) => {
|
|
67092
67291
|
const v2 = ompEntryValue(lines[i]);
|
|
67093
|
-
return OMP_ENTRY_RE.test(v2) &&
|
|
67292
|
+
return OMP_ENTRY_RE.test(v2) && fs12.existsSync(v2);
|
|
67094
67293
|
});
|
|
67095
67294
|
}
|
|
67096
67295
|
function ompRemove() {
|
|
67097
67296
|
const file = ompConfigFile();
|
|
67098
|
-
if (!
|
|
67099
|
-
const text =
|
|
67297
|
+
if (!fs12.existsSync(file)) return `omp: not installed (${file})`;
|
|
67298
|
+
const text = fs12.readFileSync(file, "utf8");
|
|
67100
67299
|
const lines = text.split("\n");
|
|
67101
67300
|
const drop = new Set(
|
|
67102
67301
|
ompExtensionItemLines(text).filter((i) => OMP_ENTRY_RE.test(ompEntryValue(lines[i])))
|
|
@@ -67104,15 +67303,15 @@ function ompRemove() {
|
|
|
67104
67303
|
if (drop.size === 0) return `omp: not installed (${file})`;
|
|
67105
67304
|
const cleaned = lines.filter((_2, i) => !drop.has(i)).join("\n");
|
|
67106
67305
|
backupOnce(file);
|
|
67107
|
-
|
|
67306
|
+
fs12.writeFileSync(file, cleaned);
|
|
67108
67307
|
return `omp: removed from ${file}`;
|
|
67109
67308
|
}
|
|
67110
67309
|
function ompInstall() {
|
|
67111
67310
|
const file = ompConfigFile();
|
|
67112
67311
|
const entry = ompExtensionPath();
|
|
67113
67312
|
requireDistFile(entry);
|
|
67114
|
-
|
|
67115
|
-
let text =
|
|
67313
|
+
fs12.mkdirSync(path17.dirname(file), { recursive: true });
|
|
67314
|
+
let text = fs12.existsSync(file) ? fs12.readFileSync(file, "utf8") : "";
|
|
67116
67315
|
if (ompBlockLoaded(text)) return `omp: already installed (${file})`;
|
|
67117
67316
|
{
|
|
67118
67317
|
const lines = text.split("\n");
|
|
@@ -67154,25 +67353,25 @@ ${tail}`;
|
|
|
67154
67353
|
throw new Error(`${file}: edit would leave ${occurrences} copies of the entry \u2014 aborting without writing`);
|
|
67155
67354
|
}
|
|
67156
67355
|
backupOnce(file);
|
|
67157
|
-
|
|
67356
|
+
fs12.writeFileSync(file, out);
|
|
67158
67357
|
return `omp: installed -> ${file} extensions += ${entry}`;
|
|
67159
67358
|
}
|
|
67160
67359
|
function ompStatus() {
|
|
67161
67360
|
const file = ompConfigFile();
|
|
67162
|
-
const text =
|
|
67361
|
+
const text = fs12.existsSync(file) ? fs12.readFileSync(file, "utf8") : "";
|
|
67163
67362
|
const lines = text.split("\n");
|
|
67164
67363
|
let broken = false;
|
|
67165
67364
|
for (const i of ompExtensionItemLines(text)) {
|
|
67166
67365
|
const v2 = ompEntryValue(lines[i]);
|
|
67167
67366
|
if (!OMP_ENTRY_RE.test(v2)) continue;
|
|
67168
|
-
if (
|
|
67367
|
+
if (fs12.existsSync(v2)) return "installed";
|
|
67169
67368
|
broken = true;
|
|
67170
67369
|
}
|
|
67171
67370
|
return broken ? "broken" : "not installed";
|
|
67172
67371
|
}
|
|
67173
67372
|
function ompPluginLoadedFrom(ompHome) {
|
|
67174
67373
|
try {
|
|
67175
|
-
return ompBlockLoaded(
|
|
67374
|
+
return ompBlockLoaded(fs12.readFileSync(path17.join(ompHome, "config.yml"), "utf8"));
|
|
67176
67375
|
} catch {
|
|
67177
67376
|
return false;
|
|
67178
67377
|
}
|
|
@@ -67226,7 +67425,7 @@ function malformedCodexArgs(block) {
|
|
|
67226
67425
|
}
|
|
67227
67426
|
function codexInstall() {
|
|
67228
67427
|
const file = codexToml();
|
|
67229
|
-
const text =
|
|
67428
|
+
const text = fs12.existsSync(file) ? fs12.readFileSync(file, "utf8") : "";
|
|
67230
67429
|
const existing = /^[ \t]*\[mcp_servers\.bili\][ \t]*$/m.exec(text);
|
|
67231
67430
|
if (existing !== null) {
|
|
67232
67431
|
const block = text.slice(existing.index, text.indexOf("\n[", existing.index + 1) === -1 ? void 0 : text.indexOf("\n[", existing.index + 1));
|
|
@@ -67234,19 +67433,19 @@ function codexInstall() {
|
|
|
67234
67433
|
if (block.trimEnd() === canonical.trimEnd()) return `codex: already installed (${file})`;
|
|
67235
67434
|
const refreshed = text.slice(0, existing.index) + canonical + text.slice(existing.index + block.length);
|
|
67236
67435
|
backupOnce(file);
|
|
67237
|
-
|
|
67436
|
+
fs12.writeFileSync(file, refreshed);
|
|
67238
67437
|
const healed = malformedCodexArgs(block) ? " (repaired args: was not an array)" : "";
|
|
67239
67438
|
return `codex: refreshed [mcp_servers.bili] -> ${file}${healed}`;
|
|
67240
67439
|
}
|
|
67241
|
-
|
|
67440
|
+
fs12.mkdirSync(path17.dirname(file), { recursive: true });
|
|
67242
67441
|
backupOnce(file);
|
|
67243
|
-
|
|
67442
|
+
fs12.writeFileSync(file, text + (text.endsWith("\n") || text.length === 0 ? "" : "\n") + codexBlock());
|
|
67244
67443
|
return `codex: installed -> ${file} [mcp_servers.bili]`;
|
|
67245
67444
|
}
|
|
67246
67445
|
function codexRemove() {
|
|
67247
67446
|
const file = codexToml();
|
|
67248
|
-
if (!
|
|
67249
|
-
const text =
|
|
67447
|
+
if (!fs12.existsSync(file)) return `codex: not installed (${file})`;
|
|
67448
|
+
const text = fs12.readFileSync(file, "utf8");
|
|
67250
67449
|
const start = (() => {
|
|
67251
67450
|
const m2 = /^[ \t]*\[mcp_servers\.bili\][ \t]*$/m.exec(text);
|
|
67252
67451
|
return m2 === null ? -1 : m2.index;
|
|
@@ -67259,11 +67458,11 @@ function codexRemove() {
|
|
|
67259
67458
|
const end = nextTable >= 0 ? start + firstNewline + 1 + nextTable : text.length;
|
|
67260
67459
|
const cleaned = (text.slice(0, lineStart).replace(/\n+$/, "\n") + text.slice(end)).replace(/^\n+/, "");
|
|
67261
67460
|
backupOnce(file);
|
|
67262
|
-
|
|
67461
|
+
fs12.writeFileSync(file, cleaned);
|
|
67263
67462
|
return `codex: removed from ${file}`;
|
|
67264
67463
|
}
|
|
67265
67464
|
function codexStatus() {
|
|
67266
|
-
const text =
|
|
67465
|
+
const text = fs12.existsSync(codexToml()) ? fs12.readFileSync(codexToml(), "utf8") : "";
|
|
67267
67466
|
return /^\[mcp_servers\.bili\]\s*$/m.test(text) ? "installed" : "not installed";
|
|
67268
67467
|
}
|
|
67269
67468
|
function opencodeJson() {
|
|
@@ -67327,7 +67526,7 @@ function pluginStatusAll() {
|
|
|
67327
67526
|
|
|
67328
67527
|
// src/launcher.ts
|
|
67329
67528
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
67330
|
-
import
|
|
67529
|
+
import fs13 from "fs";
|
|
67331
67530
|
import net2 from "net";
|
|
67332
67531
|
import os5 from "os";
|
|
67333
67532
|
import path18 from "path";
|
|
@@ -67795,7 +67994,7 @@ function overlayLockPath(overlay) {
|
|
|
67795
67994
|
function livePidHoldsOverlay(overlay) {
|
|
67796
67995
|
let raw;
|
|
67797
67996
|
try {
|
|
67798
|
-
raw =
|
|
67997
|
+
raw = fs13.readFileSync(overlayLockPath(overlay), "utf8");
|
|
67799
67998
|
} catch {
|
|
67800
67999
|
return void 0;
|
|
67801
68000
|
}
|
|
@@ -67813,13 +68012,13 @@ function linkOverlayEntry(realHome, overlay, entry) {
|
|
|
67813
68012
|
const link = path18.join(overlay, entry);
|
|
67814
68013
|
let st2;
|
|
67815
68014
|
try {
|
|
67816
|
-
st2 =
|
|
68015
|
+
st2 = fs13.lstatSync(target);
|
|
67817
68016
|
} catch {
|
|
67818
68017
|
return false;
|
|
67819
68018
|
}
|
|
67820
68019
|
const kind = st2.isDirectory() ? process.platform === "win32" ? "junction" : "dir" : "file";
|
|
67821
68020
|
try {
|
|
67822
|
-
|
|
68021
|
+
fs13.symlinkSync(target, link, kind);
|
|
67823
68022
|
return true;
|
|
67824
68023
|
} catch (err2) {
|
|
67825
68024
|
const code = err2.code;
|
|
@@ -67827,18 +68026,18 @@ function linkOverlayEntry(realHome, overlay, entry) {
|
|
|
67827
68026
|
}
|
|
67828
68027
|
if (st2.isDirectory()) {
|
|
67829
68028
|
try {
|
|
67830
|
-
|
|
68029
|
+
fs13.symlinkSync(target, link, "junction");
|
|
67831
68030
|
return true;
|
|
67832
68031
|
} catch {
|
|
67833
68032
|
return false;
|
|
67834
68033
|
}
|
|
67835
68034
|
}
|
|
67836
68035
|
try {
|
|
67837
|
-
|
|
68036
|
+
fs13.linkSync(target, link);
|
|
67838
68037
|
return true;
|
|
67839
68038
|
} catch {
|
|
67840
68039
|
try {
|
|
67841
|
-
|
|
68040
|
+
fs13.copyFileSync(target, link);
|
|
67842
68041
|
return true;
|
|
67843
68042
|
} catch {
|
|
67844
68043
|
return false;
|
|
@@ -67848,7 +68047,7 @@ function linkOverlayEntry(realHome, overlay, entry) {
|
|
|
67848
68047
|
function isWriteThroughHardlink(overlayPath, realPath, st2) {
|
|
67849
68048
|
if (st2.isDirectory() || st2.isSymbolicLink() || st2.nlink <= 1) return false;
|
|
67850
68049
|
try {
|
|
67851
|
-
const realSt =
|
|
68050
|
+
const realSt = fs13.lstatSync(realPath);
|
|
67852
68051
|
return st2.dev === realSt.dev && st2.ino === realSt.ino;
|
|
67853
68052
|
} catch {
|
|
67854
68053
|
return false;
|
|
@@ -67862,7 +68061,7 @@ function freeConflictName(dst) {
|
|
|
67862
68061
|
let n = 1;
|
|
67863
68062
|
while (n < 1e5) {
|
|
67864
68063
|
try {
|
|
67865
|
-
|
|
68064
|
+
fs13.lstatSync(candidate);
|
|
67866
68065
|
candidate = `${dst}.bili-conflict.${n}`;
|
|
67867
68066
|
n += 1;
|
|
67868
68067
|
} catch {
|
|
@@ -67875,7 +68074,7 @@ function mergeSqliteSet(overlay, realHome, base) {
|
|
|
67875
68074
|
const members = sqliteSetMembers(base);
|
|
67876
68075
|
const statFile = (dir, m2) => {
|
|
67877
68076
|
try {
|
|
67878
|
-
const st2 =
|
|
68077
|
+
const st2 = fs13.lstatSync(path18.join(dir, m2));
|
|
67879
68078
|
return st2.isFile() ? st2 : void 0;
|
|
67880
68079
|
} catch {
|
|
67881
68080
|
return void 0;
|
|
@@ -67901,22 +68100,22 @@ function mergeSqliteSet(overlay, realHome, base) {
|
|
|
67901
68100
|
const movePreserving = (src, dst) => {
|
|
67902
68101
|
let dstStat;
|
|
67903
68102
|
try {
|
|
67904
|
-
dstStat =
|
|
68103
|
+
dstStat = fs13.lstatSync(dst);
|
|
67905
68104
|
} catch {
|
|
67906
68105
|
}
|
|
67907
68106
|
if (dstStat) {
|
|
67908
68107
|
if (dstStat.isDirectory()) throw new Error("target is a directory");
|
|
67909
68108
|
const conflict = freeConflictName(dst);
|
|
67910
|
-
|
|
67911
|
-
undo.push(() =>
|
|
68109
|
+
fs13.renameSync(dst, conflict);
|
|
68110
|
+
undo.push(() => fs13.renameSync(conflict, dst));
|
|
67912
68111
|
}
|
|
67913
|
-
|
|
67914
|
-
undo.push(() =>
|
|
68112
|
+
fs13.renameSync(src, dst);
|
|
68113
|
+
undo.push(() => fs13.renameSync(dst, src));
|
|
67915
68114
|
};
|
|
67916
68115
|
const preserveAsConflict = (src, name) => {
|
|
67917
68116
|
const conflict = freeConflictName(path18.join(realHome, name));
|
|
67918
|
-
|
|
67919
|
-
undo.push(() =>
|
|
68117
|
+
fs13.renameSync(src, conflict);
|
|
68118
|
+
undo.push(() => fs13.renameSync(conflict, src));
|
|
67920
68119
|
};
|
|
67921
68120
|
try {
|
|
67922
68121
|
for (const m2 of members) {
|
|
@@ -67942,7 +68141,7 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
|
|
|
67942
68141
|
const generatedFiles = new Set(Array.isArray(generatedFile) ? generatedFile : [generatedFile]);
|
|
67943
68142
|
const isGeneratedDraft = (name) => [...generatedFiles].some((g2) => name.startsWith(`.${g2}.`) && name.endsWith(".tmp"));
|
|
67944
68143
|
try {
|
|
67945
|
-
|
|
68144
|
+
fs13.mkdirSync(overlay, { recursive: true });
|
|
67946
68145
|
} catch {
|
|
67947
68146
|
return false;
|
|
67948
68147
|
}
|
|
@@ -67953,19 +68152,19 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
|
|
|
67953
68152
|
);
|
|
67954
68153
|
}
|
|
67955
68154
|
try {
|
|
67956
|
-
|
|
68155
|
+
fs13.writeFileSync(overlayLockPath(overlay), `${process.pid}
|
|
67957
68156
|
`);
|
|
67958
68157
|
} catch {
|
|
67959
68158
|
}
|
|
67960
68159
|
const realEntries = /* @__PURE__ */ new Set();
|
|
67961
68160
|
try {
|
|
67962
|
-
for (const entry of
|
|
68161
|
+
for (const entry of fs13.readdirSync(realHome)) realEntries.add(entry);
|
|
67963
68162
|
} catch {
|
|
67964
68163
|
}
|
|
67965
68164
|
try {
|
|
67966
68165
|
let overlayEntries;
|
|
67967
68166
|
try {
|
|
67968
|
-
overlayEntries =
|
|
68167
|
+
overlayEntries = fs13.readdirSync(overlay);
|
|
67969
68168
|
} catch {
|
|
67970
68169
|
overlayEntries = [];
|
|
67971
68170
|
}
|
|
@@ -67976,7 +68175,7 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
|
|
|
67976
68175
|
if (!members.some((m2) => m2 !== entry && overlayEntries.includes(m2))) continue;
|
|
67977
68176
|
let mainSt;
|
|
67978
68177
|
try {
|
|
67979
|
-
mainSt =
|
|
68178
|
+
mainSt = fs13.lstatSync(path18.join(overlay, entry));
|
|
67980
68179
|
} catch {
|
|
67981
68180
|
}
|
|
67982
68181
|
const keepSidecars = mainSt !== void 0 && isWriteThroughHardlink(path18.join(overlay, entry), path18.join(realHome, entry), mainSt);
|
|
@@ -67993,7 +68192,7 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
|
|
|
67993
68192
|
const overlayPath = path18.join(overlay, entry);
|
|
67994
68193
|
if (isGeneratedDraft(entry)) {
|
|
67995
68194
|
try {
|
|
67996
|
-
|
|
68195
|
+
fs13.unlinkSync(overlayPath);
|
|
67997
68196
|
} catch {
|
|
67998
68197
|
}
|
|
67999
68198
|
continue;
|
|
@@ -68001,20 +68200,20 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
|
|
|
68001
68200
|
if (skipEntries.has(entry)) continue;
|
|
68002
68201
|
let st2;
|
|
68003
68202
|
try {
|
|
68004
|
-
st2 =
|
|
68203
|
+
st2 = fs13.lstatSync(overlayPath);
|
|
68005
68204
|
} catch {
|
|
68006
68205
|
continue;
|
|
68007
68206
|
}
|
|
68008
68207
|
if (st2.isSymbolicLink()) {
|
|
68009
68208
|
let target;
|
|
68010
68209
|
try {
|
|
68011
|
-
target =
|
|
68210
|
+
target = fs13.readlinkSync(overlayPath);
|
|
68012
68211
|
} catch {
|
|
68013
68212
|
}
|
|
68014
68213
|
const wanted = realEntries.has(entry) ? path18.join(realHome, entry) : void 0;
|
|
68015
68214
|
if (!wanted || target !== wanted) {
|
|
68016
68215
|
try {
|
|
68017
|
-
|
|
68216
|
+
fs13.unlinkSync(overlayPath);
|
|
68018
68217
|
} catch {
|
|
68019
68218
|
}
|
|
68020
68219
|
}
|
|
@@ -68022,12 +68221,12 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
|
|
|
68022
68221
|
const realPath = path18.join(realHome, entry);
|
|
68023
68222
|
if (isWriteThroughHardlink(overlayPath, realPath, st2)) {
|
|
68024
68223
|
try {
|
|
68025
|
-
|
|
68224
|
+
fs13.unlinkSync(overlayPath);
|
|
68026
68225
|
} catch {
|
|
68027
68226
|
}
|
|
68028
68227
|
} else if (mergeOverlayEntry(overlayPath, realPath, generatedFiles)) {
|
|
68029
68228
|
try {
|
|
68030
|
-
|
|
68229
|
+
fs13.rmSync(overlayPath, { recursive: true, force: true });
|
|
68031
68230
|
} catch {
|
|
68032
68231
|
}
|
|
68033
68232
|
} else {
|
|
@@ -68052,7 +68251,7 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
|
|
|
68052
68251
|
const overlayPath = path18.join(overlay, entry);
|
|
68053
68252
|
let present = false;
|
|
68054
68253
|
try {
|
|
68055
|
-
|
|
68254
|
+
fs13.lstatSync(overlayPath);
|
|
68056
68255
|
present = true;
|
|
68057
68256
|
} catch {
|
|
68058
68257
|
}
|
|
@@ -68084,32 +68283,32 @@ function refreshOverlayHome(realHome, overlay, generatedFile) {
|
|
|
68084
68283
|
function mergeOverlayEntry(src, dst, excludedNames) {
|
|
68085
68284
|
let st2;
|
|
68086
68285
|
try {
|
|
68087
|
-
st2 =
|
|
68286
|
+
st2 = fs13.lstatSync(src);
|
|
68088
68287
|
} catch {
|
|
68089
68288
|
return true;
|
|
68090
68289
|
}
|
|
68091
68290
|
let dstStat;
|
|
68092
68291
|
try {
|
|
68093
|
-
dstStat =
|
|
68292
|
+
dstStat = fs13.lstatSync(dst);
|
|
68094
68293
|
} catch {
|
|
68095
68294
|
}
|
|
68096
68295
|
if (st2.isDirectory()) {
|
|
68097
68296
|
if (dstStat && !dstStat.isDirectory()) {
|
|
68098
68297
|
try {
|
|
68099
|
-
|
|
68298
|
+
fs13.renameSync(dst, freeConflictName(dst));
|
|
68100
68299
|
dstStat = void 0;
|
|
68101
68300
|
} catch {
|
|
68102
68301
|
return false;
|
|
68103
68302
|
}
|
|
68104
68303
|
}
|
|
68105
68304
|
try {
|
|
68106
|
-
|
|
68305
|
+
fs13.mkdirSync(dst, { recursive: true });
|
|
68107
68306
|
} catch {
|
|
68108
68307
|
return false;
|
|
68109
68308
|
}
|
|
68110
68309
|
let entries;
|
|
68111
68310
|
try {
|
|
68112
|
-
entries =
|
|
68311
|
+
entries = fs13.readdirSync(src);
|
|
68113
68312
|
} catch {
|
|
68114
68313
|
return false;
|
|
68115
68314
|
}
|
|
@@ -68122,7 +68321,7 @@ function mergeOverlayEntry(src, dst, excludedNames) {
|
|
|
68122
68321
|
}
|
|
68123
68322
|
if (dstStat && dstStat.isDirectory()) {
|
|
68124
68323
|
try {
|
|
68125
|
-
|
|
68324
|
+
fs13.renameSync(src, freeConflictName(dst));
|
|
68126
68325
|
return true;
|
|
68127
68326
|
} catch {
|
|
68128
68327
|
return false;
|
|
@@ -68131,13 +68330,13 @@ function mergeOverlayEntry(src, dst, excludedNames) {
|
|
|
68131
68330
|
if (st2.isSymbolicLink()) {
|
|
68132
68331
|
if (dstStat) {
|
|
68133
68332
|
try {
|
|
68134
|
-
|
|
68333
|
+
fs13.unlinkSync(src);
|
|
68135
68334
|
} catch {
|
|
68136
68335
|
}
|
|
68137
68336
|
return true;
|
|
68138
68337
|
}
|
|
68139
68338
|
try {
|
|
68140
|
-
|
|
68339
|
+
fs13.renameSync(src, dst);
|
|
68141
68340
|
} catch {
|
|
68142
68341
|
return false;
|
|
68143
68342
|
}
|
|
@@ -68145,7 +68344,7 @@ function mergeOverlayEntry(src, dst, excludedNames) {
|
|
|
68145
68344
|
}
|
|
68146
68345
|
if (dstStat && dstStat.mtimeMs >= st2.mtimeMs) {
|
|
68147
68346
|
try {
|
|
68148
|
-
|
|
68347
|
+
fs13.renameSync(src, freeConflictName(dst));
|
|
68149
68348
|
return true;
|
|
68150
68349
|
} catch {
|
|
68151
68350
|
return false;
|
|
@@ -68153,13 +68352,13 @@ function mergeOverlayEntry(src, dst, excludedNames) {
|
|
|
68153
68352
|
}
|
|
68154
68353
|
if (dstStat) {
|
|
68155
68354
|
try {
|
|
68156
|
-
|
|
68355
|
+
fs13.renameSync(dst, freeConflictName(dst));
|
|
68157
68356
|
} catch {
|
|
68158
68357
|
return false;
|
|
68159
68358
|
}
|
|
68160
68359
|
}
|
|
68161
68360
|
try {
|
|
68162
|
-
|
|
68361
|
+
fs13.renameSync(src, dst);
|
|
68163
68362
|
return true;
|
|
68164
68363
|
} catch {
|
|
68165
68364
|
return false;
|
|
@@ -68169,7 +68368,7 @@ function piPluginInstalled(piHome) {
|
|
|
68169
68368
|
const root = selfPackageRoot();
|
|
68170
68369
|
if (!root) return false;
|
|
68171
68370
|
try {
|
|
68172
|
-
const parsed = JSON.parse(
|
|
68371
|
+
const parsed = JSON.parse(fs13.readFileSync(path18.join(piHome, "settings.json"), "utf8"));
|
|
68173
68372
|
const list = Array.isArray(parsed.packages) ? parsed.packages.map(String) : [];
|
|
68174
68373
|
return list.some((p2) => isBiliPiEntry(p2, root));
|
|
68175
68374
|
} catch {
|
|
@@ -68179,11 +68378,11 @@ function piPluginInstalled(piHome) {
|
|
|
68179
68378
|
function writeOverlayFileAtomic(overlay, fileName, contents) {
|
|
68180
68379
|
const draft = path18.join(overlay, `.${fileName}.${process.pid}.tmp`);
|
|
68181
68380
|
try {
|
|
68182
|
-
|
|
68183
|
-
|
|
68381
|
+
fs13.writeFileSync(draft, contents);
|
|
68382
|
+
fs13.renameSync(draft, path18.join(overlay, fileName));
|
|
68184
68383
|
} catch {
|
|
68185
68384
|
try {
|
|
68186
|
-
|
|
68385
|
+
fs13.rmSync(draft, { force: true });
|
|
68187
68386
|
} catch {
|
|
68188
68387
|
}
|
|
68189
68388
|
}
|
|
@@ -68192,7 +68391,7 @@ function prepareDshHome(dshHome, origin, rewrites) {
|
|
|
68192
68391
|
const cfgPath = path18.join(dshHome, "settings.yaml");
|
|
68193
68392
|
let txt;
|
|
68194
68393
|
try {
|
|
68195
|
-
txt =
|
|
68394
|
+
txt = fs13.readFileSync(cfgPath, "utf8");
|
|
68196
68395
|
} catch {
|
|
68197
68396
|
return void 0;
|
|
68198
68397
|
}
|
|
@@ -68241,7 +68440,7 @@ env = { BILI_MCP_PROXY = ${JSON.stringify(origin)}, BILI_CONVERSATION_ID = ${JSO
|
|
|
68241
68440
|
function prepareCodexHome(codexHome, origin, conversationId2) {
|
|
68242
68441
|
let txt = "";
|
|
68243
68442
|
try {
|
|
68244
|
-
txt =
|
|
68443
|
+
txt = fs13.readFileSync(path18.join(codexHome, "config.toml"), "utf8");
|
|
68245
68444
|
} catch {
|
|
68246
68445
|
}
|
|
68247
68446
|
const overlay = `${codexHome}-bili`;
|
|
@@ -68253,7 +68452,7 @@ function writeDshAcpPatch(dshHome) {
|
|
|
68253
68452
|
const pluginUrl = pathToFileURL(selfDistFile("agent/dsh-acp.js")).href;
|
|
68254
68453
|
const dir = `${dshHome}-bili`;
|
|
68255
68454
|
try {
|
|
68256
|
-
|
|
68455
|
+
fs13.mkdirSync(dir, { recursive: true });
|
|
68257
68456
|
} catch {
|
|
68258
68457
|
return void 0;
|
|
68259
68458
|
}
|
|
@@ -68262,7 +68461,7 @@ function writeDshAcpPatch(dshHome) {
|
|
|
68262
68461
|
`);
|
|
68263
68462
|
const file = path18.join(dir, ".bili-acp.patch.yml");
|
|
68264
68463
|
try {
|
|
68265
|
-
return
|
|
68464
|
+
return fs13.existsSync(file) ? file : void 0;
|
|
68266
68465
|
} catch {
|
|
68267
68466
|
return void 0;
|
|
68268
68467
|
}
|
|
@@ -68277,7 +68476,7 @@ function prepareOpencodeHttpRewrite(configFile2, origin, httpRewrites, httpsRewr
|
|
|
68277
68476
|
if (httpRewrites.length === 0 && httpsRewrites.length === 0 && !pluginPath) return void 0;
|
|
68278
68477
|
let root = {};
|
|
68279
68478
|
try {
|
|
68280
|
-
const txt =
|
|
68479
|
+
const txt = fs13.readFileSync(configFile2, "utf8");
|
|
68281
68480
|
const parsed = JSON.parse(txt);
|
|
68282
68481
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
68283
68482
|
root = { ...parsed };
|
|
@@ -68305,9 +68504,9 @@ function prepareOpencodeHttpRewrite(configFile2, origin, httpRewrites, httpsRewr
|
|
|
68305
68504
|
if (!plugins.includes(pluginPath)) plugins.push(pluginPath);
|
|
68306
68505
|
root.plugin = plugins;
|
|
68307
68506
|
}
|
|
68308
|
-
const tmp =
|
|
68507
|
+
const tmp = fs13.mkdtempSync(path18.join(os5.tmpdir(), "bili-opencode-"));
|
|
68309
68508
|
const tmpFile = path18.join(tmp, "opencode.json");
|
|
68310
|
-
|
|
68509
|
+
fs13.writeFileSync(tmpFile, JSON.stringify(root));
|
|
68311
68510
|
return tmpFile;
|
|
68312
68511
|
}
|
|
68313
68512
|
function dedupeInOrder(list) {
|
|
@@ -68453,7 +68652,7 @@ async function ensureProxyRunning(opts, deps = {}) {
|
|
|
68453
68652
|
const script = process.argv[1];
|
|
68454
68653
|
if (!script) throw new Error("bili: cannot resolve launcher script path");
|
|
68455
68654
|
const logPath2 = path18.join(os5.tmpdir(), `bili-proxy-${port}.log`);
|
|
68456
|
-
const logFd =
|
|
68655
|
+
const logFd = fs13.openSync(logPath2, "a");
|
|
68457
68656
|
const claimMarker = () => claimStartingMarker({ token: launchToken, pid: process.pid, host: opts.host, port, startedAt: now() });
|
|
68458
68657
|
let claimed = claimMarker();
|
|
68459
68658
|
if (!claimed) {
|
|
@@ -68487,7 +68686,7 @@ async function ensureProxyRunning(opts, deps = {}) {
|
|
|
68487
68686
|
);
|
|
68488
68687
|
} finally {
|
|
68489
68688
|
try {
|
|
68490
|
-
|
|
68689
|
+
fs13.closeSync(logFd);
|
|
68491
68690
|
} catch {
|
|
68492
68691
|
}
|
|
68493
68692
|
}
|
|
@@ -68587,7 +68786,7 @@ function resolveOnPath(name, env) {
|
|
|
68587
68786
|
for (const ext of PATH_EXTS) {
|
|
68588
68787
|
const f2 = path18.join(dir, name + ext);
|
|
68589
68788
|
try {
|
|
68590
|
-
if (
|
|
68789
|
+
if (fs13.existsSync(f2) && fs13.statSync(f2).isFile()) return f2;
|
|
68591
68790
|
} catch {
|
|
68592
68791
|
}
|
|
68593
68792
|
}
|
|
@@ -68653,7 +68852,7 @@ async function runLaunch(params, deps = {}) {
|
|
|
68653
68852
|
const ompRealHome = resolveOmpHome({ ...process.env, PI_CODING_AGENT_DIR: void 0 });
|
|
68654
68853
|
if (base === "pi" && (routes.httpRewrites.length > 0 || routes.httpsRewrites.length > 0)) {
|
|
68655
68854
|
const piExt = selfDistFile("agent/pi.js");
|
|
68656
|
-
const extAvailable = piExt !== void 0 &&
|
|
68855
|
+
const extAvailable = piExt !== void 0 && fs13.existsSync(piExt) || piPluginInstalled(piRealHome);
|
|
68657
68856
|
if (!extAvailable) {
|
|
68658
68857
|
throw new Error(
|
|
68659
68858
|
"bili: pi needs provider URL rewrites but the bili extension cannot load (dist/agent/pi.js missing and the plugin is not installed in ~/.pi/agent/settings.json) \u2014 reinstall billion-context or run `bili plugin install pi`"
|
|
@@ -68662,7 +68861,7 @@ async function runLaunch(params, deps = {}) {
|
|
|
68662
68861
|
}
|
|
68663
68862
|
if (base === "omp" && routes.httpRewrites.length > 0) {
|
|
68664
68863
|
const ompExt = selfDistFile("agent/omp.js");
|
|
68665
|
-
const extAvailable = ompExt !== void 0 &&
|
|
68864
|
+
const extAvailable = ompExt !== void 0 && fs13.existsSync(ompExt) || ompPluginLoadedFrom(ompRealHome);
|
|
68666
68865
|
if (!extAvailable) {
|
|
68667
68866
|
throw new Error(
|
|
68668
68867
|
"bili: omp needs provider URL rewrites but the bili extension cannot load (dist/agent/omp.js missing and the plugin is not installed in ~/.omp/agent/config.yml) \u2014 reinstall billion-context or run `bili plugin install omp`"
|
|
@@ -68716,20 +68915,20 @@ async function runLaunch(params, deps = {}) {
|
|
|
68716
68915
|
env = buildPiEnv(origin, ca, process.env, routes.httpRewrites, routes.httpsRewrites);
|
|
68717
68916
|
delete env.PI_CODING_AGENT_DIR;
|
|
68718
68917
|
const piExt = selfDistFile("agent/pi.js");
|
|
68719
|
-
if (piExt &&
|
|
68918
|
+
if (piExt && fs13.existsSync(piExt) && !piPluginInstalled(piRealHome)) {
|
|
68720
68919
|
clientArgs = ["-e", piExt, ...clientArgs];
|
|
68721
68920
|
}
|
|
68722
68921
|
} else if (base === "omp") {
|
|
68723
68922
|
env = buildPiEnv(origin, ca, process.env, routes.httpRewrites);
|
|
68724
68923
|
delete env.PI_CODING_AGENT_DIR;
|
|
68725
68924
|
const ompExt = selfDistFile("agent/omp.js");
|
|
68726
|
-
if (ompExt &&
|
|
68925
|
+
if (ompExt && fs13.existsSync(ompExt) && !ompPluginLoadedFrom(ompRealHome)) {
|
|
68727
68926
|
clientArgs = ["-e", ompExt, ...clientArgs];
|
|
68728
68927
|
}
|
|
68729
68928
|
} else if (base === "opencode") {
|
|
68730
68929
|
env = { ...process.env, HTTPS_PROXY: origin, NODE_EXTRA_CA_CERTS: ca, BILLION_CONTEXT_PROXY: origin };
|
|
68731
68930
|
const opencodePlugin = selfDistFile("agent/opencode.js");
|
|
68732
|
-
const opencodePluginPath = opencodePlugin &&
|
|
68931
|
+
const opencodePluginPath = opencodePlugin && fs13.existsSync(opencodePlugin) ? opencodePlugin : void 0;
|
|
68733
68932
|
opencodeTmpFile = prepareOpencodeHttpRewrite(resolveOpencodeConfigFile(process.env), origin, routes.httpRewrites, routes.httpsRewrites, opencodePluginPath);
|
|
68734
68933
|
if (opencodeTmpFile) env.OPENCODE_CONFIG = opencodeTmpFile;
|
|
68735
68934
|
} else if (base === "hermes") {
|
|
@@ -68866,7 +69065,7 @@ async function runLaunch(params, deps = {}) {
|
|
|
68866
69065
|
}
|
|
68867
69066
|
if (injectMcp) {
|
|
68868
69067
|
const mcpFile = path18.join(os5.tmpdir(), `bili-mcp-${Date.now()}.json`);
|
|
68869
|
-
|
|
69068
|
+
fs13.writeFileSync(mcpFile, JSON.stringify(buildMcpConfig(origin)));
|
|
68870
69069
|
tmpFiles.push(mcpFile);
|
|
68871
69070
|
clientArgs = ["--mcp-config", mcpFile, ...clientArgs];
|
|
68872
69071
|
}
|
|
@@ -68885,13 +69084,13 @@ async function runLaunch(params, deps = {}) {
|
|
|
68885
69084
|
stopProxy(handle2);
|
|
68886
69085
|
if (opencodeTmpFile) {
|
|
68887
69086
|
try {
|
|
68888
|
-
|
|
69087
|
+
fs13.rmSync(path18.dirname(opencodeTmpFile), { recursive: true, force: true });
|
|
68889
69088
|
} catch {
|
|
68890
69089
|
}
|
|
68891
69090
|
}
|
|
68892
69091
|
for (const f2 of tmpFiles) {
|
|
68893
69092
|
try {
|
|
68894
|
-
|
|
69093
|
+
fs13.rmSync(f2, { force: true });
|
|
68895
69094
|
} catch {
|
|
68896
69095
|
}
|
|
68897
69096
|
}
|
|
@@ -68918,7 +69117,7 @@ async function runTestPi(params, deps = {}) {
|
|
|
68918
69117
|
const ca = resolveCaCertPath(process.env);
|
|
68919
69118
|
const env = buildPiEnv(handle2.origin, ca, process.env);
|
|
68920
69119
|
const sessionDir = path18.join(os5.tmpdir(), `bili-pi-test-${Date.now()}`);
|
|
68921
|
-
|
|
69120
|
+
fs13.mkdirSync(sessionDir, { recursive: true });
|
|
68922
69121
|
const args = [
|
|
68923
69122
|
"-p",
|
|
68924
69123
|
"--no-session",
|