@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,290 +1,290 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Rebuild HNSW Index from Existing On-Chain Memories
|
|
3
|
-
*
|
|
4
|
-
* This utility fetches all existing memories from the blockchain and re-indexes them
|
|
5
|
-
* locally in IndexedDB for vector search. Use this when:
|
|
6
|
-
*
|
|
7
|
-
* 1. You have old memories created before local indexing was implemented
|
|
8
|
-
* 2. Your IndexedDB was cleared
|
|
9
|
-
* 3. You want to sync a new device with existing on-chain memories
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* ```typescript
|
|
13
|
-
* import { rebuildIndex } from 'personal-data-wallet-sdk/utils/rebuildIndex';
|
|
14
|
-
* import { useCurrentAccount, useSuiClient, useSignPersonalMessage } from '@mysten/dapp-kit';
|
|
15
|
-
*
|
|
16
|
-
* const account = useCurrentAccount();
|
|
17
|
-
* const client = useSuiClient();
|
|
18
|
-
* const { mutateAsync: signPersonalMessage } = useSignPersonalMessage();
|
|
19
|
-
*
|
|
20
|
-
* await rebuildIndex({
|
|
21
|
-
* userAddress: account.address,
|
|
22
|
-
* client,
|
|
23
|
-
* signPersonalMessage,
|
|
24
|
-
* packageId: process.env.NEXT_PUBLIC_PACKAGE_ID,
|
|
25
|
-
* geminiApiKey: process.env.NEXT_PUBLIC_GEMINI_API_KEY,
|
|
26
|
-
* walrusAggregator: process.env.NEXT_PUBLIC_WALRUS_AGGREGATOR,
|
|
27
|
-
* onProgress: (current, total) => console.log(`${current}/${total}`)
|
|
28
|
-
* });
|
|
29
|
-
* ```
|
|
30
|
-
*/
|
|
31
|
-
|
|
32
|
-
import type { SuiClient } from '@mysten/sui/client';
|
|
33
|
-
import { BrowserHnswIndexService } from '../vector/BrowserHnswIndexService';
|
|
34
|
-
import { EmbeddingService } from '../services/EmbeddingService';
|
|
35
|
-
import { ClientMemoryManager, type ClientMemoryMetadata } from '../client/ClientMemoryManager';
|
|
36
|
-
import { ViewService } from '../services/ViewService';
|
|
37
|
-
|
|
38
|
-
export interface RebuildIndexOptions {
|
|
39
|
-
/** User's blockchain address */
|
|
40
|
-
userAddress: string;
|
|
41
|
-
|
|
42
|
-
/** Sui client instance */
|
|
43
|
-
client: SuiClient;
|
|
44
|
-
|
|
45
|
-
/** Function to sign messages for SEAL decryption */
|
|
46
|
-
signPersonalMessage: (params: { message: Uint8Array }) => Promise<{ signature: string }>;
|
|
47
|
-
|
|
48
|
-
/** Package ID for the PDW smart contract */
|
|
49
|
-
packageId: string;
|
|
50
|
-
|
|
51
|
-
/** Gemini API key for generating embeddings */
|
|
52
|
-
geminiApiKey: string;
|
|
53
|
-
|
|
54
|
-
/** Walrus aggregator URL */
|
|
55
|
-
walrusAggregator: string;
|
|
56
|
-
|
|
57
|
-
/** Access registry ID (for SEAL) */
|
|
58
|
-
accessRegistryId?: string;
|
|
59
|
-
|
|
60
|
-
/** Progress callback (current, total) */
|
|
61
|
-
onProgress?: (current: number, total: number, status: string) => void;
|
|
62
|
-
|
|
63
|
-
/** Whether to force re-index even if index exists */
|
|
64
|
-
force?: boolean;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export interface RebuildIndexResult {
|
|
68
|
-
success: boolean;
|
|
69
|
-
totalMemories: number;
|
|
70
|
-
indexedMemories: number;
|
|
71
|
-
failedMemories: number;
|
|
72
|
-
errors: Array<{ blobId: string; error: string }>;
|
|
73
|
-
duration: number;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Rebuild HNSW index from existing on-chain memories
|
|
78
|
-
*/
|
|
79
|
-
export async function rebuildIndex(options: RebuildIndexOptions): Promise<RebuildIndexResult> {
|
|
80
|
-
const {
|
|
81
|
-
userAddress,
|
|
82
|
-
client,
|
|
83
|
-
signPersonalMessage,
|
|
84
|
-
packageId,
|
|
85
|
-
geminiApiKey,
|
|
86
|
-
walrusAggregator,
|
|
87
|
-
accessRegistryId,
|
|
88
|
-
onProgress,
|
|
89
|
-
force = false
|
|
90
|
-
} = options;
|
|
91
|
-
|
|
92
|
-
const startTime = Date.now();
|
|
93
|
-
const errors: Array<{ blobId: string; error: string }> = [];
|
|
94
|
-
|
|
95
|
-
console.log('🔄 Starting index rebuild...');
|
|
96
|
-
onProgress?.(0, 0, 'Initializing services...');
|
|
97
|
-
|
|
98
|
-
try {
|
|
99
|
-
// Step 1: Initialize services
|
|
100
|
-
const embeddingService = new EmbeddingService({
|
|
101
|
-
apiKey: geminiApiKey,
|
|
102
|
-
model: 'text-embedding-004',
|
|
103
|
-
dimensions: 3072
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
const hnswService = new BrowserHnswIndexService(
|
|
107
|
-
{
|
|
108
|
-
dimension: 3072,
|
|
109
|
-
maxElements: 10000,
|
|
110
|
-
m: 16,
|
|
111
|
-
efConstruction: 200
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
maxBatchSize: 50,
|
|
115
|
-
batchDelayMs: 1000 // Shorter delay for rebuild
|
|
116
|
-
}
|
|
117
|
-
);
|
|
118
|
-
|
|
119
|
-
const viewService = new ViewService(client as any, { packageId });
|
|
120
|
-
|
|
121
|
-
const memoryManager = new ClientMemoryManager({
|
|
122
|
-
packageId,
|
|
123
|
-
accessRegistryId: accessRegistryId || '',
|
|
124
|
-
walrusAggregator,
|
|
125
|
-
geminiApiKey,
|
|
126
|
-
enableLocalIndexing: false // We'll handle indexing manually
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
// Step 2: Check if index already exists
|
|
130
|
-
if (!force) {
|
|
131
|
-
try {
|
|
132
|
-
const hasExisting = await hnswService.loadIndexFromDB(userAddress);
|
|
133
|
-
if (hasExisting) {
|
|
134
|
-
console.log('ℹ️ Index already exists. Use force=true to rebuild.');
|
|
135
|
-
return {
|
|
136
|
-
success: false,
|
|
137
|
-
totalMemories: 0,
|
|
138
|
-
indexedMemories: 0,
|
|
139
|
-
failedMemories: 0,
|
|
140
|
-
errors: [{ blobId: '', error: 'Index already exists. Use force=true to rebuild.' }],
|
|
141
|
-
duration: Date.now() - startTime
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
} catch (err) {
|
|
145
|
-
// No index exists, continue with rebuild
|
|
146
|
-
console.log('✅ No existing index, proceeding with rebuild...');
|
|
147
|
-
}
|
|
148
|
-
} else {
|
|
149
|
-
// Clear existing index if force rebuild
|
|
150
|
-
hnswService.clearUserIndex(userAddress);
|
|
151
|
-
console.log('🗑️ Cleared existing index for rebuild');
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// Step 3: Fetch all on-chain memories
|
|
155
|
-
console.log('📡 Fetching memories from blockchain...');
|
|
156
|
-
onProgress?.(0, 0, 'Fetching memories from blockchain...');
|
|
157
|
-
|
|
158
|
-
const result = await viewService.getUserMemories(userAddress, {
|
|
159
|
-
limit: 1000 // Fetch up to 1000 memories
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
const totalMemories = result.data.length;
|
|
163
|
-
console.log(`📊 Found ${totalMemories} memories on-chain`);
|
|
164
|
-
|
|
165
|
-
if (totalMemories === 0) {
|
|
166
|
-
console.log('ℹ️ No memories to index');
|
|
167
|
-
return {
|
|
168
|
-
success: true,
|
|
169
|
-
totalMemories: 0,
|
|
170
|
-
indexedMemories: 0,
|
|
171
|
-
failedMemories: 0,
|
|
172
|
-
errors: [],
|
|
173
|
-
duration: Date.now() - startTime
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// Step 4: Process each memory
|
|
178
|
-
let indexedCount = 0;
|
|
179
|
-
let failedCount = 0;
|
|
180
|
-
|
|
181
|
-
for (let i = 0; i < result.data.length; i++) {
|
|
182
|
-
const memory = result.data[i];
|
|
183
|
-
const progress = `Memory ${i + 1}/${totalMemories}`;
|
|
184
|
-
|
|
185
|
-
console.log(`🔄 Processing ${progress}: ${memory.blobId}`);
|
|
186
|
-
onProgress?.(i + 1, totalMemories, `Processing ${progress}...`);
|
|
187
|
-
|
|
188
|
-
try {
|
|
189
|
-
// Retrieve and decrypt memory content
|
|
190
|
-
const memoryData = await memoryManager.retrieveMemory({
|
|
191
|
-
blobId: memory.blobId,
|
|
192
|
-
account: { address: userAddress },
|
|
193
|
-
signPersonalMessage,
|
|
194
|
-
client
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
// Generate/extract embedding
|
|
198
|
-
let embedding = memoryData.embedding;
|
|
199
|
-
if (!embedding || embedding.length !== 3072) {
|
|
200
|
-
console.log(` ⚠️ No valid embedding found, generating new one...`);
|
|
201
|
-
const embeddingResult = await embeddingService.embedText({
|
|
202
|
-
text: memoryData.content
|
|
203
|
-
});
|
|
204
|
-
embedding = embeddingResult.vector;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// Add to HNSW index
|
|
208
|
-
// Option A+: Store content in index for fast local retrieval (no Walrus fetch needed)
|
|
209
|
-
const vectorId = parseInt(memory.id.slice(-8), 16); // Use memory ID as vector ID
|
|
210
|
-
hnswService.addVectorToIndexBatched(
|
|
211
|
-
userAddress,
|
|
212
|
-
vectorId,
|
|
213
|
-
embedding,
|
|
214
|
-
{
|
|
215
|
-
blobId: memory.blobId,
|
|
216
|
-
category: memory.category,
|
|
217
|
-
importance: memory.importance,
|
|
218
|
-
contentType: 'text/plain',
|
|
219
|
-
contentSize: memory.contentSize,
|
|
220
|
-
createdTimestamp: memory.createdAt,
|
|
221
|
-
// Option A+: Store content for fast retrieval (avoids Walrus fetch on search)
|
|
222
|
-
content: memoryData.content,
|
|
223
|
-
isEncrypted: false // If we decrypted it successfully, store it
|
|
224
|
-
}
|
|
225
|
-
);
|
|
226
|
-
|
|
227
|
-
indexedCount++;
|
|
228
|
-
console.log(` ✅ Indexed: ${memory.blobId.substring(0, 20)}...`);
|
|
229
|
-
|
|
230
|
-
} catch (error: any) {
|
|
231
|
-
failedCount++;
|
|
232
|
-
const errorMsg = error.message || String(error);
|
|
233
|
-
errors.push({ blobId: memory.blobId, error: errorMsg });
|
|
234
|
-
console.error(` ❌ Failed to index ${memory.blobId}:`, errorMsg);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
// Step 5: Force flush all pending vectors
|
|
239
|
-
console.log('💾 Flushing index to IndexedDB...');
|
|
240
|
-
onProgress?.(totalMemories, totalMemories, 'Saving index...');
|
|
241
|
-
|
|
242
|
-
await hnswService.forceFlush(userAddress);
|
|
243
|
-
|
|
244
|
-
const duration = Date.now() - startTime;
|
|
245
|
-
console.log('✅ Index rebuild complete!');
|
|
246
|
-
console.log(` Total: ${totalMemories}, Indexed: ${indexedCount}, Failed: ${failedCount}`);
|
|
247
|
-
console.log(` Duration: ${(duration / 1000).toFixed(2)}s`);
|
|
248
|
-
|
|
249
|
-
return {
|
|
250
|
-
success: true,
|
|
251
|
-
totalMemories,
|
|
252
|
-
indexedMemories: indexedCount,
|
|
253
|
-
failedMemories: failedCount,
|
|
254
|
-
errors,
|
|
255
|
-
duration
|
|
256
|
-
};
|
|
257
|
-
|
|
258
|
-
} catch (error: any) {
|
|
259
|
-
console.error('❌ Index rebuild failed:', error);
|
|
260
|
-
return {
|
|
261
|
-
success: false,
|
|
262
|
-
totalMemories: 0,
|
|
263
|
-
indexedMemories: 0,
|
|
264
|
-
failedMemories: 0,
|
|
265
|
-
errors: [{ blobId: '', error: error.message || String(error) }],
|
|
266
|
-
duration: Date.now() - startTime
|
|
267
|
-
};
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
/**
|
|
272
|
-
* Check if user has an existing index
|
|
273
|
-
*/
|
|
274
|
-
export async function hasExistingIndex(userAddress: string): Promise<boolean> {
|
|
275
|
-
const hnswService = new BrowserHnswIndexService();
|
|
276
|
-
try {
|
|
277
|
-
return await hnswService.loadIndexFromDB(userAddress);
|
|
278
|
-
} catch {
|
|
279
|
-
return false;
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* Clear existing index for a user
|
|
285
|
-
*/
|
|
286
|
-
export function clearIndex(userAddress: string): void {
|
|
287
|
-
const hnswService = new BrowserHnswIndexService();
|
|
288
|
-
hnswService.clearUserIndex(userAddress);
|
|
289
|
-
console.log(`🗑️ Cleared index for user ${userAddress}`);
|
|
290
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Rebuild HNSW Index from Existing On-Chain Memories
|
|
3
|
+
*
|
|
4
|
+
* This utility fetches all existing memories from the blockchain and re-indexes them
|
|
5
|
+
* locally in IndexedDB for vector search. Use this when:
|
|
6
|
+
*
|
|
7
|
+
* 1. You have old memories created before local indexing was implemented
|
|
8
|
+
* 2. Your IndexedDB was cleared
|
|
9
|
+
* 3. You want to sync a new device with existing on-chain memories
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import { rebuildIndex } from 'personal-data-wallet-sdk/utils/rebuildIndex';
|
|
14
|
+
* import { useCurrentAccount, useSuiClient, useSignPersonalMessage } from '@mysten/dapp-kit';
|
|
15
|
+
*
|
|
16
|
+
* const account = useCurrentAccount();
|
|
17
|
+
* const client = useSuiClient();
|
|
18
|
+
* const { mutateAsync: signPersonalMessage } = useSignPersonalMessage();
|
|
19
|
+
*
|
|
20
|
+
* await rebuildIndex({
|
|
21
|
+
* userAddress: account.address,
|
|
22
|
+
* client,
|
|
23
|
+
* signPersonalMessage,
|
|
24
|
+
* packageId: process.env.NEXT_PUBLIC_PACKAGE_ID,
|
|
25
|
+
* geminiApiKey: process.env.NEXT_PUBLIC_GEMINI_API_KEY,
|
|
26
|
+
* walrusAggregator: process.env.NEXT_PUBLIC_WALRUS_AGGREGATOR,
|
|
27
|
+
* onProgress: (current, total) => console.log(`${current}/${total}`)
|
|
28
|
+
* });
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
import type { SuiClient } from '@mysten/sui/client';
|
|
33
|
+
import { BrowserHnswIndexService } from '../vector/BrowserHnswIndexService';
|
|
34
|
+
import { EmbeddingService } from '../services/EmbeddingService';
|
|
35
|
+
import { ClientMemoryManager, type ClientMemoryMetadata } from '../client/ClientMemoryManager';
|
|
36
|
+
import { ViewService } from '../services/ViewService';
|
|
37
|
+
|
|
38
|
+
export interface RebuildIndexOptions {
|
|
39
|
+
/** User's blockchain address */
|
|
40
|
+
userAddress: string;
|
|
41
|
+
|
|
42
|
+
/** Sui client instance */
|
|
43
|
+
client: SuiClient;
|
|
44
|
+
|
|
45
|
+
/** Function to sign messages for SEAL decryption */
|
|
46
|
+
signPersonalMessage: (params: { message: Uint8Array }) => Promise<{ signature: string }>;
|
|
47
|
+
|
|
48
|
+
/** Package ID for the PDW smart contract */
|
|
49
|
+
packageId: string;
|
|
50
|
+
|
|
51
|
+
/** Gemini API key for generating embeddings */
|
|
52
|
+
geminiApiKey: string;
|
|
53
|
+
|
|
54
|
+
/** Walrus aggregator URL */
|
|
55
|
+
walrusAggregator: string;
|
|
56
|
+
|
|
57
|
+
/** Access registry ID (for SEAL) */
|
|
58
|
+
accessRegistryId?: string;
|
|
59
|
+
|
|
60
|
+
/** Progress callback (current, total) */
|
|
61
|
+
onProgress?: (current: number, total: number, status: string) => void;
|
|
62
|
+
|
|
63
|
+
/** Whether to force re-index even if index exists */
|
|
64
|
+
force?: boolean;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface RebuildIndexResult {
|
|
68
|
+
success: boolean;
|
|
69
|
+
totalMemories: number;
|
|
70
|
+
indexedMemories: number;
|
|
71
|
+
failedMemories: number;
|
|
72
|
+
errors: Array<{ blobId: string; error: string }>;
|
|
73
|
+
duration: number;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Rebuild HNSW index from existing on-chain memories
|
|
78
|
+
*/
|
|
79
|
+
export async function rebuildIndex(options: RebuildIndexOptions): Promise<RebuildIndexResult> {
|
|
80
|
+
const {
|
|
81
|
+
userAddress,
|
|
82
|
+
client,
|
|
83
|
+
signPersonalMessage,
|
|
84
|
+
packageId,
|
|
85
|
+
geminiApiKey,
|
|
86
|
+
walrusAggregator,
|
|
87
|
+
accessRegistryId,
|
|
88
|
+
onProgress,
|
|
89
|
+
force = false
|
|
90
|
+
} = options;
|
|
91
|
+
|
|
92
|
+
const startTime = Date.now();
|
|
93
|
+
const errors: Array<{ blobId: string; error: string }> = [];
|
|
94
|
+
|
|
95
|
+
console.log('🔄 Starting index rebuild...');
|
|
96
|
+
onProgress?.(0, 0, 'Initializing services...');
|
|
97
|
+
|
|
98
|
+
try {
|
|
99
|
+
// Step 1: Initialize services
|
|
100
|
+
const embeddingService = new EmbeddingService({
|
|
101
|
+
apiKey: geminiApiKey,
|
|
102
|
+
model: 'text-embedding-004',
|
|
103
|
+
dimensions: 3072
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
const hnswService = new BrowserHnswIndexService(
|
|
107
|
+
{
|
|
108
|
+
dimension: 3072,
|
|
109
|
+
maxElements: 10000,
|
|
110
|
+
m: 16,
|
|
111
|
+
efConstruction: 200
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
maxBatchSize: 50,
|
|
115
|
+
batchDelayMs: 1000 // Shorter delay for rebuild
|
|
116
|
+
}
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
const viewService = new ViewService(client as any, { packageId });
|
|
120
|
+
|
|
121
|
+
const memoryManager = new ClientMemoryManager({
|
|
122
|
+
packageId,
|
|
123
|
+
accessRegistryId: accessRegistryId || '',
|
|
124
|
+
walrusAggregator,
|
|
125
|
+
geminiApiKey,
|
|
126
|
+
enableLocalIndexing: false // We'll handle indexing manually
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
// Step 2: Check if index already exists
|
|
130
|
+
if (!force) {
|
|
131
|
+
try {
|
|
132
|
+
const hasExisting = await hnswService.loadIndexFromDB(userAddress);
|
|
133
|
+
if (hasExisting) {
|
|
134
|
+
console.log('ℹ️ Index already exists. Use force=true to rebuild.');
|
|
135
|
+
return {
|
|
136
|
+
success: false,
|
|
137
|
+
totalMemories: 0,
|
|
138
|
+
indexedMemories: 0,
|
|
139
|
+
failedMemories: 0,
|
|
140
|
+
errors: [{ blobId: '', error: 'Index already exists. Use force=true to rebuild.' }],
|
|
141
|
+
duration: Date.now() - startTime
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
} catch (err) {
|
|
145
|
+
// No index exists, continue with rebuild
|
|
146
|
+
console.log('✅ No existing index, proceeding with rebuild...');
|
|
147
|
+
}
|
|
148
|
+
} else {
|
|
149
|
+
// Clear existing index if force rebuild
|
|
150
|
+
hnswService.clearUserIndex(userAddress);
|
|
151
|
+
console.log('🗑️ Cleared existing index for rebuild');
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Step 3: Fetch all on-chain memories
|
|
155
|
+
console.log('📡 Fetching memories from blockchain...');
|
|
156
|
+
onProgress?.(0, 0, 'Fetching memories from blockchain...');
|
|
157
|
+
|
|
158
|
+
const result = await viewService.getUserMemories(userAddress, {
|
|
159
|
+
limit: 1000 // Fetch up to 1000 memories
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
const totalMemories = result.data.length;
|
|
163
|
+
console.log(`📊 Found ${totalMemories} memories on-chain`);
|
|
164
|
+
|
|
165
|
+
if (totalMemories === 0) {
|
|
166
|
+
console.log('ℹ️ No memories to index');
|
|
167
|
+
return {
|
|
168
|
+
success: true,
|
|
169
|
+
totalMemories: 0,
|
|
170
|
+
indexedMemories: 0,
|
|
171
|
+
failedMemories: 0,
|
|
172
|
+
errors: [],
|
|
173
|
+
duration: Date.now() - startTime
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Step 4: Process each memory
|
|
178
|
+
let indexedCount = 0;
|
|
179
|
+
let failedCount = 0;
|
|
180
|
+
|
|
181
|
+
for (let i = 0; i < result.data.length; i++) {
|
|
182
|
+
const memory = result.data[i];
|
|
183
|
+
const progress = `Memory ${i + 1}/${totalMemories}`;
|
|
184
|
+
|
|
185
|
+
console.log(`🔄 Processing ${progress}: ${memory.blobId}`);
|
|
186
|
+
onProgress?.(i + 1, totalMemories, `Processing ${progress}...`);
|
|
187
|
+
|
|
188
|
+
try {
|
|
189
|
+
// Retrieve and decrypt memory content
|
|
190
|
+
const memoryData = await memoryManager.retrieveMemory({
|
|
191
|
+
blobId: memory.blobId,
|
|
192
|
+
account: { address: userAddress },
|
|
193
|
+
signPersonalMessage,
|
|
194
|
+
client
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
// Generate/extract embedding
|
|
198
|
+
let embedding = memoryData.embedding;
|
|
199
|
+
if (!embedding || embedding.length !== 3072) {
|
|
200
|
+
console.log(` ⚠️ No valid embedding found, generating new one...`);
|
|
201
|
+
const embeddingResult = await embeddingService.embedText({
|
|
202
|
+
text: memoryData.content
|
|
203
|
+
});
|
|
204
|
+
embedding = embeddingResult.vector;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Add to HNSW index
|
|
208
|
+
// Option A+: Store content in index for fast local retrieval (no Walrus fetch needed)
|
|
209
|
+
const vectorId = parseInt(memory.id.slice(-8), 16); // Use memory ID as vector ID
|
|
210
|
+
hnswService.addVectorToIndexBatched(
|
|
211
|
+
userAddress,
|
|
212
|
+
vectorId,
|
|
213
|
+
embedding,
|
|
214
|
+
{
|
|
215
|
+
blobId: memory.blobId,
|
|
216
|
+
category: memory.category,
|
|
217
|
+
importance: memory.importance,
|
|
218
|
+
contentType: 'text/plain',
|
|
219
|
+
contentSize: memory.contentSize,
|
|
220
|
+
createdTimestamp: memory.createdAt,
|
|
221
|
+
// Option A+: Store content for fast retrieval (avoids Walrus fetch on search)
|
|
222
|
+
content: memoryData.content,
|
|
223
|
+
isEncrypted: false // If we decrypted it successfully, store it
|
|
224
|
+
}
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
indexedCount++;
|
|
228
|
+
console.log(` ✅ Indexed: ${memory.blobId.substring(0, 20)}...`);
|
|
229
|
+
|
|
230
|
+
} catch (error: any) {
|
|
231
|
+
failedCount++;
|
|
232
|
+
const errorMsg = error.message || String(error);
|
|
233
|
+
errors.push({ blobId: memory.blobId, error: errorMsg });
|
|
234
|
+
console.error(` ❌ Failed to index ${memory.blobId}:`, errorMsg);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Step 5: Force flush all pending vectors
|
|
239
|
+
console.log('💾 Flushing index to IndexedDB...');
|
|
240
|
+
onProgress?.(totalMemories, totalMemories, 'Saving index...');
|
|
241
|
+
|
|
242
|
+
await hnswService.forceFlush(userAddress);
|
|
243
|
+
|
|
244
|
+
const duration = Date.now() - startTime;
|
|
245
|
+
console.log('✅ Index rebuild complete!');
|
|
246
|
+
console.log(` Total: ${totalMemories}, Indexed: ${indexedCount}, Failed: ${failedCount}`);
|
|
247
|
+
console.log(` Duration: ${(duration / 1000).toFixed(2)}s`);
|
|
248
|
+
|
|
249
|
+
return {
|
|
250
|
+
success: true,
|
|
251
|
+
totalMemories,
|
|
252
|
+
indexedMemories: indexedCount,
|
|
253
|
+
failedMemories: failedCount,
|
|
254
|
+
errors,
|
|
255
|
+
duration
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
} catch (error: any) {
|
|
259
|
+
console.error('❌ Index rebuild failed:', error);
|
|
260
|
+
return {
|
|
261
|
+
success: false,
|
|
262
|
+
totalMemories: 0,
|
|
263
|
+
indexedMemories: 0,
|
|
264
|
+
failedMemories: 0,
|
|
265
|
+
errors: [{ blobId: '', error: error.message || String(error) }],
|
|
266
|
+
duration: Date.now() - startTime
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Check if user has an existing index
|
|
273
|
+
*/
|
|
274
|
+
export async function hasExistingIndex(userAddress: string): Promise<boolean> {
|
|
275
|
+
const hnswService = new BrowserHnswIndexService();
|
|
276
|
+
try {
|
|
277
|
+
return await hnswService.loadIndexFromDB(userAddress);
|
|
278
|
+
} catch {
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Clear existing index for a user
|
|
285
|
+
*/
|
|
286
|
+
export function clearIndex(userAddress: string): void {
|
|
287
|
+
const hnswService = new BrowserHnswIndexService();
|
|
288
|
+
hnswService.clearUserIndex(userAddress);
|
|
289
|
+
console.log(`🗑️ Cleared index for user ${userAddress}`);
|
|
290
|
+
}
|