@cmdoss/memwal-sdk 0.7.0 → 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 (192) hide show
  1. package/README.md +129 -0
  2. package/dist/client/ClientMemoryManager.js +2 -2
  3. package/dist/client/ClientMemoryManager.js.map +1 -1
  4. package/dist/client/PersonalDataWallet.d.ts.map +1 -1
  5. package/dist/client/SimplePDWClient.d.ts +28 -0
  6. package/dist/client/SimplePDWClient.d.ts.map +1 -1
  7. package/dist/client/SimplePDWClient.js +29 -6
  8. package/dist/client/SimplePDWClient.js.map +1 -1
  9. package/dist/client/namespaces/MemoryNamespace.d.ts +4 -0
  10. package/dist/client/namespaces/MemoryNamespace.d.ts.map +1 -1
  11. package/dist/client/namespaces/MemoryNamespace.js +168 -39
  12. package/dist/client/namespaces/MemoryNamespace.js.map +1 -1
  13. package/dist/client/namespaces/consolidated/BlockchainNamespace.d.ts +12 -2
  14. package/dist/client/namespaces/consolidated/BlockchainNamespace.d.ts.map +1 -1
  15. package/dist/client/namespaces/consolidated/BlockchainNamespace.js +40 -2
  16. package/dist/client/namespaces/consolidated/BlockchainNamespace.js.map +1 -1
  17. package/dist/client/namespaces/consolidated/StorageNamespace.d.ts +67 -2
  18. package/dist/client/namespaces/consolidated/StorageNamespace.d.ts.map +1 -1
  19. package/dist/client/namespaces/consolidated/StorageNamespace.js +549 -16
  20. package/dist/client/namespaces/consolidated/StorageNamespace.js.map +1 -1
  21. package/dist/config/ConfigurationHelper.js +61 -61
  22. package/dist/config/defaults.js +2 -2
  23. package/dist/config/defaults.js.map +1 -1
  24. package/dist/graph/GraphService.js +20 -20
  25. package/dist/infrastructure/seal/EncryptionService.d.ts +9 -5
  26. package/dist/infrastructure/seal/EncryptionService.d.ts.map +1 -1
  27. package/dist/infrastructure/seal/EncryptionService.js +37 -15
  28. package/dist/infrastructure/seal/EncryptionService.js.map +1 -1
  29. package/dist/infrastructure/seal/SealService.d.ts +13 -5
  30. package/dist/infrastructure/seal/SealService.d.ts.map +1 -1
  31. package/dist/infrastructure/seal/SealService.js +36 -34
  32. package/dist/infrastructure/seal/SealService.js.map +1 -1
  33. package/dist/langchain/createPDWRAG.js +30 -30
  34. package/dist/retrieval/MemoryDecryptionPipeline.d.ts.map +1 -1
  35. package/dist/retrieval/MemoryDecryptionPipeline.js +2 -1
  36. package/dist/retrieval/MemoryDecryptionPipeline.js.map +1 -1
  37. package/dist/services/CapabilityService.d.ts.map +1 -1
  38. package/dist/services/CapabilityService.js +30 -14
  39. package/dist/services/CapabilityService.js.map +1 -1
  40. package/dist/services/CrossContextPermissionService.d.ts.map +1 -1
  41. package/dist/services/CrossContextPermissionService.js +9 -7
  42. package/dist/services/CrossContextPermissionService.js.map +1 -1
  43. package/dist/services/EncryptionService.d.ts.map +1 -1
  44. package/dist/services/EncryptionService.js +6 -5
  45. package/dist/services/EncryptionService.js.map +1 -1
  46. package/dist/services/GeminiAIService.js +309 -309
  47. package/dist/services/StorageService.d.ts +1 -0
  48. package/dist/services/StorageService.d.ts.map +1 -1
  49. package/dist/services/StorageService.js +60 -10
  50. package/dist/services/StorageService.js.map +1 -1
  51. package/dist/services/TransactionService.d.ts +20 -0
  52. package/dist/services/TransactionService.d.ts.map +1 -1
  53. package/dist/services/TransactionService.js +43 -0
  54. package/dist/services/TransactionService.js.map +1 -1
  55. package/dist/services/ViewService.js +2 -2
  56. package/dist/services/ViewService.js.map +1 -1
  57. package/package.json +1 -1
  58. package/src/access/PermissionService.ts +635 -635
  59. package/src/access/index.ts +8 -8
  60. package/src/aggregation/AggregationService.ts +389 -389
  61. package/src/aggregation/index.ts +8 -8
  62. package/src/ai-sdk/PDWVectorStore.ts +715 -715
  63. package/src/ai-sdk/index.ts +65 -65
  64. package/src/ai-sdk/tools.ts +460 -460
  65. package/src/ai-sdk/types.ts +404 -404
  66. package/src/batch/BatchManager.ts +597 -597
  67. package/src/batch/BatchingService.ts +429 -429
  68. package/src/batch/MemoryProcessingCache.ts +492 -492
  69. package/src/batch/index.ts +30 -30
  70. package/src/browser.ts +200 -200
  71. package/src/client/ClientMemoryManager.ts +987 -987
  72. package/src/client/PersonalDataWallet.ts +345 -345
  73. package/src/client/SimplePDWClient.ts +1289 -1237
  74. package/src/client/factory.ts +154 -154
  75. package/src/client/namespaces/AnalyticsNamespace.ts +377 -377
  76. package/src/client/namespaces/BatchNamespace.ts +356 -356
  77. package/src/client/namespaces/CacheNamespace.ts +123 -123
  78. package/src/client/namespaces/CapabilityNamespace.ts +217 -217
  79. package/src/client/namespaces/ClassifyNamespace.ts +169 -169
  80. package/src/client/namespaces/ContextNamespace.ts +297 -297
  81. package/src/client/namespaces/EmbeddingsNamespace.ts +99 -99
  82. package/src/client/namespaces/EncryptionNamespace.ts +221 -221
  83. package/src/client/namespaces/GraphNamespace.ts +468 -468
  84. package/src/client/namespaces/IndexNamespace.ts +361 -361
  85. package/src/client/namespaces/MemoryNamespace.ts +1422 -1272
  86. package/src/client/namespaces/PermissionsNamespace.ts +254 -254
  87. package/src/client/namespaces/PipelineNamespace.ts +220 -220
  88. package/src/client/namespaces/SearchNamespace.ts +1049 -1049
  89. package/src/client/namespaces/StorageNamespace.ts +458 -458
  90. package/src/client/namespaces/TxNamespace.ts +260 -260
  91. package/src/client/namespaces/WalletNamespace.ts +243 -243
  92. package/src/client/namespaces/consolidated/AINamespace.ts +449 -449
  93. package/src/client/namespaces/consolidated/BlockchainNamespace.ts +607 -564
  94. package/src/client/namespaces/consolidated/SecurityNamespace.ts +648 -648
  95. package/src/client/namespaces/consolidated/StorageNamespace.ts +1141 -497
  96. package/src/client/namespaces/consolidated/index.ts +39 -39
  97. package/src/client/signers/DappKitSigner.ts +207 -207
  98. package/src/client/signers/KeypairSigner.ts +108 -108
  99. package/src/client/signers/UnifiedSigner.ts +110 -110
  100. package/src/client/signers/WalletAdapterSigner.ts +159 -159
  101. package/src/client/signers/index.ts +26 -26
  102. package/src/config/ConfigurationHelper.ts +412 -412
  103. package/src/config/defaults.ts +51 -51
  104. package/src/config/index.ts +8 -8
  105. package/src/config/validation.ts +70 -70
  106. package/src/core/index.ts +14 -14
  107. package/src/core/interfaces/IService.ts +307 -307
  108. package/src/core/interfaces/index.ts +8 -8
  109. package/src/core/types/capability.ts +297 -297
  110. package/src/core/types/index.ts +870 -870
  111. package/src/core/types/wallet.ts +270 -270
  112. package/src/core/types.ts +9 -9
  113. package/src/core/wallet.ts +222 -222
  114. package/src/embedding/index.ts +19 -19
  115. package/src/embedding/types.ts +357 -357
  116. package/src/errors/index.ts +602 -602
  117. package/src/errors/recovery.ts +461 -461
  118. package/src/errors/validation.ts +567 -567
  119. package/src/generated/pdw/capability.ts +319 -319
  120. package/src/generated/pdw/deps/sui/object.ts +12 -12
  121. package/src/generated/pdw/deps/sui/vec_map.ts +32 -32
  122. package/src/generated/pdw/memory.ts +1087 -1087
  123. package/src/generated/pdw/wallet.ts +123 -123
  124. package/src/generated/utils/index.ts +159 -159
  125. package/src/graph/GraphService.ts +887 -887
  126. package/src/graph/KnowledgeGraphManager.ts +728 -728
  127. package/src/graph/index.ts +25 -25
  128. package/src/index.ts +498 -498
  129. package/src/infrastructure/index.ts +22 -22
  130. package/src/infrastructure/seal/EncryptionService.ts +628 -603
  131. package/src/infrastructure/seal/SealService.ts +613 -615
  132. package/src/infrastructure/seal/index.ts +9 -9
  133. package/src/infrastructure/sui/BlockchainManager.ts +627 -627
  134. package/src/infrastructure/sui/SuiService.ts +888 -888
  135. package/src/infrastructure/sui/index.ts +9 -9
  136. package/src/infrastructure/walrus/StorageManager.ts +604 -604
  137. package/src/infrastructure/walrus/WalrusStorageService.ts +612 -612
  138. package/src/infrastructure/walrus/index.ts +9 -9
  139. package/src/langchain/PDWEmbeddings.ts +145 -145
  140. package/src/langchain/PDWVectorStore.ts +456 -456
  141. package/src/langchain/createPDWRAG.ts +303 -303
  142. package/src/langchain/index.ts +47 -47
  143. package/src/permissions/ConsentRepository.browser.ts +249 -249
  144. package/src/permissions/ConsentRepository.ts +364 -364
  145. package/src/permissions/index.ts +9 -9
  146. package/src/pipeline/MemoryPipeline.ts +862 -862
  147. package/src/pipeline/PipelineManager.ts +683 -683
  148. package/src/pipeline/index.ts +26 -26
  149. package/src/retrieval/AdvancedSearchService.ts +629 -629
  150. package/src/retrieval/MemoryAnalyticsService.ts +711 -711
  151. package/src/retrieval/MemoryDecryptionPipeline.ts +825 -824
  152. package/src/retrieval/MemoryRetrievalService.ts +904 -904
  153. package/src/retrieval/index.ts +42 -42
  154. package/src/services/BatchService.ts +352 -352
  155. package/src/services/CapabilityService.ts +464 -448
  156. package/src/services/ClassifierService.ts +465 -465
  157. package/src/services/CrossContextPermissionService.ts +486 -484
  158. package/src/services/EmbeddingService.ts +771 -771
  159. package/src/services/EncryptionService.ts +712 -711
  160. package/src/services/GeminiAIService.ts +753 -753
  161. package/src/services/IndexManager.ts +977 -977
  162. package/src/services/MemoryIndexService.ts +1003 -1003
  163. package/src/services/MemoryService.ts +369 -369
  164. package/src/services/QueryService.ts +890 -890
  165. package/src/services/StorageService.ts +1182 -1126
  166. package/src/services/TransactionService.ts +838 -790
  167. package/src/services/VectorService.ts +462 -462
  168. package/src/services/ViewService.ts +484 -484
  169. package/src/services/index.ts +25 -25
  170. package/src/services/storage/BlobAttributesManager.ts +333 -333
  171. package/src/services/storage/KnowledgeGraphManager.ts +425 -425
  172. package/src/services/storage/MemorySearchManager.ts +387 -387
  173. package/src/services/storage/QuiltBatchManager.ts +1130 -1130
  174. package/src/services/storage/WalrusMetadataManager.ts +268 -268
  175. package/src/services/storage/WalrusStorageManager.ts +287 -287
  176. package/src/services/storage/index.ts +57 -57
  177. package/src/types/index.ts +13 -13
  178. package/src/utils/LRUCache.ts +378 -378
  179. package/src/utils/index.ts +76 -76
  180. package/src/utils/memoryIndexOnChain.ts +507 -507
  181. package/src/utils/rebuildIndex.ts +290 -290
  182. package/src/utils/rebuildIndexNode.ts +771 -771
  183. package/src/vector/BrowserHnswIndexService.ts +758 -758
  184. package/src/vector/HnswWasmService.ts +731 -731
  185. package/src/vector/IHnswService.ts +233 -233
  186. package/src/vector/NodeHnswService.ts +833 -833
  187. package/src/vector/VectorManager.ts +478 -478
  188. package/src/vector/createHnswService.ts +135 -135
  189. package/src/vector/index.ts +56 -56
  190. package/src/wallet/ContextWalletService.ts +656 -656
  191. package/src/wallet/MainWalletService.ts +317 -317
  192. package/src/wallet/index.ts +17 -17
@@ -1,863 +1,863 @@
1
- /**
2
- * MemoryPipeline - Unified Memory Processing Pipeline
3
- *
4
- * Orchestrates the complete memory processing workflow:
5
- * Memory Input → AI Embedding → Vector Indexing → Knowledge Graph → Walrus Storage → Sui Blockchain
6
- *
7
- * Provides comprehensive error handling, rollback capabilities, and monitoring.
8
- */
9
-
10
- import { EmbeddingService } from '../services/EmbeddingService';
11
- import { VectorManager } from '../vector/VectorManager';
12
- import { StorageService } from '../services/StorageService';
13
- import { BatchManager } from '../batch/BatchManager';
14
- import { KnowledgeGraphManager } from '../graph/KnowledgeGraphManager';
15
- import { StorageManager } from '../infrastructure/walrus/StorageManager';
16
- import { BlockchainManager } from '../infrastructure/sui/BlockchainManager';
17
- import { Memory, ProcessedMemory, MemoryPipelineConfig, MemoryPipelineResult } from '../embedding/types';
18
-
19
- export interface PipelineConfig {
20
- // Service configurations
21
- embedding?: {
22
- apiKey?: string;
23
- model?: string;
24
- enableBatching?: boolean;
25
- batchSize?: number;
26
- };
27
- vector?: {
28
- dimensions?: number;
29
- maxElements?: number;
30
- enablePersistence?: boolean;
31
- };
32
- batch?: {
33
- enableBatching?: boolean;
34
- batchSize?: number;
35
- batchDelayMs?: number;
36
- };
37
- graph?: {
38
- enableExtraction?: boolean;
39
- confidenceThreshold?: number;
40
- enableEmbeddings?: boolean;
41
- };
42
- storage?: {
43
- enableEncryption?: boolean;
44
- enableBatching?: boolean;
45
- network?: 'testnet' | 'mainnet';
46
- };
47
- blockchain?: {
48
- enableOwnershipTracking?: boolean;
49
- enableBatching?: boolean;
50
- network?: 'testnet' | 'mainnet';
51
- packageId?: string;
52
- };
53
- // Pipeline behavior
54
- enableRollback?: boolean;
55
- enableMonitoring?: boolean;
56
- skipFailedSteps?: boolean;
57
- maxRetryAttempts?: number;
58
- }
59
-
60
- export interface PipelineStep {
61
- name: string;
62
- status: 'pending' | 'processing' | 'completed' | 'failed' | 'skipped';
63
- startTime?: Date;
64
- endTime?: Date;
65
- processingTimeMs?: number;
66
- result?: any;
67
- error?: string;
68
- retryAttempts?: number;
69
- }
70
-
71
- export interface PipelineExecution {
72
- id: string;
73
- userId: string;
74
- memoryId: string;
75
- status: 'pending' | 'processing' | 'completed' | 'failed' | 'rolled_back';
76
- steps: PipelineStep[];
77
- startTime: Date;
78
- endTime?: Date;
79
- totalProcessingTime?: number;
80
- result?: ProcessedMemory;
81
- error?: string;
82
- rollbackReason?: string;
83
- }
84
-
85
- export interface PipelineMetrics {
86
- totalExecutions: number;
87
- successfulExecutions: number;
88
- failedExecutions: number;
89
- rolledBackExecutions: number;
90
- averageProcessingTime: number;
91
- stepMetrics: Record<string, {
92
- successCount: number;
93
- failureCount: number;
94
- averageProcessingTime: number;
95
- lastFailure?: string;
96
- }>;
97
- throughput: {
98
- memoriesPerHour: number;
99
- peakThroughput: number;
100
- currentLoad: number;
101
- };
102
- }
103
-
104
- export interface RollbackInfo {
105
- stepName: string;
106
- reason: string;
107
- rollbackActions: string[];
108
- completedActions: string[];
109
- failedActions: string[];
110
- }
111
-
112
- /**
113
- * Complete memory processing pipeline with orchestrated services
114
- */
115
- export class MemoryPipeline {
116
- private embeddingService!: EmbeddingService;
117
- private vectorManager!: VectorManager;
118
- private batchManager!: BatchManager;
119
- private graphManager!: KnowledgeGraphManager;
120
- private storageManager!: StorageManager;
121
- private blockchainManager!: BlockchainManager;
122
-
123
- private readonly config: Required<PipelineConfig>;
124
- private executions = new Map<string, PipelineExecution>();
125
- private metrics: PipelineMetrics = {
126
- totalExecutions: 0,
127
- successfulExecutions: 0,
128
- failedExecutions: 0,
129
- rolledBackExecutions: 0,
130
- averageProcessingTime: 0,
131
- stepMetrics: {},
132
- throughput: {
133
- memoriesPerHour: 0,
134
- peakThroughput: 0,
135
- currentLoad: 0
136
- }
137
- };
138
-
139
- private readonly PIPELINE_STEPS = [
140
- 'embedding_generation',
141
- 'vector_indexing',
142
- 'knowledge_graph_extraction',
143
- 'walrus_storage',
144
- 'blockchain_record'
145
- ];
146
-
147
- constructor(config: PipelineConfig = {}) {
148
- this.config = {
149
- embedding: {
150
- apiKey: config.embedding?.apiKey || '',
151
- model: config.embedding?.model || process.env.AI_CHAT_MODEL || 'google/gemini-2.5-flash',
152
- enableBatching: config.embedding?.enableBatching !== false,
153
- batchSize: config.embedding?.batchSize || 20
154
- },
155
- vector: {
156
- dimensions: config.vector?.dimensions || 3072,
157
- maxElements: config.vector?.maxElements || 10000,
158
- enablePersistence: config.vector?.enablePersistence !== false
159
- },
160
- batch: {
161
- enableBatching: config.batch?.enableBatching !== false,
162
- batchSize: config.batch?.batchSize || 50,
163
- batchDelayMs: config.batch?.batchDelayMs || 5000
164
- },
165
- graph: {
166
- enableExtraction: config.graph?.enableExtraction !== false,
167
- confidenceThreshold: config.graph?.confidenceThreshold || 0.7,
168
- enableEmbeddings: config.graph?.enableEmbeddings !== false
169
- },
170
- storage: {
171
- enableEncryption: config.storage?.enableEncryption !== false,
172
- enableBatching: config.storage?.enableBatching !== false,
173
- network: config.storage?.network || 'testnet'
174
- },
175
- blockchain: {
176
- enableOwnershipTracking: config.blockchain?.enableOwnershipTracking !== false,
177
- enableBatching: config.blockchain?.enableBatching !== false,
178
- network: config.blockchain?.network || 'testnet',
179
- packageId: config.blockchain?.packageId
180
- },
181
- enableRollback: config.enableRollback !== false,
182
- enableMonitoring: config.enableMonitoring !== false,
183
- skipFailedSteps: config.skipFailedSteps || false,
184
- maxRetryAttempts: config.maxRetryAttempts || 3
185
- };
186
-
187
- this.initializeServices();
188
- this.initializeStepMetrics();
189
- }
190
-
191
- // ==================== PIPELINE EXECUTION ====================
192
-
193
- /**
194
- * Process memory through complete pipeline
195
- */
196
- async processMemory(
197
- memory: Memory,
198
- userId: string,
199
- options: {
200
- skipSteps?: string[];
201
- priority?: 'low' | 'normal' | 'high';
202
- enableRollback?: boolean;
203
- customMetadata?: Record<string, string>;
204
- } = {}
205
- ): Promise<PipelineExecution> {
206
- const executionId = this.generateExecutionId();
207
-
208
- // Create execution record
209
- const execution: PipelineExecution = {
210
- id: executionId,
211
- userId,
212
- memoryId: memory.id,
213
- status: 'pending',
214
- steps: this.initializeSteps(options.skipSteps),
215
- startTime: new Date()
216
- };
217
-
218
- this.executions.set(executionId, execution);
219
- this.metrics.totalExecutions++;
220
-
221
- try {
222
- execution.status = 'processing';
223
- console.log(`🔄 Starting pipeline execution for memory: ${memory.id}`);
224
-
225
- let processedMemory: ProcessedMemory = {
226
- ...memory,
227
- processedAt: new Date()
228
- };
229
-
230
- // Step 1: Embedding Generation
231
- if (this.shouldExecuteStep('embedding_generation', options.skipSteps)) {
232
- processedMemory = await this.executeEmbeddingStep(execution, processedMemory);
233
- }
234
-
235
- // Step 2: Vector Indexing
236
- if (this.shouldExecuteStep('vector_indexing', options.skipSteps)) {
237
- processedMemory = await this.executeVectorIndexingStep(execution, processedMemory);
238
- }
239
-
240
- // Step 3: Knowledge Graph Extraction
241
- if (this.shouldExecuteStep('knowledge_graph_extraction', options.skipSteps)) {
242
- processedMemory = await this.executeKnowledgeGraphStep(execution, processedMemory, userId);
243
- }
244
-
245
- // Step 4: Walrus Storage
246
- if (this.shouldExecuteStep('walrus_storage', options.skipSteps)) {
247
- processedMemory = await this.executeStorageStep(execution, processedMemory, userId, options);
248
- }
249
-
250
- // Step 5: Blockchain Record
251
- if (this.shouldExecuteStep('blockchain_record', options.skipSteps)) {
252
- processedMemory = await this.executeBlockchainStep(execution, processedMemory, userId, options);
253
- }
254
-
255
- // Pipeline completed successfully
256
- execution.status = 'completed';
257
- execution.endTime = new Date();
258
- execution.totalProcessingTime = execution.endTime.getTime() - execution.startTime.getTime();
259
- execution.result = processedMemory;
260
-
261
- this.metrics.successfulExecutions++;
262
- this.updateThroughputMetrics();
263
- this.updateAverageProcessingTime(execution.totalProcessingTime);
264
-
265
- console.log(`✅ Pipeline completed successfully for memory: ${memory.id} (${execution.totalProcessingTime}ms)`);
266
-
267
- return execution;
268
-
269
- } catch (error) {
270
- console.error(`❌ Pipeline failed for memory: ${memory.id}`, error);
271
-
272
- execution.status = 'failed';
273
- execution.error = error instanceof Error ? error.message : String(error);
274
- execution.endTime = new Date();
275
-
276
- // Attempt rollback if enabled
277
- if (options.enableRollback !== false && this.config.enableRollback) {
278
- await this.attemptRollback(execution);
279
- }
280
-
281
- this.metrics.failedExecutions++;
282
-
283
- return execution;
284
- }
285
- }
286
-
287
- /**
288
- * Process multiple memories in batch
289
- */
290
- async processMemoriesBatch(
291
- memories: Memory[],
292
- userId: string,
293
- options: {
294
- batchSize?: number;
295
- skipSteps?: string[];
296
- priority?: 'low' | 'normal' | 'high';
297
- onProgress?: (completed: number, total: number, current?: PipelineExecution) => void;
298
- enableParallel?: boolean;
299
- } = {}
300
- ): Promise<PipelineExecution[]> {
301
- const batchSize = options.batchSize || 5;
302
- const results: PipelineExecution[] = [];
303
-
304
- console.log(`🔄 Starting batch processing of ${memories.length} memories`);
305
-
306
- if (options.enableParallel) {
307
- // Process all memories in parallel (use with caution for large batches)
308
- const promises = memories.map(memory =>
309
- this.processMemory(memory, userId, {
310
- skipSteps: options.skipSteps,
311
- priority: options.priority
312
- })
313
- );
314
-
315
- const batchResults = await Promise.allSettled(promises);
316
-
317
- for (const result of batchResults) {
318
- if (result.status === 'fulfilled') {
319
- results.push(result.value);
320
- } else {
321
- console.error('Batch memory processing failed:', result.reason);
322
- }
323
- }
324
- } else {
325
- // Process in sequential batches
326
- for (let i = 0; i < memories.length; i += batchSize) {
327
- const batch = memories.slice(i, i + batchSize);
328
-
329
- for (const memory of batch) {
330
- try {
331
- const execution = await this.processMemory(memory, userId, {
332
- skipSteps: options.skipSteps,
333
- priority: options.priority
334
- });
335
-
336
- results.push(execution);
337
-
338
- // Progress callback
339
- if (options.onProgress) {
340
- options.onProgress(results.length, memories.length, execution);
341
- }
342
- } catch (error) {
343
- console.error(`Failed to process memory ${memory.id}:`, error);
344
- }
345
- }
346
-
347
- // Small delay between batches to prevent overwhelming
348
- if (i + batchSize < memories.length) {
349
- await this.delay(100);
350
- }
351
- }
352
- }
353
-
354
- console.log(`✅ Batch processing completed: ${results.filter(r => r.status === 'completed').length}/${memories.length} successful`);
355
-
356
- return results;
357
- }
358
-
359
- // ==================== PIPELINE MONITORING ====================
360
-
361
- /**
362
- * Get execution status
363
- */
364
- getExecutionStatus(executionId: string): PipelineExecution | null {
365
- return this.executions.get(executionId) || null;
366
- }
367
-
368
- /**
369
- * Get all executions for user
370
- */
371
- getUserExecutions(userId: string): PipelineExecution[] {
372
- return Array.from(this.executions.values())
373
- .filter(execution => execution.userId === userId);
374
- }
375
-
376
- /**
377
- * Get pipeline metrics
378
- */
379
- getPipelineMetrics(): PipelineMetrics {
380
- return { ...this.metrics };
381
- }
382
-
383
- /**
384
- * Get active executions
385
- */
386
- getActiveExecutions(): PipelineExecution[] {
387
- return Array.from(this.executions.values())
388
- .filter(execution => execution.status === 'processing');
389
- }
390
-
391
- /**
392
- * Get failed executions
393
- */
394
- getFailedExecutions(limit?: number): PipelineExecution[] {
395
- const failed = Array.from(this.executions.values())
396
- .filter(execution => execution.status === 'failed')
397
- .sort((a, b) => b.startTime.getTime() - a.startTime.getTime());
398
-
399
- return limit ? failed.slice(0, limit) : failed;
400
- }
401
-
402
- // ==================== PIPELINE MANAGEMENT ====================
403
-
404
- /**
405
- * Retry failed execution
406
- */
407
- async retryExecution(executionId: string): Promise<PipelineExecution | null> {
408
- const execution = this.executions.get(executionId);
409
- if (!execution || execution.status !== 'failed') {
410
- return null;
411
- }
412
-
413
- // Find the failed step and retry from there
414
- const failedStepIndex = execution.steps.findIndex(step => step.status === 'failed');
415
- if (failedStepIndex === -1) {
416
- return null;
417
- }
418
-
419
- // Reset steps from failed point
420
- for (let i = failedStepIndex; i < execution.steps.length; i++) {
421
- execution.steps[i].status = 'pending';
422
- execution.steps[i].error = undefined;
423
- execution.steps[i].retryAttempts = (execution.steps[i].retryAttempts || 0) + 1;
424
- }
425
-
426
- // Retry execution (simplified - in production, implement proper retry logic)
427
- console.log(`🔄 Retrying execution ${executionId} from step: ${execution.steps[failedStepIndex].name}`);
428
-
429
- return execution;
430
- }
431
-
432
- /**
433
- * Cancel active execution
434
- */
435
- async cancelExecution(executionId: string): Promise<boolean> {
436
- const execution = this.executions.get(executionId);
437
- if (!execution || execution.status !== 'processing') {
438
- return false;
439
- }
440
-
441
- execution.status = 'failed';
442
- execution.error = 'Execution cancelled by user';
443
- execution.endTime = new Date();
444
-
445
- console.log(`⏹️ Cancelled execution: ${executionId}`);
446
- return true;
447
- }
448
-
449
- /**
450
- * Clear completed executions
451
- */
452
- clearCompletedExecutions(): number {
453
- const beforeSize = this.executions.size;
454
-
455
- for (const [id, execution] of this.executions.entries()) {
456
- if (execution.status === 'completed' || execution.status === 'failed') {
457
- this.executions.delete(id);
458
- }
459
- }
460
-
461
- const cleared = beforeSize - this.executions.size;
462
- console.log(`🧹 Cleared ${cleared} completed/failed executions`);
463
-
464
- return cleared;
465
- }
466
-
467
- /**
468
- * Get pipeline health status
469
- */
470
- getPipelineHealth(): {
471
- status: 'healthy' | 'degraded' | 'critical';
472
- activeExecutions: number;
473
- successRate: number;
474
- averageProcessingTime: number;
475
- issues: string[];
476
- } {
477
- const successRate = this.metrics.totalExecutions > 0
478
- ? this.metrics.successfulExecutions / this.metrics.totalExecutions
479
- : 1;
480
-
481
- const issues: string[] = [];
482
- let status: 'healthy' | 'degraded' | 'critical' = 'healthy';
483
-
484
- // Check success rate
485
- if (successRate < 0.8) {
486
- issues.push('Low success rate detected');
487
- status = 'degraded';
488
- }
489
- if (successRate < 0.5) {
490
- status = 'critical';
491
- }
492
-
493
- // Check processing time
494
- if (this.metrics.averageProcessingTime > 30000) { // 30 seconds
495
- issues.push('High average processing time');
496
- if (status === 'healthy') status = 'degraded';
497
- }
498
-
499
- // Check active executions
500
- const activeCount = this.getActiveExecutions().length;
501
- if (activeCount > 20) {
502
- issues.push('High number of active executions');
503
- if (status === 'healthy') status = 'degraded';
504
- }
505
-
506
- return {
507
- status,
508
- activeExecutions: activeCount,
509
- successRate,
510
- averageProcessingTime: this.metrics.averageProcessingTime,
511
- issues
512
- };
513
- }
514
-
515
- // ==================== PRIVATE METHODS ====================
516
-
517
- private initializeServices(): void {
518
- // Initialize all services with configurations
519
- this.embeddingService = new EmbeddingService({
520
- apiKey: this.config.embedding.apiKey,
521
- model: this.config.embedding.model,
522
- requestsPerMinute: 60
523
- });
524
-
525
- this.vectorManager = new VectorManager({
526
- embedding: { apiKey: '' },
527
- index: {
528
- dimension: this.config.vector.dimensions,
529
- maxElements: this.config.vector.maxElements
530
- },
531
- batch: { maxBatchSize: 10 }
532
- });
533
-
534
- this.batchManager = new BatchManager({
535
- embedding: {
536
- batchSize: this.config.batch.batchSize,
537
- delayMs: this.config.batch.batchDelayMs
538
- },
539
- enableMetrics: this.config.enableMonitoring
540
- });
541
-
542
- this.graphManager = new KnowledgeGraphManager();
543
-
544
- this.storageManager = new StorageManager({
545
- walrusConfig: {
546
- network: this.config.storage.network,
547
- enableEncryption: this.config.storage.enableEncryption,
548
- enableBatching: this.config.storage.enableBatching
549
- }
550
- });
551
-
552
- this.blockchainManager = new BlockchainManager({
553
- suiConfig: {
554
- network: this.config.blockchain.network,
555
- packageId: this.config.blockchain.packageId,
556
- enableBatching: this.config.blockchain.enableBatching
557
- }
558
- });
559
-
560
- // Initialize batch manager with services
561
- this.batchManager.initialize({
562
- embeddingService: this.embeddingService,
563
- indexService: this.vectorManager['indexService'] ?? undefined // Access private member
564
- });
565
- }
566
-
567
- private initializeSteps(skipSteps?: string[]): PipelineStep[] {
568
- return this.PIPELINE_STEPS.map(stepName => ({
569
- name: stepName,
570
- status: skipSteps?.includes(stepName) ? 'skipped' : 'pending'
571
- }));
572
- }
573
-
574
- private initializeStepMetrics(): void {
575
- for (const stepName of this.PIPELINE_STEPS) {
576
- this.metrics.stepMetrics[stepName] = {
577
- successCount: 0,
578
- failureCount: 0,
579
- averageProcessingTime: 0,
580
- };
581
- }
582
- }
583
-
584
- private shouldExecuteStep(stepName: string, skipSteps?: string[]): boolean {
585
- return !skipSteps?.includes(stepName);
586
- }
587
-
588
- private async executeEmbeddingStep(
589
- execution: PipelineExecution,
590
- memory: ProcessedMemory
591
- ): Promise<ProcessedMemory> {
592
- const step = this.findStep(execution, 'embedding_generation');
593
- return this.executeStep(step, async () => {
594
- console.log(`📊 Generating embedding for memory: ${memory.id}`);
595
-
596
- const result = await this.embeddingService.embedText({
597
- text: memory.content,
598
- type: 'content'
599
- });
600
-
601
- if (!result.vector) {
602
- throw new Error('Embedding generation failed: No vector returned');
603
- }
604
-
605
- return {
606
- ...memory,
607
- embedding: result.vector,
608
- embeddingModel: 'gemini-embedding'
609
- };
610
- });
611
- }
612
-
613
- private async executeVectorIndexingStep(
614
- execution: PipelineExecution,
615
- memory: ProcessedMemory
616
- ): Promise<ProcessedMemory> {
617
- const step = this.findStep(execution, 'vector_indexing');
618
- return this.executeStep(step, async () => {
619
- console.log(`🔍 Adding to vector index: ${memory.id}`);
620
-
621
- if (!memory.embedding) {
622
- throw new Error('No embedding available for indexing');
623
- }
624
-
625
- const vectorResult = await this.vectorManager.addTextToIndex(
626
- memory.userId || 'default-user',
627
- memory.content,
628
- {
629
- vectorId: parseInt(memory.id) || Date.now(),
630
- metadata: {
631
- content: memory.content,
632
- category: memory.category,
633
- timestamp: memory.createdAt
634
- }
635
- }
636
- );
637
-
638
- const vectorId = vectorResult.vectorId;
639
-
640
- return {
641
- ...memory,
642
- vectorId
643
- };
644
- });
645
- }
646
-
647
- private async executeKnowledgeGraphStep(
648
- execution: PipelineExecution,
649
- memory: ProcessedMemory,
650
- userId: string
651
- ): Promise<ProcessedMemory> {
652
- const step = this.findStep(execution, 'knowledge_graph_extraction');
653
- return this.executeStep(step, async () => {
654
- console.log(`🧠 Extracting knowledge graph for memory: ${memory.id}`);
655
-
656
- const result = await this.graphManager.processMemoryForGraph(memory, userId, {
657
- confidenceThreshold: this.config.graph.confidenceThreshold
658
- });
659
-
660
- if (!result.success) {
661
- console.warn(`Knowledge graph extraction failed: ${result.error}`);
662
- // Non-critical failure, continue pipeline
663
- }
664
-
665
- return memory;
666
- });
667
- }
668
-
669
- private async executeStorageStep(
670
- execution: PipelineExecution,
671
- memory: ProcessedMemory,
672
- userId: string,
673
- options: any
674
- ): Promise<ProcessedMemory> {
675
- const step = this.findStep(execution, 'walrus_storage');
676
- return this.executeStep(step, async () => {
677
- console.log(`💾 Storing memory on Walrus: ${memory.id}`);
678
-
679
- const result = await this.storageManager.storeMemory(memory, userId, {
680
- enableEncryption: this.config.storage.enableEncryption,
681
- customMetadata: options.customMetadata
682
- });
683
-
684
- if (!result.success) {
685
- throw new Error(`Storage failed: ${result.error}`);
686
- }
687
-
688
- return {
689
- ...memory,
690
- blobId: result.blobId
691
- };
692
- });
693
- }
694
-
695
- private async executeBlockchainStep(
696
- execution: PipelineExecution,
697
- memory: ProcessedMemory,
698
- userId: string,
699
- options: any
700
- ): Promise<ProcessedMemory> {
701
- const step = this.findStep(execution, 'blockchain_record');
702
- return this.executeStep(step, async () => {
703
- console.log(`⛓️ Creating blockchain record for memory: ${memory.id}`);
704
-
705
- const ownershipRecord = await this.blockchainManager.createMemoryRecord(
706
- memory,
707
- userId,
708
- {
709
- enableBatching: this.config.blockchain.enableBatching,
710
- customMetadata: options.customMetadata
711
- }
712
- );
713
-
714
- return {
715
- ...memory,
716
- blockchainRecordId: ownershipRecord.blockchainRecordId
717
- };
718
- });
719
- }
720
-
721
- private async executeStep<T>(
722
- step: PipelineStep,
723
- operation: () => Promise<T>
724
- ): Promise<T> {
725
- step.status = 'processing';
726
- step.startTime = new Date();
727
-
728
- try {
729
- const result = await operation();
730
-
731
- step.status = 'completed';
732
- step.endTime = new Date();
733
- step.processingTimeMs = step.endTime.getTime() - step.startTime.getTime();
734
- step.result = result;
735
-
736
- // Update metrics
737
- const stepMetric = this.metrics.stepMetrics[step.name];
738
- if (stepMetric) {
739
- stepMetric.successCount++;
740
- stepMetric.averageProcessingTime =
741
- (stepMetric.averageProcessingTime + step.processingTimeMs) / stepMetric.successCount;
742
- }
743
-
744
- return result;
745
-
746
- } catch (error) {
747
- step.status = 'failed';
748
- step.endTime = new Date();
749
- step.processingTimeMs = step.endTime!.getTime() - step.startTime.getTime();
750
- step.error = error instanceof Error ? error.message : String(error);
751
-
752
- // Update metrics
753
- const stepMetric = this.metrics.stepMetrics[step.name];
754
- if (stepMetric) {
755
- stepMetric.failureCount++;
756
- stepMetric.lastFailure = step.error;
757
- }
758
-
759
- throw error;
760
- }
761
- }
762
-
763
- private findStep(execution: PipelineExecution, stepName: string): PipelineStep {
764
- const step = execution.steps.find(s => s.name === stepName);
765
- if (!step) {
766
- throw new Error(`Step not found: ${stepName}`);
767
- }
768
- return step;
769
- }
770
-
771
- private async attemptRollback(execution: PipelineExecution): Promise<void> {
772
- console.log(`🔄 Attempting rollback for execution: ${execution.id}`);
773
-
774
- try {
775
- // Find completed steps that need rollback
776
- const completedSteps = execution.steps.filter(step => step.status === 'completed');
777
-
778
- // Rollback in reverse order
779
- for (let i = completedSteps.length - 1; i >= 0; i--) {
780
- const step = completedSteps[i];
781
- await this.rollbackStep(step);
782
- }
783
-
784
- execution.status = 'rolled_back';
785
- execution.rollbackReason = execution.error;
786
- this.metrics.rolledBackExecutions++;
787
-
788
- console.log(`✅ Rollback completed for execution: ${execution.id}`);
789
-
790
- } catch (rollbackError) {
791
- console.error(`❌ Rollback failed for execution: ${execution.id}`, rollbackError);
792
- // Execution remains in failed state
793
- }
794
- }
795
-
796
- private async rollbackStep(step: PipelineStep): Promise<void> {
797
- console.log(`🔙 Rolling back step: ${step.name}`);
798
-
799
- // Implement step-specific rollback logic
800
- try {
801
- switch (step.name) {
802
- case 'walrus_storage':
803
- // Delete stored blob if possible
804
- if (step.result?.blobId) {
805
- await this.storageManager.deleteMemory(step.result.blobId);
806
- }
807
- break;
808
-
809
- case 'blockchain_record':
810
- // Cannot rollback blockchain transactions, but mark as noted
811
- console.log(`⚠️ Cannot rollback blockchain transaction for step: ${step.name}`);
812
- break;
813
-
814
- default:
815
- // Most steps don't require explicit rollback
816
- break;
817
- }
818
-
819
- console.log(`✅ Rollback completed for step: ${step.name}`);
820
-
821
- } catch (error) {
822
- console.error(`❌ Rollback failed for step: ${step.name}`, error);
823
- throw error;
824
- }
825
- }
826
-
827
- private updateThroughputMetrics(): void {
828
- // Calculate memories per hour based on recent completions
829
- const now = Date.now();
830
- const oneHourAgo = now - (60 * 60 * 1000);
831
-
832
- const recentCompletions = Array.from(this.executions.values())
833
- .filter(exec =>
834
- exec.status === 'completed' &&
835
- exec.endTime &&
836
- exec.endTime.getTime() > oneHourAgo
837
- );
838
-
839
- this.metrics.throughput.memoriesPerHour = recentCompletions.length;
840
- this.metrics.throughput.currentLoad = this.getActiveExecutions().length;
841
-
842
- // Update peak if current is higher
843
- if (recentCompletions.length > this.metrics.throughput.peakThroughput) {
844
- this.metrics.throughput.peakThroughput = recentCompletions.length;
845
- }
846
- }
847
-
848
- private updateAverageProcessingTime(processingTime: number): void {
849
- const totalSuccessful = this.metrics.successfulExecutions;
850
- this.metrics.averageProcessingTime =
851
- (this.metrics.averageProcessingTime * (totalSuccessful - 1) + processingTime) / totalSuccessful;
852
- }
853
-
854
- private generateExecutionId(): string {
855
- return `exec_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`;
856
- }
857
-
858
- private delay(ms: number): Promise<void> {
859
- return new Promise(resolve => setTimeout(resolve, ms));
860
- }
861
- }
862
-
1
+ /**
2
+ * MemoryPipeline - Unified Memory Processing Pipeline
3
+ *
4
+ * Orchestrates the complete memory processing workflow:
5
+ * Memory Input → AI Embedding → Vector Indexing → Knowledge Graph → Walrus Storage → Sui Blockchain
6
+ *
7
+ * Provides comprehensive error handling, rollback capabilities, and monitoring.
8
+ */
9
+
10
+ import { EmbeddingService } from '../services/EmbeddingService';
11
+ import { VectorManager } from '../vector/VectorManager';
12
+ import { StorageService } from '../services/StorageService';
13
+ import { BatchManager } from '../batch/BatchManager';
14
+ import { KnowledgeGraphManager } from '../graph/KnowledgeGraphManager';
15
+ import { StorageManager } from '../infrastructure/walrus/StorageManager';
16
+ import { BlockchainManager } from '../infrastructure/sui/BlockchainManager';
17
+ import { Memory, ProcessedMemory, MemoryPipelineConfig, MemoryPipelineResult } from '../embedding/types';
18
+
19
+ export interface PipelineConfig {
20
+ // Service configurations
21
+ embedding?: {
22
+ apiKey?: string;
23
+ model?: string;
24
+ enableBatching?: boolean;
25
+ batchSize?: number;
26
+ };
27
+ vector?: {
28
+ dimensions?: number;
29
+ maxElements?: number;
30
+ enablePersistence?: boolean;
31
+ };
32
+ batch?: {
33
+ enableBatching?: boolean;
34
+ batchSize?: number;
35
+ batchDelayMs?: number;
36
+ };
37
+ graph?: {
38
+ enableExtraction?: boolean;
39
+ confidenceThreshold?: number;
40
+ enableEmbeddings?: boolean;
41
+ };
42
+ storage?: {
43
+ enableEncryption?: boolean;
44
+ enableBatching?: boolean;
45
+ network?: 'testnet' | 'mainnet';
46
+ };
47
+ blockchain?: {
48
+ enableOwnershipTracking?: boolean;
49
+ enableBatching?: boolean;
50
+ network?: 'testnet' | 'mainnet';
51
+ packageId?: string;
52
+ };
53
+ // Pipeline behavior
54
+ enableRollback?: boolean;
55
+ enableMonitoring?: boolean;
56
+ skipFailedSteps?: boolean;
57
+ maxRetryAttempts?: number;
58
+ }
59
+
60
+ export interface PipelineStep {
61
+ name: string;
62
+ status: 'pending' | 'processing' | 'completed' | 'failed' | 'skipped';
63
+ startTime?: Date;
64
+ endTime?: Date;
65
+ processingTimeMs?: number;
66
+ result?: any;
67
+ error?: string;
68
+ retryAttempts?: number;
69
+ }
70
+
71
+ export interface PipelineExecution {
72
+ id: string;
73
+ userId: string;
74
+ memoryId: string;
75
+ status: 'pending' | 'processing' | 'completed' | 'failed' | 'rolled_back';
76
+ steps: PipelineStep[];
77
+ startTime: Date;
78
+ endTime?: Date;
79
+ totalProcessingTime?: number;
80
+ result?: ProcessedMemory;
81
+ error?: string;
82
+ rollbackReason?: string;
83
+ }
84
+
85
+ export interface PipelineMetrics {
86
+ totalExecutions: number;
87
+ successfulExecutions: number;
88
+ failedExecutions: number;
89
+ rolledBackExecutions: number;
90
+ averageProcessingTime: number;
91
+ stepMetrics: Record<string, {
92
+ successCount: number;
93
+ failureCount: number;
94
+ averageProcessingTime: number;
95
+ lastFailure?: string;
96
+ }>;
97
+ throughput: {
98
+ memoriesPerHour: number;
99
+ peakThroughput: number;
100
+ currentLoad: number;
101
+ };
102
+ }
103
+
104
+ export interface RollbackInfo {
105
+ stepName: string;
106
+ reason: string;
107
+ rollbackActions: string[];
108
+ completedActions: string[];
109
+ failedActions: string[];
110
+ }
111
+
112
+ /**
113
+ * Complete memory processing pipeline with orchestrated services
114
+ */
115
+ export class MemoryPipeline {
116
+ private embeddingService!: EmbeddingService;
117
+ private vectorManager!: VectorManager;
118
+ private batchManager!: BatchManager;
119
+ private graphManager!: KnowledgeGraphManager;
120
+ private storageManager!: StorageManager;
121
+ private blockchainManager!: BlockchainManager;
122
+
123
+ private readonly config: Required<PipelineConfig>;
124
+ private executions = new Map<string, PipelineExecution>();
125
+ private metrics: PipelineMetrics = {
126
+ totalExecutions: 0,
127
+ successfulExecutions: 0,
128
+ failedExecutions: 0,
129
+ rolledBackExecutions: 0,
130
+ averageProcessingTime: 0,
131
+ stepMetrics: {},
132
+ throughput: {
133
+ memoriesPerHour: 0,
134
+ peakThroughput: 0,
135
+ currentLoad: 0
136
+ }
137
+ };
138
+
139
+ private readonly PIPELINE_STEPS = [
140
+ 'embedding_generation',
141
+ 'vector_indexing',
142
+ 'knowledge_graph_extraction',
143
+ 'walrus_storage',
144
+ 'blockchain_record'
145
+ ];
146
+
147
+ constructor(config: PipelineConfig = {}) {
148
+ this.config = {
149
+ embedding: {
150
+ apiKey: config.embedding?.apiKey || '',
151
+ model: config.embedding?.model || process.env.AI_CHAT_MODEL || 'google/gemini-2.5-flash',
152
+ enableBatching: config.embedding?.enableBatching !== false,
153
+ batchSize: config.embedding?.batchSize || 20
154
+ },
155
+ vector: {
156
+ dimensions: config.vector?.dimensions || 3072,
157
+ maxElements: config.vector?.maxElements || 10000,
158
+ enablePersistence: config.vector?.enablePersistence !== false
159
+ },
160
+ batch: {
161
+ enableBatching: config.batch?.enableBatching !== false,
162
+ batchSize: config.batch?.batchSize || 50,
163
+ batchDelayMs: config.batch?.batchDelayMs || 5000
164
+ },
165
+ graph: {
166
+ enableExtraction: config.graph?.enableExtraction !== false,
167
+ confidenceThreshold: config.graph?.confidenceThreshold || 0.7,
168
+ enableEmbeddings: config.graph?.enableEmbeddings !== false
169
+ },
170
+ storage: {
171
+ enableEncryption: config.storage?.enableEncryption !== false,
172
+ enableBatching: config.storage?.enableBatching !== false,
173
+ network: config.storage?.network || 'testnet'
174
+ },
175
+ blockchain: {
176
+ enableOwnershipTracking: config.blockchain?.enableOwnershipTracking !== false,
177
+ enableBatching: config.blockchain?.enableBatching !== false,
178
+ network: config.blockchain?.network || 'testnet',
179
+ packageId: config.blockchain?.packageId
180
+ },
181
+ enableRollback: config.enableRollback !== false,
182
+ enableMonitoring: config.enableMonitoring !== false,
183
+ skipFailedSteps: config.skipFailedSteps || false,
184
+ maxRetryAttempts: config.maxRetryAttempts || 3
185
+ };
186
+
187
+ this.initializeServices();
188
+ this.initializeStepMetrics();
189
+ }
190
+
191
+ // ==================== PIPELINE EXECUTION ====================
192
+
193
+ /**
194
+ * Process memory through complete pipeline
195
+ */
196
+ async processMemory(
197
+ memory: Memory,
198
+ userId: string,
199
+ options: {
200
+ skipSteps?: string[];
201
+ priority?: 'low' | 'normal' | 'high';
202
+ enableRollback?: boolean;
203
+ customMetadata?: Record<string, string>;
204
+ } = {}
205
+ ): Promise<PipelineExecution> {
206
+ const executionId = this.generateExecutionId();
207
+
208
+ // Create execution record
209
+ const execution: PipelineExecution = {
210
+ id: executionId,
211
+ userId,
212
+ memoryId: memory.id,
213
+ status: 'pending',
214
+ steps: this.initializeSteps(options.skipSteps),
215
+ startTime: new Date()
216
+ };
217
+
218
+ this.executions.set(executionId, execution);
219
+ this.metrics.totalExecutions++;
220
+
221
+ try {
222
+ execution.status = 'processing';
223
+ console.log(`🔄 Starting pipeline execution for memory: ${memory.id}`);
224
+
225
+ let processedMemory: ProcessedMemory = {
226
+ ...memory,
227
+ processedAt: new Date()
228
+ };
229
+
230
+ // Step 1: Embedding Generation
231
+ if (this.shouldExecuteStep('embedding_generation', options.skipSteps)) {
232
+ processedMemory = await this.executeEmbeddingStep(execution, processedMemory);
233
+ }
234
+
235
+ // Step 2: Vector Indexing
236
+ if (this.shouldExecuteStep('vector_indexing', options.skipSteps)) {
237
+ processedMemory = await this.executeVectorIndexingStep(execution, processedMemory);
238
+ }
239
+
240
+ // Step 3: Knowledge Graph Extraction
241
+ if (this.shouldExecuteStep('knowledge_graph_extraction', options.skipSteps)) {
242
+ processedMemory = await this.executeKnowledgeGraphStep(execution, processedMemory, userId);
243
+ }
244
+
245
+ // Step 4: Walrus Storage
246
+ if (this.shouldExecuteStep('walrus_storage', options.skipSteps)) {
247
+ processedMemory = await this.executeStorageStep(execution, processedMemory, userId, options);
248
+ }
249
+
250
+ // Step 5: Blockchain Record
251
+ if (this.shouldExecuteStep('blockchain_record', options.skipSteps)) {
252
+ processedMemory = await this.executeBlockchainStep(execution, processedMemory, userId, options);
253
+ }
254
+
255
+ // Pipeline completed successfully
256
+ execution.status = 'completed';
257
+ execution.endTime = new Date();
258
+ execution.totalProcessingTime = execution.endTime.getTime() - execution.startTime.getTime();
259
+ execution.result = processedMemory;
260
+
261
+ this.metrics.successfulExecutions++;
262
+ this.updateThroughputMetrics();
263
+ this.updateAverageProcessingTime(execution.totalProcessingTime);
264
+
265
+ console.log(`✅ Pipeline completed successfully for memory: ${memory.id} (${execution.totalProcessingTime}ms)`);
266
+
267
+ return execution;
268
+
269
+ } catch (error) {
270
+ console.error(`❌ Pipeline failed for memory: ${memory.id}`, error);
271
+
272
+ execution.status = 'failed';
273
+ execution.error = error instanceof Error ? error.message : String(error);
274
+ execution.endTime = new Date();
275
+
276
+ // Attempt rollback if enabled
277
+ if (options.enableRollback !== false && this.config.enableRollback) {
278
+ await this.attemptRollback(execution);
279
+ }
280
+
281
+ this.metrics.failedExecutions++;
282
+
283
+ return execution;
284
+ }
285
+ }
286
+
287
+ /**
288
+ * Process multiple memories in batch
289
+ */
290
+ async processMemoriesBatch(
291
+ memories: Memory[],
292
+ userId: string,
293
+ options: {
294
+ batchSize?: number;
295
+ skipSteps?: string[];
296
+ priority?: 'low' | 'normal' | 'high';
297
+ onProgress?: (completed: number, total: number, current?: PipelineExecution) => void;
298
+ enableParallel?: boolean;
299
+ } = {}
300
+ ): Promise<PipelineExecution[]> {
301
+ const batchSize = options.batchSize || 5;
302
+ const results: PipelineExecution[] = [];
303
+
304
+ console.log(`🔄 Starting batch processing of ${memories.length} memories`);
305
+
306
+ if (options.enableParallel) {
307
+ // Process all memories in parallel (use with caution for large batches)
308
+ const promises = memories.map(memory =>
309
+ this.processMemory(memory, userId, {
310
+ skipSteps: options.skipSteps,
311
+ priority: options.priority
312
+ })
313
+ );
314
+
315
+ const batchResults = await Promise.allSettled(promises);
316
+
317
+ for (const result of batchResults) {
318
+ if (result.status === 'fulfilled') {
319
+ results.push(result.value);
320
+ } else {
321
+ console.error('Batch memory processing failed:', result.reason);
322
+ }
323
+ }
324
+ } else {
325
+ // Process in sequential batches
326
+ for (let i = 0; i < memories.length; i += batchSize) {
327
+ const batch = memories.slice(i, i + batchSize);
328
+
329
+ for (const memory of batch) {
330
+ try {
331
+ const execution = await this.processMemory(memory, userId, {
332
+ skipSteps: options.skipSteps,
333
+ priority: options.priority
334
+ });
335
+
336
+ results.push(execution);
337
+
338
+ // Progress callback
339
+ if (options.onProgress) {
340
+ options.onProgress(results.length, memories.length, execution);
341
+ }
342
+ } catch (error) {
343
+ console.error(`Failed to process memory ${memory.id}:`, error);
344
+ }
345
+ }
346
+
347
+ // Small delay between batches to prevent overwhelming
348
+ if (i + batchSize < memories.length) {
349
+ await this.delay(100);
350
+ }
351
+ }
352
+ }
353
+
354
+ console.log(`✅ Batch processing completed: ${results.filter(r => r.status === 'completed').length}/${memories.length} successful`);
355
+
356
+ return results;
357
+ }
358
+
359
+ // ==================== PIPELINE MONITORING ====================
360
+
361
+ /**
362
+ * Get execution status
363
+ */
364
+ getExecutionStatus(executionId: string): PipelineExecution | null {
365
+ return this.executions.get(executionId) || null;
366
+ }
367
+
368
+ /**
369
+ * Get all executions for user
370
+ */
371
+ getUserExecutions(userId: string): PipelineExecution[] {
372
+ return Array.from(this.executions.values())
373
+ .filter(execution => execution.userId === userId);
374
+ }
375
+
376
+ /**
377
+ * Get pipeline metrics
378
+ */
379
+ getPipelineMetrics(): PipelineMetrics {
380
+ return { ...this.metrics };
381
+ }
382
+
383
+ /**
384
+ * Get active executions
385
+ */
386
+ getActiveExecutions(): PipelineExecution[] {
387
+ return Array.from(this.executions.values())
388
+ .filter(execution => execution.status === 'processing');
389
+ }
390
+
391
+ /**
392
+ * Get failed executions
393
+ */
394
+ getFailedExecutions(limit?: number): PipelineExecution[] {
395
+ const failed = Array.from(this.executions.values())
396
+ .filter(execution => execution.status === 'failed')
397
+ .sort((a, b) => b.startTime.getTime() - a.startTime.getTime());
398
+
399
+ return limit ? failed.slice(0, limit) : failed;
400
+ }
401
+
402
+ // ==================== PIPELINE MANAGEMENT ====================
403
+
404
+ /**
405
+ * Retry failed execution
406
+ */
407
+ async retryExecution(executionId: string): Promise<PipelineExecution | null> {
408
+ const execution = this.executions.get(executionId);
409
+ if (!execution || execution.status !== 'failed') {
410
+ return null;
411
+ }
412
+
413
+ // Find the failed step and retry from there
414
+ const failedStepIndex = execution.steps.findIndex(step => step.status === 'failed');
415
+ if (failedStepIndex === -1) {
416
+ return null;
417
+ }
418
+
419
+ // Reset steps from failed point
420
+ for (let i = failedStepIndex; i < execution.steps.length; i++) {
421
+ execution.steps[i].status = 'pending';
422
+ execution.steps[i].error = undefined;
423
+ execution.steps[i].retryAttempts = (execution.steps[i].retryAttempts || 0) + 1;
424
+ }
425
+
426
+ // Retry execution (simplified - in production, implement proper retry logic)
427
+ console.log(`🔄 Retrying execution ${executionId} from step: ${execution.steps[failedStepIndex].name}`);
428
+
429
+ return execution;
430
+ }
431
+
432
+ /**
433
+ * Cancel active execution
434
+ */
435
+ async cancelExecution(executionId: string): Promise<boolean> {
436
+ const execution = this.executions.get(executionId);
437
+ if (!execution || execution.status !== 'processing') {
438
+ return false;
439
+ }
440
+
441
+ execution.status = 'failed';
442
+ execution.error = 'Execution cancelled by user';
443
+ execution.endTime = new Date();
444
+
445
+ console.log(`⏹️ Cancelled execution: ${executionId}`);
446
+ return true;
447
+ }
448
+
449
+ /**
450
+ * Clear completed executions
451
+ */
452
+ clearCompletedExecutions(): number {
453
+ const beforeSize = this.executions.size;
454
+
455
+ for (const [id, execution] of this.executions.entries()) {
456
+ if (execution.status === 'completed' || execution.status === 'failed') {
457
+ this.executions.delete(id);
458
+ }
459
+ }
460
+
461
+ const cleared = beforeSize - this.executions.size;
462
+ console.log(`🧹 Cleared ${cleared} completed/failed executions`);
463
+
464
+ return cleared;
465
+ }
466
+
467
+ /**
468
+ * Get pipeline health status
469
+ */
470
+ getPipelineHealth(): {
471
+ status: 'healthy' | 'degraded' | 'critical';
472
+ activeExecutions: number;
473
+ successRate: number;
474
+ averageProcessingTime: number;
475
+ issues: string[];
476
+ } {
477
+ const successRate = this.metrics.totalExecutions > 0
478
+ ? this.metrics.successfulExecutions / this.metrics.totalExecutions
479
+ : 1;
480
+
481
+ const issues: string[] = [];
482
+ let status: 'healthy' | 'degraded' | 'critical' = 'healthy';
483
+
484
+ // Check success rate
485
+ if (successRate < 0.8) {
486
+ issues.push('Low success rate detected');
487
+ status = 'degraded';
488
+ }
489
+ if (successRate < 0.5) {
490
+ status = 'critical';
491
+ }
492
+
493
+ // Check processing time
494
+ if (this.metrics.averageProcessingTime > 30000) { // 30 seconds
495
+ issues.push('High average processing time');
496
+ if (status === 'healthy') status = 'degraded';
497
+ }
498
+
499
+ // Check active executions
500
+ const activeCount = this.getActiveExecutions().length;
501
+ if (activeCount > 20) {
502
+ issues.push('High number of active executions');
503
+ if (status === 'healthy') status = 'degraded';
504
+ }
505
+
506
+ return {
507
+ status,
508
+ activeExecutions: activeCount,
509
+ successRate,
510
+ averageProcessingTime: this.metrics.averageProcessingTime,
511
+ issues
512
+ };
513
+ }
514
+
515
+ // ==================== PRIVATE METHODS ====================
516
+
517
+ private initializeServices(): void {
518
+ // Initialize all services with configurations
519
+ this.embeddingService = new EmbeddingService({
520
+ apiKey: this.config.embedding.apiKey,
521
+ model: this.config.embedding.model,
522
+ requestsPerMinute: 60
523
+ });
524
+
525
+ this.vectorManager = new VectorManager({
526
+ embedding: { apiKey: '' },
527
+ index: {
528
+ dimension: this.config.vector.dimensions,
529
+ maxElements: this.config.vector.maxElements
530
+ },
531
+ batch: { maxBatchSize: 10 }
532
+ });
533
+
534
+ this.batchManager = new BatchManager({
535
+ embedding: {
536
+ batchSize: this.config.batch.batchSize,
537
+ delayMs: this.config.batch.batchDelayMs
538
+ },
539
+ enableMetrics: this.config.enableMonitoring
540
+ });
541
+
542
+ this.graphManager = new KnowledgeGraphManager();
543
+
544
+ this.storageManager = new StorageManager({
545
+ walrusConfig: {
546
+ network: this.config.storage.network,
547
+ enableEncryption: this.config.storage.enableEncryption,
548
+ enableBatching: this.config.storage.enableBatching
549
+ }
550
+ });
551
+
552
+ this.blockchainManager = new BlockchainManager({
553
+ suiConfig: {
554
+ network: this.config.blockchain.network,
555
+ packageId: this.config.blockchain.packageId,
556
+ enableBatching: this.config.blockchain.enableBatching
557
+ }
558
+ });
559
+
560
+ // Initialize batch manager with services
561
+ this.batchManager.initialize({
562
+ embeddingService: this.embeddingService,
563
+ indexService: this.vectorManager['indexService'] ?? undefined // Access private member
564
+ });
565
+ }
566
+
567
+ private initializeSteps(skipSteps?: string[]): PipelineStep[] {
568
+ return this.PIPELINE_STEPS.map(stepName => ({
569
+ name: stepName,
570
+ status: skipSteps?.includes(stepName) ? 'skipped' : 'pending'
571
+ }));
572
+ }
573
+
574
+ private initializeStepMetrics(): void {
575
+ for (const stepName of this.PIPELINE_STEPS) {
576
+ this.metrics.stepMetrics[stepName] = {
577
+ successCount: 0,
578
+ failureCount: 0,
579
+ averageProcessingTime: 0,
580
+ };
581
+ }
582
+ }
583
+
584
+ private shouldExecuteStep(stepName: string, skipSteps?: string[]): boolean {
585
+ return !skipSteps?.includes(stepName);
586
+ }
587
+
588
+ private async executeEmbeddingStep(
589
+ execution: PipelineExecution,
590
+ memory: ProcessedMemory
591
+ ): Promise<ProcessedMemory> {
592
+ const step = this.findStep(execution, 'embedding_generation');
593
+ return this.executeStep(step, async () => {
594
+ console.log(`📊 Generating embedding for memory: ${memory.id}`);
595
+
596
+ const result = await this.embeddingService.embedText({
597
+ text: memory.content,
598
+ type: 'content'
599
+ });
600
+
601
+ if (!result.vector) {
602
+ throw new Error('Embedding generation failed: No vector returned');
603
+ }
604
+
605
+ return {
606
+ ...memory,
607
+ embedding: result.vector,
608
+ embeddingModel: 'gemini-embedding'
609
+ };
610
+ });
611
+ }
612
+
613
+ private async executeVectorIndexingStep(
614
+ execution: PipelineExecution,
615
+ memory: ProcessedMemory
616
+ ): Promise<ProcessedMemory> {
617
+ const step = this.findStep(execution, 'vector_indexing');
618
+ return this.executeStep(step, async () => {
619
+ console.log(`🔍 Adding to vector index: ${memory.id}`);
620
+
621
+ if (!memory.embedding) {
622
+ throw new Error('No embedding available for indexing');
623
+ }
624
+
625
+ const vectorResult = await this.vectorManager.addTextToIndex(
626
+ memory.userId || 'default-user',
627
+ memory.content,
628
+ {
629
+ vectorId: parseInt(memory.id) || Date.now(),
630
+ metadata: {
631
+ content: memory.content,
632
+ category: memory.category,
633
+ timestamp: memory.createdAt
634
+ }
635
+ }
636
+ );
637
+
638
+ const vectorId = vectorResult.vectorId;
639
+
640
+ return {
641
+ ...memory,
642
+ vectorId
643
+ };
644
+ });
645
+ }
646
+
647
+ private async executeKnowledgeGraphStep(
648
+ execution: PipelineExecution,
649
+ memory: ProcessedMemory,
650
+ userId: string
651
+ ): Promise<ProcessedMemory> {
652
+ const step = this.findStep(execution, 'knowledge_graph_extraction');
653
+ return this.executeStep(step, async () => {
654
+ console.log(`🧠 Extracting knowledge graph for memory: ${memory.id}`);
655
+
656
+ const result = await this.graphManager.processMemoryForGraph(memory, userId, {
657
+ confidenceThreshold: this.config.graph.confidenceThreshold
658
+ });
659
+
660
+ if (!result.success) {
661
+ console.warn(`Knowledge graph extraction failed: ${result.error}`);
662
+ // Non-critical failure, continue pipeline
663
+ }
664
+
665
+ return memory;
666
+ });
667
+ }
668
+
669
+ private async executeStorageStep(
670
+ execution: PipelineExecution,
671
+ memory: ProcessedMemory,
672
+ userId: string,
673
+ options: any
674
+ ): Promise<ProcessedMemory> {
675
+ const step = this.findStep(execution, 'walrus_storage');
676
+ return this.executeStep(step, async () => {
677
+ console.log(`💾 Storing memory on Walrus: ${memory.id}`);
678
+
679
+ const result = await this.storageManager.storeMemory(memory, userId, {
680
+ enableEncryption: this.config.storage.enableEncryption,
681
+ customMetadata: options.customMetadata
682
+ });
683
+
684
+ if (!result.success) {
685
+ throw new Error(`Storage failed: ${result.error}`);
686
+ }
687
+
688
+ return {
689
+ ...memory,
690
+ blobId: result.blobId
691
+ };
692
+ });
693
+ }
694
+
695
+ private async executeBlockchainStep(
696
+ execution: PipelineExecution,
697
+ memory: ProcessedMemory,
698
+ userId: string,
699
+ options: any
700
+ ): Promise<ProcessedMemory> {
701
+ const step = this.findStep(execution, 'blockchain_record');
702
+ return this.executeStep(step, async () => {
703
+ console.log(`⛓️ Creating blockchain record for memory: ${memory.id}`);
704
+
705
+ const ownershipRecord = await this.blockchainManager.createMemoryRecord(
706
+ memory,
707
+ userId,
708
+ {
709
+ enableBatching: this.config.blockchain.enableBatching,
710
+ customMetadata: options.customMetadata
711
+ }
712
+ );
713
+
714
+ return {
715
+ ...memory,
716
+ blockchainRecordId: ownershipRecord.blockchainRecordId
717
+ };
718
+ });
719
+ }
720
+
721
+ private async executeStep<T>(
722
+ step: PipelineStep,
723
+ operation: () => Promise<T>
724
+ ): Promise<T> {
725
+ step.status = 'processing';
726
+ step.startTime = new Date();
727
+
728
+ try {
729
+ const result = await operation();
730
+
731
+ step.status = 'completed';
732
+ step.endTime = new Date();
733
+ step.processingTimeMs = step.endTime.getTime() - step.startTime.getTime();
734
+ step.result = result;
735
+
736
+ // Update metrics
737
+ const stepMetric = this.metrics.stepMetrics[step.name];
738
+ if (stepMetric) {
739
+ stepMetric.successCount++;
740
+ stepMetric.averageProcessingTime =
741
+ (stepMetric.averageProcessingTime + step.processingTimeMs) / stepMetric.successCount;
742
+ }
743
+
744
+ return result;
745
+
746
+ } catch (error) {
747
+ step.status = 'failed';
748
+ step.endTime = new Date();
749
+ step.processingTimeMs = step.endTime!.getTime() - step.startTime.getTime();
750
+ step.error = error instanceof Error ? error.message : String(error);
751
+
752
+ // Update metrics
753
+ const stepMetric = this.metrics.stepMetrics[step.name];
754
+ if (stepMetric) {
755
+ stepMetric.failureCount++;
756
+ stepMetric.lastFailure = step.error;
757
+ }
758
+
759
+ throw error;
760
+ }
761
+ }
762
+
763
+ private findStep(execution: PipelineExecution, stepName: string): PipelineStep {
764
+ const step = execution.steps.find(s => s.name === stepName);
765
+ if (!step) {
766
+ throw new Error(`Step not found: ${stepName}`);
767
+ }
768
+ return step;
769
+ }
770
+
771
+ private async attemptRollback(execution: PipelineExecution): Promise<void> {
772
+ console.log(`🔄 Attempting rollback for execution: ${execution.id}`);
773
+
774
+ try {
775
+ // Find completed steps that need rollback
776
+ const completedSteps = execution.steps.filter(step => step.status === 'completed');
777
+
778
+ // Rollback in reverse order
779
+ for (let i = completedSteps.length - 1; i >= 0; i--) {
780
+ const step = completedSteps[i];
781
+ await this.rollbackStep(step);
782
+ }
783
+
784
+ execution.status = 'rolled_back';
785
+ execution.rollbackReason = execution.error;
786
+ this.metrics.rolledBackExecutions++;
787
+
788
+ console.log(`✅ Rollback completed for execution: ${execution.id}`);
789
+
790
+ } catch (rollbackError) {
791
+ console.error(`❌ Rollback failed for execution: ${execution.id}`, rollbackError);
792
+ // Execution remains in failed state
793
+ }
794
+ }
795
+
796
+ private async rollbackStep(step: PipelineStep): Promise<void> {
797
+ console.log(`🔙 Rolling back step: ${step.name}`);
798
+
799
+ // Implement step-specific rollback logic
800
+ try {
801
+ switch (step.name) {
802
+ case 'walrus_storage':
803
+ // Delete stored blob if possible
804
+ if (step.result?.blobId) {
805
+ await this.storageManager.deleteMemory(step.result.blobId);
806
+ }
807
+ break;
808
+
809
+ case 'blockchain_record':
810
+ // Cannot rollback blockchain transactions, but mark as noted
811
+ console.log(`⚠️ Cannot rollback blockchain transaction for step: ${step.name}`);
812
+ break;
813
+
814
+ default:
815
+ // Most steps don't require explicit rollback
816
+ break;
817
+ }
818
+
819
+ console.log(`✅ Rollback completed for step: ${step.name}`);
820
+
821
+ } catch (error) {
822
+ console.error(`❌ Rollback failed for step: ${step.name}`, error);
823
+ throw error;
824
+ }
825
+ }
826
+
827
+ private updateThroughputMetrics(): void {
828
+ // Calculate memories per hour based on recent completions
829
+ const now = Date.now();
830
+ const oneHourAgo = now - (60 * 60 * 1000);
831
+
832
+ const recentCompletions = Array.from(this.executions.values())
833
+ .filter(exec =>
834
+ exec.status === 'completed' &&
835
+ exec.endTime &&
836
+ exec.endTime.getTime() > oneHourAgo
837
+ );
838
+
839
+ this.metrics.throughput.memoriesPerHour = recentCompletions.length;
840
+ this.metrics.throughput.currentLoad = this.getActiveExecutions().length;
841
+
842
+ // Update peak if current is higher
843
+ if (recentCompletions.length > this.metrics.throughput.peakThroughput) {
844
+ this.metrics.throughput.peakThroughput = recentCompletions.length;
845
+ }
846
+ }
847
+
848
+ private updateAverageProcessingTime(processingTime: number): void {
849
+ const totalSuccessful = this.metrics.successfulExecutions;
850
+ this.metrics.averageProcessingTime =
851
+ (this.metrics.averageProcessingTime * (totalSuccessful - 1) + processingTime) / totalSuccessful;
852
+ }
853
+
854
+ private generateExecutionId(): string {
855
+ return `exec_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`;
856
+ }
857
+
858
+ private delay(ms: number): Promise<void> {
859
+ return new Promise(resolve => setTimeout(resolve, ms));
860
+ }
861
+ }
862
+
863
863
  export default MemoryPipeline;