修复codex

This commit is contained in:
Yoahoug 2026-01-25 23:09:45 +08:00
parent 2f2d0de8b4
commit cd15a3a637
3 changed files with 43 additions and 30 deletions

View file

@ -61,7 +61,7 @@ export class CodexConverter extends BaseConverter {
effort: 'medium', effort: 'medium',
summary: 'auto' summary: 'auto'
}, },
parallel_tool_calls: data.parallel_tool_calls !== false, parallel_tool_calls: true,
include: ['reasoning.encrypted_content'] include: ['reasoning.encrypted_content']
}; };
@ -83,16 +83,10 @@ export class CodexConverter extends BaseConverter {
codexRequest.reasoning.effort = data.reasoning_effort; codexRequest.reasoning.effort = data.reasoning_effort;
} }
// 添加温度和其他参数 /*
if (data.temperature !== undefined) { Codex doesn't support temperature, top_p, top_k, max_tokens anymore in the new protocol.
codexRequest.temperature = data.temperature; Removed mapping for these fields.
} */
if (data.max_tokens !== undefined) {
codexRequest.max_output_tokens = data.max_tokens;
}
if (data.top_p !== undefined) {
codexRequest.top_p = data.top_p;
}
return codexRequest; return codexRequest;
} }

View file

@ -7,6 +7,7 @@ import os from 'os';
import { refreshCodexTokensWithRetry } from '../../auth/oauth-handlers.js'; import { refreshCodexTokensWithRetry } from '../../auth/oauth-handlers.js';
import { getProviderPoolManager } from '../../services/service-manager.js'; import { getProviderPoolManager } from '../../services/service-manager.js';
import { MODEL_PROVIDER, formatExpiryLog } from '../../utils/common.js'; import { MODEL_PROVIDER, formatExpiryLog } from '../../utils/common.js';
import { getProxyConfigForProvider } from '../../utils/proxy-utils.js';
/** /**
* Codex API 服务类 * Codex API 服务类
@ -77,10 +78,10 @@ export class CodexApiService {
creds = JSON.parse(await fs.readFile(credsPath, 'utf8')); creds = JSON.parse(await fs.readFile(credsPath, 'utf8'));
} }
this.accessToken = creds.access_token; this.accessToken = creds.access_token;
this.refreshToken = creds.refresh_token; this.refreshToken = creds.refresh_token;
this.accountId = creds.account_id; this.accountId = creds.account_id;
this.email = creds.email; this.email = creds.email;
this.expiresAt = new Date(creds.expired); // 注意:字段名是 expired this.expiresAt = new Date(creds.expired); // 注意:字段名是 expired
// 检查 token 是否需要刷新 // 检查 token 是否需要刷新
@ -117,7 +118,7 @@ export class CodexApiService {
} }
logger.info('[Codex] Token expiring soon or refresh requested, refreshing...'); logger.info('[Codex] Token expiring soon or refresh requested, refreshing...');
await this.refreshAccessToken(); await this.refreshAccessToken();
// 刷新成功,重置 PoolManager 中的刷新状态并标记为健康 // 刷新成功,重置 PoolManager 中的刷新状态并标记为健康
const poolManager = getProviderPoolManager(); const poolManager = getProviderPoolManager();
if (poolManager && this.uuid) { if (poolManager && this.uuid) {
@ -150,16 +151,25 @@ export class CodexApiService {
const headers = this.buildHeaders(body.prompt_cache_key); const headers = this.buildHeaders(body.prompt_cache_key);
try { try {
const response = await axios.post(url, body, { const config = {
headers, headers,
timeout: 120000 // 2 分钟超时 timeout: 120000 // 2 分钟超时
}); };
// 配置代理
const proxyConfig = getProxyConfigForProvider(this.config, 'codex');
if (proxyConfig) {
config.httpAgent = proxyConfig.httpAgent;
config.httpsAgent = proxyConfig.httpsAgent;
}
const response = await axios.post(url, body, config);
return this.parseNonStreamResponse(response.data); return this.parseNonStreamResponse(response.data);
} catch (error) { } catch (error) {
if (error.response?.status === 401) { if (error.response?.status === 401) {
logger.info('[Codex] Received 401. Triggering background refresh via PoolManager...'); logger.info('[Codex] Received 401. Triggering background refresh via PoolManager...');
// 标记当前凭证为不健康(会自动进入刷新队列) // 标记当前凭证为不健康(会自动进入刷新队列)
const poolManager = getProviderPoolManager(); const poolManager = getProviderPoolManager();
if (poolManager && this.uuid) { if (poolManager && this.uuid) {
@ -203,17 +213,26 @@ export class CodexApiService {
const headers = this.buildHeaders(body.prompt_cache_key); const headers = this.buildHeaders(body.prompt_cache_key);
try { try {
const response = await axios.post(url, body, { const config = {
headers, headers,
responseType: 'stream', responseType: 'stream',
timeout: 120000 timeout: 120000
}); };
// 配置代理
const proxyConfig = getProxyConfigForProvider(this.config, 'codex');
if (proxyConfig) {
config.httpAgent = proxyConfig.httpAgent;
config.httpsAgent = proxyConfig.httpsAgent;
}
const response = await axios.post(url, body, config);
yield* this.parseSSEStream(response.data); yield* this.parseSSEStream(response.data);
} catch (error) { } catch (error) {
if (error.response?.status === 401) { if (error.response?.status === 401) {
logger.info('[Codex] Received 401 during stream. Triggering background refresh via PoolManager...'); logger.info('[Codex] Received 401 during stream. Triggering background refresh via PoolManager...');
// 标记当前凭证为不健康 // 标记当前凭证为不健康
const poolManager = getProviderPoolManager(); const poolManager = getProviderPoolManager();
if (poolManager && this.uuid) { if (poolManager && this.uuid) {

View file

@ -62,12 +62,12 @@ export function isProxyEnabledForProvider(config, providerType) {
if (!config || !config.PROXY_URL || !config.PROXY_ENABLED_PROVIDERS) { if (!config || !config.PROXY_URL || !config.PROXY_ENABLED_PROVIDERS) {
return false; return false;
} }
const enabledProviders = config.PROXY_ENABLED_PROVIDERS; const enabledProviders = config.PROXY_ENABLED_PROVIDERS;
if (!Array.isArray(enabledProviders)) { if (!Array.isArray(enabledProviders)) {
return false; return false;
} }
return enabledProviders.includes(providerType); return enabledProviders.includes(providerType);
} }
@ -81,10 +81,10 @@ export function getProxyConfigForProvider(config, providerType) {
if (!isProxyEnabledForProvider(config, providerType)) { if (!isProxyEnabledForProvider(config, providerType)) {
return null; return null;
} }
const proxyConfig = parseProxyUrl(config.PROXY_URL); const proxyConfig = parseProxyUrl(config.PROXY_URL);
if (proxyConfig) { if (proxyConfig) {
logger.info(`[Proxy] Using ${proxyConfig.proxyType} proxy for ${providerType}: ${config.PROXY_URL}`); // logger.info(`[Proxy] Using ${proxyConfig.proxyType} proxy for ${providerType}: ${config.PROXY_URL}`);
} }
return proxyConfig; return proxyConfig;
} }
@ -98,7 +98,7 @@ export function getProxyConfigForProvider(config, providerType) {
*/ */
export function configureAxiosProxy(axiosConfig, config, providerType) { export function configureAxiosProxy(axiosConfig, config, providerType) {
const proxyConfig = getProxyConfigForProvider(config, providerType); const proxyConfig = getProxyConfigForProvider(config, providerType);
if (proxyConfig) { if (proxyConfig) {
// 使用代理 agent // 使用代理 agent
axiosConfig.httpAgent = proxyConfig.httpAgent; axiosConfig.httpAgent = proxyConfig.httpAgent;
@ -106,7 +106,7 @@ export function configureAxiosProxy(axiosConfig, config, providerType) {
// 禁用 axios 内置的代理配置,使用我们的 agent // 禁用 axios 内置的代理配置,使用我们的 agent
axiosConfig.proxy = false; axiosConfig.proxy = false;
} }
return axiosConfig; return axiosConfig;
} }
@ -118,12 +118,12 @@ export function configureAxiosProxy(axiosConfig, config, providerType) {
*/ */
export function getGoogleAuthProxyConfig(config, providerType) { export function getGoogleAuthProxyConfig(config, providerType) {
const proxyConfig = getProxyConfigForProvider(config, providerType); const proxyConfig = getProxyConfigForProvider(config, providerType);
if (proxyConfig) { if (proxyConfig) {
return { return {
agent: proxyConfig.httpsAgent agent: proxyConfig.httpsAgent
}; };
} }
return null; return null;
} }