superlocalmemory 3.3.0__tar.gz → 3.3.2__tar.gz

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 (216) hide show
  1. {superlocalmemory-3.3.0/src/superlocalmemory.egg-info → superlocalmemory-3.3.2}/PKG-INFO +6 -3
  2. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/pyproject.toml +6 -3
  3. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/cli/commands.py +154 -30
  4. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/core/config.py +18 -6
  5. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/core/embedding_worker.py +14 -1
  6. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/core/embeddings.py +12 -1
  7. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/core/engine_wiring.py +4 -1
  8. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/core/modes.py +2 -1
  9. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/core/recall_worker.py +11 -5
  10. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/core/worker_pool.py +13 -2
  11. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/hooks/ide_connector.py +1 -0
  12. superlocalmemory-3.3.2/src/superlocalmemory/retrieval/reranker.py +255 -0
  13. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2/src/superlocalmemory.egg-info}/PKG-INFO +6 -3
  14. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory.egg-info/requires.txt +4 -1
  15. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/tests/test_final_locomo_mini.py +9 -3
  16. superlocalmemory-3.3.0/src/superlocalmemory/retrieval/reranker.py +0 -154
  17. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/AUTHORS.md +0 -0
  18. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/LICENSE +0 -0
  19. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/NOTICE +0 -0
  20. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/README.md +0 -0
  21. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/setup.cfg +0 -0
  22. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/__init__.py +0 -0
  23. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/attribution/__init__.py +0 -0
  24. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/attribution/mathematical_dna.py +0 -0
  25. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/attribution/signer.py +0 -0
  26. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/attribution/watermark.py +0 -0
  27. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/cli/__init__.py +0 -0
  28. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/cli/json_output.py +0 -0
  29. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/cli/main.py +0 -0
  30. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/cli/migrate_cmd.py +0 -0
  31. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/cli/post_install.py +0 -0
  32. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/cli/setup_wizard.py +0 -0
  33. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/compliance/__init__.py +0 -0
  34. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/compliance/abac.py +0 -0
  35. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/compliance/audit.py +0 -0
  36. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/compliance/eu_ai_act.py +0 -0
  37. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/compliance/gdpr.py +0 -0
  38. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/compliance/lifecycle.py +0 -0
  39. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/compliance/retention.py +0 -0
  40. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/compliance/scheduler.py +0 -0
  41. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/core/__init__.py +0 -0
  42. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/core/consolidation_engine.py +0 -0
  43. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/core/engine.py +0 -0
  44. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/core/graph_analyzer.py +0 -0
  45. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/core/hooks.py +0 -0
  46. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/core/maintenance.py +0 -0
  47. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/core/ollama_embedder.py +0 -0
  48. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/core/profiles.py +0 -0
  49. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/core/recall_pipeline.py +0 -0
  50. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/core/registry.py +0 -0
  51. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/core/store_pipeline.py +0 -0
  52. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/core/summarizer.py +0 -0
  53. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/dynamics/__init__.py +0 -0
  54. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/dynamics/activation_guided_quantization.py +0 -0
  55. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/dynamics/eap_scheduler.py +0 -0
  56. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/dynamics/ebbinghaus_langevin_coupling.py +0 -0
  57. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/dynamics/fisher_langevin_coupling.py +0 -0
  58. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/encoding/__init__.py +0 -0
  59. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/encoding/auto_linker.py +0 -0
  60. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/encoding/cognitive_consolidator.py +0 -0
  61. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/encoding/consolidator.py +0 -0
  62. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/encoding/context_generator.py +0 -0
  63. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/encoding/emotional.py +0 -0
  64. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/encoding/entity_resolver.py +0 -0
  65. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/encoding/entropy_gate.py +0 -0
  66. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/encoding/fact_extractor.py +0 -0
  67. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/encoding/foresight.py +0 -0
  68. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/encoding/graph_builder.py +0 -0
  69. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/encoding/observation_builder.py +0 -0
  70. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/encoding/scene_builder.py +0 -0
  71. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/encoding/signal_inference.py +0 -0
  72. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/encoding/temporal_parser.py +0 -0
  73. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/encoding/temporal_validator.py +0 -0
  74. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/encoding/type_router.py +0 -0
  75. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/hooks/__init__.py +0 -0
  76. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/hooks/auto_capture.py +0 -0
  77. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/hooks/auto_invoker.py +0 -0
  78. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/hooks/auto_parameterize.py +0 -0
  79. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/hooks/auto_recall.py +0 -0
  80. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/hooks/claude_code_hooks.py +0 -0
  81. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/hooks/rules_engine.py +0 -0
  82. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/infra/__init__.py +0 -0
  83. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/infra/auth_middleware.py +0 -0
  84. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/infra/backup.py +0 -0
  85. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/infra/cache_manager.py +0 -0
  86. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/infra/event_bus.py +0 -0
  87. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/infra/heartbeat_monitor.py +0 -0
  88. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/infra/pid_manager.py +0 -0
  89. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/infra/process_reaper.py +0 -0
  90. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/infra/rate_limiter.py +0 -0
  91. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/infra/webhook_dispatcher.py +0 -0
  92. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/learning/__init__.py +0 -0
  93. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/learning/adaptive.py +0 -0
  94. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/learning/behavioral.py +0 -0
  95. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/learning/behavioral_listener.py +0 -0
  96. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/learning/bootstrap.py +0 -0
  97. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/learning/consolidation_quantization_worker.py +0 -0
  98. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/learning/consolidation_worker.py +0 -0
  99. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/learning/cross_project.py +0 -0
  100. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/learning/database.py +0 -0
  101. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/learning/engagement.py +0 -0
  102. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/learning/features.py +0 -0
  103. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/learning/feedback.py +0 -0
  104. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/learning/forgetting_scheduler.py +0 -0
  105. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/learning/outcomes.py +0 -0
  106. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/learning/project_context.py +0 -0
  107. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/learning/quantization_scheduler.py +0 -0
  108. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/learning/ranker.py +0 -0
  109. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/learning/signals.py +0 -0
  110. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/learning/source_quality.py +0 -0
  111. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/learning/workflows.py +0 -0
  112. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/llm/__init__.py +0 -0
  113. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/llm/backbone.py +0 -0
  114. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/math/__init__.py +0 -0
  115. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/math/ebbinghaus.py +0 -0
  116. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/math/fisher.py +0 -0
  117. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/math/fisher_quantized.py +0 -0
  118. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/math/hopfield.py +0 -0
  119. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/math/langevin.py +0 -0
  120. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/math/polar_quant.py +0 -0
  121. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/math/qjl.py +0 -0
  122. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/math/sheaf.py +0 -0
  123. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/mcp/__init__.py +0 -0
  124. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/mcp/resources.py +0 -0
  125. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/mcp/server.py +0 -0
  126. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/mcp/tools.py +0 -0
  127. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/mcp/tools_active.py +0 -0
  128. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/mcp/tools_core.py +0 -0
  129. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/mcp/tools_v28.py +0 -0
  130. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/mcp/tools_v3.py +0 -0
  131. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/mcp/tools_v33.py +0 -0
  132. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/parameterization/__init__.py +0 -0
  133. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/parameterization/pattern_extractor.py +0 -0
  134. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/parameterization/pii_filter.py +0 -0
  135. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/parameterization/prompt_injector.py +0 -0
  136. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/parameterization/prompt_lifecycle.py +0 -0
  137. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/parameterization/soft_prompt_generator.py +0 -0
  138. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/retrieval/__init__.py +0 -0
  139. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/retrieval/agentic.py +0 -0
  140. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/retrieval/ann_index.py +0 -0
  141. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/retrieval/bm25_channel.py +0 -0
  142. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/retrieval/bridge_discovery.py +0 -0
  143. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/retrieval/channel_registry.py +0 -0
  144. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/retrieval/engine.py +0 -0
  145. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/retrieval/entity_channel.py +0 -0
  146. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/retrieval/forgetting_filter.py +0 -0
  147. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/retrieval/fusion.py +0 -0
  148. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/retrieval/hopfield_channel.py +0 -0
  149. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/retrieval/profile_channel.py +0 -0
  150. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/retrieval/quantization_aware_search.py +0 -0
  151. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/retrieval/semantic_channel.py +0 -0
  152. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/retrieval/spreading_activation.py +0 -0
  153. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/retrieval/strategy.py +0 -0
  154. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/retrieval/temporal_channel.py +0 -0
  155. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/retrieval/vector_store.py +0 -0
  156. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/server/__init__.py +0 -0
  157. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/server/api.py +0 -0
  158. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/server/routes/__init__.py +0 -0
  159. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/server/routes/agents.py +0 -0
  160. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/server/routes/backup.py +0 -0
  161. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/server/routes/behavioral.py +0 -0
  162. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/server/routes/compliance.py +0 -0
  163. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/server/routes/data_io.py +0 -0
  164. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/server/routes/events.py +0 -0
  165. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/server/routes/helpers.py +0 -0
  166. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/server/routes/learning.py +0 -0
  167. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/server/routes/lifecycle.py +0 -0
  168. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/server/routes/memories.py +0 -0
  169. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/server/routes/profiles.py +0 -0
  170. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/server/routes/stats.py +0 -0
  171. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/server/routes/v3_api.py +0 -0
  172. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/server/routes/ws.py +0 -0
  173. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/server/security_middleware.py +0 -0
  174. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/server/ui.py +0 -0
  175. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/storage/__init__.py +0 -0
  176. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/storage/access_control.py +0 -0
  177. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/storage/access_log.py +0 -0
  178. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/storage/database.py +0 -0
  179. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/storage/embedding_migrator.py +0 -0
  180. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/storage/migration_v33.py +0 -0
  181. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/storage/migrations.py +0 -0
  182. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/storage/models.py +0 -0
  183. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/storage/quantized_store.py +0 -0
  184. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/storage/schema.py +0 -0
  185. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/storage/schema_v32.py +0 -0
  186. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/storage/v2_migrator.py +0 -0
  187. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/trust/__init__.py +0 -0
  188. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/trust/gate.py +0 -0
  189. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/trust/provenance.py +0 -0
  190. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/trust/scorer.py +0 -0
  191. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory/trust/signals.py +0 -0
  192. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory.egg-info/SOURCES.txt +0 -0
  193. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory.egg-info/dependency_links.txt +0 -0
  194. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory.egg-info/entry_points.txt +0 -0
  195. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/src/superlocalmemory.egg-info/top_level.txt +0 -0
  196. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/tests/test_auto_hooks.py +0 -0
  197. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/tests/test_behavioral_full.py +0 -0
  198. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/tests/test_cli.py +0 -0
  199. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/tests/test_cli_json.py +0 -0
  200. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/tests/test_cli_v33.py +0 -0
  201. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/tests/test_compliance_full.py +0 -0
  202. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/tests/test_config_system.py +0 -0
  203. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/tests/test_engine_hooks.py +0 -0
  204. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/tests/test_event_bus.py +0 -0
  205. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/tests/test_features.py +0 -0
  206. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/tests/test_ide_connector.py +0 -0
  207. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/tests/test_infra.py +0 -0
  208. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/tests/test_learning_advanced.py +0 -0
  209. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/tests/test_learning_collectors.py +0 -0
  210. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/tests/test_llm_provider.py +0 -0
  211. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/tests/test_mcp_server.py +0 -0
  212. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/tests/test_migration.py +0 -0
  213. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/tests/test_post_install.py +0 -0
  214. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/tests/test_ranker.py +0 -0
  215. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/tests/test_trust_full.py +0 -0
  216. {superlocalmemory-3.3.0 → superlocalmemory-3.3.2}/tests/test_v3_api.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: superlocalmemory
3
- Version: 3.3.0
3
+ Version: 3.3.2
4
4
  Summary: Information-geometric agent memory with mathematical guarantees
5
5
  Author-email: Varun Pratap Bhardwaj <admin@superlocalmemory.com>
6
6
  License: MIT
@@ -22,7 +22,7 @@ Classifier: Programming Language :: Python :: 3.13
22
22
  Classifier: Programming Language :: Python :: 3.14
23
23
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
24
24
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
25
- Requires-Python: >=3.11
25
+ Requires-Python: <3.15,>=3.11
26
26
  Description-Content-Type: text/markdown
27
27
  License-File: LICENSE
28
28
  License-File: NOTICE
@@ -43,11 +43,13 @@ Requires-Dist: lightgbm>=4.0.0
43
43
  Requires-Dist: diskcache>=5.6.0
44
44
  Requires-Dist: orjson>=3.9.0
45
45
  Provides-Extra: search
46
- Requires-Dist: sentence-transformers<4.0.0,>=2.5.0; extra == "search"
46
+ Requires-Dist: sentence-transformers>=4.0.0; extra == "search"
47
+ Requires-Dist: sentence-transformers[onnx]>=4.0.0; extra == "search"
47
48
  Requires-Dist: einops>=0.8.2; extra == "search"
48
49
  Requires-Dist: torch>=2.2.0; extra == "search"
49
50
  Requires-Dist: scikit-learn<2.0.0,>=1.3.0; extra == "search"
50
51
  Requires-Dist: geoopt>=0.5.0; extra == "search"
52
+ Requires-Dist: onnxruntime>=1.17.0; extra == "search"
51
53
  Provides-Extra: ui
52
54
  Requires-Dist: fastapi[all]>=0.135.1; extra == "ui"
53
55
  Requires-Dist: uvicorn>=0.42.0; extra == "ui"
@@ -62,6 +64,7 @@ Requires-Dist: superlocalmemory[learning,performance,search,ui]; extra == "full"
62
64
  Provides-Extra: dev
63
65
  Requires-Dist: pytest>=8.0; extra == "dev"
64
66
  Requires-Dist: pytest-cov>=4.1; extra == "dev"
67
+ Requires-Dist: sqlite-vec>=0.1.6; extra == "dev"
65
68
  Dynamic: license-file
66
69
 
67
70
  <p align="center">
@@ -1,10 +1,10 @@
1
1
  [project]
2
2
  name = "superlocalmemory"
3
- version = "3.3.0"
3
+ version = "3.3.2"
4
4
  description = "Information-geometric agent memory with mathematical guarantees"
5
5
  readme = "README.md"
6
6
  license = {text = "MIT"}
7
- requires-python = ">=3.11"
7
+ requires-python = ">=3.11,<3.15"
8
8
  authors = [
9
9
  {name = "Varun Pratap Bhardwaj", email = "admin@superlocalmemory.com"},
10
10
  ]
@@ -48,11 +48,13 @@ dependencies = [
48
48
 
49
49
  [project.optional-dependencies]
50
50
  search = [
51
- "sentence-transformers>=2.5.0,<4.0.0",
51
+ "sentence-transformers>=4.0.0",
52
+ "sentence-transformers[onnx]>=4.0.0",
52
53
  "einops>=0.8.2",
53
54
  "torch>=2.2.0",
54
55
  "scikit-learn>=1.3.0,<2.0.0",
55
56
  "geoopt>=0.5.0",
57
+ "onnxruntime>=1.17.0",
56
58
  ]
57
59
  ui = [
58
60
  "fastapi[all]>=0.135.1",
@@ -72,6 +74,7 @@ full = [
72
74
  dev = [
73
75
  "pytest>=8.0",
74
76
  "pytest-cov>=4.1",
77
+ "sqlite-vec>=0.1.6",
75
78
  ]
76
79
 
77
80
  [project.urls]
@@ -993,35 +993,64 @@ def cmd_dashboard(args: Namespace) -> None:
993
993
  print("Or install manually: pip install 'fastapi[all]' uvicorn")
994
994
  sys.exit(1)
995
995
 
996
+ import os
997
+ import signal
996
998
  import socket
997
999
 
998
1000
  port = getattr(args, "port", 8765)
999
1001
 
1000
- def _find_port(preferred: int) -> int:
1001
- for p in [preferred] + list(range(preferred + 1, preferred + 20)):
1002
- try:
1003
- with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
1004
- s.bind(("127.0.0.1", p))
1005
- return p
1006
- except OSError:
1007
- continue
1008
- return preferred
1002
+ def _kill_existing_on_port(target_port: int) -> None:
1003
+ """Kill any existing SLM dashboard on the target port.
1009
1004
 
1010
- ui_port = _find_port(port)
1011
- if ui_port != port:
1012
- print(f" Port {port} in use using {ui_port} instead")
1005
+ V3.3.2: ONE port, no auto-increment. If port is busy with
1006
+ another SLM instance, kill it. If busy with a non-SLM process,
1007
+ warn and exitnever silently shift to a different port.
1008
+ """
1009
+ if sys.platform == "win32":
1010
+ return # Windows: user must close manually
1011
+ try:
1012
+ import subprocess
1013
+ result = subprocess.run(
1014
+ ["lsof", "-ti", f":{target_port}"],
1015
+ capture_output=True, text=True, timeout=5,
1016
+ )
1017
+ if result.returncode == 0 and result.stdout.strip():
1018
+ pids = result.stdout.strip().split("\n")
1019
+ for pid_str in pids:
1020
+ pid = int(pid_str.strip())
1021
+ if pid == os.getpid():
1022
+ continue
1023
+ # Check if it's an SLM/Python process
1024
+ ps_result = subprocess.run(
1025
+ ["ps", "-p", str(pid), "-o", "command="],
1026
+ capture_output=True, text=True, timeout=5,
1027
+ )
1028
+ cmd = ps_result.stdout.strip().lower()
1029
+ if "superlocalmemory" in cmd or "slm" in cmd or "uvicorn" in cmd:
1030
+ os.kill(pid, signal.SIGTERM)
1031
+ print(f" Stopped previous dashboard (PID {pid})")
1032
+ import time
1033
+ time.sleep(1)
1034
+ except Exception:
1035
+ pass # Best-effort
1036
+
1037
+ _kill_existing_on_port(port)
1038
+
1039
+ # Brief wait for port to fully release after killing old process
1040
+ import time
1041
+ time.sleep(1)
1013
1042
 
1014
1043
  print("=" * 60)
1015
1044
  print(" SuperLocalMemory V3 — Web Dashboard")
1016
1045
  print("=" * 60)
1017
- print(f" Dashboard: http://localhost:{ui_port}")
1018
- print(f" API Docs: http://localhost:{ui_port}/api/docs")
1046
+ print(f" Dashboard: http://localhost:{port}")
1047
+ print(f" API Docs: http://localhost:{port}/api/docs")
1019
1048
  print(" Press Ctrl+C to stop\n")
1020
1049
 
1021
1050
  from superlocalmemory.server.ui import create_app
1022
1051
 
1023
1052
  app = create_app()
1024
- uvicorn.run(app, host="127.0.0.1", port=ui_port, log_level="info")
1053
+ uvicorn.run(app, host="127.0.0.1", port=port, log_level="info")
1025
1054
 
1026
1055
 
1027
1056
  # -- Profiles (supports --json) -------------------------------------------
@@ -1129,27 +1158,122 @@ def cmd_hooks(args: Namespace) -> None:
1129
1158
 
1130
1159
 
1131
1160
  def cmd_session_context(args: Namespace) -> None:
1132
- """Print session context (for hook scripts and piping)."""
1133
- from superlocalmemory.hooks.auto_recall import AutoRecall
1161
+ """Print session context (for hook scripts and piping).
1162
+
1163
+ Uses a FAST PATH that queries SQLite directly (no engine/Ollama needed).
1164
+ This ensures the SessionStart hook completes within its 15s timeout even
1165
+ when Ollama requires a 60s+ cold start. The fast path returns:
1166
+ - Core Memory blocks (always-on context)
1167
+ - Recent high-importance memories (last 7 days)
1168
+ - Session summary from last session
1169
+ Falls back to the full engine path only if --full is passed explicitly.
1170
+ """
1171
+ import sqlite3
1172
+ from pathlib import Path
1134
1173
  from superlocalmemory.core.config import SLMConfig
1135
- from superlocalmemory.core.engine import MemoryEngine
1136
1174
 
1175
+ use_full = getattr(args, "full", False)
1176
+
1177
+ if use_full:
1178
+ # Full engine path (slow, requires Ollama) — for explicit CLI use
1179
+ try:
1180
+ from superlocalmemory.hooks.auto_recall import AutoRecall
1181
+ from superlocalmemory.core.engine import MemoryEngine
1182
+ config = SLMConfig.load()
1183
+ engine = MemoryEngine(config)
1184
+ engine.initialize()
1185
+ auto = AutoRecall(
1186
+ engine=engine,
1187
+ config={"enabled": True, "max_memories_injected": 10, "relevance_threshold": 0.3},
1188
+ )
1189
+ context = auto.get_session_context(
1190
+ query=getattr(args, "query", "") or "recent decisions and important context",
1191
+ )
1192
+ if context:
1193
+ print(context)
1194
+ except Exception as exc:
1195
+ logger.debug("session-context (full) failed: %s", exc)
1196
+ return
1197
+
1198
+ # ── FAST PATH: direct SQLite, no engine, <500ms ──────────────
1137
1199
  try:
1138
1200
  config = SLMConfig.load()
1139
- engine = MemoryEngine(config)
1140
- engine.initialize()
1201
+ db_path = config.base_dir / "memory.db"
1202
+ if not db_path.exists():
1203
+ return
1141
1204
 
1142
- auto = AutoRecall(
1143
- engine=engine,
1144
- config={"enabled": True, "max_memories_injected": 10, "relevance_threshold": 0.3},
1145
- )
1146
- context = auto.get_session_context(
1147
- query=getattr(args, "query", "") or "recent decisions and important context",
1148
- )
1149
- if context:
1150
- print(context)
1205
+ pid = config.active_profile
1206
+ conn = sqlite3.connect(str(db_path))
1207
+ conn.row_factory = sqlite3.Row
1208
+ sections = []
1209
+
1210
+ # 1. Core Memory blocks (compiled high-value context)
1211
+ try:
1212
+ rows = conn.execute(
1213
+ "SELECT block_type, content FROM core_memory_blocks "
1214
+ "WHERE profile_id = ? ORDER BY block_type",
1215
+ (pid,),
1216
+ ).fetchall()
1217
+ if rows:
1218
+ blocks = [f"[{r['block_type']}] {r['content']}" for r in rows]
1219
+ sections.append("## Core Memory\n" + "\n".join(blocks))
1220
+ except sqlite3.OperationalError:
1221
+ pass
1222
+
1223
+ # 2. Recent important memories (last 7 days, top 10 by importance)
1224
+ try:
1225
+ rows = conn.execute(
1226
+ "SELECT content, fact_type, created_at FROM atomic_facts "
1227
+ "WHERE profile_id = ? "
1228
+ "AND created_at >= datetime('now', '-7 days') "
1229
+ "AND lifecycle = 'active' "
1230
+ "ORDER BY importance DESC, created_at DESC LIMIT 10",
1231
+ (pid,),
1232
+ ).fetchall()
1233
+ if rows:
1234
+ items = []
1235
+ for r in rows:
1236
+ content = r["content"][:200]
1237
+ items.append(f"- [{r['fact_type'] or 'fact'}] {content}")
1238
+ sections.append("## Recent Context (7 days)\n" + "\n".join(items))
1239
+ except sqlite3.OperationalError:
1240
+ pass
1241
+
1242
+ # 3. Session markers (last session summary)
1243
+ try:
1244
+ rows = conn.execute(
1245
+ "SELECT content, created_at FROM atomic_facts "
1246
+ "WHERE profile_id = ? AND content LIKE 'Session%' "
1247
+ "ORDER BY created_at DESC LIMIT 3",
1248
+ (pid,),
1249
+ ).fetchall()
1250
+ if rows:
1251
+ items = [f"- {r['content'][:150]}" for r in rows]
1252
+ sections.append("## Recent Sessions\n" + "\n".join(items))
1253
+ except sqlite3.OperationalError:
1254
+ pass
1255
+
1256
+ # 4. V3.3 Soft prompts (auto-learned patterns)
1257
+ try:
1258
+ rows = conn.execute(
1259
+ "SELECT category, content FROM soft_prompt_templates "
1260
+ "WHERE profile_id = ? AND active = 1 "
1261
+ "ORDER BY confidence DESC LIMIT 5",
1262
+ (pid,),
1263
+ ).fetchall()
1264
+ if rows:
1265
+ items = [f"- [{r['category']}] {r['content'][:150]}" for r in rows]
1266
+ sections.append("## Learned Patterns\n" + "\n".join(items))
1267
+ except sqlite3.OperationalError:
1268
+ pass
1269
+
1270
+ conn.close()
1271
+
1272
+ if sections:
1273
+ header = f"# SLM Session Context — {config.active_profile}"
1274
+ print(header + "\n\n" + "\n\n".join(sections))
1151
1275
  except Exception as exc:
1152
- logger.debug("session-context failed: %s", exc)
1276
+ logger.debug("session-context (fast) failed: %s", exc)
1153
1277
 
1154
1278
 
1155
1279
  def cmd_observe(args: Namespace) -> None:
@@ -152,9 +152,10 @@ class RetrievalConfig:
152
152
  entity_graph_max_hops: int = 3
153
153
  temporal_proximity_days: int = 30
154
154
 
155
- # Reranking
155
+ # Reranking (V3.3.2: ONNX backend enabled for all modes)
156
156
  use_cross_encoder: bool = True
157
- cross_encoder_model: str = "BAAI/bge-reranker-v2-m3"
157
+ cross_encoder_model: str = "cross-encoder/ms-marco-MiniLM-L-6-v2"
158
+ cross_encoder_backend: str = "onnx" # "onnx" (~200MB) or "" (PyTorch, ~1.5GB)
158
159
 
159
160
  # Agentic (Mode C only)
160
161
  agentic_max_rounds: int = 3
@@ -611,6 +612,15 @@ class SLMConfig:
611
612
 
612
613
  rt = data.get("retrieval", {})
613
614
  if rt:
615
+ # V3.3.2 migration: auto-enable ONNX cross-encoder.
616
+ # Pre-3.3.2 configs had use_cross_encoder=False because the
617
+ # PyTorch cross-encoder used ~1.5GB RAM. With ONNX backend
618
+ # (~200MB), it's now safe for all modes. Detect old configs
619
+ # by the absence of cross_encoder_backend field.
620
+ if "cross_encoder_backend" not in rt:
621
+ rt["use_cross_encoder"] = True
622
+ rt["cross_encoder_model"] = "cross-encoder/ms-marco-MiniLM-L-6-v2"
623
+ rt["cross_encoder_backend"] = "onnx"
614
624
  config.retrieval = RetrievalConfig(**{
615
625
  k: v for k, v in rt.items()
616
626
  if k in RetrievalConfig.__dataclass_fields__
@@ -650,6 +660,8 @@ class SLMConfig:
650
660
  },
651
661
  "retrieval": {
652
662
  "use_cross_encoder": self.retrieval.use_cross_encoder,
663
+ "cross_encoder_model": self.retrieval.cross_encoder_model,
664
+ "cross_encoder_backend": self.retrieval.cross_encoder_backend,
653
665
  },
654
666
  }
655
667
 
@@ -725,8 +737,8 @@ class SLMConfig:
725
737
  ),
726
738
  llm=LLMConfig(), # No LLM
727
739
  retrieval=RetrievalConfig(
728
- # Mode A: no cross-encoder (saves ~1.5GB PyTorch RAM)
729
- use_cross_encoder=False,
740
+ # V3.3.2: ONNX cross-encoder enabled for all modes (~200MB)
741
+ use_cross_encoder=True,
730
742
  ),
731
743
  math=MathConfig(
732
744
  sheaf_contradiction_threshold=0.45, # 768d threshold
@@ -750,8 +762,8 @@ class SLMConfig:
750
762
  api_key=llm_api_key or "",
751
763
  ),
752
764
  retrieval=RetrievalConfig(
753
- # Mode B: no cross-encoder (saves ~1.5GB PyTorch RAM)
754
- use_cross_encoder=False,
765
+ # V3.3.2: ONNX cross-encoder enabled for all modes (~200MB)
766
+ use_cross_encoder=True,
755
767
  ),
756
768
  )
757
769
 
@@ -23,6 +23,7 @@ Part of Qualixar | Author: Varun Pratap Bhardwaj
23
23
  from __future__ import annotations
24
24
 
25
25
  import json
26
+ import signal
26
27
  import sys
27
28
  import os
28
29
 
@@ -34,6 +35,11 @@ os.environ["PYTORCH_ENABLE_MPS_FALLBACK"] = "1"
34
35
  os.environ["TOKENIZERS_PARALLELISM"] = "false"
35
36
  os.environ["TORCH_DEVICE"] = "cpu"
36
37
 
38
+ # SIGTERM bridge: Docker/systemd send SIGTERM to stop processes.
39
+ # Without this, the worker ignores SIGTERM and becomes a zombie.
40
+ if sys.platform != "win32":
41
+ signal.signal(signal.SIGTERM, lambda *_: sys.exit(0))
42
+
37
43
 
38
44
  def _worker_main() -> None:
39
45
  """Main loop: read JSON requests from stdin, write responses to stdout."""
@@ -97,7 +103,14 @@ def _worker_main() -> None:
97
103
  _respond({"ok": False, "error": f"Model load failed: {exc}"})
98
104
  continue
99
105
  try:
100
- vecs = model.encode(texts, normalize_embeddings=True)
106
+ # torch.inference_mode prevents autograd graph accumulation
107
+ # which causes silent memory leaks over long-running sessions.
108
+ try:
109
+ import torch
110
+ with torch.inference_mode():
111
+ vecs = model.encode(texts, normalize_embeddings=True)
112
+ except ImportError:
113
+ vecs = model.encode(texts, normalize_embeddings=True)
101
114
  if isinstance(vecs, np.ndarray) and vecs.ndim == 2:
102
115
  result = [vecs[i].tolist() for i in range(vecs.shape[0])]
103
116
  else:
@@ -45,7 +45,8 @@ class DimensionMismatchError(RuntimeError):
45
45
 
46
46
 
47
47
  _IDLE_TIMEOUT_SECONDS = 120 # 2 minutes — kill worker after idle
48
- _SUBPROCESS_RESPONSE_TIMEOUT = 60 # seconds max wait for worker response
48
+ _SUBPROCESS_RESPONSE_TIMEOUT = 120 # V3.3.2: 120s for ONNX cold start
49
+ _WORKER_RECYCLE_AFTER = 1000 # Recycle worker after N requests (C++ fragmentation prevention)
49
50
 
50
51
 
51
52
  class EmbeddingService:
@@ -66,6 +67,7 @@ class EmbeddingService:
66
67
  self._last_used: float = 0.0
67
68
  self._idle_timer: threading.Timer | None = None
68
69
  self._worker_ready = False
70
+ self._request_count: int = 0
69
71
 
70
72
  @property
71
73
  def is_available(self) -> bool:
@@ -144,6 +146,13 @@ class EmbeddingService:
144
146
  never hangs indefinitely on cold model loads or network issues.
145
147
  """
146
148
  with self._lock:
149
+ # Worker recycling: restart after N requests to prevent
150
+ # C++ allocator fragmentation over long-running sessions.
151
+ if self._request_count >= _WORKER_RECYCLE_AFTER and self._worker_proc is not None:
152
+ logger.info("Recycling embedding worker after %d requests", self._request_count)
153
+ self._kill_worker()
154
+ self._request_count = 0
155
+
147
156
  self._ensure_worker()
148
157
  if self._worker_proc is None:
149
158
  return None
@@ -176,6 +185,7 @@ class EmbeddingService:
176
185
  logger.warning("Worker error: %s", resp.get("error"))
177
186
  return None
178
187
  self._reset_idle_timer()
188
+ self._request_count += 1
179
189
  return resp["vectors"]
180
190
  except (BrokenPipeError, OSError, json.JSONDecodeError) as exc:
181
191
  logger.warning(
@@ -235,6 +245,7 @@ class EmbeddingService:
235
245
  text=True,
236
246
  bufsize=1,
237
247
  env=env,
248
+ start_new_session=True, # Prevent terminal signals bleeding to worker
238
249
  )
239
250
  logger.info("Embedding worker spawned (PID %d)", self._worker_proc.pid)
240
251
  self._worker_ready = True
@@ -437,7 +437,10 @@ def init_retrieval(
437
437
 
438
438
  reranker = None
439
439
  if config.retrieval.use_cross_encoder:
440
- reranker = CrossEncoderReranker(config.retrieval.cross_encoder_model)
440
+ reranker = CrossEncoderReranker(
441
+ config.retrieval.cross_encoder_model,
442
+ backend=config.retrieval.cross_encoder_backend,
443
+ )
441
444
 
442
445
  profile_ch = ProfileChannel(db)
443
446
  bridge = BridgeDiscovery(db)
@@ -68,7 +68,7 @@ MODE_A = ModeCapabilities(
68
68
  description=(
69
69
  "Local Guardian — Zero LLM, zero cloud. "
70
70
  "Uses nomic-embed-text-v1.5 encoder (768d, 8K context) for embeddings. "
71
- "spaCy + rules for extraction. Cross-encoder for reranking. "
71
+ "spaCy + rules for extraction. ONNX cross-encoder reranking (~200MB). "
72
72
  "Full EU AI Act compliance. Target: 65%+"
73
73
  ),
74
74
  )
@@ -89,6 +89,7 @@ MODE_B = ModeCapabilities(
89
89
  description=(
90
90
  "Smart Local — Local Ollama LLM (Phi-3, Llama 3.2). "
91
91
  "LLM-quality extraction and classification, fully local. "
92
+ "ONNX cross-encoder reranking (~200MB). "
92
93
  "No cloud, no data export. EU AI Act compliant. Target: 75-80%"
93
94
  ),
94
95
  )
@@ -18,6 +18,7 @@ from __future__ import annotations
18
18
 
19
19
  import json
20
20
  import os
21
+ import signal
21
22
  import sys
22
23
 
23
24
  # Force CPU BEFORE any torch import
@@ -28,6 +29,11 @@ os.environ["PYTORCH_ENABLE_MPS_FALLBACK"] = "1"
28
29
  os.environ["TOKENIZERS_PARALLELISM"] = "false"
29
30
  os.environ["TORCH_DEVICE"] = "cpu"
30
31
 
32
+ # SIGTERM bridge: Docker/systemd send SIGTERM to stop processes.
33
+ # Without this, the worker ignores SIGTERM and becomes a zombie.
34
+ if sys.platform != "win32":
35
+ signal.signal(signal.SIGTERM, lambda *_: sys.exit(0))
36
+
31
37
  _engine = None
32
38
 
33
39
 
@@ -223,14 +229,14 @@ def _worker_main() -> None:
223
229
  continue
224
230
 
225
231
  if cmd == "warmup":
226
- # Pre-load engine + all models (embedding, reranker, BM25, LLM)
227
- # Called at dashboard/MCP startup so first real request is fast.
228
- # A dummy recall triggers lazy-loaded components (cross-encoder, BM25 index).
232
+ # Pre-load engine + database + embeddings only.
233
+ # V3.3.2: Do NOT run a dummy recall it triggers the ONNX
234
+ # cross-encoder export (~30s) which combined with engine init
235
+ # exceeds the worker timeout. The cross-encoder loads lazily
236
+ # in a background thread on the first real recall instead.
229
237
  try:
230
238
  engine = _get_engine()
231
239
  fact_count = engine._db.get_fact_count(engine._profile_id) if engine._db else 0
232
- if fact_count > 0:
233
- engine.recall("warmup", limit=1)
234
240
  _respond({"ok": True, "message": "Engine warm", "facts": fact_count})
235
241
  except Exception as exc:
236
242
  _respond({"ok": False, "error": f"Warmup failed: {exc}"})
@@ -29,8 +29,9 @@ import time
29
29
  logger = logging.getLogger(__name__)
30
30
 
31
31
  _IDLE_TIMEOUT = 120 # 2 min — kill worker after idle
32
- _REQUEST_TIMEOUT = 60 # 60 sec max per request
33
- _WARMUP_TIMEOUT = 120 # 2 min — first cold start loads PyTorch + models
32
+ _REQUEST_TIMEOUT = 120 # 120 sec per request (V3.3.2: ONNX cold start can take 30-60s)
33
+ _WARMUP_TIMEOUT = 180 # 3 min — first cold start: engine + ONNX export + models
34
+ _WORKER_RECYCLE_AFTER = 1000 # Recycle worker after N requests (C++ fragmentation prevention)
34
35
 
35
36
 
36
37
  class WorkerPool:
@@ -49,6 +50,7 @@ class WorkerPool:
49
50
  self._proc: subprocess.Popen | None = None
50
51
  self._idle_timer: threading.Timer | None = None
51
52
  self._last_used: float = 0.0
53
+ self._request_count: int = 0
52
54
 
53
55
  @classmethod
54
56
  def shared(cls) -> WorkerPool:
@@ -146,6 +148,13 @@ class WorkerPool:
146
148
  def _send_with_timeout(self, request: dict, timeout: float) -> dict:
147
149
  """Send request with configurable timeout. Thread-safe."""
148
150
  with self._lock:
151
+ # Worker recycling: restart after N requests to prevent
152
+ # C++ allocator fragmentation over long-running sessions.
153
+ if self._request_count >= _WORKER_RECYCLE_AFTER and self._proc is not None:
154
+ logger.info("Recycling recall worker after %d requests", self._request_count)
155
+ self._kill()
156
+ self._request_count = 0
157
+
149
158
  self._ensure_worker()
150
159
  if self._proc is None:
151
160
  return {"ok": False, "error": "Worker failed to start"}
@@ -168,6 +177,7 @@ class WorkerPool:
168
177
  return {"ok": False, "error": "Worker died"}
169
178
 
170
179
  self._reset_idle_timer()
180
+ self._request_count += 1
171
181
  return json.loads(resp_line)
172
182
 
173
183
  except (BrokenPipeError, OSError, json.JSONDecodeError) as exc:
@@ -227,6 +237,7 @@ class WorkerPool:
227
237
  text=True,
228
238
  bufsize=1,
229
239
  env=env,
240
+ start_new_session=True, # Prevent terminal signals bleeding to worker
230
241
  )
231
242
  logger.info("Recall worker spawned (PID %d)", self._proc.pid)
232
243
  except Exception as exc:
@@ -194,6 +194,7 @@ class IDEConnector:
194
194
  data["mcpServers"] = {}
195
195
 
196
196
  data["mcpServers"]["superlocalmemory"] = {
197
+ "type": "stdio",
197
198
  "command": "slm",
198
199
  "args": ["mcp"],
199
200
  "enabled": True,