Skip to content

Commit 39341fa

Browse files
committed
fix: avoid duplicate codex quota windows
1 parent 7ef1482 commit 39341fa

4 files changed

Lines changed: 69 additions & 13 deletions

File tree

cliproxyapi-pro-core/patches/sources/internal/pro/inspection/providers.go

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -570,12 +570,11 @@ func BuildCodexWindows(body string) (map[string]any, []map[string]any, *float64)
570570
if idPrefix == "" {
571571
idPrefix = fmt.Sprintf("additional-%d", index+1)
572572
}
573-
primary, _ := firstAny(rateInfo, "primary_window", "primaryWindow").(map[string]any)
574-
secondary, _ := firstAny(rateInfo, "secondary_window", "secondaryWindow").(map[string]any)
573+
additionalFiveHour, additionalLong := codexClassifiedWindows(rateInfo, true)
575574
params := map[string]any{"name": limitName}
576-
addCodexWindow(fmt.Sprintf("%s-five-hour-%d", idPrefix, index), "codex_quota.additional_primary_window", params, primary, firstAny(rateInfo, "limit_reached", "limitReached"), rateInfo["allowed"])
577-
additionalSecondaryID, additionalSecondaryLabel := codexSecondaryWindowMeta(secondary, "weekly", "codex_quota.additional_secondary_window", "monthly", "codex_quota.additional_team_secondary_window")
578-
addCodexWindow(fmt.Sprintf("%s-%s-%d", idPrefix, additionalSecondaryID, index), additionalSecondaryLabel, params, secondary, firstAny(rateInfo, "limit_reached", "limitReached"), rateInfo["allowed"])
575+
addCodexWindow(fmt.Sprintf("%s-five-hour-%d", idPrefix, index), "codex_quota.additional_primary_window", params, additionalFiveHour, firstAny(rateInfo, "limit_reached", "limitReached"), rateInfo["allowed"])
576+
additionalSecondaryID, additionalSecondaryLabel := codexSecondaryWindowMeta(additionalLong, "weekly", "codex_quota.additional_secondary_window", "monthly", "codex_quota.additional_team_secondary_window")
577+
addCodexWindow(fmt.Sprintf("%s-%s-%d", idPrefix, additionalSecondaryID, index), additionalSecondaryLabel, params, additionalLong, firstAny(rateInfo, "limit_reached", "limitReached"), rateInfo["allowed"])
579578
}
580579

581580
used := MaxUsedPercentFromWindows(windows)
@@ -590,23 +589,29 @@ func codexClassifiedWindows(limitInfo map[string]any, allowOrderFallback bool) (
590589
secondary, _ := firstAny(limitInfo, "secondary_window", "secondaryWindow").(map[string]any)
591590
var fiveHour map[string]any
592591
var weekly map[string]any
593-
for _, window := range []map[string]any{primary, secondary} {
592+
fiveHourSlot := -1
593+
weeklySlot := -1
594+
for slot, window := range []map[string]any{primary, secondary} {
594595
seconds, ok := floatFromAny(firstAny(window, "limit_window_seconds", "limitWindowSeconds"))
595596
if !ok {
596597
continue
597598
}
598599
if int(seconds) == 18000 && fiveHour == nil {
599600
fiveHour = window
601+
fiveHourSlot = slot
600602
} else if (int(seconds) == 604800 || isCodexMonthlyWindow(window)) && weekly == nil {
601603
weekly = window
604+
weeklySlot = slot
602605
}
603606
}
604607
if allowOrderFallback {
605-
if fiveHour == nil {
608+
if fiveHour == nil && primary != nil && weeklySlot != 0 {
606609
fiveHour = primary
610+
fiveHourSlot = 0
607611
}
608-
if weekly == nil {
612+
if weekly == nil && secondary != nil && fiveHourSlot != 1 {
609613
weekly = secondary
614+
weeklySlot = 1
610615
}
611616
}
612617
return fiveHour, weekly

cliproxyapi-pro-core/patches/sources/internal/pro/inspection/providers_test.go

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package inspection
22

3-
import "testing"
3+
import (
4+
"strconv"
5+
"testing"
6+
)
47

58
func TestAntigravityParserBuildsCanonicalGroups(t *testing.T) {
69
groups, err := BuildAntigravityGroups(`{
@@ -56,6 +59,54 @@ func TestClaudeAndCodexWindowParsers(t *testing.T) {
5659
}
5760
}
5861

62+
func TestCodexSingleLongWindowIsNotDuplicatedAsFiveHour(t *testing.T) {
63+
tests := []struct {
64+
name string
65+
windowSecs int
66+
wantID string
67+
}{
68+
{name: "weekly", windowSecs: 604800, wantID: "weekly"},
69+
{name: "monthly", windowSecs: 2592000, wantID: "monthly"},
70+
}
71+
for _, tt := range tests {
72+
t.Run(tt.name, func(t *testing.T) {
73+
body := `{"rate_limit":{"primary_window":{"limit_window_seconds":` +
74+
strconv.Itoa(tt.windowSecs) + `,"used_percent":25,"reset_at":1767830400}}}`
75+
_, windows, used := BuildCodexWindows(body)
76+
if len(windows) != 1 || windows[0]["id"] != tt.wantID {
77+
t.Fatalf("windows = %+v, want only %q", windows, tt.wantID)
78+
}
79+
if used == nil || *used != 25 {
80+
t.Fatalf("used percent = %v, want 25", used)
81+
}
82+
})
83+
}
84+
}
85+
86+
func TestCodexLegacyUndatedWindowsKeepDistinctOrderFallback(t *testing.T) {
87+
_, windows, _ := BuildCodexWindows(`{
88+
"rate_limit":{
89+
"primary_window":{"used_percent":10,"reset_at":1767243600},
90+
"secondary_window":{"used_percent":20,"reset_at":1767830400}
91+
}
92+
}`)
93+
if len(windows) != 2 || windows[0]["id"] != "five-hour" || windows[1]["id"] != "weekly" {
94+
t.Fatalf("legacy windows = %+v, want distinct primary/secondary fallback", windows)
95+
}
96+
}
97+
98+
func TestCodexAdditionalSingleMonthlyWindowUsesMonthlyLabel(t *testing.T) {
99+
_, windows, _ := BuildCodexWindows(`{
100+
"additional_rate_limits":[{
101+
"limit_name":"Credits",
102+
"rate_limit":{"primary_window":{"limit_window_seconds":2592000,"used_percent":30,"reset_at":1767830400}}
103+
}]
104+
}`)
105+
if len(windows) != 1 || windows[0]["id"] != "credits-monthly-0" {
106+
t.Fatalf("additional windows = %+v, want only monthly", windows)
107+
}
108+
}
109+
59110
func TestKimiParserNormalizesLimits(t *testing.T) {
60111
rows, used, err := BuildKimiRows(`{
61112
"limits":[{"name":"Weekly","limit":100,"used":40,"reset_at":"2026-01-08T00:00:00Z","window":{"duration":1,"timeUnit":"WEEKS"}}]

cliproxyapi-pro-core/patches/sources/internal/pro/quota/xai.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import (
1616
const (
1717
// CacheParserVersion is the shared version of normalized quota cache
1818
// records. Provider-specific parser versions may diverge from it later.
19-
CacheParserVersion = 6
19+
CacheParserVersion = 7
2020
XAIParserVersion = CacheParserVersion
2121
)
2222

cliproxyapi-pro-core/patches/sources/internal/pro/quota/xai_billing_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ func TestXAIBillingParserCombinesWeeklyAndMonthlyShapes(t *testing.T) {
3737
}
3838
}
3939

40-
func TestCacheParserVersionCoversQuotaTimelineFields(t *testing.T) {
41-
if CacheParserVersion != 6 {
42-
t.Fatalf("CacheParserVersion = %d, want 6", CacheParserVersion)
40+
func TestCacheParserVersionCoversCodexWindowClassification(t *testing.T) {
41+
if CacheParserVersion != 7 {
42+
t.Fatalf("CacheParserVersion = %d, want 7", CacheParserVersion)
4343
}
4444
}
4545

0 commit comments

Comments
 (0)