Skip to content

[bug]: CREDIT_LIMIT percentRemaining uses integer-rounded percentage — shows 96% left when exact is 95.25% #274

Description

@jasonisbrave

Pre-flight checks

  • I searched existing issues and did not find a duplicate.
  • I verified this on the current production released OpenCode version, or I explain why not below.

OpenCode version tested

1.18.30

opencode-quota version tested

4.9.0

Bug summary

For CREDIT_LIMIT quota windows (bigmodel.cn credit plans), percentRemaining is computed as 100 - limit.percentage, but the API's percentage field is integer-rounded. In the raw response below, percentage: 4 while exact usage is currentValue: 569 / usage: 12000 = 4.74% — so the sidebar shows 96% remaining when the exact value is 95.25%. The same response carries exact fields (usage, currentValue, remaining) that the calculation ignores.

#255 / #221 covered CREDIT_LIMIT windows being dropped entirely; once those windows are accepted (already fixed on main), this rounding is what the display shows. The rounding itself is still present on main.

Steps to reproduce

  1. Configure a Zhipu coding plan provider on bigmodel.cn (credit plan). Quota endpoint: GET https://bigmodel.cn/api/monitor/usage/quota/limit.
  2. Read the raw response for the 5h window: { "type": "CREDIT_LIMIT", "unit": 3, "usage": 12000, "currentValue": 569, "remaining": 11430, "percentage": 4 } — exact used = 569/12000 = 4.74%, but percentage is integer-rounded to 4.
  3. Run the provider query on a build where CREDIT_LIMIT windows are accepted (current main, which includes the [bug]: Zhipu Coding Plan always shows 100% used - CREDIT_LIMIT windows dropped for zhipu envelope #255 fix; on released 4.9.0 the same is observable after applying the [bug]: Zhipu Coding Plan always shows 100% used - CREDIT_LIMIT windows dropped for zhipu envelope #255 fix locally).
  4. The 5h window comes back as percentRemaining = 100 - 4 = 96, while the exact remaining is (12000 - 569) / 12000 = 95.25%.

Expected behavior

When usage and currentValue are present, percentRemaining should be derived from the exact absolute values:

clampPercent(((limit.usage - limit.currentValue) / limit.usage) * 100) = 95.25 → 95

matching remaining/usage = 11430/12000. Weekly window: 59430/60000 = 99.05% → 99. Only fall back to 100 - percentage when the absolute fields are missing.

Actual behavior

percentRemaining = clampPercent(100 - limit.percentage) = 96 — about a point off here, purely from the API's integer rounding of percentage.

Root cause

src/lib/glm-coding-plan.ts (unchanged on main):

const window = { percentRemaining: clampPercent(100 - limit.percentage), resetTimeIso };

limit.percentage is the API's rounded value; the exact usage / currentValue fields in the same response are ignored.

Suggested fix

Prefer exact absolute values for CREDIT_LIMIT, falling back to percentage only when they are missing:

- const window = { percentRemaining: clampPercent(100 - limit.percentage), resetTimeIso };
+ let percentRemaining;
+ if (limit.type === "CREDIT_LIMIT" &&
+     typeof limit.currentValue === "number" &&
+     typeof limit.usage === "number" && limit.usage > 0) {
+     percentRemaining = clampPercent(((limit.usage - limit.currentValue) / limit.usage) * 100);
+ } else {
+     percentRemaining = clampPercent(100 -
+         (typeof limit.percentage === "number" ? limit.percentage : 0));
+ }
+ const window = { percentRemaining, resetTimeIso };

Applied locally and verified: 5h window shows 95 (exact 95.25%), weekly 99 (exact 99.05%), matching remaining/usage exactly (11430/12000, 59430/60000).

Context: #255 / #221 covered CREDIT_LIMIT windows being dropped entirely; this is the precision issue that remains once those windows are accepted.

Relevant logs/output

GET https://bigmodel.cn/api/monitor/usage/quota/limit (raw response):

{
  "code": 200,
  "msg": "操作成功",
  "data": {
    "limits": [
      { "type": "CREDIT_LIMIT", "unit": 3, "usage": 12000, "currentValue": 569,
        "remaining": 11430, "percentage": 4, "nextResetTime": 1789108583924 },
      { "type": "CREDIT_LIMIT", "unit": 6, "usage": 60000, "currentValue": 569,
        "remaining": 59430, "percentage": 1, "nextResetTime": 1789694887987 }
    ]
  },
  "success": true
}

5h window, rounded vs exact:
  100 - percentage(4)          = 96      (current code)
  (12000 - 569) / 12000 * 100  = 95.25   (exact)

weekly window:
  100 - percentage(1)          = 99      (current code)
  (60000 - 569) / 60000 * 100  = 99.05   (exact)

If not tested on current production OpenCode, explain why

No response

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions