@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,598 +1,598 @@
1
- /**
2
- * BatchManager - Central orchestrator for all batch processing operations
3
- *
4
- * Coordinates embedding generation, vector indexing, knowledge graph updates,
5
- * and Walrus operations through intelligent batching and caching.
6
- */
7
-
8
- import EventEmitter from 'eventemitter3';
9
- import { BatchingService, BatchProcessor, BatchItem } from './BatchingService';
10
- import { MemoryProcessingCache } from './MemoryProcessingCache';
11
- import { EmbeddingService } from '../services/EmbeddingService';
12
- import type { IHnswService } from '../vector/IHnswService';
13
- import {
14
- Memory,
15
- ProcessedMemory,
16
- BatchConfig,
17
- BatchStats,
18
- MemoryBatchResult
19
- } from '../embedding/types';
20
-
21
- export interface BatchManagerConfig {
22
- embedding?: {
23
- batchSize?: number;
24
- delayMs?: number;
25
- };
26
- indexing?: {
27
- batchSize?: number;
28
- delayMs?: number;
29
- };
30
- walrus?: {
31
- batchSize?: number;
32
- delayMs?: number;
33
- };
34
- cache?: {
35
- maxSize?: number;
36
- ttlMs?: number;
37
- };
38
- enableMetrics?: boolean;
39
- }
40
-
41
- export interface BatchManagerStats extends BatchStats {
42
- managers: {
43
- embedding: BatchStats;
44
- indexing: BatchStats;
45
- walrus: BatchStats;
46
- };
47
- cache: any; // MemoryCacheStats
48
- performance: {
49
- totalProcessingTime: number;
50
- averageMemoryProcessingTime: number;
51
- successfulBatches: number;
52
- failedBatches: number;
53
- };
54
- }
55
-
56
- export interface BatchJobStatus {
57
- id: string;
58
- type: 'embedding' | 'indexing' | 'walrus' | 'pipeline';
59
- status: 'pending' | 'processing' | 'completed' | 'failed';
60
- itemCount: number;
61
- startTime?: Date;
62
- endTime?: Date;
63
- error?: string;
64
- processingTimeMs?: number;
65
- }
66
-
67
- /**
68
- * Central batch processing manager with integrated caching and monitoring
69
- */
70
- export class BatchManager extends EventEmitter {
71
- private embeddingBatcher!: BatchingService<Memory>;
72
- private indexingBatcher!: BatchingService<ProcessedMemory>;
73
- private walrusBatcher!: BatchingService<ProcessedMemory>;
74
- private cache!: MemoryProcessingCache;
75
-
76
- private embeddingService?: EmbeddingService;
77
- private indexService?: IHnswService;
78
-
79
- private readonly config: Required<BatchManagerConfig>;
80
- private jobStatuses = new Map<string, BatchJobStatus>();
81
- private metrics = {
82
- totalProcessingTime: 0,
83
- averageMemoryProcessingTime: 0,
84
- successfulBatches: 0,
85
- failedBatches: 0,
86
- totalMemoriesProcessed: 0
87
- };
88
-
89
- constructor(config: BatchManagerConfig = {}) {
90
- super();
91
-
92
- this.config = {
93
- embedding: {
94
- batchSize: config.embedding?.batchSize || 20,
95
- delayMs: config.embedding?.delayMs || 5000
96
- },
97
- indexing: {
98
- batchSize: config.indexing?.batchSize || 50,
99
- delayMs: config.indexing?.delayMs || 3000
100
- },
101
- walrus: {
102
- batchSize: config.walrus?.batchSize || 10,
103
- delayMs: config.walrus?.delayMs || 8000
104
- },
105
- cache: {
106
- maxSize: config.cache?.maxSize || 5000,
107
- ttlMs: config.cache?.ttlMs || 60 * 60 * 1000
108
- },
109
- enableMetrics: config.enableMetrics !== false
110
- };
111
-
112
- // Initialize services
113
- this.initializeBatchingServices();
114
- this.cache = new MemoryProcessingCache(this.config.cache);
115
- }
116
-
117
- // ==================== SERVICE INITIALIZATION ====================
118
-
119
- /**
120
- * Initialize with required services
121
- */
122
- initialize(services: {
123
- embeddingService?: EmbeddingService;
124
- indexService?: IHnswService;
125
- }): void {
126
- this.embeddingService = services.embeddingService;
127
- this.indexService = services.indexService;
128
-
129
- console.log('BatchManager initialized with services');
130
- }
131
-
132
- // ==================== MEMORY PROCESSING PIPELINE ====================
133
-
134
- /**
135
- * Add memory to complete processing pipeline
136
- */
137
- async addMemoryToPipeline(
138
- memory: Memory,
139
- options: {
140
- priority?: 'low' | 'normal' | 'high';
141
- skipCache?: boolean;
142
- immediateProcessing?: boolean;
143
- } = {}
144
- ): Promise<string> {
145
- const jobId = this.generateJobId();
146
-
147
- // Check cache first (unless skipped)
148
- if (!options.skipCache) {
149
- const cached = this.cache.getCachedMemory(memory.id);
150
- if (cached?.processingState === 'completed') {
151
- this.emit('memory:cached', { memoryId: memory.id, cached });
152
- return jobId;
153
- }
154
- }
155
-
156
- // Create job status
157
- this.jobStatuses.set(jobId, {
158
- id: jobId,
159
- type: 'pipeline',
160
- status: 'pending',
161
- itemCount: 1,
162
- startTime: new Date()
163
- });
164
-
165
- try {
166
- // Cache memory as pending
167
- this.cache.cacheMemory(memory);
168
- this.cache.updateMemoryState(memory.id, 'pending');
169
-
170
- // Add to processing pipeline
171
- if (options.immediateProcessing) {
172
- await this.processMemoryImmediate(memory);
173
- } else {
174
- // Add to embedding batch
175
- this.embeddingBatcher.addToBatch('memories', {
176
- id: memory.id,
177
- data: memory,
178
- timestamp: new Date(),
179
- priority: this.getPriorityValue(options.priority),
180
- metadata: { originalJobId: jobId }
181
- });
182
- }
183
-
184
- this.updateJobStatus(jobId, 'processing');
185
- this.emit('memory:queued', { memoryId: memory.id, jobId });
186
-
187
- } catch (error) {
188
- this.updateJobStatus(jobId, 'failed', error as Error);
189
- this.cache.updateMemoryState(memory.id, 'failed', (error as Error).message);
190
- throw error;
191
- }
192
-
193
- return jobId;
194
- }
195
-
196
- /**
197
- * Process multiple memories in batch
198
- */
199
- async addMemoriesToPipeline(
200
- memories: Memory[],
201
- options: {
202
- priority?: 'low' | 'normal' | 'high';
203
- batchSize?: number;
204
- } = {}
205
- ): Promise<string[]> {
206
- const batchSize = options.batchSize || this.config.embedding.batchSize;
207
- const jobIds: string[] = [];
208
-
209
- // Process in smaller batches to avoid overwhelming the system
210
- const safeBatchSize = batchSize || 10;
211
- for (let i = 0; i < memories.length; i += safeBatchSize) {
212
- const batch = memories.slice(i, i + safeBatchSize);
213
-
214
- for (const memory of batch) {
215
- try {
216
- const jobId = await this.addMemoryToPipeline(memory, options);
217
- jobIds.push(jobId);
218
- } catch (error) {
219
- console.error(`Failed to add memory ${memory.id} to pipeline:`, error);
220
- // Continue with other memories
221
- }
222
- }
223
-
224
- // Small delay between batches
225
- if (i + safeBatchSize < memories.length) {
226
- await this.delay(100);
227
- }
228
- }
229
-
230
- return jobIds;
231
- }
232
-
233
- // ==================== BATCH PROCESSING CONTROL ====================
234
-
235
- /**
236
- * Process all pending batches immediately
237
- */
238
- async processAllBatches(): Promise<void> {
239
- console.log('Processing all pending batches...');
240
-
241
- try {
242
- await Promise.all([
243
- this.embeddingBatcher.processAllBatches(),
244
- this.indexingBatcher.processAllBatches(),
245
- this.walrusBatcher.processAllBatches()
246
- ]);
247
-
248
- console.log('All batches processed successfully');
249
- } catch (error) {
250
- console.error('Error processing batches:', error);
251
- throw error;
252
- }
253
- }
254
-
255
- /**
256
- * Get status of specific job
257
- */
258
- getJobStatus(jobId: string): BatchJobStatus | undefined {
259
- return this.jobStatuses.get(jobId);
260
- }
261
-
262
- /**
263
- * Get all job statuses
264
- */
265
- getAllJobStatuses(): BatchJobStatus[] {
266
- return Array.from(this.jobStatuses.values());
267
- }
268
-
269
- /**
270
- * Get pending jobs count by type
271
- */
272
- getPendingJobsCount(): Record<string, number> {
273
- const counts = { embedding: 0, indexing: 0, walrus: 0, pipeline: 0 };
274
-
275
- for (const job of this.jobStatuses.values()) {
276
- if (job.status === 'pending' || job.status === 'processing') {
277
- counts[job.type]++;
278
- }
279
- }
280
-
281
- return counts;
282
- }
283
-
284
- // ==================== CACHING OPERATIONS ====================
285
-
286
- /**
287
- * Get cached memory
288
- */
289
- getCachedMemory(memoryId: string) {
290
- return this.cache.getCachedMemory(memoryId);
291
- }
292
-
293
- /**
294
- * Find similar memories
295
- */
296
- findSimilarMemories(memoryId: string, limit?: number) {
297
- return this.cache.findSimilarMemories(memoryId, limit);
298
- }
299
-
300
- /**
301
- * Get cache statistics
302
- */
303
- getCacheStats() {
304
- return this.cache.getStats();
305
- }
306
-
307
- /**
308
- * Clear all caches
309
- */
310
- clearCaches(): void {
311
- this.cache.clearAll();
312
- this.jobStatuses.clear();
313
- }
314
-
315
- // ==================== STATISTICS & MONITORING ====================
316
-
317
- /**
318
- * Get comprehensive batch manager statistics
319
- */
320
- getStats(): BatchManagerStats {
321
- const embeddingStats = this.embeddingBatcher.getBatchStats();
322
- const indexingStats = this.indexingBatcher.getBatchStats();
323
- const walrusStats = this.walrusBatcher.getBatchStats();
324
- const cacheStats = this.cache.getStats();
325
-
326
- return {
327
- // Aggregate stats
328
- totalUsers: Math.max(embeddingStats.totalUsers, indexingStats.totalUsers, walrusStats.totalUsers),
329
- totalPendingVectors: embeddingStats.totalPendingVectors + indexingStats.totalPendingVectors,
330
- activeBatchJobs: embeddingStats.activeBatchJobs + indexingStats.activeBatchJobs + walrusStats.activeBatchJobs,
331
- cacheHitRate: cacheStats.performance.hitRateMemories,
332
- averageBatchSize: (embeddingStats.averageBatchSize + indexingStats.averageBatchSize + walrusStats.averageBatchSize) / 3,
333
- averageProcessingTime: this.metrics.averageMemoryProcessingTime,
334
-
335
- // Individual managers
336
- managers: {
337
- embedding: embeddingStats,
338
- indexing: indexingStats,
339
- walrus: walrusStats
340
- },
341
-
342
- // Cache stats
343
- cache: cacheStats,
344
-
345
- // Performance metrics
346
- performance: {
347
- totalProcessingTime: this.metrics.totalProcessingTime,
348
- averageMemoryProcessingTime: this.metrics.averageMemoryProcessingTime,
349
- successfulBatches: this.metrics.successfulBatches,
350
- failedBatches: this.metrics.failedBatches
351
- }
352
- };
353
- }
354
-
355
- /**
356
- * Cleanup and destroy batch manager
357
- */
358
- destroy(): void {
359
- // Destroy all batching services
360
- this.embeddingBatcher.destroy();
361
- this.indexingBatcher.destroy();
362
- this.walrusBatcher.destroy();
363
-
364
- // Destroy cache
365
- this.cache.destroy();
366
-
367
- // Clear job statuses
368
- this.jobStatuses.clear();
369
-
370
- // Remove all listeners
371
- this.removeAllListeners();
372
-
373
- console.log('BatchManager destroyed');
374
- }
375
-
376
- // ==================== PRIVATE METHODS ====================
377
-
378
- private initializeBatchingServices(): void {
379
- // Initialize embedding batcher
380
- this.embeddingBatcher = new BatchingService<Memory>(
381
- {
382
- maxBatchSize: this.config.embedding.batchSize,
383
- batchDelayMs: this.config.embedding.delayMs
384
- }
385
- );
386
-
387
- // Initialize indexing batcher
388
- this.indexingBatcher = new BatchingService<ProcessedMemory>(
389
- {
390
- maxBatchSize: this.config.indexing.batchSize,
391
- batchDelayMs: this.config.indexing.delayMs
392
- }
393
- );
394
-
395
- // Initialize Walrus batcher
396
- this.walrusBatcher = new BatchingService<ProcessedMemory>(
397
- {
398
- maxBatchSize: this.config.walrus.batchSize,
399
- batchDelayMs: this.config.walrus.delayMs
400
- }
401
- );
402
-
403
- // Register processors
404
- this.registerBatchProcessors();
405
- }
406
-
407
- private registerBatchProcessors(): void {
408
- // Embedding processor
409
- this.embeddingBatcher.registerProcessor('memories', {
410
- process: async (items: BatchItem<Memory>[]) => {
411
- await this.processEmbeddingBatch(items.map(item => item.data));
412
- }
413
- });
414
-
415
- // Indexing processor
416
- this.indexingBatcher.registerProcessor('processed-memories', {
417
- process: async (items: BatchItem<ProcessedMemory>[]) => {
418
- await this.processIndexingBatch(items.map(item => item.data));
419
- }
420
- });
421
-
422
- // Walrus processor
423
- this.walrusBatcher.registerProcessor('walrus-uploads', {
424
- process: async (items: BatchItem<ProcessedMemory>[]) => {
425
- await this.processWalrusBatch(items.map(item => item.data));
426
- }
427
- });
428
- }
429
-
430
- private async processEmbeddingBatch(memories: Memory[]): Promise<void> {
431
- if (!this.embeddingService) {
432
- console.warn('EmbeddingService not initialized');
433
- return;
434
- }
435
-
436
- console.log(`Processing embedding batch of ${memories.length} memories`);
437
- const startTime = Date.now();
438
-
439
- try {
440
- // Generate embeddings in batch
441
- const results = await this.embeddingService.embedBatch(
442
- memories.map(m => m.content)
443
- );
444
-
445
- // Process results
446
- for (let i = 0; i < memories.length; i++) {
447
- const memory = memories[i];
448
- const embedding = results.vectors[i];
449
-
450
- if (embedding && embedding.length > 0) {
451
- const processedMemory: ProcessedMemory = {
452
- ...memory,
453
- embedding: embedding,
454
- embeddingModel: 'gemini-embedding',
455
- processedAt: new Date()
456
- };
457
-
458
- // Update cache
459
- this.cache.cacheMemory(memory, processedMemory);
460
- this.cache.updateMemoryState(memory.id, 'completed');
461
-
462
- // Add to indexing batch
463
- this.indexingBatcher.addToBatch('processed-memories', {
464
- id: memory.id,
465
- data: processedMemory,
466
- timestamp: new Date()
467
- });
468
-
469
- this.emit('memory:embedded', { memoryId: memory.id, embedding: embedding });
470
- } else {
471
- this.cache.updateMemoryState(memory.id, 'failed', 'Embedding generation failed');
472
- this.emit('memory:embedding-failed', { memoryId: memory.id, error: 'Embedding generation failed' });
473
- }
474
- }
475
-
476
- const processingTime = Date.now() - startTime;
477
- this.updateMetrics(memories.length, processingTime, true);
478
-
479
- } catch (error) {
480
- console.error('Embedding batch processing failed:', error);
481
-
482
- // Update all memories as failed
483
- for (const memory of memories) {
484
- this.cache.updateMemoryState(memory.id, 'failed', (error as Error).message);
485
- }
486
-
487
- this.updateMetrics(memories.length, Date.now() - startTime, false);
488
- throw error;
489
- }
490
- }
491
-
492
- private async processIndexingBatch(processedMemories: ProcessedMemory[]): Promise<void> {
493
- if (!this.indexService) {
494
- console.warn('IHnswService not initialized');
495
- return;
496
- }
497
-
498
- console.log(`Processing indexing batch of ${processedMemories.length} memories`);
499
-
500
- try {
501
- // Add to HNSW index
502
- for (const memory of processedMemories) {
503
- await this.indexService.addVector(
504
- memory.userId || 'default-user',
505
- parseInt(memory.id) || Date.now(),
506
- memory.embedding || [],
507
- {
508
- content: memory.content,
509
- category: memory.category,
510
- timestamp: memory.createdAt
511
- }
512
- );
513
-
514
- this.emit('memory:indexed', { memoryId: memory.id });
515
- }
516
-
517
- // Flush pending vectors
518
- if (this.indexService) {
519
- await this.indexService.flushBatch('batch-operation');
520
- }
521
-
522
- } catch (error) {
523
- console.error('Indexing batch processing failed:', error);
524
- throw error;
525
- }
526
- }
527
-
528
- private async processWalrusBatch(processedMemories: ProcessedMemory[]): Promise<void> {
529
- console.log(`Processing Walrus batch of ${processedMemories.length} memories`);
530
-
531
- try {
532
- // TODO: Implement Walrus batch operations
533
- // This would involve:
534
- // 1. Batch upload processed memories to Walrus
535
- // 2. Update Sui blockchain records
536
- // 3. Sync with knowledge graph
537
-
538
- for (const memory of processedMemories) {
539
- this.emit('memory:stored', { memoryId: memory.id });
540
- }
541
-
542
- } catch (error) {
543
- console.error('Walrus batch processing failed:', error);
544
- throw error;
545
- }
546
- }
547
-
548
- private async processMemoryImmediate(memory: Memory): Promise<void> {
549
- // Process single memory immediately (bypass batching)
550
- await this.processEmbeddingBatch([memory]);
551
- }
552
-
553
- private updateJobStatus(jobId: string, status: BatchJobStatus['status'], error?: Error): void {
554
- const job = this.jobStatuses.get(jobId);
555
- if (job) {
556
- job.status = status;
557
-
558
- if (status === 'completed' || status === 'failed') {
559
- job.endTime = new Date();
560
- job.processingTimeMs = job.endTime.getTime() - (job.startTime?.getTime() || 0);
561
- }
562
-
563
- if (error) {
564
- job.error = error.message;
565
- }
566
-
567
- this.emit('job:status-changed', { jobId, status, error });
568
- }
569
- }
570
-
571
- private updateMetrics(itemCount: number, processingTimeMs: number, success: boolean): void {
572
- if (success) {
573
- this.metrics.successfulBatches++;
574
- } else {
575
- this.metrics.failedBatches++;
576
- }
577
-
578
- this.metrics.totalMemoriesProcessed += itemCount;
579
- this.metrics.totalProcessingTime += processingTimeMs;
580
- this.metrics.averageMemoryProcessingTime =
581
- this.metrics.totalProcessingTime / this.metrics.totalMemoriesProcessed;
582
- }
583
-
584
- private getPriorityValue(priority?: 'low' | 'normal' | 'high'): number {
585
- const priorityMap = { low: 0, normal: 1, high: 2 };
586
- return priorityMap[priority || 'normal'];
587
- }
588
-
589
- private generateJobId(): string {
590
- return `job_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
591
- }
592
-
593
- private delay(ms: number): Promise<void> {
594
- return new Promise(resolve => setTimeout(resolve, ms));
595
- }
596
- }
597
-
1
+ /**
2
+ * BatchManager - Central orchestrator for all batch processing operations
3
+ *
4
+ * Coordinates embedding generation, vector indexing, knowledge graph updates,
5
+ * and Walrus operations through intelligent batching and caching.
6
+ */
7
+
8
+ import EventEmitter from 'eventemitter3';
9
+ import { BatchingService, BatchProcessor, BatchItem } from './BatchingService';
10
+ import { MemoryProcessingCache } from './MemoryProcessingCache';
11
+ import { EmbeddingService } from '../services/EmbeddingService';
12
+ import type { IHnswService } from '../vector/IHnswService';
13
+ import {
14
+ Memory,
15
+ ProcessedMemory,
16
+ BatchConfig,
17
+ BatchStats,
18
+ MemoryBatchResult
19
+ } from '../embedding/types';
20
+
21
+ export interface BatchManagerConfig {
22
+ embedding?: {
23
+ batchSize?: number;
24
+ delayMs?: number;
25
+ };
26
+ indexing?: {
27
+ batchSize?: number;
28
+ delayMs?: number;
29
+ };
30
+ walrus?: {
31
+ batchSize?: number;
32
+ delayMs?: number;
33
+ };
34
+ cache?: {
35
+ maxSize?: number;
36
+ ttlMs?: number;
37
+ };
38
+ enableMetrics?: boolean;
39
+ }
40
+
41
+ export interface BatchManagerStats extends BatchStats {
42
+ managers: {
43
+ embedding: BatchStats;
44
+ indexing: BatchStats;
45
+ walrus: BatchStats;
46
+ };
47
+ cache: any; // MemoryCacheStats
48
+ performance: {
49
+ totalProcessingTime: number;
50
+ averageMemoryProcessingTime: number;
51
+ successfulBatches: number;
52
+ failedBatches: number;
53
+ };
54
+ }
55
+
56
+ export interface BatchJobStatus {
57
+ id: string;
58
+ type: 'embedding' | 'indexing' | 'walrus' | 'pipeline';
59
+ status: 'pending' | 'processing' | 'completed' | 'failed';
60
+ itemCount: number;
61
+ startTime?: Date;
62
+ endTime?: Date;
63
+ error?: string;
64
+ processingTimeMs?: number;
65
+ }
66
+
67
+ /**
68
+ * Central batch processing manager with integrated caching and monitoring
69
+ */
70
+ export class BatchManager extends EventEmitter {
71
+ private embeddingBatcher!: BatchingService<Memory>;
72
+ private indexingBatcher!: BatchingService<ProcessedMemory>;
73
+ private walrusBatcher!: BatchingService<ProcessedMemory>;
74
+ private cache!: MemoryProcessingCache;
75
+
76
+ private embeddingService?: EmbeddingService;
77
+ private indexService?: IHnswService;
78
+
79
+ private readonly config: Required<BatchManagerConfig>;
80
+ private jobStatuses = new Map<string, BatchJobStatus>();
81
+ private metrics = {
82
+ totalProcessingTime: 0,
83
+ averageMemoryProcessingTime: 0,
84
+ successfulBatches: 0,
85
+ failedBatches: 0,
86
+ totalMemoriesProcessed: 0
87
+ };
88
+
89
+ constructor(config: BatchManagerConfig = {}) {
90
+ super();
91
+
92
+ this.config = {
93
+ embedding: {
94
+ batchSize: config.embedding?.batchSize || 20,
95
+ delayMs: config.embedding?.delayMs || 5000
96
+ },
97
+ indexing: {
98
+ batchSize: config.indexing?.batchSize || 50,
99
+ delayMs: config.indexing?.delayMs || 3000
100
+ },
101
+ walrus: {
102
+ batchSize: config.walrus?.batchSize || 10,
103
+ delayMs: config.walrus?.delayMs || 8000
104
+ },
105
+ cache: {
106
+ maxSize: config.cache?.maxSize || 5000,
107
+ ttlMs: config.cache?.ttlMs || 60 * 60 * 1000
108
+ },
109
+ enableMetrics: config.enableMetrics !== false
110
+ };
111
+
112
+ // Initialize services
113
+ this.initializeBatchingServices();
114
+ this.cache = new MemoryProcessingCache(this.config.cache);
115
+ }
116
+
117
+ // ==================== SERVICE INITIALIZATION ====================
118
+
119
+ /**
120
+ * Initialize with required services
121
+ */
122
+ initialize(services: {
123
+ embeddingService?: EmbeddingService;
124
+ indexService?: IHnswService;
125
+ }): void {
126
+ this.embeddingService = services.embeddingService;
127
+ this.indexService = services.indexService;
128
+
129
+ console.log('BatchManager initialized with services');
130
+ }
131
+
132
+ // ==================== MEMORY PROCESSING PIPELINE ====================
133
+
134
+ /**
135
+ * Add memory to complete processing pipeline
136
+ */
137
+ async addMemoryToPipeline(
138
+ memory: Memory,
139
+ options: {
140
+ priority?: 'low' | 'normal' | 'high';
141
+ skipCache?: boolean;
142
+ immediateProcessing?: boolean;
143
+ } = {}
144
+ ): Promise<string> {
145
+ const jobId = this.generateJobId();
146
+
147
+ // Check cache first (unless skipped)
148
+ if (!options.skipCache) {
149
+ const cached = this.cache.getCachedMemory(memory.id);
150
+ if (cached?.processingState === 'completed') {
151
+ this.emit('memory:cached', { memoryId: memory.id, cached });
152
+ return jobId;
153
+ }
154
+ }
155
+
156
+ // Create job status
157
+ this.jobStatuses.set(jobId, {
158
+ id: jobId,
159
+ type: 'pipeline',
160
+ status: 'pending',
161
+ itemCount: 1,
162
+ startTime: new Date()
163
+ });
164
+
165
+ try {
166
+ // Cache memory as pending
167
+ this.cache.cacheMemory(memory);
168
+ this.cache.updateMemoryState(memory.id, 'pending');
169
+
170
+ // Add to processing pipeline
171
+ if (options.immediateProcessing) {
172
+ await this.processMemoryImmediate(memory);
173
+ } else {
174
+ // Add to embedding batch
175
+ this.embeddingBatcher.addToBatch('memories', {
176
+ id: memory.id,
177
+ data: memory,
178
+ timestamp: new Date(),
179
+ priority: this.getPriorityValue(options.priority),
180
+ metadata: { originalJobId: jobId }
181
+ });
182
+ }
183
+
184
+ this.updateJobStatus(jobId, 'processing');
185
+ this.emit('memory:queued', { memoryId: memory.id, jobId });
186
+
187
+ } catch (error) {
188
+ this.updateJobStatus(jobId, 'failed', error as Error);
189
+ this.cache.updateMemoryState(memory.id, 'failed', (error as Error).message);
190
+ throw error;
191
+ }
192
+
193
+ return jobId;
194
+ }
195
+
196
+ /**
197
+ * Process multiple memories in batch
198
+ */
199
+ async addMemoriesToPipeline(
200
+ memories: Memory[],
201
+ options: {
202
+ priority?: 'low' | 'normal' | 'high';
203
+ batchSize?: number;
204
+ } = {}
205
+ ): Promise<string[]> {
206
+ const batchSize = options.batchSize || this.config.embedding.batchSize;
207
+ const jobIds: string[] = [];
208
+
209
+ // Process in smaller batches to avoid overwhelming the system
210
+ const safeBatchSize = batchSize || 10;
211
+ for (let i = 0; i < memories.length; i += safeBatchSize) {
212
+ const batch = memories.slice(i, i + safeBatchSize);
213
+
214
+ for (const memory of batch) {
215
+ try {
216
+ const jobId = await this.addMemoryToPipeline(memory, options);
217
+ jobIds.push(jobId);
218
+ } catch (error) {
219
+ console.error(`Failed to add memory ${memory.id} to pipeline:`, error);
220
+ // Continue with other memories
221
+ }
222
+ }
223
+
224
+ // Small delay between batches
225
+ if (i + safeBatchSize < memories.length) {
226
+ await this.delay(100);
227
+ }
228
+ }
229
+
230
+ return jobIds;
231
+ }
232
+
233
+ // ==================== BATCH PROCESSING CONTROL ====================
234
+
235
+ /**
236
+ * Process all pending batches immediately
237
+ */
238
+ async processAllBatches(): Promise<void> {
239
+ console.log('Processing all pending batches...');
240
+
241
+ try {
242
+ await Promise.all([
243
+ this.embeddingBatcher.processAllBatches(),
244
+ this.indexingBatcher.processAllBatches(),
245
+ this.walrusBatcher.processAllBatches()
246
+ ]);
247
+
248
+ console.log('All batches processed successfully');
249
+ } catch (error) {
250
+ console.error('Error processing batches:', error);
251
+ throw error;
252
+ }
253
+ }
254
+
255
+ /**
256
+ * Get status of specific job
257
+ */
258
+ getJobStatus(jobId: string): BatchJobStatus | undefined {
259
+ return this.jobStatuses.get(jobId);
260
+ }
261
+
262
+ /**
263
+ * Get all job statuses
264
+ */
265
+ getAllJobStatuses(): BatchJobStatus[] {
266
+ return Array.from(this.jobStatuses.values());
267
+ }
268
+
269
+ /**
270
+ * Get pending jobs count by type
271
+ */
272
+ getPendingJobsCount(): Record<string, number> {
273
+ const counts = { embedding: 0, indexing: 0, walrus: 0, pipeline: 0 };
274
+
275
+ for (const job of this.jobStatuses.values()) {
276
+ if (job.status === 'pending' || job.status === 'processing') {
277
+ counts[job.type]++;
278
+ }
279
+ }
280
+
281
+ return counts;
282
+ }
283
+
284
+ // ==================== CACHING OPERATIONS ====================
285
+
286
+ /**
287
+ * Get cached memory
288
+ */
289
+ getCachedMemory(memoryId: string) {
290
+ return this.cache.getCachedMemory(memoryId);
291
+ }
292
+
293
+ /**
294
+ * Find similar memories
295
+ */
296
+ findSimilarMemories(memoryId: string, limit?: number) {
297
+ return this.cache.findSimilarMemories(memoryId, limit);
298
+ }
299
+
300
+ /**
301
+ * Get cache statistics
302
+ */
303
+ getCacheStats() {
304
+ return this.cache.getStats();
305
+ }
306
+
307
+ /**
308
+ * Clear all caches
309
+ */
310
+ clearCaches(): void {
311
+ this.cache.clearAll();
312
+ this.jobStatuses.clear();
313
+ }
314
+
315
+ // ==================== STATISTICS & MONITORING ====================
316
+
317
+ /**
318
+ * Get comprehensive batch manager statistics
319
+ */
320
+ getStats(): BatchManagerStats {
321
+ const embeddingStats = this.embeddingBatcher.getBatchStats();
322
+ const indexingStats = this.indexingBatcher.getBatchStats();
323
+ const walrusStats = this.walrusBatcher.getBatchStats();
324
+ const cacheStats = this.cache.getStats();
325
+
326
+ return {
327
+ // Aggregate stats
328
+ totalUsers: Math.max(embeddingStats.totalUsers, indexingStats.totalUsers, walrusStats.totalUsers),
329
+ totalPendingVectors: embeddingStats.totalPendingVectors + indexingStats.totalPendingVectors,
330
+ activeBatchJobs: embeddingStats.activeBatchJobs + indexingStats.activeBatchJobs + walrusStats.activeBatchJobs,
331
+ cacheHitRate: cacheStats.performance.hitRateMemories,
332
+ averageBatchSize: (embeddingStats.averageBatchSize + indexingStats.averageBatchSize + walrusStats.averageBatchSize) / 3,
333
+ averageProcessingTime: this.metrics.averageMemoryProcessingTime,
334
+
335
+ // Individual managers
336
+ managers: {
337
+ embedding: embeddingStats,
338
+ indexing: indexingStats,
339
+ walrus: walrusStats
340
+ },
341
+
342
+ // Cache stats
343
+ cache: cacheStats,
344
+
345
+ // Performance metrics
346
+ performance: {
347
+ totalProcessingTime: this.metrics.totalProcessingTime,
348
+ averageMemoryProcessingTime: this.metrics.averageMemoryProcessingTime,
349
+ successfulBatches: this.metrics.successfulBatches,
350
+ failedBatches: this.metrics.failedBatches
351
+ }
352
+ };
353
+ }
354
+
355
+ /**
356
+ * Cleanup and destroy batch manager
357
+ */
358
+ destroy(): void {
359
+ // Destroy all batching services
360
+ this.embeddingBatcher.destroy();
361
+ this.indexingBatcher.destroy();
362
+ this.walrusBatcher.destroy();
363
+
364
+ // Destroy cache
365
+ this.cache.destroy();
366
+
367
+ // Clear job statuses
368
+ this.jobStatuses.clear();
369
+
370
+ // Remove all listeners
371
+ this.removeAllListeners();
372
+
373
+ console.log('BatchManager destroyed');
374
+ }
375
+
376
+ // ==================== PRIVATE METHODS ====================
377
+
378
+ private initializeBatchingServices(): void {
379
+ // Initialize embedding batcher
380
+ this.embeddingBatcher = new BatchingService<Memory>(
381
+ {
382
+ maxBatchSize: this.config.embedding.batchSize,
383
+ batchDelayMs: this.config.embedding.delayMs
384
+ }
385
+ );
386
+
387
+ // Initialize indexing batcher
388
+ this.indexingBatcher = new BatchingService<ProcessedMemory>(
389
+ {
390
+ maxBatchSize: this.config.indexing.batchSize,
391
+ batchDelayMs: this.config.indexing.delayMs
392
+ }
393
+ );
394
+
395
+ // Initialize Walrus batcher
396
+ this.walrusBatcher = new BatchingService<ProcessedMemory>(
397
+ {
398
+ maxBatchSize: this.config.walrus.batchSize,
399
+ batchDelayMs: this.config.walrus.delayMs
400
+ }
401
+ );
402
+
403
+ // Register processors
404
+ this.registerBatchProcessors();
405
+ }
406
+
407
+ private registerBatchProcessors(): void {
408
+ // Embedding processor
409
+ this.embeddingBatcher.registerProcessor('memories', {
410
+ process: async (items: BatchItem<Memory>[]) => {
411
+ await this.processEmbeddingBatch(items.map(item => item.data));
412
+ }
413
+ });
414
+
415
+ // Indexing processor
416
+ this.indexingBatcher.registerProcessor('processed-memories', {
417
+ process: async (items: BatchItem<ProcessedMemory>[]) => {
418
+ await this.processIndexingBatch(items.map(item => item.data));
419
+ }
420
+ });
421
+
422
+ // Walrus processor
423
+ this.walrusBatcher.registerProcessor('walrus-uploads', {
424
+ process: async (items: BatchItem<ProcessedMemory>[]) => {
425
+ await this.processWalrusBatch(items.map(item => item.data));
426
+ }
427
+ });
428
+ }
429
+
430
+ private async processEmbeddingBatch(memories: Memory[]): Promise<void> {
431
+ if (!this.embeddingService) {
432
+ console.warn('EmbeddingService not initialized');
433
+ return;
434
+ }
435
+
436
+ console.log(`Processing embedding batch of ${memories.length} memories`);
437
+ const startTime = Date.now();
438
+
439
+ try {
440
+ // Generate embeddings in batch
441
+ const results = await this.embeddingService.embedBatch(
442
+ memories.map(m => m.content)
443
+ );
444
+
445
+ // Process results
446
+ for (let i = 0; i < memories.length; i++) {
447
+ const memory = memories[i];
448
+ const embedding = results.vectors[i];
449
+
450
+ if (embedding && embedding.length > 0) {
451
+ const processedMemory: ProcessedMemory = {
452
+ ...memory,
453
+ embedding: embedding,
454
+ embeddingModel: 'gemini-embedding',
455
+ processedAt: new Date()
456
+ };
457
+
458
+ // Update cache
459
+ this.cache.cacheMemory(memory, processedMemory);
460
+ this.cache.updateMemoryState(memory.id, 'completed');
461
+
462
+ // Add to indexing batch
463
+ this.indexingBatcher.addToBatch('processed-memories', {
464
+ id: memory.id,
465
+ data: processedMemory,
466
+ timestamp: new Date()
467
+ });
468
+
469
+ this.emit('memory:embedded', { memoryId: memory.id, embedding: embedding });
470
+ } else {
471
+ this.cache.updateMemoryState(memory.id, 'failed', 'Embedding generation failed');
472
+ this.emit('memory:embedding-failed', { memoryId: memory.id, error: 'Embedding generation failed' });
473
+ }
474
+ }
475
+
476
+ const processingTime = Date.now() - startTime;
477
+ this.updateMetrics(memories.length, processingTime, true);
478
+
479
+ } catch (error) {
480
+ console.error('Embedding batch processing failed:', error);
481
+
482
+ // Update all memories as failed
483
+ for (const memory of memories) {
484
+ this.cache.updateMemoryState(memory.id, 'failed', (error as Error).message);
485
+ }
486
+
487
+ this.updateMetrics(memories.length, Date.now() - startTime, false);
488
+ throw error;
489
+ }
490
+ }
491
+
492
+ private async processIndexingBatch(processedMemories: ProcessedMemory[]): Promise<void> {
493
+ if (!this.indexService) {
494
+ console.warn('IHnswService not initialized');
495
+ return;
496
+ }
497
+
498
+ console.log(`Processing indexing batch of ${processedMemories.length} memories`);
499
+
500
+ try {
501
+ // Add to HNSW index
502
+ for (const memory of processedMemories) {
503
+ await this.indexService.addVector(
504
+ memory.userId || 'default-user',
505
+ parseInt(memory.id) || Date.now(),
506
+ memory.embedding || [],
507
+ {
508
+ content: memory.content,
509
+ category: memory.category,
510
+ timestamp: memory.createdAt
511
+ }
512
+ );
513
+
514
+ this.emit('memory:indexed', { memoryId: memory.id });
515
+ }
516
+
517
+ // Flush pending vectors
518
+ if (this.indexService) {
519
+ await this.indexService.flushBatch('batch-operation');
520
+ }
521
+
522
+ } catch (error) {
523
+ console.error('Indexing batch processing failed:', error);
524
+ throw error;
525
+ }
526
+ }
527
+
528
+ private async processWalrusBatch(processedMemories: ProcessedMemory[]): Promise<void> {
529
+ console.log(`Processing Walrus batch of ${processedMemories.length} memories`);
530
+
531
+ try {
532
+ // TODO: Implement Walrus batch operations
533
+ // This would involve:
534
+ // 1. Batch upload processed memories to Walrus
535
+ // 2. Update Sui blockchain records
536
+ // 3. Sync with knowledge graph
537
+
538
+ for (const memory of processedMemories) {
539
+ this.emit('memory:stored', { memoryId: memory.id });
540
+ }
541
+
542
+ } catch (error) {
543
+ console.error('Walrus batch processing failed:', error);
544
+ throw error;
545
+ }
546
+ }
547
+
548
+ private async processMemoryImmediate(memory: Memory): Promise<void> {
549
+ // Process single memory immediately (bypass batching)
550
+ await this.processEmbeddingBatch([memory]);
551
+ }
552
+
553
+ private updateJobStatus(jobId: string, status: BatchJobStatus['status'], error?: Error): void {
554
+ const job = this.jobStatuses.get(jobId);
555
+ if (job) {
556
+ job.status = status;
557
+
558
+ if (status === 'completed' || status === 'failed') {
559
+ job.endTime = new Date();
560
+ job.processingTimeMs = job.endTime.getTime() - (job.startTime?.getTime() || 0);
561
+ }
562
+
563
+ if (error) {
564
+ job.error = error.message;
565
+ }
566
+
567
+ this.emit('job:status-changed', { jobId, status, error });
568
+ }
569
+ }
570
+
571
+ private updateMetrics(itemCount: number, processingTimeMs: number, success: boolean): void {
572
+ if (success) {
573
+ this.metrics.successfulBatches++;
574
+ } else {
575
+ this.metrics.failedBatches++;
576
+ }
577
+
578
+ this.metrics.totalMemoriesProcessed += itemCount;
579
+ this.metrics.totalProcessingTime += processingTimeMs;
580
+ this.metrics.averageMemoryProcessingTime =
581
+ this.metrics.totalProcessingTime / this.metrics.totalMemoriesProcessed;
582
+ }
583
+
584
+ private getPriorityValue(priority?: 'low' | 'normal' | 'high'): number {
585
+ const priorityMap = { low: 0, normal: 1, high: 2 };
586
+ return priorityMap[priority || 'normal'];
587
+ }
588
+
589
+ private generateJobId(): string {
590
+ return `job_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
591
+ }
592
+
593
+ private delay(ms: number): Promise<void> {
594
+ return new Promise(resolve => setTimeout(resolve, ms));
595
+ }
596
+ }
597
+
598
598
  export default BatchManager;