pi-subagents 0.28.0 → 0.29.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 +14 -0
- package/README.md +18 -61
- package/package.json +1 -1
- package/skills/pi-subagents/SKILL.md +4 -35
- package/src/agents/agent-management.ts +10 -20
- package/src/agents/agent-selection.ts +2 -0
- package/src/agents/agent-serializer.ts +0 -10
- package/src/agents/agents.ts +304 -47
- package/src/agents/chain-serializer.ts +4 -9
- package/src/extension/doctor.ts +4 -3
- package/src/extension/fanout-child.ts +0 -2
- package/src/extension/index.ts +3 -8
- package/src/extension/schemas.ts +32 -22
- package/src/intercom/intercom-bridge.ts +11 -1
- package/src/intercom/result-intercom.ts +0 -5
- package/src/runs/background/async-execution.ts +20 -11
- package/src/runs/background/run-status.ts +1 -7
- package/src/runs/background/subagent-runner.ts +81 -211
- package/src/runs/foreground/chain-execution.ts +62 -58
- package/src/runs/foreground/execution.ts +38 -343
- package/src/runs/foreground/subagent-executor.ts +28 -99
- package/src/runs/shared/acceptance.ts +605 -22
- package/src/runs/shared/completion-guard.ts +3 -26
- package/src/runs/shared/model-fallback.ts +38 -0
- package/src/runs/shared/parallel-utils.ts +6 -10
- package/src/runs/shared/subagent-prompt-runtime.ts +3 -2
- package/src/runs/shared/workflow-graph.ts +2 -6
- package/src/shared/atomic-json.ts +68 -11
- package/src/shared/settings.ts +1 -0
- package/src/shared/types.ts +10 -48
- package/src/shared/utils.ts +2 -8
- package/src/tui/render.ts +14 -29
- package/src/runs/shared/acceptance-contract.ts +0 -318
- package/src/runs/shared/acceptance-evaluation.ts +0 -221
- package/src/runs/shared/acceptance-finalization.ts +0 -173
- package/src/runs/shared/acceptance-reports.ts +0 -127
|
@@ -13,7 +13,7 @@ import { handleManagementAction } from "../../agents/agent-management.ts";
|
|
|
13
13
|
import { buildDoctorReport } from "../../extension/doctor.ts";
|
|
14
14
|
import { clearPendingForegroundControlNotices } from "../../extension/control-notices.ts";
|
|
15
15
|
import { runSync } from "./execution.ts";
|
|
16
|
-
import { resolveModelCandidate } from "../shared/model-fallback.ts";
|
|
16
|
+
import { resolveModelCandidate, resolveSubagentModelOverride } from "../shared/model-fallback.ts";
|
|
17
17
|
import { aggregateParallelOutputs } from "../shared/parallel-utils.ts";
|
|
18
18
|
import { recordRun } from "../shared/run-history.ts";
|
|
19
19
|
import {
|
|
@@ -53,7 +53,6 @@ import { resolveSubagentRunId, type ResolvedSubagentRunId } from "../background/
|
|
|
53
53
|
import { formatNestedRunStatusLines } from "../shared/nested-render.ts";
|
|
54
54
|
import { inspectSubagentStatus } from "../background/run-status.ts";
|
|
55
55
|
import { applyForceTopLevelAsyncOverride } from "../background/top-level-async.ts";
|
|
56
|
-
import { validateAcceptanceInput } from "../shared/acceptance.ts";
|
|
57
56
|
import {
|
|
58
57
|
cleanupWorktrees,
|
|
59
58
|
createWorktrees,
|
|
@@ -121,8 +120,6 @@ export interface SubagentParamsLike {
|
|
|
121
120
|
chain?: ChainStep[];
|
|
122
121
|
tasks?: TaskParam[];
|
|
123
122
|
concurrency?: number;
|
|
124
|
-
timeoutMs?: number;
|
|
125
|
-
maxRuntimeMs?: number;
|
|
126
123
|
worktree?: boolean;
|
|
127
124
|
context?: "fresh" | "fork";
|
|
128
125
|
async?: boolean;
|
|
@@ -171,7 +168,6 @@ interface ExecutionContextData {
|
|
|
171
168
|
artifactsDir: string;
|
|
172
169
|
backgroundRequestedWhileClarifying: boolean;
|
|
173
170
|
effectiveAsync: boolean;
|
|
174
|
-
foregroundTimeoutMs?: number;
|
|
175
171
|
controlConfig: ResolvedControlConfig;
|
|
176
172
|
intercomBridge: IntercomBridgeState;
|
|
177
173
|
nestedRoute?: NestedRouteInfo;
|
|
@@ -253,7 +249,7 @@ function rememberForegroundRun(state: SubagentState, input: { runId: string; mod
|
|
|
253
249
|
children: input.results.map((result, index) => ({
|
|
254
250
|
agent: result.agent,
|
|
255
251
|
index,
|
|
256
|
-
status: resolveSubagentResultStatus({ exitCode: result.exitCode, interrupted: result.interrupted, detached: result.detached
|
|
252
|
+
status: resolveSubagentResultStatus({ exitCode: result.exitCode, interrupted: result.interrupted, detached: result.detached }),
|
|
257
253
|
...(result.sessionFile ? { sessionFile: result.sessionFile } : {}),
|
|
258
254
|
})),
|
|
259
255
|
});
|
|
@@ -653,6 +649,7 @@ async function resumeAsyncRun(input: {
|
|
|
653
649
|
cwd: input.requestCwd,
|
|
654
650
|
currentSessionId: input.deps.state.currentSessionId,
|
|
655
651
|
currentModelProvider: input.ctx.model?.provider,
|
|
652
|
+
currentModel: input.ctx.model,
|
|
656
653
|
},
|
|
657
654
|
cwd: effectiveCwd,
|
|
658
655
|
maxOutput: input.params.maxOutput,
|
|
@@ -694,6 +691,19 @@ function resultSummaryForIntercom(result: SingleResult): string {
|
|
|
694
691
|
return output || result.error || "(no output)";
|
|
695
692
|
}
|
|
696
693
|
|
|
694
|
+
function formatFailedSingleRunOutput(result: SingleResult, displayOutput: string): string {
|
|
695
|
+
const error = result.error || "Failed";
|
|
696
|
+
const output = displayOutput.trim();
|
|
697
|
+
const lines = [error];
|
|
698
|
+
if (output && output !== error.trim()) {
|
|
699
|
+
lines.push("", "Output:", output);
|
|
700
|
+
}
|
|
701
|
+
if (result.artifactPaths?.outputPath) {
|
|
702
|
+
lines.push("", `Output artifact: ${result.artifactPaths.outputPath}`);
|
|
703
|
+
}
|
|
704
|
+
return lines.join("\n");
|
|
705
|
+
}
|
|
706
|
+
|
|
697
707
|
function createForegroundControlNotifier(data: Pick<ExecutionContextData, "controlConfig" | "intercomBridge">, deps: Pick<ExecutorDeps, "pi">): (event: ControlEvent) => void {
|
|
698
708
|
return (event) => emitControlNotification({
|
|
699
709
|
pi: deps.pi,
|
|
@@ -719,7 +729,6 @@ async function emitForegroundResultIntercom(input: {
|
|
|
719
729
|
exitCode: result.exitCode,
|
|
720
730
|
interrupted: result.interrupted,
|
|
721
731
|
detached: result.detached,
|
|
722
|
-
timedOut: result.timedOut,
|
|
723
732
|
}),
|
|
724
733
|
summary: resultSummaryForIntercom(result),
|
|
725
734
|
index,
|
|
@@ -765,51 +774,6 @@ async function maybeBuildForegroundIntercomReceipt(input: {
|
|
|
765
774
|
};
|
|
766
775
|
}
|
|
767
776
|
|
|
768
|
-
function validationErrorResult(mode: Details["mode"], text: string): AgentToolResult<Details> {
|
|
769
|
-
return { content: [{ type: "text", text }], isError: true, details: { mode, results: [] } };
|
|
770
|
-
}
|
|
771
|
-
|
|
772
|
-
function resolveForegroundTimeoutMs(params: SubagentParamsLike): { timeoutMs?: number; error?: string } {
|
|
773
|
-
const rawTimeout = (params as { timeoutMs?: unknown }).timeoutMs;
|
|
774
|
-
const rawMaxRuntime = (params as { maxRuntimeMs?: unknown }).maxRuntimeMs;
|
|
775
|
-
for (const [name, value] of [["timeoutMs", rawTimeout], ["maxRuntimeMs", rawMaxRuntime]] as const) {
|
|
776
|
-
if (value !== undefined && (typeof value !== "number" || !Number.isInteger(value) || value < 1)) {
|
|
777
|
-
return { error: `${name} must be a positive integer.` };
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
if (rawTimeout !== undefined && rawMaxRuntime !== undefined && rawTimeout !== rawMaxRuntime) {
|
|
781
|
-
return { error: "timeoutMs and maxRuntimeMs are aliases; provide only one or use identical values." };
|
|
782
|
-
}
|
|
783
|
-
const timeoutMs = rawTimeout ?? rawMaxRuntime;
|
|
784
|
-
return timeoutMs === undefined ? {} : { timeoutMs };
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
function validateAcceptanceForExecution(params: SubagentParamsLike): AgentToolResult<Details> | null {
|
|
788
|
-
const topLevelErrors = validateAcceptanceInput(params.acceptance);
|
|
789
|
-
if (topLevelErrors.length > 0) return validationErrorResult("single", topLevelErrors.join(" "));
|
|
790
|
-
for (const [index, task] of (params.tasks ?? []).entries()) {
|
|
791
|
-
const errors = validateAcceptanceInput(task.acceptance, `tasks[${index}].acceptance`);
|
|
792
|
-
if (errors.length > 0) return validationErrorResult("parallel", errors.join(" "));
|
|
793
|
-
}
|
|
794
|
-
for (const [stepIndex, step] of (params.chain ?? []).entries()) {
|
|
795
|
-
if (isParallelStep(step)) {
|
|
796
|
-
if (Object.hasOwn(step, "acceptance")) return validationErrorResult("chain", `chain[${stepIndex}].acceptance is not supported on static parallel groups; set acceptance on each parallel task.`);
|
|
797
|
-
for (const [taskIndex, task] of step.parallel.entries()) {
|
|
798
|
-
const errors = validateAcceptanceInput(task.acceptance, `chain[${stepIndex}].parallel[${taskIndex}].acceptance`);
|
|
799
|
-
if (errors.length > 0) return validationErrorResult("chain", errors.join(" "));
|
|
800
|
-
}
|
|
801
|
-
} else if (isDynamicParallelStep(step)) {
|
|
802
|
-
if (Object.hasOwn(step, "acceptance")) return validationErrorResult("chain", `chain[${stepIndex}].acceptance is not supported on dynamic fanout groups; set acceptance on chain[${stepIndex}].parallel.acceptance for each materialized child.`);
|
|
803
|
-
const errors = validateAcceptanceInput(step.parallel.acceptance, `chain[${stepIndex}].parallel.acceptance`);
|
|
804
|
-
if (errors.length > 0) return validationErrorResult("chain", errors.join(" "));
|
|
805
|
-
} else {
|
|
806
|
-
const stepErrors = validateAcceptanceInput(step.acceptance, `chain[${stepIndex}].acceptance`);
|
|
807
|
-
if (stepErrors.length > 0) return validationErrorResult("chain", stepErrors.join(" "));
|
|
808
|
-
}
|
|
809
|
-
}
|
|
810
|
-
return null;
|
|
811
|
-
}
|
|
812
|
-
|
|
813
777
|
function validateExecutionInput(
|
|
814
778
|
params: SubagentParamsLike,
|
|
815
779
|
agents: AgentConfig[],
|
|
@@ -818,9 +782,6 @@ function validateExecutionInput(
|
|
|
818
782
|
hasSingle: boolean,
|
|
819
783
|
allowClarifyTaskPrompt: boolean,
|
|
820
784
|
): AgentToolResult<Details> | null {
|
|
821
|
-
const acceptanceError = validateAcceptanceForExecution(params);
|
|
822
|
-
if (acceptanceError) return acceptanceError;
|
|
823
|
-
|
|
824
785
|
if (Number(hasChain) + Number(hasTasks) + Number(hasSingle) !== 1) {
|
|
825
786
|
return {
|
|
826
787
|
content: [
|
|
@@ -834,9 +795,6 @@ function validateExecutionInput(
|
|
|
834
795
|
};
|
|
835
796
|
}
|
|
836
797
|
|
|
837
|
-
const timeoutResolution = resolveForegroundTimeoutMs(params);
|
|
838
|
-
if (timeoutResolution.error) return validationErrorResult(getRequestedModeLabel(params), timeoutResolution.error);
|
|
839
|
-
|
|
840
798
|
if (hasSingle && params.agent && !agents.find((agent) => agent.name === params.agent)) {
|
|
841
799
|
return {
|
|
842
800
|
content: [{ type: "text", text: `Unknown agent: ${params.agent}` }],
|
|
@@ -1138,6 +1096,7 @@ function runAsyncPath(data: ExecutionContextData, deps: ExecutorDeps): AgentTool
|
|
|
1138
1096
|
cwd: ctx.cwd,
|
|
1139
1097
|
currentSessionId: deps.state.currentSessionId!,
|
|
1140
1098
|
currentModelProvider: ctx.model?.provider,
|
|
1099
|
+
currentModel: ctx.model,
|
|
1141
1100
|
};
|
|
1142
1101
|
const availableModels: ModelInfo[] = ctx.modelRegistry.getAvailable().map(toModelInfo);
|
|
1143
1102
|
const currentMaxSubagentDepth = resolveCurrentMaxSubagentDepth(deps.config.maxSubagentDepth);
|
|
@@ -1148,7 +1107,7 @@ function runAsyncPath(data: ExecutionContextData, deps: ExecutorDeps): AgentTool
|
|
|
1148
1107
|
if (hasTasks && params.tasks) {
|
|
1149
1108
|
const agentConfigs = params.tasks.map((task) => agents.find((agent) => agent.name === task.agent));
|
|
1150
1109
|
const modelOverrides = params.tasks.map((task, index) =>
|
|
1151
|
-
|
|
1110
|
+
resolveSubagentModelOverride(task.model ?? agentConfigs[index]?.model, ctx.model, availableModels, currentProvider),
|
|
1152
1111
|
);
|
|
1153
1112
|
const skillOverrides = params.tasks.map((task) => normalizeSkillInput(task.skill));
|
|
1154
1113
|
const parallelTasks = params.tasks.map((task, index) => ({
|
|
@@ -1235,7 +1194,7 @@ function runAsyncPath(data: ExecutionContextData, deps: ExecutorDeps): AgentTool
|
|
|
1235
1194
|
const normalizedSkills = normalizeSkillInput(params.skill);
|
|
1236
1195
|
const skills = normalizedSkills === false ? [] : normalizedSkills;
|
|
1237
1196
|
const maxSubagentDepth = resolveChildMaxSubagentDepth(currentMaxSubagentDepth, a.maxSubagentDepth);
|
|
1238
|
-
const modelOverride =
|
|
1197
|
+
const modelOverride = resolveSubagentModelOverride((params.model as string | undefined) ?? a.model, ctx.model, availableModels, currentProvider);
|
|
1239
1198
|
return executeAsyncSingle(id, {
|
|
1240
1199
|
agent: params.agent!,
|
|
1241
1200
|
task: params.context === "fork" ? wrapForkTask(params.task ?? "") : (params.task ?? ""),
|
|
@@ -1310,7 +1269,6 @@ async function runChainPath(data: ExecutionContextData, deps: ExecutorDeps): Pro
|
|
|
1310
1269
|
onUpdate,
|
|
1311
1270
|
onControlEvent,
|
|
1312
1271
|
controlConfig,
|
|
1313
|
-
...(data.foregroundTimeoutMs !== undefined ? { timeoutMs: data.foregroundTimeoutMs } : {}),
|
|
1314
1272
|
childIntercomTarget: childIntercomTarget ? (agent, index) => childIntercomTarget(runId, agent, index) : undefined,
|
|
1315
1273
|
orchestratorIntercomTarget: data.intercomBridge.active ? data.intercomBridge.orchestratorTarget : undefined,
|
|
1316
1274
|
foregroundControl,
|
|
@@ -1337,6 +1295,7 @@ async function runChainPath(data: ExecutionContextData, deps: ExecutorDeps): Pro
|
|
|
1337
1295
|
cwd: ctx.cwd,
|
|
1338
1296
|
currentSessionId: deps.state.currentSessionId!,
|
|
1339
1297
|
currentModelProvider: ctx.model?.provider,
|
|
1298
|
+
currentModel: ctx.model,
|
|
1340
1299
|
};
|
|
1341
1300
|
const asyncChain = wrapChainTasksForFork(chainResult.requestedAsync.chain, params.context);
|
|
1342
1301
|
return executeAsyncChain(id, {
|
|
@@ -1367,7 +1326,7 @@ async function runChainPath(data: ExecutionContextData, deps: ExecutorDeps): Pro
|
|
|
1367
1326
|
const chainDetails = chainResult.details ? compactForegroundDetails({ ...chainResult.details, runId }) : undefined;
|
|
1368
1327
|
if (foregroundControl) updateForegroundNestedProjection(foregroundControl);
|
|
1369
1328
|
if (chainDetails) rememberForegroundRun(deps.state, { runId, mode: "chain", cwd: effectiveCwd, results: chainDetails.results });
|
|
1370
|
-
const intercomReceipt = chainDetails && !chainDetails.results.some((result) => result.interrupted || result.detached
|
|
1329
|
+
const intercomReceipt = chainDetails && !chainDetails.results.some((result) => result.interrupted || result.detached)
|
|
1371
1330
|
? await maybeBuildForegroundIntercomReceipt({
|
|
1372
1331
|
pi: deps.pi,
|
|
1373
1332
|
intercomBridge: data.intercomBridge,
|
|
@@ -1402,8 +1361,6 @@ interface ForegroundParallelRunInput {
|
|
|
1402
1361
|
artifactConfig: ArtifactConfig;
|
|
1403
1362
|
artifactsDir: string;
|
|
1404
1363
|
maxOutput?: MaxOutputConfig;
|
|
1405
|
-
timeoutMs?: number;
|
|
1406
|
-
timeoutAt?: number;
|
|
1407
1364
|
paramsCwd: string;
|
|
1408
1365
|
maxSubagentDepths: number[];
|
|
1409
1366
|
availableModels: ModelInfo[];
|
|
@@ -1556,7 +1513,6 @@ async function runForegroundParallelTasks(input: ForegroundParallelRunInput): Pr
|
|
|
1556
1513
|
cwd: taskCwd,
|
|
1557
1514
|
signal: input.signal,
|
|
1558
1515
|
interruptSignal: interruptController.signal,
|
|
1559
|
-
...(input.timeoutMs !== undefined && input.timeoutAt !== undefined ? { timeoutMs: input.timeoutMs, timeoutAt: input.timeoutAt } : {}),
|
|
1560
1516
|
allowIntercomDetach: agentConfig?.systemPrompt?.includes(INTERCOM_BRIDGE_MARKER) === true,
|
|
1561
1517
|
intercomEvents: input.intercomEvents,
|
|
1562
1518
|
runId: input.runId,
|
|
@@ -1570,8 +1526,6 @@ async function runForegroundParallelTasks(input: ForegroundParallelRunInput): Pr
|
|
|
1570
1526
|
outputPath,
|
|
1571
1527
|
outputMode: behavior?.outputMode,
|
|
1572
1528
|
maxSubagentDepth: input.maxSubagentDepths[index],
|
|
1573
|
-
maxExecutionTimeMs: agentConfig?.maxExecutionTimeMs,
|
|
1574
|
-
maxTokens: agentConfig?.maxTokens,
|
|
1575
1529
|
controlConfig: input.controlConfig,
|
|
1576
1530
|
onControlEvent: input.onControlEvent,
|
|
1577
1531
|
intercomSessionName: input.childIntercomTarget?.(task.agent, index),
|
|
@@ -1697,7 +1651,7 @@ async function runParallelPath(data: ExecutionContextData, deps: ExecutorDeps):
|
|
|
1697
1651
|
...(task.model ? { model: task.model } : {}),
|
|
1698
1652
|
}));
|
|
1699
1653
|
const modelOverrides: (string | undefined)[] = tasks.map((_, i) =>
|
|
1700
|
-
|
|
1654
|
+
resolveSubagentModelOverride(behaviorOverrides[i]?.model ?? agentConfigs[i]?.model, ctx.model, availableModels, currentProvider),
|
|
1701
1655
|
);
|
|
1702
1656
|
|
|
1703
1657
|
if (params.clarify === true && ctx.hasUI) {
|
|
@@ -1758,6 +1712,7 @@ async function runParallelPath(data: ExecutionContextData, deps: ExecutorDeps):
|
|
|
1758
1712
|
cwd: ctx.cwd,
|
|
1759
1713
|
currentSessionId: deps.state.currentSessionId!,
|
|
1760
1714
|
currentModelProvider: ctx.model?.provider,
|
|
1715
|
+
currentModel: ctx.model,
|
|
1761
1716
|
};
|
|
1762
1717
|
const parallelTasks = tasks.map((t, i) => {
|
|
1763
1718
|
const taskText = params.context === "fork" ? wrapForkTask(taskTexts[i]!) : taskTexts[i]!;
|
|
@@ -1839,7 +1794,6 @@ async function runParallelPath(data: ExecutionContextData, deps: ExecutorDeps):
|
|
|
1839
1794
|
}
|
|
1840
1795
|
}
|
|
1841
1796
|
|
|
1842
|
-
const timeoutAt = data.foregroundTimeoutMs !== undefined ? Date.now() + data.foregroundTimeoutMs : undefined;
|
|
1843
1797
|
const results = await runForegroundParallelTasks({
|
|
1844
1798
|
tasks,
|
|
1845
1799
|
taskTexts,
|
|
@@ -1854,7 +1808,6 @@ async function runParallelPath(data: ExecutionContextData, deps: ExecutorDeps):
|
|
|
1854
1808
|
artifactConfig,
|
|
1855
1809
|
artifactsDir,
|
|
1856
1810
|
maxOutput: params.maxOutput,
|
|
1857
|
-
...(data.foregroundTimeoutMs !== undefined && timeoutAt !== undefined ? { timeoutMs: data.foregroundTimeoutMs, timeoutAt } : {}),
|
|
1858
1811
|
paramsCwd: effectiveCwd,
|
|
1859
1812
|
availableModels,
|
|
1860
1813
|
modelOverrides,
|
|
@@ -1882,7 +1835,6 @@ async function runParallelPath(data: ExecutionContextData, deps: ExecutorDeps):
|
|
|
1882
1835
|
if (result.artifactPaths) allArtifactPaths.push(result.artifactPaths);
|
|
1883
1836
|
}
|
|
1884
1837
|
|
|
1885
|
-
const timedOut = results.find((result) => result.timedOut);
|
|
1886
1838
|
const interrupted = results.find((result) => result.interrupted);
|
|
1887
1839
|
const details = compactForegroundDetails({
|
|
1888
1840
|
mode: "parallel",
|
|
@@ -1892,13 +1844,6 @@ async function runParallelPath(data: ExecutionContextData, deps: ExecutorDeps):
|
|
|
1892
1844
|
artifacts: allArtifactPaths.length ? { dir: artifactsDir, files: allArtifactPaths } : undefined,
|
|
1893
1845
|
});
|
|
1894
1846
|
rememberForegroundRun(deps.state, { runId, mode: "parallel", cwd: effectiveCwd, results: details.results });
|
|
1895
|
-
if (timedOut) {
|
|
1896
|
-
return {
|
|
1897
|
-
content: [{ type: "text", text: `Parallel run timed out (${timedOut.agent}): ${timedOut.error ?? "timeout expired"}` }],
|
|
1898
|
-
details,
|
|
1899
|
-
isError: true,
|
|
1900
|
-
};
|
|
1901
|
-
}
|
|
1902
1847
|
if (interrupted) {
|
|
1903
1848
|
return {
|
|
1904
1849
|
content: [{ type: "text", text: `Parallel run paused after interrupt (${interrupted.agent}). Waiting for explicit next action.` }],
|
|
@@ -1990,8 +1935,9 @@ async function runSinglePath(data: ExecutionContextData, deps: ExecutorDeps): Pr
|
|
|
1990
1935
|
const currentProvider = ctx.model?.provider;
|
|
1991
1936
|
const availableModels: ModelInfo[] = ctx.modelRegistry.getAvailable().map(toModelInfo);
|
|
1992
1937
|
let task = params.task ?? "";
|
|
1993
|
-
let modelOverride: string | undefined =
|
|
1938
|
+
let modelOverride: string | undefined = resolveSubagentModelOverride(
|
|
1994
1939
|
(params.model as string | undefined) ?? agentConfig.model,
|
|
1940
|
+
ctx.model,
|
|
1995
1941
|
availableModels,
|
|
1996
1942
|
currentProvider,
|
|
1997
1943
|
);
|
|
@@ -2048,6 +1994,7 @@ async function runSinglePath(data: ExecutionContextData, deps: ExecutorDeps): Pr
|
|
|
2048
1994
|
cwd: ctx.cwd,
|
|
2049
1995
|
currentSessionId: deps.state.currentSessionId!,
|
|
2050
1996
|
currentModelProvider: ctx.model?.provider,
|
|
1997
|
+
currentModel: ctx.model,
|
|
2051
1998
|
};
|
|
2052
1999
|
return executeAsyncSingle(id, {
|
|
2053
2000
|
agent: params.agent!,
|
|
@@ -2129,12 +2076,10 @@ async function runSinglePath(data: ExecutionContextData, deps: ExecutorDeps): Pr
|
|
|
2129
2076
|
}
|
|
2130
2077
|
: undefined;
|
|
2131
2078
|
|
|
2132
|
-
const timeoutAt = data.foregroundTimeoutMs !== undefined ? Date.now() + data.foregroundTimeoutMs : undefined;
|
|
2133
2079
|
const r = await runSync(ctx.cwd, agents, params.agent!, task, {
|
|
2134
2080
|
cwd: effectiveCwd,
|
|
2135
2081
|
signal,
|
|
2136
2082
|
interruptSignal: interruptController.signal,
|
|
2137
|
-
...(data.foregroundTimeoutMs !== undefined && timeoutAt !== undefined ? { timeoutMs: data.foregroundTimeoutMs, timeoutAt } : {}),
|
|
2138
2083
|
allowIntercomDetach: agentConfig.systemPrompt?.includes(INTERCOM_BRIDGE_MARKER) === true,
|
|
2139
2084
|
intercomEvents: deps.pi.events,
|
|
2140
2085
|
runId,
|
|
@@ -2147,8 +2092,6 @@ async function runSinglePath(data: ExecutionContextData, deps: ExecutorDeps): Pr
|
|
|
2147
2092
|
outputPath,
|
|
2148
2093
|
outputMode: effectiveOutputMode,
|
|
2149
2094
|
maxSubagentDepth,
|
|
2150
|
-
maxExecutionTimeMs: agentConfig.maxExecutionTimeMs,
|
|
2151
|
-
maxTokens: agentConfig.maxTokens,
|
|
2152
2095
|
onUpdate: forwardSingleUpdate,
|
|
2153
2096
|
controlConfig,
|
|
2154
2097
|
onControlEvent,
|
|
@@ -2201,7 +2144,7 @@ async function runSinglePath(data: ExecutionContextData, deps: ExecutorDeps): Pr
|
|
|
2201
2144
|
});
|
|
2202
2145
|
rememberForegroundRun(deps.state, { runId, mode: "single", cwd: effectiveCwd, results: details.results });
|
|
2203
2146
|
|
|
2204
|
-
if (!r.detached && !r.interrupted
|
|
2147
|
+
if (!r.detached && !r.interrupted) {
|
|
2205
2148
|
if (foregroundControl) updateForegroundNestedProjection(foregroundControl);
|
|
2206
2149
|
const intercomReceipt = await maybeBuildForegroundIntercomReceipt({
|
|
2207
2150
|
pi: deps.pi,
|
|
@@ -2227,14 +2170,6 @@ async function runSinglePath(data: ExecutionContextData, deps: ExecutorDeps): Pr
|
|
|
2227
2170
|
};
|
|
2228
2171
|
}
|
|
2229
2172
|
|
|
2230
|
-
if (r.timedOut) {
|
|
2231
|
-
return {
|
|
2232
|
-
content: [{ type: "text", text: `Run timed out (${params.agent}): ${r.error ?? "timeout expired"}` }],
|
|
2233
|
-
details,
|
|
2234
|
-
isError: true,
|
|
2235
|
-
};
|
|
2236
|
-
}
|
|
2237
|
-
|
|
2238
2173
|
if (r.interrupted) {
|
|
2239
2174
|
return {
|
|
2240
2175
|
content: [{ type: "text", text: `Run paused after interrupt (${params.agent}). Waiting for explicit next action.` }],
|
|
@@ -2244,7 +2179,7 @@ async function runSinglePath(data: ExecutionContextData, deps: ExecutorDeps): Pr
|
|
|
2244
2179
|
|
|
2245
2180
|
if (r.exitCode !== 0)
|
|
2246
2181
|
return {
|
|
2247
|
-
content: [{ type: "text", text: r.
|
|
2182
|
+
content: [{ type: "text", text: formatFailedSingleRunOutput(r, finalizedOutput.displayOutput) }],
|
|
2248
2183
|
details,
|
|
2249
2184
|
isError: true,
|
|
2250
2185
|
};
|
|
@@ -2462,11 +2397,6 @@ export function createSubagentExecutor(deps: ExecutorDeps): {
|
|
|
2462
2397
|
const requestedAsync = effectiveParams.async ?? deps.asyncByDefault;
|
|
2463
2398
|
const backgroundRequestedWhileClarifying = (hasChain || hasTasks) && requestedAsync && effectiveParams.clarify === true;
|
|
2464
2399
|
const effectiveAsync = requestedAsync && effectiveParams.clarify !== true;
|
|
2465
|
-
const foregroundTimeout = resolveForegroundTimeoutMs(effectiveParams);
|
|
2466
|
-
if (foregroundTimeout.error) return buildRequestedModeError(effectiveParams, foregroundTimeout.error);
|
|
2467
|
-
if (effectiveAsync && foregroundTimeout.timeoutMs !== undefined) {
|
|
2468
|
-
return buildRequestedModeError(effectiveParams, "timeoutMs/maxRuntimeMs only applies to foreground subagent runs. Omit async:true or use action:'interrupt' for background runs.");
|
|
2469
|
-
}
|
|
2470
2400
|
const controlConfig = resolveControlConfig(deps.config.control, effectiveParams.control);
|
|
2471
2401
|
|
|
2472
2402
|
const artifactConfig: ArtifactConfig = {
|
|
@@ -2518,7 +2448,6 @@ export function createSubagentExecutor(deps: ExecutorDeps): {
|
|
|
2518
2448
|
artifactsDir,
|
|
2519
2449
|
backgroundRequestedWhileClarifying,
|
|
2520
2450
|
effectiveAsync,
|
|
2521
|
-
...(foregroundTimeout.timeoutMs !== undefined ? { foregroundTimeoutMs: foregroundTimeout.timeoutMs } : {}),
|
|
2522
2451
|
controlConfig,
|
|
2523
2452
|
intercomBridge,
|
|
2524
2453
|
nestedRoute,
|