import { useState, useCallback, useMemo } from "react"; import { useAPI } from "../contexts/APIProvider"; import { LogPanel } from "./LogViewer"; import { usePersistentState } from "../hooks/usePersistentState"; export default function ModelsPage() { const { models, unloadAllModels, loadModel, upstreamLogs, metrics } = useAPI(); const [isUnloading, setIsUnloading] = useState(false); const [showUnlisted, setShowUnlisted] = usePersistentState("showUnlisted", true); 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 { // at least give it a second to show the unloading message setTimeout(() => { setIsUnloading(false); }, 1000); } }, []); const [totalRequests, totalTokens, avgTokensPerSecond] = useMemo(() => { const totalTokens = metrics.reduce((sum, m) => sum + m.input_tokens + m.output_tokens, 0); const totalSeconds = metrics.reduce((sum, m) => sum + m.duration_ms / 1000, 0); const avgTokensPerSecond = totalSeconds > 0 ? totalTokens / totalSeconds : 0; return [metrics.length, totalTokens, avgTokensPerSecond.toFixed(2)]; }, [metrics]); return (
{/* Left Column */}

Models

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

{model.description}

)}
{model.state}
{/* Right Column */}

Chat Activity

Requests {totalRequests}
Total Tokens Generated {totalTokens}
Average Tokens/Second {avgTokensPerSecond}
); }