Files
OmniRoute/docs/reference
Diego Rodrigues de Sa e Souza abd4df63dc fix(sse): surface Qwen/Alibaba personal Token Plan quota in dashboard and preflight (#10290)
* fix(sse): surface Qwen/Alibaba personal Token Plan quota in dashboard and preflight

The personal Token Plan (5-hour / 7-day sliding windows) has no official
OpenAPI and the inference API key cannot read it. Add a cookie-authenticated
fetcher for the console gateway shared by home.qwencloud.com and the Model
Studio console (contract captured live from a logged-in session):

- open-sse/services/qwenTokenPlanQuotaFetcher.ts: POST /data/api.json
  (IntlBroadScopeAspnGateway / sfm_bailian) for usage + quota-config +
  subscription; sec_token resolved best-effort from the dashboard HTML;
  per-window parse (fields are omitted while a window is Temporarily
  Removed); 60s usage cache, 1h tier cache.
- usage/qwen-token-plan.ts leaf + registration in the usage dispatcher,
  USAGE_FETCHER_PROVIDERS, USAGE_SUPPORTED_PROVIDERS,
  PROVIDER_LIMITS_APIKEY_PROVIDERS and bespoke preflight/monitor windows.
- Also adds bailian-coding-plan to USAGE_SUPPORTED_PROVIDERS /
  PROVIDER_LIMITS_APIKEY_PROVIDERS: the coding-plan fetcher existed but the
  dashboard filtered those connections out (UI gap).

Refs #9603 (Problema 1 — quota missing; the 429 recovery half is a
follow-up).

* docs(env): document Qwen Token Plan quota env vars + regen omni-settings skill

QWEN_CLOUD_COOKIE, QWEN_CLOUD_SEC_TOKEN, QWEN_TOKEN_PLAN_HOST and
QWEN_TOKEN_PLAN_DASHBOARD_URL added to .env.example and
docs/reference/ENVIRONMENT.md (check:env-doc-sync), with the generated
omni-settings skill refreshed (check:agent-skills-sync).

Refs #9603

* revert: keep hand-tuned omni-settings thinking-budget section

The agent-skills-sync drift predates this PR (hand improvement from #10169
not yet synced into the generator source) — it fails on every open PR and
belongs to a base-reds fix, not this branch. Regenerating here would erase
the intentional content.

* feat(dashboard): add the Qwen/Model Studio console cookie field to the connection modal

The Token Plan quota fetcher is cookie-authenticated (the inference API key
cannot read the console gateway), but no modal field existed to paste that
cookie — so the quota was unconfigurable from the dashboard and the fetcher
could only ever return its 'needs a cookie' message.

Adds the field for qwen-cloud-token-plan and bailian-coding-plan alongside the
existing ollama-cloud / alibaba console-cookie inputs (same password-input,
blank-keeps-stored semantics), pre-fills it when editing a connection, and
extends the providerSpecificData string/length validation to the two new keys.

Tests: tests/unit/qwen-token-plan-cookie-field.test.ts (RED before, GREEN
after) covers persistence + trimming, the blank-input no-overwrite rule and
schema acceptance/rejection.

Refs #9603

* docs(dashboard): correct the Qwen console cookie instructions

The placeholder claimed the cookie looks like 'token=...'; the qwencloud
portal actually issues 'login_qwencloud_ticket=...' alongside cna/cnaui/aui
(mirroring login_aliyunid_ticket on the Alibaba console), so the hint pointed
at the wrong value.

Replaces the guesswork with the verified retrieval steps in all three places
an operator can hit — the modal field hint, the fetcher's 'needs a cookie'
message and .env.example/ENVIRONMENT.md: log in to home.qwencloud.com >
Billing > Subscription, F12 > Network, reload, filter by api.json, click a
request to cs-data.qwencloud.com and copy the WHOLE Cookie request header.
Also documents that the value must go on one line (it contains '=' and ';')
and that it dies with the browser session.

Refs #9603

* fix(dashboard): tolerate partial form objects in the qwen cookie branch

Adding bailian-coding-plan to QWEN_TOKEN_PLAN_PROVIDERS routed callers that
previously matched NO branch in assignQuotaScrapingProviderData into the new
one, which assumed the two new fields are always present. Older callers build
a partial form object, so buildAddProviderSpecificData threw:

  TypeError: Cannot read properties of undefined (reading 'trim')
  (tests/unit/dashboard/agentrouter-connection-modal-fields.test.ts)

Reads the new fields with optional chaining and adds a regression test that
calls the helper with those keys deleted for both providers.

Refs #9603

* refactor(dashboard): move quota-scraping form logic into a UI-free module

tests/unit/qwen-token-plan-cookie-field.test.ts imported QuotaScrapingFields
directly, which pulls `@/shared/components` and, through that barrel,
untranspiled ESM (@lobehub/icons). The node:test runner cannot parse it and
the whole test file died in CI with:

  SyntaxError: Unexpected token 'export'
    at @lobehub/icons/es/Ai21/components/Mono.js

(It passed locally, so only the CI shard surfaced it.)

Extracts the pure pieces — QWEN_TOKEN_PLAN_PROVIDERS, QuotaScrapingFieldValues,
EMPTY_QUOTA_SCRAPING_FIELDS and assignQuotaScrapingProviderData — into
quotaScrapingFieldValues.ts. The component imports them and re-exports the
public names, so every existing importer keeps its current path. The unit test
now targets the UI-free module.

Refs #9603

* fix(providers): point bailian-coding-plan at the Token Plan endpoint and its console

Two independent defects kept this provider unusable with a valid Alibaba
Token Plan key (verified live 2026-08-14 with the owner's key and cookie):

1. Wrong inference host. The catalog entry is named "Alibaba Token Plan",
   links to token-plan-overview and its hint asks for a Token Plan key, but
   the registry pointed at coding-intl.dashscope.aliyuncs.com — the Coding
   Plan host, which rejects Token Plan keys with 401 invalid_api_key. The
   documented Anthropic base URL for Token Plan is
   token-plan.ap-southeast-1.maas.aliyuncs.com/apps/anthropic
   (https://www.alibabacloud.com/help/en/model-studio/more-tools). Against
   the new host the same key returns 200 for all six registry models and a
   real completion; auth stays on x-api-key.

2. Wrong console identity for quota. The personal Token Plan is sold through
   two consoles sharing one backend, and the gateway validates the session
   against the console declared in the request: an Alibaba console cookie
   (login_aliyunid_ticket) sent with the QwenCloud identity is refused with
   BailianGateway.Login.NotLogined. resolveConsoleSite() now picks host,
   cornerstoneParam.consoleSite/domain and Origin/Referer from the cookie's
   login ticket, falling back to the provider. With that switch the same
   cookie returns usage/subscription/quota-config.

Also routes bailian-coding-plan quota through the Token Plan fetcher (the
Coding Plan call returns "Bad Request" for these accounts), keeping the old
fetcher as the fallback for real Coding Plan keys, and labels the plan by
console ("Alibaba Token Plan (Pro)" vs "Qwen …").

Live validation: inference 200 (qwen3.7-plus answered "FUNCIONA"); quota
12,934/40,000 credits, 67.7% remaining, resets 2026-08-20.

Refs #9603

---------

Co-authored-by: Xiangzhe <bakryun0718@proton.me>
2026-08-14 15:40:33 -03:00
..
2026-07-29 15:18:55 -03:00
2026-07-13 09:12:40 -03:00