@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.
- package/LICENSE +22 -22
- package/dist/core/EntityManager.d.ts +10 -15
- package/dist/core/EntityManager.d.ts.map +1 -1
- package/dist/core/EntityManager.js +21 -54
- package/dist/core/GraphStorage.d.ts +0 -51
- package/dist/core/GraphStorage.d.ts.map +1 -1
- package/dist/core/GraphStorage.js +2 -79
- package/dist/core/GraphTraversal.d.ts +2 -7
- package/dist/core/GraphTraversal.d.ts.map +1 -1
- package/dist/core/GraphTraversal.js +2 -19
- package/dist/core/ManagerContext.d.ts +0 -4
- package/dist/core/ManagerContext.d.ts.map +1 -1
- package/dist/core/ManagerContext.js +2 -12
- package/dist/core/RelationManager.d.ts.map +1 -1
- package/dist/core/RelationManager.js +4 -5
- package/dist/core/SQLiteStorage.d.ts.map +1 -1
- package/dist/core/SQLiteStorage.js +2 -3
- package/dist/core/TransactionManager.d.ts +2 -207
- package/dist/core/TransactionManager.d.ts.map +1 -1
- package/dist/core/TransactionManager.js +6 -482
- package/dist/core/index.d.ts +1 -2
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -3
- package/dist/features/ArchiveManager.d.ts +2 -14
- package/dist/features/ArchiveManager.d.ts.map +1 -1
- package/dist/features/ArchiveManager.js +3 -44
- package/dist/features/CompressionManager.d.ts +4 -14
- package/dist/features/CompressionManager.d.ts.map +1 -1
- package/dist/features/CompressionManager.js +9 -74
- package/dist/features/IOManager.d.ts +2 -6
- package/dist/features/IOManager.d.ts.map +1 -1
- package/dist/features/IOManager.js +10 -105
- package/dist/features/StreamingExporter.d.ts +4 -27
- package/dist/features/StreamingExporter.d.ts.map +1 -1
- package/dist/features/StreamingExporter.js +4 -65
- package/dist/features/index.d.ts +0 -2
- package/dist/features/index.d.ts.map +1 -1
- package/dist/features/index.js +0 -3
- package/dist/search/EmbeddingService.d.ts +9 -108
- package/dist/search/EmbeddingService.d.ts.map +1 -1
- package/dist/search/EmbeddingService.js +15 -187
- package/dist/search/FuzzySearch.js +1 -1
- package/dist/search/SavedSearchManager.d.ts.map +1 -1
- package/dist/search/SavedSearchManager.js +2 -3
- package/dist/search/SearchManager.d.ts +1 -42
- package/dist/search/SearchManager.d.ts.map +1 -1
- package/dist/search/SearchManager.js +0 -115
- package/dist/search/SemanticSearch.d.ts +1 -4
- package/dist/search/SemanticSearch.d.ts.map +1 -1
- package/dist/search/SemanticSearch.js +2 -12
- package/dist/search/TFIDFIndexManager.d.ts +0 -88
- package/dist/search/TFIDFIndexManager.d.ts.map +1 -1
- package/dist/search/TFIDFIndexManager.js +0 -217
- package/dist/search/index.d.ts +1 -18
- package/dist/search/index.d.ts.map +1 -1
- package/dist/search/index.js +1 -32
- package/dist/server/MCPServer.d.ts.map +1 -1
- package/dist/server/MCPServer.js +4 -1
- package/dist/server/responseCompressor.js +5 -5
- package/dist/server/toolDefinitions.d.ts.map +1 -1
- package/dist/server/toolDefinitions.js +5 -1
- package/dist/server/toolHandlers.d.ts +9 -5
- package/dist/server/toolHandlers.d.ts.map +1 -1
- package/dist/server/toolHandlers.js +23 -8
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/types.d.ts +2 -579
- package/dist/types/types.d.ts.map +1 -1
- package/dist/utils/compressedCache.d.ts +0 -29
- package/dist/utils/compressedCache.d.ts.map +1 -1
- package/dist/utils/compressedCache.js +0 -39
- package/dist/utils/entityUtils.d.ts +1 -59
- package/dist/utils/entityUtils.d.ts.map +1 -1
- package/dist/utils/entityUtils.js +3 -113
- package/dist/utils/errors.d.ts +0 -18
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +0 -24
- package/dist/utils/index.d.ts +2 -6
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +2 -14
- package/dist/utils/logger.d.ts +0 -7
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +2 -9
- package/dist/utils/parallelUtils.d.ts +1 -5
- package/dist/utils/parallelUtils.d.ts.map +1 -1
- package/dist/utils/parallelUtils.js +1 -23
- package/dist/utils/schemas.d.ts +16 -16
- package/dist/utils/schemas.d.ts.map +1 -1
- package/dist/utils/schemas.js +12 -12
- package/dist/utils/taskScheduler.d.ts +0 -4
- package/dist/utils/taskScheduler.d.ts.map +1 -1
- package/dist/utils/taskScheduler.js +1 -21
- package/dist/workers/WorkerPool.d.ts +81 -0
- package/dist/workers/WorkerPool.d.ts.map +1 -0
- package/dist/workers/WorkerPool.js +121 -0
- package/dist/workers/index.d.ts +1 -1
- package/dist/workers/index.d.ts.map +1 -1
- package/dist/workers/levenshteinWorker.js +1 -1
- package/package.json +1 -4
- package/dist/__tests__/file-path.test.js +0 -119
- package/dist/__tests__/knowledge-graph.test.js +0 -318
- package/dist/core/GraphEventEmitter.d.ts +0 -202
- package/dist/core/GraphEventEmitter.d.ts.map +0 -1
- package/dist/core/GraphEventEmitter.js +0 -346
- package/dist/features/KeywordExtractor.d.ts +0 -61
- package/dist/features/KeywordExtractor.d.ts.map +0 -1
- package/dist/features/KeywordExtractor.js +0 -126
- package/dist/features/ObservationNormalizer.d.ts +0 -90
- package/dist/features/ObservationNormalizer.d.ts.map +0 -1
- package/dist/features/ObservationNormalizer.js +0 -193
- package/dist/memory.jsonl +0 -1
- package/dist/search/BM25Search.d.ts +0 -148
- package/dist/search/BM25Search.d.ts.map +0 -1
- package/dist/search/BM25Search.js +0 -339
- package/dist/search/EarlyTerminationManager.d.ts +0 -140
- package/dist/search/EarlyTerminationManager.d.ts.map +0 -1
- package/dist/search/EarlyTerminationManager.js +0 -279
- package/dist/search/EmbeddingCache.d.ts +0 -175
- package/dist/search/EmbeddingCache.d.ts.map +0 -1
- package/dist/search/EmbeddingCache.js +0 -246
- package/dist/search/HybridScorer.d.ts +0 -181
- package/dist/search/HybridScorer.d.ts.map +0 -1
- package/dist/search/HybridScorer.js +0 -257
- package/dist/search/HybridSearchManager.d.ts +0 -80
- package/dist/search/HybridSearchManager.d.ts.map +0 -1
- package/dist/search/HybridSearchManager.js +0 -187
- package/dist/search/IncrementalIndexer.d.ts +0 -201
- package/dist/search/IncrementalIndexer.d.ts.map +0 -1
- package/dist/search/IncrementalIndexer.js +0 -342
- package/dist/search/OptimizedInvertedIndex.d.ts +0 -163
- package/dist/search/OptimizedInvertedIndex.d.ts.map +0 -1
- package/dist/search/OptimizedInvertedIndex.js +0 -358
- package/dist/search/ParallelSearchExecutor.d.ts +0 -172
- package/dist/search/ParallelSearchExecutor.d.ts.map +0 -1
- package/dist/search/ParallelSearchExecutor.js +0 -309
- package/dist/search/QuantizedVectorStore.d.ts +0 -171
- package/dist/search/QuantizedVectorStore.d.ts.map +0 -1
- package/dist/search/QuantizedVectorStore.js +0 -307
- package/dist/search/QueryAnalyzer.d.ts +0 -76
- package/dist/search/QueryAnalyzer.d.ts.map +0 -1
- package/dist/search/QueryAnalyzer.js +0 -227
- package/dist/search/QueryCostEstimator.d.ts +0 -244
- package/dist/search/QueryCostEstimator.d.ts.map +0 -1
- package/dist/search/QueryCostEstimator.js +0 -652
- package/dist/search/QueryPlanCache.d.ts +0 -220
- package/dist/search/QueryPlanCache.d.ts.map +0 -1
- package/dist/search/QueryPlanCache.js +0 -379
- package/dist/search/QueryPlanner.d.ts +0 -58
- package/dist/search/QueryPlanner.d.ts.map +0 -1
- package/dist/search/QueryPlanner.js +0 -137
- package/dist/search/ReflectionManager.d.ts +0 -120
- package/dist/search/ReflectionManager.d.ts.map +0 -1
- package/dist/search/ReflectionManager.js +0 -231
- package/dist/search/SymbolicSearch.d.ts +0 -61
- package/dist/search/SymbolicSearch.d.ts.map +0 -1
- package/dist/search/SymbolicSearch.js +0 -163
- package/dist/search/TFIDFEventSync.d.ts +0 -85
- package/dist/search/TFIDFEventSync.d.ts.map +0 -1
- package/dist/search/TFIDFEventSync.js +0 -133
- package/dist/utils/BatchProcessor.d.ts +0 -271
- package/dist/utils/BatchProcessor.d.ts.map +0 -1
- package/dist/utils/BatchProcessor.js +0 -376
- package/dist/utils/MemoryMonitor.d.ts +0 -176
- package/dist/utils/MemoryMonitor.d.ts.map +0 -1
- package/dist/utils/MemoryMonitor.js +0 -305
- package/dist/utils/WorkerPoolManager.d.ts +0 -233
- package/dist/utils/WorkerPoolManager.d.ts.map +0 -1
- package/dist/utils/WorkerPoolManager.js +0 -420
- package/dist/utils/operationUtils.d.ts +0 -124
- package/dist/utils/operationUtils.d.ts.map +0 -1
- package/dist/utils/operationUtils.js +0 -175
- 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
|
-
}
|