diff --git a/frontend/src/components/keys/UseKeyModal.vue b/frontend/src/components/keys/UseKeyModal.vue
index 87983f94cc..726b01b60c 100644
--- a/frontend/src/components/keys/UseKeyModal.vue
+++ b/frontend/src/components/keys/UseKeyModal.vue
@@ -563,35 +563,29 @@ name = "OpenAI"
base_url = "${baseUrl}"
wire_api = "responses"
requires_openai_auth = false
-env_key = "SUB2API_API_KEY"
http_headers = { "x-openai-actor-authorization" = "local-image-extension" }
[features]
-image_generation = true
goals = true`
+ // auth.json content
+ const authContent = `{
+ "OPENAI_API_KEY": "${apiKey}"
+}`
+
return [
{
path: `${configDir}/config.toml`,
content: configContent,
hint: t('keys.useKeyModal.openai.configTomlHint')
},
- generateCodexAPIKeyEnvironment(apiKey, isWindows)
+ {
+ path: `${configDir}/auth.json`,
+ content: authContent
+ }
]
}
-function generateCodexAPIKeyEnvironment(apiKey: string, isWindows: boolean): FileConfig {
- return isWindows
- ? {
- path: 'PowerShell',
- content: `$env:SUB2API_API_KEY="${apiKey}"`
- }
- : {
- path: 'Terminal',
- content: `export SUB2API_API_KEY="${apiKey}"`
- }
-}
-
function generateGrokFiles(baseUrl: string, apiKey: string): FileConfig[] {
const isWindows = activeTab.value === 'windows'
const configDir = isWindows ? '%userprofile%\\.grok' : '~/.grok'
@@ -620,7 +614,7 @@ function generateOpenAIWsFiles(baseUrl: string, apiKey: string): FileConfig[] {
const isWindows = activeTab.value === 'windows'
const configDir = isWindows ? '%userprofile%\\.codex' : '~/.codex'
- // config.toml content with the Responses WebSocket transport enabled
+ // config.toml content with WebSocket v2
const configContent = `model_provider = "OpenAI"
model = "gpt-5.5"
review_model = "gpt-5.5"
@@ -635,20 +629,27 @@ base_url = "${baseUrl}"
wire_api = "responses"
supports_websockets = true
requires_openai_auth = false
-env_key = "SUB2API_API_KEY"
http_headers = { "x-openai-actor-authorization" = "local-image-extension" }
[features]
-image_generation = true
+responses_websockets_v2 = true
goals = true`
+ // auth.json content
+ const authContent = `{
+ "OPENAI_API_KEY": "${apiKey}"
+}`
+
return [
{
path: `${configDir}/config.toml`,
content: configContent,
hint: t('keys.useKeyModal.openai.configTomlHint')
},
- generateCodexAPIKeyEnvironment(apiKey, isWindows)
+ {
+ path: `${configDir}/auth.json`,
+ content: authContent
+ }
]
}
diff --git a/frontend/src/components/keys/__tests__/UseKeyModal.spec.ts b/frontend/src/components/keys/__tests__/UseKeyModal.spec.ts
index 4e216de8da..da890f3d0e 100644
--- a/frontend/src/components/keys/__tests__/UseKeyModal.spec.ts
+++ b/frontend/src/components/keys/__tests__/UseKeyModal.spec.ts
@@ -78,7 +78,7 @@ describe('UseKeyModal', () => {
expect(parsed.provider.grok.models['gpt-5.6']).toBeUndefined()
})
- it('renders API key mode and local image generation in OpenAI Codex config', () => {
+ it('renders minimal image executor authorization in OpenAI Codex config', () => {
const wrapper = mount(UseKeyModal, {
props: {
show: true,
@@ -108,16 +108,17 @@ describe('UseKeyModal', () => {
expect(configToml).not.toContain('model_context_window')
expect(configToml).not.toContain('model_auto_compact_token_limit')
expect(configToml).toContain('requires_openai_auth = false')
- expect(configToml).toContain('env_key = "SUB2API_API_KEY"')
expect(configToml).toContain('http_headers = { "x-openai-actor-authorization" = "local-image-extension" }')
+ expect(configToml).not.toContain('env_key')
+ expect(configToml).not.toContain('image_generation')
expect(configToml).not.toContain('supports_websockets')
expect(configToml).not.toContain('responses_websockets_v2')
- expect(configToml).toContain('[features]\nimage_generation = true\ngoals = true')
- expect(codeBlocks).toContain('export SUB2API_API_KEY="sk-test"')
- expect(wrapper.text()).not.toContain('auth.json')
+ expect(configToml).toContain('[features]\ngoals = true')
+ expect(codeBlocks).toContain('{\n "OPENAI_API_KEY": "sk-test"\n}')
+ expect(wrapper.text()).toContain('auth.json')
})
- it('renders API key mode and current WebSocket settings in OpenAI Codex config', async () => {
+ it('renders minimal image executor authorization in OpenAI Codex WebSocket config', async () => {
const wrapper = mount(UseKeyModal, {
props: {
show: true,
@@ -155,46 +156,13 @@ describe('UseKeyModal', () => {
expect(configToml).not.toContain('model_context_window')
expect(configToml).not.toContain('model_auto_compact_token_limit')
expect(configToml).toContain('requires_openai_auth = false')
- expect(configToml).toContain('env_key = "SUB2API_API_KEY"')
expect(configToml).toContain('http_headers = { "x-openai-actor-authorization" = "local-image-extension" }')
+ expect(configToml).not.toContain('env_key')
+ expect(configToml).not.toContain('image_generation')
expect(configToml).toContain('supports_websockets = true')
- expect(configToml).not.toContain('responses_websockets_v2')
- expect(configToml).toContain('[features]\nimage_generation = true\ngoals = true')
- expect(codeBlocks).toContain('export SUB2API_API_KEY="sk-test"')
- expect(wrapper.text()).not.toContain('auth.json')
- })
-
- it('renders a PowerShell API key command for Codex on Windows', async () => {
- const wrapper = mount(UseKeyModal, {
- props: {
- show: true,
- apiKey: 'sk-test',
- baseUrl: 'https://example.com/v1',
- platform: 'openai'
- },
- global: {
- stubs: {
- BaseDialog: {
- template: '
'
- },
- Icon: {
- template: ''
- }
- }
- }
- })
-
- const windowsTab = wrapper.findAll('button').find(
- (button) => button.text().trim() === 'Windows'
- )
-
- expect(windowsTab).toBeDefined()
- await windowsTab!.trigger('click')
- await nextTick()
-
- const codeBlocks = wrapper.findAll('pre code').map((code) => code.text())
- expect(codeBlocks).toContain('$env:SUB2API_API_KEY="sk-test"')
- expect(wrapper.text()).not.toContain('auth.json')
+ expect(configToml).toContain('[features]\nresponses_websockets_v2 = true\ngoals = true')
+ expect(codeBlocks).toContain('{\n "OPENAI_API_KEY": "sk-test"\n}')
+ expect(wrapper.text()).toContain('auth.json')
})
it('renders GPT-5.4 mini entry in OpenCode config', async () => {
diff --git a/frontend/src/i18n/locales/en/admin/channels.ts b/frontend/src/i18n/locales/en/admin/channels.ts
index eaeacc73b4..07a24d0fd5 100644
--- a/frontend/src/i18n/locales/en/admin/channels.ts
+++ b/frontend/src/i18n/locales/en/admin/channels.ts
@@ -155,7 +155,7 @@ export default {
webSearchEmulationHint: '⚠️ When enabled, all accounts in this channel\'s Anthropic groups will intercept web_search requests. Use with caution.',
webSearchEmulationGlobalDisabled: 'Please enable the global switch first in Settings → Gateway → Web Search Emulation',
codexImageGenerationBridge: 'Codex Image Generation Bridge',
- codexImageGenerationBridgeHint: 'Hosted image bridge for non-Responses Lite requests only. It may inject the image_generation tool into Codex /responses text requests; Responses Lite uses the client-side image executor instead.',
+ codexImageGenerationBridgeHint: 'When enabled, Codex /responses text requests in OpenAI groups may be automatically given the image_generation tool. Keep off unless the routed accounts support image generation.',
bedrockCCCompat: 'Bedrock CC Compatibility',
bedrockCCCompatHint: '⚠️ When enabled, requests to Bedrock accounts in this channel will be transformed for Claude Code compatibility (thinking type conversion, tool_use ID sanitization).',
basicSettings: 'Basic Settings',
diff --git a/frontend/src/i18n/locales/en/dashboard.ts b/frontend/src/i18n/locales/en/dashboard.ts
index 3d70935a05..816f6bd440 100644
--- a/frontend/src/i18n/locales/en/dashboard.ts
+++ b/frontend/src/i18n/locales/en/dashboard.ts
@@ -136,16 +136,16 @@ export default {
noGroupTitle: 'Please assign a group first',
noGroupDescription: 'This API key has not been assigned to a group. Please click the group column in the key list to assign one before viewing the configuration.',
openai: {
- description: 'Set SUB2API_API_KEY before starting Codex, then add the config.toml settings below. Responses Lite image generation uses Codex\'s local image executor; hosted force injection applies only to non-Responses Lite requests.',
+ description: 'Add the following configuration files to your Codex CLI config directory.',
configTomlHint: 'Make sure the following content is at the beginning of the config.toml file',
- note: 'Make sure ~/.codex exists, set the environment variable before Codex/Desktop starts, then fully restart the client and create a new thread so the image tool is registered.',
- noteWindows: 'Make sure %userprofile%\\.codex exists, set the environment variable before Codex/Desktop starts, then fully restart the client and create a new thread so the image tool is registered.',
+ note: 'Make sure the config directory exists. macOS/Linux users can run mkdir -p ~/.codex to create it.',
+ noteWindows: 'Press Win+R and enter %userprofile%\\.codex to open the config directory. Create it manually if it does not exist.',
},
cliTabs: {
claudeCode: 'Claude Code',
geminiCli: 'Gemini CLI',
- codexCli: 'Codex (API Key Mode)',
- codexCliWs: 'Codex (API Key Mode, WebSocket)',
+ codexCli: 'Codex CLI',
+ codexCliWs: 'Codex CLI (WebSocket)',
grokCli: 'Grok CLI',
opencode: 'OpenCode',
},
diff --git a/frontend/src/i18n/locales/zh/admin/channels.ts b/frontend/src/i18n/locales/zh/admin/channels.ts
index b0b3717f64..93890e25b0 100644
--- a/frontend/src/i18n/locales/zh/admin/channels.ts
+++ b/frontend/src/i18n/locales/zh/admin/channels.ts
@@ -155,7 +155,7 @@ export default {
webSearchEmulationHint: '⚠️ 开启后该渠道下所有 Anthropic 分组的账号将自动拦截 web_search 请求,请谨慎操作',
webSearchEmulationGlobalDisabled: '请先在系统设置 → 网关 → Web Search 模拟中启用全局开关',
codexImageGenerationBridge: 'Codex 图片生成桥接',
- codexImageGenerationBridgeHint: '仅用于非 Responses Lite 请求的服务端图片桥接,可向 Codex /responses 文本请求注入 image_generation 工具;Responses Lite 改用客户端图片执行器。',
+ codexImageGenerationBridgeHint: '开启后,OpenAI 分组的 Codex /responses 文本请求可能会被自动注入 image_generation 工具。仅在路由账号支持图片生成时开启。',
bedrockCCCompat: 'Bedrock CC 兼容',
bedrockCCCompatHint: '⚠️ 开启后,该渠道下 Bedrock 账号的请求将进行 Claude Code 兼容处理(thinking 类型转换、tool_use ID 清理)',
basicSettings: '基础设置',
diff --git a/frontend/src/i18n/locales/zh/dashboard.ts b/frontend/src/i18n/locales/zh/dashboard.ts
index 7472ec781c..a268919612 100644
--- a/frontend/src/i18n/locales/zh/dashboard.ts
+++ b/frontend/src/i18n/locales/zh/dashboard.ts
@@ -136,17 +136,17 @@ export default {
noGroupDescription:
'此 API 密钥尚未分配分组,请先在密钥列表中点击分组列进行分配,然后才能查看使用配置。',
openai: {
- description: '启动 Codex 前先设置 SUB2API_API_KEY,再添加以下 config.toml 配置。Responses Lite 生图使用 Codex 本地图片执行器;服务端强制注入仅用于非 Responses Lite 请求。',
+ description: '将以下配置文件添加到 Codex CLI 配置目录中。',
configTomlHint: '请确保以下内容位于 config.toml 文件的开头部分',
- note: '请确保 ~/.codex 目录存在,并在 Codex/Desktop 启动前设置环境变量;随后完全重启客户端并新建会话,以重新注册图片工具。',
+ note: '请确保配置目录存在。macOS/Linux 用户可运行 mkdir -p ~/.codex 创建目录。',
noteWindows:
- '请确保 %userprofile%\\.codex 目录存在,并在 Codex/Desktop 启动前设置环境变量;随后完全重启客户端并新建会话,以重新注册图片工具。'
+ '按 Win+R,输入 %userprofile%\\.codex 打开配置目录。如目录不存在,请先手动创建。'
},
cliTabs: {
claudeCode: 'Claude Code',
geminiCli: 'Gemini CLI',
- codexCli: 'Codex(API Key 模式)',
- codexCliWs: 'Codex(API Key 模式,WebSocket)',
+ codexCli: 'Codex CLI',
+ codexCliWs: 'Codex CLI (WebSocket)',
grokCli: 'Grok CLI',
opencode: 'OpenCode'
},