diff --git a/rust/crates/runtime/src/conversation.rs b/rust/crates/runtime/src/conversation.rs index 99cce82..1dde559 100644 --- a/rust/crates/runtime/src/conversation.rs +++ b/rust/crates/runtime/src/conversation.rs @@ -504,6 +504,10 @@ where &self.session } + pub fn api_client_mut(&mut self) -> &mut C { + &mut self.api_client + } + pub fn session_mut(&mut self) -> &mut Session { &mut self.session } diff --git a/rust/crates/rusty-claude-cli/src/main.rs b/rust/crates/rusty-claude-cli/src/main.rs index e5c018e..ea3e902 100644 --- a/rust/crates/rusty-claude-cli/src/main.rs +++ b/rust/crates/rusty-claude-cli/src/main.rs @@ -209,7 +209,7 @@ fn run() -> Result<(), Box> { permission_mode, compact, base_commit, - .. + reasoning_effort, } => { run_stale_base_preflight(base_commit.as_deref()); // Only consume piped stdin as prompt context when the permission @@ -223,11 +223,9 @@ fn run() -> Result<(), Box> { None }; let effective_prompt = merge_prompt_with_stdin(&prompt, stdin_context.as_deref()); - LiveCli::new(model, true, allowed_tools, permission_mode)?.run_turn_with_output( - &effective_prompt, - output_format, - compact, - )?; + let mut cli = LiveCli::new(model, true, allowed_tools, permission_mode)?; + cli.set_reasoning_effort(reasoning_effort); + cli.run_turn_with_output(&effective_prompt, output_format, compact)?; } CliAction::Login { output_format } => run_login(output_format)?, CliAction::Logout { output_format } => run_logout(output_format)?, @@ -244,8 +242,14 @@ fn run() -> Result<(), Box> { allowed_tools, permission_mode, base_commit, - .. - } => run_repl(model, allowed_tools, permission_mode, base_commit)?, + reasoning_effort, + } => run_repl( + model, + allowed_tools, + permission_mode, + base_commit, + reasoning_effort, + )?, CliAction::HelpTopic(topic) => print_help_topic(topic), CliAction::Help { output_format } => print_help(output_format)?, } @@ -377,6 +381,7 @@ fn parse_args(args: &[String]) -> Result { let mut allowed_tool_values = Vec::new(); let mut compact = false; let mut base_commit: Option = None; + let mut reasoning_effort: Option = None; let mut rest = Vec::new(); let mut index = 0; @@ -442,6 +447,17 @@ fn parse_args(args: &[String]) -> Result { base_commit = Some(flag[14..].to_string()); index += 1; } + "--reasoning-effort" => { + let value = args + .get(index + 1) + .ok_or_else(|| "missing value for --reasoning-effort".to_string())?; + reasoning_effort = Some(value.clone()); + index += 2; + } + flag if flag.starts_with("--reasoning-effort=") => { + reasoning_effort = Some(flag[19..].to_string()); + index += 1; + } "-p" => { // Claw Code compat: -p "prompt" = one-shot prompt let prompt = args[index + 1..].join(" "); @@ -457,7 +473,7 @@ fn parse_args(args: &[String]) -> Result { .unwrap_or_else(default_permission_mode), compact, base_commit: base_commit.clone(), - reasoning_effort: None, + reasoning_effort: reasoning_effort.clone(), }); } "--print" => { @@ -516,7 +532,7 @@ fn parse_args(args: &[String]) -> Result { allowed_tools, permission_mode, base_commit, - reasoning_effort: None, + reasoning_effort: reasoning_effort.clone(), }); } if rest.first().map(String::as_str) == Some("--resume") { @@ -555,7 +571,7 @@ fn parse_args(args: &[String]) -> Result { permission_mode, compact, base_commit, - reasoning_effort: None, + reasoning_effort: reasoning_effort.clone(), }), SkillSlashDispatch::Local => Ok(CliAction::Skills { args, @@ -581,7 +597,7 @@ fn parse_args(args: &[String]) -> Result { permission_mode, compact, base_commit: base_commit.clone(), - reasoning_effort: None, + reasoning_effort: reasoning_effort.clone(), }) } other if other.starts_with('/') => parse_direct_slash_cli_action( @@ -592,6 +608,7 @@ fn parse_args(args: &[String]) -> Result { permission_mode, compact, base_commit, + reasoning_effort, ), _other => Ok(CliAction::Prompt { prompt: rest.join(" "), @@ -601,7 +618,7 @@ fn parse_args(args: &[String]) -> Result { permission_mode, compact, base_commit, - reasoning_effort: None, + reasoning_effort: reasoning_effort.clone(), }), } } @@ -695,6 +712,7 @@ fn parse_direct_slash_cli_action( permission_mode: PermissionMode, compact: bool, base_commit: Option, + reasoning_effort: Option, ) -> Result { let raw = rest.join(" "); match SlashCommand::parse(&raw) { @@ -722,7 +740,7 @@ fn parse_direct_slash_cli_action( permission_mode, compact, base_commit, - reasoning_effort: None, + reasoning_effort: reasoning_effort.clone(), }), SkillSlashDispatch::Local => Ok(CliAction::Skills { args, @@ -2772,10 +2790,12 @@ fn run_repl( allowed_tools: Option, permission_mode: PermissionMode, base_commit: Option, + reasoning_effort: Option, ) -> Result<(), Box> { run_stale_base_preflight(base_commit.as_deref()); let resolved_model = resolve_repl_model(model); let mut cli = LiveCli::new(resolved_model, true, allowed_tools, permission_mode)?; + cli.set_reasoning_effort(reasoning_effort); let mut editor = input::LineEditor::new("> ", cli.repl_completion_candidates().unwrap_or_default()); println!("{}", cli.startup_banner()); @@ -3358,6 +3378,12 @@ impl LiveCli { Ok(cli) } + fn set_reasoning_effort(&mut self, effort: Option) { + if let Some(rt) = self.runtime.runtime.as_mut() { + rt.api_client_mut().set_reasoning_effort(effort); + } + } + fn startup_banner(&self) -> String { let cwd = env::current_dir().map_or_else( |_| "".to_string(), @@ -6380,6 +6406,7 @@ struct AnthropicRuntimeClient { allowed_tools: Option, tool_registry: GlobalToolRegistry, progress_reporter: Option, + reasoning_effort: Option, } impl AnthropicRuntimeClient { @@ -6444,8 +6471,13 @@ impl AnthropicRuntimeClient { allowed_tools, tool_registry, progress_reporter, + reasoning_effort: None, }) } + + fn set_reasoning_effort(&mut self, effort: Option) { + self.reasoning_effort = effort; + } } fn resolve_cli_auth_source() -> Result> { @@ -6491,6 +6523,7 @@ impl ApiClient for AnthropicRuntimeClient { .then(|| filter_tool_specs(&self.tool_registry, self.allowed_tools.as_ref())), tool_choice: self.enable_tools.then_some(ToolChoice::Auto), stream: true, + reasoning_effort: self.reasoning_effort.clone(), ..Default::default() };