( continuation: AsyncContinuation, context: StreamingContext, execContext: ExecutionContext, options: CopilotLifecycleOptions, baseURL: string, workspaceId?: string )
| 481 | // caught (so Promise.all can't reject before its siblings unwind); we then |
| 482 | // rethrow the first REAL error, not the AbortErrors it triggered in the siblings. |
| 483 | async function driveSubagentChains( |
| 484 | continuation: AsyncContinuation, |
| 485 | context: StreamingContext, |
| 486 | execContext: ExecutionContext, |
| 487 | options: CopilotLifecycleOptions, |
| 488 | baseURL: string, |
| 489 | workspaceId?: string |
| 490 | ): Promise<AsyncContinuation | null> { |
| 491 | const frames = continuation.frames ?? [] |
| 492 | logger.info('Driving subagent checkpoint chains concurrently', { |
| 493 | childCount: frames.length, |
| 494 | checkpointIds: frames.map((f) => f.checkpointId), |
| 495 | }) |
| 496 | |
| 497 | const fanoutController = new AbortController() |
| 498 | const parentSignal = options.abortSignal |
| 499 | const onParentAbort = () => fanoutController.abort() |
| 500 | if (parentSignal) { |
| 501 | if (parentSignal.aborted) fanoutController.abort() |
| 502 | else parentSignal.addEventListener('abort', onParentAbort, { once: true }) |
| 503 | } |
| 504 | const legOptions: CopilotLifecycleOptions = { ...options, abortSignal: fanoutController.signal } |
| 505 | |
| 506 | let firstError: unknown |
| 507 | try { |
| 508 | const followOns = await Promise.all( |
| 509 | frames.map((frame) => |
| 510 | driveOneChildChain(frame, context, execContext, legOptions, baseURL, workspaceId).catch( |
| 511 | (error) => { |
| 512 | // First real failure wins and cancels the siblings; their resulting |
| 513 | // AbortErrors arrive later and don't overwrite it. Swallow here so |
| 514 | // Promise.all doesn't reject before every leg has unwound. |
| 515 | if (firstError === undefined) firstError = error |
| 516 | fanoutController.abort() |
| 517 | return null |
| 518 | } |
| 519 | ) |
| 520 | ) |
| 521 | ) |
| 522 | if (firstError !== undefined) throw firstError |
| 523 | return followOns.find((c): c is AsyncContinuation => !!c) ?? null |
| 524 | } finally { |
| 525 | parentSignal?.removeEventListener('abort', onParentAbort) |
| 526 | } |
| 527 | } |
| 528 | |
| 529 | // --------------------------------------------------------------------------- |
| 530 | // Checkpoint loop – the core state machine |
no test coverage detected