Skip to content

feat(server): report Z.ai coding quota through OpenCode - #11178

Closed
kolbydayley wants to merge 1 commit into
pingdotgg:mainfrom
kolbydayley:feat/zai-opencode-quota
Closed

kolbydayley wants to merge 1 commit into
pingdotgg:mainfrom
kolbydayley:feat/zai-opencode-quota

Conversation

@kolbydayley

@kolbydayley kolbydayley commented Sep 11, 2026 •

Copy link
Copy Markdown

What Changed

OpenCode users authenticated with Z.AI Coding Plan can run GLM turns, but their provider snapshot never includes the subscription quota. This adds Z.ai's coding and MCP quota windows to the existing usageLimits snapshot during the OpenCode status probe, so the existing Limits view and /usage-limits command can consume them.

The reader uses the credential OpenCode resolved for that server, including configured remote OpenCode servers. It calls Z.ai's read-only quota endpoint, keeps coding and MCP windows distinct, preserves provider reset timestamps, and bounds the request to five seconds. A failed quota request leaves the coding provider ready and uses the existing last-good-quota behavior. Custom endpoints, plugin-managed auth, and unavailable credentials are reported as unsupported instead of guessing a host-local account.

Why

This fills the Z.ai subscription-headroom gap using the existing OpenCode integration and wire contract. It adds no provider driver, configuration setting, database migration, client schema, or polling process. The endpoint is the one used by Z.ai's official usage plugin.

Related to #5539 and discussion #8148. Historical OpenCode token/cost reporting remains in #8456; this PR does not duplicate or depend on that work. These limits are account-wide, including consumption outside T3 Code.

Validation

  • 72 focused tests across the quota reader, OpenCode status probe, quota reconciliation, and shared Limits selection/pooling logic.
  • Server typecheck, targeted lint/formatting, and git diff --check.
  • Server and service-launcher bundles.
  • Live read-only smoke using an isolated OpenCode server: the resolved Coding Plan credential returned coding and MCP windows through the new reader. No credentials or account data are included in fixtures or this PR.

No frontend components or layouts changed; the existing cross-client Limits contract carries the new data. No installed app or production state was modified for this contribution.

Checklist

  • This PR is small and focused
  • I explained what changed and why

Built with GPT-6 in the Codex harness through T3 Code.

Summary by CodeRabbit

  • New Features
    • OpenCode connections using the Z.AI Coding Plan now display coding allowance, reset times, and separate MCP tool usage limits.
    • Limit information refreshes with the Limits view and indicates when quota data is unavailable.
  • Documentation
    • Added guidance about account-wide limits and unsupported custom endpoints or plugin-managed authentication.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 11, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-11T02:54:54.417785Z 2e55b98 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Sep 11, 2026

const PROVIDER_ID = "zai-coding-plan";
const CODING_URL = "https://api.z.ai/api/coding/paas/v4";
const QUOTA_URL = "https://api.z.ai/api/monitor/usage/quota/limit";

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.

🟠 High Layers/zaiUsageLimits.ts:17

Current Z.ai Coding Plan keys receive 401 from /api/monitor/usage/quota/limit, so this request is converted to probeFailed and no quota windows are published. Use /api/monitor/usage, which serves the live quota response.

Suggested change
const QUOTA_URL = "https://api.z.ai/api/monitor/usage/quota/limit";
const QUOTA_URL = "https://api.z.ai/api/monitor/usage";
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/provider/Layers/zaiUsageLimits.ts around line 17:

Current Z.ai Coding Plan keys receive `401` from `/api/monitor/usage/quota/limit`, so this request is converted to `probeFailed` and no quota windows are published. Use `/api/monitor/usage`, which serves the live quota response.

});

function quotaWindow(limit: typeof Limit.Type): ServerProviderUsageWindow | undefined {
if (limit.type !== "TOKENS_LIMIT" && limit.type !== "TIME_LIMIT") return undefined;

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.

🟠 High Layers/zaiUsageLimits.ts:32

quotaWindow discards CREDIT_LIMIT rows, so current Z.ai Coding Plan responses containing the five-hour and weekly allowances produce no supported windows and are reported as unsupported instead of displaying the account's limits. Include CREDIT_LIMIT as a supported limit type.

-  if (limit.type !== "TOKENS_LIMIT" && limit.type !== "TIME_LIMIT") return undefined;
+  if (limit.type !== "TOKENS_LIMIT" && limit.type !== "TIME_LIMIT" && limit.type !== "CREDIT_LIMIT") return undefined;
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/provider/Layers/zaiUsageLimits.ts around line 32:

`quotaWindow` discards `CREDIT_LIMIT` rows, so current Z.ai Coding Plan responses containing the five-hour and weekly allowances produce no supported windows and are reported as `unsupported` instead of displaying the account's limits. Include `CREDIT_LIMIT` as a supported limit type.

@macroscopeapp

macroscopeapp Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR adds a new production Z.ai quota integration, including authenticated outbound requests and user-facing usage windows in OpenCode provider snapshots. The implementation also has unresolved high-severity findings concerning the live endpoint and response limit types, so the behavior and credential flow need human review.

Not approved because:

  • 2 blocking correctness issues found at or above your repo's Minimum Blocking Severity

Adjust the Minimum Blocking Severity for this repo — including turning it Off — in Settings. You can add or adjust custom eligibility rules. Learn more.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2e55b98288

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

installed: true,
version,
status: connectedCount > 0 ? "ready" : "warning",
...(usageLimits ? { usageLimits } : {}),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Scope Z.ai quota to Z.ai-backed models

When an OpenCode instance has another upstream connected alongside Z.ai, this attaches Z.ai's quota to the entire OpenCode provider snapshot. Both web and mobile offer /usage-limits and build its report using only the OpenCode driver/instance (packages/shared/src/usageLimits.ts:639-649), without inspecting the selected model slug, so a thread using an Anthropic, OpenAI, or other non-Z.ai model through that instance is shown Z.ai quota as the current model's limits. Publish or advertise these limits with upstream-model scope instead.

Useful? React with 👍 / 👎.

Comment on lines +525 to +528
const usageLimits = yield* readOpenCodeZaiUsageLimits(
inventoryExit.value.inventory.providerList,
checkedAt,
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Deduplicate the account-wide Z.ai subscription

When the same Z.ai account is connected through two environments or OpenCode instances, these account-wide windows carry no stable account identity: the resulting OpenCode auth object supplies only status/type, so collectLimitAccounts falls back to ${environmentId}:${provider.instanceId} at packages/shared/src/usageLimits.ts:257-258 and pools each copy as a separate account. This can double the displayed available quota even though both snapshots describe the same subscription; provide an identity usable for deduplication or otherwise prevent duplicate Z.ai subscriptions from being summed.

AGENTS.md reference: AGENTS.md:L74-L74

Useful? React with 👍 / 👎.

@coderabbitai

coderabbitai Bot commented Sep 11, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: da89bd14-eb21-4f7a-aac7-3f88f1e592a5

📥 Commits

Reviewing files that changed from the base of the PR and between 20ef250 and 2e55b98.

📒 Files selected for processing (6)
  • apps/server/src/provider/Drivers/OpenCodeDriver.ts
  • apps/server/src/provider/Layers/OpenCodeProvider.test.ts
  • apps/server/src/provider/Layers/OpenCodeProvider.ts
  • apps/server/src/provider/Layers/zaiUsageLimits.test.ts
  • apps/server/src/provider/Layers/zaiUsageLimits.ts
  • docs/user/usage.md

Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

OpenCode provider checks now retrieve Z.ai Coding Plan usage limits through the Z.ai quota endpoint. The limits are mapped into provider snapshots, unavailable probes preserve provider readiness, credentials remain excluded from snapshots, and documentation describes the reported quota windows.

Changes

Z.ai quota reporting

Layer / File(s) Summary
Z.ai quota validation and mapping
apps/server/src/provider/Layers/zaiUsageLimits.ts, apps/server/src/provider/Layers/zaiUsageLimits.test.ts
The new quota reader validates responses, selects eligible Z.ai credentials, maps quota units to usage windows, clamps percentages, and handles unsupported data, HTTP errors, and timeouts.
Provider probe integration
apps/server/src/provider/Layers/OpenCodeProvider.ts, apps/server/src/provider/Drivers/OpenCodeDriver.ts
The OpenCode provider status check retrieves Z.ai limits and adds them to the provider draft. The driver provides the HTTP client service required by the check.
Snapshot validation and documentation
apps/server/src/provider/Layers/OpenCodeProvider.test.ts, docs/user/usage.md
Tests verify published quota data, credential omission, and authenticated readiness after quota probe failure. Documentation describes Z.AI Coding Plan limits and reporting constraints.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant OpenCodeDriver
  participant OpenCodeProvider
  participant HttpClient
  participant ZAIQuotaEndpoint
  OpenCodeDriver->>OpenCodeProvider: checkProvider
  OpenCodeProvider->>HttpClient: request Z.ai usage limits
  HttpClient->>ZAIQuotaEndpoint: send bearer-authenticated quota request
  ZAIQuotaEndpoint-->>HttpClient: return quota response
  HttpClient-->>OpenCodeProvider: return mapped usage limits
  OpenCodeProvider-->>OpenCodeDriver: publish provider snapshot
Loading

Suggested reviewers: juliusmarminge, t3dotgg, utkarshusername

Merge Risk: ⚪ Minimal · up to 2e55b

The quota integration has no substantiated merge-blocking issue and is ready for normal validation and merge.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 5 files. (1 skipped: 1 … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely identifies the main change: reporting Z.ai coding quota through the OpenCode integration.
Description check ✅ Passed The description includes clear What Changed and Why sections, explains scope and validation, and provides the applicable checklist items. UI Changes are correctly omitted because the pull request has …
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.
Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 5 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@juliusmarminge

Copy link
Copy Markdown
Member

Thanks for the PR. We're not taking changes to the orchestration and provider layers right now: that part of the server is being rewritten for V2, and merging into the current code would either conflict with or be thrown away by that work.

Closing for now. If this is still an issue once V2 lands, please reopen (or open a fresh PR against the new code) and we'll take a proper look.

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

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants