use mecha_core::agent::{Agent, AgentEvent, Conversation, RunContext, RunOutcome};
use tokio::sync::mpsc::UnboundedSender;
use tokio_util::sync::CancellationToken;
pub async fn run_interruptible(
agent: &Agent,
cx: &RunContext,
convo: &mut Conversation,
events: Option<UnboundedSender<AgentEvent>>,
) -> anyhow::Result<RunOutcome> {
let token = CancellationToken::new();
let cx = cx.clone().with_cancel(token.clone());
let watcher = {
let token = token.clone();
tokio::spawn(async move {
tokio::select! {
signal = tokio::signal::ctrl_c() => {
if signal.is_ok() {
eprintln!("\n^C — stopping after the current step. Ctrl-C again to force.");
token.cancel();
}
}
_ = token.cancelled() => {}
}
})
};
let result = agent.run_in(&cx, convo, events).await;
token.cancel();
let _ = watcher.await;
result
}