"use client"; import { useState, useEffect } from "react"; import { Check, ChevronsUpDown, Loader2 } 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 { toast } from "sonner"; import { Switch } from "./ui/switch"; interface CustomConfigProps { customLlmUrl: string; customLlmApiKey: string; customModel: string; toolCalls: boolean; disableThinking: boolean; onInputChange: (value: string | boolean, field: string) => void; } export default function CustomConfig({ customLlmUrl, customLlmApiKey, customModel, toolCalls, disableThinking, onInputChange, }: CustomConfigProps) { const [customModels, setCustomModels] = useState([]); const [customModelsLoading, setCustomModelsLoading] = useState(false); const [customModelsChecked, setCustomModelsChecked] = useState(false); const [openModelSelect, setOpenModelSelect] = useState(false); const [url, setUrl] = useState(customLlmUrl); const [apiKey, setApiKey] = useState(customLlmApiKey); useEffect(() => { setCustomModels([]); setCustomModelsChecked(false); onInputChange("", "custom_model"); }, [url, apiKey]); const onUrlChange = (value: string) => { setUrl(value); onInputChange(value, "custom_llm_url"); }; const onApiKeyChange = (value: string) => { setApiKey(value); onInputChange(value, "custom_llm_api_key"); }; const fetchCustomModels = async () => { if (!customLlmUrl) return; try { setCustomModelsLoading(true); const response = await fetch("/api/v1/ppt/openai/models/available", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ url: customLlmUrl, api_key: customLlmApiKey, }), }); if (response.ok) { const data = await response.json(); setCustomModels(data); setCustomModelsChecked(true); } else { console.error('Failed to fetch custom models'); setCustomModels([]); setCustomModelsChecked(true); toast.error('Failed to fetch custom models'); } } catch (error) { console.error('Error fetching custom models:', error); toast.error('Error fetching custom models'); setCustomModels([]); setCustomModelsChecked(true); } finally { setCustomModelsLoading(false); } }; return (
{/* URL Input */}
onUrlChange(e.target.value)} />
{/* API Key Input */}
onApiKeyChange(e.target.value)} />
{/* Check for available models button - show when no models checked or no models found */} {(!customModelsChecked || (customModelsChecked && customModels.length === 0)) && (
)} {/* Show message if no models found */} {customModelsChecked && customModels.length === 0 && (

No models found. Please make sure your API key is valid and has access to models.

)} {/* Model selection dropdown - only show if models are available */} {customModelsChecked && customModels.length > 0 && (

Important: Only models with function calling capabilities (tool calls) or JSON schema support will work.

No model found. {customModels.map((model, index) => ( { onInputChange(value, "custom_model"); setOpenModelSelect(false); }} > {model} ))}
)} {/* Tool Calls Toggle */}
onInputChange(checked, "tool_calls")} />

If enabled, Tool Calls will be used instead of JSON Schema for Structured Output.

{/* Disable Thinking Toggle */}
onInputChange(checked, "disable_thinking")} />

If enabled, Thinking will be disabled.

); }