billion-context 0.1.73 → 0.1.74-pr.477.294

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
@@ -50217,12 +50217,6 @@ ${body.slice(0, 4e3)}...`;
50217
50217
  ${body}`;
50218
50218
  }
50219
50219
 
50220
- // src/sse-util.ts
50221
- function normalizeSseLineEndings(buf) {
50222
- if (buf.indexOf("\r") === -1) return buf;
50223
- return buf.replace(/\r\n|\r/g, "\n");
50224
- }
50225
-
50226
50220
  // src/loop/tag-echo-filter.ts
50227
50221
  var PAIRED = /\x3cacp\s[^<>]{0,256}>([^<>]{0,64})<\/acp>/;
50228
50222
  var LONE_OPEN = /\x3cacp(?:\s[^<>]{0,256})?>/;
@@ -51466,8 +51460,26 @@ function recordUsage(ctx, usage, round) {
51466
51460
  async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adapter, systemPrompt, signal) {
51467
51461
  let activeClearTimer = null;
51468
51462
  let currentUpstream = upstream;
51463
+ let roundBody = requestBody;
51469
51464
  const coreMessages = [...ctx.messages];
51470
51465
  let degradedRetried = false;
51466
+ let truncationRetried = false;
51467
+ const fetchUpstream = (body) => fetchWithRetry(
51468
+ requestOptions.url,
51469
+ {
51470
+ method: "POST",
51471
+ headers: requestOptions.headers,
51472
+ body: JSON.stringify(body),
51473
+ ...ctx.proxyUrl ? { dispatcher: proxyDispatcher(ctx.proxyUrl) } : {}
51474
+ },
51475
+ void 0,
51476
+ signal,
51477
+ (info) => {
51478
+ const lc = lastCompressSuffix(ctx.session.lastCompress);
51479
+ ctx.log(`[acp-proxy: upstream rejected replay (HTTP ${info.status}: ${info.detail.slice(0, 120)}); likely provider risk-control \u2014 retrying in ${info.delayMs}ms (attempt ${info.attempt}/${info.maxAttempts})${lc}]`);
51480
+ log("warn", `[acp-loop] upstream rejected replay (HTTP ${info.status}); retrying in ${info.delayMs}ms (attempt ${info.attempt}/${info.maxAttempts})${lc}`);
51481
+ }
51482
+ );
51471
51483
  try {
51472
51484
  for (let round = 1; round <= MAX_LOOP_ROUNDS; round++) {
51473
51485
  if (signal?.aborted) break;
@@ -51480,50 +51492,93 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
51480
51492
  let finishReason;
51481
51493
  let sawDone = false;
51482
51494
  let suppressCompletion = false;
51483
- for await (const ev of adapter.parseStream(currentUpstream, round)) {
51484
- if (signal?.aborted) break;
51485
- if (ev.kind === "text") {
51486
- assistantText += ev.delta;
51487
- if (!ctx.textProtocol && ev.raw) {
51488
- yield ev.raw;
51489
- } else if (!ctx.textProtocol && round > 1 && ev.delta.length > 0) {
51490
- yield adapter.emitText(ev.delta);
51491
- }
51492
- } else if (ev.kind === "reasoning") {
51493
- assistantReasoning += ev.delta;
51494
- let seg = reasoningSegments[reasoningSegments.length - 1];
51495
- if (reasoningSealed || !seg) {
51496
- seg = { text: "", signature: "" };
51497
- reasoningSegments.push(seg);
51498
- reasoningSealed = false;
51499
- }
51500
- seg.text += ev.delta;
51501
- if (ev.signature) seg.signature += ev.signature;
51502
- if (ev.blockEnd) reasoningSealed = true;
51503
- if (!ctx.textProtocol) {
51504
- if (ev.raw) {
51505
- yield ev.raw;
51506
- } else if (round > 1 && ev.delta.length > 0 && adapter.emitReasoning) {
51507
- yield adapter.emitReasoning(ev.delta);
51508
- }
51509
- }
51510
- } else if (ev.kind === "tool_call") {
51511
- calls.push({ name: ev.name, callId: ev.callId, arguments: ev.arguments, passthrough: ev.passthrough });
51512
- } else if (ev.kind === "usage") {
51513
- usage = {
51514
- inputTokens: ev.inputTokens,
51515
- outputTokens: ev.outputTokens,
51516
- cachedTokens: ev.cachedTokens
51517
- };
51518
- } else if (ev.kind === "done") {
51519
- sawDone = true;
51520
- finishReason = ev.finishReason;
51521
- suppressCompletion = ev.suppressCompletion === true;
51522
- } else if (ev.kind === "meta") {
51523
- if (round === 1 || !ev.firstRoundOnly) {
51524
- yield ev.chunk;
51495
+ let truncatedDone = false;
51496
+ let forwardedAny = false;
51497
+ const fwd = (chunk) => {
51498
+ forwardedAny = true;
51499
+ return chunk;
51500
+ };
51501
+ for (; ; ) {
51502
+ assistantText = "";
51503
+ assistantReasoning = "";
51504
+ reasoningSegments.length = 0;
51505
+ reasoningSealed = true;
51506
+ calls.length = 0;
51507
+ usage = {};
51508
+ finishReason = void 0;
51509
+ sawDone = false;
51510
+ suppressCompletion = false;
51511
+ truncatedDone = false;
51512
+ forwardedAny = false;
51513
+ for await (const ev of adapter.parseStream(currentUpstream, round)) {
51514
+ if (signal?.aborted) break;
51515
+ if (ev.kind === "text") {
51516
+ assistantText += ev.delta;
51517
+ if (!ctx.textProtocol && ev.raw) {
51518
+ yield fwd(ev.raw);
51519
+ } else if (!ctx.textProtocol && round > 1 && ev.delta.length > 0) {
51520
+ yield fwd(adapter.emitText(ev.delta));
51521
+ }
51522
+ } else if (ev.kind === "reasoning") {
51523
+ assistantReasoning += ev.delta;
51524
+ let seg = reasoningSegments[reasoningSegments.length - 1];
51525
+ if (reasoningSealed || !seg) {
51526
+ seg = { text: "", signature: "" };
51527
+ reasoningSegments.push(seg);
51528
+ reasoningSealed = false;
51529
+ }
51530
+ seg.text += ev.delta;
51531
+ if (ev.signature) seg.signature += ev.signature;
51532
+ if (ev.blockEnd) reasoningSealed = true;
51533
+ if (!ctx.textProtocol) {
51534
+ if (ev.raw) {
51535
+ yield fwd(ev.raw);
51536
+ } else if (round > 1 && ev.delta.length > 0 && adapter.emitReasoning) {
51537
+ yield fwd(adapter.emitReasoning(ev.delta));
51538
+ }
51539
+ }
51540
+ } else if (ev.kind === "tool_call") {
51541
+ calls.push({ name: ev.name, callId: ev.callId, arguments: ev.arguments, passthrough: ev.passthrough });
51542
+ } else if (ev.kind === "usage") {
51543
+ usage = {
51544
+ inputTokens: ev.inputTokens,
51545
+ outputTokens: ev.outputTokens,
51546
+ cachedTokens: ev.cachedTokens
51547
+ };
51548
+ } else if (ev.kind === "done") {
51549
+ sawDone = true;
51550
+ finishReason = ev.finishReason;
51551
+ suppressCompletion = ev.suppressCompletion === true;
51552
+ truncatedDone = ev.truncated === true;
51553
+ } else if (ev.kind === "meta") {
51554
+ if (round === 1 || !ev.firstRoundOnly) {
51555
+ yield fwd(ev.chunk);
51556
+ }
51557
+ }
51558
+ }
51559
+ if ((!sawDone || truncatedDone) && !forwardedAny && calls.length === 0 && !(ctx.textProtocol && assistantText.length > 0) && !signal?.aborted && !truncationRetried) {
51560
+ truncationRetried = true;
51561
+ ctx.log(`[acp-loop] round ${round}: upstream truncated before any content reached the client; retrying fetch once`);
51562
+ try {
51563
+ const respResult2 = await fetchUpstream(roundBody);
51564
+ if (!respResult2.response.body) {
51565
+ respResult2.clearTimer();
51566
+ throw new UpstreamHttpError(respResult2.response.status, "(empty response body)", 1);
51567
+ }
51568
+ currentUpstream = respResult2.response.body;
51569
+ if (activeClearTimer) activeClearTimer();
51570
+ activeClearTimer = respResult2.clearTimer;
51571
+ continue;
51572
+ } catch (e) {
51573
+ if (e instanceof UpstreamHttpError) {
51574
+ const suffix = e.attempts > 1 ? ` after ${e.attempts} attempt(s)` : "";
51575
+ ctx.log(`[acp-loop] round ${round}: truncation retry failed (upstream error ${e.status}${suffix}: ${e.body.slice(0, 200)})`);
51576
+ } else {
51577
+ ctx.log(`[acp-loop] round ${round}: truncation retry failed (${e instanceof Error ? e.message : String(e)})`);
51578
+ }
51525
51579
  }
51526
51580
  }
51581
+ break;
51527
51582
  }
51528
51583
  if (usage.inputTokens !== void 0 || usage.outputTokens !== void 0 || usage.cachedTokens !== void 0) {
51529
51584
  recordUsage(ctx, usage, round);
@@ -51657,7 +51712,6 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
51657
51712
  const partialReasoning = assistantReasoning.length;
51658
51713
  const msg = `upstream stream truncated (no completion event; round ${round}, ${partialText} text chars + ${partialReasoning} reasoning chars received)`;
51659
51714
  ctx.log(`[acp-loop] round ${round}: ${msg}`);
51660
- log("error", `[acp-loop] ${msg}`);
51661
51715
  yield adapter.emitError(msg);
51662
51716
  return;
51663
51717
  }
@@ -51674,22 +51728,6 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
51674
51728
  }
51675
51729
  ctx.log(`[acp-loop] round ${round}: proxy tool executed; re-requesting so the model sees the result`);
51676
51730
  if (signal?.aborted) break;
51677
- const fetchUpstream = (body) => fetchWithRetry(
51678
- requestOptions.url,
51679
- {
51680
- method: "POST",
51681
- headers: requestOptions.headers,
51682
- body: JSON.stringify(body),
51683
- ...ctx.proxyUrl ? { dispatcher: proxyDispatcher(ctx.proxyUrl) } : {}
51684
- },
51685
- void 0,
51686
- signal,
51687
- (info) => {
51688
- const lc = lastCompressSuffix(ctx.session.lastCompress);
51689
- ctx.log(`[acp-proxy: upstream rejected replay (HTTP ${info.status}: ${info.detail.slice(0, 120)}); likely provider risk-control \u2014 retrying in ${info.delayMs}ms (attempt ${info.attempt}/${info.maxAttempts})${lc}]`);
51690
- log("warn", `[acp-loop] upstream rejected replay (HTTP ${info.status}); retrying in ${info.delayMs}ms (attempt ${info.attempt}/${info.maxAttempts})${lc}`);
51691
- }
51692
- );
51693
51731
  let newBody = adapter.buildRequest(coreMessages, systemPrompt, requestBody);
51694
51732
  if (process.env.ACP_DUMP_BODY === "1") {
51695
51733
  try {
@@ -51732,6 +51770,7 @@ async function* runCompressLoop(upstream, ctx, requestBody, requestOptions, adap
51732
51770
  return;
51733
51771
  }
51734
51772
  currentUpstream = respResult.response.body;
51773
+ roundBody = newBody;
51735
51774
  if (activeClearTimer) activeClearTimer();
51736
51775
  activeClearTimer = respResult.clearTimer;
51737
51776
  }
@@ -52056,6 +52095,20 @@ function createResponsesAdapter(textProtocol, projection) {
52056
52095
  let responseObj = null;
52057
52096
  let terminalRaw = null;
52058
52097
  let terminalKind = null;
52098
+ let createdForwarded = false;
52099
+ let createdRespId = null;
52100
+ const ensureCreated = () => {
52101
+ if (createdForwarded) return null;
52102
+ createdForwarded = true;
52103
+ if (!createdRespId) createdRespId = `resp-proxy-${Date.now()}`;
52104
+ return Buffer.from(
52105
+ `event: response.created
52106
+ data: ${JSON.stringify({ type: "response.created", response: { id: createdRespId, status: "in_progress", output: [] } })}
52107
+
52108
+ `,
52109
+ "utf8"
52110
+ );
52111
+ };
52059
52112
  return {
52060
52113
  buildRequest(coreMessages, systemPrompt, requestBody) {
52061
52114
  const customToolCallIds = /* @__PURE__ */ new Set();
@@ -52110,6 +52163,11 @@ function createResponsesAdapter(textProtocol, projection) {
52110
52163
  outputIndex = Math.max(outputIndex, obj.output_index + 1);
52111
52164
  }
52112
52165
  if (type === "response.created" || type === "response.in_progress") {
52166
+ if (type === "response.created") {
52167
+ const resp = obj.response;
52168
+ if (resp && typeof resp.id === "string") createdRespId = resp.id;
52169
+ if (round === 1) createdForwarded = true;
52170
+ }
52113
52171
  yield { kind: "meta", chunk: rawBuf, firstRoundOnly: true };
52114
52172
  } else if (type === "response.output_item.added") {
52115
52173
  const item = obj.item;
@@ -52243,7 +52301,7 @@ function createResponsesAdapter(textProtocol, projection) {
52243
52301
  }
52244
52302
  }
52245
52303
  if (!terminalKind) {
52246
- yield { kind: "done", finishReason: "failed" };
52304
+ yield { kind: "done", finishReason: "failed", truncated: true };
52247
52305
  }
52248
52306
  },
52249
52307
  emitText(delta) {
@@ -52266,18 +52324,22 @@ function createResponsesAdapter(textProtocol, projection) {
52266
52324
  return terminalRaw;
52267
52325
  }
52268
52326
  if (!responseObj && opts?.finishReason === "failed") {
52327
+ const parts = [];
52328
+ const created = ensureCreated();
52329
+ if (created) parts.push(created);
52269
52330
  const failed = {
52270
- id: `resp-error-${Date.now()}`,
52331
+ id: createdRespId ?? `resp-error-${Date.now()}`,
52271
52332
  status: "failed",
52272
52333
  error: { code: "server_error", message: "upstream returned no response" }
52273
52334
  };
52274
- return Buffer.from(
52335
+ parts.push(Buffer.from(
52275
52336
  `event: response.failed
52276
52337
  data: ${JSON.stringify({ type: "response.failed", response: failed })}
52277
52338
 
52278
52339
  `,
52279
52340
  "utf8"
52280
- );
52341
+ ));
52342
+ return Buffer.concat(parts);
52281
52343
  }
52282
52344
  let resp = responseObj ? { ...responseObj } : { id: `resp-proxy-${Date.now()}`, status: "completed", output: [] };
52283
52345
  if (opts?.usage) {
@@ -52297,18 +52359,22 @@ data: ${JSON.stringify({ type: "response.failed", response: failed })}
52297
52359
  return buildCompleted(resp);
52298
52360
  },
52299
52361
  emitError(message) {
52362
+ const parts = [];
52363
+ const created = ensureCreated();
52364
+ if (created) parts.push(created);
52300
52365
  const resp = {
52301
- id: `resp-error-${Date.now()}`,
52366
+ id: createdRespId ?? `resp-error-${Date.now()}`,
52302
52367
  status: "failed",
52303
52368
  error: { code: "server_error", message }
52304
52369
  };
52305
- return Buffer.from(
52370
+ parts.push(Buffer.from(
52306
52371
  `event: response.failed
52307
52372
  data: ${JSON.stringify({ type: "response.failed", response: resp })}
52308
52373
 
52309
52374
  `,
52310
52375
  "utf8"
52311
- );
52376
+ ));
52377
+ return Buffer.concat(parts);
52312
52378
  },
52313
52379
  extractTextTriggers(text) {
52314
52380
  const calls = [];
@@ -52818,6 +52884,33 @@ function createAnthropicAdapter(requestBody, originalSystem) {
52818
52884
  const model = requestBody.model ?? void 0;
52819
52885
  let messageId;
52820
52886
  let clientIndex = 0;
52887
+ let messageStartForwarded = false;
52888
+ const openBlocks = [];
52889
+ const removeOpenBlock = (index) => {
52890
+ const i = openBlocks.indexOf(index);
52891
+ if (i >= 0) openBlocks.splice(i, 1);
52892
+ };
52893
+ const buildSyntheticMessageStart = () => {
52894
+ const extra = {};
52895
+ if (model) extra.model = model;
52896
+ const msg = {
52897
+ id: messageId ?? `msg_acp_error_${Date.now()}`,
52898
+ type: "message",
52899
+ role: "assistant",
52900
+ content: [],
52901
+ stop_reason: null,
52902
+ stop_sequence: null,
52903
+ usage: { input_tokens: 0, output_tokens: 0 },
52904
+ ...extra
52905
+ };
52906
+ return Buffer.from(
52907
+ `event: message_start
52908
+ data: ${JSON.stringify({ type: "message_start", message: msg })}
52909
+
52910
+ `,
52911
+ "utf8"
52912
+ );
52913
+ };
52821
52914
  const buildTextBlock = (index, text) => Buffer.from(
52822
52915
  `event: content_block_start
52823
52916
  data: ${JSON.stringify({ type: "content_block_start", index, content_block: { type: "text", text: "" } })}
@@ -52901,6 +52994,7 @@ ${systemPrompt}` : systemPrompt;
52901
52994
  if (typeof u2.input_tokens === "number") roundInput = u2.input_tokens;
52902
52995
  if (typeof u2.cache_read_input_tokens === "number") roundCached = u2.cache_read_input_tokens;
52903
52996
  if (round === 1) {
52997
+ messageStartForwarded = true;
52904
52998
  yield { kind: "meta", chunk: rawBuf, firstRoundOnly: true };
52905
52999
  }
52906
53000
  } else if (type === "ping") {
@@ -52916,6 +53010,7 @@ ${systemPrompt}` : systemPrompt;
52916
53010
  if (block.type === "thinking" || block.type === "redacted_thinking") thinkingIndexes.add(upstreamIndex);
52917
53011
  const ci2 = clientIndex++;
52918
53012
  indexMap.set(upstreamIndex, ci2);
53013
+ openBlocks.push(ci2);
52919
53014
  yield { kind: "meta", chunk: remapIndexInEvent(eventStr, ci2), firstRoundOnly: round === 1 };
52920
53015
  }
52921
53016
  } else if (type === "content_block_delta") {
@@ -52965,10 +53060,12 @@ ${systemPrompt}` : systemPrompt;
52965
53060
  };
52966
53061
  } else if (thinkingIndexes.delete(upstreamIndex)) {
52967
53062
  const ci2 = indexMap.get(upstreamIndex) ?? upstreamIndex;
53063
+ removeOpenBlock(ci2);
52968
53064
  yield { kind: "meta", chunk: remapIndexInEvent(eventStr, ci2), firstRoundOnly: false };
52969
53065
  yield { kind: "reasoning", delta: "", blockEnd: true };
52970
53066
  } else {
52971
53067
  const ci2 = indexMap.get(upstreamIndex) ?? upstreamIndex;
53068
+ removeOpenBlock(ci2);
52972
53069
  if (lastTextIndex !== null) {
52973
53070
  const tail = tagFilter.flush();
52974
53071
  if (tail.length > 0) {
@@ -53060,10 +53157,22 @@ data: ${JSON.stringify({ type: "content_block_stop", index })}
53060
53157
  );
53061
53158
  },
53062
53159
  emitError(message) {
53063
- const errBlock = buildTextBlock(clientIndex++, `
53160
+ const parts = [];
53161
+ if (!messageStartForwarded) {
53162
+ parts.push(buildSyntheticMessageStart());
53163
+ messageStartForwarded = true;
53164
+ }
53165
+ for (const index of openBlocks.splice(0)) {
53166
+ parts.push(Buffer.from(`event: content_block_stop
53167
+ data: ${JSON.stringify({ type: "content_block_stop", index })}
53168
+
53169
+ `, "utf8"));
53170
+ }
53171
+ parts.push(buildTextBlock(clientIndex++, `
53064
53172
  [acp-proxy: ${message}]
53065
- `);
53066
- return Buffer.concat([errBlock, buildTerminal("end_turn", 0, 0, 0)]);
53173
+ `));
53174
+ parts.push(buildTerminal("end_turn", 0, 0, 0));
53175
+ return Buffer.concat(parts);
53067
53176
  }
53068
53177
  };
53069
53178
  }
@@ -53383,6 +53492,11 @@ function rewriteResponsesJsonResponse(body, ctx) {
53383
53492
  if (!body || typeof body !== "object") return body;
53384
53493
  const b2 = body;
53385
53494
  if (!Array.isArray(b2.output)) return body;
53495
+ const probe = JSON.stringify(b2.output);
53496
+ if (containsRenderTagText(probe)) {
53497
+ ctx.log(`[warn: tag echo] non-stream responses output contains <acp tag: ${probe.slice(0, 120).replace(/\n/g, " ")}`);
53498
+ stripResponsesText(b2);
53499
+ }
53386
53500
  let converted = false;
53387
53501
  let sawReal = false;
53388
53502
  const noteParts = [];
@@ -53944,6 +54058,14 @@ function buildStatusPanel(input) {
53944
54058
  import { fileURLToPath as fileURLToPath2 } from "url";
53945
54059
  import fs4 from "fs";
53946
54060
  import path8 from "path";
54061
+
54062
+ // src/sse-util.ts
54063
+ function normalizeSseLineEndings(buf) {
54064
+ if (buf.indexOf("\r") === -1) return buf;
54065
+ return buf.replace(/\r\n|\r/g, "\n");
54066
+ }
54067
+
54068
+ // src/plugin.ts
53947
54069
  var PROXY_VERSION = (() => {
53948
54070
  try {
53949
54071
  const here = fileURLToPath2(import.meta.url);
@@ -54603,7 +54725,7 @@ async function pipePluginJson(stream2, res, session, protocol) {
54603
54725
  try {
54604
54726
  const json = JSON.parse(text);
54605
54727
  const usage = json["usage"];
54606
- if (usage) {
54728
+ if (session && usage) {
54607
54729
  const input = num2(usage["prompt_tokens"]) ?? num2(usage["input_tokens"]);
54608
54730
  if (input !== void 0) {
54609
54731
  applyUsageSample(session, {
@@ -57618,7 +57740,12 @@ ${hdrText}
57618
57740
  if (prepared && prepared.resetAfterSuccess) {
57619
57741
  const [toClient, toObserve] = responseBody.tee();
57620
57742
  const observed = observeResponsesTerminalState(toObserve, prepared.stream);
57621
- await pipeThrough(toClient, res);
57743
+ const tagLog = (msg) => log2("info", `[${prepared.session.id}] ${msg}`);
57744
+ if ((upstream.headers.get("content-type") ?? "").includes("text/event-stream")) {
57745
+ await pipePluginResponsesWithStrip(toClient, res, void 0, tagLog);
57746
+ } else {
57747
+ await pipeThrough(toClient, res);
57748
+ }
57622
57749
  clearUpstreamTimer();
57623
57750
  const terminal = await observed;
57624
57751
  if (terminal === "completed") {
@@ -57636,6 +57763,9 @@ ${hdrText}
57636
57763
  await pipePluginChatWithStrip(responseBody, res, p2.protocol, void 0, tagLog);
57637
57764
  }
57638
57765
  clearUpstreamTimer();
57766
+ } else if (prepared && (upstream.headers.get("content-type") ?? "").includes("application/json")) {
57767
+ await pipePluginJson(responseBody, res, void 0, prepared.protocol);
57768
+ clearUpstreamTimer();
57639
57769
  } else {
57640
57770
  await pipeThrough(responseBody, res);
57641
57771
  clearUpstreamTimer();