From 4d0846b64053ea0050e11e77246d76089072abcf Mon Sep 17 00:00:00 2001 From: admin28980 <271152998+admin28980@users.noreply.github.com> Date: Wed, 8 Apr 2026 19:58:38 -0700 Subject: [PATCH] Fix Cloudflare 403s for openai-codex provider on server IPs Add ChatGPT-Account-Id and originator headers when using chatgpt.com backend-api endpoint. Matches official codex-rs CLI behavior to prevent Cloudflare JavaScript challenges on non-residential IPs (VPS, Mac Mini, always-on servers). Applied in AIAgent.__init__ and _update_base_url_headers to cover both initial setup and credential rotation paths. --- run_agent.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/run_agent.py b/run_agent.py index b7c2b44a..a46c1113 100644 --- a/run_agent.py +++ b/run_agent.py @@ -1077,6 +1077,23 @@ class AIAgent: } elif "portal.qwen.ai" in effective_base.lower(): client_kwargs["default_headers"] = _qwen_portal_headers() + elif "chatgpt.com" in effective_base.lower(): + # Match official Codex CLI headers to avoid Cloudflare challenges. + # The ChatGPT-Account-Id header is critical — without it, + # server-hosted agents get 403 Cloudflare JS challenges. + _codex_headers = { + "User-Agent": "hermes-agent/1.0", + "originator": "hermes-agent", + } + try: + import base64 as _b64 + _jwt_payload = json.loads(_b64.b64decode(api_key.split(".")[1] + "==")) + _acct_id = _jwt_payload.get("https://api.openai.com/auth", {}).get("chatgpt_account_id") + if _acct_id: + _codex_headers["ChatGPT-Account-Id"] = _acct_id + except Exception: + pass + client_kwargs["default_headers"] = _codex_headers else: # No explicit creds — use the centralized provider router from agent.auxiliary_client import resolve_provider_client @@ -5312,6 +5329,21 @@ class AIAgent: self._client_kwargs["default_headers"] = {"User-Agent": "KimiCLI/1.30.0"} elif "portal.qwen.ai" in normalized: self._client_kwargs["default_headers"] = _qwen_portal_headers() + elif "chatgpt.com" in normalized: + _codex_headers = { + "User-Agent": "hermes-agent/1.0", + "originator": "hermes-agent", + } + try: + import base64 as _b64 + _ak = self._client_kwargs.get("api_key", "") + _jwt_payload = json.loads(_b64.b64decode(_ak.split(".")[1] + "==")) + _acct_id = _jwt_payload.get("https://api.openai.com/auth", {}).get("chatgpt_account_id") + if _acct_id: + _codex_headers["ChatGPT-Account-Id"] = _acct_id + except Exception: + pass + self._client_kwargs["default_headers"] = _codex_headers else: self._client_kwargs.pop("default_headers", None)