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,248 +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 — Query-Adaptive Strategy.
|
|
6
|
-
|
|
7
|
-
Classifies query type and returns per-type channel weights.
|
|
8
|
-
V1 had this code (strategy_learner.py) but never wired it in.
|
|
9
|
-
|
|
10
|
-
Part of Qualixar | Author: Varun Pratap Bhardwaj
|
|
11
|
-
License: AGPL-3.0-or-later
|
|
12
|
-
"""
|
|
13
|
-
from __future__ import annotations
|
|
14
|
-
|
|
15
|
-
import re
|
|
16
|
-
from dataclasses import dataclass, field
|
|
17
|
-
|
|
18
|
-
STRATEGY_PRESETS: dict[str, dict[str, float]] = {
|
|
19
|
-
"temporal": {"semantic": 0.8, "bm25": 1.5, "entity_graph": 0.8, "temporal": 2.0, "spreading_activation": 0.5, "hopfield": 0.5},
|
|
20
|
-
"multi_hop": {"semantic": 1.0, "bm25": 0.8, "entity_graph": 2.5, "temporal": 0.5, "spreading_activation": 2.0, "hopfield": 0.7},
|
|
21
|
-
"aggregation": {"semantic": 1.2, "bm25": 1.5, "entity_graph": 1.0, "temporal": 0.5, "spreading_activation": 0.8, "hopfield": 0.6},
|
|
22
|
-
"opinion": {"semantic": 1.8, "bm25": 0.6, "entity_graph": 0.8, "temporal": 0.3, "spreading_activation": 0.5, "hopfield": 0.5},
|
|
23
|
-
"factual": {"semantic": 1.2, "bm25": 1.4, "entity_graph": 1.0, "temporal": 0.6, "spreading_activation": 0.8, "hopfield": 0.8},
|
|
24
|
-
"entity": {"semantic": 1.0, "bm25": 1.2, "entity_graph": 3.0, "temporal": 0.5, "spreading_activation": 1.5, "hopfield": 0.9},
|
|
25
|
-
# A question about the present carries almost no topical information in its
|
|
26
|
-
# words: "what am I working on" matches anything containing "working",
|
|
27
|
-
# including a note from a month ago about a working tree. Word-matching was
|
|
28
|
-
# set to 1.5 here, ABOVE the 1.4 of the preset this one exists to replace,
|
|
29
|
-
# so the new path boosted the exact signal that caused the original failure.
|
|
30
|
-
# It is now the weakest signal, because for this question it is the least
|
|
31
|
-
# informative one; time is what the question is actually about.
|
|
32
|
-
"recency": {
|
|
33
|
-
"temporal": 2.5, "bm25": 0.7, "semantic": 1.2,
|
|
34
|
-
"entity_graph": 1.0, "spreading_activation": 0.8, "hopfield": 0.5,
|
|
35
|
-
},
|
|
36
|
-
"general": {},
|
|
37
|
-
"vague": {"semantic": 0.8, "bm25": 0.5, "entity_graph": 0.6, "temporal": 0.3, "spreading_activation": 1.5, "hopfield": 1.1},
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
_TEMPORAL_WORDS: frozenset[str] = frozenset({
|
|
41
|
-
"when", "date", "time", "year", "month", "ago", "before", "after",
|
|
42
|
-
"during", "last", "next", "recently", "earlier", "later", "since",
|
|
43
|
-
"until", "while", "between", "january", "february", "march",
|
|
44
|
-
"april", "may", "june", "july", "august", "september", "october",
|
|
45
|
-
"november", "december",
|
|
46
|
-
"now", "today", "yesterday",
|
|
47
|
-
"tonight", "tomorrow",
|
|
48
|
-
# "current" was removed earlier because "what is the current database schema"
|
|
49
|
-
# was being answered by newest-fact recency instead of topical search.
|
|
50
|
-
# "latest" and "currently" carry the same over-trigger: in "what is the
|
|
51
|
-
# latest authentication design" or "what is the currently supported format"
|
|
52
|
-
# they mean "most recent version of X", not "at what time did X happen".
|
|
53
|
-
# Routing those queries to temporal causes the recency fallback to dump the
|
|
54
|
-
# 50 newest facts with no topic filter at temporal weight 2.0, burying the
|
|
55
|
-
# subject the user named. Present-activity phrases ("currently working",
|
|
56
|
-
# "currently doing", "currently focused") are covered by _RECENCY_PHRASES.
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
_MULTI_HOP_PHRASES: tuple[str, ...] = (
|
|
60
|
-
# Original 8 phrases
|
|
61
|
-
"and then", "after that", "because", "how did",
|
|
62
|
-
"as a result", "led to", "connection between", "relationship between",
|
|
63
|
-
# V3.3.19: LoCoMo-style multi-hop patterns (causal/temporal chains)
|
|
64
|
-
"what happened when", "what was happening",
|
|
65
|
-
"during the time", "at the same time",
|
|
66
|
-
"how did it affect", "what changed after",
|
|
67
|
-
"what did they do after", "what did they do before",
|
|
68
|
-
"what was the result", "what was the outcome",
|
|
69
|
-
"what was the reason", "why did they",
|
|
70
|
-
"in response to", "as a consequence",
|
|
71
|
-
"prior to", "following that", "subsequent to",
|
|
72
|
-
"in the meantime", "at that point",
|
|
73
|
-
"which led to", "which caused", "which resulted in",
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
# Words that signal causal/temporal chain when combined with 2+ entities.
|
|
77
|
-
# Excludes common instruction verbs (tell, help) to avoid false positives
|
|
78
|
-
# on queries like "Tell me about Alice and Bob".
|
|
79
|
-
_CAUSAL_TEMPORAL_WORDS: frozenset[str] = frozenset({
|
|
80
|
-
"before", "after", "when", "while", "because", "then",
|
|
81
|
-
"during", "since", "until", "once",
|
|
82
|
-
"affect", "cause", "change", "happen", "result",
|
|
83
|
-
"influence", "impact", "lead", "meet",
|
|
84
|
-
"start", "stop", "begin", "end", "move", "leave",
|
|
85
|
-
"join", "visit", "return",
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
# Phrases that signal a present-activity or ongoing-state question.
|
|
89
|
-
# Checked after multi_hop, entity and temporal word filters so retrospective
|
|
90
|
-
# queries ("what did I work on recently") do not short-circuit here.
|
|
91
|
-
# Order inside the tuple is irrelevant; all are substring-matched against the
|
|
92
|
-
# lowercased query.
|
|
93
|
-
_RECENCY_PHRASES: tuple[str, ...] = (
|
|
94
|
-
"working on",
|
|
95
|
-
"am i working", "are we working", "been working",
|
|
96
|
-
"what's happening", "what is happening",
|
|
97
|
-
"right now", "these days", "at the moment",
|
|
98
|
-
"currently doing", "currently working", "currently focused",
|
|
99
|
-
"what have i been", "what am i doing", "what have we been",
|
|
100
|
-
)
|
|
101
|
-
|
|
102
|
-
_AGGREGATION_WORDS: frozenset[str] = frozenset({
|
|
103
|
-
"all", "list", "every", "everything", "various", "different",
|
|
104
|
-
"many", "several", "multiple", "summarize", "overview",
|
|
105
|
-
# V3.3.21 R5: LoCoMo cat 1 patterns — "What X does/did Y Z?" needs aggregation.
|
|
106
|
-
# "What activities does Melanie partake in?" = aggregation, not factual.
|
|
107
|
-
"activities", "events", "hobbies", "instruments", "types",
|
|
108
|
-
"things", "places", "jobs", "skills", "interests", "pets",
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
# V3.3.21 R5: Plural noun patterns that signal aggregation queries.
|
|
112
|
-
# "What [noun]s has/does [entity] [verb]?" = needs cross-session aggregation.
|
|
113
|
-
_AGGREGATION_PATTERNS: tuple[str, ...] = (
|
|
114
|
-
r"what (?:\w+ )?(?:activities|events|hobbies|types|things|places|jobs)",
|
|
115
|
-
r"what (?:\w+ )?has .+ (?:done|visited|attended|participated|played|practiced)",
|
|
116
|
-
r"how many (?:\w+ )?(?:times|events|things|places)",
|
|
117
|
-
r"what are .+(?:'s|s') (?:\w+ )?(?:hobbies|interests|activities|skills)",
|
|
118
|
-
)
|
|
119
|
-
|
|
120
|
-
_OPINION_WORDS: tuple[str, ...] = (
|
|
121
|
-
"think", "feel", "opinion", "prefer", "favorite", "best", "worst",
|
|
122
|
-
"believe", "like about", "dislike", "enjoy", "hate", "love",
|
|
123
|
-
)
|
|
124
|
-
|
|
125
|
-
_VAGUE_PHRASES: tuple[str, ...] = (
|
|
126
|
-
"something about", "i think", "maybe", "not sure",
|
|
127
|
-
"vaguely remember", "partially recall", "sort of",
|
|
128
|
-
"kind of", "i forgot", "what was that",
|
|
129
|
-
)
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
@dataclass
|
|
133
|
-
class QueryStrategy:
|
|
134
|
-
"""Classified query type + adapted weights."""
|
|
135
|
-
query_type: str = "general"
|
|
136
|
-
weights: dict[str, float] = field(default_factory=dict)
|
|
137
|
-
confidence: float = 0.5
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
def _recency_enabled(config: object | None = None) -> bool:
|
|
142
|
-
"""Whether the present-tense path is switched on.
|
|
143
|
-
|
|
144
|
-
The env var SLM_DISABLE_RECENCY_STRATEGY=1 is checked first (incident
|
|
145
|
-
override). If unset, the RetrievalConfig.enable_recency_strategy field is
|
|
146
|
-
consulted when a config object is supplied. Defaults to on when neither
|
|
147
|
-
is present.
|
|
148
|
-
|
|
149
|
-
Kept as a module-level function so the classifier stays usable without an
|
|
150
|
-
engine, which is how the gate and several tests call it.
|
|
151
|
-
"""
|
|
152
|
-
import os
|
|
153
|
-
|
|
154
|
-
if os.environ.get("SLM_DISABLE_RECENCY_STRATEGY", "0") == "1":
|
|
155
|
-
return False
|
|
156
|
-
if config is not None and not getattr(config, "enable_recency_strategy", True):
|
|
157
|
-
return False
|
|
158
|
-
return True
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
class QueryStrategyClassifier:
|
|
162
|
-
"""Classifies queries and produces adaptive channel weights."""
|
|
163
|
-
|
|
164
|
-
def __init__(self, config: object | None = None) -> None:
|
|
165
|
-
"""Initialise the classifier.
|
|
166
|
-
|
|
167
|
-
Args:
|
|
168
|
-
config: Optional RetrievalConfig-like object. When supplied,
|
|
169
|
-
``enable_recency_strategy=False`` on that object acts as a
|
|
170
|
-
persistent rollback without requiring an env var change.
|
|
171
|
-
The env var SLM_DISABLE_RECENCY_STRATEGY=1 always takes
|
|
172
|
-
precedence.
|
|
173
|
-
"""
|
|
174
|
-
self._config = config
|
|
175
|
-
|
|
176
|
-
def classify(self, query: str, base_weights: dict[str, float]) -> QueryStrategy:
|
|
177
|
-
"""Classify query and return adapted weights."""
|
|
178
|
-
qtype = self._detect_type(query)
|
|
179
|
-
adapted = dict(base_weights)
|
|
180
|
-
for ch, w in STRATEGY_PRESETS.get(qtype, {}).items():
|
|
181
|
-
adapted[ch] = base_weights.get(ch, 1.0) * w
|
|
182
|
-
return QueryStrategy(qtype, adapted, 0.7 if qtype != "general" else 0.5)
|
|
183
|
-
|
|
184
|
-
def _detect_type(self, query: str) -> str:
|
|
185
|
-
q = query.lower()
|
|
186
|
-
# Strip punctuation from words so "january?" matches "january"
|
|
187
|
-
words = set(re.sub(r"[^\w\s'-]", "", q).split())
|
|
188
|
-
|
|
189
|
-
# Check multi_hop phrases FIRST (exact phrase match)
|
|
190
|
-
if any(p in q for p in _MULTI_HOP_PHRASES):
|
|
191
|
-
return "multi_hop"
|
|
192
|
-
|
|
193
|
-
# Extract proper nouns EARLY for the multi-entity heuristic
|
|
194
|
-
_SENTENCE_STARTERS = {"What", "Where", "Who", "Which", "How", "When",
|
|
195
|
-
"Does", "Did", "Can", "Could", "Would", "Should",
|
|
196
|
-
"Are", "Is", "Was", "Were", "Has", "Have", "The", "Tell"}
|
|
197
|
-
proper_nouns = [m for m in re.findall(r"\b[A-Z][a-z]{1,}\b", query)
|
|
198
|
-
if m not in _SENTENCE_STARTERS]
|
|
199
|
-
|
|
200
|
-
# V3.3.19: 2+ entities + causal/temporal word → multi_hop
|
|
201
|
-
# This MUST fire BEFORE the temporal check, otherwise "What did
|
|
202
|
-
# Alice study before moving to New York?" would classify as
|
|
203
|
-
# "temporal" instead of "multi_hop".
|
|
204
|
-
if len(proper_nouns) >= 2 and words & _CAUSAL_TEMPORAL_WORDS:
|
|
205
|
-
return "multi_hop"
|
|
206
|
-
|
|
207
|
-
# Checked BEFORE the single-word test below. "what am I working on right
|
|
208
|
-
# now" contains "now", so the word test claimed it first and routed a
|
|
209
|
-
# question about the present down the retrospective path — which weights
|
|
210
|
-
# word-matching at 1.5 against this path's 0.7, and word-matching on
|
|
211
|
-
# "working" is exactly what surfaced a month-old note about a working
|
|
212
|
-
# tree. A whole phrase states intent; a single word only hints at it.
|
|
213
|
-
#
|
|
214
|
-
# The enable_recency_strategy config field and SLM_DISABLE_RECENCY_STRATEGY
|
|
215
|
-
# env var both feed into _recency_enabled(). When either signals disabled,
|
|
216
|
-
# this block is skipped and the query falls through to subsequent checks.
|
|
217
|
-
if _recency_enabled(self._config) and any(p in q for p in _RECENCY_PHRASES):
|
|
218
|
-
return "recency"
|
|
219
|
-
if words & _TEMPORAL_WORDS:
|
|
220
|
-
return "temporal"
|
|
221
|
-
if words & _AGGREGATION_WORDS:
|
|
222
|
-
return "aggregation"
|
|
223
|
-
# V3.3.21 R5: Regex patterns for aggregation questions
|
|
224
|
-
if any(re.search(p, q) for p in _AGGREGATION_PATTERNS):
|
|
225
|
-
return "aggregation"
|
|
226
|
-
if any(w in q for w in _OPINION_WORDS):
|
|
227
|
-
return "opinion"
|
|
228
|
-
if len(proper_nouns) >= 2:
|
|
229
|
-
return "entity"
|
|
230
|
-
if q.startswith(("what ", "where ", "who ", "which ", "how ")):
|
|
231
|
-
return "factual"
|
|
232
|
-
# Vague/fuzzy recall — Hopfield pattern completion excels here
|
|
233
|
-
if any(p in q for p in _VAGUE_PHRASES):
|
|
234
|
-
return "vague"
|
|
235
|
-
return "general"
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
_DEFAULT_CLASSIFIER = QueryStrategyClassifier()
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
def classify_query(query: str, base_weights: dict[str, float] | None = None) -> QueryStrategy:
|
|
242
|
-
"""Classify a query and return adapted channel weights.
|
|
243
|
-
|
|
244
|
-
Convenience function for callers that do not maintain a classifier instance.
|
|
245
|
-
Uses an empty weight dict when base_weights is omitted, which leaves
|
|
246
|
-
absolute weights undefined — useful for type-detection only.
|
|
247
|
-
"""
|
|
248
|
-
return _DEFAULT_CLASSIFIER.classify(query, base_weights or {})
|
|
@@ -1,433 +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 — Temporal Retrieval Channel (3-Date Model).
|
|
6
|
-
|
|
7
|
-
Searches by referenced_date (NOT just created_at like V1).
|
|
8
|
-
Returns empty when query has no temporal signal (no recency noise).
|
|
9
|
-
|
|
10
|
-
Part of Qualixar | Author: Varun Pratap Bhardwaj
|
|
11
|
-
License: AGPL-3.0-or-later
|
|
12
|
-
"""
|
|
13
|
-
from __future__ import annotations
|
|
14
|
-
|
|
15
|
-
import logging
|
|
16
|
-
import math
|
|
17
|
-
from datetime import datetime, timezone
|
|
18
|
-
from typing import TYPE_CHECKING
|
|
19
|
-
|
|
20
|
-
from dateutil.parser import ParserError, parse as dateutil_parse
|
|
21
|
-
|
|
22
|
-
from superlocalmemory.encoding.temporal_parser import TemporalParser
|
|
23
|
-
from superlocalmemory.storage.database import _scope_where
|
|
24
|
-
|
|
25
|
-
if TYPE_CHECKING:
|
|
26
|
-
from superlocalmemory.storage.database import DatabaseManager
|
|
27
|
-
|
|
28
|
-
logger = logging.getLogger(__name__)
|
|
29
|
-
|
|
30
|
-
_MAX_PROXIMITY_DAYS: float = 365.0
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
def _as_utc(dt: datetime | None) -> datetime | None:
|
|
34
|
-
"""Coerce a datetime to timezone-aware UTC (naive values are assumed UTC).
|
|
35
|
-
|
|
36
|
-
Keeps proximity and interval comparisons from mixing naive and aware values.
|
|
37
|
-
"""
|
|
38
|
-
if dt is None:
|
|
39
|
-
return None
|
|
40
|
-
if dt.tzinfo is None:
|
|
41
|
-
return dt.replace(tzinfo=timezone.utc)
|
|
42
|
-
return dt.astimezone(timezone.utc)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
def _parse_iso(s: str | None) -> datetime | None:
|
|
46
|
-
if not s:
|
|
47
|
-
return None
|
|
48
|
-
# v3.5.0 perf: stored dates are ISO-8601, so try the C-level
|
|
49
|
-
# datetime.fromisoformat (~1µs) FIRST. dateutil.parser.parse is ~100x
|
|
50
|
-
# slower (~100µs) and the temporal channel parses up to 4 dates per event
|
|
51
|
-
# across thousands of events — that was ~2.6s of the recall. dateutil is
|
|
52
|
-
# now only the fallback for non-ISO strings.
|
|
53
|
-
try:
|
|
54
|
-
return _as_utc(datetime.fromisoformat(s.replace("Z", "+00:00")))
|
|
55
|
-
except (ValueError, TypeError):
|
|
56
|
-
pass
|
|
57
|
-
try:
|
|
58
|
-
return _as_utc(dateutil_parse(s))
|
|
59
|
-
except (ParserError, ValueError, OverflowError, TypeError):
|
|
60
|
-
return None
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
def _proximity_score(q: datetime, e: datetime) -> float:
|
|
64
|
-
"""Gaussian proximity: same day=1.0, 30d=0.61, 90d=0.11."""
|
|
65
|
-
dist = abs((q - e).total_seconds()) / 86400.0
|
|
66
|
-
if dist > _MAX_PROXIMITY_DAYS:
|
|
67
|
-
return 0.0
|
|
68
|
-
return math.exp(-(dist * dist) / (2.0 * 30.0 * 30.0))
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
class TemporalChannel:
|
|
72
|
-
"""Date-aware retrieval using the 3-date temporal model."""
|
|
73
|
-
|
|
74
|
-
def __init__(self, db: DatabaseManager) -> None:
|
|
75
|
-
self._db = db
|
|
76
|
-
|
|
77
|
-
def search(
|
|
78
|
-
self,
|
|
79
|
-
query: str,
|
|
80
|
-
profile_id: str,
|
|
81
|
-
top_k: int = 30,
|
|
82
|
-
include_global: bool | None = None,
|
|
83
|
-
include_shared: bool | None = None,
|
|
84
|
-
query_type: str = "general",
|
|
85
|
-
) -> list[tuple[str, float]]:
|
|
86
|
-
"""Search for temporally relevant facts.
|
|
87
|
-
|
|
88
|
-
Two strategies:
|
|
89
|
-
1. Date proximity: scores events by date closeness to query date.
|
|
90
|
-
2. Entity-temporal: filters events by entity name in query,
|
|
91
|
-
returns ALL their temporal facts (metadata-first approach).
|
|
92
|
-
|
|
93
|
-
Returns empty only when query has no temporal signal AND no
|
|
94
|
-
entity-temporal matches.
|
|
95
|
-
|
|
96
|
-
Args:
|
|
97
|
-
include_global: Include global-scope facts. Falls back to the
|
|
98
|
-
instance attribute when not supplied.
|
|
99
|
-
include_shared: Include shared-scope facts. Same fallback.
|
|
100
|
-
"""
|
|
101
|
-
if include_global is None:
|
|
102
|
-
include_global = bool(getattr(self, "include_global", False))
|
|
103
|
-
if include_shared is None:
|
|
104
|
-
include_shared = bool(getattr(self, "include_shared", False))
|
|
105
|
-
|
|
106
|
-
parser = TemporalParser()
|
|
107
|
-
dates = parser.extract_dates_from_text(query)
|
|
108
|
-
query_dt = _parse_iso(dates.get("referenced_date"))
|
|
109
|
-
if query_dt is None:
|
|
110
|
-
query_dt = self._try_parse(query)
|
|
111
|
-
query_dt = _as_utc(query_dt)
|
|
112
|
-
|
|
113
|
-
# Strategy 1: Entity-temporal metadata search
|
|
114
|
-
# "When did Alice...?" → find all temporal events for Alice
|
|
115
|
-
entity_results = self._entity_temporal_search(
|
|
116
|
-
query, profile_id,
|
|
117
|
-
include_global=include_global, include_shared=include_shared,
|
|
118
|
-
)
|
|
119
|
-
|
|
120
|
-
# Strategy 2: Date proximity search
|
|
121
|
-
if query_dt is None:
|
|
122
|
-
recent: list[tuple[str, float]] = []
|
|
123
|
-
# For a question that IS about the present ("what am I working on"),
|
|
124
|
-
# recency is the answer, and it runs regardless of what else matched.
|
|
125
|
-
# It used to sit inside a guard that also required the entity search
|
|
126
|
-
# to be empty — inherited from the case where there is simply nothing
|
|
127
|
-
# to do — so on a real store, where something almost always matches,
|
|
128
|
-
# it effectively never ran.
|
|
129
|
-
#
|
|
130
|
-
# For a merely time-FLAVOURED question ("what is the latest
|
|
131
|
-
# authentication design"), recency is a last resort, not the answer:
|
|
132
|
-
# this channel returns up to 50 newest facts with no regard for topic,
|
|
133
|
-
# and at temporal's weight of 2.0 that buries the very subject the
|
|
134
|
-
# user named. So there it runs only when nothing else matched at all.
|
|
135
|
-
if query_type == "recency" or (
|
|
136
|
-
query_type == "temporal" and not entity_results
|
|
137
|
-
):
|
|
138
|
-
recent = self._recency_fallback(
|
|
139
|
-
profile_id,
|
|
140
|
-
include_global=include_global,
|
|
141
|
-
include_shared=include_shared,
|
|
142
|
-
)
|
|
143
|
-
if not entity_results:
|
|
144
|
-
return recent
|
|
145
|
-
if recent:
|
|
146
|
-
# Both signals are real: an entity the question named, and the
|
|
147
|
-
# fact that the question is about now. Recency leads because
|
|
148
|
-
# that is what this channel was asked about; entity matches
|
|
149
|
-
# follow, and anything already present keeps its better place.
|
|
150
|
-
seen = {fid for fid, _ in recent}
|
|
151
|
-
return recent + [(f, s) for f, s in entity_results if f not in seen]
|
|
152
|
-
|
|
153
|
-
events = self._load_events(
|
|
154
|
-
profile_id, include_global=include_global, include_shared=include_shared,
|
|
155
|
-
near_date=query_dt.date().isoformat() if query_dt is not None else None,
|
|
156
|
-
)
|
|
157
|
-
scored: dict[str, float] = {}
|
|
158
|
-
|
|
159
|
-
# Include entity-temporal results with high base score
|
|
160
|
-
for fid, score in entity_results:
|
|
161
|
-
scored[fid] = max(scored.get(fid, 0.0), score)
|
|
162
|
-
|
|
163
|
-
if query_dt is not None:
|
|
164
|
-
for ev in events:
|
|
165
|
-
best = 0.0
|
|
166
|
-
ref = _parse_iso(ev.get("referenced_date"))
|
|
167
|
-
if ref is not None:
|
|
168
|
-
best = max(best, _proximity_score(query_dt, ref))
|
|
169
|
-
|
|
170
|
-
obs = _parse_iso(ev.get("observation_date"))
|
|
171
|
-
if obs is not None:
|
|
172
|
-
best = max(best, _proximity_score(query_dt, obs) * 0.8)
|
|
173
|
-
|
|
174
|
-
i_start = _parse_iso(ev.get("interval_start"))
|
|
175
|
-
i_end = _parse_iso(ev.get("interval_end"))
|
|
176
|
-
if i_start and i_end:
|
|
177
|
-
if i_start <= query_dt <= i_end:
|
|
178
|
-
best = max(best, 1.0)
|
|
179
|
-
else:
|
|
180
|
-
best = max(best, max(
|
|
181
|
-
_proximity_score(query_dt, i_start),
|
|
182
|
-
_proximity_score(query_dt, i_end),
|
|
183
|
-
) * 0.9)
|
|
184
|
-
|
|
185
|
-
if best > 0.0:
|
|
186
|
-
fid = ev["fact_id"]
|
|
187
|
-
scored[fid] = max(scored.get(fid, 0.0), best)
|
|
188
|
-
|
|
189
|
-
results = sorted(scored.items(), key=lambda x: (-x[1], x[0]))
|
|
190
|
-
return results[:top_k]
|
|
191
|
-
|
|
192
|
-
def _entity_temporal_search(
|
|
193
|
-
self,
|
|
194
|
-
query: str,
|
|
195
|
-
profile_id: str,
|
|
196
|
-
include_global: bool | None = None,
|
|
197
|
-
include_shared: bool | None = None,
|
|
198
|
-
) -> list[tuple[str, float]]:
|
|
199
|
-
"""Metadata-first: find temporal events for entities mentioned in query.
|
|
200
|
-
|
|
201
|
-
"When did Alice do X?" → SQL filter by entity_id for Alice → return
|
|
202
|
-
all temporal facts about Alice. High precision for entity+time queries.
|
|
203
|
-
"""
|
|
204
|
-
if include_global is None:
|
|
205
|
-
include_global = bool(getattr(self, "include_global", False))
|
|
206
|
-
if include_shared is None:
|
|
207
|
-
include_shared = bool(getattr(self, "include_shared", False))
|
|
208
|
-
import re
|
|
209
|
-
_PROPER_RE = re.compile(r"\b([A-Z][a-z]+)\b")
|
|
210
|
-
names = [m.group(1) for m in _PROPER_RE.finditer(query)]
|
|
211
|
-
# Also try title-cased version for lowercase queries
|
|
212
|
-
if not names:
|
|
213
|
-
names = [m.group(1) for m in _PROPER_RE.finditer(query.title())]
|
|
214
|
-
# Filter out common words from title-casing
|
|
215
|
-
_stop = {"What", "When", "Where", "Who", "Which", "How", "Does", "Did",
|
|
216
|
-
"The", "That", "This", "There", "Then", "Have", "Has", "Had",
|
|
217
|
-
"About", "After", "Before", "From", "With", "Would", "Could",
|
|
218
|
-
"Should", "Will", "Because", "Also", "Just", "Like", "Know",
|
|
219
|
-
"Think", "Tell", "Said"}
|
|
220
|
-
names = [n for n in names if n not in _stop]
|
|
221
|
-
if not names:
|
|
222
|
-
return []
|
|
223
|
-
|
|
224
|
-
results: list[tuple[str, float]] = []
|
|
225
|
-
seen: set[str] = set()
|
|
226
|
-
where, params = _scope_where(
|
|
227
|
-
profile_id,
|
|
228
|
-
include_global=include_global,
|
|
229
|
-
include_shared=include_shared,
|
|
230
|
-
prefix="af",
|
|
231
|
-
)
|
|
232
|
-
|
|
233
|
-
for name in names[:3]: # Limit to first 3 entity mentions
|
|
234
|
-
# An empty name would match the placeholder entity that dated
|
|
235
|
-
# facts with no resolved entity attach their temporal events to
|
|
236
|
-
# (core/store_pipeline.py::_ensure_unresolved_entity, whose
|
|
237
|
-
# canonical_name is ''). Entity extraction does not produce an
|
|
238
|
-
# empty name, so this guard costs nothing and removes the one way
|
|
239
|
-
# the placeholder could ever surface as a real entity match.
|
|
240
|
-
if not name or not name.strip():
|
|
241
|
-
continue
|
|
242
|
-
# Resolve the entity and event in one scope-filtered query. Looking
|
|
243
|
-
# up the entity only in the requester's profile made global events
|
|
244
|
-
# owned by another profile undiscoverable before authorization was
|
|
245
|
-
# even evaluated.
|
|
246
|
-
rows = self._db.execute(
|
|
247
|
-
"SELECT te.fact_id FROM temporal_events AS te "
|
|
248
|
-
"JOIN canonical_entities AS ce ON ce.entity_id = te.entity_id "
|
|
249
|
-
"JOIN atomic_facts AS af ON af.fact_id = te.fact_id "
|
|
250
|
-
f"WHERE {where} AND LOWER(ce.canonical_name) = LOWER(?) "
|
|
251
|
-
# The score below is derived from each row's POSITION in this
|
|
252
|
-
# result. Position must reflect temporal order so that the comment
|
|
253
|
-
# "first events more likely relevant" holds: oldest fact first,
|
|
254
|
-
# tie-broken by fact_id so two facts created in the same instant
|
|
255
|
-
# produce the same score on two runs.
|
|
256
|
-
"ORDER BY af.created_at ASC, te.fact_id ASC",
|
|
257
|
-
(*params, name),
|
|
258
|
-
)
|
|
259
|
-
for row in rows:
|
|
260
|
-
fid = dict(row)["fact_id"]
|
|
261
|
-
if fid not in seen:
|
|
262
|
-
seen.add(fid)
|
|
263
|
-
# Rank by position (first events more likely relevant) instead
|
|
264
|
-
# of flat 0.85 which loses discrimination
|
|
265
|
-
rank_score = 0.85 - len(seen) * 0.02
|
|
266
|
-
results.append((fid, max(0.3, rank_score)))
|
|
267
|
-
|
|
268
|
-
return results
|
|
269
|
-
|
|
270
|
-
def _load_events(
|
|
271
|
-
self,
|
|
272
|
-
profile_id: str,
|
|
273
|
-
include_global: bool | None = None,
|
|
274
|
-
include_shared: bool | None = None,
|
|
275
|
-
near_date: str | None = None,
|
|
276
|
-
) -> list[dict]:
|
|
277
|
-
"""Load a bounded slice of temporal events.
|
|
278
|
-
|
|
279
|
-
``near_date`` decides WHICH slice. Without it the newest events are
|
|
280
|
-
taken, which suits "what is recent". With it the events closest to that
|
|
281
|
-
date are taken, which is the only slice that can answer a question about
|
|
282
|
-
a particular time — the newest-first bound silently excluded anything
|
|
283
|
-
old, so a question about last year returned nothing rather than slowly.
|
|
284
|
-
"""
|
|
285
|
-
if include_global is None:
|
|
286
|
-
include_global = bool(getattr(self, "include_global", False))
|
|
287
|
-
if include_shared is None:
|
|
288
|
-
include_shared = bool(getattr(self, "include_shared", False))
|
|
289
|
-
where, params = _scope_where(
|
|
290
|
-
profile_id,
|
|
291
|
-
include_global=include_global,
|
|
292
|
-
include_shared=include_shared,
|
|
293
|
-
prefix="af",
|
|
294
|
-
)
|
|
295
|
-
# The bound has to match what the caller is looking for. Taking the
|
|
296
|
-
# newest 5,000 rows is right when the question is "what is recent", and
|
|
297
|
-
# wrong when it is "what happened in March 2024" — those events carry old
|
|
298
|
-
# rowids and were simply never loaded, so the answer was missing rather
|
|
299
|
-
# than slow. When a target date is known, bound by proximity to THAT date
|
|
300
|
-
# instead; the scan stays bounded either way.
|
|
301
|
-
if near_date is not None:
|
|
302
|
-
# Include events that carry only interval_start/interval_end with no
|
|
303
|
-
# referenced_date or observation_date. The original filter required
|
|
304
|
-
# at least one of the point-date columns to be non-NULL, which
|
|
305
|
-
# excluded duration events ("during March 2024") entirely. The
|
|
306
|
-
# ORDER BY now uses the best available date column so that duration
|
|
307
|
-
# events are ranked by their interval_start when no point date exists.
|
|
308
|
-
rows = self._db.execute(
|
|
309
|
-
"SELECT te.fact_id, te.observation_date, te.referenced_date, "
|
|
310
|
-
"te.interval_start, te.interval_end, af.created_at "
|
|
311
|
-
"FROM temporal_events AS te "
|
|
312
|
-
"JOIN atomic_facts AS af ON af.fact_id = te.fact_id "
|
|
313
|
-
f"WHERE {where} "
|
|
314
|
-
" AND (te.referenced_date IS NOT NULL "
|
|
315
|
-
" OR te.observation_date IS NOT NULL "
|
|
316
|
-
" OR te.interval_start IS NOT NULL) "
|
|
317
|
-
# Thousands of events can tie on the proximity expression when
|
|
318
|
-
# they share a date, and a tie with no secondary key is broken by
|
|
319
|
-
# storage order. That decides which of them survive the LIMIT.
|
|
320
|
-
"ORDER BY ABS(julianday(COALESCE(te.referenced_date, "
|
|
321
|
-
" te.observation_date, "
|
|
322
|
-
" te.interval_start)) "
|
|
323
|
-
" - julianday(?)) ASC, te.fact_id ASC "
|
|
324
|
-
"LIMIT 5000",
|
|
325
|
-
(*params, near_date),
|
|
326
|
-
)
|
|
327
|
-
else:
|
|
328
|
-
rows = self._db.execute(
|
|
329
|
-
"SELECT te.fact_id, te.observation_date, te.referenced_date, "
|
|
330
|
-
"te.interval_start, te.interval_end, af.created_at "
|
|
331
|
-
"FROM temporal_events AS te "
|
|
332
|
-
"JOIN atomic_facts AS af ON af.fact_id = te.fact_id "
|
|
333
|
-
f"WHERE {where} "
|
|
334
|
-
"ORDER BY te.rowid DESC LIMIT 5000",
|
|
335
|
-
(*params,),
|
|
336
|
-
)
|
|
337
|
-
return [dict(r) for r in rows]
|
|
338
|
-
|
|
339
|
-
def _recency_fallback(
|
|
340
|
-
self,
|
|
341
|
-
profile_id: str,
|
|
342
|
-
include_global: bool | None,
|
|
343
|
-
include_shared: bool | None,
|
|
344
|
-
) -> list[tuple[str, float]]:
|
|
345
|
-
"""Return recently created facts with Gaussian age-decay scoring.
|
|
346
|
-
|
|
347
|
-
Called when the query carries no date and the caller has said the
|
|
348
|
-
question is about the present. It deliberately does not depend on the
|
|
349
|
-
entity search being empty — requiring that made this unreachable on any
|
|
350
|
-
store where something matches, which is most of them.
|
|
351
|
-
|
|
352
|
-
One entry per fact. Facts scored here compete in fusion against semantic
|
|
353
|
-
and BM25 results, and fusion ranks facts, so repeating a fact spends
|
|
354
|
-
ranks without adding candidates.
|
|
355
|
-
|
|
356
|
-
Scoring: Gaussian with sigma=7 days. Facts older than 90 days score
|
|
357
|
-
below 0.01 and are excluded. Returns at most 50 (fact_id, score) pairs,
|
|
358
|
-
ordered highest-score first.
|
|
359
|
-
|
|
360
|
-
Source table: atomic_facts, not temporal_events. The materializer
|
|
361
|
-
populates temporal_events asynchronously and only for facts with both
|
|
362
|
-
canonical entities and resolved dates. A plain note written moments ago
|
|
363
|
-
never receives a temporal_events row until that background pass runs, so
|
|
364
|
-
a join against temporal_events makes newly written facts structurally
|
|
365
|
-
invisible here — exactly when the caller needs them most.
|
|
366
|
-
"""
|
|
367
|
-
_SIGMA = 7.0 # days — tighter than _proximity_score's 30d
|
|
368
|
-
_MAX_AGE_DAYS = 90.0 # cut-off: exp(-(90^2)/(2*7^2)) ≈ 0.0
|
|
369
|
-
now_dt = datetime.now(tz=timezone.utc)
|
|
370
|
-
|
|
371
|
-
if include_global is None:
|
|
372
|
-
include_global = bool(getattr(self, "include_global", False))
|
|
373
|
-
if include_shared is None:
|
|
374
|
-
include_shared = bool(getattr(self, "include_shared", False))
|
|
375
|
-
where, params = _scope_where(
|
|
376
|
-
profile_id,
|
|
377
|
-
include_global=include_global,
|
|
378
|
-
include_shared=include_shared,
|
|
379
|
-
prefix="af",
|
|
380
|
-
)
|
|
381
|
-
# The recency fallback is where these rows won before: they have no
|
|
382
|
-
# temporal_events at all, so they reached the top through created_at
|
|
383
|
-
# alone. Fifty slots, and 1,195 withheld rows all written recently.
|
|
384
|
-
rows = self._db.execute(
|
|
385
|
-
"SELECT af.fact_id, af.created_at "
|
|
386
|
-
"FROM atomic_facts AS af "
|
|
387
|
-
f"WHERE {where}"
|
|
388
|
-
f"{self._db.visible_fact_clause('af')} "
|
|
389
|
-
" AND af.created_at >= datetime('now', '-90 days') "
|
|
390
|
-
"ORDER BY af.created_at DESC, af.fact_id ASC "
|
|
391
|
-
"LIMIT 50",
|
|
392
|
-
(*params,),
|
|
393
|
-
)
|
|
394
|
-
|
|
395
|
-
best: dict[str, float] = {}
|
|
396
|
-
for row in rows:
|
|
397
|
-
d = dict(row)
|
|
398
|
-
fid = d.get("fact_id")
|
|
399
|
-
if not fid:
|
|
400
|
-
continue
|
|
401
|
-
created = _parse_iso(d.get("created_at"))
|
|
402
|
-
if created is None:
|
|
403
|
-
continue
|
|
404
|
-
utc_created = _as_utc(created)
|
|
405
|
-
if utc_created is None:
|
|
406
|
-
continue
|
|
407
|
-
age_days = max(
|
|
408
|
-
0.0,
|
|
409
|
-
(now_dt - utc_created).total_seconds() / 86400.0,
|
|
410
|
-
)
|
|
411
|
-
if age_days > _MAX_AGE_DAYS:
|
|
412
|
-
continue
|
|
413
|
-
score = math.exp(-(age_days ** 2) / (2.0 * _SIGMA * _SIGMA))
|
|
414
|
-
if score > 0.01 and score > best.get(fid, 0.0):
|
|
415
|
-
best[fid] = score
|
|
416
|
-
|
|
417
|
-
out = sorted(best.items(), key=lambda kv: (-kv[1], kv[0]))
|
|
418
|
-
return out[:50]
|
|
419
|
-
|
|
420
|
-
@staticmethod
|
|
421
|
-
def _try_parse(text: str) -> datetime | None:
|
|
422
|
-
"""Fuzzy date parse with safety guards.
|
|
423
|
-
|
|
424
|
-
dateutil fuzzy=True is exponential on long non-date text.
|
|
425
|
-
Guard: only attempt on short strings (< 60 chars) that contain
|
|
426
|
-
at least one digit (dates always have numbers).
|
|
427
|
-
"""
|
|
428
|
-
if len(text) > 60 or not any(c.isdigit() for c in text):
|
|
429
|
-
return None
|
|
430
|
-
try:
|
|
431
|
-
return dateutil_parse(text, fuzzy=True)
|
|
432
|
-
except (ParserError, ValueError, OverflowError):
|
|
433
|
-
return None
|