@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.
Files changed (148) hide show
  1. package/dist/ai-sdk/PDWVectorStore.d.ts.map +1 -1
  2. package/dist/ai-sdk/PDWVectorStore.js +4 -1
  3. package/dist/ai-sdk/PDWVectorStore.js.map +1 -1
  4. package/dist/ai-sdk/tools.d.ts +2 -2
  5. package/dist/ai-sdk/tools.js +2 -2
  6. package/dist/browser.d.ts +5 -6
  7. package/dist/browser.d.ts.map +1 -1
  8. package/dist/browser.js +7 -6
  9. package/dist/browser.js.map +1 -1
  10. package/dist/client/ClientMemoryManager.d.ts +1 -0
  11. package/dist/client/ClientMemoryManager.d.ts.map +1 -1
  12. package/dist/client/ClientMemoryManager.js +5 -1
  13. package/dist/client/ClientMemoryManager.js.map +1 -1
  14. package/dist/client/SimplePDWClient.d.ts +24 -1
  15. package/dist/client/SimplePDWClient.d.ts.map +1 -1
  16. package/dist/client/SimplePDWClient.js +31 -9
  17. package/dist/client/SimplePDWClient.js.map +1 -1
  18. package/dist/client/namespaces/EmbeddingsNamespace.d.ts +1 -1
  19. package/dist/client/namespaces/EmbeddingsNamespace.js +1 -1
  20. package/dist/client/namespaces/IndexNamespace.d.ts +38 -9
  21. package/dist/client/namespaces/IndexNamespace.d.ts.map +1 -1
  22. package/dist/client/namespaces/IndexNamespace.js +77 -10
  23. package/dist/client/namespaces/IndexNamespace.js.map +1 -1
  24. package/dist/client/namespaces/MemoryNamespace.d.ts +27 -0
  25. package/dist/client/namespaces/MemoryNamespace.d.ts.map +1 -1
  26. package/dist/client/namespaces/MemoryNamespace.js +104 -0
  27. package/dist/client/namespaces/MemoryNamespace.js.map +1 -1
  28. package/dist/client/namespaces/SearchNamespace.d.ts.map +1 -1
  29. package/dist/client/namespaces/SearchNamespace.js +25 -14
  30. package/dist/client/namespaces/SearchNamespace.js.map +1 -1
  31. package/dist/client/namespaces/consolidated/AINamespace.d.ts +2 -2
  32. package/dist/client/namespaces/consolidated/AINamespace.js +2 -2
  33. package/dist/client/namespaces/consolidated/BlockchainNamespace.d.ts.map +1 -1
  34. package/dist/client/namespaces/consolidated/BlockchainNamespace.js +69 -1
  35. package/dist/client/namespaces/consolidated/BlockchainNamespace.js.map +1 -1
  36. package/dist/client/namespaces/consolidated/StorageNamespace.d.ts +46 -0
  37. package/dist/client/namespaces/consolidated/StorageNamespace.d.ts.map +1 -1
  38. package/dist/client/namespaces/consolidated/StorageNamespace.js +34 -0
  39. package/dist/client/namespaces/consolidated/StorageNamespace.js.map +1 -1
  40. package/dist/graph/GraphService.js +2 -2
  41. package/dist/graph/GraphService.js.map +1 -1
  42. package/dist/index.d.ts +3 -1
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +3 -1
  45. package/dist/index.js.map +1 -1
  46. package/dist/permissions/ConsentRepository.browser.d.ts +56 -0
  47. package/dist/permissions/ConsentRepository.browser.d.ts.map +1 -0
  48. package/dist/permissions/ConsentRepository.browser.js +198 -0
  49. package/dist/permissions/ConsentRepository.browser.js.map +1 -0
  50. package/dist/retrieval/MemoryRetrievalService.d.ts +31 -0
  51. package/dist/retrieval/MemoryRetrievalService.d.ts.map +1 -1
  52. package/dist/retrieval/MemoryRetrievalService.js +44 -4
  53. package/dist/retrieval/MemoryRetrievalService.js.map +1 -1
  54. package/dist/services/EmbeddingService.d.ts +28 -1
  55. package/dist/services/EmbeddingService.d.ts.map +1 -1
  56. package/dist/services/EmbeddingService.js +54 -0
  57. package/dist/services/EmbeddingService.js.map +1 -1
  58. package/dist/services/GeminiAIService.d.ts.map +1 -1
  59. package/dist/services/GeminiAIService.js +283 -27
  60. package/dist/services/GeminiAIService.js.map +1 -1
  61. package/dist/services/IndexManager.d.ts +5 -1
  62. package/dist/services/IndexManager.d.ts.map +1 -1
  63. package/dist/services/IndexManager.js +17 -40
  64. package/dist/services/IndexManager.js.map +1 -1
  65. package/dist/services/MemoryIndexService.d.ts +31 -2
  66. package/dist/services/MemoryIndexService.d.ts.map +1 -1
  67. package/dist/services/MemoryIndexService.js +75 -3
  68. package/dist/services/MemoryIndexService.js.map +1 -1
  69. package/dist/services/QueryService.js +1 -1
  70. package/dist/services/QueryService.js.map +1 -1
  71. package/dist/services/StorageService.d.ts +10 -0
  72. package/dist/services/StorageService.d.ts.map +1 -1
  73. package/dist/services/StorageService.js +13 -0
  74. package/dist/services/StorageService.js.map +1 -1
  75. package/dist/services/storage/QuiltBatchManager.d.ts +111 -4
  76. package/dist/services/storage/QuiltBatchManager.d.ts.map +1 -1
  77. package/dist/services/storage/QuiltBatchManager.js +450 -38
  78. package/dist/services/storage/QuiltBatchManager.js.map +1 -1
  79. package/dist/services/storage/index.d.ts +1 -1
  80. package/dist/services/storage/index.d.ts.map +1 -1
  81. package/dist/services/storage/index.js.map +1 -1
  82. package/dist/utils/LRUCache.d.ts +106 -0
  83. package/dist/utils/LRUCache.d.ts.map +1 -0
  84. package/dist/utils/LRUCache.js +281 -0
  85. package/dist/utils/LRUCache.js.map +1 -0
  86. package/dist/utils/index.d.ts +1 -0
  87. package/dist/utils/index.d.ts.map +1 -1
  88. package/dist/utils/index.js +2 -0
  89. package/dist/utils/index.js.map +1 -1
  90. package/dist/utils/memoryIndexOnChain.d.ts +212 -0
  91. package/dist/utils/memoryIndexOnChain.d.ts.map +1 -0
  92. package/dist/utils/memoryIndexOnChain.js +312 -0
  93. package/dist/utils/memoryIndexOnChain.js.map +1 -0
  94. package/dist/utils/rebuildIndexNode.d.ts +29 -0
  95. package/dist/utils/rebuildIndexNode.d.ts.map +1 -1
  96. package/dist/utils/rebuildIndexNode.js +387 -45
  97. package/dist/utils/rebuildIndexNode.js.map +1 -1
  98. package/dist/vector/HnswWasmService.d.ts +20 -5
  99. package/dist/vector/HnswWasmService.d.ts.map +1 -1
  100. package/dist/vector/HnswWasmService.js +73 -40
  101. package/dist/vector/HnswWasmService.js.map +1 -1
  102. package/dist/vector/IHnswService.d.ts +10 -1
  103. package/dist/vector/IHnswService.d.ts.map +1 -1
  104. package/dist/vector/IHnswService.js.map +1 -1
  105. package/dist/vector/NodeHnswService.d.ts +16 -0
  106. package/dist/vector/NodeHnswService.d.ts.map +1 -1
  107. package/dist/vector/NodeHnswService.js +108 -10
  108. package/dist/vector/NodeHnswService.js.map +1 -1
  109. package/dist/vector/createHnswService.d.ts +1 -1
  110. package/dist/vector/createHnswService.js +1 -1
  111. package/dist/vector/index.d.ts +1 -1
  112. package/dist/vector/index.js +1 -1
  113. package/package.json +157 -157
  114. package/src/ai-sdk/PDWVectorStore.ts +4 -1
  115. package/src/ai-sdk/tools.ts +2 -2
  116. package/src/browser.ts +15 -10
  117. package/src/client/ClientMemoryManager.ts +6 -1
  118. package/src/client/SimplePDWClient.ts +63 -10
  119. package/src/client/namespaces/EmbeddingsNamespace.ts +1 -1
  120. package/src/client/namespaces/IndexNamespace.ts +89 -11
  121. package/src/client/namespaces/MemoryNamespace.ts +137 -0
  122. package/src/client/namespaces/SearchNamespace.ts +27 -14
  123. package/src/client/namespaces/consolidated/AINamespace.ts +2 -2
  124. package/src/client/namespaces/consolidated/BlockchainNamespace.ts +73 -1
  125. package/src/client/namespaces/consolidated/StorageNamespace.ts +57 -0
  126. package/src/core/types/index.ts +1 -1
  127. package/src/generated/pdw/capability.ts +319 -319
  128. package/src/graph/GraphService.ts +2 -2
  129. package/src/index.ts +25 -1
  130. package/src/permissions/ConsentRepository.browser.ts +249 -0
  131. package/src/retrieval/MemoryRetrievalService.ts +78 -4
  132. package/src/services/EmbeddingService.ts +66 -1
  133. package/src/services/GeminiAIService.ts +283 -27
  134. package/src/services/IndexManager.ts +18 -45
  135. package/src/services/MemoryIndexService.ts +85 -3
  136. package/src/services/QueryService.ts +1 -1
  137. package/src/services/StorageService.ts +15 -0
  138. package/src/services/storage/QuiltBatchManager.ts +538 -42
  139. package/src/services/storage/index.ts +6 -1
  140. package/src/utils/LRUCache.ts +378 -0
  141. package/src/utils/index.ts +8 -0
  142. package/src/utils/memoryIndexOnChain.ts +507 -0
  143. package/src/utils/rebuildIndexNode.ts +482 -52
  144. package/src/vector/HnswWasmService.ts +95 -43
  145. package/src/vector/IHnswService.ts +10 -1
  146. package/src/vector/NodeHnswService.ts +130 -10
  147. package/src/vector/createHnswService.ts +1 -1
  148. 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
- Extract meaningful entities and relationships from the following text. Focus on:
227
- - People (names, roles, professions)
228
- - Organizations (companies, institutions, groups)
229
- - Locations (cities, countries, places)
230
- - Concepts (technologies, ideas, skills)
231
- - Events (meetings, projects, activities)
232
- - Objects (products, tools, resources)
233
-
234
- Return a valid JSON response with "entities" and "relationships" arrays.
235
-
236
- For entities:
237
- - "id": unique identifier using snake_case (e.g., "john_doe", "machine_learning")
238
- - "label": human-readable name (e.g., "John Doe", "Machine Learning")
239
- - "type": entity category (person, organization, location, concept, event, object)
240
- - "confidence": confidence score 0.0-1.0
241
- - "properties": optional additional attributes
242
-
243
- For relationships:
244
- - "source": source entity id
245
- - "target": target entity id
246
- - "label": relationship description (e.g., "works_at", "located_in", "uses")
247
- - "confidence": confidence score 0.0-1.0
248
- - "type": optional relationship category
249
-
250
- Only include entities with confidence >= 0.6 and clear, meaningful relationships.
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: ${content}
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
- private vectorCache: Map<string, Map<number, number[]>> = new Map();
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
- // Initialize vector cache for this space
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
- // Initialize vector cache
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
- // Try to get vectors from VectorService cache first, then fallback to local cache
637
- let vectorMap = this.vectorService.getAllCachedVectors(spaceId);
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
- // Try to get vectors from VectorService cache first, then fallback to local cache
731
- let vectorMap = this.vectorService.getAllCachedVectors(spaceId);
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
- this.vectorCache.delete(spaceId);
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.vectorCache.get(spaceId)?.size || 0,
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
- this.vectorCache.clear();
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' : 'not 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
  /**