superlocalmemory 4.1.13 → 4.1.15
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/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +103 -0
- package/README.md +3 -3
- package/package.json +1 -8
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/CLAUDE.md +3 -3
- package/plugin/agents/slm-governance-advisor.md +1 -1
- package/plugin/agents/slm-loop-runner.md +1 -1
- package/plugin/agents/slm-memory-advisor.md +1 -1
- package/plugin/agents/slm-optimize-advisor.md +1 -1
- package/plugin/requirements.txt +1 -1
- package/plugin/skills/slm-cache/SKILL.md +1 -1
- package/plugin/skills/slm-compress/SKILL.md +1 -1
- package/plugin/skills/slm-governance/SKILL.md +1 -1
- package/plugin/skills/slm-graph/SKILL.md +1 -1
- package/plugin/skills/slm-loop/SKILL.md +1 -1
- package/plugin/skills/slm-mesh/SKILL.md +1 -1
- package/plugin/skills/slm-profile/SKILL.md +1 -1
- package/plugin/skills/slm-recall/SKILL.md +1 -1
- package/plugin/skills/slm-remember/SKILL.md +1 -1
- package/plugin/skills/slm-scope/SKILL.md +1 -1
- package/plugin/skills/slm-session/SKILL.md +1 -1
- package/plugin/skills/slm-status/SKILL.md +1 -1
- package/plugin-src/agents/slm-memory-advisor.md +1 -1
- package/plugin-src/agents/slm-optimize-advisor.md +1 -1
- package/plugin-src/rules/AGENTS.md +1 -1
- package/plugin-src/skills/slm-cache/SKILL.md +1 -1
- package/plugin-src/skills/slm-compress/SKILL.md +1 -1
- package/plugin-src/skills/slm-governance/SKILL.md +1 -1
- package/plugin-src/skills/slm-graph/SKILL.md +1 -1
- package/plugin-src/skills/slm-loop/SKILL.md +1 -1
- package/plugin-src/skills/slm-mesh/SKILL.md +1 -1
- package/plugin-src/skills/slm-profile/SKILL.md +1 -1
- package/plugin-src/skills/slm-recall/SKILL.md +1 -1
- package/plugin-src/skills/slm-remember/SKILL.md +1 -1
- package/plugin-src/skills/slm-scope/SKILL.md +1 -1
- package/plugin-src/skills/slm-session/SKILL.md +1 -1
- package/plugin-src/skills/slm-status/SKILL.md +1 -1
- package/scripts/postinstall.js +71 -2
- package/pyproject.toml +0 -250
- package/src/superlocalmemory/__init__.py +0 -82
- package/src/superlocalmemory/access/__init__.py +0 -3
- package/src/superlocalmemory/access/rbac.py +0 -575
- package/src/superlocalmemory/attribution/__init__.py +0 -9
- package/src/superlocalmemory/attribution/signer.py +0 -173
- package/src/superlocalmemory/attribution/watermark.py +0 -189
- package/src/superlocalmemory/brain/__init__.py +0 -5
- package/src/superlocalmemory/brain/truth.py +0 -418
- package/src/superlocalmemory/cli/__init__.py +0 -5
- package/src/superlocalmemory/cli/__main__.py +0 -17
- package/src/superlocalmemory/cli/_lazy_init.py +0 -115
- package/src/superlocalmemory/cli/cache_cmd.py +0 -198
- package/src/superlocalmemory/cli/commands.py +0 -4710
- package/src/superlocalmemory/cli/compress_cmd.py +0 -151
- package/src/superlocalmemory/cli/context_commands.py +0 -193
- package/src/superlocalmemory/cli/daemon.py +0 -909
- package/src/superlocalmemory/cli/db_migrate.py +0 -150
- package/src/superlocalmemory/cli/diagnostics_cmd.py +0 -101
- package/src/superlocalmemory/cli/escape_hatch.py +0 -220
- package/src/superlocalmemory/cli/evidence_cmd.py +0 -103
- package/src/superlocalmemory/cli/gdpr_cmd.py +0 -792
- package/src/superlocalmemory/cli/gdpr_io.py +0 -109
- package/src/superlocalmemory/cli/help_cmd.py +0 -197
- package/src/superlocalmemory/cli/host_upgrades.py +0 -189
- package/src/superlocalmemory/cli/ingest_cmd.py +0 -327
- package/src/superlocalmemory/cli/json_output.py +0 -81
- package/src/superlocalmemory/cli/loop_cmd.py +0 -187
- package/src/superlocalmemory/cli/main.py +0 -1145
- package/src/superlocalmemory/cli/mesh_cmd.py +0 -38
- package/src/superlocalmemory/cli/migrate_cmd.py +0 -55
- package/src/superlocalmemory/cli/ops_cmd.py +0 -281
- package/src/superlocalmemory/cli/optimize_cmd.py +0 -179
- package/src/superlocalmemory/cli/optimize_constants.py +0 -31
- package/src/superlocalmemory/cli/pending_store.py +0 -296
- package/src/superlocalmemory/cli/proxy_cmd.py +0 -108
- package/src/superlocalmemory/cli/scale_engine_cmd.py +0 -56
- package/src/superlocalmemory/cli/service_installer.py +0 -373
- package/src/superlocalmemory/cli/setup_wizard.py +0 -1162
- package/src/superlocalmemory/cli/summary_cmd.py +0 -215
- package/src/superlocalmemory/cli/version_banner.py +0 -202
- package/src/superlocalmemory/cli/wizard_v3426_options.py +0 -129
- package/src/superlocalmemory/code_graph/__init__.py +0 -46
- package/src/superlocalmemory/code_graph/blast_radius.py +0 -177
- package/src/superlocalmemory/code_graph/bridge/__init__.py +0 -36
- package/src/superlocalmemory/code_graph/bridge/entity_resolver.py +0 -490
- package/src/superlocalmemory/code_graph/bridge/event_listeners.py +0 -206
- package/src/superlocalmemory/code_graph/bridge/fact_enricher.py +0 -159
- package/src/superlocalmemory/code_graph/bridge/hebbian_linker.py +0 -170
- package/src/superlocalmemory/code_graph/bridge/maintenance.py +0 -220
- package/src/superlocalmemory/code_graph/bridge/temporal_checker.py +0 -152
- package/src/superlocalmemory/code_graph/changes.py +0 -363
- package/src/superlocalmemory/code_graph/communities.py +0 -299
- package/src/superlocalmemory/code_graph/config.py +0 -154
- package/src/superlocalmemory/code_graph/database.py +0 -526
- package/src/superlocalmemory/code_graph/extractors/__init__.py +0 -95
- package/src/superlocalmemory/code_graph/extractors/python.py +0 -413
- package/src/superlocalmemory/code_graph/extractors/typescript.py +0 -556
- package/src/superlocalmemory/code_graph/flows.py +0 -350
- package/src/superlocalmemory/code_graph/git_hooks.py +0 -226
- package/src/superlocalmemory/code_graph/graph_engine.py +0 -295
- package/src/superlocalmemory/code_graph/graph_store.py +0 -335
- package/src/superlocalmemory/code_graph/incremental.py +0 -200
- package/src/superlocalmemory/code_graph/models.py +0 -130
- package/src/superlocalmemory/code_graph/parser.py +0 -687
- package/src/superlocalmemory/code_graph/resolver.py +0 -321
- package/src/superlocalmemory/code_graph/search.py +0 -460
- package/src/superlocalmemory/code_graph/service.py +0 -95
- package/src/superlocalmemory/code_graph/watcher.py +0 -207
- package/src/superlocalmemory/compliance/__init__.py +0 -0
- package/src/superlocalmemory/compliance/abac.py +0 -204
- package/src/superlocalmemory/compliance/audit.py +0 -385
- package/src/superlocalmemory/compliance/eu_ai_act.py +0 -101
- package/src/superlocalmemory/compliance/gdpr.py +0 -1479
- package/src/superlocalmemory/compliance/lifecycle.py +0 -158
- package/src/superlocalmemory/compliance/retention.py +0 -415
- package/src/superlocalmemory/compliance/scheduler.py +0 -217
- package/src/superlocalmemory/contracts/__init__.py +0 -1
- package/src/superlocalmemory/contracts/schemas/agent-experience-v1.schema.json +0 -92
- package/src/superlocalmemory/contracts/schemas/agent-integration-contract-v2.schema.json +0 -46
- package/src/superlocalmemory/contracts/schemas/cognitive-turn-receipt-v1.schema.json +0 -59
- package/src/superlocalmemory/contracts/v402.py +0 -62
- package/src/superlocalmemory/core/__init__.py +0 -0
- package/src/superlocalmemory/core/actor_context.py +0 -166
- package/src/superlocalmemory/core/admission.py +0 -769
- package/src/superlocalmemory/core/backend_orchestrator.py +0 -637
- package/src/superlocalmemory/core/block_hygiene.py +0 -147
- package/src/superlocalmemory/core/community_summary.py +0 -267
- package/src/superlocalmemory/core/component_healer.py +0 -144
- package/src/superlocalmemory/core/component_registry.py +0 -514
- package/src/superlocalmemory/core/config.py +0 -2204
- package/src/superlocalmemory/core/consolidation_engine.py +0 -983
- package/src/superlocalmemory/core/context_cache.py +0 -574
- package/src/superlocalmemory/core/derivation_lineage.py +0 -246
- package/src/superlocalmemory/core/embedding_worker.py +0 -208
- package/src/superlocalmemory/core/embeddings.py +0 -1052
- package/src/superlocalmemory/core/engine.py +0 -1395
- package/src/superlocalmemory/core/engine_capabilities.py +0 -24
- package/src/superlocalmemory/core/engine_ingestion.py +0 -983
- package/src/superlocalmemory/core/engine_lock.py +0 -75
- package/src/superlocalmemory/core/engine_wiring.py +0 -776
- package/src/superlocalmemory/core/entity_community.py +0 -178
- package/src/superlocalmemory/core/error_envelope.py +0 -60
- package/src/superlocalmemory/core/evidence_bundle.py +0 -528
- package/src/superlocalmemory/core/fact_consolidator.py +0 -812
- package/src/superlocalmemory/core/file_lock.py +0 -92
- package/src/superlocalmemory/core/graph_analyzer.py +0 -456
- package/src/superlocalmemory/core/graph_metrics.py +0 -597
- package/src/superlocalmemory/core/graph_pruner.py +0 -939
- package/src/superlocalmemory/core/health_monitor.py +0 -338
- package/src/superlocalmemory/core/hooks.py +0 -65
- package/src/superlocalmemory/core/ingest_gate.py +0 -133
- package/src/superlocalmemory/core/ingest_policy.py +0 -38
- package/src/superlocalmemory/core/ingestion_command.py +0 -1042
- package/src/superlocalmemory/core/injection.py +0 -434
- package/src/superlocalmemory/core/install_detector.py +0 -131
- package/src/superlocalmemory/core/key_expander.py +0 -138
- package/src/superlocalmemory/core/lifecycle_state.py +0 -153
- package/src/superlocalmemory/core/maintenance.py +0 -777
- package/src/superlocalmemory/core/maintenance_scheduler.py +0 -507
- package/src/superlocalmemory/core/materialization_control.py +0 -20
- package/src/superlocalmemory/core/mcp_embedder_proxy.py +0 -89
- package/src/superlocalmemory/core/memory_health.py +0 -266
- package/src/superlocalmemory/core/mode_capability.py +0 -111
- package/src/superlocalmemory/core/modes.py +0 -168
- package/src/superlocalmemory/core/mutations.py +0 -688
- package/src/superlocalmemory/core/ollama_embedder.py +0 -266
- package/src/superlocalmemory/core/ollama_validator.py +0 -315
- package/src/superlocalmemory/core/operation_policy.py +0 -92
- package/src/superlocalmemory/core/operation_policy_registry.py +0 -542
- package/src/superlocalmemory/core/operation_request.py +0 -127
- package/src/superlocalmemory/core/ops_remediation.py +0 -542
- package/src/superlocalmemory/core/pii.py +0 -105
- package/src/superlocalmemory/core/platform_utils.py +0 -138
- package/src/superlocalmemory/core/profiles.py +0 -234
- package/src/superlocalmemory/core/progressive_abstraction.py +0 -208
- package/src/superlocalmemory/core/projection_drain.py +0 -380
- package/src/superlocalmemory/core/queue_consumer.py +0 -168
- package/src/superlocalmemory/core/ram_lock.py +0 -160
- package/src/superlocalmemory/core/rate_limit.py +0 -151
- package/src/superlocalmemory/core/recall_gate.py +0 -95
- package/src/superlocalmemory/core/recall_pipeline.py +0 -1337
- package/src/superlocalmemory/core/recall_queue.py +0 -377
- package/src/superlocalmemory/core/recall_worker.py +0 -414
- package/src/superlocalmemory/core/registry.py +0 -121
- package/src/superlocalmemory/core/remember_admission.py +0 -161
- package/src/superlocalmemory/core/remember_runtime.py +0 -1190
- package/src/superlocalmemory/core/remote_mode.py +0 -214
- package/src/superlocalmemory/core/reranker_worker.py +0 -338
- package/src/superlocalmemory/core/safe_fs.py +0 -108
- package/src/superlocalmemory/core/scale_autopromote.py +0 -196
- package/src/superlocalmemory/core/scale_engine.py +0 -915
- package/src/superlocalmemory/core/score_contract.py +0 -82
- package/src/superlocalmemory/core/security_primitives.py +0 -672
- package/src/superlocalmemory/core/session_identity.py +0 -98
- package/src/superlocalmemory/core/shadow_router.py +0 -319
- package/src/superlocalmemory/core/slm_disabled.py +0 -85
- package/src/superlocalmemory/core/status_contract.py +0 -108
- package/src/superlocalmemory/core/store_pipeline.py +0 -1404
- package/src/superlocalmemory/core/summarizer.py +0 -200
- package/src/superlocalmemory/core/tier_manager.py +0 -461
- package/src/superlocalmemory/core/topic_signature.py +0 -156
- package/src/superlocalmemory/core/transactions/__init__.py +0 -78
- package/src/superlocalmemory/core/transactions/concrete_owners.py +0 -604
- package/src/superlocalmemory/core/transactions/erasure.py +0 -825
- package/src/superlocalmemory/core/transactions/manifest.py +0 -255
- package/src/superlocalmemory/core/transactions/manifest_key.py +0 -155
- package/src/superlocalmemory/core/transactions/obligations.py +0 -272
- package/src/superlocalmemory/core/transactions/owners.py +0 -114
- package/src/superlocalmemory/core/transactions/reconciler.py +0 -285
- package/src/superlocalmemory/core/transactions/service.py +0 -330
- package/src/superlocalmemory/core/worker_pool.py +0 -377
- package/src/superlocalmemory/core/working_memory.py +0 -288
- package/src/superlocalmemory/dynamics/__init__.py +0 -0
- package/src/superlocalmemory/dynamics/activation_guided_quantization.py +0 -374
- package/src/superlocalmemory/dynamics/eap_scheduler.py +0 -294
- package/src/superlocalmemory/dynamics/ebbinghaus_langevin_coupling.py +0 -171
- package/src/superlocalmemory/dynamics/fisher_langevin_coupling.py +0 -227
- package/src/superlocalmemory/encoding/__init__.py +0 -0
- package/src/superlocalmemory/encoding/auto_linker.py +0 -308
- package/src/superlocalmemory/encoding/cognitive_consolidator.py +0 -899
- package/src/superlocalmemory/encoding/consolidator.py +0 -472
- package/src/superlocalmemory/encoding/context_generator.py +0 -175
- package/src/superlocalmemory/encoding/emotional.py +0 -189
- package/src/superlocalmemory/encoding/entity_reflexion.py +0 -200
- package/src/superlocalmemory/encoding/entity_resolver.py +0 -687
- package/src/superlocalmemory/encoding/entropy_gate.py +0 -101
- package/src/superlocalmemory/encoding/fact_extractor.py +0 -877
- package/src/superlocalmemory/encoding/foresight.py +0 -93
- package/src/superlocalmemory/encoding/graph_builder.py +0 -346
- package/src/superlocalmemory/encoding/observation_builder.py +0 -177
- package/src/superlocalmemory/encoding/prospective_markers.py +0 -262
- package/src/superlocalmemory/encoding/scene_builder.py +0 -410
- package/src/superlocalmemory/encoding/signal_inference.py +0 -90
- package/src/superlocalmemory/encoding/temporal_parser.py +0 -432
- package/src/superlocalmemory/encoding/temporal_validator.py +0 -572
- package/src/superlocalmemory/encoding/type_router.py +0 -237
- package/src/superlocalmemory/evaluation/__init__.py +0 -13
- package/src/superlocalmemory/evaluation/calibration.py +0 -308
- package/src/superlocalmemory/evolution/__init__.py +0 -29
- package/src/superlocalmemory/evolution/blind_verifier.py +0 -122
- package/src/superlocalmemory/evolution/budget.py +0 -356
- package/src/superlocalmemory/evolution/evolution_store.py +0 -619
- package/src/superlocalmemory/evolution/llm_dispatch.py +0 -559
- package/src/superlocalmemory/evolution/model_selection.py +0 -175
- package/src/superlocalmemory/evolution/mutation_generator.py +0 -226
- package/src/superlocalmemory/evolution/skill_activator.py +0 -270
- package/src/superlocalmemory/evolution/skill_evolver.py +0 -928
- package/src/superlocalmemory/evolution/triggers.py +0 -376
- package/src/superlocalmemory/evolution/types.py +0 -114
- package/src/superlocalmemory/graph/__init__.py +0 -9
- package/src/superlocalmemory/graph/cozo_adjacency.py +0 -122
- package/src/superlocalmemory/graph/cozo_backend.py +0 -751
- package/src/superlocalmemory/hooks/__init__.py +0 -3
- package/src/superlocalmemory/hooks/_outcome_common.py +0 -523
- package/src/superlocalmemory/hooks/adapter_base.py +0 -347
- package/src/superlocalmemory/hooks/antigravity_adapter.py +0 -171
- package/src/superlocalmemory/hooks/auto_capture.py +0 -133
- package/src/superlocalmemory/hooks/auto_invoker.py +0 -521
- package/src/superlocalmemory/hooks/auto_parameterize.py +0 -147
- package/src/superlocalmemory/hooks/auto_recall.py +0 -191
- package/src/superlocalmemory/hooks/auto_recall_hook.py +0 -251
- package/src/superlocalmemory/hooks/before_web_hook.py +0 -131
- package/src/superlocalmemory/hooks/claude_code_hooks.py +0 -637
- package/src/superlocalmemory/hooks/codex_assets.py +0 -251
- package/src/superlocalmemory/hooks/codex_hooks.py +0 -186
- package/src/superlocalmemory/hooks/context_payload.py +0 -311
- package/src/superlocalmemory/hooks/copilot_adapter.py +0 -208
- package/src/superlocalmemory/hooks/cross_platform_connector.py +0 -90
- package/src/superlocalmemory/hooks/cursor_adapter.py +0 -173
- package/src/superlocalmemory/hooks/hook_daemon.py +0 -295
- package/src/superlocalmemory/hooks/hook_handlers.py +0 -822
- package/src/superlocalmemory/hooks/ide_connector.py +0 -246
- package/src/superlocalmemory/hooks/memory_protocol.py +0 -158
- package/src/superlocalmemory/hooks/portable_kit.py +0 -755
- package/src/superlocalmemory/hooks/post_tool_async_hook.py +0 -183
- package/src/superlocalmemory/hooks/post_tool_outcome_hook.py +0 -351
- package/src/superlocalmemory/hooks/prewarm_auth.py +0 -187
- package/src/superlocalmemory/hooks/rules_engine.py +0 -99
- package/src/superlocalmemory/hooks/session_registry.py +0 -330
- package/src/superlocalmemory/hooks/stop_outcome_hook.py +0 -138
- package/src/superlocalmemory/hooks/sync_loop.py +0 -114
- package/src/superlocalmemory/hooks/topic_shift_hook.py +0 -302
- package/src/superlocalmemory/hooks/user_prompt_hook.py +0 -131
- package/src/superlocalmemory/hooks/user_prompt_rehash_hook.py +0 -210
- package/src/superlocalmemory/infra/__init__.py +0 -3
- package/src/superlocalmemory/infra/auth_middleware.py +0 -145
- package/src/superlocalmemory/infra/backup.py +0 -974
- package/src/superlocalmemory/infra/backup_obligations.py +0 -423
- package/src/superlocalmemory/infra/cache_manager.py +0 -267
- package/src/superlocalmemory/infra/cloud_backup.py +0 -788
- package/src/superlocalmemory/infra/daemon_identity.py +0 -300
- package/src/superlocalmemory/infra/data_root.py +0 -238
- package/src/superlocalmemory/infra/event_bus.py +0 -637
- package/src/superlocalmemory/infra/local_diagnostics.py +0 -327
- package/src/superlocalmemory/infra/pid_manager.py +0 -193
- package/src/superlocalmemory/infra/process_identity.py +0 -180
- package/src/superlocalmemory/infra/process_reaper.py +0 -624
- package/src/superlocalmemory/infra/rate_limiter.py +0 -228
- package/src/superlocalmemory/infra/self_heal.py +0 -401
- package/src/superlocalmemory/infra/version_integrity.py +0 -229
- package/src/superlocalmemory/ingestion/__init__.py +0 -13
- package/src/superlocalmemory/ingestion/adapter_manager.py +0 -255
- package/src/superlocalmemory/ingestion/base_adapter.py +0 -171
- package/src/superlocalmemory/ingestion/calendar_adapter.py +0 -349
- package/src/superlocalmemory/ingestion/credentials.py +0 -125
- package/src/superlocalmemory/ingestion/gmail_adapter.py +0 -378
- package/src/superlocalmemory/ingestion/parsers.py +0 -100
- package/src/superlocalmemory/ingestion/transcript_adapter.py +0 -161
- package/src/superlocalmemory/integrations/__init__.py +0 -1
- package/src/superlocalmemory/integrations/bounded_loops_mcp.py +0 -431
- package/src/superlocalmemory/integrations/bounded_loops_v051.py +0 -236
- package/src/superlocalmemory/learning/__init__.py +0 -0
- package/src/superlocalmemory/learning/adaptive.py +0 -172
- package/src/superlocalmemory/learning/arm_catalog.py +0 -97
- package/src/superlocalmemory/learning/assertion_miner.py +0 -403
- package/src/superlocalmemory/learning/bandit.py +0 -654
- package/src/superlocalmemory/learning/bandit_cache.py +0 -131
- package/src/superlocalmemory/learning/behavioral.py +0 -542
- package/src/superlocalmemory/learning/bootstrap.py +0 -298
- package/src/superlocalmemory/learning/consolidation_cycle.py +0 -398
- package/src/superlocalmemory/learning/consolidation_quantization_worker.py +0 -115
- package/src/superlocalmemory/learning/consolidation_worker.py +0 -261
- package/src/superlocalmemory/learning/cross_project.py +0 -408
- package/src/superlocalmemory/learning/database.py +0 -698
- package/src/superlocalmemory/learning/dedup_hnsw.py +0 -413
- package/src/superlocalmemory/learning/engagement.py +0 -487
- package/src/superlocalmemory/learning/engagement_features.py +0 -279
- package/src/superlocalmemory/learning/ensemble.py +0 -309
- package/src/superlocalmemory/learning/entity_compiler.py +0 -356
- package/src/superlocalmemory/learning/fact_outcome_joins.py +0 -207
- package/src/superlocalmemory/learning/features.py +0 -138
- package/src/superlocalmemory/learning/feedback.py +0 -724
- package/src/superlocalmemory/learning/forgetting_scheduler.py +0 -375
- package/src/superlocalmemory/learning/hnsw_dedup.py +0 -69
- package/src/superlocalmemory/learning/labeler.py +0 -85
- package/src/superlocalmemory/learning/legacy_migration.py +0 -316
- package/src/superlocalmemory/learning/lightgbm_subprocess.py +0 -236
- package/src/superlocalmemory/learning/memory_merge.py +0 -175
- package/src/superlocalmemory/learning/model_cache.py +0 -267
- package/src/superlocalmemory/learning/model_rollback.py +0 -281
- package/src/superlocalmemory/learning/outcome_queue.py +0 -306
- package/src/superlocalmemory/learning/outcomes.py +0 -286
- package/src/superlocalmemory/learning/pattern_miner.py +0 -465
- package/src/superlocalmemory/learning/pattern_miner_constants.py +0 -90
- package/src/superlocalmemory/learning/pcos.py +0 -291
- package/src/superlocalmemory/learning/project_context.py +0 -366
- package/src/superlocalmemory/learning/propensity.py +0 -131
- package/src/superlocalmemory/learning/ranker.py +0 -300
- package/src/superlocalmemory/learning/ranker_common.py +0 -163
- package/src/superlocalmemory/learning/ranker_retrain_legacy.py +0 -210
- package/src/superlocalmemory/learning/ranker_retrain_online.py +0 -423
- package/src/superlocalmemory/learning/reward.py +0 -888
- package/src/superlocalmemory/learning/reward_archive.py +0 -223
- package/src/superlocalmemory/learning/reward_boost.py +0 -211
- package/src/superlocalmemory/learning/reward_from_outcomes.py +0 -365
- package/src/superlocalmemory/learning/reward_model.py +0 -144
- package/src/superlocalmemory/learning/reward_proxy.py +0 -578
- package/src/superlocalmemory/learning/shadow_test.py +0 -524
- package/src/superlocalmemory/learning/signal_kinds.py +0 -79
- package/src/superlocalmemory/learning/signal_worker.py +0 -268
- package/src/superlocalmemory/learning/signals.py +0 -646
- package/src/superlocalmemory/learning/skill_performance_miner.py +0 -422
- package/src/superlocalmemory/learning/source_quality.py +0 -828
- package/src/superlocalmemory/learning/trigram_index.py +0 -548
- package/src/superlocalmemory/learning/workflows.py +0 -309
- package/src/superlocalmemory/llm/__init__.py +0 -0
- package/src/superlocalmemory/llm/backbone.py +0 -364
- package/src/superlocalmemory/loops/__init__.py +0 -58
- package/src/superlocalmemory/loops/budget.py +0 -58
- package/src/superlocalmemory/loops/engine.py +0 -174
- package/src/superlocalmemory/loops/ledger.py +0 -298
- package/src/superlocalmemory/loops/models.py +0 -152
- package/src/superlocalmemory/loops/rules.py +0 -52
- package/src/superlocalmemory/math/__init__.py +0 -0
- package/src/superlocalmemory/math/ebbinghaus.py +0 -352
- package/src/superlocalmemory/math/fisher.py +0 -356
- package/src/superlocalmemory/math/fisher_quantized.py +0 -255
- package/src/superlocalmemory/math/hopfield.py +0 -282
- package/src/superlocalmemory/math/langevin.py +0 -411
- package/src/superlocalmemory/math/polar_quant.py +0 -414
- package/src/superlocalmemory/math/qjl.py +0 -115
- package/src/superlocalmemory/math/sheaf.py +0 -261
- package/src/superlocalmemory/math/turbo_quant.py +0 -318
- package/src/superlocalmemory/mcp/__init__.py +0 -0
- package/src/superlocalmemory/mcp/_daemon_proxy.py +0 -203
- package/src/superlocalmemory/mcp/_pool_adapter.py +0 -181
- package/src/superlocalmemory/mcp/_stdin_guard.py +0 -60
- package/src/superlocalmemory/mcp/agent_context.py +0 -115
- package/src/superlocalmemory/mcp/cli_fallback.py +0 -602
- package/src/superlocalmemory/mcp/http_transport.py +0 -85
- package/src/superlocalmemory/mcp/profiles.py +0 -154
- package/src/superlocalmemory/mcp/resources.py +0 -281
- package/src/superlocalmemory/mcp/server.py +0 -480
- package/src/superlocalmemory/mcp/session_binding.py +0 -98
- package/src/superlocalmemory/mcp/shared.py +0 -112
- package/src/superlocalmemory/mcp/tools.py +0 -18
- package/src/superlocalmemory/mcp/tools_active.py +0 -958
- package/src/superlocalmemory/mcp/tools_brain.py +0 -298
- package/src/superlocalmemory/mcp/tools_code_graph.py +0 -1717
- package/src/superlocalmemory/mcp/tools_context.py +0 -239
- package/src/superlocalmemory/mcp/tools_core.py +0 -1112
- package/src/superlocalmemory/mcp/tools_evolution.py +0 -343
- package/src/superlocalmemory/mcp/tools_learning.py +0 -393
- package/src/superlocalmemory/mcp/tools_loops.py +0 -345
- package/src/superlocalmemory/mcp/tools_mesh.py +0 -429
- package/src/superlocalmemory/mcp/tools_ops.py +0 -115
- package/src/superlocalmemory/mcp/tools_optimize.py +0 -322
- package/src/superlocalmemory/mcp/tools_summaries.py +0 -147
- package/src/superlocalmemory/mcp/tools_v28.py +0 -292
- package/src/superlocalmemory/mcp/tools_v3.py +0 -398
- package/src/superlocalmemory/mcp/tools_v33.py +0 -507
- package/src/superlocalmemory/mesh/__init__.py +0 -12
- package/src/superlocalmemory/mesh/broker.py +0 -812
- package/src/superlocalmemory/mesh/broker_security.py +0 -470
- package/src/superlocalmemory/mesh/discovery.py +0 -365
- package/src/superlocalmemory/mesh/lock_protocol.py +0 -313
- package/src/superlocalmemory/mesh/node_identity.py +0 -97
- package/src/superlocalmemory/mesh/outbox_remote.py +0 -429
- package/src/superlocalmemory/mesh/remote_sync.py +0 -829
- package/src/superlocalmemory/mesh/state_sync.py +0 -286
- package/src/superlocalmemory/migrations/__init__.py +0 -5
- package/src/superlocalmemory/migrations/v3_4_25_to_v3_4_26.py +0 -144
- package/src/superlocalmemory/optimize/NOTICE +0 -6
- package/src/superlocalmemory/optimize/__init__.py +0 -0
- package/src/superlocalmemory/optimize/adapters/__init__.py +0 -68
- package/src/superlocalmemory/optimize/adapters/_agent_registry.py +0 -120
- package/src/superlocalmemory/optimize/adapters/anthropic_adapter.py +0 -112
- package/src/superlocalmemory/optimize/adapters/openai_adapter.py +0 -122
- package/src/superlocalmemory/optimize/adapters/wrap.py +0 -228
- package/src/superlocalmemory/optimize/cache/__init__.py +0 -31
- package/src/superlocalmemory/optimize/cache/boundary_store.py +0 -488
- package/src/superlocalmemory/optimize/cache/centroid_store.py +0 -199
- package/src/superlocalmemory/optimize/cache/context_key.py +0 -67
- package/src/superlocalmemory/optimize/cache/exact.py +0 -88
- package/src/superlocalmemory/optimize/cache/invalidation.py +0 -36
- package/src/superlocalmemory/optimize/cache/key_builder.py +0 -111
- package/src/superlocalmemory/optimize/cache/manager.py +0 -737
- package/src/superlocalmemory/optimize/cache/semantic.py +0 -637
- package/src/superlocalmemory/optimize/cache/stampede.py +0 -50
- package/src/superlocalmemory/optimize/compress/__init__.py +0 -17
- package/src/superlocalmemory/optimize/compress/align.py +0 -159
- package/src/superlocalmemory/optimize/compress/ccr.py +0 -116
- package/src/superlocalmemory/optimize/compress/prose_llmlingua.py +0 -71
- package/src/superlocalmemory/optimize/compress/router.py +0 -667
- package/src/superlocalmemory/optimize/config/__init__.py +0 -56
- package/src/superlocalmemory/optimize/config/defaults.py +0 -43
- package/src/superlocalmemory/optimize/config/schema.py +0 -327
- package/src/superlocalmemory/optimize/config/store.py +0 -270
- package/src/superlocalmemory/optimize/metrics/__init__.py +0 -8
- package/src/superlocalmemory/optimize/metrics/counters.py +0 -155
- package/src/superlocalmemory/optimize/metrics/estimator.py +0 -87
- package/src/superlocalmemory/optimize/metrics/exporters.py +0 -77
- package/src/superlocalmemory/optimize/metrics/persistence.py +0 -115
- package/src/superlocalmemory/optimize/proxy/__init__.py +0 -28
- package/src/superlocalmemory/optimize/proxy/_helpers.py +0 -730
- package/src/superlocalmemory/optimize/proxy/anthropic_surface.py +0 -375
- package/src/superlocalmemory/optimize/proxy/capture.py +0 -550
- package/src/superlocalmemory/optimize/proxy/gemini_surface.py +0 -528
- package/src/superlocalmemory/optimize/proxy/lifecycle.py +0 -126
- package/src/superlocalmemory/optimize/proxy/openai_surface.py +0 -465
- package/src/superlocalmemory/optimize/proxy/server.py +0 -199
- package/src/superlocalmemory/optimize/proxy/vertex_surface.py +0 -246
- package/src/superlocalmemory/optimize/storage/__init__.py +0 -0
- package/src/superlocalmemory/optimize/storage/db.py +0 -1185
- package/src/superlocalmemory/optimize/storage/schema.py +0 -205
- package/src/superlocalmemory/parameterization/__init__.py +0 -47
- package/src/superlocalmemory/parameterization/cross_project.py +0 -12
- package/src/superlocalmemory/parameterization/pattern_extractor.py +0 -584
- package/src/superlocalmemory/parameterization/pii_filter.py +0 -106
- package/src/superlocalmemory/parameterization/prompt_injector.py +0 -219
- package/src/superlocalmemory/parameterization/prompt_lifecycle.py +0 -281
- package/src/superlocalmemory/parameterization/soft_prompt_generator.py +0 -542
- package/src/superlocalmemory/parameterization/workflow_miner.py +0 -17
- package/src/superlocalmemory/reliability/__init__.py +0 -45
- package/src/superlocalmemory/reliability/join_liveness.py +0 -301
- package/src/superlocalmemory/reliability/prior_distance.py +0 -243
- package/src/superlocalmemory/retrieval/__init__.py +0 -0
- package/src/superlocalmemory/retrieval/agentic.py +0 -367
- package/src/superlocalmemory/retrieval/ann_index.py +0 -235
- package/src/superlocalmemory/retrieval/bm25_channel.py +0 -451
- package/src/superlocalmemory/retrieval/bridge_discovery.py +0 -253
- package/src/superlocalmemory/retrieval/channel_registry.py +0 -154
- package/src/superlocalmemory/retrieval/channel_status.py +0 -117
- package/src/superlocalmemory/retrieval/engine.py +0 -1615
- package/src/superlocalmemory/retrieval/entity_channel.py +0 -994
- package/src/superlocalmemory/retrieval/forgetting_filter.py +0 -160
- package/src/superlocalmemory/retrieval/fusion.py +0 -81
- package/src/superlocalmemory/retrieval/graph_adjacency.py +0 -219
- package/src/superlocalmemory/retrieval/hopfield_channel.py +0 -465
- package/src/superlocalmemory/retrieval/profile_channel.py +0 -105
- package/src/superlocalmemory/retrieval/quantization_aware_search.py +0 -147
- package/src/superlocalmemory/retrieval/remote_reranker.py +0 -758
- package/src/superlocalmemory/retrieval/reranker.py +0 -674
- package/src/superlocalmemory/retrieval/scope_policy.py +0 -126
- package/src/superlocalmemory/retrieval/semantic_channel.py +0 -638
- package/src/superlocalmemory/retrieval/spreading.py +0 -288
- package/src/superlocalmemory/retrieval/spreading_activation.py +0 -616
- package/src/superlocalmemory/retrieval/strategy.py +0 -248
- package/src/superlocalmemory/retrieval/temporal_channel.py +0 -433
- package/src/superlocalmemory/retrieval/temporal_frame.py +0 -102
- package/src/superlocalmemory/retrieval/temporal_utils.py +0 -122
- package/src/superlocalmemory/retrieval/temporal_validity_filter.py +0 -499
- package/src/superlocalmemory/retrieval/time_window.py +0 -181
- package/src/superlocalmemory/retrieval/vector_store.py +0 -863
- package/src/superlocalmemory/server/__init__.py +0 -1
- package/src/superlocalmemory/server/api.py +0 -310
- package/src/superlocalmemory/server/asset_versions.py +0 -171
- package/src/superlocalmemory/server/bandit_loops.py +0 -158
- package/src/superlocalmemory/server/config_file.py +0 -90
- package/src/superlocalmemory/server/consolidation_runner.py +0 -140
- package/src/superlocalmemory/server/egress_policy.py +0 -258
- package/src/superlocalmemory/server/loopback.py +0 -85
- package/src/superlocalmemory/server/middleware/__init__.py +0 -11
- package/src/superlocalmemory/server/middleware/security_headers.py +0 -144
- package/src/superlocalmemory/server/origin.py +0 -55
- package/src/superlocalmemory/server/profile_runtime.py +0 -515
- package/src/superlocalmemory/server/rbac_enforce.py +0 -194
- package/src/superlocalmemory/server/recall_health.py +0 -343
- package/src/superlocalmemory/server/recall_serializer.py +0 -320
- package/src/superlocalmemory/server/route_mutations.py +0 -104
- package/src/superlocalmemory/server/routes/__init__.py +0 -4
- package/src/superlocalmemory/server/routes/abstraction.py +0 -314
- package/src/superlocalmemory/server/routes/adapters.py +0 -63
- package/src/superlocalmemory/server/routes/agents.py +0 -303
- package/src/superlocalmemory/server/routes/backup.py +0 -869
- package/src/superlocalmemory/server/routes/behavioral.py +0 -659
- package/src/superlocalmemory/server/routes/brain.py +0 -1892
- package/src/superlocalmemory/server/routes/chat.py +0 -393
- package/src/superlocalmemory/server/routes/compliance.py +0 -533
- package/src/superlocalmemory/server/routes/config_api.py +0 -703
- package/src/superlocalmemory/server/routes/data_io.py +0 -329
- package/src/superlocalmemory/server/routes/entity.py +0 -237
- package/src/superlocalmemory/server/routes/events.py +0 -214
- package/src/superlocalmemory/server/routes/evolution.py +0 -510
- package/src/superlocalmemory/server/routes/helpers.py +0 -499
- package/src/superlocalmemory/server/routes/ingest.py +0 -137
- package/src/superlocalmemory/server/routes/insights.py +0 -366
- package/src/superlocalmemory/server/routes/learning.py +0 -834
- package/src/superlocalmemory/server/routes/learning_telemetry.py +0 -154
- package/src/superlocalmemory/server/routes/lifecycle.py +0 -184
- package/src/superlocalmemory/server/routes/memories.py +0 -1661
- package/src/superlocalmemory/server/routes/mesh.py +0 -517
- package/src/superlocalmemory/server/routes/mesh_lock.py +0 -54
- package/src/superlocalmemory/server/routes/mesh_state.py +0 -63
- package/src/superlocalmemory/server/routes/optimize.py +0 -197
- package/src/superlocalmemory/server/routes/prewarm.py +0 -173
- package/src/superlocalmemory/server/routes/profiles.py +0 -292
- package/src/superlocalmemory/server/routes/ratelimit.py +0 -132
- package/src/superlocalmemory/server/routes/rbac.py +0 -366
- package/src/superlocalmemory/server/routes/stats.py +0 -385
- package/src/superlocalmemory/server/routes/tiers.py +0 -222
- package/src/superlocalmemory/server/routes/timeline.py +0 -258
- package/src/superlocalmemory/server/routes/token.py +0 -90
- package/src/superlocalmemory/server/routes/v3_api.py +0 -3023
- package/src/superlocalmemory/server/routes/ws.py +0 -171
- package/src/superlocalmemory/server/security_middleware.py +0 -89
- package/src/superlocalmemory/server/ui.py +0 -354
- package/src/superlocalmemory/server/unified_daemon.py +0 -6326
- package/src/superlocalmemory/server/write_identity.py +0 -195
- package/src/superlocalmemory/storage/__init__.py +0 -0
- package/src/superlocalmemory/storage/_migration_internals.py +0 -638
- package/src/superlocalmemory/storage/_schema_version.py +0 -174
- package/src/superlocalmemory/storage/access_log.py +0 -170
- package/src/superlocalmemory/storage/admission_codec.py +0 -129
- package/src/superlocalmemory/storage/admission_journal.py +0 -843
- package/src/superlocalmemory/storage/agent_experience.py +0 -546
- package/src/superlocalmemory/storage/backup.py +0 -531
- package/src/superlocalmemory/storage/correction_cases.py +0 -670
- package/src/superlocalmemory/storage/database.py +0 -3180
- package/src/superlocalmemory/storage/deferred_writes.py +0 -209
- package/src/superlocalmemory/storage/embedding_codec.py +0 -200
- package/src/superlocalmemory/storage/embedding_migrator.py +0 -672
- package/src/superlocalmemory/storage/erasure_fence.py +0 -45
- package/src/superlocalmemory/storage/execution_learning.py +0 -285
- package/src/superlocalmemory/storage/external_evidence.py +0 -359
- package/src/superlocalmemory/storage/generation_fence.py +0 -63
- package/src/superlocalmemory/storage/lineage_retention.py +0 -236
- package/src/superlocalmemory/storage/logical_edges.py +0 -86
- package/src/superlocalmemory/storage/memory_write.py +0 -115
- package/src/superlocalmemory/storage/migration_runner.py +0 -895
- package/src/superlocalmemory/storage/migration_v33.py +0 -140
- package/src/superlocalmemory/storage/migrations/M001_add_signal_features_columns.py +0 -67
- package/src/superlocalmemory/storage/migrations/M002_model_state_history.py +0 -107
- package/src/superlocalmemory/storage/migrations/M003_migration_log.py +0 -38
- package/src/superlocalmemory/storage/migrations/M004_cross_platform_sync_log.py +0 -46
- package/src/superlocalmemory/storage/migrations/M005_bandit_tables.py +0 -75
- package/src/superlocalmemory/storage/migrations/M006_action_outcomes_reward.py +0 -75
- package/src/superlocalmemory/storage/migrations/M007_pending_outcomes.py +0 -63
- package/src/superlocalmemory/storage/migrations/M009_model_lineage.py +0 -94
- package/src/superlocalmemory/storage/migrations/M010_evolution_config.py +0 -80
- package/src/superlocalmemory/storage/migrations/M011_archive_and_merge.py +0 -87
- package/src/superlocalmemory/storage/migrations/M012_shadow_observations.py +0 -72
- package/src/superlocalmemory/storage/migrations/M013_bi_temporal_columns.py +0 -55
- package/src/superlocalmemory/storage/migrations/M014_v345_scale_ready.py +0 -45
- package/src/superlocalmemory/storage/migrations/M015_add_pinned_column.py +0 -58
- package/src/superlocalmemory/storage/migrations/M016_add_scope_support.py +0 -120
- package/src/superlocalmemory/storage/migrations/M017_ccq_scope_column.py +0 -79
- package/src/superlocalmemory/storage/migrations/M018_ingestion_operations.py +0 -120
- package/src/superlocalmemory/storage/migrations/M019_derivation_lineage.py +0 -54
- package/src/superlocalmemory/storage/migrations/M020_model_state_integrity.py +0 -52
- package/src/superlocalmemory/storage/migrations/M021_ingestion_log_profile.py +0 -108
- package/src/superlocalmemory/storage/migrations/M022_entity_aliases_profile.py +0 -86
- package/src/superlocalmemory/storage/migrations/M023_mesh_profile_isolation.py +0 -194
- package/src/superlocalmemory/storage/migrations/M024_rbac_users_roles.py +0 -87
- package/src/superlocalmemory/storage/migrations/M025_perf_indexes.py +0 -90
- package/src/superlocalmemory/storage/migrations/M026_rbac_memberships_fk.py +0 -136
- package/src/superlocalmemory/storage/migrations/M027_transferable_patterns_profile.py +0 -163
- package/src/superlocalmemory/storage/migrations/M028_fact_entity_associations.py +0 -305
- package/src/superlocalmemory/storage/migrations/M029_behavioral_history_indexes.py +0 -137
- package/src/superlocalmemory/storage/migrations/M030_entity_explorer_indexes.py +0 -93
- package/src/superlocalmemory/storage/migrations/M031_dead_letter_operations.py +0 -80
- package/src/superlocalmemory/storage/migrations/M032_write_coordinator_admission.py +0 -188
- package/src/superlocalmemory/storage/migrations/M033_projection_transactions.py +0 -148
- package/src/superlocalmemory/storage/migrations/M034_obligation_integrity.py +0 -58
- package/src/superlocalmemory/storage/migrations/M035_erasure_receipts.py +0 -113
- package/src/superlocalmemory/storage/migrations/M036_vector_row_map.py +0 -107
- package/src/superlocalmemory/storage/migrations/M037_manifest_hmac_version.py +0 -162
- package/src/superlocalmemory/storage/migrations/M038_learning_feedback_channel.py +0 -77
- package/src/superlocalmemory/storage/migrations/M039_scene_fact_members.py +0 -137
- package/src/superlocalmemory/storage/migrations/M040_agent_experience_receipts.py +0 -254
- package/src/superlocalmemory/storage/migrations/M041_external_evidence_receipts.py +0 -189
- package/src/superlocalmemory/storage/migrations/M042_correction_case_ledger.py +0 -245
- package/src/superlocalmemory/storage/migrations/M043_quarantine_display_summaries.py +0 -512
- package/src/superlocalmemory/storage/migrations/M044_play_carries_its_own_evidence.py +0 -127
- package/src/superlocalmemory/storage/migrations/M045_fact_outcome_score.py +0 -158
- package/src/superlocalmemory/storage/migrations/M046_prospective_memory_has_its_own_name.py +0 -620
- package/src/superlocalmemory/storage/migrations/M047_fisher_vectors_are_stored_like_every_other_vector.py +0 -306
- package/src/superlocalmemory/storage/migrations/M048_upcoming_holds_only_what_is_upcoming.py +0 -229
- package/src/superlocalmemory/storage/migrations/M049_a_schema_version_marker_is_one_row.py +0 -201
- package/src/superlocalmemory/storage/migrations/M050_execution_learning_v2.py +0 -70
- package/src/superlocalmemory/storage/migrations/__init__.py +0 -103
- package/src/superlocalmemory/storage/migrations.py +0 -333
- package/src/superlocalmemory/storage/models.py +0 -500
- package/src/superlocalmemory/storage/projection_outbox.py +0 -346
- package/src/superlocalmemory/storage/quantized_store.py +0 -280
- package/src/superlocalmemory/storage/read_connection.py +0 -115
- package/src/superlocalmemory/storage/retention_policy.py +0 -860
- package/src/superlocalmemory/storage/schema.py +0 -1108
- package/src/superlocalmemory/storage/schema_code_graph.py +0 -282
- package/src/superlocalmemory/storage/schema_v32.py +0 -382
- package/src/superlocalmemory/storage/schema_v3410.py +0 -159
- package/src/superlocalmemory/storage/schema_v3411.py +0 -149
- package/src/superlocalmemory/storage/schema_v343.py +0 -315
- package/src/superlocalmemory/storage/schema_v345.py +0 -109
- package/src/superlocalmemory/storage/schema_v347.py +0 -140
- package/src/superlocalmemory/storage/sqlite_vectors.py +0 -169
- package/src/superlocalmemory/storage/v2_migrator.py +0 -466
- package/src/superlocalmemory/storage/write_coordinator.py +0 -949
- package/src/superlocalmemory/storage/write_lock.py +0 -88
- package/src/superlocalmemory/summaries/__init__.py +0 -37
- package/src/superlocalmemory/summaries/base.py +0 -267
- package/src/superlocalmemory/summaries/daily_reflection.py +0 -340
- package/src/superlocalmemory/summaries/non_answer.py +0 -223
- package/src/superlocalmemory/summaries/project_work_log.py +0 -440
- package/src/superlocalmemory/summaries/session_summary.py +0 -311
- package/src/superlocalmemory/trust/__init__.py +0 -0
- package/src/superlocalmemory/trust/gate.py +0 -171
- package/src/superlocalmemory/trust/provenance.py +0 -124
- package/src/superlocalmemory/trust/scorer.py +0 -413
- package/src/superlocalmemory/trust/signals.py +0 -153
- package/src/superlocalmemory/ui/assets/slm-icon-white.svg +0 -64
- package/src/superlocalmemory/ui/assets/slm-icon.svg +0 -36
- package/src/superlocalmemory/ui/css/brain.css +0 -409
- package/src/superlocalmemory/ui/css/design-system.css +0 -696
- package/src/superlocalmemory/ui/css/legacy-dashboard.css +0 -663
- package/src/superlocalmemory/ui/css/neural-glass.css +0 -1599
- package/src/superlocalmemory/ui/css/od-bridge.css +0 -158
- package/src/superlocalmemory/ui/favicon.svg +0 -36
- package/src/superlocalmemory/ui/index.html +0 -1638
- package/src/superlocalmemory/ui/js/agents.js +0 -192
- package/src/superlocalmemory/ui/js/auto-settings.js +0 -624
- package/src/superlocalmemory/ui/js/brain.js +0 -1400
- package/src/superlocalmemory/ui/js/clusters.js +0 -326
- package/src/superlocalmemory/ui/js/compliance.js +0 -307
- package/src/superlocalmemory/ui/js/core.js +0 -566
- package/src/superlocalmemory/ui/js/dashboard.js +0 -503
- package/src/superlocalmemory/ui/js/event-delegation.js +0 -113
- package/src/superlocalmemory/ui/js/events.js +0 -178
- package/src/superlocalmemory/ui/js/fact-detail.js +0 -142
- package/src/superlocalmemory/ui/js/feedback.js +0 -339
- package/src/superlocalmemory/ui/js/graph-event-bus.js +0 -83
- package/src/superlocalmemory/ui/js/graph-filters.js +0 -220
- package/src/superlocalmemory/ui/js/graph-ui.js +0 -214
- package/src/superlocalmemory/ui/js/ide-status.js +0 -115
- package/src/superlocalmemory/ui/js/init.js +0 -54
- package/src/superlocalmemory/ui/js/knowledge-graph.js +0 -945
- package/src/superlocalmemory/ui/js/lifecycle.js +0 -387
- package/src/superlocalmemory/ui/js/math-health.js +0 -114
- package/src/superlocalmemory/ui/js/memories.js +0 -394
- package/src/superlocalmemory/ui/js/memory-chat.js +0 -371
- package/src/superlocalmemory/ui/js/memory-timeline.js +0 -265
- package/src/superlocalmemory/ui/js/modal.js +0 -733
- package/src/superlocalmemory/ui/js/ng-entities.js +0 -298
- package/src/superlocalmemory/ui/js/ng-health.js +0 -208
- package/src/superlocalmemory/ui/js/ng-ingestion.js +0 -203
- package/src/superlocalmemory/ui/js/ng-mesh.js +0 -374
- package/src/superlocalmemory/ui/js/ng-shell.js +0 -524
- package/src/superlocalmemory/ui/js/ng-skills.js +0 -663
- package/src/superlocalmemory/ui/js/od-agents.js +0 -588
- package/src/superlocalmemory/ui/js/od-auth-gate.js +0 -257
- package/src/superlocalmemory/ui/js/od-backup.js +0 -878
- package/src/superlocalmemory/ui/js/od-boundedloops.js +0 -324
- package/src/superlocalmemory/ui/js/od-brain.js +0 -1095
- package/src/superlocalmemory/ui/js/od-compliance-ext.js +0 -301
- package/src/superlocalmemory/ui/js/od-components.js +0 -147
- package/src/superlocalmemory/ui/js/od-entities.js +0 -622
- package/src/superlocalmemory/ui/js/od-graph.js +0 -776
- package/src/superlocalmemory/ui/js/od-health.js +0 -579
- package/src/superlocalmemory/ui/js/od-mcp.js +0 -508
- package/src/superlocalmemory/ui/js/od-memories.js +0 -1499
- package/src/superlocalmemory/ui/js/od-mesh.js +0 -645
- package/src/superlocalmemory/ui/js/od-operations.js +0 -1268
- package/src/superlocalmemory/ui/js/od-ops-health.js +0 -417
- package/src/superlocalmemory/ui/js/od-optimize.js +0 -828
- package/src/superlocalmemory/ui/js/od-settings.js +0 -1275
- package/src/superlocalmemory/ui/js/od-shell.js +0 -819
- package/src/superlocalmemory/ui/js/od-skills.js +0 -600
- package/src/superlocalmemory/ui/js/od-team.js +0 -265
- package/src/superlocalmemory/ui/js/optimize.js +0 -191
- package/src/superlocalmemory/ui/js/profiles.js +0 -362
- package/src/superlocalmemory/ui/js/quick-actions.js +0 -334
- package/src/superlocalmemory/ui/js/recall-lab.js +0 -373
- package/src/superlocalmemory/ui/js/search.js +0 -86
- package/src/superlocalmemory/ui/js/settings.js +0 -556
- package/src/superlocalmemory/ui/js/timeline.js +0 -62
- package/src/superlocalmemory/ui/js/trust-dashboard.js +0 -225
- package/src/superlocalmemory/ui/vendor/bootstrap-icons/bootstrap-icons.css +0 -2018
- package/src/superlocalmemory/ui/vendor/bootstrap-icons/fonts/bootstrap-icons.woff +0 -0
- package/src/superlocalmemory/ui/vendor/bootstrap-icons/fonts/bootstrap-icons.woff2 +0 -0
- package/src/superlocalmemory/ui/vendor/bootstrap.bundle.min.js +0 -7
- package/src/superlocalmemory/ui/vendor/bootstrap.min.css +0 -6
- package/src/superlocalmemory/ui/vendor/d3.v7.min.js +0 -2
- package/src/superlocalmemory/ui/vendor/graphology-library.min.js +0 -2
- package/src/superlocalmemory/ui/vendor/graphology.umd.min.js +0 -2
- package/src/superlocalmemory/ui/vendor/inter-ui/inter-variable.min.css +0 -8
- package/src/superlocalmemory/ui/vendor/inter-ui/variable/InterVariable-Italic.woff2 +0 -0
- package/src/superlocalmemory/ui/vendor/inter-ui/variable/InterVariable.woff2 +0 -0
- package/src/superlocalmemory/ui/vendor/sigma.min.js +0 -1
- package/src/superlocalmemory/vector/__init__.py +0 -9
- package/src/superlocalmemory/vector/lancedb_backend.py +0 -366
|
@@ -1,451 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
|
|
2
|
-
# Licensed under AGPL-3.0-or-later - see LICENSE file
|
|
3
|
-
# Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
|
|
4
|
-
|
|
5
|
-
"""SuperLocalMemory V3 — BM25 Keyword Search Channel.
|
|
6
|
-
|
|
7
|
-
Persistent BM25Plus index over fact content. Catches exact name/date
|
|
8
|
-
matches that embedding similarity misses.
|
|
9
|
-
|
|
10
|
-
V1 bug fix: V1 kept BM25 tokens in-memory only — a restart lost
|
|
11
|
-
the entire index. This version persists tokens to the DB via
|
|
12
|
-
store_bm25_tokens / get_all_bm25_tokens and cold-loads on init.
|
|
13
|
-
|
|
14
|
-
Part of Qualixar | Author: Varun Pratap Bhardwaj
|
|
15
|
-
License: AGPL-3.0-or-later
|
|
16
|
-
"""
|
|
17
|
-
|
|
18
|
-
from __future__ import annotations
|
|
19
|
-
|
|
20
|
-
import logging
|
|
21
|
-
import re
|
|
22
|
-
from typing import TYPE_CHECKING
|
|
23
|
-
|
|
24
|
-
from rank_bm25 import BM25Plus
|
|
25
|
-
|
|
26
|
-
from superlocalmemory.storage.database import _scope_where
|
|
27
|
-
|
|
28
|
-
if TYPE_CHECKING:
|
|
29
|
-
from superlocalmemory.storage.database import DatabaseManager
|
|
30
|
-
|
|
31
|
-
logger = logging.getLogger(__name__)
|
|
32
|
-
|
|
33
|
-
# Minimal stopwords — small set to avoid stripping important terms
|
|
34
|
-
_STOPWORDS: frozenset[str] = frozenset({
|
|
35
|
-
"a", "an", "the", "is", "are", "was", "were", "be", "been", "being",
|
|
36
|
-
"have", "has", "had", "do", "does", "did", "will", "would", "shall",
|
|
37
|
-
"should", "may", "might", "must", "can", "could", "of", "in", "to",
|
|
38
|
-
"for", "with", "on", "at", "from", "by", "as", "into", "through",
|
|
39
|
-
"and", "but", "or", "nor", "not", "so", "yet", "if", "then", "than",
|
|
40
|
-
"that", "this", "it", "its", "i", "me", "my", "we", "our", "you",
|
|
41
|
-
"your", "he", "him", "his", "she", "her", "they", "them", "their",
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
# Token pattern: words with letters/digits, keeps hyphens and apostrophes
|
|
45
|
-
_TOKEN_RE = re.compile(r"[a-zA-Z0-9][\w'-]*[a-zA-Z0-9]|[a-zA-Z0-9]")
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
def tokenize(text: str) -> list[str]:
|
|
49
|
-
"""Tokenize text: lowercase, split, remove stopwords.
|
|
50
|
-
|
|
51
|
-
Exported so encoding pipeline can persist tokens at ingest time.
|
|
52
|
-
"""
|
|
53
|
-
tokens = _TOKEN_RE.findall(text.lower())
|
|
54
|
-
return [t for t in tokens if t not in _STOPWORDS]
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
#: Saturation constant for the BM25 -> [0,1) transform. Chosen from measurement,
|
|
58
|
-
#: not taste: raw scores on a live store run ~2.5 to ~15 across query
|
|
59
|
-
#: lengths, so k = 5 puts an ordinary match near 0.4 and a strong one near 0.7,
|
|
60
|
-
#: leaving headroom at both ends rather than pinning everything to one corner.
|
|
61
|
-
_BM25_SATURATION = 5.0
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
def _to_unit_scale(scored: list[tuple[str, float]]) -> list[tuple[str, float]]:
|
|
65
|
-
"""Map BM25 scores into [0, 1) without disturbing order or magnitude.
|
|
66
|
-
|
|
67
|
-
WHY ANY OF THIS. ``engine.apply_channel_weights`` re-scores a candidate as
|
|
68
|
-
``sum(channel_scores[ch] * weights[ch])`` — a SUM of raw channel scores.
|
|
69
|
-
Every other channel is bounded: semantic cosine and Fisher-Rao are [0, 1],
|
|
70
|
-
the temporal proximity score is Gaussian on [0, 1]. BM25 is not. Measured on
|
|
71
|
-
a live store, one query at a time::
|
|
72
|
-
|
|
73
|
-
"slm release" max 2.845
|
|
74
|
-
"memory" max 3.865
|
|
75
|
-
"the release ships once both audits are clean" max 10.150
|
|
76
|
-
|
|
77
|
-
So the sum was decided by a scale rather than by evidence, and any weight
|
|
78
|
-
the bandit converged on was a correction for that scale — wrong the moment
|
|
79
|
-
the query length changed.
|
|
80
|
-
|
|
81
|
-
WHY NOT DIVIDE BY THE BATCH MAXIMUM. That was the first implementation here
|
|
82
|
-
and it is wrong, which an existing test caught before it shipped:
|
|
83
|
-
``test_real_fts5_exact_hit_keeps_bounded_slot`` exists to prove *"a real
|
|
84
|
-
sub-1.0 FTS5 hit remains visible under semantic pressure"*. Dividing by the
|
|
85
|
-
batch maximum makes the best result exactly 1.0 **whatever it scored**, so a
|
|
86
|
-
query with one weak lexical match reports full confidence and outranks a
|
|
87
|
-
semantic channel it should lose to. Batch-relative scaling manufactures
|
|
88
|
-
confidence out of an empty batch, and it also makes a fact's score depend on
|
|
89
|
-
which other facts happened to come back — the same query returning a
|
|
90
|
-
different number on a different day, which HARD-RULES RULE 6 puts above
|
|
91
|
-
speed.
|
|
92
|
-
|
|
93
|
-
A saturating transform has neither problem: ``s / (s + k)`` is strictly
|
|
94
|
-
increasing, so order is untouched; it is bounded below 1.0, so nothing is
|
|
95
|
-
ever certain; and it depends only on the score itself, so it is repeatable.
|
|
96
|
-
Applied to the measurements above: 2.676 -> 0.35, 2.845 -> 0.36,
|
|
97
|
-
3.865 -> 0.44, 10.150 -> 0.67.
|
|
98
|
-
|
|
99
|
-
FUSION IS UNAFFECTED, verified by reading ``fusion.weighted_rrf`` rather
|
|
100
|
-
than assuming: it computes ``fused += w / (k + rank)`` and keeps the score
|
|
101
|
-
only for reporting. Rescaling a value nothing divides by cannot move a
|
|
102
|
-
fused rank.
|
|
103
|
-
|
|
104
|
-
Non-positive scores map to 0.0. FTS5's ``bm25()`` is <= 0 and is negated
|
|
105
|
-
here, so a value at or below zero means "no lexical evidence", and that is
|
|
106
|
-
what it should contribute to a sum.
|
|
107
|
-
"""
|
|
108
|
-
if not scored:
|
|
109
|
-
return scored
|
|
110
|
-
return [
|
|
111
|
-
(fid, (s / (s + _BM25_SATURATION)) if s > 0.0 else 0.0)
|
|
112
|
-
for fid, s in scored
|
|
113
|
-
]
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
class BM25Channel:
|
|
117
|
-
"""Persistent BM25Plus index for keyword retrieval.
|
|
118
|
-
|
|
119
|
-
On cold start, loads all tokens from the DB. After that, new facts
|
|
120
|
-
are added incrementally. The BM25Plus model is rebuilt lazily
|
|
121
|
-
before each search when the corpus has changed.
|
|
122
|
-
|
|
123
|
-
Attributes:
|
|
124
|
-
document_count: Number of indexed documents.
|
|
125
|
-
"""
|
|
126
|
-
|
|
127
|
-
def __init__(self, db: DatabaseManager) -> None:
|
|
128
|
-
self._db = db
|
|
129
|
-
self._corpus: list[list[str]] = []
|
|
130
|
-
self._fact_ids: list[str] = []
|
|
131
|
-
self._fact_id_set: set[str] = set()
|
|
132
|
-
self._raw_texts: list[str] = [] # V3.3.12: raw content for phrase matching
|
|
133
|
-
self._bm25: BM25Plus | None = None
|
|
134
|
-
self._dirty: bool = False
|
|
135
|
-
self._loaded_profiles: set[str] = set()
|
|
136
|
-
self._loaded_scope_key: tuple[str, bool, bool] | None = None
|
|
137
|
-
|
|
138
|
-
@property
|
|
139
|
-
def document_count(self) -> int:
|
|
140
|
-
return len(self._corpus)
|
|
141
|
-
|
|
142
|
-
def ensure_loaded(
|
|
143
|
-
self,
|
|
144
|
-
profile_id: str,
|
|
145
|
-
include_global: bool | None = None,
|
|
146
|
-
include_shared: bool | None = None,
|
|
147
|
-
) -> None:
|
|
148
|
-
"""Cold-load BM25 tokens from DB for a profile (once).
|
|
149
|
-
|
|
150
|
-
Idempotent: subsequent calls for the same profile/scope are no-ops.
|
|
151
|
-
|
|
152
|
-
Args:
|
|
153
|
-
profile_id: Profile to load.
|
|
154
|
-
include_global: Include global-scope facts. Falls back to the
|
|
155
|
-
instance attribute when not supplied.
|
|
156
|
-
include_shared: Include shared-scope facts. Same fallback.
|
|
157
|
-
"""
|
|
158
|
-
if include_global is None:
|
|
159
|
-
include_global = bool(getattr(self, "include_global", False))
|
|
160
|
-
if include_shared is None:
|
|
161
|
-
include_shared = bool(getattr(self, "include_shared", False))
|
|
162
|
-
scope_key = (profile_id, include_global, include_shared)
|
|
163
|
-
if scope_key == self._loaded_scope_key:
|
|
164
|
-
return
|
|
165
|
-
|
|
166
|
-
# A legacy in-memory index is a visibility-specific view. Reusing a
|
|
167
|
-
# corpus warmed under another profile/scope leaks private documents or
|
|
168
|
-
# omits newly enabled global/shared documents.
|
|
169
|
-
self._corpus = []
|
|
170
|
-
self._fact_ids = []
|
|
171
|
-
self._fact_id_set = set()
|
|
172
|
-
self._raw_texts = []
|
|
173
|
-
self._bm25 = None
|
|
174
|
-
token_map = self._db.get_all_bm25_tokens(
|
|
175
|
-
profile_id,
|
|
176
|
-
include_global=include_global,
|
|
177
|
-
include_shared=include_shared,
|
|
178
|
-
)
|
|
179
|
-
if not token_map:
|
|
180
|
-
# Fallback: tokenize facts directly if no pre-stored tokens
|
|
181
|
-
facts = self._db.get_all_facts(
|
|
182
|
-
profile_id,
|
|
183
|
-
include_global=include_global,
|
|
184
|
-
include_shared=include_shared,
|
|
185
|
-
)
|
|
186
|
-
for fact in facts:
|
|
187
|
-
if fact.fact_id in self._fact_id_set:
|
|
188
|
-
continue
|
|
189
|
-
tokens = tokenize(fact.content)
|
|
190
|
-
if tokens:
|
|
191
|
-
self._corpus.append(tokens)
|
|
192
|
-
self._fact_ids.append(fact.fact_id)
|
|
193
|
-
self._fact_id_set.add(fact.fact_id)
|
|
194
|
-
self._raw_texts.append(fact.content)
|
|
195
|
-
# Persist for next cold start
|
|
196
|
-
self._db.store_bm25_tokens(fact.fact_id, profile_id, tokens)
|
|
197
|
-
else:
|
|
198
|
-
# Load raw texts for phrase matching (V3.3.12)
|
|
199
|
-
fact_content_map = {}
|
|
200
|
-
try:
|
|
201
|
-
facts = self._db.get_all_facts(
|
|
202
|
-
profile_id,
|
|
203
|
-
include_global=include_global,
|
|
204
|
-
include_shared=include_shared,
|
|
205
|
-
)
|
|
206
|
-
fact_content_map = {f.fact_id: f.content for f in facts}
|
|
207
|
-
except Exception:
|
|
208
|
-
pass
|
|
209
|
-
for fid, tokens in token_map.items():
|
|
210
|
-
if fid in self._fact_id_set:
|
|
211
|
-
continue
|
|
212
|
-
self._corpus.append(tokens)
|
|
213
|
-
self._fact_ids.append(fid)
|
|
214
|
-
self._fact_id_set.add(fid)
|
|
215
|
-
self._raw_texts.append(fact_content_map.get(fid, ""))
|
|
216
|
-
|
|
217
|
-
self._dirty = True
|
|
218
|
-
self._loaded_profiles.add(profile_id)
|
|
219
|
-
self._loaded_scope_key = scope_key
|
|
220
|
-
logger.debug(
|
|
221
|
-
"BM25 cold-loaded %d documents for profile=%s",
|
|
222
|
-
len(token_map) if token_map else 0, profile_id,
|
|
223
|
-
)
|
|
224
|
-
|
|
225
|
-
def add(self, fact_id: str, content: str, profile_id: str) -> None:
|
|
226
|
-
"""Add a single fact to the index and persist tokens.
|
|
227
|
-
|
|
228
|
-
Args:
|
|
229
|
-
fact_id: Unique fact identifier.
|
|
230
|
-
content: Raw text content to index.
|
|
231
|
-
profile_id: Owner profile.
|
|
232
|
-
"""
|
|
233
|
-
tokens = tokenize(content)
|
|
234
|
-
if not tokens:
|
|
235
|
-
return
|
|
236
|
-
|
|
237
|
-
self._corpus.append(tokens)
|
|
238
|
-
self._fact_ids.append(fact_id)
|
|
239
|
-
self._fact_id_set.add(fact_id)
|
|
240
|
-
if not hasattr(self, '_raw_texts'):
|
|
241
|
-
self._raw_texts = []
|
|
242
|
-
self._raw_texts.append(content)
|
|
243
|
-
self._dirty = True
|
|
244
|
-
|
|
245
|
-
# Persist for cold start
|
|
246
|
-
self._db.store_bm25_tokens(fact_id, profile_id, tokens)
|
|
247
|
-
|
|
248
|
-
def _fts5_search(
|
|
249
|
-
self,
|
|
250
|
-
query: str,
|
|
251
|
-
profile_id: str,
|
|
252
|
-
top_k: int = 30,
|
|
253
|
-
include_global: bool | None = None,
|
|
254
|
-
include_shared: bool | None = None,
|
|
255
|
-
) -> list[tuple[str, float]]:
|
|
256
|
-
"""v3.5.0: SQLite FTS5 keyword search (C-level indexed, scales to millions).
|
|
257
|
-
|
|
258
|
-
Uses the ``atomic_facts_fts`` external-content FTS5 table (kept in sync
|
|
259
|
-
by INSERT/DELETE/UPDATE triggers). Joins ``atomic_facts`` for profile
|
|
260
|
-
scoping (FTS table has no profile_id). ``bm25()`` returns a negative
|
|
261
|
-
score (lower = better match); we negate it to the channel's
|
|
262
|
-
"higher = better" convention. Returns [] on no matches.
|
|
263
|
-
|
|
264
|
-
Raises (OperationalError) if the FTS5 table is absent — the caller
|
|
265
|
-
then falls back to the legacy in-memory rank_bm25 path.
|
|
266
|
-
"""
|
|
267
|
-
if include_global is None:
|
|
268
|
-
include_global = bool(getattr(self, "include_global", False))
|
|
269
|
-
if include_shared is None:
|
|
270
|
-
include_shared = bool(getattr(self, "include_shared", False))
|
|
271
|
-
tokens = tokenize(query)
|
|
272
|
-
if not tokens:
|
|
273
|
-
return []
|
|
274
|
-
# Quote each token so query punctuation can't break FTS5 MATCH syntax;
|
|
275
|
-
# OR-join for high recall (any token may match).
|
|
276
|
-
match_expr = " OR ".join('"' + t.replace('"', "") + '"' for t in tokens)
|
|
277
|
-
where, params = _scope_where(
|
|
278
|
-
profile_id,
|
|
279
|
-
include_global=include_global,
|
|
280
|
-
include_shared=include_shared,
|
|
281
|
-
prefix="af",
|
|
282
|
-
)
|
|
283
|
-
# Soft-deleted and withheld rows are not live. Filtered HERE rather
|
|
284
|
-
# than only at hydration so neither spends one of this channel's top_k
|
|
285
|
-
# slots; the shared clause keeps the definition in one place.
|
|
286
|
-
archive_clause = self._db.visible_fact_clause("af")
|
|
287
|
-
sql = (
|
|
288
|
-
"SELECT af.fact_id AS fact_id, bm25(atomic_facts_fts) AS rank "
|
|
289
|
-
"FROM atomic_facts_fts "
|
|
290
|
-
"JOIN atomic_facts af ON af.rowid = atomic_facts_fts.rowid "
|
|
291
|
-
f"WHERE atomic_facts_fts MATCH ? AND {where}{archive_clause} "
|
|
292
|
-
"ORDER BY rank LIMIT ?"
|
|
293
|
-
)
|
|
294
|
-
rows = self._db.execute(sql, (match_expr, *params, int(top_k)))
|
|
295
|
-
out: list[tuple[str, float]] = []
|
|
296
|
-
for r in rows:
|
|
297
|
-
d = dict(r)
|
|
298
|
-
fid = d.get("fact_id")
|
|
299
|
-
if not fid:
|
|
300
|
-
continue
|
|
301
|
-
out.append((fid, -float(d.get("rank", 0.0))))
|
|
302
|
-
|
|
303
|
-
# T3b: UNION fact-expansion (alias / paraphrase) matches so a query for
|
|
304
|
-
# a synonym matches a fact that only used the canonical term. Additive —
|
|
305
|
-
# direct content hits stay primary; an alias-only hit is added at a
|
|
306
|
-
# discount so it ranks below content matches. Fail-open if the expansion
|
|
307
|
-
# FTS is absent (legacy DB).
|
|
308
|
-
content_ids = {fid for fid, _ in out}
|
|
309
|
-
try:
|
|
310
|
-
exp_sql = (
|
|
311
|
-
"SELECT af.fact_id AS fact_id, bm25(fact_expansion_fts) AS rank "
|
|
312
|
-
"FROM fact_expansion_fts "
|
|
313
|
-
"JOIN atomic_facts af ON af.fact_id = fact_expansion_fts.fact_id "
|
|
314
|
-
f"WHERE fact_expansion_fts MATCH ? AND {where}{archive_clause} "
|
|
315
|
-
"ORDER BY rank LIMIT ?"
|
|
316
|
-
)
|
|
317
|
-
for r in self._db.execute(exp_sql, (match_expr, *params, int(top_k))):
|
|
318
|
-
d = dict(r)
|
|
319
|
-
fid = d.get("fact_id")
|
|
320
|
-
if fid and fid not in content_ids:
|
|
321
|
-
out.append((fid, -float(d.get("rank", 0.0)) * 0.85))
|
|
322
|
-
except Exception as exc: # pragma: no cover — legacy/missing expansion FTS
|
|
323
|
-
logger.debug("Expansion FTS search skipped: %s", exc)
|
|
324
|
-
|
|
325
|
-
out.sort(key=lambda x: (-x[1], x[0]))
|
|
326
|
-
return out[:top_k]
|
|
327
|
-
|
|
328
|
-
def search(
|
|
329
|
-
self,
|
|
330
|
-
query: str,
|
|
331
|
-
profile_id: str,
|
|
332
|
-
top_k: int = 30,
|
|
333
|
-
include_global: bool | None = None,
|
|
334
|
-
include_shared: bool | None = None,
|
|
335
|
-
) -> list[tuple[str, float]]:
|
|
336
|
-
"""Search BM25 index for matching facts.
|
|
337
|
-
|
|
338
|
-
Auto-loads from DB on first call for this profile.
|
|
339
|
-
|
|
340
|
-
Args:
|
|
341
|
-
query: Search query text.
|
|
342
|
-
profile_id: Scope to this profile.
|
|
343
|
-
top_k: Maximum results.
|
|
344
|
-
include_global: Include global-scope facts. Falls back to the
|
|
345
|
-
instance attribute when not supplied.
|
|
346
|
-
include_shared: Include shared-scope facts. Same fallback.
|
|
347
|
-
|
|
348
|
-
Returns:
|
|
349
|
-
List of (fact_id, bm25_score) sorted by score descending.
|
|
350
|
-
"""
|
|
351
|
-
if include_global is None:
|
|
352
|
-
include_global = bool(getattr(self, "include_global", False))
|
|
353
|
-
if include_shared is None:
|
|
354
|
-
include_shared = bool(getattr(self, "include_shared", False))
|
|
355
|
-
# v3.5.0: FTS5 fast path — C-level indexed, ~ms, scales to millions.
|
|
356
|
-
# The legacy in-memory rank_bm25 path rebuilt the whole index over the
|
|
357
|
-
# entire corpus on every corpus change (11s+ at 17.5k facts, does not
|
|
358
|
-
# scale). FTS5 (atomic_facts_fts, kept in sync by triggers) replaces it.
|
|
359
|
-
# Falls back to rank_bm25 ONLY if the FTS5 table is genuinely
|
|
360
|
-
# unavailable (raises) — e.g. a pre-FTS legacy DB.
|
|
361
|
-
try:
|
|
362
|
-
return _to_unit_scale(self._fts5_search(
|
|
363
|
-
query, profile_id, top_k,
|
|
364
|
-
include_global=include_global, include_shared=include_shared,
|
|
365
|
-
))
|
|
366
|
-
except Exception as exc: # pragma: no cover — legacy/missing FTS table
|
|
367
|
-
logger.debug(
|
|
368
|
-
"BM25 FTS5 path unavailable, using rank_bm25 fallback: %s", exc,
|
|
369
|
-
)
|
|
370
|
-
|
|
371
|
-
self.ensure_loaded(profile_id, include_global=include_global, include_shared=include_shared)
|
|
372
|
-
|
|
373
|
-
if not self._corpus:
|
|
374
|
-
return []
|
|
375
|
-
|
|
376
|
-
query_tokens = tokenize(query)
|
|
377
|
-
if not query_tokens:
|
|
378
|
-
return []
|
|
379
|
-
|
|
380
|
-
# Rebuild BM25 model if corpus changed
|
|
381
|
-
if self._dirty or self._bm25 is None:
|
|
382
|
-
self._bm25 = BM25Plus(self._corpus, k1=1.2, b=0.75)
|
|
383
|
-
self._dirty = False
|
|
384
|
-
|
|
385
|
-
scores = self._bm25.get_scores(query_tokens)
|
|
386
|
-
|
|
387
|
-
scored: list[tuple[str, float]] = []
|
|
388
|
-
# V3.3.12: Exact phrase bonus — boost facts containing the full query phrase
|
|
389
|
-
query_lower = query.lower().strip()
|
|
390
|
-
for i, score in enumerate(scores):
|
|
391
|
-
if score > 0.0:
|
|
392
|
-
bonus = score
|
|
393
|
-
# Exact phrase match bonus: if the query appears as a substring in the document
|
|
394
|
-
if len(query_lower) >= 5 and i < len(self._raw_texts):
|
|
395
|
-
if query_lower in self._raw_texts[i].lower():
|
|
396
|
-
bonus *= 1.5 # 50% boost for exact phrase match
|
|
397
|
-
scored.append((self._fact_ids[i], bonus))
|
|
398
|
-
|
|
399
|
-
scored.sort(key=lambda x: (-x[1], x[0]))
|
|
400
|
-
# Same rescale as the FTS5 path. This fallback applies a 1.5x exact
|
|
401
|
-
# phrase bonus, so its raw ceiling is higher still.
|
|
402
|
-
return _to_unit_scale(scored[:top_k])
|
|
403
|
-
|
|
404
|
-
def update_fact(self, fact_id: str, new_content: str, profile_id: str) -> None:
|
|
405
|
-
"""Replace a fact's representation in the live index and persist new tokens.
|
|
406
|
-
|
|
407
|
-
Removes any existing in-memory entry for the fact_id first so the index
|
|
408
|
-
holds each fact exactly once after the call. Delegates to remove_fact +
|
|
409
|
-
add so the two operations stay in sync.
|
|
410
|
-
|
|
411
|
-
Args:
|
|
412
|
-
fact_id: Fact whose content has changed.
|
|
413
|
-
new_content: Updated text to index.
|
|
414
|
-
profile_id: Owner profile (used for DB token persistence).
|
|
415
|
-
"""
|
|
416
|
-
self.remove_fact(fact_id)
|
|
417
|
-
self.add(fact_id, new_content, profile_id)
|
|
418
|
-
|
|
419
|
-
def remove_fact(self, fact_id: str) -> None:
|
|
420
|
-
"""Remove a fact from the live in-memory index.
|
|
421
|
-
|
|
422
|
-
Idempotent: a no-op when the fact is not in the index. Does NOT touch
|
|
423
|
-
the persistent ``bm25_tokens`` DB table — the caller is responsible for
|
|
424
|
-
that (so a delete path can clean up storage independently).
|
|
425
|
-
|
|
426
|
-
Args:
|
|
427
|
-
fact_id: Fact to evict from the in-memory corpus.
|
|
428
|
-
"""
|
|
429
|
-
if fact_id not in self._fact_id_set:
|
|
430
|
-
return
|
|
431
|
-
try:
|
|
432
|
-
idx = self._fact_ids.index(fact_id)
|
|
433
|
-
del self._corpus[idx]
|
|
434
|
-
del self._fact_ids[idx]
|
|
435
|
-
raw_texts = getattr(self, "_raw_texts", [])
|
|
436
|
-
if idx < len(raw_texts):
|
|
437
|
-
del raw_texts[idx]
|
|
438
|
-
self._fact_id_set.discard(fact_id)
|
|
439
|
-
self._dirty = True
|
|
440
|
-
except (ValueError, IndexError):
|
|
441
|
-
self._fact_id_set.discard(fact_id)
|
|
442
|
-
|
|
443
|
-
def clear(self) -> None:
|
|
444
|
-
"""Clear the in-memory index (does NOT delete DB tokens)."""
|
|
445
|
-
self._corpus = []
|
|
446
|
-
self._fact_ids = []
|
|
447
|
-
self._fact_id_set = set()
|
|
448
|
-
self._bm25 = None
|
|
449
|
-
self._dirty = False
|
|
450
|
-
self._loaded_profiles = set()
|
|
451
|
-
self._loaded_scope_key = None
|
|
@@ -1,253 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
|
|
2
|
-
# Licensed under AGPL-3.0-or-later - see LICENSE file
|
|
3
|
-
# Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
|
|
4
|
-
|
|
5
|
-
"""SuperLocalMemory V3 — Bridge Discovery + Spreading Activation.
|
|
6
|
-
|
|
7
|
-
Connects disconnected retrieval results via intermediate facts.
|
|
8
|
-
Combines AriadneMem's 5-step bridging with Hindsight's TEMPR activation.
|
|
9
|
-
|
|
10
|
-
Algorithm:
|
|
11
|
-
1. Sort seed results chronologically
|
|
12
|
-
2. For consecutive pairs, check entity overlap + temporal proximity
|
|
13
|
-
3. If disconnected: try entity/keyword/proper-noun bridge strategies
|
|
14
|
-
4. Add bridge facts with inferred edges
|
|
15
|
-
5. Spreading activation from seeds through graph
|
|
16
|
-
|
|
17
|
-
Parameters:
|
|
18
|
-
- max_depth=3 hops
|
|
19
|
-
- node_budget=8-25
|
|
20
|
-
- time_window=1-168 hours
|
|
21
|
-
- decay=0.7 per hop
|
|
22
|
-
- typed mu: entity=1.2, causal=1.3, semantic=0.8, temporal=0.9
|
|
23
|
-
|
|
24
|
-
Part of Qualixar | Author: Varun Pratap Bhardwaj
|
|
25
|
-
License: AGPL-3.0-or-later
|
|
26
|
-
"""
|
|
27
|
-
from __future__ import annotations
|
|
28
|
-
|
|
29
|
-
import logging
|
|
30
|
-
import time
|
|
31
|
-
from typing import TYPE_CHECKING
|
|
32
|
-
|
|
33
|
-
from superlocalmemory.retrieval.scope_policy import (
|
|
34
|
-
authorized_fact_ids,
|
|
35
|
-
filter_authorized_results,
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
if TYPE_CHECKING:
|
|
39
|
-
from superlocalmemory.storage.database import DatabaseManager
|
|
40
|
-
|
|
41
|
-
logger = logging.getLogger(__name__)
|
|
42
|
-
|
|
43
|
-
# Spreading activation parameters (Hindsight TEMPR)
|
|
44
|
-
_DECAY: float = 0.7
|
|
45
|
-
_TYPED_MU: dict[str, float] = {
|
|
46
|
-
"entity": 1.2,
|
|
47
|
-
"causal": 1.3,
|
|
48
|
-
"semantic": 0.8,
|
|
49
|
-
"temporal": 0.9,
|
|
50
|
-
"supersedes": 0.0,
|
|
51
|
-
}
|
|
52
|
-
_MAX_DEPTH: int = 4
|
|
53
|
-
_NODE_BUDGET: int = 50
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
class BridgeDiscovery:
|
|
57
|
-
"""Connect disconnected retrieval results via graph paths.
|
|
58
|
-
|
|
59
|
-
Usage::
|
|
60
|
-
bridge = BridgeDiscovery(db)
|
|
61
|
-
expanded = bridge.discover(seed_fact_ids, profile_id)
|
|
62
|
-
"""
|
|
63
|
-
|
|
64
|
-
def __init__(self, db: DatabaseManager) -> None:
|
|
65
|
-
self._db = db
|
|
66
|
-
|
|
67
|
-
def discover(
|
|
68
|
-
self,
|
|
69
|
-
seed_ids: list[str],
|
|
70
|
-
profile_id: str,
|
|
71
|
-
max_bridges: int = 10,
|
|
72
|
-
*,
|
|
73
|
-
include_global: bool = False,
|
|
74
|
-
include_shared: bool = False,
|
|
75
|
-
time_budget_s: float = 0.4,
|
|
76
|
-
) -> list[tuple[str, float]]:
|
|
77
|
-
"""Find bridge facts connecting seed results.
|
|
78
|
-
|
|
79
|
-
Args:
|
|
80
|
-
seed_ids: Fact IDs from initial retrieval.
|
|
81
|
-
profile_id: Scope to this profile.
|
|
82
|
-
max_bridges: Maximum bridge facts to return.
|
|
83
|
-
|
|
84
|
-
Returns:
|
|
85
|
-
List of (fact_id, bridge_score) for discovered bridges.
|
|
86
|
-
"""
|
|
87
|
-
if len(seed_ids) < 2:
|
|
88
|
-
return []
|
|
89
|
-
|
|
90
|
-
allowed_seeds = authorized_fact_ids(
|
|
91
|
-
self._db,
|
|
92
|
-
seed_ids,
|
|
93
|
-
profile_id,
|
|
94
|
-
include_global=include_global,
|
|
95
|
-
include_shared=include_shared,
|
|
96
|
-
)
|
|
97
|
-
if any(seed_id not in allowed_seeds for seed_id in seed_ids):
|
|
98
|
-
return []
|
|
99
|
-
|
|
100
|
-
try:
|
|
101
|
-
visible_seed_facts = self._db.get_facts_by_ids(
|
|
102
|
-
seed_ids,
|
|
103
|
-
profile_id,
|
|
104
|
-
include_global=include_global,
|
|
105
|
-
include_shared=include_shared,
|
|
106
|
-
)
|
|
107
|
-
except Exception:
|
|
108
|
-
return []
|
|
109
|
-
seed_facts = {fact.fact_id: fact for fact in visible_seed_facts}
|
|
110
|
-
if any(seed_id not in seed_facts for seed_id in seed_ids):
|
|
111
|
-
return []
|
|
112
|
-
|
|
113
|
-
bridges: list[tuple[str, float]] = []
|
|
114
|
-
seen = set(seed_ids)
|
|
115
|
-
# v3.8.2: bound the per-entity get_facts_by_entity fan-out. On a dense
|
|
116
|
-
# entity graph (M5: 3.3k entities / 208k edges) a single recall could
|
|
117
|
-
# issue 200+ DB round-trips here — the primary 3.8 full-mode latency
|
|
118
|
-
# spike (observed 7.6s). Bridges are a SUPPLEMENTARY post-fusion boost
|
|
119
|
-
# (score x0.8, only added if not already found), so truncating them
|
|
120
|
-
# under a wall-clock budget is quality-safe: the ranked channels have
|
|
121
|
-
# already returned the core results.
|
|
122
|
-
deadline = time.monotonic() + time_budget_s
|
|
123
|
-
|
|
124
|
-
# Check consecutive pairs for entity overlap
|
|
125
|
-
for i in range(len(seed_ids) - 1):
|
|
126
|
-
if time.monotonic() > deadline:
|
|
127
|
-
break
|
|
128
|
-
fact_a = seed_facts.get(seed_ids[i])
|
|
129
|
-
fact_b = seed_facts.get(seed_ids[i + 1])
|
|
130
|
-
if not fact_a or not fact_b:
|
|
131
|
-
continue
|
|
132
|
-
|
|
133
|
-
entities_a = set(fact_a.canonical_entities)
|
|
134
|
-
entities_b = set(fact_b.canonical_entities)
|
|
135
|
-
|
|
136
|
-
# If they share entities, no bridge needed
|
|
137
|
-
if entities_a & entities_b:
|
|
138
|
-
continue
|
|
139
|
-
|
|
140
|
-
# Strategy 1: Entity bridge (union minus intersection)
|
|
141
|
-
bridge_entities = (entities_a | entities_b) - (entities_a & entities_b)
|
|
142
|
-
for eid in bridge_entities:
|
|
143
|
-
if time.monotonic() > deadline:
|
|
144
|
-
break
|
|
145
|
-
entity_facts = self._db.get_facts_by_entity(
|
|
146
|
-
eid,
|
|
147
|
-
profile_id,
|
|
148
|
-
include_global=include_global,
|
|
149
|
-
include_shared=include_shared,
|
|
150
|
-
)
|
|
151
|
-
for f in entity_facts[:5]:
|
|
152
|
-
if f.fact_id not in seen:
|
|
153
|
-
seen.add(f.fact_id)
|
|
154
|
-
overlap = (
|
|
155
|
-
len(set(f.canonical_entities) & entities_a)
|
|
156
|
-
+ len(set(f.canonical_entities) & entities_b)
|
|
157
|
-
)
|
|
158
|
-
bridges.append((f.fact_id, min(1.0, 0.5 + overlap * 0.15)))
|
|
159
|
-
|
|
160
|
-
if len(bridges) >= max_bridges:
|
|
161
|
-
break
|
|
162
|
-
|
|
163
|
-
bridges.sort(key=lambda x: (-x[1], x[0]))
|
|
164
|
-
return filter_authorized_results(
|
|
165
|
-
self._db,
|
|
166
|
-
bridges,
|
|
167
|
-
profile_id,
|
|
168
|
-
include_global=include_global,
|
|
169
|
-
include_shared=include_shared,
|
|
170
|
-
)[:max_bridges]
|
|
171
|
-
|
|
172
|
-
def spreading_activation(
|
|
173
|
-
self,
|
|
174
|
-
seed_ids: list[str],
|
|
175
|
-
profile_id: str,
|
|
176
|
-
max_depth: int = _MAX_DEPTH,
|
|
177
|
-
budget: int = _NODE_BUDGET,
|
|
178
|
-
*,
|
|
179
|
-
include_global: bool = False,
|
|
180
|
-
include_shared: bool = False,
|
|
181
|
-
) -> list[tuple[str, float]]:
|
|
182
|
-
"""Spreading activation from seed facts through the graph.
|
|
183
|
-
|
|
184
|
-
At each hop, activation decays by _DECAY and is modulated by
|
|
185
|
-
edge type via _TYPED_MU.
|
|
186
|
-
|
|
187
|
-
Args:
|
|
188
|
-
seed_ids: Starting fact IDs.
|
|
189
|
-
profile_id: Scope.
|
|
190
|
-
max_depth: Maximum hops.
|
|
191
|
-
budget: Maximum nodes to return.
|
|
192
|
-
|
|
193
|
-
Returns:
|
|
194
|
-
List of (fact_id, activation_score) for activated facts.
|
|
195
|
-
"""
|
|
196
|
-
allowed_seeds = authorized_fact_ids(
|
|
197
|
-
self._db,
|
|
198
|
-
seed_ids,
|
|
199
|
-
profile_id,
|
|
200
|
-
include_global=include_global,
|
|
201
|
-
include_shared=include_shared,
|
|
202
|
-
)
|
|
203
|
-
if any(seed_id not in allowed_seeds for seed_id in seed_ids):
|
|
204
|
-
return []
|
|
205
|
-
|
|
206
|
-
activations: dict[str, float] = {fid: 1.0 for fid in seed_ids}
|
|
207
|
-
frontier = list(seed_ids)
|
|
208
|
-
|
|
209
|
-
for depth in range(max_depth):
|
|
210
|
-
next_frontier: list[str] = []
|
|
211
|
-
for fid in frontier:
|
|
212
|
-
current_activation = activations.get(fid, 0.0)
|
|
213
|
-
if current_activation < 0.01:
|
|
214
|
-
continue
|
|
215
|
-
|
|
216
|
-
edges = self._db.get_edges_for_node(
|
|
217
|
-
fid,
|
|
218
|
-
profile_id,
|
|
219
|
-
include_global=include_global,
|
|
220
|
-
include_shared=include_shared,
|
|
221
|
-
)
|
|
222
|
-
for edge in edges:
|
|
223
|
-
other_id = (
|
|
224
|
-
edge.target_id
|
|
225
|
-
if edge.source_id == fid
|
|
226
|
-
else edge.source_id
|
|
227
|
-
)
|
|
228
|
-
mu = _TYPED_MU.get(edge.edge_type.value, 0.8)
|
|
229
|
-
propagated = current_activation * _DECAY * mu
|
|
230
|
-
|
|
231
|
-
if propagated > activations.get(other_id, 0.0):
|
|
232
|
-
activations[other_id] = propagated
|
|
233
|
-
if other_id not in seed_ids:
|
|
234
|
-
next_frontier.append(other_id)
|
|
235
|
-
|
|
236
|
-
frontier = next_frontier
|
|
237
|
-
if not frontier:
|
|
238
|
-
break
|
|
239
|
-
|
|
240
|
-
# Return non-seed nodes with activation
|
|
241
|
-
results = [
|
|
242
|
-
(fid, score)
|
|
243
|
-
for fid, score in activations.items()
|
|
244
|
-
if fid not in set(seed_ids) and score > 0.01
|
|
245
|
-
]
|
|
246
|
-
results.sort(key=lambda x: (-x[1], x[0]))
|
|
247
|
-
return filter_authorized_results(
|
|
248
|
-
self._db,
|
|
249
|
-
results,
|
|
250
|
-
profile_id,
|
|
251
|
-
include_global=include_global,
|
|
252
|
-
include_shared=include_shared,
|
|
253
|
-
)[:budget]
|