@inflexa-ai/harness 0.45.1 → 0.46.2

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 (790) hide show
  1. package/README.md +6 -3
  2. package/dist/agents/conversation-agent.d.ts +9 -3
  3. package/dist/agents/conversation-agent.js +34 -33
  4. package/dist/agents/report-session-agent.d.ts +15 -15
  5. package/dist/agents/report-session-agent.js +23 -15
  6. package/dist/agents/sandbox/index.d.ts +1 -1
  7. package/dist/agents/sandbox/index.js +1 -1
  8. package/dist/agents/sandbox/shared.d.ts +12 -14
  9. package/dist/agents/sandbox/shared.js +18 -12
  10. package/dist/agents/sandbox/types.d.ts +4 -4
  11. package/dist/agents/sandbox/validate-skills.d.ts +2 -2
  12. package/dist/agents/sandbox/validate-skills.js +3 -1
  13. package/dist/agents/sandbox-catalog.d.ts +2 -2
  14. package/dist/agents/sandbox-catalog.js +3 -3
  15. package/dist/agents/system-prompt.d.ts +2 -2
  16. package/dist/app/chat-turn-workflow.d.ts +114 -0
  17. package/dist/app/chat-turn-workflow.js +306 -0
  18. package/dist/app/chat-turn.d.ts +85 -57
  19. package/dist/app/chat-turn.js +123 -100
  20. package/dist/app/data-profile-orientation.js +10 -8
  21. package/dist/app/data-profile-view.d.ts +4 -4
  22. package/dist/app/data-profile-view.js +9 -8
  23. package/dist/app/in-process-turn.d.ts +42 -0
  24. package/dist/app/in-process-turn.js +139 -0
  25. package/dist/app/message-assembly.d.ts +10 -4
  26. package/dist/app/message-assembly.js +13 -8
  27. package/dist/app/report-session-runtime.d.ts +4 -4
  28. package/dist/app/report-session-runtime.js +36 -21
  29. package/dist/app/spawn-report-session.d.ts +33 -28
  30. package/dist/app/spawn-report-session.js +25 -40
  31. package/dist/app/synthesize-run.d.ts +22 -16
  32. package/dist/app/synthesize-run.js +41 -35
  33. package/dist/app/work.d.ts +96 -0
  34. package/dist/app/work.js +147 -0
  35. package/dist/auth/local-auth-context.d.ts +1 -3
  36. package/dist/auth/local-auth-context.js +1 -3
  37. package/dist/auth/local-run-authorizer.d.ts +1 -1
  38. package/dist/auth/local-run-authorizer.js +5 -3
  39. package/dist/auth/types.d.ts +26 -26
  40. package/dist/billing/cached-resolver.d.ts +4 -4
  41. package/dist/billing/run-charge.d.ts +5 -8
  42. package/dist/billing/run-charge.js +2 -2
  43. package/dist/billing/usage-recorder.d.ts +9 -9
  44. package/dist/citations/aggregate.js +1 -1
  45. package/dist/citations/clients/arxiv.d.ts +2 -2
  46. package/dist/citations/clients/arxiv.js +12 -4
  47. package/dist/citations/clients/common.js +4 -2
  48. package/dist/citations/clients/crossref.d.ts +2 -2
  49. package/dist/citations/clients/crossref.js +37 -37
  50. package/dist/citations/clients/doi-registry.js +15 -16
  51. package/dist/citations/clients/pubmed.d.ts +2 -2
  52. package/dist/citations/clients/pubmed.js +20 -13
  53. package/dist/citations/clients/semantic-scholar.d.ts +2 -2
  54. package/dist/citations/clients/semantic-scholar.js +9 -9
  55. package/dist/citations/compare.js +2 -2
  56. package/dist/citations/match.d.ts +2 -2
  57. package/dist/citations/match.js +12 -7
  58. package/dist/citations/normalize.js +35 -26
  59. package/dist/citations/plan.js +6 -2
  60. package/dist/citations/resolve.d.ts +6 -6
  61. package/dist/citations/resolve.js +34 -25
  62. package/dist/citations/types.d.ts +77 -77
  63. package/dist/config/environment-stores.d.ts +6 -6
  64. package/dist/config/resource-limits.js +1 -3
  65. package/dist/contracts/analogy-report.d.ts +7 -7
  66. package/dist/contracts/analogy-report.js +2 -2
  67. package/dist/contracts/chat-events.d.ts +38 -24
  68. package/dist/contracts/chat-frame.d.ts +15 -5
  69. package/dist/contracts/chat-frame.js +64 -41
  70. package/dist/contracts/chat-parts.d.ts +130 -67
  71. package/dist/contracts/chat-parts.js +1 -0
  72. package/dist/contracts/content-url.js +16 -2
  73. package/dist/contracts/data-profile.d.ts +38 -38
  74. package/dist/contracts/index.d.ts +2 -2
  75. package/dist/contracts/index.js +1 -1
  76. package/dist/contracts/message.d.ts +6 -6
  77. package/dist/contracts/organ-system.d.ts +11 -11
  78. package/dist/contracts/part-registry.d.ts +5 -4
  79. package/dist/contracts/part-registry.js +5 -0
  80. package/dist/contracts/profile-vocabulary.d.ts +11 -10
  81. package/dist/contracts/profile-vocabulary.js +10 -3
  82. package/dist/contracts/report-blocks.d.ts +329 -329
  83. package/dist/contracts/report-reference.d.ts +105 -81
  84. package/dist/contracts/report-reference.js +30 -13
  85. package/dist/contracts/schemas/chat-events.d.ts +30 -16
  86. package/dist/contracts/schemas/chat-events.js +15 -6
  87. package/dist/contracts/schemas/chat-parts.d.ts +175 -102
  88. package/dist/contracts/schemas/chat-parts.js +33 -7
  89. package/dist/contracts/severity.d.ts +1 -1
  90. package/dist/contracts/structure-source.d.ts +3 -3
  91. package/dist/contracts/structure-source.js +6 -2
  92. package/dist/contracts/subagent-activity.d.ts +2 -2
  93. package/dist/contracts/subagent-activity.js +5 -3
  94. package/dist/contracts/usage.d.ts +2 -2
  95. package/dist/data/safety-panel-schema.d.ts +25 -25
  96. package/dist/data/safety-panel-schema.js +13 -4
  97. package/dist/execution/artifact-metadata.d.ts +23 -15
  98. package/dist/execution/artifact-metadata.js +33 -10
  99. package/dist/execution/artifact-record.d.ts +2 -2
  100. package/dist/execution/artifact-registration.d.ts +5 -5
  101. package/dist/execution/artifact-registry.d.ts +8 -8
  102. package/dist/execution/dbos-run-launcher.d.ts +24 -4
  103. package/dist/execution/dbos-run-launcher.js +58 -4
  104. package/dist/execution/dbos-workflow-purger.d.ts +5 -6
  105. package/dist/execution/dbos-workflow-purger.js +8 -7
  106. package/dist/execution/input-signature.d.ts +2 -2
  107. package/dist/execution/post-step-pipeline.d.ts +9 -9
  108. package/dist/execution/post-step-pipeline.js +1 -1
  109. package/dist/execution/post-step.js +2 -2
  110. package/dist/execution/reconcile-manifest.d.ts +4 -4
  111. package/dist/execution/reconcile-manifest.js +3 -2
  112. package/dist/execution/run-authorizer.d.ts +46 -37
  113. package/dist/execution/run-authorizer.js +8 -8
  114. package/dist/execution/run-canceler.d.ts +7 -7
  115. package/dist/execution/run-canceler.js +14 -7
  116. package/dist/execution/run-end-record.d.ts +2 -3
  117. package/dist/execution/run-event-parts.d.ts +0 -8
  118. package/dist/execution/run-event-parts.js +29 -24
  119. package/dist/execution/run-event-stream.d.ts +8 -8
  120. package/dist/execution/run-event-stream.js +3 -4
  121. package/dist/execution/run-launcher.d.ts +4 -4
  122. package/dist/execution/run-synthesis.d.ts +49 -48
  123. package/dist/execution/run-synthesis.js +96 -255
  124. package/dist/execution/staged-input.d.ts +2 -2
  125. package/dist/execution/step-summary.d.ts +6 -6
  126. package/dist/execution/step-summary.js +4 -8
  127. package/dist/execution/topo-sort.js +4 -3
  128. package/dist/execution/workflow-purger.d.ts +2 -2
  129. package/dist/index.d.ts +17 -20
  130. package/dist/index.js +25 -36
  131. package/dist/input-sanitization.js +9 -2
  132. package/dist/input-scan/clustering.d.ts +6 -6
  133. package/dist/input-scan/clustering.js +11 -5
  134. package/dist/input-scan/companions.js +3 -2
  135. package/dist/input-scan/detect-sets.d.ts +2 -2
  136. package/dist/input-scan/detect-sets.js +25 -21
  137. package/dist/input-scan/enrich.d.ts +6 -6
  138. package/dist/input-scan/enrich.js +29 -12
  139. package/dist/input-scan/formats.d.ts +2 -2
  140. package/dist/input-scan/formats.js +8 -2
  141. package/dist/input-scan/markers.d.ts +2 -2
  142. package/dist/input-scan/markers.js +14 -5
  143. package/dist/input-scan/menu.d.ts +10 -10
  144. package/dist/input-scan/menu.js +0 -0
  145. package/dist/input-scan/quarantine.d.ts +2 -2
  146. package/dist/input-scan/quarantine.js +23 -18
  147. package/dist/input-scan/readout-budget.d.ts +2 -2
  148. package/dist/input-scan/readout-budget.js +1 -1
  149. package/dist/input-scan/readout.d.ts +2 -2
  150. package/dist/input-scan/readout.js +47 -34
  151. package/dist/input-scan/scan.d.ts +2 -2
  152. package/dist/input-scan/scan.js +7 -5
  153. package/dist/input-scan/set-types.d.ts +28 -28
  154. package/dist/input-scan/shapes.d.ts +4 -4
  155. package/dist/input-scan/shapes.js +0 -0
  156. package/dist/input-scan/templates.d.ts +10 -10
  157. package/dist/input-scan/templates.js +30 -22
  158. package/dist/input-scan/tokens.d.ts +6 -4
  159. package/dist/input-scan/tokens.js +100 -38
  160. package/dist/input-scan/types.d.ts +22 -22
  161. package/dist/lib/async-utils.d.ts +3 -7
  162. package/dist/lib/async-utils.js +5 -9
  163. package/dist/lib/cache.js +1 -1
  164. package/dist/lib/chrome.d.ts +46 -6
  165. package/dist/lib/console-logger.js +2 -2
  166. package/dist/lib/db-result.d.ts +22 -6
  167. package/dist/lib/db-result.js +9 -13
  168. package/dist/lib/eyes.d.ts +4 -4
  169. package/dist/lib/eyes.js +1 -1
  170. package/dist/lib/fs-helpers.js +18 -6
  171. package/dist/lib/fs-result.d.ts +1 -0
  172. package/dist/lib/fs-result.js +5 -6
  173. package/dist/lib/hooks.d.ts +32 -7
  174. package/dist/lib/hooks.js +22 -3
  175. package/dist/lib/host-concurrency.js +3 -2
  176. package/dist/lib/logger.d.ts +2 -2
  177. package/dist/lib/logger.js +2 -1
  178. package/dist/lib/metrics.d.ts +1 -1
  179. package/dist/lib/null-proto.d.ts +6 -0
  180. package/dist/lib/null-proto.js +17 -0
  181. package/dist/lib/otel-spans.d.ts +1 -1
  182. package/dist/lib/otel-spans.js +9 -5
  183. package/dist/lib/otel.d.ts +4 -2
  184. package/dist/lib/otel.js +10 -2
  185. package/dist/lib/page-capture.d.ts +8 -8
  186. package/dist/lib/page-capture.js +9 -4
  187. package/dist/lib/parse-json.d.ts +5 -0
  188. package/dist/lib/parse-json.js +12 -0
  189. package/dist/lib/present.d.ts +12 -0
  190. package/dist/lib/present.js +39 -0
  191. package/dist/lib/rate-limit.d.ts +4 -4
  192. package/dist/lib/rate-limit.js +12 -13
  193. package/dist/lib/regulatory-corpus/fetch-fda-guidance.d.ts +4 -4
  194. package/dist/lib/regulatory-corpus/fetch-fda-guidance.js +4 -10
  195. package/dist/lib/regulatory-corpus/fetch-ich.d.ts +4 -4
  196. package/dist/lib/regulatory-corpus/fetch-ich.js +18 -14
  197. package/dist/lib/regulatory-corpus/normalize-whitespace.d.ts +6 -0
  198. package/dist/lib/regulatory-corpus/normalize-whitespace.js +41 -0
  199. package/dist/lib/regulatory-corpus.d.ts +10 -10
  200. package/dist/lib/regulatory-corpus.js +3 -1
  201. package/dist/lib/result.d.ts +10 -11
  202. package/dist/lib/result.js +15 -13
  203. package/dist/lib/storage.d.ts +2 -2
  204. package/dist/lib/test/async-iterable.d.ts +9 -0
  205. package/dist/lib/test/async-iterable.js +28 -0
  206. package/dist/lib/test/request-url.d.ts +5 -0
  207. package/dist/lib/test/request-url.js +7 -0
  208. package/dist/lib/test/result-assert.d.ts +12 -0
  209. package/dist/lib/test/result-assert.js +17 -0
  210. package/dist/lib/test/text-shapes.d.ts +24 -0
  211. package/dist/lib/test/text-shapes.js +63 -0
  212. package/dist/lib/text.d.ts +22 -0
  213. package/dist/lib/text.js +68 -0
  214. package/dist/lib/thrown.d.ts +18 -0
  215. package/dist/lib/thrown.js +30 -0
  216. package/dist/lib/unknown-array.d.ts +6 -0
  217. package/dist/lib/unknown-array.js +8 -0
  218. package/dist/lib/unknown-containers.d.ts +14 -0
  219. package/dist/lib/unknown-containers.js +17 -0
  220. package/dist/lib/unknown-text.d.ts +8 -0
  221. package/dist/lib/unknown-text.js +28 -0
  222. package/dist/lib/zod-issue-shape.d.ts +1 -1
  223. package/dist/lib/zod-issue-shape.js +31 -31
  224. package/dist/lib/zod-issues.d.ts +3 -3
  225. package/dist/lib/zod-issues.js +30 -17
  226. package/dist/literature/sources/arxiv.d.ts +6 -6
  227. package/dist/literature/sources/arxiv.js +92 -35
  228. package/dist/literature/sources/http.d.ts +2 -2
  229. package/dist/literature/sources/http.js +16 -15
  230. package/dist/literature/sources/pubmed.d.ts +16 -16
  231. package/dist/literature/sources/pubmed.js +96 -61
  232. package/dist/literature/sources/semantic-scholar.d.ts +8 -8
  233. package/dist/literature/sources/semantic-scholar.js +22 -13
  234. package/dist/loop/accounting.d.ts +63 -0
  235. package/dist/loop/accounting.js +141 -0
  236. package/dist/loop/call-policy.d.ts +73 -0
  237. package/dist/loop/call-policy.js +109 -0
  238. package/dist/loop/chat-stream.d.ts +62 -0
  239. package/dist/loop/chat-stream.js +237 -0
  240. package/dist/loop/compaction.d.ts +9 -9
  241. package/dist/loop/compaction.js +1 -1
  242. package/dist/loop/metrics.d.ts +12 -15
  243. package/dist/loop/metrics.js +14 -26
  244. package/dist/loop/run-loop.d.ts +233 -0
  245. package/dist/loop/run-loop.js +770 -0
  246. package/dist/loop/sub-agent.d.ts +61 -0
  247. package/dist/loop/sub-agent.js +160 -0
  248. package/dist/loop/tool-adapter.d.ts +98 -0
  249. package/dist/loop/tool-adapter.js +364 -0
  250. package/dist/loop/tool-detail.d.ts +1 -1
  251. package/dist/loop/tool-detail.js +6 -5
  252. package/dist/loop/tool-outcome.d.ts +1 -1
  253. package/dist/loop/tool-output.d.ts +4 -4
  254. package/dist/loop/tool-output.js +2 -2
  255. package/dist/loop/turn-credentials.d.ts +39 -0
  256. package/dist/loop/turn-credentials.js +90 -0
  257. package/dist/loop/types.d.ts +29 -38
  258. package/dist/loop/types.js +2 -7
  259. package/dist/memory/ai-sdk-message-storage.d.ts +5 -5
  260. package/dist/memory/ai-sdk-message-storage.js +13 -11
  261. package/dist/memory/card-builders.d.ts +14 -14
  262. package/dist/memory/card-builders.js +19 -15
  263. package/dist/memory/conversation-display-recorder.d.ts +22 -4
  264. package/dist/memory/conversation-display-recorder.js +43 -24
  265. package/dist/memory/conversation-display-replay.js +3 -2
  266. package/dist/memory/conversation-display-storage.d.ts +15 -7
  267. package/dist/memory/conversation-display-storage.js +141 -36
  268. package/dist/memory/conversation-view.d.ts +4 -4
  269. package/dist/memory/conversation-view.js +5 -4
  270. package/dist/memory/count-tokens.js +10 -8
  271. package/dist/memory/derive-thread-title.d.ts +0 -13
  272. package/dist/memory/derive-thread-title.js +2 -1
  273. package/dist/memory/message-backfill.d.ts +12 -5
  274. package/dist/memory/message-backfill.js +5 -3
  275. package/dist/memory/thread-history.d.ts +36 -21
  276. package/dist/memory/thread-history.js +78 -54
  277. package/dist/memory/thread-store.d.ts +26 -17
  278. package/dist/memory/thread-store.js +15 -9
  279. package/dist/memory/tool-call-integrity.d.ts +2 -2
  280. package/dist/memory/tool-call-integrity.js +4 -3
  281. package/dist/memory/working-memory.d.ts +16 -12
  282. package/dist/memory/working-memory.js +72 -61
  283. package/dist/prompts/briefing.d.ts +12 -12
  284. package/dist/prompts/briefing.js +1 -1
  285. package/dist/prompts/synthesis-agent.d.ts +1 -1
  286. package/dist/prompts/synthesis-agent.js +6 -14
  287. package/dist/provenance/collector.d.ts +6 -6
  288. package/dist/provenance/collector.js +15 -8
  289. package/dist/provenance/exec-frame.d.ts +2 -2
  290. package/dist/provenance/exec-frame.js +6 -1
  291. package/dist/provenance/seam.d.ts +1 -4
  292. package/dist/provenance/types.d.ts +6 -6
  293. package/dist/providers/ai-sdk.d.ts +113 -62
  294. package/dist/providers/ai-sdk.js +283 -518
  295. package/dist/providers/embedding.d.ts +2 -2
  296. package/dist/providers/embedding.js +1 -1
  297. package/dist/providers/errors.d.ts +22 -2
  298. package/dist/providers/errors.js +98 -50
  299. package/dist/providers/prompt-cache.d.ts +8 -8
  300. package/dist/providers/prompt-cache.js +13 -11
  301. package/dist/providers/reasoning.d.ts +2 -2
  302. package/dist/providers/reasoning.js +2 -2
  303. package/dist/providers/request-headers.js +12 -3
  304. package/dist/providers/types.d.ts +55 -94
  305. package/dist/reference-data/catalog.d.ts +2 -15
  306. package/dist/reference-data/catalog.js +25 -8
  307. package/dist/reference-data/receipt.d.ts +2 -2
  308. package/dist/report-model/assert-rules.js +1 -1
  309. package/dist/report-model/authoring-grammar.d.ts +211 -233
  310. package/dist/report-model/block-walk.d.ts +10 -10
  311. package/dist/report-model/block-walk.js +2 -0
  312. package/dist/report-model/draft-finish.d.ts +8 -8
  313. package/dist/report-model/draft-finish.js +1 -1
  314. package/dist/report-model/draft-hash.js +8 -7
  315. package/dist/report-model/draft-operations.d.ts +22 -10
  316. package/dist/report-model/draft-operations.js +48 -30
  317. package/dist/report-model/draft-read.d.ts +19 -7
  318. package/dist/report-model/draft-read.js +16 -6
  319. package/dist/report-model/draft.d.ts +844 -2
  320. package/dist/report-model/draft.js +3 -1
  321. package/dist/report-model/fixture-resolver.js +39 -16
  322. package/dist/report-model/pin-snapshot.d.ts +2 -2
  323. package/dist/report-model/pin-snapshot.js +15 -15
  324. package/dist/report-model/production-resolver.d.ts +18 -18
  325. package/dist/report-model/production-resolver.js +50 -42
  326. package/dist/report-model/reference-resolver.d.ts +26 -10
  327. package/dist/report-model/reference-resolver.js +68 -5
  328. package/dist/report-model/reference-stamp.js +30 -38
  329. package/dist/report-model/structural-validation.js +12 -4
  330. package/dist/report-model/validate.d.ts +7 -7
  331. package/dist/report-model/validate.js +6 -6
  332. package/dist/report-render/assets.d.ts +2 -2
  333. package/dist/report-render/assets.js +27 -3
  334. package/dist/report-render/chart-export.d.ts +10 -2
  335. package/dist/report-render/chart-export.js +37 -11
  336. package/dist/report-render/chart-presets.d.ts +8 -8
  337. package/dist/report-render/chart-presets.js +3 -3
  338. package/dist/report-render/chart-renderers.d.ts +23 -16
  339. package/dist/report-render/chart-renderers.js +74 -53
  340. package/dist/report-render/chart-toolbox.d.ts +2 -2
  341. package/dist/report-render/chart-toolbox.js +7 -6
  342. package/dist/report-render/chart.d.ts +15 -16
  343. package/dist/report-render/chart.js +369 -252
  344. package/dist/report-render/design.d.ts +36 -297
  345. package/dist/report-render/design.js +0 -12
  346. package/dist/report-render/figures/common.d.ts +12 -12
  347. package/dist/report-render/figures/common.js +42 -31
  348. package/dist/report-render/figures/dendrogram.d.ts +3 -3
  349. package/dist/report-render/figures/dendrogram.js +10 -10
  350. package/dist/report-render/figures/dense.js +15 -8
  351. package/dist/report-render/figures/dotplot.js +46 -33
  352. package/dist/report-render/figures/embedding.js +52 -43
  353. package/dist/report-render/figures/equal-units.d.ts +10 -10
  354. package/dist/report-render/figures/equal-units.js +27 -27
  355. package/dist/report-render/figures/forest.js +9 -7
  356. package/dist/report-render/figures/gsea.js +21 -11
  357. package/dist/report-render/figures/heatmap.js +13 -9
  358. package/dist/report-render/figures/index.d.ts +10 -10
  359. package/dist/report-render/figures/index.js +4 -2
  360. package/dist/report-render/figures/km.js +10 -9
  361. package/dist/report-render/figures/label-room.d.ts +12 -12
  362. package/dist/report-render/figures/label-room.js +7 -2
  363. package/dist/report-render/figures/locuszoom.d.ts +2 -2
  364. package/dist/report-render/figures/locuszoom.js +59 -31
  365. package/dist/report-render/figures/lollipop.js +3 -2
  366. package/dist/report-render/figures/ma.js +8 -4
  367. package/dist/report-render/figures/manhattan.d.ts +1 -2
  368. package/dist/report-render/figures/manhattan.js +52 -34
  369. package/dist/report-render/figures/oncoprint.js +4 -5
  370. package/dist/report-render/figures/pca.js +25 -11
  371. package/dist/report-render/figures/qq.js +20 -9
  372. package/dist/report-render/figures/roc.js +1 -1
  373. package/dist/report-render/figures/sankey.d.ts +2 -2
  374. package/dist/report-render/figures/sankey.js +11 -10
  375. package/dist/report-render/figures/upset.d.ts +6 -6
  376. package/dist/report-render/figures/upset.js +7 -4
  377. package/dist/report-render/figures/volcano.js +12 -10
  378. package/dist/report-render/hybrid-svg.d.ts +4 -4
  379. package/dist/report-render/hybrid-svg.js +7 -5
  380. package/dist/report-render/number-format.d.ts +4 -4
  381. package/dist/report-render/number-format.js +62 -27
  382. package/dist/report-render/page.js +2 -1
  383. package/dist/report-render/provenance-data.d.ts +2 -2
  384. package/dist/report-render/references.d.ts +4 -4
  385. package/dist/report-render/render.d.ts +2 -2
  386. package/dist/report-render/render.js +10 -11
  387. package/dist/report-render/script-json.js +1 -1
  388. package/dist/report-render/table-data.d.ts +6 -6
  389. package/dist/report-render/test/options.d.ts +49 -0
  390. package/dist/report-render/test/options.js +143 -0
  391. package/dist/report-render/test/page-function.d.ts +19 -0
  392. package/dist/report-render/test/page-function.js +33 -0
  393. package/dist/report-render/types.d.ts +10 -10
  394. package/dist/report-render/value-bridge.d.ts +4 -4
  395. package/dist/report-render/value-bridge.js +27 -14
  396. package/dist/report-render/views/chart-view.d.ts +2 -2
  397. package/dist/report-render/views/chart-view.js +2 -2
  398. package/dist/report-render/views/lineage.d.ts +6 -6
  399. package/dist/report-render/views/lineage.js +2 -0
  400. package/dist/report-render/views/page-view.d.ts +2 -2
  401. package/dist/report-render/views/page-view.js +1 -0
  402. package/dist/report-render/views/prose.js +25 -8
  403. package/dist/report-render/views/references-view.js +12 -1
  404. package/dist/report-render/views/values.js +1 -1
  405. package/dist/runtime/assemble.d.ts +53 -26
  406. package/dist/runtime/assemble.js +103 -56
  407. package/dist/runtime/boot.d.ts +8 -7
  408. package/dist/runtime/boot.js +1 -1
  409. package/dist/runtime/connection-budget.d.ts +6 -6
  410. package/dist/runtime/connection-budget.js +1 -1
  411. package/dist/runtime/dbos.d.ts +29 -19
  412. package/dist/runtime/dbos.js +35 -20
  413. package/dist/runtime/result-serialization.js +18 -5
  414. package/dist/runtime/shutdown.d.ts +2 -2
  415. package/dist/sandbox/client.d.ts +7 -3
  416. package/dist/sandbox/cpu-files.d.ts +2 -2
  417. package/dist/sandbox/cpu-files.js +21 -4
  418. package/dist/sandbox/create-sandbox.d.ts +7 -8
  419. package/dist/sandbox/create-sandbox.js +6 -12
  420. package/dist/sandbox/docker-client.d.ts +48 -3
  421. package/dist/sandbox/docker-client.js +10 -6
  422. package/dist/sandbox/estimate-data-profile-resources.js +2 -7
  423. package/dist/sandbox/exec-outcome.d.ts +2 -2
  424. package/dist/sandbox/exec-outcome.js +1 -1
  425. package/dist/sandbox/exec.d.ts +10 -6
  426. package/dist/sandbox/exec.js +27 -12
  427. package/dist/sandbox/execution-id.js +14 -6
  428. package/dist/sandbox/farm.d.ts +2 -2
  429. package/dist/sandbox/farm.js +22 -27
  430. package/dist/sandbox/identity.d.ts +7 -0
  431. package/dist/sandbox/identity.js +14 -3
  432. package/dist/sandbox/image-packages.js +15 -27
  433. package/dist/sandbox/k8s-client.d.ts +35 -8
  434. package/dist/sandbox/k8s-client.js +6 -5
  435. package/dist/sandbox/labels.js +1 -0
  436. package/dist/sandbox/liveness.js +3 -1
  437. package/dist/sandbox/mount-plan.d.ts +10 -10
  438. package/dist/sandbox/mount-plan.js +13 -14
  439. package/dist/sandbox/notification-sweep.d.ts +4 -4
  440. package/dist/sandbox/notification-sweep.js +4 -7
  441. package/dist/sandbox/package-identity.d.ts +6 -13
  442. package/dist/sandbox/package-identity.js +46 -28
  443. package/dist/sandbox/reaper.d.ts +10 -10
  444. package/dist/sandbox/reaper.js +4 -6
  445. package/dist/sandbox/sandbox-error.d.ts +2 -9
  446. package/dist/sandbox/sandbox-error.js +21 -8
  447. package/dist/sandbox/sandbox-step-translate.d.ts +8 -5
  448. package/dist/sandbox/sandbox-step-translate.js +22 -8
  449. package/dist/sandbox/step-sandbox.d.ts +47 -0
  450. package/dist/sandbox/step-sandbox.js +53 -0
  451. package/dist/sandbox/types.d.ts +18 -19
  452. package/dist/sandbox/types.js +1 -1
  453. package/dist/schemas/artifact-manifest.d.ts +4 -4
  454. package/dist/schemas/data-profile-schemas.d.ts +343 -298
  455. package/dist/schemas/file-metadata.js +2 -4
  456. package/dist/schemas/plan-schemas.d.ts +31 -31
  457. package/dist/schemas/run-synthesis.d.ts +95 -26
  458. package/dist/schemas/run-synthesis.js +3 -1
  459. package/dist/schemas/validate-plan.d.ts +4 -4
  460. package/dist/schemas/validate-plan.js +17 -5
  461. package/dist/schemas/workflow-state.d.ts +19 -19
  462. package/dist/schemas/workflow-state.js +2 -2
  463. package/dist/state/active-turns.d.ts +36 -0
  464. package/dist/state/active-turns.js +67 -0
  465. package/dist/state/analyses-metrics.d.ts +8 -8
  466. package/dist/state/analyses-metrics.js +4 -4
  467. package/dist/state/analyses.d.ts +0 -14
  468. package/dist/state/analyses.js +0 -32
  469. package/dist/state/artifacts.d.ts +32 -19
  470. package/dist/state/artifacts.js +28 -5
  471. package/dist/state/data-profile.d.ts +2 -2
  472. package/dist/state/db.d.ts +12 -2
  473. package/dist/state/db.js +5 -0
  474. package/dist/state/edit-intents.d.ts +4 -0
  475. package/dist/state/edit-intents.js +71 -0
  476. package/dist/state/index.d.ts +4 -4
  477. package/dist/state/index.js +2 -2
  478. package/dist/state/init.d.ts +2 -1
  479. package/dist/state/init.js +5 -2
  480. package/dist/state/migrations/20260927120000_baseline.js +3 -1
  481. package/dist/state/migrations/20261026120000_add_the_edit_intents.d.ts +7 -0
  482. package/dist/state/migrations/20261026120000_add_the_edit_intents.js +21 -0
  483. package/dist/state/migrations/20261027120000_record_the_applied_memory_edits.d.ts +7 -0
  484. package/dist/state/migrations/20261027120000_record_the_applied_memory_edits.js +16 -0
  485. package/dist/state/migrations/20261027120100_store_the_authoring_results.d.ts +8 -0
  486. package/dist/state/migrations/20261027120100_store_the_authoring_results.js +20 -0
  487. package/dist/state/migrations/20261027120200_key_the_groups_of_a_turn.d.ts +7 -0
  488. package/dist/state/migrations/20261027120200_key_the_groups_of_a_turn.js +12 -0
  489. package/dist/state/migrations/20261027120300_mark_the_active_turn_of_a_thread.d.ts +7 -0
  490. package/dist/state/migrations/20261027120300_mark_the_active_turn_of_a_thread.js +11 -0
  491. package/dist/state/migrations/20261028120000_record_the_paused_work.d.ts +7 -0
  492. package/dist/state/migrations/20261028120000_record_the_paused_work.js +25 -0
  493. package/dist/state/migrations/20261028120100_end_the_suspended_runs.d.ts +8 -0
  494. package/dist/state/migrations/20261028120100_end_the_suspended_runs.js +13 -0
  495. package/dist/state/migrations/20261029120000_reference_the_run_mandate.d.ts +7 -0
  496. package/dist/state/migrations/20261029120000_reference_the_run_mandate.js +23 -0
  497. package/dist/state/migrations/20261029120100_record_the_run_session_of_a_pause.d.ts +7 -0
  498. package/dist/state/migrations/20261029120100_record_the_run_session_of_a_pause.js +11 -0
  499. package/dist/state/migrations/index.js +18 -0
  500. package/dist/state/paused-work.d.ts +52 -0
  501. package/dist/state/paused-work.js +105 -0
  502. package/dist/state/plans.d.ts +27 -8
  503. package/dist/state/plans.js +14 -11
  504. package/dist/state/purge-analysis.d.ts +6 -6
  505. package/dist/state/purge-analysis.js +10 -2
  506. package/dist/state/report-session-state.d.ts +43 -18
  507. package/dist/state/report-session-state.js +43 -4
  508. package/dist/state/report-versions.d.ts +16 -11
  509. package/dist/state/report-versions.js +5 -3
  510. package/dist/state/runs.d.ts +30 -19
  511. package/dist/state/runs.js +43 -51
  512. package/dist/state/schema.d.ts +18 -21
  513. package/dist/state/schema.js +4 -5
  514. package/dist/state/snapshot-parse.d.ts +2 -2
  515. package/dist/state/snapshot-parse.js +14 -8
  516. package/dist/state/step-executions.d.ts +20 -8
  517. package/dist/state/step-executions.js +6 -4
  518. package/dist/state/tool-outputs.d.ts +2 -2
  519. package/dist/state/tool-outputs.js +2 -1
  520. package/dist/state/vector-store.d.ts +16 -16
  521. package/dist/state/vector-store.js +11 -7
  522. package/dist/tasks/data-profile-absorb.d.ts +3 -3
  523. package/dist/tasks/data-profile-absorb.js +21 -16
  524. package/dist/tasks/data-profile-activity.d.ts +5 -5
  525. package/dist/tasks/data-profile-activity.js +5 -5
  526. package/dist/tasks/data-profile-index.d.ts +4 -4
  527. package/dist/tasks/data-profile-index.js +32 -17
  528. package/dist/tasks/data-profile-resolve.d.ts +8 -8
  529. package/dist/tasks/data-profile-resolve.js +88 -62
  530. package/dist/tasks/data-profile.d.ts +40 -31
  531. package/dist/tasks/data-profile.js +138 -95
  532. package/dist/tasks/extract-values.d.ts +26 -79
  533. package/dist/tasks/extract-values.js +48 -108
  534. package/dist/tasks/refresh-regulatory-corpus.d.ts +4 -20
  535. package/dist/tasks/refresh-regulatory-corpus.js +12 -8
  536. package/dist/tasks/regulatory-corpus-boot-refresh.d.ts +2 -2
  537. package/dist/tasks/regulatory-corpus-boot-refresh.js +12 -10
  538. package/dist/testing.d.ts +62 -0
  539. package/dist/testing.js +101 -0
  540. package/dist/tools/ad-hoc-router.d.ts +9 -9
  541. package/dist/tools/ad-hoc-router.js +65 -52
  542. package/dist/tools/analysis-invocation.d.ts +7 -0
  543. package/dist/tools/analysis-invocation.js +29 -5
  544. package/dist/tools/approval/contract.d.ts +8 -52
  545. package/dist/tools/approval/contract.js +7 -36
  546. package/dist/tools/approval/gateway.d.ts +27 -28
  547. package/dist/tools/approval/gateway.js +33 -130
  548. package/dist/tools/approval/queries.d.ts +6 -11
  549. package/dist/tools/approval/queries.js +43 -29
  550. package/dist/tools/approval/uuidv7.js +2 -2
  551. package/dist/tools/bio/chembl.d.ts +3 -3
  552. package/dist/tools/bio/chembl.js +10 -0
  553. package/dist/tools/bio/comptox.d.ts +25 -8
  554. package/dist/tools/bio/comptox.js +4 -2
  555. package/dist/tools/bio/drug-gene-interactions.d.ts +27 -17
  556. package/dist/tools/bio/drug-gene-interactions.js +11 -8
  557. package/dist/tools/bio/gene-disease-evidence.d.ts +61 -15
  558. package/dist/tools/bio/gene-disease-evidence.js +10 -6
  559. package/dist/tools/bio/gene-preclinical-profile.d.ts +11 -11
  560. package/dist/tools/bio/keys.d.ts +2 -2
  561. package/dist/tools/bio/keys.js +3 -3
  562. package/dist/tools/bio/lookup-annotation.d.ts +5 -5
  563. package/dist/tools/bio/lookup-annotation.js +3 -0
  564. package/dist/tools/bio/opentargets.d.ts +1 -1
  565. package/dist/tools/bio/opentargets.js +6 -0
  566. package/dist/tools/bio/pubchem.d.ts +2 -2
  567. package/dist/tools/bio/pubchem.js +6 -0
  568. package/dist/tools/bio/pubmed.d.ts +26 -16
  569. package/dist/tools/bio/pubmed.js +9 -3
  570. package/dist/tools/bio/search-clinical-trials.d.ts +4 -4
  571. package/dist/tools/bio/search-clinical-trials.js +5 -1
  572. package/dist/tools/bio/search-faers.d.ts +2 -2
  573. package/dist/tools/bio/search-faers.js +1 -1
  574. package/dist/tools/bio/search-gene.d.ts +2 -2
  575. package/dist/tools/bio/search-gene.js +1 -0
  576. package/dist/tools/bio/search-geo-datasets.d.ts +4 -4
  577. package/dist/tools/bio/search-geo-datasets.js +5 -5
  578. package/dist/tools/bio/search-interactions.d.ts +1 -1
  579. package/dist/tools/bio/search-patents.d.ts +28 -22
  580. package/dist/tools/bio/search-patents.js +20 -17
  581. package/dist/tools/bio/search-protein.d.ts +2 -2
  582. package/dist/tools/bio/search-protein.js +1 -1
  583. package/dist/tools/bio/search-regulatory-approvals.d.ts +64 -18
  584. package/dist/tools/bio/search-regulatory-approvals.js +21 -16
  585. package/dist/tools/bio/target-safety.d.ts +8 -8
  586. package/dist/tools/bio/target-safety.js +11 -6
  587. package/dist/tools/capability-data.d.ts +9 -5
  588. package/dist/tools/capability-data.js +2 -1
  589. package/dist/tools/define-tool.d.ts +55 -46
  590. package/dist/tools/define-tool.js +39 -27
  591. package/dist/tools/display/normalize-echart-spec.d.ts +2 -2
  592. package/dist/tools/display/normalize-echart-spec.js +51 -27
  593. package/dist/tools/display/show-user.d.ts +2 -2
  594. package/dist/tools/display/show-user.js +1 -1
  595. package/dist/tools/execute-analysis.d.ts +19 -10
  596. package/dist/tools/execute-analysis.js +83 -62
  597. package/dist/tools/knowledge/check.d.ts +166 -44
  598. package/dist/tools/knowledge/check.js +5 -3
  599. package/dist/tools/knowledge/client.d.ts +31 -62
  600. package/dist/tools/knowledge/client.js +44 -27
  601. package/dist/tools/knowledge/environment.d.ts +6 -6
  602. package/dist/tools/knowledge/environment.js +18 -7
  603. package/dist/tools/knowledge/index.d.ts +2 -2
  604. package/dist/tools/knowledge/index.js +9 -9
  605. package/dist/tools/knowledge/local-slots.d.ts +4 -4
  606. package/dist/tools/knowledge/local-slots.js +11 -4
  607. package/dist/tools/knowledge/pin.d.ts +2 -2
  608. package/dist/tools/knowledge/recommend.d.ts +20 -45
  609. package/dist/tools/knowledge/recommend.js +27 -19
  610. package/dist/tools/knowledge/situation.d.ts +40 -40
  611. package/dist/tools/knowledge/situation.js +2 -9
  612. package/dist/tools/knowledge/skeleton.d.ts +4 -4
  613. package/dist/tools/knowledge/skeleton.js +10 -11
  614. package/dist/tools/knowledge/template.d.ts +20 -18
  615. package/dist/tools/knowledge/template.js +38 -32
  616. package/dist/tools/lib/alphafold-client.js +2 -1
  617. package/dist/tools/lib/amass-client.d.ts +28 -28
  618. package/dist/tools/lib/amass-client.js +20 -10
  619. package/dist/tools/lib/api-utils.d.ts +13 -3
  620. package/dist/tools/lib/api-utils.js +17 -3
  621. package/dist/tools/lib/bgee-client.d.ts +6 -6
  622. package/dist/tools/lib/bgee-client.js +16 -10
  623. package/dist/tools/lib/cbioportal-client.d.ts +4 -4
  624. package/dist/tools/lib/cbioportal-client.js +9 -8
  625. package/dist/tools/lib/chembl-client.d.ts +14 -14
  626. package/dist/tools/lib/chembl-client.js +11 -4
  627. package/dist/tools/lib/clinical-benchmarks-client.d.ts +4 -4
  628. package/dist/tools/lib/clinical-benchmarks-client.js +4 -7
  629. package/dist/tools/lib/clinical-trials-client.d.ts +18 -18
  630. package/dist/tools/lib/clinical-trials-client.js +10 -10
  631. package/dist/tools/lib/clinvar-client.d.ts +2 -2
  632. package/dist/tools/lib/clinvar-client.js +6 -6
  633. package/dist/tools/lib/ctx-ops.d.ts +23 -23
  634. package/dist/tools/lib/ctx-ops.js +13 -10
  635. package/dist/tools/lib/dgidb-client.d.ts +6 -6
  636. package/dist/tools/lib/dgidb-client.js +10 -12
  637. package/dist/tools/lib/disgenet-client.d.ts +4 -4
  638. package/dist/tools/lib/ema-client.d.ts +2 -2
  639. package/dist/tools/lib/ensembl-client.d.ts +4 -4
  640. package/dist/tools/lib/ensembl-client.js +5 -4
  641. package/dist/tools/lib/gwas-catalog-client.d.ts +4 -4
  642. package/dist/tools/lib/gwas-catalog-client.js +17 -17
  643. package/dist/tools/lib/html-text.d.ts +6 -0
  644. package/dist/tools/lib/html-text.js +9 -0
  645. package/dist/tools/lib/identifier-resolver.d.ts +4 -4
  646. package/dist/tools/lib/identifier-resolver.js +7 -3
  647. package/dist/tools/lib/impc-client.d.ts +8 -8
  648. package/dist/tools/lib/impc-client.js +46 -35
  649. package/dist/tools/lib/iuphar-client.d.ts +2 -2
  650. package/dist/tools/lib/iuphar-client.js +7 -16
  651. package/dist/tools/lib/monarch-client.d.ts +4 -4
  652. package/dist/tools/lib/openfda-client.d.ts +22 -22
  653. package/dist/tools/lib/openfda-client.js +23 -22
  654. package/dist/tools/lib/opentargets-client.d.ts +12 -12
  655. package/dist/tools/lib/pathway-client.d.ts +4 -4
  656. package/dist/tools/lib/pathway-client.js +15 -19
  657. package/dist/tools/lib/pharmgkb-client.d.ts +2 -2
  658. package/dist/tools/lib/pharmgkb-client.js +1 -1
  659. package/dist/tools/lib/protein-family-modality.d.ts +2 -2
  660. package/dist/tools/lib/protein-family-modality.js +0 -2
  661. package/dist/tools/lib/protein-family-normalize.js +7 -0
  662. package/dist/tools/lib/pubchem-client.d.ts +2 -2
  663. package/dist/tools/lib/pubchem-client.js +1 -0
  664. package/dist/tools/lib/pubchem-ops.d.ts +4 -4
  665. package/dist/tools/lib/pubchem-ops.js +8 -0
  666. package/dist/tools/lib/pubmed-client.d.ts +9 -9
  667. package/dist/tools/lib/pubmed-client.js +1 -1
  668. package/dist/tools/lib/string-client.d.ts +6 -6
  669. package/dist/tools/lib/uniprot-client.d.ts +8 -8
  670. package/dist/tools/lib/uniprot-client.js +5 -1
  671. package/dist/tools/memory/update-working-memory.d.ts +16 -13
  672. package/dist/tools/memory/update-working-memory.js +21 -3
  673. package/dist/tools/read-tool-output.js +8 -2
  674. package/dist/tools/registry.d.ts +2 -2
  675. package/dist/tools/report-authoring/authoring-tools.d.ts +54 -23
  676. package/dist/tools/report-authoring/authoring-tools.js +128 -62
  677. package/dist/tools/report-session/derive-table.d.ts +19 -59
  678. package/dist/tools/report-session/derive-table.js +120 -122
  679. package/dist/tools/report-session/examine-page.d.ts +6 -6
  680. package/dist/tools/report-session/examine-page.js +14 -12
  681. package/dist/tools/report-session/list-artifacts.d.ts +6 -6
  682. package/dist/tools/report-session/list-artifacts.js +5 -5
  683. package/dist/tools/report-session/page-faults.d.ts +6 -6
  684. package/dist/tools/report-session/page-faults.js +3 -1
  685. package/dist/tools/report-session/preview-report.d.ts +4 -3
  686. package/dist/tools/report-session/preview-report.js +26 -7
  687. package/dist/tools/report-session/record-version.d.ts +9 -4
  688. package/dist/tools/report-session/record-version.js +16 -9
  689. package/dist/tools/report-session/session-page-publisher.d.ts +6 -6
  690. package/dist/tools/research/generate-analogy-report.d.ts +14 -7
  691. package/dist/tools/research/generate-analogy-report.js +80 -76
  692. package/dist/tools/research/generate-plan.d.ts +16 -16
  693. package/dist/tools/research/generate-plan.js +410 -374
  694. package/dist/tools/research/guarded-address.js +3 -2
  695. package/dist/tools/research/inspect-data-profile.d.ts +27 -20
  696. package/dist/tools/research/inspect-data-profile.js +26 -25
  697. package/dist/tools/research/inspect-run.d.ts +54 -27
  698. package/dist/tools/research/inspect-run.js +50 -40
  699. package/dist/tools/research/literature-reviewer.d.ts +8 -7
  700. package/dist/tools/research/literature-reviewer.js +29 -28
  701. package/dist/tools/research/search-arxiv.d.ts +1 -1
  702. package/dist/tools/research/search-arxiv.js +1 -1
  703. package/dist/tools/research/search-github-repos.d.ts +10 -7
  704. package/dist/tools/research/search-github-repos.js +25 -22
  705. package/dist/tools/research/search-semantic-scholar.js +1 -1
  706. package/dist/tools/research/searxng-engine.d.ts +2 -2
  707. package/dist/tools/research/searxng-engine.js +6 -4
  708. package/dist/tools/research/web-fetch.d.ts +24 -21
  709. package/dist/tools/research/web-fetch.js +65 -74
  710. package/dist/tools/research/web-search.d.ts +26 -17
  711. package/dist/tools/research/web-search.js +26 -21
  712. package/dist/tools/sandbox/link-packages.d.ts +11 -7
  713. package/dist/tools/sandbox/link-packages.js +11 -8
  714. package/dist/tools/sandbox/list-available-packages.d.ts +17 -8
  715. package/dist/tools/sandbox/list-available-packages.js +31 -25
  716. package/dist/tools/sandbox/list-available-refs.d.ts +17 -14
  717. package/dist/tools/sandbox/list-available-refs.js +61 -36
  718. package/dist/tools/sandbox/report-blocker.d.ts +30 -37
  719. package/dist/tools/sandbox/report-blocker.js +23 -73
  720. package/dist/tools/sandbox/skills.d.ts +16 -12
  721. package/dist/tools/sandbox/skills.js +16 -12
  722. package/dist/tools/sandbox/submit-file-metadata.d.ts +12 -9
  723. package/dist/tools/sandbox/submit-file-metadata.js +18 -21
  724. package/dist/tools/start-report-session.d.ts +13 -5
  725. package/dist/tools/start-report-session.js +35 -8
  726. package/dist/tools/terminal-text.d.ts +5 -2
  727. package/dist/tools/terminal-text.js +35 -3
  728. package/dist/tools/workspace/decision-record.d.ts +4 -4
  729. package/dist/tools/workspace/decision-record.js +23 -13
  730. package/dist/tools/workspace/edit-file.d.ts +59 -20
  731. package/dist/tools/workspace/edit-file.js +81 -16
  732. package/dist/tools/workspace/execute-command.d.ts +15 -13
  733. package/dist/tools/workspace/execute-command.js +11 -9
  734. package/dist/tools/workspace/file-stat.d.ts +6 -3
  735. package/dist/tools/workspace/grep.d.ts +10 -7
  736. package/dist/tools/workspace/grep.js +9 -3
  737. package/dist/tools/workspace/list-files.d.ts +6 -3
  738. package/dist/tools/workspace/mutator.d.ts +28 -15
  739. package/dist/tools/workspace/mutator.js +107 -53
  740. package/dist/tools/workspace/read-file.d.ts +8 -5
  741. package/dist/tools/workspace/result-bounds.d.ts +5 -5
  742. package/dist/tools/workspace/result-bounds.js +4 -2
  743. package/dist/tools/workspace/run-exec.d.ts +2 -2
  744. package/dist/tools/workspace/run-exec.js +3 -3
  745. package/dist/tools/workspace/scan-inputs.d.ts +8 -5
  746. package/dist/tools/workspace/scan-inputs.js +17 -5
  747. package/dist/tools/workspace/show-file.d.ts +1 -1
  748. package/dist/tools/workspace/show-file.js +2 -1
  749. package/dist/tools/workspace/show-plan.d.ts +8 -5
  750. package/dist/tools/workspace/show-plan.js +9 -8
  751. package/dist/tools/workspace/workspace-search.d.ts +41 -13
  752. package/dist/tools/workspace/workspace-search.js +27 -14
  753. package/dist/tools/workspace/write-file.d.ts +9 -7
  754. package/dist/workflows/execute-analysis-scheduler.d.ts +9 -9
  755. package/dist/workflows/execute-analysis-scheduler.js +6 -3
  756. package/dist/workflows/execute-analysis.d.ts +46 -62
  757. package/dist/workflows/execute-analysis.js +137 -219
  758. package/dist/workflows/pause.d.ts +71 -0
  759. package/dist/workflows/pause.js +173 -0
  760. package/dist/workflows/sandbox-step.d.ts +38 -61
  761. package/dist/workflows/sandbox-step.js +99 -106
  762. package/dist/workflows/test/sql-writes.d.ts +21 -0
  763. package/dist/workflows/test/sql-writes.js +36 -0
  764. package/dist/workspace/filesystem.d.ts +6 -6
  765. package/dist/workspace/filesystem.js +10 -8
  766. package/dist/workspace/paths.d.ts +1 -1
  767. package/dist/workspace/paths.js +15 -4
  768. package/dist/workspace/search-config.d.ts +2 -2
  769. package/dist/workspace/search-config.js +1 -1
  770. package/package.json +21 -22
  771. package/dist/loop/call-guard.d.ts +0 -50
  772. package/dist/loop/call-guard.js +0 -90
  773. package/dist/loop/continue-agent.d.ts +0 -40
  774. package/dist/loop/continue-agent.js +0 -38
  775. package/dist/loop/genai-spans.d.ts +0 -47
  776. package/dist/loop/genai-spans.js +0 -134
  777. package/dist/loop/run-agent.d.ts +0 -245
  778. package/dist/loop/run-agent.js +0 -1124
  779. package/dist/loop/run-step.d.ts +0 -29
  780. package/dist/loop/run-step.js +0 -34
  781. package/dist/loop/run-to-terminal.d.ts +0 -66
  782. package/dist/loop/run-to-terminal.js +0 -93
  783. package/dist/loop/tool-mask.d.ts +0 -23
  784. package/dist/loop/tool-mask.js +0 -46
  785. package/dist/providers/streaming-chat.d.ts +0 -32
  786. package/dist/providers/streaming-chat.js +0 -91
  787. package/dist/tasks/derive-table-exec.d.ts +0 -54
  788. package/dist/tasks/derive-table-exec.js +0 -86
  789. package/dist/workflows/suspension.d.ts +0 -32
  790. package/dist/workflows/suspension.js +0 -38
@@ -39,23 +39,15 @@
39
39
  * `partial`).
40
40
  * - the halt cascade (cancel in-flight via
41
41
  * `Promise.allSettled(handles.map(h => DBOS.cancelWorkflow(h.workflowID)))`,
42
- * stop scheduling) survives only for a suspension of a child and the
43
- * `neverFits` plan-validation guard.
44
- * 4. Suspension cascade (workflow-suspension spec)
45
- * - a child that suspends sends a typed message on `CHILD_SUSPENDED_TOPIC`
46
- * and cancels itself. The parent reads the kind of the message, never a
47
- * reason string: it cancels the siblings, then self-cancels to
48
- * `CANCELLED` (NOT `ERROR` — ERROR isn't resumable; NOTES #3)
49
- * - a refusal of the `RunCharge.open` gate with the suspend flag suspends
50
- * the run before any step starts
51
- * - a `suspend` error of a synthesis model request suspends the run in
52
- * place of the synthesis failure
53
- * - the run row and the analysis flip to `suspended_insufficient_funds` in
54
- * `collectAndComplete`. The run status is terminal and does not block a
55
- * new run of the plan. The paused parent lands in `CANCELLED`, a
56
- * durably reschedulable state; re-driving it is a future enhancement,
57
- * not yet wired here. The reason of the host rides to the run row, the
58
- * charge close, the metric, and the terminal part, unread.
42
+ * stop scheduling) survives only for the `neverFits` plan-validation guard.
43
+ * 4. Pause (work-pause spec)
44
+ * - a step pauses in its own workflow, and the parent waits for its result as
45
+ * for a step that runs. The other steps go on, and the run row stays
46
+ * `running`
47
+ * - a refusal of the `RunCharge.open` gate with the suspend flag pauses the
48
+ * run before any step starts, and the charge opens again after the resume
49
+ * - a failed model request of the synthesis with a cause of a pause waits in
50
+ * the loop of the synthesizer
59
51
  * 5. `synthesizeFindings` (single sequential block, no sandbox)
60
52
  * 6. `collectAndComplete` (terminal — runs on ALL paths)
61
53
  * - determine final status from completed/cancelled/failed counts
@@ -73,7 +65,10 @@
73
65
  * - WRITES NOTHING to the conversation thread (results are pull-only
74
66
  * via `inspectRun`)
75
67
  */
76
- import { DBOS, Error as DBOSErrors } from "@dbos-inc/dbos-sdk";
68
+ import { errorMessageOf } from "../lib/thrown.js";
69
+ import { textOf } from "../lib/unknown-text.js";
70
+ import { DBOS } from "@dbos-inc/dbos-sdk";
71
+ import { isWorkflowCancellation } from "../runtime/dbos.js";
77
72
  import { err, ok } from "neverthrow";
78
73
  import { mkdir } from "node:fs/promises";
79
74
  import { join } from "node:path";
@@ -85,7 +80,8 @@ import { ATTR_INFLEXA_STEP_ID, stableSpan } from "../lib/otel-spans.js";
85
80
  import { recordRunCompleted, recordStepCompleted, stepOutcomeOf } from "../lib/metrics.js";
86
81
  import { describeDbError, withTransaction } from "../lib/db-result.js";
87
82
  import { unwrapOrThrow } from "../lib/result.js";
88
- import { countArtifactsByRuns, insertStepExecution, loadDataProfileStatus, queryActiveRun, queryStepArtifactPaths, queryStepsByRun, seedStepExecutions, setRunSynthesisOutcome, suspendAnalysis as suspendAnalysisQuery, sweepPendingStepExecutions, updateRunStatus, updateStepExecution, } from "../state/index.js";
83
+ import { countArtifactsByRuns, insertStepExecution, loadDataProfileStatus, queryActiveRun, queryStepArtifactPaths, queryStepsByRun, seedStepExecutions, setRunSynthesisOutcome, sweepPendingStepExecutions, updateRunStatus, updateStepExecution, } from "../state/index.js";
84
+ import { clearPausesOfWork } from "../state/paused-work.js";
89
85
  import { addChatUsage, hasReportedUsage } from "../loop/metrics.js";
90
86
  import { flattenDataPart } from "../contracts/chat-frame.js";
91
87
  import { SYNTHESIS_AGENT_ID, loadStepSummariesFromDisk } from "../execution/run-synthesis.js";
@@ -95,18 +91,20 @@ import { isChatDataPart, synthesisEmission } from "../sandbox/sandbox-step-trans
95
91
  import { synthesizeRun } from "../app/synthesize-run.js";
96
92
  import { computeTopologicalLevels, scheduleReady, validatePlanDag } from "./execute-analysis-scheduler.js";
97
93
  import { recordCancelledChild } from "./metrics.js";
98
- import { CHILD_SUSPENDED_TOPIC } from "./sandbox-step.js";
99
- import { cancelSelf, suspensionOfFailure, suspensionOfRefusal } from "./suspension.js";
94
+ import { pauseAtGate, workPause } from "./pause.js";
95
+ import { presentGet } from "../lib/present.js";
100
96
  // ── In-body orchestration helpers ────────────────────────────────────
101
97
  /** Emit a chat data part on the parent's DBOS stream. */
102
98
  function emitStreamPart(part) {
103
99
  return DBOS.writeStream("events", part);
104
100
  }
105
101
  /**
106
- * A failed write rolls back no side effect that succeeded and never fails the
107
- * run. A DBOS exception passes through with no change.
102
+ * A failed write rolls back no side effect that succeeded. The step body logs
103
+ * its own failure and never throws. A DBOS exception passes through with no
104
+ * change.
108
105
  */
109
106
  async function ledgerStep(log, name, write) {
107
+ // typecheck-disable-next-line must-use-result -- a ledger miss must not fail the run
110
108
  await DBOS.runStep(async () => {
111
109
  const written = await write();
112
110
  if (written.isOk())
@@ -156,8 +154,8 @@ function buildRunObservation(args) {
156
154
  agent: input.agentByStepId[s.id] ?? "unknown",
157
155
  // A step absent from the map has not been reached yet; `pending` is its honest state.
158
156
  status: rt?.status ?? "pending",
159
- ...(rt?.durationMs !== undefined ? { durationMs: rt.durationMs } : {}),
160
- ...(rt?.error !== undefined ? { error: rt.error } : {}),
157
+ durationMs: rt?.durationMs,
158
+ error: rt?.error,
161
159
  };
162
160
  }),
163
161
  };
@@ -188,7 +186,7 @@ function observeRunGuarded(deps, observation) {
188
186
  * projection/timeout-propagation tests.
189
187
  */
190
188
  export function buildChildInput(args) {
191
- const { input, stepId, level, runId, workflowId, prompt, templateBinding } = args;
189
+ const { input, stepId, level, runId, prompt, templateBinding } = args;
192
190
  const resources = input.resourcesByStepId[stepId];
193
191
  if (!resources) {
194
192
  throw new Error(`executeAnalysis: step "${stepId}" missing from resourcesByStepId — every step must declare resources`);
@@ -212,10 +210,9 @@ export function buildChildInput(args) {
212
210
  dependsOn: planStep.depends_on,
213
211
  // Composed beside the seed, thus the same checkpoint carries both and a
214
212
  // replay hands the child the binding its briefing describes.
215
- ...(templateBinding ? { templateBinding } : {}),
213
+ templateBinding,
216
214
  level,
217
215
  prompt,
218
- parentWorkflowId: workflowId,
219
216
  resources,
220
217
  timeoutSeconds: input.timeoutByStepId?.[stepId],
221
218
  };
@@ -241,7 +238,7 @@ export function buildChildInput(args) {
241
238
  */
242
239
  export async function composeStepSeed(args) {
243
240
  const { briefing, templateBinding } = await gatherStepPackage(args);
244
- return { prompt: composeStepBriefing(briefing), ...(templateBinding ? { templateBinding } : {}) };
241
+ return { prompt: composeStepBriefing(briefing), templateBinding };
245
242
  }
246
243
  /**
247
244
  * Do every read of one step's package and give the data its seed is rendered
@@ -308,7 +305,7 @@ export async function gatherStepPackage(args) {
308
305
  memory: { goal: memory.goal, constraints: memory.constraints },
309
306
  ...contract.briefing,
310
307
  },
311
- ...(contract.binding ? { templateBinding: contract.binding } : {}),
308
+ templateBinding: contract.binding,
312
309
  };
313
310
  }
314
311
  /** A served contract carries no `match`; the two refusals do. */
@@ -338,7 +335,7 @@ async function resolveTemplateContract(step, client) {
338
335
  return bindTemplateContract(ref, answer, step.grounding?.settings ?? [], {
339
336
  stepId: step.id,
340
337
  claims: step.grounding?.claims ?? [],
341
- ...(step.grounding?.snapshot && step.grounding.snapshot !== "none" ? { snapshot: step.grounding.snapshot } : {}),
338
+ snapshot: step.grounding?.snapshot && step.grounding.snapshot !== "none" ? step.grounding.snapshot : undefined,
342
339
  });
343
340
  }
344
341
  /** The version of a template reference (`tpl-x@1.0.0` gives `1.0.0`), or `undefined` when the reference has none. */
@@ -421,28 +418,26 @@ function bindTemplateContract(ref, contract, settings, grounding) {
421
418
  inputs: (contract.inputs ?? []).map((input) => ({
422
419
  name: input.name,
423
420
  path: input.path,
424
- ...(input.description ? { description: input.description } : {}),
421
+ description: input.description,
425
422
  })),
426
423
  bound,
427
424
  unbound_settings: unbound,
428
425
  },
429
426
  },
430
- ...(versionMatches
427
+ binding: versionMatches
431
428
  ? {
432
- binding: {
433
- template: ref,
434
- slots,
435
- sources,
436
- step: grounding.stepId,
437
- claims: grounding.claims,
438
- ...(grounding.snapshot ? { snapshot: grounding.snapshot } : {}),
439
- // The local slots of the contract, thus the tool binds a path or a column name on the machine
440
- // without a second read of the contract.
441
- local: contract.parameters.filter((slot) => slot.local === true),
442
- adaptable: adaptable.map((slot) => slot.name),
443
- },
429
+ template: ref,
430
+ slots,
431
+ sources,
432
+ step: grounding.stepId,
433
+ claims: grounding.claims,
434
+ snapshot: grounding.snapshot,
435
+ // The local slots of the contract, thus the tool binds a path or a column name on the machine
436
+ // without a second read of the contract.
437
+ local: contract.parameters.filter((slot) => slot.local === true),
438
+ adaptable: adaptable.map((slot) => slot.name),
444
439
  }
445
- : {}),
440
+ : undefined,
446
441
  };
447
442
  }
448
443
  /**
@@ -485,13 +480,10 @@ async function collectUpstreamHandoffs(args) {
485
480
  * its reason in `blockedReason` — an honest agent-declared blocker, not an
486
481
  * error — and a failure carries the same reason string
487
482
  * `persist-synthesis-outcome` writes to `cortex_runs.synthesis_reason`, so the
488
- * two ledgers cannot disagree about why synthesis died. A suspension is not an
489
- * outcome: the row is canceled, as the row of a suspended step. Exported for
490
- * the projection tests (the `buildChildInput` pattern).
483
+ * two ledgers cannot disagree about why synthesis died. Exported for the
484
+ * projection tests (the `buildChildInput` pattern).
491
485
  */
492
486
  export function synthesisRowUpdate(outcome, durationMs) {
493
- if ("kind" in outcome)
494
- return { status: "canceled", durationMs, error: outcome.reason };
495
487
  switch (outcome.status) {
496
488
  case "produced":
497
489
  return { status: "completed", durationMs };
@@ -510,9 +502,11 @@ export function synthesisRowUpdate(outcome, durationMs) {
510
502
  /**
511
503
  * Run-level literature-grounded synthesis (no sandbox). Returns the
512
504
  * quick-display findings for the run-completed card; empty when synthesis is
513
- * skipped or produced no synthesizable content. A genuine failure re-throws
514
- * inside the caller's `DBOS.runStep`, failing the run (D10). Exported so
515
- * integration tests can drive the wired synthesis without a full parent body.
505
+ * skipped or produced no synthesizable content. A genuine failure re-throws,
506
+ * failing the run (D10). It runs in the body of the run workflow: each read and
507
+ * write is a step, each model call is a step, and each reviewer call starts a
508
+ * child workflow. Exported so integration tests can drive the wired synthesis
509
+ * without a full parent body.
516
510
  */
517
511
  export function synthesizeFindings(args) {
518
512
  const { analysisId, runId, completedSteps, session, deps } = args;
@@ -543,10 +537,9 @@ export function synthesizeFindings(args) {
543
537
  embedding: deps.embedding,
544
538
  resolveWorkspaceRoot: deps.resolveWorkspaceRoot,
545
539
  synthesisModel: deps.synthesisModel,
546
- bioKeys: deps.bioKeys,
547
- citationResolver: deps.citationResolver,
540
+ literatureReviewer: deps.literatureReviewer,
548
541
  usageRecorder: deps.usageRecorder,
549
- ...(deps.toolOutputStore ? { toolOutputStore: deps.toolOutputStore } : {}),
542
+ toolOutputStore: deps.toolOutputStore,
550
543
  }, {
551
544
  analysisId,
552
545
  runId,
@@ -563,9 +556,10 @@ export function synthesizeFindings(args) {
563
556
  // call path.
564
557
  session: forStep(session, SYNTHESIS_STEP_ID),
565
558
  emit,
559
+ pause: args.pause?.afterFailure,
560
+ durably: (name, run) => DBOS.runStep(run, { name }),
566
561
  onProgress: async (phase, activity, extra = {}) => {
567
- // Synthesis runs inside one `DBOS.runStep`, thus `DBOS.now()` reads the wall clock here, and a rerun of
568
- // the step after a crash writes its entries again under the same ids. A reader dedups an entry by id.
562
+ // The body checkpoints the clock and each write, thus a replay writes no entry again.
569
563
  const seq = progressSeq++;
570
564
  const at = new Date(await DBOS.now()).toISOString();
571
565
  const parts = synthesisEmission(runId, SYNTHESIS_STEP_ID, seq, phase, activity, at, extra);
@@ -603,7 +597,17 @@ export async function runExecuteAnalysisBody(input, deps) {
603
597
  // the run authorization is already minted and rides in `input.runSession`.
604
598
  const runId = input.runSession.runFrame.runId;
605
599
  const workflowId = runId;
606
- const init = await validateAndInit(input, runId, deps);
600
+ const pause = workPause({
601
+ pool: deps.pool,
602
+ workId: runId,
603
+ workKind: "run",
604
+ analysisId: input.analysisId,
605
+ emit: emitStreamPart,
606
+ retryDelaysMs: deps.pauseRetryDelaysMs,
607
+ run: { session: input.runSession, authorizer: deps.runAuthorizer },
608
+ logger,
609
+ });
610
+ const init = await validateAndInit(input, runId, deps, pause);
607
611
  if (init.kind === "joined-existing") {
608
612
  return {
609
613
  runId: init.runId,
@@ -615,7 +619,6 @@ export async function runExecuteAnalysisBody(input, deps) {
615
619
  };
616
620
  }
617
621
  if (init.kind === "charge-refused") {
618
- const suspension = suspensionOfRefusal(init.refusal) ?? null;
619
622
  const refusedAtMs = await DBOS.now();
620
623
  const refused = await collectAndComplete({
621
624
  input,
@@ -625,16 +628,13 @@ export async function runExecuteAnalysisBody(input, deps) {
625
628
  completed: new Set(),
626
629
  failed: new Set(),
627
630
  canceled: new Set(),
628
- suspension,
629
631
  failureReason: init.refusal.reason,
630
- forceFailed: suspension === null,
632
+ forceFailed: true,
631
633
  findings: [],
632
634
  synthesisOutcome: null,
633
635
  deps,
634
636
  });
635
637
  observeRunGuarded(deps, buildRunObservation({ input, runId, status: refused.status, stepStates: new Map() }));
636
- if (suspension !== null)
637
- return cancelSelf("self-cancel-suspended");
638
638
  return refused;
639
639
  }
640
640
  // Seed the full DAG as `pending` rows so ledger readers see every step from
@@ -705,12 +705,11 @@ export async function runExecuteAnalysisBody(input, deps) {
705
705
  // still run the terminal block (close charge + revoke run authorization), and re-throw
706
706
  // after so the workflow record goes to ERROR.
707
707
  let synthesisError = null;
708
- let synthesisSuspension = null;
708
+ let synthesisMessage;
709
709
  let synthesisFindings = [];
710
710
  // Null when synthesis never ran (disabled or no completed steps): the ledger
711
711
  // columns stay NULL — "unknown", not a recorded skip — and the seeded
712
- // `synthesis` row (if any) stays `pending` for the terminal sweep. Also null
713
- // when synthesis suspended: a resume of the run gives the outcome.
712
+ // `synthesis` row (if any) stays `pending` for the terminal sweep.
714
713
  let synthesisOutcome = null;
715
714
  if (synthesisEnabled && final.completed.size > 0) {
716
715
  // Bracketing clock reads for the row's duration_ms — checkpointed, so a
@@ -730,13 +729,14 @@ export async function runExecuteAnalysisBody(input, deps) {
730
729
  }));
731
730
  let rowOutcome;
732
731
  try {
733
- const synthOut = await DBOS.runStep(() => synthesizeFindings({
732
+ const synthOut = await synthesizeFindings({
734
733
  analysisId: input.analysisId,
735
734
  runId,
736
735
  completedSteps: [...final.completed],
737
736
  session: input.runSession,
738
737
  deps,
739
- }), { name: "synthesize-findings" });
738
+ pause,
739
+ });
740
740
  synthesisFindings = synthOut.findings;
741
741
  synthesisOutcome = { status: synthOut.synthesisStatus, reason: synthOut.synthesisReason };
742
742
  rowOutcome = synthesisOutcome;
@@ -749,20 +749,14 @@ export async function runExecuteAnalysisBody(input, deps) {
749
749
  // this path either, so the run row is equally non-terminal and the pair
750
750
  // stays consistent — the pre-existing cancelled-mid-flight wedge shape
751
751
  // `inflexa run` already detects via its DBOS-status cross-check.
752
- if (err instanceof DBOSErrors.DBOSWorkflowCancelledError)
752
+ if (isWorkflowCancellation(err))
753
753
  throw err;
754
- const suspended = suspensionOfFailure(err);
755
- if (suspended !== undefined) {
756
- synthesisSuspension = suspended;
757
- rowOutcome = suspended;
758
- logger.warn("synthesizeFindings suspended — suspending the run", { runId, reason: suspended.reason });
759
- }
760
- else {
761
- synthesisError = err;
762
- synthesisOutcome = { status: "failed", reason: err instanceof Error ? err.message : String(err) };
763
- rowOutcome = synthesisOutcome;
764
- logger.error("synthesizeFindings failed — failing the run", { runId, ...logger.errorFields(err) });
765
- }
754
+ // A failure with a cause of a pause waited in the loop of the synthesizer, thus this one fails the run.
755
+ synthesisError = err;
756
+ synthesisMessage = errorMessageOf(err);
757
+ synthesisOutcome = { status: "failed", reason: errorMessageOf(err) ?? textOf(err) };
758
+ rowOutcome = synthesisOutcome;
759
+ logger.error("synthesizeFindings failed — failing the run", { runId, ...logger.errorFields(err) });
766
760
  }
767
761
  // Terminal stamp for the `synthesis` row — deliberately BEFORE
768
762
  // `collectAndComplete` writes the run row's terminal status, so no reader
@@ -782,7 +776,6 @@ export async function runExecuteAnalysisBody(input, deps) {
782
776
  // (6) collectAndComplete — terminal block. Runs on EVERY path. When synthesis
783
777
  // failed, force a failed terminal status so the charge/run-authorization close correctly
784
778
  // and the run row + stream report the failure before we re-throw.
785
- const suspension = final.suspension ?? synthesisSuspension;
786
779
  const result = await collectAndComplete({
787
780
  input,
788
781
  runId,
@@ -791,15 +784,8 @@ export async function runExecuteAnalysisBody(input, deps) {
791
784
  completed: final.completed,
792
785
  failed: final.failed,
793
786
  canceled: final.canceled,
794
- suspension,
795
- ...(final.usage ? { usage: final.usage } : {}),
796
- failureReason: synthesisError
797
- ? synthesisError instanceof Error
798
- ? `synthesis-failed: ${synthesisError.message}`
799
- : "synthesis-failed"
800
- : final.suspension === null && synthesisSuspension !== null
801
- ? synthesisSuspension.reason
802
- : final.failureReason,
787
+ usage: final.usage,
788
+ failureReason: synthesisError === null ? final.failureReason : synthesisMessage === undefined ? "synthesis-failed" : `synthesis-failed: ${synthesisMessage}`,
803
789
  forceFailed: synthesisError !== null,
804
790
  findings: synthesisFindings,
805
791
  synthesisOutcome,
@@ -807,20 +793,15 @@ export async function runExecuteAnalysisBody(input, deps) {
807
793
  });
808
794
  // Terminal snapshot, fired here rather than inside `collectAndComplete` because this is the
809
795
  // first point where BOTH the derived final status and the scheduler's final step map are in
810
- // hand. It precedes the suspension self-cancel below on purpose: that branch raises out of the
811
- // body, so an observer placed after it would never see a suspended run's last state.
796
+ // hand.
812
797
  observeRunGuarded(deps, buildRunObservation({ input, runId, status: result.status, stepStates: final.stepStates }));
813
- // Synthesis failure takes priority over the suspension cascade: a run whose
814
- // synthesis threw is definitively failed (ERROR), not a resumable
815
- // suspension. Only self-cancel when synthesis did not throw a failure.
816
- if (suspension !== null && synthesisError === null)
817
- return cancelSelf("self-cancel-suspended");
818
798
  // Re-throw after the terminal block so the workflow record goes to ERROR.
799
+ // oxlint-disable-next-line typescript/only-throw-error -- the caught synthesis failure rides as-is so the workflow record fails with the original cause; a wrapper would erase its identity.
819
800
  if (synthesisError !== null)
820
801
  throw synthesisError;
821
802
  return result;
822
803
  }
823
- async function validateAndInit(input, runId, deps) {
804
+ async function validateAndInit(input, runId, deps, pause) {
824
805
  // The cortex_runs row already exists (inserted by `executePlan`). Sanity-
825
806
  // check that no other active run for the same plan won the race — the
826
807
  // partial-unique index would have rejected the insert if so, so this is
@@ -837,11 +818,17 @@ async function validateAndInit(input, runId, deps) {
837
818
  recursive: true,
838
819
  });
839
820
  }, { name: "init-run-filesystem" });
840
- const opened = await DBOS.runStep(async () => await passGate("RunCharge.open", deps.runCharge.open({
821
+ const openCharge = () => DBOS.runStep(async () => await passGate("RunCharge.open", deps.runCharge.open({
841
822
  analysisId: input.analysisId,
842
823
  runId,
843
824
  session: input.runSession,
844
825
  })), { name: "open-running-charge" });
826
+ let opened = await openCharge();
827
+ // A refusal with the suspend flag waits in a pause, and the charge opens again after the resume.
828
+ while (opened.isErr() && opened.error.kind === "suspended") {
829
+ await pauseAtGate(pause, opened.error.reason);
830
+ opened = await openCharge();
831
+ }
845
832
  if (opened.isErr())
846
833
  return { kind: "charge-refused", refusal: opened.error };
847
834
  return { kind: "fresh" };
@@ -852,14 +839,13 @@ async function runSchedulerLoop(args) {
852
839
  const failed = new Set();
853
840
  const canceled = new Set();
854
841
  const inFlight = new Map();
855
- const childSuspensions = new Map();
856
842
  // Run-level usage aggregate, folded from the children's own durable results.
857
843
  // `getResult` IS the replay-safe source: a recovered parent reads back the
858
844
  // identical value from each child's workflow record, so the sum reproduces
859
845
  // exactly without a second channel. A child that settled by throwing carries
860
846
  // no result and therefore contributes nothing — same rule as its duration.
861
847
  const runUsage = {};
862
- // Child workflow ids the parent itself cancelled (suspension / neverFits halt cascade). Their `getResult`
848
+ // Child workflow ids the parent itself cancelled (the neverFits halt cascade). Their `getResult`
863
849
  // rejects with a DBOS cancellation error and lands in the settlement error branch — but the step was
864
850
  // CANCELED by us, not failed on its own merits. Keyed here (deterministic: `cancelInFlight` runs the
865
851
  // same way on a replay) so that branch records it as canceled everywhere, matching how a child that
@@ -893,26 +879,18 @@ async function runSchedulerLoop(args) {
893
879
  const stack = [...(dependentsByStepId.get(failedStepId) ?? [])];
894
880
  while (stack.length > 0) {
895
881
  const id = stack.pop();
896
- if (stepRuntime.get(id).status === "pending") {
882
+ if (id === undefined)
883
+ break;
884
+ if (presentGet(stepRuntime, id, "the runtime of the step").status === "pending") {
897
885
  stepRuntime.set(id, { status: "skipped" });
898
886
  stack.push(...(dependentsByStepId.get(id) ?? []));
899
887
  }
900
888
  }
901
889
  };
902
- // Halts scheduling entirely — reserved for a suspension of a child and the
903
- // `neverFits` guard. An ordinary step failure does NOT set it: it dooms
904
- // only that step's transitive dependents.
890
+ // Halts scheduling entirely — reserved for the `neverFits` guard. An ordinary
891
+ // step failure does NOT set it: it dooms only that step's transitive dependents.
905
892
  let halted = false;
906
- let suspension = null;
907
893
  let failureReason = null;
908
- const haltForSuspension = async (child) => {
909
- if (suspension === null) {
910
- suspension = { kind: "suspended", reason: child.reason };
911
- halted = true;
912
- failureReason = child.reason;
913
- }
914
- await cancelInFlight(inFlight, child.reason, canceledByParent);
915
- };
916
894
  const stepIndexById = new Map(input.steps.map((s, i) => [s.id, i]));
917
895
  const emitDagSnapshot = async () => {
918
896
  await emitStreamPart({
@@ -920,7 +898,7 @@ async function runSchedulerLoop(args) {
920
898
  id: `dag-${runId}`,
921
899
  runId,
922
900
  steps: input.steps.map((s) => {
923
- const rt = stepRuntime.get(s.id);
901
+ const rt = presentGet(stepRuntime, s.id, "the runtime of the step");
924
902
  const entry = {
925
903
  id: s.id,
926
904
  // `input.steps` is the SCHEDULER's projection — `{id, depends_on}` and nothing
@@ -953,7 +931,6 @@ async function runSchedulerLoop(args) {
953
931
  // the body once `collectAndComplete` has derived the final status.
954
932
  observeRunGuarded(deps, buildRunObservation({ input, runId, status: "running", stepStates: stepRuntime }));
955
933
  };
956
- const dbosParentId = DBOS.workflowID ?? workflowId;
957
934
  const dispatchReady = async () => {
958
935
  if (halted)
959
936
  return;
@@ -987,13 +964,13 @@ async function runSchedulerLoop(args) {
987
964
  });
988
965
  }
989
966
  halted = true;
990
- failureReason = `step "${scheduled.neverFits[0]}" exceeds the machine resource budget`;
967
+ failureReason = `step "${String(scheduled.neverFits[0])}" exceeds the machine resource budget`;
991
968
  await cancelInFlight(inFlight, "fail_fast", canceledByParent);
992
969
  await emitDagSnapshot();
993
970
  return;
994
971
  }
995
972
  for (const stepId of scheduled.heldForCapacity) {
996
- if (stepRuntime.get(stepId).status !== "queued") {
973
+ if (presentGet(stepRuntime, stepId, "the runtime of the step").status !== "queued") {
997
974
  stepRuntime.set(stepId, { status: "queued" });
998
975
  queuedChanged = true;
999
976
  }
@@ -1009,7 +986,7 @@ async function runSchedulerLoop(args) {
1009
986
  return;
1010
987
  }
1011
988
  for (const stepId of admit) {
1012
- const idx = stepIndexById.get(stepId);
989
+ const idx = presentGet(stepIndexById, stepId, "the index of the step");
1013
990
  const childWorkflowId = `${workflowId}-${idx}`;
1014
991
  // Compose the seed HERE — the dependencies of `stepId` are all in
1015
992
  // `completed`, so this is the first (and only) moment their results
@@ -1028,18 +1005,16 @@ async function runSchedulerLoop(args) {
1028
1005
  stepId,
1029
1006
  level: levels.get(stepId) ?? 0,
1030
1007
  runId,
1031
- workflowId,
1032
1008
  prompt: seed.prompt,
1033
- ...(seed.templateBinding ? { templateBinding: seed.templateBinding } : {}),
1009
+ templateBinding: seed.templateBinding,
1034
1010
  });
1035
1011
  const childInput = {
1036
1012
  ...baseChildInput,
1037
- parentWorkflowId: dbosParentId,
1038
1013
  runSession: forStep(input.runSession, stepId),
1039
1014
  };
1040
- const handle = (await DBOS.startWorkflow(deps.sandboxStepCallable, {
1015
+ const handle = await DBOS.startWorkflow(deps.sandboxStepCallable, {
1041
1016
  workflowID: childWorkflowId,
1042
- })(childInput));
1017
+ })(childInput);
1043
1018
  inFlight.set(childWorkflowId, { stepId, handle });
1044
1019
  stepRuntime.set(stepId, { status: "running" });
1045
1020
  }
@@ -1053,7 +1028,7 @@ async function runSchedulerLoop(args) {
1053
1028
  // function-ID-consuming ops and diverge the counter on replay.
1054
1029
  const winner = await DBOS.waitFirst([...inFlight.values()].map((e) => e.handle));
1055
1030
  const childId = winner.workflowID;
1056
- const entry = inFlight.get(childId);
1031
+ const entry = presentGet(inFlight, childId, "the in-flight entry of the winning child");
1057
1032
  inFlight.delete(childId);
1058
1033
  let settled;
1059
1034
  try {
@@ -1063,8 +1038,6 @@ async function runSchedulerLoop(args) {
1063
1038
  catch (err) {
1064
1039
  settled = { childId, stepId: entry.stepId, kind: "error", err };
1065
1040
  }
1066
- await drainChildSuspensions(childSuspensions);
1067
- const childSuspension = childSuspensions.get(settled.childId);
1068
1041
  // Terminal step status + duration for the provenance emission below. Every
1069
1042
  // settlement branch assigns both, so the emission fires exactly once per
1070
1043
  // settled child with the mapped status.
@@ -1077,24 +1050,22 @@ async function runSchedulerLoop(args) {
1077
1050
  completed.add(settled.stepId);
1078
1051
  stepRuntime.set(settled.stepId, {
1079
1052
  status: "completed",
1080
- durationMs: r.durationMs ?? undefined,
1053
+ durationMs: r.durationMs,
1081
1054
  });
1082
1055
  stepStatus = "completed";
1083
- stepDurationMs = r.durationMs ?? undefined;
1056
+ stepDurationMs = r.durationMs;
1084
1057
  await emitDagSnapshot();
1085
1058
  await dispatchReady();
1086
1059
  }
1087
1060
  else if (r.status === "canceled") {
1088
1061
  canceled.add(settled.stepId);
1089
- if (childSuspension !== undefined)
1090
- await haltForSuspension(childSuspension);
1091
1062
  stepRuntime.set(settled.stepId, {
1092
1063
  status: "failed",
1093
- durationMs: r.durationMs ?? undefined,
1064
+ durationMs: r.durationMs,
1094
1065
  error: r.error ?? "canceled",
1095
1066
  });
1096
1067
  stepStatus = "canceled";
1097
- stepDurationMs = r.durationMs ?? undefined;
1068
+ stepDurationMs = r.durationMs;
1098
1069
  await emitDagSnapshot();
1099
1070
  }
1100
1071
  else {
@@ -1107,18 +1078,18 @@ async function runSchedulerLoop(args) {
1107
1078
  failureReason ??= r.error ?? (r.status === "blocked" ? "step_blocked" : "step_failed");
1108
1079
  stepRuntime.set(settled.stepId, {
1109
1080
  status: "failed",
1110
- durationMs: r.durationMs ?? undefined,
1081
+ durationMs: r.durationMs,
1111
1082
  error: r.error ?? (r.status === "blocked" ? "step_blocked" : "step_failed"),
1112
1083
  });
1113
1084
  markDependentsSkipped(settled.stepId);
1114
1085
  stepStatus = "failed";
1115
- stepDurationMs = r.durationMs ?? undefined;
1086
+ stepDurationMs = r.durationMs;
1116
1087
  await emitDagSnapshot();
1117
1088
  await dispatchReady();
1118
1089
  }
1119
1090
  }
1120
1091
  else if (canceledByParent.has(settled.childId)) {
1121
- // The child threw because the PARENT cancelled it (suspension / neverFits halt cascade), not
1092
+ // The child threw because the PARENT cancelled it (the neverFits halt cascade), not
1122
1093
  // because it failed on its own — its `getResult` rejects with a DBOS cancellation error.
1123
1094
  // Record it as canceled, mirroring the graceful `{status:"canceled"}` branch above so the
1124
1095
  // `canceled` set, the terminal result, and the `step_completed` provenance all agree. No
@@ -1128,34 +1099,22 @@ async function runSchedulerLoop(args) {
1128
1099
  // `stepRuntime` (the DAG snapshot) has no canceled tier; the graceful-cancel branch above
1129
1100
  // likewise renders canceled steps as "failed", so this stays consistent with it.
1130
1101
  status: "failed",
1131
- error: settled.err instanceof Error ? settled.err.message : String(settled.err),
1102
+ error: errorMessageOf(settled.err) ?? textOf(settled.err),
1132
1103
  });
1133
1104
  stepStatus = "canceled";
1134
1105
  stepDurationMs = undefined;
1135
1106
  await emitDagSnapshot();
1136
1107
  }
1137
- else if (childSuspension !== undefined) {
1138
- // The child suspended: it sent its typed suspension, then cancelled
1139
- // itself, thus `getResult` rejects with a DBOS cancellation. The
1140
- // suspension halts the run — the cascade is a decision of the host,
1141
- // not a DAG one — and it dooms no dependent: the resumed run needs them.
1142
- canceled.add(settled.stepId);
1143
- await haltForSuspension(childSuspension);
1144
- stepRuntime.set(settled.stepId, { status: "failed", error: childSuspension.reason });
1145
- stepStatus = "canceled";
1146
- stepDurationMs = undefined;
1147
- await emitDagSnapshot();
1148
- }
1149
1108
  else {
1150
- // The child threw on its own (not a parent-driven cancel, not a
1151
- // suspension). A throw is treated exactly like a step failure:
1109
+ // The child threw on its own (not a parent-driven cancel). A throw is
1110
+ // treated exactly like a step failure:
1152
1111
  // dependents doomed, siblings continue.
1153
1112
  failed.add(settled.stepId);
1154
- failureReason ??= settled.err instanceof Error ? settled.err.message : String(settled.err);
1113
+ failureReason ??= errorMessageOf(settled.err) ?? textOf(settled.err);
1155
1114
  markDependentsSkipped(settled.stepId);
1156
1115
  stepRuntime.set(settled.stepId, {
1157
1116
  status: "failed",
1158
- error: settled.err instanceof Error ? settled.err.message : String(settled.err),
1117
+ error: errorMessageOf(settled.err) ?? textOf(settled.err),
1159
1118
  });
1160
1119
  stepStatus = "failed";
1161
1120
  // A child that settled by throwing carries no durable duration.
@@ -1176,30 +1135,19 @@ async function runSchedulerLoop(args) {
1176
1135
  runId,
1177
1136
  stepId: settled.stepId,
1178
1137
  status: stepStatus,
1179
- ...(stepDurationMs !== undefined ? { durationMs: stepDurationMs } : {}),
1138
+ durationMs: stepDurationMs,
1180
1139
  atMs: settledAtMs,
1181
1140
  }, input.runSession);
1182
1141
  }
1183
- await drainChildSuspensions(childSuspensions);
1184
1142
  return {
1185
1143
  completed,
1186
1144
  failed,
1187
1145
  canceled,
1188
- suspension,
1189
1146
  failureReason,
1190
1147
  stepStates: stepRuntime,
1191
- ...(hasReportedUsage(runUsage) ? { usage: { ...runUsage } } : {}),
1148
+ usage: hasReportedUsage(runUsage) ? { ...runUsage } : undefined,
1192
1149
  };
1193
1150
  }
1194
- async function drainChildSuspensions(suspensions) {
1195
- while (true) {
1196
- const msg = await DBOS.recv(CHILD_SUSPENDED_TOPIC, 0);
1197
- if (!msg)
1198
- return;
1199
- if (msg.kind === "suspended" && !suspensions.has(msg.childWorkflowId))
1200
- suspensions.set(msg.childWorkflowId, msg);
1201
- }
1202
- }
1203
1151
  async function cancelInFlight(inFlight, cause, canceledByParent) {
1204
1152
  const ids = [...inFlight.keys()];
1205
1153
  // Record every id BEFORE the cancel so the settlement loop classifies the resulting
@@ -1215,9 +1163,7 @@ async function cancelInFlight(inFlight, cause, canceledByParent) {
1215
1163
  /** The waits between the attempts are 1, 2, 4, and 8 seconds. */
1216
1164
  const FINAL_STATUS_WRITE_RETRY = { retriesAllowed: true, maxAttempts: 5, intervalSeconds: 1, backoffRate: 2 };
1217
1165
  async function collectAndComplete(args) {
1218
- const { input, runId, workflowId, startedAtMs, completed, failed, canceled, suspension, failureReason, forceFailed, deps } = args;
1219
- // A forced failure is terminal and never a resumable suspension.
1220
- const suspended = suspension !== null && !forceFailed ? suspension : null;
1166
+ const { input, runId, workflowId, startedAtMs, completed, failed, canceled, failureReason, forceFailed, deps } = args;
1221
1167
  const logger = (deps.logger ?? createNoopLogger()).named("executeAnalysis").with({ runId, analysisId: input.analysisId });
1222
1168
  const status = forceFailed
1223
1169
  ? "failed"
@@ -1226,22 +1172,9 @@ async function collectAndComplete(args) {
1226
1172
  completed,
1227
1173
  failed,
1228
1174
  canceled,
1229
- suspended: suspended !== null,
1230
1175
  });
1231
- const chargeOutcome = status === "completed" || status === "partial"
1232
- ? { kind: "ok" }
1233
- : status === "failed"
1234
- ? { kind: "error" }
1235
- : suspended !== null
1236
- ? { kind: "suspended", reason: suspended.reason }
1237
- : { kind: "canceled" };
1238
- const revokeReason = status === "completed" || status === "partial"
1239
- ? "workflow-completed"
1240
- : status === "failed"
1241
- ? "workflow-failed"
1242
- : suspended !== null
1243
- ? "workflow-suspended"
1244
- : "workflow-canceled";
1176
+ const chargeOutcome = status === "completed" || status === "partial" ? { kind: "ok" } : status === "failed" ? { kind: "error" } : { kind: "canceled" };
1177
+ const revokeReason = status === "completed" || status === "partial" ? "workflow-completed" : status === "failed" ? "workflow-failed" : "workflow-canceled";
1245
1178
  const finalError = failureReason ?? (status === "canceled" ? "external_cancel" : null);
1246
1179
  const terminalAtMs = await DBOS.now();
1247
1180
  const emitRunEnd = () => emitProvenanceGuarded(deps, {
@@ -1252,19 +1185,13 @@ async function collectAndComplete(args) {
1252
1185
  atMs: terminalAtMs,
1253
1186
  durationMs: terminalAtMs - startedAtMs,
1254
1187
  }, input.runSession);
1255
- // Ownership defaults to true for inputs persisted before the field existed (a
1256
- // workflow recovered across this deploy) — those were always Cortex-owned.
1257
- const authorization = {
1258
- runSession: input.runSession,
1259
- ownsMandate: input.ownsMandate ?? true, // oss-core-managed-ok
1260
- };
1261
1188
  const closeCharge = () => deliverNotice(logger.with({ chargeOutcome: chargeOutcome.kind }), "RunCharge.close", deps.runCharge.close({
1262
1189
  analysisId: input.analysisId,
1263
1190
  runId,
1264
1191
  outcome: chargeOutcome,
1265
1192
  session: input.runSession,
1266
1193
  }));
1267
- const revokeAuthorization = () => deliverNotice(logger.with({ revokeReason }), "RunAuthorizer.revoke", deps.runAuthorizer.revoke(authorization, revokeReason));
1194
+ const revokeAuthorization = () => deliverNotice(logger.with({ revokeReason }), "RunAuthorizer.revoke", deps.runAuthorizer.revoke(input.runSession, revokeReason));
1268
1195
  // The writer that wins the row owns the run end: the `run_completed` emit, the charge close,
1269
1196
  // and the revoke. The step does all three when its write changes the row. An engine cancel
1270
1197
  // cannot stop a step that started, so a won write is never cut before these acts.
@@ -1278,7 +1205,8 @@ async function collectAndComplete(args) {
1278
1205
  // The last attempt returns "failed" instead: the body takes the failed path with no `try`, and a
1279
1206
  // failure of DBOS to record a won step cannot be mistaken for a failed write. A commit can fail
1280
1207
  // after the emit, so `emittedInStep` keeps the later attempts from emitting again.
1281
- let emittedInStep = false;
1208
+ // The `undefined` in the annotation exists only because control-flow analysis cannot see the closure assignment; no code may depend on the initial state.
1209
+ let emittedInStep;
1282
1210
  const finalWrite = await DBOS.runStep(async () => {
1283
1211
  const stepLog = logger.with({ status }).named("persist-final-status");
1284
1212
  const written = await withTransaction(deps.pool, "runs.persistFinalStatus", (client) => updateRunStatus(client, runId, status, finalError).map((changed) => {
@@ -1350,7 +1278,7 @@ async function collectAndComplete(args) {
1350
1278
  await DBOS.setEvent(RUN_END_EVENT_KEY, recorded);
1351
1279
  }
1352
1280
  catch (error) {
1353
- if (error instanceof DBOSErrors.DBOSWorkflowCancelledError)
1281
+ if (isWorkflowCancellation(error))
1354
1282
  throw error;
1355
1283
  logger.error("run end record failed, the run canceler acts as for a run with no record", { status, ...logger.errorFields(error) });
1356
1284
  }
@@ -1364,23 +1292,17 @@ async function collectAndComplete(args) {
1364
1292
  if (outcome !== null) {
1365
1293
  await ledgerStep(logger.with({ synthesisStatus: outcome.status }), "persist-synthesis-outcome", () => setRunSynthesisOutcome(deps.pool, runId, outcome.status, outcome.reason));
1366
1294
  }
1367
- // Sweep never-started steps to `skipped` — but ONLY on genuinely-terminal
1368
- // paths. The gate is the BRANCH, not the written run status: the pending rows
1369
- // of a suspended run must survive for a later resume. Log-don't-rollback, like
1370
- // every other finalisation step here.
1371
- if (suspended === null) {
1372
- await ledgerStep(logger, "sweep-pending-steps", () => sweepPendingStepExecutions(deps.pool, runId));
1373
- }
1374
- if (suspended !== null) {
1375
- await ledgerStep(logger, "suspend-analysis", () => suspendAnalysisQuery(deps.pool, input.analysisId));
1376
- }
1295
+ // Sweep never-started steps to `skipped`. Log-don't-rollback, like every other finalisation step here.
1296
+ await ledgerStep(logger, "sweep-pending-steps", () => sweepPendingStepExecutions(deps.pool, runId));
1297
+ // A step that the neverFits halt canceled in its pause leaves its row, thus the end of the run clears each row of the run.
1298
+ await ledgerStep(logger, "clear-run-pauses", () => clearPausesOfWork(deps.pool, runId));
1377
1299
  // The run end was emitted above. These branches only fan out the UI stream part, whose
1378
1300
  // completed/failed shapes genuinely differ — the provenance record does not.
1379
1301
  if (status === "completed" || status === "partial") {
1380
1302
  const artifactCount = await DBOS.runStep(async () => await countArtifactsByRuns(deps.pool, input.analysisId, [runId])
1381
1303
  .map((counts) => counts[0]?.count ?? 0)
1382
1304
  .unwrapOr(0), { name: "count-run-artifacts" });
1383
- await emitStreamPart({
1305
+ const runCompleted = {
1384
1306
  type: "data-run-completed",
1385
1307
  runId,
1386
1308
  status,
@@ -1391,20 +1313,18 @@ async function collectAndComplete(args) {
1391
1313
  title: f.title,
1392
1314
  confidence: f.confidence,
1393
1315
  })),
1394
- ...(status === "partial"
1395
- ? {
1396
- note: `${completed.size} of ${input.steps.length} steps completed; results are partial.`,
1397
- }
1398
- : {}),
1399
- ...(args.usage ? { usage: args.usage } : {}),
1400
- });
1316
+ };
1317
+ if (status === "partial")
1318
+ runCompleted.note = `${completed.size} of ${input.steps.length} steps completed; results are partial.`;
1319
+ if (args.usage)
1320
+ runCompleted.usage = args.usage;
1321
+ await emitStreamPart(runCompleted);
1401
1322
  }
1402
1323
  else {
1403
1324
  await emitStreamPart({
1404
1325
  type: "data-run-failed",
1405
1326
  runId,
1406
- error: failureReason ?? (suspended !== null ? suspended.reason : "Run canceled before completion"),
1407
- ...(suspended !== null ? { reason: suspended.reason } : {}),
1327
+ error: failureReason ?? "Run canceled before completion",
1408
1328
  });
1409
1329
  }
1410
1330
  return {
@@ -1423,9 +1343,7 @@ async function collectAndComplete(args) {
1423
1343
  * status vocabulary without a cast.
1424
1344
  */
1425
1345
  function deriveFinalStatus(args) {
1426
- const { totalSteps, completed, failed, canceled, suspended } = args;
1427
- if (suspended)
1428
- return "suspended_insufficient_funds";
1346
+ const { totalSteps, completed, failed, canceled } = args;
1429
1347
  if (failed.size > 0) {
1430
1348
  return completed.size > 0 ? "partial" : "failed";
1431
1349
  }