Skip to content

🔧 Give Your AI Real-World Superpowers

Your AI is already powerful - it can chat, generate images, transcribe audio, and more. But what if it could take real actions in the world? 🔧

Right now your AI can only talk about things. But what if it could actually DO things - check weather, query databases, send emails, perform calculations, and interact with any tool or API you give it?

What we’re building: An intelligent AI agent that can call real functions and tools to accomplish tasks beyond just conversation!


Current limitation: Your AI can only talk about things it knows
New superpower: Your AI can actually perform real-world actions!

Before (Chatbot):

User: "What's the weather in Tokyo?"
AI: "I don't have access to current weather data" 😕

After (Intelligent Agent):

User: "What's the weather in Tokyo?"
AI: [Calls weather function] "It's currently 15°C and rainy in Tokyo, with 80% humidity" 🌧️

The magic: Your AI becomes a real-world problem solver that can take actions, not just give advice!

🚀 Why Function Calling Changes Everything

Section titled “🚀 Why Function Calling Changes Everything”

Real-world scenarios your AI agent will handle:

  • 🌦️ Weather checking - “What’s the weather?” → Calls weather API for real data
  • 🧮 Precise calculations - “Calculate 15% tip on $127.50” → Uses calculator for accuracy
  • 🔍 Database queries - “Find user Alice” → Searches your actual database
  • 📧 Email sending - “Send meeting reminder” → Composes and sends real emails
  • 📅 Calendar management - “Schedule meeting” → Checks availability and books time
  • 🛠️ API integration - Connect to any external service or tool

Chatbot vs. Intelligent Agent:

❌ Chatbot: "I think the weather might be nice"
✅ Agent: [Calls weather API] "It's 22°C and sunny"
❌ Chatbot: "15% of $127.50 is approximately $19"
✅ Agent: [Calls calculator] "15% of $127.50 is exactly $19.13"
❌ Chatbot: "You should check your database for Alice"
✅ Agent: [Queries database] "Found Alice Johnson: alice@example.com"

🧠 Understanding Function Calling Architecture

Section titled “🧠 Understanding Function Calling Architecture”

Function calling transforms your AI through a simple 3-step process:

🎯 Step 1: You Define Tools - Create functions for specific tasks (weather, math, database) 🤖 Step 2: AI Decides When to Use - AI determines which tools are needed for each request ⚡ Step 3: AI Executes & Responds - Functions run automatically and AI uses results

Example conversation flow:

1. User: "What's the weather in Paris and calculate a 20% tip on €45?"
2. AI thinks: "I need weather data AND math calculation"
3. AI calls: get_weather("Paris, France") + calculate("45 * 0.20")
4. Functions return: {temp: 18°C, condition: "partly cloudy"} + {result: 9}
5. AI responds: "It's 18°C and partly cloudy in Paris. A 20% tip on €45 would be €9."

The beauty: Your AI automatically knows which tools to use and when!


🧠 Step 1: Understanding Function Calling Integration

Section titled “🧠 Step 1: Understanding Function Calling Integration”

Before we write any code, let’s understand how function calling works and why it transforms your AI from a conversation partner into an intelligent agent.

Function calling is like giving your AI hands to interact with the real world. Instead of being limited to its training knowledge, your AI can use tools you create to get live data, perform calculations, and take real actions.

Real-world analogy: It’s like hiring a personal assistant who doesn’t just know things, but can actually DO things - check your calendar, look up information, send messages, and complete tasks for you.

Why Function Calling vs. Your Existing Features

Section titled “Why Function Calling vs. Your Existing Features”

You already have incredible AI capabilities, but function calling is different:

🗺️ Image Generation - AI creates visual content (creative output)
🔧 Function Calling - AI performs real-world actions (practical tools)

🔊 Voice Interaction - AI communicates naturally (interface enhancement)
🔧 Function Calling - AI executes tasks for you (workflow automation)

The key difference: Function calling allows your AI to take actions beyond just generating responses, making it a true intelligent agent.

Your function calling integration will use OpenAI’s built-in function calling capabilities:

🔧 OpenAI Function Calling - The Intelligent Agent Engine

  • Best for: Connecting AI to real-world tools and APIs
  • Strengths: Automatic tool selection, parameter validation, multi-step workflows
  • Use cases: Data retrieval, calculations, external API integration, task automation
  • Think of it as: Your AI’s toolbox for taking real actions

Key capabilities:

  • Smart tool selection - AI automatically chooses the right functions
  • Parameter handling - Validates and formats function inputs correctly
  • Multi-tool coordination - Can use multiple functions in a single response
  • Error handling - Graceful fallbacks when functions fail

🔧 Step 2: Adding Function Calling to Your Backend

Section titled “🔧 Step 2: Adding Function Calling to Your Backend”

Let’s add function calling to your existing backend using the same patterns you learned in previous modules. We’ll create real functions your AI can use and the routes to handle function-powered interactions.

Building on your foundation: You already have a working Node.js server with OpenAI integration. We’re simply adding intelligent agent capabilities to what you’ve built.

Step 2A: Understanding Function Calling State

Section titled “Step 2A: Understanding Function Calling State”

Before writing code, let’s understand what data our function calling system needs to manage:

// 🧠 FUNCTION CALLING STATE CONCEPTS:
// 1. Function Definitions - Telling AI what tools are available
// 2. Parameter Schemas - Defining what inputs each function needs
// 3. Function Execution - Running the actual function code safely
// 4. Result Processing - Formatting function outputs for AI responses
// 5. Conversation Context - Managing multi-step function workflows
// 6. Error Handling - Graceful failures when functions don't work

Key function calling concepts:

  • Tool Registry: Your collection of available functions
  • Schema Validation: Ensuring function calls have correct parameters
  • Execution Safety: Running functions without breaking your app
  • Response Integration: Combining function results with AI conversation

Step 2B: Creating Real Functions for AI to Use

Section titled “Step 2B: Creating Real Functions for AI to Use”

First, let’s create the actual functions our AI can call. These are real JavaScript functions that perform actual tasks. Add this to your index.js file:

// 🔧 FUNCTION IMPLEMENTATIONS: Real tools for AI to use
// Weather function (demo with mock data - replace with real weather API)
const get_weather = async (location) => {
// 🌤️ WEATHER DEMO: Mock weather data (in production, use OpenWeatherMap API)
const mockWeatherData = {
"paris, france": { temperature: 18, condition: "partly cloudy", humidity: 65 },
"new york, usa": { temperature: 22, condition: "sunny", humidity: 45 },
"tokyo, japan": { temperature: 15, condition: "rainy", humidity: 80 },
"london, uk": { temperature: 12, condition: "overcast", humidity: 70 },
"sydney, australia": { temperature: 25, condition: "sunny", humidity: 40 },
"berlin, germany": { temperature: 8, condition: "foggy", humidity: 85 }
};
const locationKey = location.toLowerCase();
const weather = mockWeatherData[locationKey] || {
temperature: Math.floor(Math.random() * 30) + 5, // Random temp between 5-35°C
condition: ["sunny", "cloudy", "rainy", "partly cloudy"][Math.floor(Math.random() * 4)],
humidity: Math.floor(Math.random() * 50) + 30 // Random humidity 30-80%
};
console.log(`🌤️ Weather called for: ${location}`);
return {
location: location,
temperature: weather.temperature,
condition: weather.condition,
humidity: weather.humidity,
timestamp: new Date().toISOString()
};
};
// Calculator function for perfect mathematical precision
const calculate = async (expression) => {
try {
console.log(`🧮 Calculator called with: ${expression}`);
// 🧮 MATH PRECISION: Safe expression evaluation
// Basic implementation - in production, consider using math.js for advanced functions
const sanitizedExpression = expression.replace(/[^0-9+\-*/.() ]/g, '');
if (!sanitizedExpression) {
throw new Error('Invalid mathematical expression');
}
const result = Function(`"use strict"; return (${sanitizedExpression})`)();
if (typeof result !== 'number' || !isFinite(result)) {
throw new Error('Calculation resulted in invalid number');
}
return {
expression: expression,
result: Math.round(result * 100) / 100, // Round to 2 decimal places
timestamp: new Date().toISOString()
};
} catch (error) {
console.error(`🧮 Calculation error:`, error);
return {
expression: expression,
error: "Invalid expression - please use basic math operators (+, -, *, /, parentheses)",
timestamp: new Date().toISOString()
};
}
};
// Database query function (demo with mock data - replace with real database)
const query_database = async (query, table = "users") => {
console.log(`🗄️ Database query: ${query} in table: ${table}`);
// 🗄️ DATABASE DEMO: Mock database data (in production, use real database)
const mockData = {
users: [
{ id: 1, name: "Alice Johnson", email: "alice@example.com", role: "admin", joined: "2023-01-15" },
{ id: 2, name: "Bob Smith", email: "bob@example.com", role: "user", joined: "2023-03-22" },
{ id: 3, name: "Carol Davis", email: "carol@example.com", role: "moderator", joined: "2023-02-10" },
{ id: 4, name: "David Wilson", email: "david@example.com", role: "user", joined: "2023-04-05" },
{ id: 5, name: "Eva Martinez", email: "eva@example.com", role: "admin", joined: "2023-01-30" }
],
products: [
{ id: 1, name: "MacBook Pro", price: 1299, category: "electronics", stock: 15 },
{ id: 2, name: "JavaScript Guide", price: 35, category: "education", stock: 50 },
{ id: 3, name: "Wireless Headphones", price: 199, category: "electronics", stock: 23 },
{ id: 4, name: "Office Chair", price: 299, category: "furniture", stock: 8 },
{ id: 5, name: "Python Course", price: 89, category: "education", stock: 100 }
]
};
const data = mockData[table] || [];
// 🔍 SIMPLE SEARCH: Basic query simulation (use proper SQL/NoSQL in production)
let results = data;
// Search by name
if (query.toLowerCase().includes("name")) {
const searchTerm = query.match(/name.*['"]([^'"]*)['"]|name\s+(\w+)/i)?.[1] || query.match(/name\s+(\w+)/i)?.[1];
if (searchTerm) {
results = data.filter(item =>
item.name.toLowerCase().includes(searchTerm.toLowerCase())
);
}
}
// Search by role (users table)
if (query.toLowerCase().includes("role") && table === "users") {
const roleTerm = query.match(/role.*['"]([^'"]*)['"]|role\s+(\w+)/i)?.[1] || query.match(/role\s+(\w+)/i)?.[1];
if (roleTerm) {
results = data.filter(item =>
item.role.toLowerCase().includes(roleTerm.toLowerCase())
);
}
}
// Search by category (products table)
if (query.toLowerCase().includes("category") && table === "products") {
const categoryTerm = query.match(/category.*['"]([^'"]*)['"]|category\s+(\w+)/i)?.[1] || query.match(/category\s+(\w+)/i)?.[1];
if (categoryTerm) {
results = data.filter(item =>
item.category.toLowerCase().includes(categoryTerm.toLowerCase())
);
}
}
return {
query: query,
table: table,
results: results.slice(0, 5), // Limit to 5 results for display
total_found: results.length,
timestamp: new Date().toISOString()
};
};
// 📋 FUNCTION REGISTRY: Maps function names to their implementations
const AVAILABLE_FUNCTIONS = {
get_weather,
calculate,
query_database
};
console.log(`🔧 Function calling initialized with ${Object.keys(AVAILABLE_FUNCTIONS).length} functions:`, Object.keys(AVAILABLE_FUNCTIONS));

Step 2C: Adding the Function Calling Route

Section titled “Step 2C: Adding the Function Calling Route”

Now let’s add the main endpoint that handles function calling. Add this to your existing index.js file, right after your voice interaction routes:

// 🔧 FUNCTION CALLING ENDPOINT: Add this to your existing server
app.post("/api/functions/chat", async (req, res) => {
try {
// 🛡️ VALIDATION: Check required inputs
const { message, context = "[]" } = req.body;
if (!message?.trim()) {
return res.status(400).json({
error: "Message is required",
success: false
});
}
console.log(`🔧 Function calling chat: ${message}`);
// 📝 CONVERSATION CONTEXT: Parse existing conversation history
let conversationHistory = [];
try {
conversationHistory = JSON.parse(context);
} catch (error) {
console.log("Starting new function calling conversation");
}
// 🛠️ FUNCTION DEFINITIONS: Define available tools for AI
const tools = [
{
type: "function",
function: {
name: "get_weather",
description: "Get current weather conditions for any location worldwide. Use this when users ask about weather, temperature, or climate conditions.",
parameters: {
type: "object",
properties: {
location: {
type: "string",
description: "City and country, e.g. 'Paris, France' or 'New York, USA' or 'Tokyo, Japan'"
}
},
required: ["location"],
additionalProperties: false
}
}
},
{
type: "function",
function: {
name: "calculate",
description: "Perform precise mathematical calculations. Use this for any math operations, percentages, tips, conversions, or numerical computations.",
parameters: {
type: "object",
properties: {
expression: {
type: "string",
description: "Mathematical expression to evaluate. Examples: '2 + 2', '15 * 0.20', '(100 - 25) / 3', '50 * 1.15'"
}
},
required: ["expression"],
additionalProperties: false
}
}
},
{
type: "function",
function: {
name: "query_database",
description: "Search database for information about users or products. Use this when users ask about finding people, looking up products, or getting database information.",
parameters: {
type: "object",
properties: {
query: {
type: "string",
description: "Search query to find information. Include search terms like 'name Alice' or 'role admin' or 'category electronics'"
},
table: {
type: "string",
enum: ["users", "products"],
description: "Database table to search: 'users' for people/accounts, 'products' for items/inventory"
}
},
required: ["query", "table"],
additionalProperties: false
}
}
}
];
// 🤖 AI FUNCTION CALLING: Process with OpenAI Chat API
const response = await openai.chat.completions.create({
model: "gpt-4o-mini",
messages: [
{
role: "system",
content: "You are a helpful AI assistant with access to real-world tools. When users ask questions that require current data, calculations, or database lookups, use the available functions to provide accurate information. Always explain what you're doing when using tools, and present results in a clear, helpful way."
},
...conversationHistory,
{
role: "user",
content: message.trim()
}
],
tools: tools,
tool_choice: "auto"
});
// 🔄 FUNCTION EXECUTION: Handle any function calls made by AI
let finalResponse = response.choices[0].message.content;
let functionCalls = [];
let messages = [
{
role: "system",
content: "You are a helpful AI assistant with access to real-world tools. When users ask questions that require current data, calculations, or database lookups, use the available functions to provide accurate information. Always explain what you're doing when using tools, and present results in a clear, helpful way."
},
...conversationHistory,
{
role: "user",
content: message.trim()
}
];
// Check if AI wants to call functions
if (response.choices[0].message.tool_calls && response.choices[0].message.tool_calls.length > 0) {
console.log(`🔧 AI requested ${response.choices[0].message.tool_calls.length} function calls`);
// Add AI's message with tool calls to conversation
messages.push(response.choices[0].message);
// Execute each function call
for (const toolCall of response.choices[0].message.tool_calls) {
try {
const functionName = toolCall.function.name;
const functionArgs = JSON.parse(toolCall.function.arguments);
console.log(`🔧 Calling function: ${functionName} with args:`, functionArgs);
// Execute the function
if (AVAILABLE_FUNCTIONS[functionName]) {
const result = await AVAILABLE_FUNCTIONS[functionName](...Object.values(functionArgs));
functionCalls.push({
id: toolCall.id,
name: functionName,
arguments: functionArgs,
result: result,
success: true
});
// Add function result to messages
messages.push({
tool_call_id: toolCall.id,
role: "tool",
name: functionName,
content: JSON.stringify(result)
});
} else {
functionCalls.push({
id: toolCall.id,
name: functionName,
arguments: functionArgs,
error: "Function not available",
success: false
});
// Add error result to messages
messages.push({
tool_call_id: toolCall.id,
role: "tool",
name: functionName,
content: JSON.stringify({ error: "Function not available" })
});
}
} catch (error) {
console.error(`Function call error:`, error);
functionCalls.push({
id: toolCall.id,
name: toolCall.function.name,
error: error.message,
success: false
});
// Add error result to messages
messages.push({
tool_call_id: toolCall.id,
role: "tool",
name: toolCall.function.name,
content: JSON.stringify({ error: error.message })
});
}
}
// 🔄 FINAL RESPONSE: Get AI response using function results
const finalResponseCall = await openai.chat.completions.create({
model: "gpt-4o-mini",
messages: messages
});
finalResponse = finalResponseCall.choices[0].message.content;
}
// 🔄 CONVERSATION UPDATE: Update conversation history
const updatedHistory = [
...conversationHistory,
{
role: "user",
content: message.trim()
},
{
role: "assistant",
content: finalResponse
}
];
// 📤 SUCCESS RESPONSE: Send function calling results
res.json({
success: true,
message: finalResponse,
function_calls: functionCalls,
conversation_history: updatedHistory,
available_functions: tools.map(tool => ({
name: tool.function.name,
description: tool.function.description
})),
model: "gpt-4o-mini",
timestamp: new Date().toISOString()
});
} catch (error) {
// 🚨 ERROR HANDLING: Handle function calling failures
console.error("Function calling error:", error);
res.status(500).json({
error: "Failed to process function calling request",
details: error.message,
success: false
});
}
});
// 📋 FUNCTIONS LIST ENDPOINT: Get available functions
app.get("/api/functions/list", (req, res) => {
try {
const functionList = [
{
name: "get_weather",
description: "Get current weather conditions for any location",
parameters: ["location"],
example: "get_weather('Paris, France')"
},
{
name: "calculate",
description: "Perform precise mathematical calculations",
parameters: ["expression"],
example: "calculate('(25 * 4) + 10')"
},
{
name: "query_database",
description: "Search database for users or products",
parameters: ["query", "table"],
example: "query_database('name Alice', 'users')"
}
];
res.json({
success: true,
functions: functionList,
count: functionList.length,
timestamp: new Date().toISOString()
});
} catch (error) {
console.error("Function list error:", error);
res.status(500).json({
error: "Failed to get function list",
details: error.message,
success: false
});
}
});

Function breakdown:

  1. Function definitions - Tell AI what tools are available with detailed descriptions
  2. Message processing - Handle user requests with function calling capability
  3. Function execution - Run the requested functions with provided parameters
  4. Result integration - Combine function results with AI responses seamlessly
  5. Conversation management - Maintain context across function calls

🔧 Step 3: Building the React Function Calling Component

Section titled “🔧 Step 3: Building the React Function Calling Component”

Now let’s create a React component for function calling using the same patterns from your existing components.

Step 3A: Creating the Function Calling Component

Section titled “Step 3A: Creating the Function Calling Component”

Create a new file src/FunctionCalling.jsx:

import { useState, useRef, useEffect } from "react";
import { Send, Zap, Database, Calculator, Cloud, MessageSquare, Download, Trash2, Lightbulb } from "lucide-react";
function FunctionCalling() {
// 🧠 STATE: Function calling data management
const [message, setMessage] = useState(""); // User input
const [conversation, setConversation] = useState([]); // Chat history
const [isProcessing, setIsProcessing] = useState(false); // Processing status
const [availableFunctions, setAvailableFunctions] = useState([]); // Available tools
const [error, setError] = useState(null); // Error messages
const [functionCalls, setFunctionCalls] = useState([]); // Function execution history
const chatEndRef = useRef(null);
// 🔧 FUNCTIONS: Function calling logic engine
// Load available functions on component mount
useEffect(() => {
loadAvailableFunctions();
}, []);
// Auto-scroll to bottom of chat
useEffect(() => {
chatEndRef.current?.scrollIntoView({ behavior: "smooth" });
}, [conversation]);
// Load list of available functions
const loadAvailableFunctions = async () => {
try {
const response = await fetch("http://localhost:8000/api/functions/list");
const data = await response.json();
if (data.success) {
setAvailableFunctions(data.functions);
}
} catch (error) {
console.error('Failed to load functions:', error);
}
};
// Send message with function calling capability
const sendMessage = async () => {
if (!message.trim() || isProcessing) return;
const userMessage = message.trim();
setMessage("");
setIsProcessing(true);
setError(null);
// Add user message to conversation immediately
const newConversation = [
...conversation,
{ role: "user", content: userMessage, timestamp: new Date().toISOString() }
];
setConversation(newConversation);
try {
// 📤 API CALL: Send to function calling endpoint
const response = await fetch("http://localhost:8000/api/functions/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
message: userMessage,
context: JSON.stringify(conversation)
}),
});
const data = await response.json();
if (!response.ok) {
throw new Error(data.error || 'Failed to process message');
}
// ✅ SUCCESS: Update conversation and function calls
setConversation(data.conversation_history.map(msg => ({
...msg,
timestamp: new Date().toISOString()
})));
// Track function calls if any were made
if (data.function_calls && data.function_calls.length > 0) {
setFunctionCalls(prev => [...prev, ...data.function_calls.map(call => ({
...call,
timestamp: new Date().toISOString(),
message: userMessage
}))]);
}
} catch (error) {
console.error('Function calling failed:', error);
setError(error.message || 'Something went wrong while processing your message');
// Add error message to conversation
setConversation(prev => [...prev, {
role: "assistant",
content: "I'm sorry, I encountered an error while processing your request. Please try again.",
timestamp: new Date().toISOString(),
error: true
}]);
} finally {
setIsProcessing(false);
}
};
// Send a suggested query
const sendSuggestion = (query) => {
setMessage(query);
// Auto-send the suggestion
setTimeout(() => {
if (query.trim() && !isProcessing) {
const event = { target: { value: query } };
setMessage(query);
sendMessage();
}
}, 100);
};
// Handle Enter key press
const handleKeyPress = (e) => {
if (e.key === "Enter" && !e.shiftKey && !isProcessing) {
e.preventDefault();
sendMessage();
}
};
// Clear conversation
const clearConversation = () => {
setConversation([]);
setFunctionCalls([]);
setError(null);
};
// Download conversation with function calls
const downloadConversation = () => {
const exportData = {
conversation: conversation,
function_calls: functionCalls,
available_functions: availableFunctions,
timestamp: new Date().toISOString()
};
const element = document.createElement('a');
const file = new Blob([JSON.stringify(exportData, null, 2)], { type: 'application/json' });
element.href = URL.createObjectURL(file);
element.download = `function-calling-session-${Date.now()}.json`;
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
};
// Get function icon
const getFunctionIcon = (functionName) => {
switch (functionName) {
case 'get_weather': return <Cloud className="w-4 h-4" />;
case 'calculate': return <Calculator className="w-4 h-4" />;
case 'query_database': return <Database className="w-4 h-4" />;
default: return <Zap className="w-4 h-4" />;
}
};
// Format function result for display
const formatFunctionResult = (result) => {
if (typeof result === 'object') {
return JSON.stringify(result, null, 2);
}
return String(result);
};
// 🎨 UI: Interface components
return (
<div className="min-h-screen bg-gradient-to-br from-cyan-50 to-blue-50 flex items-center justify-center p-4">
<div className="bg-white rounded-2xl shadow-2xl w-full max-w-6xl flex flex-col overflow-hidden">
{/* Header */}
<div className="bg-gradient-to-r from-cyan-600 to-blue-600 text-white p-6">
<div className="flex items-center justify-between">
<div className="flex items-center space-x-3">
<div className="w-10 h-10 bg-white bg-opacity-20 rounded-full flex items-center justify-center">
<Zap className="w-5 h-5" />
</div>
<div>
<h1 className="text-xl font-bold">🔧 AI Function Calling</h1>
<p className="text-cyan-100 text-sm">AI with real-world superpowers!</p>
</div>
</div>
<div className="text-right">
<p className="text-cyan-100 text-sm">{availableFunctions.length} functions available</p>
<p className="text-cyan-200 text-xs">{functionCalls.length} calls made</p>
</div>
</div>
</div>
{/* Function Examples */}
{conversation.length === 0 && (
<div className="p-4 bg-gray-50 border-b border-gray-200">
<h3 className="font-semibold text-gray-900 mb-3 flex items-center text-sm">
<Lightbulb className="w-4 h-4 mr-2 text-cyan-600" />
Try These Function Calling Examples
</h3>
<div className="grid grid-cols-1 md:grid-cols-3 gap-3">
<div className="space-y-2">
<h4 className="font-medium text-gray-700 text-xs">Weather Queries</h4>
<button
onClick={() => sendSuggestion("What's the weather in Tokyo?")}
disabled={isProcessing}
className="w-full text-left p-2 bg-white rounded border border-gray-200 hover:border-cyan-300 hover:bg-cyan-50 transition-colors duration-200 text-xs"
>
What's the weather in Tokyo?
</button>
<button
onClick={() => sendSuggestion("Check weather in Paris, France")}
disabled={isProcessing}
className="w-full text-left p-2 bg-white rounded border border-gray-200 hover:border-cyan-300 hover:bg-cyan-50 transition-colors duration-200 text-xs"
>
Check weather in Paris, France
</button>
</div>
<div className="space-y-2">
<h4 className="font-medium text-gray-700 text-xs">Calculations</h4>
<button
onClick={() => sendSuggestion("Calculate 15% tip on $127.50")}
disabled={isProcessing}
className="w-full text-left p-2 bg-white rounded border border-gray-200 hover:border-cyan-300 hover:bg-cyan-50 transition-colors duration-200 text-xs"
>
Calculate 15% tip on $127.50
</button>
<button
onClick={() => sendSuggestion("What's 25 * 4 + 10?")}
disabled={isProcessing}
className="w-full text-left p-2 bg-white rounded border border-gray-200 hover:border-cyan-300 hover:bg-cyan-50 transition-colors duration-200 text-xs"
>
What's 25 * 4 + 10?
</button>
</div>
<div className="space-y-2">
<h4 className="font-medium text-gray-700 text-xs">Database Queries</h4>
<button
onClick={() => sendSuggestion("Find user Alice in the database")}
disabled={isProcessing}
className="w-full text-left p-2 bg-white rounded border border-gray-200 hover:border-cyan-300 hover:bg-cyan-50 transition-colors duration-200 text-xs"
>
Find user Alice in the database
</button>
<button
onClick={() => sendSuggestion("Show me all electronics products")}
disabled={isProcessing}
className="w-full text-left p-2 bg-white rounded border border-gray-200 hover:border-cyan-300 hover:bg-cyan-50 transition-colors duration-200 text-xs"
>
Show me all electronics products
</button>
</div>
</div>
</div>
)}
{/* Available Functions Display */}
<div className="p-4 bg-gray-50 border-b border-gray-200">
<h3 className="font-semibold text-gray-900 mb-3 flex items-center text-sm">
<Zap className="w-4 h-4 mr-2 text-cyan-600" />
Available Functions
</h3>
<div className="grid grid-cols-1 md:grid-cols-3 gap-3">
{availableFunctions.map((func) => (
<div key={func.name} className="bg-white rounded-lg p-3 border border-gray-200">
<div className="flex items-center mb-1">
{getFunctionIcon(func.name)}
<h4 className="font-medium text-gray-900 ml-2 text-sm">{func.name}</h4>
</div>
<p className="text-gray-600 text-xs">{func.description}</p>
<code className="text-xs text-cyan-600 bg-cyan-50 px-2 py-1 rounded mt-1 block">
{func.example}
</code>
</div>
))}
</div>
</div>
{/* Chat Area */}
<div className="flex-1 flex flex-col min-h-0">
<div className="flex-1 overflow-y-auto p-6 space-y-4">
{conversation.length === 0 ? (
<div className="text-center py-12">
<div className="w-16 h-16 bg-cyan-100 rounded-2xl flex items-center justify-center mx-auto mb-4">
<Zap className="w-8 h-8 text-cyan-600" />
</div>
<h3 className="text-lg font-semibold text-gray-700 mb-2">
Ready for Function Calling!
</h3>
<p className="text-gray-600 max-w-md mx-auto mb-4">
Ask me to check weather, perform calculations, or query the database. I'll use real functions to give you accurate results!
</p>
<div className="text-sm text-gray-500 space-y-1">
<p>💡 "What's the weather in Berlin and calculate 20% of €150?"</p>
<p>💡 "Find all admin users and show electronics products"</p>
<p>💡 "Calculate mortgage payment: (300000 * 0.05) / 12"</p>
</div>
</div>
) : (
<>
{conversation.map((msg, index) => (
<div
key={index}
className={`flex ${msg.role === 'user' ? 'justify-end' : 'justify-start'}`}
>
<div
className={`max-w-3xl px-4 py-3 rounded-lg ${
msg.role === 'user'
? 'bg-cyan-500 text-white'
: msg.error
? 'bg-red-50 text-red-700 border border-red-200'
: 'bg-gray-100 text-gray-900'
}`}
>
<p className="whitespace-pre-wrap">{msg.content}</p>
<p className="text-xs opacity-70 mt-1">
{new Date(msg.timestamp).toLocaleTimeString()}
</p>
</div>
</div>
))}
{isProcessing && (
<div className="flex justify-start">
<div className="bg-gray-100 text-gray-900 px-4 py-3 rounded-lg">
<div className="flex items-center space-x-2">
<div className="w-2 h-2 bg-cyan-600 rounded-full animate-bounce"></div>
<div className="w-2 h-2 bg-cyan-600 rounded-full animate-bounce" style={{animationDelay: '0.1s'}}></div>
<div className="w-2 h-2 bg-cyan-600 rounded-full animate-bounce" style={{animationDelay: '0.2s'}}></div>
<span className="text-sm">Thinking and calling functions...</span>
</div>
</div>
</div>
)}
<div ref={chatEndRef} />
</>
)}
</div>
{/* Function Calls Log */}
{functionCalls.length > 0 && (
<div className="border-t border-gray-200 p-4 bg-gray-50">
<h4 className="font-semibold text-gray-900 mb-2 text-sm flex items-center">
<Database className="w-4 h-4 mr-2 text-cyan-600" />
Recent Function Calls ({functionCalls.length})
</h4>
<div className="space-y-2 max-h-32 overflow-y-auto">
{functionCalls.slice(-3).map((call, index) => (
<div key={index} className="bg-white rounded p-2 border border-gray-200 text-xs">
<div className="flex items-center justify-between mb-1">
<div className="flex items-center">
{getFunctionIcon(call.name)}
<span className="font-medium ml-1">{call.name}</span>
<span className={`ml-2 px-2 py-0.5 rounded text-xs ${
call.success ? 'bg-green-100 text-green-700' : 'bg-red-100 text-red-700'
}`}>
{call.success ? 'Success' : 'Failed'}
</span>
</div>
<span className="text-gray-500">
{new Date(call.timestamp).toLocaleTimeString()}
</span>
</div>
{call.result && (
<pre className="text-xs text-gray-600 bg-gray-50 p-1 rounded overflow-hidden">
{formatFunctionResult(call.result).substring(0, 100)}...
</pre>
)}
</div>
))}
</div>
</div>
)}
{/* Error Display */}
{error && (
<div className="border-t border-red-200 bg-red-50 p-4">
<p className="text-red-700 text-sm">
<strong>Error:</strong> {error}
</p>
</div>
)}
{/* Input Area */}
<div className="border-t border-gray-200 p-4">
<div className="flex items-center space-x-3">
<div className="flex-1">
<textarea
value={message}
onChange={(e) => setMessage(e.target.value)}
onKeyPress={handleKeyPress}
rows="2"
placeholder="Ask me anything! I can check weather, calculate math, or query databases..."
disabled={isProcessing}
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-cyan-500 focus:border-transparent transition-all duration-200 resize-none disabled:bg-gray-100"
/>
</div>
<div className="space-y-2">
<button
onClick={sendMessage}
disabled={isProcessing || !message.trim()}
className="px-6 py-3 bg-gradient-to-r from-cyan-600 to-blue-600 hover:from-cyan-700 hover:to-blue-700 disabled:from-gray-300 disabled:to-gray-300 text-white rounded-lg transition-all duration-200 flex items-center space-x-2 shadow-lg disabled:shadow-none"
>
<Send className="w-4 h-4" />
<span>Send</span>
</button>
{conversation.length > 0 && (
<div className="flex space-x-1">
<button
onClick={downloadConversation}
className="p-2 bg-gray-100 text-gray-600 rounded-lg hover:bg-gray-200 transition-colors duration-200"
title="Download conversation"
>
<Download className="w-4 h-4" />
</button>
<button
onClick={clearConversation}
className="p-2 bg-red-100 text-red-600 rounded-lg hover:bg-red-200 transition-colors duration-200"
title="Clear conversation"
>
<Trash2 className="w-4 h-4" />
</button>
</div>
)}
</div>
</div>
</div>
</div>
</div>
</div>
);
}
export default FunctionCalling;

🧪 Step 4: Testing Your Function Calling

Section titled “🧪 Step 4: Testing Your Function Calling”

Let’s test your function calling feature step by step to make sure everything works correctly.

First, verify your backend routes work:

Test function calling endpoint:

Terminal window
curl -X POST http://localhost:8000/api/functions/chat \
-H "Content-Type: application/json" \
-d '{"message": "What is the weather in Paris?"}'

Test functions list endpoint:

Terminal window
curl http://localhost:8000/api/functions/list

Start both servers:

Backend (in your backend folder):

Terminal window
npm run dev

Frontend (in your frontend folder):

Terminal window
npm run dev

Test the complete flow:

  1. Navigate to Functions → Click the “Functions” tab in navigation
  2. Review available functions → See weather, calculator, and database tools
  3. Test weather function → Ask “What’s the weather in Tokyo?”
  4. Test calculator function → Ask “Calculate 15% tip on $127.50”
  5. Test database function → Ask “Find user Alice in the database”
  6. Try complex requests → Ask “What’s the weather in Paris and calculate 20% of €150?”
  7. Use example buttons → Click on suggested queries to test different functions
  8. Review function calls → See detailed logs of function executions
  9. Download conversation → Export chat with function call history

Test error scenarios:

❌ Invalid calculation: "Calculate abc + xyz"
❌ Unknown location: "Weather in made-up-city"
❌ Database errors: Query with invalid parameters
❌ Network issues: Disconnect internet during function call

Expected behavior:

  • Clear error messages displayed
  • Graceful fallback when functions fail
  • Conversation continues after errors
  • Function call history shows both successes and failures

Congratulations! You’ve extended your existing application with complete AI function calling:

  • Extended your backend with real function implementations and execution
  • Added React function calling component following the same patterns as your other features
  • Implemented intelligent agent capabilities for weather, calculations, and database queries
  • Created function call tracking with detailed execution logs
  • Added conversation management with function calling context
  • Maintained consistent design with your existing application

Your application now has:

  • Text chat with streaming responses
  • Image generation with DALL-E 3
  • Audio transcription with Whisper voice recognition
  • File analysis with intelligent document processing
  • Text-to-speech with natural voice synthesis
  • Vision analysis with GPT-4o visual intelligence
  • Voice interaction with GPT-4o Audio natural conversations
  • Function calling with real-world tool integration
  • Unified navigation between all features
  • Professional UI with consistent TailwindCSS styling

Next up: You’ll learn about Voice Interaction, where your AI can have natural spoken conversations using GPT-4o Audio - creating truly human-like AI interactions.

Your OpenAI mastery application now has real-world superpowers! 🔧