"use client"; import { useState, useEffect } from "react"; import { Tabs, TabsList, TabsTrigger, TabsContent } from "./ui/tabs"; import { Check, ChevronsUpDown, Info } from "lucide-react"; import { Button } from "./ui/button"; import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from "./ui/command"; import { Popover, PopoverContent, PopoverTrigger } from "./ui/popover"; import { cn } from "@/lib/utils"; import OpenAIConfig from "./OpenAIConfig"; import GoogleConfig from "./GoogleConfig"; import AnthropicConfig from "./AnthropicConfig"; import OllamaConfig from "./OllamaConfig"; import CustomConfig from "./CustomConfig"; import { updateLLMConfig, changeProvider as changeProviderUtil, } from "@/utils/providerUtils"; import { IMAGE_PROVIDERS, LLM_PROVIDERS } from "@/utils/providerConstants"; import { LLMConfig } from "@/types/llm_config"; // Button state interface interface ButtonState { isLoading: boolean; isDisabled: boolean; text: string; showProgress: boolean; progressPercentage?: number; status?: string; } interface LLMProviderSelectionProps { initialLLMConfig: LLMConfig; onConfigChange: (config: LLMConfig) => void; buttonState: ButtonState; setButtonState: (state: ButtonState | ((prev: ButtonState) => ButtonState)) => void; } export default function LLMProviderSelection({ initialLLMConfig, onConfigChange, setButtonState, }: LLMProviderSelectionProps) { const [llmConfig, setLlmConfig] = useState(initialLLMConfig); const [openImageProviderSelect, setOpenImageProviderSelect] = useState(false); useEffect(() => { onConfigChange(llmConfig); }, [llmConfig]); useEffect(() => { const needsModelSelection = (llmConfig.LLM === "openai" && !llmConfig.OPENAI_MODEL) || (llmConfig.LLM === "google" && !llmConfig.GOOGLE_MODEL) || (llmConfig.LLM === "ollama" && !llmConfig.OLLAMA_MODEL) || (llmConfig.LLM === "custom" && !llmConfig.CUSTOM_MODEL) || (llmConfig.LLM === "anthropic" && !llmConfig.ANTHROPIC_MODEL); const needsApiKey = ((llmConfig.IMAGE_PROVIDER === "dall-e-3" || llmConfig.LLM === "openai") && !llmConfig.OPENAI_API_KEY) || ((llmConfig.IMAGE_PROVIDER === "gemini_flash" || llmConfig.LLM === "google") && !llmConfig.GOOGLE_API_KEY) || (llmConfig.LLM === "anthropic" && !llmConfig.ANTHROPIC_API_KEY) || (llmConfig.IMAGE_PROVIDER === "pexels" && !llmConfig.PEXELS_API_KEY) || (llmConfig.IMAGE_PROVIDER === "pixabay" && !llmConfig.PIXABAY_API_KEY); const needsOllamaUrl = (llmConfig.LLM === "ollama" && !llmConfig.OLLAMA_URL); setButtonState({ isLoading: false, isDisabled: needsModelSelection || needsApiKey || needsOllamaUrl, text: needsModelSelection ? "Please Select a Model" : needsApiKey ? "Please Enter API Key" : needsOllamaUrl ? "Please Enter Ollama URL" : "Save Configuration", showProgress: false }); }, [llmConfig]); const input_field_changed = (new_value: string | boolean, field: string) => { const updatedConfig = updateLLMConfig(llmConfig, field, new_value); setLlmConfig(updatedConfig); }; const handleProviderChange = (provider: string) => { const newConfig = changeProviderUtil(llmConfig, provider); setLlmConfig(newConfig); }; useEffect(() => { if (!llmConfig.USE_CUSTOM_URL) { setLlmConfig({ ...llmConfig, OLLAMA_URL: "http://localhost:11434" }); } else { if (!llmConfig.OLLAMA_URL) { setLlmConfig({ ...llmConfig, OLLAMA_URL: "http://localhost:11434" }); } } }, [llmConfig.USE_CUSTOM_URL]); useEffect(() => { let updates: any = {}; if (!llmConfig.IMAGE_PROVIDER) { if (llmConfig.LLM === "openai") { updates.IMAGE_PROVIDER = "dall-e-3"; } else if (llmConfig.LLM === "google") { updates.IMAGE_PROVIDER = "gemini_flash"; } else { updates.IMAGE_PROVIDER = "pexels"; } } if (!llmConfig.OLLAMA_URL) { updates.OLLAMA_URL = "http://localhost:11434"; } setLlmConfig({ ...llmConfig, ...updates }); }, []); return (
{/* Provider Selection - Fixed Header */}
OpenAI Google Anthropic Ollama Custom
{/* Scrollable Content */}
{/* OpenAI Content */} {/* Google Content */} {/* Anthropic Content */} {/* Ollama Content */} {/* Custom Content */} {/* Image Provider Selection */}
No provider found. {Object.values(IMAGE_PROVIDERS).map( (provider, index) => ( { input_field_changed(value, "image_provider"); setOpenImageProviderSelect(false); }} >
{provider.label}
{provider.description}
) )}
{/* Dynamic API Key Input for Image Provider */} {llmConfig.IMAGE_PROVIDER && IMAGE_PROVIDERS[llmConfig.IMAGE_PROVIDER] && (() => { const provider = IMAGE_PROVIDERS[llmConfig.IMAGE_PROVIDER]; // Show info message when using same API key as main provider if (provider.value === "dall-e-3" && llmConfig.LLM === "openai") { return <>; } if (provider.value === "gemini_flash" && llmConfig.LLM === "google") { return <>; } // Show API key input for other providers return (
{ if (provider.apiKeyField === "PEXELS_API_KEY") { input_field_changed(e.target.value, "pexels_api_key"); } else if (provider.apiKeyField === "PIXABAY_API_KEY") { input_field_changed(e.target.value, "pixabay_api_key"); } }} />

API key for {provider.label} image generation

); })()} {/* Model Information */}

Selected Models

Using{" "} {llmConfig.LLM === "ollama" ? llmConfig.OLLAMA_MODEL ?? "xxxxx" : llmConfig.LLM === "custom" ? llmConfig.CUSTOM_MODEL ?? "xxxxx" : llmConfig.LLM === "anthropic" ? llmConfig.ANTHROPIC_MODEL ?? "xxxxx" : llmConfig.LLM === "google" ? llmConfig.GOOGLE_MODEL ?? "xxxxx" : llmConfig.LLM === "openai" ? llmConfig.OPENAI_MODEL ?? "xxxxx" : "xxxxx"}{" "} for text generation and{" "} {llmConfig.IMAGE_PROVIDER && IMAGE_PROVIDERS[llmConfig.IMAGE_PROVIDER] ? IMAGE_PROVIDERS[llmConfig.IMAGE_PROVIDER].label : "xxxxx"}{" "} for images

); }