@acarmisc/backstage-plugin-litellm 0.18.0 → 0.19.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/ui.tsx", "../src/components/DashboardHeader.tsx", "../src/components/KeysTable.tsx", "../src/format.ts", "../src/components/GenerateKeyDialog.tsx", "../src/components/ManageTeamDialog.tsx", "../src/components/UsageStats.tsx", "../src/components/TeamUsage.tsx", "../src/components/ModelsTable.tsx", "../src/components/AuditLog.tsx", "../src/permissions.ts", "../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 LiteLlmConfig,\n VectorStoreInfo,\n McpServerInfo,\n CreateTeamRequest,\n CreateTeamResponse,\n UpdateTeamRequest,\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 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 getManagedTeams(): Promise<TeamInfo[]>;\n addTeamMember(\n teamId: string,\n body: { userEntityRef: string; maxBudgetInTeam?: number },\n ): Promise<TeamInfo>;\n removeTeamMember(teamId: string, userEntityRef: string): Promise<TeamInfo>;\n getVectorStores(): Promise<VectorStoreInfo[]>;\n setTeamKnowledgeBases(teamId: string, vectorStores: string[]): Promise<TeamInfo>;\n getMcpServers(): Promise<McpServerInfo[]>;\n setTeamMcpServers(teamId: string, mcpServers: string[]): 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 getConfig(): Promise<LiteLlmConfig>;\n createTeam(request: CreateTeamRequest): Promise<CreateTeamResponse>;\n updateTeam(teamId: string, request: UpdateTeamRequest): Promise<TeamInfo>;\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 const message =\n (typeof body === 'object' && body && typeof (body as any).error === 'string'\n ? (body as any).error\n : undefined) ?? `${response.status} ${response.statusText}`;\n throw new ApiError(message, 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 private async patch<T>(path: string, body: unknown): Promise<T> {\n const response = await this.fetchApi.fetch(`${this.basePath}${path}`, {\n method: 'PATCH',\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 put<T>(path: string, body: unknown): Promise<T> {\n const response = await this.fetchApi.fetch(`${this.basePath}${path}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\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 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 // eslint-disable-next-line no-console -- best-effort bulk cleanup; no errorApi in this client class to report through\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 // Teams whose owning_group the caller administers (server-scoped). Distinct\n // from getTeams(), which returns only the teams the caller is a member of.\n async getManagedTeams(): Promise<TeamInfo[]> {\n return this.get<TeamInfo[]>('/teams/managed');\n }\n\n async addTeamMember(\n teamId: string,\n body: { userEntityRef: string; maxBudgetInTeam?: number },\n ): Promise<TeamInfo> {\n return this.post<TeamInfo>(\n `/teams/${encodeURIComponent(teamId)}/members`,\n body,\n );\n }\n\n async removeTeamMember(\n teamId: string,\n userEntityRef: string,\n ): Promise<TeamInfo> {\n return this.del<TeamInfo>(\n `/teams/${encodeURIComponent(teamId)}/members?userEntityRef=${encodeURIComponent(\n userEntityRef,\n )}`,\n );\n }\n\n // Vector stores (knowledge bases) the caller may attach \u2014 already filtered\n // server-side to the operator's allowlist.\n async getVectorStores(): Promise<VectorStoreInfo[]> {\n return this.get<VectorStoreInfo[]>('/vector-stores');\n }\n\n async setTeamKnowledgeBases(\n teamId: string,\n vectorStores: string[],\n ): Promise<TeamInfo> {\n return this.put<TeamInfo>(\n `/teams/${encodeURIComponent(teamId)}/knowledge-bases`,\n { vector_stores: vectorStores },\n );\n }\n\n async getMcpServers(): Promise<McpServerInfo[]> {\n return this.get<McpServerInfo[]>('/mcp-servers');\n }\n\n async setTeamMcpServers(\n teamId: string,\n mcpServers: string[],\n ): Promise<TeamInfo> {\n return this.put<TeamInfo>(\n `/teams/${encodeURIComponent(teamId)}/mcp-servers`,\n { mcp_servers: mcpServers },\n );\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 async getConfig(): Promise<LiteLlmConfig> {\n return this.get<LiteLlmConfig>('/config');\n }\n\n async createTeam(request: CreateTeamRequest): Promise<CreateTeamResponse> {\n return this.post<CreateTeamResponse>('/teams', request);\n }\n\n async updateTeam(teamId: string, request: UpdateTeamRequest): Promise<TeamInfo> {\n return this.patch<TeamInfo>(`/teams/${encodeURIComponent(teamId)}`, request);\n }\n}\n", "/**\n * Shared presentation primitives for the LiteLLM plugin.\n *\n * The plugin renders inside whatever Backstage theme the host app supplies, so\n * everything here derives its colour from the MUI palette rather than hard-coded\n * values. The one exception is the chart series palette: Recharts has no theme\n * awareness, and its stock colours (#8884d8 / #82ca9d / #ffc658) read as a demo\n * rather than a product, so we ship a curated ramp that holds up on both light\n * and dark surfaces.\n */\nimport React from 'react';\nimport Box from '@mui/material/Box';\nimport ButtonBase from '@mui/material/ButtonBase';\nimport Paper from '@mui/material/Paper';\nimport Typography from '@mui/material/Typography';\nimport { alpha, useTheme } from '@mui/material/styles';\nimport type { SxProps, Theme } from '@mui/material/styles';\n\n// \u2500\u2500 formatting \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\n\n/** `2026-08-16` \u2192 `Aug 16`. Falls back to the raw value for anything else. */\nexport const fmtDateShort = (value: string): string => {\n const m = /^(\\d{4})-(\\d{2})-(\\d{2})/.exec(value ?? '');\n if (!m) return value;\n return `${MONTHS[Number(m[2]) - 1]} ${Number(m[3])}`;\n};\n\n/** 54253484 \u2192 `54.3M`. Keeps axis labels from swallowing the plot area. */\nexport const fmtCompact = (n: number): string => {\n const v = n ?? 0;\n const abs = Math.abs(v);\n if (abs >= 1e9) return `${(v / 1e9).toFixed(abs >= 1e10 ? 0 : 1)}B`;\n if (abs >= 1e6) return `${(v / 1e6).toFixed(abs >= 1e7 ? 0 : 1)}M`;\n if (abs >= 1e3) return `${(v / 1e3).toFixed(abs >= 1e4 ? 0 : 1)}K`;\n return String(Math.round(v));\n};\n\n/** Compact currency for axis ticks \u2014 `$24`, `$1.2K`. */\nexport const fmtUsdCompact = (n: number): string => {\n const v = n ?? 0;\n if (Math.abs(v) >= 1000) return `$${fmtCompact(v)}`;\n if (Math.abs(v) >= 10) return `$${v.toFixed(0)}`;\n return `$${v.toFixed(2)}`;\n};\n\n// \u2500\u2500 chart palette \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Categorical ramp, ordered so neighbouring series stay distinguishable. */\nexport const CHART_COLORS = [\n '#6366F1', // indigo\n '#14B8A6', // teal\n '#F59E0B', // amber\n '#EC4899', // pink\n '#38BDF8', // sky\n '#84CC16', // lime\n '#F97316', // orange\n '#A855F7', // violet\n] as const;\n\n/** Fixed colours for series that carry meaning rather than identity. */\nexport const SERIES = {\n input: '#6366F1',\n output: '#14B8A6',\n success: '#10B981',\n failure: '#EF4444',\n spend: '#F59E0B',\n budget: '#EF4444',\n} as const;\n\nconst OTHER_COLOR = '#94A3B8';\n\n/** Stable colour per series name, so a model keeps its colour across charts. */\nexport function chartColor(name: string): string {\n if (name === 'Other') return OTHER_COLOR;\n let h = 5381;\n for (let i = 0; i < name.length; i++) h = ((h << 5) + h + name.charCodeAt(i)) >>> 0;\n return CHART_COLORS[h % CHART_COLORS.length];\n}\n\n/** Axis / grid / legend props shared by every chart, derived from the theme. */\nexport function useChartTheme() {\n const theme = useTheme();\n const tickFill = theme.palette.text.secondary;\n return {\n grid: {\n stroke: alpha(theme.palette.text.primary, theme.palette.mode === 'dark' ? 0.12 : 0.08),\n strokeDasharray: '2 4',\n vertical: false,\n },\n axis: {\n tick: { fontSize: 11, fill: tickFill },\n tickLine: false,\n axisLine: { stroke: alpha(theme.palette.text.primary, 0.12) },\n },\n legend: {\n wrapperStyle: {\n fontSize: 11,\n color: tickFill,\n paddingTop: 8,\n },\n iconType: 'circle' as const,\n iconSize: 8,\n },\n cursor: { fill: alpha(theme.palette.text.primary, 0.05) },\n };\n}\n\ninterface ChartTooltipProps {\n active?: boolean;\n label?: string | number;\n payload?: Array<{ name?: string; value?: number; color?: string; dataKey?: string | number }>;\n /** Formats each series value; defaults to a localised integer. */\n valueFormatter?: (value: number) => string;\n /** Formats the header; defaults to the short date form. */\n labelFormatter?: (label: string) => string;\n /** Drop zero-valued series \u2014 useful for stacked charts with many series. */\n hideZero?: boolean;\n}\n\n/**\n * Recharts' default tooltip is an opaque white card with a hard border \u2014 it\n * disappears on dark themes. This one uses the theme's own surface tokens.\n */\nexport const ChartTooltip: React.FC<ChartTooltipProps> = ({\n active,\n label,\n payload,\n valueFormatter = (v: number) => v.toLocaleString(),\n labelFormatter = fmtDateShort,\n hideZero = false,\n}) => {\n if (!active || !payload?.length) return null;\n const rows = payload.filter(\n p => p.value !== undefined && p.value !== null && (!hideZero || p.value !== 0),\n );\n if (!rows.length) return null;\n return (\n <Paper\n elevation={8}\n sx={{\n px: 1.5,\n py: 1,\n borderRadius: 1.5,\n border: '1px solid',\n borderColor: 'divider',\n minWidth: 150,\n pointerEvents: 'none',\n }}\n >\n <Typography\n variant=\"caption\"\n sx={{ display: 'block', fontWeight: 700, mb: 0.75, letterSpacing: '0.02em' }}\n >\n {typeof label === 'string' ? labelFormatter(label) : label}\n </Typography>\n {rows.map((row, i) => (\n <Box\n key={`${row.dataKey ?? row.name ?? i}`}\n sx={{ display: 'flex', alignItems: 'center', gap: 1, mt: i === 0 ? 0 : 0.5 }}\n >\n <Box\n sx={{\n width: 8,\n height: 8,\n borderRadius: '50%',\n bgcolor: row.color,\n flexShrink: 0,\n }}\n />\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n sx={{ flex: 1, mr: 1.5, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}\n >\n {row.name}\n </Typography>\n <Typography variant=\"caption\" sx={{ fontWeight: 700, fontVariantNumeric: 'tabular-nums' }}>\n {valueFormatter(row.value as number)}\n </Typography>\n </Box>\n ))}\n </Paper>\n );\n};\n\n/**\n * Colour key rendered outside the SVG. Recharts' own `<Legend>` cannot ellipsize,\n * so a handful of fully-qualified model names (\"bedrock/eu.anthropic.\u2026\") wrap\n * into a ragged block that eats the plot area.\n */\nexport const SeriesLegend: React.FC<{ series: Array<{ name: string; color: string }> }> = ({\n series,\n}) => (\n <Box\n sx={{\n display: 'flex',\n flexWrap: 'wrap',\n gap: 0.5,\n columnGap: 2,\n rowGap: 0.5,\n mt: 1.5,\n }}\n >\n {series.map(s => (\n <Box key={s.name} sx={{ display: 'flex', alignItems: 'center', gap: 0.75, minWidth: 0 }}>\n <Box\n sx={{ width: 8, height: 8, borderRadius: '50%', bgcolor: s.color, flexShrink: 0 }}\n />\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n title={s.name}\n sx={{\n fontSize: 11,\n maxWidth: 190,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }}\n >\n {s.name}\n </Typography>\n </Box>\n ))}\n </Box>\n);\n\n// \u2500\u2500 status pills \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type Tone = 'neutral' | 'success' | 'warning' | 'danger' | 'info' | 'accent';\n\nfunction toneColor(theme: Theme, tone: Tone): string {\n switch (tone) {\n case 'success': return theme.palette.success.main;\n case 'warning': return theme.palette.warning.main;\n case 'danger': return theme.palette.error.main;\n case 'info': return theme.palette.info.main;\n case 'accent': return theme.palette.primary.main;\n default: return theme.palette.text.secondary;\n }\n}\n\n/**\n * A soft status badge. Deliberately *not* MUI's filled `Chip` \u2014 host themes\n * tend to render those as saturated pills, and a table with one screaming\n * orange pill per row is unreadable. Tinted background, hairline border,\n * squared-off corners.\n */\nexport const StatusPill: React.FC<{\n label: React.ReactNode;\n tone?: Tone;\n /** Show the leading tone dot. */\n dot?: boolean;\n title?: string;\n sx?: SxProps<Theme>;\n}> = ({ label, tone = 'neutral', dot = true, title, sx }) => (\n <Box\n component=\"span\"\n title={title}\n sx={[\n theme => {\n const c = toneColor(theme, tone);\n return {\n display: 'inline-flex',\n alignItems: 'center',\n gap: 0.625,\n height: 22,\n px: 0.875,\n borderRadius: '6px',\n border: '1px solid',\n borderColor: alpha(c, tone === 'neutral' ? 0.25 : 0.35),\n bgcolor: alpha(c, tone === 'neutral' ? 0.06 : 0.12),\n color: tone === 'neutral' ? theme.palette.text.secondary : c,\n fontSize: 11.5,\n fontWeight: 600,\n lineHeight: 1,\n letterSpacing: '0.01em',\n whiteSpace: 'nowrap',\n maxWidth: '100%',\n };\n },\n ...(Array.isArray(sx) ? sx : [sx]),\n ]}\n >\n {dot && (\n <Box\n component=\"span\"\n sx={theme => ({\n width: 6,\n height: 6,\n borderRadius: '50%',\n bgcolor: toneColor(theme, tone),\n flexShrink: 0,\n })}\n />\n )}\n <Box component=\"span\" sx={{ overflow: 'hidden', textOverflow: 'ellipsis' }}>\n {label}\n </Box>\n </Box>\n);\n\n/** Quiet monospace tag for identifiers: model names, team slugs, roles. */\nexport const TagChip: React.FC<{ label: React.ReactNode; title?: string; mono?: boolean }> = ({\n label,\n title,\n mono = true,\n}) => (\n <Box\n component=\"span\"\n title={title}\n sx={theme => ({\n display: 'inline-flex',\n alignItems: 'center',\n height: 20,\n px: 0.75,\n borderRadius: '5px',\n bgcolor: alpha(theme.palette.text.primary, theme.palette.mode === 'dark' ? 0.08 : 0.05),\n color: theme.palette.text.secondary,\n fontFamily: mono ? 'ui-monospace, SFMono-Regular, Menlo, monospace' : undefined,\n fontSize: 11,\n lineHeight: 1,\n whiteSpace: 'nowrap',\n maxWidth: 220,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n })}\n >\n {label}\n </Box>\n);\n\n// \u2500\u2500 surfaces \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Page-level surface with a consistent title row. */\nexport const SectionCard: React.FC<{\n title?: React.ReactNode;\n subtitle?: React.ReactNode;\n actions?: React.ReactNode;\n /** Set when the body renders its own edge-to-edge content (e.g. a table). */\n flush?: boolean;\n children: React.ReactNode;\n}> = ({ title, subtitle, actions, flush = false, children }) => (\n <Paper sx={{ borderRadius: 2, overflow: 'hidden' }}>\n {(title || actions) && (\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 2,\n flexWrap: 'wrap',\n px: 2.5,\n py: 2,\n }}\n >\n <Box sx={{ minWidth: 0 }}>\n <Typography variant=\"h6\" sx={{ lineHeight: 1.2 }}>{title}</Typography>\n {subtitle && (\n <Typography variant=\"caption\" color=\"text.secondary\">{subtitle}</Typography>\n )}\n </Box>\n {actions && (\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, flexWrap: 'wrap' }}>\n {actions}\n </Box>\n )}\n </Box>\n )}\n <Box sx={flush ? undefined : { px: 2.5, pb: 2.5, pt: title ? 0 : 2.5 }}>{children}</Box>\n </Paper>\n);\n\n/** Bordered frame around a single chart, with its own caption row. */\nexport const ChartCard: React.FC<{\n title: React.ReactNode;\n meta?: React.ReactNode;\n height?: number;\n children: React.ReactNode;\n}> = ({ title, meta, height = 240, children }) => (\n // The plot area must have an explicit height, never a flex-derived one:\n // Recharts' ResponsiveContainer measures its parent, so a parent that sizes\n // itself from its children instead spins in a measure/resize loop.\n <Paper variant=\"outlined\" sx={{ p: 2, borderRadius: 2, height: '100%' }}>\n <Box sx={{ display: 'flex', alignItems: 'baseline', gap: 1, mb: 1.5, flexWrap: 'wrap' }}>\n <Typography\n variant=\"subtitle2\"\n sx={{ fontSize: 12, fontWeight: 700, letterSpacing: '0.06em', textTransform: 'uppercase' }}\n >\n {title}\n </Typography>\n {meta && (\n <Typography variant=\"caption\" color=\"text.secondary\">{meta}</Typography>\n )}\n </Box>\n <Box sx={{ height, width: '100%' }}>{children}</Box>\n </Paper>\n);\n\n// \u2500\u2500 metrics \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface MetricDef {\n label: string;\n value: string;\n hint?: string;\n tone?: Tone;\n}\n\n/**\n * KPI row rendered as one framed strip divided into cells, rather than four\n * loose cards. Cells share a baseline grid so the numbers line up even when\n * only some of them carry a hint.\n */\nexport const MetricStrip: React.FC<{ metrics: MetricDef[] }> = ({ metrics }) => (\n <Paper\n variant=\"outlined\"\n sx={{\n borderRadius: 2,\n display: 'grid',\n gridTemplateColumns: { xs: '1fr 1fr', md: `repeat(${metrics.length}, 1fr)` },\n overflow: 'hidden',\n }}\n >\n {metrics.map((m, i) => (\n <Box\n key={m.label}\n sx={theme => ({\n px: 2.5,\n py: 2,\n borderLeft: i === 0 ? 0 : '1px solid',\n borderTop: 0,\n borderColor: 'divider',\n [theme.breakpoints.down('md')]: {\n borderLeft: i % 2 === 0 ? 0 : '1px solid',\n borderTop: i < 2 ? 0 : '1px solid',\n borderColor: 'divider',\n },\n })}\n >\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.875, mb: 0.75 }}>\n <Box\n sx={theme => ({\n width: 6,\n height: 6,\n borderRadius: '50%',\n bgcolor: toneColor(theme, m.tone ?? 'accent'),\n flexShrink: 0,\n })}\n />\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n sx={{ fontSize: 11, fontWeight: 600, letterSpacing: '0.07em', textTransform: 'uppercase' }}\n >\n {m.label}\n </Typography>\n </Box>\n <Typography\n sx={{ fontSize: 26, fontWeight: 700, lineHeight: 1.15, fontVariantNumeric: 'tabular-nums' }}\n >\n {m.value}\n </Typography>\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n sx={{ display: 'block', mt: 0.5, minHeight: 16 }}\n >\n {m.hint ?? '\u00A0'}\n </Typography>\n </Box>\n ))}\n </Paper>\n);\n\n/** Label + value pair used inside cards. */\nexport const Stat: React.FC<{ label: string; value: React.ReactNode }> = ({ label, value }) => (\n <Box sx={{ minWidth: 0 }}>\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n sx={{ display: 'block', fontSize: 10.5, fontWeight: 600, letterSpacing: '0.07em', textTransform: 'uppercase' }}\n >\n {label}\n </Typography>\n <Typography\n variant=\"body2\"\n sx={{ fontWeight: 600, fontVariantNumeric: 'tabular-nums', mt: 0.25 }}\n >\n {value}\n </Typography>\n </Box>\n);\n\n/**\n * Progress meter with an explicitly drawn track. MUI's `LinearProgress` tints\n * its track from the bar colour, which makes an empty bar look full.\n */\nexport const Meter: React.FC<{ value: number; tone?: Tone; height?: number }> = ({\n value,\n tone = 'accent',\n height = 5,\n}) => (\n <Box\n sx={theme => ({\n height,\n borderRadius: height,\n bgcolor: alpha(theme.palette.text.primary, theme.palette.mode === 'dark' ? 0.12 : 0.08),\n overflow: 'hidden',\n })}\n >\n <Box\n sx={theme => ({\n height: '100%',\n width: `${Math.max(0, Math.min(100, value))}%`,\n borderRadius: height,\n bgcolor: toneColor(theme, tone),\n transition: theme.transitions.create('width'),\n })}\n />\n </Box>\n);\n\n// \u2500\u2500 segmented control \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\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Secondary navigation inside a card. Hand-rolled rather than a second set of\n * `Tabs` so it reads as subordinate to the page tabs instead of competing\n * with them, and so host theme overrides on `MuiTab` don't leak in.\n */\nexport function SegmentedControl<T extends string>({\n value,\n onChange,\n options,\n}: {\n value: T;\n onChange: (value: T) => void;\n options: Array<{ value: T; label: string }>;\n}) {\n return (\n <Box\n role=\"tablist\"\n sx={theme => ({\n display: 'inline-flex',\n gap: 0.25,\n p: 0.375,\n borderRadius: 1.5,\n border: '1px solid',\n borderColor: theme.palette.divider,\n })}\n >\n {options.map(opt => {\n const selected = opt.value === value;\n return (\n <ButtonBase\n key={opt.value}\n role=\"tab\"\n aria-selected={selected}\n onClick={() => onChange(opt.value)}\n sx={theme => ({\n px: 1.5,\n height: 28,\n borderRadius: 1,\n fontSize: 13,\n fontWeight: selected ? 700 : 500,\n // Tint the selection with the accent rather than swapping in a\n // surface colour: on a dark theme `background.paper` sits *behind*\n // the track, so the selected chip would read as recessed.\n color: selected ? theme.palette.primary.main : theme.palette.text.secondary,\n bgcolor: selected\n ? alpha(theme.palette.primary.main, theme.palette.mode === 'dark' ? 0.2 : 0.11)\n : 'transparent',\n transition: theme.transitions.create(['background-color', 'color']),\n '&:hover': {\n color: selected ? theme.palette.primary.main : theme.palette.text.primary,\n bgcolor: selected\n ? alpha(theme.palette.primary.main, theme.palette.mode === 'dark' ? 0.26 : 0.15)\n : alpha(theme.palette.text.primary, 0.05),\n },\n })}\n >\n {opt.label}\n </ButtonBase>\n );\n })}\n </Box>\n );\n}\n\n// \u2500\u2500 tables \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Shared table chrome: quiet uppercase headers, hairline row rules, a hover\n * highlight, and tabular figures so numeric columns align.\n */\nexport const dataTableSx: SxProps<Theme> = theme => ({\n // Element selectors, not `.MuiTableCell-head`: host apps may set a MUI\n // classname prefix (Backstage ships `v5-`), which breaks global class targeting.\n '& thead th': {\n fontSize: 11,\n fontWeight: 700,\n letterSpacing: '0.07em',\n textTransform: 'uppercase',\n color: theme.palette.text.secondary,\n backgroundColor: alpha(theme.palette.text.primary, theme.palette.mode === 'dark' ? 0.04 : 0.02),\n borderBottom: `1px solid ${theme.palette.divider}`,\n whiteSpace: 'nowrap',\n paddingTop: theme.spacing(1.25),\n paddingBottom: theme.spacing(1.25),\n },\n '& tbody td': {\n borderBottom: `1px solid ${alpha(theme.palette.divider, 0.6)}`,\n paddingTop: theme.spacing(1.25),\n paddingBottom: theme.spacing(1.25),\n fontVariantNumeric: 'tabular-nums',\n },\n '& tbody tr:last-of-type td': {\n borderBottom: 0,\n },\n '& tbody tr:hover': {\n backgroundColor: alpha(theme.palette.text.primary, 0.03),\n },\n});\n\n/** Muted icon button that only picks up its semantic colour on hover. */\nexport const quietIconButtonSx = (tone: Tone = 'neutral'): SxProps<Theme> => theme => ({\n color: theme.palette.text.secondary,\n '&:hover': {\n color: toneColor(theme, tone),\n bgcolor: alpha(toneColor(theme, tone), 0.1),\n },\n});\n\n/** Centered empty / loading state for a card body. */\nexport const EmptyState: React.FC<{\n message: string;\n hint?: string;\n height?: number;\n action?: React.ReactNode;\n}> = ({ message, hint, height, action }) => (\n <Box\n sx={{\n height,\n minHeight: height ? undefined : 120,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 1,\n textAlign: 'center',\n py: 3,\n }}\n >\n <Typography variant=\"body2\" color=\"text.secondary\">{message}</Typography>\n {hint && <Typography variant=\"caption\" color=\"text.secondary\">{hint}</Typography>}\n {action}\n </Box>\n);\n", "import React, { useMemo } from 'react';\nimport Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport Skeleton from '@mui/material/Skeleton';\nimport Paper from '@mui/material/Paper';\nimport Button from '@mui/material/Button';\nimport Divider from '@mui/material/Divider';\nimport { alpha } from '@mui/material/styles';\nimport { Add } from '@mui/icons-material';\nimport { UserInfo, TeamInfo, VirtualKey } from '../types';\nimport { expiryStatus } from '../api';\nimport { TagChip, Tone } from './ui';\n\ninterface DashboardHeaderProps {\n userInfo: UserInfo;\n teams: TeamInfo[];\n keys: VirtualKey[];\n loading: boolean;\n onGenerateKeyClick: () => void;\n /** Page tab bar, rendered flush with the bottom edge of the header card. */\n tabs?: React.ReactNode;\n}\n\n/** Two initials from an email or username, for the identity badge. */\nfunction initials(name: string): string {\n const local = name.split('@')[0] ?? name;\n const parts = local.split(/[.\\-_\\s]+/).filter(Boolean);\n if (parts.length >= 2) return (parts[0][0] + parts[1][0]).toUpperCase();\n return local.slice(0, 2).toUpperCase();\n}\n\nconst CountStat: React.FC<{ value: number; label: string; tone: Tone }> = ({ value, label, tone }) => {\n // Zero counts stay grey: only a real expiry deserves a colour.\n const active = value > 0;\n return (\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>\n <Box\n sx={theme => ({\n width: 7,\n height: 7,\n borderRadius: '50%',\n flexShrink: 0,\n bgcolor: active\n ? (tone === 'danger' && theme.palette.error.main) ||\n (tone === 'warning' && theme.palette.warning.main) ||\n theme.palette.primary.main\n : alpha(theme.palette.text.primary, 0.25),\n })}\n />\n <Typography\n component=\"span\"\n sx={{ fontSize: 15, fontWeight: 700, lineHeight: 1, fontVariantNumeric: 'tabular-nums' }}\n >\n {value}\n </Typography>\n <Typography\n component=\"span\"\n color=\"text.secondary\"\n sx={{ fontSize: 11, fontWeight: 600, letterSpacing: '0.07em', textTransform: 'uppercase' }}\n >\n {label}\n </Typography>\n </Box>\n );\n};\n\nexport const DashboardHeader: React.FC<DashboardHeaderProps> = ({\n userInfo,\n teams,\n keys,\n loading,\n onGenerateKeyClick,\n tabs,\n}) => {\n const counts = useMemo(() => {\n const expired = keys.filter(k => expiryStatus(k.expires_at) === 'expired').length;\n const expiringSoon = keys.filter(k => expiryStatus(k.expires_at) === 'soon').length;\n return { total: keys.length, expired, expiringSoon };\n }, [keys]);\n\n const displayName = userInfo.user_email ?? userInfo.email ?? userInfo.user_id;\n\n return (\n <Paper sx={{ borderRadius: 2, overflow: 'hidden' }}>\n <Box\n sx={{\n display: 'flex',\n alignItems: 'flex-start',\n gap: 2,\n flexWrap: 'wrap',\n px: 2.5,\n pt: 2.5,\n pb: 2,\n }}\n >\n <Box\n sx={theme => ({\n width: 44,\n height: 44,\n borderRadius: 1.5,\n flexShrink: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n bgcolor: alpha(theme.palette.primary.main, 0.12),\n color: theme.palette.primary.main,\n fontSize: 15,\n fontWeight: 700,\n letterSpacing: '0.02em',\n })}\n >\n {initials(displayName)}\n </Box>\n\n <Box sx={{ flexGrow: 1, minWidth: 220 }}>\n <Typography variant=\"h6\" sx={{ lineHeight: 1.25, wordBreak: 'break-word' }}>\n {displayName}\n </Typography>\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n sx={{ display: 'block', fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace' }}\n >\n {userInfo.user_id}\n </Typography>\n\n <Box sx={{ display: 'flex', gap: 0.75, flexWrap: 'wrap', mt: 1, minHeight: 20 }}>\n {loading ? (\n <Skeleton variant=\"rounded\" width={140} height={20} />\n ) : (\n teams.map(team => (\n <TagChip\n key={team.team_id}\n label={team.team_alias || team.team_id}\n title={team.team_id}\n />\n ))\n )}\n </Box>\n </Box>\n\n <Button\n variant=\"contained\"\n color=\"primary\"\n disableElevation\n startIcon={<Add />}\n onClick={onGenerateKeyClick}\n >\n Generate New Key\n </Button>\n </Box>\n\n <Divider />\n\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 2.5,\n flexWrap: 'wrap',\n px: 2.5,\n py: 1.5,\n }}\n >\n <CountStat value={counts.total} label=\"keys\" tone=\"accent\" />\n <Divider orientation=\"vertical\" flexItem sx={{ my: 0.25 }} />\n <CountStat value={counts.expired} label=\"expired\" tone=\"danger\" />\n <Divider orientation=\"vertical\" flexItem sx={{ my: 0.25 }} />\n <CountStat value={counts.expiringSoon} label=\"expiring soon\" tone=\"warning\" />\n </Box>\n\n {tabs && (\n <>\n <Divider />\n <Box sx={{ px: 1 }}>{tabs}</Box>\n </>\n )}\n </Paper>\n );\n};\n", "import React, { useState, useMemo } from 'react';\nimport Table from '@mui/material/Table';\nimport TableBody from '@mui/material/TableBody';\nimport TableCell from '@mui/material/TableCell';\nimport TableContainer from '@mui/material/TableContainer';\nimport TableHead from '@mui/material/TableHead';\nimport TableRow from '@mui/material/TableRow';\nimport TableSortLabel from '@mui/material/TableSortLabel';\nimport Button from '@mui/material/Button';\nimport IconButton from '@mui/material/IconButton';\nimport Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport Dialog from '@mui/material/Dialog';\nimport DialogTitle from '@mui/material/DialogTitle';\nimport DialogContent from '@mui/material/DialogContent';\nimport DialogActions from '@mui/material/DialogActions';\nimport TextField from '@mui/material/TextField';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport Autocomplete from '@mui/material/Autocomplete';\nimport Skeleton from '@mui/material/Skeleton';\nimport InputAdornment from '@mui/material/InputAdornment';\nimport { alpha } from '@mui/material/styles';\nimport { ContentCopy, Delete, Add, Edit, Autorenew, Search, Lock, LockOpen } from '@mui/icons-material';\nimport { expiryStatus } from '../api';\nimport {\n VirtualKey,\n ModelInfo,\n UpdateKeyRequest,\n} from '../types';\nimport {\n EmptyState,\n Meter,\n SectionCard,\n StatusPill,\n TagChip,\n Tone,\n dataTableSx,\n quietIconButtonSx,\n} from './ui';\n\ninterface KeysTableProps {\n keys: VirtualKey[];\n models: ModelInfo[];\n /** Opens the shared \"Generate New Key\" dialog (rendered at page level). */\n onGenerateKeyClick: () => void;\n loading: boolean;\n onUpdateKey: (keyId: string, request: UpdateKeyRequest) => Promise<void>;\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 expiryChipLabel(status: 'expired' | 'soon' | 'ok', expiresAt: string): string {\n if (status === 'expired') return 'Expired';\n if (status === 'soon') return `${Math.ceil((new Date(expiresAt).getTime() - Date.now()) / 86400000)}d left`;\n return formatDate(expiresAt);\n}\n\nfunction expiryTone(status: 'expired' | 'soon' | 'ok'): Tone {\n if (status === 'expired') return 'danger';\n if (status === 'soon') return 'warning';\n return 'neutral';\n}\n\nfunction ExpiryCell({ expiresAt }: { expiresAt?: string }) {\n const status = expiryStatus(expiresAt);\n if (!status) {\n return <Typography variant=\"body2\" color=\"text.secondary\">Never</Typography>;\n }\n // A key that is simply valid needs no badge \u2014 plain text keeps the column\n // quiet so the handful of expired/expiring rows actually stand out.\n if (status === 'ok') {\n return (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {formatDate(expiresAt!)}\n </Typography>\n );\n }\n return (\n <StatusPill\n label={expiryChipLabel(status, expiresAt!)}\n tone={expiryTone(status)}\n title={`Expires ${formatDate(expiresAt!)}`}\n />\n );\n}\n\nfunction budgetTone(pct: number): Tone {\n if (pct >= 100) return 'danger';\n if (pct >= 80) return 'warning';\n return 'accent';\n}\n\nfunction keyBlockIcon(isBlocking: boolean, blocked?: boolean) {\n if (isBlocking) return <CircularProgress size={18} />;\n if (blocked) return <LockOpen fontSize=\"small\" />;\n return <Lock fontSize=\"small\" />;\n}\n\nfunction BudgetCell({ spend, maxBudget }: { spend: number; maxBudget?: number }) {\n if (!maxBudget) {\n return (\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ fontVariantNumeric: 'tabular-nums' }}>\n ${spend.toFixed(2)}\n <Typography component=\"span\" variant=\"caption\" sx={{ ml: 0.5, opacity: 0.7 }}>\n / \u221E\n </Typography>\n </Typography>\n );\n }\n const pct = Math.min(100, (spend / maxBudget) * 100);\n return (\n <Box minWidth={104}>\n <Typography variant=\"body2\" sx={{ fontVariantNumeric: 'tabular-nums', mb: 0.5 }}>\n ${spend.toFixed(2)}\n <Typography component=\"span\" variant=\"caption\" color=\"text.secondary\" sx={{ ml: 0.5 }}>\n / ${maxBudget}\n </Typography>\n </Typography>\n <Meter value={pct} tone={budgetTone(pct)} height={4} />\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\nfunction formatContextWindow(\n maxInput?: number,\n maxOutput?: number,\n): string | null {\n if (!maxInput && !maxOutput) return null;\n const fmt = (n?: number) => {\n if (!n) return null;\n if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\n if (n >= 1_000) return `${Math.round(n / 1000)}K`;\n return String(n);\n };\n const inPart = fmt(maxInput);\n const outPart = fmt(maxOutput);\n if (inPart && outPart) return `ctx ${inPart} in / ${outPart} out`;\n if (inPart) return `ctx ${inPart}`;\n if (outPart) return `ctx ${outPart} out`;\n return null;\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\ntype SortKey = 'alias' | 'created' | 'expires' | 'budget' | 'limits' | 'models';\ntype SortDirection = 'asc' | 'desc';\n\nfunction compareKeys(a: VirtualKey, b: VirtualKey, sortKey: SortKey): number {\n switch (sortKey) {\n case 'alias': return (a.key_alias ?? '').localeCompare(b.key_alias ?? '');\n case 'created': return a.created_at.localeCompare(b.created_at);\n case 'expires': return (a.expires_at ?? '').localeCompare(b.expires_at ?? '');\n case 'budget': return (a.max_budget ?? Infinity) - (b.max_budget ?? Infinity);\n case 'limits': return (a.tpm_limit ?? Infinity) - (b.tpm_limit ?? Infinity) || (a.rpm_limit ?? Infinity) - (b.rpm_limit ?? Infinity);\n case 'models': return (a.models ?? []).join(',').localeCompare((b.models ?? []).join(','));\n default: return 0;\n }\n}\n\nexport const KeysTable: React.FC<KeysTableProps> = ({\n keys,\n models,\n loading,\n onGenerateKeyClick,\n onUpdateKey,\n onBlockKey,\n onUnblockKey,\n onResetKeySpend,\n onDeleteKey,\n onPruneExpiredKeys,\n}) => {\n const [editingKey, setEditingKey] = useState<VirtualKey | null>(null);\n const [editForm, setEditForm] = useState<UpdateKeyRequest>({});\n const [editSubmitting, setEditSubmitting] = useState(false);\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 const [sortKey, setSortKey] = useState<SortKey>('created');\n const [sortDirection, setSortDirection] = useState<SortDirection>('desc');\n\n const handleSort = (nextSortKey: SortKey) => {\n if (sortKey === nextSortKey) {\n setSortDirection(current => current === 'asc' ? 'desc' : 'asc');\n } else {\n setSortKey(nextSortKey);\n setSortDirection('asc');\n }\n };\n\n const filteredKeys = useMemo(() => {\n let result = keys;\n if (filterText.trim()) {\n const q = filterText.toLowerCase();\n result = keys.filter(k =>\n (k.key_alias ?? '').toLowerCase().includes(q) ||\n k.models?.some(m => m.toLowerCase().includes(q)),\n );\n }\n return [...result].sort((a, b) => {\n const comparison = compareKeys(a, b, sortKey);\n return sortDirection === 'asc' ? comparison : -comparison;\n });\n }, [keys, filterText, sortKey, sortDirection]);\n\n const editSelectedModels = models.filter(m => (editForm.models || []).includes(m.model_name));\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 // eslint-disable-next-line no-console -- TODO: surface via a snackbar/alert instead of console-only\n console.error('Failed to update key:', error);\n } finally {\n setEditSubmitting(false);\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 // eslint-disable-next-line no-console -- TODO: surface via a snackbar/alert instead of console-only\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 const ctx = formatContextWindow(m.max_input_tokens, m.max_output_tokens);\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 {ctx && (\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ ml: 1 }}>\n {ctx}\n </Typography>\n )}\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 const renderTableBody = () => {\n if (loading) {\n return (\n <TableRow>\n <TableCell colSpan={8} sx={{ py: 2 }}>\n <Skeleton variant=\"rounded\" height={140} />\n </TableCell>\n </TableRow>\n );\n }\n if (filteredKeys.length === 0) {\n return (\n <TableRow>\n <TableCell colSpan={8}>\n {filterText ? (\n <EmptyState\n message=\"No keys match that filter\"\n hint=\"Try a different alias or model name.\"\n />\n ) : (\n <EmptyState\n message=\"No keys yet\"\n hint=\"Generate your first key to start calling models.\"\n action={\n <Button\n variant=\"contained\"\n color=\"primary\"\n size=\"small\"\n disableElevation\n startIcon={<Add />}\n onClick={onGenerateKeyClick}\n sx={{ mt: 1 }}\n >\n Generate Your First Key\n </Button>\n }\n />\n )}\n </TableCell>\n </TableRow>\n );\n }\n return filteredKeys.map((key) => {\n const keyId = key.token ?? key.key;\n const isBlocking = blockingKeyId === keyId;\n const keyModels = key.models ?? [];\n return (\n <TableRow\n key={keyId}\n sx={\n key.blocked\n ? theme => ({\n // A left rule reads as \"suspended\" without greying the row into\n // illegibility the way a full background tint does.\n boxShadow: `inset 3px 0 0 0 ${theme.palette.error.main}`,\n '& td': { color: theme.palette.text.secondary },\n })\n : undefined\n }\n >\n <TableCell>\n <Box display=\"flex\" alignItems=\"center\" gap={1} flexWrap=\"wrap\">\n <Typography variant=\"body2\">\n {key.key_alias || '\u2014'}\n </Typography>\n {key.blocked && <StatusPill label=\"Blocked\" tone=\"danger\" />}\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={theme => ({\n fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',\n fontSize: 12,\n bgcolor: alpha(theme.palette.text.primary, theme.palette.mode === 'dark' ? 0.08 : 0.05),\n px: 0.75,\n py: 0.375,\n borderRadius: '5px',\n })}\n >\n {shortKeyId(keyId)}\n </Typography>\n <IconButton\n size=\"small\"\n onClick={() => copyToClipboard(keyId)}\n title=\"Copy Key ID\"\n sx={quietIconButtonSx('accent')}\n >\n <ContentCopy sx={{ fontSize: 15 }} />\n </IconButton>\n </Box>\n </TableCell>\n <TableCell>\n <Typography variant=\"body2\" color=\"text.secondary\">{formatDate(key.created_at)}</Typography>\n </TableCell>\n <TableCell>\n <ExpiryCell 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\" color=\"text.secondary\" sx={{ fontVariantNumeric: 'tabular-nums' }}>\n {key.tpm_limit ?? '\u221E'} / {key.rpm_limit ?? '\u221E'}\n </Typography>\n </TableCell>\n <TableCell>\n {keyModels.length === 0 ? (\n <Typography variant=\"body2\" color=\"text.secondary\">All models</Typography>\n ) : (\n <Box display=\"flex\" gap={0.5} flexWrap=\"wrap\">\n {keyModels.slice(0, 2).map((model) => (\n <TagChip key={model} label={model} title={model} />\n ))}\n {keyModels.length > 2 && (\n <TagChip\n label={`+${keyModels.length - 2}`}\n mono={false}\n title={keyModels.slice(2).join(', ')}\n />\n )}\n </Box>\n )}\n </TableCell>\n <TableCell align=\"right\">\n <Box display=\"flex\" justifyContent=\"flex-end\" gap={0.25}>\n <IconButton\n size=\"small\"\n onClick={() => handleOpenEdit(key)}\n title=\"Edit key\"\n sx={quietIconButtonSx('accent')}\n >\n <Edit fontSize=\"small\" />\n </IconButton>\n <IconButton\n size=\"small\"\n onClick={() => handleToggleBlock(key)}\n disabled={isBlocking}\n title={key.blocked ? 'Unblock key' : 'Block key \u2014 suspends without revoking'}\n sx={quietIconButtonSx('warning')}\n >\n {keyBlockIcon(isBlocking, key.blocked)}\n </IconButton>\n <IconButton\n size=\"small\"\n onClick={() => setDeleteConfirmId(keyId)}\n title=\"Revoke key\"\n sx={quietIconButtonSx('danger')}\n >\n <Delete fontSize=\"small\" />\n </IconButton>\n </Box>\n </TableCell>\n </TableRow>\n );\n });\n };\n\n return (\n <>\n <SectionCard\n title=\"Virtual Keys\"\n subtitle={\n loading\n ? 'Loading\u2026'\n : `${filteredKeys.length}${filterText ? ` of ${keys.length}` : ''} key${filteredKeys.length === 1 ? '' : 's'}`\n }\n flush\n actions={\n <>\n <TextField\n size=\"small\"\n label=\"Search alias or model\"\n placeholder=\"Search 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\" color=\"disabled\" />\n </InputAdornment>\n ),\n }}\n />\n {expiredKeys.length > 0 && (\n <Button\n variant=\"outlined\"\n color=\"inherit\"\n startIcon={<Autorenew />}\n onClick={() => setPruneConfirmCount(expiredKeys.length)}\n sx={theme => ({\n color: theme.palette.text.secondary,\n borderColor: theme.palette.divider,\n '&:hover': {\n color: theme.palette.error.main,\n borderColor: alpha(theme.palette.error.main, 0.5),\n bgcolor: alpha(theme.palette.error.main, 0.06),\n },\n })}\n >\n Prune expired ({expiredKeys.length})\n </Button>\n )}\n <Button\n variant=\"contained\"\n color=\"primary\"\n disableElevation\n startIcon={<Add />}\n onClick={onGenerateKeyClick}\n >\n Generate New Key\n </Button>\n </>\n }\n >\n <TableContainer>\n <Table size=\"small\" sx={dataTableSx}>\n <TableHead>\n <TableRow>\n <TableCell sortDirection={sortKey === 'alias' ? sortDirection : false}>\n <TableSortLabel active={sortKey === 'alias'} direction={sortKey === 'alias' ? sortDirection : 'asc'} onClick={() => handleSort('alias')}>Alias</TableSortLabel>\n </TableCell>\n <TableCell>Key ID</TableCell>\n <TableCell sortDirection={sortKey === 'created' ? sortDirection : false}>\n <TableSortLabel active={sortKey === 'created'} direction={sortKey === 'created' ? sortDirection : 'asc'} onClick={() => handleSort('created')}>Created</TableSortLabel>\n </TableCell>\n <TableCell sortDirection={sortKey === 'expires' ? sortDirection : false}>\n <TableSortLabel active={sortKey === 'expires'} direction={sortKey === 'expires' ? sortDirection : 'asc'} onClick={() => handleSort('expires')}>Expires</TableSortLabel>\n </TableCell>\n <TableCell sortDirection={sortKey === 'budget' ? sortDirection : false}>\n <TableSortLabel active={sortKey === 'budget'} direction={sortKey === 'budget' ? sortDirection : 'asc'} onClick={() => handleSort('budget')}>Budget</TableSortLabel>\n </TableCell>\n <TableCell sortDirection={sortKey === 'limits' ? sortDirection : false}>\n <TableSortLabel active={sortKey === 'limits'} direction={sortKey === 'limits' ? sortDirection : 'asc'} onClick={() => handleSort('limits')}>TPM / RPM</TableSortLabel>\n </TableCell>\n <TableCell sortDirection={sortKey === 'models' ? sortDirection : false}>\n <TableSortLabel active={sortKey === 'models'} direction={sortKey === 'models' ? sortDirection : 'asc'} onClick={() => handleSort('models')}>Models</TableSortLabel>\n </TableCell>\n <TableCell align=\"right\">Actions</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {renderTableBody()}\n </TableBody>\n </Table>\n </TableContainer>\n </SectionCard>\n\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 helperText=\"Max tokens per minute this key can consume across all models. Leave blank for no limit.\"\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 helperText=\"Max requests per minute this key can make across all models. Leave blank for no limit.\"\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 {/* 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", "export const fmtUsd = (n: number) => `$${(n ?? 0).toFixed(n < 1 ? 4 : 2)}`;\nexport const fmtInt = (n: number) => (n ?? 0).toLocaleString();\n\n/**\n * Estimate how many tokens a USD budget buys at a given per-token price.\n * Returns null when the price is missing or non-positive.\n */\nexport const estimateTokensFromBudget = (budget: number, pricePerToken?: number): number | null => {\n if (!pricePerToken || pricePerToken <= 0 || !budget || budget <= 0) return null;\n return Math.floor(budget / pricePerToken);\n};\n", "import React, { useState, useEffect, useMemo } from 'react';\nimport Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport Dialog from '@mui/material/Dialog';\nimport DialogTitle from '@mui/material/DialogTitle';\nimport DialogContent from '@mui/material/DialogContent';\nimport DialogActions from '@mui/material/DialogActions';\nimport TextField from '@mui/material/TextField';\nimport MenuItem from '@mui/material/MenuItem';\nimport Button from '@mui/material/Button';\nimport IconButton from '@mui/material/IconButton';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport Autocomplete from '@mui/material/Autocomplete';\nimport Checkbox from '@mui/material/Checkbox';\nimport FormControlLabel from '@mui/material/FormControlLabel';\nimport Alert from '@mui/material/Alert';\nimport Accordion from '@mui/material/Accordion';\nimport AccordionSummary from '@mui/material/AccordionSummary';\nimport AccordionDetails from '@mui/material/AccordionDetails';\nimport Tabs from '@mui/material/Tabs';\nimport Tab from '@mui/material/Tab';\nimport { ContentCopy, Code, ExpandMore } from '@mui/icons-material';\nimport { VirtualKey, ModelInfo, TeamInfo, GenerateKeyRequest, GenerateKeyResponse, LiteLlmConfig } from '../types';\nimport { estimateTokensFromBudget, fmtInt } from '../format';\n\ninterface GenerateKeyDialogProps {\n open: boolean;\n onClose: () => void;\n keys: VirtualKey[];\n models: ModelInfo[];\n teams: TeamInfo[];\n /** Current user's LiteLLM user id, used to pre-fill a default key alias. */\n username?: string;\n /** Controls for the \"Generate New Key\" form; see litellm.keyGeneration in app-config.yaml. */\n keyGenerationSettings?: { allowUnlimitedBudget: boolean; teamRequired: boolean };\n onGenerateKey: (request: GenerateKeyRequest) => Promise<GenerateKeyResponse>;\n onGetConfig: () => Promise<LiteLlmConfig>;\n}\n\nconst generateDefaultAlias = (username?: string): string => {\n const base = (username || 'user')\n .split('@')[0]\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '') || 'user';\n const hash = Math.random().toString(36).slice(2, 8);\n return `${base}-${hash}`;\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\nfunction trimSlash(url: string): string {\n return url.replace(/\\/+$/, '');\n}\n\n// LiteLLM sentinel: a team's `models` list is `[\"all-proxy-models\"]` when the\n// team isn't restricted to specific models. A team's `models` entries can\n// also be access-group names (see litellm model_info.access_groups) rather\n// than literal model_name values. Treating either case as a literal\n// model_name allowlist matches nothing, which previously made the whole\n// \"Models\" field disappear for such teams.\nconst ALL_PROXY_MODELS = 'all-proxy-models';\n\nfunction isModelAllowedByTeam(model: ModelInfo, teamModels?: string[]): boolean {\n if (!teamModels || teamModels.length === 0) return true;\n if (teamModels.includes(ALL_PROXY_MODELS)) return true;\n if (teamModels.includes(model.model_name)) return true;\n return !!model.access_groups?.some(group => teamModels.includes(group));\n}\n\ninterface Snippets {\n curl: string;\n openai: string;\n opencode: string;\n pi: string;\n claudeCode: string;\n publicEndpoint: string;\n}\n\nfunction buildSnippets(baseUrl: string, key: string, model: string): Snippets {\n const base = trimSlash(baseUrl);\n const apiBase = `${base}/v1`;\n return {\n publicEndpoint: apiBase,\n curl: `curl ${apiBase}/chat/completions \\\\\n -H \"Authorization: Bearer ${key}\" \\\\\n -H \"Content-Type: application/json\" \\\\\n -d '{\n \"model\": \"${model}\",\n \"messages\": [{ \"role\": \"user\", \"content\": \"Hello!\" }]\n }'`,\n openai: `from openai import OpenAI\n\nclient = OpenAI(\n api_key=\"${key}\",\n base_url=\"${apiBase}\",\n)\n\nresponse = client.chat.completions.create(\n model=\"${model}\",\n messages=[{ \"role\": \"user\", \"content\": \"Hello!\" }],\n)\nprint(response.choices[0].message.content)`,\n opencode: `{\n \"$schema\": \"https://opencode.ai/config.json\",\n \"provider\": {\n \"litellm\": {\n \"npm\": \"@ai-sdk/openai-compatible\",\n \"name\": \"LiteLLM\",\n \"options\": {\n \"baseURL\": \"${apiBase}\",\n \"apiKey\": \"${key}\"\n },\n \"models\": {\n \"${model}\": {}\n }\n }\n }\n}`,\n pi: `{\n \"litellm\": {\n \"baseUrl\": \"${apiBase}\",\n \"apiKey\": \"${key}\",\n \"api\": \"openai-completions\",\n \"models\": [\n { \"id\": \"${model}\", \"name\": \"${model}\" }\n ]\n }\n}`,\n claudeCode: `# Option 1 \u2014 Static key (Method 1: Unified Endpoint)\nexport ANTHROPIC_AUTH_TOKEN=\"${key}\"\nexport ANTHROPIC_BASE_URL=\"${base}\"\nclaude --model ${model}\n\n# Option 2 \u2014 Dynamic key via helper script\n# 1. Create ~/bin/get-litellm-key.sh:\ncat > ~/bin/get-litellm-key.sh << 'SCRIPT'\n#!/bin/bash\ncurl -s -X POST ${base}/key/generate \\\\\n -H \"Authorization: Bearer ${key}\" \\\\\n -H \"Content-Type: application/json\" \\\\\n -d '{}' | jq -r '.key'\nSCRIPT\nchmod +x ~/bin/get-litellm-key.sh\n\n# 2. Add to ~/.claude/settings.json:\n# { \"apiKeyHelper\": \"~/bin/get-litellm-key.sh\" }\n\n# 3. Set refresh interval (optional, default 1h):\nexport CLAUDE_CODE_API_KEY_HELPER_TTL_MS=3600000`,\n };\n}\n\nfunction aliasHelperText(aliasError: boolean, aliasDuplicate: boolean): string | undefined {\n if (aliasError) return 'Alias is required';\n if (aliasDuplicate) return 'This alias is already used by one of your keys \u2014 LiteLLM requires aliases to be unique across all keys';\n return undefined;\n}\n\nfunction teamHelperText(teamError: boolean, teamRequired: boolean): string {\n if (teamError) return 'Team is required';\n if (teamRequired) return 'Bind this key to a team for scoped access';\n return 'Optional: bind this key to a specific team for scoped access';\n}\n\nfunction budgetHelperText(budgetInvalid: boolean, budgetEstimate: number | null): string | undefined {\n if (budgetInvalid) return 'Enter a positive budget or tick \"Unlimited\"';\n if (budgetEstimate !== null) return `\u2248 ${fmtInt(budgetEstimate)} tokens at the selected model's rate`;\n return undefined;\n}\n\ninterface SnippetTabsProps {\n snippets: Snippets;\n model: string;\n onCopy: (text: string) => void;\n}\n\ntype SnippetTab = 'curl' | 'openai' | 'opencode' | 'pi' | 'claude-code';\n\nconst SNIPPET_FILE_HINTS: Partial<Record<SnippetTab, string>> = {\n opencode: 'Add to ~/.config/opencode/opencode.json',\n pi: 'Add to ~/.pi/agent/models.json',\n 'claude-code': 'Requires Claude Code CLI installed',\n};\n\nconst SnippetTabs: React.FC<SnippetTabsProps> = ({ snippets, model, onCopy }) => {\n const [tab, setTab] = useState<SnippetTab>('curl');\n const snippetKey = tab === 'claude-code' ? 'claudeCode' : tab;\n const code = snippets[snippetKey as keyof Snippets];\n const fileHint = SNIPPET_FILE_HINTS[tab];\n return (\n <Box>\n <Tabs value={tab} onChange={(_, v) => setTab(v as SnippetTab)} sx={{ mb: 1 }} variant=\"scrollable\">\n <Tab label=\"curl\" value=\"curl\" />\n <Tab label=\"OpenAI SDK\" value=\"openai\" />\n <Tab label=\"opencode\" value=\"opencode\" />\n <Tab label=\"pi\" value=\"pi\" />\n <Tab label=\"Claude Code\" value=\"claude-code\" />\n </Tabs>\n {fileHint && (\n <Typography variant=\"caption\" color=\"text.secondary\" display=\"block\" mb={0.5}>\n {fileHint}\n </Typography>\n )}\n <Box\n position=\"relative\"\n p={1.5}\n sx={{ backgroundColor: 'action.hover', border: '1px solid', borderColor: 'divider', borderRadius: 1 }}\n >\n <IconButton\n size=\"small\"\n onClick={() => onCopy(code)}\n title=\"Copy snippet\"\n sx={{ position: 'absolute', top: 4, right: 4 }}\n >\n <ContentCopy fontSize=\"small\" />\n </IconButton>\n <Typography\n component=\"pre\"\n sx={{\n fontFamily: 'monospace',\n fontSize: 12,\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-all',\n mb: 0,\n pr: 4,\n }}\n >\n {code}\n </Typography>\n {model && (\n <Typography variant=\"caption\" color=\"text.secondary\" display=\"block\" mt={1}>\n Using model \u201C{model}\u201D \u2014 swap it for any model you have access to.\n </Typography>\n )}\n </Box>\n </Box>\n );\n};\n\nexport const GenerateKeyDialog: React.FC<GenerateKeyDialogProps> = ({\n open,\n onClose,\n keys,\n models,\n teams,\n username,\n keyGenerationSettings,\n onGenerateKey,\n onGetConfig,\n}) => {\n const [formData, setFormData] = useState<GenerateKeyRequest>(emptyForm());\n const [unlimitedBudget, setUnlimitedBudget] = useState(false);\n const [submitting, setSubmitting] = useState(false);\n const [newKeyValue, setNewKeyValue] = useState<string | null>(null);\n const [newKeySnippets, setNewKeySnippets] = useState<Snippets | null>(null);\n const [newKeyModel, setNewKeyModel] = useState<string>('');\n const [generateError, setGenerateError] = useState<string | null>(null);\n\n // Re-arm the form each time the dialog opens so a stale result from a\n // previous run (or another user's session) is never shown.\n useEffect(() => {\n if (open) {\n setFormData({ ...emptyForm(), alias: generateDefaultAlias(username) });\n setUnlimitedBudget(false);\n setNewKeyValue(null);\n setNewKeySnippets(null);\n setNewKeyModel('');\n setGenerateError(null);\n }\n }, [open, username]);\n\n const allowUnlimitedBudget = keyGenerationSettings?.allowUnlimitedBudget ?? false;\n const teamRequired = keyGenerationSettings?.teamRequired ?? true;\n\n const selectedTeam = teams.find(t => t.team_id === formData.team_id) ?? null;\n\n // Once a team is selected, only offer models that team is actually allowed\n // to use \u2014 `models` here is already scoped to what the user can access.\n const availableModels = useMemo(() => {\n return models.filter(m => isModelAllowedByTeam(m, selectedTeam?.models));\n }, [models, selectedTeam]);\n\n const selectedModels = availableModels.filter(m => (formData.models || []).includes(m.model_name));\n\n // \u2500\u2500 Inline form validation \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 aliasError = !(formData.alias || '').trim();\n const teamError = teamRequired && !formData.team_id;\n const budgetInvalid =\n !unlimitedBudget &&\n (formData.max_budget === undefined ||\n formData.max_budget === null ||\n formData.max_budget <= 0);\n const canGenerate = !aliasError && !teamError && !budgetInvalid && !submitting;\n\n // Issue #35: warn (don't block) when the alias already matches one of the\n // user's loaded keys \u2014 LiteLLM enforces globally-unique aliases.\n const aliasDuplicate = !!formData.alias && keys.some(k => k.key_alias === formData.alias);\n\n // \u2500\u2500 Budget estimate at the selected model's input rate \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const budgetEstimate = useMemo(() => {\n if (unlimitedBudget || budgetInvalid) return null;\n const inputCosts = selectedModels\n .map(m => m.input_cost_per_token)\n .filter((c): c is number => typeof c === 'number' && c > 0);\n if (inputCosts.length === 0) return null;\n const pricePerToken = Math.max(...inputCosts);\n return estimateTokensFromBudget(formData.max_budget ?? 0, pricePerToken);\n }, [formData.max_budget, selectedModels, unlimitedBudget, budgetInvalid]);\n\n const handleGenerate = async () => {\n setSubmitting(true);\n setGenerateError(null);\n try {\n const request: GenerateKeyRequest = {\n ...formData,\n max_budget: unlimitedBudget ? null : formData.max_budget,\n };\n const response = await onGenerateKey(request);\n // When the key allows all models (none explicitly picked), fall back to\n // the first model actually allowed for the chosen team so snippets show\n // a working example rather than an empty model name.\n const model = formData.models?.[0] ?? availableModels[0]?.model_name ?? '';\n setNewKeyValue(response.key);\n setNewKeyModel(model);\n setNewKeySnippets(null);\n try {\n const config = await onGetConfig();\n setNewKeySnippets(buildSnippets(config.baseUrl, response.key, model));\n } catch {\n // Snippets are a nice-to-have; the raw key is still shown.\n }\n setFormData(emptyForm());\n setUnlimitedBudget(false);\n } catch (error: any) {\n setGenerateError(error?.message ?? 'Failed to generate key');\n } finally {\n setSubmitting(false);\n }\n };\n\n const handleClose = () => {\n onClose();\n setGenerateError(null);\n setNewKeyValue(null);\n setNewKeySnippets(null);\n setFormData(emptyForm());\n setUnlimitedBudget(false);\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 const ctx = formatContextWindow(m.max_input_tokens, m.max_output_tokens);\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 {ctx && (\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ ml: 1 }}>\n {ctx}\n </Typography>\n )}\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 const renderTeamField = () => {\n if (teams.length > 0) {\n return (\n <Autocomplete\n options={teams}\n getOptionLabel={t => t.team_alias || t.team_id}\n value={selectedTeam}\n onChange={(_e, team) => {\n const restrictedModels = (formData.models || []).filter(name => {\n const model = models.find(m => m.model_name === name);\n return model ? isModelAllowedByTeam(model, team?.models) : false;\n });\n setFormData({ ...formData, team_id: team?.team_id, models: restrictedModels });\n }}\n renderInput={params => (\n <TextField\n {...params}\n label=\"Team\"\n error={teamError}\n helperText={teamHelperText(teamError, teamRequired)}\n required={teamRequired}\n fullWidth\n />\n )}\n />\n );\n }\n if (teamRequired) {\n return (\n <Typography variant=\"body2\" color=\"error\">\n Team selection is required, but you don't belong to any team yet \u2014 contact your administrator.\n </Typography>\n );\n }\n return null;\n };\n\n return (\n <Dialog open={open} onClose={handleClose} 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\n {newKeySnippets && (\n <Box mt={2}>\n <Typography variant=\"caption\" color=\"text.secondary\" display=\"block\" gutterBottom>\n Public endpoint \u2014 paste into any tool's base URL / API base field\n </Typography>\n <Box\n display=\"flex\"\n alignItems=\"center\"\n gap={1}\n p={1.5}\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', fontSize: 13, wordBreak: 'break-all', flex: 1 }}\n >\n {newKeySnippets.publicEndpoint}\n </Typography>\n <IconButton size=\"small\" onClick={() => copyToClipboard(newKeySnippets.publicEndpoint)}>\n <ContentCopy fontSize=\"small\" />\n </IconButton>\n </Box>\n </Box>\n )}\n\n {newKeySnippets && (\n <Box mt={3}>\n <Box display=\"flex\" alignItems=\"center\" gap={1} mb={1}>\n <Code fontSize=\"small\" color=\"action\" />\n <Typography variant=\"subtitle2\">\n Start calling the proxy \u2014 paste and run\n </Typography>\n </Box>\n <SnippetTabs snippets={newKeySnippets} model={newKeyModel} onCopy={copyToClipboard} />\n </Box>\n )}\n </Box>\n ) : (\n <Box display=\"flex\" flexDirection=\"column\" gap={2} mt={1}>\n {generateError && (\n <Alert severity=\"error\" onClose={() => setGenerateError(null)}>\n {generateError}\n </Alert>\n )}\n <TextField\n label=\"Alias\"\n value={formData.alias || ''}\n onChange={(e) => {\n setFormData({ ...formData, alias: e.target.value });\n setGenerateError(null);\n }}\n error={aliasError}\n color={aliasDuplicate ? 'warning' : undefined}\n helperText={aliasHelperText(aliasError, aliasDuplicate)}\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 {renderTeamField()}\n\n {availableModels.length > 0 && (\n <Autocomplete\n multiple\n options={availableModels}\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\n {...params}\n label=\"Models\"\n helperText={\n selectedTeam\n ? 'Leave empty to allow all models available to this team'\n : 'Leave empty to allow all models'\n }\n fullWidth\n />\n )}\n />\n )}\n\n {allowUnlimitedBudget && (\n <FormControlLabel\n control={\n <Checkbox\n checked={unlimitedBudget}\n onChange={(e) => {\n setUnlimitedBudget(e.target.checked);\n if (e.target.checked) {\n setFormData({ ...formData, max_budget: null });\n } else {\n setFormData({ ...formData, max_budget: 100 });\n }\n }}\n />\n }\n label=\"Unlimited budget\"\n />\n )}\n <TextField\n label=\"Max Budget (USD)\"\n type=\"number\"\n value={unlimitedBudget ? '' : formData.max_budget ?? ''}\n onChange={(e) =>\n setFormData({ ...formData, max_budget: e.target.value ? Number(e.target.value) : undefined })\n }\n error={budgetInvalid}\n helperText={budgetHelperText(budgetInvalid, budgetEstimate)}\n disabled={unlimitedBudget}\n required\n fullWidth\n />\n <Accordion disableGutters elevation={0} sx={{ border: '1px solid', borderColor: 'divider', '&:before': { display: 'none' } }}>\n <AccordionSummary expandIcon={<ExpandMore />}>\n <Typography variant=\"body2\" fontWeight={600}>Advanced</Typography>\n </AccordionSummary>\n <AccordionDetails sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>\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 helperText=\"Max tokens per minute this key can consume across all models. Leave blank for no limit.\"\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 helperText=\"Max requests per minute this key can make across all models. Leave blank for no limit.\"\n fullWidth\n />\n </AccordionDetails>\n </Accordion>\n </Box>\n )}\n </DialogContent>\n <DialogActions>\n {newKeyValue ? (\n <Button onClick={handleClose} variant=\"contained\" color=\"success\">\n Done\n </Button>\n ) : (\n <>\n <Button onClick={handleClose}>Cancel</Button>\n <Button\n onClick={handleGenerate}\n variant=\"contained\"\n color=\"primary\"\n disabled={!canGenerate}\n >\n {submitting ? <CircularProgress size={24} /> : 'Generate'}\n </Button>\n </>\n )}\n </DialogActions>\n </Dialog>\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\nfunction formatContextWindow(\n maxInput?: number,\n maxOutput?: number,\n): string | null {\n if (!maxInput && !maxOutput) return null;\n const fmt = (n?: number) => {\n if (!n) return null;\n if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\n if (n >= 1_000) return `${Math.round(n / 1000)}K`;\n return String(n);\n };\n const inPart = fmt(maxInput);\n const outPart = fmt(maxOutput);\n if (inPart && outPart) return `ctx ${inPart} in / ${outPart} out`;\n if (inPart) return `ctx ${inPart}`;\n if (outPart) return `ctx ${outPart} out`;\n return null;\n}\n", "import React, { FC, useState, useEffect, useMemo } from 'react';\nimport Dialog from '@mui/material/Dialog';\nimport DialogTitle from '@mui/material/DialogTitle';\nimport DialogContent from '@mui/material/DialogContent';\nimport DialogActions from '@mui/material/DialogActions';\nimport TextField from '@mui/material/TextField';\nimport Button from '@mui/material/Button';\nimport Alert from '@mui/material/Alert';\nimport Checkbox from '@mui/material/Checkbox';\nimport FormControlLabel from '@mui/material/FormControlLabel';\nimport Autocomplete from '@mui/material/Autocomplete';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport MenuItem from '@mui/material/MenuItem';\nimport Box from '@mui/material/Box';\nimport Divider from '@mui/material/Divider';\nimport Typography from '@mui/material/Typography';\nimport IconButton from '@mui/material/IconButton';\nimport Paper from '@mui/material/Paper';\nimport Table from '@mui/material/Table';\nimport TableBody from '@mui/material/TableBody';\nimport TableCell from '@mui/material/TableCell';\nimport TableContainer from '@mui/material/TableContainer';\nimport TableHead from '@mui/material/TableHead';\nimport TableRow from '@mui/material/TableRow';\nimport { Delete as DeleteIcon } from '@mui/icons-material';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { catalogApiRef } from '@backstage/plugin-catalog-react';\nimport { stringifyEntityRef, UserEntity } from '@backstage/catalog-model';\nimport { useAsync } from 'react-use';\nimport { TeamInfo, ModelInfo, LiteLlmConfig, CreateTeamRequest, UpdateTeamRequest, VectorStoreInfo, McpServerInfo } from '../types';\nimport { StatusPill, dataTableSx } from './ui';\n\n/** A catalog User entity flattened into what the member picker needs. */\ninterface UserOption {\n ref: string;\n label: string;\n email?: string;\n}\n\n/** Spend-reset periods offered for a team budget (LiteLLM `budget_duration`). */\nconst BUDGET_DURATION_OPTIONS: Array<{ value: string; label: string }> = [\n { value: '1d', label: 'Daily (1d)' },\n { value: '7d', label: 'Weekly (7d)' },\n { value: '30d', label: 'Monthly (30d)' },\n { value: '90d', label: 'Quarterly (90d)' },\n { value: '365d', label: 'Yearly (365d)' },\n];\nconst DEFAULT_BUDGET_DURATION = '30d';\nconst FALLBACK_BUDGET_CEILING = 1000;\n\ninterface ManageTeamDialogProps {\n open: boolean;\n onClose: () => void;\n mode: 'create' | 'edit';\n team?: TeamInfo;\n allModels: ModelInfo[];\n config?: LiteLlmConfig;\n onSubmit: (payload: CreateTeamRequest | UpdateTeamRequest) => Promise<void>;\n /** When true, the Members section (edit mode only) exposes add/remove controls. */\n canManageMembers?: boolean;\n /** Called to add a member; the parent is expected to refresh `team` on success. */\n onAddMember?: (userEntityRef: string, maxBudgetInTeam?: number) => Promise<void>;\n /** Called to remove a member; the parent is expected to refresh `team` on success. */\n onRemoveMember?: (userEntityRef: string) => Promise<void>;\n /** When true, the Knowledge Bases section (edit mode only) is shown. */\n canManageKnowledgeBases?: boolean;\n /** Vector stores the caller may attach (already allowlist-filtered server-side). */\n vectorStores?: VectorStoreInfo[];\n /** Called to replace the team's attached knowledge bases; parent refreshes `team`. */\n onSaveKnowledgeBases?: (vectorStoreIds: string[]) => Promise<void>;\n /** When true, the MCP Servers section (edit mode only) is shown. */\n canManageMcpServers?: boolean;\n /** MCP servers the caller may attach (already allowlist-filtered server-side). */\n mcpServers?: McpServerInfo[];\n /** Called to replace the team's attached MCP servers; parent refreshes `team`. */\n onSaveMcpServers?: (mcpServerIds: string[]) => Promise<void>;\n}\n\nexport const ManageTeamDialog: FC<ManageTeamDialogProps> = ({\n open,\n onClose,\n mode,\n team,\n allModels,\n config,\n onSubmit,\n canManageMembers,\n onAddMember,\n onRemoveMember,\n canManageKnowledgeBases,\n vectorStores,\n onSaveKnowledgeBases,\n canManageMcpServers,\n mcpServers,\n onSaveMcpServers,\n}) => {\n const [alias, setAlias] = useState('');\n const [models, setModels] = useState<string[]>([]);\n const [maxBudget, setMaxBudget] = useState<string>('');\n const [unlimited, setUnlimited] = useState(false);\n const [budgetDuration, setBudgetDuration] = useState('');\n const [submitting, setSubmitting] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n // memberQuery is the text shown in the picker; memberRef is the entity ref\n // that will actually be submitted (either a picked catalog user's ref, or\n // whatever was typed, as a fallback for catalog lookup failures).\n const [memberQuery, setMemberQuery] = useState('');\n const [memberRef, setMemberRef] = useState('');\n const [memberBudget, setMemberBudget] = useState('');\n const [memberBusy, setMemberBusy] = useState(false);\n const [memberError, setMemberError] = useState<string | null>(null);\n\n const [kbIds, setKbIds] = useState<string[]>([]);\n const [kbBusy, setKbBusy] = useState(false);\n const [kbError, setKbError] = useState<string | null>(null);\n\n const [mcpIds, setMcpIds] = useState<string[]>([]);\n const [mcpBusy, setMcpBusy] = useState(false);\n const [mcpError, setMcpError] = useState<string | null>(null);\n\n const allowUnlimitedBudget = config?.teamManagement?.allowUnlimitedBudget ?? false;\n const maxBudgetCeiling =\n config?.teamManagement?.maxBudgetCeiling ?? FALLBACK_BUDGET_CEILING;\n\n const members = useMemo(() => team?.members_with_roles ?? [], [team]);\n const showMembers = mode === 'edit' && !!canManageMembers;\n\n // Catalog users for the member picker, fetched only while the Members\n // section is actually visible. Failures degrade to an empty option list \u2014\n // the field stays usable as a plain entity-ref input either way.\n const catalogApi = useApi(catalogApiRef);\n const { value: catalogUsers, loading: usersLoading } = useAsync(async () => {\n if (!open || !showMembers) return [] as UserEntity[];\n try {\n const { items } = await catalogApi.getEntities({\n filter: { kind: 'User' },\n fields: ['kind', 'metadata.namespace', 'metadata.name', 'metadata.title', 'spec.profile'],\n });\n return items as UserEntity[];\n } catch {\n return [] as UserEntity[];\n }\n }, [open, showMembers, catalogApi]);\n\n const userOptions = useMemo<UserOption[]>(() => {\n const existingEmails = new Set(\n members\n .map(m => m.user_email?.toLowerCase())\n .filter((e): e is string => !!e),\n );\n return (catalogUsers ?? [])\n .map(e => {\n const ref = stringifyEntityRef(e);\n const displayName =\n e.spec?.profile?.displayName || e.metadata.title || e.metadata.name;\n const email = e.spec?.profile?.email;\n return {\n ref,\n email,\n label: email ? `${displayName} (${email})` : displayName,\n };\n })\n .filter(o => !(o.email && existingEmails.has(o.email.toLowerCase())))\n .sort((a, b) => a.label.localeCompare(b.label));\n }, [catalogUsers, members]);\n\n useEffect(() => {\n if (open) {\n if (mode === 'edit' && team) {\n setAlias(team.team_alias ?? '');\n setModels(team.models ?? []);\n setMaxBudget(\n team.max_budget ? String(team.max_budget) : String(maxBudgetCeiling),\n );\n setUnlimited(allowUnlimitedBudget && !team.max_budget);\n setBudgetDuration(team.budget_duration ?? DEFAULT_BUDGET_DURATION);\n } else {\n setAlias('');\n setModels([]);\n // Default a new team's budget to the ceiling; the admin can lower it.\n setMaxBudget(String(maxBudgetCeiling));\n setUnlimited(allowUnlimitedBudget);\n setBudgetDuration(DEFAULT_BUDGET_DURATION);\n }\n setError(null);\n setMemberQuery('');\n setMemberRef('');\n setMemberBudget('');\n setMemberError(null);\n setKbIds(team?.object_permission?.vector_stores ?? []);\n setKbError(null);\n setMcpIds(team?.object_permission?.mcp_servers ?? []);\n setMcpError(null);\n }\n }, [open, mode, team, allowUnlimitedBudget, maxBudgetCeiling]);\n\n const handleSubmit = async () => {\n setError(null);\n\n if (!alias.trim()) {\n setError('Team alias is required');\n return;\n }\n\n if (models.length === 0) {\n setError('At least one model is required');\n return;\n }\n\n if (!unlimited) {\n if (!maxBudget) {\n setError('Budget is required when unlimited budgets are disabled');\n return;\n }\n const budget = parseFloat(maxBudget);\n if (isNaN(budget) || budget <= 0) {\n setError('Budget must be a positive number');\n return;\n }\n if (budget > maxBudgetCeiling) {\n setError(`Budget cannot exceed $${maxBudgetCeiling}`);\n return;\n }\n }\n\n try {\n setSubmitting(true);\n let payload: CreateTeamRequest | UpdateTeamRequest;\n\n if (mode === 'create') {\n payload = {\n team_alias: alias.trim(),\n models,\n ...(unlimited ? { max_budget: null } : { max_budget: parseFloat(maxBudget) }),\n ...(budgetDuration && { budget_duration: budgetDuration }),\n } as CreateTeamRequest;\n } else {\n payload = {\n team_alias: alias.trim(),\n models,\n ...(unlimited ? { max_budget: null } : { max_budget: parseFloat(maxBudget) }),\n ...(budgetDuration && { budget_duration: budgetDuration }),\n } as UpdateTeamRequest;\n }\n\n await onSubmit(payload);\n onClose();\n } catch (err) {\n setError(err instanceof Error ? err.message : 'An error occurred');\n } finally {\n setSubmitting(false);\n }\n };\n\n const handleAddMember = async () => {\n if (!onAddMember || !memberRef.trim()) return;\n setMemberError(null);\n const budget = memberBudget ? parseFloat(memberBudget) : undefined;\n if (budget !== undefined && (isNaN(budget) || budget <= 0)) {\n setMemberError('Max budget in team must be a positive number');\n return;\n }\n try {\n setMemberBusy(true);\n await onAddMember(memberRef.trim(), budget);\n setMemberQuery('');\n setMemberRef('');\n setMemberBudget('');\n } catch (err) {\n setMemberError(err instanceof Error ? err.message : 'Failed to add member');\n } finally {\n setMemberBusy(false);\n }\n };\n\n const handleRemoveMember = async (userId: string) => {\n if (!onRemoveMember) return;\n setMemberError(null);\n try {\n setMemberBusy(true);\n await onRemoveMember(userId);\n } catch (err) {\n setMemberError(err instanceof Error ? err.message : 'Failed to remove member');\n } finally {\n setMemberBusy(false);\n }\n };\n\n const handleSaveKnowledgeBases = async () => {\n if (!onSaveKnowledgeBases) return;\n setKbError(null);\n try {\n setKbBusy(true);\n await onSaveKnowledgeBases(kbIds);\n } catch (err) {\n setKbError(err instanceof Error ? err.message : 'Failed to save knowledge bases');\n } finally {\n setKbBusy(false);\n }\n };\n\n const handleSaveMcpServers = async () => {\n if (!onSaveMcpServers) return;\n setMcpError(null);\n try {\n setMcpBusy(true);\n await onSaveMcpServers(mcpIds);\n } catch (err) {\n setMcpError(err instanceof Error ? err.message : 'Failed to save MCP servers');\n } finally {\n setMcpBusy(false);\n }\n };\n\n const modelNames = allModels.map(m => m.model_name);\n // Keep an unusual existing value (e.g. \"14d\", \"1mo\") selectable so editing a\n // team doesn't silently rewrite its duration.\n const durationOptions = BUDGET_DURATION_OPTIONS.some(o => o.value === budgetDuration)\n ? BUDGET_DURATION_OPTIONS\n : [...BUDGET_DURATION_OPTIONS, { value: budgetDuration, label: budgetDuration }];\n const showKnowledgeBases = mode === 'edit' && !!canManageKnowledgeBases;\n const kbOptions = (vectorStores ?? []).map(v => v.id);\n const kbLabel = (id: string) =>\n (vectorStores ?? []).find(v => v.id === id)?.name ?? id;\n const showMcpServers = mode === 'edit' && !!canManageMcpServers;\n const mcpOptions = (mcpServers ?? []).map(s => s.id);\n const mcpLabel = (id: string) =>\n (mcpServers ?? []).find(s => s.id === id)?.name ?? id;\n\n return (\n <Dialog open={open} onClose={onClose} maxWidth=\"sm\" fullWidth>\n <DialogTitle>{mode === 'create' ? 'Create Team' : 'Edit Team'}</DialogTitle>\n <DialogContent sx={{ pt: 2, display: 'flex', flexDirection: 'column', gap: 2 }}>\n {error && <Alert severity=\"error\">{error}</Alert>}\n\n <TextField\n label=\"Team Alias\"\n value={alias}\n onChange={e => setAlias(e.target.value)}\n disabled={submitting}\n fullWidth\n />\n\n <Autocomplete\n multiple\n options={modelNames}\n value={models}\n onChange={(_, newValue) => setModels(newValue)}\n disabled={submitting}\n renderInput={params => (\n <TextField\n {...params}\n label=\"Models\"\n required\n helperText=\"At least one model is required here \u2014 this delegated flow only grants access to models your admin has allow-listed for team creation, not every proxy model. (Teams with no model restriction shown elsewhere were configured directly in LiteLLM.)\"\n />\n )}\n />\n\n <TextField\n label=\"Max Budget ($)\"\n type=\"number\"\n value={maxBudget}\n onChange={e => setMaxBudget(e.target.value)}\n disabled={submitting || unlimited}\n inputProps={{ min: 0, max: maxBudgetCeiling }}\n helperText={`Maximum: $${maxBudgetCeiling}`}\n fullWidth\n />\n\n {allowUnlimitedBudget && (\n <FormControlLabel\n control={<Checkbox checked={unlimited} onChange={e => setUnlimited(e.target.checked)} disabled={submitting} />}\n label=\"Unlimited Budget\"\n />\n )}\n\n <TextField\n select\n label=\"Budget Duration\"\n value={budgetDuration}\n onChange={e => setBudgetDuration(e.target.value)}\n disabled={submitting || unlimited}\n helperText=\"Spend-reset period for the team budget\"\n fullWidth\n >\n {durationOptions.map(o => (\n <MenuItem key={o.value} value={o.value}>\n {o.label}\n </MenuItem>\n ))}\n </TextField>\n\n {showMembers && (\n <Box>\n <Divider sx={{ my: 1 }} />\n <Typography variant=\"subtitle2\" sx={{ mb: 1 }}>\n Members\n </Typography>\n {memberError && (\n <Alert severity=\"error\" sx={{ mb: 1 }} onClose={() => setMemberError(null)}>\n {memberError}\n </Alert>\n )}\n {members.length === 0 ? (\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ mb: 1 }}>\n No members yet.\n </Typography>\n ) : (\n <TableContainer component={Paper} variant=\"outlined\" sx={{ borderRadius: 1.5, mb: 1.5 }}>\n <Table size=\"small\" sx={dataTableSx}>\n <TableHead>\n <TableRow>\n <TableCell>User</TableCell>\n <TableCell align=\"right\">Role</TableCell>\n <TableCell align=\"right\" sx={{ width: 40 }} />\n </TableRow>\n </TableHead>\n <TableBody>\n {members.map(m => (\n <TableRow key={m.user_id}>\n <TableCell>\n {m.user_email ? (\n <>\n <Typography variant=\"body2\">{m.user_email}</Typography>\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n sx={{ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace', fontSize: 11 }}\n >\n {m.user_id}\n </Typography>\n </>\n ) : (\n <Typography\n variant=\"body2\"\n sx={{ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace' }}\n >\n {m.user_id}\n </Typography>\n )}\n </TableCell>\n <TableCell align=\"right\">\n <StatusPill label={m.role} tone={m.role === 'admin' ? 'accent' : 'neutral'} dot={false} />\n </TableCell>\n <TableCell align=\"right\">\n <IconButton\n edge=\"end\"\n size=\"small\"\n aria-label={`remove ${m.user_id}`}\n disabled={memberBusy}\n onClick={() => handleRemoveMember(m.user_id)}\n >\n <DeleteIcon fontSize=\"small\" />\n </IconButton>\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </TableContainer>\n )}\n <Box sx={{ display: 'flex', gap: 1, alignItems: 'flex-start', flexWrap: 'wrap' }}>\n <Autocomplete\n freeSolo\n autoHighlight\n options={userOptions}\n loading={usersLoading}\n inputValue={memberQuery}\n onInputChange={(_, newInputValue, reason) => {\n setMemberQuery(newInputValue);\n // 'reset' fires when a selection sets the input programmatically \u2014\n // memberRef is already set by onChange in that case, so only sync\n // free typing (and clearing) back into the submitted ref here.\n if (reason === 'input' || reason === 'clear') {\n setMemberRef(newInputValue);\n }\n }}\n onChange={(_, newValue) => {\n if (newValue && typeof newValue !== 'string') {\n setMemberQuery(newValue.label);\n setMemberRef(newValue.ref);\n }\n }}\n getOptionLabel={o => (typeof o === 'string' ? o : o.label)}\n isOptionEqualToValue={(o, v) => o.ref === (typeof v === 'string' ? v : v.ref)}\n disabled={memberBusy}\n sx={{ flex: 1, minWidth: 260 }}\n renderInput={params => (\n <TextField\n {...params}\n label=\"Add member\"\n placeholder=\"Search by name or email\u2026\"\n size=\"small\"\n helperText=\"Pick a catalog user, or paste a user entity ref\"\n InputProps={{\n ...params.InputProps,\n endAdornment: (\n <>\n {usersLoading ? <CircularProgress color=\"inherit\" size={14} /> : null}\n {params.InputProps.endAdornment}\n </>\n ),\n }}\n />\n )}\n />\n <TextField\n label=\"Max budget in team ($)\"\n type=\"number\"\n value={memberBudget}\n onChange={e => setMemberBudget(e.target.value)}\n disabled={memberBusy}\n size=\"small\"\n sx={{ width: 160 }}\n />\n <Button\n onClick={handleAddMember}\n disabled={memberBusy || !memberRef.trim()}\n variant=\"outlined\"\n sx={{ mt: 0.5 }}\n >\n Add\n </Button>\n </Box>\n </Box>\n )}\n\n {showKnowledgeBases && (\n <Box>\n <Divider sx={{ my: 1 }} />\n <Typography variant=\"subtitle2\" sx={{ mb: 1 }}>\n Knowledge Bases\n </Typography>\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ mb: 1 }}>\n Attaching a knowledge base exposes its documents to every key in\n this team.\n </Typography>\n {kbError && (\n <Alert severity=\"error\" sx={{ mb: 1 }} onClose={() => setKbError(null)}>\n {kbError}\n </Alert>\n )}\n <Autocomplete\n multiple\n options={kbOptions}\n value={kbIds}\n getOptionLabel={kbLabel}\n onChange={(_, v) => setKbIds(v)}\n disabled={kbBusy}\n renderInput={params => (\n <TextField {...params} label=\"Attached knowledge bases\" />\n )}\n />\n <Box sx={{ display: 'flex', justifyContent: 'flex-end', mt: 1 }}>\n <Button\n onClick={handleSaveKnowledgeBases}\n disabled={kbBusy}\n variant=\"outlined\"\n >\n {kbBusy ? 'Saving\u2026' : 'Save knowledge bases'}\n </Button>\n </Box>\n </Box>\n )}\n\n {showMcpServers && (\n <Box>\n <Divider sx={{ my: 1 }} />\n <Typography variant=\"subtitle2\" sx={{ mb: 1 }}>\n MCP Servers\n </Typography>\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ mb: 1 }}>\n Attaching an MCP server lets every key in this team invoke that\n server's tools through the model \u2014 including any side effects\n those tools have.\n </Typography>\n {mcpError && (\n <Alert severity=\"error\" sx={{ mb: 1 }} onClose={() => setMcpError(null)}>\n {mcpError}\n </Alert>\n )}\n <Autocomplete\n multiple\n options={mcpOptions}\n value={mcpIds}\n getOptionLabel={mcpLabel}\n onChange={(_, v) => setMcpIds(v)}\n disabled={mcpBusy}\n renderInput={params => (\n <TextField {...params} label=\"Attached MCP servers\" />\n )}\n />\n <Box sx={{ display: 'flex', justifyContent: 'flex-end', mt: 1 }}>\n <Button\n onClick={handleSaveMcpServers}\n disabled={mcpBusy}\n variant=\"outlined\"\n >\n {mcpBusy ? 'Saving\u2026' : 'Save MCP servers'}\n </Button>\n </Box>\n </Box>\n )}\n </DialogContent>\n <DialogActions>\n <Button onClick={onClose} disabled={submitting}>\n Cancel\n </Button>\n <Button onClick={handleSubmit} disabled={submitting} variant=\"contained\">\n {submitting ? 'Saving...' : 'Save'}\n </Button>\n </DialogActions>\n </Dialog>\n );\n};\n", "import React, { useMemo, useState } from 'react';\nimport Paper from '@mui/material/Paper';\nimport Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport TextField from '@mui/material/TextField';\nimport MenuItem from '@mui/material/MenuItem';\nimport Grid from '@mui/material/Grid';\nimport Table from '@mui/material/Table';\nimport TableBody from '@mui/material/TableBody';\nimport TableCell from '@mui/material/TableCell';\nimport TableContainer from '@mui/material/TableContainer';\nimport TableHead from '@mui/material/TableHead';\nimport TableRow from '@mui/material/TableRow';\nimport Skeleton from '@mui/material/Skeleton';\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 Cell,\n} from 'recharts';\nimport {\n DateRange,\n UsageMetrics,\n ModelInfo,\n UserInfo,\n UsageModelBreakdown,\n UsageKeyBreakdown,\n} from '../types';\nimport { fmtUsd, fmtInt } from '../format';\nimport {\n ChartCard,\n ChartTooltip,\n EmptyState,\n Meter,\n MetricStrip,\n SectionCard,\n SegmentedControl,\n Tone,\n SeriesLegend,\n TagChip,\n chartColor,\n dataTableSx,\n fmtCompact,\n fmtDateShort,\n fmtUsdCompact,\n useChartTheme,\n SERIES,\n} from './ui';\n\ninterface UsageStatsProps {\n usage: UsageMetrics | null;\n models: ModelInfo[];\n dateRange: DateRange;\n currentPreset: DatePreset;\n onDateRangeChange: (range: DateRange, preset?: DatePreset) => 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 PRESET_LABELS: Record<DatePreset, string> = {\n today: 'Today',\n '24h': 'Last 24 hours',\n '7d': 'Last 7 days',\n '30d': 'Last 30 days',\n};\n\nconst fmtPct = (n: number) => `${(n * 100).toFixed(1)}%`;\n\n/** Green above 99%, amber down to 90%, red below. */\nfunction rateTone(rate: number): Tone {\n if (rate >= 0.99) return 'success';\n if (rate >= 0.9) return 'warning';\n return 'danger';\n}\n\nconst ChartSkeleton: React.FC<{ height?: number }> = ({ height = 240 }) => (\n <Skeleton variant=\"rounded\" height={height} />\n);\n\n/** Shows a loading skeleton, an empty-state message, or the chart itself. */\nconst ChartOrFallback: React.FC<{\n loading: boolean;\n empty: boolean;\n height?: number;\n children: React.ReactNode;\n}> = ({ loading, empty, height = 240, children }) => {\n if (loading) return <ChartSkeleton height={height} />;\n if (empty) return <EmptyState message=\"No data for this period\" height={height} />;\n return <>{children}</>;\n};\n\n/** Inline success-rate bar used in both breakdown tables. */\nconst SuccessRateCell: React.FC<{ rate: number; requests: number }> = ({ rate, requests }) => {\n if (requests === 0) return <Typography variant=\"body2\" color=\"text.secondary\">\u2014</Typography>;\n const tone = rateTone(rate);\n return (\n <Box display=\"flex\" alignItems=\"center\" gap={1}>\n {/* Fixed, not flexible: the success-rate column is the last one, so a\n flexible meter stretches across all the table's slack space. */}\n <Box width={72} flexShrink={0}>\n <Meter value={rate * 100} tone={tone} height={4} />\n </Box>\n <Typography\n variant=\"caption\"\n sx={{ fontVariantNumeric: 'tabular-nums', minWidth: 44 }}\n >\n {fmtPct(rate)}\n </Typography>\n </Box>\n );\n};\n\nexport const UsageStats: React.FC<UsageStatsProps> = ({\n usage,\n models,\n dateRange,\n currentPreset,\n onDateRangeChange,\n loading,\n userInfo,\n}) => {\n const chart = useChartTheme();\n const [selectedModel, setSelectedModel] = useState<string>('all');\n const [tab, setTab] = useState<TabKey>('costs');\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 }, preset);\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 // Keep the budget reference line inside the plot even when spend is far below it.\n const cumulativeDomain: any = maxBudget > 0\n ? [0, (dataMax: number) => Math.max(dataMax, maxBudget) * 1.05]\n : [0, 'auto'];\n\n const successTone: Tone = totalRequests === 0 ? 'neutral' : rateTone(overallSuccessRate);\n\n const metrics = [\n {\n label: 'Total spend',\n value: fmtUsd(usage?.total_spend ?? 0),\n hint: maxBudget > 0 ? `of ${fmtUsd(maxBudget)} budget` : undefined,\n tone: 'accent' as const,\n },\n {\n label: 'Requests',\n value: fmtInt(totalRequests),\n hint: `${fmtInt(usage?.failed_requests ?? 0)} failed`,\n tone: 'info' as const,\n },\n {\n label: 'Success rate',\n value: totalRequests > 0 ? fmtPct(overallSuccessRate) : '\u2014',\n hint: totalRequests > 0 ? `${fmtInt(usage?.successful_requests ?? 0)} succeeded` : undefined,\n tone: successTone,\n },\n {\n label: 'Tokens',\n value: fmtCompact(usage?.total_tokens ?? 0),\n hint: `${fmtCompact(usage?.prompt_tokens ?? 0)} in \u00B7 ${fmtCompact(usage?.completion_tokens ?? 0)} out`,\n tone: 'success' as const,\n },\n ];\n\n const renderKeyRows = () => {\n if (loading) {\n return (\n <TableRow>\n <TableCell colSpan={7} sx={{ py: 3 }}>\n <Skeleton variant=\"rounded\" height={80} />\n </TableCell>\n </TableRow>\n );\n }\n if (keyRows.length === 0) {\n return (\n <TableRow>\n <TableCell colSpan={7}><EmptyState message=\"No key activity in this period\" /></TableCell>\n </TableRow>\n );\n }\n return [...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\" sx={{ fontWeight: 600 }}>{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.slice(0, 3).map(m => (\n <TagChip key={m} label={m} title={m} />\n ))}\n {r.models.length > 3 && <TagChip label={`+${r.models.length - 3}`} mono={false} />}\n </Box>\n </TableCell>\n <TableCell align=\"right\">{fmtUsd(r.spend)}</TableCell>\n <TableCell align=\"right\">{fmtInt(r.apiRequests)}</TableCell>\n <TableCell align=\"right\">{fmtCompact(r.totalTokens)}</TableCell>\n <TableCell align=\"right\">{fmtInt(r.failedRequests)}</TableCell>\n <TableCell>\n <SuccessRateCell rate={r.successRate} requests={r.apiRequests} />\n </TableCell>\n </TableRow>\n ));\n };\n\n const renderModelRows = () => {\n if (loading) {\n return (\n <TableRow>\n <TableCell colSpan={8} sx={{ py: 3 }}>\n <Skeleton variant=\"rounded\" height={80} />\n </TableCell>\n </TableRow>\n );\n }\n if (modelRows.length === 0) {\n return (\n <TableRow>\n <TableCell colSpan={8}><EmptyState message=\"No model activity in this period\" /></TableCell>\n </TableRow>\n );\n }\n return [...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={1}>\n <Box sx={{ width: 8, height: 8, borderRadius: '50%', bgcolor: chartColor(r.model), flexShrink: 0 }} />\n <Typography variant=\"body2\" sx={{ fontWeight: 600 }}>{r.model}</Typography>\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\">{fmtCompact(r.promptTokens)}</TableCell>\n <TableCell align=\"right\">{fmtCompact(r.completionTokens)}</TableCell>\n <TableCell>\n <SuccessRateCell rate={r.successRate} requests={r.apiRequests} />\n </TableCell>\n </TableRow>\n ));\n };\n\n const periodSelect = (\n <TextField\n select\n size=\"small\"\n label=\"Period\"\n value={currentPreset}\n onChange={e => handlePresetChange(e.target.value as DatePreset)}\n sx={{ minWidth: 160 }}\n >\n {(Object.keys(PRESET_LABELS) as DatePreset[]).map(p => (\n <MenuItem key={p} value={p}>{PRESET_LABELS[p]}</MenuItem>\n ))}\n </TextField>\n );\n\n return (\n <SectionCard\n title=\"Usage Analytics\"\n subtitle={`${PRESET_LABELS[currentPreset]} \u00B7 ${dateRange.start.toLocaleDateString()} \u2013 ${dateRange.end.toLocaleDateString()}`}\n actions={periodSelect}\n >\n <MetricStrip metrics={metrics} />\n\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 2,\n flexWrap: 'wrap',\n mt: 2.5,\n mb: 2,\n }}\n >\n <SegmentedControl<TabKey>\n value={tab}\n onChange={setTab}\n options={[\n { value: 'costs', label: 'Costs' },\n { value: 'models', label: 'Model Activity' },\n { value: 'keys', label: 'Key Activity' },\n ]}\n />\n {tab === 'models' && (\n <TextField\n select\n size=\"small\"\n label=\"Model\"\n value={selectedModel}\n onChange={e => setSelectedModel(e.target.value)}\n sx={{ minWidth: 220 }}\n >\n <MenuItem value=\"all\">All models</MenuItem>\n {models.map(m => (\n <MenuItem key={m.model_name} value={m.model_name}>{m.model_name}</MenuItem>\n ))}\n </TextField>\n )}\n </Box>\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={2}>\n {/* Daily spend by model \u2014 the headline chart, given full width so the\n stack and its colour key stay legible with up to seven series. */}\n <Grid item xs={12}>\n <ChartCard title=\"Daily spend by model\" height={260}>\n <ChartOrFallback loading={loading} empty={modelSpendByDate.length === 0} height={260}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <AreaChart data={modelSpendByDate} margin={{ top: 4, right: 8, left: 0, bottom: 0 }}>\n <CartesianGrid {...chart.grid} />\n <XAxis dataKey=\"date\" tickFormatter={fmtDateShort} {...chart.axis} />\n <YAxis tickFormatter={fmtUsdCompact} width={56} {...chart.axis} />\n <Tooltip\n cursor={chart.cursor}\n content={<ChartTooltip valueFormatter={fmtUsd} hideZero />}\n />\n {topSpendModels.map(m => (\n <Area\n key={m}\n type=\"monotone\"\n dataKey={m}\n stackId=\"spend\"\n stroke={chartColor(m)}\n strokeWidth={1.5}\n fill={chartColor(m)}\n fillOpacity={0.28}\n />\n ))}\n </AreaChart>\n </ResponsiveContainer>\n </ChartOrFallback>\n {!loading && topSpendModels.length > 0 && (\n <SeriesLegend series={topSpendModels.map(m => ({ name: m, color: chartColor(m) }))} />\n )}\n </ChartCard>\n </Grid>\n\n <Grid item xs={12} md={6}>\n <ChartCard title=\"Daily token usage\">\n <ChartOrFallback loading={loading} empty={dailyData.length === 0}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <AreaChart data={dailyData} margin={{ top: 4, right: 8, left: 0, bottom: 0 }}>\n <CartesianGrid {...chart.grid} />\n <XAxis dataKey=\"date\" tickFormatter={fmtDateShort} {...chart.axis} />\n <YAxis tickFormatter={fmtCompact} width={48} {...chart.axis} />\n <Tooltip cursor={chart.cursor} content={<ChartTooltip valueFormatter={fmtInt} />} />\n <Legend {...chart.legend} />\n <Area type=\"monotone\" dataKey=\"promptTokens\" name=\"Input\" stackId=\"tok\" stroke={SERIES.input} strokeWidth={1.5} fill={SERIES.input} fillOpacity={0.25} />\n <Area type=\"monotone\" dataKey=\"completionTokens\" name=\"Output\" stackId=\"tok\" stroke={SERIES.output} strokeWidth={1.5} fill={SERIES.output} fillOpacity={0.25} />\n </AreaChart>\n </ResponsiveContainer>\n </ChartOrFallback>\n </ChartCard>\n </Grid>\n\n <Grid item xs={12} md={6}>\n <ChartCard title=\"Daily requests\">\n <ChartOrFallback loading={loading} empty={dailyData.length === 0}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart data={dailyData} margin={{ top: 4, right: 8, left: 0, bottom: 0 }} barCategoryGap=\"30%\">\n <CartesianGrid {...chart.grid} />\n <XAxis dataKey=\"date\" tickFormatter={fmtDateShort} {...chart.axis} />\n <YAxis tickFormatter={fmtCompact} width={48} {...chart.axis} />\n <Tooltip cursor={chart.cursor} content={<ChartTooltip valueFormatter={fmtInt} />} />\n <Legend {...chart.legend} />\n <Bar dataKey=\"successfulRequests\" name=\"Successful\" fill={SERIES.success} stackId=\"r\" />\n <Bar dataKey=\"failedRequests\" name=\"Failed\" fill={SERIES.failure} stackId=\"r\" radius={[3, 3, 0, 0]} />\n </BarChart>\n </ResponsiveContainer>\n </ChartOrFallback>\n </ChartCard>\n </Grid>\n\n <Grid item xs={12} md={6}>\n <ChartCard title=\"Daily success rate\">\n <ChartOrFallback loading={loading} empty={successRateData.length === 0}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <LineChart data={successRateData} margin={{ top: 4, right: 8, left: 0, bottom: 0 }}>\n <CartesianGrid {...chart.grid} />\n <XAxis dataKey=\"date\" tickFormatter={fmtDateShort} {...chart.axis} />\n <YAxis domain={[0, 100]} tickFormatter={v => `${v}%`} width={44} {...chart.axis} />\n <Tooltip\n cursor={chart.cursor}\n content={<ChartTooltip valueFormatter={(v: number) => `${v}%`} />}\n />\n <ReferenceLine y={100} stroke={SERIES.success} strokeDasharray=\"4 4\" strokeOpacity={0.5} />\n <Line\n type=\"monotone\"\n dataKey=\"successRate\"\n name=\"Success rate\"\n stroke={SERIES.input}\n strokeWidth={2}\n dot={{ r: 2.5, strokeWidth: 0, fill: SERIES.input }}\n activeDot={{ r: 4 }}\n />\n </LineChart>\n </ResponsiveContainer>\n </ChartOrFallback>\n </ChartCard>\n </Grid>\n\n <Grid item xs={12} md={6}>\n <ChartCard\n title={maxBudget > 0 ? 'Cumulative spend vs budget' : 'Cumulative spend'}\n meta={\n maxBudget > 0\n ? `${fmtUsd(totalCumSpend)} used \u00B7 ${fmtUsd(Math.max(0, maxBudget - totalCumSpend))} left`\n : undefined\n }\n >\n <ChartOrFallback loading={loading} empty={cumulativeData.length === 0}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <AreaChart data={cumulativeData} margin={{ top: 4, right: 8, left: 0, bottom: 0 }}>\n <CartesianGrid {...chart.grid} />\n <XAxis dataKey=\"date\" tickFormatter={fmtDateShort} {...chart.axis} />\n <YAxis\n tickFormatter={fmtUsdCompact}\n width={56}\n domain={cumulativeDomain}\n {...chart.axis}\n />\n <Tooltip\n cursor={chart.cursor}\n content={<ChartTooltip valueFormatter={fmtUsd} />}\n />\n {maxBudget > 0 && (\n <ReferenceLine\n y={maxBudget}\n stroke={SERIES.budget}\n strokeDasharray=\"5 4\"\n label={{ value: `Budget ${fmtUsd(maxBudget)}`, position: 'insideTopRight', fontSize: 10, fill: SERIES.budget }}\n />\n )}\n <Area\n type=\"monotone\"\n dataKey=\"cumulative\"\n name=\"Cumulative spend\"\n stroke={SERIES.spend}\n strokeWidth={2}\n fill={SERIES.spend}\n fillOpacity={0.18}\n />\n </AreaChart>\n </ResponsiveContainer>\n </ChartOrFallback>\n </ChartCard>\n </Grid>\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={2}>\n <Grid item xs={12} md={6}>\n <ChartCard title=\"Spend by model\" height={Math.max(200, topModelSpendBars.length * 34)}>\n <ChartOrFallback\n loading={loading}\n empty={topModelSpendBars.length === 0}\n height={Math.max(200, topModelSpendBars.length * 34)}\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart data={topModelSpendBars} layout=\"vertical\" margin={{ top: 0, right: 12, left: 0, bottom: 0 }}>\n <CartesianGrid {...chart.grid} vertical horizontal={false} />\n <XAxis type=\"number\" tickFormatter={fmtUsdCompact} {...chart.axis} />\n <YAxis type=\"category\" dataKey=\"model\" width={170} {...chart.axis} tick={{ fontSize: 10.5, fill: chart.axis.tick.fill }} />\n <Tooltip cursor={chart.cursor} content={<ChartTooltip valueFormatter={fmtUsd} labelFormatter={l => l} />} />\n <Bar dataKey=\"spend\" name=\"Spend\" radius={[0, 3, 3, 0]} barSize={14}>\n {topModelSpendBars.map(r => (\n <Cell key={r.model} fill={chartColor(r.model)} />\n ))}\n </Bar>\n </BarChart>\n </ResponsiveContainer>\n </ChartOrFallback>\n </ChartCard>\n </Grid>\n\n <Grid item xs={12} md={6}>\n <ChartCard title=\"Tokens by model\" height={Math.max(200, topModelSpendBars.length * 34)}>\n <ChartOrFallback\n loading={loading}\n empty={modelRows.length === 0}\n height={Math.max(200, topModelSpendBars.length * 34)}\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart data={topModelSpendBars} layout=\"vertical\" margin={{ top: 0, right: 12, left: 0, bottom: 0 }}>\n <CartesianGrid {...chart.grid} vertical horizontal={false} />\n <XAxis type=\"number\" tickFormatter={fmtCompact} {...chart.axis} />\n <YAxis type=\"category\" dataKey=\"model\" width={170} {...chart.axis} tick={{ fontSize: 10.5, fill: chart.axis.tick.fill }} />\n <Tooltip cursor={chart.cursor} content={<ChartTooltip valueFormatter={fmtInt} labelFormatter={l => l} />} />\n <Legend {...chart.legend} />\n <Bar dataKey=\"promptTokens\" name=\"Input\" fill={SERIES.input} stackId=\"t\" barSize={14} />\n <Bar dataKey=\"completionTokens\" name=\"Output\" fill={SERIES.output} stackId=\"t\" barSize={14} radius={[0, 3, 3, 0]} />\n </BarChart>\n </ResponsiveContainer>\n </ChartOrFallback>\n </ChartCard>\n </Grid>\n\n <Grid item xs={12}>\n <TableContainer component={Paper} variant=\"outlined\" sx={{ borderRadius: 2 }}>\n <Table size=\"small\" sx={dataTableSx}>\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\">Input</TableCell>\n <TableCell align=\"right\">Output</TableCell>\n <TableCell sx={{ width: 160 }}>Success rate</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {renderModelRows()}\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={2}>\n {(loading || topKeySpendBars.length > 0) && (\n <Grid item xs={12}>\n <ChartCard title=\"Spend by key\" height={Math.max(160, topKeySpendBars.length * 32)}>\n <ChartOrFallback\n loading={loading}\n empty={topKeySpendBars.length === 0}\n height={Math.max(160, topKeySpendBars.length * 32)}\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart data={topKeySpendBars} layout=\"vertical\" margin={{ top: 0, right: 12, left: 0, bottom: 0 }}>\n <CartesianGrid {...chart.grid} vertical horizontal={false} />\n <XAxis type=\"number\" tickFormatter={fmtUsdCompact} {...chart.axis} />\n <YAxis type=\"category\" dataKey=\"keyAlias\" width={160} {...chart.axis} tick={{ fontSize: 10.5, fill: chart.axis.tick.fill }} />\n <Tooltip cursor={chart.cursor} content={<ChartTooltip valueFormatter={fmtUsd} labelFormatter={l => l} />} />\n <Bar dataKey=\"spend\" name=\"Spend\" fill={SERIES.input} radius={[0, 3, 3, 0]} barSize={14} />\n </BarChart>\n </ResponsiveContainer>\n </ChartOrFallback>\n </ChartCard>\n </Grid>\n )}\n\n <Grid item xs={12}>\n <TableContainer component={Paper} variant=\"outlined\" sx={{ borderRadius: 2 }}>\n <Table size=\"small\" sx={dataTableSx}>\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={{ width: 160 }}>Success rate</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {renderKeyRows()}\n </TableBody>\n </Table>\n </TableContainer>\n </Grid>\n </Grid>\n )}\n </SectionCard>\n );\n};\n", "import React, { useState } from 'react';\nimport Paper from '@mui/material/Paper';\nimport Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport Skeleton from '@mui/material/Skeleton';\nimport Divider from '@mui/material/Divider';\nimport Table from '@mui/material/Table';\nimport TableBody from '@mui/material/TableBody';\nimport TableCell from '@mui/material/TableCell';\nimport TableHead from '@mui/material/TableHead';\nimport TableRow from '@mui/material/TableRow';\nimport TableContainer from '@mui/material/TableContainer';\nimport Collapse from '@mui/material/Collapse';\nimport IconButton from '@mui/material/IconButton';\nimport Button from '@mui/material/Button';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport { alpha } from '@mui/material/styles';\nimport { ExpandMore, Group, Add } 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 } from '../types';\nimport {\n ChartTooltip,\n EmptyState,\n Meter,\n SectionCard,\n Stat,\n StatusPill,\n TagChip,\n Tone,\n dataTableSx,\n fmtDateShort,\n fmtUsdCompact,\n useChartTheme,\n SERIES,\n} from './ui';\n\nfunction budgetTone(isOver: boolean, isNear: boolean): Tone {\n if (isOver) return 'danger';\n if (isNear) return 'warning';\n return 'accent';\n}\n\nconst fmtUsd2 = (n: number) => `$${(n ?? 0).toFixed(2)}`;\n\ninterface TeamCardProps {\n team: TeamInfo;\n usage: UsageMetrics | null;\n usageLoading: boolean;\n canManage?: boolean;\n onEditTeam?: (team: TeamInfo) => void;\n}\n\nconst TeamCard: React.FC<TeamCardProps> = ({ team, usage, usageLoading, canManage, onEditTeam }) => {\n const [expanded, setExpanded] = useState(false);\n const chart = useChartTheme();\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 const renderDailySpendSection = () => {\n if (usageLoading) {\n return (\n <Box display=\"flex\" justifyContent=\"center\" py={3}>\n <CircularProgress size={22} />\n </Box>\n );\n }\n if (dailyData.length === 0) return null;\n return (\n <Box mb={2.5}>\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n sx={{ display: 'block', fontSize: 11, fontWeight: 700, letterSpacing: '0.07em', textTransform: 'uppercase', mb: 1 }}\n >\n Daily spend\n </Typography>\n <Box height={150}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <AreaChart data={dailyData} margin={{ top: 4, right: 8, left: 0, bottom: 0 }}>\n <CartesianGrid {...chart.grid} />\n <XAxis dataKey=\"date\" tickFormatter={fmtDateShort} {...chart.axis} />\n <YAxis tickFormatter={fmtUsdCompact} width={52} {...chart.axis} />\n <Tooltip\n cursor={chart.cursor}\n content={<ChartTooltip valueFormatter={v => `$${v.toFixed(4)}`} />}\n />\n <Area\n type=\"monotone\"\n dataKey=\"spend\"\n name=\"Spend\"\n stroke={SERIES.spend}\n strokeWidth={2}\n fill={SERIES.spend}\n fillOpacity={0.18}\n />\n </AreaChart>\n </ResponsiveContainer>\n </Box>\n </Box>\n );\n };\n\n const sectionLabel = (label: string) => (\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n sx={{ display: 'block', fontSize: 11, fontWeight: 700, letterSpacing: '0.07em', textTransform: 'uppercase', mb: 1 }}\n >\n {label}\n </Typography>\n );\n\n return (\n <Paper variant=\"outlined\" sx={{ borderRadius: 2, p: 2.5 }}>\n <Box display=\"flex\" alignItems=\"center\" gap={1.5}>\n <Box\n sx={theme => ({\n width: 36,\n height: 36,\n borderRadius: 1.5,\n flexShrink: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n bgcolor: alpha(theme.palette.primary.main, 0.1),\n color: theme.palette.primary.main,\n })}\n >\n <Group fontSize=\"small\" />\n </Box>\n <Box flexGrow={1} minWidth={0}>\n <Typography variant=\"subtitle1\" sx={{ fontWeight: 600, lineHeight: 1.3 }}>\n {team.team_alias || 'Untitled team'}\n </Typography>\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n sx={{ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace', fontSize: 11 }}\n >\n {team.team_id}\n </Typography>\n </Box>\n {isOver && <StatusPill label=\"Over budget\" tone=\"danger\" />}\n {isNear && <StatusPill label=\"Near limit\" tone=\"warning\" />}\n {canManage && onEditTeam && (\n <Button\n size=\"small\"\n variant=\"text\"\n onClick={() => onEditTeam(team)}\n sx={{ textTransform: 'none' }}\n >\n Edit\n </Button>\n )}\n <IconButton\n size=\"small\"\n onClick={() => setExpanded(e => !e)}\n aria-label={expanded ? 'Hide team details' : 'Show team details'}\n aria-expanded={expanded}\n sx={theme => ({\n color: theme.palette.text.secondary,\n transform: expanded ? 'rotate(180deg)' : 'none',\n transition: theme.transitions.create('transform'),\n })}\n >\n <ExpandMore />\n </IconButton>\n </Box>\n\n {/* Fixed-track grid, capped in width, so the six stats line up across\n every team card instead of stretching to fill the row. */}\n <Box\n sx={{\n display: 'grid',\n gridTemplateColumns: { xs: 'repeat(3, minmax(0, 1fr))', sm: 'repeat(6, minmax(0, 1fr))' },\n gap: 2,\n mt: 2.5,\n maxWidth: 640,\n }}\n >\n <Stat label=\"Members\" value={team.members_with_roles?.length ?? '\u2014'} />\n <Stat label=\"Models\" value={team.models?.length ? team.models.length : 'All'} />\n <Stat label=\"Budget\" value={budget > 0 ? fmtUsd2(budget) : 'Unlimited'} />\n <Stat label=\"Spend\" value={fmtUsd2(spend)} />\n <Stat label=\"TPM\" value={team.tpm_limit && team.tpm_limit > 0 ? team.tpm_limit.toLocaleString() : '\u2014'} />\n <Stat label=\"RPM\" value={team.rpm_limit && team.rpm_limit > 0 ? team.rpm_limit.toLocaleString() : '\u2014'} />\n </Box>\n\n {budget > 0 && (\n <Box mt={2} maxWidth={640}>\n <Box display=\"flex\" justifyContent=\"space-between\" alignItems=\"baseline\" mb={0.75}>\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ fontVariantNumeric: 'tabular-nums' }}>\n {fmtUsd2(spend)} of {fmtUsd2(budget)}\n </Typography>\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ fontVariantNumeric: 'tabular-nums' }}>\n {budgetPct.toFixed(0)}%\n </Typography>\n </Box>\n <Meter value={budgetPct} tone={budgetTone(isOver, isNear)} height={5} />\n </Box>\n )}\n\n <Collapse in={expanded} unmountOnExit>\n <Divider sx={{ my: 2.5 }} />\n\n <Box mb={2.5}>\n {sectionLabel('Models')}\n {team.models?.length ? (\n <Box display=\"flex\" gap={0.5} flexWrap=\"wrap\">\n {team.models.map(m => (\n <TagChip key={m} label={m} title={m} />\n ))}\n </Box>\n ) : (\n <Typography variant=\"body2\" color=\"text.secondary\">All models allowed</Typography>\n )}\n </Box>\n\n {renderDailySpendSection()}\n\n <Box>\n {sectionLabel('Members')}\n {team.members_with_roles?.length ? (\n <TableContainer\n component={Paper}\n variant=\"outlined\"\n sx={{ borderRadius: 1.5 }}\n >\n <Table size=\"small\" sx={dataTableSx}>\n <TableHead>\n <TableRow>\n <TableCell>User</TableCell>\n <TableCell align=\"right\">Role</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {team.members_with_roles.map(m => (\n <TableRow key={m.user_id}>\n <TableCell>\n {m.user_email ? (\n <>\n <Typography variant=\"body2\">{m.user_email}</Typography>\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n sx={{ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace', fontSize: 11 }}\n >\n {m.user_id}\n </Typography>\n </>\n ) : (\n <Typography\n variant=\"body2\"\n sx={{ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace' }}\n >\n {m.user_id}\n </Typography>\n )}\n </TableCell>\n <TableCell align=\"right\">\n <StatusPill\n label={m.role}\n tone={m.role === 'admin' ? 'accent' : 'neutral'}\n dot={false}\n />\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </TableContainer>\n ) : (\n <Typography variant=\"body2\" color=\"text.secondary\">No members assigned.</Typography>\n )}\n </Box>\n </Collapse>\n </Paper>\n );\n};\n\ninterface TeamUsageProps {\n teams: TeamInfo[];\n loading: boolean;\n getTeamUsage: (teamId: string) => UsageMetrics | null;\n getTeamUsageLoading: (teamId: string) => boolean;\n canManage?: boolean;\n onEditTeam?: (team: TeamInfo) => void;\n /** When true (with `onCreateTeam`), a \"Create Team\" action renders in the section header. */\n canCreate?: boolean;\n onCreateTeam?: () => void;\n}\n\nexport const TeamUsage: React.FC<TeamUsageProps> = ({\n teams,\n loading,\n getTeamUsage,\n getTeamUsageLoading,\n canManage,\n onEditTeam,\n canCreate,\n onCreateTeam,\n}) => {\n const createAction =\n canCreate && onCreateTeam ? (\n <Button\n variant=\"contained\"\n color=\"primary\"\n disableElevation\n startIcon={<Add />}\n onClick={onCreateTeam}\n >\n Create Team\n </Button>\n ) : undefined;\n\n if (loading) {\n return (\n <SectionCard title=\"Teams\" actions={createAction}>\n <Skeleton variant=\"rounded\" height={120} sx={{ mb: 2 }} />\n <Skeleton variant=\"rounded\" height={120} />\n </SectionCard>\n );\n }\n\n if (!teams.length) {\n return (\n <SectionCard title=\"Teams\" actions={createAction}>\n <EmptyState\n message=\"You're not a member of any LiteLLM team yet.\"\n hint=\"Your account is provisioned, so you can still generate personal keys and use models. Ask an admin to add you to a team if you need a shared budget.\"\n />\n </SectionCard>\n );\n }\n\n return (\n <SectionCard\n title=\"Teams\"\n subtitle={`${teams.length} team${teams.length === 1 ? '' : 's'}`}\n actions={createAction}\n >\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>\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 canManage={canManage}\n onEditTeam={onEditTeam}\n />\n ))}\n </Box>\n </SectionCard>\n );\n};\n", "import React, { useState, useMemo, useCallback } from 'react';\nimport Box from '@mui/material/Box';\nimport Table from '@mui/material/Table';\nimport TableBody from '@mui/material/TableBody';\nimport TableCell from '@mui/material/TableCell';\nimport TableContainer from '@mui/material/TableContainer';\nimport TableHead from '@mui/material/TableHead';\nimport TableRow from '@mui/material/TableRow';\nimport Typography from '@mui/material/Typography';\nimport MenuItem from '@mui/material/MenuItem';\nimport Select from '@mui/material/Select';\nimport FormControl from '@mui/material/FormControl';\nimport InputLabel from '@mui/material/InputLabel';\nimport ContentCopyIcon from '@mui/icons-material/ContentCopy';\nimport Tooltip from '@mui/material/Tooltip';\nimport Snackbar from '@mui/material/Snackbar';\nimport Alert from '@mui/material/Alert';\nimport { ModelInfo, TeamInfo } from '../types';\nimport { SectionCard, EmptyState, TagChip, dataTableSx, quietIconButtonSx } from './ui';\nimport { alpha, useTheme } from '@mui/material/styles';\n\ninterface ModelsTableProps {\n allModels: ModelInfo[];\n teams: TeamInfo[];\n loading: boolean;\n}\n\nconst ALL_PROXY_MODELS = 'all-proxy-models';\n\nfunction isModelAllowedByTeam(model: ModelInfo, teamModels?: string[]): boolean {\n if (!teamModels || teamModels.length === 0 || teamModels.includes(ALL_PROXY_MODELS)) return true;\n return teamModels.includes(model.model_name) ||\n !!model.access_groups?.some(group => teamModels.includes(group));\n}\n\nfunction fmtCostPerToken(cost?: number): string {\n if (cost === undefined || cost === null) return '\u2014';\n if (cost === 0) return '$0';\n if (cost < 0.000001) return `$${(cost * 1_000_000).toFixed(2)}/M`;\n if (cost < 0.001) return `$${(cost * 1000).toFixed(3)}/K`;\n return `$${cost.toFixed(4)}`;\n}\n\nfunction fmtTokens(n?: number): string {\n if (n === undefined || n === null) return '\u2014';\n if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\n if (n >= 1_000) return `${(n / 1_000).toFixed(0)}K`;\n return String(n);\n}\n\nexport const ModelsTable: React.FC<ModelsTableProps> = ({ allModels, teams, loading }) => {\n const theme = useTheme();\n const [selectedTeamId, setSelectedTeamId] = useState<string>('');\n const [copiedSnackbar, setCopiedSnackbar] = useState(false);\n\n const selectedTeam = useMemo(\n () => teams.find(t => t.team_id === selectedTeamId) ?? null,\n [teams, selectedTeamId],\n );\n\n const filteredModels = useMemo(() => {\n if (!selectedTeam) return [];\n return allModels.filter(model => isModelAllowedByTeam(model, selectedTeam.models));\n }, [allModels, selectedTeam]);\n\n const handleCopyModelId = useCallback((modelId: string) => {\n navigator.clipboard.writeText(modelId).then(() => setCopiedSnackbar(true));\n }, []);\n\n const modeColor = (mode: string): string => {\n switch (mode) {\n case 'chat': return theme.palette.info.main;\n case 'embedding': return theme.palette.success.main;\n case 'completion': return theme.palette.primary.main;\n case 'image': return theme.palette.warning.main;\n default: return theme.palette.info.main;\n }\n };\n\n return (\n <SectionCard\n title=\"Available Models\"\n subtitle={selectedTeam ? `${filteredModels.length} model${filteredModels.length !== 1 ? 's' : ''} in ${selectedTeam.team_alias ?? selectedTeam.team_id}` : 'Select a team to view its models'}\n >\n <Box sx={{ px: 2.5, pb: 2.5, pt: 1 }}>\n <FormControl size=\"small\" sx={{ minWidth: 240, mb: 2 }}>\n <InputLabel id=\"team-select-label\">Team</InputLabel>\n <Select\n labelId=\"team-select-label\"\n value={selectedTeamId}\n label=\"Team\"\n onChange={e => setSelectedTeamId(e.target.value)}\n >\n {teams.map(t => (\n <MenuItem key={t.team_id} value={t.team_id}>\n {t.team_alias ?? t.team_id}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n </Box>\n\n {loading && (\n <EmptyState message=\"Loading models\u2026\" />\n )}\n\n {!loading && !selectedTeamId && (\n <EmptyState\n message=\"Select a team to see available models\"\n hint=\"Each team may have a different set of models assigned\"\n />\n )}\n\n {!loading && selectedTeamId && filteredModels.length === 0 && (\n <EmptyState\n message=\"No models available for this team\"\n hint={allModels.length === 0 ? 'No models are configured in the system' : 'None of the team\\'s assigned models were found in the catalog'}\n />\n )}\n\n {!loading && filteredModels.length > 0 && (\n <TableContainer>\n <Table size=\"small\" sx={dataTableSx}>\n <TableHead>\n <TableRow>\n <TableCell>Model ID</TableCell>\n <TableCell>Mode</TableCell>\n <TableCell align=\"right\">Input Cost</TableCell>\n <TableCell align=\"right\">Output Cost</TableCell>\n <TableCell align=\"right\">Max Input</TableCell>\n <TableCell align=\"right\">Max Output</TableCell>\n <TableCell>Capabilities</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {filteredModels.map(m => (\n <TableRow key={m.model_name} hover>\n <TableCell>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>\n <TagChip label={m.model_name} title={m.model_name} />\n <Tooltip title=\"Copy model ID\">\n <Box\n component=\"span\"\n role=\"button\"\n tabIndex={0}\n onClick={() => handleCopyModelId(m.model_name)}\n onKeyDown={e => e.key === 'Enter' && handleCopyModelId(m.model_name)}\n sx={quietIconButtonSx('accent')}\n style={{ cursor: 'pointer', display: 'inline-flex' }}\n >\n <ContentCopyIcon sx={{ fontSize: 14 }} />\n </Box>\n </Tooltip>\n </Box>\n </TableCell>\n <TableCell>\n <Box\n component=\"span\"\n sx={{\n display: 'inline-block',\n px: 0.75,\n py: 0.25,\n borderRadius: 1,\n fontSize: 11,\n fontWeight: 600,\n textTransform: 'capitalize',\n bgcolor: alpha(modeColor(m.mode), 0.1),\n color: modeColor(m.mode),\n }}\n >\n {m.mode}\n </Box>\n </TableCell>\n <TableCell align=\"right\">\n <Typography variant=\"body2\" sx={{ fontVariantNumeric: 'tabular-nums' }}>\n {fmtCostPerToken(m.input_cost_per_token)}\n </Typography>\n </TableCell>\n <TableCell align=\"right\">\n <Typography variant=\"body2\" sx={{ fontVariantNumeric: 'tabular-nums' }}>\n {fmtCostPerToken(m.output_cost_per_token)}\n </Typography>\n </TableCell>\n <TableCell align=\"right\">\n <Typography variant=\"body2\" sx={{ fontVariantNumeric: 'tabular-nums' }}>\n {fmtTokens(m.max_input_tokens)}\n </Typography>\n </TableCell>\n <TableCell align=\"right\">\n <Typography variant=\"body2\" sx={{ fontVariantNumeric: 'tabular-nums' }}>\n {fmtTokens(m.max_output_tokens)}\n </Typography>\n </TableCell>\n <TableCell>\n <Box sx={{ display: 'flex', gap: 0.5, flexWrap: 'wrap' }}>\n {m.supports_function_calling && (\n <TagChip label=\"Fn\" title=\"Function calling\" />\n )}\n {m.supports_vision && (\n <TagChip label=\"\uD83D\uDC41\" title=\"Vision\" />\n )}\n </Box>\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </TableContainer>\n )}\n\n <Snackbar\n open={copiedSnackbar}\n autoHideDuration={2000}\n onClose={() => setCopiedSnackbar(false)}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}\n >\n <Alert severity=\"success\" variant=\"filled\" sx={{ fontSize: 13 }}>\n Model ID copied to clipboard\n </Alert>\n </Snackbar>\n </SectionCard>\n );\n};\n", "import React, { useState, useCallback } from 'react';\nimport Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport Table from '@mui/material/Table';\nimport TableBody from '@mui/material/TableBody';\nimport TableCell from '@mui/material/TableCell';\nimport TableContainer from '@mui/material/TableContainer';\nimport TableHead from '@mui/material/TableHead';\nimport TableRow from '@mui/material/TableRow';\nimport TablePagination from '@mui/material/TablePagination';\nimport TextField from '@mui/material/TextField';\nimport MenuItem from '@mui/material/MenuItem';\nimport Skeleton from '@mui/material/Skeleton';\nimport Collapse from '@mui/material/Collapse';\nimport IconButton from '@mui/material/IconButton';\nimport Alert from '@mui/material/Alert';\nimport { alpha } from '@mui/material/styles';\nimport { KeyboardArrowDown } from '@mui/icons-material';\nimport { useAsync } from 'react-use';\nimport { LiteLlmApiInterface } from '../api';\nimport { AuditLogEntry, AuditLogsParams } from '../types';\nimport { EmptyState, SectionCard, StatusPill, Tone, dataTableSx } from './ui';\n\ninterface AuditLogProps {\n api: LiteLlmApiInterface;\n}\n\nconst ACTION_TONES: Record<string, Tone> = {\n created: 'success',\n deleted: 'danger',\n updated: 'warning',\n blocked: 'danger',\n unblocked: 'success',\n};\n\nfunction actionTone(action?: string): Tone {\n if (!action) return 'neutral';\n for (const [key, tone] of Object.entries(ACTION_TONES)) {\n if (action.toLowerCase().includes(key)) return tone;\n }\n return 'info';\n}\n\n/** `LiteLLM_VerificationToken` \u2192 `Key`; falls back to the raw table name. */\nconst TABLE_LABELS: Record<string, string> = {\n LiteLLM_VerificationToken: 'Key',\n LiteLLM_TeamTable: 'Team',\n LiteLLM_TeamMembership: 'Team member',\n LiteLLM_ObjectPermissionTable: 'Team access (KB / MCP)',\n LiteLLM_UserTable: 'User',\n};\n\nfunction prettyTableName(name?: string | null): string {\n if (!name) return '\u2014';\n return TABLE_LABELS[name] ?? name;\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>\n <TableCell sx={{ width: 40, pr: 0 }}>\n {hasDetail && (\n <IconButton\n size=\"small\"\n onClick={() => setOpen(o => !o)}\n aria-label={open ? 'Hide changes' : 'Show changes'}\n aria-expanded={open}\n sx={theme => ({\n color: theme.palette.text.secondary,\n transform: open ? 'rotate(180deg)' : 'none',\n transition: theme.transitions.create('transform'),\n })}\n >\n <KeyboardArrowDown fontSize=\"small\" />\n </IconButton>\n )}\n </TableCell>\n <TableCell sx={{ whiteSpace: 'nowrap' }}>\n <Typography variant=\"body2\" color=\"text.secondary\">{formatDateTime(entry.updated_at)}</Typography>\n </TableCell>\n <TableCell>\n {entry.action && <StatusPill label={entry.action} tone={actionTone(entry.action)} />}\n </TableCell>\n <TableCell>\n <Typography variant=\"body2\">{prettyTableName(entry.table_name)}</Typography>\n </TableCell>\n <TableCell>\n <Typography\n variant=\"body2\"\n component=\"code\"\n color=\"text.secondary\"\n title={entry.object_id ?? undefined}\n sx={{ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace', fontSize: 12 }}\n >\n {entry.object_id ? entry.object_id.slice(0, 20) + (entry.object_id.length > 20 ? '\u2026' : '') : '\u2014'}\n </Typography>\n </TableCell>\n <TableCell>{entry.changed_by ?? '\u2014'}</TableCell>\n </TableRow>\n {/* The `&&` selectors below double specificity so they beat the\n table-level `tbody td` rules in dataTableSx \u2014 otherwise the collapsed\n row keeps its cell padding and border, leaving an empty stripe\n between entries. */}\n {hasDetail && (\n <TableRow sx={{ '&&:hover': { bgcolor: 'transparent' } }}>\n <TableCell colSpan={6} sx={{ '&&': { py: 0, border: 0 } }}>\n <Collapse in={open} unmountOnExit>\n <Box\n display=\"flex\"\n gap={2}\n flexWrap=\"wrap\"\n sx={theme => ({\n p: 2,\n mb: 1.5,\n borderRadius: 1.5,\n bgcolor: alpha(theme.palette.text.primary, theme.palette.mode === 'dark' ? 0.05 : 0.03),\n })}\n >\n {entry.before_value && (\n <Box flex={1} minWidth={200}>\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n display=\"block\"\n mb={0.75}\n sx={{ fontSize: 10.5, fontWeight: 700, letterSpacing: '0.07em', textTransform: 'uppercase' }}\n >\n Before\n </Typography>\n <Typography component=\"pre\" variant=\"caption\" sx={{ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace', whiteSpace: 'pre-wrap', wordBreak: 'break-all', m: 0 }}>\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\n variant=\"caption\"\n color=\"text.secondary\"\n display=\"block\"\n mb={0.75}\n sx={{ fontSize: 10.5, fontWeight: 700, letterSpacing: '0.07em', textTransform: 'uppercase' }}\n >\n After\n </Typography>\n <Typography component=\"pre\" variant=\"caption\" sx={{ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace', whiteSpace: 'pre-wrap', wordBreak: 'break-all', m: 0 }}>\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\nfunction renderAuditLogBody(loading: boolean, entries: AuditLogEntry[]) {\n if (loading) {\n return (\n <TableRow>\n <TableCell colSpan={6} sx={{ py: 2 }}>\n <Skeleton variant=\"rounded\" height={160} />\n </TableCell>\n </TableRow>\n );\n }\n if (entries.length === 0) {\n return (\n <TableRow>\n <TableCell colSpan={6}>\n <EmptyState\n message=\"No audit events found\"\n hint=\"Try widening the filters or a different time window.\"\n />\n </TableCell>\n </TableRow>\n );\n }\n return entries.map(entry => <DetailRow key={entry.id} entry={entry} />);\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 <SectionCard\n title=\"Audit Log\"\n subtitle={loading ? 'Loading\u2026' : `${total.toLocaleString()} event${total === 1 ? '' : 's'}`}\n flush\n actions={\n <>\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: 150 }}\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: 150 }}\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_TeamMembership\">Team member</MenuItem>\n <MenuItem value=\"LiteLLM_ObjectPermissionTable\">Team access (KB / MCP)</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: 180 }}\n />\n </>\n }\n >\n {error && (\n <Box px={2.5} pb={2}>\n <Alert severity=\"error\">{error.message}</Alert>\n </Box>\n )}\n\n <TableContainer>\n <Table size=\"small\" sx={dataTableSx}>\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 {renderAuditLogBody(loading, entries)}\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 sx={theme => ({ borderTop: `1px solid ${theme.palette.divider}` })}\n />\n </SectionCard>\n );\n};\n", "import { createPermission } from '@backstage/plugin-permission-common';\n\n// NOTE: these MUST stay byte-for-byte in sync with\n// packages/plugin-litellm-backend/src/permissions.ts \u2014 permission identity is the `name`.\nexport const litellmTeamCreatePermission = createPermission({\n name: 'litellm.team.create',\n attributes: { action: 'create' },\n});\n\nexport const litellmTeamManagePermission = createPermission({\n name: 'litellm.team.manage',\n attributes: { action: 'update' },\n});\n\nexport const litellmTeamMembersManagePermission = createPermission({\n name: 'litellm.team.members.manage',\n attributes: { action: 'update' },\n});\n\nexport const litellmTeamKnowledgebaseManagePermission = createPermission({\n name: 'litellm.team.knowledgebase.manage',\n attributes: { action: 'update' },\n});\n\nexport const litellmTeamMcpManagePermission = createPermission({\n name: 'litellm.team.mcp.manage',\n attributes: { action: 'update' },\n});\n", "import React, { useState, useCallback, useMemo } from 'react';\nimport Box from '@mui/material/Box';\nimport Snackbar from '@mui/material/Snackbar';\nimport Alert from '@mui/material/Alert';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport Typography from '@mui/material/Typography';\nimport Paper from '@mui/material/Paper';\nimport Tabs from '@mui/material/Tabs';\nimport Tab from '@mui/material/Tab';\nimport { useAsync, useAsyncRetry } from 'react-use';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { usePermission } from '@backstage/plugin-permission-react';\nimport { DashboardHeader } from './DashboardHeader';\nimport { KeysTable } from './KeysTable';\nimport { GenerateKeyDialog } from './GenerateKeyDialog';\nimport { ManageTeamDialog } from './ManageTeamDialog';\nimport { UsageStats } from './UsageStats';\nimport { TeamUsage } from './TeamUsage';\nimport { ModelsTable } from './ModelsTable';\nimport { AuditLog } from './AuditLog';\nimport { liteLlmApiRef } from '../api';\nimport {\n litellmTeamCreatePermission,\n litellmTeamManagePermission,\n litellmTeamMembersManagePermission,\n litellmTeamKnowledgebaseManagePermission,\n litellmTeamMcpManagePermission,\n} from '../permissions';\nimport { DateRange, GenerateKeyRequest, GenerateKeyResponse, UpdateKeyRequest, UsageMetrics, CreateTeamRequest, UpdateTeamRequest, TeamInfo } from '../types';\n\nconst PERIOD_LS_KEY = 'litellm_usage_period';\ntype DatePreset = 'today' | '24h' | '7d' | '30d';\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 [currentPreset, setCurrentPreset] = useState<DatePreset>(() => {\n try { return (localStorage.getItem(PERIOD_LS_KEY) as DatePreset) ?? '7d'; } catch { return '7d'; }\n });\n const [activeTab, setActiveTab] = useState<'overview' | 'keys' | 'teams' | 'models' | 'audit'>('overview');\n\n const [snackbar, setSnackbar] = useState<{ message: string; severity: 'success' | 'warning' | 'error' } | null>(null);\n const [generateDialogOpen, setGenerateDialogOpen] = useState(false);\n const [manageTeam, setManageTeam] = useState<{ mode: 'create' | 'edit'; team?: TeamInfo } | 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, retry: refreshTeams } = useAsyncRetry(\n () => api.getTeams().catch(() => []),\n [api],\n );\n\n const { value: liteLlmConfig } = useAsync(() => api.getConfig(), [api]);\n\n // Teams the caller administers by group ownership (not membership). Only\n // fetched when team management is enabled; failures degrade to an empty list.\n const { value: managedTeams } = useAsync(\n async () =>\n liteLlmConfig?.teamManagement?.enabled\n ? api.getManagedTeams().catch(() => [])\n : [],\n [api, liteLlmConfig],\n );\n\n const { allowed: canCreateTeam } = usePermission({ permission: litellmTeamCreatePermission });\n const { allowed: canManageTeam } = usePermission({ permission: litellmTeamManagePermission });\n const { allowed: canManageMembers } = usePermission({ permission: litellmTeamMembersManagePermission });\n const { allowed: canManageKnowledgeBases } = usePermission({ permission: litellmTeamKnowledgebaseManagePermission });\n const { allowed: canManageMcpServers } = usePermission({ permission: litellmTeamMcpManagePermission });\n const teamMgmtEnabled = liteLlmConfig?.teamManagement?.enabled ?? false;\n const objectPermsEnabled = liteLlmConfig?.teamManagement?.objectPermissionsEnabled ?? false;\n\n const { value: vectorStores } = useAsync(\n async () =>\n objectPermsEnabled ? api.getVectorStores().catch(() => []) : [],\n [api, objectPermsEnabled],\n );\n const { value: mcpServers } = useAsync(\n async () =>\n objectPermsEnabled ? api.getMcpServers().catch(() => []) : [],\n [api, objectPermsEnabled],\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, preset?: DatePreset) => {\n setDateRange(range);\n if (preset) {\n setCurrentPreset(preset);\n }\n setTeamUsageCache({});\n setTeamUsageLoading({});\n }, [setDateRange, setCurrentPreset]);\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 try {\n const response = await api.generateKey(request);\n setSnackbar({ message: 'Key generated successfully', severity: 'success' });\n refreshKeys();\n return response;\n } catch (e: any) {\n setSnackbar({ message: `Failed to generate key: ${e.message}`, severity: 'error' });\n throw e;\n }\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 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 const pageTabs = (\n <Tabs\n value={activeTab}\n onChange={(_, v) => setActiveTab(v)}\n variant=\"scrollable\"\n scrollButtons=\"auto\"\n // Substring class matching so these survive a host MUI classname prefix\n // (Backstage renders `v5-MuiTabs-indicator`, not `MuiTabs-indicator`).\n sx={{\n minHeight: 44,\n '& [class*=\"MuiTabs-indicator\"]': { height: 2, borderRadius: '2px 2px 0 0' },\n '& [class*=\"MuiTab-root\"]': { minHeight: 44, textTransform: 'none', fontSize: 14 },\n }}\n >\n <Tab label=\"Overview\" value=\"overview\" />\n <Tab label=\"Keys\" value=\"keys\" />\n <Tab label=\"Teams\" value=\"teams\" />\n <Tab label=\"Models\" value=\"models\" />\n {userInfo.can_view_audit && <Tab label=\"Audit Log\" value=\"audit\" />}\n </Tabs>\n );\n\n return (\n <Box sx={{ p: 3, display: 'flex', flexDirection: 'column', gap: 2 }}>\n <DashboardHeader\n userInfo={userInfo}\n teams={teams ?? []}\n keys={keys ?? []}\n loading={userLoading || teamsLoading}\n onGenerateKeyClick={() => setGenerateDialogOpen(true)}\n tabs={pageTabs}\n />\n\n {activeTab === 'overview' && (\n <UsageStats\n usage={usage ?? null}\n models={allModels ?? []}\n dateRange={dateRange}\n currentPreset={currentPreset}\n onDateRangeChange={handleDateRangeChange}\n loading={usageLoading}\n userInfo={userInfo}\n />\n )}\n\n {activeTab === 'keys' && (\n <KeysTable\n keys={keys ?? []}\n models={allowedModels}\n loading={keysLoading || modelsLoading}\n onGenerateKeyClick={() => setGenerateDialogOpen(true)}\n onUpdateKey={handleUpdateKey}\n onBlockKey={handleBlockKey}\n onUnblockKey={handleUnblockKey}\n onResetKeySpend={handleResetKeySpend}\n onDeleteKey={handleDeleteKey}\n onPruneExpiredKeys={handlePruneExpiredKeys}\n />\n )}\n\n {activeTab === 'teams' && (() => {\n // Union of teams the user is a member of and teams their group owns,\n // de-duplicated by team_id (membership entries win on conflict).\n const teamsById = new Map<string, TeamInfo>();\n for (const t of managedTeams ?? []) teamsById.set(t.team_id, t);\n for (const t of teams ?? []) teamsById.set(t.team_id, t);\n const visibleTeams = Array.from(teamsById.values());\n return (\n <TeamUsage\n teams={visibleTeams}\n loading={teamsLoading}\n getTeamUsage={teamId => {\n if (teamUsageCache[teamId] === undefined) loadTeamUsage(teamId);\n return teamUsageCache[teamId] ?? null;\n }}\n getTeamUsageLoading={teamId => teamUsageLoading[teamId] ?? false}\n canManage={teamMgmtEnabled && canManageTeam}\n onEditTeam={t => setManageTeam({ mode: 'edit', team: t })}\n canCreate={teamMgmtEnabled && canCreateTeam}\n onCreateTeam={() => setManageTeam({ mode: 'create' })}\n />\n );\n })()}\n\n {activeTab === 'models' && (\n <ModelsTable\n allModels={allModels ?? []}\n teams={teams ?? []}\n loading={modelsLoading}\n />\n )}\n\n {activeTab === 'audit' && userInfo.can_view_audit && <AuditLog api={api} />}\n\n <GenerateKeyDialog\n open={generateDialogOpen}\n onClose={() => setGenerateDialogOpen(false)}\n keys={keys ?? []}\n models={allowedModels}\n teams={teams ?? []}\n username={userInfo.user_id}\n keyGenerationSettings={liteLlmConfig?.keyGeneration}\n onGenerateKey={handleGenerateKey}\n onGetConfig={() => api.getConfig()}\n />\n\n <ManageTeamDialog\n open={!!manageTeam}\n onClose={() => setManageTeam(null)}\n mode={manageTeam?.mode ?? 'create'}\n team={manageTeam?.team}\n allModels={allModels ?? []}\n config={liteLlmConfig}\n onSubmit={async payload => {\n if (manageTeam?.mode === 'edit' && manageTeam.team) {\n await api.updateTeam(manageTeam.team.team_id, payload as UpdateTeamRequest);\n } else {\n await api.createTeam(payload as CreateTeamRequest);\n }\n setSnackbar({ message: 'Team saved', severity: 'success' });\n refreshTeams();\n }}\n canManageMembers={teamMgmtEnabled && canManageMembers}\n onAddMember={async (userEntityRef, maxBudgetInTeam) => {\n if (!manageTeam?.team) return;\n const updated = await api.addTeamMember(manageTeam.team.team_id, {\n userEntityRef,\n ...(maxBudgetInTeam ? { maxBudgetInTeam } : {}),\n });\n setManageTeam(s => (s && s.team ? { ...s, team: updated } : s));\n refreshTeams();\n }}\n onRemoveMember={async userEntityRef => {\n if (!manageTeam?.team) return;\n const updated = await api.removeTeamMember(\n manageTeam.team.team_id,\n userEntityRef,\n );\n setManageTeam(s => (s && s.team ? { ...s, team: updated } : s));\n refreshTeams();\n }}\n canManageKnowledgeBases={\n teamMgmtEnabled && objectPermsEnabled && canManageKnowledgeBases\n }\n vectorStores={vectorStores ?? []}\n onSaveKnowledgeBases={async vectorStoreIds => {\n if (!manageTeam?.team) return;\n const updated = await api.setTeamKnowledgeBases(\n manageTeam.team.team_id,\n vectorStoreIds,\n );\n setManageTeam(s => (s && s.team ? { ...s, team: updated } : s));\n setSnackbar({ message: 'Knowledge bases updated', severity: 'success' });\n refreshTeams();\n }}\n canManageMcpServers={\n teamMgmtEnabled && objectPermsEnabled && canManageMcpServers\n }\n mcpServers={mcpServers ?? []}\n onSaveMcpServers={async mcpServerIds => {\n if (!manageTeam?.team) return;\n const updated = await api.setTeamMcpServers(\n manageTeam.team.team_id,\n mcpServerIds,\n );\n setManageTeam(s => (s && s.team ? { ...s, team: updated } : s));\n setSnackbar({ message: 'MCP servers updated', severity: 'success' });\n refreshTeams();\n }}\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 { GenerateKeyDialog } from './components/GenerateKeyDialog';\nexport { ManageTeamDialog } from './components/ManageTeamDialog';\nexport { LiteLlmApi, liteLlmApiRef } from './api';\nexport {\n litellmTeamCreatePermission,\n litellmTeamManagePermission,\n litellmTeamMembersManagePermission,\n litellmTeamKnowledgebaseManagePermission,\n litellmTeamMcpManagePermission,\n} from './permissions';\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 Paper from '@mui/material/Paper';\nimport Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport FormControl from '@mui/material/FormControl';\nimport Select from '@mui/material/Select';\nimport MenuItem from '@mui/material/MenuItem';\nimport Grid from '@mui/material/Grid';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport Alert from '@mui/material/Alert';\nimport { AreaChart, Area, ResponsiveContainer } from 'recharts';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { liteLlmApiRef } from '../api';\nimport { UsageMetrics, VirtualKey } from '../types';\nimport { fmtUsd, fmtInt } from '../format';\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\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 [usageError, setUsageError] = useState<string | null>(null);\n const [keysError, setKeysError] = 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 setUsageError(null);\n setKeysError(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.allSettled([api.getUsage(startDate, endDate), api.listKeys()]).then(\n ([usageResult, keysResult]) => {\n if (cancelled) return;\n if (usageResult.status === 'fulfilled') {\n setUsage(usageResult.value);\n } else {\n setUsage(null);\n setUsageError(usageResult.reason?.message ?? 'Failed to load usage data');\n }\n if (keysResult.status === 'fulfilled') {\n setKeys(keysResult.value);\n } else {\n setKeys([]);\n setKeysError(keysResult.reason?.message ?? 'Failed to load keys');\n }\n setLoading(false);\n },\n );\n\n return () => {\n cancelled = true;\n };\n }, [api, period]);\n\n const partialFailure =\n !loading && (usageError || keysError) && (usage || keys.length > 0);\n const totalFailure = !loading && usageError && keysError;\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 && totalFailure && (\n <Alert severity=\"error\" sx={{ mt: 1 }}>\n {usageError ?? 'Failed to load usage data'}\n </Alert>\n )}\n\n {/* Content */}\n {!loading && !totalFailure && (\n <>\n {partialFailure && (\n <Alert severity=\"warning\" sx={{ mt: 1, mb: 1 }}>\n {usageError\n ? `Usage data unavailable (${usageError}).`\n : ''}\n {keysError\n ? ` Key list unavailable (${keysError}).` : ''}\n {' Showing what loaded.'}\n </Alert>\n )}\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
- "names": ["React", "Box", "ButtonBase", "Paper", "Typography", "import_react", "import_Box", "import_Typography", "import_Paper", "import_styles", "React", "Box", "Typography", "Paper", "Skeleton", "Button", "Divider", "React", "Typography", "CircularProgress", "Box", "import_react", "import_Button", "import_Box", "import_Typography", "import_Skeleton", "import_styles", "import_icons_material", "TableRow", "TableCell", "Skeleton", "Button", "IconButton", "TextField", "InputAdornment", "TableContainer", "Table", "TableHead", "TableSortLabel", "TableBody", "Dialog", "DialogTitle", "DialogContent", "Autocomplete", "DialogActions", "fmtCost", "formatContextWindow", "import_react", "import_Box", "import_Typography", "import_Dialog", "import_DialogTitle", "import_DialogContent", "import_DialogActions", "import_TextField", "import_Button", "import_IconButton", "import_CircularProgress", "import_Autocomplete", "import_icons_material", "React", "Box", "Tabs", "Tab", "Typography", "IconButton", "Autocomplete", "TextField", "Dialog", "DialogTitle", "DialogContent", "Alert", "MenuItem", "FormControlLabel", "Checkbox", "Accordion", "AccordionSummary", "AccordionDetails", "DialogActions", "Button", "CircularProgress", "import_react", "import_Dialog", "import_DialogTitle", "import_DialogContent", "import_DialogActions", "import_TextField", "import_Button", "import_Alert", "import_Checkbox", "import_FormControlLabel", "import_Autocomplete", "import_CircularProgress", "import_MenuItem", "import_Box", "import_Divider", "import_Typography", "import_IconButton", "import_Paper", "import_Table", "import_TableBody", "import_TableCell", "import_TableContainer", "import_TableHead", "import_TableRow", "import_icons_material", "import_core_plugin_api", "React", "Dialog", "DialogTitle", "DialogContent", "Alert", "TextField", "Autocomplete", "FormControlLabel", "Checkbox", "MenuItem", "Box", "Divider", "Typography", "TableContainer", "Paper", "Table", "TableHead", "TableRow", "TableCell", "TableBody", "IconButton", "DeleteIcon", "CircularProgress", "Button", "DialogActions", "import_react", "import_Paper", "import_Box", "import_Typography", "import_TextField", "import_MenuItem", "import_Table", "import_TableBody", "import_TableCell", "import_TableContainer", "import_TableHead", "import_TableRow", "import_Skeleton", "React", "Skeleton", "Typography", "Box", "TableRow", "TableCell", "TextField", "MenuItem", "Grid", "TableContainer", "Paper", "Table", "TableHead", "TableBody", "budgetTone", "import_react", "import_Paper", "import_Box", "import_Typography", "import_Skeleton", "import_Divider", "import_Table", "import_TableBody", "import_TableCell", "import_TableHead", "import_TableRow", "import_TableContainer", "import_IconButton", "import_Button", "import_CircularProgress", "import_styles", "import_icons_material", "import_recharts", "React", "Box", "CircularProgress", "Typography", "Paper", "Button", "IconButton", "Collapse", "Divider", "TableContainer", "Table", "TableHead", "TableRow", "TableCell", "TableBody", "Skeleton", "isModelAllowedByTeam", "ALL_PROXY_MODELS", "import_react", "import_Box", "import_Table", "import_TableBody", "import_TableCell", "import_TableContainer", "import_TableHead", "import_TableRow", "import_Typography", "import_MenuItem", "import_Alert", "import_styles", "React", "Box", "FormControl", "InputLabel", "Select", "MenuItem", "TableContainer", "Table", "TableHead", "TableRow", "TableCell", "TableBody", "Tooltip", "ContentCopyIcon", "Typography", "Snackbar", "Alert", "React", "TableRow", "TableCell", "Skeleton", "import_react", "import_Box", "import_Typography", "import_Table", "import_TableBody", "import_TableCell", "import_TableContainer", "import_TableHead", "import_TableRow", "import_TextField", "import_MenuItem", "import_Skeleton", "import_Collapse", "import_IconButton", "import_Alert", "import_styles", "import_icons_material", "import_react_use", "IconButton", "Typography", "Collapse", "Box", "TextField", "MenuItem", "Alert", "TableContainer", "Table", "TableHead", "TableBody", "TablePagination", "PERIOD_LS_KEY", "import_react", "import_Box", "import_Snackbar", "import_Alert", "import_CircularProgress", "import_Typography", "import_Paper", "import_Tabs", "import_Tab", "import_react_use", "import_core_plugin_api", "React", "Box", "CircularProgress", "Paper", "Typography", "Tabs", "Tab", "Snackbar", "Alert", "import_react", "import_icons_material", "React", "TrendingUpIcon", "LiteLLMPage", "import_react", "import_Paper", "import_Box", "import_Typography", "import_FormControl", "import_Select", "import_MenuItem", "import_Grid", "import_CircularProgress", "import_Alert", "import_recharts", "import_core_plugin_api", "React", "Box", "Typography", "Paper", "FormControl", "Select", "MenuItem", "CircularProgress", "Alert", "Grid"]
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 LiteLlmConfig,\n VectorStoreInfo,\n McpServerInfo,\n CreateTeamRequest,\n CreateTeamResponse,\n UpdateTeamRequest,\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 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 getManagedTeams(): Promise<TeamInfo[]>;\n addTeamMember(\n teamId: string,\n body: { userEntityRef: string; maxBudgetInTeam?: number },\n ): Promise<TeamInfo>;\n removeTeamMember(teamId: string, userEntityRef: string): Promise<TeamInfo>;\n getVectorStores(): Promise<VectorStoreInfo[]>;\n setTeamKnowledgeBases(teamId: string, vectorStores: string[]): Promise<TeamInfo>;\n getMcpServers(): Promise<McpServerInfo[]>;\n setTeamMcpServers(teamId: string, mcpServers: string[]): 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 getConfig(): Promise<LiteLlmConfig>;\n createTeam(request: CreateTeamRequest): Promise<CreateTeamResponse>;\n updateTeam(teamId: string, request: UpdateTeamRequest): Promise<TeamInfo>;\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 const message =\n (typeof body === 'object' && body && typeof (body as any).error === 'string'\n ? (body as any).error\n : undefined) ?? `${response.status} ${response.statusText}`;\n throw new ApiError(message, 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 private async patch<T>(path: string, body: unknown): Promise<T> {\n const response = await this.fetchApi.fetch(`${this.basePath}${path}`, {\n method: 'PATCH',\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 put<T>(path: string, body: unknown): Promise<T> {\n const response = await this.fetchApi.fetch(`${this.basePath}${path}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\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 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 // eslint-disable-next-line no-console -- best-effort bulk cleanup; no errorApi in this client class to report through\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 // Teams whose owning_group the caller administers (server-scoped). Distinct\n // from getTeams(), which returns only the teams the caller is a member of.\n async getManagedTeams(): Promise<TeamInfo[]> {\n return this.get<TeamInfo[]>('/teams/managed');\n }\n\n async addTeamMember(\n teamId: string,\n body: { userEntityRef: string; maxBudgetInTeam?: number },\n ): Promise<TeamInfo> {\n return this.post<TeamInfo>(\n `/teams/${encodeURIComponent(teamId)}/members`,\n body,\n );\n }\n\n async removeTeamMember(\n teamId: string,\n userEntityRef: string,\n ): Promise<TeamInfo> {\n return this.del<TeamInfo>(\n `/teams/${encodeURIComponent(teamId)}/members?userEntityRef=${encodeURIComponent(\n userEntityRef,\n )}`,\n );\n }\n\n // Vector stores (knowledge bases) the caller may attach \u2014 already filtered\n // server-side to the operator's allowlist.\n async getVectorStores(): Promise<VectorStoreInfo[]> {\n return this.get<VectorStoreInfo[]>('/vector-stores');\n }\n\n async setTeamKnowledgeBases(\n teamId: string,\n vectorStores: string[],\n ): Promise<TeamInfo> {\n return this.put<TeamInfo>(\n `/teams/${encodeURIComponent(teamId)}/knowledge-bases`,\n { vector_stores: vectorStores },\n );\n }\n\n async getMcpServers(): Promise<McpServerInfo[]> {\n return this.get<McpServerInfo[]>('/mcp-servers');\n }\n\n async setTeamMcpServers(\n teamId: string,\n mcpServers: string[],\n ): Promise<TeamInfo> {\n return this.put<TeamInfo>(\n `/teams/${encodeURIComponent(teamId)}/mcp-servers`,\n { mcp_servers: mcpServers },\n );\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 async getConfig(): Promise<LiteLlmConfig> {\n return this.get<LiteLlmConfig>('/config');\n }\n\n async createTeam(request: CreateTeamRequest): Promise<CreateTeamResponse> {\n return this.post<CreateTeamResponse>('/teams', request);\n }\n\n async updateTeam(teamId: string, request: UpdateTeamRequest): Promise<TeamInfo> {\n return this.patch<TeamInfo>(`/teams/${encodeURIComponent(teamId)}`, request);\n }\n}\n", "/**\n * Shared presentation primitives for the LiteLLM plugin.\n *\n * The plugin renders inside whatever Backstage theme the host app supplies, so\n * everything here derives its colour from the MUI palette rather than hard-coded\n * values. The one exception is the chart series palette: Recharts has no theme\n * awareness, and its stock colours (#8884d8 / #82ca9d / #ffc658) read as a demo\n * rather than a product, so we ship a curated ramp that holds up on both light\n * and dark surfaces.\n */\nimport React from 'react';\nimport Box from '@mui/material/Box';\nimport ButtonBase from '@mui/material/ButtonBase';\nimport Paper from '@mui/material/Paper';\nimport Typography from '@mui/material/Typography';\nimport { alpha, useTheme } from '@mui/material/styles';\nimport type { SxProps, Theme } from '@mui/material/styles';\n\n// \u2500\u2500 formatting \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\n\n/** `2026-08-16` \u2192 `Aug 16`. Falls back to the raw value for anything else. */\nexport const fmtDateShort = (value: string): string => {\n const m = /^(\\d{4})-(\\d{2})-(\\d{2})/.exec(value ?? '');\n if (!m) return value;\n return `${MONTHS[Number(m[2]) - 1]} ${Number(m[3])}`;\n};\n\n/** 54253484 \u2192 `54.3M`. Keeps axis labels from swallowing the plot area. */\nexport const fmtCompact = (n: number): string => {\n const v = n ?? 0;\n const abs = Math.abs(v);\n if (abs >= 1e9) return `${(v / 1e9).toFixed(abs >= 1e10 ? 0 : 1)}B`;\n if (abs >= 1e6) return `${(v / 1e6).toFixed(abs >= 1e7 ? 0 : 1)}M`;\n if (abs >= 1e3) return `${(v / 1e3).toFixed(abs >= 1e4 ? 0 : 1)}K`;\n return String(Math.round(v));\n};\n\n/** Compact currency for axis ticks \u2014 `$24`, `$1.2K`. */\nexport const fmtUsdCompact = (n: number): string => {\n const v = n ?? 0;\n if (Math.abs(v) >= 1000) return `$${fmtCompact(v)}`;\n if (Math.abs(v) >= 10) return `$${v.toFixed(0)}`;\n return `$${v.toFixed(2)}`;\n};\n\n// \u2500\u2500 chart palette \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Categorical ramp, ordered so neighbouring series stay distinguishable. */\nexport const CHART_COLORS = [\n '#6366F1', // indigo\n '#14B8A6', // teal\n '#F59E0B', // amber\n '#EC4899', // pink\n '#38BDF8', // sky\n '#84CC16', // lime\n '#F97316', // orange\n '#A855F7', // violet\n] as const;\n\n/** Fixed colours for series that carry meaning rather than identity. */\nexport const SERIES = {\n input: '#6366F1',\n output: '#14B8A6',\n success: '#10B981',\n failure: '#EF4444',\n spend: '#F59E0B',\n budget: '#EF4444',\n} as const;\n\nconst OTHER_COLOR = '#94A3B8';\n\n/** Stable colour per series name, so a model keeps its colour across charts. */\nexport function chartColor(name: string): string {\n if (name === 'Other') return OTHER_COLOR;\n let h = 5381;\n for (let i = 0; i < name.length; i++) h = ((h << 5) + h + name.charCodeAt(i)) >>> 0;\n return CHART_COLORS[h % CHART_COLORS.length];\n}\n\n/** Axis / grid / legend props shared by every chart, derived from the theme. */\nexport function useChartTheme() {\n const theme = useTheme();\n const tickFill = theme.palette.text.secondary;\n return {\n grid: {\n stroke: alpha(theme.palette.text.primary, theme.palette.mode === 'dark' ? 0.12 : 0.08),\n strokeDasharray: '2 4',\n vertical: false,\n },\n axis: {\n tick: { fontSize: 11, fill: tickFill },\n tickLine: false,\n axisLine: { stroke: alpha(theme.palette.text.primary, 0.12) },\n },\n legend: {\n wrapperStyle: {\n fontSize: 11,\n color: tickFill,\n paddingTop: 8,\n },\n iconType: 'circle' as const,\n iconSize: 8,\n },\n cursor: { fill: alpha(theme.palette.text.primary, 0.05) },\n };\n}\n\ninterface ChartTooltipProps {\n active?: boolean;\n label?: string | number;\n payload?: Array<{ name?: string; value?: number; color?: string; dataKey?: string | number }>;\n /** Formats each series value; defaults to a localised integer. */\n valueFormatter?: (value: number) => string;\n /** Formats the header; defaults to the short date form. */\n labelFormatter?: (label: string) => string;\n /** Drop zero-valued series \u2014 useful for stacked charts with many series. */\n hideZero?: boolean;\n}\n\n/**\n * Recharts' default tooltip is an opaque white card with a hard border \u2014 it\n * disappears on dark themes. This one uses the theme's own surface tokens.\n */\nexport const ChartTooltip: React.FC<ChartTooltipProps> = ({\n active,\n label,\n payload,\n valueFormatter = (v: number) => v.toLocaleString(),\n labelFormatter = fmtDateShort,\n hideZero = false,\n}) => {\n if (!active || !payload?.length) return null;\n const rows = payload.filter(\n p => p.value !== undefined && p.value !== null && (!hideZero || p.value !== 0),\n );\n if (!rows.length) return null;\n return (\n <Paper\n elevation={8}\n sx={{\n px: 1.5,\n py: 1,\n borderRadius: 1.5,\n border: '1px solid',\n borderColor: 'divider',\n minWidth: 150,\n pointerEvents: 'none',\n }}\n >\n <Typography\n variant=\"caption\"\n sx={{ display: 'block', fontWeight: 700, mb: 0.75, letterSpacing: '0.02em' }}\n >\n {typeof label === 'string' ? labelFormatter(label) : label}\n </Typography>\n {rows.map((row, i) => (\n <Box\n key={`${row.dataKey ?? row.name ?? i}`}\n sx={{ display: 'flex', alignItems: 'center', gap: 1, mt: i === 0 ? 0 : 0.5 }}\n >\n <Box\n sx={{\n width: 8,\n height: 8,\n borderRadius: '50%',\n bgcolor: row.color,\n flexShrink: 0,\n }}\n />\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n sx={{ flex: 1, mr: 1.5, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}\n >\n {row.name}\n </Typography>\n <Typography variant=\"caption\" sx={{ fontWeight: 700, fontVariantNumeric: 'tabular-nums' }}>\n {valueFormatter(row.value as number)}\n </Typography>\n </Box>\n ))}\n </Paper>\n );\n};\n\n/**\n * Colour key rendered outside the SVG. Recharts' own `<Legend>` cannot ellipsize,\n * so a handful of fully-qualified model names (\"bedrock/eu.anthropic.\u2026\") wrap\n * into a ragged block that eats the plot area.\n */\nexport const SeriesLegend: React.FC<{ series: Array<{ name: string; color: string }> }> = ({\n series,\n}) => (\n <Box\n sx={{\n display: 'flex',\n flexWrap: 'wrap',\n gap: 0.5,\n columnGap: 2,\n rowGap: 0.5,\n mt: 1.5,\n }}\n >\n {series.map(s => (\n <Box key={s.name} sx={{ display: 'flex', alignItems: 'center', gap: 0.75, minWidth: 0 }}>\n <Box\n sx={{ width: 8, height: 8, borderRadius: '50%', bgcolor: s.color, flexShrink: 0 }}\n />\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n title={s.name}\n sx={{\n fontSize: 11,\n maxWidth: 190,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }}\n >\n {s.name}\n </Typography>\n </Box>\n ))}\n </Box>\n);\n\n// \u2500\u2500 status pills \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type Tone = 'neutral' | 'success' | 'warning' | 'danger' | 'info' | 'accent';\n\nfunction toneColor(theme: Theme, tone: Tone): string {\n switch (tone) {\n case 'success': return theme.palette.success.main;\n case 'warning': return theme.palette.warning.main;\n case 'danger': return theme.palette.error.main;\n case 'info': return theme.palette.info.main;\n case 'accent': return theme.palette.primary.main;\n default: return theme.palette.text.secondary;\n }\n}\n\n/**\n * A soft status badge. Deliberately *not* MUI's filled `Chip` \u2014 host themes\n * tend to render those as saturated pills, and a table with one screaming\n * orange pill per row is unreadable. Tinted background, hairline border,\n * squared-off corners.\n */\nexport const StatusPill: React.FC<{\n label: React.ReactNode;\n tone?: Tone;\n /** Show the leading tone dot. */\n dot?: boolean;\n title?: string;\n sx?: SxProps<Theme>;\n}> = ({ label, tone = 'neutral', dot = true, title, sx }) => (\n <Box\n component=\"span\"\n title={title}\n sx={[\n theme => {\n const c = toneColor(theme, tone);\n return {\n display: 'inline-flex',\n alignItems: 'center',\n gap: 0.625,\n height: 22,\n px: 0.875,\n borderRadius: '6px',\n border: '1px solid',\n borderColor: alpha(c, tone === 'neutral' ? 0.25 : 0.35),\n bgcolor: alpha(c, tone === 'neutral' ? 0.06 : 0.12),\n color: tone === 'neutral' ? theme.palette.text.secondary : c,\n fontSize: 11.5,\n fontWeight: 600,\n lineHeight: 1,\n letterSpacing: '0.01em',\n whiteSpace: 'nowrap',\n maxWidth: '100%',\n };\n },\n ...(Array.isArray(sx) ? sx : [sx]),\n ]}\n >\n {dot && (\n <Box\n component=\"span\"\n sx={theme => ({\n width: 6,\n height: 6,\n borderRadius: '50%',\n bgcolor: toneColor(theme, tone),\n flexShrink: 0,\n })}\n />\n )}\n <Box component=\"span\" sx={{ overflow: 'hidden', textOverflow: 'ellipsis' }}>\n {label}\n </Box>\n </Box>\n);\n\n/** Quiet monospace tag for identifiers: model names, team slugs, roles. */\nexport const TagChip: React.FC<{ label: React.ReactNode; title?: string; mono?: boolean }> = ({\n label,\n title,\n mono = true,\n}) => (\n <Box\n component=\"span\"\n title={title}\n sx={theme => ({\n display: 'inline-flex',\n alignItems: 'center',\n height: 20,\n px: 0.75,\n borderRadius: '5px',\n bgcolor: alpha(theme.palette.text.primary, theme.palette.mode === 'dark' ? 0.08 : 0.05),\n color: theme.palette.text.secondary,\n fontFamily: mono ? 'ui-monospace, SFMono-Regular, Menlo, monospace' : undefined,\n fontSize: 11,\n lineHeight: 1,\n whiteSpace: 'nowrap',\n maxWidth: 220,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n })}\n >\n {label}\n </Box>\n);\n\n// \u2500\u2500 surfaces \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Page-level surface with a consistent title row. */\nexport const SectionCard: React.FC<{\n title?: React.ReactNode;\n subtitle?: React.ReactNode;\n actions?: React.ReactNode;\n /** Set when the body renders its own edge-to-edge content (e.g. a table). */\n flush?: boolean;\n children: React.ReactNode;\n}> = ({ title, subtitle, actions, flush = false, children }) => (\n <Paper sx={{ borderRadius: 2, overflow: 'hidden' }}>\n {(title || actions) && (\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 2,\n flexWrap: 'wrap',\n px: 2.5,\n py: 2,\n }}\n >\n <Box sx={{ minWidth: 0 }}>\n <Typography variant=\"h6\" sx={{ lineHeight: 1.2 }}>{title}</Typography>\n {subtitle && (\n <Typography variant=\"caption\" color=\"text.secondary\">{subtitle}</Typography>\n )}\n </Box>\n {actions && (\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, flexWrap: 'wrap' }}>\n {actions}\n </Box>\n )}\n </Box>\n )}\n <Box sx={flush ? undefined : { px: 2.5, pb: 2.5, pt: title ? 0 : 2.5 }}>{children}</Box>\n </Paper>\n);\n\n/** Bordered frame around a single chart, with its own caption row. */\nexport const ChartCard: React.FC<{\n title: React.ReactNode;\n meta?: React.ReactNode;\n height?: number;\n children: React.ReactNode;\n}> = ({ title, meta, height = 240, children }) => (\n // The plot area must have an explicit height, never a flex-derived one:\n // Recharts' ResponsiveContainer measures its parent, so a parent that sizes\n // itself from its children instead spins in a measure/resize loop.\n <Paper variant=\"outlined\" sx={{ p: 2, borderRadius: 2, height: '100%' }}>\n <Box sx={{ display: 'flex', alignItems: 'baseline', gap: 1, mb: 1.5, flexWrap: 'wrap' }}>\n <Typography\n variant=\"subtitle2\"\n sx={{ fontSize: 12, fontWeight: 700, letterSpacing: '0.06em', textTransform: 'uppercase' }}\n >\n {title}\n </Typography>\n {meta && (\n <Typography variant=\"caption\" color=\"text.secondary\">{meta}</Typography>\n )}\n </Box>\n <Box sx={{ height, width: '100%' }}>{children}</Box>\n </Paper>\n);\n\n// \u2500\u2500 metrics \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface MetricDef {\n label: string;\n value: string;\n hint?: string;\n tone?: Tone;\n}\n\n/**\n * KPI row rendered as one framed strip divided into cells, rather than four\n * loose cards. Cells share a baseline grid so the numbers line up even when\n * only some of them carry a hint.\n */\nexport const MetricStrip: React.FC<{ metrics: MetricDef[] }> = ({ metrics }) => (\n <Paper\n variant=\"outlined\"\n sx={{\n borderRadius: 2,\n display: 'grid',\n gridTemplateColumns: { xs: '1fr 1fr', md: `repeat(${metrics.length}, 1fr)` },\n overflow: 'hidden',\n }}\n >\n {metrics.map((m, i) => (\n <Box\n key={m.label}\n sx={theme => ({\n px: 2.5,\n py: 2,\n borderLeft: i === 0 ? 0 : '1px solid',\n borderTop: 0,\n borderColor: 'divider',\n [theme.breakpoints.down('md')]: {\n borderLeft: i % 2 === 0 ? 0 : '1px solid',\n borderTop: i < 2 ? 0 : '1px solid',\n borderColor: 'divider',\n },\n })}\n >\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.875, mb: 0.75 }}>\n <Box\n sx={theme => ({\n width: 6,\n height: 6,\n borderRadius: '50%',\n bgcolor: toneColor(theme, m.tone ?? 'accent'),\n flexShrink: 0,\n })}\n />\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n sx={{ fontSize: 11, fontWeight: 600, letterSpacing: '0.07em', textTransform: 'uppercase' }}\n >\n {m.label}\n </Typography>\n </Box>\n <Typography\n sx={{ fontSize: 26, fontWeight: 700, lineHeight: 1.15, fontVariantNumeric: 'tabular-nums' }}\n >\n {m.value}\n </Typography>\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n sx={{ display: 'block', mt: 0.5, minHeight: 16 }}\n >\n {m.hint ?? '\u00A0'}\n </Typography>\n </Box>\n ))}\n </Paper>\n);\n\n/** Label + value pair used inside cards. */\nexport const Stat: React.FC<{ label: string; value: React.ReactNode }> = ({ label, value }) => (\n <Box sx={{ minWidth: 0 }}>\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n sx={{ display: 'block', fontSize: 10.5, fontWeight: 600, letterSpacing: '0.07em', textTransform: 'uppercase' }}\n >\n {label}\n </Typography>\n <Typography\n variant=\"body2\"\n sx={{ fontWeight: 600, fontVariantNumeric: 'tabular-nums', mt: 0.25 }}\n >\n {value}\n </Typography>\n </Box>\n);\n\n/**\n * Progress meter with an explicitly drawn track. MUI's `LinearProgress` tints\n * its track from the bar colour, which makes an empty bar look full.\n */\nexport const Meter: React.FC<{ value: number; tone?: Tone; height?: number }> = ({\n value,\n tone = 'accent',\n height = 5,\n}) => (\n <Box\n sx={theme => ({\n height,\n borderRadius: height,\n bgcolor: alpha(theme.palette.text.primary, theme.palette.mode === 'dark' ? 0.12 : 0.08),\n overflow: 'hidden',\n })}\n >\n <Box\n sx={theme => ({\n height: '100%',\n width: `${Math.max(0, Math.min(100, value))}%`,\n borderRadius: height,\n bgcolor: toneColor(theme, tone),\n transition: theme.transitions.create('width'),\n })}\n />\n </Box>\n);\n\n// \u2500\u2500 segmented control \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\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Secondary navigation inside a card. Hand-rolled rather than a second set of\n * `Tabs` so it reads as subordinate to the page tabs instead of competing\n * with them, and so host theme overrides on `MuiTab` don't leak in.\n */\nexport function SegmentedControl<T extends string>({\n value,\n onChange,\n options,\n}: {\n value: T;\n onChange: (value: T) => void;\n options: Array<{ value: T; label: string }>;\n}) {\n return (\n <Box\n role=\"tablist\"\n sx={theme => ({\n display: 'inline-flex',\n gap: 0.25,\n p: 0.375,\n borderRadius: 1.5,\n border: '1px solid',\n borderColor: theme.palette.divider,\n })}\n >\n {options.map(opt => {\n const selected = opt.value === value;\n return (\n <ButtonBase\n key={opt.value}\n role=\"tab\"\n aria-selected={selected}\n onClick={() => onChange(opt.value)}\n sx={theme => ({\n px: 1.5,\n height: 28,\n borderRadius: 1,\n fontSize: 13,\n fontWeight: selected ? 700 : 500,\n // Tint the selection with the accent rather than swapping in a\n // surface colour: on a dark theme `background.paper` sits *behind*\n // the track, so the selected chip would read as recessed.\n color: selected ? theme.palette.primary.main : theme.palette.text.secondary,\n bgcolor: selected\n ? alpha(theme.palette.primary.main, theme.palette.mode === 'dark' ? 0.2 : 0.11)\n : 'transparent',\n transition: theme.transitions.create(['background-color', 'color']),\n '&:hover': {\n color: selected ? theme.palette.primary.main : theme.palette.text.primary,\n bgcolor: selected\n ? alpha(theme.palette.primary.main, theme.palette.mode === 'dark' ? 0.26 : 0.15)\n : alpha(theme.palette.text.primary, 0.05),\n },\n })}\n >\n {opt.label}\n </ButtonBase>\n );\n })}\n </Box>\n );\n}\n\n// \u2500\u2500 tables \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Shared table chrome: quiet uppercase headers, hairline row rules, a hover\n * highlight, and tabular figures so numeric columns align.\n */\nexport const dataTableSx: SxProps<Theme> = theme => ({\n // Element selectors, not `.MuiTableCell-head`: host apps may set a MUI\n // classname prefix (Backstage ships `v5-`), which breaks global class targeting.\n '& thead th': {\n fontSize: 11,\n fontWeight: 700,\n letterSpacing: '0.07em',\n textTransform: 'uppercase',\n color: theme.palette.text.secondary,\n backgroundColor: alpha(theme.palette.text.primary, theme.palette.mode === 'dark' ? 0.04 : 0.02),\n borderBottom: `1px solid ${theme.palette.divider}`,\n whiteSpace: 'nowrap',\n paddingTop: theme.spacing(1.25),\n paddingBottom: theme.spacing(1.25),\n },\n '& tbody td': {\n borderBottom: `1px solid ${alpha(theme.palette.divider, 0.6)}`,\n paddingTop: theme.spacing(1.25),\n paddingBottom: theme.spacing(1.25),\n fontVariantNumeric: 'tabular-nums',\n },\n '& tbody tr:last-of-type td': {\n borderBottom: 0,\n },\n '& tbody tr:hover': {\n backgroundColor: alpha(theme.palette.text.primary, 0.03),\n },\n});\n\n/** Muted icon button that only picks up its semantic colour on hover. */\nexport const quietIconButtonSx = (tone: Tone = 'neutral'): SxProps<Theme> => theme => ({\n color: theme.palette.text.secondary,\n '&:hover': {\n color: toneColor(theme, tone),\n bgcolor: alpha(toneColor(theme, tone), 0.1),\n },\n});\n\n/** Centered empty / loading state for a card body. */\nexport const EmptyState: React.FC<{\n message: string;\n hint?: string;\n height?: number;\n action?: React.ReactNode;\n}> = ({ message, hint, height, action }) => (\n <Box\n sx={{\n height,\n minHeight: height ? undefined : 120,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 1,\n textAlign: 'center',\n py: 3,\n }}\n >\n <Typography variant=\"body2\" color=\"text.secondary\">{message}</Typography>\n {hint && <Typography variant=\"caption\" color=\"text.secondary\">{hint}</Typography>}\n {action}\n </Box>\n);\n", "import React, { useMemo } from 'react';\nimport Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport Skeleton from '@mui/material/Skeleton';\nimport Paper from '@mui/material/Paper';\nimport Button from '@mui/material/Button';\nimport Divider from '@mui/material/Divider';\nimport { alpha } from '@mui/material/styles';\nimport { Add } from '@mui/icons-material';\nimport { UserInfo, TeamInfo, VirtualKey } from '../types';\nimport { expiryStatus } from '../api';\nimport { TagChip, Tone } from './ui';\n\ninterface DashboardHeaderProps {\n userInfo: UserInfo;\n teams: TeamInfo[];\n keys: VirtualKey[];\n loading: boolean;\n onGenerateKeyClick: () => void;\n /** Page tab bar, rendered flush with the bottom edge of the header card. */\n tabs?: React.ReactNode;\n}\n\n/** Two initials from an email or username, for the identity badge. */\nfunction initials(name: string): string {\n const local = name.split('@')[0] ?? name;\n const parts = local.split(/[.\\-_\\s]+/).filter(Boolean);\n if (parts.length >= 2) return (parts[0][0] + parts[1][0]).toUpperCase();\n return local.slice(0, 2).toUpperCase();\n}\n\nconst CountStat: React.FC<{ value: number; label: string; tone: Tone }> = ({ value, label, tone }) => {\n // Zero counts stay grey: only a real expiry deserves a colour.\n const active = value > 0;\n return (\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>\n <Box\n sx={theme => ({\n width: 7,\n height: 7,\n borderRadius: '50%',\n flexShrink: 0,\n bgcolor: active\n ? (tone === 'danger' && theme.palette.error.main) ||\n (tone === 'warning' && theme.palette.warning.main) ||\n theme.palette.primary.main\n : alpha(theme.palette.text.primary, 0.25),\n })}\n />\n <Typography\n component=\"span\"\n sx={{ fontSize: 15, fontWeight: 700, lineHeight: 1, fontVariantNumeric: 'tabular-nums' }}\n >\n {value}\n </Typography>\n <Typography\n component=\"span\"\n color=\"text.secondary\"\n sx={{ fontSize: 11, fontWeight: 600, letterSpacing: '0.07em', textTransform: 'uppercase' }}\n >\n {label}\n </Typography>\n </Box>\n );\n};\n\nexport const DashboardHeader: React.FC<DashboardHeaderProps> = ({\n userInfo,\n teams,\n keys,\n loading,\n onGenerateKeyClick,\n tabs,\n}) => {\n const counts = useMemo(() => {\n const expired = keys.filter(k => expiryStatus(k.expires_at) === 'expired').length;\n const expiringSoon = keys.filter(k => expiryStatus(k.expires_at) === 'soon').length;\n return { total: keys.length, expired, expiringSoon };\n }, [keys]);\n\n const displayName = userInfo.user_email ?? userInfo.email ?? userInfo.user_id;\n\n return (\n <Paper sx={{ borderRadius: 2, overflow: 'hidden' }}>\n <Box\n sx={{\n display: 'flex',\n alignItems: 'flex-start',\n gap: 2,\n flexWrap: 'wrap',\n px: 2.5,\n pt: 2.5,\n pb: 2,\n }}\n >\n <Box\n sx={theme => ({\n width: 44,\n height: 44,\n borderRadius: 1.5,\n flexShrink: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n bgcolor: alpha(theme.palette.primary.main, 0.12),\n color: theme.palette.primary.main,\n fontSize: 15,\n fontWeight: 700,\n letterSpacing: '0.02em',\n })}\n >\n {initials(displayName)}\n </Box>\n\n <Box sx={{ flexGrow: 1, minWidth: 220 }}>\n <Typography variant=\"h6\" sx={{ lineHeight: 1.25, wordBreak: 'break-word' }}>\n {displayName}\n </Typography>\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n sx={{ display: 'block', fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace' }}\n >\n {userInfo.user_id}\n </Typography>\n\n <Box sx={{ display: 'flex', gap: 0.75, flexWrap: 'wrap', mt: 1, minHeight: 20 }}>\n {loading ? (\n <Skeleton variant=\"rounded\" width={140} height={20} />\n ) : (\n teams.map(team => (\n <TagChip\n key={team.team_id}\n label={team.team_alias || team.team_id}\n title={team.team_id}\n />\n ))\n )}\n </Box>\n </Box>\n\n <Button\n variant=\"contained\"\n color=\"primary\"\n disableElevation\n startIcon={<Add />}\n onClick={onGenerateKeyClick}\n >\n Generate New Key\n </Button>\n </Box>\n\n <Divider />\n\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 2.5,\n flexWrap: 'wrap',\n px: 2.5,\n py: 1.5,\n }}\n >\n <CountStat value={counts.total} label=\"keys\" tone=\"accent\" />\n <Divider orientation=\"vertical\" flexItem sx={{ my: 0.25 }} />\n <CountStat value={counts.expired} label=\"expired\" tone=\"danger\" />\n <Divider orientation=\"vertical\" flexItem sx={{ my: 0.25 }} />\n <CountStat value={counts.expiringSoon} label=\"expiring soon\" tone=\"warning\" />\n </Box>\n\n {tabs && (\n <>\n <Divider />\n <Box sx={{ px: 1 }}>{tabs}</Box>\n </>\n )}\n </Paper>\n );\n};\n", "import React, { useState, useMemo } from 'react';\nimport Table from '@mui/material/Table';\nimport TableBody from '@mui/material/TableBody';\nimport TableCell from '@mui/material/TableCell';\nimport TableContainer from '@mui/material/TableContainer';\nimport TableHead from '@mui/material/TableHead';\nimport TableRow from '@mui/material/TableRow';\nimport TableSortLabel from '@mui/material/TableSortLabel';\nimport Button from '@mui/material/Button';\nimport IconButton from '@mui/material/IconButton';\nimport Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport Dialog from '@mui/material/Dialog';\nimport DialogTitle from '@mui/material/DialogTitle';\nimport DialogContent from '@mui/material/DialogContent';\nimport DialogActions from '@mui/material/DialogActions';\nimport TextField from '@mui/material/TextField';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport Autocomplete from '@mui/material/Autocomplete';\nimport Skeleton from '@mui/material/Skeleton';\nimport InputAdornment from '@mui/material/InputAdornment';\nimport { alpha } from '@mui/material/styles';\nimport { ContentCopy, Delete, Add, Edit, Autorenew, Search, Lock, LockOpen } from '@mui/icons-material';\nimport { expiryStatus } from '../api';\nimport {\n VirtualKey,\n ModelInfo,\n UpdateKeyRequest,\n} from '../types';\nimport {\n EmptyState,\n Meter,\n SectionCard,\n StatusPill,\n TagChip,\n Tone,\n dataTableSx,\n quietIconButtonSx,\n} from './ui';\n\ninterface KeysTableProps {\n keys: VirtualKey[];\n models: ModelInfo[];\n /** Opens the shared \"Generate New Key\" dialog (rendered at page level). */\n onGenerateKeyClick: () => void;\n loading: boolean;\n onUpdateKey: (keyId: string, request: UpdateKeyRequest) => Promise<void>;\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 expiryChipLabel(status: 'expired' | 'soon' | 'ok', expiresAt: string): string {\n if (status === 'expired') return 'Expired';\n if (status === 'soon') return `${Math.ceil((new Date(expiresAt).getTime() - Date.now()) / 86400000)}d left`;\n return formatDate(expiresAt);\n}\n\nfunction expiryTone(status: 'expired' | 'soon' | 'ok'): Tone {\n if (status === 'expired') return 'danger';\n if (status === 'soon') return 'warning';\n return 'neutral';\n}\n\nfunction ExpiryCell({ expiresAt }: { expiresAt?: string }) {\n const status = expiryStatus(expiresAt);\n if (!status) {\n return <Typography variant=\"body2\" color=\"text.secondary\">Never</Typography>;\n }\n // A key that is simply valid needs no badge \u2014 plain text keeps the column\n // quiet so the handful of expired/expiring rows actually stand out.\n if (status === 'ok') {\n return (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {formatDate(expiresAt!)}\n </Typography>\n );\n }\n return (\n <StatusPill\n label={expiryChipLabel(status, expiresAt!)}\n tone={expiryTone(status)}\n title={`Expires ${formatDate(expiresAt!)}`}\n />\n );\n}\n\nfunction budgetTone(pct: number): Tone {\n if (pct >= 100) return 'danger';\n if (pct >= 80) return 'warning';\n return 'accent';\n}\n\nfunction keyBlockIcon(isBlocking: boolean, blocked?: boolean) {\n if (isBlocking) return <CircularProgress size={18} />;\n if (blocked) return <LockOpen fontSize=\"small\" />;\n return <Lock fontSize=\"small\" />;\n}\n\nfunction BudgetCell({ spend, maxBudget }: { spend: number; maxBudget?: number }) {\n if (!maxBudget) {\n return (\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ fontVariantNumeric: 'tabular-nums' }}>\n ${spend.toFixed(2)}\n <Typography component=\"span\" variant=\"caption\" sx={{ ml: 0.5, opacity: 0.7 }}>\n / \u221E\n </Typography>\n </Typography>\n );\n }\n const pct = Math.min(100, (spend / maxBudget) * 100);\n return (\n <Box minWidth={104}>\n <Typography variant=\"body2\" sx={{ fontVariantNumeric: 'tabular-nums', mb: 0.5 }}>\n ${spend.toFixed(2)}\n <Typography component=\"span\" variant=\"caption\" color=\"text.secondary\" sx={{ ml: 0.5 }}>\n / ${maxBudget}\n </Typography>\n </Typography>\n <Meter value={pct} tone={budgetTone(pct)} height={4} />\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\nfunction formatContextWindow(\n maxInput?: number,\n maxOutput?: number,\n): string | null {\n if (!maxInput && !maxOutput) return null;\n const fmt = (n?: number) => {\n if (!n) return null;\n if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\n if (n >= 1_000) return `${Math.round(n / 1000)}K`;\n return String(n);\n };\n const inPart = fmt(maxInput);\n const outPart = fmt(maxOutput);\n if (inPart && outPart) return `ctx ${inPart} in / ${outPart} out`;\n if (inPart) return `ctx ${inPart}`;\n if (outPart) return `ctx ${outPart} out`;\n return null;\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\ntype SortKey = 'alias' | 'created' | 'expires' | 'budget' | 'limits' | 'models';\ntype SortDirection = 'asc' | 'desc';\n\nfunction compareKeys(a: VirtualKey, b: VirtualKey, sortKey: SortKey): number {\n switch (sortKey) {\n case 'alias': return (a.key_alias ?? '').localeCompare(b.key_alias ?? '');\n case 'created': return a.created_at.localeCompare(b.created_at);\n case 'expires': return (a.expires_at ?? '').localeCompare(b.expires_at ?? '');\n case 'budget': return (a.max_budget ?? Infinity) - (b.max_budget ?? Infinity);\n case 'limits': return (a.tpm_limit ?? Infinity) - (b.tpm_limit ?? Infinity) || (a.rpm_limit ?? Infinity) - (b.rpm_limit ?? Infinity);\n case 'models': return (a.models ?? []).join(',').localeCompare((b.models ?? []).join(','));\n default: return 0;\n }\n}\n\nexport const KeysTable: React.FC<KeysTableProps> = ({\n keys,\n models,\n loading,\n onGenerateKeyClick,\n onUpdateKey,\n onBlockKey,\n onUnblockKey,\n onResetKeySpend,\n onDeleteKey,\n onPruneExpiredKeys,\n}) => {\n const [editingKey, setEditingKey] = useState<VirtualKey | null>(null);\n const [editForm, setEditForm] = useState<UpdateKeyRequest>({});\n const [editSubmitting, setEditSubmitting] = useState(false);\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 const [sortKey, setSortKey] = useState<SortKey>('created');\n const [sortDirection, setSortDirection] = useState<SortDirection>('desc');\n\n const handleSort = (nextSortKey: SortKey) => {\n if (sortKey === nextSortKey) {\n setSortDirection(current => current === 'asc' ? 'desc' : 'asc');\n } else {\n setSortKey(nextSortKey);\n setSortDirection('asc');\n }\n };\n\n const filteredKeys = useMemo(() => {\n let result = keys;\n if (filterText.trim()) {\n const q = filterText.toLowerCase();\n result = keys.filter(k =>\n (k.key_alias ?? '').toLowerCase().includes(q) ||\n k.models?.some(m => m.toLowerCase().includes(q)),\n );\n }\n return [...result].sort((a, b) => {\n const comparison = compareKeys(a, b, sortKey);\n return sortDirection === 'asc' ? comparison : -comparison;\n });\n }, [keys, filterText, sortKey, sortDirection]);\n\n const editSelectedModels = models.filter(m => (editForm.models || []).includes(m.model_name));\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 // eslint-disable-next-line no-console -- TODO: surface via a snackbar/alert instead of console-only\n console.error('Failed to update key:', error);\n } finally {\n setEditSubmitting(false);\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 // eslint-disable-next-line no-console -- TODO: surface via a snackbar/alert instead of console-only\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 const ctx = formatContextWindow(m.max_input_tokens, m.max_output_tokens);\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 {ctx && (\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ ml: 1 }}>\n {ctx}\n </Typography>\n )}\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 const renderTableBody = () => {\n if (loading) {\n return (\n <TableRow>\n <TableCell colSpan={8} sx={{ py: 2 }}>\n <Skeleton variant=\"rounded\" height={140} />\n </TableCell>\n </TableRow>\n );\n }\n if (filteredKeys.length === 0) {\n return (\n <TableRow>\n <TableCell colSpan={8}>\n {filterText ? (\n <EmptyState\n message=\"No keys match that filter\"\n hint=\"Try a different alias or model name.\"\n />\n ) : (\n <EmptyState\n message=\"No keys yet\"\n hint=\"Generate your first key to start calling models.\"\n action={\n <Button\n variant=\"contained\"\n color=\"primary\"\n size=\"small\"\n disableElevation\n startIcon={<Add />}\n onClick={onGenerateKeyClick}\n sx={{ mt: 1 }}\n >\n Generate Your First Key\n </Button>\n }\n />\n )}\n </TableCell>\n </TableRow>\n );\n }\n return filteredKeys.map((key) => {\n const keyId = key.token ?? key.key;\n const isBlocking = blockingKeyId === keyId;\n const keyModels = key.models ?? [];\n return (\n <TableRow\n key={keyId}\n sx={\n key.blocked\n ? theme => ({\n // A left rule reads as \"suspended\" without greying the row into\n // illegibility the way a full background tint does.\n boxShadow: `inset 3px 0 0 0 ${theme.palette.error.main}`,\n '& td': { color: theme.palette.text.secondary },\n })\n : undefined\n }\n >\n <TableCell>\n <Box display=\"flex\" alignItems=\"center\" gap={1} flexWrap=\"wrap\">\n <Typography variant=\"body2\">\n {key.key_alias || '\u2014'}\n </Typography>\n {key.blocked && <StatusPill label=\"Blocked\" tone=\"danger\" />}\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={theme => ({\n fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',\n fontSize: 12,\n bgcolor: alpha(theme.palette.text.primary, theme.palette.mode === 'dark' ? 0.08 : 0.05),\n px: 0.75,\n py: 0.375,\n borderRadius: '5px',\n })}\n >\n {shortKeyId(keyId)}\n </Typography>\n <IconButton\n size=\"small\"\n onClick={() => copyToClipboard(keyId)}\n title=\"Copy Key ID\"\n sx={quietIconButtonSx('accent')}\n >\n <ContentCopy sx={{ fontSize: 15 }} />\n </IconButton>\n </Box>\n </TableCell>\n <TableCell>\n <Typography variant=\"body2\" color=\"text.secondary\">{formatDate(key.created_at)}</Typography>\n </TableCell>\n <TableCell>\n <ExpiryCell 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\" color=\"text.secondary\" sx={{ fontVariantNumeric: 'tabular-nums' }}>\n {key.tpm_limit ?? '\u221E'} / {key.rpm_limit ?? '\u221E'}\n </Typography>\n </TableCell>\n <TableCell>\n {keyModels.length === 0 ? (\n <Typography variant=\"body2\" color=\"text.secondary\">All models</Typography>\n ) : (\n <Box display=\"flex\" gap={0.5} flexWrap=\"wrap\">\n {keyModels.slice(0, 2).map((model) => (\n <TagChip key={model} label={model} title={model} />\n ))}\n {keyModels.length > 2 && (\n <TagChip\n label={`+${keyModels.length - 2}`}\n mono={false}\n title={keyModels.slice(2).join(', ')}\n />\n )}\n </Box>\n )}\n </TableCell>\n <TableCell align=\"right\">\n <Box display=\"flex\" justifyContent=\"flex-end\" gap={0.25}>\n <IconButton\n size=\"small\"\n onClick={() => handleOpenEdit(key)}\n title=\"Edit key\"\n sx={quietIconButtonSx('accent')}\n >\n <Edit fontSize=\"small\" />\n </IconButton>\n <IconButton\n size=\"small\"\n onClick={() => handleToggleBlock(key)}\n disabled={isBlocking}\n title={key.blocked ? 'Unblock key' : 'Block key \u2014 suspends without revoking'}\n sx={quietIconButtonSx('warning')}\n >\n {keyBlockIcon(isBlocking, key.blocked)}\n </IconButton>\n <IconButton\n size=\"small\"\n onClick={() => setDeleteConfirmId(keyId)}\n title=\"Revoke key\"\n sx={quietIconButtonSx('danger')}\n >\n <Delete fontSize=\"small\" />\n </IconButton>\n </Box>\n </TableCell>\n </TableRow>\n );\n });\n };\n\n return (\n <>\n <SectionCard\n title=\"Virtual Keys\"\n subtitle={\n loading\n ? 'Loading\u2026'\n : `${filteredKeys.length}${filterText ? ` of ${keys.length}` : ''} key${filteredKeys.length === 1 ? '' : 's'}`\n }\n flush\n actions={\n <>\n <TextField\n size=\"small\"\n label=\"Search alias or model\"\n placeholder=\"Search 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\" color=\"disabled\" />\n </InputAdornment>\n ),\n }}\n />\n {expiredKeys.length > 0 && (\n <Button\n variant=\"outlined\"\n color=\"inherit\"\n startIcon={<Autorenew />}\n onClick={() => setPruneConfirmCount(expiredKeys.length)}\n sx={theme => ({\n color: theme.palette.text.secondary,\n borderColor: theme.palette.divider,\n '&:hover': {\n color: theme.palette.error.main,\n borderColor: alpha(theme.palette.error.main, 0.5),\n bgcolor: alpha(theme.palette.error.main, 0.06),\n },\n })}\n >\n Prune expired ({expiredKeys.length})\n </Button>\n )}\n <Button\n variant=\"contained\"\n color=\"primary\"\n disableElevation\n startIcon={<Add />}\n onClick={onGenerateKeyClick}\n >\n Generate New Key\n </Button>\n </>\n }\n >\n <TableContainer>\n <Table size=\"small\" sx={dataTableSx}>\n <TableHead>\n <TableRow>\n <TableCell sortDirection={sortKey === 'alias' ? sortDirection : false}>\n <TableSortLabel active={sortKey === 'alias'} direction={sortKey === 'alias' ? sortDirection : 'asc'} onClick={() => handleSort('alias')}>Alias</TableSortLabel>\n </TableCell>\n <TableCell>Key ID</TableCell>\n <TableCell sortDirection={sortKey === 'created' ? sortDirection : false}>\n <TableSortLabel active={sortKey === 'created'} direction={sortKey === 'created' ? sortDirection : 'asc'} onClick={() => handleSort('created')}>Created</TableSortLabel>\n </TableCell>\n <TableCell sortDirection={sortKey === 'expires' ? sortDirection : false}>\n <TableSortLabel active={sortKey === 'expires'} direction={sortKey === 'expires' ? sortDirection : 'asc'} onClick={() => handleSort('expires')}>Expires</TableSortLabel>\n </TableCell>\n <TableCell sortDirection={sortKey === 'budget' ? sortDirection : false}>\n <TableSortLabel active={sortKey === 'budget'} direction={sortKey === 'budget' ? sortDirection : 'asc'} onClick={() => handleSort('budget')}>Budget</TableSortLabel>\n </TableCell>\n <TableCell sortDirection={sortKey === 'limits' ? sortDirection : false}>\n <TableSortLabel active={sortKey === 'limits'} direction={sortKey === 'limits' ? sortDirection : 'asc'} onClick={() => handleSort('limits')}>TPM / RPM</TableSortLabel>\n </TableCell>\n <TableCell sortDirection={sortKey === 'models' ? sortDirection : false}>\n <TableSortLabel active={sortKey === 'models'} direction={sortKey === 'models' ? sortDirection : 'asc'} onClick={() => handleSort('models')}>Models</TableSortLabel>\n </TableCell>\n <TableCell align=\"right\">Actions</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {renderTableBody()}\n </TableBody>\n </Table>\n </TableContainer>\n </SectionCard>\n\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 helperText=\"Max tokens per minute this key can consume across all models. Leave blank for no limit.\"\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 helperText=\"Max requests per minute this key can make across all models. Leave blank for no limit.\"\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 {/* 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", "export const fmtUsd = (n: number) => `$${(n ?? 0).toFixed(n < 1 ? 4 : 2)}`;\nexport const fmtInt = (n: number) => (n ?? 0).toLocaleString();\n\n/**\n * Estimate how many tokens a USD budget buys at a given per-token price.\n * Returns null when the price is missing or non-positive.\n */\nexport const estimateTokensFromBudget = (budget: number, pricePerToken?: number): number | null => {\n if (!pricePerToken || pricePerToken <= 0 || !budget || budget <= 0) return null;\n return Math.floor(budget / pricePerToken);\n};\n", "import React, { useState, useEffect, useMemo } from 'react';\nimport Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport Dialog from '@mui/material/Dialog';\nimport DialogTitle from '@mui/material/DialogTitle';\nimport DialogContent from '@mui/material/DialogContent';\nimport DialogActions from '@mui/material/DialogActions';\nimport TextField from '@mui/material/TextField';\nimport MenuItem from '@mui/material/MenuItem';\nimport Button from '@mui/material/Button';\nimport IconButton from '@mui/material/IconButton';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport Autocomplete from '@mui/material/Autocomplete';\nimport Checkbox from '@mui/material/Checkbox';\nimport FormControlLabel from '@mui/material/FormControlLabel';\nimport Alert from '@mui/material/Alert';\nimport Accordion from '@mui/material/Accordion';\nimport AccordionSummary from '@mui/material/AccordionSummary';\nimport AccordionDetails from '@mui/material/AccordionDetails';\nimport Tabs from '@mui/material/Tabs';\nimport Tab from '@mui/material/Tab';\nimport { ContentCopy, Code, ExpandMore } from '@mui/icons-material';\nimport { VirtualKey, ModelInfo, TeamInfo, GenerateKeyRequest, GenerateKeyResponse, LiteLlmConfig } from '../types';\nimport { estimateTokensFromBudget, fmtInt } from '../format';\n\ninterface GenerateKeyDialogProps {\n open: boolean;\n onClose: () => void;\n keys: VirtualKey[];\n models: ModelInfo[];\n teams: TeamInfo[];\n /** Current user's LiteLLM user id, used to pre-fill a default key alias. */\n username?: string;\n /** Controls for the \"Generate New Key\" form; see litellm.keyGeneration in app-config.yaml. */\n keyGenerationSettings?: { allowUnlimitedBudget: boolean; teamRequired: boolean };\n onGenerateKey: (request: GenerateKeyRequest) => Promise<GenerateKeyResponse>;\n onGetConfig: () => Promise<LiteLlmConfig>;\n}\n\nconst generateDefaultAlias = (username?: string): string => {\n const base = (username || 'user')\n .split('@')[0]\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '') || 'user';\n const hash = Math.random().toString(36).slice(2, 8);\n return `${base}-${hash}`;\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\nfunction trimSlash(url: string): string {\n return url.replace(/\\/+$/, '');\n}\n\n// LiteLLM sentinel: a team's `models` list is `[\"all-proxy-models\"]` when the\n// team isn't restricted to specific models. A team's `models` entries can\n// also be access-group names (see litellm model_info.access_groups) rather\n// than literal model_name values. Treating either case as a literal\n// model_name allowlist matches nothing, which previously made the whole\n// \"Models\" field disappear for such teams.\nconst ALL_PROXY_MODELS = 'all-proxy-models';\n\nfunction isModelAllowedByTeam(model: ModelInfo, teamModels?: string[]): boolean {\n if (!teamModels || teamModels.length === 0) return true;\n if (teamModels.includes(ALL_PROXY_MODELS)) return true;\n if (teamModels.includes(model.model_name)) return true;\n return !!model.access_groups?.some(group => teamModels.includes(group));\n}\n\ninterface Snippets {\n curl: string;\n openai: string;\n opencode: string;\n pi: string;\n claudeCode: string;\n publicEndpoint: string;\n}\n\nfunction buildSnippets(baseUrl: string, key: string, model: string): Snippets {\n const base = trimSlash(baseUrl);\n const apiBase = `${base}/v1`;\n return {\n publicEndpoint: apiBase,\n curl: `curl ${apiBase}/chat/completions \\\\\n -H \"Authorization: Bearer ${key}\" \\\\\n -H \"Content-Type: application/json\" \\\\\n -d '{\n \"model\": \"${model}\",\n \"messages\": [{ \"role\": \"user\", \"content\": \"Hello!\" }]\n }'`,\n openai: `from openai import OpenAI\n\nclient = OpenAI(\n api_key=\"${key}\",\n base_url=\"${apiBase}\",\n)\n\nresponse = client.chat.completions.create(\n model=\"${model}\",\n messages=[{ \"role\": \"user\", \"content\": \"Hello!\" }],\n)\nprint(response.choices[0].message.content)`,\n opencode: `{\n \"$schema\": \"https://opencode.ai/config.json\",\n \"provider\": {\n \"litellm\": {\n \"npm\": \"@ai-sdk/openai-compatible\",\n \"name\": \"LiteLLM\",\n \"options\": {\n \"baseURL\": \"${apiBase}\",\n \"apiKey\": \"${key}\"\n },\n \"models\": {\n \"${model}\": {}\n }\n }\n }\n}`,\n pi: `{\n \"litellm\": {\n \"baseUrl\": \"${apiBase}\",\n \"apiKey\": \"${key}\",\n \"api\": \"openai-completions\",\n \"models\": [\n { \"id\": \"${model}\", \"name\": \"${model}\" }\n ]\n }\n}`,\n claudeCode: `# Option 1 \u2014 Static key (Method 1: Unified Endpoint)\nexport ANTHROPIC_AUTH_TOKEN=\"${key}\"\nexport ANTHROPIC_BASE_URL=\"${base}\"\nclaude --model ${model}\n\n# Option 2 \u2014 Dynamic key via helper script\n# 1. Create ~/bin/get-litellm-key.sh:\ncat > ~/bin/get-litellm-key.sh << 'SCRIPT'\n#!/bin/bash\ncurl -s -X POST ${base}/key/generate \\\\\n -H \"Authorization: Bearer ${key}\" \\\\\n -H \"Content-Type: application/json\" \\\\\n -d '{}' | jq -r '.key'\nSCRIPT\nchmod +x ~/bin/get-litellm-key.sh\n\n# 2. Add to ~/.claude/settings.json:\n# { \"apiKeyHelper\": \"~/bin/get-litellm-key.sh\" }\n\n# 3. Set refresh interval (optional, default 1h):\nexport CLAUDE_CODE_API_KEY_HELPER_TTL_MS=3600000`,\n };\n}\n\nfunction aliasHelperText(aliasError: boolean, aliasDuplicate: boolean): string | undefined {\n if (aliasError) return 'Alias is required';\n if (aliasDuplicate) return 'This alias is already used by one of your keys \u2014 LiteLLM requires aliases to be unique across all keys';\n return undefined;\n}\n\nfunction teamHelperText(teamError: boolean, teamRequired: boolean): string {\n if (teamError) return 'Team is required';\n if (teamRequired) return 'Bind this key to a team for scoped access';\n return 'Optional: bind this key to a specific team for scoped access';\n}\n\nfunction budgetHelperText(budgetInvalid: boolean, budgetEstimate: number | null): string | undefined {\n if (budgetInvalid) return 'Enter a positive budget or tick \"Unlimited\"';\n if (budgetEstimate !== null) return `\u2248 ${fmtInt(budgetEstimate)} tokens at the selected model's rate`;\n return undefined;\n}\n\ninterface SnippetTabsProps {\n snippets: Snippets;\n model: string;\n onCopy: (text: string) => void;\n}\n\ntype SnippetTab = 'curl' | 'openai' | 'opencode' | 'pi' | 'claude-code';\n\nconst SNIPPET_FILE_HINTS: Partial<Record<SnippetTab, string>> = {\n opencode: 'Add to ~/.config/opencode/opencode.json',\n pi: 'Add to ~/.pi/agent/models.json',\n 'claude-code': 'Requires Claude Code CLI installed',\n};\n\nconst SnippetTabs: React.FC<SnippetTabsProps> = ({ snippets, model, onCopy }) => {\n const [tab, setTab] = useState<SnippetTab>('curl');\n const snippetKey = tab === 'claude-code' ? 'claudeCode' : tab;\n const code = snippets[snippetKey as keyof Snippets];\n const fileHint = SNIPPET_FILE_HINTS[tab];\n return (\n <Box>\n <Tabs value={tab} onChange={(_, v) => setTab(v as SnippetTab)} sx={{ mb: 1 }} variant=\"scrollable\">\n <Tab label=\"curl\" value=\"curl\" />\n <Tab label=\"OpenAI SDK\" value=\"openai\" />\n <Tab label=\"opencode\" value=\"opencode\" />\n <Tab label=\"pi\" value=\"pi\" />\n <Tab label=\"Claude Code\" value=\"claude-code\" />\n </Tabs>\n {fileHint && (\n <Typography variant=\"caption\" color=\"text.secondary\" display=\"block\" mb={0.5}>\n {fileHint}\n </Typography>\n )}\n <Box\n position=\"relative\"\n p={1.5}\n sx={{ backgroundColor: 'action.hover', border: '1px solid', borderColor: 'divider', borderRadius: 1 }}\n >\n <IconButton\n size=\"small\"\n onClick={() => onCopy(code)}\n title=\"Copy snippet\"\n sx={{ position: 'absolute', top: 4, right: 4 }}\n >\n <ContentCopy fontSize=\"small\" />\n </IconButton>\n <Typography\n component=\"pre\"\n sx={{\n fontFamily: 'monospace',\n fontSize: 12,\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-all',\n mb: 0,\n pr: 4,\n }}\n >\n {code}\n </Typography>\n {model && (\n <Typography variant=\"caption\" color=\"text.secondary\" display=\"block\" mt={1}>\n Using model \u201C{model}\u201D \u2014 swap it for any model you have access to.\n </Typography>\n )}\n </Box>\n </Box>\n );\n};\n\nexport const GenerateKeyDialog: React.FC<GenerateKeyDialogProps> = ({\n open,\n onClose,\n keys,\n models,\n teams,\n username,\n keyGenerationSettings,\n onGenerateKey,\n onGetConfig,\n}) => {\n const [formData, setFormData] = useState<GenerateKeyRequest>(emptyForm());\n const [unlimitedBudget, setUnlimitedBudget] = useState(false);\n const [submitting, setSubmitting] = useState(false);\n const [newKeyValue, setNewKeyValue] = useState<string | null>(null);\n const [newKeySnippets, setNewKeySnippets] = useState<Snippets | null>(null);\n const [newKeyModel, setNewKeyModel] = useState<string>('');\n const [generateError, setGenerateError] = useState<string | null>(null);\n\n // Re-arm the form each time the dialog opens so a stale result from a\n // previous run (or another user's session) is never shown.\n useEffect(() => {\n if (open) {\n setFormData({ ...emptyForm(), alias: generateDefaultAlias(username) });\n setUnlimitedBudget(false);\n setNewKeyValue(null);\n setNewKeySnippets(null);\n setNewKeyModel('');\n setGenerateError(null);\n }\n }, [open, username]);\n\n const allowUnlimitedBudget = keyGenerationSettings?.allowUnlimitedBudget ?? false;\n const teamRequired = keyGenerationSettings?.teamRequired ?? true;\n\n const selectedTeam = teams.find(t => t.team_id === formData.team_id) ?? null;\n\n // Once a team is selected, only offer models that team is actually allowed\n // to use \u2014 `models` here is already scoped to what the user can access.\n const availableModels = useMemo(() => {\n return models.filter(m => isModelAllowedByTeam(m, selectedTeam?.models));\n }, [models, selectedTeam]);\n\n const selectedModels = availableModels.filter(m => (formData.models || []).includes(m.model_name));\n\n // \u2500\u2500 Inline form validation \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 aliasError = !(formData.alias || '').trim();\n const teamError = teamRequired && !formData.team_id;\n const budgetInvalid =\n !unlimitedBudget &&\n (formData.max_budget === undefined ||\n formData.max_budget === null ||\n formData.max_budget <= 0);\n const canGenerate = !aliasError && !teamError && !budgetInvalid && !submitting;\n\n // Issue #35: warn (don't block) when the alias already matches one of the\n // user's loaded keys \u2014 LiteLLM enforces globally-unique aliases.\n const aliasDuplicate = !!formData.alias && keys.some(k => k.key_alias === formData.alias);\n\n // \u2500\u2500 Budget estimate at the selected model's input rate \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const budgetEstimate = useMemo(() => {\n if (unlimitedBudget || budgetInvalid) return null;\n const inputCosts = selectedModels\n .map(m => m.input_cost_per_token)\n .filter((c): c is number => typeof c === 'number' && c > 0);\n if (inputCosts.length === 0) return null;\n const pricePerToken = Math.max(...inputCosts);\n return estimateTokensFromBudget(formData.max_budget ?? 0, pricePerToken);\n }, [formData.max_budget, selectedModels, unlimitedBudget, budgetInvalid]);\n\n const handleGenerate = async () => {\n setSubmitting(true);\n setGenerateError(null);\n try {\n const request: GenerateKeyRequest = {\n ...formData,\n max_budget: unlimitedBudget ? null : formData.max_budget,\n };\n const response = await onGenerateKey(request);\n // When the key allows all models (none explicitly picked), fall back to\n // the first model actually allowed for the chosen team so snippets show\n // a working example rather than an empty model name.\n const model = formData.models?.[0] ?? availableModels[0]?.model_name ?? '';\n setNewKeyValue(response.key);\n setNewKeyModel(model);\n setNewKeySnippets(null);\n try {\n const config = await onGetConfig();\n setNewKeySnippets(buildSnippets(config.baseUrl, response.key, model));\n } catch {\n // Snippets are a nice-to-have; the raw key is still shown.\n }\n setFormData(emptyForm());\n setUnlimitedBudget(false);\n } catch (error: any) {\n setGenerateError(error?.message ?? 'Failed to generate key');\n } finally {\n setSubmitting(false);\n }\n };\n\n const handleClose = () => {\n onClose();\n setGenerateError(null);\n setNewKeyValue(null);\n setNewKeySnippets(null);\n setFormData(emptyForm());\n setUnlimitedBudget(false);\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 const ctx = formatContextWindow(m.max_input_tokens, m.max_output_tokens);\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 {ctx && (\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ ml: 1 }}>\n {ctx}\n </Typography>\n )}\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 const renderTeamField = () => {\n if (teams.length > 0) {\n return (\n <Autocomplete\n options={teams}\n getOptionLabel={t => t.team_alias || t.team_id}\n value={selectedTeam}\n onChange={(_e, team) => {\n const restrictedModels = (formData.models || []).filter(name => {\n const model = models.find(m => m.model_name === name);\n return model ? isModelAllowedByTeam(model, team?.models) : false;\n });\n setFormData({ ...formData, team_id: team?.team_id, models: restrictedModels });\n }}\n renderInput={params => (\n <TextField\n {...params}\n label=\"Team\"\n error={teamError}\n helperText={teamHelperText(teamError, teamRequired)}\n required={teamRequired}\n fullWidth\n />\n )}\n />\n );\n }\n if (teamRequired) {\n return (\n <Typography variant=\"body2\" color=\"error\">\n Team selection is required, but you don't belong to any team yet \u2014 contact your administrator.\n </Typography>\n );\n }\n return null;\n };\n\n return (\n <Dialog open={open} onClose={handleClose} 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\n {newKeySnippets && (\n <Box mt={2}>\n <Typography variant=\"caption\" color=\"text.secondary\" display=\"block\" gutterBottom>\n Public endpoint \u2014 paste into any tool's base URL / API base field\n </Typography>\n <Box\n display=\"flex\"\n alignItems=\"center\"\n gap={1}\n p={1.5}\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', fontSize: 13, wordBreak: 'break-all', flex: 1 }}\n >\n {newKeySnippets.publicEndpoint}\n </Typography>\n <IconButton size=\"small\" onClick={() => copyToClipboard(newKeySnippets.publicEndpoint)}>\n <ContentCopy fontSize=\"small\" />\n </IconButton>\n </Box>\n </Box>\n )}\n\n {newKeySnippets && (\n <Box mt={3}>\n <Box display=\"flex\" alignItems=\"center\" gap={1} mb={1}>\n <Code fontSize=\"small\" color=\"action\" />\n <Typography variant=\"subtitle2\">\n Start calling the proxy \u2014 paste and run\n </Typography>\n </Box>\n <SnippetTabs snippets={newKeySnippets} model={newKeyModel} onCopy={copyToClipboard} />\n </Box>\n )}\n </Box>\n ) : (\n <Box display=\"flex\" flexDirection=\"column\" gap={2} mt={1}>\n {generateError && (\n <Alert severity=\"error\" onClose={() => setGenerateError(null)}>\n {generateError}\n </Alert>\n )}\n <TextField\n label=\"Alias\"\n value={formData.alias || ''}\n onChange={(e) => {\n setFormData({ ...formData, alias: e.target.value });\n setGenerateError(null);\n }}\n error={aliasError}\n color={aliasDuplicate ? 'warning' : undefined}\n helperText={aliasHelperText(aliasError, aliasDuplicate)}\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 {renderTeamField()}\n\n {availableModels.length > 0 && (\n <Autocomplete\n multiple\n options={availableModels}\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\n {...params}\n label=\"Models\"\n helperText={\n selectedTeam\n ? 'Leave empty to allow all models available to this team'\n : 'Leave empty to allow all models'\n }\n fullWidth\n />\n )}\n />\n )}\n\n {allowUnlimitedBudget && (\n <FormControlLabel\n control={\n <Checkbox\n checked={unlimitedBudget}\n onChange={(e) => {\n setUnlimitedBudget(e.target.checked);\n if (e.target.checked) {\n setFormData({ ...formData, max_budget: null });\n } else {\n setFormData({ ...formData, max_budget: 100 });\n }\n }}\n />\n }\n label=\"Unlimited budget\"\n />\n )}\n <TextField\n label=\"Max Budget (USD)\"\n type=\"number\"\n value={unlimitedBudget ? '' : formData.max_budget ?? ''}\n onChange={(e) =>\n setFormData({ ...formData, max_budget: e.target.value ? Number(e.target.value) : undefined })\n }\n error={budgetInvalid}\n helperText={budgetHelperText(budgetInvalid, budgetEstimate)}\n disabled={unlimitedBudget}\n required\n fullWidth\n />\n <Accordion disableGutters elevation={0} sx={{ border: '1px solid', borderColor: 'divider', '&:before': { display: 'none' } }}>\n <AccordionSummary expandIcon={<ExpandMore />}>\n <Typography variant=\"body2\" fontWeight={600}>Advanced</Typography>\n </AccordionSummary>\n <AccordionDetails sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>\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 helperText=\"Max tokens per minute this key can consume across all models. Leave blank for no limit.\"\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 helperText=\"Max requests per minute this key can make across all models. Leave blank for no limit.\"\n fullWidth\n />\n </AccordionDetails>\n </Accordion>\n </Box>\n )}\n </DialogContent>\n <DialogActions>\n {newKeyValue ? (\n <Button onClick={handleClose} variant=\"contained\" color=\"success\">\n Done\n </Button>\n ) : (\n <>\n <Button onClick={handleClose}>Cancel</Button>\n <Button\n onClick={handleGenerate}\n variant=\"contained\"\n color=\"primary\"\n disabled={!canGenerate}\n >\n {submitting ? <CircularProgress size={24} /> : 'Generate'}\n </Button>\n </>\n )}\n </DialogActions>\n </Dialog>\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\nfunction formatContextWindow(\n maxInput?: number,\n maxOutput?: number,\n): string | null {\n if (!maxInput && !maxOutput) return null;\n const fmt = (n?: number) => {\n if (!n) return null;\n if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\n if (n >= 1_000) return `${Math.round(n / 1000)}K`;\n return String(n);\n };\n const inPart = fmt(maxInput);\n const outPart = fmt(maxOutput);\n if (inPart && outPart) return `ctx ${inPart} in / ${outPart} out`;\n if (inPart) return `ctx ${inPart}`;\n if (outPart) return `ctx ${outPart} out`;\n return null;\n}\n", "import React, { FC, useState, useEffect, useMemo } from 'react';\nimport Dialog from '@mui/material/Dialog';\nimport DialogTitle from '@mui/material/DialogTitle';\nimport DialogContent from '@mui/material/DialogContent';\nimport DialogActions from '@mui/material/DialogActions';\nimport TextField from '@mui/material/TextField';\nimport Button from '@mui/material/Button';\nimport Alert from '@mui/material/Alert';\nimport Checkbox from '@mui/material/Checkbox';\nimport FormControlLabel from '@mui/material/FormControlLabel';\nimport Autocomplete from '@mui/material/Autocomplete';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport MenuItem from '@mui/material/MenuItem';\nimport Box from '@mui/material/Box';\nimport Divider from '@mui/material/Divider';\nimport Typography from '@mui/material/Typography';\nimport IconButton from '@mui/material/IconButton';\nimport Paper from '@mui/material/Paper';\nimport Table from '@mui/material/Table';\nimport TableBody from '@mui/material/TableBody';\nimport TableCell from '@mui/material/TableCell';\nimport TableContainer from '@mui/material/TableContainer';\nimport TableHead from '@mui/material/TableHead';\nimport TableRow from '@mui/material/TableRow';\nimport { Delete as DeleteIcon } from '@mui/icons-material';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { catalogApiRef } from '@backstage/plugin-catalog-react';\nimport { stringifyEntityRef, UserEntity } from '@backstage/catalog-model';\nimport { useAsync } from 'react-use';\nimport { TeamInfo, ModelInfo, LiteLlmConfig, CreateTeamRequest, UpdateTeamRequest, VectorStoreInfo, McpServerInfo } from '../types';\nimport { StatusPill, dataTableSx } from './ui';\n\n/** A catalog User entity flattened into what the member picker needs. */\ninterface UserOption {\n ref: string;\n label: string;\n email?: string;\n}\n\n/** Spend-reset periods offered for a team budget (LiteLLM `budget_duration`). */\nconst BUDGET_DURATION_OPTIONS: Array<{ value: string; label: string }> = [\n { value: '1d', label: 'Daily (1d)' },\n { value: '7d', label: 'Weekly (7d)' },\n { value: '30d', label: 'Monthly (30d)' },\n { value: '90d', label: 'Quarterly (90d)' },\n { value: '365d', label: 'Yearly (365d)' },\n];\nconst DEFAULT_BUDGET_DURATION = '30d';\nconst FALLBACK_BUDGET_CEILING = 1000;\n\ninterface ManageTeamDialogProps {\n open: boolean;\n onClose: () => void;\n mode: 'create' | 'edit';\n team?: TeamInfo;\n allModels: ModelInfo[];\n config?: LiteLlmConfig;\n onSubmit: (payload: CreateTeamRequest | UpdateTeamRequest) => Promise<void>;\n /** When true, the Members section (edit mode only) exposes add/remove controls. */\n canManageMembers?: boolean;\n /** Called to add a member; the parent is expected to refresh `team` on success. */\n onAddMember?: (userEntityRef: string, maxBudgetInTeam?: number) => Promise<void>;\n /** Called to remove a member; the parent is expected to refresh `team` on success. */\n onRemoveMember?: (userEntityRef: string) => Promise<void>;\n /** When true, the Knowledge Bases section (edit mode only) is shown. */\n canManageKnowledgeBases?: boolean;\n /** Vector stores the caller may attach (already allowlist-filtered server-side). */\n vectorStores?: VectorStoreInfo[];\n /** Called to replace the team's attached knowledge bases; parent refreshes `team`. */\n onSaveKnowledgeBases?: (vectorStoreIds: string[]) => Promise<void>;\n /** When true, the MCP Servers section (edit mode only) is shown. */\n canManageMcpServers?: boolean;\n /** MCP servers the caller may attach (already allowlist-filtered server-side). */\n mcpServers?: McpServerInfo[];\n /** Called to replace the team's attached MCP servers; parent refreshes `team`. */\n onSaveMcpServers?: (mcpServerIds: string[]) => Promise<void>;\n}\n\nexport const ManageTeamDialog: FC<ManageTeamDialogProps> = ({\n open,\n onClose,\n mode,\n team,\n allModels,\n config,\n onSubmit,\n canManageMembers,\n onAddMember,\n onRemoveMember,\n canManageKnowledgeBases,\n vectorStores,\n onSaveKnowledgeBases,\n canManageMcpServers,\n mcpServers,\n onSaveMcpServers,\n}) => {\n const [alias, setAlias] = useState('');\n const [models, setModels] = useState<string[]>([]);\n const [maxBudget, setMaxBudget] = useState<string>('');\n const [unlimited, setUnlimited] = useState(false);\n const [budgetDuration, setBudgetDuration] = useState('');\n const [submitting, setSubmitting] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n // memberQuery is the text shown in the picker; memberRef is the entity ref\n // that will actually be submitted (either a picked catalog user's ref, or\n // whatever was typed, as a fallback for catalog lookup failures).\n const [memberQuery, setMemberQuery] = useState('');\n const [memberRef, setMemberRef] = useState('');\n const [memberBudget, setMemberBudget] = useState('');\n const [memberBusy, setMemberBusy] = useState(false);\n const [memberError, setMemberError] = useState<string | null>(null);\n\n const [kbIds, setKbIds] = useState<string[]>([]);\n const [kbBusy, setKbBusy] = useState(false);\n const [kbError, setKbError] = useState<string | null>(null);\n\n const [mcpIds, setMcpIds] = useState<string[]>([]);\n const [mcpBusy, setMcpBusy] = useState(false);\n const [mcpError, setMcpError] = useState<string | null>(null);\n\n const allowUnlimitedBudget = config?.teamManagement?.allowUnlimitedBudget ?? false;\n const maxBudgetCeiling =\n config?.teamManagement?.maxBudgetCeiling ?? FALLBACK_BUDGET_CEILING;\n\n const members = useMemo(() => team?.members_with_roles ?? [], [team]);\n const showMembers = mode === 'edit' && !!canManageMembers;\n\n // Catalog users for the member picker, fetched only while the Members\n // section is actually visible. Failures degrade to an empty option list \u2014\n // the field stays usable as a plain entity-ref input either way.\n const catalogApi = useApi(catalogApiRef);\n const { value: catalogUsers, loading: usersLoading } = useAsync(async () => {\n if (!open || !showMembers) return [] as UserEntity[];\n try {\n const { items } = await catalogApi.getEntities({\n filter: { kind: 'User' },\n fields: ['kind', 'metadata.namespace', 'metadata.name', 'metadata.title', 'spec.profile'],\n });\n return items as UserEntity[];\n } catch {\n return [] as UserEntity[];\n }\n }, [open, showMembers, catalogApi]);\n\n const userOptions = useMemo<UserOption[]>(() => {\n const existingEmails = new Set(\n members\n .map(m => m.user_email?.toLowerCase())\n .filter((e): e is string => !!e),\n );\n return (catalogUsers ?? [])\n .map(e => {\n const ref = stringifyEntityRef(e);\n const displayName =\n e.spec?.profile?.displayName || e.metadata.title || e.metadata.name;\n const email = e.spec?.profile?.email;\n return {\n ref,\n email,\n label: email ? `${displayName} (${email})` : displayName,\n };\n })\n .filter(o => !(o.email && existingEmails.has(o.email.toLowerCase())))\n .sort((a, b) => a.label.localeCompare(b.label));\n }, [catalogUsers, members]);\n\n useEffect(() => {\n if (open) {\n if (mode === 'edit' && team) {\n setAlias(team.team_alias ?? '');\n setModels(team.models ?? []);\n setMaxBudget(\n team.max_budget ? String(team.max_budget) : String(maxBudgetCeiling),\n );\n setUnlimited(allowUnlimitedBudget && !team.max_budget);\n setBudgetDuration(team.budget_duration ?? DEFAULT_BUDGET_DURATION);\n } else {\n setAlias('');\n setModels([]);\n // Default a new team's budget to the ceiling; the admin can lower it.\n setMaxBudget(String(maxBudgetCeiling));\n setUnlimited(allowUnlimitedBudget);\n setBudgetDuration(DEFAULT_BUDGET_DURATION);\n }\n setError(null);\n setMemberQuery('');\n setMemberRef('');\n setMemberBudget('');\n setMemberError(null);\n setKbIds(team?.object_permission?.vector_stores ?? []);\n setKbError(null);\n setMcpIds(team?.object_permission?.mcp_servers ?? []);\n setMcpError(null);\n }\n }, [open, mode, team, allowUnlimitedBudget, maxBudgetCeiling]);\n\n const handleSubmit = async () => {\n setError(null);\n\n if (!alias.trim()) {\n setError('Team alias is required');\n return;\n }\n\n if (models.length === 0) {\n setError('At least one model is required');\n return;\n }\n\n if (!unlimited) {\n if (!maxBudget) {\n setError('Budget is required when unlimited budgets are disabled');\n return;\n }\n const budget = parseFloat(maxBudget);\n if (isNaN(budget) || budget <= 0) {\n setError('Budget must be a positive number');\n return;\n }\n if (budget > maxBudgetCeiling) {\n setError(`Budget cannot exceed $${maxBudgetCeiling}`);\n return;\n }\n }\n\n try {\n setSubmitting(true);\n let payload: CreateTeamRequest | UpdateTeamRequest;\n\n if (mode === 'create') {\n payload = {\n team_alias: alias.trim(),\n models,\n ...(unlimited ? { max_budget: null } : { max_budget: parseFloat(maxBudget) }),\n ...(budgetDuration && { budget_duration: budgetDuration }),\n } as CreateTeamRequest;\n } else {\n payload = {\n team_alias: alias.trim(),\n models,\n ...(unlimited ? { max_budget: null } : { max_budget: parseFloat(maxBudget) }),\n ...(budgetDuration && { budget_duration: budgetDuration }),\n } as UpdateTeamRequest;\n }\n\n await onSubmit(payload);\n onClose();\n } catch (err) {\n setError(err instanceof Error ? err.message : 'An error occurred');\n } finally {\n setSubmitting(false);\n }\n };\n\n const handleAddMember = async () => {\n if (!onAddMember || !memberRef.trim()) return;\n setMemberError(null);\n const budget = memberBudget ? parseFloat(memberBudget) : undefined;\n if (budget !== undefined && (isNaN(budget) || budget <= 0)) {\n setMemberError('Max budget in team must be a positive number');\n return;\n }\n try {\n setMemberBusy(true);\n await onAddMember(memberRef.trim(), budget);\n setMemberQuery('');\n setMemberRef('');\n setMemberBudget('');\n } catch (err) {\n setMemberError(err instanceof Error ? err.message : 'Failed to add member');\n } finally {\n setMemberBusy(false);\n }\n };\n\n const handleRemoveMember = async (userId: string) => {\n if (!onRemoveMember) return;\n setMemberError(null);\n try {\n setMemberBusy(true);\n await onRemoveMember(userId);\n } catch (err) {\n setMemberError(err instanceof Error ? err.message : 'Failed to remove member');\n } finally {\n setMemberBusy(false);\n }\n };\n\n const handleSaveKnowledgeBases = async () => {\n if (!onSaveKnowledgeBases) return;\n setKbError(null);\n try {\n setKbBusy(true);\n await onSaveKnowledgeBases(kbIds);\n } catch (err) {\n setKbError(err instanceof Error ? err.message : 'Failed to save knowledge bases');\n } finally {\n setKbBusy(false);\n }\n };\n\n const handleSaveMcpServers = async () => {\n if (!onSaveMcpServers) return;\n setMcpError(null);\n try {\n setMcpBusy(true);\n await onSaveMcpServers(mcpIds);\n } catch (err) {\n setMcpError(err instanceof Error ? err.message : 'Failed to save MCP servers');\n } finally {\n setMcpBusy(false);\n }\n };\n\n const modelNames = allModels.map(m => m.model_name);\n // Keep an unusual existing value (e.g. \"14d\", \"1mo\") selectable so editing a\n // team doesn't silently rewrite its duration.\n const durationOptions = BUDGET_DURATION_OPTIONS.some(o => o.value === budgetDuration)\n ? BUDGET_DURATION_OPTIONS\n : [...BUDGET_DURATION_OPTIONS, { value: budgetDuration, label: budgetDuration }];\n const showKnowledgeBases = mode === 'edit' && !!canManageKnowledgeBases;\n const kbOptions = (vectorStores ?? []).map(v => v.id);\n const kbLabel = (id: string) =>\n (vectorStores ?? []).find(v => v.id === id)?.name ?? id;\n const showMcpServers = mode === 'edit' && !!canManageMcpServers;\n const mcpOptions = (mcpServers ?? []).map(s => s.id);\n const mcpLabel = (id: string) =>\n (mcpServers ?? []).find(s => s.id === id)?.name ?? id;\n\n return (\n <Dialog open={open} onClose={onClose} maxWidth=\"sm\" fullWidth>\n <DialogTitle>{mode === 'create' ? 'Create Team' : 'Edit Team'}</DialogTitle>\n <DialogContent sx={{ pt: 2, display: 'flex', flexDirection: 'column', gap: 2 }}>\n {error && <Alert severity=\"error\">{error}</Alert>}\n\n <TextField\n label=\"Team Alias\"\n value={alias}\n onChange={e => setAlias(e.target.value)}\n disabled={submitting}\n fullWidth\n />\n\n <Autocomplete\n multiple\n options={modelNames}\n value={models}\n onChange={(_, newValue) => setModels(newValue)}\n disabled={submitting}\n renderInput={params => (\n <TextField\n {...params}\n label=\"Models\"\n required\n helperText=\"At least one model is required here \u2014 this delegated flow only grants access to models your admin has allow-listed for team creation, not every proxy model. (Teams with no model restriction shown elsewhere were configured directly in LiteLLM.)\"\n />\n )}\n />\n\n <TextField\n label=\"Max Budget ($)\"\n type=\"number\"\n value={maxBudget}\n onChange={e => setMaxBudget(e.target.value)}\n disabled={submitting || unlimited}\n inputProps={{ min: 0, max: maxBudgetCeiling }}\n helperText={`Maximum: $${maxBudgetCeiling}`}\n fullWidth\n />\n\n {allowUnlimitedBudget && (\n <FormControlLabel\n control={<Checkbox checked={unlimited} onChange={e => setUnlimited(e.target.checked)} disabled={submitting} />}\n label=\"Unlimited Budget\"\n />\n )}\n\n <TextField\n select\n label=\"Budget Duration\"\n value={budgetDuration}\n onChange={e => setBudgetDuration(e.target.value)}\n disabled={submitting || unlimited}\n helperText=\"Spend-reset period for the team budget\"\n fullWidth\n >\n {durationOptions.map(o => (\n <MenuItem key={o.value} value={o.value}>\n {o.label}\n </MenuItem>\n ))}\n </TextField>\n\n {showMembers && (\n <Box>\n <Divider sx={{ my: 1 }} />\n <Typography variant=\"subtitle2\" sx={{ mb: 1 }}>\n Members\n </Typography>\n {memberError && (\n <Alert severity=\"error\" sx={{ mb: 1 }} onClose={() => setMemberError(null)}>\n {memberError}\n </Alert>\n )}\n {members.length === 0 ? (\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ mb: 1 }}>\n No members yet.\n </Typography>\n ) : (\n <TableContainer component={Paper} variant=\"outlined\" sx={{ borderRadius: 1.5, mb: 1.5 }}>\n <Table size=\"small\" sx={dataTableSx}>\n <TableHead>\n <TableRow>\n <TableCell>User</TableCell>\n <TableCell align=\"right\">Role</TableCell>\n <TableCell align=\"right\" sx={{ width: 40 }} />\n </TableRow>\n </TableHead>\n <TableBody>\n {members.map(m => (\n <TableRow key={m.user_id}>\n <TableCell>\n {m.user_email ? (\n <>\n <Typography variant=\"body2\">{m.user_email}</Typography>\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n sx={{ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace', fontSize: 11 }}\n >\n {m.user_id}\n </Typography>\n </>\n ) : (\n <Typography\n variant=\"body2\"\n sx={{ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace' }}\n >\n {m.user_id}\n </Typography>\n )}\n </TableCell>\n <TableCell align=\"right\">\n <StatusPill label={m.role} tone={m.role === 'admin' ? 'accent' : 'neutral'} dot={false} />\n </TableCell>\n <TableCell align=\"right\">\n <IconButton\n edge=\"end\"\n size=\"small\"\n aria-label={`remove ${m.user_id}`}\n disabled={memberBusy}\n onClick={() => handleRemoveMember(m.user_id)}\n >\n <DeleteIcon fontSize=\"small\" />\n </IconButton>\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </TableContainer>\n )}\n <Box sx={{ display: 'flex', gap: 1, alignItems: 'flex-start', flexWrap: 'wrap' }}>\n <Autocomplete\n freeSolo\n autoHighlight\n options={userOptions}\n loading={usersLoading}\n inputValue={memberQuery}\n onInputChange={(_, newInputValue, reason) => {\n setMemberQuery(newInputValue);\n // 'reset' fires when a selection sets the input programmatically \u2014\n // memberRef is already set by onChange in that case, so only sync\n // free typing (and clearing) back into the submitted ref here.\n if (reason === 'input' || reason === 'clear') {\n setMemberRef(newInputValue);\n }\n }}\n onChange={(_, newValue) => {\n if (newValue && typeof newValue !== 'string') {\n setMemberQuery(newValue.label);\n setMemberRef(newValue.ref);\n }\n }}\n getOptionLabel={o => (typeof o === 'string' ? o : o.label)}\n isOptionEqualToValue={(o, v) => o.ref === (typeof v === 'string' ? v : v.ref)}\n disabled={memberBusy}\n sx={{ flex: 1, minWidth: 260 }}\n renderInput={params => (\n <TextField\n {...params}\n label=\"Add member\"\n placeholder=\"Search by name or email\u2026\"\n size=\"small\"\n helperText=\"Pick a catalog user, or paste a user entity ref\"\n InputProps={{\n ...params.InputProps,\n endAdornment: (\n <>\n {usersLoading ? <CircularProgress color=\"inherit\" size={14} /> : null}\n {params.InputProps.endAdornment}\n </>\n ),\n }}\n />\n )}\n />\n <TextField\n label=\"Max budget in team ($)\"\n type=\"number\"\n value={memberBudget}\n onChange={e => setMemberBudget(e.target.value)}\n disabled={memberBusy}\n size=\"small\"\n sx={{ width: 160 }}\n />\n <Button\n onClick={handleAddMember}\n disabled={memberBusy || !memberRef.trim()}\n variant=\"outlined\"\n sx={{ mt: 0.5 }}\n >\n Add\n </Button>\n </Box>\n </Box>\n )}\n\n {showKnowledgeBases && (\n <Box>\n <Divider sx={{ my: 1 }} />\n <Typography variant=\"subtitle2\" sx={{ mb: 1 }}>\n Knowledge Bases\n </Typography>\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ mb: 1 }}>\n Attaching a knowledge base exposes its documents to every key in\n this team.\n </Typography>\n {kbError && (\n <Alert severity=\"error\" sx={{ mb: 1 }} onClose={() => setKbError(null)}>\n {kbError}\n </Alert>\n )}\n <Autocomplete\n multiple\n options={kbOptions}\n value={kbIds}\n getOptionLabel={kbLabel}\n onChange={(_, v) => setKbIds(v)}\n disabled={kbBusy}\n renderInput={params => (\n <TextField {...params} label=\"Attached knowledge bases\" />\n )}\n />\n <Box sx={{ display: 'flex', justifyContent: 'flex-end', mt: 1 }}>\n <Button\n onClick={handleSaveKnowledgeBases}\n disabled={kbBusy}\n variant=\"outlined\"\n >\n {kbBusy ? 'Saving\u2026' : 'Save knowledge bases'}\n </Button>\n </Box>\n </Box>\n )}\n\n {showMcpServers && (\n <Box>\n <Divider sx={{ my: 1 }} />\n <Typography variant=\"subtitle2\" sx={{ mb: 1 }}>\n MCP Servers\n </Typography>\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ mb: 1 }}>\n Attaching an MCP server lets every key in this team invoke that\n server's tools through the model \u2014 including any side effects\n those tools have.\n </Typography>\n {mcpError && (\n <Alert severity=\"error\" sx={{ mb: 1 }} onClose={() => setMcpError(null)}>\n {mcpError}\n </Alert>\n )}\n <Autocomplete\n multiple\n options={mcpOptions}\n value={mcpIds}\n getOptionLabel={mcpLabel}\n onChange={(_, v) => setMcpIds(v)}\n disabled={mcpBusy}\n renderInput={params => (\n <TextField {...params} label=\"Attached MCP servers\" />\n )}\n />\n <Box sx={{ display: 'flex', justifyContent: 'flex-end', mt: 1 }}>\n <Button\n onClick={handleSaveMcpServers}\n disabled={mcpBusy}\n variant=\"outlined\"\n >\n {mcpBusy ? 'Saving\u2026' : 'Save MCP servers'}\n </Button>\n </Box>\n </Box>\n )}\n </DialogContent>\n <DialogActions>\n <Button onClick={onClose} disabled={submitting}>\n Cancel\n </Button>\n <Button onClick={handleSubmit} disabled={submitting} variant=\"contained\">\n {submitting ? 'Saving...' : 'Save'}\n </Button>\n </DialogActions>\n </Dialog>\n );\n};\n", "import React, { useMemo, useState } from 'react';\nimport Paper from '@mui/material/Paper';\nimport Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport TextField from '@mui/material/TextField';\nimport MenuItem from '@mui/material/MenuItem';\nimport Grid from '@mui/material/Grid';\nimport Table from '@mui/material/Table';\nimport TableBody from '@mui/material/TableBody';\nimport TableCell from '@mui/material/TableCell';\nimport TableContainer from '@mui/material/TableContainer';\nimport TableHead from '@mui/material/TableHead';\nimport TableRow from '@mui/material/TableRow';\nimport Skeleton from '@mui/material/Skeleton';\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 Cell,\n} from 'recharts';\nimport {\n DateRange,\n UsageMetrics,\n ModelInfo,\n UserInfo,\n UsageModelBreakdown,\n UsageKeyBreakdown,\n} from '../types';\nimport { fmtUsd, fmtInt } from '../format';\nimport {\n ChartCard,\n ChartTooltip,\n EmptyState,\n Meter,\n MetricStrip,\n SectionCard,\n SegmentedControl,\n Tone,\n SeriesLegend,\n TagChip,\n chartColor,\n dataTableSx,\n fmtCompact,\n fmtDateShort,\n fmtUsdCompact,\n useChartTheme,\n SERIES,\n} from './ui';\n\ninterface UsageStatsProps {\n usage: UsageMetrics | null;\n models: ModelInfo[];\n dateRange: DateRange;\n currentPreset: DatePreset;\n onDateRangeChange: (range: DateRange, preset?: DatePreset) => 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 PRESET_LABELS: Record<DatePreset, string> = {\n today: 'Today',\n '24h': 'Last 24 hours',\n '7d': 'Last 7 days',\n '30d': 'Last 30 days',\n};\n\nconst fmtPct = (n: number) => `${(n * 100).toFixed(1)}%`;\n\n/** Green above 99%, amber down to 90%, red below. */\nfunction rateTone(rate: number): Tone {\n if (rate >= 0.99) return 'success';\n if (rate >= 0.9) return 'warning';\n return 'danger';\n}\n\nconst ChartSkeleton: React.FC<{ height?: number }> = ({ height = 240 }) => (\n <Skeleton variant=\"rounded\" height={height} />\n);\n\n/** Shows a loading skeleton, an empty-state message, or the chart itself. */\nconst ChartOrFallback: React.FC<{\n loading: boolean;\n empty: boolean;\n height?: number;\n children: React.ReactNode;\n}> = ({ loading, empty, height = 240, children }) => {\n if (loading) return <ChartSkeleton height={height} />;\n if (empty) return <EmptyState message=\"No data for this period\" height={height} />;\n return <>{children}</>;\n};\n\n/** Inline success-rate bar used in both breakdown tables. */\nconst SuccessRateCell: React.FC<{ rate: number; requests: number }> = ({ rate, requests }) => {\n if (requests === 0) return <Typography variant=\"body2\" color=\"text.secondary\">\u2014</Typography>;\n const tone = rateTone(rate);\n return (\n <Box display=\"flex\" alignItems=\"center\" gap={1}>\n {/* Fixed, not flexible: the success-rate column is the last one, so a\n flexible meter stretches across all the table's slack space. */}\n <Box width={72} flexShrink={0}>\n <Meter value={rate * 100} tone={tone} height={4} />\n </Box>\n <Typography\n variant=\"caption\"\n sx={{ fontVariantNumeric: 'tabular-nums', minWidth: 44 }}\n >\n {fmtPct(rate)}\n </Typography>\n </Box>\n );\n};\n\nexport const UsageStats: React.FC<UsageStatsProps> = ({\n usage,\n models,\n dateRange,\n currentPreset,\n onDateRangeChange,\n loading,\n userInfo,\n}) => {\n const chart = useChartTheme();\n const [selectedModel, setSelectedModel] = useState<string>('all');\n const [tab, setTab] = useState<TabKey>('costs');\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 }, preset);\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 // Keep the budget reference line inside the plot even when spend is far below it.\n const cumulativeDomain: any = maxBudget > 0\n ? [0, (dataMax: number) => Math.max(dataMax, maxBudget) * 1.05]\n : [0, 'auto'];\n\n const successTone: Tone = totalRequests === 0 ? 'neutral' : rateTone(overallSuccessRate);\n\n const metrics = [\n {\n label: 'Total spend',\n value: fmtUsd(usage?.total_spend ?? 0),\n hint: maxBudget > 0 ? `of ${fmtUsd(maxBudget)} budget` : undefined,\n tone: 'accent' as const,\n },\n {\n label: 'Requests',\n value: fmtInt(totalRequests),\n hint: `${fmtInt(usage?.failed_requests ?? 0)} failed`,\n tone: 'info' as const,\n },\n {\n label: 'Success rate',\n value: totalRequests > 0 ? fmtPct(overallSuccessRate) : '\u2014',\n hint: totalRequests > 0 ? `${fmtInt(usage?.successful_requests ?? 0)} succeeded` : undefined,\n tone: successTone,\n },\n {\n label: 'Tokens',\n value: fmtCompact(usage?.total_tokens ?? 0),\n hint: `${fmtCompact(usage?.prompt_tokens ?? 0)} in \u00B7 ${fmtCompact(usage?.completion_tokens ?? 0)} out`,\n tone: 'success' as const,\n },\n ];\n\n const renderKeyRows = () => {\n if (loading) {\n return (\n <TableRow>\n <TableCell colSpan={7} sx={{ py: 3 }}>\n <Skeleton variant=\"rounded\" height={80} />\n </TableCell>\n </TableRow>\n );\n }\n if (keyRows.length === 0) {\n return (\n <TableRow>\n <TableCell colSpan={7}><EmptyState message=\"No key activity in this period\" /></TableCell>\n </TableRow>\n );\n }\n return [...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\" sx={{ fontWeight: 600 }}>{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.slice(0, 3).map(m => (\n <TagChip key={m} label={m} title={m} />\n ))}\n {r.models.length > 3 && <TagChip label={`+${r.models.length - 3}`} mono={false} />}\n </Box>\n </TableCell>\n <TableCell align=\"right\">{fmtUsd(r.spend)}</TableCell>\n <TableCell align=\"right\">{fmtInt(r.apiRequests)}</TableCell>\n <TableCell align=\"right\">{fmtCompact(r.totalTokens)}</TableCell>\n <TableCell align=\"right\">{fmtInt(r.failedRequests)}</TableCell>\n <TableCell>\n <SuccessRateCell rate={r.successRate} requests={r.apiRequests} />\n </TableCell>\n </TableRow>\n ));\n };\n\n const renderModelRows = () => {\n if (loading) {\n return (\n <TableRow>\n <TableCell colSpan={8} sx={{ py: 3 }}>\n <Skeleton variant=\"rounded\" height={80} />\n </TableCell>\n </TableRow>\n );\n }\n if (modelRows.length === 0) {\n return (\n <TableRow>\n <TableCell colSpan={8}><EmptyState message=\"No model activity in this period\" /></TableCell>\n </TableRow>\n );\n }\n return [...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={1}>\n <Box sx={{ width: 8, height: 8, borderRadius: '50%', bgcolor: chartColor(r.model), flexShrink: 0 }} />\n <Typography variant=\"body2\" sx={{ fontWeight: 600 }}>{r.model}</Typography>\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\">{fmtCompact(r.promptTokens)}</TableCell>\n <TableCell align=\"right\">{fmtCompact(r.completionTokens)}</TableCell>\n <TableCell>\n <SuccessRateCell rate={r.successRate} requests={r.apiRequests} />\n </TableCell>\n </TableRow>\n ));\n };\n\n const periodSelect = (\n <TextField\n select\n size=\"small\"\n label=\"Period\"\n value={currentPreset}\n onChange={e => handlePresetChange(e.target.value as DatePreset)}\n sx={{ minWidth: 160 }}\n >\n {(Object.keys(PRESET_LABELS) as DatePreset[]).map(p => (\n <MenuItem key={p} value={p}>{PRESET_LABELS[p]}</MenuItem>\n ))}\n </TextField>\n );\n\n return (\n <SectionCard\n title=\"Usage Analytics\"\n subtitle={`${PRESET_LABELS[currentPreset]} \u00B7 ${dateRange.start.toLocaleDateString()} \u2013 ${dateRange.end.toLocaleDateString()}`}\n actions={periodSelect}\n >\n <MetricStrip metrics={metrics} />\n\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 2,\n flexWrap: 'wrap',\n mt: 2.5,\n mb: 2,\n }}\n >\n <SegmentedControl<TabKey>\n value={tab}\n onChange={setTab}\n options={[\n { value: 'costs', label: 'Costs' },\n { value: 'models', label: 'Model Activity' },\n { value: 'keys', label: 'Key Activity' },\n ]}\n />\n {tab === 'models' && (\n <TextField\n select\n size=\"small\"\n label=\"Model\"\n value={selectedModel}\n onChange={e => setSelectedModel(e.target.value)}\n sx={{ minWidth: 220 }}\n >\n <MenuItem value=\"all\">All models</MenuItem>\n {models.map(m => (\n <MenuItem key={m.model_name} value={m.model_name}>{m.model_name}</MenuItem>\n ))}\n </TextField>\n )}\n </Box>\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={2}>\n {/* Daily spend by model \u2014 the headline chart, given full width so the\n stack and its colour key stay legible with up to seven series. */}\n <Grid item xs={12}>\n <ChartCard title=\"Daily spend by model\" height={260}>\n <ChartOrFallback loading={loading} empty={modelSpendByDate.length === 0} height={260}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <AreaChart data={modelSpendByDate} margin={{ top: 4, right: 8, left: 0, bottom: 0 }}>\n <CartesianGrid {...chart.grid} />\n <XAxis dataKey=\"date\" tickFormatter={fmtDateShort} {...chart.axis} />\n <YAxis tickFormatter={fmtUsdCompact} width={56} {...chart.axis} />\n <Tooltip\n cursor={chart.cursor}\n content={<ChartTooltip valueFormatter={fmtUsd} hideZero />}\n />\n {topSpendModels.map(m => (\n <Area\n key={m}\n type=\"monotone\"\n dataKey={m}\n stackId=\"spend\"\n stroke={chartColor(m)}\n strokeWidth={1.5}\n fill={chartColor(m)}\n fillOpacity={0.28}\n />\n ))}\n </AreaChart>\n </ResponsiveContainer>\n </ChartOrFallback>\n {!loading && topSpendModels.length > 0 && (\n <SeriesLegend series={topSpendModels.map(m => ({ name: m, color: chartColor(m) }))} />\n )}\n </ChartCard>\n </Grid>\n\n <Grid item xs={12} md={6}>\n <ChartCard title=\"Daily token usage\">\n <ChartOrFallback loading={loading} empty={dailyData.length === 0}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <AreaChart data={dailyData} margin={{ top: 4, right: 8, left: 0, bottom: 0 }}>\n <CartesianGrid {...chart.grid} />\n <XAxis dataKey=\"date\" tickFormatter={fmtDateShort} {...chart.axis} />\n <YAxis tickFormatter={fmtCompact} width={48} {...chart.axis} />\n <Tooltip cursor={chart.cursor} content={<ChartTooltip valueFormatter={fmtInt} />} />\n <Legend {...chart.legend} />\n <Area type=\"monotone\" dataKey=\"promptTokens\" name=\"Input\" stackId=\"tok\" stroke={SERIES.input} strokeWidth={1.5} fill={SERIES.input} fillOpacity={0.25} />\n <Area type=\"monotone\" dataKey=\"completionTokens\" name=\"Output\" stackId=\"tok\" stroke={SERIES.output} strokeWidth={1.5} fill={SERIES.output} fillOpacity={0.25} />\n </AreaChart>\n </ResponsiveContainer>\n </ChartOrFallback>\n </ChartCard>\n </Grid>\n\n <Grid item xs={12} md={6}>\n <ChartCard title=\"Daily requests\">\n <ChartOrFallback loading={loading} empty={dailyData.length === 0}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart data={dailyData} margin={{ top: 4, right: 8, left: 0, bottom: 0 }} barCategoryGap=\"30%\">\n <CartesianGrid {...chart.grid} />\n <XAxis dataKey=\"date\" tickFormatter={fmtDateShort} {...chart.axis} />\n <YAxis tickFormatter={fmtCompact} width={48} {...chart.axis} />\n <Tooltip cursor={chart.cursor} content={<ChartTooltip valueFormatter={fmtInt} />} />\n <Legend {...chart.legend} />\n <Bar dataKey=\"successfulRequests\" name=\"Successful\" fill={SERIES.success} stackId=\"r\" />\n <Bar dataKey=\"failedRequests\" name=\"Failed\" fill={SERIES.failure} stackId=\"r\" radius={[3, 3, 0, 0]} />\n </BarChart>\n </ResponsiveContainer>\n </ChartOrFallback>\n </ChartCard>\n </Grid>\n\n <Grid item xs={12} md={6}>\n <ChartCard title=\"Daily success rate\">\n <ChartOrFallback loading={loading} empty={successRateData.length === 0}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <LineChart data={successRateData} margin={{ top: 4, right: 8, left: 0, bottom: 0 }}>\n <CartesianGrid {...chart.grid} />\n <XAxis dataKey=\"date\" tickFormatter={fmtDateShort} {...chart.axis} />\n <YAxis domain={[0, 100]} tickFormatter={v => `${v}%`} width={44} {...chart.axis} />\n <Tooltip\n cursor={chart.cursor}\n content={<ChartTooltip valueFormatter={(v: number) => `${v}%`} />}\n />\n <ReferenceLine y={100} stroke={SERIES.success} strokeDasharray=\"4 4\" strokeOpacity={0.5} />\n <Line\n type=\"monotone\"\n dataKey=\"successRate\"\n name=\"Success rate\"\n stroke={SERIES.input}\n strokeWidth={2}\n dot={{ r: 2.5, strokeWidth: 0, fill: SERIES.input }}\n activeDot={{ r: 4 }}\n />\n </LineChart>\n </ResponsiveContainer>\n </ChartOrFallback>\n </ChartCard>\n </Grid>\n\n <Grid item xs={12} md={6}>\n <ChartCard\n title={maxBudget > 0 ? 'Cumulative spend vs budget' : 'Cumulative spend'}\n meta={\n maxBudget > 0\n ? `${fmtUsd(totalCumSpend)} used \u00B7 ${fmtUsd(Math.max(0, maxBudget - totalCumSpend))} left`\n : undefined\n }\n >\n <ChartOrFallback loading={loading} empty={cumulativeData.length === 0}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <AreaChart data={cumulativeData} margin={{ top: 4, right: 8, left: 0, bottom: 0 }}>\n <CartesianGrid {...chart.grid} />\n <XAxis dataKey=\"date\" tickFormatter={fmtDateShort} {...chart.axis} />\n <YAxis\n tickFormatter={fmtUsdCompact}\n width={56}\n domain={cumulativeDomain}\n {...chart.axis}\n />\n <Tooltip\n cursor={chart.cursor}\n content={<ChartTooltip valueFormatter={fmtUsd} />}\n />\n {maxBudget > 0 && (\n <ReferenceLine\n y={maxBudget}\n stroke={SERIES.budget}\n strokeDasharray=\"5 4\"\n label={{ value: `Budget ${fmtUsd(maxBudget)}`, position: 'insideTopRight', fontSize: 10, fill: SERIES.budget }}\n />\n )}\n <Area\n type=\"monotone\"\n dataKey=\"cumulative\"\n name=\"Cumulative spend\"\n stroke={SERIES.spend}\n strokeWidth={2}\n fill={SERIES.spend}\n fillOpacity={0.18}\n />\n </AreaChart>\n </ResponsiveContainer>\n </ChartOrFallback>\n </ChartCard>\n </Grid>\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={2}>\n <Grid item xs={12} md={6}>\n <ChartCard title=\"Spend by model\" height={Math.max(200, topModelSpendBars.length * 34)}>\n <ChartOrFallback\n loading={loading}\n empty={topModelSpendBars.length === 0}\n height={Math.max(200, topModelSpendBars.length * 34)}\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart data={topModelSpendBars} layout=\"vertical\" margin={{ top: 0, right: 12, left: 0, bottom: 0 }}>\n <CartesianGrid {...chart.grid} vertical horizontal={false} />\n <XAxis type=\"number\" tickFormatter={fmtUsdCompact} {...chart.axis} />\n <YAxis type=\"category\" dataKey=\"model\" width={170} {...chart.axis} tick={{ fontSize: 10.5, fill: chart.axis.tick.fill }} />\n <Tooltip cursor={chart.cursor} content={<ChartTooltip valueFormatter={fmtUsd} labelFormatter={l => l} />} />\n <Bar dataKey=\"spend\" name=\"Spend\" radius={[0, 3, 3, 0]} barSize={14}>\n {topModelSpendBars.map(r => (\n <Cell key={r.model} fill={chartColor(r.model)} />\n ))}\n </Bar>\n </BarChart>\n </ResponsiveContainer>\n </ChartOrFallback>\n </ChartCard>\n </Grid>\n\n <Grid item xs={12} md={6}>\n <ChartCard title=\"Tokens by model\" height={Math.max(200, topModelSpendBars.length * 34)}>\n <ChartOrFallback\n loading={loading}\n empty={modelRows.length === 0}\n height={Math.max(200, topModelSpendBars.length * 34)}\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart data={topModelSpendBars} layout=\"vertical\" margin={{ top: 0, right: 12, left: 0, bottom: 0 }}>\n <CartesianGrid {...chart.grid} vertical horizontal={false} />\n <XAxis type=\"number\" tickFormatter={fmtCompact} {...chart.axis} />\n <YAxis type=\"category\" dataKey=\"model\" width={170} {...chart.axis} tick={{ fontSize: 10.5, fill: chart.axis.tick.fill }} />\n <Tooltip cursor={chart.cursor} content={<ChartTooltip valueFormatter={fmtInt} labelFormatter={l => l} />} />\n <Legend {...chart.legend} />\n <Bar dataKey=\"promptTokens\" name=\"Input\" fill={SERIES.input} stackId=\"t\" barSize={14} />\n <Bar dataKey=\"completionTokens\" name=\"Output\" fill={SERIES.output} stackId=\"t\" barSize={14} radius={[0, 3, 3, 0]} />\n </BarChart>\n </ResponsiveContainer>\n </ChartOrFallback>\n </ChartCard>\n </Grid>\n\n <Grid item xs={12}>\n <TableContainer component={Paper} variant=\"outlined\" sx={{ borderRadius: 2 }}>\n <Table size=\"small\" sx={dataTableSx}>\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\">Input</TableCell>\n <TableCell align=\"right\">Output</TableCell>\n <TableCell sx={{ width: 160 }}>Success rate</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {renderModelRows()}\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={2}>\n {(loading || topKeySpendBars.length > 0) && (\n <Grid item xs={12}>\n <ChartCard title=\"Spend by key\" height={Math.max(160, topKeySpendBars.length * 32)}>\n <ChartOrFallback\n loading={loading}\n empty={topKeySpendBars.length === 0}\n height={Math.max(160, topKeySpendBars.length * 32)}\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart data={topKeySpendBars} layout=\"vertical\" margin={{ top: 0, right: 12, left: 0, bottom: 0 }}>\n <CartesianGrid {...chart.grid} vertical horizontal={false} />\n <XAxis type=\"number\" tickFormatter={fmtUsdCompact} {...chart.axis} />\n <YAxis type=\"category\" dataKey=\"keyAlias\" width={160} {...chart.axis} tick={{ fontSize: 10.5, fill: chart.axis.tick.fill }} />\n <Tooltip cursor={chart.cursor} content={<ChartTooltip valueFormatter={fmtUsd} labelFormatter={l => l} />} />\n <Bar dataKey=\"spend\" name=\"Spend\" fill={SERIES.input} radius={[0, 3, 3, 0]} barSize={14} />\n </BarChart>\n </ResponsiveContainer>\n </ChartOrFallback>\n </ChartCard>\n </Grid>\n )}\n\n <Grid item xs={12}>\n <TableContainer component={Paper} variant=\"outlined\" sx={{ borderRadius: 2 }}>\n <Table size=\"small\" sx={dataTableSx}>\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={{ width: 160 }}>Success rate</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {renderKeyRows()}\n </TableBody>\n </Table>\n </TableContainer>\n </Grid>\n </Grid>\n )}\n </SectionCard>\n );\n};\n", "import React, { useState } from 'react';\nimport Paper from '@mui/material/Paper';\nimport Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport Skeleton from '@mui/material/Skeleton';\nimport Divider from '@mui/material/Divider';\nimport Table from '@mui/material/Table';\nimport TableBody from '@mui/material/TableBody';\nimport TableCell from '@mui/material/TableCell';\nimport TableHead from '@mui/material/TableHead';\nimport TableRow from '@mui/material/TableRow';\nimport TableContainer from '@mui/material/TableContainer';\nimport Collapse from '@mui/material/Collapse';\nimport IconButton from '@mui/material/IconButton';\nimport Button from '@mui/material/Button';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport { alpha } from '@mui/material/styles';\nimport { ExpandMore, Group, Add } 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 } from '../types';\nimport {\n ChartTooltip,\n EmptyState,\n Meter,\n SectionCard,\n Stat,\n StatusPill,\n TagChip,\n Tone,\n dataTableSx,\n fmtDateShort,\n fmtUsdCompact,\n useChartTheme,\n SERIES,\n} from './ui';\n\nfunction budgetTone(isOver: boolean, isNear: boolean): Tone {\n if (isOver) return 'danger';\n if (isNear) return 'warning';\n return 'accent';\n}\n\nconst fmtUsd2 = (n: number) => `$${(n ?? 0).toFixed(2)}`;\n\ninterface TeamCardProps {\n team: TeamInfo;\n usage: UsageMetrics | null;\n usageLoading: boolean;\n canManage?: boolean;\n onEditTeam?: (team: TeamInfo) => void;\n}\n\nconst TeamCard: React.FC<TeamCardProps> = ({ team, usage, usageLoading, canManage, onEditTeam }) => {\n const [expanded, setExpanded] = useState(false);\n const chart = useChartTheme();\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 const renderDailySpendSection = () => {\n if (usageLoading) {\n return (\n <Box display=\"flex\" justifyContent=\"center\" py={3}>\n <CircularProgress size={22} />\n </Box>\n );\n }\n if (dailyData.length === 0) return null;\n return (\n <Box mb={2.5}>\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n sx={{ display: 'block', fontSize: 11, fontWeight: 700, letterSpacing: '0.07em', textTransform: 'uppercase', mb: 1 }}\n >\n Daily spend\n </Typography>\n <Box height={150}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <AreaChart data={dailyData} margin={{ top: 4, right: 8, left: 0, bottom: 0 }}>\n <CartesianGrid {...chart.grid} />\n <XAxis dataKey=\"date\" tickFormatter={fmtDateShort} {...chart.axis} />\n <YAxis tickFormatter={fmtUsdCompact} width={52} {...chart.axis} />\n <Tooltip\n cursor={chart.cursor}\n content={<ChartTooltip valueFormatter={v => `$${v.toFixed(4)}`} />}\n />\n <Area\n type=\"monotone\"\n dataKey=\"spend\"\n name=\"Spend\"\n stroke={SERIES.spend}\n strokeWidth={2}\n fill={SERIES.spend}\n fillOpacity={0.18}\n />\n </AreaChart>\n </ResponsiveContainer>\n </Box>\n </Box>\n );\n };\n\n const sectionLabel = (label: string) => (\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n sx={{ display: 'block', fontSize: 11, fontWeight: 700, letterSpacing: '0.07em', textTransform: 'uppercase', mb: 1 }}\n >\n {label}\n </Typography>\n );\n\n return (\n <Paper variant=\"outlined\" sx={{ borderRadius: 2, p: 2.5 }}>\n <Box display=\"flex\" alignItems=\"center\" gap={1.5}>\n <Box\n sx={theme => ({\n width: 36,\n height: 36,\n borderRadius: 1.5,\n flexShrink: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n bgcolor: alpha(theme.palette.primary.main, 0.1),\n color: theme.palette.primary.main,\n })}\n >\n <Group fontSize=\"small\" />\n </Box>\n <Box flexGrow={1} minWidth={0}>\n <Typography variant=\"subtitle1\" sx={{ fontWeight: 600, lineHeight: 1.3 }}>\n {team.team_alias || 'Untitled team'}\n </Typography>\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n sx={{ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace', fontSize: 11 }}\n >\n {team.team_id}\n </Typography>\n </Box>\n {isOver && <StatusPill label=\"Over budget\" tone=\"danger\" />}\n {isNear && <StatusPill label=\"Near limit\" tone=\"warning\" />}\n {canManage && onEditTeam && (\n <Button\n size=\"small\"\n variant=\"text\"\n onClick={() => onEditTeam(team)}\n sx={{ textTransform: 'none' }}\n >\n Edit\n </Button>\n )}\n <IconButton\n size=\"small\"\n onClick={() => setExpanded(e => !e)}\n aria-label={expanded ? 'Hide team details' : 'Show team details'}\n aria-expanded={expanded}\n sx={theme => ({\n color: theme.palette.text.secondary,\n transform: expanded ? 'rotate(180deg)' : 'none',\n transition: theme.transitions.create('transform'),\n })}\n >\n <ExpandMore />\n </IconButton>\n </Box>\n\n {/* Fixed-track grid, capped in width, so the six stats line up across\n every team card instead of stretching to fill the row. */}\n <Box\n sx={{\n display: 'grid',\n gridTemplateColumns: { xs: 'repeat(3, minmax(0, 1fr))', sm: 'repeat(6, minmax(0, 1fr))' },\n gap: 2,\n mt: 2.5,\n maxWidth: 640,\n }}\n >\n <Stat label=\"Members\" value={team.members_with_roles?.length ?? '\u2014'} />\n <Stat label=\"Models\" value={team.models?.length ? team.models.length : 'All'} />\n <Stat label=\"Budget\" value={budget > 0 ? fmtUsd2(budget) : 'Unlimited'} />\n <Stat label=\"Spend\" value={fmtUsd2(spend)} />\n <Stat label=\"TPM\" value={team.tpm_limit && team.tpm_limit > 0 ? team.tpm_limit.toLocaleString() : '\u2014'} />\n <Stat label=\"RPM\" value={team.rpm_limit && team.rpm_limit > 0 ? team.rpm_limit.toLocaleString() : '\u2014'} />\n </Box>\n\n {budget > 0 && (\n <Box mt={2} maxWidth={640}>\n <Box display=\"flex\" justifyContent=\"space-between\" alignItems=\"baseline\" mb={0.75}>\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ fontVariantNumeric: 'tabular-nums' }}>\n {fmtUsd2(spend)} of {fmtUsd2(budget)}\n </Typography>\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ fontVariantNumeric: 'tabular-nums' }}>\n {budgetPct.toFixed(0)}%\n </Typography>\n </Box>\n <Meter value={budgetPct} tone={budgetTone(isOver, isNear)} height={5} />\n </Box>\n )}\n\n <Collapse in={expanded} unmountOnExit>\n <Divider sx={{ my: 2.5 }} />\n\n <Box mb={2.5}>\n {sectionLabel('Models')}\n {team.models?.length ? (\n <Box display=\"flex\" gap={0.5} flexWrap=\"wrap\">\n {team.models.map(m => (\n <TagChip key={m} label={m} title={m} />\n ))}\n </Box>\n ) : (\n <Typography variant=\"body2\" color=\"text.secondary\">All models allowed</Typography>\n )}\n </Box>\n\n {renderDailySpendSection()}\n\n <Box>\n {sectionLabel('Members')}\n {team.members_with_roles?.length ? (\n <TableContainer\n component={Paper}\n variant=\"outlined\"\n sx={{ borderRadius: 1.5 }}\n >\n <Table size=\"small\" sx={dataTableSx}>\n <TableHead>\n <TableRow>\n <TableCell>User</TableCell>\n <TableCell align=\"right\">Role</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {team.members_with_roles.map(m => (\n <TableRow key={m.user_id}>\n <TableCell>\n {m.user_email ? (\n <>\n <Typography variant=\"body2\">{m.user_email}</Typography>\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n sx={{ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace', fontSize: 11 }}\n >\n {m.user_id}\n </Typography>\n </>\n ) : (\n <Typography\n variant=\"body2\"\n sx={{ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace' }}\n >\n {m.user_id}\n </Typography>\n )}\n </TableCell>\n <TableCell align=\"right\">\n <StatusPill\n label={m.role}\n tone={m.role === 'admin' ? 'accent' : 'neutral'}\n dot={false}\n />\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </TableContainer>\n ) : (\n <Typography variant=\"body2\" color=\"text.secondary\">No members assigned.</Typography>\n )}\n </Box>\n </Collapse>\n </Paper>\n );\n};\n\ninterface TeamUsageProps {\n teams: TeamInfo[];\n loading: boolean;\n getTeamUsage: (teamId: string) => UsageMetrics | null;\n getTeamUsageLoading: (teamId: string) => boolean;\n canManage?: boolean;\n onEditTeam?: (team: TeamInfo) => void;\n /** When true (with `onCreateTeam`), a \"Create Team\" action renders in the section header. */\n canCreate?: boolean;\n onCreateTeam?: () => void;\n}\n\nexport const TeamUsage: React.FC<TeamUsageProps> = ({\n teams,\n loading,\n getTeamUsage,\n getTeamUsageLoading,\n canManage,\n onEditTeam,\n canCreate,\n onCreateTeam,\n}) => {\n const createAction =\n canCreate && onCreateTeam ? (\n <Button\n variant=\"contained\"\n color=\"primary\"\n disableElevation\n startIcon={<Add />}\n onClick={onCreateTeam}\n >\n Create Team\n </Button>\n ) : undefined;\n\n if (loading) {\n return (\n <SectionCard title=\"Teams\" actions={createAction}>\n <Skeleton variant=\"rounded\" height={120} sx={{ mb: 2 }} />\n <Skeleton variant=\"rounded\" height={120} />\n </SectionCard>\n );\n }\n\n if (!teams.length) {\n return (\n <SectionCard title=\"Teams\" actions={createAction}>\n <EmptyState\n message=\"You're not a member of any LiteLLM team yet.\"\n hint=\"Your account is provisioned, so you can still generate personal keys and use models. Ask an admin to add you to a team if you need a shared budget.\"\n />\n </SectionCard>\n );\n }\n\n return (\n <SectionCard\n title=\"Teams\"\n subtitle={`${teams.length} team${teams.length === 1 ? '' : 's'}`}\n actions={createAction}\n >\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>\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 canManage={canManage}\n onEditTeam={onEditTeam}\n />\n ))}\n </Box>\n </SectionCard>\n );\n};\n", "import React, { useState, useMemo, useCallback } from 'react';\nimport Box from '@mui/material/Box';\nimport Table from '@mui/material/Table';\nimport TableBody from '@mui/material/TableBody';\nimport TableCell from '@mui/material/TableCell';\nimport TableContainer from '@mui/material/TableContainer';\nimport TableHead from '@mui/material/TableHead';\nimport TableRow from '@mui/material/TableRow';\nimport Typography from '@mui/material/Typography';\nimport MenuItem from '@mui/material/MenuItem';\nimport Select from '@mui/material/Select';\nimport FormControl from '@mui/material/FormControl';\nimport InputLabel from '@mui/material/InputLabel';\nimport TextField from '@mui/material/TextField';\nimport InputAdornment from '@mui/material/InputAdornment';\nimport { Search } from '@mui/icons-material';\nimport ContentCopyIcon from '@mui/icons-material/ContentCopy';\nimport Tooltip from '@mui/material/Tooltip';\nimport Snackbar from '@mui/material/Snackbar';\nimport Alert from '@mui/material/Alert';\nimport { ModelInfo, TeamInfo } from '../types';\nimport { SectionCard, EmptyState, TagChip, dataTableSx, quietIconButtonSx } from './ui';\nimport { alpha, useTheme } from '@mui/material/styles';\n\ninterface ModelsTableProps {\n allModels: ModelInfo[];\n teams: TeamInfo[];\n loading: boolean;\n}\n\nconst ALL_PROXY_MODELS = 'all-proxy-models';\n\nfunction isModelAllowedByTeam(model: ModelInfo, teamModels?: string[]): boolean {\n if (!teamModels || teamModels.length === 0 || teamModels.includes(ALL_PROXY_MODELS)) return true;\n return teamModels.includes(model.model_name) ||\n !!model.access_groups?.some(group => teamModels.includes(group));\n}\n\nfunction fmtCostPerToken(cost?: number): string {\n if (cost === undefined || cost === null) return '\u2014';\n if (cost === 0) return '$0';\n if (cost < 0.000001) return `$${(cost * 1_000_000).toFixed(2)}/M`;\n if (cost < 0.001) return `$${(cost * 1000).toFixed(3)}/K`;\n return `$${cost.toFixed(4)}`;\n}\n\nfunction fmtTokens(n?: number): string {\n if (n === undefined || n === null) return '\u2014';\n if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\n if (n >= 1_000) return `${(n / 1_000).toFixed(0)}K`;\n return String(n);\n}\n\nexport const ModelsTable: React.FC<ModelsTableProps> = ({ allModels, teams, loading }) => {\n const theme = useTheme();\n const [selectedTeamId, setSelectedTeamId] = useState<string>('');\n const [filterText, setFilterText] = useState<string>('');\n const [copiedSnackbar, setCopiedSnackbar] = useState(false);\n\n const selectedTeam = useMemo(\n () => teams.find(t => t.team_id === selectedTeamId) ?? null,\n [teams, selectedTeamId],\n );\n\n const teamModels = useMemo(() => {\n if (!selectedTeam) return [];\n return allModels.filter(model => isModelAllowedByTeam(model, selectedTeam.models));\n }, [allModels, selectedTeam]);\n\n const filteredModels = useMemo(() => {\n const q = filterText.trim().toLowerCase();\n if (!q) return teamModels;\n return teamModels.filter(model =>\n model.model_name.toLowerCase().includes(q) ||\n (model.access_groups || []).some(group => group.toLowerCase().includes(q)),\n );\n }, [teamModels, filterText]);\n\n const handleCopyModelId = useCallback((modelId: string) => {\n navigator.clipboard.writeText(modelId).then(() => setCopiedSnackbar(true));\n }, []);\n\n const modeColor = (mode: string): string => {\n switch (mode) {\n case 'chat': return theme.palette.info.main;\n case 'embedding': return theme.palette.success.main;\n case 'completion': return theme.palette.primary.main;\n case 'image': return theme.palette.warning.main;\n default: return theme.palette.info.main;\n }\n };\n\n return (\n <SectionCard\n title=\"Available Models\"\n subtitle={\n selectedTeam\n ? `${filteredModels.length}${filterText.trim() ? ` of ${teamModels.length}` : ''} model${filteredModels.length === 1 ? '' : 's'}`\n : 'Select a team to view its models'\n }\n >\n <Box sx={{ px: 2.5, pb: 2.5, pt: 1, display: 'flex', gap: 2, flexWrap: 'wrap' }}>\n <FormControl size=\"small\" sx={{ minWidth: 240, mb: 2 }}>\n <InputLabel id=\"team-select-label\">Team</InputLabel>\n <Select\n labelId=\"team-select-label\"\n value={selectedTeamId}\n label=\"Team\"\n onChange={e => setSelectedTeamId(e.target.value)}\n >\n {teams.map(t => (\n <MenuItem key={t.team_id} value={t.team_id}>\n {t.team_alias ?? t.team_id}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n <TextField\n label=\"Filter Models\"\n size=\"small\"\n value={filterText}\n onChange={e => setFilterText(e.target.value)}\n disabled={!selectedTeamId}\n sx={{ minWidth: 240, mb: 2 }}\n InputProps={{\n startAdornment: (\n <InputAdornment position=\"start\">\n <Search fontSize=\"small\" />\n </InputAdornment>\n ),\n }}\n />\n </Box>\n\n {loading && (\n <EmptyState message=\"Loading models\u2026\" />\n )}\n\n {!loading && !selectedTeamId && (\n <EmptyState\n message=\"Select a team to see available models\"\n hint=\"Each team may have a different set of models assigned\"\n />\n )}\n\n {!loading && selectedTeamId && teamModels.length === 0 && (\n <EmptyState\n message=\"No models available for this team\"\n hint={allModels.length === 0 ? 'No models are configured in the system' : 'None of the team\\'s assigned models were found in the catalog'}\n />\n )}\n\n {!loading && selectedTeamId && teamModels.length > 0 && filteredModels.length === 0 && (\n <EmptyState\n message=\"No models match your search\"\n hint=\"Try a different search term\"\n />\n )}\n\n {!loading && filteredModels.length > 0 && (\n <TableContainer>\n <Table size=\"small\" sx={dataTableSx}>\n <TableHead>\n <TableRow>\n <TableCell>Model ID</TableCell>\n <TableCell>Mode</TableCell>\n <TableCell align=\"right\">Input Cost</TableCell>\n <TableCell align=\"right\">Output Cost</TableCell>\n <TableCell align=\"right\">Max Input</TableCell>\n <TableCell align=\"right\">Max Output</TableCell>\n <TableCell>Capabilities</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {filteredModels.map(m => (\n <TableRow key={m.model_name} hover>\n <TableCell>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>\n <Tooltip title={m.model_name} placement=\"top\">\n <span\n role=\"button\"\n tabIndex={0}\n aria-label=\"Copy model ID\"\n onClick={() => handleCopyModelId(m.model_name)}\n onKeyDown={e => e.key === 'Enter' && handleCopyModelId(m.model_name)}\n style={{ cursor: 'pointer', display: 'inline-flex' }}\n >\n <TagChip label={m.model_name} title=\"Copy model ID\" />\n </span>\n </Tooltip>\n <Tooltip title=\"Copy model ID\">\n <Box\n component=\"span\"\n role=\"button\"\n tabIndex={0}\n onClick={() => handleCopyModelId(m.model_name)}\n onKeyDown={e => e.key === 'Enter' && handleCopyModelId(m.model_name)}\n sx={quietIconButtonSx('accent')}\n style={{ cursor: 'pointer', display: 'inline-flex' }}\n >\n <ContentCopyIcon sx={{ fontSize: 14 }} />\n </Box>\n </Tooltip>\n </Box>\n </TableCell>\n <TableCell>\n <Box\n component=\"span\"\n sx={{\n display: 'inline-block',\n px: 0.75,\n py: 0.25,\n borderRadius: 1,\n fontSize: 11,\n fontWeight: 600,\n textTransform: 'capitalize',\n bgcolor: alpha(modeColor(m.mode), 0.1),\n color: modeColor(m.mode),\n }}\n >\n {m.mode}\n </Box>\n </TableCell>\n <TableCell align=\"right\">\n <Typography variant=\"body2\" sx={{ fontVariantNumeric: 'tabular-nums' }}>\n {fmtCostPerToken(m.input_cost_per_token)}\n </Typography>\n </TableCell>\n <TableCell align=\"right\">\n <Typography variant=\"body2\" sx={{ fontVariantNumeric: 'tabular-nums' }}>\n {fmtCostPerToken(m.output_cost_per_token)}\n </Typography>\n </TableCell>\n <TableCell align=\"right\">\n <Typography variant=\"body2\" sx={{ fontVariantNumeric: 'tabular-nums' }}>\n {fmtTokens(m.max_input_tokens)}\n </Typography>\n </TableCell>\n <TableCell align=\"right\">\n <Typography variant=\"body2\" sx={{ fontVariantNumeric: 'tabular-nums' }}>\n {fmtTokens(m.max_output_tokens)}\n </Typography>\n </TableCell>\n <TableCell>\n <Box sx={{ display: 'flex', gap: 0.5, flexWrap: 'wrap' }}>\n {m.supports_function_calling && (\n <TagChip label=\"Fn\" title=\"Function calling\" />\n )}\n {m.supports_vision && (\n <TagChip label=\"\uD83D\uDC41\" title=\"Vision\" />\n )}\n </Box>\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </TableContainer>\n )}\n\n <Snackbar\n open={copiedSnackbar}\n autoHideDuration={2000}\n onClose={() => setCopiedSnackbar(false)}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}\n >\n <Alert severity=\"success\" variant=\"filled\" sx={{ fontSize: 13 }}>\n Model ID copied to clipboard\n </Alert>\n </Snackbar>\n </SectionCard>\n );\n};\n", "import React, { useState, useCallback } from 'react';\nimport Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport Table from '@mui/material/Table';\nimport TableBody from '@mui/material/TableBody';\nimport TableCell from '@mui/material/TableCell';\nimport TableContainer from '@mui/material/TableContainer';\nimport TableHead from '@mui/material/TableHead';\nimport TableRow from '@mui/material/TableRow';\nimport TablePagination from '@mui/material/TablePagination';\nimport TextField from '@mui/material/TextField';\nimport MenuItem from '@mui/material/MenuItem';\nimport Skeleton from '@mui/material/Skeleton';\nimport Collapse from '@mui/material/Collapse';\nimport IconButton from '@mui/material/IconButton';\nimport Alert from '@mui/material/Alert';\nimport { alpha } from '@mui/material/styles';\nimport { KeyboardArrowDown } from '@mui/icons-material';\nimport { useAsync } from 'react-use';\nimport { LiteLlmApiInterface } from '../api';\nimport { AuditLogEntry, AuditLogsParams } from '../types';\nimport { EmptyState, SectionCard, StatusPill, Tone, dataTableSx } from './ui';\n\ninterface AuditLogProps {\n api: LiteLlmApiInterface;\n}\n\nconst ACTION_TONES: Record<string, Tone> = {\n created: 'success',\n deleted: 'danger',\n updated: 'warning',\n blocked: 'danger',\n unblocked: 'success',\n};\n\nfunction actionTone(action?: string): Tone {\n if (!action) return 'neutral';\n for (const [key, tone] of Object.entries(ACTION_TONES)) {\n if (action.toLowerCase().includes(key)) return tone;\n }\n return 'info';\n}\n\n/** `LiteLLM_VerificationToken` \u2192 `Key`; falls back to the raw table name. */\nconst TABLE_LABELS: Record<string, string> = {\n LiteLLM_VerificationToken: 'Key',\n LiteLLM_TeamTable: 'Team',\n LiteLLM_TeamMembership: 'Team member',\n LiteLLM_ObjectPermissionTable: 'Team access (KB / MCP)',\n LiteLLM_UserTable: 'User',\n};\n\nfunction prettyTableName(name?: string | null): string {\n if (!name) return '\u2014';\n return TABLE_LABELS[name] ?? name;\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>\n <TableCell sx={{ width: 40, pr: 0 }}>\n {hasDetail && (\n <IconButton\n size=\"small\"\n onClick={() => setOpen(o => !o)}\n aria-label={open ? 'Hide changes' : 'Show changes'}\n aria-expanded={open}\n sx={theme => ({\n color: theme.palette.text.secondary,\n transform: open ? 'rotate(180deg)' : 'none',\n transition: theme.transitions.create('transform'),\n })}\n >\n <KeyboardArrowDown fontSize=\"small\" />\n </IconButton>\n )}\n </TableCell>\n <TableCell sx={{ whiteSpace: 'nowrap' }}>\n <Typography variant=\"body2\" color=\"text.secondary\">{formatDateTime(entry.updated_at)}</Typography>\n </TableCell>\n <TableCell>\n {entry.action && <StatusPill label={entry.action} tone={actionTone(entry.action)} />}\n </TableCell>\n <TableCell>\n <Typography variant=\"body2\">{prettyTableName(entry.table_name)}</Typography>\n </TableCell>\n <TableCell>\n <Typography\n variant=\"body2\"\n component=\"code\"\n color=\"text.secondary\"\n title={entry.object_id ?? undefined}\n sx={{ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace', fontSize: 12 }}\n >\n {entry.object_id ? entry.object_id.slice(0, 20) + (entry.object_id.length > 20 ? '\u2026' : '') : '\u2014'}\n </Typography>\n </TableCell>\n <TableCell>{entry.changed_by ?? '\u2014'}</TableCell>\n </TableRow>\n {/* The `&&` selectors below double specificity so they beat the\n table-level `tbody td` rules in dataTableSx \u2014 otherwise the collapsed\n row keeps its cell padding and border, leaving an empty stripe\n between entries. */}\n {hasDetail && (\n <TableRow sx={{ '&&:hover': { bgcolor: 'transparent' } }}>\n <TableCell colSpan={6} sx={{ '&&': { py: 0, border: 0 } }}>\n <Collapse in={open} unmountOnExit>\n <Box\n display=\"flex\"\n gap={2}\n flexWrap=\"wrap\"\n sx={theme => ({\n p: 2,\n mb: 1.5,\n borderRadius: 1.5,\n bgcolor: alpha(theme.palette.text.primary, theme.palette.mode === 'dark' ? 0.05 : 0.03),\n })}\n >\n {entry.before_value && (\n <Box flex={1} minWidth={200}>\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n display=\"block\"\n mb={0.75}\n sx={{ fontSize: 10.5, fontWeight: 700, letterSpacing: '0.07em', textTransform: 'uppercase' }}\n >\n Before\n </Typography>\n <Typography component=\"pre\" variant=\"caption\" sx={{ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace', whiteSpace: 'pre-wrap', wordBreak: 'break-all', m: 0 }}>\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\n variant=\"caption\"\n color=\"text.secondary\"\n display=\"block\"\n mb={0.75}\n sx={{ fontSize: 10.5, fontWeight: 700, letterSpacing: '0.07em', textTransform: 'uppercase' }}\n >\n After\n </Typography>\n <Typography component=\"pre\" variant=\"caption\" sx={{ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace', whiteSpace: 'pre-wrap', wordBreak: 'break-all', m: 0 }}>\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\nfunction renderAuditLogBody(loading: boolean, entries: AuditLogEntry[]) {\n if (loading) {\n return (\n <TableRow>\n <TableCell colSpan={6} sx={{ py: 2 }}>\n <Skeleton variant=\"rounded\" height={160} />\n </TableCell>\n </TableRow>\n );\n }\n if (entries.length === 0) {\n return (\n <TableRow>\n <TableCell colSpan={6}>\n <EmptyState\n message=\"No audit events found\"\n hint=\"Try widening the filters or a different time window.\"\n />\n </TableCell>\n </TableRow>\n );\n }\n return entries.map(entry => <DetailRow key={entry.id} entry={entry} />);\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 <SectionCard\n title=\"Audit Log\"\n subtitle={loading ? 'Loading\u2026' : `${total.toLocaleString()} event${total === 1 ? '' : 's'}`}\n flush\n actions={\n <>\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: 150 }}\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: 150 }}\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_TeamMembership\">Team member</MenuItem>\n <MenuItem value=\"LiteLLM_ObjectPermissionTable\">Team access (KB / MCP)</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: 180 }}\n />\n </>\n }\n >\n {error && (\n <Box px={2.5} pb={2}>\n <Alert severity=\"error\">{error.message}</Alert>\n </Box>\n )}\n\n <TableContainer>\n <Table size=\"small\" sx={dataTableSx}>\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 {renderAuditLogBody(loading, entries)}\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 sx={theme => ({ borderTop: `1px solid ${theme.palette.divider}` })}\n />\n </SectionCard>\n );\n};\n", "import { createPermission } from '@backstage/plugin-permission-common';\n\n// NOTE: these MUST stay byte-for-byte in sync with\n// packages/plugin-litellm-backend/src/permissions.ts \u2014 permission identity is the `name`.\nexport const litellmTeamCreatePermission = createPermission({\n name: 'litellm.team.create',\n attributes: { action: 'create' },\n});\n\nexport const litellmTeamManagePermission = createPermission({\n name: 'litellm.team.manage',\n attributes: { action: 'update' },\n});\n\nexport const litellmTeamMembersManagePermission = createPermission({\n name: 'litellm.team.members.manage',\n attributes: { action: 'update' },\n});\n\nexport const litellmTeamKnowledgebaseManagePermission = createPermission({\n name: 'litellm.team.knowledgebase.manage',\n attributes: { action: 'update' },\n});\n\nexport const litellmTeamMcpManagePermission = createPermission({\n name: 'litellm.team.mcp.manage',\n attributes: { action: 'update' },\n});\n", "import React, { useState, useCallback, useMemo } from 'react';\nimport Box from '@mui/material/Box';\nimport Snackbar from '@mui/material/Snackbar';\nimport Alert from '@mui/material/Alert';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport Typography from '@mui/material/Typography';\nimport Paper from '@mui/material/Paper';\nimport Tabs from '@mui/material/Tabs';\nimport Tab from '@mui/material/Tab';\nimport { useAsync, useAsyncRetry } from 'react-use';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { usePermission } from '@backstage/plugin-permission-react';\nimport { DashboardHeader } from './DashboardHeader';\nimport { KeysTable } from './KeysTable';\nimport { GenerateKeyDialog } from './GenerateKeyDialog';\nimport { ManageTeamDialog } from './ManageTeamDialog';\nimport { UsageStats } from './UsageStats';\nimport { TeamUsage } from './TeamUsage';\nimport { ModelsTable } from './ModelsTable';\nimport { AuditLog } from './AuditLog';\nimport { liteLlmApiRef } from '../api';\nimport {\n litellmTeamCreatePermission,\n litellmTeamManagePermission,\n litellmTeamMembersManagePermission,\n litellmTeamKnowledgebaseManagePermission,\n litellmTeamMcpManagePermission,\n} from '../permissions';\nimport { DateRange, GenerateKeyRequest, GenerateKeyResponse, UpdateKeyRequest, UsageMetrics, CreateTeamRequest, UpdateTeamRequest, TeamInfo } from '../types';\n\nconst PERIOD_LS_KEY = 'litellm_usage_period';\ntype DatePreset = 'today' | '24h' | '7d' | '30d';\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 [currentPreset, setCurrentPreset] = useState<DatePreset>(() => {\n try { return (localStorage.getItem(PERIOD_LS_KEY) as DatePreset) ?? '7d'; } catch { return '7d'; }\n });\n const [activeTab, setActiveTab] = useState<'overview' | 'keys' | 'teams' | 'models' | 'audit'>('overview');\n\n const [snackbar, setSnackbar] = useState<{ message: string; severity: 'success' | 'warning' | 'error' } | null>(null);\n const [generateDialogOpen, setGenerateDialogOpen] = useState(false);\n const [manageTeam, setManageTeam] = useState<{ mode: 'create' | 'edit'; team?: TeamInfo } | 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, retry: refreshTeams } = useAsyncRetry(\n () => api.getTeams().catch(() => []),\n [api],\n );\n\n const { value: liteLlmConfig } = useAsync(() => api.getConfig(), [api]);\n\n // Teams the caller administers by group ownership (not membership). Only\n // fetched when team management is enabled; failures degrade to an empty list.\n const { value: managedTeams } = useAsync(\n async () =>\n liteLlmConfig?.teamManagement?.enabled\n ? api.getManagedTeams().catch(() => [])\n : [],\n [api, liteLlmConfig],\n );\n\n const { allowed: canCreateTeam } = usePermission({ permission: litellmTeamCreatePermission });\n const { allowed: canManageTeam } = usePermission({ permission: litellmTeamManagePermission });\n const { allowed: canManageMembers } = usePermission({ permission: litellmTeamMembersManagePermission });\n const { allowed: canManageKnowledgeBases } = usePermission({ permission: litellmTeamKnowledgebaseManagePermission });\n const { allowed: canManageMcpServers } = usePermission({ permission: litellmTeamMcpManagePermission });\n const teamMgmtEnabled = liteLlmConfig?.teamManagement?.enabled ?? false;\n const objectPermsEnabled = liteLlmConfig?.teamManagement?.objectPermissionsEnabled ?? false;\n\n const { value: vectorStores } = useAsync(\n async () =>\n objectPermsEnabled ? api.getVectorStores().catch(() => []) : [],\n [api, objectPermsEnabled],\n );\n const { value: mcpServers } = useAsync(\n async () =>\n objectPermsEnabled ? api.getMcpServers().catch(() => []) : [],\n [api, objectPermsEnabled],\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, preset?: DatePreset) => {\n setDateRange(range);\n if (preset) {\n setCurrentPreset(preset);\n }\n setTeamUsageCache({});\n setTeamUsageLoading({});\n }, [setDateRange, setCurrentPreset]);\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 try {\n const response = await api.generateKey(request);\n setSnackbar({ message: 'Key generated successfully', severity: 'success' });\n refreshKeys();\n return response;\n } catch (e: any) {\n setSnackbar({ message: `Failed to generate key: ${e.message}`, severity: 'error' });\n throw e;\n }\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 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 const pageTabs = (\n <Tabs\n value={activeTab}\n onChange={(_, v) => setActiveTab(v)}\n variant=\"scrollable\"\n scrollButtons=\"auto\"\n // Substring class matching so these survive a host MUI classname prefix\n // (Backstage renders `v5-MuiTabs-indicator`, not `MuiTabs-indicator`).\n sx={{\n minHeight: 44,\n '& [class*=\"MuiTabs-indicator\"]': { height: 2, borderRadius: '2px 2px 0 0' },\n '& [class*=\"MuiTab-root\"]': { minHeight: 44, textTransform: 'none', fontSize: 14 },\n }}\n >\n <Tab label=\"Overview\" value=\"overview\" />\n <Tab label=\"Keys\" value=\"keys\" />\n <Tab label=\"Teams\" value=\"teams\" />\n <Tab label=\"Models\" value=\"models\" />\n {userInfo.can_view_audit && <Tab label=\"Audit Log\" value=\"audit\" />}\n </Tabs>\n );\n\n return (\n <Box sx={{ p: 3, display: 'flex', flexDirection: 'column', gap: 2 }}>\n <DashboardHeader\n userInfo={userInfo}\n teams={teams ?? []}\n keys={keys ?? []}\n loading={userLoading || teamsLoading}\n onGenerateKeyClick={() => setGenerateDialogOpen(true)}\n tabs={pageTabs}\n />\n\n {activeTab === 'overview' && (\n <UsageStats\n usage={usage ?? null}\n models={allModels ?? []}\n dateRange={dateRange}\n currentPreset={currentPreset}\n onDateRangeChange={handleDateRangeChange}\n loading={usageLoading}\n userInfo={userInfo}\n />\n )}\n\n {activeTab === 'keys' && (\n <KeysTable\n keys={keys ?? []}\n models={allowedModels}\n loading={keysLoading || modelsLoading}\n onGenerateKeyClick={() => setGenerateDialogOpen(true)}\n onUpdateKey={handleUpdateKey}\n onBlockKey={handleBlockKey}\n onUnblockKey={handleUnblockKey}\n onResetKeySpend={handleResetKeySpend}\n onDeleteKey={handleDeleteKey}\n onPruneExpiredKeys={handlePruneExpiredKeys}\n />\n )}\n\n {activeTab === 'teams' && (() => {\n // Union of teams the user is a member of and teams their group owns,\n // de-duplicated by team_id (membership entries win on conflict).\n const teamsById = new Map<string, TeamInfo>();\n for (const t of managedTeams ?? []) teamsById.set(t.team_id, t);\n for (const t of teams ?? []) teamsById.set(t.team_id, t);\n const visibleTeams = Array.from(teamsById.values());\n return (\n <TeamUsage\n teams={visibleTeams}\n loading={teamsLoading}\n getTeamUsage={teamId => {\n if (teamUsageCache[teamId] === undefined) loadTeamUsage(teamId);\n return teamUsageCache[teamId] ?? null;\n }}\n getTeamUsageLoading={teamId => teamUsageLoading[teamId] ?? false}\n canManage={teamMgmtEnabled && canManageTeam}\n onEditTeam={t => setManageTeam({ mode: 'edit', team: t })}\n canCreate={teamMgmtEnabled && canCreateTeam}\n onCreateTeam={() => setManageTeam({ mode: 'create' })}\n />\n );\n })()}\n\n {activeTab === 'models' && (\n <ModelsTable\n allModels={allModels ?? []}\n teams={teams ?? []}\n loading={modelsLoading}\n />\n )}\n\n {activeTab === 'audit' && userInfo.can_view_audit && <AuditLog api={api} />}\n\n <GenerateKeyDialog\n open={generateDialogOpen}\n onClose={() => setGenerateDialogOpen(false)}\n keys={keys ?? []}\n models={allowedModels}\n teams={teams ?? []}\n username={userInfo.user_id}\n keyGenerationSettings={liteLlmConfig?.keyGeneration}\n onGenerateKey={handleGenerateKey}\n onGetConfig={() => api.getConfig()}\n />\n\n <ManageTeamDialog\n open={!!manageTeam}\n onClose={() => setManageTeam(null)}\n mode={manageTeam?.mode ?? 'create'}\n team={manageTeam?.team}\n allModels={allModels ?? []}\n config={liteLlmConfig}\n onSubmit={async payload => {\n if (manageTeam?.mode === 'edit' && manageTeam.team) {\n await api.updateTeam(manageTeam.team.team_id, payload as UpdateTeamRequest);\n } else {\n await api.createTeam(payload as CreateTeamRequest);\n }\n setSnackbar({ message: 'Team saved', severity: 'success' });\n refreshTeams();\n }}\n canManageMembers={teamMgmtEnabled && canManageMembers}\n onAddMember={async (userEntityRef, maxBudgetInTeam) => {\n if (!manageTeam?.team) return;\n const updated = await api.addTeamMember(manageTeam.team.team_id, {\n userEntityRef,\n ...(maxBudgetInTeam ? { maxBudgetInTeam } : {}),\n });\n setManageTeam(s => (s && s.team ? { ...s, team: updated } : s));\n refreshTeams();\n }}\n onRemoveMember={async userEntityRef => {\n if (!manageTeam?.team) return;\n const updated = await api.removeTeamMember(\n manageTeam.team.team_id,\n userEntityRef,\n );\n setManageTeam(s => (s && s.team ? { ...s, team: updated } : s));\n refreshTeams();\n }}\n canManageKnowledgeBases={\n teamMgmtEnabled && objectPermsEnabled && canManageKnowledgeBases\n }\n vectorStores={vectorStores ?? []}\n onSaveKnowledgeBases={async vectorStoreIds => {\n if (!manageTeam?.team) return;\n const updated = await api.setTeamKnowledgeBases(\n manageTeam.team.team_id,\n vectorStoreIds,\n );\n setManageTeam(s => (s && s.team ? { ...s, team: updated } : s));\n setSnackbar({ message: 'Knowledge bases updated', severity: 'success' });\n refreshTeams();\n }}\n canManageMcpServers={\n teamMgmtEnabled && objectPermsEnabled && canManageMcpServers\n }\n mcpServers={mcpServers ?? []}\n onSaveMcpServers={async mcpServerIds => {\n if (!manageTeam?.team) return;\n const updated = await api.setTeamMcpServers(\n manageTeam.team.team_id,\n mcpServerIds,\n );\n setManageTeam(s => (s && s.team ? { ...s, team: updated } : s));\n setSnackbar({ message: 'MCP servers updated', severity: 'success' });\n refreshTeams();\n }}\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 { GenerateKeyDialog } from './components/GenerateKeyDialog';\nexport { ManageTeamDialog } from './components/ManageTeamDialog';\nexport { LiteLlmApi, liteLlmApiRef } from './api';\nexport {\n litellmTeamCreatePermission,\n litellmTeamManagePermission,\n litellmTeamMembersManagePermission,\n litellmTeamKnowledgebaseManagePermission,\n litellmTeamMcpManagePermission,\n} from './permissions';\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 Paper from '@mui/material/Paper';\nimport Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport FormControl from '@mui/material/FormControl';\nimport Select from '@mui/material/Select';\nimport MenuItem from '@mui/material/MenuItem';\nimport Grid from '@mui/material/Grid';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport Alert from '@mui/material/Alert';\nimport { AreaChart, Area, ResponsiveContainer } from 'recharts';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { liteLlmApiRef } from '../api';\nimport { UsageMetrics, VirtualKey } from '../types';\nimport { fmtUsd, fmtInt } from '../format';\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\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 [usageError, setUsageError] = useState<string | null>(null);\n const [keysError, setKeysError] = 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 setUsageError(null);\n setKeysError(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.allSettled([api.getUsage(startDate, endDate), api.listKeys()]).then(\n ([usageResult, keysResult]) => {\n if (cancelled) return;\n if (usageResult.status === 'fulfilled') {\n setUsage(usageResult.value);\n } else {\n setUsage(null);\n setUsageError(usageResult.reason?.message ?? 'Failed to load usage data');\n }\n if (keysResult.status === 'fulfilled') {\n setKeys(keysResult.value);\n } else {\n setKeys([]);\n setKeysError(keysResult.reason?.message ?? 'Failed to load keys');\n }\n setLoading(false);\n },\n );\n\n return () => {\n cancelled = true;\n };\n }, [api, period]);\n\n const partialFailure =\n !loading && (usageError || keysError) && (usage || keys.length > 0);\n const totalFailure = !loading && usageError && keysError;\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 && totalFailure && (\n <Alert severity=\"error\" sx={{ mt: 1 }}>\n {usageError ?? 'Failed to load usage data'}\n </Alert>\n )}\n\n {/* Content */}\n {!loading && !totalFailure && (\n <>\n {partialFailure && (\n <Alert severity=\"warning\" sx={{ mt: 1, mb: 1 }}>\n {usageError\n ? `Usage data unavailable (${usageError}).`\n : ''}\n {keysError\n ? ` Key list unavailable (${keysError}).` : ''}\n {' Showing what loaded.'}\n </Alert>\n )}\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
+ "names": ["React", "Box", "ButtonBase", "Paper", "Typography", "import_react", "import_Box", "import_Typography", "import_Paper", "import_styles", "React", "Box", "Typography", "Paper", "Skeleton", "Button", "Divider", "React", "Typography", "CircularProgress", "Box", "import_react", "import_Button", "import_Box", "import_Typography", "import_Skeleton", "import_styles", "import_icons_material", "TableRow", "TableCell", "Skeleton", "Button", "IconButton", "TextField", "InputAdornment", "TableContainer", "Table", "TableHead", "TableSortLabel", "TableBody", "Dialog", "DialogTitle", "DialogContent", "Autocomplete", "DialogActions", "fmtCost", "formatContextWindow", "import_react", "import_Box", "import_Typography", "import_Dialog", "import_DialogTitle", "import_DialogContent", "import_DialogActions", "import_TextField", "import_Button", "import_IconButton", "import_CircularProgress", "import_Autocomplete", "import_icons_material", "React", "Box", "Tabs", "Tab", "Typography", "IconButton", "Autocomplete", "TextField", "Dialog", "DialogTitle", "DialogContent", "Alert", "MenuItem", "FormControlLabel", "Checkbox", "Accordion", "AccordionSummary", "AccordionDetails", "DialogActions", "Button", "CircularProgress", "import_react", "import_Dialog", "import_DialogTitle", "import_DialogContent", "import_DialogActions", "import_TextField", "import_Button", "import_Alert", "import_Checkbox", "import_FormControlLabel", "import_Autocomplete", "import_CircularProgress", "import_MenuItem", "import_Box", "import_Divider", "import_Typography", "import_IconButton", "import_Paper", "import_Table", "import_TableBody", "import_TableCell", "import_TableContainer", "import_TableHead", "import_TableRow", "import_icons_material", "import_core_plugin_api", "React", "Dialog", "DialogTitle", "DialogContent", "Alert", "TextField", "Autocomplete", "FormControlLabel", "Checkbox", "MenuItem", "Box", "Divider", "Typography", "TableContainer", "Paper", "Table", "TableHead", "TableRow", "TableCell", "TableBody", "IconButton", "DeleteIcon", "CircularProgress", "Button", "DialogActions", "import_react", "import_Paper", "import_Box", "import_Typography", "import_TextField", "import_MenuItem", "import_Table", "import_TableBody", "import_TableCell", "import_TableContainer", "import_TableHead", "import_TableRow", "import_Skeleton", "React", "Skeleton", "Typography", "Box", "TableRow", "TableCell", "TextField", "MenuItem", "Grid", "TableContainer", "Paper", "Table", "TableHead", "TableBody", "budgetTone", "import_react", "import_Paper", "import_Box", "import_Typography", "import_Skeleton", "import_Divider", "import_Table", "import_TableBody", "import_TableCell", "import_TableHead", "import_TableRow", "import_TableContainer", "import_IconButton", "import_Button", "import_CircularProgress", "import_styles", "import_icons_material", "import_recharts", "React", "Box", "CircularProgress", "Typography", "Paper", "Button", "IconButton", "Collapse", "Divider", "TableContainer", "Table", "TableHead", "TableRow", "TableCell", "TableBody", "Skeleton", "isModelAllowedByTeam", "ALL_PROXY_MODELS", "import_react", "import_Box", "import_Table", "import_TableBody", "import_TableCell", "import_TableContainer", "import_TableHead", "import_TableRow", "import_Typography", "import_MenuItem", "import_TextField", "import_InputAdornment", "import_icons_material", "import_Alert", "import_styles", "React", "Box", "FormControl", "InputLabel", "Select", "MenuItem", "TextField", "InputAdornment", "TableContainer", "Table", "TableHead", "TableRow", "TableCell", "TableBody", "Tooltip", "ContentCopyIcon", "Typography", "Snackbar", "Alert", "React", "TableRow", "TableCell", "Skeleton", "import_react", "import_Box", "import_Typography", "import_Table", "import_TableBody", "import_TableCell", "import_TableContainer", "import_TableHead", "import_TableRow", "import_TextField", "import_MenuItem", "import_Skeleton", "import_Collapse", "import_IconButton", "import_Alert", "import_styles", "import_icons_material", "import_react_use", "IconButton", "Typography", "Collapse", "Box", "TextField", "MenuItem", "Alert", "TableContainer", "Table", "TableHead", "TableBody", "TablePagination", "PERIOD_LS_KEY", "import_react", "import_Box", "import_Snackbar", "import_Alert", "import_CircularProgress", "import_Typography", "import_Paper", "import_Tabs", "import_Tab", "import_react_use", "import_core_plugin_api", "React", "Box", "CircularProgress", "Paper", "Typography", "Tabs", "Tab", "Snackbar", "Alert", "import_react", "import_icons_material", "React", "TrendingUpIcon", "LiteLLMPage", "import_react", "import_Paper", "import_Box", "import_Typography", "import_FormControl", "import_Select", "import_MenuItem", "import_Grid", "import_CircularProgress", "import_Alert", "import_recharts", "import_core_plugin_api", "React", "Box", "Typography", "Paper", "FormControl", "Select", "MenuItem", "CircularProgress", "Alert", "Grid"]
7
7
  }