-
released this
2026-07-21 13:14:42 +08:00 | 5 commits to master since this release版本概述
v0.3.10 是一个聚焦于配置保存链路健壮性的修复版本。针对 v0.3.9 版本中用户反馈的"切换 Provider 后首次保存提示 LLM 配置不全,第二次才成功"的问题进行了根本性修复,并顺带消除了一批预存的隐患。
本版本无破坏性变更,所有改动向后兼容。
一、核心修复:LLM 配置批量保存(config:setBatch IPC)
1.1 问题描述
设置页一次保存 8 个 LLM 配置字段(provider、model、apiKey、baseURL、numCtx、3 个 contextWindow)。v0.3.9 之前前端采用串行 config:set 保存:
- 第 1 步保存
llm.provider时触发 C-1 修复逻辑:Provider 变化会清空llm.apiKey - 同时触发
reloadAdapter()重建 Adapter,但此时llm.apiKey已被清空且新值尚未写入 reloadAdapter()读取到空 apiKey,返回 false- 前端收到
success: false,toast 报错"LLM 配置不完整" - 但所有字段最终都已写入 DB,第二次点保存时配置已完整,显示"已保存"
用户感知:明明全部填好了,第一次点保存报错,第二次才成功。
1.2 解决方案:config:setBatch IPC
新增
config:setBatchIPC handler(electron/ipc/handlers.ts:768-920),接收{key, value}[]数组,按以下顺序原子化处理:- 参数校验:非空数组、每个元素结构合法、value 类型合法(string|number|boolean|null)
- 第一步循环:逐条写入
configService.set(key, value)+ 审计日志(脱敏) - 第二步:统一触发一次
reloadAdapter()(仅在 LLM 字段变更时) - 第三步:统一应用 Engine/Orchestrator 配置更新
- 第四步:日志级别即时应用
- 第五步:workspace.path 写入独立文件
关键改进:reloadAdapter 只在所有字段都写入后调用一次,彻底消除中间态。
1.3 前端联动改造
SettingsModal.handleSave
src/components/settings/SettingsModal.tsx:435-473 从串行 8 次
config.set改为一次性setBatch:const entries = [ { key: 'llm.provider', value: provider }, { key: 'llm.model', value: model }, { key: 'llm.apiKey', value: apiKey }, { key: 'llm.baseURL', value: baseURL }, { key: 'ollama.numCtx', value: numCtx }, { key: 'deepseek.contextWindow', value: dsCtxWindow }, { key: 'agnes.contextWindow', value: agnesCtxWindow }, { key: 'mimo.contextWindow', value: mimoCtxWindow }, ]; const r = await setBatch(entries);OnboardingWizard.handleNext
src/components/onboarding/OnboardingWizard.tsx:26-60 从
Promise.allSettled并行 6 次config.set改为setBatch。额外修复的预存隐患:旧实现
Promise.allSettled只检查status === 'rejected',完全忽略{ success: false }的情况,导致配置实际失败但前端显示成功并关闭向导。新实现正确处理!r.success分支。1.4 preload + 类型声明
- electron/preload.ts:120-127:暴露
window.metona.config.setBatch - src/types/global.d.ts:162-167:MetonaConfigAPI 接口新增
setBatch方法签名
二、workspace.path 失败感知修复
2.1 问题描述
config:set和config:setBatch在写入workspace.path到独立文件(workspace-config.json)失败时,仅记录log.error后继续返回success: true。用户感知:看到"配置已保存",但下次启动仍使用旧 workspace 路径,误以为配置系统故障。
2.2 修复
handlers.ts:751-763(config:set)和 handlers.ts:912-922(setBatch)的 catch 块改为:
catch (err) { log.error('[CONFIG] Failed to save workspace path:', err); return { success: false, error: `工作空间路径保存失败:${(err as Error).message}` }; }前端 useConfig hook(SettingsModal.tsx:95-105)已有
!r.success的回滚 UI + toast 处理逻辑,无需改前端。
三、Provider 切换防御性顺序修复
3.1 问题描述
setBatch 原实现:在循环内处理
llm.provider时,若检测到 Provider 变化,会清空llm.apiKey。这依赖一个隐含约定:entries 数组中llm.provider必须出现在llm.apiKey之前。当前前端实现确实如此,但这是脆弱的隐含依赖。若未来开发者误把
llm.apiKey放在llm.provider之前:- 先 set
llm.apiKey(用户填写的值) - 处理
llm.provider时检测到变化,清空llm.apiKey - 用户填写的 apiKey 丢失
3.2 修复
handlers.ts:813-828:将 Provider 切换清空 apiKey 的逻辑从循环内移到循环前:
// 循环前:先扫描 entries 找出 llm.provider 的值 const providerEntry = entries.find((e) => e.key === 'llm.provider'); if (providerEntry) { const oldProvider = configService.get<string>('llm.provider') ?? ''; const newProvider = (providerEntry.value as string) ?? ''; if (oldProvider && newProvider && oldProvider !== newProvider) { configService.set('llm.apiKey', ''); } } // 然后循环按 entries 顺序 set(包括 llm.apiKey),最终值正确兼容性:前端 entries 顺序正确时,新旧实现行为完全一致;顺序错误时,新实现仍能正确保存 apiKey。
四、正确性审查结论
本次修复已经过完整审查,确认:
- ✅ setBatch 错误返回路径下的中间态可接受(DB 是 source of truth,下次发消息会再次尝试 reloadAdapter)
- ✅ Engine/Orchestrator 更新顺序与原 config:set 完全一致
- ✅ useConfig hook 保留 config.set 不与 setBatch 冲突(分别用于单字段实时保存和多字段批量保存)
- ✅ 前端代码无其他遗漏的多字段 config.set 调用场景
- ✅ Provider 切换清空 apiKey 的竞态处理正确
五、修改文件清单
文件 改动类型 说明 electron/ipc/handlers.ts新增 + 修改 新增 config:setBatch IPC(150 行);config:set 的 workspace.path 错误返回 electron/preload.ts新增 暴露 setBatch API src/types/global.d.ts新增 MetonaConfigAPI 接口新增 setBatch 类型 src/components/settings/SettingsModal.tsx修改 handleSave 改用 setBatch src/components/onboarding/OnboardingWizard.tsx修改 handleNext 改用 setBatch package.json修改 版本号 0.3.9 → 0.3.10 package-lock.json修改 版本号同步 README.md修改 版本徽章 0.3.9 → 0.3.10
六、升级说明
- 从 v0.3.9 升级:直接拉取 master 分支即可,无 DB schema 变更,无配置文件格式变更
- 首次安装:参考 README.md 中的快速开始
- 配置兼容性:v0.3.9 及之前版本保存的配置完全兼容,无需迁移
七、致谢
感谢用户反馈"切换 Provider 后首次保存报错"的问题,这次反馈直接推动了 setBatch IPC 的设计实现,让配置保存链路从根本上变得更健壮。
Downloads
- 第 1 步保存