surreal-memory 2.3.1__tar.gz → 2.3.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/PKG-INFO +1 -1
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/pyproject.toml +1 -1
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/__init__.py +1 -1
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/commands/tools.py +10 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/doctor.py +186 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/full_setup.py +10 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/setup.py +121 -20
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/wizard.py +4 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/server.py +12 -0
- surreal_memory-2.3.2/src/surreal_memory/storage/surrealdb/connection.py +120 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/surrealdb/store.py +42 -12
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/unified_config.py +39 -5
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/.gitignore +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/LICENSE +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/NOTICE +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/README.md +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/__init__.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/__main__.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/_helpers.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/commands/__init__.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/commands/brain.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/commands/codebase.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/commands/config_cmd.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/commands/habits.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/commands/info.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/commands/listing.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/commands/memory.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/commands/project.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/commands/reindex.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/commands/shared.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/commands/shortcuts.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/commands/storage.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/commands/telegram.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/commands/train.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/commands/update.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/commands/version.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/commands/watch.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/config.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/embedding_setup.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/graph_export.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/ide_rules.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/main.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/markdown_export.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/storage.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/tui.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/cli/update_check.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/config_presets.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/core/__init__.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/core/action_event.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/core/alert.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/core/brain.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/core/brain_mode.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/core/eternal_context.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/core/fiber.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/core/memory_types.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/core/neuron.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/core/project.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/core/review_schedule.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/core/source.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/core/synapse.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/core/trigger_engine.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/__init__.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/activation.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/arousal.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/associative_inference.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/brain_evolution.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/brain_transplant.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/brain_versioning.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/causal_traversal.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/chart_generator.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/chunking.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/citation.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/clustering.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/codebase_encoder.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/cognitive.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/compression.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/conflict_auto_resolve.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/conflict_detection.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/connection_explainer.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/consolidation.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/consolidation_delta.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/context_merger.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/context_optimizer.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/context_retrieval.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/cross_brain.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/db_introspector.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/db_knowledge.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/db_trainer.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/decision_intel.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/dedup/__init__.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/dedup/config.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/dedup/llm_judge.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/dedup/pipeline.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/dedup/prompts.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/depth_prior.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/diagnostics.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/doc_chunker.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/doc_extractor.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/doc_trainer.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/dream.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/drift_detection.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/embedding/__init__.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/embedding/capability.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/embedding/config.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/embedding/gemini_embedding.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/embedding/ollama_embedding.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/embedding/openai_embedding.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/embedding/openrouter_embedding.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/embedding/provider.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/embedding/retry.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/embedding/sentence_transformer.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/encoder.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/enrichment.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/fidelity.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/file_watcher.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/fuzzy_match.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/fuzzy_query.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/gromov.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/hippocampal_replay.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/hooks.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/idf_anchor.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/importance.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/interference.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/koopman.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/learning_rule.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/lifecycle.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/memory_stages.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/merge.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/narrative.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/pattern_extraction.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/pipeline.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/pipeline_steps.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/ppr_activation.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/prediction_error.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/priming.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/quality_scorer.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/query_expander.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/query_expansion.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/query_pattern_mining.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/reconsolidation.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/reconstruction.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/reflection.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/reflex_activation.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/reranker.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/retrieval.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/retrieval_context.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/retrieval_types.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/schema_assimilation.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/score_fusion.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/semantic_discovery.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/sequence_mining.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/session_state.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/spaced_repetition.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/stabilization.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/sufficiency.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/temporal_binding.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/tier_engine.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/token_budget.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/token_normalizer.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/tool_memory.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/topology_analysis.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/watch_state.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/workflow_suggest.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/engine/write_queue.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/extraction/__init__.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/extraction/codebase.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/extraction/entities.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/extraction/keywords.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/extraction/llm_provider.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/extraction/parser.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/extraction/relations.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/extraction/router.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/extraction/sentiment.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/extraction/structure_detector.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/extraction/temporal.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/git_context.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/hooks/__init__.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/hooks/post_tool_use.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/hooks/pre_compact.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/hooks/project_context.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/hooks/session_start.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/hooks/stop.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/hooks/task_context.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/integration/__init__.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/integration/adapter.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/integration/adapters/__init__.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/integration/adapters/awf_adapter.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/integration/adapters/chromadb_adapter.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/integration/adapters/cognee_adapter.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/integration/adapters/graphiti_adapter.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/integration/adapters/llamaindex_adapter.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/integration/adapters/mem0_adapter.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/integration/mapper.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/integration/models.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/integration/sync_engine.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/integration/telegram.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/integrations/__init__.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/integrations/nanobot/__init__.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/integrations/nanobot/base_tool.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/integrations/nanobot/context.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/integrations/nanobot/memory_store.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/integrations/nanobot/protocol.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/integrations/nanobot/setup.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/integrations/nanobot/tools.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/integrations/openclaw_config.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/__init__.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/__main__.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/alert_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/auto_capture.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/auto_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/budget_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/cognitive_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/conflict_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/connection_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/constants.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/db_train_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/drift_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/eternal_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/evolution_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/expiry_cleanup_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/http_transport.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/index_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/instruction_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/lifecycle_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/maintenance_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/mem0_sync_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/narrative_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/onboarding_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/prompt.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/provenance_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/recall_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/remember_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/response_compactor.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/review_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/scheduled_consolidation_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/session_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/stats_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/surface_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/sync_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/telegram_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/tier_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/tool_handler_utils.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/tool_handlers.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/tool_schemas.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/train_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/version_check_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/visualize_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/mcp/watch_handler.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/plugins/__init__.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/plugins/base.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/plugins/community.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/py.typed +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/safety/__init__.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/safety/encryption.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/safety/freshness.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/safety/input_firewall.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/safety/sensitive.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/__init__.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/app.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/dependencies.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/models.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/routes/__init__.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/routes/brain.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/routes/consolidation.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/routes/dashboard_api.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/routes/hub.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/routes/integration_status.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/routes/memory.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/routes/oauth.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/routes/openclaw_api.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/routes/sync.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/static/dist/assets/DiagramsPage-BZV40eAE.css +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/static/dist/assets/DiagramsPage-DxR1C_Ua.js +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/static/dist/assets/EvolutionPage-By828lS5.js +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/static/dist/assets/GraphPage-DwQB1_DY.js +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/static/dist/assets/HealthPage-DetJg-Qr.js +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/static/dist/assets/OraclePage-7FBeVFXa.js +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/static/dist/assets/OverviewPage-xe8kFqX3.js +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/static/dist/assets/ProGate-CwBF4etn.js +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/static/dist/assets/SettingsPage-CH2mIMiD.js +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/static/dist/assets/StoragePage-CLDPXEH8.js +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/static/dist/assets/SyncPage-MbtH1dwD.js +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/static/dist/assets/TimelinePage-BIybkdH4.js +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/static/dist/assets/ToolStatsPage-BA-DvxES.js +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/static/dist/assets/VisualizePage-B_IPrBGU.js +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/static/dist/assets/card-B0vNsxr_.js +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/static/dist/assets/embed-gLOWnRXV.js +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/static/dist/assets/index-BFkJgtCN.css +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/static/dist/assets/index-C26pxqlr.js +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/static/dist/assets/skeleton-DQJ-n00q.js +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/static/dist/assets/timer-DWAvo6M8.js +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/static/dist/assets/vendor-icons-BYlYobEK.js +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/static/dist/assets/vendor-motion-Ct_HHbYW.js +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/static/dist/assets/vendor-query-CqA1cBNl.js +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/static/dist/assets/vendor-react-BfuodpLv.js +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/static/dist/assets/vendor-recharts-BkwZfCWA.js +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/static/dist/assets/vendor-ui-Qm4_4bAc.js +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/server/static/dist/index.html +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/skills/__init__.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/skills/memory-audit/SKILL.md +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/skills/memory-evolution/SKILL.md +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/skills/memory-intake/SKILL.md +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/__init__.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/base.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/factory.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/memory_brain_ops.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/memory_collections.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/memory_reviews.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/memory_store.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/neuron_cache.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/read_pool.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/shared_store.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/shared_store_collections.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/shared_store_mappers.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/sqlite_action_log.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/sqlite_alerts.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/sqlite_brain_ops.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/sqlite_calibration.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/sqlite_change_log.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/sqlite_coactivation.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/sqlite_cognitive.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/sqlite_compression.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/sqlite_depth_priors.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/sqlite_devices.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/sqlite_drift.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/sqlite_entity_refs.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/sqlite_fibers.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/sqlite_maturation.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/sqlite_merkle.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/sqlite_neurons.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/sqlite_projects.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/sqlite_reviews.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/sqlite_row_mappers.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/sqlite_schema.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/sqlite_sessions.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/sqlite_sources.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/sqlite_store.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/sqlite_synapses.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/sqlite_sync_state.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/sqlite_tool_events.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/sqlite_training_files.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/sqlite_typed.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/sqlite_versioning.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/surrealdb/__init__.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/surrealdb/activity.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/surrealdb/alerts.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/surrealdb/cognitive.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/surrealdb/compression.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/surrealdb/depth_priors.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/surrealdb/keyword_entity.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/surrealdb/projects.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/surrealdb/review_schedules.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/surrealdb/schema.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/surrealdb/sources.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/surrealdb/tool_events.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/surrealdb/typed_memory.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/storage/surrealdb/versions.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/surface/__init__.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/surface/generator.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/surface/lifecycle.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/surface/models.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/surface/parser.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/surface/resolver.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/surface/serializer.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/surface/token_budget.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/sync/__init__.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/sync/client.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/sync/device.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/sync/incremental_merge.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/sync/merkle.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/sync/protocol.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/sync/sync_engine.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/utils/__init__.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/utils/config.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/utils/consolidation_lock.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/utils/sandbox.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/utils/simhash.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/utils/ssl_helper.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/src/surreal_memory/utils/tag_normalizer.py +0 -0
- {surreal_memory-2.3.1 → surreal_memory-2.3.2}/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.
|
|
3
|
+
Version: 2.3.2
|
|
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
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "surreal-memory"
|
|
7
|
-
version = "2.3.
|
|
7
|
+
version = "2.3.2"
|
|
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"
|
|
@@ -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.
|
|
19
|
+
__version__ = "2.3.2"
|
|
20
20
|
|
|
21
21
|
__all__ = [
|
|
22
22
|
"__version__",
|
|
@@ -241,6 +241,7 @@ def init(
|
|
|
241
241
|
setup_config,
|
|
242
242
|
setup_hooks_claude,
|
|
243
243
|
setup_mcp_claude,
|
|
244
|
+
setup_mcp_claude_desktop,
|
|
244
245
|
setup_mcp_cursor,
|
|
245
246
|
setup_skills,
|
|
246
247
|
)
|
|
@@ -280,6 +281,15 @@ def init(
|
|
|
280
281
|
}
|
|
281
282
|
results["Cursor"] = cursor_labels.get(cursor_status, cursor_status)
|
|
282
283
|
|
|
284
|
+
desktop_status = setup_mcp_claude_desktop()
|
|
285
|
+
desktop_labels = {
|
|
286
|
+
"added": "claude_desktop_config.json (added MCP server)",
|
|
287
|
+
"exists": "claude_desktop_config.json (already configured)",
|
|
288
|
+
"not_found": "not detected (Claude Desktop not installed)",
|
|
289
|
+
"failed": "failed to write config",
|
|
290
|
+
}
|
|
291
|
+
results["Claude Desktop"] = desktop_labels.get(desktop_status, desktop_status)
|
|
292
|
+
|
|
283
293
|
# 4. Hooks (Claude Code only)
|
|
284
294
|
if not skip_mcp:
|
|
285
295
|
hook_status = setup_hooks_claude()
|
|
@@ -40,7 +40,9 @@ _CHECK_TIERS: dict[str, str] = {
|
|
|
40
40
|
"Dependencies": TIER_CORE,
|
|
41
41
|
"Schema version": TIER_CORE,
|
|
42
42
|
"CLI tools": TIER_CORE,
|
|
43
|
+
"SurrealDB connection": TIER_CORE,
|
|
43
44
|
"Embedding provider": TIER_RECOMMENDED,
|
|
45
|
+
"MCP env completeness": TIER_RECOMMENDED,
|
|
44
46
|
"MCP configuration": TIER_RECOMMENDED,
|
|
45
47
|
"MCP server": TIER_RECOMMENDED,
|
|
46
48
|
"Hooks": TIER_RECOMMENDED,
|
|
@@ -86,6 +88,8 @@ def run_doctor(
|
|
|
86
88
|
checks.append(_check_surface())
|
|
87
89
|
checks.append(_check_config_freshness())
|
|
88
90
|
checks.append(_check_cli_tools())
|
|
91
|
+
checks.append(_check_surrealdb_connection())
|
|
92
|
+
checks.append(_check_mcp_env_completeness())
|
|
89
93
|
checks.append(_check_pro_plugin())
|
|
90
94
|
if dev:
|
|
91
95
|
checks.extend(_check_dev_environment())
|
|
@@ -328,6 +332,12 @@ def _check_brain() -> dict[str, Any]:
|
|
|
328
332
|
|
|
329
333
|
config = get_config(reload=True)
|
|
330
334
|
brain_name = config.current_brain
|
|
335
|
+
if config.storage_backend == "surrealdb":
|
|
336
|
+
return {
|
|
337
|
+
"name": "Brain database",
|
|
338
|
+
"status": SKIP,
|
|
339
|
+
"detail": "surrealdb backend — brain lives in SurrealDB, not a local .db file",
|
|
340
|
+
}
|
|
331
341
|
except Exception:
|
|
332
342
|
brain_name = "default"
|
|
333
343
|
|
|
@@ -441,6 +451,12 @@ def _check_schema_version() -> dict[str, Any]:
|
|
|
441
451
|
from surreal_memory.unified_config import get_config, get_surrealmemory_dir
|
|
442
452
|
|
|
443
453
|
config = get_config(reload=True)
|
|
454
|
+
if config.storage_backend == "surrealdb":
|
|
455
|
+
return {
|
|
456
|
+
"name": "Schema version",
|
|
457
|
+
"status": SKIP,
|
|
458
|
+
"detail": "surrealdb backend — schema managed by SurrealDB, not SQLite",
|
|
459
|
+
}
|
|
444
460
|
brain_name = config.current_brain
|
|
445
461
|
db_path = get_surrealmemory_dir() / "brains" / f"{brain_name}.db"
|
|
446
462
|
|
|
@@ -865,6 +881,8 @@ _FIX_HANDLERS: dict[str, Any] = {
|
|
|
865
881
|
"Dedup": lambda: _fix_dedup(),
|
|
866
882
|
"Embedding provider": lambda: _fix_embedding(),
|
|
867
883
|
"Config freshness": lambda: _fix_config_freshness(),
|
|
884
|
+
"MCP env completeness": lambda: _fix_mcp_env(),
|
|
885
|
+
"SurrealDB connection": lambda: _fix_mcp_env(),
|
|
868
886
|
}
|
|
869
887
|
|
|
870
888
|
|
|
@@ -958,6 +976,174 @@ def _fix_config_freshness() -> dict[str, Any]:
|
|
|
958
976
|
}
|
|
959
977
|
|
|
960
978
|
|
|
979
|
+
# ---------------------------------------------------------------------------
|
|
980
|
+
# SurrealDB-specific checks
|
|
981
|
+
# ---------------------------------------------------------------------------
|
|
982
|
+
|
|
983
|
+
|
|
984
|
+
def _run_surrealdb_ping() -> None:
|
|
985
|
+
"""Attempt a real SurrealDB connection with a short timeout.
|
|
986
|
+
|
|
987
|
+
Raises StorageAuthError on bad credentials, any other exception on
|
|
988
|
+
connectivity issues. Returns None on success.
|
|
989
|
+
"""
|
|
990
|
+
import asyncio
|
|
991
|
+
|
|
992
|
+
from surreal_memory.storage.surrealdb.connection import SurrealSettings
|
|
993
|
+
from surreal_memory.storage.surrealdb.store import SurrealDBStorage
|
|
994
|
+
|
|
995
|
+
async def _ping() -> None:
|
|
996
|
+
settings = SurrealSettings.from_env()
|
|
997
|
+
storage = SurrealDBStorage(
|
|
998
|
+
url=settings.url,
|
|
999
|
+
user=settings.user,
|
|
1000
|
+
password=settings.password,
|
|
1001
|
+
namespace=settings.namespace,
|
|
1002
|
+
database=settings.database,
|
|
1003
|
+
)
|
|
1004
|
+
try:
|
|
1005
|
+
await asyncio.wait_for(storage.initialize(), timeout=5)
|
|
1006
|
+
finally:
|
|
1007
|
+
await storage.close()
|
|
1008
|
+
|
|
1009
|
+
run_async(_ping())
|
|
1010
|
+
|
|
1011
|
+
|
|
1012
|
+
def _check_surrealdb_connection() -> dict[str, Any]:
|
|
1013
|
+
"""Check that the SurrealDB connection works (TIER_CORE for surrealdb backend).
|
|
1014
|
+
|
|
1015
|
+
Returns SKIP when storage backend is not surrealdb.
|
|
1016
|
+
Returns FAIL with actionable hint when authentication fails.
|
|
1017
|
+
Returns WARN when SurrealDB is unreachable (not running, wrong URL, etc.).
|
|
1018
|
+
Returns OK on success.
|
|
1019
|
+
"""
|
|
1020
|
+
import os
|
|
1021
|
+
|
|
1022
|
+
from surreal_memory.storage.surrealdb.connection import StorageAuthError
|
|
1023
|
+
|
|
1024
|
+
if os.environ.get("SURREAL_MEMORY_STORAGE") != "surrealdb":
|
|
1025
|
+
try:
|
|
1026
|
+
from surreal_memory.unified_config import get_config
|
|
1027
|
+
|
|
1028
|
+
config = get_config(reload=True)
|
|
1029
|
+
if config.storage_backend != "surrealdb":
|
|
1030
|
+
return {
|
|
1031
|
+
"name": "SurrealDB connection",
|
|
1032
|
+
"status": SKIP,
|
|
1033
|
+
"detail": "surrealdb backend not active",
|
|
1034
|
+
}
|
|
1035
|
+
except Exception as cfg_exc:
|
|
1036
|
+
return {
|
|
1037
|
+
"name": "SurrealDB connection",
|
|
1038
|
+
"status": WARN,
|
|
1039
|
+
"detail": f"could not load config to determine backend: {type(cfg_exc).__name__}",
|
|
1040
|
+
"fix": "Check config.toml is valid; run: smem init",
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
try:
|
|
1044
|
+
_run_surrealdb_ping()
|
|
1045
|
+
return {
|
|
1046
|
+
"name": "SurrealDB connection",
|
|
1047
|
+
"status": OK,
|
|
1048
|
+
"detail": "authenticated and connected",
|
|
1049
|
+
}
|
|
1050
|
+
except StorageAuthError:
|
|
1051
|
+
return {
|
|
1052
|
+
"name": "SurrealDB connection",
|
|
1053
|
+
"status": FAIL,
|
|
1054
|
+
"detail": "authentication failed (wrong password or user)",
|
|
1055
|
+
"fix": "Set SURREALDB_PASS in your MCP client env or run: smem doctor --fix",
|
|
1056
|
+
"fixable": True,
|
|
1057
|
+
}
|
|
1058
|
+
except Exception as exc:
|
|
1059
|
+
return {
|
|
1060
|
+
"name": "SurrealDB connection",
|
|
1061
|
+
"status": WARN,
|
|
1062
|
+
"detail": f"could not reach SurrealDB: {type(exc).__name__}",
|
|
1063
|
+
"fix": "Ensure SurrealDB is running and SURREALDB_URL is correct",
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
|
|
1067
|
+
def _check_mcp_env_completeness() -> dict[str, Any]:
|
|
1068
|
+
"""Check that MCP entries contain the required env block (TIER_RECOMMENDED).
|
|
1069
|
+
|
|
1070
|
+
Reads ~/.claude.json (Claude Code) and claude_desktop_config.json to verify
|
|
1071
|
+
that the surreal-memory entry has SURREALDB_PASS in its env block.
|
|
1072
|
+
"""
|
|
1073
|
+
configs_to_check: list[tuple[str, Path]] = [
|
|
1074
|
+
("Claude Code (~/.claude.json)", Path.home() / ".claude.json"),
|
|
1075
|
+
]
|
|
1076
|
+
|
|
1077
|
+
# Also check Claude Desktop config
|
|
1078
|
+
try:
|
|
1079
|
+
from surreal_memory.cli.setup import _claude_desktop_config_path
|
|
1080
|
+
|
|
1081
|
+
desktop_path = _claude_desktop_config_path()
|
|
1082
|
+
if desktop_path is not None:
|
|
1083
|
+
configs_to_check.append(("Claude Desktop", desktop_path))
|
|
1084
|
+
except Exception:
|
|
1085
|
+
pass
|
|
1086
|
+
|
|
1087
|
+
missing_env: list[str] = []
|
|
1088
|
+
|
|
1089
|
+
for label, config_path in configs_to_check:
|
|
1090
|
+
if not config_path.exists():
|
|
1091
|
+
continue
|
|
1092
|
+
try:
|
|
1093
|
+
data = json.loads(config_path.read_text(encoding="utf-8"))
|
|
1094
|
+
entry = data.get("mcpServers", {}).get("surreal-memory")
|
|
1095
|
+
if entry is None:
|
|
1096
|
+
continue
|
|
1097
|
+
if not entry.get("env", {}).get("SURREALDB_PASS"):
|
|
1098
|
+
missing_env.append(label)
|
|
1099
|
+
except (json.JSONDecodeError, OSError):
|
|
1100
|
+
continue
|
|
1101
|
+
|
|
1102
|
+
if not any(p.exists() for _, p in configs_to_check):
|
|
1103
|
+
return {
|
|
1104
|
+
"name": "MCP env completeness",
|
|
1105
|
+
"status": SKIP,
|
|
1106
|
+
"detail": "no MCP client config files found",
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
if missing_env:
|
|
1110
|
+
return {
|
|
1111
|
+
"name": "MCP env completeness",
|
|
1112
|
+
"status": WARN,
|
|
1113
|
+
"detail": f"surreal-memory entry missing env in: {', '.join(missing_env)}",
|
|
1114
|
+
"fix": "Run: smem doctor --fix",
|
|
1115
|
+
"fixable": True,
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
return {
|
|
1119
|
+
"name": "MCP env completeness",
|
|
1120
|
+
"status": OK,
|
|
1121
|
+
"detail": "env block with SURREALDB_PASS present",
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
|
|
1125
|
+
def _fix_mcp_env() -> dict[str, Any]:
|
|
1126
|
+
"""Auto-fix: backfill env into MCP client configs."""
|
|
1127
|
+
from surreal_memory.cli.setup import setup_mcp_claude, setup_mcp_claude_desktop
|
|
1128
|
+
|
|
1129
|
+
try:
|
|
1130
|
+
setup_mcp_claude()
|
|
1131
|
+
setup_mcp_claude_desktop()
|
|
1132
|
+
return {
|
|
1133
|
+
"name": "MCP env completeness",
|
|
1134
|
+
"status": OK,
|
|
1135
|
+
"detail": "auto-fixed: env backfilled in MCP client configs",
|
|
1136
|
+
}
|
|
1137
|
+
except Exception:
|
|
1138
|
+
pass
|
|
1139
|
+
return {
|
|
1140
|
+
"name": "MCP env completeness",
|
|
1141
|
+
"status": WARN,
|
|
1142
|
+
"detail": "auto-fix failed",
|
|
1143
|
+
"fix": "Run: smem init",
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
|
|
961
1147
|
def _render_results(result: dict[str, Any]) -> None:
|
|
962
1148
|
"""Render diagnostic results to terminal."""
|
|
963
1149
|
typer.echo()
|
|
@@ -306,6 +306,7 @@ def run_full_setup(
|
|
|
306
306
|
setup_config,
|
|
307
307
|
setup_hooks_claude,
|
|
308
308
|
setup_mcp_claude,
|
|
309
|
+
setup_mcp_claude_desktop,
|
|
309
310
|
setup_mcp_cursor,
|
|
310
311
|
setup_skills,
|
|
311
312
|
)
|
|
@@ -347,6 +348,15 @@ def run_full_setup(
|
|
|
347
348
|
}
|
|
348
349
|
results["Cursor"] = cursor_labels.get(cursor_status, cursor_status)
|
|
349
350
|
|
|
351
|
+
desktop_status = setup_mcp_claude_desktop()
|
|
352
|
+
desktop_labels = {
|
|
353
|
+
"added": "MCP server configured",
|
|
354
|
+
"exists": "already configured",
|
|
355
|
+
"not_found": "not detected",
|
|
356
|
+
"failed": "failed",
|
|
357
|
+
}
|
|
358
|
+
results["Claude Desktop"] = desktop_labels.get(desktop_status, desktop_status)
|
|
359
|
+
|
|
350
360
|
# 4. Hooks
|
|
351
361
|
if not skip_mcp:
|
|
352
362
|
hook_status = setup_hooks_claude()
|
|
@@ -22,16 +22,27 @@ def find_smem_command() -> dict[str, Any]:
|
|
|
22
22
|
1. smem-mcp entry point (cleanest)
|
|
23
23
|
2. smem CLI with mcp subcommand
|
|
24
24
|
3. python -m fallback (uses absolute path, normalized for Windows)
|
|
25
|
+
|
|
26
|
+
Always includes an ``env`` block so MCP clients receive the full
|
|
27
|
+
SurrealDB connection config and do not start with an empty environment.
|
|
25
28
|
"""
|
|
29
|
+
from surreal_memory.storage.surrealdb.connection import build_mcp_env
|
|
30
|
+
|
|
31
|
+
env = build_mcp_env()
|
|
32
|
+
|
|
26
33
|
smem_mcp = shutil.which("smem-mcp")
|
|
27
34
|
if smem_mcp:
|
|
28
|
-
return {"command": "smem-mcp"}
|
|
35
|
+
return {"command": "smem-mcp", "env": env}
|
|
29
36
|
|
|
30
37
|
smem = shutil.which("smem")
|
|
31
38
|
if smem:
|
|
32
|
-
return {"command": "smem", "args": ["mcp"]}
|
|
39
|
+
return {"command": "smem", "args": ["mcp"], "env": env}
|
|
33
40
|
|
|
34
|
-
return {
|
|
41
|
+
return {
|
|
42
|
+
"command": _normalize_path(sys.executable),
|
|
43
|
+
"args": ["-m", "surreal_memory.mcp"],
|
|
44
|
+
"env": env,
|
|
45
|
+
}
|
|
35
46
|
|
|
36
47
|
|
|
37
48
|
def setup_config(data_dir: Path, *, force: bool = False) -> bool:
|
|
@@ -149,9 +160,13 @@ def setup_mcp_claude() -> str:
|
|
|
149
160
|
"""Auto-configure MCP in Claude Code.
|
|
150
161
|
|
|
151
162
|
Strategy:
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
163
|
+
Always use direct JSON write (``~/.claude.json``) rather than the
|
|
164
|
+
``claude mcp add`` CLI path, because the CLI does not support the ``env``
|
|
165
|
+
block required for SurrealDB credential injection. The JSON write is
|
|
166
|
+
idempotent and includes the full ``env`` dict.
|
|
167
|
+
|
|
168
|
+
If an entry already exists but lacks ``env``, the env block is backfilled
|
|
169
|
+
so upgraded installations receive the credential config.
|
|
155
170
|
|
|
156
171
|
Returns status string: "added", "exists", "failed", or "not_found".
|
|
157
172
|
"""
|
|
@@ -160,23 +175,35 @@ def setup_mcp_claude() -> str:
|
|
|
160
175
|
return "not_found"
|
|
161
176
|
|
|
162
177
|
claude_json = claude_dir.parent / ".claude.json"
|
|
163
|
-
|
|
164
|
-
# Already registered?
|
|
165
|
-
if _claude_json_has_server(claude_json, "surreal-memory"):
|
|
166
|
-
_cleanup_stale_mcp_servers_json()
|
|
167
|
-
return "exists"
|
|
168
|
-
|
|
169
|
-
# Build the command to register
|
|
170
178
|
mcp_entry = find_smem_command()
|
|
171
|
-
command_args: list[str] = [mcp_entry["command"]]
|
|
172
|
-
command_args.extend(mcp_entry.get("args", []))
|
|
173
179
|
|
|
174
|
-
#
|
|
175
|
-
if
|
|
176
|
-
|
|
177
|
-
|
|
180
|
+
# Check for existing entry
|
|
181
|
+
if claude_json.exists():
|
|
182
|
+
try:
|
|
183
|
+
raw = claude_json.read_text(encoding="utf-8").strip()
|
|
184
|
+
if raw:
|
|
185
|
+
data: dict[str, Any] = json.loads(raw)
|
|
186
|
+
servers = data.get("mcpServers", {})
|
|
187
|
+
if "surreal-memory" in servers:
|
|
188
|
+
existing = servers["surreal-memory"]
|
|
189
|
+
# If env already present and populated → exists
|
|
190
|
+
if existing.get("env", {}).get("SURREALDB_PASS"):
|
|
191
|
+
_cleanup_stale_mcp_servers_json()
|
|
192
|
+
return "exists"
|
|
193
|
+
# Backfill env for upgraded installations — backup first
|
|
194
|
+
try:
|
|
195
|
+
backup = claude_json.with_suffix(".json.bak")
|
|
196
|
+
backup.write_bytes(claude_json.read_bytes())
|
|
197
|
+
except OSError:
|
|
198
|
+
pass
|
|
199
|
+
existing["env"] = mcp_entry.get("env", {})
|
|
200
|
+
claude_json.write_text(json.dumps(data, indent=2) + "\n", encoding="utf-8")
|
|
201
|
+
_cleanup_stale_mcp_servers_json()
|
|
202
|
+
return "added"
|
|
203
|
+
except (json.JSONDecodeError, OSError):
|
|
204
|
+
pass
|
|
178
205
|
|
|
179
|
-
#
|
|
206
|
+
# Write full entry (includes env)
|
|
180
207
|
if _add_via_claude_json(claude_json, mcp_entry):
|
|
181
208
|
_cleanup_stale_mcp_servers_json()
|
|
182
209
|
return "added"
|
|
@@ -221,6 +248,80 @@ def setup_mcp_cursor() -> str:
|
|
|
221
248
|
return "failed"
|
|
222
249
|
|
|
223
250
|
|
|
251
|
+
def _claude_desktop_config_path() -> Path | None:
|
|
252
|
+
"""Return the Claude Desktop config file path for the current OS.
|
|
253
|
+
|
|
254
|
+
Returns None when the parent directory does not exist (Desktop not installed).
|
|
255
|
+
"""
|
|
256
|
+
import os
|
|
257
|
+
|
|
258
|
+
if sys.platform == "darwin":
|
|
259
|
+
config_dir = Path.home() / "Library" / "Application Support" / "Claude"
|
|
260
|
+
elif sys.platform == "win32":
|
|
261
|
+
appdata = os.environ.get("APPDATA", "")
|
|
262
|
+
if not appdata:
|
|
263
|
+
return None
|
|
264
|
+
config_dir = Path(appdata) / "Claude"
|
|
265
|
+
else:
|
|
266
|
+
config_dir = Path.home() / ".config" / "Claude"
|
|
267
|
+
|
|
268
|
+
if not config_dir.exists():
|
|
269
|
+
return None
|
|
270
|
+
return config_dir / "claude_desktop_config.json"
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def setup_mcp_claude_desktop() -> str:
|
|
274
|
+
"""Auto-configure MCP in Claude Desktop.
|
|
275
|
+
|
|
276
|
+
Writes or updates ``claude_desktop_config.json`` with a ``surreal-memory``
|
|
277
|
+
entry including the full ``env`` block so the Desktop app never starts the
|
|
278
|
+
MCP server with an empty environment.
|
|
279
|
+
|
|
280
|
+
Idempotent: if the entry already exists and has ``env.SURREALDB_PASS``,
|
|
281
|
+
returns ``"exists"``. If the entry exists without ``env``, backfills it
|
|
282
|
+
and returns ``"added"``. Creates a ``.bak`` backup before any write.
|
|
283
|
+
|
|
284
|
+
Returns status string: ``"added"``, ``"exists"``, ``"failed"``,
|
|
285
|
+
or ``"not_found"`` (Desktop not installed).
|
|
286
|
+
"""
|
|
287
|
+
config_path = _claude_desktop_config_path()
|
|
288
|
+
if config_path is None:
|
|
289
|
+
return "not_found"
|
|
290
|
+
|
|
291
|
+
mcp_entry = find_smem_command()
|
|
292
|
+
|
|
293
|
+
existing: dict[str, Any] = {}
|
|
294
|
+
if config_path.exists():
|
|
295
|
+
try:
|
|
296
|
+
raw = config_path.read_text(encoding="utf-8").strip()
|
|
297
|
+
if raw:
|
|
298
|
+
existing = json.loads(raw)
|
|
299
|
+
except (json.JSONDecodeError, OSError):
|
|
300
|
+
existing = {}
|
|
301
|
+
|
|
302
|
+
servers = existing.get("mcpServers", {})
|
|
303
|
+
if "surreal-memory" in servers:
|
|
304
|
+
current = servers["surreal-memory"]
|
|
305
|
+
if current.get("env", {}).get("SURREALDB_PASS"):
|
|
306
|
+
return "exists"
|
|
307
|
+
# Backfill env for upgraded installations — fall through to write
|
|
308
|
+
|
|
309
|
+
# Backup before modifying
|
|
310
|
+
try:
|
|
311
|
+
backup = config_path.with_suffix(".json.bak")
|
|
312
|
+
backup.write_bytes(config_path.read_bytes())
|
|
313
|
+
except OSError:
|
|
314
|
+
pass
|
|
315
|
+
|
|
316
|
+
try:
|
|
317
|
+
servers = existing.setdefault("mcpServers", {})
|
|
318
|
+
servers["surreal-memory"] = mcp_entry
|
|
319
|
+
config_path.write_text(json.dumps(existing, indent=2) + "\n", encoding="utf-8")
|
|
320
|
+
return "added"
|
|
321
|
+
except OSError:
|
|
322
|
+
return "failed"
|
|
323
|
+
|
|
324
|
+
|
|
224
325
|
def _normalize_path(path: str) -> str:
|
|
225
326
|
"""Normalize a filesystem path for use in shell commands.
|
|
226
327
|
|
|
@@ -16,6 +16,7 @@ from surreal_memory.cli.setup import (
|
|
|
16
16
|
setup_config,
|
|
17
17
|
setup_hooks_claude,
|
|
18
18
|
setup_mcp_claude,
|
|
19
|
+
setup_mcp_claude_desktop,
|
|
19
20
|
setup_mcp_cursor,
|
|
20
21
|
setup_skills,
|
|
21
22
|
)
|
|
@@ -91,6 +92,9 @@ def run_wizard(*, force: bool = False) -> None:
|
|
|
91
92
|
cursor_status = setup_mcp_cursor()
|
|
92
93
|
_format_mcp_result(results, "Cursor", cursor_status)
|
|
93
94
|
|
|
95
|
+
desktop_status = setup_mcp_claude_desktop()
|
|
96
|
+
_format_mcp_result(results, "Claude Desktop", desktop_status)
|
|
97
|
+
|
|
94
98
|
# Step 5: Hooks
|
|
95
99
|
hook_status = setup_hooks_claude()
|
|
96
100
|
hook_labels = {
|
|
@@ -55,6 +55,7 @@ from surreal_memory.mcp.train_handler import TrainHandler
|
|
|
55
55
|
from surreal_memory.mcp.version_check_handler import VersionCheckHandler
|
|
56
56
|
from surreal_memory.mcp.visualize_handler import VisualizeHandler
|
|
57
57
|
from surreal_memory.mcp.watch_handler import WatchHandler
|
|
58
|
+
from surreal_memory.storage.surrealdb.connection import StorageAuthError
|
|
58
59
|
from surreal_memory.unified_config import get_config, get_shared_storage
|
|
59
60
|
|
|
60
61
|
if TYPE_CHECKING:
|
|
@@ -492,6 +493,17 @@ async def handle_message(server: MCPServer, message: dict[str, Any]) -> dict[str
|
|
|
492
493
|
"message": f"Tool '{tool_name}' timed out after {_TOOL_CALL_TIMEOUT}s",
|
|
493
494
|
},
|
|
494
495
|
}
|
|
496
|
+
except StorageAuthError as exc:
|
|
497
|
+
logger.error("Tool '%s' failed: SurrealDB auth error", tool_name)
|
|
498
|
+
try:
|
|
499
|
+
await _record_tool_event(server, tool_name, tool_args, t0, success=False)
|
|
500
|
+
except Exception:
|
|
501
|
+
logger.debug("Tool event recording failed", exc_info=True)
|
|
502
|
+
return {
|
|
503
|
+
"jsonrpc": "2.0",
|
|
504
|
+
"id": msg_id,
|
|
505
|
+
"error": {"code": -32001, "message": str(exc)},
|
|
506
|
+
}
|
|
495
507
|
except Exception:
|
|
496
508
|
logger.error("Tool '%s' raised an exception", tool_name, exc_info=True)
|
|
497
509
|
try:
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"""SurrealDB connection settings and auth error types.
|
|
2
|
+
|
|
3
|
+
Single source of truth for:
|
|
4
|
+
- Default connection parameters (URL, user, password, namespace, database)
|
|
5
|
+
- Credential-error detection (distinct from 401 token-expiry errors)
|
|
6
|
+
- MCP env dict generation for client config backfill
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import os
|
|
12
|
+
from dataclasses import dataclass
|
|
13
|
+
|
|
14
|
+
DEFAULT_URL = "http://localhost:8001"
|
|
15
|
+
DEFAULT_USER = "root"
|
|
16
|
+
DEFAULT_PASS = "surrealmemory" # noqa: S105
|
|
17
|
+
|
|
18
|
+
AUTH_HINT = (
|
|
19
|
+
"The MCP server env is likely empty or missing SURREALDB_PASS, so it fell back to the "
|
|
20
|
+
"default password. Set SURREALDB_PASS (and SURREALDB_URL/USER) in your MCP client config "
|
|
21
|
+
"(Claude Code: ~/.claude.json; Claude Desktop: claude_desktop_config.json) or run "
|
|
22
|
+
"`smem doctor --fix`."
|
|
23
|
+
)
|
|
24
|
+
DEFAULT_NS = "surreal_memory"
|
|
25
|
+
DEFAULT_DB = "default"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dataclass(frozen=True)
|
|
29
|
+
class SurrealSettings:
|
|
30
|
+
"""Immutable SurrealDB connection settings resolved from environment."""
|
|
31
|
+
|
|
32
|
+
url: str
|
|
33
|
+
user: str
|
|
34
|
+
password: str
|
|
35
|
+
namespace: str
|
|
36
|
+
database: str
|
|
37
|
+
|
|
38
|
+
@classmethod
|
|
39
|
+
def from_env(cls) -> SurrealSettings:
|
|
40
|
+
"""Build settings from environment variables, falling back to defaults."""
|
|
41
|
+
return cls(
|
|
42
|
+
url=os.getenv("SURREALDB_URL", DEFAULT_URL),
|
|
43
|
+
user=os.getenv("SURREALDB_USER", DEFAULT_USER),
|
|
44
|
+
password=os.getenv("SURREALDB_PASS", DEFAULT_PASS),
|
|
45
|
+
namespace=os.getenv("SURREALDB_NS", DEFAULT_NS),
|
|
46
|
+
database=os.getenv("SURREALDB_DB", DEFAULT_DB),
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class StorageAuthError(Exception):
|
|
51
|
+
"""Raised when SurrealDB rejects credentials (wrong password / user).
|
|
52
|
+
|
|
53
|
+
Distinct from token-expiry 401 errors handled by _is_auth_error in store.py.
|
|
54
|
+
Carries an actionable hint so MCP clients surface the root cause instead of
|
|
55
|
+
a generic -32000 failure.
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
def __init__(self, message: str, hint: str = "") -> None:
|
|
59
|
+
super().__init__(message)
|
|
60
|
+
self.hint = hint
|
|
61
|
+
|
|
62
|
+
def __str__(self) -> str:
|
|
63
|
+
base = super().__str__()
|
|
64
|
+
return f"{base} {self.hint}".strip()
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def is_credential_error(exc: Exception) -> bool:
|
|
68
|
+
"""True if *exc* signals bad credentials (wrong password / user not allowed).
|
|
69
|
+
|
|
70
|
+
Distinct from _is_auth_error (token-expiry 401) in store.py — do NOT merge.
|
|
71
|
+
Detects NotAllowedError from surrealdb SDK by three means (in order):
|
|
72
|
+
1. isinstance check when the SDK is importable
|
|
73
|
+
2. class-name match (works when import is not available)
|
|
74
|
+
3. string content match as last resort
|
|
75
|
+
|
|
76
|
+
Returns False for 401 token-expiry errors so the reconnect loop is not
|
|
77
|
+
triggered on a bad password.
|
|
78
|
+
"""
|
|
79
|
+
# Try real isinstance first — guard against MagicMock stubs in tests.
|
|
80
|
+
try:
|
|
81
|
+
from surrealdb.errors import NotAllowedError # type: ignore[import-untyped,unused-ignore]
|
|
82
|
+
|
|
83
|
+
if isinstance(NotAllowedError, type) and isinstance(exc, NotAllowedError):
|
|
84
|
+
return True
|
|
85
|
+
except (ImportError, ModuleNotFoundError, TypeError):
|
|
86
|
+
pass
|
|
87
|
+
|
|
88
|
+
# Class-name fallback (SDK installed but import path changed)
|
|
89
|
+
if type(exc).__name__ == "NotAllowedError":
|
|
90
|
+
return True
|
|
91
|
+
|
|
92
|
+
# String-content fallback — match auth-specific phrases only.
|
|
93
|
+
# "not allowed" alone is too broad (SurrealDB reuses it for permission errors
|
|
94
|
+
# on tables/operations); require an auth-context indicator alongside it.
|
|
95
|
+
msg = str(exc).lower()
|
|
96
|
+
if "problem with authentication" in msg:
|
|
97
|
+
return True
|
|
98
|
+
if "not allowed" in msg and any(
|
|
99
|
+
kw in msg for kw in ("signin", "authenticate", "credentials", "login", "password")
|
|
100
|
+
):
|
|
101
|
+
return True
|
|
102
|
+
|
|
103
|
+
return False
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def build_mcp_env() -> dict[str, str]:
|
|
107
|
+
"""Return an env dict suitable for embedding in MCP client configs.
|
|
108
|
+
|
|
109
|
+
Reads actual env / .env values so a developer's local overrides are
|
|
110
|
+
preserved; falls back to defaults so clean installs get a working config.
|
|
111
|
+
"""
|
|
112
|
+
s = SurrealSettings.from_env()
|
|
113
|
+
return {
|
|
114
|
+
"SURREAL_MEMORY_STORAGE": "surrealdb",
|
|
115
|
+
"SURREALDB_URL": s.url,
|
|
116
|
+
"SURREALDB_USER": s.user,
|
|
117
|
+
"SURREALDB_PASS": s.password,
|
|
118
|
+
"SURREALDB_NS": s.namespace,
|
|
119
|
+
"SURREALDB_DB": s.database,
|
|
120
|
+
}
|