fix(zai): distinguish session/weekly/monthly TOKENS_LIMIT entries by unit - #181
Conversation
…`unit` Z.ai's GLM Coding Plan API returns multiple TOKENS_LIMIT entries that share the same `type` string and are distinguished only by an integer `unit` field. The previous parser mapped every TOKENS_LIMIT to `.session`, so the second entry — the weekly token quota — silently overwrote (or was overwritten by) the 5-hour session quota. The weekly cap is the most important number for users on the GLM Coding Plan; this bug made ClaudeBar useless for tracking it.
📝 WalkthroughWalkthroughThe PR enhances ZaiUsageProbe's quota parsing with unit-awareness by adding an optional unit field to QuotaLimit and converting the quota-type mapping from type-only logic to a tuple-based switch on (type, unit). This enables discrimination of TOKENS_LIMIT quotas by unit values while preserving unknown unit configurations and maintaining backward compatibility. ChangesUnit-Aware Quota Parsing
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly Related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
Sources/Infrastructure/Zai/ZaiUsageProbe.swift (1)
311-329: ⚡ Quick winAdd warning logs to detect API drift in Zai quota parsing.
The switch statement handles known quota types but silently swallows API changes in two paths:
case ("TOKENS_LIMIT", let unit?): Unknown units map to.modelSpecific("Tokens (unit \(unit))")without any log. If z.ai introduces a new quota tier, the team only learns through a strange UI label.default: Unknown limit types silentlycontinuewith no trace.Per coding guidelines,
.warning()writes to both OSLog and~/Library/Logs/ClaudeBar/ClaudeBar.log, so adding a single log line in each path surfaces API changes immediately without altering behavior.Also consider changing
case ("TIME_LIMIT", _)tocase ("TIME_LIMIT", 5)to match the documented mapping (unit=5 → MCP); unexpected TIME_LIMIT units would then log via the observability path instead of silently assuming "MCP".♻️ Proposed observability hooks
switch (limit.type, limit.unit) { - case ("TIME_LIMIT", _): + case ("TIME_LIMIT", 5): quotaType = .timeLimit("MCP") case ("TOKENS_LIMIT", 3): quotaType = .session case ("TOKENS_LIMIT", 6): quotaType = .weekly case ("TOKENS_LIMIT", 7): quotaType = .modelSpecific("Monthly") case ("TOKENS_LIMIT", nil): // Backward-compat: legacy responses with no `unit` field default to session. quotaType = .session case ("TOKENS_LIMIT", let unit?): // Unknown unit — preserve via modelSpecific so it isn't dropped/collapsed. + AppLog.probes.warning("Zai: Unknown TOKENS_LIMIT unit=\(unit) — preserving as modelSpecific. API may have changed.") quotaType = .modelSpecific("Tokens (unit \(unit))") default: - // Skip unknown limit types + // Skip unknown limit types but log so we can spot API drift. + AppLog.probes.warning("Zai: Unknown limit type='\(limit.type)' unit=\(limit.unit.map(String.init) ?? "nil") — skipping.") continue }
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d38c186e-a250-456d-a093-05b559eb12fe
📒 Files selected for processing (2)
Sources/Infrastructure/Zai/ZaiUsageProbe.swiftTests/InfrastructureTests/Zai/ZaiUsageProbeParsingTests.swift
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #181 +/- ##
==========================================
+ Coverage 80.55% 80.59% +0.04%
==========================================
Files 109 109
Lines 8085 8103 +18
==========================================
+ Hits 6513 6531 +18
Misses 1572 1572
🚀 New features to boost your workflow:
|
Summary
Z.ai's GLM Coding Plan API returns multiple
TOKENS_LIMITentries that share the sametypestring and are distinguished only by an integerunitfield. The previous parser mapped everyTOKENS_LIMIT→.session, so the second entry — the weekly token quota — silently collapsed with the 5-hour session quota.The weekly cap is arguably the most important number for users on the GLM Coding Plan; the bug made ClaudeBar's Z.ai tab useless for tracking it.
Repro
Live API response from
GET https://api.z.ai/api/monitor/usage/quota/limit:Summary by CodeRabbit
New Features
Tests