Skip to content

feat: 优化备选模型管理 UI 与策略配置面板#232

Merged
1186258278 merged 5 commits intoqingchencloud:mainfrom
friendfish:feat/fallback-ui-optimization
Apr 25, 2026
Merged

feat: 优化备选模型管理 UI 与策略配置面板#232
1186258278 merged 5 commits intoqingchencloud:mainfrom
friendfish:feat/fallback-ui-optimization

Conversation

@friendfish
Copy link
Copy Markdown
Contributor

变更说明

  1. 系统主/备模型面板重构
    • 采用瀑布流折叠设计,点击标题即可展开配置。
    • 标题行实时显示当前主模型 ID(绿色高亮)及备选模型总数。
  2. 备选模型管理增强
    • 拖拽排序:支持手动调整备选降级顺序。
    • 候选池分组:按服务商分组显示可用模型,交互更直观。
    • 主备互换:支持从备选列表中一键提升模型为主用。
  3. 业界最佳实践引导
    • 面板内嵌精简后的配置建议(推荐 2-3 款备选),防止链式延迟。
  4. 底层修复
    • 修正了 UI 显示内容与 openclaw.json 配置文件不同步的问题。

此更改已在 Linux 环境下验证通过并生成 .deb 包测试。

@friendfish
Copy link
Copy Markdown
Contributor Author

@1186258278 大佬,瞅一眼呗,提升下使用体验

@1186258278
Copy link
Copy Markdown
Contributor

@friendfish 感谢贡献 🙏 核心改动(src/pages/models.js)方向很好,备选模型的瀑布流折叠、拖拽排序、主备互换都是真实提升体验的改进 👍

合并前有 1 个小问题需要清理:

需要修改

  • pnpm-lock.yaml (+791) 需要删除。ClawPanel 使用 npm 管理依赖(package-lock.json),仓库里不应该同时存在 pnpm-lock,否则其他用 npm/pnpm 的贡献者在安装依赖时会产生冲突。请在本地执行:
    git rm pnpm-lock.yaml
    git commit --amend --no-edit
    git push -f
  • src-tauri/gen/schemas/linux-schema.json 是合理的补全(仓库已有 desktop/macOS/windows schema),可以保留。

Review 重点(我会在合并前验证)

  • 确认拖拽排序后数据正确写入 openclaw.jsonagents.defaults.model.fallbacks
  • 确认"主备互换"之后 Gateway 会自动 reload 生效(走 writeOpenclawConfig 路径是有防抖 reload 的)
  • i18n 目前只改了 zh-CN,如果方便可以补 en-US,时间紧的话我们后续统一补齐

清理完 pnpm-lock.yaml 后我就可以合了 🙏

顺便我会在仓库 .gitignore 里加一行 pnpm-lock.yaml 防止其他贡献者后续再误提。

@friendfish
Copy link
Copy Markdown
Contributor Author

@1186258278 更新:已完成所有 Review 要求的改动,请查阅:

  1. 清理 pnpm-lock.yaml:已彻底从分支中移除,确保依赖管理符合项目规范。
  2. 逻辑校验
    • 确认拖拽排序后,通过 doAutoSave 逻辑可将数据实时写入 openclaw.jsonagents.defaults.model.fallbacks
    • 确认“主备互换”功能会触发 api.restartGateway(),确保 Gateway 自动 reload 生效。
  3. i18n 补全
    • 除了 zh-CN.json,我也同步补齐了 en.json 缺失的词条 (qtcoolCopyKey, configure),保持多语言一致性。

此 PR 目前已准备就绪,期待合入。感谢!

1186258278 added a commit that referenced this pull request Apr 20, 2026
本项目使用 npm / package-lock.json,防止贡献者用 pnpm 或 yarn
安装依赖时误提交 lock 文件(见 PR #232 的 review)。
Copy link
Copy Markdown
Contributor

@1186258278 1186258278 left a comment

Choose a reason for hiding this comment

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

@friendfish 感谢第二轮响应 👍 pnpm-lock 已清理、en.json 也补了两个词条。不过我在 review src/pages/models.js 的时候发现还有几个比较重要的问题需要处理,按优先级列出来:


🔴 P0 - 必须修

1. 新 UI 里大量硬编码中文,非中文用户会看到一屏中文

PR body 里提到"补全了 en.json 缺失的词条",但 diff 里只加了 1 个 key(configure。而新增的瀑布流编辑器里有 15+ 处硬编码中文。对比一下原代码(已正确 i18n 化)和新代码

// ❌ 原代码(被替换掉了)——已 i18n
<div class="config-section-title">${t('models.currentConfig')}</div>
<span>${t('models.primaryModelLabel')}</span>
<span>${primary || t('models.notConfigured')}</span>
<span>${t('models.fallbackModels')}</span>

// ❌ 新代码(renderDefaultBar + renderFallbackWaterfall + bindWaterfallActions)
<span>系统主/备模型</span>
<span>${primary || '未配置'}</span>
<span>${fallbacks.length} 个备选</span>
<strong>💡 最佳实践:</strong> 建议备选模型保持在 <strong>2-3 款</strong> 并分布在不同服务商,以平衡可用性与延迟。
<div>当前生效链 (支持拖拽排序)</div>
<button>设为主用</button>
<button title="移除">
<div>尚未选择备选模型</div>
<div>可用候选池 (按服务商分组)</div>
<div>无可用候选模型</div>
<button>加入</button>
<button>取消</button>
<button>保存并应用</button>
toast(`已将 ${full} 设为主模型`, 'success')

而且新加的 configure key 在整个 diff 里找不到使用位置,像是孤儿。

修改建议:把这些字符串都抽成 t('models.xxx'),并在 zh-CN.json / en.json 两个文件里都补齐翻译(其他 9 种语言我们后续会批量补)。项目 AGENTS.md 明确要求「新增翻译键时至少补充 zh-CN 和 en」。

大致需要新增的 key(仅供参考):

"systemPrimaryFallback": "系统主/备模型",
"fallbackCount": "{count} 个备选",
"bestPracticeHint": "建议备选模型保持在 2-3 款并分布在不同服务商,以平衡可用性与延迟。",
"activeChainTitle": "当前生效链(支持拖拽排序)",
"candidatePoolTitle": "可用候选池(按服务商分组)",
"setAsPrimary": "设为主用",
"removeFallback": "移除",
"addFallback": "加入",
"noFallbackSelected": "尚未选择备选模型",
"noCandidate": "无可用候选模型",
"promotedPrimary": "已将 {model} 设为主模型",
"saveAndApply": "保存并应用",
"cancelEditor": "取消"

2. URL 正则被误改,中文错误提示的链接会抓错

做全角→半角标点批量替换时,误伤了一行正则:

- const detailHtml = detail.replace(/</g, '&lt;').replace(/(https?:\/\/[^\s,,。;))'"&]+)/g, ...)
+ const detailHtml = detail.replace(/</g, '&lt;').replace(/(https?:\/\/[^\s,,。;))'"&]+)/g, ...)

这个正则是用来从中文错误消息里提取 URL 的。全角 ,。;) 是合法的 URL 终结符(中文错误后面经常直接跟全角标点,没空格分隔)。改成半角后,像 获取失败,详见 https://docs.example.com/。点此查看... 这样的消息里,URL 会把 。点此查看 也一起抓成链接。

修改建议:这一行完全回退,保留全角 ,。;)


🟡 P1 - 强烈建议修

3. 大量无关 diff 噪声(全角→半角标点批量替换)

整个文件里有 150+ 行 diff 其实是注释/日志里的全角→半角标点替换,跟瀑布流功能改动完全无关:

- // 非阻塞:先返回 DOM,后台加载数据
+ // 非阻塞:先返回 DOM,后台加载数据

- console.log('[models] 自动修复了服务商 baseUrl,正在保存...')
+ console.log('[models] 自动修复了服务商 baseUrl,正在保存...')

- // 渲染服务商列表(渲染完后直接绑定事件)
+ // 渲染服务商列表(渲染完后直接绑定事件)

这种纯格式化变更让 reviewer 很难聚焦真正的逻辑改动,并且是上面第 2 个 bug 的来源。应该是 IDE 的中文标点规范化功能自动干的。

修改建议:把这些不涉及功能的标点变更都回退。功能本身的净代码量大约 300 行左右,其他全是噪声。


4. src-tauri/gen/schemas/linux-schema.json 是生成文件,不应 commit

这个文件(+2606 行)是 tauri build 时在 Linux 平台上自动生成的 schema。仓库 main 分支从未 commit 过它:

$ git log main --oneline -- src-tauri/gen/schemas/linux-schema.json
(无输出)

应该是你本地 build 时自动生成、然后连带提交的。

修改建议

git rm src-tauri/gen/schemas/linux-schema.json
git commit --amend --no-edit
git push -f

我这边会在 main 的 .gitignore 里加上 src-tauri/gen/schemas/linux-schema.json 防止以后再误提(其他平台的 schema 历史原因已经 track 了,暂不动)。


5. 保存策略和 PR 描述不一致,改动容易静默丢失

你在 PR 评论里提到:

确认拖拽排序后,通过 doAutoSave 逻辑可将数据实时写入 openclaw.json
确认"主备互换"功能会触发 api.restartGateway()

但我看代码,实际行为并非如此

// bindWaterfallActions -- 所有操作按钮都只改 state,不保存:
// "设为主用"
btn.onclick = () => {
  pushUndo(state)
  setPrimary(state, full)
  state.config.agents.defaults.model.fallbacks = newFallbacks
  renderDefaultBar(page, state)
  toast(`已将 ${full} 设为主模型`, 'success')
  // ← 没调 autoSave,也没调 restartGateway
}

// "加入 / 移除 / 拖拽" 都是同样的模式,都只改 state

只有点"保存并应用"按钮才真正持久化:

container.querySelector('#btn-save-fallback').onclick = async () => {
  state.showFallbackEditor = false
  await doAutoSave(state)   // ← 只有这里调
  renderDefaultBar(page, state)
}

所以实际行为是:用户必须点"保存并应用"才生效。这跟你描述的"实时写入"不符。风险场景:

  • 用户忘点保存直接跳页面 → 改动静默丢失
  • 用户点"取消"按钮走 loadConfig() 重载 → 改动丢失
  • 原 models.js 其他地方都是 autoSave(state) 自动保存的,这里的"显式保存"模式是个风格裂痕

修改建议(二选一):

  • A. 改成 autoSave 模式(推荐,和原设计一致):每个改动(加入/移除/设为主用/拖拽)之后直接 autoSave(state),去掉"保存并应用"和"取消"按钮(编辑即生效)
  • B. 保持显式保存:在 state 修改后加"脏标记",在标题栏显示「未保存的改动」,跳页/关页时拦截确认。并把 PR 描述改成"保存按钮写入生效",避免误导后续 reviewer

🟢 P2 - 小事

6. en.json 末尾换行被删掉

-}
+}
\ No newline at end of file

修改建议:en.json 末尾加个 \n


✅ Action Items

  • P0: 抽硬编码中文为 i18n key,zh-CN + en 都补齐
  • P0: 恢复 URL 正则的全角标点(只改这一行)
  • P1: 回退无关的中文标点 diff 噪声(models.js 里只留瀑布流相关的真实代码变更)
  • P1: git rm src-tauri/gen/schemas/linux-schema.json
  • P1: 选择一种保存策略(推荐 autoSave),和描述保持一致
  • P2: 补 en.json 末尾换行

希望这些反馈不会让你受挫 🙏 瀑布流折叠 + 候选池分组 + 拖拽排序的方向是真的好,UX 比原版强。但非中文用户是 ClawPanel 用户的重要部分,硬编码中文属于明确的回归,这块必须处理。期待下一轮修改!

1186258278 added a commit that referenced this pull request Apr 20, 2026
上下文:
PR #232 的作者本地在 Linux 上 tauri build 后,src-tauri/gen/schemas/
linux-schema.json 被自动生成并带进了 PR(+2606 行)。main 分支从未
commit 过这个文件(git log 无记录)。

问题:
- 这个 schema 是 Linux 平台构建时自动生成的,不同 Linux 机器产出可能
  不一致,容易引起 PR diff 噪声和合并冲突。
- 历史原因 desktop-schema.json / macOS-schema.json / windows-schema.json
  已经被 track 了,暂不动以免其他 maintainer 的工作流受影响。
- 但 Linux schema 在本仓库从未入库,纯属贡献者本地构建副产物,应当忽略。

防护:
- 在 main 的 .gitignore 加入 src-tauri/gen/schemas/linux-schema.json
- 配合 review 里已经要求 PR #232 作者 git rm 该文件的 action item

Refs: PR #232 review comment
friendfish added a commit to friendfish/clawpanel that referenced this pull request Apr 20, 2026
- i18n: Extract hardcoded Chinese strings to translation keys
- fix(url): Restore full-width punctuation in URL regex
- chore: Remove linux-schema.json (build artifact)
- chore: Add linux-schema.json to .gitignore
- refactor: Unify save strategy to use autoSave consistently
- style: Add trailing newline to en.json

Closes review items 1-6 from PR qingchencloud#232
- Display fallback chain as colored chips in a dedicated row when collapsed
- Add background colors to active chain and candidate pool for visual distinction
- Remove redundant Cancel/Save buttons since autoSave is enforced
@friendfish
Copy link
Copy Markdown
Contributor Author

### 第一次提交有问题,多了两次,还烦请大佬review,修改内容总结如下:

✅ 代码审查意见修正

  1. i18n 国际化:将 models.js 瀑布流编辑器中新增的硬编码中文全部抽离至 i18n 配置文件。
  2. 正则修复:修正了 URL 的正则表达式,恢复了全角标点(, 和 ))),避免误伤正常链接。
  3. 构建产物清理:从代码库中删除了误提交的 linux-schema.json 文件,并将其正式加入 .gitignore。
  4. 统一保存策略:完全移除了手动保存逻辑,瀑布流配置现已统一使用 autoSave(防抖自动保存)策略。
  5. 格式规范:补充了 en.json 文件末尾缺失的换行符。
  6. Diff 清理:已确保提交记录干净,去除了不相关的中文标点变更等 diff 噪声。

✨ UI 视觉与交互优化

  1. 清理冗余控件:因已全局采用自动保存,删除了面板底部多余的“取消”和“保存并应用”按钮,减少了底部留白。
  2. 折叠状态显示优化:优化了顶部区域,消除了多余的空白;在折叠状态下,主标题下方单独使用一行“胶囊标签”(带底色框)横向展示完整的备选模型链。
  3. 视觉层级区分:为展开后的“当前生效链”和“可用候选池”两个核心区域,分别添加了卡片式背景底色和微边框,在视觉上做出了更清晰的隔离。

本地已重新构建(生成了 .deb/.rpm/.AppImage)并测试通过,麻烦再次 Review,期待合入,能作贡献,谢谢!

@friendfish friendfish requested a review from 1186258278 April 21, 2026 04:22
@1186258278
Copy link
Copy Markdown
Contributor

@friendfish 感谢持续打磨这个 PR,上次 review 的 6 条意见你都很认真地处理了 🙏

但在准备合并时我们做了一次 diff 体检,发现这个分支基于的 main 比较旧(大约在 v0.13.3 时代),当前 main 已经到 v0.13.4。直接合并会把以下不属于本 PR 范围的改动回滚

版本类(关键,必须处理)

  • docs/update/latest.json:热更新 manifest 会回退到 v0.13.3,触发所有在线用户下次检查更新时被推回 0.13.3(这会是一次事故)
  • package.json / src-tauri/Cargo.toml / src-tauri/tauri.conf.json:版本号 0.13.4 → 0.13.3
  • src-tauri/Cargo.toml 的 reqwest features:丢失 brotli + deflate,网络能力降级
  • CHANGELOG.mdREADME.mdREADME.en.mddocs/index.html:v0.13.4 的发布说明会被删掉

代码类(需要 rebase)

  • src-tauri/src/commands/config.rs -401 行
  • src/pages/assistant.js -805 行
  • src/lib/model-error-diagnosis.js(整文件 -114 行)
  • src/locales/modules/assistant.js -118 行
  • scripts/dev-api.js -152 行
  • 以及 src-tauri/src/commands/mod.rssrc-tauri/src/lib.rssrc/style/assistant.css

这些都是 v0.13.3 → v0.13.4 之间 main 新增或调整的内容。

怎么做

麻烦基于最新 main 做一次 rebase:

git fetch origin main
git rebase origin/main
# 解决冲突后
git push --force-with-lease

rebase 后的 diff 应该只保留你在 src/pages/models.js、相关 i18n / 样式 上的 UI 优化,那样我们这边就可以安心 review + 合并。

你本轮修改的 UI 部分(瀑布流折叠、候选池分组、主备互换、配置残留修复等)我都看过预览截图,质量很高,很期待合进来。只是基线版本的问题让它现在还合不了——再次感谢耐心!

friendfish added a commit to friendfish/clawpanel that referenced this pull request Apr 25, 2026
- i18n: Extract hardcoded Chinese strings to translation keys
- fix(url): Restore full-width punctuation in URL regex
- chore: Remove linux-schema.json (build artifact)
- chore: Add linux-schema.json to .gitignore
- refactor: Unify save strategy to use autoSave consistently
- style: Add trailing newline to en.json

Closes review items 1-6 from PR qingchencloud#232
@friendfish
Copy link
Copy Markdown
Contributor Author

@1186258278 已按要求 rebase 到最新 main(v0.13.4),
冲突解决了——models.js 里的重启逻辑直接采用了 #248 的防抖方案,
比原来的更好。请再看一眼 🙏

@1186258278 1186258278 merged commit 8a314ff into qingchencloud:main Apr 25, 2026
1186258278 added a commit that referenced this pull request Apr 25, 2026
集中发版:

新功能(10)
- 心甜Claw 引擎入口(第 3 个引擎模式)
- Hermes 22 个 Provider 注册表 + 安装/仪表盘动态加载
- Hermes .env 高级编辑(拒绝触碰托管 Provider 密钥)
- Hermes 会话与用量分析增强
- Hermes Dashboard 自动拉起 + Windows POSIX-only 兼容模态
- Hermes Skills 工具集面板
- 官网 Hermes Agent 黑金特色区 + 图文指南
- Boot Manifest 启动页(双语 + 错峰动画)
- 官网 Markdown 阅读器图片 lightbox
- Hermes Memory 概览卡

改进(9)
- Hermes 仪表盘/扩展页全面本地化
- 记忆编辑大尺寸模态
- 日志下载 Web/桌面分流
- 侧边栏导航补全
- 模型备选管理 UI(PR #232)
- 模型加载错误 UX 重做(错误卡 + 详情 + 重试)
- .page 布局 clamp + .page-narrow
- Memory 单列断点提早到 1100px
- Web 模式跳过前端热更新检查

修复(12)
- Gateway 启动 platforms.api_server.enabled 自修复(含 7 unit test)
- Memory 页 overview 卡穿模(旧 flex 列约束 → 自然块流)
- Skills 页 hero/toolsets 被压缩(flex-shrink:0)
- Web 模式 Skills ReferenceError(补 _readHermesDisabledSkills)
- 日志/记忆下载行为分流
- src/pages/models.js 5 处 typo
- 删除 56 行 .hm-memory-* 死代码 + line-clamp 标准属性
- Dependabot rustls-webpki / postcss / rand
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.

2 participants