hippo-memory 1.59.0 → 1.61.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 +1 -1
- package/dist/ablation.js +9 -27
- package/dist/agent-memories/apply.js +4 -1
- package/dist/agent-memories/claude-code.js +1 -1
- package/dist/agent-memories/codex.js +1 -1
- package/dist/agent-memories/gemini.js +1 -1
- package/dist/agent-memories/legacy.js +1 -1
- package/dist/agent-memories/source.js +1 -1
- package/dist/agent-memories/sync.js +8 -3
- package/dist/ambient-store.d.ts +14 -0
- package/dist/ambient-store.js +90 -0
- package/dist/ambient.d.ts +23 -0
- package/dist/ambient.js +72 -50
- package/dist/api/assemble.d.ts +93 -0
- package/dist/api/assemble.js +152 -0
- package/dist/api/audit.d.ts +17 -0
- package/dist/api/audit.js +23 -0
- package/dist/api/auth.d.ts +79 -0
- package/dist/api/auth.js +178 -0
- package/dist/api/context-types.d.ts +105 -0
- package/dist/api/context-types.js +3 -0
- package/dist/api/context.d.ts +31 -0
- package/dist/api/context.js +705 -0
- package/dist/api/dormant.d.ts +30 -0
- package/dist/api/dormant.js +140 -0
- package/dist/api/drill-down.d.ts +84 -0
- package/dist/api/drill-down.js +123 -0
- package/dist/api/forget.d.ts +57 -0
- package/dist/api/forget.js +87 -0
- package/dist/api/goals.d.ts +18 -0
- package/dist/api/goals.js +33 -0
- package/dist/api/learn.d.ts +31 -0
- package/dist/api/learn.js +88 -0
- package/dist/api/outcome.d.ts +61 -0
- package/dist/api/outcome.js +66 -0
- package/dist/api/promote.d.ts +54 -0
- package/dist/api/promote.js +203 -0
- package/dist/api/quarantine.d.ts +24 -0
- package/dist/api/quarantine.js +121 -0
- package/dist/api/recall-types.d.ts +390 -0
- package/dist/api/recall-types.js +3 -0
- package/dist/api/recall.d.ts +36 -0
- package/dist/api/recall.js +634 -0
- package/dist/api/remember.d.ts +35 -0
- package/dist/api/remember.js +43 -0
- package/dist/api/sleep.d.ts +136 -0
- package/dist/api/sleep.js +271 -0
- package/dist/api/tokens.d.ts +26 -0
- package/dist/api/tokens.js +60 -0
- package/dist/api/types.d.ts +56 -0
- package/dist/api/types.js +38 -0
- package/dist/api.d.ts +20 -1260
- package/dist/api.js +25 -2711
- package/dist/audit.d.ts +3 -0
- package/dist/audit.js +7 -3
- package/dist/auth.d.ts +45 -4
- package/dist/auth.js +125 -48
- package/dist/autolearn.js +7 -4
- package/dist/capture/command.d.ts +33 -0
- package/dist/capture/command.js +264 -0
- package/dist/capture/compact.d.ts +44 -0
- package/dist/capture/compact.js +354 -0
- package/dist/capture/extract.d.ts +21 -0
- package/dist/capture/extract.js +464 -0
- package/dist/capture/transcript.d.ts +40 -0
- package/dist/capture/transcript.js +193 -0
- package/dist/capture-error.js +2 -1
- package/dist/churn-git.js +4 -2
- package/dist/cli/audit.d.ts +3 -0
- package/dist/cli/audit.js +159 -0
- package/dist/cli/auth.d.ts +2 -0
- package/dist/cli/auth.js +171 -0
- package/dist/cli/briefs.d.ts +4 -0
- package/dist/cli/briefs.js +435 -0
- package/dist/cli/card.d.ts +3 -0
- package/dist/cli/card.js +333 -0
- package/dist/cli/context.d.ts +15 -0
- package/dist/cli/context.js +366 -0
- package/dist/cli/continuity.d.ts +6 -0
- package/dist/cli/continuity.js +445 -0
- package/dist/cli/curate.d.ts +19 -0
- package/dist/cli/curate.js +555 -0
- package/dist/cli/dag.d.ts +5 -0
- package/dist/cli/dag.js +177 -0
- package/dist/cli/decisions.d.ts +4 -0
- package/dist/cli/decisions.js +528 -0
- package/dist/cli/eval.d.ts +5 -0
- package/dist/cli/eval.js +213 -0
- package/dist/cli/explain.d.ts +4 -0
- package/dist/cli/explain.js +150 -0
- package/dist/cli/goals.d.ts +2 -0
- package/dist/cli/goals.js +196 -0
- package/dist/cli/hook-blocks.d.ts +18 -0
- package/dist/cli/hook-blocks.js +233 -0
- package/dist/cli/init.d.ts +2 -0
- package/dist/cli/init.js +305 -0
- package/dist/cli/maintenance.d.ts +4 -0
- package/dist/cli/maintenance.js +179 -0
- package/dist/cli/playbooks.d.ts +4 -0
- package/dist/cli/playbooks.js +556 -0
- package/dist/cli/projects.js +1 -1
- package/dist/cli/recall.d.ts +7 -0
- package/dist/cli/recall.js +597 -0
- package/dist/cli/remember.d.ts +5 -0
- package/dist/cli/remember.js +442 -0
- package/dist/cli/serve.d.ts +5 -0
- package/dist/cli/serve.js +40 -0
- package/dist/cli/session-hooks.d.ts +29 -0
- package/dist/cli/session-hooks.js +637 -0
- package/dist/cli/setup.d.ts +4 -0
- package/dist/cli/setup.js +376 -0
- package/dist/cli/shared.d.ts +15 -19
- package/dist/cli/shared.js +50 -341
- package/dist/cli/slack.d.ts +2 -0
- package/dist/cli/slack.js +171 -0
- package/dist/cli/status.d.ts +18 -0
- package/dist/cli/status.js +400 -0
- package/dist/cli/transfer.d.ts +10 -0
- package/dist/cli/transfer.js +438 -0
- package/dist/cli/usage.d.ts +85 -0
- package/dist/cli/usage.js +741 -0
- package/dist/cli.d.ts +319 -13
- package/dist/cli.js +436 -8580
- package/dist/client.js +15 -8
- package/dist/compaction-record.js +12 -9
- package/dist/config.js +12 -11
- package/dist/connectors/github/backfill.js +94 -87
- package/dist/connectors/github/cli-impl.js +5 -3
- package/dist/connectors/github/dlq.js +67 -54
- package/dist/connectors/github/ingest.js +34 -35
- package/dist/connectors/github/tenant-routing.js +3 -2
- package/dist/connectors/github/webhook.js +135 -216
- package/dist/connectors/slack/dlq.js +49 -61
- package/dist/connectors/slack/ingest.js +55 -48
- package/dist/connectors/slack/tenant-routing.js +4 -3
- package/dist/connectors/slack/webhook.js +72 -74
- package/dist/consolidate/conflicts.d.ts +10 -0
- package/dist/consolidate/conflicts.js +178 -0
- package/dist/consolidate/decay.d.ts +12 -0
- package/dist/consolidate/decay.js +145 -0
- package/dist/consolidate/llm-passes.d.ts +3 -0
- package/dist/consolidate/llm-passes.js +141 -0
- package/dist/consolidate/merge.d.ts +7 -0
- package/dist/consolidate/merge.js +251 -0
- package/dist/consolidate/physics-pass.d.ts +3 -0
- package/dist/consolidate/physics-pass.js +60 -0
- package/dist/consolidate/run.d.ts +69 -0
- package/dist/consolidate/run.js +76 -0
- package/dist/consolidate/sleep.d.ts +18 -0
- package/dist/consolidate/sleep.js +209 -0
- package/dist/consolidate/traces.d.ts +4 -0
- package/dist/consolidate/traces.js +178 -0
- package/dist/context-auto.js +7 -11
- package/dist/context-render.d.ts +1 -1
- package/dist/context-render.js +1 -1
- package/dist/customer-notes.d.ts +3 -0
- package/dist/customer-notes.js +6 -4
- package/dist/dag.js +13 -12
- package/dist/dashboard-actions.d.ts +20 -0
- package/dist/dashboard-actions.js +88 -0
- package/dist/dashboard-params.d.ts +45 -0
- package/dist/dashboard-params.js +127 -0
- package/dist/dashboard-queries.d.ts +15 -0
- package/dist/dashboard-queries.js +355 -0
- package/dist/dashboard-snapshot.d.ts +138 -0
- package/dist/dashboard-snapshot.js +308 -0
- package/dist/dashboard-types.d.ts +163 -0
- package/dist/dashboard-types.js +3 -0
- package/dist/dashboard.d.ts +6 -7
- package/dist/dashboard.js +231 -203
- package/dist/db/busy.d.ts +5 -0
- package/dist/db/busy.js +24 -0
- package/dist/db/continuity.d.ts +5 -0
- package/dist/db/continuity.js +145 -0
- package/dist/db/meta.d.ts +8 -0
- package/dist/db/meta.js +35 -0
- package/dist/db/migrate.d.ts +9 -0
- package/dist/db/migrate.js +138 -0
- package/dist/db/migrations/index.d.ts +5 -0
- package/dist/db/migrations/index.js +109 -0
- package/dist/db/migrations/types.d.ts +14 -0
- package/dist/db/migrations/types.js +2 -0
- package/dist/db/migrations/v01.d.ts +3 -0
- package/dist/db/migrations/v01.js +38 -0
- package/dist/db/migrations/v02.d.ts +3 -0
- package/dist/db/migrations/v02.js +21 -0
- package/dist/db/migrations/v03.d.ts +3 -0
- package/dist/db/migrations/v03.js +22 -0
- package/dist/db/migrations/v04.d.ts +3 -0
- package/dist/db/migrations/v04.js +28 -0
- package/dist/db/migrations/v05.d.ts +3 -0
- package/dist/db/migrations/v05.js +21 -0
- package/dist/db/migrations/v06.d.ts +3 -0
- package/dist/db/migrations/v06.js +25 -0
- package/dist/db/migrations/v07.d.ts +3 -0
- package/dist/db/migrations/v07.js +13 -0
- package/dist/db/migrations/v08.d.ts +3 -0
- package/dist/db/migrations/v08.js +8 -0
- package/dist/db/migrations/v09.d.ts +3 -0
- package/dist/db/migrations/v09.js +13 -0
- package/dist/db/migrations/v10.d.ts +3 -0
- package/dist/db/migrations/v10.js +17 -0
- package/dist/db/migrations/v11.d.ts +3 -0
- package/dist/db/migrations/v11.js +15 -0
- package/dist/db/migrations/v12.d.ts +3 -0
- package/dist/db/migrations/v12.js +11 -0
- package/dist/db/migrations/v13.d.ts +3 -0
- package/dist/db/migrations/v13.js +15 -0
- package/dist/db/migrations/v14.d.ts +3 -0
- package/dist/db/migrations/v14.js +66 -0
- package/dist/db/migrations/v15.d.ts +3 -0
- package/dist/db/migrations/v15.js +42 -0
- package/dist/db/migrations/v16.d.ts +3 -0
- package/dist/db/migrations/v16.js +61 -0
- package/dist/db/migrations/v17.d.ts +3 -0
- package/dist/db/migrations/v17.js +46 -0
- package/dist/db/migrations/v18.d.ts +3 -0
- package/dist/db/migrations/v18.js +60 -0
- package/dist/db/migrations/v19.d.ts +3 -0
- package/dist/db/migrations/v19.js +28 -0
- package/dist/db/migrations/v20.d.ts +3 -0
- package/dist/db/migrations/v20.js +42 -0
- package/dist/db/migrations/v21.d.ts +3 -0
- package/dist/db/migrations/v21.js +16 -0
- package/dist/db/migrations/v22.d.ts +3 -0
- package/dist/db/migrations/v22.js +82 -0
- package/dist/db/migrations/v23.d.ts +3 -0
- package/dist/db/migrations/v23.js +48 -0
- package/dist/db/migrations/v24.d.ts +3 -0
- package/dist/db/migrations/v24.js +72 -0
- package/dist/db/migrations/v25.d.ts +3 -0
- package/dist/db/migrations/v25.js +46 -0
- package/dist/db/migrations/v26.d.ts +3 -0
- package/dist/db/migrations/v26.js +23 -0
- package/dist/db/migrations/v27.d.ts +3 -0
- package/dist/db/migrations/v27.js +57 -0
- package/dist/db/migrations/v28.d.ts +3 -0
- package/dist/db/migrations/v28.js +38 -0
- package/dist/db/migrations/v29.d.ts +3 -0
- package/dist/db/migrations/v29.js +78 -0
- package/dist/db/migrations/v30.d.ts +3 -0
- package/dist/db/migrations/v30.js +92 -0
- package/dist/db/migrations/v31.d.ts +3 -0
- package/dist/db/migrations/v31.js +74 -0
- package/dist/db/migrations/v32.d.ts +3 -0
- package/dist/db/migrations/v32.js +102 -0
- package/dist/db/migrations/v33.d.ts +3 -0
- package/dist/db/migrations/v33.js +104 -0
- package/dist/db/migrations/v34.d.ts +3 -0
- package/dist/db/migrations/v34.js +93 -0
- package/dist/db/migrations/v35.d.ts +3 -0
- package/dist/db/migrations/v35.js +98 -0
- package/dist/db/migrations/v36.d.ts +3 -0
- package/dist/db/migrations/v36.js +98 -0
- package/dist/db/migrations/v37.d.ts +3 -0
- package/dist/db/migrations/v37.js +219 -0
- package/dist/db/migrations/v38.d.ts +3 -0
- package/dist/db/migrations/v38.js +277 -0
- package/dist/db/migrations/v39.d.ts +3 -0
- package/dist/db/migrations/v39.js +59 -0
- package/dist/db/migrations/v40.d.ts +3 -0
- package/dist/db/migrations/v40.js +74 -0
- package/dist/db/migrations/v41.d.ts +3 -0
- package/dist/db/migrations/v41.js +43 -0
- package/dist/db/migrations/v42.d.ts +3 -0
- package/dist/db/migrations/v42.js +41 -0
- package/dist/db/migrations/v43.d.ts +3 -0
- package/dist/db/migrations/v43.js +67 -0
- package/dist/db/migrations/v44.d.ts +3 -0
- package/dist/db/migrations/v44.js +28 -0
- package/dist/db/migrations/v45.d.ts +3 -0
- package/dist/db/migrations/v45.js +30 -0
- package/dist/db/migrations/v46.d.ts +3 -0
- package/dist/db/migrations/v46.js +25 -0
- package/dist/db/migrations/v47.d.ts +3 -0
- package/dist/db/migrations/v47.js +17 -0
- package/dist/db/migrations/v48.d.ts +3 -0
- package/dist/db/migrations/v48.js +10 -0
- package/dist/db/migrations/v49.d.ts +3 -0
- package/dist/db/migrations/v49.js +31 -0
- package/dist/db/migrations/v50.d.ts +3 -0
- package/dist/db/migrations/v50.js +67 -0
- package/dist/db/migrations/v51.d.ts +3 -0
- package/dist/db/migrations/v51.js +14 -0
- package/dist/db/migrations/v52.d.ts +3 -0
- package/dist/db/migrations/v52.js +7 -0
- package/dist/db/open.d.ts +23 -0
- package/dist/db/open.js +146 -0
- package/dist/db/sqlite.d.ts +21 -0
- package/dist/db/sqlite.js +8 -0
- package/dist/db/tables.d.ts +7 -0
- package/dist/db/tables.js +38 -0
- package/dist/db.d.ts +6 -46
- package/dist/db.js +5 -3036
- package/dist/decisions.d.ts +4 -1
- package/dist/decisions.js +9 -7
- package/dist/dedupe.js +3 -2
- package/dist/delivery-recorder.js +5 -1
- package/dist/doctor.js +4 -3
- package/dist/dormant.js +1 -0
- package/dist/embedding-provider.d.ts +1 -1
- package/dist/embedding-provider.js +7 -5
- package/dist/embeddings.d.ts +9 -52
- package/dist/embeddings.js +47 -298
- package/dist/env.d.ts +75 -0
- package/dist/env.js +119 -0
- package/dist/eval-suite.js +1 -1
- package/dist/eval.js +2 -2
- package/dist/extract.js +5 -4
- package/dist/gated-write.js +3 -1
- package/dist/goals.d.ts +3 -1
- package/dist/goals.js +18 -0
- package/dist/graph/read.d.ts +73 -0
- package/dist/graph/read.js +325 -0
- package/dist/graph/rows.d.ts +45 -0
- package/dist/graph/rows.js +51 -0
- package/dist/graph/types.d.ts +83 -0
- package/dist/graph/types.js +11 -0
- package/dist/graph/write.d.ts +93 -0
- package/dist/{graph.js → graph/write.js} +8 -391
- package/dist/graph-extract.js +2 -1
- package/dist/graph-recall.d.ts +1 -1
- package/dist/graph-recall.js +2 -2
- package/dist/graph-stream.js +1 -1
- package/dist/graph-view.d.ts +1 -1
- package/dist/graph-view.js +1 -1
- package/dist/half-life-migration.d.ts +1 -1
- package/dist/half-life-migration.js +2 -1
- package/dist/handoff.js +3 -0
- package/dist/hooks/codex-session.d.ts +8 -0
- package/dist/hooks/codex-session.js +76 -0
- package/dist/hooks/codex-wrapper.d.ts +55 -0
- package/dist/hooks/codex-wrapper.js +288 -0
- package/dist/hooks/json-hooks.d.ts +63 -0
- package/dist/hooks/json-hooks.js +356 -0
- package/dist/hooks/opencode.d.ts +50 -0
- package/dist/hooks/opencode.js +202 -0
- package/dist/hooks/shared.d.ts +54 -0
- package/dist/hooks/shared.js +77 -0
- package/dist/http-retry.d.ts +2 -0
- package/dist/http-retry.js +4 -3
- package/dist/http-util.d.ts +3 -0
- package/dist/http-util.js +10 -0
- package/dist/{importers.d.ts → importers/core.d.ts} +13 -17
- package/dist/importers/core.js +141 -0
- package/dist/importers/markdown-parse.d.ts +41 -0
- package/dist/importers/markdown-parse.js +132 -0
- package/dist/importers/markdown.d.ts +3 -0
- package/dist/importers/markdown.js +92 -0
- package/dist/importers/sources.d.ts +7 -0
- package/dist/importers/sources.js +229 -0
- package/dist/importers/vault.d.ts +11 -0
- package/dist/importers/vault.js +352 -0
- package/dist/incidents.d.ts +3 -0
- package/dist/incidents.js +8 -5
- package/dist/index.d.ts +25 -6
- package/dist/index.js +23 -6
- package/dist/invalidation.js +2 -1
- package/dist/judgment.js +7 -3
- package/dist/keyset.d.ts +13 -0
- package/dist/keyset.js +8 -0
- package/dist/local-embedding.d.ts +13 -0
- package/dist/local-embedding.js +165 -0
- package/dist/log.d.ts +7 -0
- package/dist/log.js +19 -1
- package/dist/mcp/admin-tools.d.ts +8 -0
- package/dist/mcp/admin-tools.js +116 -0
- package/dist/mcp/format.d.ts +27 -0
- package/dist/mcp/format.js +135 -0
- package/dist/mcp/memory-tools.d.ts +5 -0
- package/dist/mcp/memory-tools.js +83 -0
- package/dist/mcp/protocol.d.ts +83 -0
- package/dist/mcp/protocol.js +55 -0
- package/dist/mcp/recall-tools.d.ts +6 -0
- package/dist/mcp/recall-tools.js +320 -0
- package/dist/mcp/request.d.ts +10 -0
- package/dist/mcp/request.js +163 -0
- package/dist/mcp/server.d.ts +4 -70
- package/dist/mcp/server.js +8 -1172
- package/dist/mcp/session-state.d.ts +11 -0
- package/dist/mcp/session-state.js +28 -0
- package/dist/mcp/stdio.d.ts +8 -0
- package/dist/mcp/stdio.js +79 -0
- package/dist/mcp/tools.d.ts +11 -0
- package/dist/mcp/tools.js +247 -0
- package/dist/memory.d.ts +8 -3
- package/dist/memory.js +27 -1
- package/dist/multihop.d.ts +1 -1
- package/dist/multihop.js +2 -1
- package/dist/owner-validation.js +2 -1
- package/dist/physics-state.js +10 -7
- package/dist/policies.d.ts +3 -0
- package/dist/policies.js +8 -6
- package/dist/postinstall.js +3 -2
- package/dist/predictions/planning-fallacy.d.ts +100 -0
- package/dist/predictions/planning-fallacy.js +190 -0
- package/dist/{predictions.d.ts → predictions/store.d.ts} +7 -102
- package/dist/predictions/store.js +434 -0
- package/dist/processes.d.ts +3 -0
- package/dist/processes.js +8 -5
- package/dist/project-briefs.d.ts +3 -0
- package/dist/project-briefs.js +7 -5
- package/dist/project-identity.d.ts +1 -1
- package/dist/project-identity.js +12 -6
- package/dist/project-merge.js +3 -1
- package/dist/quarantine.d.ts +2 -1
- package/dist/quarantine.js +8 -5
- package/dist/raw-archive-mirror-cleanup.js +2 -1
- package/dist/raw-archive.js +1 -1
- package/dist/recall-history.js +3 -2
- package/dist/recall-pipeline.d.ts +2 -2
- package/dist/recall-pipeline.js +16 -8
- package/dist/recall-scope.js +1 -1
- package/dist/recall-trace.d.ts +3 -3
- package/dist/recall-trace.js +10 -14
- package/dist/refine-llm.js +20 -11
- package/dist/reject-flow.js +6 -1
- package/dist/rerankers/clef.d.ts +2 -2
- package/dist/rerankers/clef.js +72 -30
- package/dist/rerankers/cross-encoder.js +6 -4
- package/dist/rerankers/jev.d.ts +4 -2
- package/dist/rerankers/jev.js +24 -19
- package/dist/rerankers/llm.d.ts +4 -2
- package/dist/rerankers/llm.js +61 -41
- package/dist/rerankers/types.d.ts +1 -1
- package/dist/salience.js +1 -1
- package/dist/same-text.d.ts +2 -0
- package/dist/same-text.js +4 -0
- package/dist/scheduler.d.ts +1 -0
- package/dist/scheduler.js +26 -3
- package/dist/scope.js +4 -3
- package/dist/search/as-of.d.ts +10 -0
- package/dist/search/as-of.js +22 -0
- package/dist/search/bm25-search.d.ts +14 -0
- package/dist/search/bm25-search.js +43 -0
- package/dist/search/bm25.d.ts +15 -0
- package/dist/search/bm25.js +54 -0
- package/dist/search/boosts.d.ts +54 -0
- package/dist/search/boosts.js +94 -0
- package/dist/search/breakdown.d.ts +7 -0
- package/dist/search/breakdown.js +20 -0
- package/dist/search/explain.d.ts +25 -0
- package/dist/search/explain.js +31 -0
- package/dist/search/finalize.d.ts +8 -0
- package/dist/search/finalize.js +52 -0
- package/dist/search/fusion.d.ts +27 -0
- package/dist/search/fusion.js +42 -0
- package/dist/search/hybrid-score.d.ts +20 -0
- package/dist/search/hybrid-score.js +73 -0
- package/dist/search/hybrid.d.ts +46 -0
- package/dist/search/hybrid.js +64 -0
- package/dist/search/physics-search.d.ts +29 -0
- package/dist/search/physics-search.js +162 -0
- package/dist/search/rerank.d.ts +10 -0
- package/dist/search/rerank.js +72 -0
- package/dist/search/temporal.d.ts +15 -0
- package/dist/search/temporal.js +45 -0
- package/dist/search/types.d.ts +91 -0
- package/dist/search/types.js +2 -0
- package/dist/search/vector.d.ts +30 -0
- package/dist/search/vector.js +71 -0
- package/dist/secret-detect.d.ts +2 -0
- package/dist/secret-detect.js +3 -1
- package/dist/server/auth.d.ts +52 -0
- package/dist/server/auth.js +221 -0
- package/dist/server/client-ip.d.ts +25 -0
- package/dist/server/client-ip.js +92 -0
- package/dist/server/cursor.d.ts +23 -0
- package/dist/server/cursor.js +58 -0
- package/dist/server/lifecycle.d.ts +7 -0
- package/dist/server/lifecycle.js +29 -0
- package/dist/server/mcp-http.d.ts +5 -0
- package/dist/server/mcp-http.js +199 -0
- package/dist/server/request.d.ts +33 -0
- package/dist/server/request.js +103 -0
- package/dist/server/routes/admin.d.ts +9 -0
- package/dist/server/routes/admin.js +158 -0
- package/dist/server/routes/customer-notes.d.ts +7 -0
- package/dist/server/routes/customer-notes.js +112 -0
- package/dist/server/routes/decisions.d.ts +7 -0
- package/dist/server/routes/decisions.js +133 -0
- package/dist/server/routes/incidents.d.ts +7 -0
- package/dist/server/routes/incidents.js +126 -0
- package/dist/server/routes/memories.d.ts +10 -0
- package/dist/server/routes/memories.js +179 -0
- package/dist/server/routes/policies.d.ts +8 -0
- package/dist/server/routes/policies.js +151 -0
- package/dist/server/routes/predictions.d.ts +7 -0
- package/dist/server/routes/predictions.js +164 -0
- package/dist/server/routes/processes.d.ts +7 -0
- package/dist/server/routes/processes.js +161 -0
- package/dist/server/routes/project-briefs.d.ts +8 -0
- package/dist/server/routes/project-briefs.js +136 -0
- package/dist/server/routes/recall.d.ts +8 -0
- package/dist/server/routes/recall.js +340 -0
- package/dist/server/routes/skills.d.ts +8 -0
- package/dist/server/routes/skills.js +150 -0
- package/dist/server/types.d.ts +56 -0
- package/dist/server/types.js +2 -0
- package/dist/server/validation.d.ts +14 -0
- package/dist/server/validation.js +91 -0
- package/dist/server.d.ts +7 -61
- package/dist/server.js +92 -2368
- package/dist/session-digest.d.ts +1 -1
- package/dist/session-digest.js +9 -2
- package/dist/shared.d.ts +3 -1
- package/dist/shared.js +46 -40
- package/dist/skills.d.ts +3 -0
- package/dist/skills.js +7 -5
- package/dist/stdin.js +3 -2
- package/dist/store/audit-event.d.ts +19 -0
- package/dist/store/audit-event.js +33 -0
- package/dist/store/candidates.d.ts +42 -0
- package/dist/store/candidates.js +152 -0
- package/dist/store/conflicts.d.ts +44 -0
- package/dist/store/conflicts.js +444 -0
- package/dist/store/delete-and-batch.d.ts +63 -0
- package/dist/store/delete-and-batch.js +310 -0
- package/dist/store/entry-reads.d.ts +92 -0
- package/dist/store/entry-reads.js +255 -0
- package/dist/store/entry-row.d.ts +67 -0
- package/dist/store/entry-row.js +208 -0
- package/dist/store/entry-writes.d.ts +46 -0
- package/dist/store/entry-writes.js +148 -0
- package/dist/store/handoffs.d.ts +26 -0
- package/dist/store/handoffs.js +184 -0
- package/dist/store/index-and-stats.d.ts +52 -0
- package/dist/store/index-and-stats.js +214 -0
- package/dist/store/markdown.d.ts +10 -0
- package/dist/store/markdown.js +108 -0
- package/dist/store/mirrors.d.ts +49 -0
- package/dist/store/mirrors.js +312 -0
- package/dist/store/open.d.ts +15 -0
- package/dist/store/open.js +223 -0
- package/dist/store/rows.d.ts +178 -0
- package/dist/store/rows.js +158 -0
- package/dist/store/search-rows.d.ts +86 -0
- package/dist/store/search-rows.js +254 -0
- package/dist/store/sessions.d.ts +83 -0
- package/dist/store/sessions.js +272 -0
- package/dist/store/summaries.d.ts +94 -0
- package/dist/store/summaries.js +377 -0
- package/dist/store/tenant-lookup.d.ts +12 -0
- package/dist/store/tenant-lookup.js +16 -0
- package/dist/store-cards.js +2 -1
- package/dist/summary-dirty.d.ts +4 -0
- package/dist/summary-dirty.js +32 -0
- package/dist/support-bundle.js +4 -3
- package/dist/tenant.js +2 -2
- package/dist/token-ledger.js +1 -0
- package/dist/tokenize.d.ts +2 -0
- package/dist/tokenize.js +16 -0
- package/dist/transcript-tail.d.ts +7 -0
- package/dist/transcript-tail.js +48 -0
- package/dist/vector-store.d.ts +27 -0
- package/dist/vector-store.js +210 -0
- package/dist/version.d.ts +2 -2
- package/dist/version.js +2 -2
- package/dist/working-memory.js +1 -1
- package/dist/yaml.js +36 -11
- package/dist-ui/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
- package/dist-ui/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
- package/dist-ui/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
- package/dist-ui/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
- package/dist-ui/assets/ibm-plex-mono-latin-600-normal-BgSNZQsw.woff2 +0 -0
- package/dist-ui/assets/ibm-plex-mono-latin-600-normal-DWFSQ4vo.woff +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
- package/dist-ui/assets/index-DPN7cP19.js +33 -0
- package/dist-ui/assets/index-dFloKRVr.css +1 -0
- package/dist-ui/index.html +3 -25
- 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 +2 -1
- package/dist/capture.d.ts +0 -155
- package/dist/capture.js +0 -1293
- package/dist/consolidate.d.ts +0 -58
- package/dist/consolidate.js +0 -1123
- package/dist/graph.d.ts +0 -245
- package/dist/hooks.d.ts +0 -208
- package/dist/hooks.js +0 -1073
- package/dist/importers.js +0 -897
- package/dist/predictions.js +0 -620
- package/dist/search.d.ts +0 -320
- package/dist/search.js +0 -968
- package/dist/store.d.ts +0 -744
- package/dist/store.js +0 -3372
- package/dist-ui/assets/d3-BiWEKnn4.js +0 -1
- package/dist-ui/assets/index-BhT8RvO6.js +0 -61
- package/dist-ui/assets/index-RoXXJ5dq.css +0 -1
- package/dist-ui/assets/three-BDgTxR1l.js +0 -4112
package/dist/quarantine.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/** Quarantine tier (CD5, AT3): pending/approved/rejected record for a memory `remember` flagged as untrusted. */
|
|
2
2
|
import { appendAuditEvent } from './audit.js';
|
|
3
|
+
import { keysetAfter } from './keyset.js';
|
|
3
4
|
export const QUARANTINE_SCOPE_PREFIX = 'quarantine:private:';
|
|
4
5
|
/** Scope a quarantined memory is stored under; matches PRIVATE_SCOPE_RE so every default-deny site hides it. */
|
|
5
6
|
export function quarantineScopeFor(original) {
|
|
@@ -39,16 +40,18 @@ export function getQuarantineRow(db, tenantId, memoryId) {
|
|
|
39
40
|
.get(tenantId, memoryId);
|
|
40
41
|
return row ? fromDbRow(row) : null;
|
|
41
42
|
}
|
|
42
|
-
export function listQuarantineRows(db, tenantId, status = 'pending', limit = 100) {
|
|
43
|
+
export function listQuarantineRows(db, tenantId, status = 'pending', limit = 100, afterRow) {
|
|
43
44
|
// A pending row whose memory was deleted (e.g. Slack message_deleted) is dead; keep its history, drop it from the queue.
|
|
44
45
|
const live = status === 'pending'
|
|
45
46
|
? ' AND EXISTS (SELECT 1 FROM memories m WHERE m.id = memory_quarantine.memory_id AND m.tenant_id = memory_quarantine.tenant_id)'
|
|
46
47
|
: '';
|
|
48
|
+
const after = keysetAfter('quarantined_at', 'memory_id', afterRow);
|
|
49
|
+
const order = 'ORDER BY quarantined_at DESC, memory_id DESC LIMIT ?';
|
|
47
50
|
const rows = status === 'all'
|
|
48
|
-
? db.prepare(`SELECT ${SELECT_COLUMNS} FROM memory_quarantine WHERE tenant_id =
|
|
49
|
-
.all(tenantId, limit)
|
|
50
|
-
: db.prepare(`SELECT ${SELECT_COLUMNS} FROM memory_quarantine WHERE tenant_id = ? AND status = ?${live}
|
|
51
|
-
.all(tenantId, status, limit);
|
|
51
|
+
? db.prepare(`SELECT ${SELECT_COLUMNS} FROM memory_quarantine WHERE tenant_id = ?${after.sql} ${order}`)
|
|
52
|
+
.all(tenantId, ...after.params, limit)
|
|
53
|
+
: db.prepare(`SELECT ${SELECT_COLUMNS} FROM memory_quarantine WHERE tenant_id = ? AND status = ?${live}${after.sql} ${order}`)
|
|
54
|
+
.all(tenantId, status, ...after.params, limit);
|
|
52
55
|
// SAFETY: both branches select SELECT_COLUMNS, matching QuarantineDbRow's field set.
|
|
53
56
|
return rows.map(fromDbRow);
|
|
54
57
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
|
+
import { log } from './log.js';
|
|
3
4
|
const LAYERS = ['episodic', 'buffer', 'semantic'];
|
|
4
5
|
const MAX_WARN_LOGS = 5;
|
|
5
6
|
/**
|
|
@@ -42,7 +43,7 @@ export function cleanupArchivedMirrors(hippoRoot, db) {
|
|
|
42
43
|
catch (err) {
|
|
43
44
|
allOk = false;
|
|
44
45
|
if (warnCount < MAX_WARN_LOGS) {
|
|
45
|
-
|
|
46
|
+
log.warn(`cleanupArchivedMirrors: unlink failed for ${filePath} (will retry on next DB open): ${err instanceof Error ? err.message : String(err)}`);
|
|
46
47
|
warnCount += 1;
|
|
47
48
|
}
|
|
48
49
|
}
|
package/dist/raw-archive.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BadRequestError, NotFoundError } from './api-errors.js';
|
|
2
2
|
import { isFtsAvailable } from './db.js';
|
|
3
3
|
import { appendAuditEvent, reportAuditWriteFailure } from './audit.js';
|
|
4
|
-
import { markSummaryDirtyInTx } from './
|
|
4
|
+
import { markSummaryDirtyInTx } from './summary-dirty.js';
|
|
5
5
|
export function archiveRawMemory(db, id, opts) {
|
|
6
6
|
// SAFETY: SELECT * FROM memories returns every column of the memories table; only
|
|
7
7
|
// kind, tenant_id, and dag_parent_id are read below, all guaranteed present (possibly
|
package/dist/recall-history.js
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
* Composes with J3.2: AnchoringHint + PlanningFallacyHint are independent
|
|
19
19
|
* signals; both can fire on the same recall.
|
|
20
20
|
*/
|
|
21
|
+
import { envAnchoringOff, envAvailabilityOff } from './env.js';
|
|
21
22
|
const DEFAULT_MIN_DOMINANCE = 3;
|
|
22
23
|
const DEFAULT_RECENT_REPEAT_WINDOW = 5;
|
|
23
24
|
const DEFAULT_COOLDOWN = 3;
|
|
@@ -238,7 +239,7 @@ export function snapshotRing(ring) {
|
|
|
238
239
|
*/
|
|
239
240
|
export function biasHintEnabled(kind) {
|
|
240
241
|
return kind === 'anchoring'
|
|
241
|
-
?
|
|
242
|
-
:
|
|
242
|
+
? !envAnchoringOff()
|
|
243
|
+
: !envAvailabilityOff();
|
|
243
244
|
}
|
|
244
245
|
//# sourceMappingURL=recall-history.js.map
|
|
@@ -2,7 +2,7 @@ import { type GoalRecallLogRow } from './goals.js';
|
|
|
2
2
|
import { type MemoryEntry } from './memory.js';
|
|
3
3
|
import type { PhysicsConfig } from './physics-config.js';
|
|
4
4
|
import type { RerankerFn } from './rerankers/types.js';
|
|
5
|
-
import {
|
|
5
|
+
import type { ResultCost, SearchResult } from './search/types.js';
|
|
6
6
|
/** Stores rankRecall reads and where it sends operator notes. */
|
|
7
7
|
export interface RankRecallCtx {
|
|
8
8
|
hippoRoot: string;
|
|
@@ -23,7 +23,7 @@ export interface RecallSearchOpts {
|
|
|
23
23
|
mmrLambda: number;
|
|
24
24
|
localBump: number;
|
|
25
25
|
minResults?: number;
|
|
26
|
-
/** Score breakdowns for `hippo explain`; explain's physics call also leaves out
|
|
26
|
+
/** Score breakdowns for `hippo explain`; explain's physics call also leaves out minResults and includeSuperseded. */
|
|
27
27
|
explain: boolean;
|
|
28
28
|
}
|
|
29
29
|
/** `--graph-hops` and `--graph-seeds`. */
|
package/dist/recall-pipeline.js
CHANGED
|
@@ -4,17 +4,18 @@ import { evalNow } from './ablation.js';
|
|
|
4
4
|
import { oneCopyPerMemory } from './api.js';
|
|
5
5
|
import { compareEntryIdentity } from './compare.js';
|
|
6
6
|
import { closeHippoDb, openHippoDb } from './db.js';
|
|
7
|
-
import { isEmbeddingAvailable } from './
|
|
7
|
+
import { isEmbeddingAvailable } from './local-embedding.js';
|
|
8
8
|
import { computeGoalStackBoost } from './goals.js';
|
|
9
9
|
import { graphExpandRecall } from './graph-recall.js';
|
|
10
10
|
import { DEFAULT_GRAPH_STREAM_WEIGHT } from './graph-stream.js';
|
|
11
11
|
import { Layer } from './memory.js';
|
|
12
12
|
import { multihopSearch } from './multihop.js';
|
|
13
13
|
import { passesCliRecallScopeFilter } from './recall-scope.js';
|
|
14
|
-
import { hybridSearch
|
|
14
|
+
import { hybridSearch } from './search/hybrid.js';
|
|
15
|
+
import { physicsSearch } from './search/physics-search.js';
|
|
15
16
|
import { searchBothHybrid } from './shared.js';
|
|
16
|
-
import { loadRecallSearchEntries } from './store.js';
|
|
17
|
-
import { tokenize as tokenizeQuery } from './tokenize.js';
|
|
17
|
+
import { loadRecallSearchEntries, recallScopeFilter } from './store/search-rows.js';
|
|
18
|
+
import { textOverlap, tokenize as tokenizeQuery } from './tokenize.js';
|
|
18
19
|
/** Ranks memories for a query as `hippo recall` does, through the `limit` slice. Reads stores, embeddings and
|
|
19
20
|
* physics state; writes nothing and prints nothing (notes go to `ctx.note`). The caller supplies the cost
|
|
20
21
|
* function and reranker in `opts`, and persists the returned goal-log rows. */
|
|
@@ -124,10 +125,17 @@ async function searchPool(ctx, opts, pool) {
|
|
|
124
125
|
const allEntries = oneCopyPerMemory(pool.local, pool.global, evalNow()).flat();
|
|
125
126
|
return multihopSearch(query, allEntries, { budget, cost, hippoRoot: ctx.hippoRoot, minResults, includeSuperseded, asOf });
|
|
126
127
|
}
|
|
128
|
+
const requested = opts.explicitScope || undefined;
|
|
129
|
+
const vectorCandidates = {
|
|
130
|
+
tenantId: ctx.tenantId,
|
|
131
|
+
scope: recallScopeFilter(requested, 'additive'),
|
|
132
|
+
includeSuperseded: includeSuperseded || Boolean(asOf),
|
|
133
|
+
admit: (e) => passesCliRecallScopeFilter(e.scope ?? null, requested),
|
|
134
|
+
};
|
|
127
135
|
if (search.usePhysics && !globalRoot) {
|
|
128
|
-
// Explain
|
|
129
|
-
const temporal = explain ? {} : { minResults, includeSuperseded, asOf };
|
|
130
|
-
return physicsSearch(query, pool.local, { budget, cost, hippoRoot: ctx.hippoRoot, physicsConfig: search.physicsConfig, scope, explain, ...temporal });
|
|
136
|
+
// Explain leaves minResults and includeSuperseded out to hold its output steady; asOf must reach physics or later rows leak.
|
|
137
|
+
const temporal = explain ? { asOf } : { minResults, includeSuperseded, asOf };
|
|
138
|
+
return physicsSearch(query, pool.local, { budget, cost, hippoRoot: ctx.hippoRoot, physicsConfig: search.physicsConfig, scope, explain, vectorCandidates, ...temporal });
|
|
131
139
|
}
|
|
132
140
|
if (globalRoot) {
|
|
133
141
|
// searchBothHybrid reloads candidates itself, so the scope rule is passed in rather than inherited from the pool.
|
|
@@ -137,7 +145,7 @@ async function searchPool(ctx, opts, pool) {
|
|
|
137
145
|
recallScope: opts.explicitScope ? { requested: opts.explicitScope, additive: true } : {},
|
|
138
146
|
});
|
|
139
147
|
}
|
|
140
|
-
return hybridSearch(query, pool.local, { budget, cost, hippoRoot: ctx.hippoRoot, explain, mmr, mmrLambda, minResults, scope, includeSuperseded, asOf });
|
|
148
|
+
return hybridSearch(query, pool.local, { budget, cost, hippoRoot: ctx.hippoRoot, explain, mmr, mmrLambda, minResults, scope, includeSuperseded, asOf, vectorCandidates });
|
|
141
149
|
}
|
|
142
150
|
/** Adds memories reached by walking the entity graph out from the lexical seeds. */
|
|
143
151
|
function expandGraph(ctx, opts, graph, state) {
|
package/dist/recall-scope.js
CHANGED
|
@@ -124,7 +124,7 @@ export function isRestrictedScope(scope) {
|
|
|
124
124
|
return false;
|
|
125
125
|
// SAFETY: RECALL_DEFAULT_DENY_SCOPES is a readonly tuple of string
|
|
126
126
|
// literals; widening the array (not the input) lets .includes() take any scope.
|
|
127
|
-
// `:private:` anywhere, any case, matches the store's SQL default-deny (store.ts
|
|
127
|
+
// `:private:` anywhere, any case, matches the store's SQL default-deny (store/search-rows.ts) so JS never admits what SQL hides.
|
|
128
128
|
return isPrivateScope(scope) || /:private:/i.test(scope) || RECALL_DEFAULT_DENY_SCOPES.includes(scope);
|
|
129
129
|
}
|
|
130
130
|
/** True when `actor` may read `scope`: admin always; member needs an exact grant on a restricted scope. */
|
package/dist/recall-trace.d.ts
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* new debug env var).
|
|
17
17
|
*/
|
|
18
18
|
import { type DatabaseSyncLike } from './db.js';
|
|
19
|
-
import type { RerankStep } from './search.js';
|
|
19
|
+
import type { RerankStep } from './search/types.js';
|
|
20
20
|
import { type DeliveryEventInput } from './delivery-recorder.js';
|
|
21
21
|
/** One ranked result to persist alongside its trace row. */
|
|
22
22
|
export interface RecallTraceResultInput {
|
|
@@ -102,8 +102,8 @@ export interface RecordTraceOutcomeInput {
|
|
|
102
102
|
* this function from caller-side state (`last_trace_id` / applied outcome
|
|
103
103
|
* ids) that can go stale relative to the trace it names — a forgotten
|
|
104
104
|
* memory, a tenant switch mid-session, or a race between two callers. Two
|
|
105
|
-
* checks run before the insert, both skip
|
|
106
|
-
*
|
|
105
|
+
* checks run before the insert, both skip with one log.warn line
|
|
106
|
+
* rather than throw:
|
|
107
107
|
* 1. The named trace must exist and belong to `input.tenantId` — a
|
|
108
108
|
* tenant mismatch or a dangling id (deleted trace) skips.
|
|
109
109
|
* 2. `input.memoryIds` is intersected against the trace's OWN
|
package/dist/recall-trace.js
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
import { createHash } from 'node:crypto';
|
|
19
19
|
import { openHippoDb, closeHippoDb } from './db.js';
|
|
20
20
|
import { DELIVERY_LEDGER_VERSION } from './delivery-recorder.js';
|
|
21
|
+
import { log } from './log.js';
|
|
21
22
|
/**
|
|
22
23
|
* Strip a RerankStep down to {stage, multiplier, scoreBefore, scoreAfter}
|
|
23
24
|
* before persisting (F3 privacy fix, codex cross-model finding). `note` is
|
|
@@ -76,8 +77,7 @@ export function writeRecallTrace(db, input) {
|
|
|
76
77
|
}
|
|
77
78
|
}
|
|
78
79
|
catch (error) {
|
|
79
|
-
|
|
80
|
-
console.error(`[hippo] recall trace write failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
80
|
+
log.error(`recall trace write failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
81
81
|
return null;
|
|
82
82
|
}
|
|
83
83
|
}
|
|
@@ -113,8 +113,7 @@ export function writeRecallTraceAtRoot(root, input) {
|
|
|
113
113
|
db = openHippoDb(root);
|
|
114
114
|
}
|
|
115
115
|
catch (error) {
|
|
116
|
-
|
|
117
|
-
console.error(`[hippo] recall trace connection failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
116
|
+
log.error(`recall trace connection failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
118
117
|
return null;
|
|
119
118
|
}
|
|
120
119
|
try {
|
|
@@ -140,8 +139,8 @@ export function writeRecallTraceAtRoot(root, input) {
|
|
|
140
139
|
* this function from caller-side state (`last_trace_id` / applied outcome
|
|
141
140
|
* ids) that can go stale relative to the trace it names — a forgotten
|
|
142
141
|
* memory, a tenant switch mid-session, or a race between two callers. Two
|
|
143
|
-
* checks run before the insert, both skip
|
|
144
|
-
*
|
|
142
|
+
* checks run before the insert, both skip with one log.warn line
|
|
143
|
+
* rather than throw:
|
|
145
144
|
* 1. The named trace must exist and belong to `input.tenantId` — a
|
|
146
145
|
* tenant mismatch or a dangling id (deleted trace) skips.
|
|
147
146
|
* 2. `input.memoryIds` is intersected against the trace's OWN
|
|
@@ -158,8 +157,7 @@ export function recordTraceOutcome(db, input) {
|
|
|
158
157
|
// SELECT above; sqlite returns undefined when no row matches.
|
|
159
158
|
const trace = db.prepare(`SELECT tenant_id FROM recall_traces WHERE id = ?`).get(input.traceId);
|
|
160
159
|
if (!trace || trace.tenant_id !== input.tenantId) {
|
|
161
|
-
|
|
162
|
-
console.error(`[hippo] recall trace outcome skipped: trace ${input.traceId} missing or tenant mismatch`);
|
|
160
|
+
log.warn(`recall trace outcome skipped: trace ${input.traceId} missing or tenant mismatch`);
|
|
163
161
|
return;
|
|
164
162
|
}
|
|
165
163
|
// SAFETY: row shape matches the single `memory_id` column named in the
|
|
@@ -170,8 +168,7 @@ export function recordTraceOutcome(db, input) {
|
|
|
170
168
|
const members = new Set(memberRows.map((r) => r.memory_id));
|
|
171
169
|
const credited = input.memoryIds.filter((id) => members.has(id));
|
|
172
170
|
if (credited.length === 0) {
|
|
173
|
-
|
|
174
|
-
console.error(`[hippo] recall trace outcome skipped: no credited ids intersect trace ${input.traceId}'s results`);
|
|
171
|
+
log.warn(`recall trace outcome skipped: no credited ids intersect trace ${input.traceId}'s results`);
|
|
175
172
|
return;
|
|
176
173
|
}
|
|
177
174
|
db.prepare(`
|
|
@@ -180,8 +177,7 @@ export function recordTraceOutcome(db, input) {
|
|
|
180
177
|
`).run(input.traceId, new Date().toISOString(), input.tenantId, input.outcome, JSON.stringify(credited));
|
|
181
178
|
}
|
|
182
179
|
catch (error) {
|
|
183
|
-
|
|
184
|
-
console.error(`[hippo] recall trace outcome write failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
180
|
+
log.error(`recall trace outcome write failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
185
181
|
}
|
|
186
182
|
}
|
|
187
183
|
/** Pruned on write, counted back from the event's ts capped at the real clock, so a far-future fake time spares real rows. */
|
|
@@ -270,7 +266,7 @@ export function writeDeliveryEvent(db, input) {
|
|
|
270
266
|
}
|
|
271
267
|
}
|
|
272
268
|
catch (error) {
|
|
273
|
-
//
|
|
269
|
+
// The prompt hook's stderr shows this exact `[hippo] delivery ledger` line, so it stays off the logger's format.
|
|
274
270
|
console.error(`[hippo] delivery ledger write failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
275
271
|
return null;
|
|
276
272
|
}
|
|
@@ -282,7 +278,7 @@ export function writeDeliveryEventAtRoot(root, input) {
|
|
|
282
278
|
db = openHippoDb(root, { busyWaitMs: DELIVERY_LEDGER_WAIT_MS });
|
|
283
279
|
}
|
|
284
280
|
catch (error) {
|
|
285
|
-
//
|
|
281
|
+
// Same hook stderr line as writeDeliveryEvent above.
|
|
286
282
|
console.error(`[hippo] delivery ledger write failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
287
283
|
return null;
|
|
288
284
|
}
|
package/dist/refine-llm.js
CHANGED
|
@@ -13,9 +13,11 @@
|
|
|
13
13
|
* - On failure (API error, bad response), the original memory is untouched.
|
|
14
14
|
*/
|
|
15
15
|
import { Layer } from './memory.js';
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
16
|
+
import { writeEntry } from './store/entry-writes.js';
|
|
17
|
+
import { loadAllEntries, readEntry } from './store/entry-reads.js';
|
|
18
|
+
import { redactSecretsStrict } from './secret-detect.js';
|
|
18
19
|
import { fetchWithRetry, llmTimeoutMs } from './http-retry.js';
|
|
20
|
+
import { log } from './log.js';
|
|
19
21
|
const REFINED_TAG = 'llm-refined';
|
|
20
22
|
const CONSOLIDATED_MARKERS = [
|
|
21
23
|
'[Consolidated from',
|
|
@@ -31,7 +33,7 @@ export async function refineSemanticMemory(merged, sources, opts) {
|
|
|
31
33
|
const fetchFn = opts.fetcher ?? fetch;
|
|
32
34
|
const sourceBlock = sources
|
|
33
35
|
.slice(0, 8)
|
|
34
|
-
.map((s, i) => `[source ${i + 1}] ${
|
|
36
|
+
.map((s, i) => `[source ${i + 1}] ${redactSecretsStrict(s.content).slice(0, 400)}`)
|
|
35
37
|
.join('\n\n');
|
|
36
38
|
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.
|
|
37
39
|
|
|
@@ -43,7 +45,7 @@ Rules:
|
|
|
43
45
|
- Do NOT include the "[Consolidated from N ...]" marker.
|
|
44
46
|
|
|
45
47
|
Current merged content:
|
|
46
|
-
${
|
|
48
|
+
${redactSecretsStrict(merged)}
|
|
47
49
|
|
|
48
50
|
Source memories (up to 8 shown):
|
|
49
51
|
${sourceBlock}`;
|
|
@@ -63,24 +65,31 @@ ${sourceBlock}`;
|
|
|
63
65
|
}),
|
|
64
66
|
}, { timeoutMs: llmTimeoutMs(), fetchFn });
|
|
65
67
|
}
|
|
66
|
-
catch {
|
|
68
|
+
catch (err) {
|
|
69
|
+
log.warn(`refine: request failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
67
70
|
return null;
|
|
68
71
|
}
|
|
69
|
-
if (!res.ok)
|
|
72
|
+
if (!res.ok) {
|
|
73
|
+
log.warn(`refine: API answered HTTP ${res.status}`);
|
|
70
74
|
return null;
|
|
75
|
+
}
|
|
76
|
+
let text;
|
|
71
77
|
try {
|
|
72
78
|
// SAFETY: data is the Anthropic Messages API response body; the
|
|
73
79
|
// documented response shape is `{ content: [{ type, text, ... }] }`
|
|
74
80
|
// for a text-generating request like this one.
|
|
75
81
|
const data = await res.json();
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
82
|
+
text = data.content?.[0]?.text?.trim() ?? '';
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
log.warn(`refine: unreadable response: ${err instanceof Error ? err.message : String(err)}`);
|
|
86
|
+
return null;
|
|
80
87
|
}
|
|
81
|
-
|
|
88
|
+
if (text.length < 10) {
|
|
89
|
+
log.warn('refine: response was empty or too short to use');
|
|
82
90
|
return null;
|
|
83
91
|
}
|
|
92
|
+
return text;
|
|
84
93
|
}
|
|
85
94
|
function isConsolidated(entry) {
|
|
86
95
|
if (entry.layer !== Layer.Semantic)
|
package/dist/reject-flow.js
CHANGED
|
@@ -15,7 +15,12 @@ import { closeHippoDb } from './db.js';
|
|
|
15
15
|
import { appendAuditEvent, reportAuditWriteFailure } from './audit.js';
|
|
16
16
|
import { archiveRawMemory } from './raw-archive.js';
|
|
17
17
|
import { deleteDormantRow, listDormantSnapshots, purgeDormantByDigest, replaceDormantEntry } from './dormant.js';
|
|
18
|
-
import {
|
|
18
|
+
import { stampOriginProject } from './store/entry-row.js';
|
|
19
|
+
import { purgeMirrorBestEffort } from './store/mirrors.js';
|
|
20
|
+
import { openStore } from './store/open.js';
|
|
21
|
+
import { writeEntryDbOnly, writeEntryMirrors } from './store/entry-writes.js';
|
|
22
|
+
import { selectAllEntries } from './store/entry-reads.js';
|
|
23
|
+
import { deleteEntryCore } from './store/delete-and-batch.js';
|
|
19
24
|
import { heldTexts } from './same-text.js';
|
|
20
25
|
import { mergedSuccessor } from './merged-row.js';
|
|
21
26
|
import { rejectionDigest, normalizeValueForRejection, insertRejectedValue, deleteRejectedValue, listRejectedValues, } from './rejection.js';
|
package/dist/rerankers/clef.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RerankerFn } from './types.js';
|
|
1
|
+
import type { RerankerFn, RerankProvenance } from './types.js';
|
|
2
2
|
import { type JsonValue } from '../http-util.js';
|
|
3
3
|
/** The two pretrained CLEF decision models served by Cloudflare Workers AI. */
|
|
4
4
|
export type ClefModel = 'clef-flash' | 'clef';
|
|
@@ -7,7 +7,7 @@ export declare function isClefModel(name: string): name is ClefModel;
|
|
|
7
7
|
interface ClefRoute {
|
|
8
8
|
url: string;
|
|
9
9
|
token: string | undefined;
|
|
10
|
-
backend: '
|
|
10
|
+
backend: Exclude<RerankProvenance['backend'], 'native'>;
|
|
11
11
|
}
|
|
12
12
|
interface ClefScores {
|
|
13
13
|
scores: number[];
|
package/dist/rerankers/clef.js
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { envClefEndpoint, envClefEndpointToken, envClefTimeoutMs, envCloudflareAccountId, envCloudflareApiToken } from '../env.js';
|
|
2
|
+
import { buildRelevanceRequest, JEV_DEFAULT_TOP_K, rankByScores } from './jev.js';
|
|
2
3
|
import { isJsonObjectRecord } from '../http-util.js';
|
|
4
|
+
import { log } from '../log.js';
|
|
3
5
|
const CLEF_MODELS = ['clef-flash', 'clef'];
|
|
4
6
|
const DEFAULT_TIMEOUT_MS = 15_000;
|
|
7
|
+
const MAX_TIMEOUT_MS = 120_000;
|
|
8
|
+
// 64 answers fit in a few KB; 1 MiB leaves room for a verbose envelope.
|
|
9
|
+
const MAX_REPLY_BYTES = 1024 * 1024;
|
|
5
10
|
// Workers AI rejects a request with more than 64 questions, one per candidate here.
|
|
6
11
|
const MAX_CANDIDATES = 64;
|
|
7
12
|
const ACCOUNT_ID = /^[0-9a-f]{32}$/i;
|
|
@@ -9,6 +14,10 @@ const ACCOUNT_ID = /^[0-9a-f]{32}$/i;
|
|
|
9
14
|
export function isClefModel(name) {
|
|
10
15
|
return CLEF_MODELS.some((m) => m === name);
|
|
11
16
|
}
|
|
17
|
+
// Plain http would put the token and the memory text on the wire, so only the local machine may use it.
|
|
18
|
+
function isLoopback(hostname) {
|
|
19
|
+
return hostname === 'localhost' || hostname === '[::1]' || /^127(\.\d{1,3}){3}$/.test(hostname);
|
|
20
|
+
}
|
|
12
21
|
function isNumber(v) {
|
|
13
22
|
return Number.isFinite(v);
|
|
14
23
|
}
|
|
@@ -16,11 +25,16 @@ function isString(v) {
|
|
|
16
25
|
return v !== undefined && v !== null && v.constructor === String;
|
|
17
26
|
}
|
|
18
27
|
function isRejection(v) {
|
|
19
|
-
return
|
|
28
|
+
return v.constructor === String;
|
|
29
|
+
}
|
|
30
|
+
// fetch quotes a rejected header value in its error, so a token it would reject must never reach it.
|
|
31
|
+
function checkHeaderSafe(name, token) {
|
|
32
|
+
if (!/^[\x21-\x7e]+$/.test(token))
|
|
33
|
+
throw new Error(`${name} has characters a header cannot carry`);
|
|
20
34
|
}
|
|
21
35
|
/** Transport from trusted local env, never call arguments: HIPPO_CLEF_ENDPOINT wins over hosted Workers AI. */
|
|
22
36
|
export function resolveClefRoute(model) {
|
|
23
|
-
const endpoint =
|
|
37
|
+
const endpoint = envClefEndpoint();
|
|
24
38
|
if (endpoint) {
|
|
25
39
|
let parsed;
|
|
26
40
|
try {
|
|
@@ -32,14 +46,25 @@ export function resolveClefRoute(model) {
|
|
|
32
46
|
if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') {
|
|
33
47
|
throw new Error('HIPPO_CLEF_ENDPOINT must be an http or https URL');
|
|
34
48
|
}
|
|
35
|
-
|
|
49
|
+
// fetch echoes a URL with credentials in its error text, which reaches stderr.
|
|
50
|
+
if (parsed.username || parsed.password) {
|
|
51
|
+
throw new Error('HIPPO_CLEF_ENDPOINT must not embed credentials; set HIPPO_CLEF_ENDPOINT_TOKEN');
|
|
52
|
+
}
|
|
53
|
+
if (parsed.protocol === 'http:' && !isLoopback(parsed.hostname)) {
|
|
54
|
+
throw new Error('HIPPO_CLEF_ENDPOINT must use https unless it is on this machine');
|
|
55
|
+
}
|
|
56
|
+
const endpointToken = envClefEndpointToken();
|
|
57
|
+
if (endpointToken)
|
|
58
|
+
checkHeaderSafe('HIPPO_CLEF_ENDPOINT_TOKEN', endpointToken);
|
|
59
|
+
return { url: parsed.href, token: endpointToken, backend: 'private-endpoint' };
|
|
36
60
|
}
|
|
37
|
-
const account =
|
|
38
|
-
const token =
|
|
61
|
+
const account = envCloudflareAccountId();
|
|
62
|
+
const token = envCloudflareApiToken();
|
|
39
63
|
if (!account || !token)
|
|
40
64
|
throw new Error('CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN not set');
|
|
41
65
|
if (!ACCOUNT_ID.test(account))
|
|
42
66
|
throw new Error('CLOUDFLARE_ACCOUNT_ID is not a 32-character hex id');
|
|
67
|
+
checkHeaderSafe('CLOUDFLARE_API_TOKEN', token);
|
|
43
68
|
return {
|
|
44
69
|
url: `https://api.cloudflare.com/client/v4/accounts/${account}/ai/run/@cf/cloudflare/${model}`,
|
|
45
70
|
token,
|
|
@@ -83,15 +108,43 @@ export function parseClefReply(body, n, model, requireModel) {
|
|
|
83
108
|
outputTokens: isNumber(usage.output_tokens) ? usage.output_tokens : undefined,
|
|
84
109
|
};
|
|
85
110
|
}
|
|
111
|
+
// The timeout bounds time, not bytes: a hostile endpoint could stream a huge 2xx body into memory.
|
|
112
|
+
async function readCappedJson(resp) {
|
|
113
|
+
if (!resp.body)
|
|
114
|
+
throw new Error('reply has no body');
|
|
115
|
+
const reader = resp.body.getReader();
|
|
116
|
+
const decoder = new TextDecoder();
|
|
117
|
+
let raw = '';
|
|
118
|
+
let received = 0;
|
|
119
|
+
for (;;) {
|
|
120
|
+
const { done, value } = await reader.read();
|
|
121
|
+
if (done)
|
|
122
|
+
break;
|
|
123
|
+
received += value.byteLength;
|
|
124
|
+
if (received > MAX_REPLY_BYTES) {
|
|
125
|
+
await reader.cancel();
|
|
126
|
+
throw new Error(`reply over ${MAX_REPLY_BYTES} bytes`);
|
|
127
|
+
}
|
|
128
|
+
raw += decoder.decode(value, { stream: true });
|
|
129
|
+
}
|
|
130
|
+
raw += decoder.decode();
|
|
131
|
+
try {
|
|
132
|
+
return JSON.parse(raw);
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
throw new Error('reply is not JSON');
|
|
136
|
+
}
|
|
137
|
+
}
|
|
86
138
|
async function requestScores(model, query, head, route) {
|
|
87
139
|
const { state, questions } = buildRelevanceRequest(query, head);
|
|
88
|
-
|
|
89
|
-
const
|
|
90
|
-
const
|
|
91
|
-
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
140
|
+
// Strict parse: parseInt would read "15s" as 15 ms, and Node clamps a delay past 2^31-1 to 1 ms.
|
|
141
|
+
const requested = Number(envClefTimeoutMs());
|
|
142
|
+
const timeoutMs = Number.isInteger(requested) && requested > 0 && requested <= MAX_TIMEOUT_MS ? requested : DEFAULT_TIMEOUT_MS;
|
|
92
143
|
const headers = new Headers({ 'content-type': 'application/json' });
|
|
93
144
|
if (route.token)
|
|
94
145
|
headers.set('authorization', `Bearer ${route.token}`);
|
|
146
|
+
const controller = new AbortController();
|
|
147
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
95
148
|
try {
|
|
96
149
|
const resp = await fetch(route.url, {
|
|
97
150
|
method: 'POST',
|
|
@@ -105,7 +158,7 @@ async function requestScores(model, query, head, route) {
|
|
|
105
158
|
await resp.body?.cancel();
|
|
106
159
|
throw new Error(`HTTP ${resp.status}${ray ? `, ray ${ray}` : ''}`);
|
|
107
160
|
}
|
|
108
|
-
const body = await resp
|
|
161
|
+
const body = await readCappedJson(resp);
|
|
109
162
|
const parsed = parseClefReply(body, head.length, model, route.backend === 'cloudflare');
|
|
110
163
|
if (isRejection(parsed))
|
|
111
164
|
throw new Error(parsed);
|
|
@@ -127,7 +180,8 @@ function nativeOrder(head, provenance) {
|
|
|
127
180
|
rerankScore: r.score,
|
|
128
181
|
preRerankRank: r.preRerankRank ?? i + 1,
|
|
129
182
|
postRerankRank: i + 1,
|
|
130
|
-
|
|
183
|
+
// A copy per row, so a caller editing one result cannot change another's provenance.
|
|
184
|
+
rerankProvenance: { ...provenance },
|
|
131
185
|
}));
|
|
132
186
|
}
|
|
133
187
|
/** A CLEF reranker for one model: Jev's request shape and pool; any failure keeps the native order (never paid Jev), warning once. */
|
|
@@ -137,42 +191,30 @@ export function createClefReranker(model) {
|
|
|
137
191
|
const head = results.slice(0, options?.topK ?? JEV_DEFAULT_TOP_K);
|
|
138
192
|
if (head.length === 0)
|
|
139
193
|
return [];
|
|
140
|
-
let
|
|
194
|
+
let route;
|
|
141
195
|
let got;
|
|
142
196
|
try {
|
|
143
197
|
if (head.length > MAX_CANDIDATES)
|
|
144
198
|
throw new Error(`more than ${MAX_CANDIDATES} candidates`);
|
|
145
|
-
|
|
146
|
-
backend = route.backend;
|
|
199
|
+
route = resolveClefRoute(model);
|
|
147
200
|
got = await requestScores(model, query, head, route);
|
|
148
201
|
}
|
|
149
202
|
catch (err) {
|
|
150
203
|
const reason = err instanceof Error ? err.message : 'unknown error';
|
|
151
204
|
if (!warned) {
|
|
152
205
|
warned = true;
|
|
153
|
-
|
|
154
|
-
console.warn(`[hippo] ${model} reranker unavailable (${reason}); keeping the native order. Subsequent calls will not repeat this warning.`);
|
|
206
|
+
log.warn(`${model} reranker unavailable (${reason}); keeping the native order. Subsequent calls will not repeat this warning.`);
|
|
155
207
|
}
|
|
156
208
|
return nativeOrder(head, { backend: 'native', requestedModel: model, fallbackReason: reason });
|
|
157
209
|
}
|
|
158
|
-
const
|
|
159
|
-
backend,
|
|
210
|
+
const rerankProvenance = {
|
|
211
|
+
backend: route.backend,
|
|
160
212
|
requestedModel: model,
|
|
161
213
|
actualModel: got.actualModel,
|
|
162
214
|
inputTokens: got.inputTokens,
|
|
163
215
|
outputTokens: got.outputTokens,
|
|
164
216
|
};
|
|
165
|
-
|
|
166
|
-
...r,
|
|
167
|
-
rerankScore: got.scores[i],
|
|
168
|
-
preRerankRank: r.preRerankRank ?? i + 1,
|
|
169
|
-
postRerankRank: 0,
|
|
170
|
-
rerankProvenance: provenance,
|
|
171
|
-
}));
|
|
172
|
-
// Stable sort: ties fall back to the prior relevance order.
|
|
173
|
-
scored.sort((a, b) => b.rerankScore - a.rerankScore);
|
|
174
|
-
scored.forEach((r, i) => (r.postRerankRank = i + 1));
|
|
175
|
-
return scored;
|
|
217
|
+
return rankByScores(head, got.scores).map((r) => ({ ...r, rerankProvenance: { ...rerankProvenance } }));
|
|
176
218
|
};
|
|
177
219
|
}
|
|
178
220
|
/** Opt-in CLEF-flash reranker (Cloudflare Workers AI or HIPPO_CLEF_ENDPOINT); off unless named, so defaults stay native. */
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';
|
|
2
2
|
import { pathToFileURL } from 'node:url';
|
|
3
|
+
import { log } from '../log.js';
|
|
3
4
|
const MODEL_NAME = 'Xenova/ms-marco-MiniLM-L-6-v2';
|
|
4
5
|
const _require = createRequire(import.meta.url);
|
|
5
6
|
const TRANSFORMERS_PACKAGES = ['@huggingface/transformers', '@xenova/transformers'];
|
|
@@ -36,7 +37,8 @@ async function loadTransformersModule() {
|
|
|
36
37
|
const seq = mod.AutoModelForSequenceClassification ?? mod.default?.AutoModelForSequenceClassification;
|
|
37
38
|
return tok && seq ? { AutoTokenizer: tok, AutoModelForSequenceClassification: seq } : null;
|
|
38
39
|
}
|
|
39
|
-
catch {
|
|
40
|
+
catch (err) {
|
|
41
|
+
log.debug(`cross-encoder: transformers import failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
40
42
|
return null;
|
|
41
43
|
}
|
|
42
44
|
}
|
|
@@ -78,7 +80,8 @@ async function buildPipeline() {
|
|
|
78
80
|
return score;
|
|
79
81
|
};
|
|
80
82
|
}
|
|
81
|
-
catch {
|
|
83
|
+
catch (err) {
|
|
84
|
+
log.debug(`cross-encoder: model load failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
82
85
|
return null;
|
|
83
86
|
}
|
|
84
87
|
}
|
|
@@ -102,8 +105,7 @@ export const crossEncoderReranker = async (query, results, options) => {
|
|
|
102
105
|
// working reranker.
|
|
103
106
|
if (!warnedOnFallback) {
|
|
104
107
|
warnedOnFallback = true;
|
|
105
|
-
|
|
106
|
-
console.warn('[hippo] cross-encoder reranker unavailable (no Transformers.js backend, or model fetch blocked); falling back to identity ordering. Subsequent calls will not repeat this warning.');
|
|
108
|
+
log.warn('cross-encoder reranker unavailable (no Transformers.js backend, or model fetch blocked); falling back to identity ordering. Subsequent calls will not repeat this warning.');
|
|
107
109
|
}
|
|
108
110
|
return head.map((r, i) => ({
|
|
109
111
|
...r,
|
package/dist/rerankers/jev.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { RerankerFn } from './types.js';
|
|
2
|
-
import type { SearchResult } from '../search.js';
|
|
1
|
+
import type { RerankerFn, RerankResult } from './types.js';
|
|
2
|
+
import type { SearchResult } from '../search/types.js';
|
|
3
3
|
export declare const JEV_DEFAULT_TOP_K = 40;
|
|
4
4
|
/** The System One `state` and one `noul` question per candidate (`c1`..`cN`). */
|
|
5
5
|
export interface RelevanceRequest {
|
|
@@ -13,6 +13,8 @@ export interface RelevanceRequest {
|
|
|
13
13
|
export declare function buildRelevanceRequest(query: string, head: readonly SearchResult[]): RelevanceRequest;
|
|
14
14
|
/** Builds a Jev reranker around the reranker it degrades to. Exported so a test can pass a stand-in. */
|
|
15
15
|
export declare function createJevReranker(localFallback: RerankerFn): RerankerFn;
|
|
16
|
+
/** Orders `head` by `scores[i]`, keeping any upstream pre-rerank rank. Shared with CLEF. */
|
|
17
|
+
export declare function rankByScores(head: readonly SearchResult[], scores: readonly number[]): RerankResult[];
|
|
16
18
|
/** Track 4 reranker: hosted TypeSafe Jev, opt-in and paid (TYPESAFE_API_KEY), one batched call per recall.
|
|
17
19
|
* Any failure warns once and delegates to the local cross-encoder. Scores are not bit-stable run to run.
|
|
18
20
|
* Cost, env vars, evidence and limits: docs/evals/2026-09-19-jev-reranker.md. */
|