tools
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chineseassistant-ui Tools
assistant-ui Tools
Always consult assistant-ui.com/llms.txt for latest API.
Tools let LLMs trigger actions with custom UI rendering.
请始终参考assistant-ui.com/llms.txt获取最新API。
工具允许LLMs通过自定义UI渲染来触发操作。
References
参考资料
- ./references/make-tool.md -- makeAssistantTool/useAssistantTool
- ./references/tool-ui.md -- makeAssistantToolUI rendering
- ./references/human-in-loop.md -- Confirmation patterns
- ./references/make-tool.md -- makeAssistantTool/useAssistantTool
- ./references/tool-ui.md -- makeAssistantToolUI渲染
- ./references/human-in-loop.md -- 确认模式
Tool Types
工具类型
Where does the tool execute?
├─ Backend (LLM calls API) → AI SDK tool()
│ └─ Want custom UI? → makeAssistantToolUI
└─ Frontend (browser-only) → makeAssistantTool
└─ Want custom UI? → makeAssistantToolUI工具执行位置?
├─ 后端(LLM调用API)→ AI SDK tool()
│ └─ 需要自定义UI?→ makeAssistantToolUI
└─ 前端(仅浏览器)→ makeAssistantTool
└─ 需要自定义UI?→ makeAssistantToolUIBackend Tool with UI
带UI的后端工具
ts
// Backend (app/api/chat/route.ts)
import { tool, stepCountIs } from "ai";
import { z } from "zod";
const tools = {
get_weather: tool({
description: "Get weather for a city",
inputSchema: z.object({ city: z.string() }),
execute: async ({ city }) => ({ temp: 22, city }),
}),
};
const result = streamText({
model: openai("gpt-4o"),
messages,
tools,
stopWhen: stepCountIs(5),
});tsx
// Frontend
import { makeAssistantToolUI } from "@assistant-ui/react";
const WeatherToolUI = makeAssistantToolUI({
toolName: "get_weather",
render: ({ args, result, status }) => {
if (status === "running") return <div>Loading weather...</div>;
return <div>{result?.city}: {result?.temp}°C</div>;
},
});
// Register in app
<AssistantRuntimeProvider runtime={runtime}>
<WeatherToolUI />
<Thread />
</AssistantRuntimeProvider>ts
// Backend (app/api/chat/route.ts)
import { tool, stepCountIs } from "ai";
import { z } from "zod";
const tools = {
get_weather: tool({
description: "Get weather for a city",
inputSchema: z.object({ city: z.string() }),
execute: async ({ city }) => ({ temp: 22, city }),
}),
};
const result = streamText({
model: openai("gpt-4o"),
messages,
tools,
stopWhen: stepCountIs(5),
});tsx
// Frontend
import { makeAssistantToolUI } from "@assistant-ui/react";
const WeatherToolUI = makeAssistantToolUI({
toolName: "get_weather",
render: ({ args, result, status }) => {
if (status === "running") return <div>Loading weather...</div>;
return <div>{result?.city}: {result?.temp}°C</div>;
},
});
// Register in app
<AssistantRuntimeProvider runtime={runtime}>
<WeatherToolUI />
<Thread />
</AssistantRuntimeProvider>Frontend-Only Tool
仅前端工具
tsx
import { makeAssistantTool } from "@assistant-ui/react";
import { z } from "zod";
const CopyTool = makeAssistantTool({
toolName: "copy_to_clipboard",
parameters: z.object({ text: z.string() }),
execute: async ({ text }) => {
await navigator.clipboard.writeText(text);
return { success: true };
},
});
<AssistantRuntimeProvider runtime={runtime}>
<CopyTool />
<Thread />
</AssistantRuntimeProvider>tsx
import { makeAssistantTool } from "@assistant-ui/react";
import { z } from "zod";
const CopyTool = makeAssistantTool({
toolName: "copy_to_clipboard",
parameters: z.object({ text: z.string() }),
execute: async ({ text }) => {
await navigator.clipboard.writeText(text);
return { success: true };
},
});
<AssistantRuntimeProvider runtime={runtime}>
<CopyTool />
<Thread />
</AssistantRuntimeProvider>API Reference
API参考
tsx
// makeAssistantToolUI props
interface ToolUIProps {
toolCallId: string;
toolName: string;
args: Record<string, unknown>;
argsText: string;
result?: unknown;
status: "running" | "complete" | "incomplete" | "requires-action";
submitResult: (result: unknown) => void; // For interactive tools
}tsx
// makeAssistantToolUI props
interface ToolUIProps {
toolCallId: string;
toolName: string;
args: Record<string, unknown>;
argsText: string;
result?: unknown;
status: "running" | "complete" | "incomplete" | "requires-action";
submitResult: (result: unknown) => void; // For interactive tools
}Human-in-the-Loop
人机协作模式
tsx
const DeleteToolUI = makeAssistantToolUI({
toolName: "delete_file",
render: ({ args, status, submitResult }) => {
if (status === "requires-action") {
return (
<div>
<p>Delete {args.path}?</p>
<button onClick={() => submitResult({ confirmed: true })}>Confirm</button>
<button onClick={() => submitResult({ confirmed: false })}>Cancel</button>
</div>
);
}
return <div>File deleted</div>;
},
});tsx
const DeleteToolUI = makeAssistantToolUI({
toolName: "delete_file",
render: ({ args, status, submitResult }) => {
if (status === "requires-action") {
return (
<div>
<p>Delete {args.path}?</p>
<button onClick={() => submitResult({ confirmed: true })}>Confirm</button>
<button onClick={() => submitResult({ confirmed: false })}>Cancel</button>
</div>
);
}
return <div>File deleted</div>;
},
});Common Gotchas
常见问题
Tool UI not rendering
- must match exactly (case-sensitive)
toolName - Register UI inside
AssistantRuntimeProvider
Tool not being called
- Check tool description is clear
- Use to allow multi-step
stopWhen: stepCountIs(n)
Result not showing
- Tool must return a value
- Check before accessing result
status === "complete"
工具UI未渲染
- 必须完全匹配(区分大小写)
toolName - 在内部注册UI
AssistantRuntimeProvider
工具未被调用
- 检查工具描述是否清晰
- 使用来允许多步骤执行
stopWhen: stepCountIs(n)
结果未显示
- 工具必须返回值
- 在访问结果前检查
status === "complete"