@danielsimonjr/memory-mcp 11.0.1 → 11.1.1

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 (172) hide show
  1. package/LICENSE +22 -22
  2. package/dist/core/EntityManager.d.ts +10 -15
  3. package/dist/core/EntityManager.d.ts.map +1 -1
  4. package/dist/core/EntityManager.js +21 -54
  5. package/dist/core/GraphStorage.d.ts +0 -51
  6. package/dist/core/GraphStorage.d.ts.map +1 -1
  7. package/dist/core/GraphStorage.js +2 -79
  8. package/dist/core/GraphTraversal.d.ts +2 -7
  9. package/dist/core/GraphTraversal.d.ts.map +1 -1
  10. package/dist/core/GraphTraversal.js +2 -19
  11. package/dist/core/ManagerContext.d.ts +0 -4
  12. package/dist/core/ManagerContext.d.ts.map +1 -1
  13. package/dist/core/ManagerContext.js +2 -12
  14. package/dist/core/RelationManager.d.ts.map +1 -1
  15. package/dist/core/RelationManager.js +4 -5
  16. package/dist/core/SQLiteStorage.d.ts.map +1 -1
  17. package/dist/core/SQLiteStorage.js +2 -3
  18. package/dist/core/TransactionManager.d.ts +2 -207
  19. package/dist/core/TransactionManager.d.ts.map +1 -1
  20. package/dist/core/TransactionManager.js +6 -482
  21. package/dist/core/index.d.ts +1 -2
  22. package/dist/core/index.d.ts.map +1 -1
  23. package/dist/core/index.js +1 -3
  24. package/dist/features/ArchiveManager.d.ts +2 -14
  25. package/dist/features/ArchiveManager.d.ts.map +1 -1
  26. package/dist/features/ArchiveManager.js +3 -44
  27. package/dist/features/CompressionManager.d.ts +4 -14
  28. package/dist/features/CompressionManager.d.ts.map +1 -1
  29. package/dist/features/CompressionManager.js +9 -74
  30. package/dist/features/IOManager.d.ts +2 -6
  31. package/dist/features/IOManager.d.ts.map +1 -1
  32. package/dist/features/IOManager.js +10 -105
  33. package/dist/features/StreamingExporter.d.ts +4 -27
  34. package/dist/features/StreamingExporter.d.ts.map +1 -1
  35. package/dist/features/StreamingExporter.js +4 -65
  36. package/dist/features/index.d.ts +0 -2
  37. package/dist/features/index.d.ts.map +1 -1
  38. package/dist/features/index.js +0 -3
  39. package/dist/search/EmbeddingService.d.ts +9 -108
  40. package/dist/search/EmbeddingService.d.ts.map +1 -1
  41. package/dist/search/EmbeddingService.js +15 -187
  42. package/dist/search/FuzzySearch.js +1 -1
  43. package/dist/search/SavedSearchManager.d.ts.map +1 -1
  44. package/dist/search/SavedSearchManager.js +2 -3
  45. package/dist/search/SearchManager.d.ts +1 -42
  46. package/dist/search/SearchManager.d.ts.map +1 -1
  47. package/dist/search/SearchManager.js +0 -115
  48. package/dist/search/SemanticSearch.d.ts +1 -4
  49. package/dist/search/SemanticSearch.d.ts.map +1 -1
  50. package/dist/search/SemanticSearch.js +2 -12
  51. package/dist/search/TFIDFIndexManager.d.ts +0 -88
  52. package/dist/search/TFIDFIndexManager.d.ts.map +1 -1
  53. package/dist/search/TFIDFIndexManager.js +0 -217
  54. package/dist/search/index.d.ts +1 -18
  55. package/dist/search/index.d.ts.map +1 -1
  56. package/dist/search/index.js +1 -32
  57. package/dist/server/MCPServer.d.ts.map +1 -1
  58. package/dist/server/MCPServer.js +4 -1
  59. package/dist/server/responseCompressor.js +5 -5
  60. package/dist/server/toolDefinitions.d.ts.map +1 -1
  61. package/dist/server/toolDefinitions.js +5 -1
  62. package/dist/server/toolHandlers.d.ts +9 -5
  63. package/dist/server/toolHandlers.d.ts.map +1 -1
  64. package/dist/server/toolHandlers.js +23 -8
  65. package/dist/types/index.d.ts +1 -1
  66. package/dist/types/index.d.ts.map +1 -1
  67. package/dist/types/types.d.ts +2 -579
  68. package/dist/types/types.d.ts.map +1 -1
  69. package/dist/utils/compressedCache.d.ts +0 -29
  70. package/dist/utils/compressedCache.d.ts.map +1 -1
  71. package/dist/utils/compressedCache.js +0 -39
  72. package/dist/utils/entityUtils.d.ts +1 -59
  73. package/dist/utils/entityUtils.d.ts.map +1 -1
  74. package/dist/utils/entityUtils.js +3 -113
  75. package/dist/utils/errors.d.ts +0 -18
  76. package/dist/utils/errors.d.ts.map +1 -1
  77. package/dist/utils/errors.js +0 -24
  78. package/dist/utils/index.d.ts +2 -6
  79. package/dist/utils/index.d.ts.map +1 -1
  80. package/dist/utils/index.js +2 -14
  81. package/dist/utils/logger.d.ts +0 -7
  82. package/dist/utils/logger.d.ts.map +1 -1
  83. package/dist/utils/logger.js +2 -9
  84. package/dist/utils/parallelUtils.d.ts +1 -5
  85. package/dist/utils/parallelUtils.d.ts.map +1 -1
  86. package/dist/utils/parallelUtils.js +1 -23
  87. package/dist/utils/schemas.d.ts +16 -16
  88. package/dist/utils/schemas.d.ts.map +1 -1
  89. package/dist/utils/schemas.js +12 -12
  90. package/dist/utils/taskScheduler.d.ts +0 -4
  91. package/dist/utils/taskScheduler.d.ts.map +1 -1
  92. package/dist/utils/taskScheduler.js +1 -21
  93. package/dist/workers/WorkerPool.d.ts +81 -0
  94. package/dist/workers/WorkerPool.d.ts.map +1 -0
  95. package/dist/workers/WorkerPool.js +121 -0
  96. package/dist/workers/index.d.ts +1 -1
  97. package/dist/workers/index.d.ts.map +1 -1
  98. package/dist/workers/levenshteinWorker.js +1 -1
  99. package/package.json +1 -4
  100. package/dist/__tests__/file-path.test.js +0 -119
  101. package/dist/__tests__/knowledge-graph.test.js +0 -318
  102. package/dist/core/GraphEventEmitter.d.ts +0 -202
  103. package/dist/core/GraphEventEmitter.d.ts.map +0 -1
  104. package/dist/core/GraphEventEmitter.js +0 -346
  105. package/dist/features/KeywordExtractor.d.ts +0 -61
  106. package/dist/features/KeywordExtractor.d.ts.map +0 -1
  107. package/dist/features/KeywordExtractor.js +0 -126
  108. package/dist/features/ObservationNormalizer.d.ts +0 -90
  109. package/dist/features/ObservationNormalizer.d.ts.map +0 -1
  110. package/dist/features/ObservationNormalizer.js +0 -193
  111. package/dist/memory.jsonl +0 -1
  112. package/dist/search/BM25Search.d.ts +0 -148
  113. package/dist/search/BM25Search.d.ts.map +0 -1
  114. package/dist/search/BM25Search.js +0 -339
  115. package/dist/search/EarlyTerminationManager.d.ts +0 -140
  116. package/dist/search/EarlyTerminationManager.d.ts.map +0 -1
  117. package/dist/search/EarlyTerminationManager.js +0 -279
  118. package/dist/search/EmbeddingCache.d.ts +0 -175
  119. package/dist/search/EmbeddingCache.d.ts.map +0 -1
  120. package/dist/search/EmbeddingCache.js +0 -246
  121. package/dist/search/HybridScorer.d.ts +0 -181
  122. package/dist/search/HybridScorer.d.ts.map +0 -1
  123. package/dist/search/HybridScorer.js +0 -257
  124. package/dist/search/HybridSearchManager.d.ts +0 -80
  125. package/dist/search/HybridSearchManager.d.ts.map +0 -1
  126. package/dist/search/HybridSearchManager.js +0 -187
  127. package/dist/search/IncrementalIndexer.d.ts +0 -201
  128. package/dist/search/IncrementalIndexer.d.ts.map +0 -1
  129. package/dist/search/IncrementalIndexer.js +0 -342
  130. package/dist/search/OptimizedInvertedIndex.d.ts +0 -163
  131. package/dist/search/OptimizedInvertedIndex.d.ts.map +0 -1
  132. package/dist/search/OptimizedInvertedIndex.js +0 -358
  133. package/dist/search/ParallelSearchExecutor.d.ts +0 -172
  134. package/dist/search/ParallelSearchExecutor.d.ts.map +0 -1
  135. package/dist/search/ParallelSearchExecutor.js +0 -309
  136. package/dist/search/QuantizedVectorStore.d.ts +0 -171
  137. package/dist/search/QuantizedVectorStore.d.ts.map +0 -1
  138. package/dist/search/QuantizedVectorStore.js +0 -307
  139. package/dist/search/QueryAnalyzer.d.ts +0 -76
  140. package/dist/search/QueryAnalyzer.d.ts.map +0 -1
  141. package/dist/search/QueryAnalyzer.js +0 -227
  142. package/dist/search/QueryCostEstimator.d.ts +0 -244
  143. package/dist/search/QueryCostEstimator.d.ts.map +0 -1
  144. package/dist/search/QueryCostEstimator.js +0 -652
  145. package/dist/search/QueryPlanCache.d.ts +0 -220
  146. package/dist/search/QueryPlanCache.d.ts.map +0 -1
  147. package/dist/search/QueryPlanCache.js +0 -379
  148. package/dist/search/QueryPlanner.d.ts +0 -58
  149. package/dist/search/QueryPlanner.d.ts.map +0 -1
  150. package/dist/search/QueryPlanner.js +0 -137
  151. package/dist/search/ReflectionManager.d.ts +0 -120
  152. package/dist/search/ReflectionManager.d.ts.map +0 -1
  153. package/dist/search/ReflectionManager.js +0 -231
  154. package/dist/search/SymbolicSearch.d.ts +0 -61
  155. package/dist/search/SymbolicSearch.d.ts.map +0 -1
  156. package/dist/search/SymbolicSearch.js +0 -163
  157. package/dist/search/TFIDFEventSync.d.ts +0 -85
  158. package/dist/search/TFIDFEventSync.d.ts.map +0 -1
  159. package/dist/search/TFIDFEventSync.js +0 -133
  160. package/dist/utils/BatchProcessor.d.ts +0 -271
  161. package/dist/utils/BatchProcessor.d.ts.map +0 -1
  162. package/dist/utils/BatchProcessor.js +0 -376
  163. package/dist/utils/MemoryMonitor.d.ts +0 -176
  164. package/dist/utils/MemoryMonitor.d.ts.map +0 -1
  165. package/dist/utils/MemoryMonitor.js +0 -305
  166. package/dist/utils/WorkerPoolManager.d.ts +0 -233
  167. package/dist/utils/WorkerPoolManager.d.ts.map +0 -1
  168. package/dist/utils/WorkerPoolManager.js +0 -420
  169. package/dist/utils/operationUtils.d.ts +0 -124
  170. package/dist/utils/operationUtils.d.ts.map +0 -1
  171. package/dist/utils/operationUtils.js +0 -175
  172. package/dist/vitest.config.js +0 -13
@@ -1,246 +0,0 @@
1
- /**
2
- * Embedding Cache
3
- *
4
- * Phase 12 Sprint 5: LRU cache for embedding vectors with hit/miss tracking,
5
- * auto-invalidation on text hash changes, and TTL support.
6
- *
7
- * @module search/EmbeddingCache
8
- */
9
- import { createHash } from 'crypto';
10
- /**
11
- * Default cache options.
12
- */
13
- export const DEFAULT_EMBEDDING_CACHE_OPTIONS = {
14
- maxSize: 1000,
15
- ttlMs: 3600000, // 1 hour
16
- dimensions: 384,
17
- };
18
- /**
19
- * LRU cache for embedding vectors with hit/miss tracking.
20
- *
21
- * Features:
22
- * - LRU eviction when max size is reached
23
- * - Text hash-based invalidation (detects stale entries)
24
- * - TTL support for automatic expiration
25
- * - Hit/miss statistics tracking
26
- *
27
- * @example
28
- * ```typescript
29
- * const cache = new EmbeddingCache({ maxSize: 500, ttlMs: 60000 });
30
- *
31
- * // Cache an embedding
32
- * cache.set('entity1', 'Original text content', [0.1, 0.2, ...]);
33
- *
34
- * // Retrieve from cache
35
- * const result = cache.get('entity1', 'Original text content');
36
- * if (result) {
37
- * console.log('Cache hit!', result);
38
- * }
39
- *
40
- * // Check stats
41
- * console.log(cache.getStats()); // { size, memoryBytes, hitRate, hits, misses }
42
- * ```
43
- */
44
- export class EmbeddingCache {
45
- cache;
46
- options;
47
- hits = 0;
48
- misses = 0;
49
- /**
50
- * Create a new embedding cache.
51
- *
52
- * @param options - Cache configuration options
53
- */
54
- constructor(options) {
55
- this.options = { ...DEFAULT_EMBEDDING_CACHE_OPTIONS, ...options };
56
- this.cache = new Map();
57
- }
58
- /**
59
- * Hash a text string for cache invalidation.
60
- *
61
- * @param text - Text to hash
62
- * @returns MD5 hash of the text
63
- */
64
- hashText(text) {
65
- return createHash('md5').update(text).digest('hex');
66
- }
67
- /**
68
- * Check if an entry is expired based on TTL.
69
- *
70
- * @param entry - Cache entry to check
71
- * @returns True if expired
72
- */
73
- isExpired(entry) {
74
- return Date.now() - entry.createdAt > this.options.ttlMs;
75
- }
76
- /**
77
- * Evict the least recently used entry.
78
- */
79
- evictLRU() {
80
- let oldestKey = null;
81
- let oldestTime = Infinity;
82
- for (const [key, entry] of this.cache) {
83
- if (entry.lastAccess < oldestTime) {
84
- oldestTime = entry.lastAccess;
85
- oldestKey = key;
86
- }
87
- }
88
- if (oldestKey) {
89
- this.cache.delete(oldestKey);
90
- }
91
- }
92
- /**
93
- * Get an embedding from the cache.
94
- *
95
- * Returns null if:
96
- * - Key not found
97
- * - Entry is expired (TTL)
98
- * - Text hash doesn't match (content changed)
99
- *
100
- * @param key - Cache key (typically entity name)
101
- * @param text - Current text content (for hash validation)
102
- * @returns Embedding vector if found and valid, null otherwise
103
- */
104
- get(key, text) {
105
- const entry = this.cache.get(key);
106
- if (!entry) {
107
- this.misses++;
108
- return null;
109
- }
110
- // Check TTL
111
- if (this.isExpired(entry)) {
112
- this.cache.delete(key);
113
- this.misses++;
114
- return null;
115
- }
116
- // Check text hash for invalidation
117
- const currentHash = this.hashText(text);
118
- if (entry.textHash !== currentHash) {
119
- this.cache.delete(key);
120
- this.misses++;
121
- return null;
122
- }
123
- // Update last access time
124
- entry.lastAccess = Date.now();
125
- this.hits++;
126
- return entry.vector;
127
- }
128
- /**
129
- * Set an embedding in the cache.
130
- *
131
- * Automatically evicts LRU entries if max size is reached.
132
- *
133
- * @param key - Cache key (typically entity name)
134
- * @param text - Text content (used for hash-based invalidation)
135
- * @param vector - Embedding vector to cache
136
- */
137
- set(key, text, vector) {
138
- // Evict if at capacity and not updating existing key
139
- if (this.cache.size >= this.options.maxSize && !this.cache.has(key)) {
140
- this.evictLRU();
141
- }
142
- const now = Date.now();
143
- this.cache.set(key, {
144
- vector,
145
- textHash: this.hashText(text),
146
- createdAt: now,
147
- lastAccess: now,
148
- });
149
- }
150
- /**
151
- * Check if a key exists in the cache (without affecting hit/miss stats).
152
- *
153
- * @param key - Cache key to check
154
- * @returns True if key exists (may be expired or stale)
155
- */
156
- has(key) {
157
- return this.cache.has(key);
158
- }
159
- /**
160
- * Delete an entry from the cache.
161
- *
162
- * @param key - Cache key to delete
163
- * @returns True if entry was deleted
164
- */
165
- delete(key) {
166
- return this.cache.delete(key);
167
- }
168
- /**
169
- * Clear all entries from the cache.
170
- */
171
- clear() {
172
- this.cache.clear();
173
- }
174
- /**
175
- * Get cache statistics.
176
- *
177
- * @returns Cache statistics including size, memory usage, and hit rate
178
- */
179
- getStats() {
180
- const size = this.cache.size;
181
- // Estimate memory: each entry has vector (dimensions * 8 bytes for float64)
182
- // plus overhead for hash (~32 bytes), timestamps (~16 bytes), and Map overhead (~50 bytes)
183
- const memoryPerEntry = this.options.dimensions * 8 + 32 + 16 + 50;
184
- const memoryBytes = size * memoryPerEntry;
185
- const totalRequests = this.hits + this.misses;
186
- const hitRate = totalRequests > 0 ? this.hits / totalRequests : 0;
187
- return {
188
- size,
189
- memoryBytes,
190
- hitRate,
191
- hits: this.hits,
192
- misses: this.misses,
193
- };
194
- }
195
- /**
196
- * Reset hit/miss statistics (useful for benchmarks).
197
- */
198
- resetStats() {
199
- this.hits = 0;
200
- this.misses = 0;
201
- }
202
- /**
203
- * Remove expired entries from the cache.
204
- *
205
- * Called automatically during get operations, but can be
206
- * manually triggered for maintenance.
207
- *
208
- * @returns Number of entries removed
209
- */
210
- pruneExpired() {
211
- let removed = 0;
212
- for (const [key, entry] of this.cache) {
213
- if (this.isExpired(entry)) {
214
- this.cache.delete(key);
215
- removed++;
216
- }
217
- }
218
- return removed;
219
- }
220
- /**
221
- * Get the current cache size.
222
- *
223
- * @returns Number of entries in the cache
224
- */
225
- size() {
226
- return this.cache.size;
227
- }
228
- /**
229
- * Get all cached keys.
230
- *
231
- * @returns Array of cache keys
232
- */
233
- keys() {
234
- return Array.from(this.cache.keys());
235
- }
236
- /**
237
- * Update options dynamically.
238
- *
239
- * Note: Reducing maxSize will not immediately evict entries.
240
- *
241
- * @param options - New options to apply
242
- */
243
- updateOptions(options) {
244
- this.options = { ...this.options, ...options };
245
- }
246
- }
@@ -1,181 +0,0 @@
1
- /**
2
- * Hybrid Scorer
3
- *
4
- * Combines semantic, lexical, and symbolic search scores with
5
- * min-max normalization and configurable weights.
6
- *
7
- * Phase 12 Sprint 3: Search Algorithm Optimization
8
- *
9
- * @module search/HybridScorer
10
- */
11
- import type { Entity } from '../types/index.js';
12
- /**
13
- * Result from semantic search layer.
14
- */
15
- export interface SemanticSearchResult {
16
- /** Entity name */
17
- entityName: string;
18
- /** Similarity score (typically 0-1 for cosine similarity) */
19
- similarity: number;
20
- /** The matched entity (if resolved) */
21
- entity?: Entity;
22
- }
23
- /**
24
- * Result from lexical search layer (TF-IDF or BM25).
25
- */
26
- export interface LexicalSearchResult {
27
- /** Entity name */
28
- entityName: string;
29
- /** Relevance score (unbounded, higher is better) */
30
- score: number;
31
- /** The matched entity (if resolved) */
32
- entity?: Entity;
33
- }
34
- /**
35
- * Result from symbolic search layer.
36
- */
37
- export interface SymbolicSearchResult {
38
- /** Entity name */
39
- entityName: string;
40
- /** Match score (typically 0-1) */
41
- score: number;
42
- /** The matched entity (if resolved) */
43
- entity?: Entity;
44
- }
45
- /**
46
- * Combined result with scores from all layers.
47
- */
48
- export interface ScoredResult {
49
- /** Entity name */
50
- entityName: string;
51
- /** The matched entity */
52
- entity: Entity;
53
- /** Individual layer scores (normalized 0-1) */
54
- scores: {
55
- semantic: number;
56
- lexical: number;
57
- symbolic: number;
58
- combined: number;
59
- };
60
- /** Which layers contributed to this result */
61
- matchedLayers: ('semantic' | 'lexical' | 'symbolic')[];
62
- /** Original raw scores before normalization */
63
- rawScores: {
64
- semantic?: number;
65
- lexical?: number;
66
- symbolic?: number;
67
- };
68
- }
69
- /**
70
- * Configurable weights for hybrid scoring.
71
- */
72
- export interface HybridWeights {
73
- /** Weight for semantic layer (default: 0.4) */
74
- semantic: number;
75
- /** Weight for lexical layer (default: 0.4) */
76
- lexical: number;
77
- /** Weight for symbolic layer (default: 0.2) */
78
- symbolic: number;
79
- }
80
- /**
81
- * Default weights for hybrid search.
82
- */
83
- export declare const DEFAULT_SCORER_WEIGHTS: HybridWeights;
84
- /**
85
- * Options for the HybridScorer.
86
- */
87
- export interface HybridScorerOptions {
88
- /** Weights for each layer */
89
- weights?: Partial<HybridWeights>;
90
- /** Minimum score to include in results (default: 0) */
91
- minScore?: number;
92
- /** Whether to normalize weights to sum to 1 (default: true) */
93
- normalizeWeights?: boolean;
94
- }
95
- /**
96
- * HybridScorer combines multiple search signals using min-max normalization.
97
- *
98
- * Features:
99
- * 1. Min-max normalization brings all scores to 0-1 range
100
- * 2. Configurable weights for each layer
101
- * 3. Handles missing layers gracefully (redistributes weights)
102
- * 4. Tracks which layers contributed to each result
103
- *
104
- * @example
105
- * ```typescript
106
- * const scorer = new HybridScorer({
107
- * weights: { semantic: 0.5, lexical: 0.3, symbolic: 0.2 }
108
- * });
109
- *
110
- * const results = scorer.combine(
111
- * semanticResults,
112
- * lexicalResults,
113
- * symbolicResults,
114
- * entityMap
115
- * );
116
- * ```
117
- */
118
- export declare class HybridScorer {
119
- private weights;
120
- private minScore;
121
- private normalizeWeights;
122
- constructor(options?: HybridScorerOptions);
123
- /**
124
- * Get current weights configuration.
125
- */
126
- getWeights(): HybridWeights;
127
- /**
128
- * Update weights configuration.
129
- */
130
- setWeights(weights: Partial<HybridWeights>): void;
131
- /**
132
- * Perform min-max normalization on scores.
133
- *
134
- * Formula: normalized = (x - min) / (max - min)
135
- *
136
- * @param scores - Map of entity name to raw score
137
- * @returns Map of entity name to normalized score (0-1)
138
- */
139
- minMaxNormalize(scores: Map<string, number>): Map<string, number>;
140
- /**
141
- * Combine results from all three search layers.
142
- *
143
- * @param semanticResults - Results from semantic search
144
- * @param lexicalResults - Results from lexical search
145
- * @param symbolicResults - Results from symbolic search
146
- * @param entityMap - Map of entity names to Entity objects
147
- * @returns Array of combined results sorted by score
148
- */
149
- combine(semanticResults: SemanticSearchResult[], lexicalResults: LexicalSearchResult[], symbolicResults: SymbolicSearchResult[], entityMap: Map<string, Entity>): ScoredResult[];
150
- /**
151
- * Get weights normalized to sum to 1, redistributing for missing layers.
152
- *
153
- * @param hasSemantic - Whether semantic results are available
154
- * @param hasLexical - Whether lexical results are available
155
- * @param hasSymbolic - Whether symbolic results are available
156
- * @returns Normalized weights
157
- */
158
- getNormalizedWeights(hasSemantic: boolean, hasLexical: boolean, hasSymbolic: boolean): HybridWeights;
159
- /**
160
- * Combine scores from maps directly (alternative interface).
161
- *
162
- * @param semanticScores - Map of entity name to semantic score
163
- * @param lexicalScores - Map of entity name to lexical score
164
- * @param symbolicScores - Map of entity name to symbolic score
165
- * @param entityMap - Map of entity names to Entity objects
166
- * @returns Array of combined results sorted by score
167
- */
168
- combineFromMaps(semanticScores: Map<string, number>, lexicalScores: Map<string, number>, symbolicScores: Map<string, number>, entityMap: Map<string, Entity>): ScoredResult[];
169
- /**
170
- * Calculate combined score for a single entity.
171
- *
172
- * Useful for scoring individual results without full normalization.
173
- *
174
- * @param semanticScore - Normalized semantic score (0-1)
175
- * @param lexicalScore - Normalized lexical score (0-1)
176
- * @param symbolicScore - Normalized symbolic score (0-1)
177
- * @returns Combined weighted score
178
- */
179
- calculateScore(semanticScore: number, lexicalScore: number, symbolicScore: number): number;
180
- }
181
- //# sourceMappingURL=HybridScorer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"HybridScorer.d.ts","sourceRoot":"","sources":["../../src/search/HybridScorer.ts"],"names":[],"mappings":"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"}
@@ -1,257 +0,0 @@
1
- /**
2
- * Hybrid Scorer
3
- *
4
- * Combines semantic, lexical, and symbolic search scores with
5
- * min-max normalization and configurable weights.
6
- *
7
- * Phase 12 Sprint 3: Search Algorithm Optimization
8
- *
9
- * @module search/HybridScorer
10
- */
11
- /**
12
- * Default weights for hybrid search.
13
- */
14
- export const DEFAULT_SCORER_WEIGHTS = {
15
- semantic: 0.4,
16
- lexical: 0.4,
17
- symbolic: 0.2,
18
- };
19
- /**
20
- * HybridScorer combines multiple search signals using min-max normalization.
21
- *
22
- * Features:
23
- * 1. Min-max normalization brings all scores to 0-1 range
24
- * 2. Configurable weights for each layer
25
- * 3. Handles missing layers gracefully (redistributes weights)
26
- * 4. Tracks which layers contributed to each result
27
- *
28
- * @example
29
- * ```typescript
30
- * const scorer = new HybridScorer({
31
- * weights: { semantic: 0.5, lexical: 0.3, symbolic: 0.2 }
32
- * });
33
- *
34
- * const results = scorer.combine(
35
- * semanticResults,
36
- * lexicalResults,
37
- * symbolicResults,
38
- * entityMap
39
- * );
40
- * ```
41
- */
42
- export class HybridScorer {
43
- weights;
44
- minScore;
45
- normalizeWeights;
46
- constructor(options = {}) {
47
- this.weights = {
48
- ...DEFAULT_SCORER_WEIGHTS,
49
- ...options.weights,
50
- };
51
- this.minScore = options.minScore ?? 0;
52
- this.normalizeWeights = options.normalizeWeights ?? true;
53
- }
54
- /**
55
- * Get current weights configuration.
56
- */
57
- getWeights() {
58
- return { ...this.weights };
59
- }
60
- /**
61
- * Update weights configuration.
62
- */
63
- setWeights(weights) {
64
- this.weights = { ...this.weights, ...weights };
65
- }
66
- /**
67
- * Perform min-max normalization on scores.
68
- *
69
- * Formula: normalized = (x - min) / (max - min)
70
- *
71
- * @param scores - Map of entity name to raw score
72
- * @returns Map of entity name to normalized score (0-1)
73
- */
74
- minMaxNormalize(scores) {
75
- if (scores.size === 0) {
76
- return new Map();
77
- }
78
- // Find min and max
79
- let min = Infinity;
80
- let max = -Infinity;
81
- for (const score of scores.values()) {
82
- if (score < min)
83
- min = score;
84
- if (score > max)
85
- max = score;
86
- }
87
- // Handle edge case where all scores are the same
88
- if (max === min) {
89
- const normalized = new Map();
90
- for (const name of scores.keys()) {
91
- // If all scores are zero, keep them zero; otherwise normalize to 1
92
- normalized.set(name, max === 0 ? 0 : 1);
93
- }
94
- return normalized;
95
- }
96
- // Normalize
97
- const range = max - min;
98
- const normalized = new Map();
99
- for (const [name, score] of scores) {
100
- normalized.set(name, (score - min) / range);
101
- }
102
- return normalized;
103
- }
104
- /**
105
- * Combine results from all three search layers.
106
- *
107
- * @param semanticResults - Results from semantic search
108
- * @param lexicalResults - Results from lexical search
109
- * @param symbolicResults - Results from symbolic search
110
- * @param entityMap - Map of entity names to Entity objects
111
- * @returns Array of combined results sorted by score
112
- */
113
- combine(semanticResults, lexicalResults, symbolicResults, entityMap) {
114
- // Build score maps
115
- const semanticScores = new Map();
116
- for (const result of semanticResults) {
117
- semanticScores.set(result.entityName, result.similarity);
118
- }
119
- const lexicalScores = new Map();
120
- for (const result of lexicalResults) {
121
- lexicalScores.set(result.entityName, result.score);
122
- }
123
- const symbolicScores = new Map();
124
- for (const result of symbolicResults) {
125
- symbolicScores.set(result.entityName, result.score);
126
- }
127
- // Normalize scores
128
- const normalizedSemantic = this.minMaxNormalize(semanticScores);
129
- const normalizedLexical = this.minMaxNormalize(lexicalScores);
130
- const normalizedSymbolic = this.minMaxNormalize(symbolicScores);
131
- // Calculate effective weights
132
- let effectiveWeights = { ...this.weights };
133
- if (this.normalizeWeights) {
134
- effectiveWeights = this.getNormalizedWeights(semanticResults.length > 0, lexicalResults.length > 0, symbolicResults.length > 0);
135
- }
136
- // Collect all unique entity names
137
- const allNames = new Set([
138
- ...normalizedSemantic.keys(),
139
- ...normalizedLexical.keys(),
140
- ...normalizedSymbolic.keys(),
141
- ]);
142
- // Calculate combined scores
143
- const results = [];
144
- for (const entityName of allNames) {
145
- const entity = entityMap.get(entityName);
146
- if (!entity)
147
- continue;
148
- const semanticScore = normalizedSemantic.get(entityName) ?? 0;
149
- const lexicalScore = normalizedLexical.get(entityName) ?? 0;
150
- const symbolicScore = normalizedSymbolic.get(entityName) ?? 0;
151
- // Calculate weighted combination
152
- const combined = semanticScore * effectiveWeights.semantic +
153
- lexicalScore * effectiveWeights.lexical +
154
- symbolicScore * effectiveWeights.symbolic;
155
- // Track matched layers
156
- const matchedLayers = [];
157
- const rawScores = {};
158
- if (semanticScores.has(entityName)) {
159
- matchedLayers.push('semantic');
160
- rawScores.semantic = semanticScores.get(entityName);
161
- }
162
- if (lexicalScores.has(entityName)) {
163
- matchedLayers.push('lexical');
164
- rawScores.lexical = lexicalScores.get(entityName);
165
- }
166
- if (symbolicScores.has(entityName)) {
167
- matchedLayers.push('symbolic');
168
- rawScores.symbolic = symbolicScores.get(entityName);
169
- }
170
- // Skip if below minimum score or no layers matched
171
- if (combined < this.minScore || matchedLayers.length === 0) {
172
- continue;
173
- }
174
- results.push({
175
- entityName,
176
- entity,
177
- scores: {
178
- semantic: semanticScore,
179
- lexical: lexicalScore,
180
- symbolic: symbolicScore,
181
- combined,
182
- },
183
- matchedLayers,
184
- rawScores,
185
- });
186
- }
187
- // Sort by combined score descending
188
- return results.sort((a, b) => b.scores.combined - a.scores.combined);
189
- }
190
- /**
191
- * Get weights normalized to sum to 1, redistributing for missing layers.
192
- *
193
- * @param hasSemantic - Whether semantic results are available
194
- * @param hasLexical - Whether lexical results are available
195
- * @param hasSymbolic - Whether symbolic results are available
196
- * @returns Normalized weights
197
- */
198
- getNormalizedWeights(hasSemantic, hasLexical, hasSymbolic) {
199
- let totalActiveWeight = 0;
200
- if (hasSemantic)
201
- totalActiveWeight += this.weights.semantic;
202
- if (hasLexical)
203
- totalActiveWeight += this.weights.lexical;
204
- if (hasSymbolic)
205
- totalActiveWeight += this.weights.symbolic;
206
- // If no layers are active, return zero weights
207
- if (totalActiveWeight === 0) {
208
- return { semantic: 0, lexical: 0, symbolic: 0 };
209
- }
210
- // Normalize active weights to sum to 1
211
- return {
212
- semantic: hasSemantic ? this.weights.semantic / totalActiveWeight : 0,
213
- lexical: hasLexical ? this.weights.lexical / totalActiveWeight : 0,
214
- symbolic: hasSymbolic ? this.weights.symbolic / totalActiveWeight : 0,
215
- };
216
- }
217
- /**
218
- * Combine scores from maps directly (alternative interface).
219
- *
220
- * @param semanticScores - Map of entity name to semantic score
221
- * @param lexicalScores - Map of entity name to lexical score
222
- * @param symbolicScores - Map of entity name to symbolic score
223
- * @param entityMap - Map of entity names to Entity objects
224
- * @returns Array of combined results sorted by score
225
- */
226
- combineFromMaps(semanticScores, lexicalScores, symbolicScores, entityMap) {
227
- // Convert maps to result arrays
228
- const semanticResults = [];
229
- for (const [entityName, similarity] of semanticScores) {
230
- semanticResults.push({ entityName, similarity });
231
- }
232
- const lexicalResults = [];
233
- for (const [entityName, score] of lexicalScores) {
234
- lexicalResults.push({ entityName, score });
235
- }
236
- const symbolicResults = [];
237
- for (const [entityName, score] of symbolicScores) {
238
- symbolicResults.push({ entityName, score });
239
- }
240
- return this.combine(semanticResults, lexicalResults, symbolicResults, entityMap);
241
- }
242
- /**
243
- * Calculate combined score for a single entity.
244
- *
245
- * Useful for scoring individual results without full normalization.
246
- *
247
- * @param semanticScore - Normalized semantic score (0-1)
248
- * @param lexicalScore - Normalized lexical score (0-1)
249
- * @param symbolicScore - Normalized symbolic score (0-1)
250
- * @returns Combined weighted score
251
- */
252
- calculateScore(semanticScore, lexicalScore, symbolicScore) {
253
- return (semanticScore * this.weights.semantic +
254
- lexicalScore * this.weights.lexical +
255
- symbolicScore * this.weights.symbolic);
256
- }
257
- }