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,983 +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
|
-
"""Sleep-time consolidation engine (Phase 5).
|
|
6
|
-
|
|
7
|
-
Letta-inspired 6-step consolidation cycle:
|
|
8
|
-
1. Compress — deduplicate near-identical facts
|
|
9
|
-
2. Compile Core Memory blocks — rules (Mode A) or LLM (Mode B/C)
|
|
10
|
-
3. Promote — move frequently accessed facts up lifecycle
|
|
11
|
-
4. Decay — reduce weights on unused association edges
|
|
12
|
-
5. Recompute graph — PageRank + communities
|
|
13
|
-
6. Derive associations — link new summary facts
|
|
14
|
-
|
|
15
|
-
Guarantees:
|
|
16
|
-
- Idempotent: running twice produces identical state (L18)
|
|
17
|
-
- Never deletes facts (Rule 17)
|
|
18
|
-
- No import of core/engine.py (Rule 06)
|
|
19
|
-
- Silent errors (Rule 19)
|
|
20
|
-
- Parameterized SQL (Rule 11)
|
|
21
|
-
- Feature-flagged via enabled=False (Rule 12)
|
|
22
|
-
|
|
23
|
-
Part of Qualixar | Author: Varun Pratap Bhardwaj
|
|
24
|
-
"""
|
|
25
|
-
|
|
26
|
-
from __future__ import annotations
|
|
27
|
-
|
|
28
|
-
import json
|
|
29
|
-
import logging
|
|
30
|
-
import threading
|
|
31
|
-
from datetime import datetime, timezone
|
|
32
|
-
from typing import TYPE_CHECKING, Any
|
|
33
|
-
|
|
34
|
-
if TYPE_CHECKING:
|
|
35
|
-
from superlocalmemory.core.config import ConsolidationConfig, SLMConfig
|
|
36
|
-
from superlocalmemory.core.graph_analyzer import GraphAnalyzer
|
|
37
|
-
from superlocalmemory.core.summarizer import Summarizer
|
|
38
|
-
from superlocalmemory.encoding.auto_linker import AutoLinker
|
|
39
|
-
from superlocalmemory.encoding.temporal_validator import TemporalValidator
|
|
40
|
-
from superlocalmemory.learning.behavioral import (
|
|
41
|
-
BehavioralPatternStore,
|
|
42
|
-
BehavioralTracker,
|
|
43
|
-
)
|
|
44
|
-
from superlocalmemory.learning.consolidation_quantization_worker import (
|
|
45
|
-
CCQWorker,
|
|
46
|
-
)
|
|
47
|
-
from superlocalmemory.storage.database import DatabaseManager
|
|
48
|
-
|
|
49
|
-
logger = logging.getLogger(__name__)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
def _recompute_entity_communities(
|
|
53
|
-
db: Any, profile_id: str, summarizer: Any = None,
|
|
54
|
-
) -> dict[str, int]:
|
|
55
|
-
"""Wave Q: rebuild the entity-community backbone + summaries (fail-open).
|
|
56
|
-
|
|
57
|
-
Shared spine for Q2 community summaries and Q3 progressive abstraction.
|
|
58
|
-
Runs in the background consolidation lane; never blocks store/recall.
|
|
59
|
-
Community detection and summary generation are independently fail-open.
|
|
60
|
-
"""
|
|
61
|
-
result: dict[str, int] = {"entity_count": 0, "community_count": 0}
|
|
62
|
-
try:
|
|
63
|
-
from superlocalmemory.core.entity_community import EntityCommunityBuilder
|
|
64
|
-
|
|
65
|
-
result = EntityCommunityBuilder(db).compute_and_store(profile_id)
|
|
66
|
-
logger.info(
|
|
67
|
-
"Background entity-community: %d entities, %d communities",
|
|
68
|
-
result.get("entity_count", 0),
|
|
69
|
-
result.get("community_count", 0),
|
|
70
|
-
)
|
|
71
|
-
except Exception as exc:
|
|
72
|
-
logger.debug("Entity-community recompute failed (non-fatal): %s", exc)
|
|
73
|
-
return result
|
|
74
|
-
|
|
75
|
-
# Wave Q2: one synthesized report per community (rides on the backbone).
|
|
76
|
-
try:
|
|
77
|
-
from superlocalmemory.core.community_summary import CommunitySummaryBuilder
|
|
78
|
-
|
|
79
|
-
summ = CommunitySummaryBuilder(db, summarizer=summarizer).compute_and_store(
|
|
80
|
-
profile_id,
|
|
81
|
-
)
|
|
82
|
-
result["summaries_written"] = summ.get("summaries_written", 0)
|
|
83
|
-
logger.info(
|
|
84
|
-
"Background community summaries: %d written",
|
|
85
|
-
summ.get("summaries_written", 0),
|
|
86
|
-
)
|
|
87
|
-
except Exception as exc:
|
|
88
|
-
logger.debug("Community summaries failed (non-fatal): %s", exc)
|
|
89
|
-
|
|
90
|
-
# Wave Q3: persona roll-up (top tier over the community summaries).
|
|
91
|
-
try:
|
|
92
|
-
from superlocalmemory.core.progressive_abstraction import (
|
|
93
|
-
ProgressiveAbstraction,
|
|
94
|
-
)
|
|
95
|
-
|
|
96
|
-
pa = ProgressiveAbstraction(db, summarizer=summarizer).compute_and_store(
|
|
97
|
-
profile_id,
|
|
98
|
-
)
|
|
99
|
-
result["persona_built"] = bool(pa.get("built", False))
|
|
100
|
-
except Exception as exc:
|
|
101
|
-
logger.debug("Persona roll-up failed (non-fatal): %s", exc)
|
|
102
|
-
return result
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
class ConsolidationEngine:
|
|
106
|
-
"""Sleep-time memory consolidation with 6-step cycle.
|
|
107
|
-
|
|
108
|
-
The biological metaphor: during sleep, the brain replays recent
|
|
109
|
-
experiences, compresses them into long-term memory, strengthens
|
|
110
|
-
important connections, and prunes weak ones. SLM does the same.
|
|
111
|
-
|
|
112
|
-
Consolidation is IDEMPOTENT: running twice produces identical state (L18).
|
|
113
|
-
This is guaranteed because:
|
|
114
|
-
- Block compilation uses INSERT OR REPLACE on UNIQUE(profile_id, block_type)
|
|
115
|
-
- Promotion checks current state before updating
|
|
116
|
-
- PageRank is deterministic given the same graph
|
|
117
|
-
- Edge decay is monotonic (weight only decreases)
|
|
118
|
-
|
|
119
|
-
Never overwrites or deletes facts (Rule 17).
|
|
120
|
-
"""
|
|
121
|
-
|
|
122
|
-
def __init__(
|
|
123
|
-
self,
|
|
124
|
-
db: DatabaseManager,
|
|
125
|
-
config: ConsolidationConfig,
|
|
126
|
-
summarizer: Summarizer | None = None,
|
|
127
|
-
behavioral_store: BehavioralPatternStore | BehavioralTracker | None = None,
|
|
128
|
-
auto_linker: AutoLinker | None = None,
|
|
129
|
-
graph_analyzer: GraphAnalyzer | None = None,
|
|
130
|
-
temporal_validator: TemporalValidator | None = None,
|
|
131
|
-
slm_config: SLMConfig | None = None,
|
|
132
|
-
ccq_worker: CCQWorker | None = None,
|
|
133
|
-
) -> None:
|
|
134
|
-
self._db = db
|
|
135
|
-
self._consolidation_config = config
|
|
136
|
-
self._summarizer = summarizer
|
|
137
|
-
self._behavioral = behavioral_store
|
|
138
|
-
self._auto_linker = auto_linker
|
|
139
|
-
self._graph_analyzer = graph_analyzer
|
|
140
|
-
self._temporal_validator = temporal_validator
|
|
141
|
-
self._config = slm_config
|
|
142
|
-
self._ccq_worker = ccq_worker
|
|
143
|
-
self._mode = slm_config.mode.value if slm_config else "a"
|
|
144
|
-
self._store_count: int = 0 # For step-count trigger (L7)
|
|
145
|
-
|
|
146
|
-
# ------------------------------------------------------------------
|
|
147
|
-
# Public API
|
|
148
|
-
# ------------------------------------------------------------------
|
|
149
|
-
|
|
150
|
-
def consolidate(
|
|
151
|
-
self, profile_id: str, lightweight: bool = False,
|
|
152
|
-
) -> dict[str, Any]:
|
|
153
|
-
"""Execute the consolidation cycle.
|
|
154
|
-
|
|
155
|
-
Full cycle (session end, manual, scheduled):
|
|
156
|
-
Steps 1-6 (compress, compile, promote, decay, recompute, derive)
|
|
157
|
-
|
|
158
|
-
Lightweight cycle (step-count trigger every 50 stores):
|
|
159
|
-
Steps 2 + 4 only (refresh blocks + decay edges)
|
|
160
|
-
|
|
161
|
-
Returns dict with step results for dashboard display.
|
|
162
|
-
"""
|
|
163
|
-
results: dict[str, Any] = {
|
|
164
|
-
"profile_id": profile_id,
|
|
165
|
-
"lightweight": lightweight,
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
try:
|
|
169
|
-
if lightweight:
|
|
170
|
-
results["blocks"] = self._step2_compile_blocks(profile_id)
|
|
171
|
-
results["decayed"] = self._step4_decay_edges(profile_id)
|
|
172
|
-
else:
|
|
173
|
-
results["compressed"] = self._step1_compress(profile_id)
|
|
174
|
-
results["blocks"] = self._step2_compile_blocks(profile_id)
|
|
175
|
-
results["promoted"] = self._step3_promote(profile_id)
|
|
176
|
-
results["decayed"] = self._step4_decay_edges(profile_id)
|
|
177
|
-
results["graph_stats"] = self._step5_recompute_graph(profile_id)
|
|
178
|
-
results["new_associations"] = self._step6_derive_associations(
|
|
179
|
-
profile_id,
|
|
180
|
-
)
|
|
181
|
-
# Step 7: Cognitive Consolidation Quantization (Phase E)
|
|
182
|
-
results["ccq"] = self._step7_ccq(profile_id)
|
|
183
|
-
|
|
184
|
-
# Step 8 (v3.4.7): Mine behavioral assertions from tool events.
|
|
185
|
-
try:
|
|
186
|
-
from superlocalmemory.learning.assertion_miner import AssertionMiner
|
|
187
|
-
miner = AssertionMiner(self._db.db_path)
|
|
188
|
-
results["assertions"] = miner.mine(profile_id)
|
|
189
|
-
except Exception as exc:
|
|
190
|
-
logger.debug("Assertion mining (non-fatal): %s", exc)
|
|
191
|
-
results["assertions"] = {"error": str(exc)}
|
|
192
|
-
|
|
193
|
-
# Step 9 (v3.4.7): Generate soft prompts from patterns + assertions.
|
|
194
|
-
# Previously the AutoParameterizeHook was never wired.
|
|
195
|
-
try:
|
|
196
|
-
from superlocalmemory.parameterization.pattern_extractor import PatternExtractor
|
|
197
|
-
from superlocalmemory.parameterization.soft_prompt_generator import SoftPromptGenerator
|
|
198
|
-
from superlocalmemory.parameterization.prompt_injector import PromptInjector
|
|
199
|
-
from superlocalmemory.parameterization.prompt_lifecycle import PromptLifecycleManager
|
|
200
|
-
from superlocalmemory.learning.behavioral import BehavioralPatternStore
|
|
201
|
-
from superlocalmemory.parameterization.cross_project import CrossProjectAggregator
|
|
202
|
-
from superlocalmemory.parameterization.workflow_miner import WorkflowMiner
|
|
203
|
-
from superlocalmemory.hooks.auto_parameterize import AutoParameterizeHook
|
|
204
|
-
from superlocalmemory.core.config import ParameterizationConfig
|
|
205
|
-
p_config = getattr(self._config, "parameterization", ParameterizationConfig())
|
|
206
|
-
from superlocalmemory.infra.data_root import state_path
|
|
207
|
-
learning_db = str(state_path("learning.db"))
|
|
208
|
-
beh_store = BehavioralPatternStore(learning_db)
|
|
209
|
-
# Both take a DB PATH, not a DatabaseManager. Passing
|
|
210
|
-
# self._db here made Path(db_path) raise "argument should be
|
|
211
|
-
# a str or an os.PathLike object ... not 'DatabaseManager'",
|
|
212
|
-
# which step 9 caught at debug level — so soft prompts were
|
|
213
|
-
# never generated and nothing said why.
|
|
214
|
-
#
|
|
215
|
-
# The ImportError stubs these replaced were also dead: both
|
|
216
|
-
# modules exist and re-export the canonical classes, so the
|
|
217
|
-
# stub branch could never run and only served to hide the
|
|
218
|
-
# real signatures.
|
|
219
|
-
cross_proj = CrossProjectAggregator(learning_db)
|
|
220
|
-
wf_miner = WorkflowMiner(learning_db)
|
|
221
|
-
extractor = PatternExtractor(self._db, beh_store, cross_proj, wf_miner, p_config)
|
|
222
|
-
generator = SoftPromptGenerator(p_config)
|
|
223
|
-
injector = PromptInjector(self._db, generator, p_config)
|
|
224
|
-
lifecycle = PromptLifecycleManager(self._db, p_config)
|
|
225
|
-
hook = AutoParameterizeHook(extractor, generator, injector, lifecycle, p_config)
|
|
226
|
-
sp_result = hook.on_consolidation_complete(profile_id)
|
|
227
|
-
results["soft_prompts"] = sp_result
|
|
228
|
-
except Exception as exc:
|
|
229
|
-
logger.debug("Soft prompt generation (non-fatal): %s", exc)
|
|
230
|
-
results["soft_prompts"] = {"error": str(exc)}
|
|
231
|
-
|
|
232
|
-
# Step 10 (v3.4.10): Mine skill performance from tool events.
|
|
233
|
-
# Creates per-skill assertions and skill correlation patterns.
|
|
234
|
-
try:
|
|
235
|
-
from superlocalmemory.learning.skill_performance_miner import SkillPerformanceMiner
|
|
236
|
-
spm = SkillPerformanceMiner(self._db.db_path)
|
|
237
|
-
results["skill_performance"] = spm.mine(profile_id)
|
|
238
|
-
except Exception as exc:
|
|
239
|
-
logger.debug("Skill performance mining (non-fatal): %s", exc)
|
|
240
|
-
results["skill_performance"] = {"error": str(exc)}
|
|
241
|
-
|
|
242
|
-
# Step 11 (v3.4.10): Skill evolution — 3-trigger system.
|
|
243
|
-
# Runs degradation + health check triggers. Post-session
|
|
244
|
-
# trigger runs separately from the Stop hook.
|
|
245
|
-
# Never on recall/remember hot path. Budget: max 3 per cycle.
|
|
246
|
-
try:
|
|
247
|
-
from superlocalmemory.evolution.skill_evolver import SkillEvolver
|
|
248
|
-
evolver = SkillEvolver(self._db.db_path, self._config)
|
|
249
|
-
results["skill_evolution"] = evolver.run_consolidation_cycle(profile_id)
|
|
250
|
-
except Exception as exc:
|
|
251
|
-
logger.debug("Skill evolution (non-fatal): %s", exc)
|
|
252
|
-
results["skill_evolution"] = {"error": str(exc)}
|
|
253
|
-
|
|
254
|
-
# Step 12 (v3.4.11): Generate soft prompts for evolved skills.
|
|
255
|
-
# Queries promoted evolutions and creates/updates custom soft
|
|
256
|
-
# prompts so the AI prefers evolved skill variants.
|
|
257
|
-
try:
|
|
258
|
-
results["evolution_soft_prompts"] = self._step12_evolution_soft_prompts(profile_id)
|
|
259
|
-
except Exception as exc:
|
|
260
|
-
logger.debug("Evolution soft prompts (non-fatal): %s", exc)
|
|
261
|
-
results["evolution_soft_prompts"] = {"error": str(exc)}
|
|
262
|
-
|
|
263
|
-
results["success"] = True
|
|
264
|
-
except Exception as exc:
|
|
265
|
-
logger.warning(
|
|
266
|
-
"Consolidation failed (non-fatal) for profile %s: %s",
|
|
267
|
-
profile_id, exc,
|
|
268
|
-
)
|
|
269
|
-
results["success"] = False
|
|
270
|
-
results["error"] = str(exc)
|
|
271
|
-
|
|
272
|
-
return results
|
|
273
|
-
|
|
274
|
-
def increment_store_count(self, profile_id: str) -> bool:
|
|
275
|
-
"""Called after each store() in store_pipeline.py.
|
|
276
|
-
|
|
277
|
-
Increments internal counter. When counter hits step_count_trigger
|
|
278
|
-
(default 50), runs lightweight consolidation AND queues async
|
|
279
|
-
graph analysis.
|
|
280
|
-
|
|
281
|
-
V3.4.2: Graph analysis runs in background thread after every
|
|
282
|
-
lightweight consolidation trigger. This populates fact_importance
|
|
283
|
-
(PageRank, communities, bridge scores) so retrieval channels can
|
|
284
|
-
use graph intelligence without blocking store/recall latency.
|
|
285
|
-
|
|
286
|
-
Returns True if lightweight consolidation was triggered.
|
|
287
|
-
"""
|
|
288
|
-
if not self._consolidation_config.enabled:
|
|
289
|
-
return False
|
|
290
|
-
|
|
291
|
-
self._store_count += 1
|
|
292
|
-
if self._store_count >= self._consolidation_config.step_count_trigger:
|
|
293
|
-
self._store_count = 0
|
|
294
|
-
self.consolidate(profile_id, lightweight=True)
|
|
295
|
-
# V3.4.2: Queue graph analysis in background (non-blocking)
|
|
296
|
-
self._queue_graph_analysis(profile_id)
|
|
297
|
-
return True
|
|
298
|
-
return False
|
|
299
|
-
|
|
300
|
-
def _queue_graph_analysis(self, profile_id: str) -> None:
|
|
301
|
-
"""Run graph_analyzer.compute_and_store() in a background thread.
|
|
302
|
-
|
|
303
|
-
V3.4.2: Populates fact_importance table with PageRank, community_id,
|
|
304
|
-
degree_centrality, and bridge_score. Next recall() automatically
|
|
305
|
-
uses updated graph intelligence for entity channel and spreading
|
|
306
|
-
activation. Takes ~200-800ms, runs on daemon thread, zero impact
|
|
307
|
-
on store/recall latency.
|
|
308
|
-
"""
|
|
309
|
-
analyzer = self._graph_analyzer
|
|
310
|
-
pid = profile_id
|
|
311
|
-
db = self._db
|
|
312
|
-
summarizer = self._summarizer
|
|
313
|
-
|
|
314
|
-
def _run() -> None:
|
|
315
|
-
if analyzer is not None:
|
|
316
|
-
try:
|
|
317
|
-
result = analyzer.compute_and_store(pid)
|
|
318
|
-
logger.info(
|
|
319
|
-
"Background graph analysis complete: %d nodes, "
|
|
320
|
-
"%d communities",
|
|
321
|
-
result.get("node_count", 0),
|
|
322
|
-
result.get("community_count", 0),
|
|
323
|
-
)
|
|
324
|
-
except Exception as exc:
|
|
325
|
-
logger.debug(
|
|
326
|
-
"Background graph analysis failed (non-fatal): %s", exc,
|
|
327
|
-
)
|
|
328
|
-
# Wave Q: entity-community backbone + summaries (Q2/Q3 spine).
|
|
329
|
-
_recompute_entity_communities(db, pid, summarizer)
|
|
330
|
-
|
|
331
|
-
t = threading.Thread(target=_run, daemon=True, name="graph-analysis-bg")
|
|
332
|
-
t.start()
|
|
333
|
-
|
|
334
|
-
def get_core_memory(self, profile_id: str) -> dict[str, str]:
|
|
335
|
-
"""Load all Core Memory blocks for a profile.
|
|
336
|
-
|
|
337
|
-
Returns dict of {block_type: content}.
|
|
338
|
-
Called at session_init to inject into context.
|
|
339
|
-
"""
|
|
340
|
-
rows = self._db.get_core_blocks(profile_id)
|
|
341
|
-
return {r["block_type"]: r["content"] for r in rows}
|
|
342
|
-
|
|
343
|
-
def get_core_memory_blocks(self, profile_id: str) -> list[dict]:
|
|
344
|
-
"""Load all Core Memory blocks with full metadata. For API."""
|
|
345
|
-
return self._db.get_core_blocks(profile_id)
|
|
346
|
-
|
|
347
|
-
# ------------------------------------------------------------------
|
|
348
|
-
# Step 1: Compress — deduplicate near-identical facts
|
|
349
|
-
# ------------------------------------------------------------------
|
|
350
|
-
|
|
351
|
-
def _step1_compress(self, profile_id: str) -> dict[str, Any]:
|
|
352
|
-
"""Deduplicate near-identical facts by archiving originals.
|
|
353
|
-
|
|
354
|
-
Never deletes facts (Rule 17). Sets lifecycle to 'archived'.
|
|
355
|
-
In Mode A, compression is a no-op (no VectorStore for similarity).
|
|
356
|
-
"""
|
|
357
|
-
# Mode A: heuristic compression is a stub — requires VectorStore
|
|
358
|
-
# for similarity search which is optional. Return zero counts.
|
|
359
|
-
return {
|
|
360
|
-
"clusters_found": 0,
|
|
361
|
-
"facts_compressed": 0,
|
|
362
|
-
"summaries_created": 0,
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
# ------------------------------------------------------------------
|
|
366
|
-
# Step 2: Compile Core Memory Blocks
|
|
367
|
-
# ------------------------------------------------------------------
|
|
368
|
-
|
|
369
|
-
def _step2_compile_blocks(self, profile_id: str) -> dict[str, Any]:
|
|
370
|
-
"""Compile Core Memory blocks based on mode.
|
|
371
|
-
|
|
372
|
-
Mode A: rules-based (no LLM) (L3 fix)
|
|
373
|
-
Mode B/C: LLM-assisted summarization
|
|
374
|
-
"""
|
|
375
|
-
if self._mode == "a":
|
|
376
|
-
return self.compile_core_blocks_mode_a(profile_id)
|
|
377
|
-
return self._compile_core_blocks_llm(profile_id)
|
|
378
|
-
|
|
379
|
-
def compile_core_blocks_mode_a(self, profile_id: str) -> dict[str, Any]:
|
|
380
|
-
"""Mode A: populate Core Memory blocks without LLM (L3 fix).
|
|
381
|
-
|
|
382
|
-
Rules-based compilation:
|
|
383
|
-
- user_profile: top-5 semantic/opinion facts by access_count
|
|
384
|
-
- project_context: top-5 episodic facts by recency
|
|
385
|
-
- behavioral_patterns: top-5 patterns by confidence
|
|
386
|
-
- active_decisions: facts with signal_type='decision', min access
|
|
387
|
-
- learned_preferences: opinion facts with confidence >= threshold
|
|
388
|
-
"""
|
|
389
|
-
blocks_compiled = 0
|
|
390
|
-
block_limit = self._consolidation_config.block_char_limit
|
|
391
|
-
|
|
392
|
-
# 1. user_profile: top semantic/opinion facts by access
|
|
393
|
-
user_facts = self._get_top_facts(
|
|
394
|
-
profile_id,
|
|
395
|
-
fact_types=["semantic", "opinion"],
|
|
396
|
-
sort_by="access_count",
|
|
397
|
-
limit=5,
|
|
398
|
-
)
|
|
399
|
-
self._store_core_block(
|
|
400
|
-
profile_id, "user_profile",
|
|
401
|
-
self._facts_to_content(user_facts, block_limit),
|
|
402
|
-
[f["fact_id"] for f in user_facts],
|
|
403
|
-
)
|
|
404
|
-
blocks_compiled += 1
|
|
405
|
-
|
|
406
|
-
# 2. project_context: top episodic facts by recency
|
|
407
|
-
project_facts = self._get_top_facts(
|
|
408
|
-
profile_id,
|
|
409
|
-
fact_types=["episodic"],
|
|
410
|
-
sort_by="recency",
|
|
411
|
-
limit=5,
|
|
412
|
-
)
|
|
413
|
-
self._store_core_block(
|
|
414
|
-
profile_id, "project_context",
|
|
415
|
-
self._facts_to_content(project_facts, block_limit),
|
|
416
|
-
[f["fact_id"] for f in project_facts],
|
|
417
|
-
)
|
|
418
|
-
blocks_compiled += 1
|
|
419
|
-
|
|
420
|
-
# 3. behavioral_patterns: from behavioral store
|
|
421
|
-
pattern_content = self._compile_behavioral_block(
|
|
422
|
-
profile_id, block_limit,
|
|
423
|
-
)
|
|
424
|
-
self._store_core_block(
|
|
425
|
-
profile_id, "behavioral_patterns",
|
|
426
|
-
pattern_content,
|
|
427
|
-
[],
|
|
428
|
-
)
|
|
429
|
-
blocks_compiled += 1
|
|
430
|
-
|
|
431
|
-
# 4. active_decisions: signal_type='decision' with min access
|
|
432
|
-
# CRITICAL: uses signal_type NOT fact_type (HIGH-2 fix)
|
|
433
|
-
decision_facts = self._db.execute(
|
|
434
|
-
"SELECT f.fact_id, f.content FROM atomic_facts f "
|
|
435
|
-
"LEFT JOIN fact_access_log a ON f.fact_id = a.fact_id "
|
|
436
|
-
"WHERE f.profile_id = ? AND f.signal_type = 'decision' "
|
|
437
|
-
"AND f.lifecycle = 'active' "
|
|
438
|
-
"GROUP BY f.fact_id "
|
|
439
|
-
"HAVING COUNT(a.log_id) >= ? "
|
|
440
|
-
"ORDER BY COUNT(a.log_id) DESC LIMIT 5",
|
|
441
|
-
(profile_id, self._consolidation_config.promotion_min_access),
|
|
442
|
-
)
|
|
443
|
-
self._store_core_block(
|
|
444
|
-
profile_id, "active_decisions",
|
|
445
|
-
self._rows_to_content(decision_facts, block_limit),
|
|
446
|
-
[dict(f)["fact_id"] for f in (decision_facts or [])],
|
|
447
|
-
)
|
|
448
|
-
blocks_compiled += 1
|
|
449
|
-
|
|
450
|
-
# 5. learned_preferences: opinion facts with high confidence
|
|
451
|
-
pref_facts = self._db.execute(
|
|
452
|
-
"SELECT fact_id, content FROM atomic_facts "
|
|
453
|
-
"WHERE profile_id = ? AND fact_type = 'opinion' "
|
|
454
|
-
"AND confidence >= ? AND lifecycle = 'active' "
|
|
455
|
-
"ORDER BY confidence DESC LIMIT 5",
|
|
456
|
-
(profile_id, self._consolidation_config.promotion_min_trust),
|
|
457
|
-
)
|
|
458
|
-
self._store_core_block(
|
|
459
|
-
profile_id, "learned_preferences",
|
|
460
|
-
self._rows_to_content(pref_facts, block_limit),
|
|
461
|
-
[dict(f)["fact_id"] for f in (pref_facts or [])],
|
|
462
|
-
)
|
|
463
|
-
blocks_compiled += 1
|
|
464
|
-
|
|
465
|
-
return {"blocks_compiled": blocks_compiled, "mode": "rules"}
|
|
466
|
-
|
|
467
|
-
def _compile_core_blocks_llm(self, profile_id: str) -> dict[str, Any]:
|
|
468
|
-
"""Mode B/C: LLM-assisted Core Memory block compilation.
|
|
469
|
-
|
|
470
|
-
Falls back to Mode A rules if LLM fails (Rule 19).
|
|
471
|
-
"""
|
|
472
|
-
if self._summarizer is None:
|
|
473
|
-
return self.compile_core_blocks_mode_a(profile_id)
|
|
474
|
-
|
|
475
|
-
try:
|
|
476
|
-
blocks_compiled = 0
|
|
477
|
-
|
|
478
|
-
for block_type, fact_types in [
|
|
479
|
-
("user_profile", ["semantic", "opinion"]),
|
|
480
|
-
("project_context", ["episodic"]),
|
|
481
|
-
]:
|
|
482
|
-
facts = self._get_top_facts(
|
|
483
|
-
profile_id, fact_types=fact_types,
|
|
484
|
-
sort_by="access_count", limit=8,
|
|
485
|
-
)
|
|
486
|
-
if facts:
|
|
487
|
-
fact_dicts = [
|
|
488
|
-
{"content": f.get("content", "")} for f in facts
|
|
489
|
-
]
|
|
490
|
-
summary = self._summarizer.summarize_cluster(fact_dicts)
|
|
491
|
-
self._store_core_block(
|
|
492
|
-
profile_id, block_type,
|
|
493
|
-
summary[:self._consolidation_config.block_char_limit],
|
|
494
|
-
[f["fact_id"] for f in facts],
|
|
495
|
-
compiled_by="llm",
|
|
496
|
-
)
|
|
497
|
-
blocks_compiled += 1
|
|
498
|
-
|
|
499
|
-
# Behavioral, decisions, preferences still rules-based
|
|
500
|
-
mode_a_result = self.compile_core_blocks_mode_a(profile_id)
|
|
501
|
-
blocks_compiled += mode_a_result.get("blocks_compiled", 0)
|
|
502
|
-
|
|
503
|
-
return {"blocks_compiled": blocks_compiled, "mode": "llm"}
|
|
504
|
-
except Exception:
|
|
505
|
-
# Fallback to Mode A (Rule 19)
|
|
506
|
-
return self.compile_core_blocks_mode_a(profile_id)
|
|
507
|
-
|
|
508
|
-
# ------------------------------------------------------------------
|
|
509
|
-
# Step 3: Auto-Promote
|
|
510
|
-
# ------------------------------------------------------------------
|
|
511
|
-
|
|
512
|
-
def _step3_promote(self, profile_id: str) -> dict[str, Any]:
|
|
513
|
-
"""Promote frequently accessed facts to higher lifecycle state.
|
|
514
|
-
|
|
515
|
-
Checks temporal validity (L12 fix) and trust threshold.
|
|
516
|
-
Never overwrites fact content (Rule 17).
|
|
517
|
-
"""
|
|
518
|
-
candidates = self._db.execute(
|
|
519
|
-
"SELECT f.fact_id, f.lifecycle, f.confidence, "
|
|
520
|
-
" COUNT(a.log_id) as access_count "
|
|
521
|
-
"FROM atomic_facts f "
|
|
522
|
-
"LEFT JOIN fact_access_log a ON f.fact_id = a.fact_id "
|
|
523
|
-
"WHERE f.profile_id = ? AND f.lifecycle = 'active' "
|
|
524
|
-
"GROUP BY f.fact_id "
|
|
525
|
-
"HAVING COUNT(a.log_id) >= ?",
|
|
526
|
-
(profile_id, self._consolidation_config.promotion_min_access),
|
|
527
|
-
)
|
|
528
|
-
|
|
529
|
-
promoted = 0
|
|
530
|
-
for row in (candidates or []):
|
|
531
|
-
d = dict(row)
|
|
532
|
-
fact_id = d["fact_id"]
|
|
533
|
-
|
|
534
|
-
# Temporal validity check (L12 fix)
|
|
535
|
-
if not self._is_temporally_valid(fact_id, profile_id):
|
|
536
|
-
continue
|
|
537
|
-
|
|
538
|
-
# Trust check
|
|
539
|
-
if d.get("confidence", 0) < self._consolidation_config.promotion_min_trust:
|
|
540
|
-
continue
|
|
541
|
-
|
|
542
|
-
# Promote: active -> warm (lifecycle transition)
|
|
543
|
-
from superlocalmemory.core.lifecycle_state import set_fact_lifecycle_zone
|
|
544
|
-
set_fact_lifecycle_zone(
|
|
545
|
-
self._db,
|
|
546
|
-
[fact_id],
|
|
547
|
-
"warm",
|
|
548
|
-
profile_id=profile_id,
|
|
549
|
-
from_atomic=("active",),
|
|
550
|
-
)
|
|
551
|
-
promoted += 1
|
|
552
|
-
|
|
553
|
-
return {
|
|
554
|
-
"candidates": len(candidates or []),
|
|
555
|
-
"promoted": promoted,
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
def _is_temporally_valid(
|
|
559
|
-
self, fact_id: str, profile_id: str,
|
|
560
|
-
) -> bool:
|
|
561
|
-
"""Check if fact has not been temporally invalidated (L12).
|
|
562
|
-
|
|
563
|
-
Returns True if valid, False if expired.
|
|
564
|
-
"""
|
|
565
|
-
# Use TemporalValidator.is_temporally_valid() if available (P5-BC4)
|
|
566
|
-
if self._temporal_validator is not None:
|
|
567
|
-
return self._temporal_validator.is_temporally_valid(
|
|
568
|
-
fact_id, profile_id,
|
|
569
|
-
)
|
|
570
|
-
|
|
571
|
-
# Fallback: direct SQL check. Must consider BOTH valid_until (valid-time
|
|
572
|
-
# expiry) AND system_expired_at (transaction-time expiry) — a fact that
|
|
573
|
-
# was invalidated/erased sets system_expired_at, and ignoring it would
|
|
574
|
-
# let a GDPR-erased/superseded fact be promoted back into warm lifecycle.
|
|
575
|
-
rows = self._db.execute(
|
|
576
|
-
"SELECT valid_until, system_expired_at FROM fact_temporal_validity "
|
|
577
|
-
"WHERE fact_id = ? AND profile_id = ?",
|
|
578
|
-
(fact_id, profile_id),
|
|
579
|
-
)
|
|
580
|
-
if not rows:
|
|
581
|
-
return True # No temporal record = valid
|
|
582
|
-
row = dict(rows[0])
|
|
583
|
-
if row.get("system_expired_at") is not None:
|
|
584
|
-
return False # transaction-time expired (invalidated/erased)
|
|
585
|
-
valid_until = row.get("valid_until")
|
|
586
|
-
if valid_until is None:
|
|
587
|
-
return True # Open-ended validity
|
|
588
|
-
try:
|
|
589
|
-
expiry = datetime.fromisoformat(valid_until)
|
|
590
|
-
now = datetime.now(timezone.utc)
|
|
591
|
-
# Handle naive datetimes
|
|
592
|
-
if expiry.tzinfo is None:
|
|
593
|
-
return expiry > now.replace(tzinfo=None)
|
|
594
|
-
return expiry > now
|
|
595
|
-
except (ValueError, TypeError):
|
|
596
|
-
return True # Parse failure = assume valid
|
|
597
|
-
|
|
598
|
-
# ------------------------------------------------------------------
|
|
599
|
-
# Step 4: Decay Edges
|
|
600
|
-
# ------------------------------------------------------------------
|
|
601
|
-
|
|
602
|
-
def _step4_decay_edges(self, profile_id: str) -> dict[str, int]:
|
|
603
|
-
"""Decay unused association edges. Delegates to AutoLinker."""
|
|
604
|
-
if self._auto_linker is None:
|
|
605
|
-
return {"decayed": 0}
|
|
606
|
-
try:
|
|
607
|
-
decayed = self._auto_linker.decay_unused(
|
|
608
|
-
profile_id, days_threshold=self._consolidation_config.decay_days_threshold,
|
|
609
|
-
)
|
|
610
|
-
return {"decayed": decayed}
|
|
611
|
-
except Exception as exc:
|
|
612
|
-
logger.warning("Edge decay failed: %s", exc)
|
|
613
|
-
return {"decayed": 0}
|
|
614
|
-
|
|
615
|
-
# ------------------------------------------------------------------
|
|
616
|
-
# Step 5: Recompute Graph
|
|
617
|
-
# ------------------------------------------------------------------
|
|
618
|
-
|
|
619
|
-
def _step5_recompute_graph(
|
|
620
|
-
self, profile_id: str,
|
|
621
|
-
) -> dict[str, Any]:
|
|
622
|
-
"""Recompute PageRank + communities. Delegates to GraphAnalyzer.
|
|
623
|
-
|
|
624
|
-
Wave Q: also rebuilds the entity-community backbone (Q2/Q3 spine).
|
|
625
|
-
"""
|
|
626
|
-
result: dict[str, Any] = {"node_count": 0, "community_count": 0}
|
|
627
|
-
if self._graph_analyzer is not None:
|
|
628
|
-
try:
|
|
629
|
-
result = self._graph_analyzer.compute_and_store(profile_id)
|
|
630
|
-
except Exception as exc:
|
|
631
|
-
logger.warning("Graph recompute failed: %s", exc)
|
|
632
|
-
ec = _recompute_entity_communities(
|
|
633
|
-
self._db, profile_id, self._summarizer,
|
|
634
|
-
)
|
|
635
|
-
result["entity_community_count"] = ec.get("community_count", 0)
|
|
636
|
-
result["community_summaries"] = ec.get("summaries_written", 0)
|
|
637
|
-
result["entities_compiled"] = self._compile_entities(profile_id)
|
|
638
|
-
return result
|
|
639
|
-
|
|
640
|
-
def _compile_entities(self, profile_id: str) -> int:
|
|
641
|
-
"""Bring each entity's summary up to date with its facts.
|
|
642
|
-
|
|
643
|
-
This ran only on the maintenance endpoint, never on the periodic
|
|
644
|
-
consolidation that the daemon schedules on its own. The effect was that
|
|
645
|
-
almost every entity carried no compiled summary at all: the explorer
|
|
646
|
-
asked for one, got null, and showed an entity with no description and
|
|
647
|
-
an empty timeline — which reads as "there is nothing here" rather than
|
|
648
|
-
"nothing has compiled this yet".
|
|
649
|
-
|
|
650
|
-
Runs beside the community recompute because both derive a view over the
|
|
651
|
-
same graph and both belong to the same pass. Never fatal: a compilation
|
|
652
|
-
that fails leaves the previous summary in place, and no summary is a
|
|
653
|
-
worse answer than a stale one but not a broken store.
|
|
654
|
-
"""
|
|
655
|
-
try:
|
|
656
|
-
from superlocalmemory.core.config import SLMConfig
|
|
657
|
-
from superlocalmemory.learning.entity_compiler import EntityCompiler
|
|
658
|
-
|
|
659
|
-
db_path = getattr(self._db, "db_path", None)
|
|
660
|
-
if not db_path:
|
|
661
|
-
return 0
|
|
662
|
-
compiled = EntityCompiler(str(db_path), SLMConfig.load()).compile_all(
|
|
663
|
-
profile_id,
|
|
664
|
-
)
|
|
665
|
-
count = int(compiled.get("compiled", 0) or 0)
|
|
666
|
-
if count:
|
|
667
|
-
logger.info("Entity compilation: %d entities compiled", count)
|
|
668
|
-
return count
|
|
669
|
-
except Exception as exc:
|
|
670
|
-
logger.debug("Entity compilation skipped: %s", exc)
|
|
671
|
-
return 0
|
|
672
|
-
|
|
673
|
-
# ------------------------------------------------------------------
|
|
674
|
-
# Step 6: Derive Associations
|
|
675
|
-
# ------------------------------------------------------------------
|
|
676
|
-
|
|
677
|
-
def _step6_derive_associations(
|
|
678
|
-
self, profile_id: str,
|
|
679
|
-
) -> dict[str, int]:
|
|
680
|
-
"""Derive new associations from recently created summary facts."""
|
|
681
|
-
summaries = self._db.execute(
|
|
682
|
-
"SELECT fact_id FROM atomic_facts "
|
|
683
|
-
"WHERE profile_id = ? AND fact_type = 'semantic' "
|
|
684
|
-
"AND lifecycle = 'active' "
|
|
685
|
-
"AND created_at > datetime('now', '-1 hour')",
|
|
686
|
-
(profile_id,),
|
|
687
|
-
)
|
|
688
|
-
linked = 0
|
|
689
|
-
if self._auto_linker and summaries:
|
|
690
|
-
for row in summaries:
|
|
691
|
-
fact = self._db.get_fact(dict(row)["fact_id"])
|
|
692
|
-
if fact:
|
|
693
|
-
try:
|
|
694
|
-
ids = self._auto_linker.link_new_fact(fact, profile_id)
|
|
695
|
-
linked += len(ids)
|
|
696
|
-
except Exception:
|
|
697
|
-
pass
|
|
698
|
-
return {"summary_facts_linked": linked}
|
|
699
|
-
|
|
700
|
-
# ------------------------------------------------------------------
|
|
701
|
-
# Step 7: Cognitive Consolidation Quantization (Phase E)
|
|
702
|
-
# ------------------------------------------------------------------
|
|
703
|
-
|
|
704
|
-
def _step7_ccq(self, profile_id: str) -> dict[str, Any]:
|
|
705
|
-
"""Run CCQ pipeline after existing 6-step consolidation.
|
|
706
|
-
|
|
707
|
-
CCQ is step 7 because it depends on retention data from Phase A
|
|
708
|
-
and benefits from running after standard consolidation cleanup.
|
|
709
|
-
"""
|
|
710
|
-
if self._ccq_worker is None:
|
|
711
|
-
return {"enabled": False}
|
|
712
|
-
|
|
713
|
-
if not self._ccq_worker.should_run(
|
|
714
|
-
self._store_count, is_session_end=False,
|
|
715
|
-
):
|
|
716
|
-
return {"skipped": True, "reason": "trigger not met"}
|
|
717
|
-
|
|
718
|
-
try:
|
|
719
|
-
result = self._ccq_worker.run(profile_id)
|
|
720
|
-
return {
|
|
721
|
-
"clusters": result.clusters_processed,
|
|
722
|
-
"blocks": result.blocks_created,
|
|
723
|
-
"archived": result.facts_archived,
|
|
724
|
-
"compression_ratio": result.compression_ratio,
|
|
725
|
-
}
|
|
726
|
-
except Exception as exc:
|
|
727
|
-
logger.warning("CCQ step failed (non-fatal): %s", exc)
|
|
728
|
-
return {"error": str(exc)}
|
|
729
|
-
|
|
730
|
-
# ------------------------------------------------------------------
|
|
731
|
-
# Step 12: Evolution Soft Prompts
|
|
732
|
-
# ------------------------------------------------------------------
|
|
733
|
-
|
|
734
|
-
def _step12_evolution_soft_prompts(self, profile_id: str) -> dict[str, Any]:
|
|
735
|
-
"""Generate soft prompts for promoted evolved skills.
|
|
736
|
-
|
|
737
|
-
Queries skill_evolution_log for promoted evolutions and creates
|
|
738
|
-
or updates soft_prompt_templates with category='custom' so the
|
|
739
|
-
AI agent prefers evolved skill variants over originals.
|
|
740
|
-
|
|
741
|
-
Uses 'custom' category because the soft_prompt_templates CHECK
|
|
742
|
-
constraint does not include 'skill_evolution'. The content is
|
|
743
|
-
prefixed with [SKILL_EVOLUTION] for easy filtering.
|
|
744
|
-
|
|
745
|
-
Concurrency fix (v3.8.4): all writes routed through memory_write()
|
|
746
|
-
so the process write lock (get_write_lock) serialises in-process
|
|
747
|
-
writers and proper busy_timeout handles cross-process races.
|
|
748
|
-
No slow ops are held inside the write lock — this method has none.
|
|
749
|
-
"""
|
|
750
|
-
from superlocalmemory.storage.memory_write import memory_read, memory_write
|
|
751
|
-
|
|
752
|
-
db_path = self._db.db_path
|
|
753
|
-
|
|
754
|
-
# Phase 1: read-only fetch — does NOT hold the write lock.
|
|
755
|
-
try:
|
|
756
|
-
with memory_read(db_path) as rconn:
|
|
757
|
-
promoted_rows = [
|
|
758
|
-
dict(r)
|
|
759
|
-
for r in rconn.execute(
|
|
760
|
-
"SELECT id, skill_name, parent_skill_id, evolution_type, "
|
|
761
|
-
"mutation_summary, created_at "
|
|
762
|
-
"FROM skill_evolution_log "
|
|
763
|
-
"WHERE status = 'promoted' "
|
|
764
|
-
"ORDER BY created_at DESC LIMIT 20",
|
|
765
|
-
).fetchall()
|
|
766
|
-
]
|
|
767
|
-
except Exception:
|
|
768
|
-
# Table may not exist yet
|
|
769
|
-
return {"created": 0, "message": "skill_evolution_log table not found"}
|
|
770
|
-
|
|
771
|
-
if not promoted_rows:
|
|
772
|
-
return {"promoted_skills_found": 0, "soft_prompts_created": 0}
|
|
773
|
-
|
|
774
|
-
now = datetime.now(timezone.utc).isoformat()
|
|
775
|
-
created_count = 0
|
|
776
|
-
|
|
777
|
-
# Phase 2: short write transaction — hold the write lock for the
|
|
778
|
-
# INSERT/UPDATE loop only (pure SQL, no network / embed calls).
|
|
779
|
-
with memory_write(db_path) as conn:
|
|
780
|
-
for r in promoted_rows:
|
|
781
|
-
skill_name = r["skill_name"]
|
|
782
|
-
parent = r.get("parent_skill_id") or skill_name
|
|
783
|
-
evo_type = r["evolution_type"]
|
|
784
|
-
summary_txt = r.get("mutation_summary", "")
|
|
785
|
-
evo_id = r["id"]
|
|
786
|
-
|
|
787
|
-
content = (
|
|
788
|
-
f"[SKILL_EVOLUTION] Evolved skill: '{skill_name}' "
|
|
789
|
-
f"({'replaces' if evo_type == 'fix' else 'extends'} '{parent}' "
|
|
790
|
-
f"via {evo_type}). {summary_txt}. "
|
|
791
|
-
f"Use the evolved version for better results."
|
|
792
|
-
)
|
|
793
|
-
prompt_id = f"evo-{evo_id}"
|
|
794
|
-
|
|
795
|
-
existing = conn.execute(
|
|
796
|
-
"SELECT prompt_id FROM soft_prompt_templates WHERE prompt_id = ?",
|
|
797
|
-
(prompt_id,),
|
|
798
|
-
).fetchone()
|
|
799
|
-
|
|
800
|
-
if existing:
|
|
801
|
-
# M-REPLACE: Update existing record instead of INSERT OR REPLACE
|
|
802
|
-
# to avoid silently dropping columns with defaults.
|
|
803
|
-
try:
|
|
804
|
-
conn.execute(
|
|
805
|
-
"UPDATE soft_prompt_templates "
|
|
806
|
-
"SET content = ?, updated_at = ? "
|
|
807
|
-
"WHERE prompt_id = ?",
|
|
808
|
-
(content, now, prompt_id),
|
|
809
|
-
)
|
|
810
|
-
except Exception as upd_exc:
|
|
811
|
-
logger.debug(
|
|
812
|
-
"Failed to update soft prompt %s: %s", prompt_id, upd_exc
|
|
813
|
-
)
|
|
814
|
-
continue
|
|
815
|
-
|
|
816
|
-
try:
|
|
817
|
-
cur = conn.execute(
|
|
818
|
-
"INSERT OR IGNORE INTO soft_prompt_templates "
|
|
819
|
-
"(prompt_id, profile_id, category, content, source_pattern_ids, "
|
|
820
|
-
" confidence, effectiveness, token_count, retention_score, "
|
|
821
|
-
" active, version, created_at, updated_at) "
|
|
822
|
-
"VALUES (?, ?, 'custom', ?, ?, 0.8, 0.5, ?, 1.0, 1, 1, ?, ?)",
|
|
823
|
-
(
|
|
824
|
-
prompt_id, profile_id, content,
|
|
825
|
-
json.dumps([evo_id]),
|
|
826
|
-
len(content.split()),
|
|
827
|
-
now, now,
|
|
828
|
-
),
|
|
829
|
-
)
|
|
830
|
-
if cur.rowcount > 0:
|
|
831
|
-
created_count += 1
|
|
832
|
-
except Exception as ins_exc:
|
|
833
|
-
# Unique constraint on (profile_id, category) WHERE active=1
|
|
834
|
-
logger.debug(
|
|
835
|
-
"Skipping soft prompt for %s: %s", skill_name, ins_exc
|
|
836
|
-
)
|
|
837
|
-
|
|
838
|
-
return {
|
|
839
|
-
"promoted_skills_found": len(promoted_rows),
|
|
840
|
-
"soft_prompts_created": created_count,
|
|
841
|
-
}
|
|
842
|
-
|
|
843
|
-
# ------------------------------------------------------------------
|
|
844
|
-
# Core Memory Block Storage
|
|
845
|
-
# ------------------------------------------------------------------
|
|
846
|
-
|
|
847
|
-
def _store_core_block(
|
|
848
|
-
self,
|
|
849
|
-
profile_id: str,
|
|
850
|
-
block_type: str,
|
|
851
|
-
content: str,
|
|
852
|
-
source_fact_ids: list[str],
|
|
853
|
-
compiled_by: str = "rules",
|
|
854
|
-
) -> None:
|
|
855
|
-
"""Store or update a Core Memory block.
|
|
856
|
-
|
|
857
|
-
Uses INSERT OR REPLACE on UNIQUE(profile_id, block_type).
|
|
858
|
-
Guarantees idempotency (L18).
|
|
859
|
-
"""
|
|
860
|
-
from superlocalmemory.storage.models import _new_id
|
|
861
|
-
|
|
862
|
-
# NOTE (core-promotion-02, intentionally NOT changed): the audit
|
|
863
|
-
# flagged placeholder core blocks ("No data available.") + version
|
|
864
|
-
# churn. Investigation showed BOTH the "always 5 blocks" layout and the
|
|
865
|
-
# monotonic version-on-recompile counter are intentional, tested design
|
|
866
|
-
# (see test_consolidation_engine), and the read-side injection filter
|
|
867
|
-
# already hides placeholders from agents. Suppressing or de-churning
|
|
868
|
-
# here breaks that design for a cosmetic gain — so it is left as-is.
|
|
869
|
-
|
|
870
|
-
# Get existing version for increment
|
|
871
|
-
existing = self._db.get_core_block(profile_id, block_type)
|
|
872
|
-
version = (existing["version"] + 1) if existing else 1
|
|
873
|
-
|
|
874
|
-
self._db.store_core_block(
|
|
875
|
-
block_id=_new_id(),
|
|
876
|
-
profile_id=profile_id,
|
|
877
|
-
block_type=block_type,
|
|
878
|
-
content=content,
|
|
879
|
-
source_fact_ids=json.dumps(source_fact_ids),
|
|
880
|
-
char_count=len(content),
|
|
881
|
-
version=version,
|
|
882
|
-
compiled_by=compiled_by,
|
|
883
|
-
)
|
|
884
|
-
|
|
885
|
-
# ------------------------------------------------------------------
|
|
886
|
-
# Helper Methods
|
|
887
|
-
# ------------------------------------------------------------------
|
|
888
|
-
|
|
889
|
-
def _get_top_facts(
|
|
890
|
-
self,
|
|
891
|
-
profile_id: str,
|
|
892
|
-
fact_types: list[str],
|
|
893
|
-
sort_by: str = "access_count",
|
|
894
|
-
limit: int = 5,
|
|
895
|
-
) -> list[dict]:
|
|
896
|
-
"""Get top facts by type and sort criteria."""
|
|
897
|
-
type_placeholders = ",".join("?" * len(fact_types))
|
|
898
|
-
|
|
899
|
-
if sort_by == "recency":
|
|
900
|
-
query = (
|
|
901
|
-
f"SELECT fact_id, content, fact_type FROM atomic_facts "
|
|
902
|
-
f"WHERE profile_id = ? AND fact_type IN ({type_placeholders}) "
|
|
903
|
-
f"AND lifecycle = 'active' "
|
|
904
|
-
f"ORDER BY created_at DESC LIMIT ?"
|
|
905
|
-
)
|
|
906
|
-
else:
|
|
907
|
-
query = (
|
|
908
|
-
f"SELECT f.fact_id, f.content, f.fact_type, "
|
|
909
|
-
f" COUNT(a.log_id) as access_count "
|
|
910
|
-
f"FROM atomic_facts f "
|
|
911
|
-
f"LEFT JOIN fact_access_log a ON f.fact_id = a.fact_id "
|
|
912
|
-
f"WHERE f.profile_id = ? AND f.fact_type IN ({type_placeholders}) "
|
|
913
|
-
f"AND f.lifecycle = 'active' "
|
|
914
|
-
f"GROUP BY f.fact_id "
|
|
915
|
-
f"ORDER BY access_count DESC LIMIT ?"
|
|
916
|
-
)
|
|
917
|
-
|
|
918
|
-
params: list[Any] = [profile_id] + fact_types + [limit]
|
|
919
|
-
rows = self._db.execute(query, tuple(params))
|
|
920
|
-
return [dict(r) for r in (rows or [])]
|
|
921
|
-
|
|
922
|
-
def _facts_to_content(
|
|
923
|
-
self, facts: list[dict], char_limit: int,
|
|
924
|
-
) -> str:
|
|
925
|
-
"""Compile fact contents into a block with hygiene (v3.6.6 F-5).
|
|
926
|
-
|
|
927
|
-
Filters low-quality/template facts, dedupes lines WITHIN the block
|
|
928
|
-
(fixes the "same fixture ×5" core-block bug), caps at char_limit.
|
|
929
|
-
"""
|
|
930
|
-
from superlocalmemory.core.block_hygiene import compile_block_content
|
|
931
|
-
compiled = compile_block_content(facts, max_chars=char_limit)
|
|
932
|
-
return compiled if compiled else "No data available."
|
|
933
|
-
|
|
934
|
-
def _rows_to_content(
|
|
935
|
-
self, rows: list | None, char_limit: int,
|
|
936
|
-
) -> str:
|
|
937
|
-
"""Convert DB rows to a hygienic block content string (v3.6.6 F-5)."""
|
|
938
|
-
if not rows:
|
|
939
|
-
return "No data available."
|
|
940
|
-
from superlocalmemory.core.block_hygiene import compile_block_content
|
|
941
|
-
facts = [dict(r) for r in rows]
|
|
942
|
-
compiled = compile_block_content(facts, max_chars=char_limit)
|
|
943
|
-
return compiled if compiled else "No data available."
|
|
944
|
-
|
|
945
|
-
def _compile_behavioral_block(
|
|
946
|
-
self, profile_id: str, char_limit: int,
|
|
947
|
-
) -> str:
|
|
948
|
-
"""Compile behavioral patterns into a block content string."""
|
|
949
|
-
if self._behavioral is None:
|
|
950
|
-
return "No behavioral patterns detected yet."
|
|
951
|
-
|
|
952
|
-
try:
|
|
953
|
-
from superlocalmemory.learning.behavioral import BehavioralTracker
|
|
954
|
-
|
|
955
|
-
if isinstance(self._behavioral, BehavioralTracker):
|
|
956
|
-
patterns = self._db.execute(
|
|
957
|
-
"SELECT pattern_type, pattern_key, confidence "
|
|
958
|
-
"FROM behavioral_patterns "
|
|
959
|
-
"WHERE profile_id = ? ORDER BY confidence DESC LIMIT 5",
|
|
960
|
-
(profile_id,),
|
|
961
|
-
)
|
|
962
|
-
else:
|
|
963
|
-
patterns = self._behavioral.get_patterns(
|
|
964
|
-
profile_id, limit=5,
|
|
965
|
-
)
|
|
966
|
-
|
|
967
|
-
if not patterns:
|
|
968
|
-
return "No behavioral patterns detected yet."
|
|
969
|
-
|
|
970
|
-
parts: list[str] = []
|
|
971
|
-
for p in patterns:
|
|
972
|
-
d = dict(p)
|
|
973
|
-
ptype = d.get("pattern_type", "")
|
|
974
|
-
pkey = d.get("pattern_key", "")
|
|
975
|
-
conf = d.get("confidence", 0)
|
|
976
|
-
parts.append(
|
|
977
|
-
f"{ptype}: {pkey} (confidence: {conf:.2f})"
|
|
978
|
-
)
|
|
979
|
-
|
|
980
|
-
content = "\n---\n".join(parts)
|
|
981
|
-
return content[:char_limit]
|
|
982
|
-
except Exception:
|
|
983
|
-
return "No behavioral patterns detected yet."
|