import { useMemo, useState } from 'react' import { formatNumber } from '../../lib/usage' import type { EventRow } from '../../lib/types' import styles from '../../pages/usage/UsagePage.module.css' interface RequestEventsCardProps { items: EventRow[] } const ALL = '__all__' function downloadFile(filename: string, content: string, type: string) { const blob = new Blob([content], { type }) const url = URL.createObjectURL(blob) const link = document.createElement('a') link.href = url link.download = filename link.click() URL.revokeObjectURL(url) } export function RequestEventsCard({ items }: RequestEventsCardProps) { const [modelFilter, setModelFilter] = useState(ALL) const [sourceFilter, setSourceFilter] = useState(ALL) const [authFilter, setAuthFilter] = useState(ALL) const modelOptions = useMemo(() => [ALL, ...new Set(items.map((item) => item.modelName))], [items]) const sourceOptions = useMemo(() => [ALL, ...new Set(items.map((item) => item.source))], [items]) const authOptions = useMemo(() => [ALL, ...new Set(items.map((item) => item.authIndex))], [items]) const filteredItems = useMemo( () => items.filter((item) => { if (modelFilter !== ALL && item.modelName !== modelFilter) return false if (sourceFilter !== ALL && item.source !== sourceFilter) return false if (authFilter !== ALL && item.authIndex !== authFilter) return false return true }), [authFilter, items, modelFilter, sourceFilter], ) function handleExportCsv() { const header = ['time', 'api', 'model', 'source', 'auth', 'status', 'latency_ms', 'input_tokens', 'output_tokens', 'reasoning_tokens', 'cached_tokens', 'total_tokens'] const rows = filteredItems.map((item) => [ item.timestamp, item.apiName, item.modelName, item.source, item.authIndex, item.failed ? 'failed' : 'success', item.latencyMs, item.inputTokens, item.outputTokens, item.reasoningTokens, item.cachedTokens, item.totalTokens, ]) const csv = [header.join(','), ...rows.map((row) => row.map((value) => `"${String(value).replace(/"/g, '""')}"`).join(','))].join('\n') downloadFile('usage-events.csv', csv, 'text/csv;charset=utf-8') } function handleExportJson() { downloadFile('usage-events.json', JSON.stringify(filteredItems, null, 2), 'application/json;charset=utf-8') } return (

Request event details

Filter and export request-level usage details derived from persisted events.

{filteredItems.length} rows
Time API / model Source Auth Status Latency Input Output Reasoning Cached Total
{filteredItems.map((event) => (
{new Date(event.timestamp).toLocaleString()} {event.apiName} {event.modelName} {event.source} {event.authIndex} {event.failed ? 'Failed' : 'Success'} {formatNumber(event.latencyMs)} ms {formatNumber(event.inputTokens)} {formatNumber(event.outputTokens)} {formatNumber(event.reasoningTokens)} {formatNumber(event.cachedTokens)} {formatNumber(event.totalTokens)}
))}
) }