diff --git a/assets/functions/utils/prompt-utils.sh b/assets/functions/utils/prompt-utils.sh index 14badfd..68e1a42 100755 --- a/assets/functions/utils/prompt-utils.sh +++ b/assets/functions/utils/prompt-utils.sh @@ -506,16 +506,14 @@ open_link() { } guard_operation() { - if [[ -t 1 ]]; then - if [[ -z "$AUTO_CONFIRM" && -z "$LLM_AGENT_VAR_AUTO_CONFIRM" ]]; then - ans="$(confirm "${1:-Are you sure you want to continue?}")" + if [[ -z "$AUTO_CONFIRM" && -z "$LLM_AGENT_VAR_AUTO_CONFIRM" ]]; then + ans="$(confirm "${1:-Are you sure you want to continue?}")" - if [[ "$ans" == 0 ]]; then - error "Operation aborted!" 2>&1 - exit 1 - fi + if [[ "$ans" == 0 ]]; then + error "Operation aborted!" 2>&1 + exit 1 fi - fi + fi } # Here is an example of a patch block that can be applied to modify the file to request the user's name: @@ -655,19 +653,17 @@ guard_path() { exit 1 fi - if [[ -t 1 ]]; then - path="$(_to_real_path "$1")" - confirmation_prompt="$2" + path="$(_to_real_path "$1")" + confirmation_prompt="$2" - if [[ ! "$path" == "$(pwd)"* && -z "$AUTO_CONFIRM" && -z "$LLM_AGENT_VAR_AUTO_CONFIRM" ]]; then - ans="$(confirm "$confirmation_prompt")" + if [[ ! "$path" == "$(pwd)"* && -z "$AUTO_CONFIRM" && -z "$LLM_AGENT_VAR_AUTO_CONFIRM" ]]; then + ans="$(confirm "$confirmation_prompt")" - if [[ "$ans" == 0 ]]; then - error "Operation aborted!" >&2 - exit 1 - fi - fi - fi + if [[ "$ans" == 0 ]]; then + error "Operation aborted!" >&2 + exit 1 + fi + fi } _to_real_path() { diff --git a/src/function/mod.rs b/src/function/mod.rs index 0a7d5ef..517745d 100644 --- a/src/function/mod.rs +++ b/src/function/mod.rs @@ -4,6 +4,7 @@ pub(crate) mod user_interaction; use crate::{ config::{Agent, RequestContext}, + graph, utils::*, }; @@ -1199,6 +1200,9 @@ pub fn run_llm_function( if dir.exists() { bin_dirs.push(dir); } + if graph::agent_has_graph(&agent_name) { + envs.insert("AUTO_CONFIRM".into(), "true".into()); + } } else { bin_dirs.push(paths::functions_bin_dir()); } @@ -1242,7 +1246,7 @@ pub fn run_llm_function( .map_err(|err| anyhow!("Unable to run {command_name}, {err}"))?; let stdout = child.stdout.take().expect("Failed to capture stdout"); - let mut stderr = child.stderr.take().expect("Failed to capture stderr"); + let stderr = child.stderr.take().expect("Failed to capture stderr"); let stdout_thread = std::thread::spawn(move || { let mut buffer = [0; 1024]; @@ -1269,8 +1273,29 @@ pub fn run_llm_function( }); let stderr_thread = std::thread::spawn(move || { + let mut buffer = [0; 1024]; + let mut reader = stderr; + let mut err = io::stderr(); let mut buf = Vec::new(); - let _ = stderr.read_to_end(&mut buf); + while let Ok(n) = reader.read(&mut buffer) { + if n == 0 { + break; + } + let chunk = &buffer[0..n]; + buf.extend_from_slice(chunk); + let mut last_pos = 0; + for (i, &byte) in chunk.iter().enumerate() { + if byte == b'\n' { + let _ = err.write_all(&chunk[last_pos..i]); + let _ = err.write_all(b"\r\n"); + last_pos = i + 1; + } + } + if last_pos < n { + let _ = err.write_all(&chunk[last_pos..n]); + } + let _ = err.flush(); + } buf }); @@ -1283,9 +1308,6 @@ pub fn run_llm_function( let exit_code = status.code().unwrap_or_default(); if exit_code != 0 { let stderr = String::from_utf8_lossy(&stderr_bytes).trim().to_string(); - if !stderr.is_empty() { - eprintln!("{stderr}"); - } let tool_error_message = format!("Tool call '{command_name}' exited with code {exit_code}"); eprintln!("{}", warning_text(&format!("⚠️ {tool_error_message} ⚠️"))); let mut error_json = json!({"tool_call_error": tool_error_message}); diff --git a/src/graph/script.rs b/src/graph/script.rs index c7541d1..fd30d1e 100644 --- a/src/graph/script.rs +++ b/src/graph/script.rs @@ -55,6 +55,7 @@ impl ScriptExecutor { cmd.stdout(Stdio::piped()); cmd.stderr(Stdio::piped()); cmd.envs(&self.extra_envs); + cmd.env("AUTO_CONFIRM", "true"); match &state_repr { StateRepresentation::Inline(json) => { cmd.env("GRAPH_STATE", json);