billion-context-pi 0.1.65 → 0.1.66-pr.363.154

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
@@ -1650,8 +1650,12 @@ function adjustBoundariesForReasoningPairs(startIndex, endIndex, messages) {
1650
1650
  j2++;
1651
1651
  }
1652
1652
  const companion = messages[j2 + 1];
1653
- if (companion !== void 0 && companion.role === "assistant" && (companion.contentType === "text" || companion.contentType === "tool-call") && j2 + 1 > newEndIndex) {
1654
- newEndIndex = j2 + 1;
1653
+ if (companion !== void 0 && companion.role === "assistant" && (companion.contentType === "text" || companion.contentType === "tool-call")) {
1654
+ let e = j2 + 1;
1655
+ while (e + 1 < messages.length && messages[e + 1].role === "assistant" && (messages[e + 1].contentType === "text" || messages[e + 1].contentType === "tool-call")) {
1656
+ e++;
1657
+ }
1658
+ if (e > newEndIndex) newEndIndex = e;
1655
1659
  }
1656
1660
  }
1657
1661
  if (msg.role === "assistant" && (msg.contentType === "text" || msg.contentType === "tool-call")) {
@@ -1667,6 +1671,64 @@ function adjustBoundariesForReasoningPairs(startIndex, endIndex, messages) {
1667
1671
  }
1668
1672
  return { startIndex: newStartIndex, endIndex: newEndIndex };
1669
1673
  }
1674
+ function isAssistantAct(msg) {
1675
+ return msg.role === "assistant" && (msg.contentType === "text" || msg.contentType === "tool-call");
1676
+ }
1677
+ function computeTurnGroups(messages) {
1678
+ const resultIdByCallId = /* @__PURE__ */ new Map();
1679
+ for (const msg of messages) {
1680
+ if (msg.contentType === "tool-result" && typeof msg.toolCallId === "string" && msg.id) {
1681
+ if (!resultIdByCallId.has(msg.toolCallId))
1682
+ resultIdByCallId.set(msg.toolCallId, msg.id);
1683
+ }
1684
+ }
1685
+ const grouped = /* @__PURE__ */ new Set();
1686
+ const groups = [];
1687
+ for (let i = 0; i < messages.length; i++) {
1688
+ const msg = messages[i];
1689
+ if (!msg.id || grouped.has(msg.id)) continue;
1690
+ if (!(msg.contentType === "reasoning" || isAssistantAct(msg))) continue;
1691
+ let reasoningStart = i;
1692
+ if (msg.contentType === "reasoning") {
1693
+ while (reasoningStart > 0 && messages[reasoningStart - 1].contentType === "reasoning") {
1694
+ reasoningStart--;
1695
+ }
1696
+ } else {
1697
+ let s = i;
1698
+ while (s > 0 && isAssistantAct(messages[s - 1])) s--;
1699
+ reasoningStart = s;
1700
+ while (reasoningStart > 0 && messages[reasoningStart - 1].contentType === "reasoning") {
1701
+ reasoningStart--;
1702
+ }
1703
+ }
1704
+ const burstStart = (() => {
1705
+ let s = reasoningStart;
1706
+ while (s < messages.length && messages[s].contentType === "reasoning")
1707
+ s++;
1708
+ return s;
1709
+ })();
1710
+ if (burstStart >= messages.length || !isAssistantAct(messages[burstStart])) {
1711
+ continue;
1712
+ }
1713
+ let burstEnd = burstStart;
1714
+ while (burstEnd + 1 < messages.length && isAssistantAct(messages[burstEnd + 1])) {
1715
+ burstEnd++;
1716
+ }
1717
+ const members = /* @__PURE__ */ new Set();
1718
+ for (let k = reasoningStart; k <= burstEnd; k++) {
1719
+ const m2 = messages[k];
1720
+ if (!m2.id) continue;
1721
+ members.add(m2.id);
1722
+ if (m2.role === "assistant" && m2.contentType === "tool-call" && typeof m2.toolCallId === "string") {
1723
+ const rid = resultIdByCallId.get(m2.toolCallId);
1724
+ if (rid) members.add(rid);
1725
+ }
1726
+ }
1727
+ for (const id of members) grouped.add(id);
1728
+ groups.push([...members]);
1729
+ }
1730
+ return groups;
1731
+ }
1670
1732
  function estimateTextTokens(text) {
1671
1733
  return Math.ceil(text.length / 4);
1672
1734
  }
@@ -2381,6 +2443,42 @@ function applySingleRange(input) {
2381
2443
  )} from compression range (recent/last-user zone).`
2382
2444
  );
2383
2445
  }
2446
+ {
2447
+ const reasoningIds = /* @__PURE__ */ new Set();
2448
+ const callIds = /* @__PURE__ */ new Set();
2449
+ for (const m2 of input.messages) {
2450
+ if (!m2.id) continue;
2451
+ if (m2.contentType === "reasoning") reasoningIds.add(m2.id);
2452
+ if (m2.role === "assistant" && m2.contentType === "tool-call") callIds.add(m2.id);
2453
+ }
2454
+ const withdrawIds = /* @__PURE__ */ new Set();
2455
+ let splitTurnCount = 0;
2456
+ for (const group of computeTurnGroups(input.messages)) {
2457
+ const foldHasReasoning = group.some(
2458
+ (id) => effectiveMessageIds.has(id) && reasoningIds.has(id)
2459
+ );
2460
+ if (!foldHasReasoning) continue;
2461
+ const keptHasCall = group.some(
2462
+ (id) => !effectiveMessageIds.has(id) && callIds.has(id)
2463
+ );
2464
+ if (!keptHasCall) continue;
2465
+ splitTurnCount++;
2466
+ for (const id of group) withdrawIds.add(id);
2467
+ }
2468
+ if (withdrawIds.size > 0) {
2469
+ for (const id of withdrawIds) effectiveMessageIds.delete(id);
2470
+ const beforeWithdraw = filteredIds.length;
2471
+ filteredIds = filteredIds.filter((id) => !withdrawIds.has(id));
2472
+ if (filteredIds.length === 0 && consumedBlockIds.length === 0) {
2473
+ throw new Error(
2474
+ `Range would split ${splitTurnCount} turn(s) at the protected-zone boundary: a visible tool-call must keep its reasoning run (strict-echo providers reject a rebuilt request that lost it). Shrink the range to end before the turn starts, or wait until the whole turn ages out of the protected zone.`
2475
+ );
2476
+ }
2477
+ warnings.push(
2478
+ `Withdrawn ${beforeWithdraw - filteredIds.length} message(s) from compression range to keep ${splitTurnCount} turn(s) intact (visible tool-call would lose its reasoning run).`
2479
+ );
2480
+ }
2481
+ }
2384
2482
  if (!isBlockBoundary && filteredIds.length === 0 && consumedBlockIds.length > 0) {
2385
2483
  const first = consumedBlockIds[0];
2386
2484
  const last = consumedBlockIds[consumedBlockIds.length - 1];
@@ -3986,6 +4084,13 @@ function resolveReasoningDrop(cfg) {
3986
4084
  }
3987
4085
  return { drop: cfg?.drop !== false, threshold };
3988
4086
  }
4087
+ function isStrictReasoningEcho(provider, baseUrl) {
4088
+ return /deepseek/i.test(baseUrl ?? "") || /deepseek/i.test(provider ?? "");
4089
+ }
4090
+ function applyStrictReasoningGate(cfg, provider, baseUrl) {
4091
+ if (!cfg.drop || !isStrictReasoningEcho(provider, baseUrl)) return cfg;
4092
+ return { ...cfg, drop: false };
4093
+ }
3989
4094
  function isThinking(part) {
3990
4095
  const p = part;
3991
4096
  return p?.type === "thinking" && typeof p.thinking === "string";
@@ -5235,6 +5340,7 @@ function createRuntime(adapter) {
5235
5340
  function dropTokenScale(sid) {
5236
5341
  tokenScaleStale.delete(sid);
5237
5342
  }
5343
+ const strictEchoLogged = /* @__PURE__ */ new Set();
5238
5344
  const compressOutcomeSeen = /* @__PURE__ */ new Set();
5239
5345
  let compressFailTurnKey = null;
5240
5346
  let compressFailCount = 0;
@@ -5289,7 +5395,16 @@ function createRuntime(adapter) {
5289
5395
  }
5290
5396
  function reasoningDropFor(ctx) {
5291
5397
  const m2 = ctx.model;
5292
- return resolveReasoningDrop(resolveCompress(adapterRef.compress, m2?.provider, m2?.id).reasoning);
5398
+ const resolved = resolveReasoningDrop(resolveCompress(adapterRef.compress, m2?.provider, m2?.id).reasoning);
5399
+ const gated = applyStrictReasoningGate(resolved, m2?.provider, m2?.baseUrl);
5400
+ if (resolved.drop && !gated.drop) {
5401
+ const sid = ctx.sessionManager.getSessionId();
5402
+ if (!strictEchoLogged.has(sid)) {
5403
+ strictEchoLogged.add(sid);
5404
+ logInfo("runtime", { sid, event: "compress-reasoning-auto-disabled", reason: "strict-echo-upstream", provider: m2?.provider ?? null, issue: "#361" });
5405
+ }
5406
+ }
5407
+ return gated;
5293
5408
  }
5294
5409
  async function reloadConfig(cwd) {
5295
5410
  let user;
@@ -16867,7 +16982,7 @@ async function statusReport(runtime, ctx) {
16867
16982
  const sentTokens = estimateTokens(coreMessages, coveredIds, imageTokens) + systemPromptTokens;
16868
16983
  const viewSentTokens = adjustedTokenCount(runtime.core, coreMessages, state, config, sentTokens, imageTokens, systemPromptTokens);
16869
16984
  const turn = runtime.core.processTurn({ messages: coreMessages, state, config, tokenCount: anchorStale ? viewSentTokens : Math.max(viewSentTokens, realUsage?.tokens ?? 0) });
16870
- const versionStr = "0.1.65" ? `billion-context-pi@${"0.1.65"}` : void 0;
16985
+ const versionStr = "0.1.66" ? `billion-context-pi@${"0.1.66"}` : void 0;
16871
16986
  let text = buildStatusPanel({
16872
16987
  version: versionStr,
16873
16988
  tokenCount: sessionTokens,
@@ -17565,7 +17680,7 @@ async function autoInstallLatest(latest, extDirOverride) {
17565
17680
  "--no-fund",
17566
17681
  "--no-save"
17567
17682
  ];
17568
- const prevVersion = (await readPackageJson(join11(extDir, "package.json")))?.version ?? "0.1.65";
17683
+ const prevVersion = (await readPackageJson(join11(extDir, "package.json")))?.version ?? "0.1.66";
17569
17684
  const { code, stderr } = await runNpmImpl(installArgs(latest), { cwd: npmDir, timeout: 6e4 });
17570
17685
  if (code !== 0) {
17571
17686
  logWarn("update", {
@@ -17583,7 +17698,7 @@ async function autoInstallLatest(latest, extDirOverride) {
17583
17698
  }
17584
17699
  const verify = await verifyInstall(npmDir, latest);
17585
17700
  if (!verify.ok) {
17586
- const rollbackTo = SEMVER_RE.test(prevVersion) ? prevVersion : "0.1.65";
17701
+ const rollbackTo = SEMVER_RE.test(prevVersion) ? prevVersion : "0.1.66";
17587
17702
  logWarn("update", { event: "auto-install-verify-failed", latest, reason: verify.reason, rollbackTo });
17588
17703
  const rb = await runNpmImpl(installArgs(rollbackTo), { cwd: npmDir, timeout: 6e4 });
17589
17704
  logInfo("update", { event: "rollback", from: latest, to: rollbackTo, ok: rb.code === 0 });
@@ -17658,7 +17773,7 @@ async function checkForUpdate(autoUpdate, notify) {
17658
17773
  }
17659
17774
  const latest = await fetchLatestVersion(tag);
17660
17775
  if (!latest) return;
17661
- const current = runtimeVersion ?? "0.1.65";
17776
+ const current = runtimeVersion ?? "0.1.66";
17662
17777
  const hasUpdate = isVersionNewer(latest, current);
17663
17778
  debug.event("update-check", {
17664
17779
  current,
@@ -17836,7 +17951,7 @@ function wireSessionLifecycle(pi, runtime, standDownIfProxied) {
17836
17951
  setDelegatePolicy(DEFAULT_DELEGATE_POLICY);
17837
17952
  const sid = ctx.sessionManager.getSessionId();
17838
17953
  const modelInfo = ctx.model;
17839
- logInfo("session", { event: "start", sid, cwd: ctx.cwd, debug: runtime.adapter.debug ?? null, version: true ? "0.1.65" : null, model: modelInfo?.id ?? null, modelApi: modelInfo?.api ?? null, contextWindow: modelInfo?.contextWindow ?? null });
17954
+ logInfo("session", { event: "start", sid, cwd: ctx.cwd, debug: runtime.adapter.debug ?? null, version: true ? "0.1.66" : null, model: modelInfo?.id ?? null, modelApi: modelInfo?.api ?? null, contextWindow: modelInfo?.contextWindow ?? null });
17840
17955
  try {
17841
17956
  await runtime.reloadConfig(ctx.cwd);
17842
17957
  const delegateCfg = resolveDelegate(runtime.adapter);