billion-context 0.1.88 → 0.1.89

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 CHANGED
@@ -47935,6 +47935,19 @@ function detectRoleRejection(status, bodyText) {
47935
47935
  }
47936
47936
  return null;
47937
47937
  }
47938
+ function detectSystemPlacementError(status, bodyText) {
47939
+ if (status !== 400) return false;
47940
+ const head = bodyText.slice(0, 4096);
47941
+ if (!/system/i.test(head)) return false;
47942
+ const norm = head.replace(/['"`[\](){}]/g, " ");
47943
+ const PLACEMENT_MARKERS = [
47944
+ /\b(multiple|more\s+than\s+one|exactly\s+one|only\s+one|single|another|second|third)\s+system/i,
47945
+ /\b[2-9]\d*\s+system\s+messages?\b/i,
47946
+ /system\s+messages?\b[^.\n]{0,50}\bindex\s*\d+\b/i,
47947
+ /(system\s+messages?|system\s+roles?)\b[^.\n]{0,50}\b(beginning|start|front|first\s+message|must\s+be\s+first)/i
47948
+ ];
47949
+ return PLACEMENT_MARKERS.some((re2) => re2.test(norm));
47950
+ }
47938
47951
  function applyCompatRoles(body, protocol, roles) {
47939
47952
  if (Object.keys(roles).length === 0) return { body, rewritten: 0 };
47940
47953
  let parsed;
@@ -51147,6 +51160,11 @@ function estimateRawBodyTokens(parsed) {
51147
51160
  walk(parsed);
51148
51161
  return tokens;
51149
51162
  }
51163
+ function estimateCoreMessagesUpper(messages) {
51164
+ let chars = 0;
51165
+ for (const m2 of messages) chars += (m2.text ?? "").length;
51166
+ return chars;
51167
+ }
51150
51168
  function rangeChars2(messages, startIdx, endIdx) {
51151
51169
  let chars = 0;
51152
51170
  for (let i = startIdx; i <= endIdx && i < messages.length; i++) {
@@ -51166,16 +51184,16 @@ ${text}`);
51166
51184
  }
51167
51185
  return parts.join("\n\n");
51168
51186
  }
51169
- function splitChunks(messages, startIdx, endIdx, budgetTokens) {
51187
+ function splitChunks(messages, startIdx, endIdx, budget, minUnits, countText = defaultCountTokens) {
51170
51188
  const chunks = [];
51171
51189
  let cur = startIdx;
51172
51190
  while (cur <= endIdx) {
51173
- let tokens = 0;
51191
+ let total = 0;
51174
51192
  let last = cur;
51175
51193
  for (let i = cur; i <= endIdx; i++) {
51176
- const t = defaultCountTokens(messages[i].text ?? "");
51177
- if (tokens + t > budgetTokens && i > cur) break;
51178
- tokens += t;
51194
+ const t = countText(messages[i].text ?? "");
51195
+ if (total + t > budget && i > cur && (minUnits <= 0 || total >= minUnits)) break;
51196
+ total += t;
51179
51197
  last = i;
51180
51198
  }
51181
51199
  chunks.push([cur, last]);
@@ -51262,11 +51280,14 @@ function noEmergencyTruncate(config) {
51262
51280
  }
51263
51281
  async function preflightCompress(deps, messages) {
51264
51282
  const limit = deps.config.modelContextLimit;
51265
- const result = { compressedRanges: 0, savedTokens: 0, payloadEstimate: estimateCoreMessages(messages) + (deps.imageFloor ?? 0) + (deps.wireOverhead ?? 0) };
51283
+ const result = { compressedRanges: 0, savedTokens: 0, payloadEstimate: estimateCoreMessages(messages) + (deps.imageFloor ?? 0) + (deps.wireOverhead ?? 0), fitsWindow: true };
51266
51284
  if (limit <= 0) return result;
51267
51285
  const budget = Math.max(MIN_CHUNK_TOKENS, Math.floor(limit * CHUNK_FRACTION));
51268
51286
  const minChars = deps.config.compress.minCompressRange;
51269
- let currentTokens = deps.session.stats.lastInputTokens;
51287
+ const baselineKnown = deps.unknownBaseline !== true;
51288
+ const countText = baselineKnown ? defaultCountTokens : (text) => text.length;
51289
+ let currentTokens = baselineKnown ? deps.session.stats.lastInputTokens : estimateCoreMessagesUpper(messages);
51290
+ let finalUpper = baselineKnown ? 0 : estimateCoreMessagesUpper(messages);
51270
51291
  let startTokens = -1;
51271
51292
  let failure;
51272
51293
  let activeConfig = deps.config;
@@ -51290,6 +51311,10 @@ async function preflightCompress(deps, messages) {
51290
51311
  });
51291
51312
  deps.session.state = turn.state;
51292
51313
  currentTokens = Math.max(deps.session.stats.lastInputTokens, estimateCoreMessages(turn.messages) + (deps.imageFloor ?? 0) + (deps.wireOverhead ?? 0));
51314
+ if (!baselineKnown) {
51315
+ finalUpper = estimateCoreMessagesUpper(turn.messages) + (deps.imageFloor ?? 0) + (deps.wireOverhead ?? 0);
51316
+ currentTokens = Math.max(currentTokens, finalUpper);
51317
+ }
51293
51318
  result.payloadEstimate = estimateCoreMessages(turn.messages) + (deps.imageFloor ?? 0) + (deps.wireOverhead ?? 0);
51294
51319
  if (startTokens < 0) startTokens = currentTokens;
51295
51320
  if (currentTokens < limit) break;
@@ -51325,7 +51350,7 @@ async function preflightCompress(deps, messages) {
51325
51350
  continue;
51326
51351
  }
51327
51352
  rangesTried += 1;
51328
- for (const [cs2, ce2] of splitChunks(messages, startIdx, endIdx, budget)) {
51353
+ for (const [cs2, ce2] of splitChunks(messages, startIdx, endIdx, budget, baselineKnown ? 0 : minChars, countText)) {
51329
51354
  if (currentTokens < limit) break;
51330
51355
  if (deps.signal?.aborted) {
51331
51356
  failure = ABORTED_FAILURE;
@@ -51384,7 +51409,8 @@ async function preflightCompress(deps, messages) {
51384
51409
  break;
51385
51410
  }
51386
51411
  const compressed = deps.session.stats.compressCreditTokens - creditBefore;
51387
- currentTokens = Math.max(0, currentTokens - compressed + defaultCountTokens(summary));
51412
+ const folded = baselineKnown ? compressed : rangeChars2(messages, cs2, ce2);
51413
+ currentTokens = Math.max(0, currentTokens - folded + countText(summary));
51388
51414
  deps.session.stats.lastInputTokens += defaultCountTokens(summary);
51389
51415
  appliedThisRound += 1;
51390
51416
  result.compressedRanges += 1;
@@ -51409,6 +51435,7 @@ async function preflightCompress(deps, messages) {
51409
51435
  if (result.compressedRanges > 0) deps.session.stats.lastInputTokens = currentTokens;
51410
51436
  result.savedTokens = Math.max(0, startTokens - currentTokens);
51411
51437
  if (currentTokens >= limit) result.failure = failure;
51438
+ result.fitsWindow = baselineKnown ? result.payloadEstimate < limit : finalUpper < limit;
51412
51439
  return result;
51413
51440
  }
51414
51441
 
@@ -52154,17 +52181,65 @@ var MIN_USAGE = 0.9;
52154
52181
  var WINDOW_MS = 15 * 60 * 1e3;
52155
52182
  var MIN_EVENTS = 3;
52156
52183
  var MAX_TRACKED_SESSIONS = 512;
52184
+ var RETRACT_MARGIN_PCT = 0.03;
52185
+ var RETRACT_MIN_DELTA = 256;
52157
52186
  var states = /* @__PURE__ */ new Map();
52158
- function resolvedWindow2(session) {
52187
+ function resolveConfirmedLimit(session, model) {
52188
+ const md = session.metadata ?? {};
52189
+ const map = md.confirmedContextLimits;
52190
+ return (model ? map?.[model] : void 0) ?? md.confirmedContextLimit;
52191
+ }
52192
+ function resolveSpeculativeLimit(session, model) {
52193
+ const md = session.metadata ?? {};
52194
+ const map = md.learnedContextLimits;
52195
+ return (model ? map?.[model] : void 0) ?? md.learnedContextLimit;
52196
+ }
52197
+ function resolveLearnedLimit(session, model) {
52198
+ const perModel = model ? resolveConfirmedLimit(session, model) ?? resolveSpeculativeLimit(session, model) : void 0;
52199
+ return perModel ?? resolveConfirmedLimit(session) ?? resolveSpeculativeLimit(session);
52200
+ }
52201
+ function retractStaleLearnedLimits(session, model) {
52202
+ const x = session.stats?.lastInputTokens ?? 0;
52203
+ if (!(x > 0)) return false;
52204
+ const stale = (v2) => typeof v2 === "number" && v2 > 0 && x - v2 >= Math.max(RETRACT_MIN_DELTA, v2 * RETRACT_MARGIN_PCT);
52205
+ const md = session.metadata ?? {};
52206
+ const removed = [];
52207
+ const cm = md.confirmedContextLimits;
52208
+ const lm = md.learnedContextLimits;
52209
+ if (model) {
52210
+ if (cm && stale(cm[model])) {
52211
+ removed.push(`confirmed ${cm[model]}`);
52212
+ delete cm[model];
52213
+ }
52214
+ if (lm && stale(lm[model])) {
52215
+ removed.push(`learned ${lm[model]}`);
52216
+ delete lm[model];
52217
+ }
52218
+ }
52219
+ if (stale(md.confirmedContextLimit)) {
52220
+ removed.push(`confirmed ${String(md.confirmedContextLimit)}`);
52221
+ delete md.confirmedContextLimit;
52222
+ }
52223
+ if (stale(md.learnedContextLimit)) {
52224
+ removed.push(`learned ${String(md.learnedContextLimit)}`);
52225
+ delete md.learnedContextLimit;
52226
+ }
52227
+ if (removed.length === 0) return false;
52228
+ session.metadata = md;
52229
+ log("warn", `[${session.id}] retracted stale context window(s) [${removed.join(", ")}] for ${model ?? "(unknown model)"} \u2014 a later turn succeeded at ${x} input tokens above them; using the configured window again`);
52230
+ markDirty(session);
52231
+ return true;
52232
+ }
52233
+ function resolvedWindow2(session, model) {
52159
52234
  const md = session.metadata ?? {};
52160
- const learned = md.learnedContextLimit;
52235
+ const learned = resolveLearnedLimit(session, model);
52161
52236
  const effective = md.effectiveContextLimit;
52162
52237
  const candidates = [learned, effective].filter((v2) => typeof v2 === "number" && v2 > 0);
52163
52238
  if (candidates.length === 0) return 0;
52164
52239
  return Math.min(...candidates);
52165
52240
  }
52166
52241
  function noteWeakOverflow(session, opts) {
52167
- const window2 = resolvedWindow2(session);
52242
+ const window2 = resolvedWindow2(session, opts.model);
52168
52243
  if (window2 <= 0) return;
52169
52244
  const input = opts.inputTokens && opts.inputTokens > 0 ? opts.inputTokens : session.stats?.lastInputTokens ?? 0;
52170
52245
  if (input <= 0) return;
@@ -52184,20 +52259,26 @@ function noteWeakOverflow(session, opts) {
52184
52259
  }
52185
52260
  states.delete(session.id);
52186
52261
  const md = session.metadata ?? {};
52187
- if (md.learnedContextLimits === void 0) md.learnedContextLimits = {};
52188
- const learnedMap = md.learnedContextLimits;
52189
52262
  const reqModel = opts.model;
52190
- const prev = (reqModel ? learnedMap[reqModel] : void 0) ?? md.learnedContextLimit;
52191
- if (prev === void 0 || input < prev) {
52192
- if (reqModel) learnedMap[reqModel] = input;
52193
- else md.learnedContextLimit = input;
52194
- session.metadata = md;
52195
- log("warn", `[${session.id}] weak overflow confirmed (${MIN_EVENTS}\xD7 high-usage failures, ${opts.reason}) \u2014 learned conservative window ${input} for ${reqModel ?? "(unknown model)"} (was ${prev ?? "unset"}); arming emergency shrink`);
52263
+ const confirmed = resolveConfirmedLimit(session, reqModel);
52264
+ const armInput = confirmed !== void 0 && confirmed > 0 ? Math.min(input, confirmed) : input;
52265
+ if (confirmed !== void 0 && confirmed > 0) {
52266
+ log("warn", `[${session.id}] weak overflow confirmed (${MIN_EVENTS}\xD7 high-usage failures, ${opts.reason}) \u2014 confirmed window ${confirmed} governs (failing input ${input}); arming emergency shrink only, learned window untouched`);
52196
52267
  } else {
52197
- log("warn", `[${session.id}] weak overflow confirmed (${MIN_EVENTS}\xD7 high-usage failures, ${opts.reason}) \u2014 conservative window ${input} not below learned ${prev}; arming emergency shrink only`);
52268
+ if (md.learnedContextLimits === void 0) md.learnedContextLimits = {};
52269
+ const learnedMap = md.learnedContextLimits;
52270
+ const prev = (reqModel ? learnedMap[reqModel] : void 0) ?? md.learnedContextLimit;
52271
+ if (prev === void 0 || input < prev) {
52272
+ if (reqModel) learnedMap[reqModel] = input;
52273
+ else md.learnedContextLimit = input;
52274
+ session.metadata = md;
52275
+ log("warn", `[${session.id}] weak overflow confirmed (${MIN_EVENTS}\xD7 high-usage failures, ${opts.reason}) \u2014 learned conservative window ${input} for ${reqModel ?? "(unknown model)"} (was ${prev ?? "unset"}); arming emergency shrink`);
52276
+ } else {
52277
+ log("warn", `[${session.id}] weak overflow confirmed (${MIN_EVENTS}\xD7 high-usage failures, ${opts.reason}) \u2014 conservative window ${input} not below learned ${prev}; arming emergency shrink only`);
52278
+ }
52198
52279
  }
52199
- if (!session.stats) session.stats = { lastInputTokens: input };
52200
- else session.stats.lastInputTokens = Math.max(session.stats.lastInputTokens, input);
52280
+ if (!session.stats) session.stats = { lastInputTokens: armInput };
52281
+ else session.stats.lastInputTokens = Math.max(session.stats.lastInputTokens, armInput);
52201
52282
  markDirty(session);
52202
52283
  }
52203
52284
 
@@ -52310,6 +52391,7 @@ var CONTEXT_OVERFLOW_PATTERNS = [
52310
52391
  /token limit exceeded/i,
52311
52392
  // #554: llama.cpp-family "exceed_context_size_error (A / B > W)" — carried by
52312
52393
  // side requests that bypass preflight; without it the learned channel learns nothing.
52394
+ // #570: its body also carries the real window, see parseOverflowWindow.
52313
52395
  /exceed[_\s]?context[_\s]?size/i
52314
52396
  ];
52315
52397
  function toTokenNumber(s3) {
@@ -53065,15 +53147,17 @@ data: ${JSON.stringify({ type: "response.created", response: { id: createdRespId
53065
53147
  }
53066
53148
  };
53067
53149
  for await (const eventStr of iterSseEvents(upstream)) {
53068
- const type = extractEventType(eventStr);
53150
+ const explicitType = extractEventType(eventStr);
53069
53151
  const dataLine = extractDataLine(eventStr);
53070
- if (!type || !dataLine) continue;
53152
+ if (!dataLine) continue;
53071
53153
  let obj;
53072
53154
  try {
53073
53155
  obj = JSON.parse(dataLine);
53074
53156
  } catch {
53075
53157
  continue;
53076
53158
  }
53159
+ const type = explicitType ?? (typeof obj.type === "string" ? obj.type : null);
53160
+ if (!type) continue;
53077
53161
  const rawBuf = Buffer.from(eventStr + "\n\n", "utf8");
53078
53162
  if (round === 1 && typeof obj.output_index === "number") {
53079
53163
  outputIndex = Math.max(outputIndex, obj.output_index + 1);
@@ -53417,6 +53501,23 @@ function stripFinishReasonChunk(buf) {
53417
53501
  return buf;
53418
53502
  }
53419
53503
  }
53504
+ function patchUsageChunk(eventStr, parsed, u2, hostCredit) {
53505
+ const pu = typeof u2.prompt_tokens === "number" ? u2.prompt_tokens : void 0;
53506
+ const tu = typeof u2.total_tokens === "number" ? u2.total_tokens : void 0;
53507
+ if (hostCredit > 0 && (pu !== void 0 || tu !== void 0)) {
53508
+ const patched = {
53509
+ ...parsed,
53510
+ usage: {
53511
+ ...u2,
53512
+ ...pu !== void 0 ? { prompt_tokens: pu + hostCredit } : {},
53513
+ ...tu !== void 0 ? { total_tokens: tu + hostCredit } : {}
53514
+ }
53515
+ };
53516
+ const out = eventStr.split("\n").map((l) => l.startsWith("data:") ? `data: ${JSON.stringify(patched)}` : l).join("\n");
53517
+ return Buffer.from(out + "\n\n", "utf8");
53518
+ }
53519
+ return Buffer.from(eventStr + "\n\n", "utf8");
53520
+ }
53420
53521
  function createOpenaiAdapter(requestBody, clientSystem, hostCredit = 0) {
53421
53522
  const model = requestBody.model ?? "unknown";
53422
53523
  let responseId = `chatcmpl-proxy-${Date.now()}`;
@@ -53593,6 +53694,9 @@ function createOpenaiAdapter(requestBody, clientSystem, hostCredit = 0) {
53593
53694
  outputTokens: typeof u2.completion_tokens === "number" ? u2.completion_tokens : void 0,
53594
53695
  cachedTokens: typeof pd?.cached_tokens === "number" ? pd.cached_tokens : void 0
53595
53696
  };
53697
+ if (sawRealToolCall) {
53698
+ yield { kind: "meta", chunk: patchUsageChunk(eventStr, parsed, u2, hostCredit) };
53699
+ }
53596
53700
  }
53597
53701
  continue;
53598
53702
  }
@@ -53611,23 +53715,7 @@ function createOpenaiAdapter(requestBody, clientSystem, hostCredit = 0) {
53611
53715
  cachedTokens: typeof pd?.cached_tokens === "number" ? pd.cached_tokens : void 0
53612
53716
  };
53613
53717
  if (sawRealToolCall) {
53614
- let chunk = rawBuf;
53615
- if (hostCredit > 0 && u2) {
53616
- const pu = typeof u2.prompt_tokens === "number" ? u2.prompt_tokens : void 0;
53617
- const tu = typeof u2.total_tokens === "number" ? u2.total_tokens : void 0;
53618
- if (pu !== void 0 || tu !== void 0) {
53619
- const patched = {
53620
- ...parsed,
53621
- usage: {
53622
- ...u2,
53623
- ...pu !== void 0 ? { prompt_tokens: pu + hostCredit } : {},
53624
- ...tu !== void 0 ? { total_tokens: tu + hostCredit } : {}
53625
- }
53626
- };
53627
- const out = eventStr.split("\n").map((l) => l.startsWith("data:") ? `data: ${JSON.stringify(patched)}` : l).join("\n");
53628
- chunk = Buffer.from(out + "\n\n", "utf8");
53629
- }
53630
- }
53718
+ const chunk = patchUsageChunk(eventStr, parsed, u2 ?? {}, hostCredit);
53631
53719
  yield { kind: "meta", chunk };
53632
53720
  yield { kind: "done", finishReason, suppressCompletion: true };
53633
53721
  continue;
@@ -54703,6 +54791,35 @@ data: ${JSON.stringify({ type: "message_delta", delta: { stop_reason: "end_turn"
54703
54791
  safeWrite(res, `event: message_stop
54704
54792
  data: ${JSON.stringify({ type: "message_stop" })}
54705
54793
 
54794
+ `);
54795
+ }
54796
+ } catch {
54797
+ } finally {
54798
+ try {
54799
+ res.end();
54800
+ } catch {
54801
+ }
54802
+ }
54803
+ }
54804
+ function emitPreflightError(res, protocol, error, log2) {
54805
+ const err2 = { type: "server_error", code: "preflight_compress_failed", message: error.message, retryable: error.retryable };
54806
+ log2?.(`[acp-proxy: preflight failed after early response commit \u2014 delivering in-band: ${error.message}]`);
54807
+ try {
54808
+ if (protocol === "openai") {
54809
+ safeWrite(res, `data: ${JSON.stringify({ error: err2 })}
54810
+
54811
+ data: [DONE]
54812
+
54813
+ `);
54814
+ } else if (protocol === "responses") {
54815
+ safeWrite(res, `event: error
54816
+ data: ${JSON.stringify({ type: "error", code: err2.code, message: err2.message })}
54817
+
54818
+ `);
54819
+ } else {
54820
+ safeWrite(res, `event: error
54821
+ data: ${JSON.stringify({ type: "error", error: { type: "server_error", code: err2.code, message: err2.message } })}
54822
+
54706
54823
  `);
54707
54824
  }
54708
54825
  } catch {
@@ -58239,8 +58356,7 @@ ${bodyBuffer.toString("utf8")}`);
58239
58356
  restoreOutputBudget(parsed, session, log2);
58240
58357
  if (!countTokens && !responsesCompact && protocol !== null && isSideRequest(parsed)) {
58241
58358
  const reqModel2 = parsed.model;
58242
- const learnedMap2 = session.metadata.learnedContextLimits;
58243
- const learnedLimit2 = (reqModel2 && learnedMap2 ? learnedMap2[reqModel2] : void 0) ?? session.metadata.learnedContextLimit;
58359
+ const learnedLimit2 = resolveLearnedLimit(session, reqModel2);
58244
58360
  const guard = sideRequestGuard(parsed, protocol, reqConfig.modelContextLimit, learnedLimit2);
58245
58361
  if (guard.blocked) {
58246
58362
  log2("warn", `[${session.id}] side request (~${guard.estimate} tokens) \u2265 effective window ${guard.limit} (model=${reqModel2 ?? "?"}) \u2014 NOT forwarded: guaranteed upstream 400 (side requests bypass preflight by design, #388)`);
@@ -58272,23 +58388,24 @@ ${bodyBuffer.toString("utf8")}`);
58272
58388
  return;
58273
58389
  }
58274
58390
  const reqModel = parsed.model;
58275
- const learnedMap = session.metadata.learnedContextLimits;
58276
- const learnedLimit = (reqModel && learnedMap ? learnedMap[reqModel] : void 0) ?? session.metadata.learnedContextLimit;
58391
+ retractStaleLearnedLimits(session, reqModel);
58392
+ const confirmedLimit = resolveConfirmedLimit(session, reqModel);
58393
+ const learnedLimit = confirmedLimit ?? resolveSpeculativeLimit(session, reqModel);
58277
58394
  if (learnedLimit && learnedLimit > 0 && learnedLimit < reqConfig.modelContextLimit) {
58278
58395
  const resolved = reqConfig.modelContextLimit;
58279
58396
  reqConfig = { ...reqConfig, modelContextLimit: learnedLimit };
58280
58397
  nativeFromFallback = false;
58281
- log2("info", `[${session.id}] self-healed context window: ${resolved} \u2192 ${learnedLimit} (learned from an upstream overflow)`);
58398
+ log2("info", `[${session.id}] self-healed context window: ${resolved} \u2192 ${learnedLimit} (${confirmedLimit !== void 0 ? "confirmed by an upstream overflow error" : "weak-overflow heuristic"})`);
58282
58399
  } else if (nativeFromFallback && reqModel) {
58283
58400
  const prevInput = session.stats.lastInputTokens ?? 0;
58284
58401
  const prevWindow = session.metadata.lastTurnWindow;
58285
58402
  const resolved = reqConfig.modelContextLimit;
58286
58403
  if (prevWindow !== void 0 && prevInput > prevWindow && prevInput > resolved && prevInput >= 1e3) {
58287
- const map = session.metadata.learnedContextLimits ?? {};
58404
+ const map = session.metadata.confirmedContextLimits ?? {};
58288
58405
  const prev = map[reqModel];
58289
58406
  if (prev === void 0 || prevInput > prev) {
58290
58407
  map[reqModel] = prevInput;
58291
- session.metadata.learnedContextLimits = map;
58408
+ session.metadata.confirmedContextLimits = map;
58292
58409
  markDirty(session);
58293
58410
  }
58294
58411
  reqConfig = { ...reqConfig, modelContextLimit: prevInput };
@@ -58342,23 +58459,42 @@ ${bodyBuffer.toString("utf8")}`);
58342
58459
  parsed.model,
58343
58460
  route,
58344
58461
  affinity,
58462
+ anonAffinity !== null,
58345
58463
  log2,
58346
58464
  instanceId
58347
58465
  );
58348
58466
  if (isPreflightFailFast(outcome)) {
58349
- if (outcome.respond && !res.headersSent && !res.destroyed) {
58350
- res.writeHead(outcome.status, {
58351
- "content-type": "application/json",
58352
- ...outcome.status === 503 ? { "retry-after": "30" } : {}
58353
- });
58354
- res.end(JSON.stringify({
58355
- error: {
58356
- type: "server_error",
58357
- code: "preflight_compress_failed",
58358
- message: outcome.message,
58359
- retryable: outcome.retryable
58467
+ if (outcome.respond && !res.destroyed) {
58468
+ if (res.headersSent) {
58469
+ if (prepared.stream) {
58470
+ emitPreflightError(res, prepared.protocol, { message: outcome.message, retryable: outcome.retryable }, (m2) => log2("warn", m2));
58471
+ } else {
58472
+ try {
58473
+ res.end(JSON.stringify({
58474
+ error: {
58475
+ type: "server_error",
58476
+ code: "preflight_compress_failed",
58477
+ message: outcome.message,
58478
+ retryable: outcome.retryable
58479
+ }
58480
+ }));
58481
+ } catch {
58482
+ }
58360
58483
  }
58361
- }));
58484
+ } else {
58485
+ res.writeHead(outcome.status, {
58486
+ "content-type": "application/json",
58487
+ ...outcome.status === 503 ? { "retry-after": "30" } : {}
58488
+ });
58489
+ res.end(JSON.stringify({
58490
+ error: {
58491
+ type: "server_error",
58492
+ code: "preflight_compress_failed",
58493
+ message: outcome.message,
58494
+ retryable: outcome.retryable
58495
+ }
58496
+ }));
58497
+ }
58362
58498
  }
58363
58499
  return;
58364
58500
  }
@@ -58477,6 +58613,11 @@ function armHostUsageCredit(session, originalMessages, processedMessages, log2)
58477
58613
  log2("info", `[${session.id}] host usage backfill armed: +${session.hostCreditTokens} tok (forwarded view is folded); host usage will report the uncompressed baseline`);
58478
58614
  }
58479
58615
  }
58616
+ function effectiveTokenCount(session, msgs) {
58617
+ if (session.stats.lastInputTokens > 0) return session.stats.lastInputTokens;
58618
+ if (!session.metadata.anonymousPrefixAffinity) return 0;
58619
+ return estimateCoreMessagesUpper(msgs);
58620
+ }
58480
58621
  function prepareAnthropic(parsed, req, opts, core, config, prompts, log2, session, pluginMode) {
58481
58622
  const sessionId = session.id;
58482
58623
  const stream2 = parsed.stream === true;
@@ -58501,7 +58642,7 @@ function prepareAnthropic(parsed, req, opts, core, config, prompts, log2, sessio
58501
58642
  const { msgs, cacheControls } = anthropicToCore(parsed);
58502
58643
  originalMessages = msgs;
58503
58644
  extractSystem(parsed.system);
58504
- const tokenCount = session.stats.lastInputTokens;
58645
+ const tokenCount = effectiveTokenCount(session, msgs);
58505
58646
  const activeBefore = new Set(session.state.blocks.filter((b2) => b2.active).map((b2) => b2.blockId));
58506
58647
  const turn = core.processTurn({ messages: msgs, state: session.state, config, tokenCount, renderTags: "text-only" });
58507
58648
  session.state = turn.state;
@@ -58622,7 +58763,7 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session,
58622
58763
  const { msgs, systemText } = openaiToCore(parsed);
58623
58764
  openaiSystemText = systemText;
58624
58765
  originalMessages = msgs;
58625
- const tokenCount = session.stats.lastInputTokens;
58766
+ const tokenCount = effectiveTokenCount(session, msgs);
58626
58767
  const activeBefore = new Set(session.state.blocks.filter((b2) => b2.active).map((b2) => b2.blockId));
58627
58768
  const turn = core.processTurn({ messages: msgs, state: session.state, config, tokenCount, renderTags: "text-only" });
58628
58769
  session.state = turn.state;
@@ -58727,7 +58868,7 @@ function prepareResponses(parsed, req, opts, core, config, prompts, log2, sessio
58727
58868
  if (process.env.ACP_DEBUG) {
58728
58869
  log2("info", `[${sessionId}] input items: ${Array.isArray(parsed.input) ? parsed.input.map((i) => i.type).join(",") : "(string)"}`);
58729
58870
  }
58730
- const tokenCount = session.stats.lastInputTokens;
58871
+ const tokenCount = effectiveTokenCount(session, msgs);
58731
58872
  const turn = core.processTurn({ messages: msgs, state: session.state, config, tokenCount, renderTags });
58732
58873
  session.state = turn.state;
58733
58874
  session.stats.compressCreditTokens = 0;
@@ -59025,17 +59166,57 @@ function buildForwardTarget(req, opts, route, affinity, hopMarker) {
59025
59166
  function isPreflightFailFast(outcome) {
59026
59167
  return "failFast" in outcome;
59027
59168
  }
59028
- async function preflightCompressIfNeeded(prepared, runPrepare, req, res, opts, core, config, model, route, affinity, log2, instanceId) {
59169
+ var PREFLIGHT_HOLD_GRACE_DEFAULT_MS = 3e4;
59170
+ var PREFLIGHT_KEEPALIVE_MS = 15e3;
59171
+ function preflightHoldGraceMs() {
59172
+ const raw = process.env.BILI_PREFLIGHT_HOLD_MS;
59173
+ if (!raw) return PREFLIGHT_HOLD_GRACE_DEFAULT_MS;
59174
+ const v2 = Number(raw);
59175
+ return Number.isFinite(v2) && v2 >= 0 ? Math.floor(v2) : PREFLIGHT_HOLD_GRACE_DEFAULT_MS;
59176
+ }
59177
+ function beginPreflightHold(res, prepared, log2) {
59178
+ if (res.headersSent || res.destroyed || res.writableEnded) return void 0;
59179
+ const sid = prepared.session.id;
59180
+ const keepAlive = prepared.stream ? ": bili-preflight\n\n" : " ";
59181
+ try {
59182
+ if (prepared.stream) {
59183
+ res.writeHead(200, {
59184
+ "content-type": "text/event-stream",
59185
+ "cache-control": "no-cache",
59186
+ "x-accel-buffering": "no",
59187
+ "x-bili-preflight": "compressing"
59188
+ });
59189
+ } else {
59190
+ res.writeHead(200, { "content-type": "application/json", "x-bili-preflight": "compressing" });
59191
+ }
59192
+ } catch {
59193
+ return void 0;
59194
+ }
59195
+ 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)`);
59196
+ try {
59197
+ res.write(keepAlive);
59198
+ } catch {
59199
+ }
59200
+ const iv = setInterval(() => {
59201
+ try {
59202
+ res.write(keepAlive);
59203
+ } catch {
59204
+ clearInterval(iv);
59205
+ }
59206
+ }, PREFLIGHT_KEEPALIVE_MS);
59207
+ return () => clearInterval(iv);
59208
+ }
59209
+ async function preflightCompressIfNeeded(prepared, runPrepare, req, res, opts, core, config, model, route, affinity, anonymous, log2, instanceId) {
59029
59210
  const session = prepared.session;
59030
59211
  const limit = config.modelContextLimit;
59031
59212
  const imageTokens = imageTokensInRawBody(prepared.protocol, prepared.body);
59032
59213
  const textEstimate = estimateCoreMessages(prepared.processedMessages);
59033
59214
  const overheadEstimate = estimateWireOverhead(prepared.protocol, prepared.body);
59034
59215
  const payloadEstimate = textEstimate + overheadEstimate + imageTokens;
59035
- const tokenCount = Math.max(session.stats.lastInputTokens, payloadEstimate);
59216
+ const unknownBaseline = anonymous && session.stats.lastInputTokens <= 0;
59217
+ const tokenCount = unknownBaseline ? estimateCoreMessagesUpper(prepared.processedMessages) + overheadEstimate + imageTokens : Math.max(session.stats.lastInputTokens, payloadEstimate);
59036
59218
  if (limit <= 0 || !model || tokenCount < limit) return prepared;
59037
- const learnedMap = session.metadata.learnedContextLimits;
59038
- const learnedLimit = (model ? learnedMap?.[model] : void 0) ?? session.metadata.learnedContextLimit;
59219
+ const learnedLimit = resolveLearnedLimit(session, model);
59039
59220
  const noOverflowEvidence = session.stats.lastInputTokens < limit && learnedLimit === void 0;
59040
59221
  if (imageTokens > 0 && textEstimate < limit && noOverflowEvidence) {
59041
59222
  log2("warn", `[${session.id}] image-dominated payload (~${textEstimate} text + ~${imageTokens} image tokens) exceeds window ${limit} by estimate only, no upstream overflow evidence \u2014 forwarding once so the upstream arbitrates billing (#496)`);
@@ -59047,9 +59228,14 @@ async function preflightCompressIfNeeded(prepared, runPrepare, req, res, opts, c
59047
59228
  log2("error", `[${session.id}] preflight fail-fast ${status2} (retryable=${retryable}): ${message}`);
59048
59229
  return { failFast: true, status: status2, message, retryable, respond: !res.writableEnded };
59049
59230
  };
59050
- if ((prepared.nudge?.compressibleRanges ?? []).length === 0 && payloadEstimate < limit) {
59051
- log2("warn", `[${session.id}] preflight trigger fired on a stale baseline (~${tokenCount}) but the payload fits (~${payloadEstimate}/${limit}); forwarding as-is`);
59052
- return prepared;
59231
+ if ((prepared.nudge?.compressibleRanges ?? []).length === 0) {
59232
+ if (!unknownBaseline && payloadEstimate < limit) {
59233
+ log2("warn", `[${session.id}] preflight trigger fired on a stale baseline (~${tokenCount}) but the payload fits (~${payloadEstimate}/${limit}); forwarding as-is`);
59234
+ return prepared;
59235
+ }
59236
+ if (unknownBaseline) {
59237
+ return failFast(502, "no part of the conversation is compressible (nothing left to fold)", false);
59238
+ }
59053
59239
  }
59054
59240
  log2("warn", `[${session.id}] context ${tokenCount} tokens exceeds model window ${limit} (model=${model}); preflight compressing before forward`);
59055
59241
  const { upstreamUrl, headers, proxyUrl } = buildForwardTarget(req, opts, route, affinity, instanceId);
@@ -59058,30 +59244,43 @@ async function preflightCompressIfNeeded(prepared, runPrepare, req, res, opts, c
59058
59244
  if (!res.writableEnded) clientAbort.abort();
59059
59245
  });
59060
59246
  const started = Date.now();
59061
- const result = await preflightCompress(
59062
- {
59063
- core,
59064
- session,
59065
- config,
59066
- prompts: prepared.prompts ?? defaultPrompts,
59067
- protocol: prepared.protocol,
59068
- url: upstreamUrl,
59069
- headers,
59070
- model,
59071
- proxyUrl,
59072
- signal: clientAbort.signal,
59073
- log: log2,
59074
- imageFloor: imageTokens,
59075
- wireOverhead: overheadEstimate
59076
- },
59077
- prepared.originalMessages
59078
- );
59247
+ let stopHold;
59248
+ const holdTimer = setTimeout(() => {
59249
+ stopHold = beginPreflightHold(res, prepared, log2);
59250
+ }, preflightHoldGraceMs());
59251
+ holdTimer.unref();
59252
+ let result;
59253
+ try {
59254
+ result = await preflightCompress(
59255
+ {
59256
+ core,
59257
+ session,
59258
+ config,
59259
+ prompts: prepared.prompts ?? defaultPrompts,
59260
+ protocol: prepared.protocol,
59261
+ url: upstreamUrl,
59262
+ headers,
59263
+ model,
59264
+ proxyUrl,
59265
+ signal: clientAbort.signal,
59266
+ log: log2,
59267
+ imageFloor: imageTokens,
59268
+ wireOverhead: overheadEstimate,
59269
+ unknownBaseline
59270
+ },
59271
+ prepared.originalMessages
59272
+ );
59273
+ } finally {
59274
+ clearTimeout(holdTimer);
59275
+ stopHold?.();
59276
+ }
59079
59277
  if (result.compressedRanges > 0) {
59080
59278
  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`);
59081
59279
  const rebuilt = runPrepare();
59082
59280
  session.stats.requests -= 1;
59083
- if (estimateCoreMessages(rebuilt.processedMessages) + overheadEstimate + imageTokens < limit) return rebuilt;
59084
- } else if (estimateCoreMessages(prepared.processedMessages) + overheadEstimate + imageTokens < limit) {
59281
+ const fits = unknownBaseline ? result.fitsWindow : estimateCoreMessages(rebuilt.processedMessages) + overheadEstimate + imageTokens < limit;
59282
+ if (fits) return rebuilt;
59283
+ } else if (unknownBaseline ? result.fitsWindow : estimateCoreMessages(prepared.processedMessages) + overheadEstimate + imageTokens < limit) {
59085
59284
  log2("warn", `[${session.id}] preflight made no progress but the payload fits; forwarding as-is`);
59086
59285
  return prepared;
59087
59286
  }
@@ -59096,7 +59295,7 @@ async function preflightCompressIfNeeded(prepared, runPrepare, req, res, opts, c
59096
59295
  async function forward(req, res, opts, body, prepared, core, config, log2, route, instanceId, affinity) {
59097
59296
  if (prepared?.codexForge) {
59098
59297
  log2("info", `[${prepared.session.id}] codex compact served locally (${prepared.codexForge.kind}); upstream not contacted`);
59099
- res.writeHead(200, { "content-type": prepared.codexForge.contentType });
59298
+ if (!res.headersSent) res.writeHead(200, { "content-type": prepared.codexForge.contentType });
59100
59299
  res.end(prepared.codexForge.body);
59101
59300
  return;
59102
59301
  }
@@ -59238,28 +59437,46 @@ ${bodyText}`);
59238
59437
  };
59239
59438
  const rejection = detectRoleRejection(upstreamResult.response.status, roleErrText);
59240
59439
  if (rejection && rejection.role !== "system") {
59241
- const fixed = applyCompatRoles(wireBody, compatProtocol, { [rejection.role]: "system" });
59242
- if (fixed.rewritten > 0) {
59440
+ const cp2 = compatProtocol;
59441
+ const wb = wireBody;
59442
+ const remember = (target, rewritten) => {
59443
+ const s3 = prepared?.session;
59444
+ if (s3) {
59445
+ const prev = s3.metadata.learnedCompatRoles ?? {};
59446
+ s3.metadata.learnedCompatRoles = { ...prev, [rejection.role]: target };
59447
+ markDirty(s3);
59448
+ }
59449
+ compatRoles = { ...compatRoles, [rejection.role]: target };
59450
+ const providerKey = new URL(upstreamUrl).origin;
59451
+ log2("info", `[${prepared?.session.id ?? "passthrough"}] [compat] upstream rejected role "${rejection.role}" \u2014 auto-rewrote ${rewritten} message role(s) to "${target}", retry OK (remembered for this session only). To make permanent, add: {"providers":{"${providerKey}":{"compat":{"roles":{"${rejection.role}":"${target}"}}}}`);
59452
+ };
59453
+ const hop = async (target) => {
59454
+ const fixed = applyCompatRoles(wb, cp2, { [rejection.role]: target });
59455
+ if (fixed.rewritten === 0) return "other";
59456
+ let r;
59243
59457
  try {
59244
- const retry = await fetchWithTimeout(upstreamUrl, { ...init, body: fixed.body }, void 0, clientAbort.signal);
59245
- if (retry.response.ok) {
59246
- upstreamResult.clearTimer();
59247
- const s3 = prepared?.session;
59248
- if (s3) {
59249
- const prev = s3.metadata.learnedCompatRoles ?? {};
59250
- s3.metadata.learnedCompatRoles = { ...prev, [rejection.role]: "system" };
59251
- markDirty(s3);
59252
- }
59253
- compatRoles = { ...compatRoles, [rejection.role]: "system" };
59254
- const providerKey = new URL(upstreamUrl).origin;
59255
- log2("info", `[${prepared?.session.id ?? "passthrough"}] [compat] upstream rejected role "${rejection.role}" \u2014 auto-rewrote ${fixed.rewritten} message role(s) to "system", retry OK (remembered for this session only). To make permanent, add: {"providers":{"${providerKey}":{"compat":{"roles":{"${rejection.role}":"system"}}}}`);
59256
- upstreamResult = retry;
59257
- } else {
59258
- retry.clearTimer();
59259
- }
59458
+ r = await fetchWithTimeout(upstreamUrl, { ...init, body: fixed.body }, void 0, clientAbort.signal);
59260
59459
  } catch {
59460
+ return "other";
59261
59461
  }
59262
- }
59462
+ if (r.response.ok) {
59463
+ upstreamResult.clearTimer();
59464
+ remember(target, fixed.rewritten);
59465
+ upstreamResult = r;
59466
+ return "ok";
59467
+ }
59468
+ let errText2 = null;
59469
+ if (r.response.body) {
59470
+ try {
59471
+ errText2 = (await readStreamToBuffer(r.response.body)).toString("utf8");
59472
+ } catch {
59473
+ errText2 = null;
59474
+ }
59475
+ }
59476
+ r.clearTimer();
59477
+ return errText2 !== null && detectSystemPlacementError(r.response.status, errText2) ? "placement-400" : "other";
59478
+ };
59479
+ if (await hop("system") === "placement-400") await hop("user");
59263
59480
  }
59264
59481
  }
59265
59482
  }
@@ -59317,27 +59534,31 @@ ${hdrText}
59317
59534
  } catch {
59318
59535
  reqModel = void 0;
59319
59536
  }
59320
- const learnedMap = s3.metadata.learnedContextLimits ?? {};
59537
+ const confirmedMap = s3.metadata.confirmedContextLimits ?? {};
59321
59538
  if (info.window) {
59322
- const prev = (reqModel ? learnedMap[reqModel] : void 0) ?? s3.metadata.learnedContextLimit;
59323
- if (reqModel) learnedMap[reqModel] = info.window;
59324
- else s3.metadata.learnedContextLimit = info.window;
59325
- s3.metadata.learnedContextLimits = learnedMap;
59539
+ const prev = (reqModel ? confirmedMap[reqModel] : void 0) ?? s3.metadata.confirmedContextLimit;
59540
+ if (reqModel) confirmedMap[reqModel] = info.window;
59541
+ else s3.metadata.confirmedContextLimit = info.window;
59542
+ s3.metadata.confirmedContextLimits = confirmedMap;
59326
59543
  log2("warn", `[${s3.id}] upstream context overflow \u2014 learned real window ${info.window} for ${reqModel ?? "(unknown model)"} (was ${prev ?? "unset"}); arming emergency shrink`);
59327
59544
  } else {
59328
59545
  const payloadEstimate = (prepared.processedMessages.length > 0 ? estimateCoreMessages(prepared.processedMessages) : estimateRawBodyTokens(parsedBody)) + rejectedImageTokens;
59329
- const prev = (reqModel ? learnedMap[reqModel] : void 0) ?? s3.metadata.learnedContextLimit;
59546
+ const prev = (reqModel ? confirmedMap[reqModel] : void 0) ?? s3.metadata.confirmedContextLimit;
59330
59547
  if (payloadEstimate >= 1e3 && (prev === void 0 || payloadEstimate < prev)) {
59331
- if (reqModel) learnedMap[reqModel] = payloadEstimate;
59332
- else s3.metadata.learnedContextLimit = payloadEstimate;
59333
- s3.metadata.learnedContextLimits = learnedMap;
59548
+ if (reqModel) confirmedMap[reqModel] = payloadEstimate;
59549
+ else s3.metadata.confirmedContextLimit = payloadEstimate;
59550
+ s3.metadata.confirmedContextLimits = confirmedMap;
59334
59551
  log2("warn", `[${s3.id}] upstream context overflow (window not parseable) \u2014 learned conservative window ${payloadEstimate} for ${reqModel ?? "(unknown model)"} from rejected payload size (was ${prev ?? "unset"}); arming emergency shrink`);
59335
59552
  } else {
59336
59553
  log2("warn", `[${s3.id}] upstream context overflow (window not parseable): ${info.message}`);
59337
59554
  }
59338
59555
  }
59339
- const floor = info.window ?? (reqModel ? learnedMap[reqModel] : void 0) ?? s3.metadata.learnedContextLimit ?? s3.metadata.effectiveContextLimit ?? 0;
59340
- if (floor > 0) s3.stats.lastInputTokens = Math.max(s3.stats.lastInputTokens, floor);
59556
+ if (info.window) {
59557
+ s3.stats.lastInputTokens = info.window;
59558
+ } else {
59559
+ const floor = (reqModel ? confirmedMap[reqModel] : void 0) ?? s3.metadata.confirmedContextLimit ?? s3.metadata.effectiveContextLimit ?? 0;
59560
+ if (floor > 0) s3.stats.lastInputTokens = Math.max(s3.stats.lastInputTokens, floor);
59561
+ }
59341
59562
  markDirty(s3);
59342
59563
  }
59343
59564
  }
@@ -59349,6 +59570,18 @@ ${hdrText}
59349
59570
  if (bodyText.length > 600) snippet += " \u2026";
59350
59571
  if (!snippet) snippet = "(no body)";
59351
59572
  log("warn", `[${errSid}] \u2190 upstream ${upstream.status}${reqIdText}: ${snippet}`);
59573
+ if (res.headersSent) {
59574
+ if (prepared?.stream) {
59575
+ emitStreamError(res, prepared.protocol, `upstream HTTP ${upstream.status}: ${snippet}`, (m2) => log("info", m2));
59576
+ } else {
59577
+ try {
59578
+ res.end(errBody ?? void 0);
59579
+ } catch {
59580
+ }
59581
+ }
59582
+ clearUpstreamTimer();
59583
+ return;
59584
+ }
59352
59585
  const errHeaders = { ...respHeaders };
59353
59586
  delete errHeaders["content-length"];
59354
59587
  delete errHeaders["transfer-encoding"];
@@ -59357,7 +59590,7 @@ ${hdrText}
59357
59590
  clearUpstreamTimer();
59358
59591
  return;
59359
59592
  }
59360
- res.writeHead(upstream.status, respHeaders);
59593
+ if (!res.headersSent) res.writeHead(upstream.status, respHeaders);
59361
59594
  if (!upstream.body) {
59362
59595
  res.end();
59363
59596
  clearUpstreamTimer();