From c340c44e6c85fc338663cbb90c86fda22ceb9951 Mon Sep 17 00:00:00 2001 From: Ben Brandt Date: Thu, 2 Apr 2026 17:10:02 +0200 Subject: [PATCH] more cleanup --- crates/acp_tools/src/acp_tools.rs | 12 +++- crates/agent_servers/src/acp.rs | 97 ++++++++++++++++--------------- 2 files changed, 61 insertions(+), 48 deletions(-) diff --git a/crates/acp_tools/src/acp_tools.rs b/crates/acp_tools/src/acp_tools.rs index 4876456fcbcecc1acc9f846058782c3445e690a0..94d8cff0c8d4d30db29babb31d84dfcffca9b82b 100644 --- a/crates/acp_tools/src/acp_tools.rs +++ b/crates/acp_tools/src/acp_tools.rs @@ -71,7 +71,7 @@ impl StreamMessage { let acp_err = serde_json::from_value::(error.clone()).unwrap_or_else(|err| { log::warn!("Failed to deserialize ACP error: {err}"); - acp::Error::internal_error() + acp::Error::internal_error().data(error.to_string()) }); StreamMessageContent::Response { id: id.clone(), @@ -165,6 +165,15 @@ impl AcpConnectionRegistry { }) .ok(); } + + // The transport closed — clear state so observers (e.g. the ACP + // logs tab) can transition back to the disconnected state. + this.update(cx, |this, cx| { + this.active_agent_id = None; + this.subscribers.clear(); + cx.notify(); + }) + .ok(); })); cx.notify(); @@ -224,6 +233,7 @@ impl AcpTools { }; let Some(agent_id) = agent_id else { + self.watched_connection = None; return; }; diff --git a/crates/agent_servers/src/acp.rs b/crates/agent_servers/src/acp.rs index 830d74546eeed064a72c828984c000adb8aabbe7..7fc6855d19a8f4ab4da8ff7448210cbd7539a0b9 100644 --- a/crates/agent_servers/src/acp.rs +++ b/crates/agent_servers/src/acp.rs @@ -229,17 +229,14 @@ macro_rules! dispatch_request_handler { ($dispatch_tx:expr, $handler:expr) => {{ let dispatch_tx = $dispatch_tx.clone(); async move |args, responder, _connection| { - if dispatch_tx.is_closed() { + if let Err(_) = dispatch_tx.unbounded_send(Box::new(move |cx, ctx| { + $handler(args, responder, cx, ctx); + })) { + // The dispatch channel is closed — the AcpConnection is being + // torn down and the child process is being killed. The responder + // inside the work item drops without responding; the agent won't + // be around to notice since the transport is also closing. log::error!("dispatch channel closed, cannot handle request"); - responder - .respond_with_error(acp::Error::internal_error()) - .log_err(); - } else { - dispatch_tx - .unbounded_send(Box::new(move |cx, ctx| { - $handler(args, responder, cx, ctx); - })) - .log_err(); } Ok(()) } @@ -1835,28 +1832,30 @@ fn handle_session_notification( .get("cwd") .and_then(|v| v.as_str().map(PathBuf::from)); - let _ = thread.update(cx, |thread, cx| { - let builder = TerminalBuilder::new_display_only( - CursorShape::default(), - AlternateScroll::On, - None, - 0, - cx.background_executor(), - thread.project().read(cx).path_style(cx), - )?; - let lower = cx.new(|cx| builder.subscribe(cx)); - thread.on_terminal_provider_event( - TerminalProviderEvent::Created { - terminal_id, - label: tc.title.clone(), - cwd, - output_byte_limit: None, - terminal: lower, - }, - cx, - ); - anyhow::Ok(()) - }); + thread + .update(cx, |thread, cx| { + let builder = TerminalBuilder::new_display_only( + CursorShape::default(), + AlternateScroll::On, + None, + 0, + cx.background_executor(), + thread.project().read(cx).path_style(cx), + )?; + let lower = cx.new(|cx| builder.subscribe(cx)); + thread.on_terminal_provider_event( + TerminalProviderEvent::Created { + terminal_id, + label: tc.title.clone(), + cwd, + output_byte_limit: None, + terminal: lower, + }, + cx, + ); + anyhow::Ok(()) + }) + .log_err(); } } } @@ -1883,12 +1882,14 @@ fn handle_session_notification( let terminal_id = acp::TerminalId::new(id_str); if let Some(s) = term_out.get("data").and_then(|v| v.as_str()) { let data = s.as_bytes().to_vec(); - let _ = thread.update(cx, |thread, cx| { - thread.on_terminal_provider_event( - TerminalProviderEvent::Output { terminal_id, data }, - cx, - ); - }); + thread + .update(cx, |thread, cx| { + thread.on_terminal_provider_event( + TerminalProviderEvent::Output { terminal_id, data }, + cx, + ); + }) + .log_err(); } } } @@ -1909,15 +1910,17 @@ fn handle_session_notification( .and_then(|v| v.as_str().map(|s| s.to_string())), ); - let _ = thread.update(cx, |thread, cx| { - thread.on_terminal_provider_event( - TerminalProviderEvent::Exit { - terminal_id, - status, - }, - cx, - ); - }); + thread + .update(cx, |thread, cx| { + thread.on_terminal_provider_event( + TerminalProviderEvent::Exit { + terminal_id, + status, + }, + cx, + ); + }) + .log_err(); } } }