import { useState, useCallback, useMemo } from "react"; import { useAPI } from "../contexts/APIProvider"; import { LogPanel } from "./LogViewer"; import { usePersistentState } from "../hooks/usePersistentState"; import { Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels"; import { useTheme } from "../contexts/ThemeProvider"; import { RiEyeFill, RiEyeOffFill, RiStopCircleLine, RiSwapBoxFill } from "react-icons/ri"; export default function ModelsPage() { const { isNarrow } = useTheme(); const direction = isNarrow ? "vertical" : "horizontal"; const { upstreamLogs } = useAPI(); return (
{direction === "horizontal" && }
); } function ModelsPanel() { const { models, loadModel, unloadAllModels } = useAPI(); const [isUnloading, setIsUnloading] = useState(false); const [showUnlisted, setShowUnlisted] = usePersistentState("showUnlisted", true); const [showIdorName, setShowIdorName] = usePersistentState<"id" | "name">("showIdorName", "id"); // true = show ID, false = show name const filteredModels = useMemo(() => { return models.filter((model) => showUnlisted || !model.unlisted); }, [models, showUnlisted]); const handleUnloadAllModels = useCallback(async () => { setIsUnloading(true); try { await unloadAllModels(); } catch (e) { console.error(e); } finally { setTimeout(() => { setIsUnloading(false); }, 1000); } }, [unloadAllModels]); const toggleIdorName = useCallback(() => { setShowIdorName((prev) => (prev === "name" ? "id" : "name")); }, [showIdorName]); return (

Models

{filteredModels.map((model) => ( ))}
{showIdorName === "id" ? "Model ID" : "Name"} State
{showIdorName === "id" ? model.id : model.name !== "" ? model.name : model.id} {model.description !== "" && (

{model.description}

)}
{model.state}
); } function StatsPanel() { const { metrics } = useAPI(); const [totalRequests, totalInputTokens, totalOutputTokens, avgTokensPerSecond] = useMemo(() => { const totalRequests = metrics.length; if (totalRequests === 0) { return [0, 0, 0]; } const totalInputTokens = metrics.reduce((sum, m) => sum + m.input_tokens, 0); const totalOutputTokens = metrics.reduce((sum, m) => sum + m.output_tokens, 0); const avgTokensPerSecond = (metrics.reduce((sum, m) => sum + m.tokens_per_second, 0) / totalRequests).toFixed(2); return [totalRequests, totalInputTokens, totalOutputTokens, avgTokensPerSecond]; }, [metrics]); return (
Requests Processed Generated Tokens/Sec
{totalRequests} {new Intl.NumberFormat().format(totalInputTokens)} {new Intl.NumberFormat().format(totalOutputTokens)} {avgTokensPerSecond}
); }