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/doctor.js
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `hippo doctor`: a health check people and agents can run after installing
|
|
3
|
+
* hippo, or when something seems off. Read-only: it never creates a store,
|
|
4
|
+
* installs a hook or migrates a database. Every non-passing check names the
|
|
5
|
+
* command that fixes it, so an agent can act on the `--json` output.
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from 'node:fs';
|
|
8
|
+
import * as os from 'node:os';
|
|
9
|
+
import * as path from 'node:path';
|
|
10
|
+
import { findHippoStoreDir } from './project-identity.js';
|
|
11
|
+
import { getGlobalRoot } from './shared.js';
|
|
12
|
+
import { isInitialized, loadStats } from './store.js';
|
|
13
|
+
import { openHippoDb, closeHippoDb, getSchemaVersion, getCurrentSchemaVersion } from './db.js';
|
|
14
|
+
import { isEmbeddingAvailable } from './embeddings.js';
|
|
15
|
+
/** Minimum Node.js version hippo supports (package.json engines). */
|
|
16
|
+
export const MIN_NODE = '22.16.0';
|
|
17
|
+
function versionAtLeast(actual, min) {
|
|
18
|
+
const a = actual.replace(/^v/, '').split('.').map(Number);
|
|
19
|
+
const b = min.split('.').map(Number);
|
|
20
|
+
for (let i = 0; i < 3; i++) {
|
|
21
|
+
const x = a[i] ?? 0;
|
|
22
|
+
const y = b[i] ?? 0;
|
|
23
|
+
if (x !== y)
|
|
24
|
+
return x > y;
|
|
25
|
+
}
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
function readJson(file) {
|
|
29
|
+
try {
|
|
30
|
+
// SAFETY: JSON.parse returns a JSON value by definition.
|
|
31
|
+
return JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function countRows(db, table) {
|
|
38
|
+
try {
|
|
39
|
+
// SAFETY: COUNT(*) returns one row with one numeric column.
|
|
40
|
+
const row = db.prepare(`SELECT COUNT(*) AS n FROM ${table}`).get();
|
|
41
|
+
return Number(row?.n ?? 0);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/** Run every check. Never throws for a broken install; broken parts become failed checks. */
|
|
48
|
+
export function runDoctor(opts) {
|
|
49
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
50
|
+
const home = opts.home ?? os.homedir();
|
|
51
|
+
const now = opts.now ?? new Date();
|
|
52
|
+
const checks = [];
|
|
53
|
+
const node = opts.nodeVersion ?? process.versions.node;
|
|
54
|
+
checks.push(versionAtLeast(node, MIN_NODE)
|
|
55
|
+
? { id: 'node', status: 'pass', detail: `Node.js ${node}` }
|
|
56
|
+
: { id: 'node', status: 'fail', detail: `Node.js ${node} is older than ${MIN_NODE}`, fix: `Install Node.js ${MIN_NODE} or newer` });
|
|
57
|
+
const local = findHippoStoreDir(cwd);
|
|
58
|
+
const globalRoot = getGlobalRoot();
|
|
59
|
+
const hasGlobal = isInitialized(globalRoot);
|
|
60
|
+
let store = null;
|
|
61
|
+
if (local !== null) {
|
|
62
|
+
store = local;
|
|
63
|
+
checks.push({ id: 'store', status: 'pass', detail: `project store at ${local}${hasGlobal ? ` (global store at ${globalRoot} too)` : ''}` });
|
|
64
|
+
}
|
|
65
|
+
else if (hasGlobal) {
|
|
66
|
+
store = globalRoot;
|
|
67
|
+
checks.push({ id: 'store', status: 'warn', detail: `no project store here; using the global store at ${globalRoot}`, fix: 'hippo init (in the project root)' });
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
checks.push({ id: 'store', status: 'fail', detail: 'no hippo store found (project or global)', fix: 'hippo init (in the project root), or hippo init --global' });
|
|
71
|
+
}
|
|
72
|
+
if (store !== null) {
|
|
73
|
+
let db = null;
|
|
74
|
+
try {
|
|
75
|
+
db = openHippoDb(store);
|
|
76
|
+
const have = getSchemaVersion(db);
|
|
77
|
+
const want = getCurrentSchemaVersion();
|
|
78
|
+
checks.push(have === want
|
|
79
|
+
? { id: 'schema', status: 'pass', detail: `database schema v${have}` }
|
|
80
|
+
: have > want
|
|
81
|
+
? { id: 'schema', status: 'fail', detail: `database schema v${have} is newer than this hippo (v${want})`, fix: 'npm install -g hippo-memory@latest' }
|
|
82
|
+
: { id: 'schema', status: 'info', detail: `database schema v${have}; hippo migrates it to v${want} on the next write` });
|
|
83
|
+
const memories = countRows(db, 'memories');
|
|
84
|
+
const dormant = countRows(db, 'dormant_memories');
|
|
85
|
+
const memoryCheck = { id: 'memories', status: 'info', detail: `${memories ?? '?'} memories${dormant !== null ? `, ${dormant} dormant` : ''}` };
|
|
86
|
+
if (memories === 0) {
|
|
87
|
+
memoryCheck.status = 'warn';
|
|
88
|
+
memoryCheck.fix = 'hippo learn --git (seed lessons from git history)';
|
|
89
|
+
}
|
|
90
|
+
checks.push(memoryCheck);
|
|
91
|
+
const since = new Date(now.getTime() - 7 * 86_400_000).toISOString();
|
|
92
|
+
try {
|
|
93
|
+
// SAFETY: COUNT/SUM aggregate row.
|
|
94
|
+
const row = db.prepare(`SELECT COUNT(*) AS n, COALESCE(SUM(tokens), 0) AS t FROM token_ledger WHERE ts >= ? AND event = 'inject'`).get(since);
|
|
95
|
+
checks.push({ id: 'tokens', status: 'info', detail: `${Number(row?.n ?? 0)} memory blocks sent to agents in 7 days, about ${Number(row?.t ?? 0)} tokens (hippo tokens for detail)` });
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
checks.push({ id: 'tokens', status: 'info', detail: 'no token ledger yet (created on the next write)' });
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
checks.push({ id: 'schema', status: 'fail', detail: `cannot open the database: ${err instanceof Error ? err.message : String(err)}`, fix: 'check file permissions on the .hippo folder' });
|
|
103
|
+
}
|
|
104
|
+
finally {
|
|
105
|
+
if (db !== null)
|
|
106
|
+
closeHippoDb(db);
|
|
107
|
+
}
|
|
108
|
+
try {
|
|
109
|
+
const runs = loadStats(store)['consolidation_runs'];
|
|
110
|
+
const last = Array.isArray(runs) && runs.length > 0 ? runs[runs.length - 1] : null;
|
|
111
|
+
// SAFETY: the constructor check above narrows `last` to a plain JSON object.
|
|
112
|
+
const ts = last !== null && last !== undefined && !Array.isArray(last) && last.constructor === Object ? last.timestamp : undefined;
|
|
113
|
+
const when = ts !== undefined && ts !== null ? Date.parse(String(ts)) : Number.NaN;
|
|
114
|
+
if (Number.isNaN(when)) {
|
|
115
|
+
checks.push({ id: 'sleep', status: 'warn', detail: 'hippo has never slept (consolidated) in this store', fix: 'hippo sleep (the session-end hook runs it automatically)' });
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
const days = Math.floor((now.getTime() - when) / 86_400_000);
|
|
119
|
+
checks.push(days > 7
|
|
120
|
+
? { id: 'sleep', status: 'warn', detail: `last sleep ${days} days ago`, fix: 'hippo sleep, and check the session-end hook is installed' }
|
|
121
|
+
: { id: 'sleep', status: 'pass', detail: `last sleep ${days === 0 ? 'today' : `${days} day${days === 1 ? '' : 's'} ago`}` });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
checks.push({ id: 'sleep', status: 'info', detail: 'sleep history unavailable' });
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
const claudeDir = path.join(home, '.claude');
|
|
129
|
+
if (fs.existsSync(claudeDir)) {
|
|
130
|
+
const settings = readJson(path.join(claudeDir, 'settings.json'));
|
|
131
|
+
const text = settings === null ? '' : JSON.stringify(settings);
|
|
132
|
+
const viaPlugin = /hippo-memory@/.test(text);
|
|
133
|
+
// Each hook and what it does, so a partial install says what is missing.
|
|
134
|
+
const hooks = [
|
|
135
|
+
['hippo context --pinned-only', 'per-prompt memory'],
|
|
136
|
+
['hippo session-end', 'session-end capture and sleep'],
|
|
137
|
+
['hippo pre-compact', 'compaction snapshot and capture'],
|
|
138
|
+
['hippo compact-resume', 'resume after compaction'],
|
|
139
|
+
['hippo post-compact', 'the message after compaction'],
|
|
140
|
+
['hippo capture-error', 'failed-tool capture'],
|
|
141
|
+
];
|
|
142
|
+
const missing = hooks.filter(([marker]) => !text.includes(marker)).map(([, what]) => what);
|
|
143
|
+
if (viaPlugin) {
|
|
144
|
+
checks.push({ id: 'claude-code', status: 'pass', detail: 'Claude Code: hippo plugin enabled (all hooks, including compaction and failed-tool capture)' });
|
|
145
|
+
}
|
|
146
|
+
else if (missing.length === 0) {
|
|
147
|
+
checks.push({ id: 'claude-code', status: 'pass', detail: 'Claude Code: all hippo hooks installed, including compaction and failed-tool capture' });
|
|
148
|
+
}
|
|
149
|
+
else if (missing.length === hooks.length) {
|
|
150
|
+
checks.push({ id: 'claude-code', status: 'warn', detail: 'Claude Code found, but no hippo hooks are installed', fix: 'hippo hook install claude-code' });
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
checks.push({ id: 'claude-code', status: 'warn', detail: `Claude Code: hippo hooks missing for ${missing.join(', ')}`, fix: 'hippo hook install claude-code (adds only what is missing)' });
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
checks.push({ id: 'claude-code', status: 'info', detail: 'Claude Code not found; other agents can use hippo over MCP (hippo mcp)' });
|
|
158
|
+
}
|
|
159
|
+
checks.push({ id: 'embeddings', status: 'info', detail: isEmbeddingAvailable() ? 'local embeddings available (hybrid search)' : 'embeddings not installed; recall uses BM25 (optional: hippo embed --help)' });
|
|
160
|
+
return { ok: !checks.some((c) => c.status === 'fail'), version: opts.version, store, checks };
|
|
161
|
+
}
|
|
162
|
+
/** Human-readable rendering of a {@link DoctorReport}. */
|
|
163
|
+
export function formatDoctor(report) {
|
|
164
|
+
const mark = { pass: 'ok ', warn: 'warn', fail: 'FAIL', info: 'info' };
|
|
165
|
+
const lines = [`hippo ${report.version} doctor`, ''];
|
|
166
|
+
for (const c of report.checks) {
|
|
167
|
+
lines.push(` [${mark[c.status]}] ${c.id.padEnd(11)} ${c.detail}`);
|
|
168
|
+
if (c.fix && (c.status === 'warn' || c.status === 'fail'))
|
|
169
|
+
lines.push(` ${''.padEnd(11)} fix: ${c.fix}`);
|
|
170
|
+
}
|
|
171
|
+
lines.push('', report.ok ? 'No failures.' : 'Some checks failed; run the fix commands above.');
|
|
172
|
+
return lines.join('\n');
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dormant memories: what sleep does with a faded memory instead of deleting
|
|
3
|
+
* it (config `dormant.enabled`, on by default; `retentionDays` bounds how
|
|
4
|
+
* long one is kept).
|
|
5
|
+
*
|
|
6
|
+
* A dormant memory keeps its full content in `dormant_memories` (schema v44)
|
|
7
|
+
* but is no longer a `memories` row, so recall, context, every sleep pass and
|
|
8
|
+
* every other reader of `memories` stop seeing it exactly as if it had been
|
|
9
|
+
* deleted. `hippo dormant` lists and searches them, `hippo dormant restore`
|
|
10
|
+
* brings one back, `hippo dormant forget` deletes one for good.
|
|
11
|
+
*
|
|
12
|
+
* Not to be confused with the raw archive (`raw_archive`, `archiveRawMemory`,
|
|
13
|
+
* `hippo forget --archive`): that path removes a raw receipt's content and
|
|
14
|
+
* keeps only its metadata. A dormant memory keeps its content.
|
|
15
|
+
*
|
|
16
|
+
* DB-only helpers: the caller owns the handle and any transaction. The
|
|
17
|
+
* tenant-scoped entry points are api.listDormant / restoreDormant /
|
|
18
|
+
* forgetDormant.
|
|
19
|
+
*/
|
|
20
|
+
import type { DatabaseSyncLike } from './db.js';
|
|
21
|
+
import type { MemoryEntry } from './memory.js';
|
|
22
|
+
/** Why sleep made a memory dormant. Only the decay pass does today. */
|
|
23
|
+
export type DormantReason = 'decay';
|
|
24
|
+
/** One memory that sleep is moving out of active memory into the dormant store. */
|
|
25
|
+
export interface DormantMove {
|
|
26
|
+
/** The memory as it stood when it faded; restored verbatim apart from its recall clock. */
|
|
27
|
+
entry: MemoryEntry;
|
|
28
|
+
/** Live strength at the moment it went dormant (below the decay threshold). */
|
|
29
|
+
strength: number;
|
|
30
|
+
reason: DormantReason;
|
|
31
|
+
/** ISO time of the sleep that made it dormant. */
|
|
32
|
+
dormantAt: string;
|
|
33
|
+
}
|
|
34
|
+
/** A dormant memory as listed to a user. */
|
|
35
|
+
export interface DormantMemory {
|
|
36
|
+
id: string;
|
|
37
|
+
tenantId: string;
|
|
38
|
+
content: string;
|
|
39
|
+
tags: string[];
|
|
40
|
+
/** Live strength when it went dormant. */
|
|
41
|
+
strength: number;
|
|
42
|
+
/** Why it went dormant (`decay`). */
|
|
43
|
+
reason: string;
|
|
44
|
+
/** ISO time it went dormant. */
|
|
45
|
+
dormantAt: string;
|
|
46
|
+
}
|
|
47
|
+
/** Options for {@link listDormantRows}. */
|
|
48
|
+
export interface ListDormantOpts {
|
|
49
|
+
/** Whitespace-separated terms; a row must contain every term (case-insensitive substring). */
|
|
50
|
+
query?: string;
|
|
51
|
+
/** Maximum rows returned, newest first. Default 20. */
|
|
52
|
+
limit?: number;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Insert (or refresh) the dormant snapshot for `move.entry`. Does not touch
|
|
56
|
+
* the `memories` row: the caller deletes it in the same transaction, so the
|
|
57
|
+
* memory is never in both places or in neither.
|
|
58
|
+
*/
|
|
59
|
+
export declare function insertDormantRow(db: DatabaseSyncLike, move: DormantMove): void;
|
|
60
|
+
/** A tenant's dormant memories, newest first, optionally filtered by search terms. */
|
|
61
|
+
export declare function listDormantRows(db: DatabaseSyncLike, tenantId: string, opts?: ListDormantOpts): DormantMemory[];
|
|
62
|
+
/** A dormant memory's stored snapshot plus when and why it went dormant. */
|
|
63
|
+
export interface DormantSnapshot {
|
|
64
|
+
entry: MemoryEntry;
|
|
65
|
+
reason: string;
|
|
66
|
+
strength: number;
|
|
67
|
+
dormantAt: string;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* The stored snapshot for a tenant's dormant memory, or null when the tenant
|
|
71
|
+
* has no dormant memory with that id (another tenant's id reads as absent).
|
|
72
|
+
*/
|
|
73
|
+
export declare function readDormantSnapshot(db: DatabaseSyncLike, tenantId: string, id: string): DormantSnapshot | null;
|
|
74
|
+
/** Whether a tenant has a dormant memory with this id (snapshot readable or not). */
|
|
75
|
+
export declare function hasDormantRow(db: DatabaseSyncLike, tenantId: string, id: string): boolean;
|
|
76
|
+
/** Delete a tenant's dormant memory. Returns false when there was none. */
|
|
77
|
+
export declare function deleteDormantRow(db: DatabaseSyncLike, tenantId: string, id: string): boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Delete every dormant memory in the tenant whose content has this rejection
|
|
80
|
+
* digest, so a rejected value cannot linger in dormant storage. Returns the
|
|
81
|
+
* ids removed. Same O(N) scan as the live-row sweep in reject-flow.ts.
|
|
82
|
+
*/
|
|
83
|
+
export declare function purgeDormantByDigest(db: DatabaseSyncLike, tenantId: string, digest: string): string[];
|
|
84
|
+
/** How many dormant memories went dormant before `cutoffIso` (a dry-run count). */
|
|
85
|
+
export declare function countExpiredDormant(db: DatabaseSyncLike, cutoffIso: string): number;
|
|
86
|
+
/**
|
|
87
|
+
* Delete every dormant memory (all tenants) that went dormant before
|
|
88
|
+
* `cutoffIso`: the `dormant.retentionDays` window. Returns how many went.
|
|
89
|
+
*/
|
|
90
|
+
export declare function purgeExpiredDormant(db: DatabaseSyncLike, cutoffIso: string): number;
|
|
91
|
+
//# sourceMappingURL=dormant.d.ts.map
|
package/dist/dormant.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { rejectionDigest } from './rejection.js';
|
|
2
|
+
const DEFAULT_LIST_LIMIT = 20;
|
|
3
|
+
/**
|
|
4
|
+
* Insert (or refresh) the dormant snapshot for `move.entry`. Does not touch
|
|
5
|
+
* the `memories` row: the caller deletes it in the same transaction, so the
|
|
6
|
+
* memory is never in both places or in neither.
|
|
7
|
+
*/
|
|
8
|
+
export function insertDormantRow(db, move) {
|
|
9
|
+
db.prepare(`
|
|
10
|
+
INSERT INTO dormant_memories (tenant_id, id, content, entry_json, reason, strength, dormant_at)
|
|
11
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
12
|
+
ON CONFLICT(tenant_id, id) DO UPDATE SET
|
|
13
|
+
content = excluded.content,
|
|
14
|
+
entry_json = excluded.entry_json,
|
|
15
|
+
reason = excluded.reason,
|
|
16
|
+
strength = excluded.strength,
|
|
17
|
+
dormant_at = excluded.dormant_at
|
|
18
|
+
`).run(move.entry.tenantId, move.entry.id, move.entry.content, JSON.stringify(move.entry), move.reason, move.strength, move.dormantAt);
|
|
19
|
+
}
|
|
20
|
+
/** Escape LIKE metacharacters so a search term matches literally (ESCAPE '\'). */
|
|
21
|
+
function escapeLike(term) {
|
|
22
|
+
return term.replace(/[\\%_]/g, (ch) => `\\${ch}`);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Parse a stored snapshot back into a MemoryEntry, or null when the row no
|
|
26
|
+
* longer matches the snapshot it carries (edited by hand, or truncated).
|
|
27
|
+
*/
|
|
28
|
+
function parseSnapshot(row) {
|
|
29
|
+
try {
|
|
30
|
+
// SAFETY: entry_json is only written by insertDormantRow from a MemoryEntry;
|
|
31
|
+
// the id / tenant / content checks below reject a row edited out of shape.
|
|
32
|
+
const entry = JSON.parse(row.entry_json);
|
|
33
|
+
if (entry.id !== row.id || entry.tenantId !== row.tenant_id || entry.content !== row.content) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
return entry;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function rowToDormantMemory(row) {
|
|
43
|
+
const entry = parseSnapshot(row);
|
|
44
|
+
return {
|
|
45
|
+
id: row.id,
|
|
46
|
+
tenantId: row.tenant_id,
|
|
47
|
+
content: row.content,
|
|
48
|
+
tags: entry && Array.isArray(entry.tags) ? entry.tags.map(String) : [],
|
|
49
|
+
strength: row.strength,
|
|
50
|
+
reason: row.reason,
|
|
51
|
+
dormantAt: row.dormant_at,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/** A tenant's dormant memories, newest first, optionally filtered by search terms. */
|
|
55
|
+
export function listDormantRows(db, tenantId, opts = {}) {
|
|
56
|
+
const terms = (opts.query ?? '').trim().split(/\s+/).filter((t) => t.length > 0);
|
|
57
|
+
const limit = opts.limit !== undefined && Number.isFinite(opts.limit) && opts.limit >= 1
|
|
58
|
+
? Math.floor(opts.limit)
|
|
59
|
+
: DEFAULT_LIST_LIMIT;
|
|
60
|
+
const termClauses = terms.map(() => ` AND content LIKE ? ESCAPE '\\'`).join('');
|
|
61
|
+
// SAFETY: rows' shape matches the seven columns named in the SELECT.
|
|
62
|
+
const rows = db.prepare(`SELECT tenant_id, id, content, entry_json, reason, strength, dormant_at
|
|
63
|
+
FROM dormant_memories
|
|
64
|
+
WHERE tenant_id = ?${termClauses}
|
|
65
|
+
ORDER BY dormant_at DESC, id ASC
|
|
66
|
+
LIMIT ?`).all(tenantId, ...terms.map((t) => `%${escapeLike(t)}%`), limit);
|
|
67
|
+
return rows.map(rowToDormantMemory);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* The stored snapshot for a tenant's dormant memory, or null when the tenant
|
|
71
|
+
* has no dormant memory with that id (another tenant's id reads as absent).
|
|
72
|
+
*/
|
|
73
|
+
export function readDormantSnapshot(db, tenantId, id) {
|
|
74
|
+
// SAFETY: row's shape matches the seven columns named in the SELECT.
|
|
75
|
+
const row = db.prepare(`SELECT tenant_id, id, content, entry_json, reason, strength, dormant_at
|
|
76
|
+
FROM dormant_memories WHERE tenant_id = ? AND id = ?`).get(tenantId, id);
|
|
77
|
+
const entry = row ? parseSnapshot(row) : null;
|
|
78
|
+
return row && entry ? { entry, reason: row.reason, strength: row.strength, dormantAt: row.dormant_at } : null;
|
|
79
|
+
}
|
|
80
|
+
/** Whether a tenant has a dormant memory with this id (snapshot readable or not). */
|
|
81
|
+
export function hasDormantRow(db, tenantId, id) {
|
|
82
|
+
return db.prepare(`SELECT 1 FROM dormant_memories WHERE tenant_id = ? AND id = ?`).get(tenantId, id) !== undefined;
|
|
83
|
+
}
|
|
84
|
+
/** Delete a tenant's dormant memory. Returns false when there was none. */
|
|
85
|
+
export function deleteDormantRow(db, tenantId, id) {
|
|
86
|
+
const result = db.prepare(`DELETE FROM dormant_memories WHERE tenant_id = ? AND id = ?`).run(tenantId, id);
|
|
87
|
+
return Number(result.changes ?? 0) > 0;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Delete every dormant memory in the tenant whose content has this rejection
|
|
91
|
+
* digest, so a rejected value cannot linger in dormant storage. Returns the
|
|
92
|
+
* ids removed. Same O(N) scan as the live-row sweep in reject-flow.ts.
|
|
93
|
+
*/
|
|
94
|
+
export function purgeDormantByDigest(db, tenantId, digest) {
|
|
95
|
+
// SAFETY: rows' shape matches the two columns named in the SELECT.
|
|
96
|
+
const rows = db.prepare(`SELECT id, content FROM dormant_memories WHERE tenant_id = ?`)
|
|
97
|
+
.all(tenantId);
|
|
98
|
+
const removed = [];
|
|
99
|
+
for (const row of rows) {
|
|
100
|
+
if (rejectionDigest(row.content) !== digest)
|
|
101
|
+
continue;
|
|
102
|
+
deleteDormantRow(db, tenantId, row.id);
|
|
103
|
+
removed.push(row.id);
|
|
104
|
+
}
|
|
105
|
+
return removed;
|
|
106
|
+
}
|
|
107
|
+
/** How many dormant memories went dormant before `cutoffIso` (a dry-run count). */
|
|
108
|
+
export function countExpiredDormant(db, cutoffIso) {
|
|
109
|
+
// SAFETY: row's shape matches the single aliased COUNT column in the SELECT.
|
|
110
|
+
const row = db.prepare(`SELECT COUNT(*) AS n FROM dormant_memories WHERE dormant_at < ?`).get(cutoffIso);
|
|
111
|
+
return Number(row.n);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Delete every dormant memory (all tenants) that went dormant before
|
|
115
|
+
* `cutoffIso`: the `dormant.retentionDays` window. Returns how many went.
|
|
116
|
+
*/
|
|
117
|
+
export function purgeExpiredDormant(db, cutoffIso) {
|
|
118
|
+
const result = db.prepare(`DELETE FROM dormant_memories WHERE dormant_at < ?`).run(cutoffIso);
|
|
119
|
+
return Number(result.changes ?? 0);
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=dormant.js.map
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
*/
|
|
32
32
|
import { getEmbedding, isEmbeddingAvailable, resolveEmbeddingModel, DEFAULT_EMBEDDING_MODEL, } from './embeddings.js';
|
|
33
33
|
import { loadConfig } from './config.js';
|
|
34
|
+
import { redactSecrets } from './secret-detect.js';
|
|
34
35
|
export const API_PROVIDER_KINDS = ['openai', 'voyage', 'cohere'];
|
|
35
36
|
function isApiProviderKind(x) {
|
|
36
37
|
return x === 'openai' || x === 'voyage' || x === 'cohere';
|
|
@@ -188,7 +189,7 @@ class ApiEmbeddingProvider {
|
|
|
188
189
|
'content-type': 'application/json',
|
|
189
190
|
authorization: `Bearer ${key}`,
|
|
190
191
|
},
|
|
191
|
-
body: JSON.stringify(spec.buildBody(this.model, chunk, role)),
|
|
192
|
+
body: JSON.stringify(spec.buildBody(this.model, chunk.map(redactSecrets), role)),
|
|
192
193
|
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
|
|
193
194
|
});
|
|
194
195
|
}
|
package/dist/embeddings.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import * as fs from 'fs';
|
|
7
7
|
import * as path from 'path';
|
|
8
|
+
import { randomUUID } from 'crypto';
|
|
8
9
|
import { createRequire } from 'module';
|
|
9
10
|
import { loadAllEntries } from './store.js';
|
|
10
11
|
import { openHippoDb, closeHippoDb, getMeta, setMeta } from './db.js';
|
|
@@ -244,13 +245,13 @@ export function saveStoredEmbeddingModel(hippoRoot, model) {
|
|
|
244
245
|
closeHippoDb(db);
|
|
245
246
|
}
|
|
246
247
|
}
|
|
247
|
-
export function resolveIndexedEmbeddingModel(hippoRoot, index
|
|
248
|
+
export function resolveIndexedEmbeddingModel(hippoRoot, index) {
|
|
248
249
|
const stored = loadStoredEmbeddingModel(hippoRoot);
|
|
249
250
|
if (stored)
|
|
250
251
|
return stored;
|
|
251
|
-
return Object.keys(index).length > 0 ? DEFAULT_EMBEDDING_MODEL : null;
|
|
252
|
+
return Object.keys(index ?? loadEmbeddingIndex(hippoRoot)).length > 0 ? DEFAULT_EMBEDDING_MODEL : null;
|
|
252
253
|
}
|
|
253
|
-
export function embeddingModelRequiresReindex(hippoRoot, model, index
|
|
254
|
+
export function embeddingModelRequiresReindex(hippoRoot, model, index) {
|
|
254
255
|
const stored = resolveIndexedEmbeddingModel(hippoRoot, index);
|
|
255
256
|
return stored !== null && stored !== embeddingIndexIdentity(model);
|
|
256
257
|
}
|
|
@@ -374,16 +375,86 @@ export function saveEmbeddingIndex(hippoRoot, index) {
|
|
|
374
375
|
throw err;
|
|
375
376
|
}
|
|
376
377
|
}
|
|
377
|
-
|
|
378
|
+
const EMBED_LOCK_FILE = 'embeddings.lock';
|
|
379
|
+
const EMBED_LOCK_WAIT_MS = 10_000;
|
|
380
|
+
const EMBED_LOCK_OWNER = `${process.pid}:${randomUUID()}`;
|
|
381
|
+
// In-process mutex plus an O_EXCL "<pid>:<token>" lock file: our token is a lock we leaked; our PID with another token is a live worker thread, unless the lock predates this process (a reused PID).
|
|
378
382
|
let _embedWriteLock = Promise.resolve();
|
|
379
|
-
|
|
383
|
+
function embedLockHolderAlive(lockPath) {
|
|
384
|
+
let raw;
|
|
385
|
+
try {
|
|
386
|
+
raw = fs.readFileSync(lockPath, 'utf8');
|
|
387
|
+
}
|
|
388
|
+
catch (err) {
|
|
389
|
+
return !(err instanceof Error && 'code' in err && err.code === 'ENOENT');
|
|
390
|
+
}
|
|
391
|
+
const mtimeMs = fs.statSync(lockPath, { throwIfNoEntry: false })?.mtimeMs ?? 0;
|
|
392
|
+
const pid = Number(raw.split(':')[0]);
|
|
393
|
+
// An empty lock is a holder between create and write; after 5 s it is a crashed one.
|
|
394
|
+
if (!Number.isInteger(pid) || pid <= 0)
|
|
395
|
+
return Date.now() - mtimeMs < 5_000;
|
|
396
|
+
if (raw === EMBED_LOCK_OWNER)
|
|
397
|
+
return false;
|
|
398
|
+
if (pid === process.pid)
|
|
399
|
+
return mtimeMs >= Date.now() - process.uptime() * 1000;
|
|
400
|
+
try {
|
|
401
|
+
process.kill(pid, 0);
|
|
402
|
+
return true;
|
|
403
|
+
}
|
|
404
|
+
catch (err) {
|
|
405
|
+
return err instanceof Error && 'code' in err && err.code === 'EPERM';
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
// After the double-break race below the file can be another writer's lock, so remove only our own.
|
|
409
|
+
function releaseEmbedFileLock(lockPath) {
|
|
410
|
+
let raw;
|
|
411
|
+
try {
|
|
412
|
+
raw = fs.readFileSync(lockPath, 'utf8');
|
|
413
|
+
}
|
|
414
|
+
catch (err) {
|
|
415
|
+
if (err instanceof Error && 'code' in err && err.code === 'ENOENT')
|
|
416
|
+
return;
|
|
417
|
+
throw err;
|
|
418
|
+
}
|
|
419
|
+
if (raw === EMBED_LOCK_OWNER)
|
|
420
|
+
fs.rmSync(lockPath, { force: true });
|
|
421
|
+
}
|
|
422
|
+
async function acquireEmbedFileLock(hippoRoot) {
|
|
423
|
+
const lockPath = path.join(hippoRoot, EMBED_LOCK_FILE);
|
|
424
|
+
const deadline = Date.now() + EMBED_LOCK_WAIT_MS;
|
|
425
|
+
for (;;) {
|
|
426
|
+
try {
|
|
427
|
+
fs.writeFileSync(lockPath, EMBED_LOCK_OWNER, { flag: 'wx' });
|
|
428
|
+
return () => releaseEmbedFileLock(lockPath);
|
|
429
|
+
}
|
|
430
|
+
catch (err) {
|
|
431
|
+
if (!(err instanceof Error && 'code' in err && err.code === 'EEXIST'))
|
|
432
|
+
throw err;
|
|
433
|
+
}
|
|
434
|
+
// SHORTCUT: two waiters can both break one dead holder's lock; a vector lost that way is backfilled by the next `hippo embed`.
|
|
435
|
+
if (!embedLockHolderAlive(lockPath)) {
|
|
436
|
+
fs.rmSync(lockPath, { force: true });
|
|
437
|
+
continue;
|
|
438
|
+
}
|
|
439
|
+
if (Date.now() >= deadline)
|
|
440
|
+
throw new Error(`embeddings.json is busy: another hippo process holds ${lockPath}`);
|
|
441
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
async function withEmbedLock(hippoRoot, fn) {
|
|
380
445
|
let resolve;
|
|
381
446
|
const next = new Promise(r => { resolve = r; });
|
|
382
447
|
const prev = _embedWriteLock;
|
|
383
448
|
_embedWriteLock = next;
|
|
384
449
|
await prev;
|
|
385
450
|
try {
|
|
386
|
-
|
|
451
|
+
const release = await acquireEmbedFileLock(hippoRoot);
|
|
452
|
+
try {
|
|
453
|
+
return await fn();
|
|
454
|
+
}
|
|
455
|
+
finally {
|
|
456
|
+
release();
|
|
457
|
+
}
|
|
387
458
|
}
|
|
388
459
|
finally {
|
|
389
460
|
resolve();
|
|
@@ -396,7 +467,7 @@ export async function embedMemory(hippoRoot, entry, model) {
|
|
|
396
467
|
const provider = resolveEmbeddingProvider(hippoRoot, { model });
|
|
397
468
|
if (!provider.isAvailable())
|
|
398
469
|
return;
|
|
399
|
-
return withEmbedLock(async () => {
|
|
470
|
+
return withEmbedLock(hippoRoot, async () => {
|
|
400
471
|
// embedMemory is best-effort: an embedding failure (API down / bad key / 5xx)
|
|
401
472
|
// must not reject the caller's write — `getEmbedding` historically swallowed
|
|
402
473
|
// failures and returned []. The explicit `hippo embed` / `embedAll` path is
|
|
@@ -445,6 +516,8 @@ export async function embedMemory(hippoRoot, entry, model) {
|
|
|
445
516
|
catch {
|
|
446
517
|
// Provider failure (API down / bad key). Best-effort: leave the index as-is.
|
|
447
518
|
}
|
|
519
|
+
}).catch((err) => {
|
|
520
|
+
console.error(`hippo: skipped embedding ${entry.id} (${err instanceof Error ? err.message : String(err)}); run 'hippo embed' to backfill`);
|
|
448
521
|
});
|
|
449
522
|
}
|
|
450
523
|
/**
|
|
@@ -468,7 +541,7 @@ export async function embedAll(hippoRoot, model) {
|
|
|
468
541
|
}
|
|
469
542
|
return 0;
|
|
470
543
|
}
|
|
471
|
-
return withEmbedLock(async () => {
|
|
544
|
+
return withEmbedLock(hippoRoot, async () => {
|
|
472
545
|
const identity = provider.id;
|
|
473
546
|
// L9: host-wide by design. embedAll backfills vectors for all tenants'
|
|
474
547
|
// entries into the per-host embedding index. Per-tenant filtering would
|
|
@@ -0,0 +1,123 @@
|
|
|
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
|
+
/** Token usage for one model call or one whole task, split by how it is billed. */
|
|
16
|
+
export interface Usage {
|
|
17
|
+
/** Input tokens billed at the base input price (not read from or written to a cache). */
|
|
18
|
+
inputTokens: number;
|
|
19
|
+
/** Input tokens written to a prompt cache. */
|
|
20
|
+
cacheWriteTokens: number;
|
|
21
|
+
/** Input tokens read from a prompt cache. */
|
|
22
|
+
cacheReadTokens: number;
|
|
23
|
+
/** Output tokens, including any reasoning tokens the provider bills as output. */
|
|
24
|
+
outputTokens: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Prices in dollars per million tokens. Take them from the provider's
|
|
28
|
+
* current price page for the exact model; this module has no built-in
|
|
29
|
+
* prices because they change.
|
|
30
|
+
*/
|
|
31
|
+
export interface Prices {
|
|
32
|
+
inputPerMTok: number;
|
|
33
|
+
cacheWritePerMTok: number;
|
|
34
|
+
cacheReadPerMTok: number;
|
|
35
|
+
outputPerMTok: number;
|
|
36
|
+
}
|
|
37
|
+
/** Sum several usages bucket by bucket. */
|
|
38
|
+
export declare function addUsage(...usages: Usage[]): Usage;
|
|
39
|
+
/** Dollar cost of `usage` at `prices`. */
|
|
40
|
+
export declare function priceUsage(usage: Usage, prices: Prices): number;
|
|
41
|
+
/**
|
|
42
|
+
* Relative prices of the cache buckets against the base input price, for
|
|
43
|
+
* cost in "uncached-equivalent tokens" when no dollar prices are given.
|
|
44
|
+
* Defaults follow Anthropic's published ratios (5-minute cache write 1.25x,
|
|
45
|
+
* cache read 0.1x); pass the ratios for another provider when needed.
|
|
46
|
+
*/
|
|
47
|
+
export interface CacheRatios {
|
|
48
|
+
write: number;
|
|
49
|
+
read: number;
|
|
50
|
+
}
|
|
51
|
+
/** Default cache price ratios (write 1.25x, read 0.1x of base input). */
|
|
52
|
+
export declare const DEFAULT_CACHE_RATIOS: Readonly<CacheRatios>;
|
|
53
|
+
/** Input cost of `usage` in uncached-equivalent tokens (output excluded). */
|
|
54
|
+
export declare function uncachedEquivalentInput(usage: Usage, ratios?: CacheRatios): number;
|
|
55
|
+
/**
|
|
56
|
+
* Mulberry32: a small seeded PRNG returning floats in [0, 1). Same seed,
|
|
57
|
+
* same stream, on every platform.
|
|
58
|
+
*/
|
|
59
|
+
export declare function seededRandom(seed: number): () => number;
|
|
60
|
+
/** A point estimate with a percentile bootstrap confidence interval. */
|
|
61
|
+
export interface Estimate {
|
|
62
|
+
estimate: number;
|
|
63
|
+
low: number;
|
|
64
|
+
high: number;
|
|
65
|
+
/** Resamples drawn. */
|
|
66
|
+
iterations: number;
|
|
67
|
+
}
|
|
68
|
+
/** Options shared by the bootstrap functions. */
|
|
69
|
+
export interface BootstrapOpts {
|
|
70
|
+
/** Resamples. Default 5000. */
|
|
71
|
+
iterations?: number;
|
|
72
|
+
/** Two-sided level, e.g. 0.05 for a 95% interval. Default 0.05. */
|
|
73
|
+
alpha?: number;
|
|
74
|
+
/** PRNG seed. Default 1. */
|
|
75
|
+
seed?: number;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Paired bootstrap for the mean of per-task differences (treatment minus
|
|
79
|
+
* control on the same task). An interval that excludes zero is the bar for
|
|
80
|
+
* calling a difference real.
|
|
81
|
+
*/
|
|
82
|
+
export declare function pairedBootstrap(diffs: number[], opts?: BootstrapOpts): Estimate;
|
|
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 declare function clusteredPairedBootstrap(diffsByCluster: ReadonlyMap<string, number[]>, opts?: BootstrapOpts): Estimate;
|
|
89
|
+
/** One task's outcome in one arm, for {@link costPerResolvedDelta}. */
|
|
90
|
+
export interface ArmOutcome {
|
|
91
|
+
/** Dollars (or uncached-equivalent tokens) spent on the task. */
|
|
92
|
+
cost: number;
|
|
93
|
+
/** Whether the task was resolved. */
|
|
94
|
+
resolved: boolean;
|
|
95
|
+
}
|
|
96
|
+
/** Result of {@link costPerResolvedDelta}. */
|
|
97
|
+
export interface CostPerResolvedDelta {
|
|
98
|
+
control: number;
|
|
99
|
+
treatment: number;
|
|
100
|
+
/** treatment minus control, with its interval. */
|
|
101
|
+
delta: Estimate;
|
|
102
|
+
/** (treatment minus control) / control, with its interval. Negative is a saving. */
|
|
103
|
+
relative: Estimate;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Cost per resolved task in two arms run on the same tasks, with a paired
|
|
107
|
+
* bootstrap over tasks (a task is resampled with both of its arm outcomes).
|
|
108
|
+
* `control[i]` and `treatment[i]` must be the same task. Resamples in which
|
|
109
|
+
* an arm resolves nothing are dropped; `iterations` reports how many were
|
|
110
|
+
* kept.
|
|
111
|
+
*/
|
|
112
|
+
export declare function costPerResolvedDelta(control: ArmOutcome[], treatment: ArmOutcome[], opts?: BootstrapOpts): CostPerResolvedDelta;
|
|
113
|
+
/**
|
|
114
|
+
* pass@k: share of tasks with at least one success in their first k runs.
|
|
115
|
+
* NaN when no task has k runs (not measured, which is not the same as 0).
|
|
116
|
+
*/
|
|
117
|
+
export declare function passAtK(runsByTask: boolean[][], k: number): number;
|
|
118
|
+
/**
|
|
119
|
+
* pass^k: share of tasks whose first k runs all succeed (consistency).
|
|
120
|
+
* NaN when no task has k runs.
|
|
121
|
+
*/
|
|
122
|
+
export declare function passHatK(runsByTask: boolean[][], k: number): number;
|
|
123
|
+
//# sourceMappingURL=eval-stats.d.ts.map
|