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.
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/PKG-INFO +5 -5
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/README.md +2 -2
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/pyproject.toml +2 -2
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/__init__.py +1 -1
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/config_cmd.py +1 -1
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/config_presets.py +23 -1
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/core/fiber.py +5 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/core/synapse.py +2 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/brain_transplant.py +8 -3
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/consolidation.py +9 -3
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/embedding/gemini_embedding.py +24 -4
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/encoder.py +9 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/pipeline.py +6 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/pipeline_steps.py +3 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/hooks/post_tool_use.py +101 -49
- surreal_memory-2.5.0/src/surreal_memory/mcp/offload_handler.py +202 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/recall_handler.py +85 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/remember_handler.py +4 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/server.py +35 -2
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/session_handler.py +135 -6
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/tool_handler_utils.py +6 -1
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/tool_handlers.py +2 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/tool_schemas.py +71 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/routes/dashboard_api.py +86 -0
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- surreal_memory-2.5.0/src/surreal_memory/server/static/dist/assets/StoragePage-Dfp1G5qu.js +1 -0
- 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
- 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
- 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
- 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
- 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
- surreal_memory-2.5.0/src/surreal_memory/server/static/dist/assets/index-CWIfFh7B.css +1 -0
- 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
- 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
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/static/dist/index.html +2 -2
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/base.py +2 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/memory_store.py +3 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/shared_store.py +7 -1
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_synapses.py +6 -1
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/projects.py +2 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/schema.py +17 -16
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/sources.py +2 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/store.py +42 -28
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/unified_config.py +119 -13
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/utils/tag_normalizer.py +21 -0
- surreal_memory-2.3.2/src/surreal_memory/server/static/dist/assets/StoragePage-CLDPXEH8.js +0 -1
- surreal_memory-2.3.2/src/surreal_memory/server/static/dist/assets/index-BFkJgtCN.css +0 -1
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/.gitignore +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/LICENSE +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/NOTICE +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/__init__.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/__main__.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/_helpers.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/__init__.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/brain.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/codebase.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/habits.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/info.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/listing.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/memory.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/project.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/reindex.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/shared.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/shortcuts.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/storage.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/telegram.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/tools.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/train.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/update.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/version.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/commands/watch.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/config.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/doctor.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/embedding_setup.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/full_setup.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/graph_export.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/ide_rules.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/main.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/markdown_export.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/setup.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/storage.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/tui.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/update_check.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/cli/wizard.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/core/__init__.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/core/action_event.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/core/alert.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/core/brain.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/core/brain_mode.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/core/eternal_context.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/core/memory_types.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/core/neuron.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/core/project.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/core/review_schedule.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/core/source.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/core/trigger_engine.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/__init__.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/activation.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/arousal.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/associative_inference.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/brain_evolution.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/brain_versioning.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/causal_traversal.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/chart_generator.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/chunking.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/citation.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/clustering.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/codebase_encoder.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/cognitive.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/compression.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/conflict_auto_resolve.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/conflict_detection.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/connection_explainer.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/consolidation_delta.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/context_merger.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/context_optimizer.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/context_retrieval.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/cross_brain.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/db_introspector.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/db_knowledge.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/db_trainer.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/decision_intel.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/dedup/__init__.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/dedup/config.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/dedup/llm_judge.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/dedup/pipeline.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/dedup/prompts.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/depth_prior.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/diagnostics.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/doc_chunker.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/doc_extractor.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/doc_trainer.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/dream.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/drift_detection.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/embedding/__init__.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/embedding/capability.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/embedding/config.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/embedding/ollama_embedding.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/embedding/openai_embedding.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/embedding/openrouter_embedding.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/embedding/provider.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/embedding/retry.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/embedding/sentence_transformer.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/enrichment.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/fidelity.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/file_watcher.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/fuzzy_match.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/fuzzy_query.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/gromov.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/hippocampal_replay.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/hooks.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/idf_anchor.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/importance.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/interference.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/koopman.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/learning_rule.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/lifecycle.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/memory_stages.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/merge.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/narrative.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/pattern_extraction.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/ppr_activation.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/prediction_error.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/priming.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/quality_scorer.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/query_expander.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/query_expansion.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/query_pattern_mining.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/reconsolidation.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/reconstruction.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/reflection.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/reflex_activation.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/reranker.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/retrieval.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/retrieval_context.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/retrieval_types.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/schema_assimilation.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/score_fusion.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/semantic_discovery.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/sequence_mining.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/session_state.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/spaced_repetition.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/stabilization.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/sufficiency.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/temporal_binding.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/tier_engine.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/token_budget.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/token_normalizer.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/tool_memory.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/topology_analysis.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/watch_state.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/workflow_suggest.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/engine/write_queue.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/extraction/__init__.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/extraction/codebase.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/extraction/entities.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/extraction/keywords.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/extraction/llm_provider.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/extraction/parser.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/extraction/relations.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/extraction/router.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/extraction/sentiment.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/extraction/structure_detector.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/extraction/temporal.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/git_context.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/hooks/__init__.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/hooks/pre_compact.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/hooks/project_context.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/hooks/session_start.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/hooks/stop.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/hooks/task_context.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integration/__init__.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integration/adapter.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integration/adapters/__init__.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integration/adapters/awf_adapter.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integration/adapters/chromadb_adapter.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integration/adapters/cognee_adapter.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integration/adapters/graphiti_adapter.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integration/adapters/llamaindex_adapter.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integration/adapters/mem0_adapter.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integration/mapper.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integration/models.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integration/sync_engine.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integration/telegram.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integrations/__init__.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integrations/nanobot/__init__.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integrations/nanobot/base_tool.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integrations/nanobot/context.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integrations/nanobot/memory_store.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integrations/nanobot/protocol.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integrations/nanobot/setup.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integrations/nanobot/tools.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/integrations/openclaw_config.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/__init__.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/__main__.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/alert_handler.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/auto_capture.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/auto_handler.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/budget_handler.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/cognitive_handler.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/conflict_handler.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/connection_handler.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/constants.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/db_train_handler.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/drift_handler.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/eternal_handler.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/evolution_handler.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/expiry_cleanup_handler.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/http_transport.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/index_handler.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/instruction_handler.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/lifecycle_handler.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/maintenance_handler.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/mem0_sync_handler.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/narrative_handler.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/onboarding_handler.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/prompt.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/provenance_handler.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/response_compactor.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/review_handler.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/scheduled_consolidation_handler.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/stats_handler.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/surface_handler.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/sync_handler.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/telegram_handler.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/tier_handler.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/train_handler.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/version_check_handler.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/visualize_handler.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/mcp/watch_handler.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/plugins/__init__.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/plugins/base.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/plugins/community.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/py.typed +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/safety/__init__.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/safety/encryption.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/safety/freshness.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/safety/input_firewall.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/safety/sensitive.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/__init__.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/app.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/dependencies.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/models.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/routes/__init__.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/routes/brain.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/routes/consolidation.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/routes/hub.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/routes/integration_status.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/routes/memory.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/routes/oauth.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/routes/openclaw_api.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/routes/sync.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/static/dist/assets/DiagramsPage-BZV40eAE.css +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/static/dist/assets/embed-gLOWnRXV.js +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/static/dist/assets/timer-DWAvo6M8.js +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/static/dist/assets/vendor-icons-BYlYobEK.js +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/static/dist/assets/vendor-motion-Ct_HHbYW.js +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/static/dist/assets/vendor-query-CqA1cBNl.js +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/static/dist/assets/vendor-react-BfuodpLv.js +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/static/dist/assets/vendor-recharts-BkwZfCWA.js +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/server/static/dist/assets/vendor-ui-Qm4_4bAc.js +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/skills/__init__.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/skills/memory-audit/SKILL.md +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/skills/memory-evolution/SKILL.md +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/skills/memory-intake/SKILL.md +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/__init__.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/factory.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/memory_brain_ops.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/memory_collections.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/memory_reviews.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/neuron_cache.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/read_pool.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/shared_store_collections.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/shared_store_mappers.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_action_log.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_alerts.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_brain_ops.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_calibration.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_change_log.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_coactivation.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_cognitive.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_compression.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_depth_priors.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_devices.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_drift.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_entity_refs.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_fibers.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_maturation.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_merkle.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_neurons.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_projects.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_reviews.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_row_mappers.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_schema.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_sessions.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_sources.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_store.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_sync_state.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_tool_events.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_training_files.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_typed.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/sqlite_versioning.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/__init__.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/activity.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/alerts.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/cognitive.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/compression.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/connection.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/depth_priors.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/keyword_entity.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/review_schedules.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/tool_events.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/typed_memory.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/storage/surrealdb/versions.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/surface/__init__.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/surface/generator.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/surface/lifecycle.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/surface/models.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/surface/parser.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/surface/resolver.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/surface/serializer.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/surface/token_budget.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/sync/__init__.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/sync/client.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/sync/device.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/sync/incremental_merge.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/sync/merkle.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/sync/protocol.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/sync/sync_engine.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/utils/__init__.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/utils/config.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/utils/consolidation_lock.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/utils/sandbox.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/utils/simhash.py +0 -0
- {surreal_memory-2.3.2 → surreal_memory-2.5.0}/src/surreal_memory/utils/ssl_helper.py +0 -0
- {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
|
+
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
|
|
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
|
|
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
|
-
|
|
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 (
|
|
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
|
-
|
|
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 (
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
84
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
#
|
|
98
|
-
#
|
|
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=
|
|
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
|
|
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
|
-
|
|
47
|
-
return data_dir / "tool_events.jsonl"
|
|
83
|
+
return _get_data_dir() / "tool_events.jsonl"
|
|
48
84
|
|
|
49
85
|
|
|
50
|
-
def
|
|
51
|
-
"""
|
|
86
|
+
def _read_tool_memory_config() -> dict[str, Any]:
|
|
87
|
+
"""Read [tool_memory] section from config.toml once.
|
|
52
88
|
|
|
53
|
-
|
|
54
|
-
|
|
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
|
-
|
|
57
|
-
config_path = data_dir / "config.toml"
|
|
92
|
+
config_path = _get_data_dir() / "config.toml"
|
|
58
93
|
if not config_path.exists():
|
|
59
|
-
return
|
|
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
|
-
|
|
100
|
+
result: dict[str, Any] = data.get("tool_memory", {})
|
|
101
|
+
return result
|
|
66
102
|
except Exception:
|
|
67
|
-
logger.debug("Failed to read tool_memory
|
|
68
|
-
return
|
|
103
|
+
logger.debug("Failed to read tool_memory config", exc_info=True)
|
|
104
|
+
return {}
|
|
69
105
|
|
|
70
106
|
|
|
71
|
-
def
|
|
72
|
-
"""
|
|
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
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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
|
|
101
|
-
"""
|
|
102
|
-
|
|
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":
|
|
151
|
+
"session_id": _get_session_id(),
|
|
118
152
|
"task_context": "", # Populated by processing engine if session is active
|
|
119
|
-
"created_at":
|
|
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
|
-
|
|
132
|
-
|
|
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
|
-
#
|
|
175
|
-
|
|
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
|
|
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 (
|
|
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)
|