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