diff --git a/crates/agent_ui/src/acp/thread_view.rs b/crates/agent_ui/src/acp/thread_view.rs index 984b25c6ac60a95c3a4e6395c52d2af0b60a4626..f56b19954a25db8dd204a1a8d0a6c4b12de7c2fd 100644 --- a/crates/agent_ui/src/acp/thread_view.rs +++ b/crates/agent_ui/src/acp/thread_view.rs @@ -3547,21 +3547,25 @@ impl AcpThreadView { ToolCallStatus::Pending | ToolCallStatus::InProgress ); - v_flex().ml_5().mr_5().my_1p5().gap_1().children( - subagent_threads - .into_iter() - .enumerate() - .map(|(context_ix, thread)| { - self.render_subagent_card( - entry_ix, - context_ix, - &thread, - tool_call_in_progress, - window, - cx, - ) - }), - ) + v_flex() + .mx_5() + .my_1p5() + .gap_3() + .children( + subagent_threads + .into_iter() + .enumerate() + .map(|(context_ix, thread)| { + self.render_subagent_card( + entry_ix, + context_ix, + &thread, + tool_call_in_progress, + window, + cx, + ) + }), + ) } fn render_subagent_card( @@ -3600,6 +3604,17 @@ impl AcpThreadView { .into_any_element() }); + let has_expandable_content = thread_read.entries().iter().rev().any(|entry| { + if let AgentThreadEntry::AssistantMessage(msg) = entry { + msg.chunks.iter().any(|chunk| match chunk { + AssistantMessageChunk::Message { block } => block.markdown().is_some(), + AssistantMessageChunk::Thought { block } => block.markdown().is_some(), + }) + } else { + false + } + }); + v_flex() .w_full() .rounded_md() @@ -3645,28 +3660,30 @@ impl AcpThreadView { ) }), ) - .child( - Disclosure::new( - SharedString::from(format!( - "subagent-disclosure-inner-{}-{}", - entry_ix, context_ix - )), - is_expanded, - ) - .opened_icon(IconName::ChevronUp) - .closed_icon(IconName::ChevronDown) - .visible_on_hover(card_header_id) - .on_click(cx.listener({ - move |this, _, _, cx| { - if this.expanded_subagents.contains(&session_id) { - this.expanded_subagents.remove(&session_id); - } else { - this.expanded_subagents.insert(session_id.clone()); + .when(has_expandable_content, |this| { + this.child( + Disclosure::new( + SharedString::from(format!( + "subagent-disclosure-inner-{}-{}", + entry_ix, context_ix + )), + is_expanded, + ) + .opened_icon(IconName::ChevronUp) + .closed_icon(IconName::ChevronDown) + .visible_on_hover(card_header_id) + .on_click(cx.listener({ + move |this, _, _, cx| { + if this.expanded_subagents.contains(&session_id) { + this.expanded_subagents.remove(&session_id); + } else { + this.expanded_subagents.insert(session_id.clone()); + } + cx.notify(); } - cx.notify(); - } - })), - ), + })), + ) + }), ) .when(is_expanded, |this| { this.child( @@ -3708,25 +3725,39 @@ impl AcpThreadView { .clone(); scroll_handle.scroll_to_bottom(); + let editor_bg = cx.theme().colors().editor_background; + + let gradient_overlay = { + div().absolute().inset_0().bg(linear_gradient( + 180., + linear_color_stop(editor_bg, 0.), + linear_color_stop(editor_bg.opacity(0.), 0.15), + )) + }; div() - .id(format!("subagent-content-{}", session_id)) + .relative() .w_full() .max_h_56() - .p_2() + .p_2p5() + .text_ui(cx) .border_t_1() .border_color(self.tool_card_border_color(cx)) - .bg(cx.theme().colors().editor_background.opacity(0.2)) + .bg(editor_bg.opacity(0.4)) .overflow_hidden() - .track_scroll(&scroll_handle) - .when_some(last_assistant_markdown, |this, markdown| { - this.child( - self.render_markdown( - markdown, - default_markdown_style(false, false, window, cx), - ), - ) - }) + .child( + div() + .id(format!("subagent-content-{}", session_id)) + .size_full() + .track_scroll(&scroll_handle) + .when_some(last_assistant_markdown, |this, markdown| { + this.child(self.render_markdown( + markdown, + default_markdown_style(false, false, window, cx), + )) + }), + ) + .child(gradient_overlay) } fn render_markdown_output(