Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions internal/provider/claude/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ func parseUsage(body []byte, plan, rateLimitTier, email, uuid string) quota.Resu
Utilization float64 `json:"utilization"`
ResetsAt string `json:"resets_at"`
} `json:"seven_day_opus"`
SevenDayOmelette *struct {
Utilization float64 `json:"utilization"`
ResetsAt string `json:"resets_at"`
} `json:"seven_day_omelette"`
}
if err := json.Unmarshal(body, &usage); err != nil {
return quota.ErrorResult("parse_error", fmt.Sprintf("parse: %v", err), 0)
Expand All @@ -87,6 +91,9 @@ func parseUsage(body []byte, plan, rateLimitTier, email, uuid string) quota.Resu
if usage.SevenDayOpus != nil {
windows[quota.WindowName("7d:opus")] = toWindow(usage.SevenDayOpus.Utilization, usage.SevenDayOpus.ResetsAt)
}
if usage.SevenDayOmelette != nil {
windows[quota.WindowName("7d:design")] = toWindow(usage.SevenDayOmelette.Utilization, usage.SevenDayOmelette.ResetsAt)
}

return quota.Result{
Status: quota.StatusFromWindows(windows),
Expand Down
48 changes: 28 additions & 20 deletions internal/provider/claude/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,30 +261,38 @@ func TestParseUsageModelSpecificSevenDayWindows(t *testing.T) {
"five_hour": {"utilization": 30.0, "resets_at": "2026-03-20T12:00:00Z"},
"seven_day": {"utilization": 10.0, "resets_at": "2026-03-25T00:00:00Z"},
"seven_day_sonnet": {"utilization": 25.0, "resets_at": "2026-03-24T00:00:00Z"},
"seven_day_opus": {"utilization": 40.0, "resets_at": "2026-03-23T00:00:00Z"}
"seven_day_opus": {"utilization": 40.0, "resets_at": "2026-03-23T00:00:00Z"},
"seven_day_omelette": {"utilization": 55.0, "resets_at": "2026-03-22T00:00:00Z"}
}`)

result := parseUsage(body, "max", "default_claude_max_20x", "user@example.com", "abc-123")

sonnet, ok := result.Windows[quota.WindowName("7d:sonnet")]
if !ok {
t.Fatal("missing 7d:sonnet window")
}
if sonnet.RemainingPct != 75 {
t.Errorf("7d:sonnet remaining_pct = %d, want 75", sonnet.RemainingPct)
}
if sonnet.ResetAtUnix == 0 {
t.Error("7d:sonnet reset_at_unix should be non-zero")
tests := []struct {
name string
want int
}{
{name: "7d:sonnet", want: 75},
{name: "7d:opus", want: 60},
{name: "7d:design", want: 45},
}

for _, tc := range tests {
window, ok := result.Windows[quota.WindowName(tc.name)]
if !ok {
t.Fatalf("missing %s window", tc.name)
}
if window.RemainingPct != tc.want {
t.Errorf("%s remaining_pct = %d, want %d", tc.name, window.RemainingPct, tc.want)
}
if window.ResetAtUnix == 0 {
t.Errorf("%s reset_at_unix should be non-zero", tc.name)
}
}
}

opus, ok := result.Windows[quota.WindowName("7d:opus")]
if !ok {
t.Fatal("missing 7d:opus window")
}
if opus.RemainingPct != 60 {
t.Errorf("7d:opus remaining_pct = %d, want 60", opus.RemainingPct)
}
if opus.ResetAtUnix == 0 {
t.Error("7d:opus reset_at_unix should be non-zero")
func TestParseUsageDoesNotEmitDesignWindowWhenOmeletteAbsent(t *testing.T) {
result := parseUsage(usageJSON, "max", "default_claude_max_20x", "user@example.com", "abc-123")

if _, ok := result.Windows[quota.WindowName("7d:design")]; ok {
t.Fatal("unexpected 7d:design window")
}
}
Loading