surreal-memory 2.3.2__tar.gz → 2.5.0__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 (383) hide show
  1. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/PKG-INFO +5 -5
  2. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/README.md +2 -2
  3. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/pyproject.toml +2 -2
  4. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/__init__.py +1 -1
  5. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/config_cmd.py +1 -1
  6. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/config_presets.py +23 -1
  7. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/core/fiber.py +5 -0
  8. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/core/synapse.py +2 -0
  9. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/brain_transplant.py +8 -3
  10. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/consolidation.py +9 -3
  11. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/embedding/gemini_embedding.py +24 -4
  12. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/encoder.py +9 -0
  13. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/pipeline.py +6 -0
  14. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/pipeline_steps.py +3 -0
  15. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/hooks/post_tool_use.py +101 -49
  16. surreal_memory-2.5.0/src/surreal_memory/mcp/offload_handler.py +202 -0
  17. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/recall_handler.py +85 -0
  18. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/remember_handler.py +4 -0
  19. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/server.py +35 -2
  20. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/session_handler.py +135 -6
  21. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/tool_handler_utils.py +6 -1
  22. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/tool_handlers.py +2 -0
  23. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/tool_schemas.py +71 -0
  24. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/routes/dashboard_api.py +86 -0
  25. surreal_memory-2.3.2/src/surreal_memory/server/static/dist/assets/DiagramsPage-DxR1C_Ua.js → surreal_memory-2.5.0/src/surreal_memory/server/static/dist/assets/DiagramsPage-DbhaKtcI.js +1 -1
  26. surreal_memory-2.3.2/src/surreal_memory/server/static/dist/assets/EvolutionPage-By828lS5.js → surreal_memory-2.5.0/src/surreal_memory/server/static/dist/assets/EvolutionPage-CzD9dgSX.js +1 -1
  27. surreal_memory-2.3.2/src/surreal_memory/server/static/dist/assets/GraphPage-DwQB1_DY.js → surreal_memory-2.5.0/src/surreal_memory/server/static/dist/assets/GraphPage-CrI1ELz_.js +1 -1
  28. surreal_memory-2.3.2/src/surreal_memory/server/static/dist/assets/HealthPage-DetJg-Qr.js → surreal_memory-2.5.0/src/surreal_memory/server/static/dist/assets/HealthPage-9CH7uxp0.js +1 -1
  29. surreal_memory-2.3.2/src/surreal_memory/server/static/dist/assets/OraclePage-7FBeVFXa.js → surreal_memory-2.5.0/src/surreal_memory/server/static/dist/assets/OraclePage--QnA7bus.js +1 -1
  30. surreal_memory-2.3.2/src/surreal_memory/server/static/dist/assets/OverviewPage-xe8kFqX3.js → surreal_memory-2.5.0/src/surreal_memory/server/static/dist/assets/OverviewPage-uovTY60B.js +1 -1
  31. surreal_memory-2.3.2/src/surreal_memory/server/static/dist/assets/ProGate-CwBF4etn.js → surreal_memory-2.5.0/src/surreal_memory/server/static/dist/assets/ProGate-37WFbaAW.js +1 -1
  32. surreal_memory-2.3.2/src/surreal_memory/server/static/dist/assets/SettingsPage-CH2mIMiD.js → surreal_memory-2.5.0/src/surreal_memory/server/static/dist/assets/SettingsPage-BwQ0sSKJ.js +1 -1
  33. surreal_memory-2.5.0/src/surreal_memory/server/static/dist/assets/StoragePage-Dfp1G5qu.js +1 -0
  34. surreal_memory-2.3.2/src/surreal_memory/server/static/dist/assets/SyncPage-MbtH1dwD.js → surreal_memory-2.5.0/src/surreal_memory/server/static/dist/assets/SyncPage-CNbeBod6.js +1 -1
  35. surreal_memory-2.3.2/src/surreal_memory/server/static/dist/assets/TimelinePage-BIybkdH4.js → surreal_memory-2.5.0/src/surreal_memory/server/static/dist/assets/TimelinePage-C2MQrnce.js +1 -1
  36. surreal_memory-2.3.2/src/surreal_memory/server/static/dist/assets/ToolStatsPage-BA-DvxES.js → surreal_memory-2.5.0/src/surreal_memory/server/static/dist/assets/ToolStatsPage-zZWqg3RV.js +1 -1
  37. surreal_memory-2.3.2/src/surreal_memory/server/static/dist/assets/VisualizePage-B_IPrBGU.js → surreal_memory-2.5.0/src/surreal_memory/server/static/dist/assets/VisualizePage-D-CKRU7v.js +1 -1
  38. surreal_memory-2.3.2/src/surreal_memory/server/static/dist/assets/card-B0vNsxr_.js → surreal_memory-2.5.0/src/surreal_memory/server/static/dist/assets/card-CB2KYkrP.js +1 -1
  39. surreal_memory-2.5.0/src/surreal_memory/server/static/dist/assets/index-CWIfFh7B.css +1 -0
  40. surreal_memory-2.3.2/src/surreal_memory/server/static/dist/assets/index-C26pxqlr.js → surreal_memory-2.5.0/src/surreal_memory/server/static/dist/assets/index-DzyKsRxc.js +2 -2
  41. surreal_memory-2.3.2/src/surreal_memory/server/static/dist/assets/skeleton-DQJ-n00q.js → surreal_memory-2.5.0/src/surreal_memory/server/static/dist/assets/skeleton-B4zDkVHp.js +1 -1
  42. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/static/dist/index.html +2 -2
  43. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/base.py +2 -0
  44. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/memory_store.py +3 -0
  45. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/shared_store.py +7 -1
  46. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_synapses.py +6 -1
  47. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/projects.py +2 -0
  48. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/schema.py +17 -16
  49. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/sources.py +2 -0
  50. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/store.py +42 -28
  51. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/unified_config.py +119 -13
  52. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/utils/tag_normalizer.py +21 -0
  53. surreal_memory-2.3.2/src/surreal_memory/server/static/dist/assets/StoragePage-CLDPXEH8.js +0 -1
  54. surreal_memory-2.3.2/src/surreal_memory/server/static/dist/assets/index-BFkJgtCN.css +0 -1
  55. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/.gitignore +0 -0
  56. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/LICENSE +0 -0
  57. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/NOTICE +0 -0
  58. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/__init__.py +0 -0
  59. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/__main__.py +0 -0
  60. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/_helpers.py +0 -0
  61. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/__init__.py +0 -0
  62. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/brain.py +0 -0
  63. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/codebase.py +0 -0
  64. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/habits.py +0 -0
  65. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/info.py +0 -0
  66. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/listing.py +0 -0
  67. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/memory.py +0 -0
  68. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/project.py +0 -0
  69. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/reindex.py +0 -0
  70. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/shared.py +0 -0
  71. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/shortcuts.py +0 -0
  72. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/storage.py +0 -0
  73. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/telegram.py +0 -0
  74. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/tools.py +0 -0
  75. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/train.py +0 -0
  76. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/update.py +0 -0
  77. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/version.py +0 -0
  78. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/watch.py +0 -0
  79. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/config.py +0 -0
  80. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/doctor.py +0 -0
  81. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/embedding_setup.py +0 -0
  82. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/full_setup.py +0 -0
  83. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/graph_export.py +0 -0
  84. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/ide_rules.py +0 -0
  85. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/main.py +0 -0
  86. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/markdown_export.py +0 -0
  87. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/setup.py +0 -0
  88. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/storage.py +0 -0
  89. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/tui.py +0 -0
  90. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/update_check.py +0 -0
  91. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/wizard.py +0 -0
  92. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/core/__init__.py +0 -0
  93. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/core/action_event.py +0 -0
  94. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/core/alert.py +0 -0
  95. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/core/brain.py +0 -0
  96. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/core/brain_mode.py +0 -0
  97. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/core/eternal_context.py +0 -0
  98. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/core/memory_types.py +0 -0
  99. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/core/neuron.py +0 -0
  100. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/core/project.py +0 -0
  101. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/core/review_schedule.py +0 -0
  102. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/core/source.py +0 -0
  103. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/core/trigger_engine.py +0 -0
  104. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/__init__.py +0 -0
  105. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/activation.py +0 -0
  106. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/arousal.py +0 -0
  107. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/associative_inference.py +0 -0
  108. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/brain_evolution.py +0 -0
  109. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/brain_versioning.py +0 -0
  110. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/causal_traversal.py +0 -0
  111. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/chart_generator.py +0 -0
  112. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/chunking.py +0 -0
  113. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/citation.py +0 -0
  114. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/clustering.py +0 -0
  115. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/codebase_encoder.py +0 -0
  116. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/cognitive.py +0 -0
  117. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/compression.py +0 -0
  118. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/conflict_auto_resolve.py +0 -0
  119. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/conflict_detection.py +0 -0
  120. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/connection_explainer.py +0 -0
  121. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/consolidation_delta.py +0 -0
  122. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/context_merger.py +0 -0
  123. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/context_optimizer.py +0 -0
  124. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/context_retrieval.py +0 -0
  125. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/cross_brain.py +0 -0
  126. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/db_introspector.py +0 -0
  127. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/db_knowledge.py +0 -0
  128. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/db_trainer.py +0 -0
  129. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/decision_intel.py +0 -0
  130. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/dedup/__init__.py +0 -0
  131. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/dedup/config.py +0 -0
  132. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/dedup/llm_judge.py +0 -0
  133. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/dedup/pipeline.py +0 -0
  134. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/dedup/prompts.py +0 -0
  135. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/depth_prior.py +0 -0
  136. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/diagnostics.py +0 -0
  137. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/doc_chunker.py +0 -0
  138. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/doc_extractor.py +0 -0
  139. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/doc_trainer.py +0 -0
  140. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/dream.py +0 -0
  141. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/drift_detection.py +0 -0
  142. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/embedding/__init__.py +0 -0
  143. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/embedding/capability.py +0 -0
  144. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/embedding/config.py +0 -0
  145. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/embedding/ollama_embedding.py +0 -0
  146. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/embedding/openai_embedding.py +0 -0
  147. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/embedding/openrouter_embedding.py +0 -0
  148. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/embedding/provider.py +0 -0
  149. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/embedding/retry.py +0 -0
  150. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/embedding/sentence_transformer.py +0 -0
  151. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/enrichment.py +0 -0
  152. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/fidelity.py +0 -0
  153. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/file_watcher.py +0 -0
  154. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/fuzzy_match.py +0 -0
  155. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/fuzzy_query.py +0 -0
  156. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/gromov.py +0 -0
  157. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/hippocampal_replay.py +0 -0
  158. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/hooks.py +0 -0
  159. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/idf_anchor.py +0 -0
  160. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/importance.py +0 -0
  161. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/interference.py +0 -0
  162. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/koopman.py +0 -0
  163. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/learning_rule.py +0 -0
  164. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/lifecycle.py +0 -0
  165. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/memory_stages.py +0 -0
  166. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/merge.py +0 -0
  167. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/narrative.py +0 -0
  168. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/pattern_extraction.py +0 -0
  169. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/ppr_activation.py +0 -0
  170. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/prediction_error.py +0 -0
  171. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/priming.py +0 -0
  172. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/quality_scorer.py +0 -0
  173. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/query_expander.py +0 -0
  174. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/query_expansion.py +0 -0
  175. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/query_pattern_mining.py +0 -0
  176. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/reconsolidation.py +0 -0
  177. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/reconstruction.py +0 -0
  178. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/reflection.py +0 -0
  179. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/reflex_activation.py +0 -0
  180. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/reranker.py +0 -0
  181. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/retrieval.py +0 -0
  182. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/retrieval_context.py +0 -0
  183. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/retrieval_types.py +0 -0
  184. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/schema_assimilation.py +0 -0
  185. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/score_fusion.py +0 -0
  186. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/semantic_discovery.py +0 -0
  187. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/sequence_mining.py +0 -0
  188. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/session_state.py +0 -0
  189. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/spaced_repetition.py +0 -0
  190. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/stabilization.py +0 -0
  191. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/sufficiency.py +0 -0
  192. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/temporal_binding.py +0 -0
  193. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/tier_engine.py +0 -0
  194. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/token_budget.py +0 -0
  195. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/token_normalizer.py +0 -0
  196. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/tool_memory.py +0 -0
  197. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/topology_analysis.py +0 -0
  198. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/watch_state.py +0 -0
  199. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/workflow_suggest.py +0 -0
  200. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/write_queue.py +0 -0
  201. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/extraction/__init__.py +0 -0
  202. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/extraction/codebase.py +0 -0
  203. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/extraction/entities.py +0 -0
  204. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/extraction/keywords.py +0 -0
  205. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/extraction/llm_provider.py +0 -0
  206. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/extraction/parser.py +0 -0
  207. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/extraction/relations.py +0 -0
  208. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/extraction/router.py +0 -0
  209. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/extraction/sentiment.py +0 -0
  210. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/extraction/structure_detector.py +0 -0
  211. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/extraction/temporal.py +0 -0
  212. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/git_context.py +0 -0
  213. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/hooks/__init__.py +0 -0
  214. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/hooks/pre_compact.py +0 -0
  215. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/hooks/project_context.py +0 -0
  216. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/hooks/session_start.py +0 -0
  217. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/hooks/stop.py +0 -0
  218. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/hooks/task_context.py +0 -0
  219. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integration/__init__.py +0 -0
  220. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integration/adapter.py +0 -0
  221. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integration/adapters/__init__.py +0 -0
  222. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integration/adapters/awf_adapter.py +0 -0
  223. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integration/adapters/chromadb_adapter.py +0 -0
  224. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integration/adapters/cognee_adapter.py +0 -0
  225. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integration/adapters/graphiti_adapter.py +0 -0
  226. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integration/adapters/llamaindex_adapter.py +0 -0
  227. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integration/adapters/mem0_adapter.py +0 -0
  228. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integration/mapper.py +0 -0
  229. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integration/models.py +0 -0
  230. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integration/sync_engine.py +0 -0
  231. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integration/telegram.py +0 -0
  232. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integrations/__init__.py +0 -0
  233. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integrations/nanobot/__init__.py +0 -0
  234. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integrations/nanobot/base_tool.py +0 -0
  235. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integrations/nanobot/context.py +0 -0
  236. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integrations/nanobot/memory_store.py +0 -0
  237. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integrations/nanobot/protocol.py +0 -0
  238. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integrations/nanobot/setup.py +0 -0
  239. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integrations/nanobot/tools.py +0 -0
  240. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integrations/openclaw_config.py +0 -0
  241. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/__init__.py +0 -0
  242. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/__main__.py +0 -0
  243. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/alert_handler.py +0 -0
  244. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/auto_capture.py +0 -0
  245. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/auto_handler.py +0 -0
  246. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/budget_handler.py +0 -0
  247. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/cognitive_handler.py +0 -0
  248. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/conflict_handler.py +0 -0
  249. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/connection_handler.py +0 -0
  250. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/constants.py +0 -0
  251. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/db_train_handler.py +0 -0
  252. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/drift_handler.py +0 -0
  253. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/eternal_handler.py +0 -0
  254. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/evolution_handler.py +0 -0
  255. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/expiry_cleanup_handler.py +0 -0
  256. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/http_transport.py +0 -0
  257. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/index_handler.py +0 -0
  258. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/instruction_handler.py +0 -0
  259. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/lifecycle_handler.py +0 -0
  260. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/maintenance_handler.py +0 -0
  261. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/mem0_sync_handler.py +0 -0
  262. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/narrative_handler.py +0 -0
  263. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/onboarding_handler.py +0 -0
  264. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/prompt.py +0 -0
  265. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/provenance_handler.py +0 -0
  266. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/response_compactor.py +0 -0
  267. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/review_handler.py +0 -0
  268. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/scheduled_consolidation_handler.py +0 -0
  269. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/stats_handler.py +0 -0
  270. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/surface_handler.py +0 -0
  271. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/sync_handler.py +0 -0
  272. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/telegram_handler.py +0 -0
  273. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/tier_handler.py +0 -0
  274. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/train_handler.py +0 -0
  275. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/version_check_handler.py +0 -0
  276. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/visualize_handler.py +0 -0
  277. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/watch_handler.py +0 -0
  278. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/plugins/__init__.py +0 -0
  279. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/plugins/base.py +0 -0
  280. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/plugins/community.py +0 -0
  281. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/py.typed +0 -0
  282. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/safety/__init__.py +0 -0
  283. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/safety/encryption.py +0 -0
  284. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/safety/freshness.py +0 -0
  285. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/safety/input_firewall.py +0 -0
  286. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/safety/sensitive.py +0 -0
  287. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/__init__.py +0 -0
  288. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/app.py +0 -0
  289. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/dependencies.py +0 -0
  290. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/models.py +0 -0
  291. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/routes/__init__.py +0 -0
  292. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/routes/brain.py +0 -0
  293. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/routes/consolidation.py +0 -0
  294. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/routes/hub.py +0 -0
  295. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/routes/integration_status.py +0 -0
  296. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/routes/memory.py +0 -0
  297. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/routes/oauth.py +0 -0
  298. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/routes/openclaw_api.py +0 -0
  299. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/routes/sync.py +0 -0
  300. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/static/dist/assets/DiagramsPage-BZV40eAE.css +0 -0
  301. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/static/dist/assets/embed-gLOWnRXV.js +0 -0
  302. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/static/dist/assets/timer-DWAvo6M8.js +0 -0
  303. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/static/dist/assets/vendor-icons-BYlYobEK.js +0 -0
  304. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/static/dist/assets/vendor-motion-Ct_HHbYW.js +0 -0
  305. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/static/dist/assets/vendor-query-CqA1cBNl.js +0 -0
  306. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/static/dist/assets/vendor-react-BfuodpLv.js +0 -0
  307. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/static/dist/assets/vendor-recharts-BkwZfCWA.js +0 -0
  308. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/static/dist/assets/vendor-ui-Qm4_4bAc.js +0 -0
  309. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/skills/__init__.py +0 -0
  310. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/skills/memory-audit/SKILL.md +0 -0
  311. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/skills/memory-evolution/SKILL.md +0 -0
  312. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/skills/memory-intake/SKILL.md +0 -0
  313. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/__init__.py +0 -0
  314. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/factory.py +0 -0
  315. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/memory_brain_ops.py +0 -0
  316. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/memory_collections.py +0 -0
  317. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/memory_reviews.py +0 -0
  318. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/neuron_cache.py +0 -0
  319. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/read_pool.py +0 -0
  320. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/shared_store_collections.py +0 -0
  321. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/shared_store_mappers.py +0 -0
  322. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_action_log.py +0 -0
  323. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_alerts.py +0 -0
  324. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_brain_ops.py +0 -0
  325. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_calibration.py +0 -0
  326. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_change_log.py +0 -0
  327. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_coactivation.py +0 -0
  328. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_cognitive.py +0 -0
  329. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_compression.py +0 -0
  330. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_depth_priors.py +0 -0
  331. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_devices.py +0 -0
  332. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_drift.py +0 -0
  333. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_entity_refs.py +0 -0
  334. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_fibers.py +0 -0
  335. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_maturation.py +0 -0
  336. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_merkle.py +0 -0
  337. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_neurons.py +0 -0
  338. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_projects.py +0 -0
  339. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_reviews.py +0 -0
  340. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_row_mappers.py +0 -0
  341. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_schema.py +0 -0
  342. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_sessions.py +0 -0
  343. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_sources.py +0 -0
  344. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_store.py +0 -0
  345. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_sync_state.py +0 -0
  346. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_tool_events.py +0 -0
  347. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_training_files.py +0 -0
  348. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_typed.py +0 -0
  349. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_versioning.py +0 -0
  350. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/__init__.py +0 -0
  351. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/activity.py +0 -0
  352. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/alerts.py +0 -0
  353. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/cognitive.py +0 -0
  354. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/compression.py +0 -0
  355. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/connection.py +0 -0
  356. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/depth_priors.py +0 -0
  357. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/keyword_entity.py +0 -0
  358. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/review_schedules.py +0 -0
  359. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/tool_events.py +0 -0
  360. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/typed_memory.py +0 -0
  361. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/versions.py +0 -0
  362. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/surface/__init__.py +0 -0
  363. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/surface/generator.py +0 -0
  364. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/surface/lifecycle.py +0 -0
  365. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/surface/models.py +0 -0
  366. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/surface/parser.py +0 -0
  367. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/surface/resolver.py +0 -0
  368. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/surface/serializer.py +0 -0
  369. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/surface/token_budget.py +0 -0
  370. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/sync/__init__.py +0 -0
  371. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/sync/client.py +0 -0
  372. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/sync/device.py +0 -0
  373. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/sync/incremental_merge.py +0 -0
  374. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/sync/merkle.py +0 -0
  375. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/sync/protocol.py +0 -0
  376. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/sync/sync_engine.py +0 -0
  377. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/utils/__init__.py +0 -0
  378. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/utils/config.py +0 -0
  379. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/utils/consolidation_lock.py +0 -0
  380. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/utils/sandbox.py +0 -0
  381. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/utils/simhash.py +0 -0
  382. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/utils/ssl_helper.py +0 -0
  383. {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/utils/timeutils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: surreal-memory
3
- Version: 2.3.2
3
+ Version: 2.5.0
4
4
  Summary: Reflex-based memory system for AI agents with SurrealDB backend — retrieval through activation, not search
5
5
  Project-URL: Homepage, https://github.com/acidkill/surreal-memory
6
6
  Project-URL: Documentation, https://github.com/acidkill/surreal-memory/blob/main/docs/getting-started/quickstart.md
@@ -38,7 +38,7 @@ Requires-Dist: mem0ai>=0.1.0; extra == 'all'
38
38
  Requires-Dist: python-multipart>=0.0.22; extra == 'all'
39
39
  Requires-Dist: pyvi>=0.1; extra == 'all'
40
40
  Requires-Dist: spacy>=3.6; extra == 'all'
41
- Requires-Dist: surrealdb>=0.4.0; extra == 'all'
41
+ Requires-Dist: surrealdb<3.0.0,>=2.0.0; extra == 'all'
42
42
  Requires-Dist: underthesea>=6.0; extra == 'all'
43
43
  Requires-Dist: uvicorn[standard]>=0.23; extra == 'all'
44
44
  Provides-Extra: chromadb
@@ -104,7 +104,7 @@ Requires-Dist: httpx>=0.24; extra == 'server'
104
104
  Requires-Dist: python-multipart>=0.0.22; extra == 'server'
105
105
  Requires-Dist: uvicorn[standard]>=0.23; extra == 'server'
106
106
  Provides-Extra: surrealdb
107
- Requires-Dist: surrealdb>=0.4.0; extra == 'surrealdb'
107
+ Requires-Dist: surrealdb<3.0.0,>=2.0.0; extra == 'surrealdb'
108
108
  Provides-Extra: watch
109
109
  Requires-Dist: watchdog>=4.0.0; extra == 'watch'
110
110
  Description-Content-Type: text/markdown
@@ -217,7 +217,7 @@ smem recall "auth bug"
217
217
 
218
218
  ## 3 Tools. That's It.
219
219
 
220
- 53 MCP tools are available, but you only need three:
220
+ 56 MCP tools are available, but you only need three:
221
221
 
222
222
  | Tool | What it does |
223
223
  |------|-------------|
@@ -233,7 +233,7 @@ Everything else — sessions, context loading, habit tracking, maintenance — w
233
233
 
234
234
  ```
235
235
  ┌──────────────────────────────┐
236
- │ MCP Server (53 tools) │
236
+ │ MCP Server (56 tools) │
237
237
  └──────────┬───────────────────┘
238
238
 
239
239
  ┌──────────▼───────────────────┐
@@ -106,7 +106,7 @@ smem recall "auth bug"
106
106
 
107
107
  ## 3 Tools. That's It.
108
108
 
109
- 53 MCP tools are available, but you only need three:
109
+ 56 MCP tools are available, but you only need three:
110
110
 
111
111
  | Tool | What it does |
112
112
  |------|-------------|
@@ -122,7 +122,7 @@ Everything else — sessions, context loading, habit tracking, maintenance — w
122
122
 
123
123
  ```
124
124
  ┌──────────────────────────────┐
125
- │ MCP Server (53 tools) │
125
+ │ MCP Server (56 tools) │
126
126
  └──────────┬───────────────────┘
127
127
 
128
128
  ┌──────────▼───────────────────┐
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "surreal-memory"
7
- version = "2.3.2"
7
+ version = "2.5.0"
8
8
  description = "Reflex-based memory system for AI agents with SurrealDB backend — retrieval through activation, not search"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -52,7 +52,7 @@ server = [
52
52
  "httpx>=0.24",
53
53
  ]
54
54
  surrealdb = [
55
- "surrealdb>=0.4.0",
55
+ "surrealdb>=2.0.0,<3.0.0",
56
56
  ]
57
57
  encryption = [
58
58
  "cryptography>=46.0.5",
@@ -16,7 +16,7 @@ from surreal_memory.engine.encoder import EncodingResult, MemoryEncoder
16
16
  from surreal_memory.engine.reflex_activation import CoActivation, ReflexActivation
17
17
  from surreal_memory.engine.retrieval import DepthLevel, ReflexPipeline, RetrievalResult
18
18
 
19
- __version__ = "2.3.2"
19
+ __version__ = "2.5.0"
20
20
 
21
21
  __all__ = [
22
22
  "__version__",
@@ -13,7 +13,7 @@ config_app = typer.Typer(help="Configuration management")
13
13
  def preset_cmd(
14
14
  name: Annotated[
15
15
  str,
16
- typer.Argument(help="Preset name: safe-cost, balanced, max-recall"),
16
+ typer.Argument(help="Preset name: safe-cost, balanced, max-recall, chat-heavy"),
17
17
  ] = "",
18
18
  list_available: Annotated[
19
19
  bool,
@@ -1,6 +1,6 @@
1
1
  """Static configuration presets for Surreal-Memory.
2
2
 
3
- Three built-in profiles that configure brain behavior, maintenance,
3
+ Four built-in profiles that configure brain behavior, maintenance,
4
4
  and retrieval for different use cases. Presets are static dicts
5
5
  (not a plugin system) to keep the surface simple and predictable.
6
6
 
@@ -82,16 +82,38 @@ MAX_RECALL: dict[str, dict[str, Any]] = {
82
82
  },
83
83
  }
84
84
 
85
+ CHAT_HEAVY: dict[str, dict[str, Any]] = {
86
+ "brain": {
87
+ "decay_rate": 0.15,
88
+ "reinforcement_delta": 0.05,
89
+ "activation_threshold": 0.25,
90
+ "max_spread_hops": 3,
91
+ "max_context_tokens": 800,
92
+ "freshness_weight": 0.25,
93
+ },
94
+ "maintenance": {
95
+ "auto_consolidate": True,
96
+ "check_interval": 20,
97
+ "auto_consolidate_strategies": ["prune", "merge"],
98
+ "consolidate_cooldown_minutes": 20,
99
+ },
100
+ "eternal": {
101
+ "max_context_tokens": 64_000,
102
+ },
103
+ }
104
+
85
105
  _PRESETS: dict[str, dict[str, dict[str, Any]]] = {
86
106
  "safe-cost": SAFE_COST,
87
107
  "balanced": BALANCED,
88
108
  "max-recall": MAX_RECALL,
109
+ "chat-heavy": CHAT_HEAVY,
89
110
  }
90
111
 
91
112
  _DESCRIPTIONS: dict[str, str] = {
92
113
  "safe-cost": "Lower token usage, faster decay, aggressive pruning",
93
114
  "balanced": "Default settings — good all-around performance",
94
115
  "max-recall": "Maximum retention, deeper retrieval, conservative pruning",
116
+ "chat-heavy": "Conversational agents (Telegram/Discord/Slack) — fast decay, recent-biased, compact",
95
117
  }
96
118
 
97
119
 
@@ -7,6 +7,7 @@ from datetime import datetime
7
7
  from typing import Any
8
8
  from uuid import uuid4
9
9
 
10
+ from surreal_memory.utils.tag_normalizer import normalize_tags_lower
10
11
  from surreal_memory.utils.timeutils import utcnow
11
12
 
12
13
 
@@ -125,6 +126,10 @@ class Fiber:
125
126
  if tags is not None and not auto_tags and not agent_tags:
126
127
  effective_agent = tags
127
128
 
129
+ # Normalize case at ingestion boundary so storage is always lowercase
130
+ effective_auto = normalize_tags_lower(effective_auto)
131
+ effective_agent = normalize_tags_lower(effective_agent)
132
+
128
133
  return cls(
129
134
  id=fiber_id or str(uuid4()),
130
135
  neuron_ids=neuron_ids,
@@ -94,6 +94,8 @@ class Direction(StrEnum):
94
94
 
95
95
  UNIDIRECTIONAL = "uni" # One-way: source -> target
96
96
  BIDIRECTIONAL = "bi" # Two-way: source <-> target
97
+ FORWARD = "forward" # legacy rows; also _row_to_synapse default in surrealdb store
98
+ BACKWARD = "backward" # legacy rows: target -> source
97
99
 
98
100
 
99
101
  # Synapse types that are typically bidirectional
@@ -79,9 +79,14 @@ def _fiber_matches_tags(
79
79
  fiber: dict[str, Any],
80
80
  required_tags: frozenset[str],
81
81
  ) -> bool:
82
- """Return True if the fiber carries ANY of the required tags."""
83
- fiber_tags = set(fiber.get("tags", []))
84
- return bool(fiber_tags & required_tags)
82
+ """Return True if the fiber carries ANY of the required tags.
83
+
84
+ Both the fiber's tags and the query tags are lowercased before comparison
85
+ so that "KB" matches a fiber tagged "kb" regardless of original casing.
86
+ """
87
+ fiber_tags = {t.lower() for t in fiber.get("tags", [])}
88
+ normalized_required = frozenset(t.lower() for t in required_tags)
89
+ return bool(fiber_tags & normalized_required)
85
90
 
86
91
 
87
92
  def _fiber_matches_salience(
@@ -598,6 +598,14 @@ class ConsolidationEngine:
598
598
  states = await self._storage.get_neuron_states_batch(batch_ids)
599
599
 
600
600
  for neuron in batch:
601
+ # Never auto-prune pinned neurons, whether isolated (orphan) or
602
+ # dead. The dead-neuron path already honored pinned, but the
603
+ # orphan path short-circuited above it, so pinned isolated
604
+ # neurons were permanently deleted. Hoist the guard so it
605
+ # protects both paths.
606
+ if neuron.id in pinned_neuron_ids:
607
+ continue
608
+
601
609
  is_orphan = (
602
610
  neuron.id not in connected_neuron_ids and neuron.id not in fiber_neuron_ids
603
611
  )
@@ -606,9 +614,7 @@ class ConsolidationEngine:
606
614
  orphan_ids.append(neuron.id)
607
615
  continue
608
616
 
609
- # Dead neuron: has connections but never accessed, old enough, not pinned
610
- if neuron.id in pinned_neuron_ids:
611
- continue
617
+ # Dead neuron: has connections but never accessed, old enough
612
618
  state = states.get(neuron.id)
613
619
  freq = state.access_frequency if state else 0
614
620
  if freq > 0:
@@ -61,7 +61,21 @@ class GeminiEmbedding(EmbeddingProvider):
61
61
  "Install it with: pip install 'surreal-memory[embeddings-gemini]'"
62
62
  ) from exc
63
63
 
64
- self._client = genai.Client(api_key=self._api_key)
64
+ # Optional gateway routing: honour GOOGLE_GEMINI_BASE_URL (the
65
+ # SDK env var) but build the client explicitly, because our
66
+ # gateway path already pins the API version — api_version must be
67
+ # emptied or the SDK doubles it ('/v1beta/v1beta/...').
68
+ base_url = os.getenv("GOOGLE_GEMINI_BASE_URL")
69
+ if base_url:
70
+ self._client = genai.Client(
71
+ api_key=self._api_key,
72
+ http_options={
73
+ "base_url": base_url,
74
+ "api_version": os.getenv("GOOGLE_GEMINI_API_VERSION", ""),
75
+ },
76
+ )
77
+ else:
78
+ self._client = genai.Client(api_key=self._api_key)
65
79
 
66
80
  return self._client
67
81
 
@@ -94,13 +108,19 @@ class GeminiEmbedding(EmbeddingProvider):
94
108
  batch_size = 100
95
109
  for i in range(0, len(texts), batch_size):
96
110
  chunk = texts[i : i + batch_size]
97
- # functools.partial binds `chunk` at creation (satisfies ruff B023,
98
- # no loop-var late binding) and types cleanly for mypy.
111
+ # google-genai >= 2.0 folds a plain list[str] into ONE multi-part
112
+ # content (N texts -> 1 embedding); give each text its own content
113
+ # so the API returns one embedding per text. Plain ContentDicts are
114
+ # used instead of types.Content to avoid importing google.genai here
115
+ # (keeps this path working when the SDK is mocked/absent in tests).
116
+ chunk_contents = [{"parts": [{"text": t}]} for t in chunk]
117
+ # functools.partial binds the chunk at creation (satisfies ruff
118
+ # B023, no loop-var late binding) and types cleanly for mypy.
99
119
  response = await call_with_retry(
100
120
  partial(
101
121
  client.aio.models.embed_content,
102
122
  model=self._model,
103
- contents=chunk,
123
+ contents=chunk_contents,
104
124
  config={"task_type": self._task_type},
105
125
  ),
106
126
  provider="gemini",
@@ -64,6 +64,9 @@ class EncodingResult:
64
64
  neurons_created: List of newly created neurons
65
65
  neurons_linked: List of existing neuron IDs that were linked
66
66
  synapses_created: List of newly created synapses
67
+ extraction_stats: Optional concept-extraction counters when callers
68
+ opt in via verbose_extraction. Surface schema:
69
+ ``{"dropped_short", "dropped_noise", "dropped_duplicate_entity"}``.
67
70
  """
68
71
 
69
72
  fiber: Fiber
@@ -71,6 +74,7 @@ class EncodingResult:
71
74
  neurons_linked: list[str]
72
75
  synapses_created: list[Synapse]
73
76
  conflicts_detected: int = 0
77
+ extraction_stats: dict[str, int] | None = None
74
78
 
75
79
 
76
80
  def build_default_pipeline(
@@ -432,6 +436,11 @@ class MemoryEncoder:
432
436
  neurons_linked=ctx.neurons_linked,
433
437
  synapses_created=ctx.synapses_created,
434
438
  conflicts_detected=ctx.conflicts_detected,
439
+ extraction_stats={
440
+ "dropped_short": ctx.dropped_short,
441
+ "dropped_noise": ctx.dropped_noise,
442
+ "dropped_duplicate_entity": ctx.dropped_duplicate_entity,
443
+ },
435
444
  )
436
445
 
437
446
  async def _post_encode_neuro(self, anchor: Neuron) -> None:
@@ -72,6 +72,12 @@ class PipelineContext:
72
72
  # Entities stored here are first-mentions — not yet promoted to neurons
73
73
  deferred_entity_refs: list[str] = field(default_factory=list)
74
74
 
75
+ # Concept extraction observability — incremented by ExtractConceptNeuronsStep.
76
+ # Surfaced through EncodingResult.extraction_stats only when callers opt in.
77
+ dropped_short: int = 0
78
+ dropped_noise: int = 0
79
+ dropped_duplicate_entity: int = 0
80
+
75
81
 
76
82
  @runtime_checkable
77
83
  class PipelineStep(Protocol):
@@ -320,11 +320,14 @@ class ExtractConceptNeuronsStep:
320
320
  kw_lower = kw.lower()
321
321
  # Minimum 4 chars — 3-char words produce too many noise concepts ("ai", "os")
322
322
  if len(kw_lower) < 4:
323
+ ctx.dropped_short += 1
323
324
  return False
324
325
  if kw_lower in _NOISE_CONCEPTS:
326
+ ctx.dropped_noise += 1
325
327
  return False
326
328
  # Skip if already captured as an entity neuron
327
329
  if kw_lower in entity_content:
330
+ ctx.dropped_duplicate_entity += 1
328
331
  return False
329
332
  return True
330
333
 
@@ -7,8 +7,15 @@ Usage as Claude Code hook:
7
7
  Receives JSON on stdin with tool_name, tool_input, tool_output fields.
8
8
  Writes one JSONL line to ~/.surrealmemory/tool_events.jsonl.
9
9
 
10
- This hook does NOT access SQLite or perform encoding — all processing
10
+ This hook does NOT access SurrealDB or perform encoding — all processing
11
11
  is deferred to the consolidation cycle.
12
+
13
+ Performance design (ac2a001 perf subset):
14
+ - Zero heavy imports on the hot path (stdlib only except optional tomllib)
15
+ - _NOISE_TOOLS fast-path skips the highest-frequency no-value tools
16
+ - Lock-safe JSONL append via fcntl.flock (POSIX) with a write-then-rename
17
+ fallback for platforms without flock
18
+ - Session ID: checks CLAUDE_SESSION_ID and CODEX_SESSION_ID
12
19
  """
13
20
 
14
21
  from __future__ import annotations
@@ -18,6 +25,7 @@ import logging
18
25
  import os
19
26
  import sys
20
27
  import time
28
+ from datetime import UTC, datetime
21
29
  from pathlib import Path
22
30
  from typing import Any
23
31
 
@@ -28,6 +36,29 @@ _MAX_ARGS_CHARS = 200
28
36
  # Max size for stdout response JSON
29
37
  _MAX_TOOL_OUTPUT_PREVIEW = 100
30
38
 
39
+ # High-frequency tools that never produce useful memory signal.
40
+ # Checked before any config I/O for a fast zero-cost exit.
41
+ _NOISE_TOOLS: frozenset[str] = frozenset(
42
+ {
43
+ "TodoRead",
44
+ "TodoWrite",
45
+ "WebSearch",
46
+ "WebFetch",
47
+ "mcp__Claude_Preview__preview_logs",
48
+ "mcp__Claude_Preview__preview_console_logs",
49
+ "mcp__Claude_Preview__preview_network",
50
+ "smem_recall",
51
+ "smem_session",
52
+ "smem_stats",
53
+ "smem_index",
54
+ }
55
+ )
56
+
57
+
58
+ def _get_session_id() -> str:
59
+ """Return the current session ID from env (Claude or Codex)."""
60
+ return os.environ.get("CLAUDE_SESSION_ID") or os.environ.get("CODEX_SESSION_ID", "")
61
+
31
62
 
32
63
  def _read_stdin() -> dict[str, Any]:
33
64
  """Read Claude Code PostToolUse hook JSON from stdin."""
@@ -41,49 +72,50 @@ def _read_stdin() -> dict[str, Any]:
41
72
  return {}
42
73
 
43
74
 
75
+ def _get_data_dir() -> Path:
76
+ """Return the surreal-memory data directory."""
77
+ custom = os.environ.get("SURREAL_MEMORY_DIR", "")
78
+ return Path(custom) if custom else (Path.home() / ".surrealmemory")
79
+
80
+
44
81
  def _get_buffer_path() -> Path:
45
82
  """Get the JSONL buffer file path."""
46
- data_dir = Path(os.environ.get("SURREAL_MEMORY_DIR", "")) or (Path.home() / ".surrealmemory")
47
- return data_dir / "tool_events.jsonl"
83
+ return _get_data_dir() / "tool_events.jsonl"
48
84
 
49
85
 
50
- def _is_enabled() -> bool:
51
- """Quick check if tool memory is enabled via config.
86
+ def _read_tool_memory_config() -> dict[str, Any]:
87
+ """Read [tool_memory] section from config.toml once.
52
88
 
53
- Reads only the [tool_memory] section from config.toml.
54
- Defaults to True if config is missing or section absent.
89
+ Returns an empty dict if the config is missing, unreadable, or
90
+ the section is absent. Called at most once per hook invocation.
55
91
  """
56
- data_dir = Path(os.environ.get("SURREAL_MEMORY_DIR", "")) or (Path.home() / ".surrealmemory")
57
- config_path = data_dir / "config.toml"
92
+ config_path = _get_data_dir() / "config.toml"
58
93
  if not config_path.exists():
59
- return True
94
+ return {}
60
95
  try:
61
96
  import tomllib
62
97
 
63
98
  with open(config_path, "rb") as f:
64
99
  data = tomllib.load(f)
65
- return bool(data.get("tool_memory", {}).get("enabled", True))
100
+ result: dict[str, Any] = data.get("tool_memory", {})
101
+ return result
66
102
  except Exception:
67
- logger.debug("Failed to read tool_memory.enabled from config", exc_info=True)
68
- return True
103
+ logger.debug("Failed to read tool_memory config", exc_info=True)
104
+ return {}
69
105
 
70
106
 
71
- def _get_blacklist() -> list[str]:
72
- """Read blacklist from config.toml."""
73
- data_dir = Path(os.environ.get("SURREAL_MEMORY_DIR", "")) or (Path.home() / ".surrealmemory")
74
- config_path = data_dir / "config.toml"
75
- if not config_path.exists():
76
- return []
77
- try:
78
- import tomllib
107
+ def _is_enabled(tm_cfg: dict[str, Any]) -> bool:
108
+ """Check if tool memory is enabled.
79
109
 
80
- with open(config_path, "rb") as f:
81
- data = tomllib.load(f)
82
- bl = data.get("tool_memory", {}).get("blacklist", [])
83
- return list(bl) if isinstance(bl, (list, tuple)) else []
84
- except Exception:
85
- logger.debug("Failed to read tool_memory.blacklist from config", exc_info=True)
86
- return []
110
+ Defaults to True if the key is absent.
111
+ """
112
+ return bool(tm_cfg.get("enabled", True))
113
+
114
+
115
+ def _get_blacklist(tm_cfg: dict[str, Any]) -> list[str]:
116
+ """Return the blacklist from [tool_memory] config."""
117
+ bl = tm_cfg.get("blacklist", [])
118
+ return list(bl) if isinstance(bl, (list, tuple)) else []
87
119
 
88
120
 
89
121
  def _truncate_args(tool_input: Any) -> str:
@@ -97,16 +129,18 @@ def _truncate_args(tool_input: Any) -> str:
97
129
  return raw[:_MAX_ARGS_CHARS]
98
130
 
99
131
 
100
- def _format_event(hook_input: dict[str, Any]) -> dict[str, Any]:
101
- """Format hook input into a JSONL event dict."""
102
- from surreal_memory.utils.timeutils import utcnow
132
+ def _utcnow_iso() -> str:
133
+ """Return current UTC time as naive ISO string (stdlib only, no imports)."""
134
+ return datetime.now(UTC).replace(tzinfo=None).isoformat()
135
+
103
136
 
137
+ def _format_event(hook_input: dict[str, Any]) -> dict[str, Any]:
138
+ """Format hook input into a JSONL event dict (stdlib only)."""
104
139
  tool_name = hook_input.get("tool_name", hook_input.get("tool", ""))
105
140
  server_name = hook_input.get("server_name", "")
106
141
  tool_input = hook_input.get("tool_input", {})
107
142
  tool_error = hook_input.get("tool_error")
108
143
  duration_ms = hook_input.get("duration_ms", 0)
109
- session_id = os.environ.get("CLAUDE_SESSION_ID", "")
110
144
 
111
145
  return {
112
146
  "tool_name": str(tool_name),
@@ -114,22 +148,35 @@ def _format_event(hook_input: dict[str, Any]) -> dict[str, Any]:
114
148
  "args_summary": _truncate_args(tool_input),
115
149
  "success": tool_error is None,
116
150
  "duration_ms": int(duration_ms) if isinstance(duration_ms, (int, float)) else 0,
117
- "session_id": session_id,
151
+ "session_id": _get_session_id(),
118
152
  "task_context": "", # Populated by processing engine if session is active
119
- "created_at": utcnow().isoformat(),
153
+ "created_at": _utcnow_iso(),
120
154
  }
121
155
 
122
156
 
123
157
  def _append_to_buffer(event: dict[str, Any], buffer_path: Path) -> bool:
124
- """Append one JSONL line to the buffer file.
158
+ """Append one JSONL line to the buffer file, lock-safe.
125
159
 
160
+ Uses fcntl.flock (POSIX) when available. Falls back to a plain
161
+ append on platforms that lack flock (Windows, some embedded).
126
162
  Returns True on success, False on failure.
127
163
  """
128
164
  try:
129
165
  buffer_path.parent.mkdir(parents=True, exist_ok=True)
130
- line = json.dumps(event, ensure_ascii=False, default=str)
131
- with open(buffer_path, "a", encoding="utf-8") as f:
132
- f.write(line + "\n")
166
+ line = json.dumps(event, ensure_ascii=False, default=str) + "\n"
167
+ try:
168
+ import fcntl
169
+
170
+ with open(buffer_path, "a", encoding="utf-8") as f:
171
+ fcntl.flock(f, fcntl.LOCK_EX)
172
+ try:
173
+ f.write(line)
174
+ finally:
175
+ fcntl.flock(f, fcntl.LOCK_UN)
176
+ except ImportError:
177
+ # Non-POSIX platform — plain append (best-effort)
178
+ with open(buffer_path, "a", encoding="utf-8") as f:
179
+ f.write(line)
133
180
  return True
134
181
  except OSError:
135
182
  return False
@@ -155,26 +202,31 @@ def main() -> None:
155
202
  """Entry point for the PostToolUse hook."""
156
203
  start = time.monotonic()
157
204
 
158
- # Fast exit if disabled
159
- if not _is_enabled():
160
- # Output empty JSON for hook response
161
- sys.stdout.write("{}\n")
162
- return
163
-
164
205
  hook_input = _read_stdin()
165
206
  if not hook_input:
166
207
  sys.stdout.write("{}\n")
167
208
  return
168
209
 
169
- tool_name = hook_input.get("tool_name", hook_input.get("tool", ""))
210
+ tool_name = str(hook_input.get("tool_name", hook_input.get("tool", "")))
170
211
  if not tool_name:
171
212
  sys.stdout.write("{}\n")
172
213
  return
173
214
 
174
- # Check blacklist
175
- blacklist = _get_blacklist()
215
+ # Fast-path: skip high-frequency noise tools before any config I/O
216
+ if tool_name in _NOISE_TOOLS:
217
+ sys.stdout.write("{}\n")
218
+ return
219
+
220
+ # Read config once; derive enabled + blacklist from it
221
+ tm_cfg = _read_tool_memory_config()
222
+
223
+ if not _is_enabled(tm_cfg):
224
+ sys.stdout.write("{}\n")
225
+ return
226
+
227
+ blacklist = _get_blacklist(tm_cfg)
176
228
  for prefix in blacklist:
177
- if str(tool_name).startswith(prefix):
229
+ if tool_name.startswith(prefix):
178
230
  sys.stdout.write("{}\n")
179
231
  return
180
232
 
@@ -183,7 +235,7 @@ def main() -> None:
183
235
  buffer_path = _get_buffer_path()
184
236
  _append_to_buffer(event, buffer_path)
185
237
 
186
- # Periodic buffer rotation check (every ~100 calls, cheap stat check)
238
+ # Periodic buffer rotation check (cheap stat check)
187
239
  try:
188
240
  if buffer_path.exists() and buffer_path.stat().st_size > 5_000_000: # > 5MB
189
241
  _check_buffer_rotation(buffer_path)