From 8568ea7ddd19e965451e5dd70886686069059591 Mon Sep 17 00:00:00 2001 From: euxaristia Date: Thu, 13 Aug 2026 03:43:56 -0400 Subject: [PATCH] Label Codex usage windows by duration. Refs #26 --- pkg/parsers/codex.go | 15 +++++++++++++-- pkg/parsers/codex_test.go | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/pkg/parsers/codex.go b/pkg/parsers/codex.go index 0115a4a..f539fa0 100644 --- a/pkg/parsers/codex.go +++ b/pkg/parsers/codex.go @@ -36,10 +36,10 @@ func ParseCodexUsage(data []byte, now time.Time) (CodexUsage, error) { windows := make([]CodexUsageWindow, 0, 2) if window := payload.RateLimit.PrimaryWindow; window != nil { - windows = append(windows, window.toUsageWindow("Primary", now)) + windows = append(windows, window.toUsageWindow(windowLabel("Primary", window.LimitWindowSeconds), now)) } if window := payload.RateLimit.SecondaryWindow; window != nil { - windows = append(windows, window.toUsageWindow("Secondary", now)) + windows = append(windows, window.toUsageWindow(windowLabel("Secondary", window.LimitWindowSeconds), now)) } if len(windows) == 0 { return CodexUsage{}, fmt.Errorf("no Codex rate-limit windows in response") @@ -47,6 +47,17 @@ func ParseCodexUsage(data []byte, now time.Time) (CodexUsage, error) { return CodexUsage{PlanType: payload.PlanType, Windows: windows}, nil } +func windowLabel(fallback string, seconds int) string { + switch seconds { + case 5 * 60 * 60: + return "Session" + case 7 * 24 * 60 * 60: + return "Weekly" + default: + return fallback + } +} + type codexWindow struct { UsedPercent float64 `json:"used_percent"` LimitWindowSeconds int `json:"limit_window_seconds"` diff --git a/pkg/parsers/codex_test.go b/pkg/parsers/codex_test.go index 7f89bc7..6a86918 100644 --- a/pkg/parsers/codex_test.go +++ b/pkg/parsers/codex_test.go @@ -20,14 +20,42 @@ func TestParseCodexUsage(t *testing.T) { if usage.PlanType != "plus" || len(usage.Windows) != 2 { t.Fatalf("unexpected usage: %#v", usage) } - if got := usage.Windows[0]; got.Label != "Primary" || got.UsedPercent != 42 || got.WindowSeconds != 18000 || got.ResetCountdown != "1h 0m" { + if got := usage.Windows[0]; got.Label != "Session" || got.UsedPercent != 42 || got.WindowSeconds != 18000 || got.ResetCountdown != "1h 0m" { t.Fatalf("unexpected primary window: %#v", got) } - if got := usage.Windows[1]; got.Label != "Secondary" || got.ResetCountdown != "2h 0m" { + if got := usage.Windows[1]; got.Label != "Weekly" || got.ResetCountdown != "2h 0m" { t.Fatalf("unexpected secondary window: %#v", got) } } +func TestParseCodexUsageLabelsWeeklyPrimaryWindow(t *testing.T) { + usage, err := ParseCodexUsage([]byte(`{ + "rate_limit":{ + "primary_window":{"used_percent":10,"limit_window_seconds":604800,"reset_after_seconds":590684} + } + }`), time.Unix(1_700_000_000, 0)) + if err != nil { + t.Fatal(err) + } + if got := usage.Windows[0].Label; got != "Weekly" { + t.Fatalf("expected weekly label, got %q", got) + } +} + +func TestParseCodexUsageKeepsUnknownWindowLabel(t *testing.T) { + usage, err := ParseCodexUsage([]byte(`{ + "rate_limit":{ + "primary_window":{"limit_window_seconds":86400} + } + }`), time.Unix(1_700_000_000, 0)) + if err != nil { + t.Fatal(err) + } + if got := usage.Windows[0].Label; got != "Primary" { + t.Fatalf("expected fallback label, got %q", got) + } +} + func TestParseCodexUsageRejectsMissingWindows(t *testing.T) { _, err := ParseCodexUsage([]byte(`{"rate_limit":{}}`), time.Now()) if err == nil {