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.
- package/dist/extensions/mega-compact-driver.js +1 -0
- package/dist/extensions/mega-pipeline.js +53 -17
- package/dist/extensions/mega-runtime.js +319 -122
- package/extensions/mega-compact-driver.ts +56 -55
- package/extensions/mega-pipeline.ts +481 -393
- package/extensions/mega-runtime.ts +934 -615
- package/package.json +1 -1
|
@@ -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
|
|
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 =
|
|
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
|
|
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 &&
|
|
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
|
|
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"
|
|
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", {
|
|
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
|
|
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,
|
|
398
|
-
|
|
399
|
-
|
|
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,
|
|
409
|
-
|
|
410
|
-
|
|
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,
|
|
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.
|