pi-mega-compact 0.13.1 → 0.13.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (207) hide show
  1. package/dist/extensions/dashboard-server/api-contracts/embedder-health.js +11 -0
  2. package/dist/extensions/dashboard-server/api-contracts/endpoints/registry.js +225 -0
  3. package/dist/extensions/dashboard-server/api-contracts/endpoints/types.js +1 -0
  4. package/dist/extensions/dashboard-server/api-contracts/endpoints.js +5 -224
  5. package/dist/extensions/dashboard-server/api-contracts/raptor.js +8 -0
  6. package/dist/extensions/dashboard-server/api-contracts.test/_helpers.js +32 -0
  7. package/dist/extensions/dashboard-server/routes-cache.test/_helpers.js +48 -0
  8. package/dist/extensions/dashboard-server/routes-embedder-health.js +67 -0
  9. package/dist/extensions/dashboard-server/routes-raptor.js +88 -0
  10. package/dist/extensions/dashboard-server/routes-setup.js +1 -1
  11. package/dist/extensions/dashboard-server/routes.js +2 -0
  12. package/dist/extensions/dashboard-server/server.js +5 -1
  13. package/dist/extensions/mega-cache-replay.test/_helpers.js +175 -0
  14. package/dist/extensions/mega-commands/dataCommands.js +151 -0
  15. package/dist/extensions/mega-commands/helpers.js +61 -0
  16. package/dist/extensions/mega-commands/historyCommands.js +97 -0
  17. package/dist/extensions/mega-commands/setupCommand.js +200 -0
  18. package/dist/extensions/mega-commands.js +14 -499
  19. package/dist/extensions/mega-compact-s38.test/_helpers.js +194 -0
  20. package/dist/extensions/mega-compact.test/_helpers.js +225 -0
  21. package/dist/extensions/mega-events/agent-handlers/agentEndHandler.js +211 -0
  22. package/dist/extensions/mega-events/agent-handlers/turnEndHandler/cacheStripe.js +49 -0
  23. package/dist/extensions/mega-events/agent-handlers/turnEndHandler/contextHealth.js +33 -0
  24. package/dist/extensions/mega-events/agent-handlers/turnEndHandler/errorRetry.js +387 -0
  25. package/dist/extensions/mega-events/agent-handlers/turnEndHandler/event.js +7 -0
  26. package/dist/extensions/mega-events/agent-handlers/turnEndHandler/gameScoring.js +55 -0
  27. package/dist/extensions/mega-events/agent-handlers/turnEndHandler/lengthStop.js +12 -0
  28. package/dist/extensions/mega-events/agent-handlers/turnEndHandler/memoryReview.js +22 -0
  29. package/dist/extensions/mega-events/agent-handlers/turnEndHandler/recordTurnRow.js +38 -0
  30. package/dist/extensions/mega-events/agent-handlers/turnEndHandler.js +36 -0
  31. package/dist/extensions/mega-events/agent-handlers.js +4 -799
  32. package/dist/extensions/mega-events/context-handler/afterCompact.js +163 -0
  33. package/dist/extensions/mega-events/context-handler/messageText.js +12 -0
  34. package/dist/extensions/mega-events/context-handler/tailResult.js +46 -0
  35. package/dist/extensions/mega-events/context-handler.js +11 -198
  36. package/dist/extensions/mega-events/separated-prompt.test/_helpers.js +25 -0
  37. package/dist/src/config.js +2 -0
  38. package/dist/src/dedup-engine.test/_helpers.js +55 -0
  39. package/dist/src/e2e.test/_helpers.js +52 -0
  40. package/dist/src/embedder.js +1 -0
  41. package/dist/src/httpEmbedder.js +6 -0
  42. package/dist/src/hyde.js +146 -0
  43. package/dist/src/importance.test/_helpers.js +5 -0
  44. package/dist/src/memoryGraph/sources/checkpoints.js +78 -0
  45. package/dist/src/memoryGraph/sources/edges.js +17 -0
  46. package/dist/src/memoryGraph/sources/flags.js +22 -0
  47. package/dist/src/memoryGraph/sources/helpers.js +14 -0
  48. package/dist/src/memoryGraph/sources/memories.js +88 -0
  49. package/dist/src/memoryGraph/sources/raptor.js +26 -0
  50. package/dist/src/memoryGraph/sources/turns.js +176 -0
  51. package/dist/src/memoryGraph/sources.js +15 -441
  52. package/dist/src/memoryGraph-gates.test/_helpers.js +120 -0
  53. package/dist/src/ratio.bench.test/_helpers.js +198 -0
  54. package/dist/src/recall/async.js +112 -0
  55. package/dist/src/recall/format.js +149 -0
  56. package/dist/src/recall/memory.js +62 -0
  57. package/dist/src/recall/reformulate.js +82 -0
  58. package/dist/src/recall/sync.js +169 -0
  59. package/dist/src/recall/types.js +1 -0
  60. package/dist/src/recall.js +13 -530
  61. package/dist/src/store/sqlite/schema/core.js +232 -0
  62. package/dist/src/store/sqlite/schema/game.js +65 -0
  63. package/dist/src/store/sqlite/schema/plan-v2.js +107 -0
  64. package/dist/src/store/sqlite/schema/turns.js +59 -0
  65. package/dist/src/store/sqlite/schema.js +8 -441
  66. package/dist/src/store/turns/contract-compliance.test/_helpers.js +21 -0
  67. package/dist/src/store/turns/sqlite-store/admin.js +171 -0
  68. package/dist/src/store/turns/sqlite-store/ctx.js +1 -0
  69. package/dist/src/store/turns/sqlite-store/read.js +111 -0
  70. package/dist/src/store/turns/sqlite-store/rows.js +42 -0
  71. package/dist/src/store/turns/sqlite-store/write.js +102 -0
  72. package/dist/src/store/turns/sqlite-store.js +31 -367
  73. package/dist/src/vectorStore/class.js +356 -0
  74. package/dist/src/vectorStore/hash.js +10 -0
  75. package/dist/src/vectorStore/types.js +2 -0
  76. package/dist/src/vectorStore.js +8 -359
  77. package/dist/src/vectorStore.test/_helpers.js +17 -0
  78. package/extensions/dashboard-client/dist/assets/{CacheTab-8HRroK9K.js → CacheTab-DPRHjYZ0.js} +2 -2
  79. package/extensions/dashboard-client/dist/assets/{CacheTab-8HRroK9K.js.map → CacheTab-DPRHjYZ0.js.map} +1 -1
  80. package/extensions/dashboard-client/dist/assets/{EventsTab-ncobZw-I.js → EventsTab-CgwYq-Qf.js} +2 -2
  81. package/extensions/dashboard-client/dist/assets/{EventsTab-ncobZw-I.js.map → EventsTab-CgwYq-Qf.js.map} +1 -1
  82. package/extensions/dashboard-client/dist/assets/{HealthTab-C6BI1EZG.js → HealthTab-BgOCjVzR.js} +2 -2
  83. package/extensions/dashboard-client/dist/assets/{HealthTab-C6BI1EZG.js.map → HealthTab-BgOCjVzR.js.map} +1 -1
  84. package/extensions/dashboard-client/dist/assets/MaintenanceTab-Yw1yFpsy.js +2 -0
  85. package/extensions/dashboard-client/dist/assets/MaintenanceTab-Yw1yFpsy.js.map +1 -0
  86. package/extensions/dashboard-client/dist/assets/MemoryMapTab-yHUX7Yzi.js +2 -0
  87. package/extensions/dashboard-client/dist/assets/MemoryMapTab-yHUX7Yzi.js.map +1 -0
  88. package/extensions/dashboard-client/dist/assets/{MetricsTab-B88XTCMk.js → MetricsTab-CcH9fP8P.js} +2 -2
  89. package/extensions/dashboard-client/dist/assets/{MetricsTab-B88XTCMk.js.map → MetricsTab-CcH9fP8P.js.map} +1 -1
  90. package/extensions/dashboard-client/dist/assets/{OverviewTab-CGZrSia-.js → OverviewTab-BOs8ZNev.js} +2 -2
  91. package/extensions/dashboard-client/dist/assets/{OverviewTab-CGZrSia-.js.map → OverviewTab-BOs8ZNev.js.map} +1 -1
  92. package/extensions/dashboard-client/dist/assets/{ReposTab-BZo5cNS1.js → ReposTab-B-MfSPvg.js} +2 -2
  93. package/extensions/dashboard-client/dist/assets/{ReposTab-BZo5cNS1.js.map → ReposTab-B-MfSPvg.js.map} +1 -1
  94. package/extensions/dashboard-client/dist/assets/{SessionsTab-C2RokJcw.js → SessionsTab-BmeN649Q.js} +2 -2
  95. package/extensions/dashboard-client/dist/assets/{SessionsTab-C2RokJcw.js.map → SessionsTab-BmeN649Q.js.map} +1 -1
  96. package/extensions/dashboard-client/dist/assets/SetupTab-nOknoph5.js +2 -0
  97. package/extensions/dashboard-client/dist/assets/SetupTab-nOknoph5.js.map +1 -0
  98. package/extensions/dashboard-client/dist/assets/{TimeSavedCard-CewYB2aA.js → TimeSavedCard-DnPg0L0z.js} +2 -2
  99. package/extensions/dashboard-client/dist/assets/{TimeSavedCard-CewYB2aA.js.map → TimeSavedCard-DnPg0L0z.js.map} +1 -1
  100. package/extensions/dashboard-client/dist/assets/{TopicsTab-DpVNIuaL.js → TopicsTab-BODHOg_b.js} +2 -2
  101. package/extensions/dashboard-client/dist/assets/{TopicsTab-DpVNIuaL.js.map → TopicsTab-BODHOg_b.js.map} +1 -1
  102. package/extensions/dashboard-client/dist/assets/{TurnsTab-KeuKKVC9.js → TurnsTab-BK0I7hKr.js} +2 -2
  103. package/extensions/dashboard-client/dist/assets/{TurnsTab-KeuKKVC9.js.map → TurnsTab-BK0I7hKr.js.map} +1 -1
  104. package/extensions/dashboard-client/dist/assets/{index-Cucgohga.js → index-mOlljTFI.js} +9 -9
  105. package/extensions/dashboard-client/dist/assets/index-mOlljTFI.js.map +1 -0
  106. package/extensions/dashboard-client/dist/assets/{useSSE-DJsqdPXC.js → useSSE-BYOtv1-3.js} +2 -2
  107. package/extensions/dashboard-client/dist/assets/{useSSE-DJsqdPXC.js.map → useSSE-BYOtv1-3.js.map} +1 -1
  108. package/extensions/dashboard-client/dist/index.html +1 -1
  109. package/extensions/dashboard-client/src/api/client.ts +16 -0
  110. package/extensions/dashboard-client/src/tabs/MaintenanceTab/ActionsCard.tsx +178 -0
  111. package/extensions/dashboard-client/src/tabs/MaintenanceTab/DbStatsCard.tsx +140 -0
  112. package/extensions/dashboard-client/src/tabs/MaintenanceTab/DebugBundleCard.tsx +109 -0
  113. package/extensions/dashboard-client/src/tabs/MaintenanceTab/HealthMitigationCard.tsx +98 -0
  114. package/extensions/dashboard-client/src/tabs/MaintenanceTab/SchemaHealthCard.tsx +108 -0
  115. package/extensions/dashboard-client/src/tabs/MaintenanceTab.tsx +12 -598
  116. package/extensions/dashboard-client/src/tabs/MemoryMapTab/MemoryMapView.tsx +476 -0
  117. package/extensions/dashboard-client/src/tabs/MemoryMapTab/RaptorTreeView.tsx +163 -0
  118. package/extensions/dashboard-client/src/tabs/MemoryMapTab.tsx +56 -466
  119. package/extensions/dashboard-client/src/tabs/SetupTab/EmbedderHealthCard.tsx +109 -0
  120. package/extensions/dashboard-client/src/tabs/SetupTab/EmbedderSetup.tsx +468 -0
  121. package/extensions/dashboard-client/src/tabs/SetupTab.tsx +13 -483
  122. package/extensions/dashboard-server/api-contracts/embedder-health.ts +32 -0
  123. package/extensions/dashboard-server/api-contracts/endpoints/registry.ts +360 -0
  124. package/extensions/dashboard-server/api-contracts/endpoints/types.ts +350 -0
  125. package/extensions/dashboard-server/api-contracts/endpoints.ts +27 -648
  126. package/extensions/dashboard-server/api-contracts/index.ts +6 -0
  127. package/extensions/dashboard-server/api-contracts/raptor.ts +49 -0
  128. package/extensions/dashboard-server/api-contracts.test/_helpers.ts +47 -0
  129. package/extensions/dashboard-server/routes-cache.test/_helpers.ts +94 -0
  130. package/extensions/dashboard-server/routes-embedder-health.ts +77 -0
  131. package/extensions/dashboard-server/routes-raptor.ts +128 -0
  132. package/extensions/dashboard-server/routes-setup.ts +1 -1
  133. package/extensions/dashboard-server/routes.ts +2 -0
  134. package/extensions/dashboard-server/server.ts +4 -0
  135. package/extensions/mega-cache-replay.test/_helpers.ts +188 -0
  136. package/extensions/mega-commands/dataCommands.ts +169 -0
  137. package/extensions/mega-commands/helpers.ts +62 -0
  138. package/extensions/mega-commands/historyCommands.ts +117 -0
  139. package/extensions/mega-commands/setupCommand.ts +235 -0
  140. package/extensions/mega-commands.ts +25 -538
  141. package/extensions/mega-compact-s38.test/_helpers.ts +201 -0
  142. package/extensions/mega-compact.test/_helpers.ts +237 -0
  143. package/extensions/mega-events/agent-handlers/agentEndHandler.ts +238 -0
  144. package/extensions/mega-events/agent-handlers/turnEndHandler/cacheStripe.ts +74 -0
  145. package/extensions/mega-events/agent-handlers/turnEndHandler/contextHealth.ts +50 -0
  146. package/extensions/mega-events/agent-handlers/turnEndHandler/errorRetry.ts +421 -0
  147. package/extensions/mega-events/agent-handlers/turnEndHandler/event.ts +16 -0
  148. package/extensions/mega-events/agent-handlers/turnEndHandler/gameScoring.ts +73 -0
  149. package/extensions/mega-events/agent-handlers/turnEndHandler/lengthStop.ts +29 -0
  150. package/extensions/mega-events/agent-handlers/turnEndHandler/memoryReview.ts +42 -0
  151. package/extensions/mega-events/agent-handlers/turnEndHandler/recordTurnRow.ts +61 -0
  152. package/extensions/mega-events/agent-handlers/turnEndHandler.ts +64 -0
  153. package/extensions/mega-events/agent-handlers.ts +15 -861
  154. package/extensions/mega-events/context-handler/afterCompact.ts +213 -0
  155. package/extensions/mega-events/context-handler/messageText.ts +20 -0
  156. package/extensions/mega-events/context-handler/tailResult.ts +63 -0
  157. package/extensions/mega-events/context-handler.ts +17 -235
  158. package/extensions/mega-events/separated-prompt.test/_helpers.ts +35 -0
  159. package/package.json +1 -1
  160. package/src/config.ts +4 -0
  161. package/src/dedup-engine.test/_helpers.ts +79 -0
  162. package/src/e2e.test/_helpers.ts +59 -0
  163. package/src/embedder.ts +4 -0
  164. package/src/httpEmbedder.ts +7 -0
  165. package/src/hyde.ts +162 -0
  166. package/src/importance.test/_helpers.ts +5 -0
  167. package/src/memoryGraph/sources/checkpoints.ts +99 -0
  168. package/src/memoryGraph/sources/edges.ts +23 -0
  169. package/src/memoryGraph/sources/flags.ts +26 -0
  170. package/src/memoryGraph/sources/helpers.ts +13 -0
  171. package/src/memoryGraph/sources/memories.ts +108 -0
  172. package/src/memoryGraph/sources/raptor.ts +37 -0
  173. package/src/memoryGraph/sources/turns.ts +226 -0
  174. package/src/memoryGraph/sources.ts +19 -544
  175. package/src/memoryGraph-gates.test/_helpers.ts +164 -0
  176. package/src/ratio.bench.test/_helpers.ts +268 -0
  177. package/src/recall/async.ts +142 -0
  178. package/src/recall/format.ts +173 -0
  179. package/src/recall/memory.ts +90 -0
  180. package/src/recall/reformulate.ts +111 -0
  181. package/src/recall/sync.ts +196 -0
  182. package/src/recall/types.ts +63 -0
  183. package/src/recall.ts +25 -712
  184. package/src/store/sqlite/schema/core.ts +233 -0
  185. package/src/store/sqlite/schema/game.ts +66 -0
  186. package/src/store/sqlite/schema/plan-v2.ts +108 -0
  187. package/src/store/sqlite/schema/turns.ts +60 -0
  188. package/src/store/sqlite/schema.ts +13 -441
  189. package/src/store/turns/contract-compliance.test/_helpers.ts +38 -0
  190. package/src/store/turns/sqlite-store/admin.ts +249 -0
  191. package/src/store/turns/sqlite-store/ctx.ts +14 -0
  192. package/src/store/turns/sqlite-store/read.ts +174 -0
  193. package/src/store/turns/sqlite-store/rows.ts +55 -0
  194. package/src/store/turns/sqlite-store/write.ts +193 -0
  195. package/src/store/turns/sqlite-store.ts +33 -514
  196. package/src/vectorStore/class.ts +433 -0
  197. package/src/vectorStore/hash.ts +11 -0
  198. package/src/vectorStore/types.ts +58 -0
  199. package/src/vectorStore.test/_helpers.ts +20 -0
  200. package/src/vectorStore.ts +13 -489
  201. package/extensions/dashboard-client/dist/assets/MaintenanceTab-DZi1MnZI.js +0 -2
  202. package/extensions/dashboard-client/dist/assets/MaintenanceTab-DZi1MnZI.js.map +0 -1
  203. package/extensions/dashboard-client/dist/assets/MemoryMapTab-CjUa9zzw.js +0 -2
  204. package/extensions/dashboard-client/dist/assets/MemoryMapTab-CjUa9zzw.js.map +0 -1
  205. package/extensions/dashboard-client/dist/assets/SetupTab-C_BwmebC.js +0 -2
  206. package/extensions/dashboard-client/dist/assets/SetupTab-C_BwmebC.js.map +0 -1
  207. package/extensions/dashboard-client/dist/assets/index-Cucgohga.js.map +0 -1
@@ -1,497 +1,27 @@
1
1
  /**
2
- * dashboard-client/src/tabs/SetupTab.tsx — Setup wizard tab (P0b).
2
+ * dashboard-client/src/tabs/SetupTab.tsx — Setup wizard tab shell (P0b).
3
3
  *
4
- * Shows current embedder configuration, warns about trigram recall quality,
5
- * and mirrors the /megasetup command with detection results.
4
+ * Sub-tab shell routing between Embedder / Config / Game Mode / Achievements.
5
+ * The embedder setup section lives in SetupTab/EmbedderSetup.tsx.
6
6
  *
7
7
  * PREVENT-PI-004: all data comes from localhost dashboard API endpoints —
8
8
  * no external network calls.
9
9
  */
10
-
11
10
  import type React from "react";
12
- import { useState, useEffect, useCallback } from "react";
13
- import type { SetupStatusResponse, SetupDetectResponse, SetupConfigureResponse } from "@contracts";
14
- import { fetchSetupStatus, fetchSetupDetect, configureEmbedder } from "../api/client";
11
+ import { useState } from "react";
15
12
  import GameTab from "./GameTab";
16
13
  import AchievementsTab from "./AchievementsTab";
17
14
  import ConfigTab from "./ConfigTab";
18
-
19
- // ---------------------------------------------------------------------------
20
- // Style constants
21
- // ---------------------------------------------------------------------------
22
-
23
- const styles: Record<string, React.CSSProperties> = {
24
- container: {
25
- padding: "1rem",
26
- maxWidth: "720px",
27
- margin: "0 auto",
28
- fontFamily: "system-ui, sans-serif",
29
- color: "#e0e0e0",
30
- },
31
- section: {
32
- background: "#1a1a2e",
33
- borderRadius: "8px",
34
- padding: "1rem",
35
- marginBottom: "1rem",
36
- border: "1px solid #2a2a4e",
37
- },
38
- sectionTitle: {
39
- fontSize: "1.1rem",
40
- fontWeight: 700,
41
- marginTop: 0,
42
- marginBottom: "0.75rem",
43
- color: "#e0e0e0",
44
- borderBottom: "1px solid #333",
45
- paddingBottom: "0.5rem",
46
- },
47
- label: { fontWeight: 600, color: "#a0a0c0", marginRight: "0.5rem" },
48
- value: { color: "#e0e0e0" },
49
- row: { marginBottom: "0.4rem", fontSize: "0.9rem" },
50
- warning: {
51
- background: "#3a2a00",
52
- border: "1px solid #665500",
53
- borderRadius: "8px",
54
- padding: "0.75rem",
55
- marginTop: "0.5rem",
56
- color: "#ffcc00",
57
- fontSize: "0.85rem",
58
- },
59
- badge: {
60
- display: "inline-block",
61
- padding: "0.15rem 0.5rem",
62
- borderRadius: "4px",
63
- fontSize: "0.8rem",
64
- fontWeight: 600,
65
- marginLeft: "0.5rem",
66
- },
67
- detectRow: {
68
- display: "flex",
69
- justifyContent: "space-between",
70
- alignItems: "center",
71
- padding: "0.5rem 0",
72
- borderBottom: "1px solid #2a2a4e",
73
- },
74
- button: {
75
- background: "#3a5a9f",
76
- color: "#fff",
77
- border: "none",
78
- borderRadius: "6px",
79
- padding: "0.5rem 1rem",
80
- cursor: "pointer",
81
- fontSize: "0.9rem",
82
- fontWeight: 600,
83
- },
15
+ import EmbedderSetup from "./SetupTab/EmbedderSetup";
16
+
17
+ const containerStyle: React.CSSProperties = {
18
+ padding: "1rem",
19
+ maxWidth: "720px",
20
+ margin: "0 auto",
21
+ fontFamily: "system-ui, sans-serif",
22
+ color: "#e0e0e0",
84
23
  };
85
24
 
86
- // ---------------------------------------------------------------------------
87
- // SetupTab component
88
- // ---------------------------------------------------------------------------
89
-
90
- export function EmbedderSetup(): React.ReactElement {
91
- const [status, setStatus] = useState<SetupStatusResponse | null>(null);
92
- const [detect, setDetect] = useState<SetupDetectResponse | null>(null);
93
- const [statusError, setStatusError] = useState<string | null>(null);
94
- const [detectError, setDetectError] = useState<string | null>(null);
95
- const [runningDetect, setRunningDetect] = useState(false);
96
- const [configuring, setConfiguring] = useState<string | null>(null);
97
- const [configResult, setConfigResult] = useState<SetupConfigureResponse | null>(null);
98
- const [configError, setConfigError] = useState<string | null>(null);
99
- const [customUrl, setCustomUrl] = useState("");
100
-
101
- const loadStatus = useCallback(() => {
102
- fetchSetupStatus()
103
- .then(setStatus)
104
- .catch((e: unknown) =>
105
- setStatusError(e instanceof Error ? e.message : String(e)),
106
- );
107
- }, []);
108
-
109
- const applyEmbedder = useCallback((embedder: "ollama" | "llama" | "trigram" | "custom", url?: string) => {
110
- setConfiguring(embedder);
111
- setConfigError(null);
112
- setConfigResult(null);
113
- configureEmbedder({ embedder, url })
114
- .then((r) => {
115
- setConfigResult(r);
116
- setConfiguring(null);
117
- loadStatus();
118
- })
119
- .catch((e: unknown) => {
120
- setConfigError(e instanceof Error ? e.message : String(e));
121
- setConfiguring(null);
122
- });
123
- }, [loadStatus]);
124
-
125
- const runDetect = useCallback(() => {
126
- setRunningDetect(true);
127
- setDetectError(null);
128
- fetchSetupDetect()
129
- .then((d) => {
130
- setDetect(d);
131
- setRunningDetect(false);
132
- })
133
- .catch((e: unknown) => {
134
- setDetectError(e instanceof Error ? e.message : String(e));
135
- setRunningDetect(false);
136
- });
137
- }, []);
138
-
139
- useEffect(() => {
140
- loadStatus();
141
- }, [loadStatus]);
142
-
143
- // Poll status every 30s
144
- useEffect(() => {
145
- const id = setInterval(loadStatus, 30000);
146
- return () => clearInterval(id);
147
- }, [loadStatus]);
148
-
149
- // -----------------------------------------------------------------------
150
- // Render helpers
151
- // -----------------------------------------------------------------------
152
-
153
- const embedderLabel = (e: string): string => {
154
- switch (e) {
155
- case "trigram":
156
- return "TrigramEmbedder (heuristic, default)";
157
- case "http":
158
- return "HTTP Embedder (BYO localhost)";
159
- case "minilm":
160
- return "MiniLM (experimental)";
161
- default:
162
- return "Unknown";
163
- }
164
- };
165
-
166
- const trigramWarning = status?.currentEmbedder === "trigram" && (
167
- <div style={styles.warning}>
168
- <strong>Note:</strong> TrigramEmbedder is a heuristic-strength default
169
- embedder. It works without any setup but recall quality may be lower
170
- than a dedicated embedding backend. If you notice poor recall results,
171
- consider installing Ollama and running the{" "}
172
- <code>/megasetup</code> command, or set{" "}
173
- <code>MEGACOMPACT_EMBEDDING_URL</code> to point at your own localhost
174
- embedding server.
175
- </div>
176
- );
177
-
178
- const detectBadge = (installed: boolean): React.ReactElement => {
179
- const bg = installed ? "#1a5a1a" : "#3a1a1a";
180
- const color = installed ? "#4caf50" : "#f44336";
181
- return (
182
- <span style={{ ...styles.badge, background: bg, color }}>
183
- {installed ? "Detected" : "Not found"}
184
- </span>
185
- );
186
- };
187
-
188
- // -----------------------------------------------------------------------
189
- // Main render
190
- // -----------------------------------------------------------------------
191
-
192
- return (
193
- <div style={styles.container}>
194
- <h2 style={{ fontSize: "1.3rem", marginTop: 0, marginBottom: "1rem" }}>
195
- Embedder Setup
196
- </h2>
197
-
198
- {/* Current Config Section */}
199
- <div style={styles.section}>
200
- <h3 style={styles.sectionTitle}>Current Embedder Configuration</h3>
201
- {statusError && (
202
- <p style={{ color: "#f44336", fontSize: "0.85rem" }}>
203
- Error: {statusError}
204
- </p>
205
- )}
206
- {status && (
207
- <>
208
- <div style={styles.row}>
209
- <span style={styles.label}>Active Embedder:</span>
210
- <span style={styles.value}>
211
- {embedderLabel(status.currentEmbedder)}
212
- </span>
213
- </div>
214
- {"configuredEmbedder" in status && status.configuredEmbedder !== status.currentEmbedder && (
215
- <div style={styles.warning}>
216
- <strong>Configured but not active:</strong>{" "}
217
- {embedderLabel(status.configuredEmbedder)} is configured in
218
- .mega-compact.env but not yet loaded.{" "}
219
- <strong>Restart pi</strong> to activate it.
220
- {status.configuredUrl && (
221
- <> ({status.configuredUrl})</>
222
- )}
223
- </div>
224
- )}
225
- {"restartRequired" in status && status.restartRequired && (
226
- <div style={{ ...styles.row, color: "#ff9800" }}>
227
- <span style={styles.label}>Status:</span>
228
- <span style={styles.value}>
229
- Restart required to activate the configured embedder
230
- </span>
231
- </div>
232
- )}
233
- <div style={styles.row}>
234
- <span style={styles.label}>Embedding URL:</span>
235
- <span style={styles.value}>
236
- {status.embeddingUrl ?? (
237
- <span style={{ color: "#888" }}>not set</span>
238
- )}
239
- </span>
240
- </div>
241
- <div style={styles.row}>
242
- <span style={styles.label}>Embed Cache:</span>
243
- <span style={styles.value}>
244
- {status.embedCache ?? (
245
- <span style={{ color: "#888" }}>not set</span>
246
- )}
247
- </span>
248
- </div>
249
- <div style={styles.row}>
250
- <span style={styles.label}>MiniLM:</span>
251
- <span style={styles.value}>{status.minilm ? "enabled" : "disabled"}</span>
252
- </div>
253
- {trigramWarning}
254
- </>
255
- )}
256
- {!status && !statusError && (
257
- <p style={{ color: "#888", fontSize: "0.85rem" }}>
258
- Loading configuration...
259
- </p>
260
- )}
261
- </div>
262
-
263
- {/* Detection Section */}
264
- <div style={styles.section}>
265
- <h3 style={styles.sectionTitle}>Local Embedder Detection</h3>
266
- <p style={{ fontSize: "0.85rem", color: "#a0a0c0", marginTop: 0 }}>
267
- Detect which local embedding backends are available on this machine.
268
- No software is installed — detection only.
269
- </p>
270
-
271
- {detect && (
272
- <>
273
- {/* Ollama */}
274
- <div style={styles.detectRow}>
275
- <span>
276
- <strong>Ollama</strong>
277
- </span>
278
- {detect.ollama !== null ? (
279
- <span>
280
- {detectBadge(detect.ollama.installed)}
281
- {detect.ollama.installed && (
282
- <span style={{ fontSize: "0.8rem", color: "#a0a0c0", marginLeft: "0.5rem" }}>
283
- {detect.ollama.running
284
- ? `server running, ${detect.ollama.models.length} model(s)`
285
- : "server not running"}
286
- </span>
287
- )}
288
- </span>
289
- ) : (
290
- <span style={{ color: "#888", fontSize: "0.85rem" }}>
291
- not checked
292
- </span>
293
- )}
294
- </div>
295
-
296
- {/* llama.cpp */}
297
- <div style={styles.detectRow}>
298
- <span>
299
- <strong>llama.cpp</strong>
300
- </span>
301
- {detect.llamaCpp !== null ? (
302
- <span>
303
- {detectBadge(detect.llamaCpp.installed)}
304
- {detect.llamaCpp.installed && detect.llamaCpp.detail && (
305
- <span style={{ fontSize: "0.8rem", color: "#a0a0c0", marginLeft: "0.5rem" }}>
306
- {detect.llamaCpp.detail}
307
- </span>
308
- )}
309
- </span>
310
- ) : (
311
- <span style={{ color: "#888", fontSize: "0.85rem" }}>
312
- not checked
313
- </span>
314
- )}
315
- </div>
316
-
317
- {/* ONNX */}
318
- <div style={styles.detectRow}>
319
- <span>
320
- <strong>ONNX Runtime</strong>
321
- </span>
322
- {detect.onnx !== null ? (
323
- <span>
324
- {detectBadge(detect.onnx.installed)}
325
- {detect.onnx.installed && detect.onnx.detail && (
326
- <span style={{ fontSize: "0.8rem", color: "#a0a0c0", marginLeft: "0.5rem" }}>
327
- {detect.onnx.detail}
328
- </span>
329
- )}
330
- </span>
331
- ) : (
332
- <span style={{ color: "#888", fontSize: "0.85rem" }}>
333
- not checked
334
- </span>
335
- )}
336
- </div>
337
-
338
- {detect.error && (
339
- <p style={{ color: "#f44336", fontSize: "0.8rem", marginTop: "0.5rem" }}>
340
- Detection error: {detect.error}
341
- </p>
342
- )}
343
- </>
344
- )}
345
-
346
- {detectError && (
347
- <p style={{ color: "#f44336", fontSize: "0.85rem" }}>
348
- Error: {detectError}
349
- </p>
350
- )}
351
-
352
- <div style={{ marginTop: "1rem" }}>
353
- <button
354
- style={styles.button}
355
- onClick={runDetect}
356
- disabled={runningDetect}
357
- >
358
- {runningDetect ? "Detecting..." : "Run Detection"}
359
- </button>
360
- <span style={{ fontSize: "0.8rem", color: "#888", marginLeft: "0.75rem" }}>
361
- Or run <code>/megasetup</code> in the chat for an interactive wizard.
362
- </span>
363
- </div>
364
-
365
- {/* Configure buttons — appear after detection runs */}
366
- {detect && (
367
- <div style={{ marginTop: "1rem", paddingTop: "0.75rem", borderTop: "1px solid #2a2a4e" }}>
368
- <div style={{ fontSize: "0.9rem", fontWeight: 600, marginBottom: "0.5rem" }}>
369
- Configure
370
- </div>
371
- <div style={{ display: "flex", gap: "0.5rem", flexWrap: "wrap" }}>
372
- <button
373
- style={{ ...styles.button, opacity: detect.ollama?.installed ? 1 : 0.4 }}
374
- onClick={() => applyEmbedder("ollama")}
375
- disabled={!detect.ollama?.installed || configuring !== null}
376
- >
377
- {configuring === "ollama" ? "Writing..." : "Use Ollama"}
378
- </button>
379
- <button
380
- style={{ ...styles.button, opacity: detect.llamaCpp?.installed ? 1 : 0.4 }}
381
- onClick={() => applyEmbedder("llama")}
382
- disabled={!detect.llamaCpp?.installed || configuring !== null}
383
- >
384
- {configuring === "llama" ? "Writing..." : "Use llama.cpp"}
385
- </button>
386
- <button
387
- style={{ ...styles.button, background: "#444" }}
388
- onClick={() => applyEmbedder("trigram")}
389
- disabled={configuring !== null}
390
- >
391
- {configuring === "trigram" ? "Writing..." : "Use Trigram (default)"}
392
- </button>
393
- </div>
394
- {configResult && (
395
- <div style={styles.warning}>
396
- {configResult.alreadyActive
397
- ? "Already active — no restart needed."
398
- : `Configured ${configResult.embedder}. Restart pi to activate (config written to ${configResult.envPath}).`}
399
- </div>
400
- )}
401
- {configError && (
402
- <p style={{ color: "#f44336", fontSize: "0.85rem", marginTop: "0.5rem" }}>
403
- Configure error: {configError}
404
- </p>
405
- )}
406
- </div>
407
- )}
408
- </div>
409
-
410
- {/* Custom (remote) embedder — third-party / hosted endpoint */}
411
- <div style={styles.section}>
412
- <h3 style={styles.sectionTitle}>Custom Endpoint (remote / third-party)</h3>
413
- <p style={{ fontSize: "0.85rem", color: "#a0a0c0", marginTop: 0 }}>
414
- Point at any OpenAI-compatible embeddings API or hosted endpoint.
415
- This opts in to a non-loopback connection (sets{" "}
416
- <code>MEGACOMPACT_ALLOW_REMOTE_EMBEDDER=1</code>) — your prompts'
417
- embedding requests will be sent to the URL you enter. Default is
418
- loopback-only.
419
- </p>
420
- <div style={{ display: "flex", gap: "0.5rem", flexWrap: "wrap", alignItems: "center" }}>
421
- <input
422
- type="url"
423
- placeholder="https://api.example.com/v1/embeddings"
424
- value={customUrl}
425
- onChange={(e) => setCustomUrl(e.target.value)}
426
- style={{
427
- flex: "1 1 300px",
428
- background: "#12122a",
429
- color: "#e0e0e0",
430
- border: "1px solid #2a2a4e",
431
- borderRadius: "6px",
432
- padding: "0.4rem 0.6rem",
433
- fontSize: "0.85rem",
434
- fontFamily: "monospace",
435
- }}
436
- />
437
- <button
438
- style={{ ...styles.button, opacity: customUrl ? 1 : 0.4 }}
439
- onClick={() => applyEmbedder("custom", customUrl)}
440
- disabled={!customUrl || configuring !== null}
441
- >
442
- {configuring === "custom" ? "Writing..." : "Use Custom URL"}
443
- </button>
444
- </div>
445
- <div style={styles.warning}>
446
- <strong>Heads up:</strong> a remote endpoint receives the text you embed
447
- (it does NOT receive your full conversation — only the strings passed to
448
- <code> embed()</code> for recall/dedup). Verify the endpoint's privacy
449
- policy before use.
450
- </div>
451
- </div>
452
-
453
- {/* Help Section */}
454
- <div style={styles.section}>
455
- <h3 style={styles.sectionTitle}>How to Upgrade</h3>
456
- <ul style={{ fontSize: "0.85rem", lineHeight: 1.6, paddingLeft: "1.25rem" }}>
457
- <li>
458
- <strong>Ollama:</strong> Install from{" "}
459
- <a
460
- href="https://ollama.com"
461
- style={{ color: "#6a9fff" }}
462
- target="_blank"
463
- rel="noopener noreferrer"
464
- >
465
- ollama.com
466
- </a>
467
- , then <code>ollama pull nomic-embed-text</code> and restart pi.
468
- Set <code>MEGACOMPACT_EMBEDDING_URL=http://localhost:11434/api/embeddings</code>.
469
- </li>
470
- <li>
471
- <strong>llama.cpp:</strong> Build or install llama.cpp, run{" "}
472
- <code>llama-server</code> with an embedding model, and set
473
- the URL accordingly.
474
- </li>
475
- <li>
476
- <strong>ONNX Runtime:</strong> Install{" "}
477
- <code>onnxruntime-node</code> in the project root. Not yet
478
- integrated — see docs for manual setup.
479
- </li>
480
- </ul>
481
- </div>
482
- </div>
483
- );
484
- }
485
-
486
-
487
- // ---------------------------------------------------------------------------
488
- // SetupTab shell — sub-tabs for Embedder / Config / Game Mode / Achievements.
489
- // Config + Game + Achievements moved here from the top-level tab bar (audit
490
- // #9: 15 tabs was too many; the novelty surfaces and the config editor crowd
491
- // the bar for the 95% who don't use them). The sub-tab nav reuses the
492
- // inline-style approach of the embedder section for visual consistency.
493
- // ---------------------------------------------------------------------------
494
-
495
25
  type SetupSubTab = "embedder" | "config" | "game" | "achievements";
496
26
 
497
27
  const subTabNavStyle: React.CSSProperties = {
@@ -520,7 +50,7 @@ export default function SetupTab(): React.ReactElement {
520
50
  const [subTab, setSubTab] = useState<SetupSubTab>("embedder");
521
51
 
522
52
  return (
523
- <div style={styles.container}>
53
+ <div style={containerStyle}>
524
54
  <nav style={subTabNavStyle} aria-label="Setup sections">
525
55
  <button
526
56
  type="button"
@@ -0,0 +1,32 @@
1
+ /**
2
+ * api-contracts/embedder-health.ts — Embedder health probe response types.
3
+ *
4
+ * Types for the GET /api/embedder-health endpoint used by the dashboard Setup
5
+ * tab's EmbedderHealthCard. Describes the result of round-tripping a test
6
+ * embed through the active embedder (latency + dimensions + reachability).
7
+ *
8
+ * PREVENT-PI-004: type definitions only, no network code.
9
+ * PREVENT-011: no `any` type — all types are explicit.
10
+ */
11
+
12
+ /**
13
+ * Response for GET /api/embedder-health.
14
+ * Probes the active embedder with a single test embed and reports reachability,
15
+ * latency, vector dimensionality, and a masked endpoint URL.
16
+ */
17
+ export interface EmbedderHealthResponse {
18
+ /** Which embedder implementation is currently active in the running process. */
19
+ readonly activeEmbedder: "trigram" | "http" | "minilm" | "unknown";
20
+ /** "ok" — test embed succeeded; "unreachable" — endpoint not reachable (http
21
+ * embedder); "error" — probe threw some other error. */
22
+ readonly status: "ok" | "unreachable" | "error";
23
+ /** Round-trip latency of the test embed in milliseconds. */
24
+ readonly latencyMs: number;
25
+ /** Vector dimensionality reported by the active embedder, or 0 on error. */
26
+ readonly dim: number;
27
+ /** Masked endpoint URL (scheme://hostname:port, secrets/paths stripped), or
28
+ * null when no URL is configured. */
29
+ readonly url: string | null;
30
+ /** Error message when status is "unreachable" or "error", otherwise absent. */
31
+ readonly error?: string;
32
+ }