-
Notifications
You must be signed in to change notification settings - Fork 785
fix(quota): keep the sub-day burst window instead of discarding it #1863
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,6 +9,20 @@ export type StoredAccountQuota = { | |
| monthlyPercent?: number; | ||
| weeklyResetAt?: number; | ||
| monthlyResetAt?: number; | ||
| /** | ||
| * A sub-day burst window, when upstream declares one (#1791). | ||
| * | ||
| * K12 and similar plans enforce a rolling 5-hour limit ALONGSIDE the weekly one. | ||
| * Not folding it into `weeklyPercent` stopped the mislabeling, but dropping it | ||
| * entirely hides a limit that genuinely blocks the account: a 429 at 100% here is | ||
| * real even while the weekly quota is untouched. | ||
| * | ||
| * `shortWindowSeconds` is retained because the duration is the only thing that makes | ||
| * this window self-describing; the slot it arrived in is not stable across plans. | ||
| */ | ||
| shortPercent?: number; | ||
| shortResetAt?: number; | ||
| shortWindowSeconds?: number; | ||
| resetCredits?: number; | ||
| /** | ||
| * True when `monthlyPercent` came from an explicitly-monthly PRIMARY window — | ||
|
|
@@ -85,13 +99,16 @@ export const CODEX_UNKNOWN_USAGE_SCORE = 101; | |
| export const CODEX_EXHAUSTED_USAGE_PERCENT = 100; | ||
|
|
||
| export function isCodexQuotaExhausted( | ||
| quota: Pick<StoredAccountQuota, "weeklyPercent" | "monthlyPercent"> | null, | ||
| quota: Pick<StoredAccountQuota, "weeklyPercent" | "monthlyPercent" | "shortPercent"> | null, | ||
| plan?: unknown, | ||
| ): boolean { | ||
| if (!quota) return false; | ||
| // The burst window counts on EVERY plan. It is upstream-enforced independently, so an | ||
| // account at 100% there is blocked regardless of which longer window governs its plan; | ||
| // omitting it would route traffic straight into a 429 (#1791). | ||
| const values = codexQuotaWindowForPlan(plan) === "monthly" | ||
| ? [quota.monthlyPercent] | ||
| : [quota.weeklyPercent, quota.monthlyPercent]; | ||
| ? [quota.monthlyPercent, quota.shortPercent] | ||
| : [quota.weeklyPercent, quota.monthlyPercent, quota.shortPercent]; | ||
|
Comment on lines
109
to
+111
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Updating AGENTS.md reference: AGENTS.md:L276-L278 Useful? React with 👍 / 👎. |
||
| return values.some(value => typeof value === "number" | ||
| && Number.isFinite(value) | ||
| && value >= CODEX_EXHAUSTED_USAGE_PERCENT); | ||
|
|
@@ -117,7 +134,7 @@ export function codexQuotaWindowForPlan(plan?: unknown): "monthly" | "weekly" { | |
| } | ||
|
|
||
| export function isCompleteCodexQuotaRecoverySnapshot( | ||
| quota: Pick<StoredAccountQuota, "weeklyPercent" | "monthlyPercent" | "monthlyIsPrimaryWindow"> | null, | ||
| quota: Pick<StoredAccountQuota, "weeklyPercent" | "monthlyPercent" | "monthlyIsPrimaryWindow" | "shortPercent"> | null, | ||
| plan?: unknown, | ||
| ): boolean { | ||
| if (!quota || isCodexQuotaExhausted(quota, plan)) return false; | ||
|
|
@@ -494,6 +511,14 @@ export function parseUsageQuota(data: WhamUsageResponse): Omit<StoredAccountQuot | |
| const primaryIsShort = isExplicitShortWindow(primaryWindow); | ||
| const weeklyCandidatePercent = primaryIsShort ? undefined : primaryPercent; | ||
| const weeklyCandidateResetAt = primaryIsShort ? undefined : primaryResetAt; | ||
|
Comment on lines
511
to
513
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The new representation says the upstream slot is not stable across plans, but the parser classifies only AGENTS.md reference: AGENTS.md:L276-L278 Useful? React with 👍 / 👎. |
||
| // Keep the burst reading instead of dropping it on the floor: it is a real limit, and | ||
| // the account is blocked when it fills even though the weekly window is fine (#1791). | ||
| if (primaryIsShort && primaryPercent !== undefined) { | ||
| quota.shortPercent = primaryPercent; | ||
| if (primaryResetAt !== undefined) quota.shortResetAt = primaryResetAt; | ||
| const seconds = primaryWindow?.limit_window_seconds; | ||
| if (typeof seconds === "number" && Number.isFinite(seconds)) quota.shortWindowSeconds = seconds; | ||
|
Comment on lines
+517
to
+520
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When WHAM returns the new burst fields, AGENTS.md reference: AGENTS.md:L276-L278 Useful? React with 👍 / 👎. |
||
| } | ||
|
Comment on lines
+514
to
+521
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
# Map the quota module before inspecting the unchanged helper.
ast-grep outline src/codex/quota.ts --items all --match 'hasKnownQuotaValue'
# Inspect the helper definition and the parser return condition.
rg -n -C 12 '\b(hasKnownQuotaValue|parseUsageQuota)\b' src/codex/quota.ts
# Check whether a short-primary-only payload is already covered.
rg -n -C 8 'shortPercent|shortWindowSeconds|primary_window' tests/codex-routing.test.tsRepository: lidge-jun/opencodex Length of output: 10973 🏁 Script executed: #!/bin/bash
set -euo pipefail
# Inspect the complete quota assignment path and the stored quota shape.
sed -n '1,45p;180,205p;478,552p' src/codex/quota.ts
# Check for a test whose parsed payload contains only a valid short window.
rg -n -C 10 'short-only|shortPercent:|limit_window_seconds: 18000|rate_limit: \{\}' tests srcRepository: lidge-jun/opencodex Length of output: 13684 🏁 Script executed: #!/bin/bash
set -euo pipefail
# Independently model the return guard for a short-window-only quota.
python3 - <<'PY'
import math
quota = {
"shortPercent": 100.0,
"shortResetAt": 2000000000,
"shortWindowSeconds": 18000,
}
known = any(
isinstance(quota.get(name), (int, float))
and not isinstance(quota.get(name), bool)
and math.isfinite(quota[name])
for name in ("weeklyPercent", "monthlyPercent")
)
print({"short_only_quota": quota, "hasKnownQuotaValue": known, "parser_returns_quota": known})
assert known is False
assert "shortPercent" not in ("weeklyPercent", "monthlyPercent")
PYRepository: lidge-jun/opencodex Length of output: 320 Include
🤖 Prompt for AI Agents |
||
| const weeklyPercent = primaryIsMonthly ? secondaryPercent : weeklyCandidatePercent ?? secondaryPercent; | ||
| const weeklyResetAt = primaryIsMonthly | ||
| ? secondaryResetAt | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Projecting these fields does not make the new limit visible as claimed: the CLI's
refreshLinechecks and prints only weekly/monthly quota, while the dashboardAccountQuotamodel andQuotaBarsconsume onlyfiveHourPercent, weekly, monthly, and custom windows. Thus even a response containingshortPercentsilently omits the burst bar in both user-facing surfaces; map the duration-aware field into their quota rows and labels.Useful? React with 👍 / 👎.