agent: Adjust codeblock design across edit file tool call card and Markdown (#30931)

Danilo Leal created

This PR makes the edit tool call codeblock cards expanded by default, to
be consistent with https://github.com/zed-industries/zed/pull/30806.
Also, I am removing the collapsing behavior of Markdown codeblocks where
we'd add a gradient while capping the container's height based on an
arbitrary number of lines. Figured if they're all now initially
expanded, we could simplify how the design/code operates here
altogether.

Open for feedback, as I can see an argument where the previous Markdown
codeblock design of "collapsed but not fully; it shows a preview" should
stay as it is useful.

Release Notes:

- N/A

Change summary

crates/agent/src/active_thread.rs            | 128 +++++++++------------
crates/assistant_tools/src/edit_file_tool.rs |   2 
2 files changed, 55 insertions(+), 75 deletions(-)

Detailed changes

crates/agent/src/active_thread.rs 🔗

@@ -333,7 +333,6 @@ fn tool_use_markdown_style(window: &Window, cx: &mut App) -> MarkdownStyle {
 }
 
 const CODEBLOCK_CONTAINER_GROUP: &str = "codeblock_container";
-const MAX_UNCOLLAPSED_LINES_IN_CODE_BLOCK: usize = 10;
 
 fn render_markdown_code_block(
     message_id: MessageId,
@@ -346,17 +345,20 @@ fn render_markdown_code_block(
     _window: &Window,
     cx: &App,
 ) -> Div {
+    let label_size = rems(0.8125);
+
     let label = match kind {
         CodeBlockKind::Indented => None,
         CodeBlockKind::Fenced => Some(
             h_flex()
+                .px_1()
                 .gap_1()
                 .child(
                     Icon::new(IconName::Code)
                         .color(Color::Muted)
                         .size(IconSize::XSmall),
                 )
-                .child(Label::new("untitled").size(LabelSize::Small))
+                .child(div().text_size(label_size).child("Plain Text"))
                 .into_any_element(),
         ),
         CodeBlockKind::FencedLang(raw_language_name) => Some(render_code_language(
@@ -393,7 +395,7 @@ fn render_markdown_code_block(
                         .id(("code-block-header-label", ix))
                         .ml_1()
                         .gap_1()
-                        .child(Label::new(file_name).size(LabelSize::Small))
+                        .child(div().text_size(label_size).child(file_name))
                         .child(Label::new(path).color(Color::Muted).size(LabelSize::Small))
                         .tooltip(move |window, cx| {
                             Tooltip::with_meta(
@@ -406,9 +408,10 @@ fn render_markdown_code_block(
                         })
                         .into_any_element()
                 } else {
-                    Label::new(path_range.path.to_string_lossy().to_string())
-                        .size(LabelSize::Small)
+                    div()
                         .ml_1()
+                        .text_size(label_size)
+                        .child(path_range.path.to_string_lossy().to_string())
                         .into_any_element()
                 };
 
@@ -456,19 +459,13 @@ fn render_markdown_code_block(
         .copied_code_block_ids
         .contains(&(message_id, ix));
 
-    let can_expand = metadata.line_count >= MAX_UNCOLLAPSED_LINES_IN_CODE_BLOCK;
-
-    let is_expanded = if can_expand {
-        active_thread.read(cx).is_codeblock_expanded(message_id, ix)
-    } else {
-        false
-    };
+    let is_expanded = active_thread.read(cx).is_codeblock_expanded(message_id, ix);
 
     let codeblock_header_bg = cx
         .theme()
         .colors()
         .element_background
-        .blend(cx.theme().colors().editor_foreground.opacity(0.01));
+        .blend(cx.theme().colors().editor_foreground.opacity(0.025));
 
     let control_buttons = h_flex()
         .visible_on_hover(CODEBLOCK_CONTAINER_GROUP)
@@ -519,44 +516,48 @@ fn render_markdown_code_block(
                 }
             }),
         )
-        .when(can_expand, |header| {
-            header.child(
-                IconButton::new(
-                    ("expand-collapse-code", ix),
-                    if is_expanded {
-                        IconName::ChevronUp
-                    } else {
-                        IconName::ChevronDown
-                    },
-                )
-                .icon_color(Color::Muted)
-                .shape(ui::IconButtonShape::Square)
-                .tooltip(Tooltip::text(if is_expanded {
-                    "Collapse Code"
+        .child(
+            IconButton::new(
+                ("expand-collapse-code", ix),
+                if is_expanded {
+                    IconName::ChevronUp
                 } else {
-                    "Expand Code"
-                }))
-                .on_click({
-                    let active_thread = active_thread.clone();
-                    move |_event, _window, cx| {
-                        active_thread.update(cx, |this, cx| {
-                            this.toggle_codeblock_expanded(message_id, ix);
-                            cx.notify();
-                        });
-                    }
-                }),
+                    IconName::ChevronDown
+                },
             )
-        });
+            .icon_color(Color::Muted)
+            .shape(ui::IconButtonShape::Square)
+            .tooltip(Tooltip::text(if is_expanded {
+                "Collapse Code"
+            } else {
+                "Expand Code"
+            }))
+            .on_click({
+                let active_thread = active_thread.clone();
+                move |_event, _window, cx| {
+                    active_thread.update(cx, |this, cx| {
+                        this.toggle_codeblock_expanded(message_id, ix);
+                        cx.notify();
+                    });
+                }
+            }),
+        );
 
     let codeblock_header = h_flex()
         .relative()
         .p_1()
         .gap_1()
         .justify_between()
-        .border_b_1()
-        .border_color(cx.theme().colors().border.opacity(0.6))
         .bg(codeblock_header_bg)
-        .rounded_t_md()
+        .map(|this| {
+            if !is_expanded {
+                this.rounded_md()
+            } else {
+                this.rounded_t_md()
+                    .border_b_1()
+                    .border_color(cx.theme().colors().border.opacity(0.6))
+            }
+        })
         .children(label)
         .child(control_buttons);
 
@@ -564,12 +565,12 @@ fn render_markdown_code_block(
         .group(CODEBLOCK_CONTAINER_GROUP)
         .my_2()
         .overflow_hidden()
-        .rounded_lg()
+        .rounded_md()
         .border_1()
         .border_color(cx.theme().colors().border.opacity(0.6))
         .bg(cx.theme().colors().editor_background)
         .child(codeblock_header)
-        .when(can_expand && !is_expanded, |this| this.max_h_80())
+        .when(!is_expanded, |this| this.h(rems_from_px(31.)))
 }
 
 fn open_path(
@@ -630,10 +631,13 @@ fn render_code_language(
         .map(|language| language.name().into())
         .unwrap_or(name_fallback);
 
+    let label_size = rems(0.8125);
+
     h_flex()
-        .gap_1()
-        .children(icon_path.map(|icon| icon.color(Color::Muted).size(IconSize::Small)))
-        .child(Label::new(language_label).size(LabelSize::Small))
+        .px_1()
+        .gap_1p5()
+        .children(icon_path.map(|icon| icon.color(Color::Muted).size(IconSize::XSmall)))
+        .child(div().text_size(label_size).child(language_label))
         .into_any_element()
 }
 
@@ -2369,41 +2373,17 @@ impl ActiveThread {
                                         }),
                                         transform: Some(Arc::new({
                                             let active_thread = cx.entity();
-                                            let editor_bg = cx.theme().colors().editor_background;
-
-                                            move |el, range, metadata, _, cx| {
-                                                let can_expand = metadata.line_count
-                                                    >= MAX_UNCOLLAPSED_LINES_IN_CODE_BLOCK;
-
-                                                if !can_expand {
-                                                    return el;
-                                                }
 
+                                            move |element, range, _, _, cx| {
                                                 let is_expanded = active_thread
                                                     .read(cx)
                                                     .is_codeblock_expanded(message_id, range.start);
 
                                                 if is_expanded {
-                                                    return el;
+                                                    return element;
                                                 }
 
-                                                el.child(
-                                                    div()
-                                                        .absolute()
-                                                        .bottom_0()
-                                                        .left_0()
-                                                        .w_full()
-                                                        .h_1_4()
-                                                        .rounded_b_lg()
-                                                        .bg(linear_gradient(
-                                                            0.,
-                                                            linear_color_stop(editor_bg, 0.),
-                                                            linear_color_stop(
-                                                                editor_bg.opacity(0.),
-                                                                1.,
-                                                            ),
-                                                        )),
-                                                )
+                                                element
                                             }
                                         })),
                                     },

crates/assistant_tools/src/edit_file_tool.rs 🔗

@@ -400,7 +400,7 @@ impl EditFileToolCard {
             diff_task: None,
             preview_expanded: true,
             error_expanded: None,
-            full_height_expanded: false,
+            full_height_expanded: true,
             total_lines: None,
         }
     }