@gajae-code/coding-agent 0.12.0 → 0.12.2

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 (247) hide show
  1. package/CHANGELOG.md +111 -0
  2. package/dist/types/async/job-manager.d.ts +17 -3
  3. package/dist/types/config/settings-schema.d.ts +56 -2
  4. package/dist/types/exa/mcp-client.d.ts +10 -1
  5. package/dist/types/exec/bash-executor.d.ts +45 -12
  6. package/dist/types/extensibility/extensions/types.d.ts +16 -2
  7. package/dist/types/extensibility/gjc-plugins/index.d.ts +12 -2
  8. package/dist/types/extensibility/gjc-plugins/installer.d.ts +63 -7
  9. package/dist/types/extensibility/gjc-plugins/lifecycle-reconciliation.d.ts +55 -0
  10. package/dist/types/extensibility/gjc-plugins/lifecycle.d.ts +64 -0
  11. package/dist/types/extensibility/gjc-plugins/runtime-quarantine.d.ts +67 -0
  12. package/dist/types/extensibility/gjc-plugins/session-validation.d.ts +3 -1
  13. package/dist/types/extensibility/gjc-plugins/types.d.ts +124 -0
  14. package/dist/types/gjc-runtime/launch-tmux.d.ts +1 -0
  15. package/dist/types/gjc-runtime/ralplan-review-conflicts.d.ts +114 -0
  16. package/dist/types/gjc-runtime/ralplan-runtime.d.ts +23 -3
  17. package/dist/types/gjc-runtime/team-launch.d.ts +1 -1
  18. package/dist/types/gjc-runtime/team-runtime.d.ts +25 -0
  19. package/dist/types/gjc-runtime/team-worker-heartbeat.d.ts +43 -0
  20. package/dist/types/gjc-runtime/tmux-owner-isolation.d.ts +10 -0
  21. package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +37 -80
  22. package/dist/types/modes/acp/acp-agent.d.ts +2 -19
  23. package/dist/types/modes/components/gjc-bundle-settings.d.ts +34 -0
  24. package/dist/types/modes/components/irc-sidebar.d.ts +16 -0
  25. package/dist/types/modes/components/notifications-settings-editor.d.ts +1 -0
  26. package/dist/types/modes/components/session-observer-overlay.d.ts +18 -0
  27. package/dist/types/modes/components/settings-selector.d.ts +9 -0
  28. package/dist/types/modes/components/status-line/gh.d.ts +5 -0
  29. package/dist/types/modes/components/transcript-viewer-overlay.d.ts +18 -1
  30. package/dist/types/modes/controllers/command-controller.d.ts +1 -1
  31. package/dist/types/modes/controllers/event-controller.d.ts +1 -1
  32. package/dist/types/modes/controllers/extension-ui-controller.d.ts +2 -1
  33. package/dist/types/modes/controllers/selector-controller.d.ts +1 -1
  34. package/dist/types/modes/interactive-mode.d.ts +9 -0
  35. package/dist/types/modes/theme/theme.d.ts +3 -1
  36. package/dist/types/modes/types.d.ts +32 -0
  37. package/dist/types/reminders/star-reminder.d.ts +3 -13
  38. package/dist/types/runtime-mcp/manager.d.ts +1 -0
  39. package/dist/types/sdk/acp/adapter.d.ts +3 -1
  40. package/dist/types/sdk/broker/transport.d.ts +2 -0
  41. package/dist/types/sdk/bus/attachment-registry.d.ts +1 -0
  42. package/dist/types/sdk/bus/chat-daemon-control.d.ts +5 -1
  43. package/dist/types/sdk/bus/config.d.ts +6 -2
  44. package/dist/types/sdk/bus/index.d.ts +29 -0
  45. package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +8 -1
  46. package/dist/types/sdk/bus/lifecycle-control-runtime.d.ts +4 -0
  47. package/dist/types/sdk/bus/reconciliation-store.d.ts +7 -3
  48. package/dist/types/sdk/bus/rich-draft.d.ts +1 -0
  49. package/dist/types/sdk/bus/rich-render.d.ts +2 -0
  50. package/dist/types/sdk/bus/telegram-adoption-intent.d.ts +165 -0
  51. package/dist/types/sdk/bus/telegram-cli.d.ts +12 -0
  52. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +12 -4
  53. package/dist/types/sdk/bus/telegram-daemon.d.ts +25 -1
  54. package/dist/types/sdk/bus/telegram-reference.d.ts +11 -1
  55. package/dist/types/sdk/bus/threaded-render.d.ts +3 -2
  56. package/dist/types/sdk/bus/topic-registry.d.ts +11 -1
  57. package/dist/types/sdk/host/query/revision-store.d.ts +2 -0
  58. package/dist/types/sdk/host/reverse-leases.d.ts +1 -1
  59. package/dist/types/sdk/prompt-status.d.ts +23 -3
  60. package/dist/types/sdk/session.d.ts +6 -0
  61. package/dist/types/session/agent-session.d.ts +40 -2
  62. package/dist/types/session/artifacts.d.ts +8 -0
  63. package/dist/types/session/blob-store.d.ts +57 -4
  64. package/dist/types/session/internal/managed-session-storage.d.ts +30 -4
  65. package/dist/types/session/session-manager.d.ts +23 -6
  66. package/dist/types/session/session-storage.d.ts +4 -0
  67. package/dist/types/session/streaming-output.d.ts +36 -7
  68. package/dist/types/setup/credential-import.d.ts +12 -0
  69. package/dist/types/skill-state/active-state.d.ts +12 -0
  70. package/dist/types/skill-state/workflow-hud.d.ts +6 -0
  71. package/dist/types/task/executor.d.ts +3 -2
  72. package/dist/types/task/index.d.ts +7 -1
  73. package/dist/types/task/output-manager.d.ts +1 -0
  74. package/dist/types/task/provider-retry-status.d.ts +8 -0
  75. package/dist/types/task/receipt.d.ts +9 -1
  76. package/dist/types/task/types.d.ts +23 -0
  77. package/dist/types/tools/ask-answer-registry.d.ts +2 -2
  78. package/dist/types/tools/bash-interactive.d.ts +4 -1
  79. package/dist/types/tools/bash.d.ts +3 -1
  80. package/dist/types/tools/image-gen.d.ts +4 -0
  81. package/dist/types/tools/index.d.ts +6 -0
  82. package/dist/types/tools/output-meta.d.ts +23 -2
  83. package/dist/types/tools/path-utils.d.ts +1 -0
  84. package/dist/types/tools/read.d.ts +0 -6
  85. package/dist/types/tools/review.d.ts +5 -7
  86. package/dist/types/tools/subagent.d.ts +2 -0
  87. package/dist/types/utils/gh.d.ts +13 -0
  88. package/dist/types/utils/image-resize.d.ts +1 -0
  89. package/dist/types/web/search/providers/kimi.d.ts +2 -0
  90. package/dist/types/web/search/providers/searxng.d.ts +7 -0
  91. package/dist/types/web/search/providers/xai.d.ts +2 -0
  92. package/package.json +10 -8
  93. package/scripts/acp-conformance-agent.ts +218 -0
  94. package/scripts/capture-gjc-bundle-settings.ts +306 -0
  95. package/scripts/dogfood-ralplan-review-conflicts.ts +272 -0
  96. package/scripts/generate-sdk-operation-inventory.ts +5 -0
  97. package/scripts/resident-memory-bench.ts +1341 -0
  98. package/scripts/run-acp-conformance.ts +290 -0
  99. package/src/async/job-manager.ts +99 -39
  100. package/src/cli/fast-help.ts +1 -1
  101. package/src/cli/plugin-cli.ts +176 -18
  102. package/src/commands/team.ts +19 -1
  103. package/src/config/file-lock.ts +11 -2
  104. package/src/config/settings-schema.ts +53 -2
  105. package/src/coordinator-mcp/question-gate-codec.ts +1 -1
  106. package/src/coordinator-mcp/server.ts +5 -12
  107. package/src/debug/index.ts +42 -17
  108. package/src/defaults/gjc/skills/deep-interview/SKILL.md +1 -0
  109. package/src/defaults/gjc/skills/ralplan/SKILL.md +25 -20
  110. package/src/defaults/gjc/skills/team/SKILL.md +2 -0
  111. package/src/defaults/gjc/skills/ultragoal/SKILL.md +39 -26
  112. package/src/defaults/gjc/skills/ultragoal/validation-batch-contracts.md +12 -0
  113. package/src/defaults/gjc-defaults.ts +4 -4
  114. package/src/exa/mcp-client.ts +12 -3
  115. package/src/exec/bash-executor.ts +144 -27
  116. package/src/extensibility/extensions/runner.ts +15 -0
  117. package/src/extensibility/extensions/types.ts +18 -1
  118. package/src/extensibility/gjc-plugins/constrained-hooks.ts +8 -2
  119. package/src/extensibility/gjc-plugins/index.ts +19 -2
  120. package/src/extensibility/gjc-plugins/installer.ts +189 -50
  121. package/src/extensibility/gjc-plugins/lifecycle-reconciliation.ts +199 -0
  122. package/src/extensibility/gjc-plugins/lifecycle.ts +626 -0
  123. package/src/extensibility/gjc-plugins/observability.ts +3 -3
  124. package/src/extensibility/gjc-plugins/prompt-appendix.ts +5 -1
  125. package/src/extensibility/gjc-plugins/runtime-adapters.ts +12 -2
  126. package/src/extensibility/gjc-plugins/runtime-quarantine.ts +121 -0
  127. package/src/extensibility/gjc-plugins/schema.ts +84 -12
  128. package/src/extensibility/gjc-plugins/session-validation.ts +9 -3
  129. package/src/extensibility/gjc-plugins/types.ts +141 -0
  130. package/src/extensibility/gjc-plugins/validation.ts +9 -0
  131. package/src/gjc-runtime/launch-tmux.ts +25 -6
  132. package/src/gjc-runtime/launch-worktree.ts +103 -1
  133. package/src/gjc-runtime/ledger-event-renderer.ts +1 -0
  134. package/src/gjc-runtime/managed-owner-admission.ts +1 -1
  135. package/src/gjc-runtime/ralplan-review-conflicts.ts +472 -0
  136. package/src/gjc-runtime/ralplan-runtime.ts +491 -27
  137. package/src/gjc-runtime/team-launch.ts +8 -0
  138. package/src/gjc-runtime/team-runtime.ts +140 -32
  139. package/src/gjc-runtime/team-worker-heartbeat.ts +149 -0
  140. package/src/gjc-runtime/tmux-owner-isolation.ts +10 -0
  141. package/src/gjc-runtime/tmux-sessions.ts +58 -13
  142. package/src/gjc-runtime/ultragoal-evidence.ts +6 -74
  143. package/src/gjc-runtime/ultragoal-runtime.ts +635 -612
  144. package/src/gjc-runtime/workflow-manifest.generated.json +37 -99
  145. package/src/gjc-runtime/workflow-manifest.ts +21 -70
  146. package/src/internal-urls/docs-index.generated.ts +16 -16
  147. package/src/modes/DESIGN.md +104 -0
  148. package/src/modes/acp/acp-agent.ts +298 -186
  149. package/src/modes/components/gjc-bundle-settings.ts +508 -0
  150. package/src/modes/components/irc-sidebar.ts +30 -1
  151. package/src/modes/components/notifications-settings-editor.ts +12 -1
  152. package/src/modes/components/oauth-selector.ts +68 -30
  153. package/src/modes/components/session-observer-overlay.ts +305 -86
  154. package/src/modes/components/settings-selector.ts +56 -5
  155. package/src/modes/components/status-line/gh.ts +16 -0
  156. package/src/modes/components/tool-status-header.ts +3 -15
  157. package/src/modes/components/transcript-viewer-overlay.ts +99 -24
  158. package/src/modes/controllers/command-controller.ts +42 -34
  159. package/src/modes/controllers/event-controller.ts +27 -16
  160. package/src/modes/controllers/extension-ui-controller.ts +193 -34
  161. package/src/modes/controllers/selector-controller.ts +160 -22
  162. package/src/modes/interactive-mode.ts +189 -62
  163. package/src/modes/jobs-observer.ts +1 -1
  164. package/src/modes/runtime-init.ts +3 -0
  165. package/src/modes/theme/theme.ts +11 -9
  166. package/src/modes/types.ts +88 -0
  167. package/src/prompts/agent-fragments/ralplan-persistence.md +4 -3
  168. package/src/prompts/system/eager-todo.md +8 -4
  169. package/src/prompts/system/system-prompt.md +11 -4
  170. package/src/prompts/tools/bash.md +5 -5
  171. package/src/prompts/tools/search-tool-bm25.md +5 -0
  172. package/src/prompts/tools/task.md +1 -1
  173. package/src/reminders/star-reminder.ts +4 -42
  174. package/src/runtime-mcp/manager.ts +19 -4
  175. package/src/sdk/acp/adapter.ts +22 -6
  176. package/src/sdk/broker/lifecycle.ts +18 -13
  177. package/src/sdk/broker/transport.ts +35 -3
  178. package/src/sdk/bus/attachment-registry.ts +5 -1
  179. package/src/sdk/bus/chat-daemon-cli.ts +4 -39
  180. package/src/sdk/bus/chat-daemon-control.ts +7 -3
  181. package/src/sdk/bus/config.ts +18 -2
  182. package/src/sdk/bus/index.ts +661 -126
  183. package/src/sdk/bus/kind-aware-reconciliation.ts +148 -73
  184. package/src/sdk/bus/lifecycle-commands.ts +4 -1
  185. package/src/sdk/bus/lifecycle-control-runtime.ts +403 -88
  186. package/src/sdk/bus/reconciliation-store.ts +95 -16
  187. package/src/sdk/bus/rich-draft.ts +1 -1
  188. package/src/sdk/bus/rich-render.ts +2 -2
  189. package/src/sdk/bus/telegram-adoption-intent.ts +574 -0
  190. package/src/sdk/bus/telegram-cli.ts +33 -8
  191. package/src/sdk/bus/telegram-daemon-cli.ts +1 -0
  192. package/src/sdk/bus/telegram-daemon-contract.ts +12 -4
  193. package/src/sdk/bus/telegram-daemon.ts +916 -23
  194. package/src/sdk/bus/telegram-reference.ts +40 -3
  195. package/src/sdk/bus/threaded-render.ts +48 -3
  196. package/src/sdk/bus/topic-registry.ts +20 -0
  197. package/src/sdk/host/query/revision-store.ts +36 -2
  198. package/src/sdk/host/reverse-leases.ts +44 -7
  199. package/src/sdk/prompt-status.ts +16 -3
  200. package/src/sdk/protocol/operation-inventory.generated.json +33 -0
  201. package/src/sdk/session.ts +89 -9
  202. package/src/session/agent-session.ts +844 -173
  203. package/src/session/artifacts.ts +22 -0
  204. package/src/session/auth-broker-config.ts +10 -3
  205. package/src/session/blob-store.ts +915 -24
  206. package/src/session/internal/managed-session-scope.ts +200 -111
  207. package/src/session/internal/managed-session-storage.ts +492 -62
  208. package/src/session/session-manager.ts +1614 -435
  209. package/src/session/session-storage.ts +38 -45
  210. package/src/session/streaming-output.ts +238 -68
  211. package/src/setup/credential-import.ts +75 -13
  212. package/src/skill-state/active-state.ts +32 -0
  213. package/src/skill-state/workflow-hud.ts +17 -0
  214. package/src/skill-state/workflow-mutation-guard.ts +496 -2
  215. package/src/task/executor.ts +122 -39
  216. package/src/task/index.ts +280 -45
  217. package/src/task/output-manager.ts +24 -14
  218. package/src/task/provider-retry-status.ts +16 -0
  219. package/src/task/receipt.ts +34 -8
  220. package/src/task/render.ts +6 -2
  221. package/src/task/types.ts +108 -0
  222. package/src/tools/ask-answer-registry.ts +12 -6
  223. package/src/tools/ask.ts +86 -55
  224. package/src/tools/ast-edit.ts +1 -0
  225. package/src/tools/ast-grep.ts +1 -0
  226. package/src/tools/bash-interactive.ts +8 -3
  227. package/src/tools/bash.ts +503 -60
  228. package/src/tools/find.ts +1 -0
  229. package/src/tools/image-gen.ts +29 -5
  230. package/src/tools/index.ts +6 -0
  231. package/src/tools/output-meta.ts +108 -14
  232. package/src/tools/path-utils.ts +3 -2
  233. package/src/tools/read.ts +18 -0
  234. package/src/tools/review.ts +5 -7
  235. package/src/tools/search.ts +1 -0
  236. package/src/tools/subagent-render.ts +6 -2
  237. package/src/tools/subagent.ts +6 -0
  238. package/src/tools/telegram-send.ts +6 -3
  239. package/src/utils/gh.ts +39 -0
  240. package/src/utils/image-resize.ts +3 -0
  241. package/src/web/search/providers/anthropic.ts +4 -4
  242. package/src/web/search/providers/kimi.ts +15 -5
  243. package/src/web/search/providers/searxng.ts +47 -4
  244. package/src/web/search/providers/xai.ts +7 -2
  245. package/dist/types/gjc-runtime/ultragoal-pipeline.d.ts +0 -23
  246. package/src/defaults/gjc/skills/ultragoal/pipeline-validation-contracts.md +0 -30
  247. package/src/gjc-runtime/ultragoal-pipeline.ts +0 -306
@@ -44,23 +44,25 @@ import { SessionManager } from "../session/session-manager";
44
44
  import { truncateTail } from "../session/streaming-output";
45
45
  import type { ContextFileEntry } from "../tools";
46
46
  import { jtdToJsonSchema, normalizeSchema } from "../tools/jtd-to-json-schema";
47
- import { type ReportFindingDetails, toReviewFinding } from "../tools/review";
47
+ import type { ReportFindingDetails } from "../tools/review";
48
48
  import { ToolAbortError } from "../tools/tool-errors";
49
49
  import type { EventBus } from "../utils/event-bus";
50
50
  import { buildNamedToolChoiceResult } from "../utils/tool-choice";
51
51
  import type { WorkspaceTree } from "../workspace-tree";
52
52
  import { validateAllocatedTaskId } from "./id";
53
- import { classifyProviderRetry, providerNameFromModel } from "./provider-retry-status";
53
+ import { classifyProviderRetryFromTransport, providerNameFromModel } from "./provider-retry-status";
54
54
  import { subprocessToolRegistry } from "./subprocess-tool-registry";
55
55
  import { persistTaskTokenLog, taskTokenLogFromUsage } from "./token-log";
56
56
  import {
57
57
  type AgentDefinition,
58
58
  type AgentProgress,
59
+ createSetupFailureSummary,
59
60
  hasCompleteUsageCostBreakdown,
60
61
  MAX_OUTPUT_BYTES,
61
62
  MAX_OUTPUT_LINES,
62
63
  type ModelSubstitutionWarning,
63
- type ReviewFinding,
64
+ type ReviewFindingsArtifactRef,
65
+ type SetupFailureSummary,
64
66
  type SingleResult,
65
67
  TASK_SUBAGENT_EVENT_CHANNEL,
66
68
  TASK_SUBAGENT_LIFECYCLE_CHANNEL,
@@ -241,6 +243,8 @@ export interface ExecutorOptions {
241
243
  * subagents, and a main-model fast-mode auto-disable does not clobber it.
242
244
  */
243
245
  inheritedServiceTier?: ServiceTier;
246
+ /** Resolve whether the effective subagent tier grants fast mode for the selected provider. */
247
+ isFastForSubagentProvider?: (provider?: string) => boolean;
244
248
  /** Override local:// protocol options so subagent shares parent's local:// root */
245
249
  localProtocolOptions?: LocalProtocolOptions;
246
250
  /**
@@ -291,11 +295,13 @@ export class ManagedTaskPersistence {
291
295
  }
292
296
 
293
297
  async publishOutput(rawOutput: string, metadata: Uint8Array): Promise<void> {
294
- await this.#artifacts.publishManagedOutputGeneration(
295
- `${this.#taskId}.md.selector.json`,
296
- `${this.#taskId}.md`,
297
- Buffer.from(rawOutput, "utf8"),
298
- metadata,
298
+ await withArtifactManagerFinalizationTurn(this.#artifacts, () =>
299
+ this.#artifacts.publishManagedOutputGeneration(
300
+ `${this.#taskId}.md.selector.json`,
301
+ `${this.#taskId}.md`,
302
+ Buffer.from(rawOutput, "utf8"),
303
+ metadata,
304
+ ),
299
305
  );
300
306
  }
301
307
  }
@@ -304,6 +310,59 @@ export function createManagedTaskPersistence(artifacts: ArtifactManager, taskId:
304
310
  return new ManagedTaskPersistence(artifacts, taskId);
305
311
  }
306
312
 
313
+ const MAX_REVIEW_FINDINGS_ARTIFACT_BYTES = 16 * 1024 * 1024;
314
+ const REVIEW_FINDINGS_ARTIFACT_FAILURE = "Review findings artifact publication failed.";
315
+ const artifactManagerFinalizationTails = new WeakMap<ArtifactManager, Promise<void>>();
316
+
317
+ interface ReviewFindingsArtifactPayload {
318
+ version: 1;
319
+ kind: "review-findings";
320
+ taskId: string;
321
+ findingCount: number;
322
+ findings: ReportFindingDetails[];
323
+ }
324
+
325
+ async function withArtifactManagerFinalizationTurn<T>(
326
+ manager: ArtifactManager,
327
+ operation: () => Promise<T>,
328
+ ): Promise<T> {
329
+ const priorTail = artifactManagerFinalizationTails.get(manager);
330
+ const turn = Promise.withResolvers<void>();
331
+ artifactManagerFinalizationTails.set(manager, turn.promise);
332
+
333
+ try {
334
+ await priorTail?.catch(() => undefined);
335
+ return await operation();
336
+ } finally {
337
+ turn.resolve();
338
+ if (artifactManagerFinalizationTails.get(manager) === turn.promise) {
339
+ artifactManagerFinalizationTails.delete(manager);
340
+ }
341
+ }
342
+ }
343
+
344
+ async function publishReviewFindingsArtifact(
345
+ manager: ArtifactManager,
346
+ taskId: string,
347
+ findings: ReportFindingDetails[],
348
+ ): Promise<ReviewFindingsArtifactRef> {
349
+ const payload: ReviewFindingsArtifactPayload = {
350
+ version: 1,
351
+ kind: "review-findings",
352
+ taskId,
353
+ findingCount: findings.length,
354
+ findings,
355
+ };
356
+ const serialized = JSON.stringify(payload, null, 2);
357
+ const sizeBytes = Buffer.byteLength(serialized, "utf8");
358
+ if (sizeBytes > MAX_REVIEW_FINDINGS_ARTIFACT_BYTES) throw new Error("review findings artifact exceeds limit");
359
+ const sha256 = createHash("sha256").update(serialized).digest("hex");
360
+ const artifactId = await withArtifactManagerFinalizationTurn(manager, () =>
361
+ manager.save(serialized, "review-findings", { maxBytes: sizeBytes }),
362
+ );
363
+ return { uri: `artifact://${artifactId}`, sizeBytes, sha256, findingCount: findings.length };
364
+ }
365
+
307
366
  export function renderSubagentUserPrompt(assignment: string, independentMode: boolean): string {
308
367
  return prompt.render(subagentUserPromptTemplate, { assignment: assignment.trim(), independentMode });
309
368
  }
@@ -439,21 +498,8 @@ function extractCompletionData(parsed: unknown): unknown {
439
498
  return parsed;
440
499
  }
441
500
 
442
- function normalizeCompleteData(data: unknown, reportFindings?: ReviewFinding[]): unknown {
443
- let normalized = parseStringifiedJson(data ?? null);
444
- if (
445
- Array.isArray(reportFindings) &&
446
- reportFindings.length > 0 &&
447
- normalized &&
448
- typeof normalized === "object" &&
449
- !Array.isArray(normalized)
450
- ) {
451
- const record = normalized as Record<string, unknown>;
452
- if (!("findings" in record)) {
453
- normalized = { ...record, findings: reportFindings };
454
- }
455
- }
456
- return normalized;
501
+ function normalizeCompleteData(data: unknown): unknown {
502
+ return parseStringifiedJson(data ?? null);
457
503
  }
458
504
 
459
505
  function resolveFallbackCompletion(rawOutput: string, outputSchema: unknown): { data: unknown } | null {
@@ -480,7 +526,6 @@ interface FinalizeSubprocessOutputArgs {
480
526
  doneAborted: boolean;
481
527
  signalAborted: boolean;
482
528
  yieldItems?: YieldItem[];
483
- reportFindings?: ReviewFinding[];
484
529
  outputSchema: unknown;
485
530
  }
486
531
 
@@ -541,7 +586,7 @@ function buildPlaceholderYieldOutcome(
541
586
 
542
587
  export function finalizeSubprocessOutput(args: FinalizeSubprocessOutputArgs): FinalizeSubprocessOutputResult {
543
588
  let { rawOutput, exitCode, stderr } = args;
544
- const { yieldItems, reportFindings, doneAborted, signalAborted, outputSchema } = args;
589
+ const { yieldItems, doneAborted, signalAborted, outputSchema } = args;
545
590
  let abortedViaYield = false;
546
591
  const hasYield = Array.isArray(yieldItems) && yieldItems.length > 0;
547
592
 
@@ -561,7 +606,7 @@ export function finalizeSubprocessOutput(args: FinalizeSubprocessOutputArgs): Fi
561
606
  if (submitData === null || submitData === undefined) {
562
607
  rawOutput = rawOutput ? `${SUBAGENT_WARNING_NULL_YIELD}\n\n${rawOutput}` : SUBAGENT_WARNING_NULL_YIELD;
563
608
  } else {
564
- const completeData = normalizeCompleteData(submitData, reportFindings);
609
+ const completeData = normalizeCompleteData(submitData);
565
610
  const { validator, error: schemaError } = buildOutputValidator(outputSchema);
566
611
  if (schemaError) {
567
612
  const outcome = buildSchemaViolationOutcome(
@@ -608,7 +653,7 @@ export function finalizeSubprocessOutput(args: FinalizeSubprocessOutputArgs): Fi
608
653
  const hasOutputSchema = normalizedSchema !== undefined && !schemaError;
609
654
  const fallback = allowFallback ? resolveFallbackCompletion(rawOutput, outputSchema) : null;
610
655
  if (fallback) {
611
- const completeData = normalizeCompleteData(fallback.data, reportFindings);
656
+ const completeData = normalizeCompleteData(fallback.data);
612
657
  const { validator } = buildOutputValidator(outputSchema);
613
658
  const placeholderPath = findPlaceholderYieldPath(completeData);
614
659
  if (placeholderPath) {
@@ -873,6 +918,7 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
873
918
  let sessionEventOrdinal = 0;
874
919
  let retryStartOrdinal = 0;
875
920
  const seenAssistantMessages = new WeakSet<AgentMessage>();
921
+ let llmRequestStarted = false;
876
922
  const seenAssistantMessageIdentities = new Set<string>();
877
923
 
878
924
  // Accumulate usage incrementally from message_end events (no memory for streaming events)
@@ -965,7 +1011,7 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
965
1011
  task,
966
1012
  assignment,
967
1013
  progress: progressSnapshot,
968
- sessionFile: null,
1014
+ sessionFile: sessionFile ?? undefined,
969
1015
  });
970
1016
  }
971
1017
  lastProgressEmitMs = Date.now();
@@ -1380,6 +1426,7 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
1380
1426
  error?: string;
1381
1427
  aborted?: boolean;
1382
1428
  abortReason?: string;
1429
+ setupFailure?: SetupFailureSummary;
1383
1430
  durationMs: number;
1384
1431
  }> => {
1385
1432
  const sessionAbortController = new AbortController();
@@ -1387,6 +1434,7 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
1387
1434
  let error: string | undefined;
1388
1435
  let aborted = false;
1389
1436
  let abortReasonText: string | undefined;
1437
+ let setupFailure: SetupFailureSummary | undefined;
1390
1438
  const checkAbort = () => {
1391
1439
  if (abortSignal.aborted) {
1392
1440
  aborted = abortReason === "signal" || runtimeLimitExceeded || abortReason === undefined;
@@ -1463,6 +1511,7 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
1463
1511
  resolvedModelString = formatModelString(model);
1464
1512
  activeProviderModelString = resolvedModelString;
1465
1513
  }
1514
+ progress.fastMode = model ? (options.isFastForSubagentProvider?.(model.provider) ?? false) : false;
1466
1515
  if (authFallbackUsed && model && requestedModel) {
1467
1516
  modelSubstitutionWarning = {
1468
1517
  requested: formatModelString(requestedModel),
@@ -1706,7 +1755,7 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
1706
1755
  agentSource: agent.source,
1707
1756
  description: options.description,
1708
1757
  status: "started",
1709
- sessionFile: null,
1758
+ sessionFile: sessionFile ?? undefined,
1710
1759
  index,
1711
1760
  });
1712
1761
  }
@@ -1801,7 +1850,9 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
1801
1850
  {
1802
1851
  getModel: () => session.model,
1803
1852
  isIdle: () => !session.isStreaming,
1853
+ getActivePromptHandle: () => session.activePromptHandle,
1804
1854
  abort: () => session.abort(),
1855
+ abortPromptAndWait: (handle, options) => session.abortPromptAndWait(handle, options),
1805
1856
  hasPendingMessages: () => session.queuedMessageCount > 0,
1806
1857
  getPendingMessageCounts: () => session.pendingMessageCounts,
1807
1858
  getTranscript: () => session.getTranscript(),
@@ -1842,11 +1893,15 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
1842
1893
  for (const message of session.messages) {
1843
1894
  if (message.role === "assistant") rememberAssistantMessage(message);
1844
1895
  }
1896
+ const failedAssistant = session.getLastAssistantMessage();
1845
1897
  progress.retryState = {
1846
1898
  attempt: event.attempt,
1847
1899
  maxAttempts: event.maxAttempts,
1848
1900
  unbounded: event.unbounded,
1849
- kind: classifyProviderRetry(event.errorMessage),
1901
+ kind: classifyProviderRetryFromTransport({
1902
+ providerCode: failedAssistant?.transportFailure?.providerCode,
1903
+ errorMessage: event.errorMessage,
1904
+ }),
1850
1905
  provider: providerNameFromModel(
1851
1906
  activeProviderModelString ?? lastAssistantModelString ?? resolvedModelString,
1852
1907
  ),
@@ -1905,16 +1960,24 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
1905
1960
  }
1906
1961
  }
1907
1962
  const runMode = options.runMode ?? "initial";
1963
+ const markLlmRequestStarted = () => {
1964
+ llmRequestStarted = true;
1965
+ };
1966
+ const promptOptions = {
1967
+ attribution: "agent" as const,
1968
+ // A prompt is an LLM request only after AgentSession accepts its
1969
+ // preflight fence. Rejections remain setup failures.
1970
+ onPreflightAccepted: markLlmRequestStarted,
1971
+ onPreflightAcceptCommit: markLlmRequestStarted,
1972
+ };
1908
1973
  if (runMode === "message") {
1909
- await awaitAbortable(session.prompt(options.resumeMessage ?? "", { attribution: "agent" }));
1974
+ await awaitAbortable(session.prompt(options.resumeMessage ?? "", promptOptions));
1910
1975
  await awaitAbortable(session.waitForIdle());
1911
1976
  } else if (runMode === "resume") {
1912
- await awaitAbortable(
1913
- session.prompt("Continue from the paused subagent session state.", { attribution: "agent" }),
1914
- );
1977
+ await awaitAbortable(session.prompt("Continue from the paused subagent session state.", promptOptions));
1915
1978
  await awaitAbortable(session.waitForIdle());
1916
1979
  } else {
1917
- await awaitAbortable(session.prompt(task, { attribution: "agent" }));
1980
+ await awaitAbortable(session.prompt(task, promptOptions));
1918
1981
  await awaitAbortable(session.waitForIdle());
1919
1982
  }
1920
1983
 
@@ -1991,6 +2054,7 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
1991
2054
  exitCode = 1;
1992
2055
  if (!abortSignal.aborted) {
1993
2056
  error = err instanceof Error ? err.stack || err.message : String(err);
2057
+ if (!llmRequestStarted) setupFailure = createSetupFailureSummary(err);
1994
2058
  }
1995
2059
  } finally {
1996
2060
  if (abortSignal.aborted) {
@@ -2026,6 +2090,7 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
2026
2090
  error,
2027
2091
  aborted,
2028
2092
  abortReason: aborted ? abortReasonText : undefined,
2093
+ setupFailure,
2029
2094
  durationMs: Date.now() - startTime,
2030
2095
  };
2031
2096
  };
@@ -2052,7 +2117,6 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
2052
2117
  let rawOutput = finalOutputChunks.length > 0 ? finalOutputChunks.join("") : outputChunks.join("");
2053
2118
  const yieldItems = progress.extractedToolData?.yield as YieldItem[] | undefined;
2054
2119
  const reportFindingDetails = progress.extractedToolData?.report_finding as ReportFindingDetails[] | undefined;
2055
- const reportFindings: ReviewFinding[] | undefined = reportFindingDetails?.map(toReviewFinding);
2056
2120
  const finalized = finalizeSubprocessOutput({
2057
2121
  rawOutput,
2058
2122
  exitCode,
@@ -2060,12 +2124,25 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
2060
2124
  doneAborted: Boolean(done.aborted),
2061
2125
  signalAborted: Boolean(signal?.aborted),
2062
2126
  yieldItems,
2063
- reportFindings,
2064
2127
  outputSchema,
2065
2128
  });
2066
2129
  rawOutput = finalized.rawOutput;
2067
2130
  exitCode = finalized.exitCode;
2068
2131
  stderr = finalized.stderr;
2132
+ let reviewFindingsRef: ReviewFindingsArtifactRef | undefined;
2133
+ let reviewFindingsPublicationFailed = false;
2134
+ if (reportFindingDetails && reportFindingDetails.length > 0) {
2135
+ try {
2136
+ const manager = options.parentArtifactManager;
2137
+ if (!manager) throw new Error("review findings artifact authority unavailable");
2138
+ reviewFindingsRef = await publishReviewFindingsArtifact(manager, id, reportFindingDetails);
2139
+ } catch {
2140
+ reviewFindingsPublicationFailed = true;
2141
+ exitCode = 1;
2142
+ stderr = REVIEW_FINDINGS_ARTIFACT_FAILURE;
2143
+ paused = false;
2144
+ }
2145
+ }
2069
2146
  const lastYield = yieldItems?.[yieldItems.length - 1];
2070
2147
  const yieldAbortReason = lastYield?.status === "aborted" ? lastYield.error || "Subagent aborted task" : undefined;
2071
2148
  const { abortedViaYield, hasYield } = finalized;
@@ -2122,7 +2199,9 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
2122
2199
  exitCode = 1;
2123
2200
  }
2124
2201
  const wasAborted =
2125
- runtimeLimitExceeded || abortedViaYield || (!hasYield && (done.aborted || signal?.aborted || false));
2202
+ runtimeLimitExceeded ||
2203
+ (!reviewFindingsPublicationFailed &&
2204
+ (abortedViaYield || (!hasYield && (done.aborted || signal?.aborted || false))));
2126
2205
  const finalAbortReason = wasAborted
2127
2206
  ? runtimeLimitExceeded
2128
2207
  ? resolveAbortReasonText()
@@ -2130,6 +2209,7 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
2130
2209
  ? yieldAbortReason
2131
2210
  : (done.abortReason ?? (signal?.aborted ? resolveSignalAbortReason() : resolveAbortReasonText()))
2132
2211
  : undefined;
2212
+ progress.setupFailure = done.setupFailure;
2133
2213
  progress.status = paused ? "paused" : wasAborted ? "aborted" : exitCode === 0 ? "completed" : "failed";
2134
2214
  scheduleProgress(true);
2135
2215
 
@@ -2141,7 +2221,7 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
2141
2221
  agentSource: agent.source,
2142
2222
  description: options.description,
2143
2223
  status: progress.status as "completed" | "failed" | "aborted" | "paused",
2144
- sessionFile: null,
2224
+ sessionFile: sessionFile ?? undefined,
2145
2225
  index,
2146
2226
  });
2147
2227
  }
@@ -2165,7 +2245,9 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
2165
2245
  contextWindow: progress.contextWindow,
2166
2246
  modelOverride,
2167
2247
  modelSubstitutionWarning,
2248
+ fastMode: progress.fastMode,
2168
2249
  error: exitCode !== 0 && stderr ? stderr : undefined,
2250
+ setupFailure: done.setupFailure,
2169
2251
  aborted: wasAborted,
2170
2252
  abortReason: finalAbortReason,
2171
2253
  paused,
@@ -2175,5 +2257,6 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
2175
2257
  extractedToolData: progress.extractedToolData,
2176
2258
  retryFailure: progress.retryFailure,
2177
2259
  outputMeta,
2260
+ reviewFindingsRef,
2178
2261
  };
2179
2262
  }