superlocalmemory 3.4.5 → 3.4.8

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 (232) hide show
  1. package/ide/hooks/tool-event-hook.sh +46 -0
  2. package/package.json +1 -1
  3. package/pyproject.toml +1 -1
  4. package/src/superlocalmemory/attribution/mathematical_dna.py +1 -1
  5. package/src/superlocalmemory/attribution/signer.py +1 -1
  6. package/src/superlocalmemory/attribution/watermark.py +1 -1
  7. package/src/superlocalmemory/cli/__init__.py +1 -1
  8. package/src/superlocalmemory/cli/commands.py +9 -1
  9. package/src/superlocalmemory/cli/daemon.py +57 -27
  10. package/src/superlocalmemory/cli/ingest_cmd.py +261 -0
  11. package/src/superlocalmemory/cli/json_output.py +1 -1
  12. package/src/superlocalmemory/cli/main.py +21 -1
  13. package/src/superlocalmemory/cli/migrate_cmd.py +1 -1
  14. package/src/superlocalmemory/cli/pending_store.py +1 -1
  15. package/src/superlocalmemory/cli/post_install.py +1 -1
  16. package/src/superlocalmemory/cli/service_installer.py +1 -1
  17. package/src/superlocalmemory/cli/setup_wizard.py +1 -1
  18. package/src/superlocalmemory/code_graph/__init__.py +1 -1
  19. package/src/superlocalmemory/code_graph/blast_radius.py +1 -1
  20. package/src/superlocalmemory/code_graph/bridge/__init__.py +1 -1
  21. package/src/superlocalmemory/code_graph/bridge/entity_resolver.py +1 -1
  22. package/src/superlocalmemory/code_graph/bridge/event_listeners.py +1 -1
  23. package/src/superlocalmemory/code_graph/bridge/fact_enricher.py +1 -1
  24. package/src/superlocalmemory/code_graph/bridge/hebbian_linker.py +1 -1
  25. package/src/superlocalmemory/code_graph/bridge/temporal_checker.py +1 -1
  26. package/src/superlocalmemory/code_graph/changes.py +1 -1
  27. package/src/superlocalmemory/code_graph/communities.py +1 -1
  28. package/src/superlocalmemory/code_graph/config.py +1 -1
  29. package/src/superlocalmemory/code_graph/database.py +1 -1
  30. package/src/superlocalmemory/code_graph/extractors/__init__.py +1 -1
  31. package/src/superlocalmemory/code_graph/extractors/python.py +1 -1
  32. package/src/superlocalmemory/code_graph/extractors/typescript.py +1 -1
  33. package/src/superlocalmemory/code_graph/flows.py +1 -1
  34. package/src/superlocalmemory/code_graph/git_hooks.py +1 -1
  35. package/src/superlocalmemory/code_graph/graph_engine.py +1 -1
  36. package/src/superlocalmemory/code_graph/graph_store.py +1 -1
  37. package/src/superlocalmemory/code_graph/incremental.py +1 -1
  38. package/src/superlocalmemory/code_graph/models.py +1 -1
  39. package/src/superlocalmemory/code_graph/parser.py +1 -1
  40. package/src/superlocalmemory/code_graph/resolver.py +1 -1
  41. package/src/superlocalmemory/code_graph/search.py +1 -1
  42. package/src/superlocalmemory/code_graph/service.py +1 -1
  43. package/src/superlocalmemory/code_graph/watcher.py +1 -1
  44. package/src/superlocalmemory/compliance/abac.py +1 -1
  45. package/src/superlocalmemory/compliance/audit.py +1 -1
  46. package/src/superlocalmemory/compliance/eu_ai_act.py +1 -1
  47. package/src/superlocalmemory/compliance/gdpr.py +1 -1
  48. package/src/superlocalmemory/compliance/lifecycle.py +1 -1
  49. package/src/superlocalmemory/compliance/retention.py +1 -1
  50. package/src/superlocalmemory/compliance/scheduler.py +1 -1
  51. package/src/superlocalmemory/core/config.py +1 -1
  52. package/src/superlocalmemory/core/consolidation_engine.py +52 -1
  53. package/src/superlocalmemory/core/embedding_worker.py +1 -1
  54. package/src/superlocalmemory/core/embeddings.py +1 -1
  55. package/src/superlocalmemory/core/engine.py +17 -1
  56. package/src/superlocalmemory/core/engine_wiring.py +21 -1
  57. package/src/superlocalmemory/core/graph_analyzer.py +15 -1
  58. package/src/superlocalmemory/core/health_monitor.py +1 -1
  59. package/src/superlocalmemory/core/hooks.py +1 -1
  60. package/src/superlocalmemory/core/maintenance.py +1 -1
  61. package/src/superlocalmemory/core/maintenance_scheduler.py +1 -1
  62. package/src/superlocalmemory/core/modes.py +1 -1
  63. package/src/superlocalmemory/core/ollama_embedder.py +1 -1
  64. package/src/superlocalmemory/core/profiles.py +1 -1
  65. package/src/superlocalmemory/core/recall_pipeline.py +16 -3
  66. package/src/superlocalmemory/core/recall_worker.py +1 -1
  67. package/src/superlocalmemory/core/registry.py +1 -1
  68. package/src/superlocalmemory/core/reranker_worker.py +1 -1
  69. package/src/superlocalmemory/core/store_pipeline.py +1 -1
  70. package/src/superlocalmemory/core/summarizer.py +1 -1
  71. package/src/superlocalmemory/core/worker_pool.py +1 -1
  72. package/src/superlocalmemory/dynamics/activation_guided_quantization.py +1 -1
  73. package/src/superlocalmemory/dynamics/eap_scheduler.py +1 -1
  74. package/src/superlocalmemory/dynamics/ebbinghaus_langevin_coupling.py +1 -1
  75. package/src/superlocalmemory/dynamics/fisher_langevin_coupling.py +1 -1
  76. package/src/superlocalmemory/encoding/auto_linker.py +1 -1
  77. package/src/superlocalmemory/encoding/cognitive_consolidator.py +1 -1
  78. package/src/superlocalmemory/encoding/consolidator.py +1 -1
  79. package/src/superlocalmemory/encoding/context_generator.py +1 -1
  80. package/src/superlocalmemory/encoding/emotional.py +1 -1
  81. package/src/superlocalmemory/encoding/entity_resolver.py +45 -6
  82. package/src/superlocalmemory/encoding/entropy_gate.py +1 -1
  83. package/src/superlocalmemory/encoding/fact_extractor.py +1 -1
  84. package/src/superlocalmemory/encoding/foresight.py +1 -1
  85. package/src/superlocalmemory/encoding/graph_builder.py +1 -1
  86. package/src/superlocalmemory/encoding/observation_builder.py +1 -1
  87. package/src/superlocalmemory/encoding/scene_builder.py +1 -1
  88. package/src/superlocalmemory/encoding/signal_inference.py +1 -1
  89. package/src/superlocalmemory/encoding/temporal_parser.py +1 -1
  90. package/src/superlocalmemory/encoding/temporal_validator.py +1 -1
  91. package/src/superlocalmemory/encoding/type_router.py +1 -1
  92. package/src/superlocalmemory/hooks/__init__.py +1 -1
  93. package/src/superlocalmemory/hooks/auto_capture.py +1 -1
  94. package/src/superlocalmemory/hooks/auto_invoker.py +1 -1
  95. package/src/superlocalmemory/hooks/auto_parameterize.py +1 -1
  96. package/src/superlocalmemory/hooks/auto_recall.py +1 -1
  97. package/src/superlocalmemory/hooks/claude_code_hooks.py +1 -1
  98. package/src/superlocalmemory/hooks/hook_handlers.py +1 -1
  99. package/src/superlocalmemory/hooks/ide_connector.py +1 -1
  100. package/src/superlocalmemory/hooks/rules_engine.py +1 -1
  101. package/src/superlocalmemory/infra/__init__.py +1 -1
  102. package/src/superlocalmemory/infra/auth_middleware.py +1 -1
  103. package/src/superlocalmemory/infra/backup.py +1 -1
  104. package/src/superlocalmemory/infra/cache_manager.py +1 -1
  105. package/src/superlocalmemory/infra/event_bus.py +1 -1
  106. package/src/superlocalmemory/infra/heartbeat_monitor.py +1 -1
  107. package/src/superlocalmemory/infra/pid_manager.py +1 -1
  108. package/src/superlocalmemory/infra/process_reaper.py +1 -1
  109. package/src/superlocalmemory/infra/rate_limiter.py +1 -1
  110. package/src/superlocalmemory/infra/webhook_dispatcher.py +1 -1
  111. package/src/superlocalmemory/ingestion/__init__.py +1 -1
  112. package/src/superlocalmemory/ingestion/adapter_manager.py +1 -1
  113. package/src/superlocalmemory/ingestion/base_adapter.py +1 -1
  114. package/src/superlocalmemory/ingestion/calendar_adapter.py +1 -1
  115. package/src/superlocalmemory/ingestion/credentials.py +1 -1
  116. package/src/superlocalmemory/ingestion/gmail_adapter.py +1 -1
  117. package/src/superlocalmemory/ingestion/parsers.py +1 -1
  118. package/src/superlocalmemory/ingestion/transcript_adapter.py +1 -1
  119. package/src/superlocalmemory/learning/adaptive.py +1 -1
  120. package/src/superlocalmemory/learning/assertion_miner.py +403 -0
  121. package/src/superlocalmemory/learning/behavioral.py +1 -1
  122. package/src/superlocalmemory/learning/behavioral_listener.py +1 -1
  123. package/src/superlocalmemory/learning/bootstrap.py +1 -1
  124. package/src/superlocalmemory/learning/consolidation_quantization_worker.py +1 -1
  125. package/src/superlocalmemory/learning/consolidation_worker.py +25 -9
  126. package/src/superlocalmemory/learning/cross_project.py +1 -1
  127. package/src/superlocalmemory/learning/database.py +1 -1
  128. package/src/superlocalmemory/learning/engagement.py +2 -3
  129. package/src/superlocalmemory/learning/entity_compiler.py +1 -1
  130. package/src/superlocalmemory/learning/features.py +1 -1
  131. package/src/superlocalmemory/learning/forgetting_scheduler.py +1 -1
  132. package/src/superlocalmemory/learning/outcomes.py +1 -1
  133. package/src/superlocalmemory/learning/project_context.py +1 -1
  134. package/src/superlocalmemory/learning/quantization_scheduler.py +1 -1
  135. package/src/superlocalmemory/learning/ranker.py +1 -1
  136. package/src/superlocalmemory/learning/signals.py +1 -1
  137. package/src/superlocalmemory/learning/workflows.py +1 -1
  138. package/src/superlocalmemory/llm/backbone.py +1 -1
  139. package/src/superlocalmemory/math/ebbinghaus.py +1 -1
  140. package/src/superlocalmemory/math/fisher.py +1 -1
  141. package/src/superlocalmemory/math/fisher_quantized.py +1 -1
  142. package/src/superlocalmemory/math/hopfield.py +1 -1
  143. package/src/superlocalmemory/math/langevin.py +1 -1
  144. package/src/superlocalmemory/math/polar_quant.py +1 -1
  145. package/src/superlocalmemory/math/qjl.py +1 -1
  146. package/src/superlocalmemory/math/sheaf.py +1 -1
  147. package/src/superlocalmemory/math/turbo_quant.py +1 -1
  148. package/src/superlocalmemory/mcp/resources.py +1 -1
  149. package/src/superlocalmemory/mcp/server.py +17 -2
  150. package/src/superlocalmemory/mcp/shared.py +1 -1
  151. package/src/superlocalmemory/mcp/tools.py +1 -1
  152. package/src/superlocalmemory/mcp/tools_active.py +1 -1
  153. package/src/superlocalmemory/mcp/tools_code_graph.py +1 -1
  154. package/src/superlocalmemory/mcp/tools_core.py +1 -1
  155. package/src/superlocalmemory/mcp/tools_learning.py +221 -0
  156. package/src/superlocalmemory/mcp/tools_mesh.py +55 -12
  157. package/src/superlocalmemory/mcp/tools_v28.py +23 -1
  158. package/src/superlocalmemory/mcp/tools_v3.py +1 -1
  159. package/src/superlocalmemory/mcp/tools_v33.py +1 -1
  160. package/src/superlocalmemory/mesh/__init__.py +1 -1
  161. package/src/superlocalmemory/mesh/broker.py +194 -38
  162. package/src/superlocalmemory/parameterization/__init__.py +1 -1
  163. package/src/superlocalmemory/parameterization/pattern_extractor.py +35 -1
  164. package/src/superlocalmemory/parameterization/pii_filter.py +1 -1
  165. package/src/superlocalmemory/parameterization/prompt_injector.py +3 -2
  166. package/src/superlocalmemory/parameterization/prompt_lifecycle.py +1 -1
  167. package/src/superlocalmemory/parameterization/soft_prompt_generator.py +7 -1
  168. package/src/superlocalmemory/retrieval/agentic.py +1 -1
  169. package/src/superlocalmemory/retrieval/ann_index.py +1 -1
  170. package/src/superlocalmemory/retrieval/bm25_channel.py +1 -1
  171. package/src/superlocalmemory/retrieval/bridge_discovery.py +1 -1
  172. package/src/superlocalmemory/retrieval/channel_registry.py +1 -1
  173. package/src/superlocalmemory/retrieval/engine.py +1 -1
  174. package/src/superlocalmemory/retrieval/entity_channel.py +1 -1
  175. package/src/superlocalmemory/retrieval/forgetting_filter.py +1 -1
  176. package/src/superlocalmemory/retrieval/fusion.py +1 -1
  177. package/src/superlocalmemory/retrieval/hopfield_channel.py +1 -1
  178. package/src/superlocalmemory/retrieval/profile_channel.py +1 -1
  179. package/src/superlocalmemory/retrieval/quantization_aware_search.py +1 -1
  180. package/src/superlocalmemory/retrieval/reranker.py +1 -1
  181. package/src/superlocalmemory/retrieval/semantic_channel.py +1 -1
  182. package/src/superlocalmemory/retrieval/spreading_activation.py +1 -1
  183. package/src/superlocalmemory/retrieval/strategy.py +1 -1
  184. package/src/superlocalmemory/retrieval/temporal_channel.py +1 -1
  185. package/src/superlocalmemory/retrieval/vector_store.py +1 -1
  186. package/src/superlocalmemory/server/api.py +1 -1
  187. package/src/superlocalmemory/server/routes/__init__.py +1 -1
  188. package/src/superlocalmemory/server/routes/adapters.py +1 -1
  189. package/src/superlocalmemory/server/routes/agents.py +2 -2
  190. package/src/superlocalmemory/server/routes/backup.py +2 -2
  191. package/src/superlocalmemory/server/routes/behavioral.py +129 -2
  192. package/src/superlocalmemory/server/routes/compliance.py +2 -2
  193. package/src/superlocalmemory/server/routes/data_io.py +2 -2
  194. package/src/superlocalmemory/server/routes/entity.py +1 -1
  195. package/src/superlocalmemory/server/routes/events.py +2 -2
  196. package/src/superlocalmemory/server/routes/helpers.py +2 -2
  197. package/src/superlocalmemory/server/routes/ingest.py +1 -1
  198. package/src/superlocalmemory/server/routes/learning.py +22 -5
  199. package/src/superlocalmemory/server/routes/lifecycle.py +2 -2
  200. package/src/superlocalmemory/server/routes/memories.py +2 -2
  201. package/src/superlocalmemory/server/routes/mesh.py +25 -7
  202. package/src/superlocalmemory/server/routes/profiles.py +2 -2
  203. package/src/superlocalmemory/server/routes/stats.py +26 -7
  204. package/src/superlocalmemory/server/routes/v3_api.py +1 -1
  205. package/src/superlocalmemory/server/routes/ws.py +2 -2
  206. package/src/superlocalmemory/server/ui.py +1 -1
  207. package/src/superlocalmemory/server/unified_daemon.py +42 -1
  208. package/src/superlocalmemory/storage/access_control.py +1 -1
  209. package/src/superlocalmemory/storage/access_log.py +1 -1
  210. package/src/superlocalmemory/storage/database.py +1 -1
  211. package/src/superlocalmemory/storage/embedding_migrator.py +1 -1
  212. package/src/superlocalmemory/storage/migration_v33.py +1 -1
  213. package/src/superlocalmemory/storage/migrations.py +1 -1
  214. package/src/superlocalmemory/storage/models.py +1 -1
  215. package/src/superlocalmemory/storage/quantized_store.py +1 -1
  216. package/src/superlocalmemory/storage/schema.py +1 -1
  217. package/src/superlocalmemory/storage/schema_code_graph.py +1 -1
  218. package/src/superlocalmemory/storage/schema_v32.py +1 -1
  219. package/src/superlocalmemory/storage/schema_v343.py +75 -1
  220. package/src/superlocalmemory/storage/schema_v347.py +136 -0
  221. package/src/superlocalmemory/storage/v2_migrator.py +1 -1
  222. package/src/superlocalmemory/trust/gate.py +1 -1
  223. package/src/superlocalmemory/trust/provenance.py +1 -1
  224. package/src/superlocalmemory/trust/scorer.py +1 -1
  225. package/src/superlocalmemory/trust/signals.py +1 -1
  226. package/src/superlocalmemory/ui/js/behavioral.js +174 -3
  227. package/src/superlocalmemory.egg-info/PKG-INFO +0 -601
  228. package/src/superlocalmemory.egg-info/SOURCES.txt +0 -313
  229. package/src/superlocalmemory.egg-info/dependency_links.txt +0 -1
  230. package/src/superlocalmemory.egg-info/entry_points.txt +0 -2
  231. package/src/superlocalmemory.egg-info/requires.txt +0 -55
  232. package/src/superlocalmemory.egg-info/top_level.txt +0 -1
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
- # Licensed under the Elastic License 2.0 - see LICENSE file
2
+ # Licensed under AGPL-3.0-or-later - see LICENSE file
3
3
  # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
4
 
5
5
  """Riemannian Langevin dynamics with persistence for memory lifecycle.
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
- # Licensed under the Elastic License 2.0 - see LICENSE file
2
+ # Licensed under AGPL-3.0-or-later - see LICENSE file
3
3
  # Part of SuperLocalMemory V3
4
4
 
5
5
  """PolarQuant embedding quantization.
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
- # Licensed under the Elastic License 2.0 - see LICENSE file
2
+ # Licensed under AGPL-3.0-or-later - see LICENSE file
3
3
  # Part of SuperLocalMemory V3
4
4
 
5
5
  """QJL (Quantized Johnson-Lindenstrauss) 1-bit residual correction.
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
- # Licensed under the Elastic License 2.0 - see LICENSE file
2
+ # Licensed under AGPL-3.0-or-later - see LICENSE file
3
3
  # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
4
 
5
5
  """Sheaf cohomology for contradiction detection at ENCODING time.
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
- # Licensed under the Elastic License 2.0 - see LICENSE file
2
+ # Licensed under AGPL-3.0-or-later - see LICENSE file
3
3
  # Part of SuperLocalMemory V3
4
4
 
5
5
  """TurboQuant embedding quantization (ICLR 2026).
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
- # Licensed under the Elastic License 2.0 - see LICENSE file
2
+ # Licensed under AGPL-3.0-or-later - see LICENSE file
3
3
  # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
4
 
5
5
  """SuperLocalMemory V3 — MCP Resources (6 resources).
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
- # Licensed under the Elastic License 2.0 - see LICENSE file
2
+ # Licensed under AGPL-3.0-or-later - see LICENSE file
3
3
  # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
4
 
5
5
  """SuperLocalMemory V3 — MCP Server.
@@ -76,6 +76,9 @@ _ESSENTIAL_TOOLS: set[str] = {
76
76
  # Infinite memory + learning (4)
77
77
  "consolidate_cognitive", "get_soft_prompts",
78
78
  "set_mode", "report_outcome",
79
+ # v3.4.7: Two-way learning (4)
80
+ "log_tool_event", "get_assertions",
81
+ "reinforce_assertion", "contradict_assertion",
79
82
  }
80
83
 
81
84
  # v3.4.4: Mesh tools — enabled if mesh_enabled in config or SLM_MCP_MESH_TOOLS=1
@@ -134,6 +137,7 @@ from superlocalmemory.mcp.tools_v33 import register_v33_tools
134
137
  from superlocalmemory.mcp.resources import register_resources
135
138
  from superlocalmemory.mcp.tools_code_graph import register_code_graph_tools
136
139
  from superlocalmemory.mcp.tools_mesh import register_mesh_tools
140
+ from superlocalmemory.mcp.tools_learning import register_learning_tools
137
141
 
138
142
  register_core_tools(_target, get_engine)
139
143
  register_v28_tools(_target, get_engine)
@@ -143,6 +147,7 @@ register_v33_tools(_target, get_engine)
143
147
  register_resources(server, get_engine) # Resources always registered (not tools)
144
148
  register_code_graph_tools(_target, get_engine) # CodeGraph: filtered like other tools (SLM_MCP_ALL_TOOLS=1 to show all)
145
149
  register_mesh_tools(_target, get_engine) # v3.4.4: Mesh P2P tools — ships with SLM, no separate slm-mesh needed
150
+ register_learning_tools(_target, get_engine) # v3.4.7: Two-way learning tools
146
151
 
147
152
 
148
153
  # V3.3.21: Eager engine warmup — start initializing BEFORE first tool call.
@@ -152,7 +157,7 @@ register_mesh_tools(_target, get_engine) # v3.4.4: Mesh P2P tools — ships wit
152
157
  # the first tool call arrives (1-2s later), the engine is already warm.
153
158
  # This applies to ALL IDEs: Claude Code, Cursor, Antigravity, Gemini CLI, etc.
154
159
  def _eager_warmup() -> None:
155
- """Pre-warm engine + ensure daemon is running (background thread)."""
160
+ """Pre-warm engine + ensure daemon is running + auto-register mesh (background thread)."""
156
161
  import logging
157
162
  _logger = logging.getLogger(__name__)
158
163
  try:
@@ -170,6 +175,16 @@ def _eager_warmup() -> None:
170
175
  except Exception as exc:
171
176
  _logger.debug("Daemon auto-start failed (non-fatal): %s", exc)
172
177
 
178
+ # V3.4.6: Auto-register this MCP session as a mesh peer immediately.
179
+ # Previously, registration was lazy (only on first mesh tool call).
180
+ # Now every Claude session appears on the mesh from startup.
181
+ try:
182
+ from superlocalmemory.mcp.tools_mesh import auto_register_mesh
183
+ auto_register_mesh()
184
+ _logger.info("Mesh peer auto-registered at startup")
185
+ except Exception as exc:
186
+ _logger.debug("Mesh auto-register failed (non-fatal): %s", exc)
187
+
173
188
  import threading
174
189
  _warmup_thread = threading.Thread(target=_eager_warmup, daemon=True, name="mcp-warmup")
175
190
  _warmup_thread.start()
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
- # Licensed under the Elastic License 2.0 - see LICENSE file
2
+ # Licensed under AGPL-3.0-or-later - see LICENSE file
3
3
  # Part of SuperLocalMemory V3
4
4
 
5
5
  """Shared MCP utilities — single source of truth for helpers used
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
- # Licensed under the Elastic License 2.0 - see LICENSE file
2
+ # Licensed under AGPL-3.0-or-later - see LICENSE file
3
3
  # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
4
 
5
5
  """Backward compatibility — tools are now split across sub-modules.
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
- # Licensed under the Elastic License 2.0 - see LICENSE file
2
+ # Licensed under AGPL-3.0-or-later - see LICENSE file
3
3
  # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
4
 
5
5
  """SuperLocalMemory V3.1 — Active Memory MCP Tools.
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
- # Licensed under the Elastic License 2.0 - see LICENSE file
2
+ # Licensed under AGPL-3.0-or-later - see LICENSE file
3
3
  # Part of SuperLocalMemory v3.4 — CodeGraph MCP Tools
4
4
 
5
5
  """22 MCP tools for CodeGraph: 17 graph + 5 bridge.
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
- # Licensed under the Elastic License 2.0 - see LICENSE file
2
+ # Licensed under AGPL-3.0-or-later - see LICENSE file
3
3
  # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
4
 
5
5
  """SuperLocalMemory V3 — Core MCP Tools (13 tools).
@@ -0,0 +1,221 @@
1
+ # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
+ # Licensed under AGPL-3.0-or-later - see LICENSE file
3
+ # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
+
5
+ """SLM v3.4.7 "The Learning Brain" — Learning MCP Tools.
6
+
7
+ Two-way learning tools:
8
+ - log_tool_event: Passive tool usage telemetry
9
+ - get_assertions: Retrieve behavioral assertions
10
+ - reinforce_assertion: Explicitly reinforce a learned pattern
11
+ - contradict_assertion: Mark a learned pattern as wrong
12
+
13
+ Part of Qualixar | Author: Varun Pratap Bhardwaj
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ import json
19
+ import logging
20
+ import os
21
+ import uuid
22
+ from datetime import datetime, timezone
23
+ from typing import Callable
24
+
25
+ logger = logging.getLogger(__name__)
26
+
27
+ _MAX_SUMMARY_LEN = 500 # Truncate input/output summaries
28
+
29
+
30
+ def register_learning_tools(server, get_engine: Callable) -> None:
31
+ """Register learning MCP tools for two-way intelligence."""
32
+
33
+ @server.tool()
34
+ async def log_tool_event(
35
+ tool_name: str,
36
+ event_type: str = "invoke",
37
+ input_summary: str = "",
38
+ output_summary: str = "",
39
+ duration_ms: int = 0,
40
+ metadata: str = "{}",
41
+ ) -> dict:
42
+ """Log a tool usage event for behavioral learning.
43
+
44
+ Passive telemetry — low overhead, no LLM calls.
45
+ Events feed into the behavioral assertion mining pipeline
46
+ during consolidation. Accessible via MCP, CLI, and hooks.
47
+
48
+ Args:
49
+ tool_name: Name of the tool (e.g. "Read", "Edit", "Bash")
50
+ event_type: One of 'invoke', 'complete', 'error', 'correction'
51
+ input_summary: Truncated input (max 500 chars, auto-scrubbed)
52
+ output_summary: Truncated output (max 500 chars, auto-scrubbed)
53
+ duration_ms: Execution time in milliseconds
54
+ metadata: JSON string with additional context
55
+ """
56
+ engine = get_engine()
57
+ now = datetime.now(timezone.utc).isoformat()
58
+ session_id = os.environ.get("CLAUDE_SESSION_ID", "unknown")
59
+ project_path = (
60
+ os.environ.get("CLAUDE_PROJECT_DIR")
61
+ or os.environ.get("PROJECT_PATH")
62
+ or os.getcwd()
63
+ )
64
+
65
+ # Scrub and truncate
66
+ input_clean = _scrub(input_summary[:_MAX_SUMMARY_LEN])
67
+ output_clean = _scrub(output_summary[:_MAX_SUMMARY_LEN])
68
+
69
+ try:
70
+ engine._db.execute(
71
+ "INSERT INTO tool_events "
72
+ "(session_id, profile_id, project_path, tool_name, event_type, "
73
+ " input_summary, output_summary, duration_ms, metadata, created_at) "
74
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
75
+ (session_id, engine.profile_id, project_path, tool_name,
76
+ event_type, input_clean, output_clean, duration_ms, metadata, now),
77
+ )
78
+ return {"success": True, "tool": tool_name, "event": event_type}
79
+ except Exception as exc:
80
+ logger.debug("log_tool_event failed: %s", exc)
81
+ return {"success": False, "error": str(exc)}
82
+
83
+ @server.tool()
84
+ async def get_assertions(
85
+ min_confidence: float = 0.0,
86
+ category: str = "",
87
+ project_path: str = "",
88
+ limit: int = 50,
89
+ ) -> dict:
90
+ """Get learned behavioral assertions.
91
+
92
+ Behavioral assertions are patterns SLM discovered from your usage:
93
+ trigger conditions paired with recommended actions, each with a
94
+ confidence score that evolves over time.
95
+
96
+ Args:
97
+ min_confidence: Minimum confidence threshold (0.0-1.0)
98
+ category: Filter by category (workflow, code_style, tool_preference, communication)
99
+ project_path: Filter by project (empty = all including global)
100
+ limit: Maximum results
101
+ """
102
+ engine = get_engine()
103
+ try:
104
+ query = (
105
+ "SELECT id, trigger_condition, action, category, confidence, "
106
+ "evidence_count, reinforcement_count, contradiction_count, "
107
+ "project_path, source, created_at, updated_at "
108
+ "FROM behavioral_assertions "
109
+ "WHERE profile_id = ? AND confidence >= ?"
110
+ )
111
+ params: list = [engine.profile_id, min_confidence]
112
+
113
+ if category:
114
+ query += " AND category = ?"
115
+ params.append(category)
116
+ if project_path:
117
+ query += " AND (project_path = ? OR project_path = '')"
118
+ params.append(project_path)
119
+
120
+ query += " ORDER BY confidence DESC LIMIT ?"
121
+ params.append(limit)
122
+
123
+ rows = engine._db.execute(query, tuple(params))
124
+ assertions = [dict(r) for r in rows]
125
+ return {
126
+ "assertions": assertions,
127
+ "count": len(assertions),
128
+ "min_confidence": min_confidence,
129
+ }
130
+ except Exception as exc:
131
+ logger.debug("get_assertions failed: %s", exc)
132
+ return {"assertions": [], "count": 0, "error": str(exc)}
133
+
134
+ @server.tool()
135
+ async def reinforce_assertion(assertion_id: str) -> dict:
136
+ """Reinforce a behavioral assertion (increase confidence).
137
+
138
+ Call this when an assertion's recommendation was helpful.
139
+ Confidence increases via Bayesian update toward 1.0.
140
+
141
+ Args:
142
+ assertion_id: The assertion ID to reinforce
143
+ """
144
+ engine = get_engine()
145
+ return _update_assertion_confidence(engine._db, assertion_id, reinforce=True)
146
+
147
+ @server.tool()
148
+ async def contradict_assertion(assertion_id: str) -> dict:
149
+ """Contradict a behavioral assertion (decrease confidence).
150
+
151
+ Call this when an assertion's recommendation was wrong.
152
+ Confidence decays by 30%. Assertions below 0.2 are auto-deleted.
153
+
154
+ Args:
155
+ assertion_id: The assertion ID to contradict
156
+ """
157
+ engine = get_engine()
158
+ return _update_assertion_confidence(engine._db, assertion_id, reinforce=False)
159
+
160
+
161
+ def _update_assertion_confidence(db, assertion_id: str, reinforce: bool) -> dict:
162
+ """Bayesian confidence update for behavioral assertions."""
163
+ now = datetime.now(timezone.utc).isoformat()
164
+ try:
165
+ row = db.execute(
166
+ "SELECT confidence, reinforcement_count, contradiction_count "
167
+ "FROM behavioral_assertions WHERE id = ?",
168
+ (assertion_id,),
169
+ )
170
+ rows = list(row)
171
+ if not rows:
172
+ return {"success": False, "error": "assertion not found"}
173
+
174
+ r = dict(rows[0])
175
+ old_conf = r["confidence"]
176
+
177
+ if reinforce:
178
+ new_conf = old_conf + (1.0 - old_conf) * 0.15 # Bayesian nudge toward 1.0
179
+ db.execute(
180
+ "UPDATE behavioral_assertions SET confidence = ?, "
181
+ "reinforcement_count = reinforcement_count + 1, "
182
+ "last_reinforced_at = ?, updated_at = ? WHERE id = ?",
183
+ (round(new_conf, 4), now, now, assertion_id),
184
+ )
185
+ else:
186
+ new_conf = old_conf * 0.7 # 30% decay
187
+ db.execute(
188
+ "UPDATE behavioral_assertions SET confidence = ?, "
189
+ "contradiction_count = contradiction_count + 1, "
190
+ "last_contradicted_at = ?, updated_at = ? WHERE id = ?",
191
+ (round(new_conf, 4), now, now, assertion_id),
192
+ )
193
+ # Auto-delete if confidence drops below 0.2
194
+ if new_conf < 0.2:
195
+ db.execute(
196
+ "DELETE FROM behavioral_assertions WHERE id = ?",
197
+ (assertion_id,),
198
+ )
199
+ return {
200
+ "success": True, "action": "deleted",
201
+ "reason": f"confidence dropped to {new_conf:.3f} (below 0.2 threshold)",
202
+ }
203
+
204
+ return {
205
+ "success": True,
206
+ "action": "reinforced" if reinforce else "contradicted",
207
+ "old_confidence": round(old_conf, 4),
208
+ "new_confidence": round(new_conf, 4),
209
+ }
210
+ except Exception as exc:
211
+ return {"success": False, "error": str(exc)}
212
+
213
+
214
+ def _scrub(text: str) -> str:
215
+ """Remove potential secrets from telemetry text."""
216
+ import re
217
+ # Remove API keys, tokens, passwords
218
+ text = re.sub(r'\b(sk-|pk-|api[_-]?key[_-]?)[A-Za-z0-9_-]{10,}\b', '[REDACTED]', text)
219
+ text = re.sub(r'\b[A-Za-z0-9+/]{40,}={0,2}\b', '[REDACTED]', text) # Base64 strings
220
+ text = re.sub(r'password\s*[=:]\s*\S+', 'password=[REDACTED]', text, flags=re.IGNORECASE)
221
+ return text
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
- # Licensed under the Elastic License 2.0 - see LICENSE file
2
+ # Licensed under AGPL-3.0-or-later - see LICENSE file
3
3
  # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
4
 
5
5
  """SLM Mesh MCP Tools — P2P agent communication via the unified daemon.
@@ -29,6 +29,7 @@ logger = logging.getLogger(__name__)
29
29
  # Unique peer ID for this MCP server session
30
30
  _PEER_ID = str(uuid.uuid4())[:12]
31
31
  _SESSION_SUMMARY = ""
32
+ _PROJECT_PATH = "" # v3.4.6: detected from cwd or CLAUDE_PROJECT_DIR
32
33
  _HEARTBEAT_INTERVAL = 25 # seconds (broker marks stale at 30s, dead at 60s)
33
34
  _HEARTBEAT_THREAD: threading.Thread | None = None
34
35
  _REGISTERED = False
@@ -46,6 +47,15 @@ def _daemon_url() -> str:
46
47
  return f"http://127.0.0.1:{port}"
47
48
 
48
49
 
50
+ def _detect_project_path() -> str:
51
+ """Detect current project path from env or cwd."""
52
+ return (
53
+ os.environ.get("CLAUDE_PROJECT_DIR")
54
+ or os.environ.get("PROJECT_PATH")
55
+ or os.getcwd()
56
+ )
57
+
58
+
49
59
  def _mesh_request(method: str, path: str, body: dict | None = None) -> dict | None:
50
60
  """Send request to daemon mesh broker."""
51
61
  import urllib.request
@@ -63,18 +73,24 @@ def _mesh_request(method: str, path: str, body: dict | None = None) -> dict | No
63
73
 
64
74
  def _ensure_registered() -> None:
65
75
  """Register this session with the mesh broker if not already."""
66
- global _REGISTERED
76
+ global _REGISTERED, _PROJECT_PATH
67
77
  if _REGISTERED:
68
78
  return
69
79
 
80
+ _PROJECT_PATH = _detect_project_path()
70
81
  result = _mesh_request("POST", "/register", {
71
82
  "peer_id": _PEER_ID,
72
83
  "session_id": os.environ.get("CLAUDE_SESSION_ID", _PEER_ID),
73
84
  "summary": _SESSION_SUMMARY or "SLM MCP session",
85
+ "project_path": _PROJECT_PATH,
86
+ "agent_type": os.environ.get("CLAUDE_AGENT_TYPE", "claude_code"),
74
87
  })
75
88
  if result:
76
89
  _REGISTERED = True
77
90
  _start_heartbeat()
91
+ pending = result.get("pending_messages", 0)
92
+ if pending > 0:
93
+ logger.info("Mesh: %d pending messages waiting", pending)
78
94
 
79
95
 
80
96
  def _start_heartbeat() -> None:
@@ -96,6 +112,15 @@ def _start_heartbeat() -> None:
96
112
  logger.info("Mesh heartbeat started (peer_id=%s, interval=%ds)", _PEER_ID, _HEARTBEAT_INTERVAL)
97
113
 
98
114
 
115
+ def auto_register_mesh() -> None:
116
+ """Called from server.py warmup to register this session immediately.
117
+
118
+ v3.4.6: Sessions register at MCP startup, not lazily on first tool call.
119
+ This ensures every Claude session is visible on the mesh from the start.
120
+ """
121
+ _ensure_registered()
122
+
123
+
99
124
  def register_mesh_tools(server, get_engine: Callable) -> None:
100
125
  """Register all 8 mesh MCP tools."""
101
126
 
@@ -105,6 +130,8 @@ def register_mesh_tools(server, get_engine: Callable) -> None:
105
130
 
106
131
  Call this at the start of every session. Other agents can see your summary
107
132
  and send you messages. The session stays alive via automatic heartbeat.
133
+ v3.4.6: Sessions auto-register at MCP startup, but calling this updates
134
+ the summary so other sessions know what you're doing.
108
135
 
109
136
  Args:
110
137
  summary: What this session is working on (e.g. "Fixing auth bug in api.py")
@@ -123,6 +150,7 @@ def register_mesh_tools(server, get_engine: Callable) -> None:
123
150
  return {
124
151
  "peer_id": _PEER_ID,
125
152
  "summary": _SESSION_SUMMARY,
153
+ "project_path": _PROJECT_PATH,
126
154
  "registered": True,
127
155
  "heartbeat_active": _HEARTBEAT_THREAD is not None,
128
156
  "broker_response": result,
@@ -146,11 +174,14 @@ def register_mesh_tools(server, get_engine: Callable) -> None:
146
174
 
147
175
  @server.tool()
148
176
  async def mesh_send(to: str, message: str) -> dict:
149
- """Send a message to another peer session.
177
+ """Send a message to another peer session, broadcast, or project.
150
178
 
151
179
  Args:
152
- to: The peer_id of the recipient (from mesh_peers)
153
- message: The message content to send
180
+ to: Target one of:
181
+ - A peer_id from mesh_peers (direct message)
182
+ - "broadcast" (all active + future sessions within 48h)
183
+ - "project:/path/to/dir" (all sessions in that project directory)
184
+ message: The message content (max 4KB — use file paths for large data)
154
185
  """
155
186
  _ensure_registered()
156
187
  result = _mesh_request("POST", "/send", {
@@ -164,15 +195,27 @@ def register_mesh_tools(server, get_engine: Callable) -> None:
164
195
  async def mesh_inbox() -> dict:
165
196
  """Read messages sent to this session.
166
197
 
167
- Returns unread messages from other peer sessions.
168
- Messages are marked as read after retrieval.
198
+ Returns unread messages: direct + broadcast + project-targeted.
199
+ Broadcast/project messages are delivered to ALL matching sessions.
200
+ Messages auto-expire after 48 hours.
169
201
  """
170
202
  _ensure_registered()
171
- messages = _mesh_request("GET", f"/inbox/{_PEER_ID}")
172
- if messages:
173
- # Mark as read
174
- _mesh_request("POST", f"/inbox/{_PEER_ID}/read")
175
- return messages or {"messages": [], "count": 0}
203
+ project = _PROJECT_PATH or _detect_project_path()
204
+ messages = _mesh_request(
205
+ "GET", f"/inbox/{_PEER_ID}?project_path={project}",
206
+ )
207
+ msg_list = (messages or {}).get("messages", [])
208
+ # Auto-mark unread messages as read
209
+ unread_ids = [m["id"] for m in msg_list if not m.get("read")]
210
+ if unread_ids:
211
+ _mesh_request("POST", f"/inbox/{_PEER_ID}/read", {
212
+ "message_ids": unread_ids,
213
+ })
214
+ return {
215
+ "messages": msg_list,
216
+ "count": len(msg_list),
217
+ "unread": len(unread_ids),
218
+ }
176
219
 
177
220
  @server.tool()
178
221
  async def mesh_state(key: str = "", value: str = "", action: str = "get") -> dict:
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
- # Licensed under the Elastic License 2.0 - see LICENSE file
2
+ # Licensed under AGPL-3.0-or-later - see LICENSE file
3
3
  # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
4
 
5
5
  """SuperLocalMemory V3 — V2.8 Ported MCP Tools (6 tools).
@@ -53,6 +53,28 @@ def register_v28_tools(server, get_engine: Callable) -> None:
53
53
  profile_id=engine.profile_id,
54
54
  context=ctx,
55
55
  )
56
+
57
+ # v3.4.7: Bridge outcomes → learning signals for two-way learning.
58
+ # Previously, outcomes were stored but never created learning signals.
59
+ try:
60
+ from superlocalmemory.learning.feedback import FeedbackCollector
61
+ from pathlib import Path as _Path
62
+ learning_db = _Path.home() / ".superlocalmemory" / "learning.db"
63
+ collector = FeedbackCollector(learning_db)
64
+ signal_map = {"success": ("user_positive", 1.0),
65
+ "failure": ("user_negative", 0.0),
66
+ "partial": ("user_correction", 0.5)}
67
+ sig_type, sig_val = signal_map.get(outcome, ("user_correction", 0.5))
68
+ for fid in ids:
69
+ collector.record_explicit(
70
+ profile_id=engine.profile_id,
71
+ fact_id=fid,
72
+ signal_type=sig_type,
73
+ value=sig_val,
74
+ )
75
+ except Exception as exc2:
76
+ logger.debug("Outcome→signal bridge: %s", exc2)
77
+
56
78
  return {"success": True, "outcome_id": ao.outcome_id, "outcome": outcome}
57
79
  except Exception as exc:
58
80
  logger.exception("report_outcome failed")
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
- # Licensed under the Elastic License 2.0 - see LICENSE file
2
+ # Licensed under AGPL-3.0-or-later - see LICENSE file
3
3
  # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
4
 
5
5
  """SuperLocalMemory V3 — V3-Only MCP Tools (5 tools).
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
- # Licensed under the Elastic License 2.0 - see LICENSE file
2
+ # Licensed under AGPL-3.0-or-later - see LICENSE file
3
3
  # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
4
 
5
5
  """SuperLocalMemory V3.3 — New MCP Tools (6 tools).
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
- # Licensed under the Elastic License 2.0 - see LICENSE file
2
+ # Licensed under AGPL-3.0-or-later - see LICENSE file
3
3
  # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
4
 
5
5
  """SLM Mesh — Python port of the P2P agent communication broker.