Chat with Tools
Frontend tools allow the AI to execute functions in your React components, enabling direct interaction with your UI and state. This creates powerful experiences where the AI can manipulate widgets, update data, and trigger actions based on user requests.
AI Assistant with Tools
• Can control the counter aboveHow Frontend Tools Work
Frontend tools are functions registered with useAIFrontendTool
that:
- Execute in the browser - Run client-side in your React component
- Have typed parameters - Use Zod schemas for validation
- Return structured data - Provide context back to the AI
- Update your UI - Can modify component state and trigger re-renders
Basic Tool Registration
The useAIFrontendTool
hook registers tools that the AI can call:
import { useAIFrontendTool } from "ai-chat-bootstrap";
import { z } from "zod";
function CounterWidget() {
const [counter, setCounter] = useState(0);
useAIFrontendTool({
name: "increment_counter",
description: "Increment the counter by a specified amount",
parameters: z.object({
amount: z.number().default(1).describe("Amount to increment by"),
}),
execute: async (params: { amount: number }) => {
const newValue = counter + params.amount;
setCounter(newValue);
return {
newValue,
amount: params.amount,
message: `Counter incremented by ${params.amount}. New value: ${newValue}`
};
},
});
return <div>Counter: {counter}</div>;
}
Frontend Implementation
Here’s the complete frontend code showing tool registration and chat integration:
"use client";
import React, { useState } from "react";
import { ChatContainer, useAIChat, useAIFrontendTool } from "ai-chat-bootstrap";
import { z } from "zod";
export function ChatWithTools() {
const [counter, setCounter] = useState(0);
// Register frontend tools that AI can use
useAIFrontendTool({
name: "increment_counter",
description: "Increment the counter by a specified amount",
parameters: z.object({
amount: z.number().default(1).describe("Amount to increment by"),
}),
execute: async (params: { amount: number }) => {
const newValue = counter + params.amount;
setCounter(newValue);
return {
newValue,
amount: params.amount,
message: `Counter incremented by ${params.amount}. New value: ${newValue}`
};
},
});
useAIFrontendTool({
name: "decrement_counter",
description: "Decrement the counter by a specified amount",
parameters: z.object({
amount: z.number().default(1).describe("Amount to decrement by"),
}),
execute: async (params: { amount: number }) => {
const newValue = counter - params.amount;
setCounter(newValue);
return {
newValue,
amount: params.amount,
message: `Counter decremented by ${params.amount}. New value: ${newValue}`
};
},
});
const chat = useAIChat({
api: "/api/chat",
systemPrompt: "You are a helpful assistant that can control a counter widget. Use the increment_counter and decrement_counter tools when users ask you to change the counter value."
});
return (
<div className="space-y-4">
{/* Counter Display */}
<div className="flex items-center justify-center p-6 border rounded-lg bg-muted/50">
<div className="text-center">
<div className="text-4xl font-bold text-primary mb-2">{counter}</div>
<div className="text-sm text-muted-foreground">Counter Value</div>
</div>
</div>
{/* Chat Interface */}
<div className="h-[420px] w-full">
<ChatContainer
chat={chat}
header={{
title: "AI Assistant with Tools",
subtitle: "Can control the counter above",
}}
ui={{ placeholder: "Try: 'increment by 3' or 'decrease by 2'" }}
/>
</div>
</div>
);
}
Backend API Route
The backend automatically receives registered tools and can execute them:
import { createAzure } from "@ai-sdk/azure";
import { convertToModelMessages, streamText } from "ai";
const azure = createAzure({
resourceName: process.env.AZURE_RESOURCE_NAME!,
apiKey: process.env.AZURE_API_KEY!,
apiVersion: process.env.AZURE_API_VERSION ?? "preview",
});
const model = azure(process.env.AZURE_DEPLOYMENT_ID!);
export async function POST(req: Request) {
const { messages, enrichedSystemPrompt, tools } = await req.json();
const result = await streamText({
model,
messages: [
{ role: "system", content: enrichedSystemPrompt },
...convertToModelMessages(messages),
],
tools,
});
return result.toUIMessageStreamResponse();
}
Note:
useAIChat
automatically sendsenrichedSystemPrompt
with a standardized preamble plus conditional Tools / Context / Focus sections, then appends your originalsystemPrompt
(if any). Do not rebuild those sections on the server to avoid duplication.
API Reference
- Hook: useAIFrontendTool
Tool Features
Parameter Validation
Tools use Zod schemas for type-safe parameter validation:
parameters: z.object({
amount: z.number().min(1).max(100).describe("Amount to increment by"),
reason: z.string().optional().describe("Optional reason for the increment"),
})
Return Values
Tools can return structured data that the AI uses for context:
execute: async (params) => {
// Perform the operation
const result = await performAction(params);
// Return structured data for AI context
return {
success: true,
newState: result.state,
message: "Operation completed successfully",
timestamp: new Date().toISOString(),
};
}
Error Handling
Tools should handle errors gracefully:
execute: async (params) => {
try {
const result = await riskyOperation(params);
return { success: true, result };
} catch (error) {
console.error("Tool execution failed:", error);
return {
success: false,
error: error.message,
message: "Operation failed, please try again"
};
}
}
How It Works
- Tool Registration:
useAIFrontendTool
registers tools in a global store - Schema Serialization: Tool schemas are converted to JSON Schema for the backend
- AI Decision: The AI model decides when to call tools based on user input
- Execution: Tools execute in the browser and return results
- Context Update: Tool results are added to the conversation context
- UI Updates: Tools can modify React state, triggering re-renders
Next Steps
- Add Context: Use
useAIContext
to share additional app state with tools - Custom Rendering: Implement custom rendering for tool results
- Multiple Tools: Create tool libraries for different feature areas
- Tool Composition: Combine multiple tools for complex operations
Next
Continue to Tool Result Rendering →