diff --git a/apps/next/src/components/integrations/ai-provider-profiles-panel.tsx b/apps/next/src/components/integrations/ai-provider-profiles-panel.tsx index 16e0ab4..27cd64b 100644 --- a/apps/next/src/components/integrations/ai-provider-profiles-panel.tsx +++ b/apps/next/src/components/integrations/ai-provider-profiles-panel.tsx @@ -42,7 +42,11 @@ type Provider = | 'cloudflare_ai_gateway' | 'custom_openai_compatible' | 'opencode_openai_login'; -type AuthType = 'api_key' | 'opencode_auth_json' | 'none'; +type AuthType = + | 'api_key' + | 'opencode_auth_json' + | 'anthropic_oauth_json' + | 'none'; type ReasoningEffort = 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh'; const saveProfileRef = makeFunctionReference< @@ -69,33 +73,75 @@ const setDefaultProfileRef = makeFunctionReference< >('aiProviderProfiles:setDefault'); const providerOptions: { + key: string; value: Provider; label: string; authType: AuthType; }[] = [ - { value: 'openai', label: 'OpenAI API key', authType: 'api_key' }, - { value: 'anthropic', label: 'Anthropic API key', authType: 'api_key' }, - { value: 'google', label: 'Google Gemini API key', authType: 'api_key' }, - { value: 'openrouter', label: 'OpenRouter', authType: 'api_key' }, - { value: 'requesty', label: 'Requesty', authType: 'api_key' }, - { value: 'litellm', label: 'LiteLLM', authType: 'api_key' }, { + key: 'openai', + value: 'openai', + label: 'OpenAI API key', + authType: 'api_key', + }, + { + key: 'anthropic', + value: 'anthropic', + label: 'Anthropic API key', + authType: 'api_key', + }, + { + key: 'google', + value: 'google', + label: 'Google Gemini API key', + authType: 'api_key', + }, + { + key: 'openrouter', + value: 'openrouter', + label: 'OpenRouter', + authType: 'api_key', + }, + { + key: 'requesty', + value: 'requesty', + label: 'Requesty', + authType: 'api_key', + }, + { key: 'litellm', value: 'litellm', label: 'LiteLLM', authType: 'api_key' }, + { + key: 'cloudflare_ai_gateway', value: 'cloudflare_ai_gateway', label: 'Cloudflare AI Gateway', authType: 'api_key', }, { + key: 'custom_openai_compatible', value: 'custom_openai_compatible', label: 'Custom OpenAI-compatible', authType: 'api_key', }, { + key: 'opencode_openai_login', value: 'opencode_openai_login', label: 'Codex ChatGPT login', authType: 'opencode_auth_json', }, + { + key: 'anthropic_oauth_json', + value: 'anthropic', + label: 'Anthropic OAuth (paste credentials)', + authType: 'anthropic_oauth_json', + }, ]; +const defaultProviderOption: (typeof providerOptions)[number] = { + key: 'openai', + value: 'openai', + label: 'OpenAI API key', + authType: 'api_key', +}; + const reasoningOptions: ReasoningEffort[] = [ 'none', 'minimal', @@ -112,17 +158,14 @@ export const AiProviderProfilesPanel = () => { const removeProfile = useMutation(api.aiProviderProfiles.remove); const [profileId, setProfileId] = useState>(); const [name, setName] = useState('OpenAI'); - const [provider, setProvider] = useState('openai'); + const [providerKey, setProviderKey] = useState('openai'); const selectedProvider = useMemo( () => - providerOptions.find((option) => option.value === provider) ?? - ({ - value: 'openai', - label: 'OpenAI API key', - authType: 'api_key', - } satisfies (typeof providerOptions)[number]), - [provider], + providerOptions.find((option) => option.key === providerKey) ?? + defaultProviderOption, + [providerKey], ); + const provider = selectedProvider.value; const [secret, setSecret] = useState(''); const [baseUrl, setBaseUrl] = useState(''); const [defaultModelValue, setDefaultModelValue] = useState( @@ -146,7 +189,7 @@ export const AiProviderProfilesPanel = () => { const reset = () => { setProfileId(undefined); - setProvider('openai'); + setProviderKey('openai'); setSecret(''); setBaseUrl(''); setDefaultModelValue(''); @@ -160,7 +203,16 @@ export const AiProviderProfilesPanel = () => { const edit = (profile: (typeof profiles)[number]) => { setProfileId(profile._id); setName(profile.name); - setProvider(profile.provider as Provider); + setProviderKey( + providerOptions.find( + (option) => + option.value === profile.provider && + option.authType === profile.authType, + )?.key ?? + providerOptions.find((option) => option.value === profile.provider) + ?.key ?? + 'openai', + ); setSecret(''); setBaseUrl(profile.baseUrl ?? ''); setDefaultModelValue(profile.defaultModel); @@ -314,16 +366,14 @@ export const AiProviderProfilesPanel = () => {