pub fn is_recoverable_tool_failure(tool_name: &str, error: Option<&str>) -> bool {
let Some(error) = error else {
return false;
};
let e = error.to_ascii_lowercase();
match tool_name {
"hashline_edit" => {
e.contains("not found")
|| e.contains("may have changed")
|| e.contains("hash")
|| e.contains("collision")
}
n if n.ends_with("_send") || n.ends_with("_connect") => {
e.contains("not connected") || e.contains("connect")
}
"follow_up_question" => {
e.contains("cancel")
|| e.contains("declin")
|| e.contains("timeout")
|| e.contains("timed out")
|| e.contains("no answer")
|| e.contains("no response")
}
"bash" => {
crate::brain::bash_failure::classify(error)
== crate::brain::bash_failure::BashFailureKind::Environmental
}
_ => false,
}
}