feat(proxy): add /team/daily/activity/aggregated and switch the Usage team tab to it - #36562
Conversation
…age UI The Team Usage tab drained row-paginated pages client side, which painted newest days first and drew duplicate bars when a day's rows straddled a page boundary. Serve the whole range in one SQL GROUPING SETS pass instead: the aggregated query gains optional per-entity rollup levels (entity as the most-significant GROUPING bit) so breakdown.entities keeps per-team spend, aliases, and per-key splits. The endpoint shares the paginated route's scoping via _resolve_team_daily_activity_scope, accepts the timezone the UI already sends, and the api_key filter now takes a list so non-admin member scoping works. The dashboard tries the aggregated endpoint first and falls back to page draining on failure.
Greptile SummaryThe PR adds an aggregated team daily-activity endpoint and switches Team Usage to prefer its complete-range response, with paginated fallback
Confidence Score: 5/5The PR appears safe to merge No blocking failure remains
|
| Filename | Overview |
|---|---|
| litellm/proxy/management_endpoints/common_daily_activity.py | Adds a separate entity-rollup query and folds its results into each day without changing the primary grouping bitmask |
| litellm/proxy/management_endpoints/team_endpoints.py | Adds the aggregated route, shared team permission scoping, and bounded date validation |
| ui/litellm-dashboard/src/app/(dashboard)/usage/_components/hooks/usePaginatedDailyActivity.ts | Prefers an optional single-shot aggregate fetch and falls back to the existing paginated flow |
| ui/litellm-dashboard/src/components/networking.tsx | Adds the dashboard client wrapper for aggregated team daily activity |
| ui/litellm-dashboard/src/lib/http/schema.d.ts | Regenerates OpenAPI types for the new endpoint |
Reviews (4): Last reviewed commit: "refactor(proxy): fetch entity rollups wi..." | Re-trigger Greptile
PR overviewAll previously flagged issues have been addressed. No open security concerns remain on this pull request. Security reviewNo open security issues remain on this pull request. Fixed/addressed: 1 · PR risk: 0/10 |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
…ctivity The aggregated endpoint has no pagination bounding its work, so validate start_date and end_date as real dates and cap the span at 400 days. The dashboard's widest presets fit well inside the cap, and an over-cap range falls back to the paginated flow. Also trim implementation comments that restated the grouping-set code.
|
@greptileai removed the redundant implementation comments and added date validation plus a 400 day range cap on the aggregated endpoint, please re-review |
|
@greptileai re review |
…of extending the main one The entity-as-extra-GROUPING-bit approach made the bitmask layout mode-dependent: the same constant meant (date) for normal rows and (date, entity) for entity rows, disambiguated by masking. Split it out: the shared WHERE builder feeds both the untouched main query and a small per-entity rollup query keyed by GROUPING(api_key), run concurrently, and a fold writes breakdown.entities onto the built response.
|
@greptileai reworked the entity rollups into a separate companion query so the main GROUPING SETS query and its bitmask are untouched, please re-review |
…itellm_team_daily_activity_aggregated
…itellm_team_daily_activity_aggregated
…hapes
The type-discipline ceiling for LIT002 ratcheted down on staging, so the new
aggregated endpoint had to stop hand-rolling collections the codebase already
builds elsewhere. Funnel the `{"error": ...}` detail through one construction
site, turn the range validator into an error-as-value, reuse a single
entity-metadata lookup for both breakdown paths, and widen
get_api_key_metadata to any set so callers stop copying frozensets.
9ec0145
into
litellm_internal_staging
TLDR
Problem this solves:
How it solves it:
User Flow
Before: an admin of a busy team opens the usage page and the daily chart shows duplicate and shifting bars while data trickles in
After: the same admin opens the same page and gets every day at once, one bar per day
Relevant issues
Linear ticket
Resolves LIT-2066
Pre-Submission checklist
Please complete all items before asking a LiteLLM maintainer to review your PR
@greptileaito re-request a review after pushing changes)Delays in PR merge?
If you're seeing a delay in your PR being merged, ping the LiteLLM Team on Slack (#pr-review).
Screenshots / Proof of Fix
Live proxy on 127.0.0.1:4153, throwaway Postgres seeded with 2,344 LiteLLM_DailyTeamSpend rows across 10 days and 2 teams: team "Users" $16.70 (1,500 rows on the newest day, 800 the day before), team "Platform" $1.00, grand total $17.70. Captured at a4a15ea
Before (old endpoint, unchanged): page 1 of the paginated route only contains the newest day, so anything that reads one page under-reports
After (new endpoint): the whole range in one response with per-team breakdown
Non-admin team member key (their key has $0.10 of the seed): HTTP 200, total_spend 0.10, their key hash is the only api_key anywhere in the response, and requesting another team's id returns 404 "User does not belong to Team"
UI before at be5e900, 12 bars for 10 dates (2026-08-09 and 08-10 each drawn twice at the page boundary):
UI after at a4a15ea, one aggregated request, 10 bars for 10 dates, Spend Per Team populated:
Type
🆕 New Feature
🐛 Bug Fix
Caveats (if any)
Final Attestation