mirror of
https://github.com/badlogic/pi-mono.git
synced 2026-11-05 23:37:25 +00:00
The tool is named codemode again and scripts configure it with a first-line // @options: {...} instead of the // @exec: pragma. yield_time_ms is gone; max_output_tokens and timeout_ms remain. Comments, docs, and tests no longer describe the tool in terms of another agent.
62 lines
2 KiB
TypeScript
62 lines
2 KiB
TypeScript
import { stripVTControlCharacters } from "node:util";
|
|
import type { AgentToolResult } from "@earendil-works/pi-agent-core";
|
|
import type { Text } from "@earendil-works/pi-tui";
|
|
import { beforeAll, describe, expect, it } from "vitest";
|
|
import type { ToolRenderContext } from "../src/core/extensions/types.ts";
|
|
import { codemodeRenderers } from "../src/extensions/codemode/renderer.ts";
|
|
import type { CodemodeToolDetails } from "../src/extensions/codemode/tool.ts";
|
|
import { initTheme, theme } from "../src/modes/interactive/theme/theme.ts";
|
|
|
|
function render(result: AgentToolResult<CodemodeToolDetails | undefined>, isError = false): string {
|
|
const context = {
|
|
args: { code: "" },
|
|
toolCallId: "call",
|
|
invalidate: () => {},
|
|
lastComponent: undefined,
|
|
state: {},
|
|
cwd: "/",
|
|
executionStarted: true,
|
|
argsComplete: true,
|
|
isPartial: false,
|
|
expanded: true,
|
|
showImages: false,
|
|
isError,
|
|
} satisfies ToolRenderContext;
|
|
const component = codemodeRenderers.renderResult?.(
|
|
result,
|
|
{ expanded: true, isPartial: false },
|
|
theme,
|
|
context,
|
|
) as Text;
|
|
return stripVTControlCharacters(component.render(200).join("\n"))
|
|
.split("\n")
|
|
.map((line) => line.trimEnd())
|
|
.join("\n")
|
|
.trim();
|
|
}
|
|
|
|
describe("codemode renderer", () => {
|
|
beforeAll(() => initTheme("dark"));
|
|
|
|
it("hides the script header and shows the output", () => {
|
|
const text = render({
|
|
content: [
|
|
{ type: "text", text: "Script completed\nWall time 0.1 seconds\nOutput:\n" },
|
|
{ type: "text", text: "hello" },
|
|
],
|
|
details: { calls: [{ id: "call/1", name: "read", args: '{"path":"a"}', status: "ok", durationMs: 5 }] },
|
|
});
|
|
expect(text).toBe('✓ read {"path":"a"} 5ms\n\nhello');
|
|
});
|
|
|
|
it("shows results without a header, such as rejected options", () => {
|
|
const text = render(
|
|
{
|
|
content: [{ type: "text", text: "The @options line must be followed by JavaScript source" }],
|
|
details: undefined,
|
|
},
|
|
true,
|
|
);
|
|
expect(text).toBe("The @options line must be followed by JavaScript source");
|
|
});
|
|
});
|