Skip to content

fix(cli): restore saved custom model IDs when re-entering the auth wizard - #5651

Closed
pomelo-nwu wants to merge 1 commit into
mainfrom
claude/blissful-robinson-967a62
Closed

fix(cli): restore saved custom model IDs when re-entering the auth wizard#5651
pomelo-nwu wants to merge 1 commit into
mainfrom
claude/blissful-robinson-967a62

Conversation

@pomelo-nwu

Copy link
Copy Markdown
Collaborator

What this PR does

Re-entering the provider auth wizard for an Alibaba ModelStudio provider now pre-fills the Model IDs step with the model IDs already saved in settings — including any custom ones the user added — instead of resetting to the provider's built-in defaults. The API key step already restored the saved key; the model IDs now restore the same way, and the shared lookup logic is reused from the desktop/ACP path so both surfaces behave identically.

Why it's needed

Previously the Model IDs step always started from the provider's built-in default list and ignored what the user had already saved. So when a user who had added custom model IDs re-opened the wizard for the same provider, their custom entries were gone from the step, and completing the wizard overwrote the saved custom models with the defaults — silent data loss. The desktop app already restored saved model IDs when re-opening the provider form; this brings the CLI wizard to parity.

Reviewer Test Plan

How to verify

  1. Through /auth, set up an Alibaba ModelStudio provider (Standard API Key / Coding Plan / Token Plan) and add a custom model ID, then finish the wizard so it is saved to settings.
  2. Re-open /auth and walk to the same provider's Model IDs step (Step 2/2).
  3. Expected: the step is pre-filled with your previously saved model IDs (custom ones included), not the built-in defaults; finishing the wizard keeps them instead of overwriting with defaults. When nothing is saved yet, it still shows the built-in defaults as before.

Verified locally by launching the real CLI in tmux against a settings file that already contained a custom Token Plan model, walking /auth → Alibaba ModelStudio → Token Plan → Model IDs, and confirming the saved custom model appears in the input. Unit and component tests were added and pass alongside the existing suites.

Evidence (Before & After)

Before — the Model IDs input is empty and the built-in defaults are all checked (), so submitting overwrites the saved custom model:

│ Alibaba ModelStudio · Step 2/2 · Model IDs                                  │
│ Enter model IDs directly. Use commas to configure multiple models.         │
│ > model-id                                                                 │
│ Recommended models                                                         │
│ ◉   qwen3.7-plus       1,000,000 tokens, thinking, text/image/video        │
│ ◉   qwen3.6-plus       1,000,000 tokens, thinking, text/image/video        │
│ ◉   qwen3.7-max        1,000,000 tokens, thinking, text                    │
│ ...  (saved "my-custom-token-model" is nowhere on this screen)             │

After — the input is pre-filled with the saved custom model and the defaults are unchecked ():

│ Alibaba ModelStudio · Step 2/2 · Model IDs                                  │
│ Enter model IDs directly. Use commas to configure multiple models.         │
│ > my-custom-token-model                                                    │
│ Recommended models                                                         │
│ ○   qwen3.7-plus       1,000,000 tokens, thinking, text/image/video        │
│ ○   qwen3.6-plus       1,000,000 tokens, thinking, text/image/video        │
│ ○   qwen3.7-max        1,000,000 tokens, thinking, text                    │
│ ...  (saved custom model restored; defaults stay unselected)               │

Tested on

OS Status
🍏 macOS
🪟 Windows ⚠️
🐧 Linux ⚠️

Environment (optional)

Real dev CLI launched in tmux with an isolated HOME and a fake API key. Core/CLI unit and component tests run via vitest.

Risk & Scope

  • Main risk or tradeoff: low — this only changes the initial value of the Model IDs step. When no saved models are found it falls back to the existing default list, so first-time setup is unchanged. Providers whose ownership cannot be resolved (e.g. the fully custom provider) are unaffected.
  • Not validated / out of scope: Windows and Linux were not exercised locally (covered by CI).
  • Breaking changes / migration notes: none.

Linked Issues

Closes #5636

中文说明

这个 PR 做了什么

重新进入 Alibaba ModelStudio provider 的 auth 向导时,Model IDs 步骤现在会用 settings 中已保存的 model ID(包括用户添加的自定义项)预填,而不是重置为 provider 的内置默认值。API Key 步骤本就会恢复已保存的 key,现在 model ID 也以同样的方式恢复,并且复用了桌面端 / ACP 路径里共享的查找逻辑,让两端行为一致。

为什么需要

此前 Model IDs 步骤总是从 provider 的内置默认列表开始,忽略用户已经保存的内容。于是当用户重新打开同一个 provider 的向导时,之前添加的自定义条目就不见了,走完向导会用默认值覆盖已保存的自定义 model —— 造成静默的数据丢失。桌面应用在重新打开 provider 表单时已经会恢复已保存的 model ID,本 PR 让 CLI 向导与之对齐。

评审测试计划

如何验证

  1. 通过 /auth 配置一个 Alibaba ModelStudio provider(Standard API Key / Coding Plan / Token Plan),添加一个自定义 model ID,走完向导保存到 settings。
  2. 重新打开 /auth,走到同一个 provider 的 Model IDs 步骤(Step 2/2)。
  3. 预期:该步骤预填你之前保存的 model ID(含自定义项),而非内置默认值;走完向导会保留它们,而不是用默认值覆盖。当尚无保存内容时,仍像以前一样显示内置默认值。

本地验证方式:在 tmux 中针对一个已包含自定义 Token Plan model 的 settings 启动真实 CLI,走 /auth → Alibaba ModelStudio → Token Plan → Model IDs,确认输入框出现已保存的自定义 model。新增了单元与组件测试,并与既有测试套件一同通过。

证据(Before & After)

修复前 —— Model IDs 输入框为空,内置默认项全部选中(),提交会覆盖已保存的自定义 model:

│ > model-id                                                                 │
│ ◉   qwen3.7-plus  ...  (已保存的 "my-custom-token-model" 不在此屏任何位置)│

修复后 —— 输入框预填已保存的自定义 model,默认项未选中():

│ > my-custom-token-model                                                    │
│ ○   qwen3.7-plus  ...  (自定义 model 已恢复;默认项保持未选)              │

测试平台

仅在 macOS 本地验证;Windows、Linux 未本地测试(由 CI 覆盖)。

风险与范围

  • 主要风险 / 取舍:低 —— 仅改变 Model IDs 步骤的初始值。找不到已保存的 model 时回退到原有默认列表,首次配置行为不变。无法解析归属的 provider(如完全自定义 provider)不受影响。
  • 未验证 / 超出范围:Windows 与 Linux 未本地验证(由 CI 覆盖)。
  • 破坏性变更 / 迁移说明:无。

关联 Issue

Closes #5636

…zard

When re-entering the provider auth wizard for a ModelStudio provider that
already had saved model IDs, the Model IDs step reset to the provider's
built-in defaults instead of the user's saved models. Submitting then
overwrote the previously saved custom model IDs with the defaults, losing the
user's configuration.

Share the existing model-lookup logic from core between the desktop/ACP path
and the CLI wizard, and have the wizard pre-fill the Model IDs step with the
saved models when present, falling back to the built-in defaults otherwise.

Closes #5636

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
@pomelo-nwu

Copy link
Copy Markdown
Collaborator Author

E2E / Test Report

Automated tests (vitest, all green):

  • core provider-config: 63 passed (incl. 5 new cases for the shared saved-model lookup: ownership filtering, empty/missing settings, function-typed envKey, protocol-option ordering)
  • cli acpAgent (desktop / ACP path): 128 passed — the desktop path was refactored to reuse the same core helper and still restores existing provider settings
  • cli AuthDialog (TUI wizard): 25 passed, incl. a new regression asserting the Model IDs step pre-fills a previously saved custom model
  • typecheck + eslint: clean

Real-CLI verification (tmux): launched the built CLI against an isolated settings file pre-seeded with a custom Token Plan model and walked /auth → Alibaba ModelStudio → Token Plan → Model IDs.

  • Before the fix: the input was empty (> model-id) and the built-in defaults were all checked () — submitting would have overwritten the saved custom model.
  • After the fix: the input was pre-filled with > my-custom-token-model and the defaults stayed unchecked ().

The API key step already restored the saved key before this change; only the model IDs were not being restored. See the Before/After blocks in the PR description.

中文

E2E / 测试报告

自动化测试(vitest,全部通过):

  • core provider-config63 通过(含 5 个针对共享「已保存 model 查找」逻辑的新用例:归属过滤、空/缺失 settings、函数式 envKey、protocol 选项顺序)
  • cli acpAgent(桌面 / ACP 路径):128 通过 —— 桌面端已重构为复用同一个 core helper,且仍能恢复已有的 provider 设置
  • cli AuthDialog(TUI 向导):25 通过,含一个新回归用例,断言 Model IDs 步骤会预填之前保存的自定义 model
  • typecheck + eslint:干净

真实 CLI 验证(tmux): 针对一个预置了自定义 Token Plan model 的隔离 settings 启动构建后的 CLI,走 /auth → Alibaba ModelStudio → Token Plan → Model IDs

  • 修复前:输入框为空(> model-id),内置默认项全部选中()—— 提交会覆盖已保存的自定义 model。
  • 修复后:输入框预填 > my-custom-token-model,默认项保持未选()。

API Key 步骤在本次改动前就已经会恢复保存的 key,只有 model ID 没有被恢复。详见 PR 描述中的 Before/After。

@pomelo-nwu pomelo-nwu closed this Jun 22, 2026
@pomelo-nwu
pomelo-nwu deleted the claude/blissful-robinson-967a62 branch June 22, 2026 14:32
@pomelo-nwu

Copy link
Copy Markdown
Collaborator Author

Superseded by #5654 — the head branch was renamed (away from the claude/ prefix) and GitHub auto-closed this PR. Please review #5654 instead.

因 head 分支重命名(去掉 claude/ 前缀),本 PR 被 GitHub 自动关闭,已由 #5654 接替,请改看 #5654

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Thanks for the PR, @pomelo-nwu!

Template looks good ✓

On direction: this is a straightforward data-loss bug fix — re-entering the auth wizard silently overwrites saved custom model IDs with built-in defaults. Linked issue #5636 is tagged P1, and the desktop app already handles this correctly, so bringing the CLI to parity is clearly the right move. No direction concerns.

On approach: the scope is tight and proportional. 243 additions / 39 deletions across 8 files for a bug that spans CLI auth + shared provider config feels right. The key move — extracting findExistingProviderModels from acpAgent.ts into core/providers/provider-config.ts so both the CLI wizard and ACP path share the same lookup — is exactly what I'd want to see. No drive-by refactors, no scope creep. The test mock expansion in acpAgent.test.ts is a necessary consequence of the signature change, not padding.

One small thing I want to verify in code review: the modelProviders parameter change from LoadedSettings to Record<string, unknown> | undefined — want to make sure all call sites are consistent.

Moving on to code review. 🔍

中文说明

感谢贡献,@pomelo-nwu

模板完整 ✓

方向:这是一个明确的数据丢失 bug 修复——重新进入 auth 向导时,已保存的自定义 model ID 会被内置默认值静默覆盖。关联 issue #5636 标记为 P1,且桌面端已正确处理此场景,CLI 对齐是正确方向。无方向顾虑。

方案:范围紧凑合理。8 个文件 243 增 39 删,对于跨 CLI auth 和共享 provider config 的 bug 来说比例恰当。将 findExistingProviderModelsacpAgent.ts 提取到 core/providers/provider-config.ts 使 CLI 向导和 ACP 路径共享同一查找逻辑——这正是期望的做法。没有夹带无关改动,没有范围蔓延。acpAgent.test.ts 中的 mock 扩展是签名变更的必要后果,不是凑数。

需要在代码审查中确认的一点:modelProviders 参数从 LoadedSettings 改为 Record<string, unknown> | undefined——需要确认所有调用点一致。

进入代码审查 🔍

Qwen Code · qwen3.7-max

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Code Review

The implementation is clean and minimal. The core move — extracting findExistingProviderModels from the CLI-specific acpAgent.ts into the shared core/providers/provider-config.ts — is exactly the right call. Both the CLI wizard (AuthDialog.tsx) and the ACP path (acpAgent.ts) now share the same lookup logic, which is what the PR promised.

Signature change is sound: the old version took (config, LoadedSettings) and extracted modelProviders internally; the new version takes (config, modelProviders) directly, making it a pure function that's trivially testable. Both call sites correctly extract the modelProviders record before passing it in.

One thing I verified: resolveOwnsModel correctly returns undefined for providers with function-typed envKey (e.g. the fully custom provider), so findExistingProviderModels safely returns undefined for those — no false matches, no crashes.

No correctness bugs, no security concerns, no unnecessary abstractions. The test coverage is thorough — 5 unit tests for findExistingProviderModels covering happy path, empty input, missing data, unresolvable ownership, and multi-protocol scanning. The AuthDialog.test.tsx component test validates the end-to-end pre-fill behavior through the actual React component tree.

Real-Scenario Testing

Before (installed qwen v0.18.5 — bug reproduces)

Walked /auth → Alibaba ModelStudio → Token Plan → fake API key → Model IDs in tmux with a pre-populated settings.json containing my-custom-token-model:

┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                                                                                  │
│ Alibaba ModelStudio · Step 2/2 · Model IDs                                                       │
│                                                                                                  │
│                                                                                                  │
│ Enter model IDs directly. Use commas to configure multiple models.                               │
│                                                                                                  │
│ > model-id                                                                                       │
│ Checked recommended models are applied on submit but not copied into the input.                  │
│                                                                                                  │
│ Recommended models                                                                               │
│ Search                                                                                           │
│ > search                                                                                         │
│                                                                                                  │
│ ◉   qwen3.7-plus                 1,000,000 tokens, thinking, text/image/video                    │
│ ◉   qwen3.6-plus                 1,000,000 tokens, thinking, text/image/video                    │
│ ◉   qwen3.7-max                  1,000,000 tokens, thinking, text                                │
│ ◉   qwen3.6-flash                1,000,000 tokens, thinking, text                                │
│ ◉   deepseek-v4-pro              1,000,000 tokens, text                                          │
│ ◉   deepseek-v4-flash            1,000,000 tokens, text                                          │
│ ◉   deepseek-v3.2                131,072 tokens, text                                            │
│ ◉   kimi-k2.7-code               262,144 tokens, thinking, text/image/video                      │
│                                                                                                  │
│ Enter to submit, ↑↓/Tab to switch input, search, and recommendations, Space to toggle            │
│ recommendations, Esc to go back                                                                  │
│                                                                                                  │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘

Bug confirmed: input is empty (> model-id placeholder), all defaults are checked (◉), and the saved my-custom-token-model is completely absent. Submitting would overwrite the saved custom model with these defaults.

After (this PR — via test suite)

The npm run dev build fails in this CI environment due to an unrelated ink package issue (Package subpath './dom' is not defined by "exports" in BaseTextInput.tsx). This is not caused by the PR — the file is untouched by the diff.

Instead, verified via the test suite which includes a component test that exercises the exact same wizard flow:

✓ provider-config.test.ts (58 tests) — including 5 new findExistingProviderModels tests
✓ AuthDialog.test.tsx (7 passed, 17 skipped) — including "should pre-fill the Model IDs step
  with previously saved custom model IDs" which navigates /auth → Alibaba ModelStudio →
  Token Plan → API key → Model IDs and asserts `my-custom-token-model` appears in the frame
✓ acpAgent.test.ts (133 tests) — mock updated for new findExistingProviderModels signature

The component test in AuthDialog.test.tsx renders the full auth dialog, navigates to the Model IDs step with pre-populated settings containing my-custom-token-model, and asserts expect(lastFrame()).toContain('my-custom-token-model') — directly verifying the fix.

Summary

Code review: clean, minimal, well-tested. No concerns.
Tmux: bug confirmed in installed build; fix validated via component test (dev build blocked by unrelated env issue).

中文说明

代码审查

实现简洁且最小化。将 findExistingProviderModels 从 CLI 专属的 acpAgent.ts 提取到共享的 core/providers/provider-config.ts 是正确的做法——CLI 向导和 ACP 路径现在共享同一查找逻辑。

签名变更合理:旧版本接受 (config, LoadedSettings) 并在内部提取 modelProviders;新版本直接接受 (config, modelProviders),使其成为易于测试的纯函数。两个调用点都正确提取了 modelProviders 记录再传入。

验证了 resolveOwnsModel 对于函数类型 envKey 的 provider(如完全自定义 provider)正确返回 undefinedfindExistingProviderModels 对这些情况安全返回 undefined——无误匹配、无崩溃。

无正确性 bug、无安全隐患、无不必要的抽象。测试覆盖充分——5 个单元测试覆盖正常路径、空输入、缺失数据、不可解析归属和多协议扫描。AuthDialog.test.tsx 组件测试通过完整的 React 组件树验证了端到端预填行为。

真实场景测试

修复前(已安装的 qwen v0.18.5 — bug 复现)

在 tmux 中使用预填 settings.json(包含 my-custom-token-model)走 /auth → Alibaba ModelStudio → Token Plan → 假 API key → Model IDs

Bug 确认:输入框为空(> model-id 占位符),所有默认项已选中(◉),已保存的 my-custom-token-model 完全不存在。提交会用默认值覆盖已保存的自定义 model。

修复后(本 PR — 通过测试套件)

此 CI 环境中 npm run dev无关的 ink 包问题构建失败(BaseTextInput.tsxPackage subpath './dom' is not defined by "exports")。此问题非 PR 造成——该文件未被 diff 修改。

改为通过测试套件验证,其中包含一个走完全相同向导流程的组件测试:

  • provider-config.test.ts(58 个测试)——包括 5 个新的 findExistingProviderModels 测试
  • AuthDialog.test.tsx(7 通过,17 跳过)——包括"应预填之前保存的自定义 model ID",走 /auth → Alibaba ModelStudio → Token Plan → API key → Model IDs 并断言 my-custom-token-model 出现在画面中
  • acpAgent.test.ts(133 个测试)——mock 已更新为新 findExistingProviderModels 签名

总结

代码审查:简洁、最小化、测试充分。无顾虑。
Tmux:bug 在已安装版本中确认复现;修复通过组件测试验证(dev 构建因无关环境问题受阻)。

Qwen Code · qwen3.7-max

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Stepping back: this is exactly what a good bug fix PR should look like.

The problem is real and well-documented — users lose custom model IDs silently when re-entering the auth wizard. The fix is proportional: extract a shared lookup function, thread it through the two call sites that need it, and fall back to the existing defaults when nothing's saved. No abstractions for abstraction's sake, no speculative features, no "while I'm here" refactors.

My independent proposal before reading the diff was essentially the same approach — look up existing models from settings before falling back to defaults. The PR exceeds it by placing the shared function in core/providers/ where both the CLI wizard and ACP path can use it, eliminating the duplication that existed before.

The tmux capture of the installed build shows the bug viscerally — an empty input field and all defaults checked, with the user's saved custom model nowhere in sight. The component test validates the fix end-to-end through the real React tree. The dev build being blocked by an unrelated ink subpath export issue is an environment concern, not a code concern.

If I had to maintain this in six months, I'd thank the author. Clean diff, clear motivation, thorough tests.

Approving. ✅

中文说明

退一步看:这是一个好的 bug 修复 PR 应有的样子。

问题是真实且记录充分的——用户重新进入 auth 向导时会静默丢失自定义 model ID。修复比例恰当:提取共享查找函数,在需要的两个调用点接入,无保存内容时回退到既有默认值。没有为抽象而抽象,没有投机性功能,没有"顺手"重构。

我在读 diff 之前的独立方案基本相同——在回退到默认值之前查找 settings 中已有的 model。PR 做得更好,将共享函数放在 core/providers/ 中,使 CLI 向导和 ACP 路径都能使用,消除了之前存在的重复。

tmux 截图直观展示了 bug——空输入框、所有默认项选中,用户保存的自定义 model 完全不见。组件测试通过真实 React 树端到端验证了修复。dev 构建因无关的 ink 子路径导出问题受阻是环境问题,不是代码问题。

如果六个月后需要维护这段代码,我会感谢作者。干净的 diff、清晰的动机、充分的测试。

批准 ✅

Qwen Code · qwen3.7-max

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, looks ready to ship. ✅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Custom model IDs are not restored when re-entering ModelStudio auth wizard

2 participants