pi-mega-compact 0.7.8 → 0.8.0
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/README.md +11 -12
- package/dist/extensions/dashboard-server/html.js +1023 -0
- package/dist/extensions/dashboard-server/html.test.js +41 -0
- package/dist/extensions/dashboard-server/index-reader.js +133 -0
- package/dist/extensions/dashboard-server/server.js +530 -0
- package/dist/extensions/dashboard-server/server.test.js +120 -0
- package/dist/extensions/dashboard-server/snapshot.js +43 -0
- package/dist/extensions/dashboard-server/state.js +30 -0
- package/dist/extensions/dashboard-server/types.js +5 -0
- package/dist/extensions/dashboard-server-s32.test.js +181 -0
- package/dist/extensions/dashboard-server.js +7 -1315
- package/dist/extensions/mega-commands.js +162 -134
- package/dist/extensions/mega-compact.js +3 -0
- package/dist/extensions/mega-compact.test.js +90 -21
- package/dist/extensions/mega-conflict-cmds.js +5 -1
- package/dist/extensions/mega-dashboard-cmds.js +29 -22
- package/dist/extensions/mega-db-cmds.js +11 -2
- package/dist/extensions/mega-events/agent-handlers.js +222 -0
- package/dist/extensions/mega-events/compact-handlers.js +162 -0
- package/dist/extensions/mega-events/context-handler.js +249 -0
- package/dist/extensions/mega-events/register.js +21 -0
- package/dist/extensions/mega-events/session-handlers.js +142 -0
- package/dist/extensions/mega-events.js +15 -699
- package/dist/extensions/mega-game-cmds.js +106 -0
- package/dist/extensions/mega-game-cmds.test.js +113 -0
- package/dist/extensions/mega-pipeline/compact.js +324 -0
- package/dist/extensions/mega-pipeline/memory-review.js +38 -0
- package/dist/extensions/mega-pipeline/recall.js +147 -0
- package/dist/extensions/mega-pipeline.js +9 -480
- package/dist/extensions/mega-runtime/helpers.js +40 -0
- package/dist/extensions/mega-runtime/query.js +29 -0
- package/dist/extensions/mega-runtime/state.js +877 -0
- package/dist/extensions/mega-runtime/state.test.js +171 -0
- package/dist/extensions/mega-runtime/widget.js +270 -0
- package/dist/extensions/mega-runtime/widget.test.js +160 -0
- package/dist/extensions/mega-runtime.js +15 -947
- package/dist/src/config/themes.js +84 -0
- package/dist/src/config/themes.test.js +94 -0
- package/dist/src/game/scoring.js +105 -0
- package/dist/src/game/scoring.test.js +98 -0
- package/dist/src/store/sqlite/checkpoints.js +145 -0
- package/dist/src/store/sqlite/dedup-mirror.js +64 -0
- package/dist/src/store/sqlite/foundation.js +38 -0
- package/dist/src/store/sqlite/game-achievements.js +111 -0
- package/dist/src/store/sqlite/game-achievements.test.js +67 -0
- package/dist/src/store/sqlite/game-scores.js +105 -0
- package/dist/src/store/sqlite/game-scores.test.js +106 -0
- package/dist/src/store/sqlite/game-state.js +54 -0
- package/dist/src/store/sqlite/game-state.test.js +76 -0
- package/dist/src/store/sqlite/global-index.js +224 -0
- package/dist/src/store/sqlite/maintenance.js +235 -0
- package/dist/src/store/sqlite/memories.js +164 -0
- package/dist/src/store/sqlite/meta.js +82 -0
- package/dist/src/store/sqlite/model-snapshots.js +47 -0
- package/dist/src/store/sqlite/raptor.js +57 -0
- package/dist/src/store/sqlite/raw-transcript.js +134 -0
- package/dist/src/store/sqlite/schema.js +294 -0
- package/dist/src/store/sqlite/session-state.js +28 -0
- package/dist/src/store/sqlite/stats.js +66 -0
- package/dist/src/store/sqlite/utils.js +120 -0
- package/dist/src/store/sqlite.js +23 -1607
- package/extensions/dashboard-server/html.test.ts +50 -0
- package/extensions/dashboard-server/html.ts +1026 -0
- package/extensions/dashboard-server/index-reader.ts +130 -0
- package/extensions/dashboard-server/server.test.ts +131 -0
- package/extensions/dashboard-server/server.ts +505 -0
- package/extensions/dashboard-server/snapshot.ts +44 -0
- package/extensions/dashboard-server/state.ts +33 -0
- package/extensions/dashboard-server/types.ts +134 -0
- package/extensions/dashboard-server-s32.test.ts +195 -0
- package/extensions/dashboard-server.ts +7 -1431
- package/extensions/mega-commands.ts +33 -10
- package/extensions/mega-compact.test.ts +198 -43
- package/extensions/mega-compact.ts +3 -0
- package/extensions/mega-conflict-cmds.ts +6 -2
- package/extensions/mega-dashboard-cmds.ts +30 -23
- package/extensions/mega-db-cmds.ts +11 -3
- package/extensions/mega-events/agent-handlers.ts +262 -0
- package/extensions/mega-events/compact-handlers.ts +192 -0
- package/extensions/mega-events/context-handler.ts +290 -0
- package/extensions/mega-events/register.ts +37 -0
- package/extensions/mega-events/session-handlers.ts +165 -0
- package/extensions/mega-events.ts +15 -780
- package/extensions/mega-game-cmds.test.ts +137 -0
- package/extensions/mega-game-cmds.ts +122 -0
- package/extensions/mega-pipeline/compact.ts +366 -0
- package/extensions/mega-pipeline/memory-review.ts +46 -0
- package/extensions/mega-pipeline/recall.ts +165 -0
- package/extensions/mega-pipeline.ts +9 -537
- package/extensions/mega-runtime/helpers.ts +68 -0
- package/extensions/mega-runtime/query.ts +29 -0
- package/extensions/mega-runtime/state.test.ts +171 -0
- package/extensions/mega-runtime/state.ts +967 -0
- package/extensions/mega-runtime/widget.test.ts +185 -0
- package/extensions/mega-runtime/widget.ts +359 -0
- package/extensions/mega-runtime.ts +15 -1093
- package/package.json +4 -3
- package/src/config/themes.test.ts +116 -0
- package/src/config/themes.ts +124 -0
- package/src/game/scoring.test.ts +103 -0
- package/src/game/scoring.ts +158 -0
- package/src/store/sqlite/checkpoints.ts +204 -0
- package/src/store/sqlite/dedup-mirror.ts +114 -0
- package/src/store/sqlite/foundation.ts +63 -0
- package/src/store/sqlite/game-achievements.test.ts +80 -0
- package/src/store/sqlite/game-achievements.ts +147 -0
- package/src/store/sqlite/game-scores.test.ts +132 -0
- package/src/store/sqlite/game-scores.ts +168 -0
- package/src/store/sqlite/game-state.test.ts +89 -0
- package/src/store/sqlite/game-state.ts +87 -0
- package/src/store/sqlite/global-index.ts +305 -0
- package/src/store/sqlite/maintenance.ts +294 -0
- package/src/store/sqlite/memories.ts +217 -0
- package/src/store/sqlite/meta.ts +108 -0
- package/src/store/sqlite/model-snapshots.ts +83 -0
- package/src/store/sqlite/raptor.ts +107 -0
- package/src/store/sqlite/raw-transcript.ts +221 -0
- package/src/store/sqlite/schema.ts +305 -0
- package/src/store/sqlite/session-state.ts +38 -0
- package/src/store/sqlite/stats.ts +127 -0
- package/src/store/sqlite/utils.ts +125 -0
- package/src/store/sqlite.ts +23 -2204
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* recall.ts — unified Layer-5 recall pipeline.
|
|
3
|
+
*
|
|
4
|
+
* `doRecall` is the ONE path that injects (sync). `doRecallAsync` augments with
|
|
5
|
+
* optional cross-repo HNSW on resume / /mega-recall --cross-repo. Both mutate
|
|
6
|
+
* the shared MegaRuntime (token accounting, ticker, dashboard events).
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
10
|
+
import { sessionEntryToContextMessages } from "@earendil-works/pi-coding-agent";
|
|
11
|
+
import { recallAndInline, recallAndInlineAsync, formatRecallBlock, type RecallInjectResult } from "../../src/recall.js";
|
|
12
|
+
import { normalizeSessionId } from "../../src/store.js";
|
|
13
|
+
import { incRecallInjected, incCacheHitTokens } from "../../src/store/sqlite.js";
|
|
14
|
+
import {
|
|
15
|
+
type MegaRuntime,
|
|
16
|
+
C,
|
|
17
|
+
} from "../mega-runtime.js";
|
|
18
|
+
import { type MegaConfig } from "../mega-config.js";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Unified recall (Layer 5). The ONE path that injects. Returns the recall
|
|
22
|
+
* result; callers decide whether to stage it for before_agent_start (resume)
|
|
23
|
+
* or report it (command).
|
|
24
|
+
*/
|
|
25
|
+
export function doRecall(
|
|
26
|
+
runtime: MegaRuntime,
|
|
27
|
+
config: MegaConfig,
|
|
28
|
+
ctx: ExtensionContext,
|
|
29
|
+
query: string,
|
|
30
|
+
source: "resume" | "command",
|
|
31
|
+
) {
|
|
32
|
+
runtime.bindRepo(ctx.cwd);
|
|
33
|
+
const sid = normalizeSessionId(ctx.sessionManager.getSessionId());
|
|
34
|
+
// Live window text for inline dedupe (Fix C): drop recalled checkpoints that
|
|
35
|
+
// are already resident in the session, so recall never re-injects context the
|
|
36
|
+
// model can already see. Best-effort — an empty window just skips dedupe.
|
|
37
|
+
const liveWindow = config.windowDedupe ? extractLiveWindow(ctx) : undefined;
|
|
38
|
+
const result = recallAndInline(
|
|
39
|
+
{
|
|
40
|
+
sessionId: sid,
|
|
41
|
+
query,
|
|
42
|
+
limit: config.autoInlineK,
|
|
43
|
+
source,
|
|
44
|
+
skipInjected: true,
|
|
45
|
+
recallMaxTokens: config.recallMaxTokens,
|
|
46
|
+
windowDedupe: config.windowDedupe,
|
|
47
|
+
liveWindow,
|
|
48
|
+
dedupSim: config.dedupSim,
|
|
49
|
+
},
|
|
50
|
+
runtime.store,
|
|
51
|
+
);
|
|
52
|
+
runtime.dashboard.event("recall", { source, query: query.slice(0, 120), injected: result.toInject.length, empty: result.empty });
|
|
53
|
+
if (!result.empty && result.toInject.length > 0) {
|
|
54
|
+
const top = result.toInject[0];
|
|
55
|
+
const scorePct = Math.round((top.score ?? 0) * 100);
|
|
56
|
+
const files = top.checkpoint.filesModified ?? [];
|
|
57
|
+
const label = files.length ? files.map((f) => f.split("/").pop() ?? f).slice(0, 2).join(", ") : top.checkpoint.checkpointId;
|
|
58
|
+
runtime.pushTicker(`${C.amber}↩${C.reset} recalled ${top.checkpoint.checkpointId} · ${scorePct}% · ${label}`);
|
|
59
|
+
runtime.lastWhy = `why: recalled@${scorePct}% (${result.toInject.length} chkpt)`;
|
|
60
|
+
}
|
|
61
|
+
if (result.toInject.length > 0) {
|
|
62
|
+
let sumTokens = 0; for (const h of result.toInject) sumTokens += h.checkpoint.tokenEstimate;
|
|
63
|
+
runtime.rt.recallInjections += result.toInject.length;
|
|
64
|
+
runtime.rt.cacheHitTokens += sumTokens;
|
|
65
|
+
incRecallInjected(result.toInject.length, runtime.currentStateDir);
|
|
66
|
+
incCacheHitTokens(sumTokens, runtime.currentStateDir);
|
|
67
|
+
}
|
|
68
|
+
return result;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* S17: async recall with optional cross-repo augmentation. Used on resume
|
|
73
|
+
* (session_start) and /mega-recall --cross-repo — NEVER from the mid-turn
|
|
74
|
+
* context handler (that stays sync). Runs the sync same-repo scan first; if it
|
|
75
|
+
* returns < config.autoInlineK hits AND crossRepo is enabled, awaits the PGlite
|
|
76
|
+
* HNSW cross-repo path and merges (source-labeled, deduped by checkpointId). The
|
|
77
|
+
* recallMaxTokens cap + windowDedupe apply to the merged set so cross-repo can
|
|
78
|
+
* never net-inflate the window. Cross-repo uses a stricter cosine floor
|
|
79
|
+
* (config.crossRepoCosine) than same-repo. Non-fatal: any async failure returns
|
|
80
|
+
* the same-repo result unchanged.
|
|
81
|
+
*/
|
|
82
|
+
export async function doRecallAsync(
|
|
83
|
+
runtime: MegaRuntime,
|
|
84
|
+
config: MegaConfig,
|
|
85
|
+
ctx: ExtensionContext,
|
|
86
|
+
query: string,
|
|
87
|
+
source: "resume" | "command",
|
|
88
|
+
opts: { crossRepo?: boolean } = {},
|
|
89
|
+
): Promise<RecallInjectResult> {
|
|
90
|
+
runtime.bindRepo(ctx.cwd);
|
|
91
|
+
const sid = normalizeSessionId(ctx.sessionManager.getSessionId());
|
|
92
|
+
const liveWindow = config.windowDedupe ? extractLiveWindow(ctx) : undefined;
|
|
93
|
+
// Sync same-repo first (fast, never blocks).
|
|
94
|
+
const sameRepo = recallAndInline(
|
|
95
|
+
{
|
|
96
|
+
sessionId: sid, query, limit: config.autoInlineK, source, skipInjected: true,
|
|
97
|
+
recallMaxTokens: config.recallMaxTokens, windowDedupe: config.windowDedupe,
|
|
98
|
+
liveWindow, dedupSim: config.dedupSim,
|
|
99
|
+
},
|
|
100
|
+
runtime.store,
|
|
101
|
+
);
|
|
102
|
+
if (!config.crossRepoEnabled || !opts.crossRepo) return sameRepo;
|
|
103
|
+
if (sameRepo.toInject.length >= config.autoInlineK) return sameRepo; // same-repo satisfied
|
|
104
|
+
// Augment: cross-repo HNSW (async) with the stricter floor. Non-fatal.
|
|
105
|
+
try {
|
|
106
|
+
const x = await recallAndInlineAsync(
|
|
107
|
+
{
|
|
108
|
+
sessionId: sid, query, limit: config.autoInlineK, source, skipInjected: true,
|
|
109
|
+
recallMaxTokens: config.recallMaxTokens, windowDedupe: config.windowDedupe,
|
|
110
|
+
liveWindow, dedupSim: config.crossRepoCosine, crossRepo: true,
|
|
111
|
+
globalIndexDir: process.env.MEGACOMPACT_INDEX_DIR,
|
|
112
|
+
},
|
|
113
|
+
runtime.store,
|
|
114
|
+
);
|
|
115
|
+
runtime.dashboard.event("recall-crossrepo", {
|
|
116
|
+
source, query: query.slice(0, 120), injected: x.toInject.length,
|
|
117
|
+
sourceRepos: x.toInject.map((h) => h.repoId).filter(Boolean),
|
|
118
|
+
});
|
|
119
|
+
// Merge, dedup by checkpointId, respect the same token cap by reformatting.
|
|
120
|
+
const seen = new Set(sameRepo.toInject.map((h) => h.checkpoint.checkpointId));
|
|
121
|
+
const merged = [...sameRepo.toInject];
|
|
122
|
+
for (const h of x.toInject) {
|
|
123
|
+
if (!seen.has(h.checkpoint.checkpointId)) { merged.push(h); seen.add(h.checkpoint.checkpointId); }
|
|
124
|
+
}
|
|
125
|
+
const block = merged.length ? formatRecallBlock(merged) : "";
|
|
126
|
+
if (merged.length > 0) {
|
|
127
|
+
let sumTokens = 0; for (const h of merged) sumTokens += h.checkpoint.tokenEstimate;
|
|
128
|
+
runtime.rt.recallInjections += merged.length;
|
|
129
|
+
runtime.rt.cacheHitTokens += sumTokens;
|
|
130
|
+
incRecallInjected(merged.length, runtime.currentStateDir);
|
|
131
|
+
incCacheHitTokens(sumTokens, runtime.currentStateDir);
|
|
132
|
+
}
|
|
133
|
+
return {
|
|
134
|
+
toInject: merged,
|
|
135
|
+
report: merged.map((h) => ` • ${h.checkpoint.checkpointId}${h.repoId ? ` (from ${h.repoId.split("/").filter(Boolean).pop()})` : ""}`),
|
|
136
|
+
block,
|
|
137
|
+
empty: merged.length === 0,
|
|
138
|
+
};
|
|
139
|
+
} catch {
|
|
140
|
+
return sameRepo; // cross-repo failure → same-repo only (non-fatal)
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Extract the live-window message texts from the session manager (Fix C),
|
|
146
|
+
* for inline-dedupe of recalled checkpoints. Best-effort: returns [] on any
|
|
147
|
+
* error so recall falls back to unbounded (still correct, just no dedupe).
|
|
148
|
+
* Mirrors recentUserQuery's use of sessionEntryToContextMessages.
|
|
149
|
+
*/
|
|
150
|
+
function extractLiveWindow(ctx: ExtensionContext): string[] {
|
|
151
|
+
try {
|
|
152
|
+
const entries = ctx.sessionManager.getEntries();
|
|
153
|
+
const texts: string[] = [];
|
|
154
|
+
for (const e of entries) {
|
|
155
|
+
for (const m of sessionEntryToContextMessages(e)) {
|
|
156
|
+
const c = (m as { content?: unknown }).content;
|
|
157
|
+
if (typeof c === "string") texts.push(c);
|
|
158
|
+
else if (Array.isArray(c)) texts.push(c.map((b: { text?: string }) => b.text ?? "").join(" "));
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return texts;
|
|
162
|
+
} catch {
|
|
163
|
+
return [];
|
|
164
|
+
}
|
|
165
|
+
}
|