fix(supervisor): gate + display weekly-Sonnet, not weekly-Opus
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 8s

On this claude.ai account the populated per-model weekly cap is Sonnet;
seven_day_opus is null (no separate Opus cap). So quota_available() now gates on
five_hour + seven_day + seven_day_sonnet (was seven_day_opus, which never bound),
and `status` prints weekly-Sonnet. The all-models seven_day cap remains the
backstop for Opus usage regardless. Matches the /operations display (#245).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-13 10:58:05 +00:00
parent 01bc1b9743
commit eac4dd3ac9
2 changed files with 8 additions and 5 deletions

View File

@@ -129,7 +129,7 @@ def quota_available() -> bool:
Primary: read the authoritative utilization from the OAuth usage endpoint
(subscription_usage) and treat a window as exhausted only at >=100%. Cheaper
and more precise than a probe — no Opus call, and it sees every limit
(5-hour, weekly all-models, weekly-Opus) the way the UI does. The 429 reset
(5-hour, weekly all-models, weekly-Sonnet) the way the UI does. The 429 reset
time claude.ai reports is often conservative, so this resumes the drain the
moment a window actually frees up rather than waiting blindly.
@@ -139,8 +139,11 @@ def quota_available() -> bool:
usage = subscription_usage()
if usage is not None:
# A drain run needs the 5-hour window, the weekly all-models cap, AND
# the weekly-Opus cap (the extractor runs Opus) all below 100%.
windows = ("five_hour", "seven_day", "seven_day_opus")
# the weekly per-model cap all below 100%. On this account the per-model
# cap that's actually populated is Sonnet (seven_day_opus is null — no
# separate Opus cap); the all-models seven_day cap is the backstop for
# Opus usage either way. null utilization → treated as 0% (not limiting).
windows = ("five_hour", "seven_day", "seven_day_sonnet")
utils = [(usage.get(w) or {}).get("utilization") for w in windows]
# utilization may be None (window inactive / no data) → treat as 0%.
return all((u or 0) < 100 for u in utils)
@@ -529,7 +532,7 @@ def cmd_status():
rt = ""
return f"{u:.0f}%{rt}"
print(f"מכסת claude.ai: 5-שעות={_w('five_hour')} · שבועי={_w('seven_day')} · "
f"שבועי-Opus={_w('seven_day_opus')}")
f"שבועי-Sonnet={_w('seven_day_sonnet')}")
else:
print("מכסת claude.ai: (endpoint לא זמין)")