Merge pull request #146 from AAEE86/master

fix: Codex 端点 URL 使用 /responses 而非 /v1/responses
This commit is contained in:
fawney19
2026-02-05 11:15:08 +08:00
committed by GitHub
3 changed files with 31 additions and 5 deletions

View File

@@ -95,7 +95,7 @@
<Label class="text-xs text-muted-foreground">自定义路径</Label> <Label class="text-xs text-muted-foreground">自定义路径</Label>
<Input <Input
:model-value="getEndpointEditState(endpoint.id)?.path ?? (endpoint.custom_path || '')" :model-value="getEndpointEditState(endpoint.id)?.path ?? (endpoint.custom_path || '')"
:placeholder="getDefaultPath(endpoint.api_format) || '留空使用默认'" :placeholder="getDefaultPath(endpoint.api_format, endpoint.base_url) || '留空使用默认'"
:disabled="isFixedProvider" :disabled="isFixedProvider"
@update:model-value="(v) => updateEndpointField(endpoint.id, 'path', v)" @update:model-value="(v) => updateEndpointField(endpoint.id, 'path', v)"
/> />
@@ -673,9 +673,20 @@ const deleteConfirmDescription = computed(() => {
}) })
// 获取指定 API 格式的默认路径 // 获取指定 API 格式的默认路径
function getDefaultPath(apiFormat: string): string { function getDefaultPath(apiFormat: string, baseUrl?: string): string {
const format = apiFormats.value.find(f => f.value === apiFormat) const format = apiFormats.value.find(f => f.value === apiFormat)
return format?.default_path || '' const defaultPath = format?.default_path || ''
// Codex 端点使用 /responses 而非 /v1/responses
if (apiFormat === 'openai:cli' && baseUrl && isCodexUrl(baseUrl)) {
return '/responses'
}
return defaultPath
}
// 判断是否是 Codex OAuth 端点
function isCodexUrl(baseUrl: string): boolean {
const url = baseUrl.replace(/\/+$/, '')
return url.includes('/backend-api/codex') || url.endsWith('/codex')
} }
// 初始化端点的编辑状态 // 初始化端点的编辑状态
@@ -1183,7 +1194,9 @@ function hasValidationErrorsForEndpoint(endpointId: string): boolean {
// 新端点选择的格式的默认路径 // 新端点选择的格式的默认路径
const newEndpointDefaultPath = computed(() => { const newEndpointDefaultPath = computed(() => {
return getDefaultPath(newEndpoint.value.api_format) // 使用填写的 base_url 或 provider 的 website 来判断是否是 Codex 端点
const baseUrl = newEndpoint.value.base_url || props.provider?.website || ''
return getDefaultPath(newEndpoint.value.api_format, baseUrl)
}) })
// 加载 API 格式列表 // 加载 API 格式列表

View File

@@ -118,7 +118,7 @@ export const apiFormats = [
}, },
{ {
name: 'OpenAI CLI', name: 'OpenAI CLI',
endpoint: '/v1/responses', endpoint: '/v1/responses (Codex: /responses)',
auth: 'Authorization: Bearer xxx', auth: 'Authorization: Bearer xxx',
clients: ['Codex CLI'] clients: ['Codex CLI']
}, },

View File

@@ -146,6 +146,10 @@ def build_provider_url(
else: else:
# 使用 API 格式的默认路径 # 使用 API 格式的默认路径
path = _resolve_default_path(endpoint_sig) path = _resolve_default_path(endpoint_sig)
# Codex OAuth 端点chatgpt.com/backend-api/codex使用 /responses 而非 /v1/responses
base_url = getattr(endpoint, "base_url", "") or ""
if endpoint_sig == "openai:cli" and _is_codex_url(base_url):
path = "/responses"
if effective_path_params: if effective_path_params:
try: try:
path = path.format(**effective_path_params) path = path.format(**effective_path_params)
@@ -191,6 +195,15 @@ def _resolve_default_path(endpoint_sig: str | None) -> str:
return "/" return "/"
def _is_codex_url(base_url: str) -> bool:
"""判断是否是 Codex OAuth 端点(如 chatgpt.com/backend-api/codex
Codex 端点不走标准 /v1 前缀,直接使用 /responses。
"""
url = base_url.rstrip("/")
return "/backend-api/codex" in url or url.endswith("/codex")
# ============================================================================== # ==============================================================================
# Vertex AI 配置 # Vertex AI 配置
# ============================================================================== # ==============================================================================