Skip to content

fix(settings): 切换 LLM/ASR preset 时凭据 UI 显示旧 active 的内容(race + 覆盖) #219

@appergb

Description

@appergb

现象

设置页切换 LLM 供应商(Ark / DeepSeek / SiliconFlow / OpenAI),或切换 ASR 供应商(SiliconFlow / GLM / Groq / OpenAI Whisper),输入框里的 API Key / 模型 / endpoint 不跟随当前 active provider 切换 —— 切到 DeepSeek 看到的还是 Ark 的 key,切回 Ark 看到的可能是 DeepSeek 残留。结果用户以为切换"没生效"。

根因(两条 bug 在同一函数)

底层 persistence.rs::CredsRoot.providers 已经是 per-provider HashMap,schema 不需要重写。bug 在前端:

1) Race

Settings.tsx::onLlmProviderChange / onAsrProviderChange 顺序错了:

const onLlmProviderChange = async (id) => {
    setLlmProvider(id);              // ① React state 立刻改
                                     //    → CredentialField key 变 → 立刻重挂载
                                     //    → 读 'ark.api_key' 时**后端 active 还没切**
                                     //    → 显示旧 active provider 的 entry
    await setActiveLlmProvider(id);  // ② 后端 active 才切——太晚
    ...
};

lookup_account 永远从 root.active.llm 那个 entry 读,所以 ① 这一刻读到的是切换前那个 provider 的凭据。

2) 覆盖

紧接其后的 setCredential('ark.endpoint', preset.baseUrl) 无条件写默认 baseUrl,把用户在该 provider 上之前自定义的 endpoint 也覆盖掉。每次切回该 provider 都会被重置。

修复

onLlmProviderChange / onAsrProviderChange 各 4-6 行 surgical 改动:

  1. 把 await setActive*Provider(id) 移到 React state 改动之前——先让后端 active 切到位,再让 CredentialField 重挂载读
  2. 写 endpoint / model 默认值改成"仅当该 provider entry 该字段为空时才填",不覆盖用户已配置的

不动 persistence schema、不动 IPC、不动 coordinator。

验收

  • 切到 DeepSeek,填 deepseek key/model → 切回 Ark 看到 Ark 自己的 key/model(保留)
  • 在 Ark 上自定义 baseUrl → 切到 DeepSeek 再切回 → Ark 的自定义 baseUrl 还在
  • ASR 端 SiliconFlow ↔ GLM ↔ Groq ↔ OpenAI 切换同款验收
  • 首次切到一个还没填过的 provider,endpoint/model 显示该 preset 默认值(保留预填便利)

不在范围:persistence schema 重写、coordinator 改动、新建 keychain 账号命名空间——全部已经是 per-provider,bug 在前端 race。

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions