superlocalmemory 4.1.13 → 4.1.14
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 +48 -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,687 +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 — Entity Resolution.
|
|
6
|
-
|
|
7
|
-
Maps variant mentions ("Alice", "Ms. Smith", "she") to canonical entities.
|
|
8
|
-
Persists ALL resolution results to DB — the #1 fix from the V1 audit where
|
|
9
|
-
entity resolution ran but results were silently discarded.
|
|
10
|
-
|
|
11
|
-
4-tier strategy:
|
|
12
|
-
a) Exact match in canonical_entities (case-insensitive)
|
|
13
|
-
b) Alias match in entity_aliases (case-insensitive)
|
|
14
|
-
c) Fuzzy match via Jaro-Winkler similarity (threshold 0.85)
|
|
15
|
-
d) LLM disambiguation (Mode B/C only)
|
|
16
|
-
|
|
17
|
-
Part of Qualixar | Author: Varun Pratap Bhardwaj
|
|
18
|
-
License: AGPL-3.0-or-later
|
|
19
|
-
"""
|
|
20
|
-
|
|
21
|
-
from __future__ import annotations
|
|
22
|
-
|
|
23
|
-
import json
|
|
24
|
-
import logging
|
|
25
|
-
import re
|
|
26
|
-
from typing import TYPE_CHECKING
|
|
27
|
-
|
|
28
|
-
from superlocalmemory.storage.models import CanonicalEntity, EntityAlias, _new_id, _now
|
|
29
|
-
|
|
30
|
-
if TYPE_CHECKING:
|
|
31
|
-
from superlocalmemory.llm.backbone import LLMBackbone
|
|
32
|
-
from superlocalmemory.storage.database import DatabaseManager
|
|
33
|
-
|
|
34
|
-
logger = logging.getLogger(__name__)
|
|
35
|
-
|
|
36
|
-
# ---------------------------------------------------------------------------
|
|
37
|
-
# Constants
|
|
38
|
-
# ---------------------------------------------------------------------------
|
|
39
|
-
|
|
40
|
-
JARO_WINKLER_AUTO_MERGE: float = 0.85 # Auto-merge threshold
|
|
41
|
-
JARO_WINKLER_LLM_FLOOR: float = 0.70 # Below this, never merge
|
|
42
|
-
PRONOUNS: frozenset[str] = frozenset({
|
|
43
|
-
"he", "she", "they", "him", "her", "them", "his", "hers", "their",
|
|
44
|
-
"himself", "herself", "themselves", "it", "its", "i", "me", "my",
|
|
45
|
-
"we", "us", "our", "you", "your",
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
# Heuristic entity type patterns
|
|
49
|
-
_ORG_MARKERS = ("Inc", "Corp", "LLC", "Ltd", "University", "Hospital", "Bank",
|
|
50
|
-
"Foundation", "Institute", "Company", "Group", "Agency")
|
|
51
|
-
_PLACE_MARKERS = ("City", "State", "County", "Island", "River", "Mountain",
|
|
52
|
-
"Lake", "Park", "Street", "Avenue", "Road", "District")
|
|
53
|
-
_EVENT_MARKERS = ("Festival", "Conference", "Summit", "Workshop", "Meeting",
|
|
54
|
-
"Election", "War", "Match", "Game", "Concert", "Wedding")
|
|
55
|
-
# v3.4.10: Skill entity type — skills, commands, agents, plugins
|
|
56
|
-
_SKILL_MARKERS_RE = re.compile(r'\b(?:skill|command|agent|plugin|hook|mcp)\b', re.IGNORECASE)
|
|
57
|
-
_SKILL_NAMESPACE_RE = re.compile(r"^[\w-]+:[\w-]+$") # e.g., "superpowers:brainstorming"
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
# ---------------------------------------------------------------------------
|
|
61
|
-
# Jaro-Winkler similarity — pure Python fallback
|
|
62
|
-
# ---------------------------------------------------------------------------
|
|
63
|
-
|
|
64
|
-
def jaro_winkler(s1: str, s2: str, prefix_weight: float = 0.1) -> float:
|
|
65
|
-
"""Jaro-Winkler similarity in [0, 1]. 1 = identical.
|
|
66
|
-
|
|
67
|
-
Pure Python implementation. Capped at 200 chars for O(n^2) safety.
|
|
68
|
-
"""
|
|
69
|
-
s1, s2 = s1[:200], s2[:200]
|
|
70
|
-
if not s1 or not s2:
|
|
71
|
-
return 0.0
|
|
72
|
-
if s1 == s2:
|
|
73
|
-
return 1.0
|
|
74
|
-
|
|
75
|
-
len1, len2 = len(s1), len(s2)
|
|
76
|
-
match_dist = max(len1, len2) // 2 - 1
|
|
77
|
-
if match_dist < 0:
|
|
78
|
-
match_dist = 0
|
|
79
|
-
|
|
80
|
-
s1_matched = [False] * len1
|
|
81
|
-
s2_matched = [False] * len2
|
|
82
|
-
matches = transpositions = 0
|
|
83
|
-
|
|
84
|
-
for i in range(len1):
|
|
85
|
-
lo = max(0, i - match_dist)
|
|
86
|
-
hi = min(i + match_dist + 1, len2)
|
|
87
|
-
for j in range(lo, hi):
|
|
88
|
-
if s2_matched[j] or s1[i] != s2[j]:
|
|
89
|
-
continue
|
|
90
|
-
s1_matched[i] = s2_matched[j] = True
|
|
91
|
-
matches += 1
|
|
92
|
-
break
|
|
93
|
-
|
|
94
|
-
if matches == 0:
|
|
95
|
-
return 0.0
|
|
96
|
-
|
|
97
|
-
k = 0
|
|
98
|
-
for i in range(len1):
|
|
99
|
-
if not s1_matched[i]:
|
|
100
|
-
continue
|
|
101
|
-
while not s2_matched[k]:
|
|
102
|
-
k += 1
|
|
103
|
-
if s1[i] != s2[k]:
|
|
104
|
-
transpositions += 1
|
|
105
|
-
k += 1
|
|
106
|
-
|
|
107
|
-
jaro = (
|
|
108
|
-
matches / len1 + matches / len2
|
|
109
|
-
+ (matches - transpositions / 2) / matches
|
|
110
|
-
) / 3.0
|
|
111
|
-
|
|
112
|
-
prefix = sum(
|
|
113
|
-
1 for i in range(min(4, len1, len2)) if s1[i] == s2[i]
|
|
114
|
-
)
|
|
115
|
-
return jaro + prefix * prefix_weight * (1.0 - jaro)
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
_COMMON_WORDS = frozenset({
|
|
119
|
-
# Months / time words (biggest source of garbage entities)
|
|
120
|
-
"january", "february", "march", "april", "may", "june", "july",
|
|
121
|
-
"august", "september", "october", "november", "december",
|
|
122
|
-
"monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday",
|
|
123
|
-
"today", "tomorrow", "yesterday", "morning", "evening", "night",
|
|
124
|
-
# English stop words that get capitalized at sentence start
|
|
125
|
-
"a", "an", "the", "all", "not", "no", "yes", "and", "or", "but",
|
|
126
|
-
"if", "is", "are", "was", "were", "be", "been", "being", "have",
|
|
127
|
-
"has", "had", "do", "does", "did", "will", "would", "shall", "should",
|
|
128
|
-
"can", "could", "just", "also", "only", "very", "too", "so", "then",
|
|
129
|
-
"than", "that", "this", "these", "those", "here", "there", "where",
|
|
130
|
-
"when", "what", "which", "who", "whom", "how", "why", "each", "every",
|
|
131
|
-
"both", "few", "more", "most", "other", "some", "such", "any", "many",
|
|
132
|
-
"much", "own", "same", "new", "old", "first", "last", "next", "now",
|
|
133
|
-
"still", "already", "always", "never", "often", "sometimes", "about",
|
|
134
|
-
"above", "after", "again", "against", "along", "among", "around",
|
|
135
|
-
"before", "below", "between", "beyond", "during", "except", "from",
|
|
136
|
-
"into", "near", "off", "onto", "out", "over", "past", "since",
|
|
137
|
-
"through", "under", "until", "upon", "with", "within", "without",
|
|
138
|
-
# Technical stop words (common in dev sessions)
|
|
139
|
-
"phase", "test", "gap", "dashboard", "remaining", "session", "results",
|
|
140
|
-
"tools", "projects", "prompts", "integration", "cli", "engagement",
|
|
141
|
-
"mode", "error", "step", "fix", "build", "check", "run", "start",
|
|
142
|
-
"stop", "config", "status", "version", "query", "data", "file", "path",
|
|
143
|
-
"node", "edge", "table", "index", "schema", "model", "type", "class",
|
|
144
|
-
"function", "module", "package", "import", "export", "default", "pattern",
|
|
145
|
-
"memory", "profile", "context", "pipeline", "worker", "daemon",
|
|
146
|
-
"server", "client", "route", "endpoint", "handler", "hook",
|
|
147
|
-
"feature", "release", "update", "upgrade", "deploy", "debug", "log",
|
|
148
|
-
"output", "input", "key", "value", "true", "false", "null", "none",
|
|
149
|
-
"ready", "done", "todo", "complete", "pending", "active", "failed",
|
|
150
|
-
"success", "warning", "critical", "high", "medium", "low",
|
|
151
|
-
"total", "count", "list", "item", "entry", "record", "row", "column",
|
|
152
|
-
"source", "target", "origin", "destination", "backup", "restore",
|
|
153
|
-
"create", "read", "delete", "remove", "add", "set", "get", "put",
|
|
154
|
-
"push", "pull", "fetch", "send", "receive", "request", "response",
|
|
155
|
-
"enable", "disable", "open", "close", "load", "save", "reset",
|
|
156
|
-
# Abstract nouns often misclassified as people
|
|
157
|
-
"completeness", "correctness", "limitations", "requirements",
|
|
158
|
-
"dependencies", "performance", "security", "quality", "coverage",
|
|
159
|
-
"progress", "analysis", "research", "implementation", "verification",
|
|
160
|
-
"overview", "summary", "details", "notes", "changes", "issues",
|
|
161
|
-
"approach", "strategy", "solution", "problem", "question", "answer",
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
def _guess_entity_type(name: str) -> str:
|
|
166
|
-
"""Heuristic entity type classification from name string.
|
|
167
|
-
|
|
168
|
-
v3.4.10: Aggressive false-positive prevention. "person" is assigned ONLY
|
|
169
|
-
when the name looks like a real human name (2-3 capitalized words, none
|
|
170
|
-
in the stop list). Everything else defaults to "concept".
|
|
171
|
-
"""
|
|
172
|
-
# Reject very short or very long names
|
|
173
|
-
if len(name) <= 2 or len(name) > 100:
|
|
174
|
-
return "concept"
|
|
175
|
-
|
|
176
|
-
# Reject pure numbers, dates, version strings
|
|
177
|
-
if re.match(r"^[\d.v\-/]+$", name):
|
|
178
|
-
return "concept"
|
|
179
|
-
|
|
180
|
-
if any(m in name for m in _ORG_MARKERS):
|
|
181
|
-
return "organization"
|
|
182
|
-
if any(m in name for m in _PLACE_MARKERS):
|
|
183
|
-
return "place"
|
|
184
|
-
if any(m in name for m in _EVENT_MARKERS):
|
|
185
|
-
return "event"
|
|
186
|
-
|
|
187
|
-
# v3.4.10: Skill entities — namespaced skills always skill type
|
|
188
|
-
if _SKILL_NAMESPACE_RE.match(name):
|
|
189
|
-
return "skill"
|
|
190
|
-
|
|
191
|
-
# Check ALL words against the stop list (not just the full name)
|
|
192
|
-
words = name.lower().split()
|
|
193
|
-
if any(w in _COMMON_WORDS for w in words):
|
|
194
|
-
return "concept"
|
|
195
|
-
|
|
196
|
-
# v3.4.10: Skill entities — word-boundary match AFTER common-word filter
|
|
197
|
-
if _SKILL_MARKERS_RE.search(name):
|
|
198
|
-
return "skill"
|
|
199
|
-
|
|
200
|
-
# Multi-word entity: "person" only if 2-3 capitalized words, no stop words
|
|
201
|
-
if re.match(r"^[A-Z][a-z]+ [A-Z][a-z]+( [A-Z][a-z]+)?$", name):
|
|
202
|
-
if not any(p in _COMMON_WORDS for p in words):
|
|
203
|
-
return "person"
|
|
204
|
-
|
|
205
|
-
# Single capitalized word — almost never a person in our context
|
|
206
|
-
# Only known first names should get "person" but we can't maintain
|
|
207
|
-
# a name dictionary, so default to "concept"
|
|
208
|
-
if re.match(r"^[A-Z][a-z]+$", name):
|
|
209
|
-
return "concept"
|
|
210
|
-
|
|
211
|
-
# Contains dots/slashes/hyphens/underscores = technical term
|
|
212
|
-
if re.search(r"[./\-_]", name):
|
|
213
|
-
return "concept"
|
|
214
|
-
|
|
215
|
-
# ALL-CAPS or mixed case with numbers = technical/concept
|
|
216
|
-
if re.match(r"^[A-Z]+$", name) or re.search(r"\d", name):
|
|
217
|
-
return "concept"
|
|
218
|
-
|
|
219
|
-
return "concept"
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
# ---------------------------------------------------------------------------
|
|
223
|
-
# Entity Resolver
|
|
224
|
-
# ---------------------------------------------------------------------------
|
|
225
|
-
|
|
226
|
-
def _unproject_entity(entity_id: str) -> bool:
|
|
227
|
-
"""Remove an entity node from the graph projection, if there is one.
|
|
228
|
-
|
|
229
|
-
The projection is a separate storage engine, so deleting the row from
|
|
230
|
-
SQLite reaches nothing there. An entity node left behind still carries the
|
|
231
|
-
name it was created with, which is exactly the thing an erasure was asked
|
|
232
|
-
to remove.
|
|
233
|
-
|
|
234
|
-
Returns False when a projection exists and refused, so a caller that
|
|
235
|
-
reports completeness can report this honestly. No projection at all is not
|
|
236
|
-
a failure -- there is nothing to remove.
|
|
237
|
-
"""
|
|
238
|
-
try:
|
|
239
|
-
from superlocalmemory.core.backend_orchestrator import get_orchestrator
|
|
240
|
-
except Exception: # noqa: BLE001
|
|
241
|
-
return True
|
|
242
|
-
try:
|
|
243
|
-
orchestrator = get_orchestrator()
|
|
244
|
-
graph = orchestrator.get_graph_backend() if orchestrator else None
|
|
245
|
-
if graph is None:
|
|
246
|
-
return True
|
|
247
|
-
remove = getattr(graph, "remove_entity", None)
|
|
248
|
-
if remove is None:
|
|
249
|
-
return True
|
|
250
|
-
remove(entity_id)
|
|
251
|
-
return True
|
|
252
|
-
except Exception as exc: # noqa: BLE001
|
|
253
|
-
logger.warning(
|
|
254
|
-
"the graph projection still holds entity %s (%s)", entity_id[:12], exc,
|
|
255
|
-
)
|
|
256
|
-
return False
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
class EntityResolver:
|
|
260
|
-
"""Resolves raw entity mentions to persisted canonical entities.
|
|
261
|
-
|
|
262
|
-
Every resolution is persisted — canonical entities and aliases are stored
|
|
263
|
-
immediately, ensuring downstream graph building and retrieval use the
|
|
264
|
-
resolved identities.
|
|
265
|
-
"""
|
|
266
|
-
|
|
267
|
-
def __init__(
|
|
268
|
-
self,
|
|
269
|
-
db: DatabaseManager,
|
|
270
|
-
llm: LLMBackbone | None = None,
|
|
271
|
-
) -> None:
|
|
272
|
-
self._db = db
|
|
273
|
-
self._llm = llm
|
|
274
|
-
|
|
275
|
-
# -- Public API ---------------------------------------------------------
|
|
276
|
-
|
|
277
|
-
def resolve(
|
|
278
|
-
self,
|
|
279
|
-
raw_entities: list[str],
|
|
280
|
-
profile_id: str,
|
|
281
|
-
) -> dict[str, str]:
|
|
282
|
-
"""Resolve raw mentions to canonical entity IDs.
|
|
283
|
-
|
|
284
|
-
Returns mapping: raw_name -> canonical entity_id.
|
|
285
|
-
All new entities and aliases are persisted before returning.
|
|
286
|
-
"""
|
|
287
|
-
if not raw_entities:
|
|
288
|
-
return {}
|
|
289
|
-
|
|
290
|
-
resolution: dict[str, str] = {}
|
|
291
|
-
candidates_for_llm: list[str] = []
|
|
292
|
-
|
|
293
|
-
for raw in raw_entities:
|
|
294
|
-
name = raw.strip()
|
|
295
|
-
if not name or name.lower() in PRONOUNS:
|
|
296
|
-
continue
|
|
297
|
-
|
|
298
|
-
# Skip very short/long entities
|
|
299
|
-
if len(name) <= 2 or len(name) > 100:
|
|
300
|
-
continue
|
|
301
|
-
|
|
302
|
-
# Skip single-word stop words
|
|
303
|
-
words = name.lower().split()
|
|
304
|
-
if len(words) == 1 and name.lower() in _COMMON_WORDS:
|
|
305
|
-
continue
|
|
306
|
-
|
|
307
|
-
# Skip multi-word entities where ALL words are stop words or <=2 chars
|
|
308
|
-
if len(words) > 1 and all(w in _COMMON_WORDS or len(w) <= 2 for w in words):
|
|
309
|
-
continue
|
|
310
|
-
|
|
311
|
-
# Skip pure numbers/versions
|
|
312
|
-
if re.match(r"^[\d.v\-/]+$", name):
|
|
313
|
-
continue
|
|
314
|
-
|
|
315
|
-
# Tier a: exact match on canonical_name
|
|
316
|
-
entity = self._db.get_entity_by_name(name, profile_id)
|
|
317
|
-
if entity is not None:
|
|
318
|
-
resolution[raw] = entity.entity_id
|
|
319
|
-
self._touch_last_seen(entity.entity_id, profile_id)
|
|
320
|
-
continue
|
|
321
|
-
|
|
322
|
-
# Tier b: alias match (case-insensitive, indexed)
|
|
323
|
-
entity_id = self._alias_lookup(name, profile_id)
|
|
324
|
-
if entity_id is not None:
|
|
325
|
-
resolution[raw] = entity_id
|
|
326
|
-
self._touch_last_seen(entity_id, profile_id)
|
|
327
|
-
continue
|
|
328
|
-
|
|
329
|
-
# Tier c: fuzzy match via Jaro-Winkler
|
|
330
|
-
match_id, score = self._fuzzy_match(name, profile_id)
|
|
331
|
-
if match_id is not None and score >= JARO_WINKLER_AUTO_MERGE:
|
|
332
|
-
resolution[raw] = match_id
|
|
333
|
-
self._persist_alias(match_id, name, score, "jaro_winkler", profile_id)
|
|
334
|
-
self._touch_last_seen(match_id, profile_id)
|
|
335
|
-
continue
|
|
336
|
-
|
|
337
|
-
# Candidate zone (0.70–0.85): queue for LLM in Mode B/C
|
|
338
|
-
if match_id is not None and score >= JARO_WINKLER_LLM_FLOOR:
|
|
339
|
-
candidates_for_llm.append(raw)
|
|
340
|
-
continue
|
|
341
|
-
|
|
342
|
-
# No match at all — create new entity
|
|
343
|
-
new_id = self._create_entity(name, profile_id)
|
|
344
|
-
resolution[raw] = new_id
|
|
345
|
-
|
|
346
|
-
# Tier d: LLM disambiguation for fuzzy candidates (Mode B/C)
|
|
347
|
-
if candidates_for_llm and self._llm is not None:
|
|
348
|
-
llm_resolved = self._llm_disambiguate(
|
|
349
|
-
candidates_for_llm, profile_id,
|
|
350
|
-
)
|
|
351
|
-
for raw_name, entity_id in llm_resolved.items():
|
|
352
|
-
resolution[raw_name] = entity_id
|
|
353
|
-
|
|
354
|
-
# Create new entities for candidates LLM couldn't resolve
|
|
355
|
-
for raw_name in candidates_for_llm:
|
|
356
|
-
if raw_name not in resolution:
|
|
357
|
-
new_id = self._create_entity(raw_name.strip(), profile_id)
|
|
358
|
-
resolution[raw_name] = new_id
|
|
359
|
-
elif candidates_for_llm:
|
|
360
|
-
# No LLM available — create new entities for all candidates
|
|
361
|
-
for raw_name in candidates_for_llm:
|
|
362
|
-
new_id = self._create_entity(raw_name.strip(), profile_id)
|
|
363
|
-
resolution[raw_name] = new_id
|
|
364
|
-
|
|
365
|
-
return resolution
|
|
366
|
-
|
|
367
|
-
def create_speaker_entities(
|
|
368
|
-
self,
|
|
369
|
-
speaker_a: str,
|
|
370
|
-
speaker_b: str,
|
|
371
|
-
profile_id: str,
|
|
372
|
-
) -> None:
|
|
373
|
-
"""Pre-create canonical entities for conversation speakers.
|
|
374
|
-
|
|
375
|
-
Called at session start so that speaker names are immediately
|
|
376
|
-
resolvable during fact extraction. Fixes B03 (speaker entities
|
|
377
|
-
not available during first-turn encoding).
|
|
378
|
-
"""
|
|
379
|
-
for speaker in (speaker_a, speaker_b):
|
|
380
|
-
name = speaker.strip()
|
|
381
|
-
if not name or name.lower() in PRONOUNS:
|
|
382
|
-
continue
|
|
383
|
-
existing = self._db.get_entity_by_name(name, profile_id)
|
|
384
|
-
if existing is None:
|
|
385
|
-
self._create_entity(name, profile_id, entity_type="person")
|
|
386
|
-
|
|
387
|
-
def get_canonical_name(self, raw_name: str, profile_id: str) -> str:
|
|
388
|
-
"""Quick lookup: returns canonical name or original if not found."""
|
|
389
|
-
name = raw_name.strip()
|
|
390
|
-
if not name:
|
|
391
|
-
return raw_name
|
|
392
|
-
|
|
393
|
-
entity = self._db.get_entity_by_name(name, profile_id)
|
|
394
|
-
if entity is not None:
|
|
395
|
-
return entity.canonical_name
|
|
396
|
-
|
|
397
|
-
entity_id = self._alias_lookup(name, profile_id)
|
|
398
|
-
if entity_id is not None:
|
|
399
|
-
rows = self._db.execute(
|
|
400
|
-
"SELECT canonical_name FROM canonical_entities WHERE entity_id = ?",
|
|
401
|
-
(entity_id,),
|
|
402
|
-
)
|
|
403
|
-
if rows:
|
|
404
|
-
return str(dict(rows[0])["canonical_name"])
|
|
405
|
-
|
|
406
|
-
return raw_name
|
|
407
|
-
|
|
408
|
-
def merge_entities(
|
|
409
|
-
self,
|
|
410
|
-
entity_id_keep: str,
|
|
411
|
-
entity_id_merge: str,
|
|
412
|
-
profile_id: str,
|
|
413
|
-
) -> None:
|
|
414
|
-
"""Merge two entities: move all aliases and facts to keep, delete merge.
|
|
415
|
-
|
|
416
|
-
Reassigns aliases, updates canonical_entities_json in atomic_facts,
|
|
417
|
-
and removes the merged entity record.
|
|
418
|
-
"""
|
|
419
|
-
# Move aliases from merge -> keep
|
|
420
|
-
aliases = self._db.get_aliases_for_entity(entity_id_merge, profile_id)
|
|
421
|
-
for alias in aliases:
|
|
422
|
-
new_alias = EntityAlias(
|
|
423
|
-
alias_id=_new_id(),
|
|
424
|
-
entity_id=entity_id_keep,
|
|
425
|
-
alias=alias.alias,
|
|
426
|
-
confidence=alias.confidence,
|
|
427
|
-
source=f"merge_from:{entity_id_merge}",
|
|
428
|
-
)
|
|
429
|
-
self._db.store_alias(new_alias, profile_id)
|
|
430
|
-
|
|
431
|
-
# Also add the merged entity's canonical name as an alias of keep
|
|
432
|
-
merged = self._db.get_entity_by_name("", "") # placeholder
|
|
433
|
-
rows = self._db.execute(
|
|
434
|
-
"SELECT canonical_name FROM canonical_entities WHERE entity_id = ?",
|
|
435
|
-
(entity_id_merge,),
|
|
436
|
-
)
|
|
437
|
-
if rows:
|
|
438
|
-
merged_name = str(dict(rows[0])["canonical_name"])
|
|
439
|
-
self._persist_alias(entity_id_keep, merged_name, 1.0, "merge", profile_id)
|
|
440
|
-
|
|
441
|
-
# Update atomic_facts: replace entity_id_merge with entity_id_keep
|
|
442
|
-
# in canonical_entities_json column
|
|
443
|
-
fact_rows = self._db.execute(
|
|
444
|
-
"SELECT fact_id, canonical_entities_json FROM atomic_facts "
|
|
445
|
-
"WHERE profile_id = ? AND canonical_entities_json LIKE ?",
|
|
446
|
-
(profile_id, f'%"{entity_id_merge}"%'),
|
|
447
|
-
)
|
|
448
|
-
for row in fact_rows:
|
|
449
|
-
d = dict(row)
|
|
450
|
-
try:
|
|
451
|
-
entities = json.loads(d["canonical_entities_json"])
|
|
452
|
-
updated = [
|
|
453
|
-
entity_id_keep if eid == entity_id_merge else eid
|
|
454
|
-
for eid in entities
|
|
455
|
-
]
|
|
456
|
-
# Deduplicate while preserving order
|
|
457
|
-
seen: set[str] = set()
|
|
458
|
-
deduped = []
|
|
459
|
-
for eid in updated:
|
|
460
|
-
if eid not in seen:
|
|
461
|
-
seen.add(eid)
|
|
462
|
-
deduped.append(eid)
|
|
463
|
-
self._db.execute(
|
|
464
|
-
"UPDATE atomic_facts SET canonical_entities_json = ? "
|
|
465
|
-
"WHERE fact_id = ?",
|
|
466
|
-
(json.dumps(deduped), d["fact_id"]),
|
|
467
|
-
)
|
|
468
|
-
except (json.JSONDecodeError, TypeError):
|
|
469
|
-
continue
|
|
470
|
-
|
|
471
|
-
# Delete the merged entity (tenant-scoped)
|
|
472
|
-
self._db.execute(
|
|
473
|
-
"DELETE FROM entity_aliases WHERE entity_id = ? AND profile_id = ?",
|
|
474
|
-
(entity_id_merge, profile_id),
|
|
475
|
-
)
|
|
476
|
-
self._db.execute(
|
|
477
|
-
"DELETE FROM canonical_entities WHERE entity_id = ? AND profile_id = ?",
|
|
478
|
-
(entity_id_merge, profile_id),
|
|
479
|
-
)
|
|
480
|
-
# The merged-away node has its own copy in the graph projection, and
|
|
481
|
-
# deleting the row above does not reach it. Left there it keeps its own
|
|
482
|
-
# name and its own edges, so the two halves of a merged entity stay
|
|
483
|
-
# visible to a graph query as two entities.
|
|
484
|
-
_unproject_entity(entity_id_merge)
|
|
485
|
-
logger.info(
|
|
486
|
-
"Merged entity %s into %s (profile=%s)",
|
|
487
|
-
entity_id_merge, entity_id_keep, profile_id,
|
|
488
|
-
)
|
|
489
|
-
|
|
490
|
-
# -- Internal: lookups --------------------------------------------------
|
|
491
|
-
|
|
492
|
-
def _alias_lookup(self, name: str, profile_id: str) -> str | None:
|
|
493
|
-
"""Look up entity_id via alias table (case-insensitive)."""
|
|
494
|
-
rows = self._db.execute(
|
|
495
|
-
"SELECT ea.entity_id FROM entity_aliases ea "
|
|
496
|
-
"JOIN canonical_entities ce ON ce.entity_id = ea.entity_id "
|
|
497
|
-
"WHERE LOWER(ea.alias) = LOWER(?) AND ce.profile_id = ?",
|
|
498
|
-
(name, profile_id),
|
|
499
|
-
)
|
|
500
|
-
if rows:
|
|
501
|
-
return str(dict(rows[0])["entity_id"])
|
|
502
|
-
return None
|
|
503
|
-
|
|
504
|
-
def _fuzzy_match(
|
|
505
|
-
self, name: str, profile_id: str,
|
|
506
|
-
) -> tuple[str | None, float]:
|
|
507
|
-
"""Scan all canonical names + aliases for best Jaro-Winkler match.
|
|
508
|
-
|
|
509
|
-
Returns (entity_id, score) or (None, 0.0).
|
|
510
|
-
"""
|
|
511
|
-
best_id: str | None = None
|
|
512
|
-
best_score: float = 0.0
|
|
513
|
-
name_lower = name.lower()
|
|
514
|
-
|
|
515
|
-
# Check canonical names
|
|
516
|
-
rows = self._db.execute(
|
|
517
|
-
"SELECT entity_id, canonical_name FROM canonical_entities "
|
|
518
|
-
"WHERE profile_id = ?",
|
|
519
|
-
(profile_id,),
|
|
520
|
-
)
|
|
521
|
-
for row in rows:
|
|
522
|
-
d = dict(row)
|
|
523
|
-
score = jaro_winkler(name_lower, d["canonical_name"].lower())
|
|
524
|
-
if score > best_score:
|
|
525
|
-
best_score = score
|
|
526
|
-
best_id = d["entity_id"]
|
|
527
|
-
|
|
528
|
-
# Check aliases
|
|
529
|
-
alias_rows = self._db.execute(
|
|
530
|
-
"SELECT ea.entity_id, ea.alias FROM entity_aliases ea "
|
|
531
|
-
"JOIN canonical_entities ce ON ce.entity_id = ea.entity_id "
|
|
532
|
-
"WHERE ce.profile_id = ?",
|
|
533
|
-
(profile_id,),
|
|
534
|
-
)
|
|
535
|
-
for row in alias_rows:
|
|
536
|
-
d = dict(row)
|
|
537
|
-
score = jaro_winkler(name_lower, d["alias"].lower())
|
|
538
|
-
if score > best_score:
|
|
539
|
-
best_score = score
|
|
540
|
-
best_id = d["entity_id"]
|
|
541
|
-
|
|
542
|
-
return (best_id, best_score)
|
|
543
|
-
|
|
544
|
-
# -- Internal: persistence ----------------------------------------------
|
|
545
|
-
|
|
546
|
-
def _create_entity(
|
|
547
|
-
self,
|
|
548
|
-
name: str,
|
|
549
|
-
profile_id: str,
|
|
550
|
-
entity_type: str | None = None,
|
|
551
|
-
) -> str:
|
|
552
|
-
"""Create a new canonical entity + self-alias. Returns entity_id."""
|
|
553
|
-
etype = entity_type or _guess_entity_type(name)
|
|
554
|
-
now = _now()
|
|
555
|
-
entity = CanonicalEntity(
|
|
556
|
-
entity_id=_new_id(),
|
|
557
|
-
profile_id=profile_id,
|
|
558
|
-
canonical_name=name,
|
|
559
|
-
entity_type=etype,
|
|
560
|
-
first_seen=now,
|
|
561
|
-
last_seen=now,
|
|
562
|
-
fact_count=0,
|
|
563
|
-
)
|
|
564
|
-
self._db.store_entity(entity)
|
|
565
|
-
|
|
566
|
-
# Store name as its own alias for uniform lookup
|
|
567
|
-
self._persist_alias(entity.entity_id, name, 1.0, "canonical", profile_id)
|
|
568
|
-
|
|
569
|
-
logger.debug(
|
|
570
|
-
"Created entity '%s' [%s] (type=%s, profile=%s)",
|
|
571
|
-
name, entity.entity_id, etype, profile_id,
|
|
572
|
-
)
|
|
573
|
-
return entity.entity_id
|
|
574
|
-
|
|
575
|
-
def _persist_alias(
|
|
576
|
-
self,
|
|
577
|
-
entity_id: str,
|
|
578
|
-
alias_text: str,
|
|
579
|
-
confidence: float,
|
|
580
|
-
source: str,
|
|
581
|
-
profile_id: str,
|
|
582
|
-
) -> None:
|
|
583
|
-
"""Store an alias under a profile, skipping duplicates within it."""
|
|
584
|
-
# Check if alias already exists for this entity IN THIS PROFILE. The
|
|
585
|
-
# dedup must be profile-scoped or one profile's alias suppresses
|
|
586
|
-
# another profile's identical alias for a same-id entity.
|
|
587
|
-
existing = self._db.execute(
|
|
588
|
-
"SELECT alias_id FROM entity_aliases "
|
|
589
|
-
"WHERE entity_id = ? AND profile_id = ? AND LOWER(alias) = LOWER(?)",
|
|
590
|
-
(entity_id, profile_id, alias_text),
|
|
591
|
-
)
|
|
592
|
-
if existing:
|
|
593
|
-
return
|
|
594
|
-
alias = EntityAlias(
|
|
595
|
-
alias_id=_new_id(),
|
|
596
|
-
entity_id=entity_id,
|
|
597
|
-
alias=alias_text,
|
|
598
|
-
confidence=confidence,
|
|
599
|
-
source=source,
|
|
600
|
-
)
|
|
601
|
-
self._db.store_alias(alias, profile_id)
|
|
602
|
-
|
|
603
|
-
def _touch_last_seen(self, entity_id: str, profile_id: str = "default") -> None:
|
|
604
|
-
"""Record a last_seen touch (DEFERRED, non-blocking).
|
|
605
|
-
|
|
606
|
-
last_seen is dashboard-only bookkeeping (entities/graph "last seen"
|
|
607
|
-
columns); it never feeds recall ranking. Writing it INLINE made recall
|
|
608
|
-
a WRITER that waited on the global write lock — the root of the
|
|
609
|
-
"recall is 8 s" regression. We now record it in memory and flush from a
|
|
610
|
-
single background thread in coalesced batches, so recall stays
|
|
611
|
-
READ-ONLY on its hot path. The dashboard stays correct within the flush
|
|
612
|
-
interval (~2 s). The profile_id guard (L-01) is preserved in the
|
|
613
|
-
deferred UPDATE (see storage/deferred_writes.py).
|
|
614
|
-
"""
|
|
615
|
-
try:
|
|
616
|
-
from superlocalmemory.storage.deferred_writes import (
|
|
617
|
-
get_deferred_last_seen,
|
|
618
|
-
)
|
|
619
|
-
get_deferred_last_seen(self._db).touch(entity_id, profile_id, _now())
|
|
620
|
-
except Exception:
|
|
621
|
-
# Bookkeeping must never break entity resolution.
|
|
622
|
-
pass
|
|
623
|
-
|
|
624
|
-
# -- Internal: LLM disambiguation (Mode B/C) ---------------------------
|
|
625
|
-
|
|
626
|
-
def _llm_disambiguate(
|
|
627
|
-
self,
|
|
628
|
-
raw_names: list[str],
|
|
629
|
-
profile_id: str,
|
|
630
|
-
) -> dict[str, str]:
|
|
631
|
-
"""Ask LLM whether fuzzy candidates match existing entities."""
|
|
632
|
-
if not self._llm or not raw_names:
|
|
633
|
-
return {}
|
|
634
|
-
|
|
635
|
-
# Gather known entity names for context
|
|
636
|
-
rows = self._db.execute(
|
|
637
|
-
"SELECT entity_id, canonical_name FROM canonical_entities "
|
|
638
|
-
"WHERE profile_id = ? LIMIT 50",
|
|
639
|
-
(profile_id,),
|
|
640
|
-
)
|
|
641
|
-
known = {
|
|
642
|
-
str(dict(r)["canonical_name"]): str(dict(r)["entity_id"])
|
|
643
|
-
for r in rows
|
|
644
|
-
}
|
|
645
|
-
|
|
646
|
-
prompt = (
|
|
647
|
-
"Entity resolution task. For each mention, decide if it refers to "
|
|
648
|
-
"one of the known entities or is a new entity.\n\n"
|
|
649
|
-
f"Mentions to resolve: {raw_names}\n"
|
|
650
|
-
f"Known entities: {list(known.keys())}\n\n"
|
|
651
|
-
"Respond with ONLY a JSON object mapping each mention to a "
|
|
652
|
-
"known entity name if they match, or to itself if it is new.\n"
|
|
653
|
-
'Example: {"Ms. Smith": "Alice Smith", "Bob": "Bob"}'
|
|
654
|
-
)
|
|
655
|
-
|
|
656
|
-
try:
|
|
657
|
-
response = self._llm.generate(
|
|
658
|
-
prompt=prompt,
|
|
659
|
-
system="You are a precise entity resolution system.",
|
|
660
|
-
max_tokens=256,
|
|
661
|
-
temperature=0.0,
|
|
662
|
-
)
|
|
663
|
-
match = re.search(r"\{[^}]*\}", response)
|
|
664
|
-
if not match:
|
|
665
|
-
return {}
|
|
666
|
-
|
|
667
|
-
result = json.loads(match.group())
|
|
668
|
-
if not isinstance(result, dict):
|
|
669
|
-
return {}
|
|
670
|
-
|
|
671
|
-
resolved: dict[str, str] = {}
|
|
672
|
-
for mention, canonical_name in result.items():
|
|
673
|
-
mention_str = str(mention)
|
|
674
|
-
name_str = str(canonical_name)
|
|
675
|
-
if name_str in known:
|
|
676
|
-
entity_id = known[name_str]
|
|
677
|
-
resolved[mention_str] = entity_id
|
|
678
|
-
self._persist_alias(
|
|
679
|
-
entity_id, mention_str, 0.9, "llm", profile_id,
|
|
680
|
-
)
|
|
681
|
-
self._touch_last_seen(entity_id, profile_id)
|
|
682
|
-
# If LLM says it's itself, leave for caller to create
|
|
683
|
-
return resolved
|
|
684
|
-
|
|
685
|
-
except (json.JSONDecodeError, TypeError, Exception) as exc:
|
|
686
|
-
logger.warning("LLM entity disambiguation failed: %s", exc)
|
|
687
|
-
return {}
|