( provider: string, apiKey?: string )
| 135 | } |
| 136 | |
| 137 | async function selectModel( |
| 138 | provider: string, |
| 139 | apiKey?: string |
| 140 | ): Promise<string | symbol> { |
| 141 | const providerDisplayName = |
| 142 | PROVIDER_DISPLAY_NAMES[provider]?.split(' (')[0] || provider; |
| 143 | const loadingSpinner = spinner(); |
| 144 | loadingSpinner.start(`Fetching models from ${providerDisplayName}...`); |
| 145 | |
| 146 | let models: string[] = []; |
| 147 | let usedFallback = false; |
| 148 | |
| 149 | try { |
| 150 | models = await fetchModelsForProvider(provider, apiKey); |
| 151 | } catch { |
| 152 | // Fall back to hardcoded list |
| 153 | usedFallback = true; |
| 154 | const providerKey = provider.toLowerCase() as keyof typeof MODEL_LIST; |
| 155 | models = MODEL_LIST[providerKey] || []; |
| 156 | } |
| 157 | |
| 158 | // Check cache info for display |
| 159 | const cacheInfo = getCacheInfo(); |
| 160 | const cacheAge = formatCacheAge(cacheInfo.timestamp); |
| 161 | |
| 162 | if (usedFallback) { |
| 163 | loadingSpinner.stop( |
| 164 | chalk.yellow('Could not fetch models from API. Using default list.') |
| 165 | ); |
| 166 | } else if (cacheAge) { |
| 167 | loadingSpinner.stop(`Models loaded ${chalk.dim(`(cached ${cacheAge})`)}`); |
| 168 | } else { |
| 169 | loadingSpinner.stop('Models loaded'); |
| 170 | } |
| 171 | |
| 172 | if (models.length === 0) { |
| 173 | // For Ollama/MLX, prompt for manual entry |
| 174 | if (NO_API_KEY_PROVIDERS.includes(provider as OCO_AI_PROVIDER_ENUM)) { |
| 175 | return await text({ |
| 176 | message: 'Enter model name (e.g., llama3:8b, mistral):', |
| 177 | placeholder: 'llama3:8b', |
| 178 | validate: (value) => { |
| 179 | if (!value || value.trim().length === 0) { |
| 180 | return 'Model name is required'; |
| 181 | } |
| 182 | return undefined; |
| 183 | } |
| 184 | }); |
| 185 | } |
| 186 | |
| 187 | // Use default from config |
| 188 | const providerKey = provider.toLowerCase() as keyof typeof MODEL_LIST; |
| 189 | return MODEL_LIST[providerKey]?.[0] || 'gpt-4o-mini'; |
| 190 | } |
| 191 | |
| 192 | // Get recommended model for this provider |
| 193 | const recommended = |
| 194 | RECOMMENDED_MODELS[provider as keyof typeof RECOMMENDED_MODELS]; |
no test coverage detected
searching dependent graphs…