// @ts-nocheck import { Label } from '@/components/ui/label'; import { Badge } from '@/components/ui/badge'; import { Brain, AlertTriangle } from 'lucide-react'; import { AnthropicIcon, CursorIcon, OpenAIIcon } from '@/components/ui/provider-icon'; import { cn } from '@/lib/utils'; import type { ModelAlias } from '@/store/app-store'; import { useAppStore } from '@/store/app-store'; import { useSetupStore } from '@/store/setup-store'; import { getModelProvider, PROVIDER_PREFIXES, stripProviderPrefix } from '@automaker/types'; import type { ModelProvider } from '@automaker/types'; import { CLAUDE_MODELS, CURSOR_MODELS, CODEX_MODELS, ModelOption } from './model-constants'; interface ModelSelectorProps { selectedModel: string; // Can be ModelAlias or "cursor-{id}" onModelSelect: (model: string) => void; testIdPrefix?: string; } export function ModelSelector({ selectedModel, onModelSelect, testIdPrefix = 'model-select', }: ModelSelectorProps) { const { enabledCursorModels, cursorDefaultModel } = useAppStore(); const { cursorCliStatus, codexCliStatus } = useSetupStore(); const selectedProvider = getModelProvider(selectedModel); // Check if Cursor CLI is available const isCursorAvailable = cursorCliStatus?.installed && cursorCliStatus?.auth?.authenticated; // Check if Codex CLI is available const isCodexAvailable = codexCliStatus?.installed && codexCliStatus?.auth?.authenticated; // Filter Cursor models based on enabled models from global settings const filteredCursorModels = CURSOR_MODELS.filter((model) => { // Extract the cursor model ID from the prefixed ID (e.g., "cursor-auto" -> "auto") const cursorModelId = stripProviderPrefix(model.id); return enabledCursorModels.includes(cursorModelId as any); }); const handleProviderChange = (provider: ModelProvider) => { if (provider === 'cursor' && selectedProvider !== 'cursor') { // Switch to Cursor's default model (from global settings) onModelSelect(`${PROVIDER_PREFIXES.cursor}${cursorDefaultModel}`); } else if (provider === 'codex' && selectedProvider !== 'codex') { // Switch to Codex's default model (gpt-5.2) onModelSelect('gpt-5.2'); } else if (provider === 'claude' && selectedProvider !== 'claude') { // Switch to Claude's default model onModelSelect('sonnet'); } }; return (
{/* Provider Selection */}
{/* Claude Models */} {selectedProvider === 'claude' && (
Native SDK
{CLAUDE_MODELS.map((option) => { const isSelected = selectedModel === option.id; const shortName = option.label.replace('Claude ', ''); return ( ); })}
)} {/* Cursor Models */} {selectedProvider === 'cursor' && (
{/* Warning when Cursor CLI is not available */} {!isCursorAvailable && (
Cursor CLI is not installed or authenticated. Configure it in Settings → AI Providers.
)}
CLI
{filteredCursorModels.length === 0 ? (
No Cursor models enabled. Enable models in Settings → AI Providers.
) : ( filteredCursorModels.map((option) => { const isSelected = selectedModel === option.id; return ( ); }) )}
)} {/* Codex Models */} {selectedProvider === 'codex' && (
{/* Warning when Codex CLI is not available */} {!isCodexAvailable && (
Codex CLI is not installed or authenticated. Configure it in Settings → AI Providers.
)}
CLI
{CODEX_MODELS.map((option) => { const isSelected = selectedModel === option.id; return ( ); })}
)}
); }