@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.
- package/ARCHITECTURE.md +547 -547
- package/BENCHMARKS.md +238 -238
- package/README.md +310 -181
- package/dist/ai-sdk/tools.d.ts +2 -2
- package/dist/ai-sdk/tools.js +2 -2
- package/dist/client/ClientMemoryManager.js +2 -2
- package/dist/client/ClientMemoryManager.js.map +1 -1
- package/dist/client/PersonalDataWallet.d.ts.map +1 -1
- package/dist/client/SimplePDWClient.d.ts +29 -1
- package/dist/client/SimplePDWClient.d.ts.map +1 -1
- package/dist/client/SimplePDWClient.js +45 -13
- package/dist/client/SimplePDWClient.js.map +1 -1
- package/dist/client/namespaces/EmbeddingsNamespace.d.ts +1 -1
- package/dist/client/namespaces/EmbeddingsNamespace.js +1 -1
- package/dist/client/namespaces/MemoryNamespace.d.ts +31 -0
- package/dist/client/namespaces/MemoryNamespace.d.ts.map +1 -1
- package/dist/client/namespaces/MemoryNamespace.js +272 -39
- package/dist/client/namespaces/MemoryNamespace.js.map +1 -1
- package/dist/client/namespaces/consolidated/AINamespace.d.ts +2 -2
- package/dist/client/namespaces/consolidated/AINamespace.js +2 -2
- package/dist/client/namespaces/consolidated/BlockchainNamespace.d.ts +12 -2
- package/dist/client/namespaces/consolidated/BlockchainNamespace.d.ts.map +1 -1
- package/dist/client/namespaces/consolidated/BlockchainNamespace.js +62 -4
- package/dist/client/namespaces/consolidated/BlockchainNamespace.js.map +1 -1
- package/dist/client/namespaces/consolidated/StorageNamespace.d.ts +67 -2
- package/dist/client/namespaces/consolidated/StorageNamespace.d.ts.map +1 -1
- package/dist/client/namespaces/consolidated/StorageNamespace.js +549 -16
- package/dist/client/namespaces/consolidated/StorageNamespace.js.map +1 -1
- package/dist/config/ConfigurationHelper.js +61 -61
- package/dist/config/defaults.js +2 -2
- package/dist/config/defaults.js.map +1 -1
- package/dist/graph/GraphService.js +21 -21
- package/dist/graph/GraphService.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/seal/EncryptionService.d.ts +9 -5
- package/dist/infrastructure/seal/EncryptionService.d.ts.map +1 -1
- package/dist/infrastructure/seal/EncryptionService.js +37 -15
- package/dist/infrastructure/seal/EncryptionService.js.map +1 -1
- package/dist/infrastructure/seal/SealService.d.ts +13 -5
- package/dist/infrastructure/seal/SealService.d.ts.map +1 -1
- package/dist/infrastructure/seal/SealService.js +36 -34
- package/dist/infrastructure/seal/SealService.js.map +1 -1
- package/dist/langchain/createPDWRAG.js +30 -30
- package/dist/retrieval/MemoryDecryptionPipeline.d.ts.map +1 -1
- package/dist/retrieval/MemoryDecryptionPipeline.js +2 -1
- package/dist/retrieval/MemoryDecryptionPipeline.js.map +1 -1
- package/dist/retrieval/MemoryRetrievalService.d.ts +31 -0
- package/dist/retrieval/MemoryRetrievalService.d.ts.map +1 -1
- package/dist/retrieval/MemoryRetrievalService.js +44 -4
- package/dist/retrieval/MemoryRetrievalService.js.map +1 -1
- package/dist/services/CapabilityService.d.ts.map +1 -1
- package/dist/services/CapabilityService.js +30 -14
- package/dist/services/CapabilityService.js.map +1 -1
- package/dist/services/CrossContextPermissionService.d.ts.map +1 -1
- package/dist/services/CrossContextPermissionService.js +9 -7
- package/dist/services/CrossContextPermissionService.js.map +1 -1
- package/dist/services/EmbeddingService.d.ts +28 -1
- package/dist/services/EmbeddingService.d.ts.map +1 -1
- package/dist/services/EmbeddingService.js +54 -0
- package/dist/services/EmbeddingService.js.map +1 -1
- package/dist/services/EncryptionService.d.ts.map +1 -1
- package/dist/services/EncryptionService.js +6 -5
- package/dist/services/EncryptionService.js.map +1 -1
- package/dist/services/GeminiAIService.js +309 -309
- package/dist/services/IndexManager.d.ts +5 -1
- package/dist/services/IndexManager.d.ts.map +1 -1
- package/dist/services/IndexManager.js +17 -40
- package/dist/services/IndexManager.js.map +1 -1
- package/dist/services/QueryService.js +1 -1
- package/dist/services/QueryService.js.map +1 -1
- package/dist/services/StorageService.d.ts +11 -0
- package/dist/services/StorageService.d.ts.map +1 -1
- package/dist/services/StorageService.js +73 -10
- package/dist/services/StorageService.js.map +1 -1
- package/dist/services/TransactionService.d.ts +20 -0
- package/dist/services/TransactionService.d.ts.map +1 -1
- package/dist/services/TransactionService.js +43 -0
- package/dist/services/TransactionService.js.map +1 -1
- package/dist/services/ViewService.js +2 -2
- package/dist/services/ViewService.js.map +1 -1
- package/dist/services/storage/QuiltBatchManager.d.ts +101 -1
- package/dist/services/storage/QuiltBatchManager.d.ts.map +1 -1
- package/dist/services/storage/QuiltBatchManager.js +410 -20
- package/dist/services/storage/QuiltBatchManager.js.map +1 -1
- package/dist/services/storage/index.d.ts +1 -1
- package/dist/services/storage/index.d.ts.map +1 -1
- package/dist/services/storage/index.js.map +1 -1
- package/dist/utils/LRUCache.d.ts +106 -0
- package/dist/utils/LRUCache.d.ts.map +1 -0
- package/dist/utils/LRUCache.js +281 -0
- package/dist/utils/LRUCache.js.map +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +2 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/memoryIndexOnChain.d.ts +212 -0
- package/dist/utils/memoryIndexOnChain.d.ts.map +1 -0
- package/dist/utils/memoryIndexOnChain.js +312 -0
- package/dist/utils/memoryIndexOnChain.js.map +1 -0
- package/dist/utils/rebuildIndexNode.d.ts +29 -0
- package/dist/utils/rebuildIndexNode.d.ts.map +1 -1
- package/dist/utils/rebuildIndexNode.js +366 -98
- package/dist/utils/rebuildIndexNode.js.map +1 -1
- package/dist/vector/HnswWasmService.d.ts +20 -5
- package/dist/vector/HnswWasmService.d.ts.map +1 -1
- package/dist/vector/HnswWasmService.js +73 -40
- package/dist/vector/HnswWasmService.js.map +1 -1
- package/dist/vector/IHnswService.d.ts +10 -1
- package/dist/vector/IHnswService.d.ts.map +1 -1
- package/dist/vector/IHnswService.js.map +1 -1
- package/dist/vector/NodeHnswService.d.ts +16 -0
- package/dist/vector/NodeHnswService.d.ts.map +1 -1
- package/dist/vector/NodeHnswService.js +84 -5
- package/dist/vector/NodeHnswService.js.map +1 -1
- package/dist/vector/createHnswService.d.ts +1 -1
- package/dist/vector/createHnswService.js +1 -1
- package/dist/vector/index.d.ts +1 -1
- package/dist/vector/index.js +1 -1
- package/package.json +157 -157
- package/src/access/PermissionService.ts +635 -635
- package/src/aggregation/AggregationService.ts +389 -389
- package/src/ai-sdk/PDWVectorStore.ts +715 -715
- package/src/ai-sdk/index.ts +65 -65
- package/src/ai-sdk/tools.ts +460 -460
- package/src/ai-sdk/types.ts +404 -404
- package/src/batch/BatchManager.ts +597 -597
- package/src/batch/BatchingService.ts +429 -429
- package/src/batch/MemoryProcessingCache.ts +492 -492
- package/src/batch/index.ts +30 -30
- package/src/browser.ts +200 -200
- package/src/client/ClientMemoryManager.ts +987 -987
- package/src/client/PersonalDataWallet.ts +345 -345
- package/src/client/SimplePDWClient.ts +1289 -1222
- package/src/client/factory.ts +154 -154
- package/src/client/namespaces/AnalyticsNamespace.ts +377 -377
- package/src/client/namespaces/BatchNamespace.ts +356 -356
- package/src/client/namespaces/CacheNamespace.ts +123 -123
- package/src/client/namespaces/CapabilityNamespace.ts +217 -217
- package/src/client/namespaces/ClassifyNamespace.ts +169 -169
- package/src/client/namespaces/ContextNamespace.ts +297 -297
- package/src/client/namespaces/EmbeddingsNamespace.ts +99 -99
- package/src/client/namespaces/EncryptionNamespace.ts +221 -221
- package/src/client/namespaces/GraphNamespace.ts +468 -468
- package/src/client/namespaces/IndexNamespace.ts +361 -361
- package/src/client/namespaces/MemoryNamespace.ts +1422 -1135
- package/src/client/namespaces/PermissionsNamespace.ts +254 -254
- package/src/client/namespaces/PipelineNamespace.ts +220 -220
- package/src/client/namespaces/SearchNamespace.ts +1049 -1049
- package/src/client/namespaces/StorageNamespace.ts +458 -458
- package/src/client/namespaces/TxNamespace.ts +260 -260
- package/src/client/namespaces/WalletNamespace.ts +243 -243
- package/src/client/namespaces/consolidated/AINamespace.ts +449 -449
- package/src/client/namespaces/consolidated/BlockchainNamespace.ts +607 -546
- package/src/client/namespaces/consolidated/SecurityNamespace.ts +648 -648
- package/src/client/namespaces/consolidated/StorageNamespace.ts +1141 -497
- package/src/client/namespaces/consolidated/index.ts +39 -39
- package/src/client/signers/KeypairSigner.ts +108 -108
- package/src/client/signers/UnifiedSigner.ts +110 -110
- package/src/client/signers/WalletAdapterSigner.ts +159 -159
- package/src/client/signers/index.ts +26 -26
- package/src/config/ConfigurationHelper.ts +412 -412
- package/src/config/defaults.ts +51 -51
- package/src/config/index.ts +8 -8
- package/src/config/validation.ts +70 -70
- package/src/core/index.ts +14 -14
- package/src/core/interfaces/IService.ts +307 -307
- package/src/core/interfaces/index.ts +8 -8
- package/src/core/types/capability.ts +297 -297
- package/src/core/types/index.ts +870 -870
- package/src/core/types/wallet.ts +270 -270
- package/src/core/types.ts +9 -9
- package/src/core/wallet.ts +222 -222
- package/src/embedding/index.ts +19 -19
- package/src/embedding/types.ts +357 -357
- package/src/errors/index.ts +602 -602
- package/src/errors/recovery.ts +461 -461
- package/src/errors/validation.ts +567 -567
- package/src/generated/pdw/capability.ts +319 -319
- package/src/graph/GraphService.ts +887 -887
- package/src/graph/KnowledgeGraphManager.ts +728 -728
- package/src/graph/index.ts +25 -25
- package/src/index.ts +498 -474
- package/src/infrastructure/index.ts +22 -22
- package/src/infrastructure/seal/EncryptionService.ts +628 -603
- package/src/infrastructure/seal/SealService.ts +613 -615
- package/src/infrastructure/seal/index.ts +9 -9
- package/src/infrastructure/sui/BlockchainManager.ts +627 -627
- package/src/infrastructure/sui/SuiService.ts +888 -888
- package/src/infrastructure/sui/index.ts +9 -9
- package/src/infrastructure/walrus/StorageManager.ts +604 -604
- package/src/infrastructure/walrus/WalrusStorageService.ts +612 -612
- package/src/infrastructure/walrus/index.ts +9 -9
- package/src/langchain/PDWEmbeddings.ts +145 -145
- package/src/langchain/PDWVectorStore.ts +456 -456
- package/src/langchain/createPDWRAG.ts +303 -303
- package/src/langchain/index.ts +47 -47
- package/src/permissions/ConsentRepository.browser.ts +249 -249
- package/src/permissions/ConsentRepository.ts +364 -364
- package/src/pipeline/MemoryPipeline.ts +862 -862
- package/src/pipeline/PipelineManager.ts +683 -683
- package/src/pipeline/index.ts +26 -26
- package/src/retrieval/AdvancedSearchService.ts +629 -629
- package/src/retrieval/MemoryAnalyticsService.ts +711 -711
- package/src/retrieval/MemoryDecryptionPipeline.ts +825 -824
- package/src/retrieval/MemoryRetrievalService.ts +904 -830
- package/src/retrieval/index.ts +42 -42
- package/src/services/BatchService.ts +352 -352
- package/src/services/CapabilityService.ts +464 -448
- package/src/services/ClassifierService.ts +465 -465
- package/src/services/CrossContextPermissionService.ts +486 -484
- package/src/services/EmbeddingService.ts +771 -706
- package/src/services/EncryptionService.ts +712 -711
- package/src/services/GeminiAIService.ts +753 -753
- package/src/services/IndexManager.ts +977 -1004
- package/src/services/MemoryIndexService.ts +1003 -1003
- package/src/services/MemoryService.ts +369 -369
- package/src/services/QueryService.ts +890 -890
- package/src/services/StorageService.ts +1182 -1111
- package/src/services/TransactionService.ts +838 -790
- package/src/services/VectorService.ts +462 -462
- package/src/services/ViewService.ts +484 -484
- package/src/services/index.ts +25 -25
- package/src/services/storage/BlobAttributesManager.ts +333 -333
- package/src/services/storage/KnowledgeGraphManager.ts +425 -425
- package/src/services/storage/MemorySearchManager.ts +387 -387
- package/src/services/storage/QuiltBatchManager.ts +1130 -660
- package/src/services/storage/WalrusMetadataManager.ts +268 -268
- package/src/services/storage/WalrusStorageManager.ts +287 -287
- package/src/services/storage/index.ts +57 -52
- package/src/types/index.ts +13 -13
- package/src/utils/LRUCache.ts +378 -0
- package/src/utils/index.ts +76 -68
- package/src/utils/memoryIndexOnChain.ts +507 -0
- package/src/utils/rebuildIndex.ts +290 -290
- package/src/utils/rebuildIndexNode.ts +771 -424
- package/src/vector/BrowserHnswIndexService.ts +758 -758
- package/src/vector/HnswWasmService.ts +731 -679
- package/src/vector/IHnswService.ts +233 -224
- package/src/vector/NodeHnswService.ts +833 -735
- package/src/vector/VectorManager.ts +478 -478
- package/src/vector/createHnswService.ts +135 -135
- package/src/vector/index.ts +56 -56
- package/src/wallet/ContextWalletService.ts +656 -656
- 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;
|