import { useQueryClient } from "@tanstack/react-query"; import { Button } from "@unom/ui/button"; import type { FC } from "react"; import { getListGpusQueryKey, useListGpus, useSetGpuPreference, } from "@/api/gen/gpu/gpu"; import type { GpuState } from "@/api/gen/model"; import { QueryState } from "@/components/query-state"; import { Badge } from "@/components/ui/badge"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import type { Loadable } from "@/lib/query"; import { m } from "@/paraglide/messages"; /** * Container: the host's GPU inventory + selection. Polls (a stream starting/stopping moves the * "In use" badge; an eGPU can appear) and applies auto/preferred choices via the mgmt API. A * preference applies to the NEXT session — the help text says so. */ export const GpuSection: FC = () => { const qc = useQueryClient(); const gpus = useListGpus({ query: { refetchInterval: 5_000 } }); const setPref = useSetGpuPreference(); const apply = (mode: "auto" | "manual", gpuId?: string) => setPref.mutate( { data: { mode, gpu_id: gpuId ?? null } }, { onSuccess: () => qc.invalidateQueries({ queryKey: getListGpusQueryKey() }), }, ); return ; }; const fmtVram = (mb: number) => mb >= 1024 ? `${Math.round(mb / 1024)} GiB` : `${mb} MiB`; /** * GPU list in the compositors-card style: per-GPU badges for the manual pick ("Preferred"), what * the next session will use ("Next session"), and what live sessions encode on right now * ("In use · NVENC"), plus an Automatic/Prefer control pair. */ export const GpuCard: FC<{ state: Loadable; onApply: (mode: "auto" | "manual", gpuId?: string) => void; busy: boolean; }> = ({ state, onApply, busy }) => { const s = state.data; return ( {m.host_gpus()} {s && s.gpus.length > 0 && ( )}

{m.host_gpus_help()}

{s && (s.gpus.length === 0 ? (

{m.gpu_none()}

) : (
    {s.gpus.map((g) => { const isActive = s.active?.id === g.id; const isSelected = s.selected?.id === g.id; const isPreferred = s.mode === "manual" && s.preferred_id === g.id; return (
  • {g.name} {isPreferred && ( {m.gpu_preferred()} )} {isActive && s.active ? ( {m.gpu_in_use({ backend: s.active.backend.toUpperCase(), })} ) : ( isSelected && ( {m.gpu_next_session()} ) )}
    {g.vendor} {g.vram_mb > 0 ? ` · ${fmtVram(g.vram_mb)}` : ""} {` · ${g.id}`}
  • ); })}
))} {s?.selected?.source === "preference_missing" && (

{m.gpu_missing_warning({ name: s.preferred_name ?? "?" })}

)} {s?.env_override && s.mode === "auto" && (

{m.gpu_env_note({ value: s.env_override })}

)}
); };