nlm-memory 0.4.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/.agents/plugins/marketplace.json +20 -0
- package/.github/workflows/ci.yml +30 -0
- package/LICENSE +151 -0
- package/README.md +119 -0
- package/dist/cli/classify-parity.d.ts +48 -0
- package/dist/cli/classify-parity.js +182 -0
- package/dist/cli/classify-parity.js.map +1 -0
- package/dist/cli/launchctl-helpers.d.ts +26 -0
- package/dist/cli/launchctl-helpers.js +42 -0
- package/dist/cli/launchctl-helpers.js.map +1 -0
- package/dist/cli/nlm.d.ts +25 -0
- package/dist/cli/nlm.js +832 -0
- package/dist/cli/nlm.js.map +1 -0
- package/dist/core/actions/actions-log.d.ts +40 -0
- package/dist/core/actions/actions-log.js +72 -0
- package/dist/core/actions/actions-log.js.map +1 -0
- package/dist/core/actions/overlay.d.ts +30 -0
- package/dist/core/actions/overlay.js +101 -0
- package/dist/core/actions/overlay.js.map +1 -0
- package/dist/core/adapters/aider.d.ts +33 -0
- package/dist/core/adapters/aider.js +167 -0
- package/dist/core/adapters/aider.js.map +1 -0
- package/dist/core/adapters/claude-code.d.ts +32 -0
- package/dist/core/adapters/claude-code.js +270 -0
- package/dist/core/adapters/claude-code.js.map +1 -0
- package/dist/core/adapters/common.d.ts +20 -0
- package/dist/core/adapters/common.js +60 -0
- package/dist/core/adapters/common.js.map +1 -0
- package/dist/core/adapters/from-source.d.ts +11 -0
- package/dist/core/adapters/from-source.js +55 -0
- package/dist/core/adapters/from-source.js.map +1 -0
- package/dist/core/adapters/hermes-agent.d.ts +34 -0
- package/dist/core/adapters/hermes-agent.js +192 -0
- package/dist/core/adapters/hermes-agent.js.map +1 -0
- package/dist/core/adapters/hermes.d.ts +31 -0
- package/dist/core/adapters/hermes.js +247 -0
- package/dist/core/adapters/hermes.js.map +1 -0
- package/dist/core/adapters/jsonl-generic.d.ts +56 -0
- package/dist/core/adapters/jsonl-generic.js +185 -0
- package/dist/core/adapters/jsonl-generic.js.map +1 -0
- package/dist/core/adapters/opencode.d.ts +36 -0
- package/dist/core/adapters/opencode.js +213 -0
- package/dist/core/adapters/opencode.js.map +1 -0
- package/dist/core/adapters/pi.d.ts +32 -0
- package/dist/core/adapters/pi.js +233 -0
- package/dist/core/adapters/pi.js.map +1 -0
- package/dist/core/classifier/prompt.d.ts +60 -0
- package/dist/core/classifier/prompt.js +178 -0
- package/dist/core/classifier/prompt.js.map +1 -0
- package/dist/core/dataset/build-dataset.d.ts +87 -0
- package/dist/core/dataset/build-dataset.js +335 -0
- package/dist/core/dataset/build-dataset.js.map +1 -0
- package/dist/core/embedding/chunk-body.d.ts +30 -0
- package/dist/core/embedding/chunk-body.js +60 -0
- package/dist/core/embedding/chunk-body.js.map +1 -0
- package/dist/core/embedding/embed-backfill.d.ts +36 -0
- package/dist/core/embedding/embed-backfill.js +168 -0
- package/dist/core/embedding/embed-backfill.js.map +1 -0
- package/dist/core/embedding/embed-normalize.d.ts +28 -0
- package/dist/core/embedding/embed-normalize.js +98 -0
- package/dist/core/embedding/embed-normalize.js.map +1 -0
- package/dist/core/facts/backfill-facts.d.ts +58 -0
- package/dist/core/facts/backfill-facts.js +169 -0
- package/dist/core/facts/backfill-facts.js.map +1 -0
- package/dist/core/facts/extract-facts.d.ts +20 -0
- package/dist/core/facts/extract-facts.js +37 -0
- package/dist/core/facts/extract-facts.js.map +1 -0
- package/dist/core/hook/citation-detect.d.ts +32 -0
- package/dist/core/hook/citation-detect.js +105 -0
- package/dist/core/hook/citation-detect.js.map +1 -0
- package/dist/core/hook/cite-memo.d.ts +20 -0
- package/dist/core/hook/cite-memo.js +68 -0
- package/dist/core/hook/cite-memo.js.map +1 -0
- package/dist/core/hook/claude-settings.d.ts +34 -0
- package/dist/core/hook/claude-settings.js +117 -0
- package/dist/core/hook/claude-settings.js.map +1 -0
- package/dist/core/hook/gate.d.ts +11 -0
- package/dist/core/hook/gate.js +19 -0
- package/dist/core/hook/gate.js.map +1 -0
- package/dist/core/hook/hook-log.d.ts +25 -0
- package/dist/core/hook/hook-log.js +28 -0
- package/dist/core/hook/hook-log.js.map +1 -0
- package/dist/core/hook/memo-sweep.d.ts +55 -0
- package/dist/core/hook/memo-sweep.js +134 -0
- package/dist/core/hook/memo-sweep.js.map +1 -0
- package/dist/core/hook/memo.d.ts +20 -0
- package/dist/core/hook/memo.js +66 -0
- package/dist/core/hook/memo.js.map +1 -0
- package/dist/core/hook/pointer-block.d.ts +14 -0
- package/dist/core/hook/pointer-block.js +19 -0
- package/dist/core/hook/pointer-block.js.map +1 -0
- package/dist/core/hook/select.d.ts +21 -0
- package/dist/core/hook/select.js +15 -0
- package/dist/core/hook/select.js.map +1 -0
- package/dist/core/hook/transcript.d.ts +31 -0
- package/dist/core/hook/transcript.js +103 -0
- package/dist/core/hook/transcript.js.map +1 -0
- package/dist/core/ingest/ingest-session.d.ts +40 -0
- package/dist/core/ingest/ingest-session.js +71 -0
- package/dist/core/ingest/ingest-session.js.map +1 -0
- package/dist/core/providers/provider-models.d.ts +24 -0
- package/dist/core/providers/provider-models.js +72 -0
- package/dist/core/providers/provider-models.js.map +1 -0
- package/dist/core/providers/provider-registry.d.ts +62 -0
- package/dist/core/providers/provider-registry.js +143 -0
- package/dist/core/providers/provider-registry.js.map +1 -0
- package/dist/core/recall/citation-log.d.ts +28 -0
- package/dist/core/recall/citation-log.js +90 -0
- package/dist/core/recall/citation-log.js.map +1 -0
- package/dist/core/recall/filter.d.ts +11 -0
- package/dist/core/recall/filter.js +20 -0
- package/dist/core/recall/filter.js.map +1 -0
- package/dist/core/recall/index.d.ts +6 -0
- package/dist/core/recall/index.js +5 -0
- package/dist/core/recall/index.js.map +1 -0
- package/dist/core/recall/match-fields.d.ts +10 -0
- package/dist/core/recall/match-fields.js +37 -0
- package/dist/core/recall/match-fields.js.map +1 -0
- package/dist/core/recall/query-log.d.ts +36 -0
- package/dist/core/recall/query-log.js +112 -0
- package/dist/core/recall/query-log.js.map +1 -0
- package/dist/core/recall/query-shape.d.ts +22 -0
- package/dist/core/recall/query-shape.js +64 -0
- package/dist/core/recall/query-shape.js.map +1 -0
- package/dist/core/recall/recall-service.d.ts +19 -0
- package/dist/core/recall/recall-service.js +252 -0
- package/dist/core/recall/recall-service.js.map +1 -0
- package/dist/core/recall/recent-log.d.ts +16 -0
- package/dist/core/recall/recent-log.js +46 -0
- package/dist/core/recall/recent-log.js.map +1 -0
- package/dist/core/recall/tokenize.d.ts +7 -0
- package/dist/core/recall/tokenize.js +18 -0
- package/dist/core/recall/tokenize.js.map +1 -0
- package/dist/core/recall/useful-scan.d.ts +52 -0
- package/dist/core/recall/useful-scan.js +300 -0
- package/dist/core/recall/useful-scan.js.map +1 -0
- package/dist/core/recall-facts/fact-query-log.d.ts +42 -0
- package/dist/core/recall-facts/fact-query-log.js +115 -0
- package/dist/core/recall-facts/fact-query-log.js.map +1 -0
- package/dist/core/recall-facts/fact-recall-service.d.ts +34 -0
- package/dist/core/recall-facts/fact-recall-service.js +246 -0
- package/dist/core/recall-facts/fact-recall-service.js.map +1 -0
- package/dist/core/scheduler/scan-once.d.ts +32 -0
- package/dist/core/scheduler/scan-once.js +100 -0
- package/dist/core/scheduler/scan-once.js.map +1 -0
- package/dist/core/scheduler/scheduler.d.ts +59 -0
- package/dist/core/scheduler/scheduler.js +158 -0
- package/dist/core/scheduler/scheduler.js.map +1 -0
- package/dist/core/sources/source-registry.d.ts +68 -0
- package/dist/core/sources/source-registry.js +208 -0
- package/dist/core/sources/source-registry.js.map +1 -0
- package/dist/core/storage/db-restore.d.ts +53 -0
- package/dist/core/storage/db-restore.js +113 -0
- package/dist/core/storage/db-restore.js.map +1 -0
- package/dist/core/storage/live-status.d.ts +15 -0
- package/dist/core/storage/live-status.js +43 -0
- package/dist/core/storage/live-status.js.map +1 -0
- package/dist/core/storage/migrate.d.ts +14 -0
- package/dist/core/storage/migrate.js +52 -0
- package/dist/core/storage/migrate.js.map +1 -0
- package/dist/core/storage/sqlite-fact-store.d.ts +50 -0
- package/dist/core/storage/sqlite-fact-store.js +256 -0
- package/dist/core/storage/sqlite-fact-store.js.map +1 -0
- package/dist/core/storage/sqlite-session-store.d.ts +152 -0
- package/dist/core/storage/sqlite-session-store.js +587 -0
- package/dist/core/storage/sqlite-session-store.js.map +1 -0
- package/dist/hook/pre-compact-hook.d.ts +26 -0
- package/dist/hook/pre-compact-hook.js +94 -0
- package/dist/hook/pre-compact-hook.js.map +1 -0
- package/dist/hook/prompt-recall-hook.d.ts +23 -0
- package/dist/hook/prompt-recall-hook.js +141 -0
- package/dist/hook/prompt-recall-hook.js.map +1 -0
- package/dist/hook/session-end-hook.d.ts +18 -0
- package/dist/hook/session-end-hook.js +67 -0
- package/dist/hook/session-end-hook.js.map +1 -0
- package/dist/hook/session-start-hook.d.ts +25 -0
- package/dist/hook/session-start-hook.js +129 -0
- package/dist/hook/session-start-hook.js.map +1 -0
- package/dist/hook/stop-hook.d.ts +38 -0
- package/dist/hook/stop-hook.js +171 -0
- package/dist/hook/stop-hook.js.map +1 -0
- package/dist/hook/subagent-start-hook.d.ts +30 -0
- package/dist/hook/subagent-start-hook.js +108 -0
- package/dist/hook/subagent-start-hook.js.map +1 -0
- package/dist/http/app.d.ts +65 -0
- package/dist/http/app.js +1009 -0
- package/dist/http/app.js.map +1 -0
- package/dist/install/claude-code.d.ts +57 -0
- package/dist/install/claude-code.js +76 -0
- package/dist/install/claude-code.js.map +1 -0
- package/dist/install/codex.d.ts +82 -0
- package/dist/install/codex.js +277 -0
- package/dist/install/codex.js.map +1 -0
- package/dist/install/hermes-agent.d.ts +35 -0
- package/dist/install/hermes-agent.js +48 -0
- package/dist/install/hermes-agent.js.map +1 -0
- package/dist/install/hermes.d.ts +29 -0
- package/dist/install/hermes.js +52 -0
- package/dist/install/hermes.js.map +1 -0
- package/dist/install/ollama.d.ts +54 -0
- package/dist/install/ollama.js +178 -0
- package/dist/install/ollama.js.map +1 -0
- package/dist/install/setup.d.ts +37 -0
- package/dist/install/setup.js +339 -0
- package/dist/install/setup.js.map +1 -0
- package/dist/llm/classifier-box.d.ts +29 -0
- package/dist/llm/classifier-box.js +43 -0
- package/dist/llm/classifier-box.js.map +1 -0
- package/dist/llm/deepseek-client.d.ts +40 -0
- package/dist/llm/deepseek-client.js +114 -0
- package/dist/llm/deepseek-client.js.map +1 -0
- package/dist/llm/env-autoload.d.ts +8 -0
- package/dist/llm/env-autoload.js +54 -0
- package/dist/llm/env-autoload.js.map +1 -0
- package/dist/llm/ollama-client.d.ts +47 -0
- package/dist/llm/ollama-client.js +156 -0
- package/dist/llm/ollama-client.js.map +1 -0
- package/dist/mcp/server.d.ts +64 -0
- package/dist/mcp/server.js +430 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/ports/fact-store.d.ts +82 -0
- package/dist/ports/fact-store.js +16 -0
- package/dist/ports/fact-store.js.map +1 -0
- package/dist/ports/llm-client.d.ts +42 -0
- package/dist/ports/llm-client.js +14 -0
- package/dist/ports/llm-client.js.map +1 -0
- package/dist/ports/logger.d.ts +13 -0
- package/dist/ports/logger.js +8 -0
- package/dist/ports/logger.js.map +1 -0
- package/dist/ports/session-store.d.ts +29 -0
- package/dist/ports/session-store.js +9 -0
- package/dist/ports/session-store.js.map +1 -0
- package/dist/ports/transcript-adapter.d.ts +48 -0
- package/dist/ports/transcript-adapter.js +15 -0
- package/dist/ports/transcript-adapter.js.map +1 -0
- package/dist/shared/types.d.ts +129 -0
- package/dist/shared/types.js +6 -0
- package/dist/shared/types.js.map +1 -0
- package/dist/ui/assets/index-BA6IpU8g.css +1 -0
- package/dist/ui/assets/index-B_qIVV0k.js +69 -0
- package/dist/ui/index.html +13 -0
- package/docs/methodology/re-derivation-rate.md +112 -0
- package/docs/methodology/useful-hit-rate.md +79 -0
- package/docs/plans/2026-05-20-fts5-lexical-recall.md +1088 -0
- package/docs/plans/2026-05-20-recall-daemon-wedge-fix.md +662 -0
- package/docs/plans/2026-05-20-recall-hook-design.md +131 -0
- package/docs/plans/2026-05-20-recall-hook-implementation.md +1222 -0
- package/docs/plans/desktop-product.md +69 -0
- package/docs/plans/factstore-design.md +236 -0
- package/logs/CHANGELOG/CHANGELOG-2026.md +1389 -0
- package/logs/CHANGELOG/CHANGELOG.md +320 -0
- package/migrations/000_initial_schema.sql +174 -0
- package/migrations/001_entity_type_rename.sql +17 -0
- package/migrations/002_adapter_state_extend.sql +12 -0
- package/migrations/003_session_embeddings.sql +11 -0
- package/migrations/004_facts.sql +46 -0
- package/migrations/005_sources.sql +31 -0
- package/migrations/006_providers.sql +33 -0
- package/migrations/007_source_tokens.sql +17 -0
- package/migrations/008_fts_rebuild.sql +9 -0
- package/migrations/009_session_embedding_chunks.sql +46 -0
- package/migrations/010_sources_opencode.sql +30 -0
- package/migrations/011_sources_hermes_agent.sql +30 -0
- package/migrations/012_sources_aider.sql +30 -0
- package/migrations/013_adapter_state_failure_count.sql +12 -0
- package/package.json +56 -0
- package/plugin/.codex-plugin/plugin.json +22 -0
- package/plugin/.mcp.json +8 -0
- package/plugin/README.md +51 -0
- package/plugin/hooks/hooks.json +25 -0
- package/plugin/scripts/prompt-recall-hook.mjs +202 -0
- package/plugin/scripts/stop-hook.mjs +306 -0
- package/plugin-hermes-agent/README.md +49 -0
- package/plugin-hermes-agent/__init__.py +75 -0
- package/plugin-hermes-agent/plugin.yaml +15 -0
- package/scripts/backfill-citations.mjs +0 -0
- package/scripts/build-codex-plugin.mjs +61 -0
- package/scripts/deepseek-probe.mjs +67 -0
- package/scripts/extract-triples.mjs +207 -0
- package/scripts/longmemeval/embedding-cache.ts +77 -0
- package/scripts/longmemeval/fetch-dataset.sh +25 -0
- package/scripts/longmemeval/run-harness.ts +315 -0
- package/scripts/longmemeval/scorer.ts +99 -0
- package/scripts/longmemeval/tsconfig.json +9 -0
- package/scripts/longmemeval/types.ts +35 -0
- package/scripts/nlm-daily-digest.py +239 -0
- package/scripts/nlm-daily-digest.sh +28 -0
- package/src/cli/classify-parity.ts +257 -0
- package/src/cli/launchctl-helpers.ts +49 -0
- package/src/cli/nlm.ts +885 -0
- package/src/core/actions/actions-log.ts +118 -0
- package/src/core/actions/overlay.ts +117 -0
- package/src/core/adapters/aider.ts +205 -0
- package/src/core/adapters/claude-code.ts +293 -0
- package/src/core/adapters/common.ts +54 -0
- package/src/core/adapters/from-source.ts +57 -0
- package/src/core/adapters/hermes-agent.ts +240 -0
- package/src/core/adapters/hermes.ts +277 -0
- package/src/core/adapters/jsonl-generic.ts +208 -0
- package/src/core/adapters/opencode.ts +281 -0
- package/src/core/adapters/pi.ts +264 -0
- package/src/core/classifier/prompt.ts +200 -0
- package/src/core/dataset/build-dataset.ts +463 -0
- package/src/core/embedding/chunk-body.ts +76 -0
- package/src/core/embedding/embed-backfill.ts +210 -0
- package/src/core/embedding/embed-normalize.ts +135 -0
- package/src/core/facts/backfill-facts.ts +254 -0
- package/src/core/facts/extract-facts.ts +50 -0
- package/src/core/hook/citation-detect.ts +124 -0
- package/src/core/hook/cite-memo.ts +68 -0
- package/src/core/hook/claude-settings.ts +166 -0
- package/src/core/hook/gate.ts +25 -0
- package/src/core/hook/hook-log.ts +41 -0
- package/src/core/hook/memo-sweep.ts +164 -0
- package/src/core/hook/memo.ts +67 -0
- package/src/core/hook/pointer-block.ts +26 -0
- package/src/core/hook/select.ts +32 -0
- package/src/core/hook/transcript.ts +121 -0
- package/src/core/ingest/ingest-session.ts +111 -0
- package/src/core/providers/provider-models.ts +100 -0
- package/src/core/providers/provider-registry.ts +196 -0
- package/src/core/recall/citation-log.ts +108 -0
- package/src/core/recall/filter.ts +27 -0
- package/src/core/recall/index.ts +6 -0
- package/src/core/recall/match-fields.ts +40 -0
- package/src/core/recall/query-log.ts +149 -0
- package/src/core/recall/query-shape.ts +66 -0
- package/src/core/recall/recall-service.ts +320 -0
- package/src/core/recall/recent-log.ts +59 -0
- package/src/core/recall/tokenize.ts +18 -0
- package/src/core/recall/useful-scan.ts +336 -0
- package/src/core/recall-facts/fact-query-log.ts +150 -0
- package/src/core/recall-facts/fact-recall-service.ts +327 -0
- package/src/core/scheduler/scan-once.ts +142 -0
- package/src/core/scheduler/scheduler.ts +225 -0
- package/src/core/sources/source-registry.ts +260 -0
- package/src/core/storage/db-restore.ts +133 -0
- package/src/core/storage/live-status.ts +45 -0
- package/src/core/storage/migrate.ts +72 -0
- package/src/core/storage/sqlite-fact-store.ts +304 -0
- package/src/core/storage/sqlite-session-store.ts +765 -0
- package/src/hook/prompt-recall-hook.ts +174 -0
- package/src/hook/session-end-hook.ts +81 -0
- package/src/hook/session-start-hook.ts +165 -0
- package/src/hook/stop-hook.ts +236 -0
- package/src/http/app.ts +1114 -0
- package/src/install/claude-code.ts +128 -0
- package/src/install/codex.ts +367 -0
- package/src/install/hermes-agent.ts +76 -0
- package/src/install/hermes.ts +78 -0
- package/src/install/ollama.ts +208 -0
- package/src/install/setup.ts +368 -0
- package/src/llm/classifier-box.ts +64 -0
- package/src/llm/deepseek-client.ts +150 -0
- package/src/llm/env-autoload.ts +55 -0
- package/src/llm/ollama-client.ts +189 -0
- package/src/mcp/server.ts +534 -0
- package/src/ports/fact-store.ts +102 -0
- package/src/ports/llm-client.ts +52 -0
- package/src/ports/logger.ts +16 -0
- package/src/ports/session-store.ts +45 -0
- package/src/ports/transcript-adapter.ts +55 -0
- package/src/shared/types.ts +145 -0
- package/src/ui/App.tsx +58 -0
- package/src/ui/components/PromoteOpenButton.tsx +65 -0
- package/src/ui/components/SessionDrawer.tsx +136 -0
- package/src/ui/components/SideNav.tsx +162 -0
- package/src/ui/components/Skeleton.tsx +107 -0
- package/src/ui/index.html +13 -0
- package/src/ui/lib/actions.ts +30 -0
- package/src/ui/lib/api.ts +92 -0
- package/src/ui/lib/dataset.ts +141 -0
- package/src/ui/lib/registries.ts +155 -0
- package/src/ui/lib/view-settings.ts +41 -0
- package/src/ui/main.tsx +15 -0
- package/src/ui/pages/Live.tsx +229 -0
- package/src/ui/pages/Pulse.tsx +415 -0
- package/src/ui/pages/Recall.tsx +190 -0
- package/src/ui/pages/River.tsx +308 -0
- package/src/ui/pages/Search.tsx +93 -0
- package/src/ui/pages/Stub.tsx +9 -0
- package/src/ui/pages/Thread.tsx +262 -0
- package/src/ui/pages/settings/Classifier.tsx +227 -0
- package/src/ui/pages/settings/Data.tsx +190 -0
- package/src/ui/pages/settings/Index.tsx +65 -0
- package/src/ui/pages/settings/Labels.tsx +224 -0
- package/src/ui/pages/settings/Providers.tsx +305 -0
- package/src/ui/pages/settings/SettingsSubnav.tsx +28 -0
- package/src/ui/pages/settings/Sources.tsx +326 -0
- package/src/ui/pages/settings/Views.tsx +96 -0
- package/src/ui/styles.css +1766 -0
- package/src/ui/tsconfig.json +21 -0
- package/src/ui/vite.config.ts +19 -0
- package/tests/fixtures/claude_code/short_session.jsonl +2 -0
- package/tests/fixtures/claude_code/standard_iso.jsonl +4 -0
- package/tests/fixtures/claude_code/tool_heavy.jsonl +8 -0
- package/tests/fixtures/claude_code/with_subagent.jsonl +7 -0
- package/tests/fixtures/facts.ts +17 -0
- package/tests/fixtures/golden-corpus.ts +85 -0
- package/tests/fixtures/hermes/paired_request_dump.json +24 -0
- package/tests/fixtures/hermes/paired_session.json +23 -0
- package/tests/fixtures/hermes/request_dump.json +28 -0
- package/tests/fixtures/hermes/session_iso.json +38 -0
- package/tests/fixtures/hermes/session_unix.json +38 -0
- package/tests/fixtures/hermes/system_only.json +18 -0
- package/tests/fixtures/pi/error-connection-abort.jsonl +8 -0
- package/tests/fixtures/pi/short-successful.jsonl +5 -0
- package/tests/fixtures/pi/with-custom-message.jsonl +6 -0
- package/tests/fixtures/sessions.ts +22 -0
- package/tests/integration/backfill-facts.test.ts +362 -0
- package/tests/integration/citation-explicit.test.ts +111 -0
- package/tests/integration/cite-event.test.ts +169 -0
- package/tests/integration/cite-memo.test.ts +87 -0
- package/tests/integration/db-restore.test.ts +153 -0
- package/tests/integration/embed-backfill.test.ts +176 -0
- package/tests/integration/fact-supersedence.test.ts +313 -0
- package/tests/integration/fts-index.test.ts +60 -0
- package/tests/integration/getbyids-sqlite.test.ts +60 -0
- package/tests/integration/hermes-agent-hooks.test.ts +248 -0
- package/tests/integration/hook-claude-settings.test.ts +205 -0
- package/tests/integration/hook-log.test.ts +54 -0
- package/tests/integration/hook-memo.test.ts +68 -0
- package/tests/integration/hook-pre-compact.test.ts +105 -0
- package/tests/integration/hook-subagent-start.test.ts +102 -0
- package/tests/integration/http.test.ts +401 -0
- package/tests/integration/keyword-search-fts.test.ts +66 -0
- package/tests/integration/mcp-recall-logging.test.ts +88 -0
- package/tests/integration/mcp.test.ts +248 -0
- package/tests/integration/memo-sweep.test.ts +91 -0
- package/tests/integration/prompt-recall-hook.test.ts +88 -0
- package/tests/integration/provider-registry.test.ts +107 -0
- package/tests/integration/recall-golden.test.ts +59 -0
- package/tests/integration/recall-sqlite.test.ts +169 -0
- package/tests/integration/scheduler.test.ts +391 -0
- package/tests/integration/session-end-hook.test.ts +48 -0
- package/tests/integration/session-start-hook.test.ts +126 -0
- package/tests/integration/source-registry.test.ts +120 -0
- package/tests/integration/sqlite-fact-store.test.ts +346 -0
- package/tests/integration/stop-hook.test.ts +560 -0
- package/tests/integration/wal-checkpoint.test.ts +49 -0
- package/tests/unit/cli/launchctl-helpers.test.ts +60 -0
- package/tests/unit/core/adapters/aider.test.ts +230 -0
- package/tests/unit/core/adapters/claude-code.test.ts +118 -0
- package/tests/unit/core/adapters/hermes-agent.test.ts +329 -0
- package/tests/unit/core/adapters/hermes.test.ts +81 -0
- package/tests/unit/core/adapters/jsonl-generic.test.ts +142 -0
- package/tests/unit/core/adapters/opencode.test.ts +354 -0
- package/tests/unit/core/adapters/pi.test.ts +110 -0
- package/tests/unit/core/classifier/prompt.test.ts +126 -0
- package/tests/unit/core/embedding/chunk-body.test.ts +100 -0
- package/tests/unit/core/facts/extract-facts.test.ts +117 -0
- package/tests/unit/core/filter.test.ts +40 -0
- package/tests/unit/core/hook/citation-detect-cite-session.test.ts +96 -0
- package/tests/unit/core/hook/citation-detect.test.ts +124 -0
- package/tests/unit/core/hook/gate.test.ts +29 -0
- package/tests/unit/core/hook/pointer-block.test.ts +22 -0
- package/tests/unit/core/hook/select.test.ts +66 -0
- package/tests/unit/core/match-fields.test.ts +39 -0
- package/tests/unit/core/mcp-cite-session.test.ts +51 -0
- package/tests/unit/core/providers/provider-models.test.ts +101 -0
- package/tests/unit/core/query-shape.test.ts +92 -0
- package/tests/unit/core/recall-facts/fact-recall-service.test.ts +258 -0
- package/tests/unit/core/recall-service.test.ts +200 -0
- package/tests/unit/core/storage/live-status.test.ts +54 -0
- package/tests/unit/core/tokenize.test.ts +32 -0
- package/tests/unit/core/useful-scan.test.ts +537 -0
- package/tests/unit/llm/embed.test.ts +93 -0
- package/tests/unit/llm/ollama-client.test.ts +124 -0
- package/tests/unit/scripts/longmemeval-scorer.test.ts +114 -0
- package/tsconfig.json +31 -0
- package/tsconfig.test.json +11 -0
- package/vitest.config.ts +22 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mirror of `classifier.autoload_env` from the Python daemon. Reads KEY=VALUE
|
|
3
|
+
* pairs from a small list of likely .env locations into process.env. Existing
|
|
4
|
+
* env vars are NOT overridden.
|
|
5
|
+
*
|
|
6
|
+
* Returns the list of paths actually loaded. Safe to call multiple times.
|
|
7
|
+
*/
|
|
8
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
9
|
+
import { homedir } from "node:os";
|
|
10
|
+
import { resolve } from "node:path";
|
|
11
|
+
const DEFAULT_SEARCH_PATHS = [
|
|
12
|
+
"~/.nlm/.env",
|
|
13
|
+
"./.env",
|
|
14
|
+
"../.env",
|
|
15
|
+
"../../.env",
|
|
16
|
+
];
|
|
17
|
+
function expandHome(p) {
|
|
18
|
+
if (p.startsWith("~/"))
|
|
19
|
+
return resolve(homedir(), p.slice(2));
|
|
20
|
+
return p;
|
|
21
|
+
}
|
|
22
|
+
export function autoloadEnv(extraPaths = []) {
|
|
23
|
+
const loaded = [];
|
|
24
|
+
const paths = [...DEFAULT_SEARCH_PATHS, ...extraPaths];
|
|
25
|
+
for (const raw of paths) {
|
|
26
|
+
const path = expandHome(raw);
|
|
27
|
+
if (!existsSync(path))
|
|
28
|
+
continue;
|
|
29
|
+
try {
|
|
30
|
+
const content = readFileSync(path, "utf8");
|
|
31
|
+
for (const line of content.split("\n")) {
|
|
32
|
+
const trimmed = line.trim();
|
|
33
|
+
if (!trimmed || trimmed.startsWith("#") || !trimmed.includes("="))
|
|
34
|
+
continue;
|
|
35
|
+
const eq = trimmed.indexOf("=");
|
|
36
|
+
const key = trimmed.slice(0, eq).trim();
|
|
37
|
+
let value = trimmed.slice(eq + 1).trim();
|
|
38
|
+
if ((value.startsWith('"') && value.endsWith('"')) ||
|
|
39
|
+
(value.startsWith("'") && value.endsWith("'"))) {
|
|
40
|
+
value = value.slice(1, -1);
|
|
41
|
+
}
|
|
42
|
+
if (key && process.env[key] === undefined) {
|
|
43
|
+
process.env[key] = value;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
loaded.push(path);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return loaded;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=env-autoload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-autoload.js","sourceRoot":"","sources":["../../src/llm/env-autoload.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,oBAAoB,GAAG;IAC3B,aAAa;IACb,QAAQ;IACR,SAAS;IACT,YAAY;CACb,CAAC;AAEF,SAAS,UAAU,CAAC,CAAS;IAC3B,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9D,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,aAAoC,EAAE;IAChE,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,KAAK,GAAG,CAAC,GAAG,oBAAoB,EAAE,GAAG,UAAU,CAAC,CAAC;IACvD,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,SAAS;QAChC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAC3C,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBACvC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC5B,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;oBAAE,SAAS;gBAC5E,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;gBAChC,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;gBACxC,IAAI,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBACzC,IACE,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;oBAC9C,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAC9C,CAAC;oBACD,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;gBAC7B,CAAC;gBACD,IAAI,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;oBAC1C,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;gBAC3B,CAAC;YACH,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OllamaClient — LLMClient backed by a local Ollama HTTP endpoint.
|
|
3
|
+
*
|
|
4
|
+
* embed() → POST /api/embeddings (nomic-embed-text by default)
|
|
5
|
+
* classify() → POST /api/chat (phi4-mini by default, format=json)
|
|
6
|
+
*
|
|
7
|
+
* Network/HTTP failure maps to LLMUnreachableError so RecallService can
|
|
8
|
+
* degrade to keyword mode without crashing. Classification parse failures
|
|
9
|
+
* resolve to null (caller's choice whether to retry or route to inbox).
|
|
10
|
+
*
|
|
11
|
+
* Layering: this file lives in the outer ring. core/ depends on LLMClient,
|
|
12
|
+
* not on this concrete class. Tests can substitute a fake client.
|
|
13
|
+
*/
|
|
14
|
+
import type { ClassifyResult, EmbedResult, EmbeddingKind, LLMClient } from "../ports/llm-client.js";
|
|
15
|
+
export type FetchImpl = typeof fetch;
|
|
16
|
+
export declare function l2Normalize(vec: Float32Array): Float32Array;
|
|
17
|
+
export interface OllamaClientOptions {
|
|
18
|
+
readonly baseUrl?: string;
|
|
19
|
+
readonly embedModel?: string;
|
|
20
|
+
readonly classifyModel?: string;
|
|
21
|
+
readonly timeoutMs?: number;
|
|
22
|
+
readonly classifyTimeoutMs?: number;
|
|
23
|
+
/** Inject a fake fetch for tests. Defaults to global fetch. */
|
|
24
|
+
readonly fetchImpl?: FetchImpl;
|
|
25
|
+
}
|
|
26
|
+
export declare class OllamaClient implements LLMClient {
|
|
27
|
+
private readonly baseUrl;
|
|
28
|
+
private readonly embedModel;
|
|
29
|
+
private readonly classifyModel;
|
|
30
|
+
private readonly timeoutMs;
|
|
31
|
+
private readonly classifyTimeoutMs;
|
|
32
|
+
private readonly fetchImpl;
|
|
33
|
+
constructor(opts?: OllamaClientOptions);
|
|
34
|
+
embed(text: string, kind: EmbeddingKind): Promise<EmbedResult>;
|
|
35
|
+
/**
|
|
36
|
+
* Send a transcript through the Ollama classifier with the shared system
|
|
37
|
+
* prompt. Returns a ClassifyResult on success, or throws on network failure
|
|
38
|
+
* (LLMUnreachableError) or schema-invalid output (Error). The Python
|
|
39
|
+
* counterpart returned None on parse failure; we throw a typed error so
|
|
40
|
+
* callers explicitly handle retry / inbox routing rather than swallowing
|
|
41
|
+
* silent nulls.
|
|
42
|
+
*/
|
|
43
|
+
classify(transcript: string, priorContext?: string): Promise<ClassifyResult>;
|
|
44
|
+
}
|
|
45
|
+
export declare class ClassifierSchemaError extends Error {
|
|
46
|
+
constructor(message: string);
|
|
47
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OllamaClient — LLMClient backed by a local Ollama HTTP endpoint.
|
|
3
|
+
*
|
|
4
|
+
* embed() → POST /api/embeddings (nomic-embed-text by default)
|
|
5
|
+
* classify() → POST /api/chat (phi4-mini by default, format=json)
|
|
6
|
+
*
|
|
7
|
+
* Network/HTTP failure maps to LLMUnreachableError so RecallService can
|
|
8
|
+
* degrade to keyword mode without crashing. Classification parse failures
|
|
9
|
+
* resolve to null (caller's choice whether to retry or route to inbox).
|
|
10
|
+
*
|
|
11
|
+
* Layering: this file lives in the outer ring. core/ depends on LLMClient,
|
|
12
|
+
* not on this concrete class. Tests can substitute a fake client.
|
|
13
|
+
*/
|
|
14
|
+
import { LLMUnreachableError } from "../ports/llm-client.js";
|
|
15
|
+
import { CLASSIFIER_SYSTEM_PROMPT, buildUserPrompt, coerceClassifyResult, stripJsonFences, validateClassifierJson, } from "../core/classifier/prompt.js";
|
|
16
|
+
// Tried raising 8000 → 28000 on 2026-05-25 to recover the answer-tail of
|
|
17
|
+
// long gold sessions (median LongMemEval-S gold body is 14,294 chars). The
|
|
18
|
+
// Ollama /api/embeddings endpoint returned 500 on 54% of those large
|
|
19
|
+
// inputs despite nomic-embed-text's nominal 8192-token context — semantic
|
|
20
|
+
// R@5 collapsed from 87.2% → 15.8%. Reverted. Real fix is chunk + max-pool
|
|
21
|
+
// (each body split into ≤8K-char chunks, store all vectors, score against
|
|
22
|
+
// max cosine at query time) so coverage doesn't depend on a single embed
|
|
23
|
+
// call. Filed as #174.
|
|
24
|
+
const MAX_EMBED_CHARS = 8_000;
|
|
25
|
+
const EMBED_PREFIXES = {
|
|
26
|
+
query: "search_query: ",
|
|
27
|
+
document: "search_document: ",
|
|
28
|
+
};
|
|
29
|
+
export function l2Normalize(vec) {
|
|
30
|
+
let sumSq = 0;
|
|
31
|
+
for (let i = 0; i < vec.length; i++) {
|
|
32
|
+
const v = vec[i] ?? 0;
|
|
33
|
+
sumSq += v * v;
|
|
34
|
+
}
|
|
35
|
+
if (sumSq === 0)
|
|
36
|
+
return vec;
|
|
37
|
+
const norm = Math.sqrt(sumSq);
|
|
38
|
+
const out = new Float32Array(vec.length);
|
|
39
|
+
for (let i = 0; i < vec.length; i++) {
|
|
40
|
+
out[i] = (vec[i] ?? 0) / norm;
|
|
41
|
+
}
|
|
42
|
+
return out;
|
|
43
|
+
}
|
|
44
|
+
export class OllamaClient {
|
|
45
|
+
baseUrl;
|
|
46
|
+
embedModel;
|
|
47
|
+
classifyModel;
|
|
48
|
+
timeoutMs;
|
|
49
|
+
classifyTimeoutMs;
|
|
50
|
+
fetchImpl;
|
|
51
|
+
constructor(opts = {}) {
|
|
52
|
+
this.baseUrl = (opts.baseUrl ?? "http://localhost:11434").replace(/\/+$/, "");
|
|
53
|
+
this.embedModel = opts.embedModel ?? "nomic-embed-text";
|
|
54
|
+
this.classifyModel = opts.classifyModel ?? "phi4-mini:latest";
|
|
55
|
+
this.timeoutMs = opts.timeoutMs ?? 10_000;
|
|
56
|
+
this.classifyTimeoutMs = opts.classifyTimeoutMs ?? 180_000;
|
|
57
|
+
this.fetchImpl = opts.fetchImpl ?? fetch;
|
|
58
|
+
}
|
|
59
|
+
async embed(text, kind) {
|
|
60
|
+
// nomic-embed-text v1.5 is an asymmetric retrieval model. The
|
|
61
|
+
// search_query:/search_document: prefix is part of the training
|
|
62
|
+
// contract; omitting it or using the wrong one degrades retrieval
|
|
63
|
+
// quality measurably. MAX_EMBED_CHARS matches the Python ceiling.
|
|
64
|
+
const truncated = text.slice(0, MAX_EMBED_CHARS);
|
|
65
|
+
const prompt = `${EMBED_PREFIXES[kind]}${truncated}`;
|
|
66
|
+
const controller = new AbortController();
|
|
67
|
+
const timer = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
68
|
+
try {
|
|
69
|
+
const res = await this.fetchImpl(`${this.baseUrl}/api/embeddings`, {
|
|
70
|
+
method: "POST",
|
|
71
|
+
headers: { "Content-Type": "application/json" },
|
|
72
|
+
body: JSON.stringify({ model: this.embedModel, prompt }),
|
|
73
|
+
signal: controller.signal,
|
|
74
|
+
});
|
|
75
|
+
if (!res.ok) {
|
|
76
|
+
throw new LLMUnreachableError("ollama", `status ${res.status}`);
|
|
77
|
+
}
|
|
78
|
+
const data = (await res.json());
|
|
79
|
+
if (!data.embedding || data.embedding.length === 0) {
|
|
80
|
+
throw new LLMUnreachableError("ollama", "empty embedding");
|
|
81
|
+
}
|
|
82
|
+
const raw = new Float32Array(data.embedding);
|
|
83
|
+
return { vector: l2Normalize(raw), model: this.embedModel };
|
|
84
|
+
}
|
|
85
|
+
catch (e) {
|
|
86
|
+
if (e instanceof LLMUnreachableError)
|
|
87
|
+
throw e;
|
|
88
|
+
throw new LLMUnreachableError("ollama", e);
|
|
89
|
+
}
|
|
90
|
+
finally {
|
|
91
|
+
clearTimeout(timer);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Send a transcript through the Ollama classifier with the shared system
|
|
96
|
+
* prompt. Returns a ClassifyResult on success, or throws on network failure
|
|
97
|
+
* (LLMUnreachableError) or schema-invalid output (Error). The Python
|
|
98
|
+
* counterpart returned None on parse failure; we throw a typed error so
|
|
99
|
+
* callers explicitly handle retry / inbox routing rather than swallowing
|
|
100
|
+
* silent nulls.
|
|
101
|
+
*/
|
|
102
|
+
async classify(transcript, priorContext = "") {
|
|
103
|
+
const controller = new AbortController();
|
|
104
|
+
const timer = setTimeout(() => controller.abort(), this.classifyTimeoutMs);
|
|
105
|
+
try {
|
|
106
|
+
const userPrompt = buildUserPrompt(transcript, priorContext);
|
|
107
|
+
const res = await this.fetchImpl(`${this.baseUrl}/api/chat`, {
|
|
108
|
+
method: "POST",
|
|
109
|
+
headers: { "Content-Type": "application/json" },
|
|
110
|
+
body: JSON.stringify({
|
|
111
|
+
model: this.classifyModel,
|
|
112
|
+
messages: [
|
|
113
|
+
{ role: "system", content: CLASSIFIER_SYSTEM_PROMPT },
|
|
114
|
+
{ role: "user", content: userPrompt },
|
|
115
|
+
],
|
|
116
|
+
stream: false,
|
|
117
|
+
format: "json",
|
|
118
|
+
options: { temperature: 0.1 },
|
|
119
|
+
}),
|
|
120
|
+
signal: controller.signal,
|
|
121
|
+
});
|
|
122
|
+
if (!res.ok) {
|
|
123
|
+
throw new LLMUnreachableError("ollama", `status ${res.status}`);
|
|
124
|
+
}
|
|
125
|
+
const data = (await res.json());
|
|
126
|
+
const rawContent = data.message?.content?.trim() ?? "";
|
|
127
|
+
const content = stripJsonFences(rawContent);
|
|
128
|
+
let parsed;
|
|
129
|
+
try {
|
|
130
|
+
parsed = JSON.parse(content);
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
throw new ClassifierSchemaError("ollama returned non-JSON content");
|
|
134
|
+
}
|
|
135
|
+
if (!validateClassifierJson(parsed)) {
|
|
136
|
+
throw new ClassifierSchemaError("ollama response missing required keys");
|
|
137
|
+
}
|
|
138
|
+
return coerceClassifyResult(parsed);
|
|
139
|
+
}
|
|
140
|
+
catch (e) {
|
|
141
|
+
if (e instanceof LLMUnreachableError || e instanceof ClassifierSchemaError)
|
|
142
|
+
throw e;
|
|
143
|
+
throw new LLMUnreachableError("ollama", e);
|
|
144
|
+
}
|
|
145
|
+
finally {
|
|
146
|
+
clearTimeout(timer);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
export class ClassifierSchemaError extends Error {
|
|
151
|
+
constructor(message) {
|
|
152
|
+
super(message);
|
|
153
|
+
this.name = "ClassifierSchemaError";
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=ollama-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ollama-client.js","sourceRoot":"","sources":["../../src/llm/ollama-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP adapter. Binds the `recall_sessions` and `get_session` tools directly
|
|
3
|
+
* to RecallService and SessionStore — no HTTP hop, no localhost loopback.
|
|
4
|
+
*
|
|
5
|
+
* The Python daemon's MCP server proxied through HTTP. This server runs in
|
|
6
|
+
* the same process as the rest of nlm-memory, so a tool call is a function
|
|
7
|
+
* call. Lower latency, simpler stack traces, one fewer thing to keep alive.
|
|
8
|
+
*
|
|
9
|
+
* Layering: this module knows about the inner ring (RecallService,
|
|
10
|
+
* SessionStore); core/ does not know this module exists.
|
|
11
|
+
*/
|
|
12
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
13
|
+
import type { FactRecallService } from "../core/recall-facts/fact-recall-service.js";
|
|
14
|
+
import type { RecallService } from "../core/recall/recall-service.js";
|
|
15
|
+
import type { FactStore } from "../ports/fact-store.js";
|
|
16
|
+
import type { SessionStore } from "../ports/session-store.js";
|
|
17
|
+
import type { FactKind, RecallKindFilter, RecallMode } from "../shared/types.js";
|
|
18
|
+
export interface McpDeps {
|
|
19
|
+
readonly recall: RecallService;
|
|
20
|
+
readonly store: SessionStore;
|
|
21
|
+
/** Optional — when absent, fact tools are not registered. */
|
|
22
|
+
readonly factRecall?: FactRecallService;
|
|
23
|
+
readonly factStore?: FactStore;
|
|
24
|
+
}
|
|
25
|
+
export interface ToolResult {
|
|
26
|
+
content: {
|
|
27
|
+
type: "text";
|
|
28
|
+
text: string;
|
|
29
|
+
}[];
|
|
30
|
+
isError?: boolean;
|
|
31
|
+
}
|
|
32
|
+
export interface RecallToolInput {
|
|
33
|
+
query: string | undefined;
|
|
34
|
+
entity: string | undefined;
|
|
35
|
+
kind: RecallKindFilter | undefined;
|
|
36
|
+
mode: RecallMode | undefined;
|
|
37
|
+
limit: number | undefined;
|
|
38
|
+
}
|
|
39
|
+
export declare function recallSessionsHandler(deps: McpDeps, input: Partial<RecallToolInput>): Promise<ToolResult>;
|
|
40
|
+
export declare function getSessionHandler(deps: McpDeps, input: {
|
|
41
|
+
id: string;
|
|
42
|
+
}): Promise<ToolResult>;
|
|
43
|
+
export interface RecallFactsInput {
|
|
44
|
+
query: string | undefined;
|
|
45
|
+
subject: string | undefined;
|
|
46
|
+
predicate: string | undefined;
|
|
47
|
+
kind: FactKind | undefined;
|
|
48
|
+
mode: RecallMode | undefined;
|
|
49
|
+
includeSuperseded: boolean | undefined;
|
|
50
|
+
minConfidence: number | undefined;
|
|
51
|
+
limit: number | undefined;
|
|
52
|
+
}
|
|
53
|
+
export declare function recallFactsHandler(deps: McpDeps, input: Partial<RecallFactsInput>): Promise<ToolResult>;
|
|
54
|
+
export declare function getFactHistoryHandler(deps: McpDeps, input: {
|
|
55
|
+
subject: string;
|
|
56
|
+
predicate: string | undefined;
|
|
57
|
+
}): Promise<ToolResult>;
|
|
58
|
+
export interface CiteSessionInput {
|
|
59
|
+
readonly id: string;
|
|
60
|
+
readonly conversation_id?: string | undefined;
|
|
61
|
+
readonly reason?: string | undefined;
|
|
62
|
+
}
|
|
63
|
+
export declare function citeSessionHandler(input: CiteSessionInput): Promise<ToolResult>;
|
|
64
|
+
export declare function createMcpServer(deps: McpDeps): McpServer;
|