hippo-memory 1.59.0 → 1.61.0
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/README.md +1 -1
- package/dist/ablation.js +9 -27
- package/dist/agent-memories/apply.js +4 -1
- package/dist/agent-memories/claude-code.js +1 -1
- package/dist/agent-memories/codex.js +1 -1
- package/dist/agent-memories/gemini.js +1 -1
- package/dist/agent-memories/legacy.js +1 -1
- package/dist/agent-memories/source.js +1 -1
- package/dist/agent-memories/sync.js +8 -3
- package/dist/ambient-store.d.ts +14 -0
- package/dist/ambient-store.js +90 -0
- package/dist/ambient.d.ts +23 -0
- package/dist/ambient.js +72 -50
- package/dist/api/assemble.d.ts +93 -0
- package/dist/api/assemble.js +152 -0
- package/dist/api/audit.d.ts +17 -0
- package/dist/api/audit.js +23 -0
- package/dist/api/auth.d.ts +79 -0
- package/dist/api/auth.js +178 -0
- package/dist/api/context-types.d.ts +105 -0
- package/dist/api/context-types.js +3 -0
- package/dist/api/context.d.ts +31 -0
- package/dist/api/context.js +705 -0
- package/dist/api/dormant.d.ts +30 -0
- package/dist/api/dormant.js +140 -0
- package/dist/api/drill-down.d.ts +84 -0
- package/dist/api/drill-down.js +123 -0
- package/dist/api/forget.d.ts +57 -0
- package/dist/api/forget.js +87 -0
- package/dist/api/goals.d.ts +18 -0
- package/dist/api/goals.js +33 -0
- package/dist/api/learn.d.ts +31 -0
- package/dist/api/learn.js +88 -0
- package/dist/api/outcome.d.ts +61 -0
- package/dist/api/outcome.js +66 -0
- package/dist/api/promote.d.ts +54 -0
- package/dist/api/promote.js +203 -0
- package/dist/api/quarantine.d.ts +24 -0
- package/dist/api/quarantine.js +121 -0
- package/dist/api/recall-types.d.ts +390 -0
- package/dist/api/recall-types.js +3 -0
- package/dist/api/recall.d.ts +36 -0
- package/dist/api/recall.js +634 -0
- package/dist/api/remember.d.ts +35 -0
- package/dist/api/remember.js +43 -0
- package/dist/api/sleep.d.ts +136 -0
- package/dist/api/sleep.js +271 -0
- package/dist/api/tokens.d.ts +26 -0
- package/dist/api/tokens.js +60 -0
- package/dist/api/types.d.ts +56 -0
- package/dist/api/types.js +38 -0
- package/dist/api.d.ts +20 -1260
- package/dist/api.js +25 -2711
- package/dist/audit.d.ts +3 -0
- package/dist/audit.js +7 -3
- package/dist/auth.d.ts +45 -4
- package/dist/auth.js +125 -48
- package/dist/autolearn.js +7 -4
- package/dist/capture/command.d.ts +33 -0
- package/dist/capture/command.js +264 -0
- package/dist/capture/compact.d.ts +44 -0
- package/dist/capture/compact.js +354 -0
- package/dist/capture/extract.d.ts +21 -0
- package/dist/capture/extract.js +464 -0
- package/dist/capture/transcript.d.ts +40 -0
- package/dist/capture/transcript.js +193 -0
- package/dist/capture-error.js +2 -1
- package/dist/churn-git.js +4 -2
- package/dist/cli/audit.d.ts +3 -0
- package/dist/cli/audit.js +159 -0
- package/dist/cli/auth.d.ts +2 -0
- package/dist/cli/auth.js +171 -0
- package/dist/cli/briefs.d.ts +4 -0
- package/dist/cli/briefs.js +435 -0
- package/dist/cli/card.d.ts +3 -0
- package/dist/cli/card.js +333 -0
- package/dist/cli/context.d.ts +15 -0
- package/dist/cli/context.js +366 -0
- package/dist/cli/continuity.d.ts +6 -0
- package/dist/cli/continuity.js +445 -0
- package/dist/cli/curate.d.ts +19 -0
- package/dist/cli/curate.js +555 -0
- package/dist/cli/dag.d.ts +5 -0
- package/dist/cli/dag.js +177 -0
- package/dist/cli/decisions.d.ts +4 -0
- package/dist/cli/decisions.js +528 -0
- package/dist/cli/eval.d.ts +5 -0
- package/dist/cli/eval.js +213 -0
- package/dist/cli/explain.d.ts +4 -0
- package/dist/cli/explain.js +150 -0
- package/dist/cli/goals.d.ts +2 -0
- package/dist/cli/goals.js +196 -0
- package/dist/cli/hook-blocks.d.ts +18 -0
- package/dist/cli/hook-blocks.js +233 -0
- package/dist/cli/init.d.ts +2 -0
- package/dist/cli/init.js +305 -0
- package/dist/cli/maintenance.d.ts +4 -0
- package/dist/cli/maintenance.js +179 -0
- package/dist/cli/playbooks.d.ts +4 -0
- package/dist/cli/playbooks.js +556 -0
- package/dist/cli/projects.js +1 -1
- package/dist/cli/recall.d.ts +7 -0
- package/dist/cli/recall.js +597 -0
- package/dist/cli/remember.d.ts +5 -0
- package/dist/cli/remember.js +442 -0
- package/dist/cli/serve.d.ts +5 -0
- package/dist/cli/serve.js +40 -0
- package/dist/cli/session-hooks.d.ts +29 -0
- package/dist/cli/session-hooks.js +637 -0
- package/dist/cli/setup.d.ts +4 -0
- package/dist/cli/setup.js +376 -0
- package/dist/cli/shared.d.ts +15 -19
- package/dist/cli/shared.js +50 -341
- package/dist/cli/slack.d.ts +2 -0
- package/dist/cli/slack.js +171 -0
- package/dist/cli/status.d.ts +18 -0
- package/dist/cli/status.js +400 -0
- package/dist/cli/transfer.d.ts +10 -0
- package/dist/cli/transfer.js +438 -0
- package/dist/cli/usage.d.ts +85 -0
- package/dist/cli/usage.js +741 -0
- package/dist/cli.d.ts +319 -13
- package/dist/cli.js +436 -8580
- package/dist/client.js +15 -8
- package/dist/compaction-record.js +12 -9
- package/dist/config.js +12 -11
- package/dist/connectors/github/backfill.js +94 -87
- package/dist/connectors/github/cli-impl.js +5 -3
- package/dist/connectors/github/dlq.js +67 -54
- package/dist/connectors/github/ingest.js +34 -35
- package/dist/connectors/github/tenant-routing.js +3 -2
- package/dist/connectors/github/webhook.js +135 -216
- package/dist/connectors/slack/dlq.js +49 -61
- package/dist/connectors/slack/ingest.js +55 -48
- package/dist/connectors/slack/tenant-routing.js +4 -3
- package/dist/connectors/slack/webhook.js +72 -74
- package/dist/consolidate/conflicts.d.ts +10 -0
- package/dist/consolidate/conflicts.js +178 -0
- package/dist/consolidate/decay.d.ts +12 -0
- package/dist/consolidate/decay.js +145 -0
- package/dist/consolidate/llm-passes.d.ts +3 -0
- package/dist/consolidate/llm-passes.js +141 -0
- package/dist/consolidate/merge.d.ts +7 -0
- package/dist/consolidate/merge.js +251 -0
- package/dist/consolidate/physics-pass.d.ts +3 -0
- package/dist/consolidate/physics-pass.js +60 -0
- package/dist/consolidate/run.d.ts +69 -0
- package/dist/consolidate/run.js +76 -0
- package/dist/consolidate/sleep.d.ts +18 -0
- package/dist/consolidate/sleep.js +209 -0
- package/dist/consolidate/traces.d.ts +4 -0
- package/dist/consolidate/traces.js +178 -0
- package/dist/context-auto.js +7 -11
- package/dist/context-render.d.ts +1 -1
- package/dist/context-render.js +1 -1
- package/dist/customer-notes.d.ts +3 -0
- package/dist/customer-notes.js +6 -4
- package/dist/dag.js +13 -12
- package/dist/dashboard-actions.d.ts +20 -0
- package/dist/dashboard-actions.js +88 -0
- package/dist/dashboard-params.d.ts +45 -0
- package/dist/dashboard-params.js +127 -0
- package/dist/dashboard-queries.d.ts +15 -0
- package/dist/dashboard-queries.js +355 -0
- package/dist/dashboard-snapshot.d.ts +138 -0
- package/dist/dashboard-snapshot.js +308 -0
- package/dist/dashboard-types.d.ts +163 -0
- package/dist/dashboard-types.js +3 -0
- package/dist/dashboard.d.ts +6 -7
- package/dist/dashboard.js +231 -203
- package/dist/db/busy.d.ts +5 -0
- package/dist/db/busy.js +24 -0
- package/dist/db/continuity.d.ts +5 -0
- package/dist/db/continuity.js +145 -0
- package/dist/db/meta.d.ts +8 -0
- package/dist/db/meta.js +35 -0
- package/dist/db/migrate.d.ts +9 -0
- package/dist/db/migrate.js +138 -0
- package/dist/db/migrations/index.d.ts +5 -0
- package/dist/db/migrations/index.js +109 -0
- package/dist/db/migrations/types.d.ts +14 -0
- package/dist/db/migrations/types.js +2 -0
- package/dist/db/migrations/v01.d.ts +3 -0
- package/dist/db/migrations/v01.js +38 -0
- package/dist/db/migrations/v02.d.ts +3 -0
- package/dist/db/migrations/v02.js +21 -0
- package/dist/db/migrations/v03.d.ts +3 -0
- package/dist/db/migrations/v03.js +22 -0
- package/dist/db/migrations/v04.d.ts +3 -0
- package/dist/db/migrations/v04.js +28 -0
- package/dist/db/migrations/v05.d.ts +3 -0
- package/dist/db/migrations/v05.js +21 -0
- package/dist/db/migrations/v06.d.ts +3 -0
- package/dist/db/migrations/v06.js +25 -0
- package/dist/db/migrations/v07.d.ts +3 -0
- package/dist/db/migrations/v07.js +13 -0
- package/dist/db/migrations/v08.d.ts +3 -0
- package/dist/db/migrations/v08.js +8 -0
- package/dist/db/migrations/v09.d.ts +3 -0
- package/dist/db/migrations/v09.js +13 -0
- package/dist/db/migrations/v10.d.ts +3 -0
- package/dist/db/migrations/v10.js +17 -0
- package/dist/db/migrations/v11.d.ts +3 -0
- package/dist/db/migrations/v11.js +15 -0
- package/dist/db/migrations/v12.d.ts +3 -0
- package/dist/db/migrations/v12.js +11 -0
- package/dist/db/migrations/v13.d.ts +3 -0
- package/dist/db/migrations/v13.js +15 -0
- package/dist/db/migrations/v14.d.ts +3 -0
- package/dist/db/migrations/v14.js +66 -0
- package/dist/db/migrations/v15.d.ts +3 -0
- package/dist/db/migrations/v15.js +42 -0
- package/dist/db/migrations/v16.d.ts +3 -0
- package/dist/db/migrations/v16.js +61 -0
- package/dist/db/migrations/v17.d.ts +3 -0
- package/dist/db/migrations/v17.js +46 -0
- package/dist/db/migrations/v18.d.ts +3 -0
- package/dist/db/migrations/v18.js +60 -0
- package/dist/db/migrations/v19.d.ts +3 -0
- package/dist/db/migrations/v19.js +28 -0
- package/dist/db/migrations/v20.d.ts +3 -0
- package/dist/db/migrations/v20.js +42 -0
- package/dist/db/migrations/v21.d.ts +3 -0
- package/dist/db/migrations/v21.js +16 -0
- package/dist/db/migrations/v22.d.ts +3 -0
- package/dist/db/migrations/v22.js +82 -0
- package/dist/db/migrations/v23.d.ts +3 -0
- package/dist/db/migrations/v23.js +48 -0
- package/dist/db/migrations/v24.d.ts +3 -0
- package/dist/db/migrations/v24.js +72 -0
- package/dist/db/migrations/v25.d.ts +3 -0
- package/dist/db/migrations/v25.js +46 -0
- package/dist/db/migrations/v26.d.ts +3 -0
- package/dist/db/migrations/v26.js +23 -0
- package/dist/db/migrations/v27.d.ts +3 -0
- package/dist/db/migrations/v27.js +57 -0
- package/dist/db/migrations/v28.d.ts +3 -0
- package/dist/db/migrations/v28.js +38 -0
- package/dist/db/migrations/v29.d.ts +3 -0
- package/dist/db/migrations/v29.js +78 -0
- package/dist/db/migrations/v30.d.ts +3 -0
- package/dist/db/migrations/v30.js +92 -0
- package/dist/db/migrations/v31.d.ts +3 -0
- package/dist/db/migrations/v31.js +74 -0
- package/dist/db/migrations/v32.d.ts +3 -0
- package/dist/db/migrations/v32.js +102 -0
- package/dist/db/migrations/v33.d.ts +3 -0
- package/dist/db/migrations/v33.js +104 -0
- package/dist/db/migrations/v34.d.ts +3 -0
- package/dist/db/migrations/v34.js +93 -0
- package/dist/db/migrations/v35.d.ts +3 -0
- package/dist/db/migrations/v35.js +98 -0
- package/dist/db/migrations/v36.d.ts +3 -0
- package/dist/db/migrations/v36.js +98 -0
- package/dist/db/migrations/v37.d.ts +3 -0
- package/dist/db/migrations/v37.js +219 -0
- package/dist/db/migrations/v38.d.ts +3 -0
- package/dist/db/migrations/v38.js +277 -0
- package/dist/db/migrations/v39.d.ts +3 -0
- package/dist/db/migrations/v39.js +59 -0
- package/dist/db/migrations/v40.d.ts +3 -0
- package/dist/db/migrations/v40.js +74 -0
- package/dist/db/migrations/v41.d.ts +3 -0
- package/dist/db/migrations/v41.js +43 -0
- package/dist/db/migrations/v42.d.ts +3 -0
- package/dist/db/migrations/v42.js +41 -0
- package/dist/db/migrations/v43.d.ts +3 -0
- package/dist/db/migrations/v43.js +67 -0
- package/dist/db/migrations/v44.d.ts +3 -0
- package/dist/db/migrations/v44.js +28 -0
- package/dist/db/migrations/v45.d.ts +3 -0
- package/dist/db/migrations/v45.js +30 -0
- package/dist/db/migrations/v46.d.ts +3 -0
- package/dist/db/migrations/v46.js +25 -0
- package/dist/db/migrations/v47.d.ts +3 -0
- package/dist/db/migrations/v47.js +17 -0
- package/dist/db/migrations/v48.d.ts +3 -0
- package/dist/db/migrations/v48.js +10 -0
- package/dist/db/migrations/v49.d.ts +3 -0
- package/dist/db/migrations/v49.js +31 -0
- package/dist/db/migrations/v50.d.ts +3 -0
- package/dist/db/migrations/v50.js +67 -0
- package/dist/db/migrations/v51.d.ts +3 -0
- package/dist/db/migrations/v51.js +14 -0
- package/dist/db/migrations/v52.d.ts +3 -0
- package/dist/db/migrations/v52.js +7 -0
- package/dist/db/open.d.ts +23 -0
- package/dist/db/open.js +146 -0
- package/dist/db/sqlite.d.ts +21 -0
- package/dist/db/sqlite.js +8 -0
- package/dist/db/tables.d.ts +7 -0
- package/dist/db/tables.js +38 -0
- package/dist/db.d.ts +6 -46
- package/dist/db.js +5 -3036
- package/dist/decisions.d.ts +4 -1
- package/dist/decisions.js +9 -7
- package/dist/dedupe.js +3 -2
- package/dist/delivery-recorder.js +5 -1
- package/dist/doctor.js +4 -3
- package/dist/dormant.js +1 -0
- package/dist/embedding-provider.d.ts +1 -1
- package/dist/embedding-provider.js +7 -5
- package/dist/embeddings.d.ts +9 -52
- package/dist/embeddings.js +47 -298
- package/dist/env.d.ts +75 -0
- package/dist/env.js +119 -0
- package/dist/eval-suite.js +1 -1
- package/dist/eval.js +2 -2
- package/dist/extract.js +5 -4
- package/dist/gated-write.js +3 -1
- package/dist/goals.d.ts +3 -1
- package/dist/goals.js +18 -0
- package/dist/graph/read.d.ts +73 -0
- package/dist/graph/read.js +325 -0
- package/dist/graph/rows.d.ts +45 -0
- package/dist/graph/rows.js +51 -0
- package/dist/graph/types.d.ts +83 -0
- package/dist/graph/types.js +11 -0
- package/dist/graph/write.d.ts +93 -0
- package/dist/{graph.js → graph/write.js} +8 -391
- package/dist/graph-extract.js +2 -1
- package/dist/graph-recall.d.ts +1 -1
- package/dist/graph-recall.js +2 -2
- package/dist/graph-stream.js +1 -1
- package/dist/graph-view.d.ts +1 -1
- package/dist/graph-view.js +1 -1
- package/dist/half-life-migration.d.ts +1 -1
- package/dist/half-life-migration.js +2 -1
- package/dist/handoff.js +3 -0
- package/dist/hooks/codex-session.d.ts +8 -0
- package/dist/hooks/codex-session.js +76 -0
- package/dist/hooks/codex-wrapper.d.ts +55 -0
- package/dist/hooks/codex-wrapper.js +288 -0
- package/dist/hooks/json-hooks.d.ts +63 -0
- package/dist/hooks/json-hooks.js +356 -0
- package/dist/hooks/opencode.d.ts +50 -0
- package/dist/hooks/opencode.js +202 -0
- package/dist/hooks/shared.d.ts +54 -0
- package/dist/hooks/shared.js +77 -0
- package/dist/http-retry.d.ts +2 -0
- package/dist/http-retry.js +4 -3
- package/dist/http-util.d.ts +3 -0
- package/dist/http-util.js +10 -0
- package/dist/{importers.d.ts → importers/core.d.ts} +13 -17
- package/dist/importers/core.js +141 -0
- package/dist/importers/markdown-parse.d.ts +41 -0
- package/dist/importers/markdown-parse.js +132 -0
- package/dist/importers/markdown.d.ts +3 -0
- package/dist/importers/markdown.js +92 -0
- package/dist/importers/sources.d.ts +7 -0
- package/dist/importers/sources.js +229 -0
- package/dist/importers/vault.d.ts +11 -0
- package/dist/importers/vault.js +352 -0
- package/dist/incidents.d.ts +3 -0
- package/dist/incidents.js +8 -5
- package/dist/index.d.ts +25 -6
- package/dist/index.js +23 -6
- package/dist/invalidation.js +2 -1
- package/dist/judgment.js +7 -3
- package/dist/keyset.d.ts +13 -0
- package/dist/keyset.js +8 -0
- package/dist/local-embedding.d.ts +13 -0
- package/dist/local-embedding.js +165 -0
- package/dist/log.d.ts +7 -0
- package/dist/log.js +19 -1
- package/dist/mcp/admin-tools.d.ts +8 -0
- package/dist/mcp/admin-tools.js +116 -0
- package/dist/mcp/format.d.ts +27 -0
- package/dist/mcp/format.js +135 -0
- package/dist/mcp/memory-tools.d.ts +5 -0
- package/dist/mcp/memory-tools.js +83 -0
- package/dist/mcp/protocol.d.ts +83 -0
- package/dist/mcp/protocol.js +55 -0
- package/dist/mcp/recall-tools.d.ts +6 -0
- package/dist/mcp/recall-tools.js +320 -0
- package/dist/mcp/request.d.ts +10 -0
- package/dist/mcp/request.js +163 -0
- package/dist/mcp/server.d.ts +4 -70
- package/dist/mcp/server.js +8 -1172
- package/dist/mcp/session-state.d.ts +11 -0
- package/dist/mcp/session-state.js +28 -0
- package/dist/mcp/stdio.d.ts +8 -0
- package/dist/mcp/stdio.js +79 -0
- package/dist/mcp/tools.d.ts +11 -0
- package/dist/mcp/tools.js +247 -0
- package/dist/memory.d.ts +8 -3
- package/dist/memory.js +27 -1
- package/dist/multihop.d.ts +1 -1
- package/dist/multihop.js +2 -1
- package/dist/owner-validation.js +2 -1
- package/dist/physics-state.js +10 -7
- package/dist/policies.d.ts +3 -0
- package/dist/policies.js +8 -6
- package/dist/postinstall.js +3 -2
- package/dist/predictions/planning-fallacy.d.ts +100 -0
- package/dist/predictions/planning-fallacy.js +190 -0
- package/dist/{predictions.d.ts → predictions/store.d.ts} +7 -102
- package/dist/predictions/store.js +434 -0
- package/dist/processes.d.ts +3 -0
- package/dist/processes.js +8 -5
- package/dist/project-briefs.d.ts +3 -0
- package/dist/project-briefs.js +7 -5
- package/dist/project-identity.d.ts +1 -1
- package/dist/project-identity.js +12 -6
- package/dist/project-merge.js +3 -1
- package/dist/quarantine.d.ts +2 -1
- package/dist/quarantine.js +8 -5
- package/dist/raw-archive-mirror-cleanup.js +2 -1
- package/dist/raw-archive.js +1 -1
- package/dist/recall-history.js +3 -2
- package/dist/recall-pipeline.d.ts +2 -2
- package/dist/recall-pipeline.js +16 -8
- package/dist/recall-scope.js +1 -1
- package/dist/recall-trace.d.ts +3 -3
- package/dist/recall-trace.js +10 -14
- package/dist/refine-llm.js +20 -11
- package/dist/reject-flow.js +6 -1
- package/dist/rerankers/clef.d.ts +2 -2
- package/dist/rerankers/clef.js +72 -30
- package/dist/rerankers/cross-encoder.js +6 -4
- package/dist/rerankers/jev.d.ts +4 -2
- package/dist/rerankers/jev.js +24 -19
- package/dist/rerankers/llm.d.ts +4 -2
- package/dist/rerankers/llm.js +61 -41
- package/dist/rerankers/types.d.ts +1 -1
- package/dist/salience.js +1 -1
- package/dist/same-text.d.ts +2 -0
- package/dist/same-text.js +4 -0
- package/dist/scheduler.d.ts +1 -0
- package/dist/scheduler.js +26 -3
- package/dist/scope.js +4 -3
- package/dist/search/as-of.d.ts +10 -0
- package/dist/search/as-of.js +22 -0
- package/dist/search/bm25-search.d.ts +14 -0
- package/dist/search/bm25-search.js +43 -0
- package/dist/search/bm25.d.ts +15 -0
- package/dist/search/bm25.js +54 -0
- package/dist/search/boosts.d.ts +54 -0
- package/dist/search/boosts.js +94 -0
- package/dist/search/breakdown.d.ts +7 -0
- package/dist/search/breakdown.js +20 -0
- package/dist/search/explain.d.ts +25 -0
- package/dist/search/explain.js +31 -0
- package/dist/search/finalize.d.ts +8 -0
- package/dist/search/finalize.js +52 -0
- package/dist/search/fusion.d.ts +27 -0
- package/dist/search/fusion.js +42 -0
- package/dist/search/hybrid-score.d.ts +20 -0
- package/dist/search/hybrid-score.js +73 -0
- package/dist/search/hybrid.d.ts +46 -0
- package/dist/search/hybrid.js +64 -0
- package/dist/search/physics-search.d.ts +29 -0
- package/dist/search/physics-search.js +162 -0
- package/dist/search/rerank.d.ts +10 -0
- package/dist/search/rerank.js +72 -0
- package/dist/search/temporal.d.ts +15 -0
- package/dist/search/temporal.js +45 -0
- package/dist/search/types.d.ts +91 -0
- package/dist/search/types.js +2 -0
- package/dist/search/vector.d.ts +30 -0
- package/dist/search/vector.js +71 -0
- package/dist/secret-detect.d.ts +2 -0
- package/dist/secret-detect.js +3 -1
- package/dist/server/auth.d.ts +52 -0
- package/dist/server/auth.js +221 -0
- package/dist/server/client-ip.d.ts +25 -0
- package/dist/server/client-ip.js +92 -0
- package/dist/server/cursor.d.ts +23 -0
- package/dist/server/cursor.js +58 -0
- package/dist/server/lifecycle.d.ts +7 -0
- package/dist/server/lifecycle.js +29 -0
- package/dist/server/mcp-http.d.ts +5 -0
- package/dist/server/mcp-http.js +199 -0
- package/dist/server/request.d.ts +33 -0
- package/dist/server/request.js +103 -0
- package/dist/server/routes/admin.d.ts +9 -0
- package/dist/server/routes/admin.js +158 -0
- package/dist/server/routes/customer-notes.d.ts +7 -0
- package/dist/server/routes/customer-notes.js +112 -0
- package/dist/server/routes/decisions.d.ts +7 -0
- package/dist/server/routes/decisions.js +133 -0
- package/dist/server/routes/incidents.d.ts +7 -0
- package/dist/server/routes/incidents.js +126 -0
- package/dist/server/routes/memories.d.ts +10 -0
- package/dist/server/routes/memories.js +179 -0
- package/dist/server/routes/policies.d.ts +8 -0
- package/dist/server/routes/policies.js +151 -0
- package/dist/server/routes/predictions.d.ts +7 -0
- package/dist/server/routes/predictions.js +164 -0
- package/dist/server/routes/processes.d.ts +7 -0
- package/dist/server/routes/processes.js +161 -0
- package/dist/server/routes/project-briefs.d.ts +8 -0
- package/dist/server/routes/project-briefs.js +136 -0
- package/dist/server/routes/recall.d.ts +8 -0
- package/dist/server/routes/recall.js +340 -0
- package/dist/server/routes/skills.d.ts +8 -0
- package/dist/server/routes/skills.js +150 -0
- package/dist/server/types.d.ts +56 -0
- package/dist/server/types.js +2 -0
- package/dist/server/validation.d.ts +14 -0
- package/dist/server/validation.js +91 -0
- package/dist/server.d.ts +7 -61
- package/dist/server.js +92 -2368
- package/dist/session-digest.d.ts +1 -1
- package/dist/session-digest.js +9 -2
- package/dist/shared.d.ts +3 -1
- package/dist/shared.js +46 -40
- package/dist/skills.d.ts +3 -0
- package/dist/skills.js +7 -5
- package/dist/stdin.js +3 -2
- package/dist/store/audit-event.d.ts +19 -0
- package/dist/store/audit-event.js +33 -0
- package/dist/store/candidates.d.ts +42 -0
- package/dist/store/candidates.js +152 -0
- package/dist/store/conflicts.d.ts +44 -0
- package/dist/store/conflicts.js +444 -0
- package/dist/store/delete-and-batch.d.ts +63 -0
- package/dist/store/delete-and-batch.js +310 -0
- package/dist/store/entry-reads.d.ts +92 -0
- package/dist/store/entry-reads.js +255 -0
- package/dist/store/entry-row.d.ts +67 -0
- package/dist/store/entry-row.js +208 -0
- package/dist/store/entry-writes.d.ts +46 -0
- package/dist/store/entry-writes.js +148 -0
- package/dist/store/handoffs.d.ts +26 -0
- package/dist/store/handoffs.js +184 -0
- package/dist/store/index-and-stats.d.ts +52 -0
- package/dist/store/index-and-stats.js +214 -0
- package/dist/store/markdown.d.ts +10 -0
- package/dist/store/markdown.js +108 -0
- package/dist/store/mirrors.d.ts +49 -0
- package/dist/store/mirrors.js +312 -0
- package/dist/store/open.d.ts +15 -0
- package/dist/store/open.js +223 -0
- package/dist/store/rows.d.ts +178 -0
- package/dist/store/rows.js +158 -0
- package/dist/store/search-rows.d.ts +86 -0
- package/dist/store/search-rows.js +254 -0
- package/dist/store/sessions.d.ts +83 -0
- package/dist/store/sessions.js +272 -0
- package/dist/store/summaries.d.ts +94 -0
- package/dist/store/summaries.js +377 -0
- package/dist/store/tenant-lookup.d.ts +12 -0
- package/dist/store/tenant-lookup.js +16 -0
- package/dist/store-cards.js +2 -1
- package/dist/summary-dirty.d.ts +4 -0
- package/dist/summary-dirty.js +32 -0
- package/dist/support-bundle.js +4 -3
- package/dist/tenant.js +2 -2
- package/dist/token-ledger.js +1 -0
- package/dist/tokenize.d.ts +2 -0
- package/dist/tokenize.js +16 -0
- package/dist/transcript-tail.d.ts +7 -0
- package/dist/transcript-tail.js +48 -0
- package/dist/vector-store.d.ts +27 -0
- package/dist/vector-store.js +210 -0
- package/dist/version.d.ts +2 -2
- package/dist/version.js +2 -2
- package/dist/working-memory.js +1 -1
- package/dist/yaml.js +36 -11
- package/dist-ui/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
- package/dist-ui/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
- package/dist-ui/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
- package/dist-ui/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
- package/dist-ui/assets/ibm-plex-mono-latin-600-normal-BgSNZQsw.woff2 +0 -0
- package/dist-ui/assets/ibm-plex-mono-latin-600-normal-DWFSQ4vo.woff +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
- package/dist-ui/assets/index-DPN7cP19.js +33 -0
- package/dist-ui/assets/index-dFloKRVr.css +1 -0
- package/dist-ui/index.html +3 -25
- package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
- package/extensions/openclaw-plugin/package.json +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +2 -1
- package/dist/capture.d.ts +0 -155
- package/dist/capture.js +0 -1293
- package/dist/consolidate.d.ts +0 -58
- package/dist/consolidate.js +0 -1123
- package/dist/graph.d.ts +0 -245
- package/dist/hooks.d.ts +0 -208
- package/dist/hooks.js +0 -1073
- package/dist/importers.js +0 -897
- package/dist/predictions.js +0 -620
- package/dist/search.d.ts +0 -320
- package/dist/search.js +0 -968
- package/dist/store.d.ts +0 -744
- package/dist/store.js +0 -3372
- package/dist-ui/assets/d3-BiWEKnn4.js +0 -1
- package/dist-ui/assets/index-BhT8RvO6.js +0 -61
- package/dist-ui/assets/index-RoXXJ5dq.css +0 -1
- package/dist-ui/assets/three-BDgTxR1l.js +0 -4112
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { Layer, calculateStrength } from '../memory.js';
|
|
2
|
+
import { jaccardMinShared, overlapPartners } from '../overlap-index.js';
|
|
3
|
+
import { isQuarantineScope } from '../quarantine.js';
|
|
4
|
+
import { DECAY_THRESHOLD } from './decay.js';
|
|
5
|
+
// Contradictions should be gated by content overlap, not shared tags. Tags like
|
|
6
|
+
// `feedback` / `policy` are too coarse and can make unrelated rules look like
|
|
7
|
+
// conflicts before the polarity heuristics run.
|
|
8
|
+
// Jaccard threshold on stopword-filtered tokens. Only applied after a polarity
|
|
9
|
+
// signal has already been detected (explicit pair or inferred negation), so
|
|
10
|
+
// this just filters out drive-by topic similarity, not semantic drift.
|
|
11
|
+
const CONFLICT_OVERLAP_THRESHOLD = 0.5;
|
|
12
|
+
// Minimum distinctive shared tokens before we trust an overlap score. Filters
|
|
13
|
+
// out cases where two memories share only common English + a project name.
|
|
14
|
+
const CONFLICT_MIN_RARE_SHARED = 2;
|
|
15
|
+
// Polarity is detected on the first N words only. A stray "not" in the middle
|
|
16
|
+
// of a long memory shouldn't flip the whole thing negative.
|
|
17
|
+
const POLARITY_WINDOW_WORDS = 40;
|
|
18
|
+
const CONFLICT_STOPWORDS = new Set([
|
|
19
|
+
'the', 'a', 'an', 'is', 'was', 'are', 'were', 'be', 'been', 'being', 'to', 'of', 'in',
|
|
20
|
+
'for', 'on', 'with', 'at', 'by', 'from', 'it', 'this', 'that', 'and', 'or', 'but', 'so',
|
|
21
|
+
'if', 'as', 'we', 'i', 'you', 'they', 'he', 'she', 'my', 'our', 'your', 'its', 'his',
|
|
22
|
+
'her', 'their', 'up', 'out', 'just', 'also', 'then', 'than', 'some', 'all', 'any',
|
|
23
|
+
'each', 'very', 'too', 'do', 'did', 'does', 'has', 'had', 'have', 'will', 'would',
|
|
24
|
+
'could', 'should', 'may', 'might', 'can', 'shall', 'when', 'where', 'what', 'which',
|
|
25
|
+
'who', 'how', 'why', 'there', 'here', 'about', 'into', 'over', 'after', 'before',
|
|
26
|
+
'between', 'through', 'during', 'against', 'within', 'without', 'toward', 'upon',
|
|
27
|
+
'more', 'most', 'less', 'least', 'other', 'such', 'same', 'new', 'old', 'one', 'two',
|
|
28
|
+
]);
|
|
29
|
+
/** Pairs of live non-semantic memories that contradict each other, in survivor order. */
|
|
30
|
+
export function detectConflicts(entries, now, decayOpts = {},
|
|
31
|
+
// LC2-E3 (opt-in, default off): ids rescued by this cycle's decay pass.
|
|
32
|
+
// detectConflicts recomputes its own strength>=DECAY_THRESHOLD survivor
|
|
33
|
+
// filter independently of the decay pass above; without this bypass,
|
|
34
|
+
// rescued entries would be silently re-excluded from conflict detection
|
|
35
|
+
// every cycle even though the decay pass just decided to keep them.
|
|
36
|
+
// Default empty set: flag-off behavior is unchanged.
|
|
37
|
+
rescuedIds = new Set()) {
|
|
38
|
+
const survivors = entries.filter((entry) => entry.layer !== Layer.Semantic
|
|
39
|
+
// CD5: an unreviewed quarantined row must not taint a visible memory as conflicted.
|
|
40
|
+
&& !isQuarantineScope(entry.scope ?? null)
|
|
41
|
+
&& (rescuedIds.has(entry.id) || calculateStrength(entry, now, decayOpts) >= DECAY_THRESHOLD));
|
|
42
|
+
const detected = [];
|
|
43
|
+
const profiles = survivors.map((entry) => conflictProfile(entry.content));
|
|
44
|
+
const partnersOf = overlapPartners(profiles.map((p) => p.distinct), jaccardMinShared(CONFLICT_OVERLAP_THRESHOLD, CONFLICT_MIN_RARE_SHARED));
|
|
45
|
+
for (let i = 0; i < survivors.length; i++) {
|
|
46
|
+
for (const j of partnersOf(i)) {
|
|
47
|
+
// Traces are variants of each other, not contradictions. Two
|
|
48
|
+
// strategies for the same task can both be valid; conflict detection
|
|
49
|
+
// exists for stated-rule disagreement, not strategy diversity.
|
|
50
|
+
if (survivors[i].layer === Layer.Trace && survivors[j].layer === Layer.Trace)
|
|
51
|
+
continue;
|
|
52
|
+
if (survivors[i].superseded_by || survivors[j].superseded_by)
|
|
53
|
+
continue;
|
|
54
|
+
if (!recalledTogether(survivors[i], survivors[j]))
|
|
55
|
+
continue;
|
|
56
|
+
if ([survivors[i], survivors[j]].some((e) => e.tags.includes('extracted') || e.tags.includes('session-digest')))
|
|
57
|
+
continue;
|
|
58
|
+
const reasonAndScore = describeConflict(profiles[i], profiles[j]);
|
|
59
|
+
if (!reasonAndScore)
|
|
60
|
+
continue;
|
|
61
|
+
detected.push({
|
|
62
|
+
memory_a_id: survivors[i].id,
|
|
63
|
+
memory_b_id: survivors[j].id,
|
|
64
|
+
reason: reasonAndScore.reason,
|
|
65
|
+
score: reasonAndScore.score,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return detected;
|
|
70
|
+
}
|
|
71
|
+
/** One project's ambient context can show both: same tenant, and the same project or a user-global row beside a project's. */
|
|
72
|
+
function recalledTogether(a, b) {
|
|
73
|
+
if (a.tenantId !== b.tenantId)
|
|
74
|
+
return false;
|
|
75
|
+
const [x, y] = [a.origin_project ?? null, b.origin_project ?? null];
|
|
76
|
+
return x === y || (x === '' && y !== null) || (y === '' && x !== null);
|
|
77
|
+
}
|
|
78
|
+
function conflictProfile(text) {
|
|
79
|
+
const opening = openingWindow(text);
|
|
80
|
+
// Polarity is measured only in the first POLARITY_WINDOW_WORDS, so a stray
|
|
81
|
+
// negation deep in a prose memory doesn't flip the intent.
|
|
82
|
+
// Pad with spaces so space-delimited patterns match words at the start/end.
|
|
83
|
+
return { distinct: distinctiveTokens(text), polarity: inferConflictPolarity(opening), window: ' ' + opening.toLowerCase() + ' ' };
|
|
84
|
+
}
|
|
85
|
+
function describeConflict(a, b) {
|
|
86
|
+
// Jaccard on stopword-stripped tokens. Defer the threshold check until we
|
|
87
|
+
// know whether an explicit polarity pair is present (lower bar for those).
|
|
88
|
+
const overlapScore = jaccardSets(a.distinct, b.distinct);
|
|
89
|
+
// Require at least N shared distinctive tokens so two short memories sharing
|
|
90
|
+
// only "the project name" don't register.
|
|
91
|
+
let shared = 0;
|
|
92
|
+
for (const t of a.distinct)
|
|
93
|
+
if (b.distinct.has(t))
|
|
94
|
+
shared++;
|
|
95
|
+
if (shared < CONFLICT_MIN_RARE_SHARED)
|
|
96
|
+
return null;
|
|
97
|
+
const conflictType = classifyConflictType(a.window, b.window, a.polarity, b.polarity);
|
|
98
|
+
if (!conflictType)
|
|
99
|
+
return null;
|
|
100
|
+
if (overlapScore < CONFLICT_OVERLAP_THRESHOLD)
|
|
101
|
+
return null;
|
|
102
|
+
return {
|
|
103
|
+
reason: conflictType,
|
|
104
|
+
score: overlapScore,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function distinctiveTokens(text) {
|
|
108
|
+
return new Set(text
|
|
109
|
+
.toLowerCase()
|
|
110
|
+
.replace(/[^\w\s]/g, ' ')
|
|
111
|
+
.split(/\s+/)
|
|
112
|
+
.filter((t) => t.length > 2 && !CONFLICT_STOPWORDS.has(t)));
|
|
113
|
+
}
|
|
114
|
+
export function jaccardSets(a, b) {
|
|
115
|
+
if (a.size === 0 && b.size === 0)
|
|
116
|
+
return 1;
|
|
117
|
+
if (a.size === 0 || b.size === 0)
|
|
118
|
+
return 0;
|
|
119
|
+
let inter = 0;
|
|
120
|
+
for (const t of a)
|
|
121
|
+
if (b.has(t))
|
|
122
|
+
inter++;
|
|
123
|
+
const union = a.size + b.size - inter;
|
|
124
|
+
return union === 0 ? 0 : inter / union;
|
|
125
|
+
}
|
|
126
|
+
function openingWindow(text) {
|
|
127
|
+
return text.split(/\s+/).slice(0, POLARITY_WINDOW_WORDS).join(' ');
|
|
128
|
+
}
|
|
129
|
+
// Takes opening windows only, so " on " and " off " as prepositions deep in long prose don't read as enabled/disabled.
|
|
130
|
+
function classifyConflictType(a, b, aPolarity, bPolarity) {
|
|
131
|
+
// Tightened tokens: require whole-word boundaries so " on " alone doesn't
|
|
132
|
+
// match "on/off". Pair only `enabled` ↔ `disabled` and explicit on/off in
|
|
133
|
+
// imperative context.
|
|
134
|
+
const enabledDisabled = (containsAny(a, [' enabled ', ' enable ']) && containsAny(b, [' disabled ', ' disable ']))
|
|
135
|
+
|| (containsAny(b, [' enabled ', ' enable ']) && containsAny(a, [' disabled ', ' disable ']));
|
|
136
|
+
if (enabledDisabled)
|
|
137
|
+
return 'enabled/disabled mismatch on overlapping statement';
|
|
138
|
+
const trueFalse = (containsAny(a, [' true ', ' true.', ' true,', ' yes ']) && containsAny(b, [' false ', ' false.', ' false,', ' no ']))
|
|
139
|
+
|| (containsAny(b, [' true ', ' true.', ' true,', ' yes ']) && containsAny(a, [' false ', ' false.', ' false,', ' no ']));
|
|
140
|
+
if (trueFalse)
|
|
141
|
+
return 'true/false mismatch on overlapping statement';
|
|
142
|
+
const alwaysNever = (containsAny(a, [' always ', ' must ']) && containsAny(b, [' never ', ' must not ']))
|
|
143
|
+
|| (containsAny(b, [' always ', ' must ']) && containsAny(a, [' never ', ' must not ']));
|
|
144
|
+
if (alwaysNever)
|
|
145
|
+
return 'always/never mismatch on overlapping statement';
|
|
146
|
+
if ((aPolarity === 'positive' && bPolarity === 'negative') || (aPolarity === 'negative' && bPolarity === 'positive')) {
|
|
147
|
+
return 'negation polarity mismatch on overlapping statement';
|
|
148
|
+
}
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
function inferConflictPolarity(text) {
|
|
152
|
+
const lowered = ` ${text.toLowerCase()} `;
|
|
153
|
+
const negativePatterns = [
|
|
154
|
+
' not ', ' never ', ' no ', " don't ", ' do not ', " doesn't ", ' does not ',
|
|
155
|
+
" can't ", ' cannot ', " shouldn't ", ' should not ', ' disabled ', ' disable ', ' off ',
|
|
156
|
+
' false ', ' missing ', ' broken ', ' failed ',
|
|
157
|
+
];
|
|
158
|
+
const positivePatterns = [
|
|
159
|
+
' enabled ', ' enable ', ' works ', ' working ', ' true ', ' available ', ' present ', ' on ',
|
|
160
|
+
' always ', ' must ',
|
|
161
|
+
];
|
|
162
|
+
if (containsAny(lowered, negativePatterns))
|
|
163
|
+
return 'negative';
|
|
164
|
+
if (containsAny(lowered, positivePatterns))
|
|
165
|
+
return 'positive';
|
|
166
|
+
return 'neutral';
|
|
167
|
+
}
|
|
168
|
+
function stripConflictPolarity(text) {
|
|
169
|
+
return text
|
|
170
|
+
.toLowerCase()
|
|
171
|
+
.replace(/\b(?:not|never|no|don['’]?t|do\s+not|doesn['’]?t|does\s+not|can['’]?t|cannot|shouldn['’]?t|should\s+not|enabled|enable|disabled|disable|on|off|true|false|always|must|must\s+not|works?|working|missing|broken|failed|available|present)\b/g, ' ')
|
|
172
|
+
.replace(/\s+/g, ' ')
|
|
173
|
+
.trim();
|
|
174
|
+
}
|
|
175
|
+
function containsAny(text, needles) {
|
|
176
|
+
return needles.some((needle) => text.includes(needle));
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=conflicts.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { MemoryEntry } from '../memory.js';
|
|
2
|
+
import { type MvRankInfo } from '../memory-value.js';
|
|
3
|
+
import type { SleepRun } from './run.js';
|
|
4
|
+
export declare const DECAY_THRESHOLD = 0.05;
|
|
5
|
+
/** What the decay pass hands to the conflict check and the rescue audit at the end of the run. */
|
|
6
|
+
export interface DecayOutcome {
|
|
7
|
+
rescuedIds: Set<string>;
|
|
8
|
+
rescuedEntries: MemoryEntry[];
|
|
9
|
+
rankById: Map<string, MvRankInfo>;
|
|
10
|
+
}
|
|
11
|
+
export declare function decayPass(run: SleepRun): DecayOutcome;
|
|
12
|
+
//# sourceMappingURL=decay.d.ts.map
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { calculateStrength } from '../memory.js';
|
|
2
|
+
import { detectSecret } from '../secret-detect.js';
|
|
3
|
+
import { rescueSet, rankNonPinnedByTenant, validateWeights } from '../memory-value.js';
|
|
4
|
+
import { MEMORY_VALUE_WEIGHTS, SOURCE_ARTIFACT_SHA256 } from '../memory-value-weights.js';
|
|
5
|
+
export const DECAY_THRESHOLD = 0.05;
|
|
6
|
+
// A faded, unpinned, unrescued memory leaves active memory one of three
|
|
7
|
+
// ways. A raw receipt is append-only: trg_memories_raw_append_only aborts
|
|
8
|
+
// a DELETE, and with it this whole cycle's batch and every later sleep,
|
|
9
|
+
// so it stays where it is (stored strength refreshed) but sits out the
|
|
10
|
+
// rest of this cycle the way a deleted row would. Anything else goes
|
|
11
|
+
// dormant when config.dormant is on, and is deleted otherwise.
|
|
12
|
+
// Only called for rows `retirable` allows (never pinned, raw, kept for good or backing a first-class object).
|
|
13
|
+
function retireFaded(run, entry, strength) {
|
|
14
|
+
const { result } = run;
|
|
15
|
+
const why = `(strength ${strength.toFixed(4)} < ${DECAY_THRESHOLD})`;
|
|
16
|
+
// A faded secret is deleted, never kept dormant: keeping it would hold a
|
|
17
|
+
// credential on disk that the user reasonably expects forgetting removed.
|
|
18
|
+
if (run.config.dormant.enabled && !detectSecret(entry).flagged) {
|
|
19
|
+
result.dormant++;
|
|
20
|
+
result.details.push(` 💤 dormant ${entry.id} ${why}`);
|
|
21
|
+
run.pendingDormant.push({ entry: { ...entry, strength }, strength, reason: 'decay', dormantAt: run.now.toISOString() });
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
result.removed++;
|
|
25
|
+
result.details.push(` 🗑 removed ${entry.id} ${why}`);
|
|
26
|
+
run.pendingDeletes.push(entry.id);
|
|
27
|
+
}
|
|
28
|
+
/** Keeps an entry with its live strength cached; only strength is a cached computation, confidence stays as stored. */
|
|
29
|
+
function keepSurvivor(run, entry, strength) {
|
|
30
|
+
const updated = { ...entry, strength };
|
|
31
|
+
run.survivors.push(updated);
|
|
32
|
+
if (!run.dryRun && strength !== entry.strength) {
|
|
33
|
+
run.pendingWrites.push(updated);
|
|
34
|
+
}
|
|
35
|
+
run.result.decayed++;
|
|
36
|
+
return updated;
|
|
37
|
+
}
|
|
38
|
+
// -------------------------------------------------------------------------
|
|
39
|
+
// 1. Decay pass
|
|
40
|
+
// -------------------------------------------------------------------------
|
|
41
|
+
// LC2-E3 (opt-in, default off; docs/plans/2026-08-10-lc2-e3-mv-wiring.md):
|
|
42
|
+
// flag OFF keeps the single-phase loop below byte-identical to pre-E3
|
|
43
|
+
// behavior (pre-registered gate G2). Flag ON restructures into two phases:
|
|
44
|
+
// phase 1 classifies every entry (condemned vs survivor) with ZERO
|
|
45
|
+
// commits; phase 2 runs rescueSet over the per-tenant candidate groups,
|
|
46
|
+
// then commits — rescued entries get the standard survivor bookkeeping
|
|
47
|
+
// refresh (stored strength + effective confidence; no half-life edits, no
|
|
48
|
+
// rank-derived writes) and are pushed to survivors so they fully
|
|
49
|
+
// participate in this cycle's merge/physics/conflict passes; non-rescued
|
|
50
|
+
// condemned entries follow the existing pendingDeletes/result.removed/
|
|
51
|
+
// details path.
|
|
52
|
+
export function decayPass(run) {
|
|
53
|
+
if (run.config.memoryValue.enabled)
|
|
54
|
+
return decayWithMemoryValue(run);
|
|
55
|
+
for (const entry of run.all) {
|
|
56
|
+
const strength = calculateStrength(entry, run.now, run.decayOpts);
|
|
57
|
+
if (run.retirable(entry) && strength < DECAY_THRESHOLD) {
|
|
58
|
+
retireFaded(run, entry, strength);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
keepSurvivor(run, entry, strength);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return { rescuedIds: new Set(), rescuedEntries: [], rankById: new Map() };
|
|
65
|
+
}
|
|
66
|
+
// A non-finite feature (e.g. a malformed `created`) scores -Infinity and can never be
|
|
67
|
+
// rescued, so name those entries in one warning rather than leave it a silent NaN detail.
|
|
68
|
+
function reportNonFiniteScores(result, rankById) {
|
|
69
|
+
const nonFiniteIds = [...rankById.entries()]
|
|
70
|
+
.filter(([, info]) => !Number.isFinite(info.score))
|
|
71
|
+
.map(([id]) => id);
|
|
72
|
+
if (nonFiniteIds.length > 0) {
|
|
73
|
+
result.details.push(` ⚠️ memory-value: skipped ${nonFiniteIds.length} entr${nonFiniteIds.length === 1 ? 'y' : 'ies'} ` +
|
|
74
|
+
`with non-finite computed features (never rescued): ${nonFiniteIds.join(', ')}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function decayWithMemoryValue(run) {
|
|
78
|
+
const { all, now, result } = run;
|
|
79
|
+
// Carried forward to logRun, where the mv_rescue audit rows are actually
|
|
80
|
+
// written (code-review fix: writing them here, before batchWriteAndDelete,
|
|
81
|
+
// would assert rescues for a cycle whose effects might never land if a
|
|
82
|
+
// later phase throws).
|
|
83
|
+
const rescuedEntries = [];
|
|
84
|
+
let rescuedIds = new Set();
|
|
85
|
+
let rankById = new Map();
|
|
86
|
+
// --- Phase 1: classify (zero commits) ---
|
|
87
|
+
const condemned = [];
|
|
88
|
+
const strengthById = new Map();
|
|
89
|
+
for (const entry of all) {
|
|
90
|
+
const strength = calculateStrength(entry, now, run.decayOpts);
|
|
91
|
+
strengthById.set(entry.id, strength);
|
|
92
|
+
if (run.retirable(entry) && strength < DECAY_THRESHOLD) {
|
|
93
|
+
condemned.push(entry);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// --- Phase 2a: rescue decision (pure compute) ---
|
|
97
|
+
// Runs under --dry-run too (only the pendingDeletes flush and the audit write in
|
|
98
|
+
// logRun stay !dryRun-gated), so the preview matches what a
|
|
99
|
+
// real run would decide.
|
|
100
|
+
const condemnedIds = new Set(condemned.map((e) => e.id));
|
|
101
|
+
// Fail-loud must not depend on condemnation traffic (round-2 code-review
|
|
102
|
+
// P2-2): validate the frozen weights constant unconditionally, even on a
|
|
103
|
+
// sleep with nothing condemned.
|
|
104
|
+
validateWeights();
|
|
105
|
+
if (condemnedIds.size > 0) {
|
|
106
|
+
// Compute the per-tenant ranking ONCE (round-2 code-review P2-2):
|
|
107
|
+
// rankById feeds both rescueSet's decision (via precomputedRanks,
|
|
108
|
+
// skipping its own internal rankNonPinnedByTenant call) and the
|
|
109
|
+
// detail/audit rank context below, so the whole-store ranking pass
|
|
110
|
+
// runs a single time per sleep instead of twice, and only when there
|
|
111
|
+
// is actually something condemned to rank against.
|
|
112
|
+
rankById = rankNonPinnedByTenant(all, now);
|
|
113
|
+
rescuedIds = rescueSet(all, condemnedIds, now, MEMORY_VALUE_WEIGHTS, SOURCE_ARTIFACT_SHA256, rankById);
|
|
114
|
+
reportNonFiniteScores(result, rankById);
|
|
115
|
+
}
|
|
116
|
+
// --- Phase 2b: commit, one pass over `all` in ITS ORIGINAL ORDER ---
|
|
117
|
+
// (review-round F4: rescued entries used to be appended at the tail of
|
|
118
|
+
// survivors, systematically starving them in downstream order-sensitive
|
|
119
|
+
// passes like extraction's slice(0,20) — a single pass over `all`
|
|
120
|
+
// preserves flag-off's ordering semantics exactly.)
|
|
121
|
+
for (const entry of all) {
|
|
122
|
+
const strength = strengthById.get(entry.id);
|
|
123
|
+
if (run.retirable(entry) && strength < DECAY_THRESHOLD) {
|
|
124
|
+
if (rescuedIds.has(entry.id)) {
|
|
125
|
+
// Rescued (D1): standard survivor stored-strength refresh (P2-1).
|
|
126
|
+
// Confidence is left alone here: it is an epistemic tier, not a
|
|
127
|
+
// cached computation, so resolveConfidence derives it on read.
|
|
128
|
+
rescuedEntries.push(keepSurvivor(run, entry, strength));
|
|
129
|
+
const rank = rankById.get(entry.id);
|
|
130
|
+
const rankNote = rank
|
|
131
|
+
? ` - rescued (rank ${rank.rank}/${rank.totalNonPinned} in tenant ${rank.tenantId}, top ${rank.keepN})`
|
|
132
|
+
: ' - rescued';
|
|
133
|
+
result.details.push(` 🛟 ${entry.id} (strength ${strength.toFixed(4)} < ${DECAY_THRESHOLD})${rankNote}`);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
retireFaded(run, entry, strength);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
keepSurvivor(run, entry, strength);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return { rescuedIds, rescuedEntries, rankById };
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=decay.js.map
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { envAnthropicApiKey, envDagRebuildCap } from '../env.js';
|
|
2
|
+
import { Layer } from '../memory.js';
|
|
3
|
+
import { log } from '../log.js';
|
|
4
|
+
import { keptAsWritten } from './run.js';
|
|
5
|
+
/** The key, model options and once-per-line error reporter every LLM phase shares. */
|
|
6
|
+
function sleepLlm(run, fetcher) {
|
|
7
|
+
const { config, result } = run;
|
|
8
|
+
// extraction.enabled=false is the opt-out for every LLM phase below, key or no key.
|
|
9
|
+
const apiKey = config.extraction.enabled !== false ? (envAnthropicApiKey() ?? '') : '';
|
|
10
|
+
const llmErrorsSeen = new Set();
|
|
11
|
+
const llmError = (phase) => (msg) => {
|
|
12
|
+
const line = ` ⚠️ ${phase}: ${msg}`;
|
|
13
|
+
if (llmErrorsSeen.has(line))
|
|
14
|
+
return;
|
|
15
|
+
llmErrorsSeen.add(line);
|
|
16
|
+
result.details.push(line);
|
|
17
|
+
log.warn(`consolidate ${phase}: ${msg}`);
|
|
18
|
+
};
|
|
19
|
+
const llmOpts = { apiKey, model: config.extraction.model, fetcher };
|
|
20
|
+
return { apiKey, llmError, llmOpts };
|
|
21
|
+
}
|
|
22
|
+
export async function llmPasses(run, fetcher) {
|
|
23
|
+
// -------------------------------------------------------------------------
|
|
24
|
+
// 1.6. Batch extraction — extract facts from episodic memories missing them
|
|
25
|
+
// -------------------------------------------------------------------------
|
|
26
|
+
const extractedFromIds = new Set(run.survivors.filter((e) => e.extracted_from).map((e) => e.extracted_from));
|
|
27
|
+
const extractionCandidates = run.survivors.filter((e) => e.layer === Layer.Episodic && !e.superseded_by && !extractedFromIds.has(e.id) && !keptAsWritten(e));
|
|
28
|
+
run.result.extractionCandidates = extractionCandidates.length;
|
|
29
|
+
const llm = sleepLlm(run, fetcher);
|
|
30
|
+
if (llm.apiKey && extractionCandidates.length > 0 && !run.dryRun) {
|
|
31
|
+
const { extractFacts, storeExtractedFacts } = await import('../extract.js');
|
|
32
|
+
const batchLimit = 20;
|
|
33
|
+
let extractedCount = 0;
|
|
34
|
+
for (const candidate of extractionCandidates.slice(0, batchLimit)) {
|
|
35
|
+
try {
|
|
36
|
+
const facts = await extractFacts(candidate.content, { ...llm.llmOpts, onError: llm.llmError('extraction') });
|
|
37
|
+
if (facts.length > 0) {
|
|
38
|
+
storeExtractedFacts(run.hippoRoot, candidate, facts);
|
|
39
|
+
extractedCount += facts.length;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
llm.llmError('extraction')(String(err));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
run.result.extracted = extractedCount;
|
|
47
|
+
}
|
|
48
|
+
await dagBuildPass(run, llm);
|
|
49
|
+
if (llm.apiKey && !run.dryRun) {
|
|
50
|
+
await dagRebuildPass(run, llm);
|
|
51
|
+
await entityProfilePass(run, llm);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// -------------------------------------------------------------------------
|
|
55
|
+
// 1.7. DAG summarization — cluster extracted facts and generate summaries
|
|
56
|
+
// -------------------------------------------------------------------------
|
|
57
|
+
async function dagBuildPass(run, { apiKey, llmError, llmOpts }) {
|
|
58
|
+
const extractedFacts = run.survivors.filter((e) => e.tags.includes('extracted') && e.dag_level === 1 && !e.superseded_by);
|
|
59
|
+
if (!(apiKey && extractedFacts.length >= 3 && !run.dryRun))
|
|
60
|
+
return;
|
|
61
|
+
try {
|
|
62
|
+
const { buildDag } = await import('../dag.js');
|
|
63
|
+
const dagResult = await buildDag(run.hippoRoot, extractedFacts, { ...llmOpts, onError: llmError('dag') });
|
|
64
|
+
run.result.dagCandidateClusters = dagResult.candidateClusters;
|
|
65
|
+
run.result.dagSummariesCreated = dagResult.summariesCreated;
|
|
66
|
+
if (dagResult.summariesCreated > 0) {
|
|
67
|
+
run.result.details.push(` 🌳 DAG: ${dagResult.summariesCreated} summaries created, ${dagResult.factsLinked} facts linked`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
llmError('dag')(String(err));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// -------------------------------------------------------------------------
|
|
75
|
+
// 1.8. DAG summary rebuild — drain dirty queue from E2's child-write hooks
|
|
76
|
+
// -------------------------------------------------------------------------
|
|
77
|
+
// Consumer of E2's summary_dirty flag. Walks dirty L2 summaries, regenerates
|
|
78
|
+
// each via generateDagSummary, atomically refreshes content + 6 metadata
|
|
79
|
+
// columns + clears summary_dirty (with FTS sync). Same apiKey/dryRun gate
|
|
80
|
+
// as buildDag above. Cap HIPPO_DAG_REBUILD_CAP (default 20, hard ceiling
|
|
81
|
+
// 1000) prevents runaway LLM cost.
|
|
82
|
+
async function dagRebuildPass(run, { llmError, llmOpts }) {
|
|
83
|
+
const { result } = run;
|
|
84
|
+
try {
|
|
85
|
+
const { rebuildDirtySummaries } = await import('../dag.js');
|
|
86
|
+
const rawCap = envDagRebuildCap();
|
|
87
|
+
// R1 MED must-fix: hard ceiling so misconfigured env can't burn
|
|
88
|
+
// unbounded LLM cost.
|
|
89
|
+
const cap = rawCap !== undefined ? Math.min(rawCap, 1000) : 20;
|
|
90
|
+
const rebuildResult = await rebuildDirtySummaries(run.hippoRoot, { ...llmOpts, onError: llmError('dag rebuild'), cap });
|
|
91
|
+
result.summariesRebuilt = rebuildResult.rebuilt;
|
|
92
|
+
result.summariesRebuildFailed = rebuildResult.failed;
|
|
93
|
+
result.summariesZeroChildSkipped = rebuildResult.zeroChildSkipped;
|
|
94
|
+
result.summariesRebuildRefused = rebuildResult.refused;
|
|
95
|
+
result.summariesRebuildCapped = rebuildResult.capped;
|
|
96
|
+
if (rebuildResult.rebuilt > 0 || rebuildResult.zeroChildSkipped > 0 || rebuildResult.failed > 0 || rebuildResult.refused > 0) {
|
|
97
|
+
const parts = [];
|
|
98
|
+
if (rebuildResult.rebuilt > 0)
|
|
99
|
+
parts.push(`${rebuildResult.rebuilt} rebuilt`);
|
|
100
|
+
if (rebuildResult.refused > 0)
|
|
101
|
+
parts.push(`${rebuildResult.refused} refused`);
|
|
102
|
+
if (rebuildResult.zeroChildSkipped > 0)
|
|
103
|
+
parts.push(`${rebuildResult.zeroChildSkipped} zero-child-skipped`);
|
|
104
|
+
if (rebuildResult.failed > 0)
|
|
105
|
+
parts.push(`${rebuildResult.failed} failed`);
|
|
106
|
+
if (rebuildResult.capped)
|
|
107
|
+
parts.push(`CAPPED@${cap}`);
|
|
108
|
+
result.details.push(` 🌳 DAG rebuild: ${parts.join(', ')}`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
llmError('dag rebuild')(String(err));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// -------------------------------------------------------------------------
|
|
116
|
+
// 1.9. DAG entity profiles — cluster L2 topic summaries into L3 profiles
|
|
117
|
+
// -------------------------------------------------------------------------
|
|
118
|
+
// E5 phase: aggregate per-entity L2 summaries (e.g. all the speaker:Alice
|
|
119
|
+
// topic summaries) into a single L3 entity profile. Runs even when phase
|
|
120
|
+
// 1.7 buildDag was skipped (re-clusters existing L2s every sleep).
|
|
121
|
+
//
|
|
122
|
+
// Uses loadAllL2Summaries (not `survivors`) because phase 1.7 wrote new
|
|
123
|
+
// L2s directly via writeEntry without pushing back into survivors.
|
|
124
|
+
async function entityProfilePass(run, { llmError, llmOpts }) {
|
|
125
|
+
try {
|
|
126
|
+
const { buildEntityProfiles } = await import('../dag.js');
|
|
127
|
+
const { loadAllL2Summaries } = await import('../store/summaries.js');
|
|
128
|
+
const l2Summaries = loadAllL2Summaries(run.hippoRoot);
|
|
129
|
+
if (l2Summaries.length >= 2) {
|
|
130
|
+
const profileResult = await buildEntityProfiles(run.hippoRoot, l2Summaries, { ...llmOpts, onError: llmError('dag profiles') });
|
|
131
|
+
run.result.entityProfilesCreated = profileResult.profilesCreated;
|
|
132
|
+
if (profileResult.profilesCreated > 0) {
|
|
133
|
+
run.result.details.push(` 🌲 DAG L3: ${profileResult.profilesCreated} entity profiles, ${profileResult.l2sLinked} L2s linked`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
catch (err) {
|
|
138
|
+
llmError('dag profiles')(String(err));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=llm-passes.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type SleepRun } from './run.js';
|
|
2
|
+
export declare function retireHeldTexts(run: SleepRun): void;
|
|
3
|
+
/** Returns how many clusters were skipped because their merged text matches a rejected value. */
|
|
4
|
+
export declare function mergePass(run: SleepRun): number;
|
|
5
|
+
/** Maps i to each j > i, ascending, whose text overlap with i reaches the merge threshold; every text needs at least one token. */
|
|
6
|
+
export declare function mergePartners(contents: readonly string[]): (i: number) => number[];
|
|
7
|
+
//# sourceMappingURL=merge.d.ts.map
|