Handling Tool Calls
Monitor and respond to AI agent tool executions in real-time on the client side.
Overview
When AI agents use tools (functions) during conversations, you can monitor these tool calls on the client side. Tool calls and their results are now part of the conversation history, making them easy to display and track. This is useful for:
- Real-time UI updates: Show users what actions the AI is performing
- Progress indicators: Display loading states during tool execution
- Interactive confirmations: Allow users to approve/deny tool actions
- Analytics and logging: Track tool usage and effectiveness
- Conversation history: Tool calls appear in the conversation alongside messages
Basic Tool Call Monitoring
You can monitor tool calls in two ways:
1. Through Conversation History
Tool calls and results are automatically added to the conversation history:
import { Micdrop } from '@micdrop/client'
// Access conversation including tool calls and results
const conversation = Micdrop.conversation
conversation.forEach((item, index) => {
switch (item.role) {
case 'tool_call':
console.log('Tool called:', item.toolName)
console.log('Parameters:', JSON.parse(item.parameters))
break
case 'tool_result':
console.log('Tool result:', item.toolName)
console.log('Output:', JSON.parse(item.output))
break
case 'user':
case 'assistant':
console.log(`${item.role}: ${item.content}`)
break
}
})
2. Through Real-time Events
Listen for tool call events using the Micdrop client:
import { Micdrop } from '@micdrop/client'
// Listen for tool calls from the AI agent
Micdrop.on('ToolCall', (toolCall) => {
console.log('AI is using tool:', toolCall.name)
console.log('Parameters:', toolCall.parameters)
console.log('Result:', toolCall.output)
})
Only tools with the emitOutput
option enabled will emit ToolCall
events.
Tool Call Structure
Each tool call event contains complete information about the tool execution:
interface ToolCall {
name: string // Name of the tool that was called
parameters: any // Parameters passed to the tool
output: any // Result returned by the tool
}
React Example
Update your interface based on specific tool calls:
import { useMicdropState } from '@micdrop/react'
import { useState, useEffect } from 'react'
function SmartInterface() {
const [userProfile, setUserProfile] = useState(null)
const [emailStatus, setEmailStatus] = useState(null)
const { isStarted } = useMicdropState()
useEffect(() => {
if (!isStarted) return
const handleToolCall = (toolCall) => {
// Handle different tool types
switch (toolCall.name) {
case 'save_user_data':
// Update user profile in UI
if (toolCall.output.success) {
setUserProfile({
...toolCall.parameters,
id: toolCall.output.userId,
lastUpdated: new Date(),
})
}
break
case 'send_email':
// Show email status
setEmailStatus({
sent: toolCall.output.sent,
messageId: toolCall.output.messageId,
recipient: toolCall.parameters.to,
timestamp: new Date(),
})
break
case 'search_database':
// Could trigger a UI update with search results
console.log(`Found ${toolCall.output.results.length} results`)
break
}
}
Micdrop.on('ToolCall', handleToolCall)
return () => {
Micdrop.off('ToolCall', handleToolCall)
}
}, [isStarted])
return (
<div className="smart-interface">
{userProfile && (
<div className="user-profile">
<h3>User Profile</h3>
<p>Name: {userProfile.name}</p>
<p>Email: {userProfile.email}</p>
<p>ID: {userProfile.id}</p>
<small>
Last updated: {userProfile.lastUpdated.toLocaleString()}
</small>
</div>
)}
{emailStatus && (
<div className="email-status">
<h3>Email Status</h3>
<p>
{emailStatus.sent ? '✅ Sent' : '❌ Failed'} to{' '}
{emailStatus.recipient}
</p>
{emailStatus.messageId && (
<small>Message ID: {emailStatus.messageId}</small>
)}
</div>
)}
</div>
)
}
Server-side implementation
Agents can pass tool calls output to the client by emitting the ToolCall
event.
For example, the OpenAI Agent emits the ToolCall
event when a tool is called with the emitOutput
option enabled.