refactor(cli): provider-first auth registry with unified install pipeline#3864
Conversation
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> Introduce ProviderConfig abstraction (providerConfig.ts) and a central provider registry (allProviders.ts), replacing the per-flow UI components (AlibabaModelStudioFlow, CustomProviderFlow, OAuthFlow, ThirdPartyProvidersFlow, etc.) with unified ProviderSetupSteps and useProviderSetupFlow. Key changes: - Remove setupMethods/apiKey/ directory entirely - Collapse flow-specific hooks/components into a single generic provider setup flow - Simplify each provider file to export only a ProviderConfig descriptor - Add alibabaStandard provider alongside codingPlan/tokenPlan - Move all baseUrl resolution, install plan building, and settings writing into providerConfig - Update useAuth, AuthDialog, command handler, and upstream consumers to use the new registry
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
…s props Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
…up flow Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Move metadataKey and getProviderState from per-provider config to auto-derived helpers (resolveMetadataKey, resolveProviderState) in providerConfig.ts. This centralizes version tracking logic and reduces boilerplate in individual provider definitions. Add useProviderUpdates hook that detects model template changes across all version-tracked providers and surfaces update/ignore choices. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> Closes: OSS-1730, OSS-1729
Introduce PROVIDER_METADATA_NS ('providerMetadata') to avoid top-level
settings key collisions. Provider metadata now lives under
e.g. providerMetadata.coding-plan.version instead of codingPlan.version.
Add migration logic (migrateProviderMetadata) to automatically move
legacy top-level keys (codingPlan, tokenPlan) into the new namespace
on first run.
Update auth handler, useProviderUpdates hook, and all related tests
to use the new namespace structure.
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
[skip ci]
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
… ci] Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
… ci] - Rewrite motivation.md to document provider-centric architecture - Remove Alibaba Standard API Key and Coding Plan UI flows from handler - Update status tests to use providerMetadata instead of codingPlan settings - Streamline API key auth to show docs link only Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Multi-step TUI navigation tests exceed 5s timeout on CI runners regardless of Node version. Extend skip condition from only Node 20 to all CI environments where input simulation is unreliable.
f530aab to
8558c49
Compare
yiliang114
left a comment
There was a problem hiding this comment.
LGTM. follow-up PRs planned.
wenshao
left a comment
There was a problem hiding this comment.
Additional findings that could not be anchored to changed lines:
[Critical] ModelsConfig.getResolvedModel() still resolves registry models by authType + modelId only. Per-agent content-generator paths that need a specific duplicate-id provider can inherit the first matching provider's envKey and generation settings instead of the intended endpoint. Please extend getResolvedModel(authType, modelId, baseUrl?) and thread the selected base URL through call sites that know it.
[Critical] ACP model options are still serialized by model.id and authType only, so same-id/same-authType providers with different base URLs collide and Session.setModel() cannot pass the selected base URL into switchModel(). Please include a baseUrl-aware stable identity in ACP option values and pass the parsed base URL through the switch path.
— gpt-5.5 via Qwen Code /review
wenshao
left a comment
There was a problem hiding this comment.
31x TS4111 type errors in packages/vscode-ide-companion/src/services/settingsWriter.ts (25 errors) and settingsWriter.test.ts (6 errors) — index-signature properties need bracket notation (e.g., patch.settings['env'] instead of patch.settings.env). npm run typecheck produces exit code 2.
Missing test coverage:
packages/cli/src/ui/auth/useProviderSetupFlow.ts(500-line core wizard state machine — zero tests)packages/cli/src/auth/allProviders.ts(3 exported lookup functions — zero tests)packages/vscode-ide-companion/src/services/subscriptionPlanDefinitions.ts(294 lines, 13 exports — zero tests)
Additional findings (no inline comment — not in diff hunks):
openrouterOAuth.ts:544—exchangeAuthCodeForApiKeyerror messages include untruncated server response body, which may leak secrets in TUI/logs.AuthDialog.test.tsx:245—isUnreliableTuiInputEnvironmentskips TUI tests in all CI environments (not just Node v20), removing auth dialog regression protection.
Substantive inline findings below.
wenshao
left a comment
There was a problem hiding this comment.
[Suggestion] Startup auth validation (validateAuthMethod) was removed from AppContainer.tsx mount effect. If a user's API key is revoked or env var is unset between sessions, they no longer see a specific auth error at startup — the error surfaces later as a generic HTTP failure at tool-execution time. Consider restoring credential validation on mount or adding an equivalent check in useAuthCommand's initialization.
[Suggestion] useProviderSetupFlow.ts (~500 lines, 22 useCallback handlers) has no test file. This is the core state machine for the new provider setup wizard with validation logic for baseUrl, apiKey, and modelIds. Adding tests via renderHook would provide a safety net for all provider setup flows.
- Add fallback to non-free models in OpenRouter OAuth when no free models available - Validate non-empty models list when building install plan - Fix auth status to use activeConfig instead of iterating all providers - Clear API key input when switching auth protocol - Skip unnecessary auth refresh when applying provider updates Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
wenshao
left a comment
There was a problem hiding this comment.
审查报告 — deepseek-v4-pro via Qwen Code /review
Test (windows-latest, 20.x), Test (ubuntu-latest, 20.x)
Critical
(1) CLI 与 VSCode companion 模型列表漂移 — packages/cli/src/auth/providers/alibaba/codingPlan.ts 和 packages/vscode-ide-companion/src/services/subscriptionPlanDefinitions.ts 中的模型列表已出现差异:codingPlan.ts 为 qwen3.5-plus、qwen3.6-plus、kimi-k2.5 包含了 modalities: { image: true, video: true },而 subscriptionPlanDefinitions.ts 中同样的模型缺少此字段。两个文件都有「keep in sync」注释但事实上已不同步。CLI 和 VSCode companion 将对同一订阅计划产生不同的模型配置。建议对齐 modalities 字段,或提取共享常量到 @qwen-code/qwen-code-core。
(2) migrateProviderMetadata() 迁移完全没有测试 — packages/cli/src/ui/hooks/useProviderUpdates.ts 第 91-121 行的迁移逻辑(codingPlan.*/tokenPlan.* → providerMetadata.*)在 useProviderUpdates.test.ts 的 14 个测试中完全没有覆盖。这是一次性代码路径,如果存在 bug 会在生产环境静默导致用户数据丢失且无法复现。需要添加测试验证旧 key 迁移到新命名空间且旧 key 被删除。
(3) subscriptionPlanDefinitions.ts 完全没有测试 — findSubscriptionPlanByConfig 有 6 个分支(两个参数均为 undefined、envKey 不匹配、区域匹配、区域不匹配、单端点匹配、无匹配),均无测试覆盖。此函数驱动 VSCode settings writer 的订阅计划检测逻辑,分类错误会导致用户被配置到错误的 provider。
Suggestion
(4) 回滚测试未覆盖完整恢复路径 — applyProviderInstallPlan.test.ts 的回滚测试仅验证了 process.env 的恢复(5 个恢复操作中的 2 个),未验证 restoreSettingsFromBackup()、settings.recomputeMerged()、config.reloadModelProvidersConfig() 是否正确调用。
| ); | ||
| const nonCodingPlan = existing.filter( | ||
| (e) => e.envKey !== CODING_PLAN_ENV_KEY, | ||
| (e) => !isSubscriptionPlanConfig(e.baseUrl as string, e.envKey as string), |
There was a problem hiding this comment.
[Critical] writeCodingPlanConfig 使用 isSubscriptionPlanConfig(同时匹配 Coding Plan 和 Token Plan)来过滤现有模型,但函数目的只是写入 Coding Plan 配置。如果用户同时有 Token Plan 和 Coding Plan 配置,此过滤器会静默移除 Token Plan 模型。
| (e) => !isSubscriptionPlanConfig(e.baseUrl as string, e.envKey as string), | |
| const nonCodingPlan = existing.filter( | |
| - (e) => !isSubscriptionPlanConfig(e.baseUrl as string, e.envKey as string), | |
| + (e) => e.envKey !== CODING_PLAN_ENV_KEY, | |
| ); |
— deepseek-v4-pro via Qwen Code /review
|
|
||
| // API Key | ||
| apiKey: string; | ||
| apiKeyError: string | null; |
There was a problem hiding this comment.
[Suggestion] getVisibleSteps 将 review 步骤绑定到 showAdvancedConfig === true。目前只有 customProvider 设置 showAdvancedConfig: true,意味着其他 7 个内置 provider 都没有 review/确认步骤。这个耦合让两个不相关的关注点(高级配置输入 + 确认屏幕)被同一个字段控制。建议将 review 步骤解耦为独立开关,或者重命名 showAdvancedConfig 为更准确反映其双重语义的名称。
— deepseek-v4-pro via Qwen Code /review
| } | ||
| if (spec.modalities && Object.values(spec.modalities).some(Boolean)) { | ||
| parts.modalities = spec.modalities; | ||
| hasAny = true; |
There was a problem hiding this comment.
[Suggestion] buildCustomGenConfig() 在 buildModelConfigs 的 .map() 回调内被调用,但每次返回相同结果且不依赖模型 ID。对 N 个模型会产生 N 次冗余的对象分配和属性检查。建议将调用提升到 .map() 之外复用结果。
— deepseek-v4-pro via Qwen Code /review
8558c49 only converted part of the tests to itWhenTuiInputReliable, leaving 9 multi-step keyboard-navigation tests still using bare it(). These tests reliably time out on Linux/Windows CI runners where stdin simulation timing is unpredictable. Convert all remaining it() → itWhenTuiInputReliable() so CI skips them, and add a comment block to clearly demarcate the TUI input section. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
| }: ApplyProviderInstallPlanOptions, | ||
| ): Promise<ApplyProviderInstallPlanResult> { | ||
| const persistScope = scope ?? getPersistScopeForModelSelection(settings); | ||
| const settingsFile = settings.forScope(persistScope); |
There was a problem hiding this comment.
[Critical] The rollback path does not clean up a settings file that this call creates from scratch. backupSettingsFile() only creates a backup when the file already exists; on a fresh profile the subsequent settings.setValue() calls can create settings.json, and if refreshAuth() later throws, restoreSettingsFromBackup() is a no-op. That leaves env keys, model providers, selected auth type, and possibly credentials persisted even though setup failed. Please track whether the file existed before writing and delete the newly-created file on rollback when no backup was made.
— gpt-5.5 via Qwen Code /review
| prebuiltModels: recommendedModels, | ||
| }); | ||
|
|
||
| await applyProviderInstallPlan(plan, { |
There was a problem hiding this comment.
[Critical] This OAuth path skips rebuilding/validating the active content generator but still marks authentication complete. Other provider installs call config.refreshAuth(...) through applyProviderInstallPlan; here refreshAuth: false means the settings/env are written but the current session can continue using the previous or unauthenticated generator. Please either let the install plan refresh auth here, or explicitly call await config.refreshAuth(plan.authType) before completeAuthentication().
— gpt-5.5 via Qwen Code /review
| .option('region', { | ||
| alias: 'r', | ||
| describe: t('Region for Coding Plan (china/global)'), | ||
| .option('base-url', { |
There was a problem hiding this comment.
[Critical] Replacing --region/-r with --base-url/-u breaks the documented non-interactive Coding Plan setup (qwen auth coding-plan --region china --key ...). Existing scripts will now miss baseUrl and fall into the interactive prompt, which can hang CI/provisioning environments. Please keep --region/-r as a deprecated alias and map china/global to the corresponding Coding Plan base URL.
— gpt-5.5 via Qwen Code /review
| ); | ||
| } | ||
|
|
||
| settings.setValue( |
There was a problem hiding this comment.
[Critical] applyProviderInstallPlan always writes security.auth.selectedType, but useProviderUpdates also reuses this helper for background model-list updates. Accepting a provider catalog update should not silently switch the user's active auth method/provider. Please add an option to skip auth-selection writes for update-only flows, or preserve and restore the previous selected auth type from useProviderUpdates.
— gpt-5.5 via Qwen Code /review
| } | ||
|
|
||
| config.reloadModelProvidersConfig(updatedModelProviders); | ||
| if (plan.modelSelection?.modelId) { |
There was a problem hiding this comment.
[Critical] The selected model can be overwritten by the subsequent refresh. This helper first syncs modelsConfig with plan.modelSelection.modelId, then calls config.refreshAuth(plan.authType), and refreshAuth reads modelsConfig.getModel() and calls syncAfterAuthRefresh again. If getModel() still reflects the previous model, the content generator can be rebuilt for the old provider/model even though settings now contain the new model. Please make the refresh path use the intended model id (for example by passing it into refreshAuth or updating the current model before refresh).
— gpt-5.5 via Qwen Code /review
|
|
||
| // Trigger UI refresh to update header information | ||
| onAuthChange?.(); | ||
| const oauthSession = createOpenRouterOAuthSession( |
There was a problem hiding this comment.
[Suggestion] The fallback URL shown to the user is created before runOpenRouterOAuthLogin binds the callback listener. If the listener has to retry on another port, browser auto-open may use the final URL while the manually displayed URL still points at the original callback port. Users copying that fallback URL can complete OAuth against the wrong port and hang the login. Consider displaying the final authorization URL only after the listener is bound, or returning the final URL from runOpenRouterOAuthLogin.
— gpt-5.5 via Qwen Code /review
wenshao
left a comment
There was a problem hiding this comment.
[Critical] useProviderSetupFlow.ts(503 行多步向导状态机)在整个 PR 中风险最高,但零测试覆盖。步骤导航、验证、高级配置组装、提交输出形状均无 CI 保护。建议至少覆盖:start/reset 生命周期、各步验证、边界 goBack、最终 submit 输出形状、高级配置组装。
— glm-5.1 via Qwen Code /review
| const metadata = getProviderMetadata(settings, metadataKey); | ||
| if (!metadata.version) continue; | ||
|
|
||
| const baseUrl = metadata.baseUrl || resolveBaseUrl(provider); |
There was a problem hiding this comment.
[Critical] Migration 不转换 region → baseUrl,全球 Coding Plan 用户会被静默切换到中国端点。
migrateKey (line 88) 将旧 codingPlan.region = "global" 原样迁移为 providerMetadata.coding-plan.region,但不生成 baseUrl 字段(旧数据中从未存在)。此处 metadata.baseUrl 为 undefined,回退到 resolveBaseUrl(provider) → config.baseUrl[0](中国端点)。
全球用户接受模型更新后,API 请求会发往中国端点而非国际端点。
| const baseUrl = metadata.baseUrl || resolveBaseUrl(provider); | |
| // After migration, convert known region values to baseUrl | |
| if (!metadata.baseUrl && metadata.region) { | |
| const REGION_URLS: Record<string, Record<string, string>> = { | |
| 'coding-plan': { | |
| china: 'https://coding.dashscope.aliyuncs.com/v1', | |
| global: 'https://coding-intl.dashscope.aliyuncs.com/v1', | |
| }, | |
| }; | |
| const mapping = REGION_URLS[metadataKey]; | |
| if (mapping?.[metadata.region as string]) { | |
| metadata.baseUrl = mapping[metadata.region as string]; | |
| } | |
| } | |
| const baseUrl = metadata.baseUrl || resolveBaseUrl(provider); |
— glm-5.1 via Qwen Code /review
| !key.startsWith('sk-sp-') | ||
| ? 'Invalid API key. Coding Plan API keys start with "sk-sp-". Please check.' | ||
| : null, | ||
| ownsModel: (model) => |
There was a problem hiding this comment.
[Critical] ownsModel 硬编码两个 base URL,与 baseUrl 数组(lines 75-92)独立维护。新增区域时只需更新 baseUrl 数组但不会自动更新 ownsModel,导致新区域的模型在重装时不会被清理。
| ownsModel: (model) => | |
| ownsModel: (model) => { | |
| if (model.envKey !== CODING_PLAN_ENV_KEY) return false; | |
| if (typeof model.baseUrl !== 'string') return false; | |
| return (codingPlanProvider.baseUrl as BaseUrlOption[]).some( | |
| (opt) => opt.url === model.baseUrl, | |
| ); | |
| }, |
— glm-5.1 via Qwen Code /review
| ProviderModelProvidersPatch, | ||
| } from '../types.js'; | ||
|
|
||
| function isSameModelIdentity( |
There was a problem hiding this comment.
[Critical] 模型身份去重逻辑在两个包中独立实现。此处的 isSameModelIdentity 比较 a.id === b.id && (a.baseUrl ?? '') === (b.baseUrl ?? ''),而 packages/core/src/models/modelRegistry.ts 中的 modelRegistryKey 生成 id\0baseUrl。语义相同但独立维护——一方改动另一方可能遗漏,导致 settings 写入与运行时模型查找不一致。
建议从 @qwen-code/qwen-code-core 导出共享的 modelRegistryKey 工具函数,两处统一使用。
— glm-5.1 via Qwen Code /review
| export const TOKEN_PLAN_BASE_URL = | ||
| 'https://token-plan.cn-beijing.maas.aliyuncs.com/compatible-mode/v1'; | ||
|
|
||
| const TOKEN_PLAN_MODELS: ModelSpec[] = [ |
There was a problem hiding this comment.
[Critical] CLI 的 TOKEN_PLAN_MODELS 只有 4 个模型,但 VSCode 伴侣的 subscriptionPlanDefinitions.ts 中 Token Plan 使用 ALIBABA_SUBSCRIPTION_MODELS(9 个模型)。当用户通过 VSCode 伴侣设置 Token Plan 后写入 9 个模型,CLI 的 useProviderUpdates 用 4 个模型列表计算版本哈希检测到不匹配,会提示"更新"并静默将 9 个模型替换为 4 个。
建议统一 Token Plan 模型列表定义,或提取到共享包(如 packages/core)。
— glm-5.1 via Qwen Code /review
|
|
||
| const OPENROUTER_MODEL_PRIORITY_PREFIXES = ['qwen/', 'glm/', 'minimax/']; | ||
| const OPENROUTER_RECOMMENDED_MODEL_LIMIT = 16; | ||
| const OPENROUTER_RECOMMENDED_FREE_MODEL_IDS = [ |
There was a problem hiding this comment.
[Suggestion] OpenRouter 自动配置模型从旧版的 ~6-16 个(含免费+付费+不同家族混合)缩减到仅 2 个免费模型。已有 OpenRouter 用户重新认证时,prepend-and-remove-owned 策略会删除所有之前配置的模型(Claude、GPT-5、Gemini 等),仅保留 2 个免费模型。这是一个显著的静默行为回归。
建议保留 3-5 个推荐模型(混合免费和付费旗舰),或提供迁移路径避免删除已有配置。
— glm-5.1 via Qwen Code /review
|
|
||
| // -- Preview JSON (for review step) --------------------------------------- | ||
|
|
||
| const getPreviewJson = useCallback((): string => { |
There was a problem hiding this comment.
[Suggestion] getPreviewJson 独立构建生成配置(仅含 extra_body、modalities、contextWindowSize),与 buildModelConfigs(实际保存逻辑,还含 maxTokens via samplingParams)各自维护。两者已经出现分歧:maxTokens 在 buildModelConfigs 中存在但 getPreviewJson 中缺失。
建议用 buildInstallPlan 生成预览 JSON,maskApiKey 后显示,避免展示内容与实际保存内容不一致。
— glm-5.1 via Qwen Code /review
| providerId: ProviderId; | ||
| authType: AuthType; | ||
| env?: Record<string, string>; | ||
| legacyCredentials?: { |
There was a problem hiding this comment.
[Suggestion] legacyCredentials 和 display 字段在 ProviderInstallPlan 上定义但从未被任何生产代码填充或消费(仅在单元测试中使用)。这会增加阅读者的认知负担。建议添加 // TODO 注释说明未来用途,或移除。
— glm-5.1 via Qwen Code /review
The remaining issues are all known problems. They will be addressed in follow-up PRs. Let's merge the current PR first.
…line - Resolve all cherry-pick conflicts from PR QwenLM#3864 - Fix branding: @qwen-code/qwen-code-core -> @hoptrendy/hopcode-core across 29 files - Fix AuthType.QWEN_OAUTH -> AuthType.HOPCODE_OAUTH references - Add constants/codingPlan.ts with isCodingPlanConfig helper - Fix duplicate import block in handler.ts - Fix stray closing brace in AuthDialog.tsx - Fix ModelDialog.tsx switchModel call to use 3-arg signature - Fix GeminiRespondingSpinner.test.tsx to use HopCodeSpinner - Add ProviderModelConfig type annotation to fix implicit any Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Three test assertions were left with upstream Qwen-Coder attribution strings after the QwenLM#3864 cherry-pick. Replace with HopCode branding (HopCode <hopcode@hoptrendy.com>) to match the runtime config. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…line (#3864) * fix(cli): refresh static header on model switch Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * feat(cli): simplify api key provider registry Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * refactor(cli): split Alibaba auth providers Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * polish(cli): refine auth provider onboarding Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): update OpenRouter free defaults Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): restrict token plan models Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * chore(cli): remove unused third-party providers Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * feat(cli): add regional third-party providers Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * refactor(cli): simplify api key provider endpoints Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * refactor(cli): split auth dialog flows Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * refactor(cli): unify auth around declarative provider config Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> Introduce ProviderConfig abstraction (providerConfig.ts) and a central provider registry (allProviders.ts), replacing the per-flow UI components (AlibabaModelStudioFlow, CustomProviderFlow, OAuthFlow, ThirdPartyProvidersFlow, etc.) with unified ProviderSetupSteps and useProviderSetupFlow. Key changes: - Remove setupMethods/apiKey/ directory entirely - Collapse flow-specific hooks/components into a single generic provider setup flow - Simplify each provider file to export only a ProviderConfig descriptor - Add alibabaStandard provider alongside codingPlan/tokenPlan - Move all baseUrl resolution, install plan building, and settings writing into providerConfig - Update useAuth, AuthDialog, command handler, and upstream consumers to use the new registry * refactor(cli): simplify provider setup input flow Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * refactor(cli): remove toLlmProvider and legacy auth wrappers Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * refactor(cli): flatten auth flow files and simplify ProviderSetupSteps props Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * feat(cli): prefill API key from existing env settings in provider setup flow Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): correct third-party provider context windows Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): harden provider auth setup * feat(cli): support provider modality and context settings * feat: eable modelsEditable for coding plan * refactor(cli): auto-derive provider metadata key and state Move metadataKey and getProviderState from per-provider config to auto-derived helpers (resolveMetadataKey, resolveProviderState) in providerConfig.ts. This centralizes version tracking logic and reduces boilerplate in individual provider definitions. Add useProviderUpdates hook that detects model template changes across all version-tracked providers and surfaces update/ignore choices. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> Closes: OSS-1730, OSS-1729 * refactor(cli): namespace provider metadata under providerMetadata key Introduce PROVIDER_METADATA_NS ('providerMetadata') to avoid top-level settings key collisions. Provider metadata now lives under e.g. providerMetadata.coding-plan.version instead of codingPlan.version. Add migration logic (migrateProviderMetadata) to automatically move legacy top-level keys (codingPlan, tokenPlan) into the new namespace on first run. Update auth handler, useProviderUpdates hook, and all related tests to use the new namespace structure. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> [skip ci] Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): polish ProviderUpdatePrompt styling and test coverage [skip ci] Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * refactor(auth): simplify auth flows around provider abstraction [skip ci] - Rewrite motivation.md to document provider-centric architecture - Remove Alibaba Standard API Key and Coding Plan UI flows from handler - Update status tests to use providerMetadata instead of codingPlan settings - Streamline API key auth to show docs link only Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * refactor(auth): update provider models and refine auth infrastructure - Bump model versions (qwen3.6-plus, glm-5.1) and add deepseek-v4-pro/flash with modalities to Alibaba Standard provider - Reorder DeepSeek models, add thinking+image/video modalities to v4-pro, fix v4-flash context window - Enhance auth tests with provider metadata setValue assertions - Switch env key generation from hash-based to URL-based with trailing-slash normalization - Remove deprecated codingPlan section from settings schema Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(i18n): add missing zh-TW translations for token plan and subscription providers Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * refactor(auth): improve provider install error recovery and AuthDialog state init - Restore settings from backup on provider install plan failure - Fix AuthDialog mainIndex state to null (was 0), preventing stale selection - Remove ownsModel from customProvider; fall back to id-based filtering - Change provider migration log from console.error to console.log - Add sync reminder comments between CLI and VSCode subscription models - Expand handleApiKeyAuth JSDoc explaining its role as lightweight fallback Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(auth): i18n for step labels, lazy preview JSON, and accurate header label - Wrap getStepLabel() strings and PROTOCOL_ITEMS in t() for i18n - Only compute previewJson when on the review step - Return matched provider's own label in getAuthDisplayType instead of hardcoding CODING_PLAN for all managed providers * fix(auth): address round-3 review blockers - Fix CI: add missing useProviderUpdates mock in AppContainer.test.tsx that caused TypeError breaking React effects (title/height tests) - Fix half-rollback: snapshot settings + modelProviders before install, restore in-memory state (not just disk) on refreshAuth failure - Fix .orig backup reuse: always create fresh backup (overwrite stale), cleanup on success, unlink after restore to prevent data loss - Fix cross-package key consistency: VS Code settingsWriter now writes to providerMetadata namespace matching CLI's new structure - Fix validateApiKey: remove baseUrl guard so sk-sp- prefix check applies to both China and Global Coding Plan endpoints * fix(cli): stabilize AuthDialog tests for slower CI environments Increase vi.waitFor timeouts from default 1000ms to 5000ms and replace unreliable fixed-delay waits with proper render-completion assertions, preventing flaky failures on Linux/Windows CI runners with Node 22/24. * fix(core): use id+baseUrl composite key for model identity Custom provider installs previously used model id alone to determine ownership, causing the second install to remove the first backend's model entry when both expose the same model id (e.g. gpt-4o) with different baseUrls. Use id+baseUrl as the composite identity key throughout the model registry, ModelDialog, and modelsConfig to prevent cross-provider model collisions. * fix(cli): update ModelDialog tests for composite-key model identity Add missing getModelsConfig and getActiveRuntimeModelSnapshot mocks, and update switchModel assertion to expect the new { baseUrl } options object introduced in 4c4ebb8. * fix(cli): skip flaky TUI input tests on all CI environments Multi-step TUI navigation tests exceed 5s timeout on CI runners regardless of Node version. Extend skip condition from only Node 20 to all CI environments where input simulation is unreliable. * fix(cli): improve auth/provider edge cases and UX - Add fallback to non-free models in OpenRouter OAuth when no free models available - Validate non-empty models list when building install plan - Fix auth status to use activeConfig instead of iterating all providers - Clear API key input when switching auth protocol - Skip unnecessary auth refresh when applying provider updates Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * test(cli): update tests for empty model validation and skip auth refresh Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): skip remaining flaky TUI input AuthDialog tests on CI 8558c49 only converted part of the tests to itWhenTuiInputReliable, leaving 9 multi-step keyboard-navigation tests still using bare it(). These tests reliably time out on Linux/Windows CI runners where stdin simulation timing is unpredictable. Convert all remaining it() → itWhenTuiInputReliable() so CI skips them, and add a comment block to clearly demarcate the TUI input section. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> --------- Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
…line (QwenLM#3864) * fix(cli): refresh static header on model switch Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * feat(cli): simplify api key provider registry Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * refactor(cli): split Alibaba auth providers Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * polish(cli): refine auth provider onboarding Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): update OpenRouter free defaults Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): restrict token plan models Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * chore(cli): remove unused third-party providers Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * feat(cli): add regional third-party providers Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * refactor(cli): simplify api key provider endpoints Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * refactor(cli): split auth dialog flows Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * refactor(cli): unify auth around declarative provider config Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> Introduce ProviderConfig abstraction (providerConfig.ts) and a central provider registry (allProviders.ts), replacing the per-flow UI components (AlibabaModelStudioFlow, CustomProviderFlow, OAuthFlow, ThirdPartyProvidersFlow, etc.) with unified ProviderSetupSteps and useProviderSetupFlow. Key changes: - Remove setupMethods/apiKey/ directory entirely - Collapse flow-specific hooks/components into a single generic provider setup flow - Simplify each provider file to export only a ProviderConfig descriptor - Add alibabaStandard provider alongside codingPlan/tokenPlan - Move all baseUrl resolution, install plan building, and settings writing into providerConfig - Update useAuth, AuthDialog, command handler, and upstream consumers to use the new registry * refactor(cli): simplify provider setup input flow Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * refactor(cli): remove toLlmProvider and legacy auth wrappers Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * refactor(cli): flatten auth flow files and simplify ProviderSetupSteps props Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * feat(cli): prefill API key from existing env settings in provider setup flow Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): correct third-party provider context windows Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): harden provider auth setup * feat(cli): support provider modality and context settings * feat: eable modelsEditable for coding plan * refactor(cli): auto-derive provider metadata key and state Move metadataKey and getProviderState from per-provider config to auto-derived helpers (resolveMetadataKey, resolveProviderState) in providerConfig.ts. This centralizes version tracking logic and reduces boilerplate in individual provider definitions. Add useProviderUpdates hook that detects model template changes across all version-tracked providers and surfaces update/ignore choices. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> Closes: OSS-1730, OSS-1729 * refactor(cli): namespace provider metadata under providerMetadata key Introduce PROVIDER_METADATA_NS ('providerMetadata') to avoid top-level settings key collisions. Provider metadata now lives under e.g. providerMetadata.coding-plan.version instead of codingPlan.version. Add migration logic (migrateProviderMetadata) to automatically move legacy top-level keys (codingPlan, tokenPlan) into the new namespace on first run. Update auth handler, useProviderUpdates hook, and all related tests to use the new namespace structure. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> [skip ci] Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): polish ProviderUpdatePrompt styling and test coverage [skip ci] Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * refactor(auth): simplify auth flows around provider abstraction [skip ci] - Rewrite motivation.md to document provider-centric architecture - Remove Alibaba Standard API Key and Coding Plan UI flows from handler - Update status tests to use providerMetadata instead of codingPlan settings - Streamline API key auth to show docs link only Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * refactor(auth): update provider models and refine auth infrastructure - Bump model versions (qwen3.6-plus, glm-5.1) and add deepseek-v4-pro/flash with modalities to Alibaba Standard provider - Reorder DeepSeek models, add thinking+image/video modalities to v4-pro, fix v4-flash context window - Enhance auth tests with provider metadata setValue assertions - Switch env key generation from hash-based to URL-based with trailing-slash normalization - Remove deprecated codingPlan section from settings schema Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(i18n): add missing zh-TW translations for token plan and subscription providers Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * refactor(auth): improve provider install error recovery and AuthDialog state init - Restore settings from backup on provider install plan failure - Fix AuthDialog mainIndex state to null (was 0), preventing stale selection - Remove ownsModel from customProvider; fall back to id-based filtering - Change provider migration log from console.error to console.log - Add sync reminder comments between CLI and VSCode subscription models - Expand handleApiKeyAuth JSDoc explaining its role as lightweight fallback Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(auth): i18n for step labels, lazy preview JSON, and accurate header label - Wrap getStepLabel() strings and PROTOCOL_ITEMS in t() for i18n - Only compute previewJson when on the review step - Return matched provider's own label in getAuthDisplayType instead of hardcoding CODING_PLAN for all managed providers * fix(auth): address round-3 review blockers - Fix CI: add missing useProviderUpdates mock in AppContainer.test.tsx that caused TypeError breaking React effects (title/height tests) - Fix half-rollback: snapshot settings + modelProviders before install, restore in-memory state (not just disk) on refreshAuth failure - Fix .orig backup reuse: always create fresh backup (overwrite stale), cleanup on success, unlink after restore to prevent data loss - Fix cross-package key consistency: VS Code settingsWriter now writes to providerMetadata namespace matching CLI's new structure - Fix validateApiKey: remove baseUrl guard so sk-sp- prefix check applies to both China and Global Coding Plan endpoints * fix(cli): stabilize AuthDialog tests for slower CI environments Increase vi.waitFor timeouts from default 1000ms to 5000ms and replace unreliable fixed-delay waits with proper render-completion assertions, preventing flaky failures on Linux/Windows CI runners with Node 22/24. * fix(core): use id+baseUrl composite key for model identity Custom provider installs previously used model id alone to determine ownership, causing the second install to remove the first backend's model entry when both expose the same model id (e.g. gpt-4o) with different baseUrls. Use id+baseUrl as the composite identity key throughout the model registry, ModelDialog, and modelsConfig to prevent cross-provider model collisions. * fix(cli): update ModelDialog tests for composite-key model identity Add missing getModelsConfig and getActiveRuntimeModelSnapshot mocks, and update switchModel assertion to expect the new { baseUrl } options object introduced in 4c4ebb8. * fix(cli): skip flaky TUI input tests on all CI environments Multi-step TUI navigation tests exceed 5s timeout on CI runners regardless of Node version. Extend skip condition from only Node 20 to all CI environments where input simulation is unreliable. * fix(cli): improve auth/provider edge cases and UX - Add fallback to non-free models in OpenRouter OAuth when no free models available - Validate non-empty models list when building install plan - Fix auth status to use activeConfig instead of iterating all providers - Clear API key input when switching auth protocol - Skip unnecessary auth refresh when applying provider updates Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * test(cli): update tests for empty model validation and skip auth refresh Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): skip remaining flaky TUI input AuthDialog tests on CI 8558c49 only converted part of the tests to itWhenTuiInputReliable, leaving 9 multi-step keyboard-navigation tests still using bare it(). These tests reliably time out on Linux/Windows CI runners where stdin simulation timing is unpredictable. Convert all remaining it() → itWhenTuiInputReliable() so CI skips them, and add a comment block to clearly demarcate the TUI input section. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> --------- Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
…/auth TUI dialog (#3959) The `qwen auth` CLI subcommand (with subcommands like qwen-oauth, coding-plan, api-key, openrouter, status) has been superseded by the richer /auth TUI dialog introduced in the provider-first auth registry (#3864). Running `qwen auth` now prints a deprecation notice pointing users to the /auth TUI dialog (interactive), env vars (CI/headless), or /doctor (status check). Changes: - Replace auth.ts with a stub that prints a removal notice and exits - Delete handler.ts (734 lines), interactiveSelector.ts, and their tests (interactiveSelector.test.ts, openrouter.test.ts, status.test.ts) - Update /auth slash command to handle non-interactive/ACP modes gracefully - Enrich /doctor auth check with provider-aware diagnostics using findProviderByCredentials - Mark `auth` as a subcommand that handles its own exit in config.ts Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
…/auth TUI dialog (#3959) The `qwen auth` CLI subcommand (with subcommands like qwen-oauth, coding-plan, api-key, openrouter, status) has been superseded by the richer /auth TUI dialog introduced in the provider-first auth registry (#3864). Running `qwen auth` now prints a deprecation notice pointing users to the /auth TUI dialog (interactive), env vars (CI/headless), or /doctor (status check). Changes: - Replace auth.ts with a stub that prints a removal notice and exits - Delete handler.ts (734 lines), interactiveSelector.ts, and their tests (interactiveSelector.test.ts, openrouter.test.ts, status.test.ts) - Update /auth slash command to handle non-interactive/ACP modes gracefully - Enrich /doctor auth check with provider-aware diagnostics using findProviderByCredentials - Mark `auth` as a subcommand that handles its own exit in config.ts Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
…line (QwenLM#3864) * fix(cli): refresh static header on model switch Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * feat(cli): simplify api key provider registry Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * refactor(cli): split Alibaba auth providers Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * polish(cli): refine auth provider onboarding Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): update OpenRouter free defaults Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): restrict token plan models Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * chore(cli): remove unused third-party providers Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * feat(cli): add regional third-party providers Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * refactor(cli): simplify api key provider endpoints Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * refactor(cli): split auth dialog flows Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * refactor(cli): unify auth around declarative provider config Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> Introduce ProviderConfig abstraction (providerConfig.ts) and a central provider registry (allProviders.ts), replacing the per-flow UI components (AlibabaModelStudioFlow, CustomProviderFlow, OAuthFlow, ThirdPartyProvidersFlow, etc.) with unified ProviderSetupSteps and useProviderSetupFlow. Key changes: - Remove setupMethods/apiKey/ directory entirely - Collapse flow-specific hooks/components into a single generic provider setup flow - Simplify each provider file to export only a ProviderConfig descriptor - Add alibabaStandard provider alongside codingPlan/tokenPlan - Move all baseUrl resolution, install plan building, and settings writing into providerConfig - Update useAuth, AuthDialog, command handler, and upstream consumers to use the new registry * refactor(cli): simplify provider setup input flow Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * refactor(cli): remove toLlmProvider and legacy auth wrappers Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * refactor(cli): flatten auth flow files and simplify ProviderSetupSteps props Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * feat(cli): prefill API key from existing env settings in provider setup flow Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): correct third-party provider context windows Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): harden provider auth setup * feat(cli): support provider modality and context settings * feat: eable modelsEditable for coding plan * refactor(cli): auto-derive provider metadata key and state Move metadataKey and getProviderState from per-provider config to auto-derived helpers (resolveMetadataKey, resolveProviderState) in providerConfig.ts. This centralizes version tracking logic and reduces boilerplate in individual provider definitions. Add useProviderUpdates hook that detects model template changes across all version-tracked providers and surfaces update/ignore choices. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> Closes: OSS-1730, OSS-1729 * refactor(cli): namespace provider metadata under providerMetadata key Introduce PROVIDER_METADATA_NS ('providerMetadata') to avoid top-level settings key collisions. Provider metadata now lives under e.g. providerMetadata.coding-plan.version instead of codingPlan.version. Add migration logic (migrateProviderMetadata) to automatically move legacy top-level keys (codingPlan, tokenPlan) into the new namespace on first run. Update auth handler, useProviderUpdates hook, and all related tests to use the new namespace structure. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> [skip ci] Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): polish ProviderUpdatePrompt styling and test coverage [skip ci] Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * refactor(auth): simplify auth flows around provider abstraction [skip ci] - Rewrite motivation.md to document provider-centric architecture - Remove Alibaba Standard API Key and Coding Plan UI flows from handler - Update status tests to use providerMetadata instead of codingPlan settings - Streamline API key auth to show docs link only Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * refactor(auth): update provider models and refine auth infrastructure - Bump model versions (qwen3.6-plus, glm-5.1) and add deepseek-v4-pro/flash with modalities to Alibaba Standard provider - Reorder DeepSeek models, add thinking+image/video modalities to v4-pro, fix v4-flash context window - Enhance auth tests with provider metadata setValue assertions - Switch env key generation from hash-based to URL-based with trailing-slash normalization - Remove deprecated codingPlan section from settings schema Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(i18n): add missing zh-TW translations for token plan and subscription providers Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * refactor(auth): improve provider install error recovery and AuthDialog state init - Restore settings from backup on provider install plan failure - Fix AuthDialog mainIndex state to null (was 0), preventing stale selection - Remove ownsModel from customProvider; fall back to id-based filtering - Change provider migration log from console.error to console.log - Add sync reminder comments between CLI and VSCode subscription models - Expand handleApiKeyAuth JSDoc explaining its role as lightweight fallback Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(auth): i18n for step labels, lazy preview JSON, and accurate header label - Wrap getStepLabel() strings and PROTOCOL_ITEMS in t() for i18n - Only compute previewJson when on the review step - Return matched provider's own label in getAuthDisplayType instead of hardcoding CODING_PLAN for all managed providers * fix(auth): address round-3 review blockers - Fix CI: add missing useProviderUpdates mock in AppContainer.test.tsx that caused TypeError breaking React effects (title/height tests) - Fix half-rollback: snapshot settings + modelProviders before install, restore in-memory state (not just disk) on refreshAuth failure - Fix .orig backup reuse: always create fresh backup (overwrite stale), cleanup on success, unlink after restore to prevent data loss - Fix cross-package key consistency: VS Code settingsWriter now writes to providerMetadata namespace matching CLI's new structure - Fix validateApiKey: remove baseUrl guard so sk-sp- prefix check applies to both China and Global Coding Plan endpoints * fix(cli): stabilize AuthDialog tests for slower CI environments Increase vi.waitFor timeouts from default 1000ms to 5000ms and replace unreliable fixed-delay waits with proper render-completion assertions, preventing flaky failures on Linux/Windows CI runners with Node 22/24. * fix(core): use id+baseUrl composite key for model identity Custom provider installs previously used model id alone to determine ownership, causing the second install to remove the first backend's model entry when both expose the same model id (e.g. gpt-4o) with different baseUrls. Use id+baseUrl as the composite identity key throughout the model registry, ModelDialog, and modelsConfig to prevent cross-provider model collisions. * fix(cli): update ModelDialog tests for composite-key model identity Add missing getModelsConfig and getActiveRuntimeModelSnapshot mocks, and update switchModel assertion to expect the new { baseUrl } options object introduced in 4a3eaa705. * fix(cli): skip flaky TUI input tests on all CI environments Multi-step TUI navigation tests exceed 5s timeout on CI runners regardless of Node version. Extend skip condition from only Node 20 to all CI environments where input simulation is unreliable. * fix(cli): improve auth/provider edge cases and UX - Add fallback to non-free models in OpenRouter OAuth when no free models available - Validate non-empty models list when building install plan - Fix auth status to use activeConfig instead of iterating all providers - Clear API key input when switching auth protocol - Skip unnecessary auth refresh when applying provider updates Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * test(cli): update tests for empty model validation and skip auth refresh Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(cli): skip remaining flaky TUI input AuthDialog tests on CI 8f4b82dbf only converted part of the tests to itWhenTuiInputReliable, leaving 9 multi-step keyboard-navigation tests still using bare it(). These tests reliably time out on Linux/Windows CI runners where stdin simulation timing is unpredictable. Convert all remaining it() → itWhenTuiInputReliable() so CI skips them, and add a comment block to clearly demarcate the TUI input section. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> --------- Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>









Summary
Auth setup used to treat each entry method — API key, OAuth, coding plan, token plan — as a separate architecture. In practice they all produce the same thing: a provider configuration in
settings.json. This PR makes provider the first principle and unifies all auth paths into one pipeline.Making qwen-code more open. The old auth scattered provider-specific logic across a 441-line handler, a 1,321-line dialog, and a pile of constants (347-line
codingPlan, 309-line corecodingPlan, 24-linealibabaStandardApiKey). A contributor who wanted to add a third-party provider had to understand the full auth UI. With this refactor, adding a new provider is a one-file operation: write aProviderConfigdescriptor that declares display info, required inputs, auth flow, settings patch, default models, and model ownership — and it slots into the registry automatically. No need to touch the handler, the dialog, or any constants.One unified pipeline. Every provider — whether it uses an API key, OAuth, a subscription plan, or a custom wizard — now follows the same path: collect inputs →
buildInstallPlan(config, inputs)→ProviderInstallPlandata →applyProviderInstallPlan(plan)→ settings write. Settings persistence is independent from the UI flow that collected the inputs. UI groups (alibaba,third-party,oauth,custom) help users navigate/auth; they do not drive settings logic.What changed concretely:
allProviders.ts) registers 8 providers.ProviderConfigis the declarative contract —baseUrlis three-state (fixed string skips the step,BaseUrlOption[]shows a selector,undefinedshows free input),shouldShowStep()uses TypeScript type information to drive UI behavior, andownsModelis a predicate function so complex providers like Coding Plan (two base URLs) can precisely declare model ownership.BaseUrlOption[]replaces per-providerregions— providers with multiple base URLs (Z.AI standard vs Coding Plan, MiniMax international vs China, Alibaba ModelStudio with 4 regions) useBaseUrlOption[]onProviderConfig.baseUrl. The naming shift fromregionsis intentional: Z.AI's choice is a setup variant, not a geographic region.useProviderSetupFlow(a declarative multi-step wizard state machine, 500 lines) +ProviderSetupSteps(render component, 476 lines). Back navigation uses a view stack instead of hard-coded branches.useAuthsimplified (958 → 574 lines, −40%) —handleProviderSubmitis the unified submit path. Three backward-compatible wrappers (handleSubscriptionPlanSubmit,handleApiKeyProviderSubmit,handleCustomApiKeySubmit) still exist but all converge onhandleProviderSubmit.codingPlanconstants (347 + 309 lines from CLI and core),alibabaStandardApiKey.ts(24 lines),useCodingPlanUpdates(230 lines, replaced by generaluseProviderUpdates, 344 lines). OpenAI & HuggingFace third-party provider files removed. Subscription plan definitions moved to VS Code companion boundary (294 lines,subscriptionPlanDefinitions.ts).applyProviderInstallPlanbacks up the settings file before writing and restores it on error, including rolling backprocess.envchanges and deleting newly-created env variables.useProviderUpdatesmigrates oldcodingPlan.*andtokenPlan.*top-level keys toproviderMetadata.coding-plan.*/providerMetadata.token-plan.*on first run.Reviewer focus:
ProviderConfigshape and thebaseUrlthree-state pattern, install-plan boundaries (buildInstallPlan→applyProviderInstallPlan), auth dialog step transitions (base URL selection + view-stack back-navigation), settings patches for Z.AI / MiniMax / Alibaba variants, rollback correctness, and whether the one-file contribution path actually works for a hypothetical new provider.Validation
All passed — 5 files, 57 tests, exit code 0. Includes rollback test coverage (env variable creation + deletion on error).
Quickest verification path:
Scope / Risk
This touches auth composition across CLI UI, command handling, provider definitions, and settings writing (75 files, +8,058 / −4,911). Regression risks: existing auth flows, generated settings patches for providers with multiple base URLs, and the metadata namespace migration path. CLI
qwen auth api-keynow intentionally only prints a docs link — full interactive provider setup is in the UI/authflow. Model lists in CLI and VSCode companion are independently maintained with "keep in sync" comments (no automation). No interactive E2E screenshots captured; Windows/Linux/Docker/Podman/Seatbelt not validated locally. No intentional user-facing breaking changes; OpenAI & HuggingFace entries removed (no longer referenced by the registry).Not covered — planned as follow-up PRs:
Testing Matrix
Validated on macOS only.
Linked Issues / Bugs
None.
中文说明
概要
Auth setup 之前把每种进入方式——API key、OAuth、Coding Plan、Token Plan——当作独立架构来处理。实际上它们产出的都是同一件事:
settings.json里的 provider 配置。这个 PR 把 Provider 定为第一原则,并把 所有 auth 路径统一到一条 pipeline。让 qwen-code 更 open。 旧 auth 把 provider-specific 逻辑散落在 441 行的 handler、1,321 行的 dialog 和一堆 constants 里(347 行
codingPlan、309 行 corecodingPlan、24 行alibabaStandardApiKey)。贡献者想加一个第三方 provider,就得理解整套 auth UI。重构后,新增 provider 是单文件操作:写一个ProviderConfigdescriptor,声明展示信息、所需输入、认证流程、settings patch、默认模型和模型所有权——就能自动挂进 registry。不需要碰 handler、dialog 或任何 constants。一条统一 pipeline。 无论 provider 用 API key、OAuth、订阅计划还是自定义 wizard,流程都是:收集输入 →
buildInstallPlan(config, inputs)→ProviderInstallPlan数据 →applyProviderInstallPlan(plan)→ 写入 settings。Settings 持久化与收集输入的 UI flow 解耦。UI group(alibaba、third-party、oauth、custom)帮用户导航/auth;它不驱动 settings 逻辑。具体变化:
allProviders.ts)注册 8 个 provider。ProviderConfig是声明式合约——baseUrl三态设计(固定 string 跳过步骤、BaseUrlOption[]显示选择器、undefined显示自由输入),shouldShowStep()用 TypeScript 类型信息驱动 UI 行为,ownsModel是 predicate function 让复杂 provider(如 Coding Plan 有两个 baseUrl)能精确声明模型所有权。BaseUrlOption[]替代各 provider 的regions— 有多个 base URL 的 provider(Z.AI 标准 vs Coding Plan、MiniMax 国际站 vs 中国站、Alibaba ModelStudio 4 个区域)用BaseUrlOption[]作为ProviderConfig.baseUrl的类型。从regions改名是有意的:Z.AI 的选择是 setup variant,不是地理区域。useProviderSetupFlow(声明式多步 wizard 状态机,500 行)+ProviderSetupSteps(渲染组件,476 行)。返回导航用 view stack 替代硬编码分支。useAuth简化(958 → 574 行,−40%)—handleProviderSubmit是统一提交路径。三个向后兼容 wrapper(handleSubscriptionPlanSubmit、handleApiKeyProviderSubmit、handleCustomApiKeySubmit)仍存在,但都收敛到handleProviderSubmit。codingPlanconstants(CLI 347 + core 309 行)、alibabaStandardApiKey.ts(24 行)、useCodingPlanUpdates(230 行,被通用useProviderUpdates344 行替代)。OpenAI & HuggingFace 第三方 provider 文件移除。Subscription plan 定义移到 VS Code companion 边界(294 行,subscriptionPlanDefinitions.ts)。applyProviderInstallPlan写入前备份 settings 文件,出错时完整恢复(包括回滚process.env和删除新创建的 env 变量)。useProviderUpdates在首次运行时把旧的codingPlan.*和tokenPlan.*顶层 key 迁移到providerMetadata.coding-plan.*/providerMetadata.token-plan.*。Reviewer 重点:
ProviderConfig结构和baseUrl三态模式、install-plan 边界(buildInstallPlan→applyProviderInstallPlan)、auth dialog 步骤跳转(base URL 选择 + view stack 返回导航)、Z.AI / MiniMax / Alibaba 各变体的 settings patch、rollback 正确性、以及"单文件贡献路径"对一个假设新 provider 是否真的可行。验证
全部通过——5 个文件,57 个测试,exit code 0。包含 rollback 测试覆盖(env 变量创建 + 错误时删除)。
最快验证路径:
范围 / 风险
本 PR 同时触及 CLI UI、command handling、provider definitions 和 settings 写入(75 files, +8,058 / −4,911)。回归风险:既有 auth flow、多 base URL provider 的 settings patch、metadata namespace 迁移路径。CLI
qwen auth api-key现在有意识地只打印文档链接——完整的交互式 provider setup 在 UI/auth中。CLI 和 VSCode companion 的模型列表独立维护,靠"keep in sync"注释(无自动化)。未录制交互式 E2E 截图;Windows/Linux/Docker/Podman/Seatbelt 未本地验证。无有意引入的用户可见 breaking change;OpenAI & HuggingFace 第三方 provider entry 已移除(不再被 registry 引用)。未覆盖——计划作为后续 PR:
测试矩阵
仅在 macOS 本地验证。
关联 Issue / Bug
无。