pi-subagents 0.70.1 → 0.71.0

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 (209) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/README.md +3 -1
  3. package/agents/worker.md +2 -2
  4. package/docs/agents.md +1 -1
  5. package/docs/configuration.md +15 -1
  6. package/docs/extension-api.md +3 -1
  7. package/docs/observability.md +16 -12
  8. package/docs/tool-reference.md +6 -4
  9. package/docs/workflows.md +1 -1
  10. package/package.json +2 -2
  11. package/skills/pi-subagents/references/constraints-and-recipes.md +5 -2
  12. package/skills/pi-subagents/references/execution-controls.md +2 -2
  13. package/skills/pi-subagents/references/management-authoring-rpc.md +2 -2
  14. package/src/agents/proactive-skills.d.ts +1 -0
  15. package/src/agents/proactive-skills.d.ts.map +1 -1
  16. package/src/agents/proactive-skills.js +3 -1
  17. package/src/agents/proactive-skills.js.map +1 -1
  18. package/src/agents/skills.d.ts +2 -0
  19. package/src/agents/skills.d.ts.map +1 -1
  20. package/src/agents/skills.js +41 -8
  21. package/src/agents/skills.js.map +1 -1
  22. package/src/api/delegation.d.ts +14 -0
  23. package/src/api/delegation.d.ts.map +1 -1
  24. package/src/extension/index.d.ts.map +1 -1
  25. package/src/extension/index.js +4 -0
  26. package/src/extension/index.js.map +1 -1
  27. package/src/extension/rpc.d.ts +1 -1
  28. package/src/extension/rpc.d.ts.map +1 -1
  29. package/src/extension/rpc.js +11 -1
  30. package/src/extension/rpc.js.map +1 -1
  31. package/src/extension/tool-activation.d.ts +9 -0
  32. package/src/extension/tool-activation.d.ts.map +1 -0
  33. package/src/extension/tool-activation.js +172 -0
  34. package/src/extension/tool-activation.js.map +1 -0
  35. package/src/extension/tool-description.d.ts +4 -4
  36. package/src/extension/tool-description.d.ts.map +1 -1
  37. package/src/extension/tool-description.js +1 -1
  38. package/src/intercom/intercom-bridge.d.ts.map +1 -1
  39. package/src/intercom/intercom-bridge.js +2 -0
  40. package/src/intercom/intercom-bridge.js.map +1 -1
  41. package/src/runs/background/active-async-capacity.d.ts.map +1 -1
  42. package/src/runs/background/active-async-capacity.js +4 -33
  43. package/src/runs/background/active-async-capacity.js.map +1 -1
  44. package/src/runs/background/async-execution.d.ts.map +1 -1
  45. package/src/runs/background/async-execution.js +5 -33
  46. package/src/runs/background/async-execution.js.map +1 -1
  47. package/src/runs/background/async-job-tracker.d.ts.map +1 -1
  48. package/src/runs/background/async-job-tracker.js +25 -19
  49. package/src/runs/background/async-job-tracker.js.map +1 -1
  50. package/src/runs/background/async-resume.d.ts +1 -1
  51. package/src/runs/background/async-resume.d.ts.map +1 -1
  52. package/src/runs/background/async-resume.js +7 -2
  53. package/src/runs/background/async-resume.js.map +1 -1
  54. package/src/runs/background/async-status.d.ts +1 -0
  55. package/src/runs/background/async-status.d.ts.map +1 -1
  56. package/src/runs/background/async-status.js +1 -0
  57. package/src/runs/background/async-status.js.map +1 -1
  58. package/src/runs/background/binary-bootstrap.d.ts.map +1 -1
  59. package/src/runs/background/binary-bootstrap.js +28 -6
  60. package/src/runs/background/binary-bootstrap.js.map +1 -1
  61. package/src/runs/background/fleet-view.d.ts.map +1 -1
  62. package/src/runs/background/fleet-view.js +26 -7
  63. package/src/runs/background/fleet-view.js.map +1 -1
  64. package/src/runs/background/notify.d.ts +11 -0
  65. package/src/runs/background/notify.d.ts.map +1 -1
  66. package/src/runs/background/notify.js +71 -3
  67. package/src/runs/background/notify.js.map +1 -1
  68. package/src/runs/background/process-terminal-candidate.d.ts +18 -0
  69. package/src/runs/background/process-terminal-candidate.d.ts.map +1 -0
  70. package/src/runs/background/process-terminal-candidate.js +97 -0
  71. package/src/runs/background/process-terminal-candidate.js.map +1 -0
  72. package/src/runs/background/process-terminal.d.ts +3 -15
  73. package/src/runs/background/process-terminal.d.ts.map +1 -1
  74. package/src/runs/background/process-terminal.js +19 -96
  75. package/src/runs/background/process-terminal.js.map +1 -1
  76. package/src/runs/background/retained-children.d.ts.map +1 -1
  77. package/src/runs/background/retained-children.js +3 -2
  78. package/src/runs/background/retained-children.js.map +1 -1
  79. package/src/runs/background/run-child-session.d.ts +1 -0
  80. package/src/runs/background/run-child-session.d.ts.map +1 -1
  81. package/src/runs/background/run-child-session.js.map +1 -1
  82. package/src/runs/background/run-status.d.ts.map +1 -1
  83. package/src/runs/background/run-status.js +5 -1
  84. package/src/runs/background/run-status.js.map +1 -1
  85. package/src/runs/background/runner-aliases.d.ts.map +1 -1
  86. package/src/runs/background/runner-aliases.js +2 -1
  87. package/src/runs/background/runner-aliases.js.map +1 -1
  88. package/src/runs/background/runner-startup-failure.d.ts +14 -0
  89. package/src/runs/background/runner-startup-failure.d.ts.map +1 -0
  90. package/src/runs/background/runner-startup-failure.js +47 -0
  91. package/src/runs/background/runner-startup-failure.js.map +1 -0
  92. package/src/runs/background/stale-run-reconciler.d.ts.map +1 -1
  93. package/src/runs/background/stale-run-reconciler.js +9 -1
  94. package/src/runs/background/stale-run-reconciler.js.map +1 -1
  95. package/src/runs/background/subagent-runner-bootstrap.d.ts +14 -0
  96. package/src/runs/background/subagent-runner-bootstrap.d.ts.map +1 -0
  97. package/src/runs/background/subagent-runner-bootstrap.js +277 -0
  98. package/src/runs/background/subagent-runner-bootstrap.js.map +1 -0
  99. package/src/runs/background/subagent-runner.d.ts +4 -2
  100. package/src/runs/background/subagent-runner.d.ts.map +1 -1
  101. package/src/runs/background/subagent-runner.js +53 -178
  102. package/src/runs/background/subagent-runner.js.map +1 -1
  103. package/src/runs/background/workflow-terminal-proof.d.ts +18 -0
  104. package/src/runs/background/workflow-terminal-proof.d.ts.map +1 -0
  105. package/src/runs/background/workflow-terminal-proof.js +68 -0
  106. package/src/runs/background/workflow-terminal-proof.js.map +1 -0
  107. package/src/runs/foreground/execution.d.ts.map +1 -1
  108. package/src/runs/foreground/execution.js +43 -14
  109. package/src/runs/foreground/execution.js.map +1 -1
  110. package/src/runs/foreground/subagent-executor.d.ts.map +1 -1
  111. package/src/runs/foreground/subagent-executor.js +108 -15
  112. package/src/runs/foreground/subagent-executor.js.map +1 -1
  113. package/src/runs/shared/child-launch.d.ts.map +1 -1
  114. package/src/runs/shared/child-launch.js +3 -0
  115. package/src/runs/shared/child-launch.js.map +1 -1
  116. package/src/runs/shared/child-runtime-config.d.ts +4 -0
  117. package/src/runs/shared/child-runtime-config.d.ts.map +1 -1
  118. package/src/runs/shared/child-runtime-config.js.map +1 -1
  119. package/src/runs/shared/external-cli-runner.d.ts.map +1 -1
  120. package/src/runs/shared/external-cli-runner.js +3 -1
  121. package/src/runs/shared/external-cli-runner.js.map +1 -1
  122. package/src/runs/shared/git-environment.d.ts +3 -0
  123. package/src/runs/shared/git-environment.d.ts.map +1 -0
  124. package/src/runs/shared/git-environment.js +28 -0
  125. package/src/runs/shared/git-environment.js.map +1 -0
  126. package/src/runs/shared/mcp-config-sources.d.ts +3 -0
  127. package/src/runs/shared/mcp-config-sources.d.ts.map +1 -1
  128. package/src/runs/shared/mcp-config-sources.js.map +1 -1
  129. package/src/runs/shared/mcp-direct-tool-allowlist.js +1 -1
  130. package/src/runs/shared/mcp-direct-tool-allowlist.js.map +1 -1
  131. package/src/runs/shared/mcp-direct-tool-grant.d.ts +3 -1
  132. package/src/runs/shared/mcp-direct-tool-grant.d.ts.map +1 -1
  133. package/src/runs/shared/mcp-direct-tool-grant.js +19 -5
  134. package/src/runs/shared/mcp-direct-tool-grant.js.map +1 -1
  135. package/src/runs/shared/pi-spawn.d.ts +10 -1
  136. package/src/runs/shared/pi-spawn.d.ts.map +1 -1
  137. package/src/runs/shared/pi-spawn.js +86 -7
  138. package/src/runs/shared/pi-spawn.js.map +1 -1
  139. package/src/runs/shared/single-output.js +1 -1
  140. package/src/runs/shared/single-output.js.map +1 -1
  141. package/src/runs/shared/structured-output.d.ts +7 -0
  142. package/src/runs/shared/structured-output.d.ts.map +1 -1
  143. package/src/runs/shared/structured-output.js +74 -0
  144. package/src/runs/shared/structured-output.js.map +1 -1
  145. package/src/runs/shared/subagent-prompt-runtime.d.ts.map +1 -1
  146. package/src/runs/shared/subagent-prompt-runtime.js +23 -7
  147. package/src/runs/shared/subagent-prompt-runtime.js.map +1 -1
  148. package/src/runs/shared/tool-availability.js +1 -1
  149. package/src/runs/shared/tool-availability.js.map +1 -1
  150. package/src/shared/child-session-name.d.ts.map +1 -1
  151. package/src/shared/child-session-name.js +4 -2
  152. package/src/shared/child-session-name.js.map +1 -1
  153. package/src/shared/fork-context.d.ts +4 -0
  154. package/src/shared/fork-context.d.ts.map +1 -1
  155. package/src/shared/fork-context.js +9 -4
  156. package/src/shared/fork-context.js.map +1 -1
  157. package/src/shared/pruned-fork.d.ts.map +1 -1
  158. package/src/shared/pruned-fork.js +68 -56
  159. package/src/shared/pruned-fork.js.map +1 -1
  160. package/src/shared/types.d.ts +29 -3
  161. package/src/shared/types.d.ts.map +1 -1
  162. package/src/shared/types.js +2 -0
  163. package/src/shared/types.js.map +1 -1
  164. package/src/slash/delegation-adapters.d.ts +7 -1
  165. package/src/slash/delegation-adapters.d.ts.map +1 -1
  166. package/src/slash/delegation-adapters.js +17 -0
  167. package/src/slash/delegation-adapters.js.map +1 -1
  168. package/src/slash/prompt-template-bridge.d.ts.map +1 -1
  169. package/src/slash/prompt-template-bridge.js +14 -1
  170. package/src/slash/prompt-template-bridge.js.map +1 -1
  171. package/src/slash/prompt-workflows.d.ts.map +1 -1
  172. package/src/slash/prompt-workflows.js +16 -2
  173. package/src/slash/prompt-workflows.js.map +1 -1
  174. package/src/slash/slash-commands.d.ts.map +1 -1
  175. package/src/slash/slash-commands.js +4 -250
  176. package/src/slash/slash-commands.js.map +1 -1
  177. package/src/slash/subagent-cost.d.ts +29 -0
  178. package/src/slash/subagent-cost.d.ts.map +1 -0
  179. package/src/slash/subagent-cost.js +271 -0
  180. package/src/slash/subagent-cost.js.map +1 -0
  181. package/src/tui/fleet.d.ts.map +1 -1
  182. package/src/tui/fleet.js +4 -0
  183. package/src/tui/fleet.js.map +1 -1
  184. package/src/tui/render.d.ts.map +1 -1
  185. package/src/tui/render.js +8 -4
  186. package/src/tui/render.js.map +1 -1
  187. package/src/watchdog/diff-tool.d.ts +2 -1
  188. package/src/watchdog/diff-tool.d.ts.map +1 -1
  189. package/src/watchdog/diff-tool.js +9 -3
  190. package/src/watchdog/diff-tool.js.map +1 -1
  191. package/src/watchdog/permission-arbiter.d.ts.map +1 -1
  192. package/src/watchdog/permission-arbiter.js +1 -2
  193. package/src/watchdog/permission-arbiter.js.map +1 -1
  194. package/src/watchdog/register-child.d.ts +3 -1
  195. package/src/watchdog/register-child.d.ts.map +1 -1
  196. package/src/watchdog/register-child.js +12 -3
  197. package/src/watchdog/register-child.js.map +1 -1
  198. package/src/watchdog/review.d.ts +1 -1
  199. package/src/watchdog/review.d.ts.map +1 -1
  200. package/src/watchdog/review.js +1 -2
  201. package/src/watchdog/review.js.map +1 -1
  202. package/src/watchdog/runtime.d.ts +1 -1
  203. package/src/watchdog/runtime.d.ts.map +1 -1
  204. package/src/watchdog/runtime.js +2 -1
  205. package/src/watchdog/runtime.js.map +1 -1
  206. package/src/watchdog/turn-delta.d.ts +5 -1
  207. package/src/watchdog/turn-delta.d.ts.map +1 -1
  208. package/src/watchdog/turn-delta.js +9 -5
  209. package/src/watchdog/turn-delta.js.map +1 -1
@@ -0,0 +1,18 @@
1
+ import type { AsyncStatus, ProcessTerminal, WorkflowChildSummary, WorkflowTerminalProof } from "../../shared/types.ts";
2
+ export declare function isTerminalAsyncState(state: AsyncStatus["state"]): boolean;
3
+ export type WorkflowChildProcessEvidence = {
4
+ state: "observed";
5
+ children: ProcessTerminal[];
6
+ } | {
7
+ state: "pending" | "unknown";
8
+ reason: string;
9
+ };
10
+ /**
11
+ * Process evidence for a workflow's async children. Status proofs and capacity
12
+ * release both use this so they cannot disagree about the same workflow.
13
+ * Synchronous children run inside the workflow host and have no process of their own.
14
+ */
15
+ export declare function readWorkflowChildProcessEvidence(workflowAsyncDir: string, steps: AsyncStatus["steps"]): WorkflowChildProcessEvidence;
16
+ /** A persistent workflow host is terminal only after dispatch closes and every async child has process evidence. */
17
+ export declare function readWorkflowTerminalProof(asyncDir: string, steps: AsyncStatus["steps"], summary: WorkflowChildSummary, hostCommandCount: number, closedAt: number): WorkflowTerminalProof;
18
+ //# sourceMappingURL=workflow-terminal-proof.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-terminal-proof.d.ts","sourceRoot":"","sources":["../../../../src/runs/background/workflow-terminal-proof.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAMvH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,GAAG,OAAO,CAEzE;AAED,MAAM,MAAM,4BAA4B,GACrC;IAAE,KAAK,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,eAAe,EAAE,CAAA;CAAE,GAClD;IAAE,KAAK,EAAE,SAAS,GAAG,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpD;;;;GAIG;AACH,wBAAgB,gCAAgC,CAAC,gBAAgB,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,GAAG,4BAA4B,CA2BpI;AAMD,oHAAoH;AACpH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,qBAAqB,CAYzL"}
@@ -0,0 +1,68 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ import { readStatus } from "../../shared/utils.js";
4
+ import { readProcessTerminal } from "./process-terminal.js";
5
+ const TERMINAL_WORKFLOW_STATES = new Set(["completed", "failed", "stopped"]);
6
+ export function isTerminalAsyncState(state) {
7
+ return state !== "queued" && state !== "running" && state !== "paused";
8
+ }
9
+ /**
10
+ * Process evidence for a workflow's async children. Status proofs and capacity
11
+ * release both use this so they cannot disagree about the same workflow.
12
+ * Synchronous children run inside the workflow host and have no process of their own.
13
+ */
14
+ export function readWorkflowChildProcessEvidence(workflowAsyncDir, steps) {
15
+ if (!steps)
16
+ return { state: "unknown", reason: "workflow child roster is missing" };
17
+ const children = [];
18
+ for (const step of steps) {
19
+ const label = step.workflowKey ?? step.agent;
20
+ if (typeof step.async !== "boolean")
21
+ return { state: "unknown", reason: `workflow child ${label} is missing async classification` };
22
+ if (!step.async)
23
+ continue;
24
+ if (!step.runId || path.basename(step.runId) !== step.runId)
25
+ return { state: "unknown", reason: `async workflow child ${label} is missing run id` };
26
+ const childDir = path.join(path.dirname(workflowAsyncDir), step.runId);
27
+ if (!fs.existsSync(childDir))
28
+ return { state: "unknown", reason: `async workflow child ${label} directory is missing` };
29
+ const childStatus = readStatus(childDir);
30
+ if (!childStatus)
31
+ return { state: "unknown", reason: `async workflow child ${label} status is missing or unreadable` };
32
+ if (!isTerminalAsyncState(childStatus.state))
33
+ return { state: "pending", reason: `async workflow child ${label} is still ${childStatus.state}` };
34
+ const recorded = childStatus.processTerminal;
35
+ if (!recorded?.runnerProcessInstanceId)
36
+ return { state: "unknown", reason: `async workflow child ${label} has no runner process identity` };
37
+ // A runner startup failure records `not-started` in status and never writes a process-terminal sidecar.
38
+ if (recorded.state === "not-started" && recorded.runId === step.runId && typeof childStatus.error === "string" && childStatus.error) {
39
+ children.push(recorded);
40
+ continue;
41
+ }
42
+ const proof = readProcessTerminal(childDir, { runId: step.runId, runnerProcessInstanceId: recorded.runnerProcessInstanceId });
43
+ if (proof?.state !== "observed" || proof.runId !== step.runId) {
44
+ return { state: !proof || proof.state === "pending" ? "pending" : "unknown", reason: `async workflow child ${label} process-terminal proof is ${proof?.state ?? "missing"}` };
45
+ }
46
+ children.push(proof);
47
+ }
48
+ return { state: "observed", children };
49
+ }
50
+ function unresolved(runId, state, dispatchClosed, reason) {
51
+ return { version: 1, kind: "workflow", runId, state, dispatchClosed, reason };
52
+ }
53
+ /** A persistent workflow host is terminal only after dispatch closes and every async child has process evidence. */
54
+ export function readWorkflowTerminalProof(asyncDir, steps, summary, hostCommandCount, closedAt) {
55
+ const runId = summary.workflowRunId;
56
+ if (!summary.inventoryComplete || !TERMINAL_WORKFLOW_STATES.has(summary.workflowState)) {
57
+ return unresolved(runId, "pending", false, "Workflow dispatch is still open.");
58
+ }
59
+ if (hostCommandCount > 0) {
60
+ return unresolved(runId, "unknown", true, "Workflow host commands have no process-terminal proof.");
61
+ }
62
+ const evidence = readWorkflowChildProcessEvidence(asyncDir, steps);
63
+ if (evidence.state !== "observed")
64
+ return unresolved(runId, evidence.state, true, evidence.reason);
65
+ const observedAt = Math.max(closedAt, ...evidence.children.map((child) => child.state === "observed" ? child.observedAt : 0));
66
+ return { version: 1, kind: "workflow", runId, state: "observed", dispatchClosed: true, observedAt, children: evidence.children };
67
+ }
68
+ //# sourceMappingURL=workflow-terminal-proof.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-terminal-proof.js","sourceRoot":"","sources":["../../../../src/runs/background/workflow-terminal-proof.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../../../../src/runs/foreground/execution.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EAA0E,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAWlI,OAAO,EAIN,KAAK,cAAc,EACnB,KAAK,YAAY,EAQjB,MAAM,uBAAuB,CAAC;AA89D/B;;;GAGG;AACH,wBAAsB,OAAO,CAC5B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,WAAW,EAAE,EACrB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,cAAc,GACrB,OAAO,CAAC,YAAY,CAAC,CAwHvB"}
1
+ {"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../../../../src/runs/foreground/execution.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EAA0E,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAWlI,OAAO,EAIN,KAAK,cAAc,EACnB,KAAK,YAAY,EAQjB,MAAM,uBAAuB,CAAC;AAo/D/B;;;GAGG;AACH,wBAAsB,OAAO,CAC5B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,WAAW,EAAE,EACrB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,cAAc,GACrB,OAAO,CAAC,YAAY,CAAC,CAwHvB"}
@@ -22,7 +22,7 @@ import { deriveChildSessionName } from "../../shared/child-session-name.js";
22
22
  import { assertAgentAllowedByCapabilityCeiling, intersectSubagentCapabilityCeilings, resolveCurrentSubagentCapabilityCeiling } from "../shared/capability-ceiling.js";
23
23
  import { resolveEffectiveThinking } from "../../shared/model-info.js";
24
24
  import { assertThinkingWithinCeiling, intersectThinkingCeilings } from "../../shared/thinking-ceiling.js";
25
- import { MISSING_STRUCTURED_ACCEPTANCE_REPORT_ERROR, MISSING_STRUCTURED_OUTPUT_CALL_ERROR } from "../shared/structured-output.js";
25
+ import { formatStructuredOutputRejectionError, MISSING_STRUCTURED_ACCEPTANCE_REPORT_ERROR, MISSING_STRUCTURED_OUTPUT_CALL_ERROR } from "../shared/structured-output.js";
26
26
  import { formatMidToolExitError, isOrdinaryToolForMidToolExit } from "../shared/process-signal.js";
27
27
  import { formatChildToolDiagnostic } from "../shared/tool-availability.js";
28
28
  import { formatChildModelResolutionDiagnostic, isChildModelResolutionFailure } from "../shared/model-resolution-diagnostic.js";
@@ -207,6 +207,7 @@ function captureStructuredDelegationProgressState(progress, result) {
207
207
  model: progress.model ?? result.model,
208
208
  toolCount: progress.toolCount,
209
209
  tokens: progress.tokens,
210
+ turnCount: progress.turnCount,
210
211
  };
211
212
  }
212
213
  function structuredDelegationProgressChanged(previous, progress, result) {
@@ -216,6 +217,7 @@ function structuredDelegationProgressChanged(previous, progress, result) {
216
217
  || previous.model !== (progress.model ?? result.model)
217
218
  || previous.toolCount !== progress.toolCount
218
219
  || previous.tokens !== progress.tokens
220
+ || previous.turnCount !== progress.turnCount
219
221
  || previous.recentOutput.length !== progress.recentOutput.length)
220
222
  return true;
221
223
  for (let index = 0; index < progress.recentOutput.length; index++) {
@@ -233,6 +235,9 @@ function structuredDelegationProgressChanged(previous, progress, result) {
233
235
  }
234
236
  return false;
235
237
  }
238
+ function isCompleteUsageCounter(value) {
239
+ return typeof value === "number" && Number.isFinite(value) && value >= 0;
240
+ }
236
241
  const STOPPED_BEFORE_COMPLETION_ERROR = "Subagent stopped before completion.";
237
242
  const AFTER_COMPACTION_SETTLEMENT = Symbol("afterCompactionSettlement");
238
243
  async function runSingleAttempt(runtimeCwd, agent, task, model, options, shared) {
@@ -372,6 +377,10 @@ async function runSingleAttempt(runtimeCwd, agent, task, model, options, shared)
372
377
  pendingControlEvents.push(event);
373
378
  options.onControlEvent?.(event);
374
379
  };
380
+ let inputUsageComplete = true;
381
+ let outputUsageComplete = true;
382
+ let cacheReadUsageComplete = true;
383
+ let cacheWriteUsageComplete = true;
375
384
  const progress = {
376
385
  index: options.index ?? 0,
377
386
  agent: agent.name,
@@ -385,12 +394,28 @@ async function runSingleAttempt(runtimeCwd, agent, task, model, options, shared)
385
394
  tokens: 0,
386
395
  ...(modelArg ? { model: modelArg } : {}),
387
396
  ...(resolvedThinking ? { thinking: resolvedThinking } : {}),
388
- inputTokens: 0,
389
- outputTokens: 0,
390
397
  durationMs: 0,
391
398
  lastActivityAt: startTime,
392
399
  };
393
400
  result.progress = progress;
401
+ const projectCompleteUsage = () => {
402
+ if (inputUsageComplete)
403
+ progress.inputTokens = result.usage.input;
404
+ else
405
+ delete progress.inputTokens;
406
+ if (outputUsageComplete)
407
+ progress.outputTokens = result.usage.output;
408
+ else
409
+ delete progress.outputTokens;
410
+ if (cacheReadUsageComplete)
411
+ progress.cacheRead = result.usage.cacheRead;
412
+ else
413
+ delete progress.cacheRead;
414
+ if (cacheWriteUsageComplete)
415
+ progress.cacheWrite = result.usage.cacheWrite;
416
+ else
417
+ delete progress.cacheWrite;
418
+ };
394
419
  const attemptTimeout = resolveAttemptTimeout(options);
395
420
  if (attemptTimeout?.remainingMs === 0) {
396
421
  result.exitCode = 1;
@@ -968,6 +993,10 @@ async function runSingleAttempt(runtimeCwd, agent, task, model, options, shared)
968
993
  const hasToolCall = toolCalls.length > 0;
969
994
  const terminalAssistantStop = evt.message.stopReason === "stop" && !hasToolCall;
970
995
  const u = evt.message.usage;
996
+ inputUsageComplete &&= isCompleteUsageCounter(u?.input);
997
+ outputUsageComplete &&= isCompleteUsageCounter(u?.output);
998
+ cacheReadUsageComplete &&= isCompleteUsageCounter(u?.cacheRead);
999
+ cacheWriteUsageComplete &&= isCompleteUsageCounter(u?.cacheWrite);
971
1000
  if (u) {
972
1001
  const window = (u.input || 0) + (u.cacheRead || 0);
973
1002
  result.usage.input += u.input || 0;
@@ -976,11 +1005,10 @@ async function runSingleAttempt(runtimeCwd, agent, task, model, options, shared)
976
1005
  result.usage.cacheWrite += u.cacheWrite || 0;
977
1006
  result.usage.cost += u.cost?.total || 0;
978
1007
  progress.tokens = result.usage.input + result.usage.output;
979
- progress.inputTokens = result.usage.input;
980
- progress.outputTokens = result.usage.output;
981
1008
  progress.window = window;
982
1009
  progress.windowPeak = Math.max(progress.windowPeak ?? 0, window);
983
1010
  }
1011
+ projectCompleteUsage();
984
1012
  if (evt.message.model) {
985
1013
  progress.model = evt.message.model;
986
1014
  if (!result.model)
@@ -1217,8 +1245,7 @@ async function runSingleAttempt(runtimeCwd, agent, task, model, options, shared)
1217
1245
  if (session && messageBaseline !== undefined) {
1218
1246
  result.usage = reconcileAttemptUsage(result.usage, session.messages, messageBaseline);
1219
1247
  progress.tokens = result.usage.input + result.usage.output;
1220
- progress.inputTokens = result.usage.input;
1221
- progress.outputTokens = result.usage.output;
1248
+ projectCompleteUsage();
1222
1249
  progress.turnCount = result.usage.turns;
1223
1250
  }
1224
1251
  finish(finalCode);
@@ -1351,16 +1378,11 @@ async function runSingleAttempt(runtimeCwd, agent, task, model, options, shared)
1351
1378
  result.exitCode = 1;
1352
1379
  }
1353
1380
  let validatedStructuredOutput = false;
1354
- if (options.structuredOutput && result.exitCode === 0 && !result.error) {
1381
+ if (options.structuredOutput) {
1355
1382
  result.structuredOutputSchemaPath = options.structuredOutput.schemaPath;
1356
1383
  result.structuredOutputPath = options.structuredOutput.outputPath;
1357
1384
  const structured = capture.structuredOutput();
1358
- if (!structuredOutputToolInvoked || !structured.called) {
1359
- result.exitCode = 1;
1360
- result.error = MISSING_STRUCTURED_OUTPUT_CALL_ERROR;
1361
- result.structuredOutputFailed = true;
1362
- }
1363
- else {
1385
+ if (structuredOutputToolInvoked && structured.called) {
1364
1386
  result.structuredOutput = structured.value;
1365
1387
  const acceptanceMode = options.structuredOutput.acceptanceReportPath
1366
1388
  ? options.structuredOutput.acceptanceReportRequired ? "required" : "optional"
@@ -1373,6 +1395,13 @@ async function runSingleAttempt(runtimeCwd, agent, task, model, options, shared)
1373
1395
  writeStructuredOutputArtifacts(options.structuredOutput, structured.value, acceptanceMode ? structured.acceptanceReport : undefined);
1374
1396
  validatedStructuredOutput = true;
1375
1397
  }
1398
+ else if (result.exitCode === 0 && !result.error) {
1399
+ result.exitCode = 1;
1400
+ result.error = structuredOutputToolInvoked
1401
+ ? formatStructuredOutputRejectionError(result.messages ?? [])
1402
+ : MISSING_STRUCTURED_OUTPUT_CALL_ERROR;
1403
+ result.structuredOutputFailed = true;
1404
+ }
1376
1405
  }
1377
1406
  if (result.exitCode === 0 && !result.error) {
1378
1407
  const messages = result.messages ?? [];