pi-subagents 0.77.0 → 0.78.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 +48 -0
- package/agents/evidence-auditor.md +1 -0
- package/agents/oracle.md +1 -0
- package/agents/reviewer.md +1 -0
- package/docs/agents.md +1 -1
- package/docs/configuration.md +21 -5
- package/docs/extension-api.md +5 -1
- package/docs/observability.md +2 -0
- package/docs/tool-reference.md +2 -2
- package/docs/workflows.md +2 -2
- package/package.json +1 -1
- package/skills/pi-subagents/SKILL.md +1 -1
- package/skills/pi-subagents/references/multi-lane-orchestration.md +1 -1
- package/src/api/external-runs.d.ts.map +1 -1
- package/src/api/external-runs.js +5 -4
- package/src/api/external-runs.js.map +1 -1
- package/src/api/preflight.js +1 -1
- package/src/api/preflight.js.map +1 -1
- package/src/extension/active-runs-prompt.d.ts +8 -0
- package/src/extension/active-runs-prompt.d.ts.map +1 -0
- package/src/extension/active-runs-prompt.js +30 -0
- package/src/extension/active-runs-prompt.js.map +1 -0
- package/src/extension/config.d.ts.map +1 -1
- package/src/extension/config.js +6 -0
- package/src/extension/config.js.map +1 -1
- package/src/extension/declaration-pinning.d.ts +5 -0
- package/src/extension/declaration-pinning.d.ts.map +1 -1
- package/src/extension/declaration-pinning.js +9 -2
- package/src/extension/declaration-pinning.js.map +1 -1
- package/src/extension/index.d.ts +0 -1
- package/src/extension/index.d.ts.map +1 -1
- package/src/extension/index.js +56 -14
- package/src/extension/index.js.map +1 -1
- package/src/extension/tool-activation.d.ts.map +1 -1
- package/src/extension/tool-activation.js +4 -2
- package/src/extension/tool-activation.js.map +1 -1
- package/src/intercom/native-supervisor-channel.d.ts +16 -1
- package/src/intercom/native-supervisor-channel.d.ts.map +1 -1
- package/src/intercom/native-supervisor-channel.js +25 -6
- package/src/intercom/native-supervisor-channel.js.map +1 -1
- package/src/runs/background/active-async-capacity.d.ts +2 -1
- package/src/runs/background/active-async-capacity.d.ts.map +1 -1
- package/src/runs/background/active-async-capacity.js +10 -6
- package/src/runs/background/active-async-capacity.js.map +1 -1
- package/src/runs/background/async-execution.js +3 -3
- package/src/runs/background/async-execution.js.map +1 -1
- package/src/runs/background/async-resume.d.ts.map +1 -1
- package/src/runs/background/async-resume.js +3 -1
- package/src/runs/background/async-resume.js.map +1 -1
- package/src/runs/background/chain-root-attachment.js +4 -4
- package/src/runs/background/chain-root-attachment.js.map +1 -1
- package/src/runs/background/control-channel.d.ts +1 -0
- package/src/runs/background/control-channel.d.ts.map +1 -1
- package/src/runs/background/control-channel.js +27 -3
- package/src/runs/background/control-channel.js.map +1 -1
- package/src/runs/background/notify.d.ts +1 -1
- package/src/runs/background/notify.d.ts.map +1 -1
- package/src/runs/background/notify.js +8 -4
- package/src/runs/background/notify.js.map +1 -1
- package/src/runs/background/run-child-session.d.ts.map +1 -1
- package/src/runs/background/run-child-session.js +7 -14
- package/src/runs/background/run-child-session.js.map +1 -1
- package/src/runs/background/runner-aliases.d.ts.map +1 -1
- package/src/runs/background/runner-aliases.js +11 -8
- package/src/runs/background/runner-aliases.js.map +1 -1
- package/src/runs/background/subagent-runner.d.ts.map +1 -1
- package/src/runs/background/subagent-runner.js +198 -279
- package/src/runs/background/subagent-runner.js.map +1 -1
- package/src/runs/background/workflow-terminal-proof.d.ts +1 -1
- package/src/runs/background/workflow-terminal-proof.d.ts.map +1 -1
- package/src/runs/background/workflow-terminal-proof.js +12 -3
- package/src/runs/background/workflow-terminal-proof.js.map +1 -1
- package/src/runs/foreground/async-stop-action.d.ts.map +1 -1
- package/src/runs/foreground/async-stop-action.js +6 -7
- package/src/runs/foreground/async-stop-action.js.map +1 -1
- package/src/runs/foreground/execution.d.ts.map +1 -1
- package/src/runs/foreground/execution.js +51 -55
- package/src/runs/foreground/execution.js.map +1 -1
- package/src/runs/foreground/subagent-executor.d.ts.map +1 -1
- package/src/runs/foreground/subagent-executor.js +26 -35
- package/src/runs/foreground/subagent-executor.js.map +1 -1
- package/src/runs/shared/effective-system-prompt.d.ts +4 -4
- package/src/runs/shared/effective-system-prompt.d.ts.map +1 -1
- package/src/runs/shared/effective-system-prompt.js +5 -4
- package/src/runs/shared/effective-system-prompt.js.map +1 -1
- package/src/runs/shared/external-cli-runner.d.ts.map +1 -1
- package/src/runs/shared/external-cli-runner.js +3 -2
- package/src/runs/shared/external-cli-runner.js.map +1 -1
- package/src/runs/shared/model-resolution-diagnostic.d.ts +7 -5
- package/src/runs/shared/model-resolution-diagnostic.d.ts.map +1 -1
- package/src/runs/shared/model-resolution-diagnostic.js +13 -10
- package/src/runs/shared/model-resolution-diagnostic.js.map +1 -1
- package/src/runs/shared/orca-progress-tabs.js +1 -1
- package/src/runs/shared/orca-progress-tabs.js.map +1 -1
- package/src/runs/shared/partial-output.d.ts +7 -0
- package/src/runs/shared/partial-output.d.ts.map +1 -1
- package/src/runs/shared/partial-output.js +7 -0
- package/src/runs/shared/partial-output.js.map +1 -1
- package/src/runs/shared/single-output.d.ts +11 -1
- package/src/runs/shared/single-output.d.ts.map +1 -1
- package/src/runs/shared/single-output.js +48 -26
- package/src/runs/shared/single-output.js.map +1 -1
- package/src/runs/shared/structured-output.d.ts +2 -0
- package/src/runs/shared/structured-output.d.ts.map +1 -1
- package/src/runs/shared/structured-output.js +9 -0
- package/src/runs/shared/structured-output.js.map +1 -1
- package/src/runs/shared/subagent-prompt-runtime.d.ts +29 -0
- package/src/runs/shared/subagent-prompt-runtime.d.ts.map +1 -1
- package/src/runs/shared/subagent-prompt-runtime.js +87 -2
- package/src/runs/shared/subagent-prompt-runtime.js.map +1 -1
- package/src/runs/shared/tool-budget.js +1 -1
- package/src/runs/shared/tool-budget.js.map +1 -1
- package/src/shared/child-transcript.js +1 -1
- package/src/shared/child-transcript.js.map +1 -1
- package/src/shared/extension-context.d.ts +5 -0
- package/src/shared/extension-context.d.ts.map +1 -1
- package/src/shared/extension-context.js +7 -0
- package/src/shared/extension-context.js.map +1 -1
- package/src/shared/parent-wake.d.ts +6 -0
- package/src/shared/parent-wake.d.ts.map +1 -1
- package/src/shared/parent-wake.js +11 -0
- package/src/shared/parent-wake.js.map +1 -1
- package/src/shared/types.d.ts +7 -8
- package/src/shared/types.d.ts.map +1 -1
- package/src/shared/types.js +4 -4
- package/src/shared/types.js.map +1 -1
- package/src/shared/utils.d.ts +2 -0
- package/src/shared/utils.d.ts.map +1 -1
- package/src/shared/utils.js +2 -0
- package/src/shared/utils.js.map +1 -1
- package/src/slash/slash-commands.d.ts.map +1 -1
- package/src/slash/slash-commands.js +20 -9
- package/src/slash/slash-commands.js.map +1 -1
- package/src/slash/subagents-admin.d.ts.map +1 -1
- package/src/slash/subagents-admin.js +3 -2
- package/src/slash/subagents-admin.js.map +1 -1
- package/src/tui/fleet-status.d.ts +5 -0
- package/src/tui/fleet-status.d.ts.map +1 -1
- package/src/tui/fleet-status.js +24 -3
- package/src/tui/fleet-status.js.map +1 -1
- package/src/tui/fleet.js +2 -2
- package/src/tui/fleet.js.map +1 -1
- package/src/watchdog/change-signature.d.ts.map +1 -1
- package/src/watchdog/change-signature.js +1 -3
- package/src/watchdog/change-signature.js.map +1 -1
- package/src/workflows/scripted-workflow.d.ts.map +1 -1
- package/src/workflows/scripted-workflow.js +13 -4
- package/src/workflows/scripted-workflow.js.map +1 -1
- package/src/runs/shared/run-history.d.ts +0 -67
- package/src/runs/shared/run-history.d.ts.map +0 -1
- package/src/runs/shared/run-history.js +0 -270
- package/src/runs/shared/run-history.js.map +0 -1
|
@@ -23,7 +23,8 @@ import { closeSteerInbox, closeStopInbox, consumeInterruptRequest, consumeSteerR
|
|
|
23
23
|
import { appendJsonl as appendRawJsonl, formatOutputArtifactContent, getArtifactPaths, writeArtifact, writeMetadata } from "../../shared/artifacts.js";
|
|
24
24
|
import { PI_CODING_AGENT_PACKAGE, resolveInstalledPiPackageRoot } from "../shared/pi-spawn.js";
|
|
25
25
|
import { preflightLaunchCwd } from "../shared/launch-cwd.js";
|
|
26
|
-
import { captureSingleOutputSnapshot, extractChildWrittenOutput, finalizeSingleOutput, formatSavedOutputReference,
|
|
26
|
+
import { captureSingleOutputSnapshot, extractChildWrittenOutput, finalizeSingleOutput, formatSavedOutputReference, injectSingleOutputInstruction, isSettlementFatalOutputError, resolveSingleOutput } from "../shared/single-output.js";
|
|
27
|
+
import { timedOutRunSummary } from "../shared/partial-output.js";
|
|
27
28
|
import { runSetupCommand } from "../shared/worktree-setup-command.js";
|
|
28
29
|
import { DEFAULT_MAX_OUTPUT, SUBAGENT_LIFECYCLE_ARTIFACT_VERSION, truncateOutput, } from "../../shared/types.js";
|
|
29
30
|
import { DEFAULT_CONTROL_CONFIG, buildControlEvent, deriveActivityState, claimControlNotification, formatControlIntercomMessage, formatControlNoticeMessage, shouldEmitOpenToolAttention, } from "../shared/subagent-control.js";
|
|
@@ -49,13 +50,12 @@ import { processTerminalPath, writeProcessTerminalCandidate } from "./process-te
|
|
|
49
50
|
import { persistRunnerStartupFailure } from "./runner-startup-failure.js";
|
|
50
51
|
import { currentPidNamespaceScope } from "./pid-namespace.js";
|
|
51
52
|
import { createSteeringStatus, recordSteeringRequest, steeringStatus, terminalSteeringNoticeState, unconsumedSteerReason, updateSteeringTarget } from "./steering.js";
|
|
52
|
-
import { PROMPT_REDACTED, detectSubagentError, extractTextFromContent, extractToolArgsPreview, formatEmptyTerminalAssistantResponseError, getAgentDir, hasEmptyTerminalAssistantResponse, readStatus } from "../../shared/utils.js";
|
|
53
|
-
import { planBackgroundRunHistory, recordRun } from "../shared/run-history.js";
|
|
53
|
+
import { PROMPT_REDACTED, SUBAGENT_STOPPED_MESSAGE, SUBAGENT_TIMED_OUT_MESSAGE, detectSubagentError, extractTextFromContent, extractToolArgsPreview, formatEmptyTerminalAssistantResponseError, getAgentDir, hasEmptyTerminalAssistantResponse, readStatus } from "../../shared/utils.js";
|
|
54
54
|
import { planAbortRecovery } from "../shared/abort-recovery.js";
|
|
55
55
|
import { createMutatingFailureState, didMutatingToolFail, isMutatingTool, nextLongRunningTrigger, recordMutatingFailure, resetMutatingFailureState, resolveCurrentPath, shouldEscalateMutatingFailures, summarizeRecentMutatingFailures, } from "../shared/long-running-guard.js";
|
|
56
56
|
import { parseSessionTokens } from "../../shared/session-tokens.js";
|
|
57
57
|
import { cleanupWorktrees, createWorktrees, withWorktreeTransaction, WorktreeSetupError, diffWorktrees, findWorktreeTaskCwdConflict, formatWorktreeDiffSummary, formatWorktreeTaskCwdConflict, WORKTREE_AGENT_CWD_PLACEHOLDER, } from "../shared/worktree.js";
|
|
58
|
-
import { findModelInfo, resolveEffectiveThinking } from "../../shared/model-info.js";
|
|
58
|
+
import { findModelInfo, qualifyModelWithProvider, resolveEffectiveThinking } from "../../shared/model-info.js";
|
|
59
59
|
import { assertThinkingWithinCeiling } from "../../shared/thinking-ceiling.js";
|
|
60
60
|
import { resolveLaunchBinding } from "../../shared/launch-contract.js";
|
|
61
61
|
import { writeInitialProgressFile } from "../../shared/settings.js";
|
|
@@ -65,7 +65,7 @@ import { attachContractProjections, isAgentContract } from "../shared/agent-cont
|
|
|
65
65
|
import { waitForImportedAsyncRoot } from "./chain-root-attachment.js";
|
|
66
66
|
import { appendRunnerStepsToStatus, consumeChainAppendRequests, countPendingChainAppendRequests, statusStepDescription } from "./chain-append.js";
|
|
67
67
|
import { asyncStatusChildIdentity } from "../shared/child-identity.js";
|
|
68
|
-
import { initialToolBudgetState, toolBudgetState } from "../shared/tool-budget.js";
|
|
68
|
+
import { initialToolBudgetState, isToolBudgetBlockedMessage, toolBudgetState } from "../shared/tool-budget.js";
|
|
69
69
|
import { toolTimeoutCallKey } from "../shared/tool-timeout.js";
|
|
70
70
|
import { usageBudgetExceededMessage, usageBudgetState } from "../shared/usage-budget.js";
|
|
71
71
|
import { formatParallelHandoffError, formatParallelHandoffReference, parallelHandoffPath, writeParallelHandoffGroup, writeWorktreeSetupHandoff } from "../shared/parallel-handoff.js";
|
|
@@ -467,7 +467,7 @@ export async function runSingleStepInner(step, ctx) {
|
|
|
467
467
|
}
|
|
468
468
|
const stopped = importStopped || imported.stopped === true || ctx.stopSignal?.aborted === true;
|
|
469
469
|
const timedOut = !stopped && (importTimedOut || imported.timedOut === true || ctx.timeoutSignal?.aborted === true || ctx.skipAcceptance?.() === true);
|
|
470
|
-
const message = stopped ? ctx.stopMessage ??
|
|
470
|
+
const message = stopped ? ctx.stopMessage ?? SUBAGENT_STOPPED_MESSAGE : ctx.timeoutMessage ?? SUBAGENT_TIMED_OUT_MESSAGE;
|
|
471
471
|
return omitUndefinedProperties({
|
|
472
472
|
agent: imported.agent,
|
|
473
473
|
output: timedOut || stopped ? message : imported.output,
|
|
@@ -554,6 +554,47 @@ export async function runSingleStepInner(step, ctx) {
|
|
|
554
554
|
}
|
|
555
555
|
}
|
|
556
556
|
transcriptWriter?.writeInitialUserMessage(`${PROMPT_REDACTED}; live Prompt Audit only.`);
|
|
557
|
+
// External CLI and external job runs settle their output the same way; only their runner metadata differs.
|
|
558
|
+
const settleExternalOutput = (external, outputSnapshot, runnerMetadata) => {
|
|
559
|
+
try {
|
|
560
|
+
fs.writeFileSync(ctx.outputFile, external.output, "utf-8");
|
|
561
|
+
}
|
|
562
|
+
catch { /* Observability output is best-effort. */ }
|
|
563
|
+
const resolvedOutput = step.outputPath && external.exitCode === 0
|
|
564
|
+
? resolveSingleOutput(step.outputPath, external.output, outputSnapshot, step.outputClaimPath)
|
|
565
|
+
: { fullOutput: external.output };
|
|
566
|
+
const outputReference = resolvedOutput.savedPath ? formatSavedOutputReference(resolvedOutput.savedPath, resolvedOutput.fullOutput) : undefined;
|
|
567
|
+
const settlementFatalOutputError = isSettlementFatalOutputError(resolvedOutput, step.outputMode);
|
|
568
|
+
const exitCode = settlementFatalOutputError ? 1 : external.exitCode;
|
|
569
|
+
const error = settlementFatalOutputError && resolvedOutput.saveError
|
|
570
|
+
? external.error ? `${external.error}\n${resolvedOutput.saveError}` : resolvedOutput.saveError
|
|
571
|
+
: external.error;
|
|
572
|
+
const finalizedOutput = finalizeSingleOutput(omitUndefinedProperties({
|
|
573
|
+
fullOutput: resolvedOutput.fullOutput,
|
|
574
|
+
outputPath: step.outputPath,
|
|
575
|
+
outputMode: step.outputMode,
|
|
576
|
+
exitCode: exitCode ?? 1,
|
|
577
|
+
savedPath: resolvedOutput.savedPath,
|
|
578
|
+
outputReference,
|
|
579
|
+
saveError: resolvedOutput.saveError,
|
|
580
|
+
}));
|
|
581
|
+
const artifactErrors = artifactPaths && ctx.artifactConfig?.enabled !== false
|
|
582
|
+
? persistStepArtifacts({
|
|
583
|
+
artifactPaths,
|
|
584
|
+
artifactConfig: ctx.artifactConfig,
|
|
585
|
+
output: formatOutputArtifactContent(omitUndefinedProperties({ output: resolvedOutput.fullOutput, error: error, metadataPath: ctx.artifactConfig?.includeMetadata === false ? undefined : artifactPaths.metadataPath })),
|
|
586
|
+
metadata: { runId: ctx.id, parentSessionId: step.parentSessionId, agent: step.agent, task: PROMPT_REDACTED, ...runnerMetadata, exitCode: exitCode, error: error, timestamp: Date.now() },
|
|
587
|
+
})
|
|
588
|
+
: {};
|
|
589
|
+
return {
|
|
590
|
+
output: finalizedOutput.displayOutput,
|
|
591
|
+
exitCode,
|
|
592
|
+
error,
|
|
593
|
+
outputSaveError: [resolvedOutput.saveError, artifactErrors.outputSaveError].filter(Boolean).join("\n") || undefined,
|
|
594
|
+
artifactOutputSaveFailed: artifactErrors.outputSaveError ? true : undefined,
|
|
595
|
+
metadataSaveError: artifactErrors.metadataSaveError,
|
|
596
|
+
};
|
|
597
|
+
};
|
|
557
598
|
if (step.runner?.type === "external-cli") {
|
|
558
599
|
const externalCwd = step.machine?.cwd ?? step.cwd ?? ctx.cwd;
|
|
559
600
|
const externalAbortSignal = combinedAbortSignal([ctx.timeoutSignal, ctx.stopSignal]);
|
|
@@ -561,7 +602,7 @@ export async function runSingleStepInner(step, ctx) {
|
|
|
561
602
|
await ctx.prepareExternalActivity?.(externalCwd, externalAbortSignal);
|
|
562
603
|
if (externalAbortSignal?.aborted) {
|
|
563
604
|
const stopped = ctx.stopSignal?.aborted === true;
|
|
564
|
-
const message = stopped ? ctx.stopMessage ??
|
|
605
|
+
const message = stopped ? ctx.stopMessage ?? SUBAGENT_STOPPED_MESSAGE : ctx.timeoutMessage ?? SUBAGENT_TIMED_OUT_MESSAGE;
|
|
565
606
|
return omitUndefinedProperties({ agent: step.agent, context: step.context, output: message, error: message, exitCode: 1, stopped: stopped || undefined, timedOut: stopped ? undefined : true });
|
|
566
607
|
}
|
|
567
608
|
if (step.machine) {
|
|
@@ -584,7 +625,7 @@ export async function runSingleStepInner(step, ctx) {
|
|
|
584
625
|
else if (raced.kind === "timeout")
|
|
585
626
|
settled = createHerdrExternalAdapter(step.runner.adapter).normalize(evidenceInput, "Placed external run timed out; truthful pane retained for inspection.");
|
|
586
627
|
else
|
|
587
|
-
return { agent: step.agent, context: step.context, output: "Placed external run stopped
|
|
628
|
+
return { agent: step.agent, context: step.context, output: "Placed external run stopped.", outputState: "present", exitCode: 1, stopped: true, runner, execution: { status: "stopped", success: false, exitCode: 1, stopped: true } };
|
|
588
629
|
}
|
|
589
630
|
catch (error) {
|
|
590
631
|
retain = true;
|
|
@@ -599,7 +640,7 @@ export async function runSingleStepInner(step, ctx) {
|
|
|
599
640
|
const outputReference = resolvedOutput.savedPath ? formatSavedOutputReference(resolvedOutput.savedPath, resolvedOutput.fullOutput) : undefined;
|
|
600
641
|
const finalizedOutput = finalizeSingleOutput(omitUndefinedProperties({ fullOutput: resolvedOutput.fullOutput, outputPath: step.outputPath, outputMode: step.outputMode, exitCode: 1, preserveSavedOutput: true, savedPath: resolvedOutput.savedPath, outputReference, saveError: resolvedOutput.saveError }));
|
|
601
642
|
const artifactErrors = artifactPaths && ctx.artifactConfig?.enabled !== false ? persistStepArtifacts({ artifactPaths, artifactConfig: ctx.artifactConfig, output: formatOutputArtifactContent(omitUndefinedProperties({ output: resolvedOutput.fullOutput, metadataPath: ctx.artifactConfig?.includeMetadata === false ? undefined : artifactPaths.metadataPath })), metadata: { runId: ctx.id, parentSessionId: step.parentSessionId, agent: step.agent, task: PROMPT_REDACTED, runner, placement: session.owner.identity, settlement: settled.settlement, outcome: settled.outcome, timestamp: Date.now() } }) : {};
|
|
602
|
-
return omitUndefinedProperties({ agent: step.agent, ...(childSessionName ? { sessionName: childSessionName } : {}), context: step.context, output: finalizedOutput.displayOutput, outputState: output.trim() ? "present" : "absent", exitCode: 1, error: resolvedOutput.
|
|
643
|
+
return omitUndefinedProperties({ agent: step.agent, ...(childSessionName ? { sessionName: childSessionName } : {}), context: step.context, output: finalizedOutput.displayOutput, outputState: output.trim() ? "present" : "absent", exitCode: 1, error: isSettlementFatalOutputError(resolvedOutput, step.outputMode) ? resolvedOutput.saveError : undefined, timedOut, stopped, artifactPaths, outputSaveError: [resolvedOutput.saveError, artifactErrors.outputSaveError].filter(Boolean).join("\n") || undefined, metadataSaveError: artifactErrors.metadataSaveError, runner, execution: { status: "partial", success: false, exitCode: 1 } });
|
|
603
644
|
}
|
|
604
645
|
catch (error) {
|
|
605
646
|
// Any post-allocation uncertainty retains the pane; only explicit stop
|
|
@@ -655,50 +696,22 @@ export async function runSingleStepInner(step, ctx) {
|
|
|
655
696
|
const ran = await runExternalCli(preparedExternal.input);
|
|
656
697
|
const externalProcess = preparedExternal.decorateProcess(ran.externalProcess);
|
|
657
698
|
const external = step.machine ? decorateHerdrMachineResult(ran, step.machine, step.runner.adapter) : ran;
|
|
658
|
-
|
|
659
|
-
fs.writeFileSync(ctx.outputFile, external.output, "utf-8");
|
|
660
|
-
}
|
|
661
|
-
catch { /* Observability output is best-effort. */ }
|
|
662
|
-
const resolvedOutput = step.outputPath && external.exitCode === 0
|
|
663
|
-
? resolveSingleOutput(step.outputPath, external.output, outputSnapshot, step.outputClaimPath)
|
|
664
|
-
: { fullOutput: external.output };
|
|
665
|
-
const outputReference = resolvedOutput.savedPath ? formatSavedOutputReference(resolvedOutput.savedPath, resolvedOutput.fullOutput) : undefined;
|
|
666
|
-
const exitCode = resolvedOutput.fatalError ? 1 : external.exitCode;
|
|
667
|
-
const error = resolvedOutput.fatalError && resolvedOutput.saveError
|
|
668
|
-
? external.error ? `${external.error}\n${resolvedOutput.saveError}` : resolvedOutput.saveError
|
|
669
|
-
: external.error;
|
|
670
|
-
const finalizedOutput = finalizeSingleOutput(omitUndefinedProperties({
|
|
671
|
-
fullOutput: resolvedOutput.fullOutput,
|
|
672
|
-
outputPath: step.outputPath,
|
|
673
|
-
outputMode: step.outputMode,
|
|
674
|
-
exitCode: exitCode ?? 1,
|
|
675
|
-
savedPath: resolvedOutput.savedPath,
|
|
676
|
-
outputReference,
|
|
677
|
-
saveError: resolvedOutput.saveError,
|
|
678
|
-
}));
|
|
679
|
-
const artifactErrors = artifactPaths && ctx.artifactConfig?.enabled !== false
|
|
680
|
-
? persistStepArtifacts({
|
|
681
|
-
artifactPaths,
|
|
682
|
-
artifactConfig: ctx.artifactConfig,
|
|
683
|
-
output: formatOutputArtifactContent(omitUndefinedProperties({ output: resolvedOutput.fullOutput, error: external.error, metadataPath: ctx.artifactConfig?.includeMetadata === false ? undefined : artifactPaths.metadataPath })),
|
|
684
|
-
metadata: { runId: ctx.id, parentSessionId: step.parentSessionId, agent: step.agent, task: PROMPT_REDACTED, runner, externalProcess: externalProcess, exitCode: external.exitCode, error: external.error, timestamp: Date.now() },
|
|
685
|
-
})
|
|
686
|
-
: {};
|
|
699
|
+
const settled = settleExternalOutput(external, outputSnapshot, { runner, externalProcess });
|
|
687
700
|
return omitUndefinedProperties({
|
|
688
701
|
agent: step.agent,
|
|
689
702
|
...(childSessionName ? { sessionName: childSessionName } : {}),
|
|
690
703
|
context: step.context,
|
|
691
|
-
output:
|
|
704
|
+
output: settled.output,
|
|
692
705
|
outputState: external.output.trim() ? "present" : "absent",
|
|
693
|
-
exitCode,
|
|
694
|
-
error,
|
|
706
|
+
exitCode: settled.exitCode,
|
|
707
|
+
error: settled.error,
|
|
695
708
|
timedOut: external.timedOut,
|
|
696
709
|
stopped: external.stopped,
|
|
697
710
|
processSignal: external.processSignal,
|
|
698
711
|
artifactPaths,
|
|
699
|
-
outputSaveError:
|
|
700
|
-
artifactOutputSaveFailed:
|
|
701
|
-
metadataSaveError:
|
|
712
|
+
outputSaveError: settled.outputSaveError,
|
|
713
|
+
artifactOutputSaveFailed: settled.artifactOutputSaveFailed,
|
|
714
|
+
metadataSaveError: settled.metadataSaveError,
|
|
702
715
|
runner,
|
|
703
716
|
externalProcess: externalProcess,
|
|
704
717
|
});
|
|
@@ -728,49 +741,21 @@ export async function runSingleStepInner(step, ctx) {
|
|
|
728
741
|
onExternalJob: ctx.onExternalJob,
|
|
729
742
|
followUp: step.externalJobFollowUp,
|
|
730
743
|
}));
|
|
731
|
-
|
|
732
|
-
fs.writeFileSync(ctx.outputFile, external.output, "utf-8");
|
|
733
|
-
}
|
|
734
|
-
catch { /* Observability output is best-effort. */ }
|
|
735
|
-
const resolvedOutput = step.outputPath && external.exitCode === 0
|
|
736
|
-
? resolveSingleOutput(step.outputPath, external.output, outputSnapshot, step.outputClaimPath)
|
|
737
|
-
: { fullOutput: external.output };
|
|
738
|
-
const outputReference = resolvedOutput.savedPath ? formatSavedOutputReference(resolvedOutput.savedPath, resolvedOutput.fullOutput) : undefined;
|
|
739
|
-
const exitCode = resolvedOutput.fatalError ? 1 : external.exitCode;
|
|
740
|
-
const error = resolvedOutput.fatalError && resolvedOutput.saveError
|
|
741
|
-
? external.error ? `${external.error}\n${resolvedOutput.saveError}` : resolvedOutput.saveError
|
|
742
|
-
: external.error;
|
|
743
|
-
const finalizedOutput = finalizeSingleOutput(omitUndefinedProperties({
|
|
744
|
-
fullOutput: resolvedOutput.fullOutput,
|
|
745
|
-
outputPath: step.outputPath,
|
|
746
|
-
outputMode: step.outputMode,
|
|
747
|
-
exitCode: exitCode ?? 1,
|
|
748
|
-
savedPath: resolvedOutput.savedPath,
|
|
749
|
-
outputReference,
|
|
750
|
-
saveError: resolvedOutput.saveError,
|
|
751
|
-
}));
|
|
752
|
-
const artifactErrors = artifactPaths && ctx.artifactConfig?.enabled !== false
|
|
753
|
-
? persistStepArtifacts({
|
|
754
|
-
artifactPaths,
|
|
755
|
-
artifactConfig: ctx.artifactConfig,
|
|
756
|
-
output: formatOutputArtifactContent(omitUndefinedProperties({ output: resolvedOutput.fullOutput, error: external.error, metadataPath: ctx.artifactConfig?.includeMetadata === false ? undefined : artifactPaths.metadataPath })),
|
|
757
|
-
metadata: { runId: ctx.id, parentSessionId: step.parentSessionId, agent: step.agent, task: PROMPT_REDACTED, runner, externalJob: external.externalJob, exitCode: external.exitCode, error: external.error, timestamp: Date.now() },
|
|
758
|
-
})
|
|
759
|
-
: {};
|
|
744
|
+
const settled = settleExternalOutput(external, outputSnapshot, { runner, externalJob: external.externalJob });
|
|
760
745
|
return omitUndefinedProperties({
|
|
761
746
|
agent: step.agent,
|
|
762
747
|
...(childSessionName ? { sessionName: childSessionName } : {}),
|
|
763
748
|
context: step.context,
|
|
764
|
-
output:
|
|
749
|
+
output: settled.output,
|
|
765
750
|
outputState: external.output.trim() ? "present" : "absent",
|
|
766
|
-
exitCode,
|
|
767
|
-
error,
|
|
751
|
+
exitCode: settled.exitCode,
|
|
752
|
+
error: settled.error,
|
|
768
753
|
timedOut: external.timedOut,
|
|
769
754
|
stopped: external.stopped,
|
|
770
755
|
artifactPaths,
|
|
771
|
-
outputSaveError:
|
|
772
|
-
artifactOutputSaveFailed:
|
|
773
|
-
metadataSaveError:
|
|
756
|
+
outputSaveError: settled.outputSaveError,
|
|
757
|
+
artifactOutputSaveFailed: settled.artifactOutputSaveFailed,
|
|
758
|
+
metadataSaveError: settled.metadataSaveError,
|
|
774
759
|
runner,
|
|
775
760
|
externalJob: external.externalJob,
|
|
776
761
|
});
|
|
@@ -1020,7 +1005,11 @@ export async function runSingleStepInner(step, ctx) {
|
|
|
1020
1005
|
const mutationEvidence = run.nativeMachine ? { source: "tracked-files", trackedOnly: true, changedFiles: [], attemptedMutation: remoteGitChanged === true, ...(remoteGitChanged === undefined ? { unavailable: "Remote Git before/after evidence was incomplete." } : {}) } : collectTrackedMutationEvidence(mutationSnapshot, step.cwd ?? ctx.cwd);
|
|
1021
1006
|
finalMutationEvidence = mutationEvidence;
|
|
1022
1007
|
const mutationAttemptObserved = run.observedMutationAttempt === true || mutationEvidence.attemptedMutation === true;
|
|
1023
|
-
|
|
1008
|
+
// Validated structured output is persistable file content even when the final text is only
|
|
1009
|
+
// an acceptance-report fence; otherwise the required-output precheck forces exitCode 1 before
|
|
1010
|
+
// resolveSingleOutput can publish the canonical JSON into the bound file-only path.
|
|
1011
|
+
const finalOutputHasPersistableFileContent = run.exitCode === 0 && !run.error && !emptyOutputError
|
|
1012
|
+
&& (Boolean(stripAcceptanceReport(run.finalOutput).trim()) || validatedStructuredOutput);
|
|
1024
1013
|
const requiredOutput = step.outputMode === "file-only" && step.outputPath
|
|
1025
1014
|
? { kind: "file-only", path: step.outputPath, missing: !fs.existsSync(step.outputPath) && !finalOutputHasPersistableFileContent }
|
|
1026
1015
|
: effectiveStructuredOutput
|
|
@@ -1104,7 +1093,7 @@ export async function runSingleStepInner(step, ctx) {
|
|
|
1104
1093
|
const resolvedOutput = step.outputPath && finalResult?.exitCode === 0
|
|
1105
1094
|
? resolveSingleOutput(step.outputPath, structuredText ?? replyOutput, finalOutputSnapshot, step.outputClaimPath)
|
|
1106
1095
|
: { fullOutput: replyOutput };
|
|
1107
|
-
if (resolvedOutput.
|
|
1096
|
+
if (isSettlementFatalOutputError(resolvedOutput, step.outputMode)) {
|
|
1108
1097
|
if (finalResult) {
|
|
1109
1098
|
finalResult.exitCode = 1;
|
|
1110
1099
|
finalResult.error = finalResult.error ? `${finalResult.error}\n${resolvedOutput.saveError}` : resolvedOutput.saveError;
|
|
@@ -1114,7 +1103,7 @@ export async function runSingleStepInner(step, ctx) {
|
|
|
1114
1103
|
const outputReference = resolvedOutput.savedPath ? formatSavedOutputReference(resolvedOutput.savedPath, output) : undefined;
|
|
1115
1104
|
let outputForSummary = output;
|
|
1116
1105
|
if (finalResult?.stopped && !outputForSummary.trim()) {
|
|
1117
|
-
outputForSummary = ctx.stopMessage ??
|
|
1106
|
+
outputForSummary = ctx.stopMessage ?? SUBAGENT_STOPPED_MESSAGE;
|
|
1118
1107
|
}
|
|
1119
1108
|
// Unfinished streamed text never stands in for the child's completed reply.
|
|
1120
1109
|
const outputForAcceptance = finalResult?.outputPartial ? "" : rawOutput;
|
|
@@ -1167,7 +1156,7 @@ export async function runSingleStepInner(step, ctx) {
|
|
|
1167
1156
|
cwd: step.cwd ?? ctx.cwd,
|
|
1168
1157
|
stagedIndexBaseline,
|
|
1169
1158
|
signal: combinedAbortSignal([ctx.timeoutSignal, ctx.stopSignal]),
|
|
1170
|
-
abortMessage: ctx.stopSignal?.aborted ? ctx.stopMessage ??
|
|
1159
|
+
abortMessage: ctx.stopSignal?.aborted ? ctx.stopMessage ?? SUBAGENT_STOPPED_MESSAGE : ctx.timeoutMessage ?? SUBAGENT_TIMED_OUT_MESSAGE,
|
|
1171
1160
|
reportOptional: isAgentContract(step.agentContract),
|
|
1172
1161
|
artifactsDir: ctx.artifactsDir,
|
|
1173
1162
|
runId: ctx.id,
|
|
@@ -1194,9 +1183,9 @@ export async function runSingleStepInner(step, ctx) {
|
|
|
1194
1183
|
}
|
|
1195
1184
|
const intercomDetachReceipt = finalResult?.finalOutput === INTERCOM_DETACH_RECEIPT;
|
|
1196
1185
|
const baseFinalError = stoppedAfterAcceptance
|
|
1197
|
-
? ctx.stopMessage ??
|
|
1186
|
+
? ctx.stopMessage ?? SUBAGENT_STOPPED_MESSAGE
|
|
1198
1187
|
: timedOutAfterAcceptance
|
|
1199
|
-
? finalResult?.error ?? ctx.timeoutMessage ??
|
|
1188
|
+
? finalResult?.error ?? ctx.timeoutMessage ?? SUBAGENT_TIMED_OUT_MESSAGE
|
|
1200
1189
|
: acceptanceCanFailRun
|
|
1201
1190
|
? (finalResult?.error ? `${finalResult.error}\n${acceptanceFailure}` : acceptanceFailure)
|
|
1202
1191
|
: finalResult?.error ?? (intercomDetachReceipt ? INTERCOM_DETACH_RECEIPT : undefined);
|
|
@@ -1343,8 +1332,8 @@ function markParallelGroupSetupFailure(input) {
|
|
|
1343
1332
|
const paused = !stopped && input.statusPayload.state === "paused";
|
|
1344
1333
|
const timedOut = !stopped && !paused && input.statusPayload.timedOut === true;
|
|
1345
1334
|
statusStep.status = stopped ? "stopped" : paused ? "paused" : "failed";
|
|
1346
|
-
// Mirror the run-level timeout onto the step so
|
|
1347
|
-
//
|
|
1335
|
+
// Mirror the run-level timeout onto the step so status readers see
|
|
1336
|
+
// timed_out rather than a bare failure — the
|
|
1348
1337
|
// StepResult below already carries it, the status step must too.
|
|
1349
1338
|
if (timedOut)
|
|
1350
1339
|
statusStep.timedOut = true;
|
|
@@ -1518,11 +1507,6 @@ export async function runSubagent(config, childSessions) {
|
|
|
1518
1507
|
let previousOutput = "";
|
|
1519
1508
|
const outputs = {};
|
|
1520
1509
|
const results = [];
|
|
1521
|
-
// Flat indices of steps a child session was actually dispatched for — the
|
|
1522
|
-
// ground truth for run-history: stopRunner/timeoutRunner/fail-fast/budget
|
|
1523
|
-
// skips relabel never-launched steps to terminal statuses, so status alone
|
|
1524
|
-
// cannot distinguish them from steps that really ran.
|
|
1525
|
-
const launchedFlatIndices = new Set();
|
|
1526
1510
|
const overallStartTime = Date.now();
|
|
1527
1511
|
const shareEnabled = config.share === true;
|
|
1528
1512
|
const asyncDir = config.asyncDir;
|
|
@@ -1549,7 +1533,7 @@ export async function runSubagent(config, childSessions) {
|
|
|
1549
1533
|
let stopped = false;
|
|
1550
1534
|
let usageBudgetExceeded = false;
|
|
1551
1535
|
const timeoutMessage = config.timeoutMs !== undefined ? `Subagent timed out after ${config.timeoutMs}ms.` : undefined;
|
|
1552
|
-
const stopMessage =
|
|
1536
|
+
const stopMessage = SUBAGENT_STOPPED_MESSAGE;
|
|
1553
1537
|
const timeoutAbortController = new AbortController();
|
|
1554
1538
|
const stopAbortController = new AbortController();
|
|
1555
1539
|
const setupInterruptController = new AbortController();
|
|
@@ -2211,8 +2195,8 @@ export async function runSubagent(config, childSessions) {
|
|
|
2211
2195
|
agent,
|
|
2212
2196
|
sessionName,
|
|
2213
2197
|
context,
|
|
2214
|
-
output: timeoutMessage ??
|
|
2215
|
-
error: timeoutMessage ??
|
|
2198
|
+
output: timeoutMessage ?? SUBAGENT_TIMED_OUT_MESSAGE,
|
|
2199
|
+
error: timeoutMessage ?? SUBAGENT_TIMED_OUT_MESSAGE,
|
|
2216
2200
|
exitCode: 1,
|
|
2217
2201
|
timedOut: true,
|
|
2218
2202
|
});
|
|
@@ -2251,6 +2235,7 @@ export async function runSubagent(config, childSessions) {
|
|
|
2251
2235
|
});
|
|
2252
2236
|
mutatingFailureStates.push(...Array.from({ length: added.addedFlatSteps }, () => createMutatingFailureState()));
|
|
2253
2237
|
pendingToolResults.push(...Array.from({ length: added.addedFlatSteps }, () => undefined));
|
|
2238
|
+
pendingToolResultsByCallId.push(...Array.from({ length: added.addedFlatSteps }, () => new Map()));
|
|
2254
2239
|
if (config.childIntercomTargets) {
|
|
2255
2240
|
config.childIntercomTargets = statusPayload.steps.map((statusStep, index) => resolveSubagentIntercomTarget(id, statusStep.agent, index));
|
|
2256
2241
|
}
|
|
@@ -2347,6 +2332,9 @@ export async function runSubagent(config, childSessions) {
|
|
|
2347
2332
|
const activeLongRunningSteps = new Set();
|
|
2348
2333
|
const mutatingFailureStates = initialStatusSteps.map(() => createMutatingFailureState());
|
|
2349
2334
|
const pendingToolResults = initialStatusSteps.map(() => undefined);
|
|
2335
|
+
// Pi's parallel tool execution emits every tool_execution_start before the first result message, so each
|
|
2336
|
+
// step matches results to calls by toolCallId; pendingToolResults keeps the last-started call for events without one.
|
|
2337
|
+
const pendingToolResultsByCallId = initialStatusSteps.map(() => new Map());
|
|
2350
2338
|
const activeToolCalls = initialStatusSteps.map(() => new Map());
|
|
2351
2339
|
const activeToolKeysByName = initialStatusSteps.map(() => new Map());
|
|
2352
2340
|
const activeToolSequences = initialStatusSteps.map(() => 0);
|
|
@@ -2698,11 +2686,72 @@ export async function runSubagent(config, childSessions) {
|
|
|
2698
2686
|
if (!step)
|
|
2699
2687
|
return;
|
|
2700
2688
|
setOptionalProperty(step, "model", model);
|
|
2689
|
+
setOptionalProperty(step, "launchModel", undefined);
|
|
2701
2690
|
setOptionalProperty(step, "thinking", thinking);
|
|
2702
2691
|
setOptionalProperty(step, "contextLimit", contextLimit);
|
|
2703
2692
|
statusPayload.lastUpdate = now;
|
|
2704
2693
|
writeStatusPayload();
|
|
2705
2694
|
};
|
|
2695
|
+
// Records a finished child's result on its status step; the sequential and both parallel paths share it.
|
|
2696
|
+
const recordStepResult = (fi, singleResult, startedAt, endedAt, recordLaunchContractDigest = false) => {
|
|
2697
|
+
const step = requiredStatusStep(statusPayload, fi);
|
|
2698
|
+
const childStopped = singleResult.stopped === true;
|
|
2699
|
+
const childInterrupted = singleResult.interrupted === true;
|
|
2700
|
+
step.status = stopped || childStopped ? "stopped" : timedOut ? "failed" : childInterrupted ? "paused" : singleResult.execution?.status === "partial" ? "partial" : singleResult.exitCode === 0 ? "complete" : "failed";
|
|
2701
|
+
step.endedAt = endedAt;
|
|
2702
|
+
step.durationMs = endedAt - startedAt;
|
|
2703
|
+
step.exitCode = stopped || childStopped ? 1 : timedOut ? 1 : childInterrupted ? 0 : singleResult.exitCode;
|
|
2704
|
+
setOptionalProperty(step, "timedOut", timedOut || singleResult.timedOut ? true : undefined);
|
|
2705
|
+
setOptionalProperty(step, "stopped", stopped || childStopped ? true : undefined);
|
|
2706
|
+
setOptionalProperty(step, "toolBudget", singleResult.toolBudget);
|
|
2707
|
+
setOptionalProperty(step, "toolBudgetBlocked", singleResult.toolBudgetBlocked);
|
|
2708
|
+
if (singleResult.toolBudget)
|
|
2709
|
+
statusPayload.toolBudget = singleResult.toolBudget;
|
|
2710
|
+
if (singleResult.toolBudgetBlocked)
|
|
2711
|
+
statusPayload.toolBudgetBlocked = true;
|
|
2712
|
+
setOptionalProperty(step, "sessionName", singleResult.sessionName);
|
|
2713
|
+
// Keep the model the child was observed running on; a host extension can switch it
|
|
2714
|
+
// after launch, and singleResult.model only names the launch candidate.
|
|
2715
|
+
setOptionalProperty(step, "model", step.model ?? singleResult.model);
|
|
2716
|
+
setOptionalProperty(step, "thinking", resolveEffectiveThinking(singleResult.model, step.thinking));
|
|
2717
|
+
setOptionalProperty(step, "requestedModel", singleResult.requestedModel);
|
|
2718
|
+
setOptionalProperty(step, "contextOverflow", singleResult.contextOverflow);
|
|
2719
|
+
setOptionalProperty(step, "totalCost", singleResult.totalCost);
|
|
2720
|
+
setOptionalProperty(step, "error", stopped || childStopped ? stopMessage : timedOut ? (timeoutMessage ?? SUBAGENT_TIMED_OUT_MESSAGE) : singleResult.error);
|
|
2721
|
+
setOptionalProperty(step, "transcriptPath", singleResult.transcriptPath ?? step.transcriptPath);
|
|
2722
|
+
setOptionalProperty(step, "transcriptError", singleResult.transcriptError);
|
|
2723
|
+
setOptionalProperty(step, "agentContract", singleResult.agentContract);
|
|
2724
|
+
if (recordLaunchContractDigest)
|
|
2725
|
+
setOptionalProperty(step, "launchContractDigest", singleResult.launchContractDigest);
|
|
2726
|
+
setOptionalProperty(step, "launchResolvedExtensions", singleResult.launchResolvedExtensions);
|
|
2727
|
+
setOptionalProperty(step, "runtimeAcknowledgedExtensions", singleResult.runtimeAcknowledgedExtensions);
|
|
2728
|
+
setOptionalProperty(step, "effects", singleResult.effects);
|
|
2729
|
+
setOptionalProperty(step, "execution", singleResult.execution);
|
|
2730
|
+
setOptionalProperty(step, "review", singleResult.review);
|
|
2731
|
+
setOptionalProperty(step, "structuredOutput", singleResult.structuredOutput);
|
|
2732
|
+
setOptionalProperty(step, "structuredOutputPath", singleResult.structuredOutputPath);
|
|
2733
|
+
setOptionalProperty(step, "structuredOutputSchemaPath", singleResult.structuredOutputSchemaPath);
|
|
2734
|
+
setOptionalProperty(step, "acceptance", singleResult.acceptance);
|
|
2735
|
+
setOptionalProperty(step, "timeoutRecovery", singleResult.timeoutRecovery);
|
|
2736
|
+
setOptionalProperty(step, "watchdog", singleResult.watchdog);
|
|
2737
|
+
setOptionalProperty(step, "capabilityCeiling", singleResult.capabilityCeiling);
|
|
2738
|
+
setOptionalProperty(step, "capabilityAudit", singleResult.capabilityAudit);
|
|
2739
|
+
if (singleResult.capabilityCeiling)
|
|
2740
|
+
statusPayload.capabilityCeiling = singleResult.capabilityCeiling;
|
|
2741
|
+
if (singleResult.capabilityAudit)
|
|
2742
|
+
statusPayload.capabilityAudit = singleResult.capabilityAudit;
|
|
2743
|
+
};
|
|
2744
|
+
// Adds a parallel child's cost to the in-flight usage ledger.
|
|
2745
|
+
const addParallelUsageCost = (totalCost) => {
|
|
2746
|
+
if (!totalCost)
|
|
2747
|
+
return;
|
|
2748
|
+
pendingParallelUsageCost = {
|
|
2749
|
+
inputTokens: pendingParallelUsageCost.inputTokens + totalCost.inputTokens,
|
|
2750
|
+
outputTokens: pendingParallelUsageCost.outputTokens + totalCost.outputTokens,
|
|
2751
|
+
costUsd: pendingParallelUsageCost.costUsd + totalCost.costUsd,
|
|
2752
|
+
};
|
|
2753
|
+
refreshUsageBudget();
|
|
2754
|
+
};
|
|
2706
2755
|
const updateStepFromChildEvent = (flatIndex, event) => {
|
|
2707
2756
|
const step = statusPayload.steps[flatIndex];
|
|
2708
2757
|
if (!step)
|
|
@@ -2745,11 +2794,15 @@ export async function runSubagent(config, childSessions) {
|
|
|
2745
2794
|
step.toolCount = (step.toolCount ?? 0) + 1;
|
|
2746
2795
|
const configuredToolBudget = flatSteps[flatIndex]?.toolBudget;
|
|
2747
2796
|
if (configuredToolBudget) {
|
|
2748
|
-
step.toolBudget = toolBudgetState(configuredToolBudget, step.toolCount);
|
|
2797
|
+
step.toolBudget = toolBudgetState(configuredToolBudget, step.toolCount, step.toolBudget?.blockedTool);
|
|
2749
2798
|
statusPayload.toolBudget = step.toolBudget;
|
|
2750
2799
|
}
|
|
2751
2800
|
recordActiveToolCall(flatIndex, { toolCallId: event.toolCallId, toolName: event.toolName }, { argsPreview, currentPath, blocksSupervisor, now });
|
|
2752
|
-
|
|
2801
|
+
const pending = omitUndefinedProperties({ tool: event.toolName, path: currentPath, mutates, startedAt: now });
|
|
2802
|
+
pendingToolResults[flatIndex] = pending;
|
|
2803
|
+
const startedCallId = event.toolCallId;
|
|
2804
|
+
if (typeof startedCallId === "string" && startedCallId)
|
|
2805
|
+
pendingToolResultsByCallId[flatIndex].set(startedCallId, pending);
|
|
2753
2806
|
statusPayload.toolCount = (statusPayload.toolCount ?? 0) + 1;
|
|
2754
2807
|
syncTopLevelCurrentTool();
|
|
2755
2808
|
if (controlConfig.enabled && blocksSupervisor && step.activityState !== "needs_attention") {
|
|
@@ -2794,18 +2847,25 @@ export async function runSubagent(config, childSessions) {
|
|
|
2794
2847
|
}
|
|
2795
2848
|
syncTopLevelCurrentTool();
|
|
2796
2849
|
}
|
|
2797
|
-
else if (event.type === "
|
|
2798
|
-
|
|
2799
|
-
|
|
2850
|
+
else if (event.type === "message_end" && event.message?.role === "toolResult") {
|
|
2851
|
+
// Pi delivers every tool result, including a blocked call, as a toolResult message after tool_execution_end.
|
|
2852
|
+
const resultCallId = event.message.toolCallId;
|
|
2853
|
+
const byCallId = pendingToolResultsByCallId[flatIndex];
|
|
2854
|
+
const keyedSnapshot = typeof resultCallId === "string" ? byCallId.get(resultCallId) : undefined;
|
|
2855
|
+
if (keyedSnapshot)
|
|
2856
|
+
byCallId.delete(resultCallId);
|
|
2857
|
+
const toolSnapshot = keyedSnapshot ?? pendingToolResults[flatIndex];
|
|
2858
|
+
if (!keyedSnapshot || pendingToolResults[flatIndex] === keyedSnapshot)
|
|
2859
|
+
pendingToolResults[flatIndex] = undefined;
|
|
2800
2860
|
const resultText = extractTextFromContent(event.message.content);
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2861
|
+
const resultToolName = event.message.toolName;
|
|
2862
|
+
const blockedTool = (typeof resultToolName === "string" && resultToolName.length > 0 ? resultToolName : undefined) ?? toolSnapshot?.tool;
|
|
2863
|
+
const configuredToolBudget = flatSteps[flatIndex]?.toolBudget;
|
|
2864
|
+
if (configuredToolBudget && isToolBudgetBlockedMessage(configuredToolBudget, resultText, blockedTool)) {
|
|
2865
|
+
step.toolBudget = toolBudgetState(configuredToolBudget, step.toolCount ?? 0, blockedTool);
|
|
2866
|
+
step.toolBudgetBlocked = true;
|
|
2867
|
+
statusPayload.toolBudget = step.toolBudget;
|
|
2868
|
+
statusPayload.toolBudgetBlocked = true;
|
|
2809
2869
|
}
|
|
2810
2870
|
appendRecentStepOutput(step, resultText.split("\n").slice(-10));
|
|
2811
2871
|
if (toolSnapshot?.mutates && didMutatingToolFail(resultText)) {
|
|
@@ -2847,6 +2907,17 @@ export async function runSubagent(config, childSessions) {
|
|
|
2847
2907
|
else if (event.type === "message_end" && event.message?.role === "assistant") {
|
|
2848
2908
|
appendRecentStepOutput(step, stripAcceptanceReport(extractTextFromContent(event.message.content)).split("\n").slice(-10));
|
|
2849
2909
|
step.turnCount = (step.turnCount ?? 0) + 1;
|
|
2910
|
+
// The launch model is only a candidate: a host extension (e.g. a model
|
|
2911
|
+
// router) can switch the child's model on its first input, so report the
|
|
2912
|
+
// model each assistant message actually ran on. Mirrors the foreground
|
|
2913
|
+
// path's `progress.model = observedModel`.
|
|
2914
|
+
if (event.message.model) {
|
|
2915
|
+
const observedModel = qualifyModelWithProvider(event.message.model, event.message.provider, flatSteps[flatIndex]?.modelVerificationRegistry) ?? event.message.model;
|
|
2916
|
+
if (observedModel !== step.model) {
|
|
2917
|
+
step.launchModel ??= step.model;
|
|
2918
|
+
step.model = observedModel;
|
|
2919
|
+
}
|
|
2920
|
+
}
|
|
2850
2921
|
const usage = event.message.usage;
|
|
2851
2922
|
if (config.usageBudget) {
|
|
2852
2923
|
const known = (value) => typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
@@ -3099,7 +3170,7 @@ export async function runSubagent(config, childSessions) {
|
|
|
3099
3170
|
return;
|
|
3100
3171
|
timedOut = true;
|
|
3101
3172
|
const now = Date.now();
|
|
3102
|
-
const message = timeoutMessage ??
|
|
3173
|
+
const message = timeoutMessage ?? SUBAGENT_TIMED_OUT_MESSAGE;
|
|
3103
3174
|
statusPayload.timedOut = true;
|
|
3104
3175
|
statusPayload.error = message;
|
|
3105
3176
|
currentActivityState = undefined;
|
|
@@ -3293,7 +3364,7 @@ export async function runSubagent(config, childSessions) {
|
|
|
3293
3364
|
}),
|
|
3294
3365
|
cwd,
|
|
3295
3366
|
signal: combinedAbortSignal([timeoutAbortController.signal, stopAbortController.signal]),
|
|
3296
|
-
abortMessage: stopAbortController.signal.aborted ? stopMessage : timeoutMessage ??
|
|
3367
|
+
abortMessage: stopAbortController.signal.aborted ? stopMessage : timeoutMessage ?? SUBAGENT_TIMED_OUT_MESSAGE,
|
|
3297
3368
|
reportOptional: isAgentContract(step.agentContract),
|
|
3298
3369
|
}))
|
|
3299
3370
|
: undefined;
|
|
@@ -3304,7 +3375,7 @@ export async function runSubagent(config, childSessions) {
|
|
|
3304
3375
|
placeholder.acceptance = effectiveGroupAcceptance;
|
|
3305
3376
|
const groupAcceptanceFailure = effectiveGroupAcceptance && (!isAgentContract(step.agentContract) || step.gateOn === "acceptance") ? acceptanceFailureMessage(effectiveGroupAcceptance) : undefined;
|
|
3306
3377
|
if (groupTimedOut || groupStopped || groupAcceptanceFailure) {
|
|
3307
|
-
const errorMessage = groupStopped ? stopMessage : groupTimedOut ? timeoutMessage ??
|
|
3378
|
+
const errorMessage = groupStopped ? stopMessage : groupTimedOut ? timeoutMessage ?? SUBAGENT_TIMED_OUT_MESSAGE : groupAcceptanceFailure;
|
|
3308
3379
|
statusPayload.state = groupStopped ? "stopped" : "failed";
|
|
3309
3380
|
statusPayload.error = errorMessage;
|
|
3310
3381
|
setOptionalProperty(statusPayload, "stopped", groupStopped ? true : statusPayload.stopped);
|
|
@@ -3352,7 +3423,6 @@ export async function runSubagent(config, childSessions) {
|
|
|
3352
3423
|
dynamic: step.parallel.acceptanceInput === undefined,
|
|
3353
3424
|
agentContract: step.parallel.agentContract ?? step.agentContract,
|
|
3354
3425
|
})),
|
|
3355
|
-
systemPrompt: step.parallel.namespaceOutputPath ? injectOutputPathSystemPrompt(step.parallel.systemPrompt ?? "", outputPath, step.parallel) : step.parallel.systemPrompt,
|
|
3356
3426
|
outputPath,
|
|
3357
3427
|
label: task.label ?? step.parallel.label,
|
|
3358
3428
|
...(step.sessionFiles?.[itemIndex] ? { sessionFile: step.sessionFiles[itemIndex] } : {}),
|
|
@@ -3397,6 +3467,7 @@ export async function runSubagent(config, childSessions) {
|
|
|
3397
3467
|
}
|
|
3398
3468
|
mutatingFailureStates.splice(groupStartFlatIndex, 1, ...dynamicStatusSteps.map(() => createMutatingFailureState()));
|
|
3399
3469
|
pendingToolResults.splice(groupStartFlatIndex, 1, ...dynamicStatusSteps.map(() => undefined));
|
|
3470
|
+
pendingToolResultsByCallId.splice(groupStartFlatIndex, 1, ...dynamicStatusSteps.map(() => new Map()));
|
|
3400
3471
|
const materializedDelta = dynamicStatusSteps.length - 1;
|
|
3401
3472
|
for (const group of statusPayload.parallelGroups) {
|
|
3402
3473
|
if (group.stepIndex === stepIndex) {
|
|
@@ -3477,7 +3548,6 @@ export async function runSubagent(config, childSessions) {
|
|
|
3477
3548
|
return omitUndefinedProperties({ agent: task.agent, ...(task.sessionName ? { sessionName: task.sessionName } : {}), context: task.context, output: "(skipped — fail-fast)", exitCode: -1, skipped: true });
|
|
3478
3549
|
}
|
|
3479
3550
|
const taskStartTime = Date.now();
|
|
3480
|
-
launchedFlatIndices.add(fi);
|
|
3481
3551
|
statusPayload.currentStep = fi;
|
|
3482
3552
|
requiredStatusStep(statusPayload, fi).status = "running";
|
|
3483
3553
|
delete requiredStatusStep(statusPayload, fi).error;
|
|
@@ -3531,54 +3601,8 @@ export async function runSubagent(config, childSessions) {
|
|
|
3531
3601
|
const taskEndTime = Date.now();
|
|
3532
3602
|
const childInterrupted = singleResult.interrupted === true;
|
|
3533
3603
|
const childStopped = singleResult.stopped === true;
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
requiredStatusStep(statusPayload, fi).durationMs = taskEndTime - taskStartTime;
|
|
3537
|
-
requiredStatusStep(statusPayload, fi).exitCode = stopped || childStopped ? 1 : timedOut ? 1 : childInterrupted ? 0 : singleResult.exitCode;
|
|
3538
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "timedOut", timedOut || singleResult.timedOut ? true : undefined);
|
|
3539
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "stopped", stopped || childStopped ? true : undefined);
|
|
3540
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "toolBudget", singleResult.toolBudget);
|
|
3541
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "toolBudgetBlocked", singleResult.toolBudgetBlocked);
|
|
3542
|
-
if (singleResult.toolBudget)
|
|
3543
|
-
statusPayload.toolBudget = singleResult.toolBudget;
|
|
3544
|
-
if (singleResult.toolBudgetBlocked)
|
|
3545
|
-
statusPayload.toolBudgetBlocked = true;
|
|
3546
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "sessionName", singleResult.sessionName);
|
|
3547
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "model", singleResult.model);
|
|
3548
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "thinking", resolveEffectiveThinking(singleResult.model, requiredStatusStep(statusPayload, fi).thinking));
|
|
3549
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "requestedModel", singleResult.requestedModel);
|
|
3550
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "contextOverflow", singleResult.contextOverflow);
|
|
3551
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "totalCost", singleResult.totalCost);
|
|
3552
|
-
if (singleResult.totalCost) {
|
|
3553
|
-
pendingParallelUsageCost = {
|
|
3554
|
-
inputTokens: pendingParallelUsageCost.inputTokens + singleResult.totalCost.inputTokens,
|
|
3555
|
-
outputTokens: pendingParallelUsageCost.outputTokens + singleResult.totalCost.outputTokens,
|
|
3556
|
-
costUsd: pendingParallelUsageCost.costUsd + singleResult.totalCost.costUsd,
|
|
3557
|
-
};
|
|
3558
|
-
refreshUsageBudget();
|
|
3559
|
-
}
|
|
3560
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "error", stopped || childStopped ? stopMessage : timedOut ? (timeoutMessage ?? "Subagent timed out.") : singleResult.error);
|
|
3561
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "transcriptPath", singleResult.transcriptPath ?? requiredStatusStep(statusPayload, fi).transcriptPath);
|
|
3562
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "transcriptError", singleResult.transcriptError);
|
|
3563
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "agentContract", singleResult.agentContract);
|
|
3564
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "launchContractDigest", singleResult.launchContractDigest);
|
|
3565
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "launchResolvedExtensions", singleResult.launchResolvedExtensions);
|
|
3566
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "runtimeAcknowledgedExtensions", singleResult.runtimeAcknowledgedExtensions);
|
|
3567
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "effects", singleResult.effects);
|
|
3568
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "execution", singleResult.execution);
|
|
3569
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "review", singleResult.review);
|
|
3570
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "structuredOutput", singleResult.structuredOutput);
|
|
3571
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "structuredOutputPath", singleResult.structuredOutputPath);
|
|
3572
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "structuredOutputSchemaPath", singleResult.structuredOutputSchemaPath);
|
|
3573
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "acceptance", singleResult.acceptance);
|
|
3574
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "timeoutRecovery", singleResult.timeoutRecovery);
|
|
3575
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "watchdog", singleResult.watchdog);
|
|
3576
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "capabilityCeiling", singleResult.capabilityCeiling);
|
|
3577
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "capabilityAudit", singleResult.capabilityAudit);
|
|
3578
|
-
if (singleResult.capabilityCeiling)
|
|
3579
|
-
statusPayload.capabilityCeiling = singleResult.capabilityCeiling;
|
|
3580
|
-
if (singleResult.capabilityAudit)
|
|
3581
|
-
statusPayload.capabilityAudit = singleResult.capabilityAudit;
|
|
3604
|
+
recordStepResult(fi, singleResult, taskStartTime, taskEndTime, true);
|
|
3605
|
+
addParallelUsageCost(singleResult.totalCost);
|
|
3582
3606
|
statusPayload.lastUpdate = taskEndTime;
|
|
3583
3607
|
writeStatusPayload();
|
|
3584
3608
|
appendCapabilityCeilingAppliedEvent(eventsPath, id, fi, task.agent, singleResult);
|
|
@@ -3591,7 +3615,7 @@ export async function runSubagent(config, childSessions) {
|
|
|
3591
3615
|
appendTerminalChildStatusEvent(fi, taskEndTime);
|
|
3592
3616
|
if (singleResult.exitCode !== 0 && failFast && !childStopped)
|
|
3593
3617
|
aborted = true;
|
|
3594
|
-
return stopped || childStopped ? { ...singleResult, output: stopMessage, error: stopMessage, exitCode: 1, interrupted: false, timedOut: false, stopped: true, skipped: false } : timedOut ? { ...singleResult, output: singleResult.output || (timeoutMessage ??
|
|
3618
|
+
return stopped || childStopped ? { ...singleResult, output: stopMessage, error: stopMessage, exitCode: 1, interrupted: false, timedOut: false, stopped: true, skipped: false } : timedOut ? { ...singleResult, output: singleResult.output || (timeoutMessage ?? SUBAGENT_TIMED_OUT_MESSAGE), error: singleResult.error ?? timeoutMessage ?? SUBAGENT_TIMED_OUT_MESSAGE, exitCode: 1, interrupted: false, timedOut: true, skipped: false } : { ...singleResult, skipped: false };
|
|
3595
3619
|
}, globalSemaphore);
|
|
3596
3620
|
flatIndex += dynamicSteps.length;
|
|
3597
3621
|
for (const pr of parallelResults) {
|
|
@@ -3678,7 +3702,7 @@ export async function runSubagent(config, childSessions) {
|
|
|
3678
3702
|
}),
|
|
3679
3703
|
cwd,
|
|
3680
3704
|
signal: combinedAbortSignal([timeoutAbortController.signal, stopAbortController.signal]),
|
|
3681
|
-
abortMessage: stopAbortController.signal.aborted ? stopMessage : timeoutMessage ??
|
|
3705
|
+
abortMessage: stopAbortController.signal.aborted ? stopMessage : timeoutMessage ?? SUBAGENT_TIMED_OUT_MESSAGE,
|
|
3682
3706
|
reportOptional: isAgentContract(step.agentContract),
|
|
3683
3707
|
}))
|
|
3684
3708
|
: undefined;
|
|
@@ -3686,7 +3710,7 @@ export async function runSubagent(config, childSessions) {
|
|
|
3686
3710
|
const groupTimedOut = !groupStopped && (timedOut || timeoutAbortController.signal.aborted);
|
|
3687
3711
|
const effectiveGroupAcceptance = groupTimedOut || groupStopped ? undefined : groupAcceptance;
|
|
3688
3712
|
const groupAcceptanceFailure = effectiveDynamicGroupAcceptance.explicit && effectiveGroupAcceptance && (!isAgentContract(step.agentContract) || step.gateOn === "acceptance") ? acceptanceFailureMessage(effectiveGroupAcceptance) : undefined;
|
|
3689
|
-
const groupError = groupStopped ? stopMessage : groupTimedOut ? timeoutMessage ??
|
|
3713
|
+
const groupError = groupStopped ? stopMessage : groupTimedOut ? timeoutMessage ?? SUBAGENT_TIMED_OUT_MESSAGE : groupAcceptanceFailure;
|
|
3690
3714
|
markDynamicGraphGroup(stepIndex, groupError ? groupStopped ? "stopped" : "failed" : "completed", groupError, effectiveGroupAcceptance);
|
|
3691
3715
|
if (groupError) {
|
|
3692
3716
|
results.push(omitUndefinedProperties({
|
|
@@ -3801,7 +3825,7 @@ export async function runSubagent(config, childSessions) {
|
|
|
3801
3825
|
if (config.deadlineAt !== undefined && Date.now() >= config.deadlineAt)
|
|
3802
3826
|
timeoutRunner();
|
|
3803
3827
|
if (setupSignal.aborted)
|
|
3804
|
-
throw new Error(stopped ? stopMessage : timedOut ? timeoutMessage ??
|
|
3828
|
+
throw new Error(stopped ? stopMessage : timedOut ? timeoutMessage ?? SUBAGENT_TIMED_OUT_MESSAGE : "Subagent paused during worktree setup.");
|
|
3805
3829
|
}
|
|
3806
3830
|
catch (error) {
|
|
3807
3831
|
if (worktreeSetup)
|
|
@@ -3896,7 +3920,6 @@ export async function runSubagent(config, childSessions) {
|
|
|
3896
3920
|
return omitUndefinedProperties({ agent: task.agent, ...(task.sessionName ? { sessionName: task.sessionName } : {}), context: task.context, output: "(skipped — fail-fast)", exitCode: -1, skipped: true });
|
|
3897
3921
|
}
|
|
3898
3922
|
const taskStartTime = Date.now();
|
|
3899
|
-
launchedFlatIndices.add(fi);
|
|
3900
3923
|
statusPayload.currentStep = fi;
|
|
3901
3924
|
requiredStatusStep(statusPayload, fi).status = "running";
|
|
3902
3925
|
delete requiredStatusStep(statusPayload, fi).error;
|
|
@@ -3962,53 +3985,8 @@ export async function runSubagent(config, childSessions) {
|
|
|
3962
3985
|
const taskDuration = taskEndTime - taskStartTime;
|
|
3963
3986
|
const childInterrupted = singleResult.interrupted === true;
|
|
3964
3987
|
const childStopped = singleResult.stopped === true;
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
requiredStatusStep(statusPayload, fi).durationMs = taskDuration;
|
|
3968
|
-
requiredStatusStep(statusPayload, fi).exitCode = stopped || childStopped ? 1 : timedOut ? 1 : childInterrupted ? 0 : singleResult.exitCode;
|
|
3969
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "timedOut", timedOut || singleResult.timedOut ? true : undefined);
|
|
3970
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "stopped", stopped || childStopped ? true : undefined);
|
|
3971
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "toolBudget", singleResult.toolBudget);
|
|
3972
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "toolBudgetBlocked", singleResult.toolBudgetBlocked);
|
|
3973
|
-
if (singleResult.toolBudget)
|
|
3974
|
-
statusPayload.toolBudget = singleResult.toolBudget;
|
|
3975
|
-
if (singleResult.toolBudgetBlocked)
|
|
3976
|
-
statusPayload.toolBudgetBlocked = true;
|
|
3977
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "sessionName", singleResult.sessionName);
|
|
3978
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "model", singleResult.model);
|
|
3979
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "thinking", resolveEffectiveThinking(singleResult.model, requiredStatusStep(statusPayload, fi).thinking));
|
|
3980
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "requestedModel", singleResult.requestedModel);
|
|
3981
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "contextOverflow", singleResult.contextOverflow);
|
|
3982
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "totalCost", singleResult.totalCost);
|
|
3983
|
-
if (singleResult.totalCost) {
|
|
3984
|
-
pendingParallelUsageCost = {
|
|
3985
|
-
inputTokens: pendingParallelUsageCost.inputTokens + singleResult.totalCost.inputTokens,
|
|
3986
|
-
outputTokens: pendingParallelUsageCost.outputTokens + singleResult.totalCost.outputTokens,
|
|
3987
|
-
costUsd: pendingParallelUsageCost.costUsd + singleResult.totalCost.costUsd,
|
|
3988
|
-
};
|
|
3989
|
-
refreshUsageBudget();
|
|
3990
|
-
}
|
|
3991
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "error", stopped || childStopped ? stopMessage : timedOut ? (timeoutMessage ?? "Subagent timed out.") : singleResult.error);
|
|
3992
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "transcriptPath", singleResult.transcriptPath ?? requiredStatusStep(statusPayload, fi).transcriptPath);
|
|
3993
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "transcriptError", singleResult.transcriptError);
|
|
3994
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "agentContract", singleResult.agentContract);
|
|
3995
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "launchResolvedExtensions", singleResult.launchResolvedExtensions);
|
|
3996
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "runtimeAcknowledgedExtensions", singleResult.runtimeAcknowledgedExtensions);
|
|
3997
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "effects", singleResult.effects);
|
|
3998
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "execution", singleResult.execution);
|
|
3999
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "review", singleResult.review);
|
|
4000
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "structuredOutput", singleResult.structuredOutput);
|
|
4001
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "structuredOutputPath", singleResult.structuredOutputPath);
|
|
4002
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "structuredOutputSchemaPath", singleResult.structuredOutputSchemaPath);
|
|
4003
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "acceptance", singleResult.acceptance);
|
|
4004
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "timeoutRecovery", singleResult.timeoutRecovery);
|
|
4005
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "watchdog", singleResult.watchdog);
|
|
4006
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "capabilityCeiling", singleResult.capabilityCeiling);
|
|
4007
|
-
setOptionalProperty(requiredStatusStep(statusPayload, fi), "capabilityAudit", singleResult.capabilityAudit);
|
|
4008
|
-
if (singleResult.capabilityCeiling)
|
|
4009
|
-
statusPayload.capabilityCeiling = singleResult.capabilityCeiling;
|
|
4010
|
-
if (singleResult.capabilityAudit)
|
|
4011
|
-
statusPayload.capabilityAudit = singleResult.capabilityAudit;
|
|
3988
|
+
recordStepResult(fi, singleResult, taskStartTime, taskEndTime);
|
|
3989
|
+
addParallelUsageCost(singleResult.totalCost);
|
|
4012
3990
|
statusPayload.lastUpdate = taskEndTime;
|
|
4013
3991
|
writeStatusPayload();
|
|
4014
3992
|
appendCapabilityCeilingAppliedEvent(eventsPath, id, fi, task.agent, singleResult);
|
|
@@ -4021,7 +3999,7 @@ export async function runSubagent(config, childSessions) {
|
|
|
4021
3999
|
appendTerminalChildStatusEvent(fi, taskEndTime);
|
|
4022
4000
|
if (singleResult.exitCode !== 0 && failFast && !childStopped)
|
|
4023
4001
|
aborted = true;
|
|
4024
|
-
return stopped || childStopped ? { ...singleResult, output: stopMessage, error: stopMessage, exitCode: 1, interrupted: false, timedOut: false, stopped: true, skipped: false } : timedOut ? { ...singleResult, output: singleResult.output || (timeoutMessage ??
|
|
4002
|
+
return stopped || childStopped ? { ...singleResult, output: stopMessage, error: stopMessage, exitCode: 1, interrupted: false, timedOut: false, stopped: true, skipped: false } : timedOut ? { ...singleResult, output: singleResult.output || (timeoutMessage ?? SUBAGENT_TIMED_OUT_MESSAGE), error: singleResult.error ?? timeoutMessage ?? SUBAGENT_TIMED_OUT_MESSAGE, exitCode: 1, interrupted: false, timedOut: true, skipped: false } : { ...singleResult, skipped: false };
|
|
4025
4003
|
}, globalSemaphore);
|
|
4026
4004
|
flatIndex += group.parallel.length;
|
|
4027
4005
|
for (let t = 0; t < group.parallel.length; t++) {
|
|
@@ -4290,7 +4268,6 @@ export async function runSubagent(config, childSessions) {
|
|
|
4290
4268
|
}
|
|
4291
4269
|
const singleCwd = singleWorktreeSetup?.worktrees[0]?.agentCwd ?? cwd;
|
|
4292
4270
|
const stepStartTime = Date.now();
|
|
4293
|
-
launchedFlatIndices.add(flatIndex);
|
|
4294
4271
|
statusPayload.currentStep = flatIndex;
|
|
4295
4272
|
requiredStatusStep(statusPayload, flatIndex).status = "running";
|
|
4296
4273
|
delete requiredStatusStep(statusPayload, flatIndex).activityState;
|
|
@@ -4372,10 +4349,10 @@ export async function runSubagent(config, childSessions) {
|
|
|
4372
4349
|
launchContractDigest: singleResult.launchContractDigest,
|
|
4373
4350
|
launchResolvedExtensions: singleResult.launchResolvedExtensions,
|
|
4374
4351
|
runtimeAcknowledgedExtensions: singleResult.runtimeAcknowledgedExtensions,
|
|
4375
|
-
output: stopped || childStopped ? stopMessage : timedOut ? singleResult.output || (timeoutMessage ??
|
|
4352
|
+
output: stopped || childStopped ? stopMessage : timedOut ? singleResult.output || (timeoutMessage ?? SUBAGENT_TIMED_OUT_MESSAGE) : singleResult.output,
|
|
4376
4353
|
outputState: singleResult.outputState,
|
|
4377
4354
|
outputPartial: singleResult.outputPartial,
|
|
4378
|
-
error: stopped || childStopped ? stopMessage : timedOut ? (timeoutMessage ??
|
|
4355
|
+
error: stopped || childStopped ? stopMessage : timedOut ? (timeoutMessage ?? SUBAGENT_TIMED_OUT_MESSAGE) : singleResult.error,
|
|
4379
4356
|
success: !stopped && !childStopped && !timedOut && singleResult.interrupted !== true && singleResult.exitCode === 0 && singleResult.execution?.status !== "partial",
|
|
4380
4357
|
exitCode: stopped || childStopped ? 1 : timedOut ? 1 : singleResult.interrupted === true ? 0 : singleResult.exitCode,
|
|
4381
4358
|
sessionFile: singleResult.sessionFile,
|
|
@@ -4454,45 +4431,7 @@ export async function runSubagent(config, childSessions) {
|
|
|
4454
4431
|
}
|
|
4455
4432
|
const stepEndTime = Date.now();
|
|
4456
4433
|
const childInterrupted = singleResult.interrupted === true;
|
|
4457
|
-
|
|
4458
|
-
requiredStatusStep(statusPayload, flatIndex).endedAt = stepEndTime;
|
|
4459
|
-
requiredStatusStep(statusPayload, flatIndex).durationMs = stepEndTime - stepStartTime;
|
|
4460
|
-
requiredStatusStep(statusPayload, flatIndex).exitCode = stopped || childStopped ? 1 : timedOut ? 1 : childInterrupted ? 0 : singleResult.exitCode;
|
|
4461
|
-
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "timedOut", timedOut || singleResult.timedOut ? true : undefined);
|
|
4462
|
-
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "stopped", stopped || childStopped ? true : undefined);
|
|
4463
|
-
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "toolBudget", singleResult.toolBudget);
|
|
4464
|
-
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "toolBudgetBlocked", singleResult.toolBudgetBlocked);
|
|
4465
|
-
if (singleResult.toolBudget)
|
|
4466
|
-
statusPayload.toolBudget = singleResult.toolBudget;
|
|
4467
|
-
if (singleResult.toolBudgetBlocked)
|
|
4468
|
-
statusPayload.toolBudgetBlocked = true;
|
|
4469
|
-
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "sessionName", singleResult.sessionName);
|
|
4470
|
-
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "model", singleResult.model);
|
|
4471
|
-
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "thinking", resolveEffectiveThinking(singleResult.model, requiredStatusStep(statusPayload, flatIndex).thinking));
|
|
4472
|
-
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "requestedModel", singleResult.requestedModel);
|
|
4473
|
-
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "contextOverflow", singleResult.contextOverflow);
|
|
4474
|
-
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "totalCost", singleResult.totalCost);
|
|
4475
|
-
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "error", stopped || childStopped ? stopMessage : timedOut ? (timeoutMessage ?? "Subagent timed out.") : singleResult.error);
|
|
4476
|
-
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "transcriptPath", singleResult.transcriptPath ?? requiredStatusStep(statusPayload, flatIndex).transcriptPath);
|
|
4477
|
-
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "transcriptError", singleResult.transcriptError);
|
|
4478
|
-
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "agentContract", singleResult.agentContract);
|
|
4479
|
-
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "launchResolvedExtensions", singleResult.launchResolvedExtensions);
|
|
4480
|
-
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "runtimeAcknowledgedExtensions", singleResult.runtimeAcknowledgedExtensions);
|
|
4481
|
-
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "effects", singleResult.effects);
|
|
4482
|
-
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "execution", singleResult.execution);
|
|
4483
|
-
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "review", singleResult.review);
|
|
4484
|
-
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "structuredOutput", singleResult.structuredOutput);
|
|
4485
|
-
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "structuredOutputPath", singleResult.structuredOutputPath);
|
|
4486
|
-
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "structuredOutputSchemaPath", singleResult.structuredOutputSchemaPath);
|
|
4487
|
-
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "acceptance", singleResult.acceptance);
|
|
4488
|
-
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "timeoutRecovery", singleResult.timeoutRecovery);
|
|
4489
|
-
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "watchdog", singleResult.watchdog);
|
|
4490
|
-
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "capabilityCeiling", singleResult.capabilityCeiling);
|
|
4491
|
-
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "capabilityAudit", singleResult.capabilityAudit);
|
|
4492
|
-
if (singleResult.capabilityCeiling)
|
|
4493
|
-
statusPayload.capabilityCeiling = singleResult.capabilityCeiling;
|
|
4494
|
-
if (singleResult.capabilityAudit)
|
|
4495
|
-
statusPayload.capabilityAudit = singleResult.capabilityAudit;
|
|
4434
|
+
recordStepResult(flatIndex, singleResult, stepStartTime, stepEndTime);
|
|
4496
4435
|
if (stepTokens) {
|
|
4497
4436
|
requiredStatusStep(statusPayload, flatIndex).tokens = stepTokens;
|
|
4498
4437
|
statusPayload.totalTokens = { ...previousCumulativeTokens };
|
|
@@ -4722,7 +4661,7 @@ export async function runSubagent(config, childSessions) {
|
|
|
4722
4661
|
}
|
|
4723
4662
|
if (timedOut) {
|
|
4724
4663
|
statusPayload.timedOut = true;
|
|
4725
|
-
statusPayload.error = timeoutMessage ??
|
|
4664
|
+
statusPayload.error = timeoutMessage ?? SUBAGENT_TIMED_OUT_MESSAGE;
|
|
4726
4665
|
}
|
|
4727
4666
|
if (usageBudgetExceeded && statusPayload.usageBudget && !statusPayload.error) {
|
|
4728
4667
|
statusPayload.error = usageBudgetExceededMessage(statusPayload.usageBudget);
|
|
@@ -4767,13 +4706,13 @@ export async function runSubagent(config, childSessions) {
|
|
|
4767
4706
|
mode: resultMode,
|
|
4768
4707
|
success: statusPayload.state === "complete",
|
|
4769
4708
|
state: statusPayload.state,
|
|
4770
|
-
summary: stopped ? stopMessage : signalTerminated ? (statusPayload.error ?? "Subagent process terminated by signal.") : timedOut ? (timeoutMessage ??
|
|
4709
|
+
summary: stopped ? stopMessage : signalTerminated ? (statusPayload.error ?? "Subagent process terminated by signal.") : timedOut ? timedOutRunSummary(timeoutMessage ?? SUBAGENT_TIMED_OUT_MESSAGE, summary, results) : usageBudgetExceeded ? (statusPayload.error ?? "Usage budget exhausted.") : interrupted ? "Paused after interrupt. Waiting for explicit next action." : statusPayload.state === "partial" ? (statusPayload.error ?? summary) : summary,
|
|
4771
4710
|
...(config.timeoutMs !== undefined ? { timeoutMs: config.timeoutMs } : {}),
|
|
4772
4711
|
...(config.deadlineAt !== undefined ? { deadlineAt: config.deadlineAt } : {}),
|
|
4773
4712
|
...(statusPayload.toolBudget ? { toolBudget: statusPayload.toolBudget } : {}),
|
|
4774
4713
|
...(statusPayload.toolBudgetBlocked ? { toolBudgetBlocked: true } : {}),
|
|
4775
4714
|
...(statusPayload.usageBudget ? { usageBudget: statusPayload.usageBudget } : {}),
|
|
4776
|
-
...(stopped ? { stopped: true, error: stopMessage } : timedOut ? { timedOut: true, error: timeoutMessage ??
|
|
4715
|
+
...(stopped ? { stopped: true, error: stopMessage } : timedOut ? { timedOut: true, error: timeoutMessage ?? SUBAGENT_TIMED_OUT_MESSAGE } : usageBudgetExceeded ? { error: statusPayload.error ?? "Usage budget exhausted." } : {}),
|
|
4777
4716
|
results: results.map((r) => omitUndefinedProperties({
|
|
4778
4717
|
agent: r.agent,
|
|
4779
4718
|
...(r.sessionName ? { sessionName: r.sessionName } : {}),
|
|
@@ -4883,26 +4822,6 @@ export async function runSubagent(config, childSessions) {
|
|
|
4883
4822
|
totalCost: finalTotalCost,
|
|
4884
4823
|
usageBudget: statusPayload.usageBudget,
|
|
4885
4824
|
}));
|
|
4886
|
-
// Paused runs record an interrupted attempt; a later resume records another.
|
|
4887
|
-
for (const historyEntry of planBackgroundRunHistory({
|
|
4888
|
-
steps,
|
|
4889
|
-
resultMode,
|
|
4890
|
-
statusSteps: statusPayload.steps.map((step, index) => ({
|
|
4891
|
-
agent: step.agent,
|
|
4892
|
-
status: step.status,
|
|
4893
|
-
durationMs: step.durationMs,
|
|
4894
|
-
timedOut: step.timedOut,
|
|
4895
|
-
stopped: step.stopped,
|
|
4896
|
-
launched: launchedFlatIndices.has(index),
|
|
4897
|
-
})),
|
|
4898
|
-
stepResults: results,
|
|
4899
|
-
runDurationMs: runEndedAt - overallStartTime,
|
|
4900
|
-
stopped,
|
|
4901
|
-
interrupted,
|
|
4902
|
-
timedOut,
|
|
4903
|
-
})) {
|
|
4904
|
-
recordRun(historyEntry.agent, historyEntry.task, historyEntry.exitCode, historyEntry.durationMs, historyEntry.terminal);
|
|
4905
|
-
}
|
|
4906
4825
|
writeRunLog(logPath, omitUndefinedProperties({
|
|
4907
4826
|
id,
|
|
4908
4827
|
mode: statusPayload.mode,
|