Fix z.ai 5-hour token quota discarded when API returns multiple TOKENS_LIMIT entries#632
Fix z.ai 5-hour token quota discarded when API returns multiple TOKENS_LIMIT entries#632takumi3488 wants to merge 4 commits intosteipete:mainfrom
Conversation
|
I validated this against real Z.ai data from my local CodexBar setup, using the same configured token/account the app is What I found:
I also compared main vs this branch against that real account, and both behave the same:
So from the real data I have, I can’t confirm an actual bug that this PR fixes. The approach seems reasonable if Z.ai really does return two TOKENS_LIMIT entries for some accounts, but I wasn’t able to reproduce that. If you have a redacted real response showing the extra weekly TOKENS_LIMIT entry, that would help validate both the problem and the fix. |
The z.ai API can return two TOKENS_LIMIT entries — one for the 5-hour window (unit:3/number:5) and one for the weekly window (unit:6/number:1). Previously the second entry silently overwrote the first, discarding the 5-hour quota entirely. Changes: - Add ZaiLimitUnit.weeks (rawValue 6) with windowMinutes = n×7×24×60 - Add ZaiUsageSnapshot.sessionTokenLimit for the shorter-window entry - Rewrite parseUsageSnapshot to collect all TOKENS_LIMIT entries and sort by windowMinutes: shorter → sessionTokenLimit (tertiary), longer → tokenLimit (primary), preserving the existing display unchanged for APIs that return only one TOKENS_LIMIT - Map sessionTokenLimit to UsageSnapshot.tertiary in toUsageSnapshot() - Enable supportsOpus + opusLabel "5-hour" in ZaiProviderDescriptor so MenuCardView/MenuDescriptor/CLIRenderer render the new tertiary row - Wire zaiSessionDetail text into the tertiary card metric - Add ZaiThreeLimitTests covering 3-entry parsing, unit:6 enum, and backward-compatible 2-entry fallback
3daf900 to
9a39d0b
Compare
|
Correction on my previous comment — I said the 3-limit response was "plan-specific" (Coding Plan vs other plans), but that's not accurate. Per the Z.ai DevPack FAQ:
So the actual difference is subscription start date, not plan tier. Your account is likely also on Coding Plan, but since you subscribed before Feb 12, you have unlimited weekly usage — meaning Z.ai doesn't return the weekly Accounts that subscribed after Feb 12 receive a weekly quota, which adds the second Sorry for the confusion — the backward-compat analysis still holds (accounts without the weekly limit are unaffected), but the root cause of the difference is subscription date, not plan tier. |
|
Opened a superseding PR here: #662 Thanks again, @takumi3488, for the original fix and for the extra payload/context that helped validate the edge case and carry this forward. |


Summary
The z.ai API returns up to three quota entries — a 5-hour
TOKENS_LIMIT, a weeklyTOKENS_LIMIT, and aTIME_LIMIT(MCP). The parse loop used a singletokenLimitvariable, so the second entry silently overwrote the first and the 5-hour quota was lost.ZaiLimitUnit.weeks(rawValue 6) so the weekly entry gets a correctwindowMinutesTOKENS_LIMITentries and sort by window size: shorter window →sessionTokenLimit(tertiary slot), longer →tokenLimit(primary slot)sessionTokenLimittoUsageSnapshot.tertiaryand enablesupportsOpus/opusLabel: "5-hour"in the descriptor so MenuCardView, MenuDescriptor, and CLI all render the new rowzaiSessionDetailtext into the tertiary card metricTOKENS_LIMIT+TIME_LIMIT,sessionTokenLimitis nil and the tertiary row is suppressedValidation
swift buildpassesZaiThreeLimitTests: 3-entry parse,unit:6enum, and 2-entry backward-compat fallbackZaiMenuCardTests, a new test inCodexPresentationCharacterizationTests, and a new test inCLISnapshotTestscovering the tertiary row at all three rendering layers