refactor(agent): dedupe harness and command workflows

This commit is contained in:
Peter Steinberger
2026-02-16 14:52:09 +00:00
parent 04892ee230
commit f717a13039
204 changed files with 7366 additions and 11540 deletions

View File

@@ -8,12 +8,11 @@ afterEach(() => {
resetProcessRegistryForTests();
});
test("process send-keys encodes Enter for pty sessions", async () => {
async function startPtySession(command: string) {
const execTool = createExecTool();
const processTool = createProcessTool();
const result = await execTool.execute("toolcall", {
command:
'node -e "const dataEvent=String.fromCharCode(100,97,116,97);process.stdin.on(dataEvent,d=>{process.stdout.write(d);if(d.includes(10)||d.includes(13))process.exit(0);});"',
command,
pty: true,
background: true,
});
@@ -21,6 +20,36 @@ test("process send-keys encodes Enter for pty sessions", async () => {
expect(result.details.status).toBe("running");
const sessionId = result.details.sessionId;
expect(sessionId).toBeTruthy();
return { processTool, sessionId };
}
async function waitForSessionCompletion(params: {
processTool: ReturnType<typeof createProcessTool>;
sessionId: string;
expectedText: string;
}) {
const deadline = Date.now() + (process.platform === "win32" ? 4000 : 2000);
while (Date.now() < deadline) {
await sleep(50);
const poll = await params.processTool.execute("toolcall", {
action: "poll",
sessionId: params.sessionId,
});
const details = poll.details as { status?: string; aggregated?: string };
if (details.status !== "running") {
expect(details.status).toBe("completed");
expect(details.aggregated ?? "").toContain(params.expectedText);
return;
}
}
throw new Error(`PTY session did not exit after ${params.expectedText}`);
}
test("process send-keys encodes Enter for pty sessions", async () => {
const { processTool, sessionId } = await startPtySession(
'node -e "const dataEvent=String.fromCharCode(100,97,116,97);process.stdin.on(dataEvent,d=>{process.stdout.write(d);if(d.includes(10)||d.includes(13))process.exit(0);});"',
);
await processTool.execute("toolcall", {
action: "send-keys",
@@ -28,51 +57,18 @@ test("process send-keys encodes Enter for pty sessions", async () => {
keys: ["h", "i", "Enter"],
});
const deadline = Date.now() + (process.platform === "win32" ? 4000 : 2000);
while (Date.now() < deadline) {
await sleep(50);
const poll = await processTool.execute("toolcall", { action: "poll", sessionId });
const details = poll.details as { status?: string; aggregated?: string };
if (details.status !== "running") {
expect(details.status).toBe("completed");
expect(details.aggregated ?? "").toContain("hi");
return;
}
}
throw new Error("PTY session did not exit after send-keys");
await waitForSessionCompletion({ processTool, sessionId, expectedText: "hi" });
});
test("process submit sends Enter for pty sessions", async () => {
const execTool = createExecTool();
const processTool = createProcessTool();
const result = await execTool.execute("toolcall", {
command:
'node -e "const dataEvent=String.fromCharCode(100,97,116,97);const submitted=String.fromCharCode(115,117,98,109,105,116,116,101,100);process.stdin.on(dataEvent,d=>{if(d.includes(10)||d.includes(13)){process.stdout.write(submitted);process.exit(0);}});"',
pty: true,
background: true,
});
expect(result.details.status).toBe("running");
const sessionId = result.details.sessionId;
expect(sessionId).toBeTruthy();
const { processTool, sessionId } = await startPtySession(
'node -e "const dataEvent=String.fromCharCode(100,97,116,97);const submitted=String.fromCharCode(115,117,98,109,105,116,116,101,100);process.stdin.on(dataEvent,d=>{if(d.includes(10)||d.includes(13)){process.stdout.write(submitted);process.exit(0);}});"',
);
await processTool.execute("toolcall", {
action: "submit",
sessionId,
});
const deadline = Date.now() + (process.platform === "win32" ? 4000 : 2000);
while (Date.now() < deadline) {
await sleep(50);
const poll = await processTool.execute("toolcall", { action: "poll", sessionId });
const details = poll.details as { status?: string; aggregated?: string };
if (details.status !== "running") {
expect(details.status).toBe("completed");
expect(details.aggregated ?? "").toContain("submitted");
return;
}
}
throw new Error("PTY session did not exit after submit");
await waitForSessionCompletion({ processTool, sessionId, expectedText: "submitted" });
});