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,8 +1,8 @@
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
  """SuperLocalMemory V3 - Backup Routes
5
- - Elastic License 2.0
5
+ - AGPL-3.0-or-later
6
6
 
7
7
  Routes: /api/backup/status, /api/backup/create, /api/backup/configure, /api/backup/list
8
8
  Uses V3 infra.backup.BackupManager.
@@ -1,8 +1,8 @@
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
  """SuperLocalMemory V3 - Behavioral Routes
5
- - Elastic License 2.0
5
+ - AGPL-3.0-or-later
6
6
 
7
7
  Routes: /api/behavioral/status, /api/behavioral/report-outcome
8
8
  Uses V3 learning.behavioral.BehavioralPatternStore and learning.outcomes.OutcomeTracker.
@@ -144,3 +144,130 @@ async def report_outcome(data: dict):
144
144
  except Exception as e:
145
145
  logger.error("report_outcome error: %s", e)
146
146
  return {"success": False, "error": str(e)}
147
+
148
+
149
+ # --------------------------------------------------------------------------
150
+ # v3.4.7: Behavioral Assertions API (for dashboard + external consumers)
151
+ # --------------------------------------------------------------------------
152
+
153
+ @router.get("/api/behavioral/assertions")
154
+ async def get_assertions(min_confidence: float = 0.0, category: str = "", limit: int = 50):
155
+ """Get learned behavioral assertions for dashboard display."""
156
+ try:
157
+ import sqlite3 as _sqlite3
158
+ profile = get_active_profile()
159
+ conn = _sqlite3.connect(str(MEMORY_DIR / "memory.db"))
160
+ conn.row_factory = _sqlite3.Row
161
+
162
+ query = (
163
+ "SELECT id, trigger_condition, action, category, confidence, "
164
+ "evidence_count, reinforcement_count, contradiction_count, "
165
+ "project_path, source, created_at, updated_at "
166
+ "FROM behavioral_assertions "
167
+ "WHERE profile_id = ? AND confidence >= ?"
168
+ )
169
+ params: list = [profile, min_confidence]
170
+ if category:
171
+ query += " AND category = ?"
172
+ params.append(category)
173
+ query += " ORDER BY confidence DESC LIMIT ?"
174
+ params.append(limit)
175
+
176
+ rows = conn.execute(query, tuple(params)).fetchall()
177
+ conn.close()
178
+
179
+ assertions = [dict(r) for r in rows]
180
+ return {
181
+ "assertions": assertions,
182
+ "count": len(assertions),
183
+ "active_profile": profile,
184
+ }
185
+ except Exception as e:
186
+ logger.debug("get_assertions error: %s", e)
187
+ return {"assertions": [], "count": 0, "error": str(e)}
188
+
189
+
190
+ @router.get("/api/behavioral/tool-events")
191
+ async def get_tool_events(tool_name: str = "", limit: int = 100):
192
+ """Get recent tool events for dashboard display."""
193
+ try:
194
+ import sqlite3 as _sqlite3
195
+ profile = get_active_profile()
196
+ conn = _sqlite3.connect(str(MEMORY_DIR / "memory.db"))
197
+ conn.row_factory = _sqlite3.Row
198
+
199
+ query = (
200
+ "SELECT id, tool_name, event_type, input_summary, output_summary, "
201
+ "duration_ms, created_at FROM tool_events "
202
+ "WHERE profile_id = ?"
203
+ )
204
+ params: list = [profile]
205
+ if tool_name:
206
+ query += " AND tool_name = ?"
207
+ params.append(tool_name)
208
+ query += " ORDER BY created_at DESC LIMIT ?"
209
+ params.append(limit)
210
+
211
+ rows = conn.execute(query, tuple(params)).fetchall()
212
+ conn.close()
213
+
214
+ events = [dict(r) for r in rows]
215
+ return {"events": events, "count": len(events)}
216
+ except Exception as e:
217
+ logger.debug("get_tool_events error: %s", e)
218
+ return {"events": [], "count": 0, "error": str(e)}
219
+
220
+
221
+ @router.get("/api/behavioral/soft-prompts")
222
+ async def get_soft_prompts():
223
+ """Get active soft prompt templates for dashboard display."""
224
+ try:
225
+ import sqlite3 as _sqlite3
226
+ conn = _sqlite3.connect(str(MEMORY_DIR / "memory.db"))
227
+ conn.row_factory = _sqlite3.Row
228
+ rows = conn.execute(
229
+ "SELECT prompt_id, category, content, confidence, effectiveness, "
230
+ "token_count, active, version, created_at "
231
+ "FROM soft_prompt_templates WHERE active = 1 ORDER BY category"
232
+ ).fetchall()
233
+ conn.close()
234
+ return {"prompts": [dict(zip(
235
+ ["prompt_id", "category", "content", "confidence", "effectiveness",
236
+ "token_count", "active", "version", "created_at"], r
237
+ )) for r in rows], "count": len(rows)}
238
+ except Exception as e:
239
+ logger.debug("get_soft_prompts error: %s", e)
240
+ return {"prompts": [], "count": 0, "error": str(e)}
241
+
242
+
243
+ @router.post("/api/v3/tool-event")
244
+ async def log_tool_event_api(data: dict):
245
+ """Log a tool event via HTTP (called by PostToolUse hook).
246
+
247
+ Body: { "tool_name": "Read", "event_type": "complete" }
248
+ Lightweight — no LLM, just an INSERT. For the shipped hook.
249
+ """
250
+ try:
251
+ import sqlite3 as _sqlite3
252
+ from datetime import datetime, timezone
253
+ import os
254
+
255
+ tool_name = data.get("tool_name", "unknown")
256
+ event_type = data.get("event_type", "complete")
257
+ now = datetime.now(timezone.utc).isoformat()
258
+ session_id = data.get("session_id", os.environ.get("CLAUDE_SESSION_ID", "hook"))
259
+ profile = get_active_profile()
260
+
261
+ conn = _sqlite3.connect(str(MEMORY_DIR / "memory.db"))
262
+ conn.execute(
263
+ "INSERT INTO tool_events "
264
+ "(session_id, profile_id, project_path, tool_name, event_type, "
265
+ " input_summary, output_summary, duration_ms, metadata, created_at) "
266
+ "VALUES (?, ?, ?, ?, ?, '', '', 0, '{}', ?)",
267
+ (session_id, profile, "", tool_name, event_type, now),
268
+ )
269
+ conn.commit()
270
+ conn.close()
271
+ return {"ok": True}
272
+ except Exception as e:
273
+ return {"ok": False, "error": str(e)}
@@ -1,8 +1,8 @@
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
  """SuperLocalMemory V3 - Compliance Routes
5
- - Elastic License 2.0
5
+ - AGPL-3.0-or-later
6
6
 
7
7
  Routes: /api/compliance/status, /api/compliance/audit,
8
8
  /api/compliance/retention-policy
@@ -1,8 +1,8 @@
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
  """SuperLocalMemory V3 - Import/Export Routes
5
- - Elastic License 2.0
5
+ - AGPL-3.0-or-later
6
6
 
7
7
  Routes: /api/export, /api/import
8
8
  """
@@ -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
  """Entity compilation API routes — view and recompile entity summaries."""
@@ -1,8 +1,8 @@
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
  """SuperLocalMemory V3 - Event Bus Routes
5
- - Elastic License 2.0
5
+ - AGPL-3.0-or-later
6
6
 
7
7
  Routes: /events/stream (SSE), /api/events, /api/events/stats
8
8
  Uses V3 infra.event_bus.EventBus.
@@ -1,8 +1,8 @@
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
  """SuperLocalMemory V3 - Route Helpers
5
- - Elastic License 2.0
5
+ - AGPL-3.0-or-later
6
6
 
7
7
  Shared utilities for all route modules: DB connection, dict factory,
8
8
  profile helper, validation, Pydantic models, config paths.
@@ -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
  """Ingestion endpoint — accepts data from external adapters.
@@ -1,8 +1,8 @@
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
  """SuperLocalMemory V3 - Learning Routes
5
- - Elastic License 2.0
5
+ - AGPL-3.0-or-later
6
6
 
7
7
  Routes: /api/learning/status, /api/feedback, /api/feedback/dwell,
8
8
  /api/feedback/stats, /api/learning/backup, /api/learning/reset,
@@ -143,12 +143,29 @@ async def learning_status():
143
143
  "signals": signal_count,
144
144
  }
145
145
 
146
- # Engagement
146
+ # Engagement — v3.4.8: Fixed method name (was get_engagement_stats, actual is get_stats)
147
147
  engagement = _get_engagement()
148
148
  if engagement:
149
149
  try:
150
- result["engagement"] = engagement.get_engagement_stats()
151
- except Exception:
150
+ stats = engagement.get_stats(active_profile)
151
+ health = engagement.get_health(active_profile)
152
+ active_days = stats.get("active_days", 0)
153
+ total_events = stats.get("total_events", 0)
154
+ memories_per_day = (
155
+ round(total_events / active_days, 1) if active_days > 0 else 0
156
+ )
157
+ result["engagement"] = {
158
+ "health_status": health.upper(),
159
+ "days_active": active_days,
160
+ "memories_per_day": memories_per_day,
161
+ "total_events": total_events,
162
+ "recall_count": stats.get("recall_count", 0),
163
+ "store_count": stats.get("store_count", 0),
164
+ "session_count": stats.get("session_count", 0),
165
+ "engagement_score": stats.get("engagement_score", 0),
166
+ }
167
+ except Exception as exc:
168
+ logger.debug("engagement stats: %s", exc)
152
169
  result["engagement"] = None
153
170
  else:
154
171
  result["engagement"] = None
@@ -1,8 +1,8 @@
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
  """SuperLocalMemory V3 - Lifecycle Routes
5
- - Elastic License 2.0
5
+ - AGPL-3.0-or-later
6
6
 
7
7
  Routes: /api/lifecycle/status, /api/lifecycle/compact
8
8
  Uses V3 compliance.lifecycle.LifecycleManager.
@@ -1,7 +1,7 @@
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
- """SuperLocalMemory V3 - Memory Routes (Elastic License 2.0).
4
+ """SuperLocalMemory V3 - Memory Routes (AGPL-3.0-or-later).
5
5
  Routes: /api/memories, /api/graph, /api/search, /api/clusters, /api/clusters/{id}
6
6
  Uses V3 MemoryEngine for store/recall. Falls back to direct DB for list/graph.
7
7
  """
@@ -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 — FastAPI routes for P2P agent communication.
@@ -26,6 +26,8 @@ class RegisterRequest(BaseModel):
26
26
  summary: str = ""
27
27
  host: str = "127.0.0.1"
28
28
  port: int = 0
29
+ project_path: str = ""
30
+ agent_type: str = "unknown"
29
31
 
30
32
 
31
33
  class DeregisterRequest(BaseModel):
@@ -43,7 +45,8 @@ class SummaryRequest(BaseModel):
43
45
 
44
46
  class SendRequest(BaseModel):
45
47
  from_peer: str = ""
46
- to: str
48
+ to: str = ""
49
+ to_peer: str = "" # v3.4.6: accept both 'to' and 'to_peer' for compatibility
47
50
  content: str
48
51
  type: str = "text"
49
52
 
@@ -84,7 +87,10 @@ async def register(req: RegisterRequest, request: Request):
84
87
  broker = _get_broker(request)
85
88
  if not req.session_id:
86
89
  raise HTTPException(400, detail="session_id required")
87
- return broker.register_peer(req.session_id, req.summary, req.host, req.port)
90
+ return broker.register_peer(
91
+ req.session_id, req.summary, req.host, req.port,
92
+ req.project_path, req.agent_type,
93
+ )
88
94
 
89
95
 
90
96
  @router.post("/deregister")
@@ -123,16 +129,20 @@ async def summary(req: SummaryRequest, request: Request):
123
129
  @router.post("/send")
124
130
  async def send(req: SendRequest, request: Request):
125
131
  broker = _get_broker(request)
126
- result = broker.send_message(req.from_peer, req.to, req.content, req.type)
132
+ to_target = req.to_peer or req.to # v3.4.6: accept both field names
133
+ if not to_target:
134
+ raise HTTPException(400, detail="'to' or 'to_peer' required")
135
+ result = broker.send_message(req.from_peer, to_target, req.content, req.type)
127
136
  if not result.get("ok"):
128
- raise HTTPException(404, detail=result.get("error", ""))
137
+ status = 413 if "too large" in result.get("error", "") else 404
138
+ raise HTTPException(status, detail=result.get("error", ""))
129
139
  return result
130
140
 
131
141
 
132
142
  @router.get("/inbox/{peer_id}")
133
- async def inbox(peer_id: str, request: Request):
143
+ async def inbox(peer_id: str, request: Request, project_path: str = ""):
134
144
  broker = _get_broker(request)
135
- return {"messages": broker.get_inbox(peer_id)}
145
+ return {"messages": broker.get_inbox(peer_id, project_path)}
136
146
 
137
147
 
138
148
  @router.post("/inbox/{peer_id}/read")
@@ -141,6 +151,14 @@ async def mark_read(peer_id: str, req: ReadRequest, request: Request):
141
151
  return broker.mark_read(peer_id, req.message_ids)
142
152
 
143
153
 
154
+ @router.get("/pending/{peer_id}")
155
+ async def pending(peer_id: str, request: Request, project_path: str = ""):
156
+ """Get pending broadcast/project messages for this peer."""
157
+ broker = _get_broker(request)
158
+ messages = broker.get_pending(peer_id, project_path)
159
+ return {"messages": messages, "count": len(messages)}
160
+
161
+
144
162
  @router.get("/state")
145
163
  async def state_all(request: Request):
146
164
  broker = _get_broker(request)
@@ -1,8 +1,8 @@
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
  """SuperLocalMemory V3 - Profile Routes
5
- - Elastic License 2.0
5
+ - AGPL-3.0-or-later
6
6
 
7
7
  Routes: /api/profiles, /api/profiles/{name}/switch,
8
8
  /api/profiles/create, DELETE /api/profiles/{name}
@@ -1,8 +1,8 @@
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
  """SuperLocalMemory V3 - Stats Routes
5
- - Elastic License 2.0
5
+ - AGPL-3.0-or-later
6
6
 
7
7
  Routes: /api/stats, /api/timeline, /api/patterns
8
8
  """
@@ -323,25 +323,44 @@ async def get_patterns():
323
323
  from superlocalmemory.learning.behavioral import BehavioralPatternStore
324
324
  store = BehavioralPatternStore(str(MEMORY_DIR / "learning.db"))
325
325
  raw = store.get_patterns(profile_id=active_profile)
326
- # v3.4.1: Map pattern_type to frontend-expected keys
326
+ # v3.4.7: Map all pattern types to frontend categories
327
327
  type_map = {
328
328
  "tech_preference": "preference",
329
+ "interest": "preference",
330
+ "entity_preferences": "preference",
329
331
  "style": "style",
332
+ "fact_type_distribution": "style",
333
+ "knowledge_structure": "style",
330
334
  "terminology": "terminology",
331
335
  "temporal": "workflow",
332
- "interest": "workflow",
336
+ "session_activity": "workflow",
333
337
  "workflow": "workflow",
338
+ "co_retrieval_clusters": "workflow",
339
+ "channel_performance": "performance",
334
340
  }
335
341
  grouped = defaultdict(list)
336
342
  for p in raw:
337
343
  meta = p.get("metadata", {})
344
+ data = meta # metadata IS the data dict
338
345
  frontend_key = type_map.get(p.get("pattern_type", ""), "preference")
346
+ # Extract human-readable value from data fields
347
+ readable_value = (
348
+ data.get("value")
349
+ or data.get("topic")
350
+ or data.get("pattern_key", "")
351
+ or p.get("pattern_key", "")
352
+ )
353
+ readable_key = (
354
+ data.get("pattern_key")
355
+ or data.get("key")
356
+ or p.get("pattern_key", "")
357
+ )
339
358
  grouped[frontend_key].append({
340
359
  "pattern_type": p.get("pattern_type", ""),
341
- "key": meta.get("key", p.get("pattern_key", "")),
342
- "value": meta.get("value", p.get("pattern_key", "")),
360
+ "key": readable_key,
361
+ "value": readable_value,
343
362
  "confidence": p.get("confidence", 0),
344
- "evidence_count": p.get("evidence_count", 0),
363
+ "evidence_count": data.get("evidence", p.get("evidence_count", 0)),
345
364
  })
346
365
  all_patterns = [p for ps in grouped.values() for p in ps]
347
366
  confs = [p["confidence"] for p in all_patterns if p.get("confidence")]
@@ -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
  """V3 API endpoints for the SuperLocalMemory dashboard."""
@@ -1,8 +1,8 @@
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
  """SuperLocalMemory V3 - WebSocket Routes
5
- - Elastic License 2.0
5
+ - AGPL-3.0-or-later
6
6
 
7
7
  Routes: /ws/updates
8
8
  """
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env python3
2
2
  # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
3
- # Licensed under the Elastic License 2.0 - see LICENSE file
3
+ # Licensed under AGPL-3.0-or-later - see LICENSE file
4
4
  # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
5
5
  """
6
6
  SuperLocalMemory V3 - FastAPI UI Server
@@ -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 Unified Daemon — single FastAPI process for ALL routes.
@@ -647,6 +647,44 @@ _start_time: float | None = None
647
647
  # Server entry point
648
648
  # ---------------------------------------------------------------------------
649
649
 
650
+ def _start_memory_watchdog() -> None:
651
+ """v3.4.7: Background watchdog that kills child workers exceeding memory limit.
652
+
653
+ Prevents the orphan worker memory explosion that caused 16GB+ RAM usage.
654
+ Checks every 60 seconds. Kills workers over 2GB RSS. Auto-restarts them
655
+ on next request (workers are lazy-spawned).
656
+ """
657
+ import threading
658
+
659
+ MAX_WORKER_MB = 2048 # 2GB per worker — kill if exceeded
660
+
661
+ def watchdog_loop():
662
+ while True:
663
+ time.sleep(60)
664
+ try:
665
+ import psutil
666
+ parent = psutil.Process(os.getpid())
667
+ for child in parent.children(recursive=True):
668
+ try:
669
+ rss_mb = child.memory_info().rss / (1024 * 1024)
670
+ if rss_mb > MAX_WORKER_MB:
671
+ logger.warning(
672
+ "Memory watchdog: killing %s (PID %d, %.0f MB > %d MB limit)",
673
+ child.name(), child.pid, rss_mb, MAX_WORKER_MB,
674
+ )
675
+ child.kill()
676
+ except (psutil.NoSuchProcess, psutil.AccessDenied):
677
+ pass
678
+ except ImportError:
679
+ pass # psutil not available — watchdog disabled
680
+ except Exception as exc:
681
+ logger.debug("Memory watchdog error: %s", exc)
682
+
683
+ t = threading.Thread(target=watchdog_loop, daemon=True, name="memory-watchdog")
684
+ t.start()
685
+ logger.info("Memory watchdog started (limit: %d MB per worker)", MAX_WORKER_MB)
686
+
687
+
650
688
  def start_server(port: int = _DEFAULT_PORT) -> None:
651
689
  """Start the unified daemon. Blocks until stopped."""
652
690
  global _start_time
@@ -657,6 +695,9 @@ def start_server(port: int = _DEFAULT_PORT) -> None:
657
695
  _PORT_FILE.write_text(str(port))
658
696
  _start_time = time.monotonic()
659
697
 
698
+ # v3.4.7: Start memory watchdog to prevent runaway workers
699
+ _start_memory_watchdog()
700
+
660
701
  log_dir = Path.home() / ".superlocalmemory" / "logs"
661
702
  log_dir.mkdir(parents=True, exist_ok=True)
662
703
 
@@ -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 — Attribute-Based Access Control (ABAC).
@@ -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
  """Access log for fact retrieval events.
@@ -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 — Database Manager.
@@ -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
  """Embedding migration on mode/model switch.
@@ -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 3.2.3 -> 3.3 migration: idempotent schema upgrade.
@@ -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 — Database Migrations.
@@ -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 — Data Models.
@@ -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
  """Quantized embedding storage and retrieval.
@@ -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 — Database Schema.
@@ -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 Module
4
4
 
5
5
  """DDL for the code_graph.db database.
@@ -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
  """SuperLocalMemory V3.2 -- Schema Extensions (Associative Memory).