diff --git a/packages/plugin/src/tool.ts b/packages/plugin/src/tool.ts index 9c6daa34d04a..4eb9b12d8929 100644 --- a/packages/plugin/src/tool.ts +++ b/packages/plugin/src/tool.ts @@ -47,6 +47,10 @@ export function tool(input: { args: Args execute(args: z.infer>, context: ToolContext): Promise }) { + const invalid = Object.entries(input.args).find( + (entry) => typeof entry[1] !== "object" || entry[1] === null || !("_zod" in entry[1]), + ) + if (invalid) throw new TypeError(`Invalid tool argument "${invalid[0]}": args must contain Zod schemas`) return input } tool.schema = z diff --git a/packages/plugin/test/tool.test.ts b/packages/plugin/test/tool.test.ts new file mode 100644 index 000000000000..c628fe55fc49 --- /dev/null +++ b/packages/plugin/test/tool.test.ts @@ -0,0 +1,27 @@ +import { describe, expect, test } from "bun:test" +import { tool } from "../src/tool" + +describe("tool", () => { + test("rejects plain-object argument definitions with a clear error", () => { + expect(() => + tool({ + description: "invalid tool", + args: { + // @ts-expect-error Verify the runtime diagnostic for JavaScript callers. + foo: "string", + }, + execute: async () => "ok", + }), + ).toThrow('Invalid tool argument "foo": args must contain Zod schemas') + }) + + test("accepts Zod argument definitions", () => { + expect( + tool({ + description: "valid tool", + args: { foo: tool.schema.string() }, + execute: async ({ foo }) => foo, + }), + ).toBeDefined() + }) +})