import React, { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { useQuery } from '@tanstack/react-query'; import { groupBy } from 'lodash-es'; import { ipc } from '@/ipc/manager'; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { Loader2, Eye, Zap, Code, Brain, Star } from 'lucide-react'; interface ModelCapability { id: string; object: string; displayName?: string; capabilities: { vision: boolean; thinking: boolean; streaming: boolean; jsonMode: boolean; recommended: boolean; }; limits: { maxTokens?: number; maxOutputTokens?: number; thinkingBudget?: number; }; } const CAPABILITY_ICONS = { vision: Eye, thinking: Brain, streaming: Zap, jsonMode: Code, recommended: Star, } as const; const CAPABILITY_LABELS = { vision: 'Vision', thinking: 'Thinking', streaming: 'Streaming', jsonMode: 'JSON Mode', recommended: 'Recommended', } as const; function getProvider(modelId: string): string { const id = modelId.toLowerCase(); if (id.startsWith('gemini')) return 'Google'; if (id.startsWith('claude')) return 'Anthropic'; if (id.startsWith('gpt') || id.startsWith('o1') || id.startsWith('o3') || id.startsWith('text-')) return 'OpenAI'; if (id.startsWith('deepseek')) return 'DeepSeek'; if (id.startsWith('meta-llama') || id.startsWith('llama')) return 'Meta'; if (id.startsWith('mistral') || id.startsWith('mixtral')) return 'Mistral'; if (id.startsWith('qwen')) return 'Alibaba'; if (id.startsWith('x-ai') || id.startsWith('grok')) return 'xAI'; if (id.startsWith('sonar')) return 'Perplexity'; if (id.startsWith('command')) return 'Cohere'; return 'Other'; } export const CapabilitiesTab: React.FC = () => { const { t } = useTranslation(); const { data: capabilitiesData, isLoading } = useQuery({ queryKey: ['proxyAdvanced', 'modelCapabilities'], queryFn: () => ipc.client.proxyAdvanced.getModelCapabilities(), refetchInterval: 60000, }); const models: ModelCapability[] = capabilitiesData?.success ? (capabilitiesData.data as ModelCapability[]) : []; const groupedModels = useMemo(() => { return groupBy(models, (m) => getProvider(m.id)); }, [models]); // Sort providers alphabetically, but keep 'Other' at the bottom const sortedProviders = Object.keys(groupedModels).sort((a, b) => { if (a === 'Other') return 1; if (b === 'Other') return -1; return a.localeCompare(b); }); return (
{t('proxy.advanced.capabilities.description', 'Discover what each model can do')}
Limits