litellm/tests/unit/router_strategy
norkelbyte 85a3e566f3
fix(router)!: name the request size when usage-based routing refuses an over-tpm request (#51838)
* fix(router)!: name the request size when usage-based routing refuses an over-tpm request

usage-based-routing-v2 answered "No deployments available" with no usage
shown when one request alone was over every deployment's tpm, and a
single-deployment group held the caller for 3 x 60 seconds on retries
that could never clear it.

The router now raises RequestOverDeploymentTpmError, a RateLimitError
that names the estimated tokens and the largest tpm limit, carries no
retry-after, skips retries, and still reaches group fallbacks.

* fix(router): count cooling deployments before refusing an over-tpm request, keep the Prometheus label

The over-tpm refusal now also reads every deployment in the model group, so a request that fits a cooling deployment keeps the old retryable 429. RequestOverDeploymentTpmError keeps the RateLimitError exception_class label in Prometheus.

* fix(router): count only cooling deployments the request can still reach, and keep the logged error class

The over-tpm refusal now reads cooling deployments from the caller's pool, kept to the ones team, region, and tag routing would still send the request to, so team models and tag-filtered requests get the right answer. Logs, OTEL, and Datadog keep naming the refusal RateLimitError like Prometheus does, and a tpm written as a number string counts as that number

* fix(router): keep the sync over-tpm refusal a ValueError and count every deployment the caller may use

The sync Router raises SyncRequestOverDeploymentTpmError, which is still a ValueError, so
existing except ValueError handlers keep catching it. The never-retryable refusal now counts
every deployment in the caller's pool that region and tag routing allow, so a deployment left
out of this pick by a budget, health check, order, or pin keeps the retryable 429

* fix(router): keep retry records and trace events naming the over-tpm refusal RateLimitError

Fallback records in previous_models and the litellm.routing.retry trace event now read the
error's logged class name, as the logging payload already did, so they keep RateLimitError for
the over-tpm refusal as they did before this change

---------

Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
2026-11-14 16:16:21 -05:00
..
adaptive_router refactor(typing): clear about 1,100 basedpyright Any errors across 303 files (#49986) 2026-11-06 13:31:15 -08:00
complexity_router feat(messages): serve anthropic messages on rust only (#51119) 2026-11-12 00:07:20 +00:00
switchyard_router feat(router): add the Switchyard stage router as an auto router strategy (#50407) 2026-11-06 12:07:57 -08:00
__init__.py test: add __init__.py to intermediate tests/unit packages 2026-09-20 12:55:27 +00:00
test_auto_router.py refactor(router): route the router family through RoutingContext and close the outside surface (#49118) 2026-10-30 19:18:54 -07:00
test_auto_router_model_naming.py feat(router): infer custom classifier tiers from model mappings (#48987) 2026-10-29 11:30:23 -07:00
test_auto_router_tuning_baseline.py refactor(router): fence the router surface and document the router-core boundary (#48839) 2026-10-29 00:01:52 +00:00
test_base_routing_strategy.py refactor(router): count the whole router_usage family on the native store (#50862) 2026-11-13 03:22:28 +00:00
test_baseline_request.py refactor(router): delete the python router core, the rust core is the only core (#50178) 2026-11-05 10:40:46 -08:00
test_budget_limiter.py fix(proxy): charge a video's provider-reported cost once, on the first poll that sees it completed (#49824) 2026-11-04 20:22:06 +00:00
test_budget_limiter_hotpath.py test(router_strategy): keep foreign asyncio task noise out of the budget limiter caplog asserts (#43375) 2026-10-29 06:22:06 -07:00
test_complexity_router.py fix: preserve routed prompt generation settings (#51702) 2026-11-13 16:00:18 -08:00
test_complexity_tier_predictor.py test: move tests/test_litellm core utils, routing, responses, caching and rust_bridge into tests/unit (#43199) 2026-09-25 17:10:13 -07:00
test_fuse_presets.py test: move tests/test_litellm core utils, routing, responses, caching and rust_bridge into tests/unit (#43199) 2026-09-25 17:10:13 -07:00
test_lar1_routing.py refactor(router): route the router family through RoutingContext and close the outside surface (#49118) 2026-10-30 19:18:54 -07:00
test_least_busy.py fix(router): a cancelled or retried attempt releases its io-token reservation and least-busy count (#50486) 2026-11-07 16:54:26 -08:00
test_litellm_encoder.py fix(router): restore four base behaviors the RoutingContext refactor changed (#49395) 2026-10-31 22:58:34 +00:00
test_llm_v2.py feat(redis): serve the router's session pins from a native store (#50870) 2026-11-13 03:22:28 +00:00
test_lowest_cost.py refactor(rust_bridge): route every Rust-to-Python call through host modules (#50822) 2026-11-11 01:57:54 +00:00
test_lowest_latency.py fix(router): keep latency routing alive when latency samples are unusable (#48216) 2026-10-24 13:43:07 -07:00
test_lowest_tpm_rpm.py refactor(router): count the whole router_usage family on the native store (#50862) 2026-11-13 03:22:28 +00:00
test_lowest_tpm_rpm_v2.py fix(router)!: name the request size when usage-based routing refuses an over-tpm request (#51838) 2026-11-14 16:16:21 -05:00
test_quality_router.py refactor(router): delete the python router core, the rust core is the only core (#50178) 2026-11-05 10:40:46 -08:00
test_router_routing_groups.py refactor(router): count the whole router_usage family on the native store (#50862) 2026-11-13 03:22:28 +00:00
test_router_routing_plugins.py refactor(router): delete the python router core, the rust core is the only core (#50178) 2026-11-05 10:40:46 -08:00
test_router_tag_regex_routing.py refactor(router): route the router family through RoutingContext and close the outside surface (#49118) 2026-10-30 19:18:54 -07:00
test_router_tag_routing.py feat(router): add the Switchyard stage router as an auto router strategy (#50407) 2026-11-06 12:07:57 -08:00
test_savings_baseline.py refactor(router): route the router family through RoutingContext and close the outside surface (#49118) 2026-10-30 19:18:54 -07:00
test_simple_shuffle.py test: move tests/test_litellm core utils, routing, responses, caching and rust_bridge into tests/unit (#43199) 2026-09-25 17:10:13 -07:00
test_stall_detector.py test: move tests/test_litellm core utils, routing, responses, caching and rust_bridge into tests/unit (#43199) 2026-09-25 17:10:13 -07:00