diff --git a/hermes_cli/cli_model_switch_mixin.py b/hermes_cli/cli_model_switch_mixin.py index 9d6a12a62f..6eb134bd6f 100644 --- a/hermes_cli/cli_model_switch_mixin.py +++ b/hermes_cli/cli_model_switch_mixin.py @@ -356,9 +356,10 @@ class CLIModelSwitchMixin: # 2. Replace untouched default with a Codex model if self._model_is_default: - fallback_model = "gpt-5.3-codex" + from hermes_cli.codex_models import DEFAULT_CODEX_MODELS, get_codex_model_ids + + fallback_model = DEFAULT_CODEX_MODELS[0] try: - from hermes_cli.codex_models import get_codex_model_ids available = get_codex_model_ids(access_token=self.api_key if self.api_key else None) if available: fallback_model = available[0] diff --git a/run_agent.py b/run_agent.py index 73208e3227..6165032eff 100644 --- a/run_agent.py +++ b/run_agent.py @@ -627,7 +627,7 @@ class AIAgent( "on chatgpt.com/backend-api/codex (no stream events, no error). " "This is a known backend-side pattern that has affected ChatGPT " "Plus accounts intermittently. " - "Workaround: try `gpt-5.4` on the same OAuth profile, or `gpt-5.3-codex`, " + "Workaround: try `gpt-5.4` on the same OAuth profile, " "or switch to a different model/provider in your fallback chain. " "Some ChatGPT Codex accounts do not support `gpt-5.4-codex`. " "See hermes-agent#21444 for symptom history." diff --git a/tests/agent/test_codex_silent_hang_hint.py b/tests/agent/test_codex_silent_hang_hint.py index 873ab5a8ee..447b0d11ba 100644 --- a/tests/agent/test_codex_silent_hang_hint.py +++ b/tests/agent/test_codex_silent_hang_hint.py @@ -4,7 +4,7 @@ The helper substitutes an actionable hint into the stale-call timeout warning when the request matches a known Codex silent-reject pattern (gpt-5.5 family on the ChatGPT Codex backend). See issue #21444 for symptom history. The recommended workaround for ChatGPT Codex OAuth -accounts is `gpt-5.4` / `gpt-5.3-codex`, not `gpt-5.4-codex`. +accounts is `gpt-5.4`, not `gpt-5.4-codex` (gpt-5.3-codex is retired, #52492). """ from __future__ import annotations @@ -45,7 +45,7 @@ def test_hint_fires_for_bare_gpt_5_5_on_codex(tmp_path): hint = agent._codex_silent_hang_hint(model="gpt-5.5") assert hint is not None assert "gpt-5.4" in hint - assert "gpt-5.3-codex" in hint + assert "gpt-5.3-codex" not in hint assert "gpt-5.4-codex" in hint assert "fallback chain" in hint diff --git a/tests/agent/test_codex_ttfb_watchdog.py b/tests/agent/test_codex_ttfb_watchdog.py index 1609a0ff4d..4fbbe6564c 100644 --- a/tests/agent/test_codex_ttfb_watchdog.py +++ b/tests/agent/test_codex_ttfb_watchdog.py @@ -140,11 +140,11 @@ def test_ttfb_includes_silent_hang_hint_for_gpt_5_5(tmp_path, monkeypatch): h.interruptible_api_call(agent, {"model": "gpt-5.5", "input": "hi"}) message = str(excinfo.value) assert "gpt-5.4" in message - assert "gpt-5.3-codex" in message + assert "gpt-5.3-codex" not in message assert "gpt-5.4-codex" in message assert "codex_ttfb_kill" in closes assert statuses, "expected a user-facing watchdog status" - assert any("gpt-5.4" in s and "gpt-5.3-codex" in s for s in statuses) + assert any("gpt-5.4" in s and "gpt-5.3-codex" not in s for s in statuses) finally: stop["flag"] = True diff --git a/tests/hermes_cli/test_codex_models.py b/tests/hermes_cli/test_codex_models.py index 78a057711f..66b7657726 100644 --- a/tests/hermes_cli/test_codex_models.py +++ b/tests/hermes_cli/test_codex_models.py @@ -66,6 +66,21 @@ def test_picker_never_synthesizes_900k_for_pro_or_unknown_slugs(): +def test_retired_gpt_5_3_codex_is_not_offered_offline(): + """The ChatGPT Codex backend retired ``gpt-5.3-codex`` (HTTP 400 "not supported when using + Codex with a ChatGPT account", #52492). Neither the curated offline fallback nor any + forward-compat template may surface it — only live discovery may, if the backend re-enables it. + Same precedent as the gpt-5.2-codex / gpt-5.1-codex-* removal (e8955f222ce).""" + from hermes_cli.codex_models import _FORWARD_COMPAT_TEMPLATE_MODELS, DEFAULT_CODEX_MODELS + + assert "gpt-5.3-codex" not in DEFAULT_CODEX_MODELS + for newer, templates in _FORWARD_COMPAT_TEMPLATE_MODELS: + assert newer != "gpt-5.3-codex" + assert "gpt-5.3-codex" not in templates + # Spark is still a real Codex-OAuth slug and must keep surfacing via a live template. + assert "gpt-5.3-codex-spark" in DEFAULT_CODEX_MODELS + + def test_setup_wizard_codex_import_resolves(): """Regression test for #712: setup.py must import the correct function name.""" # This mirrors the exact import used in hermes_cli/setup.py line 873. @@ -170,7 +185,7 @@ def test_model_command_prompts_to_reuse_or_reauthenticate_codex_session(monkeypa monkeypatch.setattr("hermes_cli.auth._login_openai_codex", _fake_login) monkeypatch.setattr( "hermes_cli.codex_models.get_codex_model_ids", - lambda access_token=None: ["gpt-5.4", "gpt-5.3-codex"], + lambda access_token=None: ["gpt-5.4", "gpt-5.5"], ) monkeypatch.setattr( "hermes_cli.auth._prompt_model_selection", @@ -263,12 +278,12 @@ class TestNormalizeModelForProvider: assert cli._model_is_default is True with patch( "hermes_cli.codex_models.get_codex_model_ids", - return_value=["gpt-5.3-codex", "gpt-5.4"], + return_value=["gpt-5.5", "gpt-5.4"], ): changed = cli._normalize_model_for_provider("openai-codex") assert changed is True # Uses first from available list - assert cli.model == "gpt-5.3-codex" + assert cli.model == "gpt-5.5" def test_catalog_requests_use_ungated_client_version(monkeypatch): diff --git a/website/docs/user-guide/configuration.md b/website/docs/user-guide/configuration.md index 9f9f22ad30..5519255cf9 100644 --- a/website/docs/user-guide/configuration.md +++ b/website/docs/user-guide/configuration.md @@ -1676,7 +1676,7 @@ These options apply to **auxiliary task configs** (`auxiliary:`, `compression:`) | `"auto"` | Best available (default). Vision tries OpenRouter → Nous → Codex. | — | | `"openrouter"` | Force OpenRouter — routes to any model (Gemini, GPT-4o, Claude, etc.) | `OPENROUTER_API_KEY` | | `"nous"` | Force Nous Portal | `hermes auth` | -| `"codex"` | Force Codex OAuth (ChatGPT account). Supports vision (gpt-5.3-codex). | `hermes model` → ChatGPT or Codex Subscription | +| `"codex"` | Force Codex OAuth (ChatGPT account). Set `model` explicitly (e.g. `gpt-5.4`). | `hermes model` → ChatGPT or Codex Subscription | | `"minimax-oauth"` | Force MiniMax OAuth (browser login, no API key). Uses MiniMax-M2.7-highspeed for auxiliary tasks. | `hermes model` → MiniMax (OAuth) | | `"xai-oauth"` | Force xAI Grok OAuth (browser login for SuperGrok or X Premium+ subscribers, no API key). Same OAuth token covers chat, TTS, image, video, and transcription. | `hermes model` → xAI Grok OAuth (SuperGrok / Premium+) | | `"main"` | Use your active custom/main endpoint. This can come from `OPENAI_BASE_URL` + `OPENAI_API_KEY` or from a custom endpoint saved via `hermes model` / `config.yaml`. Works with OpenAI, local models, or any OpenAI-compatible API. **Auxiliary tasks only — not valid for `model.provider`.** | Custom endpoint credentials + base URL | @@ -1730,7 +1730,7 @@ auxiliary: auxiliary: vision: provider: "codex" # uses your ChatGPT OAuth token - # model defaults to gpt-5.3-codex (supports vision) + model: "gpt-5.4" # no implicit default on the Codex route ``` **Using MiniMax OAuth** (browser login, no API key needed): diff --git a/website/docs/user-guide/features/fallback-providers.md b/website/docs/user-guide/features/fallback-providers.md index fcb033ca10..464cdf65b1 100644 --- a/website/docs/user-guide/features/fallback-providers.md +++ b/website/docs/user-guide/features/fallback-providers.md @@ -179,7 +179,7 @@ fallback_providers: ```yaml fallback_providers: - provider: openai-codex - model: gpt-5.3-codex + model: gpt-5.4 ``` ### Where Fallback Works diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/configuration.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/configuration.md index 9e86946da6..6dc7ebb343 100644 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/configuration.md +++ b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/configuration.md @@ -1000,7 +1000,7 @@ AUXILIARY_VISION_MODEL=openai/gpt-4o | `"auto"` | 最佳可用(默认)。Vision 尝试 OpenRouter → Nous → Codex。 | — | | `"openrouter"` | 强制 OpenRouter —— 路由到任何模型(Gemini、GPT-4o、Claude 等) | `OPENROUTER_API_KEY` | | `"nous"` | 强制 Nous Portal | `hermes auth` | -| `"codex"` | 强制 Codex OAuth(ChatGPT 账户)。支持视觉(gpt-5.3-codex)。 | `hermes model` → ChatGPT or Codex Subscription | +| `"codex"` | 强制 Codex OAuth(ChatGPT 账户)。请显式设置 `model`(例如 `gpt-5.4`)。 | `hermes model` → ChatGPT or Codex Subscription | | `"minimax-oauth"` | 强制 MiniMax OAuth(浏览器登录,无需 API 密钥)。辅助任务使用 MiniMax-M2.7-highspeed。 | `hermes model` → MiniMax (OAuth) | | `"xai-oauth"` | 强制 xAI Grok OAuth(SuperGrok 或 X Premium+ 订阅者的浏览器登录,无需 API 密钥)。相同的 OAuth token 涵盖聊天、TTS、图像、视频和转录。 | `hermes model` → xAI Grok OAuth (SuperGrok / Premium+) | | `"main"` | 使用您的活跃自定义/主端点。可以来自 `OPENAI_BASE_URL` + `OPENAI_API_KEY` 或通过 `hermes model` / `config.yaml` 保存的自定义端点。适用于 OpenAI、本地模型或任何 OpenAI 兼容 API。**仅限辅助任务 —— 对 `model.provider` 无效。** | 自定义端点凭据 + 基础 URL | @@ -1054,7 +1054,7 @@ auxiliary: auxiliary: vision: provider: "codex" # 使用您的 ChatGPT OAuth token - # 模型默认为 gpt-5.3-codex(支持视觉) + model: "gpt-5.4" # Codex 路径没有隐式默认模型 ``` **使用 MiniMax OAuth**(浏览器登录,无需 API 密钥): diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/features/fallback-providers.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/features/fallback-providers.md index 183d069c23..e679e33db7 100644 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/features/fallback-providers.md +++ b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/features/fallback-providers.md @@ -158,7 +158,7 @@ fallback_model: ```yaml fallback_model: provider: openai-codex - model: gpt-5.3-codex + model: gpt-5.4 ``` ### 备用适用范围