pi-mega-compact 0.13.1 → 0.13.2
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/dashboard-server/api-contracts/embedder-health.js +11 -0
- package/dist/extensions/dashboard-server/api-contracts/endpoints/registry.js +225 -0
- package/dist/extensions/dashboard-server/api-contracts/endpoints/types.js +1 -0
- package/dist/extensions/dashboard-server/api-contracts/endpoints.js +5 -224
- package/dist/extensions/dashboard-server/api-contracts/raptor.js +8 -0
- package/dist/extensions/dashboard-server/api-contracts.test/_helpers.js +32 -0
- package/dist/extensions/dashboard-server/routes-cache.test/_helpers.js +48 -0
- package/dist/extensions/dashboard-server/routes-embedder-health.js +67 -0
- package/dist/extensions/dashboard-server/routes-raptor.js +88 -0
- package/dist/extensions/dashboard-server/routes-setup.js +1 -1
- package/dist/extensions/dashboard-server/routes.js +2 -0
- package/dist/extensions/dashboard-server/server.js +5 -1
- package/dist/extensions/mega-cache-replay.test/_helpers.js +175 -0
- package/dist/extensions/mega-commands/dataCommands.js +151 -0
- package/dist/extensions/mega-commands/helpers.js +61 -0
- package/dist/extensions/mega-commands/historyCommands.js +97 -0
- package/dist/extensions/mega-commands/setupCommand.js +200 -0
- package/dist/extensions/mega-commands.js +14 -499
- package/dist/extensions/mega-compact-s38.test/_helpers.js +194 -0
- package/dist/extensions/mega-compact.test/_helpers.js +225 -0
- package/dist/extensions/mega-events/agent-handlers/agentEndHandler.js +211 -0
- package/dist/extensions/mega-events/agent-handlers/turnEndHandler/cacheStripe.js +49 -0
- package/dist/extensions/mega-events/agent-handlers/turnEndHandler/contextHealth.js +33 -0
- package/dist/extensions/mega-events/agent-handlers/turnEndHandler/errorRetry.js +387 -0
- package/dist/extensions/mega-events/agent-handlers/turnEndHandler/event.js +7 -0
- package/dist/extensions/mega-events/agent-handlers/turnEndHandler/gameScoring.js +55 -0
- package/dist/extensions/mega-events/agent-handlers/turnEndHandler/lengthStop.js +12 -0
- package/dist/extensions/mega-events/agent-handlers/turnEndHandler/memoryReview.js +22 -0
- package/dist/extensions/mega-events/agent-handlers/turnEndHandler/recordTurnRow.js +38 -0
- package/dist/extensions/mega-events/agent-handlers/turnEndHandler.js +36 -0
- package/dist/extensions/mega-events/agent-handlers.js +4 -799
- package/dist/extensions/mega-events/context-handler/afterCompact.js +163 -0
- package/dist/extensions/mega-events/context-handler/messageText.js +12 -0
- package/dist/extensions/mega-events/context-handler/tailResult.js +46 -0
- package/dist/extensions/mega-events/context-handler.js +11 -198
- package/dist/extensions/mega-events/separated-prompt.test/_helpers.js +25 -0
- package/dist/src/config.js +2 -0
- package/dist/src/dedup-engine.test/_helpers.js +55 -0
- package/dist/src/e2e.test/_helpers.js +52 -0
- package/dist/src/embedder.js +1 -0
- package/dist/src/httpEmbedder.js +6 -0
- package/dist/src/hyde.js +146 -0
- package/dist/src/importance.test/_helpers.js +5 -0
- package/dist/src/memoryGraph/sources/checkpoints.js +78 -0
- package/dist/src/memoryGraph/sources/edges.js +17 -0
- package/dist/src/memoryGraph/sources/flags.js +22 -0
- package/dist/src/memoryGraph/sources/helpers.js +14 -0
- package/dist/src/memoryGraph/sources/memories.js +88 -0
- package/dist/src/memoryGraph/sources/raptor.js +26 -0
- package/dist/src/memoryGraph/sources/turns.js +176 -0
- package/dist/src/memoryGraph/sources.js +15 -441
- package/dist/src/memoryGraph-gates.test/_helpers.js +120 -0
- package/dist/src/ratio.bench.test/_helpers.js +198 -0
- package/dist/src/recall/async.js +112 -0
- package/dist/src/recall/format.js +149 -0
- package/dist/src/recall/memory.js +62 -0
- package/dist/src/recall/reformulate.js +82 -0
- package/dist/src/recall/sync.js +169 -0
- package/dist/src/recall/types.js +1 -0
- package/dist/src/recall.js +13 -530
- package/dist/src/store/sqlite/schema/core.js +232 -0
- package/dist/src/store/sqlite/schema/game.js +65 -0
- package/dist/src/store/sqlite/schema/plan-v2.js +107 -0
- package/dist/src/store/sqlite/schema/turns.js +59 -0
- package/dist/src/store/sqlite/schema.js +8 -441
- package/dist/src/store/turns/contract-compliance.test/_helpers.js +21 -0
- package/dist/src/store/turns/sqlite-store/admin.js +171 -0
- package/dist/src/store/turns/sqlite-store/ctx.js +1 -0
- package/dist/src/store/turns/sqlite-store/read.js +111 -0
- package/dist/src/store/turns/sqlite-store/rows.js +42 -0
- package/dist/src/store/turns/sqlite-store/write.js +102 -0
- package/dist/src/store/turns/sqlite-store.js +31 -367
- package/dist/src/vectorStore/class.js +356 -0
- package/dist/src/vectorStore/hash.js +10 -0
- package/dist/src/vectorStore/types.js +2 -0
- package/dist/src/vectorStore.js +8 -359
- package/dist/src/vectorStore.test/_helpers.js +17 -0
- package/extensions/dashboard-client/dist/assets/{CacheTab-8HRroK9K.js → CacheTab-DPRHjYZ0.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{CacheTab-8HRroK9K.js.map → CacheTab-DPRHjYZ0.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{EventsTab-ncobZw-I.js → EventsTab-CgwYq-Qf.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{EventsTab-ncobZw-I.js.map → EventsTab-CgwYq-Qf.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{HealthTab-C6BI1EZG.js → HealthTab-BgOCjVzR.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{HealthTab-C6BI1EZG.js.map → HealthTab-BgOCjVzR.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/MaintenanceTab-Yw1yFpsy.js +2 -0
- package/extensions/dashboard-client/dist/assets/MaintenanceTab-Yw1yFpsy.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/MemoryMapTab-yHUX7Yzi.js +2 -0
- package/extensions/dashboard-client/dist/assets/MemoryMapTab-yHUX7Yzi.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/{MetricsTab-B88XTCMk.js → MetricsTab-CcH9fP8P.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MetricsTab-B88XTCMk.js.map → MetricsTab-CcH9fP8P.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{OverviewTab-CGZrSia-.js → OverviewTab-BOs8ZNev.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{OverviewTab-CGZrSia-.js.map → OverviewTab-BOs8ZNev.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{ReposTab-BZo5cNS1.js → ReposTab-B-MfSPvg.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{ReposTab-BZo5cNS1.js.map → ReposTab-B-MfSPvg.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{SessionsTab-C2RokJcw.js → SessionsTab-BmeN649Q.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{SessionsTab-C2RokJcw.js.map → SessionsTab-BmeN649Q.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/SetupTab-nOknoph5.js +2 -0
- package/extensions/dashboard-client/dist/assets/SetupTab-nOknoph5.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/{TimeSavedCard-CewYB2aA.js → TimeSavedCard-DnPg0L0z.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{TimeSavedCard-CewYB2aA.js.map → TimeSavedCard-DnPg0L0z.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{TopicsTab-DpVNIuaL.js → TopicsTab-BODHOg_b.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{TopicsTab-DpVNIuaL.js.map → TopicsTab-BODHOg_b.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{TurnsTab-KeuKKVC9.js → TurnsTab-BK0I7hKr.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{TurnsTab-KeuKKVC9.js.map → TurnsTab-BK0I7hKr.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{index-Cucgohga.js → index-mOlljTFI.js} +9 -9
- package/extensions/dashboard-client/dist/assets/index-mOlljTFI.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/{useSSE-DJsqdPXC.js → useSSE-BYOtv1-3.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{useSSE-DJsqdPXC.js.map → useSSE-BYOtv1-3.js.map} +1 -1
- package/extensions/dashboard-client/dist/index.html +1 -1
- package/extensions/dashboard-client/src/api/client.ts +16 -0
- package/extensions/dashboard-client/src/tabs/MaintenanceTab/ActionsCard.tsx +178 -0
- package/extensions/dashboard-client/src/tabs/MaintenanceTab/DbStatsCard.tsx +140 -0
- package/extensions/dashboard-client/src/tabs/MaintenanceTab/DebugBundleCard.tsx +109 -0
- package/extensions/dashboard-client/src/tabs/MaintenanceTab/HealthMitigationCard.tsx +98 -0
- package/extensions/dashboard-client/src/tabs/MaintenanceTab/SchemaHealthCard.tsx +108 -0
- package/extensions/dashboard-client/src/tabs/MaintenanceTab.tsx +12 -598
- package/extensions/dashboard-client/src/tabs/MemoryMapTab/MemoryMapView.tsx +476 -0
- package/extensions/dashboard-client/src/tabs/MemoryMapTab/RaptorTreeView.tsx +163 -0
- package/extensions/dashboard-client/src/tabs/MemoryMapTab.tsx +56 -466
- package/extensions/dashboard-client/src/tabs/SetupTab/EmbedderHealthCard.tsx +109 -0
- package/extensions/dashboard-client/src/tabs/SetupTab/EmbedderSetup.tsx +468 -0
- package/extensions/dashboard-client/src/tabs/SetupTab.tsx +13 -483
- package/extensions/dashboard-server/api-contracts/embedder-health.ts +32 -0
- package/extensions/dashboard-server/api-contracts/endpoints/registry.ts +360 -0
- package/extensions/dashboard-server/api-contracts/endpoints/types.ts +350 -0
- package/extensions/dashboard-server/api-contracts/endpoints.ts +27 -648
- package/extensions/dashboard-server/api-contracts/index.ts +6 -0
- package/extensions/dashboard-server/api-contracts/raptor.ts +49 -0
- package/extensions/dashboard-server/api-contracts.test/_helpers.ts +47 -0
- package/extensions/dashboard-server/routes-cache.test/_helpers.ts +94 -0
- package/extensions/dashboard-server/routes-embedder-health.ts +77 -0
- package/extensions/dashboard-server/routes-raptor.ts +128 -0
- package/extensions/dashboard-server/routes-setup.ts +1 -1
- package/extensions/dashboard-server/routes.ts +2 -0
- package/extensions/dashboard-server/server.ts +4 -0
- package/extensions/mega-cache-replay.test/_helpers.ts +188 -0
- package/extensions/mega-commands/dataCommands.ts +169 -0
- package/extensions/mega-commands/helpers.ts +62 -0
- package/extensions/mega-commands/historyCommands.ts +117 -0
- package/extensions/mega-commands/setupCommand.ts +235 -0
- package/extensions/mega-commands.ts +25 -538
- package/extensions/mega-compact-s38.test/_helpers.ts +201 -0
- package/extensions/mega-compact.test/_helpers.ts +237 -0
- package/extensions/mega-events/agent-handlers/agentEndHandler.ts +238 -0
- package/extensions/mega-events/agent-handlers/turnEndHandler/cacheStripe.ts +74 -0
- package/extensions/mega-events/agent-handlers/turnEndHandler/contextHealth.ts +50 -0
- package/extensions/mega-events/agent-handlers/turnEndHandler/errorRetry.ts +421 -0
- package/extensions/mega-events/agent-handlers/turnEndHandler/event.ts +16 -0
- package/extensions/mega-events/agent-handlers/turnEndHandler/gameScoring.ts +73 -0
- package/extensions/mega-events/agent-handlers/turnEndHandler/lengthStop.ts +29 -0
- package/extensions/mega-events/agent-handlers/turnEndHandler/memoryReview.ts +42 -0
- package/extensions/mega-events/agent-handlers/turnEndHandler/recordTurnRow.ts +61 -0
- package/extensions/mega-events/agent-handlers/turnEndHandler.ts +64 -0
- package/extensions/mega-events/agent-handlers.ts +15 -861
- package/extensions/mega-events/context-handler/afterCompact.ts +213 -0
- package/extensions/mega-events/context-handler/messageText.ts +20 -0
- package/extensions/mega-events/context-handler/tailResult.ts +63 -0
- package/extensions/mega-events/context-handler.ts +17 -235
- package/extensions/mega-events/separated-prompt.test/_helpers.ts +35 -0
- package/package.json +1 -1
- package/src/config.ts +4 -0
- package/src/dedup-engine.test/_helpers.ts +79 -0
- package/src/e2e.test/_helpers.ts +59 -0
- package/src/embedder.ts +4 -0
- package/src/httpEmbedder.ts +7 -0
- package/src/hyde.ts +162 -0
- package/src/importance.test/_helpers.ts +5 -0
- package/src/memoryGraph/sources/checkpoints.ts +99 -0
- package/src/memoryGraph/sources/edges.ts +23 -0
- package/src/memoryGraph/sources/flags.ts +26 -0
- package/src/memoryGraph/sources/helpers.ts +13 -0
- package/src/memoryGraph/sources/memories.ts +108 -0
- package/src/memoryGraph/sources/raptor.ts +37 -0
- package/src/memoryGraph/sources/turns.ts +226 -0
- package/src/memoryGraph/sources.ts +19 -544
- package/src/memoryGraph-gates.test/_helpers.ts +164 -0
- package/src/ratio.bench.test/_helpers.ts +268 -0
- package/src/recall/async.ts +142 -0
- package/src/recall/format.ts +173 -0
- package/src/recall/memory.ts +90 -0
- package/src/recall/reformulate.ts +111 -0
- package/src/recall/sync.ts +196 -0
- package/src/recall/types.ts +63 -0
- package/src/recall.ts +25 -712
- package/src/store/sqlite/schema/core.ts +233 -0
- package/src/store/sqlite/schema/game.ts +66 -0
- package/src/store/sqlite/schema/plan-v2.ts +108 -0
- package/src/store/sqlite/schema/turns.ts +60 -0
- package/src/store/sqlite/schema.ts +13 -441
- package/src/store/turns/contract-compliance.test/_helpers.ts +38 -0
- package/src/store/turns/sqlite-store/admin.ts +249 -0
- package/src/store/turns/sqlite-store/ctx.ts +14 -0
- package/src/store/turns/sqlite-store/read.ts +174 -0
- package/src/store/turns/sqlite-store/rows.ts +55 -0
- package/src/store/turns/sqlite-store/write.ts +193 -0
- package/src/store/turns/sqlite-store.ts +33 -514
- package/src/vectorStore/class.ts +433 -0
- package/src/vectorStore/hash.ts +11 -0
- package/src/vectorStore/types.ts +58 -0
- package/src/vectorStore.test/_helpers.ts +20 -0
- package/src/vectorStore.ts +13 -489
- package/extensions/dashboard-client/dist/assets/MaintenanceTab-DZi1MnZI.js +0 -2
- package/extensions/dashboard-client/dist/assets/MaintenanceTab-DZi1MnZI.js.map +0 -1
- package/extensions/dashboard-client/dist/assets/MemoryMapTab-CjUa9zzw.js +0 -2
- package/extensions/dashboard-client/dist/assets/MemoryMapTab-CjUa9zzw.js.map +0 -1
- package/extensions/dashboard-client/dist/assets/SetupTab-C_BwmebC.js +0 -2
- package/extensions/dashboard-client/dist/assets/SetupTab-C_BwmebC.js.map +0 -1
- package/extensions/dashboard-client/dist/assets/index-Cucgohga.js.map +0 -1
|
@@ -1,548 +1,35 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* mega-commands.ts — the data/inspection slash commands.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Delegate-shell (extensions split): registers the 8 user-facing commands that
|
|
5
|
+
* operate on the local vector store and live runtime state. Implementation is
|
|
6
|
+
* split by group into ./mega-commands/:
|
|
7
|
+
* - dataCommands.ts /mega-compact, /mega-recall, /mega-status
|
|
8
|
+
* - historyCommands.ts /mega-restore, /mega-history, /mega-view, /mega-help
|
|
9
|
+
* - setupCommand.ts /mega-setup
|
|
10
|
+
* - helpers.ts findCheckpoint + checkRecallQuality
|
|
7
11
|
*/
|
|
8
12
|
|
|
9
|
-
import type { ExtensionAPI
|
|
10
|
-
import {
|
|
11
|
-
import { normalizeSessionId } from "../src/store.js";
|
|
12
|
-
import { listCheckpoints, latestModelSnapshot, countInjectedGlobal, listRepoRegistry } from "../src/store/sqlite.js";
|
|
13
|
-
import { decompressSmart } from "../src/store/compression.js";
|
|
14
|
-
import { loadMetrics, fpRate, p95, defaultMetricsPath, defaultEventsPath } from "../src/monitoring.js";
|
|
15
|
-
import { type MegaRuntime, C, recentUserQuery } from "./mega-runtime.js";
|
|
16
|
-
import { runCompact, doRecall, doRecallAsync } from "./mega-pipeline.js";
|
|
17
|
-
import { vectorStats, vectorRepoStats, vectorDataInvariant } from "../src/vectorStore.js";
|
|
13
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
14
|
+
import type { MegaRuntime } from "./mega-runtime.js";
|
|
18
15
|
import type { MegaConfig } from "./mega-config.js";
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import
|
|
22
|
-
import os from "node:os";
|
|
23
|
-
import { createRequire } from "node:module";
|
|
16
|
+
import { registerDataCommands } from "./mega-commands/dataCommands.js";
|
|
17
|
+
import { registerHistoryCommands } from "./mega-commands/historyCommands.js";
|
|
18
|
+
import { registerSetupCommand } from "./mega-commands/setupCommand.js";
|
|
24
19
|
|
|
25
|
-
|
|
26
|
-
export function findCheckpoint(runtime: MegaRuntime, sid: string, ref: string) {
|
|
27
|
-
const all = listCheckpoints(sid, runtime.currentStateDir);
|
|
28
|
-
if (all.length === 0) return undefined;
|
|
29
|
-
if (!ref || ref === "recent" || ref === "last") return all[all.length - 1];
|
|
30
|
-
return all.find((c) => c.checkpointId === ref) ?? all.find((c) => c.checkpointId.endsWith(ref));
|
|
31
|
-
}
|
|
20
|
+
export { findCheckpoint } from "./mega-commands/helpers.js";
|
|
32
21
|
|
|
33
22
|
/** Register all data/inspection commands. */
|
|
34
|
-
export function registerCommands(
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
const r = (ran as { result: { deduped: boolean; checkpointId?: string; tokenEstimate: number } }).result;
|
|
49
|
-
ctx.ui.notify(
|
|
50
|
-
`[mega-compact] ${r.deduped ? "region already compacted (deduped)" : `persisted ${r.checkpointId}`} · ` +
|
|
51
|
-
`${r.tokenEstimate} tok · ${runtime.currentStateDir}`,
|
|
52
|
-
);
|
|
53
|
-
} catch (e) {
|
|
54
|
-
ctx.ui.notify(`[mega-compact] /mega-compact failed: ${String(e)}`);
|
|
55
|
-
}
|
|
56
|
-
},
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
pi.registerCommand("mega-recall", {
|
|
60
|
-
description: "Recall relevant compacted context from the vector store and inline it. Use --cross-repo to search all repos.",
|
|
61
|
-
handler: async (args: string, ctx: ExtensionContext) => {
|
|
62
|
-
try {
|
|
63
|
-
// S17: --cross-repo (or --cross repo) runs the async path over every repo's
|
|
64
|
-
// PGlite HNSW index (stricter cosine floor + source labels).
|
|
65
|
-
const crossRepo = /--cross[- ]repo\b/.test(args);
|
|
66
|
-
const query = args.replace(/--cross[- ]repo\b/, "").trim() || recentUserQuery(ctx);
|
|
67
|
-
if (!query) {
|
|
68
|
-
ctx.ui.notify("[mega-compact] /mega-recall needs a query or a prior user message.");
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
const r = crossRepo
|
|
72
|
-
? await doRecallAsync(runtime, config, ctx, query, "command", { crossRepo: true })
|
|
73
|
-
: doRecall(runtime, config, ctx, query, "command");
|
|
74
|
-
if (r.empty) {
|
|
75
|
-
runtime.logger.info("recall-empty", { query, crossRepo });
|
|
76
|
-
ctx.ui.notify(`[mega-compact] recall found nothing new for "${query}".`);
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
// Stage the block so the next before_agent_start prepends it (actual
|
|
80
|
-
// injection). Report what was selected now for immediate feedback.
|
|
81
|
-
runtime.pendingRecallBlock = r.block;
|
|
82
|
-
const list = r.report.map((l) => l).join("\n");
|
|
83
|
-
runtime.logger.info("recall", { query, crossRepo, injected: r.toInject.map((h) => h.checkpoint.checkpointId) });
|
|
84
|
-
runtime.setStatus(ctx, `mega-compact: recalled ${r.toInject.length} chkpt${crossRepo ? " (cross-repo)" : ""}`);
|
|
85
|
-
ctx.ui.notify(
|
|
86
|
-
`[mega-compact] recall staged ${r.toInject.length} checkpoint(s) for "${query}"${crossRepo ? " (cross-repo)" : ""}:\n${list}\n` +
|
|
87
|
-
`(injected at the tail of the next turn's context)`,
|
|
88
|
-
);
|
|
89
|
-
} catch (e) {
|
|
90
|
-
ctx.ui.notify(`[mega-compact] /mega-recall failed: ${String(e)}`);
|
|
91
|
-
}
|
|
92
|
-
},
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
pi.registerCommand("mega-status", {
|
|
96
|
-
description: "Show mega-compact config, context usage, and the data-safety invariant.",
|
|
97
|
-
handler: async (_args: string, ctx: ExtensionContext) => {
|
|
98
|
-
try {
|
|
99
|
-
runtime.bindRepo(ctx.cwd);
|
|
100
|
-
const usage = ctx.getContextUsage();
|
|
101
|
-
const pct = usage?.percent != null ? `${usage.percent}%` : "n/a";
|
|
102
|
-
const tokens = usage?.tokens != null ? `${usage.tokens} tok` : "n/a";
|
|
103
|
-
const sid = normalizeSessionId(ctx.sessionManager.getSessionId());
|
|
104
|
-
const st = vectorStats(runtime.store, sid);
|
|
105
|
-
const repo = vectorRepoStats(runtime.store);
|
|
106
|
-
const di = vectorDataInvariant(runtime.store);
|
|
107
|
-
const fmtB = (b: number) =>
|
|
108
|
-
b >= 1_048_576 ? `${(b / 1_048_576).toFixed(1)} MiB` :
|
|
109
|
-
b >= 1024 ? `${(b / 1024).toFixed(1)} KiB` : `${b} B`;
|
|
110
|
-
// Real cost: tokens saved × the captured model's input rate (USD/token),
|
|
111
|
-
// read from the model_snapshots table (Phase 5b schema). Falls back to 0
|
|
112
|
-
// when no model has been captured yet. contextWindow ÷ savedRate = context
|
|
113
|
-
// windows extended (how much "extra" conversation the freed space buys).
|
|
114
|
-
const model = latestModelSnapshot(runtime.currentStateDir);
|
|
115
|
-
const rate = model?.inputRate ?? 0;
|
|
116
|
-
const usd = ((repo.tokensSaved ?? 0) * rate).toFixed(4);
|
|
117
|
-
const ctxWindow = usage?.contextWindow ?? 0;
|
|
118
|
-
const daysExtended = ctxWindow > 0 && repo.tokensSaved > 0
|
|
119
|
-
? (repo.tokensSaved / ctxWindow).toFixed(1)
|
|
120
|
-
: "0";
|
|
121
|
-
// Identified model/provider (captured on model_select / session_start).
|
|
122
|
-
// Shows the human model name + provider so the user knows WHICH model's
|
|
123
|
-
// pricing drives the cost figure. Falls back when none captured yet.
|
|
124
|
-
const modelStr = model
|
|
125
|
-
? `${model.modelName ?? model.modelId ?? "?"} · ${model.providerName ?? model.provider ?? "?"}`
|
|
126
|
-
: "unknown (no model captured)";
|
|
127
|
-
const costStr = `≈ $${usd} saved · ${daysExtended} context-windows extended`;
|
|
128
|
-
// Recall-quality badge (Phase 4): trust score from monitoring metrics.
|
|
129
|
-
// H1 fix: loadMetrics expects a *file* path (dashboard.json), not the
|
|
130
|
-
// state dir — passing the dir made existsSync() true (dirs exist) then
|
|
131
|
-
// readFileSync() threw EISDIR, silently caught → metrics always zero.
|
|
132
|
-
const m = loadMetrics(defaultMetricsPath(runtime.currentStateDir));
|
|
133
|
-
const fp = fpRate(m, "L2");
|
|
134
|
-
const p95L2 = p95(m.latency.L2 ?? []);
|
|
135
|
-
const relPct = (st.dedupHitRate * 100).toFixed(0);
|
|
136
|
-
const qualityStr = `recall ${relPct}% relevant · FP ${(fp * 100).toFixed(1)}% · L2 p95 ${p95L2.toFixed(0)}ms`;
|
|
137
|
-
// S18: cross-repo stats from the machine-wide index (best-effort; the
|
|
138
|
-
// index dir may be unset → 0/empty, never throws).
|
|
139
|
-
let crossRepoInjections = 0;
|
|
140
|
-
let repoCount = 0;
|
|
141
|
-
try {
|
|
142
|
-
crossRepoInjections = countInjectedGlobal(process.env.MEGACOMPACT_INDEX_DIR);
|
|
143
|
-
repoCount = listRepoRegistry(process.env.MEGACOMPACT_INDEX_DIR).length;
|
|
144
|
-
} catch { /* non-fatal */ }
|
|
145
|
-
const crossRepoStr = `${crossRepoInjections} cross-repo injections recorded · ${repoCount} repos indexed`;
|
|
146
|
-
// Effective compaction threshold = tierPct × model context window (kept
|
|
147
|
-
// BELOW pi's native ~80% auto-compact for any model size). Falls back to
|
|
148
|
-
// the boot token value when the window is unknown (custom tier / pre-
|
|
149
|
-
// model-select). Display matches the dashboard's percentage-based view.
|
|
150
|
-
const effThreshold = config.tierPct != null && ctxWindow > 0
|
|
151
|
-
? Math.round(config.tierPct * ctxWindow)
|
|
152
|
-
: config.thresholdTokens;
|
|
153
|
-
const winStr = ctxWindow > 0
|
|
154
|
-
? (ctxWindow >= 1_000_000 ? `${Math.round(ctxWindow / 1_000_000)}M` : `${Math.round(ctxWindow / 1_000)}k`)
|
|
155
|
-
: "?";
|
|
156
|
-
const tierPctStr = config.tierPct != null ? `${Math.round(config.tierPct * 100)}%` : "n/a";
|
|
157
|
-
ctx.ui.notify(
|
|
158
|
-
`[mega-compact] pct=${pct} tokens=${tokens} tier=${runtime.pressureBand} (live) preset=${config.tier} ` +
|
|
159
|
-
`pressure=${Math.round(runtime.pressure * 100)}% fastGate=${config.fastGatePct}% ` +
|
|
160
|
-
`threshold=${effThreshold.toLocaleString()} (${tierPctStr} of ${winStr} window) tierPct=${config.tierPct != null ? config.tierPct.toFixed(2) : "n/a"} auto=${config.auto} autoInline=${config.autoInline}\n` +
|
|
161
|
-
`[mega-compact] store: ${st.checkpointCount} chkpt · ` +
|
|
162
|
-
`${st.totalTokenEstimate} tok · last=${st.lastCheckpointId ?? "—"} · ` +
|
|
163
|
-
`injected=${st.injectedCount} · dedup=${(st.dedupHitRate * 100).toFixed(0)}%\n` +
|
|
164
|
-
`[mega-compact] anchor=${config.anchorUserMessages} preserveRecent=${config.preserveRecent} ` +
|
|
165
|
-
`autoInlineK=${config.autoInlineK} dedupSim=${config.dedupSim} debug=${config.debug}\n` +
|
|
166
|
-
`[mega-compact] 🛡 data-safe: ${di.regionsRetained} regions retained ` +
|
|
167
|
-
`(${fmtB(di.compressedOriginalBytes)} compressed-original) · ` +
|
|
168
|
-
`${di.duplicatesCollapsed} dedup-duplicates collapsed · ` +
|
|
169
|
-
`${C.green}0 bytes permanently deleted${C.reset}\n` +
|
|
170
|
-
`[mega-compact] 💰 ${costStr}\n` +
|
|
171
|
-
`[mega-compact] 🤖 model: ${modelStr}\n` +
|
|
172
|
-
`[mega-compact] 🎯 ${qualityStr}\n` +
|
|
173
|
-
`[mega-compact] 🌐 ${crossRepoStr}\n` +
|
|
174
|
-
`[mega-compact] stateDir=${runtime.currentStateDir}`,
|
|
175
|
-
);
|
|
176
|
-
} catch (e) {
|
|
177
|
-
ctx.ui.notify(`[mega-compact] /mega-status error: ${String(e)}`);
|
|
178
|
-
}
|
|
179
|
-
},
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
// ---- Phase 4: cheap standout commands (data is already persisted) -------
|
|
183
|
-
|
|
184
|
-
pi.registerCommand("mega-restore", {
|
|
185
|
-
description: "Re-inject a checkpoint's verbatim original region into context. Usage: /mega-restore <chkpt|recent>",
|
|
186
|
-
handler: async (args: string, ctx: ExtensionContext) => {
|
|
187
|
-
try {
|
|
188
|
-
runtime.bindRepo(ctx.cwd);
|
|
189
|
-
const sid = normalizeSessionId(ctx.sessionManager.getSessionId());
|
|
190
|
-
const cp = findCheckpoint(runtime, sid, args.trim());
|
|
191
|
-
if (!cp) {
|
|
192
|
-
ctx.ui.notify(`[mega-compact] no checkpoint found${args.trim() ? ` for "${args.trim()}"` : ""} in this session. Try /mega-history.`);
|
|
193
|
-
return;
|
|
194
|
-
}
|
|
195
|
-
if (!cp.compressedOriginal) {
|
|
196
|
-
ctx.ui.notify(`[mega-compact] ${cp.checkpointId} has no recoverable original (pre-blob or direct add). Cannot restore verbatim.`);
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
|
-
const original = decompressSmart(cp.compressedOriginal).toString("utf-8");
|
|
200
|
-
// Re-inject verbatim via before_agent_start (PREVENT-PI-003) — never
|
|
201
|
-
// touches live messages, only prepends the restored region to systemPrompt.
|
|
202
|
-
runtime.pendingRecallBlock = `The following compacted context was RESTORED from checkpoint ${cp.checkpointId} (verbatim original region):\n\n${original}`;
|
|
203
|
-
const files = cp.filesModified?.length ? cp.filesModified.join(", ") : "(no files captured)";
|
|
204
|
-
ctx.ui.notify(
|
|
205
|
-
`[mega-compact] ♻ restored ${cp.checkpointId} — ${original.length} chars re-injected on next turn.\n` +
|
|
206
|
-
`[mega-compact] files: ${files}`,
|
|
207
|
-
);
|
|
208
|
-
runtime.dashboard.event("restore", { checkpointId: cp.checkpointId, chars: original.length });
|
|
209
|
-
} catch (e) {
|
|
210
|
-
ctx.ui.notify(`[mega-compact] /mega-restore failed (checkpoint may be corrupt): ${String(e)}`);
|
|
211
|
-
}
|
|
212
|
-
},
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
pi.registerCommand("mega-history", {
|
|
216
|
-
description: "List this session's checkpoints (id, date, files, tokens). Usage: /mega-history",
|
|
217
|
-
handler: async (_args: string, ctx: ExtensionContext) => {
|
|
218
|
-
runtime.bindRepo(ctx.cwd);
|
|
219
|
-
const sid = normalizeSessionId(ctx.sessionManager.getSessionId());
|
|
220
|
-
const all = listCheckpoints(sid, runtime.currentStateDir);
|
|
221
|
-
if (all.length === 0) {
|
|
222
|
-
ctx.ui.notify("[mega-compact] no checkpoints in this session yet.");
|
|
223
|
-
return;
|
|
224
|
-
}
|
|
225
|
-
const rows = all.map((c) => {
|
|
226
|
-
const when = c.timestamp ? new Date(c.timestamp).toISOString().slice(0, 16).replace("T", " ") : "—";
|
|
227
|
-
const files = c.filesModified?.length ? c.filesModified.map((f) => f.split("/").pop() ?? f).join(", ") : "—";
|
|
228
|
-
const orig = c.originalTokenEstimate ?? 0;
|
|
229
|
-
const stored = c.tokenEstimate ?? 0;
|
|
230
|
-
const saved = Math.max(0, orig - stored);
|
|
231
|
-
return ` ${c.checkpointId} ${when} ${C.cyan}${saved}t saved${C.reset} ${files}`;
|
|
232
|
-
});
|
|
233
|
-
ctx.ui.notify(
|
|
234
|
-
`[mega-compact] ${all.length} checkpoint(s) in this session:\n` + rows.join("\n") +
|
|
235
|
-
`\n[mega-compact] /mega-view <chkpt> to see the original region · /mega-restore <chkpt> to re-inject it`,
|
|
236
|
-
);
|
|
237
|
-
},
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
pi.registerCommand("mega-view", {
|
|
241
|
-
description: "Show a checkpoint's verbatim original region. Usage: /mega-view <chkpt|recent>",
|
|
242
|
-
handler: async (args: string, ctx: ExtensionContext) => {
|
|
243
|
-
try {
|
|
244
|
-
runtime.bindRepo(ctx.cwd);
|
|
245
|
-
const sid = normalizeSessionId(ctx.sessionManager.getSessionId());
|
|
246
|
-
const cp = findCheckpoint(runtime, sid, args.trim());
|
|
247
|
-
if (!cp) {
|
|
248
|
-
ctx.ui.notify(`[mega-compact] no checkpoint found${args.trim() ? ` for "${args.trim()}"` : ""}. Try /mega-history.`);
|
|
249
|
-
return;
|
|
250
|
-
}
|
|
251
|
-
if (!cp.compressedOriginal) {
|
|
252
|
-
ctx.ui.notify(`[mega-compact] ${cp.checkpointId} summary:\n${cp.summary.slice(0, 500)}${cp.summary.length > 500 ? "…" : ""}\n(no verbatim original stored)`);
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
255
|
-
const original = decompressSmart(cp.compressedOriginal).toString("utf-8");
|
|
256
|
-
ctx.ui.notify(
|
|
257
|
-
`[mega-compact] ${cp.checkpointId} — original region (${original.length} chars):\n` +
|
|
258
|
-
`${original.slice(0, 1500)}${original.length > 1500 ? "\n…(truncated)" : ""}`,
|
|
259
|
-
);
|
|
260
|
-
} catch (e) {
|
|
261
|
-
ctx.ui.notify(`[mega-compact] /mega-view failed (checkpoint may be corrupt): ${String(e)}`);
|
|
262
|
-
}
|
|
263
|
-
},
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
pi.registerCommand("mega-help", {
|
|
267
|
-
description: "Plain-language glossary of what mega-compact's stats mean.",
|
|
268
|
-
handler: async (_args: string, ctx: ExtensionContext) => {
|
|
269
|
-
ctx.ui.notify(
|
|
270
|
-
`[mega-compact] glossary — what the numbers mean:\n` +
|
|
271
|
-
`• token — a chunk of text (~4 chars). Context window = how much text fits in memory at once.\n` +
|
|
272
|
-
`• space freed — how much conversation we've compressed away to make room (the win).\n` +
|
|
273
|
-
`• memory held — how much compact summary we're currently keeping as your 'notes'.\n` +
|
|
274
|
-
`• saved checkpoint — a compact summary of an old conversation chunk we stored.\n` +
|
|
275
|
-
`• repeat-skipped — how often new text matched something we already had, so we didn't store a duplicate.\n` +
|
|
276
|
-
`• injected — times we pasted an old saved note back into the chat because it was relevant.\n` +
|
|
277
|
-
`• recall relevance — of those, how often the note was actually on-topic.\n` +
|
|
278
|
-
`• data safety — every compressed region is kept verbatim; nothing is permanently deleted. /mega-restore brings any of it back.`,
|
|
279
|
-
);
|
|
280
|
-
},
|
|
281
|
-
});
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* Try to peek at recent events.log and mega-compact.log for low recall quality signals.
|
|
285
|
-
* Best-effort, non-fatal — returns true if a low-quality signal was found.
|
|
286
|
-
*/
|
|
287
|
-
/**
|
|
288
|
-
* Try to peek at recent events.log and mega-compact.log for low recall quality signals.
|
|
289
|
-
* Best-effort, non-fatal — returns true if a low-quality signal was found.
|
|
290
|
-
*/
|
|
291
|
-
function checkRecallQuality(stateDir: string): boolean {
|
|
292
|
-
const eventPaths = [
|
|
293
|
-
defaultEventsPath(stateDir),
|
|
294
|
-
path.join(stateDir, "mega-compact.log"),
|
|
295
|
-
];
|
|
296
|
-
for (const fp of eventPaths) {
|
|
297
|
-
try {
|
|
298
|
-
if (!existsSync(fp)) continue;
|
|
299
|
-
const buf = readFileSync(fp, { encoding: "utf-8" });
|
|
300
|
-
// Only scan last 64 KiB of the file
|
|
301
|
-
const tail = buf.length > 65536 ? buf.slice(buf.length - 65536) : buf;
|
|
302
|
-
const lines = tail.split("\n").filter(Boolean);
|
|
303
|
-
for (const line of lines) {
|
|
304
|
-
try {
|
|
305
|
-
// guardrails-allow PREVENT-001: JSON.parse with null check
|
|
306
|
-
const parsed = JSON.parse(line);
|
|
307
|
-
if (typeof parsed !== "object" || parsed === null) continue;
|
|
308
|
-
// Check for recall_metrics_low_quality event (latest format)
|
|
309
|
-
if (parsed.event === "recall_metrics_low_quality" && parsed.score !== undefined) {
|
|
310
|
-
if (typeof parsed.score === "number" && parsed.score < 0.4) return true;
|
|
311
|
-
}
|
|
312
|
-
// Check for recall_metrics with low relevanceScore
|
|
313
|
-
if (parsed.event === "recall_metrics" && parsed.relevanceScore !== undefined) {
|
|
314
|
-
if (typeof parsed.relevanceScore === "number" && parsed.relevanceScore < 0.4) return true;
|
|
315
|
-
}
|
|
316
|
-
// Check for RecallQualityEvent format from monitoring.ts
|
|
317
|
-
if (parsed.score !== undefined && typeof parsed.score === "number" && parsed.score < 0.4) return true;
|
|
318
|
-
} catch {
|
|
319
|
-
// skip unparseable lines
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
} catch {
|
|
323
|
-
// non-fatal: skip if can't read
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
return false;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
pi.registerCommand("mega-setup", {
|
|
330
|
-
description:
|
|
331
|
-
"Local embedding setup wizard — detect available embedders and configure mega-compact.",
|
|
332
|
-
handler: async (_args: string, ctx: ExtensionContext) => {
|
|
333
|
-
try {
|
|
334
|
-
const log = (msg: string) => ctx.ui.notify(msg);
|
|
335
|
-
|
|
336
|
-
// --- 1. Current config ---
|
|
337
|
-
const embeddingUrl = process.env["MEGACOMPACT_EMBEDDING_URL"];
|
|
338
|
-
const minilm = process.env["MEGACOMPACT_MINILM"];
|
|
339
|
-
|
|
340
|
-
let currentEmbedder = "TrigramEmbedder (heuristic, default)";
|
|
341
|
-
if (embeddingUrl) currentEmbedder = `httpEmbedder → ${embeddingUrl}`;
|
|
342
|
-
else if (minilm) currentEmbedder = "MiniLM (experimental)";
|
|
343
|
-
|
|
344
|
-
// --- 2. Detection ---
|
|
345
|
-
let ollamaDetected = false;
|
|
346
|
-
let ollamaModels: string[] = [];
|
|
347
|
-
let ollamaRunning = false;
|
|
348
|
-
let llamaDetected = false;
|
|
349
|
-
let onnxDetected = false;
|
|
350
|
-
|
|
351
|
-
try {
|
|
352
|
-
const ollamaVer = spawnSync("ollama", ["--version"], {
|
|
353
|
-
timeout: 5000,
|
|
354
|
-
encoding: "utf-8",
|
|
355
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
356
|
-
}); // guardrails-allow PREVENT-PI-004: local subprocess detection only
|
|
357
|
-
if (ollamaVer.status === 0) {
|
|
358
|
-
ollamaDetected = true;
|
|
359
|
-
try {
|
|
360
|
-
const listResult = spawnSync("ollama", ["list"], {
|
|
361
|
-
timeout: 5000,
|
|
362
|
-
encoding: "utf-8",
|
|
363
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
364
|
-
}); // guardrails-allow PREVENT-PI-004: local subprocess detection only
|
|
365
|
-
if (listResult.status === 0) {
|
|
366
|
-
ollamaRunning = true;
|
|
367
|
-
const lines = listResult.stdout?.split("\n") ?? [];
|
|
368
|
-
for (const line of lines) {
|
|
369
|
-
const name = line.split(/\s+/)[0];
|
|
370
|
-
if (name && name !== "NAME") ollamaModels.push(name);
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
} catch {
|
|
374
|
-
// ollama list fails if server not running — that's fine
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
} catch {
|
|
378
|
-
// ollama not found
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
try {
|
|
382
|
-
const whichLlama = spawnSync("which", ["llama-server"], {
|
|
383
|
-
timeout: 3000,
|
|
384
|
-
encoding: "utf-8",
|
|
385
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
386
|
-
}); // guardrails-allow PREVENT-PI-004: local subprocess detection only
|
|
387
|
-
llamaDetected = whichLlama.status === 0;
|
|
388
|
-
} catch {
|
|
389
|
-
// not found
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
try {
|
|
393
|
-
const req = createRequire(import.meta.url);
|
|
394
|
-
try {
|
|
395
|
-
req.resolve("onnxruntime-node");
|
|
396
|
-
onnxDetected = true;
|
|
397
|
-
} catch {
|
|
398
|
-
// not in node_modules
|
|
399
|
-
}
|
|
400
|
-
} catch {
|
|
401
|
-
// require error
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
// --- 2.5 Quality check ---
|
|
405
|
-
// Scan recent events for low recall quality (best-effort, non-fatal)
|
|
406
|
-
const stateDir = process.env["MEGACOMPACT_STATE_DIR"] ?? path.join(os.homedir(), ".pi", "mega-compact");
|
|
407
|
-
const lowRecallQuality = checkRecallQuality(stateDir);
|
|
408
|
-
|
|
409
|
-
// --- 3. Build choices ---
|
|
410
|
-
interface Choice {
|
|
411
|
-
label: string;
|
|
412
|
-
value: string;
|
|
413
|
-
}
|
|
414
|
-
const choices: Choice[] = [];
|
|
415
|
-
|
|
416
|
-
if (ollamaDetected && ollamaRunning) {
|
|
417
|
-
const model = ollamaModels.find(
|
|
418
|
-
(m) =>
|
|
419
|
-
m.includes("nomic-embed") ||
|
|
420
|
-
m.includes("embed") ||
|
|
421
|
-
m.includes("mxbai"),
|
|
422
|
-
);
|
|
423
|
-
const suggestedModel = model ?? "nomic-embed-text";
|
|
424
|
-
choices.push({
|
|
425
|
-
label: `Use Ollama (${suggestedModel}) at localhost:11434`,
|
|
426
|
-
value: `ollama:${suggestedModel}`,
|
|
427
|
-
});
|
|
428
|
-
} else if (ollamaDetected && !ollamaRunning) {
|
|
429
|
-
choices.push({
|
|
430
|
-
label: "Ollama detected but server is not running — start it first",
|
|
431
|
-
value: "ollama:offline",
|
|
432
|
-
});
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
if (llamaDetected) {
|
|
436
|
-
choices.push({
|
|
437
|
-
label: "Use llama.cpp server at localhost:8080",
|
|
438
|
-
value: "llama:default",
|
|
439
|
-
});
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
if (onnxDetected) {
|
|
443
|
-
choices.push({
|
|
444
|
-
label: "Use ONNX Runtime (experimental, requires config)",
|
|
445
|
-
value: "onnx:default",
|
|
446
|
-
});
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
choices.push({
|
|
450
|
-
label: "Keep TrigramEmbedder (default, no setup)",
|
|
451
|
-
value: "trigram",
|
|
452
|
-
});
|
|
453
|
-
|
|
454
|
-
// --- 4. Prompt user ---
|
|
455
|
-
log(`Current embedder: ${currentEmbedder}`);
|
|
456
|
-
if (lowRecallQuality) {
|
|
457
|
-
log(
|
|
458
|
-
"Tap: recent recall quality is low. Consider switching to Ollama or llama.cpp for better results.",
|
|
459
|
-
);
|
|
460
|
-
}
|
|
461
|
-
let selected = "trigram";
|
|
462
|
-
if (choices.length > 1) {
|
|
463
|
-
try {
|
|
464
|
-
const labels = choices.map((c) => c.label);
|
|
465
|
-
const picked = await ctx.ui.select("Select an embedder to configure:", labels);
|
|
466
|
-
if (picked === undefined) {
|
|
467
|
-
log("Setup cancelled by user.");
|
|
468
|
-
return;
|
|
469
|
-
}
|
|
470
|
-
const match = choices.find((c) => c.label === picked);
|
|
471
|
-
selected = match?.value ?? "trigram";
|
|
472
|
-
} catch {
|
|
473
|
-
log("Setup cancelled by user.");
|
|
474
|
-
return;
|
|
475
|
-
}
|
|
476
|
-
} else {
|
|
477
|
-
log("No local embedders detected. Keeping TrigramEmbedder default.");
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
// --- 5. Apply selection ---
|
|
481
|
-
if (selected.startsWith("ollama:")) {
|
|
482
|
-
const model = selected.split(":")[1];
|
|
483
|
-
const url = `http://localhost:11434/api/embeddings`; // guardrails-allow PREVENT-PI-004: localhost-only config string, not a runtime fetch
|
|
484
|
-
const lines = [
|
|
485
|
-
`# Mega-Compact Embedder Configuration — Ollama`,
|
|
486
|
-
`# Generated by /megasetup at ${new Date().toISOString()}`,
|
|
487
|
-
`export MEGACOMPACT_EMBEDDING_URL="${url}"`,
|
|
488
|
-
`# Optional: uncomment to set cache size (default 1000)`,
|
|
489
|
-
`# export MEGACOMPACT_EMBED_CACHE=1000`,
|
|
490
|
-
];
|
|
491
|
-
const envContent = lines.join("\n") + "\n";
|
|
492
|
-
|
|
493
|
-
// Write .mega-compact.env to state dir
|
|
494
|
-
try {
|
|
495
|
-
mkdirSync(stateDir, { recursive: true });
|
|
496
|
-
writeFileSync(path.join(stateDir, ".mega-compact.env"), envContent, "utf-8");
|
|
497
|
-
} catch {
|
|
498
|
-
// non-fatal
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
log(
|
|
502
|
-
`Configured for Ollama (${model}).\n\nAdd to your shell profile (~/.bashrc, ~/.zshrc, or ~/.config/fish/config.fish):\n\n source "${path.join(
|
|
503
|
-
stateDir,
|
|
504
|
-
".mega-compact.env",
|
|
505
|
-
)}"\n\nOr export manually:\n\n export MEGACOMPACT_EMBEDDING_URL="${url}"\n\nThen restart pi to activate the http embedder.`,
|
|
506
|
-
);
|
|
507
|
-
} else if (selected.startsWith("llama:")) {
|
|
508
|
-
const url = "http://localhost:8080/v1/embeddings"; // guardrails-allow PREVENT-PI-004: localhost-only config string, not a runtime fetch
|
|
509
|
-
const lines = [
|
|
510
|
-
`# Mega-Compact Embedder Configuration — llama.cpp`,
|
|
511
|
-
`# Generated by /megasetup at ${new Date().toISOString()}`,
|
|
512
|
-
`export MEGACOMPACT_EMBEDDING_URL="${url}"`,
|
|
513
|
-
];
|
|
514
|
-
const envContent = lines.join("\n") + "\n";
|
|
515
|
-
try {
|
|
516
|
-
mkdirSync(stateDir, { recursive: true });
|
|
517
|
-
writeFileSync(path.join(stateDir, ".mega-compact.env"), envContent, "utf-8");
|
|
518
|
-
} catch {
|
|
519
|
-
// non-fatal
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
log(
|
|
523
|
-
`Configured for llama.cpp server.\n\nAdd to your shell profile:\n\n source "${path.join(
|
|
524
|
-
stateDir,
|
|
525
|
-
".mega-compact.env",
|
|
526
|
-
)}"\n\nOr export manually:\n\n export MEGACOMPACT_EMBEDDING_URL="${url}"\n\nThen restart pi to activate the http embedder.`,
|
|
527
|
-
);
|
|
528
|
-
} else if (selected.startsWith("onnx:")) {
|
|
529
|
-
log(
|
|
530
|
-
"ONNX Runtime configuration is experimental.\n\nSet MEGACOMPACT_EMBEDDING_URL to your local ONNX server URL, or see docs for manual setup.\nKeeping TrigramEmbedder for now.",
|
|
531
|
-
);
|
|
532
|
-
} else {
|
|
533
|
-
const qualityTip =
|
|
534
|
-
lowRecallQuality
|
|
535
|
-
? " Recent recall quality is low — consider running /mega-setup again to switch to Ollama or llama.cpp for better results."
|
|
536
|
-
: "";
|
|
537
|
-
log(`Keeping TrigramEmbedder (default). No configuration needed.${qualityTip}`);
|
|
538
|
-
}
|
|
539
|
-
} catch (e) {
|
|
540
|
-
ctx.ui.notify(`[mega-compact] /mega-setup failed: ${String(e)}`);
|
|
541
|
-
}
|
|
542
|
-
},
|
|
543
|
-
});
|
|
544
|
-
|
|
545
|
-
// NOTE: /mega-tier was removed in S24. The tier the user sees is now the LIVE
|
|
546
|
-
// pressure band (low/medium/high/ultra/mega), which climbs automatically as
|
|
547
|
-
// context fills — there is no manual tier to set. See docs/specs/s24-unified-pressure.md.
|
|
23
|
+
export function registerCommands(
|
|
24
|
+
pi: ExtensionAPI,
|
|
25
|
+
runtime: MegaRuntime,
|
|
26
|
+
config: MegaConfig,
|
|
27
|
+
): void {
|
|
28
|
+
registerDataCommands(pi, runtime, config);
|
|
29
|
+
registerHistoryCommands(pi, runtime);
|
|
30
|
+
registerSetupCommand(pi);
|
|
31
|
+
|
|
32
|
+
// NOTE: /mega-tier was removed in S24. The tier the user sees is now the LIVE
|
|
33
|
+
// pressure band (low/medium/high/ultra/mega), which climbs automatically as
|
|
34
|
+
// context fills — there is no manual tier to set. See docs/specs/s24-unified-pressure.md.
|
|
548
35
|
}
|