@danielsimonjr/memory-mcp 9.9.0 → 10.0.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.
Files changed (70) hide show
  1. package/dist/core/EntityManager.d.ts +2 -0
  2. package/dist/core/EntityManager.d.ts.map +1 -1
  3. package/dist/core/EntityManager.js +14 -9
  4. package/dist/core/RelationManager.d.ts.map +1 -1
  5. package/dist/core/RelationManager.js +5 -4
  6. package/dist/features/CompressionManager.d.ts +3 -1
  7. package/dist/features/CompressionManager.d.ts.map +1 -1
  8. package/dist/features/CompressionManager.js +14 -5
  9. package/dist/search/BM25Search.d.ts +148 -0
  10. package/dist/search/BM25Search.d.ts.map +1 -0
  11. package/dist/search/BM25Search.js +339 -0
  12. package/dist/search/EarlyTerminationManager.d.ts +140 -0
  13. package/dist/search/EarlyTerminationManager.d.ts.map +1 -0
  14. package/dist/search/EarlyTerminationManager.js +279 -0
  15. package/dist/search/EmbeddingCache.d.ts +175 -0
  16. package/dist/search/EmbeddingCache.d.ts.map +1 -0
  17. package/dist/search/EmbeddingCache.js +246 -0
  18. package/dist/search/EmbeddingService.d.ts +108 -9
  19. package/dist/search/EmbeddingService.d.ts.map +1 -1
  20. package/dist/search/EmbeddingService.js +187 -15
  21. package/dist/search/HybridScorer.d.ts +181 -0
  22. package/dist/search/HybridScorer.d.ts.map +1 -0
  23. package/dist/search/HybridScorer.js +257 -0
  24. package/dist/search/IncrementalIndexer.d.ts +201 -0
  25. package/dist/search/IncrementalIndexer.d.ts.map +1 -0
  26. package/dist/search/IncrementalIndexer.js +342 -0
  27. package/dist/search/OptimizedInvertedIndex.d.ts +163 -0
  28. package/dist/search/OptimizedInvertedIndex.d.ts.map +1 -0
  29. package/dist/search/OptimizedInvertedIndex.js +358 -0
  30. package/dist/search/ParallelSearchExecutor.d.ts +172 -0
  31. package/dist/search/ParallelSearchExecutor.d.ts.map +1 -0
  32. package/dist/search/ParallelSearchExecutor.js +309 -0
  33. package/dist/search/QuantizedVectorStore.d.ts +171 -0
  34. package/dist/search/QuantizedVectorStore.d.ts.map +1 -0
  35. package/dist/search/QuantizedVectorStore.js +307 -0
  36. package/dist/search/QueryCostEstimator.d.ts +135 -2
  37. package/dist/search/QueryCostEstimator.d.ts.map +1 -1
  38. package/dist/search/QueryCostEstimator.js +298 -1
  39. package/dist/search/QueryPlanCache.d.ts +220 -0
  40. package/dist/search/QueryPlanCache.d.ts.map +1 -0
  41. package/dist/search/QueryPlanCache.js +379 -0
  42. package/dist/search/ReflectionManager.d.ts +49 -0
  43. package/dist/search/ReflectionManager.d.ts.map +1 -1
  44. package/dist/search/ReflectionManager.js +113 -6
  45. package/dist/search/index.d.ts +12 -3
  46. package/dist/search/index.d.ts.map +1 -1
  47. package/dist/search/index.js +20 -2
  48. package/dist/types/index.d.ts +1 -1
  49. package/dist/types/index.d.ts.map +1 -1
  50. package/dist/types/types.d.ts +41 -2
  51. package/dist/types/types.d.ts.map +1 -1
  52. package/dist/utils/BatchProcessor.d.ts +271 -0
  53. package/dist/utils/BatchProcessor.d.ts.map +1 -0
  54. package/dist/utils/BatchProcessor.js +376 -0
  55. package/dist/utils/MemoryMonitor.d.ts +176 -0
  56. package/dist/utils/MemoryMonitor.d.ts.map +1 -0
  57. package/dist/utils/MemoryMonitor.js +305 -0
  58. package/dist/utils/WorkerPoolManager.d.ts +233 -0
  59. package/dist/utils/WorkerPoolManager.d.ts.map +1 -0
  60. package/dist/utils/WorkerPoolManager.js +420 -0
  61. package/dist/utils/compressedCache.d.ts +29 -0
  62. package/dist/utils/compressedCache.d.ts.map +1 -1
  63. package/dist/utils/compressedCache.js +39 -0
  64. package/dist/utils/entityUtils.d.ts +25 -0
  65. package/dist/utils/entityUtils.d.ts.map +1 -1
  66. package/dist/utils/entityUtils.js +33 -0
  67. package/dist/utils/index.d.ts +4 -1
  68. package/dist/utils/index.d.ts.map +1 -1
  69. package/dist/utils/index.js +8 -0
  70. package/package.json +1 -1
@@ -0,0 +1,358 @@
1
+ /**
2
+ * Optimized Inverted Index
3
+ *
4
+ * Memory-efficient inverted index using integer IDs and Uint32Array
5
+ * for fast multi-term intersection queries.
6
+ *
7
+ * Phase 12 Sprint 3: Search Algorithm Optimization
8
+ *
9
+ * @module search/OptimizedInvertedIndex
10
+ */
11
+ /**
12
+ * Optimized Inverted Index using integer document IDs.
13
+ *
14
+ * Memory Optimizations:
15
+ * 1. Uses integer IDs instead of string entity names
16
+ * 2. Stores posting lists as Uint32Array (4 bytes per ID vs ~20+ bytes per string)
17
+ * 3. Maintains sorted posting lists for efficient intersection
18
+ *
19
+ * Performance Optimizations:
20
+ * 1. Sorted array intersection is O(n+m) where n,m are posting list lengths
21
+ * 2. Early termination when one list is exhausted
22
+ * 3. Binary search available for unbalanced list sizes
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * const index = new OptimizedInvertedIndex();
27
+ * index.addDocument('entity1', ['machine', 'learning', 'ai']);
28
+ * index.addDocument('entity2', ['deep', 'learning', 'neural']);
29
+ *
30
+ * // Find documents containing both 'machine' AND 'learning'
31
+ * const results = index.intersect(['machine', 'learning']);
32
+ * console.log(results); // ['entity1']
33
+ * ```
34
+ */
35
+ export class OptimizedInvertedIndex {
36
+ /** Map from entity name to integer ID */
37
+ entityToId = new Map();
38
+ /** Map from integer ID to entity name */
39
+ idToEntity = new Map();
40
+ /** Next available ID */
41
+ nextId = 0;
42
+ /** Inverted index: term -> sorted array of document IDs */
43
+ postingLists = new Map();
44
+ /** Temporary posting lists (before finalization) */
45
+ tempPostingLists = new Map();
46
+ /** Whether the index is finalized (posting lists converted to Uint32Array) */
47
+ finalized = false;
48
+ /**
49
+ * Add a document to the index.
50
+ *
51
+ * @param entityName - Unique document identifier
52
+ * @param terms - Array of terms in the document (should be lowercase)
53
+ */
54
+ addDocument(entityName, terms) {
55
+ // Unfinalize if already finalized (allows incremental updates)
56
+ if (this.finalized) {
57
+ this.unfinalize();
58
+ }
59
+ // Get or assign document ID
60
+ let docId = this.entityToId.get(entityName);
61
+ if (docId === undefined) {
62
+ docId = this.nextId++;
63
+ this.entityToId.set(entityName, docId);
64
+ this.idToEntity.set(docId, entityName);
65
+ }
66
+ // Add unique terms to posting lists
67
+ const seenTerms = new Set();
68
+ for (const term of terms) {
69
+ if (seenTerms.has(term))
70
+ continue;
71
+ seenTerms.add(term);
72
+ let postingList = this.tempPostingLists.get(term);
73
+ if (!postingList) {
74
+ postingList = [];
75
+ this.tempPostingLists.set(term, postingList);
76
+ }
77
+ // Only add if not already present (maintains sorted order if added in order)
78
+ if (postingList.length === 0 || postingList[postingList.length - 1] !== docId) {
79
+ postingList.push(docId);
80
+ }
81
+ }
82
+ }
83
+ /**
84
+ * Remove a document from the index.
85
+ *
86
+ * @param entityName - Document to remove
87
+ * @returns True if document was found and removed
88
+ */
89
+ removeDocument(entityName) {
90
+ const docId = this.entityToId.get(entityName);
91
+ if (docId === undefined) {
92
+ return false;
93
+ }
94
+ // Unfinalize if needed
95
+ if (this.finalized) {
96
+ this.unfinalize();
97
+ }
98
+ // Remove from all posting lists
99
+ for (const [term, postingList] of this.tempPostingLists) {
100
+ const idx = postingList.indexOf(docId);
101
+ if (idx !== -1) {
102
+ postingList.splice(idx, 1);
103
+ if (postingList.length === 0) {
104
+ this.tempPostingLists.delete(term);
105
+ }
106
+ }
107
+ }
108
+ // Remove ID mappings
109
+ this.entityToId.delete(entityName);
110
+ this.idToEntity.delete(docId);
111
+ return true;
112
+ }
113
+ /**
114
+ * Finalize the index by converting posting lists to Uint32Array.
115
+ *
116
+ * This should be called after bulk indexing for optimal memory usage.
117
+ * The index can still be updated after finalization, but it will
118
+ * temporarily use more memory during updates.
119
+ */
120
+ finalize() {
121
+ if (this.finalized)
122
+ return;
123
+ // Convert temp posting lists to Uint32Array and sort
124
+ this.postingLists.clear();
125
+ for (const [term, list] of this.tempPostingLists) {
126
+ // Sort and convert to Uint32Array
127
+ list.sort((a, b) => a - b);
128
+ const arr = new Uint32Array(list);
129
+ this.postingLists.set(term, arr);
130
+ }
131
+ // Clear temp posting lists to save memory
132
+ this.tempPostingLists.clear();
133
+ this.finalized = true;
134
+ }
135
+ /**
136
+ * Convert finalized index back to mutable format.
137
+ */
138
+ unfinalize() {
139
+ if (!this.finalized)
140
+ return;
141
+ // Convert Uint32Array back to regular arrays
142
+ this.tempPostingLists.clear();
143
+ for (const [term, arr] of this.postingLists) {
144
+ this.tempPostingLists.set(term, Array.from(arr));
145
+ }
146
+ this.postingLists.clear();
147
+ this.finalized = false;
148
+ }
149
+ /**
150
+ * Get posting list for a term.
151
+ *
152
+ * @param term - Term to look up
153
+ * @returns Posting list result or null if term not found
154
+ */
155
+ getPostingList(term) {
156
+ if (this.finalized) {
157
+ const arr = this.postingLists.get(term);
158
+ if (!arr)
159
+ return null;
160
+ return { term, docIds: arr };
161
+ }
162
+ else {
163
+ const list = this.tempPostingLists.get(term);
164
+ if (!list)
165
+ return null;
166
+ // Sort and return as Uint32Array
167
+ const sorted = list.slice().sort((a, b) => a - b);
168
+ return { term, docIds: new Uint32Array(sorted) };
169
+ }
170
+ }
171
+ /**
172
+ * Perform intersection of posting lists for multiple terms.
173
+ *
174
+ * Returns entity names that contain ALL specified terms.
175
+ *
176
+ * @param terms - Array of terms to intersect
177
+ * @returns Array of entity names containing all terms
178
+ */
179
+ intersect(terms) {
180
+ if (terms.length === 0) {
181
+ return [];
182
+ }
183
+ // Ensure finalized for optimal performance
184
+ if (!this.finalized) {
185
+ this.finalize();
186
+ }
187
+ // Get posting lists for all terms
188
+ const postingLists = [];
189
+ for (const term of terms) {
190
+ const list = this.postingLists.get(term);
191
+ if (!list || list.length === 0) {
192
+ // If any term has no posting list, intersection is empty
193
+ return [];
194
+ }
195
+ postingLists.push(list);
196
+ }
197
+ // Sort by length (smallest first for early termination)
198
+ postingLists.sort((a, b) => a.length - b.length);
199
+ // Perform multi-way sorted intersection
200
+ let result = postingLists[0];
201
+ for (let i = 1; i < postingLists.length; i++) {
202
+ result = this.intersectTwo(result, postingLists[i]);
203
+ if (result.length === 0) {
204
+ return [];
205
+ }
206
+ }
207
+ // Convert IDs back to entity names
208
+ return Array.from(result).map(id => this.idToEntity.get(id));
209
+ }
210
+ /**
211
+ * Perform union of posting lists for multiple terms.
212
+ *
213
+ * Returns entity names that contain ANY of the specified terms.
214
+ *
215
+ * @param terms - Array of terms to union
216
+ * @returns Array of entity names containing any term
217
+ */
218
+ union(terms) {
219
+ if (terms.length === 0) {
220
+ return [];
221
+ }
222
+ // Ensure finalized for optimal performance
223
+ if (!this.finalized) {
224
+ this.finalize();
225
+ }
226
+ // Collect all unique document IDs
227
+ const allIds = new Set();
228
+ for (const term of terms) {
229
+ const list = this.postingLists.get(term);
230
+ if (list) {
231
+ for (const id of list) {
232
+ allIds.add(id);
233
+ }
234
+ }
235
+ }
236
+ // Convert IDs back to entity names
237
+ return Array.from(allIds).map(id => this.idToEntity.get(id));
238
+ }
239
+ /**
240
+ * Get entities containing a single term.
241
+ *
242
+ * @param term - Term to search for
243
+ * @returns Array of entity names containing the term
244
+ */
245
+ search(term) {
246
+ if (!this.finalized) {
247
+ const list = this.tempPostingLists.get(term);
248
+ if (!list)
249
+ return [];
250
+ return list.map(id => this.idToEntity.get(id));
251
+ }
252
+ const list = this.postingLists.get(term);
253
+ if (!list)
254
+ return [];
255
+ return Array.from(list).map(id => this.idToEntity.get(id));
256
+ }
257
+ /**
258
+ * Intersect two sorted Uint32Arrays.
259
+ *
260
+ * Uses merge-style intersection which is O(n+m).
261
+ */
262
+ intersectTwo(a, b) {
263
+ const result = [];
264
+ let i = 0;
265
+ let j = 0;
266
+ while (i < a.length && j < b.length) {
267
+ if (a[i] === b[j]) {
268
+ result.push(a[i]);
269
+ i++;
270
+ j++;
271
+ }
272
+ else if (a[i] < b[j]) {
273
+ i++;
274
+ }
275
+ else {
276
+ j++;
277
+ }
278
+ }
279
+ return new Uint32Array(result);
280
+ }
281
+ /**
282
+ * Get memory usage statistics.
283
+ */
284
+ getMemoryUsage() {
285
+ let postingListBytes = 0;
286
+ let termCount = 0;
287
+ if (this.finalized) {
288
+ for (const arr of this.postingLists.values()) {
289
+ // Uint32Array uses 4 bytes per element
290
+ postingListBytes += arr.byteLength;
291
+ termCount++;
292
+ }
293
+ }
294
+ else {
295
+ for (const list of this.tempPostingLists.values()) {
296
+ // Regular array uses 8 bytes per element (64-bit numbers in V8)
297
+ // Plus array overhead
298
+ postingListBytes += list.length * 8 + 32; // Approximate overhead
299
+ termCount++;
300
+ }
301
+ }
302
+ // Estimate ID map overhead
303
+ // Map has ~100 bytes overhead + ~50 bytes per entry for string keys
304
+ const idMapBytes = 100 +
305
+ this.entityToId.size * 50 +
306
+ this.idToEntity.size * 8; // number key is ~8 bytes
307
+ // Estimate term index overhead
308
+ // ~50 bytes per term entry (key + pointer)
309
+ const termIndexBytes = termCount * 50;
310
+ return {
311
+ postingListBytes,
312
+ idMapBytes,
313
+ termIndexBytes,
314
+ totalBytes: postingListBytes + idMapBytes + termIndexBytes,
315
+ termCount,
316
+ documentCount: this.entityToId.size,
317
+ };
318
+ }
319
+ /**
320
+ * Clear the entire index.
321
+ */
322
+ clear() {
323
+ this.entityToId.clear();
324
+ this.idToEntity.clear();
325
+ this.postingLists.clear();
326
+ this.tempPostingLists.clear();
327
+ this.nextId = 0;
328
+ this.finalized = false;
329
+ }
330
+ /**
331
+ * Get the number of documents in the index.
332
+ */
333
+ get documentCount() {
334
+ return this.entityToId.size;
335
+ }
336
+ /**
337
+ * Get the number of unique terms in the index.
338
+ */
339
+ get termCount() {
340
+ return this.finalized
341
+ ? this.postingLists.size
342
+ : this.tempPostingLists.size;
343
+ }
344
+ /**
345
+ * Check if an entity is indexed.
346
+ */
347
+ hasDocument(entityName) {
348
+ return this.entityToId.has(entityName);
349
+ }
350
+ /**
351
+ * Check if a term exists in the index.
352
+ */
353
+ hasTerm(term) {
354
+ return this.finalized
355
+ ? this.postingLists.has(term)
356
+ : this.tempPostingLists.has(term);
357
+ }
358
+ }
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Parallel Search Executor
3
+ *
4
+ * Phase 12 Sprint 2: Executes search layers (semantic, lexical, symbolic)
5
+ * concurrently using Promise.all with graceful fallback on failures.
6
+ *
7
+ * @module search/ParallelSearchExecutor
8
+ */
9
+ import type { ReadonlyKnowledgeGraph, SymbolicFilters } from '../types/index.js';
10
+ import type { SemanticSearch } from './SemanticSearch.js';
11
+ import type { RankedSearch } from './RankedSearch.js';
12
+ /**
13
+ * Timing information for a search layer.
14
+ */
15
+ export interface LayerTiming {
16
+ /** Layer identifier */
17
+ layer: 'semantic' | 'lexical' | 'symbolic';
18
+ /** Start timestamp */
19
+ startTime: number;
20
+ /** End timestamp */
21
+ endTime: number;
22
+ /** Duration in milliseconds */
23
+ durationMs: number;
24
+ /** Whether the layer succeeded */
25
+ success: boolean;
26
+ /** Error message if failed */
27
+ error?: string;
28
+ /** Number of results returned */
29
+ resultCount: number;
30
+ }
31
+ /**
32
+ * Result from parallel search execution with timing metadata.
33
+ */
34
+ export interface ParallelSearchResult {
35
+ /** Semantic search results: entity name -> similarity score */
36
+ semanticResults: Map<string, number>;
37
+ /** Lexical search results: entity name -> normalized score */
38
+ lexicalResults: Map<string, number>;
39
+ /** Symbolic search results: entity name -> filter match score */
40
+ symbolicResults: Map<string, number>;
41
+ /** Timing information for each layer */
42
+ timings: LayerTiming[];
43
+ /** Total execution time in milliseconds */
44
+ totalTimeMs: number;
45
+ /** Whether all layers succeeded */
46
+ allSucceeded: boolean;
47
+ /** Summary of failed layers */
48
+ failedLayers: string[];
49
+ }
50
+ /**
51
+ * Options for parallel search execution.
52
+ */
53
+ export interface ParallelSearchOptions {
54
+ /** Semantic search options */
55
+ semantic?: {
56
+ minSimilarity?: number;
57
+ topK?: number;
58
+ };
59
+ /** Lexical search options */
60
+ lexical?: {
61
+ useStopwords?: boolean;
62
+ useStemming?: boolean;
63
+ };
64
+ /** Symbolic filter criteria */
65
+ symbolic?: SymbolicFilters;
66
+ /** Maximum results per layer */
67
+ limit?: number;
68
+ /** Timeout per layer in milliseconds (default: 30000) */
69
+ timeoutMs?: number;
70
+ }
71
+ /**
72
+ * ParallelSearchExecutor - Execute search layers concurrently
73
+ *
74
+ * Orchestrates parallel execution of semantic, lexical, and symbolic search
75
+ * layers using Promise.all. Provides:
76
+ * - Concurrent execution for improved latency
77
+ * - Per-layer timing metadata
78
+ * - Graceful fallback on individual layer failures
79
+ * - Layer-specific error isolation
80
+ *
81
+ * @example
82
+ * ```typescript
83
+ * const executor = new ParallelSearchExecutor(semanticSearch, rankedSearch);
84
+ *
85
+ * const result = await executor.execute(graph, 'machine learning', {
86
+ * semantic: { minSimilarity: 0.5 },
87
+ * symbolic: { tags: ['ai'] }
88
+ * });
89
+ *
90
+ * console.log(`Total time: ${result.totalTimeMs}ms`);
91
+ * for (const timing of result.timings) {
92
+ * console.log(`${timing.layer}: ${timing.durationMs}ms, ${timing.resultCount} results`);
93
+ * }
94
+ * ```
95
+ */
96
+ export declare class ParallelSearchExecutor {
97
+ private semanticSearch;
98
+ private rankedSearch;
99
+ private symbolicSearch;
100
+ constructor(semanticSearch: SemanticSearch | null, rankedSearch: RankedSearch);
101
+ /**
102
+ * Execute all search layers in parallel.
103
+ *
104
+ * @param graph - Knowledge graph to search
105
+ * @param query - Search query text
106
+ * @param options - Search options for each layer
107
+ * @returns Parallel search results with timing metadata
108
+ */
109
+ execute(graph: ReadonlyKnowledgeGraph, query: string, options?: ParallelSearchOptions): Promise<ParallelSearchResult>;
110
+ /**
111
+ * Execute semantic search layer with timing.
112
+ */
113
+ private executeSemanticLayer;
114
+ /**
115
+ * Execute lexical search layer (TF-IDF/BM25) with timing.
116
+ */
117
+ private executeLexicalLayer;
118
+ /**
119
+ * Execute symbolic search layer with timing.
120
+ */
121
+ private executeSymbolicLayer;
122
+ /**
123
+ * Create a timeout promise.
124
+ */
125
+ private createTimeout;
126
+ /**
127
+ * Execute a single layer independently.
128
+ *
129
+ * @param layer - Layer to execute
130
+ * @param graph - Knowledge graph
131
+ * @param query - Search query
132
+ * @param options - Layer-specific options
133
+ * @returns Layer results with timing
134
+ */
135
+ executeLayer(layer: 'semantic' | 'lexical' | 'symbolic', graph: ReadonlyKnowledgeGraph, query: string, options?: ParallelSearchOptions): Promise<{
136
+ results: Map<string, number>;
137
+ timing: LayerTiming;
138
+ }>;
139
+ /**
140
+ * Execute only specific layers in parallel.
141
+ *
142
+ * @param layers - Layers to execute
143
+ * @param graph - Knowledge graph
144
+ * @param query - Search query
145
+ * @param options - Search options
146
+ * @returns Partial results for requested layers
147
+ */
148
+ executeSelectedLayers(layers: Array<'semantic' | 'lexical' | 'symbolic'>, graph: ReadonlyKnowledgeGraph, query: string, options?: ParallelSearchOptions): Promise<{
149
+ results: Map<'semantic' | 'lexical' | 'symbolic', Map<string, number>>;
150
+ timings: LayerTiming[];
151
+ totalTimeMs: number;
152
+ }>;
153
+ /**
154
+ * Get timing summary from results.
155
+ *
156
+ * @param timings - Array of layer timings
157
+ * @returns Formatted timing summary
158
+ */
159
+ static formatTimingSummary(timings: LayerTiming[]): string;
160
+ /**
161
+ * Calculate potential speedup from parallel execution.
162
+ *
163
+ * @param timings - Array of layer timings
164
+ * @returns Speedup metrics
165
+ */
166
+ static calculateSpeedup(timings: LayerTiming[]): {
167
+ sequentialTime: number;
168
+ parallelTime: number;
169
+ speedup: number;
170
+ };
171
+ }
172
+ //# sourceMappingURL=ParallelSearchExecutor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ParallelSearchExecutor.d.ts","sourceRoot":"","sources":["../../src/search/ParallelSearchExecutor.ts"],"names":[],"mappings":"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"}