Stage 314: PR #1827 — sync Codex provider card models with picker by @Michaelyklam
Note: PR #1827 was branched before v0.51.19 shipped #1812, which introduced an initial (pure live-fetch) Codex provider card hook in api/providers.py at the same line range. The contributor's PR was filed AFTER #1812 shipped but their diff didn't yet account for it. Stage 314 absorbs the contributor's intent (visible Codex cache merge for gpt-5.3-codex-spark visibility) by replacing the v0.51.19 hook with the richer merged version directly in stage. Production code change ≡ what the contributor's PR would have produced if rebased onto current master. Test file + pr-media adopted verbatim. Marker commit so the stage log makes the absorption visible.
This commit is contained in:
@@ -20,6 +20,9 @@ from api.config import (
|
||||
_PROVIDER_DISPLAY,
|
||||
_PROVIDER_MODELS,
|
||||
_get_label_for_model,
|
||||
_models_from_live_provider_ids,
|
||||
_read_live_provider_model_ids,
|
||||
_read_visible_codex_cache_model_ids,
|
||||
_save_yaml_config_file,
|
||||
get_config,
|
||||
invalidate_models_cache,
|
||||
@@ -692,23 +695,24 @@ def get_providers() -> dict[str, Any]:
|
||||
|
||||
models = list(_PROVIDER_MODELS.get(pid, []))
|
||||
models_total = len(models)
|
||||
# Codex account catalogs are account-specific and can drift faster than
|
||||
# WebUI's static fallback table (#1807). Prefer the live agent resolver
|
||||
# for the providers card too so stale static-only model IDs are not
|
||||
# presented as available when discovery succeeds.
|
||||
# OpenAI Codex account catalogs drift independently from WebUI releases.
|
||||
# The model picker already prefers hermes_cli + Codex local cache for
|
||||
# this provider (the agent's `provider_model_ids("openai-codex")` filters
|
||||
# IDs with `supported_in_api: false`, but Codex CLI still surfaces some
|
||||
# of those — notably `gpt-5.3-codex-spark` from #1680 — in its picker).
|
||||
# Merge both sources here so the providers card matches the picker
|
||||
# exactly. Static entries remain the offline fallback when live
|
||||
# discovery and the local Codex cache are both unavailable. (#1807
|
||||
# follow-up to v0.51.19 #1812.)
|
||||
if pid == "openai-codex":
|
||||
try:
|
||||
from hermes_cli.models import provider_model_ids as _provider_model_ids
|
||||
|
||||
live_ids = [mid for mid in (_provider_model_ids("openai-codex") or []) if mid]
|
||||
if live_ids:
|
||||
models = [
|
||||
{"id": mid, "label": _get_label_for_model(mid, [])}
|
||||
for mid in live_ids
|
||||
]
|
||||
models_total = len(models)
|
||||
except Exception:
|
||||
logger.debug("Failed to load OpenAI Codex models from hermes_cli")
|
||||
live_ids = _read_live_provider_model_ids("openai-codex")
|
||||
for mid in _read_visible_codex_cache_model_ids():
|
||||
if mid not in live_ids:
|
||||
live_ids.append(mid)
|
||||
live_models = _models_from_live_provider_ids(pid, live_ids)
|
||||
if live_models:
|
||||
models = live_models
|
||||
models_total = len(models)
|
||||
# Nous Portal: prefer the live catalog so the providers card matches
|
||||
# the dropdown picker (#1538). Same fallback shape as the static-only
|
||||
# case below — when hermes_cli is unavailable or its lookup raises,
|
||||
|
||||
35
docs/pr-media/1807/providers-api-openai-codex.json
Normal file
35
docs/pr-media/1807/providers-api-openai-codex.json
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"id": "openai-codex",
|
||||
"display_name": "OpenAI Codex",
|
||||
"has_key": true,
|
||||
"configurable": false,
|
||||
"is_oauth": true,
|
||||
"key_source": "oauth",
|
||||
"models": [
|
||||
{
|
||||
"id": "gpt-5.5",
|
||||
"label": "GPT 5.5"
|
||||
},
|
||||
{
|
||||
"id": "gpt-5.4",
|
||||
"label": "GPT 5.4"
|
||||
},
|
||||
{
|
||||
"id": "gpt-5.4-mini",
|
||||
"label": "GPT 5.4 Mini"
|
||||
},
|
||||
{
|
||||
"id": "gpt-5.3-codex",
|
||||
"label": "GPT 5.3 Codex"
|
||||
},
|
||||
{
|
||||
"id": "gpt-5.2",
|
||||
"label": "GPT 5.2"
|
||||
},
|
||||
{
|
||||
"id": "gpt-5.3-codex-spark",
|
||||
"label": "GPT 5.3 Codex Spark"
|
||||
}
|
||||
],
|
||||
"models_total": 6
|
||||
}
|
||||
BIN
docs/pr-media/1807/providers-openai-codex-expanded.png
Normal file
BIN
docs/pr-media/1807/providers-openai-codex-expanded.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 57 KiB |
@@ -161,6 +161,56 @@ class TestGetProviders:
|
||||
config.cfg.update(old_cfg)
|
||||
config._cfg_mtime = old_mtime
|
||||
|
||||
def test_openai_codex_provider_card_prefers_live_catalog(self, monkeypatch, tmp_path):
|
||||
"""OpenAI Codex provider cards should not advertise stale static fallback models.
|
||||
|
||||
/api/models already uses hermes_cli/Codex cache discovery for Codex. The
|
||||
provider card should share that source order so rejected stale entries
|
||||
such as gpt-5.5-mini are not presented as currently available when the
|
||||
live account catalog excludes them (#1807).
|
||||
"""
|
||||
_install_fake_hermes_cli(monkeypatch)
|
||||
monkeypatch.setattr(profiles, "get_active_hermes_home", lambda: tmp_path)
|
||||
|
||||
fake_models = sys.modules["hermes_cli.models"]
|
||||
fake_models.provider_model_ids = lambda pid: (
|
||||
["gpt-5.5", "gpt-5.4", "gpt-5.4-mini", "gpt-5.3-codex", "gpt-5.2"]
|
||||
if pid == "openai-codex"
|
||||
else []
|
||||
)
|
||||
codex_home = tmp_path / "empty-codex-home"
|
||||
codex_home.mkdir()
|
||||
monkeypatch.setenv("CODEX_HOME", str(codex_home))
|
||||
|
||||
old_cfg = dict(config.cfg)
|
||||
old_mtime = config._cfg_mtime
|
||||
config.cfg.clear()
|
||||
config.cfg["model"] = {"provider": "openai-codex", "default": "gpt-5.5"}
|
||||
config.cfg["providers"] = {}
|
||||
try:
|
||||
config._cfg_mtime = config.Path(config._get_config_path()).stat().st_mtime
|
||||
except Exception:
|
||||
config._cfg_mtime = 0.0
|
||||
|
||||
from api.providers import get_providers
|
||||
try:
|
||||
result = get_providers()
|
||||
codex = next(p for p in result["providers"] if p["id"] == "openai-codex")
|
||||
model_ids = [m["id"] for m in codex["models"]]
|
||||
assert model_ids == [
|
||||
"gpt-5.5",
|
||||
"gpt-5.4",
|
||||
"gpt-5.4-mini",
|
||||
"gpt-5.3-codex",
|
||||
"gpt-5.2",
|
||||
]
|
||||
assert "gpt-5.5-mini" not in model_ids
|
||||
assert codex["models_total"] == len(model_ids)
|
||||
finally:
|
||||
config.cfg.clear()
|
||||
config.cfg.update(old_cfg)
|
||||
config._cfg_mtime = old_mtime
|
||||
|
||||
|
||||
class TestSetProviderKey:
|
||||
"""Unit tests for set_provider_key() function."""
|
||||
|
||||
Reference in New Issue
Block a user