feat(providers): Z.ai Start Plan provider (OAuth login, in-process traceless captcha, gateway wire) - #4647
Draft
alexx-ftw wants to merge 7 commits into
Draft
feat(providers): Z.ai Start Plan provider (OAuth login, in-process traceless captcha, gateway wire)#4647alexx-ftw wants to merge 7 commits into
alexx-ftw wants to merge 7 commits into
Conversation
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Z.ai Start Plan provider
Adds a native
zcode-start-planprovider that serves the Z.ai Start Plan quota from the ZCode plan gateway (zcode.z.ai/api/v1/zcode-plan/anthropic) — without requiring the ZCode desktop app. Login is OpenCodex's own OAuth flow against the gateway's CLI OAuth endpoints.OAuth login
ocx login zcode-start-plan→ browser authorize → poll → plan JWT stored in the ocx auth store (multi-account ready).expclaim and has no silent refresh; gateway rejections surface as terminalneedsReauth→ re-login.Wire shape (mirrors the official client)
POST …/zcode-plan/anthropic/v1/messages, Anthropic format,Authorization: Bearer <jwt>+anthropic-versiononly — this route is exempt from the client's V4 request signing.User-Agent: ZCode/<ver> ai-sdk/anthropic/3.0.81,X-Title: Z Code@cli,X-ZCode-Agent: glmlast, per-requestx-request-id/x-zcode-trace-id,x-zcode-session-type: main.cache_controlmarking, and injectsmetadata.user_idfrom the JWT.Aliyun WAF captcha
x-aliyun-captcha-verify-paramresponse header. The adapter mints a verify param with an in-process happy-dom traceless solver (deterministic fingerprint — randomization triggers F001 — gateway cookie priming, CDN cache, guest-realm timer scoping, stall detection) and replays the request once withX-Aliyun-Captcha-Verify-Param/-Region.Atomics.wait, and any global mutation are confined to that thread — a crash or hang fails only the pending solve.1005 exceed quota limit— a per-window rate limit, not plan exhaustion) are mapped to real statuses (429/502) instead of surfacing as truncated streams. A 3012 WAF block surfaces asupstream_error.Quota
Per-account probe of
billing/balance(requires theX-Device-Midheader — its absence answers biz 3001 — persisted per install under the OpenCodex home,ZCODE_DEVICE_MIDoverrides) surfacing balance rows as custom quota windows.GUI — request log attribution
Request Logs gain an Account column resolving the opaque per-account log labels (
o<hash>,p<random>) to emails/plan via the new read-onlyGET /api/account-labels(emails masked perprivacy.maskEmails;Cache-Control: no-store).Registry
GLM-5.3,GLM-5.3-Flash(text+image),GLM-5.2,GLM-5-Turbo; 1M/200K context windows.liveModels: false— the route has no/modelslisting; the list is the client-config allowlist.Dependency
happy-dom— in-process captcha solver runtime (no browser, no headless Chrome).Tests
tests/providers/zcode-start-plan.test.ts(14 cases: identity headers, trace headers, challenge detection, body transform incl. Claude-block stripping and caller-content coercion, label mapping) + transport/layout suites.Validation
Validated live against the gateway: OAuth login, model turns (200 + streaming with
message_stop), quota probe, and recovery after per-window rate limits.Maintainer labels needed (per the PR quality gates)
The two failing checks are label-gated by design and need maintainer action:
new_suppression→suppression-approved: the vendored in-process captcha solver (src/adapters/zcode-start-plan/captcha-solver.ts, ~2.3k lines ported from a proven implementation) carries a top-level@ts-nochecklike its source; typing the port fully is follow-up work rather than review noise here.unsponsored_surface→maintainer-sponsored: touches a management route (GET /api/account-labels, read-only) and the dependency files (happy-domfor the solver runtime).Everything else the gates check is addressed in-branch: targets
dev, no empty catch blocks, bounded fetches with abort/timeout propagation, screenshot above.Review readiness checklist
This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:
Required local validation passed; commands, results, and any full-suite exception are documented.
I pushed my PR to the latest dev commit.
I resolved all correct Codex and CodeRabbit findings.
My PR is ready for review.
Summary by CodeRabbit
New Features
Bug Fixes