@cmdoss/memwal-sdk 0.8.0 → 0.9.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/README.md +389 -132
- package/dist/client/SimplePDWClient.d.ts +60 -1
- package/dist/client/SimplePDWClient.d.ts.map +1 -1
- package/dist/client/SimplePDWClient.js +73 -5
- package/dist/client/SimplePDWClient.js.map +1 -1
- package/dist/client/namespaces/IndexNamespace.d.ts +1 -1
- package/dist/client/namespaces/IndexNamespace.d.ts.map +1 -1
- package/dist/client/namespaces/IndexNamespace.js +7 -4
- package/dist/client/namespaces/IndexNamespace.js.map +1 -1
- package/dist/client/namespaces/MemoryNamespace.d.ts +41 -0
- package/dist/client/namespaces/MemoryNamespace.d.ts.map +1 -1
- package/dist/client/namespaces/MemoryNamespace.js +126 -9
- package/dist/client/namespaces/MemoryNamespace.js.map +1 -1
- package/dist/client/namespaces/consolidated/AdvancedNamespace.d.ts +215 -0
- package/dist/client/namespaces/consolidated/AdvancedNamespace.d.ts.map +1 -0
- package/dist/client/namespaces/consolidated/AdvancedNamespace.js +214 -0
- package/dist/client/namespaces/consolidated/AdvancedNamespace.js.map +1 -0
- package/dist/client/namespaces/consolidated/index.d.ts +1 -0
- package/dist/client/namespaces/consolidated/index.d.ts.map +1 -1
- package/dist/client/namespaces/consolidated/index.js +1 -0
- package/dist/client/namespaces/consolidated/index.js.map +1 -1
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +9 -4
- package/dist/config/defaults.js.map +1 -1
- package/dist/core/types/index.d.ts +4 -0
- package/dist/core/types/index.d.ts.map +1 -1
- package/dist/core/types/index.js.map +1 -1
- package/dist/infrastructure/walrus/WalrusStorageService.d.ts +6 -0
- package/dist/infrastructure/walrus/WalrusStorageService.d.ts.map +1 -1
- package/dist/infrastructure/walrus/WalrusStorageService.js +23 -4
- package/dist/infrastructure/walrus/WalrusStorageService.js.map +1 -1
- package/dist/services/EmbeddingService.d.ts +9 -0
- package/dist/services/EmbeddingService.d.ts.map +1 -1
- package/dist/services/EmbeddingService.js +31 -10
- package/dist/services/EmbeddingService.js.map +1 -1
- package/dist/services/MemoryIndexService.d.ts +2 -0
- package/dist/services/MemoryIndexService.d.ts.map +1 -1
- package/dist/services/MemoryIndexService.js +11 -4
- package/dist/services/MemoryIndexService.js.map +1 -1
- package/dist/services/VectorService.js +1 -1
- package/dist/services/VectorService.js.map +1 -1
- package/dist/vector/BrowserHnswIndexService.js +1 -1
- package/dist/vector/BrowserHnswIndexService.js.map +1 -1
- package/dist/vector/HnswWasmService.js +1 -1
- package/dist/vector/HnswWasmService.js.map +1 -1
- package/dist/vector/NodeHnswService.js +1 -1
- package/dist/vector/NodeHnswService.js.map +1 -1
- package/package.json +1 -1
- package/src/client/SimplePDWClient.ts +86 -6
- package/src/client/namespaces/IndexNamespace.ts +7 -4
- package/src/client/namespaces/MemoryNamespace.ts +156 -9
- package/src/client/namespaces/consolidated/AdvancedNamespace.ts +264 -0
- package/src/client/namespaces/consolidated/index.ts +2 -0
- package/src/config/defaults.ts +9 -4
- package/src/core/types/index.ts +4 -0
- package/src/infrastructure/walrus/WalrusStorageService.ts +29 -4
- package/src/services/EmbeddingService.ts +35 -10
- package/src/services/MemoryIndexService.ts +11 -5
- package/src/services/VectorService.ts +1 -1
- package/src/vector/BrowserHnswIndexService.ts +1 -1
- package/src/vector/HnswWasmService.ts +1 -1
- package/src/vector/NodeHnswService.ts +1 -1
|
@@ -39,6 +39,8 @@ export interface CreateMemoryOptions {
|
|
|
39
39
|
importance?: number; // 1-10
|
|
40
40
|
topic?: string;
|
|
41
41
|
metadata?: Record<string, any>;
|
|
42
|
+
/** Pre-generated embedding (if provided, skips embedding generation) */
|
|
43
|
+
embedding?: number[];
|
|
42
44
|
onProgress?: (stage: string, percent: number) => void;
|
|
43
45
|
}
|
|
44
46
|
|
|
@@ -75,6 +77,20 @@ export interface ListMemoryOptions {
|
|
|
75
77
|
order?: 'asc' | 'desc';
|
|
76
78
|
}
|
|
77
79
|
|
|
80
|
+
/**
|
|
81
|
+
* Options for searching memories
|
|
82
|
+
*/
|
|
83
|
+
export interface SearchMemoryOptions {
|
|
84
|
+
/** Maximum number of results (default: 10) */
|
|
85
|
+
limit?: number;
|
|
86
|
+
/** Minimum similarity threshold 0-1 (default: 0.5) */
|
|
87
|
+
threshold?: number;
|
|
88
|
+
/** Filter by category */
|
|
89
|
+
category?: string;
|
|
90
|
+
/** Include full content in results (default: true) */
|
|
91
|
+
includeContent?: boolean;
|
|
92
|
+
}
|
|
93
|
+
|
|
78
94
|
/**
|
|
79
95
|
* Memory context with related memories
|
|
80
96
|
*/
|
|
@@ -132,7 +148,7 @@ export class MemoryNamespace {
|
|
|
132
148
|
* ```
|
|
133
149
|
*/
|
|
134
150
|
async create(content: string, options: CreateMemoryOptions = {}): Promise<Memory> {
|
|
135
|
-
const { importance = 5, topic, metadata, onProgress } = options;
|
|
151
|
+
const { importance = 5, topic, metadata, onProgress, embedding: preGeneratedEmbedding } = options;
|
|
136
152
|
let category: string = options.category || 'general';
|
|
137
153
|
|
|
138
154
|
try {
|
|
@@ -160,17 +176,17 @@ export class MemoryNamespace {
|
|
|
160
176
|
}
|
|
161
177
|
}
|
|
162
178
|
|
|
163
|
-
// 2.
|
|
164
|
-
let embedding: number[] | undefined;
|
|
165
|
-
if (
|
|
179
|
+
// 2. Use pre-generated embedding or generate new one
|
|
180
|
+
let embedding: number[] | undefined = preGeneratedEmbedding;
|
|
181
|
+
if (embedding && embedding.length > 0) {
|
|
182
|
+
console.log(`✅ Using pre-generated embedding: ${embedding.length}D`);
|
|
183
|
+
} else if (this.services.embedding) {
|
|
166
184
|
onProgress?.('generating embedding', 20);
|
|
167
|
-
const embResult = await this.services.embedding.embedText({
|
|
168
|
-
text: content
|
|
169
|
-
});
|
|
185
|
+
const embResult = await this.services.embedding.embedText({ text: content });
|
|
170
186
|
embedding = embResult.vector;
|
|
171
|
-
console.log(`✅ Embedding generated: ${embedding?.length || 0}D
|
|
187
|
+
console.log(`✅ Embedding generated: ${embedding?.length || 0}D`);
|
|
172
188
|
} else {
|
|
173
|
-
console.warn('⚠️
|
|
189
|
+
console.warn('⚠️ No embedding available');
|
|
174
190
|
}
|
|
175
191
|
|
|
176
192
|
// 3. Encrypt (if enabled) - Use capability-based encryption (v2.2)
|
|
@@ -703,6 +719,137 @@ export class MemoryNamespace {
|
|
|
703
719
|
}
|
|
704
720
|
}
|
|
705
721
|
|
|
722
|
+
/**
|
|
723
|
+
* Search memories using natural language query
|
|
724
|
+
*
|
|
725
|
+
* Unified search that:
|
|
726
|
+
* 1. Converts query text to embedding
|
|
727
|
+
* 2. Performs vector similarity search
|
|
728
|
+
* 3. Returns ranked results with content
|
|
729
|
+
*
|
|
730
|
+
* @param query - Natural language search query
|
|
731
|
+
* @param options - Search options (limit, threshold, category)
|
|
732
|
+
* @returns Array of matching memories sorted by relevance
|
|
733
|
+
*
|
|
734
|
+
* @example
|
|
735
|
+
* ```typescript
|
|
736
|
+
* // Simple search
|
|
737
|
+
* const results = await pdw.memory.search('meeting notes');
|
|
738
|
+
*
|
|
739
|
+
* // With options
|
|
740
|
+
* const results = await pdw.memory.search('TypeScript tips', {
|
|
741
|
+
* limit: 5,
|
|
742
|
+
* category: 'note',
|
|
743
|
+
* threshold: 0.7
|
|
744
|
+
* });
|
|
745
|
+
* ```
|
|
746
|
+
*/
|
|
747
|
+
async search(query: string, options: SearchMemoryOptions = {}): Promise<Memory[]> {
|
|
748
|
+
const {
|
|
749
|
+
limit = 10,
|
|
750
|
+
threshold = 0.5,
|
|
751
|
+
category,
|
|
752
|
+
includeContent = true
|
|
753
|
+
} = options;
|
|
754
|
+
|
|
755
|
+
try {
|
|
756
|
+
// Validate query
|
|
757
|
+
if (!query || query.trim().length === 0) {
|
|
758
|
+
return [];
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
// Step 1: Generate embedding for query
|
|
762
|
+
if (!this.services.embedding) {
|
|
763
|
+
throw new Error('Embedding service not available - cannot perform semantic search');
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
const embResult = await this.services.embedding.embedText({ text: query });
|
|
767
|
+
const queryEmbedding = embResult.vector;
|
|
768
|
+
|
|
769
|
+
// Step 2: Perform vector search
|
|
770
|
+
let searchResults: any[] = [];
|
|
771
|
+
|
|
772
|
+
// Try local index first (faster)
|
|
773
|
+
if (this.services.vector) {
|
|
774
|
+
try {
|
|
775
|
+
const spaceId = this.services.config.userAddress;
|
|
776
|
+
const searchResult = await this.services.vector.searchVectors(spaceId, queryEmbedding, { k: limit * 2 });
|
|
777
|
+
searchResults = searchResult.results.map((r: any) => ({
|
|
778
|
+
id: r.metadata?.memoryObjectId || r.memoryId || String(r.vectorId),
|
|
779
|
+
vectorId: r.vectorId,
|
|
780
|
+
content: r.metadata?.content || '',
|
|
781
|
+
category: r.metadata?.category,
|
|
782
|
+
importance: r.metadata?.importance,
|
|
783
|
+
blobId: r.metadata?.blobId || r.memoryId,
|
|
784
|
+
metadata: r.metadata,
|
|
785
|
+
similarity: r.similarity || 0,
|
|
786
|
+
encrypted: r.metadata?.isEncrypted || false,
|
|
787
|
+
createdAt: r.metadata?.timestamp || Date.now()
|
|
788
|
+
}));
|
|
789
|
+
} catch (indexError) {
|
|
790
|
+
console.warn('Local index search failed:', indexError);
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
// Fallback to memory index service if available
|
|
795
|
+
if (searchResults.length === 0 && this.services.memoryIndex) {
|
|
796
|
+
try {
|
|
797
|
+
const results = await this.services.memoryIndex.searchMemories({
|
|
798
|
+
userAddress: this.services.config.userAddress,
|
|
799
|
+
vector: queryEmbedding,
|
|
800
|
+
k: limit * 2
|
|
801
|
+
});
|
|
802
|
+
searchResults = results.map((r: any) => ({
|
|
803
|
+
id: r.memoryObjectId || r.id,
|
|
804
|
+
content: r.content || '',
|
|
805
|
+
category: r.category,
|
|
806
|
+
importance: r.importance || r.metadata?.importance,
|
|
807
|
+
blobId: r.blobId || r.id,
|
|
808
|
+
metadata: r.metadata,
|
|
809
|
+
similarity: r.score || r.similarity || 0,
|
|
810
|
+
encrypted: r.isEncrypted || false,
|
|
811
|
+
createdAt: r.timestamp || Date.now()
|
|
812
|
+
}));
|
|
813
|
+
} catch (memIndexError) {
|
|
814
|
+
console.warn('Memory index search failed:', memIndexError);
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
// Step 3: Filter by threshold and category
|
|
819
|
+
let filtered = searchResults.filter(r => r.similarity >= threshold);
|
|
820
|
+
|
|
821
|
+
if (category) {
|
|
822
|
+
filtered = filtered.filter(r => r.category === category);
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
// Step 4: Limit results
|
|
826
|
+
const limited = filtered.slice(0, limit);
|
|
827
|
+
|
|
828
|
+
// Step 5: Optionally fetch full content for encrypted memories
|
|
829
|
+
if (includeContent) {
|
|
830
|
+
const withContent = await Promise.all(
|
|
831
|
+
limited.map(async (r) => {
|
|
832
|
+
// If content is missing or encrypted, try to fetch from storage
|
|
833
|
+
if (!r.content && r.blobId) {
|
|
834
|
+
try {
|
|
835
|
+
const memory = await this.get(r.blobId);
|
|
836
|
+
return { ...r, content: memory.content };
|
|
837
|
+
} catch {
|
|
838
|
+
return r;
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
return r;
|
|
842
|
+
})
|
|
843
|
+
);
|
|
844
|
+
return withContent as Memory[];
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
return limited as Memory[];
|
|
848
|
+
} catch (error) {
|
|
849
|
+
throw new Error(`Failed to search memories: ${error instanceof Error ? error.message : String(error)}`);
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
|
|
706
853
|
/**
|
|
707
854
|
* Create multiple memories in batch using Walrus Quilt
|
|
708
855
|
*
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Advanced Namespace - Power User Features
|
|
3
|
+
*
|
|
4
|
+
* Groups specialized features for advanced use cases:
|
|
5
|
+
* - Knowledge graph operations
|
|
6
|
+
* - Memory analytics and insights
|
|
7
|
+
* - Manual encryption/decryption
|
|
8
|
+
* - Access control and permissions
|
|
9
|
+
* - Transaction building
|
|
10
|
+
* - Processing pipelines
|
|
11
|
+
*
|
|
12
|
+
* Most users won't need these - use pdw.memory for common operations.
|
|
13
|
+
*
|
|
14
|
+
* @module client/namespaces/consolidated
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import type { ServiceContainer } from '../../SimplePDWClient';
|
|
18
|
+
import type { GraphNamespace } from '../GraphNamespace';
|
|
19
|
+
import type { AnalyticsNamespace } from '../AnalyticsNamespace';
|
|
20
|
+
import type { EncryptionNamespace } from '../EncryptionNamespace';
|
|
21
|
+
import type { PermissionsNamespace } from '../PermissionsNamespace';
|
|
22
|
+
import type { TxNamespace } from '../TxNamespace';
|
|
23
|
+
import type { PipelineNamespace } from '../PipelineNamespace';
|
|
24
|
+
import type { CapabilityNamespace } from '../CapabilityNamespace';
|
|
25
|
+
import type { ContextNamespace } from '../ContextNamespace';
|
|
26
|
+
import type { BatchNamespace } from '../BatchNamespace';
|
|
27
|
+
import type { CacheNamespace } from '../CacheNamespace';
|
|
28
|
+
import type { SearchNamespace } from '../SearchNamespace';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Advanced Namespace
|
|
32
|
+
*
|
|
33
|
+
* Access specialized features through sub-namespaces:
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* // Knowledge graph
|
|
38
|
+
* const entities = await pdw.advanced.graph.getEntities();
|
|
39
|
+
*
|
|
40
|
+
* // Analytics
|
|
41
|
+
* const insights = await pdw.advanced.analytics.generate();
|
|
42
|
+
*
|
|
43
|
+
* // Manual encryption
|
|
44
|
+
* const encrypted = await pdw.advanced.encryption.encrypt(data);
|
|
45
|
+
*
|
|
46
|
+
* // Permissions
|
|
47
|
+
* await pdw.advanced.permissions.grant(userId, memoryId);
|
|
48
|
+
*
|
|
49
|
+
* // Blockchain transactions
|
|
50
|
+
* const tx = pdw.advanced.blockchain.buildCreateMemory(params);
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export class AdvancedNamespace {
|
|
54
|
+
private _graph?: GraphNamespace;
|
|
55
|
+
private _analytics?: AnalyticsNamespace;
|
|
56
|
+
private _encryption?: EncryptionNamespace;
|
|
57
|
+
private _permissions?: PermissionsNamespace;
|
|
58
|
+
private _blockchain?: TxNamespace;
|
|
59
|
+
private _pipeline?: PipelineNamespace;
|
|
60
|
+
private _capability?: CapabilityNamespace;
|
|
61
|
+
private _context?: ContextNamespace;
|
|
62
|
+
private _batch?: BatchNamespace;
|
|
63
|
+
private _cache?: CacheNamespace;
|
|
64
|
+
private _search?: SearchNamespace;
|
|
65
|
+
|
|
66
|
+
constructor(
|
|
67
|
+
private services: ServiceContainer,
|
|
68
|
+
namespaces: {
|
|
69
|
+
graph?: GraphNamespace;
|
|
70
|
+
analytics?: AnalyticsNamespace;
|
|
71
|
+
encryption?: EncryptionNamespace;
|
|
72
|
+
permissions?: PermissionsNamespace;
|
|
73
|
+
blockchain?: TxNamespace;
|
|
74
|
+
pipeline?: PipelineNamespace;
|
|
75
|
+
capability?: CapabilityNamespace;
|
|
76
|
+
context?: ContextNamespace;
|
|
77
|
+
batch?: BatchNamespace;
|
|
78
|
+
cache?: CacheNamespace;
|
|
79
|
+
search?: SearchNamespace;
|
|
80
|
+
}
|
|
81
|
+
) {
|
|
82
|
+
this._graph = namespaces.graph;
|
|
83
|
+
this._analytics = namespaces.analytics;
|
|
84
|
+
this._encryption = namespaces.encryption;
|
|
85
|
+
this._permissions = namespaces.permissions;
|
|
86
|
+
this._blockchain = namespaces.blockchain;
|
|
87
|
+
this._pipeline = namespaces.pipeline;
|
|
88
|
+
this._capability = namespaces.capability;
|
|
89
|
+
this._context = namespaces.context;
|
|
90
|
+
this._batch = namespaces.batch;
|
|
91
|
+
this._cache = namespaces.cache;
|
|
92
|
+
this._search = namespaces.search;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Knowledge Graph Operations
|
|
97
|
+
*
|
|
98
|
+
* Extract entities and relationships from memories,
|
|
99
|
+
* traverse the graph, and find connections.
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```typescript
|
|
103
|
+
* const entities = await pdw.advanced.graph.getEntities();
|
|
104
|
+
* const related = await pdw.advanced.graph.traverse(entityId);
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
get graph(): GraphNamespace | undefined {
|
|
108
|
+
return this._graph;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Memory Analytics
|
|
113
|
+
*
|
|
114
|
+
* Generate insights, trends, and clustering from memories.
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* ```typescript
|
|
118
|
+
* const insights = await pdw.advanced.analytics.generate();
|
|
119
|
+
* const trends = await pdw.advanced.analytics.trends();
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
get analytics(): AnalyticsNamespace | undefined {
|
|
123
|
+
return this._analytics;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Manual Encryption/Decryption
|
|
128
|
+
*
|
|
129
|
+
* Direct access to SEAL encryption for custom use cases.
|
|
130
|
+
* Note: pdw.memory.create() handles encryption automatically.
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```typescript
|
|
134
|
+
* const encrypted = await pdw.advanced.encryption.encrypt(data, keyId);
|
|
135
|
+
* const decrypted = await pdw.advanced.encryption.decrypt(options);
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
get encryption(): EncryptionNamespace | undefined {
|
|
139
|
+
return this._encryption;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Access Control & Permissions
|
|
144
|
+
*
|
|
145
|
+
* Grant, revoke, and manage access to memories.
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* ```typescript
|
|
149
|
+
* await pdw.advanced.permissions.grant(userId, memoryId);
|
|
150
|
+
* await pdw.advanced.permissions.revoke(userId, memoryId);
|
|
151
|
+
* const perms = await pdw.advanced.permissions.list(memoryId);
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
get permissions(): PermissionsNamespace | undefined {
|
|
155
|
+
return this._permissions;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Blockchain Transaction Building
|
|
160
|
+
*
|
|
161
|
+
* Build custom Sui transactions for advanced operations.
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* ```typescript
|
|
165
|
+
* const tx = pdw.advanced.blockchain.buildCreateMemory(params);
|
|
166
|
+
* const result = await pdw.advanced.blockchain.execute(tx);
|
|
167
|
+
* ```
|
|
168
|
+
*/
|
|
169
|
+
get blockchain(): TxNamespace | undefined {
|
|
170
|
+
return this._blockchain;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Processing Pipelines
|
|
175
|
+
*
|
|
176
|
+
* Create and manage memory processing pipelines.
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* ```typescript
|
|
180
|
+
* const pipeline = await pdw.advanced.pipeline.create(config);
|
|
181
|
+
* await pdw.advanced.pipeline.execute(pipeline, data);
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
get pipeline(): PipelineNamespace | undefined {
|
|
185
|
+
return this._pipeline;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Capability Management
|
|
190
|
+
*
|
|
191
|
+
* Low-level MemoryCap object management for SEAL encryption.
|
|
192
|
+
*
|
|
193
|
+
* @example
|
|
194
|
+
* ```typescript
|
|
195
|
+
* const cap = await pdw.advanced.capability.getOrCreate(appId);
|
|
196
|
+
* const keyId = pdw.advanced.capability.computeKeyId(cap);
|
|
197
|
+
* ```
|
|
198
|
+
*/
|
|
199
|
+
get capability(): CapabilityNamespace | undefined {
|
|
200
|
+
return this._capability;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* App Context Management
|
|
205
|
+
*
|
|
206
|
+
* Manage application contexts for multi-app memory access.
|
|
207
|
+
*
|
|
208
|
+
* @example
|
|
209
|
+
* ```typescript
|
|
210
|
+
* const ctx = await pdw.advanced.context.getOrCreate(appId);
|
|
211
|
+
* await pdw.advanced.context.transfer(ctxId, newOwner);
|
|
212
|
+
* ```
|
|
213
|
+
*/
|
|
214
|
+
get context(): ContextNamespace | undefined {
|
|
215
|
+
return this._context;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Batch Processing Utilities
|
|
220
|
+
*
|
|
221
|
+
* Advanced batch operations beyond createBatch.
|
|
222
|
+
*
|
|
223
|
+
* @example
|
|
224
|
+
* ```typescript
|
|
225
|
+
* const stats = await pdw.advanced.batch.stats();
|
|
226
|
+
* const progress = await pdw.advanced.batch.progress(batchId);
|
|
227
|
+
* ```
|
|
228
|
+
*/
|
|
229
|
+
get batch(): BatchNamespace | undefined {
|
|
230
|
+
return this._batch;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Cache Management
|
|
235
|
+
*
|
|
236
|
+
* Direct access to in-memory LRU cache.
|
|
237
|
+
*
|
|
238
|
+
* @example
|
|
239
|
+
* ```typescript
|
|
240
|
+
* const cached = pdw.advanced.cache.get(key);
|
|
241
|
+
* pdw.advanced.cache.set(key, value);
|
|
242
|
+
* pdw.advanced.cache.clear();
|
|
243
|
+
* ```
|
|
244
|
+
*/
|
|
245
|
+
get cache(): CacheNamespace | undefined {
|
|
246
|
+
return this._cache;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Advanced Search
|
|
251
|
+
*
|
|
252
|
+
* Low-level vector and semantic search operations.
|
|
253
|
+
* Note: pdw.memory.search() is simpler for most use cases.
|
|
254
|
+
*
|
|
255
|
+
* @example
|
|
256
|
+
* ```typescript
|
|
257
|
+
* const results = await pdw.advanced.search.vector(embedding, k);
|
|
258
|
+
* const results = await pdw.advanced.search.hybrid(query, filters);
|
|
259
|
+
* ```
|
|
260
|
+
*/
|
|
261
|
+
get search(): SearchNamespace | undefined {
|
|
262
|
+
return this._search;
|
|
263
|
+
}
|
|
264
|
+
}
|
package/src/config/defaults.ts
CHANGED
|
@@ -22,11 +22,15 @@ export function createDefaultConfig(): PDWConfig {
|
|
|
22
22
|
cacheEnabled: true,
|
|
23
23
|
encryptionEnabled: true,
|
|
24
24
|
},
|
|
25
|
-
// Walrus Storage Configuration
|
|
25
|
+
// Walrus Storage Configuration (Testnet defaults)
|
|
26
|
+
// Publisher: Direct blob uploads (server-side, full control)
|
|
26
27
|
walrusPublisherUrl: 'https://publisher.walrus-testnet.walrus.space',
|
|
28
|
+
// Upload Relay: Optimized for browser/mobile (fewer connections, faster)
|
|
29
|
+
walrusUploadRelayUrl: 'https://upload-relay.testnet.walrus.space',
|
|
30
|
+
// Aggregator: Blob retrieval
|
|
27
31
|
walrusAggregatorUrl: 'https://aggregator.walrus-testnet.walrus.space',
|
|
28
|
-
walrusMaxFileSize:
|
|
29
|
-
walrusTimeout:
|
|
32
|
+
walrusMaxFileSize: 10 * 1024 * 1024, // 10MB (public service limit)
|
|
33
|
+
walrusTimeout: 60000, // 60 seconds for upload relay
|
|
30
34
|
};
|
|
31
35
|
}
|
|
32
36
|
|
|
@@ -44,8 +48,9 @@ export function createTestnetConfig(overrides: Partial<PDWConfig> = {}): PDWConf
|
|
|
44
48
|
threshold: 2,
|
|
45
49
|
},
|
|
46
50
|
},
|
|
47
|
-
// Testnet Walrus endpoints
|
|
51
|
+
// Testnet Walrus endpoints
|
|
48
52
|
walrusPublisherUrl: 'https://publisher.walrus-testnet.walrus.space',
|
|
53
|
+
walrusUploadRelayUrl: 'https://upload-relay.testnet.walrus.space',
|
|
49
54
|
walrusAggregatorUrl: 'https://aggregator.walrus-testnet.walrus.space',
|
|
50
55
|
...overrides,
|
|
51
56
|
};
|
package/src/core/types/index.ts
CHANGED
|
@@ -37,7 +37,11 @@ export interface PDWConfig {
|
|
|
37
37
|
/** Storage configuration */
|
|
38
38
|
storageConfig?: StorageConfig;
|
|
39
39
|
/** Walrus storage configuration */
|
|
40
|
+
/** Publisher URL for direct blob uploads (server-side) */
|
|
40
41
|
walrusPublisherUrl?: string;
|
|
42
|
+
/** Upload Relay URL for browser/mobile uploads (fewer connections, faster) */
|
|
43
|
+
walrusUploadRelayUrl?: string;
|
|
44
|
+
/** Aggregator URL for blob retrieval */
|
|
41
45
|
walrusAggregatorUrl?: string;
|
|
42
46
|
walrusMaxFileSize?: number;
|
|
43
47
|
walrusTimeout?: number;
|
|
@@ -17,8 +17,14 @@ export interface WalrusConfig {
|
|
|
17
17
|
network?: 'testnet' | 'mainnet';
|
|
18
18
|
adminAddress?: string;
|
|
19
19
|
storageEpochs?: number;
|
|
20
|
+
/** Publisher URL for direct blob uploads (server-side) */
|
|
21
|
+
publisherHost?: string;
|
|
22
|
+
/** Upload Relay URL for browser/mobile uploads (fewer connections, faster) */
|
|
20
23
|
uploadRelayHost?: string;
|
|
24
|
+
/** Aggregator URL for blob retrieval */
|
|
21
25
|
aggregatorHost?: string;
|
|
26
|
+
/** Use upload relay instead of publisher (default: true for browser, false for server) */
|
|
27
|
+
useUploadRelay?: boolean;
|
|
22
28
|
retryAttempts?: number;
|
|
23
29
|
timeoutMs?: number;
|
|
24
30
|
sealService?: SealService;
|
|
@@ -123,13 +129,21 @@ export class WalrusStorageService {
|
|
|
123
129
|
|
|
124
130
|
constructor(config: Partial<WalrusConfig> = {}) {
|
|
125
131
|
const network = config.network || 'testnet';
|
|
132
|
+
// Detect browser environment for default useUploadRelay
|
|
133
|
+
const isBrowser = typeof window !== 'undefined';
|
|
126
134
|
|
|
127
135
|
this.config = {
|
|
128
136
|
network,
|
|
129
137
|
adminAddress: config.adminAddress || '',
|
|
130
138
|
storageEpochs: config.storageEpochs || 12,
|
|
139
|
+
// Publisher: direct uploads (server-side)
|
|
140
|
+
publisherHost: config.publisherHost || 'https://publisher.walrus-testnet.walrus.space',
|
|
141
|
+
// Upload Relay: optimized for browser/mobile (fewer connections)
|
|
131
142
|
uploadRelayHost: config.uploadRelayHost || 'https://upload-relay.testnet.walrus.space',
|
|
143
|
+
// Aggregator: blob retrieval
|
|
132
144
|
aggregatorHost: config.aggregatorHost || 'https://aggregator.walrus-testnet.walrus.space',
|
|
145
|
+
// Use upload relay by default in browser, publisher on server
|
|
146
|
+
useUploadRelay: config.useUploadRelay ?? isBrowser,
|
|
133
147
|
retryAttempts: config.retryAttempts || 3,
|
|
134
148
|
timeoutMs: config.timeoutMs || 60000,
|
|
135
149
|
sealService: config.sealService,
|
|
@@ -519,9 +533,20 @@ export class WalrusStorageService {
|
|
|
519
533
|
}
|
|
520
534
|
}
|
|
521
535
|
|
|
522
|
-
// Fallback to REST API
|
|
536
|
+
// Fallback to REST API based on useUploadRelay config
|
|
523
537
|
try {
|
|
524
|
-
|
|
538
|
+
let url: string;
|
|
539
|
+
if (this.config.useUploadRelay) {
|
|
540
|
+
// Upload Relay: optimized for browser/mobile (fewer network connections)
|
|
541
|
+
// POST to /v1/blobs endpoint
|
|
542
|
+
url = `${this.config.uploadRelayHost}/v1/blobs?epochs=${this.config.storageEpochs}`;
|
|
543
|
+
} else {
|
|
544
|
+
// Publisher: direct upload (server-side)
|
|
545
|
+
// PUT to /v1/blobs endpoint
|
|
546
|
+
url = `${this.config.publisherHost}/v1/blobs?epochs=${this.config.storageEpochs}`;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
const response = await fetch(url, {
|
|
525
550
|
method: 'PUT',
|
|
526
551
|
headers: {
|
|
527
552
|
'Content-Type': 'application/octet-stream'
|
|
@@ -568,9 +593,9 @@ export class WalrusStorageService {
|
|
|
568
593
|
}
|
|
569
594
|
}
|
|
570
595
|
|
|
571
|
-
// Fallback to REST API
|
|
596
|
+
// Fallback to REST API - Aggregator endpoint: GET /v1/blobs/<blob-id>
|
|
572
597
|
try {
|
|
573
|
-
const response = await fetch(`${this.config.aggregatorHost}/v1/${blobId}`);
|
|
598
|
+
const response = await fetch(`${this.config.aggregatorHost}/v1/blobs/${blobId}`);
|
|
574
599
|
|
|
575
600
|
if (!response.ok) {
|
|
576
601
|
throw new Error(`Retrieval failed: ${response.status} ${response.statusText}`);
|
|
@@ -175,7 +175,7 @@ export class EmbeddingService {
|
|
|
175
175
|
// New behavior: Direct EmbeddingModel from ai-sdk
|
|
176
176
|
this.embeddingModel = config.model;
|
|
177
177
|
this.modelName = 'custom';
|
|
178
|
-
this.dimensions = config.dimensions || 3072
|
|
178
|
+
this.dimensions = config.dimensions || 768; // Default 768 for speed (was 3072)
|
|
179
179
|
this.provider = 'custom';
|
|
180
180
|
console.log('✅ EmbeddingService initialized with custom ai-sdk model');
|
|
181
181
|
return;
|
|
@@ -246,19 +246,26 @@ export class EmbeddingService {
|
|
|
246
246
|
|
|
247
247
|
/**
|
|
248
248
|
* Get default dimensions for provider
|
|
249
|
+
*
|
|
250
|
+
* Default is now 768 for faster performance:
|
|
251
|
+
* - 4x smaller vectors = faster indexing & search
|
|
252
|
+
* - ~4x less storage space
|
|
253
|
+
* - Minimal quality loss for most use cases
|
|
254
|
+
*
|
|
255
|
+
* Users can override via config.dimensions
|
|
249
256
|
*/
|
|
250
257
|
private getDefaultDimensions(provider: string): number {
|
|
251
258
|
switch (provider) {
|
|
252
259
|
case 'google':
|
|
253
|
-
return
|
|
260
|
+
return 768; // text-embedding-004 supports output_dimensionality
|
|
254
261
|
case 'openai':
|
|
255
|
-
return
|
|
262
|
+
return 768; // text-embedding-3-small supports dimensions param
|
|
256
263
|
case 'openrouter':
|
|
257
|
-
return
|
|
264
|
+
return 768; // Most models support dimension truncation
|
|
258
265
|
case 'cohere':
|
|
259
|
-
return
|
|
266
|
+
return 768; // embed-english-v3.0 supports dimensions
|
|
260
267
|
default:
|
|
261
|
-
return
|
|
268
|
+
return 768; // Default to 768 for speed
|
|
262
269
|
}
|
|
263
270
|
}
|
|
264
271
|
|
|
@@ -362,16 +369,25 @@ export class EmbeddingService {
|
|
|
362
369
|
/**
|
|
363
370
|
* Generate embedding using OpenRouter SDK
|
|
364
371
|
* Uses official @openrouter/sdk for embeddings
|
|
372
|
+
* Passes dimensions parameter to truncate output vectors
|
|
365
373
|
*/
|
|
366
374
|
private async embedTextOpenRouter(text: string, startTime: number): Promise<EmbeddingResult> {
|
|
367
375
|
if (!this.openRouterClient) {
|
|
368
376
|
throw new Error('OpenRouter client not initialized');
|
|
369
377
|
}
|
|
370
378
|
|
|
371
|
-
|
|
379
|
+
// Build request with optional dimensions parameter
|
|
380
|
+
const request: any = {
|
|
372
381
|
model: this.modelName,
|
|
373
382
|
input: text
|
|
374
|
-
}
|
|
383
|
+
};
|
|
384
|
+
|
|
385
|
+
// Add dimensions if configured (enables output truncation)
|
|
386
|
+
if (this.dimensions && this.dimensions < 3072) {
|
|
387
|
+
request.dimensions = this.dimensions;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
const result = await this.openRouterClient.embeddings.generate(request);
|
|
375
391
|
|
|
376
392
|
// Handle union type - result can be string or object
|
|
377
393
|
if (typeof result === 'string') {
|
|
@@ -453,16 +469,25 @@ export class EmbeddingService {
|
|
|
453
469
|
|
|
454
470
|
/**
|
|
455
471
|
* Generate batch embeddings using OpenRouter SDK
|
|
472
|
+
* Passes dimensions parameter to truncate output vectors
|
|
456
473
|
*/
|
|
457
474
|
private async embedBatchOpenRouter(texts: string[], startTime: number): Promise<BatchEmbeddingResult> {
|
|
458
475
|
if (!this.openRouterClient) {
|
|
459
476
|
throw new Error('OpenRouter client not initialized');
|
|
460
477
|
}
|
|
461
478
|
|
|
462
|
-
|
|
479
|
+
// Build request with optional dimensions parameter
|
|
480
|
+
const request: any = {
|
|
463
481
|
model: this.modelName,
|
|
464
482
|
input: texts
|
|
465
|
-
}
|
|
483
|
+
};
|
|
484
|
+
|
|
485
|
+
// Add dimensions if configured (enables output truncation)
|
|
486
|
+
if (this.dimensions && this.dimensions < 3072) {
|
|
487
|
+
request.dimensions = this.dimensions;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
const result = await this.openRouterClient.embeddings.generate(request);
|
|
466
491
|
|
|
467
492
|
// Handle union type - result can be string or object
|
|
468
493
|
if (typeof result === 'string') {
|