feat: auto-set default model when switching provider

- Add setDefaultModel() in provider.ts to set sonnet as default when using /provider command
- Add model setting in ConsoleOAuthFlow.tsx for all provider save paths:
  - Anthropic OAuth login
  - Custom platform (Anthropic Compatible)
  - OpenAI
  - Gemini
- Fix modelOptions.ts to only show CoStrict models when provider IS costrict (not when creds exist)
- Add standard model options for non-costrict providers (Sonnet/Opus/Haiku)
This commit is contained in:
Askhz 2026-04-20 21:22:29 +08:00
parent 425ca6bb19
commit 7b5e1f382d
2 changed files with 37 additions and 0 deletions

View File

@ -4,6 +4,7 @@ import { getAPIProvider } from '../utils/model/providers.js'
import { updateSettingsForSource } from '../utils/settings/settings.js'
import { getSettings_DEPRECATED } from '../utils/settings/settings.js'
import { applyConfigEnvironmentVariables } from '../utils/managedEnv.js'
import { getDefaultSonnetModel, getDefaultOpusModel, getDefaultHaikuModel } from '../utils/model/model.js'
function getEnvVarForProvider(provider: string): string {
switch (provider) {
@ -43,6 +44,28 @@ const call: LocalCommandCall = async (args, context) => {
return { type: 'text', value: `Current API provider: ${current}` }
}
// Helper function to set default model based on provider
const setDefaultModel = (provider: string) => {
const settings = getSettings_DEPRECATED() || {}
const currentModel = settings.model
// Only set default if no model has been explicitly set
if (!currentModel) {
let defaultModel: string
switch (provider) {
case 'anthropic':
defaultModel = getDefaultSonnetModel()
break
case 'openai':
case 'gemini':
case 'grok':
default:
defaultModel = getDefaultSonnetModel()
}
updateSettingsForSource('userSettings', { model: defaultModel })
}
}
// unset - clear settings, fallback to env vars
if (arg === 'unset') {
updateSettingsForSource('userSettings', { modelType: undefined })
@ -84,6 +107,7 @@ const call: LocalCommandCall = async (args, context) => {
const hasUrl = !!mergedEnv.OPENAI_BASE_URL
if (!hasKey || !hasUrl) {
updateSettingsForSource('userSettings', { modelType: 'openai' })
setDefaultModel('openai')
const missing = []
if (!hasKey) missing.push('OPENAI_API_KEY')
if (!hasUrl) missing.push('OPENAI_BASE_URL')
@ -100,6 +124,7 @@ const call: LocalCommandCall = async (args, context) => {
const hasKey = !!(mergedEnv.GROK_API_KEY || mergedEnv.XAI_API_KEY)
if (!hasKey) {
updateSettingsForSource('userSettings', { modelType: 'grok' })
setDefaultModel('grok')
return {
type: 'text',
value: `Switched to Grok provider.\nWarning: Missing env var: GROK_API_KEY (or XAI_API_KEY)\nConfigure it via settings.json env or set manually.`,
@ -114,6 +139,7 @@ const call: LocalCommandCall = async (args, context) => {
// GEMINI_BASE_URL is optional (has default)
if (!hasKey) {
updateSettingsForSource('userSettings', { modelType: 'gemini' })
setDefaultModel('gemini')
return {
type: 'text',
value: `Switched to Gemini provider.\nWarning: Missing env var: GEMINI_API_KEY\nConfigure it via /login or set manually.`,
@ -135,6 +161,8 @@ const call: LocalCommandCall = async (args, context) => {
delete process.env.CLAUDE_CODE_USE_COSTRICT
// Update settings.json
updateSettingsForSource('userSettings', { modelType: arg })
// Set default model for the provider
setDefaultModel(arg)
// Ensure settings.env gets applied to process.env
applyConfigEnvironmentVariables()
return { type: 'text', value: `API provider set to ${arg}.` }

View File

@ -13,6 +13,7 @@ import { OAuthService } from '../services/oauth/index.js'
import { getOauthAccountInfo, validateForceLoginOrg } from '../utils/auth.js'
import { logError } from '../utils/log.js'
import { getSettings_DEPRECATED, updateSettingsForSource } from '../utils/settings/settings.js'
import { getDefaultSonnetModel } from '../utils/model/model.js'
import { Select } from './CustomSelect/select.js'
import { Spinner } from './Spinner.js'
import TextInput from './TextInput.js'
@ -283,6 +284,8 @@ export function ConsoleOAuthFlow({
}
// Reset modelType to anthropic when using OAuth login
updateSettingsForSource('userSettings', { modelType: 'anthropic' } as any)
// Set default model to sonnet for Anthropic provider
updateSettingsForSource('userSettings', { model: getDefaultSonnetModel() } as any)
// Clear costrict env var to prevent conflicts
delete process.env.CLAUDE_CODE_USE_COSTRICT
@ -729,6 +732,8 @@ function OAuthStatusMessage({
for (const [k, v] of Object.entries(env)) process.env[k] = v
// Clear costrict env var to prevent conflicts when using custom platform
delete process.env.CLAUDE_CODE_USE_COSTRICT
// Set default model to sonnet for this provider
updateSettingsForSource('userSettings', { model: getDefaultSonnetModel() } as any)
setOAuthStatus({ state: 'success' })
void onDone()
}
@ -951,6 +956,8 @@ function OAuthStatusMessage({
for (const [k, v] of Object.entries(env)) process.env[k] = v
// Clear costrict env var to prevent conflicts when using OpenAI
delete process.env.CLAUDE_CODE_USE_COSTRICT
// Set default model to sonnet for this provider
updateSettingsForSource('userSettings', { model: getDefaultSonnetModel() } as any)
setOAuthStatus({ state: 'success' })
void onDone()
}
@ -1186,6 +1193,8 @@ function OAuthStatusMessage({
for (const [k, v] of Object.entries(env)) process.env[k] = v
// Clear costrict env var to prevent conflicts when using Gemini
delete process.env.CLAUDE_CODE_USE_COSTRICT
// Set default model to sonnet for this provider
updateSettingsForSource('userSettings', { model: getDefaultSonnetModel() } as any)
setOAuthStatus({ state: 'success' })
void onDone()
}