diff --git a/litellm/router.py b/litellm/router.py index da04e59f18a..b44e1b38b99 100644 --- a/litellm/router.py +++ b/litellm/router.py @@ -6214,7 +6214,12 @@ class Router: ) data: Final = deployment["litellm_params"].copy() - model_name: Final = data["model"] + deployment_model_name: Final = data["model"] + 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..da9731ef2f7 --- /dev/null +++ b/tests/router_unit_tests/test_router_wildcard_model.py @@ -0,0 +1,29 @@ +from unittest.mock import AsyncMock + +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=[ + { + "model_name": "openai/*", + "litellm_params": {"model": "openai/*", "api_key": "sk-test"}, + "model_info": {"id": "wildcard-deployment"}, + } + ] + ) + original_function = AsyncMock(return_value="response") + + 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"