@cortexkit/pi-magic-context 0.42.5 → 0.42.6

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
@@ -107,6 +107,7 @@ import {
107
107
  getNullOwnerToolTag,
108
108
  adoptNullOwnerToolTag,
109
109
  resolveOpenCodeDbPath,
110
+ assertOpenCodeStoreGeneration,
110
111
  openCodeDbPathExists,
111
112
  recordOpenCodeDbReadFailure,
112
113
  clearOpenCodeDbReadFailure,
@@ -476,7 +477,7 @@ import {
476
477
  registerTodoStateLifecycle,
477
478
  syncCtxMemoryToolEnabled,
478
479
  registerMagicContextTools
479
- } from "./index-a0960w4w.js";
480
+ } from "./index-r918mh6w.js";
480
481
  import {
481
482
  pushNotification2
482
483
  } from "./index-b3eqj1g6.js";
@@ -1247,7 +1248,19 @@ async function runSessionProjectBackfill(db, source, options = {}) {
1247
1248
  let identityResolutionsSinceYield = 0;
1248
1249
  let afterSessionId = null;
1249
1250
  for (;; ) {
1250
- const sourcePage = await readPage(afterSessionId, SESSION_PAGE_SIZE);
1251
+ let sourcePage;
1252
+ try {
1253
+ sourcePage = await readPage(afterSessionId, SESSION_PAGE_SIZE);
1254
+ } catch (error) {
1255
+ try {
1256
+ if (!markBackfillRetryPending(db, harness, holderId, now())) {
1257
+ log("[session-projects] backfill lease changed before failure cleanup");
1258
+ }
1259
+ } catch (releaseError) {
1260
+ log(`[session-projects] failed to make backfill lease retryable after discovery failed: ${releaseError}`);
1261
+ }
1262
+ throw error;
1263
+ }
1251
1264
  if (sourcePage.length === 0)
1252
1265
  break;
1253
1266
  afterSessionId = sourcePage.at(-1)?.sessionId ?? afterSessionId;
@@ -2844,6 +2857,12 @@ function openOpenCodeDb() {
2844
2857
  }
2845
2858
  try {
2846
2859
  const db = new Database(dbPath, { readonly: true });
2860
+ try {
2861
+ assertOpenCodeStoreGeneration(db, "v1", dbPath);
2862
+ } catch (error) {
2863
+ db.close();
2864
+ throw error;
2865
+ }
2847
2866
  db.exec("PRAGMA busy_timeout = 5000");
2848
2867
  clearOpenCodeDbReadFailure();
2849
2868
  return db;
@@ -12043,11 +12062,11 @@ function planDueTasks(db, projectIdentity, tasks, now) {
12043
12062
  }
12044
12063
  return due;
12045
12064
  }
12046
- function advanceAfterRun(db, projectIdentity, due, finishedAt, status, error, schedulePatch) {
12065
+ function advanceAfterRun(db, projectIdentity, due, finishedAt, status, error, schedulePatch, startedAt) {
12047
12066
  writeTaskScheduleState(db, {
12048
12067
  projectPath: projectIdentity,
12049
12068
  task: due.config.task,
12050
- lastRunAt: status === "completed" ? finishedAt : readLastRunAt(db, projectIdentity, due.config.task),
12069
+ lastRunAt: status === "completed" ? startedAt ?? finishedAt : readLastRunAt(db, projectIdentity, due.config.task),
12051
12070
  nextDueAt: nextDueAtMs(due.config.schedule, finishedAt, due.scheduledAt),
12052
12071
  schedule: due.config.schedule,
12053
12072
  lastStatus: status,
@@ -12132,6 +12151,7 @@ async function runDomainGroup(deps, group, cb) {
12132
12151
  }
12133
12152
  }
12134
12153
  let outcome;
12154
+ const startedAt = Date.now();
12135
12155
  try {
12136
12156
  outcome = await executor(due.config, {
12137
12157
  db,
@@ -12145,7 +12165,7 @@ async function runDomainGroup(deps, group, cb) {
12145
12165
  }
12146
12166
  const finishedAt = Date.now();
12147
12167
  if (outcome.status === "completed") {
12148
- advanceAfterRun(db, projectIdentity, due, finishedAt, "completed", null, outcome.schedulePatch);
12168
+ advanceAfterRun(db, projectIdentity, due, finishedAt, "completed", null, outcome.schedulePatch, startedAt);
12149
12169
  cb?.onRan?.(due.config.task, outcome.detail, outcome.backlog);
12150
12170
  } else if (outcome.transient) {
12151
12171
  recordTransientFailure(db, projectIdentity, due, finishedAt, outcome.error ?? null);
@@ -14012,6 +14032,16 @@ import {
14012
14032
  } from "node:path";
14013
14033
  import { pathToFileURL } from "node:url";
14014
14034
  var PI_CODING_AGENT_MODULE2 = "@earendil-works/pi-coding-agent";
14035
+ var OMP_CODING_AGENT_MODULE = "@oh-my-pi/pi-coding-agent";
14036
+ var CODING_AGENT_MODULES = [
14037
+ PI_CODING_AGENT_MODULE2,
14038
+ OMP_CODING_AGENT_MODULE
14039
+ ];
14040
+ var CODING_AGENT_MODULE_LABEL = CODING_AGENT_MODULES.join(" or ");
14041
+ var CODING_AGENT_PACKAGE_NAMES = new Set(CODING_AGENT_MODULES);
14042
+ function isCodingAgentPackageName(name) {
14043
+ return typeof name === "string" && CODING_AGENT_PACKAGE_NAMES.has(name);
14044
+ }
14015
14045
  var SCRIPT_ENTRY_PATTERN = /\.(mjs|cjs|mts|cts|js|ts|tsx|jsx)$/i;
14016
14046
  var TS_ENTRY_PATTERN = /\.(mts|cts|ts|tsx)$/i;
14017
14047
  function isScriptEntry(filePath) {
@@ -14046,11 +14076,11 @@ function findPackageRoot(startDir) {
14046
14076
  let dir = startDir;
14047
14077
  while (dir !== dirname2(dir)) {
14048
14078
  const pkg = readManifest(join5(dir, "package.json"));
14049
- if (pkg?.name === PI_CODING_AGENT_MODULE2) {
14079
+ if (isCodingAgentPackageName(pkg?.name)) {
14050
14080
  if (basename2(dir) === "dist") {
14051
14081
  const parentDir = dirname2(dir);
14052
14082
  const parentPkg = readManifest(join5(parentDir, "package.json"));
14053
- if (parentPkg?.name === PI_CODING_AGENT_MODULE2) {
14083
+ if (parentPkg?.name === pkg.name) {
14054
14084
  return { dir: parentDir, pkg: parentPkg };
14055
14085
  }
14056
14086
  }
@@ -14123,11 +14153,14 @@ var defaultLoaders = [
14123
14153
  }
14124
14154
  const found = findPackageRoot(dirname2(entry));
14125
14155
  if (!found) {
14126
- throw new Error(`Could not locate ${PI_CODING_AGENT_MODULE2} package.json from ${entry}`);
14156
+ throw new Error(`Could not locate ${CODING_AGENT_MODULE_LABEL} package.json from ${entry}`);
14127
14157
  }
14128
14158
  const entryPath = resolveManifestEntry(found);
14129
14159
  if (TS_ENTRY_PATTERN.test(entry)) {
14130
14160
  const srcEntry = toSourceEntry(entryPath, found.dir);
14161
+ if (!srcEntry && TS_ENTRY_PATTERN.test(entryPath) && existsSync7(entryPath)) {
14162
+ return await import(pathToFileURL(entryPath).href);
14163
+ }
14131
14164
  if (srcEntry && existsSync7(srcEntry)) {
14132
14165
  return await import(pathToFileURL(srcEntry).href);
14133
14166
  }
@@ -14139,6 +14172,10 @@ var defaultLoaders = [
14139
14172
  {
14140
14173
  name: "Bare import",
14141
14174
  load: async () => await import(PI_CODING_AGENT_MODULE2)
14175
+ },
14176
+ {
14177
+ name: "Bare import (OMP)",
14178
+ load: async () => await import(OMP_CODING_AGENT_MODULE)
14142
14179
  }
14143
14180
  ];
14144
14181
  var cachedModulePromise = null;
@@ -14156,7 +14193,7 @@ async function resolvePiCodingAgentModule(loaders) {
14156
14193
  errors.push(err);
14157
14194
  }
14158
14195
  }
14159
- throw new Error(`Failed to resolve ${PI_CODING_AGENT_MODULE2} via all strategies:
14196
+ throw new Error(`Failed to resolve a Pi/OMP coding-agent module (${CODING_AGENT_MODULE_LABEL}) via all strategies:
14160
14197
  ` + errors.map((e, i) => ` - ${activeLoaders[i].name}: ${e.message || e}`).join(`
14161
14198
  `) + `
14162
14199
  Likely cause: symlinked or nonstandard install layout.`);
@@ -16146,7 +16183,7 @@ function applyFlushedStatuses(sessionId, db, targets, preloadedTags) {
16146
16183
 
16147
16184
  // ../plugin/src/hooks/magic-context/cache-busting-signals.ts
16148
16185
  function hasReclaimRide(signals) {
16149
- return signals.hardFold || signals.force || signals.explicitFlush || signals.publishedHistory || signals.agentDrop;
16186
+ return signals.hardFold || signals.force || signals.explicitFlush || signals.publishedHistory;
16150
16187
  }
16151
16188
 
16152
16189
  // ../plugin/src/hooks/magic-context/caveman.ts
@@ -17542,6 +17579,73 @@ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPer
17542
17579
  };
17543
17580
  }
17544
17581
 
17582
+ // ../plugin/src/hooks/magic-context/dropped-token-estimate.ts
17583
+ var TAG_QUERY_CHUNK_SIZE = 900;
17584
+ var ESTIMATED_CHARACTERS_PER_TOKEN = 3.5;
17585
+ function estimateCharacters(characters) {
17586
+ return Math.ceil(Math.max(0, characters) / ESTIMATED_CHARACTERS_PER_TOKEN);
17587
+ }
17588
+ function persistedCountOrByteEstimate(count, bytes) {
17589
+ return typeof count === "number" && Number.isFinite(count) ? Math.max(0, count) : estimateCharacters(bytes);
17590
+ }
17591
+ function loadPersistedTagTokenCounts(db, sessionId, tagNumbers) {
17592
+ const countsByTag = new Map;
17593
+ for (let offset = 0;offset < tagNumbers.length; offset += TAG_QUERY_CHUNK_SIZE) {
17594
+ const chunk = tagNumbers.slice(offset, offset + TAG_QUERY_CHUNK_SIZE);
17595
+ const placeholders = chunk.map(() => "?").join(",");
17596
+ const rows = db.prepare(`SELECT tag_number AS tagNumber,
17597
+ type,
17598
+ byte_size AS byteSize,
17599
+ input_byte_size AS inputByteSize,
17600
+ reasoning_byte_size AS reasoningByteSize,
17601
+ token_count AS tokenCount,
17602
+ input_token_count AS inputTokenCount,
17603
+ reasoning_token_count AS reasoningTokenCount
17604
+ FROM tags
17605
+ WHERE session_id = ? AND tag_number IN (${placeholders})`).all(sessionId, ...chunk);
17606
+ for (const row of rows)
17607
+ countsByTag.set(row.tagNumber, row);
17608
+ }
17609
+ return countsByTag;
17610
+ }
17611
+ function estimateDroppedTokensFromTagReductions(db, sessionId, reductions) {
17612
+ if (reductions.length === 0)
17613
+ return 0;
17614
+ const structuralByTag = new Map;
17615
+ const partialCharactersByTag = new Map;
17616
+ for (const reduction of reductions) {
17617
+ if (reduction.mode === "partial") {
17618
+ partialCharactersByTag.set(reduction.tagNumber, (partialCharactersByTag.get(reduction.tagNumber) ?? 0) + Math.max(0, reduction.removedCharacters));
17619
+ continue;
17620
+ }
17621
+ const prior = structuralByTag.get(reduction.tagNumber);
17622
+ if (!prior || reduction.mode === "full") {
17623
+ structuralByTag.set(reduction.tagNumber, reduction);
17624
+ }
17625
+ }
17626
+ const tagNumbers = [...new Set([...structuralByTag.keys(), ...partialCharactersByTag.keys()])];
17627
+ const countsByTag = loadPersistedTagTokenCounts(db, sessionId, tagNumbers);
17628
+ let total = 0;
17629
+ for (const [tagNumber, reduction] of structuralByTag) {
17630
+ const row = countsByTag.get(tagNumber);
17631
+ if (!row)
17632
+ continue;
17633
+ total += persistedCountOrByteEstimate(row.tokenCount, row.byteSize);
17634
+ if (reduction.mode === "full") {
17635
+ total += persistedCountOrByteEstimate(row.reasoningTokenCount, row.reasoningByteSize);
17636
+ if (row.type === "tool") {
17637
+ total += persistedCountOrByteEstimate(row.inputTokenCount, row.inputByteSize);
17638
+ }
17639
+ }
17640
+ }
17641
+ for (const [tagNumber, removedCharacters] of partialCharactersByTag) {
17642
+ if (structuralByTag.has(tagNumber) || !countsByTag.has(tagNumber))
17643
+ continue;
17644
+ total += estimateCharacters(removedCharacters);
17645
+ }
17646
+ return Math.max(0, Math.round(total));
17647
+ }
17648
+
17545
17649
  // ../plugin/src/hooks/magic-context/emergency-fail-closed.ts
17546
17650
  class EmergencyFailClosedError extends Error {
17547
17651
  code = "EMERGENCY_FAIL_CLOSED";
@@ -18888,17 +18992,65 @@ function persistFilteredNoise(db, sessionId, chunk, eligibleEnd) {
18888
18992
  }
18889
18993
 
18890
18994
  // ../plugin/src/hooks/magic-context/producer-window-guard.ts
18891
- var PRODUCER_WINDOW_REFUSAL_MARGIN = 0.15;
18995
+ var PRODUCER_WINDOW_REFUSAL_MARGIN = 0.03;
18996
+ var HISTORIAN_TRUNCATION_MARKER = "[… tokens truncated by Magic Context to fit the historian window …]";
18997
+ function producerInputTokenLimit(contextLimitTokens, maxOutputTokens) {
18998
+ if (typeof contextLimitTokens !== "number" || !Number.isFinite(contextLimitTokens) || contextLimitTokens <= 0 || !Number.isFinite(maxOutputTokens) || maxOutputTokens < 0) {
18999
+ return;
19000
+ }
19001
+ const usableInputTokens = Math.max(0, Math.floor(contextLimitTokens - maxOutputTokens));
19002
+ return Math.max(0, Math.floor(usableInputTokens * (1 - PRODUCER_WINDOW_REFUSAL_MARGIN)));
19003
+ }
18892
19004
  function producerWindowFailureReason(input) {
18893
19005
  const { producerSourceTokens, contextLimitTokens, maxOutputTokens } = input;
18894
- if (typeof contextLimitTokens !== "number" || !Number.isFinite(contextLimitTokens) || contextLimitTokens <= 0 || !Number.isFinite(producerSourceTokens) || producerSourceTokens <= 0 || !Number.isFinite(maxOutputTokens) || maxOutputTokens < 0) {
19006
+ const producerInputLimitTokens = producerInputTokenLimit(contextLimitTokens, maxOutputTokens);
19007
+ if (producerInputLimitTokens === undefined || typeof contextLimitTokens !== "number" || !Number.isFinite(producerSourceTokens) || producerSourceTokens <= 0) {
18895
19008
  return null;
18896
19009
  }
18897
19010
  const usableInputTokens = Math.max(0, Math.floor(contextLimitTokens - maxOutputTokens));
18898
- const refusalThreshold = usableInputTokens * (1 + PRODUCER_WINDOW_REFUSAL_MARGIN);
18899
- if (producerSourceTokens < refusalThreshold)
19011
+ if (producerSourceTokens <= producerInputLimitTokens)
18900
19012
  return null;
18901
- return `producer_source_exceeds_window producer_source_tokens=${Math.round(producerSourceTokens)} usable_input_tokens=${usableInputTokens} context_limit_tokens=${Math.round(contextLimitTokens)} max_output_tokens=${Math.round(maxOutputTokens)} refusal_margin=${PRODUCER_WINDOW_REFUSAL_MARGIN}`;
19013
+ return `producer_source_exceeds_window producer_source_tokens=${Math.round(producerSourceTokens)} usable_input_tokens=${usableInputTokens} producer_input_limit_tokens=${producerInputLimitTokens} context_limit_tokens=${Math.round(contextLimitTokens)} max_output_tokens=${Math.round(maxOutputTokens)} estimator_margin=${PRODUCER_WINDOW_REFUSAL_MARGIN}`;
19014
+ }
19015
+ function splitMarkerPair() {
19016
+ return `
19017
+ ${HISTORIAN_TRUNCATION_MARKER}
19018
+ ${HISTORIAN_TRUNCATION_MARKER}
19019
+ `;
19020
+ }
19021
+ function fitAtomicHistorianSourceToProducerWindow(args) {
19022
+ const producerInputLimitTokens = producerInputTokenLimit(args.contextLimitTokens, args.maxOutputTokens);
19023
+ const originalTokens = estimateTokens(args.text);
19024
+ if (producerInputLimitTokens === undefined || originalTokens < producerInputLimitTokens || producerInputLimitTokens <= 0) {
19025
+ return { text: args.text, producerInputLimitTokens, removedTokens: 0 };
19026
+ }
19027
+ const boundary = [...args.resultBoundaries ?? []].filter((candidate) => Number.isFinite(candidate.sourceOffset) && candidate.sourceOffset > 0 && candidate.sourceOffset < args.text.length).sort((a, b) => b.bodyTokens - a.bodyTokens || a.ordinal - b.ordinal)[0];
19028
+ const splitOffset = boundary?.sourceOffset ?? Math.floor(args.text.length / 2);
19029
+ const left = args.text.slice(0, splitOffset);
19030
+ const right = args.text.slice(splitOffset);
19031
+ const markers = splitMarkerPair();
19032
+ const target = producerInputLimitTokens;
19033
+ let lo = 0;
19034
+ let hi = 1;
19035
+ let best = markers;
19036
+ for (let iteration = 0;iteration < 48; iteration++) {
19037
+ const scale = (lo + hi) / 2;
19038
+ const leftLength = Math.floor(left.length * scale);
19039
+ const rightLength = Math.floor(right.length * scale);
19040
+ const candidate = left.slice(0, leftLength) + markers + right.slice(right.length - rightLength);
19041
+ if (estimateTokens(candidate) <= target) {
19042
+ best = candidate;
19043
+ lo = scale;
19044
+ } else {
19045
+ hi = scale;
19046
+ }
19047
+ }
19048
+ return {
19049
+ text: best,
19050
+ producerInputLimitTokens,
19051
+ ...boundary ? { splitBoundaryOrdinal: boundary.ordinal } : {},
19052
+ removedTokens: Math.max(0, originalTokens - estimateTokens(best))
19053
+ };
18902
19054
  }
18903
19055
 
18904
19056
  // ../plugin/src/hooks/magic-context/reference-seeds.generated.ts
@@ -21043,11 +21195,20 @@ async function runPiHistorian(deps) {
21043
21195
  chunkStart: chunk.startIndex,
21044
21196
  sessionCompartments: priorCompartments
21045
21197
  });
21046
- const chunkText = chunk.oversizeAtomicUnit ? chunk.text : truncateHistorianInputIfNeeded(chunk.text, historianChunkTokens);
21198
+ const fittedAtomicSource = chunk.oversizeAtomicUnit ? fitAtomicHistorianSourceToProducerWindow({
21199
+ text: chunk.text,
21200
+ resultBoundaries: chunk.toolResultBoundaries,
21201
+ contextLimitTokens: historianContextLimit,
21202
+ maxOutputTokens
21203
+ }) : null;
21204
+ const chunkText = chunk.oversizeAtomicUnit ? fittedAtomicSource?.text ?? chunk.text : truncateHistorianInputIfNeeded(chunk.text, historianChunkTokens);
21047
21205
  const producerSourceTokens = estimateTokens(chunkText);
21048
21206
  if (boundarySnapshot.oversizeAtomicUnit || chunk.oversizeAtomicUnit) {
21049
21207
  sessionLog(sessionId, `historian oversize admission: range=${chunk.startIndex}-${chunk.endIndex} rawComponentTokens=${boundarySnapshot.diagnostics?.head.completedFence.tokenMass ?? "unknown"} perRunCap=${perRunCap} producerSourceTokens=${producerSourceTokens} historianChunkTokens=${historianChunkTokens}; ${describeBoundaryDiagnostics(boundarySnapshot)}`);
21050
21208
  }
21209
+ if (fittedAtomicSource && fittedAtomicSource.removedTokens > 0) {
21210
+ sessionLog(sessionId, `historian pathological component split: range=${chunk.startIndex}-${chunk.endIndex} resultBoundary=${fittedAtomicSource.splitBoundaryOrdinal ?? "midpoint"} removedTokens=${fittedAtomicSource.removedTokens} producerSourceTokens=${producerSourceTokens} producerInputLimitTokens=${fittedAtomicSource.producerInputLimitTokens ?? "unknown"}`);
21211
+ }
21051
21212
  const producerWindowFailure = producerWindowFailureReason({
21052
21213
  producerSourceTokens,
21053
21214
  contextLimitTokens: historianContextLimit,
@@ -21781,6 +21942,7 @@ function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config, pre
21781
21942
  let deduplicatedTools = 0;
21782
21943
  let droppedInjections = 0;
21783
21944
  let droppedStaleReduceCalls = 0;
21945
+ const droppedTokenReductions = [];
21784
21946
  if (config.emergency) {
21785
21947
  const emergency = config.emergency;
21786
21948
  const priorInputSample = getEmergencyInputSample(db, sessionId);
@@ -21817,6 +21979,10 @@ function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config, pre
21817
21979
  updateTagDropMode(db, sessionId, tag.tagNumber, skeleton ? "truncated" : "full");
21818
21980
  droppedTools++;
21819
21981
  emergencyDroppedTools++;
21982
+ droppedTokenReductions.push({
21983
+ tagNumber: tag.tagNumber,
21984
+ mode: skeleton ? "truncated" : "full"
21985
+ });
21820
21986
  }
21821
21987
  }
21822
21988
  }).immediate();
@@ -21876,12 +22042,22 @@ function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config, pre
21876
22042
  updateTagStatus(db, sessionId, tag.tagNumber, "dropped");
21877
22043
  if (dropResult === "removed" || didReplace) {
21878
22044
  droppedInjections++;
22045
+ droppedTokenReductions.push({
22046
+ tagNumber: tag.tagNumber,
22047
+ mode: "full"
22048
+ });
21879
22049
  }
21880
22050
  }
21881
22051
  } else {
21882
22052
  if (freezePiContentDecision(db, sessionId, "reminder-strip", tag.messageId)) {
21883
- if (target.setContent(stripped))
22053
+ if (target.setContent(stripped)) {
21884
22054
  droppedInjections++;
22055
+ droppedTokenReductions.push({
22056
+ tagNumber: tag.tagNumber,
22057
+ mode: "partial",
22058
+ removedCharacters: Math.max(0, content.length - stripped.length)
22059
+ });
22060
+ }
21885
22061
  }
21886
22062
  }
21887
22063
  }
@@ -21920,6 +22096,10 @@ function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config, pre
21920
22096
  updateTagStatus(db, sessionId, tag.tagNumber, "dropped");
21921
22097
  if (result === "removed" || result === "truncated") {
21922
22098
  deduplicatedTools++;
22099
+ droppedTokenReductions.push({
22100
+ tagNumber: tag.tagNumber,
22101
+ mode: "full"
22102
+ });
21923
22103
  }
21924
22104
  }
21925
22105
  }
@@ -21938,6 +22118,15 @@ function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config, pre
21938
22118
  });
21939
22119
  compressedTextTags = cavemanResult.compressedToLite + cavemanResult.compressedToFull + cavemanResult.compressedToUltra;
21940
22120
  mutatedTextTags = cavemanResult.mutatedTextTags;
22121
+ if (cavemanResult.textReductions) {
22122
+ for (const r of cavemanResult.textReductions) {
22123
+ droppedTokenReductions.push({
22124
+ tagNumber: r.tagNumber,
22125
+ mode: "partial",
22126
+ removedCharacters: r.removedCharacters
22127
+ });
22128
+ }
22129
+ }
21941
22130
  }
21942
22131
  return {
21943
22132
  droppedTools,
@@ -21946,7 +22135,8 @@ function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config, pre
21946
22135
  droppedStaleReduceCalls,
21947
22136
  emergencyDroppedTools,
21948
22137
  compressedTextTags,
21949
- mutatedTextTags
22138
+ mutatedTextTags,
22139
+ droppedTokenReductions
21950
22140
  };
21951
22141
  }
21952
22142
  function buildCtxReduceTagNumbers(tags) {
@@ -22512,7 +22702,7 @@ function refreshPiTailHygieneBaseline(input) {
22512
22702
  for (let index = input.previous.baselineParts.length;index < measured.parts.length; index += 1) {
22513
22703
  const part = measured.parts[index];
22514
22704
  turnDeltaT += part.tokens;
22515
- if (part.kind !== "toolOutput")
22705
+ if (part.kind !== "toolOutput" || !part.protected)
22516
22706
  turnDeltaU += part.uTokens;
22517
22707
  }
22518
22708
  return {
@@ -26491,7 +26681,7 @@ function memoryGuidanceBlock(memoryEnabled) {
26491
26681
  ` : "";
26492
26682
  }
26493
26683
  var BASE_INTRO = (memoryEnabled) => `Messages and tool outputs are tagged with §N§ identifiers (e.g., §1§, §42§).
26494
- Use \`ctx_reduce\` to mark spent tagged content as discardable and reclaim space. Marking is NOT an immediate delete — it queues the content, which stays fully visible until space is actually needed (as soon as the next turn if you're already under pressure, much later if not), so mark a tool output as soon as you're done with it rather than hoarding the call for the end of the turn. The newest token-mass window stays protected until displaced. Syntax: "3-5", "1,2,9", or "1-5,8,12-15".
26684
+ Use \`ctx_reduce\` to mark spent tagged content as discardable and reclaim space. Marking QUEUES content for release. It stays fully visible to you until it is actually released, which may be the next turn or many turns later. Mark a tool output as soon as you're done with it rather than hoarding the call for the end of the turn. The newest token-mass window stays protected until displaced. Syntax: "3-5", "1,2,9", or "1-5,8,12-15".
26495
26685
  Do not announce or narrate \`ctx_reduce\` drops — just call the tool silently. Saying "I'll drop these outputs" wastes tokens the user does not care about.
26496
26686
  ${CTX_NOTE_GUIDANCE}
26497
26687
  ${memoryGuidanceBlock(memoryEnabled)}Use \`ctx_search\` to search across project memories, indexed git commits, and this session's full conversation history (including compacted parts) from one query.
@@ -29623,7 +29813,8 @@ async function runPipeline(args) {
29623
29813
  let heuristicOrReasoningDidMutate = false;
29624
29814
  let didMutateFromFlushedStatuses = false;
29625
29815
  let droppedCount = 0;
29626
- const droppedTokens = 0;
29816
+ let droppedTokens = 0;
29817
+ const droppedTokenReductions = [];
29627
29818
  let emergency = false;
29628
29819
  let autoReclaimDidMutateThisPass = false;
29629
29820
  let suppressDeferredHistoryDrain = false;
@@ -29748,17 +29939,15 @@ async function runPipeline(args) {
29748
29939
  routinePressureAppliedBySession.set(args.sessionId, true);
29749
29940
  }
29750
29941
  const routinePressureAlreadyApplied = !args.sessionMeta.isSubagent && executePressureEligible && routinePressureAppliedBySession.get(args.sessionId) === true;
29751
- const historianRunning = inFlightHistorian.has(args.sessionId);
29752
- const publishedWorkDrainAllowed = args.schedulerDecision === "execute" || args.forceMaterialization === true || foldExecutedThisPass || firstRenderBust || hasPendingMaterialization(args.sessionId) || deferredMaterializeEligible;
29753
29942
  const hasPendingMaterializeSignal = hasPendingMaterialization(args.sessionId);
29754
29943
  const rideSignals = {
29755
29944
  hardFold: foldExecutedThisPass || firstRenderBust,
29756
- force: args.forceMaterialization === true || emergencyDropEligible,
29757
- explicitFlush: hasPendingMaterializeSignal || args.isCacheBusting,
29758
- publishedHistory: !prefixPreflightContended && (publishedM1RefreshedThisPass || canConsumeDeferredLate && deferredHistoryWasPendingAtPassStart),
29759
- agentDrop: false
29945
+ force: (args.forceMaterialization === true || emergencyDropEligible) && (args.contextUsage.percentage >= 95 || getEmergencyInputSample(args.db, args.sessionId) === 0),
29946
+ explicitFlush: hasPendingMaterializeSignal || deferredMaterializeEligible && !prefixPreflightContended,
29947
+ publishedHistory: !prefixPreflightContended && (args.isCacheBusting || publishedM1RefreshedThisPass || canConsumeDeferredLate && deferredHistoryWasPendingAtPassStart)
29760
29948
  };
29761
- let isCacheBustingPass = hasReclaimRide(rideSignals);
29949
+ const isCacheBustingPass = hasReclaimRide(rideSignals);
29950
+ const publishedWorkDrainAllowed = isCacheBustingPass;
29762
29951
  const usesTokenProtection = args.protectedTokenTierOverrides !== undefined || args.protectedTokens !== undefined;
29763
29952
  const resolveProtectionFloor = () => resolveEpochFloorForPass(args.db, args.sessionId, {
29764
29953
  configuredOverride: args.protectedTokens,
@@ -29823,15 +30012,14 @@ async function runPipeline(args) {
29823
30012
  }
29824
30013
  const deferredMaterializationWasPending = deferredMaterializationSessions.has(args.sessionId);
29825
30014
  const deferredHistoryRefreshWasPending = deferredHistoryWasPendingAtPassStart;
29826
- const shouldReadPendingOps = !args.compactionOff && (args.schedulerDecision === "execute" || args.forceMaterialization || hasPendingMaterializeSignal || foldExecutedThisPass || firstRenderBust || historianRunning);
30015
+ const shouldReadPendingOps = !args.compactionOff && (publishedWorkDrainAllowed || args.schedulerDecision === "execute" || args.forceMaterialization || hasPendingMaterializeSignal || foldExecutedThisPass || firstRenderBust);
29827
30016
  const pendingOps = shouldReadPendingOps ? getPendingOps(args.db, args.sessionId) : [];
29828
30017
  const protectionWindowForPass = getProtectionWindowForSession(args.db, args.sessionId, protectionFloorResolution.floor);
29829
30018
  const protectedTagNumbersForPass = usesTokenProtection ? protectionWindowForPass.protectedTagNumbers : newestActiveTagNumbersByCount(getActiveTagsBySession(args.db, args.sessionId), args.protectedTags);
29830
30019
  const pendingOperationTags = pendingOps.length > 0 ? getTagsForPendingOperations(args.db, args.sessionId, pendingOps.map((operation) => operation.tagId), usesTokenProtection ? 0 : args.protectedTags, RECENT_TOOL_SKELETON_WINDOW) : [];
29831
- const baseShouldApplyPendingOps = args.schedulerDecision === "execute" || args.forceMaterialization || hasPendingMaterializeSignal || foldExecutedThisPass || firstRenderBust;
29832
30020
  const deferredMaterialize = canConsumeDeferredLate && deferredMaterializationWasPending;
29833
30021
  const deferredHistoryRefresh = canConsumeDeferredLate && deferredHistoryRefreshWasPending;
29834
- const shouldApplyPendingOps = (baseShouldApplyPendingOps || deferredMaterialize) && publishedWorkDrainAllowed;
30022
+ const shouldApplyPendingOps = publishedWorkDrainAllowed;
29835
30023
  mutationGateObserverForTests?.({
29836
30024
  foldDue: foldDueDecision.value,
29837
30025
  foldExecuted: foldExecutedThisPass,
@@ -29847,15 +30035,11 @@ async function runPipeline(args) {
29847
30035
  pendingDecisionLogObserverForTests?.(pendingDecisionLog);
29848
30036
  try {
29849
30037
  const tApplyPending = performance.now();
29850
- pendingOpsDidMutate = applyPendingOperations(args.sessionId, args.db, targets, args.contextUsage.percentage >= 95 ? newestCtxReduceTagNumbers(getTagsBySession(args.db, args.sessionId)) : protectedTagNumbersForPass, pendingOperationTags, pendingOps);
30038
+ pendingOpsDidMutate = applyPendingOperations(args.sessionId, args.db, targets, args.contextUsage.percentage >= 95 ? newestCtxReduceTagNumbers(getTagsBySession(args.db, args.sessionId)) : protectedTagNumbersForPass, pendingOperationTags, pendingOps, [], new Set, (reduction) => droppedTokenReductions.push(reduction));
29851
30039
  if (pendingOpsDidMutate) {
29852
30040
  droppedCount += pendingOps.length;
29853
30041
  }
29854
30042
  logTransformTiming(args.sessionId, "applyPendingOperations", tApplyPending);
29855
- rideSignals.agentDrop = pendingOpsDidMutate;
29856
- isCacheBustingPass = hasReclaimRide(rideSignals);
29857
- if (pendingOpsDidMutate)
29858
- shouldRunHeuristics = args.heuristics !== undefined;
29859
30043
  executedWorkThisPass ||= isCacheBustingPass;
29860
30044
  materializationSatisfiedThisPass = true;
29861
30045
  pendingOpsAppliedThisPass = true;
@@ -29870,7 +30054,7 @@ async function runPipeline(args) {
29870
30054
  }
29871
30055
  } else {
29872
30056
  const pendingOpsDepth = getPendingOpsCount(args.db, args.sessionId);
29873
- const refusalReason = args.schedulerDeferReason ?? (historianRunning ? "historian_in_flight" : "scheduler_defer");
30057
+ const refusalReason = args.schedulerDeferReason ?? "no_originating_cache_bust";
29874
30058
  const pendingDecisionLog = `pending ops WILL NOT APPLY — reason=${refusalReason} pendingOps=${pendingOpsDepth === null ? "not loaded (deferred pass)" : pendingOpsDepth} context=${args.contextUsage.percentage.toFixed(1)}%`;
29875
30059
  sessionLog(args.sessionId, pendingDecisionLog);
29876
30060
  pendingDecisionLogObserverForTests?.(pendingDecisionLog);
@@ -29936,7 +30120,7 @@ async function runPipeline(args) {
29936
30120
  sessionLog(args.sessionId, heuristicsDecisionLog);
29937
30121
  pendingDecisionLogObserverForTests?.(heuristicsDecisionLog);
29938
30122
  } else {
29939
- const reason = args.heuristics === undefined ? "disabled" : args.schedulerDeferReason ?? (historianRunning ? "historian_in_flight" : alreadyRanHeuristicsThisTurn ? "already_ran_this_turn" : "scheduler_defer");
30123
+ const reason = args.heuristics === undefined ? "disabled" : args.schedulerDeferReason ?? (!isCacheBustingPass ? "no_originating_cache_bust" : alreadyRanHeuristicsThisTurn ? "already_ran_this_turn" : "scheduler_defer");
29940
30124
  const heuristicsDecisionLog = `heuristics WILL NOT RUN — reason=${reason}`;
29941
30125
  sessionLog(args.sessionId, heuristicsDecisionLog);
29942
30126
  pendingDecisionLogObserverForTests?.(heuristicsDecisionLog);
@@ -29976,7 +30160,11 @@ async function runPipeline(args) {
29976
30160
  droppedStaleReduceCalls: heuristicsResult.droppedStaleReduceCalls + ridingCleanup.droppedStaleReduceCalls,
29977
30161
  emergencyDroppedTools: heuristicsResult.emergencyDroppedTools,
29978
30162
  compressedTextTags: heuristicsResult.compressedTextTags + ridingCleanup.compressedTextTags,
29979
- mutatedTextTags: heuristicsResult.mutatedTextTags + ridingCleanup.mutatedTextTags
30163
+ mutatedTextTags: heuristicsResult.mutatedTextTags + ridingCleanup.mutatedTextTags,
30164
+ droppedTokenReductions: [
30165
+ ...heuristicsResult.droppedTokenReductions,
30166
+ ...ridingCleanup.droppedTokenReductions
30167
+ ]
29980
30168
  };
29981
30169
  routineCleanupApplied = true;
29982
30170
  }
@@ -29986,6 +30174,9 @@ async function runPipeline(args) {
29986
30174
  const heuristicMutationCount = heuristicsResult.droppedTools + heuristicsResult.deduplicatedTools + heuristicsResult.droppedInjections + heuristicsResult.droppedStaleReduceCalls + heuristicsResult.mutatedTextTags;
29987
30175
  droppedCount += heuristicsResult.droppedTools + heuristicsResult.deduplicatedTools + heuristicsResult.droppedInjections + heuristicsResult.droppedStaleReduceCalls + heuristicsResult.mutatedTextTags;
29988
30176
  emergency ||= heuristicsResult.emergencyDroppedTools > 0;
30177
+ if (heuristicsResult.droppedTokenReductions.length > 0) {
30178
+ droppedTokenReductions.push(...heuristicsResult.droppedTokenReductions);
30179
+ }
29989
30180
  if (heuristicMutationCount > 0)
29990
30181
  heuristicOrReasoningDidMutate = true;
29991
30182
  heuristicsExecuted = true;
@@ -30094,7 +30285,7 @@ async function runPipeline(args) {
30094
30285
  }
30095
30286
  autoReclaimTargetCount = syntheticPendingOps.length;
30096
30287
  if (syntheticPendingOps.length > 0) {
30097
- autoReclaimDidMutate = applyPendingOperations(args.sessionId, args.db, targets, protectedTagNumbersForPass, undefined, [], syntheticPendingOps, editMarkerTagIds);
30288
+ autoReclaimDidMutate = applyPendingOperations(args.sessionId, args.db, targets, protectedTagNumbersForPass, undefined, [], syntheticPendingOps, editMarkerTagIds, (reduction) => droppedTokenReductions.push(reduction));
30098
30289
  if (autoReclaimDidMutate) {
30099
30290
  droppedCount += syntheticPendingOps.length;
30100
30291
  autoReclaimDidMutateThisPass = true;
@@ -30358,6 +30549,9 @@ async function runPipeline(args) {
30358
30549
  pendingDropTagNumbers: new Set(channelPendingOps.filter((operation) => operation.operation === "drop").map((operation) => operation.tagId))
30359
30550
  };
30360
30551
  const bustedThisPass = firstRenderBust || didMutateFromFlushedStatuses || pendingOpsDidMutate || heuristicOrReasoningDidMutate || autoReclaimDidMutateThisPass || materialized || historyWasConsumedThisPass;
30552
+ if (bustedThisPass || isCacheBustingPass) {
30553
+ droppedTokens = estimateDroppedTokensFromTagReductions(args.db, args.sessionId, droppedTokenReductions);
30554
+ }
30361
30555
  return {
30362
30556
  messages: outputMessages,
30363
30557
  heuristicsExecuted,
@@ -32805,7 +32999,7 @@ function formatTailHygiene(status) {
32805
32999
  // package.json
32806
33000
  var package_default = {
32807
33001
  name: "@cortexkit/pi-magic-context",
32808
- version: "0.42.5",
33002
+ version: "0.42.6",
32809
33003
  type: "module",
32810
33004
  description: "Pi and OMP coding agent extension for Magic Context — cross-session memory and context management",
32811
33005
  main: "dist/index.js",
@@ -8,7 +8,7 @@ import {
8
8
  ensureProjectRegisteredFromPiDirectory,
9
9
  resolvePiHarnessKind,
10
10
  registerMagicContextTools
11
- } from "./index-a0960w4w.js";
11
+ } from "./index-r918mh6w.js";
12
12
 
13
13
  // src/subagent-entry.ts
14
14
  var SUBAGENT_DREAMER_ACTIONS_FLAG = "magic-context-dreamer-actions";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/pi-magic-context",
3
- "version": "0.42.5",
3
+ "version": "0.42.6",
4
4
  "type": "module",
5
5
  "description": "Pi and OMP coding agent extension for Magic Context — cross-session memory and context management",
6
6
  "main": "dist/index.js",