billion-context 0.1.56 → 0.1.57-pr.261.129
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/omp.js +14 -1
- package/dist/agent/omp.js.map +1 -1
- package/dist/agent/pi.js +14 -1
- package/dist/agent/pi.js.map +1 -1
- package/dist/index.js +353 -40
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -43649,7 +43649,7 @@ function formatRanges(compressible, protectedRanges) {
|
|
|
43649
43649
|
if (compressible.length === 0 && protectedRanges.length === 0) {
|
|
43650
43650
|
return "[No specific ranges detected \u2014 compress any consumed content.]";
|
|
43651
43651
|
}
|
|
43652
|
-
const
|
|
43652
|
+
const refNum3 = (ref) => {
|
|
43653
43653
|
const m2 = ref.match(/\d+/);
|
|
43654
43654
|
return m2 ? parseInt(m2[0], 10) : 0;
|
|
43655
43655
|
};
|
|
@@ -43658,8 +43658,8 @@ function formatRanges(compressible, protectedRanges) {
|
|
|
43658
43658
|
entries.push({
|
|
43659
43659
|
startRef: r.startRef,
|
|
43660
43660
|
endRef: r.endRef,
|
|
43661
|
-
startNum:
|
|
43662
|
-
endNum:
|
|
43661
|
+
startNum: refNum3(r.startRef),
|
|
43662
|
+
endNum: refNum3(r.endRef),
|
|
43663
43663
|
count: r.count,
|
|
43664
43664
|
tokens: r.tokens,
|
|
43665
43665
|
toolPct: r.toolPct,
|
|
@@ -43676,8 +43676,8 @@ function formatRanges(compressible, protectedRanges) {
|
|
|
43676
43676
|
entries.push({
|
|
43677
43677
|
startRef: r.startRef,
|
|
43678
43678
|
endRef: r.endRef,
|
|
43679
|
-
startNum:
|
|
43680
|
-
endNum:
|
|
43679
|
+
startNum: refNum3(r.startRef),
|
|
43680
|
+
endNum: refNum3(r.endRef),
|
|
43681
43681
|
count: r.count,
|
|
43682
43682
|
tokens: r.tokens,
|
|
43683
43683
|
toolPct: 0,
|
|
@@ -46427,13 +46427,13 @@ function renderUncompressedRanges(visible) {
|
|
|
46427
46427
|
lines.push(" (no uncompressed messages)");
|
|
46428
46428
|
return lines.join("\n");
|
|
46429
46429
|
}
|
|
46430
|
-
const
|
|
46430
|
+
const refNum22 = (ref) => {
|
|
46431
46431
|
const m2 = ref.match(/\d+/);
|
|
46432
46432
|
return m2 ? parseInt(m2[0], 10) : 0;
|
|
46433
46433
|
};
|
|
46434
46434
|
const merged = [];
|
|
46435
46435
|
for (const m2 of visible) {
|
|
46436
|
-
const num3 =
|
|
46436
|
+
const num3 = refNum22(m2.ref);
|
|
46437
46437
|
const last = merged[merged.length - 1];
|
|
46438
46438
|
if (last && num3 === last.startNum + last.count) {
|
|
46439
46439
|
last.endRef = m2.ref;
|
|
@@ -49919,6 +49919,213 @@ function rewriteJsonResponse(body, ctx) {
|
|
|
49919
49919
|
return body;
|
|
49920
49920
|
}
|
|
49921
49921
|
|
|
49922
|
+
// src/preflight.ts
|
|
49923
|
+
var MAX_PREFLIGHT_ROUNDS = 8;
|
|
49924
|
+
var CHUNK_FRACTION = 0.6;
|
|
49925
|
+
var MIN_CHUNK_TOKENS = 2e3;
|
|
49926
|
+
var MIN_SUMMARY_CHARS = 50;
|
|
49927
|
+
var MAX_SUMMARY_OUTPUT_TOKENS = 8192;
|
|
49928
|
+
function refMaps(messages, state) {
|
|
49929
|
+
const refToIdx = /* @__PURE__ */ new Map();
|
|
49930
|
+
const idxToRef = /* @__PURE__ */ new Map();
|
|
49931
|
+
const byRaw = state.messageRefs?.byRaw ?? {};
|
|
49932
|
+
messages.forEach((m2, i) => {
|
|
49933
|
+
const ref = byRaw[m2.id];
|
|
49934
|
+
if (!ref) return;
|
|
49935
|
+
if (!refToIdx.has(ref)) refToIdx.set(ref, i);
|
|
49936
|
+
idxToRef.set(i, ref);
|
|
49937
|
+
});
|
|
49938
|
+
return { refToIdx, idxToRef };
|
|
49939
|
+
}
|
|
49940
|
+
function refNum2(ref) {
|
|
49941
|
+
return Number(ref.replace(/\D/g, "")) || 0;
|
|
49942
|
+
}
|
|
49943
|
+
function estimateCoreMessages(messages) {
|
|
49944
|
+
let tokens = 0;
|
|
49945
|
+
for (const m2 of messages) tokens += defaultCountTokens(m2.text ?? "");
|
|
49946
|
+
return tokens;
|
|
49947
|
+
}
|
|
49948
|
+
function rangeChars2(messages, startIdx, endIdx) {
|
|
49949
|
+
let chars = 0;
|
|
49950
|
+
for (let i = startIdx; i <= endIdx && i < messages.length; i++) {
|
|
49951
|
+
chars += (messages[i].text ?? "").length;
|
|
49952
|
+
}
|
|
49953
|
+
return chars;
|
|
49954
|
+
}
|
|
49955
|
+
function renderRange(messages, startIdx, endIdx) {
|
|
49956
|
+
const parts = [];
|
|
49957
|
+
for (let i = startIdx; i <= endIdx && i < messages.length; i++) {
|
|
49958
|
+
const m2 = messages[i];
|
|
49959
|
+
const text = (m2.text ?? "").trim();
|
|
49960
|
+
if (!text) continue;
|
|
49961
|
+
const label = m2.contentType === "tool-call" ? `assistant tool-call ${m2.toolName ?? "?"}` : m2.contentType === "tool-result" ? `tool result ${m2.toolName ?? "?"}` : m2.contentType === "reasoning" ? "assistant reasoning" : m2.role;
|
|
49962
|
+
parts.push(`[${label}]
|
|
49963
|
+
${text}`);
|
|
49964
|
+
}
|
|
49965
|
+
return parts.join("\n\n");
|
|
49966
|
+
}
|
|
49967
|
+
function splitChunks(messages, startIdx, endIdx, budgetTokens) {
|
|
49968
|
+
const chunks = [];
|
|
49969
|
+
let cur = startIdx;
|
|
49970
|
+
while (cur <= endIdx) {
|
|
49971
|
+
let tokens = 0;
|
|
49972
|
+
let last = cur;
|
|
49973
|
+
for (let i = cur; i <= endIdx; i++) {
|
|
49974
|
+
const t = defaultCountTokens(messages[i].text ?? "");
|
|
49975
|
+
if (tokens + t > budgetTokens && i > cur) break;
|
|
49976
|
+
tokens += t;
|
|
49977
|
+
last = i;
|
|
49978
|
+
}
|
|
49979
|
+
chunks.push([cur, last]);
|
|
49980
|
+
cur = last + 1;
|
|
49981
|
+
}
|
|
49982
|
+
return chunks;
|
|
49983
|
+
}
|
|
49984
|
+
function summaryPayload(protocol, model, system, content) {
|
|
49985
|
+
if (protocol === "anthropic") {
|
|
49986
|
+
return { model, max_tokens: MAX_SUMMARY_OUTPUT_TOKENS, system, messages: [{ role: "user", content }], stream: false };
|
|
49987
|
+
}
|
|
49988
|
+
if (protocol === "openai") {
|
|
49989
|
+
return { model, max_tokens: MAX_SUMMARY_OUTPUT_TOKENS, messages: [{ role: "system", content: system }, { role: "user", content }], stream: false };
|
|
49990
|
+
}
|
|
49991
|
+
return { model, max_output_tokens: MAX_SUMMARY_OUTPUT_TOKENS, instructions: system, input: [{ role: "user", content }], stream: false };
|
|
49992
|
+
}
|
|
49993
|
+
function extractSummaryText(protocol, json) {
|
|
49994
|
+
if (protocol === "anthropic") {
|
|
49995
|
+
const content = json.content;
|
|
49996
|
+
if (!Array.isArray(content)) return "";
|
|
49997
|
+
return content.map((c) => c && typeof c === "object" && c.type === "text" && typeof c.text === "string" ? c.text : "").join("");
|
|
49998
|
+
}
|
|
49999
|
+
if (protocol === "openai") {
|
|
50000
|
+
const choices = json.choices;
|
|
50001
|
+
if (!Array.isArray(choices) || choices.length === 0) return "";
|
|
50002
|
+
const msg = choices[0].message;
|
|
50003
|
+
if (!msg || typeof msg !== "object") return "";
|
|
50004
|
+
const c = msg.content;
|
|
50005
|
+
if (typeof c === "string") return c;
|
|
50006
|
+
if (Array.isArray(c)) {
|
|
50007
|
+
return c.map((p2) => p2 && typeof p2 === "object" && typeof p2.text === "string" ? p2.text : "").join("");
|
|
50008
|
+
}
|
|
50009
|
+
return "";
|
|
50010
|
+
}
|
|
50011
|
+
if (typeof json.output_text === "string") return json.output_text;
|
|
50012
|
+
const output = json.output;
|
|
50013
|
+
if (!Array.isArray(output)) return "";
|
|
50014
|
+
return output.map((o) => o && typeof o === "object" ? o.content : void 0).filter((c) => Array.isArray(c)).flatMap((c) => c).map((p2) => p2 && typeof p2 === "object" && typeof p2.text === "string" ? p2.text : "").join("");
|
|
50015
|
+
}
|
|
50016
|
+
async function summarizeRange(deps, content, startRef, endRef) {
|
|
50017
|
+
const system = buildCompressSystemPrompt(deps.prompts) + `
|
|
50018
|
+
|
|
50019
|
+
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.`;
|
|
50020
|
+
const { response, clearTimer } = await fetchWithRetry(
|
|
50021
|
+
deps.url,
|
|
50022
|
+
{
|
|
50023
|
+
method: "POST",
|
|
50024
|
+
headers: { "content-type": "application/json", ...deps.headers },
|
|
50025
|
+
body: JSON.stringify(summaryPayload(deps.protocol, deps.model, system, content)),
|
|
50026
|
+
dispatcher: proxyDispatcher(deps.proxyUrl)
|
|
50027
|
+
},
|
|
50028
|
+
void 0,
|
|
50029
|
+
deps.signal,
|
|
50030
|
+
(info) => deps.log("warn", `[preflight] summary attempt ${info.attempt} got HTTP ${info.status}; retrying in ${info.delayMs}ms`)
|
|
50031
|
+
);
|
|
50032
|
+
try {
|
|
50033
|
+
const text = await response.text();
|
|
50034
|
+
let json;
|
|
50035
|
+
try {
|
|
50036
|
+
json = JSON.parse(text);
|
|
50037
|
+
} catch {
|
|
50038
|
+
deps.log("warn", `[preflight] summary response was not JSON: ${text.slice(0, 200)}`);
|
|
50039
|
+
return null;
|
|
50040
|
+
}
|
|
50041
|
+
if (!json || typeof json !== "object") return null;
|
|
50042
|
+
const summary = extractSummaryText(deps.protocol, json).trim();
|
|
50043
|
+
if (summary.length < MIN_SUMMARY_CHARS) {
|
|
50044
|
+
deps.log("warn", `[preflight] summary too short (${summary.length} chars); skipping range`);
|
|
50045
|
+
return null;
|
|
50046
|
+
}
|
|
50047
|
+
return summary;
|
|
50048
|
+
} finally {
|
|
50049
|
+
clearTimer();
|
|
50050
|
+
}
|
|
50051
|
+
}
|
|
50052
|
+
async function preflightCompress(deps, messages) {
|
|
50053
|
+
const limit = deps.config.modelContextLimit;
|
|
50054
|
+
const result = { compressedRanges: 0, savedTokens: 0 };
|
|
50055
|
+
if (limit <= 0) return result;
|
|
50056
|
+
const budget = Math.max(MIN_CHUNK_TOKENS, Math.floor(limit * CHUNK_FRACTION));
|
|
50057
|
+
const minChars = deps.config.compress.minCompressRange;
|
|
50058
|
+
let currentTokens = deps.session.stats.lastInputTokens;
|
|
50059
|
+
let startTokens = -1;
|
|
50060
|
+
for (let round = 0; round < MAX_PREFLIGHT_ROUNDS; round++) {
|
|
50061
|
+
if (deps.signal?.aborted) break;
|
|
50062
|
+
const turn = deps.core.processTurn({
|
|
50063
|
+
messages,
|
|
50064
|
+
state: deps.session.state,
|
|
50065
|
+
config: deps.config,
|
|
50066
|
+
tokenCount: currentTokens,
|
|
50067
|
+
renderTags: "text-only"
|
|
50068
|
+
});
|
|
50069
|
+
deps.session.state = turn.state;
|
|
50070
|
+
currentTokens = Math.max(deps.session.stats.lastInputTokens, estimateCoreMessages(turn.messages));
|
|
50071
|
+
if (startTokens < 0) startTokens = currentTokens;
|
|
50072
|
+
if (currentTokens < limit) break;
|
|
50073
|
+
const ranges = viableRanges(turn.nudge?.compressibleRanges ?? []);
|
|
50074
|
+
if (ranges.length === 0) break;
|
|
50075
|
+
const range = [...ranges].sort((a, b2) => refNum2(a.startRef) - refNum2(b2.startRef))[0];
|
|
50076
|
+
const { refToIdx } = refMaps(messages, deps.session.state);
|
|
50077
|
+
const startIdx = refToIdx.get(range.startRef);
|
|
50078
|
+
const endIdx = refToIdx.get(range.endRef);
|
|
50079
|
+
if (startIdx === void 0 || endIdx === void 0 || startIdx > endIdx) break;
|
|
50080
|
+
let appliedThisRound = 0;
|
|
50081
|
+
for (const [cs2, ce2] of splitChunks(messages, startIdx, endIdx, budget)) {
|
|
50082
|
+
if (currentTokens < limit) break;
|
|
50083
|
+
if (deps.signal?.aborted) break;
|
|
50084
|
+
const maps = refMaps(messages, deps.session.state);
|
|
50085
|
+
const startRef = maps.idxToRef.get(cs2);
|
|
50086
|
+
const endRef = maps.idxToRef.get(ce2);
|
|
50087
|
+
if (!startRef || !endRef) continue;
|
|
50088
|
+
if (rangeChars2(messages, cs2, ce2) < minChars) continue;
|
|
50089
|
+
const content = renderRange(messages, cs2, ce2);
|
|
50090
|
+
if (content.length === 0) continue;
|
|
50091
|
+
let summary;
|
|
50092
|
+
try {
|
|
50093
|
+
summary = await summarizeRange(deps, content, startRef, endRef);
|
|
50094
|
+
} catch (err2) {
|
|
50095
|
+
if (err2 instanceof UpstreamHttpError) {
|
|
50096
|
+
deps.log("warn", `[preflight] summarization failed: HTTP ${err2.status} ${err2.body.slice(0, 200)}`);
|
|
50097
|
+
} else {
|
|
50098
|
+
deps.log("warn", `[preflight] summarization failed: ${String(err2)}`);
|
|
50099
|
+
}
|
|
50100
|
+
break;
|
|
50101
|
+
}
|
|
50102
|
+
if (!summary) continue;
|
|
50103
|
+
const ctx = {
|
|
50104
|
+
core: deps.core,
|
|
50105
|
+
config: deps.config,
|
|
50106
|
+
messages,
|
|
50107
|
+
session: deps.session,
|
|
50108
|
+
log: (msg) => deps.log("info", msg)
|
|
50109
|
+
};
|
|
50110
|
+
const creditBefore = deps.session.stats.compressCreditTokens;
|
|
50111
|
+
const applied = applyRanges(parseCompressInput({ content: [{ startId: startRef, endId: endRef, summary, topic: "preflight overflow compress" }] }), ctx);
|
|
50112
|
+
if (applied.startsWith("[Compression FAILED")) {
|
|
50113
|
+
deps.log("warn", `[preflight] ${applied}`);
|
|
50114
|
+
continue;
|
|
50115
|
+
}
|
|
50116
|
+
const compressed = deps.session.stats.compressCreditTokens - creditBefore;
|
|
50117
|
+
currentTokens = Math.max(0, currentTokens - compressed + defaultCountTokens(summary));
|
|
50118
|
+
deps.session.stats.lastInputTokens += defaultCountTokens(summary);
|
|
50119
|
+
appliedThisRound += 1;
|
|
50120
|
+
result.compressedRanges += 1;
|
|
50121
|
+
}
|
|
50122
|
+
if (appliedThisRound === 0) break;
|
|
50123
|
+
}
|
|
50124
|
+
if (result.compressedRanges > 0) deps.session.stats.lastInputTokens = currentTokens;
|
|
50125
|
+
result.savedTokens = Math.max(0, startTokens - currentTokens);
|
|
50126
|
+
return result;
|
|
50127
|
+
}
|
|
50128
|
+
|
|
49922
50129
|
// src/web/index.ts
|
|
49923
50130
|
import { readFileSync as readFileSync3 } from "fs";
|
|
49924
50131
|
import { dirname as dirname4, join as join3 } from "path";
|
|
@@ -50212,6 +50419,10 @@ ${icon} [ACP] ${inner}
|
|
|
50212
50419
|
|
|
50213
50420
|
// src/loop/core.ts
|
|
50214
50421
|
var MAX_LOOP_ROUNDS = 10;
|
|
50422
|
+
function maxTruncationRetries() {
|
|
50423
|
+
const raw = Number(process.env.BILI_TRUNCATION_RETRY_MAX);
|
|
50424
|
+
return Number.isInteger(raw) && raw >= 0 ? raw : 2;
|
|
50425
|
+
}
|
|
50215
50426
|
function isLoopThinking(m2) {
|
|
50216
50427
|
return m2.contentType === "reasoning" && typeof m2.id === "string" && m2.id.startsWith("acp_loop_");
|
|
50217
50428
|
}
|
|
@@ -50292,6 +50503,7 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
|
|
|
50292
50503
|
let currentUpstream = upstream;
|
|
50293
50504
|
const coreMessages = [...ctx.messages];
|
|
50294
50505
|
let degradedRetried = false;
|
|
50506
|
+
let truncationRetries = 0;
|
|
50295
50507
|
try {
|
|
50296
50508
|
for (let round = 1; round <= MAX_LOOP_ROUNDS; round++) {
|
|
50297
50509
|
if (signal?.aborted) break;
|
|
@@ -50461,7 +50673,9 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
|
|
|
50461
50673
|
yield adapter.emitToolCall(tc);
|
|
50462
50674
|
}
|
|
50463
50675
|
const reRequest = proxyResults.length > 0 && realCalls === 0;
|
|
50464
|
-
|
|
50676
|
+
const zeroContent = assistantText.length === 0 && assistantReasoning.length === 0;
|
|
50677
|
+
const canRetryTruncation = !sawDone && zeroContent && realCalls === 0 && round < MAX_LOOP_ROUNDS && truncationRetries < maxTruncationRetries();
|
|
50678
|
+
if (!reRequest && !canRetryTruncation) {
|
|
50465
50679
|
if (!sawDone) {
|
|
50466
50680
|
const partialText = assistantText.length;
|
|
50467
50681
|
const partialReasoning = assistantReasoning.length;
|
|
@@ -50482,7 +50696,14 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
|
|
|
50482
50696
|
yield adapter.emitCompletion({ finishReason: "length", usage });
|
|
50483
50697
|
return;
|
|
50484
50698
|
}
|
|
50485
|
-
|
|
50699
|
+
if (canRetryTruncation && !reRequest) {
|
|
50700
|
+
truncationRetries += 1;
|
|
50701
|
+
const max = maxTruncationRetries();
|
|
50702
|
+
ctx.log(`[acp-loop] round ${round}: upstream truncated with no content; auto-retrying (attempt ${truncationRetries}/${max})`);
|
|
50703
|
+
log("warn", `[acp-loop] upstream stream truncated with no content (round ${round}); auto-retrying (attempt ${truncationRetries}/${max})`);
|
|
50704
|
+
} else {
|
|
50705
|
+
ctx.log(`[acp-loop] round ${round}: proxy tool executed; re-requesting so the model sees the result`);
|
|
50706
|
+
}
|
|
50486
50707
|
if (signal?.aborted) break;
|
|
50487
50708
|
const fetchUpstream = (body) => fetchWithRetry(
|
|
50488
50709
|
requestOptions.url,
|
|
@@ -50628,6 +50849,20 @@ function shouldReserveOutputHeadroom(protocol) {
|
|
|
50628
50849
|
|
|
50629
50850
|
// src/loop/adapter-responses.ts
|
|
50630
50851
|
var RESPONSES_ITEM_ID_MAX = 64;
|
|
50852
|
+
function normalizeResponsesMessageItems(input) {
|
|
50853
|
+
if (!Array.isArray(input)) return 0;
|
|
50854
|
+
let typed = 0;
|
|
50855
|
+
for (const item of input) {
|
|
50856
|
+
if (typeof item !== "object" || item === null) continue;
|
|
50857
|
+
const rec = item;
|
|
50858
|
+
if (rec["type"] !== void 0) continue;
|
|
50859
|
+
if (rec["role"] !== "user" && rec["role"] !== "assistant") continue;
|
|
50860
|
+
if (rec["content"] === void 0) continue;
|
|
50861
|
+
rec["type"] = "message";
|
|
50862
|
+
typed++;
|
|
50863
|
+
}
|
|
50864
|
+
return typed;
|
|
50865
|
+
}
|
|
50631
50866
|
function sanitizeResponsesInputIds(input) {
|
|
50632
50867
|
if (!Array.isArray(input)) return;
|
|
50633
50868
|
for (const item of input) {
|
|
@@ -52469,7 +52704,10 @@ function takePendingPluginRegister() {
|
|
|
52469
52704
|
var registeredIds = /* @__PURE__ */ new Map();
|
|
52470
52705
|
function consumePluginRegisterFor(conversationId2) {
|
|
52471
52706
|
const agent = registeredIds.get(conversationId2);
|
|
52472
|
-
if (agent !== void 0)
|
|
52707
|
+
if (agent !== void 0) {
|
|
52708
|
+
registeredIds.delete(conversationId2);
|
|
52709
|
+
registeredIds.set(conversationId2, agent);
|
|
52710
|
+
}
|
|
52473
52711
|
return agent;
|
|
52474
52712
|
}
|
|
52475
52713
|
function handlePluginRegister(payload, res) {
|
|
@@ -54789,17 +55027,23 @@ ${bodyBuffer.toString("utf8")}`);
|
|
|
54789
55027
|
conversationIdentityResponses(parsed, convHeader),
|
|
54790
55028
|
parsed
|
|
54791
55029
|
) : void 0;
|
|
54792
|
-
const
|
|
55030
|
+
const openaiSignal = protocol === "openai" ? conversationSignalOpenai(parsed, convHeader) : "";
|
|
55031
|
+
const openaiIdentity = protocol === "openai" ? preferPromptCacheKeyIdentity(
|
|
55032
|
+
convHeader ? { value: openaiSignal, source: "header", clientProvided: true } : { value: openaiSignal, source: "content-fingerprint", clientProvided: false },
|
|
55033
|
+
parsed
|
|
55034
|
+
) : void 0;
|
|
55035
|
+
const conversation = protocol === "anthropic" ? conversationSignalAnthropic(parsed, convHeader) : protocol === "openai" ? openaiIdentity?.value ?? openaiSignal : subagentNamespace(
|
|
54793
55036
|
responsesIdentity?.value ?? conversationSignalResponses(parsed, convHeader),
|
|
54794
55037
|
parsed.instructions
|
|
54795
55038
|
);
|
|
54796
55039
|
const sessionId = deriveSessionId(req.headers, protocol, upstreamOrigin, conversation);
|
|
54797
|
-
const
|
|
55040
|
+
const bodyIdentity = responsesIdentity ?? openaiIdentity;
|
|
55041
|
+
const affinity = affinityToken(bodyIdentity ?? {
|
|
54798
55042
|
value: clientConv ?? conversation,
|
|
54799
55043
|
source: clientConv ? "header" : "generated",
|
|
54800
55044
|
clientProvided: !!clientConv
|
|
54801
55045
|
});
|
|
54802
|
-
const clientLabel =
|
|
55046
|
+
const clientLabel = bodyIdentity?.clientProvided ? bodyIdentity.value : clientConversationHeader(req.headers);
|
|
54803
55047
|
const session = getSession(sessionId, { protocol, upstreamOrigin, label: clientLabel ?? void 0 });
|
|
54804
55048
|
if (!pluginAgent) {
|
|
54805
55049
|
const identityAgent = consumePluginRegisterFor(clientConv ?? conversation);
|
|
@@ -54822,7 +55066,7 @@ ${bodyBuffer.toString("utf8")}`);
|
|
|
54822
55066
|
session.metadata.effectiveContextLimit = reqConfig.modelContextLimit;
|
|
54823
55067
|
recordPluginSession(pluginConversation ?? conversation, session.id);
|
|
54824
55068
|
}
|
|
54825
|
-
if (protocol === "responses") {
|
|
55069
|
+
if (protocol === "responses" || protocol === "openai") {
|
|
54826
55070
|
const pck = parsed.prompt_cache_key;
|
|
54827
55071
|
if (typeof pck === "string" && pck.trim().length > 0) {
|
|
54828
55072
|
recordPluginSession(pck.trim(), session.id);
|
|
@@ -54847,7 +55091,23 @@ ${bodyBuffer.toString("utf8")}`);
|
|
|
54847
55091
|
acquireInFlight(session);
|
|
54848
55092
|
try {
|
|
54849
55093
|
await withSessionLock(session, async () => {
|
|
54850
|
-
|
|
55094
|
+
const runPrepare = () => countTokens ? prepareCountTokens(parsed, core, reqConfig, log2, session) : protocol === "anthropic" ? prepareAnthropic(parsed, req, opts, core, reqConfig, reqPrompts, log2, session, pluginMode) : protocol === "openai" ? prepareOpenai(parsed, req, opts, core, reqConfig, reqPrompts, log2, session, pluginMode) : responsesCompact ? prepareResponsesCompact(bodyBuffer, parsed, session) : prepareResponses(parsed, req, opts, core, reqConfig, reqPrompts, log2, session, responsesIdentity, pluginMode);
|
|
55095
|
+
prepared = runPrepare();
|
|
55096
|
+
if (!countTokens && !responsesCompact) {
|
|
55097
|
+
prepared = await preflightCompressIfNeeded(
|
|
55098
|
+
prepared,
|
|
55099
|
+
runPrepare,
|
|
55100
|
+
req,
|
|
55101
|
+
res,
|
|
55102
|
+
opts,
|
|
55103
|
+
core,
|
|
55104
|
+
reqConfig,
|
|
55105
|
+
parsed.model,
|
|
55106
|
+
route,
|
|
55107
|
+
affinity,
|
|
55108
|
+
log2
|
|
55109
|
+
);
|
|
55110
|
+
}
|
|
54851
55111
|
await forward(req, res, opts, prepared.body, prepared, core, reqConfig, log2, route, affinity);
|
|
54852
55112
|
if (prepared) {
|
|
54853
55113
|
rememberPluginMessages(sessionId, prepared.processedMessages, prepared.originalMessages, prepared.nudge);
|
|
@@ -54865,8 +55125,15 @@ ${bodyBuffer.toString("utf8")}`);
|
|
|
54865
55125
|
}
|
|
54866
55126
|
}
|
|
54867
55127
|
var ACP_TAG_MARK = "<acp ";
|
|
54868
|
-
function stripKernelSummaries(messages) {
|
|
54869
|
-
|
|
55128
|
+
function stripKernelSummaries(messages, state) {
|
|
55129
|
+
const carried = /* @__PURE__ */ new Set();
|
|
55130
|
+
for (const b2 of state.blocks) {
|
|
55131
|
+
if (!b2.active || !b2.compressCallId) continue;
|
|
55132
|
+
if (messages.some((m2) => m2.contentType === "tool-call" && m2.toolCallId === b2.compressCallId)) {
|
|
55133
|
+
carried.add(`acp_summary_${b2.blockId}`);
|
|
55134
|
+
}
|
|
55135
|
+
}
|
|
55136
|
+
return messages.filter((m2) => !(m2.id ?? "").startsWith("acp_summary_") || !carried.has(m2.id));
|
|
54870
55137
|
}
|
|
54871
55138
|
function diagTagSummary(messages, sessionId, strategy) {
|
|
54872
55139
|
let textTagged = 0;
|
|
@@ -54921,7 +55188,7 @@ function prepareAnthropic(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
54921
55188
|
}
|
|
54922
55189
|
log2("info", diagTagSummary(turn.messages, sessionId, "text-only"));
|
|
54923
55190
|
log2("info", diagNudge(turn, sessionId, tokenCount, config.modelContextLimit, parsed.model));
|
|
54924
|
-
processedMessages = stripKernelSummaries(turn.messages);
|
|
55191
|
+
processedMessages = stripKernelSummaries(turn.messages, turn.state);
|
|
54925
55192
|
reapOrphanBlocks(session, msgs, deactivateBlock);
|
|
54926
55193
|
rebuiltMessages = coreToAnthropic(processedMessages, cacheControls);
|
|
54927
55194
|
systemOut = injectSystem(parsed, opts, prompts);
|
|
@@ -54977,7 +55244,7 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session,
|
|
|
54977
55244
|
}
|
|
54978
55245
|
log2("info", diagTagSummary(turn.messages, sessionId, "text-only"));
|
|
54979
55246
|
log2("info", diagNudge(turn, sessionId, tokenCount, config.modelContextLimit, parsed.model));
|
|
54980
|
-
processedMessages = stripKernelSummaries(turn.messages);
|
|
55247
|
+
processedMessages = stripKernelSummaries(turn.messages, turn.state);
|
|
54981
55248
|
reapOrphanBlocks(session, msgs, deactivateBlock);
|
|
54982
55249
|
rebuiltMessages = coreToOpenai(processedMessages);
|
|
54983
55250
|
const sysParts = [];
|
|
@@ -55021,6 +55288,10 @@ function prepareResponses(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
55021
55288
|
let responsesProjection;
|
|
55022
55289
|
let rebuiltInput = parsed.input;
|
|
55023
55290
|
let toolsOut = parsed.tools;
|
|
55291
|
+
const typedItems = normalizeResponsesMessageItems(parsed.input);
|
|
55292
|
+
if (typedItems > 0) {
|
|
55293
|
+
log2("info", `[${sessionId}] stamped type:"message" on ${typedItems} type-less input item(s) before projection (omp wire form)`);
|
|
55294
|
+
}
|
|
55024
55295
|
sanitizeResponsesInputIds(parsed.input);
|
|
55025
55296
|
const droppedEmpty = dropWhitespaceResponsesMessages(parsed.input);
|
|
55026
55297
|
if (droppedEmpty > 0) {
|
|
@@ -55050,7 +55321,7 @@ function prepareResponses(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
55050
55321
|
}
|
|
55051
55322
|
log2("info", diagTagSummary(turn.messages, sessionId, "text-only"));
|
|
55052
55323
|
log2("info", diagNudge(turn, sessionId, tokenCount, config.modelContextLimit, parsed.model));
|
|
55053
|
-
processedMessages = stripKernelSummaries(turn.messages);
|
|
55324
|
+
processedMessages = stripKernelSummaries(turn.messages, turn.state);
|
|
55054
55325
|
reapOrphanBlocks(session, msgs, deactivateBlock);
|
|
55055
55326
|
rebuiltInput = patchResponsesInput(projection, processedMessages);
|
|
55056
55327
|
if (shouldInject && !process.env.ACP_NO_COMPRESS_PROMPT) {
|
|
@@ -55121,7 +55392,7 @@ function prepareCountTokens(parsed, core, config, log2, session) {
|
|
|
55121
55392
|
try {
|
|
55122
55393
|
const { msgs, cacheControls } = anthropicToCore(parsed);
|
|
55123
55394
|
const turn = core.processTurn({ messages: msgs, state: session.state, config, tokenCount: session.stats.lastInputTokens, renderTags: "text-only" });
|
|
55124
|
-
const stripped = stripKernelSummaries(turn.messages);
|
|
55395
|
+
const stripped = stripKernelSummaries(turn.messages, turn.state);
|
|
55125
55396
|
const rebuiltMessages = coreToAnthropic(stripped, cacheControls);
|
|
55126
55397
|
log2("info", `[${sessionId}] count_tokens pruned: ${msgs.length} \u2192 ${stripped.length} msgs`);
|
|
55127
55398
|
return {
|
|
@@ -55208,11 +55479,71 @@ function injectResponsesTool(tools, toolsToAdd = ACP_TOOLS_RESPONSES) {
|
|
|
55208
55479
|
const additions = toolsToAdd.filter((t) => !present.has(t.name));
|
|
55209
55480
|
return [...tools, ...additions];
|
|
55210
55481
|
}
|
|
55211
|
-
|
|
55482
|
+
function buildForwardTarget(req, opts, route, affinity) {
|
|
55212
55483
|
const reqUrl = req.url ?? "";
|
|
55213
55484
|
const isAbsoluteUrl = /^https?:\/\//i.test(reqUrl);
|
|
55214
55485
|
const rewritten = route ? route.rewrittenUrl : isAbsoluteUrl ? reqUrl : opts.upstream + reqUrl;
|
|
55215
55486
|
const upstreamUrl = rewritten.replace(/^mitm:\/\//, "https://");
|
|
55487
|
+
const headers = {};
|
|
55488
|
+
const reqConnNamed = connectionNamedHeaders(req.headers["connection"]);
|
|
55489
|
+
for (const [k2, v2] of Object.entries(req.headers)) {
|
|
55490
|
+
const lower = k2.toLowerCase();
|
|
55491
|
+
if (UPSTREAM_HOP_HEADERS.has(lower) || reqConnNamed.has(lower) || v2 === void 0) continue;
|
|
55492
|
+
headers[k2] = Array.isArray(v2) ? v2.join(", ") : v2;
|
|
55493
|
+
}
|
|
55494
|
+
headers["host"] = new URL(upstreamUrl).host;
|
|
55495
|
+
const betaKey = Object.keys(headers).find((h) => h.toLowerCase() === "x-codex-beta-features");
|
|
55496
|
+
if (betaKey) {
|
|
55497
|
+
const kept = headers[betaKey].split(",").map((s3) => s3.trim()).filter((f2) => f2 && f2 !== "remote_compaction_v2");
|
|
55498
|
+
if (kept.length > 0) headers[betaKey] = kept.join(",");
|
|
55499
|
+
else delete headers[betaKey];
|
|
55500
|
+
}
|
|
55501
|
+
if (affinity && !clientConversationHeader(req.headers)) {
|
|
55502
|
+
headers["x-session-id"] = affinity;
|
|
55503
|
+
}
|
|
55504
|
+
const proxyUrl = resolveProxy(opts.routes, opts.proxy, route?.rewrittenUrl ?? upstreamUrl, opts.proxyFallback);
|
|
55505
|
+
return { upstreamUrl, headers, proxyUrl };
|
|
55506
|
+
}
|
|
55507
|
+
async function preflightCompressIfNeeded(prepared, runPrepare, req, res, opts, core, config, model, route, affinity, log2) {
|
|
55508
|
+
const session = prepared.session;
|
|
55509
|
+
const limit = config.modelContextLimit;
|
|
55510
|
+
const tokenCount = Math.max(session.stats.lastInputTokens, estimateCoreMessages(prepared.processedMessages));
|
|
55511
|
+
if (limit <= 0 || !model || tokenCount < limit) return prepared;
|
|
55512
|
+
if ((prepared.nudge?.compressibleRanges ?? []).length === 0) return prepared;
|
|
55513
|
+
log2("warn", `[${session.id}] context ${tokenCount} tokens exceeds model window ${limit} (model=${model}); preflight compressing before forward`);
|
|
55514
|
+
const { upstreamUrl, headers, proxyUrl } = buildForwardTarget(req, opts, route, affinity);
|
|
55515
|
+
const clientAbort = new AbortController();
|
|
55516
|
+
res.on("close", () => {
|
|
55517
|
+
if (!res.writableEnded) clientAbort.abort();
|
|
55518
|
+
});
|
|
55519
|
+
const started = Date.now();
|
|
55520
|
+
const result = await preflightCompress(
|
|
55521
|
+
{
|
|
55522
|
+
core,
|
|
55523
|
+
session,
|
|
55524
|
+
config,
|
|
55525
|
+
prompts: prepared.prompts ?? defaultPrompts,
|
|
55526
|
+
protocol: prepared.protocol,
|
|
55527
|
+
url: upstreamUrl,
|
|
55528
|
+
headers,
|
|
55529
|
+
model,
|
|
55530
|
+
proxyUrl,
|
|
55531
|
+
signal: clientAbort.signal,
|
|
55532
|
+
log: log2
|
|
55533
|
+
},
|
|
55534
|
+
prepared.originalMessages
|
|
55535
|
+
);
|
|
55536
|
+
if (result.compressedRanges > 0) {
|
|
55537
|
+
log2("info", `[${session.id}] preflight compressed ${result.compressedRanges} range(s), ~${result.savedTokens} tokens saved (${tokenCount} \u2192 ${session.stats.lastInputTokens}) in ${Date.now() - started}ms; rebuilding payload`);
|
|
55538
|
+
const rebuilt = runPrepare();
|
|
55539
|
+
session.stats.requests -= 1;
|
|
55540
|
+
return rebuilt;
|
|
55541
|
+
}
|
|
55542
|
+
log2("warn", `[${session.id}] preflight could not compress enough (~${result.savedTokens} tokens saved); forwarding as-is`);
|
|
55543
|
+
return prepared;
|
|
55544
|
+
}
|
|
55545
|
+
async function forward(req, res, opts, body, prepared, core, config, log2, route, affinity) {
|
|
55546
|
+
const { upstreamUrl, headers, proxyUrl } = buildForwardTarget(req, opts, route, affinity);
|
|
55216
55547
|
log2("info", `forward ${req.method} \u2192 ${upstreamUrl}`);
|
|
55217
55548
|
if (process.env.ACP_DEBUG && prepared) {
|
|
55218
55549
|
const sid = prepared.session.id;
|
|
@@ -55254,24 +55585,6 @@ async function forward(req, res, opts, body, prepared, core, config, log2, route
|
|
|
55254
55585
|
} catch {
|
|
55255
55586
|
}
|
|
55256
55587
|
}
|
|
55257
|
-
const headers = {};
|
|
55258
|
-
const reqConnNamed = connectionNamedHeaders(req.headers["connection"]);
|
|
55259
|
-
for (const [k2, v2] of Object.entries(req.headers)) {
|
|
55260
|
-
const lower = k2.toLowerCase();
|
|
55261
|
-
if (UPSTREAM_HOP_HEADERS.has(lower) || reqConnNamed.has(lower) || v2 === void 0) continue;
|
|
55262
|
-
headers[k2] = Array.isArray(v2) ? v2.join(", ") : v2;
|
|
55263
|
-
}
|
|
55264
|
-
headers["host"] = new URL(upstreamUrl).host;
|
|
55265
|
-
const betaKey = Object.keys(headers).find((h) => h.toLowerCase() === "x-codex-beta-features");
|
|
55266
|
-
if (betaKey) {
|
|
55267
|
-
const kept = headers[betaKey].split(",").map((s3) => s3.trim()).filter((f2) => f2 && f2 !== "remote_compaction_v2");
|
|
55268
|
-
if (kept.length > 0) headers[betaKey] = kept.join(",");
|
|
55269
|
-
else delete headers[betaKey];
|
|
55270
|
-
}
|
|
55271
|
-
if (affinity && !clientConversationHeader(req.headers)) {
|
|
55272
|
-
headers["x-session-id"] = affinity;
|
|
55273
|
-
}
|
|
55274
|
-
const proxyUrl = resolveProxy(opts.routes, opts.proxy, route?.rewrittenUrl ?? upstreamUrl, opts.proxyFallback);
|
|
55275
55588
|
if (opts.debug) {
|
|
55276
55589
|
const hdrLog = {};
|
|
55277
55590
|
for (const [hk, hv] of Object.entries(headers)) {
|