Skip to content

Commit 9614b72

Browse files
authored
thread view: Add one more UI clean up pass (#36965)
Release Notes: - N/A
1 parent d7c7359 commit 9614b72

File tree

1 file changed

+99
-105
lines changed

1 file changed

+99
-105
lines changed

crates/agent_ui/src/acp/thread_view.rs

Lines changed: 99 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,10 +1340,6 @@ impl AcpThreadView {
13401340
window: &mut Window,
13411341
cx: &Context<Self>,
13421342
) -> AnyElement {
1343-
let is_generating = self
1344-
.thread()
1345-
.is_some_and(|thread| thread.read(cx).status() != ThreadStatus::Idle);
1346-
13471343
let primary = match &entry {
13481344
AgentThreadEntry::UserMessage(message) => {
13491345
let Some(editor) = self
@@ -1377,14 +1373,14 @@ impl AcpThreadView {
13771373
.id(("user_message", entry_ix))
13781374
.map(|this| {
13791375
if entry_ix == 0 && !has_checkpoint_button && rules_item.is_none() {
1380-
this.pt_4()
1376+
this.pt(rems_from_px(18.))
13811377
} else if rules_item.is_some() {
13821378
this.pt_3()
13831379
} else {
13841380
this.pt_2()
13851381
}
13861382
})
1387-
.pb_4()
1383+
.pb_3()
13881384
.px_2()
13891385
.gap_1p5()
13901386
.w_full()
@@ -1504,18 +1500,6 @@ impl AcpThreadView {
15041500
}
15051501
AgentThreadEntry::AssistantMessage(AssistantMessage { chunks }) => {
15061502
let is_last = entry_ix + 1 == total_entries;
1507-
let pending_thinking_chunk_ix = if is_generating && is_last {
1508-
chunks
1509-
.iter()
1510-
.enumerate()
1511-
.next_back()
1512-
.filter(|(_, segment)| {
1513-
matches!(segment, AssistantMessageChunk::Thought { .. })
1514-
})
1515-
.map(|(index, _)| index)
1516-
} else {
1517-
None
1518-
};
15191503

15201504
let style = default_markdown_style(false, false, window, cx);
15211505
let message_body = v_flex()
@@ -1535,7 +1519,6 @@ impl AcpThreadView {
15351519
entry_ix,
15361520
chunk_ix,
15371521
md.clone(),
1538-
Some(chunk_ix) == pending_thinking_chunk_ix,
15391522
window,
15401523
cx,
15411524
)
@@ -1548,7 +1531,7 @@ impl AcpThreadView {
15481531

15491532
v_flex()
15501533
.px_5()
1551-
.py_1()
1534+
.py_1p5()
15521535
.when(is_last, |this| this.pb_4())
15531536
.w_full()
15541537
.text_ui(cx)
@@ -1634,7 +1617,6 @@ impl AcpThreadView {
16341617
entry_ix: usize,
16351618
chunk_ix: usize,
16361619
chunk: Entity<Markdown>,
1637-
pending: bool,
16381620
window: &Window,
16391621
cx: &Context<Self>,
16401622
) -> AnyElement {
@@ -1657,7 +1639,6 @@ impl AcpThreadView {
16571639
.when_some(scroll_handle, |this, scroll_handle| {
16581640
this.track_scroll(&scroll_handle)
16591641
})
1660-
.when(!is_open, |this| this.max_h_12().opacity(0.6))
16611642
.text_ui_sm(cx)
16621643
.overflow_hidden()
16631644
.child(
@@ -1673,10 +1654,11 @@ impl AcpThreadView {
16731654
.group(&card_header_id)
16741655
.relative()
16751656
.w_full()
1657+
.pr_1()
16761658
.justify_between()
16771659
.child(
16781660
h_flex()
1679-
.h(window.line_height())
1661+
.h(window.line_height() - px(2.))
16801662
.gap_1p5()
16811663
.overflow_hidden()
16821664
.child(
@@ -1688,13 +1670,7 @@ impl AcpThreadView {
16881670
div()
16891671
.text_size(self.tool_name_font_size())
16901672
.text_color(cx.theme().colors().text_muted)
1691-
.map(|this| {
1692-
if pending {
1693-
this.child("Thinking")
1694-
} else {
1695-
this.child("Thought")
1696-
}
1697-
}),
1673+
.child("Thinking"),
16981674
),
16991675
)
17001676
.child(
@@ -1727,7 +1703,6 @@ impl AcpThreadView {
17271703
.when(is_open, |this| {
17281704
this.child(
17291705
div()
1730-
.relative()
17311706
.ml_1p5()
17321707
.pl_3p5()
17331708
.border_l_1()
@@ -1815,25 +1790,27 @@ impl AcpThreadView {
18151790

18161791
let tool_output_display = if is_open {
18171792
match &tool_call.status {
1818-
ToolCallStatus::WaitingForConfirmation { options, .. } => {
1819-
v_flex()
1820-
.w_full()
1821-
.children(tool_call.content.iter().map(|content| {
1822-
div()
1823-
.child(self.render_tool_call_content(
1824-
entry_ix, content, tool_call, window, cx,
1825-
))
1826-
.into_any_element()
1827-
}))
1828-
.child(self.render_permission_buttons(
1829-
options,
1830-
entry_ix,
1831-
tool_call.id.clone(),
1832-
tool_call.content.is_empty(),
1833-
cx,
1834-
))
1835-
.into_any()
1836-
}
1793+
ToolCallStatus::WaitingForConfirmation { options, .. } => v_flex()
1794+
.w_full()
1795+
.children(tool_call.content.iter().map(|content| {
1796+
div()
1797+
.child(self.render_tool_call_content(
1798+
entry_ix,
1799+
content,
1800+
tool_call,
1801+
use_card_layout,
1802+
window,
1803+
cx,
1804+
))
1805+
.into_any_element()
1806+
}))
1807+
.child(self.render_permission_buttons(
1808+
options,
1809+
entry_ix,
1810+
tool_call.id.clone(),
1811+
cx,
1812+
))
1813+
.into_any(),
18371814
ToolCallStatus::Pending | ToolCallStatus::InProgress
18381815
if is_edit
18391816
&& tool_call.content.is_empty()
@@ -1848,9 +1825,14 @@ impl AcpThreadView {
18481825
| ToolCallStatus::Canceled => v_flex()
18491826
.w_full()
18501827
.children(tool_call.content.iter().map(|content| {
1851-
div().child(
1852-
self.render_tool_call_content(entry_ix, content, tool_call, window, cx),
1853-
)
1828+
div().child(self.render_tool_call_content(
1829+
entry_ix,
1830+
content,
1831+
tool_call,
1832+
use_card_layout,
1833+
window,
1834+
cx,
1835+
))
18541836
}))
18551837
.into_any(),
18561838
ToolCallStatus::Rejected => Empty.into_any(),
@@ -1863,7 +1845,7 @@ impl AcpThreadView {
18631845
v_flex()
18641846
.map(|this| {
18651847
if use_card_layout {
1866-
this.my_2()
1848+
this.my_1p5()
18671849
.rounded_md()
18681850
.border_1()
18691851
.border_color(self.tool_card_border_color(cx))
@@ -1890,18 +1872,14 @@ impl AcpThreadView {
18901872
.justify_between()
18911873
.when(use_card_layout, |this| {
18921874
this.p_0p5()
1893-
.rounded_t_md()
1875+
.rounded_t(rems_from_px(5.))
18941876
.bg(self.tool_card_header_bg(cx))
1895-
.when(is_open && !failed_or_canceled, |this| {
1896-
this.border_b_1()
1897-
.border_color(self.tool_card_border_color(cx))
1898-
})
18991877
})
19001878
.child(
19011879
h_flex()
19021880
.relative()
19031881
.w_full()
1904-
.h(window.line_height())
1882+
.h(window.line_height() - px(2.))
19051883
.text_size(self.tool_name_font_size())
19061884
.gap_1p5()
19071885
.when(has_location || use_card_layout, |this| this.px_1())
@@ -1989,6 +1967,7 @@ impl AcpThreadView {
19891967
entry_ix: usize,
19901968
content: &ToolCallContent,
19911969
tool_call: &ToolCall,
1970+
card_layout: bool,
19921971
window: &Window,
19931972
cx: &Context<Self>,
19941973
) -> AnyElement {
@@ -1997,7 +1976,13 @@ impl AcpThreadView {
19971976
if let Some(resource_link) = content.resource_link() {
19981977
self.render_resource_link(resource_link, cx)
19991978
} else if let Some(markdown) = content.markdown() {
2000-
self.render_markdown_output(markdown.clone(), tool_call.id.clone(), window, cx)
1979+
self.render_markdown_output(
1980+
markdown.clone(),
1981+
tool_call.id.clone(),
1982+
card_layout,
1983+
window,
1984+
cx,
1985+
)
20011986
} else {
20021987
Empty.into_any_element()
20031988
}
@@ -2013,33 +1998,43 @@ impl AcpThreadView {
20131998
&self,
20141999
markdown: Entity<Markdown>,
20152000
tool_call_id: acp::ToolCallId,
2001+
card_layout: bool,
20162002
window: &Window,
20172003
cx: &Context<Self>,
20182004
) -> AnyElement {
20192005
let button_id = SharedString::from(format!("tool_output-{:?}", tool_call_id));
20202006

20212007
v_flex()
20222008
.mt_1p5()
2023-
.ml(rems(0.4))
2024-
.px_3p5()
20252009
.gap_2()
2026-
.border_l_1()
2027-
.border_color(self.tool_card_border_color(cx))
2010+
.when(!card_layout, |this| {
2011+
this.ml(rems(0.4))
2012+
.px_3p5()
2013+
.border_l_1()
2014+
.border_color(self.tool_card_border_color(cx))
2015+
})
2016+
.when(card_layout, |this| {
2017+
this.p_2()
2018+
.border_t_1()
2019+
.border_color(self.tool_card_border_color(cx))
2020+
})
20282021
.text_sm()
20292022
.text_color(cx.theme().colors().text_muted)
20302023
.child(self.render_markdown(markdown, default_markdown_style(false, false, window, cx)))
2031-
.child(
2032-
IconButton::new(button_id, IconName::ChevronUp)
2033-
.full_width()
2034-
.style(ButtonStyle::Outlined)
2035-
.icon_color(Color::Muted)
2036-
.on_click(cx.listener({
2037-
move |this: &mut Self, _, _, cx: &mut Context<Self>| {
2038-
this.expanded_tool_calls.remove(&tool_call_id);
2039-
cx.notify();
2040-
}
2041-
})),
2042-
)
2024+
.when(!card_layout, |this| {
2025+
this.child(
2026+
IconButton::new(button_id, IconName::ChevronUp)
2027+
.full_width()
2028+
.style(ButtonStyle::Outlined)
2029+
.icon_color(Color::Muted)
2030+
.on_click(cx.listener({
2031+
move |this: &mut Self, _, _, cx: &mut Context<Self>| {
2032+
this.expanded_tool_calls.remove(&tool_call_id);
2033+
cx.notify();
2034+
}
2035+
})),
2036+
)
2037+
})
20432038
.into_any_element()
20442039
}
20452040

@@ -2107,7 +2102,6 @@ impl AcpThreadView {
21072102
options: &[acp::PermissionOption],
21082103
entry_ix: usize,
21092104
tool_call_id: acp::ToolCallId,
2110-
empty_content: bool,
21112105
cx: &Context<Self>,
21122106
) -> Div {
21132107
h_flex()
@@ -2117,10 +2111,8 @@ impl AcpThreadView {
21172111
.gap_1()
21182112
.justify_between()
21192113
.flex_wrap()
2120-
.when(!empty_content, |this| {
2121-
this.border_t_1()
2122-
.border_color(self.tool_card_border_color(cx))
2123-
})
2114+
.border_t_1()
2115+
.border_color(self.tool_card_border_color(cx))
21242116
.child(
21252117
div()
21262118
.min_w(rems_from_px(145.))
@@ -2218,6 +2210,8 @@ impl AcpThreadView {
22182210

22192211
v_flex()
22202212
.h_full()
2213+
.border_t_1()
2214+
.border_color(self.tool_card_border_color(cx))
22212215
.child(
22222216
if let Some(entry) = self.entry_view_state.read(cx).entry(entry_ix)
22232217
&& let Some(editor) = entry.editor_for_diff(diff)
@@ -2350,6 +2344,28 @@ impl AcpThreadView {
23502344
),
23512345
)
23522346
})
2347+
.child(
2348+
Disclosure::new(
2349+
SharedString::from(format!(
2350+
"terminal-tool-disclosure-{}",
2351+
terminal.entity_id()
2352+
)),
2353+
is_expanded,
2354+
)
2355+
.opened_icon(IconName::ChevronUp)
2356+
.closed_icon(IconName::ChevronDown)
2357+
.visible_on_hover(&header_group)
2358+
.on_click(cx.listener({
2359+
let id = tool_call.id.clone();
2360+
move |this, _event, _window, _cx| {
2361+
if is_expanded {
2362+
this.expanded_tool_calls.remove(&id);
2363+
} else {
2364+
this.expanded_tool_calls.insert(id.clone());
2365+
}
2366+
}
2367+
})),
2368+
)
23532369
.when(truncated_output, |header| {
23542370
let tooltip = if let Some(output) = output {
23552371
if output_line_count + 10 > terminal::MAX_SCROLL_HISTORY_LINES {
@@ -2392,28 +2408,6 @@ impl AcpThreadView {
23922408
.size(LabelSize::XSmall),
23932409
)
23942410
})
2395-
.child(
2396-
Disclosure::new(
2397-
SharedString::from(format!(
2398-
"terminal-tool-disclosure-{}",
2399-
terminal.entity_id()
2400-
)),
2401-
is_expanded,
2402-
)
2403-
.opened_icon(IconName::ChevronUp)
2404-
.closed_icon(IconName::ChevronDown)
2405-
.visible_on_hover(&header_group)
2406-
.on_click(cx.listener({
2407-
let id = tool_call.id.clone();
2408-
move |this, _event, _window, _cx| {
2409-
if is_expanded {
2410-
this.expanded_tool_calls.remove(&id);
2411-
} else {
2412-
this.expanded_tool_calls.insert(id.clone());
2413-
}
2414-
}
2415-
})),
2416-
)
24172411
.when(tool_failed || command_failed, |header| {
24182412
header.child(
24192413
div()
@@ -2440,7 +2434,7 @@ impl AcpThreadView {
24402434
let show_output = is_expanded && terminal_view.is_some();
24412435

24422436
v_flex()
2443-
.my_2()
2437+
.my_1p5()
24442438
.mx_5()
24452439
.border_1()
24462440
.when(tool_failed || command_failed, |card| card.border_dashed())

0 commit comments

Comments
 (0)