From f5993d801bed50eefba134ba4c063db1c154d869 Mon Sep 17 00:00:00 2001 From: Danilo Leal <67129314+danilo-leal@users.noreply.github.com> Date: Wed, 1 Apr 2026 10:30:37 -0300 Subject: [PATCH] agent_ui: Add more refinements to the thinking block display (#52874) Follow-up to https://github.com/zed-industries/zed/pull/52608 This PR adds a new iteration to the thinking block display design after some internal round of feedback. It turns out, we had some people appreciating the auto-collapse when thinking is done; thinking content isn't too useful afterwards and it is just more content _to to he model_, not the user. I also liked the one old but it definitely has the issue of being a jarring layout shift when it wraps up. So that's why I'm keeping what I introduced in the PR linked above as a setting, so that anyone who feels strongly about the default (auto-expand, and auto-collapse) can change that. Release Notes: - N/A --- assets/settings/default.json | 4 +-- .../src/conversation_view/thread_view.rs | 33 ++++++++++++++++--- crates/settings_content/src/agent.rs | 7 ++-- crates/settings_ui/src/page_data.rs | 2 +- 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/assets/settings/default.json b/assets/settings/default.json index 57bad245474b9469a0a9b9d5674c692059f039af..2e0ddc2da70af5516d14a2fa8418a759bec62eb1 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -1117,8 +1117,8 @@ "expand_terminal_card": true, // How thinking blocks should be displayed by default in the agent panel. // - // Default: automatic - "thinking_display": "automatic", + // Default: auto + "thinking_display": "auto", // Whether clicking the stop button on a running terminal tool should also cancel the agent's generation. // Note that this only applies to the stop button, not to ctrl+c inside the terminal. // diff --git a/crates/agent_ui/src/conversation_view/thread_view.rs b/crates/agent_ui/src/conversation_view/thread_view.rs index 63aa8b8529655a26b99ba74062f8d0a6a4812c5f..b25769eadbe31c35a6261cc9433349a2943617be 100644 --- a/crates/agent_ui/src/conversation_view/thread_view.rs +++ b/crates/agent_ui/src/conversation_view/thread_view.rs @@ -5152,9 +5152,12 @@ impl ThreadView { } pub(crate) fn auto_expand_streaming_thought(&mut self, cx: &mut Context) { - // Only auto-expand thinking blocks in Automatic mode. - // AlwaysExpanded shows them open by default; AlwaysCollapsed keeps them closed. - if AgentSettings::get_global(cx).thinking_display != ThinkingBlockDisplay::Automatic { + let thinking_display = AgentSettings::get_global(cx).thinking_display; + + if !matches!( + thinking_display, + ThinkingBlockDisplay::Auto | ThinkingBlockDisplay::Preview + ) { return; } @@ -5183,6 +5186,13 @@ impl ThreadView { cx.notify(); } } else if self.auto_expanded_thinking_block.is_some() { + if thinking_display == ThinkingBlockDisplay::Auto { + if let Some(key) = self.auto_expanded_thinking_block { + if !self.user_toggled_thinking_blocks.contains(&key) { + self.expanded_thinking_blocks.remove(&key); + } + } + } self.auto_expanded_thinking_block = None; cx.notify(); } @@ -5196,7 +5206,16 @@ impl ThreadView { let thinking_display = AgentSettings::get_global(cx).thinking_display; match thinking_display { - ThinkingBlockDisplay::Automatic => { + ThinkingBlockDisplay::Auto => { + if self.expanded_thinking_blocks.contains(&key) { + self.expanded_thinking_blocks.remove(&key); + self.user_toggled_thinking_blocks.insert(key); + } else { + self.expanded_thinking_blocks.insert(key); + self.user_toggled_thinking_blocks.insert(key); + } + } + ThinkingBlockDisplay::Preview => { let is_user_expanded = self.user_toggled_thinking_blocks.contains(&key); let is_in_expanded_set = self.expanded_thinking_blocks.contains(&key); @@ -5249,7 +5268,11 @@ impl ThreadView { let is_in_expanded_set = self.expanded_thinking_blocks.contains(&key); let (is_open, is_constrained) = match thinking_display { - ThinkingBlockDisplay::Automatic => { + ThinkingBlockDisplay::Auto => { + let is_open = is_user_toggled || is_in_expanded_set; + (is_open, false) + } + ThinkingBlockDisplay::Preview => { let is_open = is_user_toggled || is_in_expanded_set; let is_constrained = is_in_expanded_set && !is_user_toggled; (is_open, is_constrained) diff --git a/crates/settings_content/src/agent.rs b/crates/settings_content/src/agent.rs index f9d3376a26b8d84d89e563b21a969bfca68ee2f7..dae5c99b9ef9b5b3892b1201ff9a1686330dc365 100644 --- a/crates/settings_content/src/agent.rs +++ b/crates/settings_content/src/agent.rs @@ -81,11 +81,14 @@ pub enum SidebarSide { )] #[serde(rename_all = "snake_case")] pub enum ThinkingBlockDisplay { + /// Thinking blocks fully expand during streaming, then auto-collapse + /// when the model finishes thinking. Users can re-expand after collapse. + #[default] + Auto, /// Thinking blocks auto-expand with a height constraint during streaming, /// then remain in their constrained state when complete. Users can click /// to fully expand or collapse. - #[default] - Automatic, + Preview, /// Thinking blocks are always fully expanded by default (no height constraint). AlwaysExpanded, /// Thinking blocks are always collapsed by default. diff --git a/crates/settings_ui/src/page_data.rs b/crates/settings_ui/src/page_data.rs index 08a597dc992913e144ba70e30c1a81b2ab8de1aa..b6d10424f4a6cf0710a916410e0e6068d80d6064 100644 --- a/crates/settings_ui/src/page_data.rs +++ b/crates/settings_ui/src/page_data.rs @@ -7340,7 +7340,7 @@ fn ai_page(cx: &App) -> SettingsPage { }), SettingsPageItem::SettingItem(SettingItem { title: "Thinking Display", - description: "How thinking blocks should be displayed by default. 'Automatic' auto-expands with a height constraint during streaming. 'Always Expanded' shows full content. 'Always Collapsed' keeps them collapsed.", + description: "How thinking blocks should be displayed by default. 'Auto' fully expands during streaming, then auto-collapses when done. 'Preview' auto-expands with a height constraint during streaming. 'Always Expanded' shows full content. 'Always Collapsed' keeps them collapsed.", field: Box::new(SettingField { json_path: Some("agent.thinking_display"), pick: |settings_content| {