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
@@ -1,441 +1,15 @@
1
- import { listRaptorNodes } from "../store/sqlite/raptor.js";
2
- import { decodeEmbedding } from "../store/sqlite/utils.js";
3
- import { getOrComputeEmbedding, cosineSimilarity } from "./embedding.js";
4
- // ---------------------------------------------------------------------------
5
- // Feature flags and env helpers
6
- // ---------------------------------------------------------------------------
7
- function flagEnabled(name, def) {
8
- const v = process.env[name];
9
- if (v === undefined)
10
- return def;
11
- return v === "true" || v === "1";
12
- }
13
- export function areTurnsEnabled() {
14
- return flagEnabled("MEGACOMPACT_MEMORY_GRAPH_SEED_TURNS", true);
15
- }
16
- export function isTurnContentEnabled() {
17
- return flagEnabled("MEGACOMPACT_MEMORY_GRAPH_SEED_TURN_CONTENT", true) &&
18
- flagEnabled("MEGACOMPACT_DB_MIRROR", false);
19
- }
20
- export function isTurnContentFlaggedOn() {
21
- return flagEnabled("MEGACOMPACT_MEMORY_GRAPH_SEED_TURN_CONTENT", true);
22
- }
23
- export function areMemoriesEnabled() {
24
- return flagEnabled("MEGACOMPACT_MEMORY_GRAPH_SEED_MEMORIES", true);
25
- }
26
- // ---------------------------------------------------------------------------
27
- // Source: checkpoints (from context_chunks table)
28
- // ---------------------------------------------------------------------------
29
- export function buildCheckpointNodes(db, sessionId, nodes, edges) {
30
- const rows = sessionId
31
- ? db
32
- .prepare(`SELECT id, session_id, summary, token_estimate, timestamp,
33
- dedup_status, topic_summary, key_decisions,
34
- normalized_text, embedding_blob
35
- FROM context_chunks
36
- WHERE session_id = ?
37
- ORDER BY timestamp ASC`)
38
- .all(sessionId)
39
- : db
40
- .prepare(`SELECT id, session_id, summary, token_estimate, timestamp,
41
- dedup_status, topic_summary, key_decisions,
42
- normalized_text, embedding_blob
43
- FROM context_chunks
44
- ORDER BY timestamp ASC`)
45
- .all();
46
- if (rows.length === 0)
47
- return;
48
- let prevId = null;
49
- for (const row of rows) {
50
- const id = String(row.id);
51
- const rowSessionId = sessionId || String(row.session_id ?? "");
52
- const summary = String(row.summary ?? "");
53
- const node = {
54
- id,
55
- sessionId: rowSessionId,
56
- label: id,
57
- summaryTruncated: summary.length > 200 ? summary.slice(0, 197) + "..." : summary,
58
- tokenEstimate: Number(row.token_estimate ?? 0),
59
- timestamp: Number(row.timestamp ?? Date.now()),
60
- dedupStatus: row.dedup_status ? String(row.dedup_status) : undefined,
61
- raptorLevel: 0,
62
- topicSummary: row.topic_summary ? String(row.topic_summary) : undefined,
63
- decisionCount: row.key_decisions ? safeJsonCount(String(row.key_decisions)) : 0,
64
- textSnippet: summary.length > 200 ? summary.slice(0, 197) + "..." : summary,
65
- nodeType: "checkpoint",
66
- };
67
- nodes.push(node);
68
- if (prevId !== null) {
69
- edges.push({ source: prevId, target: id, weight: 1.0, type: "temporal" });
70
- }
71
- prevId = id;
72
- }
73
- addCheckpointSemanticEdges(rows, edges);
74
- }
75
- function addCheckpointSemanticEdges(rows, edges) {
76
- const embeddings = [];
77
- for (const row of rows) {
78
- const blob = row.embedding_blob;
79
- embeddings.push({
80
- id: String(row.id),
81
- blob: blob instanceof Buffer ? blob : null,
82
- });
83
- }
84
- for (let i = 0; i < embeddings.length; i++) {
85
- if (!embeddings[i].blob)
86
- continue;
87
- const a = decodeEmbedding(embeddings[i].blob);
88
- for (let j = i + 1; j < embeddings.length; j++) {
89
- if (!embeddings[j].blob)
90
- continue;
91
- const b = decodeEmbedding(embeddings[j].blob);
92
- const sim = cosineSimilarity(a, b);
93
- if (sim > 0) {
94
- edges.push({
95
- source: embeddings[i].id,
96
- target: embeddings[j].id,
97
- weight: sim,
98
- type: "semantic",
99
- });
100
- }
101
- }
102
- }
103
- }
104
- // ---------------------------------------------------------------------------
105
- // Source A: turn structural nodes (from turns table, metadata-only)
106
- // ---------------------------------------------------------------------------
107
- export function buildTurnNodes(db, sessionId, nodes, edges) {
108
- const existingIds = new Set(nodes.map((n) => n.id));
109
- const rows = sessionId
110
- ? db
111
- .prepare(`SELECT turn_index, session_id, role, pressure_band, ctx_tokens, ctx_percent,
112
- epoch_id, ended_at
113
- FROM turns
114
- WHERE session_id = ?
115
- ORDER BY turn_index ASC`)
116
- .all(sessionId)
117
- : db
118
- .prepare(`SELECT turn_index, session_id, role, pressure_band, ctx_tokens, ctx_percent,
119
- epoch_id, ended_at
120
- FROM turns
121
- ORDER BY turn_index ASC`)
122
- .all();
123
- if (rows.length === 0)
124
- return;
125
- let prevId = null;
126
- for (const row of rows) {
127
- const ti = Number(row.turn_index);
128
- const rowSessionId = sessionId || String(row.session_id ?? "");
129
- const nodeId = `turn:${rowSessionId}:${ti}`;
130
- if (existingIds.has(nodeId))
131
- continue;
132
- existingIds.add(nodeId);
133
- const role = row.role ? String(row.role) : "unknown";
134
- const endedAt = row.ended_at ? Number(row.ended_at) : Date.now();
135
- const node = {
136
- id: nodeId,
137
- sessionId: rowSessionId,
138
- label: `Turn ${ti}`,
139
- summaryTruncated: `Turn ${ti}: ${role}${row.epoch_id ? ` (epoch: ${String(row.epoch_id)})` : ""}`,
140
- tokenEstimate: row.ctx_tokens ? Number(row.ctx_tokens) : 0,
141
- timestamp: endedAt,
142
- dedupStatus: undefined,
143
- raptorLevel: 0,
144
- topicSummary: undefined,
145
- decisionCount: 0,
146
- textSnippet: `Turn ${ti}: ${role} — ${String(row.ctx_tokens ?? "?")} tokens`,
147
- nodeType: "turn",
148
- epochId: row.epoch_id ? String(row.epoch_id) : undefined,
149
- };
150
- nodes.push(node);
151
- if (prevId !== null) {
152
- edges.push({ source: prevId, target: nodeId, weight: 1.0, type: "temporal" });
153
- }
154
- prevId = nodeId;
155
- }
156
- }
157
- // ---------------------------------------------------------------------------
158
- // Source B: turn-content nodes (from turns JOIN raw_transcript)
159
- // ---------------------------------------------------------------------------
160
- export function buildTurnContentNodes(turnDb, mainDb, sessionId, nodes, edges) {
161
- // Local dedup only — DON'T skip ids from Source A (turn-structural). Source A
162
- // and Source B share the same node id (turn:<session>:<idx>); Gate 2
163
- // (identity_merge) merges them with the richest nodeType winning. Using the
164
- // global nodes array here would skip every node (Source A already added them).
165
- const seen = new Set();
166
- // turns live in turns.db, raw_transcript in the main db — can't JOIN across
167
- // databases, so query separately and merge in JS.
168
- const turnRows = sessionId
169
- ? turnDb
170
- .prepare(`SELECT turn_index, role, ended_at
171
- FROM turns
172
- WHERE session_id = ?
173
- ORDER BY turn_index ASC`)
174
- .all(sessionId)
175
- : turnDb
176
- .prepare(`SELECT turn_index, role, ended_at
177
- FROM turns
178
- ORDER BY turn_index ASC`)
179
- .all();
180
- // Build a map of (session_id, turn_index) → content from raw_transcript.
181
- const contentMap = new Map();
182
- try {
183
- const transcriptRows = sessionId
184
- ? mainDb
185
- .prepare(`SELECT turn_index, content_bytes FROM raw_transcript WHERE session_id = ?`)
186
- .all(sessionId)
187
- : mainDb
188
- .prepare(`SELECT turn_index, content_bytes FROM raw_transcript`)
189
- .all();
190
- for (const r of transcriptRows) {
191
- contentMap.set(String(r.turn_index), String(r.content_bytes ?? ""));
192
- }
193
- }
194
- catch {
195
- // raw_transcript may not exist in the main db (dbMirror off) — return empty.
196
- return;
197
- }
198
- // Merge: only produce nodes where both a turn row AND transcript content exist.
199
- const rows = turnRows
200
- .filter((t) => contentMap.has(String(t.turn_index)))
201
- .map((t) => ({
202
- turn_index: t.turn_index,
203
- role: t.role,
204
- ended_at: t.ended_at,
205
- content_bytes: contentMap.get(String(t.turn_index)) ?? "",
206
- }));
207
- if (rows.length === 0)
208
- return;
209
- const turnContentNodes = [];
210
- for (const row of rows) {
211
- const ti = Number(row.turn_index);
212
- const nodeId = `turn:${sessionId}:${ti}`;
213
- if (seen.has(nodeId))
214
- continue;
215
- seen.add(nodeId);
216
- const contentBytes = row.content_bytes ? String(row.content_bytes) : "";
217
- const snippet = contentBytes.length > 200 ? contentBytes.slice(0, 197) + "..." : contentBytes;
218
- const node = {
219
- id: nodeId,
220
- sessionId,
221
- label: `Turn ${ti}`,
222
- summaryTruncated: snippet,
223
- tokenEstimate: contentBytes.length,
224
- timestamp: row.ended_at ? Number(row.ended_at) : Date.now(),
225
- dedupStatus: undefined,
226
- raptorLevel: 0,
227
- topicSummary: undefined,
228
- decisionCount: 0,
229
- textSnippet: snippet,
230
- nodeType: "turn-content",
231
- epochId: undefined,
232
- };
233
- turnContentNodes.push(node);
234
- }
235
- if (turnContentNodes.length > 1) {
236
- const embeddings = turnContentNodes.map((n) => {
237
- try {
238
- return { id: n.id, vec: getOrComputeEmbedding(mainDb, n.textSnippet) };
239
- }
240
- catch {
241
- return { id: n.id, vec: null };
242
- }
243
- });
244
- for (let i = 0; i < embeddings.length; i++) {
245
- if (!embeddings[i].vec)
246
- continue;
247
- for (let j = i + 1; j < embeddings.length; j++) {
248
- if (!embeddings[j].vec)
249
- continue;
250
- const sim = cosineSimilarity(embeddings[i].vec, embeddings[j].vec);
251
- if (sim > 0) {
252
- edges.push({
253
- source: embeddings[i].id,
254
- target: embeddings[j].id,
255
- weight: sim,
256
- type: "semantic",
257
- });
258
- }
259
- }
260
- }
261
- linkTurnToCheckpointEdges(mainDb, sessionId, turnContentNodes, edges);
262
- }
263
- nodes.push(...turnContentNodes);
264
- }
265
- // ---------------------------------------------------------------------------
266
- // Source C: memory nodes
267
- // ---------------------------------------------------------------------------
268
- export function buildMemoryNodes(db, sessionId, nodes, edges) {
269
- const existingIds = new Set(nodes.map((n) => n.id));
270
- const rows = db
271
- .prepare(`SELECT id, content, source_turn, created_at
272
- FROM memories
273
- ORDER BY created_at ASC`)
274
- .all();
275
- if (rows.length === 0)
276
- return;
277
- const memoryNodes = [];
278
- for (const row of rows) {
279
- const id = `mem:${String(row.id)}`;
280
- if (existingIds.has(id))
281
- continue;
282
- existingIds.add(id);
283
- const content = row.content ? String(row.content) : "";
284
- const snippet = content.length > 200 ? content.slice(0, 197) + "..." : content;
285
- const node = {
286
- id,
287
- sessionId,
288
- label: `Memory ${String(row.id)}`,
289
- summaryTruncated: snippet,
290
- tokenEstimate: content.length,
291
- timestamp: row.created_at ? Number(row.created_at) : Date.now(),
292
- dedupStatus: undefined,
293
- raptorLevel: 0,
294
- topicSummary: undefined,
295
- decisionCount: 0,
296
- textSnippet: snippet,
297
- nodeType: "memory",
298
- epochId: undefined,
299
- };
300
- memoryNodes.push(node);
301
- }
302
- if (memoryNodes.length > 1) {
303
- const embeddings = memoryNodes.map((n) => {
304
- try {
305
- return { id: n.id, vec: getOrComputeEmbedding(db, n.textSnippet) };
306
- }
307
- catch {
308
- return { id: n.id, vec: null };
309
- }
310
- });
311
- for (let i = 0; i < embeddings.length; i++) {
312
- if (!embeddings[i].vec)
313
- continue;
314
- for (let j = i + 1; j < embeddings.length; j++) {
315
- if (!embeddings[j].vec)
316
- continue;
317
- const sim = cosineSimilarity(embeddings[i].vec, embeddings[j].vec);
318
- if (sim > 0) {
319
- edges.push({
320
- source: embeddings[i].id,
321
- target: embeddings[j].id,
322
- weight: sim,
323
- type: "semantic",
324
- });
325
- }
326
- }
327
- }
328
- crossLinkMemoryToCheckpoints(memoryNodes, nodes, edges);
329
- }
330
- nodes.push(...memoryNodes);
331
- }
332
- // ---------------------------------------------------------------------------
333
- // RAPTOR annotations
334
- // ---------------------------------------------------------------------------
335
- export function addRaptorAnnotations(sessionId, stateDir, nodes, edges) {
336
- const raptorNodes = listRaptorNodes(sessionId, stateDir);
337
- if (!raptorNodes || raptorNodes.length === 0)
338
- return;
339
- const nodeIndex = new Map();
340
- for (let i = 0; i < nodes.length; i++) {
341
- nodeIndex.set(nodes[i].id, i);
342
- }
343
- for (const rn of raptorNodes) {
344
- const idx = nodeIndex.get(rn.id);
345
- if (idx !== undefined) {
346
- nodes[idx].raptorLevel = rn.level;
347
- }
348
- if (!rn.parentId)
349
- continue;
350
- if (nodeIndex.has(rn.id) && nodeIndex.has(rn.parentId)) {
351
- edges.push({
352
- source: rn.id,
353
- target: rn.parentId,
354
- weight: Math.max(0.1, 1.0 - rn.level * 0.1),
355
- type: "raptor_parent",
356
- });
357
- }
358
- }
359
- }
360
- // ---------------------------------------------------------------------------
361
- // Cross-source edge linking
362
- // ---------------------------------------------------------------------------
363
- function linkTurnToCheckpointEdges(db, sessionId, turnNodes, edges) {
364
- const checkpoints = db
365
- .prepare(`SELECT id, timestamp FROM context_chunks WHERE session_id = ? ORDER BY timestamp ASC`)
366
- .all(sessionId);
367
- for (const tn of turnNodes) {
368
- let bestCp = null;
369
- for (const cp of checkpoints) {
370
- const diff = Math.abs(tn.timestamp - cp.timestamp);
371
- if (bestCp === null || diff < bestCp.diff) {
372
- bestCp = { id: cp.id, diff };
373
- }
374
- }
375
- if (bestCp) {
376
- edges.push({
377
- source: tn.id,
378
- target: bestCp.id,
379
- weight: 1.0,
380
- type: "temporal",
381
- });
382
- }
383
- }
384
- }
385
- function crossLinkMemoryToCheckpoints(memoryNodes, allNodes, edges) {
386
- for (const mn of memoryNodes) {
387
- let bestNeighbor = null;
388
- for (const n of allNodes) {
389
- if (n.nodeType !== "checkpoint" && n.nodeType !== "turn-content")
390
- continue;
391
- if (n.id === mn.id)
392
- continue;
393
- const diff = Math.abs(mn.timestamp - n.timestamp);
394
- if (bestNeighbor === null || diff < bestNeighbor.diff) {
395
- bestNeighbor = { id: n.id, diff };
396
- }
397
- }
398
- if (bestNeighbor) {
399
- edges.push({
400
- source: mn.id,
401
- target: bestNeighbor.id,
402
- weight: 0.85,
403
- type: "semantic",
404
- });
405
- }
406
- }
407
- }
408
- // ---------------------------------------------------------------------------
409
- // Edge deduplication
410
- // ---------------------------------------------------------------------------
411
- export function deduplicateEdges(edges) {
412
- const seen = new Map();
413
- for (const e of edges) {
414
- const keyA = `${e.source}|${e.target}`;
415
- const keyB = `${e.target}|${e.source}`;
416
- const existing = seen.get(keyA) ?? seen.get(keyB);
417
- if (existing) {
418
- if (e.weight > existing.weight) {
419
- seen.set(keyA, e);
420
- }
421
- }
422
- else {
423
- seen.set(keyA, e);
424
- }
425
- }
426
- return [...seen.values()];
427
- }
428
- // ---------------------------------------------------------------------------
429
- // Helpers
430
- // ---------------------------------------------------------------------------
431
- function safeJsonCount(raw) {
432
- if (!raw || typeof raw !== "string")
433
- return 0;
434
- try {
435
- const arr = JSON.parse(raw);
436
- return Array.isArray(arr) ? arr.length : 0;
437
- }
438
- catch {
439
- return 0;
440
- }
441
- }
1
+ /**
2
+ * sources.ts D3 data-source builders for the memory graph.
3
+ *
4
+ * Thin pointer: each source builder (checkpoint, turn, turn-content, memory) plus
5
+ * RAPTOR annotation, edge dedup, and feature flags lives in ./sources/* to keep
6
+ * this file (and every impl file) under the 500-line limit. The full public API
7
+ * is re-exported here so existing callers importing "./memoryGraph/sources.js"
8
+ * are unchanged.
9
+ */
10
+ export { areTurnsEnabled, isTurnContentEnabled, isTurnContentFlaggedOn, areMemoriesEnabled, } from "./sources/flags.js";
11
+ export { buildCheckpointNodes } from "./sources/checkpoints.js";
12
+ export { buildTurnNodes, buildTurnContentNodes, } from "./sources/turns.js";
13
+ export { buildMemoryNodes } from "./sources/memories.js";
14
+ export { addRaptorAnnotations } from "./sources/raptor.js";
15
+ export { deduplicateEdges } from "./sources/edges.js";
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Shared helpers for the memoryGraph-gates split files.
3
+ * Extracted from src/memoryGraph-gates.test.ts: temp dirs, node/edge/ws
4
+ * builders, withEnv, and populateStore (real SQLite seeding).
5
+ */
6
+ import { mkdtempSync } from "node:fs";
7
+ import { tmpdir } from "node:os";
8
+ import { join } from "node:path";
9
+ import { openStore } from "../store/sqlite/utils.js";
10
+ import { upsertCheckpoint } from "../store/sqlite/checkpoints.js";
11
+ import { recordTurn, newConversationId } from "../store/sqlite/turns.js";
12
+ import { appendRawTranscript } from "../store/sqlite/raw-transcript.js";
13
+ export const baseTmp = mkdtempSync(join(tmpdir(), "mc-mgraph-gates-"));
14
+ let counter = 0;
15
+ export function tmpDir() {
16
+ return join(baseTmp, `run-${counter++}`);
17
+ }
18
+ export function n(id, overrides = {}) {
19
+ return {
20
+ id,
21
+ sessionId: "sess_test",
22
+ label: id,
23
+ summaryTruncated: "",
24
+ tokenEstimate: 0,
25
+ timestamp: 1000,
26
+ dedupStatus: undefined,
27
+ raptorLevel: 0,
28
+ topicSummary: undefined,
29
+ decisionCount: 0,
30
+ textSnippet: "",
31
+ nodeType: "checkpoint",
32
+ epochId: undefined,
33
+ ...overrides,
34
+ };
35
+ }
36
+ export function e(source, target, overrides = {}) {
37
+ return { source, target, weight: 1.0, type: "temporal", ...overrides };
38
+ }
39
+ export function ws(nodes, edges = []) {
40
+ return { nodes, edges };
41
+ }
42
+ /** Save and restore env vars around a test. */
43
+ export function withEnv(env, fn) {
44
+ const saved = {};
45
+ for (const k of Object.keys(env)) {
46
+ saved[k] = process.env[k];
47
+ if (env[k] === undefined) {
48
+ delete process.env[k];
49
+ }
50
+ else {
51
+ process.env[k] = env[k];
52
+ }
53
+ }
54
+ try {
55
+ fn();
56
+ }
57
+ finally {
58
+ for (const k of Object.keys(env)) {
59
+ if (saved[k] === undefined) {
60
+ delete process.env[k];
61
+ }
62
+ else {
63
+ process.env[k] = saved[k];
64
+ }
65
+ }
66
+ }
67
+ }
68
+ export function populateStore(dir, sessionId, sources) {
69
+ const db = openStore(dir);
70
+ if (sources.checkpoint) {
71
+ upsertCheckpoint({
72
+ checkpointId: "chkpt_001",
73
+ sessionId,
74
+ regionHash: "abc",
75
+ contentHash: "def",
76
+ normalizedText: "checkpoint one",
77
+ summary: "Checkpoint One",
78
+ tokenEstimate: 50,
79
+ timestamp: 1000,
80
+ embedding: [],
81
+ keyDecisions: [],
82
+ nextSteps: [],
83
+ filesModified: [],
84
+ }, dir);
85
+ upsertCheckpoint({
86
+ checkpointId: "chkpt_002",
87
+ sessionId,
88
+ regionHash: "ghi",
89
+ contentHash: "jkl",
90
+ normalizedText: "checkpoint two",
91
+ summary: "Checkpoint Two",
92
+ tokenEstimate: 60,
93
+ timestamp: 2000,
94
+ embedding: [],
95
+ keyDecisions: [],
96
+ nextSteps: [],
97
+ filesModified: [],
98
+ }, dir);
99
+ }
100
+ if (sources.turn) {
101
+ const convId = newConversationId();
102
+ recordTurn({ conversationId: convId, sessionId, turnIndex: 0, role: "user", endedAt: 1500, ctxTokens: 100 }, dir);
103
+ recordTurn({ conversationId: convId, sessionId, turnIndex: 1, role: "assistant", endedAt: 2500, ctxTokens: 200 }, dir);
104
+ }
105
+ if (sources.turnContent) {
106
+ const rows = [
107
+ { sessionId, seq: 0, role: "user", contentBytes: "hello from the user", contentHash: "hash_0", toolName: null, messageTimestamp: 1500, checkpointEpoch: "", turnIndex: 0 },
108
+ { sessionId, seq: 1, role: "assistant", contentBytes: "response from assistant", contentHash: "hash_1", toolName: null, messageTimestamp: 2500, checkpointEpoch: "", turnIndex: 1 },
109
+ ];
110
+ for (const row of rows) {
111
+ appendRawTranscript(db, row);
112
+ }
113
+ }
114
+ if (sources.memory) {
115
+ db.prepare(`INSERT OR IGNORE INTO memories (content, kind, created_at, source_turn)
116
+ VALUES (?, ?, ?, ?)`).run("remembered fact", "fact", 2000, 0);
117
+ db.prepare(`INSERT OR IGNORE INTO memories (content, kind, created_at, source_turn)
118
+ VALUES (?, ?, ?, ?)`).run("user preference", "preference", 3000, 1);
119
+ }
120
+ }