Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 31 additions & 4 deletions src/commands/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ function getEnvVarForProvider(provider: string): string {
return 'CLAUDE_CODE_USE_FOUNDRY'
case 'gemini':
return 'CLAUDE_CODE_USE_GEMINI'
case 'codex':
return 'CLAUDE_CODE_USE_CODEX'
case 'grok':
return 'CLAUDE_CODE_USE_GROK'
default:
Expand Down Expand Up @@ -51,6 +53,7 @@ const call: LocalCommandCall = async (args, context) => {
delete process.env.CLAUDE_CODE_USE_VERTEX
delete process.env.CLAUDE_CODE_USE_FOUNDRY
delete process.env.CLAUDE_CODE_USE_OPENAI
delete process.env.CLAUDE_CODE_USE_CODEX
delete process.env.CLAUDE_CODE_USE_GEMINI
delete process.env.CLAUDE_CODE_USE_GROK
return {
Expand All @@ -63,6 +66,7 @@ const call: LocalCommandCall = async (args, context) => {
const validProviders = [
'anthropic',
'openai',
'codex',
'gemini',
'grok',
'bedrock',
Expand Down Expand Up @@ -93,6 +97,24 @@ const call: LocalCommandCall = async (args, context) => {
}
}

if (arg === 'codex') {
const mergedEnv = getMergedEnv()
const hasKey = !!mergedEnv.CODEX_API_KEY
const hasUrl = !!mergedEnv.CODEX_BASE_URL
const hasModel = !!mergedEnv.CODEX_MODEL
if (!hasKey || !hasUrl || !hasModel) {
updateSettingsForSource('userSettings', { modelType: 'codex' })
const missing = []
if (!hasKey) missing.push('CODEX_API_KEY')
if (!hasUrl) missing.push('CODEX_BASE_URL')
if (!hasModel) missing.push('CODEX_MODEL')
return {
type: 'text',
value: `Switched to Codex provider.\nWarning: Missing env vars: ${missing.join(', ')}\nConfigure them via /login, settings.json env, or set them manually.`,
}
}
}

// Check env vars when switching to grok (including settings.env)
if (arg === 'grok') {
const mergedEnv = getMergedEnv()
Expand Down Expand Up @@ -123,19 +145,24 @@ const call: LocalCommandCall = async (args, context) => {
// Handle different provider types
// - 'anthropic', 'openai', 'gemini' are stored in settings.json (persistent)
// - 'bedrock', 'vertex', 'foundry' are env-only (do NOT touch settings.json)
if (arg === 'anthropic' || arg === 'openai' || arg === 'gemini' || arg === 'grok') {
if (arg === 'anthropic' || arg === 'openai' || arg === 'codex' || arg === 'gemini' || arg === 'grok') {
// Clear any cloud provider env vars to avoid conflicts
delete process.env.CLAUDE_CODE_USE_BEDROCK
delete process.env.CLAUDE_CODE_USE_VERTEX
delete process.env.CLAUDE_CODE_USE_FOUNDRY
delete process.env.CLAUDE_CODE_USE_OPENAI
delete process.env.CLAUDE_CODE_USE_CODEX
delete process.env.CLAUDE_CODE_USE_GEMINI
delete process.env.CLAUDE_CODE_USE_GROK
// Update settings.json
updateSettingsForSource('userSettings', { modelType: arg })
// Ensure settings.env gets applied to process.env
applyConfigEnvironmentVariables()
return { type: 'text', value: `API provider set to ${arg}.` }
const message =
arg === 'codex' && !getMergedEnv().CODEX_IMGBB_API_KEY
? `API provider set to ${arg}.\nOptional: set CODEX_IMGBB_API_KEY to enable local image uploads for image understanding.`
: `API provider set to ${arg}.`
return { type: 'text', value: message }
} else {
// Cloud providers: set env vars only, do NOT touch settings.json
delete process.env.CLAUDE_CODE_USE_OPENAI
Expand All @@ -157,9 +184,9 @@ const provider = {
type: 'local',
name: 'provider',
description:
'Switch API provider (anthropic/openai/gemini/grok/bedrock/vertex/foundry)',
'Switch API provider (anthropic/openai/codex/gemini/grok/bedrock/vertex/foundry)',
aliases: ['api'],
argumentHint: '[anthropic|openai|gemini|grok|bedrock|vertex|foundry|unset]',
argumentHint: '[anthropic|openai|codex|gemini|grok|bedrock|vertex|foundry|unset]',
supportsNonInteractive: true,
load: () => Promise.resolve({ call }),
} satisfies Command
Expand Down
Loading
Loading