billion-context-pi 0.1.83 → 0.1.84-pr.667.485

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.
@@ -7,7 +7,7 @@ var __export = (target, all) => {
7
7
  // src/contract.ts
8
8
  var SIDECAR_SCHEMA_VERSION = 1;
9
9
  function sidecarProducer() {
10
- return `billion-context-pi@${true ? "0.1.83" : "dev"}`;
10
+ return `billion-context-pi@${true ? "0.1.84" : "dev"}`;
11
11
  }
12
12
 
13
13
  export {
@@ -15,4 +15,4 @@ export {
15
15
  SIDECAR_SCHEMA_VERSION,
16
16
  sidecarProducer
17
17
  };
18
- //# sourceMappingURL=chunk-LLFL3CNI.js.map
18
+ //# sourceMappingURL=chunk-TCNGKF5D.js.map
package/dist/contract.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  SIDECAR_SCHEMA_VERSION,
3
3
  sidecarProducer
4
- } from "./chunk-LLFL3CNI.js";
4
+ } from "./chunk-TCNGKF5D.js";
5
5
  export {
6
6
  SIDECAR_SCHEMA_VERSION,
7
7
  sidecarProducer
@@ -26,6 +26,8 @@ export declare function usageAnchorPredatesCompression(entries: AnchorEntry[]):
26
26
  export interface AnchorStaleness {
27
27
  predates: boolean;
28
28
  netReclaimed: number;
29
+ fresh: boolean;
30
+ lastRealTokens: number;
29
31
  }
30
32
  export declare function compressionAnchorStaleness(entries: AnchorEntry[], blocks: readonly CompressionBlock[], countTokens: (text: string) => number): AnchorStaleness;
31
33
  export {};
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  SIDECAR_SCHEMA_VERSION,
3
3
  __export,
4
4
  sidecarProducer
5
- } from "./chunk-LLFL3CNI.js";
5
+ } from "./chunk-TCNGKF5D.js";
6
6
 
7
7
  // src/config-dir.ts
8
8
  import * as piModule from "@earendil-works/pi-coding-agent";
@@ -13480,14 +13480,24 @@ function createRuntime(adapter) {
13480
13480
  if (ep) ep.reset();
13481
13481
  throttleEpisodes.delete(sid);
13482
13482
  }
13483
- const tokenScaleStale = /* @__PURE__ */ new Map();
13484
- function noteTokenScale(sid, stale) {
13485
- const prev = tokenScaleStale.get(sid);
13486
- tokenScaleStale.set(sid, stale);
13487
- return prev !== void 0 && prev !== stale;
13483
+ const SCALE_FLIP_BAND_RATIO = 0.1;
13484
+ const SCALE_FLIP_BAND_MIN = 1e3;
13485
+ const tokenScaleDominant = /* @__PURE__ */ new Map();
13486
+ function noteTokenScale(sid, hostFloor, sentTokens) {
13487
+ const prev = tokenScaleDominant.get(sid);
13488
+ if (prev === void 0) {
13489
+ tokenScaleDominant.set(sid, sentTokens >= hostFloor ? "est" : "host");
13490
+ return false;
13491
+ }
13492
+ const band = Math.max(SCALE_FLIP_BAND_MIN, SCALE_FLIP_BAND_RATIO * Math.max(hostFloor, sentTokens));
13493
+ let dom = prev;
13494
+ if (prev === "est" && hostFloor - sentTokens > band) dom = "host";
13495
+ else if (prev === "host" && sentTokens - hostFloor > band) dom = "est";
13496
+ if (dom !== prev) tokenScaleDominant.set(sid, dom);
13497
+ return dom !== prev;
13488
13498
  }
13489
13499
  function dropTokenScale(sid) {
13490
- tokenScaleStale.delete(sid);
13500
+ tokenScaleDominant.delete(sid);
13491
13501
  }
13492
13502
  const HOST_USAGE_WINDOW = 4;
13493
13503
  const HOST_USAGE_MIN_SAMPLES = 3;
@@ -13510,6 +13520,76 @@ function createRuntime(adapter) {
13510
13520
  function dropHostUsageSamples(sid) {
13511
13521
  hostUsageSamples.delete(sid);
13512
13522
  }
13523
+ const KHAT_RING_MAX = 3;
13524
+ const KHAT_MIN_ESTIMATE = 2e3;
13525
+ const KHAT_RATIO_MIN = 0.2;
13526
+ const KHAT_RATIO_MAX = 5;
13527
+ const KHAT_AGREE_FACTOR = 2;
13528
+ const KHAT_CLAMP_MIN = 0.25;
13529
+ const KHAT_CLAMP_MAX = 1;
13530
+ const KHAT_SCALE_SHIFT = 0.1;
13531
+ const khatStates = /* @__PURE__ */ new Map();
13532
+ function khatFor(sid, model) {
13533
+ const st2 = khatStates.get(sid);
13534
+ return st2 && st2.model === model ? st2.published : null;
13535
+ }
13536
+ function noteKhatUsage(sid, model, usageTokens) {
13537
+ let st2 = khatStates.get(sid);
13538
+ let scaleChanged = false;
13539
+ if (!st2) {
13540
+ st2 = { model, pending: null, ring: [], published: null };
13541
+ khatStates.set(sid, st2);
13542
+ } else if (st2.model !== model) {
13543
+ const prevFactor = st2.published ?? 1;
13544
+ if (1 - prevFactor > KHAT_SCALE_SHIFT) scaleChanged = true;
13545
+ st2 = { model, pending: null, ring: [], published: null };
13546
+ khatStates.set(sid, st2);
13547
+ }
13548
+ const before = st2.published;
13549
+ const pending = st2.pending;
13550
+ st2.pending = null;
13551
+ if (pending && pending.model === model && pending.est >= KHAT_MIN_ESTIMATE && usageTokens > 0) {
13552
+ const ratio = usageTokens / pending.est;
13553
+ if (ratio >= KHAT_RATIO_MIN && ratio <= KHAT_RATIO_MAX) {
13554
+ const sample = Math.min(Math.max(ratio, KHAT_CLAMP_MIN), KHAT_CLAMP_MAX);
13555
+ if (st2.published !== null) {
13556
+ if (sample / st2.published > KHAT_AGREE_FACTOR || st2.published / sample > KHAT_AGREE_FACTOR) {
13557
+ st2.ring = [sample];
13558
+ st2.published = null;
13559
+ }
13560
+ } else {
13561
+ st2.ring.push(sample);
13562
+ if (st2.ring.length > KHAT_RING_MAX) st2.ring.shift();
13563
+ for (let i = 0; i < st2.ring.length && st2.published === null; i++) {
13564
+ for (let j2 = i + 1; j2 < st2.ring.length; j2++) {
13565
+ const a = st2.ring[i];
13566
+ const b2 = st2.ring[j2];
13567
+ if (a / b2 <= KHAT_AGREE_FACTOR && b2 / a <= KHAT_AGREE_FACTOR) {
13568
+ st2.published = (a + b2) / 2;
13569
+ st2.ring = [st2.published];
13570
+ break;
13571
+ }
13572
+ }
13573
+ }
13574
+ }
13575
+ }
13576
+ }
13577
+ const factorBefore = before ?? 1;
13578
+ const factorAfter = st2.published ?? 1;
13579
+ if (Math.abs(factorBefore - factorAfter) > KHAT_SCALE_SHIFT) scaleChanged = true;
13580
+ return { khat: st2.published, scaleChanged };
13581
+ }
13582
+ function setKhatPending(sid, model, estimate) {
13583
+ const st2 = khatStates.get(sid);
13584
+ if (!st2 || st2.model !== model) {
13585
+ khatStates.set(sid, { model, pending: { est: estimate, model }, ring: [], published: null });
13586
+ return;
13587
+ }
13588
+ st2.pending = { est: estimate, model };
13589
+ }
13590
+ function dropKhat(sid) {
13591
+ khatStates.delete(sid);
13592
+ }
13513
13593
  const sizeDivergenceStreaks = /* @__PURE__ */ new Map();
13514
13594
  function noteSizeDivergence(sid, divergent) {
13515
13595
  if (!divergent) {
@@ -13740,7 +13820,7 @@ function createRuntime(adapter) {
13740
13820
  return promptsRef;
13741
13821
  }, setPrompts: (p) => {
13742
13822
  promptsRef = p;
13743
- }, markNudgeShown, nudgeShownFor, nudgeShownTokensFor, clearNudgeTracking, clearNudgeTokenStamps, markNudgeRecorded, nudgeRecordedFor, noteCompressOutcomes, compressRetryCappedFor, clearCompressRetryTracking, liveContextLimit, configFor, reasoningDropFor, reloadConfig, stateFor, save, deriveChildState: deriveChild, acquireLock, overflowFor, overflowDrop, noteSentViewCount, peekSentViewCount, dropSentViewCount, dropProjectionCache, noteDeadCompress, clearDeadCompress, throttleFor, throttleDrop, noteTokenScale, dropTokenScale, noteHostUsage, dropHostUsageSamples, noteSizeDivergence, dropSizeDivergence, noteTerminalEscape, dropTerminalEscape, noteTruncationSkipped, dropTruncationSkipped, stripImagesFor };
13823
+ }, markNudgeShown, nudgeShownFor, nudgeShownTokensFor, clearNudgeTracking, clearNudgeTokenStamps, markNudgeRecorded, nudgeRecordedFor, noteCompressOutcomes, compressRetryCappedFor, clearCompressRetryTracking, liveContextLimit, configFor, reasoningDropFor, reloadConfig, stateFor, save, deriveChildState: deriveChild, acquireLock, overflowFor, overflowDrop, noteSentViewCount, peekSentViewCount, dropSentViewCount, dropProjectionCache, noteDeadCompress, clearDeadCompress, throttleFor, throttleDrop, noteTokenScale, dropTokenScale, noteKhatUsage, khatFor, setKhatPending, dropKhat, noteHostUsage, dropHostUsageSamples, noteSizeDivergence, dropSizeDivergence, noteTerminalEscape, dropTerminalEscape, noteTruncationSkipped, dropTruncationSkipped, stripImagesFor };
13744
13824
  }
13745
13825
 
13746
13826
  // node_modules/typebox/build/system/memory/memory.mjs
@@ -19207,7 +19287,7 @@ function resolveActivePack(adapter, cwd, provider, modelId, resolver) {
19207
19287
  }
19208
19288
  var HOST_VERSION = (() => {
19209
19289
  try {
19210
- return "0.1.83";
19290
+ return "0.1.84";
19211
19291
  } catch {
19212
19292
  return "dev";
19213
19293
  }
@@ -19323,26 +19403,37 @@ function readToolSurfaceWithPacks(cwd) {
19323
19403
  }
19324
19404
 
19325
19405
  // src/floor-stale.ts
19406
+ function usageTotal(u) {
19407
+ if (!u) return 0;
19408
+ return (u.totalTokens ?? 0) || (u.input ?? 0) + (u.output ?? 0) + (u.cacheRead ?? 0) + (u.cacheWrite ?? 0);
19409
+ }
19326
19410
  function validAnchorUsage(u) {
19327
- if (!u) return false;
19328
- const total = (u.totalTokens ?? 0) || (u.input ?? 0) + (u.output ?? 0) + (u.cacheRead ?? 0) + (u.cacheWrite ?? 0);
19329
- return total > 0;
19411
+ return usageTotal(u) > 0;
19412
+ }
19413
+ function isFreshAnchor(m2) {
19414
+ return m2.role === "assistant" && m2.stopReason !== "aborted" && m2.stopReason !== "error" && validAnchorUsage(m2.usage);
19330
19415
  }
19331
19416
  function scanEntries(entries) {
19332
19417
  let lastUsageIdx = -1;
19333
19418
  let lastCompressIdx = -1;
19419
+ let lastAssistantIdx = -1;
19420
+ let lastUsageTotal = 0;
19334
19421
  const compressIdxByCallId = /* @__PURE__ */ new Map();
19335
19422
  for (let i = 0; i < entries.length; i++) {
19336
19423
  const m2 = entries[i].message;
19337
19424
  if (!m2) continue;
19338
- if (m2.role === "assistant" && m2.stopReason !== "aborted" && m2.stopReason !== "error" && validAnchorUsage(m2.usage)) {
19339
- lastUsageIdx = i;
19425
+ if (m2.role === "assistant") {
19426
+ lastAssistantIdx = i;
19427
+ if (isFreshAnchor(m2)) {
19428
+ lastUsageIdx = i;
19429
+ lastUsageTotal = usageTotal(m2.usage);
19430
+ }
19340
19431
  } else if (m2.role === "toolResult" && m2.toolName === "compress" && m2.toolCallId !== void 0 && m2.isError !== true && isCompressSuccessText(extractText(m2.content))) {
19341
19432
  lastCompressIdx = i;
19342
19433
  compressIdxByCallId.set(m2.toolCallId, i);
19343
19434
  }
19344
19435
  }
19345
- return { lastUsageIdx, lastCompressIdx, compressIdxByCallId };
19436
+ return { lastUsageIdx, lastCompressIdx, compressIdxByCallId, lastAssistantIdx, lastUsageTotal };
19346
19437
  }
19347
19438
  function usageAnchorPredatesCompression(entries) {
19348
19439
  const scan = scanEntries(entries);
@@ -19358,7 +19449,9 @@ function compressionAnchorStaleness(entries, blocks, countTokens) {
19358
19449
  const saved = (block.compressedTokens ?? 0) - countTokens(block.summary ?? "");
19359
19450
  netReclaimed += saved > 0 ? saved : 0;
19360
19451
  }
19361
- return { predates: scan.lastCompressIdx > scan.lastUsageIdx, netReclaimed };
19452
+ const lastAssistant = scan.lastAssistantIdx >= 0 ? entries[scan.lastAssistantIdx] : void 0;
19453
+ const fresh = !!lastAssistant?.message && isFreshAnchor(lastAssistant.message);
19454
+ return { predates: scan.lastCompressIdx > scan.lastUsageIdx, netReclaimed, fresh, lastRealTokens: scan.lastUsageTotal };
19362
19455
  }
19363
19456
 
19364
19457
  // src/delegate-tool.ts
@@ -22670,7 +22763,7 @@ async function statusReport(runtime, ctx) {
22670
22763
  const sentTokens = estimateTokens(coreMessages, coveredIds, imageTokens) + systemPromptTokens;
22671
22764
  const viewSentTokens = adjustedTokenCount(runtime.core, coreMessages, state, config, sentTokens, imageTokens, systemPromptTokens);
22672
22765
  const turn = runtime.core.processTurn({ messages: coreMessages, state, config, tokenCount: anchorStale ? viewSentTokens : Math.max(viewSentTokens, realUsage?.tokens ?? 0) });
22673
- const versionStr = "0.1.83" ? `billion-context-pi@${"0.1.83"} \xB7 pack: ${resolveSurfaceMeta(runtime.adapter, ctx?.cwd ?? process.cwd(), ctx?.model?.provider, ctx?.model?.id).pack}` : void 0;
22766
+ const versionStr = "0.1.84" ? `billion-context-pi@${"0.1.84"} \xB7 pack: ${resolveSurfaceMeta(runtime.adapter, ctx?.cwd ?? process.cwd(), ctx?.model?.provider, ctx?.model?.id).pack}` : void 0;
22674
22767
  let text = buildStatusPanel({
22675
22768
  version: versionStr,
22676
22769
  tokenCount: sessionTokens,
@@ -23649,7 +23742,7 @@ async function autoInstallLatest(latest, extDirOverride) {
23649
23742
  "--no-fund",
23650
23743
  "--no-save"
23651
23744
  ];
23652
- const prevVersion = (await readPackageJson(join12(extDir, "package.json")))?.version ?? "0.1.83";
23745
+ const prevVersion = (await readPackageJson(join12(extDir, "package.json")))?.version ?? "0.1.84";
23653
23746
  const { code, stderr } = await runNpmImpl(installArgs(latest), { cwd: npmDir, timeout: 6e4 });
23654
23747
  if (code !== 0) {
23655
23748
  logWarn("update", {
@@ -23667,7 +23760,7 @@ async function autoInstallLatest(latest, extDirOverride) {
23667
23760
  }
23668
23761
  const verify = await verifyInstall(npmDir, latest);
23669
23762
  if (!verify.ok) {
23670
- const rollbackTo = SEMVER_RE.test(prevVersion) ? prevVersion : "0.1.83";
23763
+ const rollbackTo = SEMVER_RE.test(prevVersion) ? prevVersion : "0.1.84";
23671
23764
  logWarn("update", { event: "auto-install-verify-failed", latest, reason: verify.reason, rollbackTo });
23672
23765
  const rb = await runNpmImpl(installArgs(rollbackTo), { cwd: npmDir, timeout: 6e4 });
23673
23766
  logInfo("update", { event: "rollback", from: latest, to: rollbackTo, ok: rb.code === 0 });
@@ -23742,7 +23835,7 @@ async function checkForUpdate(autoUpdate, notify) {
23742
23835
  }
23743
23836
  const latest = await fetchLatestVersion(tag);
23744
23837
  if (!latest) return;
23745
- const current = runtimeVersion ?? "0.1.83";
23838
+ const current = runtimeVersion ?? "0.1.84";
23746
23839
  const hasUpdate = isVersionNewer(latest, current);
23747
23840
  debug.event("update-check", {
23748
23841
  current,
@@ -23953,6 +24046,7 @@ function wireSessionLifecycle(pi, runtime, standDownIfProxied) {
23953
24046
  runtime.throttleFor(ctx.sessionManager.getSessionId()).reset();
23954
24047
  runtime.clearCompressRetryTracking(ctx.sessionManager.getSessionId());
23955
24048
  runtime.dropHostUsageSamples(ctx.sessionManager.getSessionId());
24049
+ runtime.dropKhat(ctx.sessionManager.getSessionId());
23956
24050
  runtime.dropSizeDivergence(ctx.sessionManager.getSessionId());
23957
24051
  runtime.dropTerminalEscape(ctx.sessionManager.getSessionId());
23958
24052
  runtime.dropTruncationSkipped(ctx.sessionManager.getSessionId());
@@ -23964,7 +24058,7 @@ function wireSessionLifecycle(pi, runtime, standDownIfProxied) {
23964
24058
  setDelegatePolicy(DEFAULT_DELEGATE_POLICY);
23965
24059
  const sid = ctx.sessionManager.getSessionId();
23966
24060
  const modelInfo = ctx.model;
23967
- logInfo("session", { event: "start", sid, cwd: ctx.cwd, debug: runtime.adapter.debug ?? null, version: true ? "0.1.83" : null, model: modelInfo?.id ?? null, modelApi: modelInfo?.api ?? null, contextWindow: modelInfo?.contextWindow ?? null });
24061
+ logInfo("session", { event: "start", sid, cwd: ctx.cwd, debug: runtime.adapter.debug ?? null, version: true ? "0.1.84" : null, model: modelInfo?.id ?? null, modelApi: modelInfo?.api ?? null, contextWindow: modelInfo?.contextWindow ?? null });
23968
24062
  let delegateStoodDown = false;
23969
24063
  try {
23970
24064
  await runtime.reloadConfig(ctx.cwd);
@@ -24027,6 +24121,7 @@ function wireSessionLifecycle(pi, runtime, standDownIfProxied) {
24027
24121
  runtime.clearNudgeTracking(sid);
24028
24122
  runtime.clearCompressRetryTracking(sid);
24029
24123
  runtime.dropHostUsageSamples(sid);
24124
+ runtime.dropKhat(sid);
24030
24125
  runtime.dropSizeDivergence(sid);
24031
24126
  runtime.dropTerminalEscape(sid);
24032
24127
  runtime.dropTruncationSkipped(sid);
@@ -24093,11 +24188,16 @@ function wireContextTransform(pi, runtime, standDownIfProxied) {
24093
24188
  armedFloor = Math.floor(config.modelContextLimit * 0.95);
24094
24189
  logWarn("overflow-selfheal", { sid, event: "armed-emergency", floor: armedFloor, limit: config.modelContextLimit });
24095
24190
  }
24096
- const { predates, netReclaimed } = compressionAnchorStaleness(entries, state.blocks, defaultCountTokens);
24097
- const realPromptTokens = realUsage?.tokens ?? 0;
24191
+ const { predates, netReclaimed, fresh, lastRealTokens } = compressionAnchorStaleness(entries, state.blocks, defaultCountTokens);
24192
+ const reportedHost = realUsage?.tokens ?? 0;
24193
+ const realPromptTokens = fresh || lastRealTokens <= 0 ? reportedHost : lastRealTokens;
24194
+ if (!fresh && lastRealTokens > 0 && reportedHost > 0) {
24195
+ logInfo("turn", { sid, event: "host-tree-sum-rejected", reported: reportedHost, flooredAt: lastRealTokens });
24196
+ }
24098
24197
  const hostFloor = realPromptTokens > 0 ? Math.max(0, realPromptTokens - (predates ? netReclaimed : 0)) : 0;
24099
- const hostUsageStable = !predates && realPromptTokens > 0 ? runtime.noteHostUsage(sid, realPromptTokens) : false;
24100
- const calibrate = (base) => hostUsageStable ? Math.min(base, Math.ceil(realPromptTokens * 1.2)) : base;
24198
+ const hostUsageStable = fresh && !predates && realPromptTokens > 0 ? runtime.noteHostUsage(sid, realPromptTokens) : false;
24199
+ const khatReport = fresh && realPromptTokens > 0 ? runtime.noteKhatUsage(sid, modelId, realPromptTokens) : { khat: runtime.khatFor(sid, modelId), scaleChanged: false };
24200
+ const calibrate = (base) => khatReport.khat !== null ? Math.ceil(base * khatReport.khat) : hostUsageStable ? Math.min(base, Math.ceil(realPromptTokens * 1.2)) : base;
24101
24201
  const applyFloors = (base) => Math.max(calibrate(base), hostFloor, armedFloor);
24102
24202
  const guardBasis = (base) => Math.max(calibrate(base), hostFloor);
24103
24203
  let tokenCount = applyFloors(sentTokens);
@@ -24120,11 +24220,12 @@ function wireContextTransform(pi, runtime, standDownIfProxied) {
24120
24220
  }
24121
24221
  }
24122
24222
  ov.noteSentView(guardTokens, config.modelContextLimit);
24123
- const sizeDivergent = !predates && realPromptTokens > 0 && Math.abs(tokenCount - realPromptTokens) / realPromptTokens > 0.5;
24223
+ const sizeDivergent = fresh && !predates && realPromptTokens > 0 && Math.abs(tokenCount - realPromptTokens) / realPromptTokens > 0.5;
24124
24224
  if (runtime.noteSizeDivergence(sid, sizeDivergent)) {
24125
24225
  logWarn("turn", { sid, event: "size-divergence", est: tokenCount, host: realPromptTokens, ratio: Number((tokenCount / realPromptTokens).toFixed(2)), stable: hostUsageStable });
24126
24226
  }
24127
- if (runtime.noteTokenScale(sid, hostFloor <= sentTokens)) {
24227
+ const estFlipped = runtime.noteTokenScale(sid, hostFloor, calibrate(sentTokens));
24228
+ if (khatReport.scaleChanged || estFlipped) {
24128
24229
  state.nudge.lastNudgeShownTokens = state.nudge.lastNudgeShownTokens > 0 ? tokenCount : 0;
24129
24230
  state.nudge.lastPerMessageNudgeTokens = state.nudge.lastPerMessageNudgeTokens > 0 ? tokenCount : 0;
24130
24231
  const reanchored = {};
@@ -24133,7 +24234,7 @@ function wireContextTransform(pi, runtime, standDownIfProxied) {
24133
24234
  }
24134
24235
  state.nudge.lastShownByTier = reanchored;
24135
24236
  runtime.clearNudgeTokenStamps(sid);
24136
- logInfo("growth-scale", { sid, event: "scale-flip-reanchor", estScaleWins: hostFloor <= sentTokens, predates, tokenCount });
24237
+ logInfo("growth-scale", { sid, event: "scale-flip-reanchor", source: khatReport.scaleChanged ? "khat" : "dead-band", khat: khatReport.khat, estScaleWins: sentTokens >= hostFloor, predates, hostFloor, sentTokens, tokenCount });
24137
24238
  }
24138
24239
  debug.event("context-in", {
24139
24240
  sid,
@@ -24150,13 +24251,15 @@ function wireContextTransform(pi, runtime, standDownIfProxied) {
24150
24251
  const turn = runtime.core.processTurn({ messages: coreMessages, state, config, tokenCount });
24151
24252
  await runtime.save(turn.state, ctx);
24152
24253
  const truncateBand = config.modelContextLimit > 0 ? Math.floor(config.truncate.threshold * config.modelContextLimit) : Number.MAX_SAFE_INTEGER;
24254
+ const sentViewTokens = estimateTokens(turn.messages, collectCoveredMessageIds(turn.state), imageTokens) + systemPromptTokens;
24153
24255
  runtime.noteSentViewCount(sid, {
24154
- viewTokens: estimateTokens(turn.messages, collectCoveredMessageIds(turn.state), imageTokens) + systemPromptTokens,
24256
+ viewTokens: sentViewTokens,
24155
24257
  blocksLen: turn.state.blocks.length,
24156
24258
  activeBlocks: turn.state.blocks.filter((b2) => b2.active).length,
24157
24259
  limit: config.modelContextLimit,
24158
24260
  usable: tokenCount < truncateBand
24159
24261
  });
24262
+ if (tokenCount < truncateBand) runtime.setKhatPending(sid, modelId, sentViewTokens);
24160
24263
  if (turn.terminalEscape) {
24161
24264
  if (runtime.noteTerminalEscape(sid, true)) {
24162
24265
  logWarn("overflow", {