billion-context-pi 0.1.64 → 0.1.65-pr.327.152

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
@@ -10,7 +10,7 @@ import { readFileSync as readFileSync2 } from "fs";
10
10
  import { homedir as homedir8 } from "os";
11
11
  import { join as join12 } from "path";
12
12
 
13
- // node_modules/acp-kernel/dist/chunk-JGNVAFFE.js
13
+ // node_modules/acp-kernel/dist/chunk-6TAK7DSI.js
14
14
  import { createRequire } from "module";
15
15
  var require2 = createRequire(import.meta.url);
16
16
  function defaultCountTokens(text) {
@@ -19,6 +19,12 @@ function defaultCountTokens(text) {
19
19
  const cjkCount = cjk?.length ?? 0;
20
20
  return cjkCount + Math.ceil((text.length - cjkCount) / 4);
21
21
  }
22
+ function thinkingTokenValue(thinking) {
23
+ return typeof thinking === "number" && Number.isFinite(thinking) && thinking > 0 ? thinking : 0;
24
+ }
25
+ function countMessageTokens(message, countTokens = defaultCountTokens) {
26
+ return countTokens(message.text ?? "") + thinkingTokenValue(message.thinkingTokens);
27
+ }
22
28
  function estimateTokensFast(text) {
23
29
  if (!text) return 0;
24
30
  return Math.ceil(text.length / 4);
@@ -1564,7 +1570,8 @@ function renderMessage(message, map, countTokens, strategy, snapshot = null) {
1564
1570
  "^" + escapeRegex(TAG_OPEN) + "[^>]*" + GT + escapeRegex(ref) + escapeRegex(TAG_CLOSE) + "\\n?"
1565
1571
  );
1566
1572
  const cleanText = (message.text || "").replace(ownTagRe, "");
1567
- const tokens = snapshot ? snapshot[ref] ?? (snapshot[ref] = countTokens(cleanText)) : countTokens(cleanText);
1573
+ const textTokens = snapshot ? snapshot[ref] ?? (snapshot[ref] = countTokens(cleanText)) : countTokens(cleanText);
1574
+ const tokens = textTokens + thinkingTokenValue(message.thinkingTokens);
1568
1575
  const type = classifyType(message);
1569
1576
  const prefix = acpTag(ref, tokens, type) + "\n";
1570
1577
  if (!cleanText) return { ...message, text: prefix };
@@ -1683,7 +1690,7 @@ function computeProtectedRefs(messages, state, config, countTokens = estimateTex
1683
1690
  if (isNeverPreserveRecent(msg)) continue;
1684
1691
  const ref = state.messageRefs.byRaw[msg.id];
1685
1692
  if (!ref || ref === "BLOCKED") continue;
1686
- visible.push({ ref, tokens: countTokens(msg.text ?? "") });
1693
+ visible.push({ ref, tokens: countMessageTokens(msg, countTokens) });
1687
1694
  }
1688
1695
  if (preserveN > 0) {
1689
1696
  for (const m2 of visible.slice(-preserveN)) {
@@ -1726,7 +1733,7 @@ function buildCompressibleRanges(messages, state, config, protectedZoneRefs, cou
1726
1733
  protectedMsgs.push({
1727
1734
  ref,
1728
1735
  gapBefore: skipSinceProtected,
1729
- tokens: countTokens(msg.text ?? ""),
1736
+ tokens: countMessageTokens(msg, countTokens),
1730
1737
  tools: msg.toolName ? [msg.toolName] : []
1731
1738
  });
1732
1739
  skipSinceProtected = false;
@@ -1741,7 +1748,7 @@ function buildCompressibleRanges(messages, state, config, protectedZoneRefs, cou
1741
1748
  compressibleMsgs.push({
1742
1749
  ref,
1743
1750
  gapBefore: skipSinceCompressible,
1744
- tokens: countTokens(msg.text ?? ""),
1751
+ tokens: countMessageTokens(msg, countTokens),
1745
1752
  chars: (msg.text ?? "").length,
1746
1753
  isTool: isToolMessage(msg),
1747
1754
  isUser: msg.role === "user"
@@ -2387,7 +2394,7 @@ function applySingleRange(input) {
2387
2394
  let compressedTokens = 0;
2388
2395
  for (const id of filteredIds) {
2389
2396
  const message = input.messages.find((entry) => entry.id === id);
2390
- compressedTokens += input.countTokens(message?.text ?? "");
2397
+ compressedTokens += message ? countMessageTokens(message, input.countTokens) : 0;
2391
2398
  }
2392
2399
  for (const consumedId of consumedBlockIds) {
2393
2400
  const consumed = blockById(input.state, consumedId);
@@ -2594,6 +2601,9 @@ function decideNudge(input) {
2594
2601
  const growthReady = firstSightMassReady || growthSinceReference >= growthFloor;
2595
2602
  const t2Count = tiers[2]?.targetBlocks.length ?? 0;
2596
2603
  const t3Count = tiers[3]?.targetBlocks.length ?? 0;
2604
+ const tierCountUsageFloor = config.nudge.minContextLimitPct;
2605
+ const t2CountReady = t2Count >= config.tiers.tier2Trigger && usage >= tierCountUsageFloor;
2606
+ const t3CountReady = t3Count >= config.tiers.tier3Trigger && usage >= tierCountUsageFloor;
2597
2607
  if (pressure) {
2598
2608
  const candidates = [1];
2599
2609
  if (config.tiers.enabled) {
@@ -2616,19 +2626,19 @@ function decideNudge(input) {
2616
2626
  if (t1Eff >= nudgeGrowthTokens) {
2617
2627
  injectedTier = 1;
2618
2628
  injectedReason = `T1 effective ${t1Eff} >= ${nudgeGrowthTokens}, growth ${growthSinceReference}, usage ${Math.round(usage * 100)}%`;
2619
- } else if (config.tiers.enabled && (t2Count >= config.tiers.tier2Trigger || t2Pen >= tier2Threshold && t2Pen > t1Eff)) {
2629
+ } else if (config.tiers.enabled && (t2CountReady || t2Pen >= tier2Threshold && t2Pen > t1Eff)) {
2620
2630
  const lastShown = state.nudge.lastShownByTier[2] ?? 0;
2621
2631
  const cadenceMet = lastShown === 0 || tokenCount - lastShown >= growthFloor;
2622
2632
  if (cadenceMet) {
2623
2633
  injectedTier = 2;
2624
- injectedReason = t2Count >= config.tiers.tier2Trigger ? `T2 distill ready: ${t2Count} tier-1 blocks >= tier2Trigger ${config.tiers.tier2Trigger} (${t2Pen} tokens), usage ${Math.round(usage * 100)}%` : `T2 distill ready: ${tiers[2].targetBlocks.length} tier-1 blocks (${t2Pen} tokens) >= ${tier2Threshold} (1.5x) and > T1 effective ${t1Eff}, usage ${Math.round(usage * 100)}%`;
2634
+ injectedReason = t2CountReady ? `T2 distill ready: ${t2Count} tier-1 blocks >= tier2Trigger ${config.tiers.tier2Trigger} (${t2Pen} tokens), usage ${Math.round(usage * 100)}%` : `T2 distill ready: ${tiers[2].targetBlocks.length} tier-1 blocks (${t2Pen} tokens) >= ${tier2Threshold} (1.5x) and > T1 effective ${t1Eff}, usage ${Math.round(usage * 100)}%`;
2625
2635
  }
2626
- } else if (config.tiers.enabled && (t3Count >= config.tiers.tier3Trigger || t3Pen >= tier2Threshold && t3Pen > t2Pen && t3Pen > t1Eff)) {
2636
+ } else if (config.tiers.enabled && (t3CountReady || t3Pen >= tier2Threshold && t3Pen > t2Pen && t3Pen > t1Eff)) {
2627
2637
  const lastShown = state.nudge.lastShownByTier[3] ?? 0;
2628
2638
  const cadenceMet = lastShown === 0 || tokenCount - lastShown >= growthFloor;
2629
2639
  if (cadenceMet) {
2630
2640
  injectedTier = 3;
2631
- injectedReason = t3Count >= config.tiers.tier3Trigger ? `T3 condense ready: ${t3Count} tier-2 blocks >= tier3Trigger ${config.tiers.tier3Trigger} (${t3Pen} tokens), usage ${Math.round(usage * 100)}%` : `T3 condense ready: ${tiers[3].targetBlocks.length} tier-2 blocks (${t3Pen} tokens) >= ${tier2Threshold} (1.5x) and > T2 ${t2Pen} and > T1 effective ${t1Eff}, usage ${Math.round(usage * 100)}%`;
2641
+ injectedReason = t3CountReady ? `T3 condense ready: ${t3Count} tier-2 blocks >= tier3Trigger ${config.tiers.tier3Trigger} (${t3Pen} tokens), usage ${Math.round(usage * 100)}%` : `T3 condense ready: ${tiers[3].targetBlocks.length} tier-2 blocks (${t3Pen} tokens) >= ${tier2Threshold} (1.5x) and > T2 ${t2Pen} and > T1 effective ${t1Eff}, usage ${Math.round(usage * 100)}%`;
2632
2642
  }
2633
2643
  }
2634
2644
  }
@@ -2645,9 +2655,14 @@ function decideNudge(input) {
2645
2655
  } else {
2646
2656
  const tiersList = [1, 2, 3];
2647
2657
  const eligible = tiersList.filter((t) => config.tiers.enabled || t === 1);
2648
- const countReady = (t) => t === 2 ? t2Count >= config.tiers.tier2Trigger : t === 3 ? t3Count >= config.tiers.tier3Trigger : false;
2658
+ const countReadyUngated = (t) => t === 2 ? t2Count >= config.tiers.tier2Trigger : t === 3 ? t3Count >= config.tiers.tier3Trigger : false;
2659
+ const countReady = (t) => countReadyUngated(t) && usage >= tierCountUsageFloor;
2649
2660
  const ready = eligible.filter((t) => (tiers[t]?.pending ?? 0) >= nudgeGrowthTokens).map((t) => `T${t} ${tiers[t].pending}`);
2650
- const readyCount = eligible.filter((t) => (tiers[t]?.pending ?? 0) < nudgeGrowthTokens && countReady(t)).map((t) => `T${t} ${t === 2 ? t2Count : t3Count} blocks (count)`);
2661
+ const readyCount = eligible.filter(
2662
+ (t) => (tiers[t]?.pending ?? 0) < nudgeGrowthTokens && countReadyUngated(t)
2663
+ ).map(
2664
+ (t) => `T${t} ${t === 2 ? t2Count : t3Count} blocks (count${usage >= tierCountUsageFloor ? "" : ", usage-gated"})`
2665
+ );
2651
2666
  const readyAll = [...ready, ...readyCount];
2652
2667
  const readyHint = readyAll.length > 0 ? `, ready: ${readyAll.join(", ")}` : "";
2653
2668
  const blocked = eligible.filter(
@@ -2709,7 +2724,7 @@ function computeContextBreakdown(messages, total, growth, countTokens) {
2709
2724
  const count = countTokens ?? ((t) => Math.ceil(t.length / 4));
2710
2725
  let system = 0, tool = 0, summaries = 0, code = 0, text = 0;
2711
2726
  for (const msg of messages) {
2712
- const tokens = count(msg.text ?? "");
2727
+ const tokens = countMessageTokens(msg, count);
2713
2728
  if (msg.text?.startsWith("[Compressed conversation section]")) {
2714
2729
  summaries += tokens;
2715
2730
  } else if (msg.contentType === "tool-call" || msg.contentType === "tool-result") {
@@ -2871,7 +2886,7 @@ function collectVisible(messages, state, countTokens) {
2871
2886
  if (coveredIds.has(message.id)) return;
2872
2887
  const ref = refForRaw(state.messageRefs, message.id);
2873
2888
  if (!ref) return;
2874
- const tokens = countTokens(message.text ?? "");
2889
+ const tokens = countMessageTokens(message, countTokens);
2875
2890
  const tool = isToolMessage(message) ? message.toolName ?? (message.toolCallId ? toolCallNames.get(message.toolCallId) : void 0) ?? "tool" : "text";
2876
2891
  if (tokens > 0) visible.push({ ref, tokens, tool, index });
2877
2892
  });
@@ -4088,6 +4103,8 @@ function projectMessage(message, id) {
4088
4103
  }];
4089
4104
  }
4090
4105
  if (role === "assistant") {
4106
+ const thinking = thinkingTokenCount(msg.content);
4107
+ const thinkingField = thinking > 0 ? { thinkingTokens: thinking } : {};
4091
4108
  const calls = allToolCalls(msg.content);
4092
4109
  if (calls.length > 0) {
4093
4110
  const textParts = extractText(msg.content);
@@ -4096,9 +4113,9 @@ function projectMessage(message, id) {
4096
4113
  const argStr = stringifyArgs(call.arguments);
4097
4114
  const text2 = argStr && textParts ? `${textParts}
4098
4115
  ${argStr}` : argStr || textParts;
4099
- return [{ id, role: "assistant", contentType: "tool-call", toolName: call.name, toolCallId: call.id, text: text2 }];
4116
+ return [{ id, role: "assistant", contentType: "tool-call", toolName: call.name, toolCallId: call.id, text: text2, ...thinkingField }];
4100
4117
  }
4101
- return calls.map((call) => {
4118
+ return calls.map((call, i) => {
4102
4119
  const argStr = stringifyArgs(call.arguments);
4103
4120
  return {
4104
4121
  id: `${id}#${call.id}`,
@@ -4106,13 +4123,14 @@ ${argStr}` : argStr || textParts;
4106
4123
  contentType: "tool-call",
4107
4124
  toolName: call.name,
4108
4125
  toolCallId: call.id,
4109
- text: argStr || textParts
4126
+ text: argStr || textParts,
4127
+ ...i === 0 ? thinkingField : {}
4110
4128
  };
4111
4129
  });
4112
4130
  }
4113
4131
  const text = extractText(msg.content);
4114
4132
  if (!text.trim()) return [];
4115
- return [{ id, role: "assistant", contentType: "text", text }];
4133
+ return [{ id, role: "assistant", contentType: "text", text, ...thinkingField }];
4116
4134
  }
4117
4135
  const customText = extractText(msg.content) || fallbackText(msg);
4118
4136
  return customText.length > 0 ? [{ id, role: "user", contentType: "text", text: customText }] : [];
@@ -4140,6 +4158,15 @@ function extractText(content) {
4140
4158
  }
4141
4159
  return parts.join("\n");
4142
4160
  }
4161
+ function thinkingTokenCount(content) {
4162
+ if (!Array.isArray(content)) return 0;
4163
+ const parts = [];
4164
+ for (const block of content) {
4165
+ const b2 = block;
4166
+ if (b2.type === "thinking" && typeof b2.thinking === "string") parts.push(b2.thinking);
4167
+ }
4168
+ return parts.length > 0 ? defaultCountTokens(parts.join("\n")) : 0;
4169
+ }
4143
4170
  function stripRefTag(text) {
4144
4171
  return text.replace(REF_TAG, "").replace(TRAILING_REF_TAG, "");
4145
4172
  }
@@ -5157,8 +5184,37 @@ function createRuntime(adapter) {
5157
5184
  let adapterRef = adapter;
5158
5185
  let lastUserConfigKey;
5159
5186
  let promptsRef = defaultPrompts;
5160
- const nudgeShownTurns = /* @__PURE__ */ new Set();
5187
+ const nudgeShownTurns = /* @__PURE__ */ new Map();
5161
5188
  const nudgeShownTokens = /* @__PURE__ */ new Map();
5189
+ function markNudgeShown(sid, turnKey, tokenCount) {
5190
+ let turns = nudgeShownTurns.get(sid);
5191
+ if (!turns) {
5192
+ turns = /* @__PURE__ */ new Set();
5193
+ nudgeShownTurns.set(sid, turns);
5194
+ }
5195
+ turns.add(turnKey);
5196
+ if (tokenCount !== void 0) {
5197
+ let toks = nudgeShownTokens.get(sid);
5198
+ if (!toks) {
5199
+ toks = /* @__PURE__ */ new Map();
5200
+ nudgeShownTokens.set(sid, toks);
5201
+ }
5202
+ toks.set(turnKey, tokenCount);
5203
+ }
5204
+ }
5205
+ function nudgeShownFor(sid, turnKey) {
5206
+ return nudgeShownTurns.get(sid)?.has(turnKey) ?? false;
5207
+ }
5208
+ function nudgeShownTokensFor(sid, turnKey) {
5209
+ return nudgeShownTokens.get(sid)?.get(turnKey);
5210
+ }
5211
+ function clearNudgeTracking(sid) {
5212
+ nudgeShownTurns.delete(sid);
5213
+ nudgeShownTokens.delete(sid);
5214
+ }
5215
+ function clearNudgeTokenStamps(sid) {
5216
+ nudgeShownTokens.delete(sid);
5217
+ }
5162
5218
  const overflowEpisodes = /* @__PURE__ */ new Map();
5163
5219
  function overflowFor(sid) {
5164
5220
  let ep = overflowEpisodes.get(sid);
@@ -5208,34 +5264,40 @@ function createRuntime(adapter) {
5208
5264
  function dropTokenScale(sid) {
5209
5265
  tokenScaleStale.delete(sid);
5210
5266
  }
5211
- const compressOutcomeSeen = /* @__PURE__ */ new Set();
5212
- let compressFailTurnKey = null;
5213
- let compressFailCount = 0;
5214
- function noteCompressOutcomes(turnKey, outcomes) {
5215
- if (compressFailTurnKey !== turnKey) {
5216
- compressFailTurnKey = turnKey;
5217
- compressFailCount = 0;
5267
+ const compressOutcomes = /* @__PURE__ */ new Map();
5268
+ function compressTrackerFor(sid) {
5269
+ let t = compressOutcomes.get(sid);
5270
+ if (!t) {
5271
+ t = { seen: /* @__PURE__ */ new Set(), failTurnKey: null, failCount: 0 };
5272
+ compressOutcomes.set(sid, t);
5218
5273
  }
5219
- const prevCount = compressFailCount;
5274
+ return t;
5275
+ }
5276
+ function noteCompressOutcomes(sid, turnKey, outcomes) {
5277
+ const t = compressTrackerFor(sid);
5278
+ if (t.failTurnKey !== turnKey) {
5279
+ t.failTurnKey = turnKey;
5280
+ t.failCount = 0;
5281
+ }
5282
+ const prevCount = t.failCount;
5220
5283
  for (const o of outcomes) {
5221
- if (compressOutcomeSeen.has(o.toolCallId)) continue;
5222
- compressOutcomeSeen.add(o.toolCallId);
5284
+ if (t.seen.has(o.toolCallId)) continue;
5285
+ t.seen.add(o.toolCallId);
5223
5286
  if (o.isError || o.noop === true) {
5224
- compressFailCount += 1;
5287
+ t.failCount += 1;
5225
5288
  } else if (o.success) {
5226
- compressFailCount = 0;
5289
+ t.failCount = 0;
5227
5290
  }
5228
5291
  }
5229
- const cappedNow = compressFailCount >= MAX_COMPRESS_ATTEMPTS && prevCount < MAX_COMPRESS_ATTEMPTS;
5230
- return { count: compressFailCount, cappedNow };
5292
+ const cappedNow = t.failCount >= MAX_COMPRESS_ATTEMPTS && prevCount < MAX_COMPRESS_ATTEMPTS;
5293
+ return { count: t.failCount, cappedNow };
5231
5294
  }
5232
- function compressRetryCappedFor(turnKey) {
5233
- return compressFailTurnKey === turnKey && compressFailCount >= MAX_COMPRESS_ATTEMPTS;
5295
+ function compressRetryCappedFor(sid, turnKey) {
5296
+ const t = compressOutcomes.get(sid);
5297
+ return t !== void 0 && t.failTurnKey === turnKey && t.failCount >= MAX_COMPRESS_ATTEMPTS;
5234
5298
  }
5235
- function clearCompressRetryTracking() {
5236
- compressOutcomeSeen.clear();
5237
- compressFailTurnKey = null;
5238
- compressFailCount = 0;
5299
+ function clearCompressRetryTracking(sid) {
5300
+ compressOutcomes.delete(sid);
5239
5301
  }
5240
5302
  async function acquireLock(sid) {
5241
5303
  const prev = locks.get(sid) ?? Promise.resolve();
@@ -5336,13 +5398,7 @@ function createRuntime(adapter) {
5336
5398
  return promptsRef;
5337
5399
  }, setPrompts: (p) => {
5338
5400
  promptsRef = p;
5339
- }, markNudgeShown: (k, t) => {
5340
- nudgeShownTurns.add(k);
5341
- if (t !== void 0) nudgeShownTokens.set(k, t);
5342
- }, nudgeShownFor: (k) => nudgeShownTurns.has(k), nudgeShownTokensFor: (k) => nudgeShownTokens.get(k), clearNudgeTracking: () => {
5343
- nudgeShownTurns.clear();
5344
- nudgeShownTokens.clear();
5345
- }, clearNudgeTokenStamps: () => nudgeShownTokens.clear(), noteCompressOutcomes, compressRetryCappedFor, clearCompressRetryTracking, liveContextLimit, configFor, reasoningDropFor, reloadConfig, stateFor, save, acquireLock, overflowFor, overflowDrop, noteDeadCompress, clearDeadCompress, throttleFor, throttleDrop, noteTokenScale, dropTokenScale };
5401
+ }, markNudgeShown, nudgeShownFor, nudgeShownTokensFor, clearNudgeTracking, clearNudgeTokenStamps, noteCompressOutcomes, compressRetryCappedFor, clearCompressRetryTracking, liveContextLimit, configFor, reasoningDropFor, reloadConfig, stateFor, save, acquireLock, overflowFor, overflowDrop, noteDeadCompress, clearDeadCompress, throttleFor, throttleDrop, noteTokenScale, dropTokenScale };
5346
5402
  }
5347
5403
 
5348
5404
  // node_modules/typebox/build/system/memory/memory.mjs
@@ -9769,6 +9825,7 @@ function estimateTokens(messages, coveredIds, imageTokensById) {
9769
9825
  if (m2.toolName === "compress") continue;
9770
9826
  if (coveredIds?.has(m2.id)) continue;
9771
9827
  tokens += defaultCountTokens(m2.text ?? "");
9828
+ tokens += m2.thinkingTokens ?? 0;
9772
9829
  const img = imageTokensById?.get(m2.id);
9773
9830
  if (img) tokens += img;
9774
9831
  }
@@ -10064,7 +10121,7 @@ async function handleCompress(args, runtime, ctx, toolCallId) {
10064
10121
  });
10065
10122
  const turnKey = lastUserMessageId(entries) ?? sid;
10066
10123
  const snapshot = compressibleSnapshotText(turn.nudge);
10067
- if (runtime.compressRetryCappedFor(turnKey)) {
10124
+ if (runtime.compressRetryCappedFor(sid, turnKey)) {
10068
10125
  logWarn("compress", { sid, event: "capped-reject", turnKey });
10069
10126
  return cappedRejectionText(snapshot);
10070
10127
  }
@@ -16833,12 +16890,13 @@ async function statusReport(runtime, ctx) {
16833
16890
  const systemPromptTokens = systemPromptText ? defaultCountTokens(systemPromptText) : 0;
16834
16891
  const imageTokens = collectImageTokens(entries, modelSupportsImages(ctx.model));
16835
16892
  const imageTokensTotal = [...imageTokens.values()].reduce((a, b2) => a + b2, 0);
16836
- const sessionTokens = !anchorStale && realUsage?.tokens && realUsage.tokens > 0 ? realUsage.tokens : defaultCountTokens(coreMessages.map((m2) => m2.text ?? "").join("\n")) + imageTokensTotal;
16893
+ const thinkingTokensTotal = coreMessages.reduce((sum, m2) => sum + (m2.thinkingTokens ?? 0), 0);
16894
+ const sessionTokens = !anchorStale && realUsage?.tokens && realUsage.tokens > 0 ? realUsage.tokens : defaultCountTokens(coreMessages.map((m2) => m2.text ?? "").join("\n")) + imageTokensTotal + thinkingTokensTotal;
16837
16895
  const coveredIds = collectCoveredMessageIds(state);
16838
16896
  const sentTokens = estimateTokens(coreMessages, coveredIds, imageTokens) + systemPromptTokens;
16839
16897
  const viewSentTokens = adjustedTokenCount(runtime.core, coreMessages, state, config, sentTokens, imageTokens, systemPromptTokens);
16840
16898
  const turn = runtime.core.processTurn({ messages: coreMessages, state, config, tokenCount: anchorStale ? viewSentTokens : Math.max(viewSentTokens, realUsage?.tokens ?? 0) });
16841
- const versionStr = "0.1.64" ? `billion-context-pi@${"0.1.64"}` : void 0;
16899
+ const versionStr = "0.1.65" ? `billion-context-pi@${"0.1.65"}` : void 0;
16842
16900
  let text = buildStatusPanel({
16843
16901
  version: versionStr,
16844
16902
  tokenCount: sessionTokens,
@@ -16846,7 +16904,7 @@ async function statusReport(runtime, ctx) {
16846
16904
  state: turn.state,
16847
16905
  nudge: turn.nudge,
16848
16906
  modelContextLimit: config.modelContextLimit,
16849
- unprunedTokens: coreMessages.reduce((sum, m2) => sum + defaultCountTokens(m2.text ?? "") + (imageTokens.get(m2.id) ?? 0), 0),
16907
+ unprunedTokens: coreMessages.reduce((sum, m2) => sum + defaultCountTokens(m2.text ?? "") + (m2.thinkingTokens ?? 0) + (imageTokens.get(m2.id) ?? 0), 0),
16850
16908
  cacheUsages: cacheUsageSamples(entries ?? [])
16851
16909
  });
16852
16910
  const delegateUsage = getDelegateUsage();
@@ -17536,7 +17594,7 @@ async function autoInstallLatest(latest, extDirOverride) {
17536
17594
  "--no-fund",
17537
17595
  "--no-save"
17538
17596
  ];
17539
- const prevVersion = (await readPackageJson(join11(extDir, "package.json")))?.version ?? "0.1.64";
17597
+ const prevVersion = (await readPackageJson(join11(extDir, "package.json")))?.version ?? "0.1.65";
17540
17598
  const { code, stderr } = await runNpmImpl(installArgs(latest), { cwd: npmDir, timeout: 6e4 });
17541
17599
  if (code !== 0) {
17542
17600
  logWarn("update", {
@@ -17554,7 +17612,7 @@ async function autoInstallLatest(latest, extDirOverride) {
17554
17612
  }
17555
17613
  const verify = await verifyInstall(npmDir, latest);
17556
17614
  if (!verify.ok) {
17557
- const rollbackTo = SEMVER_RE.test(prevVersion) ? prevVersion : "0.1.64";
17615
+ const rollbackTo = SEMVER_RE.test(prevVersion) ? prevVersion : "0.1.65";
17558
17616
  logWarn("update", { event: "auto-install-verify-failed", latest, reason: verify.reason, rollbackTo });
17559
17617
  const rb = await runNpmImpl(installArgs(rollbackTo), { cwd: npmDir, timeout: 6e4 });
17560
17618
  logInfo("update", { event: "rollback", from: latest, to: rollbackTo, ok: rb.code === 0 });
@@ -17629,7 +17687,7 @@ async function checkForUpdate(autoUpdate, notify) {
17629
17687
  }
17630
17688
  const latest = await fetchLatestVersion(tag);
17631
17689
  if (!latest) return;
17632
- const current = runtimeVersion ?? "0.1.64";
17690
+ const current = runtimeVersion ?? "0.1.65";
17633
17691
  const hasUpdate = isVersionNewer(latest, current);
17634
17692
  debug.event("update-check", {
17635
17693
  current,
@@ -17799,15 +17857,15 @@ function wireSessionLifecycle(pi, runtime, standDownIfProxied) {
17799
17857
  }
17800
17858
  if (standDownIfProxied(ctx)) return;
17801
17859
  runtime.store.invalidate();
17802
- runtime.clearNudgeTracking();
17860
+ runtime.clearNudgeTracking(ctx.sessionManager.getSessionId());
17803
17861
  runtime.throttleFor(ctx.sessionManager.getSessionId()).reset();
17804
- runtime.clearCompressRetryTracking();
17862
+ runtime.clearCompressRetryTracking(ctx.sessionManager.getSessionId());
17805
17863
  resetDelegateUsage();
17806
17864
  setDelegateDisplayUsage("separate");
17807
17865
  setDelegatePolicy(DEFAULT_DELEGATE_POLICY);
17808
17866
  const sid = ctx.sessionManager.getSessionId();
17809
17867
  const modelInfo = ctx.model;
17810
- logInfo("session", { event: "start", sid, cwd: ctx.cwd, debug: runtime.adapter.debug ?? null, version: true ? "0.1.64" : null, model: modelInfo?.id ?? null, modelApi: modelInfo?.api ?? null, contextWindow: modelInfo?.contextWindow ?? null });
17868
+ 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 });
17811
17869
  try {
17812
17870
  await runtime.reloadConfig(ctx.cwd);
17813
17871
  const delegateCfg = resolveDelegate(runtime.adapter);
@@ -17844,8 +17902,11 @@ function wireSessionLifecycle(pi, runtime, standDownIfProxied) {
17844
17902
  delegateStatusWidget.setContext(ctx, runningRunsSnapshot);
17845
17903
  });
17846
17904
  pi.on("session_shutdown", (_event, ctx) => {
17847
- runtime.clearDeadCompress(ctx.sessionManager.getSessionId());
17848
- runtime.dropTokenScale(ctx.sessionManager.getSessionId());
17905
+ const sid = ctx.sessionManager.getSessionId();
17906
+ runtime.clearDeadCompress(sid);
17907
+ runtime.dropTokenScale(sid);
17908
+ runtime.clearNudgeTracking(sid);
17909
+ runtime.clearCompressRetryTracking(sid);
17849
17910
  delegateStatusWidget.dispose();
17850
17911
  closeLogStream();
17851
17912
  });
@@ -17902,7 +17963,7 @@ function wireContextTransform(pi, runtime, standDownIfProxied) {
17902
17963
  state.nudge.lastNudgeShownTokens = 0;
17903
17964
  state.nudge.lastPerMessageNudgeTokens = 0;
17904
17965
  state.nudge.lastShownByTier = {};
17905
- runtime.clearNudgeTokenStamps();
17966
+ runtime.clearNudgeTokenStamps(sid);
17906
17967
  logInfo("growth-scale", { sid, event: "scale-flip-reset", anchorStale: !hostFloorActive });
17907
17968
  }
17908
17969
  debug.event("context-in", {
@@ -17984,24 +18045,24 @@ function wireContextTransform(pi, runtime, standDownIfProxied) {
17984
18045
  const debugOn2 = debug.enabled;
17985
18046
  const turnKey = lastUserMessageId(entries) ?? sid;
17986
18047
  const compressOutcomes = collectCompressOutcomes(entries, turnStartIndex(entries));
17987
- const outcome = compressOutcomes.length > 0 ? runtime.noteCompressOutcomes(turnKey, compressOutcomes) : null;
18048
+ const outcome = compressOutcomes.length > 0 ? runtime.noteCompressOutcomes(sid, turnKey, compressOutcomes) : null;
17988
18049
  const adaptiveGrowth = !config.modelContextLimit || config.modelContextLimit <= 0 ? config.nudge.growthFloor : Math.min(
17989
18050
  config.nudge.growthCap,
17990
18051
  Math.max(config.nudge.growthFloor, Math.round(config.modelContextLimit * config.nudge.growthRatio))
17991
18052
  );
17992
18053
  const reInjectFloor = Math.max(config.nudge.minGrowthFloor, config.nudge.minGrowthRatio * adaptiveGrowth);
17993
- let shownAt = runtime.nudgeShownTokensFor(turnKey);
18054
+ let shownAt = runtime.nudgeShownTokensFor(sid, turnKey);
17994
18055
  if (shownAt !== void 0 && tokenCount < shownAt - adaptiveGrowth) {
17995
18056
  logInfo("nudge", { sid: ctx.sessionManager.getSessionId(), event: "drop-reanchor", turnKey, from: shownAt, to: tokenCount });
17996
18057
  shownAt = tokenCount;
17997
- runtime.markNudgeShown(turnKey, tokenCount);
18058
+ runtime.markNudgeShown(sid, turnKey, tokenCount);
17998
18059
  }
17999
18060
  if (turn.nudge?.shouldInject) {
18000
18061
  const emergency = turn.nudge.breakdown?.emergencyOverride === 1;
18001
18062
  turn.nudge.compressibleRanges = viableRanges(turn.nudge.compressibleRanges);
18002
- const retryCapped = runtime.compressRetryCappedFor(turnKey);
18063
+ const retryCapped = runtime.compressRetryCappedFor(sid, turnKey);
18003
18064
  const reInjectReady = shownAt === void 0 || tokenCount - shownAt >= reInjectFloor;
18004
- const alreadyShown = retryCapped || !emergency && runtime.nudgeShownFor(turnKey) && !reInjectReady;
18065
+ const alreadyShown = retryCapped || !emergency && runtime.nudgeShownFor(sid, turnKey) && !reInjectReady;
18005
18066
  if (!alreadyShown) {
18006
18067
  rebuilt.push(nudgeMessage(turn.nudge, turn.state.blocks.filter((b2) => b2.active), runtime.prompts));
18007
18068
  const rendered = renderNudgeText(turn.nudge, runtime.prompts);
@@ -18016,7 +18077,7 @@ Example: compress({ content: [{ startId: "${top.startRef}", endId: "${top.endRef
18016
18077
  ctx.ui.notify(`[ACP nudge \u2192 context]${emergency ? " [EMERGENCY]" : ""}
18017
18078
  ${rendered.text}${example}`);
18018
18079
  }
18019
- if (!emergency) runtime.markNudgeShown(turnKey, tokenCount);
18080
+ if (!emergency) runtime.markNudgeShown(sid, turnKey, tokenCount);
18020
18081
  debug.event("nudge-injected", { sid: ctx.sessionManager.getSessionId(), voice: rendered.voice, channels: ["context", debugOn2 ? "terminal" : null].filter(Boolean), emergency, turnKey, reInject: shownAt !== void 0, text: rendered.text + example });
18021
18082
  } else {
18022
18083
  debug.event("nudge-suppressed", { sid: ctx.sessionManager.getSessionId(), turnKey, reason: turn.nudge.reason, shownAt: shownAt ?? null, tokenCount, adaptiveGrowth, reInjectFloor });