hippo-memory 1.71.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 +1 -1
- package/dist/agent-memories/apply.d.ts +0 -11
- package/dist/agent-memories/apply.js +6 -21
- package/dist/agent-memories/claude-code.js +1 -1
- 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/project-folds.d.ts +10 -0
- package/dist/agent-memories/project-folds.js +34 -0
- package/dist/agent-memories/sync.js +8 -6
- package/dist/api/assemble.js +1 -1
- package/dist/api/audit.d.ts +29 -1
- package/dist/api/audit.js +44 -5
- package/dist/api/auth.d.ts +7 -4
- package/dist/api/auth.js +12 -8
- package/dist/api/auto-sleep.d.ts +5 -2
- package/dist/api/auto-sleep.js +7 -3
- package/dist/api/availability.js +2 -3
- 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 +9 -11
- package/dist/api/context.js +17 -8
- package/dist/api/continuity.d.ts +47 -0
- package/dist/api/continuity.js +66 -0
- package/dist/api/dormant.js +4 -2
- package/dist/api/drill-down.js +1 -1
- 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 +6 -2
- package/dist/api/forget.js +18 -7
- package/dist/api/goals.d.ts +1 -1
- package/dist/api/goals.js +5 -9
- package/dist/api/index.d.ts +4 -2
- package/dist/api/index.js +4 -2
- package/dist/api/instruction-detect.js +5 -1
- package/dist/api/learn.d.ts +4 -0
- package/dist/api/learn.js +53 -27
- package/dist/api/ledger-db.d.ts +2 -6
- package/dist/api/ledger-db.js +4 -36
- package/dist/api/memories.d.ts +19 -1
- package/dist/api/memories.js +39 -0
- package/dist/api/objects.d.ts +1 -1
- 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 +3 -1
- package/dist/api/predictions.js +6 -0
- package/dist/api/projects.d.ts +21 -0
- package/dist/api/projects.js +24 -0
- package/dist/api/promote.js +1 -1
- package/dist/api/prompt-hook.d.ts +15 -2
- package/dist/api/prompt-hook.js +44 -4
- package/dist/api/recall-cli.d.ts +3 -0
- package/dist/api/recall-cli.js +13 -4
- package/dist/api/recall-core.js +3 -3
- package/dist/api/recall-pipeline.js +6 -7
- package/dist/api/recall-request.js +1 -1
- package/dist/api/recall.d.ts +0 -3
- package/dist/api/recall.js +19 -44
- package/dist/api/remember-local.js +1 -1
- package/dist/api/remember.d.ts +2 -1
- package/dist/api/remember.js +3 -2
- package/dist/api/session-end.d.ts +22 -0
- package/dist/api/session-end.js +101 -0
- package/dist/api/sleep-run.d.ts +1 -1
- package/dist/api/sleep-run.js +13 -9
- 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.js +1 -1
- package/dist/api/types.d.ts +2 -0
- package/dist/api/types.js +6 -1
- 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.js +36 -95
- package/dist/capture/compact.js +10 -5
- package/dist/capture/compaction-items-caller.js +11 -20
- package/dist/capture/compaction-record.d.ts +7 -93
- package/dist/capture/compaction-record.js +29 -426
- package/dist/capture/compaction-spool.d.ts +4 -2
- package/dist/capture/compaction-spool.js +20 -6
- 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.js +4 -3
- package/dist/capture/session-end-caller.js +2 -1
- package/dist/capture/session-worker.js +3 -4
- package/dist/capture/transcript.d.ts +2 -1
- package/dist/capture/transcript.js +6 -3
- package/dist/capture/working-state.d.ts +4 -2
- package/dist/capture/working-state.js +4 -2
- package/dist/cli/audit-prune.d.ts +0 -25
- package/dist/cli/audit-prune.js +1 -27
- package/dist/cli/audit.js +13 -13
- package/dist/cli/auth.d.ts +1 -1
- package/dist/cli/auth.js +12 -13
- package/dist/cli/briefs.d.ts +1 -4
- package/dist/cli/briefs.js +37 -292
- package/dist/cli/card.js +41 -33
- package/dist/cli/client.d.ts +5 -0
- package/dist/cli/client.js +24 -8
- package/dist/cli/compact-resume-payload.js +1 -1
- package/dist/cli/context.d.ts +1 -1
- package/dist/cli/context.js +12 -12
- package/dist/cli/continuity.d.ts +1 -1
- package/dist/cli/continuity.js +36 -39
- package/dist/cli/curate.d.ts +1 -1
- package/dist/cli/curate.js +23 -27
- package/dist/cli/dag.d.ts +1 -1
- package/dist/cli/dag.js +23 -8
- package/dist/cli/decisions.d.ts +0 -2
- package/dist/cli/decisions.js +4 -281
- package/dist/cli/eval.d.ts +1 -1
- package/dist/cli/eval.js +12 -13
- package/dist/cli/explain.d.ts +1 -1
- package/dist/cli/explain.js +21 -25
- package/dist/cli/flag-values.js +16 -6
- package/dist/cli/flags.d.ts +0 -289
- package/dist/cli/flags.js +3 -138
- package/dist/cli/graph.d.ts +3 -0
- package/dist/cli/graph.js +83 -0
- package/dist/cli/hook-runtime.d.ts +3 -5
- package/dist/cli/hook-runtime.js +7 -34
- package/dist/cli/incidents.d.ts +3 -0
- package/dist/cli/incidents.js +112 -0
- package/dist/cli/init.d.ts +1 -1
- package/dist/cli/init.js +28 -19
- package/dist/cli/install-steps.d.ts +2 -1
- package/dist/cli/install-steps.js +11 -3
- package/dist/cli/last-sleep.js +1 -1
- package/dist/cli/lenient-id.d.ts +2 -0
- package/dist/cli/lenient-id.js +13 -0
- package/dist/cli/maintenance.d.ts +3 -3
- package/dist/cli/maintenance.js +29 -30
- package/dist/cli/notes.d.ts +2 -0
- package/dist/cli/notes.js +41 -0
- package/dist/cli/open-browser.d.ts +14 -0
- package/dist/cli/open-browser.js +26 -0
- package/dist/cli/playbooks.d.ts +3 -4
- package/dist/cli/playbooks.js +126 -290
- package/dist/cli/predictions.d.ts +3 -0
- package/dist/cli/predictions.js +175 -0
- package/dist/cli/print.js +2 -1
- package/dist/cli/projects.js +30 -22
- package/dist/cli/quality-repair-once.d.ts +1 -1
- package/dist/cli/quality-repair-once.js +6 -5
- package/dist/cli/recall.js +13 -7
- package/dist/cli/refine-llm.js +17 -17
- package/dist/cli/remember.js +12 -12
- package/dist/cli/scheduler.js +2 -1
- package/dist/cli/serve.js +3 -3
- package/dist/cli/session-hooks.d.ts +1 -1
- package/dist/cli/session-hooks.js +45 -115
- package/dist/cli/setup.d.ts +1 -1
- package/dist/cli/setup.js +17 -10
- package/dist/cli/shared.d.ts +2 -6
- package/dist/cli/shared.js +9 -29
- package/dist/cli/sleep-render.js +6 -3
- package/dist/cli/sleep.js +6 -37
- package/dist/cli/status.d.ts +3 -3
- package/dist/cli/status.js +32 -35
- package/dist/cli/transfer.d.ts +1 -1
- package/dist/cli/transfer.js +33 -31
- package/dist/cli/usage.d.ts +0 -79
- package/dist/cli/usage.js +1 -695
- 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 -272
- package/dist/cli.js +23 -313
- package/dist/connectors/dlq.d.ts +39 -3
- package/dist/connectors/dlq.js +37 -3
- package/dist/connectors/github/backfill.js +12 -3
- package/dist/connectors/github/dlq.js +31 -73
- package/dist/connectors/github/ingest.d.ts +2 -6
- package/dist/connectors/github/ingest.js +3 -28
- package/dist/connectors/github/webhook.d.ts +2 -1
- package/dist/connectors/github/webhook.js +33 -2
- package/dist/connectors/ingest.d.ts +10 -0
- package/dist/connectors/ingest.js +28 -0
- package/dist/connectors/slack/dlq.js +49 -71
- package/dist/connectors/slack/ingest.d.ts +2 -6
- package/dist/connectors/slack/ingest.js +2 -27
- package/dist/connectors/slack/webhook.d.ts +2 -1
- package/dist/connectors/slack/webhook.js +2 -1
- package/dist/consolidate/conflicts.js +1 -1
- package/dist/consolidate/dag.js +15 -9
- package/dist/consolidate/dedupe.d.ts +7 -0
- package/dist/consolidate/dedupe.js +5 -3
- package/dist/consolidate/llm-passes.js +45 -19
- package/dist/consolidate/memory-value.js +2 -1
- package/dist/consolidate/merge.js +2 -2
- package/dist/consolidate/physics-pass.d.ts +6 -1
- package/dist/consolidate/physics-pass.js +26 -6
- package/dist/consolidate/replay.js +11 -4
- package/dist/consolidate/sleep.js +8 -5
- package/dist/consolidate/traces.js +3 -3
- package/dist/core/ablation.d.ts +10 -0
- package/dist/core/ablation.js +12 -0
- package/dist/{sharing/scope.d.ts → core/active-scope.d.ts} +1 -1
- package/dist/{sharing/scope.js → core/active-scope.js} +1 -1
- package/dist/core/ambient.d.ts +4 -0
- package/dist/core/ambient.js +39 -18
- package/dist/core/api-errors.d.ts +16 -0
- package/dist/core/api-errors.js +20 -0
- package/dist/core/card.js +3 -1
- package/dist/core/compaction-timing.d.ts +7 -0
- package/dist/core/compaction-timing.js +9 -0
- package/dist/core/config.d.ts +1 -1
- package/dist/core/config.js +7 -2
- package/dist/core/cosine.d.ts +3 -0
- package/dist/core/cosine.js +19 -0
- package/dist/{store → core}/markdown.d.ts +1 -1
- package/dist/{store → core}/markdown.js +2 -2
- package/dist/core/memory-audit.d.ts +17 -0
- package/dist/core/memory-audit.js +54 -0
- package/dist/core/memory.d.ts +10 -4
- package/dist/core/memory.js +25 -18
- package/dist/{consolidate → core}/merged-row.d.ts +1 -1
- package/dist/{consolidate → core}/merged-row.js +1 -1
- package/dist/core/physics.js +6 -16
- package/dist/core/prediction.d.ts +3 -0
- package/dist/core/prediction.js +6 -0
- package/dist/core/project-identity.d.ts +3 -0
- package/dist/core/project-identity.js +10 -1
- package/dist/{store → core}/recall-scope.d.ts +1 -10
- package/dist/{store → core}/recall-scope.js +2 -19
- package/dist/db/busy.d.ts +2 -7
- package/dist/db/busy.js +21 -26
- package/dist/db/connect.d.ts +0 -1
- package/dist/db/connect.js +5 -6
- package/dist/db/index.d.ts +3 -3
- package/dist/db/index.js +3 -3
- package/dist/db/migrations/index.d.ts +1 -1
- package/dist/db/migrations/index.js +3 -1
- package/dist/db/migrations/v55.d.ts +3 -0
- package/dist/db/migrations/v55.js +17 -0
- package/dist/db/open.d.ts +0 -2
- package/dist/db/open.js +6 -10
- package/dist/db/physics-state.js +3 -3
- package/dist/db/tables.d.ts +2 -0
- package/dist/db/tables.js +6 -2
- package/dist/db/vector-store.js +17 -4
- package/dist/db/wal-checkpointer.js +2 -1
- package/dist/doctor.js +11 -8
- package/dist/embeddings/local.d.ts +62 -0
- package/dist/embeddings/local.js +146 -0
- package/dist/{store/embeddings → embeddings}/provider.d.ts +5 -2
- package/dist/{store/embeddings → embeddings}/provider.js +18 -15
- 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 +1 -1
- package/dist/eval/eval-suite.js +17 -11
- package/dist/eval/eval.js +1 -1
- package/dist/eval/judgment.js +11 -4
- package/dist/graph/extract.js +3 -3
- package/dist/graph/recall.js +1 -1
- package/dist/graph/view.js +13 -5
- 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 +2 -1
- package/dist/hooks/json-hooks.js +4 -2
- package/dist/hooks/opencode.js +8 -5
- package/dist/hooks/shared.d.ts +0 -6
- package/dist/hooks/shared.js +4 -15
- package/dist/importers/core.js +1 -1
- package/dist/importers/sources.js +5 -4
- package/dist/importers/vault.js +7 -5
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3 -2
- package/dist/learn/autolearn.d.ts +10 -2
- package/dist/learn/autolearn.js +32 -12
- package/dist/learn/churn-git.js +13 -4
- package/dist/learn/extract.d.ts +3 -2
- package/dist/learn/extract.js +6 -4
- package/dist/learn/forward-claim-detector.js +4 -2
- package/dist/learn/invalidation.js +10 -6
- package/dist/mcp/admin-tools.d.ts +2 -2
- package/dist/mcp/admin-tools.js +27 -48
- 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 +3 -1
- package/dist/mcp/protocol.d.ts +11 -7
- package/dist/mcp/protocol.js +25 -12
- package/dist/mcp/recall-tools.js +12 -9
- package/dist/mcp/request.js +2 -1
- package/dist/mcp/stdio.js +24 -8
- package/dist/mcp/tool-args.js +2 -1
- package/dist/mcp/tools.js +44 -21
- package/dist/objects/customer-notes.d.ts +2 -2
- package/dist/objects/decisions.d.ts +2 -2
- package/dist/objects/descriptor.d.ts +1 -1
- package/dist/objects/incidents.d.ts +2 -2
- package/dist/objects/lifecycle.d.ts +1 -1
- package/dist/objects/lifecycle.js +2 -1
- package/dist/objects/policies.d.ts +2 -2
- package/dist/objects/policies.js +2 -1
- package/dist/objects/processes.d.ts +2 -2
- package/dist/objects/project-briefs.d.ts +2 -2
- package/dist/objects/project-briefs.js +2 -3
- package/dist/objects/skills.d.ts +2 -2
- package/dist/postinstall.js +1 -1
- package/dist/rerankers/clef.js +3 -6
- package/dist/rerankers/cross-encoder.d.ts +31 -2
- package/dist/rerankers/cross-encoder.js +63 -97
- package/dist/rerankers/index.js +5 -4
- package/dist/rerankers/jev.js +2 -4
- package/dist/rerankers/outage-warning.d.ts +3 -1
- package/dist/rerankers/outage-warning.js +5 -3
- package/dist/search/bm25-search.js +1 -1
- package/dist/search/boosts.js +1 -1
- package/dist/search/embed-memories.d.ts +9 -0
- package/dist/search/embed-memories.js +377 -0
- package/dist/search/goal-boost.d.ts +1 -1
- package/dist/search/goal-boost.js +6 -3
- package/dist/search/hybrid.d.ts +9 -2
- package/dist/search/hybrid.js +9 -4
- package/dist/search/physics-search.d.ts +6 -3
- package/dist/search/physics-search.js +22 -15
- package/dist/search/rerank.js +1 -1
- package/dist/search/vector.d.ts +8 -6
- package/dist/search/vector.js +10 -13
- package/dist/server/auth.d.ts +2 -0
- package/dist/server/auth.js +17 -7
- package/dist/server/boot.js +7 -66
- package/dist/server/client-ip.d.ts +0 -2
- package/dist/server/client-ip.js +3 -2
- package/dist/server/deadline.d.ts +0 -2
- package/dist/server/deadline.js +1 -7
- package/dist/server/defaults.d.ts +1 -0
- package/dist/server/defaults.js +1 -0
- package/dist/server/mcp-http.js +16 -11
- package/dist/server/request.js +7 -2
- 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 -132
- package/dist/server/routes/admin.d.ts +8 -8
- package/dist/server/routes/admin.js +13 -21
- package/dist/server/routes/customer-notes.d.ts +6 -6
- package/dist/server/routes/customer-notes.js +1 -2
- package/dist/server/routes/decisions.d.ts +6 -6
- package/dist/server/routes/decisions.js +2 -4
- package/dist/server/routes/incidents.d.ts +6 -6
- package/dist/server/routes/incidents.js +2 -5
- package/dist/server/routes/memories.d.ts +9 -9
- package/dist/server/routes/memories.js +15 -38
- package/dist/server/routes/object-routes.d.ts +6 -6
- package/dist/server/routes/object-routes.js +4 -7
- package/dist/server/routes/policies.d.ts +7 -7
- package/dist/server/routes/policies.js +2 -4
- package/dist/server/routes/predictions.d.ts +6 -6
- package/dist/server/routes/predictions.js +9 -13
- package/dist/server/routes/processes.d.ts +6 -6
- package/dist/server/routes/processes.js +1 -2
- package/dist/server/routes/project-briefs.d.ts +7 -7
- package/dist/server/routes/project-briefs.js +2 -4
- package/dist/server/routes/recall.d.ts +5 -5
- package/dist/server/routes/recall.js +6 -10
- package/dist/server/routes/skills.d.ts +7 -7
- package/dist/server/routes/skills.js +2 -4
- package/dist/server/server-detect.d.ts +7 -1
- package/dist/server/server-detect.js +36 -11
- package/dist/server/sleep-child.js +26 -7
- package/dist/server/sleep-offload.d.ts +11 -5
- package/dist/server/sleep-offload.js +17 -11
- package/dist/server/types.d.ts +22 -10
- package/dist/server/validation.d.ts +1 -2
- package/dist/server/validation.js +6 -11
- package/dist/server.d.ts +5 -4
- package/dist/server.js +5 -4
- package/dist/sharing/global-store.js +2 -2
- package/dist/sharing/global-sync.js +38 -45
- package/dist/sharing/project-merge.d.ts +7 -14
- package/dist/sharing/project-merge.js +57 -121
- package/dist/sharing/search-both.js +1 -1
- package/dist/sharing/share.d.ts +2 -0
- package/dist/sharing/share.js +37 -34
- package/dist/store/ambient.js +5 -6
- package/dist/store/audit-event.d.ts +1 -1
- package/dist/store/audit.d.ts +0 -16
- package/dist/store/audit.js +4 -55
- package/dist/store/auth.d.ts +4 -2
- package/dist/store/auth.js +7 -3
- package/dist/store/candidates.d.ts +3 -2
- package/dist/store/candidates.js +42 -23
- package/dist/store/capture-write.d.ts +17 -0
- package/dist/store/capture-write.js +35 -0
- package/dist/store/cards.js +1 -1
- 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.js +7 -4
- package/dist/store/connectors/dlq.d.ts +10 -0
- package/dist/store/connectors/dlq.js +32 -0
- package/dist/store/connectors/github.d.ts +7 -9
- package/dist/store/connectors/github.js +30 -53
- package/dist/store/connectors/slack.d.ts +2 -11
- package/dist/store/connectors/slack.js +18 -47
- package/dist/store/dashboard-reads.js +7 -6
- package/dist/store/delete-and-batch.d.ts +6 -0
- package/dist/store/delete-and-batch.js +36 -3
- package/dist/store/delivery-recorder.d.ts +10 -3
- package/dist/store/delivery-recorder.js +12 -5
- package/dist/store/descendant-page.js +6 -3
- package/dist/store/dormant.d.ts +1 -1
- package/dist/store/dormant.js +3 -1
- package/dist/store/embeddings/index.d.ts +2 -12
- package/dist/store/embeddings/index.js +5 -374
- package/dist/store/entry-reads.d.ts +13 -4
- package/dist/store/entry-reads.js +47 -11
- package/dist/store/entry-writes.d.ts +5 -5
- package/dist/store/entry-writes.js +32 -12
- 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.js +20 -18
- package/dist/store/graph-reads.js +4 -2
- package/dist/store/graph-writes.d.ts +6 -6
- package/dist/store/graph-writes.js +48 -71
- package/dist/store/handoffs.d.ts +1 -1
- package/dist/store/handoffs.js +6 -6
- package/dist/store/index-and-stats.js +2 -2
- 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.js +10 -6
- package/dist/store/open.d.ts +0 -4
- package/dist/store/open.js +40 -53
- package/dist/store/pilot-arm.d.ts +12 -0
- package/dist/store/pilot-arm.js +42 -0
- package/dist/store/port.d.ts +9 -3
- package/dist/store/port.js +8 -0
- package/dist/store/predictions.d.ts +1 -2
- package/dist/store/predictions.js +3 -6
- package/dist/store/project-tags.d.ts +62 -0
- package/dist/store/project-tags.js +67 -0
- package/dist/store/quarantine.js +2 -1
- package/dist/store/recall-trace.d.ts +2 -0
- package/dist/store/recall-trace.js +18 -2
- package/dist/store/rejected-values.js +2 -1
- package/dist/store/rejection-probe.d.ts +4 -0
- package/dist/store/rejection-probe.js +19 -0
- package/dist/store/rejection.d.ts +0 -17
- package/dist/store/rejection.js +1 -21
- package/dist/store/rule-sql.d.ts +9 -0
- package/dist/store/rule-sql.js +21 -2
- package/dist/store/search-rows.js +9 -4
- package/dist/store/sessions.js +4 -2
- 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 +4 -7
- package/dist/store/sqlite/connector-writes-group.js +3 -3
- package/dist/store/sqlite/entry-writes-group.js +2 -2
- package/dist/store/sqlite/error-codec.js +4 -3
- package/dist/store/sqlite/executor.js +10 -4
- 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/object-rows.d.ts +1 -1
- package/dist/store/sqlite/objects-group.d.ts +1 -1
- package/dist/store/sqlite/objects-group.js +1 -1
- package/dist/store/sqlite/store.js +14 -12
- package/dist/store/summaries.d.ts +3 -3
- package/dist/store/summaries.js +5 -4
- package/dist/store/token-ledger.d.ts +0 -7
- package/dist/store/token-ledger.js +0 -35
- package/dist/store/vector-index.js +3 -2
- package/dist/support-bundle.js +2 -3
- package/dist/trust/reject-flow.js +2 -2
- 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 +22 -5
- package/dist/util/chunked.d.ts +3 -0
- package/dist/util/chunked.js +10 -0
- package/dist/util/ellipsize.d.ts +3 -0
- package/dist/util/ellipsize.js +5 -0
- package/dist/util/env.d.ts +2 -1
- package/dist/util/env.js +2 -1
- package/dist/util/format.d.ts +3 -0
- package/dist/util/format.js +6 -0
- package/dist/util/hook-payload.d.ts +8 -0
- package/dist/util/hook-payload.js +37 -0
- package/dist/util/http-retry.d.ts +6 -0
- package/dist/util/http-retry.js +43 -5
- 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 +4 -0
- package/dist/util/log.js +9 -0
- package/dist/util/request-scope.d.ts +3 -1
- package/dist/util/request-scope.js +11 -6
- package/dist/util/secret-detect.js +6 -1
- package/dist/util/sqlite-blocked.d.ts +2 -0
- package/dist/util/sqlite-blocked.js +5 -0
- 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/version.d.ts +1 -1
- package/dist/util/version.js +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/store/embeddings/local.d.ts +0 -15
- package/dist/store/embeddings/local.js +0 -175
- /package/dist/{cli → api}/correction-latency.d.ts +0 -0
- /package/dist/{cli → api}/correction-latency.js +0 -0
- /package/dist/{cli → api}/provenance-coverage.d.ts +0 -0
- /package/dist/{cli → api}/provenance-coverage.js +0 -0
- /package/dist/{store → core}/object-types.d.ts +0 -0
- /package/dist/{store → core}/object-types.js +0 -0
- /package/dist/{capture → util}/compaction-items.d.ts +0 -0
- /package/dist/{capture → util}/compaction-items.js +0 -0
- /package/dist/{store → util}/yaml.d.ts +0 -0
- /package/dist/{store → util}/yaml.js +0 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// The memory-quality audit rules: pure functions of a row, so any store can be audited by them.
|
|
2
|
+
import { canAutoDelete } from './memory.js';
|
|
3
|
+
import { automaticDefect, hasNoSpecificity, isFragment, isReleaseCommitNoise, substantiveWordCount, } from './memory-quality.js';
|
|
4
|
+
export function auditMemory(entry, backsObject = false) {
|
|
5
|
+
const issue = classifyMemory(entry);
|
|
6
|
+
// Error means "auto-remove"; a pinned, raw, kept-for-good or object-backing row is never auto-removed, so it can only warn.
|
|
7
|
+
if (issue?.severity === 'error' && (!canAutoDelete(entry) || backsObject)) {
|
|
8
|
+
const why = entry.pinned ? 'pinned' : entry.kind === 'raw' ? 'raw' : backsObject ? 'backs an object' : 'keep rule';
|
|
9
|
+
return { ...issue, severity: 'warning', reason: `${issue.reason} (${why}, kept)` };
|
|
10
|
+
}
|
|
11
|
+
return issue;
|
|
12
|
+
}
|
|
13
|
+
function classifyMemory(entry) {
|
|
14
|
+
const content = entry.content.trim();
|
|
15
|
+
if (content.length < 3) {
|
|
16
|
+
return { memoryId: entry.id, content, severity: 'error', reason: 'too short (< 3 chars)' };
|
|
17
|
+
}
|
|
18
|
+
if (content.length < 10) {
|
|
19
|
+
return { memoryId: entry.id, content, severity: 'error', reason: 'too short (< 10 chars)' };
|
|
20
|
+
}
|
|
21
|
+
if (isReleaseCommitNoise(content)) {
|
|
22
|
+
return { memoryId: entry.id, content, severity: 'error', reason: 'release/commit noise, not a useful memory' };
|
|
23
|
+
}
|
|
24
|
+
if (isFragment(content)) {
|
|
25
|
+
return { memoryId: entry.id, content, severity: 'warning', reason: 'sentence fragment — lacks context' };
|
|
26
|
+
}
|
|
27
|
+
const substantive = substantiveWordCount(content);
|
|
28
|
+
if (substantive < 2) {
|
|
29
|
+
return { memoryId: entry.id, content, severity: 'warning', reason: `only ${substantive} substantive word(s) — too vague` };
|
|
30
|
+
}
|
|
31
|
+
if (content.length < 40 && hasNoSpecificity(content)) {
|
|
32
|
+
return { memoryId: entry.id, content, severity: 'warning', reason: 'no specific details (names, paths, numbers, code)' };
|
|
33
|
+
}
|
|
34
|
+
const reason = automaticDefect(entry);
|
|
35
|
+
if (reason !== null) {
|
|
36
|
+
return { memoryId: entry.id, content, severity: 'warning', reason: `automatic memory defect: ${reason}` };
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
/** `backing`: ids of memories that back an object (store.memoriesBackingObjects). */
|
|
41
|
+
export function auditMemories(entries, backing) {
|
|
42
|
+
const issues = [];
|
|
43
|
+
for (const entry of entries) {
|
|
44
|
+
const issue = auditMemory(entry, backing.has(entry.id));
|
|
45
|
+
if (issue)
|
|
46
|
+
issues.push(issue);
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
total: entries.length,
|
|
50
|
+
issues,
|
|
51
|
+
clean: entries.length - issues.length,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=memory-audit.js.map
|
package/dist/core/memory.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/** Core data model for Hippo memory entries, based on the strength formula from PLAN.md. */
|
|
2
|
+
import { type StrengthAblation } from './ablation.js';
|
|
2
3
|
export declare const DEFAULT_SCHEMA_FIT = 0.5;
|
|
3
4
|
export declare const FALLBACK_HALF_LIFE_DAYS = 7;
|
|
4
5
|
export declare enum Layer {
|
|
@@ -10,7 +11,8 @@ export declare enum Layer {
|
|
|
10
11
|
export type EmotionalValence = 'neutral' | 'positive' | 'negative' | 'critical';
|
|
11
12
|
export type ConfidenceLevel = 'verified' | 'observed' | 'inferred' | 'stale';
|
|
12
13
|
export type TraceOutcome = 'success' | 'failure' | 'partial' | null;
|
|
13
|
-
export
|
|
14
|
+
export declare const MEMORY_KINDS: readonly ["raw", "distilled", "superseded", "archived"];
|
|
15
|
+
export type MemoryKind = (typeof MEMORY_KINDS)[number];
|
|
14
16
|
export interface MemoryEntry {
|
|
15
17
|
id: string;
|
|
16
18
|
created: string;
|
|
@@ -75,14 +77,14 @@ export declare function _resetLossAversionRatioCacheForTests(): void;
|
|
|
75
77
|
/** Scales only the `negative` multiplier; `critical` stays unscaled so the knob moves just the losses-vs-gains claim. */
|
|
76
78
|
export declare function applyLossAversionRatio(valence: EmotionalValence, baseMultiplier: number): number;
|
|
77
79
|
/** 1 + REWARD_SLOPE * (pos - neg) / (pos + neg + 1), in (0.5, 1.5), 1.0 with no outcomes; it scales the effective half-life. */
|
|
78
|
-
export declare function calculateRewardFactor(entry: Pick<MemoryEntry, 'outcome_positive' | 'outcome_negative'
|
|
80
|
+
export declare function calculateRewardFactor(entry: Pick<MemoryEntry, 'outcome_positive' | 'outcome_negative'>, ablation?: StrengthAblation): number;
|
|
79
81
|
/** Bad marks alone never push a memory under sleep's 0.05 retire line; supersede is the hard correction. */
|
|
80
82
|
export declare const MAX_WRONG_HALVINGS = 3;
|
|
81
83
|
export declare const DECAY_BASE = 0.5;
|
|
82
84
|
export declare const REWARD_SLOPE = 0.5;
|
|
83
85
|
export declare const RETRIEVAL_BOOST_SLOPE = 0.1;
|
|
84
86
|
/** Bad outcome marks past good ones, floored at zero; each halves strength and stops recall strengthening, so a correction outranks pinning. */
|
|
85
|
-
export declare function netWrong(entry: Pick<MemoryEntry, 'outcome_positive' | 'outcome_negative'
|
|
87
|
+
export declare function netWrong(entry: Pick<MemoryEntry, 'outcome_positive' | 'outcome_negative'>, ablation?: StrengthAblation): number;
|
|
86
88
|
/** What calculateStrength reads, so a caller can score a row without loading its text. */
|
|
87
89
|
export type StrengthInputs = Pick<MemoryEntry, 'pinned' | 'created' | 'last_retrieved' | 'half_life_days' | 'retrieval_count' | 'emotional_valence' | 'outcome_positive' | 'outcome_negative'>;
|
|
88
90
|
/** Decay basis: clock = wall time, session = per sleep cycle (intermittent agents), adaptive = half-life scaled by session frequency. */
|
|
@@ -92,6 +94,8 @@ export interface DecayOptions {
|
|
|
92
94
|
avgSessionIntervalDays?: number;
|
|
93
95
|
/** Total sleep cycles completed. Used by consolidation tracking. */
|
|
94
96
|
sleepCount?: number;
|
|
97
|
+
/** EVAL-ONLY switches resolved once at the entry layer (`strengthAblation()`); absent means production scoring. */
|
|
98
|
+
ablation?: StrengthAblation;
|
|
95
99
|
}
|
|
96
100
|
/** Strength at `now` = decay * retrieval boost * emotional multiplier, clamped to [0, 1]; the basis modes are on DecayOptions.
|
|
97
101
|
* Pinned memories skip time decay, but being marked wrong still fades them (netWrong). */
|
|
@@ -167,6 +171,8 @@ export declare function createSuccessor(old: MemoryEntry, content: string, opts:
|
|
|
167
171
|
/** How well new content fits existing knowledge, 0..1: above 0.7 consolidates faster, below 0.3 is novel and decays faster if unused.
|
|
168
172
|
* Tags shared with existing memories count by rarity (a rare shared tag fits more), plus content-token overlap. */
|
|
169
173
|
export declare function computeSchemaFit(content: string, tags: string[], existingEntries: MemoryEntry[]): number;
|
|
174
|
+
/** What schema fit reads from `entries`, built once for a caller that scores many contents against the same rows. */
|
|
175
|
+
export declare function schemaFitSourceOf(entries: readonly MemoryEntry[]): SchemaFitSource;
|
|
170
176
|
/** What schema fit reads from a set of memories, so a store can answer without loading its rows. */
|
|
171
177
|
export interface SchemaFitSource {
|
|
172
178
|
readonly rows: number;
|
|
@@ -179,5 +185,5 @@ export interface SchemaFitSource {
|
|
|
179
185
|
export declare function schemaFitFrom(content: string, tags: readonly string[], source: SchemaFitSource): number;
|
|
180
186
|
/** Returns copies with the retrieval count, clock and half-life updated; the caller persists them.
|
|
181
187
|
* Under HIPPO_ABLATE_RECALL_BOOST (eval-only) the entries come back unchanged, not empty, since callers derive last_retrieval_ids from them. */
|
|
182
|
-
export declare function markRetrieved(entries: MemoryEntry[], now?: Date): MemoryEntry[];
|
|
188
|
+
export declare function markRetrieved(entries: MemoryEntry[], now?: Date, options?: Pick<DecayOptions, 'ablation'>): MemoryEntry[];
|
|
183
189
|
//# sourceMappingURL=memory.d.ts.map
|
package/dist/core/memory.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { DEFAULT_TENANT_ID, envLossAversionRatio } from '../util/env.js';
|
|
3
3
|
import { BadRequestError } from './api-errors.js';
|
|
4
4
|
import { randomUUID } from 'crypto';
|
|
5
|
-
import {
|
|
5
|
+
import { evalNow, NO_STRENGTH_ABLATION } from './ablation.js';
|
|
6
6
|
import { AGENT_MEMORY_TOOLS, toolSourcePrefix } from './agent-memory-tools.js';
|
|
7
7
|
import { isJsonString } from '../util/json.js';
|
|
8
8
|
import { DAY_MS } from '../util/time.js';
|
|
@@ -16,6 +16,7 @@ export var Layer;
|
|
|
16
16
|
Layer["Semantic"] = "semantic";
|
|
17
17
|
Layer["Trace"] = "trace";
|
|
18
18
|
})(Layer || (Layer = {}));
|
|
19
|
+
export const MEMORY_KINDS = ['raw', 'distilled', 'superseded', 'archived'];
|
|
19
20
|
/** Tag on a memory whose named file/symbol/script changed after it was stored. */
|
|
20
21
|
export const CHURN_STALE_TAG = 'churn-stale';
|
|
21
22
|
// Losses weigh ~2x gains (Lovallo-Kahneman), so negative is 2.0; HIPPO_LOSS_AVERSION_RATIO scales it per process.
|
|
@@ -57,9 +58,9 @@ export function applyLossAversionRatio(valence, baseMultiplier) {
|
|
|
57
58
|
return baseMultiplier * getLossAversionRatio();
|
|
58
59
|
}
|
|
59
60
|
/** 1 + REWARD_SLOPE * (pos - neg) / (pos + neg + 1), in (0.5, 1.5), 1.0 with no outcomes; it scales the effective half-life. */
|
|
60
|
-
export function calculateRewardFactor(entry) {
|
|
61
|
+
export function calculateRewardFactor(entry, ablation = NO_STRENGTH_ABLATION) {
|
|
61
62
|
// EVAL-ONLY ablation (see ablation.ts): the slow outcome channel.
|
|
62
|
-
if (
|
|
63
|
+
if (ablation.outcomeSlow)
|
|
63
64
|
return 1.0;
|
|
64
65
|
const pos = entry.outcome_positive ?? 0;
|
|
65
66
|
const neg = entry.outcome_negative ?? 0;
|
|
@@ -75,8 +76,8 @@ export const DECAY_BASE = 0.5;
|
|
|
75
76
|
export const REWARD_SLOPE = 0.5;
|
|
76
77
|
export const RETRIEVAL_BOOST_SLOPE = 0.1;
|
|
77
78
|
/** Bad outcome marks past good ones, floored at zero; each halves strength and stops recall strengthening, so a correction outranks pinning. */
|
|
78
|
-
export function netWrong(entry) {
|
|
79
|
-
if (
|
|
79
|
+
export function netWrong(entry, ablation = NO_STRENGTH_ABLATION) {
|
|
80
|
+
if (ablation.outcomeSlow || ablation.decay)
|
|
80
81
|
return 0;
|
|
81
82
|
return Math.max(0, (entry.outcome_negative ?? 0) - (entry.outcome_positive ?? 0));
|
|
82
83
|
}
|
|
@@ -85,22 +86,23 @@ export function netWrong(entry) {
|
|
|
85
86
|
export function calculateStrength(entry,
|
|
86
87
|
// evalNow() is the real clock unless HIPPO_FAKE_NOW is set (eval-only); an explicit `now` wins.
|
|
87
88
|
now = evalNow(), options = {}) {
|
|
89
|
+
const ablation = options.ablation ?? NO_STRENGTH_ABLATION;
|
|
88
90
|
// Being marked wrong outranks every shield: pinning, error tags, heavy recall.
|
|
89
|
-
const wrongPenalty = Math.pow(DECAY_BASE, Math.min(netWrong(entry), MAX_WRONG_HALVINGS));
|
|
91
|
+
const wrongPenalty = Math.pow(DECAY_BASE, Math.min(netWrong(entry, ablation), MAX_WRONG_HALVINGS));
|
|
90
92
|
if (entry.pinned)
|
|
91
93
|
return wrongPenalty;
|
|
92
94
|
// EVAL-ONLY ablation (see ablation.ts): anchor decay at creation so clock resets from earlier unflagged runs cannot leak in.
|
|
93
|
-
const lastRetrieved = new Date(
|
|
95
|
+
const lastRetrieved = new Date(ablation.recallBoost ? entry.created : entry.last_retrieved);
|
|
94
96
|
const daysSince = (now.getTime() - lastRetrieved.getTime()) / DAY_MS;
|
|
95
|
-
const rewardFactor = calculateRewardFactor(entry);
|
|
97
|
+
const rewardFactor = calculateRewardFactor(entry, ablation);
|
|
96
98
|
const effectiveHalfLife = entry.half_life_days * rewardFactor;
|
|
97
99
|
// Guard: zero half-life causes 0/0 = NaN in the exponent
|
|
98
100
|
if (effectiveHalfLife <= 0)
|
|
99
101
|
return 0.0;
|
|
100
102
|
const decayExponent = decayExponentFor(options, daysSince, effectiveHalfLife);
|
|
101
103
|
// EVAL-ONLY ablation (see ablation.ts): decay := 1, so the [0,1] clamp below caps the boost at baseline.
|
|
102
|
-
const decay =
|
|
103
|
-
const retrievalBoost = retrievalBoostFor(entry);
|
|
104
|
+
const decay = ablation.decay ? 1.0 : Math.pow(DECAY_BASE, decayExponent);
|
|
105
|
+
const retrievalBoost = retrievalBoostFor(entry, ablation);
|
|
104
106
|
const baseMultiplier = EMOTIONAL_MULTIPLIERS[entry.emotional_valence] ?? 1.0;
|
|
105
107
|
const emotionalMultiplier = applyLossAversionRatio(entry.emotional_valence, baseMultiplier);
|
|
106
108
|
const raw = decay * retrievalBoost * emotionalMultiplier;
|
|
@@ -127,8 +129,8 @@ function decayExponentFor(options, daysSince, halfLifeDays) {
|
|
|
127
129
|
return daysSince / effectiveHalfLife;
|
|
128
130
|
}
|
|
129
131
|
// EVAL-ONLY ablation (see ablation.ts) neutralizes the read side too, so counts written before the flag cannot leak in.
|
|
130
|
-
function retrievalBoostFor(entry) {
|
|
131
|
-
return
|
|
132
|
+
function retrievalBoostFor(entry, ablation) {
|
|
133
|
+
return ablation.recallBoost || netWrong(entry, ablation) > 0
|
|
132
134
|
? 1.0
|
|
133
135
|
: 1 + RETRIEVAL_BOOST_SLOPE * Math.log2(entry.retrieval_count + 1);
|
|
134
136
|
}
|
|
@@ -296,13 +298,17 @@ export function createSuccessor(old, content, opts) {
|
|
|
296
298
|
/** How well new content fits existing knowledge, 0..1: above 0.7 consolidates faster, below 0.3 is novel and decays faster if unused.
|
|
297
299
|
* Tags shared with existing memories count by rarity (a rare shared tag fits more), plus content-token overlap. */
|
|
298
300
|
export function computeSchemaFit(content, tags, existingEntries) {
|
|
301
|
+
return schemaFitFrom(content, tags, schemaFitSourceOf(existingEntries));
|
|
302
|
+
}
|
|
303
|
+
/** What schema fit reads from `entries`, built once for a caller that scores many contents against the same rows. */
|
|
304
|
+
export function schemaFitSourceOf(entries) {
|
|
299
305
|
const tagCounts = new Map();
|
|
300
|
-
for (const entry of
|
|
306
|
+
for (const entry of entries) {
|
|
301
307
|
for (const tag of entry.tags) {
|
|
302
308
|
tagCounts.set(tag, (tagCounts.get(tag) ?? 0) + 1);
|
|
303
309
|
}
|
|
304
310
|
}
|
|
305
|
-
return
|
|
311
|
+
return { rows: entries.length, tagCounts, contents: entries.map((e) => e.content) };
|
|
306
312
|
}
|
|
307
313
|
function significantTokens(text) {
|
|
308
314
|
return new Set(text.toLowerCase().replace(/[^\w\s]/g, ' ').split(/\s+/).filter((t) => t.length > 3));
|
|
@@ -358,13 +364,14 @@ function inferValence(tags) {
|
|
|
358
364
|
}
|
|
359
365
|
/** Returns copies with the retrieval count, clock and half-life updated; the caller persists them.
|
|
360
366
|
* Under HIPPO_ABLATE_RECALL_BOOST (eval-only) the entries come back unchanged, not empty, since callers derive last_retrieval_ids from them. */
|
|
361
|
-
export function markRetrieved(entries, now = evalNow()) {
|
|
362
|
-
|
|
367
|
+
export function markRetrieved(entries, now = evalNow(), options = {}) {
|
|
368
|
+
const ablation = options.ablation ?? NO_STRENGTH_ABLATION;
|
|
369
|
+
if (ablation.recallBoost)
|
|
363
370
|
return entries;
|
|
364
371
|
return entries.map((e) => {
|
|
365
372
|
if (e.superseded_by)
|
|
366
373
|
return e;
|
|
367
|
-
const wrong = netWrong(e) > 0;
|
|
374
|
+
const wrong = netWrong(e, ablation) > 0;
|
|
368
375
|
// Confidence stays untouched: it is an epistemic tier, not a recency signal.
|
|
369
376
|
const updated = {
|
|
370
377
|
...e,
|
|
@@ -373,7 +380,7 @@ export function markRetrieved(entries, now = evalNow()) {
|
|
|
373
380
|
last_retrieved: wrong ? e.last_retrieved : now.toISOString(),
|
|
374
381
|
half_life_days: wrong ? e.half_life_days : e.half_life_days + RETRIEVAL_HALF_LIFE_GAIN_DAYS,
|
|
375
382
|
};
|
|
376
|
-
updated.strength = calculateStrength(updated, now);
|
|
383
|
+
updated.strength = calculateStrength(updated, now, { ablation });
|
|
377
384
|
return updated;
|
|
378
385
|
});
|
|
379
386
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type MemoryEntry } from '
|
|
1
|
+
import { type MemoryEntry } from './memory.js';
|
|
2
2
|
/** The row that replaces a merged row once its retired texts leave: undefined when it holds none, null when nothing else is left. */
|
|
3
3
|
export declare function mergedSuccessor(row: MemoryEntry, retired: (text: string) => boolean, retiredIds: ReadonlySet<string>): MemoryEntry | null | undefined;
|
|
4
4
|
/** Sleep's check on a merged row: drops texts whose source was superseded since the merge, or that a rejection now covers. */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// A sleep-merged row copies its sources' texts, so retiring a text (reject, or superseding its source) must reach the row too.
|
|
2
2
|
// SHORTCUT: reject rewrites merged rows at once, live and dormant; supersede and `resolve
|
|
3
3
|
// --reject-loser` wait for the next sleep's check, which sees a dormant row only once restored.
|
|
4
|
-
import { generateId } from '
|
|
4
|
+
import { generateId } from './memory.js';
|
|
5
5
|
import { duplicateKey, heldTexts, mergedText } from '../util/same-text.js';
|
|
6
6
|
/** The row that replaces a merged row once its retired texts leave: undefined when it holds none, null when nothing else is left. */
|
|
7
7
|
export function mergedSuccessor(row, retired, retiredIds) {
|
package/dist/core/physics.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/** Memory-as-Physics engine: pure math (forces, Velocity Verlet integration, physics-based scoring, cluster amplification), no I/O.
|
|
2
2
|
* Memories are particles on the unit hypersphere in embedding space (384-dim); query gravity, attraction, conflict repulsion and drag act on them,
|
|
3
3
|
* and nearby high-scoring memories amplify each other. */
|
|
4
|
+
import { cosineOf } from './cosine.js';
|
|
4
5
|
import { isRecallBoostAblated } from './ablation.js';
|
|
5
6
|
import { FALLBACK_HALF_LIFE_DAYS } from './memory.js';
|
|
6
7
|
import { comparePhysicsResultsBy } from './compare.js';
|
|
@@ -48,17 +49,6 @@ export function vecClampMagnitude(v, maxMag) {
|
|
|
48
49
|
return v;
|
|
49
50
|
return vecScale(v, maxMag / mag);
|
|
50
51
|
}
|
|
51
|
-
/** Cosine similarity between two vectors. */
|
|
52
|
-
function cosine(a, b) {
|
|
53
|
-
if (a.length === 0 || b.length === 0 || a.length !== b.length)
|
|
54
|
-
return 0;
|
|
55
|
-
const dot = vecDot(a, b);
|
|
56
|
-
const na = vecNorm(a);
|
|
57
|
-
const nb = vecNorm(b);
|
|
58
|
-
if (na < 1e-10 || nb < 1e-10)
|
|
59
|
-
return 0;
|
|
60
|
-
return Math.min(1, Math.max(-1, dot / (na * nb)));
|
|
61
|
-
}
|
|
62
52
|
const CHARGE_MAP = {
|
|
63
53
|
neutral: 0,
|
|
64
54
|
positive: 0.3,
|
|
@@ -79,7 +69,7 @@ export function computeTemperature(ageDays, temperatureDecay) {
|
|
|
79
69
|
}
|
|
80
70
|
/** Query gravity (retrieval-time, virtual: does not move the particle): scalar ranking magnitude F = G_Q * mass * max(0, cosine(pos, query))^2. */
|
|
81
71
|
export function queryGravityMagnitude(particle, queryEmbedding, G_query) {
|
|
82
|
-
const cos =
|
|
72
|
+
const cos = cosineOf(particle.position, queryEmbedding);
|
|
83
73
|
return G_query * particle.mass * Math.pow(Math.max(0, cos), 2);
|
|
84
74
|
}
|
|
85
75
|
/** Momentum bonus in [0, 1]: how aligned the particle's velocity is with the query direction. */
|
|
@@ -96,7 +86,7 @@ export function velocityAlignmentBonus(particle, queryEmbedding) {
|
|
|
96
86
|
/** Attraction force on particle i from j (consolidation-time): G_M m_i m_j max(0, cosine)^3, directed along (pos_j - pos_i) projected tangent to the unit
|
|
97
87
|
* sphere at pos_i (positions are re-normalized to the sphere after integration). Adds into `out` (a fresh zero vector by default) using `diff` as scratch. */
|
|
98
88
|
export function attractionForce(pi, pj, G_memory, out = vecZero(pi.position.length), diff = vecZero(pi.position.length)) {
|
|
99
|
-
const cos =
|
|
89
|
+
const cos = cosineOf(pi.position, pj.position);
|
|
100
90
|
if (cos <= 0)
|
|
101
91
|
return out;
|
|
102
92
|
const magnitude = G_memory * pi.mass * pj.mass * Math.pow(cos, 3);
|
|
@@ -113,7 +103,7 @@ export function attractionForce(pi, pj, G_memory, out = vecZero(pi.position.leng
|
|
|
113
103
|
}
|
|
114
104
|
/** Conflict repulsion on i away from j (consolidation-time): K_R * m_i * m_j / max(0.01, cosine_distance)^2, where cosine_distance = 1 - cosine_similarity. */
|
|
115
105
|
export function repulsionForce(pi, pj, K_repulsion) {
|
|
116
|
-
const cos =
|
|
106
|
+
const cos = cosineOf(pi.position, pj.position);
|
|
117
107
|
const dist = Math.max(0.01, 1 - cos);
|
|
118
108
|
const magnitude = K_repulsion * pi.mass * pj.mass / (dist * dist);
|
|
119
109
|
// Direction: away from j
|
|
@@ -237,7 +227,7 @@ export function computeSystemEnergy(particles, G_memory) {
|
|
|
237
227
|
}
|
|
238
228
|
for (let i = 0; i < particles.length; i++) {
|
|
239
229
|
for (let j = i + 1; j < particles.length; j++) {
|
|
240
|
-
const cos =
|
|
230
|
+
const cos = cosineOf(particles[i].position, particles[j].position);
|
|
241
231
|
potential -= G_memory * particles[i].mass * particles[j].mass * Math.max(0, cos);
|
|
242
232
|
}
|
|
243
233
|
}
|
|
@@ -292,7 +282,7 @@ function applyClusterAmplification(results, particles, config) {
|
|
|
292
282
|
const pj = particleMap.get(top[j].memoryId);
|
|
293
283
|
if (!pj)
|
|
294
284
|
continue;
|
|
295
|
-
const proximity =
|
|
285
|
+
const proximity = cosineOf(pi.position, pj.position);
|
|
296
286
|
if (proximity > config.cluster_threshold) {
|
|
297
287
|
clusterSignal += top[j].baseScore * proximity;
|
|
298
288
|
}
|
|
@@ -27,6 +27,9 @@ export declare function resolveProjectIdentity(cwd?: string, opts?: ResolveProje
|
|
|
27
27
|
/** Nearest ancestor `.hippo` below home and the temp root (never projects; on Windows the temp root sits inside home).
|
|
28
28
|
* Everything is realpath'd so a symlinked temp root or cwd still matches its bound. */
|
|
29
29
|
export declare function findHippoStoreDir(cwd?: string, opts?: ResolveProjectIdentityOpts): string | null;
|
|
30
|
+
/** Nearest ancestor store like git; the strict join is the fallback so `hippo init` still creates `<cwd>/.hippo`. */
|
|
31
|
+
export declare function getHippoRoot(cwd?: string, opts?: ResolveProjectIdentityOpts): string;
|
|
32
|
+
export declare function isInitialized(hippoRoot: string): boolean;
|
|
30
33
|
/** A reader's project: a bare name, or an identity whose own rows may also carry its legacy folder name. */
|
|
31
34
|
export type ProjectRef = string | Pick<ProjectIdentity, 'name' | 'legacyName' | 'aliases'>;
|
|
32
35
|
/** The id a reader's new rows are stamped with; '' outside a project. */
|
|
@@ -4,7 +4,7 @@ import * as os from 'os';
|
|
|
4
4
|
import * as path from 'path';
|
|
5
5
|
import { BadRequestError } from './api-errors.js';
|
|
6
6
|
import { isSharedStore, loadConfig } from './config.js';
|
|
7
|
-
import { MAX_ID_LEN } from '../util/
|
|
7
|
+
import { MAX_ID_LEN } from '../util/limits.js';
|
|
8
8
|
import { errorMessage, log } from '../util/log.js';
|
|
9
9
|
import { originRemoteId, projectFileId } from './project-remote.js';
|
|
10
10
|
import { realpathOrResolve } from '../util/real-path.js';
|
|
@@ -154,6 +154,15 @@ export function findHippoStoreDir(cwd, opts) {
|
|
|
154
154
|
const { hippoRoot } = walkProjectMarkers(start, home, stops);
|
|
155
155
|
return hippoRoot === null ? null : path.join(hippoRoot, '.hippo');
|
|
156
156
|
}
|
|
157
|
+
/** Nearest ancestor store like git; the strict join is the fallback so `hippo init` still creates `<cwd>/.hippo`. */
|
|
158
|
+
export function getHippoRoot(cwd = process.cwd(), opts) {
|
|
159
|
+
return findHippoStoreDir(cwd, opts) ?? path.join(realpathOrResolve(cwd), '.hippo');
|
|
160
|
+
}
|
|
161
|
+
export function isInitialized(hippoRoot) {
|
|
162
|
+
// autoInstallHooks / setupDailySchedule can create a bare .hippo with no hippo.db; counting
|
|
163
|
+
// that as initialized makes `hippo init` skip initStore, so only hippo.db counts.
|
|
164
|
+
return fs.existsSync(path.join(hippoRoot, 'hippo.db'));
|
|
165
|
+
}
|
|
157
166
|
function isBareName(project) {
|
|
158
167
|
return typeof project === 'string';
|
|
159
168
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Recall-side scope predicates, in a leaf module so search-both.ts can apply the same default-deny rule to searchBothHybrid's candidate loads without an
|
|
2
2
|
* import cycle. src/api/index.ts imports these and re-exports them for back-compat (`api.isPrivateScope`, tests importing `passesScopeFilterForRecall`). */
|
|
3
|
-
import { ForbiddenError } from '
|
|
3
|
+
import { ForbiddenError } from './api-errors.js';
|
|
4
4
|
/** Literal scopes excluded from recall by default-deny when the caller passes no `scope`; read by the SQL clause in `loadSearchRows` and by
|
|
5
5
|
* `passesScopeFilterForRecall`. Invariant: never empty, or quarantine scopes would pass both paths silently (the module-load assertion below pins this). */
|
|
6
6
|
export declare const RECALL_DEFAULT_DENY_SCOPES: readonly ["unknown:legacy"];
|
|
@@ -31,15 +31,6 @@ export declare function ownScopeTouches(ownScope: string | null, scope: string |
|
|
|
31
31
|
/** JS half of the recall default-deny rule (SQL half: `loadSearchRows`). A non-empty `requested` needs an exact match;
|
|
32
32
|
* otherwise `<source>:private:*` and `RECALL_DEFAULT_DENY_SCOPES` buckets are denied, while null, public scopes and the caller's `ownScope` pass. */
|
|
33
33
|
export declare function passesScopeFilterForRecall(scope: string | null, requested: string | undefined, ownScope?: string | null): boolean;
|
|
34
|
-
export interface SqlFragment {
|
|
35
|
-
sql: string;
|
|
36
|
-
params: string[];
|
|
37
|
-
}
|
|
38
|
-
/** SQL twin of the no-request arm of passesScopeFilterForRecall; `ownScope` is bound and compared with `=`, so `%` or `_` in an owner match nothing extra. */
|
|
39
|
-
export declare function scopeAdmitSql(col: '' | 'm.', ownScope?: string | null): SqlFragment;
|
|
40
|
-
/** SQL twin of canTouchScope, which is also canReadScope for an admin: every row but
|
|
41
|
-
* another person's personal one. LIKE folds ASCII case as isPersonalScope's /i does. */
|
|
42
|
-
export declare function touchableScopeSql(col: '' | 'm.', ownScope?: string | null): SqlFragment;
|
|
43
34
|
/** CLI `--scope` variant: an explicit `--scope X` UNLOCKS scope X on top of the default-admitted set rather than narrowing to X (api.recall keeps 'exact').
|
|
44
35
|
* Includes private/quarantine scopes (owner access); a named personal scope never unlocks: the CLI has no caller identity. */
|
|
45
36
|
export declare function passesCliRecallScopeFilter(scope: string | null, requested: string | undefined): boolean;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** Recall-side scope predicates, in a leaf module so search-both.ts can apply the same default-deny rule to searchBothHybrid's candidate loads without an
|
|
2
2
|
* import cycle. src/api/index.ts imports these and re-exports them for back-compat (`api.isPrivateScope`, tests importing `passesScopeFilterForRecall`). */
|
|
3
|
-
import { BadRequestError, ForbiddenError } from '
|
|
4
|
-
import { MAX_ID_LEN } from '../util/
|
|
3
|
+
import { BadRequestError, ForbiddenError } from './api-errors.js';
|
|
4
|
+
import { MAX_ID_LEN } from '../util/limits.js';
|
|
5
5
|
/** Literal scopes excluded from recall by default-deny when the caller passes no `scope`; read by the SQL clause in `loadSearchRows` and by
|
|
6
6
|
* `passesScopeFilterForRecall`. Invariant: never empty, or quarantine scopes would pass both paths silently (the module-load assertion below pins this). */
|
|
7
7
|
export const RECALL_DEFAULT_DENY_SCOPES = ['unknown:legacy'];
|
|
@@ -63,23 +63,6 @@ export function passesScopeFilterForRecall(scope, requested, ownScope) {
|
|
|
63
63
|
}
|
|
64
64
|
return !isRestrictedScope(scope) || (ownScope != null && scope === ownScope);
|
|
65
65
|
}
|
|
66
|
-
/** SQL twin of the no-request arm of passesScopeFilterForRecall; `ownScope` is bound and compared with `=`, so `%` or `_` in an owner match nothing extra. */
|
|
67
|
-
export function scopeAdmitSql(col, ownScope) {
|
|
68
|
-
const placeholders = RECALL_DEFAULT_DENY_SCOPES.map(() => '?').join(', ');
|
|
69
|
-
const admitted = `${col}scope IS NULL OR (${col}scope NOT IN (${placeholders}) AND ${col}scope NOT LIKE '%:private:%')`;
|
|
70
|
-
if (ownScope == null)
|
|
71
|
-
return { sql: `(${admitted})`, params: [...RECALL_DEFAULT_DENY_SCOPES] };
|
|
72
|
-
// The own arm sits inside the outer parentheses so a caller's `AND ${sql}` cannot split it off.
|
|
73
|
-
return { sql: `(${admitted} OR ${col}scope = ?)`, params: [...RECALL_DEFAULT_DENY_SCOPES, ownScope] };
|
|
74
|
-
}
|
|
75
|
-
/** SQL twin of canTouchScope, which is also canReadScope for an admin: every row but
|
|
76
|
-
* another person's personal one. LIKE folds ASCII case as isPersonalScope's /i does. */
|
|
77
|
-
export function touchableScopeSql(col, ownScope) {
|
|
78
|
-
const notPersonal = `${col}scope IS NULL OR ${col}scope NOT LIKE '${PERSONAL_SCOPE_PREFIX}%'`;
|
|
79
|
-
if (ownScope == null)
|
|
80
|
-
return { sql: `(${notPersonal})`, params: [] };
|
|
81
|
-
return { sql: `(${notPersonal} OR ${col}scope = ?)`, params: [ownScope] };
|
|
82
|
-
}
|
|
83
66
|
/** CLI `--scope` variant: an explicit `--scope X` UNLOCKS scope X on top of the default-admitted set rather than narrowing to X (api.recall keeps 'exact').
|
|
84
67
|
* Includes private/quarantine scopes (owner access); a named personal scope never unlocks: the CLI has no caller identity. */
|
|
85
68
|
export function passesCliRecallScopeFilter(scope, requested) {
|
package/dist/db/busy.d.ts
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
import type { DatabaseSyncLike } from './sqlite.js';
|
|
2
2
|
export declare function isSqliteBusy(cause: unknown): boolean;
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export declare class StoreBusyError extends Error {
|
|
6
|
-
constructor(message?: string, options?: ErrorOptions);
|
|
7
|
-
}
|
|
8
|
-
/** A held lock in any store: SQLite's busy codes or a port's StoreBusyError. */
|
|
9
|
-
export declare function isStoreBusy<E>(error: E): boolean;
|
|
3
|
+
/** The lock wait of an open that names none: its busy_timeout and every explicit wait below. */
|
|
4
|
+
export declare const DEFAULT_BUSY_WAIT_MS = 5000;
|
|
10
5
|
export declare function execWithBusyRetry(db: DatabaseSyncLike, sql: string, timeoutMs?: number): void;
|
|
11
6
|
/** Waits for the lock past busy_timeout when given; ignored inside a caller's transaction, which already holds it. */
|
|
12
7
|
export interface WriteScopeOptions {
|
package/dist/db/busy.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { errorFields, errorMessage, log } from '../util/log.js';
|
|
1
2
|
function carriesErrcode(cause) {
|
|
2
3
|
return typeof cause === 'object' && cause !== null && 'errcode' in cause;
|
|
3
4
|
}
|
|
@@ -5,21 +6,11 @@ export function isSqliteBusy(cause) {
|
|
|
5
6
|
const code = carriesErrcode(cause) ? cause.errcode : undefined;
|
|
6
7
|
return code === 5 || code === 6 || code === 517;
|
|
7
8
|
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export class StoreBusyError extends Error {
|
|
11
|
-
constructor(message = STORE_BUSY_MESSAGE, options) {
|
|
12
|
-
super(message, options);
|
|
13
|
-
this.name = 'StoreBusyError';
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
/** A held lock in any store: SQLite's busy codes or a port's StoreBusyError. */
|
|
17
|
-
export function isStoreBusy(error) {
|
|
18
|
-
return error instanceof StoreBusyError || isSqliteBusy(error);
|
|
19
|
-
}
|
|
9
|
+
/** The lock wait of an open that names none: its busy_timeout and every explicit wait below. */
|
|
10
|
+
export const DEFAULT_BUSY_WAIT_MS = 5000;
|
|
20
11
|
// busy_timeout covers neither contended statement here: SQLite skips the busy handler for `PRAGMA journal_mode` and for a write
|
|
21
12
|
// that upgrades a deferred read snapshot, so both need an explicit wait.
|
|
22
|
-
export function execWithBusyRetry(db, sql, timeoutMs =
|
|
13
|
+
export function execWithBusyRetry(db, sql, timeoutMs = DEFAULT_BUSY_WAIT_MS) {
|
|
23
14
|
const deadline = Date.now() + timeoutMs;
|
|
24
15
|
const idle = new Int32Array(new SharedArrayBuffer(4));
|
|
25
16
|
for (;;) {
|
|
@@ -43,6 +34,17 @@ function undoScope(db, top, name) {
|
|
|
43
34
|
db.exec(`RELEASE SAVEPOINT ${name}`);
|
|
44
35
|
}
|
|
45
36
|
}
|
|
37
|
+
/** Undo after a failure without letting a failed undo replace the caller's error; an idle handle means SQLite already unwound the scope. */
|
|
38
|
+
function undoAfterFailure(db, top, name) {
|
|
39
|
+
if (db.isTransaction === false)
|
|
40
|
+
return;
|
|
41
|
+
try {
|
|
42
|
+
undoScope(db, top, name);
|
|
43
|
+
}
|
|
44
|
+
catch (undoError) {
|
|
45
|
+
log.error(`rollback of write scope ${name} failed: ${errorMessage(undoError)}`, errorFields(undoError));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
46
48
|
/** Runs `fn` as one write: BEGIN IMMEDIATE on an idle handle, else SAVEPOINT `name` inside the caller's transaction.
|
|
47
49
|
* A deferred scope that reads first cannot wait out another writer, while BEGIN IMMEDIATE waits the open's busy_timeout. */
|
|
48
50
|
export function withWriteScope(db, name, fn, opts) {
|
|
@@ -57,10 +59,7 @@ export function withWriteScope(db, name, fn, opts) {
|
|
|
57
59
|
return result;
|
|
58
60
|
}
|
|
59
61
|
catch (error) {
|
|
60
|
-
|
|
61
|
-
undoScope(db, top, name);
|
|
62
|
-
}
|
|
63
|
-
catch { /* already rolled back; keep the original error */ }
|
|
62
|
+
undoAfterFailure(db, top, name);
|
|
64
63
|
throw error;
|
|
65
64
|
}
|
|
66
65
|
}
|
|
@@ -77,7 +76,9 @@ export function withReadSnapshot(db, fn) {
|
|
|
77
76
|
try {
|
|
78
77
|
db.exec('COMMIT');
|
|
79
78
|
}
|
|
80
|
-
catch {
|
|
79
|
+
catch (endError) {
|
|
80
|
+
log.error(`ending read snapshot failed: ${errorMessage(endError)}`, errorFields(endError));
|
|
81
|
+
}
|
|
81
82
|
throw error;
|
|
82
83
|
}
|
|
83
84
|
db.exec('COMMIT');
|
|
@@ -92,10 +93,7 @@ export function withTrialScope(db, name, fn) {
|
|
|
92
93
|
result = fn();
|
|
93
94
|
}
|
|
94
95
|
catch (error) {
|
|
95
|
-
|
|
96
|
-
undoScope(db, top, name);
|
|
97
|
-
}
|
|
98
|
-
catch { /* already rolled back; keep the original error */ }
|
|
96
|
+
undoAfterFailure(db, top, name);
|
|
99
97
|
throw error;
|
|
100
98
|
}
|
|
101
99
|
undoScope(db, top, name);
|
|
@@ -123,10 +121,7 @@ export function withWriteScopeOr(db, name, fn) {
|
|
|
123
121
|
return result;
|
|
124
122
|
}
|
|
125
123
|
catch (error) {
|
|
126
|
-
|
|
127
|
-
undoScope(db, top, name);
|
|
128
|
-
}
|
|
129
|
-
catch { /* already rolled back; keep the original error */ }
|
|
124
|
+
undoAfterFailure(db, top, name);
|
|
130
125
|
throw error;
|
|
131
126
|
}
|
|
132
127
|
}
|
package/dist/db/connect.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { type DatabaseSyncLike } from './sqlite.js';
|
|
2
2
|
import { type OpenFacts } from './migrate.js';
|
|
3
|
-
export declare const DEFAULT_BUSY_WAIT_MS = 5000;
|
|
4
3
|
export declare function getHippoDbPath(hippoRoot: string): string;
|
|
5
4
|
/** Runs `step` on this store unless it already ran to the end in this process; a throw leaves it due. */
|
|
6
5
|
export declare function oncePerStore(hippoRoot: string, name: string, step: () => void): void;
|
package/dist/db/connect.js
CHANGED
|
@@ -3,10 +3,9 @@ import * as path from 'path';
|
|
|
3
3
|
import { cleanupArchivedMirrors } from './raw-archive-mirror-cleanup.js';
|
|
4
4
|
import { errorFields, errorMessage, log } from '../util/log.js';
|
|
5
5
|
import { DatabaseSync } from './sqlite.js';
|
|
6
|
-
import { execWithBusyRetry } from './busy.js';
|
|
6
|
+
import { DEFAULT_BUSY_WAIT_MS, execWithBusyRetry } from './busy.js';
|
|
7
7
|
import { runMigrations } from './migrate.js';
|
|
8
8
|
import { autoCheckpointPages } from './wal-checkpointer.js';
|
|
9
|
-
export const DEFAULT_BUSY_WAIT_MS = 5000;
|
|
10
9
|
export function getHippoDbPath(hippoRoot) {
|
|
11
10
|
return path.join(hippoRoot, 'hippo.db');
|
|
12
11
|
}
|
|
@@ -53,11 +52,11 @@ function archiveTop(db) {
|
|
|
53
52
|
return Number(row?.top ?? 0);
|
|
54
53
|
}
|
|
55
54
|
/** A new connection with the store's pragmas and migrations applied and the mirror cleanup run when it is due; the caller owns and closes it. */
|
|
56
|
-
export function connectWithFacts(hippoRoot, busyWaitMs) {
|
|
55
|
+
export function connectWithFacts(hippoRoot, busyWaitMs = DEFAULT_BUSY_WAIT_MS) {
|
|
57
56
|
createStoreFilesOwnerOnly(hippoRoot);
|
|
58
57
|
const db = new DatabaseSync(getHippoDbPath(hippoRoot));
|
|
59
58
|
try {
|
|
60
|
-
db.exec(`PRAGMA busy_timeout = ${busyWaitMs
|
|
59
|
+
db.exec(`PRAGMA busy_timeout = ${busyWaitMs}`);
|
|
61
60
|
execWithBusyRetry(db, 'PRAGMA journal_mode = WAL', busyWaitMs);
|
|
62
61
|
db.exec('PRAGMA synchronous = NORMAL');
|
|
63
62
|
db.exec(`PRAGMA wal_autocheckpoint = ${autoCheckpointPages(getHippoDbPath(hippoRoot))}`);
|
|
@@ -76,8 +75,8 @@ export function connectWithFacts(hippoRoot, busyWaitMs) {
|
|
|
76
75
|
try {
|
|
77
76
|
db.close();
|
|
78
77
|
}
|
|
79
|
-
catch {
|
|
80
|
-
|
|
78
|
+
catch (closeErr) {
|
|
79
|
+
log.error(`openHippoDb: closing the handle after a failed open failed: ${errorMessage(closeErr)}`, errorFields(closeErr));
|
|
81
80
|
}
|
|
82
81
|
throw error;
|
|
83
82
|
}
|
package/dist/db/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export type { DatabaseSyncLike } from './sqlite.js';
|
|
2
|
-
export { isSqliteBusy,
|
|
2
|
+
export { isSqliteBusy, execWithBusyRetry, withReadSnapshot, withTrialScope, withWriteScope, withWriteScopeOr } from './busy.js';
|
|
3
3
|
export { getSchemaVersion, getMeta, setMeta, isFtsAvailable } from './meta.js';
|
|
4
|
-
export { countTableRows, pruneConsolidationRuns } from './tables.js';
|
|
4
|
+
export { countTableRows, pruneConsolidationRuns, CONSOLIDATION_RUNS_KEPT } from './tables.js';
|
|
5
5
|
export { getCurrentSchemaVersion, IncompatibleBinaryError, ftsRowCounts, repairFtsDrift } from './migrate.js';
|
|
6
|
-
export { getHippoDbPath, HOOK_DB_WAIT_MS, noteStoreBusy, withSharedStoreHandles, SERVER_DB_WAIT_MS, SLEEP_DB_WAIT_MS, scopedBusyWait, withSqliteBlocked, withSqliteAllowed, withSqliteOffLoop, outsideSqliteOffLoop,
|
|
6
|
+
export { getHippoDbPath, HOOK_DB_WAIT_MS, noteStoreBusy, withSharedStoreHandles, SERVER_DB_WAIT_MS, SLEEP_DB_WAIT_MS, scopedBusyWait, withSqliteBlocked, withSqliteAllowed, withSqliteOffLoop, outsideSqliteOffLoop, OTHER_STORE_MARKER, openHippoDb, openHippoDbReadOnly, closeHippoDb, } from './open.js';
|
|
7
7
|
export { RequestStores, runWithRequestStores, currentRequestStores, outsideRequestStores } from './request-stores.js';
|
|
8
8
|
export { OtherStoreFolderError, SqliteBlockedError } from '../util/sqlite-blocked.js';
|
|
9
9
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/db/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export { isSqliteBusy,
|
|
1
|
+
export { isSqliteBusy, execWithBusyRetry, withReadSnapshot, withTrialScope, withWriteScope, withWriteScopeOr } from './busy.js';
|
|
2
2
|
export { getSchemaVersion, getMeta, setMeta, isFtsAvailable } from './meta.js';
|
|
3
|
-
export { countTableRows, pruneConsolidationRuns } from './tables.js';
|
|
3
|
+
export { countTableRows, pruneConsolidationRuns, CONSOLIDATION_RUNS_KEPT } from './tables.js';
|
|
4
4
|
export { getCurrentSchemaVersion, IncompatibleBinaryError, ftsRowCounts, repairFtsDrift } from './migrate.js';
|
|
5
|
-
export { getHippoDbPath, HOOK_DB_WAIT_MS, noteStoreBusy, withSharedStoreHandles, SERVER_DB_WAIT_MS, SLEEP_DB_WAIT_MS, scopedBusyWait, withSqliteBlocked, withSqliteAllowed, withSqliteOffLoop, outsideSqliteOffLoop,
|
|
5
|
+
export { getHippoDbPath, HOOK_DB_WAIT_MS, noteStoreBusy, withSharedStoreHandles, SERVER_DB_WAIT_MS, SLEEP_DB_WAIT_MS, scopedBusyWait, withSqliteBlocked, withSqliteAllowed, withSqliteOffLoop, outsideSqliteOffLoop, OTHER_STORE_MARKER, openHippoDb, openHippoDbReadOnly, closeHippoDb, } from './open.js';
|
|
6
6
|
export { RequestStores, runWithRequestStores, currentRequestStores, outsideRequestStores } from './request-stores.js';
|
|
7
7
|
export { OtherStoreFolderError, SqliteBlockedError } from '../util/sqlite-blocked.js';
|
|
8
8
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Migration } from './types.js';
|
|
2
|
-
export declare const CURRENT_SCHEMA_VERSION =
|
|
2
|
+
export declare const CURRENT_SCHEMA_VERSION = 55;
|
|
3
3
|
/** Every schema migration in version order; runMigrations applies each one above the stored version. */
|
|
4
4
|
export declare const MIGRATIONS: Migration[];
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|