Skip to content

fix(zai): recognize CREDIT_LIMIT quota entries for credit-based plan tiers - #240

Open
digivisions wants to merge 2 commits into
tddworks:mainfrom
digivisions:zai-credit-limit
Open

fix(zai): recognize CREDIT_LIMIT quota entries for credit-based plan tiers#240
digivisions wants to merge 2 commits into
tddworks:mainfrom
digivisions:zai-credit-limit

Conversation

@digivisions

@digivisions digivisions commented Aug 1, 2026

Copy link
Copy Markdown

Problem

On credit-based GLM plan tiers ("level": "lite"), the Z.ai provider fails
with Z.ai Unavailable — Failed to parse output: No recognized quota types found,
even though the account is valid and /api/monitor/usage/quota/limit returns HTTP 200
with complete quota data.

Root cause

ZaiUsageProbe.parseQuotaLimitResponse switches on (limit.type, limit.unit) and
only matches TIME_LIMIT and TOKENS_LIMIT. Credit-based tiers report the same
information under CREDIT_LIMIT, so every entry hits the default: continue,
quotas ends up empty, and the guard throws.

Actual response from a lite account (values redacted for privacy):

{
  "code": 200,
  "data": {
    "limits": [
      { "type": "CREDIT_LIMIT", "unit": 3, "number": 5, "usage": 2000,
        "currentValue": 0, "remaining": 2000, "percentage": 0 },
      { "type": "CREDIT_LIMIT", "unit": 6, "number": 1, "usage": 10000,
        "currentValue": 2004, "remaining": 7995, "percentage": 20,
        "nextResetTime": 1786112351998 }
    ],
    "level": "lite"
  },
  "success": true
}

The unit semantics are identical to TOKENS_LIMIT3 is the rolling 5-hour
window and 6 is the rolling multi-day window — so the existing mapping from #181
applies unchanged.

Fix

Add CREDIT_LIMIT to each existing case rather than duplicating the mapping, plus a
catch-all so unrecognised units surface as Credits (unit N) instead of being dropped
silently — mirroring the existing Tokens (unit N) behaviour.

Tests

Five new cases in ZaiUsageProbeParsingTests: full credit-plan response, unit=3
session, unit=6 → weekly, unknown-unit preservation, and a mixed
TOKENS_LIMIT/CREDIT_LIMIT/TIME_LIMIT response. tuist test Infrastructure
passes (22 tests).

Verified end-to-end against a live lite account: probe now logs
Zai probe success: 2 quotas found and both windows render in the menu bar.

No behaviour change for token-based plans.

Summary by CodeRabbit

  • Bug Fixes

    • Improved quota reporting for credit-based plans.
    • Session, weekly, and monthly credit limits are now categorized correctly.
    • Unknown credit units are preserved as model-specific quotas.
    • Mixed quota responses are handled more reliably.
  • Tests

    • Added coverage for credit plans, quota unit mappings, unknown units, and mixed response payloads.

Credit-based GLM plan tiers (e.g. Coding Lite) return quota entries with
type CREDIT_LIMIT rather than TOKENS_LIMIT. The parser only matched
TOKENS_LIMIT/TIME_LIMIT tuples and hit the default continue for anything
else, so every entry was skipped and the probe failed with
"No recognized quota types found".

Map CREDIT_LIMIT using the same unit semantics as TOKENS_LIMIT
(3 = session, 6 = weekly, 7 = monthly) and preserve unknown units via
modelSpecific instead of dropping them.
@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The Zai usage probe now parses CREDIT_LIMIT entries with unit-aware quota classification. Tests cover known units, missing units, unknown units, and mixed quota payloads.

Changes

Zai credit quota support

Layer / File(s) Summary
Classify and test CREDIT_LIMIT quotas
Sources/Infrastructure/Zai/ZaiUsageProbe.swift, Tests/InfrastructureTests/Zai/ZaiUsageProbeParsingTests.swift
The parser maps known units to session, weekly, and monthly quotas. It defaults missing units to session and preserves unknown units as modelSpecific. Tests cover these mappings and mixed quota types.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding recognition for CREDIT_LIMIT quota entries in Z.ai parsing.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Sources/Infrastructure/Zai/ZaiUsageProbe.swift`:
- Around line 318-319: Update the unit-7 handling in the quota mapping switch to
use .timeLimit("Monthly") for both TOKENS_LIMIT and CREDIT_LIMIT, preserving the
monthly duration and persisted key. Add a regression test covering CREDIT_LIMIT
with unit 7 and asserting the monthly time-limit behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 231f9f01-11bb-4772-ba00-d28115613cca

📥 Commits

Reviewing files that changed from the base of the PR and between 92b9351 and b7ea647.

📒 Files selected for processing (2)
  • Sources/Infrastructure/Zai/ZaiUsageProbe.swift
  • Tests/InfrastructureTests/Zai/ZaiUsageProbeParsingTests.swift

Comment on lines +318 to 319
case ("TOKENS_LIMIT", 7), ("CREDIT_LIMIT", 7):
quotaType = .modelSpecific("Monthly")

Copy link
Copy Markdown
Contributor

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

Map unit 7 to the monthly time quota.

Line 319 creates modelSpecific("Monthly"). That type has a seven-day duration and the persisted key model:Monthly. Use .timeLimit("Monthly") so the quota has the 30-day monthly duration and the time:Monthly key. Add a CREDIT_LIMIT unit 7 regression test.

Proposed fix
 case ("TOKENS_LIMIT", 7), ("CREDIT_LIMIT", 7):
-    quotaType = .modelSpecific("Monthly")
+    quotaType = .timeLimit("Monthly")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
case ("TOKENS_LIMIT", 7), ("CREDIT_LIMIT", 7):
quotaType = .modelSpecific("Monthly")
case ("TOKENS_LIMIT", 7), ("CREDIT_LIMIT", 7):
quotaType = .timeLimit("Monthly")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Sources/Infrastructure/Zai/ZaiUsageProbe.swift` around lines 318 - 319,
Update the unit-7 handling in the quota mapping switch to use
.timeLimit("Monthly") for both TOKENS_LIMIT and CREDIT_LIMIT, preserving the
monthly duration and persisted key. Add a regression test covering CREDIT_LIMIT
with unit 7 and asserting the monthly time-limit behavior.

@codecov

codecov Bot commented Aug 2, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.98%. Comparing base (92b9351) to head (b7ea647).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #240      +/-   ##
==========================================
- Coverage   83.13%   82.98%   -0.15%     
==========================================
  Files         123      123              
  Lines        9704     9708       +4     
==========================================
- Hits         8067     8056      -11     
- Misses       1637     1652      +15     
Files with missing lines Coverage Δ
Sources/Infrastructure/Zai/ZaiUsageProbe.swift 86.99% <100.00%> (+0.21%) ⬆️

... and 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants