@bastani/atomic 0.9.12 → 0.9.13-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/builtin/intercom/CHANGELOG.md +6 -0
  3. package/dist/builtin/intercom/README.md +5 -12
  4. package/dist/builtin/intercom/broker/client.ts +11 -2
  5. package/dist/builtin/intercom/contact-supervisor-tool.ts +13 -3
  6. package/dist/builtin/intercom/index-heavy.ts +13 -3
  7. package/dist/builtin/intercom/index.ts +43 -19
  8. package/dist/builtin/intercom/intercom-utils.ts +15 -29
  9. package/dist/builtin/intercom/package.json +1 -1
  10. package/dist/builtin/intercom/source-ownership.ts +9 -12
  11. package/dist/builtin/mcp/CHANGELOG.md +6 -0
  12. package/dist/builtin/mcp/README.md +3 -1
  13. package/dist/builtin/mcp/index.ts +10 -16
  14. package/dist/builtin/mcp/package.json +1 -1
  15. package/dist/builtin/mcp/startup-warmup.ts +20 -8
  16. package/dist/builtin/subagents/CHANGELOG.md +30 -0
  17. package/dist/builtin/subagents/README.md +22 -30
  18. package/dist/builtin/subagents/package.json +1 -1
  19. package/dist/builtin/subagents/src/extension/doctor.ts +1 -1
  20. package/dist/builtin/subagents/src/extension/fanout-child.ts +76 -56
  21. package/dist/builtin/subagents/src/extension/index.ts +23 -32
  22. package/dist/builtin/subagents/src/extension/startup-maintenance.ts +25 -44
  23. package/dist/builtin/subagents/src/intercom/result-intercom.ts +7 -7
  24. package/dist/builtin/subagents/src/runs/background/async-job-tracker.ts +166 -434
  25. package/dist/builtin/subagents/src/runs/background/notify.ts +29 -8
  26. package/dist/builtin/subagents/src/runs/foreground/chain-execution-dynamic-step.ts +2 -2
  27. package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-runner.ts +4 -4
  28. package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-step.ts +2 -2
  29. package/dist/builtin/subagents/src/runs/foreground/chain-execution-sequential-step.ts +2 -2
  30. package/dist/builtin/subagents/src/runs/foreground/execution-run-sync.ts +1 -281
  31. package/dist/builtin/subagents/src/runs/foreground/execution-structured-retries.ts +11 -75
  32. package/dist/builtin/subagents/src/runs/foreground/inprocess-run-sync.ts +457 -0
  33. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-async.ts +119 -246
  34. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-chain.ts +1 -1
  35. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-context.ts +18 -9
  36. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel-task.ts +1 -1
  37. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel.ts +4 -4
  38. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-resume.ts +1 -646
  39. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-runtime.ts +2 -7
  40. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +5 -5
  41. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-status.ts +7 -8
  42. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-types.ts +14 -5
  43. package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +158 -93
  44. package/dist/builtin/subagents/src/runs/inprocess/background-single.ts +179 -0
  45. package/dist/builtin/subagents/src/runs/inprocess/background.ts +89 -0
  46. package/dist/builtin/subagents/src/runs/inprocess/child-policy.ts +27 -0
  47. package/dist/builtin/subagents/src/runs/inprocess/control-registry.ts +55 -0
  48. package/dist/builtin/subagents/src/runs/inprocess/control-status.ts +106 -0
  49. package/dist/builtin/subagents/src/runs/inprocess/index.ts +50 -0
  50. package/dist/builtin/subagents/src/runs/inprocess/nested-routing.ts +218 -0
  51. package/dist/builtin/subagents/src/runs/{shared/subagent-prompt-runtime.ts → inprocess/prompt-behavior.ts} +37 -75
  52. package/dist/builtin/subagents/src/runs/inprocess/runner.ts +1138 -0
  53. package/dist/builtin/subagents/src/runs/{shared/nested-events.ts → inprocess/runtime-support/nested-api.ts} +13 -7
  54. package/dist/builtin/subagents/src/runs/{shared/nested-events-control.ts → inprocess/runtime-support/nested-control.ts} +18 -17
  55. package/dist/builtin/subagents/src/runs/{shared/nested-events-core.ts → inprocess/runtime-support/nested-core.ts} +14 -61
  56. package/dist/builtin/subagents/src/runs/{shared/nested-events-projection.ts → inprocess/runtime-support/nested-projection.ts} +4 -10
  57. package/dist/builtin/subagents/src/runs/{shared/nested-events-registry.ts → inprocess/runtime-support/nested-registry.ts} +19 -4
  58. package/dist/builtin/subagents/src/runs/{shared/nested-render.ts → inprocess/runtime-support/nested-rendering.ts} +3 -3
  59. package/dist/builtin/subagents/src/runs/{shared/nested-events-sanitize.ts → inprocess/runtime-support/nested-sanitize.ts} +3 -3
  60. package/dist/builtin/subagents/src/runs/inprocess.ts +1 -0
  61. package/dist/builtin/subagents/src/runs/shared/dynamic-fanout.ts +10 -4
  62. package/dist/builtin/subagents/src/runs/shared/model-candidate-filter.ts +0 -1
  63. package/dist/builtin/subagents/src/runs/shared/model-fallback.ts +15 -492
  64. package/dist/builtin/subagents/src/runs/shared/parallel-utils.ts +13 -11
  65. package/dist/builtin/subagents/src/runs/shared/run-history.ts +3 -5
  66. package/dist/builtin/subagents/src/runs/shared/single-output.ts +4 -4
  67. package/dist/builtin/subagents/src/runs/shared/workflow-graph.ts +5 -5
  68. package/dist/builtin/subagents/src/shared/types-async.ts +0 -1
  69. package/dist/builtin/subagents/src/shared/types-config.ts +18 -0
  70. package/dist/builtin/subagents/src/shared/types-results.ts +9 -2
  71. package/dist/builtin/subagents/src/slash/prompt-template-bridge.ts +2 -3
  72. package/dist/builtin/subagents/src/slash/slash-live-state.ts +2 -2
  73. package/dist/builtin/subagents/src/tui/render-chain-graph.ts +10 -4
  74. package/dist/builtin/subagents/src/tui/render-event-formatting.ts +12 -11
  75. package/dist/builtin/subagents/src/tui/render-result-compact.ts +49 -12
  76. package/dist/builtin/subagents/src/tui/render-result.ts +46 -17
  77. package/dist/builtin/subagents/src/tui/render-stable-output.ts +1 -1
  78. package/dist/builtin/subagents/src/tui/render-status-progress.ts +8 -5
  79. package/dist/builtin/subagents/src/tui/render-widget-graph.ts +0 -8
  80. package/dist/builtin/subagents/src/tui/render-widget.ts +0 -24
  81. package/dist/builtin/web-access/package.json +1 -1
  82. package/dist/builtin/workflows/CHANGELOG.md +25 -0
  83. package/dist/builtin/workflows/README.md +13 -3
  84. package/dist/builtin/workflows/package.json +1 -1
  85. package/dist/builtin/workflows/src/durable/backend.ts +7 -0
  86. package/dist/builtin/workflows/src/durable/dbos-metadata.ts +11 -1
  87. package/dist/builtin/workflows/src/durable/resume-runtime.ts +1 -0
  88. package/dist/builtin/workflows/src/durable/tool-primitive.ts +4 -28
  89. package/dist/builtin/workflows/src/durable/types.ts +5 -0
  90. package/dist/builtin/workflows/src/engine/run.ts +17 -1
  91. package/dist/builtin/workflows/src/extension/atomic-stage-session.ts +12 -39
  92. package/dist/builtin/workflows/src/extension/config-file-loader.ts +10 -1
  93. package/dist/builtin/workflows/src/extension/config-loader.ts +1 -1
  94. package/dist/builtin/workflows/src/extension/dispatcher.ts +4 -0
  95. package/dist/builtin/workflows/src/extension/index.bundle.mjs +1151 -737
  96. package/dist/builtin/workflows/src/extension/lifecycle-notifications.ts +303 -38
  97. package/dist/builtin/workflows/src/extension/render-result.ts +4 -0
  98. package/dist/builtin/workflows/src/extension/runtime-durable-resume.ts +6 -3
  99. package/dist/builtin/workflows/src/extension/runtime.ts +7 -1
  100. package/dist/builtin/workflows/src/extension/wiring.ts +53 -11
  101. package/dist/builtin/workflows/src/extension/workflow-command-registration.ts +12 -3
  102. package/dist/builtin/workflows/src/extension/workflow-durable-resume-command.ts +5 -2
  103. package/dist/builtin/workflows/src/extension/workflow-run-control-command.ts +9 -7
  104. package/dist/builtin/workflows/src/extension/workflow-status-summary.ts +11 -0
  105. package/dist/builtin/workflows/src/extension/workflow-tool-content.ts +18 -1
  106. package/dist/builtin/workflows/src/extension/workflow-tool-control.ts +10 -8
  107. package/dist/builtin/workflows/src/extension/workflow-tool.ts +9 -4
  108. package/dist/builtin/workflows/src/runs/background/quit.ts +28 -4
  109. package/dist/builtin/workflows/src/runs/background/resume-acknowledgements.ts +2 -1
  110. package/dist/builtin/workflows/src/runs/background/status.ts +55 -8
  111. package/dist/builtin/workflows/src/runs/foreground/executor-direct-helpers.ts +4 -0
  112. package/dist/builtin/workflows/src/runs/foreground/executor-prompt-nodes.ts +3 -1
  113. package/dist/builtin/workflows/src/runs/foreground/executor-stage-control.ts +1 -1
  114. package/dist/builtin/workflows/src/runs/foreground/stage-runner-context.ts +1 -1
  115. package/dist/builtin/workflows/src/runs/foreground/stage-runner-controller.ts +688 -38
  116. package/dist/builtin/workflows/src/runs/foreground/stage-runner-types.ts +3 -1
  117. package/dist/builtin/workflows/src/runs/shared/model-fallback-failures.ts +19 -514
  118. package/dist/builtin/workflows/src/runs/shared/retry.ts +44 -0
  119. package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +5 -0
  120. package/dist/builtin/workflows/src/shared/authoring-contract-stage.ts +6 -0
  121. package/dist/builtin/workflows/src/shared/authoring-contract-ui.d.ts +5 -1
  122. package/dist/builtin/workflows/src/shared/authoring-contract-ui.ts +5 -0
  123. package/dist/builtin/workflows/src/shared/persistence-restore-helpers.ts +5 -0
  124. package/dist/builtin/workflows/src/shared/persistence-restore.ts +3 -0
  125. package/dist/builtin/workflows/src/shared/persistence-session-entries.ts +4 -0
  126. package/dist/builtin/workflows/src/shared/run-indicator-status.ts +75 -0
  127. package/dist/builtin/workflows/src/shared/store-public-types.ts +43 -7
  128. package/dist/builtin/workflows/src/shared/store-run-methods.ts +42 -8
  129. package/dist/builtin/workflows/src/shared/store-stage-methods.ts +31 -8
  130. package/dist/builtin/workflows/src/shared/store-types.ts +34 -0
  131. package/dist/builtin/workflows/src/shared/timing.ts +10 -0
  132. package/dist/builtin/workflows/src/tui/chat-surface-message.ts +22 -2
  133. package/dist/builtin/workflows/src/tui/session-list.ts +1 -1
  134. package/dist/builtin/workflows/src/tui/session-overlays.ts +14 -10
  135. package/dist/builtin/workflows/src/tui/session-picker.ts +20 -4
  136. package/dist/builtin/workflows/src/tui/status-list.ts +31 -47
  137. package/dist/builtin/workflows/src/tui/store-widget-installer.ts +9 -1
  138. package/dist/builtin/workflows/src/tui/widget.ts +16 -46
  139. package/dist/core/agent-session-auto-compaction.d.ts.map +1 -1
  140. package/dist/core/agent-session-auto-compaction.js +54 -11
  141. package/dist/core/agent-session-auto-compaction.js.map +1 -1
  142. package/dist/core/agent-session-events.d.ts.map +1 -1
  143. package/dist/core/agent-session-events.js +49 -14
  144. package/dist/core/agent-session-events.js.map +1 -1
  145. package/dist/core/agent-session-methods.d.ts +13 -0
  146. package/dist/core/agent-session-methods.d.ts.map +1 -1
  147. package/dist/core/agent-session-methods.js.map +1 -1
  148. package/dist/core/agent-session-models.d.ts.map +1 -1
  149. package/dist/core/agent-session-models.js +12 -1
  150. package/dist/core/agent-session-models.js.map +1 -1
  151. package/dist/core/agent-session-prompt.d.ts.map +1 -1
  152. package/dist/core/agent-session-prompt.js +4 -0
  153. package/dist/core/agent-session-prompt.js.map +1 -1
  154. package/dist/core/agent-session-retry.d.ts +21 -4
  155. package/dist/core/agent-session-retry.d.ts.map +1 -1
  156. package/dist/core/agent-session-retry.js +232 -106
  157. package/dist/core/agent-session-retry.js.map +1 -1
  158. package/dist/core/agent-session-state.d.ts.map +1 -1
  159. package/dist/core/agent-session-state.js +2 -1
  160. package/dist/core/agent-session-state.js.map +1 -1
  161. package/dist/core/agent-session-tool-hooks.d.ts.map +1 -1
  162. package/dist/core/agent-session-tool-hooks.js +12 -0
  163. package/dist/core/agent-session-tool-hooks.js.map +1 -1
  164. package/dist/core/agent-session-tool-registry.d.ts.map +1 -1
  165. package/dist/core/agent-session-tool-registry.js +1 -1
  166. package/dist/core/agent-session-tool-registry.js.map +1 -1
  167. package/dist/core/agent-session-types.d.ts +3 -1
  168. package/dist/core/agent-session-types.d.ts.map +1 -1
  169. package/dist/core/agent-session-types.js.map +1 -1
  170. package/dist/core/agent-session.d.ts +12 -1
  171. package/dist/core/agent-session.d.ts.map +1 -1
  172. package/dist/core/agent-session.js +7 -0
  173. package/dist/core/agent-session.js.map +1 -1
  174. package/dist/core/extensions/context-types.d.ts +25 -0
  175. package/dist/core/extensions/context-types.d.ts.map +1 -1
  176. package/dist/core/extensions/context-types.js.map +1 -1
  177. package/dist/core/extensions/index.d.ts +1 -1
  178. package/dist/core/extensions/index.d.ts.map +1 -1
  179. package/dist/core/extensions/index.js.map +1 -1
  180. package/dist/core/extensions/runner-context.d.ts +2 -1
  181. package/dist/core/extensions/runner-context.d.ts.map +1 -1
  182. package/dist/core/extensions/runner-context.js +4 -0
  183. package/dist/core/extensions/runner-context.js.map +1 -1
  184. package/dist/core/extensions/runner.d.ts +3 -2
  185. package/dist/core/extensions/runner.d.ts.map +1 -1
  186. package/dist/core/extensions/runner.js +3 -1
  187. package/dist/core/extensions/runner.js.map +1 -1
  188. package/dist/core/model-fallback-failures.d.ts +30 -0
  189. package/dist/core/model-fallback-failures.d.ts.map +1 -0
  190. package/dist/core/model-fallback-failures.js +610 -0
  191. package/dist/core/model-fallback-failures.js.map +1 -0
  192. package/dist/core/retry-policy.d.ts +30 -0
  193. package/dist/core/retry-policy.d.ts.map +1 -0
  194. package/dist/core/retry-policy.js +25 -0
  195. package/dist/core/retry-policy.js.map +1 -0
  196. package/dist/core/sdk-types.d.ts +8 -2
  197. package/dist/core/sdk-types.d.ts.map +1 -1
  198. package/dist/core/sdk-types.js.map +1 -1
  199. package/dist/core/sdk.d.ts.map +1 -1
  200. package/dist/core/sdk.js +6 -1
  201. package/dist/core/sdk.js.map +1 -1
  202. package/dist/core/session-manager-core.d.ts +2 -0
  203. package/dist/core/session-manager-core.d.ts.map +1 -1
  204. package/dist/core/session-manager-core.js +7 -0
  205. package/dist/core/session-manager-core.js.map +1 -1
  206. package/dist/index-extensions.d.ts +1 -1
  207. package/dist/index-extensions.d.ts.map +1 -1
  208. package/dist/index-extensions.js.map +1 -1
  209. package/dist/index.d.ts +3 -0
  210. package/dist/index.d.ts.map +1 -1
  211. package/dist/index.js +2 -0
  212. package/dist/index.js.map +1 -1
  213. package/docs/intercom.md +5 -10
  214. package/docs/settings.md +7 -1
  215. package/docs/subagents.md +19 -19
  216. package/docs/workflows.md +21 -5
  217. package/examples/extensions/gondolin/package-lock.json +3 -3
  218. package/npm-shrinkwrap.json +29 -29
  219. package/package.json +2 -2
  220. package/dist/builtin/subagents/src/runs/background/async-event-journal.ts +0 -112
  221. package/dist/builtin/subagents/src/runs/background/async-execution-chain.ts +0 -543
  222. package/dist/builtin/subagents/src/runs/background/async-execution-common.ts +0 -140
  223. package/dist/builtin/subagents/src/runs/background/async-execution-single.ts +0 -279
  224. package/dist/builtin/subagents/src/runs/background/async-execution-types.ts +0 -99
  225. package/dist/builtin/subagents/src/runs/background/async-execution.ts +0 -17
  226. package/dist/builtin/subagents/src/runs/background/async-resume.ts +0 -402
  227. package/dist/builtin/subagents/src/runs/background/async-status.ts +0 -411
  228. package/dist/builtin/subagents/src/runs/background/completion-claims.ts +0 -196
  229. package/dist/builtin/subagents/src/runs/background/completion-dedupe.ts +0 -102
  230. package/dist/builtin/subagents/src/runs/background/parallel-groups.ts +0 -59
  231. package/dist/builtin/subagents/src/runs/background/result-delivery-processor.ts +0 -300
  232. package/dist/builtin/subagents/src/runs/background/result-file-claims.ts +0 -166
  233. package/dist/builtin/subagents/src/runs/background/result-quarantine.ts +0 -77
  234. package/dist/builtin/subagents/src/runs/background/result-retry-scheduler.ts +0 -48
  235. package/dist/builtin/subagents/src/runs/background/result-status.ts +0 -87
  236. package/dist/builtin/subagents/src/runs/background/result-watcher-data.ts +0 -72
  237. package/dist/builtin/subagents/src/runs/background/result-watcher.ts +0 -320
  238. package/dist/builtin/subagents/src/runs/background/run-id-resolver.ts +0 -105
  239. package/dist/builtin/subagents/src/runs/background/run-status.ts +0 -358
  240. package/dist/builtin/subagents/src/runs/background/stale-run-reconciler.ts +0 -457
  241. package/dist/builtin/subagents/src/runs/background/subagent-runner-dynamic.ts +0 -376
  242. package/dist/builtin/subagents/src/runs/background/subagent-runner-finalize.ts +0 -150
  243. package/dist/builtin/subagents/src/runs/background/subagent-runner-output.ts +0 -109
  244. package/dist/builtin/subagents/src/runs/background/subagent-runner-parallel-helpers.ts +0 -128
  245. package/dist/builtin/subagents/src/runs/background/subagent-runner-parallel.ts +0 -309
  246. package/dist/builtin/subagents/src/runs/background/subagent-runner-sequential.ts +0 -173
  247. package/dist/builtin/subagents/src/runs/background/subagent-runner-state.ts +0 -578
  248. package/dist/builtin/subagents/src/runs/background/subagent-runner-step.ts +0 -330
  249. package/dist/builtin/subagents/src/runs/background/subagent-runner-streaming.ts +0 -330
  250. package/dist/builtin/subagents/src/runs/background/subagent-runner-types.ts +0 -210
  251. package/dist/builtin/subagents/src/runs/background/subagent-runner-utils.ts +0 -69
  252. package/dist/builtin/subagents/src/runs/background/subagent-runner.ts +0 -90
  253. package/dist/builtin/subagents/src/runs/background/top-level-async.ts +0 -12
  254. package/dist/builtin/subagents/src/runs/foreground/execution-attempt-control.ts +0 -140
  255. package/dist/builtin/subagents/src/runs/foreground/execution-attempt-finalize.ts +0 -108
  256. package/dist/builtin/subagents/src/runs/foreground/execution-attempt-types.ts +0 -17
  257. package/dist/builtin/subagents/src/runs/foreground/execution-attempt.ts +0 -558
  258. package/dist/builtin/subagents/src/runs/shared/attempt-watchdog.ts +0 -126
  259. package/dist/builtin/subagents/src/runs/shared/final-drain.ts +0 -39
  260. package/dist/builtin/subagents/src/runs/shared/pi-args.ts +0 -339
  261. package/dist/builtin/subagents/src/runs/shared/pi-spawn.ts +0 -165
  262. package/dist/builtin/subagents/src/runs/shared/spawn-env.ts +0 -21
  263. package/dist/builtin/subagents/src/shared/post-exit-stdio-guard.ts +0 -86
  264. /package/dist/builtin/subagents/src/runs/{shared/nested-path.ts → inprocess/runtime-support/nested-paths.ts} +0 -0
@@ -7,6 +7,8 @@
7
7
 
8
8
  Default to workflows for non-trivial work and requests with inherent structure plus a verifiable objective; reserve direct chat for tiny deterministic low-risk work. Workflow-first is not builtin-only or monolithic: Atomic can author custom TypeScript `workflow({...})` definitions inline, import reusable project/package workflows or builtins from `@bastani/workflows/builtin`, and nest them with `ctx.workflow(...)`. Imported children may nest further workflows within `maxDepth`, so compose proven research, implementation, design, verification, and approval graphs rather than copying them. Custom parents can also use runtime classification, dynamic fan-out and synthesis, adversarial verification, candidate tournaments, HIL gates, and bounded convergence.
9
9
 
10
+ Workflow stage sessions are created in process and receive a typed stage policy rather than inheriting subagent environment flags. Resource reload never mutates `process.env`; stage options carry the subagent management/fanout policy directly, so concurrent stage creation is race-free while existing tool allowlists and orchestration depth limits remain authoritative. Legacy child environment keys are only a compatibility path for older hosts.
11
+
10
12
  <p align="center">
11
13
  <a href="#authoring-api">Authoring API</a>
12
14
  &nbsp;·&nbsp;
@@ -43,19 +45,27 @@ After Atomic is running, use `/workflow reload` or the workflow tool's `reload`
43
45
 
44
46
  ### Workflow lifecycle notifications
45
47
 
46
- Workflow lifecycle notices are enabled by default. They send steer prompts into the main chat/model context when a run completes, fails, or ends blocked. Awaiting-input prompts are tracked for dedupe/restore, but they do not wake the main chat agent. Configure lifecycle tracking in the same extension config file:
48
+ Workflow lifecycle notices are enabled by default. They send steer prompts into the main chat/model context when a run completes, fails, or ends blocked, and when a user starts, pauses, quits, or resumes one. Awaiting-input prompts are tracked for dedupe/restore, but they do not wake the main chat agent. Configure lifecycle tracking in the same extension config file:
47
49
 
48
50
  ```json
49
51
  {
50
52
  "workflowNotifications": {
51
53
  "enabled": true,
52
- "notifyOn": ["completed", "failed", "blocked", "awaiting_input"]
54
+ "notifyOn": ["started", "completed", "failed", "blocked", "awaiting_input", "paused", "quit", "resumed"]
53
55
  }
54
56
  }
55
57
  ```
56
58
 
57
59
  Set `enabled` to `false` to disable all lifecycle notices, or narrow `notifyOn` to a non-empty list of selected events. Completion, failure, and blocked lifecycle notices are emitted for top-level workflow runs, use steer delivery, and wake an idle model so the lifecycle update enters the model context when it happens. When a fulfilled workflow body leaves admitted tool failures, the engine promotes the first admission and persists that exact tool origin for the failed notice. Ordinary body rejections retain their original error and failed graph nodes without claiming a tool origin because transparent native promises do not expose the source promise; this prevents a caught tool rejection from being misattributed when body code later throws the same object or primitive. Nested child workflow completion/failure is reflected inside the expanded parent graph instead of producing separate top-level completion cards. Awaiting-input states are tracked for dedupe/restore, but workflows do not enqueue main-chat `/workflow connect` cards for them; prompt state remains visible through workflow status/connect surfaces, avoiding stale actionable cards if a prompt resolves while the main chat is streaming.
58
60
 
61
+ Control notices report deliberate actions on a top-level run: `/workflow <name>` produces a `WORKFLOW STARTED` card (`▶`), `/workflow pause` a `WORKFLOW PAUSED` card (`⏸`, warning tone), `/workflow quit` a `WORKFLOW QUIT` card (`⏹`, warning tone, plus a `resumable` field), and `/workflow resume` a `WORKFLOW RESUMED` card (`▶`). All four travel the same steer delivery, capped-backoff retry, and card path as the failure notice. The paused and quit text says the stop was deliberate and user-requested and instructs the model not to resume the run or take the work over unless asked, hinting `/workflow resume <run-id>`; the resumed text does not, since the run is progressing again.
62
+
63
+ Only user actions notify. The matching `workflow({ action: "run" | "pause" | "quit" | "resume" })` tool calls stay silent, because the tool result already reports them to the agent, and `/workflow interrupt` raises nothing. Engine-internal transitions stay silent too — a notice exists only when a control path named an actor — which is what keeps answering a human-in-the-loop prompt, per-stage control, and the resume-acknowledgement pass from flooding the chat.
64
+
65
+ Each notice carries two attributions. *Origin* is who launched the run and renders on every kind as "which you started" or "which the user started"; it is recorded once at dispatch, persisted through session restore and durable resume, and inherited by a continuation from the run it continues. *Actor* is who performed this one event ("The user paused"). A run with no recorded origin omits the clause rather than guessing one.
66
+
67
+ One request produces one notice. A whole-run pause or resume reports at run scope; a stage-scoped pause or resume that leaves siblings paused reports at stage scope, and one that stops or restarts the whole run reports the run instead. A quit reports the quit alone, never the pause it publishes on the way. Because control actions are reversible, they are deduplicated by run id together with the occurrence timestamp (`pausedAt`/`quitAt`/`resumedAt`), so pause → resume → pause → resume notifies four times while repeated snapshot invalidations at one unchanged state notify once. Resuming reports a resume and never a start, whoever asked for it. Resuming a failed or blocked run launches a continuation under a fresh run id and its notice names both; resuming a quit run reuses the original workflow id so durable checkpoints replay, so that notice names the one id. A run already started, paused, or quit when notifications install (restore, replay, `/reload`, session-preserving reinstall) is seeded as delivered and stays silent, and nested child runs never notify at top level.
68
+
59
69
  When a stage human-in-the-loop prompt is answered from the workflow TUI/stage chat, workflows also emits a separate display-only `workflows:hil-answer-notice` custom message. It records the answer for user-visible audit, but it does not wake the main agent, enter LLM context, or authorize answering later workflow prompts. Answers sent by the main-chat `workflow` tool do not emit this notice because the tool result already tells the main agent what happened.
60
70
 
61
71
  ---
@@ -802,7 +812,7 @@ Config-based discovery (`~/.atomic/agent/extensions/workflow/config.json` or `.a
802
812
  },
803
813
  "workflowNotifications": {
804
814
  "enabled": true,
805
- "notifyOn": ["completed", "failed", "blocked", "awaiting_input"]
815
+ "notifyOn": ["started", "completed", "failed", "blocked", "awaiting_input", "paused", "quit", "resumed"]
806
816
  }
807
817
  }
808
818
  ```
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/workflows",
3
- "version": "0.9.12",
3
+ "version": "0.9.13-alpha.1",
4
4
  "private": true,
5
5
  "description": "Atomic extension for multi-stage workflow authoring and execution.",
6
6
  "contributors": [
@@ -203,6 +203,11 @@ export class InMemoryDurableBackend implements DurableWorkflowBackend {
203
203
  : existing?.handle.invocationCwd !== undefined
204
204
  ? { invocationCwd: existing.handle.invocationCwd }
205
205
  : {}),
206
+ ...(handle.origin !== undefined
207
+ ? { origin: handle.origin }
208
+ : existing?.handle.origin !== undefined
209
+ ? { origin: existing.handle.origin }
210
+ : {}),
206
211
  ...(handle.workflowCwd !== undefined
207
212
  ? { workflowCwd: handle.workflowCwd }
208
213
  : existing?.handle.workflowCwd !== undefined
@@ -474,6 +479,7 @@ export class InMemoryDurableBackend implements DurableWorkflowBackend {
474
479
  ...(h.resumable !== undefined ? { resumable: h.resumable } : {}),
475
480
  ...workflowFailureFields(h),
476
481
  ...(h.invocationCwd !== undefined ? { invocationCwd: h.invocationCwd } : {}),
482
+ ...(h.origin !== undefined ? { origin: h.origin } : {}),
477
483
  ...(h.workflowCwd !== undefined ? { workflowCwd: h.workflowCwd } : {}),
478
484
  ...(h.repositoryRoot !== undefined ? { repositoryRoot: h.repositoryRoot } : {}),
479
485
  ...(h.gitWorktreeRoot !== undefined ? { gitWorktreeRoot: h.gitWorktreeRoot } : {}),
@@ -554,6 +560,7 @@ function toResumableEntry(handle: DurableWorkflowHandle): ResumableWorkflowEntry
554
560
  ...(handle.resumable !== undefined ? { resumable: handle.resumable } : {}),
555
561
  ...workflowFailureFields(handle),
556
562
  ...(handle.invocationCwd !== undefined ? { invocationCwd: handle.invocationCwd } : {}),
563
+ ...(handle.origin !== undefined ? { origin: handle.origin } : {}),
557
564
  ...(handle.workflowCwd !== undefined ? { workflowCwd: handle.workflowCwd } : {}),
558
565
  ...(handle.repositoryRoot !== undefined ? { repositoryRoot: handle.repositoryRoot } : {}),
559
566
  ...(handle.gitWorktreeRoot !== undefined ? { gitWorktreeRoot: handle.gitWorktreeRoot } : {}),
@@ -1,3 +1,4 @@
1
+ import type { WorkflowActor } from "../shared/store-types.js";
1
2
  import type { WorkflowSerializableValue } from "../shared/types.js";
2
3
  import {
3
4
  isWorkflowFailureCode,
@@ -66,6 +67,7 @@ export function encodeMetadata(metadata: DurableWorkflowMetadata): WorkflowSeria
66
67
  : {}),
67
68
  ...(metadata.failureDisposition !== undefined ? { failureDisposition: metadata.failureDisposition } : {}),
68
69
  ...(metadata.failedToolNodeId !== undefined ? { failedToolNodeId: metadata.failedToolNodeId } : {}),
70
+ ...(metadata.origin !== undefined ? { origin: metadata.origin } : {}),
69
71
  ...(metadata.invocationCwd !== undefined ? { invocationCwd: metadata.invocationCwd } : {}),
70
72
  ...(metadata.workflowCwd !== undefined ? { workflowCwd: metadata.workflowCwd } : {}),
71
73
  ...(metadata.repositoryRoot !== undefined ? { repositoryRoot: metadata.repositoryRoot } : {}),
@@ -167,7 +169,15 @@ function parseDurableWorkflowMetadata(
167
169
  (metadata.gitWorktreeRoot !== undefined && typeof metadata.gitWorktreeRoot !== "string")
168
170
  )
169
171
  return undefined;
170
- return metadata as DurableWorkflowMetadata;
172
+ const { origin, ...metadataWithoutOrigin } = metadata;
173
+ return {
174
+ ...metadataWithoutOrigin,
175
+ ...(isWorkflowActor(origin) ? { origin } : {}),
176
+ } as DurableWorkflowMetadata;
177
+ }
178
+
179
+ function isWorkflowActor(value: WorkflowSerializableValue | undefined): value is WorkflowActor {
180
+ return value === "user" || value === "agent";
171
181
  }
172
182
 
173
183
  function isDurableWorkflowStatus(value: string): value is DurableWorkflowStatus {
@@ -206,6 +206,7 @@ export async function resumeDurableWorkflow(
206
206
  const resumeRunOpts: RunOpts = {
207
207
  ...deps.baseRunOpts,
208
208
  ...(handle.invocationCwd !== undefined ? { cwd: handle.invocationCwd } : {}),
209
+ ...(handle.origin !== undefined ? { origin: handle.origin } : {}),
209
210
  runId: resolved.workflowId,
210
211
  durableBackend: backend,
211
212
  };
@@ -16,6 +16,7 @@
16
16
  */
17
17
 
18
18
  import { runCallback } from "@bastani/atomic";
19
+ import { sleepOrAbort } from "../runs/shared/retry.js";
19
20
  import { flattenTruncatedString } from "../shared/flat-string.js";
20
21
  import type { ToolNodeSnapshot } from "../shared/store-types.js";
21
22
  import type {
@@ -26,6 +27,9 @@ import type {
26
27
  WorkflowToolPrimitive,
27
28
  } from "../shared/types.js";
28
29
  import { field, hasProcessFailureEvidence, normalizeCode } from "../shared/workflow-failures-signals.js";
30
+
31
+ export { sleepOrAbort } from "../runs/shared/retry.js";
32
+
29
33
  import type { DurableWorkflowBackend } from "./backend.js";
30
34
  import { durableHash } from "./backend.js";
31
35
  import { recordThrowingToolFailure } from "./tool-failure-checkpoint.js";
@@ -660,34 +664,6 @@ async function executeWithRetries<T>(
660
664
  throw lastError ?? new Error("ctx.tool: retries exhausted");
661
665
  }
662
666
 
663
- export function sleepOrAbort(ms: number, signal?: AbortSignal): Promise<void> {
664
- if (signal?.aborted)
665
- return Promise.reject(
666
- signal.reason instanceof Error ? signal.reason : new Error("atomic-workflows: workflow cancelled"),
667
- );
668
- return new Promise((resolve, reject) => {
669
- let settled = false;
670
- const cleanup = (): void => signal?.removeEventListener("abort", onAbort);
671
- const finish = (): void => {
672
- if (settled) return;
673
- settled = true;
674
- cleanup();
675
- resolve();
676
- };
677
- const fail = (err: Error): void => {
678
- if (settled) return;
679
- settled = true;
680
- clearTimeout(timer);
681
- cleanup();
682
- reject(err);
683
- };
684
- const timer = setTimeout(finish, ms);
685
- const onAbort = (): void =>
686
- fail(signal?.reason instanceof Error ? signal.reason : new Error("atomic-workflows: workflow cancelled"));
687
- signal?.addEventListener("abort", onAbort, { once: true });
688
- });
689
- }
690
-
691
667
  /**
692
668
  * Create a monotonic checkpoint id generator for a workflow.
693
669
  */
@@ -10,6 +10,7 @@
10
10
  */
11
11
 
12
12
  import type {
13
+ WorkflowActor,
13
14
  WorkflowFailureCode,
14
15
  WorkflowFailureDisposition,
15
16
  WorkflowFailureKind,
@@ -40,6 +41,8 @@ export interface DurableWorkflowHandle {
40
41
  readonly status: DurableWorkflowStatus;
41
42
  /** Original invocation cwd used to resolve repo-relative workflow defaults on resume. */
42
43
  readonly invocationCwd?: string;
44
+ /** Who launched this workflow, when the launcher was attributable. */
45
+ readonly origin?: WorkflowActor;
43
46
  /** Resolved workflow cwd when an input-bound reusable worktree was set up. */
44
47
  readonly workflowCwd?: string;
45
48
  /** Invoking repository root used for reusable worktree validation. */
@@ -276,6 +279,7 @@ export interface DurableWorkflowMetadata {
276
279
  readonly rootWorkflowId?: string;
277
280
  readonly resumable?: boolean;
278
281
  readonly invocationCwd?: string;
282
+ readonly origin?: WorkflowActor;
279
283
  readonly workflowCwd?: string;
280
284
  readonly repositoryRoot?: string;
281
285
  readonly gitWorktreeRoot?: string;
@@ -301,6 +305,7 @@ export interface ResumableWorkflowEntry {
301
305
  readonly rootWorkflowId?: string;
302
306
  readonly resumable?: boolean;
303
307
  readonly invocationCwd?: string;
308
+ readonly origin?: WorkflowActor;
304
309
  readonly workflowCwd?: string;
305
310
  readonly repositoryRoot?: string;
306
311
  readonly gitWorktreeRoot?: string;
@@ -164,6 +164,7 @@ export async function run<TInputs extends WorkflowInputValues, TRunInputs extend
164
164
  opts.parentRun === undefined
165
165
  ? inheritedRunElapsedMs({ backend: durableBackend, runId, continuationSource: opts.continuation?.source })
166
166
  : undefined;
167
+ const continuationOrigin = opts.continuation !== undefined ? opts.continuation.source.origin : opts.origin;
167
168
  const runSnapshot: RunSnapshot = {
168
169
  id: runId,
169
170
  name: def.name,
@@ -185,6 +186,15 @@ export async function run<TInputs extends WorkflowInputValues, TRunInputs extend
185
186
  resumeFromStageId: opts.continuation.resumeFromStageId,
186
187
  }
187
188
  : {}),
189
+ // A continuation keeps the attribution of the run it continues rather than
190
+ // recomputing it, so resuming an agent-started run still reads as one the
191
+ // agent started. Only the resume itself is attributed to its requester.
192
+ ...(continuationOrigin !== undefined ? { origin: continuationOrigin } : {}),
193
+ // A resumed run reports the resume that produced it, never a fresh start —
194
+ // whether it continues under a new id or reclaims the original one.
195
+ ...(opts.resumeActor !== undefined
196
+ ? { resumeActor: opts.resumeActor, resumeSource: "run_control" as const }
197
+ : {}),
188
198
  ...(inheritedElapsedMs !== undefined ? { accumulatedDurationMs: inheritedElapsedMs } : {}),
189
199
  };
190
200
  const classifiedFailures = new Map<unknown, WorkflowFailure>();
@@ -216,6 +226,7 @@ export async function run<TInputs extends WorkflowInputValues, TRunInputs extend
216
226
  ...(runSnapshot.parentStageId !== undefined ? { parentStageId: runSnapshot.parentStageId } : {}),
217
227
  ...(runSnapshot.rootRunId !== undefined ? { rootRunId: runSnapshot.rootRunId } : {}),
218
228
  ...(runSnapshot.resumedFromRunId !== undefined ? { resumedFromRunId: runSnapshot.resumedFromRunId } : {}),
229
+ ...(runSnapshot.origin !== undefined ? { origin: runSnapshot.origin } : {}),
219
230
  ...(runSnapshot.resumeFromStageId !== undefined ? { resumeFromStageId: runSnapshot.resumeFromStageId } : {}),
220
231
  ...(runSnapshot.accumulatedDurationMs !== undefined
221
232
  ? { accumulatedDurationMs: runSnapshot.accumulatedDurationMs }
@@ -550,7 +561,12 @@ export async function run<TInputs extends WorkflowInputValues, TRunInputs extend
550
561
  ? undefined
551
562
  : {
552
563
  ...durableRootRegistration,
553
- ...workflowInvocationMetadata(inputRuntimeDefaults, workflowInvocationCwd, gitWorktreeSetupCache),
564
+ ...workflowInvocationMetadata(
565
+ inputRuntimeDefaults,
566
+ workflowInvocationCwd,
567
+ gitWorktreeSetupCache,
568
+ runSnapshot.origin,
569
+ ),
554
570
  },
555
571
  });
556
572
  if (opts.deferWorkflowStart === true) opts.onWorkflowStartReady?.();
@@ -3,11 +3,13 @@ import type {
3
3
  CreateAgentSessionOptions,
4
4
  DefaultResourceLoaderInheritanceSnapshot,
5
5
  PackageSource,
6
+ SubagentChildPolicy,
6
7
  } from "@bastani/atomic";
7
8
  import type { StageSessionRuntime } from "../runs/foreground/stage-runner.js";
8
9
 
9
10
  export interface PiSdkSettingsManager {
10
11
  getCodexFastModeSettings(): { readonly chat: boolean; readonly workflow: boolean };
12
+ getRetrySettings?(): { readonly enabled: boolean; readonly maxRetries: number; readonly baseDelayMs: number };
11
13
  }
12
14
 
13
15
  export interface PiSdkResourceLoader {
@@ -45,8 +47,14 @@ export type AtomicCreateAgentSessionOptions = Omit<
45
47
 
46
48
  export interface PrepareAtomicStageSessionOptions {
47
49
  resourceLoaderInheritanceSnapshot?: DefaultResourceLoaderInheritanceSnapshot;
50
+ onSettingsManager?: (settingsManager: PiSdkSettingsManager) => void;
48
51
  }
49
-
52
+ const WORKFLOW_STAGE_SUBAGENT_POLICY: SubagentChildPolicy = {
53
+ managementActions: "full",
54
+ fanoutAuthorized: false,
55
+ inheritProjectContext: true,
56
+ inheritSkills: true,
57
+ };
50
58
  function resolveSessionCwd(options: AtomicCreateAgentSessionOptions | undefined): string {
51
59
  return options?.cwd ?? options?.sessionManager?.getCwd() ?? process.cwd();
52
60
  }
@@ -87,6 +95,7 @@ export async function prepareAtomicStageSessionOptions(
87
95
  ? undefined
88
96
  : { projectTrusted: inheritanceSnapshot.projectTrusted },
89
97
  );
98
+ prepareOptions.onSettingsManager?.(settingsManager);
90
99
  const inheritedBuiltinPackagePaths = inheritanceSnapshot?.builtinPackagePaths;
91
100
  const builtinPackagePaths =
92
101
  inheritedBuiltinPackagePaths === undefined
@@ -107,6 +116,7 @@ export async function prepareAtomicStageSessionOptions(
107
116
  ...(hasAgentDirOverride ? { agentDir } : {}),
108
117
  settingsManager,
109
118
  resourceLoader,
119
+ subagentPolicy: WORKFLOW_STAGE_SUBAGENT_POLICY,
110
120
  };
111
121
  }
112
122
 
@@ -143,47 +153,10 @@ function stageBuiltinPackagePaths(paths: readonly PackageSource[]): PackageSourc
143
153
  });
144
154
  }
145
155
 
146
- const SUBAGENT_CHILD_EXTENSION_ENV_KEYS = [
147
- "ATOMIC_SUBAGENT_CHILD",
148
- "ATOMIC_SUBAGENT_FANOUT_CHILD",
149
- "PI_SUBAGENT_CHILD",
150
- "PI_SUBAGENT_FANOUT_CHILD",
151
- ] as const;
152
-
153
156
  let workflowStageResourceReloadQueue: Promise<void> = Promise.resolve();
154
157
 
155
158
  async function reloadWorkflowStageResources(resourceLoader: PiSdkResourceLoader): Promise<void> {
156
- const queuedReload = workflowStageResourceReloadQueue.then(() =>
157
- reloadWorkflowStageResourcesWithEnvIsolation(resourceLoader),
158
- );
159
+ const queuedReload = workflowStageResourceReloadQueue.then(() => resourceLoader.reload());
159
160
  workflowStageResourceReloadQueue = queuedReload.catch(() => undefined);
160
161
  return queuedReload;
161
162
  }
162
-
163
- async function reloadWorkflowStageResourcesWithEnvIsolation(resourceLoader: PiSdkResourceLoader): Promise<void> {
164
- // Workflow stage sessions are already governed by an orchestration context
165
- // that disables recursive workflow tools and caps nested subagent depth. When
166
- // a workflow itself runs inside a subagent child process, inherited subagent
167
- // child env flags would otherwise make the bundled subagents extension skip
168
- // registering its `subagent` tool before the stage session exists. Isolate
169
- // extension discovery from those parent-process flags so an explicit
170
- // `tools: ["subagent"]` allowlist works the same in workflow stages everywhere.
171
- // The isolation mutates process-global env, so serialize the full
172
- // save/delete/reload/restore section. Without this queue, overlapping workflow
173
- // stage session creation can snapshot an already-cleared env and restore that
174
- // stale snapshot after another reload restores the real parent values.
175
- const previousValues = new Map<string, string | undefined>();
176
- for (const key of SUBAGENT_CHILD_EXTENSION_ENV_KEYS) {
177
- previousValues.set(key, process.env[key]);
178
- delete process.env[key];
179
- }
180
- try {
181
- await resourceLoader.reload();
182
- } finally {
183
- for (const key of SUBAGENT_CHILD_EXTENSION_ENV_KEYS) {
184
- const previousValue = previousValues.get(key);
185
- if (previousValue === undefined) delete process.env[key];
186
- else process.env[key] = previousValue;
187
- }
188
- }
189
- }
@@ -2,6 +2,15 @@ import type { ConfigDiagnostic, WorkflowExtensionConfig } from "./config-loader.
2
2
  import { WORKFLOW_LIFECYCLE_NOTICE_KINDS, type WorkflowLifecycleNoticeKind } from "./lifecycle-notifications.js";
3
3
 
4
4
  const WORKFLOW_LIFECYCLE_NOTICE_KIND_SET = new Set<string>(WORKFLOW_LIFECYCLE_NOTICE_KINDS);
5
+ /**
6
+ * Every accepted lifecycle kind, quoted for the rejection message, so adding a
7
+ * kind can never leave the error naming a stale subset of what validates.
8
+ */
9
+ const WORKFLOW_LIFECYCLE_NOTICE_KIND_LIST = ((): string => {
10
+ const quoted = WORKFLOW_LIFECYCLE_NOTICE_KINDS.map((kind) => JSON.stringify(kind));
11
+ const last = quoted[quoted.length - 1] ?? "";
12
+ return quoted.length <= 1 ? last : `${quoted.slice(0, -1).join(", ")}, or ${last}`;
13
+ })();
5
14
 
6
15
  async function tryReadFile(filePath: string): Promise<string | null> {
7
16
  const { readFile } = await import("node:fs/promises");
@@ -73,7 +82,7 @@ function validateConfig(value: unknown): string | null {
73
82
  }
74
83
  for (const item of notifyOn) {
75
84
  if (!isWorkflowLifecycleNoticeKind(item)) {
76
- return `"workflowNotifications.notifyOn" entries must be "completed", "failed", "blocked", or "awaiting_input", got ${JSON.stringify(item)}`;
85
+ return `"workflowNotifications.notifyOn" entries must be ${WORKFLOW_LIFECYCLE_NOTICE_KIND_LIST}, got ${JSON.stringify(item)}`;
77
86
  }
78
87
  }
79
88
  }
@@ -186,7 +186,7 @@ export const WORKFLOW_CONFIG_DEFAULTS = {
186
186
  resumeInFlight: "ask" as const,
187
187
  workflowNotifications: {
188
188
  enabled: true,
189
- notifyOn: ["completed", "failed", "blocked", "awaiting_input"] as const,
189
+ notifyOn: ["started", "completed", "failed", "blocked", "awaiting_input", "paused", "quit", "resumed"] as const,
190
190
  },
191
191
  worktree: {
192
192
  symlinkDirectories: ["node_modules"] as readonly string[],
@@ -16,6 +16,7 @@ import type { StageAdapters } from "../runs/foreground/stage-runner.js";
16
16
  import { effectiveRunStatus } from "../shared/returned-run-status.js";
17
17
  import { deriveInputFields, schemaIsRequired } from "../shared/schema-introspection.js";
18
18
  import { store as defaultStore, type Store } from "../shared/store.js";
19
+ import type { WorkflowActor } from "../shared/store-types.js";
19
20
  import {
20
21
  INTERACTIVE_WORKFLOW_POLICY,
21
22
  type WorkflowExecutionPolicy,
@@ -82,6 +83,8 @@ export interface DispatcherOpts {
82
83
  models?: WorkflowModelCatalogPort;
83
84
  /** Runtime-derived interaction policy for this dispatch. */
84
85
  policy?: WorkflowExecutionPolicy;
86
+ /** Who launched this run. Omitted when the launcher is not attributable. */
87
+ origin?: WorkflowActor;
85
88
  /** Invocation cwd used for workflow execution. */
86
89
  cwd?: string;
87
90
  /** Host-resolved non-default session directory inherited by stages without explicit sessionDir. */
@@ -187,6 +190,7 @@ export async function dispatch(args: WorkflowToolArgs, opts: DispatcherOpts): Pr
187
190
  executionMode: policy.mode,
188
191
  cwd: opts.cwd,
189
192
  defaultSessionDir: opts.defaultSessionDir,
193
+ ...(opts.origin === undefined ? {} : { origin: opts.origin }),
190
194
  runId,
191
195
  });
192
196
  } catch (error) {