nlm-memory 0.20.1 → 0.21.12
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 +69 -12
- package/assets/replay-eval-dark.svg +26 -0
- package/assets/replay-eval-light.svg +26 -0
- package/dist/cli/digest.js +69 -4
- package/dist/cli/digest.js.map +1 -1
- package/dist/cli/nlm.d.ts +14 -0
- package/dist/cli/nlm.js +556 -71
- package/dist/cli/nlm.js.map +1 -1
- package/dist/cli/reprocess-job-adapters.d.ts +35 -0
- package/dist/cli/reprocess-job-adapters.js +80 -0
- package/dist/cli/reprocess-job-adapters.js.map +1 -0
- package/dist/cli/scope-backfill.d.ts +34 -0
- package/dist/cli/scope-backfill.js +237 -0
- package/dist/cli/scope-backfill.js.map +1 -0
- package/dist/cli/scope-coverage.d.ts +44 -0
- package/dist/cli/scope-coverage.js +208 -0
- package/dist/cli/scope-coverage.js.map +1 -0
- package/dist/cli/supersede.js +8 -7
- package/dist/cli/supersede.js.map +1 -1
- package/dist/core/actions/actions-log.d.ts +65 -8
- package/dist/core/actions/actions-log.js +134 -17
- package/dist/core/actions/actions-log.js.map +1 -1
- package/dist/core/actions/overlay.d.ts +11 -2
- package/dist/core/actions/overlay.js +18 -6
- package/dist/core/actions/overlay.js.map +1 -1
- package/dist/core/adapters/claude-code.d.ts +14 -0
- package/dist/core/adapters/claude-code.js +30 -0
- package/dist/core/adapters/claude-code.js.map +1 -1
- package/dist/core/adapters/from-source.js +11 -3
- package/dist/core/adapters/from-source.js.map +1 -1
- package/dist/core/adapters/fs-wiki-writer.d.ts +44 -0
- package/dist/core/adapters/fs-wiki-writer.js +132 -0
- package/dist/core/adapters/fs-wiki-writer.js.map +1 -0
- package/dist/core/adapters/hermes-agent.d.ts +15 -2
- package/dist/core/adapters/hermes-agent.js +57 -11
- package/dist/core/adapters/hermes-agent.js.map +1 -1
- package/dist/core/adapters/memory-wiki-writer.d.ts +8 -0
- package/dist/core/adapters/memory-wiki-writer.js +16 -0
- package/dist/core/adapters/memory-wiki-writer.js.map +1 -0
- package/dist/core/adapters/muse.d.ts +51 -0
- package/dist/core/adapters/muse.js +271 -0
- package/dist/core/adapters/muse.js.map +1 -0
- package/dist/core/adapters/opencode.d.ts +11 -4
- package/dist/core/adapters/opencode.js +41 -7
- package/dist/core/adapters/opencode.js.map +1 -1
- package/dist/core/alerts/alert-state.d.ts +17 -0
- package/dist/core/alerts/alert-state.js +45 -0
- package/dist/core/alerts/alert-state.js.map +1 -0
- package/dist/core/alerts/check-and-alert.d.ts +28 -0
- package/dist/core/alerts/check-and-alert.js +53 -0
- package/dist/core/alerts/check-and-alert.js.map +1 -0
- package/dist/core/alerts/drift-transition.d.ts +27 -0
- package/dist/core/alerts/drift-transition.js +56 -0
- package/dist/core/alerts/drift-transition.js.map +1 -0
- package/dist/core/alerts/embedder-transition.d.ts +23 -0
- package/dist/core/alerts/embedder-transition.js +40 -0
- package/dist/core/alerts/embedder-transition.js.map +1 -0
- package/dist/core/alerts/fire-alert.d.ts +24 -0
- package/dist/core/alerts/fire-alert.js +72 -0
- package/dist/core/alerts/fire-alert.js.map +1 -0
- package/dist/core/alerts/job-alert.d.ts +12 -0
- package/dist/core/alerts/job-alert.js +37 -0
- package/dist/core/alerts/job-alert.js.map +1 -0
- package/dist/core/alerts/types.d.ts +104 -0
- package/dist/core/alerts/types.js +11 -0
- package/dist/core/alerts/types.js.map +1 -0
- package/dist/core/alerts/wiki-alert.d.ts +15 -0
- package/dist/core/alerts/wiki-alert.js +31 -0
- package/dist/core/alerts/wiki-alert.js.map +1 -0
- package/dist/core/classifier/prompt.d.ts +13 -0
- package/dist/core/classifier/prompt.js +52 -2
- package/dist/core/classifier/prompt.js.map +1 -1
- package/dist/core/dataset/build-dataset.d.ts +16 -1
- package/dist/core/dataset/build-dataset.js +46 -13
- package/dist/core/dataset/build-dataset.js.map +1 -1
- package/dist/core/digest/compose.d.ts +11 -3
- package/dist/core/digest/compose.js +70 -17
- package/dist/core/digest/compose.js.map +1 -1
- package/dist/core/digest/hook-injection.d.ts +43 -0
- package/dist/core/digest/hook-injection.js +87 -0
- package/dist/core/digest/hook-injection.js.map +1 -0
- package/dist/core/digest/hook-version-parity.d.ts +31 -0
- package/dist/core/digest/hook-version-parity.js +56 -0
- package/dist/core/digest/hook-version-parity.js.map +1 -0
- package/dist/core/embedding/pg-embed-backfill.js +1 -1
- package/dist/core/embedding/pg-embed-backfill.js.map +1 -1
- package/dist/core/exemplars/capture-from-session.d.ts +2 -1
- package/dist/core/exemplars/capture-from-session.js +4 -4
- package/dist/core/exemplars/capture-from-session.js.map +1 -1
- package/dist/core/exemplars/embed-backfill.d.ts +9 -0
- package/dist/core/exemplars/embed-backfill.js +9 -1
- package/dist/core/exemplars/embed-backfill.js.map +1 -1
- package/dist/core/exemplars/extract-exemplar.d.ts +2 -0
- package/dist/core/exemplars/extract-exemplar.js +7 -1
- package/dist/core/exemplars/extract-exemplar.js.map +1 -1
- package/dist/core/exemplars/ingest-exemplar.d.ts +1 -0
- package/dist/core/exemplars/ingest-exemplar.js +1 -0
- package/dist/core/exemplars/ingest-exemplar.js.map +1 -1
- package/dist/core/exemplars/recall-code.d.ts +1 -1
- package/dist/core/exemplars/recall-code.js +2 -2
- package/dist/core/exemplars/recall-code.js.map +1 -1
- package/dist/core/facts/backfill-facts.d.ts +1 -1
- package/dist/core/facts/backfill-facts.js +4 -4
- package/dist/core/facts/backfill-facts.js.map +1 -1
- package/dist/core/facts/embed-backfill.d.ts +54 -0
- package/dist/core/facts/embed-backfill.js +109 -0
- package/dist/core/facts/embed-backfill.js.map +1 -0
- package/dist/core/facts/reconcile-facts.d.ts +42 -0
- package/dist/core/facts/reconcile-facts.js +133 -0
- package/dist/core/facts/reconcile-facts.js.map +1 -0
- package/dist/core/health/embed-failure-state.d.ts +4 -0
- package/dist/core/health/embed-failure-state.js +12 -0
- package/dist/core/health/embed-failure-state.js.map +1 -0
- package/dist/core/health/warmup-retry.d.ts +27 -0
- package/dist/core/health/warmup-retry.js +53 -0
- package/dist/core/health/warmup-retry.js.map +1 -0
- package/dist/core/health/warmup-state.d.ts +15 -0
- package/dist/core/health/warmup-state.js +15 -1
- package/dist/core/health/warmup-state.js.map +1 -1
- package/dist/core/hook/cite-memo.d.ts +11 -7
- package/dist/core/hook/cite-memo.js +25 -17
- package/dist/core/hook/cite-memo.js.map +1 -1
- package/dist/core/hook/claude-settings.d.ts +1 -1
- package/dist/core/hook/claude-settings.js +0 -1
- package/dist/core/hook/claude-settings.js.map +1 -1
- package/dist/core/hook/hook-log.d.ts +13 -2
- package/dist/core/hook/hook-log.js +16 -8
- package/dist/core/hook/hook-log.js.map +1 -1
- package/dist/core/hook/memo.d.ts +10 -6
- package/dist/core/hook/memo.js +25 -17
- package/dist/core/hook/memo.js.map +1 -1
- package/dist/core/hook/pointer-block.d.ts +8 -1
- package/dist/core/hook/pointer-block.js +17 -4
- package/dist/core/hook/pointer-block.js.map +1 -1
- package/dist/core/hook/resolve-conversation-by-query.d.ts +6 -5
- package/dist/core/hook/resolve-conversation-by-query.js +24 -12
- package/dist/core/hook/resolve-conversation-by-query.js.map +1 -1
- package/dist/core/ingest/backfill-derivables.d.ts +92 -0
- package/dist/core/ingest/backfill-derivables.js +175 -0
- package/dist/core/ingest/backfill-derivables.js.map +1 -0
- package/dist/core/ingest/ingest-session.d.ts +1 -1
- package/dist/core/ingest/ingest-session.js +23 -3
- package/dist/core/ingest/ingest-session.js.map +1 -1
- package/dist/core/ingest/reclassify-oversized.d.ts +1 -1
- package/dist/core/ingest/reclassify-oversized.js +8 -2
- package/dist/core/ingest/reclassify-oversized.js.map +1 -1
- package/dist/core/ingest/reprocess.d.ts +1 -1
- package/dist/core/ingest/reprocess.js +7 -2
- package/dist/core/ingest/reprocess.js.map +1 -1
- package/dist/core/ingest/transcript-derivables.d.ts +27 -0
- package/dist/core/ingest/transcript-derivables.js +138 -0
- package/dist/core/ingest/transcript-derivables.js.map +1 -0
- package/dist/core/jobs/job-supervisor.d.ts +168 -0
- package/dist/core/jobs/job-supervisor.js +335 -0
- package/dist/core/jobs/job-supervisor.js.map +1 -0
- package/dist/core/learner/model.d.ts +63 -0
- package/dist/core/learner/model.js +30 -0
- package/dist/core/learner/model.js.map +1 -0
- package/dist/core/learner/service.d.ts +42 -0
- package/dist/core/learner/service.js +74 -0
- package/dist/core/learner/service.js.map +1 -0
- package/dist/core/learner/summary.d.ts +28 -0
- package/dist/core/learner/summary.js +70 -0
- package/dist/core/learner/summary.js.map +1 -0
- package/dist/core/learner/validate.d.ts +18 -0
- package/dist/core/learner/validate.js +95 -0
- package/dist/core/learner/validate.js.map +1 -0
- package/dist/core/metrics/re-derivation.d.ts +31 -2
- package/dist/core/metrics/re-derivation.js +36 -4
- package/dist/core/metrics/re-derivation.js.map +1 -1
- package/dist/core/outcome/coverage.d.ts +33 -0
- package/dist/core/outcome/coverage.js +46 -0
- package/dist/core/outcome/coverage.js.map +1 -0
- package/dist/core/outcome/rollup.d.ts +33 -0
- package/dist/core/outcome/rollup.js +113 -0
- package/dist/core/outcome/rollup.js.map +1 -0
- package/dist/core/providers/provider-registry.d.ts +40 -23
- package/dist/core/providers/provider-registry.js +99 -81
- package/dist/core/providers/provider-registry.js.map +1 -1
- package/dist/core/recall/citation-log.d.ts +10 -5
- package/dist/core/recall/citation-log.js +21 -10
- package/dist/core/recall/citation-log.js.map +1 -1
- package/dist/core/recall/hook-recall-log.d.ts +7 -4
- package/dist/core/recall/hook-recall-log.js +14 -8
- package/dist/core/recall/hook-recall-log.js.map +1 -1
- package/dist/core/recall/miss-log.d.ts +7 -4
- package/dist/core/recall/miss-log.js +18 -11
- package/dist/core/recall/miss-log.js.map +1 -1
- package/dist/core/recall/query-log.d.ts +8 -5
- package/dist/core/recall/query-log.js +16 -9
- package/dist/core/recall/query-log.js.map +1 -1
- package/dist/core/recall/recall-service.d.ts +10 -1
- package/dist/core/recall/recall-service.js +31 -12
- package/dist/core/recall/recall-service.js.map +1 -1
- package/dist/core/recall/recent-log.d.ts +6 -1
- package/dist/core/recall/recent-log.js +13 -5
- package/dist/core/recall/recent-log.js.map +1 -1
- package/dist/core/recall/related-concepts.d.ts +29 -0
- package/dist/core/recall/related-concepts.js +67 -0
- package/dist/core/recall/related-concepts.js.map +1 -0
- package/dist/core/recall/related-exemplars.d.ts +1 -1
- package/dist/core/recall/related-exemplars.js +2 -2
- package/dist/core/recall/related-exemplars.js.map +1 -1
- package/dist/core/recall/related-facts.d.ts +1 -1
- package/dist/core/recall/related-facts.js +3 -3
- package/dist/core/recall/related-facts.js.map +1 -1
- package/dist/core/recall-facts/fact-query-log.d.ts +8 -4
- package/dist/core/recall-facts/fact-query-log.js +16 -8
- package/dist/core/recall-facts/fact-query-log.js.map +1 -1
- package/dist/core/recall-facts/fact-recall-service.d.ts +2 -2
- package/dist/core/recall-facts/fact-recall-service.js +13 -12
- package/dist/core/recall-facts/fact-recall-service.js.map +1 -1
- package/dist/core/scheduler/scan-once.js +15 -12
- package/dist/core/scheduler/scan-once.js.map +1 -1
- package/dist/core/scheduler/scheduler.d.ts +3 -0
- package/dist/core/scheduler/scheduler.js +45 -10
- package/dist/core/scheduler/scheduler.js.map +1 -1
- package/dist/core/scope/alias-map.d.ts +10 -0
- package/dist/core/scope/alias-map.js +41 -0
- package/dist/core/scope/alias-map.js.map +1 -0
- package/dist/core/scope/derive-scope.d.ts +8 -0
- package/dist/core/scope/derive-scope.js +54 -0
- package/dist/core/scope/derive-scope.js.map +1 -0
- package/dist/core/scope/scope-clause.d.ts +16 -0
- package/dist/core/scope/scope-clause.js +21 -0
- package/dist/core/scope/scope-clause.js.map +1 -0
- package/dist/core/scope/stamp-flag.d.ts +1 -0
- package/dist/core/scope/stamp-flag.js +4 -0
- package/dist/core/scope/stamp-flag.js.map +1 -0
- package/dist/core/signals/code-signal.d.ts +1 -0
- package/dist/core/signals/code-signal.js +1 -0
- package/dist/core/signals/code-signal.js.map +1 -1
- package/dist/core/signals/failure-mode-recall.d.ts +1 -1
- package/dist/core/signals/failure-mode-recall.js +2 -2
- package/dist/core/signals/failure-mode-recall.js.map +1 -1
- package/dist/core/signals/ingest-signal.d.ts +1 -1
- package/dist/core/signals/ingest-signal.js +3 -1
- package/dist/core/signals/ingest-signal.js.map +1 -1
- package/dist/core/signals/stamp-scope.d.ts +18 -0
- package/dist/core/signals/stamp-scope.js +28 -0
- package/dist/core/signals/stamp-scope.js.map +1 -0
- package/dist/core/sources/source-registry.d.ts +49 -28
- package/dist/core/sources/source-registry.js +113 -70
- package/dist/core/sources/source-registry.js.map +1 -1
- package/dist/core/storage/pg-code-exemplar-store.d.ts +19 -10
- package/dist/core/storage/pg-code-exemplar-store.js +62 -27
- package/dist/core/storage/pg-code-exemplar-store.js.map +1 -1
- package/dist/core/storage/pg-entity-store.d.ts +6 -1
- package/dist/core/storage/pg-entity-store.js +33 -18
- package/dist/core/storage/pg-entity-store.js.map +1 -1
- package/dist/core/storage/pg-fact-ingest.d.ts +1 -1
- package/dist/core/storage/pg-fact-ingest.js +10 -7
- package/dist/core/storage/pg-fact-ingest.js.map +1 -1
- package/dist/core/storage/pg-fact-store.d.ts +29 -17
- package/dist/core/storage/pg-fact-store.js +99 -46
- package/dist/core/storage/pg-fact-store.js.map +1 -1
- package/dist/core/storage/pg-learner-store.d.ts +27 -0
- package/dist/core/storage/pg-learner-store.js +174 -0
- package/dist/core/storage/pg-learner-store.js.map +1 -0
- package/dist/core/storage/pg-session-store.d.ts +25 -21
- package/dist/core/storage/pg-session-store.js +186 -114
- package/dist/core/storage/pg-session-store.js.map +1 -1
- package/dist/core/storage/pg-signal-store.d.ts +10 -5
- package/dist/core/storage/pg-signal-store.js +26 -13
- package/dist/core/storage/pg-signal-store.js.map +1 -1
- package/dist/core/storage/pg-storage.d.ts +4 -0
- package/dist/core/storage/pg-storage.js +6 -0
- package/dist/core/storage/pg-storage.js.map +1 -1
- package/dist/core/storage/pg-workstream-store.d.ts +17 -11
- package/dist/core/storage/pg-workstream-store.js +47 -29
- package/dist/core/storage/pg-workstream-store.js.map +1 -1
- package/dist/core/storage/sqlite-code-exemplar-store.d.ts +24 -10
- package/dist/core/storage/sqlite-code-exemplar-store.js +86 -40
- package/dist/core/storage/sqlite-code-exemplar-store.js.map +1 -1
- package/dist/core/storage/sqlite-entity-store.d.ts +8 -1
- package/dist/core/storage/sqlite-entity-store.js +46 -27
- package/dist/core/storage/sqlite-entity-store.js.map +1 -1
- package/dist/core/storage/sqlite-fact-store.d.ts +45 -19
- package/dist/core/storage/sqlite-fact-store.js +175 -64
- package/dist/core/storage/sqlite-fact-store.js.map +1 -1
- package/dist/core/storage/sqlite-learner-store.d.ts +33 -0
- package/dist/core/storage/sqlite-learner-store.js +178 -0
- package/dist/core/storage/sqlite-learner-store.js.map +1 -0
- package/dist/core/storage/sqlite-outcome-store.d.ts +104 -0
- package/dist/core/storage/sqlite-outcome-store.js +211 -0
- package/dist/core/storage/sqlite-outcome-store.js.map +1 -0
- package/dist/core/storage/sqlite-session-store.d.ts +50 -21
- package/dist/core/storage/sqlite-session-store.js +233 -149
- package/dist/core/storage/sqlite-session-store.js.map +1 -1
- package/dist/core/storage/sqlite-signal-store.d.ts +12 -5
- package/dist/core/storage/sqlite-signal-store.js +29 -15
- package/dist/core/storage/sqlite-signal-store.js.map +1 -1
- package/dist/core/storage/sqlite-storage.d.ts +4 -0
- package/dist/core/storage/sqlite-storage.js +10 -2
- package/dist/core/storage/sqlite-storage.js.map +1 -1
- package/dist/core/storage/sqlite-workstream-store.d.ts +17 -11
- package/dist/core/storage/sqlite-workstream-store.js +53 -31
- package/dist/core/storage/sqlite-workstream-store.js.map +1 -1
- package/dist/core/storage/supersedence-log.d.ts +10 -7
- package/dist/core/storage/supersedence-log.js +21 -14
- package/dist/core/storage/supersedence-log.js.map +1 -1
- package/dist/core/telemetry/probe-filter.d.ts +35 -0
- package/dist/core/telemetry/probe-filter.js +56 -0
- package/dist/core/telemetry/probe-filter.js.map +1 -0
- package/dist/core/tenancy/default-team.d.ts +6 -0
- package/dist/core/tenancy/default-team.js +7 -0
- package/dist/core/tenancy/default-team.js.map +1 -0
- package/dist/core/tenancy/hosted-mode.d.ts +9 -0
- package/dist/core/tenancy/hosted-mode.js +12 -0
- package/dist/core/tenancy/hosted-mode.js.map +1 -0
- package/dist/core/tenancy/team-auth.d.ts +16 -0
- package/dist/core/tenancy/team-auth.js +22 -0
- package/dist/core/tenancy/team-auth.js.map +1 -0
- package/dist/core/tenancy/team-token-store.d.ts +45 -0
- package/dist/core/tenancy/team-token-store.js +52 -0
- package/dist/core/tenancy/team-token-store.js.map +1 -0
- package/dist/core/tenancy/tenant-clause.d.ts +37 -0
- package/dist/core/tenancy/tenant-clause.js +11 -0
- package/dist/core/tenancy/tenant-clause.js.map +1 -0
- package/dist/core/tenancy/tenant-state-path.d.ts +28 -0
- package/dist/core/tenancy/tenant-state-path.js +49 -0
- package/dist/core/tenancy/tenant-state-path.js.map +1 -0
- package/dist/core/update-check/check.d.ts +6 -0
- package/dist/core/update-check/check.js +35 -0
- package/dist/core/update-check/check.js.map +1 -1
- package/dist/core/wiki/project.d.ts +17 -0
- package/dist/core/wiki/project.js +37 -0
- package/dist/core/wiki/project.js.map +1 -0
- package/dist/core/wiki/reconcile.d.ts +15 -0
- package/dist/core/wiki/reconcile.js +14 -0
- package/dist/core/wiki/reconcile.js.map +1 -0
- package/dist/core/wiki/render.d.ts +5 -0
- package/dist/core/wiki/render.js +84 -0
- package/dist/core/wiki/render.js.map +1 -0
- package/dist/core/wiki/rollup.d.ts +28 -0
- package/dist/core/wiki/rollup.js +91 -0
- package/dist/core/wiki/rollup.js.map +1 -0
- package/dist/core/wiki/select.d.ts +8 -0
- package/dist/core/wiki/select.js +7 -0
- package/dist/core/wiki/select.js.map +1 -0
- package/dist/core/wiki/slug.d.ts +36 -0
- package/dist/core/wiki/slug.js +71 -0
- package/dist/core/wiki/slug.js.map +1 -0
- package/dist/core/wiki/types.d.ts +37 -0
- package/dist/core/wiki/types.js +2 -0
- package/dist/core/wiki/types.js.map +1 -0
- package/dist/core/work-digest/build-work-digest.d.ts +1 -1
- package/dist/core/work-digest/build-work-digest.js +3 -3
- package/dist/core/work-digest/build-work-digest.js.map +1 -1
- package/dist/core/workstream/bind.d.ts +3 -2
- package/dist/core/workstream/bind.js +29 -10
- package/dist/core/workstream/bind.js.map +1 -1
- package/dist/core/workstream/model.d.ts +1 -0
- package/dist/core/workstream/model.js.map +1 -1
- package/dist/core/workstream/rollup.d.ts +1 -1
- package/dist/core/workstream/rollup.js +6 -6
- package/dist/core/workstream/rollup.js.map +1 -1
- package/dist/hook/hook-helpers.d.ts +14 -0
- package/dist/hook/hook-helpers.js +29 -2
- package/dist/hook/hook-helpers.js.map +1 -1
- package/dist/hook/pre-compact-hook.js +8 -5
- package/dist/hook/pre-compact-hook.js.map +1 -1
- package/dist/hook/prompt-recall-hook.d.ts +7 -3
- package/dist/hook/prompt-recall-hook.js +35 -20
- package/dist/hook/prompt-recall-hook.js.map +1 -1
- package/dist/hook/recall-over-http.d.ts +28 -3
- package/dist/hook/recall-over-http.js +58 -12
- package/dist/hook/recall-over-http.js.map +1 -1
- package/dist/hook/session-end-hook.js +7 -5
- package/dist/hook/session-end-hook.js.map +1 -1
- package/dist/hook/session-start-hook.d.ts +14 -1
- package/dist/hook/session-start-hook.js +57 -16
- package/dist/hook/session-start-hook.js.map +1 -1
- package/dist/hook/stop-hook.js +11 -8
- package/dist/hook/stop-hook.js.map +1 -1
- package/dist/http/app.d.ts +47 -3
- package/dist/http/app.js +379 -132
- package/dist/http/app.js.map +1 -1
- package/dist/install/claude-code.d.ts +17 -0
- package/dist/install/claude-code.js +44 -5
- package/dist/install/claude-code.js.map +1 -1
- package/dist/install/codex.d.ts +23 -2
- package/dist/install/codex.js +111 -14
- package/dist/install/codex.js.map +1 -1
- package/dist/install/cursor.d.ts +2 -2
- package/dist/install/cursor.js +7 -7
- package/dist/install/cursor.js.map +1 -1
- package/dist/install/hermes.d.ts +8 -0
- package/dist/install/hermes.js +28 -5
- package/dist/install/hermes.js.map +1 -1
- package/dist/install/local-source.d.ts +20 -0
- package/dist/install/local-source.js +28 -0
- package/dist/install/local-source.js.map +1 -0
- package/dist/install/mcp-block.d.ts +77 -0
- package/dist/install/mcp-block.js +99 -0
- package/dist/install/mcp-block.js.map +1 -0
- package/dist/install/pi.d.ts +26 -0
- package/dist/install/pi.js +43 -0
- package/dist/install/pi.js.map +1 -1
- package/dist/install/setup.js +6 -0
- package/dist/install/setup.js.map +1 -1
- package/dist/install/windsurf.d.ts +2 -2
- package/dist/install/windsurf.js +7 -7
- package/dist/install/windsurf.js.map +1 -1
- package/dist/llm/classifier-box.d.ts +5 -0
- package/dist/llm/classifier-box.js +5 -0
- package/dist/llm/classifier-box.js.map +1 -1
- package/dist/mcp/server.d.ts +94 -15
- package/dist/mcp/server.js +402 -79
- package/dist/mcp/server.js.map +1 -1
- package/dist/ports/clock.d.ts +12 -0
- package/dist/ports/clock.js +10 -0
- package/dist/ports/clock.js.map +1 -0
- package/dist/ports/code-exemplar-store.d.ts +13 -13
- package/dist/ports/entity-store.d.ts +5 -1
- package/dist/ports/fact-store.d.ts +0 -0
- package/dist/ports/fact-store.js +0 -0
- package/dist/ports/fact-store.js.map +1 -1
- package/dist/ports/learner-store.d.ts +80 -0
- package/dist/ports/learner-store.js +19 -0
- package/dist/ports/learner-store.js.map +1 -0
- package/dist/ports/outcome.d.ts +85 -0
- package/dist/ports/outcome.js +11 -0
- package/dist/ports/outcome.js.map +1 -0
- package/dist/ports/session-store.d.ts +20 -20
- package/dist/ports/session-store.js +5 -0
- package/dist/ports/session-store.js.map +1 -1
- package/dist/ports/signal-store.d.ts +12 -8
- package/dist/ports/spawn-child.d.ts +14 -0
- package/dist/ports/spawn-child.js +10 -0
- package/dist/ports/spawn-child.js.map +1 -0
- package/dist/ports/storage.d.ts +6 -0
- package/dist/ports/transcript-adapter.d.ts +11 -0
- package/dist/ports/wiki-writer.d.ts +19 -0
- package/dist/ports/wiki-writer.js +12 -0
- package/dist/ports/wiki-writer.js.map +1 -0
- package/dist/ports/workstream-store.d.ts +20 -12
- package/dist/shared/net.d.ts +3 -0
- package/dist/shared/net.js +4 -0
- package/dist/shared/net.js.map +1 -0
- package/dist/shared/types.d.ts +55 -0
- package/dist/shared/types.js +4 -1
- package/dist/shared/types.js.map +1 -1
- package/dist/shared/version.d.ts +9 -0
- package/dist/shared/version.js +11 -0
- package/dist/shared/version.js.map +1 -0
- package/dist/ui/assets/index-D6F3xAis.js +11 -0
- package/dist/ui/index.html +1 -1
- package/migrations/029_project_scope.sql +21 -0
- package/migrations/032_session_derivables.sql +11 -0
- package/migrations/033_actions_kind_check.sql +58 -0
- package/migrations/034_tenancy_teams_and_stamps.sql +40 -0
- package/migrations/035_tenancy_entity_rekey.sql +75 -0
- package/migrations/036_tenant_name_uniqueness.sql +59 -0
- package/migrations/037_sessions_covering_index.sql +25 -0
- package/migrations/038_sources_muse.sql +33 -0
- package/migrations/039_learner_evidence.sql +51 -0
- package/migrations/pg/030_project_scope.sql +23 -0
- package/migrations/pg/031_widen_session_edges_kind.sql +11 -0
- package/migrations/pg/032_session_derivables.sql +17 -0
- package/migrations/pg/033_actions_kind_check.sql +17 -0
- package/migrations/pg/034_tenancy.sql +77 -0
- package/migrations/pg/035_tenant_name_uniqueness.sql +15 -0
- package/migrations/pg/036_sources_muse.sql +12 -0
- package/migrations/pg/037_learner_evidence.sql +55 -0
- package/nlm/index.js +258 -59
- package/package.json +10 -5
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/scripts/prompt-recall-hook.mjs +256 -58
- package/plugin/scripts/session-start-hook.mjs +283 -55
- package/plugin/scripts/stop-hook.mjs +199 -38
- package/dist/hook/subagent-start-hook.d.ts +0 -28
- package/dist/hook/subagent-start-hook.js +0 -81
- package/dist/hook/subagent-start-hook.js.map +0 -1
- package/dist/ui/assets/index-CMpQkbQy.js +0 -11
|
@@ -1,19 +1,38 @@
|
|
|
1
|
+
import { makeWorkstreamId } from "./model.js";
|
|
1
2
|
import { decideWorkstreamByName } from "./name-match.js";
|
|
3
|
+
import { scopeStampEnabled } from "../scope/stamp-flag.js";
|
|
2
4
|
export const NAMING_CONTENT_CHARS = 8000;
|
|
3
|
-
|
|
5
|
+
function scopeMatches(wsScope, sessionScope) {
|
|
6
|
+
return wsScope === sessionScope;
|
|
7
|
+
}
|
|
8
|
+
async function applyBinding(deps, tenantId, input, workstreamId) {
|
|
9
|
+
await deps.sessions.setWorkstreamBinding(tenantId, input.sessionId, workstreamId, deps.source ?? "classifier", null);
|
|
10
|
+
await deps.workstreams.upsertEntities(tenantId, workstreamId, input.entities);
|
|
11
|
+
await deps.workstreams.touchLastSession(tenantId, workstreamId, input.startedAt);
|
|
12
|
+
return { workstreamId };
|
|
13
|
+
}
|
|
14
|
+
export async function bindSessionToWorkstream(deps, tenantId, input) {
|
|
4
15
|
try {
|
|
5
|
-
const
|
|
6
|
-
const hints = ws.map((w) => ({ label: w.label }));
|
|
16
|
+
const all = await deps.workstreams.listAll(tenantId);
|
|
7
17
|
const content = `${input.label}\n${(input.body || input.summary).slice(0, NAMING_CONTENT_CHARS)}`;
|
|
8
|
-
|
|
9
|
-
|
|
18
|
+
if (scopeStampEnabled()) {
|
|
19
|
+
const scoped = all.filter((w) => scopeMatches(w.scope, input.scope));
|
|
20
|
+
const named = await deps.namer.nameWorkstream(content, scoped.map((w) => ({ label: w.label })));
|
|
21
|
+
const decision = decideWorkstreamByName(named, scoped, deps.aliasToLabel);
|
|
22
|
+
if (decision.kind === "bind") {
|
|
23
|
+
return applyBinding(deps, tenantId, input, decision.workstreamId);
|
|
24
|
+
}
|
|
25
|
+
if (named && named.trim()) {
|
|
26
|
+
const ws = await deps.workstreams.create(tenantId, { id: makeWorkstreamId(), label: named.trim(), scope: input.scope });
|
|
27
|
+
return applyBinding(deps, tenantId, input, ws.id);
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
const named = await deps.namer.nameWorkstream(content, all.map((w) => ({ label: w.label })));
|
|
32
|
+
const decision = decideWorkstreamByName(named, all, deps.aliasToLabel);
|
|
10
33
|
if (decision.kind === "abstain")
|
|
11
34
|
return null;
|
|
12
|
-
|
|
13
|
-
await deps.sessions.setWorkstreamBinding(input.sessionId, workstreamId, deps.source ?? "classifier", null);
|
|
14
|
-
await deps.workstreams.upsertEntities(workstreamId, input.entities);
|
|
15
|
-
await deps.workstreams.touchLastSession(workstreamId, input.startedAt);
|
|
16
|
-
return { workstreamId };
|
|
35
|
+
return applyBinding(deps, tenantId, input, decision.workstreamId);
|
|
17
36
|
}
|
|
18
37
|
catch (e) {
|
|
19
38
|
deps.log?.(`[workstream] bind failed for ${input.sessionId}: ${e instanceof Error ? e.message : String(e)}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bind.js","sourceRoot":"","sources":["../../../src/core/workstream/bind.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"bind.js","sourceRoot":"","sources":["../../../src/core/workstream/bind.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,6 +8,7 @@ export interface Workstream {
|
|
|
8
8
|
readonly createdAt: string;
|
|
9
9
|
readonly updatedAt: string;
|
|
10
10
|
readonly lastSessionAt: string | null;
|
|
11
|
+
readonly scope: string | null;
|
|
11
12
|
}
|
|
12
13
|
export type BindingSource = "classifier" | "operator" | "backfill";
|
|
13
14
|
export interface WorkstreamRollup {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.js","sourceRoot":"","sources":["../../../src/core/workstream/model.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"model.js","sourceRoot":"","sources":["../../../src/core/workstream/model.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAyBzC,MAAM,UAAU,gBAAgB;IAC9B,OAAO,MAAM,UAAU,EAAE,EAAE,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACzD,CAAC"}
|
|
@@ -9,4 +9,4 @@ export interface RollupDeps {
|
|
|
9
9
|
readonly facts: Pick<FactStore, "listBySessions">;
|
|
10
10
|
readonly exemplars: Pick<CodeExemplarStore, "listBySessions">;
|
|
11
11
|
}
|
|
12
|
-
export declare function rollupWorkstream(deps: RollupDeps, workstreamId: string): Promise<WorkstreamRollup | null>;
|
|
12
|
+
export declare function rollupWorkstream(deps: RollupDeps, tenantId: string, workstreamId: string): Promise<WorkstreamRollup | null>;
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { resolveWorkstreamId } from "./resolve.js";
|
|
2
|
-
export async function rollupWorkstream(deps, workstreamId) {
|
|
3
|
-
const all = await deps.workstreams.listAll();
|
|
2
|
+
export async function rollupWorkstream(deps, tenantId, workstreamId) {
|
|
3
|
+
const all = await deps.workstreams.listAll(tenantId);
|
|
4
4
|
const byId = new Map(all.map((w) => [w.id, { id: w.id, mergedInto: w.mergedInto }]));
|
|
5
5
|
const survivorId = resolveWorkstreamId(workstreamId, byId);
|
|
6
|
-
const workstream = await deps.workstreams.getById(survivorId);
|
|
6
|
+
const workstream = await deps.workstreams.getById(tenantId, survivorId);
|
|
7
7
|
if (!workstream)
|
|
8
8
|
return null;
|
|
9
9
|
const memberIds = all.filter((w) => resolveWorkstreamId(w.id, byId) === survivorId).map((w) => w.id);
|
|
10
|
-
const sessionIds = await deps.sessions.listSessionIdsByWorkstreams(memberIds);
|
|
10
|
+
const sessionIds = await deps.sessions.listSessionIdsByWorkstreams(tenantId, memberIds);
|
|
11
11
|
const [facts, exemplars] = await Promise.all([
|
|
12
|
-
deps.facts.listBySessions(sessionIds),
|
|
13
|
-
deps.exemplars.listBySessions(sessionIds),
|
|
12
|
+
deps.facts.listBySessions(tenantId, sessionIds),
|
|
13
|
+
deps.exemplars.listBySessions(tenantId, sessionIds),
|
|
14
14
|
]);
|
|
15
15
|
return { workstream, sessionIds, facts, exemplars };
|
|
16
16
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rollup.js","sourceRoot":"","sources":["../../../src/core/workstream/rollup.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AASnD,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAgB,EAAE,YAAoB;
|
|
1
|
+
{"version":3,"file":"rollup.js","sourceRoot":"","sources":["../../../src/core/workstream/rollup.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AASnD,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAgB,EAAE,QAAgB,EAAE,YAAoB;IAC7F,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACrD,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;IACrF,MAAM,UAAU,GAAG,mBAAmB,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;IAC3D,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IACxE,IAAI,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IAE7B,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACrG,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,2BAA2B,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACxF,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC3C,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,QAAQ,EAAE,UAAU,CAAC;QAC/C,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,QAAQ,EAAE,UAAU,CAAC;KACpD,CAAC,CAAC;IACH,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;AACtD,CAAC"}
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "Am I the entry point?" for a hook module, tolerant of symlinked installs.
|
|
3
|
+
*
|
|
4
|
+
* Node realpath-resolves `import.meta.url` but leaves `process.argv[1]` as the
|
|
5
|
+
* literal string the caller passed. Comparing them directly means any
|
|
6
|
+
* symlinked path fails the check, main() never runs, and the hook exits 0
|
|
7
|
+
* having silently done nothing. A versioned install with a `current` ->
|
|
8
|
+
* versions/X pointer invokes hooks through exactly such a symlink, so the
|
|
9
|
+
* naive comparison disables session capture while still reporting success.
|
|
10
|
+
*
|
|
11
|
+
* Resolving argv[1] before comparing makes the two agree in both layouts.
|
|
12
|
+
* A nonexistent argv[1] is not an error here — it just isn't us.
|
|
13
|
+
*/
|
|
14
|
+
export declare function isMainModule(metaUrl: string, argv1: string | undefined): boolean;
|
|
1
15
|
export declare function readStdin(): Promise<string>;
|
|
2
16
|
export declare function fetchWithTimeout(url: string, init: RequestInit, ms: number): Promise<Response>;
|
|
3
17
|
export declare function hookModeFromEnv(): "shadow" | "live";
|
|
@@ -1,6 +1,33 @@
|
|
|
1
|
-
import { appendFileSync, mkdirSync } from "node:fs";
|
|
1
|
+
import { appendFileSync, mkdirSync, realpathSync } from "node:fs";
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
|
+
import { pathToFileURL } from "node:url";
|
|
5
|
+
import { NLM_VERSION } from "../shared/version.js";
|
|
6
|
+
/**
|
|
7
|
+
* "Am I the entry point?" for a hook module, tolerant of symlinked installs.
|
|
8
|
+
*
|
|
9
|
+
* Node realpath-resolves `import.meta.url` but leaves `process.argv[1]` as the
|
|
10
|
+
* literal string the caller passed. Comparing them directly means any
|
|
11
|
+
* symlinked path fails the check, main() never runs, and the hook exits 0
|
|
12
|
+
* having silently done nothing. A versioned install with a `current` ->
|
|
13
|
+
* versions/X pointer invokes hooks through exactly such a symlink, so the
|
|
14
|
+
* naive comparison disables session capture while still reporting success.
|
|
15
|
+
*
|
|
16
|
+
* Resolving argv[1] before comparing makes the two agree in both layouts.
|
|
17
|
+
* A nonexistent argv[1] is not an error here — it just isn't us.
|
|
18
|
+
*/
|
|
19
|
+
export function isMainModule(metaUrl, argv1) {
|
|
20
|
+
if (!argv1)
|
|
21
|
+
return false;
|
|
22
|
+
let resolved;
|
|
23
|
+
try {
|
|
24
|
+
resolved = realpathSync(argv1);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
return metaUrl === pathToFileURL(resolved).href;
|
|
30
|
+
}
|
|
4
31
|
export function readStdin() {
|
|
5
32
|
return new Promise((resolve) => {
|
|
6
33
|
let data = "";
|
|
@@ -27,7 +54,7 @@ export function appendHookEvent(data) {
|
|
|
27
54
|
try {
|
|
28
55
|
const path = process.env["NLM_HOOK_LOG"] ?? join(homedir(), ".nlm", "hook-log.jsonl");
|
|
29
56
|
mkdirSync(dirname(path), { recursive: true });
|
|
30
|
-
appendFileSync(path, `${JSON.stringify(data)}\n`, "utf8");
|
|
57
|
+
appendFileSync(path, `${JSON.stringify({ ...data, v: NLM_VERSION })}\n`, "utf8");
|
|
31
58
|
}
|
|
32
59
|
catch {
|
|
33
60
|
// Telemetry failure must never break the hook.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hook-helpers.js","sourceRoot":"","sources":["../../src/hook/hook-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"hook-helpers.js","sourceRoot":"","sources":["../../src/hook/hook-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,YAAY,CAAC,OAAe,EAAE,KAAyB;IACrE,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACzB,IAAI,QAAgB,CAAC;IACrB,IAAI,CAAC;QACH,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,OAAO,KAAK,aAAa,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,SAAS;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAClC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC;QACrD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QAC7C,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,GAAW,EACX,IAAiB,EACjB,EAAU;IAEV,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;IACvD,IAAI,CAAC;QACH,OAAO,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;IAClE,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAA6B;IAC3D,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAAC;QACtF,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9C,cAAc,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACnF,CAAC;IAAC,MAAM,CAAC;QACP,+CAA+C;IACjD,CAAC;AACH,CAAC"}
|
|
@@ -12,14 +12,17 @@
|
|
|
12
12
|
*
|
|
13
13
|
* Fail-open by design: any error yields a clean exit with no output.
|
|
14
14
|
*/
|
|
15
|
-
import { pathToFileURL } from "node:url";
|
|
16
15
|
import { loadSurfaced } from "../core/hook/memo.js";
|
|
16
|
+
import { DEFAULT_TEAM_ID } from "../core/tenancy/default-team.js";
|
|
17
17
|
import { autoloadEnv } from "../llm/env-autoload.js";
|
|
18
18
|
import { hookAuthHeaders } from "./hook-auth.js";
|
|
19
|
-
import { readStdin, fetchWithTimeout, appendHookEvent } from "./hook-helpers.js";
|
|
19
|
+
import { readStdin, fetchWithTimeout, appendHookEvent, isMainModule } from "./hook-helpers.js";
|
|
20
|
+
import { DEFAULT_NLM_PORT } from "../shared/net.js";
|
|
20
21
|
const POST_TIMEOUT_MS = 1500;
|
|
21
|
-
export async function runPreCompact(input, portValue = process.env["NLM_PORT"] ??
|
|
22
|
-
|
|
22
|
+
export async function runPreCompact(input, portValue = process.env["NLM_PORT"] ?? DEFAULT_NLM_PORT) {
|
|
23
|
+
// Client-side hook composition root: no per-tenant CLI/hook concept exists
|
|
24
|
+
// today, so DEFAULT_TEAM_ID is this surface's real identity, not a placeholder.
|
|
25
|
+
const surfacedSet = [...loadSurfaced(DEFAULT_TEAM_ID, input.conversationId)];
|
|
23
26
|
const payload = {
|
|
24
27
|
conversation_id: input.conversationId,
|
|
25
28
|
transcript_path: input.transcriptPath,
|
|
@@ -60,7 +63,7 @@ async function main() {
|
|
|
60
63
|
// Fail open — never block Claude Code compaction.
|
|
61
64
|
}
|
|
62
65
|
}
|
|
63
|
-
if (
|
|
66
|
+
if (isMainModule(import.meta.url, process.argv[1])) {
|
|
64
67
|
void main();
|
|
65
68
|
}
|
|
66
69
|
//# sourceMappingURL=pre-compact-hook.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pre-compact-hook.js","sourceRoot":"","sources":["../../src/hook/pre-compact-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"pre-compact-hook.js","sourceRoot":"","sources":["../../src/hook/pre-compact-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC/F,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,eAAe,GAAG,IAAI,CAAC;AAY7B,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,KAAsB,EACtB,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,gBAAgB;IAEvD,2EAA2E;IAC3E,gFAAgF;IAChF,MAAM,WAAW,GAAG,CAAC,GAAG,YAAY,CAAC,eAAe,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;IAC7E,MAAM,OAAO,GAAG;QACd,eAAe,EAAE,KAAK,CAAC,cAAc;QACrC,eAAe,EAAE,KAAK,CAAC,cAAc;QACrC,YAAY,EAAE,WAAW;QACzB,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KAC7B,CAAC;IACF,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAChC,oBAAoB,SAAS,uBAAuB,EACpD;YACE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,eAAe,CAAC,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;YAChE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;SAC9B,EACD,eAAe,CAChB,CAAC;QACF,OAAO,EAAE,cAAc,EAAE,KAAK,CAAC,cAAc,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC;IAClE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,cAAc,EAAE,KAAK,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IACjE,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,MAAwB;IACzC,eAAe,CAAC;QACd,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAC5B,IAAI,EAAE,aAAa;QACnB,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC;QACH,WAAW,EAAE,CAAC;QACd,MAAM,GAAG,GAAG,MAAM,SAAS,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAG7B,CAAC;QACF,MAAM,cAAc,GAClB,OAAO,OAAO,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;QAC1E,MAAM,cAAc,GAClB,OAAO,OAAO,CAAC,eAAe,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7E,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,EAAE,cAAc,EAAE,cAAc,EAAE,CAAC,CAAC;QACvE,SAAS,CAAC,MAAM,CAAC,CAAC;IACpB,CAAC;IAAC,MAAM,CAAC;QACP,kDAAkD;IACpD,CAAC;AACH,CAAC;AAED,IAAI,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACnD,KAAK,IAAI,EAAE,CAAC;AACd,CAAC"}
|
|
@@ -9,9 +9,11 @@
|
|
|
9
9
|
* read from NLM_HOOK_RUNTIME (default "claude-code") so packaged hooks can
|
|
10
10
|
* share this entrypoint without polluting query logs.
|
|
11
11
|
*/
|
|
12
|
-
import { type PointerExemplar, type PointerFact } from "../core/hook/pointer-block.js";
|
|
12
|
+
import { type PointerConcept, type PointerExemplar, type PointerFact } from "../core/hook/pointer-block.js";
|
|
13
13
|
import { type RecallHitInput } from "../core/hook/select.js";
|
|
14
|
-
|
|
14
|
+
import { type RecallOutcome } from "./recall-over-http.js";
|
|
15
|
+
export declare function parseHookDeadline(raw: string | undefined, defaultMs?: number): number;
|
|
16
|
+
export declare function hookDeadlineMs(): number;
|
|
15
17
|
export type HookMode = "shadow" | "live";
|
|
16
18
|
export declare function hookRuntimeFromEnv(env?: NodeJS.ProcessEnv): string;
|
|
17
19
|
/**
|
|
@@ -45,6 +47,8 @@ export interface RecallFetchResult {
|
|
|
45
47
|
readonly hits: ReadonlyArray<RecallHitInput>;
|
|
46
48
|
readonly facts: ReadonlyArray<PointerFact>;
|
|
47
49
|
readonly exemplars?: ReadonlyArray<PointerExemplar>;
|
|
50
|
+
readonly concepts?: ReadonlyArray<PointerConcept>;
|
|
51
|
+
readonly outcome?: RecallOutcome;
|
|
48
52
|
}
|
|
49
53
|
export type GateMode = "shadow" | "live";
|
|
50
54
|
export interface RecallGate {
|
|
@@ -64,7 +68,7 @@ export interface RunHookDeps {
|
|
|
64
68
|
readonly recall: (prompt: string) => Promise<ReadonlyArray<RecallHitInput> | RecallFetchResult>;
|
|
65
69
|
/** Optional pre-injection relevance gate. Absent => no gating (today's behavior). */
|
|
66
70
|
readonly recallGate?: RecallGate;
|
|
67
|
-
/** Wall-clock deadline for the combined recall + gate stages. Defaults to NLM_HOOK_DEADLINE_MS (
|
|
71
|
+
/** Wall-clock deadline for the combined recall + gate stages. Defaults to NLM_HOOK_DEADLINE_MS (6000ms; must exceed the recall HTTP timeout, see #396). */
|
|
68
72
|
readonly deadlineMs?: number;
|
|
69
73
|
}
|
|
70
74
|
/** Orchestration. Returns the text to emit on stdout ("" for nothing). */
|
|
@@ -9,18 +9,18 @@
|
|
|
9
9
|
* read from NLM_HOOK_RUNTIME (default "claude-code") so packaged hooks can
|
|
10
10
|
* share this entrypoint without polluting query logs.
|
|
11
11
|
*/
|
|
12
|
-
import { pathToFileURL } from "node:url";
|
|
13
12
|
import { classifyPrompt } from "../core/hook/gate.js";
|
|
14
13
|
import { recentConversationContext, topicalWordCount } from "./recent-context.js";
|
|
15
14
|
import { appendHookLog } from "../core/hook/hook-log.js";
|
|
16
15
|
import { loadSurfaced, recordSurfaced } from "../core/hook/memo.js";
|
|
16
|
+
import { DEFAULT_TEAM_ID } from "../core/tenancy/default-team.js";
|
|
17
17
|
import { formatPointerBlock } from "../core/hook/pointer-block.js";
|
|
18
18
|
import { selectHits } from "../core/hook/select.js";
|
|
19
19
|
import { autoloadEnv } from "../llm/env-autoload.js";
|
|
20
20
|
import { recallOverHttp } from "./recall-over-http.js";
|
|
21
21
|
import { parseScoreFloor, parseRelativeFloor } from "./score-floor.js";
|
|
22
22
|
import { makeOllamaGate, parseRecallGateMode } from "./recall-gate.js";
|
|
23
|
-
import { readStdin, hookModeFromEnv } from "./hook-helpers.js";
|
|
23
|
+
import { readStdin, hookModeFromEnv, isMainModule } from "./hook-helpers.js";
|
|
24
24
|
// Keyword recall returns raw BM25 scores (unbounded, not the 0..1 hybrid
|
|
25
25
|
// scale). FTS5 MATCH already gates relevance — only lexically-matching
|
|
26
26
|
// sessions come back — so the default floor is 0. NLM_RECALL_SCORE_FLOOR lets
|
|
@@ -29,22 +29,31 @@ import { readStdin, hookModeFromEnv } from "./hook-helpers.js";
|
|
|
29
29
|
// parseScoreFloor guards against a bad env value: a non-numeric / non-finite /
|
|
30
30
|
// negative input falls back to 0 instead of silently deny-all'ing recall
|
|
31
31
|
// (matchScore >= NaN is always false in select.ts).
|
|
32
|
-
|
|
32
|
+
// Lazy, not module-scope: autoloadEnv() runs inside main(), after imports are
|
|
33
|
+
// evaluated, so an eager read silently ignores ~/.nlm/.env. See recallTimeoutMs
|
|
34
|
+
// in recall-over-http.ts.
|
|
35
|
+
const scoreThreshold = () => parseScoreFloor(process.env["NLM_RECALL_SCORE_FLOOR"]);
|
|
33
36
|
// Portable per-fire noise floor: drop tail hits below this fraction of the
|
|
34
37
|
// fire's median score. Default 0.9 (calibrated, #284) — trims weak tail recalls
|
|
35
38
|
// while keeping ~97% of cited ones. Only the per-message keyword path runs this;
|
|
36
39
|
// the session-start hybrid path is left unfiltered (unmeasured).
|
|
37
|
-
const
|
|
40
|
+
const relativeFloor = () => parseRelativeFloor(process.env["NLM_RECALL_REL_FLOOR"], 0.9);
|
|
38
41
|
const PER_FIRE_CAP = 3;
|
|
39
42
|
const PER_CONVERSATION_CAP = 10;
|
|
40
43
|
const PROMPT_PREVIEW_CHARS = 200;
|
|
41
|
-
export function parseHookDeadline(raw) {
|
|
44
|
+
export function parseHookDeadline(raw, defaultMs = 4000) {
|
|
42
45
|
if (raw === undefined)
|
|
43
|
-
return
|
|
46
|
+
return defaultMs;
|
|
44
47
|
const n = Number(raw);
|
|
45
|
-
return Number.isFinite(n) && n > 0 ? n :
|
|
48
|
+
return Number.isFinite(n) && n > 0 ? n : defaultMs;
|
|
49
|
+
}
|
|
50
|
+
// #396: the outer deadline wraps recall + gate + formatting and must exceed
|
|
51
|
+
// RECALL_TIMEOUT_MS (default 4000ms in recall-over-http.ts) with headroom.
|
|
52
|
+
// Invariant: HOOK_DEADLINE_MS > RECALL_TIMEOUT_MS at defaults. If the outer
|
|
53
|
+
// equals the inner, the deadline fires before post-recall work can complete.
|
|
54
|
+
export function hookDeadlineMs() {
|
|
55
|
+
return parseHookDeadline(process.env["NLM_HOOK_DEADLINE_MS"], 6000);
|
|
46
56
|
}
|
|
47
|
-
const HOOK_DEADLINE_MS = parseHookDeadline(process.env["NLM_HOOK_DEADLINE_MS"]);
|
|
48
57
|
async function withDeadline(p, ms, fallback) {
|
|
49
58
|
if (ms <= 0)
|
|
50
59
|
return fallback;
|
|
@@ -107,7 +116,9 @@ export async function runHook(input, deps) {
|
|
|
107
116
|
const gate = classifyPrompt(input.prompt);
|
|
108
117
|
const preview = input.prompt.slice(0, PROMPT_PREVIEW_CHARS);
|
|
109
118
|
if (gate === "generative" || gate === "skip") {
|
|
110
|
-
|
|
119
|
+
// Client-side hook composition root: no per-tenant CLI/hook concept exists
|
|
120
|
+
// today, so DEFAULT_TEAM_ID is this surface's real identity, not a placeholder.
|
|
121
|
+
appendHookLog(DEFAULT_TEAM_ID, {
|
|
111
122
|
ts: new Date().toISOString(),
|
|
112
123
|
conversationId: input.conversationId,
|
|
113
124
|
promptPreview: preview,
|
|
@@ -119,21 +130,24 @@ export async function runHook(input, deps) {
|
|
|
119
130
|
});
|
|
120
131
|
return "";
|
|
121
132
|
}
|
|
122
|
-
const deadline = Date.now() + (deps.deadlineMs ??
|
|
123
|
-
|
|
133
|
+
const deadline = Date.now() + (deps.deadlineMs ?? hookDeadlineMs());
|
|
134
|
+
// The outer deadline and the inner HTTP timeout are separate budgets; both
|
|
135
|
+
// yield an empty result, so both must name themselves or the log conflates
|
|
136
|
+
// them with a real miss.
|
|
137
|
+
let fetched = { hits: [], facts: [], outcome: "timeout" };
|
|
124
138
|
try {
|
|
125
|
-
fetched = normalizeRecall(await withDeadline(deps.recall(buildRecallQuery(input)), deadline - Date.now(), { hits: [], facts: [] }));
|
|
139
|
+
fetched = normalizeRecall(await withDeadline(deps.recall(buildRecallQuery(input)), deadline - Date.now(), { hits: [], facts: [], outcome: "timeout" }));
|
|
126
140
|
}
|
|
127
141
|
catch {
|
|
128
|
-
fetched = { hits: [], facts: [] };
|
|
142
|
+
fetched = { hits: [], facts: [], outcome: "unreachable" };
|
|
129
143
|
}
|
|
130
144
|
const hits = fetched.hits;
|
|
131
|
-
const surfaced = loadSurfaced(input.conversationId);
|
|
145
|
+
const surfaced = loadSurfaced(DEFAULT_TEAM_ID, input.conversationId);
|
|
132
146
|
const selected = selectHits({
|
|
133
147
|
hits,
|
|
134
148
|
surfaced,
|
|
135
|
-
scoreThreshold:
|
|
136
|
-
relativeFloor:
|
|
149
|
+
scoreThreshold: scoreThreshold(),
|
|
150
|
+
relativeFloor: relativeFloor(),
|
|
137
151
|
perFireCap: PER_FIRE_CAP,
|
|
138
152
|
perConversationCap: PER_CONVERSATION_CAP,
|
|
139
153
|
});
|
|
@@ -159,9 +173,9 @@ export async function runHook(input, deps) {
|
|
|
159
173
|
injected = selected.filter((h) => !drop.has(h.id));
|
|
160
174
|
}
|
|
161
175
|
}
|
|
162
|
-
const block = formatPointerBlock(injected, fetched.facts, fetched.exemplars);
|
|
176
|
+
const block = formatPointerBlock(injected, fetched.facts, fetched.exemplars, fetched.concepts ?? []);
|
|
163
177
|
const estTokens = Math.ceil(block.length / 4);
|
|
164
|
-
appendHookLog({
|
|
178
|
+
appendHookLog(DEFAULT_TEAM_ID, {
|
|
165
179
|
ts: new Date().toISOString(),
|
|
166
180
|
conversationId: input.conversationId,
|
|
167
181
|
promptPreview: preview,
|
|
@@ -170,10 +184,11 @@ export async function runHook(input, deps) {
|
|
|
170
184
|
wouldInject: injected.map((h) => h.id),
|
|
171
185
|
estTokens,
|
|
172
186
|
mode: deps.mode,
|
|
187
|
+
...(fetched.outcome ? { recallOutcome: fetched.outcome } : {}),
|
|
173
188
|
...(gateDecisions ? { gateDecisions } : {}),
|
|
174
189
|
});
|
|
175
190
|
if (deps.mode === "live" && injected.length > 0) {
|
|
176
|
-
recordSurfaced(input.conversationId, injected.map((h) => h.id));
|
|
191
|
+
recordSurfaced(DEFAULT_TEAM_ID, input.conversationId, injected.map((h) => h.id));
|
|
177
192
|
return block;
|
|
178
193
|
}
|
|
179
194
|
return "";
|
|
@@ -217,7 +232,7 @@ async function main() {
|
|
|
217
232
|
}
|
|
218
233
|
}
|
|
219
234
|
// Run main() only when invoked directly as a script, not when imported by tests.
|
|
220
|
-
if (
|
|
235
|
+
if (isMainModule(import.meta.url, process.argv[1])) {
|
|
221
236
|
void main();
|
|
222
237
|
}
|
|
223
238
|
//# sourceMappingURL=prompt-recall-hook.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt-recall-hook.js","sourceRoot":"","sources":["../../src/hook/prompt-recall-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"prompt-recall-hook.js","sourceRoot":"","sources":["../../src/hook/prompt-recall-hook.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,12 +13,37 @@
|
|
|
13
13
|
* code exemplar recall). The HTTP handler returns this when &withExemplars=true.
|
|
14
14
|
*/
|
|
15
15
|
import type { RecallHitInput } from "../core/hook/select.js";
|
|
16
|
-
import type { PointerExemplar, PointerFact } from "../core/hook/pointer-block.js";
|
|
16
|
+
import type { PointerConcept, PointerExemplar, PointerFact } from "../core/hook/pointer-block.js";
|
|
17
17
|
export declare const RECALL_LIMIT = 5;
|
|
18
|
-
export declare
|
|
18
|
+
export declare function parseRecallTimeout(raw: string | undefined): number;
|
|
19
|
+
/**
|
|
20
|
+
* Read at call time, not module scope. Hook entrypoints call autoloadEnv()
|
|
21
|
+
* inside main(), which runs AFTER every import has been evaluated — so a
|
|
22
|
+
* module-scope read captures the environment before ~/.nlm/.env is loaded and
|
|
23
|
+
* silently ignores anything set there. Same hazard the MCP servers avoid by
|
|
24
|
+
* importing a side-effect env module first; a lazy read is immune to import
|
|
25
|
+
* order entirely. Keep every env-derived hook knob lazy for this reason.
|
|
26
|
+
*/
|
|
27
|
+
export declare function recallTimeoutMs(): number;
|
|
28
|
+
/**
|
|
29
|
+
* Why the recall returned what it did. Without this, a timed-out recall and a
|
|
30
|
+
* genuinely-empty one are the same empty object, so a dead recall path reads
|
|
31
|
+
* as "nothing relevant" on every diagnostic surface — the failure that hid a
|
|
32
|
+
* two-week hook outage behind a healthy-looking digest.
|
|
33
|
+
*/
|
|
34
|
+
export type RecallOutcome = "ok" | "timeout" | "unreachable" | "http-error" | "skipped";
|
|
19
35
|
export interface RecallOverHttpResult {
|
|
20
36
|
readonly hits: ReadonlyArray<RecallHitInput>;
|
|
21
37
|
readonly facts: ReadonlyArray<PointerFact>;
|
|
22
38
|
readonly exemplars: ReadonlyArray<PointerExemplar>;
|
|
39
|
+
readonly concepts: ReadonlyArray<PointerConcept>;
|
|
40
|
+
readonly outcome: RecallOutcome;
|
|
23
41
|
}
|
|
24
|
-
|
|
42
|
+
/**
|
|
43
|
+
* `source` is the recall-precision bucket this fire is attributed to. It must
|
|
44
|
+
* name the CALLER, not the transport: prompt recall queries a real user prompt
|
|
45
|
+
* while session-start queries a derived project name, so blending them under
|
|
46
|
+
* one label hides two very different achievable ceilings behind one number.
|
|
47
|
+
* Defaults to "hook" because prompt recall is the majority caller.
|
|
48
|
+
*/
|
|
49
|
+
export declare function recallOverHttp(prompt: string, runtime?: string, conversationId?: string, mode?: "keyword" | "hybrid", source?: string): Promise<RecallOverHttpResult>;
|
|
@@ -15,33 +15,70 @@
|
|
|
15
15
|
import { hookAuthHeaders } from "./hook-auth.js";
|
|
16
16
|
import { extractRecallQuery } from "../core/hook/query-extract.js";
|
|
17
17
|
import { fetchWithTimeout } from "./hook-helpers.js";
|
|
18
|
+
import { DEFAULT_NLM_PORT } from "../shared/net.js";
|
|
18
19
|
export const RECALL_LIMIT = 5;
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
// #396: the budget must exceed the daemon's worst-case sequential hybrid path
|
|
21
|
+
// (keyword ~839ms + embed capped at NLM_RECALL_EMBED_DEADLINE_MS default 2000ms
|
|
22
|
+
// + semantic ~50ms + response overhead ~100ms = ~2990ms floor). A budget at or
|
|
23
|
+
// below the daemon's embed cap re-creates the dead passive layer even after the
|
|
24
|
+
// daemon-side embed fix in 73406260: the hook gives up before the embed deadline
|
|
25
|
+
// fires and the daemon finishes building the response.
|
|
26
|
+
export function parseRecallTimeout(raw) {
|
|
27
|
+
if (raw === undefined)
|
|
28
|
+
return 4000;
|
|
29
|
+
const n = Number(raw);
|
|
30
|
+
return Number.isFinite(n) && n > 0 ? n : 4000;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Read at call time, not module scope. Hook entrypoints call autoloadEnv()
|
|
34
|
+
* inside main(), which runs AFTER every import has been evaluated — so a
|
|
35
|
+
* module-scope read captures the environment before ~/.nlm/.env is loaded and
|
|
36
|
+
* silently ignores anything set there. Same hazard the MCP servers avoid by
|
|
37
|
+
* importing a side-effect env module first; a lazy read is immune to import
|
|
38
|
+
* order entirely. Keep every env-derived hook knob lazy for this reason.
|
|
39
|
+
*/
|
|
40
|
+
export function recallTimeoutMs() {
|
|
41
|
+
return parseRecallTimeout(process.env["NLM_HOOK_RECALL_TIMEOUT_MS"]);
|
|
42
|
+
}
|
|
43
|
+
const emptyResult = (outcome) => ({
|
|
44
|
+
hits: [],
|
|
45
|
+
facts: [],
|
|
46
|
+
exemplars: [],
|
|
47
|
+
concepts: [],
|
|
48
|
+
outcome,
|
|
49
|
+
});
|
|
50
|
+
/**
|
|
51
|
+
* `source` is the recall-precision bucket this fire is attributed to. It must
|
|
52
|
+
* name the CALLER, not the transport: prompt recall queries a real user prompt
|
|
53
|
+
* while session-start queries a derived project name, so blending them under
|
|
54
|
+
* one label hides two very different achievable ceilings behind one number.
|
|
55
|
+
* Defaults to "hook" because prompt recall is the majority caller.
|
|
56
|
+
*/
|
|
57
|
+
export async function recallOverHttp(prompt, runtime, conversationId, mode = "keyword", source = "hook") {
|
|
21
58
|
const query = extractRecallQuery(prompt);
|
|
22
59
|
if (query === null)
|
|
23
|
-
return
|
|
24
|
-
const portValue = process.env["NLM_PORT"] ??
|
|
60
|
+
return emptyResult("skipped");
|
|
61
|
+
const portValue = process.env["NLM_PORT"] ?? DEFAULT_NLM_PORT;
|
|
25
62
|
const url =
|
|
26
63
|
// 127.0.0.1, not localhost: each hook is a fresh process with no connection
|
|
27
64
|
// reuse, and Node resolves localhost to IPv6 ::1 first — a measured ~50-300ms
|
|
28
65
|
// per-fire connect penalty vs ~3ms on the explicit IPv4 loopback.
|
|
29
66
|
`http://127.0.0.1:${portValue}/api/recall` +
|
|
30
|
-
`?q=${encodeURIComponent(query)}&mode=${mode}&limit=${RECALL_LIMIT}&withFacts=true&withExemplars=true` +
|
|
67
|
+
`?q=${encodeURIComponent(query)}&mode=${mode}&limit=${RECALL_LIMIT}&withFacts=true&withExemplars=true&withConcepts=true` +
|
|
31
68
|
(conversationId ? `&conversation_id=${encodeURIComponent(conversationId)}` : "");
|
|
32
69
|
try {
|
|
33
|
-
const extra = { "x-recall-source":
|
|
70
|
+
const extra = { "x-recall-source": source };
|
|
34
71
|
if (runtime)
|
|
35
72
|
extra["x-recall-runtime"] = runtime;
|
|
36
|
-
const res = await fetchWithTimeout(url, { headers: hookAuthHeaders(extra) },
|
|
73
|
+
const res = await fetchWithTimeout(url, { headers: hookAuthHeaders(extra) }, recallTimeoutMs());
|
|
37
74
|
if (!res.ok)
|
|
38
|
-
return
|
|
75
|
+
return emptyResult("http-error");
|
|
39
76
|
let body;
|
|
40
77
|
try {
|
|
41
78
|
body = (await res.json());
|
|
42
79
|
}
|
|
43
80
|
catch {
|
|
44
|
-
return
|
|
81
|
+
return emptyResult("http-error");
|
|
45
82
|
}
|
|
46
83
|
const hits = (body.results ?? []).map((r) => ({
|
|
47
84
|
id: r.id,
|
|
@@ -62,10 +99,19 @@ export async function recallOverHttp(prompt, runtime, conversationId, mode = "ke
|
|
|
62
99
|
repo: e.repo,
|
|
63
100
|
taskContext: e.taskContext,
|
|
64
101
|
}));
|
|
65
|
-
|
|
102
|
+
const concepts = (body.relatedConcepts ?? []).map((c) => ({
|
|
103
|
+
concept: c.concept,
|
|
104
|
+
status: c.status,
|
|
105
|
+
attemptCount: c.attemptCount,
|
|
106
|
+
nextStep: c.nextStep,
|
|
107
|
+
}));
|
|
108
|
+
return { hits, facts, exemplars, concepts, outcome: "ok" };
|
|
66
109
|
}
|
|
67
|
-
catch {
|
|
68
|
-
|
|
110
|
+
catch (err) {
|
|
111
|
+
// fetchWithTimeout aborts on the deadline, which surfaces as AbortError.
|
|
112
|
+
// Anything else reaching here is a transport failure (refused, DNS, reset).
|
|
113
|
+
const aborted = err instanceof Error && err.name === "AbortError";
|
|
114
|
+
return emptyResult(aborted ? "timeout" : "unreachable");
|
|
69
115
|
}
|
|
70
116
|
}
|
|
71
117
|
//# sourceMappingURL=recall-over-http.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recall-over-http.js","sourceRoot":"","sources":["../../src/hook/recall-over-http.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"recall-over-http.js","sourceRoot":"","sources":["../../src/hook/recall-over-http.ts"],"names":[],"mappings":"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"}
|