-
Notifications
You must be signed in to change notification settings - Fork 0
[WRONG BRANCH] fix(quota): retain burst limits in cached routing #308
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 |
|---|---|---|
|
|
@@ -186,7 +186,7 @@ function normalizeResetAt(value: unknown): number | undefined { | |
| } | ||
|
|
||
| function hasKnownQuotaValue(quota: Omit<StoredAccountQuota, "updatedAt">): boolean { | ||
| return [quota.weeklyPercent, quota.monthlyPercent] | ||
| return [quota.weeklyPercent, quota.monthlyPercent, quota.shortPercent] | ||
| .some(value => typeof value === "number" && Number.isFinite(value)); | ||
| } | ||
|
|
||
|
|
@@ -226,8 +226,14 @@ function snapshotHasMonthly(quota: Omit<StoredAccountQuota, "updatedAt">): boole | |
| return quota.monthlyPercent !== undefined || quota.monthlyResetAt !== undefined; | ||
| } | ||
|
|
||
| function snapshotHasShort(quota: Omit<StoredAccountQuota, "updatedAt">): boolean { | ||
| return quota.shortPercent !== undefined | ||
| || quota.shortResetAt !== undefined | ||
| || quota.shortWindowSeconds !== undefined; | ||
| } | ||
|
|
||
| function snapshotHasUsage(quota: Omit<StoredAccountQuota, "updatedAt">): boolean { | ||
| return snapshotHasWeekly(quota) || snapshotHasMonthly(quota); | ||
| return snapshotHasWeekly(quota) || snapshotHasMonthly(quota) || snapshotHasShort(quota); | ||
| } | ||
| export function setAccountQuotaFromParsed( | ||
| accountId: string, | ||
|
|
@@ -246,6 +252,9 @@ export function setAccountQuotaFromParsed( | |
| if (existing?.monthlyPercent !== undefined) next.monthlyPercent = existing.monthlyPercent; | ||
| if (existing?.monthlyResetAt !== undefined) next.monthlyResetAt = existing.monthlyResetAt; | ||
| if (existing?.monthlyIsPrimaryWindow === true) next.monthlyIsPrimaryWindow = true; | ||
| if (existing?.shortPercent !== undefined) next.shortPercent = existing.shortPercent; | ||
| if (existing?.shortResetAt !== undefined) next.shortResetAt = existing.shortResetAt; | ||
| if (existing?.shortWindowSeconds !== undefined) next.shortWindowSeconds = existing.shortWindowSeconds; | ||
|
Comment on lines
+255
to
+257
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. 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win Cover burst-field retention on a credits-only refresh. The new copy path is not covered by the existing credits-only test in As per path instructions, “A behavior change in 🤖 Prompt for AI AgentsSource: Path instructions |
||
| next.resetCredits = quota.resetCredits; | ||
| accountQuota.set(accountId, next); | ||
| schedulePersistAccountQuotas(); | ||
|
|
@@ -279,6 +288,12 @@ export function setAccountQuotaFromParsed( | |
| if (quota.resetCredits !== undefined) next.resetCredits = quota.resetCredits; | ||
| else if (existing?.resetCredits !== undefined) next.resetCredits = existing.resetCredits; | ||
|
|
||
| if (snapshotHasShort(quota)) { | ||
| if (quota.shortPercent !== undefined) next.shortPercent = quota.shortPercent; | ||
| if (quota.shortResetAt !== undefined) next.shortResetAt = quota.shortResetAt; | ||
| if (quota.shortWindowSeconds !== undefined) next.shortWindowSeconds = quota.shortWindowSeconds; | ||
|
Comment on lines
+291
to
+294
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 a WHAM refresh has cached Useful? React with 👍 / 👎. |
||
| } | ||
|
|
||
| accountQuota.set(accountId, next); | ||
| schedulePersistAccountQuotas(); | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -41,6 +41,7 @@ function codexAccountQuotaEvidence(accountId: string, plan?: string): RouteQuota | |
| const percents = [ | ||
| ...(monthly ? [] : [quota.weeklyPercent]), | ||
| quota.monthlyPercent, | ||
| quota.shortPercent, | ||
| ].filter((value): value is number => typeof value === "number" && Number.isFinite(value)); | ||
| const maxPercent = percents.length > 0 ? Math.max(...percents) : undefined; | ||
| // Credits-only snapshots prove neither usage nor exhaustion. Unknown must not | ||
|
|
@@ -49,6 +50,7 @@ function codexAccountQuotaEvidence(accountId: string, plan?: string): RouteQuota | |
| const resets = [ | ||
| ...(monthly ? [] : [quota.weeklyResetAt]), | ||
| quota.monthlyResetAt, | ||
| quota.shortResetAt, | ||
|
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.
WHAM's Useful? React with 👍 / 👎. |
||
| ].filter((value): value is number => typeof value === "number" && Number.isFinite(value)) | ||
| .filter(value => value > Date.now()); | ||
|
Comment on lines
+53
to
55
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. 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- target file ---'
sed -n '1,130p' src/routing/quota.ts
printf '%s\n' '--- parser and quota references ---'
rg -n -C 5 'parseUsageQuota|shortResetAt|reset_at|resetAtMs|short' src tests -g '*.ts'
printf '%s\n' '--- relevant test sections ---'
sed -n '90,135p' tests/rate-limit-reset-credits.test.ts
sed -n '395,430p' tests/rate-limit-reset-credits.test.ts
sed -n '45,85p' tests/routing-policy-pool-quota.test.tsRepository: luvs01/opencodex Length of output: 50373 🏁 Script executed: #!/bin/bash
set -e
python3 - <<'PY'
from pathlib import Path
for p in [
Path("src/routing/quota.ts"),
Path("tests/rate-limit-reset-credits.test.ts"),
Path("tests/routing-policy-pool-quota.test.ts"),
]:
print(f"--- {p} ---")
lines = p.read_text().splitlines()
for i, line in enumerate(lines, 1):
if p.name == "quota.ts" and i <= 100:
print(f"{i:4}: {line}")
elif p.name == "rate-limit-reset-credits.test.ts" and (105 <= i <= 125 or 405 <= i <= 425):
print(f"{i:4}: {line}")
elif p.name == "routing-policy-pool-quota.test.ts" and 50 <= i <= 85:
print(f"{i:4}: {line}")
PY
printf '%s\n' '--- all definitions and consumers ---'
rg -n -C 8 'parseUsageQuota|shortResetAt|reset_at|resetAtMs' src tests -g '*.ts'Repository: luvs01/opencodex Length of output: 50373 🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- files ---'
git ls-files 'src/routing/quota.ts' 'tests/rate-limit-reset-credits.test.ts' 'tests/routing-policy-pool-quota.test.ts'
printf '%s\n' '--- quota.ts ---'
cat -n src/routing/quota.ts
printf '%s\n' '--- parser definition ---'
rg -n -C 12 'function parseUsageQuota|const parseUsageQuota|parseUsageQuota' src
printf '%s\n' '--- reset producers and consumers ---'
rg -n -C 6 'reset_at|shortResetAt|resetAtMs|short_usage|shortUsage' src testsRepository: luvs01/opencodex Length of output: 50373 🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- reset normalization implementation ---'
sed -n '150,215p' src/codex/quota.ts
printf '%s\n' '--- parser output around normalization ---'
sed -n '493,555p' src/codex/quota.ts
printf '%s\n' '--- routing test imports and setup ---'
sed -n '1,80p' tests/routing-policy-pool-quota.test.ts
printf '%s\n' '--- normalization call sites ---'
rg -n -C 3 'function normalizeResetAt|normalizeResetAt\\(' src/codex/quota.ts src/providers/quota.tsRepository: luvs01/opencodex Length of output: 10072 🏁 Script executed: #!/bin/bash
set -e
python3 - <<'PY'
from pathlib import Path
p = Path("src/codex/quota.ts")
lines = p.read_text().splitlines()
for start, end in [(150, 215), (493, 555)]:
print(f"--- {p}:{start}-{end} ---")
for n in range(start, end + 1):
print(f"{n:4}: {lines[n-1]}")
PY
printf '%s\n' '--- exact normalization declarations ---'
rg -n -C 6 'normalizeResetAt' src/codex/quota.ts src/providers/quota.tsRepository: luvs01/opencodex Length of output: 25347 🏁 Script executed: #!/bin/bash
set -e
sed -n '170,205p' src/codex/quota.ts
sed -n '493,545p' src/codex/quota.tsRepository: luvs01/opencodex Length of output: 4906 🏁 Script executed: #!/bin/bash
set -e
python3 - <<'PY'
from pathlib import Path
lines = Path("src/codex/quota.ts").read_text().splitlines()
for start, end in [(175, 190), (493, 545)]:
print(f"--- src/codex/quota.ts:{start}-{end} ---")
for number in range(start, end + 1):
print(f"{number}: {lines[number-1]}")
PY
printf '%s\n' '--- resetAtMs contract ---'
rg -n -C 5 'interface RouteQuotaEvidence|type RouteQuotaEvidence|resetAtMs' src/routing src tests/routing-policy-pool-quota.test.ts
printf '%s\n' '--- standalone unit comparison ---'
python3 - <<'PY'
import time
now_ms = int(time.time() * 1000)
reset_seconds = 2_000_000_000
print({
"now_ms": now_ms,
"reset_seconds": reset_seconds,
"seconds_passes_ms_filter": reset_seconds > now_ms,
"reset_ms": reset_seconds * 1000,
"normalized_ms_passes_filter": reset_seconds * 1000 > now_ms,
})
PYRepository: luvs01/opencodex Length of output: 16213 🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- resetAtMs consumers ---'
rg -n -C 8 'resetAtMs' src tests -g '*.ts' | head -n 240
printf '%s\n' '--- quota evidence type and policy use ---'
rg -n -C 10 'RouteQuotaEvidence|quotaScore\\(|resetAtMs' src/routing src -g '*.ts' | head -n 320Repository: luvs01/opencodex Length of output: 9855 Normalize Codex reset timestamps before routing
Store Codex reset timestamps in milliseconds at the parser/cache boundary, or use seconds consistently across the routing contract. Add a parsed-input routing test. 🤖 Prompt for AI Agents |
||
| return { | ||
|
|
||
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.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: luvs01/opencodex
Length of output: 41578
🏁 Script executed:
Repository: luvs01/opencodex
Length of output: 50372
🏁 Script executed:
Repository: luvs01/opencodex
Length of output: 41000
Handle short-only snapshots consistently in
setAccountQuotaFromParsed.parseUsageQuotacan return only the short-window fields when the primary window is sub-day and the other windows are absent. The merge then retains stale weekly fields but drops stale monthly fields. Choose one policy for short-only snapshots: preserve both long-window fields for partial updates, or clear both for authoritative snapshots. Add a regression test for this case.🤖 Prompt for AI Agents