@selesai/code 0.2.1 → 0.3.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 (284) hide show
  1. package/dist/config.d.ts +4 -15
  2. package/dist/config.d.ts.map +1 -1
  3. package/dist/config.js +5 -45
  4. package/dist/config.js.map +1 -1
  5. package/dist/core/agent-session.d.ts +1 -0
  6. package/dist/core/agent-session.d.ts.map +1 -1
  7. package/dist/core/agent-session.js +8 -0
  8. package/dist/core/agent-session.js.map +1 -1
  9. package/dist/core/diagnostics.d.ts +1 -0
  10. package/dist/core/diagnostics.d.ts.map +1 -1
  11. package/dist/core/diagnostics.js.map +1 -1
  12. package/dist/core/model-registry.d.ts +4 -1
  13. package/dist/core/model-registry.d.ts.map +1 -1
  14. package/dist/core/model-registry.js +101 -51
  15. package/dist/core/model-registry.js.map +1 -1
  16. package/dist/core/package-manager.d.ts +10 -0
  17. package/dist/core/package-manager.d.ts.map +1 -1
  18. package/dist/core/package-manager.js +93 -8
  19. package/dist/core/package-manager.js.map +1 -1
  20. package/dist/core/package-manager.test.d.ts +2 -0
  21. package/dist/core/package-manager.test.d.ts.map +1 -0
  22. package/dist/core/package-manager.test.js +20 -0
  23. package/dist/core/package-manager.test.js.map +1 -0
  24. package/dist/core/resource-loader.d.ts +3 -0
  25. package/dist/core/resource-loader.d.ts.map +1 -1
  26. package/dist/core/resource-loader.js +10 -0
  27. package/dist/core/resource-loader.js.map +1 -1
  28. package/dist/core/settings-manager.d.ts +1 -0
  29. package/dist/core/settings-manager.d.ts.map +1 -1
  30. package/dist/core/settings-manager.js.map +1 -1
  31. package/dist/defaults/models.json +64 -113
  32. package/dist/extensions/caveman/caveman-instructions.cjs +39 -0
  33. package/dist/extensions/caveman/index.js +116 -0
  34. package/dist/extensions/caveman/package.json +8 -0
  35. package/dist/extensions/caveman/test/extension.test.js +185 -0
  36. package/dist/extensions/caveman/test/helpers.test.js +67 -0
  37. package/dist/extensions/copy-turn.ts +2 -2
  38. package/dist/extensions/pi-intercom/broker/broker.ts +2 -3
  39. package/dist/extensions/pi-intercom/broker/paths.ts +10 -5
  40. package/dist/extensions/pi-intercom/broker/spawn.ts +2 -3
  41. package/dist/extensions/pi-intercom/config.ts +2 -2
  42. package/dist/extensions/pi-intercom/index.ts +2 -2
  43. package/dist/extensions/pi-intercom/package.json +2 -2
  44. package/dist/extensions/pi-intercom/ui/compose.ts +3 -3
  45. package/dist/extensions/pi-intercom/ui/inline-message.ts +3 -3
  46. package/dist/extensions/pi-intercom/ui/session-list.ts +3 -3
  47. package/dist/extensions/pi-powerline-footer/bash-mode/editor.ts +2 -2
  48. package/dist/extensions/pi-powerline-footer/bash-mode/history.ts +2 -1
  49. package/dist/extensions/pi-powerline-footer/index.ts +40 -47
  50. package/dist/extensions/pi-powerline-footer/package.json +2 -2
  51. package/dist/extensions/pi-powerline-footer/tests/bash-mode.test.ts +10 -10
  52. package/dist/extensions/pi-powerline-footer/tests/jump-shortcuts.test.ts +1 -1
  53. package/dist/extensions/pi-powerline-footer/tests/working-vibes.test.ts +2 -2
  54. package/dist/extensions/pi-powerline-footer/theme.ts +6 -6
  55. package/dist/extensions/pi-powerline-footer/tps.ts +1 -1
  56. package/dist/extensions/pi-powerline-footer/types.ts +7 -7
  57. package/dist/extensions/pi-powerline-footer/welcome.ts +23 -16
  58. package/dist/extensions/pi-powerline-footer/working-vibes.ts +52 -59
  59. package/dist/extensions/pi-rewind-hook/index.ts +1 -1
  60. package/dist/extensions/pi-rewind-hook/package.json +1 -1
  61. package/dist/extensions/pi-subagents/README.md +224 -52
  62. package/dist/extensions/pi-subagents/agents/architect.md +188 -0
  63. package/dist/extensions/pi-subagents/agents/builder.md +120 -0
  64. package/dist/extensions/pi-subagents/agents/commentator.md +131 -0
  65. package/dist/extensions/pi-subagents/agents/explorer.md +51 -0
  66. package/dist/extensions/pi-subagents/agents/recapper.md +21 -0
  67. package/dist/extensions/pi-subagents/install.mjs +93 -0
  68. package/dist/extensions/pi-subagents/package.json +4 -5
  69. package/dist/extensions/pi-subagents/prompts/parallel-context-build.md +1 -1
  70. package/dist/extensions/pi-subagents/prompts/parallel-handoff-plan.md +1 -1
  71. package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +76 -13
  72. package/dist/extensions/pi-subagents/src/agents/agent-management.ts +179 -2
  73. package/dist/extensions/pi-subagents/src/agents/agent-memory.ts +254 -0
  74. package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +11 -0
  75. package/dist/extensions/pi-subagents/src/agents/agents.ts +193 -19
  76. package/dist/extensions/pi-subagents/src/agents/chain-serializer.ts +27 -2
  77. package/dist/extensions/pi-subagents/src/extension/config.ts +27 -4
  78. package/dist/extensions/pi-subagents/src/extension/doctor.ts +1 -7
  79. package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +3 -2
  80. package/dist/extensions/pi-subagents/src/extension/index.ts +73 -71
  81. package/dist/extensions/pi-subagents/src/extension/rpc.ts +369 -0
  82. package/dist/extensions/pi-subagents/src/extension/schemas.ts +54 -10
  83. package/dist/extensions/pi-subagents/src/extension/tool-description.ts +200 -0
  84. package/dist/extensions/pi-subagents/src/intercom/intercom-bridge.ts +21 -253
  85. package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +519 -0
  86. package/dist/extensions/pi-subagents/src/profiles/profiles.ts +1 -1
  87. package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +195 -105
  88. package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +88 -2
  89. package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +67 -10
  90. package/dist/extensions/pi-subagents/src/runs/background/chain-root-attachment.ts +34 -4
  91. package/dist/extensions/pi-subagents/src/runs/background/completion-batcher.ts +166 -0
  92. package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +156 -1
  93. package/dist/extensions/pi-subagents/src/runs/background/fleet-view.ts +515 -0
  94. package/dist/extensions/pi-subagents/src/runs/background/notify.ts +161 -44
  95. package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +1 -2
  96. package/dist/extensions/pi-subagents/src/runs/background/run-id-resolver.ts +3 -2
  97. package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +167 -6
  98. package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +514 -0
  99. package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +28 -1
  100. package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +873 -204
  101. package/dist/extensions/pi-subagents/src/runs/background/wait.ts +353 -0
  102. package/dist/extensions/pi-subagents/src/runs/foreground/chain-execution.ts +123 -27
  103. package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +174 -70
  104. package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +569 -81
  105. package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +45 -22
  106. package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +3 -1
  107. package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +2 -2
  108. package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +172 -21
  109. package/dist/extensions/pi-subagents/src/runs/shared/model-scope.ts +128 -0
  110. package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +89 -0
  111. package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +50 -1
  112. package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +35 -4
  113. package/dist/extensions/pi-subagents/src/runs/shared/pi-spawn.ts +63 -45
  114. package/dist/extensions/pi-subagents/src/runs/shared/single-output.ts +2 -0
  115. package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +125 -5
  116. package/dist/extensions/pi-subagents/src/runs/shared/tool-budget.ts +74 -0
  117. package/dist/extensions/pi-subagents/src/runs/shared/turn-budget.ts +52 -0
  118. package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +28 -5
  119. package/dist/extensions/pi-subagents/src/shared/artifacts.ts +16 -1
  120. package/dist/extensions/pi-subagents/src/shared/atomic-json.ts +15 -2
  121. package/dist/extensions/pi-subagents/src/shared/child-transcript.ts +212 -0
  122. package/dist/extensions/pi-subagents/src/shared/fork-context.ts +133 -22
  123. package/dist/extensions/pi-subagents/src/shared/settings.ts +3 -1
  124. package/dist/extensions/pi-subagents/src/shared/types.ts +197 -4
  125. package/dist/extensions/pi-subagents/src/shared/utils.ts +108 -17
  126. package/dist/extensions/pi-subagents/src/slash/prompt-workflows.ts +330 -0
  127. package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +135 -4
  128. package/dist/extensions/pi-subagents/src/tui/render.ts +32 -12
  129. package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +94 -0
  130. package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +2772 -0
  131. package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +1107 -0
  132. package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +463 -0
  133. package/dist/extensions/pi-subagents/test/integration/chain-clarify.test.ts +274 -0
  134. package/dist/extensions/pi-subagents/test/integration/chain-execution.test.ts +1535 -0
  135. package/dist/extensions/pi-subagents/test/integration/detect-error.test.ts +242 -0
  136. package/dist/extensions/pi-subagents/test/integration/doctor-executor.test.ts +128 -0
  137. package/dist/extensions/pi-subagents/test/integration/error-handling.test.ts +252 -0
  138. package/dist/extensions/pi-subagents/test/integration/foreground-result-size.test.ts +188 -0
  139. package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +1306 -0
  140. package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +1033 -0
  141. package/dist/extensions/pi-subagents/test/integration/parallel-execution.test.ts +397 -0
  142. package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +583 -0
  143. package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +691 -0
  144. package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +892 -0
  145. package/dist/extensions/pi-subagents/test/integration/session-tokens.test.ts +62 -0
  146. package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +1824 -0
  147. package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +1284 -0
  148. package/dist/extensions/pi-subagents/test/integration/slash-live-state.test.ts +127 -0
  149. package/dist/extensions/pi-subagents/test/integration/template-resolution.test.ts +299 -0
  150. package/dist/extensions/pi-subagents/test/integration/top-level-async.test.ts +37 -0
  151. package/dist/extensions/pi-subagents/test/support/helpers.ts +189 -0
  152. package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +335 -0
  153. package/dist/extensions/pi-subagents/test/support/mock-pi.ts +129 -0
  154. package/dist/extensions/pi-subagents/test/support/real-session-child-cli.mjs +184 -0
  155. package/dist/extensions/pi-subagents/test/support/real-session-runner.ts +285 -0
  156. package/dist/extensions/pi-subagents/test/support/register-loader.mjs +15 -0
  157. package/dist/extensions/pi-subagents/test/support/ts-loader.mjs +108 -0
  158. package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +421 -0
  159. package/dist/extensions/pi-subagents/test/unit/agent-disabled.test.ts +213 -0
  160. package/dist/extensions/pi-subagents/test/unit/agent-eject-disable.test.ts +343 -0
  161. package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +1199 -0
  162. package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +556 -0
  163. package/dist/extensions/pi-subagents/test/unit/agent-memory.test.ts +420 -0
  164. package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +579 -0
  165. package/dist/extensions/pi-subagents/test/unit/agent-scope.test.ts +20 -0
  166. package/dist/extensions/pi-subagents/test/unit/agent-selection.test.ts +88 -0
  167. package/dist/extensions/pi-subagents/test/unit/artifacts.test.ts +24 -0
  168. package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +86 -0
  169. package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +221 -0
  170. package/dist/extensions/pi-subagents/test/unit/async-permission-session.test.ts +98 -0
  171. package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +285 -0
  172. package/dist/extensions/pi-subagents/test/unit/atomic-json.test.ts +112 -0
  173. package/dist/extensions/pi-subagents/test/unit/chain-append.test.ts +206 -0
  174. package/dist/extensions/pi-subagents/test/unit/chain-root-attachment.test.ts +159 -0
  175. package/dist/extensions/pi-subagents/test/unit/chain-serializer.test.ts +229 -0
  176. package/dist/extensions/pi-subagents/test/unit/child-transcript.test.ts +225 -0
  177. package/dist/extensions/pi-subagents/test/unit/close-grace-timer.test.ts +101 -0
  178. package/dist/extensions/pi-subagents/test/unit/completion-batcher.test.ts +228 -0
  179. package/dist/extensions/pi-subagents/test/unit/completion-dedupe.test.ts +36 -0
  180. package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +152 -0
  181. package/dist/extensions/pi-subagents/test/unit/config-dir-runtime.test.ts +72 -0
  182. package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +327 -0
  183. package/dist/extensions/pi-subagents/test/unit/control-notices.test.ts +161 -0
  184. package/dist/extensions/pi-subagents/test/unit/doctor.test.ts +159 -0
  185. package/dist/extensions/pi-subagents/test/unit/dynamic-fanout.test.ts +217 -0
  186. package/dist/extensions/pi-subagents/test/unit/extra-agent-dirs.test.ts +88 -0
  187. package/dist/extensions/pi-subagents/test/unit/file-coalescer.test.ts +68 -0
  188. package/dist/extensions/pi-subagents/test/unit/foreground-tool-call-compaction.test.ts +78 -0
  189. package/dist/extensions/pi-subagents/test/unit/fork-context.test.ts +415 -0
  190. package/dist/extensions/pi-subagents/test/unit/get-final-output.test.ts +126 -0
  191. package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +271 -0
  192. package/dist/extensions/pi-subagents/test/unit/intercom-bridge.test.ts +173 -0
  193. package/dist/extensions/pi-subagents/test/unit/jsonl-writer.test.ts +119 -0
  194. package/dist/extensions/pi-subagents/test/unit/live-async-resume.test.ts +170 -0
  195. package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +346 -0
  196. package/dist/extensions/pi-subagents/test/unit/model-info.test.ts +62 -0
  197. package/dist/extensions/pi-subagents/test/unit/model-scope-settings.test.ts +87 -0
  198. package/dist/extensions/pi-subagents/test/unit/model-scope.test.ts +145 -0
  199. package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +162 -0
  200. package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +470 -0
  201. package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +329 -0
  202. package/dist/extensions/pi-subagents/test/unit/notify.test.ts +319 -0
  203. package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +70 -0
  204. package/dist/extensions/pi-subagents/test/unit/parallel-utils.test.ts +247 -0
  205. package/dist/extensions/pi-subagents/test/unit/path-handling.test.ts +113 -0
  206. package/dist/extensions/pi-subagents/test/unit/path-resolution.test.ts +94 -0
  207. package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +803 -0
  208. package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +209 -0
  209. package/dist/extensions/pi-subagents/test/unit/pi-spawn.test.ts +238 -0
  210. package/dist/extensions/pi-subagents/test/unit/proactive-skills.test.ts +118 -0
  211. package/dist/extensions/pi-subagents/test/unit/profiles.test.ts +299 -0
  212. package/dist/extensions/pi-subagents/test/unit/prompt-template-bridge.test.ts +408 -0
  213. package/dist/extensions/pi-subagents/test/unit/prompt-workflows.test.ts +134 -0
  214. package/dist/extensions/pi-subagents/test/unit/recursion-guard.test.ts +257 -0
  215. package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +209 -0
  216. package/dist/extensions/pi-subagents/test/unit/result-intercom.test.ts +226 -0
  217. package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +294 -0
  218. package/dist/extensions/pi-subagents/test/unit/run-id-resolver.test.ts +147 -0
  219. package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +997 -0
  220. package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +478 -0
  221. package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +562 -0
  222. package/dist/extensions/pi-subagents/test/unit/single-output.test.ts +213 -0
  223. package/dist/extensions/pi-subagents/test/unit/skills-fallback.test.ts +438 -0
  224. package/dist/extensions/pi-subagents/test/unit/slash-bridge.test.ts +54 -0
  225. package/dist/extensions/pi-subagents/test/unit/slash-chain-groups.test.ts +464 -0
  226. package/dist/extensions/pi-subagents/test/unit/stale-run-reconciler.test.ts +255 -0
  227. package/dist/extensions/pi-subagents/test/unit/status-format.test.ts +19 -0
  228. package/dist/extensions/pi-subagents/test/unit/subagent-control.test.ts +245 -0
  229. package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +517 -0
  230. package/dist/extensions/pi-subagents/test/unit/temp-paths.test.ts +72 -0
  231. package/dist/extensions/pi-subagents/test/unit/tool-budget.test.ts +52 -0
  232. package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +237 -0
  233. package/dist/extensions/pi-subagents/test/unit/total-cost.test.ts +60 -0
  234. package/dist/extensions/pi-subagents/test/unit/ts-loader.test.ts +33 -0
  235. package/dist/extensions/pi-subagents/test/unit/turn-budget.test.ts +202 -0
  236. package/dist/extensions/pi-subagents/test/unit/types-fork-preamble.test.ts +23 -0
  237. package/dist/extensions/pi-subagents/test/unit/wait.test.ts +398 -0
  238. package/dist/extensions/pi-subagents/test/unit/widget-nested-render.test.ts +88 -0
  239. package/dist/extensions/pi-subagents/test/unit/windows-hide-spawn.test.ts +26 -0
  240. package/dist/extensions/pi-subagents/test/unit/workflow-graph.test.ts +134 -0
  241. package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +479 -0
  242. package/dist/extensions/pi-web-agent/package.json +2 -2
  243. package/dist/extensions/pi-web-agent/src/backends/settings-reader.ts +2 -2
  244. package/dist/extensions/pi-web-agent/src/changelog-notice.ts +5 -2
  245. package/dist/extensions/pi-web-agent/src/commands/web-agent-config.ts +1 -1
  246. package/dist/extensions/pi-web-agent/src/extension.ts +1 -1
  247. package/dist/extensions/pi-web-agent/src/presentation/config-store.ts +6 -4
  248. package/dist/extensions/question/helpers.ts +3 -3
  249. package/dist/extensions/question/index.ts +2 -2
  250. package/dist/extensions/question/navigation.ts +2 -2
  251. package/dist/extensions/question/package.json +2 -2
  252. package/dist/extensions/question/question-list.ts +2 -2
  253. package/dist/extensions/question/tests/question-list.test.ts +2 -2
  254. package/dist/extensions/question/tui-adapter.ts +2 -2
  255. package/dist/extensions/question/types.ts +2 -2
  256. package/dist/extensions/question/ui-protocol.ts +2 -2
  257. package/dist/extensions/rtk.ts +2 -2
  258. package/dist/extensions/tokenin-onboarding.ts +2 -2
  259. package/dist/extensions/undo.ts +1 -1
  260. package/dist/extensions/web-agent-onboarding.ts +3 -3
  261. package/dist/extensions/workflow/adapter.ts +16 -8
  262. package/dist/extensions/workflow/extension.ts +1 -1
  263. package/dist/extensions/workflow/package.json +1 -1
  264. package/dist/main.d.ts.map +1 -1
  265. package/dist/main.js +4 -0
  266. package/dist/main.js.map +1 -1
  267. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  268. package/dist/modes/interactive/components/assistant-message.js +2 -0
  269. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  270. package/dist/modes/interactive/components/first-time-setup.d.ts +1 -1
  271. package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
  272. package/dist/modes/interactive/components/first-time-setup.js +19 -5
  273. package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
  274. package/dist/skills/caveman/SKILL.md +49 -0
  275. package/dist/skills/handoff-text/SKILL.md +13 -0
  276. package/dist/utils/thinking-tags.d.ts +7 -0
  277. package/dist/utils/thinking-tags.d.ts.map +1 -0
  278. package/dist/utils/thinking-tags.js +63 -0
  279. package/dist/utils/thinking-tags.js.map +1 -0
  280. package/docs/docs.json +4 -0
  281. package/docs/extensions.md +2 -0
  282. package/docs/settings.md +15 -0
  283. package/docs/shared-host-extensions.md +109 -0
  284. package/package.json +2 -2
@@ -34,7 +34,8 @@ import { discoverAvailableSkills, normalizeSkillInput } from "../../agents/skill
34
34
  import { INTERCOM_BRIDGE_MARKER } from "../../intercom/intercom-bridge.ts";
35
35
  import { runSync } from "./execution.ts";
36
36
  import { buildChainSummary } from "../../shared/formatters.ts";
37
- import { compactForegroundDetails, getSingleResultOutput, mapConcurrent, resolveChildCwd } from "../../shared/utils.ts";
37
+ import { compactForegroundDetails, getSingleResultOutput, mapConcurrent, resolveChildCwd, sumResultsCost, sumResultsUsage } from "../../shared/utils.ts";
38
+ import { DEFAULT_GLOBAL_CONCURRENCY_LIMIT, Semaphore } from "../shared/parallel-utils.ts";
38
39
  import { recordRun } from "../shared/run-history.ts";
39
40
  import {
40
41
  cleanupWorktrees,
@@ -55,11 +56,15 @@ import {
55
56
  type IntercomEventBus,
56
57
  type NestedRouteInfo,
57
58
  type ResolvedControlConfig,
59
+ type ResolvedTurnBudget,
60
+ type ResolvedToolBudget,
58
61
  type SingleResult,
62
+ type ToolBudgetConfig,
59
63
  MAX_CONCURRENCY,
60
64
  resolveChildMaxSubagentDepth,
61
65
  } from "../../shared/types.ts";
62
66
  import { resolveSubagentModelOverride } from "../shared/model-fallback.ts";
67
+ import type { ModelScopeConfig } from "../shared/model-scope.ts";
63
68
  import { validateFileOnlyOutputMode } from "../shared/single-output.ts";
64
69
  import { buildWorkflowGraphSnapshot } from "../shared/workflow-graph.ts";
65
70
  import { ChainOutputValidationError, outputEntryFromResult, resolveOutputReferences, validateChainOutputBindings } from "../shared/chain-outputs.ts";
@@ -67,6 +72,7 @@ import { createStructuredOutputRuntime } from "../shared/structured-output.ts";
67
72
  import { collectDynamicResults, DynamicFanoutError, materializeDynamicParallelStep, validateDynamicCollection, type DynamicCollectedResult } from "../shared/dynamic-fanout.ts";
68
73
  import { acceptanceFailureMessage, aggregateAcceptanceReport, evaluateAcceptance, resolveEffectiveAcceptance } from "../shared/acceptance.ts";
69
74
  import type { ChainOutputMap } from "../../shared/types.ts";
75
+ import { validateToolBudgetConfig } from "../shared/tool-budget.ts";
70
76
 
71
77
  interface ChainExecutionDetailsInput {
72
78
  results: SingleResult[];
@@ -92,6 +98,7 @@ interface ParallelChainRunInput {
92
98
  agents: AgentConfig[];
93
99
  stepIndex: number;
94
100
  availableModels: ModelInfo[];
101
+ modelScope?: ModelScopeConfig;
95
102
  chainDir: string;
96
103
  prev: string;
97
104
  originalTask: string;
@@ -103,6 +110,7 @@ interface ParallelChainRunInput {
103
110
  sessionDirForIndex: (idx?: number) => string | undefined;
104
111
  sessionFileForIndex?: (idx?: number) => string | undefined;
105
112
  sessionFileForTask?: (agentName: string, idx?: number) => string | undefined;
113
+ thinkingOverrideForTask?: (agentName: string, idx?: number) => AgentConfig["thinking"] | undefined;
106
114
  shareEnabled: boolean;
107
115
  artifactConfig: ArtifactConfig;
108
116
  artifactsDir: string;
@@ -139,6 +147,11 @@ interface ParallelChainRunInput {
139
147
  nestedRoute?: NestedRouteInfo;
140
148
  timeoutMs?: number;
141
149
  deadlineAt?: number;
150
+ turnBudget?: ResolvedTurnBudget;
151
+ onDetachedExit?: (index: number, result: SingleResult) => void;
152
+ toolBudget?: ResolvedToolBudget;
153
+ configToolBudget?: ToolBudgetConfig;
154
+ globalSemaphore?: Semaphore;
142
155
  }
143
156
 
144
157
  function buildChainExecutionDetails(input: ChainExecutionDetailsInput): Details {
@@ -151,7 +164,9 @@ function buildChainExecutionDetails(input: ChainExecutionDetailsInput): Details
151
164
  totalSteps: input.totalSteps,
152
165
  currentStepIndex: input.currentStepIndex,
153
166
  outputs: input.outputs,
154
- workflowGraph: buildWorkflowGraphSnapshot({
167
+ totalChildUsage: sumResultsUsage(input.results),
168
+ totalCost: sumResultsCost(input.results),
169
+ workflowGraph: buildWorkflowGraphSnapshot({
155
170
  runId: input.runId,
156
171
  mode: "chain",
157
172
  steps: input.chainSteps,
@@ -197,6 +212,20 @@ function appendParallelWorktreeSummary(
197
212
  return `${output}\n\n${diffSummary}`;
198
213
  }
199
214
 
215
+ function resolveChainToolBudget(input: { stepBudget?: ToolBudgetConfig; runBudget?: ResolvedToolBudget; agentBudget?: ToolBudgetConfig; configBudget?: ToolBudgetConfig }): { toolBudget?: ResolvedToolBudget; error?: string } {
216
+ if (input.stepBudget !== undefined) {
217
+ const resolved = validateToolBudgetConfig(input.stepBudget, "toolBudget");
218
+ return { toolBudget: resolved.budget, error: resolved.error };
219
+ }
220
+ if (input.runBudget !== undefined) return { toolBudget: input.runBudget };
221
+ if (input.agentBudget !== undefined) {
222
+ const resolved = validateToolBudgetConfig(input.agentBudget, "agent.toolBudget");
223
+ return { toolBudget: resolved.budget, error: resolved.error };
224
+ }
225
+ const resolved = validateToolBudgetConfig(input.configBudget, "config.toolBudget");
226
+ return { toolBudget: resolved.budget, error: resolved.error };
227
+ }
228
+
200
229
  async function runParallelChainTasks(input: ParallelChainRunInput): Promise<SingleResult[]> {
201
230
  const concurrency = input.step.concurrency ?? MAX_CONCURRENCY;
202
231
  const failFast = input.step.failFast ?? false;
@@ -240,8 +269,11 @@ async function runParallelChainTasks(input: ParallelChainRunInput): Promise<Sing
240
269
  input.ctx.model,
241
270
  input.availableModels,
242
271
  input.ctx.model?.provider,
272
+ { scope: input.modelScope, source: task.model ? "explicit" : "inherited" },
243
273
  );
244
274
  const maxSubagentDepth = resolveChildMaxSubagentDepth(input.maxSubagentDepth, taskAgentConfig?.maxSubagentDepth);
275
+ const toolBudget = resolveChainToolBudget({ stepBudget: task.toolBudget, runBudget: input.toolBudget, agentBudget: taskAgentConfig?.toolBudget, configBudget: input.configToolBudget });
276
+ if (toolBudget.error) throw new Error(toolBudget.error);
245
277
 
246
278
  const taskCwd = input.worktreeSetup
247
279
  ? input.worktreeSetup.worktrees[taskIndex]!.agentCwd
@@ -280,6 +312,7 @@ async function runParallelChainTasks(input: ParallelChainRunInput): Promise<Sing
280
312
  sessionDir: input.sessionDirForIndex(input.globalTaskIndex + taskIndex),
281
313
  sessionFile: input.sessionFileForTask?.(task.agent, input.globalTaskIndex + taskIndex)
282
314
  ?? input.sessionFileForIndex?.(input.globalTaskIndex + taskIndex),
315
+ thinkingOverride: input.thinkingOverrideForTask?.(task.agent, input.globalTaskIndex + taskIndex),
283
316
  share: input.shareEnabled,
284
317
  artifactsDir: input.artifactConfig.enabled ? input.artifactsDir : undefined,
285
318
  artifactConfig: input.artifactConfig,
@@ -294,12 +327,18 @@ async function runParallelChainTasks(input: ParallelChainRunInput): Promise<Sing
294
327
  modelOverride: effectiveModel,
295
328
  availableModels: input.availableModels,
296
329
  preferredModelProvider: input.ctx.model?.provider,
330
+ modelScope: input.modelScope,
297
331
  skills: behavior.skills === false ? [] : behavior.skills,
298
332
  structuredOutput: structuredRuntime,
299
333
  acceptance: task.acceptance,
300
334
  acceptanceContext: { mode: "chain" },
301
335
  timeoutMs: input.timeoutMs,
302
336
  deadlineAt: input.deadlineAt,
337
+ turnBudget: input.turnBudget,
338
+ onDetachedExit: input.onDetachedExit
339
+ ? (result) => input.onDetachedExit?.(input.globalTaskIndex + taskIndex, result)
340
+ : undefined,
341
+ toolBudget: toolBudget.toolBudget,
303
342
  onUpdate: input.onUpdate
304
343
  ? (progressUpdate) => {
305
344
  const stepResults = progressUpdate.details?.results || [];
@@ -355,6 +394,7 @@ async function runParallelChainTasks(input: ParallelChainRunInput): Promise<Sing
355
394
  recordRun(task.agent, cleanTask, result.exitCode, result.progressSummary?.durationMs ?? 0);
356
395
  return result;
357
396
  },
397
+ input.globalSemaphore,
358
398
  );
359
399
 
360
400
  return parallelResults;
@@ -373,6 +413,7 @@ interface ChainExecutionParams {
373
413
  sessionDirForIndex: (idx?: number) => string | undefined;
374
414
  sessionFileForIndex?: (idx?: number) => string | undefined;
375
415
  sessionFileForTask?: (agentName: string, idx?: number) => string | undefined;
416
+ thinkingOverrideForTask?: (agentName: string, idx?: number) => AgentConfig["thinking"] | undefined;
376
417
  artifactsDir: string;
377
418
  artifactConfig: ArtifactConfig;
378
419
  includeProgress?: boolean;
@@ -403,8 +444,15 @@ interface ChainExecutionParams {
403
444
  nestedRoute?: NestedRouteInfo;
404
445
  worktreeSetupHook?: string;
405
446
  worktreeSetupHookTimeoutMs?: number;
447
+ worktreeBaseDir?: string;
406
448
  timeoutMs?: number;
407
449
  deadlineAt?: number;
450
+ turnBudget?: ResolvedTurnBudget;
451
+ onDetachedExit?: (index: number, result: SingleResult) => void;
452
+ toolBudget?: ResolvedToolBudget;
453
+ configToolBudget?: ToolBudgetConfig;
454
+ /** Global cap on simultaneously-running tasks within this chain. Defaults to DEFAULT_GLOBAL_CONCURRENCY_LIMIT. */
455
+ globalConcurrencyLimit?: number;
408
456
  }
409
457
 
410
458
  interface ChainExecutionResult {
@@ -433,6 +481,7 @@ export async function executeChain(params: ChainExecutionParams): Promise<ChainE
433
481
  sessionDirForIndex,
434
482
  sessionFileForIndex,
435
483
  sessionFileForTask,
484
+ thinkingOverrideForTask,
436
485
  artifactsDir,
437
486
  artifactConfig,
438
487
  includeProgress,
@@ -440,12 +489,14 @@ export async function executeChain(params: ChainExecutionParams): Promise<ChainE
440
489
  onUpdate,
441
490
  onControlEvent,
442
491
  controlConfig,
492
+ onDetachedExit,
443
493
  childIntercomTarget,
444
494
  orchestratorIntercomTarget,
445
495
  foregroundControl,
446
496
  intercomEvents,
447
497
  chainSkills: chainSkillsParam,
448
498
  chainDir: chainDirBase,
499
+ modelScope,
449
500
  } = params;
450
501
  const chainSkills = chainSkillsParam ?? [];
451
502
 
@@ -504,7 +555,7 @@ export async function executeChain(params: ChainExecutionParams): Promise<ChainE
504
555
  const chainDir = createChainDir(runId, chainDirBase);
505
556
  const hasParallelSteps = chainSteps.some((step) => isParallelStep(step) || isDynamicParallelStep(step));
506
557
  let templates: ResolvedTemplates = resolveChainTemplates(chainSteps);
507
- const shouldClarify = clarify !== false && ctx.hasUI && !hasParallelSteps;
558
+ const shouldClarify = clarify === true && ctx.hasUI && !hasParallelSteps;
508
559
  let tuiBehaviorOverrides: (BehaviorOverride | undefined)[] | undefined;
509
560
  const availableModels: ModelInfo[] = ctx.modelRegistry.getAvailable().map(toModelInfo);
510
561
  const availableSkills = discoverAvailableSkills(cwd ?? ctx.cwd);
@@ -596,6 +647,7 @@ export async function executeChain(params: ChainExecutionParams): Promise<ChainE
596
647
  }
597
648
 
598
649
  const deadlineAt = params.deadlineAt ?? (params.timeoutMs !== undefined ? Date.now() + params.timeoutMs : undefined);
650
+ const globalSemaphore = new Semaphore(params.globalConcurrencyLimit ?? DEFAULT_GLOBAL_CONCURRENCY_LIMIT);
599
651
  let prev = "";
600
652
  let globalTaskIndex = 0;
601
653
  let progressCreated = false;
@@ -622,6 +674,7 @@ export async function executeChain(params: ChainExecutionParams): Promise<ChainE
622
674
  setupHook: params.worktreeSetupHook
623
675
  ? { hookPath: params.worktreeSetupHook, timeoutMs: params.worktreeSetupHookTimeoutMs }
624
676
  : undefined,
677
+ baseDir: params.worktreeBaseDir,
625
678
  });
626
679
  } catch (error) {
627
680
  const message = error instanceof Error ? error.message : String(error);
@@ -651,6 +704,7 @@ export async function executeChain(params: ChainExecutionParams): Promise<ChainE
651
704
  agents,
652
705
  stepIndex,
653
706
  availableModels,
707
+ modelScope,
654
708
  chainDir,
655
709
  prev,
656
710
  originalTask,
@@ -662,6 +716,7 @@ export async function executeChain(params: ChainExecutionParams): Promise<ChainE
662
716
  sessionDirForIndex,
663
717
  sessionFileForIndex,
664
718
  sessionFileForTask,
719
+ thinkingOverrideForTask,
665
720
  shareEnabled,
666
721
  artifactConfig,
667
722
  artifactsDir,
@@ -685,6 +740,11 @@ export async function executeChain(params: ChainExecutionParams): Promise<ChainE
685
740
  maxSubagentDepth: params.maxSubagentDepth,
686
741
  timeoutMs: params.timeoutMs,
687
742
  deadlineAt,
743
+ turnBudget: params.turnBudget,
744
+ onDetachedExit,
745
+ toolBudget: params.toolBudget,
746
+ configToolBudget: params.configToolBudget,
747
+ globalSemaphore,
688
748
  });
689
749
  globalTaskIndex += step.parallel.length;
690
750
 
@@ -770,6 +830,8 @@ export async function executeChain(params: ChainExecutionParams): Promise<ChainE
770
830
  if (worktreeSetup) cleanupWorktrees(worktreeSetup);
771
831
  }
772
832
  } else if (isDynamicParallelStep(step)) {
833
+ const dynamicStartIndex = globalTaskIndex;
834
+ const reservedDynamicItems = step.expand.maxItems ?? params.dynamicFanoutMaxItems ?? 0;
773
835
  let materialized: ReturnType<typeof materializeDynamicParallelStep>;
774
836
  try {
775
837
  materialized = materializeDynamicParallelStep(step, outputs, stepIndex, { maxItems: params.dynamicFanoutMaxItems });
@@ -828,6 +890,7 @@ export async function executeChain(params: ChainExecutionParams): Promise<ChainE
828
890
  }
829
891
  }
830
892
  prev = "Dynamic fanout produced 0 results.";
893
+ globalTaskIndex = dynamicStartIndex + reservedDynamicItems;
831
894
  continue;
832
895
  }
833
896
 
@@ -861,6 +924,7 @@ export async function executeChain(params: ChainExecutionParams): Promise<ChainE
861
924
  agents,
862
925
  stepIndex,
863
926
  availableModels,
927
+ modelScope,
864
928
  chainDir,
865
929
  prev,
866
930
  originalTask,
@@ -872,6 +936,7 @@ export async function executeChain(params: ChainExecutionParams): Promise<ChainE
872
936
  sessionDirForIndex,
873
937
  sessionFileForIndex,
874
938
  sessionFileForTask,
939
+ thinkingOverrideForTask,
875
940
  shareEnabled,
876
941
  artifactConfig,
877
942
  artifactsDir,
@@ -894,8 +959,13 @@ export async function executeChain(params: ChainExecutionParams): Promise<ChainE
894
959
  maxSubagentDepth: params.maxSubagentDepth,
895
960
  timeoutMs: params.timeoutMs,
896
961
  deadlineAt,
962
+ turnBudget: params.turnBudget,
963
+ onDetachedExit,
964
+ toolBudget: params.toolBudget,
965
+ configToolBudget: params.configToolBudget,
966
+ globalSemaphore,
897
967
  });
898
- globalTaskIndex += dynamicParallelStep.parallel.length;
968
+ globalTaskIndex = dynamicStartIndex + reservedDynamicItems;
899
969
 
900
970
  for (const result of parallelResults) {
901
971
  results.push(result);
@@ -910,7 +980,7 @@ export async function executeChain(params: ChainExecutionParams): Promise<ChainE
910
980
  content: [{ type: "text", text: `Chain paused after interrupt at step ${stepIndex + 1} (${interrupted.agent}). Waiting for explicit next action.` }],
911
981
  details: buildChainExecutionDetails(makeDetailsInput({
912
982
  currentStepIndex: stepIndex,
913
- currentFlatIndex: globalTaskIndex - dynamicParallelStep.parallel.length + interruptedIndexInStep,
983
+ currentFlatIndex: dynamicStartIndex + interruptedIndexInStep,
914
984
  })),
915
985
  };
916
986
  }
@@ -921,7 +991,7 @@ export async function executeChain(params: ChainExecutionParams): Promise<ChainE
921
991
  content: [{ type: "text", text: `Chain detached for intercom coordination at step ${stepIndex + 1} (${detached.agent}). Reply to the supervisor request first. After the child exits, start a fresh follow-up if needed.` }],
922
992
  details: buildChainExecutionDetails(makeDetailsInput({
923
993
  currentStepIndex: stepIndex,
924
- currentFlatIndex: globalTaskIndex - dynamicParallelStep.parallel.length + detachedIndexInStep,
994
+ currentFlatIndex: dynamicStartIndex + detachedIndexInStep,
925
995
  })),
926
996
  };
927
997
  }
@@ -943,7 +1013,7 @@ export async function executeChain(params: ChainExecutionParams): Promise<ChainE
943
1013
  isError: true,
944
1014
  details: buildChainExecutionDetails(makeDetailsInput({
945
1015
  currentStepIndex: stepIndex,
946
- currentFlatIndex: globalTaskIndex - dynamicParallelStep.parallel.length + failures[0]!.originalIndex,
1016
+ currentFlatIndex: dynamicStartIndex + failures[0]!.originalIndex,
947
1017
  })),
948
1018
  };
949
1019
  }
@@ -952,7 +1022,7 @@ export async function executeChain(params: ChainExecutionParams): Promise<ChainE
952
1022
  } catch (error) {
953
1023
  const message = error instanceof DynamicFanoutError ? error.message : error instanceof Error ? error.message : String(error);
954
1024
  dynamicGroupStatuses[stepIndex] = { status: "failed", error: message };
955
- return buildChainExecutionErrorResult(message, makeDetailsInput({ currentStepIndex: stepIndex, currentFlatIndex: globalTaskIndex - dynamicParallelStep.parallel.length }));
1025
+ return buildChainExecutionErrorResult(message, makeDetailsInput({ currentStepIndex: stepIndex, currentFlatIndex: dynamicStartIndex }));
956
1026
  }
957
1027
  outputs[step.collect.as] = {
958
1028
  text: JSON.stringify(collected),
@@ -1039,13 +1109,14 @@ export async function executeChain(params: ChainExecutionParams): Promise<ChainE
1039
1109
  const cleanTask = stepTask;
1040
1110
  stepTask = prefix + stepTask + suffix;
1041
1111
 
1042
- const effectiveModel = tuiOverride?.model
1043
- ?? resolveSubagentModelOverride(
1044
- seqStep.model ?? agentConfig.model,
1045
- ctx.model,
1046
- availableModels,
1047
- ctx.model?.provider,
1048
- );
1112
+ const explicitStepModel = tuiOverride?.model ?? seqStep.model;
1113
+ const effectiveModel = resolveSubagentModelOverride(
1114
+ explicitStepModel ?? agentConfig.model,
1115
+ ctx.model,
1116
+ availableModels,
1117
+ ctx.model?.provider,
1118
+ { scope: modelScope, source: explicitStepModel ? "explicit" : "inherited" },
1119
+ );
1049
1120
 
1050
1121
  const outputPath = typeof behavior.output === "string"
1051
1122
  ? (path.isAbsolute(behavior.output) ? behavior.output : path.join(chainDir, behavior.output))
@@ -1055,10 +1126,11 @@ export async function executeChain(params: ChainExecutionParams): Promise<ChainE
1055
1126
  return buildChainExecutionErrorResult(validationError, makeDetailsInput({ currentStepIndex: stepIndex, currentFlatIndex: globalTaskIndex }));
1056
1127
  }
1057
1128
  const maxSubagentDepth = resolveChildMaxSubagentDepth(params.maxSubagentDepth, agentConfig.maxSubagentDepth);
1129
+ const childIndex = globalTaskIndex;
1058
1130
  const interruptController = new AbortController();
1059
1131
  if (foregroundControl) {
1060
1132
  foregroundControl.currentAgent = seqStep.agent;
1061
- foregroundControl.currentIndex = globalTaskIndex;
1133
+ foregroundControl.currentIndex = childIndex;
1062
1134
  foregroundControl.currentActivityState = undefined;
1063
1135
  foregroundControl.updatedAt = Date.now();
1064
1136
  foregroundControl.interrupt = () => {
@@ -1073,6 +1145,23 @@ export async function executeChain(params: ChainExecutionParams): Promise<ChainE
1073
1145
  const structuredRuntime = seqStep.outputSchema
1074
1146
  ? createStructuredOutputRuntime(seqStep.outputSchema, path.join(chainDir, "structured-output"))
1075
1147
  : undefined;
1148
+ const toolBudget = resolveChainToolBudget({ stepBudget: seqStep.toolBudget, runBudget: params.toolBudget, agentBudget: agentConfig?.toolBudget, configBudget: params.configToolBudget });
1149
+ if (toolBudget.error) return buildChainExecutionErrorResult(toolBudget.error, {
1150
+ results,
1151
+ includeProgress,
1152
+ allProgress,
1153
+ allArtifactPaths,
1154
+ artifactsDir: params.artifactsDir,
1155
+ chainAgents,
1156
+ chainSteps,
1157
+ totalSteps,
1158
+ currentStepIndex: stepIndex,
1159
+ runId: params.runId,
1160
+ outputs,
1161
+ currentFlatIndex: globalTaskIndex,
1162
+ dynamicChildren,
1163
+ dynamicGroupStatuses,
1164
+ });
1076
1165
  const r = await runSync(ctx.cwd, agents, seqStep.agent, stepTask, {
1077
1166
  parentSessionId: ctx.sessionManager.getSessionId() ?? undefined,
1078
1167
  cwd: resolveChildCwd(cwd ?? ctx.cwd, seqStep.cwd),
@@ -1081,10 +1170,11 @@ export async function executeChain(params: ChainExecutionParams): Promise<ChainE
1081
1170
  allowIntercomDetach: agentConfig.systemPrompt?.includes(INTERCOM_BRIDGE_MARKER) === true,
1082
1171
  intercomEvents,
1083
1172
  runId,
1084
- index: globalTaskIndex,
1085
- sessionDir: sessionDirForIndex(globalTaskIndex),
1086
- sessionFile: sessionFileForTask?.(seqStep.agent, globalTaskIndex)
1087
- ?? sessionFileForIndex?.(globalTaskIndex),
1173
+ index: childIndex,
1174
+ sessionDir: sessionDirForIndex(childIndex),
1175
+ sessionFile: sessionFileForTask?.(seqStep.agent, childIndex)
1176
+ ?? sessionFileForIndex?.(childIndex),
1177
+ thinkingOverride: thinkingOverrideForTask?.(seqStep.agent, childIndex),
1088
1178
  share: shareEnabled,
1089
1179
  artifactsDir: artifactConfig.enabled ? artifactsDir : undefined,
1090
1180
  artifactConfig,
@@ -1093,18 +1183,24 @@ export async function executeChain(params: ChainExecutionParams): Promise<ChainE
1093
1183
  maxSubagentDepth,
1094
1184
  controlConfig,
1095
1185
  onControlEvent,
1096
- intercomSessionName: childIntercomTarget?.(seqStep.agent, globalTaskIndex),
1186
+ intercomSessionName: childIntercomTarget?.(seqStep.agent, childIndex),
1097
1187
  orchestratorIntercomTarget,
1098
1188
  nestedRoute: params.nestedRoute,
1099
1189
  modelOverride: effectiveModel,
1100
1190
  availableModels,
1101
1191
  preferredModelProvider: ctx.model?.provider,
1192
+ modelScope,
1102
1193
  skills: behavior.skills === false ? [] : behavior.skills,
1103
1194
  structuredOutput: structuredRuntime,
1104
1195
  acceptance: seqStep.acceptance,
1105
1196
  acceptanceContext: { mode: "chain" },
1106
1197
  timeoutMs: params.timeoutMs,
1107
1198
  deadlineAt,
1199
+ turnBudget: params.turnBudget,
1200
+ onDetachedExit: onDetachedExit
1201
+ ? (result) => onDetachedExit(childIndex, result)
1202
+ : undefined,
1203
+ toolBudget: toolBudget.toolBudget,
1108
1204
  onUpdate: onUpdate
1109
1205
  ? (p) => {
1110
1206
  const stepResults = p.details?.results || [];
@@ -1112,7 +1208,7 @@ export async function executeChain(params: ChainExecutionParams): Promise<ChainE
1112
1208
  if (foregroundControl && stepProgress.length > 0) {
1113
1209
  const current = stepProgress[0];
1114
1210
  foregroundControl.currentAgent = seqStep.agent;
1115
- foregroundControl.currentIndex = globalTaskIndex;
1211
+ foregroundControl.currentIndex = childIndex;
1116
1212
  foregroundControl.currentActivityState = current?.activityState;
1117
1213
  foregroundControl.lastActivityAt = current?.lastActivityAt;
1118
1214
  foregroundControl.currentTool = current?.currentTool;
@@ -1140,7 +1236,7 @@ export async function executeChain(params: ChainExecutionParams): Promise<ChainE
1140
1236
  steps: chainSteps,
1141
1237
  results: results.concat(stepResults),
1142
1238
  currentStepIndex: stepIndex,
1143
- currentFlatIndex: globalTaskIndex,
1239
+ currentFlatIndex: childIndex,
1144
1240
  dynamicChildren,
1145
1241
  dynamicGroupStatuses,
1146
1242
  }),
@@ -1149,7 +1245,7 @@ export async function executeChain(params: ChainExecutionParams): Promise<ChainE
1149
1245
  }
1150
1246
  : undefined,
1151
1247
  });
1152
- if (foregroundControl?.currentIndex === globalTaskIndex) {
1248
+ if (foregroundControl?.currentIndex === childIndex) {
1153
1249
  foregroundControl.interrupt = undefined;
1154
1250
  foregroundControl.updatedAt = Date.now();
1155
1251
  }
@@ -1163,13 +1259,13 @@ export async function executeChain(params: ChainExecutionParams): Promise<ChainE
1163
1259
  if (r.interrupted) {
1164
1260
  return {
1165
1261
  content: [{ type: "text", text: `Chain paused after interrupt at step ${stepIndex + 1} (${r.agent}). Waiting for explicit next action.` }],
1166
- details: buildChainExecutionDetails(makeDetailsInput({ currentStepIndex: stepIndex, currentFlatIndex: globalTaskIndex - 1 })),
1262
+ details: buildChainExecutionDetails(makeDetailsInput({ currentStepIndex: stepIndex, currentFlatIndex: childIndex })),
1167
1263
  };
1168
1264
  }
1169
1265
  if (r.detached) {
1170
1266
  return {
1171
1267
  content: [{ type: "text", text: `Chain detached for intercom coordination at step ${stepIndex + 1} (${r.agent}). Reply to the supervisor request first. After the child exits, start a fresh follow-up if needed.` }],
1172
- details: buildChainExecutionDetails(makeDetailsInput({ currentStepIndex: stepIndex, currentFlatIndex: globalTaskIndex - 1 })),
1268
+ details: buildChainExecutionDetails(makeDetailsInput({ currentStepIndex: stepIndex, currentFlatIndex: childIndex })),
1173
1269
  };
1174
1270
  }
1175
1271
 
@@ -1180,7 +1276,7 @@ export async function executeChain(params: ChainExecutionParams): Promise<ChainE
1180
1276
  });
1181
1277
  return {
1182
1278
  content: [{ type: "text", text: summary }],
1183
- details: buildChainExecutionDetails(makeDetailsInput({ currentStepIndex: stepIndex, currentFlatIndex: globalTaskIndex - 1 })),
1279
+ details: buildChainExecutionDetails(makeDetailsInput({ currentStepIndex: stepIndex, currentFlatIndex: childIndex })),
1184
1280
  isError: true,
1185
1281
  };
1186
1282
  }