showcase/shell-docs/src/content/docs/tutorials/ai-todo-app/step-4-frontend-tools.mdx
Now it's time to make our copilot even more useful by enabling it to execute tools.
Once again, let's take a look at our app's state in the lib/hooks/use-tasks.tsx file.
Essentially, we want our copilot to be able to call the addTask, setTaskStatus and deleteTask functions.
useFrontendTool hookThe useFrontendTool hook makes tools available to our copilot. Let's implement it in the lib/hooks/use-tasks.tsx file.
// ... the rest of the file
export const TasksProvider = ({ children }: { children: ReactNode }) => {
const [tasks, setTasks] = useState<Task[]>(defaultTasks);
// [!code highlight:10]
useFrontendTool({
name: "addTask",
description: "Adds a task to the todo list",
parameters: z.object({
title: z.string().describe("The title of the task"),
}),
handler: ({ title }) => {
addTask(title);
return `Added task: ${title}`;
},
});
// [!code highlight:10]
useFrontendTool({
name: "deleteTask",
description: "Deletes a task from the todo list",
parameters: z.object({
id: z.number().describe("The id of the task"),
}),
handler: ({ id }) => {
deleteTask(id);
return `Deleted task ${id}`;
},
});
// [!code highlight:11]
useFrontendTool({
name: "setTaskStatus",
description: "Sets the status of a task",
parameters: z.object({
id: z.number().describe("The id of the task"),
status: z
.enum(Object.values(TaskStatus) as [string, ...string[]])
.describe("The status of the task"),
}),
handler: ({ id, status }) => {
setTaskStatus(id, status);
return `Set task ${id} status to ${status}`;
},
});
// ... the rest of the file
};
The useFrontendTool hook is a powerful hook that allows us to register tools with our copilot. It takes an object with the following properties:
name is the name of the tool.description is a description of the tool. It's important to choose a good description so that our copilot can choose the right tool.parameters is a Zod schema that defines the parameters the tool accepts. This provides runtime validation and TypeScript type inference.handler is a function that will be called when the tool is triggered. It's type safe thanks to Zod!You can check out the full reference for the useFrontendTool hook here.
Now, head back to the app and ask your pilot to do any of the following:
Your copilot is now more helpful than ever 💪
<Cards> <Card title="← Previous: Read app state" href="/tutorials/ai-todo-app/step-3-copilot-readable-state" description="Use useCopilotReadable so the copilot can answer questions about your todos." /> <Card title="Next: Wrap up →" href="/tutorials/ai-todo-app/next-steps" description="Find the source code, ideas for what to build next, and more tutorials." /> </Cards>