superlocalmemory 3.3.2__tar.gz → 3.3.6__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.
- {superlocalmemory-3.3.2/src/superlocalmemory.egg-info → superlocalmemory-3.3.6}/PKG-INFO +3 -2
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/README.md +2 -1
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/pyproject.toml +5 -1
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/cli/commands.py +150 -13
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/cli/main.py +25 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/core/config.py +12 -9
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/core/maintenance.py +111 -5
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/core/store_pipeline.py +24 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/core/worker_pool.py +9 -2
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/encoding/cognitive_consolidator.py +19 -1
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/encoding/emotional.py +5 -2
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/encoding/entity_resolver.py +1 -1
- superlocalmemory-3.3.6/src/superlocalmemory/hooks/claude_code_hooks.py +404 -0
- superlocalmemory-3.3.6/src/superlocalmemory/hooks/hook_handlers.py +394 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/math/polar_quant.py +3 -1
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/retrieval/engine.py +36 -8
- superlocalmemory-3.3.6/src/superlocalmemory/retrieval/reranker.py +332 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/storage/embedding_migrator.py +4 -3
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6/src/superlocalmemory.egg-info}/PKG-INFO +3 -2
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory.egg-info/SOURCES.txt +3 -0
- superlocalmemory-3.3.6/tests/test_claude_hooks.py +792 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/tests/test_cli_v33.py +3 -2
- superlocalmemory-3.3.6/tests/test_hook_handlers.py +991 -0
- superlocalmemory-3.3.2/src/superlocalmemory/hooks/claude_code_hooks.py +0 -175
- superlocalmemory-3.3.2/src/superlocalmemory/retrieval/reranker.py +0 -255
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/AUTHORS.md +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/LICENSE +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/NOTICE +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/setup.cfg +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/__init__.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/attribution/__init__.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/attribution/mathematical_dna.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/attribution/signer.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/attribution/watermark.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/cli/__init__.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/cli/json_output.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/cli/migrate_cmd.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/cli/post_install.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/cli/setup_wizard.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/compliance/__init__.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/compliance/abac.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/compliance/audit.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/compliance/eu_ai_act.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/compliance/gdpr.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/compliance/lifecycle.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/compliance/retention.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/compliance/scheduler.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/core/__init__.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/core/consolidation_engine.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/core/embedding_worker.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/core/embeddings.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/core/engine.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/core/engine_wiring.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/core/graph_analyzer.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/core/hooks.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/core/modes.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/core/ollama_embedder.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/core/profiles.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/core/recall_pipeline.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/core/recall_worker.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/core/registry.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/core/summarizer.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/dynamics/__init__.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/dynamics/activation_guided_quantization.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/dynamics/eap_scheduler.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/dynamics/ebbinghaus_langevin_coupling.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/dynamics/fisher_langevin_coupling.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/encoding/__init__.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/encoding/auto_linker.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/encoding/consolidator.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/encoding/context_generator.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/encoding/entropy_gate.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/encoding/fact_extractor.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/encoding/foresight.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/encoding/graph_builder.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/encoding/observation_builder.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/encoding/scene_builder.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/encoding/signal_inference.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/encoding/temporal_parser.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/encoding/temporal_validator.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/encoding/type_router.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/hooks/__init__.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/hooks/auto_capture.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/hooks/auto_invoker.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/hooks/auto_parameterize.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/hooks/auto_recall.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/hooks/ide_connector.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/hooks/rules_engine.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/infra/__init__.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/infra/auth_middleware.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/infra/backup.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/infra/cache_manager.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/infra/event_bus.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/infra/heartbeat_monitor.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/infra/pid_manager.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/infra/process_reaper.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/infra/rate_limiter.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/infra/webhook_dispatcher.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/learning/__init__.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/learning/adaptive.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/learning/behavioral.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/learning/behavioral_listener.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/learning/bootstrap.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/learning/consolidation_quantization_worker.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/learning/consolidation_worker.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/learning/cross_project.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/learning/database.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/learning/engagement.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/learning/features.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/learning/feedback.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/learning/forgetting_scheduler.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/learning/outcomes.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/learning/project_context.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/learning/quantization_scheduler.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/learning/ranker.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/learning/signals.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/learning/source_quality.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/learning/workflows.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/llm/__init__.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/llm/backbone.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/math/__init__.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/math/ebbinghaus.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/math/fisher.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/math/fisher_quantized.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/math/hopfield.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/math/langevin.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/math/qjl.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/math/sheaf.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/mcp/__init__.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/mcp/resources.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/mcp/server.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/mcp/tools.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/mcp/tools_active.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/mcp/tools_core.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/mcp/tools_v28.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/mcp/tools_v3.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/mcp/tools_v33.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/parameterization/__init__.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/parameterization/pattern_extractor.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/parameterization/pii_filter.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/parameterization/prompt_injector.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/parameterization/prompt_lifecycle.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/parameterization/soft_prompt_generator.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/retrieval/__init__.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/retrieval/agentic.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/retrieval/ann_index.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/retrieval/bm25_channel.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/retrieval/bridge_discovery.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/retrieval/channel_registry.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/retrieval/entity_channel.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/retrieval/forgetting_filter.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/retrieval/fusion.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/retrieval/hopfield_channel.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/retrieval/profile_channel.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/retrieval/quantization_aware_search.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/retrieval/semantic_channel.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/retrieval/spreading_activation.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/retrieval/strategy.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/retrieval/temporal_channel.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/retrieval/vector_store.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/server/__init__.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/server/api.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/server/routes/__init__.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/server/routes/agents.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/server/routes/backup.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/server/routes/behavioral.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/server/routes/compliance.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/server/routes/data_io.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/server/routes/events.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/server/routes/helpers.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/server/routes/learning.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/server/routes/lifecycle.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/server/routes/memories.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/server/routes/profiles.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/server/routes/stats.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/server/routes/v3_api.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/server/routes/ws.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/server/security_middleware.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/server/ui.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/storage/__init__.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/storage/access_control.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/storage/access_log.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/storage/database.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/storage/migration_v33.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/storage/migrations.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/storage/models.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/storage/quantized_store.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/storage/schema.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/storage/schema_v32.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/storage/v2_migrator.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/trust/__init__.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/trust/gate.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/trust/provenance.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/trust/scorer.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/trust/signals.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory.egg-info/dependency_links.txt +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory.egg-info/entry_points.txt +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory.egg-info/requires.txt +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory.egg-info/top_level.txt +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/tests/test_auto_hooks.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/tests/test_behavioral_full.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/tests/test_cli.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/tests/test_cli_json.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/tests/test_compliance_full.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/tests/test_config_system.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/tests/test_engine_hooks.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/tests/test_event_bus.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/tests/test_features.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/tests/test_final_locomo_mini.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/tests/test_ide_connector.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/tests/test_infra.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/tests/test_learning_advanced.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/tests/test_learning_collectors.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/tests/test_llm_provider.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/tests/test_mcp_server.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/tests/test_migration.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/tests/test_post_install.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/tests/test_ranker.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/tests/test_trust_full.py +0 -0
- {superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/tests/test_v3_api.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: superlocalmemory
|
|
3
|
-
Version: 3.3.
|
|
3
|
+
Version: 3.3.6
|
|
4
4
|
Summary: Information-geometric agent memory with mathematical guarantees
|
|
5
5
|
Author-email: Varun Pratap Bhardwaj <admin@superlocalmemory.com>
|
|
6
6
|
License: MIT
|
|
@@ -72,7 +72,8 @@ Dynamic: license-file
|
|
|
72
72
|
</p>
|
|
73
73
|
|
|
74
74
|
<h1 align="center">SuperLocalMemory V3.3</h1>
|
|
75
|
-
<p align="center"><strong>
|
|
75
|
+
<p align="center"><strong>Every other AI forgets. Yours won't.</strong><br/><em>Infinite memory for Claude Code, Cursor, Windsurf & 17+ AI tools.</em></p>
|
|
76
|
+
<p align="center"><code>v3.3.6</code> — Install once. Every session remembers the last. Automatically.</p>
|
|
76
77
|
|
|
77
78
|
<p align="center">
|
|
78
79
|
<code>+16pp vs Mem0 (zero cloud)</code> · <code>85% Open-Domain (best of any system)</code> · <code>EU AI Act Ready</code>
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<h1 align="center">SuperLocalMemory V3.3</h1>
|
|
6
|
-
<p align="center"><strong>
|
|
6
|
+
<p align="center"><strong>Every other AI forgets. Yours won't.</strong><br/><em>Infinite memory for Claude Code, Cursor, Windsurf & 17+ AI tools.</em></p>
|
|
7
|
+
<p align="center"><code>v3.3.6</code> — Install once. Every session remembers the last. Automatically.</p>
|
|
7
8
|
|
|
8
9
|
<p align="center">
|
|
9
10
|
<code>+16pp vs Mem0 (zero cloud)</code> · <code>85% Open-Domain (best of any system)</code> · <code>EU AI Act Ready</code>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "superlocalmemory"
|
|
3
|
-
version = "3.3.
|
|
3
|
+
version = "3.3.6"
|
|
4
4
|
description = "Information-geometric agent memory with mathematical guarantees"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = {text = "MIT"}
|
|
@@ -98,6 +98,10 @@ testpaths = ["tests"]
|
|
|
98
98
|
pythonpath = ["src"]
|
|
99
99
|
markers = [
|
|
100
100
|
"slow: marks tests as slow (deselect with '-m \"not slow\"')",
|
|
101
|
+
"ollama: marks tests that require a running Ollama instance",
|
|
102
|
+
]
|
|
103
|
+
filterwarnings = [
|
|
104
|
+
"ignore::DeprecationWarning:vaderSentiment",
|
|
101
105
|
]
|
|
102
106
|
|
|
103
107
|
[tool.coverage.run]
|
|
@@ -18,7 +18,16 @@ from argparse import Namespace
|
|
|
18
18
|
|
|
19
19
|
def dispatch(args: Namespace) -> None:
|
|
20
20
|
"""Route CLI command to the appropriate handler."""
|
|
21
|
+
# Auto-install/upgrade hooks on version change (single file read, ~0.1ms)
|
|
22
|
+
if args.command not in ("hooks", "init", "mcp"):
|
|
23
|
+
try:
|
|
24
|
+
from superlocalmemory.hooks.claude_code_hooks import auto_install_if_needed
|
|
25
|
+
auto_install_if_needed()
|
|
26
|
+
except Exception:
|
|
27
|
+
pass
|
|
28
|
+
|
|
21
29
|
handlers = {
|
|
30
|
+
"init": cmd_init,
|
|
22
31
|
"setup": cmd_setup,
|
|
23
32
|
"mode": cmd_mode,
|
|
24
33
|
"provider": cmd_provider,
|
|
@@ -113,6 +122,10 @@ def cmd_mode(args: Namespace) -> None:
|
|
|
113
122
|
if (config.embedding.provider != updated.embedding.provider
|
|
114
123
|
or config.embedding.model_name != updated.embedding.model_name):
|
|
115
124
|
print(" ⚠ Embedding model changed. Re-indexing will run on next recall.")
|
|
125
|
+
|
|
126
|
+
# V3.3.4: Warn if Mode C lacks cloud API key
|
|
127
|
+
if args.value == "c" and not updated.llm.api_key:
|
|
128
|
+
print(" ⚠ Mode C requires a cloud API key. Run: slm provider set")
|
|
116
129
|
else:
|
|
117
130
|
print(f"Current mode: {config.mode.value.upper()}")
|
|
118
131
|
|
|
@@ -356,12 +369,20 @@ def cmd_forget(args: Namespace) -> None:
|
|
|
356
369
|
sys.exit(1)
|
|
357
370
|
raise
|
|
358
371
|
|
|
372
|
+
dry_run = getattr(args, 'dry_run', False)
|
|
373
|
+
|
|
359
374
|
if use_json:
|
|
360
375
|
from superlocalmemory.cli.json_output import json_print
|
|
361
376
|
if not matches:
|
|
362
377
|
json_print("forget", data={"matched_count": 0, "deleted_count": 0, "matches": []})
|
|
363
378
|
return
|
|
364
379
|
match_items = [{"fact_id": f.fact_id, "content": f.content[:120]} for f in matches[:20]]
|
|
380
|
+
if dry_run:
|
|
381
|
+
json_print("forget", data={
|
|
382
|
+
"matched_count": len(matches), "deleted_count": 0,
|
|
383
|
+
"dry_run": True, "matches": match_items,
|
|
384
|
+
})
|
|
385
|
+
return
|
|
365
386
|
if getattr(args, 'yes', False):
|
|
366
387
|
for f in matches:
|
|
367
388
|
engine._db.delete_fact(f.fact_id)
|
|
@@ -387,6 +408,9 @@ def cmd_forget(args: Namespace) -> None:
|
|
|
387
408
|
print(f"Found {len(matches)} matching memories:")
|
|
388
409
|
for f in matches[:10]:
|
|
389
410
|
print(f" - {f.fact_id[:8]}... {f.content[:80]}")
|
|
411
|
+
if dry_run:
|
|
412
|
+
print(f"(dry run — {len(matches)} would be deleted)")
|
|
413
|
+
return
|
|
390
414
|
if getattr(args, 'yes', False):
|
|
391
415
|
for f in matches:
|
|
392
416
|
engine._db.delete_fact(f.fact_id)
|
|
@@ -861,7 +885,8 @@ def cmd_trace(args: Namespace) -> None:
|
|
|
861
885
|
try:
|
|
862
886
|
config = SLMConfig.load()
|
|
863
887
|
engine = MemoryEngine(config)
|
|
864
|
-
|
|
888
|
+
limit = getattr(args, 'limit', 10)
|
|
889
|
+
response = engine.recall(args.query, limit=limit)
|
|
865
890
|
except Exception as exc:
|
|
866
891
|
if use_json:
|
|
867
892
|
from superlocalmemory.cli.json_output import json_print
|
|
@@ -907,6 +932,14 @@ def cmd_trace(args: Namespace) -> None:
|
|
|
907
932
|
|
|
908
933
|
def cmd_mcp(_args: Namespace) -> None:
|
|
909
934
|
"""Start the V3 MCP server (stdio transport for IDE integration)."""
|
|
935
|
+
# Auto-install hooks on MCP startup (fast path: ~0.1ms if already current)
|
|
936
|
+
# CRITICAL: No stdout — MCP uses stdio transport, any print corrupts protocol
|
|
937
|
+
try:
|
|
938
|
+
from superlocalmemory.hooks.claude_code_hooks import auto_install_if_needed
|
|
939
|
+
auto_install_if_needed()
|
|
940
|
+
except Exception:
|
|
941
|
+
pass
|
|
942
|
+
|
|
910
943
|
from superlocalmemory.mcp.server import server
|
|
911
944
|
|
|
912
945
|
server.run(transport="stdio")
|
|
@@ -1126,6 +1159,99 @@ def cmd_profile(args: Namespace) -> None:
|
|
|
1126
1159
|
# -- Active Memory commands (V3.1) ------------------------------------------
|
|
1127
1160
|
|
|
1128
1161
|
|
|
1162
|
+
def cmd_init(args: Namespace) -> None:
|
|
1163
|
+
"""One-command setup: mode + hooks + IDE connect + warmup."""
|
|
1164
|
+
from pathlib import Path
|
|
1165
|
+
from superlocalmemory.core.config import SLMConfig
|
|
1166
|
+
|
|
1167
|
+
force = getattr(args, "force", False)
|
|
1168
|
+
|
|
1169
|
+
config_exists = (Path.home() / ".superlocalmemory" / "config.json").exists()
|
|
1170
|
+
|
|
1171
|
+
print()
|
|
1172
|
+
print("SuperLocalMemory — One-Time Setup")
|
|
1173
|
+
print("=" * 40)
|
|
1174
|
+
|
|
1175
|
+
# Step 1: Mode selection (interactive)
|
|
1176
|
+
if force or not config_exists:
|
|
1177
|
+
print()
|
|
1178
|
+
from superlocalmemory.cli.setup_wizard import run_wizard
|
|
1179
|
+
run_wizard()
|
|
1180
|
+
else:
|
|
1181
|
+
config = SLMConfig.load()
|
|
1182
|
+
print(f"\n Already configured: Mode {config.mode.value.upper()}")
|
|
1183
|
+
print(f" Profile: {config.active_profile}")
|
|
1184
|
+
|
|
1185
|
+
# Step 2: Install hooks (gate always OFF by default)
|
|
1186
|
+
print()
|
|
1187
|
+
print("Installing Claude Code hooks...")
|
|
1188
|
+
from superlocalmemory.hooks.claude_code_hooks import install_hooks, check_status
|
|
1189
|
+
|
|
1190
|
+
status = check_status()
|
|
1191
|
+
|
|
1192
|
+
if status["installed"] and not force:
|
|
1193
|
+
if status["needs_upgrade"]:
|
|
1194
|
+
from superlocalmemory.hooks.claude_code_hooks import upgrade_hooks
|
|
1195
|
+
result = upgrade_hooks()
|
|
1196
|
+
if result.get("upgraded"):
|
|
1197
|
+
print(f" Hooks upgraded: {result['from_version']} -> {result['to_version']}")
|
|
1198
|
+
else:
|
|
1199
|
+
print(f" Upgrade issue: {result.get('reason', result.get('errors', ''))}")
|
|
1200
|
+
else:
|
|
1201
|
+
print(f" Hooks already installed (v{status['version']})")
|
|
1202
|
+
else:
|
|
1203
|
+
result = install_hooks(include_gate=False)
|
|
1204
|
+
if result["success"]:
|
|
1205
|
+
print(f" Hooks installed: {', '.join(result['hooks_added'])}")
|
|
1206
|
+
print(" SLM: Hooks installed into Claude Code (slm hooks remove to undo)")
|
|
1207
|
+
else:
|
|
1208
|
+
print(f" Hook install failed: {result['errors']}")
|
|
1209
|
+
|
|
1210
|
+
# Step 3: IDE connection
|
|
1211
|
+
print()
|
|
1212
|
+
print("Detecting IDEs...")
|
|
1213
|
+
try:
|
|
1214
|
+
from superlocalmemory.hooks.ide_connector import IDEConnector
|
|
1215
|
+
connector = IDEConnector()
|
|
1216
|
+
results = connector.connect_all()
|
|
1217
|
+
for ide_id, ide_status in results.items():
|
|
1218
|
+
print(f" {ide_id}: {ide_status}")
|
|
1219
|
+
except Exception as exc:
|
|
1220
|
+
print(f" IDE detection skipped: {exc}")
|
|
1221
|
+
|
|
1222
|
+
# Step 4: Warmup (embedding model)
|
|
1223
|
+
print()
|
|
1224
|
+
print("Checking embedding model...")
|
|
1225
|
+
try:
|
|
1226
|
+
from superlocalmemory.core.config import SLMConfig as _Cfg
|
|
1227
|
+
cfg = _Cfg.load()
|
|
1228
|
+
model_name = cfg.embedding.model_name
|
|
1229
|
+
print(f" Model: {model_name}")
|
|
1230
|
+
# Quick check: try creating embedding service (auto-downloads if needed)
|
|
1231
|
+
from superlocalmemory.core.embeddings import EmbeddingService
|
|
1232
|
+
svc = EmbeddingService(cfg.embedding)
|
|
1233
|
+
test_result = svc.embed_text("test")
|
|
1234
|
+
if test_result is not None and len(test_result) > 0:
|
|
1235
|
+
print(" Status: ready")
|
|
1236
|
+
else:
|
|
1237
|
+
print(" Status: model not available (run: slm warmup)")
|
|
1238
|
+
except Exception as exc:
|
|
1239
|
+
print(f" Warmup skipped: {exc}")
|
|
1240
|
+
print(" Run 'slm warmup' later to download the embedding model.")
|
|
1241
|
+
|
|
1242
|
+
# Done
|
|
1243
|
+
print()
|
|
1244
|
+
print("=" * 40)
|
|
1245
|
+
print("SLM is active. Your AI now remembers you.")
|
|
1246
|
+
print()
|
|
1247
|
+
print("What happens next:")
|
|
1248
|
+
print(" - Open Claude Code in any project")
|
|
1249
|
+
print(" - SLM auto-injects your memory context")
|
|
1250
|
+
print(" - Decisions, bugs, preferences are captured automatically")
|
|
1251
|
+
print(" - Session summaries saved when you close")
|
|
1252
|
+
print()
|
|
1253
|
+
|
|
1254
|
+
|
|
1129
1255
|
def cmd_hooks(args: Namespace) -> None:
|
|
1130
1256
|
"""Manage Claude Code hooks for invisible memory injection."""
|
|
1131
1257
|
from superlocalmemory.hooks.claude_code_hooks import (
|
|
@@ -1133,28 +1259,38 @@ def cmd_hooks(args: Namespace) -> None:
|
|
|
1133
1259
|
)
|
|
1134
1260
|
|
|
1135
1261
|
action = getattr(args, "action", "status")
|
|
1262
|
+
# Gate is OFF by default. --gate opts in (for brave users).
|
|
1263
|
+
include_gate = getattr(args, "gate", False)
|
|
1264
|
+
|
|
1136
1265
|
if action == "install":
|
|
1137
|
-
result = install_hooks()
|
|
1138
|
-
if result["
|
|
1266
|
+
result = install_hooks(include_gate=include_gate)
|
|
1267
|
+
if result["success"]:
|
|
1139
1268
|
print("SLM hooks installed in Claude Code.")
|
|
1140
|
-
print("
|
|
1269
|
+
print(f" Hook types: {', '.join(result['hooks_added'])}")
|
|
1270
|
+
if include_gate:
|
|
1271
|
+
print(" Gate: ON (enforces session_init — experimental)")
|
|
1272
|
+
print(" SLM: Hooks installed into Claude Code (slm hooks remove to undo)")
|
|
1141
1273
|
else:
|
|
1142
|
-
print(f"Installation
|
|
1274
|
+
print(f"Installation failed: {result['errors']}")
|
|
1143
1275
|
elif action == "remove":
|
|
1144
1276
|
result = remove_hooks()
|
|
1145
|
-
if result["
|
|
1277
|
+
if result["success"]:
|
|
1146
1278
|
print("SLM hooks removed from Claude Code.")
|
|
1147
1279
|
else:
|
|
1148
|
-
print(f"Removal
|
|
1280
|
+
print(f"Removal failed: {result['errors']}")
|
|
1149
1281
|
else:
|
|
1150
1282
|
result = check_status()
|
|
1151
1283
|
if result["installed"]:
|
|
1152
|
-
print("SLM hooks: INSTALLED")
|
|
1153
|
-
print(f"
|
|
1154
|
-
print("
|
|
1284
|
+
print(f"SLM hooks: INSTALLED (v{result['version']})")
|
|
1285
|
+
print(f" Hook types: {', '.join(result['hook_types'])}")
|
|
1286
|
+
print(f" Gate: {'ON' if result['gate_enabled'] else 'OFF'}")
|
|
1287
|
+
if result["needs_upgrade"]:
|
|
1288
|
+
print(f" Update available: {result['version']} -> {result['latest_version']}")
|
|
1289
|
+
print(" Run: slm hooks install")
|
|
1155
1290
|
else:
|
|
1156
1291
|
print("SLM hooks: NOT INSTALLED")
|
|
1157
1292
|
print(" Run: slm hooks install")
|
|
1293
|
+
print(" Or: slm init (full setup)")
|
|
1158
1294
|
|
|
1159
1295
|
|
|
1160
1296
|
def cmd_session_context(args: Namespace) -> None:
|
|
@@ -1435,6 +1571,7 @@ def cmd_consolidate(args: Namespace) -> None:
|
|
|
1435
1571
|
|
|
1436
1572
|
use_json = getattr(args, "json", False)
|
|
1437
1573
|
cognitive = getattr(args, "cognitive", False)
|
|
1574
|
+
dry_run = getattr(args, "dry_run", False)
|
|
1438
1575
|
profile = getattr(args, "profile", "")
|
|
1439
1576
|
|
|
1440
1577
|
if not cognitive:
|
|
@@ -1460,7 +1597,7 @@ def cmd_consolidate(args: Namespace) -> None:
|
|
|
1460
1597
|
)
|
|
1461
1598
|
|
|
1462
1599
|
consolidator = CognitiveConsolidator(db=engine._db)
|
|
1463
|
-
result = consolidator.run_pipeline(pid)
|
|
1600
|
+
result = consolidator.run_pipeline(pid, dry_run=dry_run)
|
|
1464
1601
|
except Exception as exc:
|
|
1465
1602
|
if use_json:
|
|
1466
1603
|
from superlocalmemory.cli.json_output import json_print
|
|
@@ -1473,7 +1610,7 @@ def cmd_consolidate(args: Namespace) -> None:
|
|
|
1473
1610
|
if use_json:
|
|
1474
1611
|
from superlocalmemory.cli.json_output import json_print
|
|
1475
1612
|
json_print("consolidate", data={
|
|
1476
|
-
"
|
|
1613
|
+
"clusters_processed": result.clusters_processed,
|
|
1477
1614
|
"blocks_created": result.blocks_created,
|
|
1478
1615
|
"facts_archived": result.facts_archived,
|
|
1479
1616
|
"compression_ratio": round(result.compression_ratio, 3),
|
|
@@ -1484,7 +1621,7 @@ def cmd_consolidate(args: Namespace) -> None:
|
|
|
1484
1621
|
return
|
|
1485
1622
|
|
|
1486
1623
|
print("CCQ Cognitive Consolidation")
|
|
1487
|
-
print(f" Clusters
|
|
1624
|
+
print(f" Clusters processed: {result.clusters_processed}")
|
|
1488
1625
|
print(f" Blocks created: {result.blocks_created}")
|
|
1489
1626
|
print(f" Facts archived: {result.facts_archived}")
|
|
1490
1627
|
print(f" Compression ratio: {result.compression_ratio:.3f}")
|
|
@@ -70,6 +70,12 @@ documentation:
|
|
|
70
70
|
|
|
71
71
|
def main() -> None:
|
|
72
72
|
"""Parse CLI arguments and dispatch to command handlers."""
|
|
73
|
+
# Fast path: hook invocations bypass argparse entirely (stdlib only, ~30ms)
|
|
74
|
+
if len(sys.argv) >= 3 and sys.argv[1] == "hook":
|
|
75
|
+
from superlocalmemory.hooks.hook_handlers import handle_hook
|
|
76
|
+
handle_hook(sys.argv[2])
|
|
77
|
+
return
|
|
78
|
+
|
|
73
79
|
from superlocalmemory.cli.json_output import _get_version
|
|
74
80
|
_ver = _get_version()
|
|
75
81
|
|
|
@@ -85,6 +91,15 @@ def main() -> None:
|
|
|
85
91
|
sub = parser.add_subparsers(dest="command", title="commands")
|
|
86
92
|
|
|
87
93
|
# -- Setup & Config ------------------------------------------------
|
|
94
|
+
init_p = sub.add_parser("init", help="One-command setup: mode + hooks + IDE + warmup")
|
|
95
|
+
init_p.add_argument(
|
|
96
|
+
"--force", action="store_true", help="Re-run full setup even if already configured",
|
|
97
|
+
)
|
|
98
|
+
init_p.add_argument(
|
|
99
|
+
"--gate", action="store_true",
|
|
100
|
+
help="Enable PreToolUse gate (experimental — blocks tools until session_init)",
|
|
101
|
+
)
|
|
102
|
+
|
|
88
103
|
sub.add_parser("setup", help="Interactive first-time setup wizard")
|
|
89
104
|
|
|
90
105
|
mode_p = sub.add_parser("mode", help="Get or set operating mode (a/b/c)")
|
|
@@ -123,6 +138,7 @@ def main() -> None:
|
|
|
123
138
|
|
|
124
139
|
forget_p = sub.add_parser("forget", help="Delete memories matching a query (fuzzy)")
|
|
125
140
|
forget_p.add_argument("query", help="Query to match for deletion")
|
|
141
|
+
forget_p.add_argument("--dry-run", action="store_true", default=False, help="Preview matches without deleting")
|
|
126
142
|
forget_p.add_argument("--yes", "-y", action="store_true", help="Skip confirmation prompt")
|
|
127
143
|
forget_p.add_argument("--json", action="store_true", help="Output structured JSON (agent-native)")
|
|
128
144
|
|
|
@@ -151,6 +167,7 @@ def main() -> None:
|
|
|
151
167
|
|
|
152
168
|
trace_p = sub.add_parser("trace", help="Recall with per-channel score breakdown")
|
|
153
169
|
trace_p.add_argument("query", help="Search query")
|
|
170
|
+
trace_p.add_argument("--limit", type=int, default=10, help="Max results (default 10)")
|
|
154
171
|
trace_p.add_argument("--json", action="store_true", help="Output structured JSON (agent-native)")
|
|
155
172
|
|
|
156
173
|
# -- Diagnostics (continued) ----------------------------------------
|
|
@@ -180,6 +197,10 @@ def main() -> None:
|
|
|
180
197
|
"action", nargs="?", default="status",
|
|
181
198
|
choices=["install", "remove", "status"], help="Action (default: status)",
|
|
182
199
|
)
|
|
200
|
+
hooks_p.add_argument(
|
|
201
|
+
"--gate", action="store_true",
|
|
202
|
+
help="Enable PreToolUse gate (experimental — blocks tools until session_init)",
|
|
203
|
+
)
|
|
183
204
|
|
|
184
205
|
ctx_p = sub.add_parser("session-context", help="Print session context (for hooks)")
|
|
185
206
|
ctx_p.add_argument("query", nargs="?", default="", help="Optional context query")
|
|
@@ -217,6 +238,10 @@ def main() -> None:
|
|
|
217
238
|
"--cognitive", action="store_true",
|
|
218
239
|
help="Run CCQ cognitive consolidation",
|
|
219
240
|
)
|
|
241
|
+
consolidate_p.add_argument(
|
|
242
|
+
"--dry-run", action="store_true", default=False,
|
|
243
|
+
help="Preview without applying",
|
|
244
|
+
)
|
|
220
245
|
consolidate_p.add_argument("--profile", default="", help="Target profile")
|
|
221
246
|
consolidate_p.add_argument("--json", action="store_true", help="Output structured JSON (agent-native)")
|
|
222
247
|
|
|
@@ -612,15 +612,15 @@ class SLMConfig:
|
|
|
612
612
|
|
|
613
613
|
rt = data.get("retrieval", {})
|
|
614
614
|
if rt:
|
|
615
|
-
# V3.3.2 migration:
|
|
616
|
-
# Pre-3.3.2 configs
|
|
617
|
-
#
|
|
618
|
-
#
|
|
619
|
-
# by the absence of cross_encoder_backend field.
|
|
615
|
+
# V3.3.2 migration: add ONNX cross-encoder backend field.
|
|
616
|
+
# Pre-3.3.2 configs lacked cross_encoder_backend. Add it,
|
|
617
|
+
# but NEVER override an explicit use_cross_encoder setting.
|
|
618
|
+
# The user's explicit choice always wins.
|
|
620
619
|
if "cross_encoder_backend" not in rt:
|
|
621
|
-
rt
|
|
622
|
-
rt["cross_encoder_model"] = "cross-encoder/ms-marco-MiniLM-L-6-v2"
|
|
620
|
+
rt.setdefault("cross_encoder_model", "cross-encoder/ms-marco-MiniLM-L-6-v2")
|
|
623
621
|
rt["cross_encoder_backend"] = "onnx"
|
|
622
|
+
# Only auto-enable if user didn't explicitly set the field
|
|
623
|
+
rt.setdefault("use_cross_encoder", True)
|
|
624
624
|
config.retrieval = RetrievalConfig(**{
|
|
625
625
|
k: v for k, v in rt.items()
|
|
626
626
|
if k in RetrievalConfig.__dataclass_fields__
|
|
@@ -768,6 +768,9 @@ class SLMConfig:
|
|
|
768
768
|
)
|
|
769
769
|
|
|
770
770
|
# Mode C — FULL POWER, UNRESTRICTED
|
|
771
|
+
# Don't carry over local-only providers (ollama) to cloud mode
|
|
772
|
+
c_provider = llm_provider if llm_provider not in ("ollama", "") else "openrouter"
|
|
773
|
+
c_model = llm_model if llm_provider not in ("ollama", "") else "anthropic/claude-sonnet-4"
|
|
771
774
|
return cls(
|
|
772
775
|
mode=mode,
|
|
773
776
|
base_dir=_base,
|
|
@@ -779,8 +782,8 @@ class SLMConfig:
|
|
|
779
782
|
deployment_name=embedding_deployment,
|
|
780
783
|
),
|
|
781
784
|
llm=LLMConfig(
|
|
782
|
-
provider=
|
|
783
|
-
model=
|
|
785
|
+
provider=c_provider,
|
|
786
|
+
model=c_model,
|
|
784
787
|
api_key=llm_api_key,
|
|
785
788
|
api_base=llm_api_base,
|
|
786
789
|
),
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
Periodic batch processing for mathematical layers:
|
|
8
8
|
1. Langevin batch_step on all active facts (self-organization)
|
|
9
|
+
1a. Backfill: seed uninitialized facts with metadata-aware positions (B+C)
|
|
9
10
|
2. Sheaf batch consistency check on recent facts
|
|
10
11
|
3. Fisher adaptive temperature recalculation
|
|
11
12
|
|
|
@@ -18,15 +19,72 @@ License: MIT
|
|
|
18
19
|
from __future__ import annotations
|
|
19
20
|
|
|
20
21
|
import logging
|
|
22
|
+
import math as _math
|
|
21
23
|
from datetime import UTC, datetime, timedelta
|
|
22
24
|
from typing import TYPE_CHECKING
|
|
23
25
|
|
|
26
|
+
import numpy as np
|
|
27
|
+
|
|
24
28
|
if TYPE_CHECKING:
|
|
25
29
|
from superlocalmemory.core.config import SLMConfig
|
|
26
30
|
from superlocalmemory.storage.database import DatabaseManager
|
|
27
31
|
|
|
28
32
|
logger = logging.getLogger(__name__)
|
|
29
33
|
|
|
34
|
+
# Backfill constants
|
|
35
|
+
_BACKFILL_BURN_IN_STEPS = 50
|
|
36
|
+
_LANGEVIN_DIM = 8
|
|
37
|
+
_MAX_NORM = 0.99
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _compute_equilibrium_radius(
|
|
41
|
+
access_count: int,
|
|
42
|
+
age_days: float,
|
|
43
|
+
importance: float,
|
|
44
|
+
temperature: float = 0.3,
|
|
45
|
+
dim: int = 8,
|
|
46
|
+
) -> float:
|
|
47
|
+
"""Compute metadata-aware equilibrium radius (Strategy B).
|
|
48
|
+
|
|
49
|
+
Uses the Langevin potential coefficients to estimate where a fact
|
|
50
|
+
would settle if it had been in the dynamics from the start.
|
|
51
|
+
|
|
52
|
+
r_eq ≈ sqrt(T * dim / (2 * effective_alpha))
|
|
53
|
+
"""
|
|
54
|
+
alpha, beta, gamma, delta = 3.0, 0.8, 0.005, 0.5
|
|
55
|
+
effective_alpha = (
|
|
56
|
+
alpha
|
|
57
|
+
+ beta * _math.log(access_count + 1) / 10.0
|
|
58
|
+
- gamma * min(age_days, 365.0) / 365.0
|
|
59
|
+
+ delta * importance
|
|
60
|
+
)
|
|
61
|
+
effective_alpha = max(0.1, effective_alpha)
|
|
62
|
+
r_eq = _math.sqrt(temperature * dim / (2.0 * effective_alpha))
|
|
63
|
+
return min(r_eq, _MAX_NORM * 0.95)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _seed_langevin_position(
|
|
67
|
+
access_count: int,
|
|
68
|
+
age_days: float,
|
|
69
|
+
importance: float,
|
|
70
|
+
temperature: float = 0.3,
|
|
71
|
+
dim: int = 8,
|
|
72
|
+
) -> list[float]:
|
|
73
|
+
"""Create a metadata-aware initial position (Strategy B).
|
|
74
|
+
|
|
75
|
+
Places the fact at the equilibrium radius with a random direction.
|
|
76
|
+
"""
|
|
77
|
+
r_eq = _compute_equilibrium_radius(
|
|
78
|
+
access_count, age_days, importance, temperature, dim,
|
|
79
|
+
)
|
|
80
|
+
rng = np.random.default_rng()
|
|
81
|
+
direction = rng.standard_normal(dim)
|
|
82
|
+
norm = float(np.linalg.norm(direction))
|
|
83
|
+
if norm < 1e-8:
|
|
84
|
+
direction = np.ones(dim)
|
|
85
|
+
norm = float(np.linalg.norm(direction))
|
|
86
|
+
return (direction / norm * r_eq).tolist()
|
|
87
|
+
|
|
30
88
|
|
|
31
89
|
def run_maintenance(
|
|
32
90
|
db: DatabaseManager,
|
|
@@ -44,6 +102,7 @@ def run_maintenance(
|
|
|
44
102
|
Dict of counts: langevin_updated, sheaf_checked, etc.
|
|
45
103
|
"""
|
|
46
104
|
counts: dict[str, int] = {
|
|
105
|
+
"langevin_backfilled": 0,
|
|
47
106
|
"langevin_updated": 0,
|
|
48
107
|
"fisher_coupled": 0,
|
|
49
108
|
"sheaf_checked": 0,
|
|
@@ -53,13 +112,60 @@ def run_maintenance(
|
|
|
53
112
|
if not facts:
|
|
54
113
|
return counts
|
|
55
114
|
|
|
56
|
-
#
|
|
115
|
+
# 1a. Backfill: seed uninitialized facts with metadata-aware positions (B+C)
|
|
116
|
+
if config.math.langevin_persist_positions:
|
|
117
|
+
try:
|
|
118
|
+
from superlocalmemory.math.langevin import LangevinDynamics
|
|
119
|
+
|
|
120
|
+
ld = LangevinDynamics(
|
|
121
|
+
dim=_LANGEVIN_DIM,
|
|
122
|
+
dt=config.math.langevin_dt,
|
|
123
|
+
temperature=config.math.langevin_temperature,
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
backfilled = 0
|
|
127
|
+
for f in facts:
|
|
128
|
+
if f.langevin_position is not None:
|
|
129
|
+
continue
|
|
130
|
+
created = datetime.fromisoformat(
|
|
131
|
+
f.created_at.replace("Z", "+00:00")
|
|
132
|
+
) if f.created_at else datetime.now(UTC)
|
|
133
|
+
age_days = max(
|
|
134
|
+
0.0,
|
|
135
|
+
(datetime.now(UTC) - created).total_seconds() / 86400.0,
|
|
136
|
+
)
|
|
137
|
+
# Strategy B: metadata-aware seed position
|
|
138
|
+
position = _seed_langevin_position(
|
|
139
|
+
f.access_count, age_days, f.importance,
|
|
140
|
+
config.math.langevin_temperature, _LANGEVIN_DIM,
|
|
141
|
+
)
|
|
142
|
+
# Strategy C: burn-in from the seeded position
|
|
143
|
+
for step_i in range(_BACKFILL_BURN_IN_STEPS):
|
|
144
|
+
position, _ = ld.step(
|
|
145
|
+
position, f.access_count, age_days, f.importance,
|
|
146
|
+
)
|
|
147
|
+
weight = ld.compute_lifecycle_weight(position)
|
|
148
|
+
lifecycle = ld.get_lifecycle_state(weight).value
|
|
149
|
+
db.update_fact(f.fact_id, {
|
|
150
|
+
"langevin_position": position,
|
|
151
|
+
"lifecycle": lifecycle,
|
|
152
|
+
})
|
|
153
|
+
f.langevin_position = position # update in-memory for step 1b
|
|
154
|
+
backfilled += 1
|
|
155
|
+
|
|
156
|
+
counts["langevin_backfilled"] = backfilled
|
|
157
|
+
if backfilled:
|
|
158
|
+
logger.info("Langevin backfill: %d facts initialized", backfilled)
|
|
159
|
+
except Exception as exc:
|
|
160
|
+
logger.warning("Langevin backfill failed: %s", exc)
|
|
161
|
+
|
|
162
|
+
# 1b. Langevin batch step on all positioned facts
|
|
57
163
|
if config.math.langevin_persist_positions:
|
|
58
164
|
try:
|
|
59
165
|
from superlocalmemory.math.langevin import LangevinDynamics
|
|
60
166
|
|
|
61
167
|
ld = LangevinDynamics(
|
|
62
|
-
dim=
|
|
168
|
+
dim=_LANGEVIN_DIM,
|
|
63
169
|
dt=config.math.langevin_dt,
|
|
64
170
|
temperature=config.math.langevin_temperature,
|
|
65
171
|
)
|
|
@@ -165,8 +271,8 @@ def run_maintenance(
|
|
|
165
271
|
logger.warning("Sheaf maintenance failed: %s", exc)
|
|
166
272
|
|
|
167
273
|
logger.info(
|
|
168
|
-
"Maintenance complete: %d Langevin, %d Fisher-coupled, %d Sheaf",
|
|
169
|
-
counts["
|
|
170
|
-
counts["sheaf_checked"],
|
|
274
|
+
"Maintenance complete: %d backfilled, %d Langevin, %d Fisher-coupled, %d Sheaf",
|
|
275
|
+
counts["langevin_backfilled"], counts["langevin_updated"],
|
|
276
|
+
counts["fisher_coupled"], counts["sheaf_checked"],
|
|
171
277
|
)
|
|
172
278
|
return counts
|
{superlocalmemory-3.3.2 → superlocalmemory-3.3.6}/src/superlocalmemory/core/store_pipeline.py
RENAMED
|
@@ -25,6 +25,25 @@ from superlocalmemory.storage.models import (
|
|
|
25
25
|
|
|
26
26
|
logger = logging.getLogger(__name__)
|
|
27
27
|
|
|
28
|
+
# Langevin initialization radius for new facts (ACTIVE zone < 0.3)
|
|
29
|
+
_INIT_LANGEVIN_RADIUS = 0.05
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _init_langevin_position(dim: int = 8) -> list[float]:
|
|
33
|
+
"""Initialize Langevin position near origin for a new fact.
|
|
34
|
+
|
|
35
|
+
Small random perturbation ensures each fact gets a unique position
|
|
36
|
+
while staying deep in the ACTIVE zone (radius < 0.3).
|
|
37
|
+
"""
|
|
38
|
+
import numpy as np
|
|
39
|
+
rng = np.random.default_rng()
|
|
40
|
+
direction = rng.standard_normal(dim)
|
|
41
|
+
norm = float(np.linalg.norm(direction))
|
|
42
|
+
if norm < 1e-8:
|
|
43
|
+
direction = np.ones(dim)
|
|
44
|
+
norm = float(np.linalg.norm(direction))
|
|
45
|
+
return (direction / norm * _INIT_LANGEVIN_RADIUS).tolist()
|
|
46
|
+
|
|
28
47
|
|
|
29
48
|
# ---------------------------------------------------------------------------
|
|
30
49
|
# enrich_fact (was MemoryEngine._enrich_fact)
|
|
@@ -59,6 +78,10 @@ def enrich_fact(
|
|
|
59
78
|
emotion = tag_emotion(fact.content)
|
|
60
79
|
signal = infer_signal(fact.content)
|
|
61
80
|
|
|
81
|
+
# Strategy A: initialize Langevin position near origin (ACTIVE zone).
|
|
82
|
+
# New facts start as ACTIVE; dynamics will evolve them based on access patterns.
|
|
83
|
+
langevin_pos = _init_langevin_position(dim=8)
|
|
84
|
+
|
|
62
85
|
return AtomicFact(
|
|
63
86
|
fact_id=fact.fact_id, memory_id=record.memory_id,
|
|
64
87
|
profile_id=profile_id, content=fact.content,
|
|
@@ -73,6 +96,7 @@ def enrich_fact(
|
|
|
73
96
|
evidence_count=fact.evidence_count,
|
|
74
97
|
source_turn_ids=fact.source_turn_ids, session_id=record.session_id,
|
|
75
98
|
embedding=embedding, fisher_mean=fisher_mean, fisher_variance=fisher_variance,
|
|
99
|
+
langevin_position=langevin_pos,
|
|
76
100
|
emotional_valence=emotion.valence, emotional_arousal=emotion.arousal,
|
|
77
101
|
signal_type=signal, created_at=fact.created_at,
|
|
78
102
|
)
|
|
@@ -142,8 +142,15 @@ class WorkerPool:
|
|
|
142
142
|
# ------------------------------------------------------------------
|
|
143
143
|
|
|
144
144
|
def _send(self, request: dict) -> dict:
|
|
145
|
-
"""Send request to worker and get response. Thread-safe.
|
|
146
|
-
|
|
145
|
+
"""Send request to worker and get response. Thread-safe.
|
|
146
|
+
|
|
147
|
+
Auto-retries once on worker death (idle timeout, crash).
|
|
148
|
+
"""
|
|
149
|
+
resp = self._send_with_timeout(request, timeout=_REQUEST_TIMEOUT)
|
|
150
|
+
if not resp.get("ok") and "Worker" in resp.get("error", ""):
|
|
151
|
+
logger.info("Auto-restarting worker after failure, retrying request")
|
|
152
|
+
resp = self._send_with_timeout(request, timeout=_REQUEST_TIMEOUT)
|
|
153
|
+
return resp
|
|
147
154
|
|
|
148
155
|
def _send_with_timeout(self, request: dict, timeout: float) -> dict:
|
|
149
156
|
"""Send request with configurable timeout. Thread-safe."""
|