From b2e1bac1492ad9b435b8816a328cc7d6a5eb5fbc Mon Sep 17 00:00:00 2001 From: keyos Date: Mon, 18 May 2026 19:28:46 +0000 Subject: [PATCH] fix(config): keep anonymous custom endpoints in picker when /v1/models probe fails When an anonymous custom endpoint (bare base_url, not a named custom_providers[] entry) fails its /v1/models probe, the provider group was silently dropped from the model picker entirely. This made the endpoint unusable even when /v1/chat/completions would work fine. The fix adds an elif branch: if pid == 'custom', a cfg_base_url is configured, but no models were returned by the probe, the group is still added with an empty model list. Users can then select the Custom group and type a model ID manually in the picker's free-form input. Closes #2542. --- api/config.py | 12 +++++++ ...est_issue2542_anonymous_custom_endpoint.py | 33 +++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 tests/test_issue2542_anonymous_custom_endpoint.py diff --git a/api/config.py b/api/config.py index 0dbc462a..103a47ef 100644 --- a/api/config.py +++ b/api/config.py @@ -3807,6 +3807,18 @@ def get_available_models() -> dict: "models": models_for_group, } ) + elif pid == "custom" and cfg_base_url: + # Anonymous custom endpoint: /v1/models probe may have + # failed (e.g. llama-server, lightweight relay), but the + # chat endpoint itself may still work. Add the group + # with an empty model list so the user can type a model + # ID manually rather than being blocked by a silent + # probe failure (#2542). + groups.append({ + "provider": provider_name, + "provider_id": pid, + "models": [], + }) else: if default_model: label = _get_label_for_model(default_model, groups) diff --git a/tests/test_issue2542_anonymous_custom_endpoint.py b/tests/test_issue2542_anonymous_custom_endpoint.py new file mode 100644 index 00000000..c1b42ec3 --- /dev/null +++ b/tests/test_issue2542_anonymous_custom_endpoint.py @@ -0,0 +1,33 @@ +"""Tests for anonymous custom endpoint fallback in get_available_models(). + +Verifies that when /v1/models probe fails for an anonymous custom endpoint +(configured via bare base_url, not custom_providers[]), the provider group +is still added to the picker with an empty model list so the user can type +a model ID manually (#2542). +""" + +import re + +REPO = __file__.rsplit("/", 2)[-3] if "/" in __file__ else "." +CONFIG_PY = open(f"{REPO}/api/config.py").read() if REPO != "." else "" + + +def test_custom_anonymous_endpoint_empty_models_fallback_in_get_available_models(): + """get_available_models() must add a 'custom' provider group with empty + models when cfg_base_url is set but the /v1/models probe returned nothing + (anonymous endpoint — no match in custom_providers[]).""" + assert 'elif pid == "custom" and cfg_base_url:' in CONFIG_PY, ( + "Anonymous custom endpoints with failed /v1/models probe must get " + "an empty-model fallback group instead of being silently dropped (#2542)" + ) + # Verify the empty models dict is correct + assert '"models": []' in CONFIG_PY.split('elif pid == "custom" and cfg_base_url:')[1].split("groups.append")[1][:200], ( + "The fallback group must have an empty models list" + ) + + +def test_revert_custom_endpoint_fallback_comment(): + """The #2542 comment should reference the issue.""" + assert "#2542" in CONFIG_PY, ( + "The fallback should reference the issue number for traceability" + )