import { useState } from "react"; import { PROVIDERS, PROVIDERS_CONN_ARGS_MAP, ChatModel, BaseModel } from "@/lib/config/types"; import { Card, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Switch } from "@/components/ui/switch"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Button } from "@/components/ui/button"; import { ScrollArea } from "@/components/ui/scroll-area"; import { useUpdateConfig, useUpdateEnabledModels } from "../hooks"; import { ModelListProps } from "../types"; export const ModelList = ({ type, models, config, enabledModels, defaultModel, title, description }: ModelListProps) => { const updateEnabledModels = useUpdateEnabledModels(type); const updateConfig = useUpdateConfig(); const [selectedDefault, setSelectedDefault] = useState(defaultModel); const handleModelToggle = async (model: BaseModel, enabled: boolean) => { await updateEnabledModels.mutateAsync({ modelId: model.model, enabled, }); }; const handleDefaultModelChange = async (modelId: string) => { setSelectedDefault(modelId); await updateConfig.mutateAsync({ [type === 'chat' ? 'default_chat_model' : 'default_embedding_model']: modelId, }); }; if (!config) return null; const isProviderConfigured = (provider: PROVIDERS) => { // Special case for OpenAI - only require API key if (provider === PROVIDERS.openai) { return config.openai_api_key && config.openai_api_key.trim().length > 0; } // For other providers, check all required fields return PROVIDERS_CONN_ARGS_MAP[provider].every( (arg) => { const value = config[arg as keyof typeof config]; return typeof value === 'string' && value.trim().length > 0; } ); }; const handleSelectAll = async () => { for (const model of models) { if (isProviderConfigured(model.provider) && !enabledModels.includes(model.model)) { await updateEnabledModels.mutateAsync({ modelId: model.model, enabled: true }); } } }; const handleUnselectAll = async () => { for (const model of models) { if (enabledModels.includes(model.model)) { await updateEnabledModels.mutateAsync({ modelId: model.model, enabled: false }); } } // Then clear the default model updateConfig.mutate({ [`default_${type}_model`]: '' }); }; return (
{title} {description}
{enabledModels.length === 0 && (

Enable at least one model to set as default

)}
{models.map((model) => { const providerConfigured = isProviderConfigured(model.provider); const isChatModel = (m: BaseModel): m is ChatModel => 'modalities' in m; return (

{model.name}

{model.description}

{!providerConfigured && (

Configure {model.provider} provider first

)} {isChatModel(model) && model.modalities && model.modalities.length > 0 && (
{model.modalities.map((modality) => ( {modality.toLowerCase()} ))}
)} {isChatModel(model) && model.isReasoning && (
Thinking
)}
{ handleModelToggle(model, checked); if (!checked && selectedDefault === model.model) { handleDefaultModelChange(''); } }} disabled={!providerConfigured || updateEnabledModels.isPending} />
); })}
); }