nlm-memory 0.20.0 → 0.20.1

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 (392) hide show
  1. package/README.md +17 -10
  2. package/dist/cli/digest.js +21 -0
  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 +766 -55
  9. package/dist/cli/nlm.js.map +1 -1
  10. package/dist/core/actions/overlay.d.ts +20 -6
  11. package/dist/core/actions/overlay.js +32 -18
  12. package/dist/core/actions/overlay.js.map +1 -1
  13. package/dist/core/adapters/claude-code.js +6 -0
  14. package/dist/core/adapters/claude-code.js.map +1 -1
  15. package/dist/core/classifier/prompt.js +3 -3
  16. package/dist/core/digest/compose.d.ts +10 -0
  17. package/dist/core/digest/compose.js +7 -1
  18. package/dist/core/digest/compose.js.map +1 -1
  19. package/dist/core/embedding/embed-backfill.d.ts +13 -2
  20. package/dist/core/embedding/embed-backfill.js +181 -43
  21. package/dist/core/embedding/embed-backfill.js.map +1 -1
  22. package/dist/core/embedding/embedding-config.d.ts +17 -0
  23. package/dist/core/embedding/embedding-config.js +12 -0
  24. package/dist/core/embedding/embedding-config.js.map +1 -0
  25. package/dist/core/embedding/pg-embed-backfill.d.ts +31 -0
  26. package/dist/core/embedding/pg-embed-backfill.js +264 -0
  27. package/dist/core/embedding/pg-embed-backfill.js.map +1 -0
  28. package/dist/core/entities/dedup-suggest.d.ts +25 -0
  29. package/dist/core/entities/dedup-suggest.js +107 -0
  30. package/dist/core/entities/dedup-suggest.js.map +1 -0
  31. package/dist/core/eval/classifier-fixture-eval.d.ts +29 -0
  32. package/dist/core/eval/classifier-fixture-eval.js +217 -0
  33. package/dist/core/eval/classifier-fixture-eval.js.map +1 -0
  34. package/dist/core/eval/extraction-scoring.d.ts +63 -0
  35. package/dist/core/eval/extraction-scoring.js +79 -0
  36. package/dist/core/eval/extraction-scoring.js.map +1 -0
  37. package/dist/core/eval/run-eval.d.ts +40 -0
  38. package/dist/core/eval/run-eval.js +34 -0
  39. package/dist/core/eval/run-eval.js.map +1 -0
  40. package/dist/core/exemplars/capture-from-session.d.ts +1 -0
  41. package/dist/core/exemplars/capture-from-session.js +6 -2
  42. package/dist/core/exemplars/capture-from-session.js.map +1 -1
  43. package/dist/core/exemplars/diff-parse.d.ts +23 -0
  44. package/dist/core/exemplars/diff-parse.js +73 -0
  45. package/dist/core/exemplars/diff-parse.js.map +1 -0
  46. package/dist/core/exemplars/embed-backfill.d.ts +36 -0
  47. package/dist/core/exemplars/embed-backfill.js +85 -0
  48. package/dist/core/exemplars/embed-backfill.js.map +1 -0
  49. package/dist/core/exemplars/embed-text.d.ts +15 -0
  50. package/dist/core/exemplars/embed-text.js +18 -0
  51. package/dist/core/exemplars/embed-text.js.map +1 -0
  52. package/dist/core/exemplars/extract-exemplar.js +2 -65
  53. package/dist/core/exemplars/extract-exemplar.js.map +1 -1
  54. package/dist/core/exemplars/recall-code.js +4 -0
  55. package/dist/core/exemplars/recall-code.js.map +1 -1
  56. package/dist/core/exemplars/warm-embedder.d.ts +14 -0
  57. package/dist/core/exemplars/warm-embedder.js +18 -0
  58. package/dist/core/exemplars/warm-embedder.js.map +1 -0
  59. package/dist/core/health/corpus-state.d.ts +8 -0
  60. package/dist/core/health/corpus-state.js +11 -0
  61. package/dist/core/health/corpus-state.js.map +1 -0
  62. package/dist/core/health/embed-inflight.d.ts +9 -0
  63. package/dist/core/health/embed-inflight.js +30 -0
  64. package/dist/core/health/embed-inflight.js.map +1 -0
  65. package/dist/core/health/embedding-lane-state.d.ts +6 -0
  66. package/dist/core/health/embedding-lane-state.js +18 -0
  67. package/dist/core/health/embedding-lane-state.js.map +1 -0
  68. package/dist/core/health/warmup-state.d.ts +12 -0
  69. package/dist/core/health/warmup-state.js +12 -0
  70. package/dist/core/health/warmup-state.js.map +1 -0
  71. package/dist/core/hook/gate.d.ts +13 -6
  72. package/dist/core/hook/gate.js +47 -6
  73. package/dist/core/hook/gate.js.map +1 -1
  74. package/dist/core/hook/hook-log.d.ts +5 -0
  75. package/dist/core/hook/hook-log.js.map +1 -1
  76. package/dist/core/hook/memo.d.ts +12 -0
  77. package/dist/core/hook/memo.js +41 -1
  78. package/dist/core/hook/memo.js.map +1 -1
  79. package/dist/core/hook/pointer-block.d.ts +1 -0
  80. package/dist/core/hook/pointer-block.js +23 -2
  81. package/dist/core/hook/pointer-block.js.map +1 -1
  82. package/dist/core/hook/query-extract.d.ts +2 -1
  83. package/dist/core/hook/query-extract.js +10 -1
  84. package/dist/core/hook/query-extract.js.map +1 -1
  85. package/dist/core/hook/resolve-conversation-by-query.d.ts +28 -0
  86. package/dist/core/hook/resolve-conversation-by-query.js +98 -0
  87. package/dist/core/hook/resolve-conversation-by-query.js.map +1 -0
  88. package/dist/core/hook/select.d.ts +8 -0
  89. package/dist/core/hook/select.js +9 -2
  90. package/dist/core/hook/select.js.map +1 -1
  91. package/dist/core/hook/transcript.js +16 -2
  92. package/dist/core/hook/transcript.js.map +1 -1
  93. package/dist/core/ingest/ingest-session.d.ts +5 -0
  94. package/dist/core/ingest/ingest-session.js +3 -0
  95. package/dist/core/ingest/ingest-session.js.map +1 -1
  96. package/dist/core/ingest/reclassify-oversized.d.ts +5 -0
  97. package/dist/core/ingest/reclassify-oversized.js +3 -0
  98. package/dist/core/ingest/reclassify-oversized.js.map +1 -1
  99. package/dist/core/ingest/reprocess.d.ts +96 -0
  100. package/dist/core/ingest/reprocess.js +275 -0
  101. package/dist/core/ingest/reprocess.js.map +1 -0
  102. package/dist/core/integrity/check-invariants.d.ts +6 -1
  103. package/dist/core/integrity/check-invariants.js +209 -3
  104. package/dist/core/integrity/check-invariants.js.map +1 -1
  105. package/dist/core/metrics/corpus-stats.d.ts +49 -0
  106. package/dist/core/metrics/corpus-stats.js +111 -0
  107. package/dist/core/metrics/corpus-stats.js.map +1 -0
  108. package/dist/core/metrics/re-derivation.d.ts +48 -0
  109. package/dist/core/metrics/re-derivation.js +87 -0
  110. package/dist/core/metrics/re-derivation.js.map +1 -0
  111. package/dist/core/recall/citation-log.d.ts +8 -0
  112. package/dist/core/recall/citation-log.js +17 -0
  113. package/dist/core/recall/citation-log.js.map +1 -1
  114. package/dist/core/recall/query-intent.d.ts +7 -0
  115. package/dist/core/recall/query-intent.js +25 -0
  116. package/dist/core/recall/query-intent.js.map +1 -0
  117. package/dist/core/recall/query-log.d.ts +4 -0
  118. package/dist/core/recall/query-log.js +4 -0
  119. package/dist/core/recall/query-log.js.map +1 -1
  120. package/dist/core/recall/recall-service.d.ts +37 -1
  121. package/dist/core/recall/recall-service.js +106 -63
  122. package/dist/core/recall/recall-service.js.map +1 -1
  123. package/dist/core/recall/related-exemplars.d.ts +1 -0
  124. package/dist/core/recall/related-exemplars.js +4 -1
  125. package/dist/core/recall/related-exemplars.js.map +1 -1
  126. package/dist/core/recall/related-facts.js +2 -2
  127. package/dist/core/recall/related-facts.js.map +1 -1
  128. package/dist/core/recall/reranker.d.ts +2 -1
  129. package/dist/core/recall/reranker.js +3 -3
  130. package/dist/core/recall/reranker.js.map +1 -1
  131. package/dist/core/recall-facts/fact-query-log.d.ts +7 -0
  132. package/dist/core/recall-facts/fact-query-log.js +2 -0
  133. package/dist/core/recall-facts/fact-query-log.js.map +1 -1
  134. package/dist/core/recall-facts/fact-recall-service.d.ts +9 -1
  135. package/dist/core/recall-facts/fact-recall-service.js +21 -8
  136. package/dist/core/recall-facts/fact-recall-service.js.map +1 -1
  137. package/dist/core/scheduler/scan-once.d.ts +6 -6
  138. package/dist/core/scheduler/scan-once.js +13 -49
  139. package/dist/core/scheduler/scan-once.js.map +1 -1
  140. package/dist/core/scheduler/scheduler.d.ts +10 -0
  141. package/dist/core/scheduler/scheduler.js +75 -10
  142. package/dist/core/scheduler/scheduler.js.map +1 -1
  143. package/dist/core/signals/code-signal.d.ts +49 -0
  144. package/dist/core/signals/code-signal.js +53 -0
  145. package/dist/core/signals/code-signal.js.map +1 -0
  146. package/dist/core/storage/db-restore.js +3 -1
  147. package/dist/core/storage/db-restore.js.map +1 -1
  148. package/dist/core/storage/fact-batch.d.ts +9 -0
  149. package/dist/core/storage/fact-batch.js +14 -0
  150. package/dist/core/storage/fact-batch.js.map +1 -0
  151. package/dist/core/storage/pg-code-exemplar-store.d.ts +1 -0
  152. package/dist/core/storage/pg-code-exemplar-store.js +7 -0
  153. package/dist/core/storage/pg-code-exemplar-store.js.map +1 -1
  154. package/dist/core/storage/pg-embedding-config.d.ts +29 -0
  155. package/dist/core/storage/pg-embedding-config.js +53 -0
  156. package/dist/core/storage/pg-embedding-config.js.map +1 -0
  157. package/dist/core/storage/pg-entity-store.d.ts +12 -0
  158. package/dist/core/storage/pg-entity-store.js +79 -0
  159. package/dist/core/storage/pg-entity-store.js.map +1 -0
  160. package/dist/core/storage/pg-fact-ingest.d.ts +15 -0
  161. package/dist/core/storage/pg-fact-ingest.js +34 -0
  162. package/dist/core/storage/pg-fact-ingest.js.map +1 -0
  163. package/dist/core/storage/pg-fact-store.d.ts +3 -0
  164. package/dist/core/storage/pg-fact-store.js +26 -30
  165. package/dist/core/storage/pg-fact-store.js.map +1 -1
  166. package/dist/core/storage/pg-migrate.d.ts +18 -0
  167. package/dist/core/storage/pg-migrate.js +73 -0
  168. package/dist/core/storage/pg-migrate.js.map +1 -0
  169. package/dist/core/storage/pg-session-store.d.ts +9 -0
  170. package/dist/core/storage/pg-session-store.js +204 -76
  171. package/dist/core/storage/pg-session-store.js.map +1 -1
  172. package/dist/core/storage/pg-storage.d.ts +9 -7
  173. package/dist/core/storage/pg-storage.js +20 -50
  174. package/dist/core/storage/pg-storage.js.map +1 -1
  175. package/dist/core/storage/pg-workstream-store.d.ts +24 -0
  176. package/dist/core/storage/pg-workstream-store.js +96 -0
  177. package/dist/core/storage/pg-workstream-store.js.map +1 -0
  178. package/dist/core/storage/sqlite-code-exemplar-store.d.ts +1 -0
  179. package/dist/core/storage/sqlite-code-exemplar-store.js +11 -0
  180. package/dist/core/storage/sqlite-code-exemplar-store.js.map +1 -1
  181. package/dist/core/storage/sqlite-embedding-config.d.ts +10 -0
  182. package/dist/core/storage/sqlite-embedding-config.js +27 -0
  183. package/dist/core/storage/sqlite-embedding-config.js.map +1 -0
  184. package/dist/core/storage/sqlite-entity-store.d.ts +13 -0
  185. package/dist/core/storage/sqlite-entity-store.js +96 -0
  186. package/dist/core/storage/sqlite-entity-store.js.map +1 -0
  187. package/dist/core/storage/sqlite-fact-store.d.ts +15 -7
  188. package/dist/core/storage/sqlite-fact-store.js +76 -25
  189. package/dist/core/storage/sqlite-fact-store.js.map +1 -1
  190. package/dist/core/storage/sqlite-session-store.d.ts +20 -5
  191. package/dist/core/storage/sqlite-session-store.js +183 -68
  192. package/dist/core/storage/sqlite-session-store.js.map +1 -1
  193. package/dist/core/storage/sqlite-storage.d.ts +8 -8
  194. package/dist/core/storage/sqlite-storage.js +21 -32
  195. package/dist/core/storage/sqlite-storage.js.map +1 -1
  196. package/dist/core/storage/sqlite-workstream-store.d.ts +24 -0
  197. package/dist/core/storage/sqlite-workstream-store.js +98 -0
  198. package/dist/core/storage/sqlite-workstream-store.js.map +1 -0
  199. package/dist/core/work-digest/active-spans.d.ts +8 -0
  200. package/dist/core/work-digest/active-spans.js +29 -0
  201. package/dist/core/work-digest/active-spans.js.map +1 -0
  202. package/dist/core/work-digest/attribute.d.ts +15 -0
  203. package/dist/core/work-digest/attribute.js +76 -0
  204. package/dist/core/work-digest/attribute.js.map +1 -0
  205. package/dist/core/work-digest/build-work-digest.d.ts +12 -0
  206. package/dist/core/work-digest/build-work-digest.js +69 -0
  207. package/dist/core/work-digest/build-work-digest.js.map +1 -0
  208. package/dist/core/work-digest/compose-work-digest.d.ts +3 -0
  209. package/dist/core/work-digest/compose-work-digest.js +52 -0
  210. package/dist/core/work-digest/compose-work-digest.js.map +1 -0
  211. package/dist/core/work-digest/merge-active.d.ts +10 -0
  212. package/dist/core/work-digest/merge-active.js +22 -0
  213. package/dist/core/work-digest/merge-active.js.map +1 -0
  214. package/dist/core/work-digest/read-transcript-timestamps.d.ts +7 -0
  215. package/dist/core/work-digest/read-transcript-timestamps.js +40 -0
  216. package/dist/core/work-digest/read-transcript-timestamps.js.map +1 -0
  217. package/dist/core/work-digest/topics.d.ts +18 -0
  218. package/dist/core/work-digest/topics.js +26 -0
  219. package/dist/core/work-digest/topics.js.map +1 -0
  220. package/dist/core/work-digest/types.d.ts +45 -0
  221. package/dist/core/work-digest/types.js +2 -0
  222. package/dist/core/work-digest/types.js.map +1 -0
  223. package/dist/core/workstream/bind.d.ts +25 -0
  224. package/dist/core/workstream/bind.js +23 -0
  225. package/dist/core/workstream/bind.js.map +1 -0
  226. package/dist/core/workstream/compose-recall.d.ts +2 -0
  227. package/dist/core/workstream/compose-recall.js +39 -0
  228. package/dist/core/workstream/compose-recall.js.map +1 -0
  229. package/dist/core/workstream/merge-suggest.d.ts +19 -0
  230. package/dist/core/workstream/merge-suggest.js +61 -0
  231. package/dist/core/workstream/merge-suggest.js.map +1 -0
  232. package/dist/core/workstream/model.d.ts +20 -0
  233. package/dist/core/workstream/model.js +9 -0
  234. package/dist/core/workstream/model.js.map +1 -0
  235. package/dist/core/workstream/name-match.d.ts +8 -0
  236. package/dist/core/workstream/name-match.js +18 -0
  237. package/dist/core/workstream/name-match.js.map +1 -0
  238. package/dist/core/workstream/resolve.d.ts +10 -0
  239. package/dist/core/workstream/resolve.js +21 -0
  240. package/dist/core/workstream/resolve.js.map +1 -0
  241. package/dist/core/workstream/rollup.d.ts +12 -0
  242. package/dist/core/workstream/rollup.js +17 -0
  243. package/dist/core/workstream/rollup.js.map +1 -0
  244. package/dist/core/workstream/work-topics.d.ts +10 -0
  245. package/dist/core/workstream/work-topics.js +55 -0
  246. package/dist/core/workstream/work-topics.js.map +1 -0
  247. package/dist/hook/hook-helpers.d.ts +4 -0
  248. package/dist/hook/hook-helpers.js +36 -0
  249. package/dist/hook/hook-helpers.js.map +1 -0
  250. package/dist/hook/pre-compact-hook.d.ts +23 -0
  251. package/dist/hook/pre-compact-hook.js +66 -0
  252. package/dist/hook/pre-compact-hook.js.map +1 -0
  253. package/dist/hook/prompt-recall-hook.d.ts +37 -0
  254. package/dist/hook/prompt-recall-hook.js +120 -20
  255. package/dist/hook/prompt-recall-hook.js.map +1 -1
  256. package/dist/hook/recall-gate.d.ts +29 -0
  257. package/dist/hook/recall-gate.js +50 -0
  258. package/dist/hook/recall-gate.js.map +1 -0
  259. package/dist/hook/recall-over-http.d.ts +1 -1
  260. package/dist/hook/recall-over-http.js +11 -11
  261. package/dist/hook/recall-over-http.js.map +1 -1
  262. package/dist/hook/recent-context.d.ts +25 -0
  263. package/dist/hook/recent-context.js +104 -0
  264. package/dist/hook/recent-context.js.map +1 -0
  265. package/dist/hook/score-floor.d.ts +27 -0
  266. package/dist/hook/score-floor.js +42 -0
  267. package/dist/hook/score-floor.js.map +1 -0
  268. package/dist/hook/session-end-hook.js +8 -29
  269. package/dist/hook/session-end-hook.js.map +1 -1
  270. package/dist/hook/session-start-hook.js +24 -59
  271. package/dist/hook/session-start-hook.js.map +1 -1
  272. package/dist/hook/stop-hook.js +22 -59
  273. package/dist/hook/stop-hook.js.map +1 -1
  274. package/dist/hook/subagent-start-hook.d.ts +28 -0
  275. package/dist/hook/subagent-start-hook.js +81 -0
  276. package/dist/hook/subagent-start-hook.js.map +1 -0
  277. package/dist/http/app.js +28 -8
  278. package/dist/http/app.js.map +1 -1
  279. package/dist/install/setup.js +2 -0
  280. package/dist/install/setup.js.map +1 -1
  281. package/dist/llm/build-classifier.d.ts +22 -0
  282. package/dist/llm/build-classifier.js +42 -0
  283. package/dist/llm/build-classifier.js.map +1 -0
  284. package/dist/llm/build-embedder.d.ts +11 -0
  285. package/dist/llm/build-embedder.js +42 -0
  286. package/dist/llm/build-embedder.js.map +1 -0
  287. package/dist/llm/bundled-embedder-client.d.ts +37 -0
  288. package/dist/llm/bundled-embedder-client.js +90 -0
  289. package/dist/llm/bundled-embedder-client.js.map +1 -0
  290. package/dist/llm/classifier-box.d.ts +13 -5
  291. package/dist/llm/classifier-box.js +28 -6
  292. package/dist/llm/classifier-box.js.map +1 -1
  293. package/dist/llm/classifier-egress.d.ts +18 -0
  294. package/dist/llm/classifier-egress.js +59 -0
  295. package/dist/llm/classifier-egress.js.map +1 -0
  296. package/dist/llm/client-shared.d.ts +4 -0
  297. package/dist/llm/client-shared.js +39 -0
  298. package/dist/llm/client-shared.js.map +1 -0
  299. package/dist/llm/deepseek-client.d.ts +20 -0
  300. package/dist/llm/deepseek-client.js +59 -45
  301. package/dist/llm/deepseek-client.js.map +1 -1
  302. package/dist/llm/embedder-info.d.ts +15 -0
  303. package/dist/llm/embedder-info.js +27 -0
  304. package/dist/llm/embedder-info.js.map +1 -0
  305. package/dist/llm/model-quirks.d.ts +4 -0
  306. package/dist/llm/model-quirks.js +7 -0
  307. package/dist/llm/model-quirks.js.map +1 -0
  308. package/dist/llm/naming.d.ts +5 -0
  309. package/dist/llm/naming.js +20 -0
  310. package/dist/llm/naming.js.map +1 -0
  311. package/dist/llm/ollama-client.d.ts +7 -8
  312. package/dist/llm/ollama-client.js +59 -51
  313. package/dist/llm/ollama-client.js.map +1 -1
  314. package/dist/llm/ollama-code-embedder.d.ts +8 -3
  315. package/dist/llm/ollama-code-embedder.js +14 -24
  316. package/dist/llm/ollama-code-embedder.js.map +1 -1
  317. package/dist/llm/openai-code-embedder-client.d.ts +25 -0
  318. package/dist/llm/openai-code-embedder-client.js +52 -0
  319. package/dist/llm/openai-code-embedder-client.js.map +1 -0
  320. package/dist/llm/openai-embedder-client.d.ts +41 -0
  321. package/dist/llm/openai-embedder-client.js +83 -0
  322. package/dist/llm/openai-embedder-client.js.map +1 -0
  323. package/dist/mcp/server.d.ts +47 -2
  324. package/dist/mcp/server.js +303 -18
  325. package/dist/mcp/server.js.map +1 -1
  326. package/dist/ports/code-embedder.d.ts +6 -1
  327. package/dist/ports/code-exemplar-store.d.ts +5 -0
  328. package/dist/ports/entity-store.d.ts +35 -0
  329. package/dist/ports/entity-store.js +7 -0
  330. package/dist/ports/entity-store.js.map +1 -0
  331. package/dist/ports/fact-store.d.ts +0 -0
  332. package/dist/ports/fact-store.js.map +1 -1
  333. package/dist/ports/llm-client.d.ts +9 -1
  334. package/dist/ports/session-store.d.ts +12 -0
  335. package/dist/ports/storage.d.ts +7 -30
  336. package/dist/ports/storage.js +3 -7
  337. package/dist/ports/storage.js.map +1 -1
  338. package/dist/ports/transcript-adapter.d.ts +2 -0
  339. package/dist/ports/workstream-store.d.ts +21 -0
  340. package/dist/ports/workstream-store.js +2 -0
  341. package/dist/ports/workstream-store.js.map +1 -0
  342. package/dist/shared/types.d.ts +23 -2
  343. package/fixtures/classifier-gold/README.md +94 -0
  344. package/fixtures/classifier-gold/reference.json +318 -0
  345. package/fixtures/classifier-gold/transcripts/01-bug-fix-null-pointer-api.txt +75 -0
  346. package/fixtures/classifier-gold/transcripts/02-bug-fix-race-condition-queue.txt +77 -0
  347. package/fixtures/classifier-gold/transcripts/03-bug-fix-jwt-clock-skew.txt +86 -0
  348. package/fixtures/classifier-gold/transcripts/04-feature-webhook-retry.txt +95 -0
  349. package/fixtures/classifier-gold/transcripts/05-feature-csv-export.txt +86 -0
  350. package/fixtures/classifier-gold/transcripts/06-feature-rate-limiting.txt +61 -0
  351. package/fixtures/classifier-gold/transcripts/07-refactor-db-abstraction.txt +72 -0
  352. package/fixtures/classifier-gold/transcripts/08-refactor-config-loading.txt +89 -0
  353. package/fixtures/classifier-gold/transcripts/09-ops-docker-staging.txt +94 -0
  354. package/fixtures/classifier-gold/transcripts/10-ops-nginx-ssl.txt +121 -0
  355. package/fixtures/classifier-gold/transcripts/11-ops-postgres-migration.txt +74 -0
  356. package/fixtures/classifier-gold/transcripts/12-ops-cron-debugging.txt +73 -0
  357. package/fixtures/classifier-gold/transcripts/13-research-vector-db-comparison.txt +59 -0
  358. package/fixtures/classifier-gold/transcripts/14-research-oauth-provider.txt +74 -0
  359. package/fixtures/classifier-gold/transcripts/15-writing-api-docs.txt +154 -0
  360. package/fixtures/classifier-gold/transcripts/16-meeting-sprint-planning.txt +69 -0
  361. package/fixtures/classifier-gold/transcripts/17-trivial-list-files.txt +14 -0
  362. package/fixtures/classifier-gold/transcripts/18-trivial-version-check.txt +21 -0
  363. package/fixtures/classifier-gold/transcripts/19-trivial-syntax-help.txt +29 -0
  364. package/fixtures/classifier-gold/transcripts/20-trivial-read-package-json.txt +41 -0
  365. package/migrations/000_initial_schema.sql +1 -1
  366. package/migrations/024_backfill_exemplar_repo_basename.sql +32 -0
  367. package/migrations/025_workstreams.sql +30 -0
  368. package/migrations/026_embedding_config.sql +12 -0
  369. package/migrations/027_drop_legacy_session_embeddings.sql +7 -0
  370. package/migrations/028_classifier_provenance.sql +5 -0
  371. package/migrations/pg/001_initial.sql +34 -0
  372. package/migrations/pg/019_split_replaces.sql +16 -7
  373. package/migrations/pg/025_workstreams.sql +34 -0
  374. package/migrations/pg/026_embedding_config.sql +12 -0
  375. package/migrations/pg/028_classifier_provenance.sql +5 -0
  376. package/migrations/pg/029_entity_variants.sql +9 -0
  377. package/nlm/index.js +395 -37
  378. package/package.json +12 -2
  379. package/plugin/.codex-plugin/plugin.json +1 -1
  380. package/plugin/scripts/prompt-recall-hook.mjs +402 -41
  381. package/plugin/scripts/session-start-hook.mjs +286 -60
  382. package/plugin/scripts/stop-hook.mjs +85 -65
  383. package/plugin-hermes-agent/__init__.py +2 -1
  384. package/templates/agent-contract/README.md +24 -0
  385. package/templates/agent-contract/claude-code.md +40 -0
  386. package/templates/agent-contract/generic.md +38 -0
  387. package/dist/core/embedding/embed-normalize.d.ts +0 -28
  388. package/dist/core/embedding/embed-normalize.js +0 -98
  389. package/dist/core/embedding/embed-normalize.js.map +0 -1
  390. package/dist/core/storage/pg-tx-context.d.ts +0 -52
  391. package/dist/core/storage/pg-tx-context.js +0 -149
  392. package/dist/core/storage/pg-tx-context.js.map +0 -1
@@ -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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-eval.js","sourceRoot":"","sources":["../../../src/core/eval/run-eval.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA4BH,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,IAA0B,EAC1B,OAAiC,EACjC,IAAqC;IAErC,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,MAAM,MAAM,GAA0F,EAAE,CAAC;IACzG,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;QACjG,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACrC,MAAM,IAAI,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY;QAChF,IAAI,IAAI,KAAK,CAAC;YAAE,IAAI,EAAE,CAAC;QACvB,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC;YAAE,IAAI,EAAE,CAAC;QACnC,IAAI,IAAI,IAAI,CAAC;YAAE,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;;YAC5B,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,WAAW,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;IAC1E,CAAC;IACD,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;IAC9B,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,CAAC,EAAE,OAAO,CAAC,MAAM;QACjB,IAAI,EAAE,IAAI,GAAG,CAAC;QACd,IAAI,EAAE,IAAI,GAAG,CAAC;QACd,GAAG,EAAE,KAAK,GAAG,CAAC;QACd,MAAM;KACP,CAAC;AACJ,CAAC"}
@@ -22,6 +22,7 @@ export interface SessionExemplarContext {
22
22
  readonly summary: string;
23
23
  readonly decisions: ReadonlyArray<string>;
24
24
  readonly installScope: string;
25
+ readonly model?: string;
25
26
  }
26
27
  export declare function composeTaskContext(summary: string, decisions: ReadonlyArray<string>): string;
27
28
  export declare function captureExemplarsFromSession(ctx: SessionExemplarContext): CodeExemplarInput[];
@@ -11,8 +11,10 @@
11
11
  * (the scheduler) to insert + embed. Git failures yield fewer exemplars,
12
12
  * never wrong ones.
13
13
  */
14
+ import { basename } from "node:path";
14
15
  import { detectCommitShas } from "./detect-commits.js";
15
16
  import { extractFromGitSha } from "./extract-exemplar.js";
17
+ import { composeEmbedText } from "./embed-text.js";
16
18
  const TASK_CONTEXT_CAP = 280;
17
19
  export function composeTaskContext(summary, decisions) {
18
20
  const base = summary.trim();
@@ -27,10 +29,12 @@ export function captureExemplarsFromSession(ctx) {
27
29
  const out = [];
28
30
  for (const sha of detectCommitShas(ctx.text)) {
29
31
  const exemplar = extractFromGitSha({
30
- repo: ctx.projectDir,
32
+ repo: basename(ctx.projectDir),
33
+ repoPath: ctx.projectDir,
31
34
  sha,
32
35
  installScope: ctx.installScope,
33
36
  outcome: "pass",
37
+ ...(ctx.model ? { model: ctx.model } : {}),
34
38
  sessionId: ctx.sessionId,
35
39
  ts: ctx.startedAt,
36
40
  taskContext,
@@ -54,7 +58,7 @@ export async function drainSessionExemplars(ctx, deps) {
54
58
  const embedder = deps.codeEmbedder;
55
59
  const store = deps.exemplarStore;
56
60
  void embedder
57
- .embed(input.taskContext + "\n" + input.code, "document")
61
+ .embed(composeEmbedText(input.taskContext, input.code), "document")
58
62
  .then((r) => store.upsertEmbedding(id, r.vector))
59
63
  .catch(() => { });
60
64
  }
@@ -1 +1 @@
1
- {"version":3,"file":"capture-from-session.js","sourceRoot":"","sources":["../../../src/core/exemplars/capture-from-session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"capture-from-session.js","sourceRoot":"","sources":["../../../src/core/exemplars/capture-from-session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Unified-diff parsing helpers shared by the exemplar extractor (path a) and
3
+ * the code-signal producer. Pure string functions — no I/O.
4
+ */
5
+ export interface DiffHunk {
6
+ readonly file: string;
7
+ readonly hunkHeader: string;
8
+ readonly body: string;
9
+ }
10
+ /** Extract a git hunk header funcname: `@@ ... @@ funcname` */
11
+ export declare function parseFuncname(hunkHeader: string): string | null;
12
+ /** Detect likely language from file extension. */
13
+ export declare function detectLang(filePath: string): string | null;
14
+ /**
15
+ * Parse a unified diff into individual hunks. Returns (file, hunkHeader, body) triples.
16
+ */
17
+ export declare function parseHunks(diff: string): DiffHunk[];
18
+ /**
19
+ * Extract the added/changed lines from a hunk body (strip context and removed lines).
20
+ */
21
+ export declare function extractAddedLines(hunkBody: string): string;
22
+ /** Pick the hunk with the most non-blank added lines (most representative). */
23
+ export declare function selectLargestHunk(hunks: readonly DiffHunk[]): DiffHunk | null;
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Unified-diff parsing helpers shared by the exemplar extractor (path a) and
3
+ * the code-signal producer. Pure string functions — no I/O.
4
+ */
5
+ /** Extract a git hunk header funcname: `@@ ... @@ funcname` */
6
+ export function parseFuncname(hunkHeader) {
7
+ const m = hunkHeader.match(/@@ [^@]+ @@ (.+)/);
8
+ return m?.[1]?.trim() ?? null;
9
+ }
10
+ /** Detect likely language from file extension. */
11
+ export function detectLang(filePath) {
12
+ const ext = filePath.split(".").pop()?.toLowerCase() ?? "";
13
+ const map = {
14
+ ts: "ts", tsx: "ts", js: "js", jsx: "js", mjs: "js",
15
+ py: "py", go: "go", rb: "rb", rs: "rs", java: "java",
16
+ c: "c", cpp: "cpp", cs: "cs", swift: "swift", kt: "kt",
17
+ sh: "sh", bash: "sh", zsh: "sh",
18
+ };
19
+ return map[ext] ?? null;
20
+ }
21
+ /**
22
+ * Parse a unified diff into individual hunks. Returns (file, hunkHeader, body) triples.
23
+ */
24
+ export function parseHunks(diff) {
25
+ const result = [];
26
+ let currentFile = "";
27
+ let currentHeader = "";
28
+ let bodyLines = [];
29
+ for (const line of diff.split("\n")) {
30
+ if (line.startsWith("+++ b/")) {
31
+ currentFile = line.slice(6);
32
+ }
33
+ else if (line.startsWith("@@ ")) {
34
+ if (currentHeader && bodyLines.length > 0) {
35
+ result.push({ file: currentFile, hunkHeader: currentHeader, body: bodyLines.join("\n") });
36
+ }
37
+ currentHeader = line;
38
+ bodyLines = [];
39
+ }
40
+ else if (currentHeader && (line.startsWith("+") || line.startsWith("-") || line.startsWith(" "))) {
41
+ bodyLines.push(line);
42
+ }
43
+ }
44
+ if (currentHeader && bodyLines.length > 0) {
45
+ result.push({ file: currentFile, hunkHeader: currentHeader, body: bodyLines.join("\n") });
46
+ }
47
+ return result;
48
+ }
49
+ /**
50
+ * Extract the added/changed lines from a hunk body (strip context and removed lines).
51
+ */
52
+ export function extractAddedLines(hunkBody) {
53
+ return hunkBody
54
+ .split("\n")
55
+ .filter((l) => l.startsWith("+"))
56
+ .map((l) => l.slice(1))
57
+ .join("\n");
58
+ }
59
+ /** Pick the hunk with the most non-blank added lines (most representative). */
60
+ export function selectLargestHunk(hunks) {
61
+ let best;
62
+ let bestCount = 0;
63
+ for (const h of hunks) {
64
+ const added = extractAddedLines(h.body);
65
+ const count = added.split("\n").filter((l) => l.trim()).length;
66
+ if (count > bestCount) {
67
+ bestCount = count;
68
+ best = h;
69
+ }
70
+ }
71
+ return best ?? null;
72
+ }
73
+ //# sourceMappingURL=diff-parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff-parse.js","sourceRoot":"","sources":["../../../src/core/exemplars/diff-parse.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,+DAA+D;AAC/D,MAAM,UAAU,aAAa,CAAC,UAAkB;IAC9C,MAAM,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IAC/C,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC;AAChC,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IAC3D,MAAM,GAAG,GAA2B;QAClC,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI;QACnD,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM;QACpD,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI;QACtD,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI;KAChC,CAAC;IACF,OAAO,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,MAAM,MAAM,GAAe,EAAE,CAAC;IAC9B,IAAI,WAAW,GAAG,EAAE,CAAC;IACrB,IAAI,aAAa,GAAG,EAAE,CAAC;IACvB,IAAI,SAAS,GAAa,EAAE,CAAC;IAE7B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC9B,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC9B,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YAClC,IAAI,aAAa,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC1C,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC5F,CAAC;YACD,aAAa,GAAG,IAAI,CAAC;YACrB,SAAS,GAAG,EAAE,CAAC;QACjB,CAAC;aAAM,IAAI,aAAa,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACnG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IACD,IAAI,aAAa,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1C,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5F,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,OAAO,QAAQ;SACZ,KAAK,CAAC,IAAI,CAAC;SACX,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;SAChC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SACtB,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,iBAAiB,CAAC,KAA0B;IAC1D,IAAI,IAA0B,CAAC;IAC/B,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,KAAK,GAAG,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;QAC/D,IAAI,KAAK,GAAG,SAAS,EAAE,CAAC;YAAC,SAAS,GAAG,KAAK,CAAC;YAAC,IAAI,GAAG,CAAC,CAAC;QAAC,CAAC;IACzD,CAAC;IACD,OAAO,IAAI,IAAI,IAAI,CAAC;AACtB,CAAC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * exemplar embed-backfill — (re)embed code_exemplars rows that are missing a
3
+ * vector. The /api/signal capture path embeds exemplars fire-and-forget; a
4
+ * cold CodeRankEmbed model on first capture can drop the vector, leaving the
5
+ * exemplar permanently unretrievable (recall_code is vector-only). This is
6
+ * the repair: discover rows with no entry in code_exemplars_vec, embed
7
+ * taskContext + code via the CodeEmbedder, and upsert the vector.
8
+ *
9
+ * Mirrors the session embed-backfill (reembedCorpus): same embed-text shape
10
+ * as the live capture path (composeEmbedText, role "document"), the store's
11
+ * existing upsertEmbedding, and a single retry on transient
12
+ * embedder failures. Idempotent — rows that already have a vector are skipped
13
+ * (discovery is by absence in the vec table, so a second run finds nothing).
14
+ *
15
+ * Layering: depends on the CodeExemplarStore port for the upsert and on a
16
+ * read-only better-sqlite3 handle for discovery (the store has no
17
+ * "list rows missing a vector" method and adding one to the port for a
18
+ * one-shot operational tool isn't worth it — same direct-SQLite call the
19
+ * session backfill makes).
20
+ */
21
+ import type { CodeEmbedder } from "../../ports/code-embedder.js";
22
+ import type { CodeExemplarStore } from "../../ports/code-exemplar-store.js";
23
+ export interface ExemplarBackfillOptions {
24
+ readonly dbPath: string;
25
+ readonly embedder: CodeEmbedder;
26
+ readonly store: CodeExemplarStore;
27
+ readonly limit?: number;
28
+ readonly onProgress?: (i: number, total: number, id: string, status: string) => void;
29
+ }
30
+ export interface ExemplarBackfillReport {
31
+ readonly total: number;
32
+ readonly succeeded: number;
33
+ readonly failed: number;
34
+ readonly dbMissing: boolean;
35
+ }
36
+ export declare function backfillExemplarEmbeddings(opts: ExemplarBackfillOptions): Promise<ExemplarBackfillReport>;
@@ -0,0 +1,85 @@
1
+ /**
2
+ * exemplar embed-backfill — (re)embed code_exemplars rows that are missing a
3
+ * vector. The /api/signal capture path embeds exemplars fire-and-forget; a
4
+ * cold CodeRankEmbed model on first capture can drop the vector, leaving the
5
+ * exemplar permanently unretrievable (recall_code is vector-only). This is
6
+ * the repair: discover rows with no entry in code_exemplars_vec, embed
7
+ * taskContext + code via the CodeEmbedder, and upsert the vector.
8
+ *
9
+ * Mirrors the session embed-backfill (reembedCorpus): same embed-text shape
10
+ * as the live capture path (composeEmbedText, role "document"), the store's
11
+ * existing upsertEmbedding, and a single retry on transient
12
+ * embedder failures. Idempotent — rows that already have a vector are skipped
13
+ * (discovery is by absence in the vec table, so a second run finds nothing).
14
+ *
15
+ * Layering: depends on the CodeExemplarStore port for the upsert and on a
16
+ * read-only better-sqlite3 handle for discovery (the store has no
17
+ * "list rows missing a vector" method and adding one to the port for a
18
+ * one-shot operational tool isn't worth it — same direct-SQLite call the
19
+ * session backfill makes).
20
+ */
21
+ import { existsSync } from "node:fs";
22
+ import Database from "better-sqlite3";
23
+ import * as sqliteVec from "sqlite-vec";
24
+ import { LLMUnreachableError } from "../../ports/llm-client.js";
25
+ import { composeEmbedText } from "./embed-text.js";
26
+ export async function backfillExemplarEmbeddings(opts) {
27
+ if (!existsSync(opts.dbPath)) {
28
+ return { total: 0, succeeded: 0, failed: 0, dbMissing: true };
29
+ }
30
+ const db = new Database(opts.dbPath, { readonly: true });
31
+ sqliteVec.load(db);
32
+ let rows;
33
+ try {
34
+ const sql = "SELECT e.id, e.task_context, e.code FROM code_exemplars e " +
35
+ "WHERE e.id NOT IN (SELECT exemplar_id FROM code_exemplars_vec) " +
36
+ "ORDER BY e.created_at" +
37
+ (opts.limit ? ` LIMIT ${Math.trunc(opts.limit)}` : "");
38
+ rows = db.prepare(sql).all();
39
+ }
40
+ finally {
41
+ db.close();
42
+ }
43
+ const total = rows.length;
44
+ let succeeded = 0;
45
+ let failed = 0;
46
+ for (let i = 0; i < rows.length; i++) {
47
+ const row = rows[i];
48
+ const idx = i + 1;
49
+ const text = composeEmbedText(row.task_context, row.code);
50
+ let vector;
51
+ let lastErr;
52
+ for (let attempt = 0; attempt < 2; attempt++) {
53
+ try {
54
+ const out = await opts.embedder.embed(text, "document");
55
+ vector = out.vector;
56
+ lastErr = undefined;
57
+ break;
58
+ }
59
+ catch (e) {
60
+ lastErr = e;
61
+ if (!(e instanceof LLMUnreachableError))
62
+ throw e;
63
+ if (attempt === 0)
64
+ await new Promise((r) => setTimeout(r, 200));
65
+ }
66
+ }
67
+ if (vector === undefined) {
68
+ failed += 1;
69
+ opts.onProgress?.(idx, total, row.id, `FAIL (embedder): ${lastErr?.message ?? "unknown"}`);
70
+ continue;
71
+ }
72
+ try {
73
+ await opts.store.upsertEmbedding(row.id, vector);
74
+ }
75
+ catch (e) {
76
+ failed += 1;
77
+ opts.onProgress?.(idx, total, row.id, `FAIL (db): ${e.message}`);
78
+ continue;
79
+ }
80
+ succeeded += 1;
81
+ opts.onProgress?.(idx, total, row.id, "OK");
82
+ }
83
+ return { total, succeeded, failed, dbMissing: false };
84
+ }
85
+ //# sourceMappingURL=embed-backfill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embed-backfill.js","sourceRoot":"","sources":["../../../src/core/exemplars/embed-backfill.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,KAAK,SAAS,MAAM,YAAY,CAAC;AAGxC,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAuBnD,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,IAA6B;IAE7B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IAChE,CAAC;IAED,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEnB,IAAI,IAAkB,CAAC;IACvB,IAAI,CAAC;QACH,MAAM,GAAG,GACP,4DAA4D;YAC5D,iEAAiE;YACjE,uBAAuB;YACvB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACzD,IAAI,GAAG,EAAE,CAAC,OAAO,CAAiB,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;IAC/C,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;IAC1B,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;QACrB,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAClB,MAAM,IAAI,GAAG,gBAAgB,CAAC,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QAE1D,IAAI,MAAgC,CAAC;QACrC,IAAI,OAAgB,CAAC;QACrB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;YAC7C,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;gBACxD,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;gBACpB,OAAO,GAAG,SAAS,CAAC;gBACpB,MAAM;YACR,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,GAAG,CAAC,CAAC;gBACZ,IAAI,CAAC,CAAC,CAAC,YAAY,mBAAmB,CAAC;oBAAE,MAAM,CAAC,CAAC;gBACjD,IAAI,OAAO,KAAK,CAAC;oBAAE,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;YAClE,CAAC;QACH,CAAC;QAED,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,MAAM,IAAI,CAAC,CAAC;YACZ,IAAI,CAAC,UAAU,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,EAAE,oBAAqB,OAAiB,EAAE,OAAO,IAAI,SAAS,EAAE,CAAC,CAAC;YACtG,SAAS;QACX,CAAC;QAED,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QACnD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,IAAI,CAAC,CAAC;YACZ,IAAI,CAAC,UAAU,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,EAAE,cAAe,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;YAC5E,SAAS;QACX,CAAC;QAED,SAAS,IAAI,CAAC,CAAC;QACf,IAAI,CAAC,UAAU,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IAC9C,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;AACxD,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * The embed payload for a code exemplar is `taskContext + "\n" + code`. The
3
+ * code embedder (CodeRankEmbed) has a ~512-token context window; a real commit
4
+ * diff easily exceeds it, at which point Ollama returns HTTP 500 ("the input
5
+ * length exceeds the context length") and the vector is silently dropped —
6
+ * leaving the exemplar unretrievable (recall_code is vector-only).
7
+ *
8
+ * composeEmbedText is the single place both the live capture path and the
9
+ * backfill build that payload, capping it so the embed always fits. 2000 chars
10
+ * sits comfortably under the window even for token-dense code (empirically the
11
+ * window tolerates ~4000 chars; 2000 leaves margin for the model's prompt
12
+ * prefix and tokenizer variance).
13
+ */
14
+ export declare const EMBED_TEXT_CAP = 2000;
15
+ export declare function composeEmbedText(taskContext: string, code: string): string;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The embed payload for a code exemplar is `taskContext + "\n" + code`. The
3
+ * code embedder (CodeRankEmbed) has a ~512-token context window; a real commit
4
+ * diff easily exceeds it, at which point Ollama returns HTTP 500 ("the input
5
+ * length exceeds the context length") and the vector is silently dropped —
6
+ * leaving the exemplar unretrievable (recall_code is vector-only).
7
+ *
8
+ * composeEmbedText is the single place both the live capture path and the
9
+ * backfill build that payload, capping it so the embed always fits. 2000 chars
10
+ * sits comfortably under the window even for token-dense code (empirically the
11
+ * window tolerates ~4000 chars; 2000 leaves margin for the model's prompt
12
+ * prefix and tokenizer variance).
13
+ */
14
+ export const EMBED_TEXT_CAP = 2000;
15
+ export function composeEmbedText(taskContext, code) {
16
+ return (taskContext + "\n" + code).slice(0, EMBED_TEXT_CAP);
17
+ }
18
+ //# sourceMappingURL=embed-text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embed-text.js","sourceRoot":"","sources":["../../../src/core/exemplars/embed-text.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,CAAC;AAEnC,MAAM,UAAU,gBAAgB,CAAC,WAAmB,EAAE,IAAY;IAChE,OAAO,CAAC,WAAW,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;AAC9D,CAAC"}