assistant2: Refine thread design (#26783)

Danilo Leal created

Just some light design polish while we're in-flight with this.

<img
src="https://github.com/user-attachments/assets/40a68fe6-f37e-4df1-b669-824c7dd8ff11"
width="600px" />

---

Release Notes:

- N/A

Change summary

assets/icons/settings_alt.svg          |  8 +-
crates/assistant2/src/active_thread.rs | 86 ++++++++++++++++++---------
crates/assistant2/src/tool_selector.rs | 29 +++-----
3 files changed, 71 insertions(+), 52 deletions(-)

Detailed changes

assets/icons/settings_alt.svg 🔗

@@ -1,6 +1,6 @@
 <svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path d="M3 4H8" stroke="black" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
-<path d="M6 10L11 10" stroke="black" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
-<circle cx="4" cy="10" r="1.875" stroke="black" stroke-width="1.75"/>
-<circle cx="10" cy="4" r="1.875" stroke="black" stroke-width="1.75"/>
+<path d="M3 4H8" stroke="black" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M6 10L11 10" stroke="black" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<circle cx="4" cy="10" r="1.875" stroke="black" stroke-width="1.5"/>
+<circle cx="10" cy="4" r="1.875" stroke="black" stroke-width="1.5"/>
 </svg>

crates/assistant2/src/active_thread.rs 🔗

@@ -691,12 +691,13 @@ impl ActiveThread {
             .copied()
             .unwrap_or_default();
 
+        let lighter_border = cx.theme().colors().border.opacity(0.5);
+
         div().px_2p5().child(
             v_flex()
-                .gap_1()
                 .rounded_lg()
                 .border_1()
-                .border_color(cx.theme().colors().border)
+                .border_color(lighter_border)
                 .child(
                     h_flex()
                         .justify_between()
@@ -711,7 +712,7 @@ impl ActiveThread {
                                 element.rounded_md()
                             }
                         })
-                        .border_color(cx.theme().colors().border)
+                        .border_color(lighter_border)
                         .child(
                             h_flex()
                                 .gap_1()
@@ -728,7 +729,11 @@ impl ActiveThread {
                                         }
                                     }),
                                 ))
-                                .child(Label::new(tool_use.name)),
+                                .child(
+                                    Label::new(tool_use.name)
+                                        .size(LabelSize::Small)
+                                        .buffer_font(cx),
+                                ),
                         )
                         .child({
                             let (icon_name, color, animated) = match &tool_use.status {
@@ -765,39 +770,60 @@ impl ActiveThread {
                         return parent;
                     }
 
+                    let content_container = || v_flex().py_1().gap_0p5().px_2p5();
+
                     parent.child(
                         v_flex()
+                            .gap_1()
+                            .bg(cx.theme().colors().editor_background)
+                            .rounded_b_lg()
                             .child(
-                                v_flex()
-                                    .gap_0p5()
-                                    .py_1()
-                                    .px_2p5()
+                                content_container()
                                     .border_b_1()
-                                    .border_color(cx.theme().colors().border)
-                                    .child(Label::new("Input:"))
-                                    .child(Label::new(
-                                        serde_json::to_string_pretty(&tool_use.input)
-                                            .unwrap_or_default(),
-                                    )),
+                                    .border_color(lighter_border)
+                                    .child(
+                                        Label::new("Input")
+                                            .size(LabelSize::XSmall)
+                                            .color(Color::Muted)
+                                            .buffer_font(cx),
+                                    )
+                                    .child(
+                                        Label::new(
+                                            serde_json::to_string_pretty(&tool_use.input)
+                                                .unwrap_or_default(),
+                                        )
+                                        .size(LabelSize::Small)
+                                        .buffer_font(cx),
+                                    ),
                             )
-                            .map(|parent| match tool_use.status {
-                                ToolUseStatus::Finished(output) => parent.child(
-                                    v_flex()
-                                        .gap_0p5()
-                                        .py_1()
-                                        .px_2p5()
-                                        .child(Label::new("Result:"))
-                                        .child(Label::new(output)),
+                            .map(|container| match tool_use.status {
+                                ToolUseStatus::Finished(output) => container.child(
+                                    content_container()
+                                        .child(
+                                            Label::new("Result")
+                                                .size(LabelSize::XSmall)
+                                                .color(Color::Muted)
+                                                .buffer_font(cx),
+                                        )
+                                        .child(
+                                            Label::new(output)
+                                                .size(LabelSize::Small)
+                                                .buffer_font(cx),
+                                        ),
                                 ),
-                                ToolUseStatus::Error(err) => parent.child(
-                                    v_flex()
-                                        .gap_0p5()
-                                        .py_1()
-                                        .px_2p5()
-                                        .child(Label::new("Error:"))
-                                        .child(Label::new(err)),
+                                ToolUseStatus::Error(err) => container.child(
+                                    content_container()
+                                        .child(
+                                            Label::new("Error")
+                                                .size(LabelSize::XSmall)
+                                                .color(Color::Muted)
+                                                .buffer_font(cx),
+                                        )
+                                        .child(
+                                            Label::new(err).size(LabelSize::Small).buffer_font(cx),
+                                        ),
                                 ),
-                                ToolUseStatus::Pending | ToolUseStatus::Running => parent,
+                                ToolUseStatus::Pending | ToolUseStatus::Running => container,
                             }),
                     )
                 }),

crates/assistant2/src/tool_selector.rs 🔗

@@ -3,7 +3,7 @@ use std::sync::Arc;
 use assistant_tool::{ToolSource, ToolWorkingSet};
 use gpui::Entity;
 use scripting_tool::ScriptingTool;
-use ui::{prelude::*, ContextMenu, IconButtonShape, PopoverMenu, Tooltip};
+use ui::{prelude::*, ContextMenu, PopoverMenu, Tooltip};
 
 pub struct ToolSelector {
     tools: Arc<ToolWorkingSet>,
@@ -24,22 +24,16 @@ impl ToolSelector {
             let tools_by_source = self.tools.tools_by_source(cx);
 
             let all_tools_enabled = self.tools.are_all_tools_enabled();
-            menu = menu.header("Tools").toggleable_entry(
-                "All Tools",
-                all_tools_enabled,
-                icon_position,
-                None,
-                {
-                    let tools = self.tools.clone();
-                    move |_window, cx| {
-                        if all_tools_enabled {
-                            tools.disable_all_tools(cx);
-                        } else {
-                            tools.enable_all_tools();
-                        }
+            menu = menu.toggleable_entry("All Tools", all_tools_enabled, icon_position, None, {
+                let tools = self.tools.clone();
+                move |_window, cx| {
+                    if all_tools_enabled {
+                        tools.disable_all_tools(cx);
+                    } else {
+                        tools.enable_all_tools();
                     }
-                },
-            );
+                }
+            });
 
             for (source, tools) in tools_by_source {
                 let mut tools = tools
@@ -63,7 +57,7 @@ impl ToolSelector {
                 }
 
                 menu = match &source {
-                    ToolSource::Native => menu.header("Zed"),
+                    ToolSource::Native => menu.separator().header("Zed Tools"),
                     ToolSource::ContextServer { id } => {
                         let all_tools_from_source_enabled =
                             self.tools.are_all_tools_from_source_enabled(&source);
@@ -124,7 +118,6 @@ impl Render for ToolSelector {
             })
             .trigger_with_tooltip(
                 IconButton::new("tool-selector-button", IconName::SettingsAlt)
-                    .shape(IconButtonShape::Square)
                     .icon_size(IconSize::Small)
                     .icon_color(Color::Muted),
                 Tooltip::text("Customize Tools"),