billion-context 0.1.69 → 0.1.70-pr.459.276

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 CHANGED
@@ -65,7 +65,8 @@ The proxy runs in one of two modes, and **the mode decides who executes
65
65
  | **Summary carrier on the wire** | **the `compress` tool call** | **an `acp_summary` user message** |
66
66
  | System messages on the wire | always exactly 1 (client + prompt) | always exactly 1 (client + prompt) — summaries ride on user messages |
67
67
  | SGLang "single system" 400 (#377) | cannot happen | cannot happen (summaries are user messages, not system) |
68
- | Proxy-injected tools + nudge | none (agent owns compression) | the 4 context tools + nudge (when enabled) |
68
+ | Proxy-injected `compress` tools | none — the agent registers the 4 ACP tools natively | the 4 context tools (when enabled) |
69
+ | Proxy-injected nudge | **yes** — the agent has no nudge channel of its own, so the proxy-side nudge is the proactive compression trigger (preflight alone only fires at the hard limit; #451) | yes (when enabled) |
69
70
 
70
71
  **Why the carriers differ.** In plugin mode the agent owns compression: the
71
72
  `compress` call + result live in the agent's own history and are re-sent every
package/dist/index.js CHANGED
@@ -50393,6 +50393,44 @@ function stripResponsesText(obj) {
50393
50393
  }
50394
50394
  return obj;
50395
50395
  }
50396
+ function stripOpenAIText(obj) {
50397
+ if (!obj || typeof obj !== "object") return obj;
50398
+ const o = obj;
50399
+ const choices = o["choices"];
50400
+ if (!Array.isArray(choices)) return obj;
50401
+ o["choices"] = choices.map((c) => {
50402
+ if (!c || typeof c !== "object") return c;
50403
+ const choice = { ...c };
50404
+ const msg = choice["message"];
50405
+ if (!msg || typeof msg !== "object") return choice;
50406
+ const message = { ...msg };
50407
+ const content = message["content"];
50408
+ if (typeof content === "string" && containsRenderTagText(content)) {
50409
+ message["content"] = stripAcpTags(content);
50410
+ } else if (Array.isArray(content)) {
50411
+ message["content"] = stripParts(content);
50412
+ }
50413
+ choice["message"] = message;
50414
+ return choice;
50415
+ });
50416
+ return obj;
50417
+ }
50418
+ function stripAnthropicText(obj) {
50419
+ if (!obj || typeof obj !== "object") return obj;
50420
+ const o = obj;
50421
+ const content = o["content"];
50422
+ if (!Array.isArray(content)) return obj;
50423
+ o["content"] = content.map((blk) => {
50424
+ if (blk && typeof blk === "object" && blk.type === "text" && typeof blk.text === "string") {
50425
+ const b2 = blk;
50426
+ if (containsRenderTagText(b2.text)) {
50427
+ return { ...b2, text: stripAcpTags(b2.text) };
50428
+ }
50429
+ }
50430
+ return blk;
50431
+ });
50432
+ return obj;
50433
+ }
50396
50434
 
50397
50435
  // src/stream.ts
50398
50436
  function executeAnthropicProxyTool(toolName, args, ctx) {
@@ -51584,6 +51622,20 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
51584
51622
  coreMessages.push(...hidden.messages);
51585
51623
  }
51586
51624
  }
51625
+ if (ctx.refreshFolded && proxyResults.some((pr2) => pr2.name === "compress" && !pr2.result.includes("FAILED"))) {
51626
+ try {
51627
+ const refreshed = ctx.refreshFolded(coreMessages);
51628
+ if (refreshed.length > 0) {
51629
+ coreMessages.length = 0;
51630
+ coreMessages.push(...refreshed);
51631
+ ctx.session.stats.compressCreditTokens = 0;
51632
+ ctx.log(`[acp-loop] round ${round}: re-request view refreshed to post-compress fold`);
51633
+ }
51634
+ } catch (err2) {
51635
+ ctx.log(`[acp-loop] round ${round}: fold refresh failed (${String(err2)}); keeping pre-compress view`);
51636
+ log("warn", `[acp-loop] fold refresh failed: ${String(err2)}`);
51637
+ }
51638
+ }
51587
51639
  }
51588
51640
  for (const tc of realToolCalls) {
51589
51641
  if (tc.passthrough) continue;
@@ -54165,33 +54217,111 @@ async function pipeThroughWithUsage(stream2, res, session, protocol) {
54165
54217
  const decoder = new TextDecoder("utf-8");
54166
54218
  let buf = "";
54167
54219
  const acc = {};
54220
+ const stripText = protocol === "openai" || protocol === "anthropic";
54221
+ const tagFilter = createTagEchoFilter((snippet) => {
54222
+ log("warn", `[tag-echo] stripped model-emitted render tag (plugin passthrough): ${snippet.slice(0, 80).replace(/\n/g, " ")}`);
54223
+ });
54224
+ let lastChunkBase = null;
54225
+ let lastChoiceIndex = 0;
54226
+ let lastBlockIndex = 0;
54227
+ const write = async (s3) => {
54228
+ if (!res.write(Buffer.from(s3, "utf8"))) {
54229
+ await new Promise((r) => res.once("drain", () => r()));
54230
+ }
54231
+ };
54232
+ const flushTail = () => {
54233
+ const tail = tagFilter.flush();
54234
+ if (tail.length === 0) return "";
54235
+ if (protocol === "openai") {
54236
+ const base = lastChunkBase ? { ...lastChunkBase } : {};
54237
+ delete base["usage"];
54238
+ return `data: ${JSON.stringify({ ...base, choices: [{ index: lastChoiceIndex, delta: { content: tail }, finish_reason: null }] })}
54239
+
54240
+ `;
54241
+ }
54242
+ return `event: content_block_delta
54243
+ data: ${JSON.stringify({ type: "content_block_delta", index: lastBlockIndex, delta: { type: "text_delta", text: tail } })}
54244
+
54245
+ `;
54246
+ };
54168
54247
  try {
54169
54248
  for (; ; ) {
54170
54249
  const { done, value } = await reader.read();
54171
54250
  if (done) break;
54172
54251
  if (value && value.length > 0) {
54173
- if (!res.write(Buffer.from(value))) {
54174
- await new Promise((r) => res.once("drain", () => r()));
54175
- }
54176
54252
  buf = normalizeSseLineEndings(buf + decoder.decode(value, { stream: true }));
54177
54253
  let idx;
54178
54254
  while ((idx = buf.indexOf("\n\n")) !== -1) {
54179
54255
  const rawEvent = buf.slice(0, idx);
54180
54256
  buf = buf.slice(idx + 2);
54181
54257
  const dataLines = rawEvent.split("\n").filter((l) => l.startsWith("data:"));
54182
- if (dataLines.length === 0) continue;
54258
+ if (dataLines.length === 0) {
54259
+ await write(rawEvent + "\n\n");
54260
+ continue;
54261
+ }
54183
54262
  const jsonStr = dataLines.map((l) => l.slice(5).replace(/^ /, "")).join("\n").trim();
54184
- if (!jsonStr || jsonStr === "[DONE]") continue;
54263
+ if (!jsonStr || jsonStr === "[DONE]") {
54264
+ await write(flushTail() + rawEvent + "\n\n");
54265
+ continue;
54266
+ }
54267
+ let ev;
54185
54268
  try {
54186
- const ev = JSON.parse(jsonStr);
54187
- const sample = usageFromSseEvent(ev);
54188
- if (sample) mergeUsageSample(acc, sample);
54269
+ ev = JSON.parse(jsonStr);
54189
54270
  } catch {
54271
+ await write(rawEvent + "\n\n");
54272
+ continue;
54273
+ }
54274
+ const sample = usageFromSseEvent(ev);
54275
+ if (sample) mergeUsageSample(acc, sample);
54276
+ if (!stripText) {
54277
+ await write(rawEvent + "\n\n");
54278
+ continue;
54190
54279
  }
54280
+ let dirty = false;
54281
+ let terminal = false;
54282
+ if (protocol === "openai") {
54283
+ const choices = ev["choices"];
54284
+ if (Array.isArray(choices)) {
54285
+ for (let i = 0; i < choices.length; i++) {
54286
+ const choice = choices[i] ?? {};
54287
+ const fr2 = choice["finish_reason"];
54288
+ if (typeof fr2 === "string" && fr2 !== "null") terminal = true;
54289
+ const delta = choice["delta"];
54290
+ const content = delta?.["content"];
54291
+ if (delta && typeof content === "string" && content.length > 0) {
54292
+ lastChunkBase = ev;
54293
+ lastChoiceIndex = i;
54294
+ if (!containsRenderTagText(content) && !tagFilter.pending()) continue;
54295
+ delta["content"] = tagFilter.push(content);
54296
+ dirty = true;
54297
+ }
54298
+ }
54299
+ }
54300
+ } else {
54301
+ const t = ev["type"];
54302
+ if (t === "message_delta" || t === "message_stop") terminal = true;
54303
+ if (t === "content_block_delta") {
54304
+ const delta = ev["delta"];
54305
+ const text = delta?.["text"];
54306
+ if (delta?.["type"] === "text_delta" && typeof text === "string" && text.length > 0) {
54307
+ lastBlockIndex = typeof ev["index"] === "number" ? ev["index"] : 0;
54308
+ if (containsRenderTagText(text) || tagFilter.pending()) {
54309
+ delta["text"] = tagFilter.push(text);
54310
+ dirty = true;
54311
+ }
54312
+ }
54313
+ }
54314
+ }
54315
+ if (terminal) await write(flushTail());
54316
+ await write(dirty ? rebuildEvent(rawEvent, ev) : rawEvent + "\n\n");
54191
54317
  }
54192
54318
  }
54193
54319
  if (res.destroyed || res.writableEnded) break;
54194
54320
  }
54321
+ if (!res.destroyed && !res.writableEnded) {
54322
+ const rest = flushTail();
54323
+ if (rest.length > 0) await write(rest);
54324
+ }
54195
54325
  if (acc.inputTokens !== void 0 || acc.outputTokens !== void 0 || acc.cachedTokens !== void 0) {
54196
54326
  applyUsageSample(session, acc, protocol);
54197
54327
  markDirty(session);
@@ -54339,11 +54469,12 @@ async function pipePluginJson(stream2, res, session, protocol) {
54339
54469
  }
54340
54470
  } catch {
54341
54471
  }
54342
- if (protocol === "responses") {
54472
+ if (protocol !== void 0) {
54343
54473
  try {
54344
54474
  const json = JSON.parse(text);
54345
54475
  if (containsRenderTagText(text)) {
54346
- res.end(Buffer.from(JSON.stringify(stripResponsesText(json)), "utf8"));
54476
+ const stripped = protocol === "responses" ? stripResponsesText(json) : protocol === "openai" ? stripOpenAIText(json) : stripAnthropicText(json);
54477
+ res.end(Buffer.from(JSON.stringify(stripped), "utf8"));
54347
54478
  return;
54348
54479
  }
54349
54480
  } catch {
@@ -56584,7 +56715,7 @@ function diagTagSummary(messages, sessionId, strategy) {
56584
56715
  }
56585
56716
  return `[${sessionId}] processTurn: ${messages.length} msgs, renderTags=${strategy}, ${textTagged} text tagged, ${toolTagged} tool tagged (should be 0 with text-only)`;
56586
56717
  }
56587
- function diagNudge(turn, sessionId, tokenCount, limit, model) {
56718
+ function diagNudge(turn, sessionId, tokenCount, limit, model, willInject) {
56588
56719
  const n = turn.nudge;
56589
56720
  if (!n) return `[${sessionId}] nudge: unavailable`;
56590
56721
  const b2 = n.breakdown ?? {};
@@ -56594,7 +56725,7 @@ function diagNudge(turn, sessionId, tokenCount, limit, model) {
56594
56725
  const interval = b2["nudgeGrowthTokens"] ?? 0;
56595
56726
  const pendingT1 = b2["pendingT1"] ?? 0;
56596
56727
  const ref = b2["growthReference"] ?? 0;
56597
- const inject = n.shouldInject ? `INJECT T${n.tier ?? "?"}` : "idle";
56728
+ const inject = !n.shouldInject ? "idle" : willInject ? `INJECT T${n.tier ?? "?"}` : `ARMED-SUPPRESSED T${n.tier ?? "?"}`;
56598
56729
  const modelTag = model ? ` model=${model}` : "";
56599
56730
  return `[${sessionId}] nudge ${inject}: usage=${pct2} (${tokenCount}/${limit}), growth=${growth}/${floor} (ref=${ref}, interval=${interval}), pendingT1=${pendingT1}/${interval}${modelTag}, reason="${n.reason.slice(0, 120)}"`;
56600
56731
  }
@@ -56629,7 +56760,8 @@ function prepareAnthropic(parsed, req, opts, core, config, prompts, log2, sessio
56629
56760
  if (t) session.meta.title = t;
56630
56761
  }
56631
56762
  log2("info", diagTagSummary(turn.messages, sessionId, "text-only"));
56632
- log2("info", diagNudge(turn, sessionId, tokenCount, config.modelContextLimit, parsed.model));
56763
+ const willInjectNudge = opts.compress.injectNudge && !!turn.nudge?.shouldInject;
56764
+ log2("info", diagNudge(turn, sessionId, tokenCount, config.modelContextLimit, parsed.model, willInjectNudge));
56633
56765
  processedMessages = stripKernelSummaries(turn.messages, turn.state);
56634
56766
  reapOrphanBlocks(session, msgs, deactivateBlock);
56635
56767
  rebuiltMessages = coreToAnthropic(processedMessages, cacheControls);
@@ -56637,7 +56769,7 @@ function prepareAnthropic(parsed, req, opts, core, config, prompts, log2, sessio
56637
56769
  if (injectTools) {
56638
56770
  toolsOut = injectTool(parsed.tools);
56639
56771
  }
56640
- if (opts.compress.injectNudge && !pluginMode && turn.nudge?.shouldInject) {
56772
+ if (willInjectNudge && turn.nudge) {
56641
56773
  try {
56642
56774
  const rendered = renderNudgeText(turn.nudge, prompts);
56643
56775
  if (rendered.text) {
@@ -56654,7 +56786,7 @@ function prepareAnthropic(parsed, req, opts, core, config, prompts, log2, sessio
56654
56786
  markDirty(session);
56655
56787
  const rebuilt = { ...parsed, messages: rebuiltMessages, system: systemOut, tools: toolsOut };
56656
56788
  delete rebuilt.prompt_cache_key;
56657
- return { body: JSON.stringify(rebuilt), session, processedMessages, originalMessages, anthropicSystem: parsed.system, protocol: "anthropic", stream: stream2, compressInjected: injectTools, pluginMode, nudge, prompts };
56789
+ return { body: JSON.stringify(rebuilt), session, processedMessages, originalMessages, anthropicSystem: parsed.system, protocol: "anthropic", stream: stream2, compressInjected: injectTools, pluginMode, nudge, prompts, renderTags: "text-only" };
56658
56790
  }
56659
56791
  function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session, pluginMode) {
56660
56792
  const sessionId = session.id;
@@ -56686,7 +56818,8 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session,
56686
56818
  if (t) session.meta.title = t;
56687
56819
  }
56688
56820
  log2("info", diagTagSummary(turn.messages, sessionId, "text-only"));
56689
- log2("info", diagNudge(turn, sessionId, tokenCount, config.modelContextLimit, parsed.model));
56821
+ const willInjectNudge = opts.compress.injectNudge && !!turn.nudge?.shouldInject && shouldInject;
56822
+ log2("info", diagNudge(turn, sessionId, tokenCount, config.modelContextLimit, parsed.model, willInjectNudge));
56690
56823
  processedMessages = stripKernelSummaries(turn.messages, turn.state);
56691
56824
  reapOrphanBlocks(session, msgs, deactivateBlock);
56692
56825
  rebuiltMessages = systemToUser(coreToOpenai(processedMessages));
@@ -56697,7 +56830,7 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session,
56697
56830
  if (injectTools) {
56698
56831
  toolsOut = injectOpenaiTool(parsed.tools);
56699
56832
  }
56700
- if (opts.compress.injectNudge && !pluginMode && turn.nudge?.shouldInject && shouldInject) {
56833
+ if (willInjectNudge && turn.nudge) {
56701
56834
  try {
56702
56835
  const rendered = renderNudgeText(turn.nudge, prompts);
56703
56836
  if (rendered.text) {
@@ -56717,7 +56850,7 @@ function prepareOpenai(parsed, req, opts, core, config, prompts, log2, session,
56717
56850
  }
56718
56851
  snapshotMessages(session, originalMessages);
56719
56852
  markDirty(session);
56720
- return { body: JSON.stringify(rebuilt), session, processedMessages, originalMessages, protocol: "openai", stream: stream2, compressInjected: injectTools, pluginMode, nudge, prompts, openaiSystemText };
56853
+ return { body: JSON.stringify(rebuilt), session, processedMessages, originalMessages, protocol: "openai", stream: stream2, compressInjected: injectTools, pluginMode, nudge, prompts, openaiSystemText, renderTags: "text-only" };
56721
56854
  }
56722
56855
  function prepareResponses(parsed, req, opts, core, config, prompts, log2, session, identity, pluginMode, upstreamOrigin) {
56723
56856
  const sessionId = session.id;
@@ -56755,6 +56888,7 @@ function prepareResponses(parsed, req, opts, core, config, prompts, log2, sessio
56755
56888
  const injectTools = shouldInject && !pluginMode;
56756
56889
  const isCompactionTrigger = hasCompactionTrigger(parsed.input);
56757
56890
  const responsesTextProtocol = FORCE_TEXT_PROTOCOL || resolveCompressProtocol(opts.routes, upstreamOrigin) === "marker";
56891
+ const renderTags = process.env.ACP_RENDER_NONE || isCompactionTrigger ? "none" : "text-only";
56758
56892
  try {
56759
56893
  const projection = responsesToCore(parsed);
56760
56894
  responsesProjection = projection;
@@ -56764,7 +56898,7 @@ function prepareResponses(parsed, req, opts, core, config, prompts, log2, sessio
56764
56898
  log2("info", `[${sessionId}] input items: ${Array.isArray(parsed.input) ? parsed.input.map((i) => i.type).join(",") : "(string)"}`);
56765
56899
  }
56766
56900
  const tokenCount = session.stats.lastInputTokens;
56767
- const turn = core.processTurn({ messages: msgs, state: session.state, config, tokenCount, renderTags: process.env.ACP_RENDER_NONE || isCompactionTrigger ? "none" : "text-only" });
56901
+ const turn = core.processTurn({ messages: msgs, state: session.state, config, tokenCount, renderTags });
56768
56902
  session.state = turn.state;
56769
56903
  session.stats.compressCreditTokens = 0;
56770
56904
  if (turn.nudge) turn.nudge.compressibleRanges = viableRanges(turn.nudge.compressibleRanges);
@@ -56775,7 +56909,8 @@ function prepareResponses(parsed, req, opts, core, config, prompts, log2, sessio
56775
56909
  if (t) session.meta.title = t;
56776
56910
  }
56777
56911
  log2("info", diagTagSummary(turn.messages, sessionId, "text-only"));
56778
- log2("info", diagNudge(turn, sessionId, tokenCount, config.modelContextLimit, parsed.model));
56912
+ const willInjectNudge = opts.compress.injectNudge && !!turn.nudge?.shouldInject && shouldInject && !isCompactionTrigger;
56913
+ log2("info", diagNudge(turn, sessionId, tokenCount, config.modelContextLimit, parsed.model, willInjectNudge));
56779
56914
  processedMessages = stripKernelSummaries(turn.messages, turn.state);
56780
56915
  reapOrphanBlocks(session, msgs, deactivateBlock);
56781
56916
  rebuiltInput = patchResponsesInput(projection, processedMessages);
@@ -56791,7 +56926,7 @@ function prepareResponses(parsed, req, opts, core, config, prompts, log2, sessio
56791
56926
  const devContent = [...projection.systemParts, ...forgedSummaries].join("\n\n---\n\n");
56792
56927
  rebuiltInput = injectResponsesDeveloperMessage(rebuiltInput, devContent);
56793
56928
  }
56794
- if (opts.compress.injectNudge && !pluginMode && turn.nudge?.shouldInject && shouldInject && !isCompactionTrigger) {
56929
+ if (willInjectNudge && turn.nudge) {
56795
56930
  try {
56796
56931
  const rendered = renderNudgeText(turn.nudge, prompts);
56797
56932
  if (rendered.text) {
@@ -56858,6 +56993,7 @@ function prepareResponses(parsed, req, opts, core, config, prompts, log2, sessio
56858
56993
  responsesTextProtocol,
56859
56994
  nudge,
56860
56995
  prompts,
56996
+ renderTags,
56861
56997
  resetAfterSuccess: isCompactionTrigger,
56862
56998
  codexForge
56863
56999
  };
@@ -57360,9 +57496,21 @@ ${hdrText}
57360
57496
  const textProtocol = prepared.protocol === "responses" && !!prepared.responsesTextProtocol;
57361
57497
  const systemPrompt = textProtocol ? buildCompressHybridSystemPrompt(prepared.prompts ?? defaultPrompts) : buildCompressSystemPrompt(prepared.prompts ?? defaultPrompts);
57362
57498
  const adapter = pickAdapter(prepared.protocol, parsedReq, textProtocol, prepared.responsesProjection, prepared.anthropicSystem, prepared.openaiSystemText);
57499
+ const refreshFolded = (current) => {
57500
+ const turn = core.processTurn({
57501
+ messages: prepared.originalMessages,
57502
+ state: prepared.session.state,
57503
+ config,
57504
+ tokenCount: prepared.session.stats.lastInputTokens,
57505
+ renderTags: prepared.renderTags ?? "text-only"
57506
+ });
57507
+ prepared.session.state = turn.state;
57508
+ const records = current.filter((m2) => typeof m2.id === "string" && m2.id.startsWith("acp_loop_"));
57509
+ return stripKernelSummaries([...turn.messages, ...records], turn.state);
57510
+ };
57363
57511
  const loop = runCompressLoop(
57364
57512
  streamToRead,
57365
- { core, config, messages: prepared.processedMessages.length > 0 ? prepared.processedMessages : prepared.originalMessages, compressMessages: prepared.originalMessages, session: prepared.session, log: ctx.log, proxyUrl, protocol: prepared.protocol, textProtocol, debug: opts.debug, nudge: prepared.nudge },
57513
+ { core, config, messages: prepared.processedMessages.length > 0 ? prepared.processedMessages : prepared.originalMessages, compressMessages: prepared.originalMessages, session: prepared.session, log: ctx.log, proxyUrl, protocol: prepared.protocol, textProtocol, debug: opts.debug, nudge: prepared.nudge, refreshFolded },
57366
57514
  parsedReq,
57367
57515
  { url: upstreamUrl, headers: reqHeaders },
57368
57516
  adapter,