Skip to content

Commit f48a8f2

Browse files
authored
thread view: Simplify tool call & improve required auth state UIs (#36783)
Release Notes: - N/A
1 parent d24cad3 commit f48a8f2

File tree

1 file changed

+82
-63
lines changed

1 file changed

+82
-63
lines changed

crates/agent_ui/src/acp/thread_view.rs

Lines changed: 82 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1668,39 +1668,14 @@ impl AcpThreadView {
16681668
let header_id = SharedString::from(format!("outer-tool-call-header-{}", entry_ix));
16691669
let card_header_id = SharedString::from("inner-tool-call-header");
16701670

1671-
let status_icon = match &tool_call.status {
1672-
ToolCallStatus::Pending
1673-
| ToolCallStatus::WaitingForConfirmation { .. }
1674-
| ToolCallStatus::Completed => None,
1675-
ToolCallStatus::InProgress => Some(
1676-
div()
1677-
.absolute()
1678-
.right_2()
1679-
.child(
1680-
Icon::new(IconName::ArrowCircle)
1681-
.color(Color::Muted)
1682-
.size(IconSize::Small)
1683-
.with_animation(
1684-
"running",
1685-
Animation::new(Duration::from_secs(3)).repeat(),
1686-
|icon, delta| {
1687-
icon.transform(Transformation::rotate(percentage(delta)))
1688-
},
1689-
),
1690-
)
1691-
.into_any(),
1692-
),
1693-
ToolCallStatus::Rejected | ToolCallStatus::Canceled | ToolCallStatus::Failed => Some(
1694-
div()
1695-
.absolute()
1696-
.right_2()
1697-
.child(
1698-
Icon::new(IconName::Close)
1699-
.color(Color::Error)
1700-
.size(IconSize::Small),
1701-
)
1702-
.into_any_element(),
1703-
),
1671+
let in_progress = match &tool_call.status {
1672+
ToolCallStatus::InProgress => true,
1673+
_ => false,
1674+
};
1675+
1676+
let failed_or_canceled = match &tool_call.status {
1677+
ToolCallStatus::Rejected | ToolCallStatus::Canceled | ToolCallStatus::Failed => true,
1678+
_ => false,
17041679
};
17051680

17061681
let failed_tool_call = matches!(
@@ -1884,7 +1859,33 @@ impl AcpThreadView {
18841859
.into_any()
18851860
}),
18861861
)
1887-
.children(status_icon),
1862+
.when(in_progress && use_card_layout, |this| {
1863+
this.child(
1864+
div().absolute().right_2().child(
1865+
Icon::new(IconName::ArrowCircle)
1866+
.color(Color::Muted)
1867+
.size(IconSize::Small)
1868+
.with_animation(
1869+
"running",
1870+
Animation::new(Duration::from_secs(3)).repeat(),
1871+
|icon, delta| {
1872+
icon.transform(Transformation::rotate(percentage(
1873+
delta,
1874+
)))
1875+
},
1876+
),
1877+
),
1878+
)
1879+
})
1880+
.when(failed_or_canceled, |this| {
1881+
this.child(
1882+
div().absolute().right_2().child(
1883+
Icon::new(IconName::Close)
1884+
.color(Color::Error)
1885+
.size(IconSize::Small),
1886+
),
1887+
)
1888+
}),
18881889
)
18891890
.children(tool_output_display)
18901891
}
@@ -2579,11 +2580,15 @@ impl AcpThreadView {
25792580
window: &mut Window,
25802581
cx: &Context<Self>,
25812582
) -> Div {
2583+
let show_description =
2584+
configuration_view.is_none() && description.is_none() && pending_auth_method.is_none();
2585+
25822586
v_flex().flex_1().size_full().justify_end().child(
25832587
v_flex()
25842588
.p_2()
25852589
.pr_3()
25862590
.w_full()
2591+
.gap_1()
25872592
.border_t_1()
25882593
.border_color(cx.theme().colors().border)
25892594
.bg(cx.theme().status().warning.opacity(0.04))
@@ -2595,7 +2600,7 @@ impl AcpThreadView {
25952600
.color(Color::Warning)
25962601
.size(IconSize::Small),
25972602
)
2598-
.child(Label::new("Authentication Required")),
2603+
.child(Label::new("Authentication Required").size(LabelSize::Small)),
25992604
)
26002605
.children(description.map(|desc| {
26012606
div().text_ui(cx).child(self.render_markdown(
@@ -2609,44 +2614,20 @@ impl AcpThreadView {
26092614
.map(|view| div().w_full().child(view)),
26102615
)
26112616
.when(
2612-
configuration_view.is_none()
2613-
&& description.is_none()
2614-
&& pending_auth_method.is_none(),
2617+
show_description,
26152618
|el| {
26162619
el.child(
26172620
Label::new(format!(
26182621
"You are not currently authenticated with {}. Please choose one of the following options:",
26192622
self.agent.name()
26202623
))
2624+
.size(LabelSize::Small)
26212625
.color(Color::Muted)
26222626
.mb_1()
26232627
.ml_5(),
26242628
)
26252629
},
26262630
)
2627-
.when(!connection.auth_methods().is_empty(), |this| {
2628-
this.child(
2629-
h_flex().justify_end().flex_wrap().gap_1().children(
2630-
connection.auth_methods().iter().enumerate().rev().map(
2631-
|(ix, method)| {
2632-
Button::new(
2633-
SharedString::from(method.id.0.clone()),
2634-
method.name.clone(),
2635-
)
2636-
.when(ix == 0, |el| {
2637-
el.style(ButtonStyle::Tinted(ui::TintColor::Warning))
2638-
})
2639-
.on_click({
2640-
let method_id = method.id.clone();
2641-
cx.listener(move |this, _, window, cx| {
2642-
this.authenticate(method_id.clone(), window, cx)
2643-
})
2644-
})
2645-
},
2646-
),
2647-
),
2648-
)
2649-
})
26502631
.when_some(pending_auth_method, |el, _| {
26512632
el.child(
26522633
h_flex()
@@ -2669,9 +2650,47 @@ impl AcpThreadView {
26692650
)
26702651
.into_any_element(),
26712652
)
2672-
.child(Label::new("Authenticating…")),
2653+
.child(Label::new("Authenticating…").size(LabelSize::Small)),
26732654
)
2674-
}),
2655+
})
2656+
.when(!connection.auth_methods().is_empty(), |this| {
2657+
this.child(
2658+
h_flex()
2659+
.justify_end()
2660+
.flex_wrap()
2661+
.gap_1()
2662+
.when(!show_description, |this| {
2663+
this.border_t_1()
2664+
.mt_1()
2665+
.pt_2()
2666+
.border_color(cx.theme().colors().border.opacity(0.8))
2667+
})
2668+
.children(
2669+
connection
2670+
.auth_methods()
2671+
.iter()
2672+
.enumerate()
2673+
.rev()
2674+
.map(|(ix, method)| {
2675+
Button::new(
2676+
SharedString::from(method.id.0.clone()),
2677+
method.name.clone(),
2678+
)
2679+
.when(ix == 0, |el| {
2680+
el.style(ButtonStyle::Tinted(ui::TintColor::Warning))
2681+
})
2682+
.label_size(LabelSize::Small)
2683+
.on_click({
2684+
let method_id = method.id.clone();
2685+
cx.listener(move |this, _, window, cx| {
2686+
this.authenticate(method_id.clone(), window, cx)
2687+
})
2688+
})
2689+
}),
2690+
),
2691+
)
2692+
})
2693+
26752694
)
26762695
}
26772696

0 commit comments

Comments
 (0)