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
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SqliteLearnerStore — LearnerStore over the shared better-sqlite3 connection.
|
|
3
|
+
*
|
|
4
|
+
* Constructor takes an already-opened, already-migrated Database handle from
|
|
5
|
+
* SqliteSessionStore.rawDb(). It does not open its own connection (same
|
|
6
|
+
* single-writer rationale as SqliteFactStore).
|
|
7
|
+
*
|
|
8
|
+
* Tenancy: `learners`, `enrollments`, `learning_events` are STAMP tables;
|
|
9
|
+
* every SELECT/UPDATE WHERE routes through `tenantClause`, INSERTs stamp
|
|
10
|
+
* `tenant_id` explicitly. Learner ids are human slugs, so `learners` PK is
|
|
11
|
+
* (tenant_id, id) — same-tenant addressing only, no cross-tenant visibility.
|
|
12
|
+
*/
|
|
13
|
+
import { learningEventContentEqual, makeEnrollmentId } from "../learner/model.js";
|
|
14
|
+
import { tenantClause } from "../tenancy/tenant-clause.js";
|
|
15
|
+
function learnerFromRow(row) {
|
|
16
|
+
return {
|
|
17
|
+
id: row.id,
|
|
18
|
+
label: row.label,
|
|
19
|
+
profile: JSON.parse(row.profile_json),
|
|
20
|
+
createdAt: row.created_at,
|
|
21
|
+
updatedAt: row.updated_at,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function enrollmentFromRow(row) {
|
|
25
|
+
return {
|
|
26
|
+
id: row.id,
|
|
27
|
+
learnerId: row.learner_id,
|
|
28
|
+
courseId: row.course_id,
|
|
29
|
+
workstreamId: row.workstream_id,
|
|
30
|
+
planRef: row.plan_ref,
|
|
31
|
+
planRevision: row.plan_revision,
|
|
32
|
+
planFingerprint: row.plan_fingerprint,
|
|
33
|
+
status: row.status,
|
|
34
|
+
completionHistory: JSON.parse(row.completion_history_json),
|
|
35
|
+
createdAt: row.created_at,
|
|
36
|
+
updatedAt: row.updated_at,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function eventFromRow(row) {
|
|
40
|
+
return {
|
|
41
|
+
id: row.id,
|
|
42
|
+
date: row.date,
|
|
43
|
+
covered: JSON.parse(row.covered_json),
|
|
44
|
+
attempts: JSON.parse(row.attempts_json),
|
|
45
|
+
interpretation: row.interpretation,
|
|
46
|
+
nextStep: row.next_step,
|
|
47
|
+
createdAt: row.created_at,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/** Idempotent-record comparison via canonical JSON (see model.ts). */
|
|
51
|
+
function eventContentEqual(a, row) {
|
|
52
|
+
return learningEventContentEqual(a, {
|
|
53
|
+
date: row.date,
|
|
54
|
+
covered: JSON.parse(row.covered_json),
|
|
55
|
+
attempts: JSON.parse(row.attempts_json),
|
|
56
|
+
interpretation: row.interpretation,
|
|
57
|
+
nextStep: row.next_step,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
const LEARNER_COLS = "id, label, profile_json, created_at, updated_at";
|
|
61
|
+
const ENROLLMENT_COLS = "id, learner_id, course_id, workstream_id, plan_ref, plan_revision, " +
|
|
62
|
+
"plan_fingerprint, status, completion_history_json, created_at, updated_at";
|
|
63
|
+
const EVENT_COLS = "id, date, covered_json, attempts_json, interpretation, next_step, created_at";
|
|
64
|
+
export class SqliteLearnerStore {
|
|
65
|
+
db;
|
|
66
|
+
/**
|
|
67
|
+
* @internal. Construct via SqliteStorage.create(...) instead — see
|
|
68
|
+
* SqliteFactStore for the rationale.
|
|
69
|
+
*/
|
|
70
|
+
constructor(db) {
|
|
71
|
+
this.db = db;
|
|
72
|
+
}
|
|
73
|
+
async initLearner(tenantId, input) {
|
|
74
|
+
this.db
|
|
75
|
+
.prepare("INSERT INTO learners (id, label, profile_json, tenant_id) VALUES (?, ?, ?, ?)")
|
|
76
|
+
.run(input.id, input.label, JSON.stringify(input.profile ?? {}), tenantId);
|
|
77
|
+
}
|
|
78
|
+
async getLearner(tenantId, id) {
|
|
79
|
+
const tc = tenantClause(tenantId);
|
|
80
|
+
const row = this.db
|
|
81
|
+
.prepare(`SELECT ${LEARNER_COLS} FROM learners WHERE id = ? AND ${tc.sql}`)
|
|
82
|
+
.get(id, tc.param);
|
|
83
|
+
return row ? learnerFromRow(row) : null;
|
|
84
|
+
}
|
|
85
|
+
async enroll(tenantId, input) {
|
|
86
|
+
const txn = this.db.transaction(() => {
|
|
87
|
+
const existing = this.getEnrollmentRow(tenantId, input.learnerId, input.courseId);
|
|
88
|
+
if (existing) {
|
|
89
|
+
if (existing.plan_fingerprint !== input.planFingerprint ||
|
|
90
|
+
existing.plan_revision !== input.planRevision) {
|
|
91
|
+
throw new Error(`enroll: plan changed for ${input.learnerId}/${input.courseId} ` +
|
|
92
|
+
"(rev differs) — reconcile explicitly, refusing silent upsert");
|
|
93
|
+
}
|
|
94
|
+
return enrollmentFromRow(existing);
|
|
95
|
+
}
|
|
96
|
+
const id = makeEnrollmentId();
|
|
97
|
+
this.db
|
|
98
|
+
.prepare(`INSERT INTO enrollments (id, learner_id, course_id, workstream_id, plan_ref,
|
|
99
|
+
plan_revision, plan_fingerprint, tenant_id)
|
|
100
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
101
|
+
.run(id, input.learnerId, input.courseId, input.workstreamId, input.planRef, input.planRevision, input.planFingerprint, tenantId);
|
|
102
|
+
return enrollmentFromRow(this.getEnrollmentRow(tenantId, input.learnerId, input.courseId));
|
|
103
|
+
});
|
|
104
|
+
return txn();
|
|
105
|
+
}
|
|
106
|
+
async getEnrollment(tenantId, learnerId, courseId) {
|
|
107
|
+
const row = this.getEnrollmentRow(tenantId, learnerId, courseId);
|
|
108
|
+
return row ? enrollmentFromRow(row) : null;
|
|
109
|
+
}
|
|
110
|
+
async listEnrollments(tenantId, learnerId) {
|
|
111
|
+
const tc = tenantClause(tenantId);
|
|
112
|
+
const rows = this.db
|
|
113
|
+
.prepare(`SELECT ${ENROLLMENT_COLS} FROM enrollments WHERE learner_id = ? AND ${tc.sql} ORDER BY course_id ASC`)
|
|
114
|
+
.all(learnerId, tc.param);
|
|
115
|
+
return rows.map(enrollmentFromRow);
|
|
116
|
+
}
|
|
117
|
+
async listEnrollmentsByWorkstreams(tenantId, workstreamIds) {
|
|
118
|
+
if (workstreamIds.length === 0)
|
|
119
|
+
return [];
|
|
120
|
+
const tc = tenantClause(tenantId);
|
|
121
|
+
const placeholders = workstreamIds.map(() => "?").join(", ");
|
|
122
|
+
const rows = this.db
|
|
123
|
+
.prepare(`SELECT ${ENROLLMENT_COLS} FROM enrollments WHERE workstream_id IN (${placeholders}) AND ${tc.sql}`)
|
|
124
|
+
.all(...workstreamIds, tc.param);
|
|
125
|
+
return rows.map(enrollmentFromRow);
|
|
126
|
+
}
|
|
127
|
+
async recordEvent(tenantId, learnerId, courseId, event) {
|
|
128
|
+
const txn = this.db.transaction(() => {
|
|
129
|
+
const enrollment = this.getEnrollmentRow(tenantId, learnerId, courseId);
|
|
130
|
+
if (!enrollment)
|
|
131
|
+
throw new Error(`recordEvent: no enrollment for ${learnerId}/${courseId}`);
|
|
132
|
+
const tc = tenantClause(tenantId);
|
|
133
|
+
const existing = this.db
|
|
134
|
+
.prepare(`SELECT ${EVENT_COLS} FROM learning_events WHERE enrollment_id = ? AND id = ? AND ${tc.sql}`)
|
|
135
|
+
.get(enrollment.id, event.id, tc.param);
|
|
136
|
+
if (!existing) {
|
|
137
|
+
this.db
|
|
138
|
+
.prepare(`INSERT INTO learning_events (id, enrollment_id, date, covered_json, attempts_json,
|
|
139
|
+
interpretation, next_step, tenant_id)
|
|
140
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
141
|
+
.run(event.id, enrollment.id, event.date, JSON.stringify(event.covered), JSON.stringify(event.attempts), event.interpretation, event.nextStep, tenantId);
|
|
142
|
+
return "inserted";
|
|
143
|
+
}
|
|
144
|
+
if (!eventContentEqual(event, existing)) {
|
|
145
|
+
throw new Error(`recordEvent: conflicting event id ${event.id} — refusing to rewrite history`);
|
|
146
|
+
}
|
|
147
|
+
return "noop";
|
|
148
|
+
});
|
|
149
|
+
return txn();
|
|
150
|
+
}
|
|
151
|
+
async listEvents(tenantId, learnerId, courseId) {
|
|
152
|
+
const enrollment = this.getEnrollmentRow(tenantId, learnerId, courseId);
|
|
153
|
+
if (!enrollment)
|
|
154
|
+
return [];
|
|
155
|
+
const tc = tenantClause(tenantId);
|
|
156
|
+
const rows = this.db
|
|
157
|
+
.prepare(`SELECT ${EVENT_COLS} FROM learning_events WHERE enrollment_id = ? AND ${tc.sql} ` +
|
|
158
|
+
"ORDER BY date ASC, id ASC")
|
|
159
|
+
.all(enrollment.id, tc.param);
|
|
160
|
+
return rows.map(eventFromRow);
|
|
161
|
+
}
|
|
162
|
+
async completeCourse(tenantId, learnerId, courseId) {
|
|
163
|
+
const enrollment = this.getEnrollmentRow(tenantId, learnerId, courseId);
|
|
164
|
+
if (!enrollment)
|
|
165
|
+
throw new Error(`completeCourse: no enrollment for ${learnerId}/${courseId}`);
|
|
166
|
+
const tc = tenantClause(tenantId);
|
|
167
|
+
this.db
|
|
168
|
+
.prepare(`UPDATE enrollments SET status = 'completed', updated_at = datetime('now') WHERE id = ? AND ${tc.sql}`)
|
|
169
|
+
.run(enrollment.id, tc.param);
|
|
170
|
+
}
|
|
171
|
+
getEnrollmentRow(tenantId, learnerId, courseId) {
|
|
172
|
+
const tc = tenantClause(tenantId);
|
|
173
|
+
return this.db
|
|
174
|
+
.prepare(`SELECT ${ENROLLMENT_COLS} FROM enrollments WHERE learner_id = ? AND course_id = ? AND ${tc.sql}`)
|
|
175
|
+
.get(learnerId, courseId, tc.param);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=sqlite-learner-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-learner-store.js","sourceRoot":"","sources":["../../../src/core/storage/sqlite-learner-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite adapters for the outcome rollup ports (`@ports/outcome.js`,
|
|
3
|
+
* `@core/outcome/rollup.js`) — #352 phase 2 Task 8. No Postgres adapters yet;
|
|
4
|
+
* `get_session` and `nlm digest` both run against the operator's SQLite
|
|
5
|
+
* deployment, so parity is deferred until a Postgres-backed caller exists.
|
|
6
|
+
*
|
|
7
|
+
* Never selects `sessions.body` — see the incident class noted on
|
|
8
|
+
* `SqliteSessionStore.getByIds` (48KB/row of session markdown the recall
|
|
9
|
+
* daemon does not need for this read shape).
|
|
10
|
+
*
|
|
11
|
+
* Two entry points:
|
|
12
|
+
* - `buildSqliteOutcomeDeps` — per-session `OutcomeDeps` for `get_session`.
|
|
13
|
+
* Fine to re-query per call; a single session's evidence is a handful of
|
|
14
|
+
* indexed lookups.
|
|
15
|
+
* - `loadOutcomeCoverageInput` — one query per evidence type across an
|
|
16
|
+
* entire id set, for the digest's Tier-B coverage block. Feeds
|
|
17
|
+
* `@core/outcome/coverage.js`'s `computeOutcomeCoverage`, not `deriveOutcome`
|
|
18
|
+
* directly.
|
|
19
|
+
*
|
|
20
|
+
* `reDerivationPairs` (#405) is read from the cache file the 24h
|
|
21
|
+
* corpus-monitor job writes (tenant-derived via `tenantStatePath` — the
|
|
22
|
+
* default team's file is `~/.nlm/re-derivation-pairs.json`, every other
|
|
23
|
+
* tenant gets its own `~/.nlm/tenants/<t>/re-derivation-pairs.json`, see
|
|
24
|
+
* `src/cli/nlm.ts`'s `persistReDerivationPairs`), not recomputed inline.
|
|
25
|
+
* Measured on the real corpus copy (~4.6k sessions/42d window),
|
|
26
|
+
* `computeReDerivationRate` (`@core/metrics/re-derivation.js`) costs ~7s: an
|
|
27
|
+
* N+1 query per session for entities/decisions, then an O(n^2) pairwise
|
|
28
|
+
* jaccard scan. That blows the ~2s digest budget and would add
|
|
29
|
+
* multi-second latency to every `get_session` call - fine for a background
|
|
30
|
+
* cron, not for a request path. The cache is fresh (~24h stale at worst)
|
|
31
|
+
* while the 24h monitor runs; that is an assumption, not a guarantee, so a
|
|
32
|
+
* cache older than 72h (monitor presumed dead) is discarded. Missing,
|
|
33
|
+
* corrupt, or stale file (first boot before the monitor's first run, a
|
|
34
|
+
* stopped monitor, etc.) falls back to `[]`: sessions that would have
|
|
35
|
+
* landed in `re-derived-later` fall back to `unobserved`, which stays
|
|
36
|
+
* honest rather than silently wrong.
|
|
37
|
+
*/
|
|
38
|
+
import type Database from "better-sqlite3";
|
|
39
|
+
import { type ReDerivationPair } from "../metrics/re-derivation.js";
|
|
40
|
+
import type { OutcomeCitation, OutcomeCitationReader, OutcomeDeps, OutcomeEdge, OutcomeEdgeReader, OutcomeSession, OutcomeSessionReader, OutcomeSignal, OutcomeSignalReader } from "../../ports/outcome.js";
|
|
41
|
+
export declare class SqliteOutcomeSessionReader implements OutcomeSessionReader {
|
|
42
|
+
private readonly db;
|
|
43
|
+
constructor(db: Database.Database);
|
|
44
|
+
getById(tenantId: string, sessionId: string): Promise<OutcomeSession | null>;
|
|
45
|
+
}
|
|
46
|
+
export declare class SqliteOutcomeSignalReader implements OutcomeSignalReader {
|
|
47
|
+
private readonly db;
|
|
48
|
+
constructor(db: Database.Database);
|
|
49
|
+
listForSession(tenantId: string, sessionId: string): Promise<ReadonlyArray<OutcomeSignal>>;
|
|
50
|
+
}
|
|
51
|
+
export declare class SqliteOutcomeEdgeReader implements OutcomeEdgeReader {
|
|
52
|
+
private readonly db;
|
|
53
|
+
constructor(db: Database.Database);
|
|
54
|
+
/**
|
|
55
|
+
* session_edges carries no tenant_id (DERIVE-VIA-FK) — the tenant filter
|
|
56
|
+
* is applied via a join back to the tenant-filtered `sessions` row for
|
|
57
|
+
* `to_session` (this session), matching the resolveSuccessors pattern in
|
|
58
|
+
* SqliteSessionStore.
|
|
59
|
+
*/
|
|
60
|
+
listForSession(tenantId: string, sessionId: string): Promise<ReadonlyArray<OutcomeEdge>>;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Citations live in the append-only JSONL log (`@core/recall/citation-log.js`),
|
|
64
|
+
* not SQLite — `cite_session` calls are telemetry, not a table. `readCitationLog`
|
|
65
|
+
* takes a required day-window; passing `Infinity` reads the whole log since
|
|
66
|
+
* rollup evidence has no expiry.
|
|
67
|
+
*/
|
|
68
|
+
export declare class SqliteOutcomeCitationReader implements OutcomeCitationReader {
|
|
69
|
+
private readonly tenantId;
|
|
70
|
+
private readonly logPath?;
|
|
71
|
+
constructor(tenantId: string, logPath?: string | undefined);
|
|
72
|
+
listForSession(sessionId: string): Promise<ReadonlyArray<OutcomeCitation>>;
|
|
73
|
+
}
|
|
74
|
+
export interface BuildSqliteOutcomeDepsOptions {
|
|
75
|
+
readonly citationLogPath?: string;
|
|
76
|
+
/** Override for tests; defaults to `~/.nlm/re-derivation-pairs.json`. */
|
|
77
|
+
readonly reDerivationPairsPath?: string;
|
|
78
|
+
readonly now?: () => Date;
|
|
79
|
+
readonly heldAfterDays?: number;
|
|
80
|
+
}
|
|
81
|
+
/** Per-session OutcomeDeps for `get_session`. Safe to build fresh per call. */
|
|
82
|
+
export declare function buildSqliteOutcomeDeps(db: Database.Database, tenantId: string, opts?: BuildSqliteOutcomeDepsOptions): Promise<OutcomeDeps>;
|
|
83
|
+
export interface OutcomeCoverageInput {
|
|
84
|
+
readonly sessions: ReadonlyArray<OutcomeSession>;
|
|
85
|
+
readonly signalsBySession: ReadonlyMap<string, ReadonlyArray<OutcomeSignal>>;
|
|
86
|
+
readonly edgesBySession: ReadonlyMap<string, ReadonlyArray<OutcomeEdge>>;
|
|
87
|
+
readonly citationsBySession: ReadonlyMap<string, ReadonlyArray<OutcomeCitation>>;
|
|
88
|
+
/** Read from the corpus-monitor's cache file - see the module doc comment. */
|
|
89
|
+
readonly reDerivationPairs: ReadonlyArray<ReDerivationPair>;
|
|
90
|
+
}
|
|
91
|
+
export interface LoadOutcomeCoverageInputOptions {
|
|
92
|
+
/** ISO timestamp - only sessions with `ended_at >= sinceIso` are included. */
|
|
93
|
+
readonly sinceIso: string;
|
|
94
|
+
readonly citationLogPath?: string;
|
|
95
|
+
/** Override for tests; defaults to `~/.nlm/re-derivation-pairs.json`. */
|
|
96
|
+
readonly reDerivationPairsPath?: string;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Batched loader for the digest's Tier-B coverage block: one query per
|
|
100
|
+
* evidence type across the whole ended-in-window id set, not one query per
|
|
101
|
+
* session. `computeOutcomeCoverage` (`@core/outcome/coverage.js`) turns this
|
|
102
|
+
* into per-session verdicts via `deriveOutcome`.
|
|
103
|
+
*/
|
|
104
|
+
export declare function loadOutcomeCoverageInput(db: Database.Database, tenantId: string, opts: LoadOutcomeCoverageInputOptions): Promise<OutcomeCoverageInput>;
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite adapters for the outcome rollup ports (`@ports/outcome.js`,
|
|
3
|
+
* `@core/outcome/rollup.js`) — #352 phase 2 Task 8. No Postgres adapters yet;
|
|
4
|
+
* `get_session` and `nlm digest` both run against the operator's SQLite
|
|
5
|
+
* deployment, so parity is deferred until a Postgres-backed caller exists.
|
|
6
|
+
*
|
|
7
|
+
* Never selects `sessions.body` — see the incident class noted on
|
|
8
|
+
* `SqliteSessionStore.getByIds` (48KB/row of session markdown the recall
|
|
9
|
+
* daemon does not need for this read shape).
|
|
10
|
+
*
|
|
11
|
+
* Two entry points:
|
|
12
|
+
* - `buildSqliteOutcomeDeps` — per-session `OutcomeDeps` for `get_session`.
|
|
13
|
+
* Fine to re-query per call; a single session's evidence is a handful of
|
|
14
|
+
* indexed lookups.
|
|
15
|
+
* - `loadOutcomeCoverageInput` — one query per evidence type across an
|
|
16
|
+
* entire id set, for the digest's Tier-B coverage block. Feeds
|
|
17
|
+
* `@core/outcome/coverage.js`'s `computeOutcomeCoverage`, not `deriveOutcome`
|
|
18
|
+
* directly.
|
|
19
|
+
*
|
|
20
|
+
* `reDerivationPairs` (#405) is read from the cache file the 24h
|
|
21
|
+
* corpus-monitor job writes (tenant-derived via `tenantStatePath` — the
|
|
22
|
+
* default team's file is `~/.nlm/re-derivation-pairs.json`, every other
|
|
23
|
+
* tenant gets its own `~/.nlm/tenants/<t>/re-derivation-pairs.json`, see
|
|
24
|
+
* `src/cli/nlm.ts`'s `persistReDerivationPairs`), not recomputed inline.
|
|
25
|
+
* Measured on the real corpus copy (~4.6k sessions/42d window),
|
|
26
|
+
* `computeReDerivationRate` (`@core/metrics/re-derivation.js`) costs ~7s: an
|
|
27
|
+
* N+1 query per session for entities/decisions, then an O(n^2) pairwise
|
|
28
|
+
* jaccard scan. That blows the ~2s digest budget and would add
|
|
29
|
+
* multi-second latency to every `get_session` call - fine for a background
|
|
30
|
+
* cron, not for a request path. The cache is fresh (~24h stale at worst)
|
|
31
|
+
* while the 24h monitor runs; that is an assumption, not a guarantee, so a
|
|
32
|
+
* cache older than 72h (monitor presumed dead) is discarded. Missing,
|
|
33
|
+
* corrupt, or stale file (first boot before the monitor's first run, a
|
|
34
|
+
* stopped monitor, etc.) falls back to `[]`: sessions that would have
|
|
35
|
+
* landed in `re-derived-later` fall back to `unobserved`, which stays
|
|
36
|
+
* honest rather than silently wrong.
|
|
37
|
+
*/
|
|
38
|
+
import { readFileSync, statSync } from "node:fs";
|
|
39
|
+
import { readCitationLog } from "../recall/citation-log.js";
|
|
40
|
+
import { parseReDerivationPairsFile } from "../metrics/re-derivation.js";
|
|
41
|
+
import { tenantStatePath } from "../tenancy/tenant-state-path.js";
|
|
42
|
+
import { tenantClause } from "../tenancy/tenant-clause.js";
|
|
43
|
+
const RELEVANT_EDGE_KINDS = "('supersedes','replaces','continues')";
|
|
44
|
+
// 3x the corpus monitor's 24h refresh interval. A healthy monitor overwrites
|
|
45
|
+
// the cache daily, so a file this old means the monitor has stopped and the
|
|
46
|
+
// pairs can no longer be trusted as fresh - discard rather than serve stale
|
|
47
|
+
// verdicts indefinitely.
|
|
48
|
+
const REDERIVATION_PAIRS_MAX_AGE_MS = 72 * 60 * 60 * 1000;
|
|
49
|
+
/**
|
|
50
|
+
* tenantId picks the tenant-derived cache file (default team → legacy
|
|
51
|
+
* `~/.nlm/re-derivation-pairs.json`; every other tenant → its own
|
|
52
|
+
* `~/.nlm/tenants/<t>/re-derivation-pairs.json`) when `pairsPath` is not
|
|
53
|
+
* given explicitly. Without this, every tenant read the exact same shared
|
|
54
|
+
* file regardless of who they were (#405 follow-up).
|
|
55
|
+
*/
|
|
56
|
+
function loadCachedReDerivationPairs(tenantId, pairsPath = tenantStatePath(tenantId, "re-derivation-pairs.json")) {
|
|
57
|
+
try {
|
|
58
|
+
if (Date.now() - statSync(pairsPath).mtimeMs > REDERIVATION_PAIRS_MAX_AGE_MS)
|
|
59
|
+
return [];
|
|
60
|
+
return parseReDerivationPairsFile(readFileSync(pairsPath, "utf8"));
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return [];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export class SqliteOutcomeSessionReader {
|
|
67
|
+
db;
|
|
68
|
+
constructor(db) {
|
|
69
|
+
this.db = db;
|
|
70
|
+
}
|
|
71
|
+
async getById(tenantId, sessionId) {
|
|
72
|
+
const tc = tenantClause(tenantId);
|
|
73
|
+
const row = this.db
|
|
74
|
+
.prepare(`SELECT id, ended_at, status FROM sessions WHERE id = ? AND ${tc.sql}`)
|
|
75
|
+
.get(sessionId, tc.param);
|
|
76
|
+
if (!row)
|
|
77
|
+
return null;
|
|
78
|
+
return { id: row.id, endedAt: row.ended_at, status: row.status };
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
export class SqliteOutcomeSignalReader {
|
|
82
|
+
db;
|
|
83
|
+
constructor(db) {
|
|
84
|
+
this.db = db;
|
|
85
|
+
}
|
|
86
|
+
async listForSession(tenantId, sessionId) {
|
|
87
|
+
const tc = tenantClause(tenantId);
|
|
88
|
+
return this.db
|
|
89
|
+
.prepare(`SELECT id, outcome FROM signals WHERE session_id = ? AND ${tc.sql}`)
|
|
90
|
+
.all(sessionId, tc.param);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
export class SqliteOutcomeEdgeReader {
|
|
94
|
+
db;
|
|
95
|
+
constructor(db) {
|
|
96
|
+
this.db = db;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* session_edges carries no tenant_id (DERIVE-VIA-FK) — the tenant filter
|
|
100
|
+
* is applied via a join back to the tenant-filtered `sessions` row for
|
|
101
|
+
* `to_session` (this session), matching the resolveSuccessors pattern in
|
|
102
|
+
* SqliteSessionStore.
|
|
103
|
+
*/
|
|
104
|
+
async listForSession(tenantId, sessionId) {
|
|
105
|
+
const tc = tenantClause(tenantId, "s.tenant_id");
|
|
106
|
+
const rows = this.db
|
|
107
|
+
.prepare(`SELECT se.from_session, se.to_session, se.kind
|
|
108
|
+
FROM session_edges se
|
|
109
|
+
JOIN sessions s ON s.id = se.to_session
|
|
110
|
+
WHERE se.to_session = ? AND se.kind IN ${RELEVANT_EDGE_KINDS} AND ${tc.sql}`)
|
|
111
|
+
.all(sessionId, tc.param);
|
|
112
|
+
return rows.map((r) => ({ fromSession: r.from_session, toSession: r.to_session, kind: r.kind }));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Citations live in the append-only JSONL log (`@core/recall/citation-log.js`),
|
|
117
|
+
* not SQLite — `cite_session` calls are telemetry, not a table. `readCitationLog`
|
|
118
|
+
* takes a required day-window; passing `Infinity` reads the whole log since
|
|
119
|
+
* rollup evidence has no expiry.
|
|
120
|
+
*/
|
|
121
|
+
export class SqliteOutcomeCitationReader {
|
|
122
|
+
tenantId;
|
|
123
|
+
logPath;
|
|
124
|
+
// tenantId is captured here rather than added to the OutcomeCitationReader
|
|
125
|
+
// port's listForSession(sessionId) signature — that port is shared by every
|
|
126
|
+
// adapter and callers (deriveOutcome) already scope by the outer tenantId
|
|
127
|
+
// argument; storing it on the adapter mirrors how logPath is already held.
|
|
128
|
+
constructor(tenantId, logPath) {
|
|
129
|
+
this.tenantId = tenantId;
|
|
130
|
+
this.logPath = logPath;
|
|
131
|
+
}
|
|
132
|
+
async listForSession(sessionId) {
|
|
133
|
+
const entries = this.logPath !== undefined
|
|
134
|
+
? await readCitationLog(this.tenantId, Number.POSITIVE_INFINITY, this.logPath)
|
|
135
|
+
: await readCitationLog(this.tenantId, Number.POSITIVE_INFINITY);
|
|
136
|
+
return entries.filter((e) => e.citedId === sessionId).map((e) => ({ conversationId: e.conversationId }));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/** Per-session OutcomeDeps for `get_session`. Safe to build fresh per call. */
|
|
140
|
+
export async function buildSqliteOutcomeDeps(db, tenantId, opts = {}) {
|
|
141
|
+
return {
|
|
142
|
+
sessions: new SqliteOutcomeSessionReader(db),
|
|
143
|
+
signals: new SqliteOutcomeSignalReader(db),
|
|
144
|
+
edges: new SqliteOutcomeEdgeReader(db),
|
|
145
|
+
citations: new SqliteOutcomeCitationReader(tenantId, opts.citationLogPath),
|
|
146
|
+
reDerivationPairs: loadCachedReDerivationPairs(tenantId, opts.reDerivationPairsPath),
|
|
147
|
+
...(opts.now ? { now: opts.now } : {}),
|
|
148
|
+
...(opts.heldAfterDays !== undefined ? { heldAfterDays: opts.heldAfterDays } : {}),
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Batched loader for the digest's Tier-B coverage block: one query per
|
|
153
|
+
* evidence type across the whole ended-in-window id set, not one query per
|
|
154
|
+
* session. `computeOutcomeCoverage` (`@core/outcome/coverage.js`) turns this
|
|
155
|
+
* into per-session verdicts via `deriveOutcome`.
|
|
156
|
+
*/
|
|
157
|
+
export async function loadOutcomeCoverageInput(db, tenantId, opts) {
|
|
158
|
+
const sessionTc = tenantClause(tenantId);
|
|
159
|
+
const sessionRows = db
|
|
160
|
+
.prepare(`SELECT id, ended_at, status FROM sessions
|
|
161
|
+
WHERE ended_at IS NOT NULL AND ended_at >= ? AND ${sessionTc.sql}
|
|
162
|
+
ORDER BY ended_at DESC`)
|
|
163
|
+
.all(opts.sinceIso, sessionTc.param);
|
|
164
|
+
const sessions = sessionRows.map((r) => ({
|
|
165
|
+
id: r.id,
|
|
166
|
+
endedAt: r.ended_at,
|
|
167
|
+
status: r.status,
|
|
168
|
+
}));
|
|
169
|
+
const signalsBySession = new Map();
|
|
170
|
+
const edgesBySession = new Map();
|
|
171
|
+
const citationsBySession = new Map();
|
|
172
|
+
if (sessions.length > 0) {
|
|
173
|
+
const ids = sessions.map((s) => s.id);
|
|
174
|
+
const placeholders = ids.map(() => "?").join(",");
|
|
175
|
+
const signalTc = tenantClause(tenantId);
|
|
176
|
+
const signalRows = db
|
|
177
|
+
.prepare(`SELECT session_id, id, outcome FROM signals WHERE session_id IN (${placeholders}) AND ${signalTc.sql}`)
|
|
178
|
+
.all(...ids, signalTc.param);
|
|
179
|
+
for (const r of signalRows) {
|
|
180
|
+
const list = signalsBySession.get(r.session_id) ?? [];
|
|
181
|
+
list.push({ id: r.id, outcome: r.outcome });
|
|
182
|
+
signalsBySession.set(r.session_id, list);
|
|
183
|
+
}
|
|
184
|
+
// session_edges carries no tenant_id (DERIVE-VIA-FK); ids are already
|
|
185
|
+
// sourced from the tenant-filtered sessions query above, so a plain IN
|
|
186
|
+
// is sufficient here — no candidate id can resolve to another tenant.
|
|
187
|
+
const edgeRows = db
|
|
188
|
+
.prepare(`SELECT from_session, to_session, kind FROM session_edges
|
|
189
|
+
WHERE to_session IN (${placeholders}) AND kind IN ${RELEVANT_EDGE_KINDS}`)
|
|
190
|
+
.all(...ids);
|
|
191
|
+
for (const r of edgeRows) {
|
|
192
|
+
const list = edgesBySession.get(r.to_session) ?? [];
|
|
193
|
+
list.push({ fromSession: r.from_session, toSession: r.to_session, kind: r.kind });
|
|
194
|
+
edgesBySession.set(r.to_session, list);
|
|
195
|
+
}
|
|
196
|
+
const idSet = new Set(ids);
|
|
197
|
+
const citationEntries = opts.citationLogPath !== undefined
|
|
198
|
+
? await readCitationLog(tenantId, Number.POSITIVE_INFINITY, opts.citationLogPath)
|
|
199
|
+
: await readCitationLog(tenantId, Number.POSITIVE_INFINITY);
|
|
200
|
+
for (const entry of citationEntries) {
|
|
201
|
+
if (!idSet.has(entry.citedId))
|
|
202
|
+
continue;
|
|
203
|
+
const list = citationsBySession.get(entry.citedId) ?? [];
|
|
204
|
+
list.push({ conversationId: entry.conversationId });
|
|
205
|
+
citationsBySession.set(entry.citedId, list);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
const reDerivationPairs = loadCachedReDerivationPairs(tenantId, opts.reDerivationPairsPath);
|
|
209
|
+
return { sessions, signalsBySession, edgesBySession, citationsBySession, reDerivationPairs };
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=sqlite-outcome-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-outcome-store.js","sourceRoot":"","sources":["../../../src/core/storage/sqlite-outcome-store.ts"],"names":[],"mappings":"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"}
|