From 56490ca109613fc90bfdd502cd2c5f087071cb95 Mon Sep 17 00:00:00 2001 From: kshitijk4poor <82637225+kshitijk4poor@users.noreply.github.com> Date: Thu, 24 Sep 2026 21:40:14 +0530 Subject: [PATCH] refactor(aux): drop the now-uncalled _read_codex_access_token and retarget its test seams The fold routed every aux Codex read through _resolve_codex_credential_and_base, leaving _read_codex_access_token with no production callers; three test patches on it had gone inert (including the 'should use pool token' guard). Point them at the live seams instead. --- agent/auxiliary_client.py | 10 ---------- hermes_cli/auth_codex.py | 2 +- tests/agent/test_auxiliary_client.py | 25 ++++++++++++------------- tests/agent/test_provider_parity.py | 3 ++- 4 files changed, 15 insertions(+), 25 deletions(-) diff --git a/agent/auxiliary_client.py b/agent/auxiliary_client.py index c12e146811..ab6d440c66 100644 --- a/agent/auxiliary_client.py +++ b/agent/auxiliary_client.py @@ -2103,16 +2103,6 @@ def _resolve_xai_oauth_for_aux() -> Optional[Tuple[str, str]]: return _creds_pair(creds) -def _read_codex_access_token() -> Optional[str]: - """Valid, non-expired Codex OAuth access token; an exhausted pool falls back to the profile's auth.json token.""" - pool_present, entry = _select_pool_entry("openai-codex") - if pool_present: - token = _pool_runtime_api_key(entry) - if token: - return token - return _read_codex_singleton_token() - - def _resolve_codex_credential_and_base() -> Tuple[Optional[str], str]: """``(token, base_url)`` taken from ONE authority, so a Codex key is only ever sent to the host it belongs to (#121486): the profile-scoped ``HERMES_CODEX_BASE_URL`` wins; otherwise a pooled diff --git a/hermes_cli/auth_codex.py b/hermes_cli/auth_codex.py index cc6c0e9f2f..761ae82c50 100644 --- a/hermes_cli/auth_codex.py +++ b/hermes_cli/auth_codex.py @@ -597,7 +597,7 @@ def resolve_codex_runtime_credentials( usable access_token but the pool (``credential_pool.openai-codex``) does. This closes the divergence between the chat path (singleton-only via this function) and the auxiliary - path (pool-first via ``_read_codex_access_token``). Without this fallback, a user whose tokens live only + path (pool-first via ``auxiliary_client._resolve_codex_credential_and_base``). Without this fallback, a user whose tokens live only in the pool — for example after a manual pool seed, a partial re-auth, or pool-only restoration from a backup — gets a bare HTTP 401 ``Missing Authentication header`` from the wire instead of a usable credential. See issue #32992. diff --git a/tests/agent/test_auxiliary_client.py b/tests/agent/test_auxiliary_client.py index 0435b043b6..9e2960ca07 100644 --- a/tests/agent/test_auxiliary_client.py +++ b/tests/agent/test_auxiliary_client.py @@ -20,7 +20,7 @@ from agent.auxiliary_client import ( call_llm, async_call_llm, _build_call_kwargs, - _read_codex_access_token, + _resolve_codex_credential_and_base, _is_payment_error, _is_rate_limit_error, _is_model_not_found_error, @@ -488,7 +488,9 @@ class TestNormalizeAuxProvider: assert _normalize_aux_provider(alias) == canonical, alias -class TestReadCodexAccessToken: +class TestResolveCodexCredentialToken: + """Token half of ``_resolve_codex_credential_and_base`` with no pool (auth.json only).""" + def test_valid_auth_store(self, tmp_path, monkeypatch): hermes_home = tmp_path / "hermes" hermes_home.mkdir(parents=True, exist_ok=True) @@ -501,15 +503,10 @@ class TestReadCodexAccessToken: }, })) monkeypatch.setenv("HERMES_HOME", str(hermes_home)) - result = _read_codex_access_token() + with patch("agent.auxiliary_client._select_pool_entry", return_value=(False, None)): + result = _resolve_codex_credential_and_base()[0] assert result == "tok-123" - - - - - - def test_expired_jwt_returns_none(self, tmp_path, monkeypatch): """Expired JWT tokens should be skipped so auto chain continues.""" import base64 @@ -533,7 +530,7 @@ class TestReadCodexAccessToken: })) monkeypatch.setenv("HERMES_HOME", str(hermes_home)) with patch("agent.auxiliary_client._select_pool_entry", return_value=(False, None)): - result = _read_codex_access_token() + result = _resolve_codex_credential_and_base()[0] assert result is None, "Expired JWT should return None" def test_valid_jwt_returns_token(self, tmp_path, monkeypatch): @@ -557,7 +554,8 @@ class TestReadCodexAccessToken: }, })) monkeypatch.setenv("HERMES_HOME", str(hermes_home)) - result = _read_codex_access_token() + with patch("agent.auxiliary_client._select_pool_entry", return_value=(False, None)): + result = _resolve_codex_credential_and_base()[0] assert result == valid_jwt @@ -1157,7 +1155,8 @@ class TestGetTextAuxiliaryClient: monkeypatch.delenv("OPENAI_API_KEY", raising=False) monkeypatch.delenv("OPENROUTER_API_KEY", raising=False) with patch("agent.auxiliary_client._read_nous_auth", return_value=None), \ - patch("agent.auxiliary_client._read_codex_access_token", return_value=None), \ + patch("agent.auxiliary_client._resolve_codex_credential_and_base", + return_value=(None, "https://chatgpt.com/backend-api/codex")), \ patch("agent.auxiliary_client._resolve_api_key_provider", return_value=(None, None)): client, model = get_text_auxiliary_client() assert client is None @@ -1951,7 +1950,7 @@ class TestAuxiliaryFallbackLayering: with patch("agent.auxiliary_client._select_pool_entry", return_value=(True, pool_entry)), \ - patch("agent.auxiliary_client._read_codex_access_token", + patch("agent.auxiliary_client._read_codex_singleton_token", side_effect=AssertionError("should use pool token")), \ patch("agent.auxiliary_client.OpenAI", return_value=real_client) as mock_openai: client, model = _resolve_fallback_entry({ diff --git a/tests/agent/test_provider_parity.py b/tests/agent/test_provider_parity.py index adedf7c257..672e4d93c6 100644 --- a/tests/agent/test_provider_parity.py +++ b/tests/agent/test_provider_parity.py @@ -761,7 +761,8 @@ class TestAuxiliaryClientProviderPriority: monkeypatch.delenv("OPENAI_API_KEY", raising=False) from agent.auxiliary_client import get_text_auxiliary_client with patch("agent.auxiliary_client._read_nous_auth", return_value=None), \ - patch("agent.auxiliary_client._read_codex_access_token", return_value="codex-tok"), \ + patch("agent.auxiliary_client._resolve_codex_credential_and_base", + return_value=("codex-tok", "https://chatgpt.com/backend-api/codex")), \ patch("agent.auxiliary_client.OpenAI"): client, model = get_text_auxiliary_client() assert client is None