stellar-memory 0.5.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.
- package/LICENSE +21 -0
- package/README.md +362 -0
- package/dist/api/routes/analytics.d.ts +15 -0
- package/dist/api/routes/analytics.js +131 -0
- package/dist/api/routes/analytics.js.map +1 -0
- package/dist/api/routes/conflicts.d.ts +12 -0
- package/dist/api/routes/conflicts.js +67 -0
- package/dist/api/routes/conflicts.js.map +1 -0
- package/dist/api/routes/consolidation.d.ts +11 -0
- package/dist/api/routes/consolidation.js +63 -0
- package/dist/api/routes/consolidation.js.map +1 -0
- package/dist/api/routes/constellation.d.ts +4 -0
- package/dist/api/routes/constellation.js +84 -0
- package/dist/api/routes/constellation.js.map +1 -0
- package/dist/api/routes/memories.d.ts +4 -0
- package/dist/api/routes/memories.js +219 -0
- package/dist/api/routes/memories.js.map +1 -0
- package/dist/api/routes/observations.d.ts +10 -0
- package/dist/api/routes/observations.js +42 -0
- package/dist/api/routes/observations.js.map +1 -0
- package/dist/api/routes/orbit.d.ts +4 -0
- package/dist/api/routes/orbit.js +71 -0
- package/dist/api/routes/orbit.js.map +1 -0
- package/dist/api/routes/projects.d.ts +15 -0
- package/dist/api/routes/projects.js +121 -0
- package/dist/api/routes/projects.js.map +1 -0
- package/dist/api/routes/scan.d.ts +4 -0
- package/dist/api/routes/scan.js +403 -0
- package/dist/api/routes/scan.js.map +1 -0
- package/dist/api/routes/sun.d.ts +4 -0
- package/dist/api/routes/sun.js +43 -0
- package/dist/api/routes/sun.js.map +1 -0
- package/dist/api/routes/system.d.ts +4 -0
- package/dist/api/routes/system.js +70 -0
- package/dist/api/routes/system.js.map +1 -0
- package/dist/api/routes/temporal.d.ts +13 -0
- package/dist/api/routes/temporal.js +82 -0
- package/dist/api/routes/temporal.js.map +1 -0
- package/dist/api/server.d.ts +2 -0
- package/dist/api/server.js +99 -0
- package/dist/api/server.js.map +1 -0
- package/dist/api/websocket.d.ts +53 -0
- package/dist/api/websocket.js +168 -0
- package/dist/api/websocket.js.map +1 -0
- package/dist/cli/index.d.ts +12 -0
- package/dist/cli/index.js +35 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.d.ts +10 -0
- package/dist/cli/init.js +163 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/engine/analytics.d.ts +93 -0
- package/dist/engine/analytics.js +437 -0
- package/dist/engine/analytics.js.map +1 -0
- package/dist/engine/conflict.d.ts +54 -0
- package/dist/engine/conflict.js +322 -0
- package/dist/engine/conflict.js.map +1 -0
- package/dist/engine/consolidation.d.ts +83 -0
- package/dist/engine/consolidation.js +368 -0
- package/dist/engine/consolidation.js.map +1 -0
- package/dist/engine/constellation.d.ts +66 -0
- package/dist/engine/constellation.js +382 -0
- package/dist/engine/constellation.js.map +1 -0
- package/dist/engine/corona.d.ts +53 -0
- package/dist/engine/corona.js +181 -0
- package/dist/engine/corona.js.map +1 -0
- package/dist/engine/embedding.d.ts +44 -0
- package/dist/engine/embedding.js +168 -0
- package/dist/engine/embedding.js.map +1 -0
- package/dist/engine/gravity.d.ts +63 -0
- package/dist/engine/gravity.js +121 -0
- package/dist/engine/gravity.js.map +1 -0
- package/dist/engine/multiproject.d.ts +75 -0
- package/dist/engine/multiproject.js +241 -0
- package/dist/engine/multiproject.js.map +1 -0
- package/dist/engine/observation.d.ts +82 -0
- package/dist/engine/observation.js +357 -0
- package/dist/engine/observation.js.map +1 -0
- package/dist/engine/orbit.d.ts +91 -0
- package/dist/engine/orbit.js +249 -0
- package/dist/engine/orbit.js.map +1 -0
- package/dist/engine/planet.d.ts +64 -0
- package/dist/engine/planet.js +432 -0
- package/dist/engine/planet.js.map +1 -0
- package/dist/engine/procedural.d.ts +71 -0
- package/dist/engine/procedural.js +259 -0
- package/dist/engine/procedural.js.map +1 -0
- package/dist/engine/quality.d.ts +48 -0
- package/dist/engine/quality.js +245 -0
- package/dist/engine/quality.js.map +1 -0
- package/dist/engine/repository.d.ts +79 -0
- package/dist/engine/repository.js +13 -0
- package/dist/engine/repository.js.map +1 -0
- package/dist/engine/sun.d.ts +61 -0
- package/dist/engine/sun.js +240 -0
- package/dist/engine/sun.js.map +1 -0
- package/dist/engine/temporal.d.ts +67 -0
- package/dist/engine/temporal.js +283 -0
- package/dist/engine/temporal.js.map +1 -0
- package/dist/engine/types.d.ts +179 -0
- package/dist/engine/types.js +27 -0
- package/dist/engine/types.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +60 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/connector-registry.d.ts +20 -0
- package/dist/mcp/connector-registry.js +35 -0
- package/dist/mcp/connector-registry.js.map +1 -0
- package/dist/mcp/server.d.ts +13 -0
- package/dist/mcp/server.js +242 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools/daemon-tool.d.ts +16 -0
- package/dist/mcp/tools/daemon-tool.js +58 -0
- package/dist/mcp/tools/daemon-tool.js.map +1 -0
- package/dist/mcp/tools/ingestion-tools.d.ts +20 -0
- package/dist/mcp/tools/ingestion-tools.js +34 -0
- package/dist/mcp/tools/ingestion-tools.js.map +1 -0
- package/dist/mcp/tools/memory-tools.d.ts +122 -0
- package/dist/mcp/tools/memory-tools.js +1037 -0
- package/dist/mcp/tools/memory-tools.js.map +1 -0
- package/dist/scanner/cloud/github.d.ts +34 -0
- package/dist/scanner/cloud/github.js +260 -0
- package/dist/scanner/cloud/github.js.map +1 -0
- package/dist/scanner/cloud/google-drive.d.ts +30 -0
- package/dist/scanner/cloud/google-drive.js +289 -0
- package/dist/scanner/cloud/google-drive.js.map +1 -0
- package/dist/scanner/cloud/notion.d.ts +33 -0
- package/dist/scanner/cloud/notion.js +231 -0
- package/dist/scanner/cloud/notion.js.map +1 -0
- package/dist/scanner/cloud/slack.d.ts +38 -0
- package/dist/scanner/cloud/slack.js +282 -0
- package/dist/scanner/cloud/slack.js.map +1 -0
- package/dist/scanner/cloud/types.d.ts +73 -0
- package/dist/scanner/cloud/types.js +9 -0
- package/dist/scanner/cloud/types.js.map +1 -0
- package/dist/scanner/index.d.ts +35 -0
- package/dist/scanner/index.js +420 -0
- package/dist/scanner/index.js.map +1 -0
- package/dist/scanner/local/filesystem.d.ts +33 -0
- package/dist/scanner/local/filesystem.js +203 -0
- package/dist/scanner/local/filesystem.js.map +1 -0
- package/dist/scanner/local/git.d.ts +24 -0
- package/dist/scanner/local/git.js +161 -0
- package/dist/scanner/local/git.js.map +1 -0
- package/dist/scanner/local/parsers/code.d.ts +3 -0
- package/dist/scanner/local/parsers/code.js +127 -0
- package/dist/scanner/local/parsers/code.js.map +1 -0
- package/dist/scanner/local/parsers/index.d.ts +11 -0
- package/dist/scanner/local/parsers/index.js +24 -0
- package/dist/scanner/local/parsers/index.js.map +1 -0
- package/dist/scanner/local/parsers/json-parser.d.ts +3 -0
- package/dist/scanner/local/parsers/json-parser.js +117 -0
- package/dist/scanner/local/parsers/json-parser.js.map +1 -0
- package/dist/scanner/local/parsers/markdown.d.ts +3 -0
- package/dist/scanner/local/parsers/markdown.js +120 -0
- package/dist/scanner/local/parsers/markdown.js.map +1 -0
- package/dist/scanner/local/parsers/text.d.ts +3 -0
- package/dist/scanner/local/parsers/text.js +41 -0
- package/dist/scanner/local/parsers/text.js.map +1 -0
- package/dist/scanner/metadata-scanner.d.ts +67 -0
- package/dist/scanner/metadata-scanner.js +356 -0
- package/dist/scanner/metadata-scanner.js.map +1 -0
- package/dist/scanner/types.d.ts +47 -0
- package/dist/scanner/types.js +19 -0
- package/dist/scanner/types.js.map +1 -0
- package/dist/service/daemon.d.ts +23 -0
- package/dist/service/daemon.js +105 -0
- package/dist/service/daemon.js.map +1 -0
- package/dist/service/scheduler.d.ts +73 -0
- package/dist/service/scheduler.js +281 -0
- package/dist/service/scheduler.js.map +1 -0
- package/dist/storage/database.d.ts +10 -0
- package/dist/storage/database.js +265 -0
- package/dist/storage/database.js.map +1 -0
- package/dist/storage/queries.d.ts +85 -0
- package/dist/storage/queries.js +865 -0
- package/dist/storage/queries.js.map +1 -0
- package/dist/storage/sqlite-repository.d.ts +32 -0
- package/dist/storage/sqlite-repository.js +68 -0
- package/dist/storage/sqlite-repository.js.map +1 -0
- package/dist/storage/vec.d.ts +62 -0
- package/dist/storage/vec.js +111 -0
- package/dist/storage/vec.js.map +1 -0
- package/dist/utils/config.d.ts +5 -0
- package/dist/utils/config.js +60 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/logger.d.ts +36 -0
- package/dist/utils/logger.js +86 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/time.d.ts +21 -0
- package/dist/utils/time.js +42 -0
- package/dist/utils/time.js.map +1 -0
- package/dist/utils/tokenizer.d.ts +13 -0
- package/dist/utils/tokenizer.js +46 -0
- package/dist/utils/tokenizer.js.map +1 -0
- package/package.json +77 -0
- package/scripts/check-node.mjs +36 -0
- package/scripts/setup.mjs +157 -0
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* consolidation.ts — Memory Consolidation ("Orbital Resonance")
|
|
3
|
+
*
|
|
4
|
+
* Finds groups of similar memories and merges them into richer, more
|
|
5
|
+
* comprehensive memories. Similar to how planets form from smaller bodies
|
|
6
|
+
* (planetesimals) combining in orbital resonance.
|
|
7
|
+
*
|
|
8
|
+
* Algorithm:
|
|
9
|
+
* 1. Load all memories in a project.
|
|
10
|
+
* 2. Group memories that share the same type and are within ±3 AU of each
|
|
11
|
+
* other, with cosine similarity > 0.80 between their embeddings.
|
|
12
|
+
* Falls back to Jaccard-based text similarity when embeddings are absent.
|
|
13
|
+
* 3. For each qualifying group (2+ memories):
|
|
14
|
+
* - Merge content by deduplicating sentences.
|
|
15
|
+
* - Create a new consolidated memory.
|
|
16
|
+
* - Mark sources as consolidated and push them to the Oort cloud.
|
|
17
|
+
*/
|
|
18
|
+
import { getMemoriesByProject, consolidateMemories, getConsolidationHistory, updateMemoryOrbit, insertOrbitLog, } from '../storage/queries.js';
|
|
19
|
+
import { createMemory } from './planet.js';
|
|
20
|
+
import { generateEmbedding } from './embedding.js';
|
|
21
|
+
import { cosineSimilarity } from './gravity.js';
|
|
22
|
+
import { getDatabase } from '../storage/database.js';
|
|
23
|
+
import { createLogger } from '../utils/logger.js';
|
|
24
|
+
const log = createLogger('consolidation');
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// Constants
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
const SIMILARITY_THRESHOLD = 0.80; // cosine similarity cutoff for grouping
|
|
29
|
+
const DISTANCE_TOLERANCE = 3.0; // AU — memories must be within ±3 AU
|
|
30
|
+
const OORT_DISTANCE = 95.0; // source memories are pushed here post-merge
|
|
31
|
+
const JACCARD_DEDUP_THRESHOLD = 0.70; // sentence deduplication cutoff
|
|
32
|
+
// Type priority for choosing the merged memory's type (higher = more important)
|
|
33
|
+
const TYPE_PRIORITY = {
|
|
34
|
+
decision: 6,
|
|
35
|
+
milestone: 5,
|
|
36
|
+
error: 4,
|
|
37
|
+
task: 3,
|
|
38
|
+
context: 2,
|
|
39
|
+
observation: 1,
|
|
40
|
+
procedural: 3,
|
|
41
|
+
};
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
// Sentence deduplication helpers
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
/**
|
|
46
|
+
* Tokenize a sentence into a Set of lowercase word tokens.
|
|
47
|
+
* Used for Jaccard similarity comparison.
|
|
48
|
+
*/
|
|
49
|
+
function tokenizeToSet(sentence) {
|
|
50
|
+
const tokens = sentence
|
|
51
|
+
.toLowerCase()
|
|
52
|
+
.split(/\s+/)
|
|
53
|
+
.map(w => w.replace(/[^\w]/g, ''))
|
|
54
|
+
.filter(w => w.length >= 2);
|
|
55
|
+
return new Set(tokens);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Jaccard similarity between two token sets.
|
|
59
|
+
* Returns a value in [0, 1].
|
|
60
|
+
*/
|
|
61
|
+
function jaccardSimilarity(a, b) {
|
|
62
|
+
if (a.size === 0 && b.size === 0)
|
|
63
|
+
return 1;
|
|
64
|
+
let intersection = 0;
|
|
65
|
+
for (const token of a) {
|
|
66
|
+
if (b.has(token))
|
|
67
|
+
intersection++;
|
|
68
|
+
}
|
|
69
|
+
const union = a.size + b.size - intersection;
|
|
70
|
+
return union === 0 ? 0 : intersection / union;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Deduplicate an array of sentences using Jaccard similarity.
|
|
74
|
+
*
|
|
75
|
+
* For each new sentence, if it is too similar to one already kept (above
|
|
76
|
+
* JACCARD_DEDUP_THRESHOLD), keep the longer/more detailed version and discard
|
|
77
|
+
* the other.
|
|
78
|
+
*
|
|
79
|
+
* Returns the deduplicated array of sentences in original order.
|
|
80
|
+
*/
|
|
81
|
+
export function deduplicateSentences(sentences) {
|
|
82
|
+
const kept = [];
|
|
83
|
+
for (const sentence of sentences) {
|
|
84
|
+
const sentenceTokens = tokenizeToSet(sentence);
|
|
85
|
+
let dominated = false;
|
|
86
|
+
for (let i = 0; i < kept.length; i++) {
|
|
87
|
+
const sim = jaccardSimilarity(sentenceTokens, kept[i].tokens);
|
|
88
|
+
if (sim >= JACCARD_DEDUP_THRESHOLD) {
|
|
89
|
+
// Keep the longer, more detailed version
|
|
90
|
+
if (sentence.length > kept[i].text.length) {
|
|
91
|
+
kept[i] = { text: sentence, tokens: sentenceTokens };
|
|
92
|
+
}
|
|
93
|
+
dominated = true;
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (!dominated) {
|
|
98
|
+
kept.push({ text: sentence, tokens: sentenceTokens });
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return kept.map(k => k.text);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Split text into individual sentences.
|
|
105
|
+
* Handles common sentence-ending punctuation and newlines.
|
|
106
|
+
*/
|
|
107
|
+
function splitIntoSentences(text) {
|
|
108
|
+
return text
|
|
109
|
+
.split(/(?<=[.!?])\s+|\n+/)
|
|
110
|
+
.map(s => s.trim())
|
|
111
|
+
.filter(s => s.length > 0);
|
|
112
|
+
}
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
// Similarity helpers
|
|
115
|
+
// ---------------------------------------------------------------------------
|
|
116
|
+
/**
|
|
117
|
+
* Look up the stored embedding for a memory from the vec table.
|
|
118
|
+
* Returns null if no embedding is stored.
|
|
119
|
+
*/
|
|
120
|
+
function getStoredEmbedding(memoryId) {
|
|
121
|
+
try {
|
|
122
|
+
const db = getDatabase();
|
|
123
|
+
const row = db.prepare(`SELECT me.embedding
|
|
124
|
+
FROM memory_embeddings me
|
|
125
|
+
JOIN memory_embedding_map mm ON mm.vec_rowid = me.rowid
|
|
126
|
+
WHERE mm.memory_id = ?`).get(memoryId);
|
|
127
|
+
if (!row?.embedding)
|
|
128
|
+
return null;
|
|
129
|
+
return new Float32Array(row.embedding.buffer, row.embedding.byteOffset, row.embedding.byteLength / 4);
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Text-based similarity between two memories using Jaccard on tokenized content.
|
|
137
|
+
* Used as a fallback when embeddings are unavailable.
|
|
138
|
+
*/
|
|
139
|
+
function textSimilarity(a, b) {
|
|
140
|
+
const tokensA = tokenizeToSet(a.content + ' ' + a.summary);
|
|
141
|
+
const tokensB = tokenizeToSet(b.content + ' ' + b.summary);
|
|
142
|
+
return jaccardSimilarity(tokensA, tokensB);
|
|
143
|
+
}
|
|
144
|
+
// ---------------------------------------------------------------------------
|
|
145
|
+
// Candidate finding
|
|
146
|
+
// ---------------------------------------------------------------------------
|
|
147
|
+
/**
|
|
148
|
+
* Find groups of memories that are candidates for consolidation.
|
|
149
|
+
*
|
|
150
|
+
* Criteria for grouping:
|
|
151
|
+
* - Same type
|
|
152
|
+
* - Within ±3 AU of each other (distance)
|
|
153
|
+
* - Cosine similarity > 0.80 (falls back to Jaccard if no embeddings)
|
|
154
|
+
*
|
|
155
|
+
* Returns groups sorted by average similarity (highest first).
|
|
156
|
+
* Each group contains 2+ memories.
|
|
157
|
+
*/
|
|
158
|
+
export async function findConsolidationCandidates(project) {
|
|
159
|
+
const all = getMemoriesByProject(project).filter(m => !m.consolidated_into && !m.deleted_at);
|
|
160
|
+
if (all.length < 2)
|
|
161
|
+
return [];
|
|
162
|
+
// Pre-fetch all available embeddings in one pass to avoid repeated DB hits
|
|
163
|
+
const embeddingCache = new Map();
|
|
164
|
+
for (const m of all) {
|
|
165
|
+
embeddingCache.set(m.id, getStoredEmbedding(m.id));
|
|
166
|
+
}
|
|
167
|
+
// Build groups using a union-find-like approach:
|
|
168
|
+
// Any two memories that pass ALL criteria are put in the same group.
|
|
169
|
+
const groups = [];
|
|
170
|
+
const grouped = new Set();
|
|
171
|
+
for (let i = 0; i < all.length; i++) {
|
|
172
|
+
const a = all[i];
|
|
173
|
+
if (grouped.has(a.id))
|
|
174
|
+
continue;
|
|
175
|
+
const group = [a];
|
|
176
|
+
const similarities = [];
|
|
177
|
+
for (let j = i + 1; j < all.length; j++) {
|
|
178
|
+
const b = all[j];
|
|
179
|
+
if (grouped.has(b.id))
|
|
180
|
+
continue;
|
|
181
|
+
// Must share the same memory type
|
|
182
|
+
if (a.type !== b.type)
|
|
183
|
+
continue;
|
|
184
|
+
// Must be within ±3 AU of each other
|
|
185
|
+
if (Math.abs(a.distance - b.distance) > DISTANCE_TOLERANCE)
|
|
186
|
+
continue;
|
|
187
|
+
// Similarity check — prefer embeddings, fall back to text
|
|
188
|
+
let similarity;
|
|
189
|
+
const embA = embeddingCache.get(a.id) ?? null;
|
|
190
|
+
const embB = embeddingCache.get(b.id) ?? null;
|
|
191
|
+
if (embA && embB) {
|
|
192
|
+
similarity = cosineSimilarity(embA, embB);
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
similarity = textSimilarity(a, b);
|
|
196
|
+
}
|
|
197
|
+
if (similarity < SIMILARITY_THRESHOLD)
|
|
198
|
+
continue;
|
|
199
|
+
group.push(b);
|
|
200
|
+
similarities.push(similarity);
|
|
201
|
+
}
|
|
202
|
+
if (group.length >= 2) {
|
|
203
|
+
for (const m of group)
|
|
204
|
+
grouped.add(m.id);
|
|
205
|
+
groups.push({ memories: group, similarities });
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// Compute average similarity per group and sort descending
|
|
209
|
+
return groups
|
|
210
|
+
.map(g => ({
|
|
211
|
+
memories: g.memories,
|
|
212
|
+
similarity: g.similarities.length > 0
|
|
213
|
+
? g.similarities.reduce((s, v) => s + v, 0) / g.similarities.length
|
|
214
|
+
: SIMILARITY_THRESHOLD,
|
|
215
|
+
}))
|
|
216
|
+
.sort((a, b) => b.similarity - a.similarity);
|
|
217
|
+
}
|
|
218
|
+
// ---------------------------------------------------------------------------
|
|
219
|
+
// Consolidation
|
|
220
|
+
// ---------------------------------------------------------------------------
|
|
221
|
+
/**
|
|
222
|
+
* Consolidate a group of memories into a single new memory.
|
|
223
|
+
*
|
|
224
|
+
* Merge strategy:
|
|
225
|
+
* - Content: Combine unique sentences from all sources (Jaccard dedup).
|
|
226
|
+
* - Summary: Join all source summaries, deduplicated and truncated.
|
|
227
|
+
* - Tags: Union of all tags.
|
|
228
|
+
* - Type: Most important type by TYPE_PRIORITY ranking.
|
|
229
|
+
* - Impact: Max of all sources.
|
|
230
|
+
* - Distance: Min of all sources (closest orbit).
|
|
231
|
+
*
|
|
232
|
+
* After creating the new memory:
|
|
233
|
+
* - Source memories are marked as consolidated (consolidated_into set).
|
|
234
|
+
* - Source memories are pushed to the Oort cloud (distance = 95).
|
|
235
|
+
*
|
|
236
|
+
* Returns the newly created consolidated memory.
|
|
237
|
+
*/
|
|
238
|
+
export function consolidateGroup(memories, project) {
|
|
239
|
+
if (memories.length < 2) {
|
|
240
|
+
throw new Error('consolidateGroup requires at least 2 memories');
|
|
241
|
+
}
|
|
242
|
+
// Merge content: collect all sentences, deduplicate, combine
|
|
243
|
+
const allSentences = [];
|
|
244
|
+
for (const m of memories) {
|
|
245
|
+
allSentences.push(...splitIntoSentences(m.content));
|
|
246
|
+
}
|
|
247
|
+
const uniqueSentences = deduplicateSentences(allSentences);
|
|
248
|
+
const mergedContent = `Consolidated from ${memories.length} memories:\n` +
|
|
249
|
+
uniqueSentences.join(' ');
|
|
250
|
+
// Merge summary: collect unique summaries
|
|
251
|
+
const summaryParts = deduplicateSentences(memories.map(m => m.summary));
|
|
252
|
+
const mergedSummary = summaryParts.join('; ').slice(0, 120);
|
|
253
|
+
// Merge tags: union, deduplicated
|
|
254
|
+
const tagSet = new Set();
|
|
255
|
+
for (const m of memories) {
|
|
256
|
+
for (const t of m.tags)
|
|
257
|
+
tagSet.add(t);
|
|
258
|
+
}
|
|
259
|
+
const mergedTags = [...tagSet];
|
|
260
|
+
// Choose type by priority
|
|
261
|
+
const mergedType = memories.reduce((best, m) => (TYPE_PRIORITY[m.type] ?? 0) > (TYPE_PRIORITY[best.type] ?? 0) ? m : best).type;
|
|
262
|
+
// Max impact
|
|
263
|
+
const mergedImpact = Math.max(...memories.map(m => m.impact));
|
|
264
|
+
// Create the new consolidated memory
|
|
265
|
+
const consolidated = createMemory({
|
|
266
|
+
project,
|
|
267
|
+
content: mergedContent,
|
|
268
|
+
summary: mergedSummary,
|
|
269
|
+
type: mergedType,
|
|
270
|
+
impact: mergedImpact,
|
|
271
|
+
tags: mergedTags,
|
|
272
|
+
});
|
|
273
|
+
// Mark all source memories as consolidated and push to Oort cloud
|
|
274
|
+
const sourceIds = memories.map(m => m.id);
|
|
275
|
+
consolidateMemories(sourceIds, consolidated.id);
|
|
276
|
+
for (const m of memories) {
|
|
277
|
+
updateMemoryOrbit(m.id, OORT_DISTANCE, 0.02, OORT_DISTANCE - m.distance);
|
|
278
|
+
insertOrbitLog({
|
|
279
|
+
memory_id: m.id,
|
|
280
|
+
project,
|
|
281
|
+
old_distance: m.distance,
|
|
282
|
+
new_distance: OORT_DISTANCE,
|
|
283
|
+
old_importance: m.importance,
|
|
284
|
+
new_importance: 0.02,
|
|
285
|
+
trigger: 'manual',
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
log.info('Consolidated group', {
|
|
289
|
+
sourceCount: memories.length,
|
|
290
|
+
consolidatedId: consolidated.id,
|
|
291
|
+
type: mergedType,
|
|
292
|
+
});
|
|
293
|
+
return consolidated;
|
|
294
|
+
}
|
|
295
|
+
// ---------------------------------------------------------------------------
|
|
296
|
+
// Full consolidation pass
|
|
297
|
+
// ---------------------------------------------------------------------------
|
|
298
|
+
/**
|
|
299
|
+
* Run a full consolidation pass for a project.
|
|
300
|
+
*
|
|
301
|
+
* Finds all candidate groups, consolidates each one, and returns statistics.
|
|
302
|
+
*/
|
|
303
|
+
export async function runConsolidation(project) {
|
|
304
|
+
log.info('Starting consolidation pass', { project });
|
|
305
|
+
const candidates = await findConsolidationCandidates(project);
|
|
306
|
+
let memoriesConsolidated = 0;
|
|
307
|
+
let newMemoriesCreated = 0;
|
|
308
|
+
for (const { memories, similarity } of candidates) {
|
|
309
|
+
try {
|
|
310
|
+
log.debug('Consolidating group', {
|
|
311
|
+
size: memories.length,
|
|
312
|
+
similarity: similarity.toFixed(3),
|
|
313
|
+
ids: memories.map(m => m.id),
|
|
314
|
+
});
|
|
315
|
+
consolidateGroup(memories, project);
|
|
316
|
+
memoriesConsolidated += memories.length;
|
|
317
|
+
newMemoriesCreated += 1;
|
|
318
|
+
}
|
|
319
|
+
catch (err) {
|
|
320
|
+
log.warn('Failed to consolidate group', {
|
|
321
|
+
ids: memories.map(m => m.id),
|
|
322
|
+
error: String(err),
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
log.info('Consolidation pass complete', {
|
|
327
|
+
project,
|
|
328
|
+
groupsFound: candidates.length,
|
|
329
|
+
memoriesConsolidated,
|
|
330
|
+
newMemoriesCreated,
|
|
331
|
+
});
|
|
332
|
+
return {
|
|
333
|
+
groupsFound: candidates.length,
|
|
334
|
+
memoriesConsolidated,
|
|
335
|
+
newMemoriesCreated,
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
// ---------------------------------------------------------------------------
|
|
339
|
+
// Consolidation history
|
|
340
|
+
// ---------------------------------------------------------------------------
|
|
341
|
+
/**
|
|
342
|
+
* Return the source memories that were merged into the given memory ID.
|
|
343
|
+
* Returns an empty array if this memory was not created by consolidation.
|
|
344
|
+
*/
|
|
345
|
+
export function getConsolidationSources(memoryId) {
|
|
346
|
+
return getConsolidationHistory(memoryId);
|
|
347
|
+
}
|
|
348
|
+
// ---------------------------------------------------------------------------
|
|
349
|
+
// Async embedding-based similarity (used for higher precision when needed)
|
|
350
|
+
// ---------------------------------------------------------------------------
|
|
351
|
+
/**
|
|
352
|
+
* Generate and compare embeddings for two text strings.
|
|
353
|
+
* Returns cosine similarity in [0, 1].
|
|
354
|
+
* Used internally when stored embeddings are unavailable.
|
|
355
|
+
*/
|
|
356
|
+
export async function computeEmbeddingSimilarity(textA, textB) {
|
|
357
|
+
try {
|
|
358
|
+
const [embA, embB] = await Promise.all([
|
|
359
|
+
generateEmbedding(textA),
|
|
360
|
+
generateEmbedding(textB),
|
|
361
|
+
]);
|
|
362
|
+
return cosineSimilarity(embA, embB);
|
|
363
|
+
}
|
|
364
|
+
catch {
|
|
365
|
+
return 0;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
//# sourceMappingURL=consolidation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consolidation.js","sourceRoot":"","sources":["../../src/engine/consolidation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* constellation.ts — Knowledge Graph engine module
|
|
3
|
+
*
|
|
4
|
+
* Memories form a "constellation" — a graph where edges represent semantic
|
|
5
|
+
* and structural relationships between memory planets.
|
|
6
|
+
*
|
|
7
|
+
* Relationships are inferred using fast, local keyword heuristics:
|
|
8
|
+
* - Type-based rules (error → decision = caused_by, etc.)
|
|
9
|
+
* - Contradiction detection (negation/replacement keywords near shared terms)
|
|
10
|
+
* - Content reference detection (one memory's text mentions another's keywords)
|
|
11
|
+
* - Shared tag overlap (same domain/topic)
|
|
12
|
+
* - Default fallback: related_to
|
|
13
|
+
*
|
|
14
|
+
* All functions are synchronous except extractRelationships, which is async
|
|
15
|
+
* because it may use vector similarity as the primary similarity signal.
|
|
16
|
+
*/
|
|
17
|
+
import type { Memory, ConstellationEdge, RelationType } from './types.js';
|
|
18
|
+
/**
|
|
19
|
+
* Auto-extract relationships for a newly stored memory.
|
|
20
|
+
*
|
|
21
|
+
* Algorithm:
|
|
22
|
+
* 1. Find the top-K most similar existing memories using vector KNN if
|
|
23
|
+
* available, falling back to FTS5 keyword search.
|
|
24
|
+
* 2. For each candidate, compute a weight (cosine similarity or keyword
|
|
25
|
+
* overlap ratio).
|
|
26
|
+
* 3. Filter candidates below WEIGHT_THRESHOLD.
|
|
27
|
+
* 4. Infer the relationship type using keyword heuristics.
|
|
28
|
+
* 5. Persist edges via queries.createEdge().
|
|
29
|
+
*
|
|
30
|
+
* Returns the list of edges that were created.
|
|
31
|
+
*/
|
|
32
|
+
export declare function extractRelationships(newMemory: Memory, project: string): Promise<ConstellationEdge[]>;
|
|
33
|
+
/**
|
|
34
|
+
* Return the full constellation graph (nodes + edges) centred on a memory.
|
|
35
|
+
*
|
|
36
|
+
* Uses queries.getConstellation() which handles multi-depth BFS traversal
|
|
37
|
+
* and deduplication internally. Depth defaults to 1 (immediate neighbours).
|
|
38
|
+
*/
|
|
39
|
+
export declare function getConstellationGraph(memoryId: string, project: string, depth?: number): {
|
|
40
|
+
nodes: Memory[];
|
|
41
|
+
edges: ConstellationEdge[];
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Return the top N memories most strongly connected to the given memory,
|
|
45
|
+
* sorted by edge weight (descending).
|
|
46
|
+
*
|
|
47
|
+
* Useful for augmenting recall results with graph-traversal neighbours.
|
|
48
|
+
*/
|
|
49
|
+
export declare function findRelatedMemories(memoryId: string, project: string, limit?: number): Memory[];
|
|
50
|
+
/**
|
|
51
|
+
* Suggest potential relationships for an existing memory without persisting them.
|
|
52
|
+
* Useful for a "review" UI where a user can approve/reject suggestions.
|
|
53
|
+
*
|
|
54
|
+
* Returns candidates sorted by confidence (descending).
|
|
55
|
+
*/
|
|
56
|
+
export declare function suggestRelationships(memoryId: string, project: string): Array<{
|
|
57
|
+
target: Memory;
|
|
58
|
+
suggestedRelation: RelationType;
|
|
59
|
+
confidence: number;
|
|
60
|
+
}>;
|
|
61
|
+
/**
|
|
62
|
+
* Remove all constellation edges that reference the given memory ID.
|
|
63
|
+
* Should be called when a memory is deleted to prevent orphan edges.
|
|
64
|
+
*/
|
|
65
|
+
export declare function cleanupEdges(memoryId: string): void;
|
|
66
|
+
//# sourceMappingURL=constellation.d.ts.map
|