pi-subagents 0.60.0 → 0.62.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 +55 -0
- package/docs/agents.md +7 -3
- package/docs/configuration.md +9 -5
- package/docs/extension-api.md +14 -7
- package/docs/models.md +1 -1
- package/docs/observability.md +1 -1
- package/docs/tool-reference.md +13 -4
- package/docs/workflows.md +14 -13
- package/install.mjs +1 -1
- package/package.json +1 -1
- package/skills/pi-subagents/SKILL.md +6 -4
- package/skills/pi-subagents/references/constraints-and-recipes.md +1 -1
- package/skills/pi-subagents/references/execution-controls.md +41 -11
- package/skills/pi-subagents/references/multi-lane-orchestration.md +1 -1
- package/skills/pi-subagents/references/prompting-and-roles.md +4 -4
- package/skills/pi-subagents/references/review-and-validation.md +1 -1
- package/src/agents/agent-management.ts +121 -63
- package/src/agents/agent-serializer.ts +3 -0
- package/src/agents/agents.ts +543 -223
- package/src/agents/runtime-agent-registry.ts +5 -1
- package/src/api/background-work.ts +7 -2
- package/src/api/external-runs.ts +67 -4
- package/src/api/preflight.ts +17 -8
- package/src/api/shared-types.ts +1 -0
- package/src/extension/index.ts +7 -4
- package/src/extension/public-execution.ts +48 -4
- package/src/extension/rpc.ts +62 -4
- package/src/extension/schemas.ts +17 -9
- package/src/extension/tool-description.ts +15 -19
- package/src/runs/background/active-async-capacity.ts +26 -7
- package/src/runs/background/async-execution.ts +98 -51
- package/src/runs/background/async-job-tracker.ts +62 -3
- package/src/runs/background/async-resume.ts +6 -3
- package/src/runs/background/async-status.ts +59 -9
- package/src/runs/background/auto-drain.ts +1 -1
- package/src/runs/background/fleet-view.ts +1 -1
- package/src/runs/background/process-terminal.ts +16 -0
- package/src/runs/background/result-watcher.ts +1 -1
- package/src/runs/background/resume-guidance.ts +1 -1
- package/src/runs/background/run-status.ts +2 -2
- package/src/runs/background/scheduled-runs.ts +63 -6
- package/src/runs/background/steering.ts +4 -1
- package/src/runs/background/subagent-runner.ts +15 -9
- package/src/runs/background/subagent-wait.ts +20 -21
- package/src/runs/background/wait-completions.ts +1 -1
- package/src/runs/background/wait-tool.ts +18 -18
- package/src/runs/foreground/execution.ts +75 -9
- package/src/runs/foreground/subagent-executor.ts +181 -60
- package/src/runs/shared/acceptance.ts +113 -27
- package/src/runs/shared/capability-ceiling.ts +1 -0
- package/src/runs/shared/dynamic-fanout.ts +1 -1
- package/src/runs/shared/host-step-status.ts +1 -0
- package/src/runs/shared/model-fallback.ts +61 -17
- package/src/runs/shared/parallel-utils.ts +2 -6
- package/src/runs/shared/permissions.ts +1 -1
- package/src/runs/shared/pi-args.ts +24 -12
- package/src/runs/shared/pi-spawn.ts +69 -35
- package/src/runs/shared/structured-output.ts +33 -6
- package/src/runs/shared/subagent-prompt-runtime.ts +20 -3
- package/src/runs/shared/task-intent.ts +17 -6
- package/src/runs/shared/tool-timeout.ts +1 -1
- package/src/runs/shared/workflow-graph.ts +3 -2
- package/src/shared/atomic-json.ts +3 -1
- package/src/shared/fork-context.ts +0 -12
- package/src/shared/fork-session-cwd.ts +27 -0
- package/src/shared/launch-contract.ts +3 -0
- package/src/shared/types.ts +43 -4
- package/src/shared/workflow-child-permit.ts +91 -0
- package/src/slash/prompt-template-bridge.ts +37 -1
- package/src/slash/slash-commands.ts +18 -26
- package/src/slash/subagents-admin.ts +2 -0
- package/src/tui/render.ts +95 -52
- package/src/workflows/scripted-workflow.ts +153 -4
- package/src/workflows/workflow-child-summary.ts +1 -1
- package/src/workflows/workflow-receipt.ts +41 -4
- package/src/workflows/workflow-resources.ts +150 -0
|
@@ -23,11 +23,11 @@ import { handleManagementAction } from "../../agents/agent-management.ts";
|
|
|
23
23
|
import { handleRefinementAction } from "../../agents/agent-refinements.ts";
|
|
24
24
|
import { buildDoctorReport } from "../../extension/doctor.ts";
|
|
25
25
|
import { readSubagentGuide } from "../../extension/subagent-guide.ts";
|
|
26
|
-
import { normalizePublicSubagentExecution } from "../../extension/public-execution.ts";
|
|
26
|
+
import { normalizePublicSubagentExecution, validateWorkflowCapacityOverrides } from "../../extension/public-execution.ts";
|
|
27
27
|
import { runSync } from "./execution.ts";
|
|
28
28
|
import { handleWatchdogToolAction, WATCHDOG_TOOL_ACTIONS } from "../../watchdog/tool-actions.ts";
|
|
29
29
|
import type { MainWatchdogRuntime } from "../../watchdog/runtime.ts";
|
|
30
|
-
import { buildModelCandidates,
|
|
30
|
+
import { buildModelCandidates, normalizeParentModel, resolveEffectiveSubagentModel, resolveModelOrigin, type ModelOrigin, type ParentModel } from "../shared/model-fallback.ts";
|
|
31
31
|
import { formatRetainedChildren, listRetainedChildren } from "../background/retained-children.ts";
|
|
32
32
|
import { resolveModelScopesForAgent, type ModelScopeConfig } from "../shared/model-scope.ts";
|
|
33
33
|
import { recordRun } from "../shared/run-history.ts";
|
|
@@ -50,7 +50,7 @@ import { acquireActiveAsyncCapacity, ActiveAsyncCapacityError, getActiveAsyncCap
|
|
|
50
50
|
import { isScheduledRunAction } from "../background/scheduled-runs.ts";
|
|
51
51
|
import { enqueueChainAppendRequest, readPendingChainAppendRequests, runnerStepOutputNames } from "../background/chain-append.ts";
|
|
52
52
|
import { ChainOutputValidationError, validateChainOutputBindingsWithContext } from "../shared/chain-outputs.ts";
|
|
53
|
-
import { normalizeGateAcceptance, validateExecutionAcceptance } from "../shared/acceptance.ts";
|
|
53
|
+
import { normalizeGateAcceptance, resolveAcceptanceReportMode, validateExecutionAcceptance } from "../shared/acceptance.ts";
|
|
54
54
|
import { canPreferFork, createForkContextResolver, forkedChildRequiresThinkingOff, resolveSubagentLaunchContext } from "../../shared/fork-context.ts";
|
|
55
55
|
import { createPrunedForkSessionWriter } from "../../shared/pruned-fork.ts";
|
|
56
56
|
import { resolveCurrentSessionId } from "../../shared/session-identity.ts";
|
|
@@ -120,7 +120,17 @@ import { assertWorkflowLaneKey, normalizeWorkflowLaneMetadata } from "../shared/
|
|
|
120
120
|
import { parseWorkflowChildSummary, workflowChildSummary } from "../../workflows/workflow-child-summary.ts";
|
|
121
121
|
import { resolveWorkflowChatProgress, type WorkflowChatProgressProjection } from "../../workflows/chat-progress.ts";
|
|
122
122
|
import { annotateWorkflowPreflightTrace, formatWorkflowPreflight, formatWorkflowPreflightWarnings, normalizeWorkflowPreflight, workflowPreflightWarnings } from "../../workflows/workflow-preflight.ts";
|
|
123
|
-
import {
|
|
123
|
+
import {
|
|
124
|
+
authorizeWorkflowResourceHost,
|
|
125
|
+
claimWorkflowChildPermit,
|
|
126
|
+
consumeWorkflowResourcePermit,
|
|
127
|
+
validateWorkflowChildPermitRoot,
|
|
128
|
+
type WorkflowChildPermit,
|
|
129
|
+
type WorkflowChildPermitContext,
|
|
130
|
+
type WorkflowResourceAuthority,
|
|
131
|
+
type WorkflowResourcePermit,
|
|
132
|
+
} from "../../shared/workflow-child-permit.ts";
|
|
133
|
+
import { resolveWorkflowResource } from "../../workflows/workflow-resources.ts";
|
|
124
134
|
import {
|
|
125
135
|
cleanupWorktrees,
|
|
126
136
|
createWorktrees,
|
|
@@ -160,6 +170,7 @@ import {
|
|
|
160
170
|
type ToolBudgetConfig,
|
|
161
171
|
type Usage,
|
|
162
172
|
type UsageBudgetConfig,
|
|
173
|
+
type WorkflowResourceProvenanceV1,
|
|
163
174
|
type WorkflowGraphNode,
|
|
164
175
|
type WorkflowGraphSnapshot,
|
|
165
176
|
type WorkflowNodeStatus,
|
|
@@ -309,6 +320,8 @@ export interface SubagentParamsLike {
|
|
|
309
320
|
planId?: string;
|
|
310
321
|
workflowScript?: string;
|
|
311
322
|
workflowScriptPath?: string;
|
|
323
|
+
globalConcurrencyLimit?: number;
|
|
324
|
+
maxSubagentSpawnsPerRun?: number;
|
|
312
325
|
preflight?: import("../../shared/types.ts").WorkflowPreflightV1;
|
|
313
326
|
chatProgress?: "auto" | "off" | "live-card";
|
|
314
327
|
isolation?: "none" | "worktree";
|
|
@@ -357,8 +370,13 @@ export interface SubagentParamsLike {
|
|
|
357
370
|
artifacts?: boolean;
|
|
358
371
|
includeProgress?: boolean;
|
|
359
372
|
model?: string;
|
|
373
|
+
/** Internal recovery provenance for a resolved model override. */
|
|
374
|
+
modelOrigin?: ModelOrigin;
|
|
360
375
|
fast?: boolean;
|
|
361
376
|
thinking?: string | false;
|
|
377
|
+
/** Public named workflow resource. Resolved before entering the workflow sandbox. */
|
|
378
|
+
workflow?: string;
|
|
379
|
+
args?: Record<string, unknown>;
|
|
362
380
|
scope?: string;
|
|
363
381
|
target?: string;
|
|
364
382
|
focus?: boolean;
|
|
@@ -375,6 +393,7 @@ export interface SubagentParamsLike {
|
|
|
375
393
|
agentContract?: AgentContract;
|
|
376
394
|
at?: string;
|
|
377
395
|
every?: string;
|
|
396
|
+
sessionOnly?: boolean;
|
|
378
397
|
on?: string | number;
|
|
379
398
|
timezone?: string;
|
|
380
399
|
overlap?: "skip";
|
|
@@ -418,9 +437,9 @@ interface ExecutorDeps {
|
|
|
418
437
|
kill?: (pid: number, signal?: NodeJS.Signals | 0) => boolean;
|
|
419
438
|
}
|
|
420
439
|
|
|
421
|
-
type ForkSessionFileForTask = (agentName: string, idx?: number, modelOverride?: string, modelOverrideFromParent?: boolean) => string | undefined;
|
|
422
|
-
type PrepareForkSessionForTask = (agentName: string, idx?: number, modelOverride?: string, modelOverrideFromParent?: boolean) => Promise<void>;
|
|
423
|
-
type ForkThinkingOverrideForTask = (agentName: string, idx?: number, modelOverride?: string, modelOverrideFromParent?: boolean) => AgentConfig["thinking"] | undefined;
|
|
440
|
+
type ForkSessionFileForTask = (agentName: string, idx?: number, modelOverride?: string, modelOverrideFromParent?: boolean, modelOrigin?: ModelOrigin) => string | undefined;
|
|
441
|
+
type PrepareForkSessionForTask = (agentName: string, idx?: number, modelOverride?: string, modelOverrideFromParent?: boolean, modelOrigin?: ModelOrigin) => Promise<void>;
|
|
442
|
+
type ForkThinkingOverrideForTask = (agentName: string, idx?: number, modelOverride?: string, modelOverrideFromParent?: boolean, modelOrigin?: ModelOrigin) => AgentConfig["thinking"] | undefined;
|
|
424
443
|
|
|
425
444
|
interface ExecutionContextData {
|
|
426
445
|
params: SubagentParamsLike;
|
|
@@ -447,6 +466,8 @@ interface ExecutionContextData {
|
|
|
447
466
|
effectiveAsync: boolean;
|
|
448
467
|
asyncRunId: string;
|
|
449
468
|
controlConfig: ResolvedControlConfig;
|
|
469
|
+
/** Structured delegation consumers do not need duration-only heartbeat snapshots. */
|
|
470
|
+
suppressUnchangedDelegationUpdates?: boolean;
|
|
450
471
|
intercomBridge: IntercomBridgeState;
|
|
451
472
|
nestedRoute?: NestedRouteInfo;
|
|
452
473
|
timeoutMs?: number;
|
|
@@ -865,7 +886,7 @@ function resolveForegroundResumeTarget(params: SubagentParamsLike, state: Subage
|
|
|
865
886
|
if (matches.length === 0) return undefined;
|
|
866
887
|
if (matches.length > 1) throw new Error(`Ambiguous foreground run id prefix '${requested}' matched: ${matches.map((run) => run.runId).join(", ")}. Provide a longer id.`);
|
|
867
888
|
const run = matches[0]!;
|
|
868
|
-
if (run.children.some((child) => child.status === "detached")) throw new Error(`Foreground run '${run.runId}' is detached for intercom coordination and cannot be revived safely while any child may still be live. Reply to the supervisor request first, then wait with
|
|
889
|
+
if (run.children.some((child) => child.status === "detached")) throw new Error(`Foreground run '${run.runId}' is detached for intercom coordination and cannot be revived safely while any child may still be live. Reply to the supervisor request first, then wait with bg_wait({ id: "${run.runId}" }); use status to recover the result and do not launch a replacement while it remains detached.`);
|
|
869
890
|
if (run.children.length > 1 && params.index === undefined) throw new Error(`Foreground run '${run.runId}' has ${run.children.length} children. Provide index to choose one.`);
|
|
870
891
|
const index = params.index ?? 0;
|
|
871
892
|
if (!Number.isInteger(index)) throw new Error(`Foreground run '${run.runId}' index must be an integer.`);
|
|
@@ -2024,6 +2045,7 @@ async function resumeAsyncRun(input: {
|
|
|
2024
2045
|
modelOverride: recoveryDescriptor?.model ?? target.model,
|
|
2025
2046
|
fast: recoveryDescriptor?.fast,
|
|
2026
2047
|
modelOverrideFromParent: recoveryDescriptor?.modelOverrideFromParent,
|
|
2048
|
+
modelOrigin: recoveryDescriptor?.modelOrigin ?? (recoveryDescriptor?.modelOverrideFromParent ? "inherited" : undefined),
|
|
2027
2049
|
thinkingOverride: recoveryDescriptor?.thinking ?? target.thinking,
|
|
2028
2050
|
thinkingCeiling: recoveryDescriptor?.thinkingCeiling ?? ("thinkingCeiling" in target ? target.thinkingCeiling : undefined),
|
|
2029
2051
|
extensionBindings: recoveryDescriptor?.extensionBindings ?? ("extensionBindings" in target ? target.extensionBindings : undefined),
|
|
@@ -2997,7 +3019,15 @@ async function preflightForkSessionsForStaticTasks(
|
|
|
2997
3019
|
): Promise<void> {
|
|
2998
3020
|
if (!contextPolicy.usesFork) return;
|
|
2999
3021
|
if (params.agent) {
|
|
3000
|
-
if (shouldForkAgent(contextPolicy, params.agent))
|
|
3022
|
+
if (shouldForkAgent(contextPolicy, params.agent)) {
|
|
3023
|
+
await prepareSessionForTask(
|
|
3024
|
+
params.agent,
|
|
3025
|
+
0,
|
|
3026
|
+
params.model,
|
|
3027
|
+
params.modelOrigin === "inherited",
|
|
3028
|
+
params.modelOrigin,
|
|
3029
|
+
);
|
|
3030
|
+
}
|
|
3001
3031
|
return;
|
|
3002
3032
|
}
|
|
3003
3033
|
if (params.tasks) {
|
|
@@ -3175,10 +3205,19 @@ async function runAsyncPath(data: ExecutionContextData, deps: ExecutorDeps): Pro
|
|
|
3175
3205
|
return buildRequestedModeError(params, `Agent '${a.name}' uses runner.type='${a.runner.type}' and does not support fast mode.`);
|
|
3176
3206
|
}
|
|
3177
3207
|
const modelScopes = resolveModelScopesForAgent(data.modelScope, a.name, parentModel);
|
|
3208
|
+
const modelOrigin = resolveModelOrigin({
|
|
3209
|
+
storedOrigin: params.modelOrigin as ModelOrigin | undefined,
|
|
3210
|
+
explicitModel: params.model as string | undefined,
|
|
3211
|
+
agentModel: a.model,
|
|
3212
|
+
parentModel,
|
|
3213
|
+
});
|
|
3178
3214
|
const modelOverride = a.runner?.type === "external-cli" || a.runner?.type === "external-job"
|
|
3179
3215
|
? params.model ?? (externalRunnerWithoutExplicitModel ? undefined : a.model)
|
|
3180
|
-
: resolveEffectiveSubagentModel(params.model as string | undefined, a.model, parentModel, availableModels, a.modelProvider ?? currentProvider,
|
|
3181
|
-
|
|
3216
|
+
: resolveEffectiveSubagentModel(params.model as string | undefined, a.model, parentModel, availableModels, a.modelProvider ?? currentProvider, {
|
|
3217
|
+
...(modelScopes.length === 0 ? {} : { scope: modelScopes }),
|
|
3218
|
+
source: modelOrigin === "explicit" ? "explicit" : "inherited",
|
|
3219
|
+
});
|
|
3220
|
+
const modelOverrideFromParent = modelOrigin === "inherited";
|
|
3182
3221
|
const asyncResult = executeAsyncSingle(id, compactOptional<Parameters<typeof executeAsyncSingle>[1]>({
|
|
3183
3222
|
agent: params.agent!,
|
|
3184
3223
|
task: shouldForkAgent(contextPolicy, params.agent!) ? wrapForkTask(params.task ?? "") : (params.task ?? ""),
|
|
@@ -3195,7 +3234,7 @@ async function runAsyncPath(data: ExecutionContextData, deps: ExecutorDeps): Pro
|
|
|
3195
3234
|
shareEnabled,
|
|
3196
3235
|
activeAsyncCapacity: data.activeAsyncCapacity,
|
|
3197
3236
|
sessionRoot,
|
|
3198
|
-
sessionFile: sessionFileForTask(params.agent!, 0, modelOverride, modelOverrideFromParent),
|
|
3237
|
+
sessionFile: sessionFileForTask(params.agent!, 0, modelOverride, modelOverrideFromParent, modelOrigin),
|
|
3199
3238
|
context: contextPolicy.contextForAgent(params.agent!),
|
|
3200
3239
|
skills,
|
|
3201
3240
|
output: effectiveOutput,
|
|
@@ -3206,7 +3245,8 @@ async function runAsyncPath(data: ExecutionContextData, deps: ExecutorDeps): Pro
|
|
|
3206
3245
|
modelOverride,
|
|
3207
3246
|
fast: params.fast,
|
|
3208
3247
|
modelOverrideFromParent,
|
|
3209
|
-
|
|
3248
|
+
modelOrigin,
|
|
3249
|
+
thinkingOverride: externalRunnerWithoutExplicitModel ? undefined : thinkingOverrideForTask(params.agent!, 0, modelOverride, modelOverrideFromParent, modelOrigin),
|
|
3210
3250
|
thinkingCeiling: a.maxThinking,
|
|
3211
3251
|
maxSubagentDepth,
|
|
3212
3252
|
waitToolEnabled: deps.waitToolEnabled,
|
|
@@ -3311,8 +3351,11 @@ function workflowHostCommandRunner(input: {
|
|
|
3311
3351
|
workflowRunId: string;
|
|
3312
3352
|
claimedOutputPaths: Map<string, string>;
|
|
3313
3353
|
producedOutputPaths: Set<string>;
|
|
3354
|
+
authorize?: (key: string, params: WorkflowHostCommandParams) => string | undefined;
|
|
3314
3355
|
}) {
|
|
3315
3356
|
return async (key: string, params: WorkflowHostCommandParams, signal: AbortSignal): Promise<WorkflowHostCommandResult> => {
|
|
3357
|
+
const authorizationError = input.authorize?.(key, params);
|
|
3358
|
+
if (authorizationError) throw new Error(authorizationError);
|
|
3316
3359
|
const defaultOutputPath = path.join(input.artifactsDir, "outputs", sanitizeRunPathSegment(input.workflowRunId), "host", `${sanitizeRunPathSegment(key)}.log`);
|
|
3317
3360
|
const outputPath = params.output ? path.resolve(input.workflowCwd, params.output) : defaultOutputPath;
|
|
3318
3361
|
const claimPath = resolveWorkflowHostOutputClaimPath(outputPath);
|
|
@@ -3552,6 +3595,7 @@ async function runSinglePath(data: ExecutionContextData, deps: ExecutorDeps): Pr
|
|
|
3552
3595
|
onUpdate,
|
|
3553
3596
|
controlConfig,
|
|
3554
3597
|
contextPolicy,
|
|
3598
|
+
suppressUnchangedDelegationUpdates,
|
|
3555
3599
|
} = data;
|
|
3556
3600
|
let lane: import("../../shared/types.ts").WorkflowLaneMetadata | undefined;
|
|
3557
3601
|
try {
|
|
@@ -3581,15 +3625,24 @@ async function runSinglePath(data: ExecutionContextData, deps: ExecutorDeps): Pr
|
|
|
3581
3625
|
const availableModels: ModelInfo[] = ctx.modelRegistry.getAvailable().map(toModelInfo);
|
|
3582
3626
|
const modelScopes = resolveModelScopesForAgent(data.modelScope, agentConfig.name, parentModel);
|
|
3583
3627
|
let task = typeof params.task === "string" ? params.task : "";
|
|
3628
|
+
const modelOrigin = resolveModelOrigin({
|
|
3629
|
+
storedOrigin: params.modelOrigin as ModelOrigin | undefined,
|
|
3630
|
+
explicitModel: params.model as string | undefined,
|
|
3631
|
+
agentModel: agentConfig.model,
|
|
3632
|
+
parentModel,
|
|
3633
|
+
});
|
|
3584
3634
|
let modelOverride: string | undefined = resolveEffectiveSubagentModel(
|
|
3585
3635
|
params.model as string | undefined,
|
|
3586
3636
|
agentConfig.model,
|
|
3587
3637
|
parentModel,
|
|
3588
3638
|
availableModels,
|
|
3589
3639
|
agentConfig.modelProvider ?? currentProvider,
|
|
3590
|
-
|
|
3640
|
+
{
|
|
3641
|
+
...(modelScopes.length === 0 ? {} : { scope: modelScopes }),
|
|
3642
|
+
source: modelOrigin === "explicit" ? "explicit" : "inherited",
|
|
3643
|
+
},
|
|
3591
3644
|
);
|
|
3592
|
-
const modelOverrideFromParent =
|
|
3645
|
+
const modelOverrideFromParent = modelOrigin === "inherited";
|
|
3593
3646
|
let skillOverride: string[] | false | undefined = normalizeSkillInput(params.skill);
|
|
3594
3647
|
let readsOverride: string[] | false | undefined = params.reads;
|
|
3595
3648
|
const rawOutput = params.output !== undefined ? params.output : agentConfig.output;
|
|
@@ -3638,7 +3691,7 @@ async function runSinglePath(data: ExecutionContextData, deps: ExecutorDeps): Pr
|
|
|
3638
3691
|
return { content: [{ type: "text", text: validationError }], isError: true, details: { mode: "single", results: [] } };
|
|
3639
3692
|
}
|
|
3640
3693
|
const structuredRuntime = params.outputSchema
|
|
3641
|
-
? createStructuredOutputRuntime(params.outputSchema, artifactConfig.enabled ? path.join(artifactsDir, "structured-output", runId) : undefined, {
|
|
3694
|
+
? createStructuredOutputRuntime(params.outputSchema, artifactConfig.enabled ? path.join(artifactsDir, "structured-output", runId) : undefined, { acceptanceReport: resolveAcceptanceReportMode(params.acceptance) })
|
|
3642
3695
|
: undefined;
|
|
3643
3696
|
// Reads: caller override > agent defaultReads > none. `~`/`~/` expand to home;
|
|
3644
3697
|
// absolute paths pass through; relative paths resolve against the child cwd.
|
|
@@ -3660,7 +3713,7 @@ async function runSinglePath(data: ExecutionContextData, deps: ExecutorDeps): Pr
|
|
|
3660
3713
|
let detachForeground: ((reason?: string) => boolean) | undefined;
|
|
3661
3714
|
const foregroundControl = deps.state.foregroundControls.get(runId);
|
|
3662
3715
|
if (foregroundControl) {
|
|
3663
|
-
const thinking = resolveEffectiveThinking(modelOverride, thinkingOverrideForTask(params.agent!, 0, modelOverride, modelOverrideFromParent));
|
|
3716
|
+
const thinking = resolveEffectiveThinking(modelOverride, thinkingOverrideForTask(params.agent!, 0, modelOverride, modelOverrideFromParent, modelOrigin));
|
|
3664
3717
|
beginForegroundChild(foregroundControl, omitUndefinedProperties({
|
|
3665
3718
|
index: 0,
|
|
3666
3719
|
agent: params.agent!,
|
|
@@ -3712,7 +3765,7 @@ async function runSinglePath(data: ExecutionContextData, deps: ExecutorDeps): Pr
|
|
|
3712
3765
|
intercomEvents: deps.pi.events,
|
|
3713
3766
|
runId,
|
|
3714
3767
|
sessionDir: sessionDirForIndex(0),
|
|
3715
|
-
sessionFile: sessionFileForTask(params.agent!, 0, modelOverride, modelOverrideFromParent),
|
|
3768
|
+
sessionFile: sessionFileForTask(params.agent!, 0, modelOverride, modelOverrideFromParent, modelOrigin),
|
|
3716
3769
|
share: shareEnabled,
|
|
3717
3770
|
artifactsDir: artifactConfig.enabled ? artifactsDir : undefined,
|
|
3718
3771
|
artifactConfig,
|
|
@@ -3724,6 +3777,7 @@ async function runSinglePath(data: ExecutionContextData, deps: ExecutorDeps): Pr
|
|
|
3724
3777
|
waitToolEnabled: deps.waitToolEnabled,
|
|
3725
3778
|
waitToolDefaultTimeoutMs: deps.waitToolDefaultTimeoutMs,
|
|
3726
3779
|
onUpdate: forwardSingleUpdate,
|
|
3780
|
+
suppressUnchangedDelegationUpdates,
|
|
3727
3781
|
controlConfig,
|
|
3728
3782
|
onControlEvent,
|
|
3729
3783
|
intercomSessionName: childIntercomTarget,
|
|
@@ -3733,7 +3787,8 @@ async function runSinglePath(data: ExecutionContextData, deps: ExecutorDeps): Pr
|
|
|
3733
3787
|
modelOverride,
|
|
3734
3788
|
fast: params.fast,
|
|
3735
3789
|
modelOverrideFromParent,
|
|
3736
|
-
|
|
3790
|
+
modelOrigin,
|
|
3791
|
+
thinkingOverride: thinkingOverrideForTask(params.agent!, 0, modelOverride, modelOverrideFromParent, modelOrigin),
|
|
3737
3792
|
thinkingCeiling: agentConfig.maxThinking,
|
|
3738
3793
|
extensionBindings: params.extensionBindings,
|
|
3739
3794
|
availableModels,
|
|
@@ -3880,11 +3935,11 @@ async function runSinglePath(data: ExecutionContextData, deps: ExecutorDeps): Pr
|
|
|
3880
3935
|
const worktreeSuffix = worktreeHandoff?.suffix ? `\n\n${worktreeHandoff.suffix}` : "";
|
|
3881
3936
|
if (r.detached) {
|
|
3882
3937
|
const statusRecovery = `subagent({ action: "status", id: "${runId}" }) to recover the result; do not resume or launch a replacement while it remains detached.`;
|
|
3883
|
-
const blockingRecovery = `
|
|
3938
|
+
const blockingRecovery = `bg_wait({ id: "${runId}" }). Use ${statusRecovery}`;
|
|
3884
3939
|
const message = r.detachedReason === "intercom coordination"
|
|
3885
3940
|
? `Detached for intercom coordination: ${params.agent}. Reply to the supervisor request first, then wait with ${blockingRecovery}`
|
|
3886
3941
|
: r.detachedReason === "user request"
|
|
3887
|
-
? `Detached at user request: ${params.agent}. The child continues independently. Register a completion wake-up with
|
|
3942
|
+
? `Detached at user request: ${params.agent}. The child continues independently. Register a completion wake-up with bg_wait({ id: "${runId}", nonBlocking: true }), or use ${statusRecovery}`
|
|
3888
3943
|
: `Detached before task completion: ${params.agent}. Wait with ${blockingRecovery}`;
|
|
3889
3944
|
return {
|
|
3890
3945
|
content: [{ type: "text", text: `${message}${worktreeSuffix}` }],
|
|
@@ -4022,7 +4077,8 @@ function workflowChildResult(
|
|
|
4022
4077
|
: result.details.usageBudget?.exhausted || result.details.results.some((child) => child.turnBudgetExceeded || child.toolBudgetBlocked)
|
|
4023
4078
|
? { state: "partial" as const, reason: "budget_exhausted" as const }
|
|
4024
4079
|
: undefined);
|
|
4025
|
-
const
|
|
4080
|
+
const acceptanceRecovery = result.details.results.find((child) => child.acceptance?.recovery)?.acceptance?.recovery;
|
|
4081
|
+
const ok = result.isError !== true && !detached && !interrupted && !stopped && acceptanceRecovery === undefined;
|
|
4026
4082
|
const artifactPaths = new Set<string>();
|
|
4027
4083
|
if (result.details.asyncDir) artifactPaths.add(result.details.asyncDir);
|
|
4028
4084
|
if (result.details.parallelHandoff?.path) artifactPaths.add(result.details.parallelHandoff.path);
|
|
@@ -4080,6 +4136,7 @@ function workflowChildResult(
|
|
|
4080
4136
|
...(requestedContext ? { requestedContext } : {}),
|
|
4081
4137
|
...(resolvedContext ? { resolvedContext } : {}),
|
|
4082
4138
|
...(outputReference ? { outputReference } : {}),
|
|
4139
|
+
...(acceptanceRecovery ? { recovery: acceptanceRecovery } : {}),
|
|
4083
4140
|
...(outputPathMapping ? { outputPathMapping } : {}),
|
|
4084
4141
|
...(externalAdapter ? { externalAdapter } : {}),
|
|
4085
4142
|
resumability,
|
|
@@ -4089,13 +4146,14 @@ function workflowChildResult(
|
|
|
4089
4146
|
};
|
|
4090
4147
|
}
|
|
4091
4148
|
|
|
4092
|
-
function workflowChildAccountingFields(child: WorkflowScriptChildResult): { usage?: Usage; sessionFile?: string } {
|
|
4149
|
+
function workflowChildAccountingFields(child: WorkflowScriptChildResult): { usage?: Usage; sessionFile?: string; recovery?: import("../../shared/types.ts").AcceptanceRecoveryMetadata } {
|
|
4093
4150
|
if (!child.results?.length) return {};
|
|
4094
4151
|
const usage = sumResultsUsage(child.results);
|
|
4095
4152
|
const sessionFile = child.results.find((result) => result.sessionFile)?.sessionFile;
|
|
4096
4153
|
return {
|
|
4097
4154
|
...(usage.input !== 0 || usage.output !== 0 || usage.cacheRead !== 0 || usage.cacheWrite !== 0 || usage.cost !== 0 || usage.turns !== 0 ? { usage } : {}),
|
|
4098
4155
|
...(sessionFile ? { sessionFile } : {}),
|
|
4156
|
+
...(child.recovery ? { recovery: child.recovery } : {}),
|
|
4099
4157
|
};
|
|
4100
4158
|
}
|
|
4101
4159
|
|
|
@@ -4223,8 +4281,9 @@ function terminalWorkflowReceipt(
|
|
|
4223
4281
|
workflowChildren?: WorkflowReceipt["workflowChildren"],
|
|
4224
4282
|
terminalOutcome?: WorkflowTerminalOutcome,
|
|
4225
4283
|
hostSteps?: WorkflowReceipt["hostSteps"],
|
|
4284
|
+
resource?: WorkflowReceipt["resource"],
|
|
4226
4285
|
): WorkflowReceipt {
|
|
4227
|
-
return buildWorkflowReceipt({ workflowRunId, state, children, workflowChildren, terminalOutcome, hostSteps });
|
|
4286
|
+
return buildWorkflowReceipt({ workflowRunId, state, children, workflowChildren, terminalOutcome, hostSteps, resource });
|
|
4228
4287
|
}
|
|
4229
4288
|
|
|
4230
4289
|
function workflowFailureTerminalOutcome(error: unknown, _children: WorkflowScriptChildResult[], usageBudget: ReturnType<typeof usageBudgetState>): WorkflowTerminalOutcome | undefined {
|
|
@@ -4316,6 +4375,10 @@ export function prepareWorkflowLaunchParams(
|
|
|
4316
4375
|
workflowKey: string,
|
|
4317
4376
|
options: { missionDetached?: boolean; suppressRoutineResultIntercom?: boolean; awaitDetachedChild?: boolean; runFanoutBudget?: RunFanoutBudgetDescriptor; parentDeadlineAt?: number; externalAsyncRequired?: boolean; capabilityCeiling?: ResolvedSubagentCapabilityCeiling; outputClaimPath?: string } = {},
|
|
4318
4377
|
): SubagentParamsLike {
|
|
4378
|
+
const { globalConcurrencyLimit: _globalConcurrencyLimit, maxSubagentSpawnsPerRun: _maxSubagentSpawnsPerRun, ...workflowDefaultsWithoutCapacity } = workflowDefaults;
|
|
4379
|
+
const { globalConcurrencyLimit: _childGlobalConcurrencyLimit, maxSubagentSpawnsPerRun: _childMaxSubagentSpawnsPerRun, ...childParamsWithoutCapacity } = childParams;
|
|
4380
|
+
workflowDefaults = workflowDefaultsWithoutCapacity;
|
|
4381
|
+
childParams = childParamsWithoutCapacity;
|
|
4319
4382
|
const capabilityCeiling = intersectSubagentCapabilityCeilings(workflowDefaults.capabilityCeiling, options.capabilityCeiling);
|
|
4320
4383
|
const lane = normalizeWorkflowLaneMetadata(Object.hasOwn(childParams, "lane") ? childParams.lane : workflowDefaults.lane, `workflow child '${workflowKey}'.lane`);
|
|
4321
4384
|
assertWorkflowLaneKey(lane, workflowKey, `workflow child '${workflowKey}'.lane`);
|
|
@@ -4586,6 +4649,8 @@ export function createSubagentExecutor(deps: ExecutorDeps): {
|
|
|
4586
4649
|
const delegatedThinkingOverrides = new WeakMap<object, AgentConfig["thinking"]>();
|
|
4587
4650
|
const delegatedZeroToolBudgets = new WeakSet<object>();
|
|
4588
4651
|
const delegatedExecutions = new WeakSet<object>();
|
|
4652
|
+
const publicExecutions = new WeakSet<object>();
|
|
4653
|
+
const workflowResourcePermits = new WeakMap<object, WorkflowResourcePermit>();
|
|
4589
4654
|
const workflowPermitContexts = new WeakMap<object, { root: WorkflowChildPermit } | { child: WorkflowChildPermitContext }>();
|
|
4590
4655
|
const warnedArtifactPackageDirs = new Set<string>();
|
|
4591
4656
|
const scheduledOwnerExecutors = new Map<string, ReturnType<typeof createSubagentExecutor>>();
|
|
@@ -4602,6 +4667,8 @@ export function createSubagentExecutor(deps: ExecutorDeps): {
|
|
|
4602
4667
|
const delegatedThinkingOverride = delegatedThinkingOverrides.get(params);
|
|
4603
4668
|
const allowZeroToolBudget = delegatedZeroToolBudgets.has(params);
|
|
4604
4669
|
const delegatedExecution = delegatedExecutions.has(params);
|
|
4670
|
+
const publicExecution = publicExecutions.has(params);
|
|
4671
|
+
const workflowResourcePermit = workflowResourcePermits.get(params);
|
|
4605
4672
|
const workflowPermitContext = workflowPermitContexts.get(params);
|
|
4606
4673
|
const delegatedWorkflowPermit = workflowPermitContext && "root" in workflowPermitContext ? workflowPermitContext.root : undefined;
|
|
4607
4674
|
const workflowChildPermitLaunch = workflowPermitContext && "child" in workflowPermitContext ? workflowPermitContext.child : undefined;
|
|
@@ -4612,6 +4679,8 @@ export function createSubagentExecutor(deps: ExecutorDeps): {
|
|
|
4612
4679
|
const normalizedGate = normalizeGateParams(params);
|
|
4613
4680
|
if (!normalizedGate.ok) return buildRequestedModeError(params, normalizedGate.error);
|
|
4614
4681
|
let requestParams = normalizedGate.params;
|
|
4682
|
+
const capacityOverrideError = validateWorkflowCapacityOverrides(requestParams);
|
|
4683
|
+
if (capacityOverrideError) return buildRequestedModeError(requestParams, capacityOverrideError);
|
|
4615
4684
|
let workflowPreflight: import("../../shared/types.ts").WorkflowPreflightV1 | undefined;
|
|
4616
4685
|
try {
|
|
4617
4686
|
if (requestParams.preflight !== undefined && requestParams.workflowScript === undefined && requestParams.workflowScriptPath === undefined) {
|
|
@@ -4643,6 +4712,13 @@ export function createSubagentExecutor(deps: ExecutorDeps): {
|
|
|
4643
4712
|
}
|
|
4644
4713
|
const normalizedAction = typeof requestParams.action === "string" ? requestParams.action.trim() : requestParams.action;
|
|
4645
4714
|
if (normalizedAction === "resume" && requestParams.extensionBindings !== undefined) return buildRequestedModeError(requestParams, "extensionBindings is not supported with action='resume'; resume uses the original retained child binding.");
|
|
4715
|
+
let workflowResource: { permit: WorkflowResourcePermit; provenance: WorkflowResourceProvenanceV1; authority: WorkflowResourceAuthority } | undefined;
|
|
4716
|
+
if (workflowResourcePermit) {
|
|
4717
|
+
if (typeof requestParams.workflowScript !== "string") return buildRequestedModeError(requestParams, "Resolved workflow resource is missing its workflow script.");
|
|
4718
|
+
const consumed = consumeWorkflowResourcePermit(workflowResourcePermit, requestParams.workflowScript);
|
|
4719
|
+
if (typeof consumed === "string") return buildRequestedModeError(requestParams, consumed);
|
|
4720
|
+
workflowResource = { permit: workflowResourcePermit, ...consumed };
|
|
4721
|
+
}
|
|
4646
4722
|
if (requestParams.workflowScript !== undefined && normalizedAction === undefined) {
|
|
4647
4723
|
if (delegatedWorkflowPermit) {
|
|
4648
4724
|
const permitError = validateWorkflowChildPermitRoot(delegatedWorkflowPermit, _id);
|
|
@@ -4722,7 +4798,7 @@ export function createSubagentExecutor(deps: ExecutorDeps): {
|
|
|
4722
4798
|
try {
|
|
4723
4799
|
workflowFanoutBudget = requestParams.runFanoutBudget
|
|
4724
4800
|
?? decodeRunFanoutBudgetDescriptor(process.env[RUN_FANOUT_BUDGET_ENV])
|
|
4725
|
-
?? createRunFanoutBudget(_id, resolveMaxSubagentSpawnsPerRun(deps.config.maxSubagentSpawnsPerRun));
|
|
4801
|
+
?? createRunFanoutBudget(_id, requestParams.maxSubagentSpawnsPerRun ?? resolveMaxSubagentSpawnsPerRun(deps.config.maxSubagentSpawnsPerRun));
|
|
4726
4802
|
} catch (error) {
|
|
4727
4803
|
workflowCapacity?.rollback();
|
|
4728
4804
|
return { content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }], isError: true, details: { mode: "workflow", results: [] } };
|
|
@@ -4800,7 +4876,7 @@ export function createSubagentExecutor(deps: ExecutorDeps): {
|
|
|
4800
4876
|
pid: process.pid,
|
|
4801
4877
|
steps: [],
|
|
4802
4878
|
...(workflowPreflight ? { preflight: workflowPreflight } : {}),
|
|
4803
|
-
workflow: { trace: [], emits: [], console: [] },
|
|
4879
|
+
workflow: { trace: [], emits: [], console: [], ...(workflowResource ? { resource: workflowResource.provenance } : {}) },
|
|
4804
4880
|
workflowChildren: workflowChildSummary({ parentToolCallId: toolCallId, workflowRunId, workflowState: "running", inventoryComplete: false }),
|
|
4805
4881
|
runFanoutBudget: getRunFanoutBudgetSnapshot(workflowFanoutBudget),
|
|
4806
4882
|
};
|
|
@@ -4952,7 +5028,7 @@ export function createSubagentExecutor(deps: ExecutorDeps): {
|
|
|
4952
5028
|
const workflowDeadlineAt = timeout === undefined ? undefined : Date.now() + timeout;
|
|
4953
5029
|
const workflowResults: SingleResult[] = [];
|
|
4954
5030
|
const workflowChildRunIds = new Map<string, string>();
|
|
4955
|
-
const { action: _action, agent: _agent, task: _task, resume: _resume, tasks: _tasks, chain: _chain, concurrency: _concurrency, foregroundOnly: _foregroundOnly, clarify: _clarify, timeoutMs: _timeoutMs, maxRuntimeMs: _maxRuntimeMs, usageBudget: _usageBudget, missionId: _missionId, mission: _mission, preflight: _preflight, ...workflowChildDefaults } = workflowRequest;
|
|
5031
|
+
const { action: _action, agent: _agent, task: _task, resume: _resume, tasks: _tasks, chain: _chain, concurrency: _concurrency, foregroundOnly: _foregroundOnly, clarify: _clarify, timeoutMs: _timeoutMs, maxRuntimeMs: _maxRuntimeMs, usageBudget: _usageBudget, missionId: _missionId, mission: _mission, preflight: _preflight, globalConcurrencyLimit: _globalConcurrencyLimit, maxSubagentSpawnsPerRun: _maxSubagentSpawnsPerRun, ...workflowChildDefaults } = workflowRequest;
|
|
4956
5032
|
const workflowOutput = typeof workflowChildDefaults.output === "string" || typeof workflowChildDefaults.output === "boolean" ? workflowChildDefaults.output : undefined;
|
|
4957
5033
|
const configuredOutputBaseDir = resolveConfiguredSingleRunOutputBaseDir(deps);
|
|
4958
5034
|
const workflowAggregateOutputPath = resolveWorkflowAggregateOutputPath(workflowOutput, parentCwd, workflowCwd, resolveSingleRunOutputBaseDir(deps, workflowArtifactsDir, workflowRunId));
|
|
@@ -4961,7 +5037,17 @@ export function createSubagentExecutor(deps: ExecutorDeps): {
|
|
|
4961
5037
|
const childOutputClaimPaths = new Map<string, string>();
|
|
4962
5038
|
const producedChildOutputPaths = new Set<string>();
|
|
4963
5039
|
const workflowSteps = new Map<string, NonNullable<AsyncStatus["steps"]>[number]>();
|
|
4964
|
-
const runHostCommand = workflowHostCommandRunner({
|
|
5040
|
+
const runHostCommand = workflowHostCommandRunner({
|
|
5041
|
+
workflowCwd,
|
|
5042
|
+
artifactsDir: workflowArtifactsDir,
|
|
5043
|
+
workflowRunId,
|
|
5044
|
+
claimedOutputPaths,
|
|
5045
|
+
producedOutputPaths: producedChildOutputPaths,
|
|
5046
|
+
...(workflowResource ? { authorize: (key, params) => authorizeWorkflowResourceHost(workflowResource!.permit, key, params.command) } : {}),
|
|
5047
|
+
});
|
|
5048
|
+
const workflowHost = workflowResource
|
|
5049
|
+
? workflowResource.authority.host ? runHostCommand : undefined
|
|
5050
|
+
: publicExecution ? undefined : runHostCommand;
|
|
4965
5051
|
let projectedTraceLength = 0;
|
|
4966
5052
|
let projectedTraceTail: NonNullable<Details["workflow"]>["trace"][number] | undefined;
|
|
4967
5053
|
const updateTrace = (trace: NonNullable<Details["workflow"]>["trace"]) => {
|
|
@@ -5067,7 +5153,7 @@ export function createSubagentExecutor(deps: ExecutorDeps): {
|
|
|
5067
5153
|
try {
|
|
5068
5154
|
const workflow = await runWorkflowScript({
|
|
5069
5155
|
script: workflowScript,
|
|
5070
|
-
globalConcurrencyLimit: deps.config.globalConcurrencyLimit,
|
|
5156
|
+
globalConcurrencyLimit: requestParams.globalConcurrencyLimit ?? deps.config.globalConcurrencyLimit,
|
|
5071
5157
|
timeoutMs: timeout,
|
|
5072
5158
|
signal: controller.signal,
|
|
5073
5159
|
registerStopChild: (stop) => {
|
|
@@ -5081,7 +5167,7 @@ export function createSubagentExecutor(deps: ExecutorDeps): {
|
|
|
5081
5167
|
applyWorkflowLaneTrace(status.workflowGraph, status.workflow?.trace ?? []);
|
|
5082
5168
|
persist({ tolerateStatusWriteFailure: true });
|
|
5083
5169
|
},
|
|
5084
|
-
host:
|
|
5170
|
+
...(workflowHost ? { host: workflowHost } : {}),
|
|
5085
5171
|
onHostStep: (hostStep) => {
|
|
5086
5172
|
status = upsertHostStep({ status, hostStep, persist: (nextStatus) => {
|
|
5087
5173
|
status = nextStatus;
|
|
@@ -5206,8 +5292,8 @@ export function createSubagentExecutor(deps: ExecutorDeps): {
|
|
|
5206
5292
|
const resultSummary = appendWorkflowOutputWarning(summary, outputWarning);
|
|
5207
5293
|
const workflowUsage = sumResultsUsage(workflowResults);
|
|
5208
5294
|
const workflowChildren = workflowChildSummary({ parentToolCallId: toolCallId, workflowRunId, workflowState: "completed", inventoryComplete: true, trace: workflow.trace, children: workflow.children, steps: status.steps });
|
|
5209
|
-
status = { ...status, state: "complete", endedAt: Date.now(), workflow: { value: workflow.value, trace: finalPreflightTrace, emits: workflow.emits, console: workflow.console, ...(finalPreflightWarnings.length ? { preflightWarnings: finalPreflightWarnings } : {}) }, workflowChildren, totalTokens: { input: workflowUsage.input, output: workflowUsage.output, total: workflowUsage.input + workflowUsage.output }, totalCost: sumResultsCost(workflowResults) };
|
|
5210
|
-
const receipt = terminalWorkflowReceipt(workflowRunId, "complete", workflow.children, workflowChildren, undefined, validHostStepNodes(status.workflowGraph));
|
|
5295
|
+
status = { ...status, state: "complete", endedAt: Date.now(), workflow: { value: workflow.value, trace: finalPreflightTrace, emits: workflow.emits, console: workflow.console, ...(workflowResource ? { resource: workflowResource.provenance } : {}), ...(finalPreflightWarnings.length ? { preflightWarnings: finalPreflightWarnings } : {}) }, workflowChildren, totalTokens: { input: workflowUsage.input, output: workflowUsage.output, total: workflowUsage.input + workflowUsage.output }, totalCost: sumResultsCost(workflowResults) };
|
|
5296
|
+
const receipt = terminalWorkflowReceipt(workflowRunId, "complete", workflow.children, workflowChildren, undefined, validHostStepNodes(status.workflowGraph), workflowResource?.provenance);
|
|
5211
5297
|
let workflowReceipt: { path: string; receipt: WorkflowReceipt } | undefined;
|
|
5212
5298
|
try {
|
|
5213
5299
|
workflowReceipt = { path: writeWorkflowReceipt(asyncDir, receipt), receipt };
|
|
@@ -5241,7 +5327,7 @@ export function createSubagentExecutor(deps: ExecutorDeps): {
|
|
|
5241
5327
|
const workflowChildren = workflowChildSummary({ parentToolCallId: toolCallId, workflowRunId, workflowState, inventoryComplete: true, trace: partial.trace, children: partial.children, steps: status.steps });
|
|
5242
5328
|
const finalPreflightWarnings = workflowPreflightWarnings(workflowPreflight, partial.trace, { settled: true });
|
|
5243
5329
|
const finalPreflightTrace = annotateWorkflowPreflightTrace(partial.trace, workflowPreflight);
|
|
5244
|
-
status = compactOptional<AsyncStatus>({ ...status, state, stopped: stopped || undefined, activityState: pauseForDetached ? "needs_attention" : undefined, error: workflowFailureMessage(error, workflowRunId, partial.children), endedAt: Date.now(), workflow: { trace: finalPreflightTrace, emits: partial.emits, console: partial.console, ...(finalPreflightWarnings.length ? { preflightWarnings: finalPreflightWarnings } : {}) }, workflowChildren });
|
|
5330
|
+
status = compactOptional<AsyncStatus>({ ...status, state, stopped: stopped || undefined, activityState: pauseForDetached ? "needs_attention" : undefined, error: workflowFailureMessage(error, workflowRunId, partial.children), endedAt: Date.now(), workflow: { trace: finalPreflightTrace, emits: partial.emits, console: partial.console, ...(workflowResource ? { resource: workflowResource.provenance } : {}), ...(finalPreflightWarnings.length ? { preflightWarnings: finalPreflightWarnings } : {}) }, workflowChildren });
|
|
5245
5331
|
if (pauseForDetached) {
|
|
5246
5332
|
const promoted = promotePausedWorkflowIfSettled(status);
|
|
5247
5333
|
if (promoted) status = promoted;
|
|
@@ -5253,7 +5339,7 @@ export function createSubagentExecutor(deps: ExecutorDeps): {
|
|
|
5253
5339
|
const resultSummary = appendWorkflowOutputWarning(terminalSummary, outputWarning);
|
|
5254
5340
|
const receiptState: WorkflowReceiptState = status.state === "complete" ? "complete" : status.state === "paused" ? "paused" : status.state === "stopped" ? "stopped" : "failed";
|
|
5255
5341
|
const terminalOutcome = workflowFailureTerminalOutcome(error, partial.children, usageBudgetState(workflowUsageBudget.budget, sumResultsCost(workflowResults)));
|
|
5256
|
-
const receipt = terminalWorkflowReceipt(workflowRunId, receiptState, partial.children, workflowChildren, terminalOutcome, validHostStepNodes(status.workflowGraph));
|
|
5342
|
+
const receipt = terminalWorkflowReceipt(workflowRunId, receiptState, partial.children, workflowChildren, terminalOutcome, validHostStepNodes(status.workflowGraph), workflowResource?.provenance);
|
|
5257
5343
|
let workflowReceipt: { path: string; receipt: WorkflowReceipt } | undefined;
|
|
5258
5344
|
try {
|
|
5259
5345
|
workflowReceipt = { path: writeWorkflowReceipt(asyncDir, receipt), receipt };
|
|
@@ -5275,10 +5361,10 @@ export function createSubagentExecutor(deps: ExecutorDeps): {
|
|
|
5275
5361
|
});
|
|
5276
5362
|
return attachWorkflowMission(withRunFanoutBudget({
|
|
5277
5363
|
content: [{ type: "text", text: `${workflowPreflight ? `${formatWorkflowPreflight(workflowPreflight)}\n\n` : ""}${formatAsyncStartedMessage(`Async workflow [${workflowRunId}]`, ctx.hasUI === true)}` }],
|
|
5278
|
-
details: { mode: "workflow", runId: workflowRunId, toolCallId, asyncId: workflowRunId, asyncDir, results: [], ...(workflowPreflight ? { preflight: workflowPreflight } : {}), workflowChildren: status.workflowChildren, chatProgress, ...(deps.state.activeAsyncCapacity ? { activeAsyncCapacity: deps.state.activeAsyncCapacity } : {}) },
|
|
5364
|
+
details: { mode: "workflow", runId: workflowRunId, toolCallId, asyncId: workflowRunId, asyncDir, results: [], ...(workflowPreflight ? { preflight: workflowPreflight } : {}), workflow: status.workflow, workflowChildren: status.workflowChildren, chatProgress, ...(deps.state.activeAsyncCapacity ? { activeAsyncCapacity: deps.state.activeAsyncCapacity } : {}) },
|
|
5279
5365
|
}, workflowFanoutBudget));
|
|
5280
5366
|
}
|
|
5281
|
-
const { workflowScript: _workflowScript, action: _action, agent: _agent, task: _task, resume: _resume, tasks: _tasks, chain: _chain, concurrency: _concurrency, async: _async, foregroundOnly: _foregroundOnly, clarify: _clarify, timeoutMs: _timeoutMs, maxRuntimeMs: _maxRuntimeMs, usageBudget: _usageBudget, chatProgress: _chatProgress, missionId: _missionId, mission: _mission, preflight: _preflight, ...workflowChildDefaults } = requestParams;
|
|
5367
|
+
const { workflowScript: _workflowScript, action: _action, agent: _agent, task: _task, resume: _resume, tasks: _tasks, chain: _chain, concurrency: _concurrency, async: _async, foregroundOnly: _foregroundOnly, clarify: _clarify, timeoutMs: _timeoutMs, maxRuntimeMs: _maxRuntimeMs, usageBudget: _usageBudget, chatProgress: _chatProgress, missionId: _missionId, mission: _mission, preflight: _preflight, globalConcurrencyLimit: _globalConcurrencyLimit, maxSubagentSpawnsPerRun: _maxSubagentSpawnsPerRun, ...workflowChildDefaults } = requestParams;
|
|
5282
5368
|
const workflowOutput = typeof workflowChildDefaults.output === "string" || typeof workflowChildDefaults.output === "boolean" ? workflowChildDefaults.output : undefined;
|
|
5283
5369
|
const configuredOutputBaseDir = resolveConfiguredSingleRunOutputBaseDir(deps);
|
|
5284
5370
|
const workflowAggregateOutputPath = resolveWorkflowAggregateOutputPath(workflowOutput, ctx.cwd, workflowCwd, resolveSingleRunOutputBaseDir(deps, workflowArtifactsDir, _id));
|
|
@@ -5288,9 +5374,21 @@ export function createSubagentExecutor(deps: ExecutorDeps): {
|
|
|
5288
5374
|
const producedChildOutputPaths = new Set<string>();
|
|
5289
5375
|
const workflowResults: SingleResult[] = [];
|
|
5290
5376
|
const workflowChildRunIds = new Map<string, string>();
|
|
5291
|
-
const runHostCommand = workflowHostCommandRunner({
|
|
5377
|
+
const runHostCommand = workflowHostCommandRunner({
|
|
5378
|
+
workflowCwd,
|
|
5379
|
+
artifactsDir: workflowArtifactsDir,
|
|
5380
|
+
workflowRunId: _id,
|
|
5381
|
+
claimedOutputPaths,
|
|
5382
|
+
producedOutputPaths: producedChildOutputPaths,
|
|
5383
|
+
...(workflowResource ? { authorize: (key, params) => authorizeWorkflowResourceHost(workflowResource!.permit, key, params.command) } : {}),
|
|
5384
|
+
});
|
|
5385
|
+
const workflowHost = delegatedWorkflowPermit
|
|
5386
|
+
? undefined
|
|
5387
|
+
: workflowResource
|
|
5388
|
+
? workflowResource.authority.host ? runHostCommand : undefined
|
|
5389
|
+
: publicExecution ? undefined : runHostCommand;
|
|
5292
5390
|
const workflowHostSteps = new Map<string, HostStepNodeV1>();
|
|
5293
|
-
let liveWorkflow: NonNullable<Details["workflow"]> = { trace: [], emits: [], console: [] };
|
|
5391
|
+
let liveWorkflow: NonNullable<Details["workflow"]> = { trace: [], emits: [], console: [], ...(workflowResource ? { resource: workflowResource.provenance } : {}) };
|
|
5294
5392
|
let liveWorkflowChildren = workflowChildSummary({ parentToolCallId: _id, workflowRunId: _id, workflowState: "running", inventoryComplete: false });
|
|
5295
5393
|
const workflowDeadlineAt = timeout === undefined ? undefined : Date.now() + timeout;
|
|
5296
5394
|
const workflowCapabilityCeiling = intersectSubagentCapabilityCeilings(requestParams.capabilityCeiling, resolveCurrentSubagentCapabilityCeiling(resolveCurrentSessionId(ctx.sessionManager)));
|
|
@@ -5302,11 +5400,11 @@ export function createSubagentExecutor(deps: ExecutorDeps): {
|
|
|
5302
5400
|
const workflow = await runWorkflowScript({
|
|
5303
5401
|
script: requestParams.workflowScript,
|
|
5304
5402
|
...(delegatedWorkflowPermit ? { oneUsePermit: { claim: (key: string) => claimWorkflowChildPermit(delegatedWorkflowPermit, _id, key) } } : {}),
|
|
5305
|
-
globalConcurrencyLimit: deps.config.globalConcurrencyLimit,
|
|
5403
|
+
globalConcurrencyLimit: requestParams.globalConcurrencyLimit ?? deps.config.globalConcurrencyLimit,
|
|
5306
5404
|
timeoutMs: timeout,
|
|
5307
5405
|
signal,
|
|
5308
5406
|
...(workflowState ? { state: workflowState } : {}),
|
|
5309
|
-
...(
|
|
5407
|
+
...(workflowHost ? { host: workflowHost } : {}),
|
|
5310
5408
|
onHostStep: (hostStep) => {
|
|
5311
5409
|
workflowHostSteps.set(hostStep.id, { ...hostStep, ...(hostStep.freshness ? { freshness: { ...hostStep.freshness } } : {}) });
|
|
5312
5410
|
},
|
|
@@ -5403,7 +5501,7 @@ export function createSubagentExecutor(deps: ExecutorDeps): {
|
|
|
5403
5501
|
const finalPreflightWarnings = workflowPreflightWarnings(workflowPreflight, workflow.trace, { settled: true });
|
|
5404
5502
|
const finalPreflightTrace = annotateWorkflowPreflightTrace(workflow.trace, workflowPreflight);
|
|
5405
5503
|
const workflowChildren = workflowChildSummary({ parentToolCallId: _id, workflowRunId: _id, workflowState: "completed", inventoryComplete: true, trace: workflow.trace, children: workflow.children });
|
|
5406
|
-
const receipt = terminalWorkflowReceipt(_id, "complete", workflow.children, workflowChildren, undefined, [...workflowHostSteps.values()]);
|
|
5504
|
+
const receipt = terminalWorkflowReceipt(_id, "complete", workflow.children, workflowChildren, undefined, [...workflowHostSteps.values()], workflowResource?.provenance);
|
|
5407
5505
|
const traceLines = finalPreflightTrace.map((entry) => `- ${entry.operation} ${entry.key}: ${entry.state}${entry.runId ? ` (${entry.runId})` : ""}${entry.durationMs !== undefined ? ` in ${entry.durationMs}ms` : ""}${entry.warning ? ` — ${entry.warning}` : ""}${entry.error ? ` — ${entry.error}` : ""}`);
|
|
5408
5506
|
const sections = [
|
|
5409
5507
|
...(workflowPreflight ? [formatWorkflowPreflight(workflowPreflight)] : []),
|
|
@@ -5421,7 +5519,7 @@ export function createSubagentExecutor(deps: ExecutorDeps): {
|
|
|
5421
5519
|
const displayText = appendWorkflowOutputWarning(workflowText, outputWarning);
|
|
5422
5520
|
return attachWorkflowMission(withRunFanoutBudget({
|
|
5423
5521
|
content: [{ type: "text", text: displayText }],
|
|
5424
|
-
details: compactOptional<Details>({ mode: "workflow", runId: _id, results: workflow.children.flatMap((child) => (child.results ?? []) as SingleResult[]), ...(workflowPreflight ? { preflight: workflowPreflight } : {}), workflowChildren, totalChildUsage: sumResultsUsage(workflowResults), totalCost: sumResultsCost(workflowResults), usageBudget: usageBudgetState(workflowUsageBudget.budget, sumResultsCost(workflowResults)), workflow: { value: workflow.value, trace: finalPreflightTrace, emits: workflow.emits, console: workflow.console, ...(finalPreflightWarnings.length ? { preflightWarnings: finalPreflightWarnings } : {}), receipt }, chatProgress }),
|
|
5522
|
+
details: compactOptional<Details>({ mode: "workflow", runId: _id, results: workflow.children.flatMap((child) => (child.results ?? []) as SingleResult[]), ...(workflowPreflight ? { preflight: workflowPreflight } : {}), workflowChildren, totalChildUsage: sumResultsUsage(workflowResults), totalCost: sumResultsCost(workflowResults), usageBudget: usageBudgetState(workflowUsageBudget.budget, sumResultsCost(workflowResults)), workflow: { value: workflow.value, trace: finalPreflightTrace, emits: workflow.emits, console: workflow.console, ...(workflowResource ? { resource: workflowResource.provenance } : {}), ...(finalPreflightWarnings.length ? { preflightWarnings: finalPreflightWarnings } : {}), receipt }, chatProgress }),
|
|
5425
5523
|
}, workflowFanoutBudget));
|
|
5426
5524
|
} catch (error) {
|
|
5427
5525
|
const partial = error instanceof WorkflowScriptError ? error.partial : { trace: [], emits: [], console: [], children: [] };
|
|
@@ -5444,11 +5542,11 @@ export function createSubagentExecutor(deps: ExecutorDeps): {
|
|
|
5444
5542
|
const displayText = appendWorkflowOutputWarning(workflowText, outputWarning);
|
|
5445
5543
|
const workflowChildren = workflowChildSummary({ parentToolCallId: _id, workflowRunId: _id, workflowState: "failed", inventoryComplete: true, trace: partial.trace, children: partial.children });
|
|
5446
5544
|
const terminalOutcome = workflowFailureTerminalOutcome(error, partial.children, usageBudgetState(workflowUsageBudget.budget, sumResultsCost(workflowResults)));
|
|
5447
|
-
const receipt = terminalWorkflowReceipt(_id, "failed", partial.children, workflowChildren, terminalOutcome, [...workflowHostSteps.values()]);
|
|
5545
|
+
const receipt = terminalWorkflowReceipt(_id, "failed", partial.children, workflowChildren, terminalOutcome, [...workflowHostSteps.values()], workflowResource?.provenance);
|
|
5448
5546
|
return attachWorkflowMission(withRunFanoutBudget({
|
|
5449
5547
|
content: [{ type: "text", text: displayText }],
|
|
5450
5548
|
isError: true,
|
|
5451
|
-
details: compactOptional<Details>({ mode: "workflow", runId: _id, results: partial.children.flatMap((child) => (child.results ?? []) as SingleResult[]), ...(workflowPreflight ? { preflight: workflowPreflight } : {}), workflowChildren, totalChildUsage: sumResultsUsage(workflowResults), totalCost: sumResultsCost(workflowResults), usageBudget: usageBudgetState(workflowUsageBudget.budget, sumResultsCost(workflowResults)), workflow: { trace: finalPreflightTrace, emits: partial.emits, console: partial.console, ...(finalPreflightWarnings.length ? { preflightWarnings: finalPreflightWarnings } : {}), receipt }, chatProgress }),
|
|
5549
|
+
details: compactOptional<Details>({ mode: "workflow", runId: _id, results: partial.children.flatMap((child) => (child.results ?? []) as SingleResult[]), ...(workflowPreflight ? { preflight: workflowPreflight } : {}), workflowChildren, totalChildUsage: sumResultsUsage(workflowResults), totalCost: sumResultsCost(workflowResults), usageBudget: usageBudgetState(workflowUsageBudget.budget, sumResultsCost(workflowResults)), workflow: { trace: finalPreflightTrace, emits: partial.emits, console: partial.console, ...(workflowResource ? { resource: workflowResource.provenance } : {}), ...(finalPreflightWarnings.length ? { preflightWarnings: finalPreflightWarnings } : {}), receipt }, chatProgress }),
|
|
5452
5550
|
}, workflowFanoutBudget));
|
|
5453
5551
|
}
|
|
5454
5552
|
}
|
|
@@ -6208,34 +6306,47 @@ export function createSubagentExecutor(deps: ExecutorDeps): {
|
|
|
6208
6306
|
let forkSessionFileForIndex: (idx?: number) => string | undefined = () => undefined;
|
|
6209
6307
|
let prepareForkSessionForIndex: (idx?: number) => Promise<void> = async () => {};
|
|
6210
6308
|
let forkThinkingOverrideForIndex: (idx?: number) => AgentConfig["thinking"] | undefined = () => undefined;
|
|
6211
|
-
let prepareForkThinking = (_agentName: string, _index: number, _modelOverride?: string, _modelOverrideFromParent?: boolean): void => {};
|
|
6309
|
+
let prepareForkThinking = (_agentName: string, _index: number, _modelOverride?: string, _modelOverrideFromParent?: boolean, _modelOrigin?: ModelOrigin): void => {};
|
|
6212
6310
|
const forkThinkingRequirements = new Map<number, boolean>();
|
|
6213
6311
|
const forkThinkingDowngrades = new Map<number, string>();
|
|
6214
6312
|
try {
|
|
6215
6313
|
const forkAvailableModels = contextPolicy.usesFork ? ctx.modelRegistry.getAvailable().map(toModelInfo) : [];
|
|
6216
6314
|
const parentModel = requestParentModel;
|
|
6217
|
-
prepareForkThinking = (agentName, index, modelOverride, modelOverrideFromParent) => {
|
|
6315
|
+
prepareForkThinking = (agentName, index, modelOverride, modelOverrideFromParent, storedOrigin) => {
|
|
6218
6316
|
const agentConfig = agents.find((agent) => agent.name === agentName);
|
|
6219
6317
|
if (agentConfig?.runner?.type === "external-cli" || agentConfig?.runner?.type === "external-job") {
|
|
6220
6318
|
forkThinkingRequirements.set(index, true);
|
|
6221
6319
|
return;
|
|
6222
6320
|
}
|
|
6321
|
+
const effectiveStoredOrigin = storedOrigin === "configured" && modelOverride === undefined && agentConfig?.model === undefined
|
|
6322
|
+
? undefined
|
|
6323
|
+
: storedOrigin;
|
|
6324
|
+
const origin = resolveModelOrigin({
|
|
6325
|
+
fromParent: modelOverrideFromParent,
|
|
6326
|
+
storedOrigin: effectiveStoredOrigin,
|
|
6327
|
+
explicitModel: modelOverrideFromParent || effectiveStoredOrigin === "configured" ? undefined : modelOverride,
|
|
6328
|
+
agentModel: agentConfig?.model,
|
|
6329
|
+
parentModel,
|
|
6330
|
+
});
|
|
6223
6331
|
const primaryModel = modelOverrideFromParent
|
|
6224
6332
|
? modelOverride
|
|
6225
6333
|
: resolveEffectiveSubagentModel(
|
|
6226
|
-
modelOverride,
|
|
6334
|
+
effectiveStoredOrigin === "configured" ? undefined : modelOverride,
|
|
6227
6335
|
agentConfig?.model,
|
|
6228
6336
|
parentModel,
|
|
6229
6337
|
forkAvailableModels,
|
|
6230
6338
|
agentConfig?.modelProvider ?? parentModel?.provider,
|
|
6231
|
-
{ source: "inherited" },
|
|
6339
|
+
{ source: origin === "explicit" ? "explicit" : "inherited" },
|
|
6232
6340
|
);
|
|
6233
6341
|
const candidates = buildModelCandidates(
|
|
6234
6342
|
primaryModel,
|
|
6235
6343
|
agentConfig?.fallbackModels,
|
|
6236
6344
|
forkAvailableModels,
|
|
6237
6345
|
agentConfig?.modelProvider ?? parentModel?.provider,
|
|
6238
|
-
{
|
|
6346
|
+
{
|
|
6347
|
+
primaryModelFromParent: origin === "inherited",
|
|
6348
|
+
origin,
|
|
6349
|
+
},
|
|
6239
6350
|
);
|
|
6240
6351
|
forkThinkingRequirements.set(
|
|
6241
6352
|
index,
|
|
@@ -6353,25 +6464,25 @@ export function createSubagentExecutor(deps: ExecutorDeps): {
|
|
|
6353
6464
|
}
|
|
6354
6465
|
const sessionDirForIndex = (idx?: number) =>
|
|
6355
6466
|
path.join(sessionRoot, `run-${idx ?? 0}`);
|
|
6356
|
-
const forkSessionFileForTask: ForkSessionFileForTask = (agentName, idx = 0, modelOverride, modelOverrideFromParent) => {
|
|
6467
|
+
const forkSessionFileForTask: ForkSessionFileForTask = (agentName, idx = 0, modelOverride, modelOverrideFromParent, modelOrigin) => {
|
|
6357
6468
|
if (!shouldForkAgent(contextPolicy, agentName)) return undefined;
|
|
6358
|
-
prepareForkThinking(agentName, idx, modelOverride, modelOverrideFromParent);
|
|
6469
|
+
prepareForkThinking(agentName, idx, modelOverride, modelOverrideFromParent, modelOrigin);
|
|
6359
6470
|
return forkSessionFileForIndex(idx);
|
|
6360
6471
|
};
|
|
6361
|
-
const prepareForkSessionForTask: PrepareForkSessionForTask = async (agentName, idx = 0, modelOverride, modelOverrideFromParent) => {
|
|
6472
|
+
const prepareForkSessionForTask: PrepareForkSessionForTask = async (agentName, idx = 0, modelOverride, modelOverrideFromParent, modelOrigin) => {
|
|
6362
6473
|
if (!shouldForkAgent(contextPolicy, agentName)) return;
|
|
6363
|
-
prepareForkThinking(agentName, idx, modelOverride, modelOverrideFromParent);
|
|
6474
|
+
prepareForkThinking(agentName, idx, modelOverride, modelOverrideFromParent, modelOrigin);
|
|
6364
6475
|
await prepareForkSessionForIndex(idx);
|
|
6365
6476
|
};
|
|
6366
|
-
const forkThinkingOverrideForTask: ForkThinkingOverrideForTask = (agentName, idx = 0, modelOverride, modelOverrideFromParent) => {
|
|
6477
|
+
const forkThinkingOverrideForTask: ForkThinkingOverrideForTask = (agentName, idx = 0, modelOverride, modelOverrideFromParent, modelOrigin) => {
|
|
6367
6478
|
if (!shouldForkAgent(contextPolicy, agentName)) return delegatedThinkingOverride;
|
|
6368
|
-
prepareForkThinking(agentName, idx, modelOverride, modelOverrideFromParent);
|
|
6479
|
+
prepareForkThinking(agentName, idx, modelOverride, modelOverrideFromParent, modelOrigin);
|
|
6369
6480
|
const override = forkThinkingOverrideForIndex(idx);
|
|
6370
6481
|
if (override === "off") forkThinkingDowngrades.set(idx, agentName);
|
|
6371
6482
|
return override ?? delegatedThinkingOverride;
|
|
6372
6483
|
};
|
|
6373
|
-
const childSessionFileForTask: ForkSessionFileForTask = (agentName, idx, modelOverride, modelOverrideFromParent) =>
|
|
6374
|
-
forkSessionFileForTask(agentName, idx, modelOverride, modelOverrideFromParent) ?? path.join(sessionDirForIndex(idx), "session.jsonl");
|
|
6484
|
+
const childSessionFileForTask: ForkSessionFileForTask = (agentName, idx, modelOverride, modelOverrideFromParent, modelOrigin) =>
|
|
6485
|
+
forkSessionFileForTask(agentName, idx, modelOverride, modelOverrideFromParent, modelOrigin) ?? path.join(sessionDirForIndex(idx), "session.jsonl");
|
|
6375
6486
|
const childSessionFileForIndex = (idx?: number) =>
|
|
6376
6487
|
path.join(sessionDirForIndex(idx), "session.jsonl");
|
|
6377
6488
|
try {
|
|
@@ -6465,6 +6576,7 @@ export function createSubagentExecutor(deps: ExecutorDeps): {
|
|
|
6465
6576
|
effectiveAsync,
|
|
6466
6577
|
asyncRunId,
|
|
6467
6578
|
controlConfig,
|
|
6579
|
+
...(delegatedExecution ? { suppressUnchangedDelegationUpdates: true } : {}),
|
|
6468
6580
|
intercomBridge,
|
|
6469
6581
|
nestedRoute,
|
|
6470
6582
|
timeoutMs: foregroundTimeout.timeoutMs,
|
|
@@ -6740,10 +6852,19 @@ export function createSubagentExecutor(deps: ExecutorDeps): {
|
|
|
6740
6852
|
if (!normalized.ok) {
|
|
6741
6853
|
return Promise.resolve({ content: [{ type: "text", text: normalized.error }], isError: true, details: { mode: normalized.mode, results: [] } });
|
|
6742
6854
|
}
|
|
6743
|
-
|
|
6855
|
+
let publicParams = normalized.params as SubagentParamsLike;
|
|
6856
|
+
if (publicParams.workflow !== undefined) {
|
|
6857
|
+
const resolved = resolveWorkflowResource(publicParams.workflow, publicParams.args);
|
|
6858
|
+
if (!resolved.ok) return Promise.resolve({ content: [{ type: "text", text: resolved.error }], isError: true, details: { mode: "workflow", results: [] } });
|
|
6859
|
+
const { workflow: _workflow, args: _args, ...withoutResourceInput } = publicParams;
|
|
6860
|
+
publicParams = { ...withoutResourceInput, workflowScript: resolved.resource.script };
|
|
6861
|
+
workflowResourcePermits.set(publicParams, resolved.resource.permit);
|
|
6862
|
+
}
|
|
6863
|
+
const loaded = loadWorkflowScriptPath(publicParams, ctx.cwd);
|
|
6744
6864
|
if (loaded.error) {
|
|
6745
|
-
return Promise.resolve({ content: [{ type: "text", text: loaded.error }], isError: true, details: { mode:
|
|
6865
|
+
return Promise.resolve({ content: [{ type: "text", text: loaded.error }], isError: true, details: { mode: publicParams.action ? "management" : "workflow", results: [] } });
|
|
6746
6866
|
}
|
|
6867
|
+
publicExecutions.add(loaded.params!);
|
|
6747
6868
|
return executeWithSingleDispatchGuard(id, loaded.params!, signal, onUpdate, ctx);
|
|
6748
6869
|
};
|
|
6749
6870
|
|
|
@@ -6788,7 +6909,7 @@ export function createSubagentExecutor(deps: ExecutorDeps): {
|
|
|
6788
6909
|
});
|
|
6789
6910
|
scheduledOwnerExecutors.set(ownerSessionId, ownerExecutor);
|
|
6790
6911
|
}
|
|
6791
|
-
return ownerExecutor.
|
|
6912
|
+
return ownerExecutor.executePublic(id, params, signal, undefined, ctx);
|
|
6792
6913
|
};
|
|
6793
6914
|
|
|
6794
6915
|
return { execute: executeWithSingleDispatchGuard, executePublic, executeDelegated, executeScheduled };
|