Files
oh-my-pi/packages/coding-agent/test/tools/eval-fallback.test.ts
T
can1357 84ec8fba49 feat(coding-agent/eval): implemented JSON cell-based eval tool inputs
- Removed the legacy `parseEvalInput` parser module and `eval.lark`, eliminating `*** Cell` stream parsing.
- Replaced eval tool arguments from single `input` strings to ordered `cells` arrays in tool calls and schema.
- Updated execution to resolve language explicitly, map `py` to `python`, and apply timeout/reset defaults.
- Removed backend sniffing and `ABORT_WARNING` suffix handling, then updated docs and tests to the new JSON cells format.
2026-05-16 19:33:44 +02:00

72 lines
2.6 KiB
TypeScript

import { afterEach, describe, expect, it, vi } from "bun:test";
import { Settings } from "@oh-my-pi/pi-coding-agent/config/settings";
import * as evalIndex from "@oh-my-pi/pi-coding-agent/eval";
import * as pyKernel from "@oh-my-pi/pi-coding-agent/eval/py/kernel";
import type { ToolSession } from "@oh-my-pi/pi-coding-agent/tools";
import { EvalTool } from "@oh-my-pi/pi-coding-agent/tools/eval";
function makeSession(): ToolSession {
return {
cwd: "/tmp/eval-test",
hasUI: false,
getSessionFile: () => null,
getSessionSpawns: () => null,
settings: Settings.isolated(),
};
}
const mockResult = {
output: "ok",
exitCode: 0,
cancelled: false,
truncated: false,
artifactId: undefined,
totalLines: 1,
totalBytes: 2,
outputLines: 1,
outputBytes: 2,
displayOutputs: [],
};
describe("EvalTool language resolution", () => {
afterEach(() => {
vi.restoreAllMocks();
});
it("dispatches to js when fenced code declares ```js", async () => {
vi.spyOn(pyKernel, "checkPythonKernelAvailability").mockResolvedValue({ ok: true });
const jsExecuteSpy = vi.spyOn(evalIndex.jsBackend, "execute").mockResolvedValue(mockResult);
const pythonExecuteSpy = vi.spyOn(evalIndex.pythonBackend, "execute");
const tool = new EvalTool(makeSession());
await tool.execute("call-1", { cells: [{ language: "js", code: "```js one\nconst x = 1;\n```\n" }] });
expect(jsExecuteSpy).toHaveBeenCalledTimes(1);
expect(pythonExecuteSpy).not.toHaveBeenCalled();
});
it("dispatches to python when fenced code declares ```python", async () => {
const pythonExecuteSpy = vi.spyOn(evalIndex.pythonBackend, "execute").mockResolvedValue(mockResult);
vi.spyOn(evalIndex.pythonBackend, "isAvailable").mockResolvedValue(true);
const jsExecuteSpy = vi.spyOn(evalIndex.jsBackend, "execute");
const tool = new EvalTool(makeSession());
await tool.execute("call-2", { cells: [{ language: "js", code: "```python one\nprint('hi')\n```\n" }] });
expect(pythonExecuteSpy).toHaveBeenCalledTimes(1);
expect(jsExecuteSpy).not.toHaveBeenCalled();
});
it("auto-detects python via syntactic markers when fence is bare", async () => {
const pythonExecuteSpy = vi.spyOn(evalIndex.pythonBackend, "execute").mockResolvedValue(mockResult);
vi.spyOn(evalIndex.pythonBackend, "isAvailable").mockResolvedValue(true);
const jsExecuteSpy = vi.spyOn(evalIndex.jsBackend, "execute");
const tool = new EvalTool(makeSession());
await tool.execute("call-3", { cells: [{ language: "js", code: "def greet():\n print('hi')\ngreet()\n" }] });
expect(pythonExecuteSpy).toHaveBeenCalledTimes(1);
expect(jsExecuteSpy).not.toHaveBeenCalled();
});
});