pi-subagents 0.57.0 → 0.58.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 +39 -0
- package/docs/agents.md +13 -6
- package/docs/extension-api.md +39 -0
- package/docs/models.md +3 -3
- package/docs/tool-reference.md +3 -2
- package/docs/workflows.md +24 -0
- package/package.json +1 -1
- package/skills/pi-subagents/SKILL.md +2 -0
- package/skills/pi-subagents/references/execution-controls.md +1 -1
- package/skills/pi-subagents/references/management-authoring-rpc.md +1 -0
- package/skills/pi-subagents/references/prompting-and-roles.md +2 -2
- package/src/agents/agent-management.ts +23 -0
- package/src/agents/agent-serializer.ts +5 -0
- package/src/agents/agents.ts +38 -3
- package/src/agents/runtime-agent-events.ts +70 -0
- package/src/agents/runtime-agent-registry.ts +10 -2
- package/src/api/agents.ts +10 -5
- package/src/api/preflight.ts +26 -1
- package/src/extension/index.ts +15 -4
- package/src/extension/rpc.ts +35 -14
- package/src/extension/schemas.ts +2 -2
- package/src/extension/tool-description.ts +8 -4
- package/src/integrations/herdr-status.ts +5 -0
- package/src/runs/background/async-execution.ts +29 -12
- package/src/runs/background/async-resume.ts +6 -2
- package/src/runs/background/async-status.ts +2 -0
- package/src/runs/background/chain-append.ts +2 -0
- package/src/runs/background/notify.ts +26 -3
- package/src/runs/background/result-delivery-ownership.ts +45 -0
- package/src/runs/background/result-watcher.ts +27 -10
- package/src/runs/background/subagent-runner.ts +71 -21
- package/src/runs/foreground/execution.ts +20 -1
- package/src/runs/foreground/subagent-executor.ts +57 -26
- package/src/runs/foreground/workflow-detach-reconcile.ts +128 -17
- package/src/runs/shared/completion-guard.ts +4 -3
- package/src/runs/shared/dynamic-fanout.ts +3 -3
- package/src/runs/shared/fast-mode-extension.ts +5 -5
- package/src/runs/shared/launch-cwd.ts +16 -0
- package/src/runs/shared/long-running-guard.ts +2 -1
- package/src/runs/shared/mcp-config-sources.ts +386 -0
- package/src/runs/shared/mcp-direct-tool-allowlist.ts +155 -42
- package/src/runs/shared/model-exclusions.ts +12 -0
- package/src/runs/shared/model-fallback.ts +16 -4
- package/src/runs/shared/parallel-utils.ts +8 -1
- package/src/runs/shared/pi-args.ts +61 -6
- package/src/runs/shared/single-output.ts +17 -0
- package/src/runs/shared/subagent-prompt-runtime.ts +85 -9
- package/src/shared/formatters.ts +6 -0
- package/src/shared/launch-contract.ts +4 -0
- package/src/shared/types.ts +42 -1
- package/src/shared/utils.ts +6 -29
- package/src/slash/subagents-admin.ts +3 -0
- package/src/tui/render.ts +14 -6
- package/src/workflows/scripted-workflow.ts +52 -5
- package/src/workflows/workflow-receipt.ts +39 -4
|
@@ -14,6 +14,7 @@ import { createChildTranscriptWriter, type ChildTranscriptWriter } from "../../s
|
|
|
14
14
|
import { closeSteerInbox, consumeInterruptRequest, consumeSteerRequests, deliverInterruptRequest, deliverStopRequest, deliverTimeoutRequest, enqueueStepSteer, steerAcksDir, steerCapabilityPath, stepSteerInboxDir, watchAsyncControlInbox, type SteerAck, type SteerCapability, type SteerRequest, type StopRequest } from "./control-channel.ts";
|
|
15
15
|
import { appendJsonl as appendRawJsonl, formatOutputArtifactContent, getArtifactPaths, writeArtifact, writeMetadata } from "../../shared/artifacts.ts";
|
|
16
16
|
import { PI_CODING_AGENT_PACKAGE, getPiSpawnCommand, resolveInstalledPiPackageRoot } from "../shared/pi-spawn.ts";
|
|
17
|
+
import { preflightLaunchCwd } from "../shared/launch-cwd.ts";
|
|
17
18
|
import { captureSingleOutputSnapshot, extractChildWrittenOutput, finalizeSingleOutput, formatSavedOutputReference, injectOutputPathSystemPrompt, injectSingleOutputInstruction, resolveSingleOutput, type SingleOutputSnapshot } from "../shared/single-output.ts";
|
|
18
19
|
import {
|
|
19
20
|
type ActivityState,
|
|
@@ -49,6 +50,7 @@ import {
|
|
|
49
50
|
type SteeringTargetState,
|
|
50
51
|
type SteeringTargetStatus,
|
|
51
52
|
type SubagentChildStatusEvent,
|
|
53
|
+
type SettlementDiagnostic,
|
|
52
54
|
DEFAULT_MAX_OUTPUT,
|
|
53
55
|
type MaxOutputConfig,
|
|
54
56
|
SUBAGENT_LIFECYCLE_ARTIFACT_VERSION,
|
|
@@ -101,7 +103,7 @@ import { createOwnedProcessTreeController, type OwnedProcessTreeController } fro
|
|
|
101
103
|
import { createSteeringStatus, recordSteeringRequest, steeringStatus, terminalSteeringNoticeState, updateSteeringTarget } from "./steering.ts";
|
|
102
104
|
import { attachPostExitStdioGuard, trySignalChild } from "../../shared/post-exit-stdio-guard.ts";
|
|
103
105
|
import { PROMPT_REDACTED, detectSubagentError, extractTextFromContent, extractToolArgsPreview, getFinalOutput, hasEmptyTerminalAssistantResponse, readStatus } from "../../shared/utils.ts";
|
|
104
|
-
import { evaluateCompletionMutationGuard, validateImplementationToolContract } from "../shared/completion-guard.ts";
|
|
106
|
+
import { evaluateCompletionMutationGuard, expectsImplementationMutation, hasMutationToolCapability, validateImplementationToolContract } from "../shared/completion-guard.ts";
|
|
105
107
|
import {
|
|
106
108
|
createMutatingFailureState,
|
|
107
109
|
didMutatingToolFail,
|
|
@@ -124,7 +126,7 @@ import {
|
|
|
124
126
|
formatWorktreeTaskCwdConflict,
|
|
125
127
|
type WorktreeSetup,
|
|
126
128
|
} from "../shared/worktree.ts";
|
|
127
|
-
import { resolveEffectiveThinking } from "../../shared/model-info.ts";
|
|
129
|
+
import { findModelInfo, resolveEffectiveThinking } from "../../shared/model-info.ts";
|
|
128
130
|
import { assertThinkingWithinCeiling, decodeThinkingCeiling, SUBAGENT_THINKING_CEILING_ENV } from "../../shared/thinking-ceiling.ts";
|
|
129
131
|
import { launchBindingDigest } from "../../shared/launch-contract.ts";
|
|
130
132
|
import { writeInitialProgressFile } from "../../shared/settings.ts";
|
|
@@ -543,6 +545,7 @@ interface RunPiStreamingResult {
|
|
|
543
545
|
observedMutationAttempt?: boolean;
|
|
544
546
|
structuredOutputToolInvoked?: boolean;
|
|
545
547
|
structuredOutputMessageStartIndex?: number;
|
|
548
|
+
structuredOutput?: unknown;
|
|
546
549
|
watchdog?: ChildWatchdogStateSnapshot;
|
|
547
550
|
runtimeAcknowledgedExtensions?: RuntimeAcknowledgedChildExtensionsV1;
|
|
548
551
|
processInstanceId: string;
|
|
@@ -553,6 +556,7 @@ interface RunPiStreamingResult {
|
|
|
553
556
|
currentToolArgs?: string;
|
|
554
557
|
currentPath?: string;
|
|
555
558
|
afterCompactionSettlement?: boolean;
|
|
559
|
+
effects?: import("../../shared/types.ts").EffectsProjection;
|
|
556
560
|
}
|
|
557
561
|
|
|
558
562
|
const MAX_CHILD_FAILURE_DIAGNOSTIC_CHARS = 8_192;
|
|
@@ -561,16 +565,18 @@ function formatChildFailureDiagnostic(input: {
|
|
|
561
565
|
error: string | undefined;
|
|
562
566
|
afterCompactionSettlement?: boolean;
|
|
563
567
|
missingFileOnlyOutput?: string;
|
|
568
|
+
missingStructuredOutput?: string;
|
|
564
569
|
}): string | undefined {
|
|
565
|
-
if (!input.error) return undefined;
|
|
566
570
|
const notes = [
|
|
567
571
|
input.afterCompactionSettlement ? "Child failure followed session compaction and agent settlement." : undefined,
|
|
568
572
|
input.missingFileOnlyOutput ? `Required file-only output was not produced: ${input.missingFileOnlyOutput.slice(0, 2_048)}` : undefined,
|
|
573
|
+
input.missingStructuredOutput ? `Required structured output was not produced: ${input.missingStructuredOutput.slice(0, 2_048)}` : undefined,
|
|
569
574
|
].filter((note): note is string => Boolean(note));
|
|
570
575
|
if (notes.length === 0) return input.error;
|
|
571
576
|
const context = notes.join("\n");
|
|
572
577
|
const errorLimit = MAX_CHILD_FAILURE_DIAGNOSTIC_CHARS - (context ? context.length + 1 : 0);
|
|
573
|
-
|
|
578
|
+
const baseError = input.error || "Subagent failed.";
|
|
579
|
+
return `${baseError.slice(0, Math.max(0, errorLimit))}${context ? `\n${context}` : ""}`;
|
|
574
580
|
}
|
|
575
581
|
|
|
576
582
|
function runPiStreaming(
|
|
@@ -596,6 +602,7 @@ function runPiStreaming(
|
|
|
596
602
|
orcaProgressTab?: OrcaProgressTab,
|
|
597
603
|
expectedModelForVerification?: string,
|
|
598
604
|
modelVerificationRegistry?: Array<{ provider: string; id: string; fullId: string }>,
|
|
605
|
+
mutationTools?: readonly string[],
|
|
599
606
|
): Promise<RunPiStreamingResult> {
|
|
600
607
|
return new Promise((resolve) => {
|
|
601
608
|
const startedAt = Date.now();
|
|
@@ -791,7 +798,7 @@ function runPiStreaming(
|
|
|
791
798
|
structuredOutputToolInvoked = true;
|
|
792
799
|
structuredOutputMessageStartIndex = messages.length;
|
|
793
800
|
}
|
|
794
|
-
observedMutationAttempt = observedMutationAttempt || isMutatingTool(event.toolName, event.args);
|
|
801
|
+
observedMutationAttempt = observedMutationAttempt || isMutatingTool(event.toolName, event.args, mutationTools);
|
|
795
802
|
const toolArgs = extractToolArgsPreview(event.args ?? {});
|
|
796
803
|
writeOutputLine(toolArgs ? `${event.toolName}: ${toolArgs}` : event.toolName);
|
|
797
804
|
return;
|
|
@@ -1297,7 +1304,7 @@ interface SingleStepContext {
|
|
|
1297
1304
|
nestedRoute?: NestedRouteInfo;
|
|
1298
1305
|
capabilityCeiling?: ResolvedSubagentCapabilityCeiling;
|
|
1299
1306
|
runFanoutBudget?: RunFanoutBudgetDescriptor;
|
|
1300
|
-
onAttemptStart?: (attempt: { model?: string; thinking?: string }) => void;
|
|
1307
|
+
onAttemptStart?: (attempt: { model?: string; thinking?: string; contextLimit?: number }) => void;
|
|
1301
1308
|
onChildEvent?: (event: ChildEvent) => void;
|
|
1302
1309
|
onWriterProcess?: (writer: { state: "none" | "spawning" } | { state: "running"; pid: number }) => void;
|
|
1303
1310
|
onExternalProcess?: (process: ExternalProcessStatus) => void;
|
|
@@ -1399,6 +1406,8 @@ async function runSingleStepInner(
|
|
|
1399
1406
|
model: step.model,
|
|
1400
1407
|
modelCandidates: step.modelCandidates,
|
|
1401
1408
|
mcpDirectTools: step.mcpDirectTools,
|
|
1409
|
+
mcpConfig: step.mcpConfig,
|
|
1410
|
+
runtimeServerNames: step.runtimeServerNames,
|
|
1402
1411
|
cwd: step.cwd ?? ctx.cwd,
|
|
1403
1412
|
requireReadTool: Boolean(step.skills?.length),
|
|
1404
1413
|
structuredOutput: Boolean(effectiveStructuredOutput),
|
|
@@ -1594,6 +1603,10 @@ async function runSingleStepInner(
|
|
|
1594
1603
|
});
|
|
1595
1604
|
}
|
|
1596
1605
|
|
|
1606
|
+
const effectiveCwd = step.cwd ?? ctx.cwd;
|
|
1607
|
+
const cwdError = preflightLaunchCwd(step.requestedCwd ?? effectiveCwd, effectiveCwd);
|
|
1608
|
+
if (cwdError) return { agent: step.agent, output: cwdError, error: cwdError, exitCode: 1, context: step.context };
|
|
1609
|
+
|
|
1597
1610
|
const candidates = step.modelCandidates !== undefined
|
|
1598
1611
|
? step.modelCandidates.length > 0 ? step.modelCandidates : [undefined]
|
|
1599
1612
|
: step.model
|
|
@@ -1636,7 +1649,11 @@ async function runSingleStepInner(
|
|
|
1636
1649
|
const message = error instanceof Error ? error.message : String(error);
|
|
1637
1650
|
return omitUndefinedProperties({ agent: step.agent, output: message, error: message, exitCode: 1, context: step.context, thinkingCeiling: step.thinkingCeiling });
|
|
1638
1651
|
}
|
|
1639
|
-
ctx.onAttemptStart?.(omitUndefinedProperties({
|
|
1652
|
+
ctx.onAttemptStart?.(omitUndefinedProperties({
|
|
1653
|
+
model: candidate,
|
|
1654
|
+
thinking: resolveEffectiveThinking(candidate, step.thinking),
|
|
1655
|
+
contextLimit: findModelInfo(candidate, step.modelVerificationRegistry)?.contextWindow,
|
|
1656
|
+
}));
|
|
1640
1657
|
const outputSnapshot = captureSingleOutputSnapshot(step.outputPath);
|
|
1641
1658
|
if (effectiveStructuredOutput) {
|
|
1642
1659
|
try {
|
|
@@ -1665,6 +1682,7 @@ async function runSingleStepInner(
|
|
|
1665
1682
|
sessionFile: step.sessionFile,
|
|
1666
1683
|
model: candidate,
|
|
1667
1684
|
inheritProjectContext: step.inheritProjectContext,
|
|
1685
|
+
inheritGlobalContext: step.inheritGlobalContext,
|
|
1668
1686
|
inheritSkills: step.inheritSkills,
|
|
1669
1687
|
requireReadTool: Boolean(step.skills?.length),
|
|
1670
1688
|
tools: step.tools,
|
|
@@ -1675,6 +1693,8 @@ async function runSingleStepInner(
|
|
|
1675
1693
|
systemPrompt: appendTurnBudgetSystemPrompt(step.systemPrompt ?? "", ctx.turnBudget),
|
|
1676
1694
|
systemPromptMode: step.systemPromptMode,
|
|
1677
1695
|
mcpDirectTools: step.mcpDirectTools,
|
|
1696
|
+
mcpConfig: step.mcpConfig,
|
|
1697
|
+
runtimeServerNames: step.runtimeServerNames,
|
|
1678
1698
|
capabilityCeiling: step.capabilityCeiling ?? ctx.capabilityCeiling,
|
|
1679
1699
|
cwd: step.cwd ?? ctx.cwd,
|
|
1680
1700
|
promptFileStem: step.agent,
|
|
@@ -1718,6 +1738,8 @@ async function runSingleStepInner(
|
|
|
1718
1738
|
model: step.model,
|
|
1719
1739
|
modelCandidates: step.modelCandidates,
|
|
1720
1740
|
mcpDirectTools: step.mcpDirectTools,
|
|
1741
|
+
mcpConfig: step.mcpConfig,
|
|
1742
|
+
runtimeServerNames: step.runtimeServerNames,
|
|
1721
1743
|
cwd: step.cwd ?? ctx.cwd,
|
|
1722
1744
|
requireReadTool: Boolean(step.skills?.length),
|
|
1723
1745
|
structuredOutput: Boolean(effectiveStructuredOutput),
|
|
@@ -1737,6 +1759,7 @@ async function runSingleStepInner(
|
|
|
1737
1759
|
systemPrompt: appendTurnBudgetSystemPrompt(step.systemPrompt ?? "", ctx.turnBudget),
|
|
1738
1760
|
systemPromptMode: step.systemPromptMode,
|
|
1739
1761
|
inheritProjectContext: step.inheritProjectContext,
|
|
1762
|
+
inheritGlobalContext: step.inheritGlobalContext,
|
|
1740
1763
|
inheritSkills: step.inheritSkills,
|
|
1741
1764
|
skills: step.skills,
|
|
1742
1765
|
tools: toolPlan.effectiveToolAllowlist,
|
|
@@ -1773,6 +1796,7 @@ async function runSingleStepInner(
|
|
|
1773
1796
|
ctx.orcaProgressTab,
|
|
1774
1797
|
expectedModelForVerification,
|
|
1775
1798
|
step.modelVerificationRegistry,
|
|
1799
|
+
step.mutationTools,
|
|
1776
1800
|
);
|
|
1777
1801
|
if (run.processCloseObservedAt !== undefined) {
|
|
1778
1802
|
writerProcesses.push({
|
|
@@ -1863,6 +1887,7 @@ async function runSingleStepInner(
|
|
|
1863
1887
|
: undefined;
|
|
1864
1888
|
const completionGuardEnabled = isAgentContractV1(step.agentContract) ? step.completionGuard === true : step.completionGuard !== false;
|
|
1865
1889
|
const completionToolPlan = resolvedTaskToolPlan;
|
|
1890
|
+
const completionTools = completionToolPlan ? (completionToolPlan.explicitToolAllowlist ? completionToolPlan.effectiveToolAllowlist : undefined) : step.tools;
|
|
1866
1891
|
const mutationEvidence = collectTrackedMutationEvidence(mutationSnapshot, step.cwd ?? ctx.cwd);
|
|
1867
1892
|
finalMutationEvidence = mutationEvidence;
|
|
1868
1893
|
const completionMutationEvidence = ctx.trackedMutationEvidenceForCompletionGuard === false ? undefined : mutationEvidence;
|
|
@@ -1871,8 +1896,9 @@ async function runSingleStepInner(
|
|
|
1871
1896
|
agent: step.agent,
|
|
1872
1897
|
task: taskForCompletionGuard,
|
|
1873
1898
|
messages: run.messages,
|
|
1874
|
-
tools:
|
|
1899
|
+
tools: completionTools,
|
|
1875
1900
|
mcpDirectTools: completionToolPlan?.effectiveMcpTools ?? step.mcpDirectTools,
|
|
1901
|
+
mutationTools: step.mutationTools,
|
|
1876
1902
|
toolAvailabilityError,
|
|
1877
1903
|
mutationEvidence: completionMutationEvidence,
|
|
1878
1904
|
}))
|
|
@@ -1880,6 +1906,9 @@ async function runSingleStepInner(
|
|
|
1880
1906
|
const mutationAttemptObserved = run.observedMutationAttempt === true || completionMutationEvidence?.attemptedMutation === true;
|
|
1881
1907
|
const completionGuardTriggered = completionGuard?.triggered === true && !mutationAttemptObserved;
|
|
1882
1908
|
const completionGuardBlocked = completionGuard?.blocked === true;
|
|
1909
|
+
const mutationExpected = completionGuard?.expectedMutation ?? (completionGuardEnabled
|
|
1910
|
+
&& hasMutationToolCapability(completionTools, completionToolPlan?.effectiveMcpTools ?? step.mcpDirectTools)
|
|
1911
|
+
&& expectsImplementationMutation(step.agent, taskForCompletionGuard));
|
|
1883
1912
|
const fileMutationEffect = completionGuard
|
|
1884
1913
|
? {
|
|
1885
1914
|
status: completionGuardBlocked ? "blocked" as const : completionGuard.expectedMutation ? completionGuardTriggered ? "missing" as const : "observed" as const : "not-applicable" as const,
|
|
@@ -1940,7 +1969,24 @@ async function runSingleStepInner(
|
|
|
1940
1969
|
toolBudgetBlocked = Boolean(blockedMessage);
|
|
1941
1970
|
toolBudget = toolBudgetState(step.toolBudget, toolMessages.length, blockedMessage ? (blockedMessage as { toolName?: string }).toolName : undefined);
|
|
1942
1971
|
}
|
|
1943
|
-
|
|
1972
|
+
const requiredOutput = step.outputMode === "file-only" && step.outputPath
|
|
1973
|
+
? { kind: "file-only" as const, path: step.outputPath, missing: !fs.existsSync(step.outputPath) }
|
|
1974
|
+
: effectiveStructuredOutput
|
|
1975
|
+
? { kind: "structured" as const, path: effectiveStructuredOutput.outputPath, missing: !fs.existsSync(effectiveStructuredOutput.outputPath) }
|
|
1976
|
+
: undefined;
|
|
1977
|
+
const settlementDiagnostic: SettlementDiagnostic | undefined = effectiveExitCode !== 0 || completionGuardTriggered || completionGuardBlocked
|
|
1978
|
+
? {
|
|
1979
|
+
finalTextPresent: Boolean(stripAcceptanceReport(run.finalOutput).trim()),
|
|
1980
|
+
mutation: {
|
|
1981
|
+
expected: mutationExpected,
|
|
1982
|
+
attempted: completionGuard?.attemptedMutation === true || mutationAttemptObserved,
|
|
1983
|
+
observed: mutationEvidence.attemptedMutation,
|
|
1984
|
+
},
|
|
1985
|
+
...(requiredOutput ? { requiredOutput } : {}),
|
|
1986
|
+
afterCompactionSettlement: run.afterCompactionSettlement === true,
|
|
1987
|
+
}
|
|
1988
|
+
: undefined;
|
|
1989
|
+
finalResult = { ...run, exitCode: effectiveExitCode, model: candidate ?? run.model, error, structuredOutput, runtimeAcknowledgedExtensions, ...(step.agentContract ? { agentContract: step.agentContract } : {}), ...(fileMutationEffect || settlementDiagnostic ? { effects: { ...(fileMutationEffect ? { fileMutation: fileMutationEffect } : {}), ...(settlementDiagnostic ? { settlementDiagnostic } : {}) } } : {}) } as RunPiStreamingResult;
|
|
1944
1990
|
if (run.turnBudgetExceeded) break modelAttemptsLoop;
|
|
1945
1991
|
if (run.stopped || run.timedOut || ctx.timeoutSignal?.aborted || ctx.stopSignal?.aborted || ctx.skipAcceptance?.()) break modelAttemptsLoop;
|
|
1946
1992
|
if (attempt.success || completionGuardTriggered) break modelAttemptsLoop;
|
|
@@ -2105,13 +2151,12 @@ async function runSingleStepInner(
|
|
|
2105
2151
|
: finalResult?.error ?? (intercomDetachReceipt ? INTERCOM_DETACH_RECEIPT : undefined);
|
|
2106
2152
|
const effectiveFinalError = formatChildFailureDiagnostic({
|
|
2107
2153
|
error: baseFinalError,
|
|
2108
|
-
afterCompactionSettlement: finalResult?.afterCompactionSettlement,
|
|
2109
|
-
missingFileOnlyOutput: effectiveFinalExitCode !== 0
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
? step.outputPath
|
|
2154
|
+
afterCompactionSettlement: effectiveFinalExitCode !== 0 ? finalResult?.afterCompactionSettlement : undefined,
|
|
2155
|
+
missingFileOnlyOutput: effectiveFinalExitCode !== 0 && finalResult?.effects?.settlementDiagnostic?.requiredOutput?.kind === "file-only" && finalResult.effects.settlementDiagnostic.requiredOutput.missing
|
|
2156
|
+
? finalResult.effects.settlementDiagnostic.requiredOutput.path
|
|
2157
|
+
: undefined,
|
|
2158
|
+
missingStructuredOutput: effectiveFinalExitCode !== 0 && finalResult?.effects?.settlementDiagnostic?.requiredOutput?.kind === "structured" && finalResult.effects.settlementDiagnostic.requiredOutput.missing
|
|
2159
|
+
? finalResult.effects.settlementDiagnostic.requiredOutput.path
|
|
2115
2160
|
: undefined,
|
|
2116
2161
|
});
|
|
2117
2162
|
|
|
@@ -2514,6 +2559,7 @@ async function runSubagent(
|
|
|
2514
2559
|
...(transcriptPath ? { transcriptPath } : {}),
|
|
2515
2560
|
skills: task.skills,
|
|
2516
2561
|
model: task.model,
|
|
2562
|
+
...(task.contextLimit !== undefined ? { contextLimit: task.contextLimit } : {}),
|
|
2517
2563
|
thinking: task.thinking,
|
|
2518
2564
|
attemptedModels: task.modelCandidates && task.modelCandidates.length > 0 ? task.modelCandidates : task.model ? [task.model] : undefined,
|
|
2519
2565
|
recentTools: [],
|
|
@@ -2531,6 +2577,7 @@ async function runSubagent(
|
|
|
2531
2577
|
label: step.label ?? step.parallel.label ?? `Dynamic fanout (${step.collect.as})`,
|
|
2532
2578
|
outputName: step.collect.as,
|
|
2533
2579
|
structured: Boolean(step.collect.outputSchema),
|
|
2580
|
+
...(step.parallel.contextLimit !== undefined ? { contextLimit: step.parallel.contextLimit } : {}),
|
|
2534
2581
|
...(step.agentContract ? { agentContract: step.agentContract } : {}),
|
|
2535
2582
|
...(step.capabilityCeiling ? { capabilityCeiling: step.capabilityCeiling } : {}),
|
|
2536
2583
|
...(step.thinkingCeiling ? { thinkingCeiling: step.thinkingCeiling } : {}),
|
|
@@ -2563,6 +2610,7 @@ async function runSubagent(
|
|
|
2563
2610
|
...(transcriptPath ? { transcriptPath } : {}),
|
|
2564
2611
|
skills: step.skills,
|
|
2565
2612
|
model: step.model,
|
|
2613
|
+
...(step.contextLimit !== undefined ? { contextLimit: step.contextLimit } : {}),
|
|
2566
2614
|
thinking: step.thinking,
|
|
2567
2615
|
attemptedModels: step.modelCandidates && step.modelCandidates.length > 0 ? step.modelCandidates : step.model ? [step.model] : undefined,
|
|
2568
2616
|
recentTools: [],
|
|
@@ -3424,11 +3472,12 @@ async function runSubagent(
|
|
|
3424
3472
|
}
|
|
3425
3473
|
pendingStepSteers.push(...remaining);
|
|
3426
3474
|
};
|
|
3427
|
-
const updateStepModel = (flatIndex: number, model: string | undefined, thinking: string | undefined, now = Date.now()): void => {
|
|
3475
|
+
const updateStepModel = (flatIndex: number, model: string | undefined, thinking: string | undefined, contextLimit?: number, now = Date.now()): void => {
|
|
3428
3476
|
const step = statusPayload.steps[flatIndex];
|
|
3429
3477
|
if (!step) return;
|
|
3430
3478
|
setOptionalProperty(step, "model", model);
|
|
3431
3479
|
setOptionalProperty(step, "thinking", thinking);
|
|
3480
|
+
setOptionalProperty(step, "contextLimit", contextLimit);
|
|
3432
3481
|
statusPayload.lastUpdate = now;
|
|
3433
3482
|
writeStatusPayload();
|
|
3434
3483
|
};
|
|
@@ -3514,7 +3563,7 @@ async function runSubagent(
|
|
|
3514
3563
|
return;
|
|
3515
3564
|
}
|
|
3516
3565
|
if (event.type === "tool_execution_start" && event.toolName) {
|
|
3517
|
-
const mutates = isMutatingTool(event.toolName, event.args);
|
|
3566
|
+
const mutates = isMutatingTool(event.toolName, event.args, flatSteps[flatIndex]?.mutationTools);
|
|
3518
3567
|
const currentPath = resolveCurrentPath(event.toolName, event.args);
|
|
3519
3568
|
const argsPreview = extractToolArgsPreview(event.args ?? {});
|
|
3520
3569
|
const blocksSupervisor = isBlockingSupervisorTool(event.toolName, event.args);
|
|
@@ -4059,6 +4108,7 @@ async function runSubagent(
|
|
|
4059
4108
|
...(transcriptPath ? { transcriptPath } : {}),
|
|
4060
4109
|
...(task.skills ? { skills: task.skills } : {}),
|
|
4061
4110
|
...(task.model ? { model: task.model } : {}),
|
|
4111
|
+
...(task.contextLimit !== undefined ? { contextLimit: task.contextLimit } : {}),
|
|
4062
4112
|
...(task.thinking ? { thinking: task.thinking } : {}),
|
|
4063
4113
|
...(task.thinkingCeiling ? { thinkingCeiling: task.thinkingCeiling } : {}),
|
|
4064
4114
|
...(task.modelCandidates && task.modelCandidates.length > 0 ? { attemptedModels: task.modelCandidates } : task.model ? { attemptedModels: [task.model] } : {}),
|
|
@@ -4188,7 +4238,7 @@ async function runSubagent(
|
|
|
4188
4238
|
stopMessage,
|
|
4189
4239
|
turnBudget: config.turnBudget,
|
|
4190
4240
|
toolTimeoutMs: task.toolTimeoutMs ?? config.toolTimeoutMs,
|
|
4191
|
-
onAttemptStart: (attempt) => updateStepModel(fi, attempt.model, attempt.thinking),
|
|
4241
|
+
onAttemptStart: (attempt) => updateStepModel(fi, attempt.model, attempt.thinking, attempt.contextLimit),
|
|
4192
4242
|
onChildEvent: (event) => updateStepFromChildEvent(fi, event),
|
|
4193
4243
|
onWriterProcess,
|
|
4194
4244
|
onExternalProcess: (process) => updateExternalProcess(fi, process),
|
|
@@ -4584,7 +4634,7 @@ async function runSubagent(
|
|
|
4584
4634
|
stopMessage,
|
|
4585
4635
|
turnBudget: config.turnBudget,
|
|
4586
4636
|
toolTimeoutMs: taskForRun.toolTimeoutMs ?? config.toolTimeoutMs,
|
|
4587
|
-
onAttemptStart: (attempt) => updateStepModel(fi, attempt.model, attempt.thinking),
|
|
4637
|
+
onAttemptStart: (attempt) => updateStepModel(fi, attempt.model, attempt.thinking, attempt.contextLimit),
|
|
4588
4638
|
onChildEvent: (event) => updateStepFromChildEvent(fi, event),
|
|
4589
4639
|
onWriterProcess,
|
|
4590
4640
|
onExternalProcess: (process) => updateExternalProcess(fi, process),
|
|
@@ -4939,7 +4989,7 @@ async function runSubagent(
|
|
|
4939
4989
|
stopMessage,
|
|
4940
4990
|
turnBudget: config.turnBudget,
|
|
4941
4991
|
toolTimeoutMs: seqStep.toolTimeoutMs ?? config.toolTimeoutMs,
|
|
4942
|
-
onAttemptStart: (attempt) => updateStepModel(flatIndex, attempt.model, attempt.thinking),
|
|
4992
|
+
onAttemptStart: (attempt) => updateStepModel(flatIndex, attempt.model, attempt.thinking, attempt.contextLimit),
|
|
4943
4993
|
onChildEvent: (event) => updateStepFromChildEvent(flatIndex, event),
|
|
4944
4994
|
onWriterProcess,
|
|
4945
4995
|
onExternalProcess: (process) => updateExternalProcess(flatIndex, process),
|
|
@@ -58,6 +58,7 @@ import { effectiveToolTimeoutMs, formatToolTimeoutMessage, resolveToolTimeoutMs,
|
|
|
58
58
|
import { evaluateCompletionMutationGuard, validateImplementationToolContract } from "../shared/completion-guard.ts";
|
|
59
59
|
import { arbitrateCompletionGuardRescue } from "../shared/llm-intent-arbiter.ts";
|
|
60
60
|
import { getPiSpawnCommand } from "../shared/pi-spawn.ts";
|
|
61
|
+
import { preflightLaunchCwd } from "../shared/launch-cwd.ts";
|
|
61
62
|
import { createJsonlWriter } from "../../shared/jsonl-writer.ts";
|
|
62
63
|
import { createOrcaProgressTab, type OrcaProgressTab } from "../shared/orca-progress-tabs.ts";
|
|
63
64
|
import { attachPostExitStdioGuard, trySignalChild } from "../../shared/post-exit-stdio-guard.ts";
|
|
@@ -346,6 +347,7 @@ async function runSingleAttempt(
|
|
|
346
347
|
thinking: effectiveThinking,
|
|
347
348
|
systemPromptMode: agent.systemPromptMode,
|
|
348
349
|
inheritProjectContext: agent.inheritProjectContext,
|
|
350
|
+
inheritGlobalContext: agent.inheritGlobalContext,
|
|
349
351
|
inheritSkills: agent.inheritSkills,
|
|
350
352
|
requireReadTool: Boolean(shared.resolvedSkillNames?.length),
|
|
351
353
|
tools: agent.tools,
|
|
@@ -381,6 +383,7 @@ async function runSingleAttempt(
|
|
|
381
383
|
capabilityCeiling: options.capabilityCeiling,
|
|
382
384
|
thinkingCeiling: options.thinkingCeiling,
|
|
383
385
|
extensionBindings: options.extensionBindings,
|
|
386
|
+
runtimeSnapshotHost: options.runtimeSnapshotHost,
|
|
384
387
|
});
|
|
385
388
|
if (!shared.launchWarnings.emitted && warnings.length > 0) {
|
|
386
389
|
for (const warning of warnings) console.warn(`[pi-subagents] ${warning}`);
|
|
@@ -403,6 +406,7 @@ async function runSingleAttempt(
|
|
|
403
406
|
inheritedCapabilityCeiling: decodeSubagentCapabilityCeiling(process.env[SUBAGENT_CAPABILITY_CEILING_ENV]),
|
|
404
407
|
agentName: agent.name,
|
|
405
408
|
permissionRules,
|
|
409
|
+
runtimeSnapshotHost: options.runtimeSnapshotHost,
|
|
406
410
|
});
|
|
407
411
|
const contractTools = toolPlan.explicitToolAllowlist ? toolPlan.effectiveToolAllowlist : undefined;
|
|
408
412
|
const contractError = validateImplementationToolContract({
|
|
@@ -446,6 +450,7 @@ async function runSingleAttempt(
|
|
|
446
450
|
systemPrompt: effectiveSystemPrompt,
|
|
447
451
|
systemPromptMode: agent.systemPromptMode,
|
|
448
452
|
inheritProjectContext: agent.inheritProjectContext,
|
|
453
|
+
inheritGlobalContext: agent.inheritGlobalContext,
|
|
449
454
|
inheritSkills: agent.inheritSkills,
|
|
450
455
|
skills: shared.resolvedSkillNames ?? [],
|
|
451
456
|
tools: toolPlan.effectiveToolAllowlist,
|
|
@@ -1064,7 +1069,7 @@ async function runSingleAttempt(
|
|
|
1064
1069
|
if (options.toolBudget) {
|
|
1065
1070
|
result.toolBudget = toolBudgetState(options.toolBudget, progress.toolCount);
|
|
1066
1071
|
}
|
|
1067
|
-
const mutates = isMutatingTool(evt.toolName, toolArgs);
|
|
1072
|
+
const mutates = isMutatingTool(evt.toolName, toolArgs, agent.mutationTools);
|
|
1068
1073
|
observedMutationAttempt = observedMutationAttempt || mutates;
|
|
1069
1074
|
pendingToolResult = { tool: evt.toolName ?? "tool", path: activeTool?.path, mutates, startedAt: now };
|
|
1070
1075
|
fireUpdate();
|
|
@@ -1583,6 +1588,7 @@ async function runSingleAttempt(
|
|
|
1583
1588
|
messages: result.messages ?? [],
|
|
1584
1589
|
tools: contractTools,
|
|
1585
1590
|
mcpDirectTools: toolPlan.effectiveMcpTools,
|
|
1591
|
+
mutationTools: agent.mutationTools,
|
|
1586
1592
|
toolAvailabilityError,
|
|
1587
1593
|
mutationEvidence,
|
|
1588
1594
|
})
|
|
@@ -1688,6 +1694,19 @@ async function runSyncCompletionInner(
|
|
|
1688
1694
|
task: string,
|
|
1689
1695
|
options: RunSyncOptions,
|
|
1690
1696
|
): Promise<SingleResult> {
|
|
1697
|
+
const effectiveCwd = options.cwd ?? runtimeCwd;
|
|
1698
|
+
const cwdError = preflightLaunchCwd(options.requestedCwd ?? effectiveCwd, effectiveCwd);
|
|
1699
|
+
if (cwdError) {
|
|
1700
|
+
return redactResultPrompt(withRunContext({
|
|
1701
|
+
index: options.index ?? 0,
|
|
1702
|
+
agent: agentName,
|
|
1703
|
+
task,
|
|
1704
|
+
exitCode: 1,
|
|
1705
|
+
messages: [],
|
|
1706
|
+
usage: emptyUsage(),
|
|
1707
|
+
error: cwdError,
|
|
1708
|
+
}, options.context));
|
|
1709
|
+
}
|
|
1691
1710
|
options = {
|
|
1692
1711
|
...options,
|
|
1693
1712
|
capabilityCeiling: intersectSubagentCapabilityCeilings(options.capabilityCeiling ?? resolveCurrentSubagentCapabilityCeiling(options.parentSessionId), decodeSubagentCapabilityCeiling(process.env[SUBAGENT_CAPABILITY_CEILING_ENV])),
|