mirror of
https://github.com/block/goose.git
synced 2026-07-17 12:56:20 +02:00
Interrupt running shell tool commands (#365)
This commit is contained in:
@@ -22,8 +22,10 @@ use std::{
|
||||
convert::Infallible,
|
||||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
time::Duration,
|
||||
};
|
||||
use tokio::sync::mpsc;
|
||||
use tokio::time::timeout;
|
||||
use tokio_stream::wrappers::ReceiverStream;
|
||||
|
||||
// Types matching the incoming JSON structure
|
||||
@@ -293,18 +295,31 @@ async fn handler(
|
||||
}
|
||||
};
|
||||
|
||||
while let Some(response) = stream.next().await {
|
||||
match response {
|
||||
Ok(message) => {
|
||||
if let Err(e) = stream_message(message, &tx).await {
|
||||
tracing::error!("Error sending message through channel: {}", e);
|
||||
break;
|
||||
loop {
|
||||
tokio::select! {
|
||||
response = timeout(Duration::from_millis(500), stream.next()) => {
|
||||
match response {
|
||||
Ok(Some(Ok(message))) => {
|
||||
if let Err(e) = stream_message(message, &tx).await {
|
||||
tracing::error!("Error sending message through channel: {}", e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Ok(Some(Err(e))) => {
|
||||
tracing::error!("Error processing message: {}", e);
|
||||
break;
|
||||
}
|
||||
Ok(None) => {
|
||||
break;
|
||||
}
|
||||
Err(_) => { // Heartbeat, used to detect disconnected clients and then end running tools.
|
||||
if tx.is_closed() {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("Error processing message: {}", e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@ use serde_json::{json, Value};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::io::Cursor;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
use std::sync::Mutex;
|
||||
use tokio::process::Command;
|
||||
use xcap::Monitor;
|
||||
|
||||
use crate::errors::{AgentError, AgentResult};
|
||||
@@ -192,9 +192,11 @@ impl DeveloperSystem {
|
||||
|
||||
// Execute the command
|
||||
let output = Command::new("bash")
|
||||
.kill_on_drop(true) // Critical so that the command is killed when the agent.reply stream is interrupted.
|
||||
.arg("-c")
|
||||
.arg(cmd_with_redirect)
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| AgentError::ExecutionError(e.to_string()))?;
|
||||
|
||||
let output_str = format!(
|
||||
|
||||
Reference in New Issue
Block a user