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.
Files changed (471) hide show
  1. package/README.md +19 -10
  2. package/dist/cli/digest.js +60 -1
  3. package/dist/cli/digest.js.map +1 -1
  4. package/dist/cli/init.d.ts +12 -0
  5. package/dist/cli/init.js +49 -0
  6. package/dist/cli/init.js.map +1 -0
  7. package/dist/cli/nlm.d.ts +13 -1
  8. package/dist/cli/nlm.js +872 -61
  9. package/dist/cli/nlm.js.map +1 -1
  10. package/dist/cli/scope-backfill.d.ts +34 -0
  11. package/dist/cli/scope-backfill.js +237 -0
  12. package/dist/cli/scope-backfill.js.map +1 -0
  13. package/dist/cli/scope-coverage.d.ts +44 -0
  14. package/dist/cli/scope-coverage.js +205 -0
  15. package/dist/cli/scope-coverage.js.map +1 -0
  16. package/dist/core/actions/overlay.d.ts +20 -6
  17. package/dist/core/actions/overlay.js +32 -18
  18. package/dist/core/actions/overlay.js.map +1 -1
  19. package/dist/core/adapters/claude-code.d.ts +14 -0
  20. package/dist/core/adapters/claude-code.js +36 -0
  21. package/dist/core/adapters/claude-code.js.map +1 -1
  22. package/dist/core/classifier/prompt.js +3 -3
  23. package/dist/core/dataset/build-dataset.js +1 -0
  24. package/dist/core/dataset/build-dataset.js.map +1 -1
  25. package/dist/core/digest/compose.d.ts +13 -3
  26. package/dist/core/digest/compose.js +23 -18
  27. package/dist/core/digest/compose.js.map +1 -1
  28. package/dist/core/digest/hook-injection.d.ts +43 -0
  29. package/dist/core/digest/hook-injection.js +79 -0
  30. package/dist/core/digest/hook-injection.js.map +1 -0
  31. package/dist/core/embedding/embed-backfill.d.ts +13 -2
  32. package/dist/core/embedding/embed-backfill.js +181 -43
  33. package/dist/core/embedding/embed-backfill.js.map +1 -1
  34. package/dist/core/embedding/embedding-config.d.ts +17 -0
  35. package/dist/core/embedding/embedding-config.js +12 -0
  36. package/dist/core/embedding/embedding-config.js.map +1 -0
  37. package/dist/core/embedding/pg-embed-backfill.d.ts +31 -0
  38. package/dist/core/embedding/pg-embed-backfill.js +264 -0
  39. package/dist/core/embedding/pg-embed-backfill.js.map +1 -0
  40. package/dist/core/entities/dedup-suggest.d.ts +25 -0
  41. package/dist/core/entities/dedup-suggest.js +107 -0
  42. package/dist/core/entities/dedup-suggest.js.map +1 -0
  43. package/dist/core/eval/classifier-fixture-eval.d.ts +29 -0
  44. package/dist/core/eval/classifier-fixture-eval.js +217 -0
  45. package/dist/core/eval/classifier-fixture-eval.js.map +1 -0
  46. package/dist/core/eval/extraction-scoring.d.ts +63 -0
  47. package/dist/core/eval/extraction-scoring.js +79 -0
  48. package/dist/core/eval/extraction-scoring.js.map +1 -0
  49. package/dist/core/eval/run-eval.d.ts +40 -0
  50. package/dist/core/eval/run-eval.js +34 -0
  51. package/dist/core/eval/run-eval.js.map +1 -0
  52. package/dist/core/exemplars/capture-from-session.d.ts +2 -0
  53. package/dist/core/exemplars/capture-from-session.js +7 -3
  54. package/dist/core/exemplars/capture-from-session.js.map +1 -1
  55. package/dist/core/exemplars/diff-parse.d.ts +23 -0
  56. package/dist/core/exemplars/diff-parse.js +73 -0
  57. package/dist/core/exemplars/diff-parse.js.map +1 -0
  58. package/dist/core/exemplars/embed-backfill.d.ts +36 -0
  59. package/dist/core/exemplars/embed-backfill.js +85 -0
  60. package/dist/core/exemplars/embed-backfill.js.map +1 -0
  61. package/dist/core/exemplars/embed-text.d.ts +15 -0
  62. package/dist/core/exemplars/embed-text.js +18 -0
  63. package/dist/core/exemplars/embed-text.js.map +1 -0
  64. package/dist/core/exemplars/extract-exemplar.d.ts +2 -0
  65. package/dist/core/exemplars/extract-exemplar.js +9 -66
  66. package/dist/core/exemplars/extract-exemplar.js.map +1 -1
  67. package/dist/core/exemplars/ingest-exemplar.d.ts +1 -0
  68. package/dist/core/exemplars/ingest-exemplar.js +1 -0
  69. package/dist/core/exemplars/ingest-exemplar.js.map +1 -1
  70. package/dist/core/exemplars/recall-code.js +4 -0
  71. package/dist/core/exemplars/recall-code.js.map +1 -1
  72. package/dist/core/exemplars/warm-embedder.d.ts +14 -0
  73. package/dist/core/exemplars/warm-embedder.js +18 -0
  74. package/dist/core/exemplars/warm-embedder.js.map +1 -0
  75. package/dist/core/health/corpus-state.d.ts +8 -0
  76. package/dist/core/health/corpus-state.js +11 -0
  77. package/dist/core/health/corpus-state.js.map +1 -0
  78. package/dist/core/health/embed-inflight.d.ts +9 -0
  79. package/dist/core/health/embed-inflight.js +30 -0
  80. package/dist/core/health/embed-inflight.js.map +1 -0
  81. package/dist/core/health/embedding-lane-state.d.ts +6 -0
  82. package/dist/core/health/embedding-lane-state.js +18 -0
  83. package/dist/core/health/embedding-lane-state.js.map +1 -0
  84. package/dist/core/health/warmup-state.d.ts +12 -0
  85. package/dist/core/health/warmup-state.js +12 -0
  86. package/dist/core/health/warmup-state.js.map +1 -0
  87. package/dist/core/hook/claude-settings.d.ts +1 -1
  88. package/dist/core/hook/claude-settings.js +0 -1
  89. package/dist/core/hook/claude-settings.js.map +1 -1
  90. package/dist/core/hook/gate.d.ts +13 -6
  91. package/dist/core/hook/gate.js +47 -6
  92. package/dist/core/hook/gate.js.map +1 -1
  93. package/dist/core/hook/hook-log.d.ts +5 -0
  94. package/dist/core/hook/hook-log.js.map +1 -1
  95. package/dist/core/hook/memo.d.ts +12 -0
  96. package/dist/core/hook/memo.js +41 -1
  97. package/dist/core/hook/memo.js.map +1 -1
  98. package/dist/core/hook/pointer-block.d.ts +1 -0
  99. package/dist/core/hook/pointer-block.js +23 -2
  100. package/dist/core/hook/pointer-block.js.map +1 -1
  101. package/dist/core/hook/query-extract.d.ts +2 -1
  102. package/dist/core/hook/query-extract.js +10 -1
  103. package/dist/core/hook/query-extract.js.map +1 -1
  104. package/dist/core/hook/resolve-conversation-by-query.d.ts +28 -0
  105. package/dist/core/hook/resolve-conversation-by-query.js +98 -0
  106. package/dist/core/hook/resolve-conversation-by-query.js.map +1 -0
  107. package/dist/core/hook/select.d.ts +8 -0
  108. package/dist/core/hook/select.js +9 -2
  109. package/dist/core/hook/select.js.map +1 -1
  110. package/dist/core/hook/transcript.js +16 -2
  111. package/dist/core/hook/transcript.js.map +1 -1
  112. package/dist/core/ingest/backfill-derivables.d.ts +92 -0
  113. package/dist/core/ingest/backfill-derivables.js +175 -0
  114. package/dist/core/ingest/backfill-derivables.js.map +1 -0
  115. package/dist/core/ingest/ingest-session.d.ts +5 -0
  116. package/dist/core/ingest/ingest-session.js +23 -0
  117. package/dist/core/ingest/ingest-session.js.map +1 -1
  118. package/dist/core/ingest/reclassify-oversized.d.ts +5 -0
  119. package/dist/core/ingest/reclassify-oversized.js +9 -0
  120. package/dist/core/ingest/reclassify-oversized.js.map +1 -1
  121. package/dist/core/ingest/reprocess.d.ts +96 -0
  122. package/dist/core/ingest/reprocess.js +280 -0
  123. package/dist/core/ingest/reprocess.js.map +1 -0
  124. package/dist/core/ingest/transcript-derivables.d.ts +27 -0
  125. package/dist/core/ingest/transcript-derivables.js +138 -0
  126. package/dist/core/ingest/transcript-derivables.js.map +1 -0
  127. package/dist/core/integrity/check-invariants.d.ts +6 -1
  128. package/dist/core/integrity/check-invariants.js +209 -3
  129. package/dist/core/integrity/check-invariants.js.map +1 -1
  130. package/dist/core/metrics/corpus-stats.d.ts +49 -0
  131. package/dist/core/metrics/corpus-stats.js +111 -0
  132. package/dist/core/metrics/corpus-stats.js.map +1 -0
  133. package/dist/core/metrics/re-derivation.d.ts +48 -0
  134. package/dist/core/metrics/re-derivation.js +87 -0
  135. package/dist/core/metrics/re-derivation.js.map +1 -0
  136. package/dist/core/outcome/coverage.d.ts +33 -0
  137. package/dist/core/outcome/coverage.js +46 -0
  138. package/dist/core/outcome/coverage.js.map +1 -0
  139. package/dist/core/outcome/rollup.d.ts +33 -0
  140. package/dist/core/outcome/rollup.js +113 -0
  141. package/dist/core/outcome/rollup.js.map +1 -0
  142. package/dist/core/recall/citation-log.d.ts +8 -0
  143. package/dist/core/recall/citation-log.js +17 -0
  144. package/dist/core/recall/citation-log.js.map +1 -1
  145. package/dist/core/recall/hook-recall-log.d.ts +2 -2
  146. package/dist/core/recall/hook-recall-log.js +2 -2
  147. package/dist/core/recall/query-intent.d.ts +7 -0
  148. package/dist/core/recall/query-intent.js +25 -0
  149. package/dist/core/recall/query-intent.js.map +1 -0
  150. package/dist/core/recall/query-log.d.ts +4 -0
  151. package/dist/core/recall/query-log.js +4 -0
  152. package/dist/core/recall/query-log.js.map +1 -1
  153. package/dist/core/recall/recall-service.d.ts +37 -1
  154. package/dist/core/recall/recall-service.js +106 -63
  155. package/dist/core/recall/recall-service.js.map +1 -1
  156. package/dist/core/recall/related-exemplars.d.ts +1 -0
  157. package/dist/core/recall/related-exemplars.js +4 -1
  158. package/dist/core/recall/related-exemplars.js.map +1 -1
  159. package/dist/core/recall/related-facts.js +2 -2
  160. package/dist/core/recall/related-facts.js.map +1 -1
  161. package/dist/core/recall/reranker.d.ts +2 -1
  162. package/dist/core/recall/reranker.js +3 -3
  163. package/dist/core/recall/reranker.js.map +1 -1
  164. package/dist/core/recall-facts/fact-query-log.d.ts +7 -0
  165. package/dist/core/recall-facts/fact-query-log.js +2 -0
  166. package/dist/core/recall-facts/fact-query-log.js.map +1 -1
  167. package/dist/core/recall-facts/fact-recall-service.d.ts +9 -1
  168. package/dist/core/recall-facts/fact-recall-service.js +22 -8
  169. package/dist/core/recall-facts/fact-recall-service.js.map +1 -1
  170. package/dist/core/scheduler/scan-once.d.ts +6 -6
  171. package/dist/core/scheduler/scan-once.js +15 -49
  172. package/dist/core/scheduler/scan-once.js.map +1 -1
  173. package/dist/core/scheduler/scheduler.d.ts +10 -0
  174. package/dist/core/scheduler/scheduler.js +109 -13
  175. package/dist/core/scheduler/scheduler.js.map +1 -1
  176. package/dist/core/scope/alias-map.d.ts +10 -0
  177. package/dist/core/scope/alias-map.js +41 -0
  178. package/dist/core/scope/alias-map.js.map +1 -0
  179. package/dist/core/scope/derive-scope.d.ts +8 -0
  180. package/dist/core/scope/derive-scope.js +54 -0
  181. package/dist/core/scope/derive-scope.js.map +1 -0
  182. package/dist/core/scope/scope-clause.d.ts +16 -0
  183. package/dist/core/scope/scope-clause.js +21 -0
  184. package/dist/core/scope/scope-clause.js.map +1 -0
  185. package/dist/core/scope/stamp-flag.d.ts +1 -0
  186. package/dist/core/scope/stamp-flag.js +4 -0
  187. package/dist/core/scope/stamp-flag.js.map +1 -0
  188. package/dist/core/signals/code-signal.d.ts +50 -0
  189. package/dist/core/signals/code-signal.js +54 -0
  190. package/dist/core/signals/code-signal.js.map +1 -0
  191. package/dist/core/signals/ingest-signal.d.ts +1 -1
  192. package/dist/core/signals/ingest-signal.js +3 -1
  193. package/dist/core/signals/ingest-signal.js.map +1 -1
  194. package/dist/core/signals/stamp-scope.d.ts +18 -0
  195. package/dist/core/signals/stamp-scope.js +28 -0
  196. package/dist/core/signals/stamp-scope.js.map +1 -0
  197. package/dist/core/storage/db-restore.js +3 -1
  198. package/dist/core/storage/db-restore.js.map +1 -1
  199. package/dist/core/storage/fact-batch.d.ts +9 -0
  200. package/dist/core/storage/fact-batch.js +14 -0
  201. package/dist/core/storage/fact-batch.js.map +1 -0
  202. package/dist/core/storage/pg-code-exemplar-store.d.ts +1 -0
  203. package/dist/core/storage/pg-code-exemplar-store.js +13 -2
  204. package/dist/core/storage/pg-code-exemplar-store.js.map +1 -1
  205. package/dist/core/storage/pg-embedding-config.d.ts +29 -0
  206. package/dist/core/storage/pg-embedding-config.js +53 -0
  207. package/dist/core/storage/pg-embedding-config.js.map +1 -0
  208. package/dist/core/storage/pg-entity-store.d.ts +12 -0
  209. package/dist/core/storage/pg-entity-store.js +79 -0
  210. package/dist/core/storage/pg-entity-store.js.map +1 -0
  211. package/dist/core/storage/pg-fact-ingest.d.ts +15 -0
  212. package/dist/core/storage/pg-fact-ingest.js +34 -0
  213. package/dist/core/storage/pg-fact-ingest.js.map +1 -0
  214. package/dist/core/storage/pg-fact-store.d.ts +3 -0
  215. package/dist/core/storage/pg-fact-store.js +26 -30
  216. package/dist/core/storage/pg-fact-store.js.map +1 -1
  217. package/dist/core/storage/pg-migrate.d.ts +18 -0
  218. package/dist/core/storage/pg-migrate.js +73 -0
  219. package/dist/core/storage/pg-migrate.js.map +1 -0
  220. package/dist/core/storage/pg-session-store.d.ts +11 -2
  221. package/dist/core/storage/pg-session-store.js +224 -96
  222. package/dist/core/storage/pg-session-store.js.map +1 -1
  223. package/dist/core/storage/pg-signal-store.js +4 -3
  224. package/dist/core/storage/pg-signal-store.js.map +1 -1
  225. package/dist/core/storage/pg-storage.d.ts +9 -7
  226. package/dist/core/storage/pg-storage.js +20 -50
  227. package/dist/core/storage/pg-storage.js.map +1 -1
  228. package/dist/core/storage/pg-workstream-store.d.ts +25 -0
  229. package/dist/core/storage/pg-workstream-store.js +97 -0
  230. package/dist/core/storage/pg-workstream-store.js.map +1 -0
  231. package/dist/core/storage/sqlite-code-exemplar-store.d.ts +1 -0
  232. package/dist/core/storage/sqlite-code-exemplar-store.js +15 -2
  233. package/dist/core/storage/sqlite-code-exemplar-store.js.map +1 -1
  234. package/dist/core/storage/sqlite-embedding-config.d.ts +10 -0
  235. package/dist/core/storage/sqlite-embedding-config.js +27 -0
  236. package/dist/core/storage/sqlite-embedding-config.js.map +1 -0
  237. package/dist/core/storage/sqlite-entity-store.d.ts +13 -0
  238. package/dist/core/storage/sqlite-entity-store.js +96 -0
  239. package/dist/core/storage/sqlite-entity-store.js.map +1 -0
  240. package/dist/core/storage/sqlite-fact-store.d.ts +15 -7
  241. package/dist/core/storage/sqlite-fact-store.js +81 -27
  242. package/dist/core/storage/sqlite-fact-store.js.map +1 -1
  243. package/dist/core/storage/sqlite-outcome-store.d.ts +89 -0
  244. package/dist/core/storage/sqlite-outcome-store.js +158 -0
  245. package/dist/core/storage/sqlite-outcome-store.js.map +1 -0
  246. package/dist/core/storage/sqlite-session-store.d.ts +42 -7
  247. package/dist/core/storage/sqlite-session-store.js +208 -95
  248. package/dist/core/storage/sqlite-session-store.js.map +1 -1
  249. package/dist/core/storage/sqlite-signal-store.js +4 -2
  250. package/dist/core/storage/sqlite-signal-store.js.map +1 -1
  251. package/dist/core/storage/sqlite-storage.d.ts +8 -8
  252. package/dist/core/storage/sqlite-storage.js +21 -32
  253. package/dist/core/storage/sqlite-storage.js.map +1 -1
  254. package/dist/core/storage/sqlite-workstream-store.d.ts +25 -0
  255. package/dist/core/storage/sqlite-workstream-store.js +99 -0
  256. package/dist/core/storage/sqlite-workstream-store.js.map +1 -0
  257. package/dist/core/storage/supersedence-log.js +2 -0
  258. package/dist/core/storage/supersedence-log.js.map +1 -1
  259. package/dist/core/telemetry/probe-filter.d.ts +35 -0
  260. package/dist/core/telemetry/probe-filter.js +56 -0
  261. package/dist/core/telemetry/probe-filter.js.map +1 -0
  262. package/dist/core/update-check/check.d.ts +6 -0
  263. package/dist/core/update-check/check.js +35 -0
  264. package/dist/core/update-check/check.js.map +1 -1
  265. package/dist/core/work-digest/active-spans.d.ts +8 -0
  266. package/dist/core/work-digest/active-spans.js +29 -0
  267. package/dist/core/work-digest/active-spans.js.map +1 -0
  268. package/dist/core/work-digest/attribute.d.ts +15 -0
  269. package/dist/core/work-digest/attribute.js +76 -0
  270. package/dist/core/work-digest/attribute.js.map +1 -0
  271. package/dist/core/work-digest/build-work-digest.d.ts +12 -0
  272. package/dist/core/work-digest/build-work-digest.js +69 -0
  273. package/dist/core/work-digest/build-work-digest.js.map +1 -0
  274. package/dist/core/work-digest/compose-work-digest.d.ts +3 -0
  275. package/dist/core/work-digest/compose-work-digest.js +52 -0
  276. package/dist/core/work-digest/compose-work-digest.js.map +1 -0
  277. package/dist/core/work-digest/merge-active.d.ts +10 -0
  278. package/dist/core/work-digest/merge-active.js +22 -0
  279. package/dist/core/work-digest/merge-active.js.map +1 -0
  280. package/dist/core/work-digest/read-transcript-timestamps.d.ts +7 -0
  281. package/dist/core/work-digest/read-transcript-timestamps.js +40 -0
  282. package/dist/core/work-digest/read-transcript-timestamps.js.map +1 -0
  283. package/dist/core/work-digest/topics.d.ts +18 -0
  284. package/dist/core/work-digest/topics.js +26 -0
  285. package/dist/core/work-digest/topics.js.map +1 -0
  286. package/dist/core/work-digest/types.d.ts +45 -0
  287. package/dist/core/work-digest/types.js +2 -0
  288. package/dist/core/work-digest/types.js.map +1 -0
  289. package/dist/core/workstream/bind.d.ts +26 -0
  290. package/dist/core/workstream/bind.js +42 -0
  291. package/dist/core/workstream/bind.js.map +1 -0
  292. package/dist/core/workstream/compose-recall.d.ts +2 -0
  293. package/dist/core/workstream/compose-recall.js +39 -0
  294. package/dist/core/workstream/compose-recall.js.map +1 -0
  295. package/dist/core/workstream/merge-suggest.d.ts +19 -0
  296. package/dist/core/workstream/merge-suggest.js +61 -0
  297. package/dist/core/workstream/merge-suggest.js.map +1 -0
  298. package/dist/core/workstream/model.d.ts +21 -0
  299. package/dist/core/workstream/model.js +9 -0
  300. package/dist/core/workstream/model.js.map +1 -0
  301. package/dist/core/workstream/name-match.d.ts +8 -0
  302. package/dist/core/workstream/name-match.js +18 -0
  303. package/dist/core/workstream/name-match.js.map +1 -0
  304. package/dist/core/workstream/resolve.d.ts +10 -0
  305. package/dist/core/workstream/resolve.js +21 -0
  306. package/dist/core/workstream/resolve.js.map +1 -0
  307. package/dist/core/workstream/rollup.d.ts +12 -0
  308. package/dist/core/workstream/rollup.js +17 -0
  309. package/dist/core/workstream/rollup.js.map +1 -0
  310. package/dist/core/workstream/work-topics.d.ts +10 -0
  311. package/dist/core/workstream/work-topics.js +55 -0
  312. package/dist/core/workstream/work-topics.js.map +1 -0
  313. package/dist/hook/hook-helpers.d.ts +4 -0
  314. package/dist/hook/hook-helpers.js +36 -0
  315. package/dist/hook/hook-helpers.js.map +1 -0
  316. package/dist/hook/pre-compact-hook.d.ts +23 -0
  317. package/dist/hook/pre-compact-hook.js +67 -0
  318. package/dist/hook/pre-compact-hook.js.map +1 -0
  319. package/dist/hook/prompt-recall-hook.d.ts +38 -0
  320. package/dist/hook/prompt-recall-hook.js +124 -20
  321. package/dist/hook/prompt-recall-hook.js.map +1 -1
  322. package/dist/hook/recall-gate.d.ts +29 -0
  323. package/dist/hook/recall-gate.js +50 -0
  324. package/dist/hook/recall-gate.js.map +1 -0
  325. package/dist/hook/recall-over-http.d.ts +3 -2
  326. package/dist/hook/recall-over-http.js +26 -13
  327. package/dist/hook/recall-over-http.js.map +1 -1
  328. package/dist/hook/recent-context.d.ts +25 -0
  329. package/dist/hook/recent-context.js +104 -0
  330. package/dist/hook/recent-context.js.map +1 -0
  331. package/dist/hook/score-floor.d.ts +27 -0
  332. package/dist/hook/score-floor.js +42 -0
  333. package/dist/hook/score-floor.js.map +1 -0
  334. package/dist/hook/session-end-hook.js +8 -29
  335. package/dist/hook/session-end-hook.js.map +1 -1
  336. package/dist/hook/session-start-hook.js +26 -60
  337. package/dist/hook/session-start-hook.js.map +1 -1
  338. package/dist/hook/stop-hook.js +24 -60
  339. package/dist/hook/stop-hook.js.map +1 -1
  340. package/dist/http/app.d.ts +6 -0
  341. package/dist/http/app.js +52 -44
  342. package/dist/http/app.js.map +1 -1
  343. package/dist/install/setup.js +2 -0
  344. package/dist/install/setup.js.map +1 -1
  345. package/dist/llm/build-classifier.d.ts +22 -0
  346. package/dist/llm/build-classifier.js +42 -0
  347. package/dist/llm/build-classifier.js.map +1 -0
  348. package/dist/llm/build-embedder.d.ts +11 -0
  349. package/dist/llm/build-embedder.js +42 -0
  350. package/dist/llm/build-embedder.js.map +1 -0
  351. package/dist/llm/bundled-embedder-client.d.ts +37 -0
  352. package/dist/llm/bundled-embedder-client.js +90 -0
  353. package/dist/llm/bundled-embedder-client.js.map +1 -0
  354. package/dist/llm/classifier-box.d.ts +13 -5
  355. package/dist/llm/classifier-box.js +28 -6
  356. package/dist/llm/classifier-box.js.map +1 -1
  357. package/dist/llm/classifier-egress.d.ts +18 -0
  358. package/dist/llm/classifier-egress.js +59 -0
  359. package/dist/llm/classifier-egress.js.map +1 -0
  360. package/dist/llm/client-shared.d.ts +4 -0
  361. package/dist/llm/client-shared.js +39 -0
  362. package/dist/llm/client-shared.js.map +1 -0
  363. package/dist/llm/deepseek-client.d.ts +20 -0
  364. package/dist/llm/deepseek-client.js +59 -45
  365. package/dist/llm/deepseek-client.js.map +1 -1
  366. package/dist/llm/embedder-info.d.ts +15 -0
  367. package/dist/llm/embedder-info.js +27 -0
  368. package/dist/llm/embedder-info.js.map +1 -0
  369. package/dist/llm/model-quirks.d.ts +4 -0
  370. package/dist/llm/model-quirks.js +7 -0
  371. package/dist/llm/model-quirks.js.map +1 -0
  372. package/dist/llm/naming.d.ts +5 -0
  373. package/dist/llm/naming.js +20 -0
  374. package/dist/llm/naming.js.map +1 -0
  375. package/dist/llm/ollama-client.d.ts +7 -8
  376. package/dist/llm/ollama-client.js +59 -51
  377. package/dist/llm/ollama-client.js.map +1 -1
  378. package/dist/llm/ollama-code-embedder.d.ts +8 -3
  379. package/dist/llm/ollama-code-embedder.js +14 -24
  380. package/dist/llm/ollama-code-embedder.js.map +1 -1
  381. package/dist/llm/openai-code-embedder-client.d.ts +25 -0
  382. package/dist/llm/openai-code-embedder-client.js +52 -0
  383. package/dist/llm/openai-code-embedder-client.js.map +1 -0
  384. package/dist/llm/openai-embedder-client.d.ts +41 -0
  385. package/dist/llm/openai-embedder-client.js +83 -0
  386. package/dist/llm/openai-embedder-client.js.map +1 -0
  387. package/dist/mcp/server.d.ts +69 -2
  388. package/dist/mcp/server.js +404 -19
  389. package/dist/mcp/server.js.map +1 -1
  390. package/dist/ports/code-embedder.d.ts +6 -1
  391. package/dist/ports/code-exemplar-store.d.ts +5 -0
  392. package/dist/ports/entity-store.d.ts +35 -0
  393. package/dist/ports/entity-store.js +7 -0
  394. package/dist/ports/entity-store.js.map +1 -0
  395. package/dist/ports/fact-store.d.ts +0 -0
  396. package/dist/ports/fact-store.js.map +1 -1
  397. package/dist/ports/llm-client.d.ts +9 -1
  398. package/dist/ports/outcome.d.ts +85 -0
  399. package/dist/ports/outcome.js +11 -0
  400. package/dist/ports/outcome.js.map +1 -0
  401. package/dist/ports/session-store.d.ts +12 -6
  402. package/dist/ports/storage.d.ts +7 -30
  403. package/dist/ports/storage.js +3 -7
  404. package/dist/ports/storage.js.map +1 -1
  405. package/dist/ports/transcript-adapter.d.ts +2 -0
  406. package/dist/ports/workstream-store.d.ts +22 -0
  407. package/dist/ports/workstream-store.js +2 -0
  408. package/dist/ports/workstream-store.js.map +1 -0
  409. package/dist/shared/net.d.ts +3 -0
  410. package/dist/shared/net.js +4 -0
  411. package/dist/shared/net.js.map +1 -0
  412. package/dist/shared/types.d.ts +56 -2
  413. package/dist/shared/types.js +4 -1
  414. package/dist/shared/types.js.map +1 -1
  415. package/dist/ui/assets/{index-CMpQkbQy.js → index-CSaBtgXD.js} +1 -1
  416. package/dist/ui/index.html +1 -1
  417. package/fixtures/classifier-gold/README.md +94 -0
  418. package/fixtures/classifier-gold/reference.json +318 -0
  419. package/fixtures/classifier-gold/transcripts/01-bug-fix-null-pointer-api.txt +75 -0
  420. package/fixtures/classifier-gold/transcripts/02-bug-fix-race-condition-queue.txt +77 -0
  421. package/fixtures/classifier-gold/transcripts/03-bug-fix-jwt-clock-skew.txt +86 -0
  422. package/fixtures/classifier-gold/transcripts/04-feature-webhook-retry.txt +95 -0
  423. package/fixtures/classifier-gold/transcripts/05-feature-csv-export.txt +86 -0
  424. package/fixtures/classifier-gold/transcripts/06-feature-rate-limiting.txt +61 -0
  425. package/fixtures/classifier-gold/transcripts/07-refactor-db-abstraction.txt +72 -0
  426. package/fixtures/classifier-gold/transcripts/08-refactor-config-loading.txt +89 -0
  427. package/fixtures/classifier-gold/transcripts/09-ops-docker-staging.txt +94 -0
  428. package/fixtures/classifier-gold/transcripts/10-ops-nginx-ssl.txt +121 -0
  429. package/fixtures/classifier-gold/transcripts/11-ops-postgres-migration.txt +74 -0
  430. package/fixtures/classifier-gold/transcripts/12-ops-cron-debugging.txt +73 -0
  431. package/fixtures/classifier-gold/transcripts/13-research-vector-db-comparison.txt +59 -0
  432. package/fixtures/classifier-gold/transcripts/14-research-oauth-provider.txt +74 -0
  433. package/fixtures/classifier-gold/transcripts/15-writing-api-docs.txt +154 -0
  434. package/fixtures/classifier-gold/transcripts/16-meeting-sprint-planning.txt +69 -0
  435. package/fixtures/classifier-gold/transcripts/17-trivial-list-files.txt +14 -0
  436. package/fixtures/classifier-gold/transcripts/18-trivial-version-check.txt +21 -0
  437. package/fixtures/classifier-gold/transcripts/19-trivial-syntax-help.txt +29 -0
  438. package/fixtures/classifier-gold/transcripts/20-trivial-read-package-json.txt +41 -0
  439. package/migrations/000_initial_schema.sql +1 -1
  440. package/migrations/024_backfill_exemplar_repo_basename.sql +32 -0
  441. package/migrations/025_workstreams.sql +30 -0
  442. package/migrations/026_embedding_config.sql +12 -0
  443. package/migrations/027_drop_legacy_session_embeddings.sql +7 -0
  444. package/migrations/028_classifier_provenance.sql +5 -0
  445. package/migrations/029_project_scope.sql +21 -0
  446. package/migrations/032_session_derivables.sql +11 -0
  447. package/migrations/pg/001_initial.sql +34 -0
  448. package/migrations/pg/019_split_replaces.sql +16 -7
  449. package/migrations/pg/025_workstreams.sql +34 -0
  450. package/migrations/pg/026_embedding_config.sql +12 -0
  451. package/migrations/pg/028_classifier_provenance.sql +5 -0
  452. package/migrations/pg/029_entity_variants.sql +9 -0
  453. package/migrations/pg/030_project_scope.sql +23 -0
  454. package/migrations/pg/031_widen_session_edges_kind.sql +11 -0
  455. package/migrations/pg/032_session_derivables.sql +17 -0
  456. package/nlm/index.js +405 -39
  457. package/package.json +12 -2
  458. package/plugin/.codex-plugin/plugin.json +2 -2
  459. package/plugin/scripts/prompt-recall-hook.mjs +413 -43
  460. package/plugin/scripts/session-start-hook.mjs +295 -61
  461. package/plugin/scripts/stop-hook.mjs +89 -66
  462. package/plugin-hermes-agent/__init__.py +2 -1
  463. package/templates/agent-contract/README.md +24 -0
  464. package/templates/agent-contract/claude-code.md +40 -0
  465. package/templates/agent-contract/generic.md +38 -0
  466. package/dist/core/embedding/embed-normalize.d.ts +0 -28
  467. package/dist/core/embedding/embed-normalize.js +0 -98
  468. package/dist/core/embedding/embed-normalize.js.map +0 -1
  469. package/dist/core/storage/pg-tx-context.d.ts +0 -52
  470. package/dist/core/storage/pg-tx-context.js +0 -149
  471. package/dist/core/storage/pg-tx-context.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pg-embed-backfill.js","sourceRoot":"","sources":["../../../src/core/embedding/pg-embed-backfill.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Conservative lexical dedup suggestion for the entity table.
3
+ *
4
+ * No embedding similarity in v1: the workstream matcher falsification showed
5
+ * lexical-adjacent-but-different entities are exactly where embeddings
6
+ * over-merge. Start conservative; tighten only after adjudication data exists.
7
+ */
8
+ export interface EntityInput {
9
+ readonly canonical: string;
10
+ readonly sessionCount: number;
11
+ readonly status: string;
12
+ }
13
+ export interface MergeSuggestion {
14
+ readonly source: string;
15
+ readonly target: string;
16
+ readonly cls: "safe" | "likely";
17
+ }
18
+ /**
19
+ * Suggest merge pairs from a flat list of entities.
20
+ *
21
+ * Groups by fold key, then checks likely patterns within each group.
22
+ * Never suggests a pair twice; never chains (one target per group, all
23
+ * remaining members are sources into that target).
24
+ */
25
+ export declare function suggestMerges(entities: ReadonlyArray<EntityInput>): ReadonlyArray<MergeSuggestion>;
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Conservative lexical dedup suggestion for the entity table.
3
+ *
4
+ * No embedding similarity in v1: the workstream matcher falsification showed
5
+ * lexical-adjacent-but-different entities are exactly where embeddings
6
+ * over-merge. Start conservative; tighten only after adjudication data exists.
7
+ */
8
+ /**
9
+ * Fold for safe-class comparison: lowercase, strip spaces, hyphens,
10
+ * underscores, and dots.
11
+ */
12
+ function safeFold(s) {
13
+ return s.toLowerCase().replace(/[\s\-_.]+/g, "");
14
+ }
15
+ // Checked against the already-folded form (hyphens stripped by safeFold).
16
+ const REPO_SUFFIXES_FOLDED = ["ts", "js", "py", "rs", "go"];
17
+ function stripRepoSuffix(folded) {
18
+ for (const suf of REPO_SUFFIXES_FOLDED) {
19
+ if (folded.endsWith(suf) && folded.length > suf.length) {
20
+ return folded.slice(0, -suf.length);
21
+ }
22
+ }
23
+ return folded;
24
+ }
25
+ function isSingularPlural(a, b) {
26
+ return b === a + "s" || a === b + "s";
27
+ }
28
+ function isRepoSuffixPair(a, b) {
29
+ const baseA = stripRepoSuffix(a);
30
+ const baseB = stripRepoSuffix(b);
31
+ if (a === baseA && b === baseB)
32
+ return false;
33
+ return baseA === baseB;
34
+ }
35
+ /**
36
+ * Pick the target: higher sessionCount wins; on tie, lexicographically smaller
37
+ * canonical is the target (deterministic).
38
+ */
39
+ function pickTarget(a, b) {
40
+ if (a.sessionCount !== b.sessionCount) {
41
+ return a.sessionCount > b.sessionCount
42
+ ? { target: a, source: b }
43
+ : { target: b, source: a };
44
+ }
45
+ return a.canonical <= b.canonical
46
+ ? { target: a, source: b }
47
+ : { target: b, source: a };
48
+ }
49
+ /**
50
+ * Suggest merge pairs from a flat list of entities.
51
+ *
52
+ * Groups by fold key, then checks likely patterns within each group.
53
+ * Never suggests a pair twice; never chains (one target per group, all
54
+ * remaining members are sources into that target).
55
+ */
56
+ export function suggestMerges(entities) {
57
+ const active = entities.filter((e) => e.status !== "retired");
58
+ const safeGroups = new Map();
59
+ for (const e of active) {
60
+ const key = safeFold(e.canonical);
61
+ if (!safeGroups.has(key))
62
+ safeGroups.set(key, []);
63
+ safeGroups.get(key).push(e);
64
+ }
65
+ // Emission-order invariant the CLI applier depends on: every pair that uses
66
+ // an entity as TARGET is emitted before the (single) pair that consumes it as
67
+ // SOURCE, so sequential application never merges into an already-retired row.
68
+ // Reordering emissions (or applying suggestions out of list order) breaks this.
69
+ const suggestions = [];
70
+ const consumedAsSource = new Set();
71
+ for (const group of safeGroups.values()) {
72
+ if (group.length < 2)
73
+ continue;
74
+ const sorted = [...group].sort((a, b) => {
75
+ if (b.sessionCount !== a.sessionCount)
76
+ return b.sessionCount - a.sessionCount;
77
+ return a.canonical <= b.canonical ? -1 : 1;
78
+ });
79
+ const target = sorted[0];
80
+ for (let i = 1; i < sorted.length; i++) {
81
+ const source = sorted[i];
82
+ if (consumedAsSource.has(source.canonical))
83
+ continue;
84
+ suggestions.push({ source: source.canonical, target: target.canonical, cls: "safe" });
85
+ consumedAsSource.add(source.canonical);
86
+ }
87
+ }
88
+ const activeNonSafe = active.filter((e) => !consumedAsSource.has(e.canonical));
89
+ for (let i = 0; i < activeNonSafe.length; i++) {
90
+ for (let j = i + 1; j < activeNonSafe.length; j++) {
91
+ const a = activeNonSafe[i];
92
+ const b = activeNonSafe[j];
93
+ if (consumedAsSource.has(a.canonical) || consumedAsSource.has(b.canonical))
94
+ continue;
95
+ const fa = safeFold(a.canonical);
96
+ const fb = safeFold(b.canonical);
97
+ const isLikely = isSingularPlural(fa, fb) || isRepoSuffixPair(fa, fb);
98
+ if (!isLikely)
99
+ continue;
100
+ const { target, source } = pickTarget(a, b);
101
+ suggestions.push({ source: source.canonical, target: target.canonical, cls: "likely" });
102
+ consumedAsSource.add(source.canonical);
103
+ }
104
+ }
105
+ return suggestions;
106
+ }
107
+ //# sourceMappingURL=dedup-suggest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dedup-suggest.js","sourceRoot":"","sources":["../../../src/core/entities/dedup-suggest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import type { ClassifyResult } from "../../ports/llm-client.js";
2
+ export interface FixtureEvalResult {
3
+ readonly perTranscript: ReadonlyArray<{
4
+ readonly id: string;
5
+ readonly schemaValid: boolean;
6
+ readonly timedOutOrUnreachable: boolean;
7
+ readonly labelMatch: boolean;
8
+ readonly entityPrecision: number;
9
+ readonly entityRecall: number;
10
+ readonly decisionPrecision: number;
11
+ readonly decisionRecall: number;
12
+ readonly confidence: number;
13
+ readonly confidenceCalibrated: boolean;
14
+ readonly elapsedMs: number;
15
+ }>;
16
+ readonly aggregate: {
17
+ readonly schemaValidRate: number;
18
+ readonly labelAccuracy: number;
19
+ readonly entityF1: number;
20
+ readonly decisionF1: number;
21
+ readonly confidenceCalibrationRate: number;
22
+ readonly p50LatencyMs: number;
23
+ readonly p95LatencyMs: number;
24
+ readonly timedOutOrUnreachable: number;
25
+ };
26
+ }
27
+ export declare function runClassifierFixtureEval(classify: (transcript: string) => Promise<ClassifyResult>, fixturesDir: string, opts?: {
28
+ readonly limit?: number;
29
+ }): Promise<FixtureEvalResult>;
@@ -0,0 +1,217 @@
1
+ import { readFileSync, readdirSync } from "node:fs";
2
+ import { join, basename } from "node:path";
3
+ import { ClassifierSchemaError, LLMUnreachableError } from "../../ports/llm-client.js";
4
+ import { rate } from "../eval/extraction-scoring.js";
5
+ function loadReference(fixturesDir) {
6
+ const raw = readFileSync(join(fixturesDir, "reference.json"), "utf-8");
7
+ return JSON.parse(raw);
8
+ }
9
+ function loadTranscript(fixturesDir, id) {
10
+ return readFileSync(join(fixturesDir, "transcripts", `${id}.txt`), "utf-8");
11
+ }
12
+ function listTranscriptIds(fixturesDir) {
13
+ const dir = join(fixturesDir, "transcripts");
14
+ return readdirSync(dir)
15
+ .filter((f) => f.endsWith(".txt"))
16
+ .map((f) => basename(f, ".txt"))
17
+ .sort();
18
+ }
19
+ function normalizeStr(s) {
20
+ return s.toLowerCase().trim();
21
+ }
22
+ function labelMatches(extracted, ref) {
23
+ const e = normalizeStr(extracted);
24
+ const candidates = [ref.label, ...ref.labelAlternates].map(normalizeStr);
25
+ for (const c of candidates) {
26
+ if (e === c)
27
+ return true;
28
+ if (e.includes(c) || c.includes(e))
29
+ return true;
30
+ if (keyTokenOverlap(e, c) >= 0.5)
31
+ return true;
32
+ }
33
+ return false;
34
+ }
35
+ function keyTokenOverlap(a, b) {
36
+ const tokA = keyTokens(a);
37
+ const tokB = keyTokens(b);
38
+ if (tokA.size === 0 || tokB.size === 0)
39
+ return 0;
40
+ let hits = 0;
41
+ for (const t of tokA)
42
+ if (tokB.has(t))
43
+ hits++;
44
+ return hits / Math.max(tokA.size, tokB.size);
45
+ }
46
+ function keyTokens(s) {
47
+ const STOPWORDS = new Set([
48
+ "a", "an", "the", "and", "or", "for", "to", "of", "in", "on", "with",
49
+ "at", "by", "from", "up", "as", "is", "it", "its", "into", "that",
50
+ "this", "be", "are", "was", "were", "has", "have", "had",
51
+ ]);
52
+ return new Set(s
53
+ .replace(/[^a-z0-9\s]/g, " ")
54
+ .split(/\s+/)
55
+ .filter((t) => t.length >= 3 && !STOPWORDS.has(t)));
56
+ }
57
+ function entityMatchesAny(refEntity, extracted) {
58
+ const rn = normalizeStr(refEntity);
59
+ for (const e of extracted) {
60
+ const en = normalizeStr(e);
61
+ if (en === rn || en.includes(rn) || rn.includes(en))
62
+ return true;
63
+ }
64
+ return false;
65
+ }
66
+ function decisionMatchesAny(refDecision, extracted) {
67
+ const refToks = keyTokens(normalizeStr(refDecision));
68
+ if (refToks.size === 0)
69
+ return extracted.length > 0;
70
+ for (const e of extracted) {
71
+ const eToks = keyTokens(normalizeStr(e));
72
+ let hits = 0;
73
+ for (const t of refToks)
74
+ if (eToks.has(t))
75
+ hits++;
76
+ if (refToks.size > 0 && hits / refToks.size >= 0.5)
77
+ return true;
78
+ }
79
+ return false;
80
+ }
81
+ function scoreEntityPrecision(extracted, reference) {
82
+ if (extracted.length === 0)
83
+ return reference.length === 0 ? 1 : 0;
84
+ const hits = extracted.filter((e) => entityMatchesAny(e, reference));
85
+ return hits.length / extracted.length;
86
+ }
87
+ function scoreEntityRecall(extracted, reference) {
88
+ if (reference.length === 0)
89
+ return 1;
90
+ const verdicts = reference.map((r) => entityMatchesAny(r, extracted));
91
+ return (rate(verdicts, Boolean) ?? 0);
92
+ }
93
+ function scoreDecisionPrecision(extracted, reference) {
94
+ if (extracted.length === 0)
95
+ return reference.length === 0 ? 1 : 0;
96
+ const hits = extracted.filter((e) => decisionMatchesAny(e, reference));
97
+ return hits.length / extracted.length;
98
+ }
99
+ function scoreDecisionRecall(extracted, reference) {
100
+ if (reference.length === 0)
101
+ return 1;
102
+ const verdicts = reference.map((r) => decisionMatchesAny(r, extracted));
103
+ return (rate(verdicts, Boolean) ?? 0);
104
+ }
105
+ function percentile(sorted, p) {
106
+ if (sorted.length === 0)
107
+ return 0;
108
+ const idx = Math.floor((p / 100) * (sorted.length - 1));
109
+ return sorted[idx] ?? 0;
110
+ }
111
+ function f1(precision, recall) {
112
+ const denom = precision + recall;
113
+ if (denom === 0)
114
+ return 0;
115
+ return (2 * precision * recall) / denom;
116
+ }
117
+ function macroF1(perRow) {
118
+ if (perRow.length === 0)
119
+ return 0;
120
+ const sum = perRow.reduce((acc, x) => acc + f1(x.p, x.r), 0);
121
+ return sum / perRow.length;
122
+ }
123
+ export async function runClassifierFixtureEval(classify, fixturesDir, opts) {
124
+ const allRefs = loadReference(fixturesDir);
125
+ const allIds = listTranscriptIds(fixturesDir);
126
+ const refById = new Map(allRefs.map((r) => [r.id, r]));
127
+ const ids = opts?.limit != null ? allIds.slice(0, opts.limit) : allIds;
128
+ const perTranscript = [];
129
+ for (const id of ids) {
130
+ const ref = refById.get(id);
131
+ if (ref === undefined)
132
+ continue;
133
+ const transcript = loadTranscript(fixturesDir, id);
134
+ const start = Date.now();
135
+ let result = null;
136
+ let schemaValid = true;
137
+ let timedOutOrUnreachable = false;
138
+ try {
139
+ result = await classify(transcript);
140
+ }
141
+ catch (err) {
142
+ if (err instanceof ClassifierSchemaError) {
143
+ schemaValid = false;
144
+ }
145
+ else if (err instanceof LLMUnreachableError) {
146
+ schemaValid = false;
147
+ timedOutOrUnreachable = true;
148
+ }
149
+ else {
150
+ throw err;
151
+ }
152
+ }
153
+ const elapsedMs = Date.now() - start;
154
+ if (!schemaValid || result === null) {
155
+ perTranscript.push({
156
+ id,
157
+ schemaValid: false,
158
+ timedOutOrUnreachable,
159
+ labelMatch: false,
160
+ entityPrecision: 0,
161
+ entityRecall: 0,
162
+ decisionPrecision: 0,
163
+ decisionRecall: 0,
164
+ confidence: 0,
165
+ confidenceCalibrated: false,
166
+ elapsedMs,
167
+ });
168
+ continue;
169
+ }
170
+ const lm = labelMatches(result.label, ref);
171
+ const ep = scoreEntityPrecision(result.entities, ref.entities);
172
+ const er = scoreEntityRecall(result.entities, ref.entities);
173
+ const dp = scoreDecisionPrecision(result.decisions, ref.decisions);
174
+ const dr = scoreDecisionRecall(result.decisions, ref.decisions);
175
+ const confidence = result.confidence;
176
+ const confidenceCalibrated = ref.expectLowConfidence
177
+ ? confidence <= 0.4
178
+ : confidence > 0.4;
179
+ perTranscript.push({
180
+ id,
181
+ schemaValid: true,
182
+ timedOutOrUnreachable: false,
183
+ labelMatch: lm,
184
+ entityPrecision: ep,
185
+ entityRecall: er,
186
+ decisionPrecision: dp,
187
+ decisionRecall: dr,
188
+ confidence,
189
+ confidenceCalibrated,
190
+ elapsedMs,
191
+ });
192
+ }
193
+ const n = perTranscript.length;
194
+ const schemaValidRate = n === 0 ? 0 : perTranscript.filter((r) => r.schemaValid).length / n;
195
+ const labelAccuracy = n === 0 ? 0 : perTranscript.filter((r) => r.labelMatch).length / n;
196
+ const confidenceCalibrationRate = n === 0 ? 0 : perTranscript.filter((r) => r.confidenceCalibrated).length / n;
197
+ const timedOutOrUnreachable = perTranscript.filter((r) => r.timedOutOrUnreachable).length;
198
+ const entityF1 = macroF1(perTranscript.map((r) => ({ p: r.entityPrecision, r: r.entityRecall })));
199
+ const decisionF1 = macroF1(perTranscript.map((r) => ({ p: r.decisionPrecision, r: r.decisionRecall })));
200
+ const sortedLatency = [...perTranscript.map((r) => r.elapsedMs)].sort((a, b) => a - b);
201
+ const p50LatencyMs = percentile(sortedLatency, 50);
202
+ const p95LatencyMs = percentile(sortedLatency, 95);
203
+ return {
204
+ perTranscript,
205
+ aggregate: {
206
+ schemaValidRate,
207
+ labelAccuracy,
208
+ entityF1,
209
+ decisionF1,
210
+ confidenceCalibrationRate,
211
+ p50LatencyMs,
212
+ p95LatencyMs,
213
+ timedOutOrUnreachable,
214
+ },
215
+ };
216
+ }
217
+ //# sourceMappingURL=classifier-fixture-eval.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classifier-fixture-eval.js","sourceRoot":"","sources":["../../../src/core/eval/classifier-fixture-eval.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Pure scoring + aggregation for the classifier extraction-quality eval.
3
+ *
4
+ * The scoring model is precision/recall over three extraction surfaces:
5
+ * - DECISION PRECISION: of the decisions a candidate extracted, what fraction
6
+ * a judge ruled `supported` against the TRANSCRIPT (not the reference -- a
7
+ * candidate may legitimately surface a true decision the reference missed).
8
+ * - DECISION RECALL: of the REFERENCE decisions, what fraction the judge ruled
9
+ * semantically matched by some candidate decision.
10
+ * - ENTITY PRECISION: of the entities a candidate extracted, what fraction the
11
+ * judge ruled actually present/relevant in the transcript.
12
+ *
13
+ * These functions are deterministic and dependency-free. The live judge work
14
+ * (LLM verdicts) happens in the harness; this module only turns verdict arrays
15
+ * into rates so the math is unit-testable without an LLM.
16
+ */
17
+ export type Verdict = "supported" | "unsupported";
18
+ export type MatchVerdict = "matched" | "unmatched";
19
+ export interface ExtractionVerdicts {
20
+ /** One per candidate-extracted decision: faithful to transcript? */
21
+ readonly decisionPrecision: ReadonlyArray<Verdict>;
22
+ /** One per reference decision: matched by any candidate decision? */
23
+ readonly decisionRecall: ReadonlyArray<MatchVerdict>;
24
+ /** One per candidate-extracted entity: present/relevant in transcript? */
25
+ readonly entityPrecision: ReadonlyArray<Verdict>;
26
+ /** Distinct transcript decisions captured by no extracted decision (judge count). */
27
+ readonly missedDecisions: number;
28
+ }
29
+ export interface SessionScore {
30
+ readonly decisionPrecision: number | null;
31
+ /** Reference-based recall: fraction of reference decisions matched. Position-biased. */
32
+ readonly decisionRecall: number | null;
33
+ /** Transcript-grounded recall: supported / (supported + missedDecisions). Reference-free. */
34
+ readonly decisionRecallTranscript: number | null;
35
+ readonly entityPrecision: number | null;
36
+ /** True when the candidate produced no usable ClassifyResult for this session. */
37
+ readonly schemaFailed: boolean;
38
+ }
39
+ /**
40
+ * Per-session rates. A surface with zero items yields `null` (not 0): a session
41
+ * with no extracted decisions has undefined precision, not 0% precision, and
42
+ * must not drag the mean down. nulls are dropped at aggregation time.
43
+ */
44
+ export declare function scoreSession(verdicts: ExtractionVerdicts, schemaFailed: boolean): SessionScore;
45
+ export declare function rate<T>(items: ReadonlyArray<T>, hit: (x: T) => boolean): number | null;
46
+ export interface AggregateExtraction {
47
+ readonly n: number;
48
+ /** Sessions that produced a usable extraction (n - schema failures). */
49
+ readonly scored: number;
50
+ readonly schemaFailures: number;
51
+ /** Macro-average across sessions that had >= 1 item on the surface. */
52
+ readonly decisionPrecision: number | null;
53
+ readonly decisionRecall: number | null;
54
+ readonly decisionRecallTranscript: number | null;
55
+ readonly entityPrecision: number | null;
56
+ /** How many sessions contributed to each surface mean (had >= 1 item). */
57
+ readonly decisionPrecisionN: number;
58
+ readonly decisionRecallN: number;
59
+ readonly decisionRecallTranscriptN: number;
60
+ readonly entityPrecisionN: number;
61
+ }
62
+ /** Macro-average per-session rates, dropping nulls (surfaces with no items). */
63
+ export declare function aggregateExtraction(scores: ReadonlyArray<SessionScore>): AggregateExtraction;
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Pure scoring + aggregation for the classifier extraction-quality eval.
3
+ *
4
+ * The scoring model is precision/recall over three extraction surfaces:
5
+ * - DECISION PRECISION: of the decisions a candidate extracted, what fraction
6
+ * a judge ruled `supported` against the TRANSCRIPT (not the reference -- a
7
+ * candidate may legitimately surface a true decision the reference missed).
8
+ * - DECISION RECALL: of the REFERENCE decisions, what fraction the judge ruled
9
+ * semantically matched by some candidate decision.
10
+ * - ENTITY PRECISION: of the entities a candidate extracted, what fraction the
11
+ * judge ruled actually present/relevant in the transcript.
12
+ *
13
+ * These functions are deterministic and dependency-free. The live judge work
14
+ * (LLM verdicts) happens in the harness; this module only turns verdict arrays
15
+ * into rates so the math is unit-testable without an LLM.
16
+ */
17
+ /**
18
+ * Per-session rates. A surface with zero items yields `null` (not 0): a session
19
+ * with no extracted decisions has undefined precision, not 0% precision, and
20
+ * must not drag the mean down. nulls are dropped at aggregation time.
21
+ */
22
+ export function scoreSession(verdicts, schemaFailed) {
23
+ if (schemaFailed) {
24
+ return {
25
+ decisionPrecision: null,
26
+ decisionRecall: null,
27
+ decisionRecallTranscript: null,
28
+ entityPrecision: null,
29
+ schemaFailed: true,
30
+ };
31
+ }
32
+ const supported = verdicts.decisionPrecision.filter((v) => v === "supported").length;
33
+ const recallDenom = supported + verdicts.missedDecisions;
34
+ return {
35
+ decisionPrecision: rate(verdicts.decisionPrecision, (v) => v === "supported"),
36
+ decisionRecall: rate(verdicts.decisionRecall, (v) => v === "matched"),
37
+ decisionRecallTranscript: recallDenom === 0 ? null : supported / recallDenom,
38
+ entityPrecision: rate(verdicts.entityPrecision, (v) => v === "supported"),
39
+ schemaFailed: false,
40
+ };
41
+ }
42
+ export function rate(items, hit) {
43
+ if (items.length === 0)
44
+ return null;
45
+ let n = 0;
46
+ for (const x of items)
47
+ if (hit(x))
48
+ n++;
49
+ return n / items.length;
50
+ }
51
+ /** Macro-average per-session rates, dropping nulls (surfaces with no items). */
52
+ export function aggregateExtraction(scores) {
53
+ const schemaFailures = scores.filter((s) => s.schemaFailed).length;
54
+ const dp = meanOfDefined(scores.map((s) => s.decisionPrecision));
55
+ const dr = meanOfDefined(scores.map((s) => s.decisionRecall));
56
+ const drt = meanOfDefined(scores.map((s) => s.decisionRecallTranscript));
57
+ const ep = meanOfDefined(scores.map((s) => s.entityPrecision));
58
+ return {
59
+ n: scores.length,
60
+ scored: scores.length - schemaFailures,
61
+ schemaFailures,
62
+ decisionPrecision: dp.mean,
63
+ decisionRecall: dr.mean,
64
+ decisionRecallTranscript: drt.mean,
65
+ entityPrecision: ep.mean,
66
+ decisionPrecisionN: dp.count,
67
+ decisionRecallN: dr.count,
68
+ decisionRecallTranscriptN: drt.count,
69
+ entityPrecisionN: ep.count,
70
+ };
71
+ }
72
+ function meanOfDefined(values) {
73
+ const defined = values.filter((v) => v !== null);
74
+ if (defined.length === 0)
75
+ return { mean: null, count: 0 };
76
+ const sum = defined.reduce((a, b) => a + b, 0);
77
+ return { mean: sum / defined.length, count: defined.length };
78
+ }
79
+ //# sourceMappingURL=extraction-scoring.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extraction-scoring.js","sourceRoot":"","sources":["../../../src/core/eval/extraction-scoring.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Corpus-agnostic R@k / MRR runner shared by `nlm eval` and the regression
3
+ * gate. Takes a query set with expected ids and a recall searcher, returns a
4
+ * per-mode report. The query set is supplied by the caller and never bundled.
5
+ */
6
+ import type { RecallMode } from "../../shared/types.js";
7
+ export interface EvalQuery {
8
+ readonly query: string;
9
+ readonly expectedIds: ReadonlyArray<string>;
10
+ }
11
+ export interface EvalReport {
12
+ readonly mode: RecallMode;
13
+ readonly n: number;
14
+ readonly rAt1: number;
15
+ readonly rAt5: number;
16
+ readonly mrr: number;
17
+ readonly misses: ReadonlyArray<{
18
+ query: string;
19
+ expected: ReadonlyArray<string>;
20
+ got: ReadonlyArray<string>;
21
+ }>;
22
+ }
23
+ interface Searcher {
24
+ search(q: {
25
+ query: string;
26
+ mode: RecallMode;
27
+ limit: number;
28
+ }): Promise<{
29
+ results: ReadonlyArray<{
30
+ id: string;
31
+ }>;
32
+ }>;
33
+ }
34
+ export declare function runEval(deps: {
35
+ recall: Searcher;
36
+ }, queries: ReadonlyArray<EvalQuery>, opts: {
37
+ mode: RecallMode;
38
+ k: number;
39
+ }): Promise<EvalReport>;
40
+ export {};
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Corpus-agnostic R@k / MRR runner shared by `nlm eval` and the regression
3
+ * gate. Takes a query set with expected ids and a recall searcher, returns a
4
+ * per-mode report. The query set is supplied by the caller and never bundled.
5
+ */
6
+ export async function runEval(deps, queries, opts) {
7
+ let hit1 = 0;
8
+ let hit5 = 0;
9
+ let rrSum = 0;
10
+ const misses = [];
11
+ for (const q of queries) {
12
+ const { results } = await deps.recall.search({ query: q.query, mode: opts.mode, limit: opts.k });
13
+ const ids = results.map((r) => r.id);
14
+ const rank = ids.findIndex((id) => q.expectedIds.includes(id)) + 1; // 0 => miss
15
+ if (rank === 1)
16
+ hit1++;
17
+ if (rank >= 1 && rank <= 5)
18
+ hit5++;
19
+ if (rank >= 1)
20
+ rrSum += 1 / rank;
21
+ else
22
+ misses.push({ query: q.query, expected: q.expectedIds, got: ids });
23
+ }
24
+ const n = queries.length || 1;
25
+ return {
26
+ mode: opts.mode,
27
+ n: queries.length,
28
+ rAt1: hit1 / n,
29
+ rAt5: hit5 / n,
30
+ mrr: rrSum / n,
31
+ misses,
32
+ };
33
+ }
34
+ //# sourceMappingURL=run-eval.js.map