hippo-memory 1.70.0 → 1.71.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/claude-code.d.ts +4 -2
- package/dist/agent-memories/claude-code.js +14 -5
- 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/report.js +2 -1
- package/dist/agent-memories/sync.d.ts +4 -2
- package/dist/agent-memories/sync.js +10 -5
- package/dist/api/assemble.d.ts +7 -44
- package/dist/api/assemble.js +2 -22
- package/dist/api/audit.d.ts +5 -1
- package/dist/api/audit.js +9 -1
- package/dist/api/auth.d.ts +13 -22
- package/dist/api/auth.js +34 -24
- package/dist/api/auto-sleep.js +2 -2
- package/dist/api/availability.d.ts +2 -15
- package/dist/api/availability.js +2 -15
- package/dist/api/context-select.js +3 -4
- package/dist/api/context-types.d.ts +10 -35
- package/dist/api/context.d.ts +5 -22
- package/dist/api/context.js +21 -38
- package/dist/api/dormant.d.ts +5 -21
- package/dist/api/dormant.js +7 -26
- package/dist/api/drill-down.d.ts +7 -46
- package/dist/api/drill-down.js +5 -26
- package/dist/api/forget.d.ts +5 -24
- package/dist/api/forget.js +5 -28
- package/dist/api/graph.d.ts +8 -0
- package/dist/api/graph.js +7 -0
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.js +2 -0
- package/dist/api/instruction-detect.js +16 -5
- package/dist/api/ledger-db.d.ts +2 -1
- package/dist/api/ledger-db.js +5 -3
- package/dist/api/memories.d.ts +5 -0
- package/dist/api/memories.js +7 -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/predictions.d.ts +9 -0
- package/dist/api/predictions.js +18 -0
- package/dist/api/promote.d.ts +13 -17
- package/dist/api/promote.js +11 -19
- package/dist/api/prompt-hook.d.ts +4 -4
- package/dist/api/prompt-hook.js +10 -9
- package/dist/api/recall-cli.d.ts +55 -0
- package/dist/api/recall-cli.js +94 -0
- package/dist/api/recall-core.js +14 -6
- 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 +16 -9
- package/dist/api/recall-types.d.ts +64 -304
- package/dist/api/recall.d.ts +5 -33
- package/dist/api/recall.js +59 -60
- 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 +18 -1
- package/dist/api/remember.js +13 -1
- package/dist/api/sleep-run.d.ts +1 -3
- package/dist/api/sleep-run.js +17 -21
- package/dist/api/sleep.d.ts +9 -28
- package/dist/api/tokens.d.ts +3 -10
- package/dist/api/tokens.js +3 -10
- package/dist/api/types.d.ts +6 -29
- package/dist/api/types.js +4 -22
- package/dist/capture/command.d.ts +4 -12
- package/dist/capture/command.js +6 -22
- package/dist/capture/compact.d.ts +4 -15
- package/dist/capture/compact.js +16 -25
- package/dist/capture/compaction-record.js +101 -69
- package/dist/capture/compaction-spool.d.ts +1 -1
- package/dist/capture/compaction-spool.js +1 -1
- package/dist/capture/session-digest.d.ts +1 -1
- package/dist/capture/session-digest.js +13 -7
- package/dist/capture/transcript.d.ts +2 -10
- package/dist/capture/transcript.js +4 -18
- package/dist/cli/api-context.d.ts +3 -0
- package/dist/cli/api-context.js +6 -0
- package/dist/cli/audit-prune.d.ts +6 -39
- package/dist/cli/audit-prune.js +6 -39
- package/dist/cli/audit.d.ts +1 -1
- package/dist/cli/audit.js +33 -34
- package/dist/cli/auth.d.ts +2 -2
- package/dist/cli/auth.js +57 -39
- package/dist/cli/briefs.d.ts +4 -4
- package/dist/cli/briefs.js +18 -22
- package/dist/cli/card.d.ts +2 -2
- package/dist/cli/card.js +31 -32
- package/dist/cli/client.d.ts +7 -27
- package/dist/cli/client.js +24 -43
- package/dist/cli/compact-resume-payload.js +3 -2
- package/dist/cli/context.d.ts +1 -2
- package/dist/cli/context.js +12 -8
- package/dist/cli/continuity.d.ts +6 -6
- package/dist/cli/continuity.js +62 -64
- package/dist/cli/correction-latency.d.ts +2 -14
- package/dist/cli/correction-latency.js +2 -14
- package/dist/cli/curate.d.ts +13 -17
- package/dist/cli/curate.js +68 -92
- package/dist/cli/dag.d.ts +4 -4
- package/dist/cli/dag.js +33 -27
- package/dist/cli/decisions.d.ts +4 -4
- package/dist/cli/decisions.js +33 -47
- package/dist/cli/eval.js +15 -13
- package/dist/cli/exit.d.ts +6 -0
- package/dist/cli/exit.js +11 -0
- package/dist/cli/explain.d.ts +1 -2
- package/dist/cli/explain.js +6 -4
- package/dist/cli/flag-values.d.ts +6 -1
- package/dist/cli/flag-values.js +27 -10
- package/dist/cli/flags.d.ts +1 -0
- package/dist/cli/flags.js +1 -1
- 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/hook-runtime.d.ts +9 -27
- package/dist/cli/hook-runtime.js +15 -31
- package/dist/cli/init.d.ts +2 -2
- package/dist/cli/init.js +6 -12
- package/dist/cli/install-steps.js +3 -12
- package/dist/cli/last-sleep.d.ts +2 -1
- package/dist/cli/last-sleep.js +3 -0
- package/dist/cli/maintenance.d.ts +4 -4
- package/dist/cli/maintenance.js +14 -19
- package/dist/cli/object-verbs.js +4 -3
- package/dist/cli/owner-validation.d.ts +5 -28
- package/dist/cli/owner-validation.js +5 -28
- package/dist/cli/playbooks.d.ts +4 -4
- package/dist/cli/playbooks.js +23 -28
- package/dist/cli/print.d.ts +2 -5
- package/dist/cli/print.js +1 -4
- package/dist/cli/projects.d.ts +2 -2
- package/dist/cli/projects.js +1 -3
- package/dist/cli/provenance-coverage.d.ts +2 -6
- package/dist/cli/provenance-coverage.js +2 -6
- package/dist/cli/quality-repair-once.js +2 -2
- package/dist/cli/recall.d.ts +2 -4
- package/dist/cli/recall.js +55 -131
- package/dist/cli/refine-llm.d.ts +5 -31
- package/dist/cli/refine-llm.js +9 -36
- package/dist/cli/remember.d.ts +3 -3
- package/dist/cli/remember.js +122 -180
- package/dist/cli/scheduler.d.ts +2 -17
- package/dist/cli/scheduler.js +12 -18
- package/dist/cli/serve.js +21 -12
- package/dist/cli/session-hooks.d.ts +10 -18
- package/dist/cli/session-hooks.js +112 -113
- package/dist/cli/setup.d.ts +4 -4
- package/dist/cli/setup.js +19 -21
- package/dist/cli/shared.d.ts +9 -23
- package/dist/cli/shared.js +9 -32
- package/dist/cli/slack.d.ts +2 -2
- package/dist/cli/slack.js +19 -23
- package/dist/cli/sleep.d.ts +3 -2
- package/dist/cli/sleep.js +15 -16
- package/dist/cli/status.d.ts +9 -12
- package/dist/cli/status.js +55 -98
- 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 +66 -89
- package/dist/cli/usage.js +11 -5
- package/dist/cli.d.ts +66 -448
- package/dist/cli.js +87 -263
- package/dist/connectors/github/backfill.d.ts +5 -25
- package/dist/connectors/github/backfill.js +14 -49
- 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 +12 -29
- package/dist/connectors/github/ingest.d.ts +2 -6
- package/dist/connectors/github/ingest.js +4 -10
- 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 +2 -16
- package/dist/connectors/github/webhook.js +6 -22
- 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 +2 -19
- package/dist/connectors/slack/ingest.d.ts +2 -3
- package/dist/connectors/slack/ingest.js +2 -3
- 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 +2 -19
- package/dist/connectors/slack/webhook.js +5 -26
- package/dist/connectors/slack/workspaces.d.ts +4 -24
- package/dist/connectors/slack/workspaces.js +4 -24
- package/dist/consolidate/conflicts.js +6 -14
- 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 +14 -75
- package/dist/consolidate/decay.js +7 -19
- package/dist/consolidate/dedupe.d.ts +6 -52
- package/dist/consolidate/dedupe.js +13 -71
- 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 +4 -21
- 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 +16 -104
- package/dist/consolidate/merge.js +10 -31
- package/dist/consolidate/merged-row.js +2 -1
- package/dist/consolidate/physics-pass.js +1 -3
- package/dist/consolidate/replay.d.ts +6 -38
- package/dist/consolidate/replay.js +14 -52
- package/dist/consolidate/run.js +1 -1
- package/dist/consolidate/sleep.d.ts +1 -8
- package/dist/consolidate/sleep.js +5 -17
- package/dist/consolidate/trace.d.ts +3 -18
- package/dist/consolidate/trace.js +3 -18
- package/dist/consolidate/traces.js +6 -22
- package/dist/core/ablation.d.ts +4 -91
- package/dist/core/ablation.js +4 -91
- package/dist/core/ambient.d.ts +1 -8
- package/dist/core/ambient.js +1 -8
- 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 +8 -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 +13 -14
- package/dist/core/handoff.d.ts +1 -7
- package/dist/core/handoff.js +1 -7
- package/dist/core/memory-quality.js +1 -1
- package/dist/core/memory.d.ts +41 -164
- package/dist/core/memory.js +51 -221
- 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 +59 -122
- package/dist/core/project-identity.d.ts +17 -58
- package/dist/core/project-identity.js +17 -38
- 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/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 +1 -1
- package/dist/db/busy.js +17 -8
- package/dist/db/connect.d.ts +1 -0
- package/dist/db/connect.js +3 -3
- package/dist/db/migrate.js +3 -3
- 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/open.d.ts +2 -0
- package/dist/db/open.js +17 -1
- package/dist/db/physics-state.d.ts +6 -22
- package/dist/db/physics-state.js +25 -36
- package/dist/db/raw-archive-mirror-cleanup.d.ts +2 -17
- package/dist/db/raw-archive-mirror-cleanup.js +2 -17
- package/dist/db/vector-store.d.ts +2 -0
- package/dist/db/vector-store.js +8 -1
- package/dist/doctor.js +74 -19
- package/dist/entry/session-text.js +2 -1
- 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 +74 -34
- package/dist/eval/eval.d.ts +6 -24
- package/dist/eval/eval.js +7 -34
- package/dist/eval/judgment.d.ts +0 -3
- package/dist/eval/judgment.js +19 -11
- package/dist/extensions/openclaw-plugin/index.js +1 -1
- package/dist/graph/extract.d.ts +5 -27
- package/dist/graph/extract.js +7 -33
- package/dist/graph/recall.d.ts +7 -20
- package/dist/graph/recall.js +14 -76
- 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 +11 -39
- package/dist/hooks/codex-wrapper.js +2 -2
- 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 +18 -57
- package/dist/hooks/opencode.d.ts +0 -38
- package/dist/hooks/opencode.js +9 -76
- package/dist/hooks/shared.d.ts +8 -17
- package/dist/hooks/shared.js +29 -20
- package/dist/importers/core.d.ts +12 -37
- package/dist/importers/core.js +9 -27
- 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 +7 -35
- package/dist/importers/vault.d.ts +2 -8
- package/dist/importers/vault.js +25 -81
- package/dist/index.d.ts +6 -2
- package/dist/index.js +6 -2
- package/dist/learn/autolearn.d.ts +14 -41
- package/dist/learn/autolearn.js +14 -41
- package/dist/learn/extract.js +2 -4
- package/dist/learn/forward-claim-detector.d.ts +6 -30
- package/dist/learn/forward-claim-detector.js +14 -66
- package/dist/learn/invalidation.d.ts +6 -18
- package/dist/learn/invalidation.js +9 -26
- package/dist/mcp/admin-tools.js +3 -5
- package/dist/mcp/memory-tools.js +4 -9
- package/dist/mcp/protocol.d.ts +8 -26
- package/dist/mcp/protocol.js +3 -6
- package/dist/mcp/recall-tools.js +3 -3
- package/dist/mcp/request.d.ts +3 -11
- package/dist/mcp/request.js +10 -26
- 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 +48 -12
- package/dist/mcp/tools.js +5 -3
- package/dist/objects/customer-notes.d.ts +7 -42
- package/dist/objects/customer-notes.js +7 -48
- package/dist/objects/decisions.d.ts +12 -50
- package/dist/objects/decisions.js +15 -53
- package/dist/objects/incidents.d.ts +7 -38
- package/dist/objects/incidents.js +7 -41
- package/dist/objects/policies.d.ts +11 -89
- package/dist/objects/policies.js +11 -98
- package/dist/objects/processes.d.ts +7 -52
- package/dist/objects/processes.js +7 -61
- package/dist/objects/project-briefs.d.ts +11 -55
- package/dist/objects/project-briefs.js +14 -75
- package/dist/objects/skills.d.ts +7 -42
- package/dist/objects/skills.js +8 -54
- package/dist/postinstall.js +6 -19
- package/dist/predictions/planning-fallacy.d.ts +11 -34
- package/dist/rerankers/clef.js +3 -31
- package/dist/rerankers/cross-encoder.js +4 -6
- package/dist/rerankers/jev.js +9 -6
- package/dist/rerankers/llm.d.ts +2 -11
- package/dist/rerankers/llm.js +14 -14
- package/dist/rerankers/outage-warning.d.ts +2 -1
- package/dist/rerankers/outage-warning.js +2 -1
- 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/boosts.d.ts +0 -2
- package/dist/search/boosts.js +2 -2
- package/dist/search/goal-boost.d.ts +23 -0
- package/dist/search/goal-boost.js +90 -0
- package/dist/search/hybrid.d.ts +2 -0
- 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.js +11 -8
- package/dist/search/rrf.d.ts +7 -35
- package/dist/search/rrf.js +5 -30
- package/dist/search/vector.d.ts +7 -0
- package/dist/search/vector.js +35 -5
- package/dist/server/auth.d.ts +9 -28
- package/dist/server/auth.js +32 -25
- package/dist/server/boot.d.ts +2 -21
- package/dist/server/boot.js +63 -96
- package/dist/server/client-ip.d.ts +3 -19
- package/dist/server/client-ip.js +5 -28
- package/dist/server/defaults.d.ts +3 -0
- package/dist/server/defaults.js +4 -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 +10 -44
- 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 +9 -17
- package/dist/server/route-table.js +42 -49
- package/dist/server/routes/admin.js +22 -28
- package/dist/server/routes/customer-notes.js +7 -12
- package/dist/server/routes/decisions.js +10 -17
- package/dist/server/routes/incidents.js +12 -20
- package/dist/server/routes/memories.js +12 -32
- package/dist/server/routes/object-routes.d.ts +0 -5
- package/dist/server/routes/object-routes.js +7 -15
- package/dist/server/routes/policies.js +10 -18
- package/dist/server/routes/predictions.js +13 -25
- package/dist/server/routes/processes.js +16 -26
- package/dist/server/routes/project-briefs.js +9 -16
- package/dist/server/routes/recall.js +10 -35
- package/dist/server/routes/skills.js +8 -18
- package/dist/server/server-detect.d.ts +9 -53
- package/dist/server/server-detect.js +24 -90
- package/dist/server/sleep-offload.js +4 -1
- package/dist/server/types.d.ts +12 -10
- package/dist/server/validation.d.ts +3 -1
- package/dist/server/validation.js +10 -23
- package/dist/server.d.ts +2 -2
- package/dist/server.js +3 -2
- 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 +80 -0
- package/dist/sharing/project-merge.d.ts +4 -5
- package/dist/sharing/project-merge.js +9 -7
- package/dist/sharing/scope.d.ts +4 -11
- package/dist/sharing/scope.js +4 -11
- package/dist/sharing/search-both.d.ts +60 -0
- package/dist/sharing/search-both.js +138 -0
- package/dist/sharing/share.d.ts +38 -0
- package/dist/sharing/share.js +226 -0
- package/dist/store/ambient.js +4 -9
- package/dist/store/audit-event.d.ts +4 -12
- package/dist/store/audit-event.js +4 -12
- package/dist/store/audit.d.ts +2 -5
- package/dist/store/audit.js +4 -12
- package/dist/store/auth.d.ts +6 -6
- package/dist/store/auth.js +10 -9
- package/dist/store/candidates.d.ts +20 -3
- package/dist/store/candidates.js +77 -48
- 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/conflicts.d.ts +4 -21
- package/dist/store/conflicts.js +71 -150
- package/dist/store/connectors/github.d.ts +10 -10
- package/dist/store/connectors/github.js +10 -10
- package/dist/store/dashboard-reads.js +4 -8
- package/dist/store/delete-and-batch.d.ts +11 -31
- package/dist/store/delete-and-batch.js +48 -64
- package/dist/store/delivery-recorder.d.ts +8 -4
- package/dist/store/delivery-recorder.js +25 -15
- package/dist/store/diagnostics.js +6 -13
- package/dist/store/dormant.d.ts +7 -29
- package/dist/store/dormant.js +15 -56
- package/dist/store/embeddings/index.d.ts +11 -80
- package/dist/store/embeddings/index.js +71 -207
- package/dist/store/embeddings/local.js +15 -32
- package/dist/store/embeddings/provider.d.ts +16 -53
- package/dist/store/embeddings/provider.js +41 -69
- package/dist/store/entry-reads.d.ts +21 -57
- package/dist/store/entry-reads.js +65 -126
- package/dist/store/entry-row.d.ts +6 -35
- package/dist/store/entry-row.js +9 -37
- package/dist/store/entry-writes.d.ts +10 -16
- package/dist/store/entry-writes.js +17 -35
- package/dist/store/goals.d.ts +3 -40
- package/dist/store/goals.js +21 -160
- 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 +20 -58
- 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 +6 -31
- package/dist/store/graph-writes.js +13 -37
- package/dist/store/half-life.d.ts +2 -1
- package/dist/store/half-life.js +14 -16
- package/dist/store/handoffs.d.ts +5 -11
- package/dist/store/handoffs.js +16 -34
- package/dist/store/index-and-stats.d.ts +6 -19
- package/dist/store/index-and-stats.js +34 -82
- package/dist/store/markdown.d.ts +2 -6
- package/dist/store/markdown.js +21 -20
- package/dist/store/mirrors.d.ts +2 -6
- package/dist/store/mirrors.js +14 -23
- package/dist/store/open.js +6 -13
- 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 +82 -79
- package/dist/store/predictions.d.ts +11 -51
- package/dist/store/predictions.js +38 -119
- package/dist/{cli → store}/quality-repair.js +15 -31
- package/dist/store/raw-archive.d.ts +4 -16
- package/dist/store/raw-archive.js +14 -29
- package/dist/store/recall-scope.d.ts +19 -79
- package/dist/store/recall-scope.js +21 -82
- package/dist/store/recall-trace.d.ts +10 -77
- package/dist/store/recall-trace.js +19 -95
- package/dist/store/rejected-values.js +7 -19
- package/dist/store/rejection.d.ts +12 -58
- package/dist/store/rejection.js +13 -65
- 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 +5 -0
- package/dist/store/rule-sql.js +37 -0
- package/dist/store/search-rows.d.ts +7 -38
- package/dist/store/search-rows.js +14 -50
- package/dist/store/sessions.d.ts +10 -47
- package/dist/store/sessions.js +17 -73
- package/dist/store/sqlite/connector-events-group.js +2 -2
- package/dist/store/sqlite/entry-writes-group.js +2 -2
- package/dist/store/sqlite/error-codec.js +4 -2
- package/dist/store/sqlite/executor.d.ts +2 -1
- package/dist/store/sqlite/executor.js +2 -1
- package/dist/store/sqlite/local.d.ts +3 -3
- package/dist/store/sqlite/local.js +1 -0
- package/dist/store/sqlite/object-rows.js +6 -3
- package/dist/store/sqlite/objects-group.js +4 -2
- package/dist/store/sqlite/quarantine-group.js +2 -2
- package/dist/store/sqlite/store.d.ts +1 -4
- package/dist/store/sqlite/store.js +2 -3
- 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 +10 -62
- package/dist/store/summaries.js +34 -146
- 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 -43
- package/dist/store/token-ledger.js +19 -50
- package/dist/store/usage-reports.js +5 -13
- package/dist/store/vector-index.d.ts +46 -0
- package/dist/store/vector-index.js +170 -0
- package/dist/store/working-memory.d.ts +6 -25
- package/dist/store/working-memory.js +18 -52
- package/dist/store/yaml.d.ts +1 -5
- package/dist/store/yaml.js +2 -6
- package/dist/support-bundle.js +7 -5
- package/dist/trust/reject-flow.js +1 -3
- package/dist/util/anthropic-messages.js +14 -2
- 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/crash-handlers.d.ts +8 -1
- package/dist/util/crash-handlers.js +52 -10
- package/dist/util/env.d.ts +13 -6
- package/dist/util/env.js +14 -7
- package/dist/util/home-path.d.ts +2 -1
- package/dist/util/home-path.js +4 -2
- package/dist/util/http-retry.d.ts +3 -1
- package/dist/util/http-retry.js +26 -5
- package/dist/util/log.d.ts +3 -2
- package/dist/util/log.js +25 -9
- package/dist/util/request-scope.d.ts +2 -1
- package/dist/util/request-scope.js +2 -1
- package/dist/util/secret-detect.d.ts +5 -30
- package/dist/util/secret-detect.js +13 -39
- package/dist/util/stored-json.d.ts +1 -1
- package/dist/util/stored-json.js +1 -1
- 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/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 +1 -1
- package/dist/connectors/github/cli-impl.d.ts +0 -25
- package/dist/sharing/shared.d.ts +0 -187
- package/dist/sharing/shared.js +0 -563
- package/dist/store/vector-writes.d.ts +0 -13
- package/dist/store/vector-writes.js +0 -89
- /package/dist/{cli → store}/quality-repair.d.ts +0 -0
|
@@ -1,30 +1,9 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* One row per block of memory text sent to an agent, on every surface: the
|
|
6
|
-
* per-prompt hook, the block `hippo compact-resume` restores after compaction,
|
|
7
|
-
* `hippo context`, `hippo recall`, the MCP tools and the HTTP API. The ledger
|
|
8
|
-
* answers the question a buyer asks first ("what does this cost me per
|
|
9
|
-
* session?") and is the input for the token-savings evals.
|
|
10
|
-
*
|
|
11
|
-
* Every later model call re-reads a sent block until the host compacts; at session end the worker counts
|
|
12
|
-
* those calls from the transcript as `reread` rows for the {@link REREAD_SURFACES} blocks, dated by call day.
|
|
13
|
-
*
|
|
14
|
-
* It also backs inject-only-on-change: the per-prompt hook compares the
|
|
15
|
-
* hash of the block it is about to send with the last block it sent in the
|
|
16
|
-
* same session and records a `skip` instead of sending it again.
|
|
17
|
-
*
|
|
18
|
-
* Token counts use {@link estimateTokens} (characters / 4), the same estimate
|
|
19
|
-
* every budget in hippo uses. Rows hold counts, surfaces, session ids and
|
|
20
|
-
* hashes, never memory content or query text.
|
|
21
|
-
*
|
|
22
|
-
* DB helpers take the caller's handle; {@link readApiCalls} streams one
|
|
23
|
-
* transcript file. Writes are best-effort at the call sites; a ledger failure
|
|
24
|
-
* must never break recall.
|
|
25
|
-
*/
|
|
1
|
+
/** Token ledger: one row per block of memory text sent to an agent on any surface, with its token cost; the input for the token-savings evals.
|
|
2
|
+
* Backs inject-only-on-change: the hook records a `skip` when the block hash matches the session's last; `reread` rows cover {@link REREAD_SURFACES} blocks.
|
|
3
|
+
* Counts use {@link estimateTokens} (chars / 4); rows never hold content or query text. Writes are best-effort: a ledger failure must not break recall. */
|
|
26
4
|
import { open } from 'node:fs/promises';
|
|
27
5
|
import { withWriteScope } from '../db/index.js';
|
|
6
|
+
import { onHandle } from './open.js';
|
|
28
7
|
import { isJsonString, isJsonObjectLiteral } from '../util/json.js';
|
|
29
8
|
import { DAY_MS } from '../util/time.js';
|
|
30
9
|
import { countSkipsAfter, deleteRereadRows, injectedBlocks, insertTokenRow, latestInjectOrReset, pruneTokenRowsBefore, sessionTokenRows, sessionTotals, surfaceTotals, } from './token-ledger-rows.js';
|
|
@@ -38,9 +17,7 @@ export const TOKEN_SURFACES = [
|
|
|
38
17
|
export const REREAD_SURFACES = ['hook', 'hook_recall', 'compact_resume'];
|
|
39
18
|
/** Rows older than this are pruned on write. */
|
|
40
19
|
export const TOKEN_LEDGER_RETENTION_DAYS = 90;
|
|
41
|
-
/**
|
|
42
|
-
* Append one ledger row and prune rows past {@link TOKEN_LEDGER_RETENTION_DAYS}.
|
|
43
|
-
*/
|
|
20
|
+
/** Append one ledger row and prune rows past {@link TOKEN_LEDGER_RETENTION_DAYS}. */
|
|
44
21
|
export function recordTokenUse(db, use) {
|
|
45
22
|
const now = use.now ?? new Date().toISOString();
|
|
46
23
|
insertTokenRow(db, {
|
|
@@ -56,11 +33,7 @@ export function recordTokenUse(db, use) {
|
|
|
56
33
|
const cutoff = new Date(Date.parse(now) - TOKEN_LEDGER_RETENTION_DAYS * DAY_MS).toISOString();
|
|
57
34
|
pruneTokenRowsBefore(db, cutoff);
|
|
58
35
|
}
|
|
59
|
-
/**
|
|
60
|
-
* The last block this session injected on `surface`, or null when the
|
|
61
|
-
* session has injected nothing, a `reset` came after it, or there is no
|
|
62
|
-
* session id (without one, the caller always injects).
|
|
63
|
-
*/
|
|
36
|
+
/** The last block this session injected on `surface`, or null if none, a `reset` came after it, or there is no session id (the caller then always injects). */
|
|
64
37
|
export function lastSentState(db, tenantId, sessionId, surface) {
|
|
65
38
|
if (!sessionId)
|
|
66
39
|
return null;
|
|
@@ -70,12 +43,8 @@ export function lastSentState(db, tenantId, sessionId, surface) {
|
|
|
70
43
|
const skips = countSkipsAfter(db, tenantId, sessionId, surface, anchor.id);
|
|
71
44
|
return { hash: anchor.block_hash, skipsSince: Number(skips?.n ?? 0) };
|
|
72
45
|
}
|
|
73
|
-
/**
|
|
74
|
-
*
|
|
75
|
-
* skipped. `refreshTurns` resends an unchanged block after that many
|
|
76
|
-
* consecutive skips, so a long session still sees its pinned rules near the
|
|
77
|
-
* latest turn; 0 never resends an unchanged block.
|
|
78
|
-
*/
|
|
46
|
+
/** Whether a block identical to the session's last injection should be skipped; `refreshTurns` resends it after that many consecutive skips so a long
|
|
47
|
+
* session still sees its pinned rules, 0 never resends. */
|
|
79
48
|
export function shouldSkipUnchanged(last, hash, refreshTurns) {
|
|
80
49
|
if (!last || last.hash !== hash)
|
|
81
50
|
return false;
|
|
@@ -83,10 +52,7 @@ export function shouldSkipUnchanged(last, hash, refreshTurns) {
|
|
|
83
52
|
return false;
|
|
84
53
|
return true;
|
|
85
54
|
}
|
|
86
|
-
/**
|
|
87
|
-
* Sum the ledger for one tenant since `sinceIso`. Surfaces with no rows are
|
|
88
|
-
* omitted.
|
|
89
|
-
*/
|
|
55
|
+
/** Sum the ledger for one tenant since `sinceIso`; surfaces with no rows are omitted. */
|
|
90
56
|
export function summarizeTokenUse(db, tenantId, sinceIso) {
|
|
91
57
|
const rows = surfaceTotals(db, tenantId, sinceIso);
|
|
92
58
|
const bySurface = new Map(rows.map((r) => [r.surface, r]));
|
|
@@ -159,11 +125,8 @@ export function isSubagentPayload(stdinText) {
|
|
|
159
125
|
const agentId = parseHookPayload(stdinText)?.agent_id;
|
|
160
126
|
return isJsonString(agentId) && agentId.trim() !== '';
|
|
161
127
|
}
|
|
162
|
-
/**
|
|
163
|
-
*
|
|
164
|
-
* Claude Code hook rows carry the host's session id, which is also the
|
|
165
|
-
* transcript file name, so these join to the host's own usage records.
|
|
166
|
-
*/
|
|
128
|
+
/** Ledger totals per session id since `sinceIso`, across surfaces; hook rows carry the host's session id (the transcript file name), so they join to its
|
|
129
|
+
* usage records. */
|
|
167
130
|
export function tokensBySession(db, tenantId, sinceIso) {
|
|
168
131
|
return sessionTokenRows(db, tenantId, sinceIso).map((r) => ({
|
|
169
132
|
sessionId: r.session_id,
|
|
@@ -227,8 +190,14 @@ export function carryingCalls(calls, at) {
|
|
|
227
190
|
return [];
|
|
228
191
|
return calls.filter((call) => call.at > at && call.compactions === first.compactions);
|
|
229
192
|
}
|
|
230
|
-
/** Replace a session's `reread` rows in
|
|
231
|
-
export function recordRereads(
|
|
193
|
+
/** Replace a session's `reread` rows in `hippoRoot`'s store, one per {@link REREAD_SURFACES} surface and UTC day; returns the tokens booked. */
|
|
194
|
+
export function recordRereads(hippoRoot, tenantId, sessionId, calls) {
|
|
195
|
+
return onHandle(hippoRoot, (db) => {
|
|
196
|
+
return replaceRereadRows(db, tenantId, sessionId, calls);
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
/** One transaction, so a refused row leaves the session's earlier re-read rows in place. */
|
|
200
|
+
function replaceRereadRows(db, tenantId, sessionId, calls) {
|
|
232
201
|
return withWriteScope(db, 'record_rereads', () => {
|
|
233
202
|
const rows = injectedBlocks(db, tenantId, sessionId, REREAD_SURFACES);
|
|
234
203
|
const days = new Map();
|
|
@@ -1,26 +1,18 @@
|
|
|
1
1
|
// The token-use and failure reports, each read on one handle of its own.
|
|
2
2
|
// A file apart from token-ledger-rows.ts: src/store/token-ledger.ts imports that one, so a summary there would be an import cycle.
|
|
3
|
-
import {
|
|
3
|
+
import { onHandle } from './open.js';
|
|
4
4
|
import { summarizeTokenUse } from './token-ledger.js';
|
|
5
5
|
import { summarizeFailures } from './failure-log.js';
|
|
6
6
|
/** One tenant's token ledger totals since `sinceIso`. */
|
|
7
7
|
export function tokenUseSummary(hippoRoot, tenantId, sinceIso) {
|
|
8
|
-
|
|
9
|
-
try {
|
|
8
|
+
return onHandle(hippoRoot, (db) => {
|
|
10
9
|
return summarizeTokenUse(db, tenantId, sinceIso);
|
|
11
|
-
}
|
|
12
|
-
finally {
|
|
13
|
-
closeHippoDb(db);
|
|
14
|
-
}
|
|
10
|
+
});
|
|
15
11
|
}
|
|
16
12
|
/** One tenant's failure log totals since `sinceIso`. */
|
|
17
13
|
export function failureLogSummary(hippoRoot, tenantId, sinceIso) {
|
|
18
|
-
|
|
19
|
-
try {
|
|
14
|
+
return onHandle(hippoRoot, (db) => {
|
|
20
15
|
return summarizeFailures(db, tenantId, sinceIso);
|
|
21
|
-
}
|
|
22
|
-
finally {
|
|
23
|
-
closeHippoDb(db);
|
|
24
|
-
}
|
|
16
|
+
});
|
|
25
17
|
}
|
|
26
18
|
//# sourceMappingURL=usage-reports.js.map
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { type DatabaseSyncLike } from '../db/index.js';
|
|
2
|
+
import type { MemoryEntry } from '../core/memory.js';
|
|
3
|
+
import type { PhysicsParticle } from '../core/physics.js';
|
|
4
|
+
import type { VectorBackfillQuery, VectorWrite, VectorWriteResult } from './port.js';
|
|
5
|
+
/** What a store's vector index was built by: the stored identity, and whether any vector exists. */
|
|
6
|
+
export interface EmbeddingIndexState {
|
|
7
|
+
readonly storedModel: string | null;
|
|
8
|
+
readonly hasVectors: boolean;
|
|
9
|
+
}
|
|
10
|
+
/** The model the index was built by: the stored identity, else the default model when vectors exist. */
|
|
11
|
+
export declare function indexedModel(state: EmbeddingIndexState): string | null;
|
|
12
|
+
/** Whether a vector write under the index identity `model` first drops the stored index, which another model built. */
|
|
13
|
+
export declare function replacesIndex(state: EmbeddingIndexState, model: string): boolean;
|
|
14
|
+
/** hippo.db's index state, the meta row and the EXISTS on one handle. */
|
|
15
|
+
export declare function storedIndexState(hippoRoot: string): EmbeddingIndexState;
|
|
16
|
+
/** Records `identity` as what built the index under `hippoRoot`. */
|
|
17
|
+
export declare function saveIndexIdentity(hippoRoot: string, identity: string): void;
|
|
18
|
+
/** Every stored vector keyed by memory id; `{}` when none. Search reads only the rows it ranks via `loadStoredVectors`. */
|
|
19
|
+
export declare function loadEmbeddingIndex(hippoRoot: string): Record<string, number[]>;
|
|
20
|
+
export interface StoredVectorSummary {
|
|
21
|
+
readonly ids: Set<string>;
|
|
22
|
+
readonly dims: number | undefined;
|
|
23
|
+
}
|
|
24
|
+
/** Every stored vector id and the float count of the first row, with no vector decoded. */
|
|
25
|
+
export declare function storedVectorSummary(hippoRoot: string): StoredVectorSummary;
|
|
26
|
+
/** Stored vectors for `ids` only. */
|
|
27
|
+
export declare function loadStoredVectors(hippoRoot: string, ids: readonly string[]): Map<string, number[]>;
|
|
28
|
+
/** `loadStoredVectors` as Float32 views, for a caller that only scores them. */
|
|
29
|
+
export declare function loadStoredVectorViews(hippoRoot: string, ids: readonly string[]): Map<string, Float32Array>;
|
|
30
|
+
/** Replace every stored vector with `index`; `model` defaults to the stored index identity. */
|
|
31
|
+
export declare function saveEmbeddingIndex(hippoRoot: string, index: Record<string, number[]>, model?: string): void;
|
|
32
|
+
/** Inserts or replaces `rows` under `model`, each row its own commit so a failure keeps the rows before it; returns how many it wrote. */
|
|
33
|
+
export declare function saveStoredVectors(hippoRoot: string, rows: Iterable<readonly [string, readonly number[]]>, model: string): number;
|
|
34
|
+
/** Drops the vectors of deleted memories under `hippoRoot`, then returns the ids that still have one. */
|
|
35
|
+
export declare function pruneStoredVectors(hippoRoot: string): Set<string>;
|
|
36
|
+
export declare function entriesWithoutVectorAt(db: DatabaseSyncLike, query: VectorBackfillQuery): MemoryEntry[];
|
|
37
|
+
export declare function writeVectorsAt(db: DatabaseSyncLike, write: VectorWrite): VectorWriteResult;
|
|
38
|
+
/** Every particle stored under `hippoRoot`. */
|
|
39
|
+
export declare function loadStoredParticles(hippoRoot: string): PhysicsParticle[];
|
|
40
|
+
/** Writes `particles` over their stored state under `hippoRoot`, as one batch. */
|
|
41
|
+
export declare function saveStoredParticles(hippoRoot: string, particles: PhysicsParticle[]): void;
|
|
42
|
+
/** Replaces every particle under `hippoRoot` with a fresh one per memory in `ids` that has an embedding; returns how many. Rows are read a page at a time. */
|
|
43
|
+
export declare function resetStoredParticles(hippoRoot: string, ids: readonly string[], embeddingIndex: Record<string, number[]>): number;
|
|
44
|
+
/** Stores a first particle for `entry`, placed at `vector`; a memory that has one keeps it. */
|
|
45
|
+
export declare function seedStoredParticle(hippoRoot: string, entry: MemoryEntry, vector: number[]): void;
|
|
46
|
+
//# sourceMappingURL=vector-index.d.ts.map
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
// Owns hippo.db's stored vectors, the identity of the model that built them, and the particle rows: every read and write of the three.
|
|
2
|
+
import { getMeta, setMeta, withWriteScope } from '../db/index.js';
|
|
3
|
+
import { onHandle } from './open.js';
|
|
4
|
+
import { DEFAULT_EMBEDDING_MODEL } from './embeddings/local.js';
|
|
5
|
+
import { float32ToBuffer, initializeParticle, loadPhysicsState, resetAllPhysicsState, savePhysicsState } from '../db/physics-state.js';
|
|
6
|
+
import { EMBEDDING_MODEL_META_KEY, deleteOrphanVectors, hasStoredVectors, loadVectors, loadVectorViews, replaceAllVectors, storedVectorDims, storedVectorIds, upsertVectors, } from '../db/vector-store.js';
|
|
7
|
+
import { chunked, selectEntriesByIds } from './entry-reads.js';
|
|
8
|
+
import { MEMORY_SELECT_COLUMNS, rowToEntry } from './rows.js';
|
|
9
|
+
const MAX_BACKFILL_PAGE = 500;
|
|
10
|
+
/** The model the index was built by: the stored identity, else the default model when vectors exist. */
|
|
11
|
+
export function indexedModel(state) {
|
|
12
|
+
return state.storedModel ?? (state.hasVectors ? DEFAULT_EMBEDDING_MODEL : null);
|
|
13
|
+
}
|
|
14
|
+
/** Whether a vector write under the index identity `model` first drops the stored index, which another model built. */
|
|
15
|
+
export function replacesIndex(state, model) {
|
|
16
|
+
const indexed = indexedModel(state);
|
|
17
|
+
return indexed !== null && indexed !== model;
|
|
18
|
+
}
|
|
19
|
+
function embeddingIndexStateOn(db) {
|
|
20
|
+
return {
|
|
21
|
+
storedModel: getMeta(db, EMBEDDING_MODEL_META_KEY, '').trim() || null,
|
|
22
|
+
hasVectors: hasStoredVectors(db),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/** hippo.db's index state, the meta row and the EXISTS on one handle. */
|
|
26
|
+
export function storedIndexState(hippoRoot) {
|
|
27
|
+
return onHandle(hippoRoot, (db) => {
|
|
28
|
+
return embeddingIndexStateOn(db);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
/** Records `identity` as what built the index under `hippoRoot`. */
|
|
32
|
+
export function saveIndexIdentity(hippoRoot, identity) {
|
|
33
|
+
onHandle(hippoRoot, (db) => {
|
|
34
|
+
setMeta(db, EMBEDDING_MODEL_META_KEY, identity);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/** Every stored vector keyed by memory id; `{}` when none. Search reads only the rows it ranks via `loadStoredVectors`. */
|
|
38
|
+
export function loadEmbeddingIndex(hippoRoot) {
|
|
39
|
+
return onHandle(hippoRoot, (db) => {
|
|
40
|
+
return Object.fromEntries(loadVectors(db));
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
/** Every stored vector id and the float count of the first row, with no vector decoded. */
|
|
44
|
+
export function storedVectorSummary(hippoRoot) {
|
|
45
|
+
return onHandle(hippoRoot, (db) => {
|
|
46
|
+
return { ids: storedVectorIds(db), dims: storedVectorDims(db) };
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/** Stored vectors for `ids` only. */
|
|
50
|
+
export function loadStoredVectors(hippoRoot, ids) {
|
|
51
|
+
if (ids.length === 0)
|
|
52
|
+
return new Map();
|
|
53
|
+
return onHandle(hippoRoot, (db) => {
|
|
54
|
+
return loadVectors(db, ids);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
/** `loadStoredVectors` as Float32 views, for a caller that only scores them. */
|
|
58
|
+
export function loadStoredVectorViews(hippoRoot, ids) {
|
|
59
|
+
if (ids.length === 0)
|
|
60
|
+
return new Map();
|
|
61
|
+
return onHandle(hippoRoot, (db) => {
|
|
62
|
+
return loadVectorViews(db, ids);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
/** Replace every stored vector with `index`; `model` defaults to the stored index identity. */
|
|
66
|
+
export function saveEmbeddingIndex(hippoRoot, index, model) {
|
|
67
|
+
onHandle(hippoRoot, (db) => {
|
|
68
|
+
replaceAllVectors(db, index, model ?? getMeta(db, EMBEDDING_MODEL_META_KEY, ''));
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
/** Inserts or replaces `rows` under `model`, each row its own commit so a failure keeps the rows before it; returns how many it wrote. */
|
|
72
|
+
export function saveStoredVectors(hippoRoot, rows, model) {
|
|
73
|
+
return onHandle(hippoRoot, (db) => {
|
|
74
|
+
return upsertVectors(db, rows, model);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
/** Drops the vectors of deleted memories under `hippoRoot`, then returns the ids that still have one. */
|
|
78
|
+
export function pruneStoredVectors(hippoRoot) {
|
|
79
|
+
return onHandle(hippoRoot, (db) => {
|
|
80
|
+
deleteOrphanVectors(db);
|
|
81
|
+
return storedVectorIds(db);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
export function entriesWithoutVectorAt(db, query) {
|
|
85
|
+
if (!Number.isInteger(query.limit))
|
|
86
|
+
throw new RangeError('limit must be an integer');
|
|
87
|
+
const limit = Math.max(1, Math.min(query.limit, MAX_BACKFILL_PAGE));
|
|
88
|
+
const tenantClause = query.tenantId === undefined ? '' : ' AND tenant_id = ?';
|
|
89
|
+
const tenantArgs = query.tenantId === undefined ? [] : [query.tenantId];
|
|
90
|
+
// SAFETY: selects exactly MEMORY_SELECT_COLUMNS, matching MemoryRow's field set.
|
|
91
|
+
const rows = db.prepare(`SELECT ${MEMORY_SELECT_COLUMNS} FROM memories WHERE id > ?${tenantClause}
|
|
92
|
+
AND NOT EXISTS (SELECT 1 FROM memory_vectors v WHERE v.memory_id = memories.id AND v.model = ?)
|
|
93
|
+
ORDER BY id LIMIT ?`).all(query.afterId ?? '', ...tenantArgs, query.model, limit);
|
|
94
|
+
return rows.map(rowToEntry);
|
|
95
|
+
}
|
|
96
|
+
function ownedIds(db, ids, tenantId) {
|
|
97
|
+
const owned = new Set();
|
|
98
|
+
for (const chunk of chunked([...new Set(ids)])) {
|
|
99
|
+
// SAFETY: the SELECT names one column, id.
|
|
100
|
+
const rows = db.prepare(`SELECT id FROM memories WHERE +tenant_id = ? AND id IN (${chunk.map(() => '?').join(', ')})`).all(tenantId, ...chunk);
|
|
101
|
+
for (const row of rows)
|
|
102
|
+
owned.add(row.id);
|
|
103
|
+
}
|
|
104
|
+
return owned;
|
|
105
|
+
}
|
|
106
|
+
// savePhysicsState opens its own transaction and overwrites, so the first particle for a memory is inserted here instead.
|
|
107
|
+
function insertNewParticles(db, rows) {
|
|
108
|
+
const stmt = db.prepare(`
|
|
109
|
+
INSERT INTO memory_physics (memory_id, position_blob, velocity_blob, mass, charge, temperature, last_simulation)
|
|
110
|
+
VALUES (?, ?, ?, ?, ?, ?, ?) ON CONFLICT(memory_id) DO NOTHING
|
|
111
|
+
`);
|
|
112
|
+
for (const { memoryId, particle: p } of rows) {
|
|
113
|
+
if (p)
|
|
114
|
+
stmt.run(memoryId, float32ToBuffer(p.position), float32ToBuffer(p.velocity), p.mass, p.charge, p.temperature, p.lastSimulation);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
export function writeVectorsAt(db, write) {
|
|
118
|
+
return withWriteScope(db, 'write_vectors', () => {
|
|
119
|
+
const replaces = replacesIndex(embeddingIndexStateOn(db), write.model);
|
|
120
|
+
if (replaces && !write.replaceIndex)
|
|
121
|
+
return { written: 0, modelMismatch: true };
|
|
122
|
+
const owned = ownedIds(db, write.rows.map((r) => r.memoryId), write.tenantId);
|
|
123
|
+
const rows = write.rows.filter((r) => owned.has(r.memoryId) && r.vector.length > 0 && r.vector.every(Number.isFinite));
|
|
124
|
+
if (rows.length === 0)
|
|
125
|
+
return { written: 0, modelMismatch: false };
|
|
126
|
+
if (replaces)
|
|
127
|
+
db.exec('DELETE FROM memory_vectors; DELETE FROM memory_physics;');
|
|
128
|
+
const written = upsertVectors(db, rows.map((r) => [r.memoryId, r.vector]), write.model);
|
|
129
|
+
insertNewParticles(db, rows);
|
|
130
|
+
setMeta(db, EMBEDDING_MODEL_META_KEY, write.model);
|
|
131
|
+
return { written, modelMismatch: false };
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
/** Every particle stored under `hippoRoot`. */
|
|
135
|
+
export function loadStoredParticles(hippoRoot) {
|
|
136
|
+
return onHandle(hippoRoot, (db) => {
|
|
137
|
+
return Array.from(loadPhysicsState(db).values());
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
/** Writes `particles` over their stored state under `hippoRoot`, as one batch. */
|
|
141
|
+
export function saveStoredParticles(hippoRoot, particles) {
|
|
142
|
+
onHandle(hippoRoot, (db) => {
|
|
143
|
+
savePhysicsState(db, particles);
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
const PARTICLE_PAGE = 64;
|
|
147
|
+
function* entriesInPages(db, ids) {
|
|
148
|
+
for (const page of chunked(ids, PARTICLE_PAGE)) {
|
|
149
|
+
const rows = selectEntriesByIds(db, page);
|
|
150
|
+
for (const id of page) {
|
|
151
|
+
const entry = rows.get(id);
|
|
152
|
+
if (entry)
|
|
153
|
+
yield entry;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/** Replaces every particle under `hippoRoot` with a fresh one per memory in `ids` that has an embedding; returns how many. Rows are read a page at a time. */
|
|
158
|
+
export function resetStoredParticles(hippoRoot, ids, embeddingIndex) {
|
|
159
|
+
return onHandle(hippoRoot, (db) => {
|
|
160
|
+
return resetAllPhysicsState(db, entriesInPages(db, ids), embeddingIndex);
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
/** Stores a first particle for `entry`, placed at `vector`; a memory that has one keeps it. */
|
|
164
|
+
export function seedStoredParticle(hippoRoot, entry, vector) {
|
|
165
|
+
onHandle(hippoRoot, (db) => {
|
|
166
|
+
if (!loadPhysicsState(db, [entry.id]).has(entry.id))
|
|
167
|
+
savePhysicsState(db, [initializeParticle(entry, vector)]);
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=vector-index.js.map
|
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Working Memory — bounded buffer for current-state notes.
|
|
3
|
-
*
|
|
4
|
-
* Separate from long-term semantic memory. Entries are scoped,
|
|
5
|
-
* importance-ranked, and automatically evicted when the buffer
|
|
6
|
-
* exceeds WM_MAX_ENTRIES per scope.
|
|
7
|
-
*/
|
|
1
|
+
/** Working Memory: bounded buffer for current-state notes, separate from long-term memory; scoped, importance-ranked, evicted past WM_MAX_ENTRIES per scope. */
|
|
8
2
|
import type { JsonValue } from '../util/json.js';
|
|
9
3
|
export declare const WM_MAX_ENTRIES = 20;
|
|
10
4
|
export type JsonObject = {
|
|
@@ -21,12 +15,8 @@ export interface WorkingMemoryItem {
|
|
|
21
15
|
createdAt: string;
|
|
22
16
|
updatedAt: string;
|
|
23
17
|
}
|
|
24
|
-
/**
|
|
25
|
-
*
|
|
26
|
-
* If the scope exceeds WM_MAX_ENTRIES, the lowest-importance entry
|
|
27
|
-
* is evicted (ties broken by oldest created_at).
|
|
28
|
-
* Returns the new row ID.
|
|
29
|
-
*/
|
|
18
|
+
/** Push a new entry into working memory; past WM_MAX_ENTRIES the scope's lowest-importance entry is evicted (ties: oldest created_at). Returns the new
|
|
19
|
+
* row ID. */
|
|
30
20
|
export declare function wmPush(hippoRoot: string, opts: {
|
|
31
21
|
scope: string;
|
|
32
22
|
content: string;
|
|
@@ -36,29 +26,20 @@ export declare function wmPush(hippoRoot: string, opts: {
|
|
|
36
26
|
metadata?: JsonObject;
|
|
37
27
|
tenantId?: string;
|
|
38
28
|
}): number;
|
|
39
|
-
/**
|
|
40
|
-
* Read working memory entries, sorted by importance DESC.
|
|
41
|
-
*/
|
|
29
|
+
/** Read working memory entries, sorted by importance DESC. */
|
|
42
30
|
export declare function wmRead(hippoRoot: string, opts?: {
|
|
43
31
|
scope?: string;
|
|
44
32
|
sessionId?: string;
|
|
45
33
|
limit?: number;
|
|
46
34
|
tenantId?: string;
|
|
47
35
|
}): WorkingMemoryItem[];
|
|
48
|
-
/**
|
|
49
|
-
* Clear (delete) working memory entries. Returns the count deleted.
|
|
50
|
-
*/
|
|
36
|
+
/** Clear (delete) working memory entries. Returns the count deleted. */
|
|
51
37
|
export declare function wmClear(hippoRoot: string, opts?: {
|
|
52
38
|
scope?: string;
|
|
53
39
|
sessionId?: string;
|
|
54
40
|
tenantId?: string;
|
|
55
41
|
}): number;
|
|
56
|
-
/**
|
|
57
|
-
* Flush working memory — delete entries after session end.
|
|
58
|
-
* Functionally identical to wmClear but semantically distinct:
|
|
59
|
-
* used at session boundaries to discard ephemeral state.
|
|
60
|
-
* Returns the count flushed.
|
|
61
|
-
*/
|
|
42
|
+
/** Flush working memory after session end: same as wmClear, but marks the session-boundary discard of ephemeral state. Returns the count flushed. */
|
|
62
43
|
export declare function wmFlush(hippoRoot: string, opts?: {
|
|
63
44
|
scope?: string;
|
|
64
45
|
sessionId?: string;
|
|
@@ -1,21 +1,14 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
* Separate from long-term semantic memory. Entries are scoped,
|
|
5
|
-
* importance-ranked, and automatically evicted when the buffer
|
|
6
|
-
* exceeds WM_MAX_ENTRIES per scope.
|
|
7
|
-
*/
|
|
8
|
-
import { closeHippoDb, withWriteScope } from '../db/index.js';
|
|
9
|
-
import { openStore } from './open.js';
|
|
1
|
+
/** Working Memory: bounded buffer for current-state notes, separate from long-term memory; scoped, importance-ranked, evicted past WM_MAX_ENTRIES per scope. */
|
|
2
|
+
import { withWriteScope } from '../db/index.js';
|
|
3
|
+
import { onHandle, openStore } from './open.js';
|
|
10
4
|
import { warnDamagedColumn } from '../util/stored-json.js';
|
|
11
5
|
import { resolveTenantId } from './tenant.js';
|
|
12
6
|
export const WM_MAX_ENTRIES = 20;
|
|
13
7
|
function rowToItem(row) {
|
|
14
8
|
let metadata = {};
|
|
15
9
|
try {
|
|
16
|
-
// SAFETY: metadata_json is always written by wmPush via
|
|
17
|
-
//
|
|
18
|
-
// plain JSON object; malformed content falls through to the catch below.
|
|
10
|
+
// SAFETY: metadata_json is always written by wmPush via JSON.stringify(opts.metadata ?? {}), so a successful parse yields a plain JSON object;
|
|
11
|
+
// malformed content falls through to the catch below.
|
|
19
12
|
metadata = JSON.parse(row.metadata_json);
|
|
20
13
|
}
|
|
21
14
|
catch {
|
|
@@ -34,15 +27,10 @@ function rowToItem(row) {
|
|
|
34
27
|
updatedAt: row.updated_at,
|
|
35
28
|
};
|
|
36
29
|
}
|
|
37
|
-
/**
|
|
38
|
-
*
|
|
39
|
-
* If the scope exceeds WM_MAX_ENTRIES, the lowest-importance entry
|
|
40
|
-
* is evicted (ties broken by oldest created_at).
|
|
41
|
-
* Returns the new row ID.
|
|
42
|
-
*/
|
|
30
|
+
/** Push a new entry into working memory; past WM_MAX_ENTRIES the scope's lowest-importance entry is evicted (ties: oldest created_at). Returns the new
|
|
31
|
+
* row ID. */
|
|
43
32
|
export function wmPush(hippoRoot, opts) {
|
|
44
|
-
|
|
45
|
-
try {
|
|
33
|
+
return onHandle(hippoRoot, (db) => {
|
|
46
34
|
const now = new Date().toISOString();
|
|
47
35
|
const importance = opts.importance ?? 0;
|
|
48
36
|
const tenantId = opts.tenantId ?? resolveTenantId({});
|
|
@@ -55,16 +43,11 @@ export function wmPush(hippoRoot, opts) {
|
|
|
55
43
|
evictOverCapacity(db, opts.scope, tenantId);
|
|
56
44
|
return id;
|
|
57
45
|
});
|
|
58
|
-
}
|
|
59
|
-
finally {
|
|
60
|
-
closeHippoDb(db);
|
|
61
|
-
}
|
|
46
|
+
}, openStore);
|
|
62
47
|
}
|
|
63
48
|
function evictOverCapacity(db, scope, tenantId) {
|
|
64
|
-
// Evict if over capacity for this scope
|
|
65
|
-
// SAFETY: `COUNT(*) AS cnt`
|
|
66
|
-
// one row shaped { cnt }; .get() returns undefined only if the driver
|
|
67
|
-
// yields no row, which COUNT(*) never does.
|
|
49
|
+
// Evict if over capacity for this scope.
|
|
50
|
+
// SAFETY: `COUNT(*) AS cnt` always returns exactly one row { cnt }, so `.get()` never yields undefined.
|
|
68
51
|
const countRow = db.prepare(`
|
|
69
52
|
SELECT COUNT(*) AS cnt FROM working_memory WHERE scope = ? AND tenant_id = ?
|
|
70
53
|
`).get(scope, tenantId);
|
|
@@ -82,12 +65,9 @@ function evictOverCapacity(db, scope, tenantId) {
|
|
|
82
65
|
`).run(scope, tenantId, excess);
|
|
83
66
|
}
|
|
84
67
|
}
|
|
85
|
-
/**
|
|
86
|
-
* Read working memory entries, sorted by importance DESC.
|
|
87
|
-
*/
|
|
68
|
+
/** Read working memory entries, sorted by importance DESC. */
|
|
88
69
|
export function wmRead(hippoRoot, opts) {
|
|
89
|
-
|
|
90
|
-
try {
|
|
70
|
+
return onHandle(hippoRoot, (db) => {
|
|
91
71
|
const clauses = ['tenant_id = ?'];
|
|
92
72
|
const params = [opts?.tenantId ?? resolveTenantId({})];
|
|
93
73
|
if (opts?.scope) {
|
|
@@ -111,17 +91,11 @@ export function wmRead(hippoRoot, opts) {
|
|
|
111
91
|
LIMIT ?
|
|
112
92
|
`).all(...params);
|
|
113
93
|
return rows.map(rowToItem);
|
|
114
|
-
}
|
|
115
|
-
finally {
|
|
116
|
-
closeHippoDb(db);
|
|
117
|
-
}
|
|
94
|
+
}, openStore);
|
|
118
95
|
}
|
|
119
|
-
/**
|
|
120
|
-
* Clear (delete) working memory entries. Returns the count deleted.
|
|
121
|
-
*/
|
|
96
|
+
/** Clear (delete) working memory entries. Returns the count deleted. */
|
|
122
97
|
export function wmClear(hippoRoot, opts) {
|
|
123
|
-
|
|
124
|
-
try {
|
|
98
|
+
return onHandle(hippoRoot, (db) => {
|
|
125
99
|
const clauses = ['tenant_id = ?'];
|
|
126
100
|
const params = [opts?.tenantId ?? resolveTenantId({})];
|
|
127
101
|
if (opts?.scope) {
|
|
@@ -135,17 +109,9 @@ export function wmClear(hippoRoot, opts) {
|
|
|
135
109
|
const where = clauses.length > 0 ? `WHERE ${clauses.join(' AND ')}` : '';
|
|
136
110
|
const result = db.prepare(`DELETE FROM working_memory ${where}`).run(...params);
|
|
137
111
|
return Number(result.changes ?? 0);
|
|
138
|
-
}
|
|
139
|
-
finally {
|
|
140
|
-
closeHippoDb(db);
|
|
141
|
-
}
|
|
112
|
+
}, openStore);
|
|
142
113
|
}
|
|
143
|
-
/**
|
|
144
|
-
* Flush working memory — delete entries after session end.
|
|
145
|
-
* Functionally identical to wmClear but semantically distinct:
|
|
146
|
-
* used at session boundaries to discard ephemeral state.
|
|
147
|
-
* Returns the count flushed.
|
|
148
|
-
*/
|
|
114
|
+
/** Flush working memory after session end: same as wmClear, but marks the session-boundary discard of ephemeral state. Returns the count flushed. */
|
|
149
115
|
export function wmFlush(hippoRoot, opts) {
|
|
150
116
|
return wmClear(hippoRoot, opts);
|
|
151
117
|
}
|
package/dist/store/yaml.d.ts
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Minimal YAML frontmatter serializer/deserializer.
|
|
3
|
-
* No external deps. Handles simple key-value + arrays (inline only).
|
|
4
|
-
* Sufficient for the MemoryEntry frontmatter schema.
|
|
5
|
-
*/
|
|
1
|
+
/** Minimal YAML frontmatter serializer/deserializer with no external deps: simple key-value pairs and inline arrays, enough for the MemoryEntry schema. */
|
|
6
2
|
type YamlValue = string | number | boolean | null | string[] | number[];
|
|
7
3
|
export declare function dumpFrontmatter(obj: Record<string, YamlValue>): string;
|
|
8
4
|
export interface ParsedFrontmatter {
|
package/dist/store/yaml.js
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Minimal YAML frontmatter serializer/deserializer.
|
|
3
|
-
* No external deps. Handles simple key-value + arrays (inline only).
|
|
4
|
-
* Sufficient for the MemoryEntry frontmatter schema.
|
|
5
|
-
*/
|
|
1
|
+
/** Minimal YAML frontmatter serializer/deserializer with no external deps: simple key-value pairs and inline arrays, enough for the MemoryEntry schema. */
|
|
6
2
|
const SCALAR_LOOKALIKE = /^(null|true|false|-?\d+(\.\d+)?)$/;
|
|
7
3
|
const UNESCAPES = new Map([['\\', '\\'], ['"', '"'], ['n', '\n'], ['r', '\r']]);
|
|
8
4
|
function escapeString(s) {
|
|
9
5
|
// A string that reads as null, a boolean or a number is quoted so it comes back a string.
|
|
10
|
-
if (/[
|
|
6
|
+
if (/[:#[\]{},\n\r"']/.test(s) || s.trim() !== s || s === '' || SCALAR_LOOKALIKE.test(s)) {
|
|
11
7
|
const escaped = s.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n').replace(/\r/g, '\\r');
|
|
12
8
|
return `"${escaped}"`;
|
|
13
9
|
}
|
package/dist/support-bundle.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
/** `hippo support-bundle`: one redacted JSON snapshot for a support ticket. Read-only
|
|
1
|
+
/** `hippo support-bundle`: one redacted JSON snapshot for a support ticket. Read-only
|
|
2
|
+
* (SQLite may leave empty -wal and -shm files); never touches memory content. */
|
|
2
3
|
import { envByName, processEnv } from './util/env.js';
|
|
3
4
|
import * as fs from 'fs';
|
|
4
5
|
import * as os from 'os';
|
|
@@ -6,7 +7,7 @@ import * as path from 'path';
|
|
|
6
7
|
import { pathToFileURL } from 'url';
|
|
7
8
|
import { findHippoStoreDir, isGlobalStoreRoot } from './core/project-identity.js';
|
|
8
9
|
import { realpathOrResolve } from './util/real-path.js';
|
|
9
|
-
import { getGlobalRoot } from './sharing/
|
|
10
|
+
import { getGlobalRoot } from './sharing/global-store.js';
|
|
10
11
|
import { isInitialized } from './store/open.js';
|
|
11
12
|
import { readStoreInventory } from './store/diagnostics.js';
|
|
12
13
|
import { runDoctor } from './doctor.js';
|
|
@@ -117,12 +118,13 @@ function listLogFileNames(dir) {
|
|
|
117
118
|
.sort();
|
|
118
119
|
}
|
|
119
120
|
function tailLogFile(file) {
|
|
120
|
-
const size = fs.statSync(file).size;
|
|
121
|
-
const readSize = Math.min(size, TAIL_MAX_BYTES);
|
|
122
|
-
const startedMidFile = size > TAIL_MAX_BYTES;
|
|
123
121
|
const fd = fs.openSync(file, 'r');
|
|
124
122
|
let text;
|
|
123
|
+
let startedMidFile;
|
|
125
124
|
try {
|
|
125
|
+
const size = fs.fstatSync(fd).size;
|
|
126
|
+
const readSize = Math.min(size, TAIL_MAX_BYTES);
|
|
127
|
+
startedMidFile = size > TAIL_MAX_BYTES;
|
|
126
128
|
const buf = Buffer.alloc(readSize);
|
|
127
129
|
fs.readSync(fd, buf, 0, readSize, size - readSize);
|
|
128
130
|
text = buf.toString('utf8');
|
|
@@ -18,9 +18,7 @@ function assertRejectOpts(opts) {
|
|
|
18
18
|
throw new Error('reject accepts either a memory id or --value, not both.');
|
|
19
19
|
}
|
|
20
20
|
if (opts.value !== undefined && normalizeValueForRejection(opts.value).length === 0) {
|
|
21
|
-
// Direct api callers can pass strings the CLI flag parser would
|
|
22
|
-
// refused; an empty-normalized tombstone would refuse nothing meaningful
|
|
23
|
-
// and pollute the listing.
|
|
21
|
+
// Direct api callers can pass strings the CLI flag parser would refuse; an empty-normalized tombstone would refuse nothing and pollute the listing.
|
|
24
22
|
throw new Error('reject --value requires non-empty content.');
|
|
25
23
|
}
|
|
26
24
|
}
|
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
/** The one Anthropic Messages client: sends one user prompt and returns the reply text or a typed failure the caller reacts to. */
|
|
2
2
|
import { fetchWithRetry, llmTimeoutMs } from './http-retry.js';
|
|
3
3
|
import { errorMessage } from './log.js';
|
|
4
|
+
import { readCappedJson } from './capped-json.js';
|
|
5
|
+
import { isJsonObject, isJsonString } from './json.js';
|
|
4
6
|
const MESSAGES_URL = 'https://api.anthropic.com/v1/messages';
|
|
5
7
|
const API_VERSION = '2023-06-01';
|
|
6
8
|
const DEFAULT_MODEL = 'claude-sonnet-4-6';
|
|
9
|
+
// Callers ask for at most 1,200 tokens, a reply of a few KB; 1 MiB leaves room for a verbose envelope.
|
|
10
|
+
const MAX_REPLY_BYTES = 1024 * 1024;
|
|
11
|
+
/** The first content block's text, trimmed; empty when the reply has no such block. */
|
|
12
|
+
function firstText(reply) {
|
|
13
|
+
const first = Array.isArray(reply.content) ? reply.content[0] : undefined;
|
|
14
|
+
const text = isJsonObject(first) ? first.text : undefined;
|
|
15
|
+
return isJsonString(text) ? text.trim() : '';
|
|
16
|
+
}
|
|
7
17
|
/** The reply's first text block, trimmed (empty when the reply has none); never throws. */
|
|
8
18
|
export async function sendAnthropicMessage(req) {
|
|
9
19
|
let res;
|
|
@@ -28,8 +38,10 @@ export async function sendAnthropicMessage(req) {
|
|
|
28
38
|
if (!res.ok)
|
|
29
39
|
return { ok: false, failure: { kind: 'http', status: res.status } };
|
|
30
40
|
try {
|
|
31
|
-
const data = await res
|
|
32
|
-
|
|
41
|
+
const data = await readCappedJson(res, MAX_REPLY_BYTES);
|
|
42
|
+
if (!isJsonObject(data))
|
|
43
|
+
return { ok: false, failure: { kind: 'unreadable', message: 'the reply is not a JSON object' } };
|
|
44
|
+
return { ok: true, text: firstText(data) };
|
|
33
45
|
}
|
|
34
46
|
catch (err) {
|
|
35
47
|
return { ok: false, failure: { kind: 'unreadable', message: errorMessage(err) } };
|