From e1ec25f1e49ae0266762a1c514d1b15a1774ae4f Mon Sep 17 00:00:00 2001 From: Inferencebot Date: Sun, 1 Nov 2026 17:16:33 +0000 Subject: [PATCH] admin overview: give agent teams an all-time spend, not just the cycle counter The team spend counter is cycle-only and resets at budget_reset_at, which for the agent teams means the 1st of the month. The panel's agents table read that field directly, so on 1 November the co-op's own bot accounts appeared to have had their spend zeroed out. Members already had an all-time figure for exactly this reason; agent teams did not, because the all-time query filtered to member:% only. Widen it to agent:% and expose all_time_spend on agent rows. --- app/main.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/app/main.py b/app/main.py index 2df3f98..e0658cf 100644 --- a/app/main.py +++ b/app/main.py @@ -3068,9 +3068,11 @@ async def admin_overview(request: Request): except Exception as e: logger.warning("admin overview: team/list failed: %s", e) - # All-time spend per member team, from SpendLogs (the team `spend` counter - # is cycle-only and resets at each member's budget_reset_at — the panel - # needs both to avoid the "month change wiped the numbers" confusion). + # All-time spend per team, from SpendLogs (the team `spend` counter is + # cycle-only and resets at each team's budget_reset_at — the panel needs both + # to avoid the "month change wiped the numbers" confusion). + # Covers agent teams as well as members: an agent's cycle counter resets the + # same way, and its all-time spend is the only figure that stays meaningful. all_time_spend: dict[str, float] = {} try: conn = _pg_connect() @@ -3081,7 +3083,7 @@ async def admin_overview(request: Request): SELECT t.team_alias, COALESCE(SUM(s.spend), 0) FROM "LiteLLM_TeamTable" t LEFT JOIN "LiteLLM_SpendLogs" s ON s."team_id" = t.team_id - WHERE t.team_alias LIKE 'member:%' + WHERE t.team_alias LIKE 'member:%' OR t.team_alias LIKE 'agent:%' GROUP BY 1 """ ) @@ -3153,6 +3155,10 @@ async def admin_overview(request: Request): # "agent:" prefix is noise there. `alias` keeps the full string. "name": alias.split(":", 1)[1] if ":" in alias else alias, "spend": float(t.get("spend") or 0.0), + # Cycle counter resets at budget_reset_at (the 1st, for the agents), so + # the panel shows all-time for these accounts instead of a number that + # reads as zeroed every month. + "all_time_spend": round(all_time_spend.get(alias, 0.0), 2), "budget": t.get("max_budget"), "team_members": len(t.get("members_with_roles") or []), }