fix(model_info): map supports_parallel_function_calling into ModelInfo

The registry key was never copied into ModelInfo, so /v1/model/info reported
null for every model, /model_group/info reported false for every group, and
litellm.supports_parallel_function_calling() returned False for provider-prefixed
entries that declare true. Copy it like every other capability flag and pin the
three surfaces with regression tests.

Resolves LIT-6340
This commit is contained in:
mateo-berri 2026-08-28 12:09:48 -07:00
parent 4d9025c2bf
commit 1c6cb6dde2
4 changed files with 49 additions and 0 deletions

View file

@ -5866,6 +5866,7 @@ def _get_model_info_helper(
supports_response_schema=_model_info.get("supports_response_schema", None),
supports_vision=_model_info.get("supports_vision", None),
supports_function_calling=_model_info.get("supports_function_calling", None),
supports_parallel_function_calling=_model_info.get("supports_parallel_function_calling", None),
supports_tool_choice=_model_info.get("supports_tool_choice", None),
supports_assistant_prefill=_model_info.get("supports_assistant_prefill", None),
supports_prompt_caching=_model_info.get("supports_prompt_caching", None),

View file

@ -128,6 +128,20 @@ def test_v1_model_info_no_model_list_error(client, auth_as, null_router, path):
assert "LLM Model List not loaded" in response.text
def test_get_proxy_model_info_surfaces_supports_parallel_function_calling(local_model_cost_map):
"""``GET /v1/model/info`` enriches each deployment through ``_get_proxy_model_info``; a registry
entry declaring parallel function calling must land in ``model_info`` instead of null."""
enriched = proxy_server._get_proxy_model_info(
model={
"model_name": "glm-5.3-flash",
"litellm_params": {"model": "together_ai/zai-org/GLM-5.3-Flash"},
"model_info": {"id": "glm-deployment", "db_model": False},
}
)
assert enriched["model_info"]["supports_parallel_function_calling"] is True
def test_v1_model_info_star_wildcard_filter_keeps_provider_expansion(monkeypatch):
from litellm.proxy._types import SpecialModelNames, UserAPIKeyAuth
from litellm.proxy.auth import model_checks

View file

@ -9051,6 +9051,25 @@ def test_model_group_info_reasoning_efforts_ignore_a_deployment_off_the_map():
assert result.supported_reasoning_efforts == ("none", "minimal", "low", "medium", "high", "max")
def test_model_group_info_surfaces_supports_parallel_function_calling(local_model_cost_map):
"""``/model_group/info`` folds each deployment's registry flags into the group; a deployment whose
registry entry declares parallel function calling must flip the group to True instead of False."""
router = litellm.Router(
model_list=[
{
"model_name": "glm-group",
"litellm_params": {"model": "together_ai/zai-org/GLM-5.3-Flash", "api_key": "fake-key"},
}
]
)
result = router._set_model_group_info(model_group="glm-group", user_facing_model_group_name="glm-group")
assert result is not None
assert result.supports_parallel_function_calling is True
def test_model_group_info_reasoning_efforts_empty_on_a_mapped_non_reasoning_deployment():
"""A group mixing a reasoning model with one the map knows is not a reasoning model shares no
level, so it advertises none and the picker offers nothing rather than a level routing would

View file

@ -120,6 +120,21 @@ def test_get_model_info_surfaces_supports_adaptive_thinking(local_model_cost_map
assert generalized["supports_adaptive_thinking"] is True
def test_get_model_info_surfaces_supports_parallel_function_calling(local_model_cost_map):
"""A registry entry's supports_parallel_function_calling must read back through get_model_info
and litellm.supports_parallel_function_calling. Regression: the key was never copied into
ModelInfo, so provider-prefixed entries read None / False even when the map said True, and an
explicit False was indistinguishable from unset."""
declared_true = litellm.get_model_info(model="together_ai/zai-org/GLM-5.3-Flash")
assert declared_true["supports_parallel_function_calling"] is True
assert litellm.supports_parallel_function_calling(model="together_ai/zai-org/GLM-5.3-Flash") is True
declared_false = litellm.get_model_info(model="o3-mini")
assert declared_false["supports_parallel_function_calling"] is False
assert litellm.supports_parallel_function_calling(model="o3-mini") is False
def test_get_model_info_surfaces_supported_endpoints(local_model_cost_map):
"""supported_endpoints ships in the cost map and is declared on ModelInfoBase,
but the constructor never copied it, so get_model_info always returned None.