mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-06 08:16:43 +00:00
fix(prometheus): keep team alias and team wildcard names out of the other bucket
This commit is contained in:
parent
3b3099d78d
commit
fc091c1248
2 changed files with 50 additions and 4 deletions
|
|
@ -169,10 +169,11 @@ def _get_proxy_llm_router() -> Router | None:
|
|||
def _bounded_requested_model_label(requested_model: str | None) -> str | None:
|
||||
"""
|
||||
Bound ``requested_model`` label cardinality: names the router recognizes
|
||||
(model names, deployment ids, aliases, routing groups) or matches via a
|
||||
wildcard/pattern route keep their own label value; any other
|
||||
client-supplied string collapses into the single ``other`` bucket. With no
|
||||
router to vouch for the string, it also collapses to ``other``.
|
||||
(model names, deployment ids, aliases, routing groups, team public model
|
||||
names) or matches via a global or team wildcard/pattern route keep their
|
||||
own label value; any other client-supplied string collapses into the
|
||||
single ``other`` bucket. With no router to vouch for the string, it also
|
||||
collapses to ``other``.
|
||||
"""
|
||||
if not requested_model:
|
||||
return requested_model
|
||||
|
|
@ -181,8 +182,15 @@ def _bounded_requested_model_label(requested_model: str | None) -> str | None:
|
|||
return UNRECOGNIZED_REQUESTED_MODEL_LABEL
|
||||
if llm_router.is_recognized_model(requested_model):
|
||||
return requested_model
|
||||
if requested_model in llm_router.team_public_model_names:
|
||||
return requested_model
|
||||
if llm_router.pattern_router.route(requested_model) is not None:
|
||||
return requested_model
|
||||
if any(
|
||||
team_pattern_router.route(requested_model) is not None
|
||||
for team_pattern_router in llm_router.team_pattern_routers.values()
|
||||
):
|
||||
return requested_model
|
||||
return UNRECOGNIZED_REQUESTED_MODEL_LABEL
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -58,6 +58,24 @@ def router():
|
|||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def team_router():
|
||||
return litellm.Router(
|
||||
model_list=[
|
||||
{
|
||||
"model_name": "team-internal-gpt",
|
||||
"litellm_params": {"model": "openai/gpt-4o-mini", "api_key": "fake-key"},
|
||||
"model_info": {"team_id": "team-1", "team_public_model_name": "team-alias-gpt"},
|
||||
},
|
||||
{
|
||||
"model_name": "team-internal-bedrock",
|
||||
"litellm_params": {"model": "openai/*", "api_key": "fake-key"},
|
||||
"model_info": {"team_id": "team-1", "team_public_model_name": "team-models/*"},
|
||||
},
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def _requested_model_values(metric) -> set[str]:
|
||||
index = metric._labelnames.index("requested_model")
|
||||
return {sample_key[index] for sample_key in metric._metrics}
|
||||
|
|
@ -118,6 +136,26 @@ async def test_known_alias_and_wildcard_models_keep_their_own_labels(router):
|
|||
}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_team_alias_and_team_wildcard_models_keep_their_own_labels(team_router):
|
||||
logger = PrometheusLogger()
|
||||
|
||||
with patch("litellm.proxy.proxy_server.llm_router", team_router, create=True): # test-quality-ok: production reads proxy_server.llm_router lazily, no injection seam
|
||||
await _fire_proxy_failure(logger, "team-alias-gpt")
|
||||
await _fire_proxy_failure(logger, "team-models/gpt-4o-audio-preview")
|
||||
await _fire_proxy_failure(logger, "agent-typo-hallucinated")
|
||||
|
||||
for metric in (
|
||||
logger.litellm_proxy_failed_requests_metric,
|
||||
logger.litellm_proxy_total_requests_metric,
|
||||
):
|
||||
assert _requested_model_values(metric) == {
|
||||
"team-alias-gpt",
|
||||
"team-models/gpt-4o-audio-preview",
|
||||
UNRECOGNIZED_REQUESTED_MODEL_LABEL,
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_unknown_models_collapse_to_other_when_router_is_unavailable():
|
||||
logger = PrometheusLogger()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue