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,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Consolidation engine ("Sleep") for Hippo.
|
|
3
|
+
*
|
|
4
|
+
* Steps:
|
|
5
|
+
* 1. Decay pass - remove entries below strength threshold
|
|
6
|
+
* 2. Merge pass - find episodic entries with high text overlap, create semantic summaries
|
|
7
|
+
* 3. Stats tracking
|
|
8
|
+
*/
|
|
9
|
+
import { evalNow } from '../ablation.js';
|
|
10
|
+
import { canAutoDelete } from '../memory.js';
|
|
11
|
+
import { loadAllEntries } from '../store/entry-reads.js';
|
|
12
|
+
import { batchWriteAndDelete, memoriesBackingObjects } from '../store/delete-and-batch.js';
|
|
13
|
+
import { appendConsolidationRun, loadSessionDecayContext, incrementSleepCount } from '../store/index-and-stats.js';
|
|
14
|
+
import { replaceDetectedConflicts } from '../store/conflicts.js';
|
|
15
|
+
import { openHippoDb, closeHippoDb } from '../db.js';
|
|
16
|
+
import { countExpiredDormant, purgeExpiredDormant } from '../dormant.js';
|
|
17
|
+
import { loadConfig } from '../config.js';
|
|
18
|
+
import { appendAuditEvent, reportAuditWriteFailure } from '../audit.js';
|
|
19
|
+
import { migrateDefaultHalfLife, LEGACY_TYPED_HALF_LIFE } from '../half-life-migration.js';
|
|
20
|
+
import { log } from '../log.js';
|
|
21
|
+
import { decayPass } from './decay.js';
|
|
22
|
+
import { retireHeldTexts, mergePass } from './merge.js';
|
|
23
|
+
import { detectConflicts } from './conflicts.js';
|
|
24
|
+
import { lazyConsolidateDb, newConsolidationResult } from './run.js';
|
|
25
|
+
import { promoteSessionTraces, replayPass } from './traces.js';
|
|
26
|
+
import { llmPasses } from './llm-passes.js';
|
|
27
|
+
import { physicsPass } from './physics-pass.js';
|
|
28
|
+
/**
|
|
29
|
+
* Run a full consolidation pass.
|
|
30
|
+
*/
|
|
31
|
+
export async function consolidate(hippoRoot, options = {}) {
|
|
32
|
+
const now = options.now ?? evalNow(); // honors HIPPO_FAKE_NOW (eval-only; see ablation.ts)
|
|
33
|
+
const dryRun = options.dryRun ?? false;
|
|
34
|
+
const result = newConsolidationResult(dryRun);
|
|
35
|
+
const halfLife = migrateHalfLives(hippoRoot, dryRun, result);
|
|
36
|
+
// L9: host-wide by design. Consolidation runs across all tenants in one
|
|
37
|
+
// pass — per-tenant filtering would create N consolidation runs per host
|
|
38
|
+
// with no cross-tenant dedup. The api.sleep audit row tags this with the
|
|
39
|
+
// admin synthetic actor; see api.ts:2050 for the rationale.
|
|
40
|
+
const all = loadAllEntries(hippoRoot);
|
|
41
|
+
if (dryRun)
|
|
42
|
+
for (const e of all)
|
|
43
|
+
e.half_life_days = halfLife.halfLives.get(e.id) ?? e.half_life_days;
|
|
44
|
+
const backingObjects = memoriesBackingObjects(hippoRoot);
|
|
45
|
+
// Retirable: auto-deletable (never pinned, raw or kept for good) and not backing a first-class object.
|
|
46
|
+
const retirable = (entry) => canAutoDelete(entry) && !backingObjects.has(entry.id);
|
|
47
|
+
const snapshot = new Map(structuredClone(all).map((e) => [e.id, e]));
|
|
48
|
+
// Load decay options from config + session context
|
|
49
|
+
const config = loadConfig(hippoRoot);
|
|
50
|
+
const sessionCtx = loadSessionDecayContext(hippoRoot);
|
|
51
|
+
const decayOpts = {
|
|
52
|
+
decayBasis: config.decayBasis,
|
|
53
|
+
avgSessionIntervalDays: sessionCtx.avgSessionIntervalDays,
|
|
54
|
+
sleepCount: sessionCtx.sleepCount,
|
|
55
|
+
};
|
|
56
|
+
const consolidateDb = lazyConsolidateDb(hippoRoot, dryRun);
|
|
57
|
+
const run = {
|
|
58
|
+
hippoRoot, now, dryRun, config, decayOpts, result, all, retirable,
|
|
59
|
+
getConsolidateDb: consolidateDb.get,
|
|
60
|
+
survivors: [],
|
|
61
|
+
// Collect all writes/deletes and batch them at the end
|
|
62
|
+
pendingWrites: [],
|
|
63
|
+
pendingDeletes: [],
|
|
64
|
+
pendingDormant: [],
|
|
65
|
+
};
|
|
66
|
+
const decay = decayPass(run);
|
|
67
|
+
let mergesSkippedRejected = 0;
|
|
68
|
+
try {
|
|
69
|
+
promoteSessionTraces(run);
|
|
70
|
+
replayPass(run);
|
|
71
|
+
await llmPasses(run, options.fetcher);
|
|
72
|
+
physicsPass(run);
|
|
73
|
+
retireHeldTexts(run);
|
|
74
|
+
mergesSkippedRejected = mergePass(run);
|
|
75
|
+
}
|
|
76
|
+
finally {
|
|
77
|
+
consolidateDb.close();
|
|
78
|
+
}
|
|
79
|
+
if (mergesSkippedRejected > 0) {
|
|
80
|
+
log.warn(`consolidate: skipped ${mergesSkippedRejected} merge(s) whose content matches a rejected value`);
|
|
81
|
+
}
|
|
82
|
+
flushPending(run, snapshot);
|
|
83
|
+
expireDormant(run);
|
|
84
|
+
if (!dryRun)
|
|
85
|
+
logRun(run, decay);
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
88
|
+
// A changed default half-life moves memories still on the old base first,
|
|
89
|
+
// so this pass decays them at the new one (src/half-life-migration.ts).
|
|
90
|
+
function migrateHalfLives(hippoRoot, dryRun, result) {
|
|
91
|
+
const halfLife = migrateDefaultHalfLife(hippoRoot, loadConfig(hippoRoot).defaultHalfLifeDays, { dryRun });
|
|
92
|
+
if (halfLife.rescaled > 0) {
|
|
93
|
+
result.details.push(` ⏳ ${dryRun ? 'would move' : 'moved'} ${halfLife.rescaled} memories from the ${halfLife.from}-day to the ${halfLife.to}-day half-life`);
|
|
94
|
+
}
|
|
95
|
+
if (halfLife.typed > 0) {
|
|
96
|
+
result.details.push(` ⏳ ${dryRun ? 'would move' : 'moved'} ${halfLife.typed} memories of decisions, incidents and other objects from the ${LEGACY_TYPED_HALF_LIFE}-day to the ${halfLife.to}-day half-life`);
|
|
97
|
+
}
|
|
98
|
+
return halfLife;
|
|
99
|
+
}
|
|
100
|
+
function flushPending(run, snapshot) {
|
|
101
|
+
const { result, pendingDeletes, pendingDormant } = run;
|
|
102
|
+
result.removedIds = pendingDeletes;
|
|
103
|
+
// One transaction; the snapshot keeps what the DAG passes and other writers changed while sleep ran.
|
|
104
|
+
// Dormant moves ride in the same transaction (src/dormant.ts).
|
|
105
|
+
if (run.dryRun)
|
|
106
|
+
return;
|
|
107
|
+
const left = new Set(batchWriteAndDelete(run.hippoRoot, run.pendingWrites, pendingDeletes, { snapshot, dormant: pendingDormant }));
|
|
108
|
+
for (const id of [...pendingDeletes, ...pendingDormant.map((m) => m.entry.id)]) {
|
|
109
|
+
if (!left.has(id))
|
|
110
|
+
result.details.push(` ↩ ${id} not removed: pinned or already gone before sleep saved`);
|
|
111
|
+
}
|
|
112
|
+
result.removedIds = pendingDeletes.filter((id) => left.has(id));
|
|
113
|
+
result.removed = result.removedIds.length;
|
|
114
|
+
result.dormant = pendingDormant.filter((m) => left.has(m.entry.id)).length;
|
|
115
|
+
}
|
|
116
|
+
// Dormant retention: a dormant memory nobody restored within
|
|
117
|
+
// dormant.retentionDays is deleted for good (0 keeps them forever). Runs
|
|
118
|
+
// even when dormant.enabled is off, so turning it off still ages out what
|
|
119
|
+
// earlier sleeps kept.
|
|
120
|
+
function expireDormant(run) {
|
|
121
|
+
const { config, result, dryRun } = run;
|
|
122
|
+
if (!(config.dormant.retentionDays > 0))
|
|
123
|
+
return;
|
|
124
|
+
const cutoff = new Date(run.now.getTime() - config.dormant.retentionDays * 24 * 60 * 60 * 1000).toISOString();
|
|
125
|
+
const db = openHippoDb(run.hippoRoot);
|
|
126
|
+
try {
|
|
127
|
+
result.dormantExpired = dryRun ? countExpiredDormant(db, cutoff) : purgeExpiredDormant(db, cutoff);
|
|
128
|
+
}
|
|
129
|
+
finally {
|
|
130
|
+
closeHippoDb(db);
|
|
131
|
+
}
|
|
132
|
+
if (result.dormantExpired > 0) {
|
|
133
|
+
result.details.push(` ⌛ ${dryRun ? 'would expire' : 'expired'} ${result.dormantExpired} dormant memor${result.dormantExpired === 1 ? 'y' : 'ies'} older than ${config.dormant.retentionDays} days`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// -------------------------------------------------------------------------
|
|
137
|
+
// 4. Log run
|
|
138
|
+
// -------------------------------------------------------------------------
|
|
139
|
+
function logRun(run, decay) {
|
|
140
|
+
const { hippoRoot, now, result } = run;
|
|
141
|
+
const detectedConflicts = detectConflicts(run.survivors, now, run.decayOpts, decay.rescuedIds);
|
|
142
|
+
replaceDetectedConflicts(hippoRoot, detectedConflicts, now.toISOString());
|
|
143
|
+
if (detectedConflicts.length > 0) {
|
|
144
|
+
result.details.push(` ⚠️ detected ${detectedConflicts.length} memory conflict${detectedConflicts.length === 1 ? '' : 's'}`);
|
|
145
|
+
}
|
|
146
|
+
appendConsolidationRun(hippoRoot, {
|
|
147
|
+
timestamp: now.toISOString(),
|
|
148
|
+
decayed: result.decayed,
|
|
149
|
+
merged: result.merged,
|
|
150
|
+
removed: result.removed,
|
|
151
|
+
});
|
|
152
|
+
incrementSleepCount(hippoRoot);
|
|
153
|
+
if (decay.rescuedEntries.length > 0)
|
|
154
|
+
auditRescues(run, decay);
|
|
155
|
+
}
|
|
156
|
+
// One audit row per rescue (attributability, D1). Written here, AFTER
|
|
157
|
+
// batchWriteAndDelete has committed this cycle's writes/deletes
|
|
158
|
+
// (and after conflict detection + run logging), not inline in the decay
|
|
159
|
+
// pass — same durability posture as api.ts's top-level 'consolidate'
|
|
160
|
+
// summary audit row (written only once the whole sleep has completed).
|
|
161
|
+
// Writing it earlier would assert rescues for a cycle whose effects
|
|
162
|
+
// never landed if a later phase threw. Real writes only — dry-run
|
|
163
|
+
// previews the decision (details line above) but persists nothing.
|
|
164
|
+
function auditRescues(run, { rescuedEntries, rankById }) {
|
|
165
|
+
const { result } = run;
|
|
166
|
+
try {
|
|
167
|
+
const auditDb = openHippoDb(run.hippoRoot);
|
|
168
|
+
try {
|
|
169
|
+
// Review-round F5: per-row try/catch, not one try/catch around the
|
|
170
|
+
// whole loop — a single failed appendAuditEvent must not silently
|
|
171
|
+
// drop every remaining row. Mirrors the physics pass's
|
|
172
|
+
// skipped-warning precedent: count losses, keep
|
|
173
|
+
// the overall fail-soft posture, tell the operator via details.
|
|
174
|
+
let auditFailures = 0;
|
|
175
|
+
for (const entry of rescuedEntries) {
|
|
176
|
+
try {
|
|
177
|
+
const rank = rankById.get(entry.id);
|
|
178
|
+
appendAuditEvent(auditDb, {
|
|
179
|
+
tenantId: entry.tenantId,
|
|
180
|
+
actor: 'sleep',
|
|
181
|
+
op: 'mv_rescue',
|
|
182
|
+
targetId: entry.id,
|
|
183
|
+
metadata: rank
|
|
184
|
+
? { rank: rank.rank, totalNonPinned: rank.totalNonPinned, keepN: rank.keepN, score: rank.score }
|
|
185
|
+
: {},
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
auditFailures++;
|
|
190
|
+
reportAuditWriteFailure('mv_rescue', String(error), entry.id);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (auditFailures > 0) {
|
|
194
|
+
result.details.push(` ⚠️ memory-value: ${auditFailures} mv_rescue audit row${auditFailures === 1 ? '' : 's'} ` +
|
|
195
|
+
`failed to write (the rescue itself still landed)`);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
finally {
|
|
199
|
+
closeHippoDb(auditDb);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
// openHippoDb/closeHippoDb-level failure: audit must never crash a
|
|
204
|
+
// mutation (mirrors store.ts's audit() posture).
|
|
205
|
+
result.details.push(` ⚠️ memory-value: mv_rescue audit unavailable this cycle ` +
|
|
206
|
+
`(${rescuedEntries.length} rescue${rescuedEntries.length === 1 ? '' : 's'} not audited)`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
//# sourceMappingURL=sleep.js.map
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { isRecallBoostAblated } from '../ablation.js';
|
|
2
|
+
import { Layer, createMemory, markRetrieved } from '../memory.js';
|
|
3
|
+
import { findPromotableSessions, traceExistsForSession, listSessionEvents } from '../store/sessions.js';
|
|
4
|
+
import { rejectionDigest, findRejectedValue } from '../rejection.js';
|
|
5
|
+
import { sampleForReplay } from '../replay.js';
|
|
6
|
+
import { renderTraceContent } from '../trace.js';
|
|
7
|
+
import { resolveTenantId } from '../tenant.js';
|
|
8
|
+
import { appendAuditEvent, reportAuditWriteFailure } from '../audit.js';
|
|
9
|
+
import { commonDerivationScope } from '../recall-scope.js';
|
|
10
|
+
import { log } from '../log.js';
|
|
11
|
+
import { REPLAY_COUNT_DEFAULT, isJsonString } from './run.js';
|
|
12
|
+
// -------------------------------------------------------------------------
|
|
13
|
+
// 1.4. Auto-promote complete sessions to traces
|
|
14
|
+
// -------------------------------------------------------------------------
|
|
15
|
+
//
|
|
16
|
+
// For each session within the configured window that has a `session_complete`
|
|
17
|
+
// event and no existing trace (idempotency via the source_session_id column),
|
|
18
|
+
// render the action sequence as markdown and persist a Layer.Trace memory.
|
|
19
|
+
// Traces inherit decay, search, replay, and physics from the base MemoryEntry.
|
|
20
|
+
export function promoteSessionTraces(run) {
|
|
21
|
+
const { result } = run;
|
|
22
|
+
if (run.dryRun || run.config.autoTraceCapture === false)
|
|
23
|
+
return;
|
|
24
|
+
let tracesSkippedRejected = 0;
|
|
25
|
+
const windowDays = run.config.autoTraceWindowDays ?? 7;
|
|
26
|
+
const sinceMs = run.now.getTime() - windowDays * 24 * 60 * 60 * 1000;
|
|
27
|
+
// Auto-trace currently runs in a single-tenant context (the env-resolved
|
|
28
|
+
// tenant for this process). Multi-tenant deployments that want
|
|
29
|
+
// consolidation across all tenants need a per-tenant loop layered on top
|
|
30
|
+
// of this — tracked in docs/plans/2026-05-02-continuity-tables-tenant-scope.md.
|
|
31
|
+
const consolidationTenant = resolveTenantId({});
|
|
32
|
+
const promotable = findPromotableSessions(run.hippoRoot, consolidationTenant, sinceMs);
|
|
33
|
+
for (const session of promotable) {
|
|
34
|
+
const built = sessionTrace(run, consolidationTenant, session.session_id);
|
|
35
|
+
if (!built)
|
|
36
|
+
continue;
|
|
37
|
+
const { trace, outcome } = built;
|
|
38
|
+
if (traceRejected(run, trace, session.session_id)) {
|
|
39
|
+
tracesSkippedRejected++;
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
run.pendingWrites.push(trace);
|
|
43
|
+
run.survivors.push(trace);
|
|
44
|
+
result.promotedTraces++;
|
|
45
|
+
result.details.push(` 🧬 promoted trace ${trace.id} from session ${session.session_id} (${outcome})`);
|
|
46
|
+
}
|
|
47
|
+
if (result.promotedTraces > 0) {
|
|
48
|
+
result.details.push(` 🧬 promoted ${result.promotedTraces} trace${result.promotedTraces === 1 ? '' : 's'} from completed session${result.promotedTraces === 1 ? '' : 's'}`);
|
|
49
|
+
}
|
|
50
|
+
if (tracesSkippedRejected > 0) {
|
|
51
|
+
log.warn(`consolidate: skipped ${tracesSkippedRejected} auto-promoted trace(s) whose content matches a rejected value`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/** The trace a completed session renders to, or null when it already has one or cannot be promoted. */
|
|
55
|
+
function sessionTrace(run, consolidationTenant, sessionId) {
|
|
56
|
+
// Idempotency: skip if a trace for this session already exists.
|
|
57
|
+
if (traceExistsForSession(run.hippoRoot, consolidationTenant, sessionId))
|
|
58
|
+
return null;
|
|
59
|
+
const events = listSessionEvents(run.hippoRoot, consolidationTenant, {
|
|
60
|
+
session_id: sessionId,
|
|
61
|
+
limit: 1000,
|
|
62
|
+
});
|
|
63
|
+
// T7: a mixed-scope session would otherwise leak into one trace.
|
|
64
|
+
const sessionScope = commonDerivationScope(events.map((e) => e.scope));
|
|
65
|
+
if (!sessionScope.ok) {
|
|
66
|
+
run.result.tracesSkippedMixedScope++;
|
|
67
|
+
run.result.details.push(` ⏭ skipped session ${sessionId}: events span mixed scopes`);
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
const completeEvent = events.find((e) => e.event_type === 'session_complete');
|
|
71
|
+
if (!completeEvent)
|
|
72
|
+
return null; // defence-in-depth; findPromotableSessions filters already.
|
|
73
|
+
const outcomeRaw = completeEvent.content;
|
|
74
|
+
if (outcomeRaw !== 'success' && outcomeRaw !== 'failure' && outcomeRaw !== 'partial') {
|
|
75
|
+
// Malformed terminal event — skip rather than crash the whole sleep.
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
const outcome = outcomeRaw;
|
|
79
|
+
const steps = events
|
|
80
|
+
.filter((e) => e.event_type !== 'session_complete')
|
|
81
|
+
.map((e) => ({ action: e.content, observation: '' }));
|
|
82
|
+
// SAFETY: session event metadata is a free-form Record<string, unknown>
|
|
83
|
+
// bag; summary is optional and is only trusted once isJsonString below
|
|
84
|
+
// confirms it is actually a string.
|
|
85
|
+
const summaryValue = completeEvent.metadata.summary;
|
|
86
|
+
const summary = isJsonString(summaryValue) ? summaryValue : '(untitled)';
|
|
87
|
+
const trace = createMemory(renderTraceContent({ task: summary, steps, outcome }), {
|
|
88
|
+
layer: Layer.Trace,
|
|
89
|
+
trace_outcome: outcome,
|
|
90
|
+
source_session_id: sessionId,
|
|
91
|
+
tags: ['auto-promoted'],
|
|
92
|
+
source: 'auto-promote',
|
|
93
|
+
scope: sessionScope.scope,
|
|
94
|
+
// T1 fix (2026-08-15 hardening pass): stamp the trace into the SAME
|
|
95
|
+
// tenant the traceExistsForSession idempotency check (above) runs
|
|
96
|
+
// under. Before
|
|
97
|
+
// this, createMemory omitted tenantId and the trace always landed
|
|
98
|
+
// 'default' (memory.ts:535) while the idempotency check ran under
|
|
99
|
+
// consolidationTenant — for any non-default tenant that check never
|
|
100
|
+
// hit, and the trace regenerated every sleep.
|
|
101
|
+
tenantId: consolidationTenant,
|
|
102
|
+
baseHalfLifeDays: run.config.defaultHalfLifeDays,
|
|
103
|
+
});
|
|
104
|
+
return { trace, outcome };
|
|
105
|
+
}
|
|
106
|
+
// AT1 (same producer-side pattern as the merge pass below): traceExistsForSession
|
|
107
|
+
// only sees rows CURRENTLY in the store — once a rejected trace is
|
|
108
|
+
// removed, that idempotency check no longer blocks regeneration, and
|
|
109
|
+
// this write would otherwise reach batchWriteAndDelete's guard bypass
|
|
110
|
+
// unchecked, resurrecting it every sleep. Check under THE ENTRY'S OWN
|
|
111
|
+
// stamped tenantId (read off `trace` after createMemory — never guess
|
|
112
|
+
// the tenant) + the built content's digest. A hit skips the push
|
|
113
|
+
// entirely: not counted as promoted, not added to survivors.
|
|
114
|
+
function traceRejected(run, trace, sessionId) {
|
|
115
|
+
const consolidateDb = run.getConsolidateDb();
|
|
116
|
+
if (!consolidateDb)
|
|
117
|
+
return false;
|
|
118
|
+
const traceDigest = rejectionDigest(trace.content);
|
|
119
|
+
const tombstone = findRejectedValue(consolidateDb, trace.tenantId, traceDigest);
|
|
120
|
+
if (!tombstone)
|
|
121
|
+
return false;
|
|
122
|
+
try {
|
|
123
|
+
appendAuditEvent(consolidateDb, {
|
|
124
|
+
tenantId: trace.tenantId,
|
|
125
|
+
actor: 'sleep',
|
|
126
|
+
op: 'reject_refusal',
|
|
127
|
+
metadata: {
|
|
128
|
+
digest: traceDigest,
|
|
129
|
+
reason: tombstone.reason,
|
|
130
|
+
sourceSessionId: sessionId,
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
reportAuditWriteFailure('reject_refusal', String(error));
|
|
136
|
+
}
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
// -------------------------------------------------------------------------
|
|
140
|
+
// 1.5. Replay pass — rehearse high-value survivors
|
|
141
|
+
// -------------------------------------------------------------------------
|
|
142
|
+
//
|
|
143
|
+
// Biologically-inspired counterpart to hippocampal replay during slow-wave
|
|
144
|
+
// sleep: sample N memories weighted by outcome + valence + under-rehearsal
|
|
145
|
+
// + idle time, then apply the same retrieval-strengthening `markRetrieved`
|
|
146
|
+
// applies to real queries. Distinct from decay (removal), physics (motion),
|
|
147
|
+
// and merge (compression) — this is the "rehearse the important stuff so
|
|
148
|
+
// it doesn't fade" pass.
|
|
149
|
+
export function replayPass(run) {
|
|
150
|
+
const { survivors, now } = run;
|
|
151
|
+
const replayCount = run.config.replay?.count ?? REPLAY_COUNT_DEFAULT;
|
|
152
|
+
// EVAL-ONLY ablation (see ablation.ts): replay rehearsal IS recall
|
|
153
|
+
// strengthening (same markRetrieved dynamics), so the strengthen-off arm
|
|
154
|
+
// silences the whole pass - markRetrieved would return unmutated entries
|
|
155
|
+
// and persisting them anyway would still refresh updated_at / mirrors.
|
|
156
|
+
if (!(replayCount > 0 && survivors.length > 0 && !isRecallBoostAblated()))
|
|
157
|
+
return;
|
|
158
|
+
const seed = Math.floor(now.getTime() / 1000) & 0xffffffff;
|
|
159
|
+
const picked = sampleForReplay(survivors, replayCount, now, seed);
|
|
160
|
+
if (picked.length === 0)
|
|
161
|
+
return;
|
|
162
|
+
const rehearsed = markRetrieved(picked, now);
|
|
163
|
+
const rehearsedById = new Map(rehearsed.map((e) => [e.id, e]));
|
|
164
|
+
// Update survivors in place so downstream passes see rehearsed state.
|
|
165
|
+
for (let i = 0; i < survivors.length; i++) {
|
|
166
|
+
const replacement = rehearsedById.get(survivors[i].id);
|
|
167
|
+
if (replacement)
|
|
168
|
+
survivors[i] = replacement;
|
|
169
|
+
}
|
|
170
|
+
run.result.replayed = rehearsed.length;
|
|
171
|
+
run.result.details.push(` 💭 replayed ${rehearsed.length} memor${rehearsed.length === 1 ? 'y' : 'ies'}: ` +
|
|
172
|
+
rehearsed.map((e) => e.id).join(', '));
|
|
173
|
+
if (!run.dryRun) {
|
|
174
|
+
for (const r of rehearsed)
|
|
175
|
+
run.pendingWrites.push(r);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=traces.js.map
|
package/dist/context-auto.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { execFileSync } from 'child_process';
|
|
2
2
|
const SKIPPED_PATH_TERMS = ['src', 'dist', 'test', 'tests', 'node_modules', 'index'];
|
|
3
|
+
// stderr is dropped because git's warnings (line-ending notices, for one) would otherwise become query terms.
|
|
4
|
+
function readGit(args) {
|
|
5
|
+
return execFileSync('git', args, { encoding: 'utf8', timeout: 3000, stdio: ['ignore', 'pipe', 'ignore'], windowsHide: true }).trim();
|
|
6
|
+
}
|
|
3
7
|
/** A context query from the cwd's git state ('' means `getContext` lists by strength); kept out of the api layer, which never shells out. */
|
|
4
8
|
export function autoDetectContext() {
|
|
5
9
|
try {
|
|
6
|
-
const diff =
|
|
7
|
-
encoding: 'utf8',
|
|
8
|
-
timeout: 3000,
|
|
9
|
-
windowsHide: true,
|
|
10
|
-
}).trim();
|
|
10
|
+
const diff = readGit(['diff', '--name-only', 'HEAD']);
|
|
11
11
|
if (diff) {
|
|
12
12
|
const terms = diff
|
|
13
13
|
.split('\n')
|
|
@@ -17,11 +17,7 @@ export function autoDetectContext() {
|
|
|
17
17
|
if (terms.length > 0)
|
|
18
18
|
return terms.join(' ');
|
|
19
19
|
}
|
|
20
|
-
const branch =
|
|
21
|
-
encoding: 'utf8',
|
|
22
|
-
timeout: 3000,
|
|
23
|
-
windowsHide: true,
|
|
24
|
-
}).trim();
|
|
20
|
+
const branch = readGit(['branch', '--show-current']);
|
|
25
21
|
if (branch && branch !== 'main' && branch !== 'master') {
|
|
26
22
|
return branch.replace(/[-_/]/g, ' ');
|
|
27
23
|
}
|
package/dist/context-render.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type MemoryEntry } from './memory.js';
|
|
2
2
|
import { type SessionHandoff } from './handoff.js';
|
|
3
|
-
import type { SessionEvent, TaskSnapshot } from './store.js';
|
|
3
|
+
import type { SessionEvent, TaskSnapshot } from './store/rows.js';
|
|
4
4
|
import type { AssembleCost, AssembleResult, AssembledContextItem, ContextCost, ContextResultEntry, DrillDownChild, DrillDownCost, DrillDownResult } from './api.js';
|
|
5
5
|
export declare function snapshotText(s: TaskSnapshot): string;
|
|
6
6
|
export declare function handoffText(h: SessionHandoff): string;
|
package/dist/context-render.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// The strings a context block prints. The budget prices these same strings, so selection and print cannot drift.
|
|
2
2
|
import { calculateStrength, confidenceFacets, confidenceLabel } from './memory.js';
|
|
3
3
|
import { evalNow } from './ablation.js';
|
|
4
|
-
import { estimateTokens } from './
|
|
4
|
+
import { estimateTokens } from './token-ledger.js';
|
|
5
5
|
import { renderAmbientSummary } from './ambient.js';
|
|
6
6
|
import { formatHandoffEvidenceLine } from './handoff.js';
|
|
7
7
|
export function snapshotText(s) {
|
package/dist/customer-notes.d.ts
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
*
|
|
20
20
|
* Lifecycle: active -> superseded (a corrected version) or active -> closed (retired).
|
|
21
21
|
*/
|
|
22
|
+
import { type KeysetPosition } from './keyset.js';
|
|
22
23
|
export type NoteStatus = 'active' | 'superseded' | 'closed';
|
|
23
24
|
export declare const VALID_NOTE_STATES: ReadonlySet<NoteStatus>;
|
|
24
25
|
/** Field caps (untrusted at the HTTP/SDK boundary). note is a body, so a larger cap
|
|
@@ -61,6 +62,8 @@ export interface ListCustomerNotesOpts {
|
|
|
61
62
|
/** Filter to a single customer. */
|
|
62
63
|
customer?: string;
|
|
63
64
|
limit?: number;
|
|
65
|
+
/** Resume after this row: the position the previous page ended on. */
|
|
66
|
+
after?: KeysetPosition;
|
|
64
67
|
}
|
|
65
68
|
/**
|
|
66
69
|
* Create a customer_note (or a new version that supersedes an existing one). Writes
|
package/dist/customer-notes.js
CHANGED
|
@@ -21,12 +21,13 @@
|
|
|
21
21
|
*/
|
|
22
22
|
import { BadRequestError, ConflictError, NotFoundError } from './api-errors.js';
|
|
23
23
|
import { openHippoDb, closeHippoDb } from './db.js';
|
|
24
|
-
import { writeEntry } from './store.js';
|
|
24
|
+
import { writeEntry } from './store/entry-writes.js';
|
|
25
25
|
import { assertTenantId } from './tenant.js';
|
|
26
|
-
import { markGraphDirty, removeGraphEntitiesForObject } from './graph.js';
|
|
26
|
+
import { markGraphDirty, removeGraphEntitiesForObject } from './graph/write.js';
|
|
27
27
|
import { createMemory, Layer } from './memory.js';
|
|
28
28
|
import { appendAuditEvent } from './audit.js';
|
|
29
29
|
import { objectHalfLifeDays } from './half-life-migration.js';
|
|
30
|
+
import { keysetAfter } from './keyset.js';
|
|
30
31
|
export const VALID_NOTE_STATES = new Set([
|
|
31
32
|
'active',
|
|
32
33
|
'superseded',
|
|
@@ -284,6 +285,7 @@ export function loadCustomerNoteById(hippoRoot, tenantId, id) {
|
|
|
284
285
|
export function loadCustomerNotes(hippoRoot, tenantId, opts = {}) {
|
|
285
286
|
assertTenantId('loadCustomerNotes', tenantId);
|
|
286
287
|
const limit = opts.limit ?? 100;
|
|
288
|
+
const after = keysetAfter('created_at', 'id', opts.after);
|
|
287
289
|
if (opts.status && !VALID_NOTE_STATES.has(opts.status)) {
|
|
288
290
|
throw new BadRequestError(`loadCustomerNotes: status must be one of ${Array.from(VALID_NOTE_STATES).join('|')}; got ${opts.status}`);
|
|
289
291
|
}
|
|
@@ -299,13 +301,13 @@ export function loadCustomerNotes(hippoRoot, tenantId, opts = {}) {
|
|
|
299
301
|
clauses.push('customer = ?');
|
|
300
302
|
params.push(opts.customer);
|
|
301
303
|
}
|
|
302
|
-
params.push(limit);
|
|
304
|
+
params.push(...after.params, limit);
|
|
303
305
|
// SAFETY: SELECT ${NOTE_COLS} projects exactly the CustomerNoteRow columns
|
|
304
306
|
// regardless of the dynamic WHERE clause built above; .all() returns rows
|
|
305
307
|
// in that shape.
|
|
306
308
|
const rows = db.prepare(`
|
|
307
309
|
SELECT ${NOTE_COLS} FROM customer_notes
|
|
308
|
-
WHERE ${clauses.join(' AND ')}
|
|
310
|
+
WHERE ${clauses.join(' AND ')}${after.sql}
|
|
309
311
|
ORDER BY created_at DESC, id DESC
|
|
310
312
|
LIMIT ?
|
|
311
313
|
`).all(...params);
|
package/dist/dag.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { createMemory, Layer } from './memory.js';
|
|
2
|
-
import { writeEntry
|
|
2
|
+
import { writeEntry } from './store/entry-writes.js';
|
|
3
|
+
import { loadAllDirtySummaries, loadChildrenOfSummary, applyRebuildResult, clearSummaryDirtyAfterBuild, } from './store/summaries.js';
|
|
3
4
|
import { RejectedValueError } from './rejection.js';
|
|
4
|
-
import {
|
|
5
|
+
import { redactSecretsStrict } from './secret-detect.js';
|
|
5
6
|
import { fetchWithRetry, llmTimeoutMs } from './http-retry.js';
|
|
6
7
|
import { derivationScope, derivationPartitionKey } from './recall-scope.js';
|
|
7
8
|
import { loadConfig } from './config.js';
|
|
8
9
|
import { neverAutoShareTags } from './shared.js';
|
|
10
|
+
import { log } from './log.js';
|
|
9
11
|
export function clusterFacts(facts) {
|
|
10
12
|
if (facts.length === 0)
|
|
11
13
|
return [];
|
|
@@ -47,9 +49,9 @@ Write a single concise paragraph (2-4 sentences) that captures all the key infor
|
|
|
47
49
|
export async function generateDagSummary(label, factContents, opts) {
|
|
48
50
|
const model = opts.model ?? 'claude-sonnet-4-6';
|
|
49
51
|
const fetchFn = opts.fetcher ?? fetch;
|
|
50
|
-
const factsBlock = factContents.map((f, i) => `${i + 1}. ${
|
|
52
|
+
const factsBlock = factContents.map((f, i) => `${i + 1}. ${redactSecretsStrict(f)}`).join('\n');
|
|
51
53
|
const prompt = DAG_SUMMARY_PROMPT
|
|
52
|
-
.replace('{label}',
|
|
54
|
+
.replace('{label}', redactSecretsStrict(label))
|
|
53
55
|
.replace('{facts}', factsBlock);
|
|
54
56
|
let res;
|
|
55
57
|
try {
|
|
@@ -144,7 +146,7 @@ export async function buildDag(hippoRoot, facts, opts) {
|
|
|
144
146
|
// The tombstone check itself is tenant-scoped for free: writeEntry ->
|
|
145
147
|
// writeEntryDbOnly -> upsertEntryRow calls
|
|
146
148
|
// checkRejectionGuard(db, entry.tenantId ?? 'default', ...)
|
|
147
|
-
// (store.ts
|
|
149
|
+
// (store/entry-writes.ts), reading tenantId off the entry being written. Now
|
|
148
150
|
// that summaryEntry carries factTenant instead of the implicit
|
|
149
151
|
// 'default', the guard consults that tenant's tombstones — no
|
|
150
152
|
// separate check needed here (unlike consolidate.ts's merge pass,
|
|
@@ -157,7 +159,7 @@ export async function buildDag(hippoRoot, facts, opts) {
|
|
|
157
159
|
catch (err) {
|
|
158
160
|
if (err instanceof RejectedValueError) {
|
|
159
161
|
result.rejected++;
|
|
160
|
-
|
|
162
|
+
log.warn(`buildDag: cluster "${cluster.label}" skipped: summary matches a rejected value`);
|
|
161
163
|
continue;
|
|
162
164
|
}
|
|
163
165
|
throw err;
|
|
@@ -169,7 +171,7 @@ export async function buildDag(hippoRoot, facts, opts) {
|
|
|
169
171
|
result.factsLinked++;
|
|
170
172
|
}
|
|
171
173
|
// v0.30 / E3 — cancel the cascade of dirty-marks fired by member
|
|
172
|
-
// writeEntry calls (E2 hook on writeEntryDbOnly
|
|
174
|
+
// writeEntry calls (E2 hook on writeEntryDbOnly in store/entry-writes.ts).
|
|
173
175
|
// The summary we just built IS fresh, no rebuild needed. Without this,
|
|
174
176
|
// E3 in the SAME sleep cycle would re-rebuild every new summary
|
|
175
177
|
// (2x LLM cost). plan-eng-r1 HIGH must-fix.
|
|
@@ -235,7 +237,7 @@ export async function rebuildDirtySummaries(hippoRoot, opts) {
|
|
|
235
237
|
result.zeroChildSkipped++;
|
|
236
238
|
// changed=false → race lost / row vanished; silently skip. `refused`
|
|
237
239
|
// is always false here — applyRebuildResult only checks the
|
|
238
|
-
// tombstone when bumpRebuildCount is true (store.ts
|
|
240
|
+
// tombstone when bumpRebuildCount is true (store/summaries.ts).
|
|
239
241
|
continue;
|
|
240
242
|
}
|
|
241
243
|
// Derive label from summary's existing entity tags (mirrors clusterFacts)
|
|
@@ -271,11 +273,10 @@ export async function rebuildDirtySummaries(hippoRoot, opts) {
|
|
|
271
273
|
catch (err) {
|
|
272
274
|
// Per-summary failure isolation — one throw doesn't abort the queue.
|
|
273
275
|
// independent-review MED #2 fold: log enough to triage in production
|
|
274
|
-
// (audit() wraps its own writes try/catch per store.ts
|
|
276
|
+
// (audit() wraps its own writes try/catch per store/audit-event.ts, so a
|
|
275
277
|
// throw here is exotic: SQLite I/O error, prepare failure, etc).
|
|
276
278
|
result.failed++;
|
|
277
|
-
|
|
278
|
-
console.error(`[rebuildDirtySummaries] summary ${summary.id} (tenant ${summary.tenantId}) failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
279
|
+
log.error(`rebuildDirtySummaries: summary ${summary.id} (tenant ${summary.tenantId}) failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
279
280
|
}
|
|
280
281
|
}
|
|
281
282
|
return result;
|
|
@@ -353,7 +354,7 @@ export async function buildEntityProfiles(hippoRoot, l2Summaries, opts) {
|
|
|
353
354
|
catch (err) {
|
|
354
355
|
if (err instanceof RejectedValueError) {
|
|
355
356
|
result.rejected++;
|
|
356
|
-
|
|
357
|
+
log.warn(`buildEntityProfiles: cluster "${cluster.label}" skipped: profile matches a rejected value`);
|
|
357
358
|
continue;
|
|
358
359
|
}
|
|
359
360
|
throw err;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { MemoryEntry } from './memory.js';
|
|
2
|
+
import { type ActionBody } from './dashboard-params.js';
|
|
3
|
+
/** What an action hands the router: a status, a JSON body, and whether the store changed. */
|
|
4
|
+
export interface ActionResult {
|
|
5
|
+
status: number;
|
|
6
|
+
body: unknown;
|
|
7
|
+
/** True when a write committed, so the router drops the snapshot. */
|
|
8
|
+
changed: boolean;
|
|
9
|
+
/** The live entry an action acted on, so the router can build the detail after the cache is dropped. */
|
|
10
|
+
entry?: MemoryEntry;
|
|
11
|
+
}
|
|
12
|
+
/** Sets `pinned`; the audit row says `remember` with actor `dashboard`, the same op the old star toggle wrote. */
|
|
13
|
+
export declare function pinMemory(hippoRoot: string, tenantId: string, rawId: string, body: ActionBody): ActionResult;
|
|
14
|
+
/** Marks a memory wrong, the same signal as `hippo outcome --bad`. */
|
|
15
|
+
export declare function markWrong(hippoRoot: string, tenantId: string, rawId: string): ActionResult;
|
|
16
|
+
/** Deletes a memory like `hippo forget`; a raw receipt is append-only and answers 409 with the archive hint. */
|
|
17
|
+
export declare function forgetMemory(hippoRoot: string, tenantId: string, rawId: string): ActionResult;
|
|
18
|
+
/** Keeps one side of an open conflict and weakens the other; every refusal maps to its own status. */
|
|
19
|
+
export declare function resolveOpenConflict(hippoRoot: string, tenantId: string, conflictId: number, body: ActionBody): ActionResult;
|
|
20
|
+
//# sourceMappingURL=dashboard-actions.d.ts.map
|