diff --git a/rust/crates/api/src/providers/anthropic.rs b/rust/crates/api/src/providers/anthropic.rs index 7c9f02945e..51e10b44dd 100644 --- a/rust/crates/api/src/providers/anthropic.rs +++ b/rust/crates/api/src/providers/anthropic.rs @@ -600,8 +600,9 @@ fn jitter_for_base(base: Duration) -> Duration { } let raw_nanos = SystemTime::now() .duration_since(UNIX_EPOCH) - .map(|elapsed| u64::try_from(elapsed.as_nanos()).unwrap_or(u64::MAX)) - .unwrap_or(0); + .map_or(0, |elapsed| { + u64::try_from(elapsed.as_nanos()).unwrap_or(u64::MAX) + }); let tick = JITTER_COUNTER.fetch_add(1, Ordering::Relaxed); // splitmix64 finalizer — mixes the low bits so large bases still see // jitter across their full range instead of being clamped to subsec nanos. @@ -844,19 +845,17 @@ impl MessageStream { StreamEvent::MessageDelta(MessageDeltaEvent { usage, .. }) => { self.latest_usage = Some(usage.clone()); } - StreamEvent::MessageStop(_) => { - if !self.usage_recorded { - if let (Some(prompt_cache), Some(usage)) = - (&self.prompt_cache, self.latest_usage.as_ref()) - { - let record = prompt_cache.record_usage(&self.request, usage); - *self - .last_prompt_cache_record - .lock() - .unwrap_or_else(std::sync::PoisonError::into_inner) = Some(record); - } - self.usage_recorded = true; + StreamEvent::MessageStop(_) if !self.usage_recorded => { + if let (Some(prompt_cache), Some(usage)) = + (&self.prompt_cache, self.latest_usage.as_ref()) + { + let record = prompt_cache.record_usage(&self.request, usage); + *self + .last_prompt_cache_record + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) = Some(record); } + self.usage_recorded = true; } _ => {} } diff --git a/rust/crates/api/src/providers/mod.rs b/rust/crates/api/src/providers/mod.rs index 9c50eb7aac..3fbc22e5f6 100644 --- a/rust/crates/api/src/providers/mod.rs +++ b/rust/crates/api/src/providers/mod.rs @@ -272,9 +272,7 @@ pub fn max_tokens_for_model(model: &str) -> u32 { 64_000 }; - model_token_limit(model) - .map(|limit| heuristic.min(limit.max_output_tokens)) - .unwrap_or(heuristic) + model_token_limit(model).map_or(heuristic, |limit| heuristic.min(limit.max_output_tokens)) } /// Returns the effective max output tokens for a model, preferring a plugin diff --git a/rust/crates/api/src/providers/openai_compat.rs b/rust/crates/api/src/providers/openai_compat.rs index b3800d6acf..0e3567183f 100644 --- a/rust/crates/api/src/providers/openai_compat.rs +++ b/rust/crates/api/src/providers/openai_compat.rs @@ -327,8 +327,9 @@ fn jitter_for_base(base: Duration) -> Duration { } let raw_nanos = SystemTime::now() .duration_since(UNIX_EPOCH) - .map(|elapsed| u64::try_from(elapsed.as_nanos()).unwrap_or(u64::MAX)) - .unwrap_or(0); + .map_or(0, |elapsed| { + u64::try_from(elapsed.as_nanos()).unwrap_or(u64::MAX) + }); let tick = JITTER_COUNTER.fetch_add(1, Ordering::Relaxed); let mut mixed = raw_nanos .wrapping_add(tick) @@ -855,7 +856,7 @@ pub fn is_reasoning_model(model: &str) -> bool { || canonical.contains("thinking") } -/// Returns true for OpenAI-compatible DeepSeek V4 models that require prior +/// Returns true for OpenAI-compatible `DeepSeek` V4 models that require prior /// assistant reasoning to be echoed back as `reasoning_content` in history. #[must_use] pub fn model_requires_reasoning_content_in_history(model: &str) -> bool { @@ -1083,8 +1084,7 @@ pub fn translate_message(message: &InputMessage, model: &str) -> Vec { } Some(msg) } - InputContentBlock::Thinking { .. } => None, - InputContentBlock::ToolUse { .. } => None, + InputContentBlock::Thinking { .. } | InputContentBlock::ToolUse { .. } => None, }) .collect(), } diff --git a/rust/crates/mock-anthropic-service/src/lib.rs b/rust/crates/mock-anthropic-service/src/lib.rs index 99623d18e9..68968eed2e 100644 --- a/rust/crates/mock-anthropic-service/src/lib.rs +++ b/rust/crates/mock-anthropic-service/src/lib.rs @@ -248,7 +248,6 @@ fn detect_scenario(request: &MessageRequest) -> Option { .split_whitespace() .find_map(|token| token.strip_prefix(SCENARIO_PREFIX)) .and_then(Scenario::parse), - InputContentBlock::Thinking { .. } => None, _ => None, }) }) diff --git a/rust/crates/runtime/src/compact.rs b/rust/crates/runtime/src/compact.rs index e4fd3db0d3..7b0f5f95ed 100644 --- a/rust/crates/runtime/src/compact.rs +++ b/rust/crates/runtime/src/compact.rs @@ -212,8 +212,7 @@ fn summarize_messages(messages: &[ConversationMessage]) -> String { .filter_map(|block| match block { ContentBlock::ToolUse { name, .. } => Some(name.as_str()), ContentBlock::ToolResult { tool_name, .. } => Some(tool_name.as_str()), - ContentBlock::Text { .. } => None, - ContentBlock::Thinking { .. } => None, + ContentBlock::Text { .. } | ContentBlock::Thinking { .. } => None, }) .collect::>(); tool_names.sort_unstable(); diff --git a/rust/crates/runtime/src/hooks.rs b/rust/crates/runtime/src/hooks.rs index 6abd69fbbd..a79c2d5d35 100644 --- a/rust/crates/runtime/src/hooks.rs +++ b/rust/crates/runtime/src/hooks.rs @@ -737,7 +737,7 @@ fn format_hook_failure(command: &str, code: i32, stdout: Option<&str>, stderr: & fn shell_command(command: &str) -> CommandWithStdin { #[cfg(windows)] - let mut command_builder = { + let command_builder = { let mut command_builder = Command::new("cmd"); command_builder.arg("/C").arg(command); CommandWithStdin::new(command_builder) diff --git a/rust/crates/runtime/src/sandbox.rs b/rust/crates/runtime/src/sandbox.rs index 45f118a9f6..b5fd1797b1 100644 --- a/rust/crates/runtime/src/sandbox.rs +++ b/rust/crates/runtime/src/sandbox.rs @@ -298,8 +298,7 @@ fn unshare_user_namespace_works() -> bool { .stdout(std::process::Stdio::null()) .stderr(std::process::Stdio::null()) .status() - .map(|s| s.success()) - .unwrap_or(false) + .is_ok_and(|s| s.success()) }) } diff --git a/rust/crates/rusty-claude-cli/src/main.rs b/rust/crates/rusty-claude-cli/src/main.rs index df4d8da452..eb807c9a94 100644 --- a/rust/crates/rusty-claude-cli/src/main.rs +++ b/rust/crates/rusty-claude-cli/src/main.rs @@ -67,12 +67,12 @@ const DEFAULT_MODEL: &str = "claude-opus-4-6"; enum ModelSource { /// Explicit `--model` / `--model=` CLI flag. Flag, - /// ANTHROPIC_MODEL environment variable (when no flag was passed). + /// `ANTHROPIC_MODEL` environment variable (when no flag was passed). Env, /// `model` key in `.claw.json` / `.claw/settings.json` (when neither /// flag nor env set it). Config, - /// Compiled-in DEFAULT_MODEL fallback. + /// Compiled-in `DEFAULT_MODEL` fallback. Default, } @@ -244,7 +244,7 @@ Run `claw --help` for usage." /// #77: Classify a stringified error message into a machine-readable kind. /// -/// Returns a snake_case token that downstream consumers can switch on instead +/// Returns a `snake_case` token that downstream consumers can switch on instead /// of regex-scraping the prose. The classification is best-effort prefix/keyword /// matching against the error messages produced throughout the CLI surface. fn classify_error_kind(message: &str) -> &'static str { @@ -278,9 +278,9 @@ fn classify_error_kind(message: &str) -> &'static str { } } -/// #77: Split a multi-line error message into (short_reason, optional_hint). +/// #77: Split a multi-line error message into (`short_reason`, `optional_hint`). /// -/// The short_reason is the first line (up to the first newline), and the hint +/// The `short_reason` is the first line (up to the first newline), and the hint /// is the remaining text or `None` if there's no newline. This prevents the /// runbook prose from being stuffed into the `error` field that downstream /// parsers expect to be the short reason alone. @@ -940,9 +940,9 @@ fn parse_args(args: &[String]) -> Result { // only intercepts the bare single-word form. Catch all multi-word // forms here and return a structured guidance error so no network // call or session is created. - "permissions" => Err(format!( - "`claw permissions` is a slash command. Start `claw` and run `/permissions` inside the REPL.\n Usage /permissions [read-only|workspace-write|danger-full-access]" - )), + "permissions" => Err( + "`claw permissions` is a slash command. Start `claw` and run `/permissions` inside the REPL.\n Usage /permissions [read-only|workspace-write|danger-full-access]".to_string() + ), "skills" => { let args = join_optional_args(&rest[1..]); match classify_skills_slash_command(args.as_deref()) { @@ -3560,7 +3560,7 @@ fn run_resume_command( message: Some(handle_agents_slash_command(args.as_deref(), &cwd)?), json: Some( serde_json::to_value(handle_agents_slash_command_json(args.as_deref(), &cwd)?) - .unwrap_or_else(|_| serde_json::json!(null)), + .unwrap_or(serde_json::Value::Null), ), }) } @@ -3579,14 +3579,12 @@ fn run_resume_command( } SlashCommand::Plugins { action, target } => { // Only list is supported in resume mode (no runtime to reload) - match action.as_deref() { - Some("install") | Some("uninstall") | Some("enable") | Some("disable") - | Some("update") => { - return Err( - "resumed /plugins mutations are interactive-only; start `claw` and run `/plugins` in the REPL".into(), - ); - } - _ => {} + if let Some("install" | "uninstall" | "enable" | "disable" | "update") = + action.as_deref() + { + return Err( + "resumed /plugins mutations are interactive-only; start `claw` and run `/plugins` in the REPL".into(), + ); } let cwd = env::current_dir()?; let loader = ConfigLoader::default_for(&cwd); @@ -5136,7 +5134,7 @@ impl LiveCli { // Propagate ok:false → non-zero exit so automation callers // can rely on exit code instead of inspecting the envelope. // (#68: mcp error envelopes previously always exited 0.) - let is_error = value.get("ok").and_then(|v| v.as_bool()) == Some(false); + let is_error = value.get("ok").and_then(serde_json::Value::as_bool) == Some(false); println!("{}", serde_json::to_string_pretty(&value)?); if is_error { std::process::exit(1); @@ -6563,8 +6561,7 @@ fn render_diff_report_for(cwd: &Path) -> Result Result bool { Command::new("which") .arg(name) .output() - .map(|output| output.status.success()) - .unwrap_or(false) + .is_ok_and(|output| output.status.success()) } fn write_temp_text_file( diff --git a/rust/crates/tools/src/lib.rs b/rust/crates/tools/src/lib.rs index eb4a3905ee..e32e422881 100644 --- a/rust/crates/tools/src/lib.rs +++ b/rust/crates/tools/src/lib.rs @@ -1996,8 +1996,7 @@ fn git_ref_exists(reference: &str) -> bool { Command::new("git") .args(["rev-parse", "--verify", "--quiet", reference]) .output() - .map(|output| output.status.success()) - .unwrap_or(false) + .is_ok_and(|output| output.status.success()) } fn git_stdout(args: &[&str]) -> Option { @@ -4691,7 +4690,10 @@ async fn stream_with_provider( }, ApiStreamEvent::ContentBlockStop(stop) => { if let Some((thinking, signature)) = pending_thinking.remove(&stop.index) { - events.push(AssistantEvent::Thinking { thinking, signature }); + events.push(AssistantEvent::Thinking { + thinking, + signature, + }); } if let Some((id, name, input)) = pending_tools.remove(&stop.index) { events.push(AssistantEvent::ToolUse { id, name, input }); @@ -4859,7 +4861,10 @@ fn push_output_block( if streaming_tool_input { pending_thinking.insert(block_index, (thinking, signature)); } else { - events.push(AssistantEvent::Thinking { thinking, signature }); + events.push(AssistantEvent::Thinking { + thinking, + signature, + }); } } OutputContentBlock::RedactedThinking { .. } => {} @@ -5983,8 +5988,7 @@ fn command_exists(command: &str) -> bool { .arg("-lc") .arg(format!("command -v {command} >/dev/null 2>&1")) .status() - .map(|status| status.success()) - .unwrap_or(false) + .is_ok_and(|status| status.success()) } #[allow(clippy::too_many_lines)]