diff --git a/src/components/settings/ai-settings-form.tsx b/src/components/settings/ai-settings-form.tsx index 8ba5896..5e97c08 100644 --- a/src/components/settings/ai-settings-form.tsx +++ b/src/components/settings/ai-settings-form.tsx @@ -4,7 +4,7 @@ import { useForm } from 'react-hook-form' import { zodResolver } from '@hookform/resolvers/zod' import { z } from 'zod' import { toast } from 'sonner' -import { Cog, Loader2, Zap, AlertCircle, RefreshCw, SlidersHorizontal } from 'lucide-react' +import { Cog, Loader2, Zap, AlertCircle, RefreshCw, SlidersHorizontal, Info } from 'lucide-react' import { trpc } from '@/lib/trpc/client' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' @@ -67,7 +67,10 @@ export function AISettingsForm({ settings }: AISettingsFormProps) { }, }) - // Fetch available models from OpenAI API + const watchProvider = form.watch('ai_provider') + const isLiteLLM = watchProvider === 'litellm' + + // Fetch available models from OpenAI API (skip for LiteLLM — no models.list support) const { data: modelsData, isLoading: modelsLoading, @@ -76,6 +79,7 @@ export function AISettingsForm({ settings }: AISettingsFormProps) { } = trpc.settings.listAIModels.useQuery(undefined, { staleTime: 5 * 60 * 1000, // Cache for 5 minutes retry: false, + enabled: !isLiteLLM, }) const updateSettings = trpc.settings.updateMultiple.useMutation({ @@ -182,32 +186,50 @@ export function AISettingsForm({ settings }: AISettingsFormProps) { - OpenAI + OpenAI (API Key) + LiteLLM Proxy (ChatGPT Subscription) - AI provider for smart assignment suggestions + {field.value === 'litellm' + ? 'Route AI calls through a LiteLLM proxy connected to your ChatGPT Plus/Pro subscription' + : 'Direct OpenAI API access using your API key'} )} /> + {isLiteLLM && ( + + + + LiteLLM Proxy Mode — AI calls will be routed through your LiteLLM proxy + using your ChatGPT subscription. Token limits are automatically stripped (not supported by ChatGPT backend). + Make sure your LiteLLM proxy is running and accessible. + + + )} + ( - API Key + {isLiteLLM ? 'API Key (Optional)' : 'API Key'} - Your OpenAI API key. Leave blank to keep the existing key. + {isLiteLLM + ? 'LiteLLM proxy usually does not require an API key. Leave blank to use default.' + : 'Your OpenAI API key. Leave blank to keep the existing key.'} @@ -219,16 +241,26 @@ export function AISettingsForm({ settings }: AISettingsFormProps) { name="openai_base_url" render={({ field }) => ( - API Base URL (Optional) + {isLiteLLM ? 'LiteLLM Proxy URL' : 'API Base URL (Optional)'} - Custom base URL for OpenAI-compatible providers. Leave blank for OpenAI. - Use https://openrouter.ai/api/v1 for OpenRouter (access Claude, Gemini, Llama, etc.) + {isLiteLLM ? ( + <> + URL of your LiteLLM proxy. Typically{' '} + http://localhost:4000{' '} + or your server address. + + ) : ( + <> + Custom base URL for OpenAI-compatible providers. Leave blank for OpenAI. + Use https://openrouter.ai/api/v1 for OpenRouter. + + )} @@ -242,7 +274,7 @@ export function AISettingsForm({ settings }: AISettingsFormProps) {
Model - {modelsData?.success && ( + {!isLiteLLM && modelsData?.success && !modelsData?.manualEntry && (