diff --git a/litellm/router.py b/litellm/router.py index 9cde292657c..8f2397173d3 100644 --- a/litellm/router.py +++ b/litellm/router.py @@ -4490,7 +4490,15 @@ class Router: self._update_kwargs_with_deployment(deployment=deployment, kwargs=kwargs, function_name=function_name) data: Final = deployment["litellm_params"].copy() - model_name: Final = data["model"] + deployment_model_name: Final = data["model"] + # Wildcard deployments provide provider credentials but must keep + # the concrete model requested by the caller. Passing the wildcard + # through prevents model-cost lookups and Responses API bridging. + model_name = ( + model + if "*" in deployment_model_name and "*" not in model + else deployment_model_name + ) self.total_calls[model_name] += 1 self._add_deployment_model_to_endpoint_for_llm_passthrough_route( diff --git a/tests/router_unit_tests/test_router_wildcard_model.py b/tests/router_unit_tests/test_router_wildcard_model.py new file mode 100644 index 00000000000..c643d0f8237 --- /dev/null +++ b/tests/router_unit_tests/test_router_wildcard_model.py @@ -0,0 +1,36 @@ +from unittest.mock import AsyncMock +from unittest.mock import patch + +import pytest + +from litellm import Router + + +@pytest.mark.asyncio +async def test_wildcard_deployment_preserves_requested_model() -> None: + """Provider wildcard credentials must not replace the concrete request model.""" + router = Router(model_list=[]) + deployment = { + "model_name": "openai/*", + "litellm_params": {"model": "openai/*", "api_key": "sk-test"}, + "model_info": {"id": "wildcard-deployment"}, + } + original_function = AsyncMock(return_value="response") + + with ( + patch.object( + router, + "async_get_available_deployment", + new=AsyncMock(return_value=deployment), + ), + patch.object(router, "async_routing_strategy_pre_call_checks", new=AsyncMock()), + patch.object(router, "_get_client", return_value=None), + ): + result = await router._ageneric_api_call_with_fallbacks_helper( + model="openai/gpt-5.3-codex", + original_generic_function=original_function, + messages=[{"role": "user", "content": "ping"}], + ) + + assert result == "response" + assert original_function.await_args.kwargs["model"] == "openai/gpt-5.3-codex"