@astralyn/pi 0.84.3 → 0.84.5

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 (269) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/dist/cli/args.d.ts +1 -0
  3. package/dist/cli/args.d.ts.map +1 -1
  4. package/dist/cli/args.js +11 -0
  5. package/dist/cli/args.js.map +1 -1
  6. package/dist/cli/auth-command.d.ts.map +1 -1
  7. package/dist/cli/auth-command.js +5 -4
  8. package/dist/cli/auth-command.js.map +1 -1
  9. package/dist/cli/project-trust.d.ts.map +1 -1
  10. package/dist/cli/project-trust.js +1 -4
  11. package/dist/cli/project-trust.js.map +1 -1
  12. package/dist/core/agent-session.d.ts +6 -1
  13. package/dist/core/agent-session.d.ts.map +1 -1
  14. package/dist/core/agent-session.js +7 -6
  15. package/dist/core/agent-session.js.map +1 -1
  16. package/dist/core/experimental.d.ts +4 -0
  17. package/dist/core/experimental.d.ts.map +1 -1
  18. package/dist/core/experimental.js +4 -0
  19. package/dist/core/experimental.js.map +1 -1
  20. package/dist/core/extensions/index.d.ts +1 -1
  21. package/dist/core/extensions/index.d.ts.map +1 -1
  22. package/dist/core/extensions/index.js.map +1 -1
  23. package/dist/core/extensions/runner.d.ts.map +1 -1
  24. package/dist/core/extensions/runner.js +4 -0
  25. package/dist/core/extensions/runner.js.map +1 -1
  26. package/dist/core/extensions/types.d.ts +10 -14
  27. package/dist/core/extensions/types.d.ts.map +1 -1
  28. package/dist/core/extensions/types.js.map +1 -1
  29. package/dist/core/keybindings.d.ts +29 -0
  30. package/dist/core/keybindings.d.ts.map +1 -1
  31. package/dist/core/keybindings.js +4 -0
  32. package/dist/core/keybindings.js.map +1 -1
  33. package/dist/core/model-config.d.ts +5 -0
  34. package/dist/core/model-config.d.ts.map +1 -1
  35. package/dist/core/model-config.js +1 -0
  36. package/dist/core/model-config.js.map +1 -1
  37. package/dist/core/model-registry.d.ts +2 -0
  38. package/dist/core/model-registry.d.ts.map +1 -1
  39. package/dist/core/model-registry.js +4 -0
  40. package/dist/core/model-registry.js.map +1 -1
  41. package/dist/core/project-trust.js +2 -2
  42. package/dist/core/project-trust.js.map +1 -1
  43. package/dist/core/sdk.d.ts +5 -3
  44. package/dist/core/sdk.d.ts.map +1 -1
  45. package/dist/core/sdk.js +2 -1
  46. package/dist/core/sdk.js.map +1 -1
  47. package/dist/core/session-manager.js +2 -2
  48. package/dist/core/session-manager.js.map +1 -1
  49. package/dist/core/settings-manager.d.ts +6 -0
  50. package/dist/core/settings-manager.d.ts.map +1 -1
  51. package/dist/core/settings-manager.js +12 -0
  52. package/dist/core/settings-manager.js.map +1 -1
  53. package/dist/core/system-prompt.js +1 -1
  54. package/dist/core/system-prompt.js.map +1 -1
  55. package/dist/core/tools/bash.d.ts +2 -1
  56. package/dist/core/tools/bash.d.ts.map +1 -1
  57. package/dist/core/tools/bash.js +3 -1
  58. package/dist/core/tools/bash.js.map +1 -1
  59. package/dist/core/tools/edit.d.ts.map +1 -1
  60. package/dist/core/tools/edit.js +2 -0
  61. package/dist/core/tools/edit.js.map +1 -1
  62. package/dist/core/tools/find.js +1 -1
  63. package/dist/core/tools/find.js.map +1 -1
  64. package/dist/core/tools/grep.js +1 -1
  65. package/dist/core/tools/grep.js.map +1 -1
  66. package/dist/core/tools/read.d.ts.map +1 -1
  67. package/dist/core/tools/read.js +2 -0
  68. package/dist/core/tools/read.js.map +1 -1
  69. package/dist/core/tools/write.d.ts.map +1 -1
  70. package/dist/core/tools/write.js +2 -0
  71. package/dist/core/tools/write.js.map +1 -1
  72. package/dist/extensions/background/index.d.ts +74 -0
  73. package/dist/extensions/background/index.d.ts.map +1 -0
  74. package/dist/extensions/background/index.js +332 -0
  75. package/dist/extensions/background/index.js.map +1 -0
  76. package/dist/extensions/background/manager.d.ts +81 -0
  77. package/dist/extensions/background/manager.d.ts.map +1 -0
  78. package/dist/extensions/background/manager.js +320 -0
  79. package/dist/extensions/background/manager.js.map +1 -0
  80. package/dist/extensions/background/registry.d.ts +138 -0
  81. package/dist/extensions/background/registry.d.ts.map +1 -0
  82. package/dist/extensions/background/registry.js +358 -0
  83. package/dist/extensions/background/registry.js.map +1 -0
  84. package/dist/extensions/background/render.d.ts +26 -0
  85. package/dist/extensions/background/render.d.ts.map +1 -0
  86. package/dist/extensions/background/render.js +118 -0
  87. package/dist/extensions/background/render.js.map +1 -0
  88. package/dist/extensions/index.d.ts.map +1 -1
  89. package/dist/extensions/index.js +2 -0
  90. package/dist/extensions/index.js.map +1 -1
  91. package/dist/extensions/subagent/activity.d.ts +0 -1
  92. package/dist/extensions/subagent/activity.d.ts.map +1 -1
  93. package/dist/extensions/subagent/activity.js +2 -5
  94. package/dist/extensions/subagent/activity.js.map +1 -1
  95. package/dist/extensions/subagent/agents-command.d.ts +4 -0
  96. package/dist/extensions/subagent/agents-command.d.ts.map +1 -0
  97. package/dist/extensions/subagent/agents-command.js +385 -0
  98. package/dist/extensions/subagent/agents-command.js.map +1 -0
  99. package/dist/extensions/subagent/agents.d.ts +3 -6
  100. package/dist/extensions/subagent/agents.d.ts.map +1 -1
  101. package/dist/extensions/subagent/agents.js +22 -190
  102. package/dist/extensions/subagent/agents.js.map +1 -1
  103. package/dist/extensions/subagent/constants.d.ts +4 -5
  104. package/dist/extensions/subagent/constants.d.ts.map +1 -1
  105. package/dist/extensions/subagent/constants.js +11 -7
  106. package/dist/extensions/subagent/constants.js.map +1 -1
  107. package/dist/extensions/subagent/index.d.ts +0 -3
  108. package/dist/extensions/subagent/index.d.ts.map +1 -1
  109. package/dist/extensions/subagent/index.js +58 -315
  110. package/dist/extensions/subagent/index.js.map +1 -1
  111. package/dist/extensions/subagent/render.d.ts +1 -1
  112. package/dist/extensions/subagent/render.d.ts.map +1 -1
  113. package/dist/extensions/subagent/render.js +208 -585
  114. package/dist/extensions/subagent/render.js.map +1 -1
  115. package/dist/extensions/subagent/resolve.d.ts +2 -2
  116. package/dist/extensions/subagent/resolve.d.ts.map +1 -1
  117. package/dist/extensions/subagent/resolve.js +23 -15
  118. package/dist/extensions/subagent/resolve.js.map +1 -1
  119. package/dist/extensions/subagent/runner.d.ts +1 -2
  120. package/dist/extensions/subagent/runner.d.ts.map +1 -1
  121. package/dist/extensions/subagent/runner.js +109 -131
  122. package/dist/extensions/subagent/runner.js.map +1 -1
  123. package/dist/extensions/subagent/schema.d.ts +4 -10
  124. package/dist/extensions/subagent/schema.d.ts.map +1 -1
  125. package/dist/extensions/subagent/schema.js +8 -13
  126. package/dist/extensions/subagent/schema.js.map +1 -1
  127. package/dist/extensions/subagent/sdk-runner.d.ts.map +1 -1
  128. package/dist/extensions/subagent/sdk-runner.js +9 -20
  129. package/dist/extensions/subagent/sdk-runner.js.map +1 -1
  130. package/dist/extensions/subagent/settings.d.ts +2 -3
  131. package/dist/extensions/subagent/settings.d.ts.map +1 -1
  132. package/dist/extensions/subagent/settings.js +30 -21
  133. package/dist/extensions/subagent/settings.js.map +1 -1
  134. package/dist/extensions/subagent/text.d.ts +3 -0
  135. package/dist/extensions/subagent/text.d.ts.map +1 -0
  136. package/dist/extensions/subagent/text.js +16 -0
  137. package/dist/extensions/subagent/text.js.map +1 -0
  138. package/dist/extensions/subagent/types.d.ts +13 -33
  139. package/dist/extensions/subagent/types.d.ts.map +1 -1
  140. package/dist/extensions/subagent/types.js.map +1 -1
  141. package/dist/extensions/subagent/ui/model-list.d.ts +68 -0
  142. package/dist/extensions/subagent/ui/model-list.d.ts.map +1 -0
  143. package/dist/extensions/subagent/ui/model-list.js +248 -0
  144. package/dist/extensions/subagent/ui/model-list.js.map +1 -0
  145. package/dist/extensions/todo/constants.d.ts +6 -17
  146. package/dist/extensions/todo/constants.d.ts.map +1 -1
  147. package/dist/extensions/todo/constants.js +20 -31
  148. package/dist/extensions/todo/constants.js.map +1 -1
  149. package/dist/extensions/todo/index.d.ts.map +1 -1
  150. package/dist/extensions/todo/index.js +36 -57
  151. package/dist/extensions/todo/index.js.map +1 -1
  152. package/dist/extensions/todo/schema.d.ts +20 -59
  153. package/dist/extensions/todo/schema.d.ts.map +1 -1
  154. package/dist/extensions/todo/schema.js +23 -69
  155. package/dist/extensions/todo/schema.js.map +1 -1
  156. package/dist/extensions/todo/state.d.ts +23 -65
  157. package/dist/extensions/todo/state.d.ts.map +1 -1
  158. package/dist/extensions/todo/state.js +238 -1262
  159. package/dist/extensions/todo/state.js.map +1 -1
  160. package/dist/extensions/todo/view.d.ts +19 -10
  161. package/dist/extensions/todo/view.d.ts.map +1 -1
  162. package/dist/extensions/todo/view.js +411 -463
  163. package/dist/extensions/todo/view.js.map +1 -1
  164. package/dist/extensions/todo/widget.d.ts +15 -0
  165. package/dist/extensions/todo/widget.d.ts.map +1 -0
  166. package/dist/extensions/todo/widget.js +50 -0
  167. package/dist/extensions/todo/widget.js.map +1 -0
  168. package/dist/index.d.ts +1 -1
  169. package/dist/index.d.ts.map +1 -1
  170. package/dist/index.js.map +1 -1
  171. package/dist/main.d.ts.map +1 -1
  172. package/dist/main.js +5 -1
  173. package/dist/main.js.map +1 -1
  174. package/dist/modes/interactive/components/extension-selector.d.ts +1 -2
  175. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  176. package/dist/modes/interactive/components/extension-selector.js +5 -11
  177. package/dist/modes/interactive/components/extension-selector.js.map +1 -1
  178. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  179. package/dist/modes/interactive/components/model-selector.js +2 -1
  180. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  181. package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
  182. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  183. package/dist/modes/interactive/components/settings-selector.js +10 -0
  184. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  185. package/dist/modes/interactive/interactive-mode.d.ts +8 -2
  186. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  187. package/dist/modes/interactive/interactive-mode.js +77 -25
  188. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  189. package/dist/modes/interactive/model-catalog-refresh.d.ts +7 -0
  190. package/dist/modes/interactive/model-catalog-refresh.d.ts.map +1 -0
  191. package/dist/modes/interactive/model-catalog-refresh.js +36 -0
  192. package/dist/modes/interactive/model-catalog-refresh.js.map +1 -0
  193. package/dist/modes/interactive/theme/dark.json +2 -0
  194. package/dist/modes/interactive/theme/light.json +2 -0
  195. package/dist/modes/interactive/theme/theme-controller.d.ts +10 -2
  196. package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
  197. package/dist/modes/interactive/theme/theme-controller.js +23 -10
  198. package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
  199. package/dist/modes/interactive/theme/theme-schema.json +9 -1
  200. package/dist/modes/interactive/theme/theme.d.ts +5 -3
  201. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  202. package/dist/modes/interactive/theme/theme.js +12 -2
  203. package/dist/modes/interactive/theme/theme.js.map +1 -1
  204. package/dist/modes/json-event.d.ts +4 -1
  205. package/dist/modes/json-event.d.ts.map +1 -1
  206. package/dist/modes/json-event.js +5 -2
  207. package/dist/modes/json-event.js.map +1 -1
  208. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  209. package/dist/modes/rpc/rpc-mode.js +1 -8
  210. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  211. package/dist/package-manager-cli.js +1 -1
  212. package/dist/package-manager-cli.js.map +1 -1
  213. package/dist/server/create-harness.d.ts.map +1 -1
  214. package/dist/server/create-harness.js +2 -0
  215. package/dist/server/create-harness.js.map +1 -1
  216. package/dist/utils/tools-manager.d.ts +10 -1
  217. package/dist/utils/tools-manager.d.ts.map +1 -1
  218. package/dist/utils/tools-manager.js +14 -19
  219. package/dist/utils/tools-manager.js.map +1 -1
  220. package/docs/bundled/README.md +2 -1
  221. package/docs/bundled/extensions/background.md +64 -0
  222. package/docs/bundled/extensions/subagent.md +84 -57
  223. package/docs/bundled/extensions/todo.md +84 -24
  224. package/docs/bundled/tool-presentation.md +1 -1
  225. package/docs/compaction.md +6 -6
  226. package/docs/custom-provider.md +1 -1
  227. package/docs/docs.json +4 -0
  228. package/docs/environment-variables.md +8 -2
  229. package/docs/extensions.md +6 -2
  230. package/docs/json.md +6 -4
  231. package/docs/keybindings.md +9 -2
  232. package/docs/rpc.md +15 -4
  233. package/docs/sdk.md +9 -0
  234. package/docs/settings.md +31 -0
  235. package/docs/terminal-setup.md +23 -2
  236. package/docs/themes.md +24 -3
  237. package/docs/tui.md +2 -2
  238. package/docs/usage.md +4 -3
  239. package/examples/README.md +1 -1
  240. package/examples/extensions/README.md +0 -1
  241. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  242. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  243. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  244. package/examples/extensions/gondolin/package-lock.json +2 -2
  245. package/examples/extensions/gondolin/package.json +1 -1
  246. package/examples/extensions/sandbox/package-lock.json +2 -2
  247. package/examples/extensions/sandbox/package.json +1 -1
  248. package/examples/extensions/with-deps/package-lock.json +2 -2
  249. package/examples/extensions/with-deps/package.json +1 -1
  250. package/npm-shrinkwrap.json +170 -221
  251. package/package.json +6 -6
  252. package/dist/extensions/subagent/picker.d.ts +0 -31
  253. package/dist/extensions/subagent/picker.d.ts.map +0 -1
  254. package/dist/extensions/subagent/picker.js +0 -109
  255. package/dist/extensions/subagent/picker.js.map +0 -1
  256. package/dist/extensions/todo/overlay.d.ts +0 -24
  257. package/dist/extensions/todo/overlay.d.ts.map +0 -1
  258. package/dist/extensions/todo/overlay.js +0 -135
  259. package/dist/extensions/todo/overlay.js.map +0 -1
  260. package/examples/extensions/subagent/README.md +0 -175
  261. package/examples/extensions/subagent/agents/planner.md +0 -37
  262. package/examples/extensions/subagent/agents/reviewer.md +0 -35
  263. package/examples/extensions/subagent/agents/scout.md +0 -50
  264. package/examples/extensions/subagent/agents/worker.md +0 -24
  265. package/examples/extensions/subagent/agents.ts +0 -126
  266. package/examples/extensions/subagent/index.ts +0 -1009
  267. package/examples/extensions/subagent/prompts/implement-and-review.md +0 -10
  268. package/examples/extensions/subagent/prompts/implement.md +0 -10
  269. package/examples/extensions/subagent/prompts/scout-and-plan.md +0 -9
@@ -1,8 +1,8 @@
1
1
  import { relative } from "node:path";
2
2
  import { isRetryableAssistantError } from "@earendil-works/pi-ai/compat";
3
3
  import { sleep } from "../../utils/sleep.js";
4
- import { boundText, emptyUsage, mergeUsage, tailText, toNestedUsage } from "./activity.js";
5
- import { DETAILS_ACTIVITY_LIMIT, DETAILS_OUTPUT_LIMIT, ERROR_TEXT_LIMIT, MAX_CONCURRENCY, MAX_TASKS, PARALLEL_OUTPUT_LIMIT, PARALLEL_TASK_OUTPUT_LIMIT, RETRY_ERROR_TEXT_LIMIT, SINGLE_OUTPUT_LIMIT, TASK_RETRY_BASE_DELAY_MS, TASK_RETRY_LIMIT, } from "./constants.js";
4
+ import { boundText, emptyUsage, mergeUsage, toNestedUsage } from "./activity.js";
5
+ import { DETAILS_ACTIVITY_LIMIT, DETAILS_OUTPUT_LIMIT, ERROR_TEXT_LIMIT, MAX_CONCURRENCY, MAX_TASKS, RETRY_ERROR_TEXT_LIMIT, TASK_OUTPUT_LIMIT, TASK_RETRY_BASE_DELAY_MS, TASK_RETRY_LIMIT, TOTAL_OUTPUT_LIMIT, } from "./constants.js";
6
6
  import { resolveSubagentTask } from "./resolve.js";
7
7
  import { beginSubagentRetry, clearSubagentRetry } from "./retry.js";
8
8
  import { runSdkTask } from "./sdk-runner.js";
@@ -57,9 +57,7 @@ function createRun(task, index, parentCwd) {
57
57
  return {
58
58
  id: runId(index),
59
59
  agent: task.agent.name,
60
- agentSource: task.agent.source,
61
60
  description: task.description,
62
- prompt: task.prompt,
63
61
  // Display-only relative path; the worker session itself uses the
64
62
  // resolved absolute task.cwd. Empty means "same as the parent".
65
63
  cwd: relative(parentCwd, task.cwd),
@@ -67,8 +65,7 @@ function createRun(task, index, parentCwd) {
67
65
  thinking: task.thinking,
68
66
  status: "queued",
69
67
  activities: [],
70
- liveText: "",
71
- finalOutput: "",
68
+ report: "",
72
69
  usage: emptyUsage(),
73
70
  };
74
71
  }
@@ -83,12 +80,11 @@ function detailsSize(details) {
83
80
  }
84
81
  export function boundSubagentDetails(details) {
85
82
  const perRunBudget = Math.max(1_024, Math.floor((DETAILS_OUTPUT_LIMIT - 8 * 1024) / Math.max(1, details.runs.length)));
86
- const outputLimit = Math.min(SINGLE_OUTPUT_LIMIT, Math.max(1_024, perRunBudget - 7 * 1024));
83
+ const reportLimit = Math.min(TASK_OUTPUT_LIMIT, Math.max(1_024, perRunBudget - 7 * 1024));
87
84
  const bounded = {
88
85
  ...details,
89
86
  runs: details.runs.map((run) => ({
90
87
  ...run,
91
- prompt: boundText(run.prompt, 1_024),
92
88
  cwd: boundText(run.cwd, 1_024),
93
89
  currentActivity: run.currentActivity ? boundText(run.currentActivity, 512) : undefined,
94
90
  retry: run.retry ? { ...run.retry, error: boundText(run.retry.error, RETRY_ERROR_TEXT_LIMIT) } : undefined,
@@ -97,21 +93,13 @@ export function boundSubagentDetails(details) {
97
93
  summary: boundText(activity.summary, 256),
98
94
  resultSummary: activity.resultSummary ? boundText(activity.resultSummary, 256) : undefined,
99
95
  })),
100
- // liveText is a tail by construction: keep the newest lines, not the
101
- // head, or the transcript's live tail would freeze at the 1KB mark.
102
- liveText: tailText(run.liveText, 1_024),
103
- finalOutput: boundText(run.finalOutput, outputLimit),
96
+ report: boundText(run.report, reportLimit),
104
97
  error: run.error ? boundText(run.error, 1_024) : undefined,
105
98
  })),
106
99
  };
107
100
  const fields = [];
108
101
  for (const run of bounded.runs) {
109
102
  fields.push({
110
- get: () => run.prompt,
111
- set: (value) => {
112
- run.prompt = value;
113
- },
114
- }, {
115
103
  get: () => run.cwd,
116
104
  set: (value) => {
117
105
  run.cwd = value;
@@ -122,14 +110,9 @@ export function boundSubagentDetails(details) {
122
110
  run.currentActivity = value || undefined;
123
111
  },
124
112
  }, {
125
- get: () => run.liveText,
113
+ get: () => run.report,
126
114
  set: (value) => {
127
- run.liveText = value;
128
- },
129
- }, {
130
- get: () => run.finalOutput,
131
- set: (value) => {
132
- run.finalOutput = value;
115
+ run.report = value;
133
116
  },
134
117
  }, {
135
118
  get: () => run.error ?? "",
@@ -163,30 +146,28 @@ export function boundSubagentDetails(details) {
163
146
  return bounded;
164
147
  }
165
148
  function statusOf(runs) {
166
- if (runs.some((run) => run.status === "aborted"))
167
- return "aborted";
168
- if (runs.some((run) => run.status === "failed"))
169
- return "failed";
149
+ if (runs.length === 0)
150
+ return "running";
151
+ // Active beats terminal: any queued or running run keeps the batch
152
+ // "running" regardless of what the others have settled to.
170
153
  if (runs.some((run) => run.status === "queued" || run.status === "running"))
171
154
  return "running";
172
- return "completed";
155
+ if (runs.every((run) => run.status === "completed"))
156
+ return "completed";
157
+ if (runs.some((run) => run.status === "completed"))
158
+ return "partial";
159
+ if (runs.every((run) => run.status === "aborted"))
160
+ return "aborted";
161
+ return "failed";
173
162
  }
174
163
  function statusText(details) {
164
+ if (details.runs.length === 0)
165
+ return "Initializing…";
175
166
  const running = details.runs.filter((run) => run.status === "running").length;
176
167
  const queued = details.runs.filter((run) => run.status === "queued").length;
177
168
  const completed = details.runs.filter((run) => run.status === "completed").length;
178
169
  const failed = details.runs.filter((run) => run.status === "failed").length;
179
170
  const aborted = details.runs.filter((run) => run.status === "aborted").length;
180
- if (details.mode === "single") {
181
- const run = details.runs[0];
182
- if (run?.currentActivity)
183
- return run.currentActivity;
184
- if (!run ||
185
- (run.status === "running" && run.usage.turns === 0 && run.usage.toolUses === 0 && run.liveText.length === 0)) {
186
- return "Initializing…";
187
- }
188
- return run.status === "running" ? "Thinking…" : run.status;
189
- }
190
171
  const parts = [`${completed}/${details.runs.length} complete`];
191
172
  if (running)
192
173
  parts.push(`${running} running`);
@@ -198,9 +179,8 @@ function statusText(details) {
198
179
  parts.push(`${aborted} aborted`);
199
180
  return parts.join(" · ");
200
181
  }
201
- function emitDetails(mode, runs, startedAt, onUpdate) {
182
+ function emitDetails(runs, startedAt, onUpdate) {
202
183
  const details = {
203
- mode,
204
184
  status: statusOf(runs),
205
185
  runs: [...runs],
206
186
  startedAt,
@@ -217,8 +197,14 @@ function validateTaskCount(tasks) {
217
197
  }
218
198
  async function resolveTasks(tasks, options) {
219
199
  validateTaskCount(tasks);
200
+ // One config load and one resolution pass for the whole batch: every
201
+ // task/profile/cwd/model is settled before any run is created or any
202
+ // worker starts, so a failing task cannot strand half-initialized runs.
220
203
  const config = await loadSubagentConfig(options.agentDir);
221
- return Promise.all(tasks.map((task) => resolveSubagentTask(task, options.parentCwd, options.agents, options.parent, options.agentDir, config)));
204
+ return Promise.all(tasks.map((task, index) => resolveSubagentTask(task, options.parentCwd, options.parent, options.agentDir, config).catch((error) => {
205
+ const message = error instanceof Error ? error.message : String(error);
206
+ throw new Error(`Subagent task tasks[${index}] failed to resolve: ${message}`);
207
+ })));
222
208
  }
223
209
  // Reuses pi-ai's provider-error classification by wrapping the stored error
224
210
  // text in the assistant-message shape it inspects.
@@ -241,8 +227,7 @@ function resetRunForRetry(run, attempt, maxAttempts, delayMs) {
241
227
  run.error = undefined;
242
228
  run.startedAt = undefined;
243
229
  run.endedAt = undefined;
244
- run.finalOutput = "";
245
- run.liveText = "";
230
+ run.report = "";
246
231
  run.activities.length = 0;
247
232
  run.usage = emptyUsage();
248
233
  beginSubagentRetry(run, { attempt, maxAttempts, delayMs, error });
@@ -264,19 +249,25 @@ async function waitForTaskRetry(delayMs, options) {
264
249
  unregisterAbort?.();
265
250
  }
266
251
  }
252
+ // The gate slot is held only while a worker session actually runs. Backoff
253
+ // waits outside the slot (release, sleep, reacquire) so a retrying task
254
+ // cannot starve queued tasks, and aborting during the wait settles the run
255
+ // without occupying the gate.
267
256
  async function runWithGate(task, run, options, onProgress) {
268
257
  onProgress();
269
- let release;
270
- try {
271
- release = await options.gate.acquire(options.signal);
272
- if (options.signal?.aborted) {
273
- run.status = "aborted";
274
- run.error = "Subagent was aborted while queued.";
275
- return run;
276
- }
277
- const baseDelayMs = options.taskRetryBaseDelayMs ?? TASK_RETRY_BASE_DELAY_MS;
278
- for (let attempt = 0;; attempt++) {
279
- clearSubagentRetry(run);
258
+ const baseDelayMs = options.taskRetryBaseDelayMs ?? TASK_RETRY_BASE_DELAY_MS;
259
+ for (let attempt = 0;; attempt++) {
260
+ clearSubagentRetry(run);
261
+ let release;
262
+ let delayMs = 0;
263
+ try {
264
+ release = await options.gate.acquire(options.signal);
265
+ if (options.signal?.aborted) {
266
+ run.status = "aborted";
267
+ run.error = "Subagent was aborted while queued.";
268
+ run.endedAt = Date.now();
269
+ return run;
270
+ }
280
271
  const result = await runSdkTask({
281
272
  task,
282
273
  run,
@@ -289,77 +280,66 @@ async function runWithGate(task, run, options, onProgress) {
289
280
  });
290
281
  if (attempt >= TASK_RETRY_LIMIT || options.signal?.aborted || !shouldRetryTask(result))
291
282
  return result;
292
- const delayMs = baseDelayMs * 2 ** attempt;
283
+ delayMs = baseDelayMs * 2 ** attempt;
293
284
  resetRunForRetry(run, attempt + 1, TASK_RETRY_LIMIT, delayMs);
294
285
  onProgress();
295
- try {
296
- await waitForTaskRetry(delayMs, options);
297
- }
298
- catch {
299
- clearSubagentRetry(run);
300
- run.status = "aborted";
301
- run.error = "Subagent was aborted while waiting to retry.";
302
- run.endedAt = Date.now();
303
- onProgress();
304
- return run;
305
- }
286
+ }
287
+ catch (error) {
288
+ clearSubagentRetry(run);
289
+ run.status = options.signal?.aborted ? "aborted" : "failed";
290
+ run.error = boundText(error instanceof Error ? error.message : String(error), ERROR_TEXT_LIMIT);
291
+ run.endedAt = Date.now();
292
+ onProgress();
293
+ return run;
294
+ }
295
+ finally {
296
+ release?.();
297
+ }
298
+ try {
299
+ await waitForTaskRetry(delayMs, options);
300
+ }
301
+ catch {
302
+ clearSubagentRetry(run);
303
+ run.status = "aborted";
304
+ run.error = "Subagent was aborted while waiting to retry.";
305
+ run.endedAt = Date.now();
306
+ onProgress();
307
+ return run;
306
308
  }
307
309
  }
308
- catch (error) {
309
- clearSubagentRetry(run);
310
- run.status = options.signal?.aborted ? "aborted" : "failed";
311
- run.error = boundText(error instanceof Error ? error.message : String(error), ERROR_TEXT_LIMIT);
312
- run.endedAt = Date.now();
313
- onProgress();
314
- return run;
315
- }
316
- finally {
317
- release?.();
310
+ }
311
+ // Fair per-task report budget: the total cap is split evenly after reserving
312
+ // room for the numbered section headings and separators, capped per task.
313
+ function perTaskReportBudget(taskCount) {
314
+ const headingReserve = Math.min(256 * taskCount, Math.floor(TOTAL_OUTPUT_LIMIT / 4));
315
+ const fairShare = Math.floor((TOTAL_OUTPUT_LIMIT - headingReserve) / Math.max(1, taskCount));
316
+ return Math.min(TASK_OUTPUT_LIMIT, Math.max(2_048, fairShare));
317
+ }
318
+ function reportSectionTitle(run, index) {
319
+ return `### ${index + 1}. ${run.description} (${run.agent}) — ${run.status}`;
320
+ }
321
+ function reportSectionBody(run) {
322
+ if (run.status === "completed")
323
+ return run.report || EMPTY_OUTPUT;
324
+ if (run.status === "failed" || run.status === "aborted") {
325
+ const verdict = run.status === "aborted" ? "Subagent aborted" : "Subagent failed";
326
+ const cause = run.error ? `: ${run.error}` : ".";
327
+ const partial = run.report ? `\n\nPartial report:\n${run.report}` : "";
328
+ return `${verdict}${cause}${partial}`;
318
329
  }
330
+ if (run.status === "queued")
331
+ return "Task was queued and never started.";
332
+ return "Task was still running when the batch settled.";
319
333
  }
334
+ // Always ordered numbered sections, even for a single task, so the parent
335
+ // can reference results by number. Total cap with a fair per-task budget;
336
+ // empty, failed, aborted, and partial reports are labeled explicitly.
320
337
  function resultContent(details) {
321
- if (details.mode === "single") {
322
- const run = details.runs[0];
323
- if (!run)
324
- return "Subagent produced no run.";
325
- if (run.status === "failed" || run.status === "aborted") {
326
- return boundText(`${run.status === "aborted" ? "Subagent aborted" : "Subagent failed"}: ${run.error ?? "unknown error"}${run.finalOutput ? `\n\nPartial response:\n${run.finalOutput}` : ""}`, SINGLE_OUTPUT_LIMIT);
327
- }
328
- return run.finalOutput || EMPTY_OUTPUT;
329
- }
330
- const sections = details.runs.map((run) => {
331
- const output = run.finalOutput || run.error || EMPTY_OUTPUT;
332
- return `### ${run.description} (${run.agent}) — ${run.status}\n\n${boundText(output, PARALLEL_TASK_OUTPUT_LIMIT)}`;
338
+ const perTaskBudget = perTaskReportBudget(details.runs.length);
339
+ const sections = details.runs.map((run, index) => {
340
+ return `${reportSectionTitle(run, index)}\n\n${boundText(reportSectionBody(run), perTaskBudget)}`;
333
341
  });
334
- return boundText(sections.join("\n\n---\n\n"), PARALLEL_OUTPUT_LIMIT);
335
- }
336
- function invocationMode(params) {
337
- const provided = [];
338
- if (params.prompt != null)
339
- provided.push("prompt");
340
- if (params.tasks != null)
341
- provided.push("tasks");
342
- if (provided.length !== 1) {
343
- throw new Error(provided.length === 0
344
- ? "Provide exactly one subagent mode: prompt (single task) or tasks (parallel tasks); none was provided."
345
- : `Provide exactly one subagent mode: received ${provided.join(", ")}. Keep one and set the unused mode fields to null or omit them.`);
346
- }
347
- if (params.tasks != null) {
348
- return { mode: "parallel", tasks: params.tasks };
349
- }
350
- if (!params.description)
351
- throw new Error("description is required for single mode.");
352
- return {
353
- mode: "single",
354
- tasks: [
355
- {
356
- agent: params.agent,
357
- description: params.description,
358
- prompt: params.prompt,
359
- cwd: params.cwd,
360
- },
361
- ],
362
- };
342
+ return boundText(sections.join("\n\n---\n\n"), TOTAL_OUTPUT_LIMIT);
363
343
  }
364
344
  // Cheap change detector: consecutive events that alter nothing user-visible
365
345
  // skip the bounded-details serialization in emitDetails entirely. Every
@@ -378,9 +358,7 @@ export function progressKey(runs) {
378
358
  run.retry?.maxAttempts ?? "",
379
359
  run.retry?.deadline ?? "",
380
360
  run.retry?.error ?? "",
381
- run.liveText.length,
382
- run.liveText.slice(-24),
383
- run.finalOutput.length,
361
+ run.report.length,
384
362
  run.usage.turns,
385
363
  run.usage.toolUses,
386
364
  run.usage.totalTokens,
@@ -397,26 +375,26 @@ export function isSubagentError(details) {
397
375
  return !details.runs.some((run) => run.status === "completed");
398
376
  }
399
377
  export async function runSubagentInvocation(options) {
400
- const { mode, tasks } = invocationMode(options.params);
378
+ // Defensive count check: the schema already enforces 1..MAX_TASKS, but
379
+ // strict providers can bypass minItems, so validate before any work.
380
+ const tasks = options.params.tasks ?? [];
401
381
  const resolved = await resolveTasks(tasks, options);
402
382
  const runs = resolved.map((task, index) => createRun(task, index, options.parentCwd));
403
383
  const startedAt = Date.now();
404
- let latestDetails = emitDetails(mode, runs, startedAt, options.onUpdate);
384
+ let latestDetails = emitDetails(runs, startedAt, options.onUpdate);
405
385
  let lastProgressKey = progressKey(runs);
406
386
  const progress = () => {
407
387
  const key = progressKey(runs);
408
388
  if (key === lastProgressKey)
409
389
  return;
410
390
  lastProgressKey = key;
411
- latestDetails = emitDetails(mode, runs, startedAt, options.onUpdate);
391
+ latestDetails = emitDetails(runs, startedAt, options.onUpdate);
412
392
  };
413
- if (mode === "single") {
414
- await runWithGate(resolved[0], runs[0], options, progress);
415
- }
416
- else {
417
- await Promise.all(resolved.map((task, index) => runWithGate(task, runs[index], options, progress)));
418
- }
419
- latestDetails = emitDetails(mode, runs, startedAt, undefined);
393
+ // Every task runs concurrently through the shared gate; Promise.all keeps
394
+ // result order identical to input order. There is no single-task branch:
395
+ // one task is just a batch of one.
396
+ await Promise.all(resolved.map((task, index) => runWithGate(task, runs[index], options, progress)));
397
+ latestDetails = emitDetails(runs, startedAt, undefined);
420
398
  latestDetails.endedAt = Date.now();
421
399
  // Error classification lives in the tool_result handler (index.ts), the
422
400
  // only channel that reaches the session transcript and export.
@@ -1 +1 @@
1
- {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../../src/extensions/subagent/runner.ts"],"names":[],"mappings":"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","sourcesContent":["import { relative } from \"node:path\";\nimport { isRetryableAssistantError } from \"@earendil-works/pi-ai/compat\";\nimport type { ModelRuntime } from \"../../core/model-runtime.ts\";\nimport { sleep } from \"../../utils/sleep.ts\";\nimport { boundText, emptyUsage, mergeUsage, tailText, toNestedUsage } from \"./activity.ts\";\nimport {\n\tDETAILS_ACTIVITY_LIMIT,\n\tDETAILS_OUTPUT_LIMIT,\n\tERROR_TEXT_LIMIT,\n\tMAX_CONCURRENCY,\n\tMAX_TASKS,\n\tPARALLEL_OUTPUT_LIMIT,\n\tPARALLEL_TASK_OUTPUT_LIMIT,\n\tRETRY_ERROR_TEXT_LIMIT,\n\tSINGLE_OUTPUT_LIMIT,\n\tTASK_RETRY_BASE_DELAY_MS,\n\tTASK_RETRY_LIMIT,\n} from \"./constants.ts\";\nimport { type ParentModelContext, resolveSubagentTask } from \"./resolve.ts\";\nimport { beginSubagentRetry, clearSubagentRetry } from \"./retry.ts\";\nimport type { SubagentParams, SubagentTask } from \"./schema.ts\";\nimport { runSdkTask } from \"./sdk-runner.ts\";\nimport { loadSubagentConfig } from \"./settings.ts\";\nimport type {\n\tAgentDefinition,\n\tResolvedSubagentTask,\n\tSubagentDetails,\n\tSubagentExecutionResult,\n\tSubagentRunDetails,\n\tSubagentUsage,\n} from \"./types.ts\";\n\nconst EMPTY_OUTPUT = \"(Subagent completed but returned no output.)\";\n\ninterface Waiter {\n\tresolve: (release: () => void) => void;\n\treject: (error: Error) => void;\n\tsignal?: AbortSignal;\n\tabortListener?: () => void;\n}\n\nexport class ConcurrencyGate {\n\tprivate active = 0;\n\tprivate readonly waiters: Waiter[] = [];\n\tprivate readonly limit: number;\n\n\tconstructor(limit = MAX_CONCURRENCY) {\n\t\tthis.limit = limit;\n\t}\n\n\tacquire(signal?: AbortSignal): Promise<() => void> {\n\t\tif (signal?.aborted) return Promise.reject(new Error(\"Subagent was aborted while queued.\"));\n\t\tif (this.active < this.limit) {\n\t\t\tthis.active++;\n\t\t\treturn Promise.resolve(() => this.release());\n\t\t}\n\t\treturn new Promise<() => void>((resolve, reject) => {\n\t\t\tconst waiter: Waiter = { resolve, reject, signal };\n\t\t\tif (signal) {\n\t\t\t\twaiter.abortListener = () => {\n\t\t\t\t\tconst index = this.waiters.indexOf(waiter);\n\t\t\t\t\tif (index >= 0) this.waiters.splice(index, 1);\n\t\t\t\t\treject(new Error(\"Subagent was aborted while queued.\"));\n\t\t\t\t};\n\t\t\t\tsignal.addEventListener(\"abort\", waiter.abortListener, { once: true });\n\t\t\t}\n\t\t\tthis.waiters.push(waiter);\n\t\t});\n\t}\n\n\tprivate release(): void {\n\t\tthis.active = Math.max(0, this.active - 1);\n\t\twhile (this.waiters.length > 0) {\n\t\t\tconst waiter = this.waiters.shift()!;\n\t\t\tif (waiter.signal?.aborted) {\n\t\t\t\twaiter.abortListener?.();\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\twaiter.signal?.removeEventListener(\"abort\", waiter.abortListener!);\n\t\t\tthis.active++;\n\t\t\twaiter.resolve(() => this.release());\n\t\t\treturn;\n\t\t}\n\t}\n}\n\nexport interface SubagentInvocationOptions {\n\tparams: SubagentParams;\n\tparentCwd: string;\n\tagents: readonly AgentDefinition[];\n\tparent: ParentModelContext;\n\tmodelRuntime: ModelRuntime;\n\tagentDir: string;\n\tprojectTrusted: boolean;\n\tsignal?: AbortSignal;\n\tgate: ConcurrencyGate;\n\tonUpdate?: (details: SubagentDetails) => void;\n\tregisterAbort?: (abort: () => Promise<void>) => () => void;\n\t/** Test hook: overrides the task-retry backoff base delay. */\n\ttaskRetryBaseDelayMs?: number;\n}\n\nfunction runId(index: number): string {\n\treturn `subagent-${index + 1}`;\n}\n\nfunction createRun(task: ResolvedSubagentTask, index: number, parentCwd: string): SubagentRunDetails {\n\treturn {\n\t\tid: runId(index),\n\t\tagent: task.agent.name,\n\t\tagentSource: task.agent.source,\n\t\tdescription: task.description,\n\t\tprompt: task.prompt,\n\t\t// Display-only relative path; the worker session itself uses the\n\t\t// resolved absolute task.cwd. Empty means \"same as the parent\".\n\t\tcwd: relative(parentCwd, task.cwd),\n\t\tmodel: `${task.model.provider}/${task.model.id}`,\n\t\tthinking: task.thinking,\n\t\tstatus: \"queued\",\n\t\tactivities: [],\n\t\tliveText: \"\",\n\t\tfinalOutput: \"\",\n\t\tusage: emptyUsage(),\n\t};\n}\n\nfunction aggregateUsage(runs: readonly SubagentRunDetails[]): SubagentUsage {\n\tconst usage = emptyUsage();\n\tfor (const run of runs) mergeUsage(usage, run.usage);\n\treturn usage;\n}\n\ninterface TextField {\n\tget: () => string;\n\tset: (value: string) => void;\n}\n\nfunction detailsSize(details: SubagentDetails): number {\n\treturn Buffer.byteLength(JSON.stringify(details), \"utf8\");\n}\n\nexport function boundSubagentDetails(details: SubagentDetails): SubagentDetails {\n\tconst perRunBudget = Math.max(\n\t\t1_024,\n\t\tMath.floor((DETAILS_OUTPUT_LIMIT - 8 * 1024) / Math.max(1, details.runs.length)),\n\t);\n\tconst outputLimit = Math.min(SINGLE_OUTPUT_LIMIT, Math.max(1_024, perRunBudget - 7 * 1024));\n\tconst bounded: SubagentDetails = {\n\t\t...details,\n\t\truns: details.runs.map((run) => ({\n\t\t\t...run,\n\t\t\tprompt: boundText(run.prompt, 1_024),\n\t\t\tcwd: boundText(run.cwd, 1_024),\n\t\t\tcurrentActivity: run.currentActivity ? boundText(run.currentActivity, 512) : undefined,\n\t\t\tretry: run.retry ? { ...run.retry, error: boundText(run.retry.error, RETRY_ERROR_TEXT_LIMIT) } : undefined,\n\t\t\tactivities: run.activities.slice(-DETAILS_ACTIVITY_LIMIT).map((activity) => ({\n\t\t\t\t...activity,\n\t\t\t\tsummary: boundText(activity.summary, 256),\n\t\t\t\tresultSummary: activity.resultSummary ? boundText(activity.resultSummary, 256) : undefined,\n\t\t\t})),\n\t\t\t// liveText is a tail by construction: keep the newest lines, not the\n\t\t\t// head, or the transcript's live tail would freeze at the 1KB mark.\n\t\t\tliveText: tailText(run.liveText, 1_024),\n\t\t\tfinalOutput: boundText(run.finalOutput, outputLimit),\n\t\t\terror: run.error ? boundText(run.error, 1_024) : undefined,\n\t\t})),\n\t};\n\tconst fields: TextField[] = [];\n\tfor (const run of bounded.runs) {\n\t\tfields.push(\n\t\t\t{\n\t\t\t\tget: () => run.prompt,\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.prompt = value;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tget: () => run.cwd,\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.cwd = value;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tget: () => run.currentActivity ?? \"\",\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.currentActivity = value || undefined;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tget: () => run.liveText,\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.liveText = value;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tget: () => run.finalOutput,\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.finalOutput = value;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tget: () => run.error ?? \"\",\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.error = value || undefined;\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t\tfor (const activity of run.activities) {\n\t\t\tfields.push(\n\t\t\t\t{\n\t\t\t\t\tget: () => activity.summary,\n\t\t\t\t\tset: (value) => {\n\t\t\t\t\t\tactivity.summary = value;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tget: () => activity.resultSummary ?? \"\",\n\t\t\t\t\tset: (value) => {\n\t\t\t\t\t\tactivity.resultSummary = value || undefined;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t}\n\twhile (detailsSize(bounded) > DETAILS_OUTPUT_LIMIT) {\n\t\tconst largest = fields\n\t\t\t.map((field) => ({ field, size: Buffer.byteLength(field.get(), \"utf8\") }))\n\t\t\t.sort((left, right) => right.size - left.size)[0];\n\t\tif (!largest || largest.size === 0) break;\n\t\tconst overflow = detailsSize(bounded) - DETAILS_OUTPUT_LIMIT;\n\t\tlargest.field.set(boundText(largest.field.get(), Math.max(0, largest.size - overflow)));\n\t}\n\treturn bounded;\n}\n\nfunction statusOf(runs: readonly SubagentRunDetails[]): SubagentDetails[\"status\"] {\n\tif (runs.some((run) => run.status === \"aborted\")) return \"aborted\";\n\tif (runs.some((run) => run.status === \"failed\")) return \"failed\";\n\tif (runs.some((run) => run.status === \"queued\" || run.status === \"running\")) return \"running\";\n\treturn \"completed\";\n}\n\nfunction statusText(details: SubagentDetails): string {\n\tconst running = details.runs.filter((run) => run.status === \"running\").length;\n\tconst queued = details.runs.filter((run) => run.status === \"queued\").length;\n\tconst completed = details.runs.filter((run) => run.status === \"completed\").length;\n\tconst failed = details.runs.filter((run) => run.status === \"failed\").length;\n\tconst aborted = details.runs.filter((run) => run.status === \"aborted\").length;\n\tif (details.mode === \"single\") {\n\t\tconst run = details.runs[0];\n\t\tif (run?.currentActivity) return run.currentActivity;\n\t\tif (\n\t\t\t!run ||\n\t\t\t(run.status === \"running\" && run.usage.turns === 0 && run.usage.toolUses === 0 && run.liveText.length === 0)\n\t\t) {\n\t\t\treturn \"Initializing…\";\n\t\t}\n\t\treturn run.status === \"running\" ? \"Thinking…\" : run.status;\n\t}\n\tconst parts = [`${completed}/${details.runs.length} complete`];\n\tif (running) parts.push(`${running} running`);\n\tif (queued) parts.push(`${queued} queued`);\n\tif (failed) parts.push(`${failed} failed`);\n\tif (aborted) parts.push(`${aborted} aborted`);\n\treturn parts.join(\" · \");\n}\n\nfunction emitDetails(\n\tmode: SubagentDetails[\"mode\"],\n\truns: SubagentRunDetails[],\n\tstartedAt: number,\n\tonUpdate: ((details: SubagentDetails) => void) | undefined,\n): SubagentDetails {\n\tconst details: SubagentDetails = {\n\t\tmode,\n\t\tstatus: statusOf(runs),\n\t\truns: [...runs],\n\t\tstartedAt,\n\t\tusage: aggregateUsage(runs),\n\t};\n\tonUpdate?.(boundSubagentDetails(details));\n\treturn details;\n}\n\nfunction validateTaskCount(tasks: readonly SubagentTask[]): void {\n\tif (tasks.length === 0) throw new Error(\"Subagent task list must not be empty.\");\n\tif (tasks.length > MAX_TASKS) throw new Error(`Subagent task list is limited to ${MAX_TASKS} tasks.`);\n}\n\nasync function resolveTasks(\n\ttasks: readonly SubagentTask[],\n\toptions: SubagentInvocationOptions,\n): Promise<ResolvedSubagentTask[]> {\n\tvalidateTaskCount(tasks);\n\tconst config = await loadSubagentConfig(options.agentDir);\n\treturn Promise.all(\n\t\ttasks.map((task) =>\n\t\t\tresolveSubagentTask(task, options.parentCwd, options.agents, options.parent, options.agentDir, config),\n\t\t),\n\t);\n}\n\n// Reuses pi-ai's provider-error classification by wrapping the stored error\n// text in the assistant-message shape it inspects.\nfunction isRetryableRunError(error: string | undefined): boolean {\n\tif (!error) return false;\n\tconst probe = { role: \"assistant\", content: [], stopReason: \"error\", errorMessage: error };\n\treturn isRetryableAssistantError(probe as unknown as Parameters<typeof isRetryableAssistantError>[0]);\n}\n\n// Session-level auto-retry already covers errors that happen inside the agent\n// loop; this catches the paths that bypass it (preflight throws such as auth\n// checks). Only a run that produced nothing is retried, so partial work is\n// never discarded.\nfunction shouldRetryTask(run: SubagentRunDetails): boolean {\n\treturn (\n\t\trun.status === \"failed\" && run.usage.turns === 0 && run.usage.toolUses === 0 && isRetryableRunError(run.error)\n\t);\n}\n\nfunction resetRunForRetry(run: SubagentRunDetails, attempt: number, maxAttempts: number, delayMs: number): void {\n\tconst error = run.error ?? \"Subagent failed before retry.\";\n\trun.status = \"queued\";\n\trun.error = undefined;\n\trun.startedAt = undefined;\n\trun.endedAt = undefined;\n\trun.finalOutput = \"\";\n\trun.liveText = \"\";\n\trun.activities.length = 0;\n\trun.usage = emptyUsage();\n\tbeginSubagentRetry(run, { attempt, maxAttempts, delayMs, error });\n}\n\nasync function waitForTaskRetry(\n\tdelayMs: number,\n\toptions: Pick<SubagentInvocationOptions, \"signal\" | \"registerAbort\">,\n): Promise<void> {\n\tconst controller = new AbortController();\n\tconst abort = async (): Promise<void> => controller.abort();\n\tconst unregisterAbort = options.registerAbort?.(abort);\n\tconst abortListener = () => controller.abort();\n\tif (options.signal?.aborted) controller.abort();\n\telse options.signal?.addEventListener(\"abort\", abortListener, { once: true });\n\ttry {\n\t\tawait sleep(delayMs, controller.signal);\n\t} finally {\n\t\toptions.signal?.removeEventListener(\"abort\", abortListener);\n\t\tunregisterAbort?.();\n\t}\n}\n\nasync function runWithGate(\n\ttask: ResolvedSubagentTask,\n\trun: SubagentRunDetails,\n\toptions: SubagentInvocationOptions,\n\tonProgress: () => void,\n): Promise<SubagentRunDetails> {\n\tonProgress();\n\tlet release: (() => void) | undefined;\n\ttry {\n\t\trelease = await options.gate.acquire(options.signal);\n\t\tif (options.signal?.aborted) {\n\t\t\trun.status = \"aborted\";\n\t\t\trun.error = \"Subagent was aborted while queued.\";\n\t\t\treturn run;\n\t\t}\n\t\tconst baseDelayMs = options.taskRetryBaseDelayMs ?? TASK_RETRY_BASE_DELAY_MS;\n\t\tfor (let attempt = 0; ; attempt++) {\n\t\t\tclearSubagentRetry(run);\n\t\t\tconst result = await runSdkTask({\n\t\t\t\ttask,\n\t\t\t\trun,\n\t\t\t\tmodelRuntime: options.modelRuntime,\n\t\t\t\tagentDir: options.agentDir,\n\t\t\t\tprojectTrusted: options.projectTrusted,\n\t\t\t\tsignal: options.signal,\n\t\t\t\tonProgress,\n\t\t\t\tregisterAbort: options.registerAbort,\n\t\t\t});\n\t\t\tif (attempt >= TASK_RETRY_LIMIT || options.signal?.aborted || !shouldRetryTask(result)) return result;\n\t\t\tconst delayMs = baseDelayMs * 2 ** attempt;\n\t\t\tresetRunForRetry(run, attempt + 1, TASK_RETRY_LIMIT, delayMs);\n\t\t\tonProgress();\n\t\t\ttry {\n\t\t\t\tawait waitForTaskRetry(delayMs, options);\n\t\t\t} catch {\n\t\t\t\tclearSubagentRetry(run);\n\t\t\t\trun.status = \"aborted\";\n\t\t\t\trun.error = \"Subagent was aborted while waiting to retry.\";\n\t\t\t\trun.endedAt = Date.now();\n\t\t\t\tonProgress();\n\t\t\t\treturn run;\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tclearSubagentRetry(run);\n\t\trun.status = options.signal?.aborted ? \"aborted\" : \"failed\";\n\t\trun.error = boundText(error instanceof Error ? error.message : String(error), ERROR_TEXT_LIMIT);\n\t\trun.endedAt = Date.now();\n\t\tonProgress();\n\t\treturn run;\n\t} finally {\n\t\trelease?.();\n\t}\n}\n\nfunction resultContent(details: SubagentDetails): string {\n\tif (details.mode === \"single\") {\n\t\tconst run = details.runs[0];\n\t\tif (!run) return \"Subagent produced no run.\";\n\t\tif (run.status === \"failed\" || run.status === \"aborted\") {\n\t\t\treturn boundText(\n\t\t\t\t`${run.status === \"aborted\" ? \"Subagent aborted\" : \"Subagent failed\"}: ${run.error ?? \"unknown error\"}${run.finalOutput ? `\\n\\nPartial response:\\n${run.finalOutput}` : \"\"}`,\n\t\t\t\tSINGLE_OUTPUT_LIMIT,\n\t\t\t);\n\t\t}\n\t\treturn run.finalOutput || EMPTY_OUTPUT;\n\t}\n\tconst sections = details.runs.map((run) => {\n\t\tconst output = run.finalOutput || run.error || EMPTY_OUTPUT;\n\t\treturn `### ${run.description} (${run.agent}) — ${run.status}\\n\\n${boundText(output, PARALLEL_TASK_OUTPUT_LIMIT)}`;\n\t});\n\treturn boundText(sections.join(\"\\n\\n---\\n\\n\"), PARALLEL_OUTPUT_LIMIT);\n}\n\nfunction invocationMode(params: SubagentParams): { mode: SubagentDetails[\"mode\"]; tasks: SubagentTask[] } {\n\tconst provided: string[] = [];\n\tif (params.prompt != null) provided.push(\"prompt\");\n\tif (params.tasks != null) provided.push(\"tasks\");\n\tif (provided.length !== 1) {\n\t\tthrow new Error(\n\t\t\tprovided.length === 0\n\t\t\t\t? \"Provide exactly one subagent mode: prompt (single task) or tasks (parallel tasks); none was provided.\"\n\t\t\t\t: `Provide exactly one subagent mode: received ${provided.join(\", \")}. Keep one and set the unused mode fields to null or omit them.`,\n\t\t);\n\t}\n\tif (params.tasks != null) {\n\t\treturn { mode: \"parallel\", tasks: params.tasks };\n\t}\n\tif (!params.description) throw new Error(\"description is required for single mode.\");\n\treturn {\n\t\tmode: \"single\",\n\t\ttasks: [\n\t\t\t{\n\t\t\t\tagent: params.agent,\n\t\t\t\tdescription: params.description,\n\t\t\t\tprompt: params.prompt!,\n\t\t\t\tcwd: params.cwd,\n\t\t\t},\n\t\t],\n\t};\n}\n\n// Cheap change detector: consecutive events that alter nothing user-visible\n// skip the bounded-details serialization in emitDetails entirely. Every\n// activity contributes its status, not just the last one: agent-core can end\n// parallel tool executions out of order, and a mid-list row settling then\n// would otherwise slip past the detector.\nexport function progressKey(runs: readonly SubagentRunDetails[]): string {\n\treturn runs\n\t\t.map((run) => {\n\t\t\treturn [\n\t\t\t\trun.status,\n\t\t\t\trun.currentActivity ?? \"\",\n\t\t\t\trun.activities.length,\n\t\t\t\trun.activities.map((activity) => `${activity.status}:${activity.resultSummary ?? \"\"}`).join(\",\"),\n\t\t\t\trun.retry?.attempt ?? \"\",\n\t\t\t\trun.retry?.maxAttempts ?? \"\",\n\t\t\t\trun.retry?.deadline ?? \"\",\n\t\t\t\trun.retry?.error ?? \"\",\n\t\t\t\trun.liveText.length,\n\t\t\t\trun.liveText.slice(-24),\n\t\t\t\trun.finalOutput.length,\n\t\t\t\trun.usage.turns,\n\t\t\t\trun.usage.toolUses,\n\t\t\t\trun.usage.totalTokens,\n\t\t\t\trun.error ?? \"\",\n\t\t\t].join(\"|\");\n\t\t})\n\t\t.join(\"~\");\n}\n\nexport function isSubagentError(details: Pick<SubagentDetails, \"status\" | \"runs\">): boolean {\n\tif (details.status !== \"failed\" && details.status !== \"aborted\") return false;\n\t// A batch with any successful run is a partial result, not an error:\n\t// per-run status is already reported in the content sections.\n\treturn !details.runs.some((run) => run.status === \"completed\");\n}\n\nexport async function runSubagentInvocation(options: SubagentInvocationOptions): Promise<SubagentExecutionResult> {\n\tconst { mode, tasks } = invocationMode(options.params);\n\tconst resolved = await resolveTasks(tasks, options);\n\tconst runs = resolved.map((task, index) => createRun(task, index, options.parentCwd));\n\tconst startedAt = Date.now();\n\tlet latestDetails = emitDetails(mode, runs, startedAt, options.onUpdate);\n\tlet lastProgressKey = progressKey(runs);\n\tconst progress = () => {\n\t\tconst key = progressKey(runs);\n\t\tif (key === lastProgressKey) return;\n\t\tlastProgressKey = key;\n\t\tlatestDetails = emitDetails(mode, runs, startedAt, options.onUpdate);\n\t};\n\n\tif (mode === \"single\") {\n\t\tawait runWithGate(resolved[0]!, runs[0]!, options, progress);\n\t} else {\n\t\tawait Promise.all(resolved.map((task, index) => runWithGate(task, runs[index]!, options, progress)));\n\t}\n\tlatestDetails = emitDetails(mode, runs, startedAt, undefined);\n\tlatestDetails.endedAt = Date.now();\n\t// Error classification lives in the tool_result handler (index.ts), the\n\t// only channel that reaches the session transcript and export.\n\treturn {\n\t\tcontent: resultContent(latestDetails),\n\t\tdetails: boundSubagentDetails(latestDetails),\n\t\tusage: toNestedUsage(latestDetails.usage),\n\t};\n}\n\nexport function statusSummary(details: SubagentDetails): string {\n\treturn statusText(details);\n}\n"]}
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../../src/extensions/subagent/runner.ts"],"names":[],"mappings":"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","sourcesContent":["import { relative } from \"node:path\";\nimport { isRetryableAssistantError } from \"@earendil-works/pi-ai/compat\";\nimport type { ModelRuntime } from \"../../core/model-runtime.ts\";\nimport { sleep } from \"../../utils/sleep.ts\";\nimport { boundText, emptyUsage, mergeUsage, toNestedUsage } from \"./activity.ts\";\nimport {\n\tDETAILS_ACTIVITY_LIMIT,\n\tDETAILS_OUTPUT_LIMIT,\n\tERROR_TEXT_LIMIT,\n\tMAX_CONCURRENCY,\n\tMAX_TASKS,\n\tRETRY_ERROR_TEXT_LIMIT,\n\tTASK_OUTPUT_LIMIT,\n\tTASK_RETRY_BASE_DELAY_MS,\n\tTASK_RETRY_LIMIT,\n\tTOTAL_OUTPUT_LIMIT,\n} from \"./constants.ts\";\nimport { type ParentModelContext, resolveSubagentTask } from \"./resolve.ts\";\nimport { beginSubagentRetry, clearSubagentRetry } from \"./retry.ts\";\nimport type { SubagentParams, SubagentTask } from \"./schema.ts\";\nimport { runSdkTask } from \"./sdk-runner.ts\";\nimport { loadSubagentConfig } from \"./settings.ts\";\nimport type {\n\tResolvedSubagentTask,\n\tSubagentDetails,\n\tSubagentExecutionResult,\n\tSubagentRunDetails,\n\tSubagentUsage,\n} from \"./types.ts\";\n\nconst EMPTY_OUTPUT = \"(Subagent completed but returned no output.)\";\n\ninterface Waiter {\n\tresolve: (release: () => void) => void;\n\treject: (error: Error) => void;\n\tsignal?: AbortSignal;\n\tabortListener?: () => void;\n}\n\nexport class ConcurrencyGate {\n\tprivate active = 0;\n\tprivate readonly waiters: Waiter[] = [];\n\tprivate readonly limit: number;\n\n\tconstructor(limit = MAX_CONCURRENCY) {\n\t\tthis.limit = limit;\n\t}\n\n\tacquire(signal?: AbortSignal): Promise<() => void> {\n\t\tif (signal?.aborted) return Promise.reject(new Error(\"Subagent was aborted while queued.\"));\n\t\tif (this.active < this.limit) {\n\t\t\tthis.active++;\n\t\t\treturn Promise.resolve(() => this.release());\n\t\t}\n\t\treturn new Promise<() => void>((resolve, reject) => {\n\t\t\tconst waiter: Waiter = { resolve, reject, signal };\n\t\t\tif (signal) {\n\t\t\t\twaiter.abortListener = () => {\n\t\t\t\t\tconst index = this.waiters.indexOf(waiter);\n\t\t\t\t\tif (index >= 0) this.waiters.splice(index, 1);\n\t\t\t\t\treject(new Error(\"Subagent was aborted while queued.\"));\n\t\t\t\t};\n\t\t\t\tsignal.addEventListener(\"abort\", waiter.abortListener, { once: true });\n\t\t\t}\n\t\t\tthis.waiters.push(waiter);\n\t\t});\n\t}\n\n\tprivate release(): void {\n\t\tthis.active = Math.max(0, this.active - 1);\n\t\twhile (this.waiters.length > 0) {\n\t\t\tconst waiter = this.waiters.shift()!;\n\t\t\tif (waiter.signal?.aborted) {\n\t\t\t\twaiter.abortListener?.();\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\twaiter.signal?.removeEventListener(\"abort\", waiter.abortListener!);\n\t\t\tthis.active++;\n\t\t\twaiter.resolve(() => this.release());\n\t\t\treturn;\n\t\t}\n\t}\n}\n\nexport interface SubagentInvocationOptions {\n\tparams: SubagentParams;\n\tparentCwd: string;\n\tparent: ParentModelContext;\n\tmodelRuntime: ModelRuntime;\n\tagentDir: string;\n\tprojectTrusted: boolean;\n\tsignal?: AbortSignal;\n\tgate: ConcurrencyGate;\n\tonUpdate?: (details: SubagentDetails) => void;\n\tregisterAbort?: (abort: () => Promise<void>) => () => void;\n\t/** Test hook: overrides the task-retry backoff base delay. */\n\ttaskRetryBaseDelayMs?: number;\n}\n\nfunction runId(index: number): string {\n\treturn `subagent-${index + 1}`;\n}\n\nfunction createRun(task: ResolvedSubagentTask, index: number, parentCwd: string): SubagentRunDetails {\n\treturn {\n\t\tid: runId(index),\n\t\tagent: task.agent.name,\n\t\tdescription: task.description,\n\t\t// Display-only relative path; the worker session itself uses the\n\t\t// resolved absolute task.cwd. Empty means \"same as the parent\".\n\t\tcwd: relative(parentCwd, task.cwd),\n\t\tmodel: `${task.model.provider}/${task.model.id}`,\n\t\tthinking: task.thinking,\n\t\tstatus: \"queued\",\n\t\tactivities: [],\n\t\treport: \"\",\n\t\tusage: emptyUsage(),\n\t};\n}\n\nfunction aggregateUsage(runs: readonly SubagentRunDetails[]): SubagentUsage {\n\tconst usage = emptyUsage();\n\tfor (const run of runs) mergeUsage(usage, run.usage);\n\treturn usage;\n}\n\ninterface TextField {\n\tget: () => string;\n\tset: (value: string) => void;\n}\n\nfunction detailsSize(details: SubagentDetails): number {\n\treturn Buffer.byteLength(JSON.stringify(details), \"utf8\");\n}\n\nexport function boundSubagentDetails(details: SubagentDetails): SubagentDetails {\n\tconst perRunBudget = Math.max(\n\t\t1_024,\n\t\tMath.floor((DETAILS_OUTPUT_LIMIT - 8 * 1024) / Math.max(1, details.runs.length)),\n\t);\n\tconst reportLimit = Math.min(TASK_OUTPUT_LIMIT, Math.max(1_024, perRunBudget - 7 * 1024));\n\tconst bounded: SubagentDetails = {\n\t\t...details,\n\t\truns: details.runs.map((run) => ({\n\t\t\t...run,\n\t\t\tcwd: boundText(run.cwd, 1_024),\n\t\t\tcurrentActivity: run.currentActivity ? boundText(run.currentActivity, 512) : undefined,\n\t\t\tretry: run.retry ? { ...run.retry, error: boundText(run.retry.error, RETRY_ERROR_TEXT_LIMIT) } : undefined,\n\t\t\tactivities: run.activities.slice(-DETAILS_ACTIVITY_LIMIT).map((activity) => ({\n\t\t\t\t...activity,\n\t\t\t\tsummary: boundText(activity.summary, 256),\n\t\t\t\tresultSummary: activity.resultSummary ? boundText(activity.resultSummary, 256) : undefined,\n\t\t\t})),\n\t\t\treport: boundText(run.report, reportLimit),\n\t\t\terror: run.error ? boundText(run.error, 1_024) : undefined,\n\t\t})),\n\t};\n\tconst fields: TextField[] = [];\n\tfor (const run of bounded.runs) {\n\t\tfields.push(\n\t\t\t{\n\t\t\t\tget: () => run.cwd,\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.cwd = value;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tget: () => run.currentActivity ?? \"\",\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.currentActivity = value || undefined;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tget: () => run.report,\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.report = value;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tget: () => run.error ?? \"\",\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.error = value || undefined;\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t\tfor (const activity of run.activities) {\n\t\t\tfields.push(\n\t\t\t\t{\n\t\t\t\t\tget: () => activity.summary,\n\t\t\t\t\tset: (value) => {\n\t\t\t\t\t\tactivity.summary = value;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tget: () => activity.resultSummary ?? \"\",\n\t\t\t\t\tset: (value) => {\n\t\t\t\t\t\tactivity.resultSummary = value || undefined;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t}\n\twhile (detailsSize(bounded) > DETAILS_OUTPUT_LIMIT) {\n\t\tconst largest = fields\n\t\t\t.map((field) => ({ field, size: Buffer.byteLength(field.get(), \"utf8\") }))\n\t\t\t.sort((left, right) => right.size - left.size)[0];\n\t\tif (!largest || largest.size === 0) break;\n\t\tconst overflow = detailsSize(bounded) - DETAILS_OUTPUT_LIMIT;\n\t\tlargest.field.set(boundText(largest.field.get(), Math.max(0, largest.size - overflow)));\n\t}\n\treturn bounded;\n}\n\nfunction statusOf(runs: readonly SubagentRunDetails[]): SubagentDetails[\"status\"] {\n\tif (runs.length === 0) return \"running\";\n\t// Active beats terminal: any queued or running run keeps the batch\n\t// \"running\" regardless of what the others have settled to.\n\tif (runs.some((run) => run.status === \"queued\" || run.status === \"running\")) return \"running\";\n\tif (runs.every((run) => run.status === \"completed\")) return \"completed\";\n\tif (runs.some((run) => run.status === \"completed\")) return \"partial\";\n\tif (runs.every((run) => run.status === \"aborted\")) return \"aborted\";\n\treturn \"failed\";\n}\n\nfunction statusText(details: SubagentDetails): string {\n\tif (details.runs.length === 0) return \"Initializing…\";\n\tconst running = details.runs.filter((run) => run.status === \"running\").length;\n\tconst queued = details.runs.filter((run) => run.status === \"queued\").length;\n\tconst completed = details.runs.filter((run) => run.status === \"completed\").length;\n\tconst failed = details.runs.filter((run) => run.status === \"failed\").length;\n\tconst aborted = details.runs.filter((run) => run.status === \"aborted\").length;\n\tconst parts = [`${completed}/${details.runs.length} complete`];\n\tif (running) parts.push(`${running} running`);\n\tif (queued) parts.push(`${queued} queued`);\n\tif (failed) parts.push(`${failed} failed`);\n\tif (aborted) parts.push(`${aborted} aborted`);\n\treturn parts.join(\" · \");\n}\n\nfunction emitDetails(\n\truns: SubagentRunDetails[],\n\tstartedAt: number,\n\tonUpdate: ((details: SubagentDetails) => void) | undefined,\n): SubagentDetails {\n\tconst details: SubagentDetails = {\n\t\tstatus: statusOf(runs),\n\t\truns: [...runs],\n\t\tstartedAt,\n\t\tusage: aggregateUsage(runs),\n\t};\n\tonUpdate?.(boundSubagentDetails(details));\n\treturn details;\n}\n\nfunction validateTaskCount(tasks: readonly SubagentTask[]): void {\n\tif (tasks.length === 0) throw new Error(\"Subagent task list must not be empty.\");\n\tif (tasks.length > MAX_TASKS) throw new Error(`Subagent task list is limited to ${MAX_TASKS} tasks.`);\n}\n\nasync function resolveTasks(\n\ttasks: readonly SubagentTask[],\n\toptions: SubagentInvocationOptions,\n): Promise<ResolvedSubagentTask[]> {\n\tvalidateTaskCount(tasks);\n\t// One config load and one resolution pass for the whole batch: every\n\t// task/profile/cwd/model is settled before any run is created or any\n\t// worker starts, so a failing task cannot strand half-initialized runs.\n\tconst config = await loadSubagentConfig(options.agentDir);\n\treturn Promise.all(\n\t\ttasks.map((task, index) =>\n\t\t\tresolveSubagentTask(task, options.parentCwd, options.parent, options.agentDir, config).catch((error) => {\n\t\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\t\tthrow new Error(`Subagent task tasks[${index}] failed to resolve: ${message}`);\n\t\t\t}),\n\t\t),\n\t);\n}\n\n// Reuses pi-ai's provider-error classification by wrapping the stored error\n// text in the assistant-message shape it inspects.\nfunction isRetryableRunError(error: string | undefined): boolean {\n\tif (!error) return false;\n\tconst probe = { role: \"assistant\", content: [], stopReason: \"error\", errorMessage: error };\n\treturn isRetryableAssistantError(probe as unknown as Parameters<typeof isRetryableAssistantError>[0]);\n}\n\n// Session-level auto-retry already covers errors that happen inside the agent\n// loop; this catches the paths that bypass it (preflight throws such as auth\n// checks). Only a run that produced nothing is retried, so partial work is\n// never discarded.\nfunction shouldRetryTask(run: SubagentRunDetails): boolean {\n\treturn (\n\t\trun.status === \"failed\" && run.usage.turns === 0 && run.usage.toolUses === 0 && isRetryableRunError(run.error)\n\t);\n}\n\nfunction resetRunForRetry(run: SubagentRunDetails, attempt: number, maxAttempts: number, delayMs: number): void {\n\tconst error = run.error ?? \"Subagent failed before retry.\";\n\trun.status = \"queued\";\n\trun.error = undefined;\n\trun.startedAt = undefined;\n\trun.endedAt = undefined;\n\trun.report = \"\";\n\trun.activities.length = 0;\n\trun.usage = emptyUsage();\n\tbeginSubagentRetry(run, { attempt, maxAttempts, delayMs, error });\n}\n\nasync function waitForTaskRetry(\n\tdelayMs: number,\n\toptions: Pick<SubagentInvocationOptions, \"signal\" | \"registerAbort\">,\n): Promise<void> {\n\tconst controller = new AbortController();\n\tconst abort = async (): Promise<void> => controller.abort();\n\tconst unregisterAbort = options.registerAbort?.(abort);\n\tconst abortListener = () => controller.abort();\n\tif (options.signal?.aborted) controller.abort();\n\telse options.signal?.addEventListener(\"abort\", abortListener, { once: true });\n\ttry {\n\t\tawait sleep(delayMs, controller.signal);\n\t} finally {\n\t\toptions.signal?.removeEventListener(\"abort\", abortListener);\n\t\tunregisterAbort?.();\n\t}\n}\n\n// The gate slot is held only while a worker session actually runs. Backoff\n// waits outside the slot (release, sleep, reacquire) so a retrying task\n// cannot starve queued tasks, and aborting during the wait settles the run\n// without occupying the gate.\nasync function runWithGate(\n\ttask: ResolvedSubagentTask,\n\trun: SubagentRunDetails,\n\toptions: SubagentInvocationOptions,\n\tonProgress: () => void,\n): Promise<SubagentRunDetails> {\n\tonProgress();\n\tconst baseDelayMs = options.taskRetryBaseDelayMs ?? TASK_RETRY_BASE_DELAY_MS;\n\tfor (let attempt = 0; ; attempt++) {\n\t\tclearSubagentRetry(run);\n\t\tlet release: (() => void) | undefined;\n\t\tlet delayMs = 0;\n\t\ttry {\n\t\t\trelease = await options.gate.acquire(options.signal);\n\t\t\tif (options.signal?.aborted) {\n\t\t\t\trun.status = \"aborted\";\n\t\t\t\trun.error = \"Subagent was aborted while queued.\";\n\t\t\t\trun.endedAt = Date.now();\n\t\t\t\treturn run;\n\t\t\t}\n\t\t\tconst result = await runSdkTask({\n\t\t\t\ttask,\n\t\t\t\trun,\n\t\t\t\tmodelRuntime: options.modelRuntime,\n\t\t\t\tagentDir: options.agentDir,\n\t\t\t\tprojectTrusted: options.projectTrusted,\n\t\t\t\tsignal: options.signal,\n\t\t\t\tonProgress,\n\t\t\t\tregisterAbort: options.registerAbort,\n\t\t\t});\n\t\t\tif (attempt >= TASK_RETRY_LIMIT || options.signal?.aborted || !shouldRetryTask(result)) return result;\n\t\t\tdelayMs = baseDelayMs * 2 ** attempt;\n\t\t\tresetRunForRetry(run, attempt + 1, TASK_RETRY_LIMIT, delayMs);\n\t\t\tonProgress();\n\t\t} catch (error) {\n\t\t\tclearSubagentRetry(run);\n\t\t\trun.status = options.signal?.aborted ? \"aborted\" : \"failed\";\n\t\t\trun.error = boundText(error instanceof Error ? error.message : String(error), ERROR_TEXT_LIMIT);\n\t\t\trun.endedAt = Date.now();\n\t\t\tonProgress();\n\t\t\treturn run;\n\t\t} finally {\n\t\t\trelease?.();\n\t\t}\n\t\ttry {\n\t\t\tawait waitForTaskRetry(delayMs, options);\n\t\t} catch {\n\t\t\tclearSubagentRetry(run);\n\t\t\trun.status = \"aborted\";\n\t\t\trun.error = \"Subagent was aborted while waiting to retry.\";\n\t\t\trun.endedAt = Date.now();\n\t\t\tonProgress();\n\t\t\treturn run;\n\t\t}\n\t}\n}\n\n// Fair per-task report budget: the total cap is split evenly after reserving\n// room for the numbered section headings and separators, capped per task.\nfunction perTaskReportBudget(taskCount: number): number {\n\tconst headingReserve = Math.min(256 * taskCount, Math.floor(TOTAL_OUTPUT_LIMIT / 4));\n\tconst fairShare = Math.floor((TOTAL_OUTPUT_LIMIT - headingReserve) / Math.max(1, taskCount));\n\treturn Math.min(TASK_OUTPUT_LIMIT, Math.max(2_048, fairShare));\n}\n\nfunction reportSectionTitle(run: SubagentRunDetails, index: number): string {\n\treturn `### ${index + 1}. ${run.description} (${run.agent}) — ${run.status}`;\n}\n\nfunction reportSectionBody(run: SubagentRunDetails): string {\n\tif (run.status === \"completed\") return run.report || EMPTY_OUTPUT;\n\tif (run.status === \"failed\" || run.status === \"aborted\") {\n\t\tconst verdict = run.status === \"aborted\" ? \"Subagent aborted\" : \"Subagent failed\";\n\t\tconst cause = run.error ? `: ${run.error}` : \".\";\n\t\tconst partial = run.report ? `\\n\\nPartial report:\\n${run.report}` : \"\";\n\t\treturn `${verdict}${cause}${partial}`;\n\t}\n\tif (run.status === \"queued\") return \"Task was queued and never started.\";\n\treturn \"Task was still running when the batch settled.\";\n}\n\n// Always ordered numbered sections, even for a single task, so the parent\n// can reference results by number. Total cap with a fair per-task budget;\n// empty, failed, aborted, and partial reports are labeled explicitly.\nfunction resultContent(details: SubagentDetails): string {\n\tconst perTaskBudget = perTaskReportBudget(details.runs.length);\n\tconst sections = details.runs.map((run, index) => {\n\t\treturn `${reportSectionTitle(run, index)}\\n\\n${boundText(reportSectionBody(run), perTaskBudget)}`;\n\t});\n\treturn boundText(sections.join(\"\\n\\n---\\n\\n\"), TOTAL_OUTPUT_LIMIT);\n}\n\n// Cheap change detector: consecutive events that alter nothing user-visible\n// skip the bounded-details serialization in emitDetails entirely. Every\n// activity contributes its status, not just the last one: agent-core can end\n// parallel tool executions out of order, and a mid-list row settling then\n// would otherwise slip past the detector.\nexport function progressKey(runs: readonly SubagentRunDetails[]): string {\n\treturn runs\n\t\t.map((run) => {\n\t\t\treturn [\n\t\t\t\trun.status,\n\t\t\t\trun.currentActivity ?? \"\",\n\t\t\t\trun.activities.length,\n\t\t\t\trun.activities.map((activity) => `${activity.status}:${activity.resultSummary ?? \"\"}`).join(\",\"),\n\t\t\t\trun.retry?.attempt ?? \"\",\n\t\t\t\trun.retry?.maxAttempts ?? \"\",\n\t\t\t\trun.retry?.deadline ?? \"\",\n\t\t\t\trun.retry?.error ?? \"\",\n\t\t\t\trun.report.length,\n\t\t\t\trun.usage.turns,\n\t\t\t\trun.usage.toolUses,\n\t\t\t\trun.usage.totalTokens,\n\t\t\t\trun.error ?? \"\",\n\t\t\t].join(\"|\");\n\t\t})\n\t\t.join(\"~\");\n}\n\nexport function isSubagentError(details: Pick<SubagentDetails, \"status\" | \"runs\">): boolean {\n\tif (details.status !== \"failed\" && details.status !== \"aborted\") return false;\n\t// A batch with any successful run is a partial result, not an error:\n\t// per-run status is already reported in the content sections.\n\treturn !details.runs.some((run) => run.status === \"completed\");\n}\n\nexport async function runSubagentInvocation(options: SubagentInvocationOptions): Promise<SubagentExecutionResult> {\n\t// Defensive count check: the schema already enforces 1..MAX_TASKS, but\n\t// strict providers can bypass minItems, so validate before any work.\n\tconst tasks = options.params.tasks ?? [];\n\tconst resolved = await resolveTasks(tasks, options);\n\tconst runs = resolved.map((task, index) => createRun(task, index, options.parentCwd));\n\tconst startedAt = Date.now();\n\tlet latestDetails = emitDetails(runs, startedAt, options.onUpdate);\n\tlet lastProgressKey = progressKey(runs);\n\tconst progress = () => {\n\t\tconst key = progressKey(runs);\n\t\tif (key === lastProgressKey) return;\n\t\tlastProgressKey = key;\n\t\tlatestDetails = emitDetails(runs, startedAt, options.onUpdate);\n\t};\n\n\t// Every task runs concurrently through the shared gate; Promise.all keeps\n\t// result order identical to input order. There is no single-task branch:\n\t// one task is just a batch of one.\n\tawait Promise.all(resolved.map((task, index) => runWithGate(task, runs[index]!, options, progress)));\n\tlatestDetails = emitDetails(runs, startedAt, undefined);\n\tlatestDetails.endedAt = Date.now();\n\t// Error classification lives in the tool_result handler (index.ts), the\n\t// only channel that reaches the session transcript and export.\n\treturn {\n\t\tcontent: resultContent(latestDetails),\n\t\tdetails: boundSubagentDetails(latestDetails),\n\t\tusage: toNestedUsage(latestDetails.usage),\n\t};\n}\n\nexport function statusSummary(details: SubagentDetails): string {\n\treturn statusText(details);\n}\n"]}
@@ -1,21 +1,15 @@
1
1
  import { type Static, Type } from "typebox";
2
2
  export declare const TaskSchema: Type.TObject<{
3
- agent: Type.TOptional<Type.TUnion<[Type.TString, Type.TNull]>>;
4
- description: Type.TString;
3
+ agent: Type.TOptional<Type.TUnion<[Type.TUnsafe<"explorer" | "general">, Type.TNull]>>;
5
4
  prompt: Type.TString;
6
5
  cwd: Type.TOptional<Type.TUnion<[Type.TString, Type.TNull]>>;
7
6
  }>;
8
7
  export declare const SubagentParamsSchema: Type.TObject<{
9
- agent: Type.TOptional<Type.TUnion<[Type.TString, Type.TNull]>>;
10
- description: Type.TOptional<Type.TUnion<[Type.TString, Type.TNull]>>;
11
- prompt: Type.TOptional<Type.TUnion<[Type.TString, Type.TNull]>>;
12
- cwd: Type.TOptional<Type.TUnion<[Type.TString, Type.TNull]>>;
13
- tasks: Type.TOptional<Type.TUnion<[Type.TArray<Type.TObject<{
14
- agent: Type.TOptional<Type.TUnion<[Type.TString, Type.TNull]>>;
15
- description: Type.TString;
8
+ tasks: Type.TArray<Type.TObject<{
9
+ agent: Type.TOptional<Type.TUnion<[Type.TUnsafe<"explorer" | "general">, Type.TNull]>>;
16
10
  prompt: Type.TString;
17
11
  cwd: Type.TOptional<Type.TUnion<[Type.TString, Type.TNull]>>;
18
- }>>, Type.TNull]>>;
12
+ }>>;
19
13
  }>;
20
14
  export type SubagentParams = Static<typeof SubagentParamsSchema>;
21
15
  export type SubagentTask = Static<typeof TaskSchema>;
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/extensions/subagent/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAgB,IAAI,EAAE,MAAM,SAAS,CAAC;AAY1D,eAAO,MAAM,UAAU;;;;;EAsBtB,CAAC;AAEF,eAAO,MAAM,oBAAoB;;;;;;;;;;;EAwBhC,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,oBAAoB,CAAC,CAAC;AACjE,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/extensions/subagent/schema.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,MAAM,EAAgB,IAAI,EAAE,MAAM,SAAS,CAAC;AAW1D,eAAO,MAAM,UAAU;;;;EAiBtB,CAAC;AAEF,eAAO,MAAM,oBAAoB;;;;;;EAShC,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,oBAAoB,CAAC,CAAC;AACjE,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC"}
@@ -1,20 +1,15 @@
1
+ import { StringEnum } from "@earendil-works/pi-ai";
1
2
  import { Type } from "typebox";
2
- import { MAX_TASKS } from "./constants.js";
3
+ import { MAX_CONCURRENCY, MAX_TASKS, SUBAGENT_AGENT_NAMES } from "./constants.js";
3
4
  // Strict constrained-sampling providers treat every property as required
4
5
  // and reject bare unions at the top level, so the schema is a flat
5
6
  // `type: "object"` whose optional fields are also nullable: callers omit
6
7
  // a field when the grammar allows it and send null when it does not.
7
- // The exactly-one-mode rule is enforced at runtime in `invocationMode`.
8
8
  function nullable(schema, description) {
9
9
  return Type.Optional(Type.Union([schema, Type.Null()], { description }));
10
10
  }
11
11
  export const TaskSchema = Type.Object({
12
- agent: nullable(Type.String({ minLength: 1, maxLength: 80 }), "Agent profile from the list in the tool description; null or omit for general"),
13
- description: Type.String({
14
- minLength: 1,
15
- maxLength: 80,
16
- description: "Concise 3-8 word UI label",
17
- }),
12
+ agent: nullable(StringEnum(SUBAGENT_AGENT_NAMES, { description: "Which built-in profile runs this task" }), "Built-in profile; null or omit for explorer (the default)"),
18
13
  prompt: Type.String({
19
14
  minLength: 1,
20
15
  maxLength: 50_000,
@@ -23,10 +18,10 @@ export const TaskSchema = Type.Object({
23
18
  cwd: nullable(Type.String({ minLength: 1, maxLength: 4_096 }), "Relative or absolute directory inside the parent working directory; null or omit to inherit it"),
24
19
  }, { additionalProperties: false });
25
20
  export const SubagentParamsSchema = Type.Object({
26
- agent: nullable(Type.String({ minLength: 1, maxLength: 80 }), "Agent profile from the list in the tool description (single mode); null or omit otherwise (defaults to general)"),
27
- description: nullable(Type.String({ minLength: 1, maxLength: 80 }), "Concise 3-8 word UI label; required for single mode, null or omit otherwise"),
28
- prompt: nullable(Type.String({ minLength: 1, maxLength: 50_000 }), "Complete self-contained briefing; providing it selects single mode — null or omit when using tasks"),
29
- cwd: nullable(Type.String({ minLength: 1, maxLength: 4_096 }), "Relative or absolute directory inside the parent working directory (single mode); null or omit otherwise"),
30
- tasks: nullable(Type.Array(TaskSchema, { minItems: 1, maxItems: MAX_TASKS }), "Independent tasks run concurrently; providing it selects parallel mode — null or omit when using prompt"),
21
+ tasks: Type.Array(TaskSchema, {
22
+ minItems: 1,
23
+ maxItems: MAX_TASKS,
24
+ description: `Independent tasks run concurrently: at most ${MAX_CONCURRENCY} active at once, excess tasks queue, and results preserve input order`,
25
+ }),
31
26
  }, { additionalProperties: false });
32
27
  //# sourceMappingURL=schema.js.map