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
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Statistics and cost accounting for the token-efficiency evals (ROADMAP
|
|
3
|
+
* Part IX, TE3-TE5).
|
|
4
|
+
*
|
|
5
|
+
* - Cost: price provider usage over four buckets (uncached input, cache
|
|
6
|
+
* write, cache read, output). Raw token counts overstate savings when most
|
|
7
|
+
* input is already cache reads, so every dollar claim goes through here.
|
|
8
|
+
* - Uncertainty: paired bootstrap over tasks, cluster bootstrap (tasks that
|
|
9
|
+
* share a repository are not independent), and a paired ratio bootstrap for
|
|
10
|
+
* dollars per resolved task.
|
|
11
|
+
*
|
|
12
|
+
* Deterministic: every resampling function takes a seed, so a published
|
|
13
|
+
* result can be reproduced exactly.
|
|
14
|
+
*/
|
|
15
|
+
/** Sum several usages bucket by bucket. */
|
|
16
|
+
export function addUsage(...usages) {
|
|
17
|
+
const total = { inputTokens: 0, cacheWriteTokens: 0, cacheReadTokens: 0, outputTokens: 0 };
|
|
18
|
+
for (const u of usages) {
|
|
19
|
+
total.inputTokens += u.inputTokens;
|
|
20
|
+
total.cacheWriteTokens += u.cacheWriteTokens;
|
|
21
|
+
total.cacheReadTokens += u.cacheReadTokens;
|
|
22
|
+
total.outputTokens += u.outputTokens;
|
|
23
|
+
}
|
|
24
|
+
return total;
|
|
25
|
+
}
|
|
26
|
+
/** Dollar cost of `usage` at `prices`. */
|
|
27
|
+
export function priceUsage(usage, prices) {
|
|
28
|
+
return (usage.inputTokens * prices.inputPerMTok
|
|
29
|
+
+ usage.cacheWriteTokens * prices.cacheWritePerMTok
|
|
30
|
+
+ usage.cacheReadTokens * prices.cacheReadPerMTok
|
|
31
|
+
+ usage.outputTokens * prices.outputPerMTok) / 1_000_000;
|
|
32
|
+
}
|
|
33
|
+
/** Default cache price ratios (write 1.25x, read 0.1x of base input). */
|
|
34
|
+
export const DEFAULT_CACHE_RATIOS = { write: 1.25, read: 0.1 };
|
|
35
|
+
/** Input cost of `usage` in uncached-equivalent tokens (output excluded). */
|
|
36
|
+
export function uncachedEquivalentInput(usage, ratios = DEFAULT_CACHE_RATIOS) {
|
|
37
|
+
return usage.inputTokens + usage.cacheWriteTokens * ratios.write + usage.cacheReadTokens * ratios.read;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Mulberry32: a small seeded PRNG returning floats in [0, 1). Same seed,
|
|
41
|
+
* same stream, on every platform.
|
|
42
|
+
*/
|
|
43
|
+
export function seededRandom(seed) {
|
|
44
|
+
let a = seed >>> 0;
|
|
45
|
+
return () => {
|
|
46
|
+
a = (a + 0x6d2b79f5) >>> 0;
|
|
47
|
+
let t = a;
|
|
48
|
+
t = Math.imul(t ^ (t >>> 15), t | 1);
|
|
49
|
+
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
|
|
50
|
+
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function percentileInterval(samples, alpha) {
|
|
54
|
+
const sorted = [...samples].sort((x, y) => x - y);
|
|
55
|
+
const lowIdx = Math.max(0, Math.floor((alpha / 2) * sorted.length));
|
|
56
|
+
const highIdx = Math.min(sorted.length - 1, Math.ceil((1 - alpha / 2) * sorted.length) - 1);
|
|
57
|
+
return { low: sorted[lowIdx], high: sorted[highIdx] };
|
|
58
|
+
}
|
|
59
|
+
function mean(xs) {
|
|
60
|
+
return xs.length === 0 ? 0 : xs.reduce((s, x) => s + x, 0) / xs.length;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Paired bootstrap for the mean of per-task differences (treatment minus
|
|
64
|
+
* control on the same task). An interval that excludes zero is the bar for
|
|
65
|
+
* calling a difference real.
|
|
66
|
+
*/
|
|
67
|
+
export function pairedBootstrap(diffs, opts = {}) {
|
|
68
|
+
const iterations = opts.iterations ?? 5000;
|
|
69
|
+
const alpha = opts.alpha ?? 0.05;
|
|
70
|
+
if (diffs.length === 0)
|
|
71
|
+
return { estimate: 0, low: 0, high: 0, iterations: 0 };
|
|
72
|
+
const rand = seededRandom(opts.seed ?? 1);
|
|
73
|
+
const n = diffs.length;
|
|
74
|
+
const samples = [];
|
|
75
|
+
for (let b = 0; b < iterations; b++) {
|
|
76
|
+
let s = 0;
|
|
77
|
+
for (let i = 0; i < n; i++)
|
|
78
|
+
s += diffs[Math.floor(rand() * n)];
|
|
79
|
+
samples.push(s / n);
|
|
80
|
+
}
|
|
81
|
+
return { estimate: mean(diffs), ...percentileInterval(samples, alpha), iterations };
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Cluster bootstrap for the mean of per-task differences: resamples whole
|
|
85
|
+
* clusters (for example all tasks from one repository), because tasks in a
|
|
86
|
+
* cluster share causes and are not independent draws.
|
|
87
|
+
*/
|
|
88
|
+
export function clusteredPairedBootstrap(diffsByCluster, opts = {}) {
|
|
89
|
+
const iterations = opts.iterations ?? 5000;
|
|
90
|
+
const alpha = opts.alpha ?? 0.05;
|
|
91
|
+
const clusters = [...diffsByCluster.values()].filter((c) => c.length > 0);
|
|
92
|
+
const all = clusters.flat();
|
|
93
|
+
if (all.length === 0)
|
|
94
|
+
return { estimate: 0, low: 0, high: 0, iterations: 0 };
|
|
95
|
+
const rand = seededRandom(opts.seed ?? 1);
|
|
96
|
+
const k = clusters.length;
|
|
97
|
+
const samples = [];
|
|
98
|
+
for (let b = 0; b < iterations; b++) {
|
|
99
|
+
let sum = 0;
|
|
100
|
+
let count = 0;
|
|
101
|
+
for (let i = 0; i < k; i++) {
|
|
102
|
+
const c = clusters[Math.floor(rand() * k)];
|
|
103
|
+
for (const d of c)
|
|
104
|
+
sum += d;
|
|
105
|
+
count += c.length;
|
|
106
|
+
}
|
|
107
|
+
samples.push(count === 0 ? 0 : sum / count);
|
|
108
|
+
}
|
|
109
|
+
return { estimate: mean(all), ...percentileInterval(samples, alpha), iterations };
|
|
110
|
+
}
|
|
111
|
+
function costPerResolved(outcomes) {
|
|
112
|
+
const resolved = outcomes.filter((o) => o.resolved).length;
|
|
113
|
+
const cost = outcomes.reduce((s, o) => s + o.cost, 0);
|
|
114
|
+
return resolved === 0 ? Number.POSITIVE_INFINITY : cost / resolved;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Cost per resolved task in two arms run on the same tasks, with a paired
|
|
118
|
+
* bootstrap over tasks (a task is resampled with both of its arm outcomes).
|
|
119
|
+
* `control[i]` and `treatment[i]` must be the same task. Resamples in which
|
|
120
|
+
* an arm resolves nothing are dropped; `iterations` reports how many were
|
|
121
|
+
* kept.
|
|
122
|
+
*/
|
|
123
|
+
export function costPerResolvedDelta(control, treatment, opts = {}) {
|
|
124
|
+
if (control.length !== treatment.length) {
|
|
125
|
+
throw new Error('control and treatment must list the same tasks in the same order');
|
|
126
|
+
}
|
|
127
|
+
const iterations = opts.iterations ?? 5000;
|
|
128
|
+
const alpha = opts.alpha ?? 0.05;
|
|
129
|
+
const c = costPerResolved(control);
|
|
130
|
+
const t = costPerResolved(treatment);
|
|
131
|
+
const rand = seededRandom(opts.seed ?? 1);
|
|
132
|
+
const n = control.length;
|
|
133
|
+
const deltas = [];
|
|
134
|
+
const relatives = [];
|
|
135
|
+
for (let b = 0; b < iterations && n > 0; b++) {
|
|
136
|
+
const cs = [];
|
|
137
|
+
const ts = [];
|
|
138
|
+
for (let i = 0; i < n; i++) {
|
|
139
|
+
const j = Math.floor(rand() * n);
|
|
140
|
+
cs.push(control[j]);
|
|
141
|
+
ts.push(treatment[j]);
|
|
142
|
+
}
|
|
143
|
+
const cc = costPerResolved(cs);
|
|
144
|
+
const tt = costPerResolved(ts);
|
|
145
|
+
if (!Number.isFinite(cc) || !Number.isFinite(tt))
|
|
146
|
+
continue;
|
|
147
|
+
deltas.push(tt - cc);
|
|
148
|
+
relatives.push((tt - cc) / cc);
|
|
149
|
+
}
|
|
150
|
+
const finite = Number.isFinite(c) && Number.isFinite(t);
|
|
151
|
+
const empty = { low: Number.NaN, high: Number.NaN };
|
|
152
|
+
return {
|
|
153
|
+
control: c,
|
|
154
|
+
treatment: t,
|
|
155
|
+
delta: {
|
|
156
|
+
estimate: finite ? t - c : Number.NaN,
|
|
157
|
+
...(deltas.length > 0 ? percentileInterval(deltas, alpha) : empty),
|
|
158
|
+
iterations: deltas.length,
|
|
159
|
+
},
|
|
160
|
+
relative: {
|
|
161
|
+
estimate: finite ? (t - c) / c : Number.NaN,
|
|
162
|
+
...(relatives.length > 0 ? percentileInterval(relatives, alpha) : empty),
|
|
163
|
+
iterations: relatives.length,
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* pass@k: share of tasks with at least one success in their first k runs.
|
|
169
|
+
* NaN when no task has k runs (not measured, which is not the same as 0).
|
|
170
|
+
*/
|
|
171
|
+
export function passAtK(runsByTask, k) {
|
|
172
|
+
const eligible = runsByTask.filter((r) => r.length >= k);
|
|
173
|
+
if (eligible.length === 0)
|
|
174
|
+
return Number.NaN;
|
|
175
|
+
return eligible.filter((r) => r.slice(0, k).some(Boolean)).length / eligible.length;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* pass^k: share of tasks whose first k runs all succeed (consistency).
|
|
179
|
+
* NaN when no task has k runs.
|
|
180
|
+
*/
|
|
181
|
+
export function passHatK(runsByTask, k) {
|
|
182
|
+
const eligible = runsByTask.filter((r) => r.length >= k);
|
|
183
|
+
if (eligible.length === 0)
|
|
184
|
+
return Number.NaN;
|
|
185
|
+
return eligible.filter((r) => r.slice(0, k).every(Boolean)).length / eligible.length;
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=eval-stats.js.map
|
package/dist/extract.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export interface ExtractOptions {
|
|
|
8
8
|
apiKey: string;
|
|
9
9
|
model?: string;
|
|
10
10
|
fetcher?: typeof fetch;
|
|
11
|
+
/** Told why a call produced nothing, so callers can surface it instead of guessing. */
|
|
12
|
+
onError?: (msg: string) => void;
|
|
11
13
|
}
|
|
12
14
|
export declare function extractFacts(text: string, opts: ExtractOptions): Promise<ExtractedFact[]>;
|
|
13
15
|
export declare function storeExtractedFacts(hippoRoot: string, source: MemoryEntry, facts: ExtractedFact[]): MemoryEntry[];
|
package/dist/extract.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Layer, createMemory } from './memory.js';
|
|
2
2
|
import { writeEntry } from './store.js';
|
|
3
3
|
import { RejectedValueError } from './rejection.js';
|
|
4
|
+
import { redactSecrets } from './secret-detect.js';
|
|
4
5
|
function isJsonString(value) {
|
|
5
6
|
return typeof value === 'string';
|
|
6
7
|
}
|
|
@@ -31,15 +32,18 @@ export async function extractFacts(text, opts) {
|
|
|
31
32
|
body: JSON.stringify({
|
|
32
33
|
model,
|
|
33
34
|
max_tokens: 1200,
|
|
34
|
-
messages: [{ role: 'user', content: EXTRACTION_PROMPT + text }],
|
|
35
|
+
messages: [{ role: 'user', content: EXTRACTION_PROMPT + redactSecrets(text) }],
|
|
35
36
|
}),
|
|
36
37
|
});
|
|
37
38
|
}
|
|
38
|
-
catch {
|
|
39
|
+
catch (err) {
|
|
40
|
+
opts.onError?.(`request failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
39
41
|
return [];
|
|
40
42
|
}
|
|
41
|
-
if (!res.ok)
|
|
43
|
+
if (!res.ok) {
|
|
44
|
+
opts.onError?.(`HTTP ${res.status}`);
|
|
42
45
|
return [];
|
|
46
|
+
}
|
|
43
47
|
try {
|
|
44
48
|
const data = await res.json();
|
|
45
49
|
const raw = data.content?.[0]?.text?.trim() ?? '';
|
|
@@ -69,7 +73,8 @@ export async function extractFacts(text, opts) {
|
|
|
69
73
|
}
|
|
70
74
|
return facts;
|
|
71
75
|
}
|
|
72
|
-
catch {
|
|
76
|
+
catch (err) {
|
|
77
|
+
opts.onError?.(`unparseable response: ${err instanceof Error ? err.message : String(err)}`);
|
|
73
78
|
return [];
|
|
74
79
|
}
|
|
75
80
|
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Moving a store's memories to a new default half-life.
|
|
3
|
+
*
|
|
4
|
+
* Each memory stores its own `half_life_days`, set at write from the
|
|
5
|
+
* default base and a few write-time multipliers (`deriveHalfLife`). Changing
|
|
6
|
+
* the default therefore reaches only new memories; without this migration a
|
|
7
|
+
* store would mix old-base and new-base memories, a state the decay
|
|
8
|
+
* evaluation never tested (docs/evals/2026-09-24-decay-default-prereg.md,
|
|
9
|
+
* Migration). The rule, declared there before any run:
|
|
10
|
+
*
|
|
11
|
+
* - only a memory still on the old base is rescaled: its half-life is
|
|
12
|
+
* `deriveHalfLife(from, entry)` plus its recall bonus. A memory hippo shortened since
|
|
13
|
+
* (invalidated, superseded, a merge source, marked bad) or one with its own
|
|
14
|
+
* fixed half-life (decisions, incidents, customer notes) keeps its value;
|
|
15
|
+
* - every rescale is written to the audit log with the ids, so it can be
|
|
16
|
+
* undone, and the store records the base it is on (`meta`), so the
|
|
17
|
+
* migration runs once.
|
|
18
|
+
*
|
|
19
|
+
* `hippo sleep` runs it before its decay pass, from the base the store is on
|
|
20
|
+
* (7 days when never recorded) to the configured `defaultHalfLifeDays`.
|
|
21
|
+
*/
|
|
22
|
+
import { type MemoryEntry } from './memory.js';
|
|
23
|
+
import { HALF_LIFE_BASE_META_KEY } from './store.js';
|
|
24
|
+
/** The base every store used before the base was recorded. */
|
|
25
|
+
export declare const LEGACY_HALF_LIFE_BASE = 7;
|
|
26
|
+
export { HALF_LIFE_BASE_META_KEY };
|
|
27
|
+
/** What {@link migrateDefaultHalfLife} did, or would do under `dryRun`. */
|
|
28
|
+
export interface HalfLifeMigrationResult {
|
|
29
|
+
from: number;
|
|
30
|
+
to: number;
|
|
31
|
+
/** Memories moved to the new base. */
|
|
32
|
+
rescaled: number;
|
|
33
|
+
/** Memories left alone because they are not on the old base. */
|
|
34
|
+
kept: number;
|
|
35
|
+
dryRun: boolean;
|
|
36
|
+
/** New half-life per moved id, so a dry run can preview decay at the new base. */
|
|
37
|
+
halfLives: ReadonlyMap<string, number>;
|
|
38
|
+
}
|
|
39
|
+
type HalfLifeFields = Pick<MemoryEntry, 'half_life_days' | 'tags' | 'schema_fit' | 'retrieval_count' | 'superseded_by'>;
|
|
40
|
+
/** Recall bonus over what `base` gave `entry`, or null when off that base; pre-1.46 recalls each added 2 days. */
|
|
41
|
+
export declare function halfLifeRecallBonus(entry: HalfLifeFields, base: number): number | null;
|
|
42
|
+
/** The entries to rescale from `from` to `to`, as copies that keep their recall bonus. Pure. */
|
|
43
|
+
export declare function planHalfLifeMigration(entries: readonly MemoryEntry[], from: number, to: number): MemoryEntry[];
|
|
44
|
+
/** The base this store's memories are on. */
|
|
45
|
+
export declare function storeHalfLifeBase(hippoRoot: string): number;
|
|
46
|
+
/**
|
|
47
|
+
* Move the store's memories from the base they are on to `to`. A no-op when
|
|
48
|
+
* they are already on it. Under `dryRun` nothing is written, the recorded
|
|
49
|
+
* base included.
|
|
50
|
+
*/
|
|
51
|
+
export declare function migrateDefaultHalfLife(hippoRoot: string, to: number, opts?: {
|
|
52
|
+
dryRun?: boolean;
|
|
53
|
+
actor?: string;
|
|
54
|
+
}): HalfLifeMigrationResult;
|
|
55
|
+
//# sourceMappingURL=half-life-migration.d.ts.map
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Moving a store's memories to a new default half-life.
|
|
3
|
+
*
|
|
4
|
+
* Each memory stores its own `half_life_days`, set at write from the
|
|
5
|
+
* default base and a few write-time multipliers (`deriveHalfLife`). Changing
|
|
6
|
+
* the default therefore reaches only new memories; without this migration a
|
|
7
|
+
* store would mix old-base and new-base memories, a state the decay
|
|
8
|
+
* evaluation never tested (docs/evals/2026-09-24-decay-default-prereg.md,
|
|
9
|
+
* Migration). The rule, declared there before any run:
|
|
10
|
+
*
|
|
11
|
+
* - only a memory still on the old base is rescaled: its half-life is
|
|
12
|
+
* `deriveHalfLife(from, entry)` plus its recall bonus. A memory hippo shortened since
|
|
13
|
+
* (invalidated, superseded, a merge source, marked bad) or one with its own
|
|
14
|
+
* fixed half-life (decisions, incidents, customer notes) keeps its value;
|
|
15
|
+
* - every rescale is written to the audit log with the ids, so it can be
|
|
16
|
+
* undone, and the store records the base it is on (`meta`), so the
|
|
17
|
+
* migration runs once.
|
|
18
|
+
*
|
|
19
|
+
* `hippo sleep` runs it before its decay pass, from the base the store is on
|
|
20
|
+
* (7 days when never recorded) to the configured `defaultHalfLifeDays`.
|
|
21
|
+
*/
|
|
22
|
+
import { deriveHalfLife } from './memory.js';
|
|
23
|
+
import { initStore, selectAllEntries, HALF_LIFE_BASE_META_KEY } from './store.js';
|
|
24
|
+
import { openHippoDb, closeHippoDb, getMeta, setMeta } from './db.js';
|
|
25
|
+
import { appendAuditEvent } from './audit.js';
|
|
26
|
+
/** The base every store used before the base was recorded. */
|
|
27
|
+
export const LEGACY_HALF_LIFE_BASE = 7;
|
|
28
|
+
export { HALF_LIFE_BASE_META_KEY };
|
|
29
|
+
/** Recall bonus over what `base` gave `entry`, or null when off that base; pre-1.46 recalls each added 2 days. */
|
|
30
|
+
export function halfLifeRecallBonus(entry, base) {
|
|
31
|
+
if (entry.superseded_by || entry.tags.includes('invalidated') || entry.tags.includes('superseded'))
|
|
32
|
+
return null;
|
|
33
|
+
const bonus = entry.half_life_days - deriveHalfLife(base, entry);
|
|
34
|
+
const k = Math.round(bonus / 2);
|
|
35
|
+
return Math.abs(bonus - 2 * k) < 1e-9 && k >= 0 && k <= entry.retrieval_count ? bonus : null;
|
|
36
|
+
}
|
|
37
|
+
/** The entries to rescale from `from` to `to`, as copies that keep their recall bonus. Pure. */
|
|
38
|
+
export function planHalfLifeMigration(entries, from, to) {
|
|
39
|
+
if (from === to)
|
|
40
|
+
return [];
|
|
41
|
+
return entries.flatMap((e) => {
|
|
42
|
+
const bonus = halfLifeRecallBonus(e, from);
|
|
43
|
+
return bonus === null ? [] : [{ ...e, half_life_days: deriveHalfLife(to, e) + bonus }];
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
/** The base this store's memories are on. */
|
|
47
|
+
export function storeHalfLifeBase(hippoRoot) {
|
|
48
|
+
const db = openHippoDb(hippoRoot);
|
|
49
|
+
try {
|
|
50
|
+
return readBase(db);
|
|
51
|
+
}
|
|
52
|
+
finally {
|
|
53
|
+
closeHippoDb(db);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function readBase(db) {
|
|
57
|
+
const raw = Number(getMeta(db, HALF_LIFE_BASE_META_KEY, String(LEGACY_HALF_LIFE_BASE)));
|
|
58
|
+
return Number.isFinite(raw) && raw > 0 ? raw : LEGACY_HALF_LIFE_BASE;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Move the store's memories from the base they are on to `to`. A no-op when
|
|
62
|
+
* they are already on it. Under `dryRun` nothing is written, the recorded
|
|
63
|
+
* base included.
|
|
64
|
+
*/
|
|
65
|
+
export function migrateDefaultHalfLife(hippoRoot, to, opts = {}) {
|
|
66
|
+
const dryRun = opts.dryRun ?? false;
|
|
67
|
+
const noop = (from) => ({ from, to, rescaled: 0, kept: 0, dryRun, halfLives: new Map() });
|
|
68
|
+
initStore(hippoRoot);
|
|
69
|
+
const db = openHippoDb(hippoRoot);
|
|
70
|
+
try {
|
|
71
|
+
// Plan, write, audit and record the base under one write lock, so a concurrent write or sleep cannot interleave.
|
|
72
|
+
if (!dryRun)
|
|
73
|
+
db.exec('BEGIN IMMEDIATE');
|
|
74
|
+
try {
|
|
75
|
+
const from = readBase(db);
|
|
76
|
+
if (!(Number.isFinite(to) && to > 0) || from === to) {
|
|
77
|
+
if (!dryRun)
|
|
78
|
+
db.exec('COMMIT');
|
|
79
|
+
return noop(from);
|
|
80
|
+
}
|
|
81
|
+
const all = selectAllEntries(db);
|
|
82
|
+
const plan = planHalfLifeMigration(all, from, to);
|
|
83
|
+
const halfLives = new Map(plan.map((e) => [e.id, e.half_life_days]));
|
|
84
|
+
const result = { from, to, rescaled: plan.length, kept: all.length - plan.length, dryRun, halfLives };
|
|
85
|
+
if (dryRun)
|
|
86
|
+
return result;
|
|
87
|
+
const old = new Map(all.map((e) => [e.id, e.half_life_days]));
|
|
88
|
+
const update = db.prepare('UPDATE memories SET half_life_days = ? WHERE id = ?');
|
|
89
|
+
const byTenant = new Map();
|
|
90
|
+
for (const e of plan) {
|
|
91
|
+
update.run(e.half_life_days, e.id);
|
|
92
|
+
byTenant.set(e.tenantId, { ...byTenant.get(e.tenantId), [e.id]: old.get(e.id) });
|
|
93
|
+
}
|
|
94
|
+
for (const [tenantId, oldHalfLives] of byTenant) {
|
|
95
|
+
appendAuditEvent(db, { tenantId, actor: opts.actor ?? 'system', op: 'half_life_migrate', metadata: { from, to, ids: Object.keys(oldHalfLives), oldHalfLives } });
|
|
96
|
+
}
|
|
97
|
+
setMeta(db, HALF_LIFE_BASE_META_KEY, String(to));
|
|
98
|
+
db.exec('COMMIT');
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
if (!dryRun)
|
|
103
|
+
db.exec('ROLLBACK');
|
|
104
|
+
throw err;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
finally {
|
|
108
|
+
closeHippoDb(db);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=half-life-migration.js.map
|
package/dist/hooks.d.ts
CHANGED
|
@@ -85,6 +85,10 @@ export interface InstallResult {
|
|
|
85
85
|
installedUserPromptSubmit: boolean;
|
|
86
86
|
installedPreCompact: boolean;
|
|
87
87
|
installedCompactResume: boolean;
|
|
88
|
+
/** PostCompact -> `hippo post-compact` (tells the user what compaction saved). */
|
|
89
|
+
installedPostCompact: boolean;
|
|
90
|
+
/** PostToolUseFailure -> `hippo capture-error` (failed tool calls become error memories). */
|
|
91
|
+
installedCaptureError: boolean;
|
|
88
92
|
migratedPinnedInjectRecent: boolean;
|
|
89
93
|
migratedFromStop: boolean;
|
|
90
94
|
migratedLegacySessionEnd: boolean;
|
package/dist/hooks.js
CHANGED
|
@@ -52,6 +52,8 @@ const HIPPO_PINNED_INJECT_COMMAND = 'hippo context --pinned-only --include-recen
|
|
|
52
52
|
const HIPPO_CODEX_WRAPPER_MARKER = 'hippo codex wrapper';
|
|
53
53
|
const HIPPO_PRE_COMPACT_MARKER = 'hippo pre-compact';
|
|
54
54
|
const HIPPO_COMPACT_RESUME_MARKER = 'hippo compact-resume';
|
|
55
|
+
const HIPPO_CAPTURE_ERROR_MARKER = 'hippo capture-error';
|
|
56
|
+
const HIPPO_POST_COMPACT_MARKER = 'hippo post-compact';
|
|
55
57
|
const HIPPO_OPENCODE_PLUGIN_MARKER = 'HIPPO_OPENCODE_PLUGIN_V1';
|
|
56
58
|
/**
|
|
57
59
|
* The opencode plugin file we install at ~/.config/opencode/plugins/hippo.ts.
|
|
@@ -571,6 +573,8 @@ export function installJsonHooks(target) {
|
|
|
571
573
|
installedUserPromptSubmit: false,
|
|
572
574
|
installedPreCompact: false,
|
|
573
575
|
installedCompactResume: false,
|
|
576
|
+
installedPostCompact: false,
|
|
577
|
+
installedCaptureError: false,
|
|
574
578
|
migratedPinnedInjectRecent: false,
|
|
575
579
|
migratedFromStop: false,
|
|
576
580
|
migratedLegacySessionEnd: false,
|
|
@@ -703,11 +707,50 @@ export function installJsonHooks(target) {
|
|
|
703
707
|
});
|
|
704
708
|
installedCompactResume = true;
|
|
705
709
|
}
|
|
710
|
+
// PostCompact: tells the user what pre-compact saved. PreCompact itself
|
|
711
|
+
// must stay silent, because Claude Code hands PreCompact stdout to the
|
|
712
|
+
// summarising model as instructions; PostCompact stdout is only shown.
|
|
713
|
+
let installedPostCompact = false;
|
|
714
|
+
if (!hookArrayContains(hooks.PostCompact, HIPPO_POST_COMPACT_MARKER)) {
|
|
715
|
+
if (!Array.isArray(hooks.PostCompact))
|
|
716
|
+
hooks.PostCompact = [];
|
|
717
|
+
hooks.PostCompact.push({
|
|
718
|
+
hooks: [
|
|
719
|
+
{
|
|
720
|
+
type: 'command',
|
|
721
|
+
command: `hippo post-compact --log-file "${defaultPreCompactLogPath()}"`,
|
|
722
|
+
timeout: 10,
|
|
723
|
+
},
|
|
724
|
+
],
|
|
725
|
+
});
|
|
726
|
+
installedPostCompact = true;
|
|
727
|
+
}
|
|
728
|
+
// PostToolUseFailure: a failed tool call becomes an error memory, after
|
|
729
|
+
// `hippo capture-error` drops routine failures (interrupts, declined
|
|
730
|
+
// permissions, empty searches) and repeats. Same hook the plugin ships.
|
|
731
|
+
let installedCaptureError = false;
|
|
732
|
+
if (!hookArrayContains(hooks.PostToolUseFailure, HIPPO_CAPTURE_ERROR_MARKER)) {
|
|
733
|
+
if (!Array.isArray(hooks.PostToolUseFailure))
|
|
734
|
+
hooks.PostToolUseFailure = [];
|
|
735
|
+
hooks.PostToolUseFailure.push({
|
|
736
|
+
matcher: '.*',
|
|
737
|
+
hooks: [
|
|
738
|
+
{
|
|
739
|
+
type: 'command',
|
|
740
|
+
command: 'hippo capture-error',
|
|
741
|
+
timeout: 10,
|
|
742
|
+
},
|
|
743
|
+
],
|
|
744
|
+
});
|
|
745
|
+
installedCaptureError = true;
|
|
746
|
+
}
|
|
706
747
|
if (installedSessionEnd ||
|
|
707
748
|
installedSessionStart ||
|
|
708
749
|
installedUserPromptSubmit ||
|
|
709
750
|
installedPreCompact ||
|
|
710
751
|
installedCompactResume ||
|
|
752
|
+
installedPostCompact ||
|
|
753
|
+
installedCaptureError ||
|
|
711
754
|
migratedPinnedInjectRecent ||
|
|
712
755
|
migratedFromStop ||
|
|
713
756
|
migratedLegacySessionEnd ||
|
|
@@ -722,6 +765,8 @@ export function installJsonHooks(target) {
|
|
|
722
765
|
installedUserPromptSubmit,
|
|
723
766
|
installedPreCompact,
|
|
724
767
|
installedCompactResume,
|
|
768
|
+
installedPostCompact,
|
|
769
|
+
installedCaptureError,
|
|
725
770
|
migratedPinnedInjectRecent,
|
|
726
771
|
migratedFromStop,
|
|
727
772
|
migratedLegacySessionEnd,
|
|
@@ -753,6 +798,8 @@ export function uninstallJsonHooks(target) {
|
|
|
753
798
|
SessionStart: [HIPPO_LAST_SLEEP_MARKER, HIPPO_COMPACT_RESUME_MARKER],
|
|
754
799
|
UserPromptSubmit: [HIPPO_PINNED_INJECT_MARKER],
|
|
755
800
|
PreCompact: [HIPPO_PRE_COMPACT_MARKER],
|
|
801
|
+
PostCompact: [HIPPO_POST_COMPACT_MARKER],
|
|
802
|
+
PostToolUseFailure: [HIPPO_CAPTURE_ERROR_MARKER],
|
|
756
803
|
Stop: [HIPPO_SLEEP_MARKER],
|
|
757
804
|
};
|
|
758
805
|
for (const [key, markers] of Object.entries(markersByKey)) {
|
package/dist/mcp/server.d.ts
CHANGED
|
@@ -42,6 +42,12 @@ export interface McpContext {
|
|
|
42
42
|
hippoRoot: string;
|
|
43
43
|
tenantId: string;
|
|
44
44
|
actor: string;
|
|
45
|
+
/**
|
|
46
|
+
* The caller's role from the HTTP transport's auth. Absent for stdio, which
|
|
47
|
+
* is the local operator and runs as admin. Tools must use this rather than
|
|
48
|
+
* assuming admin, or a member key over HTTP-MCP would act as admin.
|
|
49
|
+
*/
|
|
50
|
+
role?: 'admin' | 'member';
|
|
45
51
|
/**
|
|
46
52
|
* Per-client key for state isolation under HTTP-MCP. For stdio: 'stdio-${pid}'
|
|
47
53
|
* (one process = one client). For HTTP-SSE / HTTP MCP: hash(bearer + remoteAddr)
|