@bastani/atomic 0.9.40 → 0.9.41-alpha.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 (323) hide show
  1. package/CHANGELOG.md +75 -0
  2. package/README.md +1 -1
  3. package/dist/builtin/intercom/CHANGELOG.md +12 -0
  4. package/dist/builtin/intercom/README.md +1 -1
  5. package/dist/builtin/intercom/broker/broker.ts +24 -21
  6. package/dist/builtin/intercom/broker/client.ts +97 -6
  7. package/dist/builtin/intercom/broker/list-reply.ts +53 -0
  8. package/dist/builtin/intercom/index.bundle.mjs +278 -46
  9. package/dist/builtin/intercom/package.json +2 -2
  10. package/dist/builtin/intercom/recoverable-disconnect.ts +27 -1
  11. package/dist/builtin/intercom/types.ts +8 -1
  12. package/dist/builtin/mcp/package.json +1 -1
  13. package/dist/builtin/subagents/CHANGELOG.md +14 -0
  14. package/dist/builtin/subagents/README.md +14 -0
  15. package/dist/builtin/subagents/package.json +3 -3
  16. package/dist/builtin/subagents/src/extension/index.bundle.mjs +99 -19
  17. package/dist/builtin/web-access/package.json +2 -2
  18. package/dist/builtin/workflows/CHANGELOG.md +33 -0
  19. package/dist/builtin/workflows/README.md +2 -0
  20. package/dist/builtin/workflows/builtin/adversarial-verification.js +2 -2
  21. package/dist/builtin/workflows/builtin/{chunk-qjqn389g.js → chunk-2jfst7e4.js} +72 -10
  22. package/dist/builtin/workflows/builtin/{chunk-4bwtzyjq.js → chunk-49kkbdpr.js} +1 -1
  23. package/dist/builtin/workflows/builtin/{chunk-qdd897wm.js → chunk-apagcs4r.js} +1 -1
  24. package/dist/builtin/workflows/builtin/{chunk-454hz1qt.js → chunk-dcxscfnb.js} +1 -1
  25. package/dist/builtin/workflows/builtin/{chunk-bjva9j5k.js → chunk-hx8v4p97.js} +1 -1
  26. package/dist/builtin/workflows/builtin/{chunk-85mx6wcf.js → chunk-k5q3t7je.js} +1 -1
  27. package/dist/builtin/workflows/builtin/{chunk-8kkv04hz.js → chunk-n2gkzkty.js} +1 -1
  28. package/dist/builtin/workflows/builtin/{chunk-y45tkftg.js → chunk-txbc93t6.js} +1 -1
  29. package/dist/builtin/workflows/builtin/{chunk-x0vvjyzg.js → chunk-w4xp1w1f.js} +1 -1
  30. package/dist/builtin/workflows/builtin/{chunk-5eh0brtd.js → chunk-z3pajrfs.js} +1 -1
  31. package/dist/builtin/workflows/builtin/classify-and-act.js +2 -2
  32. package/dist/builtin/workflows/builtin/fan-out-and-synthesize.js +2 -2
  33. package/dist/builtin/workflows/builtin/generate-and-filter.js +2 -2
  34. package/dist/builtin/workflows/builtin/goal.js +2 -2
  35. package/dist/builtin/workflows/builtin/index.js +10 -10
  36. package/dist/builtin/workflows/builtin/loop-until-done.js +2 -2
  37. package/dist/builtin/workflows/builtin/open-claude-design.js +2 -2
  38. package/dist/builtin/workflows/builtin/ralph.js +2 -2
  39. package/dist/builtin/workflows/builtin/tournament.js +2 -2
  40. package/dist/builtin/workflows/package.json +2 -2
  41. package/dist/builtin/workflows/src/authoring.d.ts +1 -1
  42. package/dist/builtin/workflows/src/durable/journal/internal.d.ts +16 -0
  43. package/dist/builtin/workflows/src/durable/journal/legacy-journal-tables.d.ts +9 -0
  44. package/dist/builtin/workflows/src/durable/journal/sql-run-journal.d.ts +6 -0
  45. package/dist/builtin/workflows/src/extension/index.bundle.mjs +950 -116
  46. package/dist/builtin/workflows/src/index.js +806 -131
  47. package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +17 -1
  48. package/dist/cli/credential-print.d.ts.map +1 -1
  49. package/dist/cli/credential-print.js +1 -1
  50. package/dist/cli/credential-print.js.map +1 -1
  51. package/dist/config.d.ts +1 -0
  52. package/dist/config.d.ts.map +1 -1
  53. package/dist/config.js +1 -0
  54. package/dist/config.js.map +1 -1
  55. package/dist/core/agent-session-extension-bindings.d.ts +2 -1
  56. package/dist/core/agent-session-extension-bindings.d.ts.map +1 -1
  57. package/dist/core/agent-session-extension-bindings.js +33 -18
  58. package/dist/core/agent-session-extension-bindings.js.map +1 -1
  59. package/dist/core/agent-session-methods.d.ts +2 -1
  60. package/dist/core/agent-session-methods.d.ts.map +1 -1
  61. package/dist/core/agent-session-methods.js.map +1 -1
  62. package/dist/core/agent-session-prompt.d.ts.map +1 -1
  63. package/dist/core/agent-session-prompt.js +114 -21
  64. package/dist/core/agent-session-prompt.js.map +1 -1
  65. package/dist/core/agent-session-runtime.d.ts +1 -1
  66. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  67. package/dist/core/agent-session-runtime.js +6 -0
  68. package/dist/core/agent-session-runtime.js.map +1 -1
  69. package/dist/core/agent-session-state.d.ts +19 -1
  70. package/dist/core/agent-session-state.d.ts.map +1 -1
  71. package/dist/core/agent-session-state.js +41 -6
  72. package/dist/core/agent-session-state.js.map +1 -1
  73. package/dist/core/auth-storage-backends.d.ts +3 -1
  74. package/dist/core/auth-storage-backends.d.ts.map +1 -1
  75. package/dist/core/auth-storage-backends.js +79 -12
  76. package/dist/core/auth-storage-backends.js.map +1 -1
  77. package/dist/core/client-identity.d.ts +8 -0
  78. package/dist/core/client-identity.d.ts.map +1 -0
  79. package/dist/core/client-identity.js +16 -0
  80. package/dist/core/client-identity.js.map +1 -0
  81. package/dist/core/compaction/planner-outcome.d.ts.map +1 -1
  82. package/dist/core/compaction/planner-outcome.js +2 -1
  83. package/dist/core/compaction/planner-outcome.js.map +1 -1
  84. package/dist/core/execution-model-router.d.ts +18 -0
  85. package/dist/core/execution-model-router.d.ts.map +1 -1
  86. package/dist/core/execution-model-router.js +14 -8
  87. package/dist/core/execution-model-router.js.map +1 -1
  88. package/dist/core/extension-oauth-refresh-rejection.d.ts +12 -0
  89. package/dist/core/extension-oauth-refresh-rejection.d.ts.map +1 -0
  90. package/dist/core/extension-oauth-refresh-rejection.js +70 -0
  91. package/dist/core/extension-oauth-refresh-rejection.js.map +1 -0
  92. package/dist/core/extension-startup-failure.d.ts +30 -0
  93. package/dist/core/extension-startup-failure.d.ts.map +1 -0
  94. package/dist/core/extension-startup-failure.js +62 -0
  95. package/dist/core/extension-startup-failure.js.map +1 -0
  96. package/dist/core/extensions/context-types.d.ts +2 -0
  97. package/dist/core/extensions/context-types.d.ts.map +1 -1
  98. package/dist/core/extensions/context-types.js.map +1 -1
  99. package/dist/core/extensions/provider-types.d.ts +2 -0
  100. package/dist/core/extensions/provider-types.d.ts.map +1 -1
  101. package/dist/core/extensions/provider-types.js.map +1 -1
  102. package/dist/core/extensions/runner-context.d.ts +1 -0
  103. package/dist/core/extensions/runner-context.d.ts.map +1 -1
  104. package/dist/core/extensions/runner-context.js +8 -0
  105. package/dist/core/extensions/runner-context.js.map +1 -1
  106. package/dist/core/extensions/runner.d.ts +1 -0
  107. package/dist/core/extensions/runner.d.ts.map +1 -1
  108. package/dist/core/extensions/runner.js +3 -0
  109. package/dist/core/extensions/runner.js.map +1 -1
  110. package/dist/core/extensions/runtime-types.d.ts +1 -0
  111. package/dist/core/extensions/runtime-types.d.ts.map +1 -1
  112. package/dist/core/extensions/runtime-types.js.map +1 -1
  113. package/dist/core/extensions/workflow-run-control-hub.d.ts +1 -0
  114. package/dist/core/extensions/workflow-run-control-hub.d.ts.map +1 -1
  115. package/dist/core/extensions/workflow-run-control-hub.js +3 -0
  116. package/dist/core/extensions/workflow-run-control-hub.js.map +1 -1
  117. package/dist/core/extensions/workflow-run-control.d.ts +8 -0
  118. package/dist/core/extensions/workflow-run-control.d.ts.map +1 -1
  119. package/dist/core/extensions/workflow-run-control.js.map +1 -1
  120. package/dist/core/model-config.d.ts +28 -0
  121. package/dist/core/model-config.d.ts.map +1 -1
  122. package/dist/core/model-fallback-failures.d.ts.map +1 -1
  123. package/dist/core/model-fallback-failures.js +12 -0
  124. package/dist/core/model-fallback-failures.js.map +1 -1
  125. package/dist/core/model-resolver-defaults.js +1 -1
  126. package/dist/core/model-resolver-defaults.js.map +1 -1
  127. package/dist/core/model-runtime-streaming.d.ts.map +1 -1
  128. package/dist/core/model-runtime-streaming.js +9 -3
  129. package/dist/core/model-runtime-streaming.js.map +1 -1
  130. package/dist/core/model-runtime.d.ts +5 -0
  131. package/dist/core/model-runtime.d.ts.map +1 -1
  132. package/dist/core/model-runtime.js +6 -0
  133. package/dist/core/model-runtime.js.map +1 -1
  134. package/dist/core/provider-composer-internal.d.ts +8 -6
  135. package/dist/core/provider-composer-internal.d.ts.map +1 -1
  136. package/dist/core/provider-composer-internal.js +21 -8
  137. package/dist/core/provider-composer-internal.js.map +1 -1
  138. package/dist/core/sdk.d.ts.map +1 -1
  139. package/dist/core/sdk.js +12 -4
  140. package/dist/core/sdk.js.map +1 -1
  141. package/dist/core/storage/session/sql-session-store.d.ts +35 -0
  142. package/dist/core/storage/session/sql-session-store.d.ts.map +1 -1
  143. package/dist/core/storage/session/sql-session-store.js +158 -42
  144. package/dist/core/storage/session/sql-session-store.js.map +1 -1
  145. package/dist/core/structured-output/deadline.d.ts +40 -0
  146. package/dist/core/structured-output/deadline.d.ts.map +1 -0
  147. package/dist/core/structured-output/deadline.js +110 -0
  148. package/dist/core/structured-output/deadline.js.map +1 -0
  149. package/dist/core/structured-output/index.d.ts.map +1 -1
  150. package/dist/core/structured-output/index.js +103 -47
  151. package/dist/core/structured-output/index.js.map +1 -1
  152. package/dist/core/structured-output/rejection-detail.d.ts +9 -0
  153. package/dist/core/structured-output/rejection-detail.d.ts.map +1 -0
  154. package/dist/core/structured-output/rejection-detail.js +129 -0
  155. package/dist/core/structured-output/rejection-detail.js.map +1 -0
  156. package/dist/core/structured-output/types.d.ts +8 -1
  157. package/dist/core/structured-output/types.d.ts.map +1 -1
  158. package/dist/core/structured-output/types.js.map +1 -1
  159. package/dist/core/tasks/completion.d.ts +7 -1
  160. package/dist/core/tasks/completion.d.ts.map +1 -1
  161. package/dist/core/tasks/completion.js +28 -6
  162. package/dist/core/tasks/completion.js.map +1 -1
  163. package/dist/core/tasks/contracts.d.ts +6 -1
  164. package/dist/core/tasks/contracts.d.ts.map +1 -1
  165. package/dist/core/tasks/contracts.js.map +1 -1
  166. package/dist/core/tasks/pause.d.ts +2 -1
  167. package/dist/core/tasks/pause.d.ts.map +1 -1
  168. package/dist/core/tasks/pause.js +3 -2
  169. package/dist/core/tasks/pause.js.map +1 -1
  170. package/dist/core/tools/bash-pty-native.d.ts.map +1 -1
  171. package/dist/core/tools/bash-pty-native.js +10 -5
  172. package/dist/core/tools/bash-pty-native.js.map +1 -1
  173. package/dist/core/tools/bash.d.ts.map +1 -1
  174. package/dist/core/tools/bash.js +16 -32
  175. package/dist/core/tools/bash.js.map +1 -1
  176. package/dist/core/tools/grep.js +1 -1
  177. package/dist/core/tools/grep.js.map +1 -1
  178. package/dist/core/tools/kill.d.ts.map +1 -1
  179. package/dist/core/tools/kill.js +17 -3
  180. package/dist/core/tools/kill.js.map +1 -1
  181. package/dist/core/tools/shell-task-render.d.ts +55 -0
  182. package/dist/core/tools/shell-task-render.d.ts.map +1 -0
  183. package/dist/core/tools/shell-task-render.js +123 -0
  184. package/dist/core/tools/shell-task-render.js.map +1 -0
  185. package/dist/core/tools/shell-task-status.d.ts +52 -0
  186. package/dist/core/tools/shell-task-status.d.ts.map +1 -0
  187. package/dist/core/tools/shell-task-status.js +184 -0
  188. package/dist/core/tools/shell-task-status.js.map +1 -0
  189. package/dist/core/tools/structured-output.d.ts +5 -0
  190. package/dist/core/tools/structured-output.d.ts.map +1 -1
  191. package/dist/core/tools/structured-output.js +3 -0
  192. package/dist/core/tools/structured-output.js.map +1 -1
  193. package/dist/extensions/codemode/execute.d.ts.map +1 -1
  194. package/dist/extensions/codemode/execute.js +134 -57
  195. package/dist/extensions/codemode/execute.js.map +1 -1
  196. package/dist/extensions/mcp/config.d.ts.map +1 -1
  197. package/dist/extensions/mcp/config.js +3 -2
  198. package/dist/extensions/mcp/config.js.map +1 -1
  199. package/dist/index-extensions.d.ts +1 -0
  200. package/dist/index-extensions.d.ts.map +1 -1
  201. package/dist/index-extensions.js +3 -0
  202. package/dist/index-extensions.js.map +1 -1
  203. package/dist/index.d.ts +3 -1
  204. package/dist/index.d.ts.map +1 -1
  205. package/dist/index.js +3 -1
  206. package/dist/index.js.map +1 -1
  207. package/dist/main.d.ts.map +1 -1
  208. package/dist/main.js +19 -6
  209. package/dist/main.js.map +1 -1
  210. package/dist/modes/interactive/components/task-row.d.ts.map +1 -1
  211. package/dist/modes/interactive/components/task-row.js +11 -1
  212. package/dist/modes/interactive/components/task-row.js.map +1 -1
  213. package/dist/modes/interactive/interactive-auth-routing.js +12 -10
  214. package/dist/modes/interactive/interactive-auth-routing.js.map +1 -1
  215. package/dist/modes/interactive/interactive-extension-custom-ui.js +20 -30
  216. package/dist/modes/interactive/interactive-extension-custom-ui.js.map +1 -1
  217. package/dist/modes/interactive/interactive-extension-dialogs.js +23 -96
  218. package/dist/modes/interactive/interactive-extension-dialogs.js.map +1 -1
  219. package/dist/modes/interactive/interactive-extension-runtime.js +7 -8
  220. package/dist/modes/interactive/interactive-extension-runtime.js.map +1 -1
  221. package/dist/modes/interactive/interactive-input-handling.d.ts.map +1 -1
  222. package/dist/modes/interactive/interactive-input-handling.js +27 -4
  223. package/dist/modes/interactive/interactive-input-handling.js.map +1 -1
  224. package/dist/modes/interactive/interactive-mode-base.d.ts +20 -10
  225. package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
  226. package/dist/modes/interactive/interactive-mode-base.js +40 -5
  227. package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
  228. package/dist/modes/interactive/interactive-mode-deps.d.ts +1 -1
  229. package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
  230. package/dist/modes/interactive/interactive-mode-deps.js +1 -1
  231. package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
  232. package/dist/modes/interactive/interactive-mode-surface.d.ts +2 -4
  233. package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
  234. package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
  235. package/dist/modes/interactive/interactive-mode-types.d.ts +4 -1
  236. package/dist/modes/interactive/interactive-mode-types.d.ts.map +1 -1
  237. package/dist/modes/interactive/interactive-mode-types.js.map +1 -1
  238. package/dist/modes/interactive/interactive-prompt-restore.d.ts +3 -0
  239. package/dist/modes/interactive/interactive-prompt-restore.d.ts.map +1 -1
  240. package/dist/modes/interactive/interactive-prompt-restore.js +9 -1
  241. package/dist/modes/interactive/interactive-prompt-restore.js.map +1 -1
  242. package/dist/modes/interactive/interactive-prompt-turn.js +30 -2
  243. package/dist/modes/interactive/interactive-prompt-turn.js.map +1 -1
  244. package/dist/modes/interactive/interactive-queueing.js +43 -8
  245. package/dist/modes/interactive/interactive-queueing.js.map +1 -1
  246. package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
  247. package/dist/modes/interactive/interactive-startup.js +12 -3
  248. package/dist/modes/interactive/interactive-startup.js.map +1 -1
  249. package/dist/modes/interactive/theme/color-utils.d.ts +6 -1
  250. package/dist/modes/interactive/theme/color-utils.d.ts.map +1 -1
  251. package/dist/modes/interactive/theme/color-utils.js +39 -17
  252. package/dist/modes/interactive/theme/color-utils.js.map +1 -1
  253. package/dist/modes/interactive/theme/theme-class.d.ts.map +1 -1
  254. package/dist/modes/interactive/theme/theme-class.js +2 -2
  255. package/dist/modes/interactive/theme/theme-class.js.map +1 -1
  256. package/dist/modes/interactive/theme/theme-tokens.d.ts +6 -0
  257. package/dist/modes/interactive/theme/theme-tokens.d.ts.map +1 -1
  258. package/dist/modes/interactive/theme/theme-tokens.js +7 -3
  259. package/dist/modes/interactive/theme/theme-tokens.js.map +1 -1
  260. package/dist/modes/interactive-engine/isolated-auth.d.ts +3 -0
  261. package/dist/modes/interactive-engine/isolated-auth.d.ts.map +1 -1
  262. package/dist/modes/interactive-engine/isolated-auth.js +13 -1
  263. package/dist/modes/interactive-engine/isolated-auth.js.map +1 -1
  264. package/dist/modes/interactive-engine/isolated-runtime.d.ts.map +1 -1
  265. package/dist/modes/interactive-engine/isolated-runtime.js +11 -2
  266. package/dist/modes/interactive-engine/isolated-runtime.js.map +1 -1
  267. package/dist/modes/interactive-engine/remote-model-catalog.d.ts +8 -0
  268. package/dist/modes/interactive-engine/remote-model-catalog.d.ts.map +1 -1
  269. package/dist/modes/interactive-engine/remote-model-catalog.js +54 -0
  270. package/dist/modes/interactive-engine/remote-model-catalog.js.map +1 -1
  271. package/dist/modes/rpc/rpc-command-handler.d.ts.map +1 -1
  272. package/dist/modes/rpc/rpc-command-handler.js +4 -13
  273. package/dist/modes/rpc/rpc-command-handler.js.map +1 -1
  274. package/dist/modes/rpc/rpc-model-catalog.d.ts +9 -0
  275. package/dist/modes/rpc/rpc-model-catalog.d.ts.map +1 -0
  276. package/dist/modes/rpc/rpc-model-catalog.js +19 -0
  277. package/dist/modes/rpc/rpc-model-catalog.js.map +1 -0
  278. package/dist/modes/rpc/rpc-provider-auth.d.ts.map +1 -1
  279. package/dist/modes/rpc/rpc-provider-auth.js +2 -6
  280. package/dist/modes/rpc/rpc-provider-auth.js.map +1 -1
  281. package/dist/modes/rpc/rpc-types.d.ts +6 -0
  282. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  283. package/dist/modes/rpc/rpc-types.js.map +1 -1
  284. package/dist/utils/changelog.d.ts +6 -0
  285. package/dist/utils/changelog.d.ts.map +1 -1
  286. package/dist/utils/changelog.js +11 -0
  287. package/dist/utils/changelog.js.map +1 -1
  288. package/dist/utils/clipboard.d.ts.map +1 -1
  289. package/dist/utils/clipboard.js +4 -0
  290. package/dist/utils/clipboard.js.map +1 -1
  291. package/dist/utils/tools-manager.d.ts.map +1 -1
  292. package/dist/utils/tools-manager.js +3 -2
  293. package/dist/utils/tools-manager.js.map +1 -1
  294. package/docs/background-tasks.md +5 -3
  295. package/docs/codemode.md +2 -2
  296. package/docs/custom-provider/oauth.md +42 -1
  297. package/docs/custom-provider/registration.md +2 -0
  298. package/docs/environment-variables.md +1 -0
  299. package/docs/extensions/api-reference.md +3 -4
  300. package/docs/extensions/authoring.md +1 -1
  301. package/docs/extensions/events.md +1 -1
  302. package/docs/models-configuration.md +9 -0
  303. package/docs/models.md +3 -1
  304. package/docs/providers.md +4 -4
  305. package/docs/rpc/protocol.md +4 -2
  306. package/docs/sdk/reference.md +2 -0
  307. package/docs/sdk/structured-decisions.md +7 -5
  308. package/docs/sdk.md +5 -2
  309. package/docs/settings.md +4 -2
  310. package/docs/subagents/reference.md +1 -1
  311. package/docs/subagents.md +15 -1
  312. package/docs/themes/reference.md +3 -1
  313. package/docs/usage.md +3 -1
  314. package/docs/workflows/api-reference.md +28 -0
  315. package/docs/workflows/authoring.md +1 -1
  316. package/docs/workflows/operations.md +2 -2
  317. package/npm-shrinkwrap.json +67 -54
  318. package/package.json +6 -6
  319. package/schemas/models.schema.json +21 -0
  320. package/dist/core/provider-attribution.d.ts +0 -4
  321. package/dist/core/provider-attribution.d.ts.map +0 -1
  322. package/dist/core/provider-attribution.js +0 -87
  323. package/dist/core/provider-attribution.js.map +0 -1
@@ -11,7 +11,7 @@ ${KEEP_CONTEXT_CLOSE_TAG}`;
11
11
  }
12
12
  // dist/builtin/workflows/src/authoring/workflow.ts
13
13
  import { basename } from "node:path";
14
- import { fileURLToPath } from "node:url";
14
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
15
15
 
16
16
  // dist/builtin/workflows/src/shared/budget.ts
17
17
  function enforceDurationBudget(reading, budget, options = {}) {
@@ -87,6 +87,89 @@ function resolve_budget(layers) {
87
87
  var DEFAULT_WORKFLOW_HEARTBEAT_INTERVAL_MINUTES = 15;
88
88
  var WORKFLOW_HEARTBEAT_CUSTOM_TYPE = "workflows:workflow-heartbeat";
89
89
 
90
+ // dist/builtin/workflows/src/runs/shared/prompt-callsite.ts
91
+ import { fileURLToPath } from "node:url";
92
+ var PACKAGED_WORKFLOW_RUNTIME_ROOTS = ["/dist/builtin/workflows/src/"];
93
+ function normalizeSlashes(path) {
94
+ return path.replace(/\\/g, "/");
95
+ }
96
+ function normalizeStackPath(framePath) {
97
+ let normalized = framePath;
98
+ if (normalized.startsWith("file://")) {
99
+ try {
100
+ normalized = fileURLToPath(normalized);
101
+ } catch {
102
+ try {
103
+ normalized = decodeURIComponent(new URL(normalized).pathname);
104
+ } catch {}
105
+ }
106
+ }
107
+ normalized = normalizeSlashes(normalized).replace(/^\/([A-Za-z]:\/)/, "$1");
108
+ return normalized;
109
+ }
110
+ function currentModuleRuntimeRoot() {
111
+ const modulePath = normalizeStackPath(fileURLToPath(import.meta.url));
112
+ const markers = ["packages/workflows/src/", ...PACKAGED_WORKFLOW_RUNTIME_ROOTS.map((root) => root.slice(1))];
113
+ for (const marker of markers) {
114
+ const index = modulePath.indexOf(marker);
115
+ if (index >= 0)
116
+ return modulePath.slice(0, index + marker.length);
117
+ }
118
+ return;
119
+ }
120
+ var CURRENT_WORKFLOW_RUNTIME_ROOT = currentModuleRuntimeRoot();
121
+ function isWorkflowRuntimeFrame(normalizedPath) {
122
+ const path = normalizeSlashes(normalizedPath);
123
+ if (path.startsWith("packages/workflows/src/"))
124
+ return true;
125
+ if (CURRENT_WORKFLOW_RUNTIME_ROOT !== undefined && path.startsWith(CURRENT_WORKFLOW_RUNTIME_ROOT)) {
126
+ return true;
127
+ }
128
+ const comparable = path.startsWith("/") ? path : `/${path}`;
129
+ return PACKAGED_WORKFLOW_RUNTIME_ROOTS.some((runtimeRoot) => comparable.includes(runtimeRoot));
130
+ }
131
+ function parsePromptStackFrame(stackLine) {
132
+ const line = stackLine.trim();
133
+ if (line.length === 0)
134
+ return;
135
+ if (line.includes("node:internal") || line.includes("bun:") || line.includes("(native:"))
136
+ return;
137
+ const match = line.match(/(\S+):(\d+):(\d+)\)?$/);
138
+ if (!match)
139
+ return;
140
+ const [, rawFramePath, lineNumber, columnNumber] = match;
141
+ if (rawFramePath === undefined || lineNumber === undefined || columnNumber === undefined)
142
+ return;
143
+ const normalizedPath = normalizeStackPath(rawFramePath.replace(/^\(/, ""));
144
+ return { normalizedPath, lineNumber, columnNumber };
145
+ }
146
+ function normalizedPromptCallsiteFrame(stackLine) {
147
+ const frame = parsePromptStackFrame(stackLine);
148
+ if (frame === undefined)
149
+ return;
150
+ if (isWorkflowRuntimeFrame(frame.normalizedPath))
151
+ return;
152
+ return `${frame.normalizedPath}:${frame.lineNumber}:${frame.columnNumber}`;
153
+ }
154
+ function selectPromptCallsiteFrame(stack) {
155
+ return stack.split(`
156
+ `).slice(1).map(normalizedPromptCallsiteFrame).find((candidate) => candidate !== undefined);
157
+ }
158
+
159
+ // dist/builtin/workflows/src/shared/workflow-source.ts
160
+ var WORKFLOW_SOURCES = new WeakMap;
161
+ var OWN_MODULE_PATH = normalizeStackPath(import.meta.url);
162
+ function isWorkflowRuntimeModule(path) {
163
+ const normalized = normalizeStackPath(path);
164
+ return normalized === OWN_MODULE_PATH || isWorkflowRuntimeFrame(normalized);
165
+ }
166
+ function recordWorkflowSource(definition, path) {
167
+ WORKFLOW_SOURCES.set(definition, path);
168
+ }
169
+ function workflowSource(definition) {
170
+ return WORKFLOW_SOURCES.get(definition);
171
+ }
172
+
90
173
  // dist/builtin/workflows/src/workflows/identity.ts
91
174
  function normalizeWorkflowName(name) {
92
175
  if (!name || typeof name !== "string") {
@@ -123,7 +206,7 @@ function stackFilePath(line) {
123
206
  if (!rawPath.startsWith("file://"))
124
207
  return rawPath;
125
208
  try {
126
- return fileURLToPath(rawPath);
209
+ return fileURLToPath2(rawPath);
127
210
  } catch {
128
211
  return;
129
212
  }
@@ -134,8 +217,10 @@ function isWorkflowAuthoringImplementationFrame(filePath) {
134
217
  return false;
135
218
  return normalized.includes("/packages/workflows/") || normalized.includes("/dist/builtin/workflows/") || normalized.includes("/.atomic/agent/extensions/workflows/");
136
219
  }
137
- function workflowNameFromCaller() {
138
- const stack = new Error().stack;
220
+ function callerSourcePath(entry) {
221
+ const capture = new Error;
222
+ Error.captureStackTrace(capture, entry);
223
+ const stack = capture.stack;
139
224
  if (stack === undefined)
140
225
  return;
141
226
  for (const line of stack.split(`
@@ -145,14 +230,18 @@ function workflowNameFromCaller() {
145
230
  continue;
146
231
  if (isWorkflowAuthoringImplementationFrame(filePath))
147
232
  continue;
148
- const base = basename(filePath.replace(/\\/g, "/")).replace(/\.[cm]?[jt]sx?$/, "");
149
- if (base.length > 0)
150
- return base;
233
+ return isWorkflowRuntimeModule(filePath) ? undefined : filePath;
151
234
  }
152
235
  return;
153
236
  }
154
- function resolveWorkflowName(name) {
155
- const resolved = name ?? workflowNameFromCaller();
237
+ function workflowNameFromSourcePath(filePath) {
238
+ if (filePath === undefined)
239
+ return;
240
+ const base = basename(filePath.replace(/\\/g, "/")).replace(/\.[cm]?[jt]sx?$/, "");
241
+ return base.length > 0 ? base : undefined;
242
+ }
243
+ function resolveWorkflowName(name, sourcePath) {
244
+ const resolved = name ?? workflowNameFromSourcePath(sourcePath);
156
245
  if (resolved === undefined) {
157
246
  throw new TypeError("workflow: name must be provided when caller filename cannot be inferred");
158
247
  }
@@ -188,7 +277,8 @@ function workflow(spec) {
188
277
  throw new TypeError("workflow: heartbeatIntervalMinutes must be a non-negative finite number");
189
278
  }
190
279
  assertWorkflowBudget(spec.budget, "workflow: budget");
191
- const name = resolveWorkflowName(spec.name);
280
+ const source = callerSourcePath(workflow);
281
+ const name = resolveWorkflowName(spec.name, source);
192
282
  const normalizedName = normalizeWorkflowName(name);
193
283
  requireNonEmptyString(normalizedName, "normalized name");
194
284
  const frozenInputs = freezeSchemaMap(spec.inputs ?? {});
@@ -210,6 +300,8 @@ function workflow(spec) {
210
300
  run
211
301
  };
212
302
  const branded = stampWorkflowDefinition(definition);
303
+ if (source !== undefined)
304
+ recordWorkflowSource(branded, source);
213
305
  return Object.freeze(branded);
214
306
  }
215
307
  // dist/builtin/workflows/src/durable/journal/conformance.ts
@@ -823,6 +915,13 @@ function registerRunJournalConformance(runner, name, open, observeRead) {
823
915
  }
824
916
  // dist/builtin/workflows/src/durable/journal/internal.ts
825
917
  var JOURNAL_READ_PAGE_SIZE = 256;
918
+ var versionReaders = new WeakMap;
919
+ function registerRunJournalVersions(journal, versions) {
920
+ versionReaders.set(journal, versions);
921
+ }
922
+ function runJournalVersions(journal) {
923
+ return versionReaders.get(journal);
924
+ }
826
925
 
827
926
  // dist/builtin/workflows/src/durable/journal/lease-expiry.ts
828
927
  function isWorkflowLeaseExpired(renewedAt, staleAfterMs, now = Date.now()) {
@@ -1107,6 +1206,10 @@ var LEGACY_COLUMNS = {
1107
1206
  var PENDING_LEGACY_RUNS = `SELECT ${JOURNAL_COLUMNS.runId}, ${JOURNAL_COLUMNS.headerJson}, ${JOURNAL_COLUMNS.status} FROM ${JOURNAL_TABLES.runs}
1108
1207
  WHERE ${JOURNAL_COLUMNS.runId} NOT IN (SELECT ${JOURNAL_COLUMNS.runId} FROM ${CURRENT.runs})
1109
1208
  AND ${JOURNAL_COLUMNS.runId} NOT IN (SELECT ${JOURNAL_COLUMNS.runId} FROM ${CURRENT.legacyDeleted})`;
1209
+ function latestEventColumns(events, runs) {
1210
+ const latest = (column) => `COALESCE((SELECT ${column} FROM ${events} AS latest WHERE latest.${JOURNAL_COLUMNS.runId} = ${runs}.${JOURNAL_COLUMNS.runId} ORDER BY latest.${JOURNAL_COLUMNS.seq} DESC LIMIT 1), 0) AS ${column}`;
1211
+ return `${latest(JOURNAL_COLUMNS.seq)}, ${latest(JOURNAL_COLUMNS.at)}`;
1212
+ }
1110
1213
  async function hasLegacyTable(tx, table) {
1111
1214
  const columns = await tx.all("SELECT name FROM pragma_table_info(?)", JOURNAL_TABLES[table]);
1112
1215
  const names = new Set(columns.map((column) => column.name));
@@ -1140,6 +1243,9 @@ class LegacyJournalRuns {
1140
1243
  async find(executor, runId) {
1141
1244
  return executor.get(`${PENDING_LEGACY_RUNS} AND ${JOURNAL_COLUMNS.runId} = ?`, runId);
1142
1245
  }
1246
+ async versions(executor) {
1247
+ return executor.all(`SELECT pending.${JOURNAL_COLUMNS.runId}, ${latestEventColumns(JOURNAL_TABLES.events, "pending")} FROM (${PENDING_LEGACY_RUNS}) AS pending`);
1248
+ }
1143
1249
  async events(executor, runId, fromSeq, limit) {
1144
1250
  return executor.all(`SELECT ${LEGACY_COLUMNS.events.join(", ")} FROM ${JOURNAL_TABLES.events} WHERE ${JOURNAL_COLUMNS.runId} = ? AND ${JOURNAL_COLUMNS.seq} >= ? ORDER BY ${JOURNAL_COLUMNS.seq} LIMIT ?`, runId, fromSeq, limit);
1145
1251
  }
@@ -1190,6 +1296,10 @@ class SqlRunJournal {
1190
1296
  this.database = database;
1191
1297
  this.tables = tables;
1192
1298
  this.legacy = legacy;
1299
+ registerRunJournalVersions(this, {
1300
+ changeToken: () => this.changeToken(),
1301
+ runVersions: () => this.runVersions()
1302
+ });
1193
1303
  }
1194
1304
  static async open(database, options = {}) {
1195
1305
  const t = renderStorageIdentifiers2("journal", JOURNAL_TABLES, options.prefix);
@@ -1288,6 +1398,27 @@ class SqlRunJournal {
1288
1398
  return [...rows, ...legacy].map((row) => ({ ...JSON.parse(row[JOURNAL_COLUMNS.headerJson]), status: row[JOURNAL_COLUMNS.status] })).sort((left, right) => left.runId < right.runId ? -1 : left.runId > right.runId ? 1 : 0);
1289
1399
  });
1290
1400
  }
1401
+ async changeToken() {
1402
+ this.assertOpen();
1403
+ return this.operation(async () => {
1404
+ const row = await this.database.get(`SELECT data_version, total_changes() AS changes,
1405
+ (SELECT count(*) FROM ${this.tables.runs}) AS runs,
1406
+ (SELECT max(rowid) FROM ${this.tables.events}) AS last_event
1407
+ FROM pragma_data_version`);
1408
+ return JSON.stringify(Object.values(row ?? {}).map(String));
1409
+ });
1410
+ }
1411
+ async runVersions() {
1412
+ this.assertOpen();
1413
+ return this.operation(async () => {
1414
+ const rows = await this.database.all(`SELECT runs.${JOURNAL_COLUMNS.runId}, ${latestEventColumns(this.tables.events, "runs")} FROM ${this.tables.runs} AS runs`);
1415
+ const legacy = await this.legacy?.versions(this.database) ?? [];
1416
+ return new Map([...rows, ...legacy].map((row) => [
1417
+ row[JOURNAL_COLUMNS.runId],
1418
+ { seq: journalCounter(row[JOURNAL_COLUMNS.runId], "seq", row[JOURNAL_COLUMNS.seq]), at: Number(row[JOURNAL_COLUMNS.at]) }
1419
+ ]));
1420
+ });
1421
+ }
1291
1422
  async requireRun(tx, runId) {
1292
1423
  if (await tx.get(`SELECT ${JOURNAL_COLUMNS.runId} FROM ${this.tables.runs} WHERE ${JOURNAL_COLUMNS.runId} = ?`, runId))
1293
1424
  return;
@@ -1669,6 +1800,7 @@ import { join as join3 } from "node:path";
1669
1800
  import {
1670
1801
  isStaleExtensionContextError,
1671
1802
  ModelRuntime,
1803
+ noOpUIContext,
1672
1804
  resolveRestoredModelReference
1673
1805
  } from "@bastani/atomic";
1674
1806
 
@@ -4978,7 +5110,14 @@ function stripWorkflowOnlyOptions(options) {
4978
5110
  if (!options)
4979
5111
  return options;
4980
5112
  const maybeWorkflowOptions = options;
4981
- const { schema: _schema, mcp: _mcp, fallbackModels, group: _group, ...sessionOptions } = maybeWorkflowOptions;
5113
+ const {
5114
+ schema: _schema,
5115
+ schemaTimeoutMs: _schemaTimeoutMs,
5116
+ mcp: _mcp,
5117
+ fallbackModels,
5118
+ group: _group,
5119
+ ...sessionOptions
5120
+ } = maybeWorkflowOptions;
4982
5121
  return fallbackModels?.length === 0 ? { ...sessionOptions, fallbackModels: [] } : sessionOptions;
4983
5122
  }
4984
5123
  function emitLateIntercomRoute(pi, meta, messages, options, batch) {
@@ -5095,6 +5234,7 @@ function makeStageExtensionUiContext(ui, meta, broker, inheritedBindingRevision,
5095
5234
  notify: ui.notify ?? (() => {
5096
5235
  return;
5097
5236
  }),
5237
+ requestRender: noOpUIContext.requestRender,
5098
5238
  onTerminalInput: ui.onTerminalInput ?? (() => () => {
5099
5239
  return;
5100
5240
  }),
@@ -5154,7 +5294,7 @@ function makeStageExtensionUiContext(ui, meta, broker, inheritedBindingRevision,
5154
5294
  getEditorComponent: ui.getEditorComponent ?? (() => {
5155
5295
  return;
5156
5296
  }),
5157
- theme: ui.theme,
5297
+ theme: ui.theme ?? noOpUIContext.theme,
5158
5298
  getAllThemes: ui.getAllThemes ?? (() => []),
5159
5299
  getTheme: ui.getTheme ?? (() => {
5160
5300
  return;
@@ -5164,9 +5304,8 @@ function makeStageExtensionUiContext(ui, meta, broker, inheritedBindingRevision,
5164
5304
  setToolsExpanded: ui.setToolsExpanded ?? (() => {
5165
5305
  return;
5166
5306
  }),
5167
- getChatRenderSettings: ui.getChatRenderSettings ?? (() => {
5168
- return;
5169
- })
5307
+ getFooterDataProvider: noOpUIContext.getFooterDataProvider,
5308
+ getChatRenderSettings: ui.getChatRenderSettings ?? noOpUIContext.getChatRenderSettings
5170
5309
  };
5171
5310
  }
5172
5311
  function findStageModel(runtime, reference) {
@@ -5909,75 +6048,6 @@ function buildStagePromptAdapter(id, kind, args, createdAt) {
5909
6048
  };
5910
6049
  }
5911
6050
 
5912
- // dist/builtin/workflows/src/runs/shared/prompt-callsite.ts
5913
- import { fileURLToPath as fileURLToPath2 } from "node:url";
5914
- var PACKAGED_WORKFLOW_RUNTIME_ROOTS = ["/dist/builtin/workflows/src/"];
5915
- function normalizeSlashes(path) {
5916
- return path.replace(/\\/g, "/");
5917
- }
5918
- function normalizeStackPath(framePath) {
5919
- let normalized = framePath;
5920
- if (normalized.startsWith("file://")) {
5921
- try {
5922
- normalized = fileURLToPath2(normalized);
5923
- } catch {
5924
- try {
5925
- normalized = decodeURIComponent(new URL(normalized).pathname);
5926
- } catch {}
5927
- }
5928
- }
5929
- normalized = normalizeSlashes(normalized).replace(/^\/([A-Za-z]:\/)/, "$1");
5930
- return normalized;
5931
- }
5932
- function currentModuleRuntimeRoot() {
5933
- const modulePath = normalizeStackPath(fileURLToPath2(import.meta.url));
5934
- const markers = ["packages/workflows/src/", ...PACKAGED_WORKFLOW_RUNTIME_ROOTS.map((root) => root.slice(1))];
5935
- for (const marker of markers) {
5936
- const index = modulePath.indexOf(marker);
5937
- if (index >= 0)
5938
- return modulePath.slice(0, index + marker.length);
5939
- }
5940
- return;
5941
- }
5942
- var CURRENT_WORKFLOW_RUNTIME_ROOT = currentModuleRuntimeRoot();
5943
- function isWorkflowRuntimeFrame(normalizedPath) {
5944
- const path = normalizeSlashes(normalizedPath);
5945
- if (path.startsWith("packages/workflows/src/"))
5946
- return true;
5947
- if (CURRENT_WORKFLOW_RUNTIME_ROOT !== undefined && path.startsWith(CURRENT_WORKFLOW_RUNTIME_ROOT)) {
5948
- return true;
5949
- }
5950
- const comparable = path.startsWith("/") ? path : `/${path}`;
5951
- return PACKAGED_WORKFLOW_RUNTIME_ROOTS.some((runtimeRoot) => comparable.includes(runtimeRoot));
5952
- }
5953
- function parsePromptStackFrame(stackLine) {
5954
- const line = stackLine.trim();
5955
- if (line.length === 0)
5956
- return;
5957
- if (line.includes("node:internal") || line.includes("bun:") || line.includes("(native:"))
5958
- return;
5959
- const match = line.match(/(\S+):(\d+):(\d+)\)?$/);
5960
- if (!match)
5961
- return;
5962
- const [, rawFramePath, lineNumber, columnNumber] = match;
5963
- if (rawFramePath === undefined || lineNumber === undefined || columnNumber === undefined)
5964
- return;
5965
- const normalizedPath = normalizeStackPath(rawFramePath.replace(/^\(/, ""));
5966
- return { normalizedPath, lineNumber, columnNumber };
5967
- }
5968
- function normalizedPromptCallsiteFrame(stackLine) {
5969
- const frame = parsePromptStackFrame(stackLine);
5970
- if (frame === undefined)
5971
- return;
5972
- if (isWorkflowRuntimeFrame(frame.normalizedPath))
5973
- return;
5974
- return `${frame.normalizedPath}:${frame.lineNumber}:${frame.columnNumber}`;
5975
- }
5976
- function selectPromptCallsiteFrame(stack) {
5977
- return stack.split(`
5978
- `).slice(1).map(normalizedPromptCallsiteFrame).find((candidate) => candidate !== undefined);
5979
- }
5980
-
5981
6051
  // dist/builtin/workflows/src/shared/resume-continuation.ts
5982
6052
  var RESUME_CONTINUATION_PROMPT = "Continue where you left off. If you believe you are finished with your original task (or a redefined task if the user told you), stop.";
5983
6053
 
@@ -6331,6 +6401,10 @@ function schemaIsRequired(schema) {
6331
6401
 
6332
6402
  // dist/builtin/workflows/src/runs/shared/validate-inputs.ts
6333
6403
  import { Value as Value2 } from "typebox/value";
6404
+ function firstSchemaError(def, value, kind) {
6405
+ const first = [...Value2.Errors(def, value)][0];
6406
+ return first === undefined ? `does not match ${kind} schema` : first.message;
6407
+ }
6334
6408
  function validateInputs(schema, inputs) {
6335
6409
  const errors = [];
6336
6410
  for (const key of Object.keys(inputs)) {
@@ -6359,12 +6433,16 @@ function validateInputs(schema, inputs) {
6359
6433
  if (typeof value !== "number" || !Number.isFinite(value)) {
6360
6434
  errors.push({ key, reason: `expected finite number, got ${workflowSerializableTypeName(value)}` });
6361
6435
  hasTypeError = true;
6436
+ } else if (!Value2.Check(def, value)) {
6437
+ errors.push({ key, reason: firstSchemaError(def, value, kind) });
6362
6438
  }
6363
6439
  break;
6364
6440
  case "integer":
6365
6441
  if (typeof value !== "number" || !Number.isInteger(value)) {
6366
6442
  errors.push({ key, reason: `expected integer, got ${workflowSerializableTypeName(value)}` });
6367
6443
  hasTypeError = true;
6444
+ } else if (!Value2.Check(def, value)) {
6445
+ errors.push({ key, reason: firstSchemaError(def, value, kind) });
6368
6446
  }
6369
6447
  break;
6370
6448
  case "boolean":
@@ -9492,6 +9570,8 @@ class JournalDurableBackend {
9492
9570
  persistent;
9493
9571
  projection = createJournalProjection();
9494
9572
  sequences = new Map;
9573
+ foldedAt = new Map;
9574
+ catalogToken;
9495
9575
  leases = new Map;
9496
9576
  executions = new Map;
9497
9577
  executionContext = new AsyncLocalStorage2;
@@ -9535,7 +9615,7 @@ class JournalDurableBackend {
9535
9615
  try {
9536
9616
  this.ensureOpen();
9537
9617
  if (requiresActiveExecution)
9538
- this.assertExecutionActive(runId);
9618
+ this.assertExecutionActive();
9539
9619
  } catch (error) {
9540
9620
  return Promise.reject(error);
9541
9621
  }
@@ -9588,6 +9668,7 @@ class JournalDurableBackend {
9588
9668
  this.projection.applyWorkflowSnapshot({ ...handle, pendingStageMessages: messages });
9589
9669
  }
9590
9670
  this.sequences.set(entry.runId, entry.seq);
9671
+ this.foldedAt.set(entry.runId, entry.at);
9591
9672
  }
9592
9673
  *entries(runId, fromSeq) {
9593
9674
  return yield* invoke(async () => {
@@ -9601,6 +9682,7 @@ class JournalDurableBackend {
9601
9682
  const entries = yield* this.entries(runId);
9602
9683
  this.projection.deleteWorkflow(runId);
9603
9684
  this.sequences.delete(runId);
9685
+ this.foldedAt.delete(runId);
9604
9686
  this.prompts.delete(runId);
9605
9687
  for (const entry of entries)
9606
9688
  this.fold(entry);
@@ -9613,7 +9695,7 @@ class JournalDurableBackend {
9613
9695
  }
9614
9696
  *current(runId) {
9615
9697
  this.ensureOpen();
9616
- this.assertExecutionActive(runId, true);
9698
+ this.assertExecutionActive(true);
9617
9699
  yield* this.refresh(runId);
9618
9700
  if (this.projection.getWorkflow(runId) === undefined)
9619
9701
  return;
@@ -9632,14 +9714,14 @@ class JournalDurableBackend {
9632
9714
  if (this.state === "closed" || this.state === "closing" && !this.mutationContext.getStore())
9633
9715
  throw new JournalBackendClosedError;
9634
9716
  }
9635
- assertExecutionActive(runId, admitted = false) {
9717
+ assertExecutionActive(admitted = false) {
9636
9718
  for (const [executionRunId, execution] of this.executionContext.getStore() ?? [])
9637
9719
  if (execution.retired && !(admitted && this.mutationContext.getStore()?.has(execution)))
9638
- throw new JournalExecutionRetiredError(typeof runId === "string" ? runId : executionRunId);
9720
+ throw new JournalExecutionRetiredError(executionRunId);
9639
9721
  }
9640
9722
  *ownership(runId) {
9641
9723
  this.ensureOpen();
9642
- this.assertExecutionActive(runId, true);
9724
+ this.assertExecutionActive(true);
9643
9725
  const lost = this.lost.get(runId);
9644
9726
  if (lost)
9645
9727
  throw lost;
@@ -9699,7 +9781,7 @@ class JournalDurableBackend {
9699
9781
  return this.serialize(input.workflowId, () => this.register(input));
9700
9782
  }
9701
9783
  *register(input) {
9702
- this.assertExecutionActive(input.workflowId, true);
9784
+ this.assertExecutionActive(true);
9703
9785
  this.ensureOpen();
9704
9786
  const header = {
9705
9787
  runId: input.workflowId,
@@ -9923,11 +10005,36 @@ class JournalDurableBackend {
9923
10005
  }
9924
10006
  hydrateResumableWorkflows() {
9925
10007
  return this.serialize(this.catalogQueue, () => invoke(async () => {
9926
- const runs = await this.journal.listRuns();
9927
- for (const runId of new Set([...this.sequences.keys(), ...runs.map((run) => run.runId)]))
9928
- await this.hydrateWorkflow(runId);
10008
+ const journal = runJournalVersions(this.journal);
10009
+ if (journal === undefined) {
10010
+ const runs = await this.journal.listRuns();
10011
+ for (const runId of new Set([...this.sequences.keys(), ...runs.map((run) => run.runId)]))
10012
+ await this.hydrateWorkflow(runId);
10013
+ return;
10014
+ }
10015
+ const token = await journal.changeToken();
10016
+ if (token === this.catalogToken)
10017
+ return;
10018
+ const versions = await journal.runVersions();
10019
+ for (const runId of new Set([...this.sequences.keys(), ...versions.keys()]))
10020
+ await this.serialize(runId, () => this.catchUp(runId, versions.get(runId)), false);
10021
+ this.catalogToken = token;
9929
10022
  }));
9930
10023
  }
10024
+ *catchUp(runId, version) {
10025
+ const folded = this.sequences.get(runId) ?? 0;
10026
+ if (version !== undefined && version.seq === folded && version.at === (this.foldedAt.get(runId) ?? 0))
10027
+ return;
10028
+ if (version !== undefined && folded > 0 && version.seq > folded) {
10029
+ const entries = yield* this.entries(runId, folded);
10030
+ if (entries[0]?.seq === folded && entries[0].at === this.foldedAt.get(runId)) {
10031
+ for (const entry of entries)
10032
+ this.fold(entry);
10033
+ return;
10034
+ }
10035
+ }
10036
+ yield* this.rebuild(runId);
10037
+ }
9931
10038
  async prepareWorkflowCatalog() {
9932
10039
  await this.hydrateResumableWorkflows();
9933
10040
  return this.projection.prepareWorkflowCatalog();
@@ -9945,6 +10052,7 @@ class JournalDurableBackend {
9945
10052
  }
9946
10053
  this.leases.delete(runId);
9947
10054
  this.sequences.delete(runId);
10055
+ this.foldedAt.delete(runId);
9948
10056
  this.prompts.delete(runId);
9949
10057
  this.projection.deleteWorkflow(runId);
9950
10058
  }
@@ -10037,7 +10145,7 @@ class JournalDurableBackend {
10037
10145
  }
10038
10146
  async withWorkflowLease(runId, action) {
10039
10147
  this.ensureOpen();
10040
- this.assertExecutionActive(runId);
10148
+ this.assertExecutionActive();
10041
10149
  const context = this.executionContext.getStore();
10042
10150
  const active = this.executions.get(runId);
10043
10151
  if (active !== undefined && context?.get(runId) !== active)
@@ -10072,7 +10180,7 @@ class JournalDurableBackend {
10072
10180
  return this.serialize(runId, () => this.release(runId, execution), false);
10073
10181
  }
10074
10182
  releaseWorkflow(runId) {
10075
- this.assertExecutionActive(runId);
10183
+ this.assertExecutionActive();
10076
10184
  return this.serialize(runId, () => this.release(runId));
10077
10185
  }
10078
10186
  *release(runId, execution) {
@@ -12574,7 +12682,12 @@ async function mapParallelSteps(steps, concurrency, failFast, mapper, onFirstFai
12574
12682
  if (selectedFailure !== undefined)
12575
12683
  throw selectedFailure;
12576
12684
  }
12577
- throw new AggregateError(failures.map((failure) => failure.error), `atomic-workflows: ${failures.length} parallel ${failures.length === 1 ? "step" : "steps"} failed`);
12685
+ const aggregate = new AggregateError(failures.map((failure) => failure.error), `atomic-workflows: ${failures.length} parallel ${failures.length === 1 ? "step" : "steps"} failed`);
12686
+ if (failFastEnabled)
12687
+ throw aggregate;
12688
+ const failedIndexes = new Set(failures.map((failure) => failure.index));
12689
+ const partialResults = Array.from({ length: steps.length }, (_, index) => failedIndexes.has(index) ? undefined : results[index]);
12690
+ throw Object.assign(aggregate, { partialResults });
12578
12691
  }
12579
12692
  return results;
12580
12693
  }
@@ -14374,13 +14487,24 @@ class ConcurrencyLimiter {
14374
14487
  get queued() {
14375
14488
  return this._queue.length;
14376
14489
  }
14377
- acquire() {
14490
+ acquire(signal) {
14491
+ if (signal?.aborted)
14492
+ return Promise.reject(signal.reason);
14378
14493
  if (this._running < this.limit) {
14379
14494
  this._running++;
14380
14495
  return Promise.resolve();
14381
14496
  }
14382
- return new Promise((resolve) => {
14383
- this._queue.push(resolve);
14497
+ return new Promise((resolve, reject) => {
14498
+ const grant = () => {
14499
+ signal?.removeEventListener("abort", onAbort);
14500
+ resolve();
14501
+ };
14502
+ const onAbort = () => {
14503
+ this._queue.splice(this._queue.indexOf(grant), 1);
14504
+ reject(signal?.reason);
14505
+ };
14506
+ this._queue.push(grant);
14507
+ signal?.addEventListener("abort", onAbort, { once: true });
14384
14508
  });
14385
14509
  }
14386
14510
  release() {
@@ -14391,8 +14515,8 @@ class ConcurrencyLimiter {
14391
14515
  this._running--;
14392
14516
  }
14393
14517
  }
14394
- async run(fn) {
14395
- await this.acquire();
14518
+ async run(fn, signal) {
14519
+ await this.acquire(signal);
14396
14520
  try {
14397
14521
  return await fn();
14398
14522
  } finally {
@@ -14592,6 +14716,7 @@ function createWorkflowExitManager(input) {
14592
14716
  ...outputSnapshot !== undefined ? { outputSnapshot } : {},
14593
14717
  ...validationError !== undefined ? { validationError } : {}
14594
14718
  }));
14719
+ input.onExitSelected?.(selectedExit);
14595
14720
  input.controller.abort(selectedExit);
14596
14721
  runWorkflowExitCleanups(reason);
14597
14722
  throw selectedExit;
@@ -15355,6 +15480,22 @@ function createChildWorkflowRunner(input) {
15355
15480
  }
15356
15481
  };
15357
15482
  }
15483
+ // dist/builtin/workflows/src/shared/error-with-causes.ts
15484
+ var MAX_CAUSE_DEPTH = 5;
15485
+ function describeErrorWithCauses(error) {
15486
+ const messages = [];
15487
+ const visited = new Set;
15488
+ let current = error;
15489
+ for (let depth = 0;current !== undefined && depth < MAX_CAUSE_DEPTH && !visited.has(current); depth++) {
15490
+ visited.add(current);
15491
+ const message = current instanceof Error ? current.message : String(current);
15492
+ if (!messages.includes(message))
15493
+ messages.push(message);
15494
+ current = current instanceof Error ? current.cause : undefined;
15495
+ }
15496
+ return messages.join(": ");
15497
+ }
15498
+
15358
15499
  // dist/builtin/workflows/src/shared/returned-run-status.ts
15359
15500
  var RETURNED_BLOCKED_STATUSES = new Set([
15360
15501
  "blocked",
@@ -15452,12 +15593,22 @@ function stringResultField(result, key) {
15452
15593
 
15453
15594
  // dist/builtin/workflows/src/engine/run-durable-finalize.ts
15454
15595
  async function finalizeDurableTerminalStatus(input) {
15596
+ try {
15597
+ await commitDurableTerminalStatus(input);
15598
+ } catch (error) {
15599
+ if (input.store !== undefined)
15600
+ recordDurableEndingFailure(input.store, input.runSnapshot, error);
15601
+ throw error;
15602
+ }
15603
+ }
15604
+ async function commitDurableTerminalStatus(input) {
15455
15605
  if (!input.isRoot)
15456
15606
  return;
15457
15607
  const status = effectiveRunStatus(input.runSnapshot);
15458
15608
  const isExitTerminal = input.runSnapshot.exited === true && status !== "running";
15459
15609
  const isBlocked = status === "blocked" && (input.runSnapshot.endedAt !== undefined || input.runSnapshot.blockedAt !== undefined);
15460
- if (status !== "failed" && status !== "killed" && !isExitTerminal && !isBlocked)
15610
+ const isUncommittedCompletion = status === "completed" && input.terminalStatusCommitted === false;
15611
+ if (status !== "failed" && status !== "killed" && !isExitTerminal && !isBlocked && !isUncommittedCompletion)
15461
15612
  return;
15462
15613
  const durableStatus = toDurableStatus(status);
15463
15614
  if (durableStatus !== undefined) {
@@ -15467,7 +15618,7 @@ async function finalizeDurableTerminalStatus(input) {
15467
15618
  if (input.runSnapshot.result !== undefined)
15468
15619
  throw error;
15469
15620
  }
15470
- if (durableStatus === "failed" || durableStatus === "blocked") {
15621
+ if (durableStatus === "failed" || durableStatus === "blocked" || isUncommittedCompletion) {
15471
15622
  await recordRunTimingCheckpointAsync(input.durableBackend, input.runSnapshot);
15472
15623
  }
15473
15624
  const failure = durableStatus === "failed" ? {
@@ -15485,6 +15636,16 @@ async function finalizeDurableTerminalStatus(input) {
15485
15636
  await input.durableBackend.commitWorkflowStatus(input.runId, durableStatus, undefined, input.runSnapshot.resumable, failure);
15486
15637
  }
15487
15638
  }
15639
+ function recordDurableEndingFailure(store, runSnapshot, error) {
15640
+ const detail = describeErrorWithCauses(error);
15641
+ store.recordNotice({
15642
+ id: `workflow-durable-ending-failed:${runSnapshot.id}`,
15643
+ runId: runSnapshot.id,
15644
+ level: "error",
15645
+ message: `Workflow "${runSnapshot.name}" ended ${runSnapshot.status}, but its final state could not be saved to the workflow journal: ${detail}. Readers of the journal may report it as crashed.`,
15646
+ createdAt: Date.now()
15647
+ });
15648
+ }
15488
15649
  function toDurableStatus(status) {
15489
15650
  switch (status) {
15490
15651
  case "completed":
@@ -15777,7 +15938,7 @@ function compareDraftSourceOrder(left, right) {
15777
15938
  function runTopologyFor(drafts, tools) {
15778
15939
  return drafts.find((draft) => draft.topology?.run !== undefined)?.topology?.run ?? tools.find((checkpoint) => checkpoint.topology?.run !== undefined)?.topology?.run;
15779
15940
  }
15780
- function validateRunGroups(grouped, rootRunId, tools, checkpoints) {
15941
+ function validateRunGroups(grouped, rootRunId, tools, checkpoints, allowPendingChildren = false) {
15781
15942
  const toolsFor = (runId) => tools.filter((checkpoint) => (checkpoint.topology?.run?.runId ?? rootRunId) === runId);
15782
15943
  const owners = new Map;
15783
15944
  const syntheticChildIds = new Set;
@@ -15789,6 +15950,11 @@ function validateRunGroups(grouped, rootRunId, tools, checkpoints) {
15789
15950
  if (childRunId === parentRunId || owners.has(childRunId))
15790
15951
  return false;
15791
15952
  if (!grouped.has(childRunId)) {
15953
+ if (allowPendingChildren && isPendingChildBoundary(draft, parentRunId, childRunId, rootRunId) && !childScopedEvidenceExists(checkpoints, draft.replayKey, childRunId)) {
15954
+ syntheticChildIds.add(childRunId);
15955
+ owners.set(childRunId, draft);
15956
+ continue;
15957
+ }
15792
15958
  if (!isSyntheticExitedChild(draft, parentRunId, childRunId, rootRunId) || childScopedEvidenceExists(checkpoints, draft.replayKey, childRunId))
15793
15959
  return false;
15794
15960
  syntheticChildIds.add(childRunId);
@@ -15821,6 +15987,10 @@ function validateRunGroups(grouped, rootRunId, tools, checkpoints) {
15821
15987
  }
15822
15988
  return true;
15823
15989
  }
15990
+ function isPendingChildBoundary(draft, parentRunId, childRunId, rootRunId) {
15991
+ const boundary = draft.topology?.boundary;
15992
+ return workflowChildFromDraft(draft) === undefined && boundary?.event === "start" && boundary.status === "running" && boundary.child.runId === childRunId && boundary.child.parentRunId === parentRunId && boundary.child.parentStageId === draft.topology?.stageId && boundary.child.rootRunId === rootRunId;
15993
+ }
15824
15994
  function isSyntheticExitedChild(draft, parentRunId, childRunId, rootRunId) {
15825
15995
  const child = workflowChildFromDraft(draft);
15826
15996
  const boundary = draft.topology?.boundary;
@@ -16236,11 +16406,17 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
16236
16406
  retainReachableRunGroups(grouped, rootRunId);
16237
16407
  if (policy.failOnUnreachable && grouped.size !== groupedCount)
16238
16408
  return [];
16239
- if (!validateRunGroups(grouped, rootRunId, toolCheckpoints, checkpoints))
16409
+ if (!validateRunGroups(grouped, rootRunId, toolCheckpoints, checkpoints, policy.retainActive))
16240
16410
  return [];
16241
16411
  const syntheticChildren = [];
16412
+ const pendingChildren = [];
16242
16413
  for (const [parentRunId, runDrafts] of grouped) {
16243
16414
  for (const draft of runDrafts) {
16415
+ const pendingChildRunId = childRunIdFromDraft(draft);
16416
+ if (policy.retainActive && pendingChildRunId !== undefined && !grouped.has(pendingChildRunId) && isPendingChildBoundary(draft, parentRunId, pendingChildRunId, rootRunId)) {
16417
+ pendingChildren.push({ parentRunId, owner: draft });
16418
+ continue;
16419
+ }
16244
16420
  const child = workflowChildFromDraft(draft);
16245
16421
  if (child?.exited !== true || grouped.has(child.runId))
16246
16422
  continue;
@@ -16349,6 +16525,28 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
16349
16525
  resumable: false
16350
16526
  });
16351
16527
  }
16528
+ for (const { parentRunId, owner } of pendingChildren) {
16529
+ if (!emittedRunIds.has(parentRunId))
16530
+ return [];
16531
+ const topology = owner.topology;
16532
+ const boundary = topology.boundary;
16533
+ const parentStageId = idMaps.get(parentRunId)?.get(topology.stageId);
16534
+ if (parentStageId === undefined)
16535
+ return [];
16536
+ runs.push({
16537
+ id: boundary.child.runId,
16538
+ name: boundary.child.runName,
16539
+ inputs: {},
16540
+ status: "running",
16541
+ stages: [],
16542
+ toolNodes: [],
16543
+ startedAt: owner.startedAt ?? owner.firstCompletedAt,
16544
+ parentRunId,
16545
+ parentStageId,
16546
+ rootRunId: boundary.child.rootRunId,
16547
+ resumable: false
16548
+ });
16549
+ }
16352
16550
  return runs;
16353
16551
  }
16354
16552
  function stageSnapshotFromDraft(draft, id, parentIds) {
@@ -16664,6 +16862,402 @@ function deferStageUntilRunRelease(input) {
16664
16862
  };
16665
16863
  }
16666
16864
 
16865
+ // dist/builtin/workflows/src/engine/run-rejection-boundary.ts
16866
+ import { AsyncLocalStorage as AsyncLocalStorage3 } from "node:async_hooks";
16867
+ import { inspect } from "node:util";
16868
+ var EVENT = "unhandledRejection";
16869
+ var BOUNDARY_KEY = Symbol.for("atomic-workflows/run-rejection-boundary@5");
16870
+ var FLAG = "--unhandled-rejections";
16871
+ var MAX_CAUSE_DEPTH2 = 8;
16872
+ var MAX_PRIMITIVES_PER_RUN = 64;
16873
+ var MAX_STOP_STRINGS = 64;
16874
+ var ENDED_RUN_GRACE_MS = 30000;
16875
+ var NATIVE_REPORTING_MODES = new Set(["throw", "warn-with-error-code"]);
16876
+ function boundaryBag() {
16877
+ return globalThis;
16878
+ }
16879
+ function sharedBoundary() {
16880
+ const bag = boundaryBag();
16881
+ const existing = bag[BOUNDARY_KEY];
16882
+ if (existing !== undefined && existing.version === 5)
16883
+ return existing;
16884
+ const created = {
16885
+ version: 5,
16886
+ store: new AsyncLocalStorage3,
16887
+ owners: new WeakMap,
16888
+ promises: new WeakMap,
16889
+ scopes: new Set,
16890
+ runs: new Map,
16891
+ ended: new Map,
16892
+ stops: new Set,
16893
+ listener: undefined
16894
+ };
16895
+ bag[BOUNDARY_KEY] = created;
16896
+ return created;
16897
+ }
16898
+ function isObject(value) {
16899
+ return typeof value === "object" && value !== null || typeof value === "function";
16900
+ }
16901
+ function isPrimitive(value) {
16902
+ return !isObject(value);
16903
+ }
16904
+ function safeField3(value, key) {
16905
+ try {
16906
+ return value[key];
16907
+ } catch {
16908
+ return;
16909
+ }
16910
+ }
16911
+ function strongerEffect(left, right) {
16912
+ return left === "fail-run" || right === "fail-run" ? "fail-run" : "ignore";
16913
+ }
16914
+ function addAttribution(into, scope, effect) {
16915
+ into.set(scope, strongerEffect(into.get(scope), effect));
16916
+ }
16917
+ function recordedOwners(boundary, reason) {
16918
+ const owners = new Map;
16919
+ let stopped = false;
16920
+ const seen = new Set;
16921
+ const pending = [{ value: reason, depth: 0 }];
16922
+ while (pending.length > 0) {
16923
+ const { value, depth } = pending.pop();
16924
+ if (depth > MAX_CAUSE_DEPTH2)
16925
+ continue;
16926
+ if (isPrimitive(value)) {
16927
+ if (depth === 0 || value !== undefined && value !== null) {
16928
+ for (const scope of boundary.scopes) {
16929
+ const entry = scope.primitives.get(value);
16930
+ if (entry !== undefined)
16931
+ addAttribution(owners, scope, entry.effect);
16932
+ }
16933
+ if (typeof value === "string" && boundary.stops.has(value))
16934
+ stopped = true;
16935
+ }
16936
+ continue;
16937
+ }
16938
+ if (seen.has(value))
16939
+ continue;
16940
+ seen.add(value);
16941
+ for (const [scope, effect] of boundary.owners.get(value) ?? [])
16942
+ addAttribution(owners, scope, effect);
16943
+ pending.push({ value: safeField3(value, "cause"), depth: depth + 1 });
16944
+ const errors = safeField3(value, "errors");
16945
+ if (Array.isArray(errors))
16946
+ for (const entry of errors)
16947
+ pending.push({ value: entry, depth: depth + 1 });
16948
+ }
16949
+ return { owners, stopped };
16950
+ }
16951
+ function pruneEndedSources(boundary) {
16952
+ const now = Date.now();
16953
+ for (const [source, trees] of boundary.ended) {
16954
+ for (const [rootRunId, endedAt] of trees)
16955
+ if (now - endedAt > ENDED_RUN_GRACE_MS)
16956
+ trees.delete(rootRunId);
16957
+ if (trees.size === 0)
16958
+ boundary.ended.delete(source);
16959
+ }
16960
+ }
16961
+ function recordEndedRun(boundary, scope) {
16962
+ if (scope.source === undefined)
16963
+ return;
16964
+ const trees = boundary.ended.get(scope.source) ?? new Map;
16965
+ trees.set(scope.rootRunId, Date.now());
16966
+ boundary.ended.set(scope.source, trees);
16967
+ }
16968
+ function endedInAnotherRunTree(boundary, source, live) {
16969
+ for (const endedRoot of boundary.ended.get(source)?.keys() ?? [])
16970
+ if (endedRoot !== live.rootRunId)
16971
+ return true;
16972
+ return false;
16973
+ }
16974
+ function recognizedSources(boundary) {
16975
+ pruneEndedSources(boundary);
16976
+ const sources = new Set(boundary.ended.keys());
16977
+ for (const scope of boundary.scopes)
16978
+ if (scope.live && scope.source !== undefined)
16979
+ sources.add(scope.source);
16980
+ return sources;
16981
+ }
16982
+ function authoringSource(reason, sources) {
16983
+ if (sources.size === 0 || !isObject(reason))
16984
+ return;
16985
+ const stack = safeField3(reason, "stack");
16986
+ if (typeof stack !== "string")
16987
+ return;
16988
+ for (const line of stack.split(`
16989
+ `)) {
16990
+ if (!line.trimStart().startsWith("at "))
16991
+ continue;
16992
+ const path = parsePromptStackFrame(line)?.normalizedPath;
16993
+ if (path === undefined)
16994
+ continue;
16995
+ if (isWorkflowRuntimeModule(path))
16996
+ return;
16997
+ if (/\/node_modules\//.test(path))
16998
+ continue;
16999
+ if (sources.has(path))
17000
+ return path;
17001
+ }
17002
+ return;
17003
+ }
17004
+ function hasAncestorIn(scope, candidates) {
17005
+ for (let ancestor = scope.parent;ancestor !== undefined; ancestor = ancestor.parent) {
17006
+ if (candidates.has(ancestor))
17007
+ return true;
17008
+ }
17009
+ return false;
17010
+ }
17011
+ function outermostLiveRuns(boundary, source) {
17012
+ const matching = new Set;
17013
+ for (const scope of boundary.scopes)
17014
+ if (scope.live && scope.source === source)
17015
+ matching.add(scope);
17016
+ const outermost = new Set;
17017
+ for (const scope of matching)
17018
+ if (!hasAncestorIn(scope, matching))
17019
+ outermost.add(scope);
17020
+ return outermost;
17021
+ }
17022
+ function runOfSource(boundary, source) {
17023
+ const [only, ...others] = outermostLiveRuns(boundary, source);
17024
+ if (only === undefined)
17025
+ return new Map;
17026
+ if (others.length > 0 || only.sharedSource)
17027
+ return;
17028
+ if (endedInAnotherRunTree(boundary, source, only))
17029
+ return;
17030
+ return new Map([[only, "fail-run"]]);
17031
+ }
17032
+ function markSharedSource(boundary, source) {
17033
+ const runs = outermostLiveRuns(boundary, source);
17034
+ if (runs.size > 1)
17035
+ for (const run of runs)
17036
+ run.sharedSource = true;
17037
+ }
17038
+ function rejectingRun(boundary, recorded, promise, scoped) {
17039
+ const tracked = promise === undefined ? undefined : boundary.promises.get(promise);
17040
+ if (tracked !== undefined && recorded.has(tracked))
17041
+ return tracked;
17042
+ if (scoped !== undefined && recorded.has(scoped))
17043
+ return scoped;
17044
+ return;
17045
+ }
17046
+ function attribute(boundary, reason, promise) {
17047
+ const { owners: recorded, stopped } = recordedOwners(boundary, reason);
17048
+ const scoped = boundary.store.getStore();
17049
+ if (recorded.size > 1) {
17050
+ const rejecting = rejectingRun(boundary, recorded, promise, scoped);
17051
+ if (rejecting !== undefined)
17052
+ return new Map([[rejecting, recorded.get(rejecting) ?? "fail-run"]]);
17053
+ }
17054
+ if (recorded.size > 0)
17055
+ return recorded;
17056
+ if (stopped)
17057
+ return new Map;
17058
+ if (scoped !== undefined && boundary.scopes.has(scoped))
17059
+ return new Map([[scoped, "fail-run"]]);
17060
+ const origin = authoringSource(reason, recognizedSources(boundary));
17061
+ if (origin === undefined)
17062
+ return;
17063
+ if (scoped !== undefined)
17064
+ return new Map([[scoped, "ignore"]]);
17065
+ return runOfSource(boundary, origin);
17066
+ }
17067
+ function unhandledRejectionError(reason) {
17068
+ return Object.assign(new Error("This error originated either by throwing inside of an async function without a catch block, " + `or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "${inspect(reason)}".`), { code: "ERR_UNHANDLED_REJECTION" });
17069
+ }
17070
+ function unhandledRejectionsMode() {
17071
+ const args = [...(process.env.NODE_OPTIONS ?? "").split(/\s+/), ...process.execArgv];
17072
+ let mode = "throw";
17073
+ for (let index = 0;index < args.length; index += 1) {
17074
+ const arg = args[index] ?? "";
17075
+ if (arg.startsWith(`${FLAG}=`))
17076
+ mode = arg.slice(FLAG.length + 1);
17077
+ else if (arg === FLAG && args[index + 1] !== undefined)
17078
+ mode = args[index + 1] ?? mode;
17079
+ }
17080
+ return mode;
17081
+ }
17082
+ function surfaceNatively(boundary, reason) {
17083
+ const listener = boundary.listener;
17084
+ if (listener === undefined || process.listenerCount(EVENT) > 1)
17085
+ return;
17086
+ if (!NATIVE_REPORTING_MODES.has(unhandledRejectionsMode()))
17087
+ return;
17088
+ process.nextTick(() => {
17089
+ process.removeListener(EVENT, listener);
17090
+ Promise.reject(reason);
17091
+ setImmediate(() => {
17092
+ if (!process.listeners(EVENT).includes(listener))
17093
+ process.on(EVENT, listener);
17094
+ });
17095
+ });
17096
+ }
17097
+ function onUnhandledRejection(reason, promise) {
17098
+ const boundary = sharedBoundary();
17099
+ const owners = attribute(boundary, reason, promise);
17100
+ if (owners === undefined) {
17101
+ surfaceNatively(boundary, reason);
17102
+ return;
17103
+ }
17104
+ const error = isObject(reason) ? reason : unhandledRejectionError(reason);
17105
+ for (const [scope, effect] of owners) {
17106
+ if (effect !== "fail-run" || !scope.live)
17107
+ continue;
17108
+ try {
17109
+ scope.fail(error);
17110
+ } catch {}
17111
+ }
17112
+ }
17113
+ function ensureInstalled(boundary) {
17114
+ if (boundary.listener !== undefined)
17115
+ return;
17116
+ boundary.listener = onUnhandledRejection;
17117
+ process.on(EVENT, onUnhandledRejection);
17118
+ }
17119
+ function record(boundary, scope, reason, effect) {
17120
+ if (isPrimitive(reason)) {
17121
+ recordPrimitive(scope, reason, effect);
17122
+ return;
17123
+ }
17124
+ const owners = boundary.owners.get(reason);
17125
+ if (owners === undefined)
17126
+ boundary.owners.set(reason, new Map([[scope, effect]]));
17127
+ else
17128
+ addAttribution(owners, scope, effect);
17129
+ }
17130
+ function recordStop(boundary, reason) {
17131
+ boundary.stops.delete(reason);
17132
+ boundary.stops.add(reason);
17133
+ if (boundary.stops.size <= MAX_STOP_STRINGS)
17134
+ return;
17135
+ const oldest = boundary.stops.values().next();
17136
+ if (!oldest.done)
17137
+ boundary.stops.delete(oldest.value);
17138
+ }
17139
+ function recordPrimitive(scope, reason, effect) {
17140
+ if (!scope.live)
17141
+ return;
17142
+ if (scope.primitives.size >= MAX_PRIMITIVES_PER_RUN && !scope.primitives.has(reason)) {
17143
+ const oldest = scope.primitives.keys().next();
17144
+ if (!oldest.done)
17145
+ scope.primitives.delete(oldest.value);
17146
+ }
17147
+ scope.generation += 1;
17148
+ const generation = scope.generation;
17149
+ scope.primitives.set(reason, { effect: strongerEffect(scope.primitives.get(reason)?.effect, effect), generation });
17150
+ afterPendingRejectionReports().then(() => {
17151
+ if (scope.primitives.get(reason)?.generation === generation)
17152
+ scope.primitives.delete(reason);
17153
+ });
17154
+ }
17155
+ function discardFailure() {}
17156
+ function afterPendingRejectionReports() {
17157
+ return new Promise((resolve) => {
17158
+ const { port1, port2 } = new MessageChannel;
17159
+ port1.onmessage = () => {
17160
+ port1.close();
17161
+ port2.close();
17162
+ resolve();
17163
+ };
17164
+ port2.postMessage(undefined);
17165
+ });
17166
+ }
17167
+ function openRunRejectionScope(options) {
17168
+ const boundary = sharedBoundary();
17169
+ ensureInstalled(boundary);
17170
+ pruneEndedSources(boundary);
17171
+ const parent = options.parentRunId === undefined ? undefined : boundary.runs.get(options.parentRunId);
17172
+ const scope = {
17173
+ runId: options.runId,
17174
+ rootRunId: parent?.rootRunId ?? options.runId,
17175
+ source: options.source === undefined ? undefined : normalizeStackPath(options.source),
17176
+ parent,
17177
+ fail: options.fail,
17178
+ primitives: new Map,
17179
+ generation: 0,
17180
+ live: true,
17181
+ sharedSource: false
17182
+ };
17183
+ boundary.scopes.add(scope);
17184
+ boundary.runs.set(scope.runId, scope);
17185
+ if (scope.source !== undefined)
17186
+ markSharedSource(boundary, scope.source);
17187
+ return {
17188
+ run: (callback) => boundary.store.run(scope, callback),
17189
+ contain: (promise, effect = "fail-run") => {
17190
+ boundary.promises.set(promise, scope);
17191
+ promise.then(undefined, (reason) => record(boundary, scope, reason, effect));
17192
+ return promise;
17193
+ },
17194
+ watch: (promise) => {
17195
+ const watched = promise.then(undefined, (reason) => {
17196
+ record(boundary, scope, reason, "fail-run");
17197
+ throw reason;
17198
+ });
17199
+ boundary.promises.set(watched, scope);
17200
+ return watched;
17201
+ },
17202
+ ignore: (reason) => {
17203
+ if (typeof reason === "string")
17204
+ recordStop(boundary, reason);
17205
+ else
17206
+ record(boundary, scope, reason, "ignore");
17207
+ },
17208
+ settle: afterPendingRejectionReports,
17209
+ close: () => {
17210
+ scope.live = false;
17211
+ scope.fail = discardFailure;
17212
+ recordEndedRun(boundary, scope);
17213
+ afterPendingRejectionReports().then(() => {
17214
+ scope.primitives.clear();
17215
+ scope.parent = undefined;
17216
+ boundary.scopes.delete(scope);
17217
+ if (boundary.runs.get(scope.runId) === scope)
17218
+ boundary.runs.delete(scope.runId);
17219
+ });
17220
+ }
17221
+ };
17222
+ }
17223
+ var WATCHED_STAGE_METHODS = [
17224
+ "prompt",
17225
+ "complete",
17226
+ "sendUserMessage",
17227
+ "steer",
17228
+ "followUp",
17229
+ "setModel",
17230
+ "setThinkingLevel",
17231
+ "cycleModel",
17232
+ "cycleThinkingLevel",
17233
+ "navigateTree",
17234
+ "compact",
17235
+ "abort"
17236
+ ];
17237
+ function containStageRejections(stage, scope) {
17238
+ const contained = Object.create(stage);
17239
+ const descriptors = {};
17240
+ for (const name of WATCHED_STAGE_METHODS) {
17241
+ descriptors[name] = {
17242
+ value: (...args) => {
17243
+ const result = Reflect.apply(stage[name], stage, args);
17244
+ return result instanceof Promise ? scope.watch(result) : result;
17245
+ }
17246
+ };
17247
+ }
17248
+ Object.defineProperties(contained, descriptors);
17249
+ return contained;
17250
+ }
17251
+ function containUiRejections(ui, scope) {
17252
+ return {
17253
+ input: (prompt) => scope.watch(ui.input(prompt)),
17254
+ confirm: (message) => scope.watch(ui.confirm(message)),
17255
+ select: (message, options) => scope.watch(ui.select(message, options)),
17256
+ editor: (initial) => scope.watch(ui.editor(initial)),
17257
+ custom: (factory, options) => scope.watch(ui.custom(factory, options))
17258
+ };
17259
+ }
17260
+
16667
17261
  // dist/builtin/workflows/src/engine/run-returned-status.ts
16668
17262
  function classifyReturnedRunStatus(result, runSnapshot) {
16669
17263
  const structuredFailure = runSnapshot !== undefined ? structuredRecoverableWorkflowFailure(runSnapshot) : undefined;
@@ -18760,7 +19354,9 @@ import { createStructuredOutputCapture, runCallback as runCallback2 } from "@bas
18760
19354
  import {
18761
19355
  AutoRoutingInferenceError,
18762
19356
  convertToLlm,
19357
+ isExtensionStartupFailure,
18763
19358
  isModelRoutingDebugEnabled,
19359
+ isTransientExtensionStartupFailure,
18764
19360
  parseModelConstraints,
18765
19361
  setsProviders
18766
19362
  } from "@bastani/atomic";
@@ -19031,6 +19627,23 @@ class StageDeliveryActivity {
19031
19627
  }
19032
19628
  }
19033
19629
 
19630
+ // dist/builtin/workflows/src/runs/foreground/stage-routing.ts
19631
+ var STAGE_ROUTING_CONCURRENCY = 8;
19632
+ var STAGE_ROUTING_DEADLINE_MS = 300000;
19633
+ var routingLimiter = new ConcurrencyLimiter(STAGE_ROUTING_CONCURRENCY);
19634
+ async function routeStageModel(route, input) {
19635
+ const deadline = new AbortController;
19636
+ const timer = setTimeout(() => deadline.abort(new Error("stage routing deadline")), STAGE_ROUTING_DEADLINE_MS);
19637
+ try {
19638
+ return await route({
19639
+ ...input,
19640
+ inference: { deadline: deadline.signal, limit: (run, signal) => routingLimiter.run(run, signal) }
19641
+ });
19642
+ } finally {
19643
+ clearTimeout(timer);
19644
+ }
19645
+ }
19646
+
19034
19647
  // dist/builtin/workflows/src/runs/foreground/stage-runner-artifact-capture.ts
19035
19648
  class StageArtifactCapture {
19036
19649
  session;
@@ -19521,6 +20134,7 @@ async function stripWorkflowOnlyOptions2(options, defaultSessionDir, meta, pendi
19521
20134
  }
19522
20135
  const {
19523
20136
  schema: _schema,
20137
+ schemaTimeoutMs: _schemaTimeoutMs,
19524
20138
  mcp: _mcp,
19525
20139
  fallbackModels,
19526
20140
  modelConstraints: _modelConstraints,
@@ -19768,6 +20382,15 @@ class StageSessionReplacement {
19768
20382
  this.previous = undefined;
19769
20383
  await Promise.allSettled([...previous ? [disposeStageSession(previous)] : [], ...this.cleanups]);
19770
20384
  }
20385
+ async disposeRetired() {
20386
+ const previous = this.previous;
20387
+ this.previous = undefined;
20388
+ if (!previous)
20389
+ return;
20390
+ await disposeStageSession(previous).catch((error) => {
20391
+ console.error("atomic-workflows: retired stage session disposal failed", error);
20392
+ });
20393
+ }
19771
20394
  async disposeAfterIdle(session) {
19772
20395
  const agent = session.agent;
19773
20396
  if (typeof agent?.waitForIdle === "function")
@@ -19894,7 +20517,7 @@ class WorkflowStructuredOutputContractError extends Error {
19894
20517
  }
19895
20518
  }
19896
20519
  function isStructuredOutputContractFailure(message) {
19897
- return message.startsWith(STRUCTURED_OUTPUT_MISSING_ERROR) || message.startsWith('Validation failed for tool "structured_output":') || message.startsWith("Invalid structured output: response does not match the decision schema.") || message.startsWith("Invalid structured output: non-JSON decision.") || message.startsWith("Structured output requires one structured_output call.") || message.startsWith("Structured output requires exactly one structured_output call and no provider fallback.") || message === "Structured output requires complete judgment instructions." || message === "Structured output requires a nonempty named state object containing the task and relevant context text." || message === "Structured output inputs must be finite, acyclic JSON data." || message === "Structured output inputs must be plain JSON objects." || message === "structured_output tool call failed schema validation.";
20520
+ return message.startsWith(STRUCTURED_OUTPUT_MISSING_ERROR) || message.startsWith('Validation failed for tool "structured_output":') || message.startsWith("Invalid structured output: response does not match the decision schema.") || message.startsWith("Invalid structured output: non-JSON decision.") || message.startsWith("Invalid structured output: tool call arguments were not valid JSON.") || message.startsWith("Structured output requires one structured_output call.") || message.startsWith("Structured output requires exactly one structured_output call and no provider fallback.") || message === "Structured output requires complete judgment instructions." || message === "Structured output requires a nonempty named state object containing the task and relevant context text." || message === "Structured output inputs must be finite, acyclic JSON data." || message === "Structured output inputs must be plain JSON objects." || message === "structured_output tool call failed schema validation.";
19898
20521
  }
19899
20522
  var STRUCTURED_OUTPUT_TOOL_NAME = "structured_output";
19900
20523
  function toolResultText(content) {
@@ -19946,7 +20569,8 @@ function stageOptionsWithStructuredOutput(options, capture, executionCapture) {
19946
20569
  return options;
19947
20570
  const structuredOutputTool = createStructuredOutputTool({
19948
20571
  schema: options.schema,
19949
- capture
20572
+ capture,
20573
+ ...options.schemaTimeoutMs === undefined ? {} : { timeoutMs: options.schemaTimeoutMs }
19950
20574
  });
19951
20575
  const executeStructuredOutput = structuredOutputTool.execute;
19952
20576
  const capturedStructuredOutputTool = {
@@ -20036,6 +20660,16 @@ function waitForStageStartup(operation, signal) {
20036
20660
  // dist/builtin/workflows/src/runs/foreground/stage-runner-controller.ts
20037
20661
  var WORKFLOW_STAGE_CLOSED_FOR_GOOD_STATE = "atomic:workflow-stage-closed-for-good";
20038
20662
  var WORKFLOW_STAGE_END_CHILDREN_STATE = "atomic:workflow-stage-end-children";
20663
+ function isRetryableSameCandidateFailure(error) {
20664
+ if (isExtensionStartupFailure(error))
20665
+ return isTransientExtensionStartupFailure(error);
20666
+ return isRetryableSameModelFailure(error);
20667
+ }
20668
+ function mayAdvanceToNextCandidate(error) {
20669
+ if (isExtensionStartupFailure(error))
20670
+ return isTransientExtensionStartupFailure(error);
20671
+ return isRetryableModelFailure(error);
20672
+ }
20039
20673
  function hasMeaningfulUsage(usage) {
20040
20674
  if (usage === undefined)
20041
20675
  return false;
@@ -20287,7 +20921,7 @@ class StageSessionController {
20287
20921
  return;
20288
20922
  if (!this.routingPromise) {
20289
20923
  this.beginStartup();
20290
- this.routingPromise = (async () => {
20924
+ const routing = (async () => {
20291
20925
  const route = this.modelCatalog?.routeModel;
20292
20926
  if (!route)
20293
20927
  throw new Error("Workflow stage auto routing requires a routing-capable model catalog.");
@@ -20299,7 +20933,7 @@ class StageSessionController {
20299
20933
  ...thinking === undefined ? [] : [{ allowedEfforts: [thinking] }]
20300
20934
  ].filter((c) => c !== undefined);
20301
20935
  try {
20302
- this.modelRoute = await route({
20936
+ this.modelRoute = await routeStageModel(route, {
20303
20937
  task: text,
20304
20938
  stageName: this.opts.stageName,
20305
20939
  constraints,
@@ -20320,7 +20954,17 @@ class StageSessionController {
20320
20954
  this.modelRoute.assertCurrent();
20321
20955
  this.meta.stageOptions = { ...options, model: this.modelRoute.modelOverride };
20322
20956
  this.opts.onModelFallbackMetaChange?.(this.currentModelFallbackMeta());
20323
- })();
20957
+ })().catch((error) => {
20958
+ if (this.routingPromise === routing) {
20959
+ this.routingPromise = undefined;
20960
+ this.modelRoute = undefined;
20961
+ }
20962
+ if (this.startupWait.signal.aborted || this.opts.signal?.aborted)
20963
+ throw error;
20964
+ this.settleStartup(true);
20965
+ throw new Error(`atomic-workflows: stage "${this.opts.stageName}" failed during startup phase model-resolution: ${errorMessage2(error)}`);
20966
+ });
20967
+ this.routingPromise = routing;
20324
20968
  }
20325
20969
  await this.routingPromise;
20326
20970
  }
@@ -21075,7 +21719,7 @@ class StageSessionController {
21075
21719
  const errorSettingsManager = retrySettingsManagerFromError(error);
21076
21720
  if (errorSettingsManager !== undefined)
21077
21721
  this.sessionSettingsManager = errorSettingsManager;
21078
- const decision = isWorkflowPendingStageDeliveryFailure(error) ? undefined : nextRetryDecision(this.retrySettings(), retryAttempt, isRetryableSameModelFailure(error));
21722
+ const decision = isWorkflowPendingStageDeliveryFailure(error) ? undefined : nextRetryDecision(this.retrySettings(), retryAttempt, isRetryableSameCandidateFailure(error));
21079
21723
  if (decision === undefined || this.disposed || this.opts.signal?.aborted === true || this.startupWait.signal.aborted || this.capturedStructuredOutputForAttempt()) {
21080
21724
  throw error;
21081
21725
  }
@@ -21487,10 +22131,11 @@ class StageSessionController {
21487
22131
  ...usage === undefined ? {} : { usage },
21488
22132
  error: message
21489
22133
  });
21490
- if (this.opts.signal?.aborted || this.startupWait.signal.aborted || terminalStageDelivery || !isRetryableModelFailure(err) || index === candidates.length - 1) {
22134
+ if (this.opts.signal?.aborted || this.startupWait.signal.aborted || terminalStageDelivery || !mayAdvanceToNextCandidate(err) || index === candidates.length - 1) {
21491
22135
  this.modelWarnings.push(...this.pendingFallbackWarnings);
21492
22136
  this.pendingFallbackWarnings.length = 0;
21493
22137
  this.notifyModelFallbackMetaChange();
22138
+ await this.replacement.disposeRetired();
21494
22139
  return "throw";
21495
22140
  }
21496
22141
  const nextCandidate = candidates[index + 1];
@@ -22612,13 +23257,13 @@ class EngineRuntime {
22612
23257
 
22613
23258
  // dist/builtin/workflows/src/engine/session-closed-error.ts
22614
23259
  import { isStaleExtensionContextError as isStaleExtensionContextError2 } from "@bastani/atomic";
22615
- var MAX_CAUSE_DEPTH = 8;
23260
+ var MAX_CAUSE_DEPTH3 = 8;
22616
23261
  function reportsClosedSession(error) {
22617
23262
  return "code" in error && error.code === "SessionClosed" || isStaleExtensionContextError2(error);
22618
23263
  }
22619
23264
  function isSessionClosedError(error) {
22620
23265
  let current = error;
22621
- for (let depth = 0;depth < MAX_CAUSE_DEPTH && current !== undefined; depth++) {
23266
+ for (let depth = 0;depth < MAX_CAUSE_DEPTH3 && current !== undefined; depth++) {
22622
23267
  try {
22623
23268
  if (reportsClosedSession(current))
22624
23269
  return true;
@@ -22690,7 +23335,12 @@ async function executeRun(def, resolvedInputs, opts) {
22690
23335
  workflowObservationRuntime(activeStore).control(runId, "kill");
22691
23336
  ownController.abort(callerSignal?.reason);
22692
23337
  };
22693
- const exit = createWorkflowExitManager({ runId, exitScope, controller: ownController });
23338
+ const exit = createWorkflowExitManager({
23339
+ runId,
23340
+ exitScope,
23341
+ controller: ownController,
23342
+ onExitSelected: (signal) => rejectionScope.ignore(signal)
23343
+ });
22694
23344
  const sourceBackend = opts.durableBackend;
22695
23345
  const backendView = sourceBackend;
22696
23346
  const rootBackend = opts.durableRootBackend ?? backendView;
@@ -23204,6 +23854,22 @@ async function executeRun(def, resolvedInputs, opts) {
23204
23854
  baseFromPromptNodes: getPromptNodeUi
23205
23855
  });
23206
23856
  let pausedExit;
23857
+ const authoredIn = workflowSource(def);
23858
+ const rejectionScope = openRunRejectionScope({
23859
+ runId,
23860
+ ...opts.parentRun !== undefined ? { parentRunId: opts.parentRun.runId } : {},
23861
+ ...authoredIn !== undefined ? { source: authoredIn } : {},
23862
+ fail: (error) => {
23863
+ if (findWorkflowGracefulQuit(error) !== undefined)
23864
+ return;
23865
+ const selected = terminalEvents.selectFailure(error);
23866
+ if (selected.kind === "failure" && !ownController.signal.aborted)
23867
+ ownController.abort(selected.error);
23868
+ }
23869
+ });
23870
+ ownController.signal.addEventListener("abort", () => rejectionScope.ignore(ownController.signal.reason), {
23871
+ once: true
23872
+ });
23207
23873
  const ctx = {
23208
23874
  inputs: resolvedInputs,
23209
23875
  runId,
@@ -23214,28 +23880,30 @@ async function executeRun(def, resolvedInputs, opts) {
23214
23880
  if (scheduler.isRunPaused()) {
23215
23881
  pausedExit ??= whenRunning(async () => exit.exit(options));
23216
23882
  pausedExit.catch(() => {});
23217
- throw new Error("Workflow exit is waiting for explicit resume");
23883
+ const waiting = new Error("Workflow exit is waiting for explicit resume");
23884
+ rejectionScope.ignore(waiting);
23885
+ throw waiting;
23218
23886
  }
23219
23887
  return exit.exit(options);
23220
23888
  },
23221
- ui,
23889
+ ui: containUiRejections(ui, rejectionScope),
23222
23890
  stage: (name, options) => {
23223
23891
  ownController.signal.throwIfAborted();
23224
23892
  if (!scheduler.isRunPaused())
23225
- return durableStage(name, options);
23893
+ return containStageRejections(durableStage(name, options), rejectionScope);
23226
23894
  const replayKey = stageReplayKeyGenerator(name);
23227
- return deferStageUntilRunRelease({
23895
+ return containStageRejections(deferStageUntilRunRelease({
23228
23896
  name,
23229
23897
  create: () => durableStage(name, options, replayKey),
23230
23898
  isPaused: scheduler.isRunPaused,
23231
23899
  waitForRelease: waitForRunRelease,
23232
23900
  signal: ownController.signal
23233
- });
23901
+ }), rejectionScope);
23234
23902
  },
23235
- task: gatedTask,
23236
- chain: (...args) => whenRunning(() => chain(...args)),
23237
- parallel: (...args) => whenRunning(() => parallel(...args)),
23238
- workflow: (...args) => whenRunning(() => {
23903
+ task: (...args) => rejectionScope.watch(gatedTask(...args)),
23904
+ chain: (...args) => rejectionScope.watch(whenRunning(() => chain(...args))),
23905
+ parallel: (...args) => rejectionScope.watch(whenRunning(() => parallel(...args))),
23906
+ workflow: (...args) => rejectionScope.watch(whenRunning(() => {
23239
23907
  const pending = durableWorkflow(...args);
23240
23908
  pendingChildWorkflows.add(pending);
23241
23909
  const settled = () => {
@@ -23243,18 +23911,17 @@ async function executeRun(def, resolvedInputs, opts) {
23243
23911
  };
23244
23912
  pending.then(settled, settled);
23245
23913
  return pending;
23246
- }),
23914
+ })),
23247
23915
  tool: (...args) => {
23248
23916
  if (admittedTools.closed)
23249
- return tool(...args);
23250
- const pending = whenRunning(() => tool(...args));
23251
- pending.catch(() => {});
23252
- return pending;
23917
+ return rejectionScope.contain(tool(...args), "ignore");
23918
+ return rejectionScope.contain(whenRunning(() => tool(...args)));
23253
23919
  },
23254
23920
  ...opts.models !== undefined ? { models: opts.models } : {}
23255
23921
  };
23256
23922
  const runtimeSettled = Promise.withResolvers();
23257
23923
  let durableRootAdmitted = false;
23924
+ let terminalStatusCommitted = false;
23258
23925
  let pausePersistence;
23259
23926
  let resumePersistence;
23260
23927
  let controlSettlements = Promise.resolve();
@@ -23400,7 +24067,7 @@ async function executeRun(def, resolvedInputs, opts) {
23400
24067
  while (scheduler.isRunPaused())
23401
24068
  await waitForRunRelease();
23402
24069
  ownController.signal.throwIfAborted();
23403
- const rawResult = await raceAbort2(runWorkflowDefinitionCallback(def.name, runId, () => def.run(ctx)), ownController.signal);
24070
+ const rawResult = await raceAbort2(runWorkflowDefinitionCallback(def.name, runId, () => rejectionScope.run(() => def.run(ctx))), ownController.signal);
23404
24071
  await drainCachedStagePersistence();
23405
24072
  while (scheduler.isRunPaused())
23406
24073
  await waitForRunRelease();
@@ -23410,6 +24077,7 @@ async function executeRun(def, resolvedInputs, opts) {
23410
24077
  if (pausedExit !== undefined)
23411
24078
  await pausedExit;
23412
24079
  budget.rethrowIfSystemOwnedStop(runSnapshot.stages.at(-1)?.name ?? startupFrontierStage);
24080
+ await rejectionScope.settle();
23413
24081
  const normalTerminalEvent = terminalEvents.winner();
23414
24082
  if (normalTerminalEvent?.kind === "cancellation") {
23415
24083
  const gracefulQuit = findWorkflowGracefulQuit(normalTerminalEvent.reason);
@@ -23444,6 +24112,7 @@ async function executeRun(def, resolvedInputs, opts) {
23444
24112
  await recordRunResultCheckpointAsync(durableBackend, runSnapshot);
23445
24113
  }
23446
24114
  await durableBackend.commitWorkflowStatus(runId, returned.status, undefined, returned.metadata?.resumable);
24115
+ terminalStatusCommitted = true;
23447
24116
  await appendRunEndWhenRecorded(opts.persistence, recorded, {
23448
24117
  runId,
23449
24118
  status: returned.status,
@@ -23478,6 +24147,9 @@ async function executeRun(def, resolvedInputs, opts) {
23478
24147
  }
23479
24148
  if (ownerClosing && err instanceof Error && isSessionClosedError(err))
23480
24149
  return await suspendForClosedSession(err);
24150
+ if (selectedTerminalEvent.kind === "failure" && pendingChildWorkflows.size > 0 && !ownController.signal.aborted) {
24151
+ ownController.abort(err);
24152
+ }
23481
24153
  await admittedTools.closeAndDrain();
23482
24154
  if (ownController.signal.aborted)
23483
24155
  await Promise.allSettled([...pendingChildWorkflows]);
@@ -23552,6 +24224,7 @@ async function executeRun(def, resolvedInputs, opts) {
23552
24224
  });
23553
24225
  return failed;
23554
24226
  } finally {
24227
+ rejectionScope.close();
23555
24228
  callerSignal?.removeEventListener("abort", onCallerAbort);
23556
24229
  workflowObservationRuntime(activeStore).finishRun(runId);
23557
24230
  runtimeSettled.resolve();
@@ -23565,7 +24238,9 @@ async function executeRun(def, resolvedInputs, opts) {
23565
24238
  runId,
23566
24239
  runSnapshot,
23567
24240
  isRoot: opts.parentRun === undefined,
23568
- durableBackend
24241
+ durableBackend,
24242
+ terminalStatusCommitted,
24243
+ store: activeStore
23569
24244
  });
23570
24245
  }
23571
24246
  } finally {