hippo-memory 1.44.0 → 1.45.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 +12 -10
- package/bin/hippo.js +3 -1
- package/dist/api.d.ts +21 -21
- package/dist/api.js +69 -42
- package/dist/audit.d.ts +1 -1
- package/dist/audit.js +9 -0
- package/dist/autolearn.d.ts +1 -1
- package/dist/autolearn.js +2 -1
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +151 -72
- package/dist/client.d.ts +4 -21
- package/dist/client.js +3 -112
- package/dist/config.js +2 -1
- package/dist/consolidate.d.ts +3 -0
- package/dist/consolidate.js +44 -42
- package/dist/dag.d.ts +1 -0
- package/dist/dag.js +10 -5
- package/dist/dashboard.js +7 -3
- package/dist/db.js +12 -23
- package/dist/dedupe.d.ts +1 -0
- package/dist/dedupe.js +4 -7
- package/dist/embedding-provider.js +2 -1
- package/dist/embeddings.js +81 -8
- package/dist/extract.d.ts +2 -0
- package/dist/extract.js +9 -4
- package/dist/mcp/server.js +21 -36
- package/dist/memory.d.ts +3 -0
- package/dist/memory.js +7 -1
- package/dist/refine-llm.js +3 -2
- package/dist/rerankers/jev.js +3 -2
- package/dist/rerankers/llm.js +3 -2
- package/dist/search.js +3 -3
- package/dist/server.d.ts +5 -0
- package/dist/server.js +39 -29
- package/dist/shared.js +1 -1
- package/dist/store.d.ts +18 -11
- package/dist/store.js +144 -63
- 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 +6 -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/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
|
package/dist/extract.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export interface ExtractOptions {
|
|
|
8
8
|
apiKey: string;
|
|
9
9
|
model?: string;
|
|
10
10
|
fetcher?: typeof fetch;
|
|
11
|
+
/** Told why a call produced nothing, so callers can surface it instead of guessing. */
|
|
12
|
+
onError?: (msg: string) => void;
|
|
11
13
|
}
|
|
12
14
|
export declare function extractFacts(text: string, opts: ExtractOptions): Promise<ExtractedFact[]>;
|
|
13
15
|
export declare function storeExtractedFacts(hippoRoot: string, source: MemoryEntry, facts: ExtractedFact[]): MemoryEntry[];
|
package/dist/extract.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Layer, createMemory } from './memory.js';
|
|
2
2
|
import { writeEntry } from './store.js';
|
|
3
3
|
import { RejectedValueError } from './rejection.js';
|
|
4
|
+
import { redactSecrets } from './secret-detect.js';
|
|
4
5
|
function isJsonString(value) {
|
|
5
6
|
return typeof value === 'string';
|
|
6
7
|
}
|
|
@@ -31,15 +32,18 @@ export async function extractFacts(text, opts) {
|
|
|
31
32
|
body: JSON.stringify({
|
|
32
33
|
model,
|
|
33
34
|
max_tokens: 1200,
|
|
34
|
-
messages: [{ role: 'user', content: EXTRACTION_PROMPT + text }],
|
|
35
|
+
messages: [{ role: 'user', content: EXTRACTION_PROMPT + redactSecrets(text) }],
|
|
35
36
|
}),
|
|
36
37
|
});
|
|
37
38
|
}
|
|
38
|
-
catch {
|
|
39
|
+
catch (err) {
|
|
40
|
+
opts.onError?.(`request failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
39
41
|
return [];
|
|
40
42
|
}
|
|
41
|
-
if (!res.ok)
|
|
43
|
+
if (!res.ok) {
|
|
44
|
+
opts.onError?.(`HTTP ${res.status}`);
|
|
42
45
|
return [];
|
|
46
|
+
}
|
|
43
47
|
try {
|
|
44
48
|
const data = await res.json();
|
|
45
49
|
const raw = data.content?.[0]?.text?.trim() ?? '';
|
|
@@ -69,7 +73,8 @@ export async function extractFacts(text, opts) {
|
|
|
69
73
|
}
|
|
70
74
|
return facts;
|
|
71
75
|
}
|
|
72
|
-
catch {
|
|
76
|
+
catch (err) {
|
|
77
|
+
opts.onError?.(`unparseable response: ${err instanceof Error ? err.message : String(err)}`);
|
|
73
78
|
return [];
|
|
74
79
|
}
|
|
75
80
|
}
|
package/dist/mcp/server.js
CHANGED
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
import * as fs from 'fs';
|
|
11
11
|
import * as path from 'path';
|
|
12
12
|
import { createMemory, Layer, calculateStrength, } from '../memory.js';
|
|
13
|
-
import { hybridSearch, physicsSearch
|
|
14
|
-
import {
|
|
15
|
-
import { loadAllEntries, writeEntry, readEntry, loadFreshActiveTaskSnapshot, listMemoryConflicts, resolveConflict, RECALL_DEFAULT_DENY_SCOPES } from '../store.js';
|
|
13
|
+
import { hybridSearch, physicsSearch } from '../search.js';
|
|
14
|
+
import { evalNow } from '../ablation.js';
|
|
15
|
+
import { loadAllEntries, writeEntry, strengthenRetrieved, readEntry, loadFreshActiveTaskSnapshot, listMemoryConflicts, resolveConflict, RECALL_DEFAULT_DENY_SCOPES, countCreatedSinceLastSleep } from '../store.js';
|
|
16
16
|
import { shareMemory, listPeers, getGlobalRoot } from '../shared.js';
|
|
17
17
|
import { consolidate } from '../consolidate.js';
|
|
18
18
|
import { execSync } from 'child_process';
|
|
@@ -359,6 +359,7 @@ const TOOLS = [
|
|
|
359
359
|
// `${tenantId}:default` if a McpContext is constructed in tests without a
|
|
360
360
|
// pid-bound transport.
|
|
361
361
|
const lastRecalledIds = new Map();
|
|
362
|
+
const autoSleepInFlight = new Set();
|
|
362
363
|
function resolveClientKey(ctx) {
|
|
363
364
|
if (ctx?.clientKey)
|
|
364
365
|
return ctx.clientKey;
|
|
@@ -527,15 +528,9 @@ async function executeTool(name, args, ctx) {
|
|
|
527
528
|
closeHippoDb(dbForBoost);
|
|
528
529
|
}
|
|
529
530
|
}
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
// flag; ids below stay populated for outcome attribution.
|
|
534
|
-
if (!isRecallBoostAblated()) {
|
|
535
|
-
for (const entry of retrieved)
|
|
536
|
-
writeEntry(hippoRoot, entry, { actor: ctx?.actor ?? 'mcp' });
|
|
537
|
-
}
|
|
538
|
-
lastRecalledIds.set(resolveClientKey(ctx), retrieved.map((e) => e.id));
|
|
531
|
+
const retrievedIds = results.map((r) => r.entry.id);
|
|
532
|
+
strengthenRetrieved(hippoRoot, retrievedIds);
|
|
533
|
+
lastRecalledIds.set(resolveClientKey(ctx), retrievedIds);
|
|
539
534
|
// v0.33 / J1 — MCP per-pipeline anchoring detector. UNLIKE J3.2's
|
|
540
535
|
// planningFallacyHint (which is pipeline-invariant because it
|
|
541
536
|
// depends only on queryText + predictions table state), the
|
|
@@ -902,22 +897,17 @@ async function executeTool(name, args, ctx) {
|
|
|
902
897
|
tags,
|
|
903
898
|
});
|
|
904
899
|
const entry = readEntry(hippoRoot, result.id, tenantId);
|
|
905
|
-
// Auto-sleep
|
|
906
|
-
if (config.autoSleep.enabled
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
// throw) must land as a logged line, not a crash.
|
|
917
|
-
consolidate(hippoRoot).catch((err) => {
|
|
918
|
-
console.error(`auto-sleep consolidate failed: ${err instanceof Error ? err.message : err}`);
|
|
919
|
-
});
|
|
920
|
-
}
|
|
900
|
+
// Auto-sleep: one run per store at a time, triggered by what arrived since the last one.
|
|
901
|
+
if (config.autoSleep.enabled &&
|
|
902
|
+
!autoSleepInFlight.has(hippoRoot) &&
|
|
903
|
+
countCreatedSinceLastSleep(hippoRoot, tenantId) >= config.autoSleep.threshold) {
|
|
904
|
+
autoSleepInFlight.add(hippoRoot);
|
|
905
|
+
// Fire-and-forget (never block the response); an unhandled rejection would kill the server, so log it.
|
|
906
|
+
consolidate(hippoRoot)
|
|
907
|
+
.catch((err) => {
|
|
908
|
+
console.error(`auto-sleep consolidate failed (tenant ${tenantId}): ${err instanceof Error ? err.message : err}`);
|
|
909
|
+
})
|
|
910
|
+
.finally(() => autoSleepInFlight.delete(hippoRoot));
|
|
921
911
|
}
|
|
922
912
|
const halfLife = entry?.half_life_days ?? config.defaultHalfLifeDays;
|
|
923
913
|
const tagStr = entry?.tags.join(', ') || tags.join(', ') || 'none';
|
|
@@ -1000,14 +990,9 @@ async function executeTool(name, args, ctx) {
|
|
|
1000
990
|
const results = usePhysicsCtx
|
|
1001
991
|
? await physicsSearch(query, entries, { budget, hippoRoot, physicsConfig: config.physics })
|
|
1002
992
|
: await hybridSearch(query, entries, { budget, hippoRoot });
|
|
1003
|
-
const
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
if (!isRecallBoostAblated()) {
|
|
1007
|
-
for (const entry of retrieved)
|
|
1008
|
-
writeEntry(hippoRoot, entry, { actor: ctx?.actor ?? 'mcp' });
|
|
1009
|
-
}
|
|
1010
|
-
lastRecalledIds.set(resolveClientKey(ctx), retrieved.map((e) => e.id));
|
|
993
|
+
const retrievedIds = results.map((r) => r.entry.id);
|
|
994
|
+
strengthenRetrieved(hippoRoot, retrievedIds);
|
|
995
|
+
lastRecalledIds.set(resolveClientKey(ctx), retrievedIds);
|
|
1011
996
|
// DF1 (docs/plans/2026-08-23-df1-snapshot-lifecycle.md, T2): bounded
|
|
1012
997
|
// read, no session id available on this surface (freshness bound
|
|
1013
998
|
// only) — an orphaned snapshot must age out here too, not just on the
|
package/dist/memory.d.ts
CHANGED
|
@@ -203,6 +203,9 @@ export declare function confidenceLabel(entry: MemoryEntry, now?: Date): {
|
|
|
203
203
|
* returns 'stale'. Otherwise returns the stored confidence value.
|
|
204
204
|
*/
|
|
205
205
|
export declare function resolveConfidence(entry: MemoryEntry, now?: Date): ConfidenceLevel;
|
|
206
|
+
export declare const DEFAULT_HALF_LIFE_DAYS = 7;
|
|
207
|
+
export declare const AUTO_DELETABLE_SQL = "pinned = 0 AND kind != 'raw'";
|
|
208
|
+
export declare function canAutoDelete(entry: Pick<MemoryEntry, 'pinned' | 'kind'>): boolean;
|
|
206
209
|
/**
|
|
207
210
|
* Create a new memory entry with defaults.
|
|
208
211
|
*/
|
package/dist/memory.js
CHANGED
|
@@ -296,6 +296,12 @@ export function confidenceLabel(entry, now = evalNow()) {
|
|
|
296
296
|
export function resolveConfidence(entry, now = evalNow()) {
|
|
297
297
|
return isAgedOut(entry, now) ? 'stale' : entry.confidence;
|
|
298
298
|
}
|
|
299
|
+
export const DEFAULT_HALF_LIFE_DAYS = 7;
|
|
300
|
+
// Pinned means keep; raw rows leave only through archiveRawMemory. The SQL twin guards the DELETE itself.
|
|
301
|
+
export const AUTO_DELETABLE_SQL = "pinned = 0 AND kind != 'raw'";
|
|
302
|
+
export function canAutoDelete(entry) {
|
|
303
|
+
return !entry.pinned && entry.kind !== 'raw';
|
|
304
|
+
}
|
|
299
305
|
/**
|
|
300
306
|
* Create a new memory entry with defaults.
|
|
301
307
|
*/
|
|
@@ -314,7 +320,7 @@ export function createMemory(content, options = {}) {
|
|
|
314
320
|
const emotional_valence = options.emotional_valence ?? inferValence(tags);
|
|
315
321
|
const schema_fit = options.schema_fit ?? 0.5;
|
|
316
322
|
const partial = { tags, schema_fit };
|
|
317
|
-
const half_life_days = deriveHalfLife(options.baseHalfLifeDays ??
|
|
323
|
+
const half_life_days = deriveHalfLife(options.baseHalfLifeDays ?? DEFAULT_HALF_LIFE_DAYS, partial);
|
|
318
324
|
const entry = {
|
|
319
325
|
id: generateId(layer === Layer.Semantic ? 'sem' : 'mem'),
|
|
320
326
|
created: now,
|
package/dist/refine-llm.js
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import { Layer } from './memory.js';
|
|
16
16
|
import { loadAllEntries, readEntry, writeEntry } from './store.js';
|
|
17
|
+
import { redactSecrets } from './secret-detect.js';
|
|
17
18
|
const REFINED_TAG = 'llm-refined';
|
|
18
19
|
const CONSOLIDATED_MARKERS = [
|
|
19
20
|
'[Consolidated from',
|
|
@@ -29,7 +30,7 @@ export async function refineSemanticMemory(merged, sources, opts) {
|
|
|
29
30
|
const fetchFn = opts.fetcher ?? fetch;
|
|
30
31
|
const sourceBlock = sources
|
|
31
32
|
.slice(0, 8)
|
|
32
|
-
.map((s, i) => `[source ${i + 1}] ${s.content.slice(0, 400)}`)
|
|
33
|
+
.map((s, i) => `[source ${i + 1}] ${redactSecrets(s.content).slice(0, 400)}`)
|
|
33
34
|
.join('\n\n');
|
|
34
35
|
const prompt = `You are refining a semantic memory in an agent's memory store. The rule-based consolidator merged several related episodic memories into one, but the output is clumsy. Produce a single coherent semantic memory that captures the underlying principle.
|
|
35
36
|
|
|
@@ -41,7 +42,7 @@ Rules:
|
|
|
41
42
|
- Do NOT include the "[Consolidated from N ...]" marker.
|
|
42
43
|
|
|
43
44
|
Current merged content:
|
|
44
|
-
${merged}
|
|
45
|
+
${redactSecrets(merged)}
|
|
45
46
|
|
|
46
47
|
Source memories (up to 8 shown):
|
|
47
48
|
${sourceBlock}`;
|
package/dist/rerankers/jev.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { crossEncoderReranker } from './cross-encoder.js';
|
|
2
|
+
import { redactSecrets } from '../secret-detect.js';
|
|
2
3
|
const ENDPOINT = 'https://api.typesafe.ai/v1/systemone';
|
|
3
4
|
const DEFAULT_TIMEOUT_MS = 5_000;
|
|
4
5
|
const TRUNCATE_CHARS = 1200;
|
|
@@ -32,8 +33,8 @@ async function requestScores(query, head) {
|
|
|
32
33
|
const key = process.env.TYPESAFE_API_KEY;
|
|
33
34
|
if (!key)
|
|
34
35
|
throw new Error('TYPESAFE_API_KEY not set');
|
|
35
|
-
const lines = head.map((r, i) => `[${i + 1}] ${truncate(r.entry.content, TRUNCATE_CHARS)}`);
|
|
36
|
-
const state = `Query: ${query}\n\nNumbered candidate memories from an AI coding agent's project store:\n\n${lines.join('\n\n')}`;
|
|
36
|
+
const lines = head.map((r, i) => `[${i + 1}] ${truncate(redactSecrets(r.entry.content), TRUNCATE_CHARS)}`);
|
|
37
|
+
const state = `Query: ${redactSecrets(query)}\n\nNumbered candidate memories from an AI coding agent's project store:\n\n${lines.join('\n\n')}`;
|
|
37
38
|
const questions = {};
|
|
38
39
|
for (let i = 1; i <= head.length; i++) {
|
|
39
40
|
questions[`c${i}`] = {
|
package/dist/rerankers/llm.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { redactSecrets } from '../secret-detect.js';
|
|
1
2
|
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
2
3
|
/**
|
|
3
4
|
* Track 3 reranker: listwise LLM rerank. Uses a customer-supplied
|
|
@@ -21,8 +22,8 @@ export const llmReranker = async (query, results, options) => {
|
|
|
21
22
|
const head = results.slice(0, topK);
|
|
22
23
|
const prompt = [
|
|
23
24
|
`Rerank the candidates below by relevance to the query. Output a JSON array of indices (zero-indexed) in best-first order.`,
|
|
24
|
-
`Query: ${query}`,
|
|
25
|
-
...head.map((r, i) => `[${i}] ${r.entry.content}`),
|
|
25
|
+
`Query: ${redactSecrets(query)}`,
|
|
26
|
+
...head.map((r, i) => `[${i}] ${redactSecrets(r.entry.content)}`),
|
|
26
27
|
`Output format: [<int>, <int>, ...] with all ${head.length} indices.`,
|
|
27
28
|
].join('\n');
|
|
28
29
|
const timeoutMs = Number.parseInt(process.env.HIPPO_LLM_RERANKER_TIMEOUT_MS ?? '', 10) || DEFAULT_TIMEOUT_MS;
|
package/dist/search.js
CHANGED
|
@@ -237,8 +237,8 @@ export async function hybridSearch(query, entries, options = {}) {
|
|
|
237
237
|
if (options.hippoRoot) {
|
|
238
238
|
try {
|
|
239
239
|
const provider = resolveEmbeddingProvider(options.hippoRoot);
|
|
240
|
-
|
|
241
|
-
|
|
240
|
+
const idx = provider.isAvailable() ? loadEmbeddingIndex(options.hippoRoot) : {};
|
|
241
|
+
if (provider.isAvailable() && !embeddingModelRequiresReindex(options.hippoRoot, provider.id, idx)) {
|
|
242
242
|
// Only spend a (possibly paid, off-box) query embedding when at least one
|
|
243
243
|
// of THIS search's entries has a cached vector to compare against. An
|
|
244
244
|
// index of only orphaned / out-of-scope vectors yields a meaningless
|
|
@@ -511,7 +511,7 @@ export async function hybridSearch(query, entries, options = {}) {
|
|
|
511
511
|
const head = ordered.slice(0, topK);
|
|
512
512
|
const tail = ordered.slice(topK);
|
|
513
513
|
const rerankInputWithRank = head.map((r, i) => ({ ...r, preRerankRank: i + 1 }));
|
|
514
|
-
const reranked = await options.reranker(query, rerankInputWithRank, options.rerankerOptions);
|
|
514
|
+
const reranked = await options.reranker(query, rerankInputWithRank, { ...options.rerankerOptions, topK });
|
|
515
515
|
const withPostRank = reranked.map((r, i) => ({ ...r, postRerankRank: i + 1 }));
|
|
516
516
|
ordered = [...withPostRank, ...tail];
|
|
517
517
|
}
|
package/dist/server.d.ts
CHANGED
|
@@ -15,6 +15,8 @@ export interface ServeOpts {
|
|
|
15
15
|
hippoRoot: string;
|
|
16
16
|
port?: number;
|
|
17
17
|
host?: string;
|
|
18
|
+
/** Stop and exit on SIGINT/SIGTERM. Only `hippo serve` owns the process, so only it sets this. */
|
|
19
|
+
handleSignals?: boolean;
|
|
18
20
|
}
|
|
19
21
|
/**
|
|
20
22
|
* Recognise loopback remote addresses. Node reports IPv6-mapped IPv4 as
|
|
@@ -22,6 +24,9 @@ export interface ServeOpts {
|
|
|
22
24
|
* the bare v4 and v6 loopbacks. Anything else is treated as remote.
|
|
23
25
|
*/
|
|
24
26
|
export declare function isLoopback(remoteAddress: string | undefined): boolean;
|
|
27
|
+
export declare const LOOPBACK_HOST_HEADER: RegExp;
|
|
28
|
+
/** A browser request sent by another site. Non-browser clients send neither header and pass. */
|
|
29
|
+
export declare function isCrossSite(req: IncomingMessage): boolean;
|
|
25
30
|
/**
|
|
26
31
|
* Rate-limit key for a request. Defaults to the socket's remote address.
|
|
27
32
|
*
|
package/dist/server.js
CHANGED
|
@@ -22,7 +22,7 @@ export function __resetSessionRecallHistoryHttp() {
|
|
|
22
22
|
import { PACKAGE_VERSION } from './version.js';
|
|
23
23
|
import { validateApiKey } from './auth.js';
|
|
24
24
|
import { createRateLimiter } from './rate-limit.js';
|
|
25
|
-
import { remember,
|
|
25
|
+
import { remember, retrieve, RecallContractError, ForbiddenError, drillDown, assemble, forget, promote, supersede, archiveRaw, authCreate, authList, authRevoke, auditList, outcome, outcomeForLastRecall, getContext, sleep, adminActor, } from './api.js';
|
|
26
26
|
import { buildGraphModel } from './graph-view.js';
|
|
27
27
|
import { MAX_ENTITY_NAME_LEN } from './graph.js';
|
|
28
28
|
import { savePrediction, closePrediction, loadPredictionById, loadPredictionsByClass, loadOpenPredictions, computePredictionBaserate, VALID_CLOSURE_STATES, } from './predictions.js';
|
|
@@ -289,10 +289,13 @@ async function parseJsonBody(req) {
|
|
|
289
289
|
* - /unknown/i → 404 (auth_revoke on unknown key_id)
|
|
290
290
|
* - /already superseded/i → 409 (chain conflict)
|
|
291
291
|
* - /not raw/i → 400 (archive_raw on non-raw row)
|
|
292
|
-
*
|
|
292
|
+
* ForbiddenError maps to 403; everything else to 400 (bad input).
|
|
293
293
|
*/
|
|
294
294
|
function mapApiError(err) {
|
|
295
295
|
const message = err instanceof Error ? err.message : String(err);
|
|
296
|
+
if (err instanceof ForbiddenError) {
|
|
297
|
+
return { status: 403, message };
|
|
298
|
+
}
|
|
296
299
|
const lower = message.toLowerCase();
|
|
297
300
|
if (/not found/.test(lower) || /^unknown /.test(lower)) {
|
|
298
301
|
return { status: 404, message };
|
|
@@ -354,6 +357,25 @@ export function isLoopback(remoteAddress) {
|
|
|
354
357
|
return true;
|
|
355
358
|
return false;
|
|
356
359
|
}
|
|
360
|
+
// Any other Host on a loopback socket is DNS rebinding: a hostile page resolved to 127.0.0.1.
|
|
361
|
+
export const LOOPBACK_HOST_HEADER = /^(localhost|127\.0\.0\.1|\[::1\])(:\d+)?$/i;
|
|
362
|
+
/** A browser request sent by another site. Non-browser clients send neither header and pass. */
|
|
363
|
+
export function isCrossSite(req) {
|
|
364
|
+
const site = req.headers['sec-fetch-site'];
|
|
365
|
+
if (site !== undefined && site !== 'same-origin' && site !== 'none')
|
|
366
|
+
return true;
|
|
367
|
+
const origin = req.headers.origin;
|
|
368
|
+
return origin !== undefined && origin !== `http://${req.headers.host}`;
|
|
369
|
+
}
|
|
370
|
+
// A browser on this machine is loopback too, so the no-key fallback also needs a local Host and a same-site caller.
|
|
371
|
+
function assertLocalCaller(req) {
|
|
372
|
+
if (!isLoopback(req.socket.remoteAddress))
|
|
373
|
+
throw new HttpError(401, 'auth required');
|
|
374
|
+
const host = req.headers.host;
|
|
375
|
+
if ((host !== undefined && !LOOPBACK_HOST_HEADER.test(host)) || isCrossSite(req)) {
|
|
376
|
+
throw new HttpError(403, 'cross-site or non-local request refused; send an API key');
|
|
377
|
+
}
|
|
378
|
+
}
|
|
357
379
|
function readAuthHeader(req) {
|
|
358
380
|
const raw = req.headers['authorization'];
|
|
359
381
|
if (raw === undefined)
|
|
@@ -455,9 +477,7 @@ function buildContextWithAuth(req, hippoRoot) {
|
|
|
455
477
|
if (process.env.HIPPO_REQUIRE_AUTH === '1') {
|
|
456
478
|
throw new HttpError(401, 'auth required');
|
|
457
479
|
}
|
|
458
|
-
|
|
459
|
-
throw new HttpError(401, 'auth required');
|
|
460
|
-
}
|
|
480
|
+
assertLocalCaller(req);
|
|
461
481
|
// v1.12.0: loopback fallback is process-local, treat as admin.
|
|
462
482
|
return {
|
|
463
483
|
hippoRoot,
|
|
@@ -492,9 +512,7 @@ function requireAuth(req, hippoRoot) {
|
|
|
492
512
|
if (process.env.HIPPO_REQUIRE_AUTH === '1') {
|
|
493
513
|
throw new HttpError(401, 'auth required');
|
|
494
514
|
}
|
|
495
|
-
|
|
496
|
-
throw new HttpError(401, 'auth required');
|
|
497
|
-
}
|
|
515
|
+
assertLocalCaller(req);
|
|
498
516
|
}
|
|
499
517
|
function getString(obj, key) {
|
|
500
518
|
const v = obj[key];
|
|
@@ -632,10 +650,7 @@ async function handleRequest(req, res, opts, startedAt, limiter) {
|
|
|
632
650
|
throw new HttpError(400, 'q is required');
|
|
633
651
|
}
|
|
634
652
|
const limitRaw = query.get('limit');
|
|
635
|
-
const limit = limitRaw === null ? undefined :
|
|
636
|
-
if (limit !== undefined && (!Number.isFinite(limit) || limit <= 0)) {
|
|
637
|
-
throw new HttpError(400, 'limit must be a positive number');
|
|
638
|
-
}
|
|
653
|
+
const limit = limitRaw === null ? undefined : parseListLimit(limitRaw);
|
|
639
654
|
const mode = query.get('mode');
|
|
640
655
|
if (mode !== null && mode !== 'bm25' && mode !== 'hybrid' && mode !== 'physics') {
|
|
641
656
|
throw new HttpError(400, "mode must be 'bm25', 'hybrid', or 'physics'");
|
|
@@ -671,11 +686,12 @@ async function handleRequest(req, res, opts, startedAt, limiter) {
|
|
|
671
686
|
const summarizeOverflow = summarizeOverflowRaw === null
|
|
672
687
|
? undefined
|
|
673
688
|
: (summarizeOverflowRaw === '1' || summarizeOverflowRaw === 'true');
|
|
674
|
-
//
|
|
675
|
-
// recall() which throws RecallContractError with code='invalid_scorer_window'.
|
|
676
|
-
// No transport-side validation; recall() owns the contract.
|
|
689
|
+
// recall() owns the shape rule (NaN, 0 and negatives throw invalid_scorer_window); the transport caps remote cost.
|
|
677
690
|
const scorerWindowRaw = query.get('scorer_window');
|
|
678
691
|
const scorerWindow = scorerWindowRaw === null ? undefined : Number(scorerWindowRaw);
|
|
692
|
+
if (scorerWindow !== undefined && scorerWindow > 1000) {
|
|
693
|
+
throw new HttpError(400, 'scorer_window must be <= 1000');
|
|
694
|
+
}
|
|
679
695
|
// v1.7.4: session_id for the dlPFC goal-stack boost. 256-char cap mirrors
|
|
680
696
|
// fresh_tail_session_id (above). Trim then drop if empty so api.recall
|
|
681
697
|
// sees undefined when the param is omitted or whitespace-only.
|
|
@@ -757,7 +773,7 @@ async function handleRequest(req, res, opts, startedAt, limiter) {
|
|
|
757
773
|
recallExtra.recallHistory = httpRecallHistory;
|
|
758
774
|
if (explain)
|
|
759
775
|
recallExtra.explain = explain;
|
|
760
|
-
const result =
|
|
776
|
+
const result = await retrieve(ctx, {
|
|
761
777
|
query: q,
|
|
762
778
|
limit,
|
|
763
779
|
mode: mode ?? undefined,
|
|
@@ -1038,7 +1054,8 @@ async function handleRequest(req, res, opts, startedAt, limiter) {
|
|
|
1038
1054
|
// Tenant scope (Episode A follow-up tracked in TODOS.md): api.sleep operates
|
|
1039
1055
|
// on the WHOLE hippoRoot (cross-tenant by design, matching CLI cmdSleep).
|
|
1040
1056
|
// The loopback-only guard is the trust boundary today. Future non-loopback
|
|
1041
|
-
// serving
|
|
1057
|
+
// serving must also zero the cross-tenant counters for other tenants
|
|
1058
|
+
// (D1 in docs/decisions/2026-05-24-blocked-items.md).
|
|
1042
1059
|
if (method === 'POST' && path === '/v1/sleep') {
|
|
1043
1060
|
// Defensive per-request loopback guard. Uses the canonical isLoopback()
|
|
1044
1061
|
// helper above so any future extension (additional mapped/IPv6 forms,
|
|
@@ -1084,11 +1101,7 @@ async function handleRequest(req, res, opts, startedAt, limiter) {
|
|
|
1084
1101
|
}
|
|
1085
1102
|
// v1.12.3: optional body.role mirrors the --role CLI flag. Validated
|
|
1086
1103
|
// strictly — anything other than 'admin'|'member' is a 400 (no silent
|
|
1087
|
-
// fallback to admin).
|
|
1088
|
-
// key for the same tenant; member Bearer minting an admin key is NOT
|
|
1089
|
-
// blocked here today (auth_create is currently unaudited per the A5 v2
|
|
1090
|
-
// note in authCreate doc). The HTTP layer trusts the buildContextWithAuth
|
|
1091
|
-
// role check at admin-gated routes; mint surface remains permissive.
|
|
1104
|
+
// fallback to admin). authCreate refuses a member caller with a 403.
|
|
1092
1105
|
const roleRaw = body['role'];
|
|
1093
1106
|
let role;
|
|
1094
1107
|
if (roleRaw !== undefined) {
|
|
@@ -1128,10 +1141,9 @@ async function handleRequest(req, res, opts, startedAt, limiter) {
|
|
|
1128
1141
|
sendJson(res, 200, result);
|
|
1129
1142
|
return;
|
|
1130
1143
|
}
|
|
1131
|
-
// DELETE /v1/auth/keys/:keyId — revoke.
|
|
1132
|
-
//
|
|
1133
|
-
//
|
|
1134
|
-
// surface revokedAt to the caller.
|
|
1144
|
+
// DELETE /v1/auth/keys/:keyId — revoke. Missing or cross-tenant keys are 404
|
|
1145
|
+
// (no info leak); a member key targeting any key but its own is 403.
|
|
1146
|
+
// 200 with the body rather than 204 so the caller sees revokedAt.
|
|
1135
1147
|
const keyMatch = matchPath('/v1/auth/keys/:keyId', path);
|
|
1136
1148
|
if (method === 'DELETE' && keyMatch) {
|
|
1137
1149
|
validateIdSegment(keyMatch.keyId, 'key id');
|
|
@@ -3228,9 +3240,7 @@ export async function serve(opts) {
|
|
|
3228
3240
|
server.close(() => resolve());
|
|
3229
3241
|
});
|
|
3230
3242
|
};
|
|
3231
|
-
|
|
3232
|
-
// stray SIGTERM/SIGINT listener that survives until the runner exits.
|
|
3233
|
-
if (!process.env.VITEST) {
|
|
3243
|
+
if (opts.handleSignals) {
|
|
3234
3244
|
let shuttingDown = false;
|
|
3235
3245
|
const gracefulShutdown = async (signal) => {
|
|
3236
3246
|
if (shuttingDown)
|
package/dist/shared.js
CHANGED
|
@@ -153,7 +153,7 @@ export async function searchBothHybrid(query, localRoot, globalRoot, options = {
|
|
|
153
153
|
if (!fs.existsSync(root))
|
|
154
154
|
return [];
|
|
155
155
|
return recallScope
|
|
156
|
-
? loadRecallSearchEntries(root, query, searchWindow, tenantId, recallScope.requested, recallScope.additive ? 'additive' : 'exact')
|
|
156
|
+
? loadRecallSearchEntries(root, query, searchWindow, tenantId, recallScope.requested, recallScope.additive ? 'additive' : 'exact', Boolean(includeSuperseded) || Boolean(asOf))
|
|
157
157
|
: loadSearchEntries(root, query, searchWindow, tenantId);
|
|
158
158
|
};
|
|
159
159
|
let localEntries = loadEntries(localRoot);
|