From 95ac678c75cf04c90240e6bfd4fd0418cf946cf7 Mon Sep 17 00:00:00 2001 From: ishaan-j-berri Date: Sat, 31 Oct 2026 13:35:07 -0700 Subject: [PATCH] fix: make member budget migration retry-safe and document API fields (#49091) --- .../20261031120000_team_member_budget_windows/migration.sql | 6 ++++-- litellm/proxy/management_endpoints/team_endpoints.py | 6 ++++++ ui/litellm-dashboard/src/lib/http/schema.d.ts | 6 ++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/litellm-proxy-extras/litellm_proxy_extras/migrations/20261031120000_team_member_budget_windows/migration.sql b/litellm-proxy-extras/litellm_proxy_extras/migrations/20261031120000_team_member_budget_windows/migration.sql index 89b4b2f8578..800ec783c32 100644 --- a/litellm-proxy-extras/litellm_proxy_extras/migrations/20261031120000_team_member_budget_windows/migration.sql +++ b/litellm-proxy-extras/litellm_proxy_extras/migrations/20261031120000_team_member_budget_windows/migration.sql @@ -1,2 +1,4 @@ -ALTER TABLE "LiteLLM_TeamTable" ADD COLUMN "team_member_budget_limits" JSONB; -ALTER TABLE "LiteLLM_TeamMembership" ADD COLUMN "budget_limits" JSONB; +SET LOCAL lock_timeout = '10s'; + +ALTER TABLE "LiteLLM_TeamTable" ADD COLUMN IF NOT EXISTS "team_member_budget_limits" JSONB; +ALTER TABLE "LiteLLM_TeamMembership" ADD COLUMN IF NOT EXISTS "budget_limits" JSONB; diff --git a/litellm/proxy/management_endpoints/team_endpoints.py b/litellm/proxy/management_endpoints/team_endpoints.py index 34111dea0f3..cf53f8a751e 100644 --- a/litellm/proxy/management_endpoints/team_endpoints.py +++ b/litellm/proxy/management_endpoints/team_endpoints.py @@ -1666,6 +1666,7 @@ async def new_team( - object_permission: Optional[LiteLLM_ObjectPermissionBase] - team-specific object permission. Example - {"vector_stores": ["vector_store_1", "vector_store_2"], "agents": ["agent_1", "agent_2"], "agent_access_groups": ["dev_group"]}. IF null or {} then no object permission. - team_member_budget: Optional[float] - The maximum budget allocated to an individual team member. - team_member_budget_duration: Optional[str] - The duration of the budget for the team member. Doc [here](https://docs.litellm.ai/docs/proxy/team_budgets) + - team_member_budget_limits: Optional[list] - Default concurrent spending caps for each member, e.g. [{"budget_duration": "24h", "max_budget": 20}, {"budget_duration": "30d", "max_budget": 200}]. Each window resets independently at its UTC calendar boundary. A member override replaces these defaults; an empty list disables the defaults. - team_member_model_max_budget: Optional[dict] - Per-model budgets shared by team members without an override. - team_member_rpm_limit: Optional[int] - The RPM (Requests Per Minute) limit for individual team members. - team_member_tpm_limit: Optional[int] - The TPM (Tokens Per Minute) limit for individual team members. @@ -2441,6 +2442,7 @@ async def update_team( - object_permission: Optional[LiteLLM_ObjectPermissionBase] - team-specific object permission. Example - {"vector_stores": ["vector_store_1", "vector_store_2"], "agents": ["agent_1", "agent_2"], "agent_access_groups": ["dev_group"]}. IF null or {} then no object permission. - team_member_budget: Optional[float] - The maximum budget allocated to an individual team member. - team_member_budget_duration: Optional[str] - The duration of the budget for the team member. Doc [here](https://docs.litellm.ai/docs/proxy/team_budgets) + - team_member_budget_limits: Optional[list] - Default concurrent spending caps for each member, e.g. [{"budget_duration": "24h", "max_budget": 20}, {"budget_duration": "30d", "max_budget": 200}]. Each window resets independently at its UTC calendar boundary. A member override replaces these defaults; an empty list disables the defaults. - team_member_model_max_budget: Optional[dict] - Per-model budgets shared by team members without an override. - team_member_rpm_limit: Optional[int] - The RPM (Requests Per Minute) limit for individual team members. - team_member_tpm_limit: Optional[int] - The TPM (Tokens Per Minute) limit for individual team members. @@ -3724,6 +3726,8 @@ async def team_member_add( If user doesn't exist, new user row will also be added to User Table Only proxy_admin or admin of team, allowed to access this endpoint. + + - budget_limits: Optional[list] - Concurrent caps for the added member, using budget_duration (1h, 24h, 7d, or 30d) and max_budget. Omit or send [] to inherit team defaults. ``` curl -X POST 'http://0.0.0.0:4000/team/member_add' \ @@ -4133,6 +4137,8 @@ async def team_member_update( [BETA] Update team member budgets and team member role + + - budget_limits: Optional[list] - Replace this member's concurrent spending caps. Each entry has budget_duration (1h, 24h, 7d, or 30d) and max_budget. Omit to preserve the override; send [] to restore team defaults. """ from litellm.proxy.proxy_server import ( litellm_proxy_admin_name, diff --git a/ui/litellm-dashboard/src/lib/http/schema.d.ts b/ui/litellm-dashboard/src/lib/http/schema.d.ts index 3efa1b27b6f..fd16102fb89 100644 --- a/ui/litellm-dashboard/src/lib/http/schema.d.ts +++ b/ui/litellm-dashboard/src/lib/http/schema.d.ts @@ -17023,6 +17023,8 @@ export interface paths { * If user doesn't exist, new user row will also be added to User Table * * Only proxy_admin or admin of team, allowed to access this endpoint. + * + * - budget_limits: Optional[list] - Concurrent caps for the added member, using budget_duration (1h, 24h, 7d, or 30d) and max_budget. Omit or send [] to inherit team defaults. * ``` * * curl -X POST 'http://0.0.0.0:4000/team/member_add' -H "Authorization: Bearer $LITELLM_MASTER_KEY" -H 'Content-Type: application/json' -d '{"team_id": "45e3e396-ee08-4a61-a88e-16b3ce7e0849", "member": {"role": "user", "user_id": "krrish247652@berri.ai"}}' @@ -17083,6 +17085,8 @@ export interface paths { * @description [BETA] * * Update team member budgets and team member role + * + * - budget_limits: Optional[list] - Replace this member's concurrent spending caps. Each entry has budget_duration (1h, 24h, 7d, or 30d) and max_budget. Omit to preserve the override; send [] to restore team defaults. */ post: operations["team_member_update_team_member_update_post"]; delete?: never; @@ -17230,6 +17234,7 @@ export interface paths { * - object_permission: Optional[LiteLLM_ObjectPermissionBase] - team-specific object permission. Example - {"vector_stores": ["vector_store_1", "vector_store_2"], "agents": ["agent_1", "agent_2"], "agent_access_groups": ["dev_group"]}. IF null or {} then no object permission. * - team_member_budget: Optional[float] - The maximum budget allocated to an individual team member. * - team_member_budget_duration: Optional[str] - The duration of the budget for the team member. Doc [here](https://docs.litellm.ai/docs/proxy/team_budgets) + * - team_member_budget_limits: Optional[list] - Default concurrent spending caps for each member, e.g. [{"budget_duration": "24h", "max_budget": 20}, {"budget_duration": "30d", "max_budget": 200}]. Each window resets independently at its UTC calendar boundary. A member override replaces these defaults; an empty list disables the defaults. * - team_member_model_max_budget: Optional[dict] - Per-model budgets shared by team members without an override. * - team_member_rpm_limit: Optional[int] - The RPM (Requests Per Minute) limit for individual team members. * - team_member_tpm_limit: Optional[int] - The TPM (Tokens Per Minute) limit for individual team members. @@ -17460,6 +17465,7 @@ export interface paths { * - object_permission: Optional[LiteLLM_ObjectPermissionBase] - team-specific object permission. Example - {"vector_stores": ["vector_store_1", "vector_store_2"], "agents": ["agent_1", "agent_2"], "agent_access_groups": ["dev_group"]}. IF null or {} then no object permission. * - team_member_budget: Optional[float] - The maximum budget allocated to an individual team member. * - team_member_budget_duration: Optional[str] - The duration of the budget for the team member. Doc [here](https://docs.litellm.ai/docs/proxy/team_budgets) + * - team_member_budget_limits: Optional[list] - Default concurrent spending caps for each member, e.g. [{"budget_duration": "24h", "max_budget": 20}, {"budget_duration": "30d", "max_budget": 200}]. Each window resets independently at its UTC calendar boundary. A member override replaces these defaults; an empty list disables the defaults. * - team_member_model_max_budget: Optional[dict] - Per-model budgets shared by team members without an override. * - team_member_rpm_limit: Optional[int] - The RPM (Requests Per Minute) limit for individual team members. * - team_member_tpm_limit: Optional[int] - The TPM (Tokens Per Minute) limit for individual team members.