diff --git a/ui/src/components/analytics/anomaly-alert-badge.tsx b/ui/src/components/analytics/anomaly-alert-badge.tsx
deleted file mode 100644
index b1eabb46..00000000
--- a/ui/src/components/analytics/anomaly-alert-badge.tsx
+++ /dev/null
@@ -1,128 +0,0 @@
-/**
- * Anomaly Alert Badge Component
- *
- * Displays detected usage anomalies with visual indicators.
- * Shows high input, I/O ratio, cost spikes, and cache read alerts.
- */
-
-import { useState } from 'react';
-import { Badge } from '@/components/ui/badge';
-import { Button } from '@/components/ui/button';
-import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
-import { AlertTriangle, ChevronDown, Zap, Gauge, DollarSign, Database } from 'lucide-react';
-import type { Anomaly, AnomalySummary, AnomalyType } from '@/hooks/use-usage';
-import { cn } from '@/lib/utils';
-
-interface AnomalyAlertBadgeProps {
- anomalies: Anomaly[];
- summary: AnomalySummary;
- className?: string;
-}
-
-const ANOMALY_CONFIG: Record<
- AnomalyType,
- { icon: React.ComponentType<{ className?: string }>; color: string; label: string }
-> = {
- high_input: { icon: Zap, color: 'text-yellow-600', label: 'High Input' },
- high_io_ratio: { icon: Gauge, color: 'text-orange-600', label: 'High I/O Ratio' },
- cost_spike: { icon: DollarSign, color: 'text-red-600', label: 'Cost Spike' },
- high_cache_read: { icon: Database, color: 'text-cyan-600', label: 'Heavy Caching' },
-};
-
-export function AnomalyAlertBadge({ anomalies, summary, className }: AnomalyAlertBadgeProps) {
- const [open, setOpen] = useState(false);
-
- if (summary.totalAnomalies === 0) {
- return (
-
- No anomalies
-
- );
- }
-
- // Get unique anomaly types for badges
- const anomalyTypes = new Set(anomalies.map((a) => a.type));
-
- return (
-
-
-
-
-
-
-
-
- Detected Anomalies
-
-
- Unusual usage patterns detected in the selected period
-
-
-
- {/* Summary badges */}
-
- {Array.from(anomalyTypes).map((type) => {
- const config = ANOMALY_CONFIG[type];
- const Icon = config.icon;
- const count = anomalies.filter((a) => a.type === type).length;
- return (
-
-
- {count} {config.label}
-
- );
- })}
-
-
- {/* Anomaly list */}
-
- {anomalies.slice(0, 10).map((anomaly, index) => {
- const config = ANOMALY_CONFIG[anomaly.type];
- const Icon = config.icon;
-
- return (
-
-
-
-
-
- {anomaly.date}
- {anomaly.model && (
-
- {truncateModel(anomaly.model)}
-
- )}
-
-
{anomaly.message}
-
-
-
- );
- })}
- {anomalies.length > 10 && (
-
- +{anomalies.length - 10} more anomalies
-
- )}
-
-
-
- );
-}
-
-function truncateModel(model: string): string {
- if (model.length <= 20) return model;
- // Try to extract the meaningful part
- const parts = model.split('-');
- if (parts.length >= 3) {
- return parts.slice(0, 3).join('-') + '...';
- }
- return model.slice(0, 17) + '...';
-}
diff --git a/ui/src/components/analytics/usage-insights-card.tsx b/ui/src/components/analytics/usage-insights-card.tsx
new file mode 100644
index 00000000..b7b48585
--- /dev/null
+++ b/ui/src/components/analytics/usage-insights-card.tsx
@@ -0,0 +1,168 @@
+import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
+import { Badge } from '@/components/ui/badge';
+import { ScrollArea } from '@/components/ui/scroll-area';
+import { CheckCircle2, Zap, Gauge, DollarSign, Database, Lightbulb } from 'lucide-react';
+import type { Anomaly, AnomalySummary, AnomalyType } from '@/hooks/use-usage';
+import { cn } from '@/lib/utils';
+
+interface UsageInsightsCardProps {
+ anomalies?: Anomaly[];
+ summary?: AnomalySummary;
+ isLoading?: boolean;
+ className?: string;
+}
+
+const ANOMALY_CONFIG: Record<
+ AnomalyType,
+ {
+ icon: React.ComponentType<{ className?: string }>;
+ color: string;
+ label: string;
+ description: string;
+ }
+> = {
+ high_input: {
+ icon: Zap,
+ color: 'text-yellow-600 dark:text-yellow-400',
+ label: 'High Input',
+ description: 'Unusually high input token usage detected.',
+ },
+ high_io_ratio: {
+ icon: Gauge,
+ color: 'text-orange-600 dark:text-orange-400',
+ label: 'High I/O Ratio',
+ description: 'Output tokens are significantly higher than input tokens.',
+ },
+ cost_spike: {
+ icon: DollarSign,
+ color: 'text-red-600 dark:text-red-400',
+ label: 'Cost Spike',
+ description: 'Daily cost is significantly higher than average.',
+ },
+ high_cache_read: {
+ icon: Database,
+ color: 'text-cyan-600 dark:text-cyan-400',
+ label: 'Heavy Caching',
+ description: 'High volume of cache read operations.',
+ },
+};
+
+export function UsageInsightsCard({
+ anomalies = [],
+ summary,
+ isLoading,
+ className,
+}: UsageInsightsCardProps) {
+ if (isLoading) {
+ return (
+
+
+
+
+ Usage Insights
+
+
+
+
+
+
+ );
+ }
+
+ const hasAnomalies = summary && summary.totalAnomalies > 0;
+
+ return (
+
+
+
+
+
+ Usage Insights
+
+ {hasAnomalies ? (
+
+ Attention Needed
+
+ ) : (
+
+ Healthy
+
+ )}
+
+
+
+
+ {hasAnomalies ? (
+
+
+ {anomalies.map((anomaly, index) => {
+ const config = ANOMALY_CONFIG[anomaly.type];
+ const Icon = config.icon;
+
+ return (
+
+
+
+
+
+
+
+
{config.label}
+
+ {anomaly.date}
+
+
+
+ {anomaly.message}
+
+ {anomaly.model && (
+
+
+ {anomaly.model}
+
+
+ )}
+
+
+
+ );
+ })}
+
+
+ ) : (
+
+
+
+
+
No anomalies detected
+
+ Your usage patterns look normal for the selected period.
+
+
+ )}
+
+
+ );
+}
diff --git a/ui/src/pages/analytics.tsx b/ui/src/pages/analytics.tsx
index 0605c248..f0f03dc1 100644
--- a/ui/src/pages/analytics.tsx
+++ b/ui/src/pages/analytics.tsx
@@ -18,7 +18,7 @@ import { UsageTrendChart } from '@/components/analytics/usage-trend-chart';
import { ModelBreakdownChart } from '@/components/analytics/model-breakdown-chart';
import { ModelDetailsContent } from '@/components/analytics/model-details-content';
import { SessionStatsCard } from '@/components/analytics/session-stats-card';
-import { AnomalyAlertBadge } from '@/components/analytics/anomaly-alert-badge';
+import { UsageInsightsCard } from '@/components/analytics/usage-insights-card';
import { TrendingUp, PieChart, RefreshCw, DollarSign, ChevronRight } from 'lucide-react';
import {
useUsageSummary,
@@ -105,10 +105,6 @@ export function AnalyticsPage() {
Track usage & insights
- {/* Anomaly Alert Badge */}
- {!isInsightsLoading && insights && (
-
- )}
- {/* Session Stats - 4/10 width */}
+ {/* Session Stats - 2/10 width */}
+
+ {/* Usage Insights - 2/10 width */}
+