pi-mega-compact 0.20.29 → 0.20.31

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.
Files changed (76) hide show
  1. package/dist/config/vector-cortex-vc9d.js +32 -0
  2. package/dist/config/vector-cortex.js +2 -1
  3. package/dist/config.js +1 -1
  4. package/dist/extensions/dashboard-server/routes-rag-settings-helpers.js +1 -1
  5. package/dist/extensions/dashboard-server/routes-rag-settings-vector-cortex.js +1 -0
  6. package/dist/extensions/dashboard-server/routes-setup-detect-cache.js +201 -0
  7. package/dist/extensions/dashboard-server/routes-setup.js +11 -83
  8. package/dist/extensions/mega-config-types.js +1 -0
  9. package/dist/extensions/mega-config.js +3 -1
  10. package/dist/extensions/mega-events/separated-prompt.js +7 -7
  11. package/dist/src/config/vector-cortex-vc9d.js +32 -0
  12. package/dist/src/config/vector-cortex.js +2 -1
  13. package/dist/src/config.js +1 -1
  14. package/extensions/dashboard-client/dist/assets/{AreaChart-DIKsPqLG.js → AreaChart-EL8l2Fcj.js} +2 -2
  15. package/extensions/dashboard-client/dist/assets/{AreaChart-DIKsPqLG.js.map → AreaChart-EL8l2Fcj.js.map} +1 -1
  16. package/extensions/dashboard-client/dist/assets/{BarChart-DeqN74Hn.js → BarChart-TrwfSh0w.js} +2 -2
  17. package/extensions/dashboard-client/dist/assets/{BarChart-DeqN74Hn.js.map → BarChart-TrwfSh0w.js.map} +1 -1
  18. package/extensions/dashboard-client/dist/assets/{CacheTab-x1YU4tYc.js → CacheTab-C3KWDFDm.js} +2 -2
  19. package/extensions/dashboard-client/dist/assets/{CacheTab-x1YU4tYc.js.map → CacheTab-C3KWDFDm.js.map} +1 -1
  20. package/extensions/dashboard-client/dist/assets/{EventsTab-6BuEbd8Y.js → EventsTab-CNrT-b7t.js} +2 -2
  21. package/extensions/dashboard-client/dist/assets/{EventsTab-6BuEbd8Y.js.map → EventsTab-CNrT-b7t.js.map} +1 -1
  22. package/extensions/dashboard-client/dist/assets/{HealthTab-B71Ft1ac.js → HealthTab-CkBCFPk6.js} +2 -2
  23. package/extensions/dashboard-client/dist/assets/{HealthTab-B71Ft1ac.js.map → HealthTab-CkBCFPk6.js.map} +1 -1
  24. package/extensions/dashboard-client/dist/assets/{MaintenanceTab-dysyJtHk.js → MaintenanceTab-CcbKszwx.js} +2 -2
  25. package/extensions/dashboard-client/dist/assets/{MaintenanceTab-dysyJtHk.js.map → MaintenanceTab-CcbKszwx.js.map} +1 -1
  26. package/extensions/dashboard-client/dist/assets/{MemoryMapTab-B3dKRb_4.js → MemoryMapTab-B2LvwScj.js} +2 -2
  27. package/extensions/dashboard-client/dist/assets/{MemoryMapTab-B3dKRb_4.js.map → MemoryMapTab-B2LvwScj.js.map} +1 -1
  28. package/extensions/dashboard-client/dist/assets/{MetricsTab-COn4GoUK.js → MetricsTab-Dv_xZtOG.js} +2 -2
  29. package/extensions/dashboard-client/dist/assets/{MetricsTab-COn4GoUK.js.map → MetricsTab-Dv_xZtOG.js.map} +1 -1
  30. package/extensions/dashboard-client/dist/assets/{OverviewTab-Cd9qAEB3.js → OverviewTab-D7xwhpOl.js} +2 -2
  31. package/extensions/dashboard-client/dist/assets/{OverviewTab-Cd9qAEB3.js.map → OverviewTab-D7xwhpOl.js.map} +1 -1
  32. package/extensions/dashboard-client/dist/assets/{ReposTab-DpiP1-Vv.js → ReposTab-BfhiPXdA.js} +2 -2
  33. package/extensions/dashboard-client/dist/assets/{ReposTab-DpiP1-Vv.js.map → ReposTab-BfhiPXdA.js.map} +1 -1
  34. package/extensions/dashboard-client/dist/assets/{SessionsTab-BwRUeGZM.js → SessionsTab-tQM0TQLp.js} +2 -2
  35. package/extensions/dashboard-client/dist/assets/{SessionsTab-BwRUeGZM.js.map → SessionsTab-tQM0TQLp.js.map} +1 -1
  36. package/extensions/dashboard-client/dist/assets/SetupTab-G-MkdQiR.js +3 -0
  37. package/extensions/dashboard-client/dist/assets/SetupTab-G-MkdQiR.js.map +1 -0
  38. package/extensions/dashboard-client/dist/assets/{TimeSavedCard-_XsdjQ7Z.js → TimeSavedCard-CYltysD3.js} +2 -2
  39. package/extensions/dashboard-client/dist/assets/{TimeSavedCard-_XsdjQ7Z.js.map → TimeSavedCard-CYltysD3.js.map} +1 -1
  40. package/extensions/dashboard-client/dist/assets/{TurnsTab-CWPscPLL.js → TurnsTab-1Y_Lpxx-.js} +2 -2
  41. package/extensions/dashboard-client/dist/assets/{TurnsTab-CWPscPLL.js.map → TurnsTab-1Y_Lpxx-.js.map} +1 -1
  42. package/extensions/dashboard-client/dist/assets/{VcStatusBadge-Cx56rAIM.js → VcStatusBadge-BNHVeTG7.js} +2 -2
  43. package/extensions/dashboard-client/dist/assets/{VcStatusBadge-Cx56rAIM.js.map → VcStatusBadge-BNHVeTG7.js.map} +1 -1
  44. package/extensions/dashboard-client/dist/assets/{VectorCortexTab-B5ElUM7S.js → VectorCortexTab-goacPxL1.js} +2 -2
  45. package/extensions/dashboard-client/dist/assets/{VectorCortexTab-B5ElUM7S.js.map → VectorCortexTab-goacPxL1.js.map} +1 -1
  46. package/extensions/dashboard-client/dist/assets/{WikiTab-uZ5Mq3XG.js → WikiTab-DTOemYtE.js} +2 -2
  47. package/extensions/dashboard-client/dist/assets/{WikiTab-uZ5Mq3XG.js.map → WikiTab-DTOemYtE.js.map} +1 -1
  48. package/extensions/dashboard-client/dist/assets/{button-Kc18bYFz.js → button-B_4j_PVR.js} +2 -2
  49. package/extensions/dashboard-client/dist/assets/{button-Kc18bYFz.js.map → button-B_4j_PVR.js.map} +1 -1
  50. package/extensions/dashboard-client/dist/assets/{card-COJZoG08.js → card-Ce58rSXG.js} +2 -2
  51. package/extensions/dashboard-client/dist/assets/{card-COJZoG08.js.map → card-Ce58rSXG.js.map} +1 -1
  52. package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-ChEYo017.js → generateCategoricalChart-DtNoJ6fZ.js} +2 -2
  53. package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-ChEYo017.js.map → generateCategoricalChart-DtNoJ6fZ.js.map} +1 -1
  54. package/extensions/dashboard-client/dist/assets/{index-CB7Rn5FP.js → index-eoCm0uxj.js} +3 -3
  55. package/extensions/dashboard-client/dist/assets/{index-CB7Rn5FP.js.map → index-eoCm0uxj.js.map} +1 -1
  56. package/extensions/dashboard-client/dist/assets/{switch-BFhl_tNh.js → switch-B9kM0N7R.js} +2 -2
  57. package/extensions/dashboard-client/dist/assets/{switch-BFhl_tNh.js.map → switch-B9kM0N7R.js.map} +1 -1
  58. package/extensions/dashboard-client/dist/assets/{toggle-DJ68kATc.js → toggle-BwoHYpMa.js} +2 -2
  59. package/extensions/dashboard-client/dist/assets/{toggle-DJ68kATc.js.map → toggle-BwoHYpMa.js.map} +1 -1
  60. package/extensions/dashboard-client/dist/assets/{useSSE-CXWh42xX.js → useSSE-DohG5AGv.js} +2 -2
  61. package/extensions/dashboard-client/dist/assets/{useSSE-CXWh42xX.js.map → useSSE-DohG5AGv.js.map} +1 -1
  62. package/extensions/dashboard-client/dist/index.html +1 -1
  63. package/extensions/dashboard-client/src/tabs/SetupTab/EmbedderSetup.tsx +14 -2
  64. package/extensions/dashboard-server/routes-rag-settings-helpers.ts +1 -1
  65. package/extensions/dashboard-server/routes-rag-settings-vector-cortex.ts +6 -0
  66. package/extensions/dashboard-server/routes-setup-detect-cache.ts +224 -0
  67. package/extensions/dashboard-server/routes-setup.ts +19 -79
  68. package/extensions/mega-config-types.ts +181 -0
  69. package/extensions/mega-config.ts +7 -171
  70. package/extensions/mega-events/separated-prompt.ts +7 -8
  71. package/package.json +1 -1
  72. package/src/config/vector-cortex-vc9d.ts +34 -0
  73. package/src/config/vector-cortex.ts +2 -1
  74. package/src/config.ts +1 -0
  75. package/extensions/dashboard-client/dist/assets/SetupTab-CJFDD2_v.js +0 -3
  76. package/extensions/dashboard-client/dist/assets/SetupTab-CJFDD2_v.js.map +0 -1
@@ -0,0 +1,224 @@
1
+ /**
2
+ * dashboard-server/routes-setup-detect-cache.ts — memoized embedder-barrier
3
+ * detection (VC9D).
4
+ *
5
+ * The three raw fresh detectors (`detectOllama` / `detectLlamaCpp` /
6
+ * `detectOnnx`) moved verbatim out of routes-setup.ts — they are the source of
7
+ * truth for "is this embedder backend present". Each also has a memoized
8
+ * sibling (`memoizedDetectOllama` / `memoizedDetectLlamaCpp` /
9
+ * `memoizedDetectOnnx`) that runs the expensive spawn ONLY when its mutable
10
+ * input changes, matching the `healthFactCacheKey` invalidation semantics from
11
+ * routes-vector-cortex-health.ts:71-122: the cache key is the resolved binary
12
+ * path + its size/mtime (onnx: resolved module path + package mtime), so an
13
+ * install/upgrade on PATH or in node_modules naturally invalidates the entry,
14
+ * while a steady environment reuses the result instead of re-spawning.
15
+ *
16
+ * A single module-level slot per target is shared across every
17
+ * /api/setup-detect request, so consecutive polls reuse the result.
18
+ *
19
+ * Guardrails: PREVENT-PI-004 (local subprocess + filesystem reads only, no
20
+ * network), PREVENT-011 (no `any`). Each decoration line carries a
21
+ * guardrails-allow annotation.
22
+ */
23
+
24
+ import { spawnSync } from "node:child_process"; // guardrails-allow PREVENT-PI-004: local subprocess detection only
25
+ import { createRequire } from "node:module";
26
+ import { statSync } from "node:fs";
27
+ import type { DetectResult, OllamaDetectResult } from "./api-contracts/setup.js";
28
+
29
+ // ---------------------------------------------------------------------------
30
+ // Raw fresh detectors (moved verbatim from routes-setup.ts — single source).
31
+ // ---------------------------------------------------------------------------
32
+
33
+ export function detectOllama(): OllamaDetectResult | null {
34
+ try {
35
+ const version = spawnSync("ollama", ["--version"], {
36
+ timeout: 5000,
37
+ encoding: "utf-8",
38
+ stdio: ["ignore", "pipe", "pipe"],
39
+ });
40
+ if (version.status !== 0) {
41
+ return { installed: false, models: [], running: false, detail: version.stderr?.trim() || "not found" };
42
+ }
43
+ // Check for running server
44
+ let running = false;
45
+ let models: string[] = [];
46
+ try {
47
+ const listResult = spawnSync("ollama", ["list"], {
48
+ timeout: 5000,
49
+ encoding: "utf-8",
50
+ stdio: ["ignore", "pipe", "pipe"],
51
+ });
52
+ if (listResult.status === 0) {
53
+ running = true;
54
+ // Parse lines: NAME ID SIZE MODIFIED
55
+ const lines = listResult.stdout?.split("\n") ?? [];
56
+ for (const line of lines) {
57
+ const name = line.split(/\s+/)[0];
58
+ if (name && name !== "NAME") models.push(name);
59
+ }
60
+ }
61
+ } catch {
62
+ // ollama list failed — server may not be running
63
+ running = false;
64
+ }
65
+ return {
66
+ installed: true,
67
+ models,
68
+ running,
69
+ detail: version.stdout?.trim() || null,
70
+ };
71
+ } catch {
72
+ return { installed: false, models: [], running: false, detail: "detection error" };
73
+ }
74
+ }
75
+
76
+ export function detectLlamaCpp(): DetectResult | null {
77
+ try {
78
+ const which = spawnSync("which", ["llama-server", "llama.cpp"], {
79
+ timeout: 3000,
80
+ encoding: "utf-8",
81
+ stdio: ["ignore", "pipe", "pipe"],
82
+ });
83
+ const installed = which.status === 0 && which.stdout.trim().length > 0;
84
+ return {
85
+ installed,
86
+ detail: installed ? which.stdout.trim() : null,
87
+ };
88
+ } catch {
89
+ return { installed: false, detail: "detection error" };
90
+ }
91
+ }
92
+
93
+ export function detectOnnx(): DetectResult | null {
94
+ try {
95
+ // Check for onnxruntime-node in a parent node_modules
96
+ const req = createRequire(import.meta.url);
97
+ try {
98
+ req.resolve("onnxruntime-node");
99
+ return { installed: true, detail: "onnxruntime-node found in node_modules" };
100
+ } catch {
101
+ return { installed: false, detail: "onnxruntime-node not found in node_modules" };
102
+ }
103
+ } catch {
104
+ return { installed: false, detail: "detection error" };
105
+ }
106
+ }
107
+
108
+ // ---------------------------------------------------------------------------
109
+ // Detect memo slot — generic, deterministic, unit-testable.
110
+ // ---------------------------------------------------------------------------
111
+
112
+ export interface DetectMemoSlot<V> {
113
+ /** Return the stored value when `key` matches the cached key, else null. */
114
+ get(key: string): V | null;
115
+ /** Store a value under a key. */
116
+ set(key: string, value: V): void;
117
+ /** Drop the cached entry. */
118
+ clear(): void;
119
+ }
120
+
121
+ /** A single memo slot. `value` is never null for a detect result (objects only). */
122
+ export function createDetectMemo<V>(): DetectMemoSlot<V> {
123
+ let key: string | null = null;
124
+ let value: V | null = null;
125
+ return {
126
+ get(k: string): V | null {
127
+ return key !== null && key === k ? value : null;
128
+ },
129
+ set(k: string, v: V): void {
130
+ key = k;
131
+ value = v;
132
+ },
133
+ clear(): void {
134
+ key = null;
135
+ value = null;
136
+ },
137
+ };
138
+ }
139
+
140
+ /**
141
+ * Run `compute` only when the derived key changes; a null key (inputs not
142
+ * resolvable — e.g. the binary is absent) is never cached, so every call runs
143
+ * the (cheap, fast-failing) detect fresh. This ordering is what the
144
+ * SETUP-CORTEX-030/031 fixtures pin: an unchanged key returns the stored value
145
+ * without re-running compute; a key mutation forces a recompute.
146
+ */
147
+ export function withDetectMemo<V>(
148
+ slot: DetectMemoSlot<V>,
149
+ deriveKey: () => string | null,
150
+ compute: () => V,
151
+ ): V {
152
+ const key = deriveKey();
153
+ const cached = key !== null ? slot.get(key) : null;
154
+ if (cached !== null) return cached;
155
+ const value = compute();
156
+ if (key !== null) slot.set(key, value);
157
+ return value;
158
+ }
159
+
160
+ // ---------------------------------------------------------------------------
161
+ // Mutable-input cache-key derivations.
162
+ // ---------------------------------------------------------------------------
163
+
164
+ /** Resolve the first PATH entry for a binary, or null when absent. */
165
+ function whichBin(bin: string): string | null {
166
+ const r = spawnSync("which", [bin], {
167
+ timeout: 3000,
168
+ encoding: "utf-8",
169
+ // guardrails-allow PREVENT-PI-004: local which lookup only
170
+ stdio: ["ignore", "pipe", "pipe"],
171
+ });
172
+ if (r.status !== 0 || !r.stdout) return null;
173
+ const first = r.stdout.trim().split("\n")[0]?.trim();
174
+ return first && first.length > 0 ? first : null;
175
+ }
176
+
177
+ /** Key = resolved path + size + mtimeMs, so an install/upgrade invalidates. */
178
+ function fileKey(p: string | null): string | null {
179
+ if (p === null || p.length === 0) return null;
180
+ try {
181
+ const s = statSync(p);
182
+ return `${p}:${s.size}:${s.mtimeMs}`;
183
+ } catch {
184
+ return null;
185
+ }
186
+ }
187
+
188
+ /** Key = resolved module path + its package.json mtime (node_modules rebuild). */
189
+ function moduleKey(packageName: string): string | null {
190
+ try {
191
+ const req = createRequire(import.meta.url);
192
+ const resolved = req.resolve(packageName + "/package.json");
193
+ return fileKey(resolved);
194
+ } catch {
195
+ return null;
196
+ }
197
+ }
198
+
199
+ // ---------------------------------------------------------------------------
200
+ // Memoized wrappers (shared module-level slots across requests).
201
+ // ---------------------------------------------------------------------------
202
+
203
+ const ollamaSlot = createDetectMemo<OllamaDetectResult | null>();
204
+ const llamaSlot = createDetectMemo<DetectResult | null>();
205
+ const onnxSlot = createDetectMemo<DetectResult | null>();
206
+
207
+ const ollamaKey = (): string | null => fileKey(whichBin("ollama"));
208
+ const llamaKey = (): string | null => fileKey(whichBin("llama-server") ?? whichBin("llama.cpp"));
209
+ const onnxKey = (): string | null => moduleKey("onnxruntime-node");
210
+
211
+ export function memoizedDetectOllama(): OllamaDetectResult | null {
212
+ // guardrails-allow PREVENT-PI-004: local subprocess detection only
213
+ return withDetectMemo(ollamaSlot, ollamaKey, detectOllama);
214
+ }
215
+
216
+ export function memoizedDetectLlamaCpp(): DetectResult | null {
217
+ // guardrails-allow PREVENT-PI-004: local subprocess detection only
218
+ return withDetectMemo(llamaSlot, llamaKey, detectLlamaCpp);
219
+ }
220
+
221
+ export function memoizedDetectOnnx(): DetectResult | null {
222
+ // guardrails-allow PREVENT-PI-004: local module resolution only
223
+ return withDetectMemo(onnxSlot, onnxKey, detectOnnx);
224
+ }
@@ -9,12 +9,19 @@
9
9
  * Each decoration line carries a guardrails-allow annotation.
10
10
  */
11
11
 
12
- import { spawnSync } from "node:child_process"; // guardrails-allow PREVENT-PI-004: local subprocess detection only
13
- import { createRequire } from "node:module";
14
12
  import { writeFileSync, mkdirSync, readFileSync, existsSync } from "node:fs";
15
13
  import { join } from "node:path";
16
14
  import type { IncomingMessage, ServerResponse } from "node:http";
17
15
  import type { RouteContext } from "./routes-core.js";
16
+ import { VC9D_ENABLED } from "../../src/config.js";
17
+ import {
18
+ detectOllama,
19
+ detectLlamaCpp,
20
+ detectOnnx,
21
+ memoizedDetectOllama,
22
+ memoizedDetectLlamaCpp,
23
+ memoizedDetectOnnx,
24
+ } from "./routes-setup-detect-cache.js";
18
25
  import type {
19
26
  SetupStatusResponse,
20
27
  SetupDetectResponse,
@@ -91,80 +98,10 @@ export function handleSetupStatus(
91
98
  // handleSetupDetect — "/api/setup-detect"
92
99
  // ---------------------------------------------------------------------------
93
100
 
94
- function detectOllama(): OllamaDetectResult | null {
95
- try {
96
- const version = spawnSync("ollama", ["--version"], {
97
- timeout: 5000,
98
- encoding: "utf-8",
99
- stdio: ["ignore", "pipe", "pipe"],
100
- });
101
- if (version.status !== 0) {
102
- return { installed: false, models: [], running: false, detail: version.stderr?.trim() || "not found" };
103
- }
104
- // Check for running server
105
- let running = false;
106
- let models: string[] = [];
107
- try {
108
- const listResult = spawnSync("ollama", ["list"], {
109
- timeout: 5000,
110
- encoding: "utf-8",
111
- stdio: ["ignore", "pipe", "pipe"],
112
- });
113
- if (listResult.status === 0) {
114
- running = true;
115
- // Parse lines: NAME ID SIZE MODIFIED
116
- const lines = listResult.stdout?.split("\n") ?? [];
117
- for (const line of lines) {
118
- const name = line.split(/\s+/)[0];
119
- if (name && name !== "NAME") models.push(name);
120
- }
121
- }
122
- } catch {
123
- // ollama list failed — server may not be running
124
- running = false;
125
- }
126
- return {
127
- installed: true,
128
- models,
129
- running,
130
- detail: version.stdout?.trim() || null,
131
- };
132
- } catch {
133
- return { installed: false, models: [], running: false, detail: "detection error" };
134
- }
135
- }
136
-
137
- function detectLlamaCpp(): DetectResult | null {
138
- try {
139
- const which = spawnSync("which", ["llama-server", "llama.cpp"], {
140
- timeout: 3000,
141
- encoding: "utf-8",
142
- stdio: ["ignore", "pipe", "pipe"],
143
- });
144
- const installed = which.status === 0 && which.stdout.trim().length > 0;
145
- return {
146
- installed,
147
- detail: installed ? which.stdout.trim() : null,
148
- };
149
- } catch {
150
- return { installed: false, detail: "detection error" };
151
- }
152
- }
153
-
154
- function detectOnnx(): DetectResult | null {
155
- try {
156
- // Check for onnxruntime-node in a parent node_modules
157
- const req = createRequire(import.meta.url);
158
- try {
159
- req.resolve("onnxruntime-node");
160
- return { installed: true, detail: "onnxruntime-node found in node_modules" };
161
- } catch {
162
- return { installed: false, detail: "onnxruntime-node not found in node_modules" };
163
- }
164
- } catch {
165
- return { installed: false, detail: "detection error" };
166
- }
167
- }
101
+ // Detection bodies live in routes-setup-detect-cache.ts (single source). When
102
+ // MEGACOMPACT_VC9D is ON the memoized wrappers reuse the result across requests
103
+ // (keyed by the mutable input: resolved binary path + mtime); when OFF we call
104
+ // the raw fresh detectors — byte-identical to the VC9C-era per-request spawn.
168
105
 
169
106
  export function handleSetupDetect(
170
107
  req: IncomingMessage,
@@ -183,20 +120,23 @@ export function handleSetupDetect(
183
120
  let llamaCpp: DetectResult | null = null;
184
121
  let onnx: DetectResult | null = null;
185
122
 
123
+ // guardrails-allow PREVENT-PI-004: local subprocess detection only (memoized or fresh)
124
+ const cached = VC9D_ENABLED();
125
+
186
126
  try {
187
- ollama = detectOllama();
127
+ ollama = cached ? memoizedDetectOllama() : detectOllama();
188
128
  } catch (e) {
189
129
  error = `ollama detection failed: ${e instanceof Error ? e.message : String(e)}`;
190
130
  }
191
131
 
192
132
  try {
193
- llamaCpp = detectLlamaCpp();
133
+ llamaCpp = cached ? memoizedDetectLlamaCpp() : detectLlamaCpp();
194
134
  } catch (e) {
195
135
  error = error ?? `llama.cpp detection failed: ${e instanceof Error ? e.message : String(e)}`;
196
136
  }
197
137
 
198
138
  try {
199
- onnx = detectOnnx();
139
+ onnx = cached ? memoizedDetectOnnx() : detectOnnx();
200
140
  } catch (e) {
201
141
  error = error ?? `onnx detection failed: ${e instanceof Error ? e.message : String(e)}`;
202
142
  }
@@ -0,0 +1,181 @@
1
+ /**
2
+ * mega-config-types.ts — MegaConfig type-only declarations for the extension.
3
+ *
4
+ * Split out of mega-config.ts (delegate-shell) so the runtime barrel stays under
5
+ * the extensions/ soft line limit. Type-only file: no runtime code, no logic.
6
+ * `import type` keeps the only cross-reference (CompactTier) erased at build,
7
+ * so there is no runtime import cycle.
8
+ */
9
+ import type { CompactTier } from "./mega-config.js";
10
+
11
+ /**
12
+ * Resolved, frozen-at-load config. `tier` is the base compaction PRESET chosen
13
+ * by env (low/medium/high/ultra/mega) — it sets the threshold token budget and
14
+ * is NOT changed at runtime (the /mega-tier command was removed in S24). The
15
+ * *displayed* tier the user sees in the toolbar/dashboard is the LIVE pressure
16
+ * band (see MegaRuntime.pressureBand), which climbs low→mega as context fills.
17
+ */
18
+ export interface MegaConfig {
19
+ tier: CompactTier | "custom";
20
+ /**
21
+ * Compaction threshold as a fraction of the model context window (e.g. 0.70
22
+ * for "high"). null for `custom` (explicit MEGACOMPACT_THRESHOLD_TOKENS, which
23
+ * stays an ABSOLUTE token count, never percent-scaled).
24
+ */
25
+ tierPct: number | null;
26
+ thresholdTokens: number;
27
+ stateDir: string;
28
+ fastGatePct: number;
29
+ anchorUserMessages: number;
30
+ preserveRecent: number;
31
+ /** High-pressure floor for preserveRecent — when context is near the limit
32
+ * we compact deeper, but never below this (keeps recent turns for coherence). */
33
+ preserveRecentMin: number;
34
+ /** D.1: minimum context-growth percentage delta before re-compacting instead of
35
+ * replaying the cached trim (Default 50). Set via MEGACOMPACT_RECOMPACT_PCT_DELTA.*/
36
+ recompactPctDelta: number;
37
+ auto: boolean;
38
+ autoInline: boolean;
39
+ autoInlineK: number;
40
+ /** S28: auto-continue the agent after a max-output-token length stop by
41
+ * reusing the existing S16 resume-nudge. Default true. Off = silent (the
42
+ * prior behavior). PREVENT-PI-003: restart via user-role sendUserMessage. */
43
+ autoContinueLengthStop: boolean;
44
+ /** S38: max retries for transient errors (5xx/429/network/max-output-token
45
+ * text that is NOT a length stopReason — S28 owns those). Default 5.
46
+ * `0` disables all transient retries (reverts to S28-only). */
47
+ autoRetryTransientMax: number;
48
+ /** S38: max retries for permanent errors (auth/config/malformed). Default 1.
49
+ * `0` disables permanent-error retries. */
50
+ autoRetryPermanentMax: number;
51
+ /** S38.5: strict race-guard — 30s cooldown + deferred ctx.compact() re-check
52
+ * (closes the first-race-in-burst window). Default true. `false` reverts to
53
+ * the v0.7.4 synchronous 10s-cooldown behavior. */
54
+ raceGuardStrict: boolean;
55
+ /** S38.6: max consecutive errors before circuit-breaker trips (stops retrying).
56
+ * Default 10. When `errorRetryCount` exceeds this across multiple turns,
57
+ * the extension stops retrying until a successful turn resets it. */
58
+ maxConsecutiveErrors: number;
59
+ /** S38.7: hard-stop switch — when true, ALL error retries are disabled.
60
+ * Default false. Set via env to force S28-only behavior (length-stop continues
61
+ * only). */
62
+ errorRetryHardStop: boolean;
63
+ /** R1 (retry redesign): base unit (ms) for errorRetryBackoffMs(count) pacing.
64
+ * The schedule is base, 2*base, 4*base, 6*base (cap) — so the default 5000
65
+ * yields 5s/10s/20s/30s. errorRetryUntil is now GATING (previously it was
66
+ * documented as non-gating); a nudge cannot fire before errorRetryUntil
67
+ * elapses. */
68
+ errorRetryBackoffMs: number;
69
+ /** R2: session-global cap on total S38 nudges across ALL bursts. Hitting it
70
+ * is terminal for the session — the extension stops nudging entirely,
71
+ * independent of the per-burst max and the circuit breaker. Default 3.
72
+ * `0` disables (reverts to per-burst + circuit-breaker only). */
73
+ errorRetrySessionMax: number;
74
+ /** R3: consecutive identical error-text count at which a 'transient'
75
+ * classification is upgraded to 'poisoned-context' (the stateful repeat
76
+ * signal). Default 3. Raise to make the upgrade less aggressive. */
77
+ poisonedContextRepeatThreshold: number;
78
+ /** R10: consecutive transient errors at which a calm "provider outage"
79
+ * advisory is sent to the user (distinct from the poisoned /clear advise).
80
+ * Default 3. `0` disables the advisory entirely. */
81
+ providerOutageAdviseThreshold: number;
82
+ /** R13: when true (default), poisoned-context and provider-outage advisories
83
+ * are dashboard-only (events tab + log) — no user-visible message injection.
84
+ * When false, the legacy sendUserMessage path runs (byte-identical pre-R13). */
85
+ advisoryChannel: boolean;
86
+ /** S29: override the auto-compact fire point for tiered configs, as a
87
+ * fraction of the context window (e.g. 0.85). null = inherit the tier's
88
+ * tierPct (default; preserves existing fire points). The context-handler
89
+ * gate fires on context % (reliable), not token count (under-reported),
90
+ * so it catches the overshoot that causes max-output-token truncation.
91
+ * `custom` (tierPct null) ignores this — it keeps the absolute token gate. */
92
+ autoPctTrigger: number | null;
93
+ dedupSim: number;
94
+ /** RAPTOR hierarchical recall enabled (Fix D). Drives both live recall and
95
+ * the durable-trim summary source (root summary). */
96
+ raptorEnabled: boolean;
97
+ /** Legacy v0.4.28 behavior: auto-trigger calls ctx.compact() (which STOPS
98
+ * the agent). Default false — the S16 redesign uses the live context-event
99
+ * trim + pi native auto-compaction instead (compact and continue). Kept for
100
+ * one release as rollback. */
101
+ legacyDurableTrim: boolean;
102
+ /** S27: durable raw-transcript DB mirror (MEGACOMPACT_DB_MIRROR). When on,
103
+ * raw message bytes + checkpoint-epoch bookkeeping are appended to the
104
+ * SQLite store so a compacted window can be rehydrated locally instead of
105
+ * from the pi runtime transcript. Default OFF — additive, no behavior
106
+ * change until flipped on. legacyDurableTrim takes precedence (the legacy
107
+ * v0.4.28 ctx.compact() path does not emit the S27 mirror hook). */
108
+ dbMirror: boolean;
109
+ /** S49: isolated per-turn store (turns.db). Default ON. OFF = legacy main-db
110
+ * turn path (S48 behavior — byte-identical). Mirrors TurnsConfig.TURNS_DB_ENABLED. */
111
+ turnsDbEnabled: boolean;
112
+ /** S51: auto-categorizing wiki (k-means + TF-IDF over real embeddings). Default ON.
113
+ * Mirrors TurnsConfig.AUTO_WIKI_ENABLED. Rebuild fires every Nth compaction. */
114
+ autoWikiEnabled: boolean;
115
+ /** Cross-repo recall enabled (S17). Resume + /mega-recall --cross-repo can
116
+ * pull checkpoints from OTHER repos via the PGlite HNSW index. Default true. */
117
+ crossRepoEnabled: boolean;
118
+ /** Stricter cosine floor for cross-repo hits (S17). Default 0.90 (trigram) /
119
+ * tighter than same-repo so only genuinely-relevant cross-repo context is
120
+ * injected. */
121
+ crossRepoCosine: number;
122
+ /** Memory-RAG auto-review enabled (S20). Every memoryReviewInterval turns the
123
+ * conversation is auto-reviewed into durable add/replace/remove memories. */
124
+ memoryAutoReview: boolean;
125
+ /** Turn cadence for the auto-review scan (S20). Default 10. */
126
+ memoryReviewInterval: number;
127
+ /** Token ceiling for the re-injected recall block (Fix C). Recall stops
128
+ * adding checkpoints once the block would exceed this — bounds read-path
129
+ * token cost so it can never net-inflate the window. */
130
+ recallMaxTokens: number;
131
+ /** Inline-dedupe recalled checkpoints against the live window (Fix C): drop
132
+ * a hit whose summary is ≥ dedupSim similar to a live message — "dedupe on
133
+ * inline/read" so we never re-inject context already resident. */
134
+ windowDedupe: boolean;
135
+ /** S53: Recall Tail Injection — inject staged recall block as a user message at
136
+ * the tail of the view when auto is OFF AND no trim action is needed. Default ON
137
+ * (true). When false, restores the pre-sprint systemPrompt prepend behavior. */
138
+ recallTailInject: boolean;
139
+ /** A1 PLAN_V2 Phase 2: Message Separation — isolate user/assistant turns
140
+ * from volatile tool results so the prompt-cache prefix stays stable.
141
+ * PC-A: positive sprint flag, now default ON; flag-OFF (=0) is byte-identical
142
+ * to the pre-change OFF state. The single gate lives at the call site
143
+ * (tailResult.ts, config.messageSeparation), not inside buildSeparatedPrompt. */
144
+ messageSeparation: boolean;
145
+ /** P3: Cache-aware striping (PLAN_V2 Phase 3). Inserts stability-ordered
146
+ * cache stripes between summaries and thread. Default OFF. */
147
+ cacheStriping: boolean;
148
+ debug: boolean;
149
+ /** Master reconciliation: TUI shutdown widget (MEGACOMPACT_TUI_WIDGET=0 to disable). */
150
+ tuiWidget: boolean;
151
+ /** S57 B1: Query reformulation via embedding-neighbor keyword expansion. */
152
+ ragQueryReformulation: boolean;
153
+ /** S57 B2: Tiered recall router (L0 cache -> L1 FTS5 -> L2). */
154
+ ragTieredRouter: boolean;
155
+ /** S57 B3: Recall quality metrics (precision/recall scoring + logging). */
156
+ ragRecallMetrics: boolean;
157
+ /** S57 B4: Memory graph traversal (dashboard-oriented). */
158
+ ragMemoryGraph: boolean;
159
+ /** D1: Seed initial wiki topic model from live turns when no context_chunks exist yet. */
160
+ wikiSeedFromTurns: boolean;
161
+ /** D3 Source A: Include structural turn nodes in the memory graph (metadata only, no content). */
162
+ memoryGraphSeedTurns: boolean;
163
+ /** D3 Source B: Include raw_transcript content nodes in the memory graph (requires dbMirror). */
164
+ memoryGraphSeedTurnContent: boolean;
165
+ /** D3 Source C: Include memory review nodes in the memory graph. */
166
+ memoryGraphSeedMemories: boolean;
167
+ /** D3 edges: Stricter cosine floor for cross-type edges (e.g. turn↔checkpoint). */
168
+ memoryGraphCrossTypeThreshold: number;
169
+ /** D3 edges: Cosine floor for within-type semantic edges. */
170
+ memoryGraphWithinTypeThreshold: number;
171
+ /** v0.12: Context health monitoring (drift + output quality + cache poison). Default ON. */
172
+ contextHealth: boolean;
173
+ /** Sub-flag: drift detection (topic drift + error escalation + prefix instability). */
174
+ contextHealthDrift: boolean;
175
+ /** Sub-flag: output quality analysis (repetition, coherence, token salad). */
176
+ contextHealthOutputQuality: boolean;
177
+ /** Sub-flag: tri-layer KV cache poison validation. */
178
+ contextHealthCachePoison: boolean;
179
+ /** v0.12: KV cache poison mitigation — inject prefix break on mismatch. Default OFF. */
180
+ contextHealthMitigate: boolean;
181
+ }