hippo-memory 1.70.0 → 1.72.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 +2 -2
- package/dist/agent-memories/apply.d.ts +0 -11
- package/dist/agent-memories/apply.js +6 -21
- package/dist/agent-memories/claude-code.d.ts +4 -2
- package/dist/agent-memories/claude-code.js +15 -6
- package/dist/agent-memories/codex.js +1 -1
- package/dist/agent-memories/copilot.d.ts +1 -3
- package/dist/agent-memories/copilot.js +1 -17
- package/dist/agent-memories/files.js +23 -12
- package/dist/agent-memories/markdown.d.ts +1 -3
- package/dist/agent-memories/markdown.js +1 -3
- package/dist/agent-memories/project-folds.d.ts +10 -0
- package/dist/agent-memories/project-folds.js +34 -0
- package/dist/agent-memories/report.js +2 -1
- package/dist/agent-memories/sync.d.ts +4 -2
- package/dist/agent-memories/sync.js +18 -11
- package/dist/api/assemble.d.ts +7 -44
- package/dist/api/assemble.js +3 -23
- package/dist/api/audit.d.ts +33 -1
- package/dist/api/audit.js +48 -1
- package/dist/api/auth.d.ts +20 -26
- package/dist/api/auth.js +43 -29
- package/dist/api/auto-sleep.d.ts +5 -2
- package/dist/api/auto-sleep.js +9 -5
- package/dist/api/availability.d.ts +2 -15
- package/dist/api/availability.js +4 -18
- package/dist/api/cards.d.ts +42 -0
- package/dist/api/cards.js +52 -0
- package/dist/api/conflicts.d.ts +28 -0
- package/dist/api/conflicts.js +61 -0
- package/dist/api/context-render.js +4 -3
- package/dist/api/context-select.js +12 -15
- package/dist/api/context-types.d.ts +10 -35
- package/dist/api/context.d.ts +5 -22
- package/dist/api/context.js +38 -46
- package/dist/api/continuity.d.ts +47 -0
- package/dist/api/continuity.js +66 -0
- package/dist/{cli → api}/correction-latency.d.ts +2 -14
- package/dist/{cli → api}/correction-latency.js +2 -14
- package/dist/api/dormant.d.ts +5 -21
- package/dist/api/dormant.js +11 -28
- package/dist/api/drill-down.d.ts +7 -46
- package/dist/api/drill-down.js +6 -27
- package/dist/api/embeddings.d.ts +17 -0
- package/dist/api/embeddings.js +28 -0
- package/dist/api/error-reply.d.ts +8 -0
- package/dist/api/error-reply.js +21 -0
- package/dist/api/forget.d.ts +11 -26
- package/dist/api/forget.js +23 -35
- package/dist/api/goals.d.ts +1 -1
- package/dist/api/goals.js +5 -9
- package/dist/api/graph.d.ts +8 -0
- package/dist/api/graph.js +7 -0
- package/dist/api/index.d.ts +6 -2
- package/dist/api/index.js +6 -2
- package/dist/api/instruction-detect.js +21 -6
- package/dist/api/learn.d.ts +4 -0
- package/dist/api/learn.js +53 -27
- package/dist/api/ledger-db.d.ts +2 -5
- package/dist/api/ledger-db.js +5 -35
- package/dist/api/memories.d.ts +23 -0
- package/dist/api/memories.js +46 -0
- package/dist/api/objects.d.ts +9 -0
- package/dist/api/objects.js +11 -0
- package/dist/api/on-store.js +5 -3
- package/dist/api/outcome.js +1 -1
- package/dist/api/pilot-arm.d.ts +1 -11
- package/dist/api/pilot-arm.js +5 -45
- package/dist/api/predictions.d.ts +11 -0
- package/dist/api/predictions.js +24 -0
- package/dist/api/projects.d.ts +21 -0
- package/dist/api/projects.js +24 -0
- package/dist/api/promote.d.ts +13 -17
- package/dist/api/promote.js +12 -20
- package/dist/api/prompt-hook.d.ts +19 -6
- package/dist/api/prompt-hook.js +54 -13
- package/dist/api/provenance-coverage.d.ts +14 -0
- package/dist/{cli → api}/provenance-coverage.js +2 -6
- package/dist/api/recall-cli.d.ts +58 -0
- package/dist/api/recall-cli.js +103 -0
- package/dist/api/recall-core.js +17 -9
- package/dist/api/recall-finish.d.ts +53 -0
- package/dist/api/recall-finish.js +30 -0
- package/dist/api/recall-history.d.ts +17 -84
- package/dist/api/recall-history.js +15 -88
- package/dist/api/recall-pipeline.d.ts +2 -3
- package/dist/api/recall-pipeline.js +21 -15
- package/dist/api/recall-request.js +1 -1
- package/dist/api/recall-types.d.ts +64 -304
- package/dist/api/recall.d.ts +3 -34
- package/dist/api/recall.js +63 -89
- package/dist/api/refine.d.ts +7 -0
- package/dist/api/refine.js +10 -0
- package/dist/api/remember-local.d.ts +57 -0
- package/dist/api/remember-local.js +90 -0
- package/dist/api/remember.d.ts +20 -2
- package/dist/api/remember.js +16 -3
- package/dist/api/session-end.d.ts +22 -0
- package/dist/api/session-end.js +101 -0
- package/dist/api/sleep-run.d.ts +2 -4
- package/dist/api/sleep-run.js +28 -28
- package/dist/api/sleep.d.ts +9 -28
- package/dist/api/status.d.ts +24 -0
- package/dist/api/status.js +40 -0
- package/dist/api/store-init.d.ts +4 -0
- package/dist/api/store-init.js +9 -0
- package/dist/api/tokens.d.ts +3 -10
- package/dist/api/tokens.js +4 -11
- package/dist/api/types.d.ts +8 -29
- package/dist/api/types.js +10 -23
- package/dist/capture/caller-session.d.ts +0 -3
- package/dist/capture/caller-session.js +1 -12
- package/dist/capture/capture-error.d.ts +2 -2
- package/dist/capture/capture-error.js +23 -18
- package/dist/capture/codex-patch.js +3 -1
- package/dist/capture/command.d.ts +4 -12
- package/dist/capture/command.js +39 -114
- package/dist/capture/compact.d.ts +4 -15
- package/dist/capture/compact.js +26 -30
- package/dist/capture/compaction-items-caller.js +11 -20
- package/dist/capture/compaction-record.d.ts +7 -93
- package/dist/capture/compaction-record.js +34 -399
- package/dist/capture/compaction-spool.d.ts +5 -3
- package/dist/capture/compaction-spool.js +21 -7
- package/dist/capture/copilot-transcript.d.ts +2 -1
- package/dist/capture/copilot-transcript.js +2 -1
- package/dist/capture/extract.d.ts +5 -2
- package/dist/capture/extract.js +4 -3
- package/dist/capture/failure-caller.d.ts +1 -1
- package/dist/capture/failure-caller.js +21 -16
- package/dist/capture/failure-reading.d.ts +2 -1
- package/dist/capture/failure-reading.js +7 -9
- package/dist/capture/pre-compact-caller.js +5 -4
- package/dist/capture/session-digest.d.ts +1 -1
- package/dist/capture/session-digest.js +17 -10
- package/dist/capture/session-end-caller.js +2 -1
- package/dist/capture/session-worker.js +3 -4
- package/dist/capture/transcript.d.ts +4 -11
- package/dist/capture/transcript.js +10 -21
- package/dist/capture/working-state.d.ts +4 -2
- package/dist/capture/working-state.js +4 -2
- package/dist/cli/api-context.d.ts +3 -0
- package/dist/cli/api-context.js +6 -0
- package/dist/cli/audit-prune.d.ts +1 -59
- package/dist/cli/audit-prune.js +2 -61
- package/dist/cli/audit.d.ts +1 -1
- package/dist/cli/audit.js +42 -43
- package/dist/cli/auth.d.ts +2 -2
- package/dist/cli/auth.js +61 -44
- package/dist/cli/briefs.d.ts +1 -4
- package/dist/cli/briefs.js +42 -301
- package/dist/cli/card.d.ts +2 -2
- package/dist/cli/card.js +63 -56
- package/dist/cli/client.d.ts +12 -27
- package/dist/cli/client.js +41 -44
- package/dist/cli/compact-resume-payload.js +4 -3
- package/dist/cli/context.d.ts +2 -3
- package/dist/cli/context.js +22 -18
- package/dist/cli/continuity.d.ts +6 -6
- package/dist/cli/continuity.js +81 -86
- package/dist/cli/curate.d.ts +13 -17
- package/dist/cli/curate.js +88 -116
- package/dist/cli/dag.d.ts +4 -4
- package/dist/cli/dag.js +55 -34
- package/dist/cli/decisions.d.ts +2 -4
- package/dist/cli/decisions.js +18 -309
- package/dist/cli/eval.d.ts +1 -1
- package/dist/cli/eval.js +27 -26
- package/dist/cli/exit.d.ts +6 -0
- package/dist/cli/exit.js +11 -0
- package/dist/cli/explain.d.ts +2 -3
- package/dist/cli/explain.js +25 -27
- package/dist/cli/flag-values.d.ts +6 -1
- package/dist/cli/flag-values.js +42 -15
- package/dist/cli/flags.d.ts +0 -288
- package/dist/cli/flags.js +3 -138
- package/dist/cli/github.d.ts +14 -0
- package/dist/{connectors/github/cli-impl.js → cli/github.js} +43 -71
- package/dist/cli/goals.d.ts +2 -2
- package/dist/cli/goals.js +46 -50
- package/dist/cli/graph.d.ts +3 -0
- package/dist/cli/graph.js +83 -0
- package/dist/cli/hook-runtime.d.ts +12 -32
- package/dist/cli/hook-runtime.js +21 -64
- package/dist/cli/incidents.d.ts +3 -0
- package/dist/cli/incidents.js +112 -0
- package/dist/cli/init.d.ts +2 -2
- package/dist/cli/init.js +33 -30
- package/dist/cli/install-steps.d.ts +2 -1
- package/dist/cli/install-steps.js +13 -14
- package/dist/cli/last-sleep.d.ts +2 -1
- package/dist/cli/last-sleep.js +4 -1
- package/dist/cli/lenient-id.d.ts +2 -0
- package/dist/cli/lenient-id.js +13 -0
- package/dist/cli/maintenance.d.ts +5 -5
- package/dist/cli/maintenance.js +37 -43
- package/dist/cli/notes.d.ts +2 -0
- package/dist/cli/notes.js +41 -0
- package/dist/cli/object-verbs.js +4 -3
- package/dist/cli/open-browser.d.ts +14 -0
- package/dist/cli/open-browser.js +26 -0
- package/dist/cli/owner-validation.d.ts +5 -28
- package/dist/cli/owner-validation.js +5 -28
- package/dist/cli/playbooks.d.ts +3 -4
- package/dist/cli/playbooks.js +131 -300
- package/dist/cli/predictions.d.ts +3 -0
- package/dist/cli/predictions.js +175 -0
- package/dist/cli/print.d.ts +2 -5
- package/dist/cli/print.js +3 -5
- package/dist/cli/projects.d.ts +2 -2
- package/dist/cli/projects.js +31 -25
- package/dist/cli/quality-repair-once.d.ts +1 -1
- package/dist/cli/quality-repair-once.js +7 -6
- package/dist/cli/recall.d.ts +2 -4
- package/dist/cli/recall.js +67 -137
- package/dist/cli/refine-llm.d.ts +5 -31
- package/dist/cli/refine-llm.js +23 -50
- package/dist/cli/remember.d.ts +3 -3
- package/dist/cli/remember.js +134 -192
- package/dist/cli/scheduler.d.ts +2 -17
- package/dist/cli/scheduler.js +14 -19
- package/dist/cli/serve.js +23 -14
- package/dist/cli/session-hooks.d.ts +11 -19
- package/dist/cli/session-hooks.js +143 -214
- package/dist/cli/setup.d.ts +4 -4
- package/dist/cli/setup.js +35 -30
- package/dist/cli/shared.d.ts +7 -25
- package/dist/cli/shared.js +17 -60
- package/dist/cli/slack.d.ts +2 -2
- package/dist/cli/slack.js +19 -23
- package/dist/cli/sleep-render.js +6 -3
- package/dist/cli/sleep.d.ts +3 -2
- package/dist/cli/sleep.js +17 -49
- package/dist/cli/status.d.ts +11 -14
- package/dist/cli/status.js +74 -120
- package/dist/cli/stdin.d.ts +4 -6
- package/dist/cli/stdin.js +2 -3
- package/dist/cli/transfer.d.ts +9 -9
- package/dist/cli/transfer.js +87 -108
- package/dist/cli/usage.d.ts +0 -79
- package/dist/cli/usage.js +1 -689
- package/dist/cli/verb-row.d.ts +32 -0
- package/dist/cli/verb-row.js +6 -0
- package/dist/cli/verbs/health.d.ts +27 -0
- package/dist/cli/verbs/health.js +232 -0
- package/dist/cli/verbs/memory.d.ts +16 -0
- package/dist/cli/verbs/memory.js +244 -0
- package/dist/cli/verbs/objects.d.ts +20 -0
- package/dist/cli/verbs/objects.js +254 -0
- package/dist/cli/verbs/sessions.d.ts +31 -0
- package/dist/cli/verbs/sessions.js +312 -0
- package/dist/cli/verbs.d.ts +81 -0
- package/dist/cli/verbs.js +7 -0
- package/dist/cli/versioned-verbs.d.ts +51 -0
- package/dist/cli/versioned-verbs.js +79 -0
- package/dist/cli.d.ts +1 -654
- package/dist/cli.js +44 -510
- package/dist/connectors/dlq.d.ts +39 -3
- package/dist/connectors/dlq.js +37 -3
- package/dist/connectors/github/backfill.d.ts +5 -25
- package/dist/connectors/github/backfill.js +26 -52
- package/dist/connectors/github/deletion.d.ts +4 -18
- package/dist/connectors/github/deletion.js +2 -15
- package/dist/connectors/github/dlq.d.ts +8 -33
- package/dist/connectors/github/dlq.js +34 -93
- package/dist/connectors/github/ingest.d.ts +4 -12
- package/dist/connectors/github/ingest.js +5 -36
- package/dist/connectors/github/octokit-client.d.ts +4 -16
- package/dist/connectors/github/octokit-client.js +27 -24
- package/dist/connectors/github/ratelimit.d.ts +3 -14
- package/dist/connectors/github/ratelimit.js +3 -14
- package/dist/connectors/github/scope.d.ts +3 -5
- package/dist/connectors/github/scope.js +3 -5
- package/dist/connectors/github/signature.d.ts +4 -26
- package/dist/connectors/github/signature.js +4 -26
- package/dist/connectors/github/tenant-routing.d.ts +2 -24
- package/dist/connectors/github/tenant-routing.js +4 -26
- package/dist/connectors/github/transform.js +2 -16
- package/dist/connectors/github/types.d.ts +3 -15
- package/dist/connectors/github/types.js +2 -9
- package/dist/connectors/github/webhook.d.ts +3 -16
- package/dist/connectors/github/webhook.js +38 -23
- package/dist/connectors/ingest.d.ts +10 -0
- package/dist/connectors/ingest.js +28 -0
- package/dist/connectors/slack/backfill.d.ts +4 -17
- package/dist/connectors/slack/backfill.js +4 -13
- package/dist/connectors/slack/dlq.d.ts +2 -19
- package/dist/connectors/slack/dlq.js +51 -90
- package/dist/connectors/slack/ingest.d.ts +4 -9
- package/dist/connectors/slack/ingest.js +4 -30
- package/dist/connectors/slack/scope.d.ts +2 -8
- package/dist/connectors/slack/scope.js +2 -8
- package/dist/connectors/slack/signature.d.ts +1 -6
- package/dist/connectors/slack/tenant-routing.d.ts +2 -19
- package/dist/connectors/slack/tenant-routing.js +2 -21
- package/dist/connectors/slack/transform.d.ts +2 -18
- package/dist/connectors/slack/transform.js +2 -18
- package/dist/connectors/slack/types.d.ts +3 -9
- package/dist/connectors/slack/types.js +2 -4
- package/dist/connectors/slack/web-client.js +33 -27
- package/dist/connectors/slack/webhook.d.ts +3 -19
- package/dist/connectors/slack/webhook.js +6 -26
- package/dist/connectors/slack/workspaces.d.ts +4 -24
- package/dist/connectors/slack/workspaces.js +4 -24
- package/dist/consolidate/conflicts.js +7 -15
- package/dist/consolidate/dag-summary.d.ts +8 -0
- package/dist/consolidate/dag-summary.js +41 -0
- package/dist/consolidate/dag.d.ts +5 -28
- package/dist/consolidate/dag.js +29 -84
- package/dist/consolidate/decay.js +7 -19
- package/dist/consolidate/dedupe.d.ts +13 -52
- package/dist/consolidate/dedupe.js +18 -74
- package/dist/consolidate/flush-units.d.ts +3 -4
- package/dist/consolidate/flush-units.js +3 -3
- package/dist/consolidate/half-life-migration.d.ts +3 -26
- package/dist/consolidate/half-life-migration.js +11 -28
- package/dist/consolidate/llm-passes.js +49 -40
- package/dist/consolidate/memory-value-weights.d.ts +2 -13
- package/dist/consolidate/memory-value-weights.js +2 -13
- package/dist/consolidate/memory-value.d.ts +11 -84
- package/dist/consolidate/memory-value.js +18 -105
- package/dist/consolidate/merge.js +12 -33
- package/dist/consolidate/physics-pass.d.ts +6 -1
- package/dist/consolidate/physics-pass.js +27 -9
- package/dist/consolidate/replay.d.ts +6 -38
- package/dist/consolidate/replay.js +25 -56
- package/dist/consolidate/run.js +1 -1
- package/dist/consolidate/sleep.d.ts +1 -8
- package/dist/consolidate/sleep.js +13 -22
- package/dist/consolidate/trace.d.ts +3 -18
- package/dist/consolidate/trace.js +3 -18
- package/dist/consolidate/traces.js +9 -25
- package/dist/core/ablation.d.ts +14 -91
- package/dist/core/ablation.js +16 -91
- package/dist/core/active-scope.d.ts +7 -0
- package/dist/{sharing/scope.js → core/active-scope.js} +5 -12
- package/dist/core/ambient.d.ts +5 -8
- package/dist/core/ambient.js +40 -26
- package/dist/core/api-errors.d.ts +16 -0
- package/dist/core/api-errors.js +20 -0
- package/dist/core/capture-contract.d.ts +4 -2
- package/dist/core/capture-contract.js +4 -2
- package/dist/core/card.d.ts +4 -1
- package/dist/core/card.js +11 -1
- package/dist/core/compaction-timing.d.ts +7 -0
- package/dist/core/compaction-timing.js +9 -0
- package/dist/core/compare.d.ts +11 -67
- package/dist/core/compare.js +9 -63
- package/dist/core/config.d.ts +10 -24
- package/dist/core/config.js +20 -16
- package/dist/core/cosine.d.ts +3 -0
- package/dist/core/cosine.js +19 -0
- package/dist/core/handoff.d.ts +1 -7
- package/dist/core/handoff.js +1 -7
- package/dist/core/markdown.d.ts +6 -0
- package/dist/{store → core}/markdown.js +23 -22
- package/dist/core/memory-audit.d.ts +17 -0
- package/dist/core/memory-audit.js +54 -0
- package/dist/core/memory-quality.js +1 -1
- package/dist/core/memory.d.ts +51 -168
- package/dist/core/memory.js +76 -239
- package/dist/{consolidate → core}/merged-row.d.ts +1 -1
- package/dist/{consolidate → core}/merged-row.js +3 -2
- package/dist/core/package-root.d.ts +3 -0
- package/dist/core/package-root.js +5 -0
- package/dist/core/physics-config.d.ts +1 -4
- package/dist/core/physics-config.js +3 -8
- package/dist/core/physics.d.ts +15 -61
- package/dist/core/physics.js +65 -138
- package/dist/core/prediction.d.ts +3 -0
- package/dist/core/prediction.js +6 -0
- package/dist/core/project-identity.d.ts +20 -58
- package/dist/core/project-identity.js +27 -39
- package/dist/core/project-remote.js +13 -2
- package/dist/core/raw-append-only.d.ts +5 -0
- package/dist/core/raw-append-only.js +7 -0
- package/dist/core/recall-scope.d.ts +69 -0
- package/dist/core/recall-scope.js +138 -0
- package/dist/core/salience.d.ts +1 -7
- package/dist/core/salience.js +1 -7
- package/dist/dashboard/dashboard-actions.js +2 -2
- package/dist/dashboard/dashboard-snapshot.d.ts +2 -1
- package/dist/dashboard/dashboard-snapshot.js +11 -2
- package/dist/dashboard/dashboard-types.d.ts +2 -1
- package/dist/dashboard/dashboard.d.ts +1 -0
- package/dist/dashboard/dashboard.js +50 -4
- package/dist/db/busy.d.ts +3 -8
- package/dist/db/busy.js +37 -33
- package/dist/db/connect.js +7 -8
- package/dist/db/index.d.ts +3 -3
- package/dist/db/index.js +3 -3
- package/dist/db/migrate.js +3 -3
- package/dist/db/migrations/index.d.ts +1 -1
- package/dist/db/migrations/index.js +3 -1
- package/dist/db/migrations/types.d.ts +2 -5
- package/dist/db/migrations/v14.js +2 -3
- package/dist/db/migrations/v15.js +2 -8
- package/dist/db/migrations/v16.js +2 -3
- package/dist/db/migrations/v17.js +2 -3
- package/dist/db/migrations/v19.js +2 -5
- package/dist/db/migrations/v20.js +2 -7
- package/dist/db/migrations/v22.js +4 -17
- package/dist/db/migrations/v23.js +3 -14
- package/dist/db/migrations/v24.js +2 -4
- package/dist/db/migrations/v25.js +3 -8
- package/dist/db/migrations/v26.js +2 -13
- package/dist/db/migrations/v27.js +3 -11
- package/dist/db/migrations/v28.js +2 -14
- package/dist/db/migrations/v29.js +4 -18
- package/dist/db/migrations/v30.js +4 -16
- package/dist/db/migrations/v31.js +2 -15
- package/dist/db/migrations/v32.js +4 -22
- package/dist/db/migrations/v33.js +2 -15
- package/dist/db/migrations/v34.js +2 -11
- package/dist/db/migrations/v35.js +2 -11
- package/dist/db/migrations/v36.js +2 -11
- package/dist/db/migrations/v37.js +8 -33
- package/dist/db/migrations/v38.js +5 -38
- package/dist/db/migrations/v39.js +9 -20
- package/dist/db/migrations/v40.js +2 -9
- package/dist/db/migrations/v41.js +2 -24
- package/dist/db/migrations/v43.js +1 -1
- package/dist/db/migrations/v44.js +2 -8
- package/dist/db/migrations/v45.js +2 -7
- package/dist/db/migrations/v47.js +2 -3
- package/dist/db/migrations/v51.js +1 -1
- package/dist/db/migrations/v55.d.ts +3 -0
- package/dist/db/migrations/v55.js +17 -0
- package/dist/db/open.d.ts +2 -2
- package/dist/db/open.js +21 -9
- package/dist/db/physics-state.d.ts +6 -22
- package/dist/db/physics-state.js +28 -39
- package/dist/db/raw-archive-mirror-cleanup.d.ts +2 -17
- package/dist/db/raw-archive-mirror-cleanup.js +2 -17
- package/dist/db/tables.d.ts +2 -0
- package/dist/db/tables.js +6 -2
- package/dist/db/vector-store.d.ts +2 -0
- package/dist/db/vector-store.js +25 -5
- package/dist/db/wal-checkpointer.js +2 -1
- package/dist/doctor.js +85 -27
- package/dist/embeddings/local.d.ts +62 -0
- package/dist/embeddings/local.js +146 -0
- package/dist/embeddings/provider.d.ts +43 -0
- package/dist/{store/embeddings → embeddings}/provider.js +58 -83
- package/dist/embeddings/transformers.d.ts +26 -0
- package/dist/embeddings/transformers.js +89 -0
- package/dist/entry/session-text.d.ts +1 -1
- package/dist/entry/session-text.js +3 -2
- package/dist/eval/eval-stats.d.ts +15 -53
- package/dist/eval/eval-stats.js +12 -42
- package/dist/eval/eval-suite.d.ts +2 -13
- package/dist/eval/eval-suite.js +91 -45
- package/dist/eval/eval.d.ts +6 -24
- package/dist/eval/eval.js +8 -35
- package/dist/eval/judgment.d.ts +0 -3
- package/dist/eval/judgment.js +30 -15
- package/dist/extensions/openclaw-plugin/index.js +1 -1
- package/dist/graph/extract.d.ts +5 -27
- package/dist/graph/extract.js +10 -36
- package/dist/graph/recall.d.ts +7 -20
- package/dist/graph/recall.js +15 -77
- package/dist/graph/stream.d.ts +7 -39
- package/dist/graph/stream.js +11 -34
- package/dist/graph/view.d.ts +9 -35
- package/dist/graph/view.js +24 -44
- package/dist/graph/write.d.ts +1 -1
- package/dist/graph/write.js +9 -9
- package/dist/hooks/codex-session.js +3 -2
- package/dist/hooks/codex-wrapper.js +4 -3
- package/dist/hooks/copilot.js +2 -1
- package/dist/hooks/hook-blocks.d.ts +6 -2
- package/dist/hooks/hook-blocks.js +37 -124
- package/dist/hooks/json-hooks.d.ts +4 -36
- package/dist/hooks/json-hooks.js +22 -59
- package/dist/hooks/opencode.d.ts +0 -38
- package/dist/hooks/opencode.js +17 -81
- package/dist/hooks/shared.d.ts +6 -21
- package/dist/hooks/shared.js +31 -33
- package/dist/importers/core.d.ts +12 -37
- package/dist/importers/core.js +10 -28
- package/dist/importers/markdown-parse.d.ts +8 -22
- package/dist/importers/markdown-parse.js +8 -25
- package/dist/importers/markdown.js +3 -12
- package/dist/importers/sources.js +12 -39
- package/dist/importers/vault.d.ts +2 -8
- package/dist/importers/vault.js +31 -85
- package/dist/index.d.ts +8 -3
- package/dist/index.js +8 -3
- package/dist/learn/autolearn.d.ts +23 -42
- package/dist/learn/autolearn.js +45 -52
- package/dist/learn/churn-git.js +13 -4
- package/dist/learn/extract.d.ts +3 -2
- package/dist/learn/extract.js +8 -8
- package/dist/learn/forward-claim-detector.d.ts +6 -30
- package/dist/learn/forward-claim-detector.js +18 -68
- package/dist/learn/invalidation.d.ts +6 -18
- package/dist/learn/invalidation.js +18 -31
- package/dist/mcp/admin-tools.d.ts +2 -2
- package/dist/mcp/admin-tools.js +30 -53
- package/dist/mcp/format.js +3 -2
- package/dist/mcp/framing.d.ts +1 -0
- package/dist/mcp/framing.js +1 -1
- package/dist/mcp/memory-tools.js +7 -10
- package/dist/mcp/protocol.d.ts +15 -29
- package/dist/mcp/protocol.js +26 -16
- package/dist/mcp/recall-tools.js +14 -11
- package/dist/mcp/request.d.ts +3 -11
- package/dist/mcp/request.js +12 -27
- package/dist/mcp/server.d.ts +3 -9
- package/dist/mcp/server.js +5 -16
- package/dist/mcp/session-state.d.ts +1 -1
- package/dist/mcp/session-state.js +5 -11
- package/dist/mcp/stdio.d.ts +2 -6
- package/dist/mcp/stdio.js +68 -16
- package/dist/mcp/tool-args.js +2 -1
- package/dist/mcp/tools.js +47 -22
- package/dist/objects/customer-notes.d.ts +9 -44
- package/dist/objects/customer-notes.js +7 -48
- package/dist/objects/decisions.d.ts +14 -52
- package/dist/objects/decisions.js +15 -53
- package/dist/objects/descriptor.d.ts +1 -1
- package/dist/objects/incidents.d.ts +9 -40
- package/dist/objects/incidents.js +7 -41
- package/dist/objects/lifecycle.d.ts +1 -1
- package/dist/objects/lifecycle.js +2 -1
- package/dist/objects/policies.d.ts +13 -91
- package/dist/objects/policies.js +13 -99
- package/dist/objects/processes.d.ts +9 -54
- package/dist/objects/processes.js +7 -61
- package/dist/objects/project-briefs.d.ts +13 -57
- package/dist/objects/project-briefs.js +16 -78
- package/dist/objects/skills.d.ts +9 -44
- package/dist/objects/skills.js +8 -54
- package/dist/postinstall.js +7 -20
- package/dist/predictions/planning-fallacy.d.ts +11 -34
- package/dist/rerankers/clef.js +6 -37
- package/dist/rerankers/cross-encoder.d.ts +31 -2
- package/dist/rerankers/cross-encoder.js +65 -101
- package/dist/rerankers/index.js +5 -4
- package/dist/rerankers/jev.js +11 -10
- package/dist/rerankers/llm.d.ts +2 -11
- package/dist/rerankers/llm.js +14 -14
- package/dist/rerankers/outage-warning.d.ts +5 -2
- package/dist/rerankers/outage-warning.js +7 -4
- package/dist/rerankers/remote.d.ts +1 -0
- package/dist/rerankers/remote.js +2 -0
- package/dist/rerankers/types.d.ts +2 -14
- package/dist/search/bm25-search.js +1 -1
- package/dist/search/boosts.d.ts +0 -2
- package/dist/search/boosts.js +3 -3
- package/dist/search/embed-memories.d.ts +9 -0
- package/dist/search/embed-memories.js +377 -0
- package/dist/search/goal-boost.d.ts +23 -0
- package/dist/search/goal-boost.js +93 -0
- package/dist/search/hybrid.d.ts +11 -2
- package/dist/search/hybrid.js +9 -4
- package/dist/search/multihop.js +2 -3
- package/dist/search/path-context.d.ts +5 -18
- package/dist/search/path-context.js +5 -18
- package/dist/search/physics-search.d.ts +6 -3
- package/dist/search/physics-search.js +29 -19
- package/dist/search/rerank.js +1 -1
- package/dist/search/rrf.d.ts +7 -35
- package/dist/search/rrf.js +5 -30
- package/dist/search/vector.d.ts +13 -4
- package/dist/search/vector.js +40 -13
- package/dist/server/auth.d.ts +11 -28
- package/dist/server/auth.js +49 -32
- package/dist/server/boot.d.ts +2 -21
- package/dist/server/boot.js +69 -161
- package/dist/server/client-ip.d.ts +3 -21
- package/dist/server/client-ip.js +8 -30
- package/dist/server/deadline.d.ts +0 -2
- package/dist/server/deadline.js +1 -7
- package/dist/server/defaults.d.ts +4 -0
- package/dist/server/defaults.js +5 -0
- package/dist/server/key-check-bounds.d.ts +2 -1
- package/dist/server/lifecycle.d.ts +5 -4
- package/dist/server/lifecycle.js +19 -4
- package/dist/server/mcp-http.js +24 -53
- package/dist/server/rate-limit.d.ts +5 -18
- package/dist/server/rate-limit.js +4 -13
- package/dist/server/request.d.ts +4 -8
- package/dist/server/request.js +16 -19
- package/dist/server/route-checks.d.ts +7 -0
- package/dist/server/route-checks.js +42 -0
- package/dist/server/route-table.d.ts +9 -8
- package/dist/server/route-table.js +127 -139
- package/dist/server/routes/admin.d.ts +8 -8
- package/dist/server/routes/admin.js +35 -49
- package/dist/server/routes/customer-notes.d.ts +6 -6
- package/dist/server/routes/customer-notes.js +8 -14
- package/dist/server/routes/decisions.d.ts +6 -6
- package/dist/server/routes/decisions.js +12 -21
- package/dist/server/routes/incidents.d.ts +6 -6
- package/dist/server/routes/incidents.js +14 -25
- package/dist/server/routes/memories.d.ts +9 -9
- package/dist/server/routes/memories.js +20 -63
- package/dist/server/routes/object-routes.d.ts +6 -11
- package/dist/server/routes/object-routes.js +11 -22
- package/dist/server/routes/policies.d.ts +7 -7
- package/dist/server/routes/policies.js +12 -22
- package/dist/server/routes/predictions.d.ts +6 -6
- package/dist/server/routes/predictions.js +22 -38
- package/dist/server/routes/processes.d.ts +6 -6
- package/dist/server/routes/processes.js +17 -28
- package/dist/server/routes/project-briefs.d.ts +7 -7
- package/dist/server/routes/project-briefs.js +11 -20
- package/dist/server/routes/recall.d.ts +5 -5
- package/dist/server/routes/recall.js +16 -45
- package/dist/server/routes/skills.d.ts +7 -7
- package/dist/server/routes/skills.js +10 -22
- package/dist/server/server-detect.d.ts +15 -53
- package/dist/server/server-detect.js +55 -96
- package/dist/server/sleep-child.js +26 -7
- package/dist/server/sleep-offload.d.ts +11 -5
- package/dist/server/sleep-offload.js +21 -12
- package/dist/server/types.d.ts +32 -18
- package/dist/server/validation.d.ts +3 -2
- package/dist/server/validation.js +15 -33
- package/dist/server.d.ts +7 -6
- package/dist/server.js +8 -6
- package/dist/sharing/global-store.d.ts +19 -0
- package/dist/sharing/global-store.js +75 -0
- package/dist/sharing/global-sync.d.ts +6 -0
- package/dist/sharing/global-sync.js +73 -0
- package/dist/sharing/project-merge.d.ts +11 -19
- package/dist/sharing/project-merge.js +63 -125
- package/dist/sharing/search-both.d.ts +60 -0
- package/dist/sharing/search-both.js +138 -0
- package/dist/sharing/share.d.ts +40 -0
- package/dist/sharing/share.js +229 -0
- package/dist/store/ambient.js +9 -15
- package/dist/store/audit-event.d.ts +5 -13
- package/dist/store/audit-event.js +4 -12
- package/dist/store/audit.d.ts +2 -21
- package/dist/store/audit.js +8 -67
- package/dist/store/auth.d.ts +10 -8
- package/dist/store/auth.js +17 -12
- package/dist/store/candidates.d.ts +23 -5
- package/dist/store/candidates.js +119 -71
- package/dist/store/capture-write.d.ts +17 -0
- package/dist/store/capture-write.js +35 -0
- package/dist/store/card-detail.d.ts +2 -1
- package/dist/store/card-detail.js +2 -1
- package/dist/store/cards.d.ts +14 -9
- package/dist/store/cards.js +72 -126
- package/dist/store/compaction-caller.d.ts +18 -0
- package/dist/store/compaction-caller.js +29 -0
- package/dist/store/compactions-record.d.ts +115 -0
- package/dist/store/compactions-record.js +417 -0
- package/dist/store/compactions.js +6 -4
- package/dist/store/conflicts.d.ts +4 -21
- package/dist/store/conflicts.js +76 -152
- package/dist/store/connectors/dlq.d.ts +10 -0
- package/dist/store/connectors/dlq.js +32 -0
- package/dist/store/connectors/github.d.ts +14 -16
- package/dist/store/connectors/github.js +34 -57
- package/dist/store/connectors/slack.d.ts +2 -11
- package/dist/store/connectors/slack.js +18 -47
- package/dist/store/dashboard-reads.js +11 -14
- package/dist/store/delete-and-batch.d.ts +17 -31
- package/dist/store/delete-and-batch.js +84 -67
- package/dist/store/delivery-recorder.d.ts +15 -4
- package/dist/store/delivery-recorder.js +34 -17
- package/dist/store/descendant-page.js +6 -3
- package/dist/store/diagnostics.js +6 -13
- package/dist/store/dormant.d.ts +8 -30
- package/dist/store/dormant.js +18 -57
- package/dist/store/embeddings/index.d.ts +11 -90
- package/dist/store/embeddings/index.js +18 -523
- package/dist/store/entry-reads.d.ts +34 -61
- package/dist/store/entry-reads.js +111 -136
- package/dist/store/entry-row.d.ts +6 -35
- package/dist/store/entry-row.js +9 -37
- package/dist/store/entry-writes.d.ts +12 -18
- package/dist/store/entry-writes.js +46 -44
- package/dist/store/failure-log-at.d.ts +8 -0
- package/dist/store/failure-log-at.js +16 -0
- package/dist/store/failure-log.d.ts +2 -2
- package/dist/store/failure-log.js +5 -3
- package/dist/{trust → store}/gated-write.d.ts +3 -1
- package/dist/{trust → store}/gated-write.js +7 -5
- package/dist/store/goals.d.ts +3 -40
- package/dist/store/goals.js +41 -178
- package/dist/store/graph-queue.d.ts +6 -22
- package/dist/store/graph-queue.js +14 -45
- package/dist/store/graph-reads.d.ts +11 -35
- package/dist/store/graph-reads.js +24 -60
- package/dist/store/graph-rows.d.ts +3 -6
- package/dist/store/graph-rows.js +6 -9
- package/dist/store/graph-view-rows.d.ts +2 -1
- package/dist/store/graph-view-rows.js +2 -1
- package/dist/store/graph-writes.d.ts +10 -35
- package/dist/store/graph-writes.js +59 -106
- package/dist/store/half-life.d.ts +2 -1
- package/dist/store/half-life.js +14 -16
- package/dist/store/handoffs.d.ts +6 -12
- package/dist/store/handoffs.js +22 -40
- package/dist/store/index-and-stats.d.ts +6 -19
- package/dist/store/index-and-stats.js +36 -84
- package/dist/store/key-writes.js +1 -1
- package/dist/store/ledger-turn.d.ts +9 -0
- package/dist/store/ledger-turn.js +38 -0
- package/dist/store/mirrors.d.ts +2 -6
- package/dist/store/mirrors.js +24 -29
- package/dist/store/open.d.ts +0 -4
- package/dist/store/open.js +42 -62
- package/dist/store/pilot-arm.d.ts +12 -0
- package/dist/store/pilot-arm.js +42 -0
- package/dist/store/planning-fallacy-evidence.d.ts +2 -30
- package/dist/store/planning-fallacy-evidence.js +8 -37
- package/dist/store/port.d.ts +91 -82
- package/dist/store/port.js +8 -0
- package/dist/store/predictions.d.ts +12 -53
- package/dist/store/predictions.js +41 -125
- package/dist/store/project-tags.d.ts +62 -0
- package/dist/store/project-tags.js +67 -0
- package/dist/{cli → store}/quality-repair.js +15 -31
- package/dist/store/quarantine.js +2 -1
- package/dist/store/raw-archive.d.ts +4 -16
- package/dist/store/raw-archive.js +14 -29
- package/dist/store/recall-trace.d.ts +12 -77
- package/dist/store/recall-trace.js +37 -97
- package/dist/store/rejected-values.js +9 -20
- package/dist/store/rejection-probe.d.ts +4 -0
- package/dist/store/rejection-probe.js +19 -0
- package/dist/store/rejection.d.ts +10 -73
- package/dist/store/rejection.js +12 -84
- package/dist/store/report-reads.d.ts +6 -0
- package/dist/store/report-reads.js +29 -0
- package/dist/store/rows.d.ts +9 -19
- package/dist/store/rows.js +36 -34
- package/dist/store/rule-sql.d.ts +14 -0
- package/dist/store/rule-sql.js +56 -0
- package/dist/store/search-rows.d.ts +7 -38
- package/dist/store/search-rows.js +23 -54
- package/dist/store/sessions.d.ts +10 -47
- package/dist/store/sessions.js +21 -75
- package/dist/store/set-aside.d.ts +14 -0
- package/dist/store/set-aside.js +23 -0
- package/dist/store/sqlite/busy.d.ts +3 -0
- package/dist/store/sqlite/busy.js +8 -0
- package/dist/store/sqlite/connector-events-group.js +5 -8
- package/dist/store/sqlite/connector-writes-group.js +3 -3
- package/dist/store/sqlite/entry-writes-group.js +4 -4
- package/dist/store/sqlite/error-codec.js +8 -5
- package/dist/store/sqlite/executor.d.ts +2 -1
- package/dist/store/sqlite/executor.js +12 -5
- package/dist/store/sqlite/graph-reads-group.js +1 -1
- package/dist/store/sqlite/held-connection.d.ts +9 -0
- package/dist/store/sqlite/held-connection.js +41 -0
- package/dist/store/sqlite/local.d.ts +3 -3
- package/dist/store/sqlite/local.js +1 -0
- package/dist/store/sqlite/object-rows.d.ts +1 -1
- package/dist/store/sqlite/object-rows.js +6 -3
- package/dist/store/sqlite/objects-group.d.ts +1 -1
- package/dist/store/sqlite/objects-group.js +5 -3
- package/dist/store/sqlite/quarantine-group.js +2 -2
- package/dist/store/sqlite/store.d.ts +1 -4
- package/dist/store/sqlite/store.js +16 -15
- package/dist/store/sqlite/vector-reads-group.js +2 -2
- package/dist/store/sqlite/worker-jobs.js +1 -1
- package/dist/store/sqlite/worker-ops.d.ts +13 -2
- package/dist/store/sqlite/worker-ops.js +13 -2
- package/dist/store/sqlite/worker-store.js +5 -2
- package/dist/store/summaries.d.ts +11 -63
- package/dist/store/summaries.js +37 -148
- package/dist/store/summary-dirty.js +1 -1
- package/dist/store/tenant-lookup.d.ts +6 -1
- package/dist/store/tenant-lookup.js +7 -0
- package/dist/store/tenant.d.ts +2 -16
- package/dist/store/tenant.js +4 -19
- package/dist/store/token-ledger.d.ts +13 -50
- package/dist/store/token-ledger.js +19 -85
- package/dist/store/usage-reports.js +5 -13
- package/dist/store/vector-index.d.ts +46 -0
- package/dist/store/vector-index.js +171 -0
- package/dist/store/working-memory.d.ts +6 -25
- package/dist/store/working-memory.js +18 -52
- package/dist/support-bundle.js +9 -8
- package/dist/trust/reject-flow.js +3 -5
- package/dist/util/agent-homes.d.ts +15 -0
- package/dist/util/agent-homes.js +34 -0
- package/dist/util/anthropic-messages.d.ts +3 -0
- package/dist/util/anthropic-messages.js +35 -6
- package/dist/util/atomic-write.d.ts +2 -1
- package/dist/util/atomic-write.js +35 -4
- package/dist/util/capped-json.d.ts +6 -0
- package/dist/util/capped-json.js +46 -0
- package/dist/util/chunked.d.ts +3 -0
- package/dist/util/chunked.js +10 -0
- package/dist/util/crash-handlers.d.ts +8 -1
- package/dist/util/crash-handlers.js +52 -10
- package/dist/util/ellipsize.d.ts +3 -0
- package/dist/util/ellipsize.js +5 -0
- package/dist/util/env.d.ts +14 -6
- package/dist/util/env.js +15 -7
- package/dist/util/format.d.ts +3 -0
- package/dist/util/format.js +6 -0
- package/dist/util/home-path.d.ts +2 -1
- package/dist/util/home-path.js +4 -2
- package/dist/util/hook-payload.d.ts +8 -0
- package/dist/util/hook-payload.js +37 -0
- package/dist/util/http-retry.d.ts +9 -1
- package/dist/util/http-retry.js +67 -8
- package/dist/util/http-util.d.ts +0 -8
- package/dist/util/http-util.js +10 -21
- package/dist/util/limits.d.ts +7 -0
- package/dist/util/limits.js +14 -0
- package/dist/util/log.d.ts +7 -2
- package/dist/util/log.js +34 -9
- package/dist/util/request-scope.d.ts +5 -2
- package/dist/util/request-scope.js +13 -7
- package/dist/util/secret-detect.d.ts +5 -30
- package/dist/util/secret-detect.js +19 -40
- package/dist/util/sqlite-blocked.d.ts +2 -0
- package/dist/util/sqlite-blocked.js +5 -0
- package/dist/util/stored-json.d.ts +1 -1
- package/dist/util/stored-json.js +1 -1
- package/dist/util/stream-tee.d.ts +3 -0
- package/dist/util/stream-tee.js +35 -0
- package/dist/util/time.d.ts +4 -0
- package/dist/util/time.js +4 -0
- package/dist/util/token-text.d.ts +1 -4
- package/dist/util/token-text.js +1 -4
- package/dist/util/transcript-tail.d.ts +2 -0
- package/dist/util/transcript-tail.js +24 -23
- package/dist/util/version.d.ts +5 -20
- package/dist/util/version.js +5 -20
- package/dist/{store → util}/yaml.d.ts +1 -5
- package/dist/{store → util}/yaml.js +2 -6
- package/extensions/openclaw-plugin/index.ts +1 -1
- 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 -2
- package/dist/cli/provenance-coverage.d.ts +0 -18
- package/dist/connectors/github/cli-impl.d.ts +0 -25
- package/dist/sharing/scope.d.ts +0 -14
- package/dist/sharing/shared.d.ts +0 -187
- package/dist/sharing/shared.js +0 -563
- package/dist/store/embeddings/local.d.ts +0 -15
- package/dist/store/embeddings/local.js +0 -192
- package/dist/store/embeddings/provider.d.ts +0 -77
- package/dist/store/markdown.d.ts +0 -10
- package/dist/store/recall-scope.d.ts +0 -138
- package/dist/store/recall-scope.js +0 -216
- package/dist/store/vector-writes.d.ts +0 -13
- package/dist/store/vector-writes.js +0 -89
- /package/dist/{store → core}/object-types.d.ts +0 -0
- /package/dist/{store → core}/object-types.js +0 -0
- /package/dist/{cli → store}/quality-repair.d.ts +0 -0
- /package/dist/{capture → util}/compaction-items.d.ts +0 -0
- /package/dist/{capture → util}/compaction-items.js +0 -0
|
@@ -1,85 +1,28 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import { envByName } from '../../util/env.js';
|
|
7
|
-
import * as fs from 'fs';
|
|
8
|
-
import * as path from 'path';
|
|
9
|
-
import { randomUUID } from 'crypto';
|
|
10
|
-
import { loadAllEntries } from '../entry-reads.js';
|
|
11
|
-
import { openHippoDb, closeHippoDb, getMeta, rethrowIfSqliteBlocked, setMeta } from '../../db/index.js';
|
|
12
|
-
import { EMBEDDING_MODEL_META_KEY, deleteOrphanVectors, hasStoredVectors, loadVectors, loadVectorViews, replaceAllVectors, storedVectorIds, upsertVectors, } from '../../db/vector-store.js';
|
|
13
|
-
import { initializeParticle, savePhysicsState, loadPhysicsState, resetAllPhysicsState } from '../../db/physics-state.js';
|
|
14
|
-
import { loadConfig } from '../../core/config.js';
|
|
15
|
-
import { resolveEmbeddingProvider } from './provider.js';
|
|
16
|
-
import { DEFAULT_EMBEDDING_MODEL } from './local.js';
|
|
17
|
-
import { redactSecretsStrict } from '../../util/secret-detect.js';
|
|
1
|
+
/** The stored vector index's identity: which model and text format built it, and when a provider change means a rebuild.
|
|
2
|
+
* Picking a provider and computing vectors sit in src/search/embed-memories.ts; this module only reads and writes what is stored. */
|
|
3
|
+
import { cosineOf } from '../../core/cosine.js';
|
|
4
|
+
import { EMBEDDING_MODEL_META_KEY } from '../../db/vector-store.js';
|
|
5
|
+
import { indexedModel, saveIndexIdentity, storedIndexState } from '../vector-index.js';
|
|
18
6
|
import { errorMessage, log } from '../../util/log.js';
|
|
19
|
-
import {
|
|
7
|
+
import { rethrowIfSqliteBlocked } from '../../util/sqlite-blocked.js';
|
|
20
8
|
export { EMBEDDING_MODEL_META_KEY };
|
|
21
|
-
/**
|
|
22
|
-
*
|
|
23
|
-
* changes the resulting vectors for existing entries. Folded into the stored
|
|
24
|
-
* index identity (see `embeddingIndexIdentity`) so a text-format change is
|
|
25
|
-
* treated exactly like an embedding-model change: the next embed-touching
|
|
26
|
-
* operation detects the mismatch and reindexes automatically. Format 2 =
|
|
27
|
-
* `path:*` tags excluded (see `embeddingInputText`); format 1 (implicit, no
|
|
28
|
-
* suffix) = `${content} ${tags.join(' ')}` including path tags.
|
|
29
|
-
*/
|
|
9
|
+
/** Bump when `embeddingInputText` changes existing vectors; folded into the stored index identity (`embeddingIndexIdentity`) so it reindexes like a model
|
|
10
|
+
* change. Format 2 = `path:*` tags excluded; format 1 (implicit, no suffix) included them. */
|
|
30
11
|
export const EMBED_TEXT_FORMAT = 2;
|
|
31
|
-
/**
|
|
32
|
-
*
|
|
33
|
-
* `EMBED_TEXT_FORMAT` into the provider id so index-identity comparisons
|
|
34
|
-
* automatically invalidate on either a model change OR a text-format change.
|
|
35
|
-
* This is the ONE choke point both `embeddingModelRequiresReindex` (compare
|
|
36
|
-
* side) and `saveStoredEmbeddingModel` (save side) go through — they MUST
|
|
37
|
-
* version identically, or every call reindexes in a loop (or none ever do).
|
|
38
|
-
*/
|
|
12
|
+
/** Stored-index identity for a provider id: folds `EMBED_TEXT_FORMAT` in so a model or text-format change invalidates the index. The ONE choke point for
|
|
13
|
+
* compare (`embeddingModelRequiresReindex`) and save (`saveStoredEmbeddingModel`); they MUST version identically or every call reindexes. */
|
|
39
14
|
export function embeddingIndexIdentity(providerId) {
|
|
40
15
|
return `${providerId}#t${EMBED_TEXT_FORMAT}`;
|
|
41
16
|
}
|
|
42
|
-
/**
|
|
43
|
-
*
|
|
44
|
-
* by a space and trimmed — the same shape as the legacy
|
|
45
|
-
* `` `${e.content} ${e.tags.join(' ')}`.trim() `` composition, minus `path:*`
|
|
46
|
-
* tags.
|
|
47
|
-
*
|
|
48
|
-
* `path:*` tags are excluded because they are auto-derived from
|
|
49
|
-
* `process.cwd()` (see `extractPathTags` in cli.ts) and carry every path
|
|
50
|
-
* component of the store's location, INCLUDING the store directory name
|
|
51
|
-
* itself. That means identical content embeds to a DIFFERENT vector
|
|
52
|
-
* depending on WHERE the store happens to live — e.g. a fresh benchmark run
|
|
53
|
-
* under `tempfile.mkdtemp()` gets a new directory name (hence new path
|
|
54
|
-
* tokens, hence a new vector) every single run, even with byte-identical
|
|
55
|
-
* content ingested in byte-identical order. This was diagnosed as the
|
|
56
|
-
* DOMINANT root cause of cross-fresh-ingest recall-rank variance measured on
|
|
57
|
-
* LoCoMo (mean evidence-recall@5 stdev 0.0175 across 4 fresh re-ingests of
|
|
58
|
-
* identical data; see `benchmarks/LOCOMO_INVESTIGATION.md`, "Determinism
|
|
59
|
-
* characterization"). It is a real product defect beyond benchmarks too:
|
|
60
|
-
* retrieval semantics should not depend on a project directory's name.
|
|
61
|
-
*
|
|
62
|
-
* Only `path:*` is excluded. Other tags (`conv:`, `session:`, `speaker:`,
|
|
63
|
-
* `dia:`, `error`, `scope:`, etc.) remain embedded — they carry semantic
|
|
64
|
-
* meaning. Path relevance at recall time is already handled explicitly by
|
|
65
|
-
* the v39 scope-isolation layer (`origin_project`, `pathOverlapScore`), so
|
|
66
|
-
* embedding-level path tokens are redundant with a dedicated mechanism
|
|
67
|
-
* rather than a feature.
|
|
68
|
-
*/
|
|
17
|
+
/** Text embedded for an entry: content plus tags, space-joined and trimmed, minus `path:*` tags.
|
|
18
|
+
* `path:*` tags derive from cwd, so identical content would embed differently per store location; path relevance is handled by `pathOverlapScore`. */
|
|
69
19
|
export function embeddingInputText(entry) {
|
|
70
20
|
const tags = entry.tags.filter((t) => !t.startsWith('path:'));
|
|
71
21
|
return `${entry.content} ${tags.join(' ')}`.trim();
|
|
72
22
|
}
|
|
73
23
|
function loadStoredEmbeddingModel(hippoRoot) {
|
|
74
24
|
try {
|
|
75
|
-
|
|
76
|
-
try {
|
|
77
|
-
const model = getMeta(db, EMBEDDING_MODEL_META_KEY, '').trim();
|
|
78
|
-
return model || null;
|
|
79
|
-
}
|
|
80
|
-
finally {
|
|
81
|
-
closeHippoDb(db);
|
|
82
|
-
}
|
|
25
|
+
return storedIndexState(hippoRoot).storedModel;
|
|
83
26
|
}
|
|
84
27
|
catch (err) {
|
|
85
28
|
rethrowIfSqliteBlocked(err);
|
|
@@ -87,474 +30,26 @@ function loadStoredEmbeddingModel(hippoRoot) {
|
|
|
87
30
|
return null;
|
|
88
31
|
}
|
|
89
32
|
}
|
|
90
|
-
/**
|
|
91
|
-
*
|
|
92
|
-
* Versioning happens INSIDE this function, not at call sites, so every caller
|
|
93
|
-
* — current and future — gets the identity format for free. Must stay
|
|
94
|
-
* consistent with the compare side in `embeddingModelRequiresReindex`.
|
|
95
|
-
*/
|
|
33
|
+
/** Persist the stored-index identity for `model` (see `embeddingIndexIdentity`); versioning happens here, not at call sites,
|
|
34
|
+
* and must stay consistent with the compare side in `embeddingModelRequiresReindex`. */
|
|
96
35
|
export function saveStoredEmbeddingModel(hippoRoot, model) {
|
|
97
|
-
|
|
98
|
-
try {
|
|
99
|
-
setMeta(db, EMBEDDING_MODEL_META_KEY, embeddingIndexIdentity(model));
|
|
100
|
-
}
|
|
101
|
-
finally {
|
|
102
|
-
closeHippoDb(db);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
/** The model the index was built by: the stored identity, else the default model when vectors exist. */
|
|
106
|
-
export function indexedModel(state) {
|
|
107
|
-
return state.storedModel ?? (state.hasVectors ? DEFAULT_EMBEDDING_MODEL : null);
|
|
36
|
+
saveIndexIdentity(hippoRoot, embeddingIndexIdentity(model));
|
|
108
37
|
}
|
|
109
38
|
/** The one rebuild rule every store applies to its indexed model. */
|
|
110
39
|
export function indexNeedsRebuild(indexed, providerId) {
|
|
111
40
|
return indexed !== null && indexed !== embeddingIndexIdentity(providerId);
|
|
112
41
|
}
|
|
113
|
-
/** Whether a vector write under the index identity `model` first drops the stored index, which another model built. */
|
|
114
|
-
export function replacesIndex(state, model) {
|
|
115
|
-
const indexed = indexedModel(state);
|
|
116
|
-
return indexed !== null && indexed !== model;
|
|
117
|
-
}
|
|
118
42
|
export function resolveIndexedEmbeddingModel(hippoRoot, index) {
|
|
119
43
|
const storedModel = loadStoredEmbeddingModel(hippoRoot);
|
|
120
44
|
if (storedModel)
|
|
121
45
|
return storedModel;
|
|
122
|
-
return indexedModel({ storedModel, hasVectors: index ? Object.keys(index).length > 0 :
|
|
46
|
+
return indexedModel({ storedModel, hasVectors: index ? Object.keys(index).length > 0 : storedIndexState(hippoRoot).hasVectors });
|
|
123
47
|
}
|
|
124
48
|
export function embeddingModelRequiresReindex(hippoRoot, model, index) {
|
|
125
49
|
return indexNeedsRebuild(resolveIndexedEmbeddingModel(hippoRoot, index), model);
|
|
126
50
|
}
|
|
127
|
-
/**
|
|
128
|
-
export function embeddingIndexStateAt(hippoRoot) {
|
|
129
|
-
return withVectorDb(hippoRoot, embeddingIndexStateOn);
|
|
130
|
-
}
|
|
131
|
-
export function embeddingIndexStateOn(db) {
|
|
132
|
-
return {
|
|
133
|
-
storedModel: getMeta(db, EMBEDDING_MODEL_META_KEY, '').trim() || null,
|
|
134
|
-
hasVectors: hasStoredVectors(db),
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
async function rebuildEmbeddingIndex(entries, provider) {
|
|
138
|
-
const rebuilt = {};
|
|
139
|
-
if (entries.length === 0)
|
|
140
|
-
return rebuilt;
|
|
141
|
-
const texts = entries.map((e) => embeddingInputText(e));
|
|
142
|
-
// provider.embed batches internally; on a hard transport/auth failure it
|
|
143
|
-
// throws, so the caller aborts WITHOUT saving a partial index (atomic
|
|
144
|
-
// reindex: the old index + stored identity are preserved).
|
|
145
|
-
const vectors = await provider.embed(texts, 'passage');
|
|
146
|
-
for (let i = 0; i < entries.length; i++) {
|
|
147
|
-
const vec = vectors[i];
|
|
148
|
-
if (vec && vec.length > 0) {
|
|
149
|
-
rebuilt[entries[i].id] = vec;
|
|
150
|
-
}
|
|
151
|
-
else {
|
|
152
|
-
noteSkippedEmbedding(entries[i].id);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
return rebuilt;
|
|
156
|
-
}
|
|
157
|
-
function resetPhysicsFromIndex(hippoRoot, entries, index) {
|
|
158
|
-
try {
|
|
159
|
-
const db = openHippoDb(hippoRoot);
|
|
160
|
-
try {
|
|
161
|
-
resetAllPhysicsState(db, entries, index);
|
|
162
|
-
}
|
|
163
|
-
finally {
|
|
164
|
-
closeHippoDb(db);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
catch (err) {
|
|
168
|
-
// Best effort: retrieval still falls back without physics state.
|
|
169
|
-
log.warn(`physics reset after reindex failed: ${errorMessage(err)}`);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
/** A provider's `[]` row is a swallowed per-item failure; name the memory so the gap can be traced. */
|
|
173
|
-
function noteSkippedEmbedding(id) {
|
|
174
|
-
log.warn('memory not embedded; the next embed run retries it', { id });
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* Cosine similarity between two vectors. Handles unnormalized vectors.
|
|
178
|
-
* Returns 0 for empty or mismatched vectors.
|
|
179
|
-
*/
|
|
51
|
+
/** Cosine similarity; handles unnormalized vectors, returns 0 for empty or mismatched vectors. */
|
|
180
52
|
export function cosineSimilarity(a, b) {
|
|
181
53
|
return cosineOf(a, b);
|
|
182
54
|
}
|
|
183
|
-
/** `cosineSimilarity` over any indexable vectors; a Float32 view reads the same doubles as its number[] copy, so the score is the same. */
|
|
184
|
-
export function cosineOf(a, b) {
|
|
185
|
-
if (a.length === 0 || b.length === 0 || a.length !== b.length)
|
|
186
|
-
return 0;
|
|
187
|
-
let dot = 0;
|
|
188
|
-
let normA = 0;
|
|
189
|
-
let normB = 0;
|
|
190
|
-
for (let i = 0; i < a.length; i++) {
|
|
191
|
-
dot += a[i] * b[i];
|
|
192
|
-
normA += a[i] * a[i];
|
|
193
|
-
normB += b[i] * b[i];
|
|
194
|
-
}
|
|
195
|
-
const denom = Math.sqrt(normA) * Math.sqrt(normB);
|
|
196
|
-
if (denom < 1e-10)
|
|
197
|
-
return 0;
|
|
198
|
-
// Clamp to [-1, 1] to handle floating point drift
|
|
199
|
-
return Math.min(1, Math.max(-1, dot / denom));
|
|
200
|
-
}
|
|
201
|
-
function withVectorDb(hippoRoot, fn) {
|
|
202
|
-
const db = openHippoDb(hippoRoot);
|
|
203
|
-
try {
|
|
204
|
-
return fn(db);
|
|
205
|
-
}
|
|
206
|
-
finally {
|
|
207
|
-
closeHippoDb(db);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
/** Every stored vector keyed by memory id; `{}` when none. Search reads only the rows it ranks via `loadStoredVectors`. */
|
|
211
|
-
export function loadEmbeddingIndex(hippoRoot) {
|
|
212
|
-
return Object.fromEntries(withVectorDb(hippoRoot, (db) => loadVectors(db)));
|
|
213
|
-
}
|
|
214
|
-
/** Stored vectors for `ids` only. */
|
|
215
|
-
export function loadStoredVectors(hippoRoot, ids) {
|
|
216
|
-
return ids.length === 0 ? new Map() : withVectorDb(hippoRoot, (db) => loadVectors(db, ids));
|
|
217
|
-
}
|
|
218
|
-
/** `loadStoredVectors` as Float32 views, for a caller that only scores them. */
|
|
219
|
-
export function loadStoredVectorViews(hippoRoot, ids) {
|
|
220
|
-
return ids.length === 0 ? new Map() : withVectorDb(hippoRoot, (db) => loadVectorViews(db, ids));
|
|
221
|
-
}
|
|
222
|
-
/** Replace every stored vector with `index`; `model` defaults to the stored index identity. */
|
|
223
|
-
export function saveEmbeddingIndex(hippoRoot, index, model) {
|
|
224
|
-
withVectorDb(hippoRoot, (db) => replaceAllVectors(db, index, model ?? getMeta(db, EMBEDDING_MODEL_META_KEY, '')));
|
|
225
|
-
}
|
|
226
|
-
const EMBED_LOCK_FILE = 'embeddings.lock';
|
|
227
|
-
const EMBED_LOCK_WAIT_MS = 10_000;
|
|
228
|
-
const EMBED_LOCK_OWNER = `${process.pid}:${randomUUID()}`;
|
|
229
|
-
// 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).
|
|
230
|
-
let _embedWriteLock = Promise.resolve();
|
|
231
|
-
function embedLockHolderAlive(lockPath) {
|
|
232
|
-
let raw;
|
|
233
|
-
try {
|
|
234
|
-
raw = fs.readFileSync(lockPath, 'utf8');
|
|
235
|
-
}
|
|
236
|
-
catch (err) {
|
|
237
|
-
return !(err instanceof Error && 'code' in err && err.code === 'ENOENT');
|
|
238
|
-
}
|
|
239
|
-
const mtimeMs = fs.statSync(lockPath, { throwIfNoEntry: false })?.mtimeMs ?? 0;
|
|
240
|
-
const pid = Number(raw.split(':')[0]);
|
|
241
|
-
// An empty lock is a holder between create and write; after 5 s it is a crashed one.
|
|
242
|
-
if (!Number.isInteger(pid) || pid <= 0)
|
|
243
|
-
return Date.now() - mtimeMs < 5_000;
|
|
244
|
-
if (raw === EMBED_LOCK_OWNER)
|
|
245
|
-
return false;
|
|
246
|
-
if (pid === process.pid)
|
|
247
|
-
return mtimeMs >= Date.now() - process.uptime() * 1000;
|
|
248
|
-
try {
|
|
249
|
-
process.kill(pid, 0);
|
|
250
|
-
return true;
|
|
251
|
-
}
|
|
252
|
-
catch (err) {
|
|
253
|
-
return err instanceof Error && 'code' in err && err.code === 'EPERM';
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
// After the double-break race below the file can be another writer's lock, so remove only our own.
|
|
257
|
-
function releaseEmbedFileLock(lockPath) {
|
|
258
|
-
let raw;
|
|
259
|
-
try {
|
|
260
|
-
raw = fs.readFileSync(lockPath, 'utf8');
|
|
261
|
-
}
|
|
262
|
-
catch (err) {
|
|
263
|
-
if (err instanceof Error && 'code' in err && err.code === 'ENOENT')
|
|
264
|
-
return;
|
|
265
|
-
throw err;
|
|
266
|
-
}
|
|
267
|
-
if (raw === EMBED_LOCK_OWNER)
|
|
268
|
-
fs.rmSync(lockPath, { force: true });
|
|
269
|
-
}
|
|
270
|
-
async function acquireEmbedFileLock(hippoRoot) {
|
|
271
|
-
const lockPath = path.join(hippoRoot, EMBED_LOCK_FILE);
|
|
272
|
-
const deadline = Date.now() + EMBED_LOCK_WAIT_MS;
|
|
273
|
-
for (;;) {
|
|
274
|
-
try {
|
|
275
|
-
fs.writeFileSync(lockPath, EMBED_LOCK_OWNER, { flag: 'wx' });
|
|
276
|
-
return () => releaseEmbedFileLock(lockPath);
|
|
277
|
-
}
|
|
278
|
-
catch (err) {
|
|
279
|
-
if (!(err instanceof Error && 'code' in err && err.code === 'EEXIST'))
|
|
280
|
-
throw err;
|
|
281
|
-
}
|
|
282
|
-
// SHORTCUT: two waiters can both break one dead holder's lock; a vector lost that way is backfilled by the next `hippo embed`.
|
|
283
|
-
if (!embedLockHolderAlive(lockPath)) {
|
|
284
|
-
fs.rmSync(lockPath, { force: true });
|
|
285
|
-
continue;
|
|
286
|
-
}
|
|
287
|
-
if (Date.now() >= deadline)
|
|
288
|
-
throw new Error(`the embedding index is busy: another hippo process holds ${lockPath}`);
|
|
289
|
-
await new Promise((r) => setTimeout(r, 50));
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
async function withEmbedLock(hippoRoot, fn) {
|
|
293
|
-
return withProcessEmbedLock(async () => {
|
|
294
|
-
const release = await acquireEmbedFileLock(hippoRoot);
|
|
295
|
-
try {
|
|
296
|
-
return await fn();
|
|
297
|
-
}
|
|
298
|
-
finally {
|
|
299
|
-
release();
|
|
300
|
-
}
|
|
301
|
-
});
|
|
302
|
-
}
|
|
303
|
-
// A store keeps each write whole in its own transaction, and a lock file in hippoRoot would not reach a worker on another host.
|
|
304
|
-
async function withProcessEmbedLock(fn) {
|
|
305
|
-
let resolve;
|
|
306
|
-
const next = new Promise(r => { resolve = r; });
|
|
307
|
-
const prev = _embedWriteLock;
|
|
308
|
-
_embedWriteLock = next;
|
|
309
|
-
await prev;
|
|
310
|
-
try {
|
|
311
|
-
return await fn();
|
|
312
|
-
}
|
|
313
|
-
finally {
|
|
314
|
-
resolve();
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
// A bad key fails every write; one warning tells the user, N would bury the command's own output.
|
|
318
|
-
let _embedFailureWarned = false;
|
|
319
|
-
function warnEmbedFailureOnce(source, rawMessage) {
|
|
320
|
-
if (_embedFailureWarned)
|
|
321
|
-
return;
|
|
322
|
-
_embedFailureWarned = true;
|
|
323
|
-
// Strict scrub: this line can land in a hook log file, and an API may echo the key back in its error body.
|
|
324
|
-
const message = redactSecretsStrict(rawMessage).replace(/\s+/g, ' ').replace(/\.+$/, '');
|
|
325
|
-
log.warn(`embedding failed (${source}): ${message}. Memories are stored without embeddings until this is fixed.`);
|
|
326
|
-
}
|
|
327
|
-
// store-port.ts imports this module, so its requireGroup would close an import cycle.
|
|
328
|
-
function vectorGroups(store) {
|
|
329
|
-
if (store.vectors === undefined)
|
|
330
|
-
throw new StoreNotPortedError(store.kind, 'vectors');
|
|
331
|
-
if (store.vectorWrites === undefined)
|
|
332
|
-
throw new StoreNotPortedError(store.kind, 'vectorWrites');
|
|
333
|
-
return [store.vectors, store.vectorWrites];
|
|
334
|
-
}
|
|
335
|
-
/** Writes one page's vectors, one writeVectors per tenant, and stops at the first refused write; `withParticles` seeds each memory's particle. */
|
|
336
|
-
async function writeVectorPage(writes, write, page, vectors, withParticles) {
|
|
337
|
-
const byTenant = new Map();
|
|
338
|
-
page.forEach((entry, i) => {
|
|
339
|
-
const vector = vectors[i];
|
|
340
|
-
if (!vector || vector.length === 0)
|
|
341
|
-
return noteSkippedEmbedding(entry.id);
|
|
342
|
-
const row = withParticles ? { memoryId: entry.id, vector, particle: initializeParticle(entry, vector) } : { memoryId: entry.id, vector };
|
|
343
|
-
byTenant.set(entry.tenantId, [...(byTenant.get(entry.tenantId) ?? []), row]);
|
|
344
|
-
});
|
|
345
|
-
let written = 0;
|
|
346
|
-
for (const [tenantId, rows] of byTenant) {
|
|
347
|
-
const result = await writes.writeVectors({ ...write, tenantId, rows });
|
|
348
|
-
if (result.modelMismatch)
|
|
349
|
-
return { written, modelMismatch: true };
|
|
350
|
-
written += result.written;
|
|
351
|
-
}
|
|
352
|
-
return { written, modelMismatch: false };
|
|
353
|
-
}
|
|
354
|
-
const STORE_PAGE = 64;
|
|
355
|
-
const OTHER_MODEL_INDEX = "the vector index was built by another embedding model; run 'hippo embed' to rebuild it";
|
|
356
|
-
/** Embeds every memory with no vector under `model`, page by page, so a provider failure keeps the pages written; a rebuild reseeds the particles it drops. */
|
|
357
|
-
async function backfillInStore(writes, provider, model, rebuild) {
|
|
358
|
-
let count = 0;
|
|
359
|
-
let afterId;
|
|
360
|
-
for (;;) {
|
|
361
|
-
const page = await writes.entriesWithoutVector({ model, afterId, limit: STORE_PAGE });
|
|
362
|
-
if (page.length === 0)
|
|
363
|
-
return count;
|
|
364
|
-
afterId = page[page.length - 1].id;
|
|
365
|
-
const vectors = await provider.embed(page.map((e) => embeddingInputText(e)), 'passage');
|
|
366
|
-
const result = await writeVectorPage(writes, { model, replaceIndex: rebuild }, page, vectors, rebuild);
|
|
367
|
-
// Another process rebuilt the index mid-run; every later page would be refused too, after paying the provider for it.
|
|
368
|
-
if (result.modelMismatch)
|
|
369
|
-
throw new Error(OTHER_MODEL_INDEX);
|
|
370
|
-
count += result.written;
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
/** embedAll on a store: a model change re-embeds every memory, and the first page written drops the old index. */
|
|
374
|
-
async function embedAllInStore(store, provider) {
|
|
375
|
-
const [reads, writes] = vectorGroups(store);
|
|
376
|
-
const rebuild = indexNeedsRebuild(indexedModel(await reads.embeddingIndexState()), provider.id);
|
|
377
|
-
return backfillInStore(writes, provider, embeddingIndexIdentity(provider.id), rebuild);
|
|
378
|
-
}
|
|
379
|
-
/** embedMemory on a store; like the hippo.db path it resolves whatever fails. Unlike it, it leaves a model change to embedAll, so a stale
|
|
380
|
-
* read here never drops another process's rebuild; the read only saves a paid embed call, as the write refuses another model itself. */
|
|
381
|
-
function embedMemoryInStore(store, provider, entry) {
|
|
382
|
-
return withProcessEmbedLock(async () => {
|
|
383
|
-
const [reads, writes] = vectorGroups(store);
|
|
384
|
-
const model = embeddingIndexIdentity(provider.id);
|
|
385
|
-
try {
|
|
386
|
-
const refused = replacesIndex(await reads.embeddingIndexState(), model)
|
|
387
|
-
|| (await writeVectorPage(writes, { model, replaceIndex: false }, [entry], await provider.embed([embeddingInputText(entry)], 'passage'), true)).modelMismatch;
|
|
388
|
-
if (refused)
|
|
389
|
-
warnEmbedFailureOnce('index', OTHER_MODEL_INDEX);
|
|
390
|
-
}
|
|
391
|
-
catch (err) {
|
|
392
|
-
warnEmbedFailureOnce(provider.kind, errorMessage(err));
|
|
393
|
-
}
|
|
394
|
-
}).catch((err) => {
|
|
395
|
-
log.warn(`skipped embedding ${entry.id} (${errorMessage(err)})`);
|
|
396
|
-
});
|
|
397
|
-
}
|
|
398
|
-
/** Embed a single memory entry and cache the result in the embedding index; with `store`, through its vectorWrites, never opening hippo.db. */
|
|
399
|
-
export async function embedMemory(hippoRoot, entry, model, store) {
|
|
400
|
-
let provider;
|
|
401
|
-
try {
|
|
402
|
-
provider = resolveEmbeddingProvider(hippoRoot, { model });
|
|
403
|
-
}
|
|
404
|
-
catch (err) {
|
|
405
|
-
// Callers fire and forget, so this must resolve: a bad config warns once instead of rejecting.
|
|
406
|
-
warnEmbedFailureOnce('config', errorMessage(err));
|
|
407
|
-
return;
|
|
408
|
-
}
|
|
409
|
-
if (!provider.isAvailable())
|
|
410
|
-
return;
|
|
411
|
-
if (store)
|
|
412
|
-
return embedMemoryInStore(store, provider, entry);
|
|
413
|
-
return withEmbedLock(hippoRoot, async () => {
|
|
414
|
-
// embedMemory is best-effort: an embedding failure (API down / bad key / 5xx)
|
|
415
|
-
// must not reject the caller's write — `getEmbedding` historically swallowed
|
|
416
|
-
// failures and returned []. The explicit `hippo embed` / `embedAll` path is
|
|
417
|
-
// where failures surface. On any failure we leave the existing index as-is.
|
|
418
|
-
try {
|
|
419
|
-
const identity = provider.id;
|
|
420
|
-
if (embeddingModelRequiresReindex(hippoRoot, identity)) {
|
|
421
|
-
await rebuildIndexForProvider(hippoRoot, provider);
|
|
422
|
-
return;
|
|
423
|
-
}
|
|
424
|
-
const text = embeddingInputText(entry);
|
|
425
|
-
const [vector] = await provider.embed([text], 'passage');
|
|
426
|
-
if (!vector || vector.length === 0)
|
|
427
|
-
return;
|
|
428
|
-
withVectorDb(hippoRoot, (db) => upsertVectors(db, [[entry.id, vector]], embeddingIndexIdentity(identity)));
|
|
429
|
-
saveStoredEmbeddingModel(hippoRoot, identity);
|
|
430
|
-
// Initialize physics state for this memory
|
|
431
|
-
initializePhysicsIfMissing(hippoRoot, entry, vector);
|
|
432
|
-
}
|
|
433
|
-
catch (err) {
|
|
434
|
-
// Provider failure (API down / bad key). Best-effort: leave the index as-is, but say so once.
|
|
435
|
-
warnEmbedFailureOnce(provider.kind, errorMessage(err));
|
|
436
|
-
}
|
|
437
|
-
}).catch((err) => {
|
|
438
|
-
log.warn(`skipped embedding ${entry.id} (${errorMessage(err)}); run 'hippo embed' to backfill`);
|
|
439
|
-
});
|
|
440
|
-
}
|
|
441
|
-
async function rebuildIndexForProvider(hippoRoot, provider) {
|
|
442
|
-
const identity = provider.id;
|
|
443
|
-
// Host-wide rebuild. The embedding index is keyed by entry.id
|
|
444
|
-
// (which is tenant-scoped) but the index itself is one per hippoRoot.
|
|
445
|
-
// Cross-tenant content equivalence is visible at the vector level.
|
|
446
|
-
// Per-tenant indices would be a larger architecture change.
|
|
447
|
-
const entries = loadAllEntries(hippoRoot);
|
|
448
|
-
const rebuiltIndex = await rebuildEmbeddingIndex(entries, provider);
|
|
449
|
-
saveEmbeddingIndex(hippoRoot, rebuiltIndex, embeddingIndexIdentity(identity));
|
|
450
|
-
saveStoredEmbeddingModel(hippoRoot, identity);
|
|
451
|
-
resetPhysicsFromIndex(hippoRoot, entries, rebuiltIndex);
|
|
452
|
-
}
|
|
453
|
-
function initializePhysicsIfMissing(hippoRoot, entry, vector) {
|
|
454
|
-
try {
|
|
455
|
-
const db = openHippoDb(hippoRoot);
|
|
456
|
-
try {
|
|
457
|
-
const existing = loadPhysicsState(db, [entry.id]);
|
|
458
|
-
if (!existing.has(entry.id)) {
|
|
459
|
-
const particle = initializeParticle(entry, vector);
|
|
460
|
-
savePhysicsState(db, [particle]);
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
finally {
|
|
464
|
-
closeHippoDb(db);
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
catch (err) {
|
|
468
|
-
// Physics init is best-effort and must not fail the embedding that just landed.
|
|
469
|
-
log.debug(`physics state not initialised for ${entry.id}: ${errorMessage(err)}`);
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
/** Throws when an unavailable provider is a misconfiguration rather than an intentional no-op. */
|
|
473
|
-
function throwIfProviderKeyMissing(hippoRoot, provider) {
|
|
474
|
-
// A configured (non-disabled) API provider with a missing key is a
|
|
475
|
-
// misconfiguration, not a no-op: surface it so programmatic callers of the
|
|
476
|
-
// exported embedAll() learn nothing was written. Local-not-installed and an
|
|
477
|
-
// explicit enabled=false stay silent no-ops (best-effort / intentional).
|
|
478
|
-
const cfg = loadConfig(hippoRoot).embeddings;
|
|
479
|
-
if (provider.kind !== 'local' &&
|
|
480
|
-
cfg.enabled !== false &&
|
|
481
|
-
provider.keyEnv &&
|
|
482
|
-
!envByName(provider.keyEnv)?.trim()) {
|
|
483
|
-
throw new Error(`Embedding provider '${provider.kind}' is configured but ${provider.keyEnv} is not set.`);
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
// Embed entries without a cached vector in save-checkpointed chunks.
|
|
487
|
-
// provider.embed batches internally (one HTTP request per batchSize for API
|
|
488
|
-
// providers; sequential for local). A `[]` row means that single item could
|
|
489
|
-
// not be embedded and is left for a later run (resumable). On a hard provider
|
|
490
|
-
// failure mid-backfill we persist the chunks already embedded this run rather
|
|
491
|
-
// than discarding paid progress, then stop and resume on the next run.
|
|
492
|
-
async function backfillPending(hippoRoot, provider, pending, model) {
|
|
493
|
-
let count = 0;
|
|
494
|
-
// Initialized to `undefined` (not a known-evidence literal like `null`) so
|
|
495
|
-
// it stays a plain `unknown` binding for the arbitrary caught value below;
|
|
496
|
-
// falsy either way, so `if (backfillError)` behaves identically.
|
|
497
|
-
let backfillError = undefined;
|
|
498
|
-
const SAVE_CHUNK = 64;
|
|
499
|
-
for (let i = 0; i < pending.length; i += SAVE_CHUNK) {
|
|
500
|
-
const chunk = pending.slice(i, i + SAVE_CHUNK);
|
|
501
|
-
let vectors;
|
|
502
|
-
try {
|
|
503
|
-
vectors = await provider.embed(chunk.map((e) => embeddingInputText(e)), 'passage');
|
|
504
|
-
}
|
|
505
|
-
catch (err) {
|
|
506
|
-
// Preserve the chunks already saved this run, then surface the failure
|
|
507
|
-
// below so the explicit `hippo embed` path never reports a false success.
|
|
508
|
-
backfillError = err;
|
|
509
|
-
break;
|
|
510
|
-
}
|
|
511
|
-
const rows = [];
|
|
512
|
-
for (let j = 0; j < chunk.length; j++) {
|
|
513
|
-
const vec = vectors[j];
|
|
514
|
-
if (vec && vec.length > 0)
|
|
515
|
-
rows.push([chunk[j].id, vec]);
|
|
516
|
-
else
|
|
517
|
-
noteSkippedEmbedding(chunk[j].id);
|
|
518
|
-
}
|
|
519
|
-
count += withVectorDb(hippoRoot, (db) => upsertVectors(db, rows, model));
|
|
520
|
-
}
|
|
521
|
-
return { count, backfillError };
|
|
522
|
-
}
|
|
523
|
-
/** Embeds every entry with no cached vector, prunes vectors of deleted memories, and returns how many it embedded; `provider` defaults to the
|
|
524
|
-
* configured one. With `store`, every tenant's memories with no vector for the provider's model go through its `vectorWrites`, never hippo.db. */
|
|
525
|
-
export async function embedAll(hippoRoot, model, provider = resolveEmbeddingProvider(hippoRoot, { model }), store) {
|
|
526
|
-
if (!provider.isAvailable()) {
|
|
527
|
-
throwIfProviderKeyMissing(hippoRoot, provider);
|
|
528
|
-
return 0;
|
|
529
|
-
}
|
|
530
|
-
if (store)
|
|
531
|
-
return withProcessEmbedLock(() => embedAllInStore(store, provider));
|
|
532
|
-
return withEmbedLock(hippoRoot, async () => {
|
|
533
|
-
const identity = provider.id;
|
|
534
|
-
// Host-wide by design. embedAll backfills vectors for all tenants'
|
|
535
|
-
// entries into the per-host embedding index. Per-tenant filtering would
|
|
536
|
-
// produce partial indices and break recall.
|
|
537
|
-
const entries = loadAllEntries(hippoRoot);
|
|
538
|
-
const model = embeddingIndexIdentity(identity);
|
|
539
|
-
if (embeddingModelRequiresReindex(hippoRoot, identity)) {
|
|
540
|
-
const rebuiltIndex = await rebuildEmbeddingIndex(entries, provider);
|
|
541
|
-
saveEmbeddingIndex(hippoRoot, rebuiltIndex, model);
|
|
542
|
-
saveStoredEmbeddingModel(hippoRoot, identity);
|
|
543
|
-
resetPhysicsFromIndex(hippoRoot, entries, rebuiltIndex);
|
|
544
|
-
return Object.keys(rebuiltIndex).length;
|
|
545
|
-
}
|
|
546
|
-
const embedded = withVectorDb(hippoRoot, (db) => {
|
|
547
|
-
deleteOrphanVectors(db);
|
|
548
|
-
return storedVectorIds(db);
|
|
549
|
-
});
|
|
550
|
-
const pending = entries.filter((e) => !embedded.has(e.id));
|
|
551
|
-
const { count, backfillError } = await backfillPending(hippoRoot, provider, pending, model);
|
|
552
|
-
saveStoredEmbeddingModel(hippoRoot, identity);
|
|
553
|
-
// Partial progress is now persisted; surface a hard backfill failure so the
|
|
554
|
-
// explicit embed path reports it (best-effort callers go via embedMemory).
|
|
555
|
-
if (backfillError)
|
|
556
|
-
throw backfillError;
|
|
557
|
-
return count;
|
|
558
|
-
});
|
|
559
|
-
}
|
|
560
55
|
//# sourceMappingURL=index.js.map
|