Skip to content

Commit 2ff6368

Browse files
committed
Add usage metrics to agent page
1 parent 6f2cd3a commit 2ff6368

File tree

3 files changed

+154
-3
lines changed

3 files changed

+154
-3
lines changed

web/src/app/agents/page.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ const AgentStorePage = () => {
7777
switch (sortBy) {
7878
case 'usage':
7979
return (b.usage_count || 0) - (a.usage_count || 0)
80+
case 'unique_users':
81+
return (b.unique_users || 0) - (a.unique_users || 0)
8082
case 'newest':
8183
return (
8284
new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
@@ -136,6 +138,7 @@ const AgentStorePage = () => {
136138
<SelectContent>
137139
<SelectItem value="cost">Weekly Usage</SelectItem>
138140
<SelectItem value="usage">Total Runs</SelectItem>
141+
<SelectItem value="unique_users">Unique Users</SelectItem>
139142
<SelectItem value="newest">Newest</SelectItem>
140143
<SelectItem value="name">Name</SelectItem>
141144
</SelectContent>
@@ -216,9 +219,7 @@ const AgentStorePage = () => {
216219
{agent.last_used && (
217220
<span
218221
className="text-xs text-muted-foreground shrink-0"
219-
title={new Date(
220-
agent.last_used
221-
).toLocaleString()}
222+
title={new Date(agent.last_used).toLocaleString()}
222223
>
223224
{formatRelativeTime(agent.last_used)}
224225
</span>
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
'use client'
2+
3+
import { useQuery } from '@tanstack/react-query'
4+
import { TrendingUp, Users, DollarSign, Play, Calendar } from 'lucide-react'
5+
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
6+
import { Skeleton } from '@/components/ui/skeleton'
7+
8+
interface AgentUsageMetricsProps {
9+
publisherId: string
10+
agentId: string
11+
}
12+
13+
interface AgentData {
14+
id: string
15+
publisher: {
16+
id: string
17+
}
18+
usage_count?: number
19+
weekly_spent?: number
20+
avg_cost_per_invocation?: number
21+
unique_users?: number
22+
last_used?: string
23+
}
24+
25+
const formatCurrency = (amount?: number) => {
26+
if (!amount) return '$0.00'
27+
if (amount >= 1000) return `$${(amount / 1000).toFixed(1)}k`
28+
return `$${amount.toFixed(2)}`
29+
}
30+
31+
const formatUsageCount = (count?: number) => {
32+
if (!count) return '0'
33+
if (count >= 1000000) return `${(count / 1000000).toFixed(1)}M`
34+
if (count >= 1000) return `${(count / 1000).toFixed(1)}K`
35+
return count.toString()
36+
}
37+
38+
export const AgentUsageMetrics = ({
39+
publisherId,
40+
agentId,
41+
}: AgentUsageMetricsProps) => {
42+
const { data: agents, isLoading } = useQuery<AgentData[]>({
43+
queryKey: ['agents'],
44+
queryFn: async () => {
45+
const response = await fetch('/api/agents')
46+
if (!response.ok) {
47+
throw new Error('Failed to fetch agents')
48+
}
49+
return await response.json()
50+
},
51+
})
52+
53+
const usageMetrics = agents?.find(
54+
(agent) => agent.id === agentId && agent.publisher.id === publisherId
55+
)
56+
57+
if (isLoading) {
58+
return (
59+
<Card className="mb-6">
60+
<CardHeader>
61+
<CardTitle className="text-lg">Usage Metrics</CardTitle>
62+
</CardHeader>
63+
<CardContent>
64+
<div className="grid grid-cols-2 md:grid-cols-4 gap-6">
65+
{Array.from({ length: 4 }).map((_, i) => (
66+
<div key={i} className="flex flex-col items-center gap-2">
67+
<Skeleton className="h-6 w-16" />
68+
<Skeleton className="h-4 w-20" />
69+
</div>
70+
))}
71+
</div>
72+
</CardContent>
73+
</Card>
74+
)
75+
}
76+
77+
if (!usageMetrics) {
78+
return null
79+
}
80+
81+
return (
82+
<Card className="mb-6">
83+
<CardHeader>
84+
<CardTitle className="text-lg">Usage Metrics</CardTitle>
85+
</CardHeader>
86+
<CardContent>
87+
<div className="grid grid-cols-2 md:grid-cols-4 gap-6">
88+
<div className="flex flex-col items-center gap-2">
89+
<div className="flex items-center gap-2">
90+
<TrendingUp className="h-4 w-4 text-emerald-400" />
91+
<span className="font-medium text-emerald-300">
92+
{formatCurrency(usageMetrics.weekly_spent)}
93+
</span>
94+
</div>
95+
<span className="text-xs text-muted-foreground">Weekly Usage</span>
96+
</div>
97+
<div className="flex flex-col items-center gap-2">
98+
<div className="flex items-center gap-2">
99+
<Play className="h-4 w-4 text-muted-foreground" />
100+
<span>{formatUsageCount(usageMetrics.usage_count)}</span>
101+
</div>
102+
<span className="text-xs text-muted-foreground">Total Runs</span>
103+
</div>
104+
<div className="flex flex-col items-center gap-2">
105+
<div className="flex items-center gap-2">
106+
<Users className="h-4 w-4 text-muted-foreground" />
107+
<span>{usageMetrics.unique_users || 0}</span>
108+
</div>
109+
<span className="text-xs text-muted-foreground">Unique Users</span>
110+
</div>
111+
<div className="flex flex-col items-center gap-2">
112+
<div className="flex items-center gap-2">
113+
<DollarSign className="h-4 w-4 text-muted-foreground" />
114+
<span>
115+
{formatCurrency(usageMetrics.avg_cost_per_invocation).replace(
116+
'$',
117+
''
118+
)}
119+
</span>
120+
</div>
121+
<span className="text-xs text-muted-foreground">
122+
Avg Cost per Run
123+
</span>
124+
</div>
125+
</div>
126+
{usageMetrics.last_used && (
127+
<div className="mt-4 pt-4 border-t border-border/40">
128+
<div className="flex items-center gap-2 text-sm text-muted-foreground">
129+
<Calendar className="h-4 w-4" />
130+
<span>
131+
Last used:{' '}
132+
{new Date(usageMetrics.last_used).toLocaleDateString('en-US', {
133+
year: 'numeric',
134+
month: 'short',
135+
day: 'numeric',
136+
hour: '2-digit',
137+
minute: '2-digit',
138+
})}
139+
</span>
140+
</div>
141+
</div>
142+
)}
143+
</CardContent>
144+
</Card>
145+
)
146+
}

web/src/app/publishers/[id]/agents/[agentId]/[version]/page.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
1111
import { JsonViewer } from '@/components/agent/json-viewer'
1212
import { EnhancedCopyButton } from '@/components/ui/enhanced-copy-button'
1313
import { cn } from '@/lib/utils'
14+
import { AgentUsageMetrics } from './agent-usage-metrics'
1415

1516
interface AgentDetailPageProps {
1617
params: {
@@ -187,6 +188,9 @@ const AgentDetailPage = async ({ params }: AgentDetailPageProps) => {
187188
</CardHeader>
188189
</Card>
189190

191+
{/* Usage Metrics */}
192+
<AgentUsageMetrics publisherId={params.id} agentId={params.agentId} />
193+
190194
<div className="grid grid-cols-1 lg:grid-cols-4 gap-6">
191195
{/* Version Navigation */}
192196
<div className="lg:col-span-1">

0 commit comments

Comments
 (0)