Skip to Content
ChatChat with Tools

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.

0
Counter Value

AI Assistant with Tools

Can control the counter above

Ready to chat?

Send a message to get started

How Frontend Tools Work

Frontend tools are functions registered with useAIFrontendTool that:

  1. Execute in the browser - Run client-side in your React component
  2. Have typed parameters - Use Zod schemas for validation
  3. Return structured data - Provide context back to the AI
  4. 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 sends enrichedSystemPrompt with a standardized preamble plus conditional Tools / Context / Focus sections, then appends your original systemPrompt (if any). Do not rebuild those sections on the server to avoid duplication.

API Reference

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

  1. Tool Registration: useAIFrontendTool registers tools in a global store
  2. Schema Serialization: Tool schemas are converted to JSON Schema for the backend
  3. AI Decision: The AI model decides when to call tools based on user input
  4. Execution: Tools execute in the browser and return results
  5. Context Update: Tool results are added to the conversation context
  6. 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 →

Last updated on