refactor: 将 modelType openai-responses 重命名为 codex

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
claude-code-best
2026-04-26 22:08:03 +08:00
parent 25c322c8db
commit 2af6fd42c3
12 changed files with 42 additions and 42 deletions

View File

@@ -15,7 +15,7 @@ function getEnvVarForProvider(provider: string): string {
return 'CLAUDE_CODE_USE_FOUNDRY' return 'CLAUDE_CODE_USE_FOUNDRY'
case 'gemini': case 'gemini':
return 'CLAUDE_CODE_USE_GEMINI' return 'CLAUDE_CODE_USE_GEMINI'
case 'openai-responses': case 'codex':
return 'CLAUDE_CODE_USE_CODEX' return 'CLAUDE_CODE_USE_CODEX'
case 'grok': case 'grok':
return 'CLAUDE_CODE_USE_GROK' return 'CLAUDE_CODE_USE_GROK'
@@ -66,7 +66,7 @@ const call: LocalCommandCall = async (args, context) => {
const validProviders = [ const validProviders = [
'anthropic', 'anthropic',
'openai', 'openai',
'openai-responses', 'codex',
'gemini', 'gemini',
'grok', 'grok',
'bedrock', 'bedrock',
@@ -97,11 +97,11 @@ const call: LocalCommandCall = async (args, context) => {
} }
} }
if (arg === 'openai-responses') { if (arg === 'codex') {
const mergedEnv = getMergedEnv() const mergedEnv = getMergedEnv()
const hasKey = !!mergedEnv.CODEX_API_KEY const hasKey = !!mergedEnv.CODEX_API_KEY
if (!hasKey) { if (!hasKey) {
updateSettingsForSource('userSettings', { modelType: 'openai-responses' }) updateSettingsForSource('userSettings', { modelType: 'codex' })
return { return {
type: 'text', type: 'text',
value: `Switched to OpenAI Responses provider.\nWarning: Missing env var: CODEX_API_KEY\nConfigure via /login, settings.json env, or set manually.`, value: `Switched to OpenAI Responses provider.\nWarning: Missing env var: CODEX_API_KEY\nConfigure via /login, settings.json env, or set manually.`,
@@ -139,7 +139,7 @@ const call: LocalCommandCall = async (args, context) => {
// Handle different provider types // Handle different provider types
// - 'anthropic', 'openai', 'gemini' are stored in settings.json (persistent) // - 'anthropic', 'openai', 'gemini' are stored in settings.json (persistent)
// - 'bedrock', 'vertex', 'foundry' are env-only (do NOT touch settings.json) // - 'bedrock', 'vertex', 'foundry' are env-only (do NOT touch settings.json)
if (arg === 'anthropic' || arg === 'openai' || arg === 'openai-responses' || arg === 'gemini' || arg === 'grok') { if (arg === 'anthropic' || arg === 'openai' || arg === 'codex' || arg === 'gemini' || arg === 'grok') {
// Clear any cloud provider env vars to avoid conflicts // Clear any cloud provider env vars to avoid conflicts
delete process.env.CLAUDE_CODE_USE_BEDROCK delete process.env.CLAUDE_CODE_USE_BEDROCK
delete process.env.CLAUDE_CODE_USE_VERTEX delete process.env.CLAUDE_CODE_USE_VERTEX
@@ -153,7 +153,7 @@ const call: LocalCommandCall = async (args, context) => {
// Ensure settings.env gets applied to process.env // Ensure settings.env gets applied to process.env
applyConfigEnvironmentVariables() applyConfigEnvironmentVariables()
const message = const message =
arg === 'openai-responses' && !getMergedEnv().CODEX_IMGBB_API_KEY 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}.\nOptional: set CODEX_IMGBB_API_KEY to enable local image uploads for image understanding.`
: `API provider set to ${arg}.` : `API provider set to ${arg}.`
return { type: 'text', value: message } return { type: 'text', value: message }
@@ -178,9 +178,9 @@ const provider = {
type: 'local', type: 'local',
name: 'provider', name: 'provider',
description: description:
'Switch API provider (anthropic/openai/openai-responses/gemini/grok/bedrock/vertex/foundry)', 'Switch API provider (anthropic/openai/codex/gemini/grok/bedrock/vertex/foundry)',
aliases: ['api'], aliases: ['api'],
argumentHint: '[anthropic|openai|openai-responses|gemini|grok|bedrock|vertex|foundry|unset]', argumentHint: '[anthropic|openai|codex|gemini|grok|bedrock|vertex|foundry|unset]',
supportsNonInteractive: true, supportsNonInteractive: true,
load: () => Promise.resolve({ call }), load: () => Promise.resolve({ call }),
} satisfies Command } satisfies Command

View File

@@ -1347,7 +1347,7 @@ async function* queryModel(
return return
} }
if (getAPIProvider() === 'openai-responses') { if (getAPIProvider() === 'codex') {
const { queryModelCodex } = await import('./codex/index.js') const { queryModelCodex } = await import('./codex/index.js')
yield* queryModelCodex(messagesForAPI, systemPrompt, filteredTools, signal, options) yield* queryModelCodex(messagesForAPI, systemPrompt, filteredTools, signal, options)
return return

View File

@@ -13,7 +13,7 @@ function wrapFetchForUsage(base: typeof fetch): typeof fetch {
): Promise<Response> => { ): Promise<Response> => {
const res = await base(...args) const res = await base(...args)
try { try {
updateProviderBuckets('openai-responses', openaiAdapter.parseHeaders(res.headers)) updateProviderBuckets('codex', openaiAdapter.parseHeaders(res.headers))
} catch { } catch {
// Usage tracking must not affect the request path. // Usage tracking must not affect the request path.
} }

View File

@@ -262,7 +262,7 @@ export async function* queryModelCodex(
model, model,
provider: process.env.CODEX_LOGIN_METHOD === 'chatgpt_subscription' provider: process.env.CODEX_LOGIN_METHOD === 'chatgpt_subscription'
? 'codex-chatgpt' ? 'codex-chatgpt'
: 'openai-responses', : 'codex',
input: convertMessagesToLangfuse(messagesForAPI, systemPrompt), input: convertMessagesToLangfuse(messagesForAPI, systemPrompt),
output: convertOutputToLangfuse(collectedMessages), output: convertOutputToLangfuse(collectedMessages),
usage: totalUsage, usage: totalUsage,

View File

@@ -57,7 +57,7 @@ const PROVIDER_GENERATION_NAMES: Record<string, string> = {
vertex: 'ChatVertexAnthropic', vertex: 'ChatVertexAnthropic',
foundry: 'ChatFoundry', foundry: 'ChatFoundry',
openai: 'ChatOpenAI', openai: 'ChatOpenAI',
'openai-responses': 'ChatOpenAIResponses', 'codex': 'ChatOpenAIResponses',
'codex-chatgpt': 'ChatCodex', 'codex-chatgpt': 'ChatCodex',
gemini: 'ChatGoogleGenerativeAI', gemini: 'ChatGoogleGenerativeAI',
grok: 'ChatXAI', grok: 'ChatXAI',

View File

@@ -119,7 +119,7 @@ export function isAnthropicAuthEnabled(): boolean {
isEnvTruthy(process.env.CLAUDE_CODE_USE_FOUNDRY) || isEnvTruthy(process.env.CLAUDE_CODE_USE_FOUNDRY) ||
isEnvTruthy(process.env.CLAUDE_CODE_USE_CODEX) || isEnvTruthy(process.env.CLAUDE_CODE_USE_CODEX) ||
(settings as any).modelType === 'openai' || (settings as any).modelType === 'openai' ||
(settings as any).modelType === 'openai-responses' || (settings as any).modelType === 'codex' ||
(settings as any).modelType === 'gemini' || (settings as any).modelType === 'gemini' ||
!!process.env.OPENAI_BASE_URL || !!process.env.OPENAI_BASE_URL ||
!!process.env.CODEX_BASE_URL || !!process.env.CODEX_BASE_URL ||

View File

@@ -1,7 +1,7 @@
import { describe, expect, test, beforeEach, afterEach } from "bun:test"; import { describe, expect, test, beforeEach, afterEach } from "bun:test";
import { mock } from "bun:test"; import { mock } from "bun:test";
let mockedModelType: "gemini" | "openai-responses" | undefined; let mockedModelType: "gemini" | "codex" | undefined;
mock.module("../../settings/settings.js", () => ({ mock.module("../../settings/settings.js", () => ({
getInitialSettings: () => getInitialSettings: () =>
@@ -53,9 +53,9 @@ describe("getAPIProvider", () => {
expect(getAPIProvider()).toBe("gemini"); expect(getAPIProvider()).toBe("gemini");
}); });
test('returns "openai-responses" when modelType is openai-responses', () => { test('returns "codex" when modelType is codex', () => {
mockedModelType = "openai-responses"; mockedModelType = "codex";
expect(getAPIProvider()).toBe("openai-responses"); expect(getAPIProvider()).toBe("codex");
}); });
test("modelType takes precedence over environment variables", () => { test("modelType takes precedence over environment variables", () => {
@@ -69,9 +69,9 @@ describe("getAPIProvider", () => {
expect(getAPIProvider()).toBe("gemini"); expect(getAPIProvider()).toBe("gemini");
}); });
test('returns "openai-responses" when CLAUDE_CODE_USE_CODEX is set', () => { test('returns "codex" when CLAUDE_CODE_USE_CODEX is set', () => {
process.env.CLAUDE_CODE_USE_CODEX = "1"; process.env.CLAUDE_CODE_USE_CODEX = "1";
expect(getAPIProvider()).toBe("openai-responses"); expect(getAPIProvider()).toBe("codex");
}); });
test('returns "bedrock" when CLAUDE_CODE_USE_BEDROCK is set', () => { test('returns "bedrock" when CLAUDE_CODE_USE_BEDROCK is set', () => {

View File

@@ -12,7 +12,7 @@ export const CLAUDE_3_7_SONNET_CONFIG = {
vertex: 'claude-3-7-sonnet@20250219', vertex: 'claude-3-7-sonnet@20250219',
foundry: 'claude-3-7-sonnet', foundry: 'claude-3-7-sonnet',
openai: 'claude-3-7-sonnet-20250219', openai: 'claude-3-7-sonnet-20250219',
'openai-responses': 'claude-3-7-sonnet-20250219', 'codex': 'claude-3-7-sonnet-20250219',
gemini: 'claude-3-7-sonnet-20250219', gemini: 'claude-3-7-sonnet-20250219',
grok: 'claude-3-7-sonnet-20250219', grok: 'claude-3-7-sonnet-20250219',
} as const satisfies ModelConfig } as const satisfies ModelConfig
@@ -23,7 +23,7 @@ export const CLAUDE_3_5_V2_SONNET_CONFIG = {
vertex: 'claude-3-5-sonnet-v2@20241022', vertex: 'claude-3-5-sonnet-v2@20241022',
foundry: 'claude-3-5-sonnet', foundry: 'claude-3-5-sonnet',
openai: 'claude-3-5-sonnet-20241022', openai: 'claude-3-5-sonnet-20241022',
'openai-responses': 'claude-3-5-sonnet-20241022', 'codex': 'claude-3-5-sonnet-20241022',
gemini: 'claude-3-5-sonnet-20241022', gemini: 'claude-3-5-sonnet-20241022',
grok: 'claude-3-5-sonnet-20241022', grok: 'claude-3-5-sonnet-20241022',
} as const satisfies ModelConfig } as const satisfies ModelConfig
@@ -34,7 +34,7 @@ export const CLAUDE_3_5_HAIKU_CONFIG = {
vertex: 'claude-3-5-haiku@20241022', vertex: 'claude-3-5-haiku@20241022',
foundry: 'claude-3-5-haiku', foundry: 'claude-3-5-haiku',
openai: 'claude-3-5-haiku-20241022', openai: 'claude-3-5-haiku-20241022',
'openai-responses': 'claude-3-5-haiku-20241022', 'codex': 'claude-3-5-haiku-20241022',
gemini: 'claude-3-5-haiku-20241022', gemini: 'claude-3-5-haiku-20241022',
grok: 'claude-3-5-haiku-20241022', grok: 'claude-3-5-haiku-20241022',
} as const satisfies ModelConfig } as const satisfies ModelConfig
@@ -45,7 +45,7 @@ export const CLAUDE_HAIKU_4_5_CONFIG = {
vertex: 'claude-haiku-4-5@20251001', vertex: 'claude-haiku-4-5@20251001',
foundry: 'claude-haiku-4-5', foundry: 'claude-haiku-4-5',
openai: 'claude-haiku-4-5-20251001', openai: 'claude-haiku-4-5-20251001',
'openai-responses': 'claude-haiku-4-5-20251001', 'codex': 'claude-haiku-4-5-20251001',
gemini: 'claude-haiku-4-5-20251001', gemini: 'claude-haiku-4-5-20251001',
grok: 'claude-haiku-4-5-20251001', grok: 'claude-haiku-4-5-20251001',
} as const satisfies ModelConfig } as const satisfies ModelConfig
@@ -56,7 +56,7 @@ export const CLAUDE_SONNET_4_CONFIG = {
vertex: 'claude-sonnet-4@20250514', vertex: 'claude-sonnet-4@20250514',
foundry: 'claude-sonnet-4', foundry: 'claude-sonnet-4',
openai: 'claude-sonnet-4-20250514', openai: 'claude-sonnet-4-20250514',
'openai-responses': 'claude-sonnet-4-20250514', 'codex': 'claude-sonnet-4-20250514',
gemini: 'claude-sonnet-4-20250514', gemini: 'claude-sonnet-4-20250514',
grok: 'claude-sonnet-4-20250514', grok: 'claude-sonnet-4-20250514',
} as const satisfies ModelConfig } as const satisfies ModelConfig
@@ -67,7 +67,7 @@ export const CLAUDE_SONNET_4_5_CONFIG = {
vertex: 'claude-sonnet-4-5@20250929', vertex: 'claude-sonnet-4-5@20250929',
foundry: 'claude-sonnet-4-5', foundry: 'claude-sonnet-4-5',
openai: 'claude-sonnet-4-5-20250929', openai: 'claude-sonnet-4-5-20250929',
'openai-responses': 'claude-sonnet-4-5-20250929', 'codex': 'claude-sonnet-4-5-20250929',
gemini: 'claude-sonnet-4-5-20250929', gemini: 'claude-sonnet-4-5-20250929',
grok: 'claude-sonnet-4-5-20250929', grok: 'claude-sonnet-4-5-20250929',
} as const satisfies ModelConfig } as const satisfies ModelConfig
@@ -78,7 +78,7 @@ export const CLAUDE_OPUS_4_CONFIG = {
vertex: 'claude-opus-4@20250514', vertex: 'claude-opus-4@20250514',
foundry: 'claude-opus-4', foundry: 'claude-opus-4',
openai: 'claude-opus-4-20250514', openai: 'claude-opus-4-20250514',
'openai-responses': 'claude-opus-4-20250514', 'codex': 'claude-opus-4-20250514',
gemini: 'claude-opus-4-20250514', gemini: 'claude-opus-4-20250514',
grok: 'claude-opus-4-20250514', grok: 'claude-opus-4-20250514',
} as const satisfies ModelConfig } as const satisfies ModelConfig
@@ -89,7 +89,7 @@ export const CLAUDE_OPUS_4_1_CONFIG = {
vertex: 'claude-opus-4-1@20250805', vertex: 'claude-opus-4-1@20250805',
foundry: 'claude-opus-4-1', foundry: 'claude-opus-4-1',
openai: 'claude-opus-4-1-20250805', openai: 'claude-opus-4-1-20250805',
'openai-responses': 'claude-opus-4-1-20250805', 'codex': 'claude-opus-4-1-20250805',
gemini: 'claude-opus-4-1-20250805', gemini: 'claude-opus-4-1-20250805',
grok: 'claude-opus-4-1-20250805', grok: 'claude-opus-4-1-20250805',
} as const satisfies ModelConfig } as const satisfies ModelConfig
@@ -100,7 +100,7 @@ export const CLAUDE_OPUS_4_5_CONFIG = {
vertex: 'claude-opus-4-5@20251101', vertex: 'claude-opus-4-5@20251101',
foundry: 'claude-opus-4-5', foundry: 'claude-opus-4-5',
openai: 'claude-opus-4-5-20251101', openai: 'claude-opus-4-5-20251101',
'openai-responses': 'claude-opus-4-5-20251101', 'codex': 'claude-opus-4-5-20251101',
gemini: 'claude-opus-4-5-20251101', gemini: 'claude-opus-4-5-20251101',
grok: 'claude-opus-4-5-20251101', grok: 'claude-opus-4-5-20251101',
} as const satisfies ModelConfig } as const satisfies ModelConfig
@@ -111,7 +111,7 @@ export const CLAUDE_OPUS_4_6_CONFIG = {
vertex: 'claude-opus-4-6', vertex: 'claude-opus-4-6',
foundry: 'claude-opus-4-6', foundry: 'claude-opus-4-6',
openai: 'claude-opus-4-6', openai: 'claude-opus-4-6',
'openai-responses': 'claude-opus-4-6', 'codex': 'claude-opus-4-6',
gemini: 'claude-opus-4-6', gemini: 'claude-opus-4-6',
grok: 'claude-opus-4-6', grok: 'claude-opus-4-6',
} as const satisfies ModelConfig } as const satisfies ModelConfig
@@ -122,7 +122,7 @@ export const CLAUDE_OPUS_4_7_CONFIG = {
vertex: 'claude-opus-4-7', vertex: 'claude-opus-4-7',
foundry: 'claude-opus-4-7', foundry: 'claude-opus-4-7',
openai: 'claude-opus-4-7', openai: 'claude-opus-4-7',
'openai-responses': 'claude-opus-4-7', 'codex': 'claude-opus-4-7',
gemini: 'claude-opus-4-7', gemini: 'claude-opus-4-7',
grok: 'claude-opus-4-7', grok: 'claude-opus-4-7',
} as const satisfies ModelConfig } as const satisfies ModelConfig
@@ -133,7 +133,7 @@ export const CLAUDE_SONNET_4_6_CONFIG = {
vertex: 'claude-sonnet-4-6', vertex: 'claude-sonnet-4-6',
foundry: 'claude-sonnet-4-6', foundry: 'claude-sonnet-4-6',
openai: 'claude-sonnet-4-6', openai: 'claude-sonnet-4-6',
'openai-responses': 'claude-sonnet-4-6', 'codex': 'claude-sonnet-4-6',
gemini: 'claude-sonnet-4-6', gemini: 'claude-sonnet-4-6',
grok: 'claude-sonnet-4-6', grok: 'claude-sonnet-4-6',
} as const satisfies ModelConfig } as const satisfies ModelConfig

View File

@@ -8,14 +8,14 @@ export type APIProvider =
| 'vertex' | 'vertex'
| 'foundry' | 'foundry'
| 'openai' | 'openai'
| 'openai-responses' | 'codex'
| 'gemini' | 'gemini'
| 'grok' | 'grok'
export function getAPIProvider(): APIProvider { export function getAPIProvider(): APIProvider {
const modelType = getInitialSettings().modelType const modelType = getInitialSettings().modelType
if (modelType === 'openai') return 'openai' if (modelType === 'openai') return 'openai'
if (modelType === 'openai-responses') return 'openai-responses' if (modelType === 'codex') return 'codex'
if (modelType === 'gemini') return 'gemini' if (modelType === 'gemini') return 'gemini'
if (modelType === 'grok') return 'grok' if (modelType === 'grok') return 'grok'
@@ -24,7 +24,7 @@ export function getAPIProvider(): APIProvider {
if (isEnvTruthy(process.env.CLAUDE_CODE_USE_FOUNDRY)) return 'foundry' 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_OPENAI)) return 'openai'
if (isEnvTruthy(process.env.CLAUDE_CODE_USE_CODEX)) return 'openai-responses' 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_GEMINI)) return 'gemini'
if (isEnvTruthy(process.env.CLAUDE_CODE_USE_GROK)) return 'grok' if (isEnvTruthy(process.env.CLAUDE_CODE_USE_GROK)) return 'grok'

View File

@@ -482,9 +482,9 @@ describe("gemini settings", () => {
}); });
}); });
describe("openai-responses settings", () => { describe("codex settings", () => {
test("accepts openai-responses modelType", () => { test("accepts codex modelType", () => {
const result = SettingsSchema().safeParse({ modelType: "openai-responses" }); const result = SettingsSchema().safeParse({ modelType: "codex" });
expect(result.success).toBe(true); expect(result.success).toBe(true);
}); });
}); });

View File

@@ -369,11 +369,11 @@ export const SettingsSchema = lazySchema(() =>
.optional() .optional()
.describe('Tool usage permissions configuration'), .describe('Tool usage permissions configuration'),
modelType: z modelType: z
.enum(['anthropic', 'openai', 'openai-responses', 'gemini', 'grok']) .enum(['anthropic', 'openai', 'codex', 'gemini', 'grok'])
.optional() .optional()
.describe( .describe(
'API provider type. "anthropic" uses the Anthropic API (default), "openai" uses the OpenAI Chat Completions API, "openai-responses" uses the OpenAI Responses API, "gemini" uses the Gemini API, and "grok" uses the xAI Grok API (OpenAI-compatible). ' + 'API provider type. "anthropic" uses the Anthropic API (default), "openai" uses the OpenAI Chat Completions API, "codex" uses the OpenAI Responses API, "gemini" uses the Gemini API, and "grok" uses the xAI Grok API (OpenAI-compatible). ' +
'When set to "openai", configure OPENAI_API_KEY, OPENAI_BASE_URL, and OPENAI_MODEL. When set to "openai-responses", configure CODEX_API_KEY, CODEX_BASE_URL, and CODEX_MODEL. When set to "gemini", configure GEMINI_API_KEY and optional GEMINI_BASE_URL. When set to "grok", configure GROK_API_KEY (or XAI_API_KEY), optional GROK_BASE_URL, GROK_MODEL, and GROK_MODEL_MAP.', 'When set to "openai", configure OPENAI_API_KEY, OPENAI_BASE_URL, and OPENAI_MODEL. When set to "codex", configure CODEX_API_KEY, CODEX_BASE_URL, and CODEX_MODEL. When set to "gemini", configure GEMINI_API_KEY and optional GEMINI_BASE_URL. When set to "grok", configure GROK_API_KEY (or XAI_API_KEY), optional GROK_BASE_URL, GROK_MODEL, and GROK_MODEL_MAP.',
), ),
model: z model: z
.string() .string()

View File

@@ -342,7 +342,7 @@ export function buildAPIProviderProperties(): Property[] {
gemini: 'Gemini API', gemini: 'Gemini API',
grok: 'Grok API', grok: 'Grok API',
openai: 'OpenAI API', openai: 'OpenAI API',
'openai-responses': 'OpenAI Responses API', 'codex': 'OpenAI Responses API',
}[apiProvider] }[apiProvider]
properties.push({ properties.push({
label: 'API provider', label: 'API provider',
@@ -445,7 +445,7 @@ export function buildAPIProviderProperties(): Property[] {
label: 'OpenAI base URL', label: 'OpenAI base URL',
value: openaiBaseUrl, value: openaiBaseUrl,
}) })
} else if (apiProvider === 'openai-responses') { } else if (apiProvider === 'codex') {
const codexBaseUrl = process.env.CODEX_BASE_URL const codexBaseUrl = process.env.CODEX_BASE_URL
properties.push({ properties.push({
label: 'OpenAI Responses base URL', label: 'OpenAI Responses base URL',