feat: 注册 codex modelType 并添加 /provider codex 切换

- providers.ts: 添加 codex 到 APIProvider 类型和路由
- provider.ts: /provider codex 切换,含 CODEX_API_KEY 检查
- configs.ts: 所有 12 个模型配置添加 codex 字段
- status.tsx: 状态栏显示 Codex API
- managedEnvConstants.ts: 注册 CODEX_* 环境变量

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
claude-code-best
2026-04-26 22:23:09 +08:00
parent 13799b5058
commit 4427a6c6db
5 changed files with 54 additions and 4 deletions

View File

@@ -63,6 +63,7 @@ const call: LocalCommandCall = async (args, context) => {
const validProviders = [
'anthropic',
'openai',
'codex',
'gemini',
'grok',
'bedrock',
@@ -120,10 +121,23 @@ const call: LocalCommandCall = async (args, context) => {
}
}
// Check env vars when switching to codex (including settings.env)
if (arg === 'codex') {
const mergedEnv = getMergedEnv()
const hasKey = !!mergedEnv.CODEX_API_KEY
if (!hasKey) {
updateSettingsForSource('userSettings', { modelType: 'codex' })
return {
type: 'text',
value: `Switched to Codex provider.\nWarning: Missing env var: CODEX_API_KEY\nConfigure it via /login (ChatGPT Subscription) or set manually.`,
}
}
}
// 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
@@ -131,7 +145,7 @@ const call: LocalCommandCall = async (args, context) => {
delete process.env.CLAUDE_CODE_USE_OPENAI
delete process.env.CLAUDE_CODE_USE_GEMINI
delete process.env.CLAUDE_CODE_USE_GROK
// Update settings.json
delete process.env.CLAUDE_CODE_USE_CODEX
updateSettingsForSource('userSettings', { modelType: arg })
// Ensure settings.env gets applied to process.env
applyConfigEnvironmentVariables()
@@ -157,9 +171,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

View File

@@ -23,6 +23,7 @@ const PROVIDER_MANAGED_ENV_VARS = new Set([
'CLAUDE_CODE_USE_VERTEX',
'CLAUDE_CODE_USE_FOUNDRY',
'CLAUDE_CODE_USE_GEMINI',
'CLAUDE_CODE_USE_CODEX',
// Endpoint config (base URLs, project/resource identifiers)
'ANTHROPIC_BASE_URL',
'ANTHROPIC_BEDROCK_BASE_URL',
@@ -31,6 +32,7 @@ const PROVIDER_MANAGED_ENV_VARS = new Set([
'ANTHROPIC_FOUNDRY_RESOURCE',
'ANTHROPIC_VERTEX_PROJECT_ID',
'GEMINI_BASE_URL',
'CODEX_BASE_URL',
// Region routing (per-model VERTEX_REGION_CLAUDE_* handled by prefix below)
'CLOUD_ML_REGION',
// Auth
@@ -43,6 +45,7 @@ const PROVIDER_MANAGED_ENV_VARS = new Set([
'CLAUDE_CODE_SKIP_VERTEX_AUTH',
'CLAUDE_CODE_SKIP_FOUNDRY_AUTH',
'GEMINI_API_KEY',
'CODEX_API_KEY',
// Model defaults — often set to provider-specific ID formats
'ANTHROPIC_MODEL',
'ANTHROPIC_DEFAULT_HAIKU_MODEL',
@@ -92,6 +95,17 @@ const PROVIDER_MANAGED_ENV_VARS = new Set([
'GEMINI_DEFAULT_SONNET_MODEL_DESCRIPTION',
'GEMINI_DEFAULT_SONNET_MODEL_NAME',
'GEMINI_DEFAULT_SONNET_MODEL_SUPPORTED_CAPABILITIES',
// Codex provider specific
'CODEX_BASE_URL',
'CODEX_API_KEY',
'CODEX_MODEL',
'CODEX_DEFAULT_HAIKU_MODEL',
'CODEX_DEFAULT_SONNET_MODEL',
'CODEX_DEFAULT_OPUS_MODEL',
'CODEX_IMGBB_API_KEY',
'CODEX_LOGIN_METHOD',
'CODEX_ACCESS_TOKEN',
'CODEX_REFRESH_TOKEN',
])
const PROVIDER_MANAGED_ENV_PREFIXES = [
@@ -201,6 +215,7 @@ export const SAFE_ENV_VARS = new Set([
'CLAUDE_CODE_USE_FOUNDRY',
'CLAUDE_CODE_USE_GEMINI',
'CLAUDE_CODE_USE_VERTEX',
'CLAUDE_CODE_USE_CODEX',
'GEMINI_MODEL',
'GEMINI_SMALL_FAST_MODEL',
'GEMINI_DEFAULT_HAIKU_MODEL',
@@ -215,6 +230,11 @@ export const SAFE_ENV_VARS = new Set([
'GEMINI_DEFAULT_SONNET_MODEL_DESCRIPTION',
'GEMINI_DEFAULT_SONNET_MODEL_NAME',
'GEMINI_DEFAULT_SONNET_MODEL_SUPPORTED_CAPABILITIES',
// Codex provider specific
'CODEX_DEFAULT_HAIKU_MODEL',
'CODEX_DEFAULT_SONNET_MODEL',
'CODEX_DEFAULT_OPUS_MODEL',
'CODEX_IMGBB_API_KEY',
'DISABLE_AUTOUPDATER',
'DISABLE_BUG_COMMAND',
'DISABLE_COST_WARNINGS',

View File

@@ -13,6 +13,7 @@ export const CLAUDE_3_7_SONNET_CONFIG = {
foundry: 'claude-3-7-sonnet',
openai: 'claude-3-7-sonnet-20250219',
gemini: 'claude-3-7-sonnet-20250219',
codex: 'claude-3-7-sonnet-20250219',
grok: 'claude-3-7-sonnet-20250219',
} as const satisfies ModelConfig
@@ -23,6 +24,7 @@ export const CLAUDE_3_5_V2_SONNET_CONFIG = {
foundry: 'claude-3-5-sonnet',
openai: 'claude-3-5-sonnet-20241022',
gemini: 'claude-3-5-sonnet-20241022',
codex: 'claude-3-5-sonnet-20241022',
grok: 'claude-3-5-sonnet-20241022',
} as const satisfies ModelConfig
@@ -33,6 +35,7 @@ export const CLAUDE_3_5_HAIKU_CONFIG = {
foundry: 'claude-3-5-haiku',
openai: 'claude-3-5-haiku-20241022',
gemini: 'claude-3-5-haiku-20241022',
codex: 'claude-3-5-haiku-20241022',
grok: 'claude-3-5-haiku-20241022',
} as const satisfies ModelConfig
@@ -43,6 +46,7 @@ export const CLAUDE_HAIKU_4_5_CONFIG = {
foundry: 'claude-haiku-4-5',
openai: 'claude-haiku-4-5-20251001',
gemini: 'claude-haiku-4-5-20251001',
codex: 'claude-haiku-4-5-20251001',
grok: 'claude-haiku-4-5-20251001',
} as const satisfies ModelConfig
@@ -53,6 +57,7 @@ export const CLAUDE_SONNET_4_CONFIG = {
foundry: 'claude-sonnet-4',
openai: 'claude-sonnet-4-20250514',
gemini: 'claude-sonnet-4-20250514',
codex: 'claude-sonnet-4-20250514',
grok: 'claude-sonnet-4-20250514',
} as const satisfies ModelConfig
@@ -63,6 +68,7 @@ export const CLAUDE_SONNET_4_5_CONFIG = {
foundry: 'claude-sonnet-4-5',
openai: 'claude-sonnet-4-5-20250929',
gemini: 'claude-sonnet-4-5-20250929',
codex: 'claude-sonnet-4-5-20250929',
grok: 'claude-sonnet-4-5-20250929',
} as const satisfies ModelConfig
@@ -73,6 +79,7 @@ export const CLAUDE_OPUS_4_CONFIG = {
foundry: 'claude-opus-4',
openai: 'claude-opus-4-20250514',
gemini: 'claude-opus-4-20250514',
codex: 'claude-opus-4-20250514',
grok: 'claude-opus-4-20250514',
} as const satisfies ModelConfig
@@ -83,6 +90,7 @@ export const CLAUDE_OPUS_4_1_CONFIG = {
foundry: 'claude-opus-4-1',
openai: 'claude-opus-4-1-20250805',
gemini: 'claude-opus-4-1-20250805',
codex: 'claude-opus-4-1-20250805',
grok: 'claude-opus-4-1-20250805',
} as const satisfies ModelConfig
@@ -93,6 +101,7 @@ export const CLAUDE_OPUS_4_5_CONFIG = {
foundry: 'claude-opus-4-5',
openai: 'claude-opus-4-5-20251101',
gemini: 'claude-opus-4-5-20251101',
codex: 'claude-opus-4-5-20251101',
grok: 'claude-opus-4-5-20251101',
} as const satisfies ModelConfig
@@ -103,6 +112,7 @@ export const CLAUDE_OPUS_4_6_CONFIG = {
foundry: 'claude-opus-4-6',
openai: 'claude-opus-4-6',
gemini: 'claude-opus-4-6',
codex: 'claude-opus-4-6',
grok: 'claude-opus-4-6',
} as const satisfies ModelConfig
@@ -113,6 +123,7 @@ export const CLAUDE_OPUS_4_7_CONFIG = {
foundry: 'claude-opus-4-7',
openai: 'claude-opus-4-7',
gemini: 'claude-opus-4-7',
codex: 'claude-opus-4-7',
grok: 'claude-opus-4-7',
} as const satisfies ModelConfig
@@ -123,6 +134,7 @@ export const CLAUDE_SONNET_4_6_CONFIG = {
foundry: 'claude-sonnet-4-6',
openai: 'claude-sonnet-4-6',
gemini: 'claude-sonnet-4-6',
codex: 'claude-sonnet-4-6',
grok: 'claude-sonnet-4-6',
} as const satisfies ModelConfig

View File

@@ -8,12 +8,14 @@ export type APIProvider =
| 'vertex'
| 'foundry'
| 'openai'
| 'codex'
| 'gemini'
| 'grok'
export function getAPIProvider(): APIProvider {
const modelType = getInitialSettings().modelType
if (modelType === 'openai') return 'openai'
if (modelType === 'codex') return 'codex'
if (modelType === 'gemini') return 'gemini'
if (modelType === 'grok') return 'grok'
@@ -22,6 +24,7 @@ export function getAPIProvider(): APIProvider {
if (isEnvTruthy(process.env.CLAUDE_CODE_USE_FOUNDRY)) return 'foundry'
if (isEnvTruthy(process.env.CLAUDE_CODE_USE_OPENAI)) return 'openai'
if (isEnvTruthy(process.env.CLAUDE_CODE_USE_CODEX)) return 'codex'
if (isEnvTruthy(process.env.CLAUDE_CODE_USE_GEMINI)) return 'gemini'
if (isEnvTruthy(process.env.CLAUDE_CODE_USE_GROK)) return 'grok'

View File

@@ -342,6 +342,7 @@ export function buildAPIProviderProperties(): Property[] {
gemini: 'Gemini API',
grok: 'Grok API',
openai: 'OpenAI API',
codex: 'Codex API',
}[apiProvider]
properties.push({
label: 'API provider',