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/api.js
CHANGED
|
@@ -8,15 +8,17 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { createHash } from 'node:crypto';
|
|
10
10
|
import { openHippoDb, closeHippoDb } from './db.js';
|
|
11
|
-
import { writeEntry, writeEntryDbOnly, stampOriginProject, writeEntryMirrors, readEntry, deleteEntry, loadRecallSearchEntries, loadEntriesByIds, loadChildrenOf, loadFreshRawMemories, loadSessionRawMemories, countSessionRawMemories, DEFAULT_SEARCH_CANDIDATE_LIMIT, removeEntryMirrors, loadActiveTaskSnapshot, loadFreshActiveTaskSnapshot, loadLatestHandoff, listSessionEvents, SNAPSHOT_AMBIENT_MAX_AGE_MS, loadIndex, saveIndex, loadAllEntries, loadAmbientCandidates, updateStats, isInitialized, markSummaryDirtyInTx, auditRejectionRefusal, } from './store.js';
|
|
11
|
+
import { writeEntry, writeEntryDbOnly, strengthenRetrieved, stampOriginProject, writeEntryMirrors, readEntry, deleteEntry, loadRecallSearchEntries, loadEntriesByIds, loadChildrenOf, loadFreshRawMemories, loadSessionRawMemories, countSessionRawMemories, DEFAULT_SEARCH_CANDIDATE_LIMIT, removeEntryMirrors, loadActiveTaskSnapshot, loadFreshActiveTaskSnapshot, loadLatestHandoff, listSessionEvents, SNAPSHOT_AMBIENT_MAX_AGE_MS, loadIndex, saveIndex, loadAllEntries, loadAmbientCandidates, updateStats, isInitialized, markSummaryDirtyInTx, auditRejectionRefusal, } from './store.js';
|
|
12
12
|
import { RejectedValueError } from './rejection.js';
|
|
13
13
|
import { rejectValue, unrejectValue, listRejectionsForTenant } from './reject-flow.js';
|
|
14
|
+
import { listDormantRows, readDormantSnapshot, deleteDormantRow, hasDormantRow, } from './dormant.js';
|
|
15
|
+
import { recordTokenUse, summarizeTokenUse } from './token-ledger.js';
|
|
14
16
|
import { formatHandoffEvidenceLine } from './handoff.js';
|
|
15
17
|
import { createMemory, applyOutcome, calculateStrength, Layer, } from './memory.js';
|
|
16
18
|
import { appendAuditEvent, queryAuditEvents, auditMemories, isContentWorthStoring, } from './audit.js';
|
|
17
19
|
import { promoteToGlobal, getGlobalRoot, autoShare, searchBothHybrid } from './shared.js';
|
|
18
20
|
import { writeRecallTrace, writeRecallTraceAtRoot, recordTraceOutcome } from './recall-trace.js';
|
|
19
|
-
import { evalNow
|
|
21
|
+
import { evalNow } from './ablation.js';
|
|
20
22
|
import { archiveRawMemory } from './raw-archive.js';
|
|
21
23
|
import { createApiKey, listApiKeys, revokeApiKey, } from './auth.js';
|
|
22
24
|
import { applyGoalStackBoost } from './goals.js';
|
|
@@ -69,6 +71,13 @@ export class RecallContractError extends Error {
|
|
|
69
71
|
this.code = code;
|
|
70
72
|
}
|
|
71
73
|
}
|
|
74
|
+
/** The actor's role or identity does not allow the operation. HTTP maps it to 403. */
|
|
75
|
+
export class ForbiddenError extends Error {
|
|
76
|
+
constructor(message) {
|
|
77
|
+
super(message);
|
|
78
|
+
this.name = 'ForbiddenError';
|
|
79
|
+
}
|
|
80
|
+
}
|
|
72
81
|
// v1.25.0: the recall-side scope predicates (PRIVATE_SCOPE_RE, isPrivateScope,
|
|
73
82
|
// passesScopeFilterForRecall) live in recall-scope.ts (leaf) so shared.ts can
|
|
74
83
|
// apply the same default-deny rule to searchBothHybrid's internal loads
|
|
@@ -77,9 +86,9 @@ export class RecallContractError extends Error {
|
|
|
77
86
|
// back-compat (`api.isPrivateScope`, test imports). NOTE: the import statement
|
|
78
87
|
// is required — a bare `export { x } from` re-export does not bind the local
|
|
79
88
|
// names this module's ~9 call sites use.
|
|
80
|
-
import { isPrivateScope, passesScopeFilterForRecall } from './recall-scope.js';
|
|
89
|
+
import { isPrivateScope, passesScopeFilterForRecall, assertScopeRequestAllowed } from './recall-scope.js';
|
|
81
90
|
export { isPrivateScope, passesScopeFilterForRecall };
|
|
82
|
-
export { passesCliRecallScopeFilter } from './recall-scope.js';
|
|
91
|
+
export { passesCliRecallScopeFilter, ScopeForbiddenError } from './recall-scope.js';
|
|
83
92
|
// v39: classifyOriginProject lives in project-identity.ts (leaf) so
|
|
84
93
|
// shared.ts can use it without an api.ts import cycle. Re-exported here for
|
|
85
94
|
// callers that already import the api surface.
|
|
@@ -137,6 +146,7 @@ export function remember(ctx, opts) {
|
|
|
137
146
|
artifact_ref: opts.artifactRef ?? null,
|
|
138
147
|
tags: opts.tags,
|
|
139
148
|
tenantId: ctx.tenantId,
|
|
149
|
+
baseHalfLifeDays: loadConfig(ctx.hippoRoot).defaultHalfLifeDays,
|
|
140
150
|
});
|
|
141
151
|
// writeEntry threads ctx.actor.subject into its internal audit hook, so exactly
|
|
142
152
|
// one 'remember' event lands in the log with the supplied actor.
|
|
@@ -162,9 +172,8 @@ export function buildSuppressionSummary(counts) {
|
|
|
162
172
|
}
|
|
163
173
|
/**
|
|
164
174
|
* Domain-level recall. Loads BM25-ranked candidates from SQLite scoped to
|
|
165
|
-
* `ctx.tenantId
|
|
166
|
-
*
|
|
167
|
-
* loader; later tasks can extend this to call the physics/hybrid scorer.
|
|
175
|
+
* `ctx.tenantId` and keeps that order whatever `mode` says; `retrieve` is the
|
|
176
|
+
* mode-aware, strengthening variant the HTTP route uses.
|
|
168
177
|
*
|
|
169
178
|
* **api.recall does NOT mutate `index.last_retrieval_ids`** (v1.11.5 contract
|
|
170
179
|
* lock). The CLI `cmdRecall` (cli.ts) writes `last_retrieval_ids` because the
|
|
@@ -177,7 +186,30 @@ export function buildSuppressionSummary(counts) {
|
|
|
177
186
|
* `tests/api-recall-no-side-effects.test.ts`.
|
|
178
187
|
*/
|
|
179
188
|
export function recall(ctx, opts) {
|
|
180
|
-
|
|
189
|
+
// A member key may not unlock a private or quarantined scope by naming it.
|
|
190
|
+
assertScopeRequestAllowed(ctx.actor.role, opts.scope);
|
|
191
|
+
const windowSize = recallWindowSize(opts);
|
|
192
|
+
return recallFrom(ctx, opts, windowSize, loadRecallSearchEntries(ctx.hippoRoot, opts.query, windowSize, ctx.tenantId, opts.scope, 'exact', false));
|
|
193
|
+
}
|
|
194
|
+
/** Mode-aware recall that strengthens each returned row; never writes last_retrieval_ids (v1.11.5 lock). */
|
|
195
|
+
export async function retrieve(ctx, opts) {
|
|
196
|
+
assertScopeRequestAllowed(ctx.actor.role, opts.scope);
|
|
197
|
+
const windowSize = recallWindowSize(opts);
|
|
198
|
+
let candidates = loadRecallSearchEntries(ctx.hippoRoot, opts.query, windowSize, ctx.tenantId, opts.scope, 'exact', false);
|
|
199
|
+
if (opts.mode === 'hybrid' || opts.mode === 'physics') {
|
|
200
|
+
const searchOpts = { budget: Infinity, hippoRoot: ctx.hippoRoot, scope: opts.scope ?? null };
|
|
201
|
+
const ranked = opts.mode === 'physics'
|
|
202
|
+
? await physicsSearch(opts.query, candidates, { ...searchOpts, physicsConfig: loadConfig(ctx.hippoRoot).physics })
|
|
203
|
+
: await hybridSearch(opts.query, candidates, searchOpts);
|
|
204
|
+
const rankedIds = new Set(ranked.map((r) => r.entry.id));
|
|
205
|
+
candidates = [...ranked.map((r) => r.entry), ...candidates.filter((e) => !rankedIds.has(e.id))];
|
|
206
|
+
}
|
|
207
|
+
const result = recallFrom(ctx, opts, windowSize, candidates);
|
|
208
|
+
strengthenRetrieved(ctx.hippoRoot, result.results.map((r) => r.id), ctx.tenantId);
|
|
209
|
+
return result;
|
|
210
|
+
}
|
|
211
|
+
/** Contract preflight: throws before any store-touching work. */
|
|
212
|
+
function recallWindowSize(opts) {
|
|
181
213
|
// F5 (v1.6.5) preflight — codex P1: original guard fired AFTER
|
|
182
214
|
// loadSearchEntries (which runs initStore, migrating legacy state on first
|
|
183
215
|
// call). For a true contract preflight we want the throw before any
|
|
@@ -207,7 +239,10 @@ export function recall(ctx, opts) {
|
|
|
207
239
|
throw new RecallContractError('invalid_scorer_window', `scorerWindow must be a positive integer; got ${opts.scorerWindow}`);
|
|
208
240
|
}
|
|
209
241
|
}
|
|
210
|
-
|
|
242
|
+
return opts.scorerWindow ?? DEFAULT_SEARCH_CANDIDATE_LIMIT;
|
|
243
|
+
}
|
|
244
|
+
function recallFrom(ctx, opts, windowSize, all) {
|
|
245
|
+
const limit = opts.limit ?? 10;
|
|
211
246
|
// v1.7.1 — root-cause fix for the `unknown:legacy` leak. Scope predicate
|
|
212
247
|
// is now pushed into `loadSearchRows` SQL via `loadRecallSearchEntries`.
|
|
213
248
|
// - opts.scope undefined / '': SQL excludes `unknown:legacy`.
|
|
@@ -233,16 +268,16 @@ export function recall(ctx, opts) {
|
|
|
233
268
|
let droppedByBudgetCount = 0;
|
|
234
269
|
let summarySubstitutionsCount = 0;
|
|
235
270
|
let freshTailAddedCount = 0;
|
|
236
|
-
const all = loadRecallSearchEntries(ctx.hippoRoot, opts.query, windowSize, ctx.tenantId, opts.scope);
|
|
237
271
|
// v1.12.13 / C5 — WYSIATI totalCandidates counter (post tenant + SQL scope
|
|
238
272
|
// predicate, pre JS scope filter).
|
|
239
273
|
totalCandidatesCount = all.length;
|
|
274
|
+
const current = all.filter((e) => !e.superseded_by);
|
|
240
275
|
let entries;
|
|
241
276
|
if (opts.scope !== undefined && opts.scope !== '') {
|
|
242
277
|
// SQL already exact-matched in loadRecallSearchEntries; keep the JS
|
|
243
278
|
// filter as defense-in-depth so a future SQL-clause regression cannot
|
|
244
279
|
// silently surface cross-scope rows.
|
|
245
|
-
entries =
|
|
280
|
+
entries = current.filter((e) => e.scope === opts.scope);
|
|
246
281
|
}
|
|
247
282
|
else {
|
|
248
283
|
// SQL already excluded `unknown:legacy` AND (v1.25.0) pre-filtered
|
|
@@ -252,7 +287,7 @@ export function recall(ctx, opts) {
|
|
|
252
287
|
// anchored `<source>:private:*` rule (v1.2.1 generalization) and
|
|
253
288
|
// defense-in-depth: connector authors cannot silently surface private
|
|
254
289
|
// rows to no-scope callers even if the SQL clause regresses.
|
|
255
|
-
entries =
|
|
290
|
+
entries = current.filter((e) => !isPrivateScope(e.scope ?? null));
|
|
256
291
|
}
|
|
257
292
|
// v1.12.13 / C5 — WYSIATI dropped_pre_rank counter (JS scope filter drops
|
|
258
293
|
// for api.recall; cmdRecall pipeline rolls --outcome/--layer/--as-of/etc.
|
|
@@ -326,7 +361,7 @@ export function recall(ctx, opts) {
|
|
|
326
361
|
const eligibleParentIds = Array.from(overflowByParent.keys()).filter((pid) => (overflowByParent.get(pid)?.length ?? 0) >= 2 && !baseIds.has(pid));
|
|
327
362
|
if (eligibleParentIds.length > 0) {
|
|
328
363
|
const parents = loadEntriesByIds(ctx.hippoRoot, eligibleParentIds, ctx.tenantId);
|
|
329
|
-
const eligibleParents = parents.filter((p) => (p.dag_level ?? 0) === 2 && passesScopeFilterForRecall(p.scope ?? null, opts.scope));
|
|
364
|
+
const eligibleParents = parents.filter((p) => (p.dag_level ?? 0) === 2 && !p.superseded_by && passesScopeFilterForRecall(p.scope ?? null, opts.scope));
|
|
330
365
|
const maxSub = Math.max(1, Math.ceil(limit * 0.3));
|
|
331
366
|
// Order parents by overflow count descending so the most
|
|
332
367
|
// information-dense substitutions come first. Overflow count is the
|
|
@@ -441,7 +476,7 @@ export function recall(ctx, opts) {
|
|
|
441
476
|
// prepended (NOT rows already in baseRanked that got tagged isFreshTail).
|
|
442
477
|
freshTailAddedCount = freshRanked.length;
|
|
443
478
|
rankedOut = [...freshRanked, ...baseRanked, ...summaryRanked];
|
|
444
|
-
tokensOut = rankedOut.reduce((acc, r) => acc +
|
|
479
|
+
tokensOut = rankedOut.reduce((acc, r) => acc + estimateTokens(r.content), 0);
|
|
445
480
|
totalOut = entries.length;
|
|
446
481
|
// TODO(a1-task-4): emit via the shared audit hook in store.ts so we don't
|
|
447
482
|
// double-emit. Recall does not currently write through writeEntry, so no
|
|
@@ -523,7 +558,7 @@ export function recall(ctx, opts) {
|
|
|
523
558
|
sessionHandoff: filteredHandoff,
|
|
524
559
|
recentSessionEvents: filteredEvents,
|
|
525
560
|
};
|
|
526
|
-
const tokenize = (s) => s ?
|
|
561
|
+
const tokenize = (s) => s ? estimateTokens(s) : 0;
|
|
527
562
|
continuityTokens =
|
|
528
563
|
tokenize(filteredSnapshot?.task) +
|
|
529
564
|
tokenize(filteredSnapshot?.summary) +
|
|
@@ -689,6 +724,7 @@ export function recall(ctx, opts) {
|
|
|
689
724
|
* - all rows fail the scope/tenant filter
|
|
690
725
|
*/
|
|
691
726
|
export function assemble(ctx, sessionId, opts = {}) {
|
|
727
|
+
assertScopeRequestAllowed(ctx.actor.role, opts.scope);
|
|
692
728
|
const budget = opts.budget ?? 4000;
|
|
693
729
|
const freshTailCount = opts.freshTailCount ?? 10;
|
|
694
730
|
const summarizeOlder = opts.summarizeOlder ?? true;
|
|
@@ -736,7 +772,7 @@ export function assemble(ctx, sessionId, opts = {}) {
|
|
|
736
772
|
const eligibleParentIds = Array.from(olderByParent.keys()).filter((pid) => (olderByParent.get(pid)?.length ?? 0) >= 2);
|
|
737
773
|
const parents = eligibleParentIds.length > 0
|
|
738
774
|
? loadEntriesByIds(ctx.hippoRoot, eligibleParentIds, ctx.tenantId)
|
|
739
|
-
.filter((p) => (p.dag_level ?? 0) === 2)
|
|
775
|
+
.filter((p) => (p.dag_level ?? 0) === 2 && !p.superseded_by)
|
|
740
776
|
.filter((p) => passesScopeFilterForRecall(p.scope ?? null, opts.scope))
|
|
741
777
|
: [];
|
|
742
778
|
const claimedRawIds = new Set();
|
|
@@ -788,7 +824,7 @@ export function assemble(ctx, sessionId, opts = {}) {
|
|
|
788
824
|
olderItems.sort((a, b) => cmpIso(a.createdAt, b.createdAt));
|
|
789
825
|
tailItems.sort((a, b) => cmpIso(a.createdAt, b.createdAt));
|
|
790
826
|
let items = [...olderItems, ...tailItems];
|
|
791
|
-
let tokens = items.reduce((acc, it) => acc +
|
|
827
|
+
let tokens = items.reduce((acc, it) => acc + estimateTokens(it.content), 0);
|
|
792
828
|
let evicted = 0;
|
|
793
829
|
while (tokens > budget && items.length > 0) {
|
|
794
830
|
let worstIdx = -1;
|
|
@@ -803,7 +839,7 @@ export function assemble(ctx, sessionId, opts = {}) {
|
|
|
803
839
|
}
|
|
804
840
|
if (worstIdx === -1)
|
|
805
841
|
break;
|
|
806
|
-
const cost =
|
|
842
|
+
const cost = estimateTokens(items[worstIdx].content);
|
|
807
843
|
items = items.filter((_, i) => i !== worstIdx);
|
|
808
844
|
tokens -= cost;
|
|
809
845
|
evicted++;
|
|
@@ -887,7 +923,7 @@ export function drillDown(ctx, summaryId, opts = {}) {
|
|
|
887
923
|
const out = [];
|
|
888
924
|
let used = 0;
|
|
889
925
|
for (const c of collected) {
|
|
890
|
-
const t =
|
|
926
|
+
const t = estimateTokens(c.content);
|
|
891
927
|
if (out.length > 0 && used + t > opts.budget) {
|
|
892
928
|
truncated = true;
|
|
893
929
|
break;
|
|
@@ -1258,11 +1294,13 @@ export function archiveRaw(ctx, id, reason, opts = {}) {
|
|
|
1258
1294
|
* `src/server.ts` POST /v1/auth/keys mirrors this: it ignores any body
|
|
1259
1295
|
* `tenantId` and uses the resolved Bearer's tenant exclusively.
|
|
1260
1296
|
*
|
|
1261
|
-
*
|
|
1262
|
-
*
|
|
1263
|
-
* lands and adds the audit op, this function should mirror the cli handler.
|
|
1297
|
+
* Only an admin actor can mint (ForbiddenError otherwise), so a member key
|
|
1298
|
+
* can never create a key, least of all an admin one.
|
|
1264
1299
|
*/
|
|
1265
1300
|
export function authCreate(ctx, opts) {
|
|
1301
|
+
if (ctx.actor.role !== 'admin') {
|
|
1302
|
+
throw new ForbiddenError('Only an admin key can create API keys');
|
|
1303
|
+
}
|
|
1266
1304
|
const db = openHippoDb(ctx.hippoRoot);
|
|
1267
1305
|
try {
|
|
1268
1306
|
const role = opts.role ?? 'admin';
|
|
@@ -1311,6 +1349,9 @@ export function authList(ctx, opts) {
|
|
|
1311
1349
|
}
|
|
1312
1350
|
}
|
|
1313
1351
|
export function authRevoke(ctx, keyId) {
|
|
1352
|
+
if (ctx.actor.role !== 'admin' && ctx.actor.subject !== `api_key:${keyId}`) {
|
|
1353
|
+
throw new ForbiddenError('A member key can revoke only itself');
|
|
1354
|
+
}
|
|
1314
1355
|
const db = openHippoDb(ctx.hippoRoot);
|
|
1315
1356
|
try {
|
|
1316
1357
|
// SAFETY: row's shape matches the three columns named in the SELECT
|
|
@@ -1767,21 +1808,11 @@ export async function getContext(ctx, opts = {}) {
|
|
|
1767
1808
|
const toUpdate = selectedItems.map((s) => s.entry);
|
|
1768
1809
|
const updatedEntries = markRetrieved(toUpdate);
|
|
1769
1810
|
const localIndex = loadIndex(ctx.hippoRoot);
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
for (const u of updatedEntries) {
|
|
1776
|
-
const targetRoot = localIndex.entries[u.id]
|
|
1777
|
-
? ctx.hippoRoot
|
|
1778
|
-
: hasGlobal
|
|
1779
|
-
? globalRoot
|
|
1780
|
-
: ctx.hippoRoot;
|
|
1781
|
-
writeEntry(targetRoot, u);
|
|
1782
|
-
}
|
|
1783
|
-
}
|
|
1784
|
-
localIndex.last_retrieval_ids = updatedEntries.map((u) => u.id);
|
|
1811
|
+
const retrievedIds = updatedEntries.map((u) => u.id);
|
|
1812
|
+
const strengthenedHere = strengthenRetrieved(ctx.hippoRoot, retrievedIds);
|
|
1813
|
+
if (hasGlobal)
|
|
1814
|
+
strengthenRetrieved(globalRoot, retrievedIds.filter((id) => !strengthenedHere.has(id)));
|
|
1815
|
+
localIndex.last_retrieval_ids = retrievedIds;
|
|
1785
1816
|
// LC1 F1 structural fix (docs/plans/2026-08-02-lc1-recall-trace-persistence.md):
|
|
1786
1817
|
// write the trace FIRST — post-limit, post-annotation `selectedItems`
|
|
1787
1818
|
// actually returned, on a fresh short-lived connection (the audit
|
|
@@ -1833,6 +1864,174 @@ export async function getContext(ctx, opts = {}) {
|
|
|
1833
1864
|
ambientState,
|
|
1834
1865
|
};
|
|
1835
1866
|
}
|
|
1867
|
+
/**
|
|
1868
|
+
* Record memory text handed to an agent in the token ledger (ROADMAP TE0).
|
|
1869
|
+
* Best-effort: never throws, because a ledger failure must not fail the
|
|
1870
|
+
* recall or context call that produced the text.
|
|
1871
|
+
*/
|
|
1872
|
+
export function recordTokens(ctx, surface, use) {
|
|
1873
|
+
try {
|
|
1874
|
+
const db = openHippoDb(ctx.hippoRoot);
|
|
1875
|
+
try {
|
|
1876
|
+
recordTokenUse(db, {
|
|
1877
|
+
tenantId: ctx.tenantId,
|
|
1878
|
+
sessionId: use.sessionId ?? null,
|
|
1879
|
+
surface,
|
|
1880
|
+
event: 'inject',
|
|
1881
|
+
items: use.items,
|
|
1882
|
+
tokens: use.tokens,
|
|
1883
|
+
});
|
|
1884
|
+
}
|
|
1885
|
+
finally {
|
|
1886
|
+
closeHippoDb(db);
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
catch {
|
|
1890
|
+
// Ledger is best-effort.
|
|
1891
|
+
}
|
|
1892
|
+
}
|
|
1893
|
+
/**
|
|
1894
|
+
* Token ledger totals for the tenant over the last `days` days (default 30):
|
|
1895
|
+
* tokens sent per surface, blocks skipped as unchanged and the tokens that
|
|
1896
|
+
* saved, and mean tokens per session.
|
|
1897
|
+
*/
|
|
1898
|
+
export function tokenSummary(ctx, opts = {}) {
|
|
1899
|
+
const days = opts.days !== undefined && Number.isFinite(opts.days) && opts.days > 0 ? opts.days : 30;
|
|
1900
|
+
const since = new Date(Date.now() - days * 86_400_000).toISOString();
|
|
1901
|
+
const db = openHippoDb(ctx.hippoRoot);
|
|
1902
|
+
try {
|
|
1903
|
+
return summarizeTokenUse(db, ctx.tenantId, since);
|
|
1904
|
+
}
|
|
1905
|
+
finally {
|
|
1906
|
+
closeHippoDb(db);
|
|
1907
|
+
}
|
|
1908
|
+
}
|
|
1909
|
+
/**
|
|
1910
|
+
* A tenant's dormant memories (src/dormant.ts): what sleep moved out of
|
|
1911
|
+
* active memory instead of deleting, when `dormant.enabled` is on. Newest
|
|
1912
|
+
* first; `opts.query` keeps rows containing every term (case-insensitive).
|
|
1913
|
+
*/
|
|
1914
|
+
export function listDormant(ctx, opts = {}) {
|
|
1915
|
+
const db = openHippoDb(ctx.hippoRoot);
|
|
1916
|
+
try {
|
|
1917
|
+
return listDormantRows(db, ctx.tenantId, opts);
|
|
1918
|
+
}
|
|
1919
|
+
finally {
|
|
1920
|
+
closeHippoDb(db);
|
|
1921
|
+
}
|
|
1922
|
+
}
|
|
1923
|
+
/**
|
|
1924
|
+
* Bring a dormant memory back into active memory. It returns as if just
|
|
1925
|
+
* recalled: `last_retrieved` is now, so it gets a full half-life before it
|
|
1926
|
+
* can fade again. Every other field is the snapshot taken when it went
|
|
1927
|
+
* dormant.
|
|
1928
|
+
*
|
|
1929
|
+
* Throws when the tenant has no dormant memory with that id (another
|
|
1930
|
+
* tenant's id reads the same way), when a live memory already holds the id,
|
|
1931
|
+
* and RejectedValueError when the value has been rejected since. On any
|
|
1932
|
+
* throw the dormant copy stays where it is.
|
|
1933
|
+
*/
|
|
1934
|
+
export function restoreDormant(ctx, id) {
|
|
1935
|
+
const db = openHippoDb(ctx.hippoRoot);
|
|
1936
|
+
try {
|
|
1937
|
+
let restored;
|
|
1938
|
+
db.exec('BEGIN IMMEDIATE');
|
|
1939
|
+
try {
|
|
1940
|
+
const dormant = readDormantSnapshot(db, ctx.tenantId, id);
|
|
1941
|
+
if (!dormant) {
|
|
1942
|
+
throw new Error(`dormant memory not found: ${id}`);
|
|
1943
|
+
}
|
|
1944
|
+
if (db.prepare(`SELECT 1 FROM memories WHERE id = ?`).get(id) !== undefined) {
|
|
1945
|
+
throw new Error(`memory ${id} is already active; forget it before restoring its dormant copy`);
|
|
1946
|
+
}
|
|
1947
|
+
const now = new Date();
|
|
1948
|
+
// Dormant rows are long-lived, so a snapshot can predate a field added
|
|
1949
|
+
// later: createMemory supplies a default for anything it lacks, then
|
|
1950
|
+
// the snapshot overrides every field it does carry, content included.
|
|
1951
|
+
// (The placeholder only satisfies createMemory's minimum length, so a
|
|
1952
|
+
// legacy row shorter than 3 chars can still be restored.)
|
|
1953
|
+
const revived = {
|
|
1954
|
+
...createMemory('dormant snapshot defaults'),
|
|
1955
|
+
...dormant.entry,
|
|
1956
|
+
last_retrieved: now.toISOString(),
|
|
1957
|
+
};
|
|
1958
|
+
restored = stampOriginProject(ctx.hippoRoot, { ...revived, strength: calculateStrength(revived, now) });
|
|
1959
|
+
writeEntryDbOnly(db, restored, { actor: ctx.actor.subject });
|
|
1960
|
+
deleteDormantRow(db, ctx.tenantId, id);
|
|
1961
|
+
// A restore is a labelled "forgot it, then needed it" event: the
|
|
1962
|
+
// signal a learned lifecycle (ROADMAP LC3) trains on. Same transaction
|
|
1963
|
+
// as the restore, so the label exists exactly when the restore does.
|
|
1964
|
+
appendAuditEvent(db, {
|
|
1965
|
+
tenantId: ctx.tenantId,
|
|
1966
|
+
actor: ctx.actor.subject,
|
|
1967
|
+
op: 'dormant_restore',
|
|
1968
|
+
targetId: id,
|
|
1969
|
+
metadata: {
|
|
1970
|
+
reason: dormant.reason,
|
|
1971
|
+
strengthAtDormancy: dormant.strength,
|
|
1972
|
+
dormantAt: dormant.dormantAt,
|
|
1973
|
+
daysDormant: Math.max(0, (now.getTime() - Date.parse(dormant.dormantAt)) / (24 * 60 * 60 * 1000)),
|
|
1974
|
+
},
|
|
1975
|
+
});
|
|
1976
|
+
db.exec('COMMIT');
|
|
1977
|
+
}
|
|
1978
|
+
catch (err) {
|
|
1979
|
+
try {
|
|
1980
|
+
db.exec('ROLLBACK');
|
|
1981
|
+
}
|
|
1982
|
+
catch { /* already rolled back */ }
|
|
1983
|
+
if (err instanceof RejectedValueError) {
|
|
1984
|
+
auditRejectionRefusal(db, err, ctx.actor.subject);
|
|
1985
|
+
}
|
|
1986
|
+
throw err;
|
|
1987
|
+
}
|
|
1988
|
+
writeEntryMirrors(ctx.hippoRoot, db, restored);
|
|
1989
|
+
return restored;
|
|
1990
|
+
}
|
|
1991
|
+
finally {
|
|
1992
|
+
closeHippoDb(db);
|
|
1993
|
+
}
|
|
1994
|
+
}
|
|
1995
|
+
/**
|
|
1996
|
+
* Permanently delete a dormant memory: the explicit "forget it for good"
|
|
1997
|
+
* that dormant storage leaves to the user. Throws when the tenant has no
|
|
1998
|
+
* dormant memory with that id.
|
|
1999
|
+
*/
|
|
2000
|
+
export function forgetDormant(ctx, id) {
|
|
2001
|
+
const db = openHippoDb(ctx.hippoRoot);
|
|
2002
|
+
try {
|
|
2003
|
+
if (!deleteDormantRow(db, ctx.tenantId, id)) {
|
|
2004
|
+
throw new Error(`dormant memory not found: ${id}`);
|
|
2005
|
+
}
|
|
2006
|
+
try {
|
|
2007
|
+
appendAuditEvent(db, {
|
|
2008
|
+
tenantId: ctx.tenantId,
|
|
2009
|
+
actor: ctx.actor.subject,
|
|
2010
|
+
op: 'forget',
|
|
2011
|
+
targetId: id,
|
|
2012
|
+
metadata: { dormant: true },
|
|
2013
|
+
});
|
|
2014
|
+
}
|
|
2015
|
+
catch {
|
|
2016
|
+
// Best-effort, like every other forget audit row: the delete stands.
|
|
2017
|
+
}
|
|
2018
|
+
}
|
|
2019
|
+
finally {
|
|
2020
|
+
closeHippoDb(db);
|
|
2021
|
+
}
|
|
2022
|
+
// Counted like every other permanent removal (forget, archiveRaw).
|
|
2023
|
+
updateStats(ctx.hippoRoot, { forgotten: 1 });
|
|
2024
|
+
}
|
|
2025
|
+
/** Whether the tenant holds a dormant memory with this id (for "not found" hints). */
|
|
2026
|
+
export function isDormant(ctx, id) {
|
|
2027
|
+
const db = openHippoDb(ctx.hippoRoot);
|
|
2028
|
+
try {
|
|
2029
|
+
return hasDormantRow(db, ctx.tenantId, id);
|
|
2030
|
+
}
|
|
2031
|
+
finally {
|
|
2032
|
+
closeHippoDb(db);
|
|
2033
|
+
}
|
|
2034
|
+
}
|
|
1836
2035
|
const DEFAULT_SLEEP_PHASES = {
|
|
1837
2036
|
consolidate,
|
|
1838
2037
|
deduplicateStore,
|
|
@@ -1896,10 +2095,16 @@ export async function sleep(ctx, opts = {}) {
|
|
|
1896
2095
|
dryRun,
|
|
1897
2096
|
details: consolidateResult.details,
|
|
1898
2097
|
};
|
|
1899
|
-
|
|
1900
|
-
|
|
2098
|
+
// Set only when non-zero, so a store without dormant memories gets a
|
|
2099
|
+
// byte-identical result (HTTP /v1/sleep, the CLI render snapshot).
|
|
2100
|
+
if (consolidateResult.dormant > 0) {
|
|
2101
|
+
result.dormant = consolidateResult.dormant;
|
|
2102
|
+
}
|
|
2103
|
+
if (consolidateResult.dormantExpired > 0) {
|
|
2104
|
+
result.dormantExpired = consolidateResult.dormantExpired;
|
|
2105
|
+
}
|
|
1901
2106
|
// Phase 2: Dedup (post-consolidate near-duplicate cleanup).
|
|
1902
|
-
const dedupResult = phases.deduplicateStore(ctx.hippoRoot);
|
|
2107
|
+
const dedupResult = phases.deduplicateStore(ctx.hippoRoot, { dryRun, actor: ctx.actor.subject });
|
|
1903
2108
|
dedupCount = dedupResult.removed;
|
|
1904
2109
|
if (dedupResult.removed > 0) {
|
|
1905
2110
|
const semDups = dedupResult.pairs.filter((p) => p.keptLayer === 'semantic' && p.removedLayer === 'semantic').length;
|
|
@@ -1912,25 +2117,29 @@ export async function sleep(ctx, opts = {}) {
|
|
|
1912
2117
|
crossDups,
|
|
1913
2118
|
};
|
|
1914
2119
|
}
|
|
1915
|
-
// Phase 3: Quality audit (remove junk, report warnings).
|
|
1916
|
-
const
|
|
2120
|
+
// Phase 3: Quality audit (remove junk, report warnings; a dry run skips rows earlier phases would remove).
|
|
2121
|
+
const planned = new Set(dryRun ? [...(consolidateResult.removedIds ?? []), ...dedupResult.pairs.map((p) => p.removed)] : []);
|
|
2122
|
+
const allEntries = phases.loadAllEntries(ctx.hippoRoot).filter((e) => !planned.has(e.id));
|
|
1917
2123
|
const auditOut = phases.auditMemories(allEntries);
|
|
1918
2124
|
if (auditOut.issues.length > 0) {
|
|
1919
2125
|
const errors = auditOut.issues.filter((i) => i.severity === 'error');
|
|
1920
2126
|
const warnings = auditOut.issues.filter((i) => i.severity === 'warning');
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
}
|
|
2127
|
+
let removed = 0;
|
|
2128
|
+
for (const issue of errors) {
|
|
2129
|
+
const reason = `sleep-audit: ${issue.reason}`;
|
|
2130
|
+
if (dryRun || phases.deleteEntry(ctx.hippoRoot, issue.memoryId, { actor: ctx.actor.subject, reason, automatic: true }))
|
|
2131
|
+
removed++;
|
|
1925
2132
|
}
|
|
1926
|
-
auditDeletedCount =
|
|
1927
|
-
if (
|
|
2133
|
+
auditDeletedCount = removed;
|
|
2134
|
+
if (removed > 0 || warnings.length > 0) {
|
|
1928
2135
|
result.audit = {
|
|
1929
|
-
errorsRemoved:
|
|
2136
|
+
errorsRemoved: removed,
|
|
1930
2137
|
warningCount: warnings.length,
|
|
1931
2138
|
};
|
|
1932
2139
|
}
|
|
1933
2140
|
}
|
|
2141
|
+
if (dryRun)
|
|
2142
|
+
return result;
|
|
1934
2143
|
// Phase 4: Auto-share high-transfer-score memories to global.
|
|
1935
2144
|
if (!opts.noShare) {
|
|
1936
2145
|
const sleepConfig = phases.loadConfig(ctx.hippoRoot);
|
package/dist/audit.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type MemoryEntry } from './memory.js';
|
|
2
2
|
import type { DatabaseSyncLike } from './db.js';
|
|
3
3
|
import type { JsonObject } from './working-memory.js';
|
|
4
4
|
export type AuditSeverity = 'warning' | 'error';
|
|
@@ -16,7 +16,7 @@ export interface AuditResult {
|
|
|
16
16
|
export declare function auditMemory(entry: MemoryEntry): AuditIssue | null;
|
|
17
17
|
export declare function auditMemories(entries: MemoryEntry[]): AuditResult;
|
|
18
18
|
export declare function isContentWorthStoring(content: string): boolean;
|
|
19
|
-
export type AuditOp = 'remember' | 'recall' | 'promote' | 'supersede' | 'forget' | 'archive_raw' | 'auth_revoke' | 'auth_create' | 'outcome' | 'consolidate' | 'audit_prune' | 'summary_marked_dirty' | 'summary_marked_clean' | 'summary_rebuilt' | 'predict_create' | 'predict_close' | 'predict_baserate' | 'recall_autodebias_hint' | 'recall_autodebias_hint_no_class_match' | 'recall_autodebias_hint_tiebreak' | 'recall_anchor_detected_query_repeat' | 'recall_anchor_detected_memory_dominance' | 'recall_anchor_skipped_no_session' | 'recall_availability_detected' | 'decision_create' | 'decision_supersede' | 'decision_close' | 'incident_open' | 'incident_resolve' | 'incident_close' | 'process_create' | 'process_supersede' | 'process_close' | 'policy_create' | 'policy_supersede' | 'policy_close' | 'skill_create' | 'skill_supersede' | 'skill_close' | 'project_brief_create' | 'project_brief_supersede' | 'project_brief_close' | 'customer_note_create' | 'customer_note_supersede' | 'customer_note_close' | 'mv_rescue' | 'reject_value' | 'reject_refusal' | 'unreject_value' | 'conflict_resolve';
|
|
19
|
+
export type AuditOp = 'remember' | 'recall' | 'promote' | 'supersede' | 'forget' | 'archive_raw' | 'auth_revoke' | 'auth_create' | 'outcome' | 'consolidate' | 'audit_prune' | 'summary_marked_dirty' | 'summary_marked_clean' | 'summary_rebuilt' | 'predict_create' | 'predict_close' | 'predict_baserate' | 'recall_autodebias_hint' | 'recall_autodebias_hint_no_class_match' | 'recall_autodebias_hint_tiebreak' | 'recall_anchor_detected_query_repeat' | 'recall_anchor_detected_memory_dominance' | 'recall_anchor_skipped_no_session' | 'recall_availability_detected' | 'decision_create' | 'decision_supersede' | 'decision_close' | 'incident_open' | 'incident_resolve' | 'incident_close' | 'process_create' | 'process_supersede' | 'process_close' | 'policy_create' | 'policy_supersede' | 'policy_close' | 'skill_create' | 'skill_supersede' | 'skill_close' | 'project_brief_create' | 'project_brief_supersede' | 'project_brief_close' | 'customer_note_create' | 'customer_note_supersede' | 'customer_note_close' | 'mv_rescue' | 'reject_value' | 'reject_refusal' | 'unreject_value' | 'half_life_migrate' | 'dormant_restore' | 'conflict_resolve';
|
|
20
20
|
export interface AppendAuditOpts {
|
|
21
21
|
tenantId: string;
|
|
22
22
|
actor: string;
|
package/dist/audit.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { canAutoDelete } from './memory.js';
|
|
1
2
|
const STOP_WORDS = new Set([
|
|
2
3
|
'the', 'a', 'an', 'is', 'was', 'are', 'were', 'be', 'been', 'being',
|
|
3
4
|
'to', 'of', 'in', 'for', 'on', 'with', 'at', 'by', 'from', 'it',
|
|
@@ -109,6 +110,14 @@ function hasNoSpecificity(text) {
|
|
|
109
110
|
return words.length < 8 && VAGUE_ONLY.test(text);
|
|
110
111
|
}
|
|
111
112
|
export function auditMemory(entry) {
|
|
113
|
+
const issue = classifyMemory(entry);
|
|
114
|
+
// Error means "auto-remove"; a pinned or raw row is never auto-removed, so it can only warn.
|
|
115
|
+
if (issue?.severity === 'error' && !canAutoDelete(entry)) {
|
|
116
|
+
return { ...issue, severity: 'warning', reason: `${issue.reason} (${entry.pinned ? 'pinned' : 'raw'}, kept)` };
|
|
117
|
+
}
|
|
118
|
+
return issue;
|
|
119
|
+
}
|
|
120
|
+
function classifyMemory(entry) {
|
|
112
121
|
const content = entry.content.trim();
|
|
113
122
|
if (content.length < 3) {
|
|
114
123
|
return { memoryId: entry.id, content, severity: 'error', reason: 'too short (< 3 chars)' };
|
package/dist/autolearn.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { MemoryEntry } from './memory.js';
|
|
|
7
7
|
* Create a MemoryEntry capturing a command failure.
|
|
8
8
|
* Content format: "Command '<cmd>' failed: <truncated stderr>"
|
|
9
9
|
*/
|
|
10
|
-
export declare function captureError(exitCode: number, stderr: string, command: string): MemoryEntry;
|
|
10
|
+
export declare function captureError(exitCode: number, stderr: string, command: string, tenantId?: string): MemoryEntry;
|
|
11
11
|
/**
|
|
12
12
|
* Parse git log output for actionable lessons.
|
|
13
13
|
* Looks for fix:, revert:, bug:, error:, hotfix: commit messages.
|
package/dist/autolearn.js
CHANGED
|
@@ -11,7 +11,7 @@ import { isContentWorthStoring } from './audit.js';
|
|
|
11
11
|
* Create a MemoryEntry capturing a command failure.
|
|
12
12
|
* Content format: "Command '<cmd>' failed: <truncated stderr>"
|
|
13
13
|
*/
|
|
14
|
-
export function captureError(exitCode, stderr, command) {
|
|
14
|
+
export function captureError(exitCode, stderr, command, tenantId) {
|
|
15
15
|
// Truncate to first 500 chars to avoid storing megabytes of build logs
|
|
16
16
|
const wasTruncated = stderr.length > 500;
|
|
17
17
|
const truncated = stderr.slice(0, 500).trim();
|
|
@@ -29,6 +29,7 @@ export function captureError(exitCode, stderr, command) {
|
|
|
29
29
|
tags,
|
|
30
30
|
source: 'autolearn',
|
|
31
31
|
confidence: 'observed',
|
|
32
|
+
tenantId,
|
|
32
33
|
});
|
|
33
34
|
}
|
|
34
35
|
/**
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { JsonValue } from './working-memory.js';
|
|
2
|
+
/** Why a failure was not stored, or `stored`. */
|
|
3
|
+
export type CaptureErrorOutcome = 'stored' | 'duplicate' | 'skipped-interrupt' | 'skipped-routine' | 'skipped-invalid';
|
|
4
|
+
/** Normalised form used to spot repeats of the same failure. */
|
|
5
|
+
export declare function failureSignature(text: string): string;
|
|
6
|
+
/**
|
|
7
|
+
* The memory text for a failure payload, or the reason it is not stored.
|
|
8
|
+
* Pure: no store access.
|
|
9
|
+
*/
|
|
10
|
+
export declare function lessonFromFailure(payload: JsonValue): {
|
|
11
|
+
text: string;
|
|
12
|
+
} | {
|
|
13
|
+
skip: Exclude<CaptureErrorOutcome, 'stored' | 'duplicate'>;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Store a failure payload as an error memory unless it is routine or a
|
|
17
|
+
* repeat of an auto-captured error already in the store.
|
|
18
|
+
*/
|
|
19
|
+
export declare function captureToolFailure(hippoRoot: string, tenantId: string, payload: JsonValue): CaptureErrorOutcome;
|
|
20
|
+
//# sourceMappingURL=capture-error.d.ts.map
|