@cmdoss/memwal-sdk 0.6.1 → 0.7.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/dist/ai-sdk/PDWVectorStore.d.ts.map +1 -1
- package/dist/ai-sdk/PDWVectorStore.js +4 -1
- package/dist/ai-sdk/PDWVectorStore.js.map +1 -1
- package/dist/ai-sdk/tools.d.ts +2 -2
- package/dist/ai-sdk/tools.js +2 -2
- package/dist/browser.d.ts +5 -6
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +7 -6
- package/dist/browser.js.map +1 -1
- package/dist/client/ClientMemoryManager.d.ts +1 -0
- package/dist/client/ClientMemoryManager.d.ts.map +1 -1
- package/dist/client/ClientMemoryManager.js +5 -1
- package/dist/client/ClientMemoryManager.js.map +1 -1
- package/dist/client/SimplePDWClient.d.ts +24 -1
- package/dist/client/SimplePDWClient.d.ts.map +1 -1
- package/dist/client/SimplePDWClient.js +31 -9
- 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/IndexNamespace.d.ts +38 -9
- package/dist/client/namespaces/IndexNamespace.d.ts.map +1 -1
- package/dist/client/namespaces/IndexNamespace.js +77 -10
- package/dist/client/namespaces/IndexNamespace.js.map +1 -1
- package/dist/client/namespaces/MemoryNamespace.d.ts +27 -0
- package/dist/client/namespaces/MemoryNamespace.d.ts.map +1 -1
- package/dist/client/namespaces/MemoryNamespace.js +104 -0
- package/dist/client/namespaces/MemoryNamespace.js.map +1 -1
- package/dist/client/namespaces/SearchNamespace.d.ts.map +1 -1
- package/dist/client/namespaces/SearchNamespace.js +25 -14
- package/dist/client/namespaces/SearchNamespace.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.map +1 -1
- package/dist/client/namespaces/consolidated/BlockchainNamespace.js +69 -1
- package/dist/client/namespaces/consolidated/BlockchainNamespace.js.map +1 -1
- package/dist/client/namespaces/consolidated/StorageNamespace.d.ts +46 -0
- package/dist/client/namespaces/consolidated/StorageNamespace.d.ts.map +1 -1
- package/dist/client/namespaces/consolidated/StorageNamespace.js +34 -0
- package/dist/client/namespaces/consolidated/StorageNamespace.js.map +1 -1
- package/dist/graph/GraphService.js +2 -2
- 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/permissions/ConsentRepository.browser.d.ts +56 -0
- package/dist/permissions/ConsentRepository.browser.d.ts.map +1 -0
- package/dist/permissions/ConsentRepository.browser.js +198 -0
- package/dist/permissions/ConsentRepository.browser.js.map +1 -0
- 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/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/GeminiAIService.d.ts.map +1 -1
- package/dist/services/GeminiAIService.js +283 -27
- package/dist/services/GeminiAIService.js.map +1 -1
- 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/MemoryIndexService.d.ts +31 -2
- package/dist/services/MemoryIndexService.d.ts.map +1 -1
- package/dist/services/MemoryIndexService.js +75 -3
- package/dist/services/MemoryIndexService.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 +10 -0
- package/dist/services/StorageService.d.ts.map +1 -1
- package/dist/services/StorageService.js +13 -0
- package/dist/services/StorageService.js.map +1 -1
- package/dist/services/storage/QuiltBatchManager.d.ts +111 -4
- package/dist/services/storage/QuiltBatchManager.d.ts.map +1 -1
- package/dist/services/storage/QuiltBatchManager.js +450 -38
- 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 +387 -45
- 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 +108 -10
- 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/ai-sdk/PDWVectorStore.ts +4 -1
- package/src/ai-sdk/tools.ts +2 -2
- package/src/browser.ts +15 -10
- package/src/client/ClientMemoryManager.ts +6 -1
- package/src/client/SimplePDWClient.ts +63 -10
- package/src/client/namespaces/EmbeddingsNamespace.ts +1 -1
- package/src/client/namespaces/IndexNamespace.ts +89 -11
- package/src/client/namespaces/MemoryNamespace.ts +137 -0
- package/src/client/namespaces/SearchNamespace.ts +27 -14
- package/src/client/namespaces/consolidated/AINamespace.ts +2 -2
- package/src/client/namespaces/consolidated/BlockchainNamespace.ts +73 -1
- package/src/client/namespaces/consolidated/StorageNamespace.ts +57 -0
- package/src/core/types/index.ts +1 -1
- package/src/generated/pdw/capability.ts +319 -319
- package/src/graph/GraphService.ts +2 -2
- package/src/index.ts +25 -1
- package/src/permissions/ConsentRepository.browser.ts +249 -0
- package/src/retrieval/MemoryRetrievalService.ts +78 -4
- package/src/services/EmbeddingService.ts +66 -1
- package/src/services/GeminiAIService.ts +283 -27
- package/src/services/IndexManager.ts +18 -45
- package/src/services/MemoryIndexService.ts +85 -3
- package/src/services/QueryService.ts +1 -1
- package/src/services/StorageService.ts +15 -0
- package/src/services/storage/QuiltBatchManager.ts +538 -42
- package/src/services/storage/index.ts +6 -1
- package/src/utils/LRUCache.ts +378 -0
- package/src/utils/index.ts +8 -0
- package/src/utils/memoryIndexOnChain.ts +507 -0
- package/src/utils/rebuildIndexNode.ts +482 -52
- package/src/vector/HnswWasmService.ts +95 -43
- package/src/vector/IHnswService.ts +10 -1
- package/src/vector/NodeHnswService.ts +130 -10
- package/src/vector/createHnswService.ts +1 -1
- package/src/vector/index.ts +1 -1
|
@@ -223,35 +223,291 @@ JSON:`;
|
|
|
223
223
|
const contextSection = context ? `\nCONTEXT: ${context}\n` : '';
|
|
224
224
|
|
|
225
225
|
return `
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
-
|
|
247
|
-
- "
|
|
248
|
-
-
|
|
249
|
-
|
|
250
|
-
|
|
226
|
+
You are a knowledge graph extraction system for a Personal Data Wallet application. Your task is to extract meaningful entities and relationships from personal memories, notes, and user statements.
|
|
227
|
+
|
|
228
|
+
## CRITICAL RULE: User Entity
|
|
229
|
+
ALWAYS include a "user" entity to represent the person who wrote this memory:
|
|
230
|
+
{
|
|
231
|
+
"id": "user",
|
|
232
|
+
"label": "User",
|
|
233
|
+
"type": "person",
|
|
234
|
+
"confidence": 1.0
|
|
235
|
+
}
|
|
236
|
+
This "user" entity should be the source or target of relationships describing personal preferences, attributes, or experiences.
|
|
237
|
+
|
|
238
|
+
## Entity Types (Comprehensive List)
|
|
239
|
+
|
|
240
|
+
### People & Social
|
|
241
|
+
- **person**: Individual people, including the user themselves
|
|
242
|
+
- Examples: "user", "john_doe", "my_mother", "boss"
|
|
243
|
+
- Properties: name, role, relationship_to_user
|
|
244
|
+
|
|
245
|
+
### Organizations & Groups
|
|
246
|
+
- **organization**: Companies, institutions, teams, communities
|
|
247
|
+
- Examples: "google", "harvard_university", "local_gym"
|
|
248
|
+
- Properties: industry, size, location
|
|
249
|
+
|
|
250
|
+
### Locations & Places
|
|
251
|
+
- **location**: Geographic places, addresses, venues
|
|
252
|
+
- Examples: "ho_chi_minh_city", "vietnam", "my_office", "central_park"
|
|
253
|
+
- Properties: type (city/country/venue), coordinates
|
|
254
|
+
|
|
255
|
+
### Food & Dining
|
|
256
|
+
- **food**: Foods, dishes, cuisines, beverages, ingredients
|
|
257
|
+
- Examples: "spaghetti", "vietnamese_cuisine", "coffee", "chocolate"
|
|
258
|
+
- Properties: cuisine_type, meal_type, dietary_info
|
|
259
|
+
- **restaurant**: Eating establishments
|
|
260
|
+
- Examples: "starbucks", "local_pho_shop"
|
|
261
|
+
- Properties: cuisine, price_range
|
|
262
|
+
|
|
263
|
+
### Preferences & Interests
|
|
264
|
+
- **preference**: General likes, dislikes, favorites
|
|
265
|
+
- Examples: "blue_color", "morning_routine", "minimalist_style"
|
|
266
|
+
- Properties: sentiment (positive/negative/neutral), intensity (1-10)
|
|
267
|
+
- **hobby**: Recreational activities, pastimes
|
|
268
|
+
- Examples: "playing_guitar", "photography", "hiking", "gaming"
|
|
269
|
+
- Properties: frequency, skill_level
|
|
270
|
+
- **interest**: Topics of curiosity or passion
|
|
271
|
+
- Examples: "artificial_intelligence", "history", "cooking"
|
|
272
|
+
- Properties: depth (casual/moderate/deep)
|
|
273
|
+
|
|
274
|
+
### Skills & Abilities
|
|
275
|
+
- **skill**: Technical or soft skills, expertise areas
|
|
276
|
+
- Examples: "python_programming", "public_speaking", "cooking"
|
|
277
|
+
- Properties: proficiency (beginner/intermediate/expert)
|
|
278
|
+
- **language**: Languages known or being learned
|
|
279
|
+
- Examples: "english", "vietnamese", "japanese"
|
|
280
|
+
- Properties: proficiency, native (true/false)
|
|
281
|
+
|
|
282
|
+
### Objects & Possessions
|
|
283
|
+
- **object**: Physical items, products, tools
|
|
284
|
+
- Examples: "macbook_pro", "my_car", "guitar"
|
|
285
|
+
- Properties: brand, model, acquisition_date
|
|
286
|
+
- **digital_product**: Software, apps, digital services
|
|
287
|
+
- Examples: "spotify", "notion", "chatgpt"
|
|
288
|
+
- Properties: category, usage_frequency
|
|
289
|
+
|
|
290
|
+
### Time & Events
|
|
291
|
+
- **event**: Occasions, milestones, meetings
|
|
292
|
+
- Examples: "birthday_2024", "job_interview", "vacation_trip"
|
|
293
|
+
- Properties: date, duration, importance
|
|
294
|
+
- **routine**: Regular activities or habits
|
|
295
|
+
- Examples: "morning_workout", "weekly_meeting", "daily_meditation"
|
|
296
|
+
- Properties: frequency, time_of_day
|
|
297
|
+
|
|
298
|
+
### Abstract & Conceptual
|
|
299
|
+
- **concept**: Ideas, topics, abstract things
|
|
300
|
+
- Examples: "work_life_balance", "productivity", "happiness"
|
|
301
|
+
- **goal**: Objectives, aspirations, plans
|
|
302
|
+
- Examples: "learn_japanese", "run_marathon", "save_money"
|
|
303
|
+
- Properties: deadline, priority, status
|
|
304
|
+
- **emotion**: Feelings, moods, emotional states
|
|
305
|
+
- Examples: "happiness", "stress", "excitement"
|
|
306
|
+
- Properties: intensity, trigger
|
|
307
|
+
|
|
308
|
+
### Health & Wellness
|
|
309
|
+
- **health_condition**: Medical conditions, allergies
|
|
310
|
+
- Examples: "lactose_intolerance", "migraine", "allergy_to_peanuts"
|
|
311
|
+
- **medication**: Medicines, supplements
|
|
312
|
+
- Examples: "vitamin_d", "aspirin"
|
|
313
|
+
- **exercise**: Physical activities for health
|
|
314
|
+
- Examples: "running", "yoga", "weight_training"
|
|
315
|
+
|
|
316
|
+
### Media & Entertainment
|
|
317
|
+
- **music**: Songs, artists, genres, albums
|
|
318
|
+
- Examples: "jazz_music", "beatles", "classical_piano"
|
|
319
|
+
- **movie**: Films, TV shows, documentaries
|
|
320
|
+
- Examples: "inception", "game_of_thrones"
|
|
321
|
+
- **book**: Books, authors, genres
|
|
322
|
+
- Examples: "atomic_habits", "fiction_genre"
|
|
323
|
+
- **game**: Video games, board games
|
|
324
|
+
- Examples: "chess", "minecraft"
|
|
325
|
+
|
|
326
|
+
## Relationship Types (Comprehensive List)
|
|
327
|
+
|
|
328
|
+
### Preference Relationships (source: usually "user")
|
|
329
|
+
- **loves**: Strong positive preference (intensity 9-10)
|
|
330
|
+
- **likes**: Moderate positive preference (intensity 6-8)
|
|
331
|
+
- **enjoys**: Positive experience with something
|
|
332
|
+
- **prefers**: Comparative preference
|
|
333
|
+
- **favorite**: Top choice in a category
|
|
334
|
+
- **interested_in**: Curiosity or engagement
|
|
335
|
+
- **dislikes**: Moderate negative preference
|
|
336
|
+
- **hates**: Strong negative preference (intensity 9-10)
|
|
337
|
+
- **avoids**: Intentionally stays away from
|
|
338
|
+
- **allergic_to**: Medical/physical aversion
|
|
339
|
+
|
|
340
|
+
### Affiliation Relationships
|
|
341
|
+
- **works_at**: Employment relationship
|
|
342
|
+
- **studies_at**: Educational institution
|
|
343
|
+
- **member_of**: Group membership
|
|
344
|
+
- **belongs_to**: General affiliation
|
|
345
|
+
- **founded**: Created an organization
|
|
346
|
+
- **leads**: Leadership role
|
|
347
|
+
|
|
348
|
+
### Location Relationships
|
|
349
|
+
- **lives_in**: Current residence
|
|
350
|
+
- **from**: Origin/hometown
|
|
351
|
+
- **located_in**: Physical location
|
|
352
|
+
- **visited**: Past travel
|
|
353
|
+
- **wants_to_visit**: Travel aspiration
|
|
354
|
+
|
|
355
|
+
### Social Relationships
|
|
356
|
+
- **knows**: Acquaintance
|
|
357
|
+
- **friends_with**: Friendship
|
|
358
|
+
- **family_of**: Family relationship (specify: parent, sibling, child, spouse)
|
|
359
|
+
- **works_with**: Professional relationship
|
|
360
|
+
- **mentored_by**: Learning relationship
|
|
361
|
+
|
|
362
|
+
### Skill & Knowledge Relationships
|
|
363
|
+
- **has_skill**: Possesses ability
|
|
364
|
+
- **expert_in**: High proficiency
|
|
365
|
+
- **learning**: Currently acquiring
|
|
366
|
+
- **wants_to_learn**: Aspiration to learn
|
|
367
|
+
- **teaches**: Instructing others
|
|
368
|
+
- **certified_in**: Formal qualification
|
|
369
|
+
|
|
370
|
+
### Possession & Usage
|
|
371
|
+
- **owns**: Ownership
|
|
372
|
+
- **uses**: Regular usage
|
|
373
|
+
- **wants**: Desire to acquire
|
|
374
|
+
- **recommends**: Positive endorsement
|
|
375
|
+
|
|
376
|
+
### Temporal Relationships
|
|
377
|
+
- **started_on**: Beginning date
|
|
378
|
+
- **ended_on**: Ending date
|
|
379
|
+
- **scheduled_for**: Future event
|
|
380
|
+
- **happens_during**: Temporal context
|
|
381
|
+
|
|
382
|
+
### Causal & Descriptive
|
|
383
|
+
- **causes**: Causal relationship
|
|
384
|
+
- **related_to**: General association
|
|
385
|
+
- **part_of**: Component relationship
|
|
386
|
+
- **similar_to**: Similarity
|
|
387
|
+
- **opposite_of**: Contrast
|
|
388
|
+
|
|
389
|
+
## Output Format
|
|
390
|
+
|
|
391
|
+
Return ONLY valid JSON with this structure:
|
|
392
|
+
{
|
|
393
|
+
"entities": [
|
|
394
|
+
{
|
|
395
|
+
"id": "snake_case_identifier",
|
|
396
|
+
"label": "Human Readable Name",
|
|
397
|
+
"type": "entity_type_from_list_above",
|
|
398
|
+
"confidence": 0.0-1.0,
|
|
399
|
+
"properties": { "optional": "attributes" }
|
|
400
|
+
}
|
|
401
|
+
],
|
|
402
|
+
"relationships": [
|
|
403
|
+
{
|
|
404
|
+
"source": "source_entity_id",
|
|
405
|
+
"target": "target_entity_id",
|
|
406
|
+
"label": "relationship_type_from_list_above",
|
|
407
|
+
"confidence": 0.0-1.0,
|
|
408
|
+
"type": "optional_category"
|
|
409
|
+
}
|
|
410
|
+
]
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
## Examples
|
|
414
|
+
|
|
415
|
+
### Example 1: Food Preference
|
|
416
|
+
Input: "i love spaghetti"
|
|
417
|
+
Output:
|
|
418
|
+
{
|
|
419
|
+
"entities": [
|
|
420
|
+
{"id": "user", "label": "User", "type": "person", "confidence": 1.0},
|
|
421
|
+
{"id": "spaghetti", "label": "Spaghetti", "type": "food", "confidence": 0.95, "properties": {"cuisine": "italian", "meal_type": "main_course"}}
|
|
422
|
+
],
|
|
423
|
+
"relationships": [
|
|
424
|
+
{"source": "user", "target": "spaghetti", "label": "loves", "confidence": 0.95, "type": "preference"}
|
|
425
|
+
]
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
### Example 2: Multiple Preferences
|
|
429
|
+
Input: "i like hamburgers but hate vegetables"
|
|
430
|
+
Output:
|
|
431
|
+
{
|
|
432
|
+
"entities": [
|
|
433
|
+
{"id": "user", "label": "User", "type": "person", "confidence": 1.0},
|
|
434
|
+
{"id": "hamburgers", "label": "Hamburgers", "type": "food", "confidence": 0.95},
|
|
435
|
+
{"id": "vegetables", "label": "Vegetables", "type": "food", "confidence": 0.95}
|
|
436
|
+
],
|
|
437
|
+
"relationships": [
|
|
438
|
+
{"source": "user", "target": "hamburgers", "label": "likes", "confidence": 0.9, "type": "preference"},
|
|
439
|
+
{"source": "user", "target": "vegetables", "label": "dislikes", "confidence": 0.9, "type": "preference"}
|
|
440
|
+
]
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
### Example 3: Work Information
|
|
444
|
+
Input: "i work at Google as a software engineer in Mountain View"
|
|
445
|
+
Output:
|
|
446
|
+
{
|
|
447
|
+
"entities": [
|
|
448
|
+
{"id": "user", "label": "User", "type": "person", "confidence": 1.0, "properties": {"role": "software_engineer"}},
|
|
449
|
+
{"id": "google", "label": "Google", "type": "organization", "confidence": 0.98, "properties": {"industry": "technology"}},
|
|
450
|
+
{"id": "software_engineer", "label": "Software Engineer", "type": "skill", "confidence": 0.9},
|
|
451
|
+
{"id": "mountain_view", "label": "Mountain View", "type": "location", "confidence": 0.95, "properties": {"type": "city"}}
|
|
452
|
+
],
|
|
453
|
+
"relationships": [
|
|
454
|
+
{"source": "user", "target": "google", "label": "works_at", "confidence": 0.98, "type": "affiliation"},
|
|
455
|
+
{"source": "user", "target": "software_engineer", "label": "has_skill", "confidence": 0.9, "type": "skill"},
|
|
456
|
+
{"source": "google", "target": "mountain_view", "label": "located_in", "confidence": 0.85, "type": "location"}
|
|
457
|
+
]
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
### Example 4: Personal Life
|
|
461
|
+
Input: "my name is Aaron and I live in Ho Chi Minh City with my wife"
|
|
462
|
+
Output:
|
|
463
|
+
{
|
|
464
|
+
"entities": [
|
|
465
|
+
{"id": "user", "label": "Aaron", "type": "person", "confidence": 1.0, "properties": {"name": "Aaron"}},
|
|
466
|
+
{"id": "ho_chi_minh_city", "label": "Ho Chi Minh City", "type": "location", "confidence": 0.98, "properties": {"type": "city", "country": "Vietnam"}},
|
|
467
|
+
{"id": "wife", "label": "Wife", "type": "person", "confidence": 0.9, "properties": {"relationship": "spouse"}}
|
|
468
|
+
],
|
|
469
|
+
"relationships": [
|
|
470
|
+
{"source": "user", "target": "ho_chi_minh_city", "label": "lives_in", "confidence": 0.98, "type": "location"},
|
|
471
|
+
{"source": "user", "target": "wife", "label": "family_of", "confidence": 0.95, "type": "social", "properties": {"relationship_type": "spouse"}}
|
|
472
|
+
]
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
### Example 5: Hobbies and Interests
|
|
476
|
+
Input: "i enjoy playing guitar and listening to jazz music on weekends"
|
|
477
|
+
Output:
|
|
478
|
+
{
|
|
479
|
+
"entities": [
|
|
480
|
+
{"id": "user", "label": "User", "type": "person", "confidence": 1.0},
|
|
481
|
+
{"id": "playing_guitar", "label": "Playing Guitar", "type": "hobby", "confidence": 0.95},
|
|
482
|
+
{"id": "guitar", "label": "Guitar", "type": "object", "confidence": 0.9, "properties": {"category": "musical_instrument"}},
|
|
483
|
+
{"id": "jazz_music", "label": "Jazz Music", "type": "music", "confidence": 0.95, "properties": {"genre": "jazz"}},
|
|
484
|
+
{"id": "weekends", "label": "Weekends", "type": "routine", "confidence": 0.8, "properties": {"frequency": "weekly"}}
|
|
485
|
+
],
|
|
486
|
+
"relationships": [
|
|
487
|
+
{"source": "user", "target": "playing_guitar", "label": "enjoys", "confidence": 0.95, "type": "hobby"},
|
|
488
|
+
{"source": "playing_guitar", "target": "guitar", "label": "uses", "confidence": 0.9, "type": "activity"},
|
|
489
|
+
{"source": "user", "target": "jazz_music", "label": "enjoys", "confidence": 0.9, "type": "preference"},
|
|
490
|
+
{"source": "playing_guitar", "target": "weekends", "label": "happens_during", "confidence": 0.8, "type": "temporal"}
|
|
491
|
+
]
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
## Guidelines
|
|
495
|
+
|
|
496
|
+
1. **Always include "user" entity** for personal statements (first-person: "I", "my", "me")
|
|
497
|
+
2. **Extract implicit information**: "i'm a doctor" implies medical skill
|
|
498
|
+
3. **Handle negations properly**: "don't like" = dislikes relationship
|
|
499
|
+
4. **Capture intensity**: "love" vs "like" vs "enjoy" = different confidence/intensity
|
|
500
|
+
5. **Include relevant properties**: cuisine type for food, location type for places
|
|
501
|
+
6. **Create bidirectional relationships when applicable**: if A works_at B, B employs A
|
|
502
|
+
7. **Minimum confidence threshold**: 0.5 for entities, 0.5 for relationships
|
|
503
|
+
8. **Be comprehensive**: Extract ALL meaningful entities, even from short texts
|
|
504
|
+
9. **Handle multilingual content**: Vietnamese, English, etc.
|
|
505
|
+
10. **Infer entity types from context**: "spaghetti" = food, "Python" = skill/language based on context
|
|
251
506
|
${contextSection}
|
|
252
|
-
TEXT:
|
|
507
|
+
## TEXT TO ANALYZE:
|
|
508
|
+
${content}
|
|
253
509
|
|
|
254
|
-
JSON:`;
|
|
510
|
+
## JSON OUTPUT:`;
|
|
255
511
|
}
|
|
256
512
|
|
|
257
513
|
private parseExtractionResponse(response: string): { entities: any[]; relationships: any[] } {
|
|
@@ -108,6 +108,10 @@ export interface IndexManagerOptions {
|
|
|
108
108
|
* 2. If failed, rebuild from blockchain + Walrus (slow but complete)
|
|
109
109
|
* 3. Sync any new memories since last save
|
|
110
110
|
* 4. Auto-save periodically
|
|
111
|
+
*
|
|
112
|
+
* Memory Optimization:
|
|
113
|
+
* - Removed duplicate vectorCache - now uses VectorService.getAllCachedVectors()
|
|
114
|
+
* - Vectors are only stored once in VectorService's HnswWasmService LRU cache
|
|
111
115
|
*/
|
|
112
116
|
export class IndexManager {
|
|
113
117
|
private vectorService: VectorService;
|
|
@@ -120,7 +124,7 @@ export class IndexManager {
|
|
|
120
124
|
};
|
|
121
125
|
private autoSaveTimer?: ReturnType<typeof setInterval>;
|
|
122
126
|
private indexStates: Map<string, IndexState> = new Map();
|
|
123
|
-
|
|
127
|
+
// Note: vectorCache removed - now using VectorService.getAllCachedVectors() to avoid duplication
|
|
124
128
|
|
|
125
129
|
// Storage adapter (can be replaced for non-browser environments)
|
|
126
130
|
private storage: {
|
|
@@ -417,16 +421,11 @@ export class IndexManager {
|
|
|
417
421
|
efConstruction: pkg.hnswConfig.efConstruction,
|
|
418
422
|
});
|
|
419
423
|
|
|
420
|
-
//
|
|
421
|
-
const vectorMap = new Map<number, number[]>();
|
|
422
|
-
this.vectorCache.set(spaceId, vectorMap);
|
|
423
|
-
|
|
424
|
-
// Restore vectors and metadata
|
|
424
|
+
// Restore vectors and metadata (VectorService caches vectors internally)
|
|
425
425
|
const metadataMap = new Map<number, any>(pkg.metadata);
|
|
426
426
|
|
|
427
427
|
for (const { vectorId, vector } of pkg.vectors) {
|
|
428
428
|
await this.vectorService.addVector(spaceId, vectorId, vector, metadataMap.get(vectorId));
|
|
429
|
-
vectorMap.set(vectorId, vector);
|
|
430
429
|
}
|
|
431
430
|
|
|
432
431
|
// Update index state
|
|
@@ -482,11 +481,7 @@ export class IndexManager {
|
|
|
482
481
|
efConstruction: 200,
|
|
483
482
|
});
|
|
484
483
|
|
|
485
|
-
//
|
|
486
|
-
const vectorMap = new Map<number, number[]>();
|
|
487
|
-
this.vectorCache.set(spaceId, vectorMap);
|
|
488
|
-
|
|
489
|
-
// Process each memory
|
|
484
|
+
// Process each memory (VectorService caches vectors internally)
|
|
490
485
|
let processed = 0;
|
|
491
486
|
const batchSize = 10;
|
|
492
487
|
|
|
@@ -514,7 +509,7 @@ export class IndexManager {
|
|
|
514
509
|
|
|
515
510
|
const vectorId = memory.vectorId ?? Date.now() % 4294967295;
|
|
516
511
|
|
|
517
|
-
// Add to index
|
|
512
|
+
// Add to index (VectorService caches vector internally)
|
|
518
513
|
await this.vectorService.addVector(spaceId, vectorId, embedding, {
|
|
519
514
|
blobId: memory.blobId,
|
|
520
515
|
memoryId: memory.id,
|
|
@@ -524,9 +519,6 @@ export class IndexManager {
|
|
|
524
519
|
timestamp: memory.createdAt || Date.now(),
|
|
525
520
|
});
|
|
526
521
|
|
|
527
|
-
// Cache vector for serialization
|
|
528
|
-
vectorMap.set(vectorId, embedding);
|
|
529
|
-
|
|
530
522
|
processed++;
|
|
531
523
|
} catch (error) {
|
|
532
524
|
console.warn(`Failed to rebuild memory ${memory.id}:`, error);
|
|
@@ -579,13 +571,6 @@ export class IndexManager {
|
|
|
579
571
|
|
|
580
572
|
console.log(`🔄 Syncing ${newMemories.length} new memories...`);
|
|
581
573
|
|
|
582
|
-
// Get or create vector cache
|
|
583
|
-
let vectorMap = this.vectorCache.get(spaceId);
|
|
584
|
-
if (!vectorMap) {
|
|
585
|
-
vectorMap = new Map();
|
|
586
|
-
this.vectorCache.set(spaceId, vectorMap);
|
|
587
|
-
}
|
|
588
|
-
|
|
589
574
|
let synced = 0;
|
|
590
575
|
|
|
591
576
|
for (const memory of newMemories) {
|
|
@@ -601,6 +586,7 @@ export class IndexManager {
|
|
|
601
586
|
|
|
602
587
|
const vectorId = memory.vectorId ?? Date.now() % 4294967295;
|
|
603
588
|
|
|
589
|
+
// Add to index (VectorService caches vector internally)
|
|
604
590
|
await this.vectorService.addVector(spaceId, vectorId, embedding, {
|
|
605
591
|
blobId: memory.blobId,
|
|
606
592
|
memoryId: memory.id,
|
|
@@ -610,7 +596,6 @@ export class IndexManager {
|
|
|
610
596
|
timestamp: memory.createdAt || Date.now(),
|
|
611
597
|
});
|
|
612
598
|
|
|
613
|
-
vectorMap.set(vectorId, embedding);
|
|
614
599
|
synced++;
|
|
615
600
|
} catch (error) {
|
|
616
601
|
console.warn(`Failed to sync memory ${memory.id}:`, error);
|
|
@@ -633,11 +618,8 @@ export class IndexManager {
|
|
|
633
618
|
// Get all vectors and metadata
|
|
634
619
|
const allVectors = this.vectorService.getAllVectors(spaceId);
|
|
635
620
|
|
|
636
|
-
//
|
|
637
|
-
|
|
638
|
-
if (vectorMap.size === 0) {
|
|
639
|
-
vectorMap = this.vectorCache.get(spaceId) || new Map();
|
|
640
|
-
}
|
|
621
|
+
// Get vectors from VectorService cache (single source of truth)
|
|
622
|
+
const vectorMap = this.vectorService.getAllCachedVectors(spaceId);
|
|
641
623
|
|
|
642
624
|
if (vectorMap.size === 0) {
|
|
643
625
|
console.warn('Vector cache is empty, cannot save index');
|
|
@@ -727,11 +709,8 @@ export class IndexManager {
|
|
|
727
709
|
|
|
728
710
|
const allVectors = this.vectorService.getAllVectors(spaceId);
|
|
729
711
|
|
|
730
|
-
//
|
|
731
|
-
|
|
732
|
-
if (vectorMap.size === 0) {
|
|
733
|
-
vectorMap = this.vectorCache.get(spaceId) || new Map();
|
|
734
|
-
}
|
|
712
|
+
// Get vectors from VectorService cache (single source of truth)
|
|
713
|
+
const vectorMap = this.vectorService.getAllCachedVectors(spaceId);
|
|
735
714
|
|
|
736
715
|
if (vectorMap.size === 0) {
|
|
737
716
|
console.warn('Vector cache is empty, cannot save index');
|
|
@@ -855,6 +834,7 @@ export class IndexManager {
|
|
|
855
834
|
|
|
856
835
|
/**
|
|
857
836
|
* Add vector and cache it for serialization
|
|
837
|
+
* Note: VectorService now handles caching internally, this method is kept for API compatibility
|
|
858
838
|
*/
|
|
859
839
|
async addVectorWithCache(
|
|
860
840
|
spaceId: string,
|
|
@@ -862,15 +842,8 @@ export class IndexManager {
|
|
|
862
842
|
vector: number[],
|
|
863
843
|
metadata?: any
|
|
864
844
|
): Promise<void> {
|
|
845
|
+
// VectorService.addVector now caches vectors internally
|
|
865
846
|
await this.vectorService.addVector(spaceId, vectorId, vector, metadata);
|
|
866
|
-
|
|
867
|
-
// Cache vector for later serialization
|
|
868
|
-
let vectorMap = this.vectorCache.get(spaceId);
|
|
869
|
-
if (!vectorMap) {
|
|
870
|
-
vectorMap = new Map();
|
|
871
|
-
this.vectorCache.set(spaceId, vectorMap);
|
|
872
|
-
}
|
|
873
|
-
vectorMap.set(vectorId, vector);
|
|
874
847
|
}
|
|
875
848
|
|
|
876
849
|
/**
|
|
@@ -940,7 +913,7 @@ export class IndexManager {
|
|
|
940
913
|
const key = `${this.options.storageKeyPrefix}${spaceId}`;
|
|
941
914
|
this.storage.removeItem(key);
|
|
942
915
|
this.indexStates.delete(spaceId);
|
|
943
|
-
|
|
916
|
+
// Note: VectorService cache is managed by HnswWasmService LRU cache
|
|
944
917
|
console.log(`Cleared index state for ${spaceId}`);
|
|
945
918
|
}
|
|
946
919
|
|
|
@@ -988,7 +961,7 @@ export class IndexManager {
|
|
|
988
961
|
} {
|
|
989
962
|
return {
|
|
990
963
|
indexState: this.getIndexState(spaceId),
|
|
991
|
-
vectorCacheSize: this.
|
|
964
|
+
vectorCacheSize: this.vectorService.getAllCachedVectors(spaceId).size,
|
|
992
965
|
isAutoSaveEnabled: !!this.autoSaveTimer,
|
|
993
966
|
};
|
|
994
967
|
}
|
|
@@ -999,6 +972,6 @@ export class IndexManager {
|
|
|
999
972
|
async cleanup(): Promise<void> {
|
|
1000
973
|
this.stopAutoSave();
|
|
1001
974
|
this.indexStates.clear();
|
|
1002
|
-
|
|
975
|
+
// Note: VectorService cleanup is handled by its own cleanup() method
|
|
1003
976
|
}
|
|
1004
977
|
}
|
|
@@ -568,18 +568,34 @@ export class MemoryIndexService {
|
|
|
568
568
|
}
|
|
569
569
|
|
|
570
570
|
/**
|
|
571
|
-
* Load index from storage
|
|
571
|
+
* Load index from storage (local or Walrus)
|
|
572
|
+
*
|
|
573
|
+
* @param userAddress - User's wallet address
|
|
574
|
+
* @param indexBlobId - Optional Walrus blob ID to load from cloud
|
|
572
575
|
*/
|
|
573
576
|
async loadIndex(userAddress: string, indexBlobId?: string): Promise<void> {
|
|
574
577
|
const hnswService = await this.getHnswService();
|
|
578
|
+
|
|
579
|
+
// If blobId provided, try to load from Walrus first
|
|
580
|
+
if (indexBlobId && 'loadFromWalrus' in hnswService) {
|
|
581
|
+
console.log(`📥 Attempting to load index from Walrus: ${indexBlobId}`);
|
|
582
|
+
const walrusLoaded = await (hnswService as any).loadFromWalrus(userAddress, indexBlobId);
|
|
583
|
+
if (walrusLoaded) {
|
|
584
|
+
console.log(`✅ Memory index loaded from Walrus for user ${userAddress}`);
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
587
|
+
console.log(`⚠️ Walrus load failed, falling back to local storage`);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
// Fallback to local storage
|
|
575
591
|
const loaded = await hnswService.loadIndex(userAddress);
|
|
576
592
|
if (loaded) {
|
|
577
|
-
console.log(`✅ Memory index loaded for user ${userAddress}`);
|
|
593
|
+
console.log(`✅ Memory index loaded from local storage for user ${userAddress}`);
|
|
578
594
|
}
|
|
579
595
|
}
|
|
580
596
|
|
|
581
597
|
/**
|
|
582
|
-
* Save index to storage
|
|
598
|
+
* Save index to local storage
|
|
583
599
|
*/
|
|
584
600
|
async saveIndex(userAddress: string): Promise<void> {
|
|
585
601
|
const hnswService = await this.getHnswService();
|
|
@@ -587,6 +603,72 @@ export class MemoryIndexService {
|
|
|
587
603
|
console.log(`✅ Memory index saved for user ${userAddress}`);
|
|
588
604
|
}
|
|
589
605
|
|
|
606
|
+
/**
|
|
607
|
+
* Sync index to Walrus cloud storage
|
|
608
|
+
*
|
|
609
|
+
* @param userAddress - User's wallet address
|
|
610
|
+
* @returns Walrus blob ID if successful, null if Walrus is disabled
|
|
611
|
+
*/
|
|
612
|
+
async syncToWalrus(userAddress: string): Promise<string | null> {
|
|
613
|
+
const hnswService = await this.getHnswService();
|
|
614
|
+
|
|
615
|
+
if (!('syncToWalrus' in hnswService)) {
|
|
616
|
+
console.warn('⚠️ HNSW service does not support Walrus sync');
|
|
617
|
+
return null;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
const blobId = await (hnswService as any).syncToWalrus(userAddress);
|
|
621
|
+
if (blobId) {
|
|
622
|
+
console.log(`☁️ Memory index synced to Walrus: ${blobId}`);
|
|
623
|
+
}
|
|
624
|
+
return blobId;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
/**
|
|
628
|
+
* Load index directly from Walrus cloud storage
|
|
629
|
+
*
|
|
630
|
+
* @param userAddress - User's wallet address
|
|
631
|
+
* @param blobId - Walrus blob ID
|
|
632
|
+
* @returns true if successfully loaded
|
|
633
|
+
*/
|
|
634
|
+
async loadFromWalrus(userAddress: string, blobId: string): Promise<boolean> {
|
|
635
|
+
const hnswService = await this.getHnswService();
|
|
636
|
+
|
|
637
|
+
if (!('loadFromWalrus' in hnswService)) {
|
|
638
|
+
console.warn('⚠️ HNSW service does not support Walrus load');
|
|
639
|
+
return false;
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
const loaded = await (hnswService as any).loadFromWalrus(userAddress, blobId);
|
|
643
|
+
if (loaded) {
|
|
644
|
+
console.log(`☁️ Memory index loaded from Walrus: ${blobId}`);
|
|
645
|
+
}
|
|
646
|
+
return loaded;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
/**
|
|
650
|
+
* Get the Walrus blob ID for a user's index (if backed up)
|
|
651
|
+
*
|
|
652
|
+
* @param userAddress - User's wallet address
|
|
653
|
+
* @returns Blob ID or null if not backed up
|
|
654
|
+
*/
|
|
655
|
+
getWalrusBlobId(userAddress: string): string | null {
|
|
656
|
+
if (this.hnswService && 'getWalrusBlobId' in this.hnswService) {
|
|
657
|
+
return (this.hnswService as any).getWalrusBlobId(userAddress);
|
|
658
|
+
}
|
|
659
|
+
return null;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
/**
|
|
663
|
+
* Check if Walrus backup is enabled
|
|
664
|
+
*/
|
|
665
|
+
isWalrusEnabled(): boolean {
|
|
666
|
+
if (this.hnswService && 'isWalrusEnabled' in this.hnswService) {
|
|
667
|
+
return (this.hnswService as any).isWalrusEnabled();
|
|
668
|
+
}
|
|
669
|
+
return false;
|
|
670
|
+
}
|
|
671
|
+
|
|
590
672
|
/**
|
|
591
673
|
* Clear user's index
|
|
592
674
|
*/
|
|
@@ -136,7 +136,7 @@ export class QueryService {
|
|
|
136
136
|
console.log(` Model: ${stats.model}, Dimensions: ${stats.dimensions}`);
|
|
137
137
|
}
|
|
138
138
|
console.log(` Storage: ${!!storageService ? 'available' : 'not available'}`);
|
|
139
|
-
console.log(` Knowledge Graph: ${!!graphService ? 'available' : '
|
|
139
|
+
console.log(` Knowledge Graph: ${!!graphService ? 'available' : 'pending initialization...'}`);
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
/**
|
|
@@ -916,6 +916,21 @@ export class StorageService {
|
|
|
916
916
|
return this.quiltBatch.listQuiltPatches(quiltId);
|
|
917
917
|
}
|
|
918
918
|
|
|
919
|
+
/**
|
|
920
|
+
* Get all memory packages from a Quilt as JSON
|
|
921
|
+
* Used for indexing Quilt memories into local HNSW index
|
|
922
|
+
*/
|
|
923
|
+
async getAllMemoryPackages(quiltId: string) {
|
|
924
|
+
return this.quiltBatch.getAllMemoryPackages(quiltId);
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
/**
|
|
928
|
+
* Get the QuiltBatchManager instance for advanced operations
|
|
929
|
+
*/
|
|
930
|
+
get quiltBatchManager(): QuiltBatchManager {
|
|
931
|
+
return this.quiltBatch;
|
|
932
|
+
}
|
|
933
|
+
|
|
919
934
|
// ==================== BLOB ATTRIBUTES (Delegate to BlobAttributesManager) ====================
|
|
920
935
|
|
|
921
936
|
/**
|