pi-subagents 0.55.0 → 0.56.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 +28 -3
- package/docs/models.md +6 -0
- package/package.json +1 -1
- package/src/agents/agent-serializer.ts +2 -0
- package/src/agents/agents.ts +23 -1
- package/src/api/preflight.ts +20 -1
- package/src/extension/schemas.ts +5 -0
- package/src/runs/background/async-execution.ts +48 -18
- package/src/runs/background/async-resume.ts +3 -0
- package/src/runs/background/subagent-runner.ts +83 -11
- package/src/runs/foreground/execution.ts +35 -6
- package/src/runs/foreground/foreground-history.ts +3 -2
- package/src/runs/foreground/subagent-executor.ts +59 -8
- package/src/runs/foreground/workflow-detach-reconcile.ts +15 -6
- package/src/runs/shared/acceptance.ts +10 -5
- package/src/runs/shared/agent-contract.ts +1 -1
- package/src/runs/shared/completion-guard.ts +3 -2
- package/src/runs/shared/dynamic-fanout.ts +1 -1
- package/src/runs/shared/extension-bindings.ts +78 -0
- package/src/runs/shared/external-cli-runner.ts +2 -0
- package/src/runs/shared/fast-mode-extension.ts +10 -0
- package/src/runs/shared/model-exclusions.ts +2 -1
- package/src/runs/shared/model-fallback.ts +2 -7
- package/src/runs/shared/mutation-evidence.ts +145 -0
- package/src/runs/shared/parallel-utils.ts +3 -0
- package/src/runs/shared/pi-args.ts +47 -0
- package/src/runs/shared/structured-output.ts +18 -4
- package/src/runs/shared/subagent-prompt-runtime.ts +9 -5
- package/src/shared/launch-contract.ts +6 -0
- package/src/shared/settings.ts +6 -1
- package/src/shared/types.ts +48 -0
- package/src/workflows/scripted-workflow.ts +50 -3
|
@@ -80,9 +80,10 @@ import {
|
|
|
80
80
|
import { applyThinkingSuffix, buildPiArgs, cleanupTempDir, projectLaunchResolvedChildExtensions, resolvePiLaunchToolPlan, type SubagentTaskDelivery } from "../shared/pi-args.ts";
|
|
81
81
|
import { readRuntimeAcknowledgedExtensions } from "../shared/runtime-acknowledged-extensions.ts";
|
|
82
82
|
import { outputEntryFromAsyncResult, resolveOutputReferences } from "../shared/chain-outputs.ts";
|
|
83
|
-
import { createStructuredOutputRuntime, MISSING_STRUCTURED_OUTPUT_CALL_ERROR, readStructuredOutput } from "../shared/structured-output.ts";
|
|
83
|
+
import { createStructuredOutputRuntime, MISSING_STRUCTURED_OUTPUT_CALL_ERROR, readStructuredOutput, readStructuredOutputAcceptanceReport } from "../shared/structured-output.ts";
|
|
84
84
|
import { formatProcessSignalError, isUnexplainedProcessSignal } from "../shared/process-signal.ts";
|
|
85
85
|
import { readChildToolDiagnosticError } from "../shared/tool-availability.ts";
|
|
86
|
+
import { buildTimeoutRecoverySummary, collectTrackedMutationEvidence, snapshotTrackedMutations } from "../shared/mutation-evidence.ts";
|
|
86
87
|
import { collectDynamicResults, DynamicFanoutError, materializeDynamicParallelStep, validateDynamicCollection } from "../shared/dynamic-fanout.ts";
|
|
87
88
|
import { claimRunFanoutBatch, getRunFanoutBudgetSnapshot } from "../shared/run-fanout-budget.ts";
|
|
88
89
|
import { nestedSummaryFromAsyncStatus, projectNestedEvents, resolveNestedAsyncDir, writeNestedEvent } from "../shared/nested-events.ts";
|
|
@@ -131,6 +132,7 @@ import { resolveSubagentIntercomTarget } from "../../intercom/intercom-bridge.ts
|
|
|
131
132
|
import { acceptanceFailureMessage, aggregateAcceptanceReport, buildSkippedAcceptanceLedger, evaluateAcceptance, formatAcceptancePrompt, resolveEffectiveAcceptance, stripAcceptanceReport } from "../shared/acceptance.ts";
|
|
132
133
|
import { attachContractProjections, isAgentContractV1 } from "../shared/agent-contract.ts";
|
|
133
134
|
import { waitForImportedAsyncRoot } from "./chain-root-attachment.ts";
|
|
135
|
+
import { normalizeExtensionBindings } from "../shared/extension-bindings.ts";
|
|
134
136
|
import { appendRunnerStepsToStatus, consumeChainAppendRequests, countPendingChainAppendRequests, statusStepDescription } from "./chain-append.ts";
|
|
135
137
|
import { asyncStatusChildIdentity } from "../shared/child-identity.ts";
|
|
136
138
|
import { appendTurnBudgetSystemPrompt, formatTurnBudgetOutput, initialTurnBudgetState, turnBudgetDecision, turnBudgetDeferredNote, turnBudgetDeferredState, turnBudgetExceededMessage, turnBudgetSoftNote, turnBudgetState } from "../shared/turn-budget.ts";
|
|
@@ -229,6 +231,7 @@ interface StepResult {
|
|
|
229
231
|
timedOut?: boolean;
|
|
230
232
|
stopped?: boolean;
|
|
231
233
|
processSignal?: string | null;
|
|
234
|
+
timeoutRecovery?: import("../../shared/types.ts").TimeoutRecoverySummary;
|
|
232
235
|
turnBudget?: TurnBudgetState;
|
|
233
236
|
turnBudgetExceeded?: boolean;
|
|
234
237
|
wrapUpRequested?: boolean;
|
|
@@ -540,6 +543,9 @@ interface RunPiStreamingResult {
|
|
|
540
543
|
processCloseObservedAt?: number;
|
|
541
544
|
processSignal?: string | null;
|
|
542
545
|
processTree: ProcessTreeTerminalV1;
|
|
546
|
+
currentTool?: string;
|
|
547
|
+
currentToolArgs?: string;
|
|
548
|
+
currentPath?: string;
|
|
543
549
|
}
|
|
544
550
|
|
|
545
551
|
function runPiStreaming(
|
|
@@ -610,6 +616,9 @@ function runPiStreaming(
|
|
|
610
616
|
let observedMutationAttempt = false;
|
|
611
617
|
let structuredOutputToolInvoked = false;
|
|
612
618
|
let structuredOutputMessageStartIndex: number | undefined;
|
|
619
|
+
let currentTool: string | undefined;
|
|
620
|
+
let currentToolArgs: string | undefined;
|
|
621
|
+
let currentPath: string | undefined;
|
|
613
622
|
let toolCount = 0;
|
|
614
623
|
const childWatchdogConfig = decodeChildWatchdogConfig(env?.[CHILD_WATCHDOG_CONFIG_ENV]);
|
|
615
624
|
let childWatchdogState: ChildWatchdogStateSnapshot | undefined;
|
|
@@ -701,12 +710,18 @@ function runPiStreaming(
|
|
|
701
710
|
|
|
702
711
|
if (event.type === "tool_execution_end") {
|
|
703
712
|
clearActiveToolTimeout(event);
|
|
713
|
+
currentTool = undefined;
|
|
714
|
+
currentToolArgs = undefined;
|
|
715
|
+
currentPath = undefined;
|
|
704
716
|
return;
|
|
705
717
|
}
|
|
706
718
|
|
|
707
719
|
if (event.type === "tool_execution_start" && event.toolName) {
|
|
708
720
|
toolCount += 1;
|
|
709
721
|
armToolTimeout({ toolCallId: (event as { toolCallId?: unknown }).toolCallId, toolName: event.toolName });
|
|
722
|
+
currentTool = event.toolName;
|
|
723
|
+
currentToolArgs = extractToolArgsPreview(event.args ?? {});
|
|
724
|
+
currentPath = resolveCurrentPath(event.toolName, event.args);
|
|
710
725
|
if (event.toolName === "structured_output") {
|
|
711
726
|
structuredOutputToolInvoked = true;
|
|
712
727
|
structuredOutputMessageStartIndex = messages.length;
|
|
@@ -1029,6 +1044,9 @@ function runPiStreaming(
|
|
|
1029
1044
|
processCloseObservedAt,
|
|
1030
1045
|
processSignal: signal,
|
|
1031
1046
|
processTree,
|
|
1047
|
+
currentTool,
|
|
1048
|
+
currentToolArgs,
|
|
1049
|
+
currentPath,
|
|
1032
1050
|
}));
|
|
1033
1051
|
});
|
|
1034
1052
|
|
|
@@ -1207,6 +1225,8 @@ interface SingleStepContext {
|
|
|
1207
1225
|
onExternalProcess?: (process: ExternalProcessStatus) => void;
|
|
1208
1226
|
onExternalJob?: (status: ExternalJobStatus) => void;
|
|
1209
1227
|
skipAcceptance?: () => boolean;
|
|
1228
|
+
/** False when sibling work in the same Git worktree could have caused the tracked diff. */
|
|
1229
|
+
trackedMutationEvidenceForCompletionGuard?: boolean;
|
|
1210
1230
|
orcaProgressTab?: OrcaProgressTab;
|
|
1211
1231
|
}
|
|
1212
1232
|
|
|
@@ -1297,6 +1317,9 @@ async function runSingleStepInner(
|
|
|
1297
1317
|
tools: step.tools,
|
|
1298
1318
|
extensions: step.extensions,
|
|
1299
1319
|
subagentOnlyExtensions: step.subagentOnlyExtensions,
|
|
1320
|
+
fast: step.fast,
|
|
1321
|
+
model: step.model,
|
|
1322
|
+
modelCandidates: step.modelCandidates,
|
|
1300
1323
|
mcpDirectTools: step.mcpDirectTools,
|
|
1301
1324
|
cwd: step.cwd ?? ctx.cwd,
|
|
1302
1325
|
requireReadTool: Boolean(step.skills?.length),
|
|
@@ -1329,7 +1352,7 @@ async function runSingleStepInner(
|
|
|
1329
1352
|
}
|
|
1330
1353
|
}
|
|
1331
1354
|
if (step.effectiveAcceptance) {
|
|
1332
|
-
const acceptancePrompt = formatAcceptancePrompt(step.effectiveAcceptance, { reportOptional: isAgentContractV1(step.agentContract) });
|
|
1355
|
+
const acceptancePrompt = formatAcceptancePrompt(step.effectiveAcceptance, { reportOptional: isAgentContractV1(step.agentContract), structuredOutput: Boolean(step.structuredOutput?.acceptanceReportPath) });
|
|
1333
1356
|
if (acceptancePrompt) task = `${task}\n${acceptancePrompt}`;
|
|
1334
1357
|
}
|
|
1335
1358
|
const sessionEnabled = Boolean(step.sessionFile) || ctx.sessionEnabled;
|
|
@@ -1500,11 +1523,15 @@ async function runSingleStepInner(
|
|
|
1500
1523
|
const eventsPath = path.join(path.dirname(ctx.outputFile), "events.jsonl");
|
|
1501
1524
|
let finalResult: RunPiStreamingResult | undefined;
|
|
1502
1525
|
let finalOutputSnapshot: SingleOutputSnapshot | undefined;
|
|
1526
|
+
let structuredAcceptanceReport: unknown;
|
|
1527
|
+
let structuredAcceptanceReportError: string | undefined;
|
|
1503
1528
|
let completionGuardTriggeredFinal = false;
|
|
1504
1529
|
let turnBudget = ctx.turnBudget ? initialTurnBudgetState(ctx.turnBudget) : undefined;
|
|
1505
1530
|
let toolBudget = step.toolBudget ? initialToolBudgetState(step.toolBudget) : undefined;
|
|
1506
1531
|
let toolBudgetBlocked = false;
|
|
1507
1532
|
let actualLaunchContractDigest = step.launchContractDigest;
|
|
1533
|
+
const mutationSnapshot = snapshotTrackedMutations(step.cwd ?? ctx.cwd);
|
|
1534
|
+
let finalMutationEvidence = collectTrackedMutationEvidence(mutationSnapshot, step.cwd ?? ctx.cwd);
|
|
1508
1535
|
|
|
1509
1536
|
let modelIndex = 0;
|
|
1510
1537
|
let startupAttemptIndex = 0;
|
|
@@ -1533,6 +1560,7 @@ async function runSingleStepInner(
|
|
|
1533
1560
|
}
|
|
1534
1561
|
}
|
|
1535
1562
|
const watchdogConfig = resolveWatchdogConfig(step.cwd ?? ctx.cwd);
|
|
1563
|
+
const extensionBindings = normalizeExtensionBindings(step.extensionBindings)?.value;
|
|
1536
1564
|
const childWatchdog = watchdogConfig.ok
|
|
1537
1565
|
? resolveChildWatchdogConfig({
|
|
1538
1566
|
config: watchdogConfig.config,
|
|
@@ -1556,6 +1584,8 @@ async function runSingleStepInner(
|
|
|
1556
1584
|
tools: step.tools,
|
|
1557
1585
|
extensions: step.extensions,
|
|
1558
1586
|
subagentOnlyExtensions: step.subagentOnlyExtensions,
|
|
1587
|
+
fast: step.fast,
|
|
1588
|
+
modelCandidates: step.modelCandidates,
|
|
1559
1589
|
systemPrompt: appendTurnBudgetSystemPrompt(step.systemPrompt ?? "", ctx.turnBudget),
|
|
1560
1590
|
systemPromptMode: step.systemPromptMode,
|
|
1561
1591
|
mcpDirectTools: step.mcpDirectTools,
|
|
@@ -1587,6 +1617,7 @@ async function runSingleStepInner(
|
|
|
1587
1617
|
childWatchdog,
|
|
1588
1618
|
waitToolEnabled: step.waitToolEnabled,
|
|
1589
1619
|
thinkingCeiling: step.thinkingCeiling,
|
|
1620
|
+
extensionBindings,
|
|
1590
1621
|
}));
|
|
1591
1622
|
if (!launchWarningsEmitted && warnings.length > 0) {
|
|
1592
1623
|
for (const warning of warnings) console.warn(`[pi-subagents] ${warning}`);
|
|
@@ -1597,6 +1628,9 @@ async function runSingleStepInner(
|
|
|
1597
1628
|
tools: step.tools,
|
|
1598
1629
|
extensions: step.extensions,
|
|
1599
1630
|
subagentOnlyExtensions: step.subagentOnlyExtensions,
|
|
1631
|
+
fast: step.fast,
|
|
1632
|
+
model: step.model,
|
|
1633
|
+
modelCandidates: step.modelCandidates,
|
|
1600
1634
|
mcpDirectTools: step.mcpDirectTools,
|
|
1601
1635
|
cwd: step.cwd ?? ctx.cwd,
|
|
1602
1636
|
requireReadTool: Boolean(step.skills?.length),
|
|
@@ -1611,6 +1645,7 @@ async function runSingleStepInner(
|
|
|
1611
1645
|
task: step.launchBindingTask ?? task,
|
|
1612
1646
|
...(candidate ? { model: candidate } : {}),
|
|
1613
1647
|
modelCandidates: candidates as string[],
|
|
1648
|
+
...(step.fast !== undefined ? { fast: step.fast } : {}),
|
|
1614
1649
|
...(resolveEffectiveThinking(candidate, step.thinking) ? { thinking: resolveEffectiveThinking(candidate, step.thinking) } : {}),
|
|
1615
1650
|
...(step.thinkingCeiling ? { thinkingCeiling: step.thinkingCeiling } : {}),
|
|
1616
1651
|
systemPrompt: appendTurnBudgetSystemPrompt(step.systemPrompt ?? "", ctx.turnBudget),
|
|
@@ -1624,6 +1659,7 @@ async function runSingleStepInner(
|
|
|
1624
1659
|
...(step.outputPath ? { outputPath: step.outputPath } : {}),
|
|
1625
1660
|
...(step.outputMode ? { outputMode: step.outputMode } : {}),
|
|
1626
1661
|
...(step.structuredOutputSchema ? { structuredOutputSchema: step.structuredOutputSchema } : {}),
|
|
1662
|
+
...(extensionBindings ? { extensionBindings } : {}),
|
|
1627
1663
|
}));
|
|
1628
1664
|
}
|
|
1629
1665
|
capabilityAudit = attemptCapabilityAudit;
|
|
@@ -1703,6 +1739,9 @@ async function runSingleStepInner(
|
|
|
1703
1739
|
if (structured.error) structuredError = structured.error;
|
|
1704
1740
|
else {
|
|
1705
1741
|
structuredOutput = structured.value;
|
|
1742
|
+
const acceptanceReport = readStructuredOutputAcceptanceReport(effectiveStructuredOutput);
|
|
1743
|
+
structuredAcceptanceReport = acceptanceReport.value;
|
|
1744
|
+
structuredAcceptanceReportError = acceptanceReport.error;
|
|
1706
1745
|
validatedStructuredOutput = true;
|
|
1707
1746
|
}
|
|
1708
1747
|
}
|
|
@@ -1724,6 +1763,9 @@ async function runSingleStepInner(
|
|
|
1724
1763
|
: undefined;
|
|
1725
1764
|
const completionGuardEnabled = isAgentContractV1(step.agentContract) ? step.completionGuard === true : step.completionGuard !== false;
|
|
1726
1765
|
const completionToolPlan = resolvedTaskToolPlan;
|
|
1766
|
+
const mutationEvidence = collectTrackedMutationEvidence(mutationSnapshot, step.cwd ?? ctx.cwd);
|
|
1767
|
+
finalMutationEvidence = mutationEvidence;
|
|
1768
|
+
const completionMutationEvidence = ctx.trackedMutationEvidenceForCompletionGuard === false ? undefined : mutationEvidence;
|
|
1727
1769
|
const completionGuard = run.exitCode === 0 && !run.error && !structuredError && !hiddenError?.hasError && !emptyOutputError && completionGuardEnabled
|
|
1728
1770
|
? evaluateCompletionMutationGuard(omitUndefinedProperties({
|
|
1729
1771
|
agent: step.agent,
|
|
@@ -1732,15 +1774,18 @@ async function runSingleStepInner(
|
|
|
1732
1774
|
tools: completionToolPlan ? (completionToolPlan.explicitToolAllowlist ? completionToolPlan.effectiveToolAllowlist : undefined) : step.tools,
|
|
1733
1775
|
mcpDirectTools: completionToolPlan?.effectiveMcpTools ?? step.mcpDirectTools,
|
|
1734
1776
|
toolAvailabilityError,
|
|
1777
|
+
mutationEvidence: completionMutationEvidence,
|
|
1735
1778
|
}))
|
|
1736
1779
|
: undefined;
|
|
1737
|
-
const
|
|
1780
|
+
const mutationAttemptObserved = run.observedMutationAttempt === true || completionMutationEvidence?.attemptedMutation === true;
|
|
1781
|
+
const completionGuardTriggered = completionGuard?.triggered === true && !mutationAttemptObserved;
|
|
1738
1782
|
const completionGuardBlocked = completionGuard?.blocked === true;
|
|
1739
1783
|
const fileMutationEffect = completionGuard
|
|
1740
1784
|
? {
|
|
1741
1785
|
status: completionGuardBlocked ? "blocked" as const : completionGuard.expectedMutation ? completionGuardTriggered ? "missing" as const : "observed" as const : "not-applicable" as const,
|
|
1742
1786
|
expected: completionGuard.expectedMutation,
|
|
1743
|
-
attempted: completionGuardBlocked ? false : completionGuard.attemptedMutation ||
|
|
1787
|
+
attempted: completionGuardBlocked ? false : completionGuard.attemptedMutation || mutationAttemptObserved,
|
|
1788
|
+
...(completionMutationEvidence ? { evidence: completionMutationEvidence } : {}),
|
|
1744
1789
|
...(completionGuardBlocked && completionGuard.message ? { message: completionGuard.message } : {}),
|
|
1745
1790
|
...(completionGuardTriggered ? { message: "Subagent completed without making edits for an implementation task." } : {}),
|
|
1746
1791
|
}
|
|
@@ -1890,6 +1935,21 @@ async function runSingleStepInner(
|
|
|
1890
1935
|
: resolvedOutput.savedPath
|
|
1891
1936
|
? "unknown"
|
|
1892
1937
|
: finalResult?.outputState ?? "unknown";
|
|
1938
|
+
const timeoutRecovery = finalResult?.timedOut === true || ctx.timeoutSignal?.aborted === true
|
|
1939
|
+
? buildTimeoutRecoverySummary({
|
|
1940
|
+
termination: "timed-out",
|
|
1941
|
+
evidence: finalMutationEvidence,
|
|
1942
|
+
currentTool: finalResult?.currentTool,
|
|
1943
|
+
currentToolArgs: finalResult?.currentToolArgs,
|
|
1944
|
+
currentPath: finalResult?.currentPath,
|
|
1945
|
+
sessionFile: step.sessionFile,
|
|
1946
|
+
transcriptPath: transcriptWriter ? artifactPaths?.transcriptPath : undefined,
|
|
1947
|
+
artifactPaths,
|
|
1948
|
+
})
|
|
1949
|
+
: undefined;
|
|
1950
|
+
if (timeoutRecovery) outputForSummary = outputForSummary.trim()
|
|
1951
|
+
? `${outputForSummary}\n\n${timeoutRecovery.message}`
|
|
1952
|
+
: timeoutRecovery.message;
|
|
1893
1953
|
const finalizedOutput = finalizeSingleOutput(omitUndefinedProperties({
|
|
1894
1954
|
fullOutput: outputForSummary,
|
|
1895
1955
|
outputPath: step.outputPath,
|
|
@@ -1904,6 +1964,8 @@ async function runSingleStepInner(
|
|
|
1904
1964
|
? await evaluateAcceptance(omitUndefinedProperties({
|
|
1905
1965
|
acceptance: step.effectiveAcceptance,
|
|
1906
1966
|
output: outputForAcceptance,
|
|
1967
|
+
report: structuredAcceptanceReport as import("../../shared/types.ts").AcceptanceReport | undefined,
|
|
1968
|
+
reportError: structuredAcceptanceReportError,
|
|
1907
1969
|
fileOutput: childWrittenOutput !== undefined && step.outputPath
|
|
1908
1970
|
? { content: childWrittenOutput, path: step.outputPath, authoritative: step.outputMode === "file-only" }
|
|
1909
1971
|
: undefined,
|
|
@@ -1999,6 +2061,7 @@ async function runSingleStepInner(
|
|
|
1999
2061
|
timedOut: timedOutAfterAcceptance ? true : finalResult?.timedOut,
|
|
2000
2062
|
stopped: stoppedAfterAcceptance ? true : finalResult?.stopped,
|
|
2001
2063
|
processSignal: finalResult?.processSignal,
|
|
2064
|
+
timeoutRecovery,
|
|
2002
2065
|
turnBudget,
|
|
2003
2066
|
turnBudgetExceeded: turnBudgetExceeded || undefined,
|
|
2004
2067
|
wrapUpRequested: finalResult?.wrapUpRequested || turnBudget?.outcome === "wrap-up-requested" || turnBudget?.outcome === "termination-deferred" || turnBudgetExceeded || undefined,
|
|
@@ -4013,6 +4076,7 @@ async function runSubagent(
|
|
|
4013
4076
|
registerTurnBudgetAbort: (abort) => registerStepTurnBudgetAbort(fi, abort),
|
|
4014
4077
|
timeoutSignal: timeoutAbortController.signal,
|
|
4015
4078
|
stopSignal: stopAbortController.signal,
|
|
4079
|
+
trackedMutationEvidenceForCompletionGuard: false,
|
|
4016
4080
|
timeoutMessage,
|
|
4017
4081
|
stopMessage,
|
|
4018
4082
|
turnBudget: config.turnBudget,
|
|
@@ -4072,6 +4136,7 @@ async function runSubagent(
|
|
|
4072
4136
|
setOptionalProperty(requiredStatusStep(statusPayload, fi), "structuredOutputPath", singleResult.structuredOutputPath);
|
|
4073
4137
|
setOptionalProperty(requiredStatusStep(statusPayload, fi), "structuredOutputSchemaPath", singleResult.structuredOutputSchemaPath);
|
|
4074
4138
|
setOptionalProperty(requiredStatusStep(statusPayload, fi), "acceptance", singleResult.acceptance);
|
|
4139
|
+
setOptionalProperty(requiredStatusStep(statusPayload, fi), "timeoutRecovery", singleResult.timeoutRecovery);
|
|
4075
4140
|
setOptionalProperty(requiredStatusStep(statusPayload, fi), "watchdog", singleResult.watchdog);
|
|
4076
4141
|
setOptionalProperty(requiredStatusStep(statusPayload, fi), "capabilityCeiling", singleResult.capabilityCeiling);
|
|
4077
4142
|
setOptionalProperty(requiredStatusStep(statusPayload, fi), "capabilityAudit", singleResult.capabilityAudit);
|
|
@@ -4087,7 +4152,7 @@ async function runSubagent(
|
|
|
4087
4152
|
}));
|
|
4088
4153
|
if (stopped || childStopped) appendTerminalChildStatusEvent(fi, taskEndTime);
|
|
4089
4154
|
if (singleResult.exitCode !== 0 && failFast && !childStopped) aborted = true;
|
|
4090
|
-
return stopped || childStopped ? { ...singleResult, output: stopMessage, error: stopMessage, exitCode: 1, interrupted: false, timedOut: false, stopped: true, skipped: false } : timedOut ? { ...singleResult, output: timeoutMessage ?? "Subagent timed out.", error: timeoutMessage ?? "Subagent timed out.", exitCode: 1, interrupted: false, timedOut: true, skipped: false } : { ...singleResult, skipped: false };
|
|
4155
|
+
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."), error: singleResult.error ?? timeoutMessage ?? "Subagent timed out.", exitCode: 1, interrupted: false, timedOut: true, skipped: false } : { ...singleResult, skipped: false };
|
|
4091
4156
|
}, globalSemaphore);
|
|
4092
4157
|
|
|
4093
4158
|
flatIndex += dynamicSteps.length;
|
|
@@ -4127,6 +4192,7 @@ async function runSubagent(
|
|
|
4127
4192
|
effects: pr.effects,
|
|
4128
4193
|
execution: pr.execution,
|
|
4129
4194
|
review: pr.review,
|
|
4195
|
+
timeoutRecovery: pr.timeoutRecovery,
|
|
4130
4196
|
structuredOutput: pr.structuredOutput,
|
|
4131
4197
|
structuredOutputPath: pr.structuredOutputPath,
|
|
4132
4198
|
structuredOutputSchemaPath: pr.structuredOutputSchemaPath,
|
|
@@ -4406,6 +4472,7 @@ async function runSubagent(
|
|
|
4406
4472
|
registerTurnBudgetAbort: (abort) => registerStepTurnBudgetAbort(fi, abort),
|
|
4407
4473
|
timeoutSignal: timeoutAbortController.signal,
|
|
4408
4474
|
stopSignal: stopAbortController.signal,
|
|
4475
|
+
trackedMutationEvidenceForCompletionGuard: Boolean(worktreeSetup),
|
|
4409
4476
|
timeoutMessage,
|
|
4410
4477
|
stopMessage,
|
|
4411
4478
|
turnBudget: config.turnBudget,
|
|
@@ -4470,6 +4537,7 @@ async function runSubagent(
|
|
|
4470
4537
|
setOptionalProperty(requiredStatusStep(statusPayload, fi), "structuredOutputPath", singleResult.structuredOutputPath);
|
|
4471
4538
|
setOptionalProperty(requiredStatusStep(statusPayload, fi), "structuredOutputSchemaPath", singleResult.structuredOutputSchemaPath);
|
|
4472
4539
|
setOptionalProperty(requiredStatusStep(statusPayload, fi), "acceptance", singleResult.acceptance);
|
|
4540
|
+
setOptionalProperty(requiredStatusStep(statusPayload, fi), "timeoutRecovery", singleResult.timeoutRecovery);
|
|
4473
4541
|
setOptionalProperty(requiredStatusStep(statusPayload, fi), "watchdog", singleResult.watchdog);
|
|
4474
4542
|
setOptionalProperty(requiredStatusStep(statusPayload, fi), "capabilityCeiling", singleResult.capabilityCeiling);
|
|
4475
4543
|
setOptionalProperty(requiredStatusStep(statusPayload, fi), "capabilityAudit", singleResult.capabilityAudit);
|
|
@@ -4500,7 +4568,7 @@ async function runSubagent(
|
|
|
4500
4568
|
}
|
|
4501
4569
|
|
|
4502
4570
|
if (singleResult.exitCode !== 0 && failFast && !childStopped) aborted = true;
|
|
4503
|
-
return stopped || childStopped ? { ...singleResult, output: stopMessage, error: stopMessage, exitCode: 1, interrupted: false, timedOut: false, stopped: true, skipped: false } : timedOut ? { ...singleResult, output: timeoutMessage ?? "Subagent timed out.", error: timeoutMessage ?? "Subagent timed out.", exitCode: 1, interrupted: false, timedOut: true, skipped: false } : { ...singleResult, skipped: false };
|
|
4571
|
+
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."), error: singleResult.error ?? timeoutMessage ?? "Subagent timed out.", exitCode: 1, interrupted: false, timedOut: true, skipped: false } : { ...singleResult, skipped: false };
|
|
4504
4572
|
},
|
|
4505
4573
|
globalSemaphore,
|
|
4506
4574
|
);
|
|
@@ -4557,10 +4625,11 @@ async function runSubagent(
|
|
|
4557
4625
|
artifactPaths: pr.artifactPaths,
|
|
4558
4626
|
transcriptPath: pr.transcriptPath,
|
|
4559
4627
|
transcriptError: pr.transcriptError,
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
|
|
4628
|
+
effects: pr.effects,
|
|
4629
|
+
execution: pr.execution,
|
|
4630
|
+
review: pr.review,
|
|
4631
|
+
timeoutRecovery: pr.timeoutRecovery,
|
|
4632
|
+
structuredOutput: pr.structuredOutput,
|
|
4564
4633
|
structuredOutputPath: pr.structuredOutputPath,
|
|
4565
4634
|
structuredOutputSchemaPath: pr.structuredOutputSchemaPath,
|
|
4566
4635
|
acceptance: pr.acceptance,
|
|
@@ -4780,7 +4849,7 @@ async function runSubagent(
|
|
|
4780
4849
|
launchContractDigest: singleResult.launchContractDigest,
|
|
4781
4850
|
launchResolvedExtensions: singleResult.launchResolvedExtensions,
|
|
4782
4851
|
runtimeAcknowledgedExtensions: singleResult.runtimeAcknowledgedExtensions,
|
|
4783
|
-
output: stopped || childStopped ? stopMessage : timedOut ? (timeoutMessage ?? "Subagent timed out.") : singleResult.output,
|
|
4852
|
+
output: stopped || childStopped ? stopMessage : timedOut ? singleResult.output || (timeoutMessage ?? "Subagent timed out.") : singleResult.output,
|
|
4784
4853
|
outputState: singleResult.outputState,
|
|
4785
4854
|
error: stopped || childStopped ? stopMessage : timedOut ? (timeoutMessage ?? "Subagent timed out.") : singleResult.error,
|
|
4786
4855
|
protocolError: singleResult.protocolError,
|
|
@@ -4799,6 +4868,7 @@ async function runSubagent(
|
|
|
4799
4868
|
effects: singleResult.effects,
|
|
4800
4869
|
execution: singleResult.execution,
|
|
4801
4870
|
review: singleResult.review,
|
|
4871
|
+
timeoutRecovery: singleResult.timeoutRecovery,
|
|
4802
4872
|
structuredOutput: singleResult.structuredOutput,
|
|
4803
4873
|
structuredOutputPath: singleResult.structuredOutputPath,
|
|
4804
4874
|
structuredOutputSchemaPath: singleResult.structuredOutputSchemaPath,
|
|
@@ -4885,6 +4955,7 @@ async function runSubagent(
|
|
|
4885
4955
|
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "structuredOutputPath", singleResult.structuredOutputPath);
|
|
4886
4956
|
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "structuredOutputSchemaPath", singleResult.structuredOutputSchemaPath);
|
|
4887
4957
|
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "acceptance", singleResult.acceptance);
|
|
4958
|
+
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "timeoutRecovery", singleResult.timeoutRecovery);
|
|
4888
4959
|
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "watchdog", singleResult.watchdog);
|
|
4889
4960
|
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "capabilityCeiling", singleResult.capabilityCeiling);
|
|
4890
4961
|
setOptionalProperty(requiredStatusStep(statusPayload, flatIndex), "capabilityAudit", singleResult.capabilityAudit);
|
|
@@ -5169,6 +5240,7 @@ async function runSubagent(
|
|
|
5169
5240
|
structuredOutputSchemaPath: r.structuredOutputSchemaPath,
|
|
5170
5241
|
acceptance: r.acceptance,
|
|
5171
5242
|
watchdog: r.watchdog,
|
|
5243
|
+
timeoutRecovery: r.timeoutRecovery,
|
|
5172
5244
|
capabilityCeiling: r.capabilityCeiling,
|
|
5173
5245
|
capabilityAudit: r.capabilityAudit,
|
|
5174
5246
|
})),
|
|
@@ -67,9 +67,10 @@ import { readRuntimeAcknowledgedExtensions } from "../shared/runtime-acknowledge
|
|
|
67
67
|
import { assertAgentAllowedByCapabilityCeiling, decodeSubagentCapabilityCeiling, intersectSubagentCapabilityCeilings, resolveCurrentSubagentCapabilityCeiling, SUBAGENT_CAPABILITY_CEILING_ENV } from "../shared/capability-ceiling.ts";
|
|
68
68
|
import { resolveEffectiveThinking } from "../../shared/model-info.ts";
|
|
69
69
|
import { assertThinkingWithinCeiling, decodeThinkingCeiling, intersectThinkingCeilings, SUBAGENT_THINKING_CEILING_ENV } from "../../shared/thinking-ceiling.ts";
|
|
70
|
-
import { MISSING_STRUCTURED_OUTPUT_CALL_ERROR, readStructuredOutput } from "../shared/structured-output.ts";
|
|
70
|
+
import { MISSING_STRUCTURED_OUTPUT_CALL_ERROR, readStructuredOutput, readStructuredOutputAcceptanceReport } from "../shared/structured-output.ts";
|
|
71
71
|
import { formatProcessSignalError, isUnexplainedProcessSignal } from "../shared/process-signal.ts";
|
|
72
72
|
import { readChildToolDiagnosticError } from "../shared/tool-availability.ts";
|
|
73
|
+
import { buildTimeoutRecoverySummary, collectTrackedMutationEvidence, snapshotTrackedMutations } from "../shared/mutation-evidence.ts";
|
|
73
74
|
import { captureSingleOutputSnapshot, extractChildWrittenOutput, finalizeSingleOutput, formatSavedOutputReference, injectOutputPathSystemPrompt, resolveSingleOutput, validateFileOnlyOutputMode, type SingleOutputSnapshot } from "../shared/single-output.ts";
|
|
74
75
|
import {
|
|
75
76
|
buildModelCandidates,
|
|
@@ -368,6 +369,8 @@ async function runSingleAttempt(
|
|
|
368
369
|
steerCapabilityPath: options.steerCapabilityPath,
|
|
369
370
|
steerAckDir: options.steerAckDir,
|
|
370
371
|
structuredOutput: options.structuredOutput,
|
|
372
|
+
fast: options.fast ?? agent.fast,
|
|
373
|
+
modelCandidates: shared.modelCandidates,
|
|
371
374
|
toolBudget: options.toolBudget,
|
|
372
375
|
allowZeroToolBudget: options.allowZeroToolBudget,
|
|
373
376
|
permissionRules,
|
|
@@ -376,6 +379,7 @@ async function runSingleAttempt(
|
|
|
376
379
|
waitToolEnabled: options.waitToolEnabled,
|
|
377
380
|
capabilityCeiling: options.capabilityCeiling,
|
|
378
381
|
thinkingCeiling: options.thinkingCeiling,
|
|
382
|
+
extensionBindings: options.extensionBindings,
|
|
379
383
|
});
|
|
380
384
|
if (!shared.launchWarnings.emitted && warnings.length > 0) {
|
|
381
385
|
for (const warning of warnings) console.warn(`[pi-subagents] ${warning}`);
|
|
@@ -391,6 +395,9 @@ async function runSingleAttempt(
|
|
|
391
395
|
cwd: options.cwd ?? runtimeCwd,
|
|
392
396
|
requireReadTool: Boolean(shared.resolvedSkillNames?.length),
|
|
393
397
|
structuredOutput: Boolean(options.structuredOutput),
|
|
398
|
+
fast: options.fast ?? agent.fast,
|
|
399
|
+
model: modelArg,
|
|
400
|
+
modelCandidates: shared.modelCandidates,
|
|
394
401
|
capabilityCeiling: options.capabilityCeiling,
|
|
395
402
|
inheritedCapabilityCeiling: decodeSubagentCapabilityCeiling(process.env[SUBAGENT_CAPABILITY_CEILING_ENV]),
|
|
396
403
|
agentName: agent.name,
|
|
@@ -432,6 +439,7 @@ async function runSingleAttempt(
|
|
|
432
439
|
task: shared.originalTask ?? task,
|
|
433
440
|
...(modelArg ? { model: modelArg } : {}),
|
|
434
441
|
modelCandidates: shared.modelCandidates,
|
|
442
|
+
...((options.fast ?? agent.fast) !== undefined ? { fast: options.fast ?? agent.fast } : {}),
|
|
435
443
|
...(resolvedThinking ? { thinking: resolvedThinking } : {}),
|
|
436
444
|
...(options.thinkingCeiling ? { thinkingCeiling: options.thinkingCeiling } : {}),
|
|
437
445
|
systemPrompt: effectiveSystemPrompt,
|
|
@@ -445,6 +453,7 @@ async function runSingleAttempt(
|
|
|
445
453
|
...(options.outputPath ? { outputPath: options.outputPath } : {}),
|
|
446
454
|
outputMode: options.outputMode ?? "inline",
|
|
447
455
|
...(options.structuredOutput ? { structuredOutputSchema: options.structuredOutput.schema } : {}),
|
|
456
|
+
...(options.extensionBindings ? { extensionBindings: options.extensionBindings } : {}),
|
|
448
457
|
});
|
|
449
458
|
const result: SingleResult = withRunContext({
|
|
450
459
|
index: options.index ?? 0,
|
|
@@ -524,6 +533,7 @@ async function runSingleAttempt(
|
|
|
524
533
|
return result;
|
|
525
534
|
}
|
|
526
535
|
const spawnEnv = { ...process.env, ...sharedEnv, ...getSubagentDepthEnv(options.maxSubagentDepth) };
|
|
536
|
+
const mutationSnapshot = snapshotTrackedMutations(options.cwd ?? runtimeCwd);
|
|
527
537
|
let observedMutationAttempt = false;
|
|
528
538
|
let structuredOutputToolInvoked = false;
|
|
529
539
|
let structuredOutputMessageStartIndex: number | undefined;
|
|
@@ -1448,6 +1458,9 @@ async function runSingleAttempt(
|
|
|
1448
1458
|
result.structuredOutputFailed = true;
|
|
1449
1459
|
} else {
|
|
1450
1460
|
result.structuredOutput = structured.value;
|
|
1461
|
+
const acceptanceReport = readStructuredOutputAcceptanceReport(options.structuredOutput);
|
|
1462
|
+
(result as SingleResult & { structuredAcceptanceReport?: unknown; structuredAcceptanceReportError?: string }).structuredAcceptanceReport = acceptanceReport.value;
|
|
1463
|
+
(result as SingleResult & { structuredAcceptanceReport?: unknown; structuredAcceptanceReportError?: string }).structuredAcceptanceReportError = acceptanceReport.error;
|
|
1451
1464
|
validatedStructuredOutput = true;
|
|
1452
1465
|
}
|
|
1453
1466
|
}
|
|
@@ -1485,6 +1498,7 @@ async function runSingleAttempt(
|
|
|
1485
1498
|
tokens: progress.tokens,
|
|
1486
1499
|
durationMs: progress.durationMs,
|
|
1487
1500
|
};
|
|
1501
|
+
const mutationEvidence = collectTrackedMutationEvidence(mutationSnapshot, options.cwd ?? runtimeCwd);
|
|
1488
1502
|
|
|
1489
1503
|
const acceptanceOutput = getFinalOutput(result.messages ?? []);
|
|
1490
1504
|
let fullOutput = stripAcceptanceReport(acceptanceOutput);
|
|
@@ -1492,9 +1506,19 @@ async function runSingleAttempt(
|
|
|
1492
1506
|
result.outputState = fullOutput.trim() || result.structuredOutput !== undefined ? "present" : "absent";
|
|
1493
1507
|
if (result.timedOut) {
|
|
1494
1508
|
const timeoutMessage = formatTimeoutMessage(options.timeoutMs ?? 0);
|
|
1509
|
+
result.timeoutRecovery = buildTimeoutRecoverySummary({
|
|
1510
|
+
termination: "timed-out",
|
|
1511
|
+
evidence: mutationEvidence,
|
|
1512
|
+
currentTool: progress.currentTool,
|
|
1513
|
+
currentToolArgs: progress.currentToolArgs,
|
|
1514
|
+
currentPath: progress.currentPath,
|
|
1515
|
+
sessionFile: options.sessionFile,
|
|
1516
|
+
transcriptPath: shared.transcriptWriter ? shared.artifactPaths?.transcriptPath : undefined,
|
|
1517
|
+
artifactPaths: shared.artifactPaths,
|
|
1518
|
+
});
|
|
1495
1519
|
fullOutput = fullOutput.trim()
|
|
1496
|
-
? `${timeoutMessage}\n\nPartial output before timeout:\n${fullOutput}`
|
|
1497
|
-
: timeoutMessage
|
|
1520
|
+
? `${timeoutMessage}\n\n${result.timeoutRecovery.message}\n\nPartial output before timeout:\n${fullOutput}`
|
|
1521
|
+
: `${timeoutMessage}\n\n${result.timeoutRecovery.message}`;
|
|
1498
1522
|
} else if (result.turnBudgetExceeded && result.turnBudget) {
|
|
1499
1523
|
fullOutput = formatTurnBudgetOutput(turnBudgetExceededMessage(result.turnBudget, result.turnBudget.turnCount), fullOutput);
|
|
1500
1524
|
} else if (result.turnBudget?.outcome === "termination-deferred") {
|
|
@@ -1513,9 +1537,11 @@ async function runSingleAttempt(
|
|
|
1513
1537
|
tools: contractTools,
|
|
1514
1538
|
mcpDirectTools: toolPlan.effectiveMcpTools,
|
|
1515
1539
|
toolAvailabilityError,
|
|
1540
|
+
mutationEvidence,
|
|
1516
1541
|
})
|
|
1517
1542
|
: undefined;
|
|
1518
|
-
|
|
1543
|
+
const mutationAttemptObserved = observedMutationAttempt || mutationEvidence.attemptedMutation;
|
|
1544
|
+
let completionGuardTriggered = completionGuard?.triggered === true && !mutationAttemptObserved;
|
|
1519
1545
|
const completionGuardBlocked = completionGuard?.blocked === true;
|
|
1520
1546
|
// The classifier is deliberately narrow, so a read-only review task can
|
|
1521
1547
|
// still be misread as implementation. Arbitrate BEFORE any failure side
|
|
@@ -1547,7 +1573,8 @@ async function runSingleAttempt(
|
|
|
1547
1573
|
: "observed"
|
|
1548
1574
|
: "not-applicable",
|
|
1549
1575
|
expected: completionGuard.expectedMutation,
|
|
1550
|
-
attempted: completionGuardBlocked ? false : completionGuard.attemptedMutation ||
|
|
1576
|
+
attempted: completionGuardBlocked ? false : completionGuard.attemptedMutation || mutationAttemptObserved,
|
|
1577
|
+
evidence: mutationEvidence,
|
|
1551
1578
|
...(completionGuardBlocked && completionGuard.message ? { message: completionGuard.message } : {}),
|
|
1552
1579
|
...(completionGuardTriggered ? { message: "Subagent completed without making edits for an implementation task." } : {}),
|
|
1553
1580
|
...(arbiterRescued ? { resolvedBy: "llm-intent-arbiter" } : {}),
|
|
@@ -1708,7 +1735,7 @@ async function runSyncCompletionInner(
|
|
|
1708
1735
|
dynamicGroup: options.acceptanceContext?.dynamicGroup,
|
|
1709
1736
|
agentContract: options.agentContract,
|
|
1710
1737
|
});
|
|
1711
|
-
const acceptancePrompt = formatAcceptancePrompt(effectiveAcceptance, { reportOptional: isAgentContractV1(options.agentContract) });
|
|
1738
|
+
const acceptancePrompt = formatAcceptancePrompt(effectiveAcceptance, { reportOptional: isAgentContractV1(options.agentContract), structuredOutput: Boolean(options.structuredOutput?.acceptanceReportPath) });
|
|
1712
1739
|
const taskWithAcceptance = acceptancePrompt ? `${task}\n${acceptancePrompt}` : task;
|
|
1713
1740
|
options.onEffectivePrompt?.(taskWithAcceptance);
|
|
1714
1741
|
const sessionEnabled = Boolean(options.sessionFile || options.sessionDir) || shareEnabled;
|
|
@@ -2045,6 +2072,8 @@ async function runSyncCompletionInner(
|
|
|
2045
2072
|
result.acceptance = await evaluateAcceptance({
|
|
2046
2073
|
acceptance: effectiveAcceptance,
|
|
2047
2074
|
output: acceptanceOutputByResult.get(result) ?? result.finalOutput ?? "",
|
|
2075
|
+
report: (result as SingleResult & { structuredAcceptanceReport?: import("../../shared/types.ts").AcceptanceReport; structuredAcceptanceReportError?: string }).structuredAcceptanceReport,
|
|
2076
|
+
reportError: (result as SingleResult & { structuredAcceptanceReport?: import("../../shared/types.ts").AcceptanceReport; structuredAcceptanceReportError?: string }).structuredAcceptanceReportError,
|
|
2048
2077
|
fileOutput: childWrittenOutput !== undefined && options.outputPath
|
|
2049
2078
|
? { content: childWrittenOutput, path: options.outputPath, authoritative: options.outputMode === "file-only" }
|
|
2050
2079
|
: undefined,
|
|
@@ -2,7 +2,7 @@ import * as fs from "node:fs";
|
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import type { ForegroundResumeChild, ForegroundResumeRun, SubagentState } from "../../shared/types.ts";
|
|
4
4
|
import { DIRS } from "../../shared/types.ts";
|
|
5
|
-
import {
|
|
5
|
+
import { writePrivateAtomicJson } from "../../shared/atomic-json.ts";
|
|
6
6
|
import { utf8Tail } from "../../shared/utf8.ts";
|
|
7
7
|
|
|
8
8
|
export const MAX_REMEMBERED_FOREGROUND_RUNS = 50;
|
|
@@ -52,6 +52,7 @@ function compactChild(child: ForegroundResumeChild): ForegroundResumeChild {
|
|
|
52
52
|
...(child.transcriptError ? { transcriptError: child.transcriptError } : {}),
|
|
53
53
|
...(child.acceptance ? { acceptance: child.acceptance } : {}),
|
|
54
54
|
...(child.launchContractDigest ? { launchContractDigest: child.launchContractDigest } : {}),
|
|
55
|
+
...(child.extensionBindings ? { extensionBindings: child.extensionBindings } : {}),
|
|
55
56
|
...(child.capabilityCeiling ? { capabilityCeiling: child.capabilityCeiling } : {}),
|
|
56
57
|
...(child.updatedAt !== undefined ? { updatedAt: child.updatedAt } : {}),
|
|
57
58
|
};
|
|
@@ -118,7 +119,7 @@ export function persistForegroundRunHistory(state: SubagentState, options: { res
|
|
|
118
119
|
if (compact) merged.set(compact.runId, compact);
|
|
119
120
|
}
|
|
120
121
|
const runs = sortAndBound([...merged.values()], limit);
|
|
121
|
-
|
|
122
|
+
writePrivateAtomicJson(historyPath(resultsDir), { version: HISTORY_VERSION, runs });
|
|
122
123
|
}
|
|
123
124
|
|
|
124
125
|
export function restoreForegroundRunHistory(state: SubagentState, options: { resultsDir?: string; sessionId?: string | null; limit?: number } = {}): number {
|