Skip to content

fix(glm-coding-plan): recognize CREDIT_LIMIT windows for the Zhipu descriptor - #256

Merged
slkiser merged 1 commit into
slkiser:mainfrom
ConcealedBlade:fix/zhipu-credit-limit
Sep 7, 2026
Merged

fix(glm-coding-plan): recognize CREDIT_LIMIT windows for the Zhipu descriptor#256
slkiser merged 1 commit into
slkiser:mainfrom
ConcealedBlade:fix/zhipu-credit-limit

Conversation

@ConcealedBlade

@ConcealedBlade ConcealedBlade commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #255

The Zhipu Coding Plan provider renders as 100% used regardless of actual usage
whenever the account returns CREDIT_LIMIT quota windows (credit-based plans, e.g.
Lite on bigmodel.cn). Auth resolves and the HTTP request succeeds (/quota_status
reports zhipu: enabled available), but every window is silently dropped during
parsing, so the UI falls back to the fully-used display with no error surfaced.

The parser already handles CREDIT_LIMIT — but only for the Z.ai descriptor. This
change removes the envelope gate on the window type so both descriptors treat
CREDIT_LIMIT identically.

Root cause (timeline of two changes)

This is a coverage gap between two merged changes, not a faulty provider:

  1. 2026-05-08 — feat: add Zhipu Coding Plan provider (domestic China) #78 (bc5c20e) introduces the Zhipu provider. At that point
    glm-coding-plan.ts accepted only TOKENS_LIMIT windows, and the Zhipu test
    fixtures mocked TOKENS_LIMIT responses only.

  2. 2026-08-16 — 928a16e "fix(provider): support Z.ai credit quota windows"
    teaches the parser to recognize CREDIT_LIMIT units 3 and 6 as the existing
    fiveHour/weekly percent windows — because Z.ai credit-plan users were hitting
    the same empty-windows failure. The envelope gate added there,
    (descriptor.envelope === "zai" && limit.type === "CREDIT_LIMIT"), scoped the
    fix to Z.ai only; the existing test "maps Z.ai credit limits…" even asserted
    the Zhipu descriptor returns windows: {} for the same payload.

  3. Result: Zhipu + credit-plan responses still drop every window on current
    main.

Live capture against bigmodel.cn with a valid Lite key (before this change:
opencode-quota show renders [Zhipu] 100% used):

{"code":200,"success":true,"data":{"limits":[
  {"type":"CREDIT_LIMIT","unit":3,"number":5,"usage":2000,"currentValue":27,"remaining":1972,"percentage":1,"nextResetTime":1788739057523},
  {"type":"CREDIT_LIMIT","unit":6,"number":1,"usage":10000,"currentValue":3193,"remaining":6806,"percentage":31,"nextResetTime":1789095331982}],
"level":"lite"}}

The request succeeds → auth resolves → limits parses → the type filter rejects
both entries → windows is {} → the display silently degrades to "100% used".

Why the type filter cannot be envelope-gated

CREDIT_LIMIT is not platform-specific:

  • Z.ai (international): commit 928a16e exists precisely because Z.ai returns
    CREDIT_LIMIT windows with units 3 and 6; its test pins the mapping.
  • Zhipu (domestic): live payload above.

The official Z.ai plugin
(zai-org/zai-coding-plugins,
plugins/glm-plan-usage/.../scripts/query-usage.mjs) confirms both platforms are
one API surface: identical endpoint paths (/api/monitor/usage/quota/limit), auth
(raw key in Authorization), envelope (data.limits[]), and unit semantics —
differing only by domain (api.z.ai vs open.bigmodel.cn). Whether the
TOKENS_LIMIT vs CREDIT_LIMIT split maps strictly to plan tiers is likely but
unverified; the fix only requires the proven fact that both types occur on both
platforms
. (The official plugin maps TOKENS_LIMIT → "Token usage(5 Hour)" and
TIME_LIMIT → "MCP usage(1 Month)", matching the unit semantics already
implemented in this parser.)

Fix

Smallest safe change — drop the envelope gate on the type (src/lib/glm-coding-plan.ts):

-          const isQuotaWindow =
-            limit.type === "TOKENS_LIMIT" ||
-            (descriptor.envelope === "zai" && limit.type === "CREDIT_LIMIT");
+          const isQuotaWindow = limit.type === "TOKENS_LIMIT" || limit.type === "CREDIT_LIMIT";

Everything else already matches the official reference and is covered by existing
tests: unit 3 → fiveHour, unit 6 → weekly, TIME_LIMITmcp,
percentRemaining = clampPercent(100 - percentage) (the API's percentage is the
used percent — live: 27/2000 → percentage 1), nextResetTime epoch-ms.

This change intentionally does not start surfacing raw credit amounts
(usage/currentValue/remaining): 928a16e explicitly deferred that until
provider units are defined, and its tests assert windows stay percent-only. That
invariant is preserved.

Tests updated

tests/lib.glm-coding-plan.test.ts — the existing case
"maps Z.ai credit limits to percent windows…" asserted the broken behavior for
Zhipu (windows: {}). It now:

  • runs the same CREDIT_LIMIT units 3/6 payload through both descriptors and
    asserts populated fiveHour/weekly percent windows for each;
  • keeps the no-credit-amounts assertions for both providers
    (not.toHaveProperty("windows.fiveHour.usage" | "currentValue" | "remaining"));
  • is retitled "maps credit limits to percent windows for both providers without
    inferring credit amounts".

OpenCode Validation

  • Current production released OpenCode version tested: 1.18.29
  • Why this version is relevant: this is the reporter's daily-driver OpenCode
    version where the broken [Zhipu] 100% used rendering was observed, and where
    the fixed rendering was re-verified.

Live end-to-end against bigmodel.cn (valid Lite key), opencode-quota show:

Before:

[Zhipu]
Zhipu
█████████████████████████  100% used

After:

[Zhipu]
Five-hour   1% used   (resets in ~5h)
Weekly     31% used   (resets in ~4d)

Quality Checklist

  • I ran pnpm run typecheck
  • I ran pnpm run build
  • I ran pnpm test
  • This change is focused and avoids unrelated behavior changes
  • I updated or added tests when behavior changed
  • I updated docs when user-facing workflow, command, or config behavior changed — N/A: no user-facing config/workflow change
  • For provider changes, I followed Provider Changes / provider-template — N/A: behavior fix to an existing provider, not a new provider

@slkiser
slkiser merged commit 173f5da into slkiser:main Sep 7, 2026
4 checks passed
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.

[bug]: Zhipu Coding Plan always shows 100% used - CREDIT_LIMIT windows dropped for zhipu envelope

2 participants