@cmdoss/memwal-sdk 0.6.2 → 0.8.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 (247) hide show
  1. package/ARCHITECTURE.md +547 -547
  2. package/BENCHMARKS.md +238 -238
  3. package/README.md +310 -181
  4. package/dist/ai-sdk/tools.d.ts +2 -2
  5. package/dist/ai-sdk/tools.js +2 -2
  6. package/dist/client/ClientMemoryManager.js +2 -2
  7. package/dist/client/ClientMemoryManager.js.map +1 -1
  8. package/dist/client/PersonalDataWallet.d.ts.map +1 -1
  9. package/dist/client/SimplePDWClient.d.ts +29 -1
  10. package/dist/client/SimplePDWClient.d.ts.map +1 -1
  11. package/dist/client/SimplePDWClient.js +45 -13
  12. package/dist/client/SimplePDWClient.js.map +1 -1
  13. package/dist/client/namespaces/EmbeddingsNamespace.d.ts +1 -1
  14. package/dist/client/namespaces/EmbeddingsNamespace.js +1 -1
  15. package/dist/client/namespaces/MemoryNamespace.d.ts +31 -0
  16. package/dist/client/namespaces/MemoryNamespace.d.ts.map +1 -1
  17. package/dist/client/namespaces/MemoryNamespace.js +272 -39
  18. package/dist/client/namespaces/MemoryNamespace.js.map +1 -1
  19. package/dist/client/namespaces/consolidated/AINamespace.d.ts +2 -2
  20. package/dist/client/namespaces/consolidated/AINamespace.js +2 -2
  21. package/dist/client/namespaces/consolidated/BlockchainNamespace.d.ts +12 -2
  22. package/dist/client/namespaces/consolidated/BlockchainNamespace.d.ts.map +1 -1
  23. package/dist/client/namespaces/consolidated/BlockchainNamespace.js +62 -4
  24. package/dist/client/namespaces/consolidated/BlockchainNamespace.js.map +1 -1
  25. package/dist/client/namespaces/consolidated/StorageNamespace.d.ts +67 -2
  26. package/dist/client/namespaces/consolidated/StorageNamespace.d.ts.map +1 -1
  27. package/dist/client/namespaces/consolidated/StorageNamespace.js +549 -16
  28. package/dist/client/namespaces/consolidated/StorageNamespace.js.map +1 -1
  29. package/dist/config/ConfigurationHelper.js +61 -61
  30. package/dist/config/defaults.js +2 -2
  31. package/dist/config/defaults.js.map +1 -1
  32. package/dist/graph/GraphService.js +21 -21
  33. package/dist/graph/GraphService.js.map +1 -1
  34. package/dist/index.d.ts +3 -1
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +3 -1
  37. package/dist/index.js.map +1 -1
  38. package/dist/infrastructure/seal/EncryptionService.d.ts +9 -5
  39. package/dist/infrastructure/seal/EncryptionService.d.ts.map +1 -1
  40. package/dist/infrastructure/seal/EncryptionService.js +37 -15
  41. package/dist/infrastructure/seal/EncryptionService.js.map +1 -1
  42. package/dist/infrastructure/seal/SealService.d.ts +13 -5
  43. package/dist/infrastructure/seal/SealService.d.ts.map +1 -1
  44. package/dist/infrastructure/seal/SealService.js +36 -34
  45. package/dist/infrastructure/seal/SealService.js.map +1 -1
  46. package/dist/langchain/createPDWRAG.js +30 -30
  47. package/dist/retrieval/MemoryDecryptionPipeline.d.ts.map +1 -1
  48. package/dist/retrieval/MemoryDecryptionPipeline.js +2 -1
  49. package/dist/retrieval/MemoryDecryptionPipeline.js.map +1 -1
  50. package/dist/retrieval/MemoryRetrievalService.d.ts +31 -0
  51. package/dist/retrieval/MemoryRetrievalService.d.ts.map +1 -1
  52. package/dist/retrieval/MemoryRetrievalService.js +44 -4
  53. package/dist/retrieval/MemoryRetrievalService.js.map +1 -1
  54. package/dist/services/CapabilityService.d.ts.map +1 -1
  55. package/dist/services/CapabilityService.js +30 -14
  56. package/dist/services/CapabilityService.js.map +1 -1
  57. package/dist/services/CrossContextPermissionService.d.ts.map +1 -1
  58. package/dist/services/CrossContextPermissionService.js +9 -7
  59. package/dist/services/CrossContextPermissionService.js.map +1 -1
  60. package/dist/services/EmbeddingService.d.ts +28 -1
  61. package/dist/services/EmbeddingService.d.ts.map +1 -1
  62. package/dist/services/EmbeddingService.js +54 -0
  63. package/dist/services/EmbeddingService.js.map +1 -1
  64. package/dist/services/EncryptionService.d.ts.map +1 -1
  65. package/dist/services/EncryptionService.js +6 -5
  66. package/dist/services/EncryptionService.js.map +1 -1
  67. package/dist/services/GeminiAIService.js +309 -309
  68. package/dist/services/IndexManager.d.ts +5 -1
  69. package/dist/services/IndexManager.d.ts.map +1 -1
  70. package/dist/services/IndexManager.js +17 -40
  71. package/dist/services/IndexManager.js.map +1 -1
  72. package/dist/services/QueryService.js +1 -1
  73. package/dist/services/QueryService.js.map +1 -1
  74. package/dist/services/StorageService.d.ts +11 -0
  75. package/dist/services/StorageService.d.ts.map +1 -1
  76. package/dist/services/StorageService.js +73 -10
  77. package/dist/services/StorageService.js.map +1 -1
  78. package/dist/services/TransactionService.d.ts +20 -0
  79. package/dist/services/TransactionService.d.ts.map +1 -1
  80. package/dist/services/TransactionService.js +43 -0
  81. package/dist/services/TransactionService.js.map +1 -1
  82. package/dist/services/ViewService.js +2 -2
  83. package/dist/services/ViewService.js.map +1 -1
  84. package/dist/services/storage/QuiltBatchManager.d.ts +101 -1
  85. package/dist/services/storage/QuiltBatchManager.d.ts.map +1 -1
  86. package/dist/services/storage/QuiltBatchManager.js +410 -20
  87. package/dist/services/storage/QuiltBatchManager.js.map +1 -1
  88. package/dist/services/storage/index.d.ts +1 -1
  89. package/dist/services/storage/index.d.ts.map +1 -1
  90. package/dist/services/storage/index.js.map +1 -1
  91. package/dist/utils/LRUCache.d.ts +106 -0
  92. package/dist/utils/LRUCache.d.ts.map +1 -0
  93. package/dist/utils/LRUCache.js +281 -0
  94. package/dist/utils/LRUCache.js.map +1 -0
  95. package/dist/utils/index.d.ts +1 -0
  96. package/dist/utils/index.d.ts.map +1 -1
  97. package/dist/utils/index.js +2 -0
  98. package/dist/utils/index.js.map +1 -1
  99. package/dist/utils/memoryIndexOnChain.d.ts +212 -0
  100. package/dist/utils/memoryIndexOnChain.d.ts.map +1 -0
  101. package/dist/utils/memoryIndexOnChain.js +312 -0
  102. package/dist/utils/memoryIndexOnChain.js.map +1 -0
  103. package/dist/utils/rebuildIndexNode.d.ts +29 -0
  104. package/dist/utils/rebuildIndexNode.d.ts.map +1 -1
  105. package/dist/utils/rebuildIndexNode.js +366 -98
  106. package/dist/utils/rebuildIndexNode.js.map +1 -1
  107. package/dist/vector/HnswWasmService.d.ts +20 -5
  108. package/dist/vector/HnswWasmService.d.ts.map +1 -1
  109. package/dist/vector/HnswWasmService.js +73 -40
  110. package/dist/vector/HnswWasmService.js.map +1 -1
  111. package/dist/vector/IHnswService.d.ts +10 -1
  112. package/dist/vector/IHnswService.d.ts.map +1 -1
  113. package/dist/vector/IHnswService.js.map +1 -1
  114. package/dist/vector/NodeHnswService.d.ts +16 -0
  115. package/dist/vector/NodeHnswService.d.ts.map +1 -1
  116. package/dist/vector/NodeHnswService.js +84 -5
  117. package/dist/vector/NodeHnswService.js.map +1 -1
  118. package/dist/vector/createHnswService.d.ts +1 -1
  119. package/dist/vector/createHnswService.js +1 -1
  120. package/dist/vector/index.d.ts +1 -1
  121. package/dist/vector/index.js +1 -1
  122. package/package.json +157 -157
  123. package/src/access/PermissionService.ts +635 -635
  124. package/src/aggregation/AggregationService.ts +389 -389
  125. package/src/ai-sdk/PDWVectorStore.ts +715 -715
  126. package/src/ai-sdk/index.ts +65 -65
  127. package/src/ai-sdk/tools.ts +460 -460
  128. package/src/ai-sdk/types.ts +404 -404
  129. package/src/batch/BatchManager.ts +597 -597
  130. package/src/batch/BatchingService.ts +429 -429
  131. package/src/batch/MemoryProcessingCache.ts +492 -492
  132. package/src/batch/index.ts +30 -30
  133. package/src/browser.ts +200 -200
  134. package/src/client/ClientMemoryManager.ts +987 -987
  135. package/src/client/PersonalDataWallet.ts +345 -345
  136. package/src/client/SimplePDWClient.ts +1289 -1222
  137. package/src/client/factory.ts +154 -154
  138. package/src/client/namespaces/AnalyticsNamespace.ts +377 -377
  139. package/src/client/namespaces/BatchNamespace.ts +356 -356
  140. package/src/client/namespaces/CacheNamespace.ts +123 -123
  141. package/src/client/namespaces/CapabilityNamespace.ts +217 -217
  142. package/src/client/namespaces/ClassifyNamespace.ts +169 -169
  143. package/src/client/namespaces/ContextNamespace.ts +297 -297
  144. package/src/client/namespaces/EmbeddingsNamespace.ts +99 -99
  145. package/src/client/namespaces/EncryptionNamespace.ts +221 -221
  146. package/src/client/namespaces/GraphNamespace.ts +468 -468
  147. package/src/client/namespaces/IndexNamespace.ts +361 -361
  148. package/src/client/namespaces/MemoryNamespace.ts +1422 -1135
  149. package/src/client/namespaces/PermissionsNamespace.ts +254 -254
  150. package/src/client/namespaces/PipelineNamespace.ts +220 -220
  151. package/src/client/namespaces/SearchNamespace.ts +1049 -1049
  152. package/src/client/namespaces/StorageNamespace.ts +458 -458
  153. package/src/client/namespaces/TxNamespace.ts +260 -260
  154. package/src/client/namespaces/WalletNamespace.ts +243 -243
  155. package/src/client/namespaces/consolidated/AINamespace.ts +449 -449
  156. package/src/client/namespaces/consolidated/BlockchainNamespace.ts +607 -546
  157. package/src/client/namespaces/consolidated/SecurityNamespace.ts +648 -648
  158. package/src/client/namespaces/consolidated/StorageNamespace.ts +1141 -497
  159. package/src/client/namespaces/consolidated/index.ts +39 -39
  160. package/src/client/signers/KeypairSigner.ts +108 -108
  161. package/src/client/signers/UnifiedSigner.ts +110 -110
  162. package/src/client/signers/WalletAdapterSigner.ts +159 -159
  163. package/src/client/signers/index.ts +26 -26
  164. package/src/config/ConfigurationHelper.ts +412 -412
  165. package/src/config/defaults.ts +51 -51
  166. package/src/config/index.ts +8 -8
  167. package/src/config/validation.ts +70 -70
  168. package/src/core/index.ts +14 -14
  169. package/src/core/interfaces/IService.ts +307 -307
  170. package/src/core/interfaces/index.ts +8 -8
  171. package/src/core/types/capability.ts +297 -297
  172. package/src/core/types/index.ts +870 -870
  173. package/src/core/types/wallet.ts +270 -270
  174. package/src/core/types.ts +9 -9
  175. package/src/core/wallet.ts +222 -222
  176. package/src/embedding/index.ts +19 -19
  177. package/src/embedding/types.ts +357 -357
  178. package/src/errors/index.ts +602 -602
  179. package/src/errors/recovery.ts +461 -461
  180. package/src/errors/validation.ts +567 -567
  181. package/src/generated/pdw/capability.ts +319 -319
  182. package/src/graph/GraphService.ts +887 -887
  183. package/src/graph/KnowledgeGraphManager.ts +728 -728
  184. package/src/graph/index.ts +25 -25
  185. package/src/index.ts +498 -474
  186. package/src/infrastructure/index.ts +22 -22
  187. package/src/infrastructure/seal/EncryptionService.ts +628 -603
  188. package/src/infrastructure/seal/SealService.ts +613 -615
  189. package/src/infrastructure/seal/index.ts +9 -9
  190. package/src/infrastructure/sui/BlockchainManager.ts +627 -627
  191. package/src/infrastructure/sui/SuiService.ts +888 -888
  192. package/src/infrastructure/sui/index.ts +9 -9
  193. package/src/infrastructure/walrus/StorageManager.ts +604 -604
  194. package/src/infrastructure/walrus/WalrusStorageService.ts +612 -612
  195. package/src/infrastructure/walrus/index.ts +9 -9
  196. package/src/langchain/PDWEmbeddings.ts +145 -145
  197. package/src/langchain/PDWVectorStore.ts +456 -456
  198. package/src/langchain/createPDWRAG.ts +303 -303
  199. package/src/langchain/index.ts +47 -47
  200. package/src/permissions/ConsentRepository.browser.ts +249 -249
  201. package/src/permissions/ConsentRepository.ts +364 -364
  202. package/src/pipeline/MemoryPipeline.ts +862 -862
  203. package/src/pipeline/PipelineManager.ts +683 -683
  204. package/src/pipeline/index.ts +26 -26
  205. package/src/retrieval/AdvancedSearchService.ts +629 -629
  206. package/src/retrieval/MemoryAnalyticsService.ts +711 -711
  207. package/src/retrieval/MemoryDecryptionPipeline.ts +825 -824
  208. package/src/retrieval/MemoryRetrievalService.ts +904 -830
  209. package/src/retrieval/index.ts +42 -42
  210. package/src/services/BatchService.ts +352 -352
  211. package/src/services/CapabilityService.ts +464 -448
  212. package/src/services/ClassifierService.ts +465 -465
  213. package/src/services/CrossContextPermissionService.ts +486 -484
  214. package/src/services/EmbeddingService.ts +771 -706
  215. package/src/services/EncryptionService.ts +712 -711
  216. package/src/services/GeminiAIService.ts +753 -753
  217. package/src/services/IndexManager.ts +977 -1004
  218. package/src/services/MemoryIndexService.ts +1003 -1003
  219. package/src/services/MemoryService.ts +369 -369
  220. package/src/services/QueryService.ts +890 -890
  221. package/src/services/StorageService.ts +1182 -1111
  222. package/src/services/TransactionService.ts +838 -790
  223. package/src/services/VectorService.ts +462 -462
  224. package/src/services/ViewService.ts +484 -484
  225. package/src/services/index.ts +25 -25
  226. package/src/services/storage/BlobAttributesManager.ts +333 -333
  227. package/src/services/storage/KnowledgeGraphManager.ts +425 -425
  228. package/src/services/storage/MemorySearchManager.ts +387 -387
  229. package/src/services/storage/QuiltBatchManager.ts +1130 -660
  230. package/src/services/storage/WalrusMetadataManager.ts +268 -268
  231. package/src/services/storage/WalrusStorageManager.ts +287 -287
  232. package/src/services/storage/index.ts +57 -52
  233. package/src/types/index.ts +13 -13
  234. package/src/utils/LRUCache.ts +378 -0
  235. package/src/utils/index.ts +76 -68
  236. package/src/utils/memoryIndexOnChain.ts +507 -0
  237. package/src/utils/rebuildIndex.ts +290 -290
  238. package/src/utils/rebuildIndexNode.ts +771 -424
  239. package/src/vector/BrowserHnswIndexService.ts +758 -758
  240. package/src/vector/HnswWasmService.ts +731 -679
  241. package/src/vector/IHnswService.ts +233 -224
  242. package/src/vector/NodeHnswService.ts +833 -735
  243. package/src/vector/VectorManager.ts +478 -478
  244. package/src/vector/createHnswService.ts +135 -135
  245. package/src/vector/index.ts +56 -56
  246. package/src/wallet/ContextWalletService.ts +656 -656
  247. package/src/wallet/MainWalletService.ts +317 -317
@@ -1,831 +1,905 @@
1
- /**
2
- * MemoryRetrievalService - Unified Memory Retrieval & Search
3
- *
4
- * Consolidates all memory retrieval operations into a single, powerful service
5
- * with advanced caching, decryption, analytics, and multi-dimensional search.
6
- *
7
- * Features:
8
- * - 🔍 Vector similarity search with HNSW indexing
9
- * - 📊 Semantic search with AI understanding
10
- * - 🕒 Time-based and metadata filtering
11
- * - 🔐 Automatic SEAL decryption pipeline
12
- * - 📈 Memory analytics and relationship discovery
13
- * - ⚡ Multi-tier caching for performance
14
- * - 🔄 Real-time memory streaming
15
- * - 📤 Export and backup capabilities
16
- */
17
-
18
- import { EmbeddingService } from '../services/EmbeddingService';
19
- import { VectorManager } from '../vector/VectorManager';
20
- import { KnowledgeGraphManager } from '../graph/KnowledgeGraphManager';
21
- import { StorageManager } from '../infrastructure/walrus/StorageManager';
22
- import { BlockchainManager } from '../infrastructure/sui/BlockchainManager';
23
- import { EncryptionService } from '../services/EncryptionService';
24
- import { BatchManager } from '../batch/BatchManager';
25
- import { MemoryDecryptionPipeline, DecryptionConfig } from './MemoryDecryptionPipeline';
26
-
27
- // Enhanced types for unified retrieval
28
- export interface UnifiedMemoryQuery {
29
- // Core search parameters
30
- query?: string;
31
- userId: string;
32
-
33
- // Search types
34
- searchType?: 'vector' | 'semantic' | 'keyword' | 'hybrid' | 'graph' | 'temporal';
35
-
36
- // Filtering options
37
- categories?: string[];
38
- dateRange?: {
39
- start?: Date;
40
- end?: Date;
41
- };
42
- importanceRange?: {
43
- min?: number;
44
- max?: number;
45
- };
46
- tags?: string[];
47
- contentTypes?: string[];
48
-
49
- // Vector search parameters
50
- similarity?: {
51
- threshold?: number;
52
- k?: number;
53
- efSearch?: number;
54
- };
55
-
56
- // Graph search parameters
57
- graphTraversal?: {
58
- maxDepth?: number;
59
- includeEntities?: string[];
60
- excludeRelations?: string[];
61
- };
62
-
63
- // Result options
64
- includeContent?: boolean;
65
- includeMetadata?: boolean;
66
- includeEmbeddings?: boolean;
67
- includeAnalytics?: boolean;
68
-
69
- // Performance options
70
- useCache?: boolean;
71
- timeout?: number;
72
- batchSize?: number;
73
- }
74
-
75
- export interface UnifiedMemoryResult {
76
- id: string;
77
- content?: string;
78
- category: string;
79
- created: Date;
80
- updated?: Date;
81
-
82
- // Scoring and relevance
83
- similarity?: number;
84
- relevanceScore: number;
85
- searchRelevance: {
86
- vectorSimilarity?: number;
87
- semanticMatch?: number;
88
- keywordMatch?: number;
89
- graphRelevance?: number;
90
- temporalRelevance?: number;
91
- };
92
-
93
- // Rich metadata
94
- metadata: {
95
- owner: string;
96
- size: number;
97
- importance: number;
98
- tags: string[];
99
- contentType: string;
100
- isEncrypted: boolean;
101
- accessCount?: number;
102
- lastAccessed?: Date;
103
- };
104
-
105
- // Storage information
106
- storage: {
107
- blobId: string;
108
- walrusHash?: string;
109
- blockchainId?: string;
110
- cacheStatus: 'cached' | 'retrieved' | 'not-cached';
111
- };
112
-
113
- // Relationships and context
114
- relationships?: {
115
- relatedMemories: string[];
116
- knowledgeGraphNodes: string[];
117
- semanticClusters: string[];
118
- };
119
-
120
- // Analytics
121
- analytics?: {
122
- viewCount: number;
123
- shareCount: number;
124
- editCount: number;
125
- sentimentScore?: number;
126
- topicDistribution?: Record<string, number>;
127
- };
128
- }
129
-
130
- export interface RetrievalStats {
131
- totalResults: number;
132
- processingTime: number;
133
- cacheHitRate: number;
134
- searchBreakdown: {
135
- vectorSearchTime: number;
136
- semanticAnalysisTime: number;
137
- decryptionTime: number;
138
- graphTraversalTime: number;
139
- };
140
- dataSourcesUsed: string[];
141
- qualityMetrics: {
142
- averageRelevance: number;
143
- diversityScore: number;
144
- freshnessScore: number;
145
- };
146
- }
147
-
148
- export interface RetrievalContext {
149
- query: UnifiedMemoryQuery;
150
- results: UnifiedMemoryResult[];
151
- stats: RetrievalStats;
152
- suggestions: {
153
- relatedQueries: string[];
154
- filterSuggestions: string[];
155
- explorationPaths: string[];
156
- };
157
- timeline?: {
158
- events: Array<{
159
- date: Date;
160
- type: 'created' | 'modified' | 'accessed' | 'shared';
161
- memoryId: string;
162
- description: string;
163
- }>;
164
- };
165
- }
166
-
167
- /**
168
- * Unified Memory Retrieval Service
169
- */
170
- export class MemoryRetrievalService {
171
- private embeddingService: EmbeddingService;
172
- private vectorManager: VectorManager;
173
- private graphManager: KnowledgeGraphManager;
174
- private storageManager: StorageManager;
175
- private blockchainManager: BlockchainManager;
176
- private encryptionService: EncryptionService | null;
177
- private batchManager: BatchManager;
178
- private decryptionPipeline: MemoryDecryptionPipeline | null;
179
-
180
- // Multi-tier caching system
181
- private queryCache = new Map<string, { result: RetrievalContext; timestamp: number }>();
182
- private contentCache = new Map<string, { content: string; metadata: any; timestamp: number }>();
183
- private analyticsCache = new Map<string, { analytics: any; timestamp: number }>();
184
-
185
- // Cache TTL settings
186
- private readonly QUERY_CACHE_TTL = 5 * 60 * 1000; // 5 minutes
187
- private readonly CONTENT_CACHE_TTL = 30 * 60 * 1000; // 30 minutes
188
- private readonly ANALYTICS_CACHE_TTL = 60 * 60 * 1000; // 1 hour
189
-
190
- constructor(config?: {
191
- embeddingService?: EmbeddingService;
192
- vectorManager?: VectorManager;
193
- graphManager?: KnowledgeGraphManager;
194
- storageManager?: StorageManager;
195
- blockchainManager?: BlockchainManager;
196
- encryptionService?: EncryptionService;
197
- batchManager?: BatchManager;
198
- decryptionConfig?: DecryptionConfig;
199
- }) {
200
- // Initialize services (can be injected or created with default configs)
201
- this.embeddingService = config?.embeddingService ?? new EmbeddingService();
202
- this.storageManager = config?.storageManager ?? new StorageManager();
203
- this.vectorManager = config?.vectorManager ?? new VectorManager({
204
- embedding: { apiKey: '' },
205
- index: { dimension: 3072 },
206
- batch: { maxBatchSize: 10 }
207
- });
208
- this.graphManager = config?.graphManager ?? new KnowledgeGraphManager();
209
- this.blockchainManager = config?.blockchainManager ?? new BlockchainManager();
210
- this.encryptionService = config?.encryptionService ?? null;
211
- this.batchManager = config?.batchManager ?? new BatchManager();
212
-
213
- // Initialize decryption pipeline only if encryption service is provided
214
- this.decryptionPipeline = this.encryptionService
215
- ? new MemoryDecryptionPipeline(
216
- this.encryptionService,
217
- this.storageManager,
218
- config?.decryptionConfig
219
- )
220
- : null;
221
- }
222
-
223
- // ==================== UNIFIED SEARCH ====================
224
-
225
- /**
226
- * Main unified search method - handles all types of memory retrieval
227
- */
228
- async searchMemories(query: UnifiedMemoryQuery): Promise<RetrievalContext> {
229
- const startTime = Date.now();
230
-
231
- // Check cache first
232
- const cacheKey = this.generateCacheKey(query);
233
- if (query.useCache !== false) {
234
- const cached = this.getCachedQuery(cacheKey);
235
- if (cached) {
236
- return cached;
237
- }
238
- }
239
-
240
- try {
241
- // Execute search based on type
242
- let results: UnifiedMemoryResult[];
243
- let searchStats: Partial<RetrievalStats['searchBreakdown']> = {};
244
-
245
- switch (query.searchType || 'hybrid') {
246
- case 'vector':
247
- results = await this.performVectorSearch(query, searchStats);
248
- break;
249
- case 'semantic':
250
- results = await this.performSemanticSearch(query, searchStats);
251
- break;
252
- case 'keyword':
253
- results = await this.performKeywordSearch(query, searchStats);
254
- break;
255
- case 'graph':
256
- results = await this.performGraphSearch(query, searchStats);
257
- break;
258
- case 'temporal':
259
- results = await this.performTemporalSearch(query, searchStats);
260
- break;
261
- case 'hybrid':
262
- default:
263
- results = await this.performHybridSearch(query, searchStats);
264
- break;
265
- }
266
-
267
- // Apply filters and post-processing
268
- results = await this.applyFilters(results, query);
269
- results = await this.enrichResults(results, query);
270
- results = this.rankAndSortResults(results, query);
271
-
272
- // Auto-decrypt encrypted memories if decryption is available
273
- if (this.decryptionPipeline?.isReady()) {
274
- try {
275
- results = await this.decryptionPipeline.decryptMemoryResults(results, query.userId);
276
- } catch (error) {
277
- console.warn('⚠️ Auto-decryption failed, returning encrypted results:', error);
278
- }
279
- }
280
-
281
- // Generate stats and suggestions
282
- const stats = this.generateStats(results, searchStats, startTime);
283
- const suggestions = await this.generateSuggestions(query, results);
284
- const timeline = await this.generateTimeline(results, query);
285
-
286
- const context: RetrievalContext = {
287
- query,
288
- results,
289
- stats,
290
- suggestions,
291
- timeline
292
- };
293
-
294
- // Cache the results
295
- if (query.useCache !== false) {
296
- this.cacheQuery(cacheKey, context);
297
- }
298
-
299
- return context;
300
-
301
- } catch (error) {
302
- throw new Error(`Memory retrieval failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
303
- }
304
- }
305
-
306
- // ==================== SPECIFIC SEARCH IMPLEMENTATIONS ====================
307
-
308
- /**
309
- * Vector similarity search using HNSW index
310
- */
311
- private async performVectorSearch(
312
- query: UnifiedMemoryQuery,
313
- stats: Partial<RetrievalStats['searchBreakdown']>
314
- ): Promise<UnifiedMemoryResult[]> {
315
- const vectorStart = Date.now();
316
-
317
- if (!query.query) {
318
- throw new Error('Vector search requires a query string');
319
- }
320
-
321
- // Generate query embedding
322
- const embedding = await this.embeddingService.embedText({
323
- text: query.query,
324
- taskType: 'RETRIEVAL_QUERY'
325
- });
326
-
327
- // Search vector index
328
- const vectorResults = await this.vectorManager.searchSimilarTexts(
329
- 'default-user',
330
- query.query,
331
- {
332
- k: query.similarity?.k || 10,
333
- efSearch: query.similarity?.efSearch || 100,
334
- threshold: query.similarity?.threshold || 0.7
335
- }
336
- );
337
-
338
- stats.vectorSearchTime = Date.now() - vectorStart;
339
-
340
- // Convert to unified format
341
- return await this.convertVectorResults(vectorResults.results, query);
342
- }
343
-
344
- /**
345
- * Semantic search with AI understanding
346
- */
347
- private async performSemanticSearch(
348
- query: UnifiedMemoryQuery,
349
- stats: Partial<RetrievalStats['searchBreakdown']>
350
- ): Promise<UnifiedMemoryResult[]> {
351
- const semanticStart = Date.now();
352
-
353
- // First, get vector results as base
354
- const vectorResults = await this.performVectorSearch(query, stats);
355
-
356
- // Apply semantic analysis for better understanding
357
- if (query.query) {
358
- // Analyze query semantics
359
- const semanticAnalysis = await this.analyzeQuerySemantics(query.query);
360
-
361
- // Re-rank results based on semantic understanding
362
- for (const result of vectorResults) {
363
- result.searchRelevance.semanticMatch = await this.calculateSemanticMatch(
364
- result,
365
- semanticAnalysis
366
- );
367
- result.relevanceScore = this.combineRelevanceScores(result.searchRelevance);
368
- }
369
- }
370
-
371
- stats.semanticAnalysisTime = (stats.semanticAnalysisTime || 0) + (Date.now() - semanticStart);
372
-
373
- return vectorResults;
374
- }
375
-
376
- /**
377
- * Knowledge graph traversal search
378
- */
379
- private async performGraphSearch(
380
- query: UnifiedMemoryQuery,
381
- stats: Partial<RetrievalStats['searchBreakdown']>
382
- ): Promise<UnifiedMemoryResult[]> {
383
- const graphStart = Date.now();
384
-
385
- const results: UnifiedMemoryResult[] = [];
386
-
387
- if (query.query) {
388
- // Search graph for related entities and memories
389
- const graphResults = await this.graphManager.searchGraph(
390
- query.query,
391
- {
392
- maxResults: query.similarity?.k || 20
393
- }
394
- );
395
-
396
- // Find memories related to discovered entities
397
- for (const entity of graphResults.entities) {
398
- const relatedMemories = await this.graphManager.findMemoriesRelatedToEntity(
399
- entity.label || entity.id,
400
- query.userId
401
- );
402
-
403
- const memoryIds = Array.isArray(relatedMemories) ? relatedMemories :
404
- (relatedMemories?.memories || []);
405
- for (const memoryId of memoryIds) {
406
- const memory = await this.retrieveMemoryById(memoryId, query);
407
- if (memory) {
408
- memory.searchRelevance.graphRelevance = entity.confidence || 0.8;
409
- results.push(memory);
410
- }
411
- }
412
- }
413
- }
414
-
415
- stats.graphTraversalTime = Date.now() - graphStart;
416
- return results;
417
- }
418
-
419
- /**
420
- * Temporal/time-based search
421
- */
422
- private async performTemporalSearch(
423
- query: UnifiedMemoryQuery,
424
- stats: Partial<RetrievalStats['searchBreakdown']>
425
- ): Promise<UnifiedMemoryResult[]> {
426
- // Get all user memories
427
- const allMemories = await this.getAllUserMemories(query.userId);
428
-
429
- // Filter by date range
430
- let filteredMemories = allMemories;
431
-
432
- if (query.dateRange?.start) {
433
- filteredMemories = filteredMemories.filter(
434
- m => m.created >= query.dateRange!.start!
435
- );
436
- }
437
-
438
- if (query.dateRange?.end) {
439
- filteredMemories = filteredMemories.filter(
440
- m => m.created <= query.dateRange!.end!
441
- );
442
- }
443
-
444
- // Calculate temporal relevance
445
- filteredMemories.forEach(memory => {
446
- memory.searchRelevance.temporalRelevance = this.calculateTemporalRelevance(
447
- memory.created,
448
- query.dateRange
449
- );
450
- });
451
-
452
- return filteredMemories;
453
- }
454
-
455
- /**
456
- * Keyword-based search
457
- */
458
- private async performKeywordSearch(
459
- query: UnifiedMemoryQuery,
460
- stats: Partial<RetrievalStats['searchBreakdown']>
461
- ): Promise<UnifiedMemoryResult[]> {
462
- if (!query.query) {
463
- return [];
464
- }
465
-
466
- const keywords = query.query.toLowerCase().split(/\s+/);
467
- const allMemories = await this.getAllUserMemories(query.userId);
468
-
469
- // Score memories based on keyword matches
470
- const results = allMemories.filter(memory => {
471
- const content = (memory.content || '').toLowerCase();
472
- const matchCount = keywords.filter(keyword =>
473
- content.includes(keyword)
474
- ).length;
475
-
476
- if (matchCount > 0) {
477
- memory.searchRelevance.keywordMatch = matchCount / keywords.length;
478
- return true;
479
- }
480
-
481
- return false;
482
- });
483
-
484
- return results;
485
- }
486
-
487
- /**
488
- * Hybrid search combining multiple methods
489
- */
490
- private async performHybridSearch(
491
- query: UnifiedMemoryQuery,
492
- stats: Partial<RetrievalStats['searchBreakdown']>
493
- ): Promise<UnifiedMemoryResult[]> {
494
- const allResults: UnifiedMemoryResult[] = [];
495
- const resultMap = new Map<string, UnifiedMemoryResult>();
496
-
497
- // Perform multiple search types
498
- if (query.query) {
499
- // Vector search
500
- const vectorResults = await this.performVectorSearch(query, stats);
501
- vectorResults.forEach(result => {
502
- result.searchRelevance.vectorSimilarity = result.similarity || 0;
503
- resultMap.set(result.id, result);
504
- });
505
-
506
- // Semantic enhancement
507
- const semanticResults = await this.performSemanticSearch(query, stats);
508
- semanticResults.forEach(result => {
509
- const existing = resultMap.get(result.id);
510
- if (existing) {
511
- existing.searchRelevance.semanticMatch = result.searchRelevance.semanticMatch;
512
- } else {
513
- resultMap.set(result.id, result);
514
- }
515
- });
516
-
517
- // Graph search
518
- const graphResults = await this.performGraphSearch(query, stats);
519
- graphResults.forEach(result => {
520
- const existing = resultMap.get(result.id);
521
- if (existing) {
522
- existing.searchRelevance.graphRelevance = result.searchRelevance.graphRelevance;
523
- } else {
524
- resultMap.set(result.id, result);
525
- }
526
- });
527
- }
528
-
529
- // Temporal search if date range specified
530
- if (query.dateRange) {
531
- const temporalResults = await this.performTemporalSearch(query, stats);
532
- temporalResults.forEach(result => {
533
- const existing = resultMap.get(result.id);
534
- if (existing) {
535
- existing.searchRelevance.temporalRelevance = result.searchRelevance.temporalRelevance;
536
- } else {
537
- resultMap.set(result.id, result);
538
- }
539
- });
540
- }
541
-
542
- // Combine and calculate final relevance scores
543
- Array.from(resultMap.values()).forEach(result => {
544
- result.relevanceScore = this.combineRelevanceScores(result.searchRelevance);
545
- });
546
-
547
- return Array.from(resultMap.values());
548
- }
549
-
550
- // ==================== HELPER METHODS ====================
551
-
552
- /**
553
- * Apply filters to search results
554
- */
555
- private async applyFilters(
556
- results: UnifiedMemoryResult[],
557
- query: UnifiedMemoryQuery
558
- ): Promise<UnifiedMemoryResult[]> {
559
- let filtered = results;
560
-
561
- // Category filter
562
- if (query.categories && query.categories.length > 0) {
563
- filtered = filtered.filter(result =>
564
- query.categories!.includes(result.category)
565
- );
566
- }
567
-
568
- // Importance filter
569
- if (query.importanceRange) {
570
- filtered = filtered.filter(result => {
571
- const importance = result.metadata.importance;
572
- return (!query.importanceRange!.min || importance >= query.importanceRange!.min) &&
573
- (!query.importanceRange!.max || importance <= query.importanceRange!.max);
574
- });
575
- }
576
-
577
- // Tags filter
578
- if (query.tags && query.tags.length > 0) {
579
- filtered = filtered.filter(result =>
580
- query.tags!.some(tag => result.metadata.tags.includes(tag))
581
- );
582
- }
583
-
584
- // Content type filter
585
- if (query.contentTypes && query.contentTypes.length > 0) {
586
- filtered = filtered.filter(result =>
587
- query.contentTypes!.includes(result.metadata.contentType)
588
- );
589
- }
590
-
591
- return filtered;
592
- }
593
-
594
- /**
595
- * Enrich results with additional data
596
- */
597
- private async enrichResults(
598
- results: UnifiedMemoryResult[],
599
- query: UnifiedMemoryQuery
600
- ): Promise<UnifiedMemoryResult[]> {
601
- const enriched = await Promise.all(results.map(async (result) => {
602
- // Load content if requested
603
- if (query.includeContent && !result.content) {
604
- try {
605
- const content = await this.loadMemoryContent(result.storage.blobId, query.userId);
606
- result.content = content;
607
- } catch (error) {
608
- console.warn(`Failed to load content for memory ${result.id}:`, error);
609
- }
610
- }
611
-
612
- // Load analytics if requested
613
- if (query.includeAnalytics) {
614
- result.analytics = await this.loadMemoryAnalytics(result.id);
615
- }
616
-
617
- // Load relationships if requested
618
- if (query.includeMetadata) {
619
- result.relationships = await this.loadMemoryRelationships(result.id, query.userId);
620
- }
621
-
622
- return result;
623
- }));
624
-
625
- return enriched;
626
- }
627
-
628
- // ... [Continuing with remaining helper methods]
629
-
630
- /**
631
- * Rank and sort results by relevance
632
- */
633
- private rankAndSortResults(
634
- results: UnifiedMemoryResult[],
635
- query: UnifiedMemoryQuery
636
- ): UnifiedMemoryResult[] {
637
- return results
638
- .sort((a, b) => b.relevanceScore - a.relevanceScore)
639
- .slice(0, query.similarity?.k || 50);
640
- }
641
-
642
- /**
643
- * Generate comprehensive search statistics
644
- */
645
- private generateStats(
646
- results: UnifiedMemoryResult[],
647
- searchBreakdown: Partial<RetrievalStats['searchBreakdown']>,
648
- startTime: number
649
- ): RetrievalStats {
650
- const totalTime = Date.now() - startTime;
651
-
652
- return {
653
- totalResults: results.length,
654
- processingTime: totalTime,
655
- cacheHitRate: this.calculateCacheHitRate(),
656
- searchBreakdown: {
657
- vectorSearchTime: searchBreakdown.vectorSearchTime || 0,
658
- semanticAnalysisTime: searchBreakdown.semanticAnalysisTime || 0,
659
- decryptionTime: searchBreakdown.decryptionTime || 0,
660
- graphTraversalTime: searchBreakdown.graphTraversalTime || 0
661
- },
662
- dataSourcesUsed: this.getDataSourcesUsed(results),
663
- qualityMetrics: {
664
- averageRelevance: results.reduce((sum, r) => sum + r.relevanceScore, 0) / results.length || 0,
665
- diversityScore: this.calculateDiversityScore(results),
666
- freshnessScore: this.calculateFreshnessScore(results)
667
- }
668
- };
669
- }
670
-
671
- // ==================== CACHE MANAGEMENT ====================
672
-
673
- private generateCacheKey(query: UnifiedMemoryQuery): string {
674
- return `query:${JSON.stringify(query)}`;
675
- }
676
-
677
- private getCachedQuery(key: string): RetrievalContext | null {
678
- const cached = this.queryCache.get(key);
679
- if (cached && Date.now() - cached.timestamp < this.QUERY_CACHE_TTL) {
680
- return cached.result;
681
- }
682
- this.queryCache.delete(key);
683
- return null;
684
- }
685
-
686
- private cacheQuery(key: string, result: RetrievalContext): void {
687
- this.queryCache.set(key, { result, timestamp: Date.now() });
688
- }
689
-
690
- // ==================== UTILITY METHODS ====================
691
-
692
- private calculateCacheHitRate(): number {
693
- // Implementation for cache hit rate calculation
694
- return 0.85; // Placeholder
695
- }
696
-
697
- private getDataSourcesUsed(results: UnifiedMemoryResult[]): string[] {
698
- const sources = new Set<string>();
699
- results.forEach(result => {
700
- if (result.storage.cacheStatus === 'cached') sources.add('cache');
701
- if (result.storage.walrusHash) sources.add('walrus');
702
- if (result.storage.blockchainId) sources.add('blockchain');
703
- });
704
- return Array.from(sources);
705
- }
706
-
707
- private calculateDiversityScore(results: UnifiedMemoryResult[]): number {
708
- const categories = new Set(results.map(r => r.category));
709
- return categories.size / Math.max(results.length, 1);
710
- }
711
-
712
- private calculateFreshnessScore(results: UnifiedMemoryResult[]): number {
713
- const now = Date.now();
714
- const avgAge = results.reduce((sum, r) => sum + (now - r.created.getTime()), 0) / results.length;
715
- const maxAge = 365 * 24 * 60 * 60 * 1000; // 1 year in ms
716
- return Math.max(0, 1 - (avgAge / maxAge));
717
- }
718
-
719
- // Placeholder methods - to be implemented
720
- private async convertVectorResults(vectorResults: any[], query: UnifiedMemoryQuery): Promise<UnifiedMemoryResult[]> {
721
- // Convert vector search results to unified format
722
- return [];
723
- }
724
-
725
- private async analyzeQuerySemantics(query: string): Promise<any> {
726
- // Analyze query for semantic understanding
727
- return {};
728
- }
729
-
730
- private async calculateSemanticMatch(result: UnifiedMemoryResult, semantics: any): Promise<number> {
731
- // Calculate semantic match score
732
- return 0.8;
733
- }
734
-
735
- private combineRelevanceScores(scores: UnifiedMemoryResult['searchRelevance']): number {
736
- // Combine different relevance scores into final score
737
- const weights = {
738
- vectorSimilarity: 0.4,
739
- semanticMatch: 0.3,
740
- keywordMatch: 0.1,
741
- graphRelevance: 0.15,
742
- temporalRelevance: 0.05
743
- };
744
-
745
- return (scores.vectorSimilarity || 0) * weights.vectorSimilarity +
746
- (scores.semanticMatch || 0) * weights.semanticMatch +
747
- (scores.keywordMatch || 0) * weights.keywordMatch +
748
- (scores.graphRelevance || 0) * weights.graphRelevance +
749
- (scores.temporalRelevance || 0) * weights.temporalRelevance;
750
- }
751
-
752
- private calculateTemporalRelevance(date: Date, range?: { start?: Date; end?: Date }): number {
753
- // Calculate temporal relevance score
754
- return 0.7;
755
- }
756
-
757
- private async getAllUserMemories(userId: string): Promise<UnifiedMemoryResult[]> {
758
- // Get all memories for user from blockchain
759
- return [];
760
- }
761
-
762
- private async retrieveMemoryById(memoryId: string, query: UnifiedMemoryQuery): Promise<UnifiedMemoryResult | null> {
763
- // Retrieve specific memory by ID
764
- return null;
765
- }
766
-
767
- private async loadMemoryContent(blobId: string, userId: string): Promise<string> {
768
- // Load and decrypt memory content
769
- return "";
770
- }
771
-
772
- private async loadMemoryAnalytics(memoryId: string): Promise<any> {
773
- // Load memory analytics data
774
- return {};
775
- }
776
-
777
- private async loadMemoryRelationships(memoryId: string, userId: string): Promise<any> {
778
- // Load memory relationships from knowledge graph
779
- return {};
780
- }
781
-
782
- private async generateSuggestions(query: UnifiedMemoryQuery, results: UnifiedMemoryResult[]): Promise<any> {
783
- // Generate query suggestions and exploration paths
784
- return {
785
- relatedQueries: [],
786
- filterSuggestions: [],
787
- explorationPaths: []
788
- };
789
- }
790
-
791
- private async generateTimeline(results: UnifiedMemoryResult[], query: UnifiedMemoryQuery): Promise<any> {
792
- // Generate timeline of memory events
793
- return undefined;
794
- }
795
-
796
- // ==================== PUBLIC API ====================
797
-
798
- /**
799
- * Get comprehensive memory retrieval statistics
800
- */
801
- getRetrievalStats(): {
802
- cacheStats: { queries: number; content: number; analytics: number };
803
- performanceMetrics: any;
804
- } {
805
- return {
806
- cacheStats: {
807
- queries: this.queryCache.size,
808
- content: this.contentCache.size,
809
- analytics: this.analyticsCache.size
810
- },
811
- performanceMetrics: {}
812
- };
813
- }
814
-
815
- /**
816
- * Clear all caches
817
- */
818
- clearCache(): void {
819
- this.queryCache.clear();
820
- this.contentCache.clear();
821
- this.analyticsCache.clear();
822
- }
823
-
824
- /**
825
- * Warm up caches for a user
826
- */
827
- async warmupCache(userId: string): Promise<void> {
828
- // Pre-load frequently accessed data
829
- console.log(`Warming up cache for user ${userId}`);
830
- }
1
+ /**
2
+ * MemoryRetrievalService - Unified Memory Retrieval & Search
3
+ *
4
+ * Consolidates all memory retrieval operations into a single, powerful service
5
+ * with advanced caching, decryption, analytics, and multi-dimensional search.
6
+ *
7
+ * Features:
8
+ * - 🔍 Vector similarity search with HNSW indexing
9
+ * - 📊 Semantic search with AI understanding
10
+ * - 🕒 Time-based and metadata filtering
11
+ * - 🔐 Automatic SEAL decryption pipeline
12
+ * - 📈 Memory analytics and relationship discovery
13
+ * - ⚡ Multi-tier caching for performance
14
+ * - 🔄 Real-time memory streaming
15
+ * - 📤 Export and backup capabilities
16
+ */
17
+
18
+ import { EmbeddingService } from '../services/EmbeddingService';
19
+ import { VectorManager } from '../vector/VectorManager';
20
+ import { KnowledgeGraphManager } from '../graph/KnowledgeGraphManager';
21
+ import { StorageManager } from '../infrastructure/walrus/StorageManager';
22
+ import { BlockchainManager } from '../infrastructure/sui/BlockchainManager';
23
+ import { EncryptionService } from '../services/EncryptionService';
24
+ import { BatchManager } from '../batch/BatchManager';
25
+ import { MemoryDecryptionPipeline, DecryptionConfig } from './MemoryDecryptionPipeline';
26
+
27
+ // Enhanced types for unified retrieval
28
+ export interface UnifiedMemoryQuery {
29
+ // Core search parameters
30
+ query?: string;
31
+ userId: string;
32
+
33
+ // Search types
34
+ searchType?: 'vector' | 'semantic' | 'keyword' | 'hybrid' | 'graph' | 'temporal';
35
+
36
+ // Filtering options
37
+ categories?: string[];
38
+ dateRange?: {
39
+ start?: Date;
40
+ end?: Date;
41
+ };
42
+ importanceRange?: {
43
+ min?: number;
44
+ max?: number;
45
+ };
46
+ tags?: string[];
47
+ contentTypes?: string[];
48
+
49
+ // Vector search parameters
50
+ similarity?: {
51
+ threshold?: number;
52
+ k?: number;
53
+ efSearch?: number;
54
+ };
55
+
56
+ // Graph search parameters
57
+ graphTraversal?: {
58
+ maxDepth?: number;
59
+ includeEntities?: string[];
60
+ excludeRelations?: string[];
61
+ };
62
+
63
+ // Result options
64
+ includeContent?: boolean;
65
+ includeMetadata?: boolean;
66
+ includeEmbeddings?: boolean;
67
+ includeAnalytics?: boolean;
68
+
69
+ // Performance options
70
+ useCache?: boolean;
71
+ timeout?: number;
72
+ batchSize?: number;
73
+ }
74
+
75
+ export interface UnifiedMemoryResult {
76
+ id: string;
77
+ content?: string;
78
+ category: string;
79
+ created: Date;
80
+ updated?: Date;
81
+
82
+ // Scoring and relevance
83
+ similarity?: number;
84
+ relevanceScore: number;
85
+ searchRelevance: {
86
+ vectorSimilarity?: number;
87
+ semanticMatch?: number;
88
+ keywordMatch?: number;
89
+ graphRelevance?: number;
90
+ temporalRelevance?: number;
91
+ };
92
+
93
+ // Rich metadata
94
+ metadata: {
95
+ owner: string;
96
+ size: number;
97
+ importance: number;
98
+ tags: string[];
99
+ contentType: string;
100
+ isEncrypted: boolean;
101
+ accessCount?: number;
102
+ lastAccessed?: Date;
103
+ };
104
+
105
+ // Storage information
106
+ storage: {
107
+ blobId: string;
108
+ walrusHash?: string;
109
+ blockchainId?: string;
110
+ cacheStatus: 'cached' | 'retrieved' | 'not-cached';
111
+ };
112
+
113
+ // Relationships and context
114
+ relationships?: {
115
+ relatedMemories: string[];
116
+ knowledgeGraphNodes: string[];
117
+ semanticClusters: string[];
118
+ };
119
+
120
+ // Analytics
121
+ analytics?: {
122
+ viewCount: number;
123
+ shareCount: number;
124
+ editCount: number;
125
+ sentimentScore?: number;
126
+ topicDistribution?: Record<string, number>;
127
+ };
128
+ }
129
+
130
+ export interface RetrievalStats {
131
+ totalResults: number;
132
+ processingTime: number;
133
+ cacheHitRate: number;
134
+ searchBreakdown: {
135
+ vectorSearchTime: number;
136
+ semanticAnalysisTime: number;
137
+ decryptionTime: number;
138
+ graphTraversalTime: number;
139
+ };
140
+ dataSourcesUsed: string[];
141
+ qualityMetrics: {
142
+ averageRelevance: number;
143
+ diversityScore: number;
144
+ freshnessScore: number;
145
+ };
146
+ }
147
+
148
+ export interface RetrievalContext {
149
+ query: UnifiedMemoryQuery;
150
+ results: UnifiedMemoryResult[];
151
+ stats: RetrievalStats;
152
+ suggestions: {
153
+ relatedQueries: string[];
154
+ filterSuggestions: string[];
155
+ explorationPaths: string[];
156
+ };
157
+ timeline?: {
158
+ events: Array<{
159
+ date: Date;
160
+ type: 'created' | 'modified' | 'accessed' | 'shared';
161
+ memoryId: string;
162
+ description: string;
163
+ }>;
164
+ };
165
+ }
166
+
167
+ /**
168
+ * Unified Memory Retrieval Service
169
+ */
170
+ export class MemoryRetrievalService {
171
+ private embeddingService: EmbeddingService;
172
+ private vectorManager: VectorManager;
173
+ private graphManager: KnowledgeGraphManager;
174
+ private storageManager: StorageManager;
175
+ private blockchainManager: BlockchainManager;
176
+ private encryptionService: EncryptionService | null;
177
+ private batchManager: BatchManager;
178
+ private decryptionPipeline: MemoryDecryptionPipeline | null;
179
+
180
+ // Multi-tier caching system
181
+ private queryCache = new Map<string, { result: RetrievalContext; timestamp: number }>();
182
+ private contentCache = new Map<string, { content: string; metadata: any; timestamp: number }>();
183
+ private analyticsCache = new Map<string, { analytics: any; timestamp: number }>();
184
+
185
+ // Cache TTL settings (configurable)
186
+ private readonly QUERY_CACHE_TTL: number;
187
+ private readonly CONTENT_CACHE_TTL: number;
188
+ private readonly ANALYTICS_CACHE_TTL: number;
189
+
190
+ // Cache size limits to prevent memory leaks (configurable)
191
+ private readonly MAX_QUERY_CACHE_SIZE: number;
192
+ private readonly MAX_CONTENT_CACHE_SIZE: number;
193
+ private readonly MAX_ANALYTICS_CACHE_SIZE: number;
194
+
195
+ constructor(config?: {
196
+ embeddingService?: EmbeddingService;
197
+ vectorManager?: VectorManager;
198
+ graphManager?: KnowledgeGraphManager;
199
+ storageManager?: StorageManager;
200
+ blockchainManager?: BlockchainManager;
201
+ encryptionService?: EncryptionService;
202
+ batchManager?: BatchManager;
203
+ decryptionConfig?: DecryptionConfig;
204
+ /** Cache configuration for memory management */
205
+ cacheConfig?: {
206
+ /** Query cache TTL in ms (default: 5 minutes) */
207
+ queryCacheTtlMs?: number;
208
+ /** Content cache TTL in ms (default: 30 minutes) */
209
+ contentCacheTtlMs?: number;
210
+ /** Analytics cache TTL in ms (default: 1 hour) */
211
+ analyticsCacheTtlMs?: number;
212
+ /** Max query cache entries (default: 100) */
213
+ maxQueryCacheSize?: number;
214
+ /** Max content cache entries (default: 50) */
215
+ maxContentCacheSize?: number;
216
+ /** Max analytics cache entries (default: 100) */
217
+ maxAnalyticsCacheSize?: number;
218
+ };
219
+ }) {
220
+ // Initialize cache settings with configurable defaults
221
+ this.QUERY_CACHE_TTL = config?.cacheConfig?.queryCacheTtlMs ?? 5 * 60 * 1000; // 5 minutes
222
+ this.CONTENT_CACHE_TTL = config?.cacheConfig?.contentCacheTtlMs ?? 30 * 60 * 1000; // 30 minutes
223
+ this.ANALYTICS_CACHE_TTL = config?.cacheConfig?.analyticsCacheTtlMs ?? 60 * 60 * 1000; // 1 hour
224
+ this.MAX_QUERY_CACHE_SIZE = config?.cacheConfig?.maxQueryCacheSize ?? 100;
225
+ this.MAX_CONTENT_CACHE_SIZE = config?.cacheConfig?.maxContentCacheSize ?? 50; // Content can be large
226
+ this.MAX_ANALYTICS_CACHE_SIZE = config?.cacheConfig?.maxAnalyticsCacheSize ?? 100;
227
+ // Initialize services (can be injected or created with default configs)
228
+ this.embeddingService = config?.embeddingService ?? new EmbeddingService();
229
+ this.storageManager = config?.storageManager ?? new StorageManager();
230
+ this.vectorManager = config?.vectorManager ?? new VectorManager({
231
+ embedding: { apiKey: '' },
232
+ index: { dimension: 3072 },
233
+ batch: { maxBatchSize: 10 }
234
+ });
235
+ this.graphManager = config?.graphManager ?? new KnowledgeGraphManager();
236
+ this.blockchainManager = config?.blockchainManager ?? new BlockchainManager();
237
+ this.encryptionService = config?.encryptionService ?? null;
238
+ this.batchManager = config?.batchManager ?? new BatchManager();
239
+
240
+ // Initialize decryption pipeline only if encryption service is provided
241
+ this.decryptionPipeline = this.encryptionService
242
+ ? new MemoryDecryptionPipeline(
243
+ this.encryptionService,
244
+ this.storageManager,
245
+ config?.decryptionConfig
246
+ )
247
+ : null;
248
+ }
249
+
250
+ // ==================== UNIFIED SEARCH ====================
251
+
252
+ /**
253
+ * Main unified search method - handles all types of memory retrieval
254
+ */
255
+ async searchMemories(query: UnifiedMemoryQuery): Promise<RetrievalContext> {
256
+ const startTime = Date.now();
257
+
258
+ // Check cache first
259
+ const cacheKey = this.generateCacheKey(query);
260
+ if (query.useCache !== false) {
261
+ const cached = this.getCachedQuery(cacheKey);
262
+ if (cached) {
263
+ return cached;
264
+ }
265
+ }
266
+
267
+ try {
268
+ // Execute search based on type
269
+ let results: UnifiedMemoryResult[];
270
+ let searchStats: Partial<RetrievalStats['searchBreakdown']> = {};
271
+
272
+ switch (query.searchType || 'hybrid') {
273
+ case 'vector':
274
+ results = await this.performVectorSearch(query, searchStats);
275
+ break;
276
+ case 'semantic':
277
+ results = await this.performSemanticSearch(query, searchStats);
278
+ break;
279
+ case 'keyword':
280
+ results = await this.performKeywordSearch(query, searchStats);
281
+ break;
282
+ case 'graph':
283
+ results = await this.performGraphSearch(query, searchStats);
284
+ break;
285
+ case 'temporal':
286
+ results = await this.performTemporalSearch(query, searchStats);
287
+ break;
288
+ case 'hybrid':
289
+ default:
290
+ results = await this.performHybridSearch(query, searchStats);
291
+ break;
292
+ }
293
+
294
+ // Apply filters and post-processing
295
+ results = await this.applyFilters(results, query);
296
+ results = await this.enrichResults(results, query);
297
+ results = this.rankAndSortResults(results, query);
298
+
299
+ // Auto-decrypt encrypted memories if decryption is available
300
+ if (this.decryptionPipeline?.isReady()) {
301
+ try {
302
+ results = await this.decryptionPipeline.decryptMemoryResults(results, query.userId);
303
+ } catch (error) {
304
+ console.warn('⚠️ Auto-decryption failed, returning encrypted results:', error);
305
+ }
306
+ }
307
+
308
+ // Generate stats and suggestions
309
+ const stats = this.generateStats(results, searchStats, startTime);
310
+ const suggestions = await this.generateSuggestions(query, results);
311
+ const timeline = await this.generateTimeline(results, query);
312
+
313
+ const context: RetrievalContext = {
314
+ query,
315
+ results,
316
+ stats,
317
+ suggestions,
318
+ timeline
319
+ };
320
+
321
+ // Cache the results
322
+ if (query.useCache !== false) {
323
+ this.cacheQuery(cacheKey, context);
324
+ }
325
+
326
+ return context;
327
+
328
+ } catch (error) {
329
+ throw new Error(`Memory retrieval failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
330
+ }
331
+ }
332
+
333
+ // ==================== SPECIFIC SEARCH IMPLEMENTATIONS ====================
334
+
335
+ /**
336
+ * Vector similarity search using HNSW index
337
+ */
338
+ private async performVectorSearch(
339
+ query: UnifiedMemoryQuery,
340
+ stats: Partial<RetrievalStats['searchBreakdown']>
341
+ ): Promise<UnifiedMemoryResult[]> {
342
+ const vectorStart = Date.now();
343
+
344
+ if (!query.query) {
345
+ throw new Error('Vector search requires a query string');
346
+ }
347
+
348
+ // Generate query embedding
349
+ const embedding = await this.embeddingService.embedText({
350
+ text: query.query,
351
+ taskType: 'RETRIEVAL_QUERY'
352
+ });
353
+
354
+ // Search vector index
355
+ const vectorResults = await this.vectorManager.searchSimilarTexts(
356
+ 'default-user',
357
+ query.query,
358
+ {
359
+ k: query.similarity?.k || 10,
360
+ efSearch: query.similarity?.efSearch || 100,
361
+ threshold: query.similarity?.threshold || 0.7
362
+ }
363
+ );
364
+
365
+ stats.vectorSearchTime = Date.now() - vectorStart;
366
+
367
+ // Convert to unified format
368
+ return await this.convertVectorResults(vectorResults.results, query);
369
+ }
370
+
371
+ /**
372
+ * Semantic search with AI understanding
373
+ */
374
+ private async performSemanticSearch(
375
+ query: UnifiedMemoryQuery,
376
+ stats: Partial<RetrievalStats['searchBreakdown']>
377
+ ): Promise<UnifiedMemoryResult[]> {
378
+ const semanticStart = Date.now();
379
+
380
+ // First, get vector results as base
381
+ const vectorResults = await this.performVectorSearch(query, stats);
382
+
383
+ // Apply semantic analysis for better understanding
384
+ if (query.query) {
385
+ // Analyze query semantics
386
+ const semanticAnalysis = await this.analyzeQuerySemantics(query.query);
387
+
388
+ // Re-rank results based on semantic understanding
389
+ for (const result of vectorResults) {
390
+ result.searchRelevance.semanticMatch = await this.calculateSemanticMatch(
391
+ result,
392
+ semanticAnalysis
393
+ );
394
+ result.relevanceScore = this.combineRelevanceScores(result.searchRelevance);
395
+ }
396
+ }
397
+
398
+ stats.semanticAnalysisTime = (stats.semanticAnalysisTime || 0) + (Date.now() - semanticStart);
399
+
400
+ return vectorResults;
401
+ }
402
+
403
+ /**
404
+ * Knowledge graph traversal search
405
+ */
406
+ private async performGraphSearch(
407
+ query: UnifiedMemoryQuery,
408
+ stats: Partial<RetrievalStats['searchBreakdown']>
409
+ ): Promise<UnifiedMemoryResult[]> {
410
+ const graphStart = Date.now();
411
+
412
+ const results: UnifiedMemoryResult[] = [];
413
+
414
+ if (query.query) {
415
+ // Search graph for related entities and memories
416
+ const graphResults = await this.graphManager.searchGraph(
417
+ query.query,
418
+ {
419
+ maxResults: query.similarity?.k || 20
420
+ }
421
+ );
422
+
423
+ // Find memories related to discovered entities
424
+ for (const entity of graphResults.entities) {
425
+ const relatedMemories = await this.graphManager.findMemoriesRelatedToEntity(
426
+ entity.label || entity.id,
427
+ query.userId
428
+ );
429
+
430
+ const memoryIds = Array.isArray(relatedMemories) ? relatedMemories :
431
+ (relatedMemories?.memories || []);
432
+ for (const memoryId of memoryIds) {
433
+ const memory = await this.retrieveMemoryById(memoryId, query);
434
+ if (memory) {
435
+ memory.searchRelevance.graphRelevance = entity.confidence || 0.8;
436
+ results.push(memory);
437
+ }
438
+ }
439
+ }
440
+ }
441
+
442
+ stats.graphTraversalTime = Date.now() - graphStart;
443
+ return results;
444
+ }
445
+
446
+ /**
447
+ * Temporal/time-based search
448
+ */
449
+ private async performTemporalSearch(
450
+ query: UnifiedMemoryQuery,
451
+ stats: Partial<RetrievalStats['searchBreakdown']>
452
+ ): Promise<UnifiedMemoryResult[]> {
453
+ // Get all user memories
454
+ const allMemories = await this.getAllUserMemories(query.userId);
455
+
456
+ // Filter by date range
457
+ let filteredMemories = allMemories;
458
+
459
+ if (query.dateRange?.start) {
460
+ filteredMemories = filteredMemories.filter(
461
+ m => m.created >= query.dateRange!.start!
462
+ );
463
+ }
464
+
465
+ if (query.dateRange?.end) {
466
+ filteredMemories = filteredMemories.filter(
467
+ m => m.created <= query.dateRange!.end!
468
+ );
469
+ }
470
+
471
+ // Calculate temporal relevance
472
+ filteredMemories.forEach(memory => {
473
+ memory.searchRelevance.temporalRelevance = this.calculateTemporalRelevance(
474
+ memory.created,
475
+ query.dateRange
476
+ );
477
+ });
478
+
479
+ return filteredMemories;
480
+ }
481
+
482
+ /**
483
+ * Keyword-based search
484
+ */
485
+ private async performKeywordSearch(
486
+ query: UnifiedMemoryQuery,
487
+ stats: Partial<RetrievalStats['searchBreakdown']>
488
+ ): Promise<UnifiedMemoryResult[]> {
489
+ if (!query.query) {
490
+ return [];
491
+ }
492
+
493
+ const keywords = query.query.toLowerCase().split(/\s+/);
494
+ const allMemories = await this.getAllUserMemories(query.userId);
495
+
496
+ // Score memories based on keyword matches
497
+ const results = allMemories.filter(memory => {
498
+ const content = (memory.content || '').toLowerCase();
499
+ const matchCount = keywords.filter(keyword =>
500
+ content.includes(keyword)
501
+ ).length;
502
+
503
+ if (matchCount > 0) {
504
+ memory.searchRelevance.keywordMatch = matchCount / keywords.length;
505
+ return true;
506
+ }
507
+
508
+ return false;
509
+ });
510
+
511
+ return results;
512
+ }
513
+
514
+ /**
515
+ * Hybrid search combining multiple methods
516
+ */
517
+ private async performHybridSearch(
518
+ query: UnifiedMemoryQuery,
519
+ stats: Partial<RetrievalStats['searchBreakdown']>
520
+ ): Promise<UnifiedMemoryResult[]> {
521
+ const allResults: UnifiedMemoryResult[] = [];
522
+ const resultMap = new Map<string, UnifiedMemoryResult>();
523
+
524
+ // Perform multiple search types
525
+ if (query.query) {
526
+ // Vector search
527
+ const vectorResults = await this.performVectorSearch(query, stats);
528
+ vectorResults.forEach(result => {
529
+ result.searchRelevance.vectorSimilarity = result.similarity || 0;
530
+ resultMap.set(result.id, result);
531
+ });
532
+
533
+ // Semantic enhancement
534
+ const semanticResults = await this.performSemanticSearch(query, stats);
535
+ semanticResults.forEach(result => {
536
+ const existing = resultMap.get(result.id);
537
+ if (existing) {
538
+ existing.searchRelevance.semanticMatch = result.searchRelevance.semanticMatch;
539
+ } else {
540
+ resultMap.set(result.id, result);
541
+ }
542
+ });
543
+
544
+ // Graph search
545
+ const graphResults = await this.performGraphSearch(query, stats);
546
+ graphResults.forEach(result => {
547
+ const existing = resultMap.get(result.id);
548
+ if (existing) {
549
+ existing.searchRelevance.graphRelevance = result.searchRelevance.graphRelevance;
550
+ } else {
551
+ resultMap.set(result.id, result);
552
+ }
553
+ });
554
+ }
555
+
556
+ // Temporal search if date range specified
557
+ if (query.dateRange) {
558
+ const temporalResults = await this.performTemporalSearch(query, stats);
559
+ temporalResults.forEach(result => {
560
+ const existing = resultMap.get(result.id);
561
+ if (existing) {
562
+ existing.searchRelevance.temporalRelevance = result.searchRelevance.temporalRelevance;
563
+ } else {
564
+ resultMap.set(result.id, result);
565
+ }
566
+ });
567
+ }
568
+
569
+ // Combine and calculate final relevance scores
570
+ Array.from(resultMap.values()).forEach(result => {
571
+ result.relevanceScore = this.combineRelevanceScores(result.searchRelevance);
572
+ });
573
+
574
+ return Array.from(resultMap.values());
575
+ }
576
+
577
+ // ==================== HELPER METHODS ====================
578
+
579
+ /**
580
+ * Apply filters to search results
581
+ */
582
+ private async applyFilters(
583
+ results: UnifiedMemoryResult[],
584
+ query: UnifiedMemoryQuery
585
+ ): Promise<UnifiedMemoryResult[]> {
586
+ let filtered = results;
587
+
588
+ // Category filter
589
+ if (query.categories && query.categories.length > 0) {
590
+ filtered = filtered.filter(result =>
591
+ query.categories!.includes(result.category)
592
+ );
593
+ }
594
+
595
+ // Importance filter
596
+ if (query.importanceRange) {
597
+ filtered = filtered.filter(result => {
598
+ const importance = result.metadata.importance;
599
+ return (!query.importanceRange!.min || importance >= query.importanceRange!.min) &&
600
+ (!query.importanceRange!.max || importance <= query.importanceRange!.max);
601
+ });
602
+ }
603
+
604
+ // Tags filter
605
+ if (query.tags && query.tags.length > 0) {
606
+ filtered = filtered.filter(result =>
607
+ query.tags!.some(tag => result.metadata.tags.includes(tag))
608
+ );
609
+ }
610
+
611
+ // Content type filter
612
+ if (query.contentTypes && query.contentTypes.length > 0) {
613
+ filtered = filtered.filter(result =>
614
+ query.contentTypes!.includes(result.metadata.contentType)
615
+ );
616
+ }
617
+
618
+ return filtered;
619
+ }
620
+
621
+ /**
622
+ * Enrich results with additional data
623
+ */
624
+ private async enrichResults(
625
+ results: UnifiedMemoryResult[],
626
+ query: UnifiedMemoryQuery
627
+ ): Promise<UnifiedMemoryResult[]> {
628
+ const enriched = await Promise.all(results.map(async (result) => {
629
+ // Load content if requested
630
+ if (query.includeContent && !result.content) {
631
+ try {
632
+ const content = await this.loadMemoryContent(result.storage.blobId, query.userId);
633
+ result.content = content;
634
+ } catch (error) {
635
+ console.warn(`Failed to load content for memory ${result.id}:`, error);
636
+ }
637
+ }
638
+
639
+ // Load analytics if requested
640
+ if (query.includeAnalytics) {
641
+ result.analytics = await this.loadMemoryAnalytics(result.id);
642
+ }
643
+
644
+ // Load relationships if requested
645
+ if (query.includeMetadata) {
646
+ result.relationships = await this.loadMemoryRelationships(result.id, query.userId);
647
+ }
648
+
649
+ return result;
650
+ }));
651
+
652
+ return enriched;
653
+ }
654
+
655
+ // ... [Continuing with remaining helper methods]
656
+
657
+ /**
658
+ * Rank and sort results by relevance
659
+ */
660
+ private rankAndSortResults(
661
+ results: UnifiedMemoryResult[],
662
+ query: UnifiedMemoryQuery
663
+ ): UnifiedMemoryResult[] {
664
+ return results
665
+ .sort((a, b) => b.relevanceScore - a.relevanceScore)
666
+ .slice(0, query.similarity?.k || 50);
667
+ }
668
+
669
+ /**
670
+ * Generate comprehensive search statistics
671
+ */
672
+ private generateStats(
673
+ results: UnifiedMemoryResult[],
674
+ searchBreakdown: Partial<RetrievalStats['searchBreakdown']>,
675
+ startTime: number
676
+ ): RetrievalStats {
677
+ const totalTime = Date.now() - startTime;
678
+
679
+ return {
680
+ totalResults: results.length,
681
+ processingTime: totalTime,
682
+ cacheHitRate: this.calculateCacheHitRate(),
683
+ searchBreakdown: {
684
+ vectorSearchTime: searchBreakdown.vectorSearchTime || 0,
685
+ semanticAnalysisTime: searchBreakdown.semanticAnalysisTime || 0,
686
+ decryptionTime: searchBreakdown.decryptionTime || 0,
687
+ graphTraversalTime: searchBreakdown.graphTraversalTime || 0
688
+ },
689
+ dataSourcesUsed: this.getDataSourcesUsed(results),
690
+ qualityMetrics: {
691
+ averageRelevance: results.reduce((sum, r) => sum + r.relevanceScore, 0) / results.length || 0,
692
+ diversityScore: this.calculateDiversityScore(results),
693
+ freshnessScore: this.calculateFreshnessScore(results)
694
+ }
695
+ };
696
+ }
697
+
698
+ // ==================== CACHE MANAGEMENT ====================
699
+
700
+ private generateCacheKey(query: UnifiedMemoryQuery): string {
701
+ return `query:${JSON.stringify(query)}`;
702
+ }
703
+
704
+ private getCachedQuery(key: string): RetrievalContext | null {
705
+ const cached = this.queryCache.get(key);
706
+ if (cached && Date.now() - cached.timestamp < this.QUERY_CACHE_TTL) {
707
+ return cached.result;
708
+ }
709
+ this.queryCache.delete(key);
710
+ return null;
711
+ }
712
+
713
+ private cacheQuery(key: string, result: RetrievalContext): void {
714
+ this.enforceCacheLimit(this.queryCache, this.MAX_QUERY_CACHE_SIZE, this.QUERY_CACHE_TTL);
715
+ this.queryCache.set(key, { result, timestamp: Date.now() });
716
+ }
717
+
718
+ /**
719
+ * Cache content with size limit enforcement
720
+ */
721
+ private cacheContent(key: string, content: string, metadata: any): void {
722
+ this.enforceCacheLimit(this.contentCache, this.MAX_CONTENT_CACHE_SIZE, this.CONTENT_CACHE_TTL);
723
+ this.contentCache.set(key, { content, metadata, timestamp: Date.now() });
724
+ }
725
+
726
+ /**
727
+ * Cache analytics with size limit enforcement
728
+ */
729
+ private cacheAnalytics(key: string, analytics: any): void {
730
+ this.enforceCacheLimit(this.analyticsCache, this.MAX_ANALYTICS_CACHE_SIZE, this.ANALYTICS_CACHE_TTL);
731
+ this.analyticsCache.set(key, { analytics, timestamp: Date.now() });
732
+ }
733
+
734
+ /**
735
+ * Enforce cache size limit using LRU eviction (oldest entries first)
736
+ * Also removes expired entries based on TTL
737
+ */
738
+ private enforceCacheLimit<T extends { timestamp: number }>(
739
+ cache: Map<string, T>,
740
+ maxSize: number,
741
+ ttl: number
742
+ ): void {
743
+ // First, clean up expired entries
744
+ const now = Date.now();
745
+
746
+ for (const [key, value] of cache.entries()) {
747
+ if (now - value.timestamp > ttl) {
748
+ cache.delete(key);
749
+ }
750
+ }
751
+
752
+ // If still over limit, remove oldest entries (LRU)
753
+ if (cache.size >= maxSize) {
754
+ const entries = Array.from(cache.entries())
755
+ .sort((a, b) => a[1].timestamp - b[1].timestamp);
756
+
757
+ const toRemove = cache.size - maxSize + 1; // +1 to make room for new entry
758
+ for (let i = 0; i < toRemove && i < entries.length; i++) {
759
+ cache.delete(entries[i][0]);
760
+ }
761
+ }
762
+ }
763
+
764
+ // ==================== UTILITY METHODS ====================
765
+
766
+ private calculateCacheHitRate(): number {
767
+ // Implementation for cache hit rate calculation
768
+ return 0.85; // Placeholder
769
+ }
770
+
771
+ private getDataSourcesUsed(results: UnifiedMemoryResult[]): string[] {
772
+ const sources = new Set<string>();
773
+ results.forEach(result => {
774
+ if (result.storage.cacheStatus === 'cached') sources.add('cache');
775
+ if (result.storage.walrusHash) sources.add('walrus');
776
+ if (result.storage.blockchainId) sources.add('blockchain');
777
+ });
778
+ return Array.from(sources);
779
+ }
780
+
781
+ private calculateDiversityScore(results: UnifiedMemoryResult[]): number {
782
+ const categories = new Set(results.map(r => r.category));
783
+ return categories.size / Math.max(results.length, 1);
784
+ }
785
+
786
+ private calculateFreshnessScore(results: UnifiedMemoryResult[]): number {
787
+ const now = Date.now();
788
+ const avgAge = results.reduce((sum, r) => sum + (now - r.created.getTime()), 0) / results.length;
789
+ const maxAge = 365 * 24 * 60 * 60 * 1000; // 1 year in ms
790
+ return Math.max(0, 1 - (avgAge / maxAge));
791
+ }
792
+
793
+ // Placeholder methods - to be implemented
794
+ private async convertVectorResults(vectorResults: any[], query: UnifiedMemoryQuery): Promise<UnifiedMemoryResult[]> {
795
+ // Convert vector search results to unified format
796
+ return [];
797
+ }
798
+
799
+ private async analyzeQuerySemantics(query: string): Promise<any> {
800
+ // Analyze query for semantic understanding
801
+ return {};
802
+ }
803
+
804
+ private async calculateSemanticMatch(result: UnifiedMemoryResult, semantics: any): Promise<number> {
805
+ // Calculate semantic match score
806
+ return 0.8;
807
+ }
808
+
809
+ private combineRelevanceScores(scores: UnifiedMemoryResult['searchRelevance']): number {
810
+ // Combine different relevance scores into final score
811
+ const weights = {
812
+ vectorSimilarity: 0.4,
813
+ semanticMatch: 0.3,
814
+ keywordMatch: 0.1,
815
+ graphRelevance: 0.15,
816
+ temporalRelevance: 0.05
817
+ };
818
+
819
+ return (scores.vectorSimilarity || 0) * weights.vectorSimilarity +
820
+ (scores.semanticMatch || 0) * weights.semanticMatch +
821
+ (scores.keywordMatch || 0) * weights.keywordMatch +
822
+ (scores.graphRelevance || 0) * weights.graphRelevance +
823
+ (scores.temporalRelevance || 0) * weights.temporalRelevance;
824
+ }
825
+
826
+ private calculateTemporalRelevance(date: Date, range?: { start?: Date; end?: Date }): number {
827
+ // Calculate temporal relevance score
828
+ return 0.7;
829
+ }
830
+
831
+ private async getAllUserMemories(userId: string): Promise<UnifiedMemoryResult[]> {
832
+ // Get all memories for user from blockchain
833
+ return [];
834
+ }
835
+
836
+ private async retrieveMemoryById(memoryId: string, query: UnifiedMemoryQuery): Promise<UnifiedMemoryResult | null> {
837
+ // Retrieve specific memory by ID
838
+ return null;
839
+ }
840
+
841
+ private async loadMemoryContent(blobId: string, userId: string): Promise<string> {
842
+ // Load and decrypt memory content
843
+ return "";
844
+ }
845
+
846
+ private async loadMemoryAnalytics(memoryId: string): Promise<any> {
847
+ // Load memory analytics data
848
+ return {};
849
+ }
850
+
851
+ private async loadMemoryRelationships(memoryId: string, userId: string): Promise<any> {
852
+ // Load memory relationships from knowledge graph
853
+ return {};
854
+ }
855
+
856
+ private async generateSuggestions(query: UnifiedMemoryQuery, results: UnifiedMemoryResult[]): Promise<any> {
857
+ // Generate query suggestions and exploration paths
858
+ return {
859
+ relatedQueries: [],
860
+ filterSuggestions: [],
861
+ explorationPaths: []
862
+ };
863
+ }
864
+
865
+ private async generateTimeline(results: UnifiedMemoryResult[], query: UnifiedMemoryQuery): Promise<any> {
866
+ // Generate timeline of memory events
867
+ return undefined;
868
+ }
869
+
870
+ // ==================== PUBLIC API ====================
871
+
872
+ /**
873
+ * Get comprehensive memory retrieval statistics
874
+ */
875
+ getRetrievalStats(): {
876
+ cacheStats: { queries: number; content: number; analytics: number };
877
+ performanceMetrics: any;
878
+ } {
879
+ return {
880
+ cacheStats: {
881
+ queries: this.queryCache.size,
882
+ content: this.contentCache.size,
883
+ analytics: this.analyticsCache.size
884
+ },
885
+ performanceMetrics: {}
886
+ };
887
+ }
888
+
889
+ /**
890
+ * Clear all caches
891
+ */
892
+ clearCache(): void {
893
+ this.queryCache.clear();
894
+ this.contentCache.clear();
895
+ this.analyticsCache.clear();
896
+ }
897
+
898
+ /**
899
+ * Warm up caches for a user
900
+ */
901
+ async warmupCache(userId: string): Promise<void> {
902
+ // Pre-load frequently accessed data
903
+ console.log(`Warming up cache for user ${userId}`);
904
+ }
831
905
  }