billion-context 0.1.97 → 0.1.98-pr.665.492
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 +181 -37
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +38 -13
- package/dist/mcp.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -48726,6 +48726,7 @@ function mergeCompress(global2, provider, model) {
|
|
|
48726
48726
|
const promptLevels = [global2?.prompts, provider?.prompts, model?.prompts].filter(Boolean);
|
|
48727
48727
|
const rangeOf = (s3) => s3?.minCompressRangeChars ?? s3?.minCompressRange;
|
|
48728
48728
|
const absorbLevels = [global2?.absorb, provider?.absorb, model?.absorb].filter(Boolean);
|
|
48729
|
+
const reasoningLevels = [global2?.reasoning, provider?.reasoning, model?.reasoning].filter(Boolean);
|
|
48729
48730
|
return {
|
|
48730
48731
|
modelContextLimit: pick("modelContextLimit"),
|
|
48731
48732
|
maxContextLimit: pick("maxContextLimit"),
|
|
@@ -48739,7 +48740,11 @@ function mergeCompress(global2, provider, model) {
|
|
|
48739
48740
|
acknowledgePromptsRisk: pick("acknowledgePromptsRisk"),
|
|
48740
48741
|
absorb: absorbLevels.length > 0 ? Object.assign({}, ...absorbLevels) : void 0,
|
|
48741
48742
|
stripImages: pick("stripImages"),
|
|
48742
|
-
stripImagesKeepRecent: pick("stripImagesKeepRecent")
|
|
48743
|
+
stripImagesKeepRecent: pick("stripImagesKeepRecent"),
|
|
48744
|
+
// `reasoning` is a third nested-object field merged sub-field-wise
|
|
48745
|
+
// exactly like `absorb`/`prompts`: a model-level `threshold` must not
|
|
48746
|
+
// discard a provider-level `drop: false`.
|
|
48747
|
+
reasoning: reasoningLevels.length > 0 ? Object.assign({}, ...reasoningLevels) : void 0
|
|
48743
48748
|
};
|
|
48744
48749
|
}
|
|
48745
48750
|
function resolveCompress(routes, upstreamUrl, model, global2) {
|
|
@@ -48819,6 +48824,53 @@ function resolveRequestConfig(base, routes, embeddedUrl, model, native, globalCo
|
|
|
48819
48824
|
return applyCompressSettings(base, limit, compress);
|
|
48820
48825
|
}
|
|
48821
48826
|
|
|
48827
|
+
// src/reasoning-drop.ts
|
|
48828
|
+
var DEFAULT_COMPRESS_REASONING = { drop: true, threshold: 2048 };
|
|
48829
|
+
function resolveReasoningDrop(cfg) {
|
|
48830
|
+
let threshold = DEFAULT_COMPRESS_REASONING.threshold;
|
|
48831
|
+
if (cfg?.threshold !== void 0) {
|
|
48832
|
+
const t = cfg.threshold;
|
|
48833
|
+
if (typeof t === "number" && Number.isFinite(t) && t >= 0) {
|
|
48834
|
+
threshold = Math.floor(t);
|
|
48835
|
+
}
|
|
48836
|
+
}
|
|
48837
|
+
return { drop: cfg?.drop !== false, threshold };
|
|
48838
|
+
}
|
|
48839
|
+
function dropCompressReasoning(messages, cfg) {
|
|
48840
|
+
const { drop, threshold } = resolveReasoningDrop(cfg);
|
|
48841
|
+
if (!drop || messages.length === 0) return messages;
|
|
48842
|
+
try {
|
|
48843
|
+
const last = messages.length - 1;
|
|
48844
|
+
const resultAt = /* @__PURE__ */ new Map();
|
|
48845
|
+
for (let i = 0; i <= last; i++) {
|
|
48846
|
+
const m2 = messages[i];
|
|
48847
|
+
if (m2.contentType === "tool-result" && typeof m2.toolCallId === "string" && !resultAt.has(m2.toolCallId)) {
|
|
48848
|
+
resultAt.set(m2.toolCallId, i);
|
|
48849
|
+
}
|
|
48850
|
+
}
|
|
48851
|
+
const dropIdx = /* @__PURE__ */ new Set();
|
|
48852
|
+
for (let i = 0; i <= last; i++) {
|
|
48853
|
+
const m2 = messages[i];
|
|
48854
|
+
if (m2.contentType !== "tool-call" || m2.toolName !== "compress") continue;
|
|
48855
|
+
const ri2 = typeof m2.toolCallId === "string" ? resultAt.get(m2.toolCallId) : void 0;
|
|
48856
|
+
if (ri2 === void 0 || ri2 <= i || ri2 >= last) continue;
|
|
48857
|
+
let total = 0;
|
|
48858
|
+
let j2 = i - 1;
|
|
48859
|
+
while (j2 >= 0 && messages[j2].contentType === "reasoning") {
|
|
48860
|
+
total += (messages[j2].text ?? "").length;
|
|
48861
|
+
j2--;
|
|
48862
|
+
}
|
|
48863
|
+
if (total > threshold) {
|
|
48864
|
+
for (let k2 = j2 + 1; k2 < i; k2++) dropIdx.add(k2);
|
|
48865
|
+
}
|
|
48866
|
+
}
|
|
48867
|
+
if (dropIdx.size === 0) return messages;
|
|
48868
|
+
return messages.filter((_2, idx) => !dropIdx.has(idx));
|
|
48869
|
+
} catch {
|
|
48870
|
+
return messages;
|
|
48871
|
+
}
|
|
48872
|
+
}
|
|
48873
|
+
|
|
48822
48874
|
// src/strip-images.ts
|
|
48823
48875
|
var DEFAULT_STRIP_IMAGES_KEEP_RECENT = 5;
|
|
48824
48876
|
var IMAGE_PLACEHOLDER = "[image]";
|
|
@@ -51880,16 +51932,41 @@ function splitChunks(messages, startIdx, endIdx, budget, minUnits, countText = d
|
|
|
51880
51932
|
}
|
|
51881
51933
|
return chunks;
|
|
51882
51934
|
}
|
|
51883
|
-
function summaryPayload(protocol, model, system, content, stream2) {
|
|
51935
|
+
function summaryPayload(protocol, model, system, content, stream2, includeMaxOutputTokens) {
|
|
51884
51936
|
if (protocol === "anthropic") {
|
|
51885
51937
|
return { model, max_tokens: MAX_SUMMARY_OUTPUT_TOKENS, system, messages: [{ role: "user", content }], stream: stream2 };
|
|
51886
51938
|
}
|
|
51887
51939
|
if (protocol === "openai") {
|
|
51888
51940
|
return { model, max_tokens: MAX_SUMMARY_OUTPUT_TOKENS, messages: [{ role: "system", content: system }, { role: "user", content }], stream: stream2 };
|
|
51889
51941
|
}
|
|
51890
|
-
|
|
51942
|
+
const payload = { model, instructions: system, input: [{ role: "user", content }], stream: stream2, store: false };
|
|
51943
|
+
if (includeMaxOutputTokens) payload.max_output_tokens = MAX_SUMMARY_OUTPUT_TOKENS;
|
|
51944
|
+
return payload;
|
|
51891
51945
|
}
|
|
51892
51946
|
var STREAM_REQUIRED_RE = /\bstream\b[^\n]{0,60}\btrue\b/i;
|
|
51947
|
+
var MAX_OUTPUT_TOKENS_REJECTED_RE = /\bmax_output_tokens\b/i;
|
|
51948
|
+
function noMaxOutputTokensKey(deps) {
|
|
51949
|
+
return `${deps.url}\0${deps.model}`;
|
|
51950
|
+
}
|
|
51951
|
+
function hasLearnedNoMaxOutputTokens(deps) {
|
|
51952
|
+
const learned = deps.session.metadata.preflightNoMaxOutputTokens;
|
|
51953
|
+
return typeof learned === "object" && learned !== null && learned[noMaxOutputTokensKey(deps)] === true;
|
|
51954
|
+
}
|
|
51955
|
+
function rememberNoMaxOutputTokens(deps) {
|
|
51956
|
+
const learned = deps.session.metadata.preflightNoMaxOutputTokens;
|
|
51957
|
+
const map = typeof learned === "object" && learned !== null ? learned : {};
|
|
51958
|
+
map[noMaxOutputTokensKey(deps)] = true;
|
|
51959
|
+
deps.session.metadata.preflightNoMaxOutputTokens = map;
|
|
51960
|
+
}
|
|
51961
|
+
var SUMMARY_STRIP_HEADERS = /* @__PURE__ */ new Set(["x-openai-internal-codex-responses-lite"]);
|
|
51962
|
+
function summaryHeaders(deps) {
|
|
51963
|
+
const headers = {};
|
|
51964
|
+
for (const [k2, v2] of Object.entries(deps.headers)) {
|
|
51965
|
+
if (SUMMARY_STRIP_HEADERS.has(k2.toLowerCase())) continue;
|
|
51966
|
+
headers[k2] = v2;
|
|
51967
|
+
}
|
|
51968
|
+
return headers;
|
|
51969
|
+
}
|
|
51893
51970
|
function extractSummaryFromSse(protocol, text) {
|
|
51894
51971
|
let out = "";
|
|
51895
51972
|
for (const line of text.split("\n")) {
|
|
@@ -51953,25 +52030,39 @@ async function summarizeRange(deps, content, startRef, endRef) {
|
|
|
51953
52030
|
const system = buildCompressSystemPrompt(deps.prompts) + `
|
|
51954
52031
|
|
|
51955
52032
|
TASK: The conversation segment below (messages ${startRef}\u2013${endRef}) must be compressed because the session context exceeds the current model's window. Write a tier-1 compression summary of the segment following every rule above. Output ONLY the summary text \u2014 no preamble, no closing remarks, no tool calls.`;
|
|
51956
|
-
|
|
51957
|
-
|
|
51958
|
-
|
|
51959
|
-
|
|
51960
|
-
|
|
51961
|
-
|
|
51962
|
-
|
|
51963
|
-
|
|
52033
|
+
let stream2 = deps.session.metadata.preflightStreamSummary === true;
|
|
52034
|
+
let includeMaxOutputTokens = !(deps.protocol === "responses" && hasLearnedNoMaxOutputTokens(deps));
|
|
52035
|
+
for (; ; ) {
|
|
52036
|
+
try {
|
|
52037
|
+
return await requestSummary(deps, system, content, stream2, includeMaxOutputTokens);
|
|
52038
|
+
} catch (err2) {
|
|
52039
|
+
if (err2 instanceof UpstreamHttpError && err2.status === 400) {
|
|
52040
|
+
let adapted = false;
|
|
52041
|
+
if (!stream2 && STREAM_REQUIRED_RE.test(err2.body)) {
|
|
52042
|
+
deps.session.metadata.preflightStreamSummary = true;
|
|
52043
|
+
stream2 = true;
|
|
52044
|
+
adapted = true;
|
|
52045
|
+
deps.log("info", "[preflight] upstream requires stream for summaries; retrying with SSE (learned for this session)");
|
|
52046
|
+
}
|
|
52047
|
+
if (deps.protocol === "responses" && includeMaxOutputTokens && MAX_OUTPUT_TOKENS_REJECTED_RE.test(err2.body)) {
|
|
52048
|
+
rememberNoMaxOutputTokens(deps);
|
|
52049
|
+
includeMaxOutputTokens = false;
|
|
52050
|
+
adapted = true;
|
|
52051
|
+
deps.log("info", `[preflight] upstream rejects max_output_tokens for summaries (model=${deps.model}); retrying without it (learned for this session+upstream+model)`);
|
|
52052
|
+
}
|
|
52053
|
+
if (adapted) continue;
|
|
52054
|
+
}
|
|
52055
|
+
throw err2;
|
|
51964
52056
|
}
|
|
51965
|
-
throw err2;
|
|
51966
52057
|
}
|
|
51967
52058
|
}
|
|
51968
|
-
async function requestSummary(deps, system, content, stream2) {
|
|
52059
|
+
async function requestSummary(deps, system, content, stream2, includeMaxOutputTokens) {
|
|
51969
52060
|
const { response, clearTimer } = await fetchWithRetry(
|
|
51970
52061
|
deps.url,
|
|
51971
52062
|
{
|
|
51972
52063
|
method: "POST",
|
|
51973
|
-
headers: { "content-type": "application/json", ...deps
|
|
51974
|
-
body: JSON.stringify(summaryPayload(deps.protocol, deps.model, system, content, stream2)),
|
|
52064
|
+
headers: { "content-type": "application/json", ...summaryHeaders(deps) },
|
|
52065
|
+
body: JSON.stringify(summaryPayload(deps.protocol, deps.model, system, content, stream2, includeMaxOutputTokens)),
|
|
51975
52066
|
dispatcher: proxyDispatcher(deps.proxyUrl)
|
|
51976
52067
|
},
|
|
51977
52068
|
void 0,
|
|
@@ -56255,15 +56346,28 @@ function handlePluginManifest(res) {
|
|
|
56255
56346
|
statusEndpoint: "/__bili/plugin/status"
|
|
56256
56347
|
}));
|
|
56257
56348
|
}
|
|
56349
|
+
function conversationIdForSession(sessionId) {
|
|
56350
|
+
let bestId;
|
|
56351
|
+
let bestSeen = -Infinity;
|
|
56352
|
+
for (const [cid, entry] of conversations) {
|
|
56353
|
+
if (entry.sessionId === sessionId && entry.lastSeen > bestSeen) {
|
|
56354
|
+
bestId = cid;
|
|
56355
|
+
bestSeen = entry.lastSeen;
|
|
56356
|
+
}
|
|
56357
|
+
}
|
|
56358
|
+
return bestId;
|
|
56359
|
+
}
|
|
56258
56360
|
function handlePluginStatus(conversationId2, res, deps, fallbackLatest = false) {
|
|
56259
56361
|
let entry = conversations.get(conversationId2);
|
|
56260
56362
|
let session = entry ? peekSession(entry.sessionId) : void 0;
|
|
56261
56363
|
let viaFallback = false;
|
|
56364
|
+
let resolvedConversationId = conversationId2;
|
|
56262
56365
|
if ((!entry || !session) && fallbackLatest) {
|
|
56263
56366
|
const latest = listSessions().filter((s3) => s3.restored !== true).sort((a, b2) => (b2.lastSeen ?? 0) - (a.lastSeen ?? 0))[0];
|
|
56264
56367
|
if (latest) {
|
|
56265
56368
|
session = latest;
|
|
56266
56369
|
viaFallback = true;
|
|
56370
|
+
resolvedConversationId = conversationIdForSession(latest.id) ?? conversationId2;
|
|
56267
56371
|
} else {
|
|
56268
56372
|
res.writeHead(404, { "content-type": "application/json" });
|
|
56269
56373
|
res.end(JSON.stringify({ ok: false, error: "no session with activity since boot \u2014 issue a model request or pass the conversation id" }));
|
|
@@ -56313,7 +56417,7 @@ function handlePluginStatus(conversationId2, res, deps, fallbackLatest = false)
|
|
|
56313
56417
|
res.writeHead(200, { "content-type": "application/json" });
|
|
56314
56418
|
res.end(JSON.stringify({
|
|
56315
56419
|
ok: true,
|
|
56316
|
-
conversationId:
|
|
56420
|
+
conversationId: resolvedConversationId,
|
|
56317
56421
|
fallback: viaFallback || void 0,
|
|
56318
56422
|
label: session.meta.label ?? null,
|
|
56319
56423
|
pluginAgent: session.metadata.pluginAgent ?? null,
|
|
@@ -56348,8 +56452,12 @@ async function handlePluginTool(payload, res, deps) {
|
|
|
56348
56452
|
const entry = conversations.get(conversationId2);
|
|
56349
56453
|
const session = entry ? peekSession(entry.sessionId) : void 0;
|
|
56350
56454
|
if (!entry || !session) {
|
|
56455
|
+
deps.log("warn", `[plugin] tool "${tool}" rejected for conversation ${conversationId2}: ${entry ? "id registered but session not resident in this proxy instance" : "id never registered (stale shim session id after host resume?)"}`);
|
|
56351
56456
|
res.writeHead(404, { "content-type": "application/json" });
|
|
56352
|
-
res.end(JSON.stringify({
|
|
56457
|
+
res.end(JSON.stringify({
|
|
56458
|
+
ok: false,
|
|
56459
|
+
error: !entry ? "unknown plugin conversation (no model request has arrived with this conversation id yet)" : "unknown plugin conversation (id registered but its session is not resident in this proxy instance \u2014 a fresh model request re-binds it)"
|
|
56460
|
+
}));
|
|
56353
56461
|
return;
|
|
56354
56462
|
}
|
|
56355
56463
|
if (!isProxyToolFor(tool, session, deps.config)) {
|
|
@@ -59214,13 +59322,14 @@ ${bodyBuffer.toString("utf8")}`);
|
|
|
59214
59322
|
await withSessionLock(session, async () => {
|
|
59215
59323
|
const runPrepare = () => {
|
|
59216
59324
|
const cs2 = resolveCompress(opts.routes, route?.rewrittenUrl, parsed.model, opts.compress);
|
|
59325
|
+
const reasoningCfg = cs2.reasoning;
|
|
59217
59326
|
const keepRecent = cs2.stripImagesKeepRecent ?? DEFAULT_STRIP_IMAGES_KEEP_RECENT;
|
|
59218
59327
|
const stripped = cs2.stripImages ? stripHistoricalImages(parsed, protocol, keepRecent) : { body: parsed, removed: 0 };
|
|
59219
59328
|
if (opts.debug && stripped.removed > 0) {
|
|
59220
59329
|
log2("info", `[debug] strip-images: dropped ${stripped.removed} historical image part(s), kept last ${keepRecent} (session=${session.id})`);
|
|
59221
59330
|
}
|
|
59222
59331
|
const work = stripped.body;
|
|
59223
|
-
return countTokens ? prepareCountTokens(work, core, reqConfig, log2, session) : protocol === "anthropic" ? prepareAnthropic(work, req, opts, core, reqConfig, reqPrompts, log2, session, pluginMode) : protocol === "openai" ? prepareOpenai(work, req, opts, core, reqConfig, reqPrompts, log2, session, pluginMode, nativeWindow) : responsesCompact ? prepareResponsesCompact(stripped.removed > 0 ? Buffer.from(JSON.stringify(work)) : bodyBuffer, work, session, req, core, reqConfig, log2) : prepareResponses(work, req, opts, core, reqConfig, reqPrompts, log2, session, responsesIdentity, pluginMode, upstreamOrigin, nativeWindow);
|
|
59332
|
+
return countTokens ? prepareCountTokens(work, core, reqConfig, log2, session) : protocol === "anthropic" ? prepareAnthropic(work, req, opts, core, reqConfig, reqPrompts, log2, session, pluginMode, reasoningCfg) : protocol === "openai" ? prepareOpenai(work, req, opts, core, reqConfig, reqPrompts, log2, session, pluginMode, nativeWindow, reasoningCfg) : responsesCompact ? prepareResponsesCompact(stripped.removed > 0 ? Buffer.from(JSON.stringify(work)) : bodyBuffer, work, session, req, core, reqConfig, log2) : prepareResponses(work, req, opts, core, reqConfig, reqPrompts, log2, session, responsesIdentity, pluginMode, upstreamOrigin, nativeWindow, reasoningCfg);
|
|
59224
59333
|
};
|
|
59225
59334
|
const isCodexCompactTrigger = protocol === "responses" && !responsesCompact && isCodexClient(req.headers) && hasCompactionTrigger(parsed.input);
|
|
59226
59335
|
if (isCodexCompactTrigger) {
|
|
@@ -59308,6 +59417,13 @@ ${bodyBuffer.toString("utf8")}`);
|
|
|
59308
59417
|
}
|
|
59309
59418
|
}
|
|
59310
59419
|
var ACP_TAG_MARK = "<acp ";
|
|
59420
|
+
function withReasoningDrop(msgs, reasoning, log2, sessionId) {
|
|
59421
|
+
const out = dropCompressReasoning(msgs, reasoning);
|
|
59422
|
+
if (out.length !== msgs.length) {
|
|
59423
|
+
log2("info", `[${sessionId}] compress-reasoning: dropped ${msgs.length - out.length} reasoning message(s) from closed compress turns (#651)`);
|
|
59424
|
+
}
|
|
59425
|
+
return out;
|
|
59426
|
+
}
|
|
59311
59427
|
function stripKernelSummaries(messages, state) {
|
|
59312
59428
|
const carried = /* @__PURE__ */ new Set();
|
|
59313
59429
|
for (const b2 of state.blocks) {
|
|
@@ -59409,12 +59525,13 @@ function effectiveTokenCount(session, msgs) {
|
|
|
59409
59525
|
if (!session.metadata.anonymousPrefixAffinity) return 0;
|
|
59410
59526
|
return estimateCoreMessagesUpper(msgs);
|
|
59411
59527
|
}
|
|
59412
|
-
function prepareAnthropic(parsed, req, opts, core, config, prompts, log2, session, pluginMode) {
|
|
59528
|
+
function prepareAnthropic(parsed, req, opts, core, config, prompts, log2, session, pluginMode, reasoning) {
|
|
59413
59529
|
const sessionId = session.id;
|
|
59414
59530
|
const stream2 = parsed.stream === true;
|
|
59415
59531
|
++session.stats.requests;
|
|
59416
59532
|
session.hostCreditTokens = 0;
|
|
59417
59533
|
const injectTools = opts.compress.injectTool && !pluginMode;
|
|
59534
|
+
const stripReasoning = (msgs) => withReasoningDrop(msgs, reasoning, log2, sessionId);
|
|
59418
59535
|
if (isAutoModeClassifier(parsed)) {
|
|
59419
59536
|
log2("info", `[${sessionId}] auto-mode classifier passthrough (skipping compress injection)`);
|
|
59420
59537
|
return { body: JSON.stringify(parsed), session, processedMessages: [], originalMessages: [], anthropicSystem: parsed.system, protocol: "anthropic", stream: stream2, compressInjected: false, pluginMode, nudge: void 0, prompts };
|
|
@@ -59452,7 +59569,7 @@ function prepareAnthropic(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
59452
59569
|
log2("info", diagTagSummary(turn.messages, sessionId, "text-only"));
|
|
59453
59570
|
const willInjectNudge = opts.compress.injectNudge && !!turn.nudge && (turn.nudge.shouldInject || emergencyNudge(turn.nudge));
|
|
59454
59571
|
log2("info", diagNudge(turn, sessionId, tokenCount, config.modelContextLimit, parsed.model, willInjectNudge));
|
|
59455
|
-
processedMessages = stripKernelSummaries(turn.messages, turn.state);
|
|
59572
|
+
processedMessages = stripReasoning(stripKernelSummaries(turn.messages, turn.state));
|
|
59456
59573
|
applyCompactionArchive(session, activeBefore, new Set(msgs.map((m2) => m2.id)), log2);
|
|
59457
59574
|
reapOrphanBlocks(session, msgs, deactivateBlock);
|
|
59458
59575
|
rebuiltMessages = coreToAnthropic(processedMessages, cacheControls);
|
|
@@ -59534,12 +59651,13 @@ function clampOutgoingOutput(rebuilt, field, ctx, sessionId, log2) {
|
|
|
59534
59651
|
log2("info", `[${sessionId}] output budget clamped ${raw} -> ${capped} (input~${inputEstimate}, window=${ctx.nativeWindow}); prevents input+output overflow (#453)`);
|
|
59535
59652
|
}
|
|
59536
59653
|
}
|
|
59537
|
-
function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session, pluginMode, nativeWindow) {
|
|
59654
|
+
function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session, pluginMode, nativeWindow, reasoning) {
|
|
59538
59655
|
const sessionId = session.id;
|
|
59539
59656
|
const stream2 = parsed.stream === true;
|
|
59540
59657
|
++session.stats.requests;
|
|
59541
59658
|
session.hostCreditTokens = 0;
|
|
59542
59659
|
let openaiSystemText = "";
|
|
59660
|
+
const stripReasoning = (msgs) => withReasoningDrop(msgs, reasoning, log2, sessionId);
|
|
59543
59661
|
let openaiOutboundSystem;
|
|
59544
59662
|
let processedMessages = [];
|
|
59545
59663
|
let originalMessages = [];
|
|
@@ -59577,7 +59695,7 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session,
|
|
|
59577
59695
|
log2("info", diagTagSummary(turn.messages, sessionId, "text-only"));
|
|
59578
59696
|
const willInjectNudge = opts.compress.injectNudge && !!turn.nudge && shouldInject && (turn.nudge.shouldInject || emergencyNudge(turn.nudge));
|
|
59579
59697
|
log2("info", diagNudge(turn, sessionId, tokenCount, config.modelContextLimit, parsed.model, willInjectNudge));
|
|
59580
|
-
processedMessages = stripKernelSummaries(turn.messages, turn.state);
|
|
59698
|
+
processedMessages = stripReasoning(stripKernelSummaries(turn.messages, turn.state));
|
|
59581
59699
|
applyCompactionArchive(session, activeBefore, new Set(msgs.map((m2) => m2.id)), log2);
|
|
59582
59700
|
reapOrphanBlocks(session, msgs, deactivateBlock);
|
|
59583
59701
|
rebuiltMessages = systemToUser(coreToOpenai(processedMessages));
|
|
@@ -59617,11 +59735,12 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session,
|
|
|
59617
59735
|
markDirty(session);
|
|
59618
59736
|
return { body: JSON.stringify(rebuilt), session, processedMessages, originalMessages, protocol: "openai", stream: stream2, compressInjected: injectTools, pluginMode, nudge, prompts, openaiSystemText, renderTags: "text-only" };
|
|
59619
59737
|
}
|
|
59620
|
-
function prepareResponses(parsed, req, opts, core, config, prompts, log2, session, identity, pluginMode, upstreamOrigin, nativeWindow) {
|
|
59738
|
+
function prepareResponses(parsed, req, opts, core, config, prompts, log2, session, identity, pluginMode, upstreamOrigin, nativeWindow, reasoning) {
|
|
59621
59739
|
const sessionId = session.id;
|
|
59622
59740
|
const stream2 = parsed.stream === true;
|
|
59623
59741
|
++session.stats.requests;
|
|
59624
59742
|
session.hostCreditTokens = 0;
|
|
59743
|
+
const stripReasoning = (msgs) => withReasoningDrop(msgs, reasoning, log2, sessionId);
|
|
59625
59744
|
if (reconcileNativeCompactionBoundary(session)) {
|
|
59626
59745
|
log2("info", `[${sessionId}] reconciled ACP state after native Responses compact boundary`);
|
|
59627
59746
|
}
|
|
@@ -59686,7 +59805,7 @@ function prepareResponses(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
59686
59805
|
log2("info", diagTagSummary(turn.messages, sessionId, "text-only"));
|
|
59687
59806
|
const willInjectNudge = opts.compress.injectNudge && !!turn.nudge && shouldInject && !isCompactionTrigger && (turn.nudge.shouldInject || emergencyNudge(turn.nudge));
|
|
59688
59807
|
log2("info", diagNudge(turn, sessionId, tokenCount, config.modelContextLimit, parsed.model, willInjectNudge));
|
|
59689
|
-
processedMessages = repairResponsesAssistantOrdering(stripKernelSummaries(turn.messages, turn.state), originalMessages);
|
|
59808
|
+
processedMessages = repairResponsesAssistantOrdering(stripReasoning(stripKernelSummaries(turn.messages, turn.state)), originalMessages);
|
|
59690
59809
|
reapOrphanBlocks(session, msgs, deactivateBlock);
|
|
59691
59810
|
rebuiltInput = patchResponsesInput(projection, processedMessages);
|
|
59692
59811
|
const forgedSummaries = echoReplaced ? [] : session.metadata.codexForgedSummaries ?? [];
|
|
@@ -64321,6 +64440,7 @@ function resolveProxyOrigin() {
|
|
|
64321
64440
|
var TOOL_TIMEOUT_MS = 6e4;
|
|
64322
64441
|
var CONVERSATION_FROM_ENV = process.env.CLAUDE_CODE_SESSION_ID?.trim() || process.env.BILI_CONVERSATION_ID?.trim() || void 0;
|
|
64323
64442
|
var IDENTITY_BINDING = Boolean(process.env.CLAUDE_CODE_SESSION_ID?.trim());
|
|
64443
|
+
var ORPHAN_ADOPT = IDENTITY_BINDING && process.env.BILI_MCP_NO_ORPHAN_ADOPT !== "1";
|
|
64324
64444
|
var manifestTools = [];
|
|
64325
64445
|
var conversationId = CONVERSATION_FROM_ENV;
|
|
64326
64446
|
var registered = false;
|
|
@@ -64353,21 +64473,45 @@ function ensureManifest() {
|
|
|
64353
64473
|
return manifestPromise;
|
|
64354
64474
|
}
|
|
64355
64475
|
async function forwardTool(tool, args, timeoutMs = TOOL_TIMEOUT_MS) {
|
|
64356
|
-
let
|
|
64476
|
+
for (let attempt = 0; ; attempt++) {
|
|
64477
|
+
let res;
|
|
64478
|
+
try {
|
|
64479
|
+
res = await fetch(`${resolveProxyOrigin()}/__bili/plugin/tool`, {
|
|
64480
|
+
method: "POST",
|
|
64481
|
+
headers: { "content-type": "application/json" },
|
|
64482
|
+
body: JSON.stringify({ conversationId, tool, args }),
|
|
64483
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
64484
|
+
});
|
|
64485
|
+
} catch (err2) {
|
|
64486
|
+
if (err2 instanceof Error && err2.name === "TimeoutError") throw new Error(`tool forward timed out after ${timeoutMs}ms: ${tool}`);
|
|
64487
|
+
throw err2;
|
|
64488
|
+
}
|
|
64489
|
+
const data = await res.json();
|
|
64490
|
+
if (res.ok && data.ok) return data.result ?? "";
|
|
64491
|
+
if (res.status === 404 && attempt === 0 && ORPHAN_ADOPT && conversationId && typeof data.error === "string" && data.error.includes("no model request has arrived")) {
|
|
64492
|
+
if (await adoptLatestActiveConversation()) continue;
|
|
64493
|
+
}
|
|
64494
|
+
throw new Error(data.error ?? `tool forward failed: ${res.status}`);
|
|
64495
|
+
}
|
|
64496
|
+
}
|
|
64497
|
+
async function adoptLatestActiveConversation() {
|
|
64357
64498
|
try {
|
|
64358
|
-
res = await fetch(
|
|
64359
|
-
|
|
64360
|
-
|
|
64361
|
-
|
|
64362
|
-
|
|
64363
|
-
|
|
64364
|
-
|
|
64365
|
-
|
|
64366
|
-
|
|
64499
|
+
const res = await fetch(
|
|
64500
|
+
`${resolveProxyOrigin()}/__bili/plugin/status?conversationId=${encodeURIComponent(conversationId ?? "")}&fallback=latest`,
|
|
64501
|
+
{ signal: AbortSignal.timeout(5e3) }
|
|
64502
|
+
);
|
|
64503
|
+
if (!res.ok) return false;
|
|
64504
|
+
const data = await res.json();
|
|
64505
|
+
if (data.ok !== true || data.fallback !== true || !data.conversationId || data.conversationId === conversationId) return false;
|
|
64506
|
+
process.stderr.write(
|
|
64507
|
+
`[bili-mcp] conversation id no longer known by the proxy (host resumed its session?); adopting latest active conversation ${data.conversationId}
|
|
64508
|
+
`
|
|
64509
|
+
);
|
|
64510
|
+
conversationId = data.conversationId;
|
|
64511
|
+
return true;
|
|
64512
|
+
} catch {
|
|
64513
|
+
return false;
|
|
64367
64514
|
}
|
|
64368
|
-
const data = await res.json();
|
|
64369
|
-
if (!res.ok || !data.ok) throw new Error(data.error ?? `tool forward failed: ${res.status}`);
|
|
64370
|
-
return data.result ?? "";
|
|
64371
64515
|
}
|
|
64372
64516
|
var ERR_TOOL = -32602;
|
|
64373
64517
|
async function handleMessage(msg) {
|