Skip to content

feature: support end_user_budget alerts to slack#22279

Open
huetterma wants to merge 4 commits intoBerriAI:mainfrom
huetterma:customer-budget-alerts
Open

feature: support end_user_budget alerts to slack#22279
huetterma wants to merge 4 commits intoBerriAI:mainfrom
huetterma:customer-budget-alerts

Conversation

@huetterma
Copy link
Contributor

@huetterma huetterma commented Feb 27, 2026

Relevant issues

Expected to see slack alerts when my end_users are exceeding spend limit when they have a budget attached. But nothing happened, so went into the code to see if we already support alerting for end_users. No support for alerting currently, this addresses this.

Pre-Submission checklist

  • I have Added testing in the tests/litellm/ directory, Adding at least 1 test is a hard requirement - see details
  • My PR passes all unit tests on make test-unit
  • My PR's scope is as isolated as possible, it only solves 1 specific problem
  • I have requested a Greptile review by commenting @greptileai and received a Confidence Score of at least 4/5 before requesting a maintainer review

CI (LiteLLM team)

CI status guideline:

  • 50-55 passing tests: main is stable with minor issues.
  • 45-49 passing tests: acceptable but needs attention
  • <= 40 passing tests: unstable; be careful with your merges and assess the risk.
  • Branch creation CI run
    Link:

  • CI run for the last commit
    Link:

  • Merge / cherry-pick CI run
    Links:

Type

🆕 New Feature
🐛 Bug Fix

Changes

Introducing a end_user_budget alert to slack for alerting.

Decoupled _check_end_user_budget from get_end_user_object as they serve different functionality

@vercel
Copy link

vercel bot commented Feb 27, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
litellm Ready Ready Preview, Comment Feb 27, 2026 1:08pm

Request Review

@huetterma
Copy link
Contributor Author

@greptileai

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 27, 2026

Greptile Summary

This PR adds Slack/webhook budget alerting support for end_user entities, which was previously missing. It decouples budget enforcement (_check_end_user_budget) from data fetching (get_end_user_object), adds both max budget (alert + block) and soft budget (alert only) support, and introduces a new EndUserBudgetAlert type in the SlackAlerting system.

  • Decoupled _check_end_user_budget from get_end_user_object so that budget enforcement happens in common_checks instead of during data fetching — this follows the same separation of concerns as other entity types
  • Added "end_user_budget" alert type across SlackAlerting, ProxyLogging, and budget_alert_types.py with a new EndUserBudgetAlert class using customer_id for tracking
  • Converted _check_end_user_budget from sync to async, added valid_token and proxy_logging_obj parameters, and implemented both max and soft budget alert firing via asyncio.create_task — consistent with _team_max_budget_check / _team_soft_budget_check patterns
  • Simplified get_end_user_object exception handler by removing the now-unnecessary BudgetExceededError re-raise
  • Comprehensive test coverage added in tests/test_litellm/ (8 new tests for _check_end_user_budget) and updated existing tests in tests/proxy_unit_tests/ to reflect the new architecture

Confidence Score: 4/5

  • This PR is safe to merge — it follows established patterns and has good test coverage.
  • The implementation closely mirrors existing patterns for team/project budget alerting. The architectural change (decoupling budget check from data fetch) is clean and well-motivated. Tests are comprehensive. The only concern is ensuring make test-unit passes end-to-end (the PR checklist has this unchecked).
  • Pay close attention to litellm/proxy/auth/auth_checks.py — the core logic change lives here and should be verified with a full integration test run.

Important Files Changed

Filename Overview
litellm/proxy/auth/auth_checks.py Core change: decoupled _check_end_user_budget from get_end_user_object, converted to async, added Slack/webhook budget alerting for both max and soft budgets, and moved budget enforcement into common_checks. Exception handler in get_end_user_object simplified appropriately.
litellm/integrations/SlackAlerting/budget_alert_types.py New EndUserBudgetAlert class added following the same pattern as other alert types. Uses customer_id for ID tracking. Registered in factory function.
litellm/integrations/SlackAlerting/slack_alerting.py Added "end_user_budget" to the Literal type union for the budget_alerts method. Minimal, correct change.
litellm/proxy/utils.py Added "end_user_budget" to the Literal type union in ProxyLogging.budget_alerts. Minimal, correct change.
tests/test_litellm/integrations/SlackAlerting/test_budget_alert_types.py Added TestEndUserBudgetAlert class with tests for get_event_message and get_id with various customer_id states. Uses only mocks, no network calls.
tests/test_litellm/proxy/auth/test_auth_checks.py Comprehensive TestCheckEndUserBudget class with 8 tests covering max budget alerts, soft budget alerts, no-proxy-logging fallback, info route skipping, missing budget table, and combined max+soft budget scenarios. All use mocks.
tests/proxy_unit_tests/test_auth_checks.py Updated test_get_end_user_object to reflect the new architecture: get_end_user_object returns the object without raising, then _check_end_user_budget is called separately for budget enforcement.
tests/proxy_unit_tests/test_default_end_user_budget_simple.py Updated test_budget_enforcement_blocks_over_budget_users to reflect the decoupled architecture: fetch via get_end_user_object, then enforce via _check_end_user_budget.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[common_checks] --> B{end_user_object is not None?}
    B -->|No| Z[Continue to next check]
    B -->|Yes| C["_check_end_user_budget()"]
    C --> D{litellm_budget_table is None?}
    D -->|Yes| Z
    D -->|No| E{spend > max_budget?}
    E -->|Yes| F["Fire 'end_user_budget' alert via asyncio.create_task"]
    F --> G["Raise BudgetExceededError"]
    E -->|No| H{spend >= soft_budget?}
    H -->|Yes| I["Fire 'end_user_budget' soft alert via asyncio.create_task"]
    I --> Z
    H -->|No| Z
Loading

Last reviewed commit: 9dbd349

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

8 files reviewed, 4 comments

Edit Code Review Agent Settings | Greptile

@huetterma
Copy link
Contributor Author

@greptileai

@huetterma
Copy link
Contributor Author

@greptileai

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 27, 2026

Additional Comments (1)

litellm/proxy/auth/auth_checks.py, line 929
Dead BudgetExceededError handler

Since _check_end_user_budget has been moved out of get_end_user_object, a BudgetExceededError can no longer be raised inside this try block. The isinstance(e, litellm.BudgetExceededError) check on line 927 is now dead code. Consider removing it to keep the function clean and avoid confusion for future readers.

    except Exception as e:
        return None

@huetterma
Copy link
Contributor Author

@greptileai

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant