fix(logging): fallback to bare model name on provider mismatch in model cost lookup (closes #47675)

This commit is contained in:
Surender Gulia 2026-10-28 11:25:10 +00:00
parent 1176e608b1
commit 59a48b3b89
2 changed files with 77 additions and 8 deletions

View file

@ -6757,7 +6757,7 @@ class StandardLoggingPayloadSetup:
model_cost_information = StandardLoggingModelInformation(model_map_key="", model_map_value=None)
else:
try:
_model_cost_information: Final = litellm.get_model_info(
_model_cost_information = litellm.get_model_info(
model=pricing_model_name or model_cost_name,
custom_llm_provider=custom_llm_provider,
api_base=api_base,
@ -6767,13 +6767,30 @@ class StandardLoggingPayloadSetup:
model_map_value=_model_cost_information,
)
except Exception:
verbose_logger.debug( # keep in debug otherwise it will trigger on every call
"Model=%s is not mapped in model cost map. Defaulting to None model_cost_information for standard_logging_payload",
model_cost_name,
)
model_cost_information = StandardLoggingModelInformation(
model_map_key=model_cost_name, model_map_value=None
)
# Fallback: if provider mismatch lookup fails, try bare model name
_model_cost_information = None
if custom_llm_provider is not None:
try:
_model_cost_information = litellm.get_model_info(
model=pricing_model_name or model_cost_name,
api_base=api_base,
)
except Exception:
_model_cost_information = None
if _model_cost_information is not None:
model_cost_information = StandardLoggingModelInformation(
model_map_key=model_cost_name,
model_map_value=_model_cost_information,
)
else:
verbose_logger.debug( # keep in debug otherwise it will trigger on every call
"Model=%s is not mapped in model cost map. Defaulting to None model_cost_information for standard_logging_payload",
model_cost_name,
)
model_cost_information = StandardLoggingModelInformation(
model_map_key=model_cost_name, model_map_value=None
)
return model_cost_information
@staticmethod

View file

@ -0,0 +1,52 @@
"""
Regression test for Issue #47675:
Verifies that get_model_cost_information falls back to bare model name lookup
when deployment custom_llm_provider does not match the provider key in model pricing map.
"""
import pytest
import litellm
from litellm.litellm_core_utils.litellm_logging import StandardLoggingPayloadSetup
from litellm.types.utils import ModelResponse
def test_cross_key_provider_mismatch_fallback():
"""
Test that when custom_llm_provider='anthropic' is used with a model priced under
another provider (e.g., 'tencent/deepseek-v4.1-flash'), the fallback populates
model_map_value instead of silently returning None ($0 spend).
"""
setup = StandardLoggingPayloadSetup()
model = "tencent/deepseek-v4.1-flash"
mock_response = ModelResponse(model=model)
info = setup.get_model_cost_information(
base_model=model,
custom_pricing=False,
custom_llm_provider="anthropic",
init_response_obj=mock_response,
)
assert info.get("model_map_key") == model
assert info.get("model_map_value") is not None
assert info["model_map_value"].get("litellm_provider") == "tencent"
assert info["model_map_value"].get("input_cost_per_token") == 3e-07
def test_unmapped_model_safely_returns_none():
"""
Test that an unknown model that does not exist in the pricing map
safely returns model_map_value=None without raising unhandled exceptions.
"""
setup = StandardLoggingPayloadSetup()
fake_model = "fake_provider/completely_non_existent_model_xyz"
mock_response = ModelResponse(model=fake_model)
info = setup.get_model_cost_information(
base_model=fake_model,
custom_pricing=False,
custom_llm_provider="anthropic",
init_response_obj=mock_response,
)
assert info.get("model_map_key") == fake_model
assert info.get("model_map_value") is None