@@ -70,6 +70,7 @@ export const AIGatewayAnalytics: React.FC<AIGatewayAnalyticsProps> = React.memo(
7070 < Tabs defaultValue = "performance" className = "w-full" >
7171 < TabsList >
7272 < TabsTrigger value = "performance" > { t ( 'Performance' ) } </ TabsTrigger >
73+ < TabsTrigger value = "providers" > { t ( 'Providers' ) } </ TabsTrigger >
7374 < TabsTrigger value = "models" > { t ( 'Models' ) } </ TabsTrigger >
7475 < TabsTrigger value = "users" > { t ( 'Users' ) } </ TabsTrigger >
7576 < TabsTrigger value = "errors" > { t ( 'Errors' ) } </ TabsTrigger >
@@ -217,6 +218,153 @@ export const AIGatewayAnalytics: React.FC<AIGatewayAnalyticsProps> = React.memo(
217218 </ div >
218219 </ TabsContent >
219220
221+ { /* Provider Analytics */ }
222+ < TabsContent value = "providers" className = "space-y-4" >
223+ < div className = "grid grid-cols-1 gap-4 lg:grid-cols-2" >
224+ < Card >
225+ < CardHeader >
226+ < CardTitle > { t ( 'Request Count by Provider' ) } </ CardTitle >
227+ < p className = "text-muted-foreground text-sm" >
228+ { t (
229+ 'Total request count distribution across different upstream providers (e.g. openai, openrouter, anthropic)'
230+ ) }
231+ </ p >
232+ </ CardHeader >
233+ < CardContent >
234+ < InsightQueryChart
235+ className = "h-[300px] w-full"
236+ workspaceId = { workspaceId }
237+ insightId = { gatewayId }
238+ insightType = "aigateway"
239+ metrics = { [ { name : '$all_event' , math : 'events' } ] }
240+ filters = { [ ] }
241+ groups = { [ { value : 'modelProvider' , type : 'string' } ] }
242+ time = { timeConfig }
243+ chartType = "pie"
244+ valueProcessor = { defaultValueProcessor . alwaysPositive }
245+ />
246+ </ CardContent >
247+ </ Card >
248+
249+ < Card >
250+ < CardHeader >
251+ < CardTitle > { t ( 'Cost by Provider' ) } </ CardTitle >
252+ < p className = "text-muted-foreground text-sm" >
253+ { t (
254+ 'Total cost distribution across different upstream providers'
255+ ) }
256+ </ p >
257+ </ CardHeader >
258+ < CardContent >
259+ < InsightQueryChart
260+ className = "h-[300px] w-full"
261+ workspaceId = { workspaceId }
262+ insightId = { gatewayId }
263+ insightType = "aigateway"
264+ metrics = { [ { name : 'price' , math : 'events' } ] }
265+ filters = { [ ] }
266+ groups = { [ { value : 'modelProvider' , type : 'string' } ] }
267+ time = { timeConfig }
268+ chartType = "bar"
269+ valueProcessor = { defaultValueProcessor . alwaysPositive }
270+ />
271+ </ CardContent >
272+ </ Card >
273+ </ div >
274+
275+ < Card >
276+ < CardHeader >
277+ < CardTitle > { t ( 'Provider Request Trend' ) } </ CardTitle >
278+ < p className = "text-muted-foreground text-sm" >
279+ { t (
280+ 'Request volume over time grouped by upstream providers'
281+ ) }
282+ </ p >
283+ </ CardHeader >
284+ < CardContent >
285+ < InsightQueryChart
286+ className = "h-[300px] w-full"
287+ workspaceId = { workspaceId }
288+ insightId = { gatewayId }
289+ insightType = "aigateway"
290+ metrics = { [ { name : '$all_event' , math : 'events' } ] }
291+ filters = { [ ] }
292+ groups = { [ { value : 'modelProvider' , type : 'string' } ] }
293+ time = { timeConfig }
294+ chartType = "line"
295+ valueProcessor = { defaultValueProcessor . alwaysPositive }
296+ />
297+ </ CardContent >
298+ </ Card >
299+
300+ < Card >
301+ < CardHeader >
302+ < CardTitle > { t ( 'Token Usage by Provider' ) } </ CardTitle >
303+ < p className = "text-muted-foreground text-sm" >
304+ { t (
305+ 'Total token consumption (input + output + cache) distribution across different upstream providers'
306+ ) }
307+ </ p >
308+ </ CardHeader >
309+ < CardContent >
310+ < InsightQueryChart
311+ className = "h-[400px] w-full"
312+ workspaceId = { workspaceId }
313+ insightId = { gatewayId }
314+ insightType = "aigateway"
315+ metrics = { [
316+ { name : 'inputToken' , math : 'events' , alias : 'inputToken' } ,
317+ {
318+ name : 'outputToken' ,
319+ math : 'events' ,
320+ alias : 'outputToken' ,
321+ } ,
322+ {
323+ name : 'cacheReadInputToken' ,
324+ math : 'events' ,
325+ alias : 'cacheReadInputToken' ,
326+ } ,
327+ {
328+ name : 'cacheWriteInputToken' ,
329+ math : 'events' ,
330+ alias : 'cacheWriteInputToken' ,
331+ } ,
332+ ] }
333+ filters = { [ ] }
334+ groups = { [ { value : 'modelProvider' , type : 'string' } ] }
335+ time = { timeConfig }
336+ chartType = "bar"
337+ valueProcessor = { defaultValueProcessor . alwaysPositive }
338+ />
339+ </ CardContent >
340+ </ Card >
341+
342+ < Card >
343+ < CardHeader >
344+ < CardTitle > { t ( 'Average Response Time by Provider' ) } </ CardTitle >
345+ < p className = "text-muted-foreground text-sm" >
346+ { t (
347+ 'Average response time (duration) comparison across different upstream providers'
348+ ) }
349+ </ p >
350+ </ CardHeader >
351+ < CardContent >
352+ < InsightQueryChart
353+ className = "h-[300px] w-full"
354+ workspaceId = { workspaceId }
355+ insightId = { gatewayId }
356+ insightType = "aigateway"
357+ metrics = { [ { name : 'duration' , math : 'avg' } ] }
358+ filters = { [ ] }
359+ groups = { [ { value : 'modelProvider' , type : 'string' } ] }
360+ time = { timeConfig }
361+ chartType = "bar"
362+ valueProcessor = { defaultValueProcessor . alwaysPositive }
363+ />
364+ </ CardContent >
365+ </ Card >
366+ </ TabsContent >
367+
220368 { /* Model Analytics */ }
221369 < TabsContent value = "models" className = "space-y-4" >
222370 < Card >
0 commit comments