Spaces:
Running
Running
| import React, { useMemo } from "react"; | |
| import { Card, CardContent } from "@/components/ui/card"; | |
| import { Skeleton } from "@/components/ui/skeleton"; | |
| import { TraceAnalyticsData } from "@/hooks/useDashboardVisualizationData"; | |
| import { FileText, ArrowRight, Clock, Zap } from "lucide-react"; | |
| interface TraceAnalyticsProps { | |
| data: TraceAnalyticsData[]; | |
| isLoading?: boolean; | |
| error?: string | null; | |
| className?: string; | |
| } | |
| export function TraceAnalytics({ | |
| data, | |
| isLoading = false, | |
| error, | |
| className, | |
| }: TraceAnalyticsProps) { | |
| // Calculate key metrics | |
| const stats = useMemo(() => { | |
| if (!data.length) return null; | |
| const totalTraces = data.length; | |
| const avgReadingTime = | |
| data.reduce((sum, item) => sum + item.readingTime, 0) / totalTraces; | |
| const avgTimeWithoutAgentGraph = | |
| data.reduce((sum, item) => sum + item.timeWithoutAgentGraph, 0) / | |
| totalTraces; | |
| const avgComplexity = | |
| data.reduce((sum, item) => sum + item.complexity, 0) / totalTraces; | |
| const efficiencyMultiplier = avgTimeWithoutAgentGraph / avgReadingTime; | |
| const timeSavedMinutes = (avgTimeWithoutAgentGraph - avgReadingTime) * 3.5; | |
| // Simplified complexity calculation - 1-10 scale | |
| const complexityScore = Math.min( | |
| 10, | |
| Math.max(1, Math.round(3 + (avgComplexity / 100) * 7)) | |
| ); | |
| const readabilityGrade = Math.min(16, Math.max(6, 6 + complexityScore)); | |
| return { | |
| timeSavedMinutes, | |
| efficiencyMultiplier, | |
| complexityScore, // 1-10 scale for red circle | |
| readabilityGrade, | |
| }; | |
| }, [data]); | |
| if (error) { | |
| return ( | |
| <Card className={className}> | |
| <CardContent className="pt-6"> | |
| <div className="text-center py-4"> | |
| <p className="text-sm text-destructive">{error}</p> | |
| </div> | |
| </CardContent> | |
| </Card> | |
| ); | |
| } | |
| if (isLoading) { | |
| return ( | |
| <Card className={className}> | |
| <CardContent className="pt-6"> | |
| <Skeleton className="h-64 w-full" /> | |
| </CardContent> | |
| </Card> | |
| ); | |
| } | |
| if (data.length === 0 || !stats) { | |
| return ( | |
| <Card className={className}> | |
| <CardContent className="pt-6"> | |
| <div className="text-center py-4"> | |
| <p className="text-sm text-muted-foreground">No data available</p> | |
| </div> | |
| </CardContent> | |
| </Card> | |
| ); | |
| } | |
| return ( | |
| <Card className={className}> | |
| <CardContent className="pt-6"> | |
| <div className="space-y-6"> | |
| {/* Transformation Example */} | |
| <div className="grid grid-cols-3 gap-4 items-center"> | |
| {/* Complex Trace Example */} | |
| <div className="p-4 bg-red-50 border border-red-200 rounded-lg"> | |
| <div className="flex items-center justify-between mb-3"> | |
| <div className="flex items-center gap-2"> | |
| <FileText className="h-5 w-5 text-red-500" /> | |
| <span className="text-sm font-medium text-red-700"> | |
| Raw Agent Trace | |
| </span> | |
| </div> | |
| <div className="bg-red-500 text-white text-xs rounded-full w-6 h-6 flex items-center justify-center font-bold"> | |
| {stats.complexityScore} | |
| </div> | |
| </div> | |
| {/* Example trace content */} | |
| <div className="bg-white p-3 rounded border text-xs font-mono"> | |
| <div className="text-gray-800 mb-2"> | |
| <span className="text-blue-600">{"{"}</span> | |
| <br /> | |
| <span className="ml-2">"agent_action": "web_search",</span> | |
| <br /> | |
| <span className="ml-2">"tool_calls": [</span> | |
| <br /> | |
| <span className="ml-4">{"{"} "function": "search",</span> | |
| <br /> | |
| <span className="ml-6">"parameters": {"{"}</span> | |
| <br /> | |
| <span className="ml-8">"query": "analyze data"</span> | |
| <br /> | |
| <span className="ml-6"> | |
| {"}"} {"}"} | |
| </span> | |
| <br /> | |
| <span className="ml-2">],</span> | |
| <br /> | |
| <span className="ml-2">"reasoning": "User needs...</span> | |
| <br /> | |
| <span className="text-blue-600">{"}"}</span> | |
| </div> | |
| <div className="text-xs text-red-600 mt-2"> | |
| + 47 more nested objects... | |
| </div> | |
| </div> | |
| <div className="text-xs text-red-600 mt-2 text-center"> | |
| Complexity {stats.complexityScore}/10 • Grade{" "} | |
| {stats.readabilityGrade} | |
| </div> | |
| </div> | |
| {/* Arrow */} | |
| <div className="text-center"> | |
| <ArrowRight className="h-8 w-8 text-blue-500 mx-auto mb-2" /> | |
| <div className="text-sm font-bold text-blue-600">AgentGraph</div> | |
| <div className="text-xs text-blue-500">Auto-transforms</div> | |
| </div> | |
| {/* Agent Graph Preview */} | |
| <div className="p-4 bg-green-50 border border-green-200 rounded-lg"> | |
| <div className="flex items-center justify-between mb-3"> | |
| <div className="flex items-center gap-2"> | |
| <div className="h-5 w-5 bg-green-500 rounded-sm flex items-center justify-center"> | |
| <div className="w-2 h-2 bg-white rounded-full"></div> | |
| </div> | |
| <span className="text-sm font-medium text-green-700"> | |
| Agent Graph | |
| </span> | |
| </div> | |
| <div className="bg-green-500 text-white text-xs rounded-full w-6 h-6 flex items-center justify-center"> | |
| ✓ | |
| </div> | |
| </div> | |
| {/* Example graph visualization */} | |
| <div className="bg-white p-3 rounded border"> | |
| <div className="flex items-center justify-between mb-3"> | |
| <div className="flex items-center gap-2"> | |
| <div className="w-3 h-3 bg-blue-400 rounded-full"></div> | |
| <span className="text-xs font-medium">User</span> | |
| </div> | |
| <ArrowRight className="h-3 w-3 text-gray-400" /> | |
| <div className="flex items-center gap-2"> | |
| <div className="w-3 h-3 bg-purple-400 rounded-full"></div> | |
| <span className="text-xs font-medium">Agent</span> | |
| </div> | |
| </div> | |
| <div className="flex items-center justify-center mb-2"> | |
| <ArrowRight className="h-3 w-3 text-gray-400 rotate-90" /> | |
| </div> | |
| <div className="flex items-center gap-2 justify-center"> | |
| <div className="w-3 h-3 bg-green-400 rounded-full"></div> | |
| <span className="text-xs font-medium">Search Tool</span> | |
| </div> | |
| </div> | |
| <div className="text-xs text-green-600 mt-2 text-center"> | |
| Simplified to Grade 5 • 1/10 complexity | |
| </div> | |
| </div> | |
| </div> | |
| {/* Impact Metrics */} | |
| <div className="p-6 bg-gradient-to-r from-blue-50 to-blue-100 rounded-lg border border-blue-200"> | |
| <div className="flex items-center justify-center gap-6"> | |
| <div className="text-center"> | |
| <div className="flex items-center justify-center gap-2 mb-2"> | |
| <Clock className="h-5 w-5 text-blue-600" /> | |
| <span className="text-lg font-bold text-blue-800"> | |
| {stats.timeSavedMinutes.toFixed(0)} min saved | |
| </span> | |
| </div> | |
| <div className="text-xs text-blue-600">per trace</div> | |
| </div> | |
| <div className="w-px h-12 bg-blue-300"></div> | |
| <div className="text-center"> | |
| <div className="flex items-center justify-center gap-2 mb-2"> | |
| <Zap className="h-5 w-5 text-blue-600" /> | |
| <span className="text-lg font-bold text-blue-800"> | |
| {stats.efficiencyMultiplier.toFixed(1)}× faster | |
| </span> | |
| </div> | |
| <div className="text-xs text-blue-600">comprehension</div> | |
| </div> | |
| <div className="w-px h-12 bg-blue-300"></div> | |
| <div className="text-center"> | |
| <div className="flex items-center justify-center gap-2 mb-2"> | |
| <div className="h-5 w-5 bg-red-500 text-white rounded-full text-xs flex items-center justify-center font-bold"> | |
| {stats.complexityScore} | |
| </div> | |
| <ArrowRight className="h-4 w-4 text-blue-500" /> | |
| <div className="h-5 w-5 bg-green-500 text-white rounded-full text-xs flex items-center justify-center font-bold"> | |
| 1 | |
| </div> | |
| </div> | |
| <div className="text-xs text-blue-600"> | |
| complexity reduction | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| {/* Complexity Scale Explanation */} | |
| <div className="p-3 bg-gray-50 rounded-lg border"> | |
| <div className="text-center"> | |
| <div className="text-sm font-medium text-gray-700 mb-2"> | |
| Complexity Scale: What does "{stats.complexityScore}" mean? | |
| </div> | |
| <div className="flex items-center justify-center gap-2 text-xs text-gray-600"> | |
| <span>1-3: Simple</span> | |
| <span>•</span> | |
| <span>4-6: Moderate</span> | |
| <span>•</span> | |
| <span className="font-medium text-red-600">7-10: Complex</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </CardContent> | |
| </Card> | |
| ); | |
| } | |