"use client"; /** * Click-to-open model dropdown that always shows the full current choice as * text (no collapse-to-icon, no hover-expand). Used for the partner's * primary/backup model rows; `noneLabel` names the null choice ("System * default" for primary, "No backup" for backup). */ import { useEffect, useRef, useState } from "react"; import { Check, ChevronDown, Loader2 } from "lucide-react"; import { useTranslation } from "react-i18next"; import { llmSelectionKey, sameLLMSelection, type LLMOption, } from "@/lib/llm-options"; import type { LLMSelection } from "@/lib/unified-ws"; function formatContext(tokens?: number): string { if (!tokens || tokens <= 0) return ""; if (tokens >= 1_000_000) return `${Math.round(tokens / 100_000) / 10}M`; if (tokens >= 1_000) return `${Math.round(tokens / 1_000)}K`; return String(tokens); } export default function PartnerModelSelect({ options, activeDefault, value, loading, error, noneLabel, noneDetail, onChange, }: { options: LLMOption[]; activeDefault: LLMSelection | null; value: LLMSelection | null; loading: boolean; error: boolean; noneLabel: string; noneDetail?: string; onChange: (selection: LLMSelection | null) => void; }) { const { t } = useTranslation(); const [open, setOpen] = useState(false); const rootRef = useRef(null); useEffect(() => { if (!open) return; const onPointerDown = (e: PointerEvent) => { if (rootRef.current && !rootRef.current.contains(e.target as Node)) { setOpen(false); } }; document.addEventListener("pointerdown", onPointerDown); return () => document.removeEventListener("pointerdown", onPointerDown); }, [open]); if (loading) { return (
{t("Loading models…")}
); } if (error) { return (

{t( "Could not load the model catalog — the partner will use the system default.", )}

); } const current = value ? options.find((option) => sameLLMSelection(option, value)) : undefined; const defaultOption = activeDefault ? options.find((option) => sameLLMSelection(option, activeDefault)) : undefined; const currentTitle = value ? current ? current.model_name || current.model : value.model_id : noneLabel; const currentSubtitle = value ? current ? `${current.provider_label || current.provider} · ${current.profile_name}` : "" : (noneDetail ?? (defaultOption ? `${defaultOption.model_name || defaultOption.model} · ${defaultOption.provider_label || defaultOption.provider}` : "")); const select = (next: LLMSelection | null) => { onChange(next); setOpen(false); }; return (
{open && (
select(null)} /> {options.map((option) => ( select({ profile_id: option.profile_id, model_id: option.model_id, }) } /> ))} {options.length === 0 && (

{t("No models configured yet — add providers in Settings → LLM.")}

)}
)}
); } function DropdownRow({ title, subtitle, trailing, selected, onClick, }: { title: string; subtitle?: string; trailing?: string; selected: boolean; onClick: () => void; }) { return ( ); }