billion-context 0.1.88-pr.558.418 → 0.1.88-pr.571.415
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -0
- package/dist/index.js +161 -79
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -112,6 +112,25 @@ turn is a semantic mismatch the model tolerates (it is clearly marked
|
|
|
112
112
|
summaries (their tool call isn't in the agent's history and the agent's view
|
|
113
113
|
skips `acp_summary`) — but that needs the id match above, which doesn't occur.
|
|
114
114
|
|
|
115
|
+
### Preflight hold (#568)
|
|
116
|
+
|
|
117
|
+
Preflight compression runs **before** the proxy sends any response bytes, and on
|
|
118
|
+
big sessions it takes minutes (summarization round-trips to the same upstream).
|
|
119
|
+
That exceeds client-side header timeouts (undici's default is 300s): the client
|
|
120
|
+
aborts, the proxy drops the in-flight compression and never forwards — a
|
|
121
|
+
repeating death loop every few minutes.
|
|
122
|
+
|
|
123
|
+
So when preflight outlives a grace period (default **30s**, override with
|
|
124
|
+
`BILI_PREFLIGHT_HOLD_MS`), the proxy commits the response early: streams get
|
|
125
|
+
`200` + `text/event-stream` + SSE comment keep-alives (`: bili-preflight`, every
|
|
126
|
+
15s); non-stream requests get `200` + `application/json` + whitespace padding.
|
|
127
|
+
Early commits carry an `x-bili-preflight: compressing` header. Once the status
|
|
128
|
+
is committed, late failures can no longer change it, so they are delivered
|
|
129
|
+
**in-band** instead: a protocol error event (`preflight_compress_failed`) for
|
|
130
|
+
streams, the identical structured error body under the already-sent 200 for
|
|
131
|
+
JSON. Fast paths (preflight finishes within the grace) are unchanged and keep
|
|
132
|
+
full status-code fidelity.
|
|
133
|
+
|
|
115
134
|
## Which do I need?
|
|
116
135
|
|
|
117
136
|
Pick by your client:
|
package/dist/index.js
CHANGED
|
@@ -51147,11 +51147,6 @@ function estimateRawBodyTokens(parsed) {
|
|
|
51147
51147
|
walk(parsed);
|
|
51148
51148
|
return tokens;
|
|
51149
51149
|
}
|
|
51150
|
-
function estimateCoreMessagesUpper(messages) {
|
|
51151
|
-
let chars = 0;
|
|
51152
|
-
for (const m2 of messages) chars += (m2.text ?? "").length;
|
|
51153
|
-
return chars;
|
|
51154
|
-
}
|
|
51155
51150
|
function rangeChars2(messages, startIdx, endIdx) {
|
|
51156
51151
|
let chars = 0;
|
|
51157
51152
|
for (let i = startIdx; i <= endIdx && i < messages.length; i++) {
|
|
@@ -51171,16 +51166,16 @@ ${text}`);
|
|
|
51171
51166
|
}
|
|
51172
51167
|
return parts.join("\n\n");
|
|
51173
51168
|
}
|
|
51174
|
-
function splitChunks(messages, startIdx, endIdx,
|
|
51169
|
+
function splitChunks(messages, startIdx, endIdx, budgetTokens) {
|
|
51175
51170
|
const chunks = [];
|
|
51176
51171
|
let cur = startIdx;
|
|
51177
51172
|
while (cur <= endIdx) {
|
|
51178
|
-
let
|
|
51173
|
+
let tokens = 0;
|
|
51179
51174
|
let last = cur;
|
|
51180
51175
|
for (let i = cur; i <= endIdx; i++) {
|
|
51181
|
-
const t =
|
|
51182
|
-
if (
|
|
51183
|
-
|
|
51176
|
+
const t = defaultCountTokens(messages[i].text ?? "");
|
|
51177
|
+
if (tokens + t > budgetTokens && i > cur) break;
|
|
51178
|
+
tokens += t;
|
|
51184
51179
|
last = i;
|
|
51185
51180
|
}
|
|
51186
51181
|
chunks.push([cur, last]);
|
|
@@ -51267,14 +51262,11 @@ function noEmergencyTruncate(config) {
|
|
|
51267
51262
|
}
|
|
51268
51263
|
async function preflightCompress(deps, messages) {
|
|
51269
51264
|
const limit = deps.config.modelContextLimit;
|
|
51270
|
-
const result = { compressedRanges: 0, savedTokens: 0, payloadEstimate: estimateCoreMessages(messages) + (deps.imageFloor ?? 0) + (deps.wireOverhead ?? 0)
|
|
51265
|
+
const result = { compressedRanges: 0, savedTokens: 0, payloadEstimate: estimateCoreMessages(messages) + (deps.imageFloor ?? 0) + (deps.wireOverhead ?? 0) };
|
|
51271
51266
|
if (limit <= 0) return result;
|
|
51272
51267
|
const budget = Math.max(MIN_CHUNK_TOKENS, Math.floor(limit * CHUNK_FRACTION));
|
|
51273
51268
|
const minChars = deps.config.compress.minCompressRange;
|
|
51274
|
-
|
|
51275
|
-
const countText = baselineKnown ? defaultCountTokens : (text) => text.length;
|
|
51276
|
-
let currentTokens = baselineKnown ? deps.session.stats.lastInputTokens : estimateCoreMessagesUpper(messages);
|
|
51277
|
-
let finalUpper = baselineKnown ? 0 : estimateCoreMessagesUpper(messages);
|
|
51269
|
+
let currentTokens = deps.session.stats.lastInputTokens;
|
|
51278
51270
|
let startTokens = -1;
|
|
51279
51271
|
let failure;
|
|
51280
51272
|
let activeConfig = deps.config;
|
|
@@ -51298,10 +51290,6 @@ async function preflightCompress(deps, messages) {
|
|
|
51298
51290
|
});
|
|
51299
51291
|
deps.session.state = turn.state;
|
|
51300
51292
|
currentTokens = Math.max(deps.session.stats.lastInputTokens, estimateCoreMessages(turn.messages) + (deps.imageFloor ?? 0) + (deps.wireOverhead ?? 0));
|
|
51301
|
-
if (!baselineKnown) {
|
|
51302
|
-
finalUpper = estimateCoreMessagesUpper(turn.messages) + (deps.imageFloor ?? 0) + (deps.wireOverhead ?? 0);
|
|
51303
|
-
currentTokens = Math.max(currentTokens, finalUpper);
|
|
51304
|
-
}
|
|
51305
51293
|
result.payloadEstimate = estimateCoreMessages(turn.messages) + (deps.imageFloor ?? 0) + (deps.wireOverhead ?? 0);
|
|
51306
51294
|
if (startTokens < 0) startTokens = currentTokens;
|
|
51307
51295
|
if (currentTokens < limit) break;
|
|
@@ -51337,7 +51325,7 @@ async function preflightCompress(deps, messages) {
|
|
|
51337
51325
|
continue;
|
|
51338
51326
|
}
|
|
51339
51327
|
rangesTried += 1;
|
|
51340
|
-
for (const [cs2, ce2] of splitChunks(messages, startIdx, endIdx, budget
|
|
51328
|
+
for (const [cs2, ce2] of splitChunks(messages, startIdx, endIdx, budget)) {
|
|
51341
51329
|
if (currentTokens < limit) break;
|
|
51342
51330
|
if (deps.signal?.aborted) {
|
|
51343
51331
|
failure = ABORTED_FAILURE;
|
|
@@ -51396,8 +51384,7 @@ async function preflightCompress(deps, messages) {
|
|
|
51396
51384
|
break;
|
|
51397
51385
|
}
|
|
51398
51386
|
const compressed = deps.session.stats.compressCreditTokens - creditBefore;
|
|
51399
|
-
|
|
51400
|
-
currentTokens = Math.max(0, currentTokens - folded + countText(summary));
|
|
51387
|
+
currentTokens = Math.max(0, currentTokens - compressed + defaultCountTokens(summary));
|
|
51401
51388
|
deps.session.stats.lastInputTokens += defaultCountTokens(summary);
|
|
51402
51389
|
appliedThisRound += 1;
|
|
51403
51390
|
result.compressedRanges += 1;
|
|
@@ -51422,7 +51409,6 @@ async function preflightCompress(deps, messages) {
|
|
|
51422
51409
|
if (result.compressedRanges > 0) deps.session.stats.lastInputTokens = currentTokens;
|
|
51423
51410
|
result.savedTokens = Math.max(0, startTokens - currentTokens);
|
|
51424
51411
|
if (currentTokens >= limit) result.failure = failure;
|
|
51425
|
-
result.fitsWindow = baselineKnown ? result.payloadEstimate < limit : finalUpper < limit;
|
|
51426
51412
|
return result;
|
|
51427
51413
|
}
|
|
51428
51414
|
|
|
@@ -54717,6 +54703,35 @@ data: ${JSON.stringify({ type: "message_delta", delta: { stop_reason: "end_turn"
|
|
|
54717
54703
|
safeWrite(res, `event: message_stop
|
|
54718
54704
|
data: ${JSON.stringify({ type: "message_stop" })}
|
|
54719
54705
|
|
|
54706
|
+
`);
|
|
54707
|
+
}
|
|
54708
|
+
} catch {
|
|
54709
|
+
} finally {
|
|
54710
|
+
try {
|
|
54711
|
+
res.end();
|
|
54712
|
+
} catch {
|
|
54713
|
+
}
|
|
54714
|
+
}
|
|
54715
|
+
}
|
|
54716
|
+
function emitPreflightError(res, protocol, error, log2) {
|
|
54717
|
+
const err2 = { type: "server_error", code: "preflight_compress_failed", message: error.message, retryable: error.retryable };
|
|
54718
|
+
log2?.(`[acp-proxy: preflight failed after early response commit \u2014 delivering in-band: ${error.message}]`);
|
|
54719
|
+
try {
|
|
54720
|
+
if (protocol === "openai") {
|
|
54721
|
+
safeWrite(res, `data: ${JSON.stringify({ error: err2 })}
|
|
54722
|
+
|
|
54723
|
+
data: [DONE]
|
|
54724
|
+
|
|
54725
|
+
`);
|
|
54726
|
+
} else if (protocol === "responses") {
|
|
54727
|
+
safeWrite(res, `event: error
|
|
54728
|
+
data: ${JSON.stringify({ type: "error", code: err2.code, message: err2.message })}
|
|
54729
|
+
|
|
54730
|
+
`);
|
|
54731
|
+
} else {
|
|
54732
|
+
safeWrite(res, `event: error
|
|
54733
|
+
data: ${JSON.stringify({ type: "error", error: { type: "server_error", code: err2.code, message: err2.message } })}
|
|
54734
|
+
|
|
54720
54735
|
`);
|
|
54721
54736
|
}
|
|
54722
54737
|
} catch {
|
|
@@ -58356,24 +58371,41 @@ ${bodyBuffer.toString("utf8")}`);
|
|
|
58356
58371
|
parsed.model,
|
|
58357
58372
|
route,
|
|
58358
58373
|
affinity,
|
|
58359
|
-
anonAffinity !== null,
|
|
58360
58374
|
log2,
|
|
58361
58375
|
instanceId
|
|
58362
58376
|
);
|
|
58363
58377
|
if (isPreflightFailFast(outcome)) {
|
|
58364
|
-
if (outcome.respond && !res.
|
|
58365
|
-
res.
|
|
58366
|
-
|
|
58367
|
-
|
|
58368
|
-
|
|
58369
|
-
|
|
58370
|
-
|
|
58371
|
-
|
|
58372
|
-
|
|
58373
|
-
|
|
58374
|
-
|
|
58378
|
+
if (outcome.respond && !res.destroyed) {
|
|
58379
|
+
if (res.headersSent) {
|
|
58380
|
+
if (prepared.stream) {
|
|
58381
|
+
emitPreflightError(res, prepared.protocol, { message: outcome.message, retryable: outcome.retryable }, (m2) => log2("warn", m2));
|
|
58382
|
+
} else {
|
|
58383
|
+
try {
|
|
58384
|
+
res.end(JSON.stringify({
|
|
58385
|
+
error: {
|
|
58386
|
+
type: "server_error",
|
|
58387
|
+
code: "preflight_compress_failed",
|
|
58388
|
+
message: outcome.message,
|
|
58389
|
+
retryable: outcome.retryable
|
|
58390
|
+
}
|
|
58391
|
+
}));
|
|
58392
|
+
} catch {
|
|
58393
|
+
}
|
|
58375
58394
|
}
|
|
58376
|
-
}
|
|
58395
|
+
} else {
|
|
58396
|
+
res.writeHead(outcome.status, {
|
|
58397
|
+
"content-type": "application/json",
|
|
58398
|
+
...outcome.status === 503 ? { "retry-after": "30" } : {}
|
|
58399
|
+
});
|
|
58400
|
+
res.end(JSON.stringify({
|
|
58401
|
+
error: {
|
|
58402
|
+
type: "server_error",
|
|
58403
|
+
code: "preflight_compress_failed",
|
|
58404
|
+
message: outcome.message,
|
|
58405
|
+
retryable: outcome.retryable
|
|
58406
|
+
}
|
|
58407
|
+
}));
|
|
58408
|
+
}
|
|
58377
58409
|
}
|
|
58378
58410
|
return;
|
|
58379
58411
|
}
|
|
@@ -58492,11 +58524,6 @@ function armHostUsageCredit(session, originalMessages, processedMessages, log2)
|
|
|
58492
58524
|
log2("info", `[${session.id}] host usage backfill armed: +${session.hostCreditTokens} tok (forwarded view is folded); host usage will report the uncompressed baseline`);
|
|
58493
58525
|
}
|
|
58494
58526
|
}
|
|
58495
|
-
function effectiveTokenCount(session, msgs) {
|
|
58496
|
-
if (session.stats.lastInputTokens > 0) return session.stats.lastInputTokens;
|
|
58497
|
-
if (!session.metadata.anonymousPrefixAffinity) return 0;
|
|
58498
|
-
return estimateCoreMessagesUpper(msgs);
|
|
58499
|
-
}
|
|
58500
58527
|
function prepareAnthropic(parsed, req, opts, core, config, prompts, log2, session, pluginMode) {
|
|
58501
58528
|
const sessionId = session.id;
|
|
58502
58529
|
const stream2 = parsed.stream === true;
|
|
@@ -58521,7 +58548,7 @@ function prepareAnthropic(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
58521
58548
|
const { msgs, cacheControls } = anthropicToCore(parsed);
|
|
58522
58549
|
originalMessages = msgs;
|
|
58523
58550
|
extractSystem(parsed.system);
|
|
58524
|
-
const tokenCount =
|
|
58551
|
+
const tokenCount = session.stats.lastInputTokens;
|
|
58525
58552
|
const activeBefore = new Set(session.state.blocks.filter((b2) => b2.active).map((b2) => b2.blockId));
|
|
58526
58553
|
const turn = core.processTurn({ messages: msgs, state: session.state, config, tokenCount, renderTags: "text-only" });
|
|
58527
58554
|
session.state = turn.state;
|
|
@@ -58642,7 +58669,7 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session,
|
|
|
58642
58669
|
const { msgs, systemText } = openaiToCore(parsed);
|
|
58643
58670
|
openaiSystemText = systemText;
|
|
58644
58671
|
originalMessages = msgs;
|
|
58645
|
-
const tokenCount =
|
|
58672
|
+
const tokenCount = session.stats.lastInputTokens;
|
|
58646
58673
|
const activeBefore = new Set(session.state.blocks.filter((b2) => b2.active).map((b2) => b2.blockId));
|
|
58647
58674
|
const turn = core.processTurn({ messages: msgs, state: session.state, config, tokenCount, renderTags: "text-only" });
|
|
58648
58675
|
session.state = turn.state;
|
|
@@ -58747,7 +58774,7 @@ function prepareResponses(parsed, req, opts, core, config, prompts, log2, sessio
|
|
|
58747
58774
|
if (process.env.ACP_DEBUG) {
|
|
58748
58775
|
log2("info", `[${sessionId}] input items: ${Array.isArray(parsed.input) ? parsed.input.map((i) => i.type).join(",") : "(string)"}`);
|
|
58749
58776
|
}
|
|
58750
|
-
const tokenCount =
|
|
58777
|
+
const tokenCount = session.stats.lastInputTokens;
|
|
58751
58778
|
const turn = core.processTurn({ messages: msgs, state: session.state, config, tokenCount, renderTags });
|
|
58752
58779
|
session.state = turn.state;
|
|
58753
58780
|
session.stats.compressCreditTokens = 0;
|
|
@@ -59045,15 +59072,54 @@ function buildForwardTarget(req, opts, route, affinity, hopMarker) {
|
|
|
59045
59072
|
function isPreflightFailFast(outcome) {
|
|
59046
59073
|
return "failFast" in outcome;
|
|
59047
59074
|
}
|
|
59048
|
-
|
|
59075
|
+
var PREFLIGHT_HOLD_GRACE_DEFAULT_MS = 3e4;
|
|
59076
|
+
var PREFLIGHT_KEEPALIVE_MS = 15e3;
|
|
59077
|
+
function preflightHoldGraceMs() {
|
|
59078
|
+
const raw = process.env.BILI_PREFLIGHT_HOLD_MS;
|
|
59079
|
+
if (!raw) return PREFLIGHT_HOLD_GRACE_DEFAULT_MS;
|
|
59080
|
+
const v2 = Number(raw);
|
|
59081
|
+
return Number.isFinite(v2) && v2 >= 0 ? Math.floor(v2) : PREFLIGHT_HOLD_GRACE_DEFAULT_MS;
|
|
59082
|
+
}
|
|
59083
|
+
function beginPreflightHold(res, prepared, log2) {
|
|
59084
|
+
if (res.headersSent || res.destroyed || res.writableEnded) return void 0;
|
|
59085
|
+
const sid = prepared.session.id;
|
|
59086
|
+
const keepAlive = prepared.stream ? ": bili-preflight\n\n" : " ";
|
|
59087
|
+
try {
|
|
59088
|
+
if (prepared.stream) {
|
|
59089
|
+
res.writeHead(200, {
|
|
59090
|
+
"content-type": "text/event-stream",
|
|
59091
|
+
"cache-control": "no-cache",
|
|
59092
|
+
"x-accel-buffering": "no",
|
|
59093
|
+
"x-bili-preflight": "compressing"
|
|
59094
|
+
});
|
|
59095
|
+
} else {
|
|
59096
|
+
res.writeHead(200, { "content-type": "application/json", "x-bili-preflight": "compressing" });
|
|
59097
|
+
}
|
|
59098
|
+
} catch {
|
|
59099
|
+
return void 0;
|
|
59100
|
+
}
|
|
59101
|
+
log2("info", `[${sid}] preflight still running after ${preflightHoldGraceMs()}ms grace \u2014 committed early ${prepared.stream ? "SSE" : "JSON"} headers + keep-alive to hold the client (#568)`);
|
|
59102
|
+
try {
|
|
59103
|
+
res.write(keepAlive);
|
|
59104
|
+
} catch {
|
|
59105
|
+
}
|
|
59106
|
+
const iv = setInterval(() => {
|
|
59107
|
+
try {
|
|
59108
|
+
res.write(keepAlive);
|
|
59109
|
+
} catch {
|
|
59110
|
+
clearInterval(iv);
|
|
59111
|
+
}
|
|
59112
|
+
}, PREFLIGHT_KEEPALIVE_MS);
|
|
59113
|
+
return () => clearInterval(iv);
|
|
59114
|
+
}
|
|
59115
|
+
async function preflightCompressIfNeeded(prepared, runPrepare, req, res, opts, core, config, model, route, affinity, log2, instanceId) {
|
|
59049
59116
|
const session = prepared.session;
|
|
59050
59117
|
const limit = config.modelContextLimit;
|
|
59051
59118
|
const imageTokens = imageTokensInRawBody(prepared.protocol, prepared.body);
|
|
59052
59119
|
const textEstimate = estimateCoreMessages(prepared.processedMessages);
|
|
59053
59120
|
const overheadEstimate = estimateWireOverhead(prepared.protocol, prepared.body);
|
|
59054
59121
|
const payloadEstimate = textEstimate + overheadEstimate + imageTokens;
|
|
59055
|
-
const
|
|
59056
|
-
const tokenCount = unknownBaseline ? estimateCoreMessagesUpper(prepared.processedMessages) + overheadEstimate + imageTokens : Math.max(session.stats.lastInputTokens, payloadEstimate);
|
|
59122
|
+
const tokenCount = Math.max(session.stats.lastInputTokens, payloadEstimate);
|
|
59057
59123
|
if (limit <= 0 || !model || tokenCount < limit) return prepared;
|
|
59058
59124
|
const learnedMap = session.metadata.learnedContextLimits;
|
|
59059
59125
|
const learnedLimit = (model ? learnedMap?.[model] : void 0) ?? session.metadata.learnedContextLimit;
|
|
@@ -59068,14 +59134,9 @@ async function preflightCompressIfNeeded(prepared, runPrepare, req, res, opts, c
|
|
|
59068
59134
|
log2("error", `[${session.id}] preflight fail-fast ${status2} (retryable=${retryable}): ${message}`);
|
|
59069
59135
|
return { failFast: true, status: status2, message, retryable, respond: !res.writableEnded };
|
|
59070
59136
|
};
|
|
59071
|
-
if ((prepared.nudge?.compressibleRanges ?? []).length === 0) {
|
|
59072
|
-
|
|
59073
|
-
|
|
59074
|
-
return prepared;
|
|
59075
|
-
}
|
|
59076
|
-
if (unknownBaseline) {
|
|
59077
|
-
return failFast(502, "no part of the conversation is compressible (nothing left to fold)", false);
|
|
59078
|
-
}
|
|
59137
|
+
if ((prepared.nudge?.compressibleRanges ?? []).length === 0 && payloadEstimate < limit) {
|
|
59138
|
+
log2("warn", `[${session.id}] preflight trigger fired on a stale baseline (~${tokenCount}) but the payload fits (~${payloadEstimate}/${limit}); forwarding as-is`);
|
|
59139
|
+
return prepared;
|
|
59079
59140
|
}
|
|
59080
59141
|
log2("warn", `[${session.id}] context ${tokenCount} tokens exceeds model window ${limit} (model=${model}); preflight compressing before forward`);
|
|
59081
59142
|
const { upstreamUrl, headers, proxyUrl } = buildForwardTarget(req, opts, route, affinity, instanceId);
|
|
@@ -59084,32 +59145,41 @@ async function preflightCompressIfNeeded(prepared, runPrepare, req, res, opts, c
|
|
|
59084
59145
|
if (!res.writableEnded) clientAbort.abort();
|
|
59085
59146
|
});
|
|
59086
59147
|
const started = Date.now();
|
|
59087
|
-
|
|
59088
|
-
|
|
59089
|
-
|
|
59090
|
-
|
|
59091
|
-
|
|
59092
|
-
|
|
59093
|
-
|
|
59094
|
-
|
|
59095
|
-
|
|
59096
|
-
|
|
59097
|
-
|
|
59098
|
-
|
|
59099
|
-
|
|
59100
|
-
|
|
59101
|
-
|
|
59102
|
-
|
|
59103
|
-
|
|
59104
|
-
|
|
59105
|
-
|
|
59148
|
+
let stopHold;
|
|
59149
|
+
const holdTimer = setTimeout(() => {
|
|
59150
|
+
stopHold = beginPreflightHold(res, prepared, log2);
|
|
59151
|
+
}, preflightHoldGraceMs());
|
|
59152
|
+
holdTimer.unref();
|
|
59153
|
+
let result;
|
|
59154
|
+
try {
|
|
59155
|
+
result = await preflightCompress(
|
|
59156
|
+
{
|
|
59157
|
+
core,
|
|
59158
|
+
session,
|
|
59159
|
+
config,
|
|
59160
|
+
prompts: prepared.prompts ?? defaultPrompts,
|
|
59161
|
+
protocol: prepared.protocol,
|
|
59162
|
+
url: upstreamUrl,
|
|
59163
|
+
headers,
|
|
59164
|
+
model,
|
|
59165
|
+
proxyUrl,
|
|
59166
|
+
signal: clientAbort.signal,
|
|
59167
|
+
log: log2,
|
|
59168
|
+
imageFloor: imageTokens,
|
|
59169
|
+
wireOverhead: overheadEstimate
|
|
59170
|
+
},
|
|
59171
|
+
prepared.originalMessages
|
|
59172
|
+
);
|
|
59173
|
+
} finally {
|
|
59174
|
+
clearTimeout(holdTimer);
|
|
59175
|
+
stopHold?.();
|
|
59176
|
+
}
|
|
59106
59177
|
if (result.compressedRanges > 0) {
|
|
59107
59178
|
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`);
|
|
59108
59179
|
const rebuilt = runPrepare();
|
|
59109
59180
|
session.stats.requests -= 1;
|
|
59110
|
-
|
|
59111
|
-
|
|
59112
|
-
} else if (unknownBaseline ? result.fitsWindow : estimateCoreMessages(prepared.processedMessages) + overheadEstimate + imageTokens < limit) {
|
|
59181
|
+
if (estimateCoreMessages(rebuilt.processedMessages) + overheadEstimate + imageTokens < limit) return rebuilt;
|
|
59182
|
+
} else if (estimateCoreMessages(prepared.processedMessages) + overheadEstimate + imageTokens < limit) {
|
|
59113
59183
|
log2("warn", `[${session.id}] preflight made no progress but the payload fits; forwarding as-is`);
|
|
59114
59184
|
return prepared;
|
|
59115
59185
|
}
|
|
@@ -59124,7 +59194,7 @@ async function preflightCompressIfNeeded(prepared, runPrepare, req, res, opts, c
|
|
|
59124
59194
|
async function forward(req, res, opts, body, prepared, core, config, log2, route, instanceId, affinity) {
|
|
59125
59195
|
if (prepared?.codexForge) {
|
|
59126
59196
|
log2("info", `[${prepared.session.id}] codex compact served locally (${prepared.codexForge.kind}); upstream not contacted`);
|
|
59127
|
-
res.writeHead(200, { "content-type": prepared.codexForge.contentType });
|
|
59197
|
+
if (!res.headersSent) res.writeHead(200, { "content-type": prepared.codexForge.contentType });
|
|
59128
59198
|
res.end(prepared.codexForge.body);
|
|
59129
59199
|
return;
|
|
59130
59200
|
}
|
|
@@ -59377,6 +59447,18 @@ ${hdrText}
|
|
|
59377
59447
|
if (bodyText.length > 600) snippet += " \u2026";
|
|
59378
59448
|
if (!snippet) snippet = "(no body)";
|
|
59379
59449
|
log("warn", `[${errSid}] \u2190 upstream ${upstream.status}${reqIdText}: ${snippet}`);
|
|
59450
|
+
if (res.headersSent) {
|
|
59451
|
+
if (prepared?.stream) {
|
|
59452
|
+
emitStreamError(res, prepared.protocol, `upstream HTTP ${upstream.status}: ${snippet}`, (m2) => log("info", m2));
|
|
59453
|
+
} else {
|
|
59454
|
+
try {
|
|
59455
|
+
res.end(errBody ?? void 0);
|
|
59456
|
+
} catch {
|
|
59457
|
+
}
|
|
59458
|
+
}
|
|
59459
|
+
clearUpstreamTimer();
|
|
59460
|
+
return;
|
|
59461
|
+
}
|
|
59380
59462
|
const errHeaders = { ...respHeaders };
|
|
59381
59463
|
delete errHeaders["content-length"];
|
|
59382
59464
|
delete errHeaders["transfer-encoding"];
|
|
@@ -59385,7 +59467,7 @@ ${hdrText}
|
|
|
59385
59467
|
clearUpstreamTimer();
|
|
59386
59468
|
return;
|
|
59387
59469
|
}
|
|
59388
|
-
res.writeHead(upstream.status, respHeaders);
|
|
59470
|
+
if (!res.headersSent) res.writeHead(upstream.status, respHeaders);
|
|
59389
59471
|
if (!upstream.body) {
|
|
59390
59472
|
res.end();
|
|
59391
59473
|
clearUpstreamTimer();
|