import { PROVIDERS, CHAT_MODELS, EMBEDDING_MODELS, IConfig, PROVIDERS_CONN_ARGS_MAP, ChatModel, BaseModel } from "@/lib/config/types"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs"; 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 { useConfig, useUpdateConfig, useUpdateEnabledModels } from "@/hooks/use-config"; import { useDebounceCallback } from "@/hooks/use-debounce"; import { useState } from "react"; const Providers = ({ config }: { config: IConfig | undefined }) => { const updateConfig = useUpdateConfig(); const [localValues, setLocalValues] = useState>({}); const debouncedUpdateConfig = useDebounceCallback((updates: Record) => { updateConfig.mutate(updates); }, 500); if (!config) return null; return ( Providers Configure your AI provider credentials {Object.values(PROVIDERS).map((provider) => (

{provider}

{PROVIDERS_CONN_ARGS_MAP[provider].map((arg) => { const value = localValues[arg] ?? config[arg as keyof IConfig] ?? ''; return (
{ const newValue = e.target.value; setLocalValues(prev => ({ ...prev, [arg]: newValue })); debouncedUpdateConfig({ [arg]: newValue }); }} disabled={updateConfig.isPending} className="font-mono" />
); })}
))}
); } interface ModelListProps { type: 'chat' | 'embedding'; models: BaseModel[]; config: IConfig | undefined; enabledModels: string[]; defaultModel: string; title: string; description: string; } 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) => { return PROVIDERS_CONN_ARGS_MAP[provider].every( (arg) => { const value = config[arg as keyof IConfig]; 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()} ))}
)}
{ handleModelToggle(model, checked); if (!checked && selectedDefault === model.model) { handleDefaultModelChange(''); } }} disabled={!providerConfigured || updateEnabledModels.isPending} />
); })}
); } const ChatModels = ({ config }: { config: IConfig | undefined }) => { if (!config) return null; return ( ); } const EmbeddingModels = ({ config }: { config: IConfig | undefined }) => { if (!config) return null; return ( ); } const Others = () => { return (

Others

); } export function HomePage() { const { data: config, isLoading, error } = useConfig(); if (isLoading) { return (

Loading configuration...

); } if (error) { return (

Failed to load configuration

Please try refreshing the page

); } return (
Providers Chat Models Embedding Models Others
); }