@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,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;