This commit is contained in:
Aftab 2026-09-23 14:45:50 +00:00 • committed by GitHub
commit 0d866b5495
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 14 additions and 9 deletions

View file

@ -12,8 +12,6 @@ from datetime import datetime, time, timedelta, timezone, tzinfo
from typing import Final
from zoneinfo import ZoneInfo
from litellm._logging import verbose_logger
_BUDGET_DURATION_WORD_ALIASES: Final[dict[str, str]] = {
"hourly": "1h",
"daily": "24h",
@ -131,6 +129,9 @@ def get_next_standardized_reset_time(
Returns:
- Next reset time at a standardized interval in the specified timezone
Raises:
- ValueError: If the duration string is empty or cannot be parsed.
"""
# Set up timezone and normalize current time
current_time, _ = _setup_timezone(current_time, timezone_str)
@ -138,12 +139,10 @@ def get_next_standardized_reset_time(
# Parse duration
value, unit = _parse_duration(_normalize_duration(duration))
if value is None:
verbose_logger.warning(
"Unrecognized budget_duration %r; falling back to a next-midnight reset. "
"Use the <int><unit> format (e.g. '1h', '7d', '30d', '1mo').",
duration,
raise ValueError(
f"Invalid budget_duration {duration!r}. "
"Use the <int><unit> format (e.g. '1h', '7d', '30d', '1mo')."
)
return current_time.replace(hour=0, minute=0, second=0, microsecond=0) + timedelta(days=1)
# Midnight of the current day in the specified timezone
base_midnight: Final = current_time.replace(hour=0, minute=0, second=0, microsecond=0)

View file

@ -798,7 +798,7 @@ class ResetBudgetJob:
compute_budget_reset_at(budget_duration=b.budget_duration, settings=self.reset_settings),
)
for b in budgets_to_reset
if b.budget_id is not None and b.budget_duration is not None
if b.budget_id is not None and b.budget_duration
),
counter_resets=(
*(
@ -1408,6 +1408,12 @@ class ResetBudgetJob:
except Exception as redis_err:
verbose_proxy_logger.warning("Failed to reset Redis counter %s: %s", counter_key, redis_err)
budget_duration: Final = window["budget_duration"]
if not budget_duration:
verbose_proxy_logger.warning(
"Skipping window reset for entity %s: budget_duration is empty or missing",
entity_id,
)
return False
next_reset_at: Final = compute_budget_reset_at(budget_duration=budget_duration, settings=reset_settings)
window["reset_at"] = next_reset_at.isoformat()
await ResetBudgetJob._roll_window_spend_row(
@ -1586,7 +1592,7 @@ class ResetBudgetJob:
"""
try:
item.spend = _carried_spend(item.spend, _rollover_cap(item.max_budget)) if _rollover_enabled() else 0.0
if hasattr(item, "budget_duration") and item.budget_duration is not None:
if hasattr(item, "budget_duration") and item.budget_duration:
item.budget_reset_at = compute_budget_reset_at(
budget_duration=item.budget_duration, settings=reset_settings
)