@mnemoai/core 1.1.0 → 1.1.2

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 (220) hide show
  1. package/dist/cli.d.ts +2 -0
  2. package/dist/cli.d.ts.map +1 -0
  3. package/dist/cli.js +7 -0
  4. package/dist/cli.js.map +7 -0
  5. package/dist/index.d.ts +136 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/{index.ts → dist/index.js} +537 -1333
  8. package/dist/index.js.map +7 -0
  9. package/dist/src/access-tracker.d.ts +97 -0
  10. package/dist/src/access-tracker.d.ts.map +1 -0
  11. package/dist/src/access-tracker.js +184 -0
  12. package/dist/src/access-tracker.js.map +7 -0
  13. package/dist/src/adapters/chroma.d.ts +31 -0
  14. package/dist/src/adapters/chroma.d.ts.map +1 -0
  15. package/{src/adapters/chroma.ts → dist/src/adapters/chroma.js} +45 -107
  16. package/dist/src/adapters/chroma.js.map +7 -0
  17. package/dist/src/adapters/lancedb.d.ts +29 -0
  18. package/dist/src/adapters/lancedb.d.ts.map +1 -0
  19. package/{src/adapters/lancedb.ts → dist/src/adapters/lancedb.js} +41 -109
  20. package/dist/src/adapters/lancedb.js.map +7 -0
  21. package/dist/src/adapters/pgvector.d.ts +33 -0
  22. package/dist/src/adapters/pgvector.d.ts.map +1 -0
  23. package/{src/adapters/pgvector.ts → dist/src/adapters/pgvector.js} +42 -104
  24. package/dist/src/adapters/pgvector.js.map +7 -0
  25. package/dist/src/adapters/qdrant.d.ts +34 -0
  26. package/dist/src/adapters/qdrant.d.ts.map +1 -0
  27. package/dist/src/adapters/qdrant.js +132 -0
  28. package/dist/src/adapters/qdrant.js.map +7 -0
  29. package/dist/src/adaptive-retrieval.d.ts +14 -0
  30. package/dist/src/adaptive-retrieval.d.ts.map +1 -0
  31. package/dist/src/adaptive-retrieval.js +52 -0
  32. package/dist/src/adaptive-retrieval.js.map +7 -0
  33. package/dist/src/audit-log.d.ts +56 -0
  34. package/dist/src/audit-log.d.ts.map +1 -0
  35. package/dist/src/audit-log.js +139 -0
  36. package/dist/src/audit-log.js.map +7 -0
  37. package/dist/src/chunker.d.ts +45 -0
  38. package/dist/src/chunker.d.ts.map +1 -0
  39. package/dist/src/chunker.js +157 -0
  40. package/dist/src/chunker.js.map +7 -0
  41. package/dist/src/config.d.ts +70 -0
  42. package/dist/src/config.d.ts.map +1 -0
  43. package/dist/src/config.js +142 -0
  44. package/dist/src/config.js.map +7 -0
  45. package/dist/src/decay-engine.d.ts +73 -0
  46. package/dist/src/decay-engine.d.ts.map +1 -0
  47. package/dist/src/decay-engine.js +119 -0
  48. package/dist/src/decay-engine.js.map +7 -0
  49. package/dist/src/embedder.d.ts +94 -0
  50. package/dist/src/embedder.d.ts.map +1 -0
  51. package/{src/embedder.ts → dist/src/embedder.js} +119 -317
  52. package/dist/src/embedder.js.map +7 -0
  53. package/dist/src/extraction-prompts.d.ts +12 -0
  54. package/dist/src/extraction-prompts.d.ts.map +1 -0
  55. package/dist/src/extraction-prompts.js +311 -0
  56. package/dist/src/extraction-prompts.js.map +7 -0
  57. package/dist/src/license.d.ts +29 -0
  58. package/dist/src/license.d.ts.map +1 -0
  59. package/{src/license.ts → dist/src/license.js} +42 -113
  60. package/dist/src/license.js.map +7 -0
  61. package/dist/src/llm-client.d.ts +23 -0
  62. package/dist/src/llm-client.d.ts.map +1 -0
  63. package/{src/llm-client.ts → dist/src/llm-client.js} +22 -55
  64. package/dist/src/llm-client.js.map +7 -0
  65. package/dist/src/logger.d.ts +33 -0
  66. package/dist/src/logger.d.ts.map +1 -0
  67. package/dist/src/logger.js +35 -0
  68. package/dist/src/logger.js.map +7 -0
  69. package/dist/src/mcp-server.d.ts +16 -0
  70. package/dist/src/mcp-server.d.ts.map +1 -0
  71. package/{src/mcp-server.ts → dist/src/mcp-server.js} +81 -181
  72. package/dist/src/mcp-server.js.map +7 -0
  73. package/dist/src/memory-categories.d.ts +40 -0
  74. package/dist/src/memory-categories.d.ts.map +1 -0
  75. package/dist/src/memory-categories.js +33 -0
  76. package/dist/src/memory-categories.js.map +7 -0
  77. package/dist/src/memory-upgrader.d.ts +71 -0
  78. package/dist/src/memory-upgrader.d.ts.map +1 -0
  79. package/dist/src/memory-upgrader.js +238 -0
  80. package/dist/src/memory-upgrader.js.map +7 -0
  81. package/dist/src/migrate.d.ts +47 -0
  82. package/dist/src/migrate.d.ts.map +1 -0
  83. package/{src/migrate.ts → dist/src/migrate.js} +57 -165
  84. package/dist/src/migrate.js.map +7 -0
  85. package/dist/src/mnemo.d.ts +67 -0
  86. package/dist/src/mnemo.d.ts.map +1 -0
  87. package/dist/src/mnemo.js +66 -0
  88. package/dist/src/mnemo.js.map +7 -0
  89. package/dist/src/noise-filter.d.ts +23 -0
  90. package/dist/src/noise-filter.d.ts.map +1 -0
  91. package/dist/src/noise-filter.js +62 -0
  92. package/dist/src/noise-filter.js.map +7 -0
  93. package/dist/src/noise-prototypes.d.ts +40 -0
  94. package/dist/src/noise-prototypes.d.ts.map +1 -0
  95. package/dist/src/noise-prototypes.js +116 -0
  96. package/dist/src/noise-prototypes.js.map +7 -0
  97. package/dist/src/observability.d.ts +16 -0
  98. package/dist/src/observability.d.ts.map +1 -0
  99. package/dist/src/observability.js +53 -0
  100. package/dist/src/observability.js.map +7 -0
  101. package/dist/src/query-tracker.d.ts +27 -0
  102. package/dist/src/query-tracker.d.ts.map +1 -0
  103. package/dist/src/query-tracker.js +32 -0
  104. package/dist/src/query-tracker.js.map +7 -0
  105. package/dist/src/reflection-event-store.d.ts +44 -0
  106. package/dist/src/reflection-event-store.d.ts.map +1 -0
  107. package/dist/src/reflection-event-store.js +50 -0
  108. package/dist/src/reflection-event-store.js.map +7 -0
  109. package/dist/src/reflection-item-store.d.ts +58 -0
  110. package/dist/src/reflection-item-store.d.ts.map +1 -0
  111. package/dist/src/reflection-item-store.js +69 -0
  112. package/dist/src/reflection-item-store.js.map +7 -0
  113. package/dist/src/reflection-mapped-metadata.d.ts +47 -0
  114. package/dist/src/reflection-mapped-metadata.d.ts.map +1 -0
  115. package/dist/src/reflection-mapped-metadata.js +40 -0
  116. package/dist/src/reflection-mapped-metadata.js.map +7 -0
  117. package/dist/src/reflection-metadata.d.ts +11 -0
  118. package/dist/src/reflection-metadata.d.ts.map +1 -0
  119. package/dist/src/reflection-metadata.js +24 -0
  120. package/dist/src/reflection-metadata.js.map +7 -0
  121. package/dist/src/reflection-ranking.d.ts +13 -0
  122. package/dist/src/reflection-ranking.d.ts.map +1 -0
  123. package/{src/reflection-ranking.ts → dist/src/reflection-ranking.js} +12 -21
  124. package/dist/src/reflection-ranking.js.map +7 -0
  125. package/dist/src/reflection-retry.d.ts +30 -0
  126. package/dist/src/reflection-retry.d.ts.map +1 -0
  127. package/{src/reflection-retry.ts → dist/src/reflection-retry.js} +24 -64
  128. package/dist/src/reflection-retry.js.map +7 -0
  129. package/dist/src/reflection-slices.d.ts +42 -0
  130. package/dist/src/reflection-slices.d.ts.map +1 -0
  131. package/{src/reflection-slices.ts → dist/src/reflection-slices.js} +60 -136
  132. package/dist/src/reflection-slices.js.map +7 -0
  133. package/dist/src/reflection-store.d.ts +85 -0
  134. package/dist/src/reflection-store.d.ts.map +1 -0
  135. package/dist/src/reflection-store.js +407 -0
  136. package/dist/src/reflection-store.js.map +7 -0
  137. package/dist/src/resonance-state.d.ts +19 -0
  138. package/dist/src/resonance-state.d.ts.map +1 -0
  139. package/{src/resonance-state.ts → dist/src/resonance-state.js} +13 -42
  140. package/dist/src/resonance-state.js.map +7 -0
  141. package/dist/src/retriever.d.ts +228 -0
  142. package/dist/src/retriever.d.ts.map +1 -0
  143. package/dist/src/retriever.js +1006 -0
  144. package/dist/src/retriever.js.map +7 -0
  145. package/dist/src/scopes.d.ts +58 -0
  146. package/dist/src/scopes.d.ts.map +1 -0
  147. package/dist/src/scopes.js +252 -0
  148. package/dist/src/scopes.js.map +7 -0
  149. package/dist/src/self-improvement-files.d.ts +20 -0
  150. package/dist/src/self-improvement-files.d.ts.map +1 -0
  151. package/{src/self-improvement-files.ts → dist/src/self-improvement-files.js} +24 -49
  152. package/dist/src/self-improvement-files.js.map +7 -0
  153. package/dist/src/semantic-gate.d.ts +24 -0
  154. package/dist/src/semantic-gate.d.ts.map +1 -0
  155. package/dist/src/semantic-gate.js +86 -0
  156. package/dist/src/semantic-gate.js.map +7 -0
  157. package/dist/src/session-recovery.d.ts +9 -0
  158. package/dist/src/session-recovery.d.ts.map +1 -0
  159. package/{src/session-recovery.ts → dist/src/session-recovery.js} +40 -57
  160. package/dist/src/session-recovery.js.map +7 -0
  161. package/dist/src/smart-extractor.d.ts +107 -0
  162. package/dist/src/smart-extractor.d.ts.map +1 -0
  163. package/{src/smart-extractor.ts → dist/src/smart-extractor.js} +130 -383
  164. package/dist/src/smart-extractor.js.map +7 -0
  165. package/dist/src/smart-metadata.d.ts +103 -0
  166. package/dist/src/smart-metadata.d.ts.map +1 -0
  167. package/dist/src/smart-metadata.js +361 -0
  168. package/dist/src/smart-metadata.js.map +7 -0
  169. package/dist/src/storage-adapter.d.ts +102 -0
  170. package/dist/src/storage-adapter.d.ts.map +1 -0
  171. package/dist/src/storage-adapter.js +22 -0
  172. package/dist/src/storage-adapter.js.map +7 -0
  173. package/dist/src/store.d.ts +108 -0
  174. package/dist/src/store.d.ts.map +1 -0
  175. package/dist/src/store.js +939 -0
  176. package/dist/src/store.js.map +7 -0
  177. package/dist/src/tier-manager.d.ts +57 -0
  178. package/dist/src/tier-manager.d.ts.map +1 -0
  179. package/dist/src/tier-manager.js +80 -0
  180. package/dist/src/tier-manager.js.map +7 -0
  181. package/dist/src/tools.d.ts +43 -0
  182. package/dist/src/tools.d.ts.map +1 -0
  183. package/dist/src/tools.js +1075 -0
  184. package/dist/src/tools.js.map +7 -0
  185. package/dist/src/wal-recovery.d.ts +30 -0
  186. package/dist/src/wal-recovery.d.ts.map +1 -0
  187. package/{src/wal-recovery.ts → dist/src/wal-recovery.js} +26 -79
  188. package/dist/src/wal-recovery.js.map +7 -0
  189. package/package.json +21 -2
  190. package/openclaw.plugin.json +0 -815
  191. package/src/access-tracker.ts +0 -341
  192. package/src/adapters/README.md +0 -78
  193. package/src/adapters/qdrant.ts +0 -191
  194. package/src/adaptive-retrieval.ts +0 -90
  195. package/src/audit-log.ts +0 -238
  196. package/src/chunker.ts +0 -254
  197. package/src/config.ts +0 -271
  198. package/src/decay-engine.ts +0 -238
  199. package/src/extraction-prompts.ts +0 -339
  200. package/src/memory-categories.ts +0 -71
  201. package/src/memory-upgrader.ts +0 -388
  202. package/src/mnemo.ts +0 -142
  203. package/src/noise-filter.ts +0 -97
  204. package/src/noise-prototypes.ts +0 -164
  205. package/src/observability.ts +0 -81
  206. package/src/query-tracker.ts +0 -57
  207. package/src/reflection-event-store.ts +0 -98
  208. package/src/reflection-item-store.ts +0 -112
  209. package/src/reflection-mapped-metadata.ts +0 -84
  210. package/src/reflection-metadata.ts +0 -23
  211. package/src/reflection-store.ts +0 -602
  212. package/src/retriever.ts +0 -1510
  213. package/src/scopes.ts +0 -375
  214. package/src/semantic-gate.ts +0 -121
  215. package/src/smart-metadata.ts +0 -561
  216. package/src/storage-adapter.ts +0 -153
  217. package/src/store.ts +0 -1330
  218. package/src/tier-manager.ts +0 -189
  219. package/src/tools.ts +0 -1292
  220. package/test/core.test.mjs +0 -301
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/smart-metadata.ts"],
4
+ "sourcesContent": ["// SPDX-License-Identifier: MIT\nimport type { MemoryCategory, MemoryTier } from \"./memory-categories.js\";\nimport type { DecayableMemory } from \"./decay-engine.js\";\n\ntype LegacyStoreCategory =\n | \"preference\"\n | \"fact\"\n | \"decision\"\n | \"entity\"\n | \"other\"\n | \"reflection\";\n\ntype EntryLike = {\n text?: string;\n category?: LegacyStoreCategory;\n importance?: number;\n timestamp?: number;\n metadata?: string;\n};\n\nexport interface SmartMemoryMetadata {\n l0_abstract: string;\n l1_overview: string;\n l2_content: string;\n memory_category: MemoryCategory;\n tier: MemoryTier;\n access_count: number;\n confidence: number;\n last_accessed_at: number;\n source_session?: string;\n /** Emotional salience score (0-1). Higher = more emotionally significant = decays slower.\n * Computed at store time via heuristic rules (zero LLM cost). */\n emotional_salience: number;\n [key: string]: unknown;\n}\n\nexport interface LifecycleMemory {\n id: string;\n importance: number;\n confidence: number;\n tier: MemoryTier;\n accessCount: number;\n createdAt: number;\n lastAccessedAt: number;\n emotionalSalience: number;\n}\n\nfunction clamp01(value: unknown, fallback: number): number {\n const n = typeof value === \"number\" ? value : Number(value);\n if (!Number.isFinite(n)) return fallback;\n return Math.min(1, Math.max(0, n));\n}\n\nfunction clampCount(value: unknown, fallback = 0): number {\n const n = typeof value === \"number\" ? value : Number(value);\n if (!Number.isFinite(n) || n < 0) return fallback;\n return Math.floor(n);\n}\n\n// ============================================================================\n// Emotional Salience \u2014 heuristic scoring (zero LLM cost)\n// ============================================================================\n\n/** High-salience signal patterns (decisions, strong emotions, firsts, money, people) */\nconst SALIENCE_BOOSTERS: Array<{ pattern: RegExp; boost: number }> = [\n // Decisions and commitments\n { pattern: /\\b(\u51B3\u5B9A|\u51B3\u7B56|confirmed|decided|commit|approved|\u6279\u4E86|\u62CD\u677F|\u5B9A\u4E86)\\b/i, boost: 0.3 },\n // Strong emotions\n { pattern: /\\b(\u9707\u60CA|\u60CA\u559C|\u6124\u6012|\u5931\u671B|\u5174\u594B|amazing|shocked|frustrated|excited|worried|\u62C5\u5FC3)\\b/i, boost: 0.25 },\n // First-time events\n { pattern: /\\b(\u7B2C\u4E00\u6B21|\u9996\u6B21|first time|first ever|\u4ECE\u672A|never before)\\b/i, boost: 0.25 },\n // Financial significance\n { pattern: /\\b(\\d+\u4E07|\\d+\u4EBF|\\$[\\d,.]+[MBK]|\u4F30\u503C|valuation|\u6295\u8D44|\u6301\u4ED3)\\b/i, boost: 0.2 },\n // People and relationships (user-configurable entity names)\n { pattern: /\\b(colleague|partner|mentor|friend|manager|teammate)\\b/i, boost: 0.15 },\n // Lessons learned / mistakes\n { pattern: /\\b(\u6559\u8BAD|\u8E29\u5751|pitfall|lesson|mistake|bug|\u6545\u969C|\u6302\u4E86|\u5D29\u4E86)\\b/i, boost: 0.2 },\n // Preferences and identity\n { pattern: /\\b(\u559C\u6B22|\u8BA8\u538C|\u504F\u597D|prefer|hate|love|always|never)\\b/i, boost: 0.15 },\n // Exclamation / emphasis (emotional weight)\n { pattern: /[!\uFF01]{2,}|\u203C\uFE0F|\u26A0\uFE0F|\uD83D\uDD34|\uD83D\uDC80/, boost: 0.1 },\n];\n\n/** Low-salience patterns (routine, technical noise) */\nconst SALIENCE_DAMPENERS: Array<{ pattern: RegExp; dampen: number }> = [\n { pattern: /\\b(heartbeat|HEARTBEAT_OK)\\b/i, dampen: 0.2 },\n { pattern: /\\b(cron|restart|gateway|status)\\b/i, dampen: 0.1 },\n { pattern: /\\b(debug|stack trace|npm|node_modules|\\.tsx?|\\.jsx?)\\b/i, dampen: 0.1 },\n { pattern: /^\\[?(Updated|Added|Removed|Fixed|Set)\\]?\\s.{0,30}$/i, dampen: 0.15 }, // short auto-generated entries only\n];\n\n/**\n * Compute emotional salience from text + category.\n * Returns 0-1. Higher = more emotionally charged / personally significant.\n * Pure heuristic, no LLM call.\n */\nexport function computeEmotionalSalience(\n text: string,\n category?: string,\n importance?: number,\n): number {\n let score = 0.35; // baseline \u2014 neutral memory\n\n // Category boost\n if (category === \"decision\") score += 0.15;\n if (category === \"preference\") score += 0.1;\n if (category === \"reflection\") score += 0.1;\n\n // Importance as a weak signal\n if (typeof importance === \"number\" && importance > 0.8) score += 0.1;\n if (typeof importance === \"number\" && importance > 0.9) score += 0.05;\n\n // Pattern matching\n for (const { pattern, boost } of SALIENCE_BOOSTERS) {\n if (pattern.test(text)) score += boost;\n }\n for (const { pattern, dampen } of SALIENCE_DAMPENERS) {\n if (pattern.test(text)) score -= dampen;\n }\n\n return Math.min(1, Math.max(0, score));\n}\n\n// ============================================================================\n// Emotion Calibration \u2014 rule-based post-processing for LLM valence\n// ============================================================================\n\n/** Strong emotion signal words (positive or negative) */\nconst STRONG_EMOTION_PATTERNS = [\n /\u592A\u597D\u4E86|\u592A\u68D2\u4E86|amazing|incredible|wonderful|fantastic|excellent/i,\n /terrible|horrible|awful|disgusting|devastating/i,\n /fuck|shit|damn|\u9760|\u5367\u69FD|\u6211\u53BB|\u5988\u7684/i,\n /\u54C8\u54C8\u54C8|lol|lmao|rofl|\uD83D\uDE02|\uD83E\uDD23/i,\n /[!\uFF01]{3,}/,\n /heartbroken|ecstatic|furious|thrilled|terrified/i,\n /\u5D29\u6E83|\u66B4\u6012|\u72C2\u559C|\u7EDD\u671B|\u9707\u60CA|\u5174\u594B\u6B7B\u4E86/i,\n];\n\n/** Factual / data-heavy text indicators */\nconst FACTUAL_PATTERNS = [\n /\u4F30\u503C|revenue|valuation|profit|loss|margin/i,\n /[$\uFFE5\u20AC\u00A3]/,\n /%/,\n];\n\n/**\n * Calibrate LLM-returned emotion valence with rule-based post-processing.\n *\n * Fixes two common LLM failure modes:\n * 1. Strong emotional text scored as neutral (0.4-0.6) \u2192 push toward extremes\n * 2. Pure factual/data text scored as emotional \u2192 compress toward neutral\n *\n * @param text - The memory text\n * @param rawValence - LLM-returned valence (0-1, 0.5 = neutral)\n * @returns Calibrated valence (0-1)\n */\nexport function calibrateEmotion(text: string, rawValence: number): number {\n if (!Number.isFinite(rawValence)) return 0.5;\n\n // Check for strong emotion signals\n const hasStrongEmotion = STRONG_EMOTION_PATTERNS.some(p => p.test(text));\n\n // Check if text is factual/data-heavy\n const digitChars = (text.match(/\\d/g) || []).length;\n const digitRatio = text.length > 0 ? digitChars / text.length : 0;\n const hasFactualSignals = digitRatio > 0.3 || FACTUAL_PATTERNS.some(p => p.test(text));\n\n let calibrated = rawValence;\n\n // Fix 1: Strong emotion + neutral valence \u2192 push to 0.3 or 0.7\n if (hasStrongEmotion && rawValence >= 0.4 && rawValence <= 0.6) {\n // Determine direction: below 0.5 \u2192 negative, above \u2192 positive\n calibrated = rawValence <= 0.5 ? 0.3 : 0.7;\n }\n\n // Fix 2: Factual text \u2192 compress to 0.45-0.55\n if (hasFactualSignals && !hasStrongEmotion) {\n if (calibrated < 0.45) calibrated = 0.45;\n if (calibrated > 0.55) calibrated = 0.55;\n }\n\n return Math.min(1, Math.max(0, calibrated));\n}\n\nfunction normalizeTier(value: unknown): MemoryTier {\n switch (value) {\n case \"core\":\n case \"working\":\n case \"peripheral\":\n return value;\n default:\n return \"working\";\n }\n}\n\nexport function reverseMapLegacyCategory(\n oldCategory: LegacyStoreCategory | undefined,\n text = \"\",\n): MemoryCategory {\n switch (oldCategory) {\n case \"preference\":\n return \"preferences\";\n case \"entity\":\n return \"entities\";\n case \"decision\":\n return \"events\";\n case \"other\":\n return \"patterns\";\n case \"fact\":\n if (\n /\\b(my |i am |i'm |name is |\u53EB\u6211|\u6211\u7684|\u6211\u662F)\\b/i.test(text) &&\n text.length < 200\n ) {\n return \"profile\";\n }\n return \"cases\";\n default:\n return \"patterns\";\n }\n}\n\nfunction defaultOverview(text: string): string {\n return `- ${text}`;\n}\n\nfunction normalizeText(value: unknown, fallback: string): string {\n return typeof value === \"string\" && value.trim() ? value.trim() : fallback;\n}\n\nexport function parseSmartMetadata(\n rawMetadata: string | undefined,\n entry: EntryLike = {},\n): SmartMemoryMetadata {\n let parsed: Record<string, unknown> = {};\n if (rawMetadata) {\n try {\n const obj = JSON.parse(rawMetadata);\n if (obj && typeof obj === \"object\") {\n parsed = obj as Record<string, unknown>;\n }\n } catch {\n parsed = {};\n }\n }\n\n const text = entry.text ?? \"\";\n const timestamp =\n typeof entry.timestamp === \"number\" && Number.isFinite(entry.timestamp)\n ? entry.timestamp\n : Date.now();\n\n const memoryCategory = reverseMapLegacyCategory(entry.category, text);\n const l0 = normalizeText(parsed.l0_abstract, text);\n const l2 = normalizeText(parsed.l2_content, text);\n const normalized: SmartMemoryMetadata = {\n ...parsed,\n l0_abstract: l0,\n l1_overview: normalizeText(parsed.l1_overview, defaultOverview(l0)),\n l2_content: l2,\n memory_category:\n typeof parsed.memory_category === \"string\"\n ? (parsed.memory_category as MemoryCategory)\n : memoryCategory,\n tier: normalizeTier(parsed.tier),\n access_count: clampCount(parsed.access_count, 0),\n confidence: clamp01(parsed.confidence, 0.7),\n last_accessed_at: clampCount(parsed.last_accessed_at, timestamp),\n source_session:\n typeof parsed.source_session === \"string\" ? parsed.source_session : undefined,\n emotional_salience: clamp01(\n parsed.emotional_salience,\n computeEmotionalSalience(text, entry.category, entry.importance),\n ),\n };\n\n return normalized;\n}\n\nexport function buildSmartMetadata(\n entry: EntryLike,\n patch: Partial<SmartMemoryMetadata> = {},\n): SmartMemoryMetadata {\n const base = parseSmartMetadata(entry.metadata, entry);\n const text = entry.text ?? \"\";\n\n // Calibrate emotional salience: fix LLM mis-scoring of strong emotions / factual text\n const rawSalience = clamp01(\n patch.emotional_salience ?? base.emotional_salience,\n base.emotional_salience,\n );\n const calibratedSalience = calibrateEmotion(text, rawSalience);\n\n return {\n ...base,\n ...patch,\n l0_abstract: normalizeText(patch.l0_abstract, base.l0_abstract),\n l1_overview: normalizeText(patch.l1_overview, base.l1_overview),\n l2_content: normalizeText(patch.l2_content, base.l2_content),\n memory_category:\n typeof patch.memory_category === \"string\"\n ? patch.memory_category\n : base.memory_category,\n tier: normalizeTier(patch.tier ?? base.tier),\n access_count: clampCount(patch.access_count, base.access_count),\n confidence: clamp01(patch.confidence, base.confidence),\n last_accessed_at: clampCount(\n patch.last_accessed_at,\n base.last_accessed_at || entry.timestamp || Date.now(),\n ),\n source_session:\n typeof patch.source_session === \"string\"\n ? patch.source_session\n : base.source_session,\n emotional_salience: calibratedSalience,\n };\n}\n\n// Metadata array size caps \u2014 prevent unbounded JSON growth\nconst MAX_SOURCES = 20;\nconst MAX_HISTORY = 50;\nconst MAX_RELATIONS = 16;\n\nexport function stringifySmartMetadata(\n metadata: SmartMemoryMetadata | Record<string, unknown>,\n): string {\n const capped = { ...metadata } as Record<string, unknown>;\n\n // Cap array fields to prevent metadata bloat\n if (Array.isArray(capped.sources) && capped.sources.length > MAX_SOURCES) {\n capped.sources = capped.sources.slice(-MAX_SOURCES); // keep most recent\n }\n if (Array.isArray(capped.history) && capped.history.length > MAX_HISTORY) {\n capped.history = capped.history.slice(-MAX_HISTORY);\n }\n if (Array.isArray(capped.relations) && capped.relations.length > MAX_RELATIONS) {\n capped.relations = capped.relations.slice(0, MAX_RELATIONS);\n }\n\n return JSON.stringify(capped);\n}\n\nexport function toLifecycleMemory(\n id: string,\n entry: EntryLike,\n): LifecycleMemory {\n const metadata = parseSmartMetadata(entry.metadata, entry);\n const createdAt =\n typeof entry.timestamp === \"number\" && Number.isFinite(entry.timestamp)\n ? entry.timestamp\n : Date.now();\n\n return {\n id,\n importance:\n typeof entry.importance === \"number\" && Number.isFinite(entry.importance)\n ? entry.importance\n : 0.7,\n confidence: metadata.confidence,\n tier: metadata.tier,\n accessCount: metadata.access_count,\n createdAt,\n lastAccessedAt: metadata.last_accessed_at || createdAt,\n emotionalSalience: metadata.emotional_salience,\n };\n}\n\n/**\n * Parse a memory entry into both a DecayableMemory (for the decay engine)\n * and the raw SmartMemoryMetadata (for in-place mutation before write-back).\n */\nexport function getDecayableFromEntry(\n entry: EntryLike & { id?: string },\n): { memory: DecayableMemory; meta: SmartMemoryMetadata } {\n const meta = parseSmartMetadata(entry.metadata, entry);\n const createdAt =\n typeof entry.timestamp === \"number\" && Number.isFinite(entry.timestamp)\n ? entry.timestamp\n : Date.now();\n\n const memory: DecayableMemory = {\n id: (entry as { id?: string }).id ?? \"\",\n importance:\n typeof entry.importance === \"number\" && Number.isFinite(entry.importance)\n ? entry.importance\n : 0.7,\n confidence: meta.confidence,\n tier: meta.tier,\n accessCount: meta.access_count,\n createdAt,\n lastAccessedAt: meta.last_accessed_at || createdAt,\n emotionalSalience: meta.emotional_salience,\n };\n\n return { memory, meta };\n}\n\n// ============================================================================\n// Contextual Support \u2014 optional extension to SmartMemoryMetadata\n// ============================================================================\n\n/** Predefined context vocabulary for support slices */\nexport const SUPPORT_CONTEXT_VOCABULARY = [\n \"general\", \"morning\", \"afternoon\", \"evening\", \"night\",\n \"weekday\", \"weekend\", \"work\", \"leisure\",\n \"summer\", \"winter\", \"travel\",\n] as const;\n\nexport type SupportContext = (typeof SUPPORT_CONTEXT_VOCABULARY)[number] | string;\n\n/** Max number of context slices per memory to prevent metadata bloat */\nexport const MAX_SUPPORT_SLICES = 8;\n\n/** A single context-specific support slice */\nexport interface ContextualSupport {\n context: SupportContext;\n confirmations: number;\n contradictions: number;\n strength: number; // confirmations / (confirmations + contradictions)\n last_observed_at: number;\n}\n\n/** V2 support info with per-context slices */\nexport interface SupportInfoV2 {\n global_strength: number; // weighted average across all slices\n total_observations: number; // sum of all confirmations + contradictions\n slices: ContextualSupport[];\n}\n\n/**\n * Normalize a raw context label to a canonical context.\n * Maps common variants and falls back to \"general\".\n */\nexport function normalizeContext(raw: string | undefined): SupportContext {\n if (!raw || !raw.trim()) return \"general\";\n const lower = raw.trim().toLowerCase();\n\n // Direct vocabulary match\n if ((SUPPORT_CONTEXT_VOCABULARY as readonly string[]).includes(lower)) {\n return lower as SupportContext;\n }\n\n // Common Chinese/English mappings\n const aliases: Record<string, SupportContext> = {\n \"\u65E9\u4E0A\": \"morning\", \"\u4E0A\u5348\": \"morning\", \"\u65E9\u6668\": \"morning\",\n \"\u4E0B\u5348\": \"afternoon\", \"\u508D\u665A\": \"evening\", \"\u665A\u4E0A\": \"evening\",\n \"\u6DF1\u591C\": \"night\", \"\u591C\u665A\": \"night\", \"\u51CC\u6668\": \"night\",\n \"\u5DE5\u4F5C\u65E5\": \"weekday\", \"\u5E73\u65F6\": \"weekday\",\n \"\u5468\u672B\": \"weekend\", \"\u5047\u65E5\": \"weekend\", \"\u4F11\u606F\u65E5\": \"weekend\",\n \"\u5DE5\u4F5C\": \"work\", \"\u4E0A\u73ED\": \"work\", \"\u529E\u516C\": \"work\",\n \"\u4F11\u95F2\": \"leisure\", \"\u653E\u677E\": \"leisure\", \"\u4F11\u606F\": \"leisure\",\n \"\u590F\u5929\": \"summer\", \"\u590F\u5B63\": \"summer\",\n \"\u51AC\u5929\": \"winter\", \"\u51AC\u5B63\": \"winter\",\n \"\u65C5\u884C\": \"travel\", \"\u51FA\u5DEE\": \"travel\", \"\u65C5\u6E38\": \"travel\",\n };\n\n return aliases[lower] || lower; // keep as custom context if not mapped\n}\n\n/**\n * Parse support_info from metadata JSON. Handles V1 (flat) \u2192 V2 (sliced) migration.\n */\nexport function parseSupportInfo(raw: unknown): SupportInfoV2 {\n const defaultV2: SupportInfoV2 = {\n global_strength: 0.5,\n total_observations: 0,\n slices: [],\n };\n\n if (!raw || typeof raw !== \"object\") return defaultV2;\n const obj = raw as Record<string, unknown>;\n\n // V2 format: has slices array\n if (Array.isArray(obj.slices)) {\n return {\n global_strength: typeof obj.global_strength === \"number\" ? obj.global_strength : 0.5,\n total_observations: typeof obj.total_observations === \"number\" ? obj.total_observations : 0,\n slices: (obj.slices as Record<string, unknown>[]).filter(\n s => s && typeof s.context === \"string\",\n ).map(s => ({\n context: String(s.context),\n confirmations: typeof s.confirmations === \"number\" && s.confirmations >= 0 ? s.confirmations : 0,\n contradictions: typeof s.contradictions === \"number\" && s.contradictions >= 0 ? s.contradictions : 0,\n strength: typeof s.strength === \"number\" && s.strength >= 0 && s.strength <= 1 ? s.strength : 0.5,\n last_observed_at: typeof s.last_observed_at === \"number\" ? s.last_observed_at : Date.now(),\n })),\n };\n }\n\n // V1 format: flat { confirmations, contradictions, strength }\n const conf = typeof obj.confirmations === \"number\" ? obj.confirmations : 0;\n const contra = typeof obj.contradictions === \"number\" ? obj.contradictions : 0;\n const total = conf + contra;\n if (total === 0) return defaultV2;\n\n return {\n global_strength: total > 0 ? conf / total : 0.5,\n total_observations: total,\n slices: [{\n context: \"general\",\n confirmations: conf,\n contradictions: contra,\n strength: total > 0 ? conf / total : 0.5,\n last_observed_at: Date.now(),\n }],\n };\n}\n\n/**\n * Update support stats for a specific context.\n * Returns a new SupportInfoV2 with the updated slice.\n */\nexport function updateSupportStats(\n existing: SupportInfoV2,\n contextLabel: string | undefined,\n event: \"support\" | \"contradict\",\n): SupportInfoV2 {\n const ctx = normalizeContext(contextLabel);\n const base = { ...existing, slices: [...existing.slices.map(s => ({ ...s }))] };\n\n // Find or create the context slice\n let slice = base.slices.find(s => s.context === ctx);\n if (!slice) {\n slice = { context: ctx, confirmations: 0, contradictions: 0, strength: 0.5, last_observed_at: Date.now() };\n base.slices.push(slice);\n }\n\n // Update slice\n if (event === \"support\") slice.confirmations++;\n else slice.contradictions++;\n const sliceTotal = slice.confirmations + slice.contradictions;\n slice.strength = sliceTotal > 0 ? slice.confirmations / sliceTotal : 0.5;\n slice.last_observed_at = Date.now();\n\n // Cap slices (keep most recently observed, but preserve dropped evidence).\n // NOTE: Evidence from slices dropped in *previous* updates is already baked\n // into total_observations/global_strength, so those values may drift slightly\n // over many truncation cycles. This is an accepted trade-off for bounded JSON size.\n let slices = base.slices;\n let droppedConf = 0, droppedContra = 0;\n if (slices.length > MAX_SUPPORT_SLICES) {\n slices = slices\n .sort((a, b) => b.last_observed_at - a.last_observed_at);\n const dropped = slices.slice(MAX_SUPPORT_SLICES);\n for (const d of dropped) {\n droppedConf += d.confirmations;\n droppedContra += d.contradictions;\n }\n slices = slices.slice(0, MAX_SUPPORT_SLICES);\n }\n\n // Recompute global strength including evidence from dropped slices\n let totalConf = droppedConf, totalContra = droppedContra;\n for (const s of slices) {\n totalConf += s.confirmations;\n totalContra += s.contradictions;\n }\n const totalObs = totalConf + totalContra;\n const global_strength = totalObs > 0 ? totalConf / totalObs : 0.5;\n\n return { global_strength, total_observations: totalObs, slices };\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,102 @@
1
+ /**
2
+ * StorageAdapter — Abstract interface for vector storage backends.
3
+ *
4
+ * Mnemo ships with LanceDB as the default adapter.
5
+ * Implement this interface to add support for other backends
6
+ * (Qdrant, Chroma, Milvus, Pinecone, PGVector, etc.)
7
+ */
8
+ export interface MemoryRecord {
9
+ id: string;
10
+ text: string;
11
+ vector: number[];
12
+ timestamp: number;
13
+ scope: string;
14
+ importance: number;
15
+ category: string;
16
+ metadata: string;
17
+ [key: string]: unknown;
18
+ }
19
+ export interface SearchResult {
20
+ record: MemoryRecord;
21
+ score: number;
22
+ }
23
+ export interface QueryOptions {
24
+ where?: string;
25
+ select?: string[];
26
+ limit?: number;
27
+ offset?: number;
28
+ }
29
+ export interface StorageAdapter {
30
+ /** Adapter name for logging and diagnostics */
31
+ readonly name: string;
32
+ /**
33
+ * Connect to the storage backend.
34
+ * @param dbPath - path or connection string
35
+ */
36
+ connect(dbPath: string): Promise<void>;
37
+ /**
38
+ * Ensure the memories table exists with proper schema.
39
+ * Creates the table if it doesn't exist, opens it if it does.
40
+ * @param vectorDimensions - embedding vector dimensions (e.g. 1024)
41
+ */
42
+ ensureTable(vectorDimensions: number): Promise<void>;
43
+ /**
44
+ * Insert one or more records.
45
+ */
46
+ add(records: MemoryRecord[]): Promise<void>;
47
+ /**
48
+ * Update a record by ID. Typically delete + re-insert.
49
+ */
50
+ update(id: string, record: MemoryRecord): Promise<void>;
51
+ /**
52
+ * Delete records matching a filter expression.
53
+ * @param filter - SQL-like filter string, e.g. "id = 'abc'"
54
+ */
55
+ delete(filter: string): Promise<void>;
56
+ /**
57
+ * Vector similarity search.
58
+ * @returns results sorted by descending similarity score (0-1)
59
+ */
60
+ vectorSearch(vector: number[], limit: number, minScore?: number, scopeFilter?: string[]): Promise<SearchResult[]>;
61
+ /**
62
+ * Full-text (BM25) search.
63
+ * @returns results sorted by descending relevance score
64
+ */
65
+ fullTextSearch(query: string, limit: number, scopeFilter?: string[]): Promise<SearchResult[]>;
66
+ /**
67
+ * General-purpose query with optional filter, select, limit.
68
+ */
69
+ query(options: QueryOptions): Promise<MemoryRecord[]>;
70
+ /**
71
+ * Count records matching an optional filter.
72
+ */
73
+ count(filter?: string): Promise<number>;
74
+ /**
75
+ * Ensure full-text search index exists on the text field.
76
+ */
77
+ ensureFullTextIndex(): Promise<void>;
78
+ /**
79
+ * Check if full-text search is supported and initialized.
80
+ */
81
+ hasFullTextSearch(): boolean;
82
+ /**
83
+ * Close the connection / cleanup resources.
84
+ */
85
+ close(): Promise<void>;
86
+ }
87
+ export type AdapterFactory = (config?: Record<string, unknown>) => StorageAdapter;
88
+ /**
89
+ * Register a storage adapter backend.
90
+ * @example registerAdapter("qdrant", (config) => new QdrantAdapter(config))
91
+ */
92
+ export declare function registerAdapter(name: string, factory: AdapterFactory): void;
93
+ /**
94
+ * Create a storage adapter by name.
95
+ * Falls back to LanceDB if name is not registered.
96
+ */
97
+ export declare function createAdapter(name: string, config?: Record<string, unknown>): StorageAdapter;
98
+ /**
99
+ * List all registered adapter names.
100
+ */
101
+ export declare function listAdapters(): string[];
102
+ //# sourceMappingURL=storage-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage-adapter.d.ts","sourceRoot":"","sources":["../../src/storage-adapter.ts"],"names":[],"mappings":"AACA;;;;;;GAMG;AAIH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAID,MAAM,WAAW,cAAc;IAC7B,+CAA+C;IAC/C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvC;;;;OAIG;IACH,WAAW,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAErD;;OAEG;IACH,GAAG,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5C;;OAEG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExD;;;OAGG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtC;;;OAGG;IACH,YAAY,CACV,MAAM,EAAE,MAAM,EAAE,EAChB,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,EACjB,WAAW,CAAC,EAAE,MAAM,EAAE,GACrB,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAE3B;;;OAGG;IACH,cAAc,CACZ,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,WAAW,CAAC,EAAE,MAAM,EAAE,GACrB,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAE3B;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAEtD;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAExC;;OAEG;IACH,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAErC;;OAEG;IACH,iBAAiB,IAAI,OAAO,CAAC;IAE7B;;OAEG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAID,MAAM,MAAM,cAAc,GAAG,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,cAAc,CAAC;AAIlF;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI,CAE3E;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,cAAc,CAU5F;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,EAAE,CAEvC"}
@@ -0,0 +1,22 @@
1
+ const _registry = /* @__PURE__ */ new Map();
2
+ function registerAdapter(name, factory) {
3
+ _registry.set(name, factory);
4
+ }
5
+ function createAdapter(name, config) {
6
+ const factory = _registry.get(name);
7
+ if (!factory) {
8
+ throw new Error(
9
+ `Storage adapter "${name}" not found. Available: ${[..._registry.keys()].join(", ") || "(none)"}. Did you forget to call registerAdapter()?`
10
+ );
11
+ }
12
+ return factory(config);
13
+ }
14
+ function listAdapters() {
15
+ return [..._registry.keys()];
16
+ }
17
+ export {
18
+ createAdapter,
19
+ listAdapters,
20
+ registerAdapter
21
+ };
22
+ //# sourceMappingURL=storage-adapter.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/storage-adapter.ts"],
4
+ "sourcesContent": ["// SPDX-License-Identifier: MIT\n/**\n * StorageAdapter \u2014 Abstract interface for vector storage backends.\n *\n * Mnemo ships with LanceDB as the default adapter.\n * Implement this interface to add support for other backends\n * (Qdrant, Chroma, Milvus, Pinecone, PGVector, etc.)\n */\n\n// \u2500\u2500 Types \u2500\u2500\n\nexport interface MemoryRecord {\n id: string;\n text: string;\n vector: number[];\n timestamp: number;\n scope: string;\n importance: number;\n category: string;\n metadata: string;\n [key: string]: unknown;\n}\n\nexport interface SearchResult {\n record: MemoryRecord;\n score: number;\n}\n\nexport interface QueryOptions {\n where?: string;\n select?: string[];\n limit?: number;\n offset?: number;\n}\n\n// \u2500\u2500 Interface \u2500\u2500\n\nexport interface StorageAdapter {\n /** Adapter name for logging and diagnostics */\n readonly name: string;\n\n /**\n * Connect to the storage backend.\n * @param dbPath - path or connection string\n */\n connect(dbPath: string): Promise<void>;\n\n /**\n * Ensure the memories table exists with proper schema.\n * Creates the table if it doesn't exist, opens it if it does.\n * @param vectorDimensions - embedding vector dimensions (e.g. 1024)\n */\n ensureTable(vectorDimensions: number): Promise<void>;\n\n /**\n * Insert one or more records.\n */\n add(records: MemoryRecord[]): Promise<void>;\n\n /**\n * Update a record by ID. Typically delete + re-insert.\n */\n update(id: string, record: MemoryRecord): Promise<void>;\n\n /**\n * Delete records matching a filter expression.\n * @param filter - SQL-like filter string, e.g. \"id = 'abc'\"\n */\n delete(filter: string): Promise<void>;\n\n /**\n * Vector similarity search.\n * @returns results sorted by descending similarity score (0-1)\n */\n vectorSearch(\n vector: number[],\n limit: number,\n minScore?: number,\n scopeFilter?: string[],\n ): Promise<SearchResult[]>;\n\n /**\n * Full-text (BM25) search.\n * @returns results sorted by descending relevance score\n */\n fullTextSearch(\n query: string,\n limit: number,\n scopeFilter?: string[],\n ): Promise<SearchResult[]>;\n\n /**\n * General-purpose query with optional filter, select, limit.\n */\n query(options: QueryOptions): Promise<MemoryRecord[]>;\n\n /**\n * Count records matching an optional filter.\n */\n count(filter?: string): Promise<number>;\n\n /**\n * Ensure full-text search index exists on the text field.\n */\n ensureFullTextIndex(): Promise<void>;\n\n /**\n * Check if full-text search is supported and initialized.\n */\n hasFullTextSearch(): boolean;\n\n /**\n * Close the connection / cleanup resources.\n */\n close(): Promise<void>;\n}\n\n// \u2500\u2500 Factory \u2500\u2500\n\nexport type AdapterFactory = (config?: Record<string, unknown>) => StorageAdapter;\n\nconst _registry = new Map<string, AdapterFactory>();\n\n/**\n * Register a storage adapter backend.\n * @example registerAdapter(\"qdrant\", (config) => new QdrantAdapter(config))\n */\nexport function registerAdapter(name: string, factory: AdapterFactory): void {\n _registry.set(name, factory);\n}\n\n/**\n * Create a storage adapter by name.\n * Falls back to LanceDB if name is not registered.\n */\nexport function createAdapter(name: string, config?: Record<string, unknown>): StorageAdapter {\n const factory = _registry.get(name);\n if (!factory) {\n throw new Error(\n `Storage adapter \"${name}\" not found. ` +\n `Available: ${[..._registry.keys()].join(\", \") || \"(none)\"}. ` +\n `Did you forget to call registerAdapter()?`\n );\n }\n return factory(config);\n}\n\n/**\n * List all registered adapter names.\n */\nexport function listAdapters(): string[] {\n return [..._registry.keys()];\n}\n"],
5
+ "mappings": "AAyHA,MAAM,YAAY,oBAAI,IAA4B;AAM3C,SAAS,gBAAgB,MAAc,SAA+B;AAC3E,YAAU,IAAI,MAAM,OAAO;AAC7B;AAMO,SAAS,cAAc,MAAc,QAAkD;AAC5F,QAAM,UAAU,UAAU,IAAI,IAAI;AAClC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR,oBAAoB,IAAI,2BACV,CAAC,GAAG,UAAU,KAAK,CAAC,EAAE,KAAK,IAAI,KAAK,QAAQ;AAAA,IAE5D;AAAA,EACF;AACA,SAAO,QAAQ,MAAM;AACvB;AAKO,SAAS,eAAyB;AACvC,SAAO,CAAC,GAAG,UAAU,KAAK,CAAC;AAC7B;",
6
+ "names": []
7
+ }
@@ -0,0 +1,108 @@
1
+ /**
2
+ * LanceDB Storage Layer with Multi-Scope Support
3
+ */
4
+ import type { SemanticGate } from "./semantic-gate.js";
5
+ export interface MemoryEntry {
6
+ id: string;
7
+ text: string;
8
+ vector: number[];
9
+ category: "preference" | "fact" | "decision" | "entity" | "other" | "reflection";
10
+ scope: string;
11
+ importance: number;
12
+ timestamp: number;
13
+ metadata?: string;
14
+ }
15
+ export interface MemorySearchResult {
16
+ entry: MemoryEntry;
17
+ score: number;
18
+ }
19
+ export interface StoreConfig {
20
+ dbPath: string;
21
+ vectorDim: number;
22
+ /** Enable near-duplicate detection before writing (default: true) */
23
+ deduplication?: boolean;
24
+ /** Enable semantic noise gate to filter fragments (default: true) */
25
+ semanticGate?: boolean;
26
+ /** Storage backend: "lancedb" (default), "qdrant", "chroma", "pgvector" */
27
+ storageBackend?: string;
28
+ /** Backend-specific config (url, connectionString, etc.) */
29
+ storageConfig?: Record<string, unknown>;
30
+ }
31
+ export interface MetadataPatch {
32
+ [key: string]: unknown;
33
+ }
34
+ import type { StorageAdapter } from "./storage-adapter.js";
35
+ export declare const loadLanceDB: () => Promise<typeof import("@lancedb/lancedb")>;
36
+ /**
37
+ * Validate and prepare the storage directory before LanceDB connection.
38
+ * Resolves symlinks, creates missing directories, and checks write permissions.
39
+ * Returns the resolved absolute path on success, or throws a descriptive error.
40
+ */
41
+ export declare function validateStoragePath(dbPath: string): string;
42
+ export declare class MemoryStore {
43
+ private readonly config;
44
+ private db;
45
+ private table;
46
+ private initPromise;
47
+ private ftsIndexCreated;
48
+ private updateQueue;
49
+ private semanticGateInstance;
50
+ /** When using a non-LanceDB adapter, this holds the active adapter instance */
51
+ private _adapter;
52
+ /** True when using the adapter path (non-LanceDB backends) */
53
+ get usingAdapter(): boolean;
54
+ constructor(config: StoreConfig);
55
+ /** Inject a SemanticGate instance (created externally with an Embedder). */
56
+ setSemanticGate(gate: SemanticGate): void;
57
+ get dbPath(): string;
58
+ /** Get the active adapter (null if using legacy LanceDB path) */
59
+ get adapter(): StorageAdapter | null;
60
+ /** Whether BM25 full-text search is available */
61
+ get hasFtsSupport(): boolean;
62
+ private ensureInitialized;
63
+ private doInitialize;
64
+ private createFtsIndex;
65
+ store(entry: Omit<MemoryEntry, "id" | "timestamp">): Promise<MemoryEntry>;
66
+ /**
67
+ * Import a pre-built entry while preserving its id/timestamp.
68
+ * Used for re-embedding / migration / A/B testing across embedding models.
69
+ * Intentionally separate from `store()` to keep normal writes simple.
70
+ */
71
+ importEntry(entry: MemoryEntry): Promise<MemoryEntry>;
72
+ hasId(id: string): Promise<boolean>;
73
+ getById(id: string, scopeFilter?: string[]): Promise<MemoryEntry | null>;
74
+ vectorSearch(vector: number[], limit?: number, minScore?: number, scopeFilter?: string[]): Promise<MemorySearchResult[]>;
75
+ bm25Search(query: string, limit?: number, scopeFilter?: string[]): Promise<MemorySearchResult[]>;
76
+ private lexicalFallbackSearch;
77
+ delete(id: string, scopeFilter?: string[]): Promise<boolean>;
78
+ list(scopeFilter?: string[], category?: string, limit?: number, offset?: number): Promise<MemoryEntry[]>;
79
+ stats(scopeFilter?: string[]): Promise<{
80
+ totalCount: number;
81
+ scopeCounts: Record<string, number>;
82
+ categoryCounts: Record<string, number>;
83
+ }>;
84
+ update(id: string, updates: {
85
+ text?: string;
86
+ vector?: number[];
87
+ importance?: number;
88
+ category?: MemoryEntry["category"];
89
+ metadata?: string;
90
+ }, scopeFilter?: string[]): Promise<MemoryEntry | null>;
91
+ private runSerializedUpdate;
92
+ patchMetadata(id: string, patch: MetadataPatch, scopeFilter?: string[]): Promise<MemoryEntry | null>;
93
+ bulkDelete(scopeFilter: string[], beforeTimestamp?: number): Promise<number>;
94
+ /** Last FTS error for diagnostics */
95
+ private _lastFtsError;
96
+ get lastFtsError(): string | null;
97
+ /** Get FTS index health status */
98
+ getFtsStatus(): {
99
+ available: boolean;
100
+ lastError: string | null;
101
+ };
102
+ /** Rebuild FTS index (drops and recreates). Useful for recovery after corruption. */
103
+ rebuildFtsIndex(): Promise<{
104
+ success: boolean;
105
+ error?: string;
106
+ }>;
107
+ }
108
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/store.ts"],"names":[],"mappings":"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"}