fix(prometheus): bound non-string model values on failed requests

A numeric, list or dict model with no deployment behind the call skipped the bounding and became its own label value. Send every such value through the same helper so they collapse into the shared other series.

Signed-off-by: Denel John <denelbjohn18@gmail.com>
This commit is contained in:
Denel John 2026-10-16 16:22:24 -04:00
parent 8c297d232b
commit 32c15b5478
2 changed files with 14 additions and 3 deletions

View file

@ -2617,9 +2617,9 @@ class PrometheusLogger(CustomLogger):
# With no deployment behind the call, the name is whatever the caller sent (for example a model the
# key may not use). Bound it like ``requested_model`` so unknown names share one series.
model: Final = (
_bounded_requested_model_label(requested_name, router_originated=True)
if not deployment_model_id and isinstance(requested_name, str)
else requested_name
requested_name
if deployment_model_id
else _bounded_requested_model_label(requested_name, router_originated=True) # pyright: ignore[reportUnknownArgumentType] # caller-supplied value, the helper type-checks it
)
litellm_params: Final = kwargs.get("litellm_params", {}) or {}

View file

@ -360,3 +360,14 @@ async def test_sdk_failures_without_proxy_router_keep_their_model_label_on_llm_a
await _fire_llm_api_failure(logger, "gpt-4o-mini")
assert _model_label_values(logger.litellm_llm_api_failed_requests_metric) == {"gpt-4o-mini"}
@pytest.mark.asyncio
@pytest.mark.parametrize("model", [123, 4.5, ["gpt-4o-mini"], {"name": "gpt-4o-mini"}])
async def test_non_string_denied_models_collapse_to_other_on_llm_api_failed_requests_metric(router, model: object):
logger = PrometheusLogger()
with patch("litellm.proxy.proxy_server.llm_router", router, create=True): # test-quality-ok: production reads proxy_server.llm_router lazily, no injection seam
await _fire_llm_api_failure(logger, model) # type: ignore[arg-type]
assert _model_label_values(logger.litellm_llm_api_failed_requests_metric) == {UNRECOGNIZED_REQUESTED_MODEL_LABEL}