pi-mega-compact 0.11.4 → 0.11.5
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/endpoints.js +19 -0
- package/dist/extensions/dashboard-server/api-contracts/memory.js +8 -0
- package/dist/extensions/dashboard-server/api-contracts/provider-cache.js +1 -0
- package/dist/extensions/dashboard-server/api-contracts/setup.js +10 -0
- package/dist/extensions/dashboard-server/index-reader.js +6 -2
- package/dist/extensions/dashboard-server/routes-cache.js +115 -55
- package/dist/extensions/dashboard-server/routes-memory.js +51 -0
- package/dist/extensions/dashboard-server/routes-repo.js +2 -2
- package/dist/extensions/dashboard-server/routes-setup.js +162 -0
- package/dist/extensions/dashboard-server/routes.js +2 -0
- package/dist/extensions/dashboard-server/server.js +7 -1
- package/dist/extensions/mega-commands.js +189 -1
- package/dist/extensions/mega-config.js +2 -0
- package/dist/extensions/mega-events/agent-handlers.js +19 -4
- package/dist/extensions/mega-events/compact-handlers.js +1 -0
- package/dist/extensions/mega-events/context-handler.js +37 -92
- package/dist/extensions/mega-events/context-hwm.js +51 -0
- package/dist/extensions/mega-events/error-classifier.js +16 -5
- package/dist/extensions/mega-events/mirror-append.js +107 -0
- package/dist/extensions/mega-events/outage-advisor.js +7 -1
- package/dist/extensions/mega-events/perf-handler.js +51 -1
- package/dist/extensions/mega-events/recall-tail.js +59 -0
- package/dist/extensions/mega-events/session-handlers.js +15 -8
- package/dist/extensions/mega-runtime/reset-runtime.js +5 -0
- package/dist/extensions/mega-runtime/runtime.js +6 -0
- package/dist/src/embedder.js +41 -2
- package/dist/src/memoryStats.js +75 -0
- package/dist/src/prefix-break.js +43 -0
- package/dist/src/pricing.js +1 -1
- package/dist/src/store/sqlite/perf-samples.js +144 -16
- package/dist/src/store/turns/memory-store.js +8 -0
- package/dist/src/store/turns/sqlite-store.js +14 -3
- package/dist/src/store/turns/types.js +18 -1
- package/dist/src/store/vectorIndex.js +26 -5
- package/extensions/dashboard-client/dist/assets/{AchievementTiles-vEo2MtE2.js → AchievementTiles-BoL7qBOJ.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{AchievementTiles-vEo2MtE2.js.map → AchievementTiles-BoL7qBOJ.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/AchievementsTab-BFDE3HYc.js +2 -0
- package/extensions/dashboard-client/dist/assets/{AchievementsTab-DjxfYrDc.js.map → AchievementsTab-BFDE3HYc.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/CacheTab-eKVc-NV1.js +2 -0
- package/extensions/dashboard-client/dist/assets/CacheTab-eKVc-NV1.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/{ConfigTab-Cm6ymbmx.js → ConfigTab-DDFE-ckA.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{ConfigTab-Cm6ymbmx.js.map → ConfigTab-DDFE-ckA.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{EventsTab-DXWl_YzI.js → EventsTab-B6UxZ7PM.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{EventsTab-DXWl_YzI.js.map → EventsTab-B6UxZ7PM.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{GameTab-BLDudcO5.js → GameTab-DehUX-KE.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{GameTab-BLDudcO5.js.map → GameTab-DehUX-KE.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MaintenanceTab-DLkKCztn.js → MaintenanceTab-0GWRt4wn.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MaintenanceTab-DLkKCztn.js.map → MaintenanceTab-0GWRt4wn.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MetricsTab-Cq4u-rZF.js → MetricsTab-C3rwMVsN.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MetricsTab-Cq4u-rZF.js.map → MetricsTab-C3rwMVsN.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/OverviewTab-39O9_x5j.js +2 -0
- package/extensions/dashboard-client/dist/assets/{OverviewTab-D4kGvsiQ.js.map → OverviewTab-39O9_x5j.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/ReposTab-Cfj6Q5sH.js +2 -0
- package/extensions/dashboard-client/dist/assets/ReposTab-Cfj6Q5sH.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/{SessionsTab-DZC2-GCn.js → SessionsTab-DXDTCi3r.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{SessionsTab-DZC2-GCn.js.map → SessionsTab-DXDTCi3r.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/SetupTab-mMlfunJa.js +2 -0
- package/extensions/dashboard-client/dist/assets/SetupTab-mMlfunJa.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/TimeSavedCard-Cw1dJ4e9.js +2 -0
- package/extensions/dashboard-client/dist/assets/TimeSavedCard-Cw1dJ4e9.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/{TopicsTab-01G71hv1.js → TopicsTab-BAw972BV.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{TopicsTab-01G71hv1.js.map → TopicsTab-BAw972BV.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{TurnsTab-DLRg0LZT.js → TurnsTab-Cf5mGIdl.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{TurnsTab-DLRg0LZT.js.map → TurnsTab-Cf5mGIdl.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/format-COjDIVGj.js +2 -0
- package/extensions/dashboard-client/dist/assets/format-COjDIVGj.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/{index-BX0bcgLu.js → index-4gQ7auad.js} +10 -10
- package/extensions/dashboard-client/dist/assets/index-4gQ7auad.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/pricing-CvE4NllQ.js +2 -0
- package/extensions/dashboard-client/dist/assets/pricing-CvE4NllQ.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/{useSSE-BBYt5UPB.js → useSSE-DNgMuyP6.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{useSSE-BBYt5UPB.js.map → useSSE-DNgMuyP6.js.map} +1 -1
- package/extensions/dashboard-client/dist/index.html +1 -1
- package/extensions/dashboard-client/src/App.tsx +4 -0
- package/extensions/dashboard-client/src/api/client.ts +14 -0
- package/extensions/dashboard-client/src/components/ActiveReposTable.tsx +21 -12
- package/extensions/dashboard-client/src/components/ProviderCacheCard.tsx +56 -0
- package/extensions/dashboard-client/src/components/SavingsByModelTable.tsx +38 -57
- package/extensions/dashboard-client/src/tabs/CacheTab.tsx +1 -0
- package/extensions/dashboard-client/src/tabs/SetupTab.tsx +355 -0
- package/extensions/dashboard-client/tsconfig.json +3 -2
- package/extensions/dashboard-client/vite.config.ts +2 -0
- package/extensions/dashboard-server/api-contracts/endpoints.ts +36 -3
- package/extensions/dashboard-server/api-contracts/index.ts +7 -0
- package/extensions/dashboard-server/api-contracts/memory.ts +27 -0
- package/extensions/dashboard-server/api-contracts/multi-repo.ts +231 -231
- package/extensions/dashboard-server/api-contracts/provider-cache.ts +37 -0
- package/extensions/dashboard-server/api-contracts/setup.ts +58 -0
- package/extensions/dashboard-server/index-reader.ts +138 -121
- package/extensions/dashboard-server/routes-cache.ts +161 -85
- package/extensions/dashboard-server/routes-memory.ts +63 -0
- package/extensions/dashboard-server/routes-repo.ts +36 -36
- package/extensions/dashboard-server/routes-setup.ts +181 -0
- package/extensions/dashboard-server/routes.ts +2 -0
- package/extensions/dashboard-server/server.ts +6 -0
- package/extensions/mega-commands.ts +211 -1
- package/extensions/mega-config.ts +10 -0
- package/extensions/mega-events/agent-handlers.ts +20 -4
- package/extensions/mega-events/compact-handlers.ts +1 -0
- package/extensions/mega-events/context-handler.ts +45 -110
- package/extensions/mega-events/context-hwm.ts +85 -0
- package/extensions/mega-events/error-classifier.ts +15 -4
- package/extensions/mega-events/mirror-append.ts +155 -0
- package/extensions/mega-events/outage-advisor.ts +11 -5
- package/extensions/mega-events/perf-handler.ts +79 -5
- package/extensions/mega-events/recall-tail.ts +88 -0
- package/extensions/mega-events/session-handlers.ts +14 -7
- package/extensions/mega-runtime/helpers.ts +12 -0
- package/extensions/mega-runtime/reset-runtime.ts +5 -0
- package/extensions/mega-runtime/runtime.ts +6 -0
- package/package.json +5 -2
- package/src/embedder.ts +42 -2
- package/src/memoryStats.ts +107 -0
- package/src/prefix-break.ts +83 -0
- package/src/pricing.ts +2 -2
- package/src/store/sqlite/perf-samples.ts +215 -22
- package/src/store/turns/memory-store.ts +10 -1
- package/src/store/turns/sqlite-store.ts +27 -15
- package/src/store/turns/types.ts +21 -0
- package/src/store/vectorIndex.ts +33 -4
- package/dist/extensions/conflict-scan.test.js +0 -115
- package/dist/extensions/dashboard-server/api-contracts.test.js +0 -884
- package/dist/extensions/dashboard-server/html.test.js +0 -52
- package/dist/extensions/dashboard-server/perf-server.test.js +0 -80
- package/dist/extensions/dashboard-server/routes-cache.test.js +0 -248
- package/dist/extensions/dashboard-server/server.test.js +0 -120
- package/dist/extensions/dashboard-server-s32.test.js +0 -181
- package/dist/extensions/dashboard-server.test.js +0 -339
- package/dist/extensions/mega-cache-replay.test.js +0 -400
- package/dist/extensions/mega-compact-s38.test.js +0 -1383
- package/dist/extensions/mega-compact.test.js +0 -1112
- package/dist/extensions/mega-events.test.js +0 -47
- package/dist/extensions/mega-game-cmds.test.js +0 -163
- package/dist/extensions/mega-runtime/snapshot.test.js +0 -127
- package/dist/extensions/mega-runtime/state.test.js +0 -266
- package/dist/extensions/mega-runtime/widget.test.js +0 -343
- package/dist/extensions/mega-shutdown-widget.test.js +0 -121
- package/dist/extensions/mega-teamrun.test.js +0 -156
- package/dist/extensions/mega-trim.test.js +0 -58
- package/dist/extensions/mega-turn-store.test.js +0 -68
- package/dist/src/boundary.test.js +0 -170
- package/dist/src/compact.test.js +0 -78
- package/dist/src/config/themes.test.js +0 -94
- package/dist/src/dedup/dedup.test.js +0 -41
- package/dist/src/dedup/l1.test.js +0 -50
- package/dist/src/dedup/raptor/buildHistory.test.js +0 -292
- package/dist/src/dedup/raptor/multilevel-serve.test.js +0 -229
- package/dist/src/dedup/raptor/multilevel.test.js +0 -238
- package/dist/src/dedup/raptor/promote.test.js +0 -69
- package/dist/src/dedup/raptor/raptor.test.js +0 -248
- package/dist/src/dedup/raptor/retrieval.test.js +0 -95
- package/dist/src/dedup/raptor/serve-gate.test.js +0 -298
- package/dist/src/dedup/sprint12.test.js +0 -219
- package/dist/src/dedup-engine.test.js +0 -472
- package/dist/src/driftDetection.test.js +0 -87
- package/dist/src/e2e.test.js +0 -698
- package/dist/src/engine.test.js +0 -111
- package/dist/src/extractive.test.js +0 -147
- package/dist/src/fork.test.js +0 -81
- package/dist/src/game/scoring.test.js +0 -98
- package/dist/src/httpEmbedder.test.js +0 -277
- package/dist/src/importance.test.js +0 -372
- package/dist/src/intent.test.js +0 -78
- package/dist/src/log.test.js +0 -42
- package/dist/src/mechanical-fix.test.js +0 -65
- package/dist/src/memory.test.js +0 -70
- package/dist/src/memoryConsolidate.test.js +0 -38
- package/dist/src/memoryOps.test.js +0 -129
- package/dist/src/memoryRecall.test.js +0 -171
- package/dist/src/memoryRoundtrip.test.js +0 -137
- package/dist/src/metrics/turns.test.js +0 -152
- package/dist/src/mirror/mirror.test.js +0 -185
- package/dist/src/raptor-inject-summaries.test.js +0 -162
- package/dist/src/ratio.bench.test.js +0 -897
- package/dist/src/recall.integration.test.js +0 -77
- package/dist/src/recall.test.js +0 -379
- package/dist/src/sprint14.test.js +0 -219
- package/dist/src/sprint4x-rag-verification.test.js +0 -93
- package/dist/src/store/compression.test.js +0 -139
- package/dist/src/store/memoryIndex.test.js +0 -51
- package/dist/src/store/migrate.test.js +0 -139
- package/dist/src/store/pgOpenGuard.test.js +0 -74
- package/dist/src/store/phase01.test.js +0 -81
- package/dist/src/store/phase04.test.js +0 -54
- package/dist/src/store/sprint10.test.js +0 -186
- package/dist/src/store/sqlite/game-achievements.test.js +0 -67
- package/dist/src/store/sqlite/game-scores.test.js +0 -106
- package/dist/src/store/sqlite/game-state.test.js +0 -76
- package/dist/src/store/sqlite/global-index.test.js +0 -136
- package/dist/src/store/sqlite/mechanical-fix.test.js +0 -146
- package/dist/src/store/sqlite/perf-samples.test.js +0 -146
- package/dist/src/store/sqlite/raptor.test.js +0 -106
- package/dist/src/store/sqlite/turns.test.js +0 -183
- package/dist/src/store/sqlite.cachehit.test.js +0 -55
- package/dist/src/store/sqlite.dbmaint.test.js +0 -158
- package/dist/src/store/sqlite.dbmirror.test.js +0 -184
- package/dist/src/store/turns/contract-compliance.test.js +0 -428
- package/dist/src/store/turns/memory-store.test.js +0 -9
- package/dist/src/store/turns/migrations.test.js +0 -138
- package/dist/src/store/turns/sqlite-store.test.js +0 -144
- package/dist/src/store/vectorIndex.test.js +0 -123
- package/dist/src/store.test.js +0 -161
- package/dist/src/supersede.test.js +0 -36
- package/dist/src/topics/cluster.test.js +0 -150
- package/dist/src/topics/store.test.js +0 -117
- package/dist/src/types.test.js +0 -9
- package/dist/src/vector-search-cache.test.js +0 -157
- package/dist/src/vectorStore.test.js +0 -479
- package/dist/src/wiki.test.js +0 -171
- package/extensions/conflict-scan.test.ts +0 -129
- package/extensions/dashboard-client/dist/assets/AchievementsTab-DjxfYrDc.js +0 -2
- package/extensions/dashboard-client/dist/assets/CacheTab-Dnpv94wq.js +0 -2
- package/extensions/dashboard-client/dist/assets/CacheTab-Dnpv94wq.js.map +0 -1
- package/extensions/dashboard-client/dist/assets/OverviewTab-D4kGvsiQ.js +0 -2
- package/extensions/dashboard-client/dist/assets/ReposTab-C0Wnrf2u.js +0 -2
- package/extensions/dashboard-client/dist/assets/ReposTab-C0Wnrf2u.js.map +0 -1
- package/extensions/dashboard-client/dist/assets/TimeSavedCard-UqljSyP-.js +0 -2
- package/extensions/dashboard-client/dist/assets/TimeSavedCard-UqljSyP-.js.map +0 -1
- package/extensions/dashboard-client/dist/assets/index-BX0bcgLu.js.map +0 -1
- package/extensions/dashboard-server/api-contracts.test.ts +0 -1065
- package/extensions/dashboard-server/html.test.ts +0 -62
- package/extensions/dashboard-server/perf-server.test.ts +0 -101
- package/extensions/dashboard-server/routes-cache.test.ts +0 -302
- package/extensions/dashboard-server/server.test.ts +0 -131
- package/extensions/dashboard-server-s32.test.ts +0 -195
- package/extensions/dashboard-server.test.ts +0 -382
- package/extensions/mega-cache-replay.test.ts +0 -526
- package/extensions/mega-compact-s38.test.ts +0 -1433
- package/extensions/mega-compact.test.ts +0 -1509
- package/extensions/mega-events.test.ts +0 -55
- package/extensions/mega-game-cmds.test.ts +0 -197
- package/extensions/mega-runtime/snapshot.test.ts +0 -139
- package/extensions/mega-runtime/state.test.ts +0 -262
- package/extensions/mega-runtime/widget.test.ts +0 -468
- package/extensions/mega-shutdown-widget.test.ts +0 -141
- package/extensions/mega-teamrun.test.ts +0 -176
- package/extensions/mega-trim.test.ts +0 -64
- package/extensions/mega-turn-store.test.ts +0 -108
- package/src/boundary.test.ts +0 -187
- package/src/compact.test.ts +0 -99
- package/src/config/themes.test.ts +0 -116
- package/src/dedup/dedup.test.ts +0 -46
- package/src/dedup/l1.test.ts +0 -57
- package/src/dedup/raptor/buildHistory.test.ts +0 -353
- package/src/dedup/raptor/multilevel-serve.test.ts +0 -273
- package/src/dedup/raptor/multilevel.test.ts +0 -325
- package/src/dedup/raptor/promote.test.ts +0 -82
- package/src/dedup/raptor/raptor.test.ts +0 -297
- package/src/dedup/raptor/retrieval.test.ts +0 -118
- package/src/dedup/raptor/serve-gate.test.ts +0 -348
- package/src/dedup/sprint12.test.ts +0 -242
- package/src/dedup-engine.test.ts +0 -670
- package/src/driftDetection.test.ts +0 -100
- package/src/e2e.test.ts +0 -843
- package/src/engine.test.ts +0 -123
- package/src/extractive.test.ts +0 -174
- package/src/fork.test.ts +0 -94
- package/src/game/scoring.test.ts +0 -103
- package/src/httpEmbedder.test.ts +0 -286
- package/src/importance.test.ts +0 -538
- package/src/intent.test.ts +0 -87
- package/src/log.test.ts +0 -47
- package/src/mechanical-fix.test.ts +0 -70
- package/src/memory.test.ts +0 -92
- package/src/memoryConsolidate.test.ts +0 -47
- package/src/memoryOps.test.ts +0 -148
- package/src/memoryRecall.test.ts +0 -194
- package/src/memoryRoundtrip.test.ts +0 -155
- package/src/metrics/turns.test.ts +0 -165
- package/src/mirror/mirror.test.ts +0 -240
- package/src/raptor-inject-summaries.test.ts +0 -228
- package/src/ratio.bench.test.ts +0 -1316
- package/src/recall.integration.test.ts +0 -96
- package/src/recall.test.ts +0 -467
- package/src/sprint14.test.ts +0 -245
- package/src/sprint4x-rag-verification.test.ts +0 -119
- package/src/store/compression.test.ts +0 -168
- package/src/store/memoryIndex.test.ts +0 -61
- package/src/store/migrate.test.ts +0 -158
- package/src/store/pgOpenGuard.test.ts +0 -89
- package/src/store/phase01.test.ts +0 -88
- package/src/store/phase04.test.ts +0 -58
- package/src/store/sprint10.test.ts +0 -214
- package/src/store/sqlite/game-achievements.test.ts +0 -80
- package/src/store/sqlite/game-scores.test.ts +0 -132
- package/src/store/sqlite/game-state.test.ts +0 -89
- package/src/store/sqlite/global-index.test.ts +0 -222
- package/src/store/sqlite/mechanical-fix.test.ts +0 -162
- package/src/store/sqlite/perf-samples.test.ts +0 -169
- package/src/store/sqlite/raptor.test.ts +0 -139
- package/src/store/sqlite/turns.test.ts +0 -218
- package/src/store/sqlite.cachehit.test.ts +0 -68
- package/src/store/sqlite.dbmaint.test.ts +0 -193
- package/src/store/sqlite.dbmirror.test.ts +0 -229
- package/src/store/turns/contract-compliance.test.ts +0 -562
- package/src/store/turns/memory-store.test.ts +0 -15
- package/src/store/turns/migrations.test.ts +0 -161
- package/src/store/turns/sqlite-store.test.ts +0 -161
- package/src/store/vectorIndex.test.ts +0 -140
- package/src/store.test.ts +0 -191
- package/src/supersede.test.ts +0 -42
- package/src/topics/cluster.test.ts +0 -176
- package/src/topics/store.test.ts +0 -132
- package/src/types.test.ts +0 -10
- package/src/vector-search-cache.test.ts +0 -190
- package/src/vectorStore.test.ts +0 -533
- package/src/wiki.test.ts +0 -217
|
@@ -13,7 +13,10 @@ import { ACTIVE_WINDOW_SEC } from "./types.js";
|
|
|
13
13
|
import type { RouteContext } from "./routes-core.js";
|
|
14
14
|
import type { LiveSnapshot } from "./types.js";
|
|
15
15
|
import { readProviderCacheForRepo } from "../../src/store/sqlite/perf-samples.js";
|
|
16
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
computeCacheSavings,
|
|
18
|
+
lookupModelInputRate,
|
|
19
|
+
} from "../../src/pricing.js";
|
|
17
20
|
import { latestModelSnapshot } from "../../src/store/sqlite/model-snapshots.js";
|
|
18
21
|
|
|
19
22
|
// ---------------------------------------------------------------------------
|
|
@@ -154,43 +157,42 @@ export function handleRepoIndex(
|
|
|
154
157
|
try {
|
|
155
158
|
const p = join(r.stateDir, "dashboard.json");
|
|
156
159
|
if (existsSync(p)) {
|
|
157
|
-
const snap = JSON.parse(
|
|
158
|
-
readFileSync(p, "utf-8"),
|
|
159
|
-
) as LiveSnapshot;
|
|
160
|
+
const snap = JSON.parse(readFileSync(p, "utf-8")) as LiveSnapshot;
|
|
160
161
|
out.tier = snap.tier ?? null;
|
|
161
162
|
out.contextPct =
|
|
162
163
|
snap.context && snap.context.percent != null
|
|
163
164
|
? snap.context.percent
|
|
164
165
|
: null;
|
|
165
166
|
out.state = (snap.session && snap.session.state) || null;
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
167
|
+
out.cacheHits = snap.cacheHits ?? null;
|
|
168
|
+
out.compacts = snap.compacts ?? null;
|
|
169
|
+
out.timeSaved = snap.timeSaved ?? null;
|
|
170
|
+
out.updatedAt = snap.updatedAt ?? null;
|
|
171
|
+
// Provider cache per-repo lifetime (E.2)
|
|
172
|
+
try {
|
|
173
|
+
const pc = readProviderCacheForRepo(r.stateDir);
|
|
174
|
+
// Price from model snapshot if available
|
|
175
|
+
const modelSnap = latestModelSnapshot(r.stateDir);
|
|
176
|
+
const inputRate = modelSnap
|
|
177
|
+
? modelSnap.inputRate
|
|
178
|
+
: (lookupModelInputRate(r.modelName ?? "") ?? 0);
|
|
179
|
+
const savings = computeCacheSavings(
|
|
180
|
+
pc.totalCacheRead,
|
|
181
|
+
pc.totalCacheWrite,
|
|
182
|
+
inputRate,
|
|
183
|
+
);
|
|
184
|
+
out.providerCache = {
|
|
185
|
+
avgHitPct: pc.avgHitPct,
|
|
186
|
+
cacheRead: pc.totalCacheRead,
|
|
187
|
+
cacheWrite: pc.totalCacheWrite,
|
|
188
|
+
totalInput: pc.totalInput,
|
|
189
|
+
sampleCount: pc.sampleCount,
|
|
190
|
+
estimatedSaved:
|
|
191
|
+
savings.netSaved > 0 ? savings.netSaved : null,
|
|
192
|
+
};
|
|
193
|
+
} catch {
|
|
194
|
+
/* best-effort — repo may not have perf_samples */
|
|
195
|
+
}
|
|
194
196
|
}
|
|
195
197
|
} catch {
|
|
196
198
|
/* best-effort */
|
|
@@ -199,9 +201,7 @@ export function handleRepoIndex(
|
|
|
199
201
|
})
|
|
200
202
|
.sort((a, b) => (b.lastSeen as number) - (a.lastSeen as number));
|
|
201
203
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
202
|
-
res.end(
|
|
203
|
-
JSON.stringify({ updatedAt: new Date().toISOString(), servers }),
|
|
204
|
-
);
|
|
204
|
+
res.end(JSON.stringify({ updatedAt: new Date().toISOString(), servers }));
|
|
205
205
|
} catch {
|
|
206
206
|
res.writeHead(500, { "Content-Type": "application/json" });
|
|
207
207
|
res.end(JSON.stringify({ error: "servers_unavailable" }));
|
|
@@ -236,4 +236,4 @@ export function handleStatic(
|
|
|
236
236
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
237
237
|
res.end(dashboardHtml(tier));
|
|
238
238
|
return true;
|
|
239
|
-
}
|
|
239
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dashboard-server/routes-setup.ts — Setup wizard route handlers.
|
|
3
|
+
*
|
|
4
|
+
* GET /api/setup-status — Returns current embedder configuration from env.
|
|
5
|
+
* GET /api/setup-detect — Runs best-effort detection of local embedder backends.
|
|
6
|
+
*
|
|
7
|
+
* Guardrails: PREVENT-PI-004 (loopback-only), PREVENT-001 (null-safe JSON).
|
|
8
|
+
* The detection commands run local subprocesses via spawnSync, NOT network calls.
|
|
9
|
+
* Each decoration line carries a guardrails-allow annotation.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { spawnSync } from "node:child_process"; // guardrails-allow PREVENT-PI-004: local subprocess detection only
|
|
13
|
+
import { createRequire } from "node:module";
|
|
14
|
+
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
15
|
+
import type { RouteContext } from "./routes-core.js";
|
|
16
|
+
import type {
|
|
17
|
+
SetupStatusResponse,
|
|
18
|
+
SetupDetectResponse,
|
|
19
|
+
DetectResult,
|
|
20
|
+
OllamaDetectResult,
|
|
21
|
+
} from "./api-contracts/setup.js";
|
|
22
|
+
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
// handleSetupStatus — "/api/setup-status"
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
|
|
27
|
+
function detectCurrentEmbedder(): SetupStatusResponse["currentEmbedder"] {
|
|
28
|
+
const url = process.env["MEGACOMPACT_EMBEDDING_URL"];
|
|
29
|
+
const minilm = process.env["MEGACOMPACT_MINILM"];
|
|
30
|
+
if (url && url.trim().length > 0) return "http";
|
|
31
|
+
if (minilm && ["1", "true", "yes"].includes(minilm.trim().toLowerCase()))
|
|
32
|
+
return "minilm";
|
|
33
|
+
return "trigram";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function handleSetupStatus(
|
|
37
|
+
req: IncomingMessage,
|
|
38
|
+
res: ServerResponse,
|
|
39
|
+
_ctx: RouteContext,
|
|
40
|
+
): boolean {
|
|
41
|
+
if (req.url !== "/api/setup-status") return false;
|
|
42
|
+
if (req.method !== "GET") {
|
|
43
|
+
// guardrails-allow PREVENT-PI-004: loopback dashboard response (local)
|
|
44
|
+
res.writeHead(405, { "Content-Type": "application/json" });
|
|
45
|
+
res.end(JSON.stringify({ error: "method_not_allowed" }));
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
const body: SetupStatusResponse = {
|
|
49
|
+
currentEmbedder: detectCurrentEmbedder(),
|
|
50
|
+
embeddingUrl: process.env["MEGACOMPACT_EMBEDDING_URL"] ?? null,
|
|
51
|
+
embedCache: process.env["MEGACOMPACT_EMBED_CACHE"] ?? null,
|
|
52
|
+
minilm: ["1", "true", "yes"].includes(
|
|
53
|
+
(process.env["MEGACOMPACT_MINILM"] ?? "").trim().toLowerCase(),
|
|
54
|
+
),
|
|
55
|
+
};
|
|
56
|
+
// guardrails-allow PREVENT-PI-004: loopback dashboard response (local)
|
|
57
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
58
|
+
res.end(JSON.stringify(body));
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
// handleSetupDetect — "/api/setup-detect"
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
|
|
66
|
+
function detectOllama(): OllamaDetectResult | null {
|
|
67
|
+
try {
|
|
68
|
+
const version = spawnSync("ollama", ["--version"], {
|
|
69
|
+
timeout: 5000,
|
|
70
|
+
encoding: "utf-8",
|
|
71
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
72
|
+
});
|
|
73
|
+
if (version.status !== 0) {
|
|
74
|
+
return { installed: false, models: [], running: false, detail: version.stderr?.trim() || "not found" };
|
|
75
|
+
}
|
|
76
|
+
// Check for running server
|
|
77
|
+
let running = false;
|
|
78
|
+
let models: string[] = [];
|
|
79
|
+
try {
|
|
80
|
+
const listResult = spawnSync("ollama", ["list"], {
|
|
81
|
+
timeout: 5000,
|
|
82
|
+
encoding: "utf-8",
|
|
83
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
84
|
+
});
|
|
85
|
+
if (listResult.status === 0) {
|
|
86
|
+
running = true;
|
|
87
|
+
// Parse lines: NAME ID SIZE MODIFIED
|
|
88
|
+
const lines = listResult.stdout?.split("\n") ?? [];
|
|
89
|
+
for (const line of lines) {
|
|
90
|
+
const name = line.split(/\s+/)[0];
|
|
91
|
+
if (name && name !== "NAME") models.push(name);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
} catch {
|
|
95
|
+
// ollama list failed — server may not be running
|
|
96
|
+
running = false;
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
installed: true,
|
|
100
|
+
models,
|
|
101
|
+
running,
|
|
102
|
+
detail: version.stdout?.trim() || null,
|
|
103
|
+
};
|
|
104
|
+
} catch {
|
|
105
|
+
return { installed: false, models: [], running: false, detail: "detection error" };
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function detectLlamaCpp(): DetectResult | null {
|
|
110
|
+
try {
|
|
111
|
+
const which = spawnSync("which", ["llama-server", "llama.cpp"], {
|
|
112
|
+
timeout: 3000,
|
|
113
|
+
encoding: "utf-8",
|
|
114
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
115
|
+
});
|
|
116
|
+
const installed = which.status === 0 && which.stdout.trim().length > 0;
|
|
117
|
+
return {
|
|
118
|
+
installed,
|
|
119
|
+
detail: installed ? which.stdout.trim() : null,
|
|
120
|
+
};
|
|
121
|
+
} catch {
|
|
122
|
+
return { installed: false, detail: "detection error" };
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function detectOnnx(): DetectResult | null {
|
|
127
|
+
try {
|
|
128
|
+
// Check for onnxruntime-node in a parent node_modules
|
|
129
|
+
const req = createRequire(import.meta.url);
|
|
130
|
+
try {
|
|
131
|
+
req.resolve("onnxruntime-node");
|
|
132
|
+
return { installed: true, detail: "onnxruntime-node found in node_modules" };
|
|
133
|
+
} catch {
|
|
134
|
+
return { installed: false, detail: "onnxruntime-node not found in node_modules" };
|
|
135
|
+
}
|
|
136
|
+
} catch {
|
|
137
|
+
return { installed: false, detail: "detection error" };
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export function handleSetupDetect(
|
|
142
|
+
req: IncomingMessage,
|
|
143
|
+
res: ServerResponse,
|
|
144
|
+
_ctx: RouteContext,
|
|
145
|
+
): boolean {
|
|
146
|
+
if (req.url !== "/api/setup-detect") return false;
|
|
147
|
+
if (req.method !== "GET") {
|
|
148
|
+
// guardrails-allow PREVENT-PI-004: loopback dashboard response (local)
|
|
149
|
+
res.writeHead(405, { "Content-Type": "application/json" });
|
|
150
|
+
res.end(JSON.stringify({ error: "method_not_allowed" }));
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
let error: string | null = null;
|
|
154
|
+
let ollama: OllamaDetectResult | null = null;
|
|
155
|
+
let llamaCpp: DetectResult | null = null;
|
|
156
|
+
let onnx: DetectResult | null = null;
|
|
157
|
+
|
|
158
|
+
try {
|
|
159
|
+
ollama = detectOllama();
|
|
160
|
+
} catch (e) {
|
|
161
|
+
error = `ollama detection failed: ${e instanceof Error ? e.message : String(e)}`;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
try {
|
|
165
|
+
llamaCpp = detectLlamaCpp();
|
|
166
|
+
} catch (e) {
|
|
167
|
+
error = error ?? `llama.cpp detection failed: ${e instanceof Error ? e.message : String(e)}`;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
try {
|
|
171
|
+
onnx = detectOnnx();
|
|
172
|
+
} catch (e) {
|
|
173
|
+
error = error ?? `onnx detection failed: ${e instanceof Error ? e.message : String(e)}`;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const body: SetupDetectResponse = { ollama, llamaCpp, onnx, error };
|
|
177
|
+
// guardrails-allow PREVENT-PI-004: loopback dashboard response (local)
|
|
178
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
179
|
+
res.end(JSON.stringify(body));
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
@@ -20,3 +20,5 @@ export { handleTopics } from "./routes-topics.js";
|
|
|
20
20
|
export { handleTurns } from "./routes-turns.js";
|
|
21
21
|
export { handleMaintenance } from "./routes-maintenance.js";
|
|
22
22
|
export { handleProviderCache } from "./routes-cache.js";
|
|
23
|
+
export { handleMemoryStatus } from "./routes-memory.js";
|
|
24
|
+
export { handleSetupStatus, handleSetupDetect } from "./routes-setup.js";
|
|
@@ -38,6 +38,9 @@ import {
|
|
|
38
38
|
handleTurns,
|
|
39
39
|
handleMaintenance,
|
|
40
40
|
handleProviderCache,
|
|
41
|
+
handleMemoryStatus,
|
|
42
|
+
handleSetupStatus,
|
|
43
|
+
handleSetupDetect,
|
|
41
44
|
handleStatic,
|
|
42
45
|
} from "./routes.js";
|
|
43
46
|
|
|
@@ -227,6 +230,9 @@ export async function launchDashboardServer(
|
|
|
227
230
|
if (handleTurns(req, res, ctx)) return;
|
|
228
231
|
if (handleMaintenance(req, res, ctx)) return;
|
|
229
232
|
if (handleProviderCache(req, res, ctx)) return;
|
|
233
|
+
if (handleMemoryStatus(req, res, ctx)) return;
|
|
234
|
+
if (handleSetupStatus(req, res, ctx)) return;
|
|
235
|
+
if (handleSetupDetect(req, res, ctx)) return;
|
|
230
236
|
handleStatic(req, res, ctx);
|
|
231
237
|
});
|
|
232
238
|
|
|
@@ -16,6 +16,11 @@ import { type MegaRuntime, C, recentUserQuery } from "./mega-runtime.js";
|
|
|
16
16
|
import { runCompact, doRecall, doRecallAsync } from "./mega-pipeline.js";
|
|
17
17
|
import { vectorStats, vectorRepoStats, vectorDataInvariant } from "../src/vectorStore.js";
|
|
18
18
|
import type { MegaConfig } from "./mega-config.js";
|
|
19
|
+
import { spawnSync } from "node:child_process"; // guardrails-allow PREVENT-PI-004: local subprocess detection only (no network)
|
|
20
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
21
|
+
import path from "node:path";
|
|
22
|
+
import os from "node:os";
|
|
23
|
+
import { createRequire } from "node:module";
|
|
19
24
|
|
|
20
25
|
/** Resolve a checkpoint by id (or "recent"/"last") from this session's store. */
|
|
21
26
|
export function findCheckpoint(runtime: MegaRuntime, sid: string, ref: string) {
|
|
@@ -79,7 +84,7 @@ export function registerCommands(pi: ExtensionAPI, runtime: MegaRuntime, config:
|
|
|
79
84
|
runtime.setStatus(ctx, `mega-compact: recalled ${r.toInject.length} chkpt${crossRepo ? " (cross-repo)" : ""}`);
|
|
80
85
|
ctx.ui.notify(
|
|
81
86
|
`[mega-compact] recall staged ${r.toInject.length} checkpoint(s) for "${query}"${crossRepo ? " (cross-repo)" : ""}:\n${list}\n` +
|
|
82
|
-
`(injected at the next turn
|
|
87
|
+
`(injected at the tail of the next turn's context)`,
|
|
83
88
|
);
|
|
84
89
|
} catch (e) {
|
|
85
90
|
ctx.ui.notify(`[mega-compact] /mega-recall failed: ${String(e)}`);
|
|
@@ -275,6 +280,211 @@ export function registerCommands(pi: ExtensionAPI, runtime: MegaRuntime, config:
|
|
|
275
280
|
},
|
|
276
281
|
});
|
|
277
282
|
|
|
283
|
+
pi.registerCommand("mega-setup", {
|
|
284
|
+
description:
|
|
285
|
+
"Local embedding setup wizard — detect available embedders and configure mega-compact.",
|
|
286
|
+
handler: async (_args: string, ctx: ExtensionContext) => {
|
|
287
|
+
try {
|
|
288
|
+
const log = (msg: string) => ctx.ui.notify(msg);
|
|
289
|
+
|
|
290
|
+
// --- 1. Current config ---
|
|
291
|
+
const embeddingUrl = process.env["MEGACOMPACT_EMBEDDING_URL"];
|
|
292
|
+
const minilm = process.env["MEGACOMPACT_MINILM"];
|
|
293
|
+
|
|
294
|
+
let currentEmbedder = "TrigramEmbedder (heuristic, default)";
|
|
295
|
+
if (embeddingUrl) currentEmbedder = `httpEmbedder → ${embeddingUrl}`;
|
|
296
|
+
else if (minilm) currentEmbedder = "MiniLM (experimental)";
|
|
297
|
+
|
|
298
|
+
// --- 2. Detection ---
|
|
299
|
+
let ollamaDetected = false;
|
|
300
|
+
let ollamaModels: string[] = [];
|
|
301
|
+
let ollamaRunning = false;
|
|
302
|
+
let llamaDetected = false;
|
|
303
|
+
let onnxDetected = false;
|
|
304
|
+
|
|
305
|
+
try {
|
|
306
|
+
const ollamaVer = spawnSync("ollama", ["--version"], {
|
|
307
|
+
timeout: 5000,
|
|
308
|
+
encoding: "utf-8",
|
|
309
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
310
|
+
}); // guardrails-allow PREVENT-PI-004: local subprocess detection only
|
|
311
|
+
if (ollamaVer.status === 0) {
|
|
312
|
+
ollamaDetected = true;
|
|
313
|
+
try {
|
|
314
|
+
const listResult = spawnSync("ollama", ["list"], {
|
|
315
|
+
timeout: 5000,
|
|
316
|
+
encoding: "utf-8",
|
|
317
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
318
|
+
}); // guardrails-allow PREVENT-PI-004: local subprocess detection only
|
|
319
|
+
if (listResult.status === 0) {
|
|
320
|
+
ollamaRunning = true;
|
|
321
|
+
const lines = listResult.stdout?.split("\n") ?? [];
|
|
322
|
+
for (const line of lines) {
|
|
323
|
+
const name = line.split(/\s+/)[0];
|
|
324
|
+
if (name && name !== "NAME") ollamaModels.push(name);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
} catch {
|
|
328
|
+
// ollama list fails if server not running — that's fine
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
} catch {
|
|
332
|
+
// ollama not found
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
try {
|
|
336
|
+
const whichLlama = spawnSync("which", ["llama-server"], {
|
|
337
|
+
timeout: 3000,
|
|
338
|
+
encoding: "utf-8",
|
|
339
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
340
|
+
}); // guardrails-allow PREVENT-PI-004: local subprocess detection only
|
|
341
|
+
llamaDetected = whichLlama.status === 0;
|
|
342
|
+
} catch {
|
|
343
|
+
// not found
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
try {
|
|
347
|
+
const req = createRequire(import.meta.url);
|
|
348
|
+
try {
|
|
349
|
+
req.resolve("onnxruntime-node");
|
|
350
|
+
onnxDetected = true;
|
|
351
|
+
} catch {
|
|
352
|
+
// not in node_modules
|
|
353
|
+
}
|
|
354
|
+
} catch {
|
|
355
|
+
// require error
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// --- 3. Build choices ---
|
|
359
|
+
interface Choice {
|
|
360
|
+
label: string;
|
|
361
|
+
value: string;
|
|
362
|
+
}
|
|
363
|
+
const choices: Choice[] = [];
|
|
364
|
+
|
|
365
|
+
if (ollamaDetected && ollamaRunning) {
|
|
366
|
+
const model = ollamaModels.find(
|
|
367
|
+
(m) =>
|
|
368
|
+
m.includes("nomic-embed") ||
|
|
369
|
+
m.includes("embed") ||
|
|
370
|
+
m.includes("mxbai"),
|
|
371
|
+
);
|
|
372
|
+
const suggestedModel = model ?? "nomic-embed-text";
|
|
373
|
+
choices.push({
|
|
374
|
+
label: `Use Ollama (${suggestedModel}) at localhost:11434`,
|
|
375
|
+
value: `ollama:${suggestedModel}`,
|
|
376
|
+
});
|
|
377
|
+
} else if (ollamaDetected && !ollamaRunning) {
|
|
378
|
+
choices.push({
|
|
379
|
+
label: "Ollama detected but server is not running — start it first",
|
|
380
|
+
value: "ollama:offline",
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
if (llamaDetected) {
|
|
385
|
+
choices.push({
|
|
386
|
+
label: "Use llama.cpp server at localhost:8080",
|
|
387
|
+
value: "llama:default",
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
if (onnxDetected) {
|
|
392
|
+
choices.push({
|
|
393
|
+
label: "Use ONNX Runtime (experimental, requires config)",
|
|
394
|
+
value: "onnx:default",
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
choices.push({
|
|
399
|
+
label: "Keep TrigramEmbedder (default, no setup)",
|
|
400
|
+
value: "trigram",
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
// --- 4. Prompt user ---
|
|
404
|
+
log(`Current embedder: ${currentEmbedder}`);
|
|
405
|
+
let selected = "trigram";
|
|
406
|
+
if (choices.length > 1) {
|
|
407
|
+
try {
|
|
408
|
+
const labels = choices.map((c) => c.label);
|
|
409
|
+
const picked = await ctx.ui.select("Select an embedder to configure:", labels);
|
|
410
|
+
if (picked === undefined) {
|
|
411
|
+
log("Setup cancelled by user.");
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
const match = choices.find((c) => c.label === picked);
|
|
415
|
+
selected = match?.value ?? "trigram";
|
|
416
|
+
} catch {
|
|
417
|
+
log("Setup cancelled by user.");
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
} else {
|
|
421
|
+
log("No local embedders detected. Keeping TrigramEmbedder default.");
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// --- 5. Apply selection ---
|
|
425
|
+
if (selected.startsWith("ollama:")) {
|
|
426
|
+
const model = selected.split(":")[1];
|
|
427
|
+
const url = `http://localhost:11434/api/embeddings`; // guardrails-allow PREVENT-PI-004: localhost-only config string, not a runtime fetch
|
|
428
|
+
const lines = [
|
|
429
|
+
`# Mega-Compact Embedder Configuration — Ollama`,
|
|
430
|
+
`# Generated by /megasetup at ${new Date().toISOString()}`,
|
|
431
|
+
`export MEGACOMPACT_EMBEDDING_URL="${url}"`,
|
|
432
|
+
`# Optional: uncomment to set cache size (default 1000)`,
|
|
433
|
+
`# export MEGACOMPACT_EMBED_CACHE=1000`,
|
|
434
|
+
];
|
|
435
|
+
const envContent = lines.join("\n") + "\n";
|
|
436
|
+
|
|
437
|
+
// Write .mega-compact.env to state dir
|
|
438
|
+
const stateDir = process.env["MEGACOMPACT_STATE_DIR"] ?? path.join(os.homedir(), ".pi", "mega-compact");
|
|
439
|
+
try {
|
|
440
|
+
mkdirSync(stateDir, { recursive: true });
|
|
441
|
+
writeFileSync(path.join(stateDir, ".mega-compact.env"), envContent, "utf-8");
|
|
442
|
+
} catch {
|
|
443
|
+
// non-fatal
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
log(
|
|
447
|
+
`Configured for Ollama (${model}).\n\nAdd to your shell profile (~/.bashrc, ~/.zshrc, or ~/.config/fish/config.fish):\n\n source "${path.join(
|
|
448
|
+
stateDir,
|
|
449
|
+
".mega-compact.env",
|
|
450
|
+
)}"\n\nOr export manually:\n\n export MEGACOMPACT_EMBEDDING_URL="${url}"\n\nThen restart pi to activate the http embedder.`,
|
|
451
|
+
);
|
|
452
|
+
} else if (selected.startsWith("llama:")) {
|
|
453
|
+
const url = "http://localhost:8080/v1/embeddings"; // guardrails-allow PREVENT-PI-004: localhost-only config string, not a runtime fetch
|
|
454
|
+
const lines = [
|
|
455
|
+
`# Mega-Compact Embedder Configuration — llama.cpp`,
|
|
456
|
+
`# Generated by /megasetup at ${new Date().toISOString()}`,
|
|
457
|
+
`export MEGACOMPACT_EMBEDDING_URL="${url}"`,
|
|
458
|
+
];
|
|
459
|
+
const envContent = lines.join("\n") + "\n";
|
|
460
|
+
|
|
461
|
+
const stateDir = process.env["MEGACOMPACT_STATE_DIR"] ?? path.join(os.homedir(), ".pi", "mega-compact");
|
|
462
|
+
try {
|
|
463
|
+
mkdirSync(stateDir, { recursive: true });
|
|
464
|
+
writeFileSync(path.join(stateDir, ".mega-compact.env"), envContent, "utf-8");
|
|
465
|
+
} catch {
|
|
466
|
+
// non-fatal
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
log(
|
|
470
|
+
`Configured for llama.cpp server.\n\nAdd to your shell profile:\n\n source "${path.join(
|
|
471
|
+
stateDir,
|
|
472
|
+
".mega-compact.env",
|
|
473
|
+
)}"\n\nOr export manually:\n\n export MEGACOMPACT_EMBEDDING_URL="${url}"\n\nThen restart pi to activate the http embedder.`,
|
|
474
|
+
);
|
|
475
|
+
} else if (selected.startsWith("onnx:")) {
|
|
476
|
+
log(
|
|
477
|
+
"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.",
|
|
478
|
+
);
|
|
479
|
+
} else {
|
|
480
|
+
log("Keeping TrigramEmbedder (default). No configuration needed.");
|
|
481
|
+
}
|
|
482
|
+
} catch (e) {
|
|
483
|
+
ctx.ui.notify(`[mega-compact] /mega-setup failed: ${String(e)}`);
|
|
484
|
+
}
|
|
485
|
+
},
|
|
486
|
+
});
|
|
487
|
+
|
|
278
488
|
// NOTE: /mega-tier was removed in S24. The tier the user sees is now the LIVE
|
|
279
489
|
// pressure band (low/medium/high/ultra/mega), which climbs automatically as
|
|
280
490
|
// context fills — there is no manual tier to set. See docs/specs/s24-unified-pressure.md.
|
|
@@ -111,6 +111,10 @@ export interface MegaConfig {
|
|
|
111
111
|
* advisory is sent to the user (distinct from the poisoned /clear advise).
|
|
112
112
|
* Default 3. `0` disables the advisory entirely. */
|
|
113
113
|
providerOutageAdviseThreshold: number;
|
|
114
|
+
/** R13: when true (default), poisoned-context and provider-outage advisories
|
|
115
|
+
* are dashboard-only (events tab + log) — no user-visible message injection.
|
|
116
|
+
* When false, the legacy sendUserMessage path runs (byte-identical pre-R13). */
|
|
117
|
+
advisoryChannel: boolean;
|
|
114
118
|
/** S29: override the auto-compact fire point for tiered configs, as a
|
|
115
119
|
* fraction of the context window (e.g. 0.85). null = inherit the tier's
|
|
116
120
|
* tierPct (default; preserves existing fire points). The context-handler
|
|
@@ -160,6 +164,10 @@ export interface MegaConfig {
|
|
|
160
164
|
* a hit whose summary is ≥ dedupSim similar to a live message — "dedupe on
|
|
161
165
|
* inline/read" so we never re-inject context already resident. */
|
|
162
166
|
windowDedupe: boolean;
|
|
167
|
+
/** S53: Recall Tail Injection — inject staged recall block as a user message at
|
|
168
|
+
* the tail of the view when auto is OFF AND no trim action is needed. Default ON
|
|
169
|
+
* (true). When false, restores the pre-sprint systemPrompt prepend behavior. */
|
|
170
|
+
recallTailInject: boolean;
|
|
163
171
|
debug: boolean;
|
|
164
172
|
/** Master reconciliation: TUI shutdown widget (MEGACOMPACT_TUI_WIDGET=0 to disable). */
|
|
165
173
|
tuiWidget: boolean;
|
|
@@ -306,6 +314,7 @@ export function loadConfig(): MegaConfig {
|
|
|
306
314
|
"MEGACOMPACT_PROVIDER_OUTAGE_THRESHOLD",
|
|
307
315
|
3,
|
|
308
316
|
),
|
|
317
|
+
advisoryChannel: envBool("MEGACOMPACT_ADVISORY_CHANNEL", true),
|
|
309
318
|
autoPctTrigger,
|
|
310
319
|
autoInlineK: envFlag("MEGACOMPACT_AUTO_INLINE_K", 3),
|
|
311
320
|
dedupSim: Number(process.env.MEGACOMPACT_DEDUP_SIM ?? "0.9"),
|
|
@@ -322,6 +331,7 @@ export function loadConfig(): MegaConfig {
|
|
|
322
331
|
memoryReviewInterval: envFlag("MEGACOMPACT_MEMORY_REVIEW_INTERVAL", 10),
|
|
323
332
|
recallMaxTokens: envFlag("MEGACOMPACT_RECALL_MAX_TOKENS", 1500),
|
|
324
333
|
windowDedupe: envBool("MEGACOMPACT_WINDOW_DEDUPE", true),
|
|
334
|
+
recallTailInject: envBool("MEGACOMPACT_RECALL_TAIL_INJECT", true),
|
|
325
335
|
tuiWidget: envBool("MEGACOMPACT_TUI_WIDGET", true),
|
|
326
336
|
// D.1: env-overridable recompact delta (minimum context growth % before
|
|
327
337
|
// re-compacting instead of replaying the cached live trim). Default 50.
|
|
@@ -189,7 +189,10 @@ export function registerAgentHandlers(
|
|
|
189
189
|
setTimeout(() => {
|
|
190
190
|
try {
|
|
191
191
|
if (runtime.rt.sessionId !== liveSid) return; // session reset
|
|
192
|
-
|
|
192
|
+
// IMPORTANT: recompute Date.now() inside the timeout.
|
|
193
|
+
// `now` above is the durable-trim handler's timestamp and can be
|
|
194
|
+
// ~500ms stale by the time this callback runs.
|
|
195
|
+
const since2 = Date.now() - (runtime.rt.lastNativeCompactAt ?? 0);
|
|
193
196
|
if (
|
|
194
197
|
runtime.rt.lastNativeCompactAt !== stamp &&
|
|
195
198
|
since2 < cooldownMs
|
|
@@ -267,6 +270,16 @@ export function registerAgentHandlers(
|
|
|
267
270
|
runtime.dashboard.event("turn_end", { turnIndex: event.turnIndex });
|
|
268
271
|
runtime.snapshot(ctx);
|
|
269
272
|
|
|
273
|
+
// S53: consume staged recall blocks ONLY if they were actually injected
|
|
274
|
+
// into a view this turn. If no context event fired (edge: turn ended
|
|
275
|
+
// before any LLM call), recallInjectedThisTurn stays false and the blocks
|
|
276
|
+
// remain staged for the next turn's first context event.
|
|
277
|
+
if (config.recallTailInject && runtime.rt.recallInjectedThisTurn) {
|
|
278
|
+
runtime.pendingRecallBlock = undefined;
|
|
279
|
+
runtime.pendingMemoryRecallBlock = undefined;
|
|
280
|
+
runtime.rt.recallInjectedThisTurn = false;
|
|
281
|
+
}
|
|
282
|
+
|
|
270
283
|
// S43 (per-turn tracking): record one turn row with the cached metrics so
|
|
271
284
|
// the turn layer is queryable + forkable. Best-effort + non-fatal: a write
|
|
272
285
|
// failure never breaks the agent loop.
|
|
@@ -571,9 +584,12 @@ export function registerAgentHandlers(
|
|
|
571
584
|
rawText: (errSig || '').slice(0, 500),
|
|
572
585
|
...(detail.httpStatus !== undefined ? { httpStatus: detail.httpStatus } : {}),
|
|
573
586
|
});
|
|
574
|
-
// (b)
|
|
575
|
-
|
|
576
|
-
|
|
587
|
+
// (b) throttle flag: set unconditionally so the advise fires at
|
|
588
|
+
// most once per session regardless of channel.
|
|
589
|
+
runtime.rt.poisonedAdviseSent = true;
|
|
590
|
+
// Legacy flag-OFF path: user-role advise message.
|
|
591
|
+
// Default ON (advisoryChannel=true): dashboard-only, no user message.
|
|
592
|
+
if (!config.advisoryChannel) {
|
|
577
593
|
// PREVENT-PI-003: user-role sendUserMessage only.
|
|
578
594
|
await safeSendUserMessage(
|
|
579
595
|
pi,
|
|
@@ -69,6 +69,7 @@ async function nudgeResume(pi: ExtensionAPI, runtime: MegaRuntime): Promise<void
|
|
|
69
69
|
const now = Date.now();
|
|
70
70
|
if (now >= runtime.resumeNudgeUntil) {
|
|
71
71
|
runtime.resumeNudgeUntil = now + 30_000;
|
|
72
|
+
runtime.rt.extensionInitiatedTurn = true; // R13: suppress self-classification
|
|
72
73
|
await safeSendUserMessage(
|
|
73
74
|
pi,
|
|
74
75
|
"[mega-compact] continue from the compacted context above.",
|