Real-Time Tool Execution Tracking
Implemented: 2025-08-09
Component: ChatInterface.jsx
Phase: 2, Item 5 of Tool Message UX Improvements
Overview
Real-time execution tracking provides live feedback on tool operations, showing users exactly how long each tool takes to execute. This feature displays running timers that update in real-time and preserves execution times for completed operations.
Purpose
Problems Solved
- Users had no visibility into how long tools were taking to execute
- No feedback during long-running operations (builds, searches, etc.)
- Difficult to identify performance bottlenecks
- No way to compare execution times across similar operations
Benefits
- Transparency: Users see exactly how long each operation takes
- Feedback: Live timers provide reassurance that tools are still running
- Performance Insights: Identify slow operations that need optimization
- Better UX: Reduces uncertainty during long operations
Technical Implementation
State Management
// Tool execution tracking state
const [toolExecutions, setToolExecutions] = useState(new Map());
const [, forceUpdate] = useState(0); // For forcing re-renders
// Execution record structure
{
toolId: {
status: 'running' | 'complete' | 'failed',
startTime: Date.now(), // Timestamp in milliseconds
endTime: Date.now() // Set when tool completes
}
}
Live Timer Updates
// Update running tool timers every 100ms
useEffect(() => {
const interval = setInterval(() => {
const hasRunningTools = Array.from(toolExecutions.values()).some(
exec => exec.status === 'running'
);
if (hasRunningTools) {
forceUpdate(prev => prev + 1); // Trigger re-render
}
}, 100);
return () => clearInterval(interval);
}, [toolExecutions]);
Lifecycle Tracking
1. Tool Start
When a tool message arrives via WebSocket:
setToolExecutions(prev => {
const newMap = new Map(prev);
newMap.set(part.id, {
status: 'running',
startTime: Date.now()
});
return newMap;
});
2. Tool Completion
When a tool result arrives:
setToolExecutions(prev => {
const newMap = new Map(prev);
const execution = newMap.get(part.tool_use_id);
if (execution) {
execution.status = part.is_error ? 'failed' : 'complete';
execution.endTime = Date.now();
}
return newMap;
});
Time Calculation
const getElapsedTime = (startTime, endTime = Date.now()) => {
const elapsed = (endTime - startTime) / 1000;
if (elapsed < 1) {
return `${Math.round(elapsed * 1000)}ms`; // Milliseconds
} else if (elapsed < 60) {
return `${elapsed.toFixed(1)}s`; // Seconds
} else {
const minutes = Math.floor(elapsed / 60);
const seconds = Math.floor(elapsed % 60);
return `${minutes}m ${seconds}s`; // Minutes
}
};
Visual Design
Status Badge Display
The execution time appears in the status badge next to the status text:
<span className="px-2 py-1 text-xs font-medium ... rounded flex items-center gap-1">
{status} {elapsedTime && <span className="opacity-75">β’ {elapsedTime}</span>}
</span>
Visual States
Running (Blue badge)
- Shows:
running β’ 2.3s(updates every 100ms) - Animated spinner icon
- Timer counts up in real-time
- Shows:
Completed (Green badge)
- Shows:
completed β’ 1.2s - Check mark icon
- Displays final execution time
- Shows:
Failed (Red badge)
- Shows:
failed β’ 0.8s - X icon
- Shows time until failure
- Shows:
Performance Considerations
Optimizations
- Conditional Updates: Only runs interval when tools are active
- 100ms Interval: Balanced between smooth updates and performance
- Map Data Structure: O(1) lookups for tool execution data
- Memoized Components: MessageComponent uses React.memo to prevent unnecessary re-renders
Resource Usage
- Memory: Minimal - stores timing for active session only
- CPU: Low impact - simple time calculations every 100ms
- Network: No additional network calls required
Example Scenarios
Quick Operation
Tool: Read file
Display: completed β’ 245ms
Medium Operation
Tool: Running npm install
Display: running β’ 5.2s β completed β’ 8.7s
Long Operation
Tool: Building project
Display: running β’ 1m 23s β completed β’ 2m 45s
Failed Operation
Tool: Git push
Display: running β’ 3.2s β failed β’ 3.4s
Future Enhancements
Potential Improvements
- Progress Bars: For operations with known steps
- Time Estimates: Based on historical execution times
- Performance Warnings: Alert when operations take unusually long
- Execution History: Track and display average times
- Batch Timing: Group timing for related operations
Advanced Features
- Queue Position: Show position when multiple tools are pending
- Parallel Execution: Display concurrent tool operations
- Time Breakdowns: Show phases within long operations
- Performance Metrics: Daily/weekly execution statistics
Usage Notes
For Developers
- Tool IDs must be unique for proper tracking
- Ensure tool_result messages include the correct tool_use_id
- Handle edge cases where tools may not send completion messages
For Users
- Times shown are actual execution times, not estimates
- Network latency is included in the displayed times
- Failed operations show time until failure occurred
- Times persist for the current session only
Troubleshooting
Common Issues
Timer Not Updating
- Check if toolExecutions state is properly initialized
- Verify useEffect interval is running
- Ensure forceUpdate is triggering re-renders
Wrong Times Displayed
- Verify tool IDs match between start and completion
- Check Date.now() timestamp accuracy
- Ensure endTime is set on completion
Missing Execution Data
- Confirm WebSocket messages include tool IDs
- Check that state updates aren't being overwritten
- Verify Map operations preserve existing data
Related Documentation
Success Metrics
- User Feedback: Reduced uncertainty during long operations
- Performance Visibility: Clear identification of slow tools
- Debugging: Easier to diagnose timeout issues
- UX Improvement: More professional, responsive interface
This feature significantly enhances the tool message experience by providing real-time feedback that keeps users informed about operation progress and performance.