import { describe, expect, test } from "vitest"; import { formatMcpInputForPrompt, registerBuiltinToolInputFormatters, } from "#src/builtin-tool-input-formatters"; import { ToolInputFormatterRegistry } from "#src/tool-input-formatter-registry"; // ── formatMcpInputForPrompt ─────────────────────────────────────────────── describe("formatMcpInputForPrompt", () => { test("returns undefined when arguments is absent", () => { expect(formatMcpInputForPrompt({ tool: "exa:search" })).toBeUndefined(); }); test("returns undefined when arguments is an empty object", () => { expect( formatMcpInputForPrompt({ tool: "exa:search", arguments: {} }), ).toBeUndefined(); }); test("returns a summary for a single string argument", () => { const result = formatMcpInputForPrompt({ tool: "exa:search", arguments: { query: "typescript generics" }, }); expect(result).toBeDefined(); expect(result).toContain("query"); expect(result).toContain("typescript generics"); expect(result).toMatch(/^with /); }); test("returns a comma-separated summary for multiple arguments", () => { const result = formatMcpInputForPrompt({ tool: "exa:search", arguments: { query: "test", numResults: 5 }, }); expect(result).toContain("query"); expect(result).toContain("numResults"); expect(result).toContain("5"); }); test("renders number arguments without quotes", () => { const result = formatMcpInputForPrompt({ arguments: { count: 42 }, }); expect(result).toContain("42"); expect(result).not.toContain('"42"'); }); test("renders boolean arguments without quotes", () => { const result = formatMcpInputForPrompt({ arguments: { verbose: true }, }); expect(result).toContain("true"); }); test("renders array arguments as '[N items]'", () => { const result = formatMcpInputForPrompt({ arguments: { ids: [1, 2, 3] }, }); expect(result).toContain("[3 items]"); }); test("renders nested object arguments as '{…}'", () => { const result = formatMcpInputForPrompt({ arguments: { filter: { type: "file" } }, }); expect(result).toContain("{…}"); }); test("truncates the full summary when it exceeds the limit", () => { // Need multiple long-valued args so the joined summary exceeds 160 chars const result = formatMcpInputForPrompt({ arguments: { first: "x".repeat(80), second: "y".repeat(80), third: "z".repeat(80), }, }); expect(result).toBeDefined(); expect(result!.endsWith("…")).toBe(true); }); test("truncates long string argument values", () => { const result = formatMcpInputForPrompt({ arguments: { query: "x".repeat(100) }, }); expect(result).toBeDefined(); // Should not include the full 100-char string verbatim expect(result).not.toContain("x".repeat(100)); }); }); // ── registerBuiltinToolInputFormatters ──────────────────────────────────── describe("registerBuiltinToolInputFormatters", () => { test("registers the mcp formatter in the registry", () => { const registry = new ToolInputFormatterRegistry(); registerBuiltinToolInputFormatters(registry); expect(registry.get("mcp")).toBe(formatMcpInputForPrompt); }); test("throws if called twice (duplicate registration guard)", () => { const registry = new ToolInputFormatterRegistry(); registerBuiltinToolInputFormatters(registry); expect(() => registerBuiltinToolInputFormatters(registry)).toThrow("mcp"); }); });