nlm-memory 0.20.0 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -10
- package/dist/cli/digest.js +60 -1
- package/dist/cli/digest.js.map +1 -1
- package/dist/cli/init.d.ts +12 -0
- package/dist/cli/init.js +49 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/nlm.d.ts +13 -1
- package/dist/cli/nlm.js +872 -61
- package/dist/cli/nlm.js.map +1 -1
- 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 +205 -0
- package/dist/cli/scope-coverage.js.map +1 -0
- package/dist/core/actions/overlay.d.ts +20 -6
- package/dist/core/actions/overlay.js +32 -18
- 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 +36 -0
- package/dist/core/adapters/claude-code.js.map +1 -1
- package/dist/core/classifier/prompt.js +3 -3
- package/dist/core/dataset/build-dataset.js +1 -0
- package/dist/core/dataset/build-dataset.js.map +1 -1
- package/dist/core/digest/compose.d.ts +13 -3
- package/dist/core/digest/compose.js +23 -18
- 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 +79 -0
- package/dist/core/digest/hook-injection.js.map +1 -0
- package/dist/core/embedding/embed-backfill.d.ts +13 -2
- package/dist/core/embedding/embed-backfill.js +181 -43
- package/dist/core/embedding/embed-backfill.js.map +1 -1
- package/dist/core/embedding/embedding-config.d.ts +17 -0
- package/dist/core/embedding/embedding-config.js +12 -0
- package/dist/core/embedding/embedding-config.js.map +1 -0
- package/dist/core/embedding/pg-embed-backfill.d.ts +31 -0
- package/dist/core/embedding/pg-embed-backfill.js +264 -0
- package/dist/core/embedding/pg-embed-backfill.js.map +1 -0
- package/dist/core/entities/dedup-suggest.d.ts +25 -0
- package/dist/core/entities/dedup-suggest.js +107 -0
- package/dist/core/entities/dedup-suggest.js.map +1 -0
- package/dist/core/eval/classifier-fixture-eval.d.ts +29 -0
- package/dist/core/eval/classifier-fixture-eval.js +217 -0
- package/dist/core/eval/classifier-fixture-eval.js.map +1 -0
- package/dist/core/eval/extraction-scoring.d.ts +63 -0
- package/dist/core/eval/extraction-scoring.js +79 -0
- package/dist/core/eval/extraction-scoring.js.map +1 -0
- package/dist/core/eval/run-eval.d.ts +40 -0
- package/dist/core/eval/run-eval.js +34 -0
- package/dist/core/eval/run-eval.js.map +1 -0
- package/dist/core/exemplars/capture-from-session.d.ts +2 -0
- package/dist/core/exemplars/capture-from-session.js +7 -3
- package/dist/core/exemplars/capture-from-session.js.map +1 -1
- package/dist/core/exemplars/diff-parse.d.ts +23 -0
- package/dist/core/exemplars/diff-parse.js +73 -0
- package/dist/core/exemplars/diff-parse.js.map +1 -0
- package/dist/core/exemplars/embed-backfill.d.ts +36 -0
- package/dist/core/exemplars/embed-backfill.js +85 -0
- package/dist/core/exemplars/embed-backfill.js.map +1 -0
- package/dist/core/exemplars/embed-text.d.ts +15 -0
- package/dist/core/exemplars/embed-text.js +18 -0
- package/dist/core/exemplars/embed-text.js.map +1 -0
- package/dist/core/exemplars/extract-exemplar.d.ts +2 -0
- package/dist/core/exemplars/extract-exemplar.js +9 -66
- 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.js +4 -0
- package/dist/core/exemplars/recall-code.js.map +1 -1
- package/dist/core/exemplars/warm-embedder.d.ts +14 -0
- package/dist/core/exemplars/warm-embedder.js +18 -0
- package/dist/core/exemplars/warm-embedder.js.map +1 -0
- package/dist/core/health/corpus-state.d.ts +8 -0
- package/dist/core/health/corpus-state.js +11 -0
- package/dist/core/health/corpus-state.js.map +1 -0
- package/dist/core/health/embed-inflight.d.ts +9 -0
- package/dist/core/health/embed-inflight.js +30 -0
- package/dist/core/health/embed-inflight.js.map +1 -0
- package/dist/core/health/embedding-lane-state.d.ts +6 -0
- package/dist/core/health/embedding-lane-state.js +18 -0
- package/dist/core/health/embedding-lane-state.js.map +1 -0
- package/dist/core/health/warmup-state.d.ts +12 -0
- package/dist/core/health/warmup-state.js +12 -0
- package/dist/core/health/warmup-state.js.map +1 -0
- 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/gate.d.ts +13 -6
- package/dist/core/hook/gate.js +47 -6
- package/dist/core/hook/gate.js.map +1 -1
- package/dist/core/hook/hook-log.d.ts +5 -0
- package/dist/core/hook/hook-log.js.map +1 -1
- package/dist/core/hook/memo.d.ts +12 -0
- package/dist/core/hook/memo.js +41 -1
- package/dist/core/hook/memo.js.map +1 -1
- package/dist/core/hook/pointer-block.d.ts +1 -0
- package/dist/core/hook/pointer-block.js +23 -2
- package/dist/core/hook/pointer-block.js.map +1 -1
- package/dist/core/hook/query-extract.d.ts +2 -1
- package/dist/core/hook/query-extract.js +10 -1
- package/dist/core/hook/query-extract.js.map +1 -1
- package/dist/core/hook/resolve-conversation-by-query.d.ts +28 -0
- package/dist/core/hook/resolve-conversation-by-query.js +98 -0
- package/dist/core/hook/resolve-conversation-by-query.js.map +1 -0
- package/dist/core/hook/select.d.ts +8 -0
- package/dist/core/hook/select.js +9 -2
- package/dist/core/hook/select.js.map +1 -1
- package/dist/core/hook/transcript.js +16 -2
- package/dist/core/hook/transcript.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 +5 -0
- package/dist/core/ingest/ingest-session.js +23 -0
- package/dist/core/ingest/ingest-session.js.map +1 -1
- package/dist/core/ingest/reclassify-oversized.d.ts +5 -0
- package/dist/core/ingest/reclassify-oversized.js +9 -0
- package/dist/core/ingest/reclassify-oversized.js.map +1 -1
- package/dist/core/ingest/reprocess.d.ts +96 -0
- package/dist/core/ingest/reprocess.js +280 -0
- package/dist/core/ingest/reprocess.js.map +1 -0
- 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/integrity/check-invariants.d.ts +6 -1
- package/dist/core/integrity/check-invariants.js +209 -3
- package/dist/core/integrity/check-invariants.js.map +1 -1
- package/dist/core/metrics/corpus-stats.d.ts +49 -0
- package/dist/core/metrics/corpus-stats.js +111 -0
- package/dist/core/metrics/corpus-stats.js.map +1 -0
- package/dist/core/metrics/re-derivation.d.ts +48 -0
- package/dist/core/metrics/re-derivation.js +87 -0
- package/dist/core/metrics/re-derivation.js.map +1 -0
- 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/recall/citation-log.d.ts +8 -0
- package/dist/core/recall/citation-log.js +17 -0
- package/dist/core/recall/citation-log.js.map +1 -1
- package/dist/core/recall/hook-recall-log.d.ts +2 -2
- package/dist/core/recall/hook-recall-log.js +2 -2
- package/dist/core/recall/query-intent.d.ts +7 -0
- package/dist/core/recall/query-intent.js +25 -0
- package/dist/core/recall/query-intent.js.map +1 -0
- package/dist/core/recall/query-log.d.ts +4 -0
- package/dist/core/recall/query-log.js +4 -0
- package/dist/core/recall/query-log.js.map +1 -1
- package/dist/core/recall/recall-service.d.ts +37 -1
- package/dist/core/recall/recall-service.js +106 -63
- package/dist/core/recall/recall-service.js.map +1 -1
- package/dist/core/recall/related-exemplars.d.ts +1 -0
- package/dist/core/recall/related-exemplars.js +4 -1
- package/dist/core/recall/related-exemplars.js.map +1 -1
- package/dist/core/recall/related-facts.js +2 -2
- package/dist/core/recall/related-facts.js.map +1 -1
- package/dist/core/recall/reranker.d.ts +2 -1
- package/dist/core/recall/reranker.js +3 -3
- package/dist/core/recall/reranker.js.map +1 -1
- package/dist/core/recall-facts/fact-query-log.d.ts +7 -0
- package/dist/core/recall-facts/fact-query-log.js +2 -0
- package/dist/core/recall-facts/fact-query-log.js.map +1 -1
- package/dist/core/recall-facts/fact-recall-service.d.ts +9 -1
- package/dist/core/recall-facts/fact-recall-service.js +22 -8
- package/dist/core/recall-facts/fact-recall-service.js.map +1 -1
- package/dist/core/scheduler/scan-once.d.ts +6 -6
- package/dist/core/scheduler/scan-once.js +15 -49
- package/dist/core/scheduler/scan-once.js.map +1 -1
- package/dist/core/scheduler/scheduler.d.ts +10 -0
- package/dist/core/scheduler/scheduler.js +109 -13
- 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 +50 -0
- package/dist/core/signals/code-signal.js +54 -0
- package/dist/core/signals/code-signal.js.map +1 -0
- 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/storage/db-restore.js +3 -1
- package/dist/core/storage/db-restore.js.map +1 -1
- package/dist/core/storage/fact-batch.d.ts +9 -0
- package/dist/core/storage/fact-batch.js +14 -0
- package/dist/core/storage/fact-batch.js.map +1 -0
- package/dist/core/storage/pg-code-exemplar-store.d.ts +1 -0
- package/dist/core/storage/pg-code-exemplar-store.js +13 -2
- package/dist/core/storage/pg-code-exemplar-store.js.map +1 -1
- package/dist/core/storage/pg-embedding-config.d.ts +29 -0
- package/dist/core/storage/pg-embedding-config.js +53 -0
- package/dist/core/storage/pg-embedding-config.js.map +1 -0
- package/dist/core/storage/pg-entity-store.d.ts +12 -0
- package/dist/core/storage/pg-entity-store.js +79 -0
- package/dist/core/storage/pg-entity-store.js.map +1 -0
- package/dist/core/storage/pg-fact-ingest.d.ts +15 -0
- package/dist/core/storage/pg-fact-ingest.js +34 -0
- package/dist/core/storage/pg-fact-ingest.js.map +1 -0
- package/dist/core/storage/pg-fact-store.d.ts +3 -0
- package/dist/core/storage/pg-fact-store.js +26 -30
- package/dist/core/storage/pg-fact-store.js.map +1 -1
- package/dist/core/storage/pg-migrate.d.ts +18 -0
- package/dist/core/storage/pg-migrate.js +73 -0
- package/dist/core/storage/pg-migrate.js.map +1 -0
- package/dist/core/storage/pg-session-store.d.ts +11 -2
- package/dist/core/storage/pg-session-store.js +224 -96
- package/dist/core/storage/pg-session-store.js.map +1 -1
- package/dist/core/storage/pg-signal-store.js +4 -3
- package/dist/core/storage/pg-signal-store.js.map +1 -1
- package/dist/core/storage/pg-storage.d.ts +9 -7
- package/dist/core/storage/pg-storage.js +20 -50
- package/dist/core/storage/pg-storage.js.map +1 -1
- package/dist/core/storage/pg-workstream-store.d.ts +25 -0
- package/dist/core/storage/pg-workstream-store.js +97 -0
- package/dist/core/storage/pg-workstream-store.js.map +1 -0
- package/dist/core/storage/sqlite-code-exemplar-store.d.ts +1 -0
- package/dist/core/storage/sqlite-code-exemplar-store.js +15 -2
- package/dist/core/storage/sqlite-code-exemplar-store.js.map +1 -1
- package/dist/core/storage/sqlite-embedding-config.d.ts +10 -0
- package/dist/core/storage/sqlite-embedding-config.js +27 -0
- package/dist/core/storage/sqlite-embedding-config.js.map +1 -0
- package/dist/core/storage/sqlite-entity-store.d.ts +13 -0
- package/dist/core/storage/sqlite-entity-store.js +96 -0
- package/dist/core/storage/sqlite-entity-store.js.map +1 -0
- package/dist/core/storage/sqlite-fact-store.d.ts +15 -7
- package/dist/core/storage/sqlite-fact-store.js +81 -27
- package/dist/core/storage/sqlite-fact-store.js.map +1 -1
- package/dist/core/storage/sqlite-outcome-store.d.ts +89 -0
- package/dist/core/storage/sqlite-outcome-store.js +158 -0
- package/dist/core/storage/sqlite-outcome-store.js.map +1 -0
- package/dist/core/storage/sqlite-session-store.d.ts +42 -7
- package/dist/core/storage/sqlite-session-store.js +208 -95
- package/dist/core/storage/sqlite-session-store.js.map +1 -1
- package/dist/core/storage/sqlite-signal-store.js +4 -2
- package/dist/core/storage/sqlite-signal-store.js.map +1 -1
- package/dist/core/storage/sqlite-storage.d.ts +8 -8
- package/dist/core/storage/sqlite-storage.js +21 -32
- package/dist/core/storage/sqlite-storage.js.map +1 -1
- package/dist/core/storage/sqlite-workstream-store.d.ts +25 -0
- package/dist/core/storage/sqlite-workstream-store.js +99 -0
- package/dist/core/storage/sqlite-workstream-store.js.map +1 -0
- package/dist/core/storage/supersedence-log.js +2 -0
- 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/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/work-digest/active-spans.d.ts +8 -0
- package/dist/core/work-digest/active-spans.js +29 -0
- package/dist/core/work-digest/active-spans.js.map +1 -0
- package/dist/core/work-digest/attribute.d.ts +15 -0
- package/dist/core/work-digest/attribute.js +76 -0
- package/dist/core/work-digest/attribute.js.map +1 -0
- package/dist/core/work-digest/build-work-digest.d.ts +12 -0
- package/dist/core/work-digest/build-work-digest.js +69 -0
- package/dist/core/work-digest/build-work-digest.js.map +1 -0
- package/dist/core/work-digest/compose-work-digest.d.ts +3 -0
- package/dist/core/work-digest/compose-work-digest.js +52 -0
- package/dist/core/work-digest/compose-work-digest.js.map +1 -0
- package/dist/core/work-digest/merge-active.d.ts +10 -0
- package/dist/core/work-digest/merge-active.js +22 -0
- package/dist/core/work-digest/merge-active.js.map +1 -0
- package/dist/core/work-digest/read-transcript-timestamps.d.ts +7 -0
- package/dist/core/work-digest/read-transcript-timestamps.js +40 -0
- package/dist/core/work-digest/read-transcript-timestamps.js.map +1 -0
- package/dist/core/work-digest/topics.d.ts +18 -0
- package/dist/core/work-digest/topics.js +26 -0
- package/dist/core/work-digest/topics.js.map +1 -0
- package/dist/core/work-digest/types.d.ts +45 -0
- package/dist/core/work-digest/types.js +2 -0
- package/dist/core/work-digest/types.js.map +1 -0
- package/dist/core/workstream/bind.d.ts +26 -0
- package/dist/core/workstream/bind.js +42 -0
- package/dist/core/workstream/bind.js.map +1 -0
- package/dist/core/workstream/compose-recall.d.ts +2 -0
- package/dist/core/workstream/compose-recall.js +39 -0
- package/dist/core/workstream/compose-recall.js.map +1 -0
- package/dist/core/workstream/merge-suggest.d.ts +19 -0
- package/dist/core/workstream/merge-suggest.js +61 -0
- package/dist/core/workstream/merge-suggest.js.map +1 -0
- package/dist/core/workstream/model.d.ts +21 -0
- package/dist/core/workstream/model.js +9 -0
- package/dist/core/workstream/model.js.map +1 -0
- package/dist/core/workstream/name-match.d.ts +8 -0
- package/dist/core/workstream/name-match.js +18 -0
- package/dist/core/workstream/name-match.js.map +1 -0
- package/dist/core/workstream/resolve.d.ts +10 -0
- package/dist/core/workstream/resolve.js +21 -0
- package/dist/core/workstream/resolve.js.map +1 -0
- package/dist/core/workstream/rollup.d.ts +12 -0
- package/dist/core/workstream/rollup.js +17 -0
- package/dist/core/workstream/rollup.js.map +1 -0
- package/dist/core/workstream/work-topics.d.ts +10 -0
- package/dist/core/workstream/work-topics.js +55 -0
- package/dist/core/workstream/work-topics.js.map +1 -0
- package/dist/hook/hook-helpers.d.ts +4 -0
- package/dist/hook/hook-helpers.js +36 -0
- package/dist/hook/hook-helpers.js.map +1 -0
- package/dist/hook/pre-compact-hook.d.ts +23 -0
- package/dist/hook/pre-compact-hook.js +67 -0
- package/dist/hook/pre-compact-hook.js.map +1 -0
- package/dist/hook/prompt-recall-hook.d.ts +38 -0
- package/dist/hook/prompt-recall-hook.js +124 -20
- package/dist/hook/prompt-recall-hook.js.map +1 -1
- package/dist/hook/recall-gate.d.ts +29 -0
- package/dist/hook/recall-gate.js +50 -0
- package/dist/hook/recall-gate.js.map +1 -0
- package/dist/hook/recall-over-http.d.ts +3 -2
- package/dist/hook/recall-over-http.js +26 -13
- package/dist/hook/recall-over-http.js.map +1 -1
- package/dist/hook/recent-context.d.ts +25 -0
- package/dist/hook/recent-context.js +104 -0
- package/dist/hook/recent-context.js.map +1 -0
- package/dist/hook/score-floor.d.ts +27 -0
- package/dist/hook/score-floor.js +42 -0
- package/dist/hook/score-floor.js.map +1 -0
- package/dist/hook/session-end-hook.js +8 -29
- package/dist/hook/session-end-hook.js.map +1 -1
- package/dist/hook/session-start-hook.js +26 -60
- package/dist/hook/session-start-hook.js.map +1 -1
- package/dist/hook/stop-hook.js +24 -60
- package/dist/hook/stop-hook.js.map +1 -1
- package/dist/http/app.d.ts +6 -0
- package/dist/http/app.js +52 -44
- package/dist/http/app.js.map +1 -1
- package/dist/install/setup.js +2 -0
- package/dist/install/setup.js.map +1 -1
- package/dist/llm/build-classifier.d.ts +22 -0
- package/dist/llm/build-classifier.js +42 -0
- package/dist/llm/build-classifier.js.map +1 -0
- package/dist/llm/build-embedder.d.ts +11 -0
- package/dist/llm/build-embedder.js +42 -0
- package/dist/llm/build-embedder.js.map +1 -0
- package/dist/llm/bundled-embedder-client.d.ts +37 -0
- package/dist/llm/bundled-embedder-client.js +90 -0
- package/dist/llm/bundled-embedder-client.js.map +1 -0
- package/dist/llm/classifier-box.d.ts +13 -5
- package/dist/llm/classifier-box.js +28 -6
- package/dist/llm/classifier-box.js.map +1 -1
- package/dist/llm/classifier-egress.d.ts +18 -0
- package/dist/llm/classifier-egress.js +59 -0
- package/dist/llm/classifier-egress.js.map +1 -0
- package/dist/llm/client-shared.d.ts +4 -0
- package/dist/llm/client-shared.js +39 -0
- package/dist/llm/client-shared.js.map +1 -0
- package/dist/llm/deepseek-client.d.ts +20 -0
- package/dist/llm/deepseek-client.js +59 -45
- package/dist/llm/deepseek-client.js.map +1 -1
- package/dist/llm/embedder-info.d.ts +15 -0
- package/dist/llm/embedder-info.js +27 -0
- package/dist/llm/embedder-info.js.map +1 -0
- package/dist/llm/model-quirks.d.ts +4 -0
- package/dist/llm/model-quirks.js +7 -0
- package/dist/llm/model-quirks.js.map +1 -0
- package/dist/llm/naming.d.ts +5 -0
- package/dist/llm/naming.js +20 -0
- package/dist/llm/naming.js.map +1 -0
- package/dist/llm/ollama-client.d.ts +7 -8
- package/dist/llm/ollama-client.js +59 -51
- package/dist/llm/ollama-client.js.map +1 -1
- package/dist/llm/ollama-code-embedder.d.ts +8 -3
- package/dist/llm/ollama-code-embedder.js +14 -24
- package/dist/llm/ollama-code-embedder.js.map +1 -1
- package/dist/llm/openai-code-embedder-client.d.ts +25 -0
- package/dist/llm/openai-code-embedder-client.js +52 -0
- package/dist/llm/openai-code-embedder-client.js.map +1 -0
- package/dist/llm/openai-embedder-client.d.ts +41 -0
- package/dist/llm/openai-embedder-client.js +83 -0
- package/dist/llm/openai-embedder-client.js.map +1 -0
- package/dist/mcp/server.d.ts +69 -2
- package/dist/mcp/server.js +404 -19
- package/dist/mcp/server.js.map +1 -1
- package/dist/ports/code-embedder.d.ts +6 -1
- package/dist/ports/code-exemplar-store.d.ts +5 -0
- package/dist/ports/entity-store.d.ts +35 -0
- package/dist/ports/entity-store.js +7 -0
- package/dist/ports/entity-store.js.map +1 -0
- package/dist/ports/fact-store.d.ts +0 -0
- package/dist/ports/fact-store.js.map +1 -1
- package/dist/ports/llm-client.d.ts +9 -1
- 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 +12 -6
- package/dist/ports/storage.d.ts +7 -30
- package/dist/ports/storage.js +3 -7
- package/dist/ports/storage.js.map +1 -1
- package/dist/ports/transcript-adapter.d.ts +2 -0
- package/dist/ports/workstream-store.d.ts +22 -0
- package/dist/ports/workstream-store.js +2 -0
- package/dist/ports/workstream-store.js.map +1 -0
- 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 +56 -2
- package/dist/shared/types.js +4 -1
- package/dist/shared/types.js.map +1 -1
- package/dist/ui/assets/{index-CMpQkbQy.js → index-CSaBtgXD.js} +1 -1
- package/dist/ui/index.html +1 -1
- package/fixtures/classifier-gold/README.md +94 -0
- package/fixtures/classifier-gold/reference.json +318 -0
- package/fixtures/classifier-gold/transcripts/01-bug-fix-null-pointer-api.txt +75 -0
- package/fixtures/classifier-gold/transcripts/02-bug-fix-race-condition-queue.txt +77 -0
- package/fixtures/classifier-gold/transcripts/03-bug-fix-jwt-clock-skew.txt +86 -0
- package/fixtures/classifier-gold/transcripts/04-feature-webhook-retry.txt +95 -0
- package/fixtures/classifier-gold/transcripts/05-feature-csv-export.txt +86 -0
- package/fixtures/classifier-gold/transcripts/06-feature-rate-limiting.txt +61 -0
- package/fixtures/classifier-gold/transcripts/07-refactor-db-abstraction.txt +72 -0
- package/fixtures/classifier-gold/transcripts/08-refactor-config-loading.txt +89 -0
- package/fixtures/classifier-gold/transcripts/09-ops-docker-staging.txt +94 -0
- package/fixtures/classifier-gold/transcripts/10-ops-nginx-ssl.txt +121 -0
- package/fixtures/classifier-gold/transcripts/11-ops-postgres-migration.txt +74 -0
- package/fixtures/classifier-gold/transcripts/12-ops-cron-debugging.txt +73 -0
- package/fixtures/classifier-gold/transcripts/13-research-vector-db-comparison.txt +59 -0
- package/fixtures/classifier-gold/transcripts/14-research-oauth-provider.txt +74 -0
- package/fixtures/classifier-gold/transcripts/15-writing-api-docs.txt +154 -0
- package/fixtures/classifier-gold/transcripts/16-meeting-sprint-planning.txt +69 -0
- package/fixtures/classifier-gold/transcripts/17-trivial-list-files.txt +14 -0
- package/fixtures/classifier-gold/transcripts/18-trivial-version-check.txt +21 -0
- package/fixtures/classifier-gold/transcripts/19-trivial-syntax-help.txt +29 -0
- package/fixtures/classifier-gold/transcripts/20-trivial-read-package-json.txt +41 -0
- package/migrations/000_initial_schema.sql +1 -1
- package/migrations/024_backfill_exemplar_repo_basename.sql +32 -0
- package/migrations/025_workstreams.sql +30 -0
- package/migrations/026_embedding_config.sql +12 -0
- package/migrations/027_drop_legacy_session_embeddings.sql +7 -0
- package/migrations/028_classifier_provenance.sql +5 -0
- package/migrations/029_project_scope.sql +21 -0
- package/migrations/032_session_derivables.sql +11 -0
- package/migrations/pg/001_initial.sql +34 -0
- package/migrations/pg/019_split_replaces.sql +16 -7
- package/migrations/pg/025_workstreams.sql +34 -0
- package/migrations/pg/026_embedding_config.sql +12 -0
- package/migrations/pg/028_classifier_provenance.sql +5 -0
- package/migrations/pg/029_entity_variants.sql +9 -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/nlm/index.js +405 -39
- package/package.json +12 -2
- package/plugin/.codex-plugin/plugin.json +2 -2
- package/plugin/scripts/prompt-recall-hook.mjs +413 -43
- package/plugin/scripts/session-start-hook.mjs +295 -61
- package/plugin/scripts/stop-hook.mjs +89 -66
- package/plugin-hermes-agent/__init__.py +2 -1
- package/templates/agent-contract/README.md +24 -0
- package/templates/agent-contract/claude-code.md +40 -0
- package/templates/agent-contract/generic.md +38 -0
- package/dist/core/embedding/embed-normalize.d.ts +0 -28
- package/dist/core/embedding/embed-normalize.js +0 -98
- package/dist/core/embedding/embed-normalize.js.map +0 -1
- package/dist/core/storage/pg-tx-context.d.ts +0 -52
- package/dist/core/storage/pg-tx-context.js +0 -149
- package/dist/core/storage/pg-tx-context.js.map +0 -1
package/dist/core/hook/select.js
CHANGED
|
@@ -5,9 +5,16 @@
|
|
|
5
5
|
* surfaced in this conversation, then the per-fire cap bounded by the
|
|
6
6
|
* remaining per-conversation budget. Hits are assumed pre-ranked best-first.
|
|
7
7
|
*/
|
|
8
|
+
function medianScore(hits) {
|
|
9
|
+
if (hits.length === 0)
|
|
10
|
+
return 0;
|
|
11
|
+
const sorted = hits.map((h) => h.matchScore).sort((a, b) => a - b);
|
|
12
|
+
return sorted[Math.floor(sorted.length / 2)] ?? 0;
|
|
13
|
+
}
|
|
8
14
|
export function selectHits(params) {
|
|
9
|
-
const { hits, surfaced, scoreThreshold, perFireCap, perConversationCap } = params;
|
|
10
|
-
const
|
|
15
|
+
const { hits, surfaced, scoreThreshold, perFireCap, perConversationCap, relativeFloor = 0 } = params;
|
|
16
|
+
const relCut = relativeFloor > 0 ? relativeFloor * medianScore(hits) : 0;
|
|
17
|
+
const eligible = hits.filter((h) => h.matchScore >= scoreThreshold && h.matchScore >= relCut && !surfaced.has(h.id));
|
|
11
18
|
const budget = Math.max(0, perConversationCap - surfaced.size);
|
|
12
19
|
const limit = Math.min(perFireCap, budget);
|
|
13
20
|
return eligible.slice(0, limit);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.js","sourceRoot":"","sources":["../../../src/core/hook/select.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"select.js","sourceRoot":"","sources":["../../../src/core/hook/select.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA0BH,SAAS,WAAW,CAAC,IAAmC;IACtD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAChC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACnE,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAoB;IAC7C,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,cAAc,EAAE,UAAU,EAAE,kBAAkB,EAAE,aAAa,GAAG,CAAC,EAAE,GAAG,MAAM,CAAC;IACrG,MAAM,MAAM,GAAG,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACzE,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAC1B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,IAAI,cAAc,IAAI,CAAC,CAAC,UAAU,IAAI,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CACvF,CAAC;IACF,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,kBAAkB,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC/D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAC3C,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;AAClC,CAAC"}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* Fail-quiet: a malformed file yields nulls/empty rather than throwing —
|
|
18
18
|
* the Stop hook must never break on transcript I/O.
|
|
19
19
|
*/
|
|
20
|
-
import { existsSync,
|
|
20
|
+
import { closeSync, existsSync, fstatSync, openSync, readSync } from "node:fs";
|
|
21
21
|
const EMPTY_TURN = { text: "", toolUses: [] };
|
|
22
22
|
function parseTurn(parsed) {
|
|
23
23
|
if (parsed.type !== "assistant" || !parsed.message)
|
|
@@ -42,11 +42,25 @@ function parseTurn(parsed) {
|
|
|
42
42
|
return null;
|
|
43
43
|
return { text: textParts.join("\n"), toolUses };
|
|
44
44
|
}
|
|
45
|
+
const MAX_TRANSCRIPT_BYTES = 256 * 1024;
|
|
45
46
|
function readLines(transcriptPath) {
|
|
46
47
|
if (!transcriptPath || !existsSync(transcriptPath))
|
|
47
48
|
return null;
|
|
48
49
|
try {
|
|
49
|
-
|
|
50
|
+
const fd = openSync(transcriptPath, "r");
|
|
51
|
+
try {
|
|
52
|
+
const size = fstatSync(fd).size;
|
|
53
|
+
const start = size > MAX_TRANSCRIPT_BYTES ? size - MAX_TRANSCRIPT_BYTES : 0;
|
|
54
|
+
const len = size - start;
|
|
55
|
+
if (len <= 0)
|
|
56
|
+
return [];
|
|
57
|
+
const buf = Buffer.alloc(len);
|
|
58
|
+
readSync(fd, buf, 0, len, start);
|
|
59
|
+
return buf.toString("utf8").split("\n");
|
|
60
|
+
}
|
|
61
|
+
finally {
|
|
62
|
+
closeSync(fd);
|
|
63
|
+
}
|
|
50
64
|
}
|
|
51
65
|
catch {
|
|
52
66
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transcript.js","sourceRoot":"","sources":["../../../src/core/hook/transcript.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"transcript.js","sourceRoot":"","sources":["../../../src/core/hook/transcript.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* backfill-derivables — one-time retroactive stamp of agent_persona +
|
|
3
|
+
* parent_session_id (#352 phase 2) onto sessions ingested before the
|
|
4
|
+
* scheduler started stamping them at classify time (see
|
|
5
|
+
* src/core/scheduler/scheduler.ts, commit 34968a8).
|
|
6
|
+
*
|
|
7
|
+
* Mirrors the live stamp site exactly so backfilled rows match
|
|
8
|
+
* freshly-ingested ones: claude-code rows go through deriveSubagentMeta
|
|
9
|
+
* (reversing the `<parent>/agent-<id>` runtimeSessionId + `[subagent <slug>]`
|
|
10
|
+
* label encoding); every other runtime has no subagent concept, so persona
|
|
11
|
+
* is just the runtime name and parent is null.
|
|
12
|
+
*
|
|
13
|
+
* Idempotent: selection is WHERE agent_persona IS NULL, so a re-run only
|
|
14
|
+
* touches rows a prior run (or live ingest) hasn't stamped yet.
|
|
15
|
+
*
|
|
16
|
+
* Known data quirk (Task 2 review): some subagent transcripts encode a
|
|
17
|
+
* literal `unknown` parent (`unknown/agent-<id>`), which derives
|
|
18
|
+
* parentSessionId = "unknown" — a non-joining placeholder, not a real
|
|
19
|
+
* session id. The backfill still writes it, for consistency with live
|
|
20
|
+
* stamping, but counts it separately (`unknownParent`) so operators can see
|
|
21
|
+
* how much of the corpus has an unresolvable parent link.
|
|
22
|
+
*
|
|
23
|
+
* Persona is frequently unrecoverable for pre-existing subagent rows: the
|
|
24
|
+
* live stamp site derives persona from the transient pre-classification
|
|
25
|
+
* chunk.label (which carries the `[subagent <slug>]` prefix), but the
|
|
26
|
+
* `label` column this backfill reads is the classifier's generated title —
|
|
27
|
+
* that prefix is already gone by the time a row lands in `sessions`. In
|
|
28
|
+
* practice this means most historical subagent rows get parent_session_id
|
|
29
|
+
* populated but agent_persona stays NULL. Only genuinely new ingests (which
|
|
30
|
+
* derive from the live chunk before classification overwrites it) get both.
|
|
31
|
+
* Such rows stay selectable (agent_persona IS NULL) forever, so the run
|
|
32
|
+
* compares derived values against stored ones and counts a row `updated`
|
|
33
|
+
* only when the write would change something; a re-run over a fully
|
|
34
|
+
* backfilled corpus reports updated=0 with the unrecoverable rows under
|
|
35
|
+
* `skippedNoop`.
|
|
36
|
+
*
|
|
37
|
+
* Task 5 addition: `--with-transcript-scan` optionally also re-scans each
|
|
38
|
+
* candidate's transcript file for primary_model/total_tokens/skill via
|
|
39
|
+
* scanTranscriptDerivables. Off by default — scanning streams every
|
|
40
|
+
* candidate's transcript off disk and is far slower than the persona/parent
|
|
41
|
+
* derivation above, which only touches already-loaded columns. When the
|
|
42
|
+
* flag is set, candidacy widens beyond WHERE agent_persona IS NULL with an
|
|
43
|
+
* OR arm keyed on the scan's own columns (claude-code-jsonl rows with a
|
|
44
|
+
* transcript_path and all three scan columns still NULL) — otherwise a row
|
|
45
|
+
* whose persona was stamped by an earlier flagless run would never be
|
|
46
|
+
* scannable, leaving the flag shipped but effectively unwired for exactly
|
|
47
|
+
* the rows Task 3 already processed. Rows selected only via that arm get a
|
|
48
|
+
* scan-only write (persona/parent untouched); either way the scan columns
|
|
49
|
+
* COALESCE-preserve, and a re-run reports updated=0: a stamped scan column
|
|
50
|
+
* excludes the row from the OR arm on the next pass, and rows that stay
|
|
51
|
+
* selectable via the persona arm (persona-unrecoverable subagent rows) skip
|
|
52
|
+
* the re-scan once any scan column is stamped and count as no-op when the
|
|
53
|
+
* scan cannot change the row (all-null result, or derivables already
|
|
54
|
+
* stored).
|
|
55
|
+
*/
|
|
56
|
+
import type { Database } from "better-sqlite3";
|
|
57
|
+
export interface BackfillOptions {
|
|
58
|
+
readonly dryRun?: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Also scan each candidate's transcript file for
|
|
61
|
+
* primary_model/total_tokens/skill (#352 phase 2, Task 5). Off by
|
|
62
|
+
* default: slower than the persona/parent derivation (streams every
|
|
63
|
+
* candidate's transcript off disk).
|
|
64
|
+
*/
|
|
65
|
+
readonly withTranscriptScan?: boolean;
|
|
66
|
+
}
|
|
67
|
+
export interface BackfillReport {
|
|
68
|
+
/** All rows in the sessions table, stamped or not. */
|
|
69
|
+
readonly total: number;
|
|
70
|
+
/** Rows whose write would change something (or did, when not --dry-run). */
|
|
71
|
+
readonly updated: number;
|
|
72
|
+
/**
|
|
73
|
+
* Rows not selected at all: agent_persona already stamped and (when
|
|
74
|
+
* withTranscriptScan) not eligible for the scan arm either.
|
|
75
|
+
*/
|
|
76
|
+
readonly skippedAlreadyStamped: number;
|
|
77
|
+
/**
|
|
78
|
+
* Selected rows whose derived values match what's already stored — persona
|
|
79
|
+
* unrecoverable (NULL derives NULL), parent either already stamped by a
|
|
80
|
+
* prior run or also underivable, and (when withTranscriptScan) the
|
|
81
|
+
* transcript scan derived nothing either. Attempted, nothing to write.
|
|
82
|
+
*/
|
|
83
|
+
readonly skippedNoop: number;
|
|
84
|
+
/** Of the selected rows, how many derived a real parent link (subagent-shaped runtimeSessionId). */
|
|
85
|
+
readonly subagentCandidates: number;
|
|
86
|
+
/** Of the selected rows, how many derived a literal "unknown" parent placeholder. */
|
|
87
|
+
readonly unknownParent: number;
|
|
88
|
+
/** Rows whose transcript was scanned and derived at least one non-null
|
|
89
|
+
* field. Always 0 when withTranscriptScan is not set. */
|
|
90
|
+
readonly transcriptScanned: number;
|
|
91
|
+
}
|
|
92
|
+
export declare function backfillDerivables(db: Database, opts?: BackfillOptions): Promise<BackfillReport>;
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* backfill-derivables — one-time retroactive stamp of agent_persona +
|
|
3
|
+
* parent_session_id (#352 phase 2) onto sessions ingested before the
|
|
4
|
+
* scheduler started stamping them at classify time (see
|
|
5
|
+
* src/core/scheduler/scheduler.ts, commit 34968a8).
|
|
6
|
+
*
|
|
7
|
+
* Mirrors the live stamp site exactly so backfilled rows match
|
|
8
|
+
* freshly-ingested ones: claude-code rows go through deriveSubagentMeta
|
|
9
|
+
* (reversing the `<parent>/agent-<id>` runtimeSessionId + `[subagent <slug>]`
|
|
10
|
+
* label encoding); every other runtime has no subagent concept, so persona
|
|
11
|
+
* is just the runtime name and parent is null.
|
|
12
|
+
*
|
|
13
|
+
* Idempotent: selection is WHERE agent_persona IS NULL, so a re-run only
|
|
14
|
+
* touches rows a prior run (or live ingest) hasn't stamped yet.
|
|
15
|
+
*
|
|
16
|
+
* Known data quirk (Task 2 review): some subagent transcripts encode a
|
|
17
|
+
* literal `unknown` parent (`unknown/agent-<id>`), which derives
|
|
18
|
+
* parentSessionId = "unknown" — a non-joining placeholder, not a real
|
|
19
|
+
* session id. The backfill still writes it, for consistency with live
|
|
20
|
+
* stamping, but counts it separately (`unknownParent`) so operators can see
|
|
21
|
+
* how much of the corpus has an unresolvable parent link.
|
|
22
|
+
*
|
|
23
|
+
* Persona is frequently unrecoverable for pre-existing subagent rows: the
|
|
24
|
+
* live stamp site derives persona from the transient pre-classification
|
|
25
|
+
* chunk.label (which carries the `[subagent <slug>]` prefix), but the
|
|
26
|
+
* `label` column this backfill reads is the classifier's generated title —
|
|
27
|
+
* that prefix is already gone by the time a row lands in `sessions`. In
|
|
28
|
+
* practice this means most historical subagent rows get parent_session_id
|
|
29
|
+
* populated but agent_persona stays NULL. Only genuinely new ingests (which
|
|
30
|
+
* derive from the live chunk before classification overwrites it) get both.
|
|
31
|
+
* Such rows stay selectable (agent_persona IS NULL) forever, so the run
|
|
32
|
+
* compares derived values against stored ones and counts a row `updated`
|
|
33
|
+
* only when the write would change something; a re-run over a fully
|
|
34
|
+
* backfilled corpus reports updated=0 with the unrecoverable rows under
|
|
35
|
+
* `skippedNoop`.
|
|
36
|
+
*
|
|
37
|
+
* Task 5 addition: `--with-transcript-scan` optionally also re-scans each
|
|
38
|
+
* candidate's transcript file for primary_model/total_tokens/skill via
|
|
39
|
+
* scanTranscriptDerivables. Off by default — scanning streams every
|
|
40
|
+
* candidate's transcript off disk and is far slower than the persona/parent
|
|
41
|
+
* derivation above, which only touches already-loaded columns. When the
|
|
42
|
+
* flag is set, candidacy widens beyond WHERE agent_persona IS NULL with an
|
|
43
|
+
* OR arm keyed on the scan's own columns (claude-code-jsonl rows with a
|
|
44
|
+
* transcript_path and all three scan columns still NULL) — otherwise a row
|
|
45
|
+
* whose persona was stamped by an earlier flagless run would never be
|
|
46
|
+
* scannable, leaving the flag shipped but effectively unwired for exactly
|
|
47
|
+
* the rows Task 3 already processed. Rows selected only via that arm get a
|
|
48
|
+
* scan-only write (persona/parent untouched); either way the scan columns
|
|
49
|
+
* COALESCE-preserve, and a re-run reports updated=0: a stamped scan column
|
|
50
|
+
* excludes the row from the OR arm on the next pass, and rows that stay
|
|
51
|
+
* selectable via the persona arm (persona-unrecoverable subagent rows) skip
|
|
52
|
+
* the re-scan once any scan column is stamped and count as no-op when the
|
|
53
|
+
* scan cannot change the row (all-null result, or derivables already
|
|
54
|
+
* stored).
|
|
55
|
+
*/
|
|
56
|
+
import { deriveSubagentMeta } from "../adapters/claude-code.js";
|
|
57
|
+
import { scanTranscriptDerivables } from "./transcript-derivables.js";
|
|
58
|
+
const BATCH_SIZE = 500;
|
|
59
|
+
const NULL_TRANSCRIPT_DERIVABLES = {
|
|
60
|
+
primaryModel: null,
|
|
61
|
+
totalTokens: null,
|
|
62
|
+
skill: null,
|
|
63
|
+
};
|
|
64
|
+
// Widened OR arm for --with-transcript-scan: rows already persona-stamped
|
|
65
|
+
// (e.g. by an earlier flagless Task 3 run) but never transcript-scanned.
|
|
66
|
+
// Scoped to claude-code-jsonl since scanTranscriptDerivables derives nothing
|
|
67
|
+
// for any other kind; requires ALL three scan columns NULL so any stamped
|
|
68
|
+
// scan column excludes the row on the next pass (re-run idempotency).
|
|
69
|
+
const SCAN_CANDIDATE_ARM = " OR (transcript_path IS NOT NULL AND transcript_kind = 'claude-code-jsonl'" +
|
|
70
|
+
" AND primary_model IS NULL AND total_tokens IS NULL AND skill IS NULL)";
|
|
71
|
+
function selectCandidates(db, withTranscriptScan) {
|
|
72
|
+
return db
|
|
73
|
+
.prepare("SELECT id, runtime, runtime_session_id, label, agent_persona, parent_session_id, transcript_path, transcript_kind, primary_model, total_tokens, skill" +
|
|
74
|
+
" FROM sessions WHERE agent_persona IS NULL" +
|
|
75
|
+
(withTranscriptScan ? SCAN_CANDIDATE_ARM : ""))
|
|
76
|
+
.all();
|
|
77
|
+
}
|
|
78
|
+
// The sessions.runtime column stores the adapter's versioned runtime string
|
|
79
|
+
// (e.g. "claude-code/1.0", "hermes/1.0" — see each adapter's runtimeVersion
|
|
80
|
+
// field), but the live stamp site in scheduler.ts branches on the bare
|
|
81
|
+
// adapter name ("claude-code", "hermes", ...). Strip the version suffix so
|
|
82
|
+
// the backfill branches identically to a fresh ingest.
|
|
83
|
+
function bareRuntimeName(runtime) {
|
|
84
|
+
const slash = runtime.indexOf("/");
|
|
85
|
+
return slash === -1 ? runtime : runtime.slice(0, slash);
|
|
86
|
+
}
|
|
87
|
+
function deriveMeta(row) {
|
|
88
|
+
const runtimeName = bareRuntimeName(row.runtime);
|
|
89
|
+
if (runtimeName === "claude-code") {
|
|
90
|
+
return deriveSubagentMeta(row.runtime_session_id ?? "", row.label);
|
|
91
|
+
}
|
|
92
|
+
return { persona: runtimeName, parentSessionId: null };
|
|
93
|
+
}
|
|
94
|
+
export async function backfillDerivables(db, opts = {}) {
|
|
95
|
+
const total = db.prepare("SELECT COUNT(*) AS n FROM sessions").get().n;
|
|
96
|
+
const candidates = selectCandidates(db, Boolean(opts.withTranscriptScan));
|
|
97
|
+
const skippedAlreadyStamped = total - candidates.length;
|
|
98
|
+
let subagentCandidates = 0;
|
|
99
|
+
let unknownParent = 0;
|
|
100
|
+
let skippedNoop = 0;
|
|
101
|
+
let transcriptScanned = 0;
|
|
102
|
+
const toWrite = [];
|
|
103
|
+
for (const row of candidates) {
|
|
104
|
+
const meta = row.agent_persona === null ? deriveMeta(row) : null;
|
|
105
|
+
if (meta) {
|
|
106
|
+
if (meta.parentSessionId !== null)
|
|
107
|
+
subagentCandidates++;
|
|
108
|
+
if (meta.parentSessionId === "unknown")
|
|
109
|
+
unknownParent++;
|
|
110
|
+
}
|
|
111
|
+
// Any non-null stored scan column means a completed prior scan already
|
|
112
|
+
// stamped every field this transcript can derive (all three co-derive
|
|
113
|
+
// from the same pass, at ingest and here) - re-scanning would only
|
|
114
|
+
// re-derive values COALESCE discards. Skipping is what keeps
|
|
115
|
+
// persona-unrecoverable rows (agent_persona NULL forever, re-selected
|
|
116
|
+
// every run via the persona arm) from re-streaming their transcript and
|
|
117
|
+
// churning as "updated" on every pass.
|
|
118
|
+
const scanAlreadyRan = row.primary_model !== null || row.total_tokens !== null || row.skill !== null;
|
|
119
|
+
let transcript = NULL_TRANSCRIPT_DERIVABLES;
|
|
120
|
+
if (opts.withTranscriptScan && row.transcript_path && !scanAlreadyRan) {
|
|
121
|
+
transcript = await scanTranscriptDerivables(row.transcript_path, row.transcript_kind ?? "");
|
|
122
|
+
if (transcript.primaryModel !== null || transcript.totalTokens !== null || transcript.skill !== null) {
|
|
123
|
+
transcriptScanned++;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// Persona-null rows: the meta write is a no-op exactly when the derived
|
|
127
|
+
// persona is also NULL and the derived parent matches what a prior run
|
|
128
|
+
// already stamped (or is equally NULL). Scan-only rows have nothing to
|
|
129
|
+
// write for meta by definition.
|
|
130
|
+
const metaIsNoop = meta === null || (meta.persona === null && meta.parentSessionId === row.parent_session_id);
|
|
131
|
+
// The scan write is COALESCE-guarded, so it changes the row only where a
|
|
132
|
+
// stored column is NULL and the scan derived a value for it. An all-null
|
|
133
|
+
// scan (missing/unreadable transcript) or a scan whose derivables are
|
|
134
|
+
// already stored is a no-op - counting those as "updated" was the run-N
|
|
135
|
+
// churn bug (updated=N repeating forever with byte-identical results).
|
|
136
|
+
const transcriptWrites = (row.primary_model === null && transcript.primaryModel !== null) ||
|
|
137
|
+
(row.total_tokens === null && transcript.totalTokens !== null) ||
|
|
138
|
+
(row.skill === null && transcript.skill !== null);
|
|
139
|
+
if (metaIsNoop && !transcriptWrites) {
|
|
140
|
+
skippedNoop++;
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
toWrite.push({ id: row.id, meta, transcript });
|
|
144
|
+
}
|
|
145
|
+
if (opts.dryRun) {
|
|
146
|
+
return { total, updated: toWrite.length, skippedAlreadyStamped, skippedNoop, subagentCandidates, unknownParent, transcriptScanned };
|
|
147
|
+
}
|
|
148
|
+
const metaAndScanStmt = db.prepare(`UPDATE sessions SET
|
|
149
|
+
agent_persona = ?, parent_session_id = ?,
|
|
150
|
+
primary_model = COALESCE(primary_model, ?),
|
|
151
|
+
total_tokens = COALESCE(total_tokens, ?),
|
|
152
|
+
skill = COALESCE(skill, ?)
|
|
153
|
+
WHERE id = ? AND agent_persona IS NULL`);
|
|
154
|
+
const scanOnlyStmt = db.prepare(`UPDATE sessions SET
|
|
155
|
+
primary_model = COALESCE(primary_model, ?),
|
|
156
|
+
total_tokens = COALESCE(total_tokens, ?),
|
|
157
|
+
skill = COALESCE(skill, ?)
|
|
158
|
+
WHERE id = ?`);
|
|
159
|
+
for (let i = 0; i < toWrite.length; i += BATCH_SIZE) {
|
|
160
|
+
const batch = toWrite.slice(i, i + BATCH_SIZE);
|
|
161
|
+
const runBatch = db.transaction((rows) => {
|
|
162
|
+
for (const row of rows) {
|
|
163
|
+
if (row.meta) {
|
|
164
|
+
metaAndScanStmt.run(row.meta.persona, row.meta.parentSessionId, row.transcript.primaryModel, row.transcript.totalTokens, row.transcript.skill, row.id);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
scanOnlyStmt.run(row.transcript.primaryModel, row.transcript.totalTokens, row.transcript.skill, row.id);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
runBatch(batch);
|
|
172
|
+
}
|
|
173
|
+
return { total, updated: toWrite.length, skippedAlreadyStamped, skippedNoop, subagentCandidates, unknownParent, transcriptScanned };
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=backfill-derivables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backfill-derivables.js","sourceRoot":"","sources":["../../../src/core/ingest/backfill-derivables.ts"],"names":[],"mappings":"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"}
|
|
@@ -28,6 +28,11 @@ export interface IngestDeps {
|
|
|
28
28
|
readonly embedder: LLMClient;
|
|
29
29
|
readonly store: SqliteSessionStore | PgSessionStore;
|
|
30
30
|
readonly factStore?: SqliteFactStore | PgFactStore;
|
|
31
|
+
/** Provider and model name of the active classifier, for provenance stamping. */
|
|
32
|
+
readonly classifierDescriptor?: {
|
|
33
|
+
readonly provider: string;
|
|
34
|
+
readonly model: string;
|
|
35
|
+
};
|
|
31
36
|
/** Optional logger — defaults to console.error. */
|
|
32
37
|
readonly log?: (msg: string) => void;
|
|
33
38
|
}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { createHash } from "node:crypto";
|
|
10
10
|
import { extractFacts } from "../facts/extract-facts.js";
|
|
11
|
+
import { scanTranscriptDerivables } from "../ingest/transcript-derivables.js";
|
|
11
12
|
import { PgSessionStore } from "../storage/pg-session-store.js";
|
|
12
13
|
const BODY_CAP = 200_000;
|
|
13
14
|
const CONFIDENCE_FLOOR = 0.3;
|
|
@@ -44,6 +45,14 @@ export async function ingestSession(input, deps) {
|
|
|
44
45
|
confidence: classification.confidence,
|
|
45
46
|
};
|
|
46
47
|
}
|
|
48
|
+
// Task #352 phase 2 (Task 5): scan the transcript file (if any) for
|
|
49
|
+
// primary_model/total_tokens/skill. Webhook pushes carry transcriptKind
|
|
50
|
+
// "webhook", not "claude-code-jsonl", so this always resolves all-null
|
|
51
|
+
// today -- wired for parity with the scheduler stamp site and any future
|
|
52
|
+
// webhook kind that does carry a scannable transcript.
|
|
53
|
+
const transcriptDerivables = input.transcriptPath
|
|
54
|
+
? await scanTranscriptDerivables(input.transcriptPath, "webhook")
|
|
55
|
+
: { primaryModel: null, totalTokens: null, skill: null };
|
|
47
56
|
const record = {
|
|
48
57
|
id,
|
|
49
58
|
runtime: input.runtime,
|
|
@@ -62,6 +71,20 @@ export async function ingestSession(input, deps) {
|
|
|
62
71
|
entities: classification.entities,
|
|
63
72
|
decisions: classification.decisions,
|
|
64
73
|
openQuestions: classification.open,
|
|
74
|
+
// Push ingest carries no project directory; the scope backfill command
|
|
75
|
+
// derives it later from the transcript when evidence exists.
|
|
76
|
+
scope: null,
|
|
77
|
+
// Webhook pushes have no adapter chunk to derive subagent lineage from;
|
|
78
|
+
// stamp the runtime name as persona, matching every non-claude-code
|
|
79
|
+
// adapter at the scheduler stamp site (#352 phase 2).
|
|
80
|
+
agentPersona: input.runtime,
|
|
81
|
+
parentSessionId: null,
|
|
82
|
+
primaryModel: transcriptDerivables.primaryModel,
|
|
83
|
+
totalTokens: transcriptDerivables.totalTokens,
|
|
84
|
+
skill: transcriptDerivables.skill,
|
|
85
|
+
...(deps.classifierDescriptor !== undefined
|
|
86
|
+
? { classifier: { ...deps.classifierDescriptor, confidence: classification.confidence } }
|
|
87
|
+
: {}),
|
|
65
88
|
};
|
|
66
89
|
const facts = deps.factStore
|
|
67
90
|
? extractFacts(classification, id, startedAt)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ingest-session.js","sourceRoot":"","sources":["../../../src/core/ingest/ingest-session.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"ingest-session.js","sourceRoot":"","sources":["../../../src/core/ingest/ingest-session.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,6 +16,11 @@ export interface ReclassifyDeps {
|
|
|
16
16
|
readonly embedder: LLMClient;
|
|
17
17
|
readonly classifier: LLMClient;
|
|
18
18
|
readonly adapters: ReadonlyArray<TranscriptAdapter>;
|
|
19
|
+
/** Provider and model name of the active classifier, for provenance stamping. */
|
|
20
|
+
readonly classifierDescriptor?: {
|
|
21
|
+
readonly provider: string;
|
|
22
|
+
readonly model: string;
|
|
23
|
+
};
|
|
19
24
|
readonly log?: (msg: string) => void;
|
|
20
25
|
}
|
|
21
26
|
export interface ReclassifyOptions {
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { classifyAdaptive } from "../classifier/hierarchical-classify.js";
|
|
2
2
|
import { extractFacts } from "../facts/extract-facts.js";
|
|
3
|
+
import { deriveScope } from "../scope/derive-scope.js";
|
|
4
|
+
import { loadAliasMap } from "../scope/alias-map.js";
|
|
5
|
+
import { scopeStampEnabled } from "../scope/stamp-flag.js";
|
|
3
6
|
const BODY_CAP = 200_000;
|
|
4
7
|
const CONFIDENCE_FLOOR = 0.3;
|
|
5
8
|
export function selectOversizedFailures(db, limit) {
|
|
@@ -78,6 +81,12 @@ export async function reclassifyOversized(deps, opts = {}) {
|
|
|
78
81
|
entities: classification.entities,
|
|
79
82
|
decisions: classification.decisions,
|
|
80
83
|
openQuestions: classification.open,
|
|
84
|
+
scope: scopeStampEnabled() && chunk.projectDir
|
|
85
|
+
? deriveScope(chunk.projectDir, loadAliasMap())
|
|
86
|
+
: null,
|
|
87
|
+
...(deps.classifierDescriptor !== undefined
|
|
88
|
+
? { classifier: { ...deps.classifierDescriptor, confidence: classification.confidence } }
|
|
89
|
+
: {}),
|
|
81
90
|
};
|
|
82
91
|
const extracted = extractFacts(classification, chunk.id, chunk.startedAt);
|
|
83
92
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reclassify-oversized.js","sourceRoot":"","sources":["../../../src/core/ingest/reclassify-oversized.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"reclassify-oversized.js","sourceRoot":"","sources":["../../../src/core/ingest/reclassify-oversized.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* reprocess: retroactive re-classification of prior sessions under a
|
|
3
|
+
* stronger configured lane.
|
|
4
|
+
*
|
|
5
|
+
* Selection: sessions with a non-empty body whose classifier_model is NULL,
|
|
6
|
+
* differs from the current lane model, or (when --min-confidence is given)
|
|
7
|
+
* whose stored confidence falls below the threshold even for the same model.
|
|
8
|
+
*
|
|
9
|
+
* Per session: classifyAdaptive on the stored body, then a full insertSession
|
|
10
|
+
* upsert (refreshes chunks + facts). A below-floor classification updates the
|
|
11
|
+
* session row (label, summary, markers, provenance) but preserves prior facts
|
|
12
|
+
* and their embeddings unchanged. It is counted in belowFloorOverwrites.
|
|
13
|
+
* Workstream binding (workstream_id) is NOT touched by the upsert.
|
|
14
|
+
*
|
|
15
|
+
* Resumable via a JSON state file (default ~/.nlm/reprocess.state). A lane
|
|
16
|
+
* change (different provider or model) invalidates the done-set.
|
|
17
|
+
*
|
|
18
|
+
* SQLite only. Pg variant deferred; file task against nlm#TODO in report.
|
|
19
|
+
*/
|
|
20
|
+
import type { Database } from "better-sqlite3";
|
|
21
|
+
import type { EmbeddingConfigStore } from "../embedding/embedding-config.js";
|
|
22
|
+
import type { SqliteFactStore } from "../storage/sqlite-fact-store.js";
|
|
23
|
+
import type { SqliteSessionStore } from "../storage/sqlite-session-store.js";
|
|
24
|
+
import type { LLMClient } from "../../ports/llm-client.js";
|
|
25
|
+
export interface ReprocessDeps {
|
|
26
|
+
readonly db: Database;
|
|
27
|
+
readonly store: SqliteSessionStore;
|
|
28
|
+
readonly factStore: SqliteFactStore;
|
|
29
|
+
readonly embedder: LLMClient;
|
|
30
|
+
readonly classifier: LLMClient;
|
|
31
|
+
readonly classifierDescriptor: {
|
|
32
|
+
readonly provider: string;
|
|
33
|
+
readonly model: string;
|
|
34
|
+
};
|
|
35
|
+
readonly embeddingConfig?: EmbeddingConfigStore;
|
|
36
|
+
readonly embedderDescriptor?: {
|
|
37
|
+
readonly provider: string;
|
|
38
|
+
readonly model: string;
|
|
39
|
+
};
|
|
40
|
+
readonly log?: (msg: string) => void;
|
|
41
|
+
}
|
|
42
|
+
export interface ReprocessOptions {
|
|
43
|
+
readonly limit?: number;
|
|
44
|
+
readonly dryRun?: boolean;
|
|
45
|
+
readonly minConfidence?: number;
|
|
46
|
+
readonly onlyNull?: boolean;
|
|
47
|
+
readonly excludeModels?: string[];
|
|
48
|
+
readonly statePath?: string;
|
|
49
|
+
readonly classifyTimeoutMs?: number;
|
|
50
|
+
readonly verbose?: boolean;
|
|
51
|
+
readonly forceEmbed?: boolean;
|
|
52
|
+
readonly onProgress?: (i: number, n: number, sid: string, status: string) => void;
|
|
53
|
+
}
|
|
54
|
+
export interface CohortGroup {
|
|
55
|
+
readonly classifierProvider: string | null;
|
|
56
|
+
readonly classifierModel: string | null;
|
|
57
|
+
readonly confidenceBand: string;
|
|
58
|
+
readonly count: number;
|
|
59
|
+
}
|
|
60
|
+
export interface ReprocessReport {
|
|
61
|
+
readonly totalEligible: number;
|
|
62
|
+
readonly processed: number;
|
|
63
|
+
readonly succeeded: number;
|
|
64
|
+
readonly failed: number;
|
|
65
|
+
readonly skippedAlreadyDone: number;
|
|
66
|
+
readonly limitSkipped: number;
|
|
67
|
+
readonly belowFloorOverwrites: number;
|
|
68
|
+
readonly meanConfidenceOld: number | null;
|
|
69
|
+
readonly meanConfidenceNew: number | null;
|
|
70
|
+
readonly cohort?: ReadonlyArray<CohortGroup>;
|
|
71
|
+
readonly stateNote?: string;
|
|
72
|
+
}
|
|
73
|
+
interface ReprocessSessionRow {
|
|
74
|
+
readonly id: string;
|
|
75
|
+
readonly runtime: string;
|
|
76
|
+
readonly runtime_session_id: string | null;
|
|
77
|
+
readonly started_at: string;
|
|
78
|
+
readonly ended_at: string | null;
|
|
79
|
+
readonly duration_min: number | null;
|
|
80
|
+
readonly label: string;
|
|
81
|
+
readonly summary: string;
|
|
82
|
+
readonly status: string;
|
|
83
|
+
readonly transcript_kind: string | null;
|
|
84
|
+
readonly transcript_path: string | null;
|
|
85
|
+
readonly transcript_offset: number | null;
|
|
86
|
+
readonly transcript_length: number | null;
|
|
87
|
+
readonly classifier_provider: string | null;
|
|
88
|
+
readonly classifier_model: string | null;
|
|
89
|
+
readonly classifier_confidence: number | null;
|
|
90
|
+
}
|
|
91
|
+
export declare function selectReprocessCandidates(db: Database, model: string, minConfidence?: number, opts?: {
|
|
92
|
+
onlyNull?: boolean;
|
|
93
|
+
excludeModels?: string[];
|
|
94
|
+
}): ReprocessSessionRow[];
|
|
95
|
+
export declare function reprocess(deps: ReprocessDeps, opts?: ReprocessOptions): Promise<ReprocessReport>;
|
|
96
|
+
export {};
|