pi-mega-compact 0.20.21 → 0.20.23
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/resolve-snapshot.js +42 -28
- package/dist/extensions/dashboard-server/routes-setup.js +4 -1
- package/dist/extensions/dashboard-server/routes-vector-cortex-crystals.js +11 -3
- package/dist/extensions/dashboard-server/routes-vector-cortex-diagnostics.js +7 -2
- package/dist/extensions/dashboard-server/routes-vector-cortex-economics.js +1 -0
- package/dist/extensions/dashboard-server/routes-vector-cortex-heal.js +18 -6
- package/dist/extensions/dashboard-server/routes-vector-cortex-policy.js +1 -0
- package/dist/extensions/dashboard-server/routes-vector-cortex-reconstruct.js +10 -3
- package/dist/extensions/dashboard-server/routes-vector-cortex-repair.js +13 -5
- package/dist/extensions/dashboard-server/routes-vector-cortex-shards.js +12 -4
- package/dist/extensions/dashboard-server/vc-event-counts.js +63 -0
- package/dist/extensions/mega-events/context-handler/afterCompact.js +34 -0
- package/dist/extensions/mega-events/context-handler/pipelineRun.js +33 -0
- package/dist/extensions/mega-runtime/dashboard-snapshot.js +9 -6
- package/dist/extensions/mega-runtime/runtime-snapshot.js +2 -0
- package/dist/extensions/mega-runtime/vc-observer.js +98 -0
- package/dist/src/vector-cortex/platform/_cross-language-fixture.js +57 -0
- package/dist/vector-cortex/platform/_cross-language-fixture.js +57 -0
- package/extensions/dashboard-client/dist/assets/{AreaChart-BkfB-LSQ.js → AreaChart-BzEedilo.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{AreaChart-BkfB-LSQ.js.map → AreaChart-BzEedilo.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{BarChart-Cs1kogko.js → BarChart-CzAVg1_J.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{BarChart-Cs1kogko.js.map → BarChart-CzAVg1_J.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{CacheTab-BZgaguGr.js → CacheTab-D2-rzTuX.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{CacheTab-BZgaguGr.js.map → CacheTab-D2-rzTuX.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{EventsTab-BFbkI_MO.js → EventsTab-DB7g1Szy.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{EventsTab-BFbkI_MO.js.map → EventsTab-DB7g1Szy.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{HealthTab-CvlOENCX.js → HealthTab-Cvkmi-R3.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{HealthTab-CvlOENCX.js.map → HealthTab-Cvkmi-R3.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MaintenanceTab-CtBuz2qL.js → MaintenanceTab-g_udcOO7.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MaintenanceTab-CtBuz2qL.js.map → MaintenanceTab-g_udcOO7.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MemoryMapTab-K4775S4d.js → MemoryMapTab-DAjBaf8P.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MemoryMapTab-K4775S4d.js.map → MemoryMapTab-DAjBaf8P.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MetricsTab-DVGcFInz.js → MetricsTab-13dYYocB.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MetricsTab-DVGcFInz.js.map → MetricsTab-13dYYocB.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{OverviewTab-4LmW5ZCl.js → OverviewTab-CLpCyLvx.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{OverviewTab-4LmW5ZCl.js.map → OverviewTab-CLpCyLvx.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{ReposTab-StebchgQ.js → ReposTab-EdAqUrwG.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{ReposTab-StebchgQ.js.map → ReposTab-EdAqUrwG.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{SessionsTab-C3D_XAkX.js → SessionsTab-C21ZuOL_.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{SessionsTab-C3D_XAkX.js.map → SessionsTab-C21ZuOL_.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/SetupTab-CP7lE3L_.js +2 -0
- package/extensions/dashboard-client/dist/assets/SetupTab-CP7lE3L_.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/{TimeSavedCard-CTPi_AAW.js → TimeSavedCard-DZ3QR8qt.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{TimeSavedCard-CTPi_AAW.js.map → TimeSavedCard-DZ3QR8qt.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{TurnsTab-DSOGcY5Q.js → TurnsTab-CNchE5rD.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{TurnsTab-DSOGcY5Q.js.map → TurnsTab-CNchE5rD.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{VectorCortexTab-OMW8_RFf.js → VectorCortexTab-B3WuPeyn.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{VectorCortexTab-OMW8_RFf.js.map → VectorCortexTab-B3WuPeyn.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{WikiTab-Db-qFDdg.js → WikiTab-BIe5Z9Nc.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{WikiTab-Db-qFDdg.js.map → WikiTab-BIe5Z9Nc.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{button-BF4UgBAD.js → button-BrVreSt5.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{button-BF4UgBAD.js.map → button-BrVreSt5.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{card-XmXoYQqB.js → card-D9F4wbqs.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{card-XmXoYQqB.js.map → card-D9F4wbqs.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-Be8hM1aU.js → generateCategoricalChart-mkdzCnMP.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-Be8hM1aU.js.map → generateCategoricalChart-mkdzCnMP.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{index-NXDgILxv.js → index-CtlmOlj1.js} +3 -3
- package/extensions/dashboard-client/dist/assets/{index-NXDgILxv.js.map → index-CtlmOlj1.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{switch-kUZCrbia.js → switch-BXmp5iwA.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{switch-kUZCrbia.js.map → switch-BXmp5iwA.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{toggle-DEe5mCwF.js → toggle-BgawNwW9.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{toggle-DEe5mCwF.js.map → toggle-BgawNwW9.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{useSSE-BlCyLqge.js → useSSE-DZKX73Ea.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{useSSE-BlCyLqge.js.map → useSSE-DZKX73Ea.js.map} +1 -1
- package/extensions/dashboard-client/dist/index.html +1 -1
- package/extensions/dashboard-client/src/tabs/SetupTab/CustomEndpointSection.tsx +65 -0
- package/extensions/dashboard-client/src/tabs/SetupTab/EmbedderSetup.tsx +19 -108
- package/extensions/dashboard-client/src/tabs/SetupTab/EmbedderSetupStyles.ts +69 -0
- package/extensions/dashboard-client/src/tabs/VectorCortexTab.tsx +5 -3
- package/extensions/dashboard-server/api-contracts/setup.ts +4 -3
- package/extensions/dashboard-server/api-contracts/vector-cortex-cache.ts +5 -0
- package/extensions/dashboard-server/api-contracts/vector-cortex-diagnostics.ts +2 -0
- package/extensions/dashboard-server/api-contracts/vector-cortex-economics.ts +2 -0
- package/extensions/dashboard-server/api-contracts/vector-cortex-policy.ts +2 -0
- package/extensions/dashboard-server/resolve-snapshot.ts +42 -28
- package/extensions/dashboard-server/routes-setup.ts +3 -1
- package/extensions/dashboard-server/routes-vector-cortex-crystals.ts +12 -3
- package/extensions/dashboard-server/routes-vector-cortex-diagnostics.ts +8 -2
- package/extensions/dashboard-server/routes-vector-cortex-economics.ts +1 -0
- package/extensions/dashboard-server/routes-vector-cortex-heal.ts +19 -6
- package/extensions/dashboard-server/routes-vector-cortex-policy.ts +1 -0
- package/extensions/dashboard-server/routes-vector-cortex-reconstruct.ts +11 -3
- package/extensions/dashboard-server/routes-vector-cortex-repair.ts +14 -5
- package/extensions/dashboard-server/routes-vector-cortex-shards.ts +13 -4
- package/extensions/dashboard-server/vc-event-counts.ts +67 -0
- package/extensions/mega-dashboard.ts +2 -0
- package/extensions/mega-events/context-handler/afterCompact.ts +46 -0
- package/extensions/mega-events/context-handler/pipelineRun.ts +39 -0
- package/extensions/mega-runtime/dashboard-snapshot.ts +12 -6
- package/extensions/mega-runtime/runtime-snapshot.ts +6 -0
- package/extensions/mega-runtime/vc-observer.ts +120 -0
- package/package.json +1 -1
- package/src/vector-cortex/platform/_cross-language-fixture.ts +83 -0
- package/extensions/dashboard-client/dist/assets/SetupTab-BTBGyppF.js +0 -2
- package/extensions/dashboard-client/dist/assets/SetupTab-BTBGyppF.js.map +0 -1
|
@@ -14,69 +14,8 @@ import type { SetupStatusResponse, SetupDetectResponse, SetupConfigureResponse }
|
|
|
14
14
|
import { fetchSetupStatus, fetchSetupDetect, configureEmbedder } from "../../api/client";
|
|
15
15
|
import EmbedderHealthCard from "./EmbedderHealthCard";
|
|
16
16
|
import SettingsPanel from "./SettingsPanel";
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
container: {
|
|
20
|
-
padding: "1rem",
|
|
21
|
-
maxWidth: "720px",
|
|
22
|
-
margin: "0 auto",
|
|
23
|
-
fontFamily: "system-ui, sans-serif",
|
|
24
|
-
color: "#e0e0e0",
|
|
25
|
-
},
|
|
26
|
-
section: {
|
|
27
|
-
background: "#1a1a2e",
|
|
28
|
-
borderRadius: "8px",
|
|
29
|
-
padding: "1rem",
|
|
30
|
-
marginBottom: "1rem",
|
|
31
|
-
border: "1px solid #2a2a4e",
|
|
32
|
-
},
|
|
33
|
-
sectionTitle: {
|
|
34
|
-
fontSize: "1.1rem",
|
|
35
|
-
fontWeight: 700,
|
|
36
|
-
marginTop: 0,
|
|
37
|
-
marginBottom: "0.75rem",
|
|
38
|
-
color: "#e0e0e0",
|
|
39
|
-
borderBottom: "1px solid #333",
|
|
40
|
-
paddingBottom: "0.5rem",
|
|
41
|
-
},
|
|
42
|
-
label: { fontWeight: 600, color: "#a0a0c0", marginRight: "0.5rem" },
|
|
43
|
-
value: { color: "#e0e0e0" },
|
|
44
|
-
row: { marginBottom: "0.4rem", fontSize: "0.9rem" },
|
|
45
|
-
warning: {
|
|
46
|
-
background: "#3a2a00",
|
|
47
|
-
border: "1px solid #665500",
|
|
48
|
-
borderRadius: "8px",
|
|
49
|
-
padding: "0.75rem",
|
|
50
|
-
marginTop: "0.5rem",
|
|
51
|
-
color: "#ffcc00",
|
|
52
|
-
fontSize: "0.85rem",
|
|
53
|
-
},
|
|
54
|
-
badge: {
|
|
55
|
-
display: "inline-block",
|
|
56
|
-
padding: "0.15rem 0.5rem",
|
|
57
|
-
borderRadius: "4px",
|
|
58
|
-
fontSize: "0.8rem",
|
|
59
|
-
fontWeight: 600,
|
|
60
|
-
marginLeft: "0.5rem",
|
|
61
|
-
},
|
|
62
|
-
detectRow: {
|
|
63
|
-
display: "flex",
|
|
64
|
-
justifyContent: "space-between",
|
|
65
|
-
alignItems: "center",
|
|
66
|
-
padding: "0.5rem 0",
|
|
67
|
-
borderBottom: "1px solid #2a2a4e",
|
|
68
|
-
},
|
|
69
|
-
button: {
|
|
70
|
-
background: "#3a5a9f",
|
|
71
|
-
color: "#fff",
|
|
72
|
-
border: "none",
|
|
73
|
-
borderRadius: "6px",
|
|
74
|
-
padding: "0.5rem 1rem",
|
|
75
|
-
cursor: "pointer",
|
|
76
|
-
fontSize: "0.9rem",
|
|
77
|
-
fontWeight: 600,
|
|
78
|
-
},
|
|
79
|
-
};
|
|
17
|
+
import CustomEndpointSection from "./CustomEndpointSection";
|
|
18
|
+
import { styles } from "./EmbedderSetupStyles";
|
|
80
19
|
|
|
81
20
|
export default function EmbedderSetup(): React.ReactElement {
|
|
82
21
|
const [status, setStatus] = useState<SetupStatusResponse | null>(null);
|
|
@@ -97,7 +36,7 @@ export default function EmbedderSetup(): React.ReactElement {
|
|
|
97
36
|
);
|
|
98
37
|
}, []);
|
|
99
38
|
|
|
100
|
-
const applyEmbedder = useCallback((embedder: "ollama" | "llama" | "trigram" | "custom", url?: string) => {
|
|
39
|
+
const applyEmbedder = useCallback((embedder: "ollama" | "llama" | "trigram" | "custom" | "onnx", url?: string) => {
|
|
101
40
|
setConfiguring(embedder);
|
|
102
41
|
setConfigError(null);
|
|
103
42
|
setConfigResult(null);
|
|
@@ -368,6 +307,13 @@ export default function EmbedderSetup(): React.ReactElement {
|
|
|
368
307
|
>
|
|
369
308
|
{configuring === "llama" ? "Writing..." : "Use llama.cpp"}
|
|
370
309
|
</button>
|
|
310
|
+
<button
|
|
311
|
+
style={{ ...styles.button, opacity: detect.onnx?.installed ? 1 : 0.4 }}
|
|
312
|
+
onClick={() => applyEmbedder("onnx")}
|
|
313
|
+
disabled={!detect.onnx?.installed || configuring !== null}
|
|
314
|
+
>
|
|
315
|
+
{configuring === "onnx" ? "Writing..." : "Use ONNX"}
|
|
316
|
+
</button>
|
|
371
317
|
<button
|
|
372
318
|
style={{ ...styles.button, background: "#444" }}
|
|
373
319
|
onClick={() => applyEmbedder("trigram")}
|
|
@@ -393,47 +339,12 @@ export default function EmbedderSetup(): React.ReactElement {
|
|
|
393
339
|
</div>
|
|
394
340
|
|
|
395
341
|
{/* Custom (remote) embedder — third-party / hosted endpoint */}
|
|
396
|
-
<
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
embedding requests will be sent to the URL you enter. Default is
|
|
403
|
-
loopback-only.
|
|
404
|
-
</p>
|
|
405
|
-
<div style={{ display: "flex", gap: "0.5rem", flexWrap: "wrap", alignItems: "center" }}>
|
|
406
|
-
<input
|
|
407
|
-
type="url"
|
|
408
|
-
placeholder="https://api.example.com/v1/embeddings"
|
|
409
|
-
value={customUrl}
|
|
410
|
-
onChange={(e) => setCustomUrl(e.target.value)}
|
|
411
|
-
style={{
|
|
412
|
-
flex: "1 1 300px",
|
|
413
|
-
background: "#12122a",
|
|
414
|
-
color: "#e0e0e0",
|
|
415
|
-
border: "1px solid #2a2a4e",
|
|
416
|
-
borderRadius: "6px",
|
|
417
|
-
padding: "0.4rem 0.6rem",
|
|
418
|
-
fontSize: "0.85rem",
|
|
419
|
-
fontFamily: "monospace",
|
|
420
|
-
}}
|
|
421
|
-
/>
|
|
422
|
-
<button
|
|
423
|
-
style={{ ...styles.button, opacity: customUrl ? 1 : 0.4 }}
|
|
424
|
-
onClick={() => applyEmbedder("custom", customUrl)}
|
|
425
|
-
disabled={!customUrl || configuring !== null}
|
|
426
|
-
>
|
|
427
|
-
{configuring === "custom" ? "Writing..." : "Use Custom URL"}
|
|
428
|
-
</button>
|
|
429
|
-
</div>
|
|
430
|
-
<div style={styles.warning}>
|
|
431
|
-
<strong>Heads up:</strong> a remote endpoint receives the text you embed
|
|
432
|
-
(it does NOT receive your full conversation — only the strings passed to
|
|
433
|
-
<code> embed()</code> for recall/dedup). Verify the endpoint's privacy
|
|
434
|
-
policy before use.
|
|
435
|
-
</div>
|
|
436
|
-
</div>
|
|
342
|
+
<CustomEndpointSection
|
|
343
|
+
customUrl={customUrl}
|
|
344
|
+
setCustomUrl={setCustomUrl}
|
|
345
|
+
applyEmbedder={applyEmbedder}
|
|
346
|
+
configuring={configuring}
|
|
347
|
+
/>
|
|
437
348
|
|
|
438
349
|
{/* Help Section */}
|
|
439
350
|
<div style={styles.section}>
|
|
@@ -458,9 +369,9 @@ export default function EmbedderSetup(): React.ReactElement {
|
|
|
458
369
|
the URL accordingly.
|
|
459
370
|
</li>
|
|
460
371
|
<li>
|
|
461
|
-
<strong>ONNX Runtime:</strong>
|
|
462
|
-
<
|
|
463
|
-
|
|
372
|
+
<strong>ONNX Runtime:</strong> Run a local text-embeddings
|
|
373
|
+
server (e.g. TEI) and click <strong>Use ONNX</strong> above.
|
|
374
|
+
Default URL: <code>http://localhost:8081/v1/embeddings</code>.
|
|
464
375
|
</li>
|
|
465
376
|
</ul>
|
|
466
377
|
</div>
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SetupTab/EmbedderSetupStyles.ts — extracted styles for EmbedderSetup.
|
|
3
|
+
*
|
|
4
|
+
* Split from EmbedderSetup.tsx to respect the extensions/ 400-line soft limit.
|
|
5
|
+
*/
|
|
6
|
+
import type React from "react";
|
|
7
|
+
|
|
8
|
+
export const styles: Record<string, React.CSSProperties> = {
|
|
9
|
+
container: {
|
|
10
|
+
padding: "1rem",
|
|
11
|
+
maxWidth: "720px",
|
|
12
|
+
margin: "0 auto",
|
|
13
|
+
fontFamily: "system-ui, sans-serif",
|
|
14
|
+
color: "#e0e0e0",
|
|
15
|
+
},
|
|
16
|
+
section: {
|
|
17
|
+
background: "#1a1a2e",
|
|
18
|
+
borderRadius: "8px",
|
|
19
|
+
padding: "1rem",
|
|
20
|
+
marginBottom: "1rem",
|
|
21
|
+
border: "1px solid #2a2a4e",
|
|
22
|
+
},
|
|
23
|
+
sectionTitle: {
|
|
24
|
+
fontSize: "1.1rem",
|
|
25
|
+
fontWeight: 700,
|
|
26
|
+
marginTop: 0,
|
|
27
|
+
marginBottom: "0.75rem",
|
|
28
|
+
color: "#e0e0e0",
|
|
29
|
+
borderBottom: "1px solid #333",
|
|
30
|
+
paddingBottom: "0.5rem",
|
|
31
|
+
},
|
|
32
|
+
label: { fontWeight: 600, color: "#a0a0c0", marginRight: "0.5rem" },
|
|
33
|
+
value: { color: "#e0e0e0" },
|
|
34
|
+
row: { marginBottom: "0.4rem", fontSize: "0.9rem" },
|
|
35
|
+
warning: {
|
|
36
|
+
background: "#3a2a00",
|
|
37
|
+
border: "1px solid #665500",
|
|
38
|
+
borderRadius: "8px",
|
|
39
|
+
padding: "0.75rem",
|
|
40
|
+
marginTop: "0.5rem",
|
|
41
|
+
color: "#ffcc00",
|
|
42
|
+
fontSize: "0.85rem",
|
|
43
|
+
},
|
|
44
|
+
badge: {
|
|
45
|
+
display: "inline-block",
|
|
46
|
+
padding: "0.15rem 0.5rem",
|
|
47
|
+
borderRadius: "4px",
|
|
48
|
+
fontSize: "0.8rem",
|
|
49
|
+
fontWeight: 600,
|
|
50
|
+
marginLeft: "0.5rem",
|
|
51
|
+
},
|
|
52
|
+
detectRow: {
|
|
53
|
+
display: "flex",
|
|
54
|
+
justifyContent: "space-between",
|
|
55
|
+
alignItems: "center",
|
|
56
|
+
padding: "0.5rem 0",
|
|
57
|
+
borderBottom: "1px solid #2a2a4e",
|
|
58
|
+
},
|
|
59
|
+
button: {
|
|
60
|
+
background: "#3a5a9f",
|
|
61
|
+
color: "#fff",
|
|
62
|
+
border: "none",
|
|
63
|
+
borderRadius: "6px",
|
|
64
|
+
padding: "0.5rem 1rem",
|
|
65
|
+
cursor: "pointer",
|
|
66
|
+
fontSize: "0.9rem",
|
|
67
|
+
fontWeight: 600,
|
|
68
|
+
},
|
|
69
|
+
};
|
|
@@ -77,10 +77,12 @@ export default function VectorCortexTab(): React.ReactElement {
|
|
|
77
77
|
<div className="flex flex-col gap-4">
|
|
78
78
|
<div className="flex items-center gap-2">
|
|
79
79
|
<h2 className="text-lg font-semibold">Vector Cortex Evaluation</h2>
|
|
80
|
-
{data.enabled ? (
|
|
81
|
-
<Badge variant="warning">OBSERVER PENDING (A)</Badge>
|
|
82
|
-
) : (
|
|
80
|
+
{!data.enabled ? (
|
|
83
81
|
<Badge variant="danger">MODE C (OFF)</Badge>
|
|
82
|
+
) : data.samples === 0 ? (
|
|
83
|
+
<Badge variant="warning">OBSERVER (A) — NO SAMPLES YET</Badge>
|
|
84
|
+
) : (
|
|
85
|
+
<Badge variant="success">OBSERVER (A) — {data.samples} SAMPLES</Badge>
|
|
84
86
|
)}
|
|
85
87
|
</div>
|
|
86
88
|
|
|
@@ -67,9 +67,10 @@ export interface SetupDetectResponse {
|
|
|
67
67
|
export interface SetupConfigureRequest {
|
|
68
68
|
/** Which embedder to configure. "trigram" clears the URL (uses built-in).
|
|
69
69
|
* "custom" writes a user-supplied URL and opts in to non-loopback endpoints
|
|
70
|
-
* (sets MEGACOMPACT_ALLOW_REMOTE_EMBEDDER=1) for third-party / hosted APIs.
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
* (sets MEGACOMPACT_ALLOW_REMOTE_EMBEDDER=1) for third-party / hosted APIs.
|
|
71
|
+
* "onnx" points at a local ONNX text-embeddings-inference server. */
|
|
72
|
+
readonly embedder: "ollama" | "llama" | "trigram" | "custom" | "onnx";
|
|
73
|
+
/** Override URL (required for "custom"; optional defaults for ollama/llama/onnx). */
|
|
73
74
|
readonly url?: string;
|
|
74
75
|
}
|
|
75
76
|
|
|
@@ -50,4 +50,9 @@ export interface VectorCortexCrystalsView {
|
|
|
50
50
|
readonly lastFailure: string | null;
|
|
51
51
|
/** ISO timestamp of the snapshot. */
|
|
52
52
|
readonly updatedAt: string;
|
|
53
|
+
/**
|
|
54
|
+
* Present when the underlying subsystem is not fully wired yet, explaining
|
|
55
|
+
* why emit-only counters are reported instead of live cache-serve integration.
|
|
56
|
+
*/
|
|
57
|
+
readonly deferredReason?: string;
|
|
53
58
|
}
|
|
@@ -69,6 +69,8 @@ export interface VectorCortexDiagnosticsView {
|
|
|
69
69
|
readonly serveBlocked: number;
|
|
70
70
|
/** Observable cache-breaker state (a state name, not a payload). */
|
|
71
71
|
readonly breakerState: string;
|
|
72
|
+
/** Present when the miss-classifier is not yet wired, with a reason. */
|
|
73
|
+
readonly deferredReason?: string;
|
|
72
74
|
/** Last diagnostics rejection reason (a CACHE or M5 code), or null. */
|
|
73
75
|
readonly lastFailure: string | null;
|
|
74
76
|
/** ISO timestamp of the snapshot. */
|
|
@@ -44,4 +44,6 @@ export interface VectorCortexEconomicsView {
|
|
|
44
44
|
readonly lastFailure: string | null;
|
|
45
45
|
/** ISO timestamp of the snapshot. */
|
|
46
46
|
readonly updatedAt: string;
|
|
47
|
+
/** Present when the economic aggregate is not yet computed, with a reason. */
|
|
48
|
+
readonly deferredReason?: string;
|
|
47
49
|
}
|
|
@@ -33,4 +33,6 @@ export interface VectorCortexPolicyView {
|
|
|
33
33
|
readonly lastFailure: string | null;
|
|
34
34
|
/** ISO timestamp of the snapshot. */
|
|
35
35
|
readonly updatedAt: string;
|
|
36
|
+
/** Present when the shadow controller is not yet instantiated, with a reason. */
|
|
37
|
+
readonly deferredReason?: string;
|
|
36
38
|
}
|
|
@@ -8,16 +8,14 @@
|
|
|
8
8
|
* Resolution order (the launch dir is the OWNer of this dashboard):
|
|
9
9
|
* 1. The launch stateDir's OWN dashboard.json — the pi process that launched
|
|
10
10
|
* this dashboard server is the session you are coding in, so its snapshot
|
|
11
|
-
* is "this session" by definition.
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* the launch dir has no live snapshot yet (e.g. dashboard launched before
|
|
20
|
-
* any compaction wrote dashboard.json).
|
|
11
|
+
* is "this session" by definition. It must be fresh (updatedAt within
|
|
12
|
+
* STALE_MS) to win; otherwise the launch dir's pi process has exited or
|
|
13
|
+
* stopped snapshotting, and showing its stale data as "this session" is
|
|
14
|
+
* misleading. When stale, fall through to the most-recently-active repo.
|
|
15
|
+
* 2. Most recently seen repo (by last_seen in repo_registry) whose
|
|
16
|
+
* dashboard.json exists and has a non-null updatedAt — this includes the
|
|
17
|
+
* launch dir via the registry, so an exited-but-recent launch session
|
|
18
|
+
* still appears.
|
|
21
19
|
* 3. The static launch stateDir's dashboard.json (original behavior).
|
|
22
20
|
*/
|
|
23
21
|
|
|
@@ -34,6 +32,19 @@ export interface ResolvedSnapshot {
|
|
|
34
32
|
stateDir: string;
|
|
35
33
|
}
|
|
36
34
|
|
|
35
|
+
/** Snapshots older than this are stale — the owning pi session has exited or
|
|
36
|
+
* stopped snapshotting. 5 minutes covers the slowest possible context event
|
|
37
|
+
* cadence + debounce + snapshot throttle. */
|
|
38
|
+
const STALE_MS = 5 * 60 * 1000;
|
|
39
|
+
|
|
40
|
+
/** Age of a snapshot's updatedAt in ms. Returns Infinity for invalid dates. */
|
|
41
|
+
function snapshotAgeMs(updatedAt: string | null | undefined): number {
|
|
42
|
+
if (!updatedAt) return Infinity;
|
|
43
|
+
const t = Date.parse(updatedAt);
|
|
44
|
+
if (Number.isNaN(t)) return Infinity;
|
|
45
|
+
return Date.now() - t;
|
|
46
|
+
}
|
|
47
|
+
|
|
37
48
|
const require = createRequire(import.meta.url);
|
|
38
49
|
|
|
39
50
|
interface RepoRegistryRow {
|
|
@@ -42,12 +53,14 @@ interface RepoRegistryRow {
|
|
|
42
53
|
}
|
|
43
54
|
|
|
44
55
|
/**
|
|
45
|
-
* Find the most recently active
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
56
|
+
* Find the most recently active repo's stateDir by scanning the repo registry
|
|
57
|
+
* for the repo with the highest last_seen whose dashboard.json exists and has
|
|
58
|
+
* a non-null updatedAt. Unlike the old `mostRecentOtherRepoStateDir`, this
|
|
59
|
+
* does NOT exclude the launch dir — when the launch dir's snapshot is stale
|
|
60
|
+
* but its registry entry has a recent last_seen (e.g. session just exited),
|
|
61
|
+
* it should still be eligible.
|
|
49
62
|
*/
|
|
50
|
-
function
|
|
63
|
+
function mostRecentActiveRepoStateDir(_launchStateDir: string): string | null {
|
|
51
64
|
const indexPath = join(getIndexDir(), "index.sqlite");
|
|
52
65
|
if (!existsSync(indexPath)) return null;
|
|
53
66
|
let db;
|
|
@@ -59,10 +72,9 @@ function mostRecentOtherRepoStateDir(launchStateDir: string): string | null {
|
|
|
59
72
|
.prepare(
|
|
60
73
|
`SELECT state_dir, last_seen FROM repo_registry
|
|
61
74
|
WHERE state_dir IS NOT NULL AND last_seen IS NOT NULL
|
|
62
|
-
AND state_dir != @launch
|
|
63
75
|
ORDER BY last_seen DESC`,
|
|
64
76
|
)
|
|
65
|
-
.all(
|
|
77
|
+
.all() as unknown as RepoRegistryRow[];
|
|
66
78
|
for (const r of rows) {
|
|
67
79
|
const dashPath = join(r.state_dir, "dashboard.json");
|
|
68
80
|
if (!existsSync(dashPath)) continue;
|
|
@@ -84,27 +96,29 @@ function mostRecentOtherRepoStateDir(launchStateDir: string): string | null {
|
|
|
84
96
|
}
|
|
85
97
|
|
|
86
98
|
/**
|
|
87
|
-
* Resolve the best snapshot to serve.
|
|
88
|
-
*
|
|
99
|
+
* Resolve the best snapshot to serve. The launch dir wins when its snapshot is
|
|
100
|
+
* fresh; when stale (or missing) the most recently active repo wins instead.
|
|
89
101
|
*/
|
|
90
102
|
export function resolveSnapshot(
|
|
91
103
|
staticSnapshotPath: string,
|
|
92
104
|
staticStateDir: string,
|
|
93
105
|
): ResolvedSnapshot {
|
|
94
|
-
// 1. The launch dir's OWN snapshot is "this session" —
|
|
95
|
-
//
|
|
96
|
-
//
|
|
97
|
-
//
|
|
98
|
-
//
|
|
106
|
+
// 1. The launch dir's OWN snapshot is "this session" — but only when it's
|
|
107
|
+
// fresh (updated within STALE_MS). A stale launch-dir snapshot means
|
|
108
|
+
// the pi process that owned it has exited or stopped snapshotting; serving
|
|
109
|
+
// its frozen data as "this session" is misleading. Fall through to the
|
|
110
|
+
// most-recently-active repo so the user sees the session that is actually
|
|
111
|
+
// running.
|
|
99
112
|
if (existsSync(staticSnapshotPath)) {
|
|
100
113
|
const launchSnap = readSnapshot(staticSnapshotPath);
|
|
101
|
-
if (launchSnap.updatedAt) {
|
|
114
|
+
if (launchSnap.updatedAt && snapshotAgeMs(launchSnap.updatedAt) < STALE_MS) {
|
|
102
115
|
return { snapshot: launchSnap, stateDir: staticStateDir };
|
|
103
116
|
}
|
|
104
117
|
}
|
|
105
|
-
// 2. Fall back to the most recently active OTHER repo (launch dir
|
|
106
|
-
// live snapshot yet).
|
|
107
|
-
|
|
118
|
+
// 2. Fall back to the most recently active OTHER repo (launch dir stale or
|
|
119
|
+
// had no live snapshot yet). The registry includes the launch dir too,
|
|
120
|
+
// so a recently-exited launch session can still appear.
|
|
121
|
+
const activeDir = mostRecentActiveRepoStateDir(staticStateDir);
|
|
108
122
|
if (activeDir) {
|
|
109
123
|
const activePath = join(activeDir, "dashboard.json");
|
|
110
124
|
const snap = readSnapshot(activePath);
|
|
@@ -214,6 +214,7 @@ export function handleSetupDetect(
|
|
|
214
214
|
|
|
215
215
|
const OLLAMA_DEFAULT_URL = "http://localhost:11434/api/embeddings"; // guardrails-allow PREVENT-PI-004: localhost-only config string, not a runtime fetch
|
|
216
216
|
const LLAMA_DEFAULT_URL = "http://localhost:8080/v1/embeddings"; // guardrails-allow PREVENT-PI-004: localhost-only config string, not a runtime fetch
|
|
217
|
+
const ONNX_DEFAULT_URL = "http://localhost:8081/v1/embeddings"; // guardrails-allow PREVENT-PI-004: localhost-only config string, not a runtime fetch — TEI / ONNX embedding server
|
|
217
218
|
|
|
218
219
|
function readJsonBody(
|
|
219
220
|
req: IncomingMessage,
|
|
@@ -265,7 +266,7 @@ export function handleSetupConfigure(
|
|
|
265
266
|
}
|
|
266
267
|
const body = parsed.value as unknown as SetupConfigureRequest;
|
|
267
268
|
const embedder = body.embedder;
|
|
268
|
-
if (embedder !== "ollama" && embedder !== "llama" && embedder !== "trigram" && embedder !== "custom") {
|
|
269
|
+
if (embedder !== "ollama" && embedder !== "llama" && embedder !== "trigram" && embedder !== "custom" && embedder !== "onnx") {
|
|
269
270
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
270
271
|
res.end(JSON.stringify({ error: "invalid_embedder" }));
|
|
271
272
|
return;
|
|
@@ -275,6 +276,7 @@ export function handleSetupConfigure(
|
|
|
275
276
|
let allowRemote = false;
|
|
276
277
|
if (embedder === "ollama") resolvedUrl = typeof url === "string" && url ? url : OLLAMA_DEFAULT_URL;
|
|
277
278
|
else if (embedder === "llama") resolvedUrl = typeof url === "string" && url ? url : LLAMA_DEFAULT_URL;
|
|
279
|
+
else if (embedder === "onnx") resolvedUrl = typeof url === "string" && url ? url : ONNX_DEFAULT_URL;
|
|
278
280
|
else if (embedder === "custom") {
|
|
279
281
|
// Third-party / remote endpoint. Requires a URL; opts in to the
|
|
280
282
|
// non-loopback allowlist so embeddingConfigFromEnv() accepts it.
|
|
@@ -28,8 +28,15 @@ import type { IncomingMessage, ServerResponse } from "node:http";
|
|
|
28
28
|
import type { RouteContext } from "./routes-core.js";
|
|
29
29
|
import { VC7A_ENABLED } from "../../src/config.js";
|
|
30
30
|
import { sendJson } from "./routes-vector-cortex-shared.js";
|
|
31
|
+
import { countVcEvents, vcCount } from "./vc-event-counts.js";
|
|
31
32
|
import type { VectorCortexCrystalsView } from "./api-contracts/vector-cortex-cache.js";
|
|
32
33
|
|
|
34
|
+
// Actual events emitted by src/vector-cortex/cache/crystal-emit.ts.
|
|
35
|
+
const CRYSTAL_EVENTS = [
|
|
36
|
+
"vector_cortex_crystal_written",
|
|
37
|
+
"vector_cortex_crystal_collision",
|
|
38
|
+
] as const;
|
|
39
|
+
|
|
33
40
|
/**
|
|
34
41
|
* Reader-only GET /api/vector-cortex/cache-crystals (VC7A).
|
|
35
42
|
*
|
|
@@ -39,7 +46,7 @@ import type { VectorCortexCrystalsView } from "./api-contracts/vector-cortex-cac
|
|
|
39
46
|
export function handleVectorCortexCrystals(
|
|
40
47
|
req: IncomingMessage,
|
|
41
48
|
res: ServerResponse,
|
|
42
|
-
|
|
49
|
+
ctx: RouteContext,
|
|
43
50
|
): boolean {
|
|
44
51
|
const url = req.url ?? "";
|
|
45
52
|
const path = url.split("?")[0] ?? url;
|
|
@@ -50,6 +57,7 @@ export function handleVectorCortexCrystals(
|
|
|
50
57
|
}
|
|
51
58
|
|
|
52
59
|
const enabled = VC7A_ENABLED();
|
|
60
|
+
const counts = countVcEvents(ctx.stateDir, CRYSTAL_EVENTS);
|
|
53
61
|
// Flag-off routes to mode C: with VC7A off nothing is served from the crystal
|
|
54
62
|
// cache, which is exactly the spec's "cache bypass" outcome. Reporting A (hit)
|
|
55
63
|
// or B (fresh render forced by a miss) would imply a cache path that is not
|
|
@@ -58,16 +66,17 @@ export function handleVectorCortexCrystals(
|
|
|
58
66
|
const body: VectorCortexCrystalsView = {
|
|
59
67
|
enabled,
|
|
60
68
|
mode,
|
|
61
|
-
crystalCount:
|
|
69
|
+
crystalCount: vcCount(counts, "vector_cortex_crystal_written"),
|
|
62
70
|
totalBytes: 0,
|
|
63
71
|
hits: 0,
|
|
64
72
|
misses: 0,
|
|
65
73
|
hitBytes: 0,
|
|
66
74
|
writes: 0,
|
|
67
75
|
duplicateWrites: 0,
|
|
68
|
-
collisions:
|
|
76
|
+
collisions: vcCount(counts, "vector_cortex_crystal_collision"),
|
|
69
77
|
lastFailure: null,
|
|
70
78
|
updatedAt: new Date().toISOString(),
|
|
79
|
+
deferredReason: "crystal_store_not_instantiated_v0_20_23",
|
|
71
80
|
};
|
|
72
81
|
sendJson(res, 200, body);
|
|
73
82
|
return true;
|
|
@@ -30,8 +30,12 @@ import type { IncomingMessage, ServerResponse } from "node:http";
|
|
|
30
30
|
import type { RouteContext } from "./routes-core.js";
|
|
31
31
|
import { VC7C_ENABLED } from "../../src/config.js";
|
|
32
32
|
import { sendJson } from "./routes-vector-cortex-shared.js";
|
|
33
|
+
import { countVcEvents, vcCount } from "./vc-event-counts.js";
|
|
33
34
|
import type { VectorCortexDiagnosticsView } from "./api-contracts/vector-cortex-diagnostics.js";
|
|
34
35
|
|
|
36
|
+
// Actual events emitted by src/vector-cortex/cache/diagnostics-emit.ts.
|
|
37
|
+
const DIAGNOSTICS_EVENTS = ["vector_cortex_cache_serve_blocked"] as const;
|
|
38
|
+
|
|
35
39
|
/**
|
|
36
40
|
* Reader-only GET /api/vector-cortex/cache-diagnostics (VC7C).
|
|
37
41
|
*
|
|
@@ -41,7 +45,7 @@ import type { VectorCortexDiagnosticsView } from "./api-contracts/vector-cortex-
|
|
|
41
45
|
export function handleVectorCortexDiagnostics(
|
|
42
46
|
req: IncomingMessage,
|
|
43
47
|
res: ServerResponse,
|
|
44
|
-
|
|
48
|
+
ctx: RouteContext,
|
|
45
49
|
): boolean {
|
|
46
50
|
const url = req.url ?? "";
|
|
47
51
|
const path = url.split("?")[0] ?? url;
|
|
@@ -52,6 +56,7 @@ export function handleVectorCortexDiagnostics(
|
|
|
52
56
|
}
|
|
53
57
|
|
|
54
58
|
const enabled = VC7C_ENABLED();
|
|
59
|
+
const counts = countVcEvents(ctx.stateDir, DIAGNOSTICS_EVENTS);
|
|
55
60
|
// Flag-off routes to mode C: with VC7C off the diagnostics/breaker reporter is
|
|
56
61
|
// suppressed, so no cache serve is attested here and the surface reports the
|
|
57
62
|
// all-cache bypass outcome. Reporting A (crystal served) or B (fresh render
|
|
@@ -67,10 +72,11 @@ export function handleVectorCortexDiagnostics(
|
|
|
67
72
|
requestMisses: 0,
|
|
68
73
|
generationMisses: 0,
|
|
69
74
|
unknownMisses: 0,
|
|
70
|
-
serveBlocked:
|
|
75
|
+
serveBlocked: vcCount(counts, "vector_cortex_cache_serve_blocked"),
|
|
71
76
|
breakerState: "closed",
|
|
72
77
|
lastFailure: null,
|
|
73
78
|
updatedAt: new Date().toISOString(),
|
|
79
|
+
deferredReason: "cache_classifier_not_wired_v0_20_23",
|
|
74
80
|
};
|
|
75
81
|
sendJson(res, 200, body);
|
|
76
82
|
return true;
|
|
@@ -24,16 +24,27 @@ import type { IncomingMessage, ServerResponse } from "node:http";
|
|
|
24
24
|
import type { RouteContext } from "./routes-core.js";
|
|
25
25
|
import { VC6A_ENABLED, VC6B_ENABLED } from "../../src/config.js";
|
|
26
26
|
import { sendJson } from "./routes-vector-cortex-shared.js";
|
|
27
|
+
import { countVcEvents, vcCount } from "./vc-event-counts.js";
|
|
27
28
|
import type {
|
|
28
29
|
VectorCortexClosureProofView,
|
|
29
30
|
VectorCortexRestoreView,
|
|
30
31
|
} from "./api-contracts/vector-cortex.js";
|
|
31
32
|
|
|
33
|
+
// Actual event names emitted by src/vector-cortex/heal/emit.ts + restore-emit.ts.
|
|
34
|
+
const CLOSURE_EVENTS = [
|
|
35
|
+
"vector_cortex_closure_optimized",
|
|
36
|
+
"vector_cortex_closure_proof_rejected",
|
|
37
|
+
] as const;
|
|
38
|
+
const RESTORE_EVENTS = [
|
|
39
|
+
"vector_cortex_source_restored",
|
|
40
|
+
"vector_cortex_restore_digest_rejected",
|
|
41
|
+
] as const;
|
|
42
|
+
|
|
32
43
|
/** Reader-only GET /api/vector-cortex/closure-proof (VC6A). */
|
|
33
44
|
export function handleVectorCortexClosureProof(
|
|
34
45
|
req: IncomingMessage,
|
|
35
46
|
res: ServerResponse,
|
|
36
|
-
|
|
47
|
+
ctx: RouteContext,
|
|
37
48
|
): boolean {
|
|
38
49
|
const url = req.url ?? "";
|
|
39
50
|
const path = url.split("?")[0] ?? url;
|
|
@@ -44,13 +55,14 @@ export function handleVectorCortexClosureProof(
|
|
|
44
55
|
}
|
|
45
56
|
|
|
46
57
|
const enabled = VC6A_ENABLED();
|
|
58
|
+
const counts = countVcEvents(ctx.stateDir, CLOSURE_EVENTS);
|
|
47
59
|
// Flag-off routes to mode B (conservative closure, no reduction) per spec.
|
|
48
60
|
const mode: "A" | "B" | "C" = enabled ? "A" : "B";
|
|
49
61
|
const body: VectorCortexClosureProofView = {
|
|
50
62
|
enabled,
|
|
51
63
|
mode,
|
|
52
|
-
optimizations:
|
|
53
|
-
proofRejections:
|
|
64
|
+
optimizations: vcCount(counts, "vector_cortex_closure_optimized"),
|
|
65
|
+
proofRejections: vcCount(counts, "vector_cortex_closure_proof_rejected"),
|
|
54
66
|
retainedEdgeTotal: 0,
|
|
55
67
|
removedEdgeTotal: 0,
|
|
56
68
|
conservativeTraversalTotal: 0,
|
|
@@ -72,7 +84,7 @@ export function handleVectorCortexClosureProof(
|
|
|
72
84
|
export function handleVectorCortexRestore(
|
|
73
85
|
req: IncomingMessage,
|
|
74
86
|
res: ServerResponse,
|
|
75
|
-
|
|
87
|
+
ctx: RouteContext,
|
|
76
88
|
): boolean {
|
|
77
89
|
const url = req.url ?? "";
|
|
78
90
|
const path = url.split("?")[0] ?? url;
|
|
@@ -83,6 +95,7 @@ export function handleVectorCortexRestore(
|
|
|
83
95
|
}
|
|
84
96
|
|
|
85
97
|
const enabled = VC6B_ENABLED();
|
|
98
|
+
const counts = countVcEvents(ctx.stateDir, RESTORE_EVENTS);
|
|
86
99
|
// Flag-off routes to mode C: with VC6B off there is no exact-restoration path
|
|
87
100
|
// at all, so the honest OFF view is the disclose-loss mode (old context is
|
|
88
101
|
// omitted rather than inferred) — mirroring how VC6A's OFF view reports the
|
|
@@ -91,10 +104,10 @@ export function handleVectorCortexRestore(
|
|
|
91
104
|
const body: VectorCortexRestoreView = {
|
|
92
105
|
enabled,
|
|
93
106
|
mode,
|
|
94
|
-
restoreAttempts:
|
|
107
|
+
restoreAttempts: vcCount(counts, "vector_cortex_source_restored"),
|
|
95
108
|
restoredCount: 0,
|
|
96
109
|
missingCount: 0,
|
|
97
|
-
digestRejections:
|
|
110
|
+
digestRejections: vcCount(counts, "vector_cortex_restore_digest_rejected"),
|
|
98
111
|
lastRejection: null,
|
|
99
112
|
updatedAt: new Date().toISOString(),
|
|
100
113
|
};
|