superlocalmemory 2.8.6 → 3.0.0
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.
- package/LICENSE +9 -1
- package/NOTICE +63 -0
- package/README.md +165 -480
- package/bin/slm +17 -449
- package/bin/slm-npm +1 -1
- package/conftest.py +5 -0
- package/docs/api-reference.md +284 -0
- package/docs/architecture.md +149 -0
- package/docs/auto-memory.md +150 -0
- package/docs/cli-reference.md +276 -0
- package/docs/compliance.md +191 -0
- package/docs/configuration.md +182 -0
- package/docs/getting-started.md +102 -0
- package/docs/ide-setup.md +261 -0
- package/docs/mcp-tools.md +220 -0
- package/docs/migration-from-v2.md +170 -0
- package/docs/profiles.md +173 -0
- package/docs/troubleshooting.md +310 -0
- package/{configs → ide/configs}/antigravity-mcp.json +3 -3
- package/ide/configs/chatgpt-desktop-mcp.json +16 -0
- package/{configs → ide/configs}/claude-desktop-mcp.json +3 -3
- package/{configs → ide/configs}/codex-mcp.toml +4 -4
- package/{configs → ide/configs}/continue-mcp.yaml +4 -3
- package/{configs → ide/configs}/continue-skills.yaml +6 -6
- package/ide/configs/cursor-mcp.json +15 -0
- package/{configs → ide/configs}/gemini-cli-mcp.json +2 -2
- package/{configs → ide/configs}/jetbrains-mcp.json +2 -2
- package/{configs → ide/configs}/opencode-mcp.json +2 -2
- package/{configs → ide/configs}/perplexity-mcp.json +2 -2
- package/{configs → ide/configs}/vscode-copilot-mcp.json +2 -2
- package/{configs → ide/configs}/windsurf-mcp.json +3 -3
- package/{configs → ide/configs}/zed-mcp.json +2 -2
- package/{hooks → ide/hooks}/context-hook.js +9 -20
- package/ide/hooks/memory-list-skill.js +70 -0
- package/ide/hooks/memory-profile-skill.js +101 -0
- package/ide/hooks/memory-recall-skill.js +62 -0
- package/ide/hooks/memory-remember-skill.js +68 -0
- package/ide/hooks/memory-reset-skill.js +160 -0
- package/{hooks → ide/hooks}/post-recall-hook.js +2 -2
- package/ide/integrations/langchain/README.md +106 -0
- package/ide/integrations/langchain/langchain_superlocalmemory/__init__.py +9 -0
- package/ide/integrations/langchain/langchain_superlocalmemory/chat_message_history.py +201 -0
- package/ide/integrations/langchain/pyproject.toml +38 -0
- package/{src/learning → ide/integrations/langchain}/tests/__init__.py +1 -0
- package/ide/integrations/langchain/tests/test_chat_message_history.py +215 -0
- package/ide/integrations/langchain/tests/test_security.py +117 -0
- package/ide/integrations/llamaindex/README.md +81 -0
- package/ide/integrations/llamaindex/llama_index/storage/chat_store/superlocalmemory/__init__.py +9 -0
- package/ide/integrations/llamaindex/llama_index/storage/chat_store/superlocalmemory/base.py +316 -0
- package/ide/integrations/llamaindex/pyproject.toml +43 -0
- package/{src/lifecycle → ide/integrations/llamaindex}/tests/__init__.py +1 -2
- package/ide/integrations/llamaindex/tests/test_chat_store.py +294 -0
- package/ide/integrations/llamaindex/tests/test_security.py +241 -0
- package/{skills → ide/skills}/slm-build-graph/SKILL.md +6 -6
- package/{skills → ide/skills}/slm-list-recent/SKILL.md +5 -5
- package/{skills → ide/skills}/slm-recall/SKILL.md +5 -5
- package/{skills → ide/skills}/slm-remember/SKILL.md +6 -6
- package/{skills → ide/skills}/slm-show-patterns/SKILL.md +7 -7
- package/{skills → ide/skills}/slm-status/SKILL.md +9 -9
- package/{skills → ide/skills}/slm-switch-profile/SKILL.md +9 -9
- package/package.json +13 -22
- package/pyproject.toml +85 -0
- package/scripts/build-dmg.sh +417 -0
- package/scripts/install-skills.ps1 +334 -0
- package/scripts/postinstall.js +2 -2
- package/scripts/start-dashboard.ps1 +52 -0
- package/scripts/start-dashboard.sh +41 -0
- package/scripts/sync-wiki.ps1 +127 -0
- package/scripts/sync-wiki.sh +82 -0
- package/scripts/test-dmg.sh +161 -0
- package/scripts/test-npm-package.ps1 +252 -0
- package/scripts/test-npm-package.sh +207 -0
- package/scripts/verify-install.ps1 +294 -0
- package/scripts/verify-install.sh +266 -0
- package/src/superlocalmemory/__init__.py +0 -0
- package/src/superlocalmemory/attribution/__init__.py +9 -0
- package/src/superlocalmemory/attribution/mathematical_dna.py +235 -0
- package/src/superlocalmemory/attribution/signer.py +153 -0
- package/src/superlocalmemory/attribution/watermark.py +189 -0
- package/src/superlocalmemory/cli/__init__.py +5 -0
- package/src/superlocalmemory/cli/commands.py +245 -0
- package/src/superlocalmemory/cli/main.py +89 -0
- package/src/superlocalmemory/cli/migrate_cmd.py +55 -0
- package/src/superlocalmemory/cli/post_install.py +99 -0
- package/src/superlocalmemory/cli/setup_wizard.py +129 -0
- package/src/superlocalmemory/compliance/__init__.py +0 -0
- package/src/superlocalmemory/compliance/abac.py +204 -0
- package/src/superlocalmemory/compliance/audit.py +314 -0
- package/src/superlocalmemory/compliance/eu_ai_act.py +131 -0
- package/src/superlocalmemory/compliance/gdpr.py +294 -0
- package/src/superlocalmemory/compliance/lifecycle.py +158 -0
- package/src/superlocalmemory/compliance/retention.py +232 -0
- package/src/superlocalmemory/compliance/scheduler.py +148 -0
- package/src/superlocalmemory/core/__init__.py +0 -0
- package/src/superlocalmemory/core/config.py +391 -0
- package/src/superlocalmemory/core/embeddings.py +293 -0
- package/src/superlocalmemory/core/engine.py +701 -0
- package/src/superlocalmemory/core/hooks.py +65 -0
- package/src/superlocalmemory/core/maintenance.py +172 -0
- package/src/superlocalmemory/core/modes.py +140 -0
- package/src/superlocalmemory/core/profiles.py +234 -0
- package/src/superlocalmemory/core/registry.py +117 -0
- package/src/superlocalmemory/dynamics/__init__.py +0 -0
- package/src/superlocalmemory/dynamics/fisher_langevin_coupling.py +223 -0
- package/src/superlocalmemory/encoding/__init__.py +0 -0
- package/src/superlocalmemory/encoding/consolidator.py +485 -0
- package/src/superlocalmemory/encoding/emotional.py +125 -0
- package/src/superlocalmemory/encoding/entity_resolver.py +525 -0
- package/src/superlocalmemory/encoding/entropy_gate.py +104 -0
- package/src/superlocalmemory/encoding/fact_extractor.py +775 -0
- package/src/superlocalmemory/encoding/foresight.py +91 -0
- package/src/superlocalmemory/encoding/graph_builder.py +302 -0
- package/src/superlocalmemory/encoding/observation_builder.py +160 -0
- package/src/superlocalmemory/encoding/scene_builder.py +183 -0
- package/src/superlocalmemory/encoding/signal_inference.py +90 -0
- package/src/superlocalmemory/encoding/temporal_parser.py +426 -0
- package/src/superlocalmemory/encoding/type_router.py +235 -0
- package/src/superlocalmemory/hooks/__init__.py +3 -0
- package/src/superlocalmemory/hooks/auto_capture.py +111 -0
- package/src/superlocalmemory/hooks/auto_recall.py +93 -0
- package/src/superlocalmemory/hooks/ide_connector.py +204 -0
- package/src/superlocalmemory/hooks/rules_engine.py +99 -0
- package/src/superlocalmemory/infra/__init__.py +3 -0
- package/src/superlocalmemory/infra/auth_middleware.py +82 -0
- package/src/superlocalmemory/infra/backup.py +317 -0
- package/src/superlocalmemory/infra/cache_manager.py +267 -0
- package/src/superlocalmemory/infra/event_bus.py +381 -0
- package/src/superlocalmemory/infra/rate_limiter.py +135 -0
- package/src/{webhook_dispatcher.py → superlocalmemory/infra/webhook_dispatcher.py} +104 -101
- package/src/superlocalmemory/learning/__init__.py +0 -0
- package/src/superlocalmemory/learning/adaptive.py +172 -0
- package/src/superlocalmemory/learning/behavioral.py +490 -0
- package/src/superlocalmemory/learning/behavioral_listener.py +94 -0
- package/src/superlocalmemory/learning/bootstrap.py +298 -0
- package/src/superlocalmemory/learning/cross_project.py +399 -0
- package/src/superlocalmemory/learning/database.py +376 -0
- package/src/superlocalmemory/learning/engagement.py +323 -0
- package/src/superlocalmemory/learning/features.py +138 -0
- package/src/superlocalmemory/learning/feedback.py +316 -0
- package/src/superlocalmemory/learning/outcomes.py +255 -0
- package/src/superlocalmemory/learning/project_context.py +366 -0
- package/src/superlocalmemory/learning/ranker.py +155 -0
- package/src/superlocalmemory/learning/source_quality.py +303 -0
- package/src/superlocalmemory/learning/workflows.py +309 -0
- package/src/superlocalmemory/llm/__init__.py +0 -0
- package/src/superlocalmemory/llm/backbone.py +316 -0
- package/src/superlocalmemory/math/__init__.py +0 -0
- package/src/superlocalmemory/math/fisher.py +356 -0
- package/src/superlocalmemory/math/langevin.py +398 -0
- package/src/superlocalmemory/math/sheaf.py +257 -0
- package/src/superlocalmemory/mcp/__init__.py +0 -0
- package/src/superlocalmemory/mcp/resources.py +245 -0
- package/src/superlocalmemory/mcp/server.py +61 -0
- package/src/superlocalmemory/mcp/tools.py +18 -0
- package/src/superlocalmemory/mcp/tools_core.py +305 -0
- package/src/superlocalmemory/mcp/tools_v28.py +223 -0
- package/src/superlocalmemory/mcp/tools_v3.py +286 -0
- package/src/superlocalmemory/retrieval/__init__.py +0 -0
- package/src/superlocalmemory/retrieval/agentic.py +295 -0
- package/src/superlocalmemory/retrieval/ann_index.py +223 -0
- package/src/superlocalmemory/retrieval/bm25_channel.py +185 -0
- package/src/superlocalmemory/retrieval/bridge_discovery.py +170 -0
- package/src/superlocalmemory/retrieval/engine.py +390 -0
- package/src/superlocalmemory/retrieval/entity_channel.py +179 -0
- package/src/superlocalmemory/retrieval/fusion.py +78 -0
- package/src/superlocalmemory/retrieval/profile_channel.py +105 -0
- package/src/superlocalmemory/retrieval/reranker.py +154 -0
- package/src/superlocalmemory/retrieval/semantic_channel.py +232 -0
- package/src/superlocalmemory/retrieval/strategy.py +96 -0
- package/src/superlocalmemory/retrieval/temporal_channel.py +175 -0
- package/src/superlocalmemory/server/__init__.py +1 -0
- package/src/superlocalmemory/server/api.py +248 -0
- package/src/superlocalmemory/server/routes/__init__.py +4 -0
- package/src/superlocalmemory/server/routes/agents.py +107 -0
- package/src/superlocalmemory/server/routes/backup.py +91 -0
- package/src/superlocalmemory/server/routes/behavioral.py +127 -0
- package/src/superlocalmemory/server/routes/compliance.py +160 -0
- package/src/superlocalmemory/server/routes/data_io.py +188 -0
- package/src/superlocalmemory/server/routes/events.py +183 -0
- package/src/superlocalmemory/server/routes/helpers.py +85 -0
- package/src/superlocalmemory/server/routes/learning.py +273 -0
- package/src/superlocalmemory/server/routes/lifecycle.py +116 -0
- package/src/superlocalmemory/server/routes/memories.py +399 -0
- package/src/superlocalmemory/server/routes/profiles.py +219 -0
- package/src/superlocalmemory/server/routes/stats.py +346 -0
- package/src/superlocalmemory/server/routes/v3_api.py +365 -0
- package/src/superlocalmemory/server/routes/ws.py +82 -0
- package/src/superlocalmemory/server/security_middleware.py +57 -0
- package/src/superlocalmemory/server/ui.py +245 -0
- package/src/superlocalmemory/storage/__init__.py +0 -0
- package/src/superlocalmemory/storage/access_control.py +182 -0
- package/src/superlocalmemory/storage/database.py +594 -0
- package/src/superlocalmemory/storage/migrations.py +303 -0
- package/src/superlocalmemory/storage/models.py +406 -0
- package/src/superlocalmemory/storage/schema.py +726 -0
- package/src/superlocalmemory/storage/v2_migrator.py +317 -0
- package/src/superlocalmemory/trust/__init__.py +0 -0
- package/src/superlocalmemory/trust/gate.py +130 -0
- package/src/superlocalmemory/trust/provenance.py +124 -0
- package/src/superlocalmemory/trust/scorer.py +347 -0
- package/src/superlocalmemory/trust/signals.py +153 -0
- package/ui/index.html +278 -5
- package/ui/js/auto-settings.js +70 -0
- package/ui/js/dashboard.js +90 -0
- package/ui/js/fact-detail.js +92 -0
- package/ui/js/feedback.js +2 -2
- package/ui/js/ide-status.js +102 -0
- package/ui/js/math-health.js +98 -0
- package/ui/js/recall-lab.js +127 -0
- package/ui/js/settings.js +2 -2
- package/ui/js/trust-dashboard.js +73 -0
- package/api_server.py +0 -724
- package/bin/aider-smart +0 -72
- package/bin/superlocalmemoryv2-learning +0 -4
- package/bin/superlocalmemoryv2-list +0 -3
- package/bin/superlocalmemoryv2-patterns +0 -4
- package/bin/superlocalmemoryv2-profile +0 -3
- package/bin/superlocalmemoryv2-recall +0 -3
- package/bin/superlocalmemoryv2-remember +0 -3
- package/bin/superlocalmemoryv2-reset +0 -3
- package/bin/superlocalmemoryv2-status +0 -3
- package/configs/chatgpt-desktop-mcp.json +0 -16
- package/configs/cursor-mcp.json +0 -15
- package/hooks/memory-list-skill.js +0 -139
- package/hooks/memory-profile-skill.js +0 -273
- package/hooks/memory-recall-skill.js +0 -114
- package/hooks/memory-remember-skill.js +0 -127
- package/hooks/memory-reset-skill.js +0 -274
- package/mcp_server.py +0 -1808
- package/requirements-core.txt +0 -22
- package/requirements-learning.txt +0 -12
- package/requirements.txt +0 -12
- package/src/agent_registry.py +0 -411
- package/src/auth_middleware.py +0 -61
- package/src/auto_backup.py +0 -459
- package/src/behavioral/__init__.py +0 -49
- package/src/behavioral/behavioral_listener.py +0 -203
- package/src/behavioral/behavioral_patterns.py +0 -275
- package/src/behavioral/cross_project_transfer.py +0 -206
- package/src/behavioral/outcome_inference.py +0 -194
- package/src/behavioral/outcome_tracker.py +0 -193
- package/src/behavioral/tests/__init__.py +0 -4
- package/src/behavioral/tests/test_behavioral_integration.py +0 -108
- package/src/behavioral/tests/test_behavioral_patterns.py +0 -150
- package/src/behavioral/tests/test_cross_project_transfer.py +0 -142
- package/src/behavioral/tests/test_mcp_behavioral.py +0 -139
- package/src/behavioral/tests/test_mcp_report_outcome.py +0 -117
- package/src/behavioral/tests/test_outcome_inference.py +0 -107
- package/src/behavioral/tests/test_outcome_tracker.py +0 -96
- package/src/cache_manager.py +0 -518
- package/src/compliance/__init__.py +0 -48
- package/src/compliance/abac_engine.py +0 -149
- package/src/compliance/abac_middleware.py +0 -116
- package/src/compliance/audit_db.py +0 -215
- package/src/compliance/audit_logger.py +0 -148
- package/src/compliance/retention_manager.py +0 -289
- package/src/compliance/retention_scheduler.py +0 -186
- package/src/compliance/tests/__init__.py +0 -4
- package/src/compliance/tests/test_abac_enforcement.py +0 -95
- package/src/compliance/tests/test_abac_engine.py +0 -124
- package/src/compliance/tests/test_abac_mcp_integration.py +0 -118
- package/src/compliance/tests/test_audit_db.py +0 -123
- package/src/compliance/tests/test_audit_logger.py +0 -98
- package/src/compliance/tests/test_mcp_audit.py +0 -128
- package/src/compliance/tests/test_mcp_retention_policy.py +0 -125
- package/src/compliance/tests/test_retention_manager.py +0 -131
- package/src/compliance/tests/test_retention_scheduler.py +0 -99
- package/src/compression/__init__.py +0 -25
- package/src/compression/cli.py +0 -150
- package/src/compression/cold_storage.py +0 -217
- package/src/compression/config.py +0 -72
- package/src/compression/orchestrator.py +0 -133
- package/src/compression/tier2_compressor.py +0 -228
- package/src/compression/tier3_compressor.py +0 -153
- package/src/compression/tier_classifier.py +0 -148
- package/src/db_connection_manager.py +0 -536
- package/src/embedding_engine.py +0 -63
- package/src/embeddings/__init__.py +0 -47
- package/src/embeddings/cache.py +0 -70
- package/src/embeddings/cli.py +0 -113
- package/src/embeddings/constants.py +0 -47
- package/src/embeddings/database.py +0 -91
- package/src/embeddings/engine.py +0 -247
- package/src/embeddings/model_loader.py +0 -145
- package/src/event_bus.py +0 -562
- package/src/graph/__init__.py +0 -36
- package/src/graph/build_helpers.py +0 -74
- package/src/graph/cli.py +0 -87
- package/src/graph/cluster_builder.py +0 -188
- package/src/graph/cluster_summary.py +0 -148
- package/src/graph/constants.py +0 -47
- package/src/graph/edge_builder.py +0 -162
- package/src/graph/entity_extractor.py +0 -95
- package/src/graph/graph_core.py +0 -226
- package/src/graph/graph_search.py +0 -231
- package/src/graph/hierarchical.py +0 -207
- package/src/graph/schema.py +0 -99
- package/src/graph_engine.py +0 -52
- package/src/hnsw_index.py +0 -628
- package/src/hybrid_search.py +0 -46
- package/src/learning/__init__.py +0 -217
- package/src/learning/adaptive_ranker.py +0 -682
- package/src/learning/bootstrap/__init__.py +0 -69
- package/src/learning/bootstrap/constants.py +0 -93
- package/src/learning/bootstrap/db_queries.py +0 -316
- package/src/learning/bootstrap/sampling.py +0 -82
- package/src/learning/bootstrap/text_utils.py +0 -71
- package/src/learning/cross_project_aggregator.py +0 -857
- package/src/learning/db/__init__.py +0 -40
- package/src/learning/db/constants.py +0 -44
- package/src/learning/db/schema.py +0 -279
- package/src/learning/engagement_tracker.py +0 -628
- package/src/learning/feature_extractor.py +0 -708
- package/src/learning/feedback_collector.py +0 -806
- package/src/learning/learning_db.py +0 -915
- package/src/learning/project_context_manager.py +0 -572
- package/src/learning/ranking/__init__.py +0 -33
- package/src/learning/ranking/constants.py +0 -84
- package/src/learning/ranking/helpers.py +0 -278
- package/src/learning/source_quality_scorer.py +0 -676
- package/src/learning/synthetic_bootstrap.py +0 -755
- package/src/learning/tests/test_adaptive_ranker.py +0 -325
- package/src/learning/tests/test_adaptive_ranker_v28.py +0 -60
- package/src/learning/tests/test_aggregator.py +0 -306
- package/src/learning/tests/test_auto_retrain_v28.py +0 -35
- package/src/learning/tests/test_e2e_ranking_v28.py +0 -82
- package/src/learning/tests/test_feature_extractor_v28.py +0 -93
- package/src/learning/tests/test_feedback_collector.py +0 -294
- package/src/learning/tests/test_learning_db.py +0 -602
- package/src/learning/tests/test_learning_db_v28.py +0 -110
- package/src/learning/tests/test_learning_init_v28.py +0 -48
- package/src/learning/tests/test_outcome_signals.py +0 -48
- package/src/learning/tests/test_project_context.py +0 -292
- package/src/learning/tests/test_schema_migration.py +0 -319
- package/src/learning/tests/test_signal_inference.py +0 -397
- package/src/learning/tests/test_source_quality.py +0 -351
- package/src/learning/tests/test_synthetic_bootstrap.py +0 -429
- package/src/learning/tests/test_workflow_miner.py +0 -318
- package/src/learning/workflow_pattern_miner.py +0 -655
- package/src/lifecycle/__init__.py +0 -54
- package/src/lifecycle/bounded_growth.py +0 -239
- package/src/lifecycle/compaction_engine.py +0 -226
- package/src/lifecycle/lifecycle_engine.py +0 -355
- package/src/lifecycle/lifecycle_evaluator.py +0 -257
- package/src/lifecycle/lifecycle_scheduler.py +0 -130
- package/src/lifecycle/retention_policy.py +0 -285
- package/src/lifecycle/tests/test_bounded_growth.py +0 -193
- package/src/lifecycle/tests/test_compaction.py +0 -179
- package/src/lifecycle/tests/test_lifecycle_engine.py +0 -137
- package/src/lifecycle/tests/test_lifecycle_evaluation.py +0 -177
- package/src/lifecycle/tests/test_lifecycle_scheduler.py +0 -127
- package/src/lifecycle/tests/test_lifecycle_search.py +0 -109
- package/src/lifecycle/tests/test_mcp_compact.py +0 -149
- package/src/lifecycle/tests/test_mcp_lifecycle_status.py +0 -114
- package/src/lifecycle/tests/test_retention_policy.py +0 -162
- package/src/mcp_tools_v28.py +0 -281
- package/src/memory/__init__.py +0 -36
- package/src/memory/cli.py +0 -205
- package/src/memory/constants.py +0 -39
- package/src/memory/helpers.py +0 -28
- package/src/memory/schema.py +0 -166
- package/src/memory-profiles.py +0 -595
- package/src/memory-reset.py +0 -491
- package/src/memory_compression.py +0 -989
- package/src/memory_store_v2.py +0 -1155
- package/src/migrate_v1_to_v2.py +0 -629
- package/src/pattern_learner.py +0 -34
- package/src/patterns/__init__.py +0 -24
- package/src/patterns/analyzers.py +0 -251
- package/src/patterns/learner.py +0 -271
- package/src/patterns/scoring.py +0 -171
- package/src/patterns/store.py +0 -225
- package/src/patterns/terminology.py +0 -140
- package/src/provenance_tracker.py +0 -312
- package/src/qualixar_attribution.py +0 -139
- package/src/qualixar_watermark.py +0 -78
- package/src/query_optimizer.py +0 -511
- package/src/rate_limiter.py +0 -83
- package/src/search/__init__.py +0 -20
- package/src/search/cli.py +0 -77
- package/src/search/constants.py +0 -26
- package/src/search/engine.py +0 -241
- package/src/search/fusion.py +0 -122
- package/src/search/index_loader.py +0 -114
- package/src/search/methods.py +0 -162
- package/src/search_engine_v2.py +0 -401
- package/src/setup_validator.py +0 -482
- package/src/subscription_manager.py +0 -391
- package/src/tree/__init__.py +0 -59
- package/src/tree/builder.py +0 -185
- package/src/tree/nodes.py +0 -202
- package/src/tree/queries.py +0 -257
- package/src/tree/schema.py +0 -80
- package/src/tree_manager.py +0 -19
- package/src/trust/__init__.py +0 -45
- package/src/trust/constants.py +0 -66
- package/src/trust/queries.py +0 -157
- package/src/trust/schema.py +0 -95
- package/src/trust/scorer.py +0 -299
- package/src/trust/signals.py +0 -95
- package/src/trust_scorer.py +0 -44
- package/ui/app.js +0 -1588
- package/ui/js/graph-cytoscape-monolithic-backup.js +0 -1168
- package/ui/js/graph-cytoscape.js +0 -1168
- package/ui/js/graph-d3-backup.js +0 -32
- package/ui/js/graph.js +0 -32
- package/ui_server.py +0 -286
- /package/docs/{ACCESSIBILITY.md → v2-archive/ACCESSIBILITY.md} +0 -0
- /package/docs/{ARCHITECTURE.md → v2-archive/ARCHITECTURE.md} +0 -0
- /package/docs/{CLI-COMMANDS-REFERENCE.md → v2-archive/CLI-COMMANDS-REFERENCE.md} +0 -0
- /package/docs/{COMPRESSION-README.md → v2-archive/COMPRESSION-README.md} +0 -0
- /package/docs/{FRAMEWORK-INTEGRATIONS.md → v2-archive/FRAMEWORK-INTEGRATIONS.md} +0 -0
- /package/docs/{MCP-MANUAL-SETUP.md → v2-archive/MCP-MANUAL-SETUP.md} +0 -0
- /package/docs/{MCP-TROUBLESHOOTING.md → v2-archive/MCP-TROUBLESHOOTING.md} +0 -0
- /package/docs/{PATTERN-LEARNING.md → v2-archive/PATTERN-LEARNING.md} +0 -0
- /package/docs/{PROFILES-GUIDE.md → v2-archive/PROFILES-GUIDE.md} +0 -0
- /package/docs/{RESET-GUIDE.md → v2-archive/RESET-GUIDE.md} +0 -0
- /package/docs/{SEARCH-ENGINE-V2.2.0.md → v2-archive/SEARCH-ENGINE-V2.2.0.md} +0 -0
- /package/docs/{SEARCH-INTEGRATION-GUIDE.md → v2-archive/SEARCH-INTEGRATION-GUIDE.md} +0 -0
- /package/docs/{UI-SERVER.md → v2-archive/UI-SERVER.md} +0 -0
- /package/docs/{UNIVERSAL-INTEGRATION.md → v2-archive/UNIVERSAL-INTEGRATION.md} +0 -0
- /package/docs/{V2.2.0-OPTIONAL-SEARCH.md → v2-archive/V2.2.0-OPTIONAL-SEARCH.md} +0 -0
- /package/docs/{WINDOWS-INSTALL-README.txt → v2-archive/WINDOWS-INSTALL-README.txt} +0 -0
- /package/docs/{WINDOWS-POST-INSTALL.txt → v2-archive/WINDOWS-POST-INSTALL.txt} +0 -0
- /package/docs/{example_graph_usage.py → v2-archive/example_graph_usage.py} +0 -0
- /package/{completions → ide/completions}/slm.bash +0 -0
- /package/{completions → ide/completions}/slm.zsh +0 -0
- /package/{configs → ide/configs}/cody-commands.json +0 -0
- /package/{install-skills.sh → scripts/install-skills.sh} +0 -0
- /package/{install.ps1 → scripts/install.ps1} +0 -0
- /package/{install.sh → scripts/install.sh} +0 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
# Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
|
|
2
|
+
# Licensed under the MIT License - see LICENSE file
|
|
3
|
+
# Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
|
|
4
|
+
"""SuperLocalMemory V3 - Learning Routes
|
|
5
|
+
- MIT License
|
|
6
|
+
|
|
7
|
+
Routes: /api/learning/status, /api/feedback, /api/feedback/dwell,
|
|
8
|
+
/api/feedback/stats, /api/learning/backup, /api/learning/reset,
|
|
9
|
+
/api/learning/retrain
|
|
10
|
+
Uses V3 learning modules: FeedbackCollector, EngagementTracker, AdaptiveLearner.
|
|
11
|
+
"""
|
|
12
|
+
import shutil
|
|
13
|
+
import logging
|
|
14
|
+
from datetime import datetime
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
|
|
17
|
+
from fastapi import APIRouter
|
|
18
|
+
|
|
19
|
+
from .helpers import get_active_profile, MEMORY_DIR
|
|
20
|
+
|
|
21
|
+
logger = logging.getLogger("superlocalmemory.routes.learning")
|
|
22
|
+
router = APIRouter()
|
|
23
|
+
|
|
24
|
+
LEARNING_DB = MEMORY_DIR / "learning.db"
|
|
25
|
+
|
|
26
|
+
# Feature detection
|
|
27
|
+
LEARNING_AVAILABLE = False
|
|
28
|
+
try:
|
|
29
|
+
from superlocalmemory.learning.feedback import FeedbackCollector
|
|
30
|
+
from superlocalmemory.learning.engagement import EngagementTracker
|
|
31
|
+
from superlocalmemory.learning.ranker import AdaptiveRanker
|
|
32
|
+
LEARNING_AVAILABLE = True
|
|
33
|
+
except ImportError:
|
|
34
|
+
try:
|
|
35
|
+
from superlocalmemory.learning.adaptive import AdaptiveLearner
|
|
36
|
+
LEARNING_AVAILABLE = True
|
|
37
|
+
except ImportError:
|
|
38
|
+
logger.info("V3 learning system not available")
|
|
39
|
+
|
|
40
|
+
# Lazy singletons
|
|
41
|
+
_feedback: FeedbackCollector | None = None
|
|
42
|
+
_engagement: EngagementTracker | None = None
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _get_feedback() -> "FeedbackCollector | None":
|
|
46
|
+
global _feedback
|
|
47
|
+
if _feedback is None and LEARNING_AVAILABLE:
|
|
48
|
+
try:
|
|
49
|
+
_feedback = FeedbackCollector(str(LEARNING_DB))
|
|
50
|
+
except Exception:
|
|
51
|
+
pass
|
|
52
|
+
return _feedback
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _get_engagement() -> "EngagementTracker | None":
|
|
56
|
+
global _engagement
|
|
57
|
+
if _engagement is None and LEARNING_AVAILABLE:
|
|
58
|
+
try:
|
|
59
|
+
_engagement = EngagementTracker(str(LEARNING_DB))
|
|
60
|
+
except Exception:
|
|
61
|
+
pass
|
|
62
|
+
return _engagement
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@router.get("/api/learning/status")
|
|
66
|
+
async def learning_status():
|
|
67
|
+
"""Get comprehensive learning system status for dashboard."""
|
|
68
|
+
if not LEARNING_AVAILABLE:
|
|
69
|
+
return {
|
|
70
|
+
"available": False, "ranking_phase": None,
|
|
71
|
+
"stats": None, "tech_preferences": [], "workflow_patterns": [],
|
|
72
|
+
"source_scores": {}, "engagement": None,
|
|
73
|
+
"message": "Learning features not installed.",
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
result = {"available": True}
|
|
77
|
+
|
|
78
|
+
try:
|
|
79
|
+
active_profile = get_active_profile()
|
|
80
|
+
result["active_profile"] = active_profile
|
|
81
|
+
|
|
82
|
+
# Ranking phase
|
|
83
|
+
result["ranking_phase"] = "baseline"
|
|
84
|
+
|
|
85
|
+
# Feedback stats
|
|
86
|
+
feedback = _get_feedback()
|
|
87
|
+
if feedback:
|
|
88
|
+
try:
|
|
89
|
+
summary = feedback.get_feedback_summary()
|
|
90
|
+
result["stats"] = summary
|
|
91
|
+
result["profile_feedback"] = {
|
|
92
|
+
"profile": active_profile,
|
|
93
|
+
"signals": summary.get("total_signals", 0),
|
|
94
|
+
}
|
|
95
|
+
except Exception as exc:
|
|
96
|
+
logger.debug("feedback summary: %s", exc)
|
|
97
|
+
|
|
98
|
+
# Engagement
|
|
99
|
+
engagement = _get_engagement()
|
|
100
|
+
if engagement:
|
|
101
|
+
try:
|
|
102
|
+
result["engagement"] = engagement.get_engagement_stats()
|
|
103
|
+
except Exception:
|
|
104
|
+
result["engagement"] = None
|
|
105
|
+
else:
|
|
106
|
+
result["engagement"] = None
|
|
107
|
+
|
|
108
|
+
# Tech preferences (stub until learning DB populated)
|
|
109
|
+
result["tech_preferences"] = []
|
|
110
|
+
result["workflow_patterns"] = []
|
|
111
|
+
result["source_scores"] = {}
|
|
112
|
+
|
|
113
|
+
except Exception as e:
|
|
114
|
+
logger.error("Error getting learning status: %s", e)
|
|
115
|
+
result["error"] = str(e)
|
|
116
|
+
|
|
117
|
+
return result
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
# ============================================================================
|
|
121
|
+
# FEEDBACK ENDPOINTS
|
|
122
|
+
# ============================================================================
|
|
123
|
+
|
|
124
|
+
@router.post("/api/feedback")
|
|
125
|
+
async def record_feedback(data: dict):
|
|
126
|
+
"""Record explicit feedback from dashboard (thumbs up/down, pin)."""
|
|
127
|
+
if not LEARNING_AVAILABLE:
|
|
128
|
+
return {"success": False, "error": "Learning system not available"}
|
|
129
|
+
|
|
130
|
+
memory_id = data.get("memory_id")
|
|
131
|
+
query = data.get("query", "")
|
|
132
|
+
feedback_type = data.get("feedback_type")
|
|
133
|
+
|
|
134
|
+
if not memory_id or not feedback_type:
|
|
135
|
+
return {"success": False, "error": "memory_id and feedback_type required"}
|
|
136
|
+
|
|
137
|
+
valid_types = {"thumbs_up", "thumbs_down", "pin"}
|
|
138
|
+
if feedback_type not in valid_types:
|
|
139
|
+
return {"success": False, "error": f"Invalid feedback_type. Must be one of: {valid_types}"}
|
|
140
|
+
|
|
141
|
+
try:
|
|
142
|
+
feedback = _get_feedback()
|
|
143
|
+
if not feedback:
|
|
144
|
+
return {"success": False, "error": "Feedback collector not initialized"}
|
|
145
|
+
|
|
146
|
+
row_id = feedback.record_dashboard_feedback(
|
|
147
|
+
memory_id=str(memory_id), query=query, feedback_type=feedback_type,
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
return {
|
|
151
|
+
"success": True,
|
|
152
|
+
"message": f"Feedback recorded: {feedback_type} for memory #{memory_id}",
|
|
153
|
+
"feedback_id": row_id,
|
|
154
|
+
}
|
|
155
|
+
except Exception as e:
|
|
156
|
+
logger.error("Error recording feedback: %s", e)
|
|
157
|
+
return {"success": False, "error": str(e)}
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
@router.post("/api/feedback/dwell")
|
|
161
|
+
async def record_dwell(data: dict):
|
|
162
|
+
"""Record dwell time feedback from dashboard modal."""
|
|
163
|
+
if not LEARNING_AVAILABLE:
|
|
164
|
+
return {"success": False, "error": "Learning system not available"}
|
|
165
|
+
|
|
166
|
+
memory_id = data.get("memory_id")
|
|
167
|
+
query = data.get("query", "")
|
|
168
|
+
dwell_time = data.get("dwell_time", 0)
|
|
169
|
+
|
|
170
|
+
if not memory_id:
|
|
171
|
+
return {"success": False, "error": "memory_id required"}
|
|
172
|
+
|
|
173
|
+
try:
|
|
174
|
+
dwell_seconds = float(dwell_time)
|
|
175
|
+
except (ValueError, TypeError):
|
|
176
|
+
return {"success": False, "error": "dwell_time must be a number"}
|
|
177
|
+
|
|
178
|
+
if dwell_seconds >= 10.0:
|
|
179
|
+
feedback_type = "dwell_positive"
|
|
180
|
+
elif dwell_seconds < 2.0:
|
|
181
|
+
feedback_type = "dwell_negative"
|
|
182
|
+
else:
|
|
183
|
+
return {"success": True, "message": "Dwell time in neutral range, no signal recorded"}
|
|
184
|
+
|
|
185
|
+
try:
|
|
186
|
+
feedback = _get_feedback()
|
|
187
|
+
if not feedback:
|
|
188
|
+
return {"success": False, "error": "Feedback collector not initialized"}
|
|
189
|
+
|
|
190
|
+
row_id = feedback.record_dashboard_feedback(
|
|
191
|
+
memory_id=str(memory_id), query=query, feedback_type=feedback_type,
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
return {
|
|
195
|
+
"success": True,
|
|
196
|
+
"message": f"Dwell feedback recorded: {feedback_type} ({dwell_seconds:.1f}s)",
|
|
197
|
+
"feedback_id": row_id,
|
|
198
|
+
}
|
|
199
|
+
except Exception as e:
|
|
200
|
+
logger.error("Error recording dwell: %s", e)
|
|
201
|
+
return {"success": False, "error": str(e)}
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
@router.get("/api/feedback/stats")
|
|
205
|
+
async def feedback_stats():
|
|
206
|
+
"""Get feedback signal statistics for dashboard progress bar."""
|
|
207
|
+
if not LEARNING_AVAILABLE:
|
|
208
|
+
return {
|
|
209
|
+
"total_signals": 0, "ranking_phase": "baseline",
|
|
210
|
+
"progress": 0, "target": 200, "available": False,
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
try:
|
|
214
|
+
feedback = _get_feedback()
|
|
215
|
+
total = 0
|
|
216
|
+
by_channel = {}
|
|
217
|
+
by_type = {}
|
|
218
|
+
|
|
219
|
+
if feedback:
|
|
220
|
+
summary = feedback.get_feedback_summary()
|
|
221
|
+
total = summary.get("total_signals", 0)
|
|
222
|
+
by_channel = summary.get("by_channel", {})
|
|
223
|
+
by_type = summary.get("by_type", {})
|
|
224
|
+
|
|
225
|
+
target = 200
|
|
226
|
+
progress = min(total / target * 100, 100)
|
|
227
|
+
|
|
228
|
+
return {
|
|
229
|
+
"total_signals": total, "ranking_phase": "baseline",
|
|
230
|
+
"progress": round(progress, 1), "target": target,
|
|
231
|
+
"by_channel": by_channel, "by_type": by_type, "available": True,
|
|
232
|
+
}
|
|
233
|
+
except Exception as e:
|
|
234
|
+
logger.error("Error getting feedback stats: %s", e)
|
|
235
|
+
return {"total_signals": 0, "ranking_phase": "baseline", "progress": 0, "error": str(e)}
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
@router.post("/api/learning/backup")
|
|
239
|
+
async def learning_backup():
|
|
240
|
+
"""Backup learning.db to a timestamped file."""
|
|
241
|
+
try:
|
|
242
|
+
if not LEARNING_DB.exists():
|
|
243
|
+
return {"success": False, "error": "No learning.db found"}
|
|
244
|
+
|
|
245
|
+
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
246
|
+
backup_name = f"learning.db.backup_{timestamp}"
|
|
247
|
+
backup_path = MEMORY_DIR / backup_name
|
|
248
|
+
shutil.copy2(str(LEARNING_DB), str(backup_path))
|
|
249
|
+
|
|
250
|
+
return {
|
|
251
|
+
"success": True, "filename": backup_name,
|
|
252
|
+
"path": str(backup_path),
|
|
253
|
+
"message": f"Learning DB backed up to {backup_name}",
|
|
254
|
+
}
|
|
255
|
+
except Exception as e:
|
|
256
|
+
logger.error("Error backing up learning DB: %s", e)
|
|
257
|
+
return {"success": False, "error": str(e)}
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
@router.post("/api/learning/reset")
|
|
261
|
+
async def learning_reset():
|
|
262
|
+
"""Reset all learning data. Memories preserved."""
|
|
263
|
+
if not LEARNING_AVAILABLE:
|
|
264
|
+
return {"success": False, "error": "Learning system not available"}
|
|
265
|
+
return {"status": "not_implemented", "message": "Coming soon"}
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
@router.post("/api/learning/retrain")
|
|
269
|
+
async def learning_retrain():
|
|
270
|
+
"""Force retrain the ranking model."""
|
|
271
|
+
if not LEARNING_AVAILABLE:
|
|
272
|
+
return {"success": False, "error": "Learning system not available"}
|
|
273
|
+
return {"status": "not_implemented", "message": "Coming soon"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
|
|
2
|
+
# Licensed under the MIT License - see LICENSE file
|
|
3
|
+
# Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
|
|
4
|
+
"""SuperLocalMemory V3 - Lifecycle Routes
|
|
5
|
+
- MIT License
|
|
6
|
+
|
|
7
|
+
Routes: /api/lifecycle/status, /api/lifecycle/compact
|
|
8
|
+
Uses V3 compliance.lifecycle.LifecycleManager.
|
|
9
|
+
"""
|
|
10
|
+
import json
|
|
11
|
+
import logging
|
|
12
|
+
import sqlite3
|
|
13
|
+
|
|
14
|
+
from fastapi import APIRouter
|
|
15
|
+
|
|
16
|
+
from .helpers import get_active_profile, MEMORY_DIR, DB_PATH
|
|
17
|
+
|
|
18
|
+
logger = logging.getLogger("superlocalmemory.routes.lifecycle")
|
|
19
|
+
router = APIRouter()
|
|
20
|
+
|
|
21
|
+
# Feature detection
|
|
22
|
+
LIFECYCLE_AVAILABLE = False
|
|
23
|
+
try:
|
|
24
|
+
from superlocalmemory.compliance.lifecycle import LifecycleManager
|
|
25
|
+
LIFECYCLE_AVAILABLE = True
|
|
26
|
+
except ImportError:
|
|
27
|
+
logger.info("V3 lifecycle engine not available")
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@router.get("/api/lifecycle/status")
|
|
31
|
+
async def lifecycle_status():
|
|
32
|
+
"""Get lifecycle state distribution for active profile."""
|
|
33
|
+
if not LIFECYCLE_AVAILABLE:
|
|
34
|
+
return {"available": False, "message": "Lifecycle engine not available"}
|
|
35
|
+
|
|
36
|
+
try:
|
|
37
|
+
profile = get_active_profile()
|
|
38
|
+
conn = sqlite3.connect(str(DB_PATH))
|
|
39
|
+
conn.row_factory = sqlite3.Row
|
|
40
|
+
|
|
41
|
+
# Try V3 schema first (atomic_facts with lifecycle_state)
|
|
42
|
+
states = {}
|
|
43
|
+
try:
|
|
44
|
+
rows = conn.execute(
|
|
45
|
+
"SELECT lifecycle_state, COUNT(*) as cnt "
|
|
46
|
+
"FROM atomic_facts WHERE profile_id = ? GROUP BY lifecycle_state",
|
|
47
|
+
(profile,),
|
|
48
|
+
).fetchall()
|
|
49
|
+
states = {
|
|
50
|
+
(row['lifecycle_state'] or 'active'): row['cnt']
|
|
51
|
+
for row in rows
|
|
52
|
+
}
|
|
53
|
+
except sqlite3.OperationalError:
|
|
54
|
+
# V2 fallback: memories table
|
|
55
|
+
try:
|
|
56
|
+
rows = conn.execute(
|
|
57
|
+
"SELECT lifecycle_state, COUNT(*) as cnt "
|
|
58
|
+
"FROM memories WHERE profile = ? GROUP BY lifecycle_state",
|
|
59
|
+
(profile,),
|
|
60
|
+
).fetchall()
|
|
61
|
+
states = {
|
|
62
|
+
(row['lifecycle_state'] or 'active'): row['cnt']
|
|
63
|
+
for row in rows
|
|
64
|
+
}
|
|
65
|
+
except sqlite3.OperationalError:
|
|
66
|
+
# No lifecycle_state column at all
|
|
67
|
+
total = conn.execute(
|
|
68
|
+
"SELECT COUNT(*) FROM atomic_facts WHERE profile_id = ?",
|
|
69
|
+
(profile,),
|
|
70
|
+
).fetchone()[0]
|
|
71
|
+
states = {'active': total}
|
|
72
|
+
|
|
73
|
+
total = sum(states.values())
|
|
74
|
+
|
|
75
|
+
# Age distribution per state
|
|
76
|
+
age_stats = {}
|
|
77
|
+
for state in ('active', 'warm', 'cold', 'archived'):
|
|
78
|
+
try:
|
|
79
|
+
row = conn.execute(
|
|
80
|
+
"SELECT AVG(julianday('now') - julianday(created_at)) as avg_age, "
|
|
81
|
+
"MIN(julianday('now') - julianday(created_at)) as min_age, "
|
|
82
|
+
"MAX(julianday('now') - julianday(created_at)) as max_age "
|
|
83
|
+
"FROM atomic_facts WHERE profile_id = ? AND lifecycle_state = ?",
|
|
84
|
+
(profile, state),
|
|
85
|
+
).fetchone()
|
|
86
|
+
if row and row['avg_age'] is not None:
|
|
87
|
+
age_stats[state] = {
|
|
88
|
+
'avg_days': round(row['avg_age'], 1),
|
|
89
|
+
'min_days': round(row['min_age'], 1),
|
|
90
|
+
'max_days': round(row['max_age'], 1),
|
|
91
|
+
}
|
|
92
|
+
except sqlite3.OperationalError:
|
|
93
|
+
pass
|
|
94
|
+
|
|
95
|
+
conn.close()
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
"available": True,
|
|
99
|
+
"active_profile": profile,
|
|
100
|
+
"total_memories": total,
|
|
101
|
+
"states": states,
|
|
102
|
+
"recent_transitions": [],
|
|
103
|
+
"age_stats": age_stats,
|
|
104
|
+
}
|
|
105
|
+
except Exception as e:
|
|
106
|
+
logger.error("lifecycle_status error: %s", e)
|
|
107
|
+
return {"available": False, "error": str(e)}
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
@router.post("/api/lifecycle/compact")
|
|
111
|
+
async def trigger_compaction(data: dict = {}):
|
|
112
|
+
"""Trigger lifecycle compaction. Body: {dry_run: true/false}."""
|
|
113
|
+
if not LIFECYCLE_AVAILABLE:
|
|
114
|
+
return {"success": False, "error": "Lifecycle engine not available"}
|
|
115
|
+
|
|
116
|
+
return {"status": "not_implemented", "message": "Coming soon"}
|