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,758 +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 — Remote (OpenAI-compatible) cross-encoder reranker.
|
|
6
|
-
|
|
7
|
-
v3.8.12 (issue #105). The mirror image of the remote EMBEDDING endpoint that
|
|
8
|
-
shipped in v3.4.24 (issue #16): when ``retrieval.cross_encoder_backend`` is
|
|
9
|
-
``"openai"`` (or ``"remote"``) and ``retrieval.cross_encoder_endpoint`` is set,
|
|
10
|
-
reranking is an HTTP POST to that endpoint instead of a local subprocess.
|
|
11
|
-
|
|
12
|
-
WHY THIS EXISTS
|
|
13
|
-
The bundled cross-encoder, ``cross-encoder/ms-marco-MiniLM-L-12-v2``, is
|
|
14
|
-
English-only. A Chinese, Japanese, or Arabic corpus was being scored by a
|
|
15
|
-
model that cannot read it — a silent relevance regression with no error to
|
|
16
|
-
look at. Bringing your own multilingual reranker (bge-reranker-v2-m3, a
|
|
17
|
-
Qwen reranker, …) is the same escape hatch embeddings already had.
|
|
18
|
-
|
|
19
|
-
WHY IT LIVES IN THE PARENT PROCESS
|
|
20
|
-
``CrossEncoderReranker`` spawns a subprocess to keep torch/ONNX out of the
|
|
21
|
-
parent. The remote path imports neither, so a subprocess would buy nothing
|
|
22
|
-
and cost a fork, a PID-file singleton, a warmup handshake, and the JSON
|
|
23
|
-
pipe. Issue #103's reporter hit exactly that: a machine-wide worker
|
|
24
|
-
singleton blocking a reranker that was never local to begin with. The
|
|
25
|
-
remote path never spawns, never touches the PID file, and never warms up a
|
|
26
|
-
model. This also mirrors the embedding side, where the OpenAI-compatible
|
|
27
|
-
call lives in ``core/embeddings.py`` (parent), not ``embedding_worker.py``.
|
|
28
|
-
|
|
29
|
-
WIRE PROTOCOL (Cohere-shaped ``/v1/rerank``; llama-server, TEI, Infinity, …)
|
|
30
|
-
Request : {"model": "...", "query": "...", "documents": ["...", ...]}
|
|
31
|
-
Response: {"results": [{"index": 0, "relevance_score": -5.94}, ...]}
|
|
32
|
-
|
|
33
|
-
Bare-list responses (``[{"index": 0, "score": 0.9}, ...]``) are accepted
|
|
34
|
-
too. Anything else is REJECTED with a precise error rather than coerced
|
|
35
|
-
into plausible-looking scores — issue #103 was a lesson in what silent
|
|
36
|
-
degradation costs.
|
|
37
|
-
|
|
38
|
-
FAILURE POLICY
|
|
39
|
-
An unreachable, slow, or malformed endpoint degrades to fusion-score
|
|
40
|
-
ordering and logs an error. It does NOT fall back to the local
|
|
41
|
-
cross-encoder: a user who configured a multilingual reranker asked for it
|
|
42
|
-
precisely because the local English model is wrong for their corpus, and
|
|
43
|
-
quietly substituting it would recreate the bug this feature fixes.
|
|
44
|
-
|
|
45
|
-
Part of Qualixar | Author: Varun Pratap Bhardwaj
|
|
46
|
-
"""
|
|
47
|
-
|
|
48
|
-
from __future__ import annotations
|
|
49
|
-
|
|
50
|
-
import json
|
|
51
|
-
import ipaddress
|
|
52
|
-
import logging
|
|
53
|
-
import math
|
|
54
|
-
import os
|
|
55
|
-
import threading
|
|
56
|
-
import time
|
|
57
|
-
from typing import Any
|
|
58
|
-
from urllib.parse import urlparse, urlunparse
|
|
59
|
-
|
|
60
|
-
from superlocalmemory.storage.models import AtomicFact
|
|
61
|
-
|
|
62
|
-
logger = logging.getLogger(__name__)
|
|
63
|
-
|
|
64
|
-
# Backend tokens that select the remote path. "openai" is what issue #105
|
|
65
|
-
# asked for and matches ``embedding.provider == "openai"``, the established
|
|
66
|
-
# repo token for "any OpenAI-compatible HTTP endpoint". It is a slight misnomer
|
|
67
|
-
# — OpenAI has no rerank API and these endpoints are usually llama-server or
|
|
68
|
-
# TEI — so "remote" is accepted as a truthful alias.
|
|
69
|
-
REMOTE_CROSS_ENCODER_BACKENDS = ("openai", "remote")
|
|
70
|
-
|
|
71
|
-
# Environment override for the bearer token. Preferred over the config field:
|
|
72
|
-
# ``config.json`` is world-readable in many installs and is copied around.
|
|
73
|
-
CROSS_ENCODER_API_KEY_ENV = "SLM_CROSS_ENCODER_API_KEY"
|
|
74
|
-
|
|
75
|
-
_CONNECT_TIMEOUT_S = 5.0
|
|
76
|
-
_DEFAULT_READ_TIMEOUT_S = 15.0
|
|
77
|
-
|
|
78
|
-
# A rerank response is a small array of floats. Anything past this is either a
|
|
79
|
-
# misconfigured URL pointing at something that is not a reranker, or a hostile
|
|
80
|
-
# endpoint trying to exhaust memory. Bounded read, hard stop.
|
|
81
|
-
_MAX_RESPONSE_BYTES = 8 * 1024 * 1024
|
|
82
|
-
|
|
83
|
-
# Candidate pools are 50-200 in practice (semantic_top_k/bm25_top_k are 50).
|
|
84
|
-
# This cap only guards against a pathological pool inflating one HTTP body.
|
|
85
|
-
_MAX_DOCUMENTS = 512
|
|
86
|
-
|
|
87
|
-
# Only transport faults and 5xx are retried, and only once: recall is
|
|
88
|
-
# interactive, so a second failure must surface fast rather than pay a
|
|
89
|
-
# backoff sleep on the user's latency budget.
|
|
90
|
-
_MAX_ATTEMPTS = 2
|
|
91
|
-
|
|
92
|
-
# Consecutive failures re-log at most this often. The first failure always
|
|
93
|
-
# logs; the operator must never have to guess whether reranking is running.
|
|
94
|
-
_FAILURE_RELOG_INTERVAL_S = 60.0
|
|
95
|
-
|
|
96
|
-
class RemoteRerankerError(RuntimeError):
|
|
97
|
-
"""A remote rerank request failed (transport, status, or schema)."""
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
class RemoteRerankerConfigError(ValueError):
|
|
101
|
-
"""The remote reranker configuration is unusable as written."""
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
# ---------------------------------------------------------------------------
|
|
105
|
-
# Configuration (pure functions — no I/O, directly testable)
|
|
106
|
-
# ---------------------------------------------------------------------------
|
|
107
|
-
|
|
108
|
-
def is_remote_cross_encoder_backend(backend: str) -> bool:
|
|
109
|
-
"""True when ``backend`` selects the remote reranker."""
|
|
110
|
-
return (backend or "").strip().lower() in REMOTE_CROSS_ENCODER_BACKENDS
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
def validate_remote_reranker_config(
|
|
114
|
-
backend: str,
|
|
115
|
-
endpoint: str,
|
|
116
|
-
trust_plain_http_lan: bool = True,
|
|
117
|
-
) -> str | None:
|
|
118
|
-
"""Return an actionable error string, or None when the pair is coherent.
|
|
119
|
-
|
|
120
|
-
Covers the issue-#103 leftover directly: an endpoint configured against a
|
|
121
|
-
LOCAL backend used to be dropped on the floor by ``SLMConfig.load``. It now
|
|
122
|
-
produces a named error naming both keys and the exact edit to make.
|
|
123
|
-
|
|
124
|
-
Args:
|
|
125
|
-
backend: Value of ``retrieval.cross_encoder_backend``.
|
|
126
|
-
endpoint: Value of ``retrieval.cross_encoder_endpoint``.
|
|
127
|
-
trust_plain_http_lan: When True (the default), numeric RFC1918/ULA/
|
|
128
|
-
link-local addresses may use plain HTTP — the same security posture
|
|
129
|
-
as the local reranker, where memory text only crosses loopback.
|
|
130
|
-
Set to False in hardened deployments (zero-trust networks, shared
|
|
131
|
-
colocation) to require HTTPS for all non-loopback hosts.
|
|
132
|
-
|
|
133
|
-
Threat model note: trusting a private-LAN address does NOT prevent a
|
|
134
|
-
MITM attack by an adversary on the same physical LAN (e.g. via ARP
|
|
135
|
-
spoofing). This flag means "the LAN is under my control and I accept that
|
|
136
|
-
risk." It is not a claim that RFC1918 traffic is cryptographically secure.
|
|
137
|
-
"""
|
|
138
|
-
backend = (backend or "").strip()
|
|
139
|
-
endpoint = (endpoint or "").strip()
|
|
140
|
-
remote = is_remote_cross_encoder_backend(backend)
|
|
141
|
-
|
|
142
|
-
if remote and not endpoint:
|
|
143
|
-
return (
|
|
144
|
-
f"retrieval.cross_encoder_backend={backend!r} selects the remote "
|
|
145
|
-
f"reranker but retrieval.cross_encoder_endpoint is empty. Set the "
|
|
146
|
-
f"endpoint (e.g. \"http://127.0.0.1:8041/v1/rerank\"), or set "
|
|
147
|
-
f"cross_encoder_backend to \"\" (PyTorch) / \"onnx\" to rerank "
|
|
148
|
-
f"locally."
|
|
149
|
-
)
|
|
150
|
-
if endpoint and not remote:
|
|
151
|
-
return (
|
|
152
|
-
f"retrieval.cross_encoder_endpoint is set to {endpoint!r} but "
|
|
153
|
-
f"retrieval.cross_encoder_backend={backend!r} is a LOCAL backend, "
|
|
154
|
-
f"so the endpoint would be ignored. Set cross_encoder_backend to "
|
|
155
|
-
f"\"openai\" to use the endpoint, or remove cross_encoder_endpoint "
|
|
156
|
-
f"to rerank locally."
|
|
157
|
-
)
|
|
158
|
-
if not remote:
|
|
159
|
-
return None
|
|
160
|
-
return _validate_endpoint_url(endpoint, trust_plain_http_lan=trust_plain_http_lan)
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
def _validate_endpoint_url(
|
|
164
|
-
endpoint: str,
|
|
165
|
-
trust_plain_http_lan: bool = True,
|
|
166
|
-
) -> str | None:
|
|
167
|
-
"""Scheme/host allow-listing for the operator-supplied rerank URL.
|
|
168
|
-
|
|
169
|
-
Plain-HTTP allowances (most-to-least trusted):
|
|
170
|
-
1. Loopback (127.x, ::1, localhost) — always allowed.
|
|
171
|
-
2. Numeric RFC1918/ULA/link-local addresses — allowed when
|
|
172
|
-
``trust_plain_http_lan`` is True (the default). Only numeric
|
|
173
|
-
addresses qualify; bare hostnames are never trusted because DNS is
|
|
174
|
-
mutable and not a trust boundary.
|
|
175
|
-
3. Everything else (public IPs, bare hostnames) — always requires HTTPS.
|
|
176
|
-
"""
|
|
177
|
-
try:
|
|
178
|
-
parsed = urlparse(endpoint)
|
|
179
|
-
except ValueError as exc:
|
|
180
|
-
return f"retrieval.cross_encoder_endpoint is not a valid URL: {exc}"
|
|
181
|
-
if parsed.scheme not in ("http", "https"):
|
|
182
|
-
return (
|
|
183
|
-
f"retrieval.cross_encoder_endpoint must use http or https, got "
|
|
184
|
-
f"{parsed.scheme or '(none)'!r}. SuperLocalMemory will not open "
|
|
185
|
-
f"file/ftp/other schemes for reranking."
|
|
186
|
-
)
|
|
187
|
-
if not parsed.hostname:
|
|
188
|
-
return (
|
|
189
|
-
"retrieval.cross_encoder_endpoint has no host; expected something "
|
|
190
|
-
"like \"http://127.0.0.1:8041/v1/rerank\"."
|
|
191
|
-
)
|
|
192
|
-
if parsed.query or parsed.fragment:
|
|
193
|
-
return (
|
|
194
|
-
"retrieval.cross_encoder_endpoint must not include a query string "
|
|
195
|
-
"or fragment. Put bearer credentials in "
|
|
196
|
-
"SLM_CROSS_ENCODER_API_KEY and configure a clean endpoint URL."
|
|
197
|
-
)
|
|
198
|
-
if parsed.username or parsed.password:
|
|
199
|
-
# httpx logs "HTTP Request: POST <url>" at INFO using str(url), which
|
|
200
|
-
# renders an embedded password in full. This module never logs the raw
|
|
201
|
-
# URL, but it does not own the httpx logger — so credentials are
|
|
202
|
-
# refused at the door instead of being trusted to stay redacted.
|
|
203
|
-
return (
|
|
204
|
-
"retrieval.cross_encoder_endpoint must not embed credentials "
|
|
205
|
-
"(user:password@host) — the HTTP client logs request URLs in "
|
|
206
|
-
"full. Put the token in SLM_CROSS_ENCODER_API_KEY (preferred) or "
|
|
207
|
-
"retrieval.cross_encoder_api_key; it is sent as a Bearer header "
|
|
208
|
-
"and never logged."
|
|
209
|
-
)
|
|
210
|
-
if parsed.scheme == "http":
|
|
211
|
-
hostname = parsed.hostname
|
|
212
|
-
if _is_loopback_host(hostname):
|
|
213
|
-
return None # loopback always allowed regardless of trust flag
|
|
214
|
-
if trust_plain_http_lan and _is_private_lan_host(hostname):
|
|
215
|
-
# Numeric private address on an operator-trusted LAN. Threat model:
|
|
216
|
-
# an attacker on the same physical LAN can still MITM plain HTTP
|
|
217
|
-
# (ARP spoofing). This is allowed because the LAN is assumed to be
|
|
218
|
-
# under the operator's control. Set trust_plain_http_lan=False in
|
|
219
|
-
# hardened/zero-trust environments.
|
|
220
|
-
return None
|
|
221
|
-
if not _is_private_lan_host(hostname):
|
|
222
|
-
# Public IP, CGNAT, or a bare hostname (DNS not trusted as a
|
|
223
|
-
# proof of locality). Bare hostnames that happen to resolve to
|
|
224
|
-
# private IPs are NOT trusted: DNS can be poisoned or changed,
|
|
225
|
-
# so only provably-private numeric addresses are accepted.
|
|
226
|
-
return (
|
|
227
|
-
"retrieval.cross_encoder_endpoint must use HTTPS for this "
|
|
228
|
-
"host. Plain HTTP is allowed only for loopback "
|
|
229
|
-
"(127.x/::1/localhost) and numeric private-LAN addresses "
|
|
230
|
-
"(RFC1918: 10.x, 172.16-31.x, 192.168.x; IPv6 ULA fc00::/7; "
|
|
231
|
-
"link-local 169.254.x/fe80::). "
|
|
232
|
-
"Bare hostnames are not trusted even if they resolve to a "
|
|
233
|
-
"private IP — use a numeric address or configure HTTPS."
|
|
234
|
-
)
|
|
235
|
-
# Private-LAN address but trust_plain_http_lan is False (hardened mode)
|
|
236
|
-
return (
|
|
237
|
-
"retrieval.cross_encoder_endpoint uses plain HTTP to a "
|
|
238
|
-
"private-LAN address. HTTPS is required because "
|
|
239
|
-
"retrieval.trust_plain_http_lan is set to false. "
|
|
240
|
-
"Either configure a TLS-terminating proxy on the reranker, or "
|
|
241
|
-
"set retrieval.trust_plain_http_lan=true to permit plain HTTP "
|
|
242
|
-
"within your private network (default for new installs)."
|
|
243
|
-
)
|
|
244
|
-
return None
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
def _is_loopback_host(hostname: str) -> bool:
|
|
248
|
-
"""Return True only for literal loopback names/addresses (no DNS trust)."""
|
|
249
|
-
host = (hostname or "").rstrip(".").lower()
|
|
250
|
-
if host == "localhost" or host.endswith(".localhost"):
|
|
251
|
-
return True
|
|
252
|
-
try:
|
|
253
|
-
return ipaddress.ip_address(host).is_loopback
|
|
254
|
-
except ValueError:
|
|
255
|
-
return False
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
def _is_private_lan_host(hostname: str) -> bool:
|
|
259
|
-
"""True only for numeric private-range addresses (RFC1918, ULA, link-local).
|
|
260
|
-
|
|
261
|
-
Deliberate non-DNS: bare hostnames (e.g. ``my-reranker.lan``) return False
|
|
262
|
-
even if they currently resolve to a private IP. DNS is mutable and not a
|
|
263
|
-
trust boundary — an adversary who can influence DNS resolution can redirect
|
|
264
|
-
the endpoint to a public host, defeating the locality check. Only numeric
|
|
265
|
-
addresses are provably bound to a private range at configuration time.
|
|
266
|
-
|
|
267
|
-
Accepted ranges (Python 3.11+ ``ipaddress.is_private``):
|
|
268
|
-
IPv4 RFC1918: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
|
|
269
|
-
IPv4 link-local: 169.254.0.0/16
|
|
270
|
-
IPv6 ULA: fc00::/7 (includes fd00::/8)
|
|
271
|
-
IPv6 link-local: fe80::/10
|
|
272
|
-
|
|
273
|
-
Excluded ranges (not accepted for plain HTTP):
|
|
274
|
-
CGNAT 100.64.0.0/10 — ISP-shared address space, not operator-controlled
|
|
275
|
-
172.15.0.0/8 and 172.32.0.0/8 — outside the 172.16.0.0/12 boundary
|
|
276
|
-
Public unicast addresses
|
|
277
|
-
|
|
278
|
-
IPv4-mapped IPv6 addresses (``::ffff:192.168.1.1``) are unwrapped to their
|
|
279
|
-
IPv4 equivalent before the range check, so they are handled consistently.
|
|
280
|
-
"""
|
|
281
|
-
host = (hostname or "").rstrip(".").lower()
|
|
282
|
-
try:
|
|
283
|
-
addr = ipaddress.ip_address(host)
|
|
284
|
-
except ValueError:
|
|
285
|
-
# Not a numeric address — bare hostname, not provably private
|
|
286
|
-
return False
|
|
287
|
-
# Unwrap IPv4-mapped IPv6 (::ffff:192.168.1.1 → 192.168.1.1) so the
|
|
288
|
-
# RFC1918 check applies to the IPv4 portion.
|
|
289
|
-
if isinstance(addr, ipaddress.IPv6Address) and addr.ipv4_mapped is not None:
|
|
290
|
-
addr = addr.ipv4_mapped
|
|
291
|
-
return addr.is_private
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
def normalize_rerank_endpoint(endpoint: str) -> str:
|
|
295
|
-
"""Append ``/rerank`` when the URL stops at the API root.
|
|
296
|
-
|
|
297
|
-
Mirrors the embedding path's ``/embeddings`` suffixing so a user can paste
|
|
298
|
-
either ``http://host:8041/v1`` or ``http://host:8041/v1/rerank``.
|
|
299
|
-
"""
|
|
300
|
-
url = (endpoint or "").strip().rstrip("/")
|
|
301
|
-
parsed = urlparse(url)
|
|
302
|
-
if parsed.path.endswith("/rerank"):
|
|
303
|
-
return url
|
|
304
|
-
return f"{url}/rerank"
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
def redact_endpoint(endpoint: str) -> str:
|
|
308
|
-
"""Drop any ``user:password@`` userinfo before an endpoint reaches a log.
|
|
309
|
-
|
|
310
|
-
Defence in depth. ``_validate_endpoint_url`` already refuses credentialed
|
|
311
|
-
URLs, so this should never have anything to strip in a configured install
|
|
312
|
-
— it exists so that any future caller constructing a reranker directly
|
|
313
|
-
still cannot put a password in the log.
|
|
314
|
-
"""
|
|
315
|
-
try:
|
|
316
|
-
parsed = urlparse(endpoint)
|
|
317
|
-
except ValueError:
|
|
318
|
-
return "<unparseable endpoint>"
|
|
319
|
-
if not parsed.hostname:
|
|
320
|
-
return endpoint
|
|
321
|
-
netloc = parsed.hostname
|
|
322
|
-
if parsed.port:
|
|
323
|
-
netloc = f"{netloc}:{parsed.port}"
|
|
324
|
-
if parsed.username or parsed.password:
|
|
325
|
-
netloc = f"***@{netloc}"
|
|
326
|
-
return urlunparse(parsed._replace(netloc=netloc, query="", fragment=""))
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
def _redact_remote_text(text: str) -> str:
|
|
330
|
-
"""Remove recognized secrets and PII before a remote trust boundary."""
|
|
331
|
-
from superlocalmemory.core.pii import redact_pii_text
|
|
332
|
-
from superlocalmemory.core.security_primitives import redact_secrets
|
|
333
|
-
|
|
334
|
-
return redact_pii_text(redact_secrets(str(text), aggression="high"))
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
# ---------------------------------------------------------------------------
|
|
338
|
-
# Response parsing (pure — the schema gate)
|
|
339
|
-
# ---------------------------------------------------------------------------
|
|
340
|
-
|
|
341
|
-
def parse_rerank_response(payload: Any, expected: int) -> list[float]:
|
|
342
|
-
"""Validate a ``/v1/rerank`` payload and return scores in document order.
|
|
343
|
-
|
|
344
|
-
Raises ``RemoteRerankerError`` on ANY deviation. A rerank response that is
|
|
345
|
-
not understood must abort reranking, never yield partly-invented scores:
|
|
346
|
-
a wrong score silently reorders a user's memory, and nothing downstream
|
|
347
|
-
can tell that apart from a good one.
|
|
348
|
-
"""
|
|
349
|
-
results = _extract_results_array(payload)
|
|
350
|
-
if len(results) != expected:
|
|
351
|
-
raise RemoteRerankerError(
|
|
352
|
-
f"rerank endpoint returned {len(results)} results for "
|
|
353
|
-
f"{expected} documents; refusing to guess the missing scores"
|
|
354
|
-
)
|
|
355
|
-
|
|
356
|
-
scores: list[float | None] = [None] * expected
|
|
357
|
-
for position, item in enumerate(results):
|
|
358
|
-
if not isinstance(item, dict):
|
|
359
|
-
raise RemoteRerankerError(
|
|
360
|
-
f"rerank result #{position} is {type(item).__name__}, "
|
|
361
|
-
f"expected an object with 'index' and 'relevance_score'"
|
|
362
|
-
)
|
|
363
|
-
index = _coerce_index(item, position, expected)
|
|
364
|
-
if scores[index] is not None:
|
|
365
|
-
raise RemoteRerankerError(
|
|
366
|
-
"rerank endpoint returned a duplicate document index"
|
|
367
|
-
)
|
|
368
|
-
scores[index] = _coerce_score(item, index)
|
|
369
|
-
|
|
370
|
-
missing = [i for i, s in enumerate(scores) if s is None]
|
|
371
|
-
if missing:
|
|
372
|
-
raise RemoteRerankerError(
|
|
373
|
-
"rerank endpoint omitted one or more document scores"
|
|
374
|
-
)
|
|
375
|
-
return [float(s) for s in scores] # type: ignore[arg-type]
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
def _extract_results_array(payload: Any) -> list[Any]:
|
|
379
|
-
if isinstance(payload, list):
|
|
380
|
-
return payload # text-embeddings-inference style bare array
|
|
381
|
-
if not isinstance(payload, dict):
|
|
382
|
-
raise RemoteRerankerError(
|
|
383
|
-
f"rerank endpoint returned {type(payload).__name__}, expected a "
|
|
384
|
-
f"JSON object with a 'results' array"
|
|
385
|
-
)
|
|
386
|
-
results = payload.get("results")
|
|
387
|
-
if results is None:
|
|
388
|
-
raise RemoteRerankerError(
|
|
389
|
-
"rerank response has no 'results' array. Is "
|
|
390
|
-
"cross_encoder_endpoint pointing at a "
|
|
391
|
-
f"rerank route and not, say, /v1/embeddings?"
|
|
392
|
-
)
|
|
393
|
-
if not isinstance(results, list):
|
|
394
|
-
raise RemoteRerankerError(
|
|
395
|
-
f"rerank response 'results' is {type(results).__name__}, "
|
|
396
|
-
f"expected an array"
|
|
397
|
-
)
|
|
398
|
-
return results
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
def _coerce_index(item: dict, position: int, expected: int) -> int:
|
|
402
|
-
raw = item.get("index", position)
|
|
403
|
-
if isinstance(raw, bool) or not isinstance(raw, int):
|
|
404
|
-
raise RemoteRerankerError(
|
|
405
|
-
f"rerank result #{position} has a non-integer index"
|
|
406
|
-
)
|
|
407
|
-
if not 0 <= raw < expected:
|
|
408
|
-
raise RemoteRerankerError(
|
|
409
|
-
f"rerank result #{position} has an out-of-range index "
|
|
410
|
-
f"for a {expected}-document request"
|
|
411
|
-
)
|
|
412
|
-
return raw
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
def _coerce_score(item: dict, index: int) -> float:
|
|
416
|
-
for key in ("relevance_score", "score"):
|
|
417
|
-
if key in item:
|
|
418
|
-
raw = item[key]
|
|
419
|
-
if isinstance(raw, bool) or not isinstance(raw, (int, float)):
|
|
420
|
-
raise RemoteRerankerError(
|
|
421
|
-
f"rerank result for index {index} has non-numeric "
|
|
422
|
-
f"{key}"
|
|
423
|
-
)
|
|
424
|
-
value = float(raw)
|
|
425
|
-
if not math.isfinite(value):
|
|
426
|
-
raise RemoteRerankerError(
|
|
427
|
-
f"rerank result for index {index} has non-finite "
|
|
428
|
-
f"{key}"
|
|
429
|
-
)
|
|
430
|
-
return value
|
|
431
|
-
raise RemoteRerankerError(
|
|
432
|
-
f"rerank result for index {index} has neither 'relevance_score' nor "
|
|
433
|
-
"'score'"
|
|
434
|
-
)
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
# ---------------------------------------------------------------------------
|
|
438
|
-
# The reranker
|
|
439
|
-
# ---------------------------------------------------------------------------
|
|
440
|
-
|
|
441
|
-
class RemoteReranker:
|
|
442
|
-
"""Rerank candidates via an OpenAI-compatible ``/v1/rerank`` endpoint.
|
|
443
|
-
|
|
444
|
-
Public surface is interchangeable with ``CrossEncoderReranker`` so
|
|
445
|
-
``RetrievalEngine`` never learns which one it holds.
|
|
446
|
-
|
|
447
|
-
Args:
|
|
448
|
-
model_name: Model identifier passed to the endpoint (llama-server
|
|
449
|
-
wants the served path, e.g. ``/root/model/reranker.gguf``).
|
|
450
|
-
endpoint: Base or full rerank URL. ``/rerank`` is appended when absent.
|
|
451
|
-
api_key: Optional bearer token. ``SLM_CROSS_ENCODER_API_KEY`` wins.
|
|
452
|
-
backend: The configured backend token, for validation + logs.
|
|
453
|
-
timeout_seconds: Per-request read budget.
|
|
454
|
-
|
|
455
|
-
Raises:
|
|
456
|
-
RemoteRerankerConfigError: the backend/endpoint pair is unusable.
|
|
457
|
-
"""
|
|
458
|
-
|
|
459
|
-
def __init__(
|
|
460
|
-
self,
|
|
461
|
-
model_name: str,
|
|
462
|
-
endpoint: str,
|
|
463
|
-
*,
|
|
464
|
-
api_key: str = "",
|
|
465
|
-
backend: str = "openai",
|
|
466
|
-
timeout_seconds: float = _DEFAULT_READ_TIMEOUT_S,
|
|
467
|
-
trust_plain_http_lan: bool = True,
|
|
468
|
-
) -> None:
|
|
469
|
-
error = validate_remote_reranker_config(
|
|
470
|
-
backend, endpoint, trust_plain_http_lan=trust_plain_http_lan,
|
|
471
|
-
)
|
|
472
|
-
if error:
|
|
473
|
-
raise RemoteRerankerConfigError(error)
|
|
474
|
-
|
|
475
|
-
self._model_name = model_name
|
|
476
|
-
self._backend = backend
|
|
477
|
-
self._endpoint = normalize_rerank_endpoint(endpoint)
|
|
478
|
-
self.safe_endpoint = redact_endpoint(self._endpoint)
|
|
479
|
-
self._api_key = os.environ.get(CROSS_ENCODER_API_KEY_ENV, "") or api_key
|
|
480
|
-
try:
|
|
481
|
-
self._read_timeout = max(1.0, float(timeout_seconds))
|
|
482
|
-
except (TypeError, ValueError):
|
|
483
|
-
self._read_timeout = _DEFAULT_READ_TIMEOUT_S
|
|
484
|
-
|
|
485
|
-
self._client: Any = None
|
|
486
|
-
self._client_lock = threading.Lock()
|
|
487
|
-
self._shutdown = threading.Event()
|
|
488
|
-
self._consecutive_failures = 0
|
|
489
|
-
self._last_failure_log = 0.0
|
|
490
|
-
self._probe_ok = False
|
|
491
|
-
|
|
492
|
-
# -- lifecycle ---------------------------------------------------------
|
|
493
|
-
|
|
494
|
-
def warmup_sync(self, timeout: float = _DEFAULT_READ_TIMEOUT_S) -> bool:
|
|
495
|
-
"""Probe the endpoint once so startup states reachability out loud.
|
|
496
|
-
|
|
497
|
-
Diagnostic only: a failed probe never disables reranking, because an
|
|
498
|
-
endpoint that is still booting will serve the next real recall fine.
|
|
499
|
-
"""
|
|
500
|
-
if self._shutdown.is_set():
|
|
501
|
-
return False
|
|
502
|
-
try:
|
|
503
|
-
self._request_scores("ping", ["SuperLocalMemory reranker probe"])
|
|
504
|
-
except RemoteRerankerError as exc:
|
|
505
|
-
self._probe_ok = False
|
|
506
|
-
logger.error(
|
|
507
|
-
"Remote reranker probe failed for %s (model=%s): %s. Recall "
|
|
508
|
-
"will run WITHOUT reranking until the endpoint answers. "
|
|
509
|
-
"Verify retrieval.cross_encoder_endpoint and that the service "
|
|
510
|
-
"is up.",
|
|
511
|
-
self.safe_endpoint, self._model_name, exc,
|
|
512
|
-
)
|
|
513
|
-
return False
|
|
514
|
-
self._probe_ok = True
|
|
515
|
-
logger.info(
|
|
516
|
-
"Remote reranker ready: %s (model=%s, backend=%s)",
|
|
517
|
-
self.safe_endpoint, self._model_name, self._backend,
|
|
518
|
-
)
|
|
519
|
-
return True
|
|
520
|
-
|
|
521
|
-
def unload(self) -> None:
|
|
522
|
-
"""Release the pooled HTTP connections; the object stays usable."""
|
|
523
|
-
self._close_client()
|
|
524
|
-
|
|
525
|
-
def shutdown(self, timeout: float = 3.0) -> None: # noqa: ARG002 - parity
|
|
526
|
-
"""Stop serving and close the HTTP client."""
|
|
527
|
-
self._shutdown.set()
|
|
528
|
-
self._close_client()
|
|
529
|
-
|
|
530
|
-
def __del__(self) -> None:
|
|
531
|
-
try:
|
|
532
|
-
self._close_client()
|
|
533
|
-
except Exception:
|
|
534
|
-
pass
|
|
535
|
-
|
|
536
|
-
@property
|
|
537
|
-
def is_available(self) -> bool:
|
|
538
|
-
"""Whether the endpoint answers a probe right now."""
|
|
539
|
-
if self._shutdown.is_set():
|
|
540
|
-
return False
|
|
541
|
-
try:
|
|
542
|
-
self._request_scores("ping", ["SuperLocalMemory reranker probe"])
|
|
543
|
-
except RemoteRerankerError:
|
|
544
|
-
return False
|
|
545
|
-
return True
|
|
546
|
-
|
|
547
|
-
# -- public reranking --------------------------------------------------
|
|
548
|
-
|
|
549
|
-
def rerank(
|
|
550
|
-
self,
|
|
551
|
-
query: str,
|
|
552
|
-
candidates: list[tuple[AtomicFact, float]],
|
|
553
|
-
top_k: int = 10,
|
|
554
|
-
) -> list[tuple[AtomicFact, float]]:
|
|
555
|
-
"""Rerank ``candidates``; fusion order is returned when the endpoint fails."""
|
|
556
|
-
results, _, _ = self.rerank_with_status(query, candidates, top_k=top_k)
|
|
557
|
-
return results
|
|
558
|
-
|
|
559
|
-
def rerank_with_status(
|
|
560
|
-
self,
|
|
561
|
-
query: str,
|
|
562
|
-
candidates: list[tuple[AtomicFact, float]],
|
|
563
|
-
top_k: int = 10,
|
|
564
|
-
) -> tuple[list[tuple[AtomicFact, float]], bool, str]:
|
|
565
|
-
"""Return results plus whether remote reranking actually ran."""
|
|
566
|
-
if not candidates:
|
|
567
|
-
return [], False, "no_candidates"
|
|
568
|
-
if self._shutdown.is_set():
|
|
569
|
-
return self._fusion_order(candidates)[:top_k], False, "shutdown"
|
|
570
|
-
|
|
571
|
-
ranked = self._fusion_order(candidates)
|
|
572
|
-
if len(ranked) > _MAX_DOCUMENTS:
|
|
573
|
-
# Unreachable with stock config (semantic_top_k/bm25_top_k are 50).
|
|
574
|
-
# RetrievalEngine keeps every fused result and assigns the batch
|
|
575
|
-
# minimum to any fact absent from the rerank map, so the excluded
|
|
576
|
-
# tail — already the lowest-fusion candidates — is demoted, not
|
|
577
|
-
# lost.
|
|
578
|
-
logger.warning(
|
|
579
|
-
"Remote reranker: %d candidates exceeds the %d-document "
|
|
580
|
-
"request cap; reranking the top %d by fusion score and "
|
|
581
|
-
"dropping the rest",
|
|
582
|
-
len(ranked), _MAX_DOCUMENTS, _MAX_DOCUMENTS,
|
|
583
|
-
)
|
|
584
|
-
ranked = ranked[:_MAX_DOCUMENTS]
|
|
585
|
-
|
|
586
|
-
try:
|
|
587
|
-
scores = self._request_scores(
|
|
588
|
-
query, [fact.content for fact, _ in ranked],
|
|
589
|
-
)
|
|
590
|
-
except RemoteRerankerError as exc:
|
|
591
|
-
self._note_failure(exc)
|
|
592
|
-
return ranked[:top_k], False, "remote_unavailable"
|
|
593
|
-
|
|
594
|
-
self._note_success()
|
|
595
|
-
scored = [
|
|
596
|
-
(fact, float(score))
|
|
597
|
-
for (fact, _), score in zip(ranked, scores)
|
|
598
|
-
]
|
|
599
|
-
scored.sort(key=lambda pair: (-pair[1], pair[0].fact_id))
|
|
600
|
-
return scored[:top_k], True, "applied"
|
|
601
|
-
|
|
602
|
-
def score_pair(self, query: str, document: str) -> float:
|
|
603
|
-
"""Score one (query, document) pair; 0.0 when the endpoint fails."""
|
|
604
|
-
if self._shutdown.is_set():
|
|
605
|
-
return 0.0
|
|
606
|
-
try:
|
|
607
|
-
return self._request_scores(query, [document])[0]
|
|
608
|
-
except RemoteRerankerError as exc:
|
|
609
|
-
self._note_failure(exc)
|
|
610
|
-
return 0.0
|
|
611
|
-
|
|
612
|
-
# -- HTTP --------------------------------------------------------------
|
|
613
|
-
|
|
614
|
-
def _request_scores(self, query: str, documents: list[str]) -> list[float]:
|
|
615
|
-
"""POST one rerank request, retrying only genuinely transient faults."""
|
|
616
|
-
headers = {"Content-Type": "application/json"}
|
|
617
|
-
if self._api_key:
|
|
618
|
-
# Never logged: no error path in this module formats `headers`.
|
|
619
|
-
headers["Authorization"] = f"Bearer {self._api_key}"
|
|
620
|
-
body = {
|
|
621
|
-
"model": self._model_name,
|
|
622
|
-
"query": _redact_remote_text(query),
|
|
623
|
-
"documents": [_redact_remote_text(document) for document in documents],
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
last_error: RemoteRerankerError | None = None
|
|
627
|
-
for attempt in range(_MAX_ATTEMPTS):
|
|
628
|
-
try:
|
|
629
|
-
payload = self._post(headers, body)
|
|
630
|
-
except _RetryableRemoteError as exc:
|
|
631
|
-
last_error = RemoteRerankerError(str(exc))
|
|
632
|
-
if attempt < _MAX_ATTEMPTS - 1:
|
|
633
|
-
continue
|
|
634
|
-
break
|
|
635
|
-
return parse_rerank_response(payload, len(documents))
|
|
636
|
-
raise RemoteRerankerError(
|
|
637
|
-
f"remote reranker at {self.safe_endpoint} failed after "
|
|
638
|
-
f"{_MAX_ATTEMPTS} attempts: {last_error}"
|
|
639
|
-
)
|
|
640
|
-
|
|
641
|
-
def _post(self, headers: dict[str, str], body: dict[str, Any]) -> Any:
|
|
642
|
-
"""Send the request and return parsed JSON, with a bounded body read."""
|
|
643
|
-
import httpx
|
|
644
|
-
|
|
645
|
-
client = self._get_client()
|
|
646
|
-
try:
|
|
647
|
-
with client.stream(
|
|
648
|
-
"POST", self._endpoint, headers=headers, json=body,
|
|
649
|
-
) as resp:
|
|
650
|
-
raw = _read_bounded(resp)
|
|
651
|
-
if 300 <= resp.status_code < 400:
|
|
652
|
-
# Redirects are not followed: a rerank endpoint that
|
|
653
|
-
# bounces us elsewhere is either misconfigured or an
|
|
654
|
-
# attempt to pivot this outbound request at a host the
|
|
655
|
-
# operator never approved.
|
|
656
|
-
raise RemoteRerankerError(
|
|
657
|
-
f"rerank endpoint {self.safe_endpoint} replied HTTP "
|
|
658
|
-
f"{resp.status_code} (redirect). Redirects are not "
|
|
659
|
-
f"followed — configure the final URL directly."
|
|
660
|
-
)
|
|
661
|
-
if resp.status_code >= 400:
|
|
662
|
-
message = (
|
|
663
|
-
f"HTTP {resp.status_code} from {self.safe_endpoint}; "
|
|
664
|
-
"response body suppressed"
|
|
665
|
-
)
|
|
666
|
-
if resp.status_code >= 500:
|
|
667
|
-
raise _RetryableRemoteError(message)
|
|
668
|
-
raise RemoteRerankerError(message)
|
|
669
|
-
except httpx.TransportError as exc:
|
|
670
|
-
raise _RetryableRemoteError(
|
|
671
|
-
f"cannot reach {self.safe_endpoint}: "
|
|
672
|
-
f"{type(exc).__name__}: {exc}"
|
|
673
|
-
) from exc
|
|
674
|
-
try:
|
|
675
|
-
return json.loads(raw)
|
|
676
|
-
except (json.JSONDecodeError, UnicodeDecodeError) as exc:
|
|
677
|
-
raise RemoteRerankerError(
|
|
678
|
-
f"rerank endpoint {self.safe_endpoint} returned non-JSON "
|
|
679
|
-
f"({exc})"
|
|
680
|
-
) from exc
|
|
681
|
-
|
|
682
|
-
def _get_client(self) -> Any:
|
|
683
|
-
import httpx
|
|
684
|
-
|
|
685
|
-
with self._client_lock:
|
|
686
|
-
if self._client is None:
|
|
687
|
-
self._client = httpx.Client(
|
|
688
|
-
timeout=httpx.Timeout(
|
|
689
|
-
connect=_CONNECT_TIMEOUT_S,
|
|
690
|
-
read=self._read_timeout,
|
|
691
|
-
write=10.0,
|
|
692
|
-
pool=5.0,
|
|
693
|
-
),
|
|
694
|
-
follow_redirects=False,
|
|
695
|
-
)
|
|
696
|
-
return self._client
|
|
697
|
-
|
|
698
|
-
def _close_client(self) -> None:
|
|
699
|
-
with self._client_lock:
|
|
700
|
-
client, self._client = self._client, None
|
|
701
|
-
if client is not None:
|
|
702
|
-
try:
|
|
703
|
-
client.close()
|
|
704
|
-
except Exception:
|
|
705
|
-
pass
|
|
706
|
-
|
|
707
|
-
# -- failure visibility ------------------------------------------------
|
|
708
|
-
|
|
709
|
-
def _note_failure(self, exc: Exception) -> None:
|
|
710
|
-
"""Make a degraded reranker impossible to miss, without log flooding."""
|
|
711
|
-
self._consecutive_failures += 1
|
|
712
|
-
now = time.time()
|
|
713
|
-
if (
|
|
714
|
-
self._consecutive_failures == 1
|
|
715
|
-
or now - self._last_failure_log >= _FAILURE_RELOG_INTERVAL_S
|
|
716
|
-
):
|
|
717
|
-
logger.error(
|
|
718
|
-
"Remote reranker unavailable (%d consecutive failures): %s. "
|
|
719
|
-
"Recall is returning fusion-ranked results with NO reranking. "
|
|
720
|
-
"SuperLocalMemory will not silently substitute the local "
|
|
721
|
-
"English cross-encoder for your configured model.",
|
|
722
|
-
self._consecutive_failures, exc,
|
|
723
|
-
)
|
|
724
|
-
self._last_failure_log = now
|
|
725
|
-
|
|
726
|
-
def _note_success(self) -> None:
|
|
727
|
-
if self._consecutive_failures:
|
|
728
|
-
logger.info(
|
|
729
|
-
"Remote reranker recovered after %d consecutive failures (%s)",
|
|
730
|
-
self._consecutive_failures, self.safe_endpoint,
|
|
731
|
-
)
|
|
732
|
-
self._consecutive_failures = 0
|
|
733
|
-
|
|
734
|
-
@staticmethod
|
|
735
|
-
def _fusion_order(
|
|
736
|
-
candidates: list[tuple[AtomicFact, float]],
|
|
737
|
-
) -> list[tuple[AtomicFact, float]]:
|
|
738
|
-
return sorted(candidates, key=lambda pair: (-pair[1], pair[0].fact_id))
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
class _RetryableRemoteError(RemoteRerankerError):
|
|
742
|
-
"""Internal marker: this failure is worth exactly one more attempt."""
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
def _read_bounded(resp: Any) -> bytes:
|
|
746
|
-
"""Read a streaming response body, refusing to buffer past the cap."""
|
|
747
|
-
chunks: list[bytes] = []
|
|
748
|
-
total = 0
|
|
749
|
-
for chunk in resp.iter_bytes():
|
|
750
|
-
total += len(chunk)
|
|
751
|
-
if total > _MAX_RESPONSE_BYTES:
|
|
752
|
-
raise RemoteRerankerError(
|
|
753
|
-
f"rerank response exceeded {_MAX_RESPONSE_BYTES} bytes; "
|
|
754
|
-
f"aborting the read. Is cross_encoder_endpoint pointing at a "
|
|
755
|
-
f"rerank route?"
|
|
756
|
-
)
|
|
757
|
-
chunks.append(chunk)
|
|
758
|
-
return b"".join(chunks)
|