diff --git a/src/shared/provider-preset-catalog.ts b/src/shared/provider-preset-catalog.ts index bdb16441..42c6e7be 100644 --- a/src/shared/provider-preset-catalog.ts +++ b/src/shared/provider-preset-catalog.ts @@ -8,11 +8,11 @@ export type PresetCategory = 'recommended' | 'alternative'; export const PROVIDER_PRESET_IDS = [ - 'anthropic', 'openrouter', 'alibaba-coding-plan', 'ollama', 'llamacpp', + 'anthropic', 'glm', 'glmt', 'km', @@ -60,20 +60,6 @@ export const PROVIDER_PRESET_ALIASES: Readonly> }); const RAW_PROVIDER_PRESET_DEFINITIONS: readonly ProviderPresetDefinition[] = [ - { - id: 'anthropic', - name: 'Anthropic (Direct API)', - description: 'Use your own Anthropic API key (sk-ant-...)', - baseUrl: '', - defaultProfileName: 'anthropic', - defaultModel: 'claude-sonnet-4-5-20250929', - apiKeyPlaceholder: 'sk-ant-api03-...', - apiKeyHint: 'Get key at console.anthropic.com/settings/keys', - category: 'recommended', - requiresApiKey: true, - badge: 'Direct', - featured: true, - }, { id: 'openrouter', name: 'OpenRouter', @@ -133,6 +119,21 @@ const RAW_PROVIDER_PRESET_DEFINITIONS: readonly ProviderPresetDefinition[] = [ badge: 'Local', featured: true, }, + { + id: 'anthropic', + name: 'Anthropic (Direct API)', + description: 'Use your own Anthropic API key (sk-ant-...)', + baseUrl: '', + defaultProfileName: 'anthropic', + defaultModel: 'claude-sonnet-4-5-20250929', + apiKeyPlaceholder: 'sk-ant-api03-...', + apiKeyHint: 'Get key at console.anthropic.com/settings/keys', + category: 'recommended', + requiresApiKey: true, + badge: 'Direct', + featured: true, + icon: '/assets/providers/claude.svg', + }, { id: 'glm', name: 'GLM', diff --git a/tests/unit/api/provider-presets.test.ts b/tests/unit/api/provider-presets.test.ts index 9f5d03e2..e4518e07 100644 --- a/tests/unit/api/provider-presets.test.ts +++ b/tests/unit/api/provider-presets.test.ts @@ -61,6 +61,15 @@ describe('provider-presets', () => { expect(preset?.defaultProfileName).toBe('qwen-api'); }); + it('keeps Anthropic direct last in the recommended preset order and reuses the Claude logo', () => { + const recommendedPresetIds = PROVIDER_PRESETS.filter( + (preset) => preset.category === 'recommended' + ).map((preset) => preset.id); + + expect(recommendedPresetIds.at(-1)).toBe('anthropic'); + expect(getPresetById('anthropic')?.icon).toBe('/assets/providers/claude.svg'); + }); + it('only references provider preset icons that exist in ui/public', () => { for (const preset of PROVIDER_PRESETS) { if (!preset.icon) continue; diff --git a/ui/src/components/profiles/profile-create-dialog.tsx b/ui/src/components/profiles/profile-create-dialog.tsx index 5face9d6..d08f0c98 100644 --- a/ui/src/components/profiles/profile-create-dialog.tsx +++ b/ui/src/components/profiles/profile-create-dialog.tsx @@ -28,6 +28,7 @@ import { } from '@/components/ui/dialog'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { Badge } from '@/components/ui/badge'; +import { ProviderLogo } from '@/components/cliproxy/provider-logo'; import { useCreateProfile } from '@/hooks/use-profiles'; import { useOpenRouterCatalog } from '@/hooks/use-openrouter-models'; import { Loader2, Plus, AlertTriangle, Info, Eye, EyeOff, Settings2, Sparkles } from 'lucide-react'; @@ -105,6 +106,12 @@ const QUICK_TEMPLATE_PRESETS = PROVIDER_PRESETS.filter( const QUICK_TEMPLATE_PRESET_IDS = new Set( QUICK_TEMPLATE_PRESETS.map((preset) => preset.id) ); +const CARD_META_CLAMP_STYLE = { + display: '-webkit-box', + WebkitLineClamp: 2, + WebkitBoxOrient: 'vertical', + overflow: 'hidden', +} as const; export function ProfileCreateDialog({ open, @@ -277,6 +284,7 @@ export function ProfileCreateDialog({ const isQuickTemplateSelected = selectedPreset !== CUSTOM_PRESET_ID && QUICK_TEMPLATE_PRESET_IDS.has(selectedPreset); const isOpenRouter = currentPreset?.id === DEFAULT_PRESET_ID; + const showQuickTemplates = selectedPreset === CUSTOM_PRESET_ID || isQuickTemplateSelected; return ( @@ -295,57 +303,70 @@ export function ProfileCreateDialog({ onSubmit={handleSubmit(onSubmit)} className="flex flex-col flex-1 min-h-0 overflow-hidden" > - {/* Provider Preset Cards - Compact horizontal layout */} -
- {/* Main Options: OpenRouter + Custom */} -
- -
- {RECOMMENDED_PRESETS.map((preset) => ( - handlePresetSelect(preset.id)} - /> - ))} - {/* Custom option */} - -
-
- - {/* Show quick templates when custom mode or non-recommended preset is selected */} - {(selectedPreset === CUSTOM_PRESET_ID || isQuickTemplateSelected) && ( -
-