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,303 @@
|
|
|
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
|
+
|
|
5
|
+
"""SuperLocalMemory V3 — Database Migrations.
|
|
6
|
+
|
|
7
|
+
Handles schema versioning and V1 (slm_alpha) → Innovation migration.
|
|
8
|
+
Preserves existing data while upgrading schema structure.
|
|
9
|
+
|
|
10
|
+
Part of Qualixar | Author: Varun Pratap Bhardwaj
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import json
|
|
16
|
+
import logging
|
|
17
|
+
import shutil
|
|
18
|
+
import sqlite3
|
|
19
|
+
from datetime import UTC, datetime
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
from typing import Any
|
|
22
|
+
|
|
23
|
+
logger = logging.getLogger(__name__)
|
|
24
|
+
|
|
25
|
+
CURRENT_SCHEMA_VERSION = 1 # Innovation v1
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def get_schema_version(conn: sqlite3.Connection) -> int:
|
|
29
|
+
"""Read current schema version. Returns 0 if no version table."""
|
|
30
|
+
try:
|
|
31
|
+
row = conn.execute(
|
|
32
|
+
"SELECT version FROM schema_version ORDER BY applied_at DESC LIMIT 1"
|
|
33
|
+
).fetchone()
|
|
34
|
+
return int(row[0]) if row else 0
|
|
35
|
+
except sqlite3.OperationalError:
|
|
36
|
+
return 0
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def set_schema_version(conn: sqlite3.Connection, version: int) -> None:
|
|
40
|
+
"""Record a schema version upgrade."""
|
|
41
|
+
conn.execute(
|
|
42
|
+
"INSERT INTO schema_version (version, applied_at, description) VALUES (?, ?, ?)",
|
|
43
|
+
(version, datetime.now(UTC).isoformat(), f"Migration to v{version}"),
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def needs_migration(db_path: Path) -> bool:
|
|
48
|
+
"""Check if database needs migration."""
|
|
49
|
+
if not db_path.exists():
|
|
50
|
+
return False
|
|
51
|
+
conn = sqlite3.connect(str(db_path))
|
|
52
|
+
try:
|
|
53
|
+
version = get_schema_version(conn)
|
|
54
|
+
return version < CURRENT_SCHEMA_VERSION
|
|
55
|
+
finally:
|
|
56
|
+
conn.close()
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def is_v1_database(db_path: Path) -> bool:
|
|
60
|
+
"""Detect if this is a V1 (slm_alpha) database by checking for V1-specific tables."""
|
|
61
|
+
if not db_path.exists():
|
|
62
|
+
return False
|
|
63
|
+
conn = sqlite3.connect(str(db_path))
|
|
64
|
+
try:
|
|
65
|
+
tables = {
|
|
66
|
+
row[0]
|
|
67
|
+
for row in conn.execute(
|
|
68
|
+
"SELECT name FROM sqlite_master WHERE type='table'"
|
|
69
|
+
).fetchall()
|
|
70
|
+
}
|
|
71
|
+
# V1 markers: episodic_memory table + no schema_version
|
|
72
|
+
return "episodic_memory" in tables and "schema_version" not in tables
|
|
73
|
+
finally:
|
|
74
|
+
conn.close()
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def backup_database(db_path: Path) -> Path:
|
|
78
|
+
"""Create timestamped backup before migration."""
|
|
79
|
+
timestamp = datetime.now(UTC).strftime("%Y%m%d_%H%M%S")
|
|
80
|
+
backup_path = db_path.with_suffix(f".backup_{timestamp}.db")
|
|
81
|
+
shutil.copy2(str(db_path), str(backup_path))
|
|
82
|
+
logger.info("Database backed up to %s", backup_path)
|
|
83
|
+
return backup_path
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def migrate_v1_to_innovation(
|
|
87
|
+
v1_db_path: Path,
|
|
88
|
+
innovation_db_path: Path,
|
|
89
|
+
profile_id: str = "default",
|
|
90
|
+
) -> dict[str, Any]:
|
|
91
|
+
"""Migrate V1 (slm_alpha) database to Innovation schema.
|
|
92
|
+
|
|
93
|
+
Preserves all memories and facts. Creates proper typed stores.
|
|
94
|
+
Returns migration statistics.
|
|
95
|
+
"""
|
|
96
|
+
from superlocalmemory.storage import schema
|
|
97
|
+
|
|
98
|
+
stats: dict[str, Any] = {
|
|
99
|
+
"memories_migrated": 0,
|
|
100
|
+
"facts_migrated": 0,
|
|
101
|
+
"entities_migrated": 0,
|
|
102
|
+
"edges_migrated": 0,
|
|
103
|
+
"errors": [],
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if not v1_db_path.exists():
|
|
107
|
+
stats["errors"].append(f"V1 database not found: {v1_db_path}")
|
|
108
|
+
return stats
|
|
109
|
+
|
|
110
|
+
# Backup V1 database
|
|
111
|
+
backup_database(v1_db_path)
|
|
112
|
+
|
|
113
|
+
# Create Innovation database with clean schema
|
|
114
|
+
new_conn = sqlite3.connect(str(innovation_db_path))
|
|
115
|
+
new_conn.row_factory = sqlite3.Row
|
|
116
|
+
try:
|
|
117
|
+
new_conn.execute("PRAGMA foreign_keys=ON")
|
|
118
|
+
schema.create_all_tables(new_conn)
|
|
119
|
+
|
|
120
|
+
# Ensure default profile exists
|
|
121
|
+
new_conn.execute(
|
|
122
|
+
"INSERT OR IGNORE INTO profiles (profile_id, name, description, mode, created_at) "
|
|
123
|
+
"VALUES (?, ?, ?, ?, ?)",
|
|
124
|
+
(profile_id, profile_id, "Migrated from V1", "a", datetime.now(UTC).isoformat()),
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
# Open V1 database
|
|
128
|
+
v1_conn = sqlite3.connect(str(v1_db_path))
|
|
129
|
+
v1_conn.row_factory = sqlite3.Row
|
|
130
|
+
try:
|
|
131
|
+
stats = _migrate_memories(v1_conn, new_conn, profile_id, stats)
|
|
132
|
+
stats = _migrate_facts(v1_conn, new_conn, profile_id, stats)
|
|
133
|
+
stats = _migrate_entities(v1_conn, new_conn, profile_id, stats)
|
|
134
|
+
stats = _migrate_edges(v1_conn, new_conn, profile_id, stats)
|
|
135
|
+
new_conn.commit()
|
|
136
|
+
finally:
|
|
137
|
+
v1_conn.close()
|
|
138
|
+
|
|
139
|
+
set_schema_version(new_conn, CURRENT_SCHEMA_VERSION)
|
|
140
|
+
new_conn.commit()
|
|
141
|
+
logger.info("Migration complete: %s", stats)
|
|
142
|
+
|
|
143
|
+
finally:
|
|
144
|
+
new_conn.close()
|
|
145
|
+
|
|
146
|
+
return stats
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def _migrate_memories(
|
|
150
|
+
v1: sqlite3.Connection,
|
|
151
|
+
new: sqlite3.Connection,
|
|
152
|
+
profile_id: str,
|
|
153
|
+
stats: dict[str, Any],
|
|
154
|
+
) -> dict[str, Any]:
|
|
155
|
+
"""Migrate episodic_memory → memories table."""
|
|
156
|
+
try:
|
|
157
|
+
rows = v1.execute("SELECT * FROM episodic_memory").fetchall()
|
|
158
|
+
except sqlite3.OperationalError:
|
|
159
|
+
stats["errors"].append("No episodic_memory table in V1")
|
|
160
|
+
return stats
|
|
161
|
+
|
|
162
|
+
for row in rows:
|
|
163
|
+
d = dict(row)
|
|
164
|
+
try:
|
|
165
|
+
new.execute(
|
|
166
|
+
"INSERT OR IGNORE INTO memories "
|
|
167
|
+
"(memory_id, profile_id, content, session_id, speaker, role, "
|
|
168
|
+
"session_date, created_at, metadata) "
|
|
169
|
+
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
|
170
|
+
(
|
|
171
|
+
d.get("memory_id", d.get("id", "")),
|
|
172
|
+
profile_id,
|
|
173
|
+
d.get("content", ""),
|
|
174
|
+
d.get("session_id", ""),
|
|
175
|
+
d.get("speaker", ""),
|
|
176
|
+
d.get("role", ""),
|
|
177
|
+
d.get("session_date"),
|
|
178
|
+
d.get("created_at", datetime.now(UTC).isoformat()),
|
|
179
|
+
json.dumps({"migrated_from": "v1"}),
|
|
180
|
+
),
|
|
181
|
+
)
|
|
182
|
+
stats["memories_migrated"] += 1
|
|
183
|
+
except sqlite3.Error as exc:
|
|
184
|
+
stats["errors"].append(f"Memory {d.get('id', '?')}: {exc}")
|
|
185
|
+
|
|
186
|
+
return stats
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def _migrate_facts(
|
|
190
|
+
v1: sqlite3.Connection,
|
|
191
|
+
new: sqlite3.Connection,
|
|
192
|
+
profile_id: str,
|
|
193
|
+
stats: dict[str, Any],
|
|
194
|
+
) -> dict[str, Any]:
|
|
195
|
+
"""Migrate semantic_facts → facts table."""
|
|
196
|
+
try:
|
|
197
|
+
rows = v1.execute("SELECT * FROM semantic_facts").fetchall()
|
|
198
|
+
except sqlite3.OperationalError:
|
|
199
|
+
return stats
|
|
200
|
+
|
|
201
|
+
for row in rows:
|
|
202
|
+
d = dict(row)
|
|
203
|
+
try:
|
|
204
|
+
new.execute(
|
|
205
|
+
"INSERT OR IGNORE INTO facts "
|
|
206
|
+
"(fact_id, memory_id, profile_id, content, fact_type, "
|
|
207
|
+
"entities, canonical_entities, confidence, importance, "
|
|
208
|
+
"evidence_count, access_count, created_at) "
|
|
209
|
+
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
|
210
|
+
(
|
|
211
|
+
d.get("fact_id", d.get("id", "")),
|
|
212
|
+
d.get("memory_id", ""),
|
|
213
|
+
profile_id,
|
|
214
|
+
d.get("content", d.get("fact", "")),
|
|
215
|
+
d.get("fact_type", "semantic"),
|
|
216
|
+
d.get("entities_json", "[]"),
|
|
217
|
+
d.get("canonical_entities_json", "[]"),
|
|
218
|
+
d.get("confidence", 1.0),
|
|
219
|
+
d.get("importance", 0.5),
|
|
220
|
+
d.get("evidence_count", 1),
|
|
221
|
+
d.get("access_count", 0),
|
|
222
|
+
d.get("created_at", datetime.now(UTC).isoformat()),
|
|
223
|
+
),
|
|
224
|
+
)
|
|
225
|
+
stats["facts_migrated"] += 1
|
|
226
|
+
except sqlite3.Error as exc:
|
|
227
|
+
stats["errors"].append(f"Fact {d.get('id', '?')}: {exc}")
|
|
228
|
+
|
|
229
|
+
return stats
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def _migrate_entities(
|
|
233
|
+
v1: sqlite3.Connection,
|
|
234
|
+
new: sqlite3.Connection,
|
|
235
|
+
profile_id: str,
|
|
236
|
+
stats: dict[str, Any],
|
|
237
|
+
) -> dict[str, Any]:
|
|
238
|
+
"""Migrate canonical_entities → entities table."""
|
|
239
|
+
try:
|
|
240
|
+
rows = v1.execute("SELECT * FROM canonical_entities").fetchall()
|
|
241
|
+
except sqlite3.OperationalError:
|
|
242
|
+
return stats
|
|
243
|
+
|
|
244
|
+
for row in rows:
|
|
245
|
+
d = dict(row)
|
|
246
|
+
try:
|
|
247
|
+
new.execute(
|
|
248
|
+
"INSERT OR IGNORE INTO entities "
|
|
249
|
+
"(entity_id, profile_id, canonical_name, entity_type, "
|
|
250
|
+
"first_seen, last_seen, fact_count) "
|
|
251
|
+
"VALUES (?, ?, ?, ?, ?, ?, ?)",
|
|
252
|
+
(
|
|
253
|
+
d.get("entity_id", d.get("id", "")),
|
|
254
|
+
profile_id,
|
|
255
|
+
d.get("canonical_name", d.get("name", "")),
|
|
256
|
+
d.get("entity_type", "unknown"),
|
|
257
|
+
d.get("first_seen", datetime.now(UTC).isoformat()),
|
|
258
|
+
d.get("last_seen", datetime.now(UTC).isoformat()),
|
|
259
|
+
d.get("fact_count", 0),
|
|
260
|
+
),
|
|
261
|
+
)
|
|
262
|
+
stats["entities_migrated"] += 1
|
|
263
|
+
except sqlite3.Error as exc:
|
|
264
|
+
stats["errors"].append(f"Entity {d.get('id', '?')}: {exc}")
|
|
265
|
+
|
|
266
|
+
return stats
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
def _migrate_edges(
|
|
270
|
+
v1: sqlite3.Connection,
|
|
271
|
+
new: sqlite3.Connection,
|
|
272
|
+
profile_id: str,
|
|
273
|
+
stats: dict[str, Any],
|
|
274
|
+
) -> dict[str, Any]:
|
|
275
|
+
"""Migrate memory_edges → graph_edges table."""
|
|
276
|
+
try:
|
|
277
|
+
rows = v1.execute("SELECT * FROM memory_edges").fetchall()
|
|
278
|
+
except sqlite3.OperationalError:
|
|
279
|
+
return stats
|
|
280
|
+
|
|
281
|
+
for row in rows:
|
|
282
|
+
d = dict(row)
|
|
283
|
+
try:
|
|
284
|
+
new.execute(
|
|
285
|
+
"INSERT OR IGNORE INTO graph_edges "
|
|
286
|
+
"(edge_id, profile_id, source_id, target_id, edge_type, "
|
|
287
|
+
"weight, created_at) "
|
|
288
|
+
"VALUES (?, ?, ?, ?, ?, ?, ?)",
|
|
289
|
+
(
|
|
290
|
+
d.get("edge_id", d.get("id", "")),
|
|
291
|
+
profile_id,
|
|
292
|
+
d.get("source_id", d.get("source", "")),
|
|
293
|
+
d.get("target_id", d.get("target", "")),
|
|
294
|
+
d.get("edge_type", d.get("relation_type", "entity")),
|
|
295
|
+
d.get("weight", 1.0),
|
|
296
|
+
d.get("created_at", datetime.now(UTC).isoformat()),
|
|
297
|
+
),
|
|
298
|
+
)
|
|
299
|
+
stats["edges_migrated"] += 1
|
|
300
|
+
except sqlite3.Error as exc:
|
|
301
|
+
stats["errors"].append(f"Edge {d.get('id', '?')}: {exc}")
|
|
302
|
+
|
|
303
|
+
return stats
|
|
@@ -0,0 +1,406 @@
|
|
|
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
|
+
|
|
5
|
+
"""SuperLocalMemory V3 — Data Models.
|
|
6
|
+
|
|
7
|
+
All dataclasses for the memory system. Profile-scoped by design.
|
|
8
|
+
Every model that persists to DB includes profile_id.
|
|
9
|
+
|
|
10
|
+
Part of Qualixar | Author: Varun Pratap Bhardwaj
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import uuid
|
|
16
|
+
from dataclasses import dataclass, field
|
|
17
|
+
from datetime import UTC, datetime
|
|
18
|
+
from enum import Enum
|
|
19
|
+
from typing import Any
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# ---------------------------------------------------------------------------
|
|
23
|
+
# Enums
|
|
24
|
+
# ---------------------------------------------------------------------------
|
|
25
|
+
|
|
26
|
+
class FactType(str, Enum):
|
|
27
|
+
"""Memory fact classification — ENGRAM-inspired typed stores."""
|
|
28
|
+
|
|
29
|
+
EPISODIC = "episodic" # Events: who did what when
|
|
30
|
+
SEMANTIC = "semantic" # World knowledge: X is Y
|
|
31
|
+
OPINION = "opinion" # Subjective with confidence
|
|
32
|
+
TEMPORAL = "temporal" # Time-bounded events with intervals
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class EdgeType(str, Enum):
|
|
36
|
+
"""Knowledge graph edge types."""
|
|
37
|
+
|
|
38
|
+
ENTITY = "entity" # Shared entity link
|
|
39
|
+
TEMPORAL = "temporal" # Chronological ordering
|
|
40
|
+
SEMANTIC = "semantic" # Embedding similarity
|
|
41
|
+
CAUSAL = "causal" # Cause-effect relationship
|
|
42
|
+
CONTRADICTION = "contradiction" # Conflicting facts
|
|
43
|
+
SUPERSEDES = "supersedes" # Newer fact replaces older
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class ConsolidationActionType(str, Enum):
|
|
47
|
+
"""Mem0-style consolidation actions."""
|
|
48
|
+
|
|
49
|
+
ADD = "add" # New information, store as new fact
|
|
50
|
+
UPDATE = "update" # Refines existing fact
|
|
51
|
+
SUPERSEDE = "supersede" # Contradicts existing fact
|
|
52
|
+
NOOP = "noop" # Duplicate, skip storage
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class MemoryLifecycle(str, Enum):
|
|
56
|
+
"""Memory lifecycle states — coupled with Langevin dynamics."""
|
|
57
|
+
|
|
58
|
+
ACTIVE = "active" # Frequently accessed, near origin
|
|
59
|
+
WARM = "warm" # Moderate access, mid-radius
|
|
60
|
+
COLD = "cold" # Rarely accessed, near boundary
|
|
61
|
+
ARCHIVED = "archived" # Beyond boundary, deep storage
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class SignalType(str, Enum):
|
|
65
|
+
"""V2-compatible signal inference types."""
|
|
66
|
+
|
|
67
|
+
FACTUAL = "factual"
|
|
68
|
+
EMOTIONAL = "emotional"
|
|
69
|
+
TEMPORAL = "temporal"
|
|
70
|
+
OPINION = "opinion"
|
|
71
|
+
REQUEST = "request"
|
|
72
|
+
SOCIAL = "social"
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class Mode(str, Enum):
|
|
76
|
+
"""Operating modes — EU AI Act alignment."""
|
|
77
|
+
|
|
78
|
+
A = "a" # Local Guardian: zero LLM, EU AI Act FULL
|
|
79
|
+
B = "b" # Smart Local: local Ollama LLM, EU AI Act FULL
|
|
80
|
+
C = "c" # Full Power: UNRESTRICTED, best models, 90%+ target
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
# ---------------------------------------------------------------------------
|
|
84
|
+
# Core Models
|
|
85
|
+
# ---------------------------------------------------------------------------
|
|
86
|
+
|
|
87
|
+
def _new_id() -> str:
|
|
88
|
+
return uuid.uuid4().hex[:16]
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def _now() -> str:
|
|
92
|
+
return datetime.now(UTC).isoformat()
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
@dataclass(frozen=True)
|
|
96
|
+
class Profile:
|
|
97
|
+
"""Memory profile — first-class isolation boundary.
|
|
98
|
+
|
|
99
|
+
Every table is scoped by profile_id. Instant switching.
|
|
100
|
+
Ported from V2.8 columnar profile isolation pattern.
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
profile_id: str
|
|
104
|
+
name: str
|
|
105
|
+
description: str = ""
|
|
106
|
+
personality: str = "" # Profile personality description
|
|
107
|
+
mode: Mode = Mode.A # Default operating mode for this profile
|
|
108
|
+
created_at: str = field(default_factory=_now)
|
|
109
|
+
last_used: str | None = None
|
|
110
|
+
config: dict[str, Any] = field(default_factory=dict)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
@dataclass
|
|
114
|
+
class MemoryRecord:
|
|
115
|
+
"""Primary memory entry — a conversation turn or message.
|
|
116
|
+
|
|
117
|
+
This is the RAW input. Facts are extracted FROM this during encoding.
|
|
118
|
+
"""
|
|
119
|
+
|
|
120
|
+
memory_id: str = field(default_factory=_new_id)
|
|
121
|
+
profile_id: str = "default"
|
|
122
|
+
content: str = ""
|
|
123
|
+
session_id: str = ""
|
|
124
|
+
speaker: str = "" # Who said this
|
|
125
|
+
role: str = "" # user / assistant / system
|
|
126
|
+
session_date: str | None = None # Parsed ISO-8601 date
|
|
127
|
+
created_at: str = field(default_factory=_now)
|
|
128
|
+
metadata: dict[str, Any] = field(default_factory=dict)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
@dataclass
|
|
132
|
+
class AtomicFact:
|
|
133
|
+
"""Structured fact extracted from memory — the PRIMARY retrieval unit.
|
|
134
|
+
|
|
135
|
+
This is what the encoding engine produces. This is what retrieval searches.
|
|
136
|
+
Typed stores (ENGRAM pattern): episodic / semantic / opinion / temporal.
|
|
137
|
+
"""
|
|
138
|
+
|
|
139
|
+
fact_id: str = field(default_factory=_new_id)
|
|
140
|
+
memory_id: str = "" # Source memory this was extracted from
|
|
141
|
+
profile_id: str = "default"
|
|
142
|
+
content: str = "" # Atomic fact statement
|
|
143
|
+
fact_type: FactType = FactType.SEMANTIC
|
|
144
|
+
|
|
145
|
+
# Entities
|
|
146
|
+
entities: list[str] = field(default_factory=list)
|
|
147
|
+
canonical_entities: list[str] = field(default_factory=list)
|
|
148
|
+
|
|
149
|
+
# Temporal (3-date model — Mastra pattern)
|
|
150
|
+
observation_date: str | None = None # When the conversation happened
|
|
151
|
+
referenced_date: str | None = None # Date mentioned in content
|
|
152
|
+
interval_start: str | None = None # Event start (for duration events)
|
|
153
|
+
interval_end: str | None = None # Event end
|
|
154
|
+
|
|
155
|
+
# Quality
|
|
156
|
+
confidence: float = 1.0
|
|
157
|
+
importance: float = 0.5 # Priority: 0.0 (low) to 1.0 (critical)
|
|
158
|
+
evidence_count: int = 1 # Incremented on UPDATE consolidation
|
|
159
|
+
access_count: int = 0
|
|
160
|
+
|
|
161
|
+
# Source tracing
|
|
162
|
+
source_turn_ids: list[str] = field(default_factory=list)
|
|
163
|
+
session_id: str = ""
|
|
164
|
+
|
|
165
|
+
# Embeddings (populated by encoding pipeline)
|
|
166
|
+
embedding: list[float] | None = None
|
|
167
|
+
fisher_mean: list[float] | None = None
|
|
168
|
+
fisher_variance: list[float] | None = None
|
|
169
|
+
|
|
170
|
+
# Lifecycle (Langevin-coupled)
|
|
171
|
+
lifecycle: MemoryLifecycle = MemoryLifecycle.ACTIVE
|
|
172
|
+
langevin_position: list[float] | None = None
|
|
173
|
+
|
|
174
|
+
# Emotional (VADER)
|
|
175
|
+
emotional_valence: float = 0.0 # -1.0 negative to +1.0 positive
|
|
176
|
+
emotional_arousal: float = 0.0 # 0.0 calm to 1.0 intense
|
|
177
|
+
|
|
178
|
+
# Signal type (V2 compatible)
|
|
179
|
+
signal_type: SignalType = SignalType.FACTUAL
|
|
180
|
+
|
|
181
|
+
created_at: str = field(default_factory=_now)
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
@dataclass
|
|
185
|
+
class CanonicalEntity:
|
|
186
|
+
"""Resolved canonical entity — the single identity for an entity.
|
|
187
|
+
|
|
188
|
+
Aliases point here. Entity profiles accumulate knowledge about this entity.
|
|
189
|
+
"""
|
|
190
|
+
|
|
191
|
+
entity_id: str = field(default_factory=_new_id)
|
|
192
|
+
profile_id: str = "default"
|
|
193
|
+
canonical_name: str = ""
|
|
194
|
+
entity_type: str = "" # person / place / org / concept / event
|
|
195
|
+
first_seen: str = field(default_factory=_now)
|
|
196
|
+
last_seen: str = field(default_factory=_now)
|
|
197
|
+
fact_count: int = 0
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
@dataclass
|
|
201
|
+
class EntityAlias:
|
|
202
|
+
"""Alias mapping to a canonical entity."""
|
|
203
|
+
|
|
204
|
+
alias_id: str = field(default_factory=_new_id)
|
|
205
|
+
entity_id: str = "" # FK to CanonicalEntity
|
|
206
|
+
alias: str = ""
|
|
207
|
+
confidence: float = 1.0
|
|
208
|
+
source: str = "" # How this alias was discovered
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
@dataclass
|
|
212
|
+
class EntityProfile:
|
|
213
|
+
"""Accumulated knowledge about a canonical entity.
|
|
214
|
+
|
|
215
|
+
Built during encoding by ObservationBuilder. Updated on each new fact.
|
|
216
|
+
"""
|
|
217
|
+
|
|
218
|
+
profile_entry_id: str = field(default_factory=_new_id)
|
|
219
|
+
entity_id: str = "" # FK to CanonicalEntity
|
|
220
|
+
profile_id: str = "default"
|
|
221
|
+
knowledge_summary: str = "" # Running summary of all facts about entity
|
|
222
|
+
fact_ids: list[str] = field(default_factory=list)
|
|
223
|
+
last_updated: str = field(default_factory=_now)
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
@dataclass
|
|
227
|
+
class MemoryScene:
|
|
228
|
+
"""Clustered group of related facts — EverMemOS MemScene pattern.
|
|
229
|
+
|
|
230
|
+
Scenes provide contextual retrieval: related facts come together.
|
|
231
|
+
"""
|
|
232
|
+
|
|
233
|
+
scene_id: str = field(default_factory=_new_id)
|
|
234
|
+
profile_id: str = "default"
|
|
235
|
+
theme: str = "" # Scene description / topic
|
|
236
|
+
fact_ids: list[str] = field(default_factory=list)
|
|
237
|
+
entity_ids: list[str] = field(default_factory=list)
|
|
238
|
+
created_at: str = field(default_factory=_now)
|
|
239
|
+
last_updated: str = field(default_factory=_now)
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
@dataclass
|
|
243
|
+
class TemporalEvent:
|
|
244
|
+
"""Per-entity timeline entry with 3-date model.
|
|
245
|
+
|
|
246
|
+
Enables temporal retrieval: "What happened to Alice in March?"
|
|
247
|
+
"""
|
|
248
|
+
|
|
249
|
+
event_id: str = field(default_factory=_new_id)
|
|
250
|
+
profile_id: str = "default"
|
|
251
|
+
entity_id: str = "" # FK to CanonicalEntity
|
|
252
|
+
fact_id: str = "" # FK to AtomicFact
|
|
253
|
+
observation_date: str | None = None
|
|
254
|
+
referenced_date: str | None = None
|
|
255
|
+
interval_start: str | None = None
|
|
256
|
+
interval_end: str | None = None
|
|
257
|
+
description: str = ""
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
@dataclass
|
|
261
|
+
class GraphEdge:
|
|
262
|
+
"""Knowledge graph edge between facts or entities."""
|
|
263
|
+
|
|
264
|
+
edge_id: str = field(default_factory=_new_id)
|
|
265
|
+
profile_id: str = "default"
|
|
266
|
+
source_id: str = "" # Fact ID or Entity ID
|
|
267
|
+
target_id: str = "" # Fact ID or Entity ID
|
|
268
|
+
edge_type: EdgeType = EdgeType.ENTITY
|
|
269
|
+
weight: float = 1.0
|
|
270
|
+
created_at: str = field(default_factory=_now)
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
@dataclass
|
|
274
|
+
class ConsolidationAction:
|
|
275
|
+
"""Log of consolidation decisions (ADD/UPDATE/SUPERSEDE/NOOP)."""
|
|
276
|
+
|
|
277
|
+
action_id: str = field(default_factory=_new_id)
|
|
278
|
+
profile_id: str = "default"
|
|
279
|
+
action_type: ConsolidationActionType = ConsolidationActionType.ADD
|
|
280
|
+
new_fact_id: str = "" # The incoming fact
|
|
281
|
+
existing_fact_id: str = "" # The matched existing fact (if any)
|
|
282
|
+
reason: str = "" # Why this action was chosen
|
|
283
|
+
timestamp: str = field(default_factory=_now)
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
# ---------------------------------------------------------------------------
|
|
287
|
+
# Trust & Provenance (Ported from V2.8)
|
|
288
|
+
# ---------------------------------------------------------------------------
|
|
289
|
+
|
|
290
|
+
@dataclass
|
|
291
|
+
class TrustScore:
|
|
292
|
+
"""Bayesian trust score per source / entity / fact.
|
|
293
|
+
|
|
294
|
+
Updated on access, contradiction, confirmation. Profile-scoped.
|
|
295
|
+
"""
|
|
296
|
+
|
|
297
|
+
trust_id: str = field(default_factory=_new_id)
|
|
298
|
+
profile_id: str = "default"
|
|
299
|
+
target_type: str = "" # "entity" / "source" / "fact"
|
|
300
|
+
target_id: str = "" # ID of the entity/source/fact
|
|
301
|
+
trust_score: float = 0.5 # Bayesian: 0.0 = untrusted, 1.0 = fully trusted
|
|
302
|
+
evidence_count: int = 0
|
|
303
|
+
last_updated: str = field(default_factory=_now)
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
@dataclass
|
|
307
|
+
class ProvenanceRecord:
|
|
308
|
+
"""Provenance tracking — who/what created this memory and how."""
|
|
309
|
+
|
|
310
|
+
provenance_id: str = field(default_factory=_new_id)
|
|
311
|
+
profile_id: str = "default"
|
|
312
|
+
fact_id: str = ""
|
|
313
|
+
source_type: str = "" # "conversation" / "import" / "consolidation"
|
|
314
|
+
source_id: str = "" # Session ID or import batch ID
|
|
315
|
+
created_by: str = "" # Agent or user who created this
|
|
316
|
+
timestamp: str = field(default_factory=_now)
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
# ---------------------------------------------------------------------------
|
|
320
|
+
# Learning & Behavioral (Ported from V2.8)
|
|
321
|
+
# ---------------------------------------------------------------------------
|
|
322
|
+
|
|
323
|
+
@dataclass
|
|
324
|
+
class FeedbackRecord:
|
|
325
|
+
"""User feedback on retrieval results — drives adaptive learning."""
|
|
326
|
+
|
|
327
|
+
feedback_id: str = field(default_factory=_new_id)
|
|
328
|
+
profile_id: str = "default"
|
|
329
|
+
query: str = ""
|
|
330
|
+
fact_id: str = ""
|
|
331
|
+
feedback_type: str = "" # "relevant" / "irrelevant" / "partial"
|
|
332
|
+
dwell_time_ms: int = 0
|
|
333
|
+
timestamp: str = field(default_factory=_now)
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
@dataclass
|
|
337
|
+
class BehavioralPattern:
|
|
338
|
+
"""Learned behavioral pattern — query habits, topic preferences."""
|
|
339
|
+
|
|
340
|
+
pattern_id: str = field(default_factory=_new_id)
|
|
341
|
+
profile_id: str = "default"
|
|
342
|
+
pattern_type: str = "" # "query_topic" / "time_of_day" / "entity_pref"
|
|
343
|
+
pattern_key: str = "" # The pattern identifier
|
|
344
|
+
pattern_value: str = "" # Serialized pattern data
|
|
345
|
+
confidence: float = 0.0
|
|
346
|
+
observation_count: int = 0
|
|
347
|
+
last_updated: str = field(default_factory=_now)
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
@dataclass
|
|
351
|
+
class ActionOutcome:
|
|
352
|
+
"""Outcome tracking for learning — did the retrieved facts help?"""
|
|
353
|
+
|
|
354
|
+
outcome_id: str = field(default_factory=_new_id)
|
|
355
|
+
profile_id: str = "default"
|
|
356
|
+
query: str = ""
|
|
357
|
+
fact_ids: list[str] = field(default_factory=list)
|
|
358
|
+
outcome: str = "" # "success" / "partial" / "failure"
|
|
359
|
+
context: dict[str, Any] = field(default_factory=dict)
|
|
360
|
+
timestamp: str = field(default_factory=_now)
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
# ---------------------------------------------------------------------------
|
|
364
|
+
# Compliance (EU AI Act, GDPR, Lifecycle)
|
|
365
|
+
# ---------------------------------------------------------------------------
|
|
366
|
+
|
|
367
|
+
@dataclass
|
|
368
|
+
class ComplianceAuditEntry:
|
|
369
|
+
"""Audit trail for compliance (GDPR right-to-know, EU AI Act)."""
|
|
370
|
+
|
|
371
|
+
audit_id: str = field(default_factory=_new_id)
|
|
372
|
+
profile_id: str = "default"
|
|
373
|
+
action: str = "" # "store" / "retrieve" / "delete" / "export"
|
|
374
|
+
target_type: str = "" # "fact" / "memory" / "profile"
|
|
375
|
+
target_id: str = ""
|
|
376
|
+
details: str = ""
|
|
377
|
+
timestamp: str = field(default_factory=_now)
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
# ---------------------------------------------------------------------------
|
|
381
|
+
# Retrieval Result (Not persisted — runtime only)
|
|
382
|
+
# ---------------------------------------------------------------------------
|
|
383
|
+
|
|
384
|
+
@dataclass
|
|
385
|
+
class RetrievalResult:
|
|
386
|
+
"""A single retrieval result with scores and evidence chain."""
|
|
387
|
+
|
|
388
|
+
fact: AtomicFact
|
|
389
|
+
score: float = 0.0
|
|
390
|
+
channel_scores: dict[str, float] = field(default_factory=dict)
|
|
391
|
+
confidence: float = 0.0
|
|
392
|
+
evidence_chain: list[str] = field(default_factory=list)
|
|
393
|
+
trust_score: float = 0.5
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
@dataclass
|
|
397
|
+
class RecallResponse:
|
|
398
|
+
"""Complete recall response with ranked results and metadata."""
|
|
399
|
+
|
|
400
|
+
query: str = ""
|
|
401
|
+
mode: Mode = Mode.A
|
|
402
|
+
results: list[RetrievalResult] = field(default_factory=list)
|
|
403
|
+
query_type: str = "" # factual / temporal / opinion / multi-hop
|
|
404
|
+
channel_weights: dict[str, float] = field(default_factory=dict)
|
|
405
|
+
total_candidates: int = 0
|
|
406
|
+
retrieval_time_ms: float = 0.0
|