pi-subagents 0.58.0 → 0.59.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.
- package/CHANGELOG.md +65 -0
- package/docs/agents.md +5 -3
- package/docs/configuration.md +4 -4
- package/docs/extension-api.md +1 -1
- package/docs/models.md +24 -1
- package/docs/observability.md +1 -1
- package/docs/tool-reference.md +89 -4
- package/docs/workflows.md +93 -2
- package/package.json +3 -1
- package/prompts/review-loop.md +2 -2
- package/skills/council-mode/SKILL.md +1 -1
- package/skills/pi-subagents/SKILL.md +1 -1
- package/skills/pi-subagents/references/execution-controls.md +5 -1
- package/skills/pi-subagents/references/management-authoring-rpc.md +1 -2
- package/skills/pi-subagents/references/prompting-and-roles.md +24 -3
- package/src/agents/agent-management.ts +5 -17
- package/src/agents/agent-serializer.ts +4 -2
- package/src/agents/agents.ts +67 -26
- package/src/agents/runtime-agent-registry.ts +9 -16
- package/src/api/background-work.ts +5 -1
- package/src/api/delegation.ts +0 -7
- package/src/api/preflight.ts +6 -9
- package/src/extension/fanout-child.ts +5 -3
- package/src/extension/index.ts +51 -23
- package/src/extension/public-execution.ts +15 -2
- package/src/extension/schemas.ts +35 -10
- package/src/extension/tool-description.ts +18 -3
- package/src/intercom/result-intercom.ts +2 -0
- package/src/profiles/profiles.ts +5 -6
- package/src/runs/background/active-async-capacity.ts +2 -2
- package/src/runs/background/async-execution.ts +50 -35
- package/src/runs/background/async-job-tracker.ts +14 -12
- package/src/runs/background/async-resume.ts +23 -25
- package/src/runs/background/async-status-snapshot.ts +23 -261
- package/src/runs/background/async-status.ts +66 -7
- package/src/runs/background/chain-append.ts +6 -3
- package/src/runs/background/chain-root-attachment.ts +60 -8
- package/src/runs/background/fleet-view.ts +21 -11
- package/src/runs/background/notify.ts +158 -6
- package/src/runs/background/result-files.ts +2 -1
- package/src/runs/background/result-watcher.ts +2 -0
- package/src/runs/background/resume-guidance.ts +1 -1
- package/src/runs/background/retained-children.ts +1 -1
- package/src/runs/background/run-status.ts +18 -8
- package/src/runs/background/scheduled-runs.ts +86 -7
- package/src/runs/background/stale-run-reconciler.ts +10 -4
- package/src/runs/background/steering.ts +4 -14
- package/src/runs/background/subagent-runner.ts +346 -357
- package/src/runs/background/subagent-wait.ts +58 -10
- package/src/runs/background/terminal-run-index.ts +1 -1
- package/src/runs/background/wait-completions.ts +22 -1
- package/src/runs/background/wait-config.ts +23 -9
- package/src/runs/background/wait-tool.ts +9 -2
- package/src/runs/foreground/async-steering-action.ts +2 -2
- package/src/runs/foreground/execution.ts +114 -120
- package/src/runs/foreground/foreground-control.ts +3 -0
- package/src/runs/foreground/foreground-history.ts +1 -0
- package/src/runs/foreground/subagent-executor.ts +478 -239
- package/src/runs/foreground/workflow-detach-reconcile.ts +99 -200
- package/src/runs/shared/abort-recovery.ts +119 -0
- package/src/runs/shared/async-status-projection.ts +463 -0
- package/src/runs/shared/child-identity.ts +19 -4
- package/src/runs/shared/child-launch-plan.ts +151 -0
- package/src/runs/shared/completion-evidence.ts +89 -0
- package/src/runs/shared/completion-guard.ts +1 -1
- package/src/runs/shared/dynamic-fanout.ts +2 -2
- package/src/runs/shared/host-step-status.ts +230 -0
- package/src/runs/shared/lane-metadata.ts +105 -0
- package/src/runs/shared/mcp-config-sources.ts +42 -6
- package/src/runs/shared/mcp-direct-tool-allowlist.ts +93 -143
- package/src/runs/shared/mcp-direct-tool-grant.ts +197 -0
- package/src/runs/shared/model-fallback.ts +9 -2
- package/src/runs/shared/nested-events.ts +6 -2
- package/src/runs/shared/nested-render.ts +7 -3
- package/src/runs/shared/parallel-handoff.ts +419 -7
- package/src/runs/shared/parallel-utils.ts +7 -0
- package/src/runs/shared/pi-args.ts +20 -2
- package/src/runs/shared/single-output.ts +27 -4
- package/src/runs/shared/subagent-prompt-runtime.ts +13 -4
- package/src/runs/shared/worktree-cleanup-plan.ts +847 -0
- package/src/runs/shared/worktree.ts +18 -0
- package/src/shared/child-session-name.ts +46 -0
- package/src/shared/extension-context.ts +24 -0
- package/src/shared/formatters.ts +5 -2
- package/src/shared/launch-contract.ts +1 -1
- package/src/shared/settings.ts +9 -103
- package/src/shared/types.ts +198 -29
- package/src/shared/utils.ts +35 -55
- package/src/slash/delegation-adapters.ts +1 -8
- package/src/slash/delegation-request.ts +0 -4
- package/src/slash/slash-bridge.ts +1 -2
- package/src/slash/slash-commands.ts +369 -90
- package/src/slash/slash-live-state.ts +22 -11
- package/src/tui/fleet-status.ts +125 -74
- package/src/tui/fleet.ts +11 -5
- package/src/tui/render.ts +316 -27
- package/src/watchdog/turn-delta.ts +1 -1
- package/src/workflows/chat-progress.ts +6 -3
- package/src/workflows/host-command.ts +230 -0
- package/src/workflows/scripted-workflow.ts +452 -38
- package/src/workflows/workflow-child-summary.ts +9 -5
- package/src/workflows/workflow-preflight.ts +270 -0
- package/src/workflows/workflow-receipt.ts +43 -4
- package/src/workflows/workflow-settlement.ts +246 -0
- package/src/runs/shared/turn-budget.ts +0 -98
package/src/profiles/profiles.ts
CHANGED
|
@@ -335,7 +335,6 @@ function resolveProbeStatus(text: string, timedOut: boolean): ProbeStatus {
|
|
|
335
335
|
|
|
336
336
|
async function probeModel(
|
|
337
337
|
pi: Pick<ExtensionAPI, "exec"> | { exec?: ExtensionAPI["exec"] },
|
|
338
|
-
ctx: Pick<ExtensionContext, "cwd">,
|
|
339
338
|
fullId: string,
|
|
340
339
|
): Promise<{ status: ProbeStatus; message?: string }> {
|
|
341
340
|
if (typeof pi.exec !== "function") {
|
|
@@ -401,7 +400,7 @@ function filterDominatedModels(models: ProviderModelCatalogModel[]): ProviderMod
|
|
|
401
400
|
return models.filter((candidate, index) => !models.some((other, otherIndex) => otherIndex !== index && dominatesModel(other, candidate)));
|
|
402
401
|
}
|
|
403
402
|
|
|
404
|
-
function buildProfileFile(
|
|
403
|
+
function buildProfileFile(models: { cheap: string; medium: string; strong: string }): SubagentProfileFile {
|
|
405
404
|
return {
|
|
406
405
|
subagents: {
|
|
407
406
|
agentOverrides: {
|
|
@@ -544,7 +543,7 @@ export async function refreshProviderModelCatalog(
|
|
|
544
543
|
const fullId = `${modelRecord.provider}/${modelRecord.id}`;
|
|
545
544
|
const probe = options.probe === false
|
|
546
545
|
? { status: "skipped" as const, message: "Live probing disabled." }
|
|
547
|
-
: await probeModel(pi,
|
|
546
|
+
: await probeModel(pi, fullId);
|
|
548
547
|
observedModels.push({ rawModel, modelRecord, fullId, probe });
|
|
549
548
|
}
|
|
550
549
|
const classificationContext = buildClassificationContext(observedModels.map(({ modelRecord }) => ({
|
|
@@ -624,8 +623,8 @@ export async function generateProfilesForProvider(
|
|
|
624
623
|
const dir = ensureSubagentProfilesDir();
|
|
625
624
|
const quotaPath = path.join(dir, `${normalizedProvider}.quota.json`);
|
|
626
625
|
const qualityPath = path.join(dir, `${normalizedProvider}.quality.json`);
|
|
627
|
-
writeJsonFile(quotaPath, buildProfileFile(
|
|
628
|
-
writeJsonFile(qualityPath, buildProfileFile(
|
|
626
|
+
writeJsonFile(quotaPath, buildProfileFile(quotaModels));
|
|
627
|
+
writeJsonFile(qualityPath, buildProfileFile(qualityModels));
|
|
629
628
|
const selectedModels = new Set([...Object.values(quotaModels), ...Object.values(qualityModels)]);
|
|
630
629
|
const selectedHeuristicFallbackCount = profileModels.filter((model) => selectedModels.has(model.fullId) && modelUsesHeuristicClassification(model)).length;
|
|
631
630
|
return { quotaPath, qualityPath, catalogPath, quotaModels, qualityModels, heuristicFallbackCount, selectedHeuristicFallbackCount };
|
|
@@ -649,7 +648,7 @@ export async function checkSubagentProfile(
|
|
|
649
648
|
const probeModelId = modelInfo ? `${modelInfo.fullId}${thinkingSuffix}` : entry.model;
|
|
650
649
|
let probe = probeCache.get(probeModelId);
|
|
651
650
|
if (!probe) {
|
|
652
|
-
probe = await probeModel(pi,
|
|
651
|
+
probe = await probeModel(pi, probeModelId);
|
|
653
652
|
probeCache.set(probeModelId, probe);
|
|
654
653
|
}
|
|
655
654
|
results.push({
|
|
@@ -230,10 +230,10 @@ function runnerReleaseVerdict(owner: ActiveAsyncCapacityOwnerV1, status: AsyncSt
|
|
|
230
230
|
&& proof.runId === owner.runId
|
|
231
231
|
&& proof.runnerProcessInstanceId === owner.runnerProcessInstanceId
|
|
232
232
|
? { state: "releasable", reason: "matching observed process-terminal proof is present" }
|
|
233
|
-
: abandonedRunnerReleaseVerdict(
|
|
233
|
+
: abandonedRunnerReleaseVerdict(status, proof?.state ?? "missing", options);
|
|
234
234
|
}
|
|
235
235
|
|
|
236
|
-
function abandonedRunnerReleaseVerdict(
|
|
236
|
+
function abandonedRunnerReleaseVerdict(status: AsyncStatus, proofState: string, options: CapacityOptions): ActiveAsyncCapacityReleaseVerdict {
|
|
237
237
|
const proofReason = `process-terminal proof is ${proofState}`;
|
|
238
238
|
const thresholdMs = resolveAbandonedSlotReleaseAfterMs(options.abandonedSlotReleaseAfterMs);
|
|
239
239
|
if (thresholdMs === false) return { state: "retained", reason: `${proofReason}; abandoned-timeout policy is disabled` };
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
import { spawn } from "node:child_process";
|
|
6
6
|
import { randomUUID } from "node:crypto";
|
|
7
7
|
import * as fs from "node:fs";
|
|
8
|
-
import * as os from "node:os";
|
|
9
8
|
import * as path from "node:path";
|
|
10
9
|
import { fileURLToPath } from "node:url";
|
|
11
10
|
import { createRequire } from "node:module";
|
|
@@ -14,9 +13,10 @@ import { discoverAgents, formatUnknownAgentError, unknownAgentDiagnosticContext,
|
|
|
14
13
|
import { appendAgentRefinementOverlay } from "../../agents/agent-refinements.ts";
|
|
15
14
|
import { writePrivateAtomicJson } from "../../shared/atomic-json.ts";
|
|
16
15
|
import { currentCompletionOwnerId } from "../../shared/completion-owner.ts";
|
|
16
|
+
import { planChildLaunch, resolveStepBehavior, suppressProgressForReadOnlyTask, type ResolvedStepBehavior } from "../shared/child-launch-plan.ts";
|
|
17
17
|
import { applyThinkingSuffix, projectLaunchResolvedChildExtensions, resolvePiLaunchToolPlan } from "../shared/pi-args.ts";
|
|
18
18
|
import { injectOutputPathSystemPrompt, injectSingleOutputInstruction, normalizeSingleOutputOverride, resolveSingleOutputPath, validateFileOnlyOutputMode } from "../shared/single-output.ts";
|
|
19
|
-
import { buildChainInstructions, isDynamicParallelStep, isParallelStep,
|
|
19
|
+
import { buildChainInstructions, isDynamicParallelStep, isParallelStep, resolveExistingReadPaths, writeInitialProgressFile, type ChainStep, type SequentialStep, type StepOverrides } from "../../shared/settings.ts";
|
|
20
20
|
import type { RunnerStep } from "../shared/parallel-utils.ts";
|
|
21
21
|
import type { ContextMode } from "../shared/context-mode.ts";
|
|
22
22
|
import { resolvePiPackageRoot } from "../shared/pi-spawn.ts";
|
|
@@ -25,7 +25,7 @@ import { resolveNodeExecutable } from "../../shared/node-executable.ts";
|
|
|
25
25
|
import { buildSkillInjection, normalizeSkillInput, resolveSkillsWithFallback } from "../../agents/skills.ts";
|
|
26
26
|
import { buildAgentMemoryInjection } from "../../agents/agent-memory.ts";
|
|
27
27
|
import { PI_CODING_AGENT_PACKAGE_ROOT_ENV, PROMPT_REDACTED, resolveChildCwd } from "../../shared/utils.ts";
|
|
28
|
-
import { buildModelCandidates, inheritsParentModel, resolveEffectiveSubagentModel,
|
|
28
|
+
import { buildModelCandidates, inheritsParentModel, resolveEffectiveSubagentModel, resolveSubagentModelOverride, type AvailableModelInfo, type ParentModel } from "../shared/model-fallback.ts";
|
|
29
29
|
import { resolveToolTimeoutMs, toolTimeoutFromEnv } from "../shared/tool-timeout.ts";
|
|
30
30
|
import { resolveModelScopesForAgent, type ModelScopeConfig } from "../shared/model-scope.ts";
|
|
31
31
|
import { findModelInfo, resolveEffectiveThinking } from "../../shared/model-info.ts";
|
|
@@ -49,12 +49,12 @@ import {
|
|
|
49
49
|
type MaxOutputConfig,
|
|
50
50
|
type NestedRouteInfo,
|
|
51
51
|
type ResolvedControlConfig,
|
|
52
|
-
type ResolvedTurnBudget,
|
|
53
52
|
type ResolvedToolBudget,
|
|
54
53
|
type RunFanoutBudgetDescriptor,
|
|
55
54
|
type ToolBudgetConfig,
|
|
56
55
|
type SubagentRunMode,
|
|
57
56
|
type SteeringRecoveryDescriptor,
|
|
57
|
+
type WorkflowLaneMetadata,
|
|
58
58
|
type UsageBudgetConfig,
|
|
59
59
|
DIRS,
|
|
60
60
|
SUBAGENT_ASYNC_STARTED_EVENT,
|
|
@@ -65,7 +65,6 @@ import {
|
|
|
65
65
|
} from "../../shared/types.ts";
|
|
66
66
|
import { nestedResultsPath, nestedSummaryFromAsyncStatus, resolveInheritedNestedRouteFromEnv, resolveNestedParentAddressFromEnv, writeNestedEvent } from "../shared/nested-events.ts";
|
|
67
67
|
import { resultFilePath } from "./result-files.ts";
|
|
68
|
-
import { appendTurnBudgetSystemPrompt, initialTurnBudgetState } from "../shared/turn-budget.ts";
|
|
69
68
|
import { validateToolBudgetConfig } from "../shared/tool-budget.ts";
|
|
70
69
|
import { usageBudgetState } from "../shared/usage-budget.ts";
|
|
71
70
|
import type { ImportedAsyncRoot } from "./chain-root-attachment.ts";
|
|
@@ -78,6 +77,7 @@ import { assertAgentAllowedByCapabilityCeiling, decodeSubagentCapabilityCeiling,
|
|
|
78
77
|
import { agentDefinitionDigest, launchBindingDigest } from "../../shared/launch-contract.ts";
|
|
79
78
|
import { resolvePermissionRules, type PermissionConfig } from "../shared/permissions.ts";
|
|
80
79
|
import { normalizeExtensionBindings, omitExtensionBindingsEnv, type ExtensionBindings } from "../shared/extension-bindings.ts";
|
|
80
|
+
import { assertWorkflowLaneKey, normalizeWorkflowLaneMetadata } from "../shared/lane-metadata.ts";
|
|
81
81
|
|
|
82
82
|
const require = createRequire(import.meta.url);
|
|
83
83
|
const piPackageRoot = resolvePiPackageRoot();
|
|
@@ -173,6 +173,7 @@ interface AsyncChainParams {
|
|
|
173
173
|
dynamicFanoutMaxItems?: number;
|
|
174
174
|
maxSubagentDepth: number;
|
|
175
175
|
waitToolEnabled?: boolean;
|
|
176
|
+
waitToolDefaultTimeoutMs?: number;
|
|
176
177
|
worktreeSetupHook?: string;
|
|
177
178
|
worktreeSetupHookTimeoutMs?: number;
|
|
178
179
|
worktreeBaseDir?: string;
|
|
@@ -183,7 +184,6 @@ interface AsyncChainParams {
|
|
|
183
184
|
acceptance?: AcceptanceInput;
|
|
184
185
|
fast?: boolean;
|
|
185
186
|
timeoutMs?: number;
|
|
186
|
-
turnBudget?: ResolvedTurnBudget;
|
|
187
187
|
toolBudget?: ResolvedToolBudget;
|
|
188
188
|
usageBudget?: UsageBudgetConfig;
|
|
189
189
|
configToolBudget?: ResolvedToolBudget;
|
|
@@ -200,6 +200,7 @@ interface AsyncChainParams {
|
|
|
200
200
|
runFanoutBudget?: RunFanoutBudgetDescriptor;
|
|
201
201
|
parentWorkflowRunId?: string;
|
|
202
202
|
workflowKey?: string;
|
|
203
|
+
lane?: WorkflowLaneMetadata;
|
|
203
204
|
activeAsyncCapacity?: ActiveAsyncCapacityHandle;
|
|
204
205
|
}
|
|
205
206
|
|
|
@@ -228,6 +229,7 @@ interface AsyncSingleParams {
|
|
|
228
229
|
reads?: string[] | false;
|
|
229
230
|
outputMode?: "inline" | "file-only";
|
|
230
231
|
outputBaseDir?: string;
|
|
232
|
+
outputClaimPath?: string;
|
|
231
233
|
agentContract?: AgentContract;
|
|
232
234
|
structuredOutputSchema?: JsonSchemaObject;
|
|
233
235
|
modelOverride?: string;
|
|
@@ -237,6 +239,7 @@ interface AsyncSingleParams {
|
|
|
237
239
|
availableModels?: AvailableModelInfo[];
|
|
238
240
|
maxSubagentDepth: number;
|
|
239
241
|
waitToolEnabled?: boolean;
|
|
242
|
+
waitToolDefaultTimeoutMs?: number;
|
|
240
243
|
worktreeSetupHook?: string;
|
|
241
244
|
worktreeSetupHookTimeoutMs?: number;
|
|
242
245
|
worktreeBaseDir?: string;
|
|
@@ -251,7 +254,6 @@ interface AsyncSingleParams {
|
|
|
251
254
|
absoluteDeadlineAt?: number;
|
|
252
255
|
/** Optional per-call hard toolTimeoutMs override (highest precedence). */
|
|
253
256
|
toolTimeoutMs?: number;
|
|
254
|
-
turnBudget?: { maxTurns: number; graceTurns?: number };
|
|
255
257
|
toolBudget?: ResolvedToolBudget | ToolBudgetConfig;
|
|
256
258
|
usageBudget?: UsageBudgetConfig;
|
|
257
259
|
configToolBudget?: ResolvedToolBudget;
|
|
@@ -265,6 +267,7 @@ interface AsyncSingleParams {
|
|
|
265
267
|
runFanoutBudget?: RunFanoutBudgetDescriptor;
|
|
266
268
|
parentWorkflowRunId?: string;
|
|
267
269
|
workflowKey?: string;
|
|
270
|
+
lane?: WorkflowLaneMetadata;
|
|
268
271
|
workflowAwaitAsync?: boolean;
|
|
269
272
|
activeAsyncCapacity?: ActiveAsyncCapacityHandle;
|
|
270
273
|
externalJobFollowUp?: {
|
|
@@ -303,6 +306,7 @@ export interface AsyncRunnerStepBuildParams {
|
|
|
303
306
|
dynamicFanoutMaxItems?: number;
|
|
304
307
|
maxSubagentDepth: number;
|
|
305
308
|
waitToolEnabled?: boolean;
|
|
309
|
+
waitToolDefaultTimeoutMs?: number;
|
|
306
310
|
worktreeBaseDir?: string;
|
|
307
311
|
asyncDir: string;
|
|
308
312
|
outputBaseDir?: string;
|
|
@@ -804,19 +808,21 @@ export function buildAsyncRunnerSteps(id: string, params: AsyncRunnerStepBuildPa
|
|
|
804
808
|
envValue: params.toolTimeoutMsEnv ?? toolTimeoutFromEnv(),
|
|
805
809
|
});
|
|
806
810
|
if (resolvedToolTimeout.error) throw new AsyncStartValidationError(resolvedToolTimeout.error);
|
|
807
|
-
const
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
811
|
+
const launchPlan = planChildLaunch({
|
|
812
|
+
agentConfig: a,
|
|
813
|
+
stepOverrides: buildStepOverrides(s),
|
|
814
|
+
task: s.task,
|
|
815
|
+
originalTask,
|
|
816
|
+
runnerCwd,
|
|
817
|
+
runtimeCwd: ctx.cwd,
|
|
818
|
+
stepCwdInput: s.cwd,
|
|
819
|
+
behaviorCwd,
|
|
820
|
+
chainSkills,
|
|
821
|
+
outputBaseDir,
|
|
822
|
+
parallelOutputNamespace,
|
|
823
|
+
resolvedBehavior,
|
|
824
|
+
});
|
|
825
|
+
const { stepCwd, instructionCwd, readExistenceCwd, behavior, namespaceOutputPath, outputPath, skillNames } = launchPlan;
|
|
820
826
|
const { resolved: resolvedSkills, missing: missingSkills } = resolveSkillsWithFallback(
|
|
821
827
|
skillNames,
|
|
822
828
|
stepCwd,
|
|
@@ -841,7 +847,6 @@ export function buildAsyncRunnerSteps(id: string, params: AsyncRunnerStepBuildPa
|
|
|
841
847
|
const isFirstProgressAgent = behavior.progress && !progressPrecreated && !progressInstructionCreated;
|
|
842
848
|
if (behavior.progress) progressInstructionCreated = true;
|
|
843
849
|
const progressInstructions = buildChainInstructions({ ...behavior, output: false, reads: false }, progressDir, isFirstProgressAgent);
|
|
844
|
-
const outputPath = resolveSingleOutputPath(behavior.output, ctx.cwd, instructionCwd, outputBaseDir);
|
|
845
850
|
if (!namespaceOutputPath) systemPrompt = injectOutputPathSystemPrompt(systemPrompt, outputPath, a);
|
|
846
851
|
const validationError = validateFileOnlyOutputMode(behavior.outputMode, outputPath, `Async step (${s.agent})`);
|
|
847
852
|
if (validationError) throw new AsyncStartValidationError(validationError);
|
|
@@ -896,6 +901,7 @@ export function buildAsyncRunnerSteps(id: string, params: AsyncRunnerStepBuildPa
|
|
|
896
901
|
const fast = s.fast ?? params.fast ?? a.fast;
|
|
897
902
|
const toolPlan = resolvePiLaunchToolPlan({
|
|
898
903
|
tools: a.tools,
|
|
904
|
+
allowNestedSubagents: a.allowNestedSubagents,
|
|
899
905
|
extensions: a.extensions,
|
|
900
906
|
subagentOnlyExtensions: a.subagentOnlyExtensions,
|
|
901
907
|
mcpDirectTools: a.mcpDirectTools,
|
|
@@ -957,6 +963,7 @@ export function buildAsyncRunnerSteps(id: string, params: AsyncRunnerStepBuildPa
|
|
|
957
963
|
...(primaryModelFromParent ? { skipPrimaryModelVerification: true } : {}),
|
|
958
964
|
...(availableModels && availableModels.length > 0 ? { modelVerificationRegistry: availableModels } : {}),
|
|
959
965
|
tools: a.tools,
|
|
966
|
+
allowNestedSubagents: a.allowNestedSubagents,
|
|
960
967
|
extensions: a.extensions,
|
|
961
968
|
subagentOnlyExtensions: a.subagentOnlyExtensions,
|
|
962
969
|
mcpDirectTools: a.mcpDirectTools,
|
|
@@ -976,6 +983,7 @@ export function buildAsyncRunnerSteps(id: string, params: AsyncRunnerStepBuildPa
|
|
|
976
983
|
timeoutMs: a.defaultTimeoutMs ?? DEFAULT_ASYNC_TIMEOUT_MS,
|
|
977
984
|
toolTimeoutMs: resolvedToolTimeout.toolTimeoutMs,
|
|
978
985
|
waitToolEnabled: params.waitToolEnabled,
|
|
986
|
+
waitToolDefaultTimeoutMs: params.waitToolDefaultTimeoutMs,
|
|
979
987
|
effectiveAcceptance: resolveEffectiveAcceptance({
|
|
980
988
|
explicit: s.acceptance,
|
|
981
989
|
agentName: s.agent,
|
|
@@ -1203,6 +1211,7 @@ export function executeAsyncChain(
|
|
|
1203
1211
|
dynamicFanoutMaxItems: params.dynamicFanoutMaxItems,
|
|
1204
1212
|
maxSubagentDepth,
|
|
1205
1213
|
waitToolEnabled: params.waitToolEnabled,
|
|
1214
|
+
waitToolDefaultTimeoutMs: params.waitToolDefaultTimeoutMs,
|
|
1206
1215
|
worktreeBaseDir,
|
|
1207
1216
|
asyncDir,
|
|
1208
1217
|
fast: params.fast,
|
|
@@ -1224,7 +1233,6 @@ export function executeAsyncChain(
|
|
|
1224
1233
|
}
|
|
1225
1234
|
const { steps, runnerCwd, workflowGraph, eventChain } = built;
|
|
1226
1235
|
const deadlineAt = params.timeoutMs !== undefined ? Date.now() + params.timeoutMs : undefined;
|
|
1227
|
-
const initialTurnBudget = params.turnBudget ? initialTurnBudgetState(params.turnBudget) : undefined;
|
|
1228
1236
|
const initialUsageBudget = usageBudgetState(params.usageBudget, undefined);
|
|
1229
1237
|
let childTargetIndex = 0;
|
|
1230
1238
|
const childIntercomTargets = childIntercomTarget ? steps.flatMap((step) => {
|
|
@@ -1281,7 +1289,6 @@ export function executeAsyncChain(
|
|
|
1281
1289
|
worktreeSetupHookTimeoutMs,
|
|
1282
1290
|
worktreeBaseDir,
|
|
1283
1291
|
controlConfig,
|
|
1284
|
-
turnBudget: params.turnBudget,
|
|
1285
1292
|
toolBudget: params.toolBudget,
|
|
1286
1293
|
usageBudget: params.usageBudget,
|
|
1287
1294
|
controlIntercomTarget,
|
|
@@ -1400,7 +1407,6 @@ export function executeAsyncChain(
|
|
|
1400
1407
|
chainStepCount: eventChain.length,
|
|
1401
1408
|
parallelGroups,
|
|
1402
1409
|
...(params.timeoutMs !== undefined ? { timeoutMs: params.timeoutMs, deadlineAt } : {}),
|
|
1403
|
-
...(initialTurnBudget ? { turnBudget: initialTurnBudget } : {}),
|
|
1404
1410
|
startedAt: now,
|
|
1405
1411
|
lastUpdate: now,
|
|
1406
1412
|
...(capabilityCeiling ? { capabilityCeiling } : {}),
|
|
@@ -1431,7 +1437,6 @@ export function executeAsyncChain(
|
|
|
1431
1437
|
asyncDir,
|
|
1432
1438
|
...(sessionRoot ? { sessionRoot } : {}),
|
|
1433
1439
|
...(params.timeoutMs !== undefined ? { timeoutMs: params.timeoutMs, deadlineAt } : {}),
|
|
1434
|
-
...(initialTurnBudget ? { turnBudget: initialTurnBudget } : {}),
|
|
1435
1440
|
...(initialUsageBudget ? { usageBudget: initialUsageBudget } : {}),
|
|
1436
1441
|
...(capabilityCeiling ? { capabilityCeiling } : {}),
|
|
1437
1442
|
...(params.parentWorkflowRunId ? { parentWorkflowRunId: params.parentWorkflowRunId } : {}),
|
|
@@ -1448,7 +1453,7 @@ export function executeAsyncChain(
|
|
|
1448
1453
|
|
|
1449
1454
|
return {
|
|
1450
1455
|
content: [{ type: "text", text: formatAsyncStartedMessage(`Async ${resultMode}: ${chainDesc} [${id}]`, ctx.interactive === true) }],
|
|
1451
|
-
details: { mode: resultMode, runId: id, results: [], asyncId: id, asyncDir, workflowGraph, ...(capabilityCeiling ? { capabilityCeiling } : {}), ...(params.parentWorkflowRunId ? { parentWorkflowRunId: params.parentWorkflowRunId } : {}), ...(params.workflowKey ? { workflowKey: params.workflowKey } : {}), ...(params.timeoutMs !== undefined ? { timeoutMs: params.timeoutMs, deadlineAt } : {}), ...(params.
|
|
1456
|
+
details: { mode: resultMode, runId: id, results: [], asyncId: id, asyncDir, workflowGraph, ...(capabilityCeiling ? { capabilityCeiling } : {}), ...(params.parentWorkflowRunId ? { parentWorkflowRunId: params.parentWorkflowRunId } : {}), ...(params.workflowKey ? { workflowKey: params.workflowKey } : {}), ...(params.timeoutMs !== undefined ? { timeoutMs: params.timeoutMs, deadlineAt } : {}), ...(params.toolBudget ? { toolBudget: params.toolBudget } : {}), ...(initialUsageBudget ? { usageBudget: initialUsageBudget } : {}) },
|
|
1452
1457
|
};
|
|
1453
1458
|
}
|
|
1454
1459
|
|
|
@@ -1483,6 +1488,13 @@ export function executeAsyncSingle(
|
|
|
1483
1488
|
childIntercomTarget,
|
|
1484
1489
|
nestedRoute,
|
|
1485
1490
|
} = params;
|
|
1491
|
+
let lane: WorkflowLaneMetadata | undefined;
|
|
1492
|
+
try {
|
|
1493
|
+
lane = normalizeWorkflowLaneMetadata(params.lane, "lane");
|
|
1494
|
+
assertWorkflowLaneKey(lane, params.workflowKey, "lane");
|
|
1495
|
+
} catch (error) {
|
|
1496
|
+
return formatAsyncStartError("single", error instanceof Error ? error.message : String(error));
|
|
1497
|
+
}
|
|
1486
1498
|
const task = params.task ?? "";
|
|
1487
1499
|
let extensionBindings: ExtensionBindings | undefined;
|
|
1488
1500
|
try {
|
|
@@ -1616,7 +1628,6 @@ export function executeAsyncSingle(
|
|
|
1616
1628
|
});
|
|
1617
1629
|
if (resolvedToolTimeout.error) return formatAsyncStartError("single", resolvedToolTimeout.error);
|
|
1618
1630
|
const toolTimeoutMs = resolvedToolTimeout.toolTimeoutMs;
|
|
1619
|
-
const initialTurnBudget = params.turnBudget ? initialTurnBudgetState(params.turnBudget) : undefined;
|
|
1620
1631
|
const initialUsageBudget = usageBudgetState(params.usageBudget, undefined);
|
|
1621
1632
|
const resolvedSessionDir = params.sessionDir ?? (sessionRoot ? path.join(sessionRoot, `async-${id}`) : undefined);
|
|
1622
1633
|
const structuredOutput = params.structuredOutputSchema
|
|
@@ -1639,9 +1650,9 @@ export function executeAsyncSingle(
|
|
|
1639
1650
|
return formatAsyncStartError("single", error instanceof Error ? error.message : String(error));
|
|
1640
1651
|
}
|
|
1641
1652
|
}
|
|
1642
|
-
const effectiveSystemPrompt = appendTurnBudgetSystemPrompt(systemPrompt, params.turnBudget);
|
|
1643
1653
|
const toolPlan = resolvePiLaunchToolPlan({
|
|
1644
1654
|
tools: agentConfig.tools,
|
|
1655
|
+
allowNestedSubagents: agentConfig.allowNestedSubagents,
|
|
1645
1656
|
extensions: agentConfig.extensions,
|
|
1646
1657
|
subagentOnlyExtensions: agentConfig.subagentOnlyExtensions,
|
|
1647
1658
|
mcpDirectTools: agentConfig.mcpDirectTools,
|
|
@@ -1680,7 +1691,7 @@ export function executeAsyncSingle(
|
|
|
1680
1691
|
...((params.fast ?? agentConfig.fast) !== undefined ? { fast: params.fast ?? agentConfig.fast } : {}),
|
|
1681
1692
|
...(resolveEffectiveThinking(model, effectiveThinking) ? { thinking: resolveEffectiveThinking(model, effectiveThinking) } : {}),
|
|
1682
1693
|
...(thinkingCeiling ? { thinkingCeiling } : {}),
|
|
1683
|
-
systemPrompt
|
|
1694
|
+
systemPrompt,
|
|
1684
1695
|
systemPromptMode: agentConfig.systemPromptMode,
|
|
1685
1696
|
inheritProjectContext: agentConfig.inheritProjectContext,
|
|
1686
1697
|
inheritGlobalContext: agentConfig.inheritGlobalContext,
|
|
@@ -1706,6 +1717,7 @@ export function executeAsyncSingle(
|
|
|
1706
1717
|
const recoveryAgentConfig = params.recoveryAgentConfig ?? agentConfig;
|
|
1707
1718
|
const recoveryDescriptor: SteeringRecoveryDescriptor = {
|
|
1708
1719
|
version: 1,
|
|
1720
|
+
...(lane ? { lane } : {}),
|
|
1709
1721
|
launchContractDigest,
|
|
1710
1722
|
...(extensionBindings ? { extensionBindings } : {}),
|
|
1711
1723
|
runFanoutBudget,
|
|
@@ -1723,6 +1735,7 @@ export function executeAsyncSingle(
|
|
|
1723
1735
|
...(effectiveThinking ? { thinking: resolveEffectiveThinking(model, effectiveThinking) } : {}),
|
|
1724
1736
|
...(thinkingCeiling ? { thinkingCeiling } : {}),
|
|
1725
1737
|
...(recoveryAgentConfig.tools ? { tools: [...recoveryAgentConfig.tools] } : {}),
|
|
1738
|
+
...(recoveryAgentConfig.allowNestedSubagents !== undefined ? { allowNestedSubagents: recoveryAgentConfig.allowNestedSubagents } : {}),
|
|
1726
1739
|
...(recoveryAgentConfig.extensions ? { extensions: [...recoveryAgentConfig.extensions] } : {}),
|
|
1727
1740
|
...(recoveryAgentConfig.subagentOnlyExtensions ? { subagentOnlyExtensions: [...recoveryAgentConfig.subagentOnlyExtensions] } : {}),
|
|
1728
1741
|
...(recoveryAgentConfig.mcpDirectTools ? { mcpDirectTools: [...recoveryAgentConfig.mcpDirectTools] } : {}),
|
|
@@ -1745,7 +1758,6 @@ export function executeAsyncSingle(
|
|
|
1745
1758
|
...(params.context ? { context: params.context } : {}),
|
|
1746
1759
|
...(params.intercomBridge !== undefined ? { intercomBridge: params.intercomBridge } : {}),
|
|
1747
1760
|
...(deadlineAt !== undefined ? { absoluteDeadlineAt: deadlineAt } : {}),
|
|
1748
|
-
...(initialTurnBudget ? { initialTurnBudget: { maxTurns: initialTurnBudget.maxTurns, graceTurns: initialTurnBudget.graceTurns } } : {}),
|
|
1749
1761
|
...(resolvedToolBudget.budget ? { initialToolBudget: resolvedToolBudget.budget } : {}),
|
|
1750
1762
|
maxSubagentDepth: resolveChildMaxSubagentDepth(maxSubagentDepth, recoveryAgentConfig.maxSubagentDepth),
|
|
1751
1763
|
...(maxOutput ? { maxOutput } : {}),
|
|
@@ -1790,6 +1802,7 @@ export function executeAsyncSingle(
|
|
|
1790
1802
|
...(params.modelOverrideFromParent ? { skipPrimaryModelVerification: true } : {}),
|
|
1791
1803
|
...(availableModels && availableModels.length > 0 ? { modelVerificationRegistry: availableModels } : {}),
|
|
1792
1804
|
tools: agentConfig.tools,
|
|
1805
|
+
allowNestedSubagents: agentConfig.allowNestedSubagents,
|
|
1793
1806
|
extensions: agentConfig.extensions,
|
|
1794
1807
|
subagentOnlyExtensions: agentConfig.subagentOnlyExtensions,
|
|
1795
1808
|
mcpDirectTools: agentConfig.mcpDirectTools,
|
|
@@ -1804,10 +1817,12 @@ export function executeAsyncSingle(
|
|
|
1804
1817
|
inheritSkills: agentConfig.inheritSkills,
|
|
1805
1818
|
skills: resolvedSkills.map((r) => r.name),
|
|
1806
1819
|
outputPath,
|
|
1820
|
+
...(params.outputClaimPath ? { outputClaimPath: params.outputClaimPath } : {}),
|
|
1807
1821
|
outputMode,
|
|
1808
1822
|
...(!externalRunner && sessionFile ? { sessionFile } : {}),
|
|
1809
1823
|
maxSubagentDepth: resolveChildMaxSubagentDepth(maxSubagentDepth, agentConfig.maxSubagentDepth),
|
|
1810
1824
|
waitToolEnabled: params.waitToolEnabled,
|
|
1825
|
+
waitToolDefaultTimeoutMs: params.waitToolDefaultTimeoutMs,
|
|
1811
1826
|
...(params.agentContract ? { agentContract: params.agentContract } : {}),
|
|
1812
1827
|
definitionDigest: agentDefinitionDigest(agentConfig),
|
|
1813
1828
|
launchBindingTask: task,
|
|
@@ -1819,6 +1834,7 @@ export function executeAsyncSingle(
|
|
|
1819
1834
|
...(params.structuredOutputSchema ? { structuredOutputSchema: params.structuredOutputSchema } : {}),
|
|
1820
1835
|
...(resolvedToolBudget.budget ? { toolBudget: resolvedToolBudget.budget } : {}),
|
|
1821
1836
|
...(params.worktree === true ? { worktree: true } : {}),
|
|
1837
|
+
...(lane ? { lane } : {}),
|
|
1822
1838
|
},
|
|
1823
1839
|
],
|
|
1824
1840
|
resultPath: params.parentWorkflowRunId !== undefined && (params.revivalLease !== undefined || params.workflowAwaitAsync === true)
|
|
@@ -1844,7 +1860,6 @@ export function executeAsyncSingle(
|
|
|
1844
1860
|
timeoutMs,
|
|
1845
1861
|
deadlineAt,
|
|
1846
1862
|
toolTimeoutMs,
|
|
1847
|
-
turnBudget: params.turnBudget,
|
|
1848
1863
|
toolBudget: params.toolBudget,
|
|
1849
1864
|
usageBudget: params.usageBudget,
|
|
1850
1865
|
controlIntercomTarget,
|
|
@@ -1855,6 +1870,7 @@ export function executeAsyncSingle(
|
|
|
1855
1870
|
runFanoutBudget,
|
|
1856
1871
|
...(params.parentWorkflowRunId ? { parentWorkflowRunId: params.parentWorkflowRunId } : {}),
|
|
1857
1872
|
...(params.workflowKey ? { workflowKey: params.workflowKey } : {}),
|
|
1873
|
+
...(lane ? { lane } : {}),
|
|
1858
1874
|
...(params.revivalLease ? { revivalLease: params.revivalLease } : {}),
|
|
1859
1875
|
nestedRoute: nestedRoute ?? inheritedNestedRoute,
|
|
1860
1876
|
nestedSelf: inheritedNestedRoute && nestedAddress ? {
|
|
@@ -1877,7 +1893,8 @@ export function executeAsyncSingle(
|
|
|
1877
1893
|
lastUpdate: initialStatusAt,
|
|
1878
1894
|
currentStep: 0,
|
|
1879
1895
|
chainStepCount: 1,
|
|
1880
|
-
|
|
1896
|
+
...(lane ? { lane } : {}),
|
|
1897
|
+
steps: [{ agent, status: "pending", ...(lane ? { lane } : {}), ...(model ? { model } : {}), ...(contextLimit !== undefined ? { contextLimit } : {}) }],
|
|
1881
1898
|
},
|
|
1882
1899
|
path.join(asyncDir, "status.json"),
|
|
1883
1900
|
(proof) => emitProcessTerminalEvent(ctx, proof),
|
|
@@ -1927,7 +1944,6 @@ export function executeAsyncSingle(
|
|
|
1927
1944
|
agents: [agent],
|
|
1928
1945
|
chainStepCount: 1,
|
|
1929
1946
|
...(timeoutMs !== undefined ? { timeoutMs, deadlineAt } : {}),
|
|
1930
|
-
...(initialTurnBudget ? { turnBudget: initialTurnBudget } : {}),
|
|
1931
1947
|
startedAt: now,
|
|
1932
1948
|
lastUpdate: now,
|
|
1933
1949
|
...(capabilityCeiling ? { capabilityCeiling } : {}),
|
|
@@ -1955,7 +1971,6 @@ export function executeAsyncSingle(
|
|
|
1955
1971
|
...(params.parentWorkflowRunId ? { parentWorkflowRunId: params.parentWorkflowRunId } : {}),
|
|
1956
1972
|
...(params.workflowKey ? { workflowKey: params.workflowKey } : {}),
|
|
1957
1973
|
...(timeoutMs !== undefined ? { timeoutMs, deadlineAt } : {}),
|
|
1958
|
-
...(initialTurnBudget ? { turnBudget: initialTurnBudget } : {}),
|
|
1959
1974
|
...(initialUsageBudget ? { usageBudget: initialUsageBudget } : {}),
|
|
1960
1975
|
...(capabilityCeiling ? { capabilityCeiling } : {}),
|
|
1961
1976
|
nestedRoute,
|
|
@@ -1964,6 +1979,6 @@ export function executeAsyncSingle(
|
|
|
1964
1979
|
|
|
1965
1980
|
return {
|
|
1966
1981
|
content: [{ type: "text", text: formatAsyncStartedMessage(`Async: ${agent} [${id}]`, ctx.interactive === true) }],
|
|
1967
|
-
details: { mode: "single", runId: id, results: [], asyncId: id, asyncDir, launchContractDigest, launchResolvedExtensions, ...(capabilityCeiling ? { capabilityCeiling } : {}), ...(params.context ? { context: params.context } : {}), ...(timeoutMs !== undefined ? { timeoutMs, deadlineAt } : {}), ...(params.
|
|
1982
|
+
details: { mode: "single", runId: id, results: [], asyncId: id, asyncDir, launchContractDigest, launchResolvedExtensions, ...(capabilityCeiling ? { capabilityCeiling } : {}), ...(params.context ? { context: params.context } : {}), ...(timeoutMs !== undefined ? { timeoutMs, deadlineAt } : {}), ...(params.toolBudget ? { toolBudget: resolvedToolBudget.budget ?? params.toolBudget } : {}), ...(initialUsageBudget ? { usageBudget: initialUsageBudget } : {}) } as Details,
|
|
1968
1983
|
};
|
|
1969
1984
|
}
|
|
@@ -25,6 +25,8 @@ import { listAsyncRuns, type AsyncRunSummary } from "./async-status.ts";
|
|
|
25
25
|
import { EXTERNAL_JOB_BRIDGE_REQUEST_DIR, serviceExternalJobBridgeRequests } from "../shared/external-job-bridge.ts";
|
|
26
26
|
import { shouldUseNativeFsWatch } from "../../shared/watch-strategy.ts";
|
|
27
27
|
import { parseWorkflowChildSummary } from "../../workflows/workflow-child-summary.ts";
|
|
28
|
+
import { validHostStepNodes } from "../shared/host-step-status.ts";
|
|
29
|
+
import { withCachedUiContext } from "../../shared/extension-context.ts";
|
|
28
30
|
|
|
29
31
|
interface AsyncJobTrackerOptions {
|
|
30
32
|
completionRetentionMs?: number;
|
|
@@ -78,23 +80,19 @@ export function createAsyncJobTracker(pi: Pick<ExtensionAPI, "events">, state: S
|
|
|
78
80
|
const watch = options.watch ?? fs.watch;
|
|
79
81
|
const useNativeWatcher = () => shouldUseNativeFsWatch("async-job-tracker", options.platform);
|
|
80
82
|
const terminalStatus = (status: string) => status === "complete" || status === "failed" || status === "paused" || status === "stopped";
|
|
83
|
+
const withLastUiContext = <T>(run: (ctx: ExtensionContext) => T): T | undefined => {
|
|
84
|
+
const cached = state.lastUiContext;
|
|
85
|
+
return withCachedUiContext(cached, () => {
|
|
86
|
+
if (state.lastUiContext === cached) state.lastUiContext = null;
|
|
87
|
+
}, run);
|
|
88
|
+
};
|
|
81
89
|
const rerenderWidget = (ctx: ExtensionContext, jobs = Array.from(state.asyncJobs.values())) => {
|
|
82
90
|
if (state.widgetsSuspended) return;
|
|
83
91
|
renderWidget(ctx, options.widgetEnabled === false ? [] : jobs);
|
|
84
92
|
(ctx.ui as { requestRender?: () => void }).requestRender?.();
|
|
85
93
|
};
|
|
86
94
|
const rerenderLastWidget = (jobs = Array.from(state.asyncJobs.values())) => {
|
|
87
|
-
|
|
88
|
-
if (!ctx) return;
|
|
89
|
-
try {
|
|
90
|
-
if (ctx.hasUI) rerenderWidget(ctx, jobs);
|
|
91
|
-
} catch (error) {
|
|
92
|
-
if (error instanceof Error && error.message.includes("extension ctx is stale")) {
|
|
93
|
-
state.lastUiContext = null;
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
throw error;
|
|
97
|
-
}
|
|
95
|
+
withLastUiContext((ctx) => rerenderWidget(ctx, jobs));
|
|
98
96
|
};
|
|
99
97
|
const requestLastWidgetRender = () => {
|
|
100
98
|
if (options.widgetEnabled === false) return;
|
|
@@ -147,6 +145,8 @@ export function createAsyncJobTracker(pi: Pick<ExtensionAPI, "events">, state: S
|
|
|
147
145
|
currentStep: run.currentStep,
|
|
148
146
|
chainStepCount: run.chainStepCount,
|
|
149
147
|
parallelGroups: groups,
|
|
148
|
+
hostSteps: run.hostSteps,
|
|
149
|
+
preflight: run.preflight,
|
|
150
150
|
steps: visibleSteps,
|
|
151
151
|
stepsTotal: visibleSteps.length,
|
|
152
152
|
runningSteps: visibleSteps.filter((step) => step.status === "running").length,
|
|
@@ -342,7 +342,7 @@ export function createAsyncJobTracker(pi: Pick<ExtensionAPI, "events">, state: S
|
|
|
342
342
|
};
|
|
343
343
|
|
|
344
344
|
const refreshJob = (job: AsyncJobState): boolean => {
|
|
345
|
-
const widgetExpanded =
|
|
345
|
+
const widgetExpanded = withLastUiContext((ctx) => ctx.ui.getToolsExpanded?.() ?? false) ?? false;
|
|
346
346
|
const widgetStateBefore = widgetRenderKey(job, widgetExpanded);
|
|
347
347
|
let nestedRefreshFailed = false;
|
|
348
348
|
const refreshNestedProjection = () => {
|
|
@@ -399,7 +399,9 @@ export function createAsyncJobTracker(pi: Pick<ExtensionAPI, "events">, state: S
|
|
|
399
399
|
job.mode = status.mode;
|
|
400
400
|
job.parentWorkflowRunId = status.parentWorkflowRunId ?? job.parentWorkflowRunId;
|
|
401
401
|
job.workflowKey = status.workflowKey ?? job.workflowKey;
|
|
402
|
+
job.lane = status.lane ?? job.lane;
|
|
402
403
|
job.workflow = status.workflow ?? job.workflow;
|
|
404
|
+
job.hostSteps = validHostStepNodes(status.workflowGraph);
|
|
403
405
|
const workflowChildren = parseWorkflowChildSummary(status.workflowChildren);
|
|
404
406
|
if (workflowChildren && workflowChildren.workflowRunId !== status.runId) throw new Error("workflowChildren.workflowRunId does not match async status runId.");
|
|
405
407
|
job.workflowChildren = workflowChildren ?? job.workflowChildren;
|