litellm/tests/unit/proxy/management_endpoints
Mateo Wang 6cdb9959df
feat(router): opt in to non-chat deployment filtering (#46257)
* feat(proxy): reject chat routes on models declared non-chat via model_info.supported_endpoints

A model whose every deployment sets a non-chat model_info.mode and a supported_endpoints list with no chat endpoint now answers /v1/chat/completions, /v1/messages and /v1/responses with a 400 before any provider call. Models without both fields keep today's behavior.

* fix(proxy): let fallbacks answer and cover more chat routes in the non-chat model check

The check now steps aside when a request, key, team or router fallback would answer, skips such models in the rate-limit fallback loop, ignores mode and supported_endpoints copied from the cost map by old Admin UI saves, treats a blank mode as unset, and also covers /v1/completions, the Responses WebSocket, Gemini generateContent and /v1beta/interactions

* fix(proxy): only step aside for fallbacks that can answer chat, gate the Responses WebSocket after alias resolution, and compare declarations to the loaded catalog

* fix(proxy): gate the Responses WebSocket with the router after aliases resolve, and ignore client-set internal fallback flags

* fix(proxy): walk fallback groups breadth first and release reservations on a rejected WebSocket

Each fallback group is looked up once however often the request repeats it, and a WebSocket closed by the endpoint gate runs the failure hook so rate-limit reservations are released

* fix(proxy): walk fallback layers without recursion and gate the compact Responses route

The fallback walk now folds one layer at a time, so the recursion check passes, and /v1/responses/compact on a model declared non-chat gets the same 400 as the other chat-shaped routes

* fix(proxy): keep chat on rows whose cost map entry serves chat

A row that carries the cost map key of an entry that serves chat counts as declaring nothing, so a catalog edit that adds a chat path never turns old Admin UI copies into 400s

* fix(proxy): check chat sent to a deployment id or backend model name

* fix(proxy): check a model the read-through loads from the database

* fix(proxy): step aside for fallbacks the check cannot follow and wildcards that serve a backend name

A fallback target with no deployments of its own, a client routing stamp, and a wildcard that does not match the requested backend name no longer turn a working request into a 400

* fix(proxy): ignore a client model_group that is not a string when building rate-limit headers

A client metadata.model_group sent as an int or a list crashed the error handler with a 500 once the embedding-only check rejected the call before routing. The header helper now treats a non-string stamp as no model group. Drops the pattern clause in the backend-name lookup, since the group lookup already returns wildcard matches. Adds the third audit round's routing-stamp cells.

* fix(proxy): keep a non-string client model_group out of spend rows

* fix(proxy): validate standard fallbacks before the typed fallback-group lookup

* feat(router): opt in to non-chat deployment filtering

* fix(router): skip unresolved local rate-limit fallbacks

* fix(router): ignore caller-provided endpoint selector values

* fix(router): normalize declared chat endpoint prefixes

* test(router): cover preflight error-value behavior

* test(router): derive replay metadata defaults from model info

* fix(router): preserve fallback aliases and check synchronous text calls

* test(routing): rewrite the WebSocket model with a pre-call callback, since main no longer runs guardrails at socket admission

* test(routing): keep the endpoint gate's owned proxies on the worker's database

* fix(router): keep the endpoint gate on model_info patches that omit it and on same-group stream retries

A partial PATCH of model_info reset a stored enforce_supported_endpoints true back to false, because the
field defaulted to False and the update merges model_dump(exclude_none=True). The field now defaults to None
so an omitted flag keeps the stored value

The same-group retry of a stream dropped before content called the provider without the endpoint selection
context, so it could land on an enforced embedding-only deployment of the same group. It now runs inside
endpoint_selection like every other router attempt

* fix(router): probe rate-limit fallbacks through get_routable_deployments so the router surface does not grow

Main's router fence lets code outside the router use only listed Router members and
router_utils modules. The proxy's fallback probe now calls the listed
get_routable_deployments with the request's call type, and the gate's 400 moves to
litellm.exceptions as EndpointNotSupportedByModelError. It stays separate from main's
UnsupportedEndpointError, which the router retries on the group's other deployments,
while the gate refuses the whole group

* test(responses): cover the WebSocket error frame for a model that refuses the endpoint

* fix(proxy): let the rate-limit fallback probe try a fallback this worker has not loaded yet

The probe now skips a fallback only when the endpoint check removed every deployment it has, so a model added on another worker still reaches route_request and its database lookup

* fix(proxy): keep key router settings off the Responses WebSocket, read unrooted or single-string endpoint lists, and add status to the refusal frame

* fix(router): warn when enforce_supported_endpoints has no usable list and match chat endpoints regardless of case, trailing slash, or Gemini path

* test(router): type the load-warning test's caplog and router

* test(routing): match the endpoint gate's integration tests to base fallback behavior on unloaded fallbacks and the Responses WebSocket

---------

Co-authored-by: Mateo <mateo@Mateos-MBP-2.localdomain>
2026-10-29 08:33:36 -07:00
..
management_v1 feat(ui): sort budgets by reset duration (#48107) 2026-10-23 16:21:53 -07:00
policy_endpoints refactor(types): replace Any with proven types in 14 files (#48928) 2026-10-29 07:26:07 -07:00
scim fix(scim)!: delete a group through the team delete's bulk path instead of one member at a time (#47544) 2026-10-21 00:59:23 +00:00
search_endpoints feat(auth): deny search tools by default when search_tool_deny_by_default is set (#44490) 2026-10-06 12:50:26 -07:00
sso fix(proxy): route SSO token exchange and userinfo calls through litellm's httpx client (#46547) 2026-10-15 15:14:25 -07:00
usage_endpoints feat(ui): unify gateway and usage assistance as Aria Agent (#48082) 2026-10-23 20:24:19 +00:00
__init__.py ci: move tests/proxy_unit_tests to tests/unit/proxy and run the proxy-db shards from litellm-tests (#42903) 2026-09-24 22:59:11 +00:00
jwt_key_mapping_doubles.py test(proxy): move management_endpoints, management_helpers and guardrails tests into tests/unit/proxy (#44003) 2026-10-01 10:52:03 -07:00
test_access_group_endpoints.py feat(access-groups): grant Claude Code skills through access groups (#46294) 2026-10-14 23:18:50 +00:00
test_access_group_management.py test(proxy): move management_endpoints, management_helpers and guardrails tests into tests/unit/proxy (#44003) 2026-10-01 10:52:03 -07:00
test_activity_tenant_scoping.py feat(proxy): bounded daily activity routes for all usage entities (#43408) 2026-10-01 16:57:23 -07:00
test_auto_router_endpoints.py refactor(router): fence the router surface and document the router-core boundary (#48839) 2026-10-29 00:01:52 +00:00
test_budget_endpoints.py feat(proxy): per-model team member budgets with router fallback (#43887) 2026-10-10 20:33:55 +00:00
test_cache_settings_endpoints.py refactor(proxy): expose public names for private proxy helpers (#45170) 2026-10-07 18:59:27 -07:00
test_callback_management_endpoints.py feat(otel): let team and key Arize callbacks choose the OTLP transport (#44492) 2026-10-06 14:46:50 -05:00
test_common_daily_activity.py fix(proxy)!: return provider-matching 4xx for the LIT-8062 status code follow-ups (#45537) 2026-10-13 11:42:39 -07:00
test_common_utils.py feat(proxy): per-model team member budgets with router fallback (#43887) 2026-10-10 20:33:55 +00:00
test_compliance_endpoints.py test(proxy): move management_endpoints, management_helpers and guardrails tests into tests/unit/proxy (#44003) 2026-10-01 10:52:03 -07:00
test_config_override_endpoints.py refactor(proxy): expose public names for private proxy helpers (#45170) 2026-10-07 18:59:27 -07:00
test_coordination_redis_endpoints.py refactor(proxy): expose public names for private proxy helpers (#45170) 2026-10-07 18:59:27 -07:00
test_cost_estimate_endpoint.py test(proxy): move management_endpoints, management_helpers and guardrails tests into tests/unit/proxy (#44003) 2026-10-01 10:52:03 -07:00
test_cost_tracking_settings.py feat(cost): support provider/model-pattern keys in cost_discount_config (#43335) 2026-10-12 14:59:18 -07:00
test_credential_migration.py refactor(proxy): expose public names for private proxy helpers (#45170) 2026-10-07 18:59:27 -07:00
test_customer_budget.py test(proxy): move management_endpoints, management_helpers and guardrails tests into tests/unit/proxy (#44003) 2026-10-01 10:52:03 -07:00
test_customer_endpoints.py fix(proxy)!: paginate customer lists and usage filters (#48700) 2026-10-27 19:46:06 -07:00
test_daily_activity_routes.py feat(daily-activity): per-guardrail spend breakdown in user, team and organization daily activity (#48702) 2026-10-28 15:35:08 -07:00
test_delete_callbacks_endpoint.py fix(security): remove the publicly known master key from the repo (#44718) 2026-10-06 10:55:24 -07:00
test_delete_verification_tokens_failed.py refactor(proxy): expose public names for private proxy helpers (#45170) 2026-10-07 18:59:27 -07:00
test_encryption_endpoints.py test: migrate tests/proxy_behavior into integration and unit tiers (#45939) 2026-10-11 08:28:42 -07:00
test_entraid_app_roles.py test(proxy): move management_endpoints, management_helpers and guardrails tests into tests/unit/proxy (#44003) 2026-10-01 10:52:03 -07:00
test_gateway_request_endpoints.py feat(proxy): track failed requests by HTTP status and caller (#45244) 2026-10-09 14:27:56 -07:00
test_id_jag_assertion_capture.py feat(sso): retain the SAML assertion at login as the saml2 subject token for oauth2_id_jag (#46745) 2026-10-16 12:16:56 -07:00
test_internal_user_endpoints.py fix(proxy)!: stop labelling management and health rejections as auth failures (#48739) 2026-10-28 21:49:03 -07:00
test_jwt_key_mapping.py fix(security): remove the publicly known master key from the repo (#44718) 2026-10-06 10:55:24 -07:00
test_key_budget_change.py fix(proxy)!: gate key budget_duration and budget_id updates like max_budget (#47681) 2026-10-26 16:45:35 -07:00
test_key_generate_prisma.py fix(auth): return a generic 401 for an unknown key (#39787) 2026-10-15 01:05:25 -07:00
test_key_management_endpoints.py fix(proxy)!: stop labelling management and health rejections as auth failures (#48739) 2026-10-28 21:49:03 -07:00
test_management_route_coverage.py test: migrate tests/proxy_behavior into integration and unit tiers (#45939) 2026-10-11 08:28:42 -07:00
test_mcp_connector_import.py feat(mcp)!: disable stdio MCP servers by default (#44066) 2026-10-02 10:28:04 -07:00
test_mcp_management_endpoints.py refactor(mcp): drop the experimental label from the MCP server and client paths (#48513) 2026-10-27 17:47:50 +00:00
test_mcp_servers.py refactor(mcp): drop the experimental label from the MCP server and client paths (#48513) 2026-10-27 17:47:50 +00:00
test_model_insights_endpoints.py fix(proxy): bound daily spend rollup row-lock waits with lock_timeout and requeue 55P03 (#44450) 2026-10-06 17:38:55 -05:00
test_model_management_endpoints.py feat(router): opt in to non-chat deployment filtering (#46257) 2026-10-29 08:33:36 -07:00
test_org_admin_team_access.py refactor(proxy): expose public names for private proxy helpers (#45170) 2026-10-07 18:59:27 -07:00
test_organization_endpoints.py fix(proxy)!: stop labelling management and health rejections as auth failures (#48739) 2026-10-28 21:49:03 -07:00
test_password_endpoints.py test(proxy): move management_endpoints, management_helpers and guardrails tests into tests/unit/proxy (#44003) 2026-10-01 10:52:03 -07:00
test_policy_endpoints.py refactor(proxy): expose public names for private proxy helpers (#45170) 2026-10-07 18:59:27 -07:00
test_project_org_authz.py test(proxy): move management_endpoints, management_helpers and guardrails tests into tests/unit/proxy (#44003) 2026-10-01 10:52:03 -07:00
test_prompt_cache_prediction.py refactor(proxy): expose public names for private proxy helpers (#45170) 2026-10-07 18:59:27 -07:00
test_prompt_caching_requests.py test(proxy): move management_endpoints, management_helpers and guardrails tests into tests/unit/proxy (#44003) 2026-10-01 10:52:03 -07:00
test_ptu_consumption.py fix(router): serve a team's wildcard deployment before a proxy-wide wildcard (#48490) 2026-10-26 17:06:09 -07:00
test_ptu_model_settings.py fix(ui): persist model parameter deletions after refresh (#48456) 2026-10-26 18:50:12 -07:00
test_request_error_endpoints.py feat(proxy): track failed requests by HTTP status and caller (#45244) 2026-10-09 14:27:56 -07:00
test_roi_calculator_endpoints.py feat(roi): measure shipping velocity, quality, and recorded spend (#44426) 2026-10-03 23:07:34 +00:00
test_router_settings_endpoints.py fix(security): remove the publicly known master key from the repo (#44718) 2026-10-06 10:55:24 -07:00
test_saml_sso.py refactor(mcp): drop the experimental label from the MCP server and client paths (#48513) 2026-10-27 17:47:50 +00:00
test_session_endpoints.py refactor(proxy): expose public names for private proxy helpers (#45170) 2026-10-07 18:59:27 -07:00
test_sso_helper_utils.py test: move whole-unit legacy test files into tests/unit and delete dead skips (#44807) 2026-10-07 05:02:28 +00:00
test_tag_management_endpoints.py feat(proxy): map baggage values to budget tags (#47358) 2026-10-20 09:09:42 +00:00
test_team_admin_field_permissions.py feat(proxy): let proxy admins open team metadata to team admins, keeping proxy settings with proxy admins (#46506) 2026-10-14 23:51:44 +00:00
test_team_callback_endpoints.py feat(otel): let a team or key excluded_services override the global setting for its OTel v2 destination (#45880) 2026-10-12 19:25:52 -04:00
test_team_default_params.py fix(security): remove the publicly known master key from the repo (#44718) 2026-10-06 10:55:24 -07:00
test_team_endpoints.py fix(proxy)!: stop labelling management and health rejections as auth failures (#48739) 2026-10-28 21:49:03 -07:00
test_team_model_alias_merge.py refactor(proxy): expose public names for private proxy helpers (#45170) 2026-10-07 18:59:27 -07:00
test_tool_management_endpoints.py test(proxy): move management_endpoints, management_helpers and guardrails tests into tests/unit/proxy (#44003) 2026-10-01 10:52:03 -07:00
test_ui_sso.py feat(proxy): let a Claude Code gateway user choose the session team (#49001) 2026-10-29 03:47:27 -07:00
test_workflow_management_endpoints.py test(proxy): move management_endpoints, management_helpers and guardrails tests into tests/unit/proxy (#44003) 2026-10-01 10:52:03 -07:00