From d5951c174df762df0e8b669dd724af6c15e35c9d Mon Sep 17 00:00:00 2001 From: ryder777777 Date: Fri, 23 Oct 2026 21:08:33 +0000 Subject: [PATCH] fix(router): annotate fallback as Final[ModelMapInfo] and add unit coverage (#47922) --- litellm/router.py | 2 +- .../test_router_model_not_mapped_fallback.py | 48 +++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 tests/unit/test_router_model_not_mapped_fallback.py diff --git a/litellm/router.py b/litellm/router.py index 052498f43d6..3795c426582 100644 --- a/litellm/router.py +++ b/litellm/router.py @@ -12207,7 +12207,7 @@ class Router: model_info_name, e, ) - fallback: ModelMapInfo = { + fallback: Final[ModelMapInfo] = { "key": model_info_name, "max_tokens": None, "max_input_tokens": None, diff --git a/tests/unit/test_router_model_not_mapped_fallback.py b/tests/unit/test_router_model_not_mapped_fallback.py new file mode 100644 index 00000000000..95161dc879c --- /dev/null +++ b/tests/unit/test_router_model_not_mapped_fallback.py @@ -0,0 +1,48 @@ +from typing import Final +from unittest.mock import patch + +import pytest + +import litellm +from litellm.exceptions import ModelNotMappedError +from litellm.router import Router + + +def test_get_router_model_info_returns_fallback_on_model_not_mapped_error() -> None: + router: Final = Router( + model_list=[ + { + "model_name": "mcp-stdio-group", + "litellm_params": { + "model": "openai/unmapped-mcp-stdio-model", + "api_key": "test-key", + }, + } + ] + ) + + with patch.object( + litellm, + "get_model_info", + side_effect=ModelNotMappedError(message="Model 'unmapped-mcp-stdio-model' is not mapped", model="unmapped-mcp-stdio-model"), + ): + info: Final = router.get_router_model_info(model="mcp-stdio-group") + + assert info is not None + assert info["max_tokens"] is None + assert info["max_input_tokens"] is None + assert info["max_output_tokens"] is None + assert info["input_cost_per_token"] == 0 + assert info["output_cost_per_token"] == 0 + assert info["litellm_provider"] == "openai" + assert info["mode"] == "chat" + + +def test_get_router_model_info_reraises_unrelated_exceptions() -> None: + router: Final = Router(model_list=[]) + + with ( + patch.object(litellm, "get_model_info", side_effect=RuntimeError("unexpected failure")), + pytest.raises(RuntimeError, match="unexpected failure"), + ): + router.get_router_model_info(model="any-model")