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,248 @@
1
+ #!/usr/bin/env python3
2
+ # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
3
+ # Licensed under the MIT License - see LICENSE file
4
+ # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
5
+ """
6
+ SuperLocalMemory V3 - FastAPI API Server
7
+ Provides REST endpoints for memory visualization and exploration.
8
+ Uses V3 MemoryEngine for all operations.
9
+ """
10
+
11
+ import json
12
+ import logging
13
+ from pathlib import Path
14
+ from contextlib import asynccontextmanager
15
+ from typing import Optional
16
+
17
+ from fastapi import FastAPI, HTTPException, Query, Request
18
+ from fastapi.staticfiles import StaticFiles
19
+ from fastapi.responses import HTMLResponse
20
+ from fastapi.middleware.cors import CORSMiddleware
21
+ from fastapi.middleware.gzip import GZipMiddleware
22
+ from pydantic import BaseModel
23
+ import uvicorn
24
+
25
+ from superlocalmemory.server.security_middleware import SecurityHeadersMiddleware
26
+
27
+ logger = logging.getLogger("superlocalmemory.api_server")
28
+
29
+ # V3 paths
30
+ MEMORY_DIR = Path.home() / ".superlocalmemory"
31
+ DB_PATH = MEMORY_DIR / "memory.db"
32
+ # ui/ is at repo root, 4 levels up from src/superlocalmemory/server/api.py
33
+ UI_DIR = Path(__file__).resolve().parent.parent.parent.parent / "ui"
34
+
35
+
36
+ # ============================================================================
37
+ # Request/Response Models
38
+ # ============================================================================
39
+
40
+ class SearchRequest(BaseModel):
41
+ query: str
42
+ limit: int = 10
43
+ min_score: float = 0.3
44
+
45
+
46
+ class MemoryFilter(BaseModel):
47
+ category: Optional[str] = None
48
+ project_name: Optional[str] = None
49
+ cluster_id: Optional[int] = None
50
+ min_importance: Optional[int] = None
51
+
52
+
53
+ # ============================================================================
54
+ # V3 Engine Initialization (lifespan context)
55
+ # ============================================================================
56
+
57
+ @asynccontextmanager
58
+ async def lifespan(application: FastAPI):
59
+ """Initialize V3 engine on startup, cleanup on shutdown."""
60
+ try:
61
+ from superlocalmemory.core.config import SLMConfig
62
+ from superlocalmemory.core.engine import MemoryEngine
63
+
64
+ config = SLMConfig.load()
65
+ engine = MemoryEngine(config)
66
+ engine.initialize()
67
+ application.state.engine = engine
68
+ application.state.config = config
69
+ logger.info("V3 MemoryEngine initialized: mode=%s", config.mode.value)
70
+ except Exception as exc:
71
+ logger.warning("V3 engine init failed (API will use fallback): %s", exc)
72
+ application.state.engine = None
73
+ application.state.config = None
74
+
75
+ yield
76
+
77
+ # Cleanup
78
+ if hasattr(application.state, 'engine') and application.state.engine:
79
+ application.state.engine.close()
80
+
81
+
82
+ def create_app() -> FastAPI:
83
+ """Create and configure the FastAPI application."""
84
+ application = FastAPI(
85
+ title="SuperLocalMemory V3 API",
86
+ description="V3 Memory Engine REST API",
87
+ version="3.0.0",
88
+ lifespan=lifespan,
89
+ )
90
+
91
+ # Middleware
92
+ application.add_middleware(SecurityHeadersMiddleware)
93
+ application.add_middleware(GZipMiddleware, minimum_size=1000)
94
+ application.add_middleware(
95
+ CORSMiddleware,
96
+ allow_origins=[
97
+ "http://localhost:8765", "http://127.0.0.1:8765",
98
+ "http://localhost:8417", "http://127.0.0.1:8417",
99
+ ],
100
+ allow_credentials=True,
101
+ allow_methods=["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"],
102
+ allow_headers=["Content-Type", "Authorization", "X-SLM-API-Key"],
103
+ )
104
+
105
+ # Rate limiting (graceful)
106
+ try:
107
+ from superlocalmemory.infra.rate_limiter import RateLimiter
108
+ _write_limiter = RateLimiter(max_requests=30, window_seconds=60)
109
+ _read_limiter = RateLimiter(max_requests=120, window_seconds=60)
110
+
111
+ @application.middleware("http")
112
+ async def rate_limit_middleware(request, call_next):
113
+ client_ip = request.client.host if request.client else "unknown"
114
+ is_write = request.method in ("POST", "PUT", "DELETE", "PATCH")
115
+ limiter = _write_limiter if is_write else _read_limiter
116
+ allowed, remaining = limiter.is_allowed(client_ip)
117
+ if not allowed:
118
+ from fastapi.responses import JSONResponse
119
+ return JSONResponse(
120
+ status_code=429,
121
+ content={"error": "Too many requests."},
122
+ headers={"Retry-After": str(limiter.window_seconds)},
123
+ )
124
+ response = await call_next(request)
125
+ response.headers["X-RateLimit-Remaining"] = str(remaining)
126
+ return response
127
+ except (ImportError, Exception):
128
+ pass
129
+
130
+ # Auth middleware (graceful)
131
+ try:
132
+ from superlocalmemory.infra.auth_middleware import check_api_key
133
+
134
+ @application.middleware("http")
135
+ async def auth_middleware(request, call_next):
136
+ is_write = request.method in ("POST", "PUT", "DELETE", "PATCH")
137
+ headers = dict(request.headers)
138
+ if not check_api_key(headers, is_write=is_write):
139
+ from fastapi.responses import JSONResponse
140
+ return JSONResponse(
141
+ status_code=401,
142
+ content={"error": "Invalid or missing API key."},
143
+ )
144
+ response = await call_next(request)
145
+ return response
146
+ except (ImportError, Exception):
147
+ pass
148
+
149
+ # Mount static files
150
+ UI_DIR.mkdir(exist_ok=True)
151
+ application.mount("/static", StaticFiles(directory=str(UI_DIR)), name="static")
152
+
153
+ # ========================================================================
154
+ # Register Route Modules
155
+ # ========================================================================
156
+ from superlocalmemory.server.routes.memories import router as memories_router
157
+ from superlocalmemory.server.routes.stats import router as stats_router
158
+ from superlocalmemory.server.routes.profiles import router as profiles_router
159
+ from superlocalmemory.server.routes.backup import router as backup_router
160
+ from superlocalmemory.server.routes.data_io import router as data_io_router
161
+ from superlocalmemory.server.routes.events import router as events_router, register_event_listener
162
+ from superlocalmemory.server.routes.agents import router as agents_router
163
+ from superlocalmemory.server.routes.ws import router as ws_router, manager as ws_manager
164
+ from superlocalmemory.server.routes.v3_api import router as v3_router
165
+
166
+ application.include_router(memories_router)
167
+ application.include_router(stats_router)
168
+ application.include_router(profiles_router)
169
+ application.include_router(backup_router)
170
+ application.include_router(data_io_router)
171
+ application.include_router(events_router)
172
+ application.include_router(agents_router)
173
+ application.include_router(ws_router)
174
+ application.include_router(v3_router)
175
+
176
+ # Graceful optional routers
177
+ for _module_name in ("learning", "lifecycle", "behavioral", "compliance"):
178
+ try:
179
+ _mod = __import__(f"superlocalmemory.server.routes.{_module_name}", fromlist=["router"])
180
+ application.include_router(_mod.router)
181
+ except (ImportError, Exception):
182
+ pass
183
+
184
+ # Wire WebSocket manager
185
+ import superlocalmemory.server.routes.profiles as _profiles_mod
186
+ import superlocalmemory.server.routes.data_io as _data_io_mod
187
+ _profiles_mod.ws_manager = ws_manager
188
+ _data_io_mod.ws_manager = ws_manager
189
+
190
+ # ========================================================================
191
+ # Basic Routes
192
+ # ========================================================================
193
+
194
+ @application.get("/", response_class=HTMLResponse)
195
+ async def root():
196
+ """Serve main UI page."""
197
+ index_path = UI_DIR / "index.html"
198
+ if not index_path.exists():
199
+ return (
200
+ "<html><head><title>SuperLocalMemory V3</title></head>"
201
+ "<body style='font-family:Arial;padding:40px'>"
202
+ "<h1>SuperLocalMemory V3 API Server Running</h1>"
203
+ "<p><a href='/docs'>API Documentation</a></p>"
204
+ "</body></html>"
205
+ )
206
+ return index_path.read_text()
207
+
208
+ @application.get("/health")
209
+ async def health_check():
210
+ """Health check."""
211
+ from datetime import datetime
212
+ engine = application.state.engine
213
+ return {
214
+ "status": "healthy",
215
+ "version": "3.0.0",
216
+ "engine": "initialized" if engine else "unavailable",
217
+ "database": "connected" if DB_PATH.exists() else "missing",
218
+ "timestamp": datetime.now().isoformat(),
219
+ }
220
+
221
+ @application.on_event("startup")
222
+ async def startup_event():
223
+ register_event_listener()
224
+
225
+ return application
226
+
227
+
228
+ app = create_app()
229
+
230
+
231
+ # ============================================================================
232
+ # Server Startup
233
+ # ============================================================================
234
+
235
+ if __name__ == "__main__":
236
+ print("=" * 60)
237
+ print("SuperLocalMemory V3 - API Server")
238
+ print("=" * 60)
239
+ print(f"Database: {DB_PATH}")
240
+ print(f"UI Directory: {UI_DIR}")
241
+ print("=" * 60)
242
+ print("\nStarting server on http://localhost:8000")
243
+ print("API Documentation: http://localhost:8000/docs")
244
+ print("\nPress Ctrl+C to stop\n")
245
+
246
+ uvicorn.run(
247
+ app, host="127.0.0.1", port=8000, log_level="info",
248
+ )
@@ -0,0 +1,4 @@
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
+ # SuperLocalMemory V3 - API Routes Package
@@ -0,0 +1,107 @@
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
+ """SuperLocalMemory V3 - Agent Registry + Trust Routes
5
+ - MIT License
6
+
7
+ Routes: /api/agents, /api/agents/stats, /api/trust/stats, /api/trust/signals/{agent_id}
8
+ Uses V3 TrustScorer and core.registry.
9
+ """
10
+ import logging
11
+ from typing import Optional
12
+
13
+ from fastapi import APIRouter, HTTPException, Query, Request
14
+
15
+ from .helpers import DB_PATH
16
+
17
+ logger = logging.getLogger("superlocalmemory.routes.agents")
18
+ router = APIRouter()
19
+
20
+ # Feature flag: V3 trust scorer
21
+ TRUST_AVAILABLE = False
22
+ try:
23
+ from superlocalmemory.trust.scorer import TrustScorer
24
+ TRUST_AVAILABLE = True
25
+ except ImportError:
26
+ pass
27
+
28
+ REGISTRY_AVAILABLE = False
29
+ try:
30
+ from superlocalmemory.core.registry import AgentRegistry
31
+ REGISTRY_AVAILABLE = True
32
+ except ImportError:
33
+ pass
34
+
35
+
36
+ @router.get("/api/agents")
37
+ async def get_agents(
38
+ request: Request,
39
+ protocol: Optional[str] = None,
40
+ limit: int = Query(50, ge=1, le=200),
41
+ ):
42
+ """List registered agents with optional protocol filter."""
43
+ if not REGISTRY_AVAILABLE:
44
+ return {"agents": [], "count": 0, "message": "Agent registry not available"}
45
+ try:
46
+ engine = getattr(request.app.state, "engine", None)
47
+ if engine and hasattr(engine, '_db'):
48
+ registry = AgentRegistry(engine._db)
49
+ agents = registry.list_agents(protocol=protocol, limit=limit)
50
+ stats = registry.get_stats()
51
+ return {"agents": agents, "count": len(agents), "stats": stats}
52
+ return {"agents": [], "count": 0, "message": "Engine not initialized"}
53
+ except Exception as e:
54
+ raise HTTPException(status_code=500, detail=f"Agent registry error: {str(e)}")
55
+
56
+
57
+ @router.get("/api/agents/stats")
58
+ async def get_agent_stats(request: Request):
59
+ """Get agent registry statistics."""
60
+ if not REGISTRY_AVAILABLE:
61
+ return {"total_agents": 0, "message": "Agent registry not available"}
62
+ try:
63
+ engine = getattr(request.app.state, "engine", None)
64
+ if engine and hasattr(engine, '_db'):
65
+ registry = AgentRegistry(engine._db)
66
+ return registry.get_stats()
67
+ return {"total_agents": 0, "message": "Engine not initialized"}
68
+ except Exception as e:
69
+ raise HTTPException(status_code=500, detail=f"Agent stats error: {str(e)}")
70
+
71
+
72
+ @router.get("/api/trust/stats")
73
+ async def get_trust_stats(request: Request):
74
+ """Get trust scoring statistics."""
75
+ if not TRUST_AVAILABLE:
76
+ return {"total_signals": 0, "message": "Trust scorer not available"}
77
+ try:
78
+ engine = getattr(request.app.state, "engine", None)
79
+ if engine and engine._trust_scorer:
80
+ scorer = engine._trust_scorer
81
+ return scorer.get_trust_stats()
82
+ return {"total_signals": 0, "message": "Trust scorer not initialized"}
83
+ except Exception as e:
84
+ raise HTTPException(status_code=500, detail=f"Trust stats error: {str(e)}")
85
+
86
+
87
+ @router.get("/api/trust/signals/{agent_id}")
88
+ async def get_agent_trust_signals(
89
+ request: Request, agent_id: str,
90
+ limit: int = Query(50, ge=1, le=200),
91
+ ):
92
+ """Get trust signal history for a specific agent."""
93
+ if not TRUST_AVAILABLE:
94
+ return {"signals": [], "count": 0}
95
+ try:
96
+ engine = getattr(request.app.state, "engine", None)
97
+ if engine and engine._trust_scorer:
98
+ scorer = engine._trust_scorer
99
+ signals = scorer.get_signals(agent_id, limit=limit)
100
+ score = scorer.get_trust_score(agent_id)
101
+ return {
102
+ "agent_id": agent_id, "trust_score": score,
103
+ "signals": signals, "count": len(signals),
104
+ }
105
+ return {"agent_id": agent_id, "signals": [], "count": 0}
106
+ except Exception as e:
107
+ raise HTTPException(status_code=500, detail=f"Trust signals error: {str(e)}")
@@ -0,0 +1,91 @@
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
+ """SuperLocalMemory V3 - Backup Routes
5
+ - MIT License
6
+
7
+ Routes: /api/backup/status, /api/backup/create, /api/backup/configure, /api/backup/list
8
+ Uses V3 infra.backup.BackupManager.
9
+ """
10
+ import logging
11
+
12
+ from fastapi import APIRouter, HTTPException
13
+
14
+ from .helpers import BackupConfigRequest, DB_PATH, MEMORY_DIR
15
+
16
+ logger = logging.getLogger("superlocalmemory.routes.backup")
17
+ router = APIRouter()
18
+
19
+ # Feature flag
20
+ BACKUP_AVAILABLE = False
21
+ try:
22
+ from superlocalmemory.infra.backup import BackupManager
23
+ BACKUP_AVAILABLE = True
24
+ except ImportError:
25
+ pass
26
+
27
+
28
+ def _get_backup_manager() -> "BackupManager":
29
+ """Get V3 backup manager instance."""
30
+ return BackupManager(db_path=DB_PATH, base_dir=MEMORY_DIR)
31
+
32
+
33
+ @router.get("/api/backup/status")
34
+ async def backup_status():
35
+ """Get auto-backup system status."""
36
+ if not BACKUP_AVAILABLE:
37
+ return {"status": "not_implemented", "message": "Backup module not available"}
38
+ try:
39
+ manager = _get_backup_manager()
40
+ return manager.get_status()
41
+ except Exception as e:
42
+ raise HTTPException(status_code=500, detail=f"Backup status error: {str(e)}")
43
+
44
+
45
+ @router.post("/api/backup/create")
46
+ async def backup_create():
47
+ """Create a manual backup immediately."""
48
+ if not BACKUP_AVAILABLE:
49
+ return {"success": False, "message": "Backup module not available"}
50
+ try:
51
+ manager = _get_backup_manager()
52
+ filename = manager.create_backup(label='manual')
53
+ if filename:
54
+ return {
55
+ "success": True, "filename": str(filename),
56
+ "message": f"Backup created: {filename}",
57
+ "status": manager.get_status(),
58
+ }
59
+ return {"success": False, "message": "Backup failed"}
60
+ except Exception as e:
61
+ raise HTTPException(status_code=500, detail=f"Backup create error: {str(e)}")
62
+
63
+
64
+ @router.post("/api/backup/configure")
65
+ async def backup_configure(request: BackupConfigRequest):
66
+ """Update auto-backup configuration."""
67
+ if not BACKUP_AVAILABLE:
68
+ return {"success": False, "message": "Backup module not available"}
69
+ try:
70
+ manager = _get_backup_manager()
71
+ result = manager.configure(
72
+ interval_hours=request.interval_hours,
73
+ max_backups=request.max_backups,
74
+ enabled=request.enabled,
75
+ )
76
+ return {"success": True, "message": "Backup configuration updated", "status": result}
77
+ except Exception as e:
78
+ raise HTTPException(status_code=500, detail=f"Backup configure error: {str(e)}")
79
+
80
+
81
+ @router.get("/api/backup/list")
82
+ async def backup_list():
83
+ """List all available backups."""
84
+ if not BACKUP_AVAILABLE:
85
+ return {"backups": [], "count": 0, "message": "Backup module not available"}
86
+ try:
87
+ manager = _get_backup_manager()
88
+ backups = manager.list_backups()
89
+ return {"backups": backups, "count": len(backups)}
90
+ except Exception as e:
91
+ raise HTTPException(status_code=500, detail=f"Backup list error: {str(e)}")
@@ -0,0 +1,127 @@
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
+ """SuperLocalMemory V3 - Behavioral Routes
5
+ - MIT License
6
+
7
+ Routes: /api/behavioral/status, /api/behavioral/report-outcome
8
+ Uses V3 learning.behavioral.BehavioralPatternStore and learning.outcomes.OutcomeTracker.
9
+ """
10
+ import json
11
+ import logging
12
+
13
+ from fastapi import APIRouter
14
+
15
+ from .helpers import get_active_profile, MEMORY_DIR
16
+
17
+ logger = logging.getLogger("superlocalmemory.routes.behavioral")
18
+ router = APIRouter()
19
+
20
+ LEARNING_DB = MEMORY_DIR / "learning.db"
21
+
22
+ # Feature detection
23
+ BEHAVIORAL_AVAILABLE = False
24
+ try:
25
+ from superlocalmemory.learning.behavioral import BehavioralPatternStore
26
+ from superlocalmemory.learning.outcomes import OutcomeTracker
27
+ BEHAVIORAL_AVAILABLE = True
28
+ except ImportError:
29
+ logger.info("V3 behavioral engine not available")
30
+
31
+
32
+ @router.get("/api/behavioral/status")
33
+ async def behavioral_status():
34
+ """Get behavioral learning status for active profile."""
35
+ if not BEHAVIORAL_AVAILABLE:
36
+ return {"available": False, "message": "Behavioral engine not available"}
37
+
38
+ try:
39
+ profile = get_active_profile()
40
+ db_path = str(LEARNING_DB)
41
+
42
+ # Outcomes
43
+ total_outcomes = 0
44
+ outcome_breakdown = {"success": 0, "failure": 0, "partial": 0}
45
+ recent_outcomes = []
46
+ try:
47
+ tracker = OutcomeTracker(db_path)
48
+ total_outcomes = tracker.get_outcome_count(profile=profile)
49
+ outcome_breakdown = tracker.get_outcome_breakdown(profile=profile)
50
+ recent_outcomes = tracker.get_recent_outcomes(profile=profile, limit=20)
51
+ except Exception as exc:
52
+ logger.debug("outcome tracker: %s", exc)
53
+
54
+ # Patterns
55
+ patterns = []
56
+ cross_project_transfers = 0
57
+ try:
58
+ store = BehavioralPatternStore(db_path)
59
+ patterns = store.get_patterns(profile=profile)
60
+ cross_project_transfers = store.get_cross_project_count(profile=profile)
61
+ except Exception as exc:
62
+ logger.debug("pattern store: %s", exc)
63
+
64
+ return {
65
+ "available": True,
66
+ "active_profile": profile,
67
+ "total_outcomes": total_outcomes,
68
+ "outcome_breakdown": outcome_breakdown,
69
+ "patterns": patterns,
70
+ "cross_project_transfers": cross_project_transfers,
71
+ "recent_outcomes": recent_outcomes,
72
+ }
73
+ except Exception as e:
74
+ logger.error("behavioral_status error: %s", e)
75
+ return {"available": False, "error": str(e)}
76
+
77
+
78
+ @router.post("/api/behavioral/report-outcome")
79
+ async def report_outcome(data: dict):
80
+ """Record an action outcome for behavioral learning.
81
+
82
+ Body: {
83
+ memory_ids: [str, ...],
84
+ outcome: "success" | "failure" | "partial",
85
+ action_type: str (optional),
86
+ context: str (optional)
87
+ }
88
+ """
89
+ if not BEHAVIORAL_AVAILABLE:
90
+ return {"success": False, "error": "Behavioral engine not available"}
91
+
92
+ memory_ids = data.get('memory_ids')
93
+ outcome = data.get('outcome')
94
+ action_type = data.get('action_type', 'other')
95
+ context_note = data.get('context', '')
96
+
97
+ if not memory_ids or not isinstance(memory_ids, list):
98
+ return {"success": False, "error": "memory_ids must be a non-empty list"}
99
+
100
+ valid_outcomes = ("success", "failure", "partial")
101
+ if outcome not in valid_outcomes:
102
+ return {"success": False, "error": f"outcome must be one of: {valid_outcomes}"}
103
+
104
+ try:
105
+ profile = get_active_profile()
106
+ tracker = OutcomeTracker(str(LEARNING_DB))
107
+
108
+ context_dict = {"note": context_note} if context_note else {}
109
+ row_id = tracker.record_outcome(
110
+ memory_ids=memory_ids,
111
+ outcome=outcome,
112
+ action_type=action_type,
113
+ context=context_dict,
114
+ project=profile,
115
+ )
116
+
117
+ if row_id is None:
118
+ return {"success": False, "error": "Failed to record outcome"}
119
+
120
+ return {
121
+ "success": True, "outcome_id": row_id,
122
+ "active_profile": profile,
123
+ "message": f"Recorded {outcome} outcome for {len(memory_ids)} memories",
124
+ }
125
+ except Exception as e:
126
+ logger.error("report_outcome error: %s", e)
127
+ return {"success": False, "error": str(e)}