pi-mega-compact 0.7.0 → 0.7.1

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.
@@ -67,6 +67,7 @@ export function driveNativeCompaction(event, runtime, config) {
67
67
  runtime.rt.lastCompactedFrom = keepFrom;
68
68
  runtime.rt.lastCompactedTokens = tokensBefore;
69
69
  runtime.rt.tokensSaved += savedTokens;
70
+ runtime.rt.lastCompactAt = Date.now();
70
71
  runtime.rt.persistedThisSession = true;
71
72
  return {
72
73
  compaction: {
@@ -8,13 +8,13 @@
8
8
  */
9
9
  import { sessionEntryToContextMessages } from "@earendil-works/pi-coding-agent";
10
10
  import { compactSession } from "../src/engine.js";
11
- import { recallAndInline, recallAndInlineAsync, formatRecallBlock } from "../src/recall.js";
11
+ import { recallAndInline, recallAndInlineAsync, formatRecallBlock, } from "../src/recall.js";
12
12
  import { normalizeSessionId } from "../src/store.js";
13
13
  import { estimateBlockTokens } from "../src/tokens.js";
14
14
  import { touchSession, logDaily } from "../src/store/sqlite.js";
15
15
  import { consolidateMemories } from "../src/memory.js";
16
- import { C, MARKER_TYPE, } from "./mega-runtime.js";
17
- import { resolveRepoRoot, preserveRecentForPressure } from "./mega-config.js";
16
+ import { C, MARKER_TYPE } from "./mega-runtime.js";
17
+ import { resolveRepoRoot, preserveRecentForPressure, } from "./mega-config.js";
18
18
  import { runRaptor } from "../src/dedup/raptor/index.js";
19
19
  import { loadDedupConfig } from "../src/config/dedup.js";
20
20
  import { upsertEmbedding as indexUpsertEmbedding } from "../src/store/vectorIndex.js";
@@ -104,18 +104,23 @@ function doCompact(view, keepFrom, opts, sid, config, pi, ctx, runtime) {
104
104
  ? result.originalTokenEstimate
105
105
  : Math.max(0, result.originalTokenEstimate - result.tokenEstimate);
106
106
  runtime.rt.tokensSaved += saved;
107
+ runtime.rt.lastCompactAt = Date.now();
107
108
  if (result.deduped)
108
109
  runtime.rt.dedupSkips++;
109
110
  // Grow the rolling "saved" goal so the progress bar always has a fresh
110
111
  // denominator (we don't want it pinned at 100% once we pass an old target).
111
112
  if (runtime.rt.tokensSaved > runtime.savedGoal)
112
- runtime.savedGoal = Math.ceil((runtime.rt.tokensSaved * 1.25) / 10_000) * 10_000;
113
+ runtime.savedGoal =
114
+ Math.ceil((runtime.rt.tokensSaved * 1.25) / 10_000) * 10_000;
113
115
  // Live toolbar activity: what file/region just got compacted or deduped.
114
116
  // Rendered via the rotating ticker line (see snapshot); the ring buffer is
115
117
  // cycled one-per-repaint so the single line scrolls through recent files.
116
118
  const files = result.filesModified ?? [];
117
119
  const fileLabel = files.length
118
- ? files.map((f) => f.split("/").pop() ?? f).slice(0, 2).join(", ")
120
+ ? files
121
+ .map((f) => f.split("/").pop() ?? f)
122
+ .slice(0, 2)
123
+ .join(", ")
119
124
  : result.regionHash.slice(0, 8);
120
125
  runtime.lastActivityAt = Date.now();
121
126
  // Explain-why line: surfaced while fresh. Pulls the dedup reason (which for
@@ -167,7 +172,10 @@ function doCompact(view, keepFrom, opts, sid, config, pi, ctx, runtime) {
167
172
  // waiting for the next turn-cadence tick. Uses the shared runMemoryReview
168
173
  // helper (fire-and-forget; doCompact is sync). Best-effort + non-fatal. Only
169
174
  // fires above the `high` band so low-pressure compactions don't pay the cost.
170
- if (!result.deduped && config.memoryAutoReview && runtime.pressureBand !== "low" && runtime.pressureBand !== "medium") {
175
+ if (!result.deduped &&
176
+ config.memoryAutoReview &&
177
+ runtime.pressureBand !== "low" &&
178
+ runtime.pressureBand !== "medium") {
171
179
  void runMemoryReview(runtime, view, "pressure");
172
180
  }
173
181
  // Sentinel marker: a non-LLM bookkeeping entry so subsequent triggers can
@@ -195,7 +203,9 @@ function doCompact(view, keepFrom, opts, sid, config, pi, ctx, runtime) {
195
203
  // S25: stamp the tree with the newest checkpoint epoch so the
196
204
  // freshness guard in raptorSearchHits can reject stale trees after a
197
205
  // later compaction adds newer checkpoints.
198
- const builtAt = all.length > 0 ? Math.max(...all.map((c) => c.timestamp)) : Date.now();
206
+ const builtAt = all.length > 0
207
+ ? Math.max(...all.map((c) => c.timestamp))
208
+ : Date.now();
199
209
  runRaptor(leaves, {
200
210
  stateDir: runtime.currentStateDir,
201
211
  sessionId: sid,
@@ -313,7 +323,8 @@ export function piCompactWouldNoop(ctx) {
313
323
  if (m.role !== "toolResult")
314
324
  isCut = true;
315
325
  const c = m.content;
316
- const text = typeof c === "string" ? c
326
+ const text = typeof c === "string"
327
+ ? c
317
328
  : Array.isArray(c)
318
329
  ? c.map((b) => b?.text ?? "").join(" ")
319
330
  : "";
@@ -366,12 +377,22 @@ export function doRecall(runtime, config, ctx, query, source) {
366
377
  liveWindow,
367
378
  dedupSim: config.dedupSim,
368
379
  }, runtime.store);
369
- runtime.dashboard.event("recall", { source, query: query.slice(0, 120), injected: result.toInject.length, empty: result.empty });
380
+ runtime.dashboard.event("recall", {
381
+ source,
382
+ query: query.slice(0, 120),
383
+ injected: result.toInject.length,
384
+ empty: result.empty,
385
+ });
370
386
  if (!result.empty && result.toInject.length > 0) {
371
387
  const top = result.toInject[0];
372
388
  const scorePct = Math.round((top.score ?? 0) * 100);
373
389
  const files = top.checkpoint.filesModified ?? [];
374
- const label = files.length ? files.map((f) => f.split("/").pop() ?? f).slice(0, 2).join(", ") : top.checkpoint.checkpointId;
390
+ const label = files.length
391
+ ? files
392
+ .map((f) => f.split("/").pop() ?? f)
393
+ .slice(0, 2)
394
+ .join(", ")
395
+ : top.checkpoint.checkpointId;
375
396
  runtime.pushTicker(`${C.amber}↩${C.reset} recalled ${top.checkpoint.checkpointId} · ${scorePct}% · ${label}`);
376
397
  runtime.lastWhy = `why: recalled@${scorePct}% (${result.toInject.length} chkpt)`;
377
398
  }
@@ -394,9 +415,15 @@ export async function doRecallAsync(runtime, config, ctx, query, source, opts =
394
415
  const liveWindow = config.windowDedupe ? extractLiveWindow(ctx) : undefined;
395
416
  // Sync same-repo first (fast, never blocks).
396
417
  const sameRepo = recallAndInline({
397
- sessionId: sid, query, limit: config.autoInlineK, source, skipInjected: true,
398
- recallMaxTokens: config.recallMaxTokens, windowDedupe: config.windowDedupe,
399
- liveWindow, dedupSim: config.dedupSim,
418
+ sessionId: sid,
419
+ query,
420
+ limit: config.autoInlineK,
421
+ source,
422
+ skipInjected: true,
423
+ recallMaxTokens: config.recallMaxTokens,
424
+ windowDedupe: config.windowDedupe,
425
+ liveWindow,
426
+ dedupSim: config.dedupSim,
400
427
  }, runtime.store);
401
428
  if (!config.crossRepoEnabled || !opts.crossRepo)
402
429
  return sameRepo;
@@ -405,13 +432,22 @@ export async function doRecallAsync(runtime, config, ctx, query, source, opts =
405
432
  // Augment: cross-repo HNSW (async) with the stricter floor. Non-fatal.
406
433
  try {
407
434
  const x = await recallAndInlineAsync({
408
- sessionId: sid, query, limit: config.autoInlineK, source, skipInjected: true,
409
- recallMaxTokens: config.recallMaxTokens, windowDedupe: config.windowDedupe,
410
- liveWindow, dedupSim: config.crossRepoCosine, crossRepo: true,
435
+ sessionId: sid,
436
+ query,
437
+ limit: config.autoInlineK,
438
+ source,
439
+ skipInjected: true,
440
+ recallMaxTokens: config.recallMaxTokens,
441
+ windowDedupe: config.windowDedupe,
442
+ liveWindow,
443
+ dedupSim: config.crossRepoCosine,
444
+ crossRepo: true,
411
445
  globalIndexDir: process.env.MEGACOMPACT_INDEX_DIR,
412
446
  }, runtime.store);
413
447
  runtime.dashboard.event("recall-crossrepo", {
414
- source, query: query.slice(0, 120), injected: x.toInject.length,
448
+ source,
449
+ query: query.slice(0, 120),
450
+ injected: x.toInject.length,
415
451
  sourceRepos: x.toInject.map((h) => h.repoId).filter(Boolean),
416
452
  });
417
453
  // Merge, dedup by checkpointId, respect the same token cap by reformatting.