/** * `ModelServerSelect` (F35.2) — a dropdown to bind an OpenCode profile to one of * the declared local model servers, or to none ("external endpoint"). Replaces * the free-text `localModelServerId` input posed in F36. Presentational: the * server list and the current value are passed in. */ import type { LocalModelServerConfig } from "@/domain"; import { SmallDropdown } from "@/shared"; /** The sentinel option value standing for "no managed server". */ const NONE = ""; export interface ModelServerSelectProps { /** The declared servers to choose from. */ servers: LocalModelServerConfig[]; /** The currently-bound server id, or `undefined` for none. */ value?: string; /** Called with the new server id, or `undefined` when "none" is chosen. */ onChange: (serverId: string | undefined) => void; /** Accessible label (defaults to a generic one). */ ariaLabel?: string; } export function ModelServerSelect({ servers, value, onChange, ariaLabel = "local model server", }: ModelServerSelectProps) { // A previously-bound server that no longer exists (deleted): keep it visible // so the binding isn't silently dropped from the UI. const missing = value !== undefined && !servers.some((s) => s.id === value); return ( onChange(next === NONE ? undefined : next)} options={[ { value: NONE, label: "None (external endpoint)" }, ...servers.map((s) => ({ value: s.id, label: `${s.name} — ${s.servedModelName}`, })), ...(missing && value !== undefined ? [{ value, label: `${value} (unknown / removed)` }] : []), ]} /> ); }