pi-mega-compact 0.20.58 → 0.20.60

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 (91) hide show
  1. package/dist/config/vector-cortex-dash-0b.js +21 -0
  2. package/dist/config/vector-cortex-dash-0c.js +23 -0
  3. package/dist/config/vector-cortex.js +4 -0
  4. package/dist/config.js +1 -1
  5. package/dist/extensions/dashboard-server/routes-rag-settings-vector-cortex.js +2 -0
  6. package/dist/src/config/vector-cortex-dash-0b.js +21 -0
  7. package/dist/src/config/vector-cortex-dash-0c.js +23 -0
  8. package/dist/src/config/vector-cortex.js +4 -0
  9. package/dist/src/config.js +1 -1
  10. package/extensions/dashboard-client/dist/assets/{AreaChart-CtJ6dSMT.js → AreaChart-B5Is2_EN.js} +2 -2
  11. package/extensions/dashboard-client/dist/assets/{AreaChart-CtJ6dSMT.js.map → AreaChart-B5Is2_EN.js.map} +1 -1
  12. package/extensions/dashboard-client/dist/assets/{BarChart-DJ3j3xDz.js → BarChart-Bj2oT871.js} +2 -2
  13. package/extensions/dashboard-client/dist/assets/{BarChart-DJ3j3xDz.js.map → BarChart-Bj2oT871.js.map} +1 -1
  14. package/extensions/dashboard-client/dist/assets/CacheTab-DuhLeKHW.js +2 -0
  15. package/extensions/dashboard-client/dist/assets/CacheTab-DuhLeKHW.js.map +1 -0
  16. package/extensions/dashboard-client/dist/assets/{EventsTab-DF-Q3o7x.js → EventsTab-BG6L8uWh.js} +2 -2
  17. package/extensions/dashboard-client/dist/assets/{EventsTab-DF-Q3o7x.js.map → EventsTab-BG6L8uWh.js.map} +1 -1
  18. package/extensions/dashboard-client/dist/assets/{HealthTab-Dr1HGOkl.js → HealthTab-CZmGCUJh.js} +2 -2
  19. package/extensions/dashboard-client/dist/assets/{HealthTab-Dr1HGOkl.js.map → HealthTab-CZmGCUJh.js.map} +1 -1
  20. package/extensions/dashboard-client/dist/assets/HydeDetailPanel-B-P1jTtk.js +5 -0
  21. package/extensions/dashboard-client/dist/assets/HydeDetailPanel-B-P1jTtk.js.map +1 -0
  22. package/extensions/dashboard-client/dist/assets/{MaintenanceTab-zKhR18_s.js → MaintenanceTab-CoZ1mSjU.js} +2 -2
  23. package/extensions/dashboard-client/dist/assets/{MaintenanceTab-zKhR18_s.js.map → MaintenanceTab-CoZ1mSjU.js.map} +1 -1
  24. package/extensions/dashboard-client/dist/assets/{MemoryMapTab-DekIzfn2.js → MemoryMapTab-BwVaWniY.js} +2 -2
  25. package/extensions/dashboard-client/dist/assets/{MemoryMapTab-DekIzfn2.js.map → MemoryMapTab-BwVaWniY.js.map} +1 -1
  26. package/extensions/dashboard-client/dist/assets/{MetricsTab-CEKajY38.js → MetricsCards-BCJoHe_n.js} +2 -2
  27. package/extensions/dashboard-client/dist/assets/MetricsCards-BCJoHe_n.js.map +1 -0
  28. package/extensions/dashboard-client/dist/assets/MetricsTab-UQSqUGXe.js +2 -0
  29. package/extensions/dashboard-client/dist/assets/MetricsTab-UQSqUGXe.js.map +1 -0
  30. package/extensions/dashboard-client/dist/assets/{OverviewTab-24sG8xiE.js → OverviewTab-qi12IYvs.js} +2 -2
  31. package/extensions/dashboard-client/dist/assets/{OverviewTab-24sG8xiE.js.map → OverviewTab-qi12IYvs.js.map} +1 -1
  32. package/extensions/dashboard-client/dist/assets/{ReposTab-70gkV8l9.js → ReposTab-CcHZPzOO.js} +2 -2
  33. package/extensions/dashboard-client/dist/assets/{ReposTab-70gkV8l9.js.map → ReposTab-CcHZPzOO.js.map} +1 -1
  34. package/extensions/dashboard-client/dist/assets/SessionsTab-nzd1408Z.js +2 -0
  35. package/extensions/dashboard-client/dist/assets/SessionsTab-nzd1408Z.js.map +1 -0
  36. package/extensions/dashboard-client/dist/assets/SetupTab-DPrG3s9V.js +3 -0
  37. package/extensions/dashboard-client/dist/assets/{SetupTab-tbPrrfYx.js.map → SetupTab-DPrG3s9V.js.map} +1 -1
  38. package/extensions/dashboard-client/dist/assets/{TimeSavedCard-B6mdtCWE.js → TimeSavedCard-DhfdRM3_.js} +2 -2
  39. package/extensions/dashboard-client/dist/assets/{TimeSavedCard-B6mdtCWE.js.map → TimeSavedCard-DhfdRM3_.js.map} +1 -1
  40. package/extensions/dashboard-client/dist/assets/TurnsTab-oalBNLVr.js +2 -0
  41. package/extensions/dashboard-client/dist/assets/TurnsTab-oalBNLVr.js.map +1 -0
  42. package/extensions/dashboard-client/dist/assets/{VcStatusBadge-SDThp0R0.js → VcStatusBadge-XGMW6u62.js} +2 -2
  43. package/extensions/dashboard-client/dist/assets/{VcStatusBadge-SDThp0R0.js.map → VcStatusBadge-XGMW6u62.js.map} +1 -1
  44. package/extensions/dashboard-client/dist/assets/VectorCortexTab-BACHKLjU.js +2 -0
  45. package/extensions/dashboard-client/dist/assets/VectorCortexTab-BACHKLjU.js.map +1 -0
  46. package/extensions/dashboard-client/dist/assets/{WikiTab-Cki48_8N.js → WikiTab-CGQWHuRq.js} +2 -2
  47. package/extensions/dashboard-client/dist/assets/{WikiTab-Cki48_8N.js.map → WikiTab-CGQWHuRq.js.map} +1 -1
  48. package/extensions/dashboard-client/dist/assets/{button-CojFYd7q.js → button-SyOWCGkp.js} +2 -2
  49. package/extensions/dashboard-client/dist/assets/{button-CojFYd7q.js.map → button-SyOWCGkp.js.map} +1 -1
  50. package/extensions/dashboard-client/dist/assets/{card-Cxeeje9o.js → card-69DCTMel.js} +2 -2
  51. package/extensions/dashboard-client/dist/assets/{card-Cxeeje9o.js.map → card-69DCTMel.js.map} +1 -1
  52. package/extensions/dashboard-client/dist/assets/{client-extra-DLxyGxW8.js → client-extra-CgeDg1Md.js} +2 -2
  53. package/extensions/dashboard-client/dist/assets/{client-extra-DLxyGxW8.js.map → client-extra-CgeDg1Md.js.map} +1 -1
  54. package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-DRlqBks2.js → generateCategoricalChart-BwTtrqm5.js} +2 -2
  55. package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-DRlqBks2.js.map → generateCategoricalChart-BwTtrqm5.js.map} +1 -1
  56. package/extensions/dashboard-client/dist/assets/{index-CkbdlPBm.js → index-BZcYzeCr.js} +3 -3
  57. package/extensions/dashboard-client/dist/assets/{index-CkbdlPBm.js.map → index-BZcYzeCr.js.map} +1 -1
  58. package/extensions/dashboard-client/dist/assets/{switch-Cx_nl-Ba.js → switch-DhQfmSFD.js} +2 -2
  59. package/extensions/dashboard-client/dist/assets/{switch-Cx_nl-Ba.js.map → switch-DhQfmSFD.js.map} +1 -1
  60. package/extensions/dashboard-client/dist/assets/{toggle-CfIFzp6P.js → toggle-B3gNAVog.js} +2 -2
  61. package/extensions/dashboard-client/dist/assets/{toggle-CfIFzp6P.js.map → toggle-B3gNAVog.js.map} +1 -1
  62. package/extensions/dashboard-client/dist/assets/{useSSE-B9_N7ccG.js → useSSE-BkkjZ4bO.js} +2 -2
  63. package/extensions/dashboard-client/dist/assets/{useSSE-B9_N7ccG.js.map → useSSE-BkkjZ4bO.js.map} +1 -1
  64. package/extensions/dashboard-client/dist/index.html +1 -1
  65. package/extensions/dashboard-client/src/tabs/AdminTab.tsx +81 -0
  66. package/extensions/dashboard-client/src/tabs/CacheTab/MetricsCards.tsx +66 -0
  67. package/extensions/dashboard-client/src/tabs/CacheTab.tsx +46 -0
  68. package/extensions/dashboard-client/src/tabs/MetricsTab.tsx +10 -51
  69. package/extensions/dashboard-client/src/tabs/SessionsTab/TurnMemoryView.tsx +383 -0
  70. package/extensions/dashboard-client/src/tabs/SessionsTab.tsx +77 -6
  71. package/extensions/dashboard-client/src/tabs/SetupTab.tsx +33 -4
  72. package/extensions/dashboard-client/src/tabs/VectorCortexTab/sections.tsx +201 -0
  73. package/extensions/dashboard-client/src/tabs/VectorCortexTab.tsx +168 -122
  74. package/extensions/dashboard-client/src/tabs/index.ts +31 -0
  75. package/extensions/dashboard-client/src/tabs/registry.ts +34 -0
  76. package/extensions/dashboard-server/routes-rag-settings-vector-cortex.ts +12 -0
  77. package/package.json +1 -1
  78. package/src/config/vector-cortex-dash-0b.ts +23 -0
  79. package/src/config/vector-cortex-dash-0c.ts +25 -0
  80. package/src/config/vector-cortex.ts +4 -0
  81. package/src/config.ts +2 -0
  82. package/extensions/dashboard-client/dist/assets/CacheTab-CXU1_9lR.js +0 -2
  83. package/extensions/dashboard-client/dist/assets/CacheTab-CXU1_9lR.js.map +0 -1
  84. package/extensions/dashboard-client/dist/assets/MetricsTab-CEKajY38.js.map +0 -1
  85. package/extensions/dashboard-client/dist/assets/SessionsTab-B3quvYPZ.js +0 -2
  86. package/extensions/dashboard-client/dist/assets/SessionsTab-B3quvYPZ.js.map +0 -1
  87. package/extensions/dashboard-client/dist/assets/SetupTab-tbPrrfYx.js +0 -3
  88. package/extensions/dashboard-client/dist/assets/TurnsTab-CmhRJJqr.js +0 -5
  89. package/extensions/dashboard-client/dist/assets/TurnsTab-CmhRJJqr.js.map +0 -1
  90. package/extensions/dashboard-client/dist/assets/VectorCortexTab-DDjCkTjk.js +0 -2
  91. package/extensions/dashboard-client/dist/assets/VectorCortexTab-DDjCkTjk.js.map +0 -1
@@ -10,7 +10,8 @@
10
10
  * no external network calls.
11
11
  */
12
12
  import type React from "react";
13
- import { useState, useMemo } from "react";
13
+ import { useState, useMemo, useCallback } from "react";
14
+ import type { SettingsResponse } from "@contracts";
14
15
  import GameTab from "./GameTab";
15
16
  import AchievementsTab from "./AchievementsTab";
16
17
  import ConfigTab from "./ConfigTab";
@@ -18,8 +19,26 @@ import EmbedderSetup from "./SetupTab/EmbedderSetup";
18
19
  import ThresholdsPanel from "./SetupTab/ThresholdsPanel";
19
20
  import CortexSetup from "./SetupTab/CortexSetup";
20
21
  import { Toggle } from "../components/ui/toggle";
22
+ import { useApi } from "../hooks/useApi";
23
+ import { fetchSettings } from "../api/client";
21
24
  import { useSetupCortexPoll, isCortexSubTabVisible } from "./useSetupCortexPoll";
22
25
 
26
+ const DASH_0C_KEY = "MEGACOMPACT_DASH_0C";
27
+
28
+ /** Resolve the DASH-0c consolidation flag from the server settings state.
29
+ * Absent/not-yet-loaded => false (flag-off posture), so flag-off users keep the
30
+ * Config sub-tab; it is hidden only once settings confirm the flag is ON (the
31
+ * config editor then lives solely on the Admin surface). */
32
+ function dash0cEnabled(settings: SettingsResponse | null): boolean {
33
+ if (!settings) return false;
34
+ for (const cat of settings.categories) {
35
+ for (const s of cat.settings) {
36
+ if (s.key === DASH_0C_KEY && s.type === "boolean") return s.value === true;
37
+ }
38
+ }
39
+ return false;
40
+ }
41
+
23
42
  type SetupSubTab =
24
43
  | "embedder"
25
44
  | "thresholds"
@@ -43,11 +62,21 @@ export default function SetupTab(): React.ReactElement {
43
62
  const [subTab, setSubTab] = useState<SetupSubTab>("embedder");
44
63
  const [cortex] = useSetupCortexPoll();
45
64
 
65
+ /* DASH-0c: flag-ON hides the config sub-tab member (the config editor is then
66
+ * reachable only via the Admin surface). Flag-OFF renders config as today. */
67
+ const { data: settingsData } = useApi<SettingsResponse>(
68
+ useCallback(() => fetchSettings(), []),
69
+ { pollInterval: 0, maxRetries: 0 },
70
+ );
71
+ const dash0cOn = dash0cEnabled(settingsData);
72
+
46
73
  const subTabs = useMemo(() => {
47
- const tabs = [...BASE_SUB_TABS];
74
+ const tabs = dash0cOn
75
+ ? BASE_SUB_TABS.filter((t) => t.id !== "config")
76
+ : [...BASE_SUB_TABS];
48
77
  if (isCortexSubTabVisible(cortex.data)) tabs.push(CORTEX_TAB);
49
78
  return tabs;
50
- }, [cortex.data]);
79
+ }, [cortex.data, dash0cOn]);
51
80
 
52
81
  return (
53
82
  <div className="mx-auto flex max-w-3xl flex-col gap-4 p-4">
@@ -68,7 +97,7 @@ export default function SetupTab(): React.ReactElement {
68
97
 
69
98
  {subTab === "embedder" && <EmbedderSetup />}
70
99
  {subTab === "thresholds" && <ThresholdsPanel />}
71
- {subTab === "config" && <ConfigTab />}
100
+ {subTab === "config" && !dash0cOn && <ConfigTab />}
72
101
  {subTab === "game" && <GameTab />}
73
102
  {subTab === "achievements" && <AchievementsTab />}
74
103
  {subTab === "cortex" && <CortexSetup />}
@@ -0,0 +1,201 @@
1
+ /**
2
+ * dashboard-client/src/tabs/VectorCortexTab/sections.tsx — DASH-0b sectioned
3
+ * layout for the Vector Cortex tab.
4
+ *
5
+ * Groups the existent flat VectorCortexTab card list under 4 `<section
6
+ * aria-labelledby>` headers — Cortex status / Cortex repair / Cortex cache /
7
+ * Cortex adaptive — without editing any card component file. Every card is
8
+ * imported verbatim by its current path (unchanged prop contract) and appears
9
+ * under EXACTLY one section (bijective assignment).
10
+ *
11
+ * Groups (spec §Goal):
12
+ * - Cortex status — VC0C health card + ModelImprovementCard +
13
+ * VectorCortexTopologyCard + VectorCortexShardsCard
14
+ * (+ embedded Reconstruct)
15
+ * - Cortex repair — VectorCortexClosureCard + VectorCortexRestoreCard +
16
+ * VectorCortexRepairCard
17
+ * - Cortex cache — VectorCortexCrystalsCard + VectorCortexEconomicsCard +
18
+ * VectorCortexDiagnosticsCard
19
+ * - Cortex adaptive— VectorCortexOutcomesCard + VectorCortexPolicyCard +
20
+ * VectorCortexPlansCard + VectorCortexRenderCard +
21
+ * VectorCortexRolloutCard + VectorCortexPlatformCard +
22
+ * VectorCortexLedgerCard
23
+ *
24
+ * The health card (VC0C "Live Safety Envelope") markup is moved here verbatim
25
+ * from the predecessor VectorCortexTab so the sectioned (flag-ON) layout owns
26
+ * all 18 cards. Consumers pass the live poll state + health-reset handlers.
27
+ *
28
+ * PREVENT-PI-004: local reader data only. PREVENT-011: no `any`.
29
+ */
30
+
31
+ import type {
32
+ VectorCortexHealthCard,
33
+ VectorCortexEvaluationSummary,
34
+ } from "../../api/vector-cortex";
35
+ import type { VectorCortexPollState } from "../useVectorCortexPoll";
36
+ import { Card, CardContent, CardHeader, CardTitle } from "../../components/ui/card";
37
+ import { Badge } from "../../components/ui/badge";
38
+ import { Metric } from "../VectorCortexMetric";
39
+ import { VectorCortexRenderCard } from "../VectorCortexRenderCard";
40
+ import { VectorCortexRolloutCard } from "../VectorCortexRolloutCard";
41
+ import { VectorCortexClosureCard } from "../VectorCortexClosureCard";
42
+ import { VectorCortexRestoreCard } from "../VectorCortexRestoreCard";
43
+ import { VectorCortexRepairCard } from "../VectorCortexRepairCard";
44
+ import { VectorCortexCrystalsCard } from "../VectorCortexCrystalsCard";
45
+ import { VectorCortexEconomicsCard } from "../VectorCortexEconomicsCard";
46
+ import { VectorCortexDiagnosticsCard } from "../VectorCortexDiagnosticsCard";
47
+ import { VectorCortexOutcomesCard } from "../VectorCortexOutcomesCard";
48
+ import { VectorCortexPolicyCard } from "../VectorCortexPolicyCard";
49
+ import { VectorCortexPlatformCard } from "../VectorCortexPlatformCard";
50
+ import {
51
+ VectorCortexShardsCard,
52
+ VectorCortexReconstructCard,
53
+ } from "../VectorCortexShardsCard";
54
+ import { VectorCortexPlansCard } from "../VectorCortexPlansCard";
55
+ import { VectorCortexTopologyCard } from "../VectorCortexTopologyCard";
56
+ import { VectorCortexLedgerCard } from "../VectorCortexLedgerCard";
57
+ import { ModelImprovementCard } from "../../components/ModelImprovementCard";
58
+
59
+ /** Props the sectioned layout needs from the VectorCortexTab shell. */
60
+ export interface VectorCortexSectionsProps {
61
+ /** The polled evaluation summary (guaranteed non-null by the shell). */
62
+ data: VectorCortexEvaluationSummary;
63
+ /** Live VC0C health envelope (may be null when VC0C is off). */
64
+ health: VectorCortexHealthCard | null;
65
+ /** The full poll state (holds every card's view slice). */
66
+ poll: VectorCortexPollState;
67
+ /** Reset-cooldown handler wired to the VC0C health card. */
68
+ onReset: () => void;
69
+ /** Reset feedback message shown on the VC0C health card. */
70
+ resetMsg: string | null;
71
+ }
72
+
73
+ function StatusHeading({ id, title }: { id: string; title: string }): React.ReactElement {
74
+ return (
75
+ <h2 id={id} className="font-heading text-lg font-semibold">
76
+ {title}
77
+ </h2>
78
+ );
79
+ }
80
+
81
+ /**
82
+ * The VC0C "Live Safety Envelope" health card, moved verbatim from the
83
+ * predecessor VectorCortexTab. It is the 18th card in the sectioned layout.
84
+ */
85
+ function Vc0cHealthCard({
86
+ health,
87
+ onReset,
88
+ resetMsg,
89
+ }: {
90
+ health: VectorCortexHealthCard | null;
91
+ onReset: () => void;
92
+ resetMsg: string | null;
93
+ }): React.ReactElement {
94
+ return (
95
+ <Card>
96
+ <CardHeader>
97
+ <div className="flex items-center justify-between">
98
+ <CardTitle>Live Safety Envelope (VC0C)</CardTitle>
99
+ <div className="flex items-center gap-2">
100
+ {health?.stateSource === "ephemeral" && (
101
+ <Badge variant="outline">EPHEMERAL (non-live)</Badge>
102
+ )}
103
+ <button
104
+ onClick={onReset}
105
+ disabled={!health?.enabled}
106
+ className="rounded border border-border px-2 py-1 text-xs disabled:opacity-50"
107
+ >
108
+ Reset Cooldown
109
+ </button>
110
+ </div>
111
+ </div>
112
+ </CardHeader>
113
+ <CardContent>
114
+ {resetMsg && (
115
+ <div className="mb-2 text-xs text-muted-foreground">{resetMsg}</div>
116
+ )}
117
+ {!health ? (
118
+ <div className="vc-empty">Health unavailable (VC0C off).</div>
119
+ ) : (
120
+ <div className="grid grid-cols-2 gap-4 md:grid-cols-4">
121
+ <Metric label="State" value={health.state} />
122
+ <Metric label="Mode" value={health.mode} />
123
+ <Metric label="Window" value={`${health.windowMs}ms`} />
124
+ <Metric label="Probes" value={String(health.probeCount)} />
125
+ <Metric label="Backoff" value={`${health.backoffDelayMs}ms`} />
126
+ <Metric
127
+ label="Failures"
128
+ value={`${health.failures}/${health.attempts}`}
129
+ />
130
+ <Metric
131
+ label="Frontier"
132
+ value={
133
+ health.stateSource === "ephemeral"
134
+ ? "non-live"
135
+ : health.frontierFrozen
136
+ ? "FROZEN"
137
+ : "LIVE"
138
+ }
139
+ />
140
+ <Metric label="Spool lag" value={String(health.spoolLag)} />
141
+ <Metric label="Encoder mode" value={health.encoderMode} />
142
+ <Metric label="Encoder asset" value={health.encoderAssetDigest ? health.encoderAssetDigest.slice(0, 12) : "none"} />
143
+ </div>
144
+ )}
145
+ </CardContent>
146
+ </Card>
147
+ );
148
+ }
149
+
150
+ /** The four section groups, rendered as `<section aria-labelledby>` blocks. */
151
+ export function VectorCortexSections({
152
+ data,
153
+ health,
154
+ poll,
155
+ onReset,
156
+ resetMsg,
157
+ }: VectorCortexSectionsProps): React.ReactElement {
158
+ return (
159
+ <>
160
+ <section aria-labelledby="cortex-status" className="flex flex-col gap-4">
161
+ <StatusHeading id="cortex-status" title="Cortex status" />
162
+ <Vc0cHealthCard health={health} onReset={onReset} resetMsg={resetMsg} />
163
+ {data.ml5dEnabled && (
164
+ <ModelImprovementCard
165
+ encoderMode={health?.encoderMode ?? "B"}
166
+ encoderAssetDigest={health?.encoderAssetDigest ?? null}
167
+ status={data.status}
168
+ />
169
+ )}
170
+ <VectorCortexTopologyCard topology={poll.topology} query={poll.query} />
171
+ <VectorCortexShardsCard view={poll.shards} />
172
+ <VectorCortexReconstructCard view={poll.reconstruct} />
173
+ </section>
174
+
175
+ <section aria-labelledby="cortex-repair" className="flex flex-col gap-4">
176
+ <StatusHeading id="cortex-repair" title="Cortex repair" />
177
+ <VectorCortexClosureCard view={poll.closureProof} />
178
+ <VectorCortexRestoreCard view={poll.restore} />
179
+ <VectorCortexRepairCard view={poll.repair} />
180
+ </section>
181
+
182
+ <section aria-labelledby="cortex-cache" className="flex flex-col gap-4">
183
+ <StatusHeading id="cortex-cache" title="Cortex cache" />
184
+ <VectorCortexCrystalsCard view={poll.crystals} />
185
+ <VectorCortexEconomicsCard view={poll.economics} />
186
+ <VectorCortexDiagnosticsCard view={poll.diagnostics} />
187
+ </section>
188
+
189
+ <section aria-labelledby="cortex-adaptive" className="flex flex-col gap-4">
190
+ <StatusHeading id="cortex-adaptive" title="Cortex adaptive" />
191
+ <VectorCortexOutcomesCard view={poll.outcomes} />
192
+ <VectorCortexPolicyCard view={poll.policy} />
193
+ <VectorCortexPlansCard view={poll.plans} />
194
+ <VectorCortexRenderCard view={poll.render} />
195
+ <VectorCortexRolloutCard view={poll.rollout} />
196
+ <VectorCortexPlatformCard view={poll.platform} />
197
+ <VectorCortexLedgerCard ledger={poll.ledger} />
198
+ </section>
199
+ </>
200
+ );
201
+ }
@@ -1,13 +1,27 @@
1
1
  /**
2
- * VectorCortexTab.tsx — vector-cortex dashboard tab.
2
+ * VectorCortexTab.tsx — vector-cortex dashboard tab (VC0A, DASH-0b).
3
3
  * VC0A: reader-only aggregate latency histogram + per-mode sample counts from
4
4
  * GET /api/vector-cortex/evaluation. VC0C (task 5): live safety envelope health
5
5
  * card (breaker state, window/probe/backoff, durable spool frontier/lag) from
6
6
  * GET /api/vector-cortex/health plus an admin "reset cooldown" action. Polls
7
7
  * every 5s via useVectorCortexPoll.
8
+ *
9
+ * DASH-0b: delegate-shell. Flag `MEGACOMPACT_DASH_0B` default ON re-groups the
10
+ * flat 18-card layout under 4 `<section aria-labelledby>` headers (rendered by
11
+ * `VectorCortexTab/sections.tsx`). Flag-OFF keeps the original flat card list
12
+ * in this file — byte-identical predecessor layout. No card component file is
13
+ * edited; only their import grouping moves.
14
+ *
15
+ * The client is a browser bundle with no `process` global, so the flag is read
16
+ * from the server-authoritative `/api/rag-settings` state (the server resolves
17
+ * `process.env["MEGACOMPACT_DASH_0B"] ?? default` into a boolean SettingState);
18
+ * see the same pattern in SessionsTab. PREVENT-PI-004: loopback reader calls only.
8
19
  */
9
20
 
10
21
  import { useState } from "react";
22
+ import { useApi } from "../hooks/useApi";
23
+ import { fetchSettings } from "../api/client";
24
+ import type { SettingsResponse } from "@contracts";
11
25
  import {
12
26
  resetVectorCortexBreaker,
13
27
  fetchVectorCortexHealth,
@@ -17,6 +31,7 @@ import { Card, CardContent, CardHeader, CardTitle } from "../components/ui/card"
17
31
  import { Badge } from "../components/ui/badge";
18
32
  import { Metric } from "./VectorCortexMetric";
19
33
  import { useVectorCortexPoll } from "./useVectorCortexPoll";
34
+ import { VectorCortexSections } from "./VectorCortexTab/sections";
20
35
  import { VectorCortexRenderCard } from "./VectorCortexRenderCard";
21
36
  import { VectorCortexRolloutCard } from "./VectorCortexRolloutCard";
22
37
  import { VectorCortexClosureCard } from "./VectorCortexClosureCard";
@@ -38,6 +53,19 @@ import { VectorCortexLedgerCard } from "./VectorCortexLedgerCard";
38
53
  import { VcStatusBadge } from "./VcStatusBadge";
39
54
  import { ModelImprovementCard } from "../components/ModelImprovementCard";
40
55
 
56
+ const DASH_0B_KEY = "MEGACOMPACT_DASH_0B";
57
+
58
+ /** Resolve the DASH-0b flag from the server settings state (false unless confirmed). */
59
+ function dash0bEnabled(settings: SettingsResponse | null): boolean {
60
+ if (!settings) return false;
61
+ for (const cat of settings.categories) {
62
+ for (const s of cat.settings) {
63
+ if (s.key === DASH_0B_KEY && s.type === "boolean") return s.value === true;
64
+ }
65
+ }
66
+ return false;
67
+ }
68
+
41
69
  function ModeChip({ mode, count }: { mode: string; count: number }): React.ReactElement {
42
70
  return (
43
71
  <div className="flex items-center justify-between border-b border-border/50 py-1 text-sm">
@@ -51,6 +79,12 @@ export default function VectorCortexTab(): React.ReactElement {
51
79
  const [poll, refetch] = useVectorCortexPoll();
52
80
  const [resetMsg, setResetMsg] = useState<string | null>(null);
53
81
 
82
+ const { data: settingsData } = useApi<SettingsResponse>(
83
+ () => fetchSettings(),
84
+ { pollInterval: 0, maxRetries: 0 },
85
+ );
86
+ const dash0bOn = dash0bEnabled(settingsData);
87
+
54
88
  const { loading, error, data, health } = poll;
55
89
 
56
90
  const onReset = () => {
@@ -85,138 +119,150 @@ export default function VectorCortexTab(): React.ReactElement {
85
119
  </span>
86
120
  </div>
87
121
 
88
- <div className="grid grid-cols-1 gap-4 md:grid-cols-3">
89
- <Card>
90
- <CardHeader>
91
- <CardTitle>Samples</CardTitle>
92
- </CardHeader>
93
- <CardContent>
94
- <div className="text-3xl font-bold">{data.samples}</div>
95
- <div className="mt-2 flex flex-col">
96
- <ModeChip mode="A" count={data.byMode.A} />
97
- <ModeChip mode="B" count={data.byMode.B} />
98
- <ModeChip mode="C" count={data.byMode.C} />
99
- </div>
100
- </CardContent>
101
- </Card>
122
+ {dash0bOn ? (
123
+ <VectorCortexSections
124
+ data={data}
125
+ health={health}
126
+ poll={poll}
127
+ onReset={onReset}
128
+ resetMsg={resetMsg}
129
+ />
130
+ ) : (
131
+ <>
132
+ <div className="grid grid-cols-1 gap-4 md:grid-cols-3">
133
+ <Card>
134
+ <CardHeader>
135
+ <CardTitle>Samples</CardTitle>
136
+ </CardHeader>
137
+ <CardContent>
138
+ <div className="text-3xl font-bold">{data.samples}</div>
139
+ <div className="mt-2 flex flex-col">
140
+ <ModeChip mode="A" count={data.byMode.A} />
141
+ <ModeChip mode="B" count={data.byMode.B} />
142
+ <ModeChip mode="C" count={data.byMode.C} />
143
+ </div>
144
+ </CardContent>
145
+ </Card>
102
146
 
103
- <Card className="md:col-span-2">
104
- <CardHeader>
105
- <CardTitle>Latency Histogram (ms, inclusive edges)</CardTitle>
106
- </CardHeader>
107
- <CardContent>
108
- <div className="flex items-end gap-2" style={{ height: 160 }}>
109
- {data.histogram.edges.map((edge, i) => {
110
- const h = (data.histogram.cells[i] / max) * 140;
111
- return (
112
- <div key={edge} className="flex flex-1 flex-col items-center gap-1">
147
+ <Card className="md:col-span-2">
148
+ <CardHeader>
149
+ <CardTitle>Latency Histogram (ms, inclusive edges)</CardTitle>
150
+ </CardHeader>
151
+ <CardContent>
152
+ <div className="flex items-end gap-2" style={{ height: 160 }}>
153
+ {data.histogram.edges.map((edge, i) => {
154
+ const h = (data.histogram.cells[i] / max) * 140;
155
+ return (
156
+ <div key={edge} className="flex flex-1 flex-col items-center gap-1">
157
+ <span className="text-xs text-muted-foreground">
158
+ {data.histogram.cells[i]}
159
+ </span>
160
+ <div
161
+ className="w-full rounded-t"
162
+ style={{ height: Math.max(2, h), background: "#6366f1" }}
163
+ />
164
+ <span className="text-[10px] text-muted-foreground">&le;{edge}</span>
165
+ </div>
166
+ );
167
+ })}
168
+ <div className="flex flex-1 flex-col items-center gap-1">
113
169
  <span className="text-xs text-muted-foreground">
114
- {data.histogram.cells[i]}
170
+ {data.histogram.overflow}
115
171
  </span>
116
172
  <div
117
173
  className="w-full rounded-t"
118
- style={{ height: Math.max(2, h), background: "#6366f1" }}
174
+ style={{
175
+ height: Math.max(2, (data.histogram.overflow / max) * 140),
176
+ background: "#f87171",
177
+ }}
119
178
  />
120
- <span className="text-[10px] text-muted-foreground">&le;{edge}</span>
179
+ <span className="text-[10px] text-muted-foreground">&gt;250</span>
121
180
  </div>
122
- );
123
- })}
124
- <div className="flex flex-1 flex-col items-center gap-1">
125
- <span className="text-xs text-muted-foreground">
126
- {data.histogram.overflow}
127
- </span>
128
- <div
129
- className="w-full rounded-t"
130
- style={{
131
- height: Math.max(2, (data.histogram.overflow / max) * 140),
132
- background: "#f87171",
133
- }}
134
- />
135
- <span className="text-[10px] text-muted-foreground">&gt;250</span>
136
- </div>
137
- </div>
138
- <div className="mt-1 text-xs text-muted-foreground">
139
- Total: {data.histogram.total} · Rejects: {data.rejects.length}
140
- </div>
141
- </CardContent>
142
- </Card>
143
- </div>
181
+ </div>
182
+ <div className="mt-1 text-xs text-muted-foreground">
183
+ Total: {data.histogram.total} · Rejects: {data.rejects.length}
184
+ </div>
185
+ </CardContent>
186
+ </Card>
187
+ </div>
144
188
 
145
- <Card>
146
- <CardHeader>
147
- <div className="flex items-center justify-between">
148
- <CardTitle>Live Safety Envelope (VC0C)</CardTitle>
149
- <div className="flex items-center gap-2">
150
- {health?.stateSource === "ephemeral" && (
151
- <Badge variant="outline">EPHEMERAL (non-live)</Badge>
189
+ <Card>
190
+ <CardHeader>
191
+ <div className="flex items-center justify-between">
192
+ <CardTitle>Live Safety Envelope (VC0C)</CardTitle>
193
+ <div className="flex items-center gap-2">
194
+ {health?.stateSource === "ephemeral" && (
195
+ <Badge variant="outline">EPHEMERAL (non-live)</Badge>
196
+ )}
197
+ <button
198
+ onClick={onReset}
199
+ disabled={!health?.enabled}
200
+ className="rounded border border-border px-2 py-1 text-xs disabled:opacity-50"
201
+ >
202
+ Reset Cooldown
203
+ </button>
204
+ </div>
205
+ </div>
206
+ </CardHeader>
207
+ <CardContent>
208
+ {resetMsg && (
209
+ <div className="mb-2 text-xs text-muted-foreground">{resetMsg}</div>
152
210
  )}
153
- <button
154
- onClick={onReset}
155
- disabled={!health?.enabled}
156
- className="rounded border border-border px-2 py-1 text-xs disabled:opacity-50"
157
- >
158
- Reset Cooldown
159
- </button>
160
- </div>
161
- </div>
162
- </CardHeader>
163
- <CardContent>
164
- {resetMsg && (
165
- <div className="mb-2 text-xs text-muted-foreground">{resetMsg}</div>
166
- )}
167
- {!health ? (
168
- <div className="vc-empty">Health unavailable (VC0C off).</div>
169
- ) : (
170
- <div className="grid grid-cols-2 gap-4 md:grid-cols-4">
171
- <Metric label="State" value={health.state} />
172
- <Metric label="Mode" value={health.mode} />
173
- <Metric label="Window" value={`${health.windowMs}ms`} />
174
- <Metric label="Probes" value={String(health.probeCount)} />
175
- <Metric label="Backoff" value={`${health.backoffDelayMs}ms`} />
176
- <Metric
177
- label="Failures"
178
- value={`${health.failures}/${health.attempts}`}
179
- />
180
- <Metric
181
- label="Frontier"
182
- value={
183
- health.stateSource === "ephemeral"
184
- ? "non-live"
185
- : health.frontierFrozen
186
- ? "FROZEN"
187
- : "LIVE"
188
- }
189
- />
190
- <Metric label="Spool lag" value={String(health.spoolLag)} />
191
- <Metric label="Encoder mode" value={health.encoderMode} />
192
- <Metric label="Encoder asset" value={health.encoderAssetDigest ? health.encoderAssetDigest.slice(0, 12) : "none"} />
193
- </div>
211
+ {!health ? (
212
+ <div className="vc-empty">Health unavailable (VC0C off).</div>
213
+ ) : (
214
+ <div className="grid grid-cols-2 gap-4 md:grid-cols-4">
215
+ <Metric label="State" value={health.state} />
216
+ <Metric label="Mode" value={health.mode} />
217
+ <Metric label="Window" value={`${health.windowMs}ms`} />
218
+ <Metric label="Probes" value={String(health.probeCount)} />
219
+ <Metric label="Backoff" value={`${health.backoffDelayMs}ms`} />
220
+ <Metric
221
+ label="Failures"
222
+ value={`${health.failures}/${health.attempts}`}
223
+ />
224
+ <Metric
225
+ label="Frontier"
226
+ value={
227
+ health.stateSource === "ephemeral"
228
+ ? "non-live"
229
+ : health.frontierFrozen
230
+ ? "FROZEN"
231
+ : "LIVE"
232
+ }
233
+ />
234
+ <Metric label="Spool lag" value={String(health.spoolLag)} />
235
+ <Metric label="Encoder mode" value={health.encoderMode} />
236
+ <Metric label="Encoder asset" value={health.encoderAssetDigest ? health.encoderAssetDigest.slice(0, 12) : "none"} />
237
+ </div>
238
+ )}
239
+ </CardContent>
240
+ </Card>
241
+ {data.ml5dEnabled && (
242
+ <ModelImprovementCard
243
+ encoderMode={health?.encoderMode ?? "B"}
244
+ encoderAssetDigest={health?.encoderAssetDigest ?? null}
245
+ status={data.status}
246
+ />
194
247
  )}
195
- </CardContent>
196
- </Card>
197
- {data.ml5dEnabled && (
198
- <ModelImprovementCard
199
- encoderMode={health?.encoderMode ?? "B"}
200
- encoderAssetDigest={health?.encoderAssetDigest ?? null}
201
- status={data.status}
202
- />
248
+ <VectorCortexTopologyCard topology={poll.topology} query={poll.query} />
249
+ <VectorCortexShardsCard view={poll.shards} />
250
+ <VectorCortexReconstructCard view={poll.reconstruct} />
251
+ <VectorCortexPlansCard view={poll.plans} />
252
+ <VectorCortexRenderCard view={poll.render} />
253
+ <VectorCortexRolloutCard view={poll.rollout} />
254
+ <VectorCortexClosureCard view={poll.closureProof} />
255
+ <VectorCortexRestoreCard view={poll.restore} />
256
+ <VectorCortexRepairCard view={poll.repair} />
257
+ <VectorCortexCrystalsCard view={poll.crystals} />
258
+ <VectorCortexEconomicsCard view={poll.economics} />
259
+ <VectorCortexDiagnosticsCard view={poll.diagnostics} />
260
+ <VectorCortexOutcomesCard view={poll.outcomes} />
261
+ <VectorCortexPolicyCard view={poll.policy} />
262
+ <VectorCortexPlatformCard view={poll.platform} />
263
+ <VectorCortexLedgerCard ledger={poll.ledger} />
264
+ </>
203
265
  )}
204
- <VectorCortexTopologyCard topology={poll.topology} query={poll.query} />
205
- <VectorCortexShardsCard view={poll.shards} />
206
- <VectorCortexReconstructCard view={poll.reconstruct} />
207
- <VectorCortexPlansCard view={poll.plans} />
208
- <VectorCortexRenderCard view={poll.render} />
209
- <VectorCortexRolloutCard view={poll.rollout} />
210
- <VectorCortexClosureCard view={poll.closureProof} />
211
- <VectorCortexRestoreCard view={poll.restore} />
212
- <VectorCortexRepairCard view={poll.repair} />
213
- <VectorCortexCrystalsCard view={poll.crystals} />
214
- <VectorCortexEconomicsCard view={poll.economics} />
215
- <VectorCortexDiagnosticsCard view={poll.diagnostics} />
216
- <VectorCortexOutcomesCard view={poll.outcomes} />
217
- <VectorCortexPolicyCard view={poll.policy} />
218
- <VectorCortexPlatformCard view={poll.platform} />
219
- <VectorCortexLedgerCard ledger={poll.ledger} />
220
266
  </div>
221
267
  );
222
268
  }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * dashboard-client/src/tabs/index.ts — additive tab barrel (DASH-0b).
3
+ *
4
+ * Re-exports the 7 fixed navigational SURFACE host components defined by the
5
+ * DASH-0a merge plan (plan.ts `DASHSurface`). These map the consolidated
6
+ * surfaces to their host components; DASH-0d rewires App.tsx's lazy list to
7
+ * this barrel. THIS SPRINT App.tsx does NOT switch to it — the barrel is purely
8
+ * additive and the break-native 13-tab surface keeps rendering as today.
9
+ *
10
+ * Host mapping (surface → component):
11
+ * - overview → OverviewTab
12
+ * - sessions → SessionsTab (TurnsTab folded in via TurnMemoryView)
13
+ * - cache-perf → CacheTab (label "Cache+Performance"; MetricsTab
14
+ * folded in via CacheTab/MetricsCards)
15
+ * - memory-graph → MemoryMapTab
16
+ * - diagnostics → VectorCortexTab
17
+ * - setup → SetupTab (config sub-tab hidden when DASH-0c ON)
18
+ * - admin → AdminTab (DASH-0c: MaintenanceTab + ConfigTab
19
+ * combined via an AdminViews toggle)
20
+ *
21
+ * PREVENT-PI-004: imports only — no network. PREVENT-011: no `any`.
22
+ */
23
+
24
+ export { default as OverviewTab } from "./OverviewTab";
25
+ export { default as SessionsTab } from "./SessionsTab";
26
+ export { default as CacheTab } from "./CacheTab";
27
+ export { default as MemoryMapTab } from "./MemoryMapTab";
28
+ export { default as VectorCortexTab } from "./VectorCortexTab";
29
+ export { default as SetupTab } from "./SetupTab";
30
+ /** DASH-0c: the Admin surface combines MaintenanceTab + ConfigTab. */
31
+ export { default as AdminTab } from "./AdminTab";