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,674 +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 — Cross-Encoder Reranker (Subprocess-Isolated).
|
|
6
|
-
|
|
7
|
-
V3.3.3: All PyTorch/ONNX model work runs in a SEPARATE subprocess.
|
|
8
|
-
The main process (dashboard, MCP, CLI) NEVER imports torch and stays
|
|
9
|
-
at ~60 MB. Same isolation pattern as EmbeddingService.
|
|
10
|
-
|
|
11
|
-
The worker subprocess auto-kills after 2 minutes idle.
|
|
12
|
-
|
|
13
|
-
Part of Qualixar | Author: Varun Pratap Bhardwaj
|
|
14
|
-
License: AGPL-3.0-or-later
|
|
15
|
-
"""
|
|
16
|
-
|
|
17
|
-
from __future__ import annotations
|
|
18
|
-
|
|
19
|
-
import atexit
|
|
20
|
-
import json
|
|
21
|
-
import logging
|
|
22
|
-
import os
|
|
23
|
-
import subprocess
|
|
24
|
-
import sys
|
|
25
|
-
import threading
|
|
26
|
-
import time
|
|
27
|
-
import weakref
|
|
28
|
-
from pathlib import Path
|
|
29
|
-
from typing import Any
|
|
30
|
-
|
|
31
|
-
from superlocalmemory.infra.data_root import state_path
|
|
32
|
-
from superlocalmemory.storage.models import AtomicFact
|
|
33
|
-
|
|
34
|
-
_RERANKER_PID_FILE = None # test-only override
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def _reranker_pid_file() -> Path:
|
|
38
|
-
return _RERANKER_PID_FILE or state_path(".reranker-worker.pid")
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
def _is_reranker_worker_alive() -> bool:
|
|
42
|
-
"""Check if a reranker worker PID is already alive (machine-wide singleton)."""
|
|
43
|
-
try:
|
|
44
|
-
pid_file = _reranker_pid_file()
|
|
45
|
-
if not pid_file.exists():
|
|
46
|
-
return False
|
|
47
|
-
pid = int(pid_file.read_text().strip())
|
|
48
|
-
os.kill(pid, 0)
|
|
49
|
-
return True
|
|
50
|
-
except (ValueError, OSError, ProcessLookupError):
|
|
51
|
-
_reranker_pid_file().unlink(missing_ok=True)
|
|
52
|
-
return False
|
|
53
|
-
|
|
54
|
-
# Track all live reranker instances for atexit cleanup
|
|
55
|
-
_live_rerankers: set[weakref.ref] = set()
|
|
56
|
-
|
|
57
|
-
logger = logging.getLogger(__name__)
|
|
58
|
-
|
|
59
|
-
_IDLE_TIMEOUT_SECONDS = 1800 # V3.8.1: keep interactive sessions warm.
|
|
60
|
-
# V3.3.12: Configurable via SLM_RERANKER_IDLE_TIMEOUT env var.
|
|
61
|
-
# Low-RAM installations can retain aggressive recycling through the override.
|
|
62
|
-
# Set ``SLM_RERANKER_IDLE_TIMEOUT=120`` + ``slm restart`` to revert.
|
|
63
|
-
_IDLE_TIMEOUT_SECONDS = int(os.environ.get("SLM_RERANKER_IDLE_TIMEOUT", _IDLE_TIMEOUT_SECONDS))
|
|
64
|
-
_SUBPROCESS_RESPONSE_TIMEOUT = 15 # v3.4.52: 15s (was 180s). Long timeout blocked the
|
|
65
|
-
# entire FastAPI event loop — a dead reranker subprocess held ALL
|
|
66
|
-
# endpoints hostage for 3 minutes. 15s is enough for ONNX inference
|
|
67
|
-
# cold start; if the worker can't respond, we fall back to fusion
|
|
68
|
-
# scores without reranking.
|
|
69
|
-
_WORKER_RECYCLE_AFTER = 500 # Recycle after N requests
|
|
70
|
-
|
|
71
|
-
# One-time model load is far heavier than a live rerank request: the child
|
|
72
|
-
# process imports torch / sentence-transformers and runs a warmup inference,
|
|
73
|
-
# which measured 9-16s on the reference machine. Sharing the 15s live-request
|
|
74
|
-
# timeout (``_SUBPROCESS_RESPONSE_TIMEOUT``) made the load a coin flip — logs
|
|
75
|
-
# showed ~half of daemon boots hitting "timed out after 15s", killing the
|
|
76
|
-
# worker, and leaving recall on FALLBACK scoring for the entire daemon
|
|
77
|
-
# lifetime (a silent quality regression, not a transient one). The load gets
|
|
78
|
-
# its own generous budget, and the background warmup RETRIES with backoff so a
|
|
79
|
-
# transient slow/failed load self-heals instead of permanently degrading
|
|
80
|
-
# recall quality. Live rerank requests keep the tight 15s cap so a recall
|
|
81
|
-
# never blocks on a sick subprocess.
|
|
82
|
-
_WARMUP_LOAD_TIMEOUT = int(os.environ.get("SLM_RERANKER_WARMUP_TIMEOUT", "90"))
|
|
83
|
-
_WARMUP_MAX_ATTEMPTS = int(os.environ.get("SLM_RERANKER_WARMUP_ATTEMPTS", "5"))
|
|
84
|
-
_WARMUP_RETRY_BACKOFF_S = float(os.environ.get("SLM_RERANKER_WARMUP_BACKOFF", "3"))
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
# Substrings that mark a load failure as a configuration problem rather than a
|
|
88
|
-
# transient one. Retrying these can never succeed, so the warmup aborts on the
|
|
89
|
-
# first occurrence instead of spending _WARMUP_MAX_ATTEMPTS × backoff on them.
|
|
90
|
-
_PERMANENT_LOAD_ERROR_MARKERS = (
|
|
91
|
-
"unknown backend",
|
|
92
|
-
"sentence-transformers is not installed",
|
|
93
|
-
)
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
def _is_permanent_load_error(error: str) -> bool:
|
|
97
|
-
"""True when a worker load error cannot be fixed by retrying."""
|
|
98
|
-
lowered = (error or "").lower()
|
|
99
|
-
return any(m in lowered for m in _PERMANENT_LOAD_ERROR_MARKERS)
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
class CrossEncoderReranker:
|
|
103
|
-
"""Rerank candidate facts using a local cross-encoder model.
|
|
104
|
-
|
|
105
|
-
V3.3.3: SUBPROCESS-ISOLATED. The main process never imports
|
|
106
|
-
sentence_transformers or torch. All model work runs in a child
|
|
107
|
-
process via JSON over stdin/stdout.
|
|
108
|
-
|
|
109
|
-
Non-blocking first-use: triggers background worker spawn, returns
|
|
110
|
-
fallback scores until worker is ready.
|
|
111
|
-
|
|
112
|
-
Args:
|
|
113
|
-
model_name: HuggingFace cross-encoder model identifier.
|
|
114
|
-
backend: Inference backend. "onnx" for ONNX Runtime (light),
|
|
115
|
-
"" for PyTorch (heavy). Default: "onnx".
|
|
116
|
-
"""
|
|
117
|
-
|
|
118
|
-
def __init__(
|
|
119
|
-
self,
|
|
120
|
-
model_name: str = "cross-encoder/ms-marco-MiniLM-L-12-v2",
|
|
121
|
-
backend: str = "onnx",
|
|
122
|
-
) -> None:
|
|
123
|
-
self._model_name = model_name
|
|
124
|
-
self._backend = backend
|
|
125
|
-
self._worker_proc: subprocess.Popen | None = None
|
|
126
|
-
self._model_loaded = False # True once worker confirms model is ready
|
|
127
|
-
self._worker_loading = False # True while background warmup in progress
|
|
128
|
-
self._lock = threading.Lock()
|
|
129
|
-
self._shutdown_event = threading.Event()
|
|
130
|
-
self._warmup_thread: threading.Thread | None = None
|
|
131
|
-
self._idle_timer: threading.Timer | None = None
|
|
132
|
-
self._request_count: int = 0
|
|
133
|
-
|
|
134
|
-
# Register for atexit cleanup (prevent orphaned workers)
|
|
135
|
-
ref = weakref.ref(self, _live_rerankers.discard)
|
|
136
|
-
_live_rerankers.add(ref)
|
|
137
|
-
|
|
138
|
-
# Start background warmup immediately — worker loads model
|
|
139
|
-
# while the rest of init continues. First recall gets instant
|
|
140
|
-
# fallback; second recall uses the warm model.
|
|
141
|
-
self._start_background_warmup()
|
|
142
|
-
|
|
143
|
-
def __del__(self) -> None:
|
|
144
|
-
"""Kill worker subprocess when reranker is garbage-collected."""
|
|
145
|
-
try:
|
|
146
|
-
self.shutdown(timeout=0.1)
|
|
147
|
-
except Exception:
|
|
148
|
-
pass
|
|
149
|
-
|
|
150
|
-
# ------------------------------------------------------------------
|
|
151
|
-
# Background warmup (non-blocking model load)
|
|
152
|
-
# ------------------------------------------------------------------
|
|
153
|
-
|
|
154
|
-
def _start_background_warmup(self) -> None:
|
|
155
|
-
"""Start worker and load model in background thread.
|
|
156
|
-
|
|
157
|
-
V3.3.16: Uses _send_request (lock-protected) instead of raw
|
|
158
|
-
stdin/stdout access. Previous code wrote to stdin without the
|
|
159
|
-
lock, creating a race where the warmup's readline thread could
|
|
160
|
-
steal responses meant for _send_request → deadlock → timeout.
|
|
161
|
-
"""
|
|
162
|
-
if self._shutdown_event.is_set() or self._worker_loading or self._model_loaded:
|
|
163
|
-
return
|
|
164
|
-
self._worker_loading = True
|
|
165
|
-
|
|
166
|
-
def _warmup() -> None:
|
|
167
|
-
try:
|
|
168
|
-
for attempt in range(1, _WARMUP_MAX_ATTEMPTS + 1):
|
|
169
|
-
if self._shutdown_event.is_set() or self._model_loaded:
|
|
170
|
-
return
|
|
171
|
-
try:
|
|
172
|
-
self._ensure_worker()
|
|
173
|
-
except Exception as exc:
|
|
174
|
-
logger.warning(
|
|
175
|
-
"Reranker warmup attempt %d/%d: worker spawn "
|
|
176
|
-
"raised: %s", attempt, _WARMUP_MAX_ATTEMPTS, exc,
|
|
177
|
-
)
|
|
178
|
-
self._worker_proc = None
|
|
179
|
-
|
|
180
|
-
if self._worker_proc is None:
|
|
181
|
-
# Either the spawn failed, or another process already
|
|
182
|
-
# owns the machine-wide singleton worker. If a sibling
|
|
183
|
-
# worker is alive this instance will use it on demand —
|
|
184
|
-
# stop retrying quietly rather than spinning.
|
|
185
|
-
if _is_reranker_worker_alive():
|
|
186
|
-
logger.debug(
|
|
187
|
-
"Reranker warmup: worker owned by another "
|
|
188
|
-
"process; this instance uses it on demand",
|
|
189
|
-
)
|
|
190
|
-
return
|
|
191
|
-
else:
|
|
192
|
-
# Give the ONE-TIME model load a generous budget — it is
|
|
193
|
-
# far heavier than a live rerank request. On timeout
|
|
194
|
-
# _send_request kills the worker, so the next attempt
|
|
195
|
-
# respawns cleanly (no stale-response race).
|
|
196
|
-
resp = None
|
|
197
|
-
try:
|
|
198
|
-
resp = self._send_request({
|
|
199
|
-
"cmd": "load",
|
|
200
|
-
"model_name": self._model_name,
|
|
201
|
-
"backend": self._backend,
|
|
202
|
-
}, timeout=_WARMUP_LOAD_TIMEOUT)
|
|
203
|
-
except Exception as exc:
|
|
204
|
-
logger.warning(
|
|
205
|
-
"Reranker warmup attempt %d/%d: load request "
|
|
206
|
-
"raised: %s",
|
|
207
|
-
attempt, _WARMUP_MAX_ATTEMPTS, exc,
|
|
208
|
-
)
|
|
209
|
-
if resp and resp.get("ok"):
|
|
210
|
-
self._model_loaded = True
|
|
211
|
-
logger.info(
|
|
212
|
-
"Reranker worker warm (attempt %d/%d, "
|
|
213
|
-
"backend=%s, warmup_inference=%s)",
|
|
214
|
-
attempt, _WARMUP_MAX_ATTEMPTS,
|
|
215
|
-
resp.get("backend", "?"),
|
|
216
|
-
resp.get("warmup_inference", False),
|
|
217
|
-
)
|
|
218
|
-
return
|
|
219
|
-
# v3.8.11 (issue #103): this used to report
|
|
220
|
-
# "(timeout=90s)" for EVERY failure, including loads
|
|
221
|
-
# that failed instantly. A user whose retries were 3s
|
|
222
|
-
# apart was told each one timed out after 90s, and the
|
|
223
|
-
# worker's actual error was never printed at all.
|
|
224
|
-
# Distinguish the two cases and surface the real cause.
|
|
225
|
-
if resp is None:
|
|
226
|
-
logger.warning(
|
|
227
|
-
"Reranker warmup attempt %d/%d: no response "
|
|
228
|
-
"from worker within %ds; retrying",
|
|
229
|
-
attempt, _WARMUP_MAX_ATTEMPTS,
|
|
230
|
-
_WARMUP_LOAD_TIMEOUT,
|
|
231
|
-
)
|
|
232
|
-
else:
|
|
233
|
-
load_error = (
|
|
234
|
-
resp.get("error")
|
|
235
|
-
or "worker reported not-ready without an error"
|
|
236
|
-
)
|
|
237
|
-
# A misconfiguration cannot fix itself. Retrying a
|
|
238
|
-
# bad backend name or a missing dependency four
|
|
239
|
-
# more times burns ~7.5 minutes of daemon startup
|
|
240
|
-
# to reach the same answer (issue #103). Fail fast
|
|
241
|
-
# and say exactly what to change.
|
|
242
|
-
if _is_permanent_load_error(load_error):
|
|
243
|
-
logger.error(
|
|
244
|
-
"Reranker disabled — configuration error: "
|
|
245
|
-
"%s. Not retrying. Fix the config or set "
|
|
246
|
-
"retrieval.use_cross_encoder=false; recall "
|
|
247
|
-
"continues with fusion scores.",
|
|
248
|
-
load_error,
|
|
249
|
-
)
|
|
250
|
-
return
|
|
251
|
-
logger.warning(
|
|
252
|
-
"Reranker warmup attempt %d/%d failed: %s; "
|
|
253
|
-
"retrying",
|
|
254
|
-
attempt, _WARMUP_MAX_ATTEMPTS, load_error,
|
|
255
|
-
)
|
|
256
|
-
|
|
257
|
-
if attempt < _WARMUP_MAX_ATTEMPTS and not self._model_loaded:
|
|
258
|
-
if self._shutdown_event.wait(
|
|
259
|
-
min(_WARMUP_RETRY_BACKOFF_S * attempt, 15.0),
|
|
260
|
-
):
|
|
261
|
-
return
|
|
262
|
-
|
|
263
|
-
if not self._model_loaded:
|
|
264
|
-
logger.warning(
|
|
265
|
-
"Reranker warmup exhausted %d attempts; recall uses "
|
|
266
|
-
"fallback scoring until the next rerank triggers a "
|
|
267
|
-
"fresh load. Run 'slm doctor' for diagnostics.",
|
|
268
|
-
_WARMUP_MAX_ATTEMPTS,
|
|
269
|
-
)
|
|
270
|
-
except Exception as exc:
|
|
271
|
-
logger.debug("Background reranker warmup failed: %s", exc)
|
|
272
|
-
finally:
|
|
273
|
-
self._worker_loading = False
|
|
274
|
-
|
|
275
|
-
self._warmup_thread = threading.Thread(target=_warmup, daemon=True, name="ce-warmup")
|
|
276
|
-
self._warmup_thread.start()
|
|
277
|
-
|
|
278
|
-
def warmup_sync(self, timeout: float = 120.0) -> bool:
|
|
279
|
-
"""Block until reranker model is loaded. Returns True if ready.
|
|
280
|
-
|
|
281
|
-
V3.3.12: Critical for benchmarks and first-recall quality.
|
|
282
|
-
Without this, first 30-60s of recalls get no reranking (-30.7pp).
|
|
283
|
-
"""
|
|
284
|
-
if self._model_loaded:
|
|
285
|
-
return True
|
|
286
|
-
if (
|
|
287
|
-
not self._shutdown_event.is_set()
|
|
288
|
-
and not self._worker_loading
|
|
289
|
-
and not self._model_loaded
|
|
290
|
-
):
|
|
291
|
-
self._start_background_warmup()
|
|
292
|
-
t = getattr(self, '_warmup_thread', None)
|
|
293
|
-
if t is not None:
|
|
294
|
-
t.join(timeout=timeout)
|
|
295
|
-
return self._model_loaded
|
|
296
|
-
|
|
297
|
-
# ------------------------------------------------------------------
|
|
298
|
-
# Worker management (mirrors EmbeddingService pattern)
|
|
299
|
-
# ------------------------------------------------------------------
|
|
300
|
-
|
|
301
|
-
def _ensure_worker(self) -> None:
|
|
302
|
-
"""Spawn worker subprocess if not running. Machine-wide singleton.
|
|
303
|
-
|
|
304
|
-
v3.4.13: Checks PID file before spawning — only ONE reranker worker
|
|
305
|
-
can exist at a time on the machine.
|
|
306
|
-
"""
|
|
307
|
-
if self._shutdown_event.is_set():
|
|
308
|
-
return
|
|
309
|
-
if self._worker_proc is not None and self._worker_proc.poll() is None:
|
|
310
|
-
return
|
|
311
|
-
self._worker_proc = None
|
|
312
|
-
self._worker_ready = False
|
|
313
|
-
|
|
314
|
-
# v3.4.13: Machine-wide singleton guard
|
|
315
|
-
if _is_reranker_worker_alive():
|
|
316
|
-
logger.debug("Reranker worker already alive (PID file), skipping spawn")
|
|
317
|
-
return
|
|
318
|
-
|
|
319
|
-
worker_module = "superlocalmemory.core.reranker_worker"
|
|
320
|
-
try:
|
|
321
|
-
env = {
|
|
322
|
-
**os.environ,
|
|
323
|
-
"CUDA_VISIBLE_DEVICES": "",
|
|
324
|
-
"PYTORCH_MPS_HIGH_WATERMARK_RATIO": "0.0",
|
|
325
|
-
"PYTORCH_MPS_MEM_LIMIT": "0",
|
|
326
|
-
"PYTORCH_ENABLE_MPS_FALLBACK": "1",
|
|
327
|
-
"TOKENIZERS_PARALLELISM": "false",
|
|
328
|
-
"TORCH_DEVICE": "cpu",
|
|
329
|
-
"ORT_DISABLE_COREML": "1",
|
|
330
|
-
# Restore parallel OpenMP. The package caps OMP_NUM_THREADS
|
|
331
|
-
# globally to avoid a torch+lightgbm libomp SIGSEGV in the
|
|
332
|
-
# main process. This worker loads torch but never lightgbm,
|
|
333
|
-
# so there is no collision risk and full parallelism is safe.
|
|
334
|
-
"OMP_NUM_THREADS": str(os.cpu_count() or 4),
|
|
335
|
-
}
|
|
336
|
-
from superlocalmemory.core.platform_utils import popen_platform_kwargs
|
|
337
|
-
self._worker_proc = subprocess.Popen(
|
|
338
|
-
[sys.executable, "-m", worker_module],
|
|
339
|
-
stdin=subprocess.PIPE,
|
|
340
|
-
stdout=subprocess.PIPE,
|
|
341
|
-
stderr=subprocess.DEVNULL,
|
|
342
|
-
text=True,
|
|
343
|
-
bufsize=1,
|
|
344
|
-
env=env,
|
|
345
|
-
**popen_platform_kwargs(),
|
|
346
|
-
)
|
|
347
|
-
# v3.4.13: Register PID for machine-wide singleton
|
|
348
|
-
pid_file = _reranker_pid_file()
|
|
349
|
-
pid_file.parent.mkdir(parents=True, exist_ok=True)
|
|
350
|
-
pid_file.write_text(str(self._worker_proc.pid))
|
|
351
|
-
logger.info(
|
|
352
|
-
"Reranker worker spawned (PID %d)", self._worker_proc.pid,
|
|
353
|
-
)
|
|
354
|
-
# v3.4.51: Detect immediate subprocess crash (e.g. ONNX segfault on
|
|
355
|
-
# Python 3.14 before official ONNX Runtime support). Poll after 1s;
|
|
356
|
-
# if the process already exited, disable reranking rather than
|
|
357
|
-
# letting the broken worker linger and corrupt scores.
|
|
358
|
-
time.sleep(1.0)
|
|
359
|
-
if self._worker_proc.poll() is not None:
|
|
360
|
-
rc = self._worker_proc.returncode
|
|
361
|
-
logger.warning(
|
|
362
|
-
"Reranker worker exited immediately (returncode=%d). "
|
|
363
|
-
"ONNX Runtime may be unsupported on this Python version (%s). "
|
|
364
|
-
"Reranking disabled — recall will use fusion scores only.",
|
|
365
|
-
rc, sys.version,
|
|
366
|
-
)
|
|
367
|
-
self._worker_proc = None
|
|
368
|
-
return
|
|
369
|
-
self._worker_ready = True
|
|
370
|
-
except Exception as exc:
|
|
371
|
-
logger.warning("Failed to spawn reranker worker: %s", exc)
|
|
372
|
-
self._worker_proc = None
|
|
373
|
-
|
|
374
|
-
def _send_request(self, req: dict, timeout: float | None = None,
|
|
375
|
-
block: bool = True) -> dict | None:
|
|
376
|
-
"""Send JSON request to worker, get response. Thread-safe.
|
|
377
|
-
|
|
378
|
-
Uses a short timeout (10s) for rerank requests since the model
|
|
379
|
-
should already be loaded by the background warmup. Uses the full
|
|
380
|
-
timeout only for explicit load/ping commands.
|
|
381
|
-
|
|
382
|
-
v3.4.52: when ``block=False``, uses ``try_lock`` instead of
|
|
383
|
-
``lock.acquire()``. If another thread is already using the
|
|
384
|
-
reranker subprocess, returns ``None`` immediately (the caller
|
|
385
|
-
falls back to fusion scores without reranking). This prevents
|
|
386
|
-
concurrent recall requests from serialising on the lock.
|
|
387
|
-
"""
|
|
388
|
-
if self._shutdown_event.is_set():
|
|
389
|
-
return None
|
|
390
|
-
effective_timeout = timeout or _SUBPROCESS_RESPONSE_TIMEOUT
|
|
391
|
-
|
|
392
|
-
acquired = self._lock.acquire(blocking=block)
|
|
393
|
-
if not acquired:
|
|
394
|
-
return None # another request is using the subprocess
|
|
395
|
-
try:
|
|
396
|
-
if self._request_count >= _WORKER_RECYCLE_AFTER and self._worker_proc is not None:
|
|
397
|
-
logger.info("Recycling reranker worker after %d requests", self._request_count)
|
|
398
|
-
self._kill_worker()
|
|
399
|
-
self._model_loaded = False
|
|
400
|
-
self._request_count = 0
|
|
401
|
-
|
|
402
|
-
# Ensure worker is alive (re-spawn if crashed)
|
|
403
|
-
if self._worker_proc is None or self._worker_proc.poll() is not None:
|
|
404
|
-
self._ensure_worker()
|
|
405
|
-
if self._worker_proc is None:
|
|
406
|
-
return None
|
|
407
|
-
|
|
408
|
-
msg = json.dumps(req) + "\n"
|
|
409
|
-
self._worker_proc.stdin.write(msg)
|
|
410
|
-
self._worker_proc.stdin.flush()
|
|
411
|
-
|
|
412
|
-
resp_line = self._readline_with_timeout(
|
|
413
|
-
self._worker_proc.stdout,
|
|
414
|
-
effective_timeout,
|
|
415
|
-
)
|
|
416
|
-
if not resp_line:
|
|
417
|
-
logger.warning("Reranker worker timed out after %ds", effective_timeout)
|
|
418
|
-
self._kill_worker()
|
|
419
|
-
self._model_loaded = False
|
|
420
|
-
return None
|
|
421
|
-
|
|
422
|
-
resp = json.loads(resp_line)
|
|
423
|
-
self._reset_idle_timer()
|
|
424
|
-
self._request_count += 1
|
|
425
|
-
return resp
|
|
426
|
-
except (BrokenPipeError, OSError, json.JSONDecodeError) as exc:
|
|
427
|
-
logger.warning("Reranker worker communication failed: %s", exc)
|
|
428
|
-
self._kill_worker()
|
|
429
|
-
self._model_loaded = False
|
|
430
|
-
return None
|
|
431
|
-
finally:
|
|
432
|
-
self._lock.release()
|
|
433
|
-
|
|
434
|
-
@staticmethod
|
|
435
|
-
def _readline_with_timeout(stream: Any, timeout_seconds: float) -> str:
|
|
436
|
-
"""Read a line from stream with timeout. Returns '' on timeout.
|
|
437
|
-
|
|
438
|
-
Prefer a deadline-driven selector poll of the stream's file descriptor
|
|
439
|
-
(POSIX pipes). That path never spawns a helper thread, so a hung
|
|
440
|
-
worker cannot leak reader threads or pin the pipe FD across timeouts.
|
|
441
|
-
A thread fallback remains only for streams without a usable fileno
|
|
442
|
-
(unit-test mocks) and for Windows, where selectors cannot wait on
|
|
443
|
-
pipes.
|
|
444
|
-
"""
|
|
445
|
-
import selectors
|
|
446
|
-
|
|
447
|
-
timeout_seconds = max(0.0, float(timeout_seconds))
|
|
448
|
-
fd: int | None
|
|
449
|
-
try:
|
|
450
|
-
raw_fd = stream.fileno()
|
|
451
|
-
fd = raw_fd if isinstance(raw_fd, int) else None
|
|
452
|
-
except (AttributeError, OSError, ValueError, TypeError):
|
|
453
|
-
fd = None
|
|
454
|
-
|
|
455
|
-
# Windows select()/selectors only accept sockets, not subprocess pipes.
|
|
456
|
-
if fd is not None and sys.platform != "win32":
|
|
457
|
-
try:
|
|
458
|
-
with selectors.DefaultSelector() as sel:
|
|
459
|
-
sel.register(fd, selectors.EVENT_READ)
|
|
460
|
-
events = sel.select(timeout=timeout_seconds)
|
|
461
|
-
if not events:
|
|
462
|
-
return ""
|
|
463
|
-
line = stream.readline()
|
|
464
|
-
return line if line else ""
|
|
465
|
-
except (OSError, ValueError):
|
|
466
|
-
return ""
|
|
467
|
-
|
|
468
|
-
result_container: list[str] = []
|
|
469
|
-
error_container: list[Exception] = []
|
|
470
|
-
|
|
471
|
-
def _read() -> None:
|
|
472
|
-
try:
|
|
473
|
-
result_container.append(stream.readline())
|
|
474
|
-
except Exception as exc:
|
|
475
|
-
error_container.append(exc)
|
|
476
|
-
|
|
477
|
-
reader = threading.Thread(target=_read, daemon=True)
|
|
478
|
-
reader.start()
|
|
479
|
-
reader.join(timeout=timeout_seconds)
|
|
480
|
-
|
|
481
|
-
if reader.is_alive():
|
|
482
|
-
return ""
|
|
483
|
-
if error_container:
|
|
484
|
-
raise error_container[0]
|
|
485
|
-
return result_container[0] if result_container else ""
|
|
486
|
-
|
|
487
|
-
def _kill_worker(self, timeout: float = 3.0) -> None:
|
|
488
|
-
"""Terminate the worker and close every owned pipe exactly once."""
|
|
489
|
-
if self._idle_timer is not None:
|
|
490
|
-
self._idle_timer.cancel()
|
|
491
|
-
self._idle_timer = None
|
|
492
|
-
|
|
493
|
-
proc = self._worker_proc
|
|
494
|
-
if proc is not None:
|
|
495
|
-
# Detach first so re-entrant/finalizer cleanup is idempotent.
|
|
496
|
-
self._worker_proc = None
|
|
497
|
-
self._worker_ready = False
|
|
498
|
-
# Invariant: a dead worker has no loaded model. Enforcing this in
|
|
499
|
-
# ONE place (not just the recycle/timeout callers) means the idle
|
|
500
|
-
# timer's kill also clears the flag, so the recall path sees the
|
|
501
|
-
# gap and triggers a background re-warmup instead of sending a
|
|
502
|
-
# rerank to a cold worker and risking a 15s-timeout churn.
|
|
503
|
-
self._model_loaded = False
|
|
504
|
-
try:
|
|
505
|
-
proc.stdin.write('{"cmd":"quit"}\n')
|
|
506
|
-
proc.stdin.flush()
|
|
507
|
-
proc.wait(timeout=max(0.0, timeout))
|
|
508
|
-
except Exception:
|
|
509
|
-
try:
|
|
510
|
-
returncode = proc.poll()
|
|
511
|
-
except Exception:
|
|
512
|
-
returncode = None
|
|
513
|
-
if returncode is None or not isinstance(returncode, int):
|
|
514
|
-
try:
|
|
515
|
-
proc.kill()
|
|
516
|
-
proc.wait(timeout=max(0.0, timeout))
|
|
517
|
-
except Exception:
|
|
518
|
-
pass
|
|
519
|
-
finally:
|
|
520
|
-
# Explicit close prevents TextIOWrapper from flushing a dead
|
|
521
|
-
# child's stdin later from an unraisable object finalizer.
|
|
522
|
-
for stream_name in ("stdin", "stdout", "stderr"):
|
|
523
|
-
stream = getattr(proc, stream_name, None)
|
|
524
|
-
if stream is not None:
|
|
525
|
-
try:
|
|
526
|
-
stream.close()
|
|
527
|
-
except (BrokenPipeError, OSError, ValueError):
|
|
528
|
-
pass
|
|
529
|
-
|
|
530
|
-
def _reset_idle_timer(self) -> None:
|
|
531
|
-
"""Reset idle timer — kills worker after 2 min inactivity."""
|
|
532
|
-
if self._shutdown_event.is_set():
|
|
533
|
-
return
|
|
534
|
-
if self._idle_timer is not None:
|
|
535
|
-
self._idle_timer.cancel()
|
|
536
|
-
self._idle_timer = threading.Timer(
|
|
537
|
-
_IDLE_TIMEOUT_SECONDS, self.unload,
|
|
538
|
-
)
|
|
539
|
-
self._idle_timer.daemon = True
|
|
540
|
-
self._idle_timer.start()
|
|
541
|
-
|
|
542
|
-
def unload(self) -> None:
|
|
543
|
-
"""Kill the worker subprocess to free all memory."""
|
|
544
|
-
with self._lock:
|
|
545
|
-
self._kill_worker()
|
|
546
|
-
logger.info("CrossEncoderReranker: worker killed (idle timeout)")
|
|
547
|
-
|
|
548
|
-
def shutdown(self, timeout: float = 3.0) -> None:
|
|
549
|
-
"""Cancel warmup, terminate the child, and join owned background work."""
|
|
550
|
-
shutdown_event = getattr(self, "_shutdown_event", None)
|
|
551
|
-
if shutdown_event is not None:
|
|
552
|
-
shutdown_event.set()
|
|
553
|
-
self._kill_worker(timeout=min(max(0.0, timeout), 1.0))
|
|
554
|
-
warmup_thread = getattr(self, "_warmup_thread", None)
|
|
555
|
-
if warmup_thread is not None and warmup_thread is not threading.current_thread():
|
|
556
|
-
warmup_thread.join(timeout=timeout)
|
|
557
|
-
|
|
558
|
-
# ------------------------------------------------------------------
|
|
559
|
-
# Public API
|
|
560
|
-
# ------------------------------------------------------------------
|
|
561
|
-
|
|
562
|
-
def rerank(
|
|
563
|
-
self,
|
|
564
|
-
query: str,
|
|
565
|
-
candidates: list[tuple[AtomicFact, float]],
|
|
566
|
-
top_k: int = 10,
|
|
567
|
-
) -> list[tuple[AtomicFact, float]]:
|
|
568
|
-
"""Rerank candidates by cross-encoder relevance.
|
|
569
|
-
|
|
570
|
-
NON-BLOCKING: If the worker is still loading the model
|
|
571
|
-
(background warmup), returns candidates by existing score
|
|
572
|
-
immediately. Once the worker is warm, subsequent calls use
|
|
573
|
-
the cross-encoder. This means CLI first-call gets instant
|
|
574
|
-
results (without reranking), and MCP gets reranked results
|
|
575
|
-
(worker stays warm between calls).
|
|
576
|
-
"""
|
|
577
|
-
results, _, _ = self.rerank_with_status(query, candidates, top_k=top_k)
|
|
578
|
-
return results
|
|
579
|
-
|
|
580
|
-
def rerank_with_status(
|
|
581
|
-
self,
|
|
582
|
-
query: str,
|
|
583
|
-
candidates: list[tuple[AtomicFact, float]],
|
|
584
|
-
top_k: int = 10,
|
|
585
|
-
) -> tuple[list[tuple[AtomicFact, float]], bool, str]:
|
|
586
|
-
"""Return results plus whether cross-encoder inference actually ran."""
|
|
587
|
-
if not candidates:
|
|
588
|
-
return [], False, "no_candidates"
|
|
589
|
-
|
|
590
|
-
# Non-blocking: if the model isn't loaded, return fallback AND kick a
|
|
591
|
-
# background (re)warmup so the reranker SELF-HEALS. Without this, a
|
|
592
|
-
# worker that was recycled (every 500 reqs), idle-killed (30 min), or
|
|
593
|
-
# crashed left ``_model_loaded`` False with nothing to reload it — every
|
|
594
|
-
# subsequent recall degraded to fallback scoring until the daemon was
|
|
595
|
-
# restarted (a silent, sustained quality regression). The warmup is
|
|
596
|
-
# guarded (no-op if already loading/loaded), retried, and never blocks
|
|
597
|
-
# this recall — it returns fallback now and full quality resumes within
|
|
598
|
-
# seconds once the model is warm again.
|
|
599
|
-
if not self._model_loaded:
|
|
600
|
-
if not self._shutdown_event.is_set() and not self._worker_loading:
|
|
601
|
-
self._start_background_warmup()
|
|
602
|
-
sorted_cands = sorted(candidates, key=lambda x: (-x[1], x[0].fact_id))
|
|
603
|
-
return sorted_cands[:top_k], False, "fallback_not_ready"
|
|
604
|
-
|
|
605
|
-
documents = [fact.content for fact, _ in candidates]
|
|
606
|
-
|
|
607
|
-
# v3.4.53: block=False — if another recall is using the reranker
|
|
608
|
-
# subprocess, skip reranking and return fusion scores directly.
|
|
609
|
-
# This prevents concurrent recalls from serialising on the lock.
|
|
610
|
-
# 15s timeout (was 180s) — warm ONNX inference takes ~100ms; if
|
|
611
|
-
# the worker can't respond in 15s it's dead and we fall back.
|
|
612
|
-
resp = self._send_request({
|
|
613
|
-
"cmd": "rerank",
|
|
614
|
-
"query": query,
|
|
615
|
-
"documents": documents,
|
|
616
|
-
}, timeout=15.0, block=False)
|
|
617
|
-
|
|
618
|
-
if resp is None or not resp.get("ok"):
|
|
619
|
-
# Fallback: return by existing score
|
|
620
|
-
sorted_cands = sorted(candidates, key=lambda x: (-x[1], x[0].fact_id))
|
|
621
|
-
return sorted_cands[:top_k], False, "fallback_busy_or_unavailable"
|
|
622
|
-
|
|
623
|
-
scores = resp["scores"]
|
|
624
|
-
scored: list[tuple[AtomicFact, float]] = [
|
|
625
|
-
(fact, float(score))
|
|
626
|
-
for (fact, _), score in zip(candidates, scores)
|
|
627
|
-
]
|
|
628
|
-
scored.sort(key=lambda x: (-x[1], x[0].fact_id))
|
|
629
|
-
return scored[:top_k], True, "applied"
|
|
630
|
-
|
|
631
|
-
def score_pair(self, query: str, document: str) -> float:
|
|
632
|
-
"""Score a single (query, document) pair."""
|
|
633
|
-
resp = self._send_request({
|
|
634
|
-
"cmd": "score",
|
|
635
|
-
"query": query,
|
|
636
|
-
"document": document,
|
|
637
|
-
"model_name": self._model_name,
|
|
638
|
-
"backend": self._backend,
|
|
639
|
-
})
|
|
640
|
-
|
|
641
|
-
if resp is None or not resp.get("ok"):
|
|
642
|
-
return 0.0
|
|
643
|
-
return float(resp.get("score", 0.0))
|
|
644
|
-
|
|
645
|
-
@property
|
|
646
|
-
def is_available(self) -> bool:
|
|
647
|
-
"""Whether the cross-encoder worker can be spawned."""
|
|
648
|
-
resp = self._send_request({"cmd": "ping"})
|
|
649
|
-
if resp is None:
|
|
650
|
-
return False
|
|
651
|
-
return resp.get("ok", False)
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
# ---------------------------------------------------------------------------
|
|
655
|
-
# Module-level atexit: kill ALL reranker workers on process exit
|
|
656
|
-
# ---------------------------------------------------------------------------
|
|
657
|
-
|
|
658
|
-
def _cleanup_all_rerankers() -> None:
|
|
659
|
-
"""Kill all reranker worker subprocesses on interpreter exit.
|
|
660
|
-
|
|
661
|
-
Prevents orphaned 1.3 GB ONNX/PyTorch workers surviving after
|
|
662
|
-
parent exits (especially during test runs with parallel agents).
|
|
663
|
-
"""
|
|
664
|
-
for ref in list(_live_rerankers):
|
|
665
|
-
reranker = ref()
|
|
666
|
-
if reranker is not None:
|
|
667
|
-
try:
|
|
668
|
-
reranker.shutdown()
|
|
669
|
-
except Exception:
|
|
670
|
-
pass
|
|
671
|
-
_live_rerankers.clear()
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
atexit.register(_cleanup_all_rerankers)
|