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
package/dist/store/audit.js
CHANGED
|
@@ -1,63 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { canAutoDelete } from '../core/memory.js';
|
|
1
|
+
import { DEFAULT_LIST_LIMIT } from '../util/limits.js';
|
|
3
2
|
import { closeHippoDb, openHippoDb, withWriteScope } from '../db/index.js';
|
|
4
3
|
import { log } from '../util/log.js';
|
|
4
|
+
import { blockHash } from '../util/token-text.js';
|
|
5
5
|
import { keysetAfter } from '../util/keyset.js';
|
|
6
6
|
import { warnDamagedColumn } from '../util/stored-json.js';
|
|
7
|
-
import { automaticDefect, hasNoSpecificity, isFragment, isReleaseCommitNoise, substantiveWordCount, } from '../core/memory-quality.js';
|
|
8
|
-
export function auditMemory(entry, backsObject = false) {
|
|
9
|
-
const issue = classifyMemory(entry);
|
|
10
|
-
// Error means "auto-remove"; a pinned, raw, kept-for-good or object-backing row is never auto-removed, so it can only warn.
|
|
11
|
-
if (issue?.severity === 'error' && (!canAutoDelete(entry) || backsObject)) {
|
|
12
|
-
const why = entry.pinned ? 'pinned' : entry.kind === 'raw' ? 'raw' : backsObject ? 'backs an object' : 'keep rule';
|
|
13
|
-
return { ...issue, severity: 'warning', reason: `${issue.reason} (${why}, kept)` };
|
|
14
|
-
}
|
|
15
|
-
return issue;
|
|
16
|
-
}
|
|
17
|
-
function classifyMemory(entry) {
|
|
18
|
-
const content = entry.content.trim();
|
|
19
|
-
if (content.length < 3) {
|
|
20
|
-
return { memoryId: entry.id, content, severity: 'error', reason: 'too short (< 3 chars)' };
|
|
21
|
-
}
|
|
22
|
-
if (content.length < 10) {
|
|
23
|
-
return { memoryId: entry.id, content, severity: 'error', reason: 'too short (< 10 chars)' };
|
|
24
|
-
}
|
|
25
|
-
if (isReleaseCommitNoise(content)) {
|
|
26
|
-
return { memoryId: entry.id, content, severity: 'error', reason: 'release/commit noise, not a useful memory' };
|
|
27
|
-
}
|
|
28
|
-
if (isFragment(content)) {
|
|
29
|
-
return { memoryId: entry.id, content, severity: 'warning', reason: 'sentence fragment — lacks context' };
|
|
30
|
-
}
|
|
31
|
-
const substantive = substantiveWordCount(content);
|
|
32
|
-
if (substantive < 2) {
|
|
33
|
-
return { memoryId: entry.id, content, severity: 'warning', reason: `only ${substantive} substantive word(s) — too vague` };
|
|
34
|
-
}
|
|
35
|
-
if (content.length < 40 && hasNoSpecificity(content)) {
|
|
36
|
-
return { memoryId: entry.id, content, severity: 'warning', reason: 'no specific details (names, paths, numbers, code)' };
|
|
37
|
-
}
|
|
38
|
-
const reason = automaticDefect(entry);
|
|
39
|
-
if (reason !== null) {
|
|
40
|
-
return { memoryId: entry.id, content, severity: 'warning', reason: `automatic memory defect: ${reason}` };
|
|
41
|
-
}
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
|
-
/** `backing`: ids of memories that back an object (store.memoriesBackingObjects). */
|
|
45
|
-
export function auditMemories(entries, backing) {
|
|
46
|
-
const issues = [];
|
|
47
|
-
for (const entry of entries) {
|
|
48
|
-
const issue = auditMemory(entry, backing.has(entry.id));
|
|
49
|
-
if (issue)
|
|
50
|
-
issues.push(issue);
|
|
51
|
-
}
|
|
52
|
-
return {
|
|
53
|
-
total: entries.length,
|
|
54
|
-
issues,
|
|
55
|
-
clean: entries.length - issues.length,
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
// ---------------------------------------------------------------------------
|
|
59
|
-
// Audit log primitives (append-only mutation trail)
|
|
60
|
-
// ---------------------------------------------------------------------------
|
|
61
7
|
// The one list of audit ops: the AuditOp type, `hippo audit list --op` and GET /v1/audit?op= all read it.
|
|
62
8
|
export const AUDIT_OPS = [
|
|
63
9
|
'remember',
|
|
@@ -131,7 +77,7 @@ function bigintSafeReplacer(_key, value) {
|
|
|
131
77
|
}
|
|
132
78
|
export function auditQueryFields(query) {
|
|
133
79
|
return {
|
|
134
|
-
query_hash:
|
|
80
|
+
query_hash: blockHash(query),
|
|
135
81
|
query_length: query.length,
|
|
136
82
|
};
|
|
137
83
|
}
|
|
@@ -175,18 +121,15 @@ export function queryAuditEvents(db, opts) {
|
|
|
175
121
|
}
|
|
176
122
|
const after = keysetAfter('ts', 'id', opts.after);
|
|
177
123
|
// One past the route's 10000 cap: GET /v1/audit reads a row ahead to tell whether another page exists.
|
|
178
|
-
const limit = Math.max(1, Math.min(opts.limit ??
|
|
124
|
+
const limit = Math.max(1, Math.min(opts.limit ?? DEFAULT_LIST_LIMIT, 10001));
|
|
179
125
|
// SAFETY: AUDIT_COLUMNS names exactly the AuditRow columns, in this order.
|
|
180
126
|
const rows = db
|
|
181
127
|
.prepare(`SELECT ${AUDIT_COLUMNS} FROM audit_log WHERE ${where.join(' AND ')}${after.sql} ORDER BY ts DESC, id DESC LIMIT ?`)
|
|
182
128
|
.all(...params, ...after.params, limit);
|
|
183
129
|
return rows.map(rowToAuditEvent);
|
|
184
130
|
}
|
|
185
|
-
/**
|
|
186
|
-
*
|
|
187
|
-
* and never reused, but deletes (retention prune) leave gaps, so resume from
|
|
188
|
-
* the last id returned, never from a count.
|
|
189
|
-
*/
|
|
131
|
+
/** Cursor read: events with id > afterId, ascending. Retention prune leaves gaps in the ids,
|
|
132
|
+
* so resume from the last id returned, never from a count. */
|
|
190
133
|
export function listAuditEventsAfter(db, opts) {
|
|
191
134
|
if (!Number.isInteger(opts.afterId) || opts.afterId < 0) {
|
|
192
135
|
throw new RangeError('afterId must be a non-negative integer');
|
|
@@ -255,10 +198,8 @@ function rowToAuditEvent(r) {
|
|
|
255
198
|
function safeJsonParse(raw, id) {
|
|
256
199
|
try {
|
|
257
200
|
const v = JSON.parse(raw);
|
|
258
|
-
// SAFETY: JSON.parse
|
|
259
|
-
//
|
|
260
|
-
// (both are valid JsonObject shapes for our purposes), matching the prior
|
|
261
|
-
// `typeof v === 'object' && v !== null` check without using typeof.
|
|
201
|
+
// SAFETY: JSON.parse returns only an object, array or primitive; `instanceof Object` is true for the first two,
|
|
202
|
+
// both valid JsonObject shapes here.
|
|
262
203
|
return v instanceof Object ? v : {};
|
|
263
204
|
}
|
|
264
205
|
catch {
|
package/dist/store/auth.d.ts
CHANGED
|
@@ -12,13 +12,15 @@ export declare function apiKeyVerifyStats(): ApiKeyVerifyStats;
|
|
|
12
12
|
export interface CreateApiKeyOpts {
|
|
13
13
|
tenantId: string;
|
|
14
14
|
label?: string;
|
|
15
|
-
/** 'admin' | 'member'. Defaults to '
|
|
15
|
+
/** 'admin' | 'member'. Defaults to 'member', like the API layer. */
|
|
16
16
|
role?: 'admin' | 'member';
|
|
17
17
|
/** The auth-resolver subject a self-service key belongs to; unset for keys an admin or the CLI mints. */
|
|
18
18
|
ownerSubject?: string;
|
|
19
|
-
/** ISO time the key stops working; unset means
|
|
19
|
+
/** ISO time the key stops working; unset means DEFAULT_KEY_TTL_DAYS from now. */
|
|
20
20
|
expiresAt?: string;
|
|
21
21
|
}
|
|
22
|
+
/** Days a key lives when its mint names no expiry, so a key nobody remembers stops working by itself. */
|
|
23
|
+
export declare const DEFAULT_KEY_TTL_DAYS = 90;
|
|
22
24
|
export interface CreateApiKeyResult {
|
|
23
25
|
keyId: string;
|
|
24
26
|
plaintext: string;
|
|
@@ -75,7 +77,8 @@ export interface ApiKeyRecord {
|
|
|
75
77
|
/** The api_keys row for `keyId` with its scope grants; null when no row matches. */
|
|
76
78
|
export declare function readApiKeyRecord(db: DatabaseSyncLike, keyId: string): ApiKeyRecord | null;
|
|
77
79
|
export declare function validateApiKey(db: DatabaseSyncLike, plaintext: string): ValidateResult;
|
|
78
|
-
/** LRU of the tokens that matched a stored key hash, so a repeat skips scrypt. Holds
|
|
80
|
+
/** LRU of the tokens that matched a stored key hash, so a repeat skips scrypt. Holds
|
|
81
|
+
* a SHA-256 of the token, never the token, and nothing about the key's state. */
|
|
79
82
|
export declare class VerifiedKeyCache {
|
|
80
83
|
private readonly capacity;
|
|
81
84
|
private readonly proven;
|
|
@@ -86,7 +89,8 @@ export declare class VerifiedKeyCache {
|
|
|
86
89
|
}
|
|
87
90
|
/** A caller's limit on scrypt work, called once per derivation: it may throw to refuse `derive` or hold it in a queue. */
|
|
88
91
|
type DerivationBound = (keyId: string, derive: () => Promise<Buffer>) => Promise<Buffer>;
|
|
89
|
-
/** Verify a bearer API key against `store`, null when invalid. The key's row is read on every
|
|
92
|
+
/** Verify a bearer API key against `store`, null when invalid. The key's row is read on every
|
|
93
|
+
* call, so a revoke, expiry, role or scope change by any process applies on the next one. */
|
|
90
94
|
export declare function verifyApiKeyCached(plaintext: string, store: HippoStore, bound?: DerivationBound): Promise<VerifiedApiKey | null>;
|
|
91
95
|
export declare function revokeApiKey(db: DatabaseSyncLike, keyId: string, at?: string): void;
|
|
92
96
|
/** Grant `keyId` read access to one restricted `scope`. Idempotent. */
|
|
@@ -99,10 +103,8 @@ export interface ApiKeyListItem {
|
|
|
99
103
|
label: string | null;
|
|
100
104
|
createdAt: string;
|
|
101
105
|
revokedAt: string | null;
|
|
102
|
-
/**
|
|
103
|
-
*
|
|
104
|
-
* Fail-safe-to-member cast: any non-'admin' value reads as 'member'.
|
|
105
|
-
*/
|
|
106
|
+
/** Authorization role from the `role` column (schema migration v26).
|
|
107
|
+
* Fail-safe cast: any non-'admin' value reads as 'member'. */
|
|
106
108
|
role: 'admin' | 'member';
|
|
107
109
|
/** Restricted scopes this key may read. */
|
|
108
110
|
scopes: string[];
|
package/dist/store/auth.js
CHANGED
|
@@ -3,6 +3,7 @@ import { promisify } from 'node:util';
|
|
|
3
3
|
import { closeHippoDb, openHippoDb } from '../db/index.js';
|
|
4
4
|
import { raiseMinBinary } from '../db/meta.js';
|
|
5
5
|
import { keysetAfter } from '../util/keyset.js';
|
|
6
|
+
import { DAY_MS } from '../util/time.js';
|
|
6
7
|
import { EXPIRING_KEYS_MIN_BINARY } from '../util/version.js';
|
|
7
8
|
/** Every minted API key starts with this, so the server can route a bearer token by shape. */
|
|
8
9
|
export const API_KEY_PREFIX = 'hk_';
|
|
@@ -48,15 +49,16 @@ function verifyKey(plaintext, stored) {
|
|
|
48
49
|
return parsed.matches(scryptSync(plaintext, parsed.salt, parsed.keylen));
|
|
49
50
|
}
|
|
50
51
|
const scryptOffLoop = promisify(scrypt);
|
|
52
|
+
/** Days a key lives when its mint names no expiry, so a key nobody remembers stops working by itself. */
|
|
53
|
+
export const DEFAULT_KEY_TTL_DAYS = 90;
|
|
51
54
|
export function mintApiKey() {
|
|
52
55
|
const keyId = `${API_KEY_PREFIX}${randBase32(ID_LEN)}`;
|
|
53
56
|
const plaintext = `${keyId}.${randBase32(SECRET_LEN)}`;
|
|
54
57
|
return { keyId, plaintext, keyHash: hashKey(plaintext) };
|
|
55
58
|
}
|
|
56
59
|
export function insertApiKey(db, key) {
|
|
57
|
-
//
|
|
58
|
-
// so
|
|
59
|
-
// An older binary ignores expires_at and would honour an expired key, so the store shuts it out before the first one exists.
|
|
60
|
+
// Migration v26 (role column) has already run; an older binary ignores expires_at and would honour an expired key,
|
|
61
|
+
// so the store shuts it out before the first one exists.
|
|
60
62
|
if (key.expiresAt !== null)
|
|
61
63
|
raiseMinBinary(db, EXPIRING_KEYS_MIN_BINARY);
|
|
62
64
|
db.prepare(`INSERT INTO api_keys (key_id, key_hash, tenant_id, label, created_at, role, owner_subject, expires_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`).run(key.keyId, key.keyHash, key.tenantId, key.label, key.createdAt, key.role, key.ownerSubject, key.expiresAt);
|
|
@@ -64,16 +66,15 @@ export function insertApiKey(db, key) {
|
|
|
64
66
|
export function createApiKey(db, opts) {
|
|
65
67
|
const { keyId, plaintext, keyHash } = mintApiKey();
|
|
66
68
|
insertApiKey(db, {
|
|
67
|
-
keyId, keyHash, tenantId: opts.tenantId, label: opts.label ?? null, role: opts.role ?? '
|
|
68
|
-
ownerSubject: opts.ownerSubject ?? null, expiresAt: opts.expiresAt ??
|
|
69
|
+
keyId, keyHash, tenantId: opts.tenantId, label: opts.label ?? null, role: opts.role ?? 'member', createdAt: new Date().toISOString(),
|
|
70
|
+
ownerSubject: opts.ownerSubject ?? null, expiresAt: opts.expiresAt ?? new Date(Date.now() + DEFAULT_KEY_TTL_DAYS * DAY_MS).toISOString(),
|
|
69
71
|
});
|
|
70
72
|
return { keyId, plaintext };
|
|
71
73
|
}
|
|
72
74
|
/** The api_keys row for `keyId` with its scope grants; null when no row matches. */
|
|
73
75
|
export function readApiKeyRecord(db, keyId) {
|
|
74
|
-
// SAFETY: row comes from the SELECT above, which projects exactly
|
|
75
|
-
//
|
|
76
|
-
// row matches key_id.
|
|
76
|
+
// SAFETY: row comes from the SELECT above, which projects exactly key_hash, tenant_id, revoked_at, role, expires_at, owner_subject;
|
|
77
|
+
// `.get` returns undefined when no row matches key_id.
|
|
77
78
|
const row = db
|
|
78
79
|
.prepare(`SELECT key_hash, tenant_id, revoked_at, role, expires_at, owner_subject FROM api_keys WHERE key_id = ?`)
|
|
79
80
|
.get(keyId);
|
|
@@ -84,7 +85,8 @@ export function readApiKeyRecord(db, keyId) {
|
|
|
84
85
|
expiresAt: row.expires_at, ownerSubject: row.owner_subject,
|
|
85
86
|
};
|
|
86
87
|
}
|
|
87
|
-
/** When a key stops working, in epoch ms: Infinity for null, and already past for a missing
|
|
88
|
+
/** When a key stops working, in epoch ms: Infinity for null, and already past for a missing
|
|
89
|
+
* field (a store that predates expiry) or a stamp that does not parse, so both fail closed. */
|
|
88
90
|
function keyExpiryMs(expiresAt) {
|
|
89
91
|
if (expiresAt === null)
|
|
90
92
|
return Infinity;
|
|
@@ -130,7 +132,8 @@ const VERIFIED_KEY_CACHE_CAP = 1_000;
|
|
|
130
132
|
function secretDigest(plaintext) {
|
|
131
133
|
return createHash('sha256').update(plaintext).digest();
|
|
132
134
|
}
|
|
133
|
-
/** LRU of the tokens that matched a stored key hash, so a repeat skips scrypt. Holds
|
|
135
|
+
/** LRU of the tokens that matched a stored key hash, so a repeat skips scrypt. Holds
|
|
136
|
+
* a SHA-256 of the token, never the token, and nothing about the key's state. */
|
|
134
137
|
export class VerifiedKeyCache {
|
|
135
138
|
capacity;
|
|
136
139
|
// Keyed on the stored hash, so a rotated or re-minted key never meets an old entry; Map order makes the first key the least recent.
|
|
@@ -192,7 +195,8 @@ async function secretMatches(keyId, plaintext, keyHash, bound) {
|
|
|
192
195
|
void check.then(forget, forget);
|
|
193
196
|
return check;
|
|
194
197
|
}
|
|
195
|
-
/** Verify a bearer API key against `store`, null when invalid. The key's row is read on every
|
|
198
|
+
/** Verify a bearer API key against `store`, null when invalid. The key's row is read on every
|
|
199
|
+
* call, so a revoke, expiry, role or scope change by any process applies on the next one. */
|
|
196
200
|
export async function verifyApiKeyCached(plaintext, store, bound) {
|
|
197
201
|
const keyId = mintedKeyId(plaintext);
|
|
198
202
|
if (keyId === null)
|
|
@@ -250,7 +254,8 @@ export function listApiKeyRows(db, opts) {
|
|
|
250
254
|
const limitSql = opts.limit === undefined ? '' : ' LIMIT ?';
|
|
251
255
|
if (opts.limit !== undefined)
|
|
252
256
|
params.push(opts.limit);
|
|
253
|
-
const sql = `SELECT id, key_id, tenant_id, label, created_at, revoked_at, role, expires_at, owner_subject FROM api_keys
|
|
257
|
+
const sql = `SELECT id, key_id, tenant_id, label, created_at, revoked_at, role, expires_at, owner_subject FROM api_keys ` +
|
|
258
|
+
`WHERE ${where.join(' AND ')}${after.sql} ORDER BY id DESC${limitSql}`;
|
|
254
259
|
// SAFETY: the SELECT above projects exactly these 9 columns, in this order.
|
|
255
260
|
const rows = db.prepare(sql).all(...params);
|
|
256
261
|
return rows.map(r => ({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type MemoryEntry } from '../core/memory.js';
|
|
2
|
-
import { type SqlFragment } from './
|
|
1
|
+
import { type MemoryEntry, type ConfidenceLevel, Layer } from '../core/memory.js';
|
|
2
|
+
import { type SqlFragment } from './rule-sql.js';
|
|
3
3
|
export interface AmbientRecallRequest {
|
|
4
4
|
terms: string[];
|
|
5
5
|
limit: number;
|
|
@@ -32,12 +32,13 @@ export declare function loadContextCandidates(hippoRoot: string, tenantId: strin
|
|
|
32
32
|
export type HeldText = Pick<MemoryEntry, 'content' | 'source' | 'origin_project'>;
|
|
33
33
|
/** Admits every scope, for a reader that sees the whole store, such as the CLI on its own machine. */
|
|
34
34
|
export declare const EVERY_SCOPE: SqlFragment;
|
|
35
|
-
/**
|
|
36
|
-
*
|
|
35
|
+
/** Tenant rows holding any of `words` that `admit` passes (default: team-visible); a row equal to a text apart from spacing holds its every word.
|
|
36
|
+
* With `project`, only rows carrying one of those names plus user-global rows, as loadContextCandidates' filter. No `tenantId` reads every tenant. */
|
|
37
37
|
export declare function loadTextsHoldingWords(hippoRoot: string, tenantId: string | undefined, words: readonly string[], project?: readonly string[], admit?: SqlFragment): HeldText[];
|
|
38
38
|
/** A tenant's `limit` newest rows, oldest first: the tail of loadAllEntries' order, without reading the rows before it. */
|
|
39
39
|
export declare function loadNewestEntries(hippoRoot: string, tenantId: string, limit: number): MemoryEntry[];
|
|
40
|
-
/** computeSchemaFit against
|
|
40
|
+
/** computeSchemaFit against a tenant's newest SCHEMA_FIT_WINDOW_ROWS rows: tag counts come from one aggregate
|
|
41
|
+
* and texts stream one column, so no row is loaded. */
|
|
41
42
|
export declare function schemaFitInStore(hippoRoot: string, tenantId: string, content: string, tags: readonly string[]): number;
|
|
42
43
|
export interface SourceTally {
|
|
43
44
|
source: string;
|
|
@@ -61,4 +62,21 @@ export interface StrengthTallies {
|
|
|
61
62
|
}
|
|
62
63
|
/** calculateStrength over every row of a tenant in one aggregate pass, no row loaded. */
|
|
63
64
|
export declare function loadStrengthTallies(hippoRoot: string, tenantId: string, now: Date, atRiskBelow: number): StrengthTallies;
|
|
65
|
+
/** What `hippo status` prints about the whole store: every tenant and superseded rows too. */
|
|
66
|
+
export interface StatusCounts {
|
|
67
|
+
total: number;
|
|
68
|
+
byLayer: Record<Layer, number>;
|
|
69
|
+
byConfidence: Record<ConfidenceLevel, number>;
|
|
70
|
+
pinned: number;
|
|
71
|
+
/** Rows whose strength is under the caller's line; unlike StrengthTallies, pinned rows count. */
|
|
72
|
+
atRisk: number;
|
|
73
|
+
agedOut: number;
|
|
74
|
+
avgStrength: number;
|
|
75
|
+
/** Open conflicts of every tenant, the rows listMemoryConflicts returns when given no tenant. */
|
|
76
|
+
openConflicts: number;
|
|
77
|
+
/** Rows that have a stored vector. */
|
|
78
|
+
embedded: number;
|
|
79
|
+
}
|
|
80
|
+
/** The counts `hippo status` prints, from one pass over ten narrow columns: no text is read and no row array is built. */
|
|
81
|
+
export declare function loadStatusCounts(hippoRoot: string, now: Date, atRiskBelow: number): StatusCounts;
|
|
64
82
|
//# sourceMappingURL=candidates.d.ts.map
|
package/dist/store/candidates.js
CHANGED
|
@@ -1,45 +1,58 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { FALLBACK_HALF_LIFE_DAYS, Layer, calculateStrength, facetsOf, schemaFitFrom } from '../core/memory.js';
|
|
2
|
+
import { strengthSql } from './rule-sql.js';
|
|
3
|
+
import { withReadSnapshot } from '../db/index.js';
|
|
4
|
+
import { scopeAdmitSql } from './rule-sql.js';
|
|
4
5
|
import { MEMORY_SELECT_COLUMNS, rowToEntry, parseJsonArray } from './rows.js';
|
|
5
|
-
import { openStore } from './open.js';
|
|
6
|
+
import { onHandle, openStore } from './open.js';
|
|
6
7
|
import { originInSql } from '../core/project-identity.js';
|
|
7
8
|
import { pickRarestFtsQuery, loadRecallSearchEntriesFromDb } from './search-rows.js';
|
|
8
9
|
const AMBIENT_SCOPED = 'superseded_by IS NULL AND tenant_id = ?';
|
|
9
|
-
/** idx_memories_pinned (
|
|
10
|
+
/** idx_memories_pinned (migration v51) serves it. */
|
|
10
11
|
const AMBIENT_PINNED_WHERE = `pinned = 1 AND ${AMBIENT_SCOPED} ORDER BY created ASC, id ASC`;
|
|
11
|
-
/** idx_memories_created_drift (
|
|
12
|
+
/** idx_memories_created_drift (migration v51) serves it. */
|
|
12
13
|
const AMBIENT_DRIFT_SQL = `SELECT 1 FROM memories WHERE ${AMBIENT_SCOPED} AND (length(created) <> 24 OR created NOT LIKE '%Z') LIMIT 1`;
|
|
13
14
|
function inOrigins(e, origins) {
|
|
14
15
|
const origin = e.origin_project ?? null;
|
|
15
16
|
return origin === '' ? origins.userGlobal : origin !== null && origins.names.includes(origin);
|
|
16
17
|
}
|
|
18
|
+
// `id DESC` mirrors getContext's comparator, not loadFreshRawMemories'
|
|
19
|
+
// cross-ingest-stable order: that would change what the hook injects.
|
|
20
|
+
const NEWEST = 'ORDER BY created DESC, id DESC';
|
|
17
21
|
// The newest rows `admit` keeps, newest first. The first window stays unfiltered so admit still sees, and the
|
|
18
22
|
// delivery ledger still counts, the other-project rows it refuses; past it, the reads narrow to the caller's origins.
|
|
19
23
|
function loadRecentRows(run, drifted, tenantId, options) {
|
|
20
24
|
const { needed, admit, origins } = options;
|
|
21
25
|
const keep = origins ? (e) => admit(e) && inOrigins(e, origins) : admit;
|
|
22
|
-
// `id DESC` mirrors getContext's comparator, not loadFreshRawMemories'
|
|
23
|
-
// cross-ingest-stable order: that would change what the hook injects.
|
|
24
|
-
const newest = 'ORDER BY created DESC, id DESC';
|
|
25
26
|
const window = Math.max(needed * 4, 32);
|
|
26
27
|
const originSql = origins && (origins.userGlobal ? `(origin_project = '' OR ${originInSql(origins.names)})` : originInSql(origins.names));
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
if (
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
const own = { where: originSql ? `${AMBIENT_SCOPED} AND ${originSql}` : AMBIENT_SCOPED, params: [tenantId, ...(origins?.names ?? [])] };
|
|
29
|
+
// Text order is chronological only for standard UTC ISO (memory.ts), so a drifted store is read whole and re-sorted downstream.
|
|
30
|
+
if (drifted)
|
|
31
|
+
return run(`${own.where} ${NEWEST}`, [...own.params]).filter(keep);
|
|
32
|
+
let read = run(`${AMBIENT_SCOPED} ${NEWEST} LIMIT ?`, [tenantId, window]);
|
|
33
|
+
let kept = read.filter(keep);
|
|
34
|
+
if (kept.length >= needed || read.length < window)
|
|
35
|
+
return kept;
|
|
36
|
+
if (origins) {
|
|
37
|
+
read = run(`${own.where} ${NEWEST} LIMIT ?`, [...own.params, window]);
|
|
38
|
+
kept = read.filter(keep);
|
|
39
|
+
if (kept.length >= needed || read.length < window)
|
|
33
40
|
return kept;
|
|
34
|
-
if (origins) {
|
|
35
|
-
const ownWindow = run(`${ownWhere} ${newest} LIMIT ?`, [...ownParams, window]);
|
|
36
|
-
const ownKept = ownWindow.filter(keep);
|
|
37
|
-
if (ownKept.length >= needed || ownWindow.length < window)
|
|
38
|
-
return ownKept;
|
|
39
|
-
}
|
|
40
41
|
}
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
return [...kept, ...keptPastWindow(run, own, read, needed - kept.length, keep)];
|
|
43
|
+
}
|
|
44
|
+
// A window of refused rows can hide older ones, so read on in keyset pages, each four times the last, until enough are kept.
|
|
45
|
+
function keptPastWindow(run, own, read, wanted, keep) {
|
|
46
|
+
const out = [];
|
|
47
|
+
let last = read[read.length - 1];
|
|
48
|
+
for (let size = read.length * 4; out.length < wanted; size *= 4) {
|
|
49
|
+
const page = run(`${own.where} AND created <= ? AND (created < ? OR id < ?) ${NEWEST} LIMIT ?`, [...own.params, last.created, last.created, last.id, size]);
|
|
50
|
+
out.push(...page.filter(keep));
|
|
51
|
+
if (page.length < size)
|
|
52
|
+
break;
|
|
53
|
+
last = page[page.length - 1];
|
|
54
|
+
}
|
|
55
|
+
return out;
|
|
43
56
|
}
|
|
44
57
|
// The pins plus the `recentNeeded` newest rows that pass `admit`, for ambient injection. One connection;
|
|
45
58
|
// `recall` piggybacks the prompt-recall FTS query on it too. `origins` narrows the recent rows past the first window.
|
|
@@ -47,8 +60,7 @@ export function loadAmbientCandidates(hippoRoot, tenantId, recentNeeded, admit,
|
|
|
47
60
|
// A SQL LIMIT takes an integer; the Array.slice this replaced truncated one,
|
|
48
61
|
// and include_recent is any non-negative finite number at the HTTP edge.
|
|
49
62
|
const needed = Math.trunc(recentNeeded);
|
|
50
|
-
|
|
51
|
-
try {
|
|
63
|
+
return onHandle(hippoRoot, (db) => {
|
|
52
64
|
// SAFETY: every `where` below starts from MEMORY_SELECT_COLUMNS' table.
|
|
53
65
|
const run = (where, params) => db.prepare(`SELECT ${MEMORY_SELECT_COLUMNS} FROM memories WHERE ${where}`).all(...params).map(rowToEntry);
|
|
54
66
|
const byId = new Map();
|
|
@@ -74,10 +86,7 @@ export function loadAmbientCandidates(hippoRoot, tenantId, recentNeeded, admit,
|
|
|
74
86
|
? loadRecallSearchEntriesFromDb(db, ftsQuery, { limit: recall.limit, tenantId, includeSuperseded: false, ownScope: recall.ownScope })
|
|
75
87
|
: [];
|
|
76
88
|
return { entries, recall: recallEntries };
|
|
77
|
-
}
|
|
78
|
-
finally {
|
|
79
|
-
closeHippoDb(db);
|
|
80
|
-
}
|
|
89
|
+
}, openStore);
|
|
81
90
|
}
|
|
82
91
|
// calculateStrength's decay exponent with its reward factor, pins first: the strongest rows, without scoring each one in JS.
|
|
83
92
|
const DECAY_RANK_SQL = `pinned DESC,
|
|
@@ -102,70 +111,62 @@ export function loadContextCandidates(hippoRoot, tenantId, filter) {
|
|
|
102
111
|
where.push(`(origin_project = '' OR ${originInSql(filter.project)})`);
|
|
103
112
|
params.push(...filter.project);
|
|
104
113
|
}
|
|
105
|
-
|
|
106
|
-
try {
|
|
114
|
+
return onHandle(hippoRoot, (db) => {
|
|
107
115
|
// SAFETY: the outer SELECT names exactly MEMORY_SELECT_COLUMNS, matching MemoryRow's field set; the rank sort carries ids only.
|
|
108
116
|
const rows = db.prepare(`SELECT ${MEMORY_SELECT_COLUMNS} FROM memories WHERE id IN (
|
|
109
117
|
SELECT id FROM memories WHERE ${where.join(' AND ')} ORDER BY ${DECAY_RANK_SQL} LIMIT ?
|
|
110
118
|
) ORDER BY created ASC, id ASC`).all(...params, filter.now.toISOString(), Math.max(0, Math.trunc(filter.cap)));
|
|
111
119
|
return rows.map(rowToEntry);
|
|
112
|
-
}
|
|
113
|
-
finally {
|
|
114
|
-
closeHippoDb(db);
|
|
115
|
-
}
|
|
120
|
+
}, openStore);
|
|
116
121
|
}
|
|
117
122
|
// No owner: for session capture, a personal or connector-private row must never stop a team copy being written.
|
|
118
123
|
const TEAM_VISIBLE = scopeAdmitSql('');
|
|
119
124
|
/** Admits every scope, for a reader that sees the whole store, such as the CLI on its own machine. */
|
|
120
125
|
export const EVERY_SCOPE = Object.freeze({ sql: '1', params: [] });
|
|
121
|
-
/**
|
|
122
|
-
*
|
|
126
|
+
/** Tenant rows holding any of `words` that `admit` passes (default: team-visible); a row equal to a text apart from spacing holds its every word.
|
|
127
|
+
* With `project`, only rows carrying one of those names plus user-global rows, as loadContextCandidates' filter. No `tenantId` reads every tenant. */
|
|
123
128
|
export function loadTextsHoldingWords(hippoRoot, tenantId, words, project, admit = TEAM_VISIBLE) {
|
|
124
129
|
const unique = [...new Set(words)];
|
|
125
130
|
const out = [];
|
|
126
131
|
const tenantWhere = tenantId === undefined ? '1' : 'tenant_id = ?';
|
|
127
132
|
const tenantParams = tenantId === undefined ? [] : [tenantId];
|
|
128
133
|
const originWhere = project === undefined ? '' : ` AND (origin_project = '' OR ${originInSql(project)})`;
|
|
129
|
-
|
|
130
|
-
try {
|
|
134
|
+
return onHandle(hippoRoot, (db) => {
|
|
131
135
|
// Chunked so one statement stays far under SQLite's bound-parameter limit.
|
|
132
136
|
for (let i = 0; i < unique.length; i += 200) {
|
|
133
137
|
const chunk = unique.slice(i, i + 200);
|
|
134
138
|
// SAFETY: rows' shape matches the three columns named in the SELECT below.
|
|
135
|
-
const rows = db.prepare(`SELECT content, source, origin_project FROM memories WHERE ${tenantWhere}${originWhere} AND ${admit.sql} AND (${chunk.map(() => 'instr(content, ?)
|
|
139
|
+
const rows = db.prepare(`SELECT content, source, origin_project FROM memories WHERE ${tenantWhere}${originWhere} AND ${admit.sql} AND (${chunk.map(() => 'instr(content, ?) ' +
|
|
140
|
+
'> 0').join(' OR ')})`).all(...tenantParams, ...(project ?? []), ...admit.params, ...chunk);
|
|
136
141
|
for (const row of rows)
|
|
137
142
|
out.push({ content: row.content, source: row.source ?? 'cli', origin_project: row.origin_project });
|
|
138
143
|
}
|
|
139
144
|
return out;
|
|
140
|
-
}
|
|
141
|
-
finally {
|
|
142
|
-
closeHippoDb(db);
|
|
143
|
-
}
|
|
145
|
+
}, openStore);
|
|
144
146
|
}
|
|
145
147
|
/** A tenant's `limit` newest rows, oldest first: the tail of loadAllEntries' order, without reading the rows before it. */
|
|
146
148
|
export function loadNewestEntries(hippoRoot, tenantId, limit) {
|
|
147
|
-
|
|
148
|
-
try {
|
|
149
|
+
return onHandle(hippoRoot, (db) => {
|
|
149
150
|
// SAFETY: the SELECT names exactly MEMORY_SELECT_COLUMNS, matching MemoryRow's field set.
|
|
150
151
|
const rows = db.prepare(`SELECT ${MEMORY_SELECT_COLUMNS} FROM memories WHERE tenant_id = ? ORDER BY created DESC, id DESC LIMIT ?`).all(tenantId, limit);
|
|
151
152
|
return rows.reverse().map(rowToEntry);
|
|
152
|
-
}
|
|
153
|
-
finally {
|
|
154
|
-
closeHippoDb(db);
|
|
155
|
-
}
|
|
153
|
+
}, openStore);
|
|
156
154
|
}
|
|
157
155
|
function* contentsOf(rows) {
|
|
158
156
|
for (const row of rows)
|
|
159
157
|
yield row.content;
|
|
160
158
|
}
|
|
161
|
-
/**
|
|
159
|
+
/** How many of a tenant's newest rows schemaFitInStore reads; older rows no longer move the fit. */
|
|
160
|
+
const SCHEMA_FIT_WINDOW_ROWS = 2000;
|
|
161
|
+
/** computeSchemaFit against a tenant's newest SCHEMA_FIT_WINDOW_ROWS rows: tag counts come from one aggregate
|
|
162
|
+
* and texts stream one column, so no row is loaded. */
|
|
162
163
|
export function schemaFitInStore(hippoRoot, tenantId, content, tags) {
|
|
163
|
-
const
|
|
164
|
-
|
|
164
|
+
const newest = 'SELECT tags_json, content FROM memories WHERE tenant_id = ? ORDER BY created DESC, id DESC LIMIT ?';
|
|
165
|
+
return onHandle(hippoRoot, (db) => {
|
|
165
166
|
// One read transaction, so the row count and the texts come from the same snapshot.
|
|
166
167
|
return withReadSnapshot(db, () => {
|
|
167
168
|
// SAFETY: rows' shape matches the two columns named in the SELECT.
|
|
168
|
-
const groups = db.prepare(
|
|
169
|
+
const groups = db.prepare(`SELECT tags_json, COUNT(*) AS n FROM (${newest}) GROUP BY tags_json`).all(tenantId, SCHEMA_FIT_WINDOW_ROWS);
|
|
169
170
|
let rows = 0;
|
|
170
171
|
const tagCounts = new Map();
|
|
171
172
|
for (const group of groups) {
|
|
@@ -173,28 +174,23 @@ export function schemaFitInStore(hippoRoot, tenantId, content, tags) {
|
|
|
173
174
|
for (const tag of parseJsonArray(group.tags_json))
|
|
174
175
|
tagCounts.set(tag, (tagCounts.get(tag) ?? 0) + group.n);
|
|
175
176
|
}
|
|
176
|
-
// SHORTCUT: the
|
|
177
|
+
// SHORTCUT: only the newest SCHEMA_FIT_WINDOW_ROWS rows count, so older tags drop out;
|
|
178
|
+
// a stored per-tenant tag and token tally is the upgrade.
|
|
177
179
|
// SAFETY: the SELECT names exactly the one column read.
|
|
178
|
-
const texts = db.prepare(
|
|
180
|
+
const texts = db.prepare(`SELECT content FROM (${newest})`)
|
|
181
|
+
.iterate(tenantId, SCHEMA_FIT_WINDOW_ROWS);
|
|
179
182
|
return schemaFitFrom(content, tags, { rows, tagCounts, contents: contentsOf(texts) });
|
|
180
183
|
});
|
|
181
|
-
}
|
|
182
|
-
finally {
|
|
183
|
-
closeHippoDb(db);
|
|
184
|
-
}
|
|
184
|
+
}, openStore);
|
|
185
185
|
}
|
|
186
186
|
/** Row count and newest `created` per source, for peer listings that need no row; all tenants when `tenantId` is absent. */
|
|
187
187
|
export function tallySources(hippoRoot, tenantId) {
|
|
188
|
-
|
|
189
|
-
try {
|
|
188
|
+
return onHandle(hippoRoot, (db) => {
|
|
190
189
|
const where = tenantId !== undefined ? 'WHERE tenant_id = ?' : '';
|
|
191
190
|
// SAFETY: rows' shape matches the four aliased columns in the SELECT below.
|
|
192
191
|
return db.prepare(`SELECT COALESCE(source, 'cli') AS source, COUNT(*) AS count, MAX(created) AS latest, MIN(created || char(31) || id) AS first
|
|
193
192
|
FROM memories ${where} GROUP BY COALESCE(source, 'cli')`).all(...(tenantId !== undefined ? [tenantId] : []));
|
|
194
|
-
}
|
|
195
|
-
finally {
|
|
196
|
-
closeHippoDb(db);
|
|
197
|
-
}
|
|
193
|
+
}, openStore);
|
|
198
194
|
}
|
|
199
195
|
// A malformed or non-array JSON list reads as empty, as parseJsonArray does, instead of failing json_each.
|
|
200
196
|
export const jsonList = (column) => `(CASE WHEN json_valid(${column}) AND json_type(${column}) = 'array' THEN ${column} ELSE '[]' END)`;
|
|
@@ -202,8 +198,7 @@ export const jsonList = (column) => `(CASE WHEN json_valid(${column}) AND json_t
|
|
|
202
198
|
export function loadStrengthTallies(hippoRoot, tenantId, now, atRiskBelow) {
|
|
203
199
|
// An unparseable date scores NULL in SQL and 0 in calculateStrength.
|
|
204
200
|
const strength = `COALESCE(${strengthSql(now)}, 0)`;
|
|
205
|
-
|
|
206
|
-
try {
|
|
201
|
+
return onHandle(hippoRoot, (db) => {
|
|
207
202
|
// SAFETY: one aggregate row whose columns are the aliases named below.
|
|
208
203
|
const row = db.prepare(`SELECT
|
|
209
204
|
COUNT(*) AS total,
|
|
@@ -219,9 +214,62 @@ export function loadStrengthTallies(hippoRoot, tenantId, now, atRiskBelow) {
|
|
|
219
214
|
strengthSum: Number(row.strengthSum),
|
|
220
215
|
atRisk: Number(row.atRisk),
|
|
221
216
|
};
|
|
217
|
+
}, openStore);
|
|
218
|
+
}
|
|
219
|
+
// What calculateStrength and facetsOf read, plus the layer: no text and no JSON column.
|
|
220
|
+
const STATUS_ROW_COLUMNS = [
|
|
221
|
+
'layer', 'confidence', 'pinned', 'created', 'last_retrieved', 'half_life_days', 'retrieval_count',
|
|
222
|
+
'emotional_valence', 'outcome_positive', 'outcome_negative',
|
|
223
|
+
];
|
|
224
|
+
// Scored in JavaScript, not with strengthSql: SQLite reads fewer date shapes than Date does, so its counts would differ.
|
|
225
|
+
function tallyStatusRows(rows, now, atRiskBelow) {
|
|
226
|
+
const byLayer = { [Layer.Buffer]: 0, [Layer.Episodic]: 0, [Layer.Semantic]: 0, [Layer.Trace]: 0 };
|
|
227
|
+
const byConfidence = { verified: 0, observed: 0, inferred: 0, stale: 0 };
|
|
228
|
+
const sums = { total: 0, strength: 0, pinned: 0, atRisk: 0, agedOut: 0 };
|
|
229
|
+
for (const row of rows) {
|
|
230
|
+
// rowToEntry's defaults for these columns, so a row scores as its loaded entry would.
|
|
231
|
+
const entry = {
|
|
232
|
+
pinned: Boolean(row.pinned),
|
|
233
|
+
confidence: row.confidence ?? 'observed',
|
|
234
|
+
created: row.created,
|
|
235
|
+
last_retrieved: row.last_retrieved,
|
|
236
|
+
half_life_days: Number(row.half_life_days ?? FALLBACK_HALF_LIFE_DAYS),
|
|
237
|
+
retrieval_count: Number(row.retrieval_count ?? 0),
|
|
238
|
+
emotional_valence: row.emotional_valence ?? 'neutral',
|
|
239
|
+
outcome_positive: Number(row.outcome_positive ?? 0),
|
|
240
|
+
outcome_negative: Number(row.outcome_negative ?? 0),
|
|
241
|
+
};
|
|
242
|
+
const strength = calculateStrength(entry, now);
|
|
243
|
+
const facets = facetsOf(entry, now);
|
|
244
|
+
sums.total++;
|
|
245
|
+
sums.strength += strength;
|
|
246
|
+
byLayer[row.layer] = (byLayer[row.layer] ?? 0) + 1;
|
|
247
|
+
byConfidence[facets.tier] = (byConfidence[facets.tier] ?? 0) + 1;
|
|
248
|
+
if (entry.pinned)
|
|
249
|
+
sums.pinned++;
|
|
250
|
+
if (strength < atRiskBelow)
|
|
251
|
+
sums.atRisk++;
|
|
252
|
+
if (facets.agedOut)
|
|
253
|
+
sums.agedOut++;
|
|
222
254
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
255
|
+
const { total, pinned, atRisk, agedOut } = sums;
|
|
256
|
+
return { total, byLayer, byConfidence, pinned, atRisk, agedOut, avgStrength: total > 0 ? sums.strength / total : 0 };
|
|
257
|
+
}
|
|
258
|
+
/** The counts `hippo status` prints, from one pass over ten narrow columns: no text is read and no row array is built. */
|
|
259
|
+
export function loadStatusCounts(hippoRoot, now, atRiskBelow) {
|
|
260
|
+
return onHandle(hippoRoot, (db) => {
|
|
261
|
+
// One read transaction, so the row tallies and the two counts describe the same store.
|
|
262
|
+
return withReadSnapshot(db, () => {
|
|
263
|
+
// loadAllEntries' order, so the strengths add up in the order they did and the average rounds the same.
|
|
264
|
+
// SAFETY: the SELECT names exactly StatusRow's columns, and the store writes `layer` only from the Layer enum.
|
|
265
|
+
const rows = db.prepare(`SELECT ${STATUS_ROW_COLUMNS.join(', ')} FROM memories ORDER BY created ASC, id ASC`).iterate();
|
|
266
|
+
const tallies = tallyStatusRows(rows, now, atRiskBelow);
|
|
267
|
+
// SAFETY: one row whose columns are the two aliases named below.
|
|
268
|
+
const counts = db.prepare(`SELECT
|
|
269
|
+
(SELECT COUNT(*) FROM memory_conflicts WHERE status = 'open') AS openConflicts,
|
|
270
|
+
(SELECT COUNT(*) FROM memory_vectors WHERE memory_id IN (SELECT id FROM memories)) AS embedded`).get();
|
|
271
|
+
return { ...tallies, openConflicts: Number(counts.openConflicts), embedded: Number(counts.embedded) };
|
|
272
|
+
});
|
|
273
|
+
}, openStore);
|
|
226
274
|
}
|
|
227
275
|
//# sourceMappingURL=candidates.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { MemoryEntry } from '../core/memory.js';
|
|
2
|
+
export type CapturedOutcome = 'captured' | 'skipped' | 'rejected';
|
|
3
|
+
export interface CaptureItem {
|
|
4
|
+
readonly content: string;
|
|
5
|
+
/** Built only for an item that is not a repeat of an earlier one, since building can throw. */
|
|
6
|
+
readonly makeEntry: () => MemoryEntry;
|
|
7
|
+
}
|
|
8
|
+
export interface CaptureWriteOpts {
|
|
9
|
+
readonly actor?: string;
|
|
10
|
+
/** No stats, as in a server process. */
|
|
11
|
+
readonly lean: boolean;
|
|
12
|
+
/** Called with each captured entry after its write, so the caller can embed it; the store never picks a provider. */
|
|
13
|
+
readonly onCaptured?: (entry: MemoryEntry) => void;
|
|
14
|
+
}
|
|
15
|
+
/** One outcome per item, in order. `keys` holds the texts already stored and gains each one written, so a repeat inside the batch is skipped. */
|
|
16
|
+
export declare function writeCapturedItems(hippoRoot: string, items: readonly CaptureItem[], keys: Set<string>, opts: CaptureWriteOpts): CapturedOutcome[];
|
|
17
|
+
//# sourceMappingURL=capture-write.d.ts.map
|