import { Label } from '@/components/ui/label'; import { Badge } from '@/components/ui/badge'; import { Checkbox } from '@/components/ui/checkbox'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { Terminal, Cloud, Cpu, Brain, Sparkles, Zap } from 'lucide-react'; import { cn } from '@/lib/utils'; import type { OpencodeModelId, OpencodeProvider, OpencodeModelConfig } from '@automaker/types'; import { OPENCODE_MODELS, OPENCODE_MODEL_CONFIG_MAP } from '@automaker/types'; import { AnthropicIcon } from '@/components/ui/provider-icon'; import type { ComponentType } from 'react'; interface OpencodeModelConfigurationProps { enabledOpencodeModels: OpencodeModelId[]; opencodeDefaultModel: OpencodeModelId; isSaving: boolean; onDefaultModelChange: (model: OpencodeModelId) => void; onModelToggle: (model: OpencodeModelId, enabled: boolean) => void; } /** * Returns the appropriate icon component for a given OpenCode provider */ function getProviderIcon(provider: OpencodeProvider): ComponentType<{ className?: string }> { switch (provider) { case 'opencode': return Terminal; case 'amazon-bedrock-anthropic': return AnthropicIcon; case 'amazon-bedrock-deepseek': return Brain; case 'amazon-bedrock-amazon': return Cloud; case 'amazon-bedrock-meta': return Cpu; case 'amazon-bedrock-mistral': return Sparkles; case 'amazon-bedrock-qwen': return Zap; default: return Terminal; } } /** * Returns a formatted provider label for display */ function getProviderLabel(provider: OpencodeProvider): string { switch (provider) { case 'opencode': return 'OpenCode (Free)'; case 'amazon-bedrock-anthropic': return 'Claude (Bedrock)'; case 'amazon-bedrock-deepseek': return 'DeepSeek (Bedrock)'; case 'amazon-bedrock-amazon': return 'Amazon Nova (Bedrock)'; case 'amazon-bedrock-meta': return 'Meta Llama (Bedrock)'; case 'amazon-bedrock-mistral': return 'Mistral (Bedrock)'; case 'amazon-bedrock-qwen': return 'Qwen (Bedrock)'; default: return provider; } } export function OpencodeModelConfiguration({ enabledOpencodeModels, opencodeDefaultModel, isSaving, onDefaultModelChange, onModelToggle, }: OpencodeModelConfigurationProps) { // Group models by provider for organized display const modelsByProvider = OPENCODE_MODELS.reduce( (acc, model) => { if (!acc[model.provider]) { acc[model.provider] = []; } acc[model.provider].push(model); return acc; }, {} as Record ); // Order: Free tier first, then Claude, then others const providerOrder: OpencodeProvider[] = [ 'opencode', 'amazon-bedrock-anthropic', 'amazon-bedrock-deepseek', 'amazon-bedrock-amazon', 'amazon-bedrock-meta', 'amazon-bedrock-mistral', 'amazon-bedrock-qwen', ]; return (

Model Configuration

Configure which OpenCode models are available in the feature modal

{/* Default Model Selection */}
{/* Available Models grouped by provider */}
{providerOrder.map((provider) => { const models = modelsByProvider[provider]; if (!models || models.length === 0) return null; const ProviderIconComponent = getProviderIcon(provider); return (
{getProviderLabel(provider)} {provider === 'opencode' && ( Free )}
{models.map((model) => { const isEnabled = enabledOpencodeModels.includes(model.id); const isDefault = model.id === opencodeDefaultModel; return (
onModelToggle(model.id, !!checked)} disabled={isSaving || isDefault} />
{model.label} {model.supportsVision && ( Vision )} {model.tier === 'free' && ( Free )} {isDefault && ( Default )}

{model.description}

); })}
); })}
); }