From 1141b5867b147ac9070919e7cf2a51ae50b2bbb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=99=B4=E5=A4=A9?= Date: Thu, 26 Mar 2026 02:11:53 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20#142=20=E5=AD=90Agent=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E4=B8=8D=E5=86=8D=E8=A2=AB=E5=85=A8=E5=B1=80?= =?UTF-8?q?=E4=B8=BB=E6=A8=A1=E5=9E=8B=E8=A6=86=E7=9B=96=20+=20#143=20nvm/?= =?UTF-8?q?fnm=E7=89=88=E6=9C=AC=E6=8C=89=E5=80=92=E5=BA=8F=E6=8E=92?= =?UTF-8?q?=E5=88=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - models.js: 移除 applyDefaults 中强制同步全局 primary 到所有子 Agent 的逻辑 (#142) - mod.rs: nvm/fnm 版本目录按文件名倒序排列,最新版优先 (#143,macOS + Linux) --- src-tauri/src/commands/mod.rs | 50 +++++++++++++++++++++-------------- src/pages/models.js | 12 +++------ 2 files changed, 33 insertions(+), 29 deletions(-) diff --git a/src-tauri/src/commands/mod.rs b/src-tauri/src/commands/mod.rs index ef7ceff..157de82 100644 --- a/src-tauri/src/commands/mod.rs +++ b/src-tauri/src/commands/mod.rs @@ -259,14 +259,17 @@ fn build_enhanced_path() -> String { extra.push(format!("{}/bin", prefix)); } // 扫描 nvm 实际安装的版本目录(兼容无 current 符号链接的情况) + // 按版本号倒序排列,确保最新版优先(修复 #143:v20 排在 v24 前面) let nvm_versions = home.join(".nvm/versions/node"); if nvm_versions.is_dir() { if let Ok(entries) = std::fs::read_dir(&nvm_versions) { - for entry in entries.flatten() { - let bin = entry.path().join("bin"); - if bin.is_dir() { - extra.push(bin.to_string_lossy().to_string()); - } + let mut dirs: Vec<_> = entries + .flatten() + .filter(|e| e.path().join("bin").is_dir()) + .collect(); + dirs.sort_by(|a, b| b.file_name().cmp(&a.file_name())); + for entry in dirs { + extra.push(entry.path().join("bin").to_string_lossy().to_string()); } } } @@ -278,11 +281,13 @@ fn build_enhanced_path() -> String { let fnm_versions = fnm_dir.join("node-versions"); if fnm_versions.is_dir() { if let Ok(entries) = std::fs::read_dir(&fnm_versions) { - for entry in entries.flatten() { - let bin = entry.path().join("installation/bin"); - if bin.is_dir() { - extra.push(bin.to_string_lossy().to_string()); - } + let mut dirs: Vec<_> = entries + .flatten() + .filter(|e| e.path().join("installation/bin").is_dir()) + .collect(); + dirs.sort_by(|a, b| b.file_name().cmp(&a.file_name())); + for entry in dirs { + extra.push(entry.path().join("installation/bin").to_string_lossy().to_string()); } } } @@ -316,6 +321,7 @@ fn build_enhanced_path() -> String { extra.push(format!("{}/bin", prefix)); } // NVM_DIR 环境变量(用户可能自定义了 nvm 安装目录) + // 按版本号倒序排列,确保最新版优先(修复 #143:v20 排在 v24 前面) let nvm_dir = std::env::var("NVM_DIR") .ok() .map(std::path::PathBuf::from) @@ -323,11 +329,13 @@ fn build_enhanced_path() -> String { let nvm_versions = nvm_dir.join("versions/node"); if nvm_versions.is_dir() { if let Ok(entries) = std::fs::read_dir(&nvm_versions) { - for entry in entries.flatten() { - let bin = entry.path().join("bin"); - if bin.is_dir() { - extra.push(bin.to_string_lossy().to_string()); - } + let mut dirs: Vec<_> = entries + .flatten() + .filter(|e| e.path().join("bin").is_dir()) + .collect(); + dirs.sort_by(|a, b| b.file_name().cmp(&a.file_name())); + for entry in dirs { + extra.push(entry.path().join("bin").to_string_lossy().to_string()); } } } @@ -339,11 +347,13 @@ fn build_enhanced_path() -> String { let fnm_versions = fnm_dir.join("node-versions"); if fnm_versions.is_dir() { if let Ok(entries) = std::fs::read_dir(&fnm_versions) { - for entry in entries.flatten() { - let bin = entry.path().join("installation/bin"); - if bin.is_dir() { - extra.push(bin.to_string_lossy().to_string()); - } + let mut dirs: Vec<_> = entries + .flatten() + .filter(|e| e.path().join("installation/bin").is_dir()) + .collect(); + dirs.sort_by(|a, b| b.file_name().cmp(&a.file_name())); + for entry in dirs { + extra.push(entry.path().join("installation/bin").to_string_lossy().to_string()); } } } diff --git a/src/pages/models.js b/src/pages/models.js index cbf8c82..8d22be9 100644 --- a/src/pages/models.js +++ b/src/pages/models.js @@ -741,15 +741,9 @@ function applyDefaultModel(state) { for (const fb of fallbacks) modelsMap[fb] = {} defaults.models = modelsMap - // 同步到各 agent 的模型覆盖配置,避免 agent 级别的旧值覆盖全局默认 - const list = state.config.agents?.list - if (Array.isArray(list)) { - for (const agent of list) { - if (agent.model && typeof agent.model === 'object' && agent.model.primary) { - agent.model.primary = primary - } - } - } + // 注意:不再强制同步到各 agent 的 model.primary + // 子 Agent 的模型覆盖是 OpenClaw 正常功能(用户可通过对话为不同 Agent 设置不同模型) + // 强制覆盖会导致 #142:重开 ClawPanel 后子 Agent 模型配置被重置 } // 顶部按钮事件