superlocalmemory 2.8.6 → 3.0.1

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 (431) hide show
  1. package/LICENSE +9 -1
  2. package/NOTICE +63 -0
  3. package/README.md +165 -480
  4. package/bin/slm +17 -449
  5. package/bin/slm-npm +62 -48
  6. package/conftest.py +5 -0
  7. package/docs/api-reference.md +284 -0
  8. package/docs/architecture.md +149 -0
  9. package/docs/auto-memory.md +150 -0
  10. package/docs/cli-reference.md +276 -0
  11. package/docs/compliance.md +191 -0
  12. package/docs/configuration.md +182 -0
  13. package/docs/getting-started.md +102 -0
  14. package/docs/ide-setup.md +261 -0
  15. package/docs/mcp-tools.md +220 -0
  16. package/docs/migration-from-v2.md +170 -0
  17. package/docs/profiles.md +173 -0
  18. package/docs/troubleshooting.md +310 -0
  19. package/{configs → ide/configs}/antigravity-mcp.json +3 -3
  20. package/ide/configs/chatgpt-desktop-mcp.json +16 -0
  21. package/{configs → ide/configs}/claude-desktop-mcp.json +3 -3
  22. package/{configs → ide/configs}/codex-mcp.toml +4 -4
  23. package/{configs → ide/configs}/continue-mcp.yaml +4 -3
  24. package/{configs → ide/configs}/continue-skills.yaml +6 -6
  25. package/ide/configs/cursor-mcp.json +15 -0
  26. package/{configs → ide/configs}/gemini-cli-mcp.json +2 -2
  27. package/{configs → ide/configs}/jetbrains-mcp.json +2 -2
  28. package/{configs → ide/configs}/opencode-mcp.json +2 -2
  29. package/{configs → ide/configs}/perplexity-mcp.json +2 -2
  30. package/{configs → ide/configs}/vscode-copilot-mcp.json +2 -2
  31. package/{configs → ide/configs}/windsurf-mcp.json +3 -3
  32. package/{configs → ide/configs}/zed-mcp.json +2 -2
  33. package/{hooks → ide/hooks}/context-hook.js +9 -20
  34. package/ide/hooks/memory-list-skill.js +70 -0
  35. package/ide/hooks/memory-profile-skill.js +101 -0
  36. package/ide/hooks/memory-recall-skill.js +62 -0
  37. package/ide/hooks/memory-remember-skill.js +68 -0
  38. package/ide/hooks/memory-reset-skill.js +160 -0
  39. package/{hooks → ide/hooks}/post-recall-hook.js +2 -2
  40. package/ide/integrations/langchain/README.md +106 -0
  41. package/ide/integrations/langchain/langchain_superlocalmemory/__init__.py +9 -0
  42. package/ide/integrations/langchain/langchain_superlocalmemory/chat_message_history.py +201 -0
  43. package/ide/integrations/langchain/pyproject.toml +38 -0
  44. package/{src/learning → ide/integrations/langchain}/tests/__init__.py +1 -0
  45. package/ide/integrations/langchain/tests/test_chat_message_history.py +215 -0
  46. package/ide/integrations/langchain/tests/test_security.py +117 -0
  47. package/ide/integrations/llamaindex/README.md +81 -0
  48. package/ide/integrations/llamaindex/llama_index/storage/chat_store/superlocalmemory/__init__.py +9 -0
  49. package/ide/integrations/llamaindex/llama_index/storage/chat_store/superlocalmemory/base.py +316 -0
  50. package/ide/integrations/llamaindex/pyproject.toml +43 -0
  51. package/{src/lifecycle → ide/integrations/llamaindex}/tests/__init__.py +1 -2
  52. package/ide/integrations/llamaindex/tests/test_chat_store.py +294 -0
  53. package/ide/integrations/llamaindex/tests/test_security.py +241 -0
  54. package/{skills → ide/skills}/slm-build-graph/SKILL.md +6 -6
  55. package/{skills → ide/skills}/slm-list-recent/SKILL.md +5 -5
  56. package/{skills → ide/skills}/slm-recall/SKILL.md +5 -5
  57. package/{skills → ide/skills}/slm-remember/SKILL.md +6 -6
  58. package/{skills → ide/skills}/slm-show-patterns/SKILL.md +7 -7
  59. package/{skills → ide/skills}/slm-status/SKILL.md +9 -9
  60. package/{skills → ide/skills}/slm-switch-profile/SKILL.md +9 -9
  61. package/package.json +13 -22
  62. package/pyproject.toml +85 -0
  63. package/scripts/build-dmg.sh +417 -0
  64. package/scripts/install-skills.ps1 +334 -0
  65. package/scripts/postinstall.js +2 -2
  66. package/scripts/start-dashboard.ps1 +52 -0
  67. package/scripts/start-dashboard.sh +41 -0
  68. package/scripts/sync-wiki.ps1 +127 -0
  69. package/scripts/sync-wiki.sh +82 -0
  70. package/scripts/test-dmg.sh +161 -0
  71. package/scripts/test-npm-package.ps1 +252 -0
  72. package/scripts/test-npm-package.sh +207 -0
  73. package/scripts/verify-install.ps1 +294 -0
  74. package/scripts/verify-install.sh +266 -0
  75. package/src/superlocalmemory/__init__.py +0 -0
  76. package/src/superlocalmemory/attribution/__init__.py +9 -0
  77. package/src/superlocalmemory/attribution/mathematical_dna.py +235 -0
  78. package/src/superlocalmemory/attribution/signer.py +153 -0
  79. package/src/superlocalmemory/attribution/watermark.py +189 -0
  80. package/src/superlocalmemory/cli/__init__.py +5 -0
  81. package/src/superlocalmemory/cli/commands.py +245 -0
  82. package/src/superlocalmemory/cli/main.py +89 -0
  83. package/src/superlocalmemory/cli/migrate_cmd.py +55 -0
  84. package/src/superlocalmemory/cli/post_install.py +99 -0
  85. package/src/superlocalmemory/cli/setup_wizard.py +129 -0
  86. package/src/superlocalmemory/compliance/__init__.py +0 -0
  87. package/src/superlocalmemory/compliance/abac.py +204 -0
  88. package/src/superlocalmemory/compliance/audit.py +314 -0
  89. package/src/superlocalmemory/compliance/eu_ai_act.py +131 -0
  90. package/src/superlocalmemory/compliance/gdpr.py +294 -0
  91. package/src/superlocalmemory/compliance/lifecycle.py +158 -0
  92. package/src/superlocalmemory/compliance/retention.py +232 -0
  93. package/src/superlocalmemory/compliance/scheduler.py +148 -0
  94. package/src/superlocalmemory/core/__init__.py +0 -0
  95. package/src/superlocalmemory/core/config.py +391 -0
  96. package/src/superlocalmemory/core/embeddings.py +293 -0
  97. package/src/superlocalmemory/core/engine.py +701 -0
  98. package/src/superlocalmemory/core/hooks.py +65 -0
  99. package/src/superlocalmemory/core/maintenance.py +172 -0
  100. package/src/superlocalmemory/core/modes.py +140 -0
  101. package/src/superlocalmemory/core/profiles.py +234 -0
  102. package/src/superlocalmemory/core/registry.py +117 -0
  103. package/src/superlocalmemory/dynamics/__init__.py +0 -0
  104. package/src/superlocalmemory/dynamics/fisher_langevin_coupling.py +223 -0
  105. package/src/superlocalmemory/encoding/__init__.py +0 -0
  106. package/src/superlocalmemory/encoding/consolidator.py +485 -0
  107. package/src/superlocalmemory/encoding/emotional.py +125 -0
  108. package/src/superlocalmemory/encoding/entity_resolver.py +525 -0
  109. package/src/superlocalmemory/encoding/entropy_gate.py +104 -0
  110. package/src/superlocalmemory/encoding/fact_extractor.py +775 -0
  111. package/src/superlocalmemory/encoding/foresight.py +91 -0
  112. package/src/superlocalmemory/encoding/graph_builder.py +302 -0
  113. package/src/superlocalmemory/encoding/observation_builder.py +160 -0
  114. package/src/superlocalmemory/encoding/scene_builder.py +183 -0
  115. package/src/superlocalmemory/encoding/signal_inference.py +90 -0
  116. package/src/superlocalmemory/encoding/temporal_parser.py +426 -0
  117. package/src/superlocalmemory/encoding/type_router.py +235 -0
  118. package/src/superlocalmemory/hooks/__init__.py +3 -0
  119. package/src/superlocalmemory/hooks/auto_capture.py +111 -0
  120. package/src/superlocalmemory/hooks/auto_recall.py +93 -0
  121. package/src/superlocalmemory/hooks/ide_connector.py +204 -0
  122. package/src/superlocalmemory/hooks/rules_engine.py +99 -0
  123. package/src/superlocalmemory/infra/__init__.py +3 -0
  124. package/src/superlocalmemory/infra/auth_middleware.py +82 -0
  125. package/src/superlocalmemory/infra/backup.py +317 -0
  126. package/src/superlocalmemory/infra/cache_manager.py +267 -0
  127. package/src/superlocalmemory/infra/event_bus.py +381 -0
  128. package/src/superlocalmemory/infra/rate_limiter.py +135 -0
  129. package/src/{webhook_dispatcher.py → superlocalmemory/infra/webhook_dispatcher.py} +104 -101
  130. package/src/superlocalmemory/learning/__init__.py +0 -0
  131. package/src/superlocalmemory/learning/adaptive.py +172 -0
  132. package/src/superlocalmemory/learning/behavioral.py +490 -0
  133. package/src/superlocalmemory/learning/behavioral_listener.py +94 -0
  134. package/src/superlocalmemory/learning/bootstrap.py +298 -0
  135. package/src/superlocalmemory/learning/cross_project.py +399 -0
  136. package/src/superlocalmemory/learning/database.py +376 -0
  137. package/src/superlocalmemory/learning/engagement.py +323 -0
  138. package/src/superlocalmemory/learning/features.py +138 -0
  139. package/src/superlocalmemory/learning/feedback.py +316 -0
  140. package/src/superlocalmemory/learning/outcomes.py +255 -0
  141. package/src/superlocalmemory/learning/project_context.py +366 -0
  142. package/src/superlocalmemory/learning/ranker.py +155 -0
  143. package/src/superlocalmemory/learning/source_quality.py +303 -0
  144. package/src/superlocalmemory/learning/workflows.py +309 -0
  145. package/src/superlocalmemory/llm/__init__.py +0 -0
  146. package/src/superlocalmemory/llm/backbone.py +316 -0
  147. package/src/superlocalmemory/math/__init__.py +0 -0
  148. package/src/superlocalmemory/math/fisher.py +356 -0
  149. package/src/superlocalmemory/math/langevin.py +398 -0
  150. package/src/superlocalmemory/math/sheaf.py +257 -0
  151. package/src/superlocalmemory/mcp/__init__.py +0 -0
  152. package/src/superlocalmemory/mcp/resources.py +245 -0
  153. package/src/superlocalmemory/mcp/server.py +61 -0
  154. package/src/superlocalmemory/mcp/tools.py +18 -0
  155. package/src/superlocalmemory/mcp/tools_core.py +305 -0
  156. package/src/superlocalmemory/mcp/tools_v28.py +223 -0
  157. package/src/superlocalmemory/mcp/tools_v3.py +286 -0
  158. package/src/superlocalmemory/retrieval/__init__.py +0 -0
  159. package/src/superlocalmemory/retrieval/agentic.py +295 -0
  160. package/src/superlocalmemory/retrieval/ann_index.py +223 -0
  161. package/src/superlocalmemory/retrieval/bm25_channel.py +185 -0
  162. package/src/superlocalmemory/retrieval/bridge_discovery.py +170 -0
  163. package/src/superlocalmemory/retrieval/engine.py +390 -0
  164. package/src/superlocalmemory/retrieval/entity_channel.py +179 -0
  165. package/src/superlocalmemory/retrieval/fusion.py +78 -0
  166. package/src/superlocalmemory/retrieval/profile_channel.py +105 -0
  167. package/src/superlocalmemory/retrieval/reranker.py +154 -0
  168. package/src/superlocalmemory/retrieval/semantic_channel.py +232 -0
  169. package/src/superlocalmemory/retrieval/strategy.py +96 -0
  170. package/src/superlocalmemory/retrieval/temporal_channel.py +175 -0
  171. package/src/superlocalmemory/server/__init__.py +1 -0
  172. package/src/superlocalmemory/server/api.py +248 -0
  173. package/src/superlocalmemory/server/routes/__init__.py +4 -0
  174. package/src/superlocalmemory/server/routes/agents.py +107 -0
  175. package/src/superlocalmemory/server/routes/backup.py +91 -0
  176. package/src/superlocalmemory/server/routes/behavioral.py +127 -0
  177. package/src/superlocalmemory/server/routes/compliance.py +160 -0
  178. package/src/superlocalmemory/server/routes/data_io.py +188 -0
  179. package/src/superlocalmemory/server/routes/events.py +183 -0
  180. package/src/superlocalmemory/server/routes/helpers.py +85 -0
  181. package/src/superlocalmemory/server/routes/learning.py +273 -0
  182. package/src/superlocalmemory/server/routes/lifecycle.py +116 -0
  183. package/src/superlocalmemory/server/routes/memories.py +399 -0
  184. package/src/superlocalmemory/server/routes/profiles.py +219 -0
  185. package/src/superlocalmemory/server/routes/stats.py +346 -0
  186. package/src/superlocalmemory/server/routes/v3_api.py +365 -0
  187. package/src/superlocalmemory/server/routes/ws.py +82 -0
  188. package/src/superlocalmemory/server/security_middleware.py +57 -0
  189. package/src/superlocalmemory/server/ui.py +245 -0
  190. package/src/superlocalmemory/storage/__init__.py +0 -0
  191. package/src/superlocalmemory/storage/access_control.py +182 -0
  192. package/src/superlocalmemory/storage/database.py +594 -0
  193. package/src/superlocalmemory/storage/migrations.py +303 -0
  194. package/src/superlocalmemory/storage/models.py +406 -0
  195. package/src/superlocalmemory/storage/schema.py +726 -0
  196. package/src/superlocalmemory/storage/v2_migrator.py +317 -0
  197. package/src/superlocalmemory/trust/__init__.py +0 -0
  198. package/src/superlocalmemory/trust/gate.py +130 -0
  199. package/src/superlocalmemory/trust/provenance.py +124 -0
  200. package/src/superlocalmemory/trust/scorer.py +347 -0
  201. package/src/superlocalmemory/trust/signals.py +153 -0
  202. package/ui/index.html +278 -5
  203. package/ui/js/auto-settings.js +70 -0
  204. package/ui/js/dashboard.js +90 -0
  205. package/ui/js/fact-detail.js +92 -0
  206. package/ui/js/feedback.js +2 -2
  207. package/ui/js/ide-status.js +102 -0
  208. package/ui/js/math-health.js +98 -0
  209. package/ui/js/recall-lab.js +127 -0
  210. package/ui/js/settings.js +2 -2
  211. package/ui/js/trust-dashboard.js +73 -0
  212. package/api_server.py +0 -724
  213. package/bin/aider-smart +0 -72
  214. package/bin/superlocalmemoryv2-learning +0 -4
  215. package/bin/superlocalmemoryv2-list +0 -3
  216. package/bin/superlocalmemoryv2-patterns +0 -4
  217. package/bin/superlocalmemoryv2-profile +0 -3
  218. package/bin/superlocalmemoryv2-recall +0 -3
  219. package/bin/superlocalmemoryv2-remember +0 -3
  220. package/bin/superlocalmemoryv2-reset +0 -3
  221. package/bin/superlocalmemoryv2-status +0 -3
  222. package/configs/chatgpt-desktop-mcp.json +0 -16
  223. package/configs/cursor-mcp.json +0 -15
  224. package/hooks/memory-list-skill.js +0 -139
  225. package/hooks/memory-profile-skill.js +0 -273
  226. package/hooks/memory-recall-skill.js +0 -114
  227. package/hooks/memory-remember-skill.js +0 -127
  228. package/hooks/memory-reset-skill.js +0 -274
  229. package/mcp_server.py +0 -1808
  230. package/requirements-core.txt +0 -22
  231. package/requirements-learning.txt +0 -12
  232. package/requirements.txt +0 -12
  233. package/src/agent_registry.py +0 -411
  234. package/src/auth_middleware.py +0 -61
  235. package/src/auto_backup.py +0 -459
  236. package/src/behavioral/__init__.py +0 -49
  237. package/src/behavioral/behavioral_listener.py +0 -203
  238. package/src/behavioral/behavioral_patterns.py +0 -275
  239. package/src/behavioral/cross_project_transfer.py +0 -206
  240. package/src/behavioral/outcome_inference.py +0 -194
  241. package/src/behavioral/outcome_tracker.py +0 -193
  242. package/src/behavioral/tests/__init__.py +0 -4
  243. package/src/behavioral/tests/test_behavioral_integration.py +0 -108
  244. package/src/behavioral/tests/test_behavioral_patterns.py +0 -150
  245. package/src/behavioral/tests/test_cross_project_transfer.py +0 -142
  246. package/src/behavioral/tests/test_mcp_behavioral.py +0 -139
  247. package/src/behavioral/tests/test_mcp_report_outcome.py +0 -117
  248. package/src/behavioral/tests/test_outcome_inference.py +0 -107
  249. package/src/behavioral/tests/test_outcome_tracker.py +0 -96
  250. package/src/cache_manager.py +0 -518
  251. package/src/compliance/__init__.py +0 -48
  252. package/src/compliance/abac_engine.py +0 -149
  253. package/src/compliance/abac_middleware.py +0 -116
  254. package/src/compliance/audit_db.py +0 -215
  255. package/src/compliance/audit_logger.py +0 -148
  256. package/src/compliance/retention_manager.py +0 -289
  257. package/src/compliance/retention_scheduler.py +0 -186
  258. package/src/compliance/tests/__init__.py +0 -4
  259. package/src/compliance/tests/test_abac_enforcement.py +0 -95
  260. package/src/compliance/tests/test_abac_engine.py +0 -124
  261. package/src/compliance/tests/test_abac_mcp_integration.py +0 -118
  262. package/src/compliance/tests/test_audit_db.py +0 -123
  263. package/src/compliance/tests/test_audit_logger.py +0 -98
  264. package/src/compliance/tests/test_mcp_audit.py +0 -128
  265. package/src/compliance/tests/test_mcp_retention_policy.py +0 -125
  266. package/src/compliance/tests/test_retention_manager.py +0 -131
  267. package/src/compliance/tests/test_retention_scheduler.py +0 -99
  268. package/src/compression/__init__.py +0 -25
  269. package/src/compression/cli.py +0 -150
  270. package/src/compression/cold_storage.py +0 -217
  271. package/src/compression/config.py +0 -72
  272. package/src/compression/orchestrator.py +0 -133
  273. package/src/compression/tier2_compressor.py +0 -228
  274. package/src/compression/tier3_compressor.py +0 -153
  275. package/src/compression/tier_classifier.py +0 -148
  276. package/src/db_connection_manager.py +0 -536
  277. package/src/embedding_engine.py +0 -63
  278. package/src/embeddings/__init__.py +0 -47
  279. package/src/embeddings/cache.py +0 -70
  280. package/src/embeddings/cli.py +0 -113
  281. package/src/embeddings/constants.py +0 -47
  282. package/src/embeddings/database.py +0 -91
  283. package/src/embeddings/engine.py +0 -247
  284. package/src/embeddings/model_loader.py +0 -145
  285. package/src/event_bus.py +0 -562
  286. package/src/graph/__init__.py +0 -36
  287. package/src/graph/build_helpers.py +0 -74
  288. package/src/graph/cli.py +0 -87
  289. package/src/graph/cluster_builder.py +0 -188
  290. package/src/graph/cluster_summary.py +0 -148
  291. package/src/graph/constants.py +0 -47
  292. package/src/graph/edge_builder.py +0 -162
  293. package/src/graph/entity_extractor.py +0 -95
  294. package/src/graph/graph_core.py +0 -226
  295. package/src/graph/graph_search.py +0 -231
  296. package/src/graph/hierarchical.py +0 -207
  297. package/src/graph/schema.py +0 -99
  298. package/src/graph_engine.py +0 -52
  299. package/src/hnsw_index.py +0 -628
  300. package/src/hybrid_search.py +0 -46
  301. package/src/learning/__init__.py +0 -217
  302. package/src/learning/adaptive_ranker.py +0 -682
  303. package/src/learning/bootstrap/__init__.py +0 -69
  304. package/src/learning/bootstrap/constants.py +0 -93
  305. package/src/learning/bootstrap/db_queries.py +0 -316
  306. package/src/learning/bootstrap/sampling.py +0 -82
  307. package/src/learning/bootstrap/text_utils.py +0 -71
  308. package/src/learning/cross_project_aggregator.py +0 -857
  309. package/src/learning/db/__init__.py +0 -40
  310. package/src/learning/db/constants.py +0 -44
  311. package/src/learning/db/schema.py +0 -279
  312. package/src/learning/engagement_tracker.py +0 -628
  313. package/src/learning/feature_extractor.py +0 -708
  314. package/src/learning/feedback_collector.py +0 -806
  315. package/src/learning/learning_db.py +0 -915
  316. package/src/learning/project_context_manager.py +0 -572
  317. package/src/learning/ranking/__init__.py +0 -33
  318. package/src/learning/ranking/constants.py +0 -84
  319. package/src/learning/ranking/helpers.py +0 -278
  320. package/src/learning/source_quality_scorer.py +0 -676
  321. package/src/learning/synthetic_bootstrap.py +0 -755
  322. package/src/learning/tests/test_adaptive_ranker.py +0 -325
  323. package/src/learning/tests/test_adaptive_ranker_v28.py +0 -60
  324. package/src/learning/tests/test_aggregator.py +0 -306
  325. package/src/learning/tests/test_auto_retrain_v28.py +0 -35
  326. package/src/learning/tests/test_e2e_ranking_v28.py +0 -82
  327. package/src/learning/tests/test_feature_extractor_v28.py +0 -93
  328. package/src/learning/tests/test_feedback_collector.py +0 -294
  329. package/src/learning/tests/test_learning_db.py +0 -602
  330. package/src/learning/tests/test_learning_db_v28.py +0 -110
  331. package/src/learning/tests/test_learning_init_v28.py +0 -48
  332. package/src/learning/tests/test_outcome_signals.py +0 -48
  333. package/src/learning/tests/test_project_context.py +0 -292
  334. package/src/learning/tests/test_schema_migration.py +0 -319
  335. package/src/learning/tests/test_signal_inference.py +0 -397
  336. package/src/learning/tests/test_source_quality.py +0 -351
  337. package/src/learning/tests/test_synthetic_bootstrap.py +0 -429
  338. package/src/learning/tests/test_workflow_miner.py +0 -318
  339. package/src/learning/workflow_pattern_miner.py +0 -655
  340. package/src/lifecycle/__init__.py +0 -54
  341. package/src/lifecycle/bounded_growth.py +0 -239
  342. package/src/lifecycle/compaction_engine.py +0 -226
  343. package/src/lifecycle/lifecycle_engine.py +0 -355
  344. package/src/lifecycle/lifecycle_evaluator.py +0 -257
  345. package/src/lifecycle/lifecycle_scheduler.py +0 -130
  346. package/src/lifecycle/retention_policy.py +0 -285
  347. package/src/lifecycle/tests/test_bounded_growth.py +0 -193
  348. package/src/lifecycle/tests/test_compaction.py +0 -179
  349. package/src/lifecycle/tests/test_lifecycle_engine.py +0 -137
  350. package/src/lifecycle/tests/test_lifecycle_evaluation.py +0 -177
  351. package/src/lifecycle/tests/test_lifecycle_scheduler.py +0 -127
  352. package/src/lifecycle/tests/test_lifecycle_search.py +0 -109
  353. package/src/lifecycle/tests/test_mcp_compact.py +0 -149
  354. package/src/lifecycle/tests/test_mcp_lifecycle_status.py +0 -114
  355. package/src/lifecycle/tests/test_retention_policy.py +0 -162
  356. package/src/mcp_tools_v28.py +0 -281
  357. package/src/memory/__init__.py +0 -36
  358. package/src/memory/cli.py +0 -205
  359. package/src/memory/constants.py +0 -39
  360. package/src/memory/helpers.py +0 -28
  361. package/src/memory/schema.py +0 -166
  362. package/src/memory-profiles.py +0 -595
  363. package/src/memory-reset.py +0 -491
  364. package/src/memory_compression.py +0 -989
  365. package/src/memory_store_v2.py +0 -1155
  366. package/src/migrate_v1_to_v2.py +0 -629
  367. package/src/pattern_learner.py +0 -34
  368. package/src/patterns/__init__.py +0 -24
  369. package/src/patterns/analyzers.py +0 -251
  370. package/src/patterns/learner.py +0 -271
  371. package/src/patterns/scoring.py +0 -171
  372. package/src/patterns/store.py +0 -225
  373. package/src/patterns/terminology.py +0 -140
  374. package/src/provenance_tracker.py +0 -312
  375. package/src/qualixar_attribution.py +0 -139
  376. package/src/qualixar_watermark.py +0 -78
  377. package/src/query_optimizer.py +0 -511
  378. package/src/rate_limiter.py +0 -83
  379. package/src/search/__init__.py +0 -20
  380. package/src/search/cli.py +0 -77
  381. package/src/search/constants.py +0 -26
  382. package/src/search/engine.py +0 -241
  383. package/src/search/fusion.py +0 -122
  384. package/src/search/index_loader.py +0 -114
  385. package/src/search/methods.py +0 -162
  386. package/src/search_engine_v2.py +0 -401
  387. package/src/setup_validator.py +0 -482
  388. package/src/subscription_manager.py +0 -391
  389. package/src/tree/__init__.py +0 -59
  390. package/src/tree/builder.py +0 -185
  391. package/src/tree/nodes.py +0 -202
  392. package/src/tree/queries.py +0 -257
  393. package/src/tree/schema.py +0 -80
  394. package/src/tree_manager.py +0 -19
  395. package/src/trust/__init__.py +0 -45
  396. package/src/trust/constants.py +0 -66
  397. package/src/trust/queries.py +0 -157
  398. package/src/trust/schema.py +0 -95
  399. package/src/trust/scorer.py +0 -299
  400. package/src/trust/signals.py +0 -95
  401. package/src/trust_scorer.py +0 -44
  402. package/ui/app.js +0 -1588
  403. package/ui/js/graph-cytoscape-monolithic-backup.js +0 -1168
  404. package/ui/js/graph-cytoscape.js +0 -1168
  405. package/ui/js/graph-d3-backup.js +0 -32
  406. package/ui/js/graph.js +0 -32
  407. package/ui_server.py +0 -286
  408. /package/docs/{ACCESSIBILITY.md → v2-archive/ACCESSIBILITY.md} +0 -0
  409. /package/docs/{ARCHITECTURE.md → v2-archive/ARCHITECTURE.md} +0 -0
  410. /package/docs/{CLI-COMMANDS-REFERENCE.md → v2-archive/CLI-COMMANDS-REFERENCE.md} +0 -0
  411. /package/docs/{COMPRESSION-README.md → v2-archive/COMPRESSION-README.md} +0 -0
  412. /package/docs/{FRAMEWORK-INTEGRATIONS.md → v2-archive/FRAMEWORK-INTEGRATIONS.md} +0 -0
  413. /package/docs/{MCP-MANUAL-SETUP.md → v2-archive/MCP-MANUAL-SETUP.md} +0 -0
  414. /package/docs/{MCP-TROUBLESHOOTING.md → v2-archive/MCP-TROUBLESHOOTING.md} +0 -0
  415. /package/docs/{PATTERN-LEARNING.md → v2-archive/PATTERN-LEARNING.md} +0 -0
  416. /package/docs/{PROFILES-GUIDE.md → v2-archive/PROFILES-GUIDE.md} +0 -0
  417. /package/docs/{RESET-GUIDE.md → v2-archive/RESET-GUIDE.md} +0 -0
  418. /package/docs/{SEARCH-ENGINE-V2.2.0.md → v2-archive/SEARCH-ENGINE-V2.2.0.md} +0 -0
  419. /package/docs/{SEARCH-INTEGRATION-GUIDE.md → v2-archive/SEARCH-INTEGRATION-GUIDE.md} +0 -0
  420. /package/docs/{UI-SERVER.md → v2-archive/UI-SERVER.md} +0 -0
  421. /package/docs/{UNIVERSAL-INTEGRATION.md → v2-archive/UNIVERSAL-INTEGRATION.md} +0 -0
  422. /package/docs/{V2.2.0-OPTIONAL-SEARCH.md → v2-archive/V2.2.0-OPTIONAL-SEARCH.md} +0 -0
  423. /package/docs/{WINDOWS-INSTALL-README.txt → v2-archive/WINDOWS-INSTALL-README.txt} +0 -0
  424. /package/docs/{WINDOWS-POST-INSTALL.txt → v2-archive/WINDOWS-POST-INSTALL.txt} +0 -0
  425. /package/docs/{example_graph_usage.py → v2-archive/example_graph_usage.py} +0 -0
  426. /package/{completions → ide/completions}/slm.bash +0 -0
  427. /package/{completions → ide/completions}/slm.zsh +0 -0
  428. /package/{configs → ide/configs}/cody-commands.json +0 -0
  429. /package/{install-skills.sh → scripts/install-skills.sh} +0 -0
  430. /package/{install.ps1 → scripts/install.ps1} +0 -0
  431. /package/{install.sh → scripts/install.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