feat: Remove OpenRouter OAuth flow, keep API key authentication
What would you like to be added?
Remove the OpenRouter OAuth authentication flow (browser-based PKCE authorization + local callback server) from Qwen Code. Keep OpenRouter as a provider, but switch its authentication method to standard API key input — the same approach used by DeepSeek, MiniMax, Z.ai, and other third-party providers.
The following should be preserved:
- OpenRouter as a provider (base URL, env key, model catalog)
- Automatic model fetching from
https://openrouter.ai/api/v1/models
- Recommended model selection logic
- The
OpenRouter · model name prefix
The following should be removed:
openrouterOAuth.ts — the entire OAuth implementation (~700 lines: PKCE, callback HTTP server, port retry, browser open, signal handling, timeout, code exchange)
openrouterOAuth.test.ts — its test suite
- OAuth-specific branching in
useAuth.ts (the only provider with a genuinely different auth flow)
- OAuth-specific branching in
useAuth.test.ts and manageModels.test.ts
- The
oauth uiGroup category (OpenRouter is the only provider in it)
- Change
openRouterProvider.authMethod from 'oauth' to 'api-key'
- Update
openRouterProvider.description to reflect API key auth
Why is this needed?
The OAuth flow is incompatible with web terminal / remote development environments
The OpenRouter OAuth flow relies on three assumptions that don't hold outside a local desktop:
- A browser can be opened —
open(authUrl) has no effect in SSH sessions, Codespaces, Web Terminals, or CI environments
localhost:3000 is reachable — the callback server binds to localhost on the machine running Qwen Code; when that machine is remote, the browser redirect (on the user's local machine) never reaches it
- The terminal and browser are on the same machine — the entire PKCE round-trip assumes co-located browser and callback server
Remote development is a real and growing use case for Qwen Code. The OAuth flow silently fails in these environments — users see the auth URL printed but have no way to complete the round-trip.
OpenRouter is the only OAuth provider — the complexity is not amortized
Every other provider (Coding Plan, Token Plan, DeepSeek, MiniMax, Z.ai, iDealAB, Custom) uses API key authentication. OpenRouter is the sole occupant of the oauth uiGroup. The OAuth infrastructure (PKCE generation, HTTP callback server with port retry, browser launch, signal handling, abort coordination, code exchange) exists entirely to serve this one provider.
API key auth is a trivially equivalent alternative
OpenRouter users can obtain an API key from https://openrouter.ai/keys and paste it into the auth dialog — the same 10-second flow every other third-party provider uses. The automatic model catalog fetching (fetchOpenRouterModels) and recommended model selection can continue to work with an API key; they don't depend on OAuth.
Additional context
Files affected
| File |
Action |
packages/cli/src/auth/providers/oauth/openrouterOAuth.ts |
Delete |
packages/cli/src/auth/providers/oauth/openrouterOAuth.test.ts |
Delete |
packages/cli/src/auth/providers/oauth/openrouter.ts |
Update (switch to API key auth method, keep model catalog helpers) |
packages/cli/src/auth/providers/oauth/openrouter.test.ts |
Update |
packages/cli/src/ui/auth/useAuth.ts |
Update (remove OAuth branching) |
packages/cli/src/ui/auth/useAuth.test.ts |
Update (remove OAuth tests) |
packages/cli/src/ui/manageModels/manageModels.ts |
Update (remove OAuth imports, keep model fetch) |
packages/cli/src/ui/manageModels/manageModels.test.ts |
Update |
packages/cli/src/auth/allProviders.ts |
Update (remove OAUTH_PROVIDERS export if empty) |
Net LOC reduction
~700 lines of OAuth implementation + ~400 lines of OAuth tests removed. The remaining OpenRouter provider definition shrinks to ~50 lines (provider config + model fetch helpers).
中文
建议删除 OpenRouter OAuth 流程,保留 API Key 认证
要做什么
删除 OpenRouter 的 OAuth 认证流程(基于浏览器的 PKCE 授权 + 本地回调服务器)。保留 OpenRouter 作为 provider,但将认证方式改为标准 API Key 输入——与 DeepSeek、MiniMax、Z.ai 等第三方 provider 一致。
保留:
- OpenRouter provider 本身(base URL、env key、模型目录)
- 自动从
https://openrouter.ai/api/v1/models 拉取模型
- 推荐模型选择逻辑
OpenRouter · 模型名称前缀
删除:
openrouterOAuth.ts — 整个 OAuth 实现(约 700 行:PKCE、回调 HTTP 服务器、端口重试、浏览器打开、信号处理、超时、code 交换)
openrouterOAuth.test.ts — 对应测试
useAuth.ts 中 OAuth 特有的分支逻辑(唯一使用不同认证流程的 provider)
oauth uiGroup 分类(OpenRouter 是其中唯一的 provider)
- 将
openRouterProvider.authMethod 从 'oauth' 改为 'api-key'
为什么要做
OAuth 流程在 Web Terminal / 远程开发环境下完全不可用:
- SSH 会话、Codespaces、Web Terminal 中无法打开浏览器
- 回调服务器绑定在远程机器的
localhost:3000,用户本地浏览器的重定向永远到不了
- 整个 PKCE 流程假设终端和浏览器在同一台机器上
远程开发是 Qwen Code 的真实使用场景,OAuth 在这些环境下静默失败。
OpenRouter 是唯一的 OAuth provider,复杂度没有被分摊:
其他所有 provider 都用 API Key 认证。整套 OAuth 基础设施(PKCE、HTTP 回调服务器、端口重试、浏览器启动、信号处理、中止协调、code 交换)只为一个 provider 服务。
API Key 是 trivially equivalent 的替代方案:
用户去 openrouter.ai/keys 复制 API Key,粘贴到认证对话框——和其他第三方 provider 一样的 10 秒操作。自动模型拉取和推荐模型选择不依赖 OAuth,可以继续保留。
预计净减少代码量
约 700 行 OAuth 实现 + 400 行 OAuth 测试删除。剩余的 OpenRouter provider 定义缩减到约 50 行。
feat: Remove OpenRouter OAuth flow, keep API key authentication
What would you like to be added?
Remove the OpenRouter OAuth authentication flow (browser-based PKCE authorization + local callback server) from Qwen Code. Keep OpenRouter as a provider, but switch its authentication method to standard API key input — the same approach used by DeepSeek, MiniMax, Z.ai, and other third-party providers.
The following should be preserved:
https://openrouter.ai/api/v1/modelsOpenRouter ·model name prefixThe following should be removed:
openrouterOAuth.ts— the entire OAuth implementation (~700 lines: PKCE, callback HTTP server, port retry, browser open, signal handling, timeout, code exchange)openrouterOAuth.test.ts— its test suiteuseAuth.ts(the only provider with a genuinely different auth flow)useAuth.test.tsandmanageModels.test.tsoauthuiGroup category (OpenRouter is the only provider in it)openRouterProvider.authMethodfrom'oauth'to'api-key'openRouterProvider.descriptionto reflect API key authWhy is this needed?
The OAuth flow is incompatible with web terminal / remote development environments
The OpenRouter OAuth flow relies on three assumptions that don't hold outside a local desktop:
open(authUrl)has no effect in SSH sessions, Codespaces, Web Terminals, or CI environmentslocalhost:3000is reachable — the callback server binds to localhost on the machine running Qwen Code; when that machine is remote, the browser redirect (on the user's local machine) never reaches itRemote development is a real and growing use case for Qwen Code. The OAuth flow silently fails in these environments — users see the auth URL printed but have no way to complete the round-trip.
OpenRouter is the only OAuth provider — the complexity is not amortized
Every other provider (Coding Plan, Token Plan, DeepSeek, MiniMax, Z.ai, iDealAB, Custom) uses API key authentication. OpenRouter is the sole occupant of the
oauthuiGroup. The OAuth infrastructure (PKCE generation, HTTP callback server with port retry, browser launch, signal handling, abort coordination, code exchange) exists entirely to serve this one provider.API key auth is a trivially equivalent alternative
OpenRouter users can obtain an API key from https://openrouter.ai/keys and paste it into the auth dialog — the same 10-second flow every other third-party provider uses. The automatic model catalog fetching (
fetchOpenRouterModels) and recommended model selection can continue to work with an API key; they don't depend on OAuth.Additional context
Files affected
packages/cli/src/auth/providers/oauth/openrouterOAuth.tspackages/cli/src/auth/providers/oauth/openrouterOAuth.test.tspackages/cli/src/auth/providers/oauth/openrouter.tspackages/cli/src/auth/providers/oauth/openrouter.test.tspackages/cli/src/ui/auth/useAuth.tspackages/cli/src/ui/auth/useAuth.test.tspackages/cli/src/ui/manageModels/manageModels.tspackages/cli/src/ui/manageModels/manageModels.test.tspackages/cli/src/auth/allProviders.tsOAUTH_PROVIDERSexport if empty)Net LOC reduction
~700 lines of OAuth implementation + ~400 lines of OAuth tests removed. The remaining OpenRouter provider definition shrinks to ~50 lines (provider config + model fetch helpers).
中文
建议删除 OpenRouter OAuth 流程,保留 API Key 认证
要做什么
删除 OpenRouter 的 OAuth 认证流程(基于浏览器的 PKCE 授权 + 本地回调服务器)。保留 OpenRouter 作为 provider,但将认证方式改为标准 API Key 输入——与 DeepSeek、MiniMax、Z.ai 等第三方 provider 一致。
保留:
https://openrouter.ai/api/v1/models拉取模型OpenRouter ·模型名称前缀删除:
openrouterOAuth.ts— 整个 OAuth 实现(约 700 行:PKCE、回调 HTTP 服务器、端口重试、浏览器打开、信号处理、超时、code 交换)openrouterOAuth.test.ts— 对应测试useAuth.ts中 OAuth 特有的分支逻辑(唯一使用不同认证流程的 provider)oauthuiGroup 分类(OpenRouter 是其中唯一的 provider)openRouterProvider.authMethod从'oauth'改为'api-key'为什么要做
OAuth 流程在 Web Terminal / 远程开发环境下完全不可用:
localhost:3000,用户本地浏览器的重定向永远到不了远程开发是 Qwen Code 的真实使用场景,OAuth 在这些环境下静默失败。
OpenRouter 是唯一的 OAuth provider,复杂度没有被分摊:
其他所有 provider 都用 API Key 认证。整套 OAuth 基础设施(PKCE、HTTP 回调服务器、端口重试、浏览器启动、信号处理、中止协调、code 交换)只为一个 provider 服务。
API Key 是 trivially equivalent 的替代方案:
用户去 openrouter.ai/keys 复制 API Key,粘贴到认证对话框——和其他第三方 provider 一样的 10 秒操作。自动模型拉取和推荐模型选择不依赖 OAuth,可以继续保留。
预计净减少代码量
约 700 行 OAuth 实现 + 400 行 OAuth 测试删除。剩余的 OpenRouter provider 定义缩减到约 50 行。