@astralyn/pi 0.84.4 → 0.84.6

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 (263) hide show
  1. package/CHANGELOG.md +57 -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/core/agent-session.d.ts +6 -1
  10. package/dist/core/agent-session.d.ts.map +1 -1
  11. package/dist/core/agent-session.js +11 -6
  12. package/dist/core/agent-session.js.map +1 -1
  13. package/dist/core/experimental.d.ts +4 -0
  14. package/dist/core/experimental.d.ts.map +1 -1
  15. package/dist/core/experimental.js +4 -0
  16. package/dist/core/experimental.js.map +1 -1
  17. package/dist/core/extensions/index.d.ts +1 -1
  18. package/dist/core/extensions/index.d.ts.map +1 -1
  19. package/dist/core/extensions/index.js.map +1 -1
  20. package/dist/core/extensions/runner.d.ts +1 -0
  21. package/dist/core/extensions/runner.d.ts.map +1 -1
  22. package/dist/core/extensions/runner.js +10 -0
  23. package/dist/core/extensions/runner.js.map +1 -1
  24. package/dist/core/extensions/types.d.ts +19 -1
  25. package/dist/core/extensions/types.d.ts.map +1 -1
  26. package/dist/core/extensions/types.js.map +1 -1
  27. package/dist/core/keybindings.d.ts +29 -0
  28. package/dist/core/keybindings.d.ts.map +1 -1
  29. package/dist/core/keybindings.js +4 -0
  30. package/dist/core/keybindings.js.map +1 -1
  31. package/dist/core/model-config.d.ts +5 -0
  32. package/dist/core/model-config.d.ts.map +1 -1
  33. package/dist/core/model-config.js +1 -0
  34. package/dist/core/model-config.js.map +1 -1
  35. package/dist/core/model-registry.d.ts +2 -0
  36. package/dist/core/model-registry.d.ts.map +1 -1
  37. package/dist/core/model-registry.js +4 -0
  38. package/dist/core/model-registry.js.map +1 -1
  39. package/dist/core/project-trust.js +2 -2
  40. package/dist/core/project-trust.js.map +1 -1
  41. package/dist/core/sdk.d.ts +5 -3
  42. package/dist/core/sdk.d.ts.map +1 -1
  43. package/dist/core/sdk.js +2 -1
  44. package/dist/core/sdk.js.map +1 -1
  45. package/dist/core/session-manager.js +2 -2
  46. package/dist/core/session-manager.js.map +1 -1
  47. package/dist/core/settings-manager.d.ts +6 -0
  48. package/dist/core/settings-manager.d.ts.map +1 -1
  49. package/dist/core/settings-manager.js +12 -0
  50. package/dist/core/settings-manager.js.map +1 -1
  51. package/dist/core/system-prompt.js +1 -1
  52. package/dist/core/system-prompt.js.map +1 -1
  53. package/dist/core/tools/bash.d.ts +7 -1
  54. package/dist/core/tools/bash.d.ts.map +1 -1
  55. package/dist/core/tools/bash.js +4 -2
  56. package/dist/core/tools/bash.js.map +1 -1
  57. package/dist/core/tools/edit.d.ts.map +1 -1
  58. package/dist/core/tools/edit.js +2 -0
  59. package/dist/core/tools/edit.js.map +1 -1
  60. package/dist/core/tools/find.js +1 -1
  61. package/dist/core/tools/find.js.map +1 -1
  62. package/dist/core/tools/grep.js +1 -1
  63. package/dist/core/tools/grep.js.map +1 -1
  64. package/dist/core/tools/read.d.ts.map +1 -1
  65. package/dist/core/tools/read.js +2 -0
  66. package/dist/core/tools/read.js.map +1 -1
  67. package/dist/core/tools/write.d.ts.map +1 -1
  68. package/dist/core/tools/write.js +2 -0
  69. package/dist/core/tools/write.js.map +1 -1
  70. package/dist/extensions/background/index.d.ts +149 -0
  71. package/dist/extensions/background/index.d.ts.map +1 -0
  72. package/dist/extensions/background/index.js +666 -0
  73. package/dist/extensions/background/index.js.map +1 -0
  74. package/dist/extensions/background/manager.d.ts +95 -0
  75. package/dist/extensions/background/manager.d.ts.map +1 -0
  76. package/dist/extensions/background/manager.js +421 -0
  77. package/dist/extensions/background/manager.js.map +1 -0
  78. package/dist/extensions/background/registry.d.ts +220 -0
  79. package/dist/extensions/background/registry.d.ts.map +1 -0
  80. package/dist/extensions/background/registry.js +589 -0
  81. package/dist/extensions/background/registry.js.map +1 -0
  82. package/dist/extensions/background/render.d.ts +50 -0
  83. package/dist/extensions/background/render.d.ts.map +1 -0
  84. package/dist/extensions/background/render.js +260 -0
  85. package/dist/extensions/background/render.js.map +1 -0
  86. package/dist/extensions/index.d.ts.map +1 -1
  87. package/dist/extensions/index.js +2 -0
  88. package/dist/extensions/index.js.map +1 -1
  89. package/dist/extensions/subagent/activity.d.ts +3 -6
  90. package/dist/extensions/subagent/activity.d.ts.map +1 -1
  91. package/dist/extensions/subagent/activity.js +9 -93
  92. package/dist/extensions/subagent/activity.js.map +1 -1
  93. package/dist/extensions/subagent/agents-command.d.ts.map +1 -1
  94. package/dist/extensions/subagent/agents-command.js +270 -169
  95. package/dist/extensions/subagent/agents-command.js.map +1 -1
  96. package/dist/extensions/subagent/agents.d.ts +5 -6
  97. package/dist/extensions/subagent/agents.d.ts.map +1 -1
  98. package/dist/extensions/subagent/agents.js +28 -192
  99. package/dist/extensions/subagent/agents.js.map +1 -1
  100. package/dist/extensions/subagent/budget.d.ts +15 -0
  101. package/dist/extensions/subagent/budget.d.ts.map +1 -0
  102. package/dist/extensions/subagent/budget.js +96 -0
  103. package/dist/extensions/subagent/budget.js.map +1 -0
  104. package/dist/extensions/subagent/cancellation.d.ts +29 -0
  105. package/dist/extensions/subagent/cancellation.d.ts.map +1 -0
  106. package/dist/extensions/subagent/cancellation.js +73 -0
  107. package/dist/extensions/subagent/cancellation.js.map +1 -0
  108. package/dist/extensions/subagent/constants.d.ts +4 -5
  109. package/dist/extensions/subagent/constants.d.ts.map +1 -1
  110. package/dist/extensions/subagent/constants.js +11 -7
  111. package/dist/extensions/subagent/constants.js.map +1 -1
  112. package/dist/extensions/subagent/index.d.ts +0 -3
  113. package/dist/extensions/subagent/index.d.ts.map +1 -1
  114. package/dist/extensions/subagent/index.js +59 -208
  115. package/dist/extensions/subagent/index.js.map +1 -1
  116. package/dist/extensions/subagent/model-selection.d.ts +16 -0
  117. package/dist/extensions/subagent/model-selection.d.ts.map +1 -0
  118. package/dist/extensions/subagent/model-selection.js +51 -0
  119. package/dist/extensions/subagent/model-selection.js.map +1 -0
  120. package/dist/extensions/subagent/render.d.ts +7 -2
  121. package/dist/extensions/subagent/render.d.ts.map +1 -1
  122. package/dist/extensions/subagent/render.js +219 -576
  123. package/dist/extensions/subagent/render.js.map +1 -1
  124. package/dist/extensions/subagent/resolve.d.ts +2 -2
  125. package/dist/extensions/subagent/resolve.d.ts.map +1 -1
  126. package/dist/extensions/subagent/resolve.js +24 -35
  127. package/dist/extensions/subagent/resolve.js.map +1 -1
  128. package/dist/extensions/subagent/runner.d.ts +4 -6
  129. package/dist/extensions/subagent/runner.d.ts.map +1 -1
  130. package/dist/extensions/subagent/runner.js +101 -316
  131. package/dist/extensions/subagent/runner.js.map +1 -1
  132. package/dist/extensions/subagent/schema.d.ts +4 -10
  133. package/dist/extensions/subagent/schema.d.ts.map +1 -1
  134. package/dist/extensions/subagent/schema.js +8 -13
  135. package/dist/extensions/subagent/schema.js.map +1 -1
  136. package/dist/extensions/subagent/sdk-runner.d.ts +13 -11
  137. package/dist/extensions/subagent/sdk-runner.d.ts.map +1 -1
  138. package/dist/extensions/subagent/sdk-runner.js +169 -161
  139. package/dist/extensions/subagent/sdk-runner.js.map +1 -1
  140. package/dist/extensions/subagent/settings.d.ts +2 -2
  141. package/dist/extensions/subagent/settings.d.ts.map +1 -1
  142. package/dist/extensions/subagent/settings.js +27 -14
  143. package/dist/extensions/subagent/settings.js.map +1 -1
  144. package/dist/extensions/subagent/state.d.ts +89 -0
  145. package/dist/extensions/subagent/state.d.ts.map +1 -0
  146. package/dist/extensions/subagent/state.js +294 -0
  147. package/dist/extensions/subagent/state.js.map +1 -0
  148. package/dist/extensions/subagent/text.d.ts +7 -0
  149. package/dist/extensions/subagent/text.d.ts.map +1 -0
  150. package/dist/extensions/subagent/text.js +91 -0
  151. package/dist/extensions/subagent/text.js.map +1 -0
  152. package/dist/extensions/subagent/types.d.ts +16 -43
  153. package/dist/extensions/subagent/types.d.ts.map +1 -1
  154. package/dist/extensions/subagent/types.js.map +1 -1
  155. package/dist/extensions/subagent/ui/choices.d.ts +36 -0
  156. package/dist/extensions/subagent/ui/choices.d.ts.map +1 -0
  157. package/dist/extensions/subagent/ui/choices.js +54 -0
  158. package/dist/extensions/subagent/ui/choices.js.map +1 -0
  159. package/dist/extensions/subagent/ui/model-list.d.ts +4 -3
  160. package/dist/extensions/subagent/ui/model-list.d.ts.map +1 -1
  161. package/dist/extensions/subagent/ui/model-list.js +20 -22
  162. package/dist/extensions/subagent/ui/model-list.js.map +1 -1
  163. package/dist/index.d.ts +2 -2
  164. package/dist/index.d.ts.map +1 -1
  165. package/dist/index.js.map +1 -1
  166. package/dist/main.d.ts.map +1 -1
  167. package/dist/main.js +5 -1
  168. package/dist/main.js.map +1 -1
  169. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  170. package/dist/modes/interactive/components/model-selector.js +2 -1
  171. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  172. package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
  173. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  174. package/dist/modes/interactive/components/settings-selector.js +10 -0
  175. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  176. package/dist/modes/interactive/interactive-mode.d.ts +8 -2
  177. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  178. package/dist/modes/interactive/interactive-mode.js +77 -25
  179. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  180. package/dist/modes/interactive/model-catalog-refresh.d.ts +7 -0
  181. package/dist/modes/interactive/model-catalog-refresh.d.ts.map +1 -0
  182. package/dist/modes/interactive/model-catalog-refresh.js +36 -0
  183. package/dist/modes/interactive/model-catalog-refresh.js.map +1 -0
  184. package/dist/modes/interactive/theme/dark.json +2 -0
  185. package/dist/modes/interactive/theme/light.json +2 -0
  186. package/dist/modes/interactive/theme/theme-controller.d.ts +10 -2
  187. package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
  188. package/dist/modes/interactive/theme/theme-controller.js +23 -10
  189. package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
  190. package/dist/modes/interactive/theme/theme-schema.json +9 -1
  191. package/dist/modes/interactive/theme/theme.d.ts +5 -3
  192. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  193. package/dist/modes/interactive/theme/theme.js +12 -2
  194. package/dist/modes/interactive/theme/theme.js.map +1 -1
  195. package/dist/modes/json-event.d.ts +4 -1
  196. package/dist/modes/json-event.d.ts.map +1 -1
  197. package/dist/modes/json-event.js +5 -2
  198. package/dist/modes/json-event.js.map +1 -1
  199. package/dist/package-manager-cli.js +1 -1
  200. package/dist/package-manager-cli.js.map +1 -1
  201. package/dist/server/create-harness.d.ts.map +1 -1
  202. package/dist/server/create-harness.js +2 -0
  203. package/dist/server/create-harness.js.map +1 -1
  204. package/dist/utils/tools-manager.d.ts +10 -1
  205. package/dist/utils/tools-manager.d.ts.map +1 -1
  206. package/dist/utils/tools-manager.js +14 -19
  207. package/dist/utils/tools-manager.js.map +1 -1
  208. package/docs/bundled/README.md +1 -0
  209. package/docs/bundled/extensions/background.md +99 -0
  210. package/docs/bundled/extensions/subagent.md +83 -71
  211. package/docs/compaction.md +6 -6
  212. package/docs/custom-provider.md +1 -1
  213. package/docs/docs.json +4 -0
  214. package/docs/environment-variables.md +8 -2
  215. package/docs/extensions.md +19 -2
  216. package/docs/json.md +6 -4
  217. package/docs/keybindings.md +9 -2
  218. package/docs/rpc.md +15 -4
  219. package/docs/sdk.md +9 -0
  220. package/docs/settings.md +31 -0
  221. package/docs/terminal-setup.md +23 -2
  222. package/docs/themes.md +24 -3
  223. package/docs/tui.md +2 -2
  224. package/docs/usage.md +4 -3
  225. package/examples/README.md +1 -1
  226. package/examples/extensions/README.md +0 -1
  227. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  228. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  229. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  230. package/examples/extensions/gondolin/package-lock.json +2 -2
  231. package/examples/extensions/gondolin/package.json +1 -1
  232. package/examples/extensions/sandbox/package-lock.json +2 -2
  233. package/examples/extensions/sandbox/package.json +1 -1
  234. package/examples/extensions/with-deps/package-lock.json +2 -2
  235. package/examples/extensions/with-deps/package.json +1 -1
  236. package/npm-shrinkwrap.json +170 -221
  237. package/package.json +6 -6
  238. package/dist/extensions/subagent/display-name.d.ts +0 -6
  239. package/dist/extensions/subagent/display-name.d.ts.map +0 -1
  240. package/dist/extensions/subagent/display-name.js +0 -13
  241. package/dist/extensions/subagent/display-name.js.map +0 -1
  242. package/dist/extensions/subagent/retry.d.ts +0 -17
  243. package/dist/extensions/subagent/retry.d.ts.map +0 -1
  244. package/dist/extensions/subagent/retry.js +0 -41
  245. package/dist/extensions/subagent/retry.js.map +0 -1
  246. package/dist/extensions/subagent/ui/profile-editor.d.ts +0 -54
  247. package/dist/extensions/subagent/ui/profile-editor.d.ts.map +0 -1
  248. package/dist/extensions/subagent/ui/profile-editor.js +0 -154
  249. package/dist/extensions/subagent/ui/profile-editor.js.map +0 -1
  250. package/dist/extensions/subagent/ui/profile-picker.d.ts +0 -32
  251. package/dist/extensions/subagent/ui/profile-picker.d.ts.map +0 -1
  252. package/dist/extensions/subagent/ui/profile-picker.js +0 -149
  253. package/dist/extensions/subagent/ui/profile-picker.js.map +0 -1
  254. package/examples/extensions/subagent/README.md +0 -175
  255. package/examples/extensions/subagent/agents/planner.md +0 -37
  256. package/examples/extensions/subagent/agents/reviewer.md +0 -35
  257. package/examples/extensions/subagent/agents/scout.md +0 -50
  258. package/examples/extensions/subagent/agents/worker.md +0 -24
  259. package/examples/extensions/subagent/agents.ts +0 -126
  260. package/examples/extensions/subagent/index.ts +0 -1009
  261. package/examples/extensions/subagent/prompts/implement-and-review.md +0 -10
  262. package/examples/extensions/subagent/prompts/implement.md +0 -10
  263. package/examples/extensions/subagent/prompts/scout-and-plan.md +0 -9
@@ -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
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/extensions/subagent/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,IAAI,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,yEAAyE;AACzE,mEAAmE;AACnE,yEAAyE;AACzE,qEAAqE;AACrE,wEAAwE;AACxE,SAAS,QAAQ,CAAoB,MAAS,EAAE,WAAmB;IAClE,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;AAC1E,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CACpC;IACC,KAAK,EAAE,QAAQ,CACd,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,EAC5C,+EAA+E,CAC/E;IACD,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC;QACxB,SAAS,EAAE,CAAC;QACZ,SAAS,EAAE,EAAE;QACb,WAAW,EAAE,2BAA2B;KACxC,CAAC;IACF,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;QACnB,SAAS,EAAE,CAAC;QACZ,SAAS,EAAE,MAAM;QACjB,WAAW,EAAE,iFAAiF;KAC9F,CAAC;IACF,GAAG,EAAE,QAAQ,CACZ,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,EAC/C,gGAAgG,CAChG;CACD,EACD,EAAE,oBAAoB,EAAE,KAAK,EAAE,CAC/B,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,CAAC,MAAM,CAC9C;IACC,KAAK,EAAE,QAAQ,CACd,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,EAC5C,iHAAiH,CACjH;IACD,WAAW,EAAE,QAAQ,CACpB,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,EAC5C,6EAA6E,CAC7E;IACD,MAAM,EAAE,QAAQ,CACf,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,EAChD,oGAAoG,CACpG;IACD,GAAG,EAAE,QAAQ,CACZ,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,EAC/C,0GAA0G,CAC1G;IACD,KAAK,EAAE,QAAQ,CACd,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,EAC5D,yGAAyG,CACzG;CACD,EACD,EAAE,oBAAoB,EAAE,KAAK,EAAE,CAC/B,CAAC","sourcesContent":["import { type Static, type TSchema, Type } from \"typebox\";\nimport { MAX_TASKS } from \"./constants.ts\";\n\n// Strict constrained-sampling providers treat every property as required\n// and reject bare unions at the top level, so the schema is a flat\n// `type: \"object\"` whose optional fields are also nullable: callers omit\n// a field when the grammar allows it and send null when it does not.\n// The exactly-one-mode rule is enforced at runtime in `invocationMode`.\nfunction nullable<T extends TSchema>(schema: T, description: string) {\n\treturn Type.Optional(Type.Union([schema, Type.Null()], { description }));\n}\n\nexport const TaskSchema = Type.Object(\n\t{\n\t\tagent: nullable(\n\t\t\tType.String({ minLength: 1, maxLength: 80 }),\n\t\t\t\"Agent profile from the list in the tool description; null or omit for general\",\n\t\t),\n\t\tdescription: Type.String({\n\t\t\tminLength: 1,\n\t\t\tmaxLength: 80,\n\t\t\tdescription: \"Concise 3-8 word UI label\",\n\t\t}),\n\t\tprompt: Type.String({\n\t\t\tminLength: 1,\n\t\t\tmaxLength: 50_000,\n\t\t\tdescription: \"Complete self-contained briefing; the worker cannot see the parent conversation\",\n\t\t}),\n\t\tcwd: nullable(\n\t\t\tType.String({ minLength: 1, maxLength: 4_096 }),\n\t\t\t\"Relative or absolute directory inside the parent working directory; null or omit to inherit it\",\n\t\t),\n\t},\n\t{ additionalProperties: false },\n);\n\nexport const SubagentParamsSchema = Type.Object(\n\t{\n\t\tagent: nullable(\n\t\t\tType.String({ minLength: 1, maxLength: 80 }),\n\t\t\t\"Agent profile from the list in the tool description (single mode); null or omit otherwise (defaults to general)\",\n\t\t),\n\t\tdescription: nullable(\n\t\t\tType.String({ minLength: 1, maxLength: 80 }),\n\t\t\t\"Concise 3-8 word UI label; required for single mode, null or omit otherwise\",\n\t\t),\n\t\tprompt: nullable(\n\t\t\tType.String({ minLength: 1, maxLength: 50_000 }),\n\t\t\t\"Complete self-contained briefing; providing it selects single mode — null or omit when using tasks\",\n\t\t),\n\t\tcwd: nullable(\n\t\t\tType.String({ minLength: 1, maxLength: 4_096 }),\n\t\t\t\"Relative or absolute directory inside the parent working directory (single mode); null or omit otherwise\",\n\t\t),\n\t\ttasks: nullable(\n\t\t\tType.Array(TaskSchema, { minItems: 1, maxItems: MAX_TASKS }),\n\t\t\t\"Independent tasks run concurrently; providing it selects parallel mode — null or omit when using prompt\",\n\t\t),\n\t},\n\t{ additionalProperties: false },\n);\n\nexport type SubagentParams = Static<typeof SubagentParamsSchema>;\nexport type SubagentTask = Static<typeof TaskSchema>;\n"]}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/extensions/subagent/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAA6B,IAAI,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAElF,yEAAyE;AACzE,mEAAmE;AACnE,yEAAyE;AACzE,qEAAqE;AACrE,SAAS,QAAQ,CAAoB,MAAS,EAAE,WAAmB;IAClE,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;AAC1E,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CACpC;IACC,KAAK,EAAE,QAAQ,CACd,UAAU,CAAC,oBAAoB,EAAE,EAAE,WAAW,EAAE,uCAAuC,EAAE,CAAC,EAC1F,2DAA2D,CAC3D;IACD,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;QACnB,SAAS,EAAE,CAAC;QACZ,SAAS,EAAE,MAAM;QACjB,WAAW,EAAE,iFAAiF;KAC9F,CAAC;IACF,GAAG,EAAE,QAAQ,CACZ,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,EAC/C,gGAAgG,CAChG;CACD,EACD,EAAE,oBAAoB,EAAE,KAAK,EAAE,CAC/B,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,CAAC,MAAM,CAC9C;IACC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE;QAC7B,QAAQ,EAAE,CAAC;QACX,QAAQ,EAAE,SAAS;QACnB,WAAW,EAAE,+CAA+C,eAAe,uEAAuE;KAClJ,CAAC;CACF,EACD,EAAE,oBAAoB,EAAE,KAAK,EAAE,CAC/B,CAAC","sourcesContent":["import { StringEnum } from \"@earendil-works/pi-ai\";\nimport { type Static, type TSchema, Type } from \"typebox\";\nimport { MAX_CONCURRENCY, MAX_TASKS, SUBAGENT_AGENT_NAMES } from \"./constants.ts\";\n\n// Strict constrained-sampling providers treat every property as required\n// and reject bare unions at the top level, so the schema is a flat\n// `type: \"object\"` whose optional fields are also nullable: callers omit\n// a field when the grammar allows it and send null when it does not.\nfunction nullable<T extends TSchema>(schema: T, description: string) {\n\treturn Type.Optional(Type.Union([schema, Type.Null()], { description }));\n}\n\nexport const TaskSchema = Type.Object(\n\t{\n\t\tagent: nullable(\n\t\t\tStringEnum(SUBAGENT_AGENT_NAMES, { description: \"Which built-in profile runs this task\" }),\n\t\t\t\"Built-in profile; null or omit for explorer (the default)\",\n\t\t),\n\t\tprompt: Type.String({\n\t\t\tminLength: 1,\n\t\t\tmaxLength: 50_000,\n\t\t\tdescription: \"Complete self-contained briefing; the worker cannot see the parent conversation\",\n\t\t}),\n\t\tcwd: nullable(\n\t\t\tType.String({ minLength: 1, maxLength: 4_096 }),\n\t\t\t\"Relative or absolute directory inside the parent working directory; null or omit to inherit it\",\n\t\t),\n\t},\n\t{ additionalProperties: false },\n);\n\nexport const SubagentParamsSchema = Type.Object(\n\t{\n\t\ttasks: Type.Array(TaskSchema, {\n\t\t\tminItems: 1,\n\t\t\tmaxItems: MAX_TASKS,\n\t\t\tdescription: `Independent tasks run concurrently: at most ${MAX_CONCURRENCY} active at once, excess tasks queue, and results preserve input order`,\n\t\t}),\n\t},\n\t{ additionalProperties: false },\n);\n\nexport type SubagentParams = Static<typeof SubagentParamsSchema>;\nexport type SubagentTask = Static<typeof TaskSchema>;\n"]}
@@ -1,20 +1,22 @@
1
- import type { AgentSessionEvent } from "../../core/agent-session.ts";
2
1
  import type { ModelRuntime } from "../../core/model-runtime.ts";
3
- import type { ResolvedSubagentTask, SubagentRunDetails } from "./types.ts";
2
+ import type { RunCancellation } from "./cancellation.ts";
3
+ import type { SubagentRunEvent } from "./state.ts";
4
+ import type { ResolvedSubagentTask } from "./types.ts";
4
5
  export interface SdkRunnerOptions {
5
6
  task: ResolvedSubagentTask;
6
- run: SubagentRunDetails;
7
+ /** Cancellation scope covering this attempt (queued through session end). */
8
+ scope: RunCancellation;
9
+ /** Reducer input; the adapter never touches run state directly. */
10
+ dispatch: (event: SubagentRunEvent) => void;
7
11
  modelRuntime: ModelRuntime;
8
12
  agentDir: string;
9
13
  projectTrusted: boolean;
10
- signal?: AbortSignal;
11
14
  onProgress?: () => void;
12
- registerAbort?: (abort: () => Promise<void>) => () => void;
13
15
  }
14
- type AutoRetryEvent = Extract<AgentSessionEvent, {
15
- type: "auto_retry_start" | "auto_retry_end";
16
- }>;
17
- export declare function applySubagentAutoRetryEvent(run: SubagentRunDetails, event: AutoRetryEvent): void;
18
- export declare function runSdkTask(options: SdkRunnerOptions): Promise<SubagentRunDetails>;
19
- export {};
16
+ /**
17
+ * Runs one worker attempt as a pure adapter: it owns the worker session's
18
+ * lifecycle and translates AgentSessionEvents into SubagentRunEvents; every
19
+ * state transition happens in the reducer on the other side of dispatch.
20
+ */
21
+ export declare function runSdkTask(options: SdkRunnerOptions): Promise<void>;
20
22
  //# sourceMappingURL=sdk-runner.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sdk-runner.d.ts","sourceRoot":"","sources":["../../../src/extensions/subagent/sdk-runner.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAiBhE,OAAO,KAAK,EAAE,oBAAoB,EAAE,kBAAkB,EAAgB,MAAM,YAAY,CAAC;AAEzF,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,oBAAoB,CAAC;IAC3B,GAAG,EAAE,kBAAkB,CAAC;IACxB,YAAY,EAAE,YAAY,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC;CAC3D;AAyDD,KAAK,cAAc,GAAG,OAAO,CAAC,iBAAiB,EAAE;IAAE,IAAI,EAAE,kBAAkB,GAAG,gBAAgB,CAAA;CAAE,CAAC,CAAC;AAElG,wBAAgB,2BAA2B,CAAC,GAAG,EAAE,kBAAkB,EAAE,KAAK,EAAE,cAAc,GAAG,IAAI,CAWhG;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAqNvF"}
1
+ {"version":3,"file":"sdk-runner.d.ts","sourceRoot":"","sources":["../../../src/extensions/subagent/sdk-runner.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAMhE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,oBAAoB,CAAC;IAC3B,6EAA6E;IAC7E,KAAK,EAAE,eAAe,CAAC;IACvB,mEAAmE;IACnE,QAAQ,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC5C,YAAY,EAAE,YAAY,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,OAAO,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AAiGD;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmNzE"}
@@ -2,9 +2,7 @@ import { DefaultResourceLoader } from "../../core/resource-loader.js";
2
2
  import { createAgentSession } from "../../core/sdk.js";
3
3
  import { SessionManager } from "../../core/session-manager.js";
4
4
  import { SettingsManager } from "../../core/settings-manager.js";
5
- import { activitySummary, addUsage, appendActivity, assistantText, boundText, finalAssistantText, resultSummary, setLiveText, } from "./activity.js";
6
- import { ERROR_TEXT_LIMIT, LIVE_TEXT_LIMIT, SINGLE_OUTPUT_LIMIT } from "./constants.js";
7
- import { beginSubagentRetry, clearSubagentRetry } from "./retry.js";
5
+ import { finalAssistantText } from "./activity.js";
8
6
  function workerSystemPrompt(base, task) {
9
7
  return [
10
8
  base,
@@ -15,7 +13,7 @@ function workerSystemPrompt(base, task) {
15
13
  "Stay inside the assigned working directory and delegated scope.",
16
14
  "Do not ask the end user questions. If blocked, report the exact blocker and what would resolve it.",
17
15
  "Do not spawn subagents or invoke tools outside the configured tool list.",
18
- "When referencing files in the final report, use absolute paths so the caller can locate them unambiguously.",
16
+ "When referencing files in the final report, use paths relative to the task's working directory so the caller can locate them unambiguously.",
19
17
  "Include code snippets only when the exact text is load-bearing (a bug you found, a signature the caller asked for); do not recap code you merely read.",
20
18
  "End with a concise report covering findings or changes, verification performed, blockers, and unresolved risks. The caller will relay it to the user, so include only the essentials.",
21
19
  task.agent.systemPrompt,
@@ -54,53 +52,63 @@ function createThrottledEmitter(onProgress) {
54
52
  },
55
53
  };
56
54
  }
57
- export function applySubagentAutoRetryEvent(run, event) {
58
- if (event.type === "auto_retry_start") {
59
- beginSubagentRetry(run, {
60
- attempt: event.attempt,
61
- maxAttempts: event.maxAttempts,
62
- delayMs: event.delayMs,
63
- error: event.errorMessage,
64
- });
65
- return;
66
- }
67
- clearSubagentRetry(run);
55
+ // Neither resource loading nor session creation takes an abort signal, and
56
+ // both can hang on network work; race both against the scope. The losing
57
+ // chain keeps running, so its eventual result or rejection is always
58
+ // consumed by a no-op handler.
59
+ async function raceInitialization(chain, scope) {
60
+ return new Promise((resolve) => {
61
+ let settled = false;
62
+ const finish = (outcome) => {
63
+ if (settled)
64
+ return;
65
+ settled = true;
66
+ scope.signal.removeEventListener("abort", onAbort);
67
+ resolve(outcome);
68
+ };
69
+ const onAbort = () => {
70
+ finish({ kind: "aborted" });
71
+ };
72
+ if (scope.signal.aborted) {
73
+ onAbort();
74
+ void chain.then(() => undefined, () => undefined);
75
+ return;
76
+ }
77
+ scope.signal.addEventListener("abort", onAbort, { once: true });
78
+ void chain.then((outcome) => finish(outcome), (error) => finish({ kind: "error", error }));
79
+ });
68
80
  }
81
+ /**
82
+ * Runs one worker attempt as a pure adapter: it owns the worker session's
83
+ * lifecycle and translates AgentSessionEvents into SubagentRunEvents; every
84
+ * state transition happens in the reducer on the other side of dispatch.
85
+ */
69
86
  export async function runSdkTask(options) {
70
- const { task, run, modelRuntime, agentDir, projectTrusted, signal, onProgress } = options;
87
+ const { task, scope, dispatch, modelRuntime, agentDir, projectTrusted, onProgress } = options;
71
88
  const throttled = createThrottledEmitter(onProgress);
72
89
  let unsubscribe;
73
90
  let unregisterAbort;
74
91
  let session;
75
- const activeActivities = new Map();
92
+ // Streaming updates carry no semantic weight; the settled messages are
93
+ // where usage is accounted, and worker sessions can replay them.
76
94
  const seenAssistantMessages = new Set();
77
- const initializationAbortController = new AbortController();
78
- const markAbort = async () => {
79
- clearSubagentRetry(run);
80
- run.status = "aborted";
81
- run.error ??= "Subagent was aborted.";
82
- initializationAbortController.abort();
95
+ const emitImmediate = () => onProgress?.();
96
+ const emitThrottled = throttled.emit;
97
+ unregisterAbort = scope.onAbort(async () => {
83
98
  if (session)
84
99
  await session.abort();
85
- };
86
- const isAborted = () => signal?.aborted === true || run.status === "aborted";
87
- const abortListener = () => {
88
- void markAbort().catch(() => undefined);
89
- };
90
- unregisterAbort = options.registerAbort?.(markAbort);
91
- if (signal)
92
- signal.addEventListener("abort", abortListener, { once: true });
100
+ });
93
101
  try {
94
- if (isAborted()) {
95
- clearSubagentRetry(run);
96
- run.status = "aborted";
97
- run.error = "Subagent was aborted before it started.";
98
- return run;
102
+ if (scope.aborted) {
103
+ dispatch({
104
+ type: "settle",
105
+ verdict: "aborted",
106
+ report: "",
107
+ error: "Subagent was aborted before it started.",
108
+ endedAt: Date.now(),
109
+ });
110
+ return;
99
111
  }
100
- clearSubagentRetry(run);
101
- run.status = "running";
102
- run.startedAt = Date.now();
103
- onProgress?.();
104
112
  const settingsManager = SettingsManager.create(task.cwd, agentDir, { projectTrusted });
105
113
  const resourceLoader = new DefaultResourceLoader({
106
114
  cwd: task.cwd,
@@ -115,179 +123,179 @@ export async function runSdkTask(options) {
115
123
  noContextFiles: task.agent.omitContextFiles ?? false,
116
124
  systemPromptOverride: (base) => workerSystemPrompt(base, task),
117
125
  });
118
- await resourceLoader.reload();
119
- if (isAborted()) {
120
- run.error ??= "Subagent was aborted during initialization.";
121
- return run;
122
- }
123
- const createPromise = createAgentSession({
124
- cwd: task.cwd,
125
- agentDir,
126
- modelRuntime,
127
- model: task.model,
128
- thinkingLevel: task.thinking,
129
- tools: task.agent.tools,
130
- resourceLoader,
131
- sessionManager: SessionManager.inMemory(task.cwd),
132
- settingsManager,
133
- });
134
- // createAgentSession takes no signal and can hang on network work. Race
135
- // both parent-signal and registered shutdown cancellation against it;
136
- // only the winning branch owns disposal of the resulting session.
137
- const initializationSignal = initializationAbortController.signal;
138
- let creationAbortListener;
139
- const abortedOutcome = new Promise((resolve) => {
140
- const resolveAborted = () => resolve({ kind: "aborted" });
141
- if (initializationSignal.aborted) {
142
- resolveAborted();
143
- return;
144
- }
145
- creationAbortListener = resolveAborted;
146
- initializationSignal.addEventListener("abort", resolveAborted, { once: true });
147
- });
148
- const outcome = await Promise.race([
149
- createPromise.then((created) => ({ kind: "created", created })),
150
- abortedOutcome,
151
- ]).finally(() => {
152
- if (creationAbortListener)
153
- initializationSignal.removeEventListener("abort", creationAbortListener);
154
- });
126
+ const initialization = (async () => {
127
+ await resourceLoader.reload();
128
+ if (scope.signal.aborted)
129
+ return { kind: "aborted" };
130
+ const created = await createAgentSession({
131
+ cwd: task.cwd,
132
+ agentDir,
133
+ modelRuntime,
134
+ model: task.model,
135
+ thinkingLevel: task.thinking,
136
+ tools: task.agent.tools,
137
+ resourceLoader,
138
+ sessionManager: SessionManager.inMemory(task.cwd),
139
+ settingsManager,
140
+ });
141
+ return { kind: "created", session: created.session };
142
+ })();
143
+ const outcome = await raceInitialization(initialization, scope);
144
+ if (outcome.kind === "error")
145
+ throw outcome.error;
155
146
  if (outcome.kind === "aborted") {
156
- // The creation promise cannot be cancelled. Dispose its session if it
157
- // eventually resolves, but keep background cleanup from surfacing an
158
- // unhandled rejection after this run has already settled.
159
- void createPromise.then((createdLate) => {
160
- try {
161
- createdLate.session.dispose();
162
- }
163
- catch {
164
- // The aborted run has no remaining channel for cleanup errors.
147
+ // The initialization chain cannot be cancelled. Dispose the
148
+ // session if it eventually resolves, and swallow a late rejection
149
+ // after this run has already settled.
150
+ void initialization.then((late) => {
151
+ if (late.kind === "created") {
152
+ try {
153
+ late.session.dispose();
154
+ }
155
+ catch {
156
+ // The aborted run has no remaining channel for cleanup errors.
157
+ }
165
158
  }
166
159
  }, () => { });
167
- run.error ??= "Subagent was aborted during initialization.";
168
- return run;
160
+ dispatch({
161
+ type: "settle",
162
+ verdict: "aborted",
163
+ report: "",
164
+ error: "Subagent was aborted during initialization.",
165
+ endedAt: Date.now(),
166
+ });
167
+ return;
169
168
  }
170
- const created = outcome.created;
171
- session = created.session;
172
- if (isAborted()) {
173
- run.error ??= "Subagent was aborted during initialization.";
169
+ session = outcome.session;
170
+ if (scope.aborted) {
174
171
  await session.abort();
175
- return run;
172
+ dispatch({
173
+ type: "settle",
174
+ verdict: "aborted",
175
+ report: "",
176
+ error: "Subagent was aborted during initialization.",
177
+ endedAt: Date.now(),
178
+ });
179
+ return;
176
180
  }
177
- const emitImmediate = () => onProgress?.();
178
- const emitText = throttled.emit;
179
181
  unsubscribe = session.subscribe((event) => {
180
- if (event.type === "auto_retry_start" || event.type === "auto_retry_end") {
181
- applySubagentAutoRetryEvent(run, event);
182
+ if (event.type === "auto_retry_start") {
183
+ dispatch({
184
+ type: "auto_retry_start",
185
+ attempt: event.attempt,
186
+ maxAttempts: event.maxAttempts,
187
+ deadline: Date.now() + event.delayMs,
188
+ error: event.errorMessage,
189
+ });
190
+ emitImmediate();
191
+ return;
192
+ }
193
+ if (event.type === "auto_retry_end") {
194
+ dispatch({ type: "auto_retry_end" });
182
195
  emitImmediate();
183
196
  return;
184
197
  }
185
198
  if (event.type === "turn_end") {
186
- clearSubagentRetry(run);
187
- run.usage.turns++;
188
- run.currentActivity = undefined;
199
+ dispatch({ type: "turn_end" });
189
200
  emitImmediate();
190
201
  return;
191
202
  }
192
203
  if (event.type === "message_end" && event.message.role === "assistant") {
193
- clearSubagentRetry(run);
194
204
  if (!seenAssistantMessages.has(event.message)) {
195
205
  seenAssistantMessages.add(event.message);
196
- addUsage(run.usage, event.message.usage);
206
+ dispatch({ type: "assistant_message_settled", usage: event.message.usage });
197
207
  }
198
- run.liveText = setLiveText(assistantText(event.message));
199
- emitText();
200
- return;
201
- }
202
- if (event.type === "message_update") {
203
- clearSubagentRetry(run);
204
- if (event.message.role === "assistant")
205
- run.liveText = setLiveText(assistantText(event.message));
206
- if (event.assistantMessageEvent.type === "thinking_delta")
207
- run.currentActivity = "Thinking…";
208
- if (event.assistantMessageEvent.type === "text_delta")
209
- run.currentActivity = "Writing response…";
210
- emitText();
208
+ else {
209
+ dispatch({ type: "assistant_message_settled", usage: undefined });
210
+ }
211
+ emitImmediate();
211
212
  return;
212
213
  }
213
214
  if (event.type === "tool_execution_start") {
214
- clearSubagentRetry(run);
215
- run.usage.toolUses++;
216
- const activity = {
217
- id: event.toolCallId,
215
+ dispatch({
216
+ type: "tool_started",
217
+ toolCallId: event.toolCallId,
218
218
  toolName: event.toolName,
219
- summary: activitySummary(event.toolName, event.args),
220
- status: "running",
219
+ args: event.args,
221
220
  startedAt: Date.now(),
222
- };
223
- activeActivities.set(event.toolCallId, activity);
224
- appendActivity(run.activities, activity);
225
- run.currentActivity = activity.summary;
221
+ });
226
222
  emitImmediate();
227
223
  return;
228
224
  }
229
225
  if (event.type === "tool_execution_update") {
230
- clearSubagentRetry(run);
231
- run.currentActivity = activitySummary(event.toolName, event.args);
232
- emitText();
226
+ dispatch({
227
+ type: "tool_updated",
228
+ toolCallId: event.toolCallId,
229
+ toolName: event.toolName,
230
+ args: event.args,
231
+ });
232
+ emitThrottled();
233
233
  return;
234
234
  }
235
235
  if (event.type === "tool_execution_end") {
236
- clearSubagentRetry(run);
237
- const activity = activeActivities.get(event.toolCallId);
238
- if (activity) {
239
- activity.status = event.isError ? "failed" : "succeeded";
240
- activity.endedAt = Date.now();
241
- activity.resultSummary = resultSummary(event.result);
242
- }
243
- activeActivities.delete(event.toolCallId);
244
- run.currentActivity = undefined;
236
+ dispatch({
237
+ type: "tool_ended",
238
+ toolCallId: event.toolCallId,
239
+ result: event.result,
240
+ isError: event.isError,
241
+ endedAt: Date.now(),
242
+ });
245
243
  emitImmediate();
246
244
  }
247
245
  });
248
246
  await session.prompt(task.prompt);
249
247
  const finalMessage = lastAssistantMessage(session);
250
- run.finalOutput = finalAssistantText(session.messages);
248
+ const report = finalAssistantText(session.messages);
251
249
  const error = assistantError(finalMessage);
252
- if (signal?.aborted || finalMessage?.stopReason === "aborted") {
253
- run.status = "aborted";
254
- run.error = boundText(error ?? "Subagent was aborted.", ERROR_TEXT_LIMIT);
250
+ if (scope.signal.aborted || finalMessage?.stopReason === "aborted") {
251
+ dispatch({
252
+ type: "settle",
253
+ verdict: "aborted",
254
+ report,
255
+ error: error ?? "Subagent was aborted.",
256
+ endedAt: Date.now(),
257
+ });
255
258
  }
256
259
  else if (finalMessage?.stopReason === "error" || error) {
257
- run.status = "failed";
258
- run.error = boundText(error ?? "Subagent failed.", ERROR_TEXT_LIMIT);
260
+ dispatch({
261
+ type: "settle",
262
+ verdict: "failed",
263
+ report,
264
+ error: error ?? "Subagent failed.",
265
+ endedAt: Date.now(),
266
+ });
259
267
  }
260
268
  else {
261
- run.status = "completed";
269
+ dispatch({ type: "settle", verdict: "completed", report, error: undefined, endedAt: Date.now() });
262
270
  }
263
271
  }
264
272
  catch (error) {
265
- if (signal?.aborted || run.status === "aborted") {
266
- run.status = "aborted";
267
- run.error = run.error ?? "Subagent was aborted.";
273
+ const report = session ? finalAssistantText(session.messages) : "";
274
+ if (scope.signal.aborted) {
275
+ dispatch({
276
+ type: "settle",
277
+ verdict: "aborted",
278
+ report,
279
+ error: "Subagent was aborted.",
280
+ endedAt: Date.now(),
281
+ });
268
282
  }
269
283
  else {
270
- run.status = "failed";
271
- run.error = boundText(error instanceof Error ? error.message : String(error), ERROR_TEXT_LIMIT);
284
+ dispatch({
285
+ type: "settle",
286
+ verdict: "failed",
287
+ report,
288
+ error: error instanceof Error ? error.message : String(error),
289
+ endedAt: Date.now(),
290
+ });
272
291
  }
273
- if (session)
274
- run.finalOutput = finalAssistantText(session.messages);
275
292
  }
276
293
  finally {
277
- if (signal)
278
- signal.removeEventListener("abort", abortListener);
279
294
  throttled.cancel();
280
295
  unregisterAbort?.();
281
296
  unsubscribe?.();
282
297
  session?.dispose();
283
- run.liveText = boundText(run.liveText, LIVE_TEXT_LIMIT);
284
- run.finalOutput = boundText(run.finalOutput, SINGLE_OUTPUT_LIMIT);
285
- if (run.error)
286
- run.error = boundText(run.error, ERROR_TEXT_LIMIT);
287
- clearSubagentRetry(run);
288
- run.endedAt = Date.now();
289
- onProgress?.();
298
+ emitImmediate();
290
299
  }
291
- return run;
292
300
  }
293
301
  //# sourceMappingURL=sdk-runner.js.map