import { describe, expect, it, vi } from "bun:test"; import type { AgentTool, AgentToolResult } from "@oh-my-pi/pi-agent-core"; import { Settings } from "@oh-my-pi/pi-coding-agent/config/settings"; import type { ToolSession } from "@oh-my-pi/pi-coding-agent/tools"; import { Type } from "@sinclair/typebox"; import { callSessionTool } from "../../src/eval/js/tool-bridge"; function createTool( name: string, execute: (toolCallId: string, args: unknown, signal?: AbortSignal) => Promise, ): AgentTool { return { name, label: name, description: `${name} tool`, parameters: Type.Object({}), concurrency: "parallel", execute, } as unknown as AgentTool; } function createSession(tools: AgentTool[]): ToolSession { const registry = new Map(tools.map(tool => [tool.name, tool])); return { cwd: "/tmp/test", hasUI: false, getSessionFile: () => null, getSessionSpawns: () => null, settings: Settings.isolated(), getToolByName: name => registry.get(name), }; } describe("callSessionTool", () => { it("injects js intent and summarizes text results", async () => { const execute = vi.fn().mockResolvedValue({ content: [{ type: "text", text: "hello" }], }); const session = createSession([createTool("read", execute)]); const statuses: Array> = []; const result = await callSessionTool( "read", { path: "/tmp/demo.txt" }, { session, emitStatus: event => { statuses.push(event); }, }, ); expect(result).toBe("hello"); expect(execute).toHaveBeenCalledWith( expect.stringMatching(/^js-read-/), { path: "/tmp/demo.txt", _i: "js prelude" }, undefined, ); expect(statuses).toEqual([expect.objectContaining({ op: "read", path: "/tmp/demo.txt", chars: 5 })]); }); it("returns structured tool results when details or images are present", async () => { const session = createSession([ createTool("custom", async () => ({ content: [ { type: "text", text: "done" }, { type: "image", mimeType: "image/png", data: "abc123" }, ], details: { ok: true }, })), ]); const result = await callSessionTool("custom", {}, { session }); expect(result).toEqual({ text: "done", details: { ok: true }, images: [{ mimeType: "image/png", data: "abc123" }], }); }); it("throws when the requested tool is not available in the session registry", async () => { const session = createSession([]); await expect(callSessionTool("missing", {}, { session })).rejects.toThrow("Unknown tool from js runtime"); }); });