fix: expose gpt-5.5 and gpt-5.4 in OpenAI model list (#14828)

### What problem does this PR solve?

OpenAI model catalogs used in provider selection flows were missing the
latest GPT models (`gpt-5.5` and `gpt-5.4`).
Because model availability is driven by seeded catalog data
(`conf/llm_factories.json` → DB seed → API response), these models were
not selectable in the UI or `/llm/list` responses.

This PR updates and synchronizes the OpenAI catalog definitions across
configuration sources and ensures the new models are correctly exposed
through the API layer and validated in tests.

---

### Type of change

* [x] New Feature (non-breaking change which adds functionality)

---

### Changes Made

* Added `gpt-5.5` and `gpt-5.4` to OpenAI catalog definitions in:

  * `conf/llm_factories.json`
  * `conf/models/openai.json` (chat + vision support)
* Ensured consistency between DB-seeded factory config and provider
model configuration
* Updated test coverage in:

  * `test_llm_list_unit.py`

    * seeded OpenAI catalog entries
* added response-level assertion validating `/llm/list` includes both
new model IDs under OpenAI grouping

---

### Root Cause

OpenAI model listings in selection flows are generated from catalog data
seeded via `conf/llm_factories.json`.
The catalog had not been updated to include the latest GPT models,
resulting in missing availability in UI and API responses.

---

### Testing

* Created isolated test environment:

  * `python -m venv .venv-review`
  * installed `pytest`
* Ran targeted and full test suite:

  * `test_list_app_grouping_availability_and_merge`:  passed
  * Full `test_llm_list_unit.py`:  10 passed

---

### Risks / Limitations

* Adding models to the catalog does not guarantee upstream provider
availability or account entitlement.
* Environments with pre-seeded DB catalogs may require reseed or refresh
to reflect updated configuration.

---

### Notes

* Changes are minimal and scoped strictly to catalog configuration and
related test coverage.
* Ensures `/llm/list` API remains aligned with expected latest OpenAI
model availability.
* Closes #14827
This commit is contained in:
0xτensor
2026-05-12 03:03:47 -07:00
committed by GitHub
parent 45ee5ca9cd
commit 127aeac4aa
3 changed files with 61 additions and 1 deletions

View File

@@ -8,6 +8,20 @@
"rank": "999",
"url": "https://api.openai.com/v1",
"llm": [
{
"llm_name": "gpt-5.5",
"tags": "LLM,CHAT,400k,IMAGE2TEXT",
"max_tokens": 400000,
"model_type": "chat",
"is_tools": true
},
{
"llm_name": "gpt-5.4",
"tags": "LLM,CHAT,400k,IMAGE2TEXT",
"max_tokens": 400000,
"model_type": "chat",
"is_tools": true
},
{
"llm_name": "gpt-5.2-pro",
"tags": "LLM,CHAT,400k,IMAGE2TEXT",

View File

@@ -10,6 +10,22 @@
},
"class": "gpt",
"models": [
{
"name": "gpt-5.5",
"max_tokens": 400000,
"model_types": [
"chat",
"vision"
]
},
{
"name": "gpt-5.4",
"max_tokens": 400000,
"model_types": [
"chat",
"vision"
]
},
{
"name": "gpt-5.2-pro",
"max_tokens": 400000,

View File

@@ -252,6 +252,28 @@ def _load_llm_app(monkeypatch):
return module
@pytest.mark.p2
def test_openai_catalog_contains_latest_gpt_models_unit():
repo_root = Path(__file__).resolve().parents[4]
openai_provider_path = repo_root / "conf" / "llm_factories.json"
openai_model_path = repo_root / "conf" / "models" / "openai.json"
with open(openai_provider_path, "r", encoding="utf-8") as f:
factories = json.load(f)["factory_llm_infos"]
openai_factory = next(item for item in factories if item["name"] == "OpenAI")
factory_model_names = {item["llm_name"] for item in openai_factory["llm"]}
with open(openai_model_path, "r", encoding="utf-8") as f:
openai_models = json.load(f)["models"]
model_file_names = {item["name"] for item in openai_models}
for model_name in ["gpt-5.5", "gpt-5.4"]:
assert model_name in factory_model_names
assert model_name in model_file_names
@pytest.mark.p2
def test_list_app_grouping_availability_and_merge(monkeypatch):
module = _load_llm_app(monkeypatch)
@@ -262,12 +284,16 @@ def test_list_app_grouping_availability_and_merge(monkeypatch):
tenant_rows = [
_TenantLLMRow(id=1, llm_name="fast-emb", llm_factory="FastEmbed", model_type="embedding", api_key="k1", status="1"),
_TenantLLMRow(id=2, llm_name="tenant-only", llm_factory="CustomFactory", model_type="chat", api_key="k2", status="1"),
_TenantLLMRow(id=3, llm_name="gpt-5.5", llm_factory="OpenAI", model_type="chat", api_key="k3", status="1"),
_TenantLLMRow(id=4, llm_name="gpt-5.4", llm_factory="OpenAI", model_type="chat", api_key="k4", status="1"),
]
monkeypatch.setattr(module.TenantLLMService, "query", lambda **_kwargs: tenant_rows)
all_llms = [
_LLMRow(llm_name="tei-embed", fid="Builtin", model_type="embedding", status="1"),
_LLMRow(llm_name="fast-emb", fid="FastEmbed", model_type="embedding", status="1"),
_LLMRow(llm_name="gpt-5.5", fid="OpenAI", model_type="chat", status="1"),
_LLMRow(llm_name="gpt-5.4", fid="OpenAI", model_type="chat", status="1"),
_LLMRow(llm_name="not-in-status", fid="Other", model_type="chat", status="1"),
]
monkeypatch.setattr(module.LLMService, "get_all", lambda: all_llms)
@@ -281,7 +307,7 @@ def test_list_app_grouping_availability_and_merge(monkeypatch):
assert ensure_calls == ["tenant-1"]
data = res["data"]
assert {"Builtin", "FastEmbed", "CustomFactory"}.issubset(set(data.keys()))
assert {"Builtin", "FastEmbed", "CustomFactory", "OpenAI"}.issubset(set(data.keys()))
builtin = data["Builtin"][0]
assert builtin["llm_name"] == "tei-embed"
@@ -295,6 +321,10 @@ def test_list_app_grouping_availability_and_merge(monkeypatch):
assert tenant_only["llm_name"] == "tenant-only"
assert tenant_only["available"] is True
# Response-level assertion: /llm/list output includes latest OpenAI IDs.
openai_names = {item["llm_name"] for item in data["OpenAI"]}
assert {"gpt-5.5", "gpt-5.4"}.issubset(openai_names)
@pytest.mark.p2
def test_list_app_model_type_filter(monkeypatch):