From 603e6d6742ef0c9e5f9ea98af9aaae0e6d1b3311 Mon Sep 17 00:00:00 2001 From: Ben Brandt Date: Mon, 16 Mar 2026 13:13:23 +0100 Subject: [PATCH] agent_ui: Disable editing and regeneration for subagent messages (#51654) We had inconsistent handling of this read-only behavior. Now subagents should behave the same as agents that don't support editing Release Notes: - agent_ui: Fix inconsistent behavior for subagent views when focusing on previous messages. --- .../src/connection_view/thread_view.rs | 100 ++++++++---------- 1 file changed, 46 insertions(+), 54 deletions(-) diff --git a/crates/agent_ui/src/connection_view/thread_view.rs b/crates/agent_ui/src/connection_view/thread_view.rs index eed8de86c841350d507b040287088989ae23c023..c5e44a582cefba92161760711ebd5ba6bf0d1936 100644 --- a/crates/agent_ui/src/connection_view/thread_view.rs +++ b/crates/agent_ui/src/connection_view/thread_view.rs @@ -630,6 +630,7 @@ impl ThreadView { if let Some(AgentThreadEntry::UserMessage(user_message)) = self.thread.read(cx).entries().get(event.entry_index) && user_message.id.is_some() + && !self.is_subagent() { self.editing_message = Some(event.entry_index); cx.notify(); @@ -639,6 +640,7 @@ impl ThreadView { if let Some(AgentThreadEntry::UserMessage(user_message)) = self.thread.read(cx).entries().get(event.entry_index) && user_message.id.is_some() + && !self.is_subagent() { if editor.read(cx).text(cx).as_str() == user_message.content.to_markdown(cx) { self.editing_message = None; @@ -648,7 +650,9 @@ impl ThreadView { } ViewEvent::MessageEditorEvent(_editor, MessageEditorEvent::SendImmediately) => {} ViewEvent::MessageEditorEvent(editor, MessageEditorEvent::Send) => { - self.regenerate(event.entry_index, editor.clone(), window, cx); + if !self.is_subagent() { + self.regenerate(event.entry_index, editor.clone(), window, cx); + } } ViewEvent::MessageEditorEvent(_editor, MessageEditorEvent::Cancel) => { self.cancel_editing(&Default::default(), window, cx); @@ -3792,14 +3796,12 @@ impl ThreadView { .as_ref() .is_some_and(|checkpoint| checkpoint.show); - let agent_name = self.agent_name.clone(); let is_subagent = self.is_subagent(); - - let non_editable_icon = || { - IconButton::new("non_editable", IconName::PencilUnavailable) - .icon_size(IconSize::Small) - .icon_color(Color::Muted) - .style(ButtonStyle::Transparent) + let is_editable = message.id.is_some() && !is_subagent; + let agent_name = if is_subagent { + "subagents".into() + } else { + self.agent_name.clone() }; v_flex() @@ -3820,8 +3822,8 @@ impl ThreadView { .gap_1p5() .w_full() .children(rules_item) - .children(message.id.clone().and_then(|message_id| { - message.checkpoint.as_ref()?.show.then(|| { + .when(is_editable && has_checkpoint_button, |this| { + this.children(message.id.clone().map(|message_id| { h_flex() .px_3() .gap_2() @@ -3837,8 +3839,8 @@ impl ThreadView { })) ) .child(Divider::horizontal()) - }) - })) + })) + }) .child( div() .relative() @@ -3854,8 +3856,11 @@ impl ThreadView { }) .border_color(cx.theme().colors().border) .map(|this| { - if is_subagent { - return this.border_dashed(); + if !is_editable { + if is_subagent { + return this.border_dashed(); + } + return this; } if editing && editor_focus { return this.border_color(focus_border); @@ -3863,12 +3868,9 @@ impl ThreadView { if editing && !editor_focus { return this.border_dashed() } - if message.id.is_some() { - return this.shadow_md().hover(|s| { - s.border_color(focus_border.opacity(0.8)) - }); - } - this + this.shadow_md().hover(|s| { + s.border_color(focus_border.opacity(0.8)) + }) }) .text_xs() .child(editor.clone().into_any_element()) @@ -3886,20 +3888,7 @@ impl ThreadView { .overflow_hidden(); let is_loading_contents = self.is_loading_contents; - if is_subagent { - this.child( - base_container.border_dashed().child( - non_editable_icon().tooltip(move |_, cx| { - Tooltip::with_meta( - "Unavailable Editing", - None, - "Editing subagent messages is currently not supported.", - cx, - ) - }), - ), - ) - } else if message.id.is_some() { + if is_editable { this.child( base_container .child( @@ -3938,26 +3927,29 @@ impl ThreadView { this.child( base_container .border_dashed() - .child( - non_editable_icon() - .tooltip(Tooltip::element({ - move |_, _| { - v_flex() - .gap_1() - .child(Label::new("Unavailable Editing")).child( - div().max_w_64().child( - Label::new(format!( - "Editing previous messages is not available for {} yet.", - agent_name.clone() - )) - .size(LabelSize::Small) - .color(Color::Muted), - ), - ) - .into_any_element() - } - })) - ) + .child(IconButton::new("non_editable", IconName::PencilUnavailable) + .icon_size(IconSize::Small) + .icon_color(Color::Muted) + .style(ButtonStyle::Transparent) + .tooltip(Tooltip::element({ + let agent_name = agent_name.clone(); + move |_, _| { + v_flex() + .gap_1() + .child(Label::new("Unavailable Editing")) + .child( + div().max_w_64().child( + Label::new(format!( + "Editing previous messages is not available for {} yet.", + agent_name + )) + .size(LabelSize::Small) + .color(Color::Muted), + ), + ) + .into_any_element() + } + }))), ) } }),