wu981526092's picture
add
7bc750c
/**
* Trace Overview Section Component
*
* Displays trace statistics, performance metrics, and cost analytics
*/
import React from "react";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { Activity, AlertCircle, Eye, HelpCircle } from "lucide-react";
import { Trace } from "@/types";
import {
CompactMetadataCard,
CompactMetadataCardAdd,
type MetadataCardConfig,
} from "@/components/shared/CompactMetadataCard";
interface TraceOverviewSectionProps {
trace: Trace;
metadataOutdated: boolean;
currentMetadata: any;
enhancedStats: any;
enhancedStatsLoading: boolean;
onOpenTraceContent: () => void;
metadataCards: MetadataCardConfig[];
onOpenMetadataCardSelector: () => void;
}
export function TraceOverviewSection({
trace: _trace,
metadataOutdated,
currentMetadata,
enhancedStats,
enhancedStatsLoading,
onOpenTraceContent,
metadataCards,
onOpenMetadataCardSelector,
}: TraceOverviewSectionProps) {
return (
<div className="h-full">
{/* Trace Overview Section */}
<div className="border border-border/50 rounded-lg bg-background h-full">
<div className="p-4 pb-3">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2 flex-1 min-w-0">
<Activity className="h-5 w-5 text-primary" />
<h4 className="text-lg font-semibold">Trace Overview</h4>
</div>
{/* View Content Button in header */}
<Tooltip>
<TooltipTrigger asChild>
<Button
onClick={onOpenTraceContent}
size="sm"
variant="outline"
className="gap-1"
>
<Eye className="h-4 w-4" />
<span className="hidden sm:inline">View Content</span>
</Button>
</TooltipTrigger>
<TooltipContent>
<div className="max-w-sm">
<p className="font-medium mb-1 text-primary-foreground">
View Trace Content
</p>
<p className="text-xs text-primary-foreground/80">
View and edit the raw trace data in a larger window.
</p>
</div>
</TooltipContent>
</Tooltip>
</div>
{/* Subtitle */}
<p className="text-sm text-muted-foreground">
Performance metrics and trace analytics
</p>
</div>
{/* Metadata Cards Section */}
<div className="px-4 pb-3">
<div className="flex items-center gap-2 sm:gap-3 flex-wrap">
{metadataCards.map((cardConfig) => (
<CompactMetadataCard key={cardConfig.id} config={cardConfig} />
))}
<CompactMetadataCardAdd onClick={onOpenMetadataCardSelector} />
</div>
</div>
<div className="p-4 space-y-4 flex-1 overflow-hidden">
{/* Metadata Outdated Warning Banner */}
{metadataOutdated && (
<div className="bg-yellow-50 border border-yellow-200 rounded-lg p-4">
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<AlertCircle className="h-5 w-5 text-yellow-600" />
<div>
<h4 className="text-sm font-semibold text-yellow-800">
Trace Statistics May Be Outdated
</h4>
<p className="text-sm text-yellow-700">
The trace content has been modified since statistics were
generated. Consider updating for accurate metrics.
</p>
</div>
</div>
</div>
</div>
)}
<div className="space-y-4">
{/* Trace Statistics & Performance Section */}
<Card>
<CardContent className="p-3">
<div className="flex items-center gap-2 mb-3">
<Activity className="h-4 w-4" />
<h4 className="text-sm font-semibold">
Trace Statistics & Performance
</h4>
<Tooltip>
<TooltipTrigger>
<HelpCircle className="h-3 w-3 text-muted-foreground" />
</TooltipTrigger>
<TooltipContent>
<p>
Key metrics and performance data from the trace analysis
</p>
</TooltipContent>
</Tooltip>
</div>
<div className="grid grid-cols-3 gap-3">
<div className="bg-muted/30 rounded-lg p-3">
<div className="flex items-center gap-1 mb-1">
<p className="text-xs text-muted-foreground uppercase tracking-wide">
Tokens
</p>
<Tooltip>
<TooltipTrigger>
<HelpCircle className="h-3 w-3 text-muted-foreground" />
</TooltipTrigger>
<TooltipContent>
<p>Total input and output tokens used in LLM calls</p>
</TooltipContent>
</Tooltip>
</div>
<p className="text-lg font-semibold">
{(() => {
const tokens =
enhancedStats?.tokens?.total_tokens ||
currentMetadata?.schema_analytics?.numerical_overview
?.token_analytics?.total_tokens;
return tokens ? tokens.toLocaleString() : "N/A";
})()}
</p>
</div>
<div className="bg-muted/30 rounded-lg p-3">
<div className="flex items-center gap-1 mb-1">
<p className="text-xs text-muted-foreground uppercase tracking-wide">
Prompts
</p>
<Tooltip>
<TooltipTrigger>
<HelpCircle className="h-3 w-3 text-muted-foreground" />
</TooltipTrigger>
<TooltipContent>
<p>
Number of LLM prompt calls made during execution
</p>
</TooltipContent>
</Tooltip>
</div>
<p className="text-lg font-semibold">
{enhancedStats?.prompt_calls?.total_calls ||
currentMetadata?.schema_analytics?.prompt_analytics
?.prompt_calls_detected ||
"N/A"}
</p>
</div>
<div className="bg-muted/30 rounded-lg p-3">
<div className="flex items-center gap-1 mb-1">
<p className="text-xs text-muted-foreground uppercase tracking-wide">
Tools & Functions
</p>
<Tooltip>
<TooltipTrigger>
<HelpCircle className="h-3 w-3 text-muted-foreground" />
</TooltipTrigger>
<TooltipContent>
<p>
Number of tools, functions, or agent components used
during execution
</p>
</TooltipContent>
</Tooltip>
</div>
<p className="text-lg font-semibold">
{enhancedStats?.components?.total_components ||
currentMetadata?.schema_analytics?.numerical_overview
?.component_stats?.total_components ||
"N/A"}
</p>
</div>
<div className="bg-muted/30 rounded-lg p-3">
<div className="flex items-center gap-1 mb-1">
<p className="text-xs text-muted-foreground uppercase tracking-wide">
Success Rate
</p>
<Tooltip>
<TooltipTrigger>
<HelpCircle className="h-3 w-3 text-muted-foreground" />
</TooltipTrigger>
<TooltipContent>
<p>Percentage of successful component executions</p>
</TooltipContent>
</Tooltip>
</div>
<p className="text-lg font-semibold">
{(() => {
const successRate =
enhancedStats?.components?.success_rate ||
currentMetadata?.schema_analytics?.numerical_overview
?.component_stats?.success_rate;
return successRate !== undefined && successRate !== null
? `${successRate.toFixed(1)}%`
: "N/A";
})()}
</p>
</div>
<div className="bg-muted/30 rounded-lg p-3">
<div className="flex items-center gap-1 mb-1">
<p className="text-xs text-muted-foreground uppercase tracking-wide">
Execution Time
</p>
<Tooltip>
<TooltipTrigger>
<HelpCircle className="h-3 w-3 text-muted-foreground" />
</TooltipTrigger>
<TooltipContent>
<p>Total execution time for the trace</p>
</TooltipContent>
</Tooltip>
</div>
<p className="text-lg font-semibold">
{(() => {
const totalTimeMs =
enhancedStats?.performance?.total_execution_time_ms ||
currentMetadata?.schema_analytics?.numerical_overview
?.timing_analytics?.total_execution_time_ms;
if (totalTimeMs && totalTimeMs > 0) {
if (totalTimeMs >= 1000) {
return `${(totalTimeMs / 1000).toFixed(1)}s`;
} else {
return `${totalTimeMs}ms`;
}
}
return "N/A";
})()}
</p>
</div>
<div className="bg-muted/30 rounded-lg p-3">
<div className="flex items-center gap-1 mb-1">
<p className="text-xs text-muted-foreground uppercase tracking-wide">
Call Stack Depth
</p>
<Tooltip>
<TooltipTrigger>
<HelpCircle className="h-3 w-3 text-muted-foreground" />
</TooltipTrigger>
<TooltipContent>
<p>
Maximum depth of nested function calls (how many
levels deep the execution goes)
</p>
</TooltipContent>
</Tooltip>
</div>
<p className="text-lg font-semibold">
{enhancedStats?.components?.max_depth ||
currentMetadata?.schema_analytics?.numerical_overview
?.component_stats?.max_depth ||
"N/A"}
</p>
</div>
</div>
</CardContent>
</Card>
{/* Cost & Token Analytics Section */}
{(enhancedStats?.cost || enhancedStats?.tokens) && (
<Card>
<CardContent className="p-3">
<h4 className="text-sm font-semibold mb-3 flex items-center gap-2">
<Activity className="h-4 w-4" />
Cost & Token Analytics
<Tooltip>
<TooltipTrigger>
<HelpCircle className="h-3 w-3 text-muted-foreground" />
</TooltipTrigger>
<TooltipContent>
<p>
Cost breakdown and token usage analytics for LLM calls
</p>
</TooltipContent>
</Tooltip>
</h4>
{enhancedStats?.cost && (
<div className="bg-gradient-to-r from-green-50 to-emerald-50 border border-green-200 rounded-lg p-3 mb-3">
<div className="flex items-start justify-between">
{/* Left side: Model and Cost */}
<div className="flex-1">
<p className="text-lg font-bold text-green-800 mb-1">
{enhancedStats?.cost?.model_used || "gpt-5-mini"}
</p>
<p className="text-base font-semibold text-green-600">
Avg:{" "}
{enhancedStatsLoading
? "Loading..."
: enhancedStats?.cost?.avg_cost_per_call_usd
? `$${enhancedStats.cost.avg_cost_per_call_usd.toFixed(
6
)}/call`
: "$0.00/call"}
</p>
</div>
{/* Right side: Model Information */}
{enhancedStats?.cost?.model_metadata && (
<div className="ml-4 text-xs text-green-700 space-y-1">
{enhancedStats.cost.model_metadata
.litellm_provider && (
<div className="flex items-center gap-1">
<span className="font-medium">Provider:</span>
<span className="capitalize">
{
enhancedStats.cost.model_metadata
.litellm_provider
}
</span>
</div>
)}
{enhancedStats.cost.model_metadata
.max_input_tokens && (
<div className="flex items-center gap-1">
<span className="font-medium">Max Input:</span>
<span>
{enhancedStats.cost.model_metadata.max_input_tokens.toLocaleString()}{" "}
tokens
</span>
</div>
)}
{enhancedStats.cost.model_metadata
.max_output_tokens && (
<div className="flex items-center gap-1">
<span className="font-medium">Max Output:</span>
<span>
{enhancedStats.cost.model_metadata.max_output_tokens.toLocaleString()}{" "}
tokens
</span>
</div>
)}
{/* Capabilities */}
<div className="flex flex-wrap gap-1 mt-2">
{enhancedStats.cost.model_metadata
.supports_function_calling && (
<Tooltip>
<TooltipTrigger>
<span className="px-1.5 py-0.5 bg-green-200 text-green-800 rounded text-xs cursor-help">
Functions
</span>
</TooltipTrigger>
<TooltipContent>
<p>
Model supports function calling - can
execute predefined functions and tools
during conversations
</p>
</TooltipContent>
</Tooltip>
)}
{enhancedStats.cost.model_metadata
.supports_vision && (
<Tooltip>
<TooltipTrigger>
<span className="px-1.5 py-0.5 bg-blue-200 text-blue-800 rounded text-xs cursor-help">
Vision
</span>
</TooltipTrigger>
<TooltipContent>
<p>
Model supports vision capabilities - can
analyze and understand images, charts, and
visual content
</p>
</TooltipContent>
</Tooltip>
)}
{enhancedStats.cost.model_metadata
.supports_response_schema && (
<Tooltip>
<TooltipTrigger>
<span className="px-1.5 py-0.5 bg-purple-200 text-purple-800 rounded text-xs cursor-help">
Schema
</span>
</TooltipTrigger>
<TooltipContent>
<p>
Model supports structured output schemas -
can return responses in predefined JSON
formats
</p>
</TooltipContent>
</Tooltip>
)}
{enhancedStats.cost.model_metadata
.supports_prompt_caching && (
<Tooltip>
<TooltipTrigger>
<span className="px-1.5 py-0.5 bg-orange-200 text-orange-800 rounded text-xs cursor-help">
Caching
</span>
</TooltipTrigger>
<TooltipContent>
<p>
Model supports prompt caching - can cache
common prompts to reduce latency and costs
</p>
</TooltipContent>
</Tooltip>
)}
</div>
</div>
)}
</div>
</div>
)}
<div className="grid grid-cols-3 gap-2">
{/* Total Tokens & Cost */}
<div className="bg-muted/30 rounded-lg p-2.5">
<div className="text-center">
<p className="text-xs text-muted-foreground uppercase tracking-wide mb-1">
Total Tokens
</p>
<p className="text-lg font-bold mb-1">
{enhancedStatsLoading
? "..."
: enhancedStats?.tokens?.total_tokens?.toLocaleString() ||
"N/A"}
</p>
{enhancedStats?.cost && (
<div className="mt-2 pt-2 border-t border-muted-foreground/20">
<p className="text-sm font-bold text-green-700">
{enhancedStatsLoading
? "..."
: enhancedStats?.cost?.total_cost_usd
? `$${enhancedStats.cost.total_cost_usd.toFixed(
6
)}`
: "$0.00"}
</p>
</div>
)}
</div>
</div>
{/* Input Tokens & Cost */}
<div className="bg-muted/30 rounded-lg p-2.5">
<div className="text-center">
<p className="text-xs text-muted-foreground uppercase tracking-wide mb-1">
Input Tokens
</p>
<p className="text-lg font-bold mb-1">
{enhancedStatsLoading
? "..."
: enhancedStats?.tokens?.total_prompt_tokens?.toLocaleString() ||
"N/A"}
</p>
{enhancedStats?.cost && (
<div className="mt-2 pt-2 border-t border-muted-foreground/20">
<p className="text-sm font-bold text-blue-700">
{enhancedStatsLoading
? "..."
: enhancedStats?.cost?.input_cost_usd
? `$${enhancedStats.cost.input_cost_usd.toFixed(
6
)}`
: "$0.00"}
</p>
</div>
)}
</div>
</div>
{/* Output Tokens & Cost */}
<div className="bg-muted/30 rounded-lg p-2.5">
<div className="text-center">
<p className="text-xs text-muted-foreground uppercase tracking-wide mb-1">
Output Tokens
</p>
<p className="text-lg font-bold mb-1">
{enhancedStatsLoading
? "..."
: enhancedStats?.tokens?.total_completion_tokens?.toLocaleString() ||
"N/A"}
</p>
{enhancedStats?.cost && (
<div className="mt-2 pt-2 border-t border-muted-foreground/20">
<p className="text-sm font-bold text-purple-700">
{enhancedStatsLoading
? "..."
: enhancedStats?.cost?.output_cost_usd
? `$${enhancedStats.cost.output_cost_usd.toFixed(
6
)}`
: "$0.00"}
</p>
</div>
)}
</div>
</div>
</div>
</CardContent>
</Card>
)}
</div>
</div>
</div>
</div>
);
}