diff --git a/ui/desktop/src/components/settings/api_keys/types.ts b/ui/desktop/src/components/settings/api_keys/types.ts index 78dc57b3..9d8b2245 100644 --- a/ui/desktop/src/components/settings/api_keys/types.ts +++ b/ui/desktop/src/components/settings/api_keys/types.ts @@ -11,11 +11,3 @@ export interface ConfigDetails { is_set: boolean; location?: string; } - -export interface Provider { - id: string; // Lowercase key (e.g., "openai") - name: string; // Provider name (e.g., "OpenAI") - description: string; // Description of the provider - models: string[]; // List of supported models - requiredKeys: string[]; // List of required keys -} diff --git a/ui/desktop/src/components/settings/api_keys/utils.tsx b/ui/desktop/src/components/settings/api_keys/utils.tsx index 8ae62fef..994a547b 100644 --- a/ui/desktop/src/components/settings/api_keys/utils.tsx +++ b/ui/desktop/src/components/settings/api_keys/utils.tsx @@ -1,7 +1,19 @@ -import { Provider, ProviderResponse } from './types'; +import { ProviderResponse, ConfigDetails } from './types'; import { getApiUrl, getSecretKey } from '../../../config'; import { default_key_value, required_keys } from '../models/hardcoded_stuff'; // e.g. { OPENAI_HOST: '', OLLAMA_HOST: '' } +// Backend API response types +interface ProviderMetadata { + description: string; + models: string[]; +} + +interface ProviderDetails { + name: string; + metadata: ProviderMetadata; + is_configured: boolean; +} + export function isSecretKey(keyName: string): boolean { // Endpoints and hosts should not be stored as secrets const nonSecretKeys = [ @@ -66,57 +78,41 @@ export async function getActiveProviders(): Promise { } export async function getConfigSettings(): Promise> { - const providerList = await getProvidersList(); - // Extract the list of IDs - const providerIds = providerList.map((provider) => provider.id); - - // Fetch configs state (set/unset) using the provider IDs - const response = await fetch(getApiUrl('/configs/providers'), { - method: 'POST', + // Fetch provider config status + const response = await fetch(getApiUrl('/config/providers'), { + method: 'GET', headers: { 'Content-Type': 'application/json', 'X-Secret-Key': getSecretKey(), }, - body: JSON.stringify({ - providers: providerIds, - }), }); if (!response.ok) { - throw new Error('Failed to fetch secrets'); + throw new Error('Failed to fetch provider configuration status'); } - const data = (await response.json()) as Record; + const providers: ProviderDetails[] = await response.json(); + + // Convert the response to the expected format + const data: Record = {}; + providers.forEach((provider) => { + const providerRequiredKeys = required_keys[provider.name] || []; + + data[provider.name] = { + name: provider.name, + supported: true, + description: provider.metadata.description, + models: provider.metadata.models, + config_status: providerRequiredKeys.reduce>((acc, key) => { + acc[key] = { + key, + is_set: provider.is_configured, + location: provider.is_configured ? 'config' : undefined, + }; + return acc; + }, {}), + }; + }); + return data; } - -export async function getProvidersList(): Promise { - const response = await fetch(getApiUrl('/agent/providers'), { - method: 'GET', - }); - - if (!response.ok) { - throw new Error(`Failed to fetch providers: ${response.statusText}`); - } - - const data = await response.json(); - - interface ProviderItem { - id: string; - details?: { - name?: string; - description?: string; - models?: string[]; - required_keys?: string[]; - }; - } - - // Format the response into an array of providers - return data.map((item: ProviderItem) => ({ - id: item.id, // Root-level ID - name: item.details?.name || 'Unknown Provider', // Nested name in details - description: item.details?.description || 'No description available.', // Nested description - models: item.details?.models || [], // Nested models array - requiredKeys: item.details?.required_keys || [], // Nested required keys array - })); -} diff --git a/ui/desktop/src/components/settings/models/hardcoded_stuff.tsx b/ui/desktop/src/components/settings/models/hardcoded_stuff.tsx index 41b0d1f4..20b464fb 100644 --- a/ui/desktop/src/components/settings/models/hardcoded_stuff.tsx +++ b/ui/desktop/src/components/settings/models/hardcoded_stuff.tsx @@ -1,41 +1,3 @@ -export const openai_models = ['gpt-4o-mini', 'gpt-4o', 'gpt-4-turbo', 'o1']; - -export const anthropic_models = [ - 'claude-3-5-sonnet-latest', - 'claude-3-5-sonnet-2', - 'claude-3-5-haiku-latest', - 'claude-3-opus-latest', -]; - -export const google_models = [ - 'gemini-1.5-pro', - 'gemini-1.5-flash', - 'gemini-2.0-flash', - 'gemini-2.0-flash-lite-preview-02-05', - 'gemini-2.0-flash-thinking-exp-01-21', - 'gemini-2.0-pro-exp-02-05', - 'gemini-2.5-pro-exp-03-25', -]; - -export const groq_models = ['llama-3.3-70b-versatile']; - -export const ollama_mdoels = ['qwen2.5']; - -export const openrouter_models = ['anthropic/claude-3.5-sonnet']; - -export const azure_openai_models = ['gpt-4o']; - -export const gcp_vertex_ai_models = [ - 'claude-3-7-sonnet@20250219', - 'claude-3-5-sonnet-v2@20241022', - 'claude-3-5-sonnet@20240620', - 'claude-3-5-haiku@20241022', - 'gemini-1.5-pro-002', - 'gemini-2.0-flash-001', - 'gemini-2.0-pro-exp-02-05', - 'gemini-2.5-pro-exp-03-25', -]; - export const default_models = { openai: 'gpt-4o', anthropic: 'claude-3-5-sonnet-latest', @@ -54,8 +16,6 @@ export function getDefaultModel(key: string): string | undefined { return default_models[key as keyof typeof default_models] || undefined; } -export const short_list = ['gpt-4o', 'claude-3-5-sonnet-latest']; - export const required_keys = { OpenAI: ['OPENAI_API_KEY', 'OPENAI_HOST', 'OPENAI_BASE_PATH'], Anthropic: ['ANTHROPIC_API_KEY', 'ANTHROPIC_HOST'],