From 9ee9a4297de7998bf64b42dc396c226098e52b27 Mon Sep 17 00:00:00 2001 From: kshitij <82637225+kshitijk4poor@users.noreply.github.com> Date: Sun, 10 May 2026 10:41:24 +0530 Subject: [PATCH] docs(codex-spark): document ChatGPT Pro entitlement gating MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #12994 stripped gpt-5.3-codex-spark on the assumption that it was unsupported. It's actually research-preview, ChatGPT-Pro-only, exposed via the Codex OAuth backend at chatgpt.com/backend-api/codex/models — not via the public OpenAI API. Add explanatory comments in: - DEFAULT_CODEX_MODELS / _FORWARD_COMPAT_TEMPLATE_MODELS (codex_models.py) - _CODEX_OAUTH_CONTEXT_FALLBACK (model_metadata.py) - list_authenticated_providers' live-discovery branch (model_switch.py) so future maintainers don't strip the entry again. Also documents the intentional asymmetry that Spark stays out of the "openai" provider catalog (it isn't on the public API) and why the supported_in_api filter is *not* applied for the openai-codex route. --- agent/model_metadata.py | 5 +++++ hermes_cli/codex_models.py | 16 ++++++++++++++++ hermes_cli/model_switch.py | 7 +++++++ 3 files changed, 28 insertions(+) diff --git a/agent/model_metadata.py b/agent/model_metadata.py index a8590b58384..653a90619a5 100644 --- a/agent/model_metadata.py +++ b/agent/model_metadata.py @@ -1108,6 +1108,11 @@ _CODEX_OAUTH_CONTEXT_FALLBACK: Dict[str, int] = { "gpt-5.1-codex-max": 272_000, "gpt-5.1-codex-mini": 272_000, "gpt-5.3-codex": 272_000, + # Spark runs on specialised low-latency hardware and exposes a smaller + # 128k window than other Codex OAuth slugs. Listed explicitly so the + # longest-key-first fallback resolves it correctly — substring match + # on "gpt-5.3-codex" otherwise wins and reports 272k. Availability is + # gated by ChatGPT Pro entitlement on the Codex backend. "gpt-5.3-codex-spark": 128_000, "gpt-5.2-codex": 272_000, "gpt-5.4-mini": 272_000, diff --git a/hermes_cli/codex_models.py b/hermes_cli/codex_models.py index 9e388ef0892..8e50004c2d6 100644 --- a/hermes_cli/codex_models.py +++ b/hermes_cli/codex_models.py @@ -16,6 +16,18 @@ DEFAULT_CODEX_MODELS: List[str] = [ "gpt-5.4-mini", "gpt-5.4", "gpt-5.3-codex", + # gpt-5.3-codex-spark is in research preview and is exposed *only* via + # the Codex CLI / OAuth backend (chatgpt.com/backend-api/codex/models) + # for ChatGPT Pro subscribers. It is NOT available in the public OpenAI + # API, so it intentionally stays out of the "openai" provider catalog + # in hermes_cli/models.py — only the openai-codex (OAuth) provider + # surfaces it. The Codex backend reports ``supported_in_api: false`` for + # this slug; that flag describes API availability, not Codex backend + # availability, so the fetch/cache code paths below intentionally do + # not filter on it. PR #12994 removed this entry on the assumption it + # was unsupported — that was wrong; restored here. Keep it in the + # curated fallback so Pro users still see Spark in `/model` when live + # discovery is unavailable (offline first run, transient API failure). "gpt-5.3-codex-spark", "gpt-5.2-codex", "gpt-5.1-codex-max", @@ -27,6 +39,10 @@ _FORWARD_COMPAT_TEMPLATE_MODELS: List[tuple[str, tuple[str, ...]]] = [ ("gpt-5.4-mini", ("gpt-5.3-codex", "gpt-5.2-codex")), ("gpt-5.4", ("gpt-5.3-codex", "gpt-5.2-codex")), ("gpt-5.3-codex", ("gpt-5.2-codex",)), + # Surface Spark whenever any compatible Codex template is present so + # accounts hitting the live endpoint with an older lineup still see + # Spark in the picker. Backend gates real availability by ChatGPT Pro + # entitlement; Hermes does not. ("gpt-5.3-codex-spark", ("gpt-5.3-codex", "gpt-5.2-codex")), ] diff --git a/hermes_cli/model_switch.py b/hermes_cli/model_switch.py index 3a282425dc4..d75aca5cd08 100644 --- a/hermes_cli/model_switch.py +++ b/hermes_cli/model_switch.py @@ -1343,6 +1343,13 @@ def list_authenticated_providers( continue if hermes_slug in {"openai-codex", "copilot", "copilot-acp"}: + # Use live OAuth-backed discovery so the gateway /model picker + # matches what the user's authenticated Codex/Copilot backend + # actually serves — including ChatGPT-Pro-only Codex slugs + # (e.g. gpt-5.3-codex-spark) that aren't in the static curated + # catalog. ``provider_model_ids()`` falls back to the curated + # list when the live endpoint is unreachable, so this is safe + # for unauthenticated and offline cases too. model_ids = provider_model_ids(hermes_slug) # For aws_sdk providers (bedrock), use live discovery so the list # reflects the active region (eu.*, ap.*) not the static us.* list.