litellm/tests/test_litellm/router_strategy
tin-berri 8159f240c4
feat(complexity_router): plan-mode tier floor for coding-agent clients (#37230)
* feat(complexity_router): plan-mode tier floor for coding-agent clients

Claude Code and Copilot signal plan mode only through client-injected prompt
text, which the ask-extraction path deliberately strips, so the router could
never see it. Detect the sentinels on the raw wire body and route those
requests to at least plan_mode_min_tier.

The floor is raise-only and transient: classifier results above it still win,
it overrides a session-affinity pin only on turns carrying the sentinel
without rewriting the pin, and plan_mode decisions are not pinnable, so the
first turn after plan mode exits routes as if plan mode had never happened.
Classification is skipped when the floor is the top configured tier. On
adaptive routers the floor rides _soft_floor_pick as a hard_floor that
excludes below-floor candidates, closing the adaptive_eligible=all gap where
a request classified at or above the floor could still route below it.
Detection is staleness-aware: only leading system content and the newest-ask
tail count, so sentinels surviving in history after plan mode exits, built-in
or operator-supplied, never fire. Custom tier sets are supported with
severity from the tier_definitions list order, same as keyword_tier_rules.
Off by default; decisions are recorded with the new plan_mode cause and the
matched sentinel in matched_keyword

* fix(complexity_router): gate pin writes and the failure exit on sentinel presence, not the floor binding

A plan-mode turn classified at or above the floor keeps its ordinary cause,
but pinning it would carry a plan-mode-shaped choice past plan mode's exit
(on adaptive routers the hard floor constrained that pick), so no
sentinel-carrying turn writes the session pin. The default_model failure
exit is skipped for sentinel turns for the same reason: default_model's
placeholder tier can equal the floor while default_model itself sits in no
pool the floor can vouch for
2026-08-18 10:24:11 -07:00
..
adaptive_router feat(router): record why the auto-router picked a tier and show it in the logs (#35016) 2026-07-30 11:55:10 -07:00
test_auto_router.py fix(auto-router): stop the embedding model's context window from failing long requests (#35956) 2026-08-05 14:47:40 -07:00
test_base_routing_strategy.py [Fix] Fix test failures and Docker build from pinned dependency upgrade 2026-04-01 09:43:33 -07:00
test_budget_limiter_hotpath.py fix(router): enforce deployment budgets for dynamically added models (#29273) 2026-05-29 19:43:14 -07:00
test_complexity_router.py feat(complexity_router): plan-mode tier floor for coding-agent clients (#37230) 2026-08-18 10:24:11 -07:00
test_lar1_routing.py chore: litellm oss staging (#31185) 2026-06-26 09:17:44 -07:00
test_litellm_encoder.py fix(auto-router): stop the embedding model's context window from failing long requests (#35956) 2026-08-05 14:47:40 -07:00
test_lowest_latency.py test(router_strategy): cover chat-path normalization branches in both handlers 2026-07-23 08:36:48 +10:00
test_quality_router.py Fix: ComplexityRouter should not score system prompt text for code/technical complexity (#36721) 2026-08-13 11:15:14 -07:00
test_router_routing_groups.py feat(router): make routing groups callable as virtual models and list them in /v1/models (#36519) 2026-08-11 18:41:19 -07:00
test_router_routing_plugins.py feat(router): resolve auto-router routing plugins from proxy YAML config (#33251) 2026-07-14 21:27:14 -07:00
test_router_tag_regex_routing.py feat(router): add required-AND (&) tag prefix and allow_fail_open flag (#36193) 2026-08-11 11:49:18 -07:00
test_router_tag_routing.py fix(router): read no tags, instead of raising, from a non-dict metadata bucket 2026-08-13 00:45:49 +00:00
test_savings_baseline.py feat(spend): derive a default auto-router savings baseline from the hardest tier (#35907) 2026-08-04 22:36:45 -07:00