diff --git a/conf/llm_factories.json b/conf/llm_factories.json index 2fc12803d7..09273fe245 100644 --- a/conf/llm_factories.json +++ b/conf/llm_factories.json @@ -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", diff --git a/conf/models/openai.json b/conf/models/openai.json index c78a82b4c2..ae252fdccc 100644 --- a/conf/models/openai.json +++ b/conf/models/openai.json @@ -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, diff --git a/test/testcases/test_web_api/test_llm_app/test_llm_list_unit.py b/test/testcases/test_web_api/test_llm_app/test_llm_list_unit.py index 53a8705f31..e0442e0aa7 100644 --- a/test/testcases/test_web_api/test_llm_app/test_llm_list_unit.py +++ b/test/testcases/test_web_api/test_llm_app/test_llm_list_unit.py @@ -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):