hippo-memory 1.60.0 → 1.62.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 +29 -54
- package/dist/ablation.js +9 -27
- package/dist/agent-memories/apply.d.ts +1 -1
- package/dist/agent-memories/apply.js +4 -1
- package/dist/agent-memories/claude-code.d.ts +3 -1
- package/dist/agent-memories/claude-code.js +54 -10
- package/dist/agent-memories/codex.js +1 -1
- package/dist/agent-memories/gemini.js +1 -1
- package/dist/agent-memories/legacy.js +1 -1
- package/dist/agent-memories/source.js +1 -1
- package/dist/agent-memories/sync.d.ts +3 -3
- package/dist/agent-memories/sync.js +22 -9
- package/dist/agent-memories/types.d.ts +0 -2
- package/dist/ambient-store.d.ts +14 -0
- package/dist/ambient-store.js +90 -0
- package/dist/ambient.d.ts +23 -0
- package/dist/ambient.js +72 -50
- package/dist/api/assemble.d.ts +93 -0
- package/dist/api/assemble.js +153 -0
- package/dist/api/audit.d.ts +17 -0
- package/dist/api/audit.js +23 -0
- package/dist/api/auth.d.ts +79 -0
- package/dist/api/auth.js +178 -0
- package/dist/api/context-select.d.ts +49 -0
- package/dist/api/context-select.js +344 -0
- package/dist/api/context-types.d.ts +105 -0
- package/dist/api/context-types.js +3 -0
- package/dist/api/context.d.ts +31 -0
- package/dist/api/context.js +378 -0
- package/dist/api/dormant.d.ts +30 -0
- package/dist/api/dormant.js +140 -0
- package/dist/api/drill-down.d.ts +84 -0
- package/dist/api/drill-down.js +126 -0
- package/dist/api/forget.d.ts +57 -0
- package/dist/api/forget.js +87 -0
- package/dist/api/goals.d.ts +18 -0
- package/dist/api/goals.js +33 -0
- package/dist/api/learn.d.ts +31 -0
- package/dist/api/learn.js +88 -0
- package/dist/api/outcome.d.ts +61 -0
- package/dist/api/outcome.js +66 -0
- package/dist/api/promote.d.ts +54 -0
- package/dist/api/promote.js +192 -0
- package/dist/api/quarantine.d.ts +24 -0
- package/dist/api/quarantine.js +121 -0
- package/dist/api/recall-types.d.ts +390 -0
- package/dist/api/recall-types.js +3 -0
- package/dist/api/recall.d.ts +36 -0
- package/dist/api/recall.js +499 -0
- package/dist/api/remember.d.ts +35 -0
- package/dist/api/remember.js +43 -0
- package/dist/api/sleep.d.ts +136 -0
- package/dist/api/sleep.js +256 -0
- package/dist/api/tokens.d.ts +26 -0
- package/dist/api/tokens.js +60 -0
- package/dist/api/types.d.ts +56 -0
- package/dist/api/types.js +38 -0
- package/dist/api.d.ts +20 -1262
- package/dist/api.js +25 -2727
- package/dist/audit.d.ts +3 -0
- package/dist/audit.js +6 -3
- package/dist/auth.d.ts +45 -4
- package/dist/auth.js +125 -48
- package/dist/autolearn.js +2 -2
- package/dist/capture/command.d.ts +33 -0
- package/dist/capture/command.js +264 -0
- package/dist/capture/compact.d.ts +44 -0
- package/dist/capture/compact.js +354 -0
- package/dist/capture/extract.d.ts +21 -0
- package/dist/capture/extract.js +464 -0
- package/dist/capture/transcript.d.ts +40 -0
- package/dist/capture/transcript.js +193 -0
- package/dist/capture-error.js +2 -1
- package/dist/churn-git.js +4 -2
- package/dist/cli/audit.d.ts +3 -0
- package/dist/cli/audit.js +159 -0
- package/dist/cli/auth.d.ts +2 -0
- package/dist/cli/auth.js +171 -0
- package/dist/cli/briefs.d.ts +4 -0
- package/dist/cli/briefs.js +453 -0
- package/dist/cli/card.d.ts +3 -0
- package/dist/cli/card.js +333 -0
- package/dist/cli/context.d.ts +15 -0
- package/dist/cli/context.js +376 -0
- package/dist/cli/continuity.d.ts +6 -0
- package/dist/cli/continuity.js +457 -0
- package/dist/cli/curate.d.ts +19 -0
- package/dist/cli/curate.js +556 -0
- package/dist/cli/dag.d.ts +5 -0
- package/dist/cli/dag.js +177 -0
- package/dist/cli/decisions.d.ts +4 -0
- package/dist/cli/decisions.js +528 -0
- package/dist/cli/eval.d.ts +5 -0
- package/dist/cli/eval.js +213 -0
- package/dist/cli/explain.d.ts +4 -0
- package/dist/cli/explain.js +156 -0
- package/dist/cli/goals.d.ts +2 -0
- package/dist/cli/goals.js +196 -0
- package/dist/cli/hook-blocks.d.ts +18 -0
- package/dist/cli/hook-blocks.js +233 -0
- package/dist/cli/init.d.ts +2 -0
- package/dist/cli/init.js +305 -0
- package/dist/cli/maintenance.d.ts +4 -0
- package/dist/cli/maintenance.js +190 -0
- package/dist/cli/playbooks.d.ts +4 -0
- package/dist/cli/playbooks.js +573 -0
- package/dist/cli/projects.js +9 -6
- package/dist/cli/recall.d.ts +7 -0
- package/dist/cli/recall.js +582 -0
- package/dist/cli/remember.d.ts +5 -0
- package/dist/cli/remember.js +485 -0
- package/dist/cli/serve.d.ts +5 -0
- package/dist/cli/serve.js +40 -0
- package/dist/cli/session-hooks.d.ts +29 -0
- package/dist/cli/session-hooks.js +647 -0
- package/dist/cli/setup.d.ts +4 -0
- package/dist/cli/setup.js +397 -0
- package/dist/cli/shared.d.ts +15 -19
- package/dist/cli/shared.js +50 -341
- package/dist/cli/slack.d.ts +2 -0
- package/dist/cli/slack.js +171 -0
- package/dist/cli/status.d.ts +18 -0
- package/dist/cli/status.js +409 -0
- package/dist/cli/transfer.d.ts +10 -0
- package/dist/cli/transfer.js +424 -0
- package/dist/cli/usage.d.ts +85 -0
- package/dist/cli/usage.js +741 -0
- package/dist/cli.d.ts +71 -120
- package/dist/cli.js +170 -8469
- package/dist/client.js +15 -8
- package/dist/compaction-record.d.ts +0 -2
- package/dist/compaction-record.js +7 -5
- package/dist/connectors/github/backfill.js +94 -87
- package/dist/connectors/github/cli-impl.js +4 -3
- package/dist/connectors/github/dlq.js +67 -54
- package/dist/connectors/github/ingest.js +34 -35
- package/dist/connectors/github/tenant-routing.js +3 -2
- package/dist/connectors/github/webhook.js +135 -216
- package/dist/connectors/slack/dlq.js +49 -61
- package/dist/connectors/slack/ingest.js +55 -48
- package/dist/connectors/slack/tenant-routing.js +4 -3
- package/dist/connectors/slack/webhook.js +72 -74
- package/dist/consolidate/conflicts.d.ts +10 -0
- package/dist/consolidate/conflicts.js +178 -0
- package/dist/consolidate/decay.d.ts +12 -0
- package/dist/consolidate/decay.js +145 -0
- package/dist/consolidate/llm-passes.d.ts +3 -0
- package/dist/consolidate/llm-passes.js +141 -0
- package/dist/consolidate/merge.d.ts +7 -0
- package/dist/consolidate/merge.js +251 -0
- package/dist/consolidate/physics-pass.d.ts +3 -0
- package/dist/consolidate/physics-pass.js +60 -0
- package/dist/consolidate/run.d.ts +69 -0
- package/dist/consolidate/run.js +76 -0
- package/dist/consolidate/sleep.d.ts +18 -0
- package/dist/consolidate/sleep.js +209 -0
- package/dist/consolidate/traces.d.ts +4 -0
- package/dist/consolidate/traces.js +178 -0
- package/dist/context-auto.js +7 -11
- package/dist/context-render.d.ts +1 -1
- package/dist/context-render.js +1 -1
- package/dist/customer-notes.d.ts +3 -0
- package/dist/customer-notes.js +83 -72
- package/dist/dag.js +225 -188
- package/dist/dashboard-actions.d.ts +20 -0
- package/dist/dashboard-actions.js +88 -0
- package/dist/dashboard-params.d.ts +45 -0
- package/dist/dashboard-params.js +127 -0
- package/dist/dashboard-queries.d.ts +15 -0
- package/dist/dashboard-queries.js +355 -0
- package/dist/dashboard-snapshot.d.ts +138 -0
- package/dist/dashboard-snapshot.js +308 -0
- package/dist/dashboard-types.d.ts +163 -0
- package/dist/dashboard-types.js +3 -0
- package/dist/dashboard.d.ts +6 -7
- package/dist/dashboard.js +228 -202
- package/dist/db/busy.d.ts +5 -0
- package/dist/db/busy.js +24 -0
- package/dist/db/continuity.d.ts +5 -0
- package/dist/db/continuity.js +145 -0
- package/dist/db/meta.d.ts +8 -0
- package/dist/db/meta.js +35 -0
- package/dist/db/migrate.d.ts +9 -0
- package/dist/db/migrate.js +138 -0
- package/dist/db/migrations/index.d.ts +5 -0
- package/dist/db/migrations/index.js +109 -0
- package/dist/db/migrations/types.d.ts +14 -0
- package/dist/db/migrations/types.js +2 -0
- package/dist/db/migrations/v01.d.ts +3 -0
- package/dist/db/migrations/v01.js +38 -0
- package/dist/db/migrations/v02.d.ts +3 -0
- package/dist/db/migrations/v02.js +21 -0
- package/dist/db/migrations/v03.d.ts +3 -0
- package/dist/db/migrations/v03.js +22 -0
- package/dist/db/migrations/v04.d.ts +3 -0
- package/dist/db/migrations/v04.js +28 -0
- package/dist/db/migrations/v05.d.ts +3 -0
- package/dist/db/migrations/v05.js +21 -0
- package/dist/db/migrations/v06.d.ts +3 -0
- package/dist/db/migrations/v06.js +25 -0
- package/dist/db/migrations/v07.d.ts +3 -0
- package/dist/db/migrations/v07.js +13 -0
- package/dist/db/migrations/v08.d.ts +3 -0
- package/dist/db/migrations/v08.js +8 -0
- package/dist/db/migrations/v09.d.ts +3 -0
- package/dist/db/migrations/v09.js +13 -0
- package/dist/db/migrations/v10.d.ts +3 -0
- package/dist/db/migrations/v10.js +17 -0
- package/dist/db/migrations/v11.d.ts +3 -0
- package/dist/db/migrations/v11.js +15 -0
- package/dist/db/migrations/v12.d.ts +3 -0
- package/dist/db/migrations/v12.js +11 -0
- package/dist/db/migrations/v13.d.ts +3 -0
- package/dist/db/migrations/v13.js +15 -0
- package/dist/db/migrations/v14.d.ts +3 -0
- package/dist/db/migrations/v14.js +66 -0
- package/dist/db/migrations/v15.d.ts +3 -0
- package/dist/db/migrations/v15.js +42 -0
- package/dist/db/migrations/v16.d.ts +3 -0
- package/dist/db/migrations/v16.js +61 -0
- package/dist/db/migrations/v17.d.ts +3 -0
- package/dist/db/migrations/v17.js +46 -0
- package/dist/db/migrations/v18.d.ts +3 -0
- package/dist/db/migrations/v18.js +60 -0
- package/dist/db/migrations/v19.d.ts +3 -0
- package/dist/db/migrations/v19.js +28 -0
- package/dist/db/migrations/v20.d.ts +3 -0
- package/dist/db/migrations/v20.js +42 -0
- package/dist/db/migrations/v21.d.ts +3 -0
- package/dist/db/migrations/v21.js +16 -0
- package/dist/db/migrations/v22.d.ts +3 -0
- package/dist/db/migrations/v22.js +82 -0
- package/dist/db/migrations/v23.d.ts +3 -0
- package/dist/db/migrations/v23.js +48 -0
- package/dist/db/migrations/v24.d.ts +3 -0
- package/dist/db/migrations/v24.js +72 -0
- package/dist/db/migrations/v25.d.ts +3 -0
- package/dist/db/migrations/v25.js +46 -0
- package/dist/db/migrations/v26.d.ts +3 -0
- package/dist/db/migrations/v26.js +23 -0
- package/dist/db/migrations/v27.d.ts +3 -0
- package/dist/db/migrations/v27.js +57 -0
- package/dist/db/migrations/v28.d.ts +3 -0
- package/dist/db/migrations/v28.js +38 -0
- package/dist/db/migrations/v29.d.ts +3 -0
- package/dist/db/migrations/v29.js +78 -0
- package/dist/db/migrations/v30.d.ts +3 -0
- package/dist/db/migrations/v30.js +92 -0
- package/dist/db/migrations/v31.d.ts +3 -0
- package/dist/db/migrations/v31.js +74 -0
- package/dist/db/migrations/v32.d.ts +3 -0
- package/dist/db/migrations/v32.js +102 -0
- package/dist/db/migrations/v33.d.ts +3 -0
- package/dist/db/migrations/v33.js +104 -0
- package/dist/db/migrations/v34.d.ts +3 -0
- package/dist/db/migrations/v34.js +93 -0
- package/dist/db/migrations/v35.d.ts +3 -0
- package/dist/db/migrations/v35.js +98 -0
- package/dist/db/migrations/v36.d.ts +3 -0
- package/dist/db/migrations/v36.js +98 -0
- package/dist/db/migrations/v37.d.ts +3 -0
- package/dist/db/migrations/v37.js +219 -0
- package/dist/db/migrations/v38.d.ts +3 -0
- package/dist/db/migrations/v38.js +277 -0
- package/dist/db/migrations/v39.d.ts +3 -0
- package/dist/db/migrations/v39.js +59 -0
- package/dist/db/migrations/v40.d.ts +3 -0
- package/dist/db/migrations/v40.js +74 -0
- package/dist/db/migrations/v41.d.ts +3 -0
- package/dist/db/migrations/v41.js +43 -0
- package/dist/db/migrations/v42.d.ts +3 -0
- package/dist/db/migrations/v42.js +41 -0
- package/dist/db/migrations/v43.d.ts +3 -0
- package/dist/db/migrations/v43.js +67 -0
- package/dist/db/migrations/v44.d.ts +3 -0
- package/dist/db/migrations/v44.js +28 -0
- package/dist/db/migrations/v45.d.ts +3 -0
- package/dist/db/migrations/v45.js +30 -0
- package/dist/db/migrations/v46.d.ts +3 -0
- package/dist/db/migrations/v46.js +25 -0
- package/dist/db/migrations/v47.d.ts +3 -0
- package/dist/db/migrations/v47.js +17 -0
- package/dist/db/migrations/v48.d.ts +3 -0
- package/dist/db/migrations/v48.js +10 -0
- package/dist/db/migrations/v49.d.ts +3 -0
- package/dist/db/migrations/v49.js +31 -0
- package/dist/db/migrations/v50.d.ts +3 -0
- package/dist/db/migrations/v50.js +67 -0
- package/dist/db/migrations/v51.d.ts +3 -0
- package/dist/db/migrations/v51.js +14 -0
- package/dist/db/migrations/v52.d.ts +3 -0
- package/dist/db/migrations/v52.js +7 -0
- package/dist/db/open.d.ts +23 -0
- package/dist/db/open.js +146 -0
- package/dist/db/sqlite.d.ts +21 -0
- package/dist/db/sqlite.js +8 -0
- package/dist/db/tables.d.ts +7 -0
- package/dist/db/tables.js +38 -0
- package/dist/db.d.ts +6 -46
- package/dist/db.js +5 -3049
- package/dist/decisions.d.ts +4 -1
- package/dist/decisions.js +102 -83
- package/dist/dedupe.js +3 -2
- package/dist/delivery-recorder.js +4 -1
- package/dist/doctor.js +14 -10
- package/dist/embedding-provider.d.ts +1 -1
- package/dist/embedding-provider.js +4 -3
- package/dist/embeddings.d.ts +9 -52
- package/dist/embeddings.js +43 -297
- package/dist/env.d.ts +75 -0
- package/dist/env.js +119 -0
- package/dist/eval-suite.js +1 -1
- package/dist/eval.js +2 -2
- package/dist/extract.js +1 -1
- package/dist/gated-write.js +3 -1
- package/dist/goals.d.ts +3 -1
- package/dist/goals.js +117 -86
- package/dist/graph/read.d.ts +73 -0
- package/dist/graph/read.js +325 -0
- package/dist/graph/rows.d.ts +45 -0
- package/dist/graph/rows.js +51 -0
- package/dist/graph/types.d.ts +83 -0
- package/dist/graph/types.js +11 -0
- package/dist/graph/write.d.ts +93 -0
- package/dist/{graph.js → graph/write.js} +6 -384
- package/dist/graph-extract.js +2 -1
- package/dist/graph-recall.d.ts +1 -1
- package/dist/graph-recall.js +2 -2
- package/dist/graph-stream.js +1 -1
- package/dist/graph-view.d.ts +1 -1
- package/dist/graph-view.js +1 -1
- package/dist/half-life-migration.d.ts +1 -1
- package/dist/half-life-migration.js +2 -1
- package/dist/hooks/codex-session.d.ts +8 -0
- package/dist/hooks/codex-session.js +76 -0
- package/dist/hooks/codex-wrapper.d.ts +55 -0
- package/dist/hooks/codex-wrapper.js +288 -0
- package/dist/hooks/json-hooks.d.ts +63 -0
- package/dist/hooks/json-hooks.js +356 -0
- package/dist/hooks/opencode.d.ts +50 -0
- package/dist/hooks/opencode.js +202 -0
- package/dist/hooks/shared.d.ts +54 -0
- package/dist/hooks/shared.js +77 -0
- package/dist/http-retry.d.ts +2 -0
- package/dist/http-retry.js +4 -3
- package/dist/http-util.d.ts +3 -0
- package/dist/http-util.js +10 -0
- package/dist/{importers.d.ts → importers/core.d.ts} +13 -17
- package/dist/importers/core.js +141 -0
- package/dist/importers/markdown-parse.d.ts +41 -0
- package/dist/importers/markdown-parse.js +132 -0
- package/dist/importers/markdown.d.ts +3 -0
- package/dist/importers/markdown.js +92 -0
- package/dist/importers/sources.d.ts +7 -0
- package/dist/importers/sources.js +229 -0
- package/dist/importers/vault.d.ts +11 -0
- package/dist/importers/vault.js +352 -0
- package/dist/incidents.d.ts +3 -0
- package/dist/incidents.js +52 -43
- package/dist/index.d.ts +25 -6
- package/dist/index.js +23 -6
- package/dist/invalidation.js +2 -1
- package/dist/judgment.js +2 -1
- package/dist/keyset.d.ts +13 -0
- package/dist/keyset.js +8 -0
- package/dist/local-embedding.d.ts +13 -0
- package/dist/local-embedding.js +165 -0
- package/dist/log.d.ts +7 -0
- package/dist/log.js +19 -1
- package/dist/mcp/admin-tools.d.ts +8 -0
- package/dist/mcp/admin-tools.js +116 -0
- package/dist/mcp/format.d.ts +27 -0
- package/dist/mcp/format.js +135 -0
- package/dist/mcp/memory-tools.d.ts +5 -0
- package/dist/mcp/memory-tools.js +83 -0
- package/dist/mcp/protocol.d.ts +83 -0
- package/dist/mcp/protocol.js +55 -0
- package/dist/mcp/recall-tools.d.ts +6 -0
- package/dist/mcp/recall-tools.js +320 -0
- package/dist/mcp/request.d.ts +10 -0
- package/dist/mcp/request.js +163 -0
- package/dist/mcp/server.d.ts +4 -75
- package/dist/mcp/server.js +7 -1190
- package/dist/mcp/session-state.d.ts +11 -0
- package/dist/mcp/session-state.js +28 -0
- package/dist/mcp/stdio.d.ts +8 -0
- package/dist/mcp/stdio.js +79 -0
- package/dist/mcp/tools.d.ts +11 -0
- package/dist/mcp/tools.js +247 -0
- package/dist/memory.d.ts +3 -0
- package/dist/memory.js +27 -1
- package/dist/multihop.d.ts +1 -1
- package/dist/multihop.js +2 -1
- package/dist/owner-validation.js +2 -1
- package/dist/physics-state.js +10 -7
- package/dist/policies.d.ts +3 -0
- package/dist/policies.js +93 -74
- package/dist/postinstall.js +3 -2
- package/dist/predictions/planning-fallacy.d.ts +100 -0
- package/dist/predictions/planning-fallacy.js +190 -0
- package/dist/{predictions.d.ts → predictions/store.d.ts} +7 -102
- package/dist/predictions/store.js +434 -0
- package/dist/processes.d.ts +3 -0
- package/dist/processes.js +94 -76
- package/dist/project-briefs.d.ts +3 -0
- package/dist/project-briefs.js +142 -113
- package/dist/project-identity.js +3 -2
- package/dist/project-merge.d.ts +12 -4
- package/dist/project-merge.js +132 -45
- package/dist/quarantine.d.ts +2 -1
- package/dist/quarantine.js +8 -5
- package/dist/raw-archive.js +1 -1
- package/dist/recall-history.js +3 -2
- package/dist/recall-pipeline.d.ts +2 -2
- package/dist/recall-pipeline.js +16 -8
- package/dist/recall-scope.js +1 -1
- package/dist/recall-trace.d.ts +1 -1
- package/dist/refine-llm.js +2 -1
- package/dist/reject-flow.js +6 -1
- package/dist/rerankers/clef.js +6 -5
- package/dist/rerankers/jev.d.ts +1 -1
- package/dist/rerankers/jev.js +4 -4
- package/dist/rerankers/llm.d.ts +4 -2
- package/dist/rerankers/llm.js +58 -38
- package/dist/rerankers/types.d.ts +1 -1
- package/dist/salience.js +1 -1
- package/dist/scheduler.d.ts +1 -0
- package/dist/scheduler.js +26 -4
- package/dist/scope.js +4 -3
- package/dist/search/as-of.d.ts +10 -0
- package/dist/search/as-of.js +22 -0
- package/dist/search/bm25-search.d.ts +14 -0
- package/dist/search/bm25-search.js +43 -0
- package/dist/search/bm25.d.ts +15 -0
- package/dist/search/bm25.js +54 -0
- package/dist/search/boosts.d.ts +54 -0
- package/dist/search/boosts.js +94 -0
- package/dist/search/breakdown.d.ts +7 -0
- package/dist/search/breakdown.js +20 -0
- package/dist/search/explain.d.ts +25 -0
- package/dist/search/explain.js +31 -0
- package/dist/search/finalize.d.ts +8 -0
- package/dist/search/finalize.js +52 -0
- package/dist/search/fusion.d.ts +27 -0
- package/dist/search/fusion.js +42 -0
- package/dist/search/hybrid-score.d.ts +20 -0
- package/dist/search/hybrid-score.js +73 -0
- package/dist/search/hybrid.d.ts +46 -0
- package/dist/search/hybrid.js +64 -0
- package/dist/search/physics-search.d.ts +29 -0
- package/dist/search/physics-search.js +162 -0
- package/dist/search/rerank.d.ts +10 -0
- package/dist/search/rerank.js +72 -0
- package/dist/search/temporal.d.ts +15 -0
- package/dist/search/temporal.js +45 -0
- package/dist/search/types.d.ts +91 -0
- package/dist/search/types.js +2 -0
- package/dist/search/vector.d.ts +30 -0
- package/dist/search/vector.js +71 -0
- package/dist/secret-detect.d.ts +2 -0
- package/dist/secret-detect.js +2 -1
- package/dist/server/auth.d.ts +52 -0
- package/dist/server/auth.js +221 -0
- package/dist/server/client-ip.d.ts +25 -0
- package/dist/server/client-ip.js +92 -0
- package/dist/server/cursor.d.ts +23 -0
- package/dist/server/cursor.js +58 -0
- package/dist/server/lifecycle.d.ts +7 -0
- package/dist/server/lifecycle.js +29 -0
- package/dist/server/mcp-http.d.ts +5 -0
- package/dist/server/mcp-http.js +199 -0
- package/dist/server/request.d.ts +33 -0
- package/dist/server/request.js +103 -0
- package/dist/server/routes/admin.d.ts +9 -0
- package/dist/server/routes/admin.js +158 -0
- package/dist/server/routes/customer-notes.d.ts +7 -0
- package/dist/server/routes/customer-notes.js +112 -0
- package/dist/server/routes/decisions.d.ts +7 -0
- package/dist/server/routes/decisions.js +133 -0
- package/dist/server/routes/incidents.d.ts +7 -0
- package/dist/server/routes/incidents.js +126 -0
- package/dist/server/routes/memories.d.ts +10 -0
- package/dist/server/routes/memories.js +179 -0
- package/dist/server/routes/policies.d.ts +8 -0
- package/dist/server/routes/policies.js +151 -0
- package/dist/server/routes/predictions.d.ts +7 -0
- package/dist/server/routes/predictions.js +164 -0
- package/dist/server/routes/processes.d.ts +7 -0
- package/dist/server/routes/processes.js +161 -0
- package/dist/server/routes/project-briefs.d.ts +8 -0
- package/dist/server/routes/project-briefs.js +136 -0
- package/dist/server/routes/recall.d.ts +8 -0
- package/dist/server/routes/recall.js +340 -0
- package/dist/server/routes/skills.d.ts +8 -0
- package/dist/server/routes/skills.js +150 -0
- package/dist/server/types.d.ts +56 -0
- package/dist/server/types.js +2 -0
- package/dist/server/validation.d.ts +14 -0
- package/dist/server/validation.js +91 -0
- package/dist/server.d.ts +7 -61
- package/dist/server.js +69 -2362
- package/dist/session-digest.d.ts +1 -1
- package/dist/session-digest.js +9 -2
- package/dist/shared.d.ts +12 -1
- package/dist/shared.js +33 -27
- package/dist/skills.d.ts +3 -0
- package/dist/skills.js +88 -70
- package/dist/stdin.js +2 -2
- package/dist/store/audit-event.d.ts +19 -0
- package/dist/store/audit-event.js +33 -0
- package/dist/store/candidates.d.ts +42 -0
- package/dist/store/candidates.js +152 -0
- package/dist/store/conflicts.d.ts +44 -0
- package/dist/store/conflicts.js +444 -0
- package/dist/store/delete-and-batch.d.ts +63 -0
- package/dist/store/delete-and-batch.js +310 -0
- package/dist/store/entry-reads.d.ts +92 -0
- package/dist/store/entry-reads.js +255 -0
- package/dist/store/entry-row.d.ts +67 -0
- package/dist/store/entry-row.js +208 -0
- package/dist/store/entry-writes.d.ts +46 -0
- package/dist/store/entry-writes.js +148 -0
- package/dist/store/handoffs.d.ts +26 -0
- package/dist/store/handoffs.js +184 -0
- package/dist/store/index-and-stats.d.ts +52 -0
- package/dist/store/index-and-stats.js +214 -0
- package/dist/store/markdown.d.ts +10 -0
- package/dist/store/markdown.js +108 -0
- package/dist/store/mirrors.d.ts +49 -0
- package/dist/store/mirrors.js +312 -0
- package/dist/store/open.d.ts +15 -0
- package/dist/store/open.js +223 -0
- package/dist/store/rows.d.ts +178 -0
- package/dist/store/rows.js +158 -0
- package/dist/store/search-rows.d.ts +86 -0
- package/dist/store/search-rows.js +260 -0
- package/dist/store/sessions.d.ts +83 -0
- package/dist/store/sessions.js +272 -0
- package/dist/store/summaries.d.ts +94 -0
- package/dist/store/summaries.js +377 -0
- package/dist/store/tenant-lookup.d.ts +12 -0
- package/dist/store/tenant-lookup.js +16 -0
- package/dist/store-cards.js +2 -1
- package/dist/summary-dirty.d.ts +4 -0
- package/dist/summary-dirty.js +32 -0
- package/dist/support-bundle.js +4 -3
- package/dist/tenant.js +2 -2
- package/dist/tokenize.d.ts +2 -0
- package/dist/tokenize.js +16 -0
- package/dist/transcript-tail.d.ts +7 -0
- package/dist/transcript-tail.js +48 -0
- package/dist/vector-store.d.ts +27 -0
- package/dist/vector-store.js +210 -0
- package/dist/version.d.ts +2 -2
- package/dist/version.js +2 -2
- package/dist/working-memory.js +1 -1
- package/dist/yaml.js +36 -11
- package/dist-ui/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
- package/dist-ui/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
- package/dist-ui/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
- package/dist-ui/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
- package/dist-ui/assets/ibm-plex-mono-latin-600-normal-BgSNZQsw.woff2 +0 -0
- package/dist-ui/assets/ibm-plex-mono-latin-600-normal-DWFSQ4vo.woff +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
- package/dist-ui/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
- package/dist-ui/assets/index-DPN7cP19.js +33 -0
- package/dist-ui/assets/index-dFloKRVr.css +1 -0
- package/dist-ui/index.html +3 -25
- package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
- package/extensions/openclaw-plugin/package.json +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/dist/capture.d.ts +0 -155
- package/dist/capture.js +0 -1295
- package/dist/consolidate.d.ts +0 -58
- package/dist/consolidate.js +0 -1124
- package/dist/graph.d.ts +0 -245
- package/dist/hooks.d.ts +0 -208
- package/dist/hooks.js +0 -1076
- package/dist/importers.js +0 -900
- package/dist/predictions.js +0 -620
- package/dist/search.d.ts +0 -320
- package/dist/search.js +0 -970
- package/dist/store.d.ts +0 -776
- package/dist/store.js +0 -3473
- package/dist-ui/assets/d3-BiWEKnn4.js +0 -1
- package/dist-ui/assets/index-BhT8RvO6.js +0 -61
- package/dist-ui/assets/index-RoXXJ5dq.css +0 -1
- package/dist-ui/assets/three-BDgTxR1l.js +0 -4112
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
// Read-side tool handlers: hippo_recall, hippo_assemble, hippo_drill and hippo_context.
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { fitBudget } from '../search/finalize.js';
|
|
4
|
+
import { dropHeldCopies, duplicateKey, storedTextKeys } from '../same-text.js';
|
|
5
|
+
import { retrieve as apiRetrieve, drillDown as apiDrillDown, assemble as apiAssemble, getContext as apiGetContext, buildSuppressionSummary } from '../api.js';
|
|
6
|
+
import { autoDetectContext } from '../context-auto.js';
|
|
7
|
+
import { resolveProjectIdentity } from '../project-identity.js';
|
|
8
|
+
import { appendAuditEvent, auditQueryFields } from '../audit.js';
|
|
9
|
+
import { detectAnchoring, hashQueryText, biasHintEnabled, buildSessionKey, getOrCreateRing, appendRecall, snapshotRing, } from '../recall-history.js';
|
|
10
|
+
import { detectAvailabilityBias } from '../availability.js';
|
|
11
|
+
import { openHippoDb, closeHippoDb } from '../db.js';
|
|
12
|
+
import { estimateTokens } from '../token-ledger.js';
|
|
13
|
+
import { assembleCost, assembleText, drillCost, drillText } from '../context-render.js';
|
|
14
|
+
import { mcpActor, isJsonString, isJsonBoolean } from './protocol.js';
|
|
15
|
+
import { sessionRecallHistoryMcp, lastRecalledIds, resolveClientKey } from './session-state.js';
|
|
16
|
+
import { formatContinuityBlock, formatMemories, memoryCost, memoriesReserve, snapshotPiece, handoffPiece, trailPiece, contextCost, tailSection, planningSection, } from './format.js';
|
|
17
|
+
function parseRecallArgs(args, defaultBudget) {
|
|
18
|
+
const query = String(args.query || '');
|
|
19
|
+
const budget = Number(args.budget) || defaultBudget;
|
|
20
|
+
const includeContinuity = Boolean(args.include_continuity);
|
|
21
|
+
const explicitScope = isJsonString(args.scope) && args.scope.length > 0
|
|
22
|
+
? args.scope
|
|
23
|
+
: undefined;
|
|
24
|
+
const freshTailCountArg = Number(args.fresh_tail_count);
|
|
25
|
+
const freshTailCount = Number.isFinite(freshTailCountArg) && freshTailCountArg > 0
|
|
26
|
+
? freshTailCountArg
|
|
27
|
+
: undefined;
|
|
28
|
+
const freshTailSessionId = isJsonString(args.fresh_tail_session_id) && args.fresh_tail_session_id.length > 0
|
|
29
|
+
? args.fresh_tail_session_id
|
|
30
|
+
: undefined;
|
|
31
|
+
const summarizeOverflow = isJsonBoolean(args.summarize_overflow)
|
|
32
|
+
? args.summarize_overflow
|
|
33
|
+
: undefined;
|
|
34
|
+
// Number-coerce, never typeof-check: "abc" must reach api.retrieve and fail as invalid_scorer_window, the same code HTTP returns.
|
|
35
|
+
const scorerWindow = args.scorer_window === undefined
|
|
36
|
+
? undefined
|
|
37
|
+
: Number(args.scorer_window);
|
|
38
|
+
// session_id drives the goal-stack boost inside api.retrieve; same trim and 256-char cap as fresh_tail_session_id.
|
|
39
|
+
const sessionIdRaw = isJsonString(args.session_id) ? args.session_id.trim() : '';
|
|
40
|
+
const sessionId = sessionIdRaw.length > 0 && sessionIdRaw.length <= 256
|
|
41
|
+
? sessionIdRaw
|
|
42
|
+
: undefined;
|
|
43
|
+
const recallExtra = {};
|
|
44
|
+
if (freshTailCount !== undefined)
|
|
45
|
+
recallExtra.freshTailCount = freshTailCount;
|
|
46
|
+
if (freshTailSessionId !== undefined)
|
|
47
|
+
recallExtra.freshTailSessionId = freshTailSessionId;
|
|
48
|
+
if (summarizeOverflow !== undefined)
|
|
49
|
+
recallExtra.summarizeOverflow = summarizeOverflow;
|
|
50
|
+
if (scorerWindow !== undefined)
|
|
51
|
+
recallExtra.scorerWindow = scorerWindow;
|
|
52
|
+
if (sessionId !== undefined)
|
|
53
|
+
recallExtra.sessionId = sessionId;
|
|
54
|
+
return { query, budget, includeContinuity, explicitScope, sessionId, recallExtra };
|
|
55
|
+
}
|
|
56
|
+
/** Builds the showRanked callback that renders the list MCP shows and parks the render in `out`. */
|
|
57
|
+
function recallPresenter(budget, includeContinuity, anchorRing, queryHash, out) {
|
|
58
|
+
return ({ ranked, pool, droppedByScope }, apiResult) => {
|
|
59
|
+
// Sections are paid in print order, ahead of the memories and after the heading; one that does not fit is dropped whole.
|
|
60
|
+
let left = budget - memoriesReserve(budget);
|
|
61
|
+
const pays = (piece) => {
|
|
62
|
+
const tokens = estimateTokens(piece);
|
|
63
|
+
if (tokens > left)
|
|
64
|
+
return false;
|
|
65
|
+
left -= tokens;
|
|
66
|
+
return true;
|
|
67
|
+
};
|
|
68
|
+
const planPiece = planningSection(apiResult);
|
|
69
|
+
const showPlan = planPiece !== '' && pays(planPiece);
|
|
70
|
+
const tailRows = apiResult.results.filter((r) => r.isFreshTail || r.isSummary);
|
|
71
|
+
const showTail = tailRows.length > 0 && pays(tailSection(tailRows));
|
|
72
|
+
const continuityPiece = includeContinuity && apiResult.continuity ? `\n\n${formatContinuityBlock(apiResult.continuity)}` : '';
|
|
73
|
+
const showContinuity = continuityPiece !== '' && pays(continuityPiece);
|
|
74
|
+
// J1, J2 and C5: the hints and Cutoff block describe the list MCP shows, not the window band in apiResult.
|
|
75
|
+
const render = (cut) => {
|
|
76
|
+
const list = dropHeldCopies(cut, (r) => r.entry); // after every cut, so a merged row cut here never hides its sources
|
|
77
|
+
const anchoring = anchorRing ? detectAnchoring(snapshotRing(anchorRing), queryHash, list[0]?.entry.id ?? null) : null;
|
|
78
|
+
const availability = biasHintEnabled('availability')
|
|
79
|
+
? detectAvailabilityBias({
|
|
80
|
+
topK: list.map((r) => ({ id: r.entry.id, created: r.entry.created })),
|
|
81
|
+
pool: pool.map((e) => ({ id: e.id, created: e.created })),
|
|
82
|
+
})
|
|
83
|
+
: null;
|
|
84
|
+
const shownIds = new Set(list.map((r) => r.entry.id));
|
|
85
|
+
const shownKeys = storedTextKeys(list.map((r) => r.entry));
|
|
86
|
+
const tail = showTail
|
|
87
|
+
? dropHeldCopies(tailRows.filter((r) => !shownIds.has(r.id) && !shownKeys.has(duplicateKey(r.content))), (r) => r)
|
|
88
|
+
: [];
|
|
89
|
+
const s = buildSuppressionSummary({
|
|
90
|
+
totalCandidates: pool.length + droppedByScope,
|
|
91
|
+
droppedPreRank: droppedByScope + cut.length - list.length, // the bucket CLI and API recall put hidden copies in
|
|
92
|
+
droppedByBudget: Math.max(0, pool.length - cut.length), // an upper bound: rows that never matched count too
|
|
93
|
+
summarySubstitutionsAdded: tail.filter((r) => r.isSummary).length,
|
|
94
|
+
freshTailAdded: tail.filter((r) => r.isFreshTail && !r.isSummary).length,
|
|
95
|
+
suppressedByInterference: anchoring?.reason === 'memory_dominance' ? 1 : 0,
|
|
96
|
+
});
|
|
97
|
+
// Anchoring is the stronger pull, so it prints first; the Cutoff block sits above the list, where the agent reads it.
|
|
98
|
+
let text = anchoring ? `## Anchoring hint\n${anchoring.summary}\n[anchored_on: ${anchoring.memoryId}]\n\n---\n\n` : '';
|
|
99
|
+
if (availability)
|
|
100
|
+
text += `## Availability bias\n${availability.summary}\n\n---\n\n`;
|
|
101
|
+
if (showPlan)
|
|
102
|
+
text += planPiece;
|
|
103
|
+
const cutoffClauses = [];
|
|
104
|
+
if (s.droppedByBudget > 0)
|
|
105
|
+
cutoffClauses.push(`${s.droppedByBudget} dropped to fit limit`);
|
|
106
|
+
if (s.droppedPreRank > 0)
|
|
107
|
+
cutoffClauses.push(`${s.droppedPreRank} filtered pre-rank`);
|
|
108
|
+
if (s.summarySubstitutionsAdded > 0)
|
|
109
|
+
cutoffClauses.push(`${s.summarySubstitutionsAdded} summary substitutions added`);
|
|
110
|
+
if (s.freshTailAdded > 0)
|
|
111
|
+
cutoffClauses.push(`${s.freshTailAdded} fresh-tail added`);
|
|
112
|
+
if (s.suppressedByInterference > 0)
|
|
113
|
+
cutoffClauses.push(`${s.suppressedByInterference} suppressed by interference`);
|
|
114
|
+
if (cutoffClauses.length > 0) {
|
|
115
|
+
text += `## Cutoff\nShowing ${list.length} of ${s.totalCandidates} candidates; ${cutoffClauses.join('; ')}.\n\n---\n\n`;
|
|
116
|
+
}
|
|
117
|
+
// The window band's fresh-tail and summary rows follow the ranked list, or the MCP fields go unanswered.
|
|
118
|
+
text += formatMemories(list) + tailSection(tail) + (showContinuity ? continuityPiece : '');
|
|
119
|
+
return { anchoring, availability, text, list };
|
|
120
|
+
};
|
|
121
|
+
let results = fitBudget(ranked, Math.max(0, left), 1, memoryCost);
|
|
122
|
+
let rendered = render(results);
|
|
123
|
+
// The hints, Cutoff block and heading vary with the list, so the lowest-ranked entry goes until the whole response fits.
|
|
124
|
+
while (results.length > 1 && estimateTokens(rendered.text) > budget) {
|
|
125
|
+
results = results.slice(0, -1);
|
|
126
|
+
rendered = render(results);
|
|
127
|
+
}
|
|
128
|
+
out.rendered = rendered;
|
|
129
|
+
return rendered.list.map((r) => r.entry.id);
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
function appendRecallAudit(hippoRoot, event) {
|
|
133
|
+
const dbForAudit = openHippoDb(hippoRoot);
|
|
134
|
+
try {
|
|
135
|
+
appendAuditEvent(dbForAudit, event);
|
|
136
|
+
}
|
|
137
|
+
finally {
|
|
138
|
+
closeHippoDb(dbForAudit);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
function auditRecallHints(call, query, anchorRing, queryHash, rendered) {
|
|
142
|
+
const { hippoRoot, tenantId, ctx } = call;
|
|
143
|
+
const { anchoring: mcpAnchoringHint, availability: mcpAvailabilityHint, list: shown } = rendered;
|
|
144
|
+
if (biasHintEnabled('anchoring')) {
|
|
145
|
+
if (anchorRing) {
|
|
146
|
+
// Appended after the final detect: anchoredOn feeds the cooldown for the next recall on this session.
|
|
147
|
+
appendRecall(anchorRing, queryHash, shown[0]?.entry.id ?? null, mcpAnchoringHint?.memoryId);
|
|
148
|
+
if (mcpAnchoringHint?.reason === 'memory_dominance') {
|
|
149
|
+
appendRecallAudit(hippoRoot, {
|
|
150
|
+
tenantId,
|
|
151
|
+
actor: ctx?.actor ?? 'mcp',
|
|
152
|
+
op: 'recall_anchor_detected_memory_dominance',
|
|
153
|
+
targetId: mcpAnchoringHint.memoryId,
|
|
154
|
+
metadata: {
|
|
155
|
+
memory_id: mcpAnchoringHint.memoryId,
|
|
156
|
+
query_count: mcpAnchoringHint.queryCount ?? null,
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
else if (mcpAnchoringHint?.reason === 'query_repeat') {
|
|
161
|
+
appendRecallAudit(hippoRoot, {
|
|
162
|
+
tenantId,
|
|
163
|
+
actor: ctx?.actor ?? 'mcp',
|
|
164
|
+
op: 'recall_anchor_detected_query_repeat',
|
|
165
|
+
targetId: mcpAnchoringHint.memoryId,
|
|
166
|
+
metadata: { memory_id: mcpAnchoringHint.memoryId },
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
// Telemetry: caller had no sessionId so ring tracking skipped.
|
|
172
|
+
// Per the recall-audit convention at api.ts:854, use SHA-256/16
|
|
173
|
+
// for prompt hashing (NOT hashQueryText which is FNV-1a 32-bit
|
|
174
|
+
// for recall matching; brute-force trivial for low-entropy
|
|
175
|
+
// queries). Codex round-2 P2 catch.
|
|
176
|
+
appendRecallAudit(hippoRoot, {
|
|
177
|
+
tenantId,
|
|
178
|
+
actor: ctx?.actor ?? 'mcp',
|
|
179
|
+
op: 'recall_anchor_skipped_no_session',
|
|
180
|
+
targetId: undefined,
|
|
181
|
+
metadata: auditQueryFields(query),
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (mcpAvailabilityHint) {
|
|
186
|
+
appendRecallAudit(hippoRoot, {
|
|
187
|
+
tenantId,
|
|
188
|
+
actor: ctx?.actor ?? 'mcp',
|
|
189
|
+
op: 'recall_availability_detected',
|
|
190
|
+
metadata: {
|
|
191
|
+
recent_fraction: mcpAvailabilityHint.recentFraction,
|
|
192
|
+
older_passed_over: mcpAvailabilityHint.olderCandidatesPassedOver,
|
|
193
|
+
returned_count: mcpAvailabilityHint.returnedCount,
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
export async function runRecallTool(call) {
|
|
199
|
+
const { ctx, hippoRoot, config, tenantId } = call;
|
|
200
|
+
const { query, budget, includeContinuity, explicitScope, sessionId, recallExtra } = parseRecallArgs(call.args, config.defaultBudget);
|
|
201
|
+
const apiCtx = {
|
|
202
|
+
hippoRoot,
|
|
203
|
+
tenantId,
|
|
204
|
+
actor: mcpActor(ctx),
|
|
205
|
+
};
|
|
206
|
+
const anchorRing = biasHintEnabled('anchoring') && sessionId
|
|
207
|
+
? getOrCreateRing(sessionRecallHistoryMcp, buildSessionKey(tenantId, sessionId))
|
|
208
|
+
: null;
|
|
209
|
+
const queryHash = hashQueryText(query);
|
|
210
|
+
const out = {};
|
|
211
|
+
// RecallContractError throws reach the MCP caller raw, as mcp-recall-fresh-tail-policy.test.ts pins.
|
|
212
|
+
await apiRetrieve(apiCtx, {
|
|
213
|
+
query,
|
|
214
|
+
limit: 50,
|
|
215
|
+
scope: explicitScope,
|
|
216
|
+
includeContinuity,
|
|
217
|
+
mode: config.physics?.enabled !== false ? 'physics' : 'hybrid',
|
|
218
|
+
// The hint is computed below over the list MCP shows; the window band's copy would emit its audit row twice.
|
|
219
|
+
suppressAvailabilityHint: true,
|
|
220
|
+
keepHeldCopies: true,
|
|
221
|
+
...recallExtra,
|
|
222
|
+
showRanked: recallPresenter(budget, includeContinuity, anchorRing, queryHash, out),
|
|
223
|
+
});
|
|
224
|
+
if (!out.rendered)
|
|
225
|
+
throw new Error('hippo_recall: api.retrieve returned without calling showRanked');
|
|
226
|
+
lastRecalledIds.set(resolveClientKey(ctx), out.rendered.list.map((r) => r.entry.id));
|
|
227
|
+
auditRecallHints(call, query, anchorRing, queryHash, out.rendered);
|
|
228
|
+
return out.rendered.text;
|
|
229
|
+
}
|
|
230
|
+
export function runAssembleTool({ args, ctx, hippoRoot, tenantId }) {
|
|
231
|
+
const sessionId = String(args.session_id || '');
|
|
232
|
+
if (!sessionId)
|
|
233
|
+
return 'No session_id provided.';
|
|
234
|
+
const budget = Number(args.budget);
|
|
235
|
+
const freshTailCount = Number(args.fresh_tail_count);
|
|
236
|
+
const summarizeOlder = args.summarize_older !== false;
|
|
237
|
+
const apiCtx = {
|
|
238
|
+
hippoRoot,
|
|
239
|
+
tenantId,
|
|
240
|
+
actor: mcpActor(ctx),
|
|
241
|
+
};
|
|
242
|
+
const explicitScope = isJsonString(args.scope) && args.scope.length > 0
|
|
243
|
+
? args.scope
|
|
244
|
+
: undefined;
|
|
245
|
+
const assembleExtra = {};
|
|
246
|
+
if (Number.isFinite(budget) && budget > 0)
|
|
247
|
+
assembleExtra.budget = budget;
|
|
248
|
+
if (Number.isFinite(freshTailCount) && freshTailCount >= 0)
|
|
249
|
+
assembleExtra.freshTailCount = freshTailCount;
|
|
250
|
+
if (explicitScope !== undefined)
|
|
251
|
+
assembleExtra.scope = explicitScope;
|
|
252
|
+
const r = apiAssemble(apiCtx, sessionId, {
|
|
253
|
+
summarizeOlder,
|
|
254
|
+
...assembleExtra,
|
|
255
|
+
cost: assembleCost(sessionId),
|
|
256
|
+
});
|
|
257
|
+
return assembleText(r);
|
|
258
|
+
}
|
|
259
|
+
export function runDrillTool({ args, ctx, hippoRoot, tenantId }) {
|
|
260
|
+
const summaryId = String(args.summary_id || '');
|
|
261
|
+
if (!summaryId)
|
|
262
|
+
return 'No summary_id provided.';
|
|
263
|
+
const limit = Number(args.limit);
|
|
264
|
+
const budget = Number(args.budget);
|
|
265
|
+
// The inputSchema rejects a depth outside 1..10 before this runs, so no silent clamp hides the cap.
|
|
266
|
+
const depth = args.depth === undefined ? undefined : Number(args.depth);
|
|
267
|
+
const apiCtx = {
|
|
268
|
+
hippoRoot,
|
|
269
|
+
tenantId,
|
|
270
|
+
actor: mcpActor(ctx),
|
|
271
|
+
};
|
|
272
|
+
const drillExtra = {};
|
|
273
|
+
if (Number.isFinite(limit) && limit > 0)
|
|
274
|
+
drillExtra.limit = limit;
|
|
275
|
+
if (Number.isFinite(budget) && budget > 0)
|
|
276
|
+
drillExtra.budget = budget;
|
|
277
|
+
if (depth !== undefined)
|
|
278
|
+
drillExtra.depth = depth;
|
|
279
|
+
const r = apiDrillDown(apiCtx, summaryId, { ...drillExtra, cost: drillCost });
|
|
280
|
+
if ('failure' in r) {
|
|
281
|
+
// v1.6.4: only not_drillable is caller-actionable. not_found
|
|
282
|
+
// intentionally collapses cross-tenant + scope-blocked + missing
|
|
283
|
+
// (codex round 3 P1: distinguishing scope_blocked would leak
|
|
284
|
+
// private-row existence on this surface).
|
|
285
|
+
if (r.failure === 'not_drillable') {
|
|
286
|
+
return `Id ${summaryId} is a leaf row, not a level-2+ summary; nothing to drill into.`;
|
|
287
|
+
}
|
|
288
|
+
return `No drillable summary at id=${summaryId}.`;
|
|
289
|
+
}
|
|
290
|
+
return drillText(r);
|
|
291
|
+
}
|
|
292
|
+
export async function runContextTool({ args, ctx, hippoRoot, config, tenantId }) {
|
|
293
|
+
const budget = args.budget === undefined
|
|
294
|
+
? config.defaultContextBudget
|
|
295
|
+
: Number(args.budget);
|
|
296
|
+
if (!Number.isFinite(budget) || budget < 0)
|
|
297
|
+
return 'budget must be a non-negative number.';
|
|
298
|
+
if (budget === 0)
|
|
299
|
+
return '';
|
|
300
|
+
if (budget < memoriesReserve(budget))
|
|
301
|
+
return ''; // not even the heading fits, so nothing prints, as at budget 0
|
|
302
|
+
const exactScope = isJsonString(args.scope) && args.scope.length > 0
|
|
303
|
+
? args.scope
|
|
304
|
+
: undefined;
|
|
305
|
+
// The served store names the project (an HTTP daemon runs from anywhere); the global root names none, so stdio falls back to its launch cwd.
|
|
306
|
+
const storeProject = resolveProjectIdentity(path.dirname(path.resolve(hippoRoot))).name;
|
|
307
|
+
const result = await apiGetContext({ hippoRoot, tenantId, actor: mcpActor(ctx) }, {
|
|
308
|
+
q: autoDetectContext(),
|
|
309
|
+
budget,
|
|
310
|
+
exactScope,
|
|
311
|
+
currentProject: storeProject !== '' ? storeProject : resolveProjectIdentity(process.cwd()).name,
|
|
312
|
+
cost: contextCost,
|
|
313
|
+
});
|
|
314
|
+
lastRecalledIds.set(resolveClientKey(ctx), result.entries.map((r) => r.entry.id));
|
|
315
|
+
return (result.activeSnapshot ? snapshotPiece(result.activeSnapshot) : '')
|
|
316
|
+
+ (result.sessionHandoff ? handoffPiece(result.sessionHandoff) : '')
|
|
317
|
+
+ (result.recentEvents ? trailPiece(result.recentEvents) : '')
|
|
318
|
+
+ formatMemories(result.entries);
|
|
319
|
+
}
|
|
320
|
+
//# sourceMappingURL=recall-tools.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type McpContext, type McpRequest, type McpResponse } from './protocol.js';
|
|
2
|
+
/**
|
|
3
|
+
* Transport-agnostic MCP dispatcher. Both the stdio loop (below) and the
|
|
4
|
+
* HTTP/SSE transport in src/server.ts route every incoming JSON-RPC message
|
|
5
|
+
* through this single function. Returns null for notifications (no response
|
|
6
|
+
* expected) and a McpResponse otherwise. Errors thrown by `executeTool` are
|
|
7
|
+
* the caller's problem — wrap with try/catch on the transport side.
|
|
8
|
+
*/
|
|
9
|
+
export declare function handleMcpRequest(req: McpRequest, ctx?: McpContext): Promise<McpResponse | null>;
|
|
10
|
+
//# sourceMappingURL=request.d.ts.map
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
// Transport-agnostic request handling: tool dispatch table, tool execution and the JSON-RPC method switch.
|
|
2
|
+
import { log } from '../log.js';
|
|
3
|
+
import { getGlobalRoot, initGlobal } from '../shared.js';
|
|
4
|
+
import { loadConfig } from '../config.js';
|
|
5
|
+
import { resolveTenantId } from '../tenant.js';
|
|
6
|
+
import { openHippoDb, closeHippoDb } from '../db.js';
|
|
7
|
+
import { estimateTokens, recordTokenUse } from '../token-ledger.js';
|
|
8
|
+
import { PACKAGE_VERSION } from '../version.js';
|
|
9
|
+
import { validateToolArgs } from './tool-args.js';
|
|
10
|
+
import { findHippoRoot, isJsonString, isJsonObjectRecord } from './protocol.js';
|
|
11
|
+
import { TOOLS, TOOLS_BY_NAME, ARGS_CHECKED_BY_API } from './tools.js';
|
|
12
|
+
import { runRecallTool, runAssembleTool, runDrillTool, runContextTool } from './recall-tools.js';
|
|
13
|
+
import { runRememberTool, runOutcomeTool, runLearnTool } from './memory-tools.js';
|
|
14
|
+
import { runPredictBaserateTool, runStatusTool, runConflictsTool, runResolveTool, runShareTool, runPeersTool } from './admin-tools.js';
|
|
15
|
+
/**
|
|
16
|
+
* Zero-install first run (`npx -y hippo-memory mcp` with no store anywhere):
|
|
17
|
+
* create the global store instead of failing every tool call, and say so on
|
|
18
|
+
* stderr (stdout carries the protocol). `hippo init` in a project later adds
|
|
19
|
+
* a project store, which then takes precedence.
|
|
20
|
+
*/
|
|
21
|
+
function createGlobalStoreOnFirstRun() {
|
|
22
|
+
initGlobal();
|
|
23
|
+
const root = getGlobalRoot();
|
|
24
|
+
log.warn(`no memory store found; created the global store at ${root}. Run \`hippo init\` in a project for a project store.`);
|
|
25
|
+
return root;
|
|
26
|
+
}
|
|
27
|
+
// ── Token ledger (ROADMAP TE0) ──
|
|
28
|
+
const MCP_TOKEN_SURFACES = new Map([
|
|
29
|
+
['hippo_recall', 'mcp_recall'],
|
|
30
|
+
['hippo_context', 'mcp_context'],
|
|
31
|
+
]);
|
|
32
|
+
/**
|
|
33
|
+
* Record the memory text a recall or context tool returned. Best-effort: a
|
|
34
|
+
* ledger failure never fails the tool call. Other tools are not recorded.
|
|
35
|
+
*/
|
|
36
|
+
function recordMcpTokens(toolName, output, ctx) {
|
|
37
|
+
const surface = MCP_TOKEN_SURFACES.get(toolName);
|
|
38
|
+
if (!surface || !output)
|
|
39
|
+
return;
|
|
40
|
+
try {
|
|
41
|
+
const hippoRoot = ctx?.hippoRoot ?? findHippoRoot();
|
|
42
|
+
if (!hippoRoot)
|
|
43
|
+
return;
|
|
44
|
+
const db = openHippoDb(hippoRoot);
|
|
45
|
+
try {
|
|
46
|
+
recordTokenUse(db, {
|
|
47
|
+
tenantId: ctx?.tenantId ?? resolveTenantId({}),
|
|
48
|
+
surface,
|
|
49
|
+
event: 'inject',
|
|
50
|
+
items: 0,
|
|
51
|
+
tokens: estimateTokens(output),
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
finally {
|
|
55
|
+
closeHippoDb(db);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
log.warnThenDebug('mcp-token-ledger', `token ledger write failed; the tool reply is unaffected: ${err instanceof Error ? err.message : String(err)}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// ── Tool execution ──
|
|
63
|
+
const TOOL_HANDLERS = new Map([
|
|
64
|
+
['hippo_recall', runRecallTool],
|
|
65
|
+
['hippo_assemble', runAssembleTool],
|
|
66
|
+
['hippo_drill', runDrillTool],
|
|
67
|
+
['hippo_predict_baserate', runPredictBaserateTool],
|
|
68
|
+
['hippo_remember', runRememberTool],
|
|
69
|
+
['hippo_outcome', runOutcomeTool],
|
|
70
|
+
['hippo_context', runContextTool],
|
|
71
|
+
['hippo_status', runStatusTool],
|
|
72
|
+
['hippo_learn', runLearnTool],
|
|
73
|
+
['hippo_conflicts', runConflictsTool],
|
|
74
|
+
['hippo_resolve', runResolveTool],
|
|
75
|
+
['hippo_share', runShareTool],
|
|
76
|
+
['hippo_peers', runPeersTool],
|
|
77
|
+
]);
|
|
78
|
+
async function executeTool(name, args, ctx) {
|
|
79
|
+
// When a transport hands us a context (HTTP path), trust it: the HTTP
|
|
80
|
+
// server already resolved hippoRoot from its bound opts and tenantId
|
|
81
|
+
// from the Bearer token (or the loopback fallback). The stdio path
|
|
82
|
+
// continues to walk from cwd / fall back to the global root, and to
|
|
83
|
+
// resolve tenant from HIPPO_TENANT.
|
|
84
|
+
const hippoRoot = ctx?.hippoRoot ?? findHippoRoot() ?? createGlobalStoreOnFirstRun();
|
|
85
|
+
const config = loadConfig(hippoRoot);
|
|
86
|
+
// A5: every store read in this server returns to the caller and is
|
|
87
|
+
// tenant-isolated. Resolved once per tool call: prefer the transport's
|
|
88
|
+
// ctx.tenantId so an HTTP Bearer for tenant B doesn't drop to HIPPO_TENANT.
|
|
89
|
+
const tenantId = ctx?.tenantId ?? resolveTenantId({});
|
|
90
|
+
const handler = TOOL_HANDLERS.get(name);
|
|
91
|
+
// handleMcpRequest rejects names missing from TOOLS, so reaching here means TOOLS and this table drifted apart.
|
|
92
|
+
if (!handler)
|
|
93
|
+
throw new Error(`hippo-mcp: tool ${name} is declared but has no handler`);
|
|
94
|
+
return handler({ args, ctx, hippoRoot, config, tenantId });
|
|
95
|
+
}
|
|
96
|
+
// ── Request handling ──
|
|
97
|
+
/**
|
|
98
|
+
* Transport-agnostic MCP dispatcher. Both the stdio loop (below) and the
|
|
99
|
+
* HTTP/SSE transport in src/server.ts route every incoming JSON-RPC message
|
|
100
|
+
* through this single function. Returns null for notifications (no response
|
|
101
|
+
* expected) and a McpResponse otherwise. Errors thrown by `executeTool` are
|
|
102
|
+
* the caller's problem — wrap with try/catch on the transport side.
|
|
103
|
+
*/
|
|
104
|
+
export async function handleMcpRequest(req, ctx) {
|
|
105
|
+
const { id, method, params } = req;
|
|
106
|
+
switch (method) {
|
|
107
|
+
case 'initialize':
|
|
108
|
+
return {
|
|
109
|
+
jsonrpc: '2.0',
|
|
110
|
+
id,
|
|
111
|
+
result: {
|
|
112
|
+
protocolVersion: '2024-11-05',
|
|
113
|
+
capabilities: { tools: {} },
|
|
114
|
+
serverInfo: { name: 'hippo-memory', version: PACKAGE_VERSION },
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
case 'notifications/initialized':
|
|
118
|
+
return null;
|
|
119
|
+
case 'tools/list':
|
|
120
|
+
return { jsonrpc: '2.0', id, result: { tools: TOOLS } };
|
|
121
|
+
case 'tools/call': {
|
|
122
|
+
const nameValue = params?.name;
|
|
123
|
+
const toolName = isJsonString(nameValue) ? nameValue : '';
|
|
124
|
+
const tool = TOOLS_BY_NAME.get(toolName);
|
|
125
|
+
if (!tool) {
|
|
126
|
+
return { jsonrpc: '2.0', id, error: { code: -32602, message: `Unknown tool: ${toolName.slice(0, 128)}` } };
|
|
127
|
+
}
|
|
128
|
+
const argumentsValue = params?.arguments;
|
|
129
|
+
if (argumentsValue !== undefined && argumentsValue !== null && !isJsonObjectRecord(argumentsValue)) {
|
|
130
|
+
return { jsonrpc: '2.0', id, error: { code: -32602, message: `${toolName}: arguments must be an object` } };
|
|
131
|
+
}
|
|
132
|
+
const toolArgs = isJsonObjectRecord(argumentsValue) ? argumentsValue : {};
|
|
133
|
+
// The MCP spec reports input validation as a tool result with isError, so the model can read it and retry.
|
|
134
|
+
const problems = validateToolArgs(tool.inputSchema, toolArgs, ARGS_CHECKED_BY_API.get(toolName));
|
|
135
|
+
if (problems.length > 0) {
|
|
136
|
+
return {
|
|
137
|
+
jsonrpc: '2.0',
|
|
138
|
+
id,
|
|
139
|
+
result: { content: [{ type: 'text', text: `Invalid arguments for ${toolName}: ${problems.join('; ')}` }], isError: true },
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
const output = await executeTool(toolName, toolArgs, ctx);
|
|
143
|
+
recordMcpTokens(toolName, output, ctx);
|
|
144
|
+
return {
|
|
145
|
+
jsonrpc: '2.0',
|
|
146
|
+
id,
|
|
147
|
+
result: {
|
|
148
|
+
content: [{ type: 'text', text: output || 'Done.' }],
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
default:
|
|
153
|
+
// Notifications (no id) must not receive a response
|
|
154
|
+
if (method.startsWith('notifications/'))
|
|
155
|
+
return null;
|
|
156
|
+
return {
|
|
157
|
+
jsonrpc: '2.0',
|
|
158
|
+
id,
|
|
159
|
+
error: { code: -32601, message: `Method not found: ${method}` },
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=request.js.map
|
package/dist/mcp/server.d.ts
CHANGED
|
@@ -7,79 +7,8 @@
|
|
|
7
7
|
*
|
|
8
8
|
* Usage: hippo mcp (or npx hippo-memory mcp)
|
|
9
9
|
*/
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
export
|
|
13
|
-
|
|
14
|
-
export declare function findHippoRoot(cwd?: string, opts?: ResolveProjectIdentityOpts): string | null;
|
|
15
|
-
interface McpRequest {
|
|
16
|
-
jsonrpc: '2.0';
|
|
17
|
-
id: number | string;
|
|
18
|
-
method: string;
|
|
19
|
-
params?: Record<string, JsonValue>;
|
|
20
|
-
}
|
|
21
|
-
interface McpResponse {
|
|
22
|
-
jsonrpc: '2.0';
|
|
23
|
-
id: number | string;
|
|
24
|
-
result?: unknown;
|
|
25
|
-
error?: {
|
|
26
|
-
code: number;
|
|
27
|
-
message: string;
|
|
28
|
-
data?: {
|
|
29
|
-
requestId: string;
|
|
30
|
-
};
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
/** JSON-RPC reply for a request that threw: typed API errors keep their text; anything else is logged and answered generically. */
|
|
34
|
-
export declare function mcpErrorResponse<E>(id: McpResponse['id'], err: E, requestId?: string): McpResponse;
|
|
35
|
-
export type { McpRequest, McpResponse };
|
|
36
|
-
/**
|
|
37
|
-
* Optional execution context threaded from a non-stdio transport. When the
|
|
38
|
-
* HTTP transport in src/server.ts calls handleMcpRequest, it knows the
|
|
39
|
-
* server's bound hippoRoot and the auth-resolved tenantId/actor. Passing
|
|
40
|
-
* those through here lets executeTool skip the findHippoRoot() walk and
|
|
41
|
-
* the env-based resolveTenantId({}) fallback — both of which would
|
|
42
|
-
* otherwise produce the wrong store and the wrong tenant for HTTP callers.
|
|
43
|
-
*
|
|
44
|
-
* Stdio callers pass nothing; behavior stays unchanged for that path.
|
|
45
|
-
*/
|
|
46
|
-
export interface McpContext {
|
|
47
|
-
hippoRoot: string;
|
|
48
|
-
tenantId: string;
|
|
49
|
-
actor: string;
|
|
50
|
-
/**
|
|
51
|
-
* The caller's role from the HTTP transport's auth. Absent for stdio, which
|
|
52
|
-
* is the local operator and runs as admin. Tools must use this rather than
|
|
53
|
-
* assuming admin, or a member key over HTTP-MCP would act as admin.
|
|
54
|
-
*/
|
|
55
|
-
role?: 'admin' | 'member';
|
|
56
|
-
/** EI2: scope grants for the HTTP-MCP caller's key. Absent for stdio (admin, needs none). */
|
|
57
|
-
scopes?: readonly string[];
|
|
58
|
-
viaAuthResolver?: true;
|
|
59
|
-
/**
|
|
60
|
-
* Per-client key for state isolation under HTTP-MCP. For stdio: 'stdio-${pid}'
|
|
61
|
-
* (one process = one client). For HTTP-SSE / HTTP MCP: hash(bearer + remoteAddr)
|
|
62
|
-
* built by src/server.ts when constructing McpContext for the request.
|
|
63
|
-
* Optional for backwards compatibility; defaults to `${tenantId}:default`.
|
|
64
|
-
*/
|
|
65
|
-
clientKey?: string;
|
|
66
|
-
}
|
|
67
|
-
type JsonValue = string | number | boolean | null | JsonValue[] | {
|
|
68
|
-
[key: string]: JsonValue;
|
|
69
|
-
};
|
|
70
|
-
/**
|
|
71
|
-
* Transport-agnostic MCP dispatcher. Both the stdio loop (below) and the
|
|
72
|
-
* HTTP/SSE transport in src/server.ts route every incoming JSON-RPC message
|
|
73
|
-
* through this single function. Returns null for notifications (no response
|
|
74
|
-
* expected) and a McpResponse otherwise. Errors thrown by `executeTool` are
|
|
75
|
-
* the caller's problem — wrap with try/catch on the transport side.
|
|
76
|
-
*/
|
|
77
|
-
export declare function handleMcpRequest(req: McpRequest, ctx?: McpContext): Promise<McpResponse | null>;
|
|
78
|
-
/**
|
|
79
|
-
* Wire stdin/stdout to the dispatcher. Idempotent — only the entrypoint
|
|
80
|
-
* (cli.ts `hippo mcp`, or running this file directly) should call this.
|
|
81
|
-
* src/server.ts imports `handleMcpRequest` without invoking this, so the
|
|
82
|
-
* HTTP daemon does not steal stdin or exit when its parent closes a pipe.
|
|
83
|
-
*/
|
|
84
|
-
export declare function startStdioLoop(): void;
|
|
10
|
+
export { __resetSessionRecallHistoryMcp } from './session-state.js';
|
|
11
|
+
export { findHippoRoot, mcpErrorResponse, type McpRequest, type McpResponse, type McpContext } from './protocol.js';
|
|
12
|
+
export { handleMcpRequest } from './request.js';
|
|
13
|
+
export { startStdioLoop } from './stdio.js';
|
|
85
14
|
//# sourceMappingURL=server.d.ts.map
|