import { actionParametersToJsonSchema, convertJsonSchemaToZodRawShape } from "./utils.js"; import { uuidv4, z, ZodRawShape } from "zod"; import { Action, Parameter } from "./copilotkit-actions.js"; import { zodToJsonSchema } from "zod-to-json-schema"; import { Message } from "@langchain/langgraph-sdk"; import { ToolRenderData } from "./ToolUI.js"; import { HumanInTheLoopDecision, InterruptResponse as HumanInTheLoopResponse } from "../humanInTheLoop.js"; import { ToolManager } from "../ToolManager.js"; export interface UnionTool { name: string; description: string; parameters: Args; /** 是否直接返回工具结果,而不是通过消息返回 */ returnDirect?: boolean; execute?: ToolCallback; /** 工具执行成功后触发的附加消息 */ callbackMessage?: (result: CallToolResult) => Message[]; handler?: (args: z.infer>, context?: any) => ResponseType | Promise; render?: (tool: ToolRenderData>, ResponseType>) => Child; onlyRender?: boolean; /** 只允许指定的 agent 使用该工具,如果未指定,则所有 agent 都可以使用 */ allowAgent?: string[]; /** 只允许指定的 Graph 使用该工具 */ allowGraph?: string[]; /** 是否是纯净的 json schema 参数,而不是 zod 参数 */ isPureParams?: boolean; } export type ToolCallback = (args: z.infer>, context?: any) => CallToolResult | Promise; export type CallToolResult = string | { type: "text"; text: string }[] | HumanInTheLoopDecision | HumanInTheLoopResponse; /** 用于格式校验 */ export const createTool = (tool: UnionTool) => { return tool; }; /** * create Type Safe Tool with zod and UI Render Feature */ export const createUITool = (tool: UnionTool): UnionTool => { const execute = tool.execute || (async (args, context) => { try { const result = await tool.handler?.(args, context); if (typeof result === "string") { return [{ type: "text", text: result }]; } else if (result.decisions) { return result; } return [{ type: "text", text: JSON.stringify(result) }]; } catch (error) { return [{ type: "text", text: `Error: ${error}` }]; } }); return { ...tool, execute, }; }; export const createRenderUITool = createUITool; export const createInteractiveUITool = (tool: UnionTool): UnionTool => { const execute = tool.execute || (async (args, context) => { try { const result = await tool.handler?.(args, context); if (typeof result === "string") { return [{ type: "text", text: result }]; } else if (result.decisions) { return result; } return [{ type: "text", text: JSON.stringify(result) }]; } catch (error) { return [{ type: "text", text: `Error: ${error}` }]; } }); return { ...tool, handler: ToolManager.waitForUIDone, execute, }; }; ///======= UnionTool 到 各种工具的辅助函数 export const createJSONDefineTool = (tool: UnionTool) => { return { name: tool.name, description: tool.description, parameters: tool.isPureParams ? tool.parameters : zodToJsonSchema(z.object(tool.parameters)), }; };