/**
* Contract: /dump tool catalog renders parameters as JSON Schema.
*
* Tools carry live Zod v4 schemas; the dump formatter must convert them to
* the wire JSON Schema (same shape providers receive) instead of enumerating
* the schema instance's internals (`def`, `shape`, stringified methods).
* Legacy plain JSON-Schema parameters still pass through with TypeBox
* bookkeeping fields stripped.
*/
import { describe, expect, it } from "bun:test";
import { formatSessionDumpText } from "@oh-my-pi/pi-coding-agent/session/session-dump-format";
import { z } from "zod/v4";
describe("formatSessionDumpText tool parameters", () => {
it("renders Zod schemas as wire JSON Schema, not schema internals", () => {
const out = formatSessionDumpText({
messages: [],
tools: [
{
name: "web_search",
description: "Searches the web.",
parameters: z.object({
query: z.string().describe("search query"),
recency: z.enum(["day", "week"]).optional(),
}),
},
],
});
expect(out).toContain('object');
expect(out).toContain('"query":{"type":"string","description":"search query"}');
expect(out).toContain('["query"]');
// Zod instance internals must never leak into the dump.
expect(out).not.toContain('name="def"');
expect(out).not.toContain('name="shape"');
expect(out).not.toContain(">undefined");
});
it("passes plain JSON-Schema parameters through, stripping TypeBox fields", () => {
const out = formatSessionDumpText({
messages: [],
tools: [
{
name: "legacy",
description: "Legacy tool.",
parameters: {
type: "object",
properties: { path: { type: "string", "TypeBox.Kind": "String" } },
required: ["path"],
},
},
],
});
expect(out).toContain('object');
expect(out).toContain('"path":{"type":"string"}');
expect(out).not.toContain("TypeBox.");
});
});