Compare commits

..

1 Commits

Author SHA1 Message Date
YoVinchen 1b22a89572 Align Thinking fallback with main-model-only Claude mappings
The Claude provider form reopened with an empty Thinking model after users saved only a main model. This updates model-state hydration to mirror the existing Haiku-style fallback semantics: read ANTHROPIC_REASONING_MODEL when present, otherwise display ANTHROPIC_MODEL, without writing a synthetic reasoning field back into config.

Constraint: Existing Haiku, Sonnet, and Opus selectors already rely on read-time fallback behavior
Rejected: Persist ANTHROPIC_REASONING_MODEL from ANTHROPIC_MODEL automatically | would diverge from Haiku behavior and silently rewrite saved config
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep Thinking fallback read-only unless all model-mapping fields are intentionally migrated to write-through semantics
Tested: pnpm typecheck
Tested: pnpm test:unit (1 unrelated pre-existing failure in tests/components/UnifiedSkillsPanel.test.tsx mock setup)
Not-tested: Manual add-provider reopen flow in the desktop UI
2026-04-10 11:31:39 +08:00
9 changed files with 30 additions and 92 deletions
-1
View File
@@ -948,7 +948,6 @@ exec bash --norc --noprofile
"kitty" => launch_macos_open_app("kitty", &script_file, false),
"ghostty" => launch_macos_open_app("Ghostty", &script_file, true),
"wezterm" => launch_macos_open_app("WezTerm", &script_file, true),
"kaku" => launch_macos_open_app("Kaku", &script_file, true),
_ => launch_macos_terminal_app(&script_file), // "terminal" or default
};
+17 -77
View File
@@ -20,7 +20,6 @@ pub fn launch_terminal(
"ghostty" => launch_ghostty(command, cwd),
"kitty" => launch_kitty(command, cwd),
"wezterm" => launch_wezterm(command, cwd),
"kaku" => launch_kaku(command, cwd),
"alacritty" => launch_alacritty(command, cwd),
"custom" => launch_custom(command, cwd, custom_config),
_ => Err(format!("Unsupported terminal target: {target}")),
@@ -154,10 +153,25 @@ fn launch_kitty(command: &str, cwd: Option<&str>) -> Result<(), String> {
fn launch_wezterm(command: &str, cwd: Option<&str>) -> Result<(), String> {
// wezterm start --cwd ... -- command
// To invoke via `open`, we use `open -na "WezTerm" --args start ...`
let args = build_wezterm_compatible_args("WezTerm", command, cwd);
let full_command = build_shell_command(command, None);
let mut args = vec!["-na", "WezTerm", "--args", "start"];
if let Some(dir) = cwd {
args.push("--cwd");
args.push(dir);
}
// Invoke shell to run the command string (to handle pipes, etc)
let shell = std::env::var("SHELL").unwrap_or_else(|_| "/bin/zsh".to_string());
args.push("--");
args.push(&shell);
args.push("-c");
args.push(&full_command);
let status = Command::new("open")
.args(args.iter().map(String::as_str))
.args(&args)
.status()
.map_err(|e| format!("Failed to launch WezTerm: {e}"))?;
@@ -168,54 +182,6 @@ fn launch_wezterm(command: &str, cwd: Option<&str>) -> Result<(), String> {
}
}
fn launch_kaku(command: &str, cwd: Option<&str>) -> Result<(), String> {
// Kaku is a WezTerm-derived terminal and keeps a compatible `start` entrypoint.
let args = build_wezterm_compatible_args("Kaku", command, cwd);
let status = Command::new("open")
.args(args.iter().map(String::as_str))
.status()
.map_err(|e| format!("Failed to launch Kaku: {e}"))?;
if status.success() {
Ok(())
} else {
Err("Failed to launch Kaku.".to_string())
}
}
fn build_wezterm_compatible_args(app_name: &str, command: &str, cwd: Option<&str>) -> Vec<String> {
let shell = std::env::var("SHELL").unwrap_or_else(|_| "/bin/zsh".to_string());
build_wezterm_compatible_args_with_shell(app_name, command, cwd, &shell)
}
fn build_wezterm_compatible_args_with_shell(
app_name: &str,
command: &str,
cwd: Option<&str>,
shell: &str,
) -> Vec<String> {
let full_command = build_shell_command(command, None);
let mut args = vec![
"-na".to_string(),
app_name.to_string(),
"--args".to_string(),
"start".to_string(),
];
if let Some(dir) = cwd {
args.push("--cwd".to_string());
args.push(dir.to_string());
}
// Invoke shell to run the command string (to handle pipes, etc)
args.push("--".to_string());
args.push(shell.to_string());
args.push("-c".to_string());
args.push(full_command);
args
}
fn launch_alacritty(command: &str, cwd: Option<&str>) -> Result<(), String> {
// Alacritty: open -na Alacritty --args --working-directory ... -e shell -c command
let full_command = build_shell_command(command, None);
@@ -339,30 +305,4 @@ mod tests {
"raw:echo foo\\\\\\\\bar\\npwd\\n"
);
}
#[test]
fn wezterm_compatible_terminals_use_start_and_cwd_arguments() {
let args = build_wezterm_compatible_args_with_shell(
"Kaku",
"claude --resume abc-123",
Some("/tmp/project dir"),
"/bin/zsh",
);
assert_eq!(
args,
vec![
"-na".to_string(),
"Kaku".to_string(),
"--args".to_string(),
"start".to_string(),
"--cwd".to_string(),
"/tmp/project dir".to_string(),
"--".to_string(),
"/bin/zsh".to_string(),
"-c".to_string(),
"claude --resume abc-123".to_string(),
]
);
}
}
+1 -1
View File
@@ -273,7 +273,7 @@ pub struct AppSettings {
// ===== 终端设置 =====
/// 首选终端应用(可选,默认使用系统默认终端)
/// - macOS: "terminal" | "iterm2" | "warp" | "alacritty" | "kitty" | "ghostty" | "wezterm" | "kaku"
/// - macOS: "terminal" | "iterm2" | "warp" | "alacritty" | "kitty" | "ghostty"
/// - Windows: "cmd" | "powershell" | "wt" (Windows Terminal)
/// - Linux: "gnome-terminal" | "konsole" | "xfce4-terminal" | "alacritty" | "kitty" | "ghostty"
#[serde(default, skip_serializing_if = "Option::is_none")]
@@ -14,10 +14,11 @@ function parseModelsFromConfig(settingsConfig: string) {
const env = cfg?.env || {};
const model =
typeof env.ANTHROPIC_MODEL === "string" ? env.ANTHROPIC_MODEL : "";
const reasoning =
const explicitReasoning =
typeof env.ANTHROPIC_REASONING_MODEL === "string"
? env.ANTHROPIC_REASONING_MODEL
: "";
const reasoning = explicitReasoning || model;
const small =
typeof env.ANTHROPIC_SMALL_FAST_MODEL === "string"
? env.ANTHROPIC_SMALL_FAST_MODEL
@@ -92,10 +93,11 @@ export function useModelState({
const env = cfg?.env || {};
const model =
typeof env.ANTHROPIC_MODEL === "string" ? env.ANTHROPIC_MODEL : "";
const reasoning =
const explicitReasoning =
typeof env.ANTHROPIC_REASONING_MODEL === "string"
? env.ANTHROPIC_REASONING_MODEL
: "";
const reasoning = explicitReasoning || model;
const small =
typeof env.ANTHROPIC_SMALL_FAST_MODEL === "string"
? env.ANTHROPIC_SMALL_FAST_MODEL
@@ -148,16 +150,17 @@ export function useModelState({
? JSON.parse(settingsConfig)
: { env: {} };
if (!currentConfig.env) currentConfig.env = {};
const env = currentConfig.env as Record<string, unknown>;
// 新键仅写入;旧键不再写入
const trimmed = value.trim();
if (trimmed) {
currentConfig.env[field] = trimmed;
env[field] = trimmed;
} else {
delete currentConfig.env[field];
delete env[field];
}
// 删除旧键
delete currentConfig.env["ANTHROPIC_SMALL_FAST_MODEL"];
delete env["ANTHROPIC_SMALL_FAST_MODEL"];
onConfigChange(JSON.stringify(currentConfig, null, 2));
} catch (err) {
@@ -16,7 +16,6 @@ const MACOS_TERMINALS = [
{ value: "kitty", labelKey: "settings.terminal.options.macos.kitty" },
{ value: "ghostty", labelKey: "settings.terminal.options.macos.ghostty" },
{ value: "wezterm", labelKey: "settings.terminal.options.macos.wezterm" },
{ value: "kaku", labelKey: "settings.terminal.options.macos.kaku" },
] as const;
const WINDOWS_TERMINALS = [
+1 -2
View File
@@ -535,8 +535,7 @@
"alacritty": "Alacritty",
"kitty": "Kitty",
"ghostty": "Ghostty",
"wezterm": "WezTerm",
"kaku": "Kaku"
"wezterm": "WezTerm"
},
"windows": {
"cmd": "Command Prompt",
+1 -2
View File
@@ -535,8 +535,7 @@
"alacritty": "Alacritty",
"kitty": "Kitty",
"ghostty": "Ghostty",
"wezterm": "WezTerm",
"kaku": "Kaku"
"wezterm": "WezTerm"
},
"windows": {
"cmd": "コマンドプロンプト",
+1 -2
View File
@@ -535,8 +535,7 @@
"alacritty": "Alacritty",
"kitty": "Kitty",
"ghostty": "Ghostty",
"wezterm": "WezTerm",
"kaku": "Kaku"
"wezterm": "WezTerm"
},
"windows": {
"cmd": "命令提示符",
+1 -1
View File
@@ -313,7 +313,7 @@ export interface Settings {
// ===== 终端设置 =====
// 首选终端应用(可选,默认使用系统默认终端)
// macOS: "terminal" | "iterm2" | "warp" | "alacritty" | "kitty" | "ghostty" | "wezterm" | "kaku"
// macOS: "terminal" | "iterm2" | "warp" | "alacritty" | "kitty" | "ghostty"
// Windows: "cmd" | "powershell" | "wt"
// Linux: "gnome-terminal" | "konsole" | "xfce4-terminal" | "alacritty" | "kitty" | "ghostty"
preferredTerminal?: string;