feat(proxy): add budget_exceeded_status_code setting to restore 429 for budget refusals

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
yassin 2026-09-20 07:00:10 +00:00
parent b7e11546b5
commit bf804f5188
3 changed files with 8 additions and 1 deletions

View file

@ -400,6 +400,7 @@ default_redis_batch_cache_expiry: Optional[float] = None
model_alias_map: Dict[str, str] = {} model_alias_map: Dict[str, str] = {}
model_group_settings: Optional["ModelGroupSettings"] = None model_group_settings: Optional["ModelGroupSettings"] = None
max_budget: float = 0.0 # set the max budget across all providers max_budget: float = 0.0 # set the max budget across all providers
budget_exceeded_status_code: int = 422 # set to 429 to restore the pre-422 budget_exceeded response code
budget_duration: Optional[str] = ( budget_duration: Optional[str] = (
None # proxy only - resets budget after fixed duration. You can set duration as seconds ("30s"), minutes ("30m"), hours ("30h"), days ("30d"). None # proxy only - resets budget after fixed duration. You can set duration as seconds ("30s"), minutes ("30m"), hours ("30h"), days ("30d").
) )

View file

@ -16,6 +16,7 @@ from typing import Any, Final
import httpx import httpx
import openai import openai
import litellm
from litellm.types.utils import LiteLLMCommonStrings from litellm.types.utils import LiteLLMCommonStrings
from litellm.types.vector_stores import VectorStoreSearchFailure from litellm.types.vector_stores import VectorStoreSearchFailure
@ -1002,7 +1003,7 @@ class BudgetExceededError(Exception):
): ):
self.current_cost = current_cost self.current_cost = current_cost
self.max_budget = max_budget self.max_budget = max_budget
self.status_code = 422 self.status_code = litellm.budget_exceeded_status_code
self.llm_provider = llm_provider or "" self.llm_provider = llm_provider or ""
self.entity_type = entity_type self.entity_type = entity_type
self.entity_id = entity_id self.entity_id = entity_id

View file

@ -1404,6 +1404,11 @@ class TestBudgetExceededErrorSurfacesUnifiedFields:
assert "Current cost: 0.000109" in e.message assert "Current cost: 0.000109" in e.message
assert "Max budget: 0.0001" in e.message assert "Max budget: 0.0001" in e.message
def test_should_honor_budget_exceeded_status_code_override(self, monkeypatch: pytest.MonkeyPatch):
monkeypatch.setattr(litellm, "budget_exceeded_status_code", 429)
e = litellm.BudgetExceededError(current_cost=0.5, max_budget=0.1)
assert e.status_code == 429
def test_should_still_be_catchable_as_exception_not_rate_limit_error(self): def test_should_still_be_catchable_as_exception_not_rate_limit_error(self):
# Critical: we deliberately did NOT make BudgetExceededError a # Critical: we deliberately did NOT make BudgetExceededError a
# RateLimitError subclass. Existing `except BudgetExceededError:` # RateLimitError subclass. Existing `except BudgetExceededError:`