Handle waiting for tool confirmation in UI

Agus Zubiaga created

Change summary

crates/acp/src/acp.rs         | 17 +++++++++++++++++
crates/acp/src/thread_view.rs | 24 +++++++++++++-----------
2 files changed, 30 insertions(+), 11 deletions(-)

Detailed changes

crates/acp/src/acp.rs 🔗

@@ -335,6 +335,23 @@ impl AcpThread {
         entry
     }
 
+    /// Returns true if the last turn is awaiting tool authorization
+    pub fn waiting_for_tool_confirmation(&self) -> bool {
+        for entry in self.entries.iter().rev() {
+            match &entry.content {
+                AgentThreadEntryContent::ToolCall(call) => match call.status {
+                    ToolCallStatus::WaitingForConfirmation { .. } => return true,
+                    ToolCallStatus::Allowed | ToolCallStatus::Rejected => continue,
+                },
+                AgentThreadEntryContent::Message(_) => {
+                    // Reached the beginning of the turn
+                    return false;
+                }
+            }
+        }
+        false
+    }
+
     pub fn send(&mut self, message: &str, cx: &mut Context<Self>) -> Task<Result<()>> {
         let agent = self.server.clone();
         let id = self.id.clone();

crates/acp/src/thread_view.rs 🔗

@@ -368,7 +368,7 @@ impl Render for AcpThreadView {
                     .flex_1()
                     .justify_end()
                     .child(Label::new(format!("Failed to load {e}")).into_any_element()),
-                ThreadState::Ready { .. } => v_flex()
+                ThreadState::Ready { thread, .. } => v_flex()
                     .flex_1()
                     .gap_2()
                     .pb_2()
@@ -377,16 +377,18 @@ impl Render for AcpThreadView {
                             .with_sizing_behavior(gpui::ListSizingBehavior::Auto)
                             .flex_grow(),
                     )
-                    .child(
-                        div()
-                            .px_3()
-                            .child(
-                                Label::new("Generating...")
-                                    .color(Color::Muted)
-                                    .size(LabelSize::Small),
-                            )
-                            .when(self.send_task.is_none(), |this| this.invisible()),
-                    ),
+                    .child(div().px_3().children(if self.send_task.is_none() {
+                        None
+                    } else {
+                        Label::new(if thread.read(cx).waiting_for_tool_confirmation() {
+                            "Waiting for tool confirmation"
+                        } else {
+                            "Generating..."
+                        })
+                        .color(Color::Muted)
+                        .size(LabelSize::Small)
+                        .into()
+                    })),
             })
             .child(
                 v_flex()