hippo-memory 1.44.0 → 1.46.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 +68 -24
- package/bin/hippo.js +3 -1
- package/dist/ablation.d.ts +10 -1
- package/dist/ablation.js +17 -1
- package/dist/api.d.ts +81 -22
- package/dist/api.js +258 -49
- package/dist/audit.d.ts +2 -2
- package/dist/audit.js +9 -0
- package/dist/autolearn.d.ts +1 -1
- package/dist/autolearn.js +2 -1
- package/dist/capture-error.d.ts +20 -0
- package/dist/capture-error.js +82 -0
- package/dist/capture.d.ts +25 -8
- package/dist/capture.js +100 -5
- package/dist/cli.d.ts +9 -1
- package/dist/cli.js +531 -119
- package/dist/client.d.ts +4 -21
- package/dist/client.js +3 -112
- package/dist/config.d.ts +20 -0
- package/dist/config.js +37 -1
- package/dist/consolidate.d.ts +9 -0
- package/dist/consolidate.js +133 -46
- package/dist/dag.d.ts +1 -0
- package/dist/dag.js +10 -5
- package/dist/dashboard.js +7 -3
- package/dist/db.js +69 -24
- package/dist/dedupe.d.ts +1 -0
- package/dist/dedupe.js +4 -7
- package/dist/doctor.d.ts +34 -0
- package/dist/doctor.js +174 -0
- package/dist/dormant.d.ts +91 -0
- package/dist/dormant.js +121 -0
- package/dist/embedding-provider.js +2 -1
- package/dist/embeddings.js +81 -8
- package/dist/eval-stats.d.ts +123 -0
- package/dist/eval-stats.js +187 -0
- package/dist/extract.d.ts +2 -0
- package/dist/extract.js +9 -4
- package/dist/half-life-migration.d.ts +55 -0
- package/dist/half-life-migration.js +111 -0
- package/dist/hooks.d.ts +4 -0
- package/dist/hooks.js +47 -0
- package/dist/mcp/server.d.ts +6 -0
- package/dist/mcp/server.js +90 -48
- package/dist/memory.d.ts +18 -1
- package/dist/memory.js +33 -5
- package/dist/physics-config.js +5 -1
- package/dist/recall-scope.d.ts +24 -0
- package/dist/recall-scope.js +41 -0
- package/dist/refine-llm.js +3 -2
- package/dist/reject-flow.d.ts +3 -3
- package/dist/reject-flow.js +10 -3
- package/dist/rerankers/jev.js +3 -2
- package/dist/rerankers/llm.js +3 -2
- package/dist/search.d.ts +4 -4
- package/dist/search.js +26 -21
- package/dist/server.d.ts +5 -0
- package/dist/server.js +49 -29
- package/dist/shared.js +1 -1
- package/dist/store.d.ts +29 -11
- package/dist/store.js +197 -70
- package/dist/token-ledger.d.ts +119 -0
- package/dist/token-ledger.js +181 -0
- package/dist/version.d.ts +4 -6
- package/dist/version.js +4 -7
- 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 +7 -3
- package/dist/ablation.d.ts.map +0 -1
- package/dist/ablation.js.map +0 -1
- package/dist/ambient.d.ts.map +0 -1
- package/dist/ambient.js.map +0 -1
- package/dist/api.d.ts.map +0 -1
- package/dist/api.js.map +0 -1
- package/dist/audit-prune.d.ts.map +0 -1
- package/dist/audit-prune.js.map +0 -1
- package/dist/audit.d.ts.map +0 -1
- package/dist/audit.js.map +0 -1
- package/dist/auth.d.ts.map +0 -1
- package/dist/auth.js.map +0 -1
- package/dist/autolearn.d.ts.map +0 -1
- package/dist/autolearn.js.map +0 -1
- package/dist/availability.d.ts.map +0 -1
- package/dist/availability.js.map +0 -1
- package/dist/benchmarks/e1.3/incident-recall-eval.js +0 -78
- package/dist/benchmarks/e1.3/incident-recall-eval.js.map +0 -1
- package/dist/benchmarks/e1.3/slack-1000-event-smoke.js +0 -103
- package/dist/benchmarks/e1.3/slack-1000-event-smoke.js.map +0 -1
- package/dist/capture.d.ts.map +0 -1
- package/dist/capture.js.map +0 -1
- package/dist/card-detail.d.ts.map +0 -1
- package/dist/card-detail.js.map +0 -1
- package/dist/card.d.ts.map +0 -1
- package/dist/card.js.map +0 -1
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/client.d.ts.map +0 -1
- package/dist/client.js.map +0 -1
- package/dist/compare.d.ts.map +0 -1
- package/dist/compare.js.map +0 -1
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js.map +0 -1
- package/dist/connectors/github/backfill.d.ts.map +0 -1
- package/dist/connectors/github/backfill.js.map +0 -1
- package/dist/connectors/github/cli-impl.d.ts.map +0 -1
- package/dist/connectors/github/cli-impl.js.map +0 -1
- package/dist/connectors/github/deletion.d.ts.map +0 -1
- package/dist/connectors/github/deletion.js.map +0 -1
- package/dist/connectors/github/dlq.d.ts.map +0 -1
- package/dist/connectors/github/dlq.js.map +0 -1
- package/dist/connectors/github/idempotency.d.ts.map +0 -1
- package/dist/connectors/github/idempotency.js.map +0 -1
- package/dist/connectors/github/ingest.d.ts.map +0 -1
- package/dist/connectors/github/ingest.js.map +0 -1
- package/dist/connectors/github/octokit-client.d.ts.map +0 -1
- package/dist/connectors/github/octokit-client.js.map +0 -1
- package/dist/connectors/github/ratelimit.d.ts.map +0 -1
- package/dist/connectors/github/ratelimit.js.map +0 -1
- package/dist/connectors/github/scope.d.ts.map +0 -1
- package/dist/connectors/github/scope.js.map +0 -1
- package/dist/connectors/github/signature.d.ts.map +0 -1
- package/dist/connectors/github/signature.js.map +0 -1
- package/dist/connectors/github/tenant-routing.d.ts.map +0 -1
- package/dist/connectors/github/tenant-routing.js.map +0 -1
- package/dist/connectors/github/transform.d.ts.map +0 -1
- package/dist/connectors/github/transform.js.map +0 -1
- package/dist/connectors/github/types.d.ts.map +0 -1
- package/dist/connectors/github/types.js.map +0 -1
- package/dist/connectors/slack/backfill.d.ts.map +0 -1
- package/dist/connectors/slack/backfill.js.map +0 -1
- package/dist/connectors/slack/deletion.d.ts.map +0 -1
- package/dist/connectors/slack/deletion.js.map +0 -1
- package/dist/connectors/slack/dlq.d.ts.map +0 -1
- package/dist/connectors/slack/dlq.js.map +0 -1
- package/dist/connectors/slack/idempotency.d.ts.map +0 -1
- package/dist/connectors/slack/idempotency.js.map +0 -1
- package/dist/connectors/slack/ingest.d.ts.map +0 -1
- package/dist/connectors/slack/ingest.js.map +0 -1
- package/dist/connectors/slack/ratelimit.d.ts.map +0 -1
- package/dist/connectors/slack/ratelimit.js.map +0 -1
- package/dist/connectors/slack/scope.d.ts.map +0 -1
- package/dist/connectors/slack/scope.js.map +0 -1
- package/dist/connectors/slack/signature.d.ts.map +0 -1
- package/dist/connectors/slack/signature.js.map +0 -1
- package/dist/connectors/slack/tenant-routing.d.ts.map +0 -1
- package/dist/connectors/slack/tenant-routing.js.map +0 -1
- package/dist/connectors/slack/transform.d.ts.map +0 -1
- package/dist/connectors/slack/transform.js.map +0 -1
- package/dist/connectors/slack/types.d.ts.map +0 -1
- package/dist/connectors/slack/types.js.map +0 -1
- package/dist/connectors/slack/web-client.d.ts.map +0 -1
- package/dist/connectors/slack/web-client.js.map +0 -1
- package/dist/connectors/slack/workspaces.d.ts.map +0 -1
- package/dist/connectors/slack/workspaces.js.map +0 -1
- package/dist/consolidate.d.ts.map +0 -1
- package/dist/consolidate.js.map +0 -1
- package/dist/correction-latency.d.ts.map +0 -1
- package/dist/correction-latency.js.map +0 -1
- package/dist/customer-notes.d.ts.map +0 -1
- package/dist/customer-notes.js.map +0 -1
- package/dist/dag.d.ts.map +0 -1
- package/dist/dag.js.map +0 -1
- package/dist/dashboard.d.ts.map +0 -1
- package/dist/dashboard.js.map +0 -1
- package/dist/db.d.ts.map +0 -1
- package/dist/db.js.map +0 -1
- package/dist/decisions.d.ts.map +0 -1
- package/dist/decisions.js.map +0 -1
- package/dist/dedupe.d.ts.map +0 -1
- package/dist/dedupe.js.map +0 -1
- package/dist/embedding-provider.d.ts.map +0 -1
- package/dist/embedding-provider.js.map +0 -1
- package/dist/embeddings.d.ts.map +0 -1
- package/dist/embeddings.js.map +0 -1
- package/dist/eval-suite.d.ts.map +0 -1
- package/dist/eval-suite.js.map +0 -1
- package/dist/eval.d.ts.map +0 -1
- package/dist/eval.js.map +0 -1
- package/dist/extensions/openclaw-plugin/index.js.map +0 -1
- package/dist/extract.d.ts.map +0 -1
- package/dist/extract.js.map +0 -1
- package/dist/forward-claim-detector.d.ts.map +0 -1
- package/dist/forward-claim-detector.js.map +0 -1
- package/dist/goals.d.ts.map +0 -1
- package/dist/goals.js.map +0 -1
- package/dist/graph-extract.d.ts.map +0 -1
- package/dist/graph-extract.js.map +0 -1
- package/dist/graph-recall.d.ts.map +0 -1
- package/dist/graph-recall.js.map +0 -1
- package/dist/graph-stream.d.ts.map +0 -1
- package/dist/graph-stream.js.map +0 -1
- package/dist/graph-view.d.ts.map +0 -1
- package/dist/graph-view.js.map +0 -1
- package/dist/graph.d.ts.map +0 -1
- package/dist/graph.js.map +0 -1
- package/dist/handoff.d.ts.map +0 -1
- package/dist/handoff.js.map +0 -1
- package/dist/hooks.d.ts.map +0 -1
- package/dist/hooks.js.map +0 -1
- package/dist/importers.d.ts.map +0 -1
- package/dist/importers.js.map +0 -1
- package/dist/incidents.d.ts.map +0 -1
- package/dist/incidents.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/invalidation.d.ts.map +0 -1
- package/dist/invalidation.js.map +0 -1
- package/dist/mcp/framing.d.ts.map +0 -1
- package/dist/mcp/framing.js.map +0 -1
- package/dist/mcp/server.d.ts.map +0 -1
- package/dist/mcp/server.js.map +0 -1
- package/dist/memory-value-weights.d.ts.map +0 -1
- package/dist/memory-value-weights.js.map +0 -1
- package/dist/memory-value.d.ts.map +0 -1
- package/dist/memory-value.js.map +0 -1
- package/dist/memory.d.ts.map +0 -1
- package/dist/memory.js.map +0 -1
- package/dist/multihop.d.ts.map +0 -1
- package/dist/multihop.js.map +0 -1
- package/dist/owner-validation.d.ts.map +0 -1
- package/dist/owner-validation.js.map +0 -1
- package/dist/path-context.d.ts.map +0 -1
- package/dist/path-context.js.map +0 -1
- package/dist/physics-config.d.ts.map +0 -1
- package/dist/physics-config.js.map +0 -1
- package/dist/physics-state.d.ts.map +0 -1
- package/dist/physics-state.js.map +0 -1
- package/dist/physics.d.ts.map +0 -1
- package/dist/physics.js.map +0 -1
- package/dist/policies.d.ts.map +0 -1
- package/dist/policies.js.map +0 -1
- package/dist/postinstall.d.ts.map +0 -1
- package/dist/postinstall.js.map +0 -1
- package/dist/predictions.d.ts.map +0 -1
- package/dist/predictions.js.map +0 -1
- package/dist/processes.d.ts.map +0 -1
- package/dist/processes.js.map +0 -1
- package/dist/project-briefs.d.ts.map +0 -1
- package/dist/project-briefs.js.map +0 -1
- package/dist/project-identity.d.ts.map +0 -1
- package/dist/project-identity.js.map +0 -1
- package/dist/provenance-coverage.d.ts.map +0 -1
- package/dist/provenance-coverage.js.map +0 -1
- package/dist/rate-limit.d.ts.map +0 -1
- package/dist/rate-limit.js.map +0 -1
- package/dist/raw-archive-mirror-cleanup.d.ts.map +0 -1
- package/dist/raw-archive-mirror-cleanup.js.map +0 -1
- package/dist/raw-archive.d.ts.map +0 -1
- package/dist/raw-archive.js.map +0 -1
- package/dist/recall-history.d.ts.map +0 -1
- package/dist/recall-history.js.map +0 -1
- package/dist/recall-scope.d.ts.map +0 -1
- package/dist/recall-scope.js.map +0 -1
- package/dist/recall-trace.d.ts.map +0 -1
- package/dist/recall-trace.js.map +0 -1
- package/dist/refine-llm.d.ts.map +0 -1
- package/dist/refine-llm.js.map +0 -1
- package/dist/reject-flow.d.ts.map +0 -1
- package/dist/reject-flow.js.map +0 -1
- package/dist/rejection.d.ts.map +0 -1
- package/dist/rejection.js.map +0 -1
- package/dist/replay.d.ts.map +0 -1
- package/dist/replay.js.map +0 -1
- package/dist/rerankers/cross-encoder.d.ts.map +0 -1
- package/dist/rerankers/cross-encoder.js.map +0 -1
- package/dist/rerankers/index.d.ts.map +0 -1
- package/dist/rerankers/index.js.map +0 -1
- package/dist/rerankers/jev.d.ts.map +0 -1
- package/dist/rerankers/jev.js.map +0 -1
- package/dist/rerankers/llm.d.ts.map +0 -1
- package/dist/rerankers/llm.js.map +0 -1
- package/dist/rerankers/types.d.ts.map +0 -1
- package/dist/rerankers/types.js.map +0 -1
- package/dist/rrf.d.ts.map +0 -1
- package/dist/rrf.js.map +0 -1
- package/dist/salience.d.ts.map +0 -1
- package/dist/salience.js.map +0 -1
- package/dist/scheduler.d.ts.map +0 -1
- package/dist/scheduler.js.map +0 -1
- package/dist/scope.d.ts.map +0 -1
- package/dist/scope.js.map +0 -1
- package/dist/search.d.ts.map +0 -1
- package/dist/search.js.map +0 -1
- package/dist/secret-detect.d.ts.map +0 -1
- package/dist/secret-detect.js.map +0 -1
- package/dist/server-detect.d.ts.map +0 -1
- package/dist/server-detect.js.map +0 -1
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js.map +0 -1
- package/dist/shared.d.ts.map +0 -1
- package/dist/shared.js.map +0 -1
- package/dist/skills.d.ts.map +0 -1
- package/dist/skills.js.map +0 -1
- package/dist/sleep-redact.d.ts +0 -58
- package/dist/sleep-redact.d.ts.map +0 -1
- package/dist/sleep-redact.js +0 -80
- package/dist/sleep-redact.js.map +0 -1
- package/dist/src/ablation.js +0 -138
- package/dist/src/ablation.js.map +0 -1
- package/dist/src/ambient.js +0 -148
- package/dist/src/ambient.js.map +0 -1
- package/dist/src/api.js +0 -2109
- package/dist/src/api.js.map +0 -1
- package/dist/src/audit-prune.js +0 -109
- package/dist/src/audit-prune.js.map +0 -1
- package/dist/src/audit.js +0 -213
- package/dist/src/audit.js.map +0 -1
- package/dist/src/auth.js +0 -97
- package/dist/src/auth.js.map +0 -1
- package/dist/src/autolearn.js +0 -174
- package/dist/src/autolearn.js.map +0 -1
- package/dist/src/availability.js +0 -94
- package/dist/src/availability.js.map +0 -1
- package/dist/src/capture.js +0 -1346
- package/dist/src/capture.js.map +0 -1
- package/dist/src/card-detail.js +0 -15
- package/dist/src/card-detail.js.map +0 -1
- package/dist/src/card.js +0 -19
- package/dist/src/card.js.map +0 -1
- package/dist/src/cli.js +0 -9387
- package/dist/src/cli.js.map +0 -1
- package/dist/src/client.js +0 -237
- package/dist/src/client.js.map +0 -1
- package/dist/src/compare.js +0 -122
- package/dist/src/compare.js.map +0 -1
- package/dist/src/config.js +0 -135
- package/dist/src/config.js.map +0 -1
- package/dist/src/connectors/github/backfill.js +0 -281
- package/dist/src/connectors/github/backfill.js.map +0 -1
- package/dist/src/connectors/github/cli-impl.js +0 -234
- package/dist/src/connectors/github/cli-impl.js.map +0 -1
- package/dist/src/connectors/github/deletion.js +0 -85
- package/dist/src/connectors/github/deletion.js.map +0 -1
- package/dist/src/connectors/github/dlq.js +0 -190
- package/dist/src/connectors/github/dlq.js.map +0 -1
- package/dist/src/connectors/github/idempotency.js +0 -27
- package/dist/src/connectors/github/idempotency.js.map +0 -1
- package/dist/src/connectors/github/ingest.js +0 -156
- package/dist/src/connectors/github/ingest.js.map +0 -1
- package/dist/src/connectors/github/octokit-client.js +0 -70
- package/dist/src/connectors/github/octokit-client.js.map +0 -1
- package/dist/src/connectors/github/ratelimit.js +0 -31
- package/dist/src/connectors/github/ratelimit.js.map +0 -1
- package/dist/src/connectors/github/scope.js +0 -13
- package/dist/src/connectors/github/scope.js.map +0 -1
- package/dist/src/connectors/github/signature.js +0 -81
- package/dist/src/connectors/github/signature.js.map +0 -1
- package/dist/src/connectors/github/tenant-routing.js +0 -69
- package/dist/src/connectors/github/tenant-routing.js.map +0 -1
- package/dist/src/connectors/github/transform.js +0 -103
- package/dist/src/connectors/github/transform.js.map +0 -1
- package/dist/src/connectors/github/types.js +0 -100
- package/dist/src/connectors/github/types.js.map +0 -1
- package/dist/src/connectors/slack/backfill.js +0 -78
- package/dist/src/connectors/slack/backfill.js.map +0 -1
- package/dist/src/connectors/slack/deletion.js +0 -59
- package/dist/src/connectors/slack/deletion.js.map +0 -1
- package/dist/src/connectors/slack/dlq.js +0 -224
- package/dist/src/connectors/slack/dlq.js.map +0 -1
- package/dist/src/connectors/slack/idempotency.js +0 -31
- package/dist/src/connectors/slack/idempotency.js.map +0 -1
- package/dist/src/connectors/slack/ingest.js +0 -109
- package/dist/src/connectors/slack/ingest.js.map +0 -1
- package/dist/src/connectors/slack/ratelimit.js +0 -18
- package/dist/src/connectors/slack/ratelimit.js.map +0 -1
- package/dist/src/connectors/slack/scope.js +0 -13
- package/dist/src/connectors/slack/scope.js.map +0 -1
- package/dist/src/connectors/slack/signature.js +0 -27
- package/dist/src/connectors/slack/signature.js.map +0 -1
- package/dist/src/connectors/slack/tenant-routing.js +0 -41
- package/dist/src/connectors/slack/tenant-routing.js.map +0 -1
- package/dist/src/connectors/slack/transform.js +0 -47
- package/dist/src/connectors/slack/transform.js.map +0 -1
- package/dist/src/connectors/slack/types.js +0 -35
- package/dist/src/connectors/slack/types.js.map +0 -1
- package/dist/src/connectors/slack/web-client.js +0 -43
- package/dist/src/connectors/slack/web-client.js.map +0 -1
- package/dist/src/connectors/slack/workspaces.js +0 -62
- package/dist/src/connectors/slack/workspaces.js.map +0 -1
- package/dist/src/consolidate.js +0 -978
- package/dist/src/consolidate.js.map +0 -1
- package/dist/src/correction-latency.js +0 -74
- package/dist/src/correction-latency.js.map +0 -1
- package/dist/src/customer-notes.js +0 -325
- package/dist/src/customer-notes.js.map +0 -1
- package/dist/src/dag.js +0 -352
- package/dist/src/dag.js.map +0 -1
- package/dist/src/dashboard.js +0 -258
- package/dist/src/dashboard.js.map +0 -1
- package/dist/src/db.js +0 -2731
- package/dist/src/db.js.map +0 -1
- package/dist/src/decisions.js +0 -304
- package/dist/src/decisions.js.map +0 -1
- package/dist/src/dedupe.js +0 -141
- package/dist/src/dedupe.js.map +0 -1
- package/dist/src/embedding-provider.js +0 -314
- package/dist/src/embedding-provider.js.map +0 -1
- package/dist/src/embeddings.js +0 -543
- package/dist/src/embeddings.js.map +0 -1
- package/dist/src/eval-suite.js +0 -294
- package/dist/src/eval-suite.js.map +0 -1
- package/dist/src/eval.js +0 -187
- package/dist/src/eval.js.map +0 -1
- package/dist/src/extract.js +0 -117
- package/dist/src/extract.js.map +0 -1
- package/dist/src/forward-claim-detector.js +0 -117
- package/dist/src/forward-claim-detector.js.map +0 -1
- package/dist/src/goals.js +0 -399
- package/dist/src/goals.js.map +0 -1
- package/dist/src/graph-extract.js +0 -314
- package/dist/src/graph-extract.js.map +0 -1
- package/dist/src/graph-recall.js +0 -277
- package/dist/src/graph-recall.js.map +0 -1
- package/dist/src/graph-stream.js +0 -176
- package/dist/src/graph-stream.js.map +0 -1
- package/dist/src/graph-view.js +0 -310
- package/dist/src/graph-view.js.map +0 -1
- package/dist/src/graph.js +0 -762
- package/dist/src/graph.js.map +0 -1
- package/dist/src/handoff.js +0 -65
- package/dist/src/handoff.js.map +0 -1
- package/dist/src/hooks.js +0 -926
- package/dist/src/hooks.js.map +0 -1
- package/dist/src/importers.js +0 -881
- package/dist/src/importers.js.map +0 -1
- package/dist/src/incidents.js +0 -336
- package/dist/src/incidents.js.map +0 -1
- package/dist/src/index.js +0 -32
- package/dist/src/index.js.map +0 -1
- package/dist/src/invalidation.js +0 -129
- package/dist/src/invalidation.js.map +0 -1
- package/dist/src/mcp/framing.js +0 -45
- package/dist/src/mcp/framing.js.map +0 -1
- package/dist/src/mcp/server.js +0 -1298
- package/dist/src/mcp/server.js.map +0 -1
- package/dist/src/memory-value-weights.js +0 -31
- package/dist/src/memory-value-weights.js.map +0 -1
- package/dist/src/memory-value.js +0 -261
- package/dist/src/memory-value.js.map +0 -1
- package/dist/src/memory.js +0 -425
- package/dist/src/memory.js.map +0 -1
- package/dist/src/multihop.js +0 -35
- package/dist/src/multihop.js.map +0 -1
- package/dist/src/owner-validation.js +0 -56
- package/dist/src/owner-validation.js.map +0 -1
- package/dist/src/path-context.js +0 -48
- package/dist/src/path-context.js.map +0 -1
- package/dist/src/physics-config.js +0 -26
- package/dist/src/physics-config.js.map +0 -1
- package/dist/src/physics-state.js +0 -172
- package/dist/src/physics-state.js.map +0 -1
- package/dist/src/physics.js +0 -378
- package/dist/src/physics.js.map +0 -1
- package/dist/src/policies.js +0 -414
- package/dist/src/policies.js.map +0 -1
- package/dist/src/postinstall.js +0 -101
- package/dist/src/postinstall.js.map +0 -1
- package/dist/src/predictions.js +0 -629
- package/dist/src/predictions.js.map +0 -1
- package/dist/src/processes.js +0 -349
- package/dist/src/processes.js.map +0 -1
- package/dist/src/project-briefs.js +0 -492
- package/dist/src/project-briefs.js.map +0 -1
- package/dist/src/project-identity.js +0 -200
- package/dist/src/project-identity.js.map +0 -1
- package/dist/src/provenance-coverage.js +0 -23
- package/dist/src/provenance-coverage.js.map +0 -1
- package/dist/src/rate-limit.js +0 -60
- package/dist/src/rate-limit.js.map +0 -1
- package/dist/src/raw-archive-mirror-cleanup.js +0 -55
- package/dist/src/raw-archive-mirror-cleanup.js.map +0 -1
- package/dist/src/raw-archive.js +0 -91
- package/dist/src/raw-archive.js.map +0 -1
- package/dist/src/recall-history.js +0 -235
- package/dist/src/recall-history.js.map +0 -1
- package/dist/src/recall-scope.js +0 -89
- package/dist/src/recall-scope.js.map +0 -1
- package/dist/src/recall-trace.js +0 -186
- package/dist/src/recall-trace.js.map +0 -1
- package/dist/src/refine-llm.js +0 -156
- package/dist/src/refine-llm.js.map +0 -1
- package/dist/src/reject-flow.js +0 -209
- package/dist/src/reject-flow.js.map +0 -1
- package/dist/src/rejection.js +0 -160
- package/dist/src/rejection.js.map +0 -1
- package/dist/src/replay.js +0 -122
- package/dist/src/replay.js.map +0 -1
- package/dist/src/rerankers/cross-encoder.js +0 -137
- package/dist/src/rerankers/cross-encoder.js.map +0 -1
- package/dist/src/rerankers/index.js +0 -20
- package/dist/src/rerankers/index.js.map +0 -1
- package/dist/src/rerankers/jev.js +0 -119
- package/dist/src/rerankers/jev.js.map +0 -1
- package/dist/src/rerankers/llm.js +0 -80
- package/dist/src/rerankers/llm.js.map +0 -1
- package/dist/src/rerankers/types.js +0 -2
- package/dist/src/rerankers/types.js.map +0 -1
- package/dist/src/rrf.js +0 -61
- package/dist/src/rrf.js.map +0 -1
- package/dist/src/salience.js +0 -74
- package/dist/src/salience.js.map +0 -1
- package/dist/src/scheduler.js +0 -77
- package/dist/src/scheduler.js.map +0 -1
- package/dist/src/scope.js +0 -35
- package/dist/src/scope.js.map +0 -1
- package/dist/src/search.js +0 -1003
- package/dist/src/search.js.map +0 -1
- package/dist/src/secret-detect.js +0 -95
- package/dist/src/secret-detect.js.map +0 -1
- package/dist/src/server-detect.js +0 -231
- package/dist/src/server-detect.js.map +0 -1
- package/dist/src/server.js +0 -3255
- package/dist/src/server.js.map +0 -1
- package/dist/src/shared.js +0 -502
- package/dist/src/shared.js.map +0 -1
- package/dist/src/skills.js +0 -346
- package/dist/src/skills.js.map +0 -1
- package/dist/src/sleep-redact.js +0 -80
- package/dist/src/sleep-redact.js.map +0 -1
- package/dist/src/sso.js +0 -22
- package/dist/src/sso.js.map +0 -1
- package/dist/src/stdin.js +0 -41
- package/dist/src/stdin.js.map +0 -1
- package/dist/src/store.js +0 -3749
- package/dist/src/store.js.map +0 -1
- package/dist/src/tenant.js +0 -17
- package/dist/src/tenant.js.map +0 -1
- package/dist/src/trace.js +0 -72
- package/dist/src/trace.js.map +0 -1
- package/dist/src/version.js +0 -40
- package/dist/src/version.js.map +0 -1
- package/dist/src/working-memory.js +0 -157
- package/dist/src/working-memory.js.map +0 -1
- package/dist/src/yaml.js +0 -107
- package/dist/src/yaml.js.map +0 -1
- package/dist/sso.d.ts +0 -13
- package/dist/sso.d.ts.map +0 -1
- package/dist/sso.js +0 -22
- package/dist/sso.js.map +0 -1
- package/dist/stdin.d.ts.map +0 -1
- package/dist/stdin.js.map +0 -1
- package/dist/store.d.ts.map +0 -1
- package/dist/store.js.map +0 -1
- package/dist/tenant.d.ts.map +0 -1
- package/dist/tenant.js.map +0 -1
- package/dist/trace.d.ts.map +0 -1
- package/dist/trace.js.map +0 -1
- package/dist/version.d.ts.map +0 -1
- package/dist/version.js.map +0 -1
- package/dist/working-memory.d.ts.map +0 -1
- package/dist/working-memory.js.map +0 -1
- package/dist/yaml.d.ts.map +0 -1
- package/dist/yaml.js.map +0 -1
package/dist/store.js
CHANGED
|
@@ -6,12 +6,13 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import * as fs from 'fs';
|
|
8
8
|
import * as path from 'path';
|
|
9
|
-
import { Layer, generateId } from './memory.js';
|
|
9
|
+
import { Layer, generateId, AUTO_DELETABLE_SQL, DEFAULT_HALF_LIFE_DAYS } from './memory.js';
|
|
10
10
|
import { dumpFrontmatter, parseFrontmatter } from './yaml.js';
|
|
11
11
|
import { openHippoDb, closeHippoDb, getMeta, setMeta, isFtsAvailable, pruneConsolidationRuns, getHippoDbPath, } from './db.js';
|
|
12
12
|
import { rowToSessionHandoff, isHandoffOutcome } from './handoff.js';
|
|
13
13
|
import { CARD_TRANSITIONS, CARD_LEASE_MS } from './card.js';
|
|
14
|
-
import { tokenize } from './search.js';
|
|
14
|
+
import { tokenize, markRetrieved } from './search.js';
|
|
15
|
+
import { isRecallBoostAblated } from './ablation.js';
|
|
15
16
|
import { appendAuditEvent } from './audit.js';
|
|
16
17
|
import { resolveTenantId } from './tenant.js';
|
|
17
18
|
import { deriveOriginProject, originFromSource, findHippoStoreDir, realpathOrResolve } from './project-identity.js';
|
|
@@ -22,6 +23,7 @@ import { checkRejectionGuard, RejectedValueError, rejectionDigest, normalizeValu
|
|
|
22
23
|
// inside function bodies (never at module-evaluation time), so the cycle
|
|
23
24
|
// is the standard safe mutual-function-reference shape under NodeNext ESM.
|
|
24
25
|
import { archiveRawMemory } from './raw-archive.js';
|
|
26
|
+
import { insertDormantRow } from './dormant.js';
|
|
25
27
|
/**
|
|
26
28
|
* Emit an audit event for a mutation against `db`. Wrapped so a broken audit
|
|
27
29
|
* log can never crash the surrounding mutation — the SQLite store is still the
|
|
@@ -118,11 +120,27 @@ export function initStore(hippoRoot) {
|
|
|
118
120
|
if (bootstrapped) {
|
|
119
121
|
syncMirrorFiles(hippoRoot, db);
|
|
120
122
|
}
|
|
123
|
+
recordHalfLifeBaseForNewStore(db);
|
|
121
124
|
}
|
|
122
125
|
finally {
|
|
123
126
|
closeHippoDb(db);
|
|
124
127
|
}
|
|
125
128
|
}
|
|
129
|
+
/** `meta` key holding the default half-life base a store's memories are on (src/half-life-migration.ts). */
|
|
130
|
+
export const HALF_LIFE_BASE_META_KEY = 'default_half_life_base';
|
|
131
|
+
/**
|
|
132
|
+
* A store with no memories starts on the current default half-life base, so
|
|
133
|
+
* `hippo sleep` never migrates it. A store that already holds memories and
|
|
134
|
+
* no recorded base predates the record, and keeps reading as the legacy
|
|
135
|
+
* 7-day base until sleep migrates it.
|
|
136
|
+
*/
|
|
137
|
+
function recordHalfLifeBaseForNewStore(db) {
|
|
138
|
+
if (getMeta(db, HALF_LIFE_BASE_META_KEY, '') !== '')
|
|
139
|
+
return;
|
|
140
|
+
if (db.prepare(`SELECT 1 AS x FROM memories LIMIT 1`).get() !== undefined)
|
|
141
|
+
return;
|
|
142
|
+
setMeta(db, HALF_LIFE_BASE_META_KEY, String(DEFAULT_HALF_LIFE_DAYS));
|
|
143
|
+
}
|
|
126
144
|
function ensureMirrorDirectories(hippoRoot) {
|
|
127
145
|
const dirs = [
|
|
128
146
|
hippoRoot,
|
|
@@ -504,7 +522,7 @@ function canonicalConflictPair(aId, bId) {
|
|
|
504
522
|
? { memory_a_id: aId, memory_b_id: bId }
|
|
505
523
|
: { memory_a_id: bId, memory_b_id: aId };
|
|
506
524
|
}
|
|
507
|
-
function loadSearchRows(db, query, limit, tenantId, scopeFilter) {
|
|
525
|
+
function loadSearchRows(db, query, limit, tenantId, scopeFilter, includeSuperseded = true) {
|
|
508
526
|
// tenantId undefined = no tenant filter (legacy callers / cross-deployment
|
|
509
527
|
// helpers). tenantId set = strict tenant isolation, leveraging the composite
|
|
510
528
|
// idx_memories_tenant_created (leading column tenant_id, O(log n) lookup).
|
|
@@ -597,13 +615,15 @@ function loadSearchRows(db, query, limit, tenantId, scopeFilter) {
|
|
|
597
615
|
scopeParams.push(scopeFilter.value);
|
|
598
616
|
}
|
|
599
617
|
}
|
|
618
|
+
const currentAlias = includeSuperseded ? '' : ' AND m.superseded_by IS NULL';
|
|
619
|
+
const currentNoAlias = includeSuperseded ? '' : ' AND superseded_by IS NULL';
|
|
600
620
|
const terms = Array.from(new Set(tokenize(query)));
|
|
601
621
|
if (terms.length === 0) {
|
|
602
622
|
// F3 (v1.7.0) self-review: empty-query path is the second uncapped
|
|
603
623
|
// path (codex diff-pass caught the full-store fallback at the bottom;
|
|
604
624
|
// this no-terms path had the same shape). Apply LIMIT so all four
|
|
605
625
|
// candidate paths honour the caller's cap when set.
|
|
606
|
-
const sql = `SELECT ${MEMORY_SELECT_COLUMNS} FROM memories${tenantOnlyPredicate}${archivedClauseTenantOnly}${scopeClauseTenantOnly} ORDER BY created ASC, id ASC LIMIT ?`;
|
|
626
|
+
const sql = `SELECT ${MEMORY_SELECT_COLUMNS} FROM memories${tenantOnlyPredicate}${archivedClauseTenantOnly}${scopeClauseTenantOnly}${currentNoAlias} ORDER BY created ASC, id ASC LIMIT ?`;
|
|
607
627
|
// SAFETY: sql selects exactly MEMORY_SELECT_COLUMNS, whose column list
|
|
608
628
|
// matches MemoryRow's field set.
|
|
609
629
|
return db.prepare(sql).all(...tenantParams, ...scopeParams, limit);
|
|
@@ -630,7 +650,7 @@ function loadSearchRows(db, query, limit, tenantId, scopeFilter) {
|
|
|
630
650
|
SELECT ${MEMORY_SEARCH_COLUMNS}
|
|
631
651
|
FROM memories m
|
|
632
652
|
JOIN memories_fts f ON f.id = m.id
|
|
633
|
-
WHERE memories_fts MATCH ?${tenantPredicate}${archivedClauseAlias}${scopeClauseAlias}
|
|
653
|
+
WHERE memories_fts MATCH ?${tenantPredicate}${archivedClauseAlias}${scopeClauseAlias}${currentAlias}
|
|
634
654
|
ORDER BY bm25(memories_fts), m.updated_at DESC, m.content ASC, m.id ASC
|
|
635
655
|
LIMIT ?
|
|
636
656
|
`).all(ftsQuery, ...tenantParams, ...scopeParams, limit);
|
|
@@ -652,7 +672,7 @@ function loadSearchRows(db, query, limit, tenantId, scopeFilter) {
|
|
|
652
672
|
const rows = db.prepare(`
|
|
653
673
|
SELECT ${MEMORY_SELECT_COLUMNS}
|
|
654
674
|
FROM memories
|
|
655
|
-
WHERE (${where})${tenantPredicateNoAlias}${archivedClauseNoAlias}${scopeClauseNoAlias}
|
|
675
|
+
WHERE (${where})${tenantPredicateNoAlias}${archivedClauseNoAlias}${scopeClauseNoAlias}${currentNoAlias}
|
|
656
676
|
ORDER BY updated_at DESC, created DESC, content ASC, id ASC
|
|
657
677
|
LIMIT ?
|
|
658
678
|
`).all(...params, ...tenantParams, ...scopeParams, limit);
|
|
@@ -663,7 +683,7 @@ function loadSearchRows(db, query, limit, tenantId, scopeFilter) {
|
|
|
663
683
|
// now reported on RecallResult, an unbounded fallback would lie about
|
|
664
684
|
// candidate-pool size. Apply LIMIT here so all four paths honour the
|
|
665
685
|
// caller's cap.
|
|
666
|
-
const fallback = `SELECT ${MEMORY_SELECT_COLUMNS} FROM memories${tenantOnlyPredicate}${archivedClauseTenantOnly}${scopeClauseTenantOnly} ORDER BY created ASC, id ASC LIMIT ?`;
|
|
686
|
+
const fallback = `SELECT ${MEMORY_SELECT_COLUMNS} FROM memories${tenantOnlyPredicate}${archivedClauseTenantOnly}${scopeClauseTenantOnly}${currentNoAlias} ORDER BY created ASC, id ASC LIMIT ?`;
|
|
667
687
|
// SAFETY: fallback selects exactly MEMORY_SELECT_COLUMNS, matching
|
|
668
688
|
// MemoryRow's field set.
|
|
669
689
|
return db.prepare(fallback).all(...tenantParams, ...scopeParams, limit);
|
|
@@ -1064,18 +1084,28 @@ function buildStatsFromDb(db) {
|
|
|
1064
1084
|
* `buildIndexFromDb`'s query.
|
|
1065
1085
|
*/
|
|
1066
1086
|
export function writeIndexMirror(hippoRoot, index) {
|
|
1067
|
-
fs.writeFileSync(path.join(hippoRoot, 'index.json'), JSON.stringify(index, null, 2), 'utf8');
|
|
1087
|
+
mirrorBestEffort('index.json', () => fs.writeFileSync(path.join(hippoRoot, 'index.json'), JSON.stringify(index, null, 2), 'utf8'));
|
|
1068
1088
|
}
|
|
1069
1089
|
function writeStatsMirror(hippoRoot, stats) {
|
|
1070
|
-
fs.writeFileSync(path.join(hippoRoot, 'stats.json'), JSON.stringify(stats, null, 2), 'utf8');
|
|
1090
|
+
mirrorBestEffort('stats.json', () => fs.writeFileSync(path.join(hippoRoot, 'stats.json'), JSON.stringify(stats, null, 2), 'utf8'));
|
|
1091
|
+
}
|
|
1092
|
+
/** Mirrors are derived from SQLite and written after COMMIT, so a failed write warns instead of failing a committed change. */
|
|
1093
|
+
function mirrorBestEffort(what, write) {
|
|
1094
|
+
try {
|
|
1095
|
+
write();
|
|
1096
|
+
}
|
|
1097
|
+
catch (err) {
|
|
1098
|
+
console.error(`hippo: ${what} not refreshed (${err instanceof Error ? err.message : String(err)}); the database write succeeded`);
|
|
1099
|
+
}
|
|
1071
1100
|
}
|
|
1072
1101
|
function syncMirrorFiles(hippoRoot, db) {
|
|
1073
1102
|
// SAFETY: this query selects exactly MEMORY_SELECT_COLUMNS, matching
|
|
1074
1103
|
// MemoryRow's field set.
|
|
1075
1104
|
const entries = db.prepare(`SELECT ${MEMORY_SELECT_COLUMNS} FROM memories ORDER BY created ASC, id ASC`).all();
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1105
|
+
mirrorBestEffort('markdown mirrors', () => {
|
|
1106
|
+
for (const entry of entries.map(rowToEntry))
|
|
1107
|
+
writeMarkdownMirror(hippoRoot, entry);
|
|
1108
|
+
});
|
|
1079
1109
|
// SAFETY: conflicts' shape matches the eight columns named in the SELECT
|
|
1080
1110
|
// above.
|
|
1081
1111
|
const conflicts = db.prepare(`
|
|
@@ -1084,20 +1114,16 @@ function syncMirrorFiles(hippoRoot, db) {
|
|
|
1084
1114
|
WHERE status = 'open'
|
|
1085
1115
|
ORDER BY updated_at DESC, id DESC
|
|
1086
1116
|
`).all();
|
|
1087
|
-
writeConflictMirrors(hippoRoot, conflicts.map(rowToMemoryConflict));
|
|
1117
|
+
mirrorBestEffort('conflict mirrors', () => writeConflictMirrors(hippoRoot, conflicts.map(rowToMemoryConflict)));
|
|
1088
1118
|
writeIndexMirror(hippoRoot, buildIndexFromDb(db));
|
|
1089
1119
|
writeStatsMirror(hippoRoot, buildStatsFromDb(db));
|
|
1090
1120
|
}
|
|
1091
|
-
/**
|
|
1092
|
-
* Load the current derived index from SQLite and refresh the mirror file.
|
|
1093
|
-
*/
|
|
1121
|
+
/** Load the derived index from SQLite. Read-only: writers refresh index.json, so readers never race on it. */
|
|
1094
1122
|
export function loadIndex(hippoRoot) {
|
|
1095
1123
|
initStore(hippoRoot);
|
|
1096
1124
|
const db = openHippoDb(hippoRoot);
|
|
1097
1125
|
try {
|
|
1098
|
-
|
|
1099
|
-
writeIndexMirror(hippoRoot, index);
|
|
1100
|
-
return index;
|
|
1126
|
+
return buildIndexFromDb(db);
|
|
1101
1127
|
}
|
|
1102
1128
|
finally {
|
|
1103
1129
|
closeHippoDb(db);
|
|
@@ -1267,7 +1293,7 @@ export function writeEntryDbOnly(db, entry, opts) {
|
|
|
1267
1293
|
* during a tx that subsequently rolls back would leave orphan markdown.
|
|
1268
1294
|
*/
|
|
1269
1295
|
export function writeEntryMirrors(hippoRoot, db, entry) {
|
|
1270
|
-
writeMarkdownMirror(hippoRoot, entry);
|
|
1296
|
+
mirrorBestEffort(`${entry.id}.md`, () => writeMarkdownMirror(hippoRoot, entry));
|
|
1271
1297
|
writeIndexMirror(hippoRoot, buildIndexFromDb(db));
|
|
1272
1298
|
}
|
|
1273
1299
|
/**
|
|
@@ -1320,6 +1346,46 @@ export function loadEntriesByIds(hippoRoot, ids, tenantId) {
|
|
|
1320
1346
|
closeHippoDb(db);
|
|
1321
1347
|
}
|
|
1322
1348
|
}
|
|
1349
|
+
/** Strengthen what a read returned: update only the four retrieval columns on the live row, never a stale copy.
|
|
1350
|
+
* Best effort: a failure logs and never fails the read. Returns the ids found in this store. */
|
|
1351
|
+
export function strengthenRetrieved(hippoRoot, ids, tenantId) {
|
|
1352
|
+
const found = new Set();
|
|
1353
|
+
if (ids.length === 0 || isRecallBoostAblated())
|
|
1354
|
+
return found;
|
|
1355
|
+
let db;
|
|
1356
|
+
try {
|
|
1357
|
+
db = openHippoDb(hippoRoot);
|
|
1358
|
+
db.exec('BEGIN IMMEDIATE');
|
|
1359
|
+
const tenantClause = tenantId !== undefined ? ' AND tenant_id = ?' : '';
|
|
1360
|
+
const select = db.prepare(`SELECT ${MEMORY_SELECT_COLUMNS} FROM memories WHERE id = ?${tenantClause}`);
|
|
1361
|
+
const live = [];
|
|
1362
|
+
for (const id of ids) {
|
|
1363
|
+
// SAFETY: the SELECT names exactly MEMORY_SELECT_COLUMNS, matching MemoryRow's field set.
|
|
1364
|
+
const row = (tenantId !== undefined ? select.get(id, tenantId) : select.get(id));
|
|
1365
|
+
if (row)
|
|
1366
|
+
live.push(rowToEntry(row));
|
|
1367
|
+
}
|
|
1368
|
+
const update = db.prepare('UPDATE memories SET retrieval_count = ?, last_retrieved = ?, half_life_days = ?, strength = ? WHERE id = ?');
|
|
1369
|
+
for (const e of markRetrieved(live)) {
|
|
1370
|
+
update.run(e.retrieval_count, e.last_retrieved, e.half_life_days, e.strength, e.id);
|
|
1371
|
+
found.add(e.id);
|
|
1372
|
+
}
|
|
1373
|
+
db.exec('COMMIT');
|
|
1374
|
+
}
|
|
1375
|
+
catch (error) {
|
|
1376
|
+
try {
|
|
1377
|
+
db?.exec('ROLLBACK');
|
|
1378
|
+
}
|
|
1379
|
+
catch { /* already rolled back; keep the original error */ }
|
|
1380
|
+
console.error(`hippo: retrieval stats not saved (${error instanceof Error ? error.message : String(error)})`);
|
|
1381
|
+
found.clear();
|
|
1382
|
+
}
|
|
1383
|
+
finally {
|
|
1384
|
+
if (db)
|
|
1385
|
+
closeHippoDb(db);
|
|
1386
|
+
}
|
|
1387
|
+
return found;
|
|
1388
|
+
}
|
|
1323
1389
|
/**
|
|
1324
1390
|
* All `kind='raw'` rows for a given session, tenant-scoped, returned
|
|
1325
1391
|
* oldest-first. Used by `api.assemble` to walk a session's chronological
|
|
@@ -1499,8 +1565,8 @@ export function loadChildrenOf(hippoRoot, parentId, tenantId) {
|
|
|
1499
1565
|
* removed) and `resolveConflict` (`conflict_resolve` row per resolution).
|
|
1500
1566
|
* Default keeps `deleteEntry` byte-identical to its pre-split behavior.
|
|
1501
1567
|
*
|
|
1502
|
-
* Returns `{tenantId, dagParentId}` for the removed row, or `null` if no row
|
|
1503
|
-
*
|
|
1568
|
+
* Returns `{tenantId, dagParentId}` for the removed row, or `null` if no row with `id`
|
|
1569
|
+
* existed or `automatic` refused it (pinned or raw at DELETE time, so a late pin wins).
|
|
1504
1570
|
*/
|
|
1505
1571
|
export function deleteEntryCore(db, id, opts) {
|
|
1506
1572
|
// SAFETY: row's shape matches the three columns named in the SELECT above.
|
|
@@ -1509,10 +1575,12 @@ export function deleteEntryCore(db, id, opts) {
|
|
|
1509
1575
|
.get(id);
|
|
1510
1576
|
if (!row?.id)
|
|
1511
1577
|
return null;
|
|
1512
|
-
|
|
1578
|
+
const guard = opts?.automatic ? ` AND ${AUTO_DELETABLE_SQL}` : '';
|
|
1579
|
+
if (Number(db.prepare(`DELETE FROM memories WHERE id = ?${guard}`).run(id).changes ?? 0) === 0)
|
|
1580
|
+
return null;
|
|
1513
1581
|
deleteFtsRow(db, id);
|
|
1514
1582
|
if (!opts?.suppressForgetAudit) {
|
|
1515
|
-
audit(db, 'forget', id, undefined, opts?.actor ?? 'cli', row.tenant_id);
|
|
1583
|
+
audit(db, 'forget', id, opts?.reason ? { reason: opts.reason } : undefined, opts?.actor ?? 'cli', row.tenant_id);
|
|
1516
1584
|
}
|
|
1517
1585
|
// v0.30 / E2 — DAG live-coupling: forget of a child under a level-2
|
|
1518
1586
|
// summary marks parent dirty. Non-atomic with the DELETE (no SAVEPOINT
|
|
@@ -1542,7 +1610,7 @@ export function deleteEntry(hippoRoot, id, opts) {
|
|
|
1542
1610
|
const result = deleteEntryCore(db, id, opts);
|
|
1543
1611
|
if (!result)
|
|
1544
1612
|
return false;
|
|
1545
|
-
|
|
1613
|
+
purgeMirrorBestEffort(hippoRoot, id, false, 'deleteEntry');
|
|
1546
1614
|
writeIndexMirror(hippoRoot, buildIndexFromDb(db));
|
|
1547
1615
|
return true;
|
|
1548
1616
|
}
|
|
@@ -1550,13 +1618,28 @@ export function deleteEntry(hippoRoot, id, opts) {
|
|
|
1550
1618
|
closeHippoDb(db);
|
|
1551
1619
|
}
|
|
1552
1620
|
}
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1621
|
+
// The child fields a level-2/3 summary is built from (loadChildrenOfSummary, generateDagSummary).
|
|
1622
|
+
const SUMMARY_INPUTS = ['content', 'created', 'dag_parent_id', 'kind'];
|
|
1623
|
+
function mergeOwnChanges(base, ours, live) {
|
|
1624
|
+
const row = { ...live };
|
|
1625
|
+
const loaded = new Map(Object.entries(base));
|
|
1626
|
+
for (const [key, value] of Object.entries(ours)) {
|
|
1627
|
+
if (JSON.stringify(value) !== JSON.stringify(loaded.get(key)))
|
|
1628
|
+
Object.assign(row, { [key]: value });
|
|
1629
|
+
}
|
|
1630
|
+
return row;
|
|
1631
|
+
}
|
|
1632
|
+
/** Consolidation's flush, one transaction. With `snapshot` (rows as the caller loaded them), a write keeps only
|
|
1633
|
+
* the fields the caller changed, takes the rest from the live row, and never resurrects a row that is gone.
|
|
1634
|
+
*
|
|
1635
|
+
* `dormant` (src/dormant.ts): each move's snapshot is inserted into `dormant_memories` and its `memories` row
|
|
1636
|
+
* leaves exactly like a delete (FTS row, DAG parent dirty-mark, mirrors), in the same transaction, so a memory
|
|
1637
|
+
* is never in both places or in neither. Deletes and moves both skip rows that are no longer auto-deletable
|
|
1638
|
+
* (pinned or raw since the caller decided). Returns the ids that left `memories`, deleted or moved. */
|
|
1639
|
+
export function batchWriteAndDelete(hippoRoot, toWrite, toDeleteIds, opts) {
|
|
1640
|
+
const dormantMoves = opts?.dormant ?? [];
|
|
1641
|
+
if (toWrite.length === 0 && toDeleteIds.length === 0 && dormantMoves.length === 0)
|
|
1642
|
+
return [];
|
|
1560
1643
|
initStore(hippoRoot);
|
|
1561
1644
|
const db = openHippoDb(hippoRoot);
|
|
1562
1645
|
try {
|
|
@@ -1576,23 +1659,23 @@ export function batchWriteAndDelete(hippoRoot, toWrite, toDeleteIds) {
|
|
|
1576
1659
|
// dirty for the dominant mutation source (decay, merge, garbage-collect).
|
|
1577
1660
|
const dirtyParents = new Set();
|
|
1578
1661
|
const tenantById = new Map();
|
|
1662
|
+
const deletableIds = [];
|
|
1579
1663
|
if (toDeleteIds.length > 0) {
|
|
1580
1664
|
const placeholders = toDeleteIds.map(() => '?').join(',');
|
|
1581
|
-
//
|
|
1582
|
-
//
|
|
1583
|
-
const rows = db.prepare(`SELECT dag_parent_id, tenant_id FROM memories WHERE id IN (${placeholders})`).all(...toDeleteIds);
|
|
1665
|
+
// A row pinned after the caller decided to delete it survives.
|
|
1666
|
+
// SAFETY: rows' shape matches the three columns named in the SELECT.
|
|
1667
|
+
const rows = db.prepare(`SELECT id, dag_parent_id, tenant_id FROM memories WHERE id IN (${placeholders}) AND ${AUTO_DELETABLE_SQL}`).all(...toDeleteIds);
|
|
1584
1668
|
for (const row of rows) {
|
|
1669
|
+
deletableIds.push(row.id);
|
|
1585
1670
|
if (row.dag_parent_id) {
|
|
1586
1671
|
dirtyParents.add(row.dag_parent_id);
|
|
1587
1672
|
tenantById.set(row.dag_parent_id, row.tenant_id ?? 'default');
|
|
1588
1673
|
}
|
|
1589
1674
|
}
|
|
1590
1675
|
}
|
|
1591
|
-
// v39:
|
|
1592
|
-
//
|
|
1593
|
-
|
|
1594
|
-
// context (codex gating review P1).
|
|
1595
|
-
const stampedWrites = toWrite.map((e) => stampOriginProject(hippoRoot, e));
|
|
1676
|
+
// v39: batch writers bypass writeEntry, so stamp store-derived origins here too (a NULL origin hides new
|
|
1677
|
+
// memories from ambient context). A row queued twice keeps only its last version, the one the merge compares.
|
|
1678
|
+
const stampedWrites = [...new Map(toWrite.map((e) => [e.id, stampOriginProject(hippoRoot, e)])).values()];
|
|
1596
1679
|
// AT1 P1 fix (codex, batch-transaction rejection race): the producer-side
|
|
1597
1680
|
// check (e.g. consolidate.ts's merge pass) runs BEFORE this transaction,
|
|
1598
1681
|
// on a different connection. A `hippo reject X` that commits in that
|
|
@@ -1611,9 +1694,15 @@ export function batchWriteAndDelete(hippoRoot, toWrite, toDeleteIds) {
|
|
|
1611
1694
|
// demotion/replay re-persist of a rejected-removed row means it stays
|
|
1612
1695
|
// gone, which is the entire point of the tombstone.
|
|
1613
1696
|
let batchRejectedSkips = 0;
|
|
1614
|
-
const
|
|
1697
|
+
const written = [];
|
|
1698
|
+
const readLiveRow = db.prepare(`SELECT ${MEMORY_SELECT_COLUMNS} FROM memories WHERE id = ?`);
|
|
1615
1699
|
for (const entry of stampedWrites) {
|
|
1616
|
-
const
|
|
1700
|
+
const base = opts?.snapshot?.get(entry.id);
|
|
1701
|
+
// SAFETY: MEMORY_SELECT_COLUMNS is the MemoryRow shape rowToEntry reads.
|
|
1702
|
+
const liveRow = readLiveRow.get(entry.id);
|
|
1703
|
+
const live = liveRow ? rowToEntry(liveRow) : undefined;
|
|
1704
|
+
const row = base && live ? mergeOwnChanges(base, entry, live) : entry;
|
|
1705
|
+
const entryTenantId = row.tenantId ?? 'default';
|
|
1617
1706
|
// Codex delta-review P2 fix: reuse checkRejectionGuard rather than a
|
|
1618
1707
|
// bare tombstone probe — the guard's content-INTRODUCTION
|
|
1619
1708
|
// classification must apply here too. A tombstone can legitimately
|
|
@@ -1624,17 +1713,19 @@ export function batchWriteAndDelete(hippoRoot, toWrite, toDeleteIds) {
|
|
|
1624
1713
|
// changes content TO the rejected value; unchanged same-id re-persists
|
|
1625
1714
|
// pass through, exactly as on the writeEntry path.
|
|
1626
1715
|
try {
|
|
1627
|
-
checkRejectionGuard(db, entryTenantId,
|
|
1716
|
+
checkRejectionGuard(db, entryTenantId, row.id, row.content);
|
|
1628
1717
|
}
|
|
1629
1718
|
catch (err) {
|
|
1630
1719
|
if (err instanceof RejectedValueError) {
|
|
1631
1720
|
batchRejectedSkips++;
|
|
1632
|
-
|
|
1633
|
-
audit(db, 'reject_refusal', entry.id, { digest: err.digest, reason: err.reason }, 'sleep-batch', entryTenantId);
|
|
1721
|
+
audit(db, 'reject_refusal', row.id, { digest: err.digest, reason: err.reason }, 'sleep-batch', entryTenantId);
|
|
1634
1722
|
continue;
|
|
1635
1723
|
}
|
|
1636
1724
|
throw err;
|
|
1637
1725
|
}
|
|
1726
|
+
if (base && !live)
|
|
1727
|
+
continue;
|
|
1728
|
+
written.push(row);
|
|
1638
1729
|
// AT1 (plan §3, corrected): bypass the rejection guard here.
|
|
1639
1730
|
// Consolidation merges are DETERMINISTIC CONCATENATION (mergeContents,
|
|
1640
1731
|
// consolidate.ts:736-751) of already-guarded leaf facts, not an LLM
|
|
@@ -1647,14 +1738,33 @@ export function batchWriteAndDelete(hippoRoot, toWrite, toDeleteIds) {
|
|
|
1647
1738
|
// check and this COMMIT. The guard itself still belongs on leaf
|
|
1648
1739
|
// inserts, which write through writeEntry / writeEntryDbOnly and stay
|
|
1649
1740
|
// guarded (bypassRejectionGuard defaults false).
|
|
1650
|
-
upsertEntryRow(db,
|
|
1651
|
-
// Hook for writes: child
|
|
1652
|
-
if (
|
|
1653
|
-
dirtyParents.add(
|
|
1654
|
-
tenantById.set(
|
|
1741
|
+
upsertEntryRow(db, row, true);
|
|
1742
|
+
// Hook for writes: a new child, or a change to what its summary reads, marks the parent dirty; decay alone does not.
|
|
1743
|
+
if (row.dag_parent_id && (!live || SUMMARY_INPUTS.some((k) => row[k] !== live[k]))) {
|
|
1744
|
+
dirtyParents.add(row.dag_parent_id);
|
|
1745
|
+
tenantById.set(row.dag_parent_id, row.tenantId);
|
|
1655
1746
|
}
|
|
1656
1747
|
}
|
|
1657
|
-
|
|
1748
|
+
// Dormant moves: same eligibility and DAG bookkeeping as deletes.
|
|
1749
|
+
const movable = [];
|
|
1750
|
+
if (dormantMoves.length > 0) {
|
|
1751
|
+
const byId = new Map(dormantMoves.map((m) => [m.entry.id, m]));
|
|
1752
|
+
const placeholders = dormantMoves.map(() => '?').join(',');
|
|
1753
|
+
// SAFETY: rows' shape matches the three columns named in the SELECT.
|
|
1754
|
+
const rows = db.prepare(`SELECT id, dag_parent_id, tenant_id FROM memories WHERE id IN (${placeholders}) AND ${AUTO_DELETABLE_SQL}`).all(...byId.keys());
|
|
1755
|
+
for (const row of rows) {
|
|
1756
|
+
movable.push(byId.get(row.id));
|
|
1757
|
+
if (row.dag_parent_id) {
|
|
1758
|
+
dirtyParents.add(row.dag_parent_id);
|
|
1759
|
+
tenantById.set(row.dag_parent_id, row.tenant_id ?? 'default');
|
|
1760
|
+
}
|
|
1761
|
+
}
|
|
1762
|
+
}
|
|
1763
|
+
for (const move of movable) {
|
|
1764
|
+
insertDormantRow(db, move);
|
|
1765
|
+
}
|
|
1766
|
+
const removedIds = [...deletableIds, ...movable.map((m) => m.entry.id)];
|
|
1767
|
+
for (const id of removedIds) {
|
|
1658
1768
|
db.prepare('DELETE FROM memories WHERE id = ?').run(id);
|
|
1659
1769
|
deleteFtsRow(db, id);
|
|
1660
1770
|
}
|
|
@@ -1670,15 +1780,14 @@ export function batchWriteAndDelete(hippoRoot, toWrite, toDeleteIds) {
|
|
|
1670
1780
|
// Sync mirrors once after all DB writes. Entries skipped above were
|
|
1671
1781
|
// never inserted — writing their markdown mirror would resurrect the
|
|
1672
1782
|
// exact content the skip just kept out of the DB.
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
removeEntryMirrors(hippoRoot, id);
|
|
1680
|
-
}
|
|
1783
|
+
mirrorBestEffort('markdown mirrors', () => {
|
|
1784
|
+
for (const entry of written)
|
|
1785
|
+
writeMarkdownMirror(hippoRoot, entry);
|
|
1786
|
+
});
|
|
1787
|
+
for (const id of removedIds)
|
|
1788
|
+
purgeMirrorBestEffort(hippoRoot, id, false, 'batchWriteAndDelete');
|
|
1681
1789
|
writeIndexMirror(hippoRoot, buildIndexFromDb(db));
|
|
1790
|
+
return removedIds;
|
|
1682
1791
|
}
|
|
1683
1792
|
catch (error) {
|
|
1684
1793
|
try {
|
|
@@ -1702,17 +1811,21 @@ export function loadAllEntries(hippoRoot, tenantId) {
|
|
|
1702
1811
|
initStore(hippoRoot);
|
|
1703
1812
|
const db = openHippoDb(hippoRoot);
|
|
1704
1813
|
try {
|
|
1705
|
-
|
|
1706
|
-
// MemoryRow's field set.
|
|
1707
|
-
const rows = tenantId !== undefined
|
|
1708
|
-
? db.prepare(`SELECT ${MEMORY_SELECT_COLUMNS} FROM memories WHERE tenant_id = ? ORDER BY created ASC, id ASC`).all(tenantId)
|
|
1709
|
-
: db.prepare(`SELECT ${MEMORY_SELECT_COLUMNS} FROM memories ORDER BY created ASC, id ASC`).all();
|
|
1710
|
-
return rows.map(rowToEntry);
|
|
1814
|
+
return selectAllEntries(db, tenantId);
|
|
1711
1815
|
}
|
|
1712
1816
|
finally {
|
|
1713
1817
|
closeHippoDb(db);
|
|
1714
1818
|
}
|
|
1715
1819
|
}
|
|
1820
|
+
/** Every memory row on an open connection, so a caller can read inside its own transaction. */
|
|
1821
|
+
export function selectAllEntries(db, tenantId) {
|
|
1822
|
+
// SAFETY: both branches select exactly MEMORY_SELECT_COLUMNS, matching
|
|
1823
|
+
// MemoryRow's field set.
|
|
1824
|
+
const rows = tenantId !== undefined
|
|
1825
|
+
? db.prepare(`SELECT ${MEMORY_SELECT_COLUMNS} FROM memories WHERE tenant_id = ? ORDER BY created ASC, id ASC`).all(tenantId)
|
|
1826
|
+
: db.prepare(`SELECT ${MEMORY_SELECT_COLUMNS} FROM memories ORDER BY created ASC, id ASC`).all();
|
|
1827
|
+
return rows.map(rowToEntry);
|
|
1828
|
+
}
|
|
1716
1829
|
// The pins plus the `recentNeeded` newest rows that pass `admit`, for ambient
|
|
1717
1830
|
// injection. One connection: opening one costs ~5.8ms on a warm 1896-row store,
|
|
1718
1831
|
// so a second handle loses more than the narrower scan saves.
|
|
@@ -1799,7 +1912,7 @@ export function loadSearchEntries(hippoRoot, query, limit = DEFAULT_SEARCH_CANDI
|
|
|
1799
1912
|
* mode (its `tenantId` option is optional); `loadSearchRows` already treats
|
|
1800
1913
|
* undefined as "no tenant filter" for legacy callers.
|
|
1801
1914
|
*/
|
|
1802
|
-
export function loadRecallSearchEntries(hippoRoot, query, limit = DEFAULT_SEARCH_CANDIDATE_LIMIT, tenantId, requestedScope, explicitScopeMode = 'exact') {
|
|
1915
|
+
export function loadRecallSearchEntries(hippoRoot, query, limit = DEFAULT_SEARCH_CANDIDATE_LIMIT, tenantId, requestedScope, explicitScopeMode = 'exact', includeSuperseded = true) {
|
|
1803
1916
|
initStore(hippoRoot);
|
|
1804
1917
|
const db = openHippoDb(hippoRoot);
|
|
1805
1918
|
try {
|
|
@@ -1812,7 +1925,7 @@ export function loadRecallSearchEntries(hippoRoot, query, limit = DEFAULT_SEARCH
|
|
|
1812
1925
|
? { mode: 'default-deny-or-exact', value: requestedScope }
|
|
1813
1926
|
: { mode: 'exact', value: requestedScope }
|
|
1814
1927
|
: { mode: 'default-deny' };
|
|
1815
|
-
return loadSearchRows(db, query, limit, tenantId, scopeFilter).map(rowToEntry);
|
|
1928
|
+
return loadSearchRows(db, query, limit, tenantId, scopeFilter, includeSuperseded).map(rowToEntry);
|
|
1816
1929
|
}
|
|
1817
1930
|
finally {
|
|
1818
1931
|
closeHippoDb(db);
|
|
@@ -1903,9 +2016,7 @@ export function loadStats(hippoRoot) {
|
|
|
1903
2016
|
initStore(hippoRoot);
|
|
1904
2017
|
const db = openHippoDb(hippoRoot);
|
|
1905
2018
|
try {
|
|
1906
|
-
|
|
1907
|
-
writeStatsMirror(hippoRoot, stats);
|
|
1908
|
-
return stats;
|
|
2019
|
+
return buildStatsFromDb(db);
|
|
1909
2020
|
}
|
|
1910
2021
|
finally {
|
|
1911
2022
|
closeHippoDb(db);
|
|
@@ -1923,6 +2034,20 @@ export function appendConsolidationRun(hippoRoot, run) {
|
|
|
1923
2034
|
closeHippoDb(db);
|
|
1924
2035
|
}
|
|
1925
2036
|
}
|
|
2037
|
+
/** Rows a tenant created since the last sleep (runs are host-wide), looking back at most 24 hours. */
|
|
2038
|
+
export function countCreatedSinceLastSleep(hippoRoot, tenantId, now = new Date()) {
|
|
2039
|
+
initStore(hippoRoot);
|
|
2040
|
+
const db = openHippoDb(hippoRoot);
|
|
2041
|
+
try {
|
|
2042
|
+
const dayAgo = new Date(now.getTime() - 86_400_000).toISOString();
|
|
2043
|
+
const row = db.prepare(`SELECT COUNT(*) AS n FROM memories WHERE tenant_id = ?
|
|
2044
|
+
AND created > MAX(?, COALESCE((SELECT MAX(timestamp) FROM consolidation_runs), ''))`).get(tenantId, dayAgo);
|
|
2045
|
+
return row.n;
|
|
2046
|
+
}
|
|
2047
|
+
finally {
|
|
2048
|
+
closeHippoDb(db);
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
1926
2051
|
/**
|
|
1927
2052
|
* Load the session decay context from the store.
|
|
1928
2053
|
* Uses consolidation_runs timestamps to compute session intervals.
|
|
@@ -3492,6 +3617,7 @@ export function loadAllL2Summaries(hippoRoot) {
|
|
|
3492
3617
|
WHERE dag_level = 2
|
|
3493
3618
|
AND dag_parent_id IS NULL
|
|
3494
3619
|
AND kind != 'archived'
|
|
3620
|
+
AND superseded_by IS NULL
|
|
3495
3621
|
ORDER BY created ASC, id ASC
|
|
3496
3622
|
`).all();
|
|
3497
3623
|
return rows.map(rowToEntry);
|
|
@@ -3548,6 +3674,7 @@ export function loadChildrenOfSummary(hippoRoot, summaryId, tenantId) {
|
|
|
3548
3674
|
WHERE dag_parent_id = ?
|
|
3549
3675
|
AND tenant_id = ?
|
|
3550
3676
|
AND kind != 'archived'
|
|
3677
|
+
AND superseded_by IS NULL
|
|
3551
3678
|
ORDER BY created ASC
|
|
3552
3679
|
`).all(summaryId, tenantId);
|
|
3553
3680
|
return rows.map(rowToEntry);
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import type { DatabaseSyncLike } from './db.js';
|
|
2
|
+
/**
|
|
3
|
+
* Where a block of memory text was sent.
|
|
4
|
+
* - `hook`: the per-prompt `UserPromptSubmit` hook (`hippo context --pinned-only`).
|
|
5
|
+
* - `context`, `recall`: the CLI commands.
|
|
6
|
+
* - `mcp_recall`, `mcp_context`: the MCP tools.
|
|
7
|
+
* - `http_recall`, `http_context`, `http_assemble`: the HTTP API.
|
|
8
|
+
*/
|
|
9
|
+
export type TokenSurface = 'hook' | 'context' | 'recall' | 'mcp_recall' | 'mcp_context' | 'http_recall' | 'http_context' | 'http_assemble';
|
|
10
|
+
/** All surfaces, in report order. */
|
|
11
|
+
export declare const TOKEN_SURFACES: readonly TokenSurface[];
|
|
12
|
+
/**
|
|
13
|
+
* What happened to a block.
|
|
14
|
+
* - `inject`: sent to the agent.
|
|
15
|
+
* - `skip`: identical to the session's last injected block, so not sent again.
|
|
16
|
+
* - `reset`: the host compacted its context, so the next block must be sent.
|
|
17
|
+
*/
|
|
18
|
+
export type TokenEvent = 'inject' | 'skip' | 'reset';
|
|
19
|
+
/** Rows older than this are pruned on write. */
|
|
20
|
+
export declare const TOKEN_LEDGER_RETENTION_DAYS = 90;
|
|
21
|
+
/**
|
|
22
|
+
* Rough token estimate: characters / 4. The single estimate behind every
|
|
23
|
+
* token budget and ledger count in hippo.
|
|
24
|
+
*/
|
|
25
|
+
export declare function estimateTokens(text: string): number;
|
|
26
|
+
/** Stable 16-hex-char hash of a rendered block, for change detection. */
|
|
27
|
+
export declare function blockHash(text: string): string;
|
|
28
|
+
/** One ledger write. */
|
|
29
|
+
export interface TokenUse {
|
|
30
|
+
tenantId: string;
|
|
31
|
+
/** Host session id when known (hook payload, `HIPPO_SESSION_ID`); null otherwise. */
|
|
32
|
+
sessionId?: string | null;
|
|
33
|
+
surface: TokenSurface;
|
|
34
|
+
event: TokenEvent;
|
|
35
|
+
/** Memories (and continuity blocks) in the text. */
|
|
36
|
+
items: number;
|
|
37
|
+
/** Estimated tokens of the text; for a `skip`, the tokens not sent. */
|
|
38
|
+
tokens: number;
|
|
39
|
+
/** {@link blockHash} of the text, when the caller wants change detection. */
|
|
40
|
+
hash?: string | null;
|
|
41
|
+
/** Override the timestamp (tests). ISO string. */
|
|
42
|
+
now?: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Append one ledger row and prune rows past {@link TOKEN_LEDGER_RETENTION_DAYS}.
|
|
46
|
+
*/
|
|
47
|
+
export declare function recordTokenUse(db: DatabaseSyncLike, use: TokenUse): void;
|
|
48
|
+
/** What a session last sent on a surface, for {@link lastSentState}. */
|
|
49
|
+
export interface LastSent {
|
|
50
|
+
/** {@link blockHash} of the last injected block. */
|
|
51
|
+
hash: string;
|
|
52
|
+
/** Consecutive `skip` rows since that injection. */
|
|
53
|
+
skipsSince: number;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The last block this session injected on `surface`, or null when the
|
|
57
|
+
* session has injected nothing, a `reset` came after it, or there is no
|
|
58
|
+
* session id (without one, the caller always injects).
|
|
59
|
+
*/
|
|
60
|
+
export declare function lastSentState(db: DatabaseSyncLike, tenantId: string, sessionId: string | null | undefined, surface: TokenSurface): LastSent | null;
|
|
61
|
+
/**
|
|
62
|
+
* Whether a block identical to the session's last injection should be
|
|
63
|
+
* skipped. `refreshTurns` resends an unchanged block after that many
|
|
64
|
+
* consecutive skips, so a long session still sees its pinned rules near the
|
|
65
|
+
* latest turn; 0 never resends an unchanged block.
|
|
66
|
+
*/
|
|
67
|
+
export declare function shouldSkipUnchanged(last: LastSent | null, hash: string, refreshTurns: number): boolean;
|
|
68
|
+
/** Per-surface totals for {@link summarizeTokenUse}. */
|
|
69
|
+
export interface TokenSurfaceSummary {
|
|
70
|
+
surface: TokenSurface;
|
|
71
|
+
/** Blocks sent. */
|
|
72
|
+
injected: number;
|
|
73
|
+
/** Tokens sent. */
|
|
74
|
+
tokens: number;
|
|
75
|
+
/** Blocks not sent because they were unchanged. */
|
|
76
|
+
skipped: number;
|
|
77
|
+
/** Tokens those skipped blocks would have cost. */
|
|
78
|
+
tokensAvoided: number;
|
|
79
|
+
/** Distinct session ids seen (rows without one are not counted). */
|
|
80
|
+
sessions: number;
|
|
81
|
+
}
|
|
82
|
+
/** Ledger totals over a window. */
|
|
83
|
+
export interface TokenSummary {
|
|
84
|
+
/** ISO start of the window (inclusive). */
|
|
85
|
+
since: string;
|
|
86
|
+
surfaces: TokenSurfaceSummary[];
|
|
87
|
+
totalTokens: number;
|
|
88
|
+
totalTokensAvoided: number;
|
|
89
|
+
/** Mean tokens sent per session, over rows that carry a session id. */
|
|
90
|
+
meanTokensPerSession: number;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Sum the ledger for one tenant since `sinceIso`. Surfaces with no rows are
|
|
94
|
+
* omitted.
|
|
95
|
+
*/
|
|
96
|
+
export declare function summarizeTokenUse(db: DatabaseSyncLike, tenantId: string, sinceIso: string): TokenSummary;
|
|
97
|
+
/**
|
|
98
|
+
* The `session_id` of a Claude Code hook payload on stdin, or null when the
|
|
99
|
+
* text is empty, malformed, has no non-empty session id, or (with
|
|
100
|
+
* `requiredSource`) a different `source`.
|
|
101
|
+
*/
|
|
102
|
+
export declare function hookPayloadSessionId(stdinText: string | undefined, requiredSource?: string | null): string | null;
|
|
103
|
+
/** Tokens hippo sent and skipped in one session, for {@link tokensBySession}. */
|
|
104
|
+
export interface SessionTokens {
|
|
105
|
+
sessionId: string;
|
|
106
|
+
/** Tokens of memory text sent to the agent. */
|
|
107
|
+
sent: number;
|
|
108
|
+
/** Tokens of unchanged blocks not sent. */
|
|
109
|
+
skipped: number;
|
|
110
|
+
/** Blocks sent. */
|
|
111
|
+
injections: number;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Ledger totals per session id since `sinceIso`, across every surface.
|
|
115
|
+
* Claude Code hook rows carry the host's session id, which is also the
|
|
116
|
+
* transcript file name, so these join to the host's own usage records.
|
|
117
|
+
*/
|
|
118
|
+
export declare function tokensBySession(db: DatabaseSyncLike, tenantId: string, sinceIso: string): SessionTokens[];
|
|
119
|
+
//# sourceMappingURL=token-ledger.d.ts.map
|