@acarmisc/backstage-plugin-litellm 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/api.ts", "../src/components/DashboardHeader.tsx", "../src/components/KeysTable.tsx", "../src/components/UsageStats.tsx", "../src/components/TeamUsage.tsx", "../src/components/AuditLog.tsx", "../src/components/LiteLLMPage.tsx", "../src/index.ts", "../src/plugin.tsx", "../src/components/LiteLLMHomeWidget.tsx"],
4
- "sourcesContent": ["import { createApiRef, FetchApi } from '@backstage/core-plugin-api';\nimport {\n UserInfo,\n VirtualKey,\n ModelInfo,\n UsageMetrics,\n TeamInfo,\n GenerateKeyRequest,\n GenerateKeyResponse,\n UpdateKeyRequest,\n AuditLogsParams,\n PaginatedAuditLogs,\n} from './types';\n\nclass ApiError extends Error {\n body: unknown;\n status: number;\n constructor(message: string, status: number, body: unknown) {\n super(message);\n this.status = status;\n this.body = body;\n }\n}\n\nexport interface LiteLlmApiInterface {\n getUserInfo(): Promise<UserInfo>;\n listKeys(): Promise<VirtualKey[]>;\n generateKey(request: GenerateKeyRequest): Promise<GenerateKeyResponse>;\n updateKey(keyId: string, request: UpdateKeyRequest): Promise<VirtualKey>;\n deleteKey(keyId: string): Promise<{ success: boolean }>;\n rotateKey(keyId: string): Promise<GenerateKeyResponse>;\n blockKey(keyId: string): Promise<void>;\n unblockKey(keyId: string): Promise<void>;\n resetKeySpend(keyId: string): Promise<void>;\n listModels(): Promise<ModelInfo[]>;\n getTeams(): Promise<TeamInfo[]>;\n getUsage(startDate: string, endDate: string): Promise<UsageMetrics>;\n getTeamUsage(teamId: string, startDate: string, endDate: string): Promise<UsageMetrics>;\n getAuditLogs(params: AuditLogsParams): Promise<PaginatedAuditLogs>;\n}\n\nexport const liteLlmApiRef = createApiRef<LiteLlmApiInterface>({\n id: 'plugin.litellm.api',\n});\n\nexport class LiteLlmApi implements LiteLlmApiInterface {\n private fetchApi: FetchApi;\n private basePath: string;\n\n constructor(fetchApi: FetchApi, basePath: string = '/api/litellm') {\n this.fetchApi = fetchApi;\n this.basePath = basePath;\n }\n\n private async throwIfNotOk(response: Response): Promise<void> {\n if (!response.ok) {\n let body: unknown;\n try { body = await response.json(); } catch { body = await response.text().catch(() => ''); }\n throw new ApiError(`${response.status} ${response.statusText}`, response.status, body);\n }\n }\n\n private async get<T>(path: string, params?: Record<string, string>): Promise<T> {\n const url = new URL(`${this.basePath}${path}`, window.location.origin);\n if (params) {\n Object.entries(params).forEach(([key, value]) => url.searchParams.append(key, value));\n }\n const response = await this.fetchApi.fetch(url.toString());\n await this.throwIfNotOk(response);\n return response.json();\n }\n\n private async post<T>(path: string, body: unknown): Promise<T> {\n const response = await this.fetchApi.fetch(`${this.basePath}${path}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n await this.throwIfNotOk(response);\n return response.json();\n }\n\n private async del<T>(path: string): Promise<T> {\n const response = await this.fetchApi.fetch(`${this.basePath}${path}`, {\n method: 'DELETE',\n headers: { 'Content-Type': 'application/json' },\n });\n await this.throwIfNotOk(response);\n return response.json();\n }\n\n // User identity is resolved server-side from the Backstage Bearer token.\n // No user_id param needed on the frontend.\n async getUserInfo(): Promise<UserInfo> {\n return this.get<UserInfo>('/user/info');\n }\n\n async listKeys(): Promise<VirtualKey[]> {\n return this.get<VirtualKey[]>('/keys');\n }\n\n async generateKey(request: GenerateKeyRequest): Promise<GenerateKeyResponse> {\n return this.post<GenerateKeyResponse>('/keys/generate', request);\n }\n\n async updateKey(keyId: string, request: UpdateKeyRequest): Promise<VirtualKey> {\n return this.post<VirtualKey>(`/keys/${encodeURIComponent(keyId)}/update`, request);\n }\n\n async deleteKey(keyId: string): Promise<{ success: boolean }> {\n return this.del<{ success: boolean }>(`/keys/${encodeURIComponent(keyId)}`);\n }\n\n async rotateKey(keyId: string): Promise<GenerateKeyResponse> {\n return this.post<GenerateKeyResponse>(`/keys/${encodeURIComponent(keyId)}/regenerate`, {});\n }\n\n async blockKey(keyId: string): Promise<void> {\n await this.post(`/keys/${encodeURIComponent(keyId)}/block`, {});\n }\n\n async unblockKey(keyId: string): Promise<void> {\n await this.post(`/keys/${encodeURIComponent(keyId)}/unblock`, {});\n }\n\n async resetKeySpend(keyId: string): Promise<void> {\n await this.post(`/keys/${encodeURIComponent(keyId)}/reset_spend`, {});\n }\n\n async getAuditLogs(params: AuditLogsParams): Promise<PaginatedAuditLogs> {\n const strParams: Record<string, string> = {};\n if (params.page !== undefined) strParams.page = String(params.page);\n if (params.page_size !== undefined) strParams.page_size = String(params.page_size);\n if (params.start_date) strParams.start_date = params.start_date;\n if (params.end_date) strParams.end_date = params.end_date;\n if (params.action) strParams.action = params.action;\n if (params.table_name) strParams.table_name = params.table_name;\n if (params.changed_by) strParams.changed_by = params.changed_by;\n return this.get<PaginatedAuditLogs>('/audit', strParams);\n }\n\n async listModels(): Promise<ModelInfo[]> {\n return this.get<ModelInfo[]>('/models');\n }\n\n async getTeams(): Promise<TeamInfo[]> {\n return this.get<TeamInfo[]>('/teams');\n }\n\n async getUsage(startDate: string, endDate: string): Promise<UsageMetrics> {\n return this.get<UsageMetrics>('/usage', { start_date: startDate, end_date: endDate });\n }\n\n async getTeamUsage(teamId: string, startDate: string, endDate: string): Promise<UsageMetrics> {\n return this.get<UsageMetrics>(`/teams/${encodeURIComponent(teamId)}/usage`, {\n start_date: startDate,\n end_date: endDate,\n });\n }\n}\n", "import React from 'react';\nimport { Box, Typography, LinearProgress, Paper, Chip } from '@mui/material';\nimport { UserInfo, TeamInfo } from '../types';\n\ninterface DashboardHeaderProps {\n userInfo: UserInfo;\n teams: TeamInfo[];\n loading: boolean;\n}\n\nexport const DashboardHeader: React.FC<DashboardHeaderProps> = ({ userInfo, teams, loading }) => {\n if (loading) {\n return (\n <Paper sx={{ p: 2, mb: 2 }}>\n <LinearProgress />\n </Paper>\n );\n }\n\n const displayName = userInfo.user_email ?? userInfo.email ?? userInfo.user_id;\n\n return (\n <Paper sx={{ p: 2, mb: 2 }}>\n <Box display=\"flex\" alignItems=\"flex-start\" gap={2} flexWrap=\"wrap\">\n <Box flexGrow={1}>\n <Typography variant=\"h6\">{displayName}</Typography>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {userInfo.user_id}\n </Typography>\n\n {teams.length > 0 && (\n <Box display=\"flex\" gap={0.75} flexWrap=\"wrap\" mt={1}>\n {teams.map(team => (\n <Chip\n key={team.team_id}\n label={team.team_alias || team.team_id}\n size=\"small\"\n variant=\"outlined\"\n color=\"primary\"\n />\n ))}\n </Box>\n )}\n </Box>\n </Box>\n </Paper>\n );\n};\n", "import React, { useState, useMemo } from 'react';\nimport {\n Paper,\n Table,\n TableBody,\n TableCell,\n TableContainer,\n TableHead,\n TableRow,\n Button,\n IconButton,\n Box,\n Typography,\n Dialog,\n DialogTitle,\n DialogContent,\n DialogActions,\n TextField,\n MenuItem,\n Chip,\n CircularProgress,\n Autocomplete,\n LinearProgress,\n InputAdornment,\n} from '@mui/material';\nimport { ContentCopy, Delete, Add, Edit, Autorenew, Search, Warning, Lock, LockOpen } from '@mui/icons-material';\nimport {\n VirtualKey,\n ModelInfo,\n TeamInfo,\n GenerateKeyRequest,\n GenerateKeyResponse,\n UpdateKeyRequest,\n} from '../types';\n\ninterface KeysTableProps {\n keys: VirtualKey[];\n models: ModelInfo[];\n teams: TeamInfo[];\n loading: boolean;\n onGenerateKey: (request: GenerateKeyRequest) => Promise<GenerateKeyResponse>;\n onUpdateKey: (keyId: string, request: UpdateKeyRequest) => Promise<void>;\n onRotateKey: (keyId: string) => Promise<GenerateKeyResponse>;\n onBlockKey: (keyId: string) => Promise<void>;\n onUnblockKey: (keyId: string) => Promise<void>;\n onResetKeySpend: (keyId: string) => Promise<void>;\n onDeleteKey: (keyId: string) => Promise<void>;\n}\n\nconst maskKey = (key: string): string => {\n if (key.length <= 8) return '***';\n return `${key.slice(0, 4)}...${key.slice(-4)}`;\n};\n\nconst shortKeyId = (token: string): string => {\n if (!token) return '-';\n if (token.length <= 16) return token;\n return `${token.slice(0, 12)}\u2026`;\n};\n\nconst formatDate = (dateStr: string): string => {\n try {\n return new Date(dateStr).toLocaleDateString();\n } catch {\n return dateStr;\n }\n};\n\ntype ExpiryStatus = 'expired' | 'soon' | 'ok';\n\nfunction expiryStatus(expiresAt?: string): ExpiryStatus | null {\n if (!expiresAt) return null;\n const diff = new Date(expiresAt).getTime() - Date.now();\n const days = diff / (1000 * 60 * 60 * 24);\n if (days < 0) return 'expired';\n if (days < 7) return 'soon';\n return 'ok';\n}\n\nfunction ExpiryChip({ expiresAt }: { expiresAt?: string }) {\n const status = expiryStatus(expiresAt);\n if (!status) return <Typography variant=\"body2\" color=\"text.secondary\">-</Typography>;\n const label = status === 'expired' ? 'Expired' : status === 'soon' ? `${Math.ceil((new Date(expiresAt!).getTime() - Date.now()) / 86400000)}d left` : formatDate(expiresAt!);\n const color = status === 'expired' ? 'error' : status === 'soon' ? 'warning' : 'default';\n const icon = (status === 'expired' || status === 'soon') ? <Warning fontSize=\"small\" /> : undefined;\n return <Chip label={label} color={color} size=\"small\" icon={icon} />;\n}\n\nfunction BudgetCell({ spend, maxBudget }: { spend: number; maxBudget?: number }) {\n if (!maxBudget) return <Typography variant=\"body2\" color=\"text.secondary\">-</Typography>;\n const pct = Math.min(100, (spend / maxBudget) * 100);\n const color = pct >= 100 ? 'error' : pct >= 80 ? 'warning' : 'primary';\n return (\n <Box minWidth={100}>\n <Box display=\"flex\" justifyContent=\"space-between\">\n <Typography variant=\"caption\">${spend.toFixed(2)}</Typography>\n <Typography variant=\"caption\" color=\"text.secondary\">${maxBudget}</Typography>\n </Box>\n <LinearProgress variant=\"determinate\" value={pct} color={color} sx={{ height: 5, borderRadius: 1, mt: 0.25 }} />\n </Box>\n );\n}\n\nfunction fmtCost(perToken?: number): string | null {\n if (!perToken) return null;\n const per1k = perToken * 1000;\n return per1k < 0.01 ? `$${(perToken * 1_000_000).toFixed(2)}/M` : `$${per1k.toFixed(3)}/1K`;\n}\n\nconst emptyForm = (): GenerateKeyRequest => ({\n alias: '',\n models: [],\n duration: '30d',\n max_budget: 100,\n tpm_limit: undefined,\n rpm_limit: undefined,\n team_id: undefined,\n key_type: 'llm_api',\n});\n\nconst keyToEditForm = (k: VirtualKey): UpdateKeyRequest => ({\n key_alias: k.key_alias ?? '',\n models: k.models ?? [],\n max_budget: k.max_budget,\n tpm_limit: k.tpm_limit,\n rpm_limit: k.rpm_limit,\n});\n\nexport const KeysTable: React.FC<KeysTableProps> = ({\n keys,\n models,\n teams,\n loading,\n onGenerateKey,\n onUpdateKey,\n onRotateKey,\n onBlockKey,\n onUnblockKey,\n onResetKeySpend,\n onDeleteKey,\n}) => {\n const [generateModalOpen, setGenerateModalOpen] = useState(false);\n const [newKeyValue, setNewKeyValue] = useState<string | null>(null);\n const [formData, setFormData] = useState<GenerateKeyRequest>(emptyForm());\n const [submitting, setSubmitting] = useState(false);\n\n const [editingKey, setEditingKey] = useState<VirtualKey | null>(null);\n const [editForm, setEditForm] = useState<UpdateKeyRequest>({});\n const [editSubmitting, setEditSubmitting] = useState(false);\n\n // Rotation\n const [rotatingKeyId, setRotatingKeyId] = useState<string | null>(null);\n const [rotatedKeyValue, setRotatedKeyValue] = useState<string | null>(null);\n\n // Block/unblock\n const [blockingKeyId, setBlockingKeyId] = useState<string | null>(null);\n\n // Delete confirmation\n const [deleteConfirmId, setDeleteConfirmId] = useState<string | null>(null);\n const [deleteSubmitting, setDeleteSubmitting] = useState(false);\n\n // Reset spend (lives inside edit dialog)\n const [resetSpendConfirm, setResetSpendConfirm] = useState(false);\n const [resetSpendSubmitting, setResetSpendSubmitting] = useState(false);\n\n // Filter\n const [filterText, setFilterText] = useState('');\n\n const filteredKeys = useMemo(() => {\n if (!filterText.trim()) return keys;\n const q = filterText.toLowerCase();\n return keys.filter(k =>\n (k.key_alias ?? '').toLowerCase().includes(q) ||\n k.models?.some(m => m.toLowerCase().includes(q)),\n );\n }, [keys, filterText]);\n\n const selectedModels = models.filter(m => (formData.models || []).includes(m.model_name));\n const selectedTeam = teams.find(t => t.team_id === formData.team_id) ?? null;\n const editSelectedModels = models.filter(m => (editForm.models || []).includes(m.model_name));\n\n const handleGenerate = async () => {\n setSubmitting(true);\n try {\n const response = await onGenerateKey(formData);\n setNewKeyValue(response.key);\n setFormData(emptyForm());\n } catch (error) {\n console.error('Failed to generate key:', error);\n } finally {\n setSubmitting(false);\n }\n };\n\n const handleCloseModal = () => {\n setGenerateModalOpen(false);\n setNewKeyValue(null);\n setFormData(emptyForm());\n };\n\n const handleOpenEdit = (k: VirtualKey) => {\n setEditingKey(k);\n setEditForm(keyToEditForm(k));\n };\n\n const handleCloseEdit = () => {\n setEditingKey(null);\n setEditForm({});\n setResetSpendConfirm(false);\n };\n\n const handleUpdate = async () => {\n if (!editingKey) return;\n setEditSubmitting(true);\n try {\n await onUpdateKey(editingKey.token ?? editingKey.key, editForm);\n handleCloseEdit();\n } catch (error) {\n console.error('Failed to update key:', error);\n } finally {\n setEditSubmitting(false);\n }\n };\n\n const handleRotate = async (keyId: string) => {\n setRotatingKeyId(keyId);\n try {\n const response = await onRotateKey(keyId);\n setRotatedKeyValue(response.key);\n } catch (error) {\n console.error('Failed to rotate key:', error);\n } finally {\n setRotatingKeyId(null);\n }\n };\n\n const handleToggleBlock = async (key: VirtualKey) => {\n const keyId = key.token ?? key.key;\n setBlockingKeyId(keyId);\n try {\n if (key.blocked) {\n await onUnblockKey(keyId);\n } else {\n await onBlockKey(keyId);\n }\n } finally {\n setBlockingKeyId(null);\n }\n };\n\n const handleResetSpend = async () => {\n if (!editingKey) return;\n setResetSpendSubmitting(true);\n try {\n await onResetKeySpend(editingKey.token ?? editingKey.key);\n setResetSpendConfirm(false);\n handleCloseEdit();\n } finally {\n setResetSpendSubmitting(false);\n }\n };\n\n const handleConfirmDelete = async () => {\n if (!deleteConfirmId) return;\n setDeleteSubmitting(true);\n try {\n await onDeleteKey(deleteConfirmId);\n } finally {\n setDeleteSubmitting(false);\n setDeleteConfirmId(null);\n }\n };\n\n const copyToClipboard = (text: string) => {\n navigator.clipboard.writeText(text);\n };\n\n const modelOption = (m: ModelInfo) => {\n const inCost = fmtCost(m.input_cost_per_token);\n const outCost = fmtCost(m.output_cost_per_token);\n return (\n <Box>\n <span>{m.model_name}</span>\n {m.supports_function_calling && ' \uD83D\uDD27'}\n {m.supports_vision && ' \uD83D\uDC41\uFE0F'}\n {(inCost || outCost) && (\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ ml: 1 }}>\n {inCost} in \u00B7 {outCost} out\n </Typography>\n )}\n </Box>\n );\n };\n\n return (\n <>\n <Paper sx={{ mb: 2 }}>\n <Box display=\"flex\" justifyContent=\"space-between\" alignItems=\"center\" p={2} gap={2}>\n <Typography variant=\"h6\">Virtual Keys</Typography>\n <Box display=\"flex\" gap={1} alignItems=\"center\" flex={1} justifyContent=\"flex-end\">\n <TextField\n size=\"small\"\n placeholder=\"Filter by alias or model\u2026\"\n value={filterText}\n onChange={e => setFilterText(e.target.value)}\n sx={{ minWidth: 240 }}\n InputProps={{\n startAdornment: (\n <InputAdornment position=\"start\">\n <Search fontSize=\"small\" />\n </InputAdornment>\n ),\n }}\n />\n <Button\n variant=\"contained\"\n color=\"primary\"\n startIcon={<Add />}\n onClick={() => setGenerateModalOpen(true)}\n >\n Generate New Key\n </Button>\n </Box>\n </Box>\n\n <TableContainer>\n <Table>\n <TableHead>\n <TableRow>\n <TableCell>Alias</TableCell>\n <TableCell>Key ID</TableCell>\n <TableCell>Created</TableCell>\n <TableCell>Expires</TableCell>\n <TableCell>Budget</TableCell>\n <TableCell>TPM / RPM</TableCell>\n <TableCell>Models</TableCell>\n <TableCell align=\"right\">Actions</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {loading ? (\n <TableRow>\n <TableCell colSpan={8} align=\"center\">\n <CircularProgress size={24} />\n </TableCell>\n </TableRow>\n ) : filteredKeys.length === 0 ? (\n <TableRow>\n <TableCell colSpan={8} align=\"center\">\n <Typography color=\"text.secondary\">\n {filterText ? 'No keys match filter' : 'No keys found'}\n </Typography>\n </TableCell>\n </TableRow>\n ) : (\n filteredKeys.map((key) => {\n const keyId = key.token ?? key.key;\n const isRotating = rotatingKeyId === keyId;\n const isBlocking = blockingKeyId === keyId;\n return (\n <TableRow key={keyId} sx={key.blocked ? { bgcolor: 'action.disabledBackground' } : undefined}>\n <TableCell>\n <Box display=\"flex\" alignItems=\"center\" gap={0.5}>\n {key.key_alias || '-'}\n {key.blocked && <Chip label=\"Blocked\" color=\"error\" size=\"small\" />}\n </Box>\n </TableCell>\n <TableCell>\n <Box display=\"flex\" alignItems=\"center\" gap={0.5}>\n <Typography\n variant=\"body2\"\n component=\"code\"\n color=\"text.secondary\"\n title={keyId}\n sx={{\n fontFamily: 'monospace',\n backgroundColor: 'background.default',\n px: 1,\n py: 0.5,\n borderRadius: 1,\n }}\n >\n {shortKeyId(keyId)}\n </Typography>\n <IconButton size=\"small\" onClick={() => copyToClipboard(keyId)} title=\"Copy Key ID\">\n <ContentCopy fontSize=\"small\" />\n </IconButton>\n </Box>\n </TableCell>\n <TableCell>{formatDate(key.created_at)}</TableCell>\n <TableCell>\n <ExpiryChip expiresAt={key.expires_at} />\n </TableCell>\n <TableCell>\n <BudgetCell spend={key.spend ?? 0} maxBudget={key.max_budget} />\n </TableCell>\n <TableCell>\n <Typography variant=\"body2\">{key.tpm_limit ?? '-'} / {key.rpm_limit ?? '-'}</Typography>\n </TableCell>\n <TableCell>\n <Box display=\"flex\" gap={0.5} flexWrap=\"wrap\">\n {key.models?.slice(0, 2).map((model) => (\n <Chip key={model} label={model} size=\"small\" />\n ))}\n {(key.models?.length || 0) > 2 && (\n <Chip label={`+${(key.models?.length || 0) - 2}`} size=\"small\" variant=\"outlined\" />\n )}\n </Box>\n </TableCell>\n <TableCell align=\"right\">\n <IconButton onClick={() => handleOpenEdit(key)} title=\"Edit key\">\n <Edit fontSize=\"small\" />\n </IconButton>\n <IconButton\n onClick={() => handleRotate(keyId)}\n disabled={isRotating}\n title=\"Rotate key \u2014 generates a new secret, same settings\"\n >\n {isRotating ? <CircularProgress size={18} /> : <Autorenew fontSize=\"small\" />}\n </IconButton>\n <IconButton\n onClick={() => handleToggleBlock(key)}\n disabled={isBlocking}\n color={key.blocked ? 'warning' : 'default'}\n title={key.blocked ? 'Unblock key' : 'Block key \u2014 suspends without revoking'}\n >\n {isBlocking ? <CircularProgress size={18} /> : key.blocked ? <LockOpen fontSize=\"small\" /> : <Lock fontSize=\"small\" />}\n </IconButton>\n <IconButton\n color=\"error\"\n onClick={() => setDeleteConfirmId(keyId)}\n title=\"Revoke key\"\n >\n <Delete />\n </IconButton>\n </TableCell>\n </TableRow>\n );\n })\n )}\n </TableBody>\n </Table>\n </TableContainer>\n </Paper>\n\n {/* Generate dialog */}\n <Dialog open={generateModalOpen} onClose={handleCloseModal} maxWidth=\"sm\" fullWidth>\n <DialogTitle>{newKeyValue ? 'Key Generated' : 'Generate New Key'}</DialogTitle>\n <DialogContent>\n {newKeyValue ? (\n <Box>\n <Typography variant=\"body2\" color=\"text.secondary\" gutterBottom>\n Copy this key now. You won't be able to see it again.\n </Typography>\n <Box\n display=\"flex\"\n alignItems=\"center\"\n gap={1}\n mt={2}\n p={2}\n sx={{\n backgroundColor: 'action.hover',\n border: '1px solid',\n borderColor: 'divider',\n borderRadius: 1,\n }}\n >\n <Typography\n component=\"code\"\n color=\"text.primary\"\n sx={{ fontFamily: 'monospace', wordBreak: 'break-all', flex: 1 }}\n >\n {newKeyValue}\n </Typography>\n <IconButton onClick={() => copyToClipboard(newKeyValue)}>\n <ContentCopy />\n </IconButton>\n </Box>\n </Box>\n ) : (\n <Box display=\"flex\" flexDirection=\"column\" gap={2} mt={1}>\n <TextField\n label=\"Alias\"\n value={formData.alias || ''}\n onChange={(e) => setFormData({ ...formData, alias: e.target.value })}\n required\n fullWidth\n />\n <TextField\n select\n label=\"Duration\"\n value={formData.duration || '30d'}\n onChange={(e) => setFormData({ ...formData, duration: e.target.value })}\n fullWidth\n >\n <MenuItem value=\"1d\">1 Day</MenuItem>\n <MenuItem value=\"7d\">7 Days</MenuItem>\n <MenuItem value=\"30d\">30 Days</MenuItem>\n <MenuItem value=\"90d\">90 Days</MenuItem>\n <MenuItem value=\"1y\">1 Year</MenuItem>\n </TextField>\n\n {teams.length > 0 && (\n <Autocomplete\n options={teams}\n getOptionLabel={t => t.team_alias || t.team_id}\n value={selectedTeam}\n onChange={(_e, team) =>\n setFormData({ ...formData, team_id: team?.team_id })\n }\n renderInput={params => (\n <TextField\n {...params}\n label=\"Team\"\n helperText=\"Optional: bind this key to a specific team for scoped access\"\n fullWidth\n />\n )}\n />\n )}\n\n {models.length > 0 && (\n <Autocomplete\n multiple\n options={models}\n groupBy={m => m.mode || 'other'}\n getOptionLabel={m => m.model_name}\n value={selectedModels}\n onChange={(_e, selected) =>\n setFormData({ ...formData, models: selected.map(m => m.model_name) })\n }\n renderOption={(props, m) => <li {...props}>{modelOption(m)}</li>}\n renderInput={params => (\n <TextField {...params} label=\"Models\" helperText=\"Leave empty to allow all models\" fullWidth />\n )}\n />\n )}\n\n <TextField\n label=\"Max Budget (USD)\"\n type=\"number\"\n value={formData.max_budget ?? ''}\n onChange={(e) =>\n setFormData({ ...formData, max_budget: e.target.value ? Number(e.target.value) : undefined })\n }\n required\n fullWidth\n />\n <TextField\n label=\"TPM Limit\"\n type=\"number\"\n value={formData.tpm_limit ?? ''}\n onChange={(e) =>\n setFormData({ ...formData, tpm_limit: e.target.value ? Number(e.target.value) : undefined })\n }\n fullWidth\n />\n <TextField\n label=\"RPM Limit\"\n type=\"number\"\n value={formData.rpm_limit ?? ''}\n onChange={(e) =>\n setFormData({ ...formData, rpm_limit: e.target.value ? Number(e.target.value) : undefined })\n }\n fullWidth\n />\n </Box>\n )}\n </DialogContent>\n <DialogActions>\n <Button onClick={handleCloseModal}>{newKeyValue ? 'Done' : 'Cancel'}</Button>\n {!newKeyValue && (\n <Button\n onClick={handleGenerate}\n variant=\"contained\"\n color=\"primary\"\n disabled={submitting}\n >\n {submitting ? <CircularProgress size={24} /> : 'Generate'}\n </Button>\n )}\n {newKeyValue && (\n <Button onClick={handleCloseModal} variant=\"contained\" color=\"success\">\n Done\n </Button>\n )}\n </DialogActions>\n </Dialog>\n\n {/* Edit dialog */}\n <Dialog open={!!editingKey} onClose={handleCloseEdit} maxWidth=\"sm\" fullWidth>\n <DialogTitle>Edit Key</DialogTitle>\n <DialogContent>\n {editingKey && (\n <Box display=\"flex\" flexDirection=\"column\" gap={2} mt={1}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n <code style={{ fontFamily: 'monospace', color: 'inherit' }}>{maskKey(editingKey.key)}</code>\n </Typography>\n <TextField\n label=\"Alias\"\n value={editForm.key_alias || ''}\n onChange={(e) => setEditForm({ ...editForm, key_alias: e.target.value })}\n fullWidth\n />\n\n {models.length > 0 && (\n <Autocomplete\n multiple\n options={models}\n groupBy={m => m.mode || 'other'}\n getOptionLabel={m => m.model_name}\n value={editSelectedModels}\n onChange={(_e, selected) =>\n setEditForm({ ...editForm, models: selected.map(m => m.model_name) })\n }\n renderOption={(props, m) => <li {...props}>{modelOption(m)}</li>}\n renderInput={params => (\n <TextField {...params} label=\"Models\" fullWidth />\n )}\n />\n )}\n\n <TextField\n label=\"Max Budget (USD)\"\n type=\"number\"\n value={editForm.max_budget ?? ''}\n onChange={(e) =>\n setEditForm({ ...editForm, max_budget: e.target.value ? Number(e.target.value) : undefined })\n }\n fullWidth\n />\n <TextField\n label=\"TPM Limit\"\n type=\"number\"\n value={editForm.tpm_limit ?? ''}\n onChange={(e) =>\n setEditForm({ ...editForm, tpm_limit: e.target.value ? Number(e.target.value) : undefined })\n }\n fullWidth\n />\n <TextField\n label=\"RPM Limit\"\n type=\"number\"\n value={editForm.rpm_limit ?? ''}\n onChange={(e) =>\n setEditForm({ ...editForm, rpm_limit: e.target.value ? Number(e.target.value) : undefined })\n }\n fullWidth\n />\n\n <Box mt={1} pt={2} borderTop=\"1px solid\" sx={{ borderColor: 'divider' }}>\n <Typography variant=\"caption\" color=\"text.secondary\" display=\"block\" mb={1}>\n Danger Zone\n </Typography>\n {!resetSpendConfirm ? (\n <Button\n size=\"small\"\n color=\"warning\"\n variant=\"outlined\"\n onClick={() => setResetSpendConfirm(true)}\n >\n Reset Spend to $0\n </Button>\n ) : (\n <Box display=\"flex\" alignItems=\"center\" gap={1} flexWrap=\"wrap\">\n <Typography variant=\"body2\" color=\"warning.main\">\n Zero out spend counter?\n </Typography>\n <Button\n size=\"small\"\n color=\"warning\"\n variant=\"contained\"\n disabled={resetSpendSubmitting}\n onClick={handleResetSpend}\n >\n {resetSpendSubmitting ? <CircularProgress size={16} /> : 'Confirm'}\n </Button>\n <Button size=\"small\" onClick={() => setResetSpendConfirm(false)}>\n Cancel\n </Button>\n </Box>\n )}\n </Box>\n </Box>\n )}\n </DialogContent>\n <DialogActions>\n <Button onClick={handleCloseEdit}>Cancel</Button>\n <Button onClick={handleUpdate} variant=\"contained\" color=\"primary\" disabled={editSubmitting}>\n {editSubmitting ? <CircularProgress size={24} /> : 'Save'}\n </Button>\n </DialogActions>\n </Dialog>\n\n {/* Rotate result dialog */}\n <Dialog open={!!rotatedKeyValue} onClose={() => setRotatedKeyValue(null)} maxWidth=\"sm\" fullWidth>\n <DialogTitle>Key Rotated</DialogTitle>\n <DialogContent>\n <Typography variant=\"body2\" color=\"text.secondary\" gutterBottom>\n The old secret is now invalid. Copy the new one \u2014 you won't see it again.\n </Typography>\n <Box\n display=\"flex\"\n alignItems=\"center\"\n gap={1}\n mt={2}\n p={2}\n sx={{ backgroundColor: 'action.hover', border: '1px solid', borderColor: 'divider', borderRadius: 1 }}\n >\n <Typography\n component=\"code\"\n sx={{ fontFamily: 'monospace', wordBreak: 'break-all', flex: 1 }}\n >\n {rotatedKeyValue}\n </Typography>\n <IconButton onClick={() => copyToClipboard(rotatedKeyValue!)}>\n <ContentCopy />\n </IconButton>\n </Box>\n </DialogContent>\n <DialogActions>\n <Button onClick={() => setRotatedKeyValue(null)} variant=\"contained\" color=\"success\">\n Done\n </Button>\n </DialogActions>\n </Dialog>\n\n {/* Delete confirmation dialog */}\n <Dialog open={!!deleteConfirmId} onClose={() => setDeleteConfirmId(null)} maxWidth=\"xs\" fullWidth>\n <DialogTitle>Revoke Key?</DialogTitle>\n <DialogContent>\n <Typography>\n This will permanently revoke the key. Any integrations using it will stop working immediately.\n </Typography>\n </DialogContent>\n <DialogActions>\n <Button onClick={() => setDeleteConfirmId(null)} disabled={deleteSubmitting}>\n Cancel\n </Button>\n <Button\n onClick={handleConfirmDelete}\n variant=\"contained\"\n color=\"error\"\n disabled={deleteSubmitting}\n >\n {deleteSubmitting ? <CircularProgress size={20} /> : 'Revoke'}\n </Button>\n </DialogActions>\n </Dialog>\n </>\n );\n};\n", "import React, { useMemo, useState } from 'react';\nimport {\n Paper,\n Box,\n Typography,\n FormControl,\n InputLabel,\n Select,\n MenuItem,\n Grid,\n Tabs,\n Tab,\n Table,\n TableBody,\n TableCell,\n TableContainer,\n TableHead,\n TableRow,\n Chip,\n LinearProgress,\n Skeleton,\n} from '@mui/material';\nimport {\n AreaChart,\n Area,\n BarChart,\n Bar,\n LineChart,\n Line,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n ResponsiveContainer,\n Legend,\n ReferenceLine,\n} from 'recharts';\nimport {\n DateRange,\n UsageMetrics,\n ModelInfo,\n UserInfo,\n UsageModelBreakdown,\n UsageKeyBreakdown,\n} from '../types';\n\ninterface UsageStatsProps {\n usage: UsageMetrics | null;\n models: ModelInfo[];\n dateRange: DateRange;\n onDateRangeChange: (range: DateRange) => void;\n loading: boolean;\n userInfo?: UserInfo;\n}\n\ntype DatePreset = 'today' | '24h' | '7d' | '30d';\ntype TabKey = 'costs' | 'models' | 'keys';\n\nconst TOP_N_MODELS = 6;\nconst PERIOD_LS_KEY = 'litellm_usage_period';\n\nconst MODEL_COLORS = [\n '#8884d8', '#82ca9d', '#ffc658', '#ff7300',\n '#0088fe', '#00C49F', '#FFBB28', '#FF8042',\n '#a4de6c', '#d0ed57',\n];\n\nfunction modelColor(model: string): string {\n let h = 5381;\n for (let i = 0; i < model.length; i++) h = ((h << 5) + h + model.charCodeAt(i)) >>> 0;\n return MODEL_COLORS[h % MODEL_COLORS.length];\n}\n\nconst fmtUsd = (n: number) => `$${(n ?? 0).toFixed(n < 1 ? 4 : 2)}`;\nconst fmtInt = (n: number) => (n ?? 0).toLocaleString();\nconst fmtPct = (n: number) => `${(n * 100).toFixed(1)}%`;\n\nconst KpiCard: React.FC<{ label: string; value: string; hint?: string }> = ({ label, value, hint }) => (\n <Paper variant=\"outlined\" sx={{ p: 2, height: '100%' }}>\n <Typography variant=\"caption\" color=\"text.secondary\">{label}</Typography>\n <Typography variant=\"h5\" sx={{ mt: 0.5 }}>{value}</Typography>\n {hint ? <Typography variant=\"caption\" color=\"text.secondary\">{hint}</Typography> : null}\n </Paper>\n);\n\nconst ChartSkeleton: React.FC<{ height?: number }> = ({ height = 260 }) => (\n <Skeleton variant=\"rectangular\" height={height} sx={{ borderRadius: 1 }} />\n);\n\nconst EmptyChart: React.FC<{ height?: number; message?: string }> = ({\n height = 260,\n message = 'No data for this period',\n}) => (\n <Box height={height} display=\"flex\" alignItems=\"center\" justifyContent=\"center\">\n <Typography color=\"text.secondary\" variant=\"body2\">{message}</Typography>\n </Box>\n);\n\nexport const UsageStats: React.FC<UsageStatsProps> = ({\n usage,\n models,\n dateRange,\n onDateRangeChange,\n loading,\n userInfo,\n}) => {\n const [selectedModel, setSelectedModel] = useState<string>('all');\n const [tab, setTab] = useState<TabKey>('costs');\n\n const selectedPreset = useMemo<DatePreset>(() => {\n if (dateRange.start.toDateString() === dateRange.end.toDateString()) return 'today';\n const diffMs = dateRange.end.getTime() - dateRange.start.getTime();\n const diffHours = diffMs / (1000 * 60 * 60);\n if (diffHours <= 26) return '24h';\n const diffDays = Math.ceil(diffMs / (1000 * 60 * 60 * 24));\n if (diffDays <= 7) return '7d';\n return '30d';\n }, [dateRange]);\n\n const handlePresetChange = (preset: DatePreset) => {\n const end = new Date();\n const start = new Date();\n if (preset === 'today') start.setHours(0, 0, 0, 0);\n else if (preset === '24h') start.setHours(start.getHours() - 24);\n else if (preset === '7d') start.setDate(start.getDate() - 7);\n else if (preset === '30d') start.setDate(start.getDate() - 30);\n try { localStorage.setItem(PERIOD_LS_KEY, preset); } catch { /* ignore */ }\n onDateRangeChange({ start, end });\n };\n\n // \u2500\u2500 daily_usage \u2192 base series \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const dailyData = useMemo(\n () =>\n (usage?.daily_usage ?? []).map(d => ({\n date: d.date,\n spend: d.spend,\n promptTokens: d.prompt_tokens,\n completionTokens: d.completion_tokens,\n totalTokens: d.total_tokens,\n apiRequests: d.api_requests,\n successfulRequests: d.successful_requests,\n failedRequests: d.failed_requests,\n })),\n [usage],\n );\n\n // \u2500\u2500 Cumulative spend per day \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const cumulativeData = useMemo(() => {\n let cum = 0;\n return dailyData.map(d => { cum += d.spend; return { date: d.date, cumulative: cum }; });\n }, [dailyData]);\n\n // \u2500\u2500 Success rate trend (days with requests only) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const successRateData = useMemo(\n () =>\n dailyData\n .filter(d => d.apiRequests > 0)\n .map(d => ({\n date: d.date,\n successRate: parseFloat(((d.successfulRequests / d.apiRequests) * 100).toFixed(1)),\n })),\n [dailyData],\n );\n\n // \u2500\u2500 Stacked spend by model per day \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const { modelSpendByDate, topModels: topSpendModels } = useMemo(() => {\n const rows = usage?.daily_by_model ?? [];\n const modelTotals: Record<string, number> = {};\n for (const r of rows) modelTotals[r.model] = (modelTotals[r.model] ?? 0) + r.spend;\n\n const top = Object.entries(modelTotals)\n .sort(([, a], [, b]) => b - a)\n .slice(0, TOP_N_MODELS)\n .map(([m]) => m);\n\n const dateMap: Record<string, Record<string, number>> = {};\n for (const r of rows) {\n if (!dateMap[r.date]) dateMap[r.date] = {};\n const bucket = top.includes(r.model) ? r.model : 'Other';\n dateMap[r.date][bucket] = (dateMap[r.date][bucket] ?? 0) + r.spend;\n }\n\n const sorted = Object.entries(dateMap)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([date, m]) => ({ date, ...m }));\n\n const hasOther = sorted.some(r => (r as any).Other > 0);\n return { modelSpendByDate: sorted, topModels: hasOther ? [...top, 'Other'] : top };\n }, [usage]);\n\n // \u2500\u2500 Model breakdown rows \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const modelRows = useMemo(() => {\n const entries = Object.entries<UsageModelBreakdown>(usage?.usage_by_model ?? {}).map(([model, d]) => ({\n model,\n spend: d.total_spend,\n promptTokens: d.prompt_tokens,\n completionTokens: d.completion_tokens,\n totalTokens: d.total_tokens,\n apiRequests: d.api_requests,\n successfulRequests: d.successful_requests,\n failedRequests: d.failed_requests,\n successRate: d.api_requests > 0 ? d.successful_requests / d.api_requests : 0,\n }));\n return selectedModel === 'all' ? entries : entries.filter(e => e.model === selectedModel);\n }, [usage, selectedModel]);\n\n // top-models horizontal bar (sorted by spend)\n const topModelSpendBars = useMemo(\n () => [...modelRows].sort((a, b) => b.spend - a.spend).slice(0, 10),\n [modelRows],\n );\n\n // \u2500\u2500 Key breakdown rows \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const keyRows = useMemo(\n () =>\n Object.entries<UsageKeyBreakdown>(usage?.usage_by_key ?? {}).map(([keyHash, d]) => ({\n keyHash,\n keyAlias: d.key_alias ?? keyHash.slice(0, 8),\n teamId: d.team_id ?? null,\n models: d.models,\n spend: d.total_spend,\n totalTokens: d.total_tokens,\n promptTokens: d.prompt_tokens,\n completionTokens: d.completion_tokens,\n apiRequests: d.api_requests,\n successfulRequests: d.successful_requests,\n failedRequests: d.failed_requests,\n successRate: d.api_requests > 0 ? d.successful_requests / d.api_requests : 0,\n })),\n [usage],\n );\n\n const topKeySpendBars = useMemo(\n () => [...keyRows].sort((a, b) => b.spend - a.spend).slice(0, 10),\n [keyRows],\n );\n\n const totalRequests = usage?.api_requests ?? 0;\n const overallSuccessRate = totalRequests > 0 ? (usage?.successful_requests ?? 0) / totalRequests : 0;\n const maxBudget = userInfo?.max_budget ?? 0;\n const totalCumSpend = cumulativeData[cumulativeData.length - 1]?.cumulative ?? 0;\n\n return (\n <Paper sx={{ p: 2 }}>\n {/* \u2500\u2500 Header \u2500\u2500 */}\n <Box display=\"flex\" justifyContent=\"space-between\" alignItems=\"center\" mb={2} flexWrap=\"wrap\" gap={2}>\n <Typography variant=\"h6\">Usage Analytics</Typography>\n <Box display=\"flex\" gap={2} alignItems=\"center\" flexWrap=\"wrap\">\n <FormControl size=\"small\" sx={{ minWidth: 140 }}>\n <InputLabel>Period</InputLabel>\n <Select\n value={selectedPreset}\n label=\"Period\"\n onChange={e => handlePresetChange(e.target.value as DatePreset)}\n >\n <MenuItem value=\"today\">Today</MenuItem>\n <MenuItem value=\"24h\">Last 24h</MenuItem>\n <MenuItem value=\"7d\">Last 7 days</MenuItem>\n <MenuItem value=\"30d\">Last 30 days</MenuItem>\n </Select>\n </FormControl>\n {tab === 'models' && (\n <FormControl size=\"small\" sx={{ minWidth: 180 }}>\n <InputLabel>Model</InputLabel>\n <Select\n value={selectedModel}\n label=\"Model\"\n onChange={e => setSelectedModel(e.target.value)}\n >\n <MenuItem value=\"all\">All Models</MenuItem>\n {models.map(m => (\n <MenuItem key={m.model_name} value={m.model_name}>\n {m.model_name}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n )}\n </Box>\n </Box>\n\n {/* \u2500\u2500 KPI row \u2500\u2500 */}\n <Grid container spacing={2} sx={{ mb: 2 }}>\n <Grid item xs={6} sm={3}>\n {loading ? <ChartSkeleton height={80} /> : <KpiCard label=\"Total Spend\" value={fmtUsd(usage?.total_spend ?? 0)} />}\n </Grid>\n <Grid item xs={6} sm={3}>\n {loading ? <ChartSkeleton height={80} /> : (\n <KpiCard label=\"Total Requests\" value={fmtInt(totalRequests)} hint={`${fmtInt(usage?.failed_requests ?? 0)} failed`} />\n )}\n </Grid>\n <Grid item xs={6} sm={3}>\n {loading ? <ChartSkeleton height={80} /> : (\n <KpiCard label=\"Success Rate\" value={totalRequests > 0 ? fmtPct(overallSuccessRate) : '\u2014'} />\n )}\n </Grid>\n <Grid item xs={6} sm={3}>\n {loading ? <ChartSkeleton height={80} /> : (\n <KpiCard\n label=\"Total Tokens\"\n value={fmtInt(usage?.total_tokens ?? 0)}\n hint={`${fmtInt(usage?.prompt_tokens ?? 0)} in \u00B7 ${fmtInt(usage?.completion_tokens ?? 0)} out`}\n />\n )}\n </Grid>\n </Grid>\n\n <Tabs value={tab} onChange={(_, v) => setTab(v as TabKey)} sx={{ mb: 2 }}>\n <Tab value=\"costs\" label=\"Costs\" />\n <Tab value=\"models\" label=\"Model Activity\" />\n <Tab value=\"keys\" label=\"Key Activity\" />\n </Tabs>\n\n {/* \u2550\u2550 COSTS TAB \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */}\n {tab === 'costs' && (\n <Grid container spacing={3}>\n {/* Daily Spend by Model */}\n <Grid item xs={12} md={6}>\n <Typography variant=\"subtitle2\" color=\"text.secondary\" gutterBottom>\n Daily Spend by Model\n </Typography>\n {loading ? <ChartSkeleton /> : modelSpendByDate.length === 0 ? <EmptyChart /> : (\n <Box height={260}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <AreaChart data={modelSpendByDate}>\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis dataKey=\"date\" tick={{ fontSize: 12 }} />\n <YAxis tick={{ fontSize: 12 }} tickFormatter={v => `$${v.toFixed(2)}`} />\n <Tooltip formatter={(v: number) => [`$${v.toFixed(4)}`, undefined]} />\n <Legend />\n {topSpendModels.map(m => (\n <Area\n key={m}\n type=\"monotone\"\n dataKey={m}\n stackId=\"spend\"\n stroke={modelColor(m)}\n fill={modelColor(m)}\n fillOpacity={0.6}\n />\n ))}\n </AreaChart>\n </ResponsiveContainer>\n </Box>\n )}\n </Grid>\n\n {/* Token Usage Trend */}\n <Grid item xs={12} md={6}>\n <Typography variant=\"subtitle2\" color=\"text.secondary\" gutterBottom>\n Daily Token Usage\n </Typography>\n {loading ? <ChartSkeleton /> : dailyData.length === 0 ? <EmptyChart /> : (\n <Box height={260}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <AreaChart data={dailyData}>\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis dataKey=\"date\" tick={{ fontSize: 12 }} />\n <YAxis tick={{ fontSize: 12 }} tickFormatter={fmtInt} />\n <Tooltip formatter={(v: number) => [fmtInt(v), undefined]} />\n <Legend />\n <Area type=\"monotone\" dataKey=\"promptTokens\" name=\"Input (prompt)\" stackId=\"tok\" stroke=\"#8884d8\" fill=\"#8884d8\" fillOpacity={0.5} />\n <Area type=\"monotone\" dataKey=\"completionTokens\" name=\"Output (completion)\" stackId=\"tok\" stroke=\"#82ca9d\" fill=\"#82ca9d\" fillOpacity={0.5} />\n </AreaChart>\n </ResponsiveContainer>\n </Box>\n )}\n </Grid>\n\n {/* Daily Requests */}\n <Grid item xs={12} md={6}>\n <Typography variant=\"subtitle2\" color=\"text.secondary\" gutterBottom>\n Daily Requests\n </Typography>\n {loading ? <ChartSkeleton /> : dailyData.length === 0 ? <EmptyChart /> : (\n <Box height={260}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart data={dailyData}>\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis dataKey=\"date\" tick={{ fontSize: 12 }} />\n <YAxis tick={{ fontSize: 12 }} />\n <Tooltip />\n <Legend />\n <Bar dataKey=\"successfulRequests\" name=\"Successful\" fill=\"#82ca9d\" stackId=\"r\" />\n <Bar dataKey=\"failedRequests\" name=\"Failed\" fill=\"#e57373\" stackId=\"r\" />\n </BarChart>\n </ResponsiveContainer>\n </Box>\n )}\n </Grid>\n\n {/* Success Rate Trend */}\n <Grid item xs={12} md={6}>\n <Typography variant=\"subtitle2\" color=\"text.secondary\" gutterBottom>\n Daily Success Rate\n </Typography>\n {loading ? <ChartSkeleton /> : successRateData.length === 0 ? <EmptyChart /> : (\n <Box height={260}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <LineChart data={successRateData}>\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis dataKey=\"date\" tick={{ fontSize: 12 }} />\n <YAxis domain={[0, 100]} tick={{ fontSize: 12 }} tickFormatter={v => `${v}%`} />\n <Tooltip formatter={(v: number) => [`${v}%`, 'Success rate']} />\n <ReferenceLine y={100} stroke=\"#82ca9d\" strokeDasharray=\"4 2\" />\n <Line type=\"monotone\" dataKey=\"successRate\" name=\"Success rate\" stroke=\"#8884d8\" dot={{ r: 3 }} />\n </LineChart>\n </ResponsiveContainer>\n </Box>\n )}\n </Grid>\n\n {/* Cumulative Spend \u2014 only when max_budget is set */}\n {(maxBudget > 0 || cumulativeData.length > 0) && (\n <Grid item xs={12}>\n <Typography variant=\"subtitle2\" color=\"text.secondary\" gutterBottom>\n Cumulative Spend{maxBudget > 0 ? ` vs Budget (${fmtUsd(maxBudget)})` : ''}\n {maxBudget > 0 && (\n <Typography component=\"span\" variant=\"caption\" color=\"text.secondary\" sx={{ ml: 1 }}>\n {fmtUsd(totalCumSpend)} used \u00B7 {fmtUsd(Math.max(0, maxBudget - totalCumSpend))} remaining\n </Typography>\n )}\n </Typography>\n {loading ? <ChartSkeleton height={180} /> : cumulativeData.length === 0 ? <EmptyChart height={180} /> : (\n <Box height={180}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <AreaChart data={cumulativeData}>\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis dataKey=\"date\" tick={{ fontSize: 12 }} />\n <YAxis tick={{ fontSize: 12 }} tickFormatter={v => `$${v.toFixed(2)}`} />\n <Tooltip formatter={(v: number) => [`$${v.toFixed(4)}`, 'Cumulative spend']} />\n {maxBudget > 0 && (\n <ReferenceLine y={maxBudget} stroke=\"#e57373\" strokeDasharray=\"6 3\" label={{ value: `Budget ${fmtUsd(maxBudget)}`, position: 'insideTopRight', fontSize: 11 }} />\n )}\n <Area type=\"monotone\" dataKey=\"cumulative\" name=\"Cumulative spend\" stroke=\"#ffc658\" fill=\"#ffc658\" fillOpacity={0.3} />\n </AreaChart>\n </ResponsiveContainer>\n </Box>\n )}\n </Grid>\n )}\n </Grid>\n )}\n\n {/* \u2550\u2550 MODELS TAB \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */}\n {tab === 'models' && (\n <Grid container spacing={3}>\n {/* Top models spend horizontal bar */}\n <Grid item xs={12}>\n <Typography variant=\"subtitle2\" color=\"text.secondary\" gutterBottom>\n Spend by Model\n </Typography>\n {loading ? <ChartSkeleton /> : topModelSpendBars.length === 0 ? <EmptyChart /> : (\n <Box height={Math.max(200, topModelSpendBars.length * 36)}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart data={topModelSpendBars} layout=\"vertical\" margin={{ left: 20 }}>\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis type=\"number\" tick={{ fontSize: 12 }} tickFormatter={v => `$${v.toFixed(2)}`} />\n <YAxis type=\"category\" dataKey=\"model\" tick={{ fontSize: 11 }} width={200} />\n <Tooltip formatter={(v: number) => [fmtUsd(v), 'Spend']} />\n <Bar dataKey=\"spend\" name=\"Spend\" radius={[0, 4, 4, 0]}>\n {topModelSpendBars.map(r => (\n <rect key={r.model} fill={modelColor(r.model)} />\n ))}\n </Bar>\n </BarChart>\n </ResponsiveContainer>\n </Box>\n )}\n </Grid>\n\n {/* Tokens by model stacked bar */}\n <Grid item xs={12}>\n <Typography variant=\"subtitle2\" color=\"text.secondary\" gutterBottom>\n Tokens by Model\n </Typography>\n {loading ? <ChartSkeleton /> : modelRows.length === 0 ? <EmptyChart /> : (\n <Box height={260}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart data={modelRows}>\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis dataKey=\"model\" tick={{ fontSize: 10 }} interval={0} angle={-15} textAnchor=\"end\" height={60} />\n <YAxis tick={{ fontSize: 12 }} />\n <Tooltip />\n <Legend />\n <Bar dataKey=\"promptTokens\" name=\"Prompt\" fill=\"#8884d8\" stackId=\"t\" />\n <Bar dataKey=\"completionTokens\" name=\"Completion\" fill=\"#82ca9d\" stackId=\"t\" />\n </BarChart>\n </ResponsiveContainer>\n </Box>\n )}\n </Grid>\n\n {/* Model table */}\n <Grid item xs={12}>\n <TableContainer component={Paper} variant=\"outlined\">\n <Table size=\"small\">\n <TableHead>\n <TableRow>\n <TableCell>Model</TableCell>\n <TableCell align=\"right\">Spend</TableCell>\n <TableCell align=\"right\">Requests</TableCell>\n <TableCell align=\"right\">Success</TableCell>\n <TableCell align=\"right\">Failed</TableCell>\n <TableCell align=\"right\">Prompt</TableCell>\n <TableCell align=\"right\">Completion</TableCell>\n <TableCell sx={{ minWidth: 120 }}>Success rate</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {loading ? (\n <TableRow><TableCell colSpan={8}><LinearProgress /></TableCell></TableRow>\n ) : modelRows.length === 0 ? (\n <TableRow><TableCell colSpan={8} align=\"center\">No model activity</TableCell></TableRow>\n ) : [...modelRows]\n .sort((a, b) => b.spend - a.spend || b.totalTokens - a.totalTokens)\n .map(r => (\n <TableRow key={r.model}>\n <TableCell>\n <Box display=\"flex\" alignItems=\"center\" gap={0.75}>\n <Box sx={{ width: 10, height: 10, borderRadius: '50%', bgcolor: modelColor(r.model), flexShrink: 0 }} />\n {r.model}\n </Box>\n </TableCell>\n <TableCell align=\"right\">{fmtUsd(r.spend)}</TableCell>\n <TableCell align=\"right\">{fmtInt(r.apiRequests)}</TableCell>\n <TableCell align=\"right\">{fmtInt(r.successfulRequests)}</TableCell>\n <TableCell align=\"right\">{fmtInt(r.failedRequests)}</TableCell>\n <TableCell align=\"right\">{fmtInt(r.promptTokens)}</TableCell>\n <TableCell align=\"right\">{fmtInt(r.completionTokens)}</TableCell>\n <TableCell>\n {r.apiRequests > 0 ? (\n <Box display=\"flex\" alignItems=\"center\" gap={1}>\n <LinearProgress\n variant=\"determinate\"\n value={r.successRate * 100}\n sx={{ flex: 1, height: 6, borderRadius: 3 }}\n />\n <Typography variant=\"caption\">{fmtPct(r.successRate)}</Typography>\n </Box>\n ) : '\u2014'}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </TableContainer>\n </Grid>\n </Grid>\n )}\n\n {/* \u2550\u2550 KEYS TAB \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */}\n {tab === 'keys' && (\n <Grid container spacing={3}>\n {/* Top keys spend horizontal bar */}\n {(loading || topKeySpendBars.length > 0) && (\n <Grid item xs={12}>\n <Typography variant=\"subtitle2\" color=\"text.secondary\" gutterBottom>\n Spend by Key\n </Typography>\n {loading ? <ChartSkeleton /> : (\n <Box height={Math.max(160, topKeySpendBars.length * 36)}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart data={topKeySpendBars} layout=\"vertical\" margin={{ left: 20 }}>\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis type=\"number\" tick={{ fontSize: 12 }} tickFormatter={v => `$${v.toFixed(2)}`} />\n <YAxis type=\"category\" dataKey=\"keyAlias\" tick={{ fontSize: 11 }} width={160} />\n <Tooltip formatter={(v: number) => [fmtUsd(v), 'Spend']} />\n <Bar dataKey=\"spend\" name=\"Spend\" fill=\"#8884d8\" radius={[0, 4, 4, 0]} />\n </BarChart>\n </ResponsiveContainer>\n </Box>\n )}\n </Grid>\n )}\n\n {/* Keys table */}\n <Grid item xs={12}>\n <TableContainer component={Paper} variant=\"outlined\">\n <Table size=\"small\">\n <TableHead>\n <TableRow>\n <TableCell>Key</TableCell>\n <TableCell>Models</TableCell>\n <TableCell align=\"right\">Spend</TableCell>\n <TableCell align=\"right\">Requests</TableCell>\n <TableCell align=\"right\">Tokens</TableCell>\n <TableCell align=\"right\">Failed</TableCell>\n <TableCell sx={{ minWidth: 120 }}>Success rate</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {loading ? (\n <TableRow><TableCell colSpan={7}><LinearProgress /></TableCell></TableRow>\n ) : keyRows.length === 0 ? (\n <TableRow><TableCell colSpan={7} align=\"center\">No key activity</TableCell></TableRow>\n ) : [...keyRows]\n .sort((a, b) => b.spend - a.spend || b.apiRequests - a.apiRequests)\n .map(r => (\n <TableRow key={r.keyHash}>\n <TableCell>\n <Typography variant=\"body2\">{r.keyAlias}</Typography>\n {r.teamId ? (\n <Typography variant=\"caption\" color=\"text.secondary\">team: {r.teamId}</Typography>\n ) : null}\n </TableCell>\n <TableCell>\n <Box display=\"flex\" gap={0.5} flexWrap=\"wrap\">\n {r.models.map(m => (\n <Chip key={m} label={m} size=\"small\" variant=\"outlined\" />\n ))}\n </Box>\n </TableCell>\n <TableCell align=\"right\">{fmtUsd(r.spend)}</TableCell>\n <TableCell align=\"right\">{fmtInt(r.apiRequests)}</TableCell>\n <TableCell align=\"right\">{fmtInt(r.totalTokens)}</TableCell>\n <TableCell align=\"right\">{fmtInt(r.failedRequests)}</TableCell>\n <TableCell>\n {r.apiRequests > 0 ? (\n <Box display=\"flex\" alignItems=\"center\" gap={1}>\n <LinearProgress\n variant=\"determinate\"\n value={r.successRate * 100}\n sx={{ flex: 1, height: 6, borderRadius: 3 }}\n />\n <Typography variant=\"caption\">{fmtPct(r.successRate)}</Typography>\n </Box>\n ) : '\u2014'}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </TableContainer>\n </Grid>\n </Grid>\n )}\n </Paper>\n );\n};\n", "import React, { useState } from 'react';\nimport {\n Paper,\n Box,\n Typography,\n LinearProgress,\n Chip,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableRow,\n TableContainer,\n Collapse,\n IconButton,\n CircularProgress,\n} from '@mui/material';\nimport { ExpandMore, ExpandLess, Group } from '@mui/icons-material';\nimport {\n AreaChart,\n Area,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n ResponsiveContainer,\n} from 'recharts';\nimport { TeamInfo, UsageMetrics, DateRange } from '../types';\n\ninterface TeamCardProps {\n team: TeamInfo;\n usage: UsageMetrics | null;\n usageLoading: boolean;\n}\n\nconst TeamCard: React.FC<TeamCardProps> = ({ team, usage, usageLoading }) => {\n const [expanded, setExpanded] = useState(false);\n\n const budget = team.max_budget ?? 0;\n const spend = team.spend ?? 0;\n const budgetPct = budget > 0 ? Math.min((spend / budget) * 100, 100) : 0;\n const isOver = budget > 0 && spend >= budget;\n const isNear = budget > 0 && spend >= budget * 0.8 && !isOver;\n\n const dailyData = usage?.daily_usage?.map(d => ({ date: d.date, spend: d.spend })) ?? [];\n\n return (\n <Paper variant=\"outlined\" sx={{ p: 2, mb: 2 }}>\n <Box display=\"flex\" alignItems=\"center\" gap={1}>\n <Group color=\"action\" />\n <Box flexGrow={1}>\n <Typography variant=\"subtitle1\" fontWeight={600}>\n {team.team_alias ?? team.team_id}\n </Typography>\n {team.models?.length ? (\n <Box display=\"flex\" gap={0.5} flexWrap=\"wrap\" mt={0.5}>\n {team.models.map(m => (\n <Chip key={m} label={m} size=\"small\" variant=\"outlined\" />\n ))}\n </Box>\n ) : (\n <Typography variant=\"caption\" color=\"text.secondary\">All models</Typography>\n )}\n </Box>\n <IconButton size=\"small\" onClick={() => setExpanded(e => !e)}>\n {expanded ? <ExpandLess /> : <ExpandMore />}\n </IconButton>\n </Box>\n\n {budget > 0 && (\n <Box mt={1.5}>\n <Box display=\"flex\" justifyContent=\"space-between\" mb={0.5}>\n <Typography variant=\"body2\">\n ${spend.toFixed(2)} / ${budget.toFixed(2)}\n </Typography>\n {isOver && <Chip label=\"Over Budget\" size=\"small\" color=\"error\" />}\n {isNear && <Chip label=\"Near Limit\" size=\"small\" color=\"warning\" />}\n </Box>\n <LinearProgress\n variant=\"determinate\"\n value={budgetPct}\n color={isOver ? 'error' : isNear ? 'warning' : 'primary'}\n sx={{ height: 6, borderRadius: 1 }}\n />\n </Box>\n )}\n\n <Collapse in={expanded}>\n <Box mt={2}>\n {usageLoading ? (\n <Box display=\"flex\" justifyContent=\"center\" p={2}>\n <CircularProgress size={24} />\n </Box>\n ) : dailyData.length > 0 ? (\n <>\n <Typography variant=\"subtitle2\" color=\"text.secondary\" gutterBottom>\n Daily Spend\n </Typography>\n <Box height={160}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <AreaChart data={dailyData}>\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis dataKey=\"date\" tick={{ fontSize: 11 }} />\n <YAxis tick={{ fontSize: 11 }} tickFormatter={v => `$${v.toFixed(2)}`} />\n <Tooltip formatter={(v: number) => [`$${v.toFixed(4)}`, 'Spend']} />\n <Area type=\"monotone\" dataKey=\"spend\" stroke=\"#8884d8\" fill=\"#8884d8\" fillOpacity={0.3} />\n </AreaChart>\n </ResponsiveContainer>\n </Box>\n </>\n ) : null}\n\n {team.members_with_roles?.length ? (\n <Box mt={2}>\n <Typography variant=\"subtitle2\" color=\"text.secondary\" gutterBottom>\n Members\n </Typography>\n <TableContainer>\n <Table size=\"small\">\n <TableHead>\n <TableRow>\n <TableCell>User</TableCell>\n <TableCell>Role</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {team.members_with_roles.map(m => (\n <TableRow key={m.user_id}>\n <TableCell sx={{ fontFamily: 'monospace', fontSize: 12 }}>{m.user_id}</TableCell>\n <TableCell>\n <Chip\n label={m.role}\n size=\"small\"\n color={m.role === 'admin' ? 'primary' : 'default'}\n />\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </TableContainer>\n </Box>\n ) : null}\n </Box>\n </Collapse>\n </Paper>\n );\n};\n\ninterface TeamUsageProps {\n teams: TeamInfo[];\n loading: boolean;\n dateRange: DateRange;\n getTeamUsage: (teamId: string) => UsageMetrics | null;\n getTeamUsageLoading: (teamId: string) => boolean;\n}\n\nexport const TeamUsage: React.FC<TeamUsageProps> = ({\n teams,\n loading,\n getTeamUsage,\n getTeamUsageLoading,\n}) => {\n if (loading) {\n return (\n <Paper sx={{ p: 2 }}>\n <LinearProgress />\n </Paper>\n );\n }\n\n if (!teams.length) {\n return (\n <Paper sx={{ p: 2 }}>\n <Box display=\"flex\" alignItems=\"center\" gap={1}>\n <Group color=\"disabled\" />\n <Typography color=\"text.secondary\" variant=\"body2\">\n No team membership found in LiteLLM for this account.\n </Typography>\n </Box>\n </Paper>\n );\n }\n\n return (\n <Box>\n <Typography variant=\"h6\" mb={1}>Teams</Typography>\n {teams.map(team => (\n <TeamCard\n key={team.team_id}\n team={team}\n usage={getTeamUsage(team.team_id)}\n usageLoading={getTeamUsageLoading(team.team_id)}\n />\n ))}\n </Box>\n );\n};\n", "import React, { useState, useCallback } from 'react';\nimport {\n Paper,\n Box,\n Typography,\n Table,\n TableBody,\n TableCell,\n TableContainer,\n TableHead,\n TableRow,\n TablePagination,\n TextField,\n MenuItem,\n Chip,\n CircularProgress,\n Collapse,\n IconButton,\n Alert,\n} from '@mui/material';\nimport { KeyboardArrowDown, KeyboardArrowUp } from '@mui/icons-material';\nimport { useAsync } from 'react-use';\nimport { LiteLlmApiInterface } from '../api';\nimport { AuditLogEntry, AuditLogsParams } from '../types';\n\ninterface AuditLogProps {\n api: LiteLlmApiInterface;\n}\n\nconst ACTION_COLORS: Record<string, 'success' | 'error' | 'warning' | 'info' | 'default'> = {\n created: 'success',\n deleted: 'error',\n updated: 'warning',\n blocked: 'error',\n unblocked: 'success',\n};\n\nfunction actionColor(action?: string): 'success' | 'error' | 'warning' | 'info' | 'default' {\n if (!action) return 'default';\n for (const [key, color] of Object.entries(ACTION_COLORS)) {\n if (action.toLowerCase().includes(key)) return color;\n }\n return 'info';\n}\n\nfunction formatDateTime(iso: string): string {\n try {\n return new Date(iso).toLocaleString();\n } catch {\n return iso;\n }\n}\n\nconst DetailRow: React.FC<{ entry: AuditLogEntry }> = ({ entry }) => {\n const [open, setOpen] = useState(false);\n const hasDetail = entry.before_value || entry.updated_values;\n\n return (\n <>\n <TableRow hover>\n <TableCell sx={{ width: 40, pr: 0 }}>\n {hasDetail && (\n <IconButton size=\"small\" onClick={() => setOpen(o => !o)}>\n {open ? <KeyboardArrowUp fontSize=\"small\" /> : <KeyboardArrowDown fontSize=\"small\" />}\n </IconButton>\n )}\n </TableCell>\n <TableCell sx={{ whiteSpace: 'nowrap' }}>{formatDateTime(entry.updated_at)}</TableCell>\n <TableCell>\n {entry.action && (\n <Chip label={entry.action} color={actionColor(entry.action)} size=\"small\" />\n )}\n </TableCell>\n <TableCell>{entry.table_name ?? '-'}</TableCell>\n <TableCell>\n <Typography variant=\"body2\" component=\"code\" sx={{ fontFamily: 'monospace', fontSize: '0.75rem' }}>\n {entry.object_id ? entry.object_id.slice(0, 20) + (entry.object_id.length > 20 ? '\u2026' : '') : '-'}\n </Typography>\n </TableCell>\n <TableCell>{entry.changed_by ?? '-'}</TableCell>\n </TableRow>\n {hasDetail && (\n <TableRow>\n <TableCell colSpan={6} sx={{ py: 0 }}>\n <Collapse in={open} unmountOnExit>\n <Box p={2} display=\"flex\" gap={2} flexWrap=\"wrap\">\n {entry.before_value && (\n <Box flex={1} minWidth={200}>\n <Typography variant=\"caption\" color=\"text.secondary\" display=\"block\" mb={0.5}>Before</Typography>\n <Typography component=\"pre\" variant=\"caption\" sx={{ fontFamily: 'monospace', whiteSpace: 'pre-wrap', wordBreak: 'break-all' }}>\n {JSON.stringify(entry.before_value, null, 2)}\n </Typography>\n </Box>\n )}\n {entry.updated_values && (\n <Box flex={1} minWidth={200}>\n <Typography variant=\"caption\" color=\"text.secondary\" display=\"block\" mb={0.5}>After</Typography>\n <Typography component=\"pre\" variant=\"caption\" sx={{ fontFamily: 'monospace', whiteSpace: 'pre-wrap', wordBreak: 'break-all' }}>\n {JSON.stringify(entry.updated_values, null, 2)}\n </Typography>\n </Box>\n )}\n </Box>\n </Collapse>\n </TableCell>\n </TableRow>\n )}\n </>\n );\n};\n\nexport const AuditLog: React.FC<AuditLogProps> = ({ api }) => {\n const [page, setPage] = useState(0);\n const [pageSize, setPageSize] = useState(25);\n const [filters, setFilters] = useState<Pick<AuditLogsParams, 'action' | 'table_name' | 'changed_by'>>({});\n\n const fetchParams: AuditLogsParams = useCallback(\n () => ({ page: page + 1, page_size: pageSize, ...filters }),\n [page, pageSize, filters],\n )();\n\n const { value, loading, error } = useAsync(\n () => api.getAuditLogs(fetchParams),\n [api, fetchParams],\n );\n\n const entries: AuditLogEntry[] = value?.audit_logs ?? [];\n const total = value?.total ?? 0;\n\n return (\n <Paper>\n <Box p={2} display=\"flex\" gap={2} flexWrap=\"wrap\" alignItems=\"center\">\n <Typography variant=\"h6\" sx={{ flex: '0 0 auto', mr: 1 }}>Audit Log</Typography>\n <TextField\n size=\"small\"\n label=\"Action\"\n select\n value={filters.action ?? ''}\n onChange={e => { setFilters(f => ({ ...f, action: e.target.value || undefined })); setPage(0); }}\n sx={{ minWidth: 160 }}\n >\n <MenuItem value=\"\">All actions</MenuItem>\n <MenuItem value=\"created\">Created</MenuItem>\n <MenuItem value=\"updated\">Updated</MenuItem>\n <MenuItem value=\"deleted\">Deleted</MenuItem>\n <MenuItem value=\"blocked\">Blocked</MenuItem>\n </TextField>\n <TextField\n size=\"small\"\n label=\"Table\"\n select\n value={filters.table_name ?? ''}\n onChange={e => { setFilters(f => ({ ...f, table_name: e.target.value || undefined })); setPage(0); }}\n sx={{ minWidth: 160 }}\n >\n <MenuItem value=\"\">All tables</MenuItem>\n <MenuItem value=\"LiteLLM_VerificationToken\">Key</MenuItem>\n <MenuItem value=\"LiteLLM_TeamTable\">Team</MenuItem>\n <MenuItem value=\"LiteLLM_UserTable\">User</MenuItem>\n </TextField>\n <TextField\n size=\"small\"\n label=\"Changed by\"\n value={filters.changed_by ?? ''}\n onChange={e => { setFilters(f => ({ ...f, changed_by: e.target.value || undefined })); setPage(0); }}\n sx={{ minWidth: 200 }}\n />\n </Box>\n\n {error && (\n <Box px={2} pb={2}>\n <Alert severity=\"error\">{error.message}</Alert>\n </Box>\n )}\n\n <TableContainer>\n <Table size=\"small\">\n <TableHead>\n <TableRow>\n <TableCell sx={{ width: 40 }} />\n <TableCell>Time</TableCell>\n <TableCell>Action</TableCell>\n <TableCell>Table</TableCell>\n <TableCell>Object ID</TableCell>\n <TableCell>Changed By</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {loading ? (\n <TableRow>\n <TableCell colSpan={6} align=\"center\" sx={{ py: 4 }}>\n <CircularProgress size={24} />\n </TableCell>\n </TableRow>\n ) : entries.length === 0 ? (\n <TableRow>\n <TableCell colSpan={6} align=\"center\" sx={{ py: 4 }}>\n <Typography color=\"text.secondary\">No audit events found</Typography>\n </TableCell>\n </TableRow>\n ) : (\n entries.map(entry => <DetailRow key={entry.id} entry={entry} />)\n )}\n </TableBody>\n </Table>\n </TableContainer>\n\n <TablePagination\n component=\"div\"\n count={total}\n page={page}\n onPageChange={(_, p) => setPage(p)}\n rowsPerPage={pageSize}\n onRowsPerPageChange={e => { setPageSize(Number(e.target.value)); setPage(0); }}\n rowsPerPageOptions={[10, 25, 50]}\n />\n </Paper>\n );\n};\n", "import React, { useState, useCallback, useMemo } from 'react';\nimport { Grid, Box, Snackbar, Alert, CircularProgress, Typography, Paper, Tabs, Tab } from '@mui/material';\nimport { useAsync, useAsyncRetry } from 'react-use';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { DashboardHeader } from './DashboardHeader';\nimport { KeysTable } from './KeysTable';\nimport { UsageStats } from './UsageStats';\nimport { TeamUsage } from './TeamUsage';\nimport { AuditLog } from './AuditLog';\nimport { liteLlmApiRef } from '../api';\nimport { DateRange, GenerateKeyRequest, GenerateKeyResponse, UpdateKeyRequest, UsageMetrics } from '../types';\n\nconst PERIOD_LS_KEY = 'litellm_usage_period';\n\nfunction initDateRange(): DateRange {\n let preset = '7d';\n try { preset = localStorage.getItem(PERIOD_LS_KEY) ?? '7d'; } catch { /* ignore */ }\n const end = new Date();\n const start = new Date();\n if (preset === 'today') start.setHours(0, 0, 0, 0);\n else if (preset === '24h') start.setHours(start.getHours() - 24);\n else if (preset === '30d') start.setDate(start.getDate() - 30);\n else start.setDate(start.getDate() - 7);\n return { start, end };\n}\n\nexport const LiteLLMPage: React.FC = () => {\n const api = useApi(liteLlmApiRef);\n\n const [dateRange, setDateRange] = useState<DateRange>(initDateRange);\n const [activeTab, setActiveTab] = useState<'overview' | 'audit'>('overview');\n\n const [snackbar, setSnackbar] = useState<{ message: string; severity: 'success' | 'warning' | 'error' } | null>(null);\n\n // Team usage cache: teamId -> UsageMetrics\n const [teamUsageCache, setTeamUsageCache] = useState<Record<string, UsageMetrics | null>>({});\n const [teamUsageLoading, setTeamUsageLoading] = useState<Record<string, boolean>>({});\n\n const { value: userInfo, loading: userLoading, error: userError } = useAsync(\n () => api.getUserInfo(),\n [api],\n );\n\n const { value: keys, loading: keysLoading, retry: refreshKeys } = useAsyncRetry(\n async () => {\n try {\n return await api.listKeys();\n } catch (e: any) {\n setSnackbar({ message: `Failed to load keys: ${e.message}`, severity: 'error' });\n return [];\n }\n },\n [api],\n );\n\n const { value: allModels, loading: modelsLoading } = useAsync(\n () => api.listModels().catch(() => []),\n [api],\n );\n\n const { value: allTeams, loading: teamsLoading } = useAsync(\n () => api.getTeams().catch(() => []),\n [api],\n );\n\n // Filter to teams the current user belongs to\n const teams = useMemo(() => {\n if (!allTeams?.length) return [];\n if (!userInfo) return allTeams;\n const userId = userInfo.user_id;\n if (userInfo.teams?.length) {\n return allTeams.filter(t => userInfo.teams!.includes(t.team_id));\n }\n const byMembership = allTeams.filter(t =>\n t.members_with_roles?.some(m => m.user_id === userId),\n );\n return byMembership.length > 0 ? byMembership : allTeams;\n }, [allTeams, userInfo]);\n\n const { value: usage, loading: usageLoading } = useAsync(async () => {\n const startDate = dateRange.start.toISOString().split('T')[0];\n const endDate = dateRange.end.toISOString().split('T')[0];\n return api.getUsage(startDate, endDate);\n }, [api, dateRange]);\n\n // Invalidate team usage cache when date range changes so stale data isn't shown\n const handleDateRangeChange = useCallback((range: DateRange) => {\n setDateRange(range);\n setTeamUsageCache({});\n setTeamUsageLoading({});\n }, [setDateRange]);\n\n // Fetch team usage on demand when a team card is expanded\n const loadTeamUsage = useCallback(async (teamId: string) => {\n if (teamUsageCache[teamId] !== undefined || teamUsageLoading[teamId]) return;\n setTeamUsageLoading(prev => ({ ...prev, [teamId]: true }));\n try {\n const startDate = dateRange.start.toISOString().split('T')[0];\n const endDate = dateRange.end.toISOString().split('T')[0];\n const data = await api.getTeamUsage(teamId, startDate, endDate);\n setTeamUsageCache(prev => ({ ...prev, [teamId]: data }));\n } catch {\n setTeamUsageCache(prev => ({ ...prev, [teamId]: null }));\n } finally {\n setTeamUsageLoading(prev => ({ ...prev, [teamId]: false }));\n }\n }, [api, dateRange, teamUsageCache, teamUsageLoading]);\n\n // Models available for key generation: intersection of all models with user-level\n // and team-level restrictions. If a user has no model restrictions, all models are allowed.\n const allowedModels = useMemo(() => {\n if (!allModels?.length) return [];\n const userModels = userInfo?.models;\n const teamModels = teams?.flatMap(t => t.models ?? []);\n const hasUserRestriction = userModels && userModels.length > 0;\n const hasTeamRestriction = teamModels && teamModels.length > 0;\n if (!hasUserRestriction && !hasTeamRestriction) return allModels;\n const allowed = new Set([\n ...(hasUserRestriction ? userModels! : allModels.map(m => m.model_name)),\n ...(hasTeamRestriction ? teamModels! : []),\n ]);\n return allModels.filter(m => allowed.has(m.model_name));\n }, [allModels, userInfo, teams]);\n\n const handleGenerateKey = useCallback(\n async (request: GenerateKeyRequest): Promise<GenerateKeyResponse> => {\n const response = await api.generateKey(request);\n setSnackbar({ message: 'Key generated successfully', severity: 'success' });\n refreshKeys();\n return response;\n },\n [api, refreshKeys],\n );\n\n const handleUpdateKey = useCallback(\n async (keyId: string, request: UpdateKeyRequest) => {\n try {\n await api.updateKey(keyId, request);\n setSnackbar({ message: 'Key updated successfully', severity: 'success' });\n refreshKeys();\n } catch (e: any) {\n setSnackbar({ message: `Failed to update key: ${e.message}`, severity: 'error' });\n throw e;\n }\n },\n [api, refreshKeys],\n );\n\n const handleBlockKey = useCallback(\n async (keyId: string) => {\n try {\n await api.blockKey(keyId);\n setSnackbar({ message: 'Key blocked \u2014 requests will be rejected until unblocked', severity: 'warning' });\n refreshKeys();\n } catch (e: any) {\n setSnackbar({ message: `Failed to block key: ${e.message}`, severity: 'error' });\n }\n },\n [api, refreshKeys],\n );\n\n const handleUnblockKey = useCallback(\n async (keyId: string) => {\n try {\n await api.unblockKey(keyId);\n setSnackbar({ message: 'Key unblocked', severity: 'success' });\n refreshKeys();\n } catch (e: any) {\n setSnackbar({ message: `Failed to unblock key: ${e.message}`, severity: 'error' });\n }\n },\n [api, refreshKeys],\n );\n\n const handleResetKeySpend = useCallback(\n async (keyId: string) => {\n try {\n await api.resetKeySpend(keyId);\n setSnackbar({ message: 'Spend counter reset to $0', severity: 'success' });\n refreshKeys();\n } catch (e: any) {\n setSnackbar({ message: `Failed to reset spend: ${e.message}`, severity: 'error' });\n }\n },\n [api, refreshKeys],\n );\n\n const handleRotateKey = useCallback(\n async (keyId: string): Promise<GenerateKeyResponse> => {\n const response = await api.rotateKey(keyId);\n setSnackbar({ message: 'Key rotated \u2014 copy the new secret now', severity: 'success' });\n refreshKeys();\n return response;\n },\n [api, refreshKeys],\n );\n\n const handleDeleteKey = useCallback(\n async (keyId: string) => {\n try {\n await api.deleteKey(keyId);\n setSnackbar({ message: 'Key revoked successfully', severity: 'success' });\n refreshKeys();\n } catch (e: any) {\n if (e.body?.success && (e.body?.message?.includes('already deleted') || e.body?.message?.includes('never existed'))) {\n setSnackbar({ message: 'Key was already deleted', severity: 'warning' });\n refreshKeys();\n return;\n }\n setSnackbar({ message: `Failed to revoke key: ${e.message}`, severity: 'error' });\n }\n },\n [api, refreshKeys],\n );\n\n const isInitialLoading = userLoading && !userInfo;\n\n if (isInitialLoading) {\n return (\n <Box display=\"flex\" justifyContent=\"center\" alignItems=\"center\" minHeight=\"50vh\">\n <CircularProgress />\n </Box>\n );\n }\n\n // User exists in Backstage but has no LiteLLM account\n if (userError || !userInfo) {\n const isProvisioningEnabled = (userError as any)?.body?.provisioning === true;\n const hint = (userError as any)?.body?.hint;\n return (\n <Box p={3}>\n <Paper sx={{ p: 3 }}>\n <Typography variant=\"h6\" gutterBottom>Account not provisioned</Typography>\n <Typography color=\"text.secondary\" paragraph>\n Your Backstage account is not linked to a LiteLLM user.\n </Typography>\n {hint ? (\n <Typography variant=\"body2\" color=\"text.secondary\">{hint}</Typography>\n ) : (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {isProvisioningEnabled\n ? 'Auto-provisioning is enabled but failed. Check the backend logs.'\n : 'Set litellm.provisioning.enabled: true in app-config.yaml to enable auto-provisioning, or ask your administrator to create the account manually.'}\n </Typography>\n )}\n </Paper>\n </Box>\n );\n }\n\n return (\n <Box p={3}>\n {userInfo.can_view_audit && (\n <Tabs\n value={activeTab}\n onChange={(_, v) => setActiveTab(v)}\n sx={{ mb: 2, borderBottom: 1, borderColor: 'divider' }}\n >\n <Tab label=\"Overview\" value=\"overview\" />\n <Tab label=\"Audit Log\" value=\"audit\" />\n </Tabs>\n )}\n\n {activeTab === 'audit' ? (\n <AuditLog api={api} />\n ) : (\n <Grid container spacing={2}>\n <Grid item xs={12}>\n <DashboardHeader userInfo={userInfo} teams={teams ?? []} loading={userLoading || teamsLoading} />\n </Grid>\n\n <Grid item xs={12}>\n <TeamUsage\n teams={teams ?? []}\n loading={teamsLoading}\n dateRange={dateRange}\n getTeamUsage={teamId => {\n if (teamUsageCache[teamId] === undefined) loadTeamUsage(teamId);\n return teamUsageCache[teamId] ?? null;\n }}\n getTeamUsageLoading={teamId => teamUsageLoading[teamId] ?? false}\n />\n </Grid>\n\n <Grid item xs={12}>\n <UsageStats\n usage={usage ?? null}\n models={allModels ?? []}\n dateRange={dateRange}\n onDateRangeChange={handleDateRangeChange}\n loading={usageLoading}\n userInfo={userInfo}\n />\n </Grid>\n\n <Grid item xs={12}>\n <KeysTable\n keys={keys ?? []}\n models={allowedModels}\n teams={teams ?? []}\n loading={keysLoading || modelsLoading}\n onGenerateKey={handleGenerateKey}\n onUpdateKey={handleUpdateKey}\n onRotateKey={handleRotateKey}\n onBlockKey={handleBlockKey}\n onUnblockKey={handleUnblockKey}\n onResetKeySpend={handleResetKeySpend}\n onDeleteKey={handleDeleteKey}\n />\n </Grid>\n </Grid>\n )}\n\n <Snackbar\n open={!!snackbar}\n autoHideDuration={5000}\n onClose={() => setSnackbar(null)}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n >\n {snackbar ? (\n <Alert severity={snackbar.severity} onClose={() => setSnackbar(null)}>\n {snackbar.message}\n </Alert>\n ) : undefined}\n </Snackbar>\n </Box>\n );\n};\n", "export { litellmPlugin } from './plugin';\nexport { LiteLLMPage } from './components/LiteLLMPage';\nexport { DashboardHeader } from './components/DashboardHeader';\nexport { KeysTable } from './components/KeysTable';\nexport { UsageStats } from './components/UsageStats';\nexport { TeamUsage } from './components/TeamUsage';\nexport { LiteLLMHomeWidget } from './components/LiteLLMHomeWidget';\nexport type { LiteLLMHomeWidgetProps } from './components/LiteLLMHomeWidget';\nexport { LiteLlmApi, liteLlmApiRef } from './api';\nexport type { LiteLlmApiInterface } from './api';\nexport * from './types';\n", "import React from 'react';\nimport { TrendingUp as TrendingUpIcon } from '@mui/icons-material';\nimport {\n createFrontendPlugin,\n ApiBlueprint,\n PageBlueprint,\n fetchApiRef,\n} from '@backstage/frontend-plugin-api';\nimport { liteLlmApiRef, LiteLlmApi } from './api';\n\nconst liteLlmApi = ApiBlueprint.make({\n params: defineParams =>\n defineParams({\n api: liteLlmApiRef,\n deps: { fetchApi: fetchApiRef },\n factory: ({ fetchApi }) => new LiteLlmApi(fetchApi),\n }),\n});\n\nconst liteLlmPage = PageBlueprint.make({\n params: {\n path: '/litellm',\n title: 'LiteLLM',\n icon: <TrendingUpIcon />,\n loader: async () => {\n const { LiteLLMPage } = await import('./components/LiteLLMPage');\n return <LiteLLMPage />;\n },\n },\n});\n\nexport const litellmPlugin = createFrontendPlugin({\n pluginId: 'litellm',\n extensions: [liteLlmApi, liteLlmPage],\n});\n", "import React, { useState, useEffect } from 'react';\nimport {\n Paper,\n Box,\n Typography,\n FormControl,\n Select,\n MenuItem,\n Grid,\n CircularProgress,\n Alert,\n} from '@mui/material';\nimport { AreaChart, Area, ResponsiveContainer } from 'recharts';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { liteLlmApiRef } from '../api';\nimport { UsageMetrics, VirtualKey } from '../types';\n\nexport interface LiteLLMHomeWidgetProps {\n /** Default period when the widget mounts. Defaults to '7d'. */\n defaultPeriod?: 'today' | '7d' | '30d';\n /** Optional title override. Defaults to 'LiteLLM Usage'. */\n title?: string;\n}\n\ntype DatePreset = 'today' | '7d' | '30d';\n\nconst fmtUsd = (n: number) => `$${(n ?? 0).toFixed(n < 1 ? 4 : 2)}`;\nconst fmtInt = (n: number) => (n ?? 0).toLocaleString();\n\nfunction presetToDateRange(preset: DatePreset): { start: Date; end: Date } {\n const end = new Date();\n const start = new Date();\n if (preset === 'today') {\n start.setHours(0, 0, 0, 0);\n } else if (preset === '7d') {\n start.setDate(start.getDate() - 7);\n } else {\n start.setDate(start.getDate() - 30);\n }\n return { start, end };\n}\n\ninterface KpiProps {\n label: string;\n value: string;\n}\n\nconst Kpi: React.FC<KpiProps> = ({ label, value }) => (\n <Box>\n <Typography variant=\"caption\" color=\"text.secondary\" display=\"block\">\n {label}\n </Typography>\n <Typography variant=\"subtitle1\" fontWeight={600}>\n {value}\n </Typography>\n </Box>\n);\n\nexport const LiteLLMHomeWidget: React.FC<LiteLLMHomeWidgetProps> = ({\n defaultPeriod = '7d',\n title = 'LiteLLM Usage',\n}) => {\n const api = useApi(liteLlmApiRef);\n const [period, setPeriod] = useState<DatePreset>(defaultPeriod);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [usage, setUsage] = useState<UsageMetrics | null>(null);\n const [keys, setKeys] = useState<VirtualKey[]>([]);\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n setError(null);\n\n const { start, end } = presetToDateRange(period);\n const startDate = start.toISOString().split('T')[0];\n const endDate = end.toISOString().split('T')[0];\n\n Promise.all([api.getUsage(startDate, endDate), api.listKeys()])\n .then(([usageData, keysData]) => {\n if (!cancelled) {\n setUsage(usageData);\n setKeys(keysData);\n setLoading(false);\n }\n })\n .catch((err: Error) => {\n if (!cancelled) {\n setError(err.message ?? 'Failed to load usage data');\n setLoading(false);\n }\n });\n\n return () => {\n cancelled = true;\n };\n }, [api, period]);\n\n const dailyData = (usage?.daily_usage ?? []).map(d => ({\n date: d.date,\n spend: d.spend,\n }));\n\n const hasSparkline = dailyData.length > 0;\n\n return (\n <Paper sx={{ p: 2 }}>\n {/* Card header */}\n <Box display=\"flex\" justifyContent=\"space-between\" alignItems=\"center\" mb={1.5}>\n <Typography variant=\"h6\">{title}</Typography>\n <FormControl size=\"small\" sx={{ minWidth: 90 }}>\n <Select\n value={period}\n onChange={e => setPeriod(e.target.value as DatePreset)}\n displayEmpty\n >\n <MenuItem value=\"today\">Today</MenuItem>\n <MenuItem value=\"7d\">7d</MenuItem>\n <MenuItem value=\"30d\">30d</MenuItem>\n </Select>\n </FormControl>\n </Box>\n\n {/* Loading state */}\n {loading && (\n <Box display=\"flex\" justifyContent=\"center\" alignItems=\"center\" minHeight={120}>\n <CircularProgress size={32} />\n </Box>\n )}\n\n {/* Error state */}\n {!loading && error && (\n <Alert severity=\"error\" sx={{ mt: 1 }}>\n {error}\n </Alert>\n )}\n\n {/* Content */}\n {!loading && !error && (\n <>\n <Grid container spacing={2} sx={{ mb: hasSparkline ? 1.5 : 0 }}>\n <Grid item xs={6}>\n <Kpi label=\"USD Spent\" value={fmtUsd(usage?.total_spend ?? 0)} />\n </Grid>\n <Grid item xs={6}>\n <Kpi label=\"Tokens In\" value={fmtInt(usage?.prompt_tokens ?? 0)} />\n </Grid>\n <Grid item xs={6}>\n <Kpi label=\"Tokens Out\" value={fmtInt(usage?.completion_tokens ?? 0)} />\n </Grid>\n <Grid item xs={6}>\n <Kpi label=\"Keys\" value={fmtInt(keys.length)} />\n </Grid>\n </Grid>\n\n {/* Sparkline */}\n {hasSparkline && (\n <Box height={120}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <AreaChart data={dailyData} margin={{ top: 4, right: 0, bottom: 0, left: 0 }}>\n <Area\n type=\"monotone\"\n dataKey=\"spend\"\n stroke=\"#8884d8\"\n fill=\"#8884d8\"\n fillOpacity={0.3}\n dot={false}\n isAnimationActive={false}\n />\n </AreaChart>\n </ResponsiveContainer>\n </Box>\n )}\n </>\n )}\n </Paper>\n );\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { createApiRef, FetchApi } from '@backstage/core-plugin-api';\nimport {\n UserInfo,\n VirtualKey,\n ModelInfo,\n UsageMetrics,\n TeamInfo,\n GenerateKeyRequest,\n GenerateKeyResponse,\n UpdateKeyRequest,\n AuditLogsParams,\n PaginatedAuditLogs,\n} from './types';\n\nclass ApiError extends Error {\n body: unknown;\n status: number;\n constructor(message: string, status: number, body: unknown) {\n super(message);\n this.status = status;\n this.body = body;\n }\n}\n\nexport interface LiteLlmApiInterface {\n getUserInfo(): Promise<UserInfo>;\n listKeys(): Promise<VirtualKey[]>;\n generateKey(request: GenerateKeyRequest): Promise<GenerateKeyResponse>;\n updateKey(keyId: string, request: UpdateKeyRequest): Promise<VirtualKey>;\n deleteKey(keyId: string): Promise<{ success: boolean }>;\n rotateKey(keyId: string): Promise<GenerateKeyResponse>;\n blockKey(keyId: string): Promise<void>;\n unblockKey(keyId: string): Promise<void>;\n resetKeySpend(keyId: string): Promise<void>;\n pruneExpiredKeys(): Promise<{ pruned: number }>;\n listModels(): Promise<ModelInfo[]>;\n getTeams(): Promise<TeamInfo[]>;\n getUsage(startDate: string, endDate: string): Promise<UsageMetrics>;\n getTeamUsage(teamId: string, startDate: string, endDate: string): Promise<UsageMetrics>;\n getAuditLogs(params: AuditLogsParams): Promise<PaginatedAuditLogs>;\n}\n\nexport const liteLlmApiRef = createApiRef<LiteLlmApiInterface>({\n id: 'plugin.litellm.api',\n});\n\nexport type ExpiryStatus = 'expired' | 'soon' | 'ok';\n\nexport function expiryStatus(expiresAt?: string): ExpiryStatus | null {\n if (!expiresAt) return null;\n const diff = new Date(expiresAt).getTime() - Date.now();\n const days = diff / (1000 * 60 * 60 * 24);\n if (days < 0) return 'expired';\n if (days < 7) return 'soon';\n return 'ok';\n}\n\nexport class LiteLlmApi implements LiteLlmApiInterface {\n private fetchApi: FetchApi;\n private basePath: string;\n\n constructor(fetchApi: FetchApi, basePath: string = '/api/litellm') {\n this.fetchApi = fetchApi;\n this.basePath = basePath;\n }\n\n private async throwIfNotOk(response: Response): Promise<void> {\n if (!response.ok) {\n let body: unknown;\n try { body = await response.json(); } catch { body = await response.text().catch(() => ''); }\n throw new ApiError(`${response.status} ${response.statusText}`, response.status, body);\n }\n }\n\n private async get<T>(path: string, params?: Record<string, string>): Promise<T> {\n const url = new URL(`${this.basePath}${path}`, window.location.origin);\n if (params) {\n Object.entries(params).forEach(([key, value]) => url.searchParams.append(key, value));\n }\n const response = await this.fetchApi.fetch(url.toString());\n await this.throwIfNotOk(response);\n return response.json();\n }\n\n private async post<T>(path: string, body: unknown): Promise<T> {\n const response = await this.fetchApi.fetch(`${this.basePath}${path}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n await this.throwIfNotOk(response);\n return response.json();\n }\n\n private async del<T>(path: string): Promise<T> {\n const response = await this.fetchApi.fetch(`${this.basePath}${path}`, {\n method: 'DELETE',\n headers: { 'Content-Type': 'application/json' },\n });\n await this.throwIfNotOk(response);\n return response.json();\n }\n\n // User identity is resolved server-side from the Backstage Bearer token.\n // No user_id param needed on the frontend.\n async getUserInfo(): Promise<UserInfo> {\n return this.get<UserInfo>('/user/info');\n }\n\n async listKeys(): Promise<VirtualKey[]> {\n return this.get<VirtualKey[]>('/keys');\n }\n\n async generateKey(request: GenerateKeyRequest): Promise<GenerateKeyResponse> {\n return this.post<GenerateKeyResponse>('/keys/generate', request);\n }\n\n async updateKey(keyId: string, request: UpdateKeyRequest): Promise<VirtualKey> {\n return this.post<VirtualKey>(`/keys/${encodeURIComponent(keyId)}/update`, request);\n }\n\n async deleteKey(keyId: string): Promise<{ success: boolean }> {\n return this.del<{ success: boolean }>(`/keys/${encodeURIComponent(keyId)}`);\n }\n\n async rotateKey(keyId: string): Promise<GenerateKeyResponse> {\n return this.post<GenerateKeyResponse>(`/keys/${encodeURIComponent(keyId)}/regenerate`, {});\n }\n\n async blockKey(keyId: string): Promise<void> {\n await this.post(`/keys/${encodeURIComponent(keyId)}/block`, {});\n }\n\n async unblockKey(keyId: string): Promise<void> {\n await this.post(`/keys/${encodeURIComponent(keyId)}/unblock`, {});\n }\n\n async resetKeySpend(keyId: string): Promise<void> {\n await this.post(`/keys/${encodeURIComponent(keyId)}/reset_spend`, {});\n }\n\n async pruneExpiredKeys(): Promise<{ pruned: number }> {\n const keys = await this.get<VirtualKey[]>('/keys');\n const expired = keys.filter(k => expiryStatus(k.expires_at) === 'expired');\n if (expired.length === 0) return { pruned: 0 };\n for (const key of expired) {\n try {\n await this.del(`/keys/${encodeURIComponent(key.token ?? key.key)}`);\n } catch (err) {\n console.warn(`Failed to delete expired key ${key.token ?? key.key}:`, err);\n }\n }\n return { pruned: expired.length };\n }\n\n async getAuditLogs(params: AuditLogsParams): Promise<PaginatedAuditLogs> {\n const strParams: Record<string, string> = {};\n if (params.page !== undefined) strParams.page = String(params.page);\n if (params.page_size !== undefined) strParams.page_size = String(params.page_size);\n if (params.start_date) strParams.start_date = params.start_date;\n if (params.end_date) strParams.end_date = params.end_date;\n if (params.action) strParams.action = params.action;\n if (params.table_name) strParams.table_name = params.table_name;\n if (params.changed_by) strParams.changed_by = params.changed_by;\n return this.get<PaginatedAuditLogs>('/audit', strParams);\n }\n\n async listModels(): Promise<ModelInfo[]> {\n return this.get<ModelInfo[]>('/models');\n }\n\n async getTeams(): Promise<TeamInfo[]> {\n return this.get<TeamInfo[]>('/teams');\n }\n\n async getUsage(startDate: string, endDate: string): Promise<UsageMetrics> {\n return this.get<UsageMetrics>('/usage', { start_date: startDate, end_date: endDate });\n }\n\n async getTeamUsage(teamId: string, startDate: string, endDate: string): Promise<UsageMetrics> {\n return this.get<UsageMetrics>(`/teams/${encodeURIComponent(teamId)}/usage`, {\n start_date: startDate,\n end_date: endDate,\n });\n }\n}\n", "import React from 'react';\nimport { Box, Typography, LinearProgress, Paper, Chip } from '@mui/material';\nimport { UserInfo, TeamInfo } from '../types';\n\ninterface DashboardHeaderProps {\n userInfo: UserInfo;\n teams: TeamInfo[];\n loading: boolean;\n}\n\nexport const DashboardHeader: React.FC<DashboardHeaderProps> = ({ userInfo, teams, loading }) => {\n if (loading) {\n return (\n <Paper sx={{ p: 2, mb: 2 }}>\n <LinearProgress />\n </Paper>\n );\n }\n\n const displayName = userInfo.user_email ?? userInfo.email ?? userInfo.user_id;\n\n return (\n <Paper sx={{ p: 2, mb: 2 }}>\n <Box display=\"flex\" alignItems=\"flex-start\" gap={2} flexWrap=\"wrap\">\n <Box flexGrow={1}>\n <Typography variant=\"h6\">{displayName}</Typography>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {userInfo.user_id}\n </Typography>\n\n {teams.length > 0 && (\n <Box display=\"flex\" gap={0.75} flexWrap=\"wrap\" mt={1}>\n {teams.map(team => (\n <Chip\n key={team.team_id}\n label={team.team_alias || team.team_id}\n size=\"small\"\n variant=\"outlined\"\n color=\"primary\"\n />\n ))}\n </Box>\n )}\n </Box>\n </Box>\n </Paper>\n );\n};\n", "import React, { useState, useMemo } from 'react';\nimport {\n Paper,\n Table,\n TableBody,\n TableCell,\n TableContainer,\n TableHead,\n TableRow,\n Button,\n IconButton,\n Box,\n Typography,\n Dialog,\n DialogTitle,\n DialogContent,\n DialogActions,\n TextField,\n MenuItem,\n Chip,\n CircularProgress,\n Autocomplete,\n LinearProgress,\n InputAdornment,\n} from '@mui/material';\nimport { ContentCopy, Delete, Add, Edit, Autorenew, Search, Warning, Lock, LockOpen } from '@mui/icons-material';\nimport { expiryStatus } from '../api';\nimport {\n VirtualKey,\n ModelInfo,\n TeamInfo,\n GenerateKeyRequest,\n GenerateKeyResponse,\n UpdateKeyRequest,\n} from '../types';\n\ninterface KeysTableProps {\n keys: VirtualKey[];\n models: ModelInfo[];\n teams: TeamInfo[];\n loading: boolean;\n onGenerateKey: (request: GenerateKeyRequest) => Promise<GenerateKeyResponse>;\n onUpdateKey: (keyId: string, request: UpdateKeyRequest) => Promise<void>;\n onRotateKey: (keyId: string) => Promise<GenerateKeyResponse>;\n onBlockKey: (keyId: string) => Promise<void>;\n onUnblockKey: (keyId: string) => Promise<void>;\n onResetKeySpend: (keyId: string) => Promise<void>;\n onDeleteKey: (keyId: string) => Promise<void>;\n onPruneExpiredKeys: () => Promise<{ pruned: number }>;\n}\n\nconst maskKey = (key: string): string => {\n if (key.length <= 8) return '***';\n return `${key.slice(0, 4)}...${key.slice(-4)}`;\n};\n\nconst shortKeyId = (token: string): string => {\n if (!token) return '-';\n if (token.length <= 16) return token;\n return `${token.slice(0, 12)}\u2026`;\n};\n\nconst formatDate = (dateStr: string): string => {\n try {\n return new Date(dateStr).toLocaleDateString();\n } catch {\n return dateStr;\n }\n};\n\nfunction ExpiryChip({ expiresAt }: { expiresAt?: string }) {\n const status = expiryStatus(expiresAt);\n if (!status) return <Typography variant=\"body2\" color=\"text.secondary\">-</Typography>;\n const label = status === 'expired' ? 'Expired' : status === 'soon' ? `${Math.ceil((new Date(expiresAt!).getTime() - Date.now()) / 86400000)}d left` : formatDate(expiresAt!);\n const color = status === 'expired' ? 'error' : status === 'soon' ? 'warning' : 'default';\n const icon = (status === 'expired' || status === 'soon') ? <Warning fontSize=\"small\" /> : undefined;\n return <Chip label={label} color={color} size=\"small\" icon={icon} />;\n}\n\nfunction BudgetCell({ spend, maxBudget }: { spend: number; maxBudget?: number }) {\n if (!maxBudget) return <Typography variant=\"body2\" color=\"text.secondary\">-</Typography>;\n const pct = Math.min(100, (spend / maxBudget) * 100);\n const color = pct >= 100 ? 'error' : pct >= 80 ? 'warning' : 'primary';\n return (\n <Box minWidth={100}>\n <Box display=\"flex\" justifyContent=\"space-between\">\n <Typography variant=\"caption\">${spend.toFixed(2)}</Typography>\n <Typography variant=\"caption\" color=\"text.secondary\">${maxBudget}</Typography>\n </Box>\n <LinearProgress variant=\"determinate\" value={pct} color={color} sx={{ height: 5, borderRadius: 1, mt: 0.25 }} />\n </Box>\n );\n}\n\nfunction fmtCost(perToken?: number): string | null {\n if (!perToken) return null;\n const per1k = perToken * 1000;\n return per1k < 0.01 ? `$${(perToken * 1_000_000).toFixed(2)}/M` : `$${per1k.toFixed(3)}/1K`;\n}\n\nconst emptyForm = (): GenerateKeyRequest => ({\n alias: '',\n models: [],\n duration: '30d',\n max_budget: 100,\n tpm_limit: undefined,\n rpm_limit: undefined,\n team_id: undefined,\n key_type: 'llm_api',\n});\n\nconst keyToEditForm = (k: VirtualKey): UpdateKeyRequest => ({\n key_alias: k.key_alias ?? '',\n models: k.models ?? [],\n max_budget: k.max_budget,\n tpm_limit: k.tpm_limit,\n rpm_limit: k.rpm_limit,\n});\n\nexport const KeysTable: React.FC<KeysTableProps> = ({\n keys,\n models,\n teams,\n loading,\n onGenerateKey,\n onUpdateKey,\n onRotateKey,\n onBlockKey,\n onUnblockKey,\n onResetKeySpend,\n onDeleteKey,\n onPruneExpiredKeys,\n}) => {\n const [generateModalOpen, setGenerateModalOpen] = useState(false);\n const [newKeyValue, setNewKeyValue] = useState<string | null>(null);\n const [formData, setFormData] = useState<GenerateKeyRequest>(emptyForm());\n const [submitting, setSubmitting] = useState(false);\n\n const [editingKey, setEditingKey] = useState<VirtualKey | null>(null);\n const [editForm, setEditForm] = useState<UpdateKeyRequest>({});\n const [editSubmitting, setEditSubmitting] = useState(false);\n\n // Rotation\n const [rotatingKeyId, setRotatingKeyId] = useState<string | null>(null);\n const [rotatedKeyValue, setRotatedKeyValue] = useState<string | null>(null);\n\n // Block/unblock\n const [blockingKeyId, setBlockingKeyId] = useState<string | null>(null);\n\n // Delete confirmation\n const [deleteConfirmId, setDeleteConfirmId] = useState<string | null>(null);\n const [deleteSubmitting, setDeleteSubmitting] = useState(false);\n\n // Reset spend (lives inside edit dialog)\n const [resetSpendConfirm, setResetSpendConfirm] = useState(false);\n const [resetSpendSubmitting, setResetSpendSubmitting] = useState(false);\n\n // Filter\n const [filterText, setFilterText] = useState('');\n\n const filteredKeys = useMemo(() => {\n if (!filterText.trim()) return keys;\n const q = filterText.toLowerCase();\n return keys.filter(k =>\n (k.key_alias ?? '').toLowerCase().includes(q) ||\n k.models?.some(m => m.toLowerCase().includes(q)),\n );\n }, [keys, filterText]);\n\n const selectedModels = models.filter(m => (formData.models || []).includes(m.model_name));\n const selectedTeam = teams.find(t => t.team_id === formData.team_id) ?? null;\n const editSelectedModels = models.filter(m => (editForm.models || []).includes(m.model_name));\n\n const handleGenerate = async () => {\n setSubmitting(true);\n try {\n const response = await onGenerateKey(formData);\n setNewKeyValue(response.key);\n setFormData(emptyForm());\n } catch (error) {\n console.error('Failed to generate key:', error);\n } finally {\n setSubmitting(false);\n }\n };\n\n const handleCloseModal = () => {\n setGenerateModalOpen(false);\n setNewKeyValue(null);\n setFormData(emptyForm());\n };\n\n const handleOpenEdit = (k: VirtualKey) => {\n setEditingKey(k);\n setEditForm(keyToEditForm(k));\n };\n\n const handleCloseEdit = () => {\n setEditingKey(null);\n setEditForm({});\n setResetSpendConfirm(false);\n };\n\n const handleUpdate = async () => {\n if (!editingKey) return;\n setEditSubmitting(true);\n try {\n await onUpdateKey(editingKey.token ?? editingKey.key, editForm);\n handleCloseEdit();\n } catch (error) {\n console.error('Failed to update key:', error);\n } finally {\n setEditSubmitting(false);\n }\n };\n\n const handleRotate = async (keyId: string) => {\n setRotatingKeyId(keyId);\n try {\n const response = await onRotateKey(keyId);\n setRotatedKeyValue(response.key);\n } catch (error) {\n console.error('Failed to rotate key:', error);\n } finally {\n setRotatingKeyId(null);\n }\n };\n\n const handleToggleBlock = async (key: VirtualKey) => {\n const keyId = key.token ?? key.key;\n setBlockingKeyId(keyId);\n try {\n if (key.blocked) {\n await onUnblockKey(keyId);\n } else {\n await onBlockKey(keyId);\n }\n } finally {\n setBlockingKeyId(null);\n }\n };\n\n const handleResetSpend = async () => {\n if (!editingKey) return;\n setResetSpendSubmitting(true);\n try {\n await onResetKeySpend(editingKey.token ?? editingKey.key);\n setResetSpendConfirm(false);\n handleCloseEdit();\n } finally {\n setResetSpendSubmitting(false);\n }\n };\n\n const handleConfirmDelete = async () => {\n if (!deleteConfirmId) return;\n setDeleteSubmitting(true);\n try {\n await onDeleteKey(deleteConfirmId);\n } finally {\n setDeleteSubmitting(false);\n setDeleteConfirmId(null);\n }\n };\n\n const copyToClipboard = (text: string) => {\n navigator.clipboard.writeText(text);\n };\n\n // Prune expired keys\n const [pruneConfirmCount, setPruneConfirmCount] = useState<number | null>(null);\n const [pruneSubmitting, setPruneSubmitting] = useState(false);\n\n const expiredKeys = useMemo(() => {\n return keys.filter(k => expiryStatus(k.expires_at) === 'expired');\n }, [keys]);\n\n const handlePruneExpired = async () => {\n if (pruneConfirmCount === null || pruneConfirmCount === 0) return;\n setPruneSubmitting(true);\n try {\n await onPruneExpiredKeys();\n } catch (error) {\n console.error('Failed to prune expired keys:', error);\n } finally {\n setPruneSubmitting(false);\n setPruneConfirmCount(null);\n }\n };\n\n const modelOption = (m: ModelInfo) => {\n const inCost = fmtCost(m.input_cost_per_token);\n const outCost = fmtCost(m.output_cost_per_token);\n return (\n <Box>\n <span>{m.model_name}</span>\n {m.supports_function_calling && ' \uD83D\uDD27'}\n {m.supports_vision && ' \uD83D\uDC41\uFE0F'}\n {(inCost || outCost) && (\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ ml: 1 }}>\n {inCost} in \u00B7 {outCost} out\n </Typography>\n )}\n </Box>\n );\n };\n\n return (\n <>\n <Paper sx={{ mb: 2 }}>\n <Box display=\"flex\" justifyContent=\"space-between\" alignItems=\"center\" p={2} gap={2}>\n <Typography variant=\"h6\">Virtual Keys</Typography>\n <Box display=\"flex\" gap={1} alignItems=\"center\" flex={1} justifyContent=\"flex-end\">\n <TextField\n size=\"small\"\n placeholder=\"Filter by alias or model\u2026\"\n value={filterText}\n onChange={e => setFilterText(e.target.value)}\n sx={{ minWidth: 240 }}\n InputProps={{\n startAdornment: (\n <InputAdornment position=\"start\">\n <Search fontSize=\"small\" />\n </InputAdornment>\n ),\n }}\n />\n {expiredKeys.length > 0 && (\n <Button\n variant=\"outlined\"\n color=\"error\"\n startIcon={<Autorenew />}\n onClick={() => setPruneConfirmCount(expiredKeys.length)}\n >\n Prune expired ({expiredKeys.length})\n </Button>\n )}\n <Button\n variant=\"contained\"\n color=\"primary\"\n startIcon={<Add />}\n onClick={() => setGenerateModalOpen(true)}\n >\n Generate New Key\n </Button>\n </Box>\n </Box>\n\n <TableContainer>\n <Table>\n <TableHead>\n <TableRow>\n <TableCell>Alias</TableCell>\n <TableCell>Key ID</TableCell>\n <TableCell>Created</TableCell>\n <TableCell>Expires</TableCell>\n <TableCell>Budget</TableCell>\n <TableCell>TPM / RPM</TableCell>\n <TableCell>Models</TableCell>\n <TableCell align=\"right\">Actions</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {loading ? (\n <TableRow>\n <TableCell colSpan={8} align=\"center\">\n <CircularProgress size={24} />\n </TableCell>\n </TableRow>\n ) : filteredKeys.length === 0 ? (\n <TableRow>\n <TableCell colSpan={8} align=\"center\">\n <Typography color=\"text.secondary\">\n {filterText ? 'No keys match filter' : 'No keys found'}\n </Typography>\n </TableCell>\n </TableRow>\n ) : (\n filteredKeys.map((key) => {\n const keyId = key.token ?? key.key;\n const isRotating = rotatingKeyId === keyId;\n const isBlocking = blockingKeyId === keyId;\n return (\n <TableRow key={keyId} sx={key.blocked ? { bgcolor: 'action.disabledBackground' } : undefined}>\n <TableCell>\n <Box display=\"flex\" alignItems=\"center\" gap={0.5}>\n {key.key_alias || '-'}\n {key.blocked && <Chip label=\"Blocked\" color=\"error\" size=\"small\" />}\n </Box>\n </TableCell>\n <TableCell>\n <Box display=\"flex\" alignItems=\"center\" gap={0.5}>\n <Typography\n variant=\"body2\"\n component=\"code\"\n color=\"text.secondary\"\n title={keyId}\n sx={{\n fontFamily: 'monospace',\n backgroundColor: 'background.default',\n px: 1,\n py: 0.5,\n borderRadius: 1,\n }}\n >\n {shortKeyId(keyId)}\n </Typography>\n <IconButton size=\"small\" onClick={() => copyToClipboard(keyId)} title=\"Copy Key ID\">\n <ContentCopy fontSize=\"small\" />\n </IconButton>\n </Box>\n </TableCell>\n <TableCell>{formatDate(key.created_at)}</TableCell>\n <TableCell>\n <ExpiryChip expiresAt={key.expires_at} />\n </TableCell>\n <TableCell>\n <BudgetCell spend={key.spend ?? 0} maxBudget={key.max_budget} />\n </TableCell>\n <TableCell>\n <Typography variant=\"body2\">{key.tpm_limit ?? '-'} / {key.rpm_limit ?? '-'}</Typography>\n </TableCell>\n <TableCell>\n <Box display=\"flex\" gap={0.5} flexWrap=\"wrap\">\n {key.models?.slice(0, 2).map((model) => (\n <Chip key={model} label={model} size=\"small\" />\n ))}\n {(key.models?.length || 0) > 2 && (\n <Chip label={`+${(key.models?.length || 0) - 2}`} size=\"small\" variant=\"outlined\" />\n )}\n </Box>\n </TableCell>\n <TableCell align=\"right\">\n <IconButton onClick={() => handleOpenEdit(key)} title=\"Edit key\">\n <Edit fontSize=\"small\" />\n </IconButton>\n <IconButton\n onClick={() => handleRotate(keyId)}\n disabled={isRotating}\n title=\"Rotate key \u2014 generates a new secret, same settings\"\n >\n {isRotating ? <CircularProgress size={18} /> : <Autorenew fontSize=\"small\" />}\n </IconButton>\n <IconButton\n onClick={() => handleToggleBlock(key)}\n disabled={isBlocking}\n color={key.blocked ? 'warning' : 'default'}\n title={key.blocked ? 'Unblock key' : 'Block key \u2014 suspends without revoking'}\n >\n {isBlocking ? <CircularProgress size={18} /> : key.blocked ? <LockOpen fontSize=\"small\" /> : <Lock fontSize=\"small\" />}\n </IconButton>\n <IconButton\n color=\"error\"\n onClick={() => setDeleteConfirmId(keyId)}\n title=\"Revoke key\"\n >\n <Delete />\n </IconButton>\n </TableCell>\n </TableRow>\n );\n })\n )}\n </TableBody>\n </Table>\n </TableContainer>\n </Paper>\n\n {/* Generate dialog */}\n <Dialog open={generateModalOpen} onClose={handleCloseModal} maxWidth=\"sm\" fullWidth>\n <DialogTitle>{newKeyValue ? 'Key Generated' : 'Generate New Key'}</DialogTitle>\n <DialogContent>\n {newKeyValue ? (\n <Box>\n <Typography variant=\"body2\" color=\"text.secondary\" gutterBottom>\n Copy this key now. You won't be able to see it again.\n </Typography>\n <Box\n display=\"flex\"\n alignItems=\"center\"\n gap={1}\n mt={2}\n p={2}\n sx={{\n backgroundColor: 'action.hover',\n border: '1px solid',\n borderColor: 'divider',\n borderRadius: 1,\n }}\n >\n <Typography\n component=\"code\"\n color=\"text.primary\"\n sx={{ fontFamily: 'monospace', wordBreak: 'break-all', flex: 1 }}\n >\n {newKeyValue}\n </Typography>\n <IconButton onClick={() => copyToClipboard(newKeyValue)}>\n <ContentCopy />\n </IconButton>\n </Box>\n </Box>\n ) : (\n <Box display=\"flex\" flexDirection=\"column\" gap={2} mt={1}>\n <TextField\n label=\"Alias\"\n value={formData.alias || ''}\n onChange={(e) => setFormData({ ...formData, alias: e.target.value })}\n required\n fullWidth\n />\n <TextField\n select\n label=\"Duration\"\n value={formData.duration || '30d'}\n onChange={(e) => setFormData({ ...formData, duration: e.target.value })}\n fullWidth\n >\n <MenuItem value=\"1d\">1 Day</MenuItem>\n <MenuItem value=\"7d\">7 Days</MenuItem>\n <MenuItem value=\"30d\">30 Days</MenuItem>\n <MenuItem value=\"90d\">90 Days</MenuItem>\n <MenuItem value=\"1y\">1 Year</MenuItem>\n </TextField>\n\n {teams.length > 0 && (\n <Autocomplete\n options={teams}\n getOptionLabel={t => t.team_alias || t.team_id}\n value={selectedTeam}\n onChange={(_e, team) =>\n setFormData({ ...formData, team_id: team?.team_id })\n }\n renderInput={params => (\n <TextField\n {...params}\n label=\"Team\"\n helperText=\"Optional: bind this key to a specific team for scoped access\"\n fullWidth\n />\n )}\n />\n )}\n\n {models.length > 0 && (\n <Autocomplete\n multiple\n options={models}\n groupBy={m => m.mode || 'other'}\n getOptionLabel={m => m.model_name}\n value={selectedModels}\n onChange={(_e, selected) =>\n setFormData({ ...formData, models: selected.map(m => m.model_name) })\n }\n renderOption={(props, m) => <li {...props}>{modelOption(m)}</li>}\n renderInput={params => (\n <TextField {...params} label=\"Models\" helperText=\"Leave empty to allow all models\" fullWidth />\n )}\n />\n )}\n\n <TextField\n label=\"Max Budget (USD)\"\n type=\"number\"\n value={formData.max_budget ?? ''}\n onChange={(e) =>\n setFormData({ ...formData, max_budget: e.target.value ? Number(e.target.value) : undefined })\n }\n required\n fullWidth\n />\n <TextField\n label=\"TPM Limit\"\n type=\"number\"\n value={formData.tpm_limit ?? ''}\n onChange={(e) =>\n setFormData({ ...formData, tpm_limit: e.target.value ? Number(e.target.value) : undefined })\n }\n fullWidth\n />\n <TextField\n label=\"RPM Limit\"\n type=\"number\"\n value={formData.rpm_limit ?? ''}\n onChange={(e) =>\n setFormData({ ...formData, rpm_limit: e.target.value ? Number(e.target.value) : undefined })\n }\n fullWidth\n />\n </Box>\n )}\n </DialogContent>\n <DialogActions>\n <Button onClick={handleCloseModal}>{newKeyValue ? 'Done' : 'Cancel'}</Button>\n {!newKeyValue && (\n <Button\n onClick={handleGenerate}\n variant=\"contained\"\n color=\"primary\"\n disabled={submitting}\n >\n {submitting ? <CircularProgress size={24} /> : 'Generate'}\n </Button>\n )}\n {newKeyValue && (\n <Button onClick={handleCloseModal} variant=\"contained\" color=\"success\">\n Done\n </Button>\n )}\n </DialogActions>\n </Dialog>\n\n {/* Edit dialog */}\n <Dialog open={!!editingKey} onClose={handleCloseEdit} maxWidth=\"sm\" fullWidth>\n <DialogTitle>Edit Key</DialogTitle>\n <DialogContent>\n {editingKey && (\n <Box display=\"flex\" flexDirection=\"column\" gap={2} mt={1}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n <code style={{ fontFamily: 'monospace', color: 'inherit' }}>{maskKey(editingKey.key)}</code>\n </Typography>\n <TextField\n label=\"Alias\"\n value={editForm.key_alias || ''}\n onChange={(e) => setEditForm({ ...editForm, key_alias: e.target.value })}\n fullWidth\n />\n\n {models.length > 0 && (\n <Autocomplete\n multiple\n options={models}\n groupBy={m => m.mode || 'other'}\n getOptionLabel={m => m.model_name}\n value={editSelectedModels}\n onChange={(_e, selected) =>\n setEditForm({ ...editForm, models: selected.map(m => m.model_name) })\n }\n renderOption={(props, m) => <li {...props}>{modelOption(m)}</li>}\n renderInput={params => (\n <TextField {...params} label=\"Models\" fullWidth />\n )}\n />\n )}\n\n <TextField\n label=\"Max Budget (USD)\"\n type=\"number\"\n value={editForm.max_budget ?? ''}\n onChange={(e) =>\n setEditForm({ ...editForm, max_budget: e.target.value ? Number(e.target.value) : undefined })\n }\n fullWidth\n />\n <TextField\n label=\"TPM Limit\"\n type=\"number\"\n value={editForm.tpm_limit ?? ''}\n onChange={(e) =>\n setEditForm({ ...editForm, tpm_limit: e.target.value ? Number(e.target.value) : undefined })\n }\n fullWidth\n />\n <TextField\n label=\"RPM Limit\"\n type=\"number\"\n value={editForm.rpm_limit ?? ''}\n onChange={(e) =>\n setEditForm({ ...editForm, rpm_limit: e.target.value ? Number(e.target.value) : undefined })\n }\n fullWidth\n />\n\n <Box mt={1} pt={2} borderTop=\"1px solid\" sx={{ borderColor: 'divider' }}>\n <Typography variant=\"caption\" color=\"text.secondary\" display=\"block\" mb={1}>\n Danger Zone\n </Typography>\n {!resetSpendConfirm ? (\n <Button\n size=\"small\"\n color=\"warning\"\n variant=\"outlined\"\n onClick={() => setResetSpendConfirm(true)}\n >\n Reset Spend to $0\n </Button>\n ) : (\n <Box display=\"flex\" alignItems=\"center\" gap={1} flexWrap=\"wrap\">\n <Typography variant=\"body2\" color=\"warning.main\">\n Zero out spend counter?\n </Typography>\n <Button\n size=\"small\"\n color=\"warning\"\n variant=\"contained\"\n disabled={resetSpendSubmitting}\n onClick={handleResetSpend}\n >\n {resetSpendSubmitting ? <CircularProgress size={16} /> : 'Confirm'}\n </Button>\n <Button size=\"small\" onClick={() => setResetSpendConfirm(false)}>\n Cancel\n </Button>\n </Box>\n )}\n </Box>\n </Box>\n )}\n </DialogContent>\n <DialogActions>\n <Button onClick={handleCloseEdit}>Cancel</Button>\n <Button onClick={handleUpdate} variant=\"contained\" color=\"primary\" disabled={editSubmitting}>\n {editSubmitting ? <CircularProgress size={24} /> : 'Save'}\n </Button>\n </DialogActions>\n </Dialog>\n\n {/* Rotate result dialog */}\n <Dialog open={!!rotatedKeyValue} onClose={() => setRotatedKeyValue(null)} maxWidth=\"sm\" fullWidth>\n <DialogTitle>Key Rotated</DialogTitle>\n <DialogContent>\n <Typography variant=\"body2\" color=\"text.secondary\" gutterBottom>\n The old secret is now invalid. Copy the new one \u2014 you won't see it again.\n </Typography>\n <Box\n display=\"flex\"\n alignItems=\"center\"\n gap={1}\n mt={2}\n p={2}\n sx={{ backgroundColor: 'action.hover', border: '1px solid', borderColor: 'divider', borderRadius: 1 }}\n >\n <Typography\n component=\"code\"\n sx={{ fontFamily: 'monospace', wordBreak: 'break-all', flex: 1 }}\n >\n {rotatedKeyValue}\n </Typography>\n <IconButton onClick={() => copyToClipboard(rotatedKeyValue!)}>\n <ContentCopy />\n </IconButton>\n </Box>\n </DialogContent>\n <DialogActions>\n <Button onClick={() => setRotatedKeyValue(null)} variant=\"contained\" color=\"success\">\n Done\n </Button>\n </DialogActions>\n </Dialog>\n\n {/* Delete confirmation dialog */}\n <Dialog open={!!deleteConfirmId} onClose={() => setDeleteConfirmId(null)} maxWidth=\"xs\" fullWidth>\n <DialogTitle>Revoke Key?</DialogTitle>\n <DialogContent>\n <Typography>\n This will permanently revoke the key. Any integrations using it will stop working immediately.\n </Typography>\n </DialogContent>\n <DialogActions>\n <Button onClick={() => setDeleteConfirmId(null)} disabled={deleteSubmitting}>\n Cancel\n </Button>\n <Button\n onClick={handleConfirmDelete}\n variant=\"contained\"\n color=\"error\"\n disabled={deleteSubmitting}\n >\n {deleteSubmitting ? <CircularProgress size={20} /> : 'Revoke'}\n </Button>\n </DialogActions>\n </Dialog>\n\n {/* Prune expired keys confirmation dialog */}\n <Dialog open={pruneConfirmCount !== null} onClose={() => setPruneConfirmCount(null)} maxWidth=\"xs\" fullWidth>\n <DialogTitle>Prune Expired Keys?</DialogTitle>\n <DialogContent>\n <Typography>\n This will permanently delete {pruneConfirmCount} expired key{pruneConfirmCount !== 1 ? 's' : ''} from LiteLLM.\n Any integrations using them will stop working immediately.\n </Typography>\n </DialogContent>\n <DialogActions>\n <Button onClick={() => setPruneConfirmCount(null)} disabled={pruneSubmitting}>\n Cancel\n </Button>\n <Button\n onClick={handlePruneExpired}\n variant=\"contained\"\n color=\"error\"\n disabled={pruneSubmitting}\n >\n {pruneSubmitting ? <CircularProgress size={20} /> : 'Prune'}\n </Button>\n </DialogActions>\n </Dialog>\n </>\n );\n};\n", "import React, { useMemo, useState } from 'react';\nimport {\n Paper,\n Box,\n Typography,\n FormControl,\n InputLabel,\n Select,\n MenuItem,\n Grid,\n Tabs,\n Tab,\n Table,\n TableBody,\n TableCell,\n TableContainer,\n TableHead,\n TableRow,\n Chip,\n LinearProgress,\n Skeleton,\n} from '@mui/material';\nimport {\n AreaChart,\n Area,\n BarChart,\n Bar,\n LineChart,\n Line,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n ResponsiveContainer,\n Legend,\n ReferenceLine,\n} from 'recharts';\nimport {\n DateRange,\n UsageMetrics,\n ModelInfo,\n UserInfo,\n UsageModelBreakdown,\n UsageKeyBreakdown,\n} from '../types';\n\ninterface UsageStatsProps {\n usage: UsageMetrics | null;\n models: ModelInfo[];\n dateRange: DateRange;\n onDateRangeChange: (range: DateRange) => void;\n loading: boolean;\n userInfo?: UserInfo;\n}\n\ntype DatePreset = 'today' | '24h' | '7d' | '30d';\ntype TabKey = 'costs' | 'models' | 'keys';\n\nconst TOP_N_MODELS = 6;\nconst PERIOD_LS_KEY = 'litellm_usage_period';\n\nconst MODEL_COLORS = [\n '#8884d8', '#82ca9d', '#ffc658', '#ff7300',\n '#0088fe', '#00C49F', '#FFBB28', '#FF8042',\n '#a4de6c', '#d0ed57',\n];\n\nfunction modelColor(model: string): string {\n let h = 5381;\n for (let i = 0; i < model.length; i++) h = ((h << 5) + h + model.charCodeAt(i)) >>> 0;\n return MODEL_COLORS[h % MODEL_COLORS.length];\n}\n\nconst fmtUsd = (n: number) => `$${(n ?? 0).toFixed(n < 1 ? 4 : 2)}`;\nconst fmtInt = (n: number) => (n ?? 0).toLocaleString();\nconst fmtPct = (n: number) => `${(n * 100).toFixed(1)}%`;\n\nconst KpiCard: React.FC<{ label: string; value: string; hint?: string }> = ({ label, value, hint }) => (\n <Paper variant=\"outlined\" sx={{ p: 2, height: '100%' }}>\n <Typography variant=\"caption\" color=\"text.secondary\">{label}</Typography>\n <Typography variant=\"h5\" sx={{ mt: 0.5 }}>{value}</Typography>\n {hint ? <Typography variant=\"caption\" color=\"text.secondary\">{hint}</Typography> : null}\n </Paper>\n);\n\nconst ChartSkeleton: React.FC<{ height?: number }> = ({ height = 260 }) => (\n <Skeleton variant=\"rectangular\" height={height} sx={{ borderRadius: 1 }} />\n);\n\nconst EmptyChart: React.FC<{ height?: number; message?: string }> = ({\n height = 260,\n message = 'No data for this period',\n}) => (\n <Box height={height} display=\"flex\" alignItems=\"center\" justifyContent=\"center\">\n <Typography color=\"text.secondary\" variant=\"body2\">{message}</Typography>\n </Box>\n);\n\nexport const UsageStats: React.FC<UsageStatsProps> = ({\n usage,\n models,\n dateRange,\n onDateRangeChange,\n loading,\n userInfo,\n}) => {\n const [selectedModel, setSelectedModel] = useState<string>('all');\n const [tab, setTab] = useState<TabKey>('costs');\n\n const selectedPreset = useMemo<DatePreset>(() => {\n if (dateRange.start.toDateString() === dateRange.end.toDateString()) return 'today';\n const diffMs = dateRange.end.getTime() - dateRange.start.getTime();\n const diffHours = diffMs / (1000 * 60 * 60);\n if (diffHours <= 26) return '24h';\n const diffDays = Math.ceil(diffMs / (1000 * 60 * 60 * 24));\n if (diffDays <= 7) return '7d';\n return '30d';\n }, [dateRange]);\n\n const handlePresetChange = (preset: DatePreset) => {\n const end = new Date();\n const start = new Date();\n if (preset === 'today') start.setHours(0, 0, 0, 0);\n else if (preset === '24h') start.setHours(start.getHours() - 24);\n else if (preset === '7d') start.setDate(start.getDate() - 7);\n else if (preset === '30d') start.setDate(start.getDate() - 30);\n try { localStorage.setItem(PERIOD_LS_KEY, preset); } catch { /* ignore */ }\n onDateRangeChange({ start, end });\n };\n\n // \u2500\u2500 daily_usage \u2192 base series \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const dailyData = useMemo(\n () =>\n (usage?.daily_usage ?? []).map(d => ({\n date: d.date,\n spend: d.spend,\n promptTokens: d.prompt_tokens,\n completionTokens: d.completion_tokens,\n totalTokens: d.total_tokens,\n apiRequests: d.api_requests,\n successfulRequests: d.successful_requests,\n failedRequests: d.failed_requests,\n })),\n [usage],\n );\n\n // \u2500\u2500 Cumulative spend per day \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const cumulativeData = useMemo(() => {\n let cum = 0;\n return dailyData.map(d => { cum += d.spend; return { date: d.date, cumulative: cum }; });\n }, [dailyData]);\n\n // \u2500\u2500 Success rate trend (days with requests only) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const successRateData = useMemo(\n () =>\n dailyData\n .filter(d => d.apiRequests > 0)\n .map(d => ({\n date: d.date,\n successRate: parseFloat(((d.successfulRequests / d.apiRequests) * 100).toFixed(1)),\n })),\n [dailyData],\n );\n\n // \u2500\u2500 Stacked spend by model per day \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const { modelSpendByDate, topModels: topSpendModels } = useMemo(() => {\n const rows = usage?.daily_by_model ?? [];\n const modelTotals: Record<string, number> = {};\n for (const r of rows) modelTotals[r.model] = (modelTotals[r.model] ?? 0) + r.spend;\n\n const top = Object.entries(modelTotals)\n .sort(([, a], [, b]) => b - a)\n .slice(0, TOP_N_MODELS)\n .map(([m]) => m);\n\n const dateMap: Record<string, Record<string, number>> = {};\n for (const r of rows) {\n if (!dateMap[r.date]) dateMap[r.date] = {};\n const bucket = top.includes(r.model) ? r.model : 'Other';\n dateMap[r.date][bucket] = (dateMap[r.date][bucket] ?? 0) + r.spend;\n }\n\n const sorted = Object.entries(dateMap)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([date, m]) => ({ date, ...m }));\n\n const hasOther = sorted.some(r => (r as any).Other > 0);\n return { modelSpendByDate: sorted, topModels: hasOther ? [...top, 'Other'] : top };\n }, [usage]);\n\n // \u2500\u2500 Model breakdown rows \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const modelRows = useMemo(() => {\n const entries = Object.entries<UsageModelBreakdown>(usage?.usage_by_model ?? {}).map(([model, d]) => ({\n model,\n spend: d.total_spend,\n promptTokens: d.prompt_tokens,\n completionTokens: d.completion_tokens,\n totalTokens: d.total_tokens,\n apiRequests: d.api_requests,\n successfulRequests: d.successful_requests,\n failedRequests: d.failed_requests,\n successRate: d.api_requests > 0 ? d.successful_requests / d.api_requests : 0,\n }));\n return selectedModel === 'all' ? entries : entries.filter(e => e.model === selectedModel);\n }, [usage, selectedModel]);\n\n // top-models horizontal bar (sorted by spend)\n const topModelSpendBars = useMemo(\n () => [...modelRows].sort((a, b) => b.spend - a.spend).slice(0, 10),\n [modelRows],\n );\n\n // \u2500\u2500 Key breakdown rows \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const keyRows = useMemo(\n () =>\n Object.entries<UsageKeyBreakdown>(usage?.usage_by_key ?? {}).map(([keyHash, d]) => ({\n keyHash,\n keyAlias: d.key_alias ?? keyHash.slice(0, 8),\n teamId: d.team_id ?? null,\n models: d.models,\n spend: d.total_spend,\n totalTokens: d.total_tokens,\n promptTokens: d.prompt_tokens,\n completionTokens: d.completion_tokens,\n apiRequests: d.api_requests,\n successfulRequests: d.successful_requests,\n failedRequests: d.failed_requests,\n successRate: d.api_requests > 0 ? d.successful_requests / d.api_requests : 0,\n })),\n [usage],\n );\n\n const topKeySpendBars = useMemo(\n () => [...keyRows].sort((a, b) => b.spend - a.spend).slice(0, 10),\n [keyRows],\n );\n\n const totalRequests = usage?.api_requests ?? 0;\n const overallSuccessRate = totalRequests > 0 ? (usage?.successful_requests ?? 0) / totalRequests : 0;\n const maxBudget = userInfo?.max_budget ?? 0;\n const totalCumSpend = cumulativeData[cumulativeData.length - 1]?.cumulative ?? 0;\n\n return (\n <Paper sx={{ p: 2 }}>\n {/* \u2500\u2500 Header \u2500\u2500 */}\n <Box display=\"flex\" justifyContent=\"space-between\" alignItems=\"center\" mb={2} flexWrap=\"wrap\" gap={2}>\n <Typography variant=\"h6\">Usage Analytics</Typography>\n <Box display=\"flex\" gap={2} alignItems=\"center\" flexWrap=\"wrap\">\n <FormControl size=\"small\" sx={{ minWidth: 140 }}>\n <InputLabel>Period</InputLabel>\n <Select\n value={selectedPreset}\n label=\"Period\"\n onChange={e => handlePresetChange(e.target.value as DatePreset)}\n >\n <MenuItem value=\"today\">Today</MenuItem>\n <MenuItem value=\"24h\">Last 24h</MenuItem>\n <MenuItem value=\"7d\">Last 7 days</MenuItem>\n <MenuItem value=\"30d\">Last 30 days</MenuItem>\n </Select>\n </FormControl>\n {tab === 'models' && (\n <FormControl size=\"small\" sx={{ minWidth: 180 }}>\n <InputLabel>Model</InputLabel>\n <Select\n value={selectedModel}\n label=\"Model\"\n onChange={e => setSelectedModel(e.target.value)}\n >\n <MenuItem value=\"all\">All Models</MenuItem>\n {models.map(m => (\n <MenuItem key={m.model_name} value={m.model_name}>\n {m.model_name}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n )}\n </Box>\n </Box>\n\n {/* \u2500\u2500 KPI row \u2500\u2500 */}\n <Grid container spacing={2} sx={{ mb: 2 }}>\n <Grid item xs={6} sm={3}>\n {loading ? <ChartSkeleton height={80} /> : <KpiCard label=\"Total Spend\" value={fmtUsd(usage?.total_spend ?? 0)} />}\n </Grid>\n <Grid item xs={6} sm={3}>\n {loading ? <ChartSkeleton height={80} /> : (\n <KpiCard label=\"Total Requests\" value={fmtInt(totalRequests)} hint={`${fmtInt(usage?.failed_requests ?? 0)} failed`} />\n )}\n </Grid>\n <Grid item xs={6} sm={3}>\n {loading ? <ChartSkeleton height={80} /> : (\n <KpiCard label=\"Success Rate\" value={totalRequests > 0 ? fmtPct(overallSuccessRate) : '\u2014'} />\n )}\n </Grid>\n <Grid item xs={6} sm={3}>\n {loading ? <ChartSkeleton height={80} /> : (\n <KpiCard\n label=\"Total Tokens\"\n value={fmtInt(usage?.total_tokens ?? 0)}\n hint={`${fmtInt(usage?.prompt_tokens ?? 0)} in \u00B7 ${fmtInt(usage?.completion_tokens ?? 0)} out`}\n />\n )}\n </Grid>\n </Grid>\n\n <Tabs value={tab} onChange={(_, v) => setTab(v as TabKey)} sx={{ mb: 2 }}>\n <Tab value=\"costs\" label=\"Costs\" />\n <Tab value=\"models\" label=\"Model Activity\" />\n <Tab value=\"keys\" label=\"Key Activity\" />\n </Tabs>\n\n {/* \u2550\u2550 COSTS TAB \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */}\n {tab === 'costs' && (\n <Grid container spacing={3}>\n {/* Daily Spend by Model */}\n <Grid item xs={12} md={6}>\n <Typography variant=\"subtitle2\" color=\"text.secondary\" gutterBottom>\n Daily Spend by Model\n </Typography>\n {loading ? <ChartSkeleton /> : modelSpendByDate.length === 0 ? <EmptyChart /> : (\n <Box height={260}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <AreaChart data={modelSpendByDate}>\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis dataKey=\"date\" tick={{ fontSize: 12 }} />\n <YAxis tick={{ fontSize: 12 }} tickFormatter={v => `$${v.toFixed(2)}`} />\n <Tooltip formatter={(v: number) => [`$${v.toFixed(4)}`, undefined]} />\n <Legend />\n {topSpendModels.map(m => (\n <Area\n key={m}\n type=\"monotone\"\n dataKey={m}\n stackId=\"spend\"\n stroke={modelColor(m)}\n fill={modelColor(m)}\n fillOpacity={0.6}\n />\n ))}\n </AreaChart>\n </ResponsiveContainer>\n </Box>\n )}\n </Grid>\n\n {/* Token Usage Trend */}\n <Grid item xs={12} md={6}>\n <Typography variant=\"subtitle2\" color=\"text.secondary\" gutterBottom>\n Daily Token Usage\n </Typography>\n {loading ? <ChartSkeleton /> : dailyData.length === 0 ? <EmptyChart /> : (\n <Box height={260}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <AreaChart data={dailyData}>\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis dataKey=\"date\" tick={{ fontSize: 12 }} />\n <YAxis tick={{ fontSize: 12 }} tickFormatter={fmtInt} />\n <Tooltip formatter={(v: number) => [fmtInt(v), undefined]} />\n <Legend />\n <Area type=\"monotone\" dataKey=\"promptTokens\" name=\"Input (prompt)\" stackId=\"tok\" stroke=\"#8884d8\" fill=\"#8884d8\" fillOpacity={0.5} />\n <Area type=\"monotone\" dataKey=\"completionTokens\" name=\"Output (completion)\" stackId=\"tok\" stroke=\"#82ca9d\" fill=\"#82ca9d\" fillOpacity={0.5} />\n </AreaChart>\n </ResponsiveContainer>\n </Box>\n )}\n </Grid>\n\n {/* Daily Requests */}\n <Grid item xs={12} md={6}>\n <Typography variant=\"subtitle2\" color=\"text.secondary\" gutterBottom>\n Daily Requests\n </Typography>\n {loading ? <ChartSkeleton /> : dailyData.length === 0 ? <EmptyChart /> : (\n <Box height={260}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart data={dailyData}>\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis dataKey=\"date\" tick={{ fontSize: 12 }} />\n <YAxis tick={{ fontSize: 12 }} />\n <Tooltip />\n <Legend />\n <Bar dataKey=\"successfulRequests\" name=\"Successful\" fill=\"#82ca9d\" stackId=\"r\" />\n <Bar dataKey=\"failedRequests\" name=\"Failed\" fill=\"#e57373\" stackId=\"r\" />\n </BarChart>\n </ResponsiveContainer>\n </Box>\n )}\n </Grid>\n\n {/* Success Rate Trend */}\n <Grid item xs={12} md={6}>\n <Typography variant=\"subtitle2\" color=\"text.secondary\" gutterBottom>\n Daily Success Rate\n </Typography>\n {loading ? <ChartSkeleton /> : successRateData.length === 0 ? <EmptyChart /> : (\n <Box height={260}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <LineChart data={successRateData}>\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis dataKey=\"date\" tick={{ fontSize: 12 }} />\n <YAxis domain={[0, 100]} tick={{ fontSize: 12 }} tickFormatter={v => `${v}%`} />\n <Tooltip formatter={(v: number) => [`${v}%`, 'Success rate']} />\n <ReferenceLine y={100} stroke=\"#82ca9d\" strokeDasharray=\"4 2\" />\n <Line type=\"monotone\" dataKey=\"successRate\" name=\"Success rate\" stroke=\"#8884d8\" dot={{ r: 3 }} />\n </LineChart>\n </ResponsiveContainer>\n </Box>\n )}\n </Grid>\n\n {/* Cumulative Spend \u2014 only when max_budget is set */}\n {(maxBudget > 0 || cumulativeData.length > 0) && (\n <Grid item xs={12}>\n <Typography variant=\"subtitle2\" color=\"text.secondary\" gutterBottom>\n Cumulative Spend{maxBudget > 0 ? ` vs Budget (${fmtUsd(maxBudget)})` : ''}\n {maxBudget > 0 && (\n <Typography component=\"span\" variant=\"caption\" color=\"text.secondary\" sx={{ ml: 1 }}>\n {fmtUsd(totalCumSpend)} used \u00B7 {fmtUsd(Math.max(0, maxBudget - totalCumSpend))} remaining\n </Typography>\n )}\n </Typography>\n {loading ? <ChartSkeleton height={180} /> : cumulativeData.length === 0 ? <EmptyChart height={180} /> : (\n <Box height={180}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <AreaChart data={cumulativeData}>\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis dataKey=\"date\" tick={{ fontSize: 12 }} />\n <YAxis tick={{ fontSize: 12 }} tickFormatter={v => `$${v.toFixed(2)}`} />\n <Tooltip formatter={(v: number) => [`$${v.toFixed(4)}`, 'Cumulative spend']} />\n {maxBudget > 0 && (\n <ReferenceLine y={maxBudget} stroke=\"#e57373\" strokeDasharray=\"6 3\" label={{ value: `Budget ${fmtUsd(maxBudget)}`, position: 'insideTopRight', fontSize: 11 }} />\n )}\n <Area type=\"monotone\" dataKey=\"cumulative\" name=\"Cumulative spend\" stroke=\"#ffc658\" fill=\"#ffc658\" fillOpacity={0.3} />\n </AreaChart>\n </ResponsiveContainer>\n </Box>\n )}\n </Grid>\n )}\n </Grid>\n )}\n\n {/* \u2550\u2550 MODELS TAB \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */}\n {tab === 'models' && (\n <Grid container spacing={3}>\n {/* Top models spend horizontal bar */}\n <Grid item xs={12}>\n <Typography variant=\"subtitle2\" color=\"text.secondary\" gutterBottom>\n Spend by Model\n </Typography>\n {loading ? <ChartSkeleton /> : topModelSpendBars.length === 0 ? <EmptyChart /> : (\n <Box height={Math.max(200, topModelSpendBars.length * 36)}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart data={topModelSpendBars} layout=\"vertical\" margin={{ left: 20 }}>\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis type=\"number\" tick={{ fontSize: 12 }} tickFormatter={v => `$${v.toFixed(2)}`} />\n <YAxis type=\"category\" dataKey=\"model\" tick={{ fontSize: 11 }} width={200} />\n <Tooltip formatter={(v: number) => [fmtUsd(v), 'Spend']} />\n <Bar dataKey=\"spend\" name=\"Spend\" radius={[0, 4, 4, 0]}>\n {topModelSpendBars.map(r => (\n <rect key={r.model} fill={modelColor(r.model)} />\n ))}\n </Bar>\n </BarChart>\n </ResponsiveContainer>\n </Box>\n )}\n </Grid>\n\n {/* Tokens by model stacked bar */}\n <Grid item xs={12}>\n <Typography variant=\"subtitle2\" color=\"text.secondary\" gutterBottom>\n Tokens by Model\n </Typography>\n {loading ? <ChartSkeleton /> : modelRows.length === 0 ? <EmptyChart /> : (\n <Box height={260}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart data={modelRows}>\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis dataKey=\"model\" tick={{ fontSize: 10 }} interval={0} angle={-15} textAnchor=\"end\" height={60} />\n <YAxis tick={{ fontSize: 12 }} />\n <Tooltip />\n <Legend />\n <Bar dataKey=\"promptTokens\" name=\"Prompt\" fill=\"#8884d8\" stackId=\"t\" />\n <Bar dataKey=\"completionTokens\" name=\"Completion\" fill=\"#82ca9d\" stackId=\"t\" />\n </BarChart>\n </ResponsiveContainer>\n </Box>\n )}\n </Grid>\n\n {/* Model table */}\n <Grid item xs={12}>\n <TableContainer component={Paper} variant=\"outlined\">\n <Table size=\"small\">\n <TableHead>\n <TableRow>\n <TableCell>Model</TableCell>\n <TableCell align=\"right\">Spend</TableCell>\n <TableCell align=\"right\">Requests</TableCell>\n <TableCell align=\"right\">Success</TableCell>\n <TableCell align=\"right\">Failed</TableCell>\n <TableCell align=\"right\">Prompt</TableCell>\n <TableCell align=\"right\">Completion</TableCell>\n <TableCell sx={{ minWidth: 120 }}>Success rate</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {loading ? (\n <TableRow><TableCell colSpan={8}><LinearProgress /></TableCell></TableRow>\n ) : modelRows.length === 0 ? (\n <TableRow><TableCell colSpan={8} align=\"center\">No model activity</TableCell></TableRow>\n ) : [...modelRows]\n .sort((a, b) => b.spend - a.spend || b.totalTokens - a.totalTokens)\n .map(r => (\n <TableRow key={r.model}>\n <TableCell>\n <Box display=\"flex\" alignItems=\"center\" gap={0.75}>\n <Box sx={{ width: 10, height: 10, borderRadius: '50%', bgcolor: modelColor(r.model), flexShrink: 0 }} />\n {r.model}\n </Box>\n </TableCell>\n <TableCell align=\"right\">{fmtUsd(r.spend)}</TableCell>\n <TableCell align=\"right\">{fmtInt(r.apiRequests)}</TableCell>\n <TableCell align=\"right\">{fmtInt(r.successfulRequests)}</TableCell>\n <TableCell align=\"right\">{fmtInt(r.failedRequests)}</TableCell>\n <TableCell align=\"right\">{fmtInt(r.promptTokens)}</TableCell>\n <TableCell align=\"right\">{fmtInt(r.completionTokens)}</TableCell>\n <TableCell>\n {r.apiRequests > 0 ? (\n <Box display=\"flex\" alignItems=\"center\" gap={1}>\n <LinearProgress\n variant=\"determinate\"\n value={r.successRate * 100}\n sx={{ flex: 1, height: 6, borderRadius: 3 }}\n />\n <Typography variant=\"caption\">{fmtPct(r.successRate)}</Typography>\n </Box>\n ) : '\u2014'}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </TableContainer>\n </Grid>\n </Grid>\n )}\n\n {/* \u2550\u2550 KEYS TAB \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */}\n {tab === 'keys' && (\n <Grid container spacing={3}>\n {/* Top keys spend horizontal bar */}\n {(loading || topKeySpendBars.length > 0) && (\n <Grid item xs={12}>\n <Typography variant=\"subtitle2\" color=\"text.secondary\" gutterBottom>\n Spend by Key\n </Typography>\n {loading ? <ChartSkeleton /> : (\n <Box height={Math.max(160, topKeySpendBars.length * 36)}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart data={topKeySpendBars} layout=\"vertical\" margin={{ left: 20 }}>\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis type=\"number\" tick={{ fontSize: 12 }} tickFormatter={v => `$${v.toFixed(2)}`} />\n <YAxis type=\"category\" dataKey=\"keyAlias\" tick={{ fontSize: 11 }} width={160} />\n <Tooltip formatter={(v: number) => [fmtUsd(v), 'Spend']} />\n <Bar dataKey=\"spend\" name=\"Spend\" fill=\"#8884d8\" radius={[0, 4, 4, 0]} />\n </BarChart>\n </ResponsiveContainer>\n </Box>\n )}\n </Grid>\n )}\n\n {/* Keys table */}\n <Grid item xs={12}>\n <TableContainer component={Paper} variant=\"outlined\">\n <Table size=\"small\">\n <TableHead>\n <TableRow>\n <TableCell>Key</TableCell>\n <TableCell>Models</TableCell>\n <TableCell align=\"right\">Spend</TableCell>\n <TableCell align=\"right\">Requests</TableCell>\n <TableCell align=\"right\">Tokens</TableCell>\n <TableCell align=\"right\">Failed</TableCell>\n <TableCell sx={{ minWidth: 120 }}>Success rate</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {loading ? (\n <TableRow><TableCell colSpan={7}><LinearProgress /></TableCell></TableRow>\n ) : keyRows.length === 0 ? (\n <TableRow><TableCell colSpan={7} align=\"center\">No key activity</TableCell></TableRow>\n ) : [...keyRows]\n .sort((a, b) => b.spend - a.spend || b.apiRequests - a.apiRequests)\n .map(r => (\n <TableRow key={r.keyHash}>\n <TableCell>\n <Typography variant=\"body2\">{r.keyAlias}</Typography>\n {r.teamId ? (\n <Typography variant=\"caption\" color=\"text.secondary\">team: {r.teamId}</Typography>\n ) : null}\n </TableCell>\n <TableCell>\n <Box display=\"flex\" gap={0.5} flexWrap=\"wrap\">\n {r.models.map(m => (\n <Chip key={m} label={m} size=\"small\" variant=\"outlined\" />\n ))}\n </Box>\n </TableCell>\n <TableCell align=\"right\">{fmtUsd(r.spend)}</TableCell>\n <TableCell align=\"right\">{fmtInt(r.apiRequests)}</TableCell>\n <TableCell align=\"right\">{fmtInt(r.totalTokens)}</TableCell>\n <TableCell align=\"right\">{fmtInt(r.failedRequests)}</TableCell>\n <TableCell>\n {r.apiRequests > 0 ? (\n <Box display=\"flex\" alignItems=\"center\" gap={1}>\n <LinearProgress\n variant=\"determinate\"\n value={r.successRate * 100}\n sx={{ flex: 1, height: 6, borderRadius: 3 }}\n />\n <Typography variant=\"caption\">{fmtPct(r.successRate)}</Typography>\n </Box>\n ) : '\u2014'}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </TableContainer>\n </Grid>\n </Grid>\n )}\n </Paper>\n );\n};\n", "import React, { useState } from 'react';\nimport {\n Paper,\n Box,\n Typography,\n LinearProgress,\n Chip,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableRow,\n TableContainer,\n Collapse,\n IconButton,\n CircularProgress,\n} from '@mui/material';\nimport { ExpandMore, ExpandLess, Group } from '@mui/icons-material';\nimport {\n AreaChart,\n Area,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n ResponsiveContainer,\n} from 'recharts';\nimport { TeamInfo, UsageMetrics, DateRange } from '../types';\n\ninterface TeamCardProps {\n team: TeamInfo;\n usage: UsageMetrics | null;\n usageLoading: boolean;\n}\n\nconst TeamCard: React.FC<TeamCardProps> = ({ team, usage, usageLoading }) => {\n const [expanded, setExpanded] = useState(false);\n\n const budget = team.max_budget ?? 0;\n const spend = team.spend ?? 0;\n const budgetPct = budget > 0 ? Math.min((spend / budget) * 100, 100) : 0;\n const isOver = budget > 0 && spend >= budget;\n const isNear = budget > 0 && spend >= budget * 0.8 && !isOver;\n\n const dailyData = usage?.daily_usage?.map(d => ({ date: d.date, spend: d.spend })) ?? [];\n\n return (\n <Paper variant=\"outlined\" sx={{ p: 2, mb: 2 }}>\n <Box display=\"flex\" alignItems=\"center\" gap={1}>\n <Group color=\"action\" />\n <Box flexGrow={1}>\n <Typography variant=\"subtitle1\" fontWeight={600}>\n {team.team_alias ?? team.team_id}\n </Typography>\n {team.models?.length ? (\n <Box display=\"flex\" gap={0.5} flexWrap=\"wrap\" mt={0.5}>\n {team.models.map(m => (\n <Chip key={m} label={m} size=\"small\" variant=\"outlined\" />\n ))}\n </Box>\n ) : (\n <Typography variant=\"caption\" color=\"text.secondary\">All models</Typography>\n )}\n </Box>\n <IconButton size=\"small\" onClick={() => setExpanded(e => !e)}>\n {expanded ? <ExpandLess /> : <ExpandMore />}\n </IconButton>\n </Box>\n\n {budget > 0 && (\n <Box mt={1.5}>\n <Box display=\"flex\" justifyContent=\"space-between\" mb={0.5}>\n <Typography variant=\"body2\">\n ${spend.toFixed(2)} / ${budget.toFixed(2)}\n </Typography>\n {isOver && <Chip label=\"Over Budget\" size=\"small\" color=\"error\" />}\n {isNear && <Chip label=\"Near Limit\" size=\"small\" color=\"warning\" />}\n </Box>\n <LinearProgress\n variant=\"determinate\"\n value={budgetPct}\n color={isOver ? 'error' : isNear ? 'warning' : 'primary'}\n sx={{ height: 6, borderRadius: 1 }}\n />\n </Box>\n )}\n\n <Collapse in={expanded}>\n <Box mt={2}>\n {usageLoading ? (\n <Box display=\"flex\" justifyContent=\"center\" p={2}>\n <CircularProgress size={24} />\n </Box>\n ) : dailyData.length > 0 ? (\n <>\n <Typography variant=\"subtitle2\" color=\"text.secondary\" gutterBottom>\n Daily Spend\n </Typography>\n <Box height={160}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <AreaChart data={dailyData}>\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis dataKey=\"date\" tick={{ fontSize: 11 }} />\n <YAxis tick={{ fontSize: 11 }} tickFormatter={v => `$${v.toFixed(2)}`} />\n <Tooltip formatter={(v: number) => [`$${v.toFixed(4)}`, 'Spend']} />\n <Area type=\"monotone\" dataKey=\"spend\" stroke=\"#8884d8\" fill=\"#8884d8\" fillOpacity={0.3} />\n </AreaChart>\n </ResponsiveContainer>\n </Box>\n </>\n ) : null}\n\n {team.members_with_roles?.length ? (\n <Box mt={2}>\n <Typography variant=\"subtitle2\" color=\"text.secondary\" gutterBottom>\n Members\n </Typography>\n <TableContainer>\n <Table size=\"small\">\n <TableHead>\n <TableRow>\n <TableCell>User</TableCell>\n <TableCell>Role</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {team.members_with_roles.map(m => (\n <TableRow key={m.user_id}>\n <TableCell sx={{ fontFamily: 'monospace', fontSize: 12 }}>{m.user_id}</TableCell>\n <TableCell>\n <Chip\n label={m.role}\n size=\"small\"\n color={m.role === 'admin' ? 'primary' : 'default'}\n />\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </TableContainer>\n </Box>\n ) : null}\n </Box>\n </Collapse>\n </Paper>\n );\n};\n\ninterface TeamUsageProps {\n teams: TeamInfo[];\n loading: boolean;\n dateRange: DateRange;\n getTeamUsage: (teamId: string) => UsageMetrics | null;\n getTeamUsageLoading: (teamId: string) => boolean;\n}\n\nexport const TeamUsage: React.FC<TeamUsageProps> = ({\n teams,\n loading,\n getTeamUsage,\n getTeamUsageLoading,\n}) => {\n if (loading) {\n return (\n <Paper sx={{ p: 2 }}>\n <LinearProgress />\n </Paper>\n );\n }\n\n if (!teams.length) {\n return (\n <Paper sx={{ p: 2 }}>\n <Box display=\"flex\" alignItems=\"center\" gap={1}>\n <Group color=\"disabled\" />\n <Typography color=\"text.secondary\" variant=\"body2\">\n No team membership found in LiteLLM for this account.\n </Typography>\n </Box>\n </Paper>\n );\n }\n\n return (\n <Box>\n <Typography variant=\"h6\" mb={1}>Teams</Typography>\n {teams.map(team => (\n <TeamCard\n key={team.team_id}\n team={team}\n usage={getTeamUsage(team.team_id)}\n usageLoading={getTeamUsageLoading(team.team_id)}\n />\n ))}\n </Box>\n );\n};\n", "import React, { useState, useCallback } from 'react';\nimport {\n Paper,\n Box,\n Typography,\n Table,\n TableBody,\n TableCell,\n TableContainer,\n TableHead,\n TableRow,\n TablePagination,\n TextField,\n MenuItem,\n Chip,\n CircularProgress,\n Collapse,\n IconButton,\n Alert,\n} from '@mui/material';\nimport { KeyboardArrowDown, KeyboardArrowUp } from '@mui/icons-material';\nimport { useAsync } from 'react-use';\nimport { LiteLlmApiInterface } from '../api';\nimport { AuditLogEntry, AuditLogsParams } from '../types';\n\ninterface AuditLogProps {\n api: LiteLlmApiInterface;\n}\n\nconst ACTION_COLORS: Record<string, 'success' | 'error' | 'warning' | 'info' | 'default'> = {\n created: 'success',\n deleted: 'error',\n updated: 'warning',\n blocked: 'error',\n unblocked: 'success',\n};\n\nfunction actionColor(action?: string): 'success' | 'error' | 'warning' | 'info' | 'default' {\n if (!action) return 'default';\n for (const [key, color] of Object.entries(ACTION_COLORS)) {\n if (action.toLowerCase().includes(key)) return color;\n }\n return 'info';\n}\n\nfunction formatDateTime(iso: string): string {\n try {\n return new Date(iso).toLocaleString();\n } catch {\n return iso;\n }\n}\n\nconst DetailRow: React.FC<{ entry: AuditLogEntry }> = ({ entry }) => {\n const [open, setOpen] = useState(false);\n const hasDetail = entry.before_value || entry.updated_values;\n\n return (\n <>\n <TableRow hover>\n <TableCell sx={{ width: 40, pr: 0 }}>\n {hasDetail && (\n <IconButton size=\"small\" onClick={() => setOpen(o => !o)}>\n {open ? <KeyboardArrowUp fontSize=\"small\" /> : <KeyboardArrowDown fontSize=\"small\" />}\n </IconButton>\n )}\n </TableCell>\n <TableCell sx={{ whiteSpace: 'nowrap' }}>{formatDateTime(entry.updated_at)}</TableCell>\n <TableCell>\n {entry.action && (\n <Chip label={entry.action} color={actionColor(entry.action)} size=\"small\" />\n )}\n </TableCell>\n <TableCell>{entry.table_name ?? '-'}</TableCell>\n <TableCell>\n <Typography variant=\"body2\" component=\"code\" sx={{ fontFamily: 'monospace', fontSize: '0.75rem' }}>\n {entry.object_id ? entry.object_id.slice(0, 20) + (entry.object_id.length > 20 ? '\u2026' : '') : '-'}\n </Typography>\n </TableCell>\n <TableCell>{entry.changed_by ?? '-'}</TableCell>\n </TableRow>\n {hasDetail && (\n <TableRow>\n <TableCell colSpan={6} sx={{ py: 0 }}>\n <Collapse in={open} unmountOnExit>\n <Box p={2} display=\"flex\" gap={2} flexWrap=\"wrap\">\n {entry.before_value && (\n <Box flex={1} minWidth={200}>\n <Typography variant=\"caption\" color=\"text.secondary\" display=\"block\" mb={0.5}>Before</Typography>\n <Typography component=\"pre\" variant=\"caption\" sx={{ fontFamily: 'monospace', whiteSpace: 'pre-wrap', wordBreak: 'break-all' }}>\n {JSON.stringify(entry.before_value, null, 2)}\n </Typography>\n </Box>\n )}\n {entry.updated_values && (\n <Box flex={1} minWidth={200}>\n <Typography variant=\"caption\" color=\"text.secondary\" display=\"block\" mb={0.5}>After</Typography>\n <Typography component=\"pre\" variant=\"caption\" sx={{ fontFamily: 'monospace', whiteSpace: 'pre-wrap', wordBreak: 'break-all' }}>\n {JSON.stringify(entry.updated_values, null, 2)}\n </Typography>\n </Box>\n )}\n </Box>\n </Collapse>\n </TableCell>\n </TableRow>\n )}\n </>\n );\n};\n\nexport const AuditLog: React.FC<AuditLogProps> = ({ api }) => {\n const [page, setPage] = useState(0);\n const [pageSize, setPageSize] = useState(25);\n const [filters, setFilters] = useState<Pick<AuditLogsParams, 'action' | 'table_name' | 'changed_by'>>({});\n\n const fetchParams: AuditLogsParams = useCallback(\n () => ({ page: page + 1, page_size: pageSize, ...filters }),\n [page, pageSize, filters],\n )();\n\n const { value, loading, error } = useAsync(\n () => api.getAuditLogs(fetchParams),\n [api, fetchParams],\n );\n\n const entries: AuditLogEntry[] = value?.audit_logs ?? [];\n const total = value?.total ?? 0;\n\n return (\n <Paper>\n <Box p={2} display=\"flex\" gap={2} flexWrap=\"wrap\" alignItems=\"center\">\n <Typography variant=\"h6\" sx={{ flex: '0 0 auto', mr: 1 }}>Audit Log</Typography>\n <TextField\n size=\"small\"\n label=\"Action\"\n select\n value={filters.action ?? ''}\n onChange={e => { setFilters(f => ({ ...f, action: e.target.value || undefined })); setPage(0); }}\n sx={{ minWidth: 160 }}\n >\n <MenuItem value=\"\">All actions</MenuItem>\n <MenuItem value=\"created\">Created</MenuItem>\n <MenuItem value=\"updated\">Updated</MenuItem>\n <MenuItem value=\"deleted\">Deleted</MenuItem>\n <MenuItem value=\"blocked\">Blocked</MenuItem>\n </TextField>\n <TextField\n size=\"small\"\n label=\"Table\"\n select\n value={filters.table_name ?? ''}\n onChange={e => { setFilters(f => ({ ...f, table_name: e.target.value || undefined })); setPage(0); }}\n sx={{ minWidth: 160 }}\n >\n <MenuItem value=\"\">All tables</MenuItem>\n <MenuItem value=\"LiteLLM_VerificationToken\">Key</MenuItem>\n <MenuItem value=\"LiteLLM_TeamTable\">Team</MenuItem>\n <MenuItem value=\"LiteLLM_UserTable\">User</MenuItem>\n </TextField>\n <TextField\n size=\"small\"\n label=\"Changed by\"\n value={filters.changed_by ?? ''}\n onChange={e => { setFilters(f => ({ ...f, changed_by: e.target.value || undefined })); setPage(0); }}\n sx={{ minWidth: 200 }}\n />\n </Box>\n\n {error && (\n <Box px={2} pb={2}>\n <Alert severity=\"error\">{error.message}</Alert>\n </Box>\n )}\n\n <TableContainer>\n <Table size=\"small\">\n <TableHead>\n <TableRow>\n <TableCell sx={{ width: 40 }} />\n <TableCell>Time</TableCell>\n <TableCell>Action</TableCell>\n <TableCell>Table</TableCell>\n <TableCell>Object ID</TableCell>\n <TableCell>Changed By</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {loading ? (\n <TableRow>\n <TableCell colSpan={6} align=\"center\" sx={{ py: 4 }}>\n <CircularProgress size={24} />\n </TableCell>\n </TableRow>\n ) : entries.length === 0 ? (\n <TableRow>\n <TableCell colSpan={6} align=\"center\" sx={{ py: 4 }}>\n <Typography color=\"text.secondary\">No audit events found</Typography>\n </TableCell>\n </TableRow>\n ) : (\n entries.map(entry => <DetailRow key={entry.id} entry={entry} />)\n )}\n </TableBody>\n </Table>\n </TableContainer>\n\n <TablePagination\n component=\"div\"\n count={total}\n page={page}\n onPageChange={(_, p) => setPage(p)}\n rowsPerPage={pageSize}\n onRowsPerPageChange={e => { setPageSize(Number(e.target.value)); setPage(0); }}\n rowsPerPageOptions={[10, 25, 50]}\n />\n </Paper>\n );\n};\n", "import React, { useState, useCallback, useMemo } from 'react';\nimport { Box, Snackbar, Alert, CircularProgress, Typography, Paper, Tabs, Tab } from '@mui/material';\nimport { useAsync, useAsyncRetry } from 'react-use';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { DashboardHeader } from './DashboardHeader';\nimport { KeysTable } from './KeysTable';\nimport { UsageStats } from './UsageStats';\nimport { TeamUsage } from './TeamUsage';\nimport { AuditLog } from './AuditLog';\nimport { liteLlmApiRef } from '../api';\nimport { DateRange, GenerateKeyRequest, GenerateKeyResponse, UpdateKeyRequest, UsageMetrics } from '../types';\n\nconst PERIOD_LS_KEY = 'litellm_usage_period';\n\nfunction initDateRange(): DateRange {\n let preset = '7d';\n try { preset = localStorage.getItem(PERIOD_LS_KEY) ?? '7d'; } catch { /* ignore */ }\n const end = new Date();\n const start = new Date();\n if (preset === 'today') start.setHours(0, 0, 0, 0);\n else if (preset === '24h') start.setHours(start.getHours() - 24);\n else if (preset === '30d') start.setDate(start.getDate() - 30);\n else start.setDate(start.getDate() - 7);\n return { start, end };\n}\n\nexport const LiteLLMPage: React.FC = () => {\n const api = useApi(liteLlmApiRef);\n\n const [dateRange, setDateRange] = useState<DateRange>(initDateRange);\n const [activeTab, setActiveTab] = useState<'overview' | 'keys' | 'teams' | 'audit'>('overview');\n\n const [snackbar, setSnackbar] = useState<{ message: string; severity: 'success' | 'warning' | 'error' } | null>(null);\n\n // Team usage cache: teamId -> UsageMetrics\n const [teamUsageCache, setTeamUsageCache] = useState<Record<string, UsageMetrics | null>>({});\n const [teamUsageLoading, setTeamUsageLoading] = useState<Record<string, boolean>>({});\n\n const { value: userInfo, loading: userLoading, error: userError } = useAsync(\n () => api.getUserInfo(),\n [api],\n );\n\n const { value: keys, loading: keysLoading, retry: refreshKeys } = useAsyncRetry(\n async () => {\n try {\n return await api.listKeys();\n } catch (e: any) {\n setSnackbar({ message: `Failed to load keys: ${e.message}`, severity: 'error' });\n return [];\n }\n },\n [api],\n );\n\n const { value: allModels, loading: modelsLoading } = useAsync(\n () => api.listModels().catch(() => []),\n [api],\n );\n\n const { value: allTeams, loading: teamsLoading } = useAsync(\n () => api.getTeams().catch(() => []),\n [api],\n );\n\n // Filter to teams the current user belongs to\n const teams = useMemo(() => {\n if (!allTeams?.length) return [];\n if (!userInfo) return allTeams;\n const userId = userInfo.user_id;\n if (userInfo.teams?.length) {\n return allTeams.filter(t => userInfo.teams!.includes(t.team_id));\n }\n const byMembership = allTeams.filter(t =>\n t.members_with_roles?.some(m => m.user_id === userId),\n );\n return byMembership.length > 0 ? byMembership : allTeams;\n }, [allTeams, userInfo]);\n\n const { value: usage, loading: usageLoading } = useAsync(async () => {\n const startDate = dateRange.start.toISOString().split('T')[0];\n const endDate = dateRange.end.toISOString().split('T')[0];\n return api.getUsage(startDate, endDate);\n }, [api, dateRange]);\n\n // Invalidate team usage cache when date range changes so stale data isn't shown\n const handleDateRangeChange = useCallback((range: DateRange) => {\n setDateRange(range);\n setTeamUsageCache({});\n setTeamUsageLoading({});\n }, [setDateRange]);\n\n // Fetch team usage on demand when a team card is expanded\n const loadTeamUsage = useCallback(async (teamId: string) => {\n if (teamUsageCache[teamId] !== undefined || teamUsageLoading[teamId]) return;\n setTeamUsageLoading(prev => ({ ...prev, [teamId]: true }));\n try {\n const startDate = dateRange.start.toISOString().split('T')[0];\n const endDate = dateRange.end.toISOString().split('T')[0];\n const data = await api.getTeamUsage(teamId, startDate, endDate);\n setTeamUsageCache(prev => ({ ...prev, [teamId]: data }));\n } catch {\n setTeamUsageCache(prev => ({ ...prev, [teamId]: null }));\n } finally {\n setTeamUsageLoading(prev => ({ ...prev, [teamId]: false }));\n }\n }, [api, dateRange, teamUsageCache, teamUsageLoading]);\n\n // Models available for key generation: intersection of all models with user-level\n // and team-level restrictions. If a user has no model restrictions, all models are allowed.\n const allowedModels = useMemo(() => {\n if (!allModels?.length) return [];\n const userModels = userInfo?.models;\n const teamModels = teams?.flatMap(t => t.models ?? []);\n const hasUserRestriction = userModels && userModels.length > 0;\n const hasTeamRestriction = teamModels && teamModels.length > 0;\n if (!hasUserRestriction && !hasTeamRestriction) return allModels;\n const allowed = new Set([\n ...(hasUserRestriction ? userModels! : allModels.map(m => m.model_name)),\n ...(hasTeamRestriction ? teamModels! : []),\n ]);\n return allModels.filter(m => allowed.has(m.model_name));\n }, [allModels, userInfo, teams]);\n\n const handleGenerateKey = useCallback(\n async (request: GenerateKeyRequest): Promise<GenerateKeyResponse> => {\n const response = await api.generateKey(request);\n setSnackbar({ message: 'Key generated successfully', severity: 'success' });\n refreshKeys();\n return response;\n },\n [api, refreshKeys],\n );\n\n const handleUpdateKey = useCallback(\n async (keyId: string, request: UpdateKeyRequest) => {\n try {\n await api.updateKey(keyId, request);\n setSnackbar({ message: 'Key updated successfully', severity: 'success' });\n refreshKeys();\n } catch (e: any) {\n setSnackbar({ message: `Failed to update key: ${e.message}`, severity: 'error' });\n throw e;\n }\n },\n [api, refreshKeys],\n );\n\n const handleBlockKey = useCallback(\n async (keyId: string) => {\n try {\n await api.blockKey(keyId);\n setSnackbar({ message: 'Key blocked \u2014 requests will be rejected until unblocked', severity: 'warning' });\n refreshKeys();\n } catch (e: any) {\n setSnackbar({ message: `Failed to block key: ${e.message}`, severity: 'error' });\n }\n },\n [api, refreshKeys],\n );\n\n const handleUnblockKey = useCallback(\n async (keyId: string) => {\n try {\n await api.unblockKey(keyId);\n setSnackbar({ message: 'Key unblocked', severity: 'success' });\n refreshKeys();\n } catch (e: any) {\n setSnackbar({ message: `Failed to unblock key: ${e.message}`, severity: 'error' });\n }\n },\n [api, refreshKeys],\n );\n\n const handleResetKeySpend = useCallback(\n async (keyId: string) => {\n try {\n await api.resetKeySpend(keyId);\n setSnackbar({ message: 'Spend counter reset to $0', severity: 'success' });\n refreshKeys();\n } catch (e: any) {\n setSnackbar({ message: `Failed to reset spend: ${e.message}`, severity: 'error' });\n }\n },\n [api, refreshKeys],\n );\n\n const handleRotateKey = useCallback(\n async (keyId: string): Promise<GenerateKeyResponse> => {\n const response = await api.rotateKey(keyId);\n setSnackbar({ message: 'Key rotated \u2014 copy the new secret now', severity: 'success' });\n refreshKeys();\n return response;\n },\n [api, refreshKeys],\n );\n\n const handleDeleteKey = useCallback(\n async (keyId: string) => {\n try {\n await api.deleteKey(keyId);\n setSnackbar({ message: 'Key revoked successfully', severity: 'success' });\n refreshKeys();\n } catch (e: any) {\n if (e.body?.success && (e.body?.message?.includes('already deleted') || e.body?.message?.includes('never existed'))) {\n setSnackbar({ message: 'Key was already deleted', severity: 'warning' });\n refreshKeys();\n return;\n }\n setSnackbar({ message: `Failed to revoke key: ${e.message}`, severity: 'error' });\n }\n },\n [api, refreshKeys],\n );\n\n const handlePruneExpiredKeys = useCallback(\n async () => {\n try {\n const result = await api.pruneExpiredKeys();\n setSnackbar({ message: `Pruned ${result.pruned} expired key${result.pruned !== 1 ? 's' : ''}`, severity: 'success' });\n refreshKeys();\n } catch (e: any) {\n setSnackbar({ message: `Failed to prune expired keys: ${e.message}`, severity: 'error' });\n }\n return { pruned: 0 };\n },\n [api, refreshKeys],\n ) as () => Promise<{ pruned: number }>;\n\n const isInitialLoading = userLoading && !userInfo;\n\n if (isInitialLoading) {\n return (\n <Box display=\"flex\" justifyContent=\"center\" alignItems=\"center\" minHeight=\"50vh\">\n <CircularProgress />\n </Box>\n );\n }\n\n // User exists in Backstage but has no LiteLLM account\n if (userError || !userInfo) {\n const isProvisioningEnabled = (userError as any)?.body?.provisioning === true;\n const hint = (userError as any)?.body?.hint;\n return (\n <Box p={3}>\n <Paper sx={{ p: 3 }}>\n <Typography variant=\"h6\" gutterBottom>Account not provisioned</Typography>\n <Typography color=\"text.secondary\" paragraph>\n Your Backstage account is not linked to a LiteLLM user.\n </Typography>\n {hint ? (\n <Typography variant=\"body2\" color=\"text.secondary\">{hint}</Typography>\n ) : (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {isProvisioningEnabled\n ? 'Auto-provisioning is enabled but failed. Check the backend logs.'\n : 'Set litellm.provisioning.enabled: true in app-config.yaml to enable auto-provisioning, or ask your administrator to create the account manually.'}\n </Typography>\n )}\n </Paper>\n </Box>\n );\n }\n\n return (\n <Box p={3}>\n <Box mb={2}>\n <DashboardHeader userInfo={userInfo} teams={teams ?? []} loading={userLoading || teamsLoading} />\n </Box>\n\n <Tabs\n value={activeTab}\n onChange={(_, v) => setActiveTab(v)}\n sx={{ mb: 2, borderBottom: 1, borderColor: 'divider' }}\n >\n <Tab label=\"Overview\" value=\"overview\" />\n <Tab label=\"Keys\" value=\"keys\" />\n <Tab label=\"Teams\" value=\"teams\" />\n {userInfo.can_view_audit && <Tab label=\"Audit Log\" value=\"audit\" />}\n </Tabs>\n\n {activeTab === 'overview' && (\n <UsageStats\n usage={usage ?? null}\n models={allModels ?? []}\n dateRange={dateRange}\n onDateRangeChange={handleDateRangeChange}\n loading={usageLoading}\n userInfo={userInfo}\n />\n )}\n\n {activeTab === 'keys' && (\n <KeysTable\n keys={keys ?? []}\n models={allowedModels}\n teams={teams ?? []}\n loading={keysLoading || modelsLoading}\n onGenerateKey={handleGenerateKey}\n onUpdateKey={handleUpdateKey}\n onRotateKey={handleRotateKey}\n onBlockKey={handleBlockKey}\n onUnblockKey={handleUnblockKey}\n onResetKeySpend={handleResetKeySpend}\n onDeleteKey={handleDeleteKey}\n onPruneExpiredKeys={handlePruneExpiredKeys}\n />\n )}\n\n {activeTab === 'teams' && (\n <TeamUsage\n teams={teams ?? []}\n loading={teamsLoading}\n dateRange={dateRange}\n getTeamUsage={teamId => {\n if (teamUsageCache[teamId] === undefined) loadTeamUsage(teamId);\n return teamUsageCache[teamId] ?? null;\n }}\n getTeamUsageLoading={teamId => teamUsageLoading[teamId] ?? false}\n />\n )}\n\n {activeTab === 'audit' && userInfo.can_view_audit && <AuditLog api={api} />}\n\n <Snackbar\n open={!!snackbar}\n autoHideDuration={5000}\n onClose={() => setSnackbar(null)}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n >\n {snackbar ? (\n <Alert severity={snackbar.severity} onClose={() => setSnackbar(null)}>\n {snackbar.message}\n </Alert>\n ) : undefined}\n </Snackbar>\n </Box>\n );\n};\n", "export { litellmPlugin } from './plugin';\nexport { LiteLLMPage } from './components/LiteLLMPage';\nexport { DashboardHeader } from './components/DashboardHeader';\nexport { KeysTable } from './components/KeysTable';\nexport { UsageStats } from './components/UsageStats';\nexport { TeamUsage } from './components/TeamUsage';\nexport { LiteLLMHomeWidget } from './components/LiteLLMHomeWidget';\nexport type { LiteLLMHomeWidgetProps } from './components/LiteLLMHomeWidget';\nexport { LiteLlmApi, liteLlmApiRef } from './api';\nexport type { LiteLlmApiInterface } from './api';\nexport * from './types';\n", "import React from 'react';\nimport { TrendingUp as TrendingUpIcon } from '@mui/icons-material';\nimport {\n createFrontendPlugin,\n ApiBlueprint,\n PageBlueprint,\n fetchApiRef,\n} from '@backstage/frontend-plugin-api';\nimport { liteLlmApiRef, LiteLlmApi } from './api';\n\nconst liteLlmApi = ApiBlueprint.make({\n params: defineParams =>\n defineParams({\n api: liteLlmApiRef,\n deps: { fetchApi: fetchApiRef },\n factory: ({ fetchApi }) => new LiteLlmApi(fetchApi),\n }),\n});\n\nconst liteLlmPage = PageBlueprint.make({\n params: {\n path: '/litellm',\n title: 'LiteLLM',\n icon: <TrendingUpIcon />,\n loader: async () => {\n const { LiteLLMPage } = await import('./components/LiteLLMPage');\n return <LiteLLMPage />;\n },\n },\n});\n\nexport const litellmPlugin = createFrontendPlugin({\n pluginId: 'litellm',\n extensions: [liteLlmApi, liteLlmPage],\n});\n", "import React, { useState, useEffect } from 'react';\nimport {\n Paper,\n Box,\n Typography,\n FormControl,\n Select,\n MenuItem,\n Grid,\n CircularProgress,\n Alert,\n} from '@mui/material';\nimport { AreaChart, Area, ResponsiveContainer } from 'recharts';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { liteLlmApiRef } from '../api';\nimport { UsageMetrics, VirtualKey } from '../types';\n\nexport interface LiteLLMHomeWidgetProps {\n /** Default period when the widget mounts. Defaults to '7d'. */\n defaultPeriod?: 'today' | '7d' | '30d';\n /** Optional title override. Defaults to 'LiteLLM Usage'. */\n title?: string;\n}\n\ntype DatePreset = 'today' | '7d' | '30d';\n\nconst fmtUsd = (n: number) => `$${(n ?? 0).toFixed(n < 1 ? 4 : 2)}`;\nconst fmtInt = (n: number) => (n ?? 0).toLocaleString();\n\nfunction presetToDateRange(preset: DatePreset): { start: Date; end: Date } {\n const end = new Date();\n const start = new Date();\n if (preset === 'today') {\n start.setHours(0, 0, 0, 0);\n } else if (preset === '7d') {\n start.setDate(start.getDate() - 7);\n } else {\n start.setDate(start.getDate() - 30);\n }\n return { start, end };\n}\n\ninterface KpiProps {\n label: string;\n value: string;\n}\n\nconst Kpi: React.FC<KpiProps> = ({ label, value }) => (\n <Box>\n <Typography variant=\"caption\" color=\"text.secondary\" display=\"block\">\n {label}\n </Typography>\n <Typography variant=\"subtitle1\" fontWeight={600}>\n {value}\n </Typography>\n </Box>\n);\n\nexport const LiteLLMHomeWidget: React.FC<LiteLLMHomeWidgetProps> = ({\n defaultPeriod = '7d',\n title = 'LiteLLM Usage',\n}) => {\n const api = useApi(liteLlmApiRef);\n const [period, setPeriod] = useState<DatePreset>(defaultPeriod);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [usage, setUsage] = useState<UsageMetrics | null>(null);\n const [keys, setKeys] = useState<VirtualKey[]>([]);\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n setError(null);\n\n const { start, end } = presetToDateRange(period);\n const startDate = start.toISOString().split('T')[0];\n const endDate = end.toISOString().split('T')[0];\n\n Promise.all([api.getUsage(startDate, endDate), api.listKeys()])\n .then(([usageData, keysData]) => {\n if (!cancelled) {\n setUsage(usageData);\n setKeys(keysData);\n setLoading(false);\n }\n })\n .catch((err: Error) => {\n if (!cancelled) {\n setError(err.message ?? 'Failed to load usage data');\n setLoading(false);\n }\n });\n\n return () => {\n cancelled = true;\n };\n }, [api, period]);\n\n const dailyData = (usage?.daily_usage ?? []).map(d => ({\n date: d.date,\n spend: d.spend,\n }));\n\n const hasSparkline = dailyData.length > 0;\n\n return (\n <Paper sx={{ p: 2 }}>\n {/* Card header */}\n <Box display=\"flex\" justifyContent=\"space-between\" alignItems=\"center\" mb={1.5}>\n <Typography variant=\"h6\">{title}</Typography>\n <FormControl size=\"small\" sx={{ minWidth: 90 }}>\n <Select\n value={period}\n onChange={e => setPeriod(e.target.value as DatePreset)}\n displayEmpty\n >\n <MenuItem value=\"today\">Today</MenuItem>\n <MenuItem value=\"7d\">7d</MenuItem>\n <MenuItem value=\"30d\">30d</MenuItem>\n </Select>\n </FormControl>\n </Box>\n\n {/* Loading state */}\n {loading && (\n <Box display=\"flex\" justifyContent=\"center\" alignItems=\"center\" minHeight={120}>\n <CircularProgress size={32} />\n </Box>\n )}\n\n {/* Error state */}\n {!loading && error && (\n <Alert severity=\"error\" sx={{ mt: 1 }}>\n {error}\n </Alert>\n )}\n\n {/* Content */}\n {!loading && !error && (\n <>\n <Grid container spacing={2} sx={{ mb: hasSparkline ? 1.5 : 0 }}>\n <Grid item xs={6}>\n <Kpi label=\"USD Spent\" value={fmtUsd(usage?.total_spend ?? 0)} />\n </Grid>\n <Grid item xs={6}>\n <Kpi label=\"Tokens In\" value={fmtInt(usage?.prompt_tokens ?? 0)} />\n </Grid>\n <Grid item xs={6}>\n <Kpi label=\"Tokens Out\" value={fmtInt(usage?.completion_tokens ?? 0)} />\n </Grid>\n <Grid item xs={6}>\n <Kpi label=\"Keys\" value={fmtInt(keys.length)} />\n </Grid>\n </Grid>\n\n {/* Sparkline */}\n {hasSparkline && (\n <Box height={120}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <AreaChart data={dailyData} margin={{ top: 4, right: 0, bottom: 0, left: 0 }}>\n <Area\n type=\"monotone\"\n dataKey=\"spend\"\n stroke=\"#8884d8\"\n fill=\"#8884d8\"\n fillOpacity={0.3}\n dot={false}\n isAnimationActive={false}\n />\n </AreaChart>\n </ResponsiveContainer>\n </Box>\n )}\n </>\n )}\n </Paper>\n );\n};\n"],
5
+ "mappings": "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",
6
6
  "names": ["React", "React", "import_react", "import_material", "import_react", "import_material", "React", "import_react", "import_material", "import_icons_material", "import_recharts", "React", "import_react", "import_material", "import_icons_material", "React", "PERIOD_LS_KEY", "import_react", "import_material", "import_react_use", "import_core_plugin_api", "React", "import_react", "import_icons_material", "React", "TrendingUpIcon", "LiteLLMPage", "import_react", "import_material", "import_recharts", "import_core_plugin_api", "fmtUsd", "fmtInt", "React"]
7
7
  }