diff --git a/backend/integrations/claude_usage.py b/backend/integrations/claude_usage.py index 79cc64d..f25461f 100644 --- a/backend/integrations/claude_usage.py +++ b/backend/integrations/claude_usage.py @@ -64,6 +64,22 @@ class Window: return f"{m}min" +@dataclass +class ExtraUsage: + """Crédits « extra usage » (pay-as-you-go au-delà de l'abonnement).""" + + used: float + limit: float | None + currency: str = "EUR" + + @property + def label(self) -> str: + sym = "€" if self.currency == "EUR" else self.currency + if self.limit: + return f"Extra : {self.used:.0f}{sym} / {self.limit:.0f}{sym}" + return f"Extra : {self.used:.0f}{sym}" + + @dataclass class ClaudeUsage: ok: bool @@ -72,6 +88,7 @@ class ClaudeUsage: seven_day: Window | None = None seven_day_opus: Window | None = None seven_day_sonnet: Window | None = None + extra: ExtraUsage | None = None burn_rate: float | None = None # tokens/min (ccusage, optionnel) @@ -208,11 +225,22 @@ async def fetch_usage() -> ClaudeUsage: data = resp.json() burn = _burn_rate_from_ccusage() if config.ccusage_enabled else None + + extra = None + eu = data.get("extra_usage") or {} + if eu.get("is_enabled") and eu.get("used_credits"): + extra = ExtraUsage( + used=float(eu.get("used_credits", 0)), + limit=float(eu["monthly_limit"]) if eu.get("monthly_limit") else None, + currency=eu.get("currency", "EUR"), + ) + return ClaudeUsage( ok=True, five_hour=_parse_window(data.get("five_hour")), seven_day=_parse_window(data.get("seven_day")), seven_day_opus=_parse_window(data.get("seven_day_opus")), seven_day_sonnet=_parse_window(data.get("seven_day_sonnet")), + extra=extra, burn_rate=burn, ) diff --git a/backend/templates/dashboard.html b/backend/templates/dashboard.html index 0e14f4e..2f123ec 100644 --- a/backend/templates/dashboard.html +++ b/backend/templates/dashboard.html @@ -111,6 +111,9 @@