@timmeck/brain-core 2.27.0 → 2.28.0

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.
@@ -0,0 +1,150 @@
1
+ import type Database from 'better-sqlite3';
2
+ import type { ThoughtStream } from '../consciousness/thought-stream.js';
3
+ export interface MemoryPalaceConfig {
4
+ brainName: string;
5
+ /** Maximum BFS path depth. Default: 6 */
6
+ maxPathDepth?: number;
7
+ /** Minimum strength for auto-detected connections. Default: 0.3 */
8
+ minAutoStrength?: number;
9
+ }
10
+ export type NodeType = 'principle' | 'anti_pattern' | 'strategy' | 'hypothesis' | 'experiment' | 'journal' | 'anomaly' | 'causal_edge' | 'emergence' | 'prediction' | 'curiosity_gap';
11
+ export type RelationType = 'derived_from' | 'contradicts' | 'supports' | 'caused_by' | 'tested_by' | 'related_to' | 'supersedes' | 'references';
12
+ export interface KnowledgeConnection {
13
+ id?: number;
14
+ sourceType: NodeType;
15
+ sourceId: string;
16
+ targetType: NodeType;
17
+ targetId: string;
18
+ relation: RelationType;
19
+ strength: number;
20
+ autoDetected: boolean;
21
+ createdAt: string;
22
+ }
23
+ export interface KnowledgeNode {
24
+ type: NodeType;
25
+ id: string;
26
+ label: string;
27
+ connections: number;
28
+ }
29
+ export interface KnowledgeEdge {
30
+ source: string;
31
+ target: string;
32
+ relation: RelationType;
33
+ strength: number;
34
+ }
35
+ export interface KnowledgeMap {
36
+ nodes: KnowledgeNode[];
37
+ edges: KnowledgeEdge[];
38
+ }
39
+ export interface PathStep {
40
+ type: NodeType;
41
+ id: string;
42
+ relation: RelationType;
43
+ }
44
+ export interface MemoryPalaceStats {
45
+ totalNodes: number;
46
+ totalEdges: number;
47
+ density: number;
48
+ nodesByType: Record<string, number>;
49
+ topConnected: Array<{
50
+ type: NodeType;
51
+ id: string;
52
+ connections: number;
53
+ }>;
54
+ avgStrength: number;
55
+ }
56
+ export interface BuildResult {
57
+ newConnections: number;
58
+ totalConnections: number;
59
+ scannedSources: string[];
60
+ }
61
+ export interface MemoryPalaceStatus {
62
+ stats: MemoryPalaceStats;
63
+ recentConnections: KnowledgeConnection[];
64
+ topConnectedNodes: Array<{
65
+ type: NodeType;
66
+ id: string;
67
+ connections: number;
68
+ }>;
69
+ uptime: number;
70
+ }
71
+ export interface MemoryPalaceDataSources {
72
+ /** Query confirmed hypotheses: {id, statement, status} */
73
+ getHypotheses?: (status?: string, limit?: number) => Array<{
74
+ id?: number | string;
75
+ statement: string;
76
+ status?: string;
77
+ }>;
78
+ /** Query principles: {id, statement} */
79
+ getPrinciples?: (domain?: string, limit?: number) => Array<{
80
+ id: number | string;
81
+ statement: string;
82
+ }>;
83
+ /** Query anti-patterns: {id, statement} */
84
+ getAntiPatterns?: (domain?: string, limit?: number) => Array<{
85
+ id: number | string;
86
+ statement: string;
87
+ }>;
88
+ /** Query experiments: {id, name, hypothesis} */
89
+ getExperiments?: (status?: string, limit?: number) => Array<{
90
+ id?: number | string;
91
+ name: string;
92
+ hypothesis: string;
93
+ }>;
94
+ /** Query journal entries: {id, title, tags (JSON string or array)} */
95
+ getJournalEntries?: (limit?: number) => Array<{
96
+ id?: number;
97
+ title: string;
98
+ tags: string[] | string;
99
+ data?: unknown;
100
+ }>;
101
+ /** Query anomalies: {id, title} */
102
+ getAnomalies?: (type?: string, limit?: number) => Array<{
103
+ id?: number;
104
+ title: string;
105
+ }>;
106
+ /** Query curiosity gaps: {id, topic} */
107
+ getCuriosityGaps?: (limit?: number) => Array<{
108
+ id?: number;
109
+ topic: string;
110
+ }>;
111
+ }
112
+ export declare function runMemoryPalaceMigration(db: Database.Database): void;
113
+ export declare class MemoryPalace {
114
+ private readonly db;
115
+ private readonly config;
116
+ private readonly log;
117
+ private ts;
118
+ private sources;
119
+ private startTime;
120
+ private readonly stmtInsertConnection;
121
+ private readonly stmtGetConnectionsFor;
122
+ private readonly stmtGetConnectionsFrom;
123
+ private readonly stmtGetConnectionsTo;
124
+ private readonly stmtCountEdges;
125
+ private readonly stmtDistinctNodes;
126
+ private readonly stmtAvgStrength;
127
+ private readonly stmtTopConnected;
128
+ private readonly stmtRecentConnections;
129
+ private readonly stmtNodesByType;
130
+ private readonly stmtAllEdges;
131
+ constructor(db: Database.Database, config: MemoryPalaceConfig);
132
+ setThoughtStream(stream: ThoughtStream): void;
133
+ setDataSources(sources: MemoryPalaceDataSources): void;
134
+ buildConnections(): BuildResult;
135
+ addConnection(sourceType: NodeType, sourceId: string, targetType: NodeType, targetId: string, relation: RelationType, strength?: number): boolean;
136
+ getConnections(type: NodeType, id: string): KnowledgeConnection[];
137
+ getPath(fromType: NodeType, fromId: string, toType: NodeType, toId: string, maxDepth?: number): PathStep[] | null;
138
+ getKnowledgeMap(topic?: string, limit?: number): KnowledgeMap;
139
+ getIsolatedNodes(): Array<{
140
+ type: string;
141
+ id: string;
142
+ }>;
143
+ getStats(): MemoryPalaceStats;
144
+ getStatus(): MemoryPalaceStatus;
145
+ private insertConnection;
146
+ /** Compute text overlap between two strings using bigram similarity (Dice coefficient). */
147
+ private textOverlap;
148
+ private bigrams;
149
+ private toConnection;
150
+ }
@@ -0,0 +1,479 @@
1
+ import { getLogger } from '../utils/logger.js';
2
+ // ── Migration ───────────────────────────────────────────
3
+ export function runMemoryPalaceMigration(db) {
4
+ db.exec(`
5
+ CREATE TABLE IF NOT EXISTS knowledge_connections (
6
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
7
+ source_type TEXT NOT NULL,
8
+ source_id TEXT NOT NULL,
9
+ target_type TEXT NOT NULL,
10
+ target_id TEXT NOT NULL,
11
+ relation TEXT NOT NULL DEFAULT 'related_to',
12
+ strength REAL NOT NULL DEFAULT 0.5,
13
+ auto_detected INTEGER NOT NULL DEFAULT 1,
14
+ created_at TEXT DEFAULT (datetime('now')),
15
+ UNIQUE(source_type, source_id, target_type, target_id, relation)
16
+ );
17
+ CREATE INDEX IF NOT EXISTS idx_kc_source ON knowledge_connections(source_type, source_id);
18
+ CREATE INDEX IF NOT EXISTS idx_kc_target ON knowledge_connections(target_type, target_id);
19
+ CREATE INDEX IF NOT EXISTS idx_kc_relation ON knowledge_connections(relation);
20
+ CREATE INDEX IF NOT EXISTS idx_kc_strength ON knowledge_connections(strength DESC);
21
+ `);
22
+ }
23
+ // ── Engine ──────────────────────────────────────────────
24
+ export class MemoryPalace {
25
+ db;
26
+ config;
27
+ log = getLogger();
28
+ ts = null;
29
+ sources = {};
30
+ startTime = Date.now();
31
+ // ── Prepared statements ──────────────────────────────
32
+ stmtInsertConnection;
33
+ stmtGetConnectionsFor;
34
+ stmtGetConnectionsFrom;
35
+ stmtGetConnectionsTo;
36
+ stmtCountEdges;
37
+ stmtDistinctNodes;
38
+ stmtAvgStrength;
39
+ stmtTopConnected;
40
+ stmtRecentConnections;
41
+ stmtNodesByType;
42
+ stmtAllEdges;
43
+ constructor(db, config) {
44
+ this.db = db;
45
+ this.config = {
46
+ brainName: config.brainName,
47
+ maxPathDepth: config.maxPathDepth ?? 6,
48
+ minAutoStrength: config.minAutoStrength ?? 0.3,
49
+ };
50
+ runMemoryPalaceMigration(db);
51
+ this.stmtInsertConnection = db.prepare(`
52
+ INSERT OR IGNORE INTO knowledge_connections (source_type, source_id, target_type, target_id, relation, strength, auto_detected)
53
+ VALUES (?, ?, ?, ?, ?, ?, ?)
54
+ `);
55
+ this.stmtGetConnectionsFor = db.prepare(`
56
+ SELECT * FROM knowledge_connections
57
+ WHERE (source_type = ? AND source_id = ?) OR (target_type = ? AND target_id = ?)
58
+ ORDER BY strength DESC
59
+ `);
60
+ this.stmtGetConnectionsFrom = db.prepare(`
61
+ SELECT * FROM knowledge_connections WHERE source_type = ? AND source_id = ? ORDER BY strength DESC
62
+ `);
63
+ this.stmtGetConnectionsTo = db.prepare(`
64
+ SELECT * FROM knowledge_connections WHERE target_type = ? AND target_id = ? ORDER BY strength DESC
65
+ `);
66
+ this.stmtCountEdges = db.prepare('SELECT COUNT(*) as count FROM knowledge_connections');
67
+ this.stmtDistinctNodes = db.prepare(`
68
+ SELECT COUNT(*) as count FROM (
69
+ SELECT source_type || ':' || source_id as node FROM knowledge_connections
70
+ UNION
71
+ SELECT target_type || ':' || target_id as node FROM knowledge_connections
72
+ )
73
+ `);
74
+ this.stmtAvgStrength = db.prepare('SELECT AVG(strength) as avg FROM knowledge_connections');
75
+ this.stmtTopConnected = db.prepare(`
76
+ SELECT node_type, node_id, COUNT(*) as connections FROM (
77
+ SELECT source_type as node_type, source_id as node_id FROM knowledge_connections
78
+ UNION ALL
79
+ SELECT target_type as node_type, target_id as node_id FROM knowledge_connections
80
+ ) GROUP BY node_type, node_id ORDER BY connections DESC LIMIT ?
81
+ `);
82
+ this.stmtRecentConnections = db.prepare('SELECT * FROM knowledge_connections ORDER BY created_at DESC LIMIT ?');
83
+ this.stmtNodesByType = db.prepare(`
84
+ SELECT node_type, COUNT(*) as count FROM (
85
+ SELECT source_type as node_type FROM knowledge_connections
86
+ UNION ALL
87
+ SELECT target_type as node_type FROM knowledge_connections
88
+ ) GROUP BY node_type
89
+ `);
90
+ this.stmtAllEdges = db.prepare('SELECT * FROM knowledge_connections ORDER BY strength DESC LIMIT ?');
91
+ }
92
+ setThoughtStream(stream) { this.ts = stream; }
93
+ setDataSources(sources) { this.sources = sources; }
94
+ // ── Build connections automatically ───────────────────
95
+ buildConnections() {
96
+ const scanned = [];
97
+ let newCount = 0;
98
+ // 1. Confirmed hypotheses → principles (text-overlap matching)
99
+ if (this.sources.getHypotheses && this.sources.getPrinciples) {
100
+ try {
101
+ const confirmed = this.sources.getHypotheses('confirmed', 200);
102
+ const principles = this.sources.getPrinciples(undefined, 200);
103
+ for (const h of confirmed) {
104
+ for (const p of principles) {
105
+ const overlap = this.textOverlap(h.statement, p.statement);
106
+ if (overlap >= this.config.minAutoStrength) {
107
+ const added = this.insertConnection('hypothesis', String(h.id), 'principle', String(p.id), 'derived_from', overlap, true);
108
+ if (added)
109
+ newCount++;
110
+ }
111
+ }
112
+ }
113
+ scanned.push('hypotheses→principles');
114
+ }
115
+ catch (err) {
116
+ this.log.warn(`[palace] hypotheses→principles scan error: ${err.message}`);
117
+ }
118
+ }
119
+ // 2. Rejected hypotheses → anti-patterns
120
+ if (this.sources.getHypotheses && this.sources.getAntiPatterns) {
121
+ try {
122
+ const rejected = this.sources.getHypotheses('rejected', 200);
123
+ const antiPatterns = this.sources.getAntiPatterns(undefined, 200);
124
+ for (const h of rejected) {
125
+ for (const ap of antiPatterns) {
126
+ const overlap = this.textOverlap(h.statement, ap.statement);
127
+ if (overlap >= this.config.minAutoStrength) {
128
+ const added = this.insertConnection('hypothesis', String(h.id), 'anti_pattern', String(ap.id), 'derived_from', overlap, true);
129
+ if (added)
130
+ newCount++;
131
+ }
132
+ }
133
+ }
134
+ scanned.push('rejected→anti_patterns');
135
+ }
136
+ catch (err) {
137
+ this.log.warn(`[palace] rejected→anti_patterns scan error: ${err.message}`);
138
+ }
139
+ }
140
+ // 3. Experiments → hypotheses (experiment.hypothesis match)
141
+ if (this.sources.getExperiments && this.sources.getHypotheses) {
142
+ try {
143
+ const experiments = this.sources.getExperiments(undefined, 200);
144
+ const allHypotheses = this.sources.getHypotheses(undefined, 500);
145
+ for (const exp of experiments) {
146
+ for (const h of allHypotheses) {
147
+ const overlap = this.textOverlap(exp.hypothesis || exp.name, h.statement);
148
+ if (overlap >= this.config.minAutoStrength) {
149
+ const added = this.insertConnection('experiment', String(exp.id), 'hypothesis', String(h.id), 'tested_by', overlap, true);
150
+ if (added)
151
+ newCount++;
152
+ }
153
+ }
154
+ }
155
+ scanned.push('experiments→hypotheses');
156
+ }
157
+ catch (err) {
158
+ this.log.warn(`[palace] experiments→hypotheses scan error: ${err.message}`);
159
+ }
160
+ }
161
+ // 4. Anomalies → experiments (text-overlap)
162
+ if (this.sources.getAnomalies && this.sources.getExperiments) {
163
+ try {
164
+ const anomalies = this.sources.getAnomalies(undefined, 200);
165
+ const experiments = this.sources.getExperiments(undefined, 200);
166
+ for (const a of anomalies) {
167
+ for (const exp of experiments) {
168
+ const overlap = this.textOverlap(a.title, exp.name);
169
+ if (overlap >= this.config.minAutoStrength) {
170
+ const added = this.insertConnection('anomaly', String(a.id), 'experiment', String(exp.id), 'caused_by', overlap, true);
171
+ if (added)
172
+ newCount++;
173
+ }
174
+ }
175
+ }
176
+ scanned.push('anomalies→experiments');
177
+ }
178
+ catch (err) {
179
+ this.log.warn(`[palace] anomalies→experiments scan error: ${err.message}`);
180
+ }
181
+ }
182
+ // 5. Journal entries → cross-references via tags/data
183
+ if (this.sources.getJournalEntries) {
184
+ try {
185
+ const entries = this.sources.getJournalEntries(500);
186
+ for (const entry of entries) {
187
+ // Parse tags for cross-references (supports string[] or JSON string)
188
+ let tags = [];
189
+ if (Array.isArray(entry.tags)) {
190
+ tags = entry.tags;
191
+ }
192
+ else {
193
+ try {
194
+ tags = JSON.parse(entry.tags || '[]');
195
+ }
196
+ catch { /* skip */ }
197
+ }
198
+ // Connect journal entries that share tags
199
+ for (const other of entries) {
200
+ if (entry.id === other.id)
201
+ continue;
202
+ let otherTags = [];
203
+ if (Array.isArray(other.tags)) {
204
+ otherTags = other.tags;
205
+ }
206
+ else {
207
+ try {
208
+ otherTags = JSON.parse(other.tags || '[]');
209
+ }
210
+ catch { /* skip */ }
211
+ }
212
+ const shared = tags.filter(t => otherTags.includes(t));
213
+ if (shared.length >= 2) {
214
+ const strength = Math.min(1, shared.length * 0.2);
215
+ const added = this.insertConnection('journal', String(entry.id), 'journal', String(other.id), 'references', strength, true);
216
+ if (added)
217
+ newCount++;
218
+ }
219
+ }
220
+ }
221
+ scanned.push('journal→cross-refs');
222
+ }
223
+ catch (err) {
224
+ this.log.warn(`[palace] journal cross-ref scan error: ${err.message}`);
225
+ }
226
+ }
227
+ // 6. Curiosity gaps → journal entries (topic overlap)
228
+ if (this.sources.getCuriosityGaps && this.sources.getJournalEntries) {
229
+ try {
230
+ const gaps = this.sources.getCuriosityGaps(100);
231
+ const entries = this.sources.getJournalEntries(200);
232
+ for (const gap of gaps) {
233
+ for (const entry of entries) {
234
+ const overlap = this.textOverlap(gap.topic, entry.title);
235
+ if (overlap >= this.config.minAutoStrength) {
236
+ const added = this.insertConnection('curiosity_gap', String(gap.id ?? 0), 'journal', String(entry.id), 'related_to', overlap, true);
237
+ if (added)
238
+ newCount++;
239
+ }
240
+ }
241
+ }
242
+ scanned.push('gaps→journal');
243
+ }
244
+ catch (err) {
245
+ this.log.warn(`[palace] gaps→journal scan error: ${err.message}`);
246
+ }
247
+ }
248
+ const totalEdges = this.stmtCountEdges.get().count;
249
+ this.ts?.emit('palace', 'discovering', `MemoryPalace built ${newCount} new connections (${totalEdges} total, scanned: ${scanned.join(', ')})`, newCount > 5 ? 'notable' : 'routine');
250
+ this.log.info(`[palace] buildConnections: +${newCount} new (${totalEdges} total), scanned: ${scanned.join(', ')}`);
251
+ return { newConnections: newCount, totalConnections: totalEdges, scannedSources: scanned };
252
+ }
253
+ // ── Manual connection ─────────────────────────────────
254
+ addConnection(sourceType, sourceId, targetType, targetId, relation, strength = 0.5) {
255
+ return this.insertConnection(sourceType, sourceId, targetType, targetId, relation, strength, false);
256
+ }
257
+ // ── Query connections ─────────────────────────────────
258
+ getConnections(type, id) {
259
+ const rows = this.stmtGetConnectionsFor.all(type, id, type, id);
260
+ return rows.map(r => this.toConnection(r));
261
+ }
262
+ // ── BFS shortest path ─────────────────────────────────
263
+ getPath(fromType, fromId, toType, toId, maxDepth) {
264
+ const depth = maxDepth ?? this.config.maxPathDepth;
265
+ const startKey = `${fromType}:${fromId}`;
266
+ const endKey = `${toType}:${toId}`;
267
+ if (startKey === endKey)
268
+ return [];
269
+ // BFS
270
+ const visited = new Set();
271
+ const queue = [{ key: startKey, path: [] }];
272
+ visited.add(startKey);
273
+ while (queue.length > 0) {
274
+ const current = queue.shift();
275
+ if (current.path.length >= depth)
276
+ continue;
277
+ // Get all neighbors
278
+ const [type, id] = current.key.split(':');
279
+ const fromRows = this.stmtGetConnectionsFrom.all(type, id);
280
+ const toRows = this.stmtGetConnectionsTo.all(type, id);
281
+ const neighbors = [];
282
+ for (const r of fromRows) {
283
+ neighbors.push({ key: `${r.target_type}:${r.target_id}`, relation: r.relation });
284
+ }
285
+ for (const r of toRows) {
286
+ neighbors.push({ key: `${r.source_type}:${r.source_id}`, relation: r.relation });
287
+ }
288
+ for (const neighbor of neighbors) {
289
+ if (visited.has(neighbor.key))
290
+ continue;
291
+ visited.add(neighbor.key);
292
+ const [nType, nId] = neighbor.key.split(':');
293
+ const newPath = [...current.path, { type: nType, id: nId, relation: neighbor.relation }];
294
+ if (neighbor.key === endKey)
295
+ return newPath;
296
+ queue.push({ key: neighbor.key, path: newPath });
297
+ }
298
+ }
299
+ return null; // No path found
300
+ }
301
+ // ── Knowledge map (subgraph) ──────────────────────────
302
+ getKnowledgeMap(topic, limit = 100) {
303
+ let edges;
304
+ if (topic) {
305
+ // Get connections where source or target relates to the topic
306
+ edges = this.db.prepare(`
307
+ SELECT * FROM knowledge_connections
308
+ WHERE source_type LIKE ? OR target_type LIKE ?
309
+ OR source_id IN (SELECT source_id FROM knowledge_connections WHERE source_type = 'journal')
310
+ ORDER BY strength DESC LIMIT ?
311
+ `).all(`%${topic}%`, `%${topic}%`, limit);
312
+ // If topic-based search didn't find much, search by checking all connection labels
313
+ if (edges.length === 0) {
314
+ edges = this.stmtAllEdges.all(limit);
315
+ }
316
+ }
317
+ else {
318
+ edges = this.stmtAllEdges.all(limit);
319
+ }
320
+ const nodeMap = new Map();
321
+ const mapEdges = [];
322
+ for (const e of edges) {
323
+ const sourceKey = `${e.source_type}:${e.source_id}`;
324
+ const targetKey = `${e.target_type}:${e.target_id}`;
325
+ if (!nodeMap.has(sourceKey)) {
326
+ nodeMap.set(sourceKey, { type: e.source_type, id: e.source_id, label: sourceKey, connections: 0 });
327
+ }
328
+ if (!nodeMap.has(targetKey)) {
329
+ nodeMap.set(targetKey, { type: e.target_type, id: e.target_id, label: targetKey, connections: 0 });
330
+ }
331
+ nodeMap.get(sourceKey).connections++;
332
+ nodeMap.get(targetKey).connections++;
333
+ mapEdges.push({
334
+ source: sourceKey,
335
+ target: targetKey,
336
+ relation: e.relation,
337
+ strength: e.strength,
338
+ });
339
+ }
340
+ return { nodes: Array.from(nodeMap.values()), edges: mapEdges };
341
+ }
342
+ // ── Isolated nodes ────────────────────────────────────
343
+ getIsolatedNodes() {
344
+ const connected = new Set();
345
+ const allEdges = this.stmtAllEdges.all(10000);
346
+ for (const e of allEdges) {
347
+ connected.add(`${e.source_type}:${e.source_id}`);
348
+ connected.add(`${e.target_type}:${e.target_id}`);
349
+ }
350
+ const isolated = [];
351
+ // Check each data source for items not in the connection graph
352
+ if (this.sources.getPrinciples) {
353
+ try {
354
+ const principles = this.sources.getPrinciples(undefined, 500);
355
+ for (const p of principles) {
356
+ if (!connected.has(`principle:${p.id}`)) {
357
+ isolated.push({ type: 'principle', id: String(p.id) });
358
+ }
359
+ }
360
+ }
361
+ catch { /* skip */ }
362
+ }
363
+ if (this.sources.getHypotheses) {
364
+ try {
365
+ const hypotheses = this.sources.getHypotheses(undefined, 500);
366
+ for (const h of hypotheses) {
367
+ if (!connected.has(`hypothesis:${h.id}`)) {
368
+ isolated.push({ type: 'hypothesis', id: String(h.id) });
369
+ }
370
+ }
371
+ }
372
+ catch { /* skip */ }
373
+ }
374
+ if (this.sources.getExperiments) {
375
+ try {
376
+ const experiments = this.sources.getExperiments(undefined, 500);
377
+ for (const exp of experiments) {
378
+ if (!connected.has(`experiment:${exp.id}`)) {
379
+ isolated.push({ type: 'experiment', id: String(exp.id) });
380
+ }
381
+ }
382
+ }
383
+ catch { /* skip */ }
384
+ }
385
+ if (this.sources.getAnomalies) {
386
+ try {
387
+ const anomalies = this.sources.getAnomalies(undefined, 500);
388
+ for (const a of anomalies) {
389
+ if (!connected.has(`anomaly:${a.id}`)) {
390
+ isolated.push({ type: 'anomaly', id: String(a.id) });
391
+ }
392
+ }
393
+ }
394
+ catch { /* skip */ }
395
+ }
396
+ return isolated;
397
+ }
398
+ // ── Stats ─────────────────────────────────────────────
399
+ getStats() {
400
+ const totalEdges = this.stmtCountEdges.get().count;
401
+ const totalNodes = this.stmtDistinctNodes.get().count;
402
+ const avgStrength = this.stmtAvgStrength.get().avg ?? 0;
403
+ const topRows = this.stmtTopConnected.all(10);
404
+ // Density = edges / (nodes * (nodes - 1) / 2) — for undirected graph
405
+ const maxEdges = totalNodes > 1 ? (totalNodes * (totalNodes - 1)) / 2 : 1;
406
+ const density = totalEdges / maxEdges;
407
+ const nodesByTypeRows = this.stmtNodesByType.all();
408
+ const nodesByType = {};
409
+ for (const row of nodesByTypeRows) {
410
+ nodesByType[row.node_type] = row.count;
411
+ }
412
+ return {
413
+ totalNodes,
414
+ totalEdges,
415
+ density: Math.min(1, density),
416
+ nodesByType,
417
+ topConnected: topRows.map(r => ({ type: r.node_type, id: r.node_id, connections: r.connections })),
418
+ avgStrength,
419
+ };
420
+ }
421
+ // ── Status ────────────────────────────────────────────
422
+ getStatus() {
423
+ const stats = this.getStats();
424
+ const recent = this.stmtRecentConnections.all(10);
425
+ return {
426
+ stats,
427
+ recentConnections: recent.map(r => this.toConnection(r)),
428
+ topConnectedNodes: stats.topConnected,
429
+ uptime: Date.now() - this.startTime,
430
+ };
431
+ }
432
+ // ── Private helpers ───────────────────────────────────
433
+ insertConnection(sourceType, sourceId, targetType, targetId, relation, strength, auto) {
434
+ try {
435
+ const result = this.stmtInsertConnection.run(sourceType, sourceId, targetType, targetId, relation, strength, auto ? 1 : 0);
436
+ return result.changes > 0;
437
+ }
438
+ catch {
439
+ return false; // UNIQUE constraint — already exists
440
+ }
441
+ }
442
+ /** Compute text overlap between two strings using bigram similarity (Dice coefficient). */
443
+ textOverlap(a, b) {
444
+ const aBigrams = this.bigrams(a.toLowerCase());
445
+ const bBigrams = this.bigrams(b.toLowerCase());
446
+ if (aBigrams.size === 0 || bBigrams.size === 0)
447
+ return 0;
448
+ let intersection = 0;
449
+ for (const bg of aBigrams) {
450
+ if (bBigrams.has(bg))
451
+ intersection++;
452
+ }
453
+ return (2 * intersection) / (aBigrams.size + bBigrams.size);
454
+ }
455
+ bigrams(text) {
456
+ const words = text.split(/\s+/).filter(w => w.length > 2);
457
+ const result = new Set();
458
+ for (const word of words) {
459
+ for (let i = 0; i < word.length - 1; i++) {
460
+ result.add(word.substring(i, i + 2));
461
+ }
462
+ }
463
+ return result;
464
+ }
465
+ toConnection(row) {
466
+ return {
467
+ id: row.id,
468
+ sourceType: row.source_type,
469
+ sourceId: row.source_id,
470
+ targetType: row.target_type,
471
+ targetId: row.target_id,
472
+ relation: row.relation,
473
+ strength: row.strength,
474
+ autoDetected: row.auto_detected === 1,
475
+ createdAt: row.created_at,
476
+ };
477
+ }
478
+ }
479
+ //# sourceMappingURL=memory-palace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-palace.js","sourceRoot":"","sources":["../../src/memory-palace/memory-palace.ts"],"names":[],"mappings":"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"}