Support Qwen Cloud personal token plan, and unblock Alibaba Token Plan on Linux#2329
Support Qwen Cloud personal token plan, and unblock Alibaba Token Plan on Linux#2329Yach0 wants to merge 2 commits into
Conversation
The Qwen Cloud personal ("solo") token plan is a different product from the
team edition already supported: it lives on home.qwencloud.com, posts to a
separate gateway host, tunnels a REST path through the generic ASPN action,
and reports rolling 5-hour/weekly windows instead of a monthly credit pool.
Add a qwen region covering that gateway, and model the two quota shapes as an
enum so the invalid mixes of the previous optional fields are unrepresentable.
Also exempt the provider from the macOS web-support gate when cookies are
supplied manually, matching qoder/opencodego/commandcode. The quota fetch is
plain URLSession plus cookies; only browser cookie import needs macOS, so the
provider was unreachable on Linux for no reason.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 73ebb460e5
ℹ️ 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".
| if provider == .alibabatokenplan, | ||
| settings?.alibabaTokenPlan?.cookieSource == .manual |
There was a problem hiding this comment.
Include ALIBABA_TOKEN_PLAN_COOKIE in Linux bypass
This bypass only covers config snapshots where cookieSource == .manual, but the provider also supports a manually supplied cookie via ALIBABA_TOKEN_PLAN_COOKIE in AlibabaTokenPlanWebFetchStrategy.resolveCookieHeaders. On Linux, a user who sets that existing env var while leaving the config at the default auto mode is still stopped by this gate before the strategy can read the cookie, so the provider remains unusable in that manual-cookie setup; add the same env-cookie check here that other providers such as Sakana use.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Good catch — fixed in b1efecb.
You are right that resolveCookieHeaders reads ALIBABA_TOKEN_PLAN_COOKIE independently of cookieSource, so gating only on cookieSource == .manual blocked a setup that would otherwise have worked. The gate now also opens on the env cookie, mirroring the Sakana check:
if provider == .alibabatokenplan,
settings?.alibabaTokenPlan?.cookieSource == .manual ||
environment.map({ AlibabaTokenPlanSettingsReader.cookieHeader(environment: $0) != nil }) == true
{
return false
}Since cookieHeader(environment:) goes through cleaned(...), a blank or whitespace-only value still leaves the gate closed rather than letting the provider through to fail later.
Verified on Linux with the config left at the default auto mode:
- no env var →
selected source requires web support and is only supported on macOS(unchanged) ALIBABA_TOKEN_PLAN_COOKIE=...→ real usage returned
Added three cases for it (env-only opens the gate, whitespace-only does not, browser-import still gated). Suite is at 311 passing.
The env cookie is honored regardless of the configured cookie source, so a user setting only that variable was still blocked before the strategy could read it. Mirrors the existing Sakana env-cookie check.
|
Codex review: needs real behavior proof before merge. Reviewed July 19, 2026, 11:12 AM ET / 15:12 UTC. Summary Reproducibility: yes. for the Linux gate at source level: the added condition shows that manual cookies and ALIBABA_TOKEN_PLAN_COOKIE were previously rejected before fetching. The Qwen live gateway path is claimed by the contributor but lacks inspectable after-fix output. Review metrics: 1 noteworthy metric.
Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Risk before merge
Maintainer options:
Next step before merge
Maintainer decision needed
Security Review detailsBest possible solution: If the manual-cookie Qwen workflow is approved, retain or deliberately deprecate the prior public snapshot surface, keep browser import disabled, and land the feature with a redacted Fedora live-run transcript proving both rolling windows. Do we have a high-confidence way to reproduce the issue? Yes for the Linux gate at source level: the added condition shows that manual cookies and ALIBABA_TOKEN_PLAN_COOKIE were previously rejected before fetching. The Qwen live gateway path is claimed by the contributor but lacks inspectable after-fix output. Is this the best way to solve the issue? Unclear. Reusing the provider and sharing transport logic is a narrow implementation, but accepting a manual-cookie-only Qwen region and removing the prior public snapshot API both need explicit compatibility and product confirmation. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 76772d7d60a5. Label changesLabel changes:
Label justifications:
Evidence reviewedWhat I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
Review history (1 earlier review cycle)
|
Closes #2328.
Adds support for the Qwen Cloud personal/solo token plan, and unblocks the provider on Linux.
Why this isn't just a new region string
The existing
alibabatokenplanprovider targets the Team Edition (GetSubscriptionSummary,product=BssOpenAPI-V3) and models a monthly credit pool. The personal plan onhome.qwencloud.comis a different product end to end: different console, different gateway host,a REST path tunneled through a generic ASPN action, and rolling 5-hour + weekly windows rather
than a credit pool — i.e. the same shape as Claude/Codex.
Payloads nest at
data.DataV2.data.data:usage—per5HourPercentage/per1WeekPercentage(fractions of 1.0) plus reset times inepoch ms. Required.
subscription—specCode(lite/standard/pro),status. Best-effort.quota-config— per-tierfive_hour/weeklyceilings, joined onspecCodeto convert thepercentages into credit counts. Best-effort, and skipped entirely when no tier is known.
sec_tokenresolves fromGET https://home.qwencloud.com/tool/user/info.json— the same/tool/user/info.jsonpath the team edition already uses, so the existing resolver is reused as isand cookies alone are sufficient.
Changes
qwenregion covering that gateway, withquotaAPIBaseURLStringsplit from the consolehost (Qwen serves them separately) and
tokenPlanProductCodemade optional since the personalgateway takes none.
AlibabaTokenPlanPersonalAPI— request builders and parsers for the three endpoints.creditPool/rollingWindows) instead of four nullablefields, so the combinations that were never valid are now unrepresentable. The
creditPoolpathis behaviourally identical to before.
performGatewayRequestextracted so both editions share the cookie /sec_token/ redirectmachinery. Usage is required; the two enrichment calls are best-effort and cannot abort a
fetch that already has valid data.
configured manually, matching the existing
qoder/opencodego/commandcode/cursorprecedent. The quota fetch is plainURLSession+ cookies — only browser cookieimport needs macOS, so the provider was unreachable on Linux for no reason.
Drive-by fix
URLComponents.percentEncodedQueryleaves+literal, and anapplication/x-www-form-urlencodedreader decodes it as a space — so asec_tokencontaining+was silently corrupted. This affected the existing team edition too; both body builders now go
through a shared
formEncodedBodythat escapes it.Notes / limitations
region: "qwen"is manual-cookie only on every platform. Qwen Cloud logs in under its owndomain with its own ticket cookie (
login_qwencloud_ticket), which the shared Alibaba browserimporter's authentication gate does not recognise. Rather than widen that shared importer — which
would have leaked qwencloud cookies into the Alibaba Coding Plan's unscoped request header —
auto-import is rejected up front with a message pointing at the console. Documented in
docs/alibaba-token-plan.md.the existing
isLoginOrTokenError/isLikelyLoginHTMLdetectors. Without that they surface as.apiError, which is not anisCredentialFailure, and the cookie re-import retry never fires.ProviderMetadata(sessionLabel: "Credits",weeklyLabel: "Usage"). Those fit the team edition's credit pool but read oddly for 5-hour /weekly windows, where "Session" / "Weekly" would be right. Making them region-aware needs
settings plumbed into metadata resolution, so I left it alone rather than guess at the shape you'd
want — happy to follow up.
sk-sp-*key againsttoken-plan.ap-southeast-1.maas.aliyuncs.comroutes only/compatible-mode/v1/*,/apps/anthropic/v1/messagesand/api/v1/services/aigc/*; every billing path 404s unrouted,successful responses carry no rate-limit headers, and posting the key to the console gateway
returns
ConsoleNeedLogin. Cookie auth is the only option. Recorded in the docs so it isn'tre-investigated.
Testing
swift test— 309 tests, all passing (Linux). 33 new cases covering the three payloadparsers, envelope/error classification at every level, cookie scoping, the
+encoding, regionwiring, and the platform gate.
API exactly, and both windows independently agree on absolute credits consumed
(
34.778% × 700 == 9.738% × 2500), which only holds if the tier ceilings are paired with theright percentages.
Not verified: macOS UI/menu rendering and browser cookie import (no macOS machine available), and
the team-edition live path (no team account). Both are untouched by this change beyond the shared
formEncodedBodyfix.