pi-subagents 0.74.0 → 0.75.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 +46 -0
- package/docs/agents.md +15 -5
- package/docs/configuration.md +10 -0
- package/docs/extension-api.md +1 -1
- package/docs/missions.md +15 -1
- package/docs/models.md +6 -2
- package/docs/observability.md +8 -3
- package/docs/tool-reference.md +28 -3
- package/docs/workflows.md +2 -2
- package/package.json +1 -1
- package/src/agents/agents.d.ts +1 -0
- package/src/agents/agents.d.ts.map +1 -1
- package/src/agents/agents.js +65 -3
- package/src/agents/agents.js.map +1 -1
- package/src/api/preflight.d.ts +1 -1
- package/src/api/preflight.d.ts.map +1 -1
- package/src/api/preflight.js +44 -1
- package/src/api/preflight.js.map +1 -1
- package/src/extension/config.d.ts.map +1 -1
- package/src/extension/config.js +4 -1
- package/src/extension/config.js.map +1 -1
- package/src/extension/index.d.ts.map +1 -1
- package/src/extension/index.js +26 -19
- package/src/extension/index.js.map +1 -1
- package/src/extension/public-execution.d.ts.map +1 -1
- package/src/extension/public-execution.js +4 -0
- package/src/extension/public-execution.js.map +1 -1
- package/src/extension/reply-workflow-script.js +1 -1
- package/src/extension/reply-workflow-script.js.map +1 -1
- package/src/extension/rpc.js +1 -1
- package/src/extension/rpc.js.map +1 -1
- package/src/extension/schemas.d.ts +1 -0
- package/src/extension/schemas.d.ts.map +1 -1
- package/src/extension/schemas.js +5 -3
- package/src/extension/schemas.js.map +1 -1
- package/src/extension/tool-description.js +1 -1
- package/src/extension/tool-description.js.map +1 -1
- package/src/missions/goal-driver.d.ts +1 -0
- package/src/missions/goal-driver.d.ts.map +1 -1
- package/src/missions/goal-driver.js +49 -34
- package/src/missions/goal-driver.js.map +1 -1
- package/src/missions/store.d.ts.map +1 -1
- package/src/missions/store.js +11 -1
- package/src/missions/store.js.map +1 -1
- package/src/profiles/profiles.d.ts +1 -1
- package/src/profiles/profiles.d.ts.map +1 -1
- package/src/profiles/profiles.js +4 -0
- package/src/profiles/profiles.js.map +1 -1
- package/src/runs/background/async-execution.d.ts +13 -0
- package/src/runs/background/async-execution.d.ts.map +1 -1
- package/src/runs/background/async-execution.js +89 -6
- package/src/runs/background/async-execution.js.map +1 -1
- package/src/runs/background/async-job-tracker.d.ts +1 -0
- package/src/runs/background/async-job-tracker.d.ts.map +1 -1
- package/src/runs/background/async-job-tracker.js +2 -2
- package/src/runs/background/async-job-tracker.js.map +1 -1
- package/src/runs/background/await-async-run.d.ts.map +1 -1
- package/src/runs/background/await-async-run.js +4 -2
- package/src/runs/background/await-async-run.js.map +1 -1
- package/src/runs/background/control-channel.d.ts +10 -0
- package/src/runs/background/control-channel.d.ts.map +1 -1
- package/src/runs/background/control-channel.js +51 -0
- package/src/runs/background/control-channel.js.map +1 -1
- package/src/runs/background/run-child-session.d.ts.map +1 -1
- package/src/runs/background/run-child-session.js +20 -6
- package/src/runs/background/run-child-session.js.map +1 -1
- package/src/runs/background/runner-aliases.d.ts +1 -0
- package/src/runs/background/runner-aliases.d.ts.map +1 -1
- package/src/runs/background/runner-aliases.js +6 -2
- package/src/runs/background/runner-aliases.js.map +1 -1
- package/src/runs/background/scheduled-runs.d.ts +2 -1
- package/src/runs/background/scheduled-runs.d.ts.map +1 -1
- package/src/runs/background/scheduled-runs.js +28 -11
- package/src/runs/background/scheduled-runs.js.map +1 -1
- package/src/runs/background/stale-run-reconciler.d.ts +1 -1
- package/src/runs/background/stale-run-reconciler.d.ts.map +1 -1
- package/src/runs/background/stale-run-reconciler.js +15 -2
- package/src/runs/background/stale-run-reconciler.js.map +1 -1
- package/src/runs/background/subagent-runner.d.ts.map +1 -1
- package/src/runs/background/subagent-runner.js +44 -3
- package/src/runs/background/subagent-runner.js.map +1 -1
- package/src/runs/foreground/command-action.d.ts +13 -0
- package/src/runs/foreground/command-action.d.ts.map +1 -0
- package/src/runs/foreground/command-action.js +38 -0
- package/src/runs/foreground/command-action.js.map +1 -0
- package/src/runs/foreground/execution.d.ts.map +1 -1
- package/src/runs/foreground/execution.js +19 -5
- package/src/runs/foreground/execution.js.map +1 -1
- package/src/runs/foreground/subagent-executor.d.ts +1 -0
- package/src/runs/foreground/subagent-executor.d.ts.map +1 -1
- package/src/runs/foreground/subagent-executor.js +64 -11
- package/src/runs/foreground/subagent-executor.js.map +1 -1
- package/src/runs/shared/child-commands.d.ts +28 -0
- package/src/runs/shared/child-commands.d.ts.map +1 -0
- package/src/runs/shared/child-commands.js +250 -0
- package/src/runs/shared/child-commands.js.map +1 -0
- package/src/runs/shared/child-session.d.ts +4 -0
- package/src/runs/shared/child-session.d.ts.map +1 -1
- package/src/runs/shared/child-session.js +97 -20
- package/src/runs/shared/child-session.js.map +1 -1
- package/src/runs/shared/child-tool-plan.js +1 -1
- package/src/runs/shared/child-tool-plan.js.map +1 -1
- package/src/runs/shared/claude-code-adapter.d.ts +56 -0
- package/src/runs/shared/claude-code-adapter.d.ts.map +1 -1
- package/src/runs/shared/claude-code-adapter.js +138 -2
- package/src/runs/shared/claude-code-adapter.js.map +1 -1
- package/src/runs/shared/dynamic-fanout.js +1 -1
- package/src/runs/shared/dynamic-fanout.js.map +1 -1
- package/src/runs/shared/external-cli-preflight.d.ts +10 -0
- package/src/runs/shared/external-cli-preflight.d.ts.map +1 -1
- package/src/runs/shared/external-cli-preflight.js +50 -6
- package/src/runs/shared/external-cli-preflight.js.map +1 -1
- package/src/runs/shared/external-cli-runner.d.ts.map +1 -1
- package/src/runs/shared/external-cli-runner.js +4 -2
- package/src/runs/shared/external-cli-runner.js.map +1 -1
- package/src/runs/shared/mcp-direct-tool-allowlist.d.ts.map +1 -1
- package/src/runs/shared/mcp-direct-tool-allowlist.js +5 -4
- package/src/runs/shared/mcp-direct-tool-allowlist.js.map +1 -1
- package/src/runs/shared/model-resolution.d.ts +6 -2
- package/src/runs/shared/model-resolution.d.ts.map +1 -1
- package/src/runs/shared/model-resolution.js +9 -2
- package/src/runs/shared/model-resolution.js.map +1 -1
- package/src/runs/shared/parallel-utils.d.ts +2 -0
- package/src/runs/shared/parallel-utils.d.ts.map +1 -1
- package/src/runs/shared/parallel-utils.js.map +1 -1
- package/src/runs/shared/run-history.d.ts +47 -0
- package/src/runs/shared/run-history.d.ts.map +1 -1
- package/src/runs/shared/run-history.js +70 -0
- package/src/runs/shared/run-history.js.map +1 -1
- package/src/runs/shared/subagent-control.d.ts.map +1 -1
- package/src/runs/shared/subagent-control.js +30 -17
- package/src/runs/shared/subagent-control.js.map +1 -1
- package/src/runs/shared/subagent-prompt-runtime.d.ts +1 -0
- package/src/runs/shared/subagent-prompt-runtime.d.ts.map +1 -1
- package/src/runs/shared/subagent-prompt-runtime.js +12 -5
- package/src/runs/shared/subagent-prompt-runtime.js.map +1 -1
- package/src/shared/required-child-extensions.d.ts +16 -1
- package/src/shared/required-child-extensions.d.ts.map +1 -1
- package/src/shared/required-child-extensions.js +37 -5
- package/src/shared/required-child-extensions.js.map +1 -1
- package/src/shared/types.d.ts +6 -1
- package/src/shared/types.d.ts.map +1 -1
- package/src/shared/types.js +1 -1
- package/src/shared/types.js.map +1 -1
- package/src/slash/subagent-cost.d.ts.map +1 -1
- package/src/slash/subagent-cost.js +8 -4
- package/src/slash/subagent-cost.js.map +1 -1
- package/src/tui/render.d.ts +1 -1
- package/src/tui/render.d.ts.map +1 -1
- package/src/tui/render.js +4 -4
- package/src/tui/render.js.map +1 -1
- package/src/workflows/workflow-receipt.js +2 -2
- package/src/workflows/workflow-receipt.js.map +1 -1
- package/src/workflows/workflow-resources.d.ts +4 -0
- package/src/workflows/workflow-resources.d.ts.map +1 -1
- package/src/workflows/workflow-resources.js +7 -4
- package/src/workflows/workflow-resources.js.map +1 -1
|
@@ -19,6 +19,7 @@ import { isWorkflowScriptPath, normalizePublicSubagentExecution, validateWorkflo
|
|
|
19
19
|
import { readReplyWorkflowScript } from "../../extension/reply-workflow-script.js";
|
|
20
20
|
import { disabledFeatureNotice, disabledFeatureUseError, resolveDisabledFeatureSurface } from "../../shared/disabled-features.js";
|
|
21
21
|
import { runSync } from "./execution.js";
|
|
22
|
+
import { commandAction } from "./command-action.js";
|
|
22
23
|
import { handleWatchdogToolAction, WATCHDOG_TOOL_ACTIONS } from "../../watchdog/tool-actions.js";
|
|
23
24
|
import { applyWatchdogLaunchRules } from "../../watchdog/rules.js";
|
|
24
25
|
import { childWatchdogProgressForModel } from "../../watchdog/child-status.js";
|
|
@@ -54,7 +55,7 @@ import { usageBudgetExceededMessage, usageBudgetState, validateUsageBudgetConfig
|
|
|
54
55
|
import { assertAgentAllowedByCapabilityCeiling, intersectSubagentCapabilityCeilings, resolveCurrentSubagentCapabilityCeiling } from "../shared/capability-ceiling.js";
|
|
55
56
|
import { isAgentContract } from "../shared/agent-contract.js";
|
|
56
57
|
import { normalizeExtensionBindings } from "../shared/extension-bindings.js";
|
|
57
|
-
import { resolveRequiredChildExtensions } from "../../shared/required-child-extensions.js";
|
|
58
|
+
import { assertRequiredChildExtensionsAdmitted, hasMandatoryRequiredChildExtensions, readRetainedRequiredChildExtensions, resolveRequiredChildExtensions } from "../../shared/required-child-extensions.js";
|
|
58
59
|
import { finalizeSingleOutput, injectSingleOutputInstruction, normalizeSingleOutputOverride, outputPathMappingFromTask, resolveSingleOutputPath, validateFileOnlyOutputMode } from "../shared/single-output.js";
|
|
59
60
|
import { assertJsonSchemaObject, cleanupStructuredOutputRuntime, createStructuredOutputRuntime } from "../shared/structured-output.js";
|
|
60
61
|
import { compactForegroundDetails, getSingleResultOutput, PROMPT_REDACTED, readStatus, resolveChildCwd, sumResultsCost, sumResultsUsage, toAgentToolUsage } from "../../shared/utils.js";
|
|
@@ -109,8 +110,8 @@ import { cleanupWorktrees, createWorktrees, preflightWorktreeSource, withWorktre
|
|
|
109
110
|
import { createWorktreeCleanupPlan, formatWorktreeCleanupPlan } from "../shared/worktree-cleanup-plan.js";
|
|
110
111
|
import { DIRS, DEFAULT_ARTIFACT_CONFIG, DEFAULT_MAX_OUTPUT, DEFAULT_FORK_PREAMBLE, SUBAGENT_ACTIONS, SUBAGENT_ASYNC_STARTED_EVENT, SUBAGENT_CHILD_STATUS_EVENT, SUBAGENT_CONTROL_EVENT, SUBAGENT_CONTROL_INTERCOM_EVENT, SUBAGENT_FOREGROUND_COMPLETE_EVENT, SUBAGENT_LIFECYCLE_ARTIFACT_VERSION, checkSubagentDepth, resolveChildMaxSubagentDepth, resolveCurrentMaxSubagentDepth, resolveMaxSubagentSpawnsPerRun, truncateOutput, wrapForkTask, } from "../../shared/types.js";
|
|
111
112
|
import { deriveChildSessionName } from "../../shared/child-session-name.js";
|
|
112
|
-
const MUTATING_MANAGEMENT_ACTIONS = new Set(["create", "update", "delete", "eject", "disable", "enable", "reset", "grant-spawn-budget", "watchdog.configure", "mission.create", "mission.update", "mission.resolve-decision", "mission.attach-run", "mission.close", "inspector.open", "inspector.close", "project.open", "project.close", "worktree.discard", "worktree.cleanup", "lane.recordMerge", "lane.recordSupersession", "refine", "refine.rollback", "dismiss", "schedule.create", "schedule.pause", "schedule.resume", "schedule.run", "schedule.run-due", "schedule.delete"]);
|
|
113
|
-
const DESTRUCTIVE_MANAGEMENT_ACTIONS = new Set(["delete", "eject", "disable", "reset", "mission.close", "worktree.discard", "refine.rollback", "inspector.close", "project.close", "stop", "interrupt", "schedule.delete"]);
|
|
113
|
+
const MUTATING_MANAGEMENT_ACTIONS = new Set(["command.yield", "command.cancel", "create", "update", "delete", "eject", "disable", "enable", "reset", "grant-spawn-budget", "watchdog.configure", "mission.create", "mission.update", "mission.resolve-decision", "mission.attach-run", "mission.close", "inspector.open", "inspector.close", "project.open", "project.close", "worktree.discard", "worktree.cleanup", "lane.recordMerge", "lane.recordSupersession", "refine", "refine.rollback", "dismiss", "schedule.create", "schedule.pause", "schedule.resume", "schedule.run", "schedule.run-due", "schedule.delete"]);
|
|
114
|
+
const DESTRUCTIVE_MANAGEMENT_ACTIONS = new Set(["command.cancel", "delete", "eject", "disable", "reset", "mission.close", "worktree.discard", "refine.rollback", "inspector.close", "project.close", "stop", "interrupt", "schedule.delete"]);
|
|
114
115
|
function resolveSteerDeliveryMode(mode) {
|
|
115
116
|
return mode === "steer" || mode === "follow_up" || mode === "auto" ? mode : undefined;
|
|
116
117
|
}
|
|
@@ -960,6 +961,17 @@ function appendStepToAsyncChain(input) {
|
|
|
960
961
|
details: { mode: "management", results: [] },
|
|
961
962
|
};
|
|
962
963
|
}
|
|
964
|
+
let retainedRequiredExtensions;
|
|
965
|
+
try {
|
|
966
|
+
retainedRequiredExtensions = readRetainedRequiredChildExtensions(resolved.location.asyncDir);
|
|
967
|
+
}
|
|
968
|
+
catch (error) {
|
|
969
|
+
return {
|
|
970
|
+
content: [{ type: "text", text: `Cannot append step to run '${resolved.id}': ${error instanceof Error ? error.message : String(error)}` }],
|
|
971
|
+
isError: true,
|
|
972
|
+
details: { mode: "management", results: [] },
|
|
973
|
+
};
|
|
974
|
+
}
|
|
963
975
|
const pendingAppendRequests = readPendingChainAppendRequests(resolved.location.asyncDir);
|
|
964
976
|
const reservedOutputNames = new Set([
|
|
965
977
|
...Object.keys(status.outputs ?? {}),
|
|
@@ -1031,6 +1043,7 @@ function appendStepToAsyncChain(input) {
|
|
|
1031
1043
|
asyncDir: resolved.location.asyncDir,
|
|
1032
1044
|
validateOutputBindings: false,
|
|
1033
1045
|
capabilityCeiling: intersectSubagentCapabilityCeilings(status.capabilityCeiling, resolveCurrentSubagentCapabilityCeiling(asyncCtx.currentSessionId)),
|
|
1046
|
+
requiredExtensions: retainedRequiredExtensions,
|
|
1034
1047
|
}));
|
|
1035
1048
|
if ("error" in built) {
|
|
1036
1049
|
return {
|
|
@@ -3069,6 +3082,7 @@ async function runAsyncPath(data, deps) {
|
|
|
3069
3082
|
goal: params.task ?? "",
|
|
3070
3083
|
agentConfig: a,
|
|
3071
3084
|
recoveryAgentConfig: data.recoveryAgents.find((agent) => agent.name === params.agent),
|
|
3085
|
+
requiredExtensions: data.requiredExtensions,
|
|
3072
3086
|
ctx: asyncCtx,
|
|
3073
3087
|
availableModels,
|
|
3074
3088
|
cwd: effectiveCwd,
|
|
@@ -3455,8 +3469,10 @@ async function runSinglePath(data, deps) {
|
|
|
3455
3469
|
}
|
|
3456
3470
|
let foregroundMachine;
|
|
3457
3471
|
const requestedMachine = params.machine ?? agentConfig.machine;
|
|
3472
|
+
const requiredExtensions = data.requiredExtensions ?? deps.childRuntime?.requiredExtensions ?? resolveRequiredChildExtensions(data.parentPiSessionId);
|
|
3458
3473
|
if (requestedMachine) {
|
|
3459
3474
|
try {
|
|
3475
|
+
assertRequiredChildExtensionsAdmitted([requiredExtensions], { agent: agentConfig.name, runnerType: agentConfig.runner?.type, machine: requestedMachine });
|
|
3460
3476
|
foregroundMachine = resolveHerdrMachinePlacement({ machine: requestedMachine, cwd: ctx.cwd, stepCwd: params.machineCwd }).machine;
|
|
3461
3477
|
}
|
|
3462
3478
|
catch (error) {
|
|
@@ -3643,7 +3659,6 @@ async function runSinglePath(data, deps) {
|
|
|
3643
3659
|
}
|
|
3644
3660
|
: undefined;
|
|
3645
3661
|
const deadlineAt = data.deadlineAt ?? (data.timeoutMs !== undefined ? Date.now() + data.timeoutMs : undefined);
|
|
3646
|
-
const requiredExtensions = deps.childRuntime?.requiredExtensions ?? resolveRequiredChildExtensions(data.parentPiSessionId);
|
|
3647
3662
|
let r;
|
|
3648
3663
|
let resolveDetachedWorkflowChild;
|
|
3649
3664
|
const detachedWorkflowChild = params.workflowAwaitDetached === true
|
|
@@ -3900,6 +3915,7 @@ function duplicateSubagentCallResult(params) {
|
|
|
3900
3915
|
}
|
|
3901
3916
|
const workflowLaunchObservers = new WeakMap();
|
|
3902
3917
|
const workflowOwnedUsageBudgets = new WeakMap();
|
|
3918
|
+
const workflowRetainedRequiredExtensions = new WeakMap();
|
|
3903
3919
|
/**
|
|
3904
3920
|
* Terminal-mission retention can remove a mission while its children still
|
|
3905
3921
|
* report. Remember it to prevent later heartbeats from warning repeatedly.
|
|
@@ -4087,7 +4103,11 @@ function workflowOutputPathMappingSummary(children) {
|
|
|
4087
4103
|
return mappings.length > 0 ? ` Output path mappings: ${mappings.join("; ")}.` : "";
|
|
4088
4104
|
}
|
|
4089
4105
|
function workflowDetailsResults(children) {
|
|
4090
|
-
return children.flatMap((child) => (child.results ?? []).map((result) =>
|
|
4106
|
+
return children.flatMap((child) => (child.results ?? []).map((result) => ({
|
|
4107
|
+
...result,
|
|
4108
|
+
workflowKey: result.workflowKey ?? child.key,
|
|
4109
|
+
...(child.runId && !result.runId ? { runId: child.runId } : {}),
|
|
4110
|
+
})));
|
|
4091
4111
|
}
|
|
4092
4112
|
function workflowSteerReceipt(key, result) {
|
|
4093
4113
|
const steering = result.details.steering;
|
|
@@ -4625,6 +4645,7 @@ export function createSubagentExecutor(deps) {
|
|
|
4625
4645
|
const execute = async (_id, params, signal, onUpdate, ctx, preserveActiveSession = false, parentModelOverride) => {
|
|
4626
4646
|
const workflowLaunchObserver = workflowLaunchObservers.get(params);
|
|
4627
4647
|
const inheritedUsageBudget = workflowOwnedUsageBudgets.get(params);
|
|
4648
|
+
const retainedRequiredExtensions = workflowRetainedRequiredExtensions.get(params);
|
|
4628
4649
|
const delegatedThinkingOverride = delegatedThinkingOverrides.get(params);
|
|
4629
4650
|
const allowZeroToolBudget = delegatedZeroToolBudgets.has(params);
|
|
4630
4651
|
const delegatedExecution = delegatedExecutions.has(params);
|
|
@@ -4655,6 +4676,12 @@ export function createSubagentExecutor(deps) {
|
|
|
4655
4676
|
? currentParentModel
|
|
4656
4677
|
: rememberParentModel(deps.state, resolveCurrentSessionId(ctx.sessionManager), currentParentModel)) ?? null;
|
|
4657
4678
|
})();
|
|
4679
|
+
// validate checks args with the same normalization launch uses, reported beside script errors.
|
|
4680
|
+
const validateWorkflowRequest = () => {
|
|
4681
|
+
const validation = validateWorkflowScript(requestParams.workflowScript ?? "", workflowValidationOptions(deps, requestParams, ctx.cwd, () => resolveWorkflowParentModel()?.provider));
|
|
4682
|
+
const normalizedArgs = normalizeWorkflowArgs(requestParams.args);
|
|
4683
|
+
return "error" in normalizedArgs ? { ...validation, ok: false, errors: [...validation.errors, { message: normalizedArgs.error }] } : validation;
|
|
4684
|
+
};
|
|
4658
4685
|
try {
|
|
4659
4686
|
if (requestParams.preflight !== undefined && requestParams.workflowScript === undefined) {
|
|
4660
4687
|
throw new Error("preflight requires workflow: true or a workflow script path.");
|
|
@@ -4666,7 +4693,7 @@ export function createSubagentExecutor(deps) {
|
|
|
4666
4693
|
catch (error) {
|
|
4667
4694
|
const message = error instanceof Error ? error.message : String(error);
|
|
4668
4695
|
if (requestParams.action?.trim() === "validate") {
|
|
4669
|
-
const validation =
|
|
4696
|
+
const validation = validateWorkflowRequest();
|
|
4670
4697
|
const invalidValidation = { ...validation, ok: false, errors: [...validation.errors, { message }] };
|
|
4671
4698
|
return {
|
|
4672
4699
|
content: [{ type: "text", text: JSON.stringify(invalidValidation) }],
|
|
@@ -4677,8 +4704,7 @@ export function createSubagentExecutor(deps) {
|
|
|
4677
4704
|
return buildRequestedModeError(requestParams, message);
|
|
4678
4705
|
}
|
|
4679
4706
|
if (requestParams.action?.trim() === "validate") {
|
|
4680
|
-
|
|
4681
|
-
return buildWorkflowValidationResult(validation, "management", workflowPreflight);
|
|
4707
|
+
return buildWorkflowValidationResult(validateWorkflowRequest(), "management", workflowPreflight);
|
|
4682
4708
|
}
|
|
4683
4709
|
const normalizedAction = typeof requestParams.action === "string" ? requestParams.action.trim() : requestParams.action;
|
|
4684
4710
|
if (normalizedAction === "resume" && requestParams.extensionBindings !== undefined)
|
|
@@ -4713,6 +4739,9 @@ export function createSubagentExecutor(deps) {
|
|
|
4713
4739
|
const acceptanceErrors = validateAcceptanceInput(requestParams.acceptance);
|
|
4714
4740
|
if (acceptanceErrors.length > 0)
|
|
4715
4741
|
return buildRequestedModeError(requestParams, acceptanceErrors.join(" "));
|
|
4742
|
+
// Capture mandatory host extensions at admission: script children may launch after the host disposes its registration.
|
|
4743
|
+
const admittedRequiredExtensions = retainedRequiredExtensions ?? deps.childRuntime?.requiredExtensions ?? resolveRequiredChildExtensions(ctx.sessionManager.getSessionId() ?? undefined);
|
|
4744
|
+
const workflowRequiredExtensions = hasMandatoryRequiredChildExtensions(admittedRequiredExtensions) ? admittedRequiredExtensions : undefined;
|
|
4716
4745
|
const foregroundWorkflowRunId = encodeIndexSegment(_id);
|
|
4717
4746
|
if (delegatedWorkflowPermit) {
|
|
4718
4747
|
const permitError = validateWorkflowChildPermitRoot(delegatedWorkflowPermit, foregroundWorkflowRunId);
|
|
@@ -5588,6 +5617,8 @@ export function createSubagentExecutor(deps) {
|
|
|
5588
5617
|
preparedChildParams = childRequest;
|
|
5589
5618
|
if (workflowUsageBudget.budget)
|
|
5590
5619
|
workflowOwnedUsageBudgets.set(childRequest, workflowUsageBudget.budget);
|
|
5620
|
+
if (workflowRequiredExtensions)
|
|
5621
|
+
workflowRetainedRequiredExtensions.set(childRequest, workflowRequiredExtensions);
|
|
5591
5622
|
workflowLaunchObservers.set(childRequest, (launch) => {
|
|
5592
5623
|
if (launch.runId)
|
|
5593
5624
|
appendWorkflowChildJournal(asyncDir, { type: "start", key, fingerprint: journalFingerprint, runId: launch.runId });
|
|
@@ -5910,6 +5941,8 @@ export function createSubagentExecutor(deps) {
|
|
|
5910
5941
|
preparedChildParams = childRequest;
|
|
5911
5942
|
if (workflowUsageBudget.budget)
|
|
5912
5943
|
workflowOwnedUsageBudgets.set(childRequest, workflowUsageBudget.budget);
|
|
5944
|
+
if (workflowRequiredExtensions)
|
|
5945
|
+
workflowRetainedRequiredExtensions.set(childRequest, workflowRequiredExtensions);
|
|
5913
5946
|
if (delegatedWorkflowPermit) {
|
|
5914
5947
|
if (childRequest.async !== false)
|
|
5915
5948
|
throw new Error("Workflow child permit supports one foreground child only.");
|
|
@@ -6178,7 +6211,7 @@ export function createSubagentExecutor(deps) {
|
|
|
6178
6211
|
return { content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }], isError: true, details: { mode: "management", results: [] } };
|
|
6179
6212
|
}
|
|
6180
6213
|
}
|
|
6181
|
-
const policyAction = action === "stop" ? "stopRun" : action === "steer" ? "steerRun" : action === "schedule.create" ? "scheduleCreate" : action === "inspector.open" ? "inspectorOpen" : action === "project.open" ? "projectOpen" : undefined;
|
|
6214
|
+
const policyAction = action === "stop" || action === "command.cancel" ? "stopRun" : action === "steer" || action === "command.yield" ? "steerRun" : action === "schedule.create" ? "scheduleCreate" : action === "inspector.open" ? "inspectorOpen" : action === "project.open" ? "projectOpen" : undefined;
|
|
6182
6215
|
if (policyAction) {
|
|
6183
6216
|
// Child-safe mode is a hard capability boundary; the policy is an operator
|
|
6184
6217
|
// preference. Refuse first, so the gate never prompts for an action that is
|
|
@@ -6402,6 +6435,23 @@ export function createSubagentExecutor(deps) {
|
|
|
6402
6435
|
details: { mode: "management", results: [], spawnBudget, activeAsyncCapacity },
|
|
6403
6436
|
};
|
|
6404
6437
|
}
|
|
6438
|
+
if (["command.status", "command.yield", "command.cancel"].includes(action)) {
|
|
6439
|
+
try {
|
|
6440
|
+
if (deps.allowMutatingManagementActions === false && action !== "command.status")
|
|
6441
|
+
throw new Error(`Action '${action}' is not available from child-safe subagent fanout mode.`);
|
|
6442
|
+
const targetRunId = paramsWithResolvedCwd.id ?? paramsWithResolvedCwd.runId;
|
|
6443
|
+
if (!targetRunId || paramsWithResolvedCwd.dir)
|
|
6444
|
+
throw new Error(`${action} requires id or runId; directory targets are not supported.`);
|
|
6445
|
+
deps.state.currentSessionId = resolveCurrentSessionId(ctx.sessionManager);
|
|
6446
|
+
const target = resolveSubagentRunId(targetRunId, { state: deps.state, nested: nestedResolutionScopeForExecutor(deps) });
|
|
6447
|
+
if (!target)
|
|
6448
|
+
throw new Error(`No run found for '${targetRunId}'.`);
|
|
6449
|
+
return await commandAction({ state: deps.state, target, operation: action.slice("command.".length), index: paramsWithResolvedCwd.index, toolCallId: paramsWithResolvedCwd.toolCallId, signal });
|
|
6450
|
+
}
|
|
6451
|
+
catch (error) {
|
|
6452
|
+
return { content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }], isError: true, details: { mode: "management", results: [] } };
|
|
6453
|
+
}
|
|
6454
|
+
}
|
|
6405
6455
|
if (action === "status" || action === "debug.run") {
|
|
6406
6456
|
if (!preserveActiveSession)
|
|
6407
6457
|
deps.state.currentSessionId = resolveCurrentSessionId(ctx.sessionManager);
|
|
@@ -7088,6 +7138,7 @@ export function createSubagentExecutor(deps) {
|
|
|
7088
7138
|
toolBudget: runToolBudget.toolBudget,
|
|
7089
7139
|
usageBudget: usageBudget.budget,
|
|
7090
7140
|
inheritedUsageBudget,
|
|
7141
|
+
requiredExtensions: retainedRequiredExtensions,
|
|
7091
7142
|
allowZeroToolBudget,
|
|
7092
7143
|
configToolBudget: configToolBudget.toolBudget,
|
|
7093
7144
|
configToolTimeoutMs: deps.config.toolTimeoutMs,
|
|
@@ -7373,7 +7424,9 @@ export function createSubagentExecutor(deps) {
|
|
|
7373
7424
|
}
|
|
7374
7425
|
else if (workflow !== undefined || publicParams.workflowScript !== undefined) {
|
|
7375
7426
|
const normalizedArgs = normalizeWorkflowArgs(publicParams.args);
|
|
7376
|
-
|
|
7427
|
+
// validate reports args errors with its script errors; launch rejects them here.
|
|
7428
|
+
const validateOnly = publicParams.action === "validate";
|
|
7429
|
+
if ("error" in normalizedArgs && !validateOnly)
|
|
7377
7430
|
return errorResult(normalizedArgs.error);
|
|
7378
7431
|
let workflowScript = publicParams.workflowScript;
|
|
7379
7432
|
if (workflow !== undefined) {
|
|
@@ -7383,7 +7436,7 @@ export function createSubagentExecutor(deps) {
|
|
|
7383
7436
|
workflowScript = source.script;
|
|
7384
7437
|
}
|
|
7385
7438
|
const { workflow: _workflow, ...withoutWorkflowSource } = publicParams;
|
|
7386
|
-
publicParams = { ...withoutWorkflowSource, workflowScript, args: deepFreezeWorkflowArgs(normalizedArgs.args) };
|
|
7439
|
+
publicParams = { ...withoutWorkflowSource, workflowScript, args: "error" in normalizedArgs ? publicParams.args : deepFreezeWorkflowArgs(normalizedArgs.args) };
|
|
7387
7440
|
}
|
|
7388
7441
|
publicExecutions.add(publicParams);
|
|
7389
7442
|
return executeWithSingleDispatchGuard(id, publicParams, signal, onUpdate, ctx);
|