fix(codex): 强制统一出站身份并让客户端版本号跟随官方发布

上游 /backend-api/codex 在容量紧张时按客户端身份分优先级降载,被降载的请求
HTTP 200 后立刻推流内 server_is_overloaded。此前网关对配不出官方身份的客户端
整体回退到硬编码的 codex_cli_rs/0.144.1(落后官方 4 个发布),这些请求稳定
落在被优先丢弃的一侧。

- 强制统一出口:所有 OAuth 出站的 User-Agent / originator / version 一律改写
  为网关规范身份,客户端自报身份不参与构造;HTTP / 透传 / WS / alpha-search /
  探针全覆盖。compat 桥接故意删除 originator 的路径保持 no-op。
- 版本号收敛为单一来源,运行时优先级为面板覆写 → 自动同步值 → 内置常量;
  UA 与 version 头同源派生,不再各自硬编码。
- 新增 3 小时自动同步官方客户端最新稳定版,面板可关闭,无需为跟版本而发版。
- 流内 server_is_overloaded / slow_down 改为先在同账号有界重试再切号,并标记为
  请求级瞬时故障,不再据此临时封禁账号。
- 移除被取代的降载身份黑名单、浏览器 UA 兜底及其辅助函数。
This commit is contained in:
zhiyu committed 2026-08-03 20:14:58 +08:00
1 parent 825ca7b1fc
commit 2eb24814fe
37 files changed
+1273 -439

No files matched your search

+75
View File
@@ -5168,6 +5168,65 @@
</p>
</div>
<!-- Codex 客户端版本号 -->
<div>
<label
class="mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300"
>
{{
t(
"admin.settings.gatewayForwarding.openaiCodexClientVersion",
)
}}
</label>
<input
v-model="form.openai_codex_client_version"
type="text"
class="input w-full font-mono text-sm"
:placeholder="
t(
'admin.settings.gatewayForwarding.openaiCodexClientVersionPlaceholder',
)
"
/>
<p class="mt-1.5 text-xs text-gray-500 dark:text-gray-400">
{{
t(
"admin.settings.gatewayForwarding.openaiCodexClientVersionHint",
)
}}
</p>
</div>
<!-- Codex 版本号自动同步 -->
<div class="flex items-center justify-between">
<div>
<label
class="text-sm font-medium text-gray-700 dark:text-gray-300"
>
{{
t(
"admin.settings.gatewayForwarding.openaiCodexVersionAutoSync",
)
}}
</label>
<p class="mt-0.5 text-xs text-gray-500 dark:text-gray-400">
{{
t(
"admin.settings.gatewayForwarding.openaiCodexVersionAutoSyncHint",
)
}}
</p>
<p
v-if="codexSyncedVersionLabel"
class="mt-0.5 text-xs text-gray-500 dark:text-gray-400"
>
{{ codexSyncedVersionLabel }}
</p>
</div>
<Toggle v-model="form.openai_codex_version_auto_sync_enabled" />
</div>
</div>
</div>
@@ -9038,6 +9097,10 @@ const form = reactive<SettingsForm>({
enable_client_dateline_normalization: true,
antigravity_user_agent_version: "",
openai_codex_user_agent: "",
openai_codex_client_version: "",
// 只读展示:自动同步任务写入的官方最新稳定版,不参与提交(提交载荷按字段显式构造)
openai_codex_client_version_synced: "",
openai_codex_version_auto_sync_enabled: true,
// codex_cli_only 加固
min_codex_version: "",
max_codex_version: "",
@@ -9957,6 +10020,14 @@ function removeCodexWhitelistRow(i: number): void {
codexWhitelistRows.value.splice(i, 1);
}
const codexSyncedVersionLabel = computed(() => {
const synced = form.openai_codex_client_version_synced?.trim();
if (!synced) return "";
return t("admin.settings.gatewayForwarding.openaiCodexVersionSyncedValue", {
version: synced,
});
});
async function loadSettings() {
loading.value = true;
loadFailed.value = false;
@@ -10510,6 +10581,10 @@ async function saveSettings() {
form.antigravity_user_agent_version?.trim() || "",
openai_codex_user_agent:
form.openai_codex_user_agent?.trim() || "",
openai_codex_client_version:
form.openai_codex_client_version?.trim() || "",
openai_codex_version_auto_sync_enabled:
form.openai_codex_version_auto_sync_enabled,
min_codex_version: form.min_codex_version?.trim() || "",
max_codex_version: form.max_codex_version?.trim() || "",
codex_cli_only_allow_app_server_clients: