fix: finish lingering subagent wrapper runs

This commit is contained in:
pi
2026-04-11 01:25:26 +01:00
parent e99edfee42
commit e0c7c99d71
2 changed files with 92 additions and 1 deletions

View File

@@ -3,6 +3,13 @@ import { spawn } from "node:child_process";
import { normalizePiEvent } from "./normalize.mjs";
import { renderHeader, renderEventLine } from "./render.mjs";
const SEMANTIC_EXIT_GRACE_MS = 250;
const FORCED_EXIT_GRACE_MS = 250;
async function sleep(ms) {
await new Promise((resolve) => setTimeout(resolve, ms));
}
async function appendJsonLine(path, value) {
await appendBestEffort(path, `${JSON.stringify(value)}\n`);
}
@@ -68,8 +75,26 @@ async function runWrapper(meta, startedAt) {
let stdoutBuffer = "";
let stderrText = "";
let spawnError;
let childClosed = false;
let completionCleanupStarted = false;
let child;
let queue = Promise.resolve();
const forceChildExitAfterSemanticCompletion = async () => {
if (completionCleanupStarted) return;
completionCleanupStarted = true;
await sleep(SEMANTIC_EXIT_GRACE_MS);
if (childClosed) return;
child.kill("SIGTERM");
await sleep(FORCED_EXIT_GRACE_MS);
if (childClosed) return;
child.kill("SIGKILL");
};
const enqueue = (work) => {
queue = queue.then(work, work);
return queue;
@@ -98,6 +123,10 @@ async function runWrapper(meta, startedAt) {
resolvedModel = normalized.model ?? resolvedModel;
stopReason = normalized.stopReason ?? stopReason;
usage = normalized.usage ?? usage;
if (normalized.stopReason) {
void forceChildExitAfterSemanticCompletion();
}
}
};
@@ -112,7 +141,7 @@ async function runWrapper(meta, startedAt) {
childEnv.PI_SUBAGENTS_GITHUB_COPILOT_INITIATOR = "agent";
}
const child = spawn("pi", args, {
child = spawn("pi", args, {
cwd: meta.cwd,
env: childEnv,
stdio: ["ignore", "pipe", "pipe"],
@@ -151,10 +180,12 @@ async function runWrapper(meta, startedAt) {
child.on("error", (error) => {
spawnError = error;
childClosed = true;
finish(1);
});
child.on("close", (code) => {
childClosed = true;
finish(code ?? (spawnError ? 1 : 0));
});
});