@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
@@ -0,0 +1,457 @@
1
+ import { existsSync, statSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import type { AgentConfig } from "../../agents/agent-types.ts";
4
+ import { ensureArtifactsDir, getArtifactPaths, writeArtifact } from "../../shared/artifacts.ts";
5
+ import type {
6
+ AgentProgress,
7
+ ArtifactPaths,
8
+ Details,
9
+ ModelAttempt,
10
+ RunSyncOptions,
11
+ SingleResult,
12
+ SubagentToolResult,
13
+ Usage,
14
+ } from "../../shared/types.ts";
15
+ import { getOrCreateSubagentControl } from "../inprocess/control-registry.ts";
16
+ import type { AttemptOutcome, ChildSpec, ParentContext } from "../inprocess/runner.ts";
17
+ import { filterSpawnableModelCandidates } from "../shared/model-candidate-filter.ts";
18
+ import { buildModelCandidates } from "../shared/model-fallback.ts";
19
+ import { registerExecutionIntercomDetach } from "./execution-intercom-detach.ts";
20
+
21
+ function emptyUsage(): Usage {
22
+ return {
23
+ input: 0,
24
+ output: 0,
25
+ cacheRead: 0,
26
+ cacheWrite: 0,
27
+ cost: 0,
28
+ turns: 0,
29
+ };
30
+ }
31
+
32
+ function usageFromStats(stats: AttemptOutcome["stats"]): Usage {
33
+ return {
34
+ input: stats.tokens.input,
35
+ output: stats.tokens.output,
36
+ cacheRead: stats.tokens.cacheRead,
37
+ cacheWrite: stats.tokens.cacheWrite,
38
+ cost: stats.cost,
39
+ turns: stats.assistantMessages,
40
+ };
41
+ }
42
+
43
+ function workflowOrchestrationContext(options: RunSyncOptions): ParentContext["orchestrationContext"] | undefined {
44
+ const workflow = options.workflowSessionMetadata;
45
+ if (!workflow) return undefined;
46
+ return {
47
+ kind: "workflow-stage",
48
+ workflowRunId: workflow.runId,
49
+ workflowStageId: workflow.stageId,
50
+ workflowStageName: workflow.stageName,
51
+ constraints: {
52
+ disableWorkflowTool: true,
53
+ maxSubagentDepth: options.maxSubagentDepth ?? 5,
54
+ },
55
+ ...(options.intercomGroup ? { intercomGroup: options.intercomGroup } : {}),
56
+ };
57
+ }
58
+
59
+ function progressFor(agent: AgentConfig, task: string, outcome: AttemptOutcome, startedAt: number): AgentProgress {
60
+ const status = outcome.status === "ok" ? "completed" : outcome.status === "interrupted" ? "failed" : "failed";
61
+ return {
62
+ index: 0,
63
+ agent: agent.name,
64
+ status,
65
+ task,
66
+ recentTools: [],
67
+ recentOutput: outcome.envelope ? outcome.envelope.split("\n").slice(-10) : [],
68
+ toolCount: outcome.stats.toolCalls,
69
+ turnCount: outcome.stats.assistantMessages,
70
+ tokens: outcome.stats.tokens.total,
71
+ durationMs: Math.max(0, Date.now() - startedAt),
72
+ lastActivityAt: Date.now(),
73
+ ...(outcome.status === "error" ? { error: outcome.cause } : {}),
74
+ };
75
+ }
76
+
77
+ function resultFromOutcome(
78
+ agent: AgentConfig,
79
+ task: string,
80
+ outcome: AttemptOutcome,
81
+ startedAt: number,
82
+ artifactPaths?: ArtifactPaths,
83
+ ): SingleResult {
84
+ const status = outcome.status;
85
+ const output = outcome.status === "ok" ? outcome.output : outcome.envelope;
86
+ const result: SingleResult = {
87
+ agent: agent.name,
88
+ task,
89
+ status,
90
+ ...(outcome.status === "error" ? { cause: outcome.cause, error: outcome.cause } : {}),
91
+ stats: outcome.stats,
92
+ path: outcome.path,
93
+ envelope: outcome.envelope,
94
+ interrupted: status === "interrupted" ? true : undefined,
95
+ messages: [],
96
+ usage: usageFromStats(outcome.stats),
97
+ model: outcome.status === "ok" || outcome.status === "error" ? outcome.model : undefined,
98
+ ...(outcome.status === "ok" || outcome.status === "error"
99
+ ? outcome.attemptedModels?.length
100
+ ? { attemptedModels: [...outcome.attemptedModels] }
101
+ : {}
102
+ : {}),
103
+ finalOutput: output,
104
+ sessionFile: outcome.sessionFile,
105
+ ...(outcome.status === "ok" && outcome.structuredOutput !== undefined
106
+ ? { structuredOutput: outcome.structuredOutput }
107
+ : {}),
108
+ progress: progressFor(agent, task, outcome, startedAt),
109
+ progressSummary: {
110
+ toolCount: outcome.stats.toolCalls,
111
+ tokens: outcome.stats.tokens.total,
112
+ durationMs: Math.max(0, Date.now() - startedAt),
113
+ },
114
+ ...(artifactPaths ? { artifactPaths } : {}),
115
+ };
116
+ return result;
117
+ }
118
+
119
+ function refusedResult(agent: AgentConfig, task: string, reason: string): SingleResult {
120
+ return {
121
+ agent: agent.name,
122
+ task,
123
+ status: "error",
124
+ cause: reason,
125
+ error: reason,
126
+ stats: {
127
+ sessionFile: undefined,
128
+ sessionId: "",
129
+ userMessages: 0,
130
+ assistantMessages: 0,
131
+ toolCalls: 0,
132
+ toolResults: 0,
133
+ totalMessages: 0,
134
+ tokens: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
135
+ cost: 0,
136
+ },
137
+ path: "",
138
+ envelope: reason,
139
+ messages: [],
140
+ usage: emptyUsage(),
141
+ };
142
+ }
143
+
144
+ function noSpawnableCandidatesResult(agent: AgentConfig, task: string, skippedAttempts: ModelAttempt[]): SingleResult {
145
+ const reason = "No spawnable subagent model candidates after pre-spawn filtering.";
146
+ return { ...refusedResult(agent, task, reason), modelAttempts: skippedAttempts };
147
+ }
148
+
149
+ export async function runSingleInProcess(
150
+ runtimeCwd: string,
151
+ agent: AgentConfig,
152
+ task: string,
153
+ options: RunSyncOptions,
154
+ ): Promise<SingleResult> {
155
+ const cwd = options.cwd ?? runtimeCwd;
156
+ if (!existsSync(cwd)) return refusedResult(agent, task, `cwd does not exist: ${cwd}`);
157
+ if (!statSync(cwd).isDirectory()) return refusedResult(agent, task, `cwd is not a directory: ${cwd}`);
158
+ const rawCandidates = buildModelCandidates(
159
+ options.modelOverride ?? agent.model,
160
+ agent.fallbackModels,
161
+ options.availableModels,
162
+ options.preferredModelProvider,
163
+ options.currentModel,
164
+ agent.fallbackThinkingLevels,
165
+ );
166
+ const filteredCandidates = filterSpawnableModelCandidates({
167
+ candidates: rawCandidates,
168
+ availableModels: options.availableModels,
169
+ knownModelProviders: options.knownModelProviders,
170
+ currentModel: options.currentModel,
171
+ });
172
+ if (rawCandidates.length > 0 && filteredCandidates.candidates.length === 0)
173
+ return noSpawnableCandidatesResult(agent, task, filteredCandidates.skippedAttempts);
174
+ const candidate = filteredCandidates.candidates[0];
175
+ const fallbackCandidates = filteredCandidates.candidates.slice(1);
176
+ const orchestrationContext = workflowOrchestrationContext(options);
177
+ const parent: ParentContext = {
178
+ path: options.runId,
179
+ depth: 0,
180
+ ...(options.intercomGroup ? { intercomGroup: options.intercomGroup } : {}),
181
+ ...(orchestrationContext ? { orchestrationContext } : {}),
182
+ };
183
+ const sessionRoot = options.sessionDir ?? join(options.artifactsDir ?? cwd, ".atomic", "subagents");
184
+ const control = getOrCreateSubagentControl(parent, sessionRoot);
185
+ control.registerAgents([agent]);
186
+ const artifactsDir =
187
+ options.artifactsDir && options.artifactConfig?.enabled !== false ? options.artifactsDir : undefined;
188
+ const artifactPaths = artifactsDir
189
+ ? getArtifactPaths(artifactsDir, options.runId, agent.name, options.index)
190
+ : undefined;
191
+ const artifactsDisabled =
192
+ options.artifactConfig?.enabled === false ||
193
+ (options.artifactsDir === undefined && options.artifactConfig === undefined);
194
+ if (artifactsDir && artifactPaths && options.artifactConfig?.includeInput !== false) {
195
+ ensureArtifactsDir(artifactsDir);
196
+ writeArtifact(artifactPaths.inputPath, `# Task for ${agent.name}\n\n${task}`);
197
+ }
198
+ const testSession =
199
+ options.testSession ?? (process.env.NODE_TEST_CONTEXT !== undefined || process.env.NODE_ENV === "test");
200
+ const spec: ChildSpec = {
201
+ taskName: agent.name,
202
+ task,
203
+ agent,
204
+ cwd,
205
+ testSession: testSession,
206
+ sessionFile: options.sessionFile,
207
+ structuredOutput: options.structuredOutput
208
+ ? { schema: options.structuredOutput.schema, outputPath: options.structuredOutput.outputPath }
209
+ : undefined,
210
+ tools: agent.tools,
211
+ mcpDirectTools: agent.mcpDirectTools,
212
+ skills: options.skills ?? agent.skills,
213
+ model: undefined,
214
+ thinkingLevel: agent.thinking as ChildSpec["thinkingLevel"],
215
+ parent,
216
+ intercom: options.orchestratorIntercomTarget
217
+ ? {
218
+ orchestratorTarget: options.orchestratorIntercomTarget,
219
+ runId: options.runId,
220
+ agent: agent.name,
221
+ index: options.index ?? 0,
222
+ ...(options.intercomSessionName ? { sessionName: options.intercomSessionName } : {}),
223
+ ...(options.supervisorAuthorization
224
+ ? {
225
+ supervisor: {
226
+ capability: options.supervisorAuthorization.capability,
227
+ supervisorSessionId: options.supervisorAuthorization.supervisorSessionId,
228
+ },
229
+ }
230
+ : {}),
231
+ }
232
+ : undefined,
233
+ artifactJsonlPath: artifactPaths?.jsonlPath,
234
+ ...(fallbackCandidates.length ? { fallbackModels: fallbackCandidates } : {}),
235
+ onProgress: options.onUpdate
236
+ ? (progress) => {
237
+ const liveProgress = { ...progress, index: options.index ?? 0 };
238
+ const liveResult: SingleResult = {
239
+ agent: agent.name,
240
+ task,
241
+ status: "continued",
242
+ messages: [],
243
+ usage: emptyUsage(),
244
+ progress: liveProgress,
245
+ };
246
+ options.onUpdate?.({
247
+ content: [{ type: "text", text: "running" }],
248
+ details: {
249
+ mode: "single",
250
+ runId: options.runId,
251
+ results: [liveResult],
252
+ progress: [liveProgress],
253
+ } satisfies Details,
254
+ });
255
+ }
256
+ : undefined,
257
+ };
258
+ const admission = control.admitChildSession(spec, parent);
259
+ if (!admission.admitted) return refusedResult(agent, task, admission.refusal?.reason ?? "child admission refused");
260
+ const startedAt = Date.now();
261
+ const neverAbort = new AbortController().signal;
262
+ const running = control.startAttempt(
263
+ admission.admitted,
264
+ { modelId: candidate, thinkingLevel: spec.thinkingLevel },
265
+ {
266
+ abort: options.signal ?? neverAbort,
267
+ interrupt: options.interruptSignal ?? neverAbort,
268
+ },
269
+ );
270
+ control.registerNestedAttempt(options.runId, running, { modelId: candidate, thinkingLevel: spec.thinkingLevel });
271
+ if (options.backgroundContinuation) {
272
+ control.continueInBackground(running, "async-requested");
273
+ void running.promise.then(
274
+ async (backgroundOutcome) => {
275
+ const recovered = resultFromOutcome(agent, task, backgroundOutcome, startedAt, artifactPaths);
276
+ await control.deliverChildResult(
277
+ {
278
+ path: backgroundOutcome.path,
279
+ status: backgroundOutcome.status,
280
+ ...(backgroundOutcome.status === "error" ? { cause: backgroundOutcome.cause } : {}),
281
+ stats: backgroundOutcome.stats,
282
+ envelope: backgroundOutcome.envelope,
283
+ sessionFile: backgroundOutcome.sessionFile,
284
+ timestamp: Date.now(),
285
+ artifactsDir: options.artifactsDir,
286
+ },
287
+ { artifactsDir: options.artifactsDir, artifactPaths, artifactsDisabled, maxOutput: options.maxOutput },
288
+ );
289
+ const delivered = control.getDeliveredResult(backgroundOutcome.path);
290
+ if (delivered) {
291
+ recovered.envelope = delivered.envelope;
292
+ recovered.finalOutput = delivered.envelope;
293
+ }
294
+ options.onDetachedExit?.(recovered);
295
+ },
296
+ () => undefined,
297
+ );
298
+ const continuedResult: SingleResult = {
299
+ agent: agent.name,
300
+ task,
301
+ status: "continued",
302
+ path: admission.admitted.identity.path,
303
+ envelope: "Child continued in background.",
304
+ detached: true,
305
+ detachedReason: "async-requested",
306
+ messages: [],
307
+ usage: emptyUsage(),
308
+ progress: {
309
+ index: options.index ?? 0,
310
+ agent: agent.name,
311
+ status: "running",
312
+ task,
313
+ recentTools: [],
314
+ recentOutput: [],
315
+ toolCount: 0,
316
+ tokens: 0,
317
+ durationMs: Math.max(0, Date.now() - startedAt),
318
+ lastActivityAt: Date.now(),
319
+ },
320
+ };
321
+ options.onUpdate?.({
322
+ content: [{ type: "text", text: continuedResult.envelope ?? "" }],
323
+ details: { mode: "single", runId: options.runId, results: [continuedResult] } satisfies Details,
324
+ });
325
+ return continuedResult;
326
+ }
327
+ let detached = false;
328
+ let resolveContinuation!: () => void;
329
+ const continuation = new Promise<void>((resolve) => {
330
+ resolveContinuation = resolve;
331
+ });
332
+ const detachCleanup = registerExecutionIntercomDetach(options, {
333
+ isUnavailable: () => running.status !== "running",
334
+ isDetached: () => detached,
335
+ detach: () => {
336
+ if (detached) return;
337
+ detached = true;
338
+ control.continueInBackground(running, "intercom-coordination");
339
+ resolveContinuation();
340
+ },
341
+ });
342
+ const terminal = running.promise.then((value) => ({ kind: "terminal" as const, value }));
343
+ const winner = await Promise.race([terminal, continuation.then(() => ({ kind: "continued" as const }))]);
344
+ if (winner.kind === "continued") {
345
+ detachCleanup();
346
+ void running.promise.then(async (backgroundOutcome) => {
347
+ const recovered = resultFromOutcome(agent, task, backgroundOutcome, startedAt, artifactPaths);
348
+ await control.deliverChildResult(
349
+ {
350
+ path: backgroundOutcome.path,
351
+ status: backgroundOutcome.status,
352
+ ...(backgroundOutcome.status === "error" ? { cause: backgroundOutcome.cause } : {}),
353
+ stats: backgroundOutcome.stats,
354
+ envelope: backgroundOutcome.envelope,
355
+ sessionFile: backgroundOutcome.sessionFile,
356
+ timestamp: Date.now(),
357
+ artifactsDir: options.artifactsDir,
358
+ },
359
+ { artifactsDir: options.artifactsDir, artifactPaths, artifactsDisabled, maxOutput: options.maxOutput },
360
+ );
361
+ const delivered = control.getDeliveredResult(backgroundOutcome.path);
362
+ if (delivered) {
363
+ recovered.envelope = delivered.envelope;
364
+ recovered.finalOutput = delivered.envelope;
365
+ }
366
+ options.onDetachedExit?.(recovered);
367
+ });
368
+ const continuedResult: SingleResult = {
369
+ agent: agent.name,
370
+ task,
371
+ status: "continued",
372
+ path: admission.admitted.identity.path,
373
+ envelope: "Child continued in background.",
374
+ detached: true,
375
+ detachedReason: "intercom-coordination",
376
+ messages: [],
377
+ usage: emptyUsage(),
378
+ progress: {
379
+ index: options.index ?? 0,
380
+ agent: agent.name,
381
+ status: "running",
382
+ task,
383
+ recentTools: [],
384
+ recentOutput: [],
385
+ toolCount: 0,
386
+ tokens: 0,
387
+ durationMs: Math.max(0, Date.now() - startedAt),
388
+ lastActivityAt: Date.now(),
389
+ },
390
+ };
391
+ options.onUpdate?.({
392
+ content: [{ type: "text", text: continuedResult.envelope ?? "" }],
393
+ details: { mode: "single", runId: options.runId, results: [continuedResult] } satisfies Details,
394
+ });
395
+ return continuedResult;
396
+ }
397
+ detachCleanup();
398
+ const outcome = winner.value;
399
+ const result = resultFromOutcome(agent, task, outcome, startedAt, artifactPaths);
400
+ if (filteredCandidates.skippedAttempts.length)
401
+ result.modelAttempts = [...filteredCandidates.skippedAttempts, ...(result.modelAttempts ?? [])];
402
+ await control.deliverChildResult(
403
+ {
404
+ path: outcome.path,
405
+ status: outcome.status,
406
+ ...(outcome.status === "error" ? { cause: outcome.cause } : {}),
407
+ stats: outcome.stats,
408
+ envelope: outcome.envelope,
409
+ sessionFile: outcome.sessionFile,
410
+ timestamp: Date.now(),
411
+ artifactsDir: options.artifactsDir,
412
+ },
413
+ { artifactsDir: options.artifactsDir, artifactPaths, artifactsDisabled, maxOutput: options.maxOutput },
414
+ );
415
+ const delivered = control.getDeliveredResult(outcome.path);
416
+ if (delivered) {
417
+ result.envelope = delivered.envelope;
418
+ result.finalOutput = delivered.envelope;
419
+ }
420
+ const update: SubagentToolResult = {
421
+ content: [{ type: "text", text: result.finalOutput ?? "(no output)" }],
422
+ details: {
423
+ mode: "single",
424
+ runId: options.runId,
425
+ results: [result],
426
+ progress: result.progress ? [result.progress] : undefined,
427
+ } satisfies Details,
428
+ };
429
+ options.onUpdate?.(update);
430
+ return result;
431
+ }
432
+
433
+ export async function runSync(
434
+ runtimeCwd: string,
435
+ agents: AgentConfig[],
436
+ agentName: string,
437
+ task: string,
438
+ options: RunSyncOptions,
439
+ ): Promise<SingleResult> {
440
+ const agent = agents.find((candidate) => candidate.name === agentName);
441
+ if (!agent)
442
+ return refusedResult(
443
+ {
444
+ name: agentName,
445
+ description: "",
446
+ systemPrompt: "",
447
+ systemPromptMode: "replace",
448
+ inheritProjectContext: false,
449
+ inheritSkills: false,
450
+ source: "user",
451
+ filePath: "",
452
+ },
453
+ task,
454
+ `Unknown agent: ${agentName}`,
455
+ );
456
+ return runSingleInProcess(runtimeCwd, agent, task, options);
457
+ }