fix(codex): respect HERMES_CODEX_BASE_URL in all paths - #40924
Conversation
The openai-codex provider hardcodes the Codex base URL in three code paths, ignoring both HERMES_CODEX_BASE_URL env var and config.yaml model.base_url. This makes proxy routing impossible. Affected paths: - credential_pool._seed_from_singletons() bakes hardcoded URL into pool entries on every startup - runtime_provider._resolve_runtime_from_pool_entry() exits before reaching the config base_url override block - run_agent._swap_credential() reads pool entry base_url directly without consulting env var Centralize resolution into resolve_codex_base_url() helper in auth.py with priority: HERMES_CODEX_BASE_URL > pool entry > DEFAULT_CODEX_BASE_URL. All three sites now call this helper. Closes NousResearch#40913
|
Hi @austinpickett Hope, its okay to loop you in. But is there something I've to improve to merge this PR? |
|
I hit this same bug on a live gateway today while routing
One gap I noticed in this PR as currently written:
Those tests passed in a clean clone with: uv run --with pytest python -m pytest tests/hermes_cli/test_runtime_provider_resolution.py -qIf helpful, the relevant patch is in commit |
|
This issue is part of a systemic credential resolution cascade documented in #62435, with unit test proof in PR #62434. Root cause: (gateway/desktop path) never calls any provider-specific resolver (, , etc.). Only the auxiliary path () does. When a manual pool entry has , the override also fails due to the trap (). Cross-provider impact: Z.AI (critical), MiniMax-CN (medium), DeepSeek (low), openai-codex (critical). 7 unit tests prove the inconsistency across 3 providers. See #62435 for the full cascade analysis and PR #62434 for the test file. |
teknium1
left a comment
There was a problem hiding this comment.
Thanks for targeting a real Codex routing defect. Current main still selects a credential-pool entry before the singleton resolver (hermes_cli/runtime_provider.py:1753-1760) and then defaults Codex to the hardcoded endpoint (:418-420); pool seeding also persists that endpoint (agent/credential_pool.py:2103).
Problems
- The proposed helper only resolves
HERMES_CODEX_BASE_URL > pool URL > default. It has nomodelconfiguration input, so it cannot satisfy the PR's statedmodel.base_urlsupport. Current generic config handling is in the separateelsebranch athermes_cli/runtime_provider.py:480-491, which Codex never reaches. tests/agent/test_resolve_codex_base_url.pytests the helper alone, not the pool-first resolver or rotation path. The affected rotation path isrun_agent.py:4516-4544.
Suggested changes
- Add the matching-provider/default-pool-url config fallback while preserving non-default pool endpoints, then cover pool resolution, singleton fallback, and rotation with regression tests.
Automated hermes-sweeper review.
| @@ -308,7 +309,7 @@ def _resolve_runtime_from_pool_entry( | |||
| api_mode = "chat_completions" | |||
There was a problem hiding this comment.
This applies the environment override, but resolve_codex_base_url(base_url) cannot honor model.base_url because it receives no model configuration. Please add the matching-provider config fallback for an empty/default pool URL (while preserving a non-default pool endpoint), as the PR description and #60198 discussion require.
Related to the openai-codex base_url resolution cluster: fixes #40913, sibling to the raw_codex path #5875 / fix PR #5988, and the api_mode-resolution PR #56094. Independently reproduced on a live gateway by @robinbraemer. Two notes for reviewers:
|
The openai-codex provider hardcodes the Codex base URL in three code paths, ignoring both HERMES_CODEX_BASE_URL env var and config.yaml model.base_url. This makes proxy routing impossible.
Affected paths:
Centralize resolution into resolve_codex_base_url() helper in
auth.py with priority: HERMES_CODEX_BASE_URL > pool entry >
DEFAULT_CODEX_BASE_URL. All three sites now call this helper.
Closes #40913
What does this PR do?
Adds a centralized resolve_codex_base_url() helper that makes the openai-codex provider respect HERMES_CODEX_BASE_URL across all code paths — not just the fallback
singleton resolver.
Problem: HERMES_CODEX_BASE_URL is correctly read by resolve_codex_runtime_credentials(), but that function is only the fallback path. In normal operation, the
credential pool path wins and hardcodes https://chatgpt.com/backend-api/codex in three places:
This makes it impossible to route openai-codex traffic through a proxy (Headroom, load balancer, etc.), even when the env var is correctly set.
Fix: A single resolve_codex_base_url(pool_base_url=None) helper in auth.py with a clear priority chain (env var > pool entry > default), called from all four sites.
Same class of bug as #5561 (kimi-coding pool seeding wrong base_url).
Related Issue
Fixes #
Type of Change
Changes Made
How to Test
After fix: provider=openai-codex base_url=http://localhost:8787/v1
Checklist
Code
fix(scope):,feat(scope):, etc.)pytest tests/ -qand all tests passDocumentation & Housekeeping
docs/, docstrings) — or N/Acli-config.yaml.exampleif I added/changed config keys — or N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — or N/A