fix(codex): send catalog/image credentials only to their own route

Follow-up to the two contributor commits for #121486. The picker, the
image plugin and the auxiliary Codex client still composed a pooled
gateway key with a base re-read from ambient state (HERMES_CODEX_BASE_URL
or the chatgpt.com default), so a model.base_url-only gateway (env unset)
still sent its key to chatgpt.com.

- auth_codex: resolve_codex_runtime_credentials reports the host a pooled
  credential actually routes to (runtime_provider._pool_entry_mode_and_url:
  env > model.base_url while the row is canonical > row URL) instead of the
  ambient default; get_codex_auth_status carries the same bound base_url.
- picker: get_codex_model_ids(access_token, base_url=) now receives the base
  resolved with the token from hermes_cli/models.py, the CLI default-model
  swap (self.base_url) and the `hermes model` Codex flow.
- aux/image: _resolve_codex_credential_and_base() returns (token, base) from
  one pool selection; the image plugin, _build_codex_client and the raw
  Codex client use it (profile-scoped override from #121497 still wins).
- model_metadata: the non-JWT refusal now applies only when the target is
  chatgpt.com; a gateway key may probe its own gateway's /models.

Adversarial regressions: model.base_url with env unset, env/route mismatch,
opaque + JWT gateway keys, pool-selected credential, pool row with its own
gateway URL, direct-ChatGPT positive control.

Addresses @andrexibiza's review on #121508.
This commit is contained in:
kshitijk4poor
2026-09-24 19:32:54 +05:30
committed by kshitij
parent 602aa9a55b
commit e87f673faa
14 changed files with 484 additions and 57 deletions

View File

@@ -377,7 +377,9 @@ class CLIModelSwitchMixin:
fallback_model = DEFAULT_CODEX_MODELS[0]
try:
available = get_codex_model_ids(access_token=self.api_key if self.api_key else None)
# self.base_url is the route resolved with self.api_key (#121486).
available = get_codex_model_ids(
access_token=self.api_key if self.api_key else None, base_url=getattr(self, "base_url", None) or None)
if available:
fallback_model = available[0]
except Exception: