agent investigation

Lukas Wirth created

Change summary

crates/acp_thread/src/acp_thread.rs                  |  4 +
crates/agent_ui/src/conversation_view.rs             |  3 +
crates/agent_ui/src/conversation_view/thread_view.rs | 32 ++++++++++++++
3 files changed, 39 insertions(+)

Detailed changes

crates/acp_thread/src/acp_thread.rs 🔗

@@ -2367,6 +2367,10 @@ impl AcpThread {
                             });
                         }
                     }
+
+                    // Release buffer handles that were tracked during the
+                    // rewound portion so they don't keep buffers alive.
+                    this.shared_buffers.clear();
                 }
                 this.action_log().update(cx, |action_log, cx| {
                     action_log.reject_all_edits(Some(telemetry), cx)

crates/agent_ui/src/conversation_view.rs 🔗

@@ -1234,6 +1234,9 @@ impl ConversationView {
                     let list_state = active.read(cx).list_state.clone();
                     entry_view_state.update(cx, |view_state, _cx| view_state.remove(range.clone()));
                     list_state.splice(range.clone(), 0);
+                    active.update(cx, |thread_view, cx| {
+                        thread_view.on_entries_removed(range, cx);
+                    });
                 }
             }
             AcpThreadEvent::SubagentSpawned(session_id) => self.load_subagent_session(

crates/agent_ui/src/conversation_view/thread_view.rs 🔗

@@ -1,5 +1,6 @@
 use crate::{DEFAULT_THREAD_TITLE, SelectPermissionGranularity};
 use std::cell::RefCell;
+use std::ops::Range;
 
 use acp_thread::ContentBlock;
 use cloud_api_types::{SubmitAgentThreadFeedbackBody, SubmitAgentThreadFeedbackCommentsBody};
@@ -733,6 +734,37 @@ impl ThreadView {
         }
     }
 
+    pub fn on_entries_removed(&mut self, range: &Range<usize>, cx: &mut Context<Self>) {
+        let entries = self.thread.read(cx).entries();
+        let valid_tool_call_ids: HashSet<_> = entries
+            .iter()
+            .filter_map(|entry| {
+                if let AgentThreadEntry::ToolCall(tool_call) = entry {
+                    Some(&tool_call.id)
+                } else {
+                    None
+                }
+            })
+            .collect();
+        let entry_count = entries.len();
+
+        self.expanded_tool_calls
+            .retain(|id| valid_tool_call_ids.contains(id));
+        self.expanded_tool_call_raw_inputs
+            .retain(|id| valid_tool_call_ids.contains(id));
+        self.expanded_thinking_blocks
+            .retain(|&(entry_index, _)| entry_index < entry_count);
+        if let Some((entry_index, _)) = self.auto_expanded_thinking_block {
+            if range.contains(&entry_index) || entry_index >= range.start {
+                self.auto_expanded_thinking_block = None;
+            }
+        }
+        self.discarded_partial_edits
+            .retain(|id| valid_tool_call_ids.contains(id));
+        self.permission_selections
+            .retain(|id, _| valid_tool_call_ids.contains(id));
+    }
+
     fn open_diff_location(
         &self,
         path: &str,