@langgraph-js/sdk
Version:
The UI SDK for LangGraph - seamlessly integrate your AI agents with frontend interfaces
94 lines (88 loc) • 3.9 kB
text/typescript
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<Args extends ZodRawShape, Child extends Object = Object, ResponseType = any> {
name: string;
description: string;
parameters: Args;
/** 是否直接返回工具结果,而不是通过消息返回 */
returnDirect?: boolean;
execute?: ToolCallback<Args>;
/** 工具执行成功后触发的附加消息 */
callbackMessage?: (result: CallToolResult) => Message[];
handler?: (args: z.infer<z.ZodObject<Args>>, context?: any) => ResponseType | Promise<ResponseType>;
render?: (tool: ToolRenderData<z.infer<z.ZodObject<Args>>, ResponseType>) => Child;
onlyRender?: boolean;
/** 只允许指定的 agent 使用该工具,如果未指定,则所有 agent 都可以使用 */
allowAgent?: string[];
/** 只允许指定的 Graph 使用该工具 */
allowGraph?: string[];
/** 是否是纯净的 json schema 参数,而不是 zod 参数 */
isPureParams?: boolean;
}
export type ToolCallback<Args extends ZodRawShape> = (args: z.infer<z.ZodObject<Args>>, context?: any) => CallToolResult | Promise<CallToolResult>;
export type CallToolResult = string | { type: "text"; text: string }[] | HumanInTheLoopDecision | HumanInTheLoopResponse;
/** 用于格式校验 */
export const createTool = <Args extends ZodRawShape>(tool: UnionTool<Args>) => {
return tool;
};
/**
* create Type Safe Tool with zod and UI Render Feature
*/
export const createUITool = <Args extends ZodRawShape, Child extends Object = {}>(tool: UnionTool<Args, Child>): UnionTool<Args, Child> => {
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 = <Args extends ZodRawShape, Child extends Object = {}>(tool: UnionTool<Args, Child>): UnionTool<Args, Child> => {
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 = <Args extends ZodRawShape>(tool: UnionTool<Args>) => {
return {
name: tool.name,
description: tool.description,
parameters: tool.isPureParams ? tool.parameters : zodToJsonSchema(z.object(tool.parameters)),
};
};