superlocalmemory 2.8.5 → 3.0.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 (434) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE +9 -1
  3. package/NOTICE +63 -0
  4. package/README.md +165 -480
  5. package/bin/slm +17 -449
  6. package/bin/slm-npm +2 -2
  7. package/bin/slm.bat +4 -2
  8. package/conftest.py +5 -0
  9. package/docs/api-reference.md +284 -0
  10. package/docs/architecture.md +149 -0
  11. package/docs/auto-memory.md +150 -0
  12. package/docs/cli-reference.md +276 -0
  13. package/docs/compliance.md +191 -0
  14. package/docs/configuration.md +182 -0
  15. package/docs/getting-started.md +102 -0
  16. package/docs/ide-setup.md +261 -0
  17. package/docs/mcp-tools.md +220 -0
  18. package/docs/migration-from-v2.md +170 -0
  19. package/docs/profiles.md +173 -0
  20. package/docs/troubleshooting.md +310 -0
  21. package/{configs → ide/configs}/antigravity-mcp.json +3 -3
  22. package/ide/configs/chatgpt-desktop-mcp.json +16 -0
  23. package/{configs → ide/configs}/claude-desktop-mcp.json +3 -3
  24. package/{configs → ide/configs}/codex-mcp.toml +4 -4
  25. package/{configs → ide/configs}/continue-mcp.yaml +4 -3
  26. package/{configs → ide/configs}/continue-skills.yaml +6 -6
  27. package/ide/configs/cursor-mcp.json +15 -0
  28. package/{configs → ide/configs}/gemini-cli-mcp.json +2 -2
  29. package/{configs → ide/configs}/jetbrains-mcp.json +2 -2
  30. package/{configs → ide/configs}/opencode-mcp.json +2 -2
  31. package/{configs → ide/configs}/perplexity-mcp.json +2 -2
  32. package/{configs → ide/configs}/vscode-copilot-mcp.json +2 -2
  33. package/{configs → ide/configs}/windsurf-mcp.json +3 -3
  34. package/{configs → ide/configs}/zed-mcp.json +2 -2
  35. package/{hooks → ide/hooks}/context-hook.js +9 -20
  36. package/ide/hooks/memory-list-skill.js +70 -0
  37. package/ide/hooks/memory-profile-skill.js +101 -0
  38. package/ide/hooks/memory-recall-skill.js +62 -0
  39. package/ide/hooks/memory-remember-skill.js +68 -0
  40. package/ide/hooks/memory-reset-skill.js +160 -0
  41. package/{hooks → ide/hooks}/post-recall-hook.js +2 -2
  42. package/ide/integrations/langchain/README.md +106 -0
  43. package/ide/integrations/langchain/langchain_superlocalmemory/__init__.py +9 -0
  44. package/ide/integrations/langchain/langchain_superlocalmemory/chat_message_history.py +201 -0
  45. package/ide/integrations/langchain/pyproject.toml +38 -0
  46. package/{src/learning → ide/integrations/langchain}/tests/__init__.py +1 -0
  47. package/ide/integrations/langchain/tests/test_chat_message_history.py +215 -0
  48. package/ide/integrations/langchain/tests/test_security.py +117 -0
  49. package/ide/integrations/llamaindex/README.md +81 -0
  50. package/ide/integrations/llamaindex/llama_index/storage/chat_store/superlocalmemory/__init__.py +9 -0
  51. package/ide/integrations/llamaindex/llama_index/storage/chat_store/superlocalmemory/base.py +316 -0
  52. package/ide/integrations/llamaindex/pyproject.toml +43 -0
  53. package/{src/lifecycle → ide/integrations/llamaindex}/tests/__init__.py +1 -2
  54. package/ide/integrations/llamaindex/tests/test_chat_store.py +294 -0
  55. package/ide/integrations/llamaindex/tests/test_security.py +241 -0
  56. package/{skills → ide/skills}/slm-build-graph/SKILL.md +6 -6
  57. package/{skills → ide/skills}/slm-list-recent/SKILL.md +5 -5
  58. package/{skills → ide/skills}/slm-recall/SKILL.md +5 -5
  59. package/{skills → ide/skills}/slm-remember/SKILL.md +6 -6
  60. package/{skills → ide/skills}/slm-show-patterns/SKILL.md +7 -7
  61. package/{skills → ide/skills}/slm-status/SKILL.md +9 -9
  62. package/{skills → ide/skills}/slm-switch-profile/SKILL.md +9 -9
  63. package/package.json +13 -22
  64. package/pyproject.toml +85 -0
  65. package/scripts/build-dmg.sh +417 -0
  66. package/scripts/install-skills.ps1 +334 -0
  67. package/{install.ps1 → scripts/install.ps1} +36 -4
  68. package/{install.sh → scripts/install.sh} +14 -13
  69. package/scripts/postinstall.js +2 -2
  70. package/scripts/start-dashboard.ps1 +52 -0
  71. package/scripts/start-dashboard.sh +41 -0
  72. package/scripts/sync-wiki.ps1 +127 -0
  73. package/scripts/sync-wiki.sh +82 -0
  74. package/scripts/test-dmg.sh +161 -0
  75. package/scripts/test-npm-package.ps1 +252 -0
  76. package/scripts/test-npm-package.sh +207 -0
  77. package/scripts/verify-install.ps1 +294 -0
  78. package/scripts/verify-install.sh +266 -0
  79. package/src/superlocalmemory/__init__.py +0 -0
  80. package/src/superlocalmemory/attribution/__init__.py +9 -0
  81. package/src/superlocalmemory/attribution/mathematical_dna.py +235 -0
  82. package/src/superlocalmemory/attribution/signer.py +153 -0
  83. package/src/superlocalmemory/attribution/watermark.py +189 -0
  84. package/src/superlocalmemory/cli/__init__.py +5 -0
  85. package/src/superlocalmemory/cli/commands.py +245 -0
  86. package/src/superlocalmemory/cli/main.py +89 -0
  87. package/src/superlocalmemory/cli/migrate_cmd.py +55 -0
  88. package/src/superlocalmemory/cli/post_install.py +99 -0
  89. package/src/superlocalmemory/cli/setup_wizard.py +129 -0
  90. package/src/superlocalmemory/compliance/__init__.py +0 -0
  91. package/src/superlocalmemory/compliance/abac.py +204 -0
  92. package/src/superlocalmemory/compliance/audit.py +314 -0
  93. package/src/superlocalmemory/compliance/eu_ai_act.py +131 -0
  94. package/src/superlocalmemory/compliance/gdpr.py +294 -0
  95. package/src/superlocalmemory/compliance/lifecycle.py +158 -0
  96. package/src/superlocalmemory/compliance/retention.py +232 -0
  97. package/src/superlocalmemory/compliance/scheduler.py +148 -0
  98. package/src/superlocalmemory/core/__init__.py +0 -0
  99. package/src/superlocalmemory/core/config.py +391 -0
  100. package/src/superlocalmemory/core/embeddings.py +293 -0
  101. package/src/superlocalmemory/core/engine.py +701 -0
  102. package/src/superlocalmemory/core/hooks.py +65 -0
  103. package/src/superlocalmemory/core/maintenance.py +172 -0
  104. package/src/superlocalmemory/core/modes.py +140 -0
  105. package/src/superlocalmemory/core/profiles.py +234 -0
  106. package/src/superlocalmemory/core/registry.py +117 -0
  107. package/src/superlocalmemory/dynamics/__init__.py +0 -0
  108. package/src/superlocalmemory/dynamics/fisher_langevin_coupling.py +223 -0
  109. package/src/superlocalmemory/encoding/__init__.py +0 -0
  110. package/src/superlocalmemory/encoding/consolidator.py +485 -0
  111. package/src/superlocalmemory/encoding/emotional.py +125 -0
  112. package/src/superlocalmemory/encoding/entity_resolver.py +525 -0
  113. package/src/superlocalmemory/encoding/entropy_gate.py +104 -0
  114. package/src/superlocalmemory/encoding/fact_extractor.py +775 -0
  115. package/src/superlocalmemory/encoding/foresight.py +91 -0
  116. package/src/superlocalmemory/encoding/graph_builder.py +302 -0
  117. package/src/superlocalmemory/encoding/observation_builder.py +160 -0
  118. package/src/superlocalmemory/encoding/scene_builder.py +183 -0
  119. package/src/superlocalmemory/encoding/signal_inference.py +90 -0
  120. package/src/superlocalmemory/encoding/temporal_parser.py +426 -0
  121. package/src/superlocalmemory/encoding/type_router.py +235 -0
  122. package/src/superlocalmemory/hooks/__init__.py +3 -0
  123. package/src/superlocalmemory/hooks/auto_capture.py +111 -0
  124. package/src/superlocalmemory/hooks/auto_recall.py +93 -0
  125. package/src/superlocalmemory/hooks/ide_connector.py +204 -0
  126. package/src/superlocalmemory/hooks/rules_engine.py +99 -0
  127. package/src/superlocalmemory/infra/__init__.py +3 -0
  128. package/src/superlocalmemory/infra/auth_middleware.py +82 -0
  129. package/src/superlocalmemory/infra/backup.py +317 -0
  130. package/src/superlocalmemory/infra/cache_manager.py +267 -0
  131. package/src/superlocalmemory/infra/event_bus.py +381 -0
  132. package/src/superlocalmemory/infra/rate_limiter.py +135 -0
  133. package/src/{webhook_dispatcher.py → superlocalmemory/infra/webhook_dispatcher.py} +104 -101
  134. package/src/superlocalmemory/learning/__init__.py +0 -0
  135. package/src/superlocalmemory/learning/adaptive.py +172 -0
  136. package/src/superlocalmemory/learning/behavioral.py +490 -0
  137. package/src/superlocalmemory/learning/behavioral_listener.py +94 -0
  138. package/src/superlocalmemory/learning/bootstrap.py +298 -0
  139. package/src/superlocalmemory/learning/cross_project.py +399 -0
  140. package/src/superlocalmemory/learning/database.py +376 -0
  141. package/src/superlocalmemory/learning/engagement.py +323 -0
  142. package/src/superlocalmemory/learning/features.py +138 -0
  143. package/src/superlocalmemory/learning/feedback.py +316 -0
  144. package/src/superlocalmemory/learning/outcomes.py +255 -0
  145. package/src/superlocalmemory/learning/project_context.py +366 -0
  146. package/src/superlocalmemory/learning/ranker.py +155 -0
  147. package/src/superlocalmemory/learning/source_quality.py +303 -0
  148. package/src/superlocalmemory/learning/workflows.py +309 -0
  149. package/src/superlocalmemory/llm/__init__.py +0 -0
  150. package/src/superlocalmemory/llm/backbone.py +316 -0
  151. package/src/superlocalmemory/math/__init__.py +0 -0
  152. package/src/superlocalmemory/math/fisher.py +356 -0
  153. package/src/superlocalmemory/math/langevin.py +398 -0
  154. package/src/superlocalmemory/math/sheaf.py +257 -0
  155. package/src/superlocalmemory/mcp/__init__.py +0 -0
  156. package/src/superlocalmemory/mcp/resources.py +245 -0
  157. package/src/superlocalmemory/mcp/server.py +61 -0
  158. package/src/superlocalmemory/mcp/tools.py +18 -0
  159. package/src/superlocalmemory/mcp/tools_core.py +305 -0
  160. package/src/superlocalmemory/mcp/tools_v28.py +223 -0
  161. package/src/superlocalmemory/mcp/tools_v3.py +286 -0
  162. package/src/superlocalmemory/retrieval/__init__.py +0 -0
  163. package/src/superlocalmemory/retrieval/agentic.py +295 -0
  164. package/src/superlocalmemory/retrieval/ann_index.py +223 -0
  165. package/src/superlocalmemory/retrieval/bm25_channel.py +185 -0
  166. package/src/superlocalmemory/retrieval/bridge_discovery.py +170 -0
  167. package/src/superlocalmemory/retrieval/engine.py +390 -0
  168. package/src/superlocalmemory/retrieval/entity_channel.py +179 -0
  169. package/src/superlocalmemory/retrieval/fusion.py +78 -0
  170. package/src/superlocalmemory/retrieval/profile_channel.py +105 -0
  171. package/src/superlocalmemory/retrieval/reranker.py +154 -0
  172. package/src/superlocalmemory/retrieval/semantic_channel.py +232 -0
  173. package/src/superlocalmemory/retrieval/strategy.py +96 -0
  174. package/src/superlocalmemory/retrieval/temporal_channel.py +175 -0
  175. package/src/superlocalmemory/server/__init__.py +1 -0
  176. package/src/superlocalmemory/server/api.py +248 -0
  177. package/src/superlocalmemory/server/routes/__init__.py +4 -0
  178. package/src/superlocalmemory/server/routes/agents.py +107 -0
  179. package/src/superlocalmemory/server/routes/backup.py +91 -0
  180. package/src/superlocalmemory/server/routes/behavioral.py +127 -0
  181. package/src/superlocalmemory/server/routes/compliance.py +160 -0
  182. package/src/superlocalmemory/server/routes/data_io.py +188 -0
  183. package/src/superlocalmemory/server/routes/events.py +183 -0
  184. package/src/superlocalmemory/server/routes/helpers.py +85 -0
  185. package/src/superlocalmemory/server/routes/learning.py +273 -0
  186. package/src/superlocalmemory/server/routes/lifecycle.py +116 -0
  187. package/src/superlocalmemory/server/routes/memories.py +399 -0
  188. package/src/superlocalmemory/server/routes/profiles.py +219 -0
  189. package/src/superlocalmemory/server/routes/stats.py +346 -0
  190. package/src/superlocalmemory/server/routes/v3_api.py +365 -0
  191. package/src/superlocalmemory/server/routes/ws.py +82 -0
  192. package/src/superlocalmemory/server/security_middleware.py +57 -0
  193. package/src/superlocalmemory/server/ui.py +245 -0
  194. package/src/superlocalmemory/storage/__init__.py +0 -0
  195. package/src/superlocalmemory/storage/access_control.py +182 -0
  196. package/src/superlocalmemory/storage/database.py +594 -0
  197. package/src/superlocalmemory/storage/migrations.py +303 -0
  198. package/src/superlocalmemory/storage/models.py +406 -0
  199. package/src/superlocalmemory/storage/schema.py +726 -0
  200. package/src/superlocalmemory/storage/v2_migrator.py +317 -0
  201. package/src/superlocalmemory/trust/__init__.py +0 -0
  202. package/src/superlocalmemory/trust/gate.py +130 -0
  203. package/src/superlocalmemory/trust/provenance.py +124 -0
  204. package/src/superlocalmemory/trust/scorer.py +347 -0
  205. package/src/superlocalmemory/trust/signals.py +153 -0
  206. package/ui/index.html +278 -5
  207. package/ui/js/auto-settings.js +70 -0
  208. package/ui/js/dashboard.js +90 -0
  209. package/ui/js/fact-detail.js +92 -0
  210. package/ui/js/feedback.js +2 -2
  211. package/ui/js/ide-status.js +102 -0
  212. package/ui/js/math-health.js +98 -0
  213. package/ui/js/recall-lab.js +127 -0
  214. package/ui/js/settings.js +2 -2
  215. package/ui/js/trust-dashboard.js +73 -0
  216. package/api_server.py +0 -724
  217. package/bin/aider-smart +0 -72
  218. package/bin/superlocalmemoryv2-learning +0 -4
  219. package/bin/superlocalmemoryv2-list +0 -3
  220. package/bin/superlocalmemoryv2-patterns +0 -4
  221. package/bin/superlocalmemoryv2-profile +0 -3
  222. package/bin/superlocalmemoryv2-recall +0 -3
  223. package/bin/superlocalmemoryv2-remember +0 -3
  224. package/bin/superlocalmemoryv2-reset +0 -3
  225. package/bin/superlocalmemoryv2-status +0 -3
  226. package/configs/chatgpt-desktop-mcp.json +0 -16
  227. package/configs/cursor-mcp.json +0 -15
  228. package/docs/SECURITY-QUICK-REFERENCE.md +0 -214
  229. package/hooks/memory-list-skill.js +0 -139
  230. package/hooks/memory-profile-skill.js +0 -273
  231. package/hooks/memory-recall-skill.js +0 -114
  232. package/hooks/memory-remember-skill.js +0 -127
  233. package/hooks/memory-reset-skill.js +0 -274
  234. package/mcp_server.py +0 -1800
  235. package/requirements-core.txt +0 -22
  236. package/requirements-learning.txt +0 -12
  237. package/requirements.txt +0 -12
  238. package/src/agent_registry.py +0 -411
  239. package/src/auth_middleware.py +0 -61
  240. package/src/auto_backup.py +0 -459
  241. package/src/behavioral/__init__.py +0 -49
  242. package/src/behavioral/behavioral_listener.py +0 -203
  243. package/src/behavioral/behavioral_patterns.py +0 -275
  244. package/src/behavioral/cross_project_transfer.py +0 -206
  245. package/src/behavioral/outcome_inference.py +0 -194
  246. package/src/behavioral/outcome_tracker.py +0 -193
  247. package/src/behavioral/tests/__init__.py +0 -4
  248. package/src/behavioral/tests/test_behavioral_integration.py +0 -108
  249. package/src/behavioral/tests/test_behavioral_patterns.py +0 -150
  250. package/src/behavioral/tests/test_cross_project_transfer.py +0 -142
  251. package/src/behavioral/tests/test_mcp_behavioral.py +0 -139
  252. package/src/behavioral/tests/test_mcp_report_outcome.py +0 -117
  253. package/src/behavioral/tests/test_outcome_inference.py +0 -107
  254. package/src/behavioral/tests/test_outcome_tracker.py +0 -96
  255. package/src/cache_manager.py +0 -518
  256. package/src/compliance/__init__.py +0 -48
  257. package/src/compliance/abac_engine.py +0 -149
  258. package/src/compliance/abac_middleware.py +0 -116
  259. package/src/compliance/audit_db.py +0 -215
  260. package/src/compliance/audit_logger.py +0 -148
  261. package/src/compliance/retention_manager.py +0 -289
  262. package/src/compliance/retention_scheduler.py +0 -186
  263. package/src/compliance/tests/__init__.py +0 -4
  264. package/src/compliance/tests/test_abac_enforcement.py +0 -95
  265. package/src/compliance/tests/test_abac_engine.py +0 -124
  266. package/src/compliance/tests/test_abac_mcp_integration.py +0 -118
  267. package/src/compliance/tests/test_audit_db.py +0 -123
  268. package/src/compliance/tests/test_audit_logger.py +0 -98
  269. package/src/compliance/tests/test_mcp_audit.py +0 -128
  270. package/src/compliance/tests/test_mcp_retention_policy.py +0 -125
  271. package/src/compliance/tests/test_retention_manager.py +0 -131
  272. package/src/compliance/tests/test_retention_scheduler.py +0 -99
  273. package/src/compression/__init__.py +0 -25
  274. package/src/compression/cli.py +0 -150
  275. package/src/compression/cold_storage.py +0 -217
  276. package/src/compression/config.py +0 -72
  277. package/src/compression/orchestrator.py +0 -133
  278. package/src/compression/tier2_compressor.py +0 -228
  279. package/src/compression/tier3_compressor.py +0 -153
  280. package/src/compression/tier_classifier.py +0 -148
  281. package/src/db_connection_manager.py +0 -536
  282. package/src/embedding_engine.py +0 -63
  283. package/src/embeddings/__init__.py +0 -47
  284. package/src/embeddings/cache.py +0 -70
  285. package/src/embeddings/cli.py +0 -113
  286. package/src/embeddings/constants.py +0 -47
  287. package/src/embeddings/database.py +0 -91
  288. package/src/embeddings/engine.py +0 -247
  289. package/src/embeddings/model_loader.py +0 -145
  290. package/src/event_bus.py +0 -562
  291. package/src/graph/__init__.py +0 -36
  292. package/src/graph/build_helpers.py +0 -74
  293. package/src/graph/cli.py +0 -87
  294. package/src/graph/cluster_builder.py +0 -188
  295. package/src/graph/cluster_summary.py +0 -148
  296. package/src/graph/constants.py +0 -47
  297. package/src/graph/edge_builder.py +0 -162
  298. package/src/graph/entity_extractor.py +0 -95
  299. package/src/graph/graph_core.py +0 -226
  300. package/src/graph/graph_search.py +0 -231
  301. package/src/graph/hierarchical.py +0 -207
  302. package/src/graph/schema.py +0 -99
  303. package/src/graph_engine.py +0 -52
  304. package/src/hnsw_index.py +0 -628
  305. package/src/hybrid_search.py +0 -46
  306. package/src/learning/__init__.py +0 -217
  307. package/src/learning/adaptive_ranker.py +0 -682
  308. package/src/learning/bootstrap/__init__.py +0 -69
  309. package/src/learning/bootstrap/constants.py +0 -93
  310. package/src/learning/bootstrap/db_queries.py +0 -316
  311. package/src/learning/bootstrap/sampling.py +0 -82
  312. package/src/learning/bootstrap/text_utils.py +0 -71
  313. package/src/learning/cross_project_aggregator.py +0 -857
  314. package/src/learning/db/__init__.py +0 -40
  315. package/src/learning/db/constants.py +0 -44
  316. package/src/learning/db/schema.py +0 -279
  317. package/src/learning/engagement_tracker.py +0 -628
  318. package/src/learning/feature_extractor.py +0 -708
  319. package/src/learning/feedback_collector.py +0 -806
  320. package/src/learning/learning_db.py +0 -915
  321. package/src/learning/project_context_manager.py +0 -572
  322. package/src/learning/ranking/__init__.py +0 -33
  323. package/src/learning/ranking/constants.py +0 -84
  324. package/src/learning/ranking/helpers.py +0 -278
  325. package/src/learning/source_quality_scorer.py +0 -676
  326. package/src/learning/synthetic_bootstrap.py +0 -755
  327. package/src/learning/tests/test_adaptive_ranker.py +0 -325
  328. package/src/learning/tests/test_adaptive_ranker_v28.py +0 -60
  329. package/src/learning/tests/test_aggregator.py +0 -306
  330. package/src/learning/tests/test_auto_retrain_v28.py +0 -35
  331. package/src/learning/tests/test_e2e_ranking_v28.py +0 -82
  332. package/src/learning/tests/test_feature_extractor_v28.py +0 -93
  333. package/src/learning/tests/test_feedback_collector.py +0 -294
  334. package/src/learning/tests/test_learning_db.py +0 -602
  335. package/src/learning/tests/test_learning_db_v28.py +0 -110
  336. package/src/learning/tests/test_learning_init_v28.py +0 -48
  337. package/src/learning/tests/test_outcome_signals.py +0 -48
  338. package/src/learning/tests/test_project_context.py +0 -292
  339. package/src/learning/tests/test_schema_migration.py +0 -319
  340. package/src/learning/tests/test_signal_inference.py +0 -397
  341. package/src/learning/tests/test_source_quality.py +0 -351
  342. package/src/learning/tests/test_synthetic_bootstrap.py +0 -429
  343. package/src/learning/tests/test_workflow_miner.py +0 -318
  344. package/src/learning/workflow_pattern_miner.py +0 -655
  345. package/src/lifecycle/__init__.py +0 -54
  346. package/src/lifecycle/bounded_growth.py +0 -239
  347. package/src/lifecycle/compaction_engine.py +0 -226
  348. package/src/lifecycle/lifecycle_engine.py +0 -355
  349. package/src/lifecycle/lifecycle_evaluator.py +0 -257
  350. package/src/lifecycle/lifecycle_scheduler.py +0 -130
  351. package/src/lifecycle/retention_policy.py +0 -285
  352. package/src/lifecycle/tests/test_bounded_growth.py +0 -193
  353. package/src/lifecycle/tests/test_compaction.py +0 -179
  354. package/src/lifecycle/tests/test_lifecycle_engine.py +0 -137
  355. package/src/lifecycle/tests/test_lifecycle_evaluation.py +0 -177
  356. package/src/lifecycle/tests/test_lifecycle_scheduler.py +0 -127
  357. package/src/lifecycle/tests/test_lifecycle_search.py +0 -109
  358. package/src/lifecycle/tests/test_mcp_compact.py +0 -149
  359. package/src/lifecycle/tests/test_mcp_lifecycle_status.py +0 -114
  360. package/src/lifecycle/tests/test_retention_policy.py +0 -162
  361. package/src/mcp_tools_v28.py +0 -281
  362. package/src/memory/__init__.py +0 -36
  363. package/src/memory/cli.py +0 -205
  364. package/src/memory/constants.py +0 -39
  365. package/src/memory/helpers.py +0 -28
  366. package/src/memory/schema.py +0 -166
  367. package/src/memory-profiles.py +0 -595
  368. package/src/memory-reset.py +0 -491
  369. package/src/memory_compression.py +0 -989
  370. package/src/memory_store_v2.py +0 -1155
  371. package/src/migrate_v1_to_v2.py +0 -629
  372. package/src/pattern_learner.py +0 -34
  373. package/src/patterns/__init__.py +0 -24
  374. package/src/patterns/analyzers.py +0 -251
  375. package/src/patterns/learner.py +0 -271
  376. package/src/patterns/scoring.py +0 -171
  377. package/src/patterns/store.py +0 -225
  378. package/src/patterns/terminology.py +0 -140
  379. package/src/provenance_tracker.py +0 -312
  380. package/src/qualixar_attribution.py +0 -139
  381. package/src/qualixar_watermark.py +0 -78
  382. package/src/query_optimizer.py +0 -511
  383. package/src/rate_limiter.py +0 -83
  384. package/src/search/__init__.py +0 -20
  385. package/src/search/cli.py +0 -77
  386. package/src/search/constants.py +0 -26
  387. package/src/search/engine.py +0 -241
  388. package/src/search/fusion.py +0 -122
  389. package/src/search/index_loader.py +0 -114
  390. package/src/search/methods.py +0 -162
  391. package/src/search_engine_v2.py +0 -401
  392. package/src/setup_validator.py +0 -482
  393. package/src/subscription_manager.py +0 -391
  394. package/src/tree/__init__.py +0 -59
  395. package/src/tree/builder.py +0 -185
  396. package/src/tree/nodes.py +0 -202
  397. package/src/tree/queries.py +0 -257
  398. package/src/tree/schema.py +0 -80
  399. package/src/tree_manager.py +0 -19
  400. package/src/trust/__init__.py +0 -45
  401. package/src/trust/constants.py +0 -66
  402. package/src/trust/queries.py +0 -157
  403. package/src/trust/schema.py +0 -95
  404. package/src/trust/scorer.py +0 -299
  405. package/src/trust/signals.py +0 -95
  406. package/src/trust_scorer.py +0 -44
  407. package/ui/app.js +0 -1588
  408. package/ui/js/graph-cytoscape-monolithic-backup.js +0 -1168
  409. package/ui/js/graph-cytoscape.js +0 -1168
  410. package/ui/js/graph-d3-backup.js +0 -32
  411. package/ui/js/graph.js +0 -32
  412. package/ui_server.py +0 -266
  413. /package/docs/{ACCESSIBILITY.md → v2-archive/ACCESSIBILITY.md} +0 -0
  414. /package/docs/{ARCHITECTURE.md → v2-archive/ARCHITECTURE.md} +0 -0
  415. /package/docs/{CLI-COMMANDS-REFERENCE.md → v2-archive/CLI-COMMANDS-REFERENCE.md} +0 -0
  416. /package/docs/{COMPRESSION-README.md → v2-archive/COMPRESSION-README.md} +0 -0
  417. /package/docs/{FRAMEWORK-INTEGRATIONS.md → v2-archive/FRAMEWORK-INTEGRATIONS.md} +0 -0
  418. /package/docs/{MCP-MANUAL-SETUP.md → v2-archive/MCP-MANUAL-SETUP.md} +0 -0
  419. /package/docs/{MCP-TROUBLESHOOTING.md → v2-archive/MCP-TROUBLESHOOTING.md} +0 -0
  420. /package/docs/{PATTERN-LEARNING.md → v2-archive/PATTERN-LEARNING.md} +0 -0
  421. /package/docs/{PROFILES-GUIDE.md → v2-archive/PROFILES-GUIDE.md} +0 -0
  422. /package/docs/{RESET-GUIDE.md → v2-archive/RESET-GUIDE.md} +0 -0
  423. /package/docs/{SEARCH-ENGINE-V2.2.0.md → v2-archive/SEARCH-ENGINE-V2.2.0.md} +0 -0
  424. /package/docs/{SEARCH-INTEGRATION-GUIDE.md → v2-archive/SEARCH-INTEGRATION-GUIDE.md} +0 -0
  425. /package/docs/{UI-SERVER.md → v2-archive/UI-SERVER.md} +0 -0
  426. /package/docs/{UNIVERSAL-INTEGRATION.md → v2-archive/UNIVERSAL-INTEGRATION.md} +0 -0
  427. /package/docs/{V2.2.0-OPTIONAL-SEARCH.md → v2-archive/V2.2.0-OPTIONAL-SEARCH.md} +0 -0
  428. /package/docs/{WINDOWS-INSTALL-README.txt → v2-archive/WINDOWS-INSTALL-README.txt} +0 -0
  429. /package/docs/{WINDOWS-POST-INSTALL.txt → v2-archive/WINDOWS-POST-INSTALL.txt} +0 -0
  430. /package/docs/{example_graph_usage.py → v2-archive/example_graph_usage.py} +0 -0
  431. /package/{completions → ide/completions}/slm.bash +0 -0
  432. /package/{completions → ide/completions}/slm.zsh +0 -0
  433. /package/{configs → ide/configs}/cody-commands.json +0 -0
  434. /package/{install-skills.sh → scripts/install-skills.sh} +0 -0
@@ -0,0 +1,245 @@
1
+ # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
+ # Licensed under the MIT License - see LICENSE file
3
+ # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
+
5
+ """SuperLocalMemory V3 — MCP Resources (6 resources).
6
+
7
+ slm://recent, slm://stats, slm://clusters, slm://identity,
8
+ slm://learning, slm://engagement.
9
+
10
+ Part of Qualixar | Author: Varun Pratap Bhardwaj
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import json
16
+ import logging
17
+ from typing import Callable
18
+
19
+ logger = logging.getLogger(__name__)
20
+
21
+
22
+ def register_resources(server, get_engine: Callable) -> None:
23
+ """Register 6 MCP resources on *server*."""
24
+
25
+ # ------------------------------------------------------------------
26
+ # 1. slm://recent
27
+ # ------------------------------------------------------------------
28
+ @server.resource("slm://recent")
29
+ async def recent_memories() -> str:
30
+ """Recent memories summary.
31
+
32
+ Returns a plain-text summary of the 20 most recent facts
33
+ stored in the active profile.
34
+ """
35
+ try:
36
+ engine = get_engine()
37
+ pid = engine.profile_id
38
+ facts = engine._db.get_all_facts(pid)[:20]
39
+ if not facts:
40
+ return "No memories stored yet."
41
+ lines = [f"Recent memories for profile '{pid}' ({len(facts)} shown):"]
42
+ for f in facts:
43
+ preview = f.content[:100].replace("\n", " ")
44
+ lines.append(
45
+ f" [{f.fact_type.value}] {preview} "
46
+ f"(id={f.fact_id}, {f.created_at[:10]})"
47
+ )
48
+ return "\n".join(lines)
49
+ except Exception as exc:
50
+ return f"Error loading recent memories: {exc}"
51
+
52
+ # ------------------------------------------------------------------
53
+ # 2. slm://stats
54
+ # ------------------------------------------------------------------
55
+ @server.resource("slm://stats")
56
+ async def stats() -> str:
57
+ """Memory system statistics.
58
+
59
+ Returns a text summary of fact counts, entity counts,
60
+ edge counts, and storage breakdown by type.
61
+ """
62
+ try:
63
+ engine = get_engine()
64
+ pid = engine.profile_id
65
+ fact_count = engine._db.get_fact_count(pid)
66
+
67
+ entity_rows = engine._db.execute(
68
+ "SELECT COUNT(*) AS c FROM canonical_entities WHERE profile_id = ?",
69
+ (pid,),
70
+ )
71
+ entity_count = int(dict(entity_rows[0])["c"]) if entity_rows else 0
72
+
73
+ edge_rows = engine._db.execute(
74
+ "SELECT COUNT(*) AS c FROM graph_edges WHERE profile_id = ?",
75
+ (pid,),
76
+ )
77
+ edge_count = int(dict(edge_rows[0])["c"]) if edge_rows else 0
78
+
79
+ scene_rows = engine._db.execute(
80
+ "SELECT COUNT(*) AS c FROM memory_scenes WHERE profile_id = ?",
81
+ (pid,),
82
+ )
83
+ scene_count = int(dict(scene_rows[0])["c"]) if scene_rows else 0
84
+
85
+ lines = [
86
+ f"SuperLocalMemory V3 Statistics (profile: {pid})",
87
+ f" Mode: {engine._config.mode.value.upper()}",
88
+ f" Facts: {fact_count}",
89
+ f" Entities: {entity_count}",
90
+ f" Edges: {edge_count}",
91
+ f" Scenes: {scene_count}",
92
+ ]
93
+ return "\n".join(lines)
94
+ except Exception as exc:
95
+ return f"Error loading stats: {exc}"
96
+
97
+ # ------------------------------------------------------------------
98
+ # 3. slm://clusters
99
+ # ------------------------------------------------------------------
100
+ @server.resource("slm://clusters")
101
+ async def clusters() -> str:
102
+ """Memory scene clusters.
103
+
104
+ Returns a summary of memory scenes (topic clusters)
105
+ with their themes and fact counts.
106
+ """
107
+ try:
108
+ engine = get_engine()
109
+ pid = engine.profile_id
110
+ scenes = engine._db.get_all_scenes(pid)
111
+ if not scenes:
112
+ return "No memory scenes/clusters formed yet."
113
+ lines = [f"Memory Scenes ({len(scenes)} clusters):"]
114
+ for s in scenes[:30]:
115
+ theme = s.theme[:80] if s.theme else "(no theme)"
116
+ lines.append(
117
+ f" [{s.scene_id[:8]}] {theme} "
118
+ f"({len(s.fact_ids)} facts, {len(s.entity_ids)} entities)"
119
+ )
120
+ return "\n".join(lines)
121
+ except Exception as exc:
122
+ return f"Error loading clusters: {exc}"
123
+
124
+ # ------------------------------------------------------------------
125
+ # 4. slm://identity
126
+ # ------------------------------------------------------------------
127
+ @server.resource("slm://identity")
128
+ async def coding_identity() -> str:
129
+ """Active profile identity and coding context.
130
+
131
+ Returns profile name, personality description, mode, and
132
+ top entities with fact counts for context-aware assistance.
133
+ """
134
+ try:
135
+ engine = get_engine()
136
+ pid = engine.profile_id
137
+ mode = engine._config.mode.value.upper()
138
+
139
+ # Top entities by fact count
140
+ entity_rows = engine._db.execute(
141
+ "SELECT canonical_name, fact_count FROM canonical_entities "
142
+ "WHERE profile_id = ? ORDER BY fact_count DESC LIMIT 10",
143
+ (pid,),
144
+ )
145
+ entities = [
146
+ f"{dict(r)['canonical_name']} ({dict(r)['fact_count']} facts)"
147
+ for r in entity_rows
148
+ ]
149
+
150
+ lines = [
151
+ f"Profile: {pid}",
152
+ f"Mode: {mode}",
153
+ f"Top entities: {', '.join(entities) if entities else 'none yet'}",
154
+ ]
155
+ return "\n".join(lines)
156
+ except Exception as exc:
157
+ return f"Error loading identity: {exc}"
158
+
159
+ # ------------------------------------------------------------------
160
+ # 5. slm://learning
161
+ # ------------------------------------------------------------------
162
+ @server.resource("slm://learning")
163
+ async def learning_status() -> str:
164
+ """Learning system status.
165
+
166
+ Returns adaptive learning health, pattern summary, and
167
+ outcome tracking statistics.
168
+ """
169
+ try:
170
+ engine = get_engine()
171
+ pid = engine.profile_id
172
+
173
+ # Behavioral patterns summary
174
+ try:
175
+ from superlocalmemory.learning.behavioral import BehavioralStore
176
+ store = BehavioralStore(engine._db.db_path)
177
+ summary = store.get_summary(pid)
178
+ except Exception:
179
+ summary = {}
180
+
181
+ # Outcome stats
182
+ try:
183
+ outcome_rows = engine._db.execute(
184
+ "SELECT outcome, COUNT(*) AS c FROM action_outcomes "
185
+ "WHERE profile_id = ? GROUP BY outcome",
186
+ (pid,),
187
+ )
188
+ outcomes = {dict(r)["outcome"]: dict(r)["c"] for r in outcome_rows}
189
+ except Exception:
190
+ outcomes = {}
191
+
192
+ lines = [
193
+ f"Learning Status (profile: {pid})",
194
+ f" Behavioral patterns: {json.dumps(summary) if summary else 'none detected'}",
195
+ f" Outcome tracking: {json.dumps(outcomes) if outcomes else 'no outcomes recorded'}",
196
+ ]
197
+ return "\n".join(lines)
198
+ except Exception as exc:
199
+ return f"Error loading learning status: {exc}"
200
+
201
+ # ------------------------------------------------------------------
202
+ # 6. slm://engagement
203
+ # ------------------------------------------------------------------
204
+ @server.resource("slm://engagement")
205
+ async def engagement() -> str:
206
+ """Engagement metrics.
207
+
208
+ Returns memory usage activity: recent stores, recalls,
209
+ and top-accessed facts.
210
+ """
211
+ try:
212
+ engine = get_engine()
213
+ pid = engine.profile_id
214
+
215
+ # Recent activity via audit trail
216
+ try:
217
+ audit_rows = engine._db.execute(
218
+ "SELECT action, COUNT(*) AS c FROM compliance_audit "
219
+ "WHERE profile_id = ? GROUP BY action",
220
+ (pid,),
221
+ )
222
+ activity = {dict(r)["action"]: dict(r)["c"] for r in audit_rows}
223
+ except Exception:
224
+ activity = {}
225
+
226
+ # Top-accessed facts
227
+ top_rows = engine._db.execute(
228
+ "SELECT fact_id, content, access_count FROM atomic_facts "
229
+ "WHERE profile_id = ? AND access_count > 0 "
230
+ "ORDER BY access_count DESC LIMIT 5",
231
+ (pid,),
232
+ )
233
+ top_facts = [
234
+ f"{dict(r)['content'][:60]}... (accessed {dict(r)['access_count']}x)"
235
+ for r in top_rows
236
+ ]
237
+
238
+ lines = [
239
+ f"Engagement (profile: {pid})",
240
+ f" Activity: {json.dumps(activity) if activity else 'no activity'}",
241
+ f" Top facts: {'; '.join(top_facts) if top_facts else 'none accessed'}",
242
+ ]
243
+ return "\n".join(lines)
244
+ except Exception as exc:
245
+ return f"Error loading engagement: {exc}"
@@ -0,0 +1,61 @@
1
+ # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
+ # Licensed under the MIT License - see LICENSE file
3
+ # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
+
5
+ """SuperLocalMemory V3 — MCP Server.
6
+
7
+ Clean MCP server calling V3 MemoryEngine. Supports all MCP-compatible IDEs.
8
+
9
+ Part of Qualixar | Author: Varun Pratap Bhardwaj
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import logging
15
+ import sys
16
+
17
+ from mcp.server.fastmcp import FastMCP
18
+
19
+ logger = logging.getLogger(__name__)
20
+
21
+ server = FastMCP("SuperLocalMemory V3")
22
+
23
+ # Lazy engine singleton -------------------------------------------------------
24
+
25
+ _engine = None
26
+
27
+
28
+ def get_engine():
29
+ """Return (or create) the singleton MemoryEngine."""
30
+ global _engine
31
+ if _engine is None:
32
+ from superlocalmemory.core.config import SLMConfig
33
+ from superlocalmemory.core.engine import MemoryEngine
34
+
35
+ config = SLMConfig.load()
36
+ _engine = MemoryEngine(config)
37
+ _engine.initialize()
38
+ return _engine
39
+
40
+
41
+ def reset_engine():
42
+ """Reset engine singleton (for testing or mode switch)."""
43
+ global _engine
44
+ _engine = None
45
+
46
+
47
+ # Register all tools and resources --------------------------------------------
48
+
49
+ from superlocalmemory.mcp.tools_core import register_core_tools
50
+ from superlocalmemory.mcp.tools_v28 import register_v28_tools
51
+ from superlocalmemory.mcp.tools_v3 import register_v3_tools
52
+ from superlocalmemory.mcp.resources import register_resources
53
+
54
+ register_core_tools(server, get_engine)
55
+ register_v28_tools(server, get_engine)
56
+ register_v3_tools(server, get_engine)
57
+ register_resources(server, get_engine)
58
+
59
+
60
+ if __name__ == "__main__":
61
+ server.run(transport="stdio")
@@ -0,0 +1,18 @@
1
+ # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
+ # Licensed under the MIT License - see LICENSE file
3
+ # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
+
5
+ """Backward compatibility — tools are now split across sub-modules.
6
+
7
+ tools_core: 13 core tools (remember, recall, search, etc.)
8
+ tools_v28: 6 V2.8-ported tools (report_outcome, lifecycle, audit, etc.)
9
+ tools_v3: 5 V3-only tools (set_mode, health, consistency, recall_trace)
10
+
11
+ Part of Qualixar | Author: Varun Pratap Bhardwaj
12
+ """
13
+
14
+ from superlocalmemory.mcp.tools_core import register_core_tools
15
+ from superlocalmemory.mcp.tools_v28 import register_v28_tools
16
+ from superlocalmemory.mcp.tools_v3 import register_v3_tools
17
+
18
+ __all__ = ["register_core_tools", "register_v28_tools", "register_v3_tools"]
@@ -0,0 +1,305 @@
1
+ # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
+ # Licensed under the MIT License - see LICENSE file
3
+ # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
+
5
+ """SuperLocalMemory V3 — Core MCP Tools (13 tools).
6
+
7
+ remember, recall, search, fetch, list_recent, get_status, build_graph,
8
+ switch_profile, backup_status, memory_used, get_learned_patterns,
9
+ correct_pattern, get_attribution.
10
+
11
+ Part of Qualixar | Author: Varun Pratap Bhardwaj
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import json
17
+ import logging
18
+ from typing import Any, Callable
19
+
20
+ logger = logging.getLogger(__name__)
21
+
22
+
23
+ def register_core_tools(server, get_engine: Callable) -> None:
24
+ """Register the 13 core MCP tools on *server*."""
25
+
26
+ @server.tool()
27
+ async def remember(
28
+ content: str, tags: str = "", project: str = "",
29
+ importance: int = 5, session_id: str = "",
30
+ agent_id: str = "mcp_client",
31
+ ) -> dict:
32
+ """Store content to memory with intelligent indexing.
33
+
34
+ Extracts atomic facts, resolves entities, builds graph edges,
35
+ and indexes for 4-channel retrieval.
36
+ """
37
+ try:
38
+ engine = get_engine()
39
+ metadata: dict[str, Any] = {"tags": tags, "project": project, "importance": importance, "agent_id": agent_id}
40
+ fact_ids = engine.store(content, session_id=session_id, metadata=metadata)
41
+ return {"success": True, "fact_ids": fact_ids, "count": len(fact_ids)}
42
+ except Exception as exc:
43
+ logger.exception("remember failed")
44
+ return {"success": False, "error": str(exc)}
45
+
46
+ @server.tool()
47
+ async def recall(query: str, limit: int = 10, agent_id: str = "mcp_client") -> dict:
48
+ """Search memories by semantic query with 4-channel retrieval, RRF fusion, and reranking."""
49
+ try:
50
+ engine = get_engine()
51
+ response = engine.recall(query, limit=limit)
52
+ results = _format_results(response.results[:limit])
53
+ return {"success": True, "results": results, "count": len(results), "query_type": response.query_type}
54
+ except Exception as exc:
55
+ logger.exception("recall failed")
56
+ return {"success": False, "error": str(exc)}
57
+
58
+ @server.tool()
59
+ async def search(query: str, limit: int = 10, profile_id: str = "") -> dict:
60
+ """Full-text search across memories using FTS5 with BM25 ranking."""
61
+ try:
62
+ engine = get_engine()
63
+ pid = profile_id or engine.profile_id
64
+ facts = engine._db.search_facts_fts(query, pid, limit=limit)
65
+ items = []
66
+ for f in facts:
67
+ items.append({
68
+ "fact_id": f.fact_id,
69
+ "content": f.content,
70
+ "fact_type": f.fact_type.value,
71
+ "confidence": round(f.confidence, 3),
72
+ "date": f.observation_date,
73
+ })
74
+ return {"success": True, "results": items, "count": len(items)}
75
+ except Exception as exc:
76
+ logger.exception("search failed")
77
+ return {"success": False, "error": str(exc)}
78
+
79
+ @server.tool()
80
+ async def fetch(fact_ids: str) -> dict:
81
+ """Fetch full details for specific fact IDs (comma-separated)."""
82
+ try:
83
+ engine = get_engine()
84
+ ids = [fid.strip() for fid in fact_ids.split(",") if fid.strip()]
85
+ facts = engine._db.get_facts_by_ids(ids, engine.profile_id)
86
+ items = []
87
+ for f in facts:
88
+ items.append({
89
+ "fact_id": f.fact_id,
90
+ "content": f.content,
91
+ "fact_type": f.fact_type.value,
92
+ "entities": f.canonical_entities,
93
+ "confidence": round(f.confidence, 3),
94
+ "importance": round(f.importance, 3),
95
+ "observation_date": f.observation_date,
96
+ "referenced_date": f.referenced_date,
97
+ "lifecycle": f.lifecycle.value,
98
+ "access_count": f.access_count,
99
+ })
100
+ return {"success": True, "results": items, "count": len(items)}
101
+ except Exception as exc:
102
+ logger.exception("fetch failed")
103
+ return {"success": False, "error": str(exc)}
104
+
105
+ @server.tool()
106
+ async def list_recent(limit: int = 20, profile_id: str = "") -> dict:
107
+ """List most recently stored memories, newest first."""
108
+ try:
109
+ engine = get_engine()
110
+ pid = profile_id or engine.profile_id
111
+ facts = engine._db.get_all_facts(pid)[:limit]
112
+ items = []
113
+ for f in facts:
114
+ items.append({
115
+ "fact_id": f.fact_id,
116
+ "content": f.content[:120],
117
+ "fact_type": f.fact_type.value,
118
+ "created_at": f.created_at,
119
+ "session_id": f.session_id,
120
+ })
121
+ return {"success": True, "results": items, "count": len(items)}
122
+ except Exception as exc:
123
+ logger.exception("list_recent failed")
124
+ return {"success": False, "error": str(exc)}
125
+
126
+ @server.tool()
127
+ async def get_status() -> dict:
128
+ """Get memory system status: fact count, entity count, mode, profile, db size."""
129
+ try:
130
+ engine = get_engine()
131
+ pid = engine.profile_id
132
+ fact_count = engine._db.get_fact_count(pid)
133
+ entities = engine._db.execute(
134
+ "SELECT COUNT(*) AS c FROM canonical_entities WHERE profile_id = ?",
135
+ (pid,),
136
+ )
137
+ entity_count = int(dict(entities[0])["c"]) if entities else 0
138
+ edges = engine._db.execute(
139
+ "SELECT COUNT(*) AS c FROM graph_edges WHERE profile_id = ?",
140
+ (pid,),
141
+ )
142
+ edge_count = int(dict(edges[0])["c"]) if edges else 0
143
+
144
+ import os
145
+ db_size_mb = 0.0
146
+ db_path = engine._db.db_path
147
+ if db_path.exists():
148
+ db_size_mb = round(os.path.getsize(db_path) / (1024 * 1024), 2)
149
+
150
+ return {
151
+ "success": True,
152
+ "mode": engine._config.mode.value,
153
+ "profile": pid,
154
+ "fact_count": fact_count,
155
+ "entity_count": entity_count,
156
+ "edge_count": edge_count,
157
+ "db_size_mb": db_size_mb,
158
+ }
159
+ except Exception as exc:
160
+ logger.exception("get_status failed")
161
+ return {"success": False, "error": str(exc)}
162
+
163
+ @server.tool()
164
+ async def build_graph(profile_id: str = "") -> dict:
165
+ """Rebuild knowledge graph edges for all facts in the active profile."""
166
+ try:
167
+ engine = get_engine()
168
+ pid = profile_id or engine.profile_id
169
+ facts = engine._db.get_all_facts(pid)
170
+ edge_count = 0
171
+ for fact in facts:
172
+ if engine._graph_builder:
173
+ engine._graph_builder.build_edges(fact, pid)
174
+ edge_count += 1
175
+ return {
176
+ "success": True,
177
+ "facts_processed": len(facts),
178
+ "edges_built": edge_count,
179
+ }
180
+ except Exception as exc:
181
+ logger.exception("build_graph failed")
182
+ return {"success": False, "error": str(exc)}
183
+
184
+ @server.tool()
185
+ async def switch_profile(profile_id: str) -> dict:
186
+ """Switch the active memory profile. All operations scope to this profile."""
187
+ try:
188
+ engine = get_engine()
189
+ old = engine.profile_id
190
+ engine.profile_id = profile_id
191
+ return {
192
+ "success": True,
193
+ "previous_profile": old,
194
+ "current_profile": profile_id,
195
+ }
196
+ except Exception as exc:
197
+ logger.exception("switch_profile failed")
198
+ return {"success": False, "error": str(exc)}
199
+
200
+ @server.tool()
201
+ async def backup_status() -> dict:
202
+ """Get backup system status, last backup time, and available backup files."""
203
+ try:
204
+ engine = get_engine()
205
+ from superlocalmemory.infra.backup import BackupManager
206
+ bm = BackupManager(engine._config.base_dir, engine._db.db_path)
207
+ return {"success": True, **bm.get_status()}
208
+ except Exception as exc:
209
+ logger.exception("backup_status failed")
210
+ return {"success": False, "error": str(exc)}
211
+
212
+ @server.tool()
213
+ async def memory_used() -> dict:
214
+ """Get memory usage breakdown by fact type and lifecycle state."""
215
+ try:
216
+ engine = get_engine()
217
+ pid = engine.profile_id
218
+ facts = engine._db.get_all_facts(pid)
219
+ by_type: dict[str, int] = {}
220
+ by_lifecycle: dict[str, int] = {}
221
+ for f in facts:
222
+ by_type[f.fact_type.value] = by_type.get(f.fact_type.value, 0) + 1
223
+ by_lifecycle[f.lifecycle.value] = (
224
+ by_lifecycle.get(f.lifecycle.value, 0) + 1
225
+ )
226
+ return {
227
+ "success": True,
228
+ "total_facts": len(facts),
229
+ "by_type": by_type,
230
+ "by_lifecycle": by_lifecycle,
231
+ "profile": pid,
232
+ }
233
+ except Exception as exc:
234
+ logger.exception("memory_used failed")
235
+ return {"success": False, "error": str(exc)}
236
+
237
+ @server.tool()
238
+ async def get_learned_patterns(pattern_type: str = "", limit: int = 20) -> dict:
239
+ """Get learned behavioral patterns (interests, refinements, archival habits)."""
240
+ try:
241
+ engine = get_engine()
242
+ from superlocalmemory.learning.behavioral import BehavioralStore
243
+ store = BehavioralStore(engine._db.db_path)
244
+ ptype = pattern_type if pattern_type else None
245
+ patterns = store.get_patterns(
246
+ engine.profile_id, pattern_type=ptype, limit=limit,
247
+ )
248
+ return {"success": True, "patterns": patterns, "count": len(patterns)}
249
+ except Exception as exc:
250
+ logger.exception("get_learned_patterns failed")
251
+ return {"success": False, "error": str(exc)}
252
+
253
+ @server.tool()
254
+ async def correct_pattern(pattern_id: str, correction: str) -> dict:
255
+ """Correct or annotate a learned behavioral pattern to improve retrieval."""
256
+ try:
257
+ engine = get_engine()
258
+ from superlocalmemory.learning.behavioral import BehavioralStore
259
+ store = BehavioralStore(engine._db.db_path)
260
+ store.record(
261
+ engine.profile_id,
262
+ pattern_type="correction",
263
+ pattern_key=pattern_id,
264
+ metadata={"correction": correction},
265
+ )
266
+ return {"success": True, "pattern_id": pattern_id}
267
+ except Exception as exc:
268
+ logger.exception("correct_pattern failed")
269
+ return {"success": False, "error": str(exc)}
270
+
271
+ @server.tool()
272
+ async def get_attribution() -> dict:
273
+ """Get system attribution: author, version, license, and provenance metadata."""
274
+ return {
275
+ "success": True,
276
+ "product": "SuperLocalMemory V3",
277
+ "author": "Varun Pratap Bhardwaj",
278
+ "organization": "Qualixar",
279
+ "license": "MIT",
280
+ "urls": {
281
+ "product": "https://superlocalmemory.com",
282
+ "author": "https://varunpratap.com",
283
+ "organization": "https://qualixar.com",
284
+ },
285
+ }
286
+
287
+
288
+ # -- Helpers ------------------------------------------------------------------
289
+
290
+ def _format_results(results) -> list[dict]:
291
+ """Convert RetrievalResult list to serialisable dicts."""
292
+ items: list[dict] = []
293
+ for r in results:
294
+ items.append({
295
+ "fact_id": r.fact.fact_id,
296
+ "content": r.fact.content,
297
+ "score": round(r.score, 3),
298
+ "confidence": round(r.confidence, 3),
299
+ "trust_score": round(r.trust_score, 3),
300
+ "fact_type": r.fact.fact_type.value,
301
+ "channel_scores": {
302
+ k: round(v, 3) for k, v in r.channel_scores.items()
303
+ },
304
+ })
305
+ return items