feat(CodeTools): enhance OpenAI Codex integration with configurable parameters (#10180)

* feat(CodeTools): enhance OpenAI Codex integration with configurable parameters

- Added support for custom OpenAI model provider and model configuration in CodeToolsService.
- Updated CodeToolsPage to filter providers based on the selected CLI tool, including OpenAI Codex.
- Introduced OPENAI_CODEX_SUPPORTED_PROVIDERS constant for better provider management.
- Refactored environment variable generation to include OpenAI-specific settings.

* fix(CodeTools): correct environment variable generation for OpenAI Codex integration

- Added a break statement in the environment generation logic for OpenAI Codex to ensure proper handling of API key and base URL.
- Moved the import of codeTools to maintain consistency in the CodeToolsPage component.
This commit is contained in:
beyondkmp 2025-09-15 17:32:40 +08:00 committed by GitHub
parent d5487ba6ac
commit 7f9f5514a4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 39 additions and 7 deletions

View File

@ -308,6 +308,24 @@ class CodeToolsService {
// Build command to execute
let baseCommand = isWin ? `"${executablePath}"` : `"${bunPath}" "${executablePath}"`
// Add configuration parameters for OpenAI Codex
if (cliTool === codeTools.openaiCodex && env.OPENAI_MODEL_PROVIDER && env.OPENAI_MODEL_PROVIDER != 'openai') {
const provider = env.OPENAI_MODEL_PROVIDER
const model = env.OPENAI_MODEL
// delete the latest /
const baseUrl = env.OPENAI_BASE_URL.replace(/\/$/, '')
const configParams = [
`--config model_provider="${provider}"`,
`--config model="${model}"`,
`--config model_providers.${provider}.name="${provider}"`,
`--config model_providers.${provider}.base_url="${baseUrl}"`,
`--config model_providers.${provider}.env_key="OPENAI_API_KEY"`
].join(' ')
baseCommand = `${baseCommand} ${configParams}`
}
const bunInstallPath = path.join(os.homedir(), '.cherrystudio')
if (isInstalled) {

View File

@ -13,6 +13,7 @@ import { getModelUniqId } from '@renderer/services/ModelService'
import { useAppDispatch, useAppSelector } from '@renderer/store'
import { setIsBunInstalled } from '@renderer/store/mcp'
import { Model } from '@renderer/types'
import { codeTools } from '@shared/config/constant'
import { Alert, Avatar, Button, Checkbox, Input, Popover, Select, Space } from 'antd'
import { ArrowUpRight, Download, HelpCircle, Terminal, X } from 'lucide-react'
import { FC, useCallback, useEffect, useMemo, useState } from 'react'
@ -26,6 +27,7 @@ import {
CLI_TOOLS,
generateToolEnvironment,
getClaudeSupportedProviders,
OPENAI_CODEX_SUPPORTED_PROVIDERS,
parseEnvironmentVariables
} from '.'
@ -65,12 +67,15 @@ const CodeToolsPage: FC = () => {
if (m.provider === 'cherryin') {
return false
}
if (selectedCliTool === 'claude-code') {
if (selectedCliTool === codeTools.claudeCode) {
return m.id.includes('claude') || CLAUDE_OFFICIAL_SUPPORTED_PROVIDERS.includes(m.provider)
}
if (selectedCliTool === 'gemini-cli') {
if (selectedCliTool === codeTools.geminiCli) {
return m.id.includes('gemini')
}
if (selectedCliTool === codeTools.openaiCodex) {
return m.id.includes('openai') || OPENAI_CODEX_SUPPORTED_PROVIDERS.includes(m.provider)
}
return true
},
[selectedCliTool]
@ -153,8 +158,8 @@ const CodeToolsPage: FC = () => {
const modelProvider = getProviderByModel(selectedModel)
const aiProvider = new AiProvider(modelProvider)
const baseUrl = await aiProvider.getBaseURL()
const apiKey = await aiProvider.getApiKey()
const baseUrl = aiProvider.getBaseURL()
const apiKey = aiProvider.getApiKey()
// 生成工具特定的环境变量
const toolEnv = generateToolEnvironment({
@ -173,7 +178,9 @@ const CodeToolsPage: FC = () => {
// 执行启动操作
const executeLaunch = async (env: Record<string, string>) => {
window.api.codeTools.run(selectedCliTool, selectedModel?.id!, currentDirectory, env, { autoUpdateToLatest })
window.api.codeTools.run(selectedCliTool, selectedModel?.id!, currentDirectory, env, {
autoUpdateToLatest
})
window.toast.success(t('code.launch.success'))
}
@ -197,7 +204,7 @@ const CodeToolsPage: FC = () => {
await executeLaunch(env)
} catch (error) {
logger.error('启动失败:', error as Error)
logger.error('start code tools failed:', error as Error)
window.toast.error(t('code.launch.error'))
} finally {
setIsLaunching(false)

View File

@ -25,6 +25,7 @@ export const CLI_TOOLS = [
export const GEMINI_SUPPORTED_PROVIDERS = ['aihubmix', 'dmxapi', 'new-api']
export const CLAUDE_OFFICIAL_SUPPORTED_PROVIDERS = ['deepseek', 'moonshot', 'zhipu', 'dashscope', 'modelscope']
export const CLAUDE_SUPPORTED_PROVIDERS = ['aihubmix', 'dmxapi', 'new-api', ...CLAUDE_OFFICIAL_SUPPORTED_PROVIDERS]
export const OPENAI_CODEX_SUPPORTED_PROVIDERS = ['openai', 'openrouter', 'aihubmix', 'new-api']
// Provider 过滤映射
export const CLI_TOOL_PROVIDER_MAP: Record<string, (providers: Provider[]) => Provider[]> = {
@ -33,7 +34,8 @@ export const CLI_TOOL_PROVIDER_MAP: Record<string, (providers: Provider[]) => Pr
[codeTools.geminiCli]: (providers) =>
providers.filter((p) => p.type === 'gemini' || GEMINI_SUPPORTED_PROVIDERS.includes(p.id)),
[codeTools.qwenCode]: (providers) => providers.filter((p) => p.type.includes('openai')),
[codeTools.openaiCodex]: (providers) => providers.filter((p) => p.id === 'openai')
[codeTools.openaiCodex]: (providers) =>
providers.filter((p) => p.id === 'openai' || OPENAI_CODEX_SUPPORTED_PROVIDERS.includes(p.id))
}
export const getCodeToolsApiBaseUrl = (model: Model, type: EndpointType) => {
@ -132,10 +134,15 @@ export const generateToolEnvironment = ({
}
case codeTools.qwenCode:
env.OPENAI_API_KEY = apiKey
env.OPENAI_BASE_URL = baseUrl
env.OPENAI_MODEL = model.id
break
case codeTools.openaiCodex:
env.OPENAI_API_KEY = apiKey
env.OPENAI_BASE_URL = baseUrl
env.OPENAI_MODEL = model.id
env.OPENAI_MODEL_PROVIDER = modelProvider.id
break
}