agent_ui: Fix message editor not expanding after sending a message (#52545)

João Soares and Danilo Leal created

Context

Tracks the previous `v2_empty_state` so `set_mode()` only fires on
actual state transitions, not every render frame.

Closes #52424

## Demo
### Before:


https://github.com/user-attachments/assets/76b61861-cebc-44ce-b483-596eeed19bb1

### After:




https://github.com/user-attachments/assets/9da9f3bc-2fc0-4182-8712-4f42d108650b



<!-- Videos/screenshots showing before and after go here -->

## How to review

1. `crates/agent_ui/src/conversation_view/thread_view.rs` — adds a
`was_v2_empty_state` field to gate the `set_mode()` call in
`render_message_editor()` so it only runs on transitions
2. `crates/agent_ui/src/agent_panel.rs` — test verifying that manually
setting the editor to Full mode survives a render cycle without being
reset back to AutoHeight

## Self-review checklist

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- Fixed agent chat input box not expanding after sending a message
(#52424)

---------

Co-authored-by: Danilo Leal <daniloleal09@gmail.com>

Change summary

crates/agent_ui/src/conversation_view.rs             |  6 +
crates/agent_ui/src/conversation_view/thread_view.rs | 47 ++++++-------
2 files changed, 28 insertions(+), 25 deletions(-)

Detailed changes

crates/agent_ui/src/conversation_view.rs 🔗

@@ -1229,6 +1229,9 @@ impl ConversationView {
                                 .and_then(|entry| entry.focus_handle(cx))],
                         );
                     });
+                    active.update(cx, |active, cx| {
+                        active.sync_editor_mode_for_empty_state(cx);
+                    });
                 }
             }
             AcpThreadEvent::EntryUpdated(index) => {
@@ -1248,6 +1251,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, |active, cx| {
+                        active.sync_editor_mode_for_empty_state(cx);
+                    });
                 }
             }
             AcpThreadEvent::SubagentSpawned(session_id) => self.load_subagent_session(

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

@@ -533,6 +533,7 @@ impl ThreadView {
         };
 
         this.sync_generating_indicator(cx);
+        this.sync_editor_mode_for_empty_state(cx);
         let list_state_for_scroll = this.list_state.clone();
         let thread_view = cx.entity().downgrade();
 
@@ -3125,31 +3126,6 @@ impl ThreadView {
             (IconName::Maximize, "Expand Message Editor")
         };
 
-        if v2_empty_state {
-            self.message_editor.update(cx, |editor, cx| {
-                editor.set_mode(
-                    EditorMode::Full {
-                        scale_ui_elements_with_buffer_font_size: false,
-                        show_active_line_background: false,
-                        sizing_behavior: SizingBehavior::Default,
-                    },
-                    cx,
-                );
-            });
-        } else {
-            self.message_editor.update(cx, |editor, cx| {
-                editor.set_mode(
-                    EditorMode::AutoHeight {
-                        min_lines: AgentSettings::get_global(cx).message_editor_min_lines,
-                        max_lines: Some(
-                            AgentSettings::get_global(cx).set_message_editor_max_lines(),
-                        ),
-                    },
-                    cx,
-                );
-            });
-        }
-
         v_flex()
             .on_action(cx.listener(Self::expand_message_editor))
             .p_2()
@@ -5068,6 +5044,27 @@ impl ThreadView {
         })
     }
 
+    pub(crate) fn sync_editor_mode_for_empty_state(&mut self, cx: &mut Context<Self>) {
+        let has_messages = self.list_state.item_count() > 0;
+        let v2_empty_state = cx.has_flag::<AgentV2FeatureFlag>() && !has_messages;
+
+        let mode = if v2_empty_state {
+            EditorMode::Full {
+                scale_ui_elements_with_buffer_font_size: false,
+                show_active_line_background: false,
+                sizing_behavior: SizingBehavior::Default,
+            }
+        } else {
+            EditorMode::AutoHeight {
+                min_lines: AgentSettings::get_global(cx).message_editor_min_lines,
+                max_lines: Some(AgentSettings::get_global(cx).set_message_editor_max_lines()),
+            }
+        };
+        self.message_editor.update(cx, |editor, cx| {
+            editor.set_mode(mode, cx);
+        });
+    }
+
     /// Ensures the list item count includes (or excludes) an extra item for the generating indicator
     pub(crate) fn sync_generating_indicator(&mut self, cx: &App) {
         let is_generating = matches!(self.thread.read(cx).status(), ThreadStatus::Generating);