diff --git a/Cargo.lock b/Cargo.lock index e5b8db8..621d189 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2953,6 +2953,7 @@ dependencies = [ "tiktoken-rs", "tokio", "tokio-rustls", + "tokio-scoped", "tokio-util", "toml", "tracing", @@ -4371,6 +4372,16 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-scoped" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4beb8ba13bc53ac53ce1d52b42f02e5d8060f0f42138862869beb769722b256" +dependencies = [ + "tokio", + "tokio-stream", +] + [[package]] name = "tokio-stream" version = "0.1.18" diff --git a/Cargo.toml b/Cargo.toml index d0be3ac..44a8196 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -65,6 +65,7 @@ webpki-roots = "1" tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } tracing-appender = "0.2" +tokio-scoped = "0.2.0" [build-dependencies] capnpc = "0.20" diff --git a/src/user/event_loop.rs b/src/user/event_loop.rs index 50b8e65..476d75b 100644 --- a/src/user/event_loop.rs +++ b/src/user/event_loop.rs @@ -31,22 +31,28 @@ pub async fn start(cli: crate::user::CliArgs) -> Result<()> { let (mind_tx, mind_rx) = tokio::sync::mpsc::unbounded_channel(); let mind = crate::mind::Mind::new(config, ui_tx.clone(), turn_tx); - mind.init().await; - let ui_agent = mind.agent.clone(); - let shared_mind = mind.shared.clone(); let shared_context = mind.agent.lock().await.shared_context.clone(); let shared_active_tools = mind.agent.lock().await.active_tools.clone(); let turn_watch = mind.turn_watch(); - tokio::spawn(async move { - mind.run(mind_rx, turn_rx).await; - }); + let mut result = Ok(()); + tokio_scoped::scope(|s| { + // Mind event loop — init + run + s.spawn(async { + mind.init().await; + mind.run(mind_rx, turn_rx).await; + }); - run( - tui::App::new(String::new(), shared_context, shared_active_tools), - ui_agent, shared_mind, turn_watch, mind_tx, ui_tx, ui_rx, - ).await + // UI event loop + s.spawn(async { + result = run( + tui::App::new(String::new(), shared_context, shared_active_tools), + &mind.agent, &mind.shared, turn_watch, mind_tx, ui_tx, ui_rx, + ).await; + }); + }); + result } fn send_help(ui_tx: &ui_channel::UiSender) { @@ -210,8 +216,8 @@ pub async fn cmd_switch_model( pub async fn run( mut app: tui::App, - agent: Arc>, - shared_mind: crate::mind::SharedMindState, + agent: &Arc>, + shared_mind: &crate::mind::SharedMindState, turn_watch: tokio::sync::watch::Receiver, mind_tx: tokio::sync::mpsc::UnboundedSender, ui_tx: ui_channel::UiSender,