From 7f9f5514a421d1a4a410a5d80f0585474d9010fd Mon Sep 17 00:00:00 2001 From: beyondkmp Date: Mon, 15 Sep 2025 17:32:40 +0800 Subject: [PATCH] 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. --- src/main/services/CodeToolsService.ts | 18 ++++++++++++++++++ src/renderer/src/pages/code/CodeToolsPage.tsx | 19 +++++++++++++------ src/renderer/src/pages/code/index.ts | 9 ++++++++- 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/main/services/CodeToolsService.ts b/src/main/services/CodeToolsService.ts index 12da4896be..6e3bb19022 100644 --- a/src/main/services/CodeToolsService.ts +++ b/src/main/services/CodeToolsService.ts @@ -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) { diff --git a/src/renderer/src/pages/code/CodeToolsPage.tsx b/src/renderer/src/pages/code/CodeToolsPage.tsx index bee260efa5..4dc0f287cf 100644 --- a/src/renderer/src/pages/code/CodeToolsPage.tsx +++ b/src/renderer/src/pages/code/CodeToolsPage.tsx @@ -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) => { - 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) diff --git a/src/renderer/src/pages/code/index.ts b/src/renderer/src/pages/code/index.ts index 99e311bdbc..2c36da3ec6 100644 --- a/src/renderer/src/pages/code/index.ts +++ b/src/renderer/src/pages/code/index.ts @@ -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 Provider[]> = { @@ -33,7 +34,8 @@ export const CLI_TOOL_PROVIDER_MAP: Record 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 }