"use client"; import * as React from "react"; import { Brain, Crown, X, Zap } from "lucide-react"; import { useApp } from "@/components/app/store"; import { ModelSelector } from "@/components/chat/model-selector"; import { ProviderIcon } from "@/components/brand/provider-icon"; import { Tooltip } from "@/components/ui/tooltip"; import { toast } from "@/components/ui/toast"; import { cn } from "@/lib/utils"; import { MAX_MODELS, presetModels, type PresetId } from "./types"; const PRESETS: { id: PresetId; label: string; icon: React.ReactNode; hint: string }[] = [ { id: "flagships", label: "Flagships", icon: , hint: "The top model of each connected provider" }, { id: "fast", label: "Fast", icon: , hint: "Low-latency, low-cost tier" }, { id: "reasoning", label: "Reasoning", icon: , hint: "Models with extended thinking" }, ]; /** Selected-model chips + "Add model" + quick presets. One scrollable row on phones, wraps from `md`. */ export function ArenaModelPicker({ selected, onChange, disabled, className }: { selected: string[]; onChange: (keys: string[]) => void; disabled?: boolean; className?: string }) { const { models, modelsByKey, connectedProviders } = useApp(); const set = React.useMemo(() => new Set(selected), [selected]); const toggle = (key: string) => { if (set.has(key)) return onChange(selected.filter((k) => k !== key)); if (selected.length >= MAX_MODELS) return toast.warning(`Up to ${MAX_MODELS} models`, "Remove one to add another."); onChange([...selected, key]); }; const applyPreset = (id: PresetId) => { const keys = presetModels(id, models, connectedProviders); if (!keys.length) return toast.info("No matching models", "Connect a provider or pick models manually."); onChange(keys); }; return (
{selected.map((key, i) => { const m = modelsByKey.get(key); return ( {m?.displayName ?? key} ); })} {selected.length < MAX_MODELS ? ( ) : null} {selected.length}/{MAX_MODELS}
{PRESETS.map((p) => ( ))}
); }