027dbb4900
A per-cell timeout used to kill the persistent Python kernel, losing all session state. The kernel.ts timeout path now sends SIGINT first (letting the cell raise KeyboardInterrupt) and only escalates to shutdown after a 5s grace window if the interrupt is ignored. KernelExecuteResult gains an optional kernelKilled flag (defaulting to false, propagated by the escalation timer and the unexpected-exit handler). executor.ts formats two distinct timeout annotations: one that says the kernel is still alive and reset:true would clear state, one that says the kernel was killed and will be recreated.
42 lines
1.5 KiB
TypeScript
42 lines
1.5 KiB
TypeScript
import { describe, expect, it } from "bun:test";
|
|
import { executePythonWithKernel, type PythonKernelExecutor } from "@oh-my-pi/pi-coding-agent/eval/py/executor";
|
|
import type { KernelExecuteOptions, KernelExecuteResult } from "@oh-my-pi/pi-coding-agent/eval/py/kernel";
|
|
|
|
class FakeKernel implements PythonKernelExecutor {
|
|
constructor(
|
|
private result: KernelExecuteResult,
|
|
private onExecute: (options?: KernelExecuteOptions) => void = () => {},
|
|
) {}
|
|
|
|
async execute(_code: string, options?: KernelExecuteOptions): Promise<KernelExecuteResult> {
|
|
this.onExecute(options);
|
|
return this.result;
|
|
}
|
|
}
|
|
|
|
describe("executePythonWithKernel mapping", () => {
|
|
it("annotates timeout cancellations", async () => {
|
|
const kernel = new FakeKernel({ status: "ok", cancelled: true, timedOut: true, stdinRequested: false });
|
|
const result = await executePythonWithKernel(kernel, "sleep(10)", { timeoutMs: 5000 });
|
|
|
|
expect(result.cancelled).toBe(true);
|
|
expect(result.exitCode).toBeUndefined();
|
|
expect(result.output).toContain("eval cell timed out after 5s");
|
|
});
|
|
|
|
it("maps error status to non-zero exit code", async () => {
|
|
const kernel = new FakeKernel(
|
|
{ status: "error", cancelled: false, timedOut: false, stdinRequested: false },
|
|
options => {
|
|
options?.onChunk?.("traceback\n");
|
|
},
|
|
);
|
|
|
|
const result = await executePythonWithKernel(kernel, "1 / 0");
|
|
|
|
expect(result.exitCode).toBe(1);
|
|
expect(result.output).toContain("traceback");
|
|
expect(result.stdinRequested).toBe(false);
|
|
});
|
|
});
|