From 9aa0c0e6c0a56b0ab649dc563f7a31a62dc88de8 Mon Sep 17 00:00:00 2001 From: Raden Salman Alfaridzi Date: Wed, 22 Jul 2026 01:00:39 +0700 Subject: [PATCH] feat(v0.7.4): C1 auth bypass fix, Forge/TokenRouter/Qwen/Alibaba/hcnsec providers, GitHub Copilot /v1/messages, opencode effort tiers, xAI quota handler, ModelAccessModal crash fix Features: - New providers: Forge Workspace (33 models, 3 tiers), TokenRouter (with management key + Quota Tracker), Huancheng (hcnsec), Qwen Cloud + Qwen Cloud Token Plan, Alibaba + Alibaba CN - GitHub Copilot native /v1/messages routing for Claude models (targetFormat:claude, anthropic-version header) - GitHub Copilot model catalog synced to OmniRoute fea1d54 (20 models) - opencode-go effort-tier aliases (9 models) + EFFORT_TIERS table (port of OmniRoute 1843b34) - Qwen3.8 Max Preview on Qwen Web (Subscription) with REQUIRED_THINKING_MODELS Fixes: - C1 Critical: dashboardGuard method-based auth routing (mutations always require JWT/CLI token even when requireLogin=false) - Cline/GLM 500 stream_options (inject stream_options on streaming requests) - HuggingChat HTML 200 (DEFAULT_MODEL omni + preprompt + native fetch) - xAI Quota Tracker empty card (billing API removed; show informative message) - ModelAccessModal crash (Cannot read properties of null (reading 'length')) - TokenRouter quota null plan crash - Playground value/key/object Object crashes (3 separate fixes) Improvements: - SanitizeHtml utility + unit tests - Playground MessageContent markdown renderer - AddApiKeyModal TokenRouter management key field - 8 new provider SVG icons Bumps package.json + cli/package.json to 0.7.4 --- CHANGELOG.md | 30 ++++ cli/package.json | 2 +- open-sse/executors/base.js | 2 +- open-sse/executors/github.js | 73 +++++++-- open-sse/executors/huggingchat.js | 35 ++++- open-sse/executors/opencode-go.js | 71 ++++++++- open-sse/executors/qwen-web.js | 73 ++++++++- open-sse/providers/capabilities.js | 2 + open-sse/providers/pricing.js | 36 +++++ open-sse/providers/registry/alibaba-cn.js | 50 +++++++ open-sse/providers/registry/alibaba.js | 52 +++++++ open-sse/providers/registry/forge.js | 97 ++++++++++++ open-sse/providers/registry/github.js | 55 ++++--- open-sse/providers/registry/hcnsec.js | 47 ++++++ open-sse/providers/registry/huggingchat.js | 5 + open-sse/providers/registry/index.js | 16 +- open-sse/providers/registry/opencode-go.js | 15 ++ .../registry/qwen-cloud-token-plan.js | 76 ++++++++++ open-sse/providers/registry/qwen-cloud.js | 55 +++++++ open-sse/providers/registry/qwen-web.js | 30 +++- open-sse/providers/registry/tokenrouter.js | 55 +++++++ open-sse/providers/registry/xai.js | 6 +- open-sse/services/usage.js | 2 + open-sse/services/usage/tokenrouter.js | 116 +++++++++++++++ open-sse/services/usage/xai.js | 140 +++++++----------- package.json | 4 +- public/providers/alibaba-cn.svg | 11 ++ public/providers/alibaba.svg | 11 ++ public/providers/forge.svg | 9 ++ public/providers/hcnsec.svg | 10 ++ public/providers/qwen-cloud-token-plan.svg | 8 + public/providers/qwen-cloud.svg | 8 + public/providers/tokenrouter.svg | 15 ++ .../dashboard/endpoint/EndpointPageClient.js | 12 +- .../providers/[id]/AddApiKeyModal.js | 23 +++ .../quota/components/ProviderLimits/index.js | 11 +- .../quota/components/ProviderLimits/utils.js | 18 +++ src/dashboardGuard.js | 21 +++ src/shared/utils/providerIcon.js | 3 +- src/shared/utils/sanitizeHtml.js | 77 ++++++---- tests/unit/sanitize-html.test.js | 90 +++++++++++ 41 files changed, 1289 insertions(+), 183 deletions(-) create mode 100644 open-sse/providers/registry/alibaba-cn.js create mode 100644 open-sse/providers/registry/alibaba.js create mode 100644 open-sse/providers/registry/forge.js create mode 100644 open-sse/providers/registry/hcnsec.js create mode 100644 open-sse/providers/registry/qwen-cloud-token-plan.js create mode 100644 open-sse/providers/registry/qwen-cloud.js create mode 100644 open-sse/providers/registry/tokenrouter.js create mode 100644 open-sse/services/usage/tokenrouter.js create mode 100644 public/providers/alibaba-cn.svg create mode 100644 public/providers/alibaba.svg create mode 100644 public/providers/forge.svg create mode 100644 public/providers/hcnsec.svg create mode 100644 public/providers/qwen-cloud-token-plan.svg create mode 100644 public/providers/qwen-cloud.svg create mode 100644 public/providers/tokenrouter.svg create mode 100644 tests/unit/sanitize-html.test.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 69124a9..2853a66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,33 @@ +# v0.7.4 (2026-07-19) + +## Features +- **Forge Workspace provider**: new API-key provider (forge) with 33 models across 3 pricing tiers (free/pro/enterprise), live model discovery via modelsFetcher, dedicated pricing block, and SVG brand icon. +- **TokenRouter provider + Quota Tracker**: new API-key provider (tokenrouter) with a separate Management API key (mirrors TokenRouter's two-credential design). Quota card surfaces Wallet / Top-up / Voucher balances from the management endpoint. Handler returns a graceful `message` when no management key is configured (no more UI crash). +- **Huancheng Public API (hcnsec) provider**: new OpenAI-compatible regional API-key provider. +- **Qwen Cloud + Qwen Cloud Token Plan providers**: two new dedicated API-key providers for Alibaba Cloud's Bailian Qwen endpoints (pay-as-you-go + token-plan variants). +- **Alibaba + Alibaba CN providers**: regional Alibaba DashScope API-key providers (international + China mainland base URLs). +- **GitHub Copilot native /v1/messages routing**: Claude models routed directly to GitHub's `/messages` endpoint (targetFormat:"claude") with `anthropic-version:2023-06-01` header, bypassing Chat Completions quirks and `sanitizeMessagesForChatCompletions`. Result: native Anthropic-format responses for Claude Code, Cline, etc. +- **GitHub Copilot model catalog sync**: synced to OmniRoute fea1d54 (20 models, including the latest Claude 4.5/4.10 family). +- **opencode-go effort-tier aliases**: 9 new alias models (`glm-5.2-high/max`, `mimo-v2.5-high/max`, `deepseek-v4-pro-low/medium/high/max`) auto-rewriting model id + injecting `reasoning_effort` via a new EFFORT_TIERS table + `parseEffortLevel()` suffix parser (port of OmniRoute commit 1843b34). +- **Qwen3.8 Max Preview model**: added to Qwen Web (Subscription) catalog. Auto-enables thinking mode via `REQUIRED_THINKING_MODELS` set; SSE parser handles `thinking_summary` via `delta.extra.summary_thought.content[]`. + +## Fixes +- **C1 Critical — Dashboard auth bypass**: `dashboardGuard.js` now uses method-based routing. Mutation routes (POST/PUT/PATCH/DELETE) **always** require a real JWT/CLI token even when `requireLogin=false`. Previously anyone with network access to the dashboard port could mutate state (create/delete providers, keys, settings) without authentication. +- **Cline/GLM 500 `stream_options` error**: `DefaultExecutor.transformRequest` now injects `stream_options: { include_usage: true }` on streaming requests so providers that require usage-on-stream don't 500. Signature expanded to `(model, body, stream, credentials)`. +- **HuggingChat provider dead (HTML 200 response)**: `zai-org/GLM-5.2` was retired by HF. Switched `DEFAULT_MODEL` to `omni` (HF's auto-router), always send `preprompt: ""`, switched `tlsFetch` → native `proxyAwareFetch` (no longer needs TLS impersonation), and added `isEncryptedCredentialBlob` guard. +- **xAI Quota Tracker empty card**: xAI removed both `/v1/billing?format=credits` and `/v1/user?include=subscription` (now 404) and migrated billing to a separate Management API on `management-api.x.ai` (requires a different key). Handler rewritten to return a clear `message` explaining where to find usage (`console.x.ai → Billing`) instead of leaving the card blank. No network calls — no more 404 spam. +- **ModelAccessModal crash (`Cannot read properties of null (reading 'length')`)**: `allowedModels` was `useState(null)` and only synced to an array inside `useEffect` (post-render), so the first render hit `.length` on null. Now uses lazy initializer `useState(() => [...])` so the first render already has a stable array. +- **TokenRouter quota `Cannot read properties of null (reading 'plan')`**: handler previously returned `null` when no management key was present; UI didn't guard. Fixed on both sides — handler returns an object with a `message` field (never null), and `ProviderLimits/index.js` uses `data ?? {}` for null-safe access. +- **Playground value/key TypeErrors (3 separate crashes)**: added `valueStr` coercion in ModelPicker, defensive coercion in `useModelCaps.getCaps`, and `model.value || model.name || model.id` extraction in the modal `onSelect` handler (modal passes the whole object, not a string). +- **Playground `[object Object]` model name after model swap**: extraction fix above also resolved the rendering bug. + +## Improvements +- **SanitizeHtml utility** (`src/shared/utils/sanitizeHtml.js`): regex-based HTML sanitizer for markdown model output. Strips `', (o) => !o.includes("ipt>", "ipt>alert(1)ipt>", (o) => !/