pi-cohort 7.1.2 → 7.2.1
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 +12 -0
- package/README.md +6 -0
- package/package.json +3 -3
- package/src/execution-backend/child-host-controller.ts +10 -8
- package/src/extension/doctor.ts +6 -2
- package/src/extension/fanout-child.ts +2 -2
- package/src/extension/index.ts +10 -45
- package/src/runs/background/async-execution.ts +154 -87
- package/src/runs/background/async-job-tracker.ts +4 -1
- package/src/runs/background/async-resume.ts +93 -17
- package/src/runs/background/async-status.ts +12 -9
- package/src/runs/background/external-attempt.ts +6 -2
- package/src/runs/background/notify.ts +2 -13
- package/src/runs/background/run-id-resolver.ts +15 -18
- package/src/runs/background/run-status.ts +22 -11
- package/src/runs/background/stale-run-reconciler.ts +9 -1
- package/src/runs/background/subagent-runner.ts +54 -79
- package/src/runs/foreground/chain-execution.ts +7 -0
- package/src/runs/foreground/execution.ts +30 -13
- package/src/runs/foreground/external-single-attempt.ts +3 -2
- package/src/runs/foreground/subagent-executor.ts +142 -63
- package/src/runs/shared/external-execution.ts +2 -0
- package/src/runs/shared/jiti-cli.ts +17 -48
- package/src/runs/shared/nested-events.ts +103 -30
- package/src/runs/shared/pi-spawn.ts +75 -67
- package/src/shared/agent-dir.ts +12 -0
- package/src/shared/atomic-json.ts +12 -1
- package/src/shared/fork-context.ts +15 -3
- package/src/shared/types.ts +11 -1
- package/src/shared/utils.ts +1 -6
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
} from "../../shared/settings.ts";
|
|
33
33
|
import { discoverAvailableSkills, normalizeSkillInput } from "../../agents/skills.ts";
|
|
34
34
|
import { runSync } from "./execution.ts";
|
|
35
|
+
import type { PiRuntimeIdentity } from "../shared/pi-spawn.ts";
|
|
35
36
|
import { buildChainSummary } from "../../shared/formatters.ts";
|
|
36
37
|
import { compactForegroundDetails, getSingleResultOutput, mapConcurrent, resolveChildCwd } from "../../shared/utils.ts";
|
|
37
38
|
import { recordRun } from "../shared/run-history.ts";
|
|
@@ -85,6 +86,7 @@ interface ChainExecutionDetailsInput {
|
|
|
85
86
|
}
|
|
86
87
|
|
|
87
88
|
interface ParallelChainRunInput {
|
|
89
|
+
runtime: PiRuntimeIdentity;
|
|
88
90
|
step: ParallelStep;
|
|
89
91
|
parallelTemplates: string[];
|
|
90
92
|
parallelBehaviors: ResolvedStepBehavior[];
|
|
@@ -260,6 +262,7 @@ async function runParallelChainTasks(input: ParallelChainRunInput): Promise<Sing
|
|
|
260
262
|
? createStructuredOutputRuntime(task.outputSchema, path.join(input.chainDir, "structured-output"))
|
|
261
263
|
: undefined;
|
|
262
264
|
const result = await runSync(input.ctx.cwd, input.agents, task.agent, taskStr, {
|
|
265
|
+
runtime: input.runtime,
|
|
263
266
|
cwd: taskCwd,
|
|
264
267
|
signal: input.signal,
|
|
265
268
|
interruptSignal: interruptController.signal,
|
|
@@ -347,6 +350,7 @@ async function runParallelChainTasks(input: ParallelChainRunInput): Promise<Sing
|
|
|
347
350
|
}
|
|
348
351
|
|
|
349
352
|
interface ChainExecutionParams {
|
|
353
|
+
runtime: PiRuntimeIdentity;
|
|
350
354
|
chain: ChainStep[];
|
|
351
355
|
task?: string;
|
|
352
356
|
agents: AgentConfig[];
|
|
@@ -629,6 +633,7 @@ export async function executeChain(params: ChainExecutionParams): Promise<ChainE
|
|
|
629
633
|
createParallelDirs(chainDir, stepIndex, step.parallel.length, agentNames);
|
|
630
634
|
|
|
631
635
|
const parallelResults = await runParallelChainTasks({
|
|
636
|
+
runtime: params.runtime,
|
|
632
637
|
step,
|
|
633
638
|
parallelTemplates,
|
|
634
639
|
parallelBehaviors,
|
|
@@ -822,6 +827,7 @@ export async function executeChain(params: ChainExecutionParams): Promise<ChainE
|
|
|
822
827
|
progressCreated = ensureParallelProgressFile(chainDir, progressCreated, parallelBehaviors);
|
|
823
828
|
createParallelDirs(chainDir, stepIndex, dynamicParallelStep.parallel.length, dynamicParallelStep.parallel.map((task) => task.agent));
|
|
824
829
|
const parallelResults = await runParallelChainTasks({
|
|
830
|
+
runtime: params.runtime,
|
|
825
831
|
step: dynamicParallelStep,
|
|
826
832
|
parallelTemplates,
|
|
827
833
|
parallelBehaviors,
|
|
@@ -1021,6 +1027,7 @@ export async function executeChain(params: ChainExecutionParams): Promise<ChainE
|
|
|
1021
1027
|
? createStructuredOutputRuntime(seqStep.outputSchema, path.join(chainDir, "structured-output"))
|
|
1022
1028
|
: undefined;
|
|
1023
1029
|
const r = await runSync(ctx.cwd, agents, seqStep.agent, stepTask, {
|
|
1030
|
+
runtime: params.runtime,
|
|
1024
1031
|
cwd: resolveChildCwd(cwd ?? ctx.cwd, seqStep.cwd),
|
|
1025
1032
|
signal,
|
|
1026
1033
|
interruptSignal: interruptController.signal,
|
|
@@ -41,7 +41,8 @@ import {
|
|
|
41
41
|
} from "../../shared/utils.ts";
|
|
42
42
|
import { buildSkillInjection, resolveSkillsWithFallback } from "../../agents/skills.ts";
|
|
43
43
|
import { blockedLine } from "../shared/completion-guard.ts";
|
|
44
|
-
import { getPiSpawnCommand } from "../shared/pi-spawn.ts";
|
|
44
|
+
import { getPiSpawnCommand, PiRuntimeLaunchError } from "../shared/pi-spawn.ts";
|
|
45
|
+
import { PINNED_AGENT_DIR_OVERRIDE } from "../../shared/agent-dir.ts";
|
|
45
46
|
import { createJsonlWriter } from "../../shared/jsonl-writer.ts";
|
|
46
47
|
import { attachPostExitStdioGuard, trySignalChild } from "../../shared/post-exit-stdio-guard.ts";
|
|
47
48
|
import { buildPiArgs, cleanupTempDir } from "../shared/pi-args.ts";
|
|
@@ -170,11 +171,11 @@ async function runSingleAttempt(
|
|
|
170
171
|
let interruptedByControl = false;
|
|
171
172
|
let pendingControlEvents: ControlEvent[] = init.pendingControlEvents;
|
|
172
173
|
const controlConfig = init.controlConfig;
|
|
173
|
-
const spawnEnv = { ...process.env, ...sharedEnv, ...getSubagentDepthEnv(options.maxSubagentDepth) };
|
|
174
|
+
const spawnEnv = { ...process.env, ...sharedEnv, ...getSubagentDepthEnv(options.maxSubagentDepth), ...(PINNED_AGENT_DIR_OVERRIDE ? { PI_CODING_AGENT_DIR: PINNED_AGENT_DIR_OVERRIDE } : {}) };
|
|
174
175
|
let observedMutationAttempt = false;
|
|
175
176
|
|
|
176
|
-
const exitCode = await new Promise<number>((resolve) => {
|
|
177
|
-
const spawnSpec = getPiSpawnCommand(args);
|
|
177
|
+
const exitCode = await new Promise<number>((resolve, reject) => {
|
|
178
|
+
const spawnSpec = getPiSpawnCommand(args, options.runtime);
|
|
178
179
|
const proc = spawn(spawnSpec.command, spawnSpec.args, {
|
|
179
180
|
cwd: options.cwd ?? runtimeCwd,
|
|
180
181
|
env: spawnEnv,
|
|
@@ -553,6 +554,7 @@ async function runSingleAttempt(
|
|
|
553
554
|
if (!result.error) {
|
|
554
555
|
result.error = error instanceof Error ? error.message : String(error);
|
|
555
556
|
}
|
|
557
|
+
reject(new PiRuntimeLaunchError(`${options.runtime.nodeExecPath} ${options.runtime.piEntryPath}: ${error.message}`));
|
|
556
558
|
finish(1);
|
|
557
559
|
});
|
|
558
560
|
|
|
@@ -591,7 +593,7 @@ async function runSingleAttempt(
|
|
|
591
593
|
removeInterruptListener = () => options.interruptSignal?.removeEventListener("abort", interrupt);
|
|
592
594
|
}
|
|
593
595
|
}
|
|
594
|
-
});
|
|
596
|
+
}).finally(() => cleanupTempDir(tempDir));
|
|
595
597
|
result.exitCode = exitCode;
|
|
596
598
|
return finalizeSingleAttempt(result, progress, {
|
|
597
599
|
agent,
|
|
@@ -640,6 +642,12 @@ export async function runSync(
|
|
|
640
642
|
};
|
|
641
643
|
}
|
|
642
644
|
|
|
645
|
+
try {
|
|
646
|
+
getPiSpawnCommand([], options.runtime);
|
|
647
|
+
} catch (error) {
|
|
648
|
+
return failedResult(agentName, task, error instanceof Error ? error.message : String(error));
|
|
649
|
+
}
|
|
650
|
+
|
|
643
651
|
const childCwd = options.cwd ?? runtimeCwd;
|
|
644
652
|
let backendSelection: ExecutionBackendSelectionResult;
|
|
645
653
|
try {
|
|
@@ -717,6 +725,7 @@ export async function runSync(
|
|
|
717
725
|
try {
|
|
718
726
|
externalOwner = await (dependencies.createExternalOwner ?? createExternalExecution)({
|
|
719
727
|
backend: backendSelection.selection.backend,
|
|
728
|
+
runtime: options.runtime,
|
|
720
729
|
runId: options.runId,
|
|
721
730
|
childId,
|
|
722
731
|
cwd: childCwd,
|
|
@@ -724,8 +733,8 @@ export async function runSync(
|
|
|
724
733
|
signal: options.signal ?? NEVER_ABORTED_SIGNAL,
|
|
725
734
|
});
|
|
726
735
|
await externalOwner.ready;
|
|
727
|
-
} catch {
|
|
728
|
-
lastResult = failedResult(agentName, task, safeExternalFailure("startup"));
|
|
736
|
+
} catch (error) {
|
|
737
|
+
lastResult = failedResult(agentName, task, error instanceof PiRuntimeLaunchError ? error.message : safeExternalFailure("startup"));
|
|
729
738
|
}
|
|
730
739
|
}
|
|
731
740
|
|
|
@@ -746,6 +755,7 @@ export async function runSync(
|
|
|
746
755
|
originalTask: task,
|
|
747
756
|
};
|
|
748
757
|
let result: SingleResult;
|
|
758
|
+
let runtimeFailure = false;
|
|
749
759
|
if (externalOwner) {
|
|
750
760
|
try {
|
|
751
761
|
result = await (dependencies.runExternalAttempt ?? runExternalSingleAttempt)({
|
|
@@ -758,13 +768,20 @@ export async function runSync(
|
|
|
758
768
|
options,
|
|
759
769
|
shared,
|
|
760
770
|
});
|
|
761
|
-
} catch {
|
|
762
|
-
|
|
771
|
+
} catch (error) {
|
|
772
|
+
runtimeFailure = error instanceof PiRuntimeLaunchError;
|
|
773
|
+
result = failedResult(agentName, task, runtimeFailure ? (error as Error).message : safeExternalFailure("attempt"));
|
|
763
774
|
}
|
|
764
775
|
} else {
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
776
|
+
try {
|
|
777
|
+
result = await (dependencies.runNativeAttempt ?? runSingleAttempt)(
|
|
778
|
+
runtimeCwd, effectiveAgent, taskWithAcceptance, candidate, options, shared,
|
|
779
|
+
);
|
|
780
|
+
} catch (error) {
|
|
781
|
+
if (!(error instanceof PiRuntimeLaunchError)) throw error;
|
|
782
|
+
runtimeFailure = true;
|
|
783
|
+
result = failedResult(agentName, task, error.message);
|
|
784
|
+
}
|
|
768
785
|
}
|
|
769
786
|
lastResult = result;
|
|
770
787
|
sumUsage(aggregateUsage, result.usage);
|
|
@@ -782,7 +799,7 @@ export async function runSync(
|
|
|
782
799
|
if (attemptSucceeded) {
|
|
783
800
|
break;
|
|
784
801
|
}
|
|
785
|
-
if (blockedLine(result.error ?? "") || !isRetryableModelFailure(result.error) || i === modelsToTry.length - 1) {
|
|
802
|
+
if (runtimeFailure || blockedLine(result.error ?? "") || !isRetryableModelFailure(result.error) || i === modelsToTry.length - 1) {
|
|
786
803
|
break;
|
|
787
804
|
}
|
|
788
805
|
attemptNotes.push(formatModelAttemptNote(attempt, modelsToTry[i + 1]));
|
|
@@ -12,6 +12,7 @@ import type { RunSyncOptions, SingleResult, Usage } from "../../shared/types.ts"
|
|
|
12
12
|
import { getSubagentDepthEnv } from "../../shared/types.ts";
|
|
13
13
|
import { buildPiArgs, cleanupTempDir } from "../shared/pi-args.ts";
|
|
14
14
|
import { getPiSpawnCommand } from "../shared/pi-spawn.ts";
|
|
15
|
+
import { PINNED_AGENT_DIR_OVERRIDE } from "../../shared/agent-dir.ts";
|
|
15
16
|
import { isMutatingTool } from "../shared/long-running-guard.ts";
|
|
16
17
|
import type { ExternalAttemptResult, ExternalExecution } from "../shared/external-execution.ts";
|
|
17
18
|
import { type AttemptSharedInit, finalizeSingleAttempt, initializeAttempt } from "./attempt-finalization.ts";
|
|
@@ -104,8 +105,8 @@ export async function runExternalSingleAttempt(input: RunExternalSingleAttemptIn
|
|
|
104
105
|
args.push("--extension", REPORTING_EXTENSION_PATH);
|
|
105
106
|
if (taskArg !== undefined) args.push(taskArg);
|
|
106
107
|
|
|
107
|
-
const spawnSpec = getPiSpawnCommand(args);
|
|
108
|
-
const mergedEnv: Record<string, string | undefined> = { ...process.env, ...sharedEnv, ...getSubagentDepthEnv(options.maxSubagentDepth) };
|
|
108
|
+
const spawnSpec = getPiSpawnCommand(args, options.runtime);
|
|
109
|
+
const mergedEnv: Record<string, string | undefined> = { ...process.env, ...sharedEnv, ...getSubagentDepthEnv(options.maxSubagentDepth), ...(PINNED_AGENT_DIR_OVERRIDE ? { PI_CODING_AGENT_DIR: PINNED_AGENT_DIR_OVERRIDE } : {}) };
|
|
109
110
|
const environment: Record<string, string> = {};
|
|
110
111
|
for (const [key, value] of Object.entries(mergedEnv)) {
|
|
111
112
|
if (value !== undefined) environment[key] = value;
|