mirror of
https://github.com/zed-industries/zed.git
synced 2025-02-02 08:20:09 +00:00
assistant panel: Stop animation & show explicit state if canceled (#16200)
This fixes a bug by stopping the animation when a completion is canceled and it also makes the state more explicit, which I think is very valuable. https://github.com/user-attachments/assets/9ede9b25-86ac-4901-8434-7407896bb799 Release Notes: - N/A
This commit is contained in:
parent
97469cd049
commit
8b8335f449
4 changed files with 75 additions and 31 deletions
|
@ -102,6 +102,7 @@ pub enum MessageStatus {
|
||||||
Pending,
|
Pending,
|
||||||
Done,
|
Done,
|
||||||
Error(SharedString),
|
Error(SharedString),
|
||||||
|
Canceled,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MessageStatus {
|
impl MessageStatus {
|
||||||
|
@ -112,6 +113,7 @@ impl MessageStatus {
|
||||||
Some(proto::context_message_status::Variant::Error(error)) => {
|
Some(proto::context_message_status::Variant::Error(error)) => {
|
||||||
MessageStatus::Error(error.message.into())
|
MessageStatus::Error(error.message.into())
|
||||||
}
|
}
|
||||||
|
Some(proto::context_message_status::Variant::Canceled(_)) => MessageStatus::Canceled,
|
||||||
None => MessageStatus::Pending,
|
None => MessageStatus::Pending,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,6 +137,11 @@ impl MessageStatus {
|
||||||
},
|
},
|
||||||
)),
|
)),
|
||||||
},
|
},
|
||||||
|
MessageStatus::Canceled => proto::ContextMessageStatus {
|
||||||
|
variant: Some(proto::context_message_status::Variant::Canceled(
|
||||||
|
proto::context_message_status::Canceled {},
|
||||||
|
)),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1975,7 +1975,7 @@ impl ContextEditor {
|
||||||
fn cancel(&mut self, _: &editor::actions::Cancel, cx: &mut ViewContext<Self>) {
|
fn cancel(&mut self, _: &editor::actions::Cancel, cx: &mut ViewContext<Self>) {
|
||||||
if self
|
if self
|
||||||
.context
|
.context
|
||||||
.update(cx, |context, _| context.cancel_last_assist())
|
.update(cx, |context, cx| context.cancel_last_assist(cx))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3042,22 +3042,6 @@ impl ContextEditor {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let trigger = Button::new("show-error", "Error")
|
|
||||||
.color(Color::Error)
|
|
||||||
.selected_label_color(Color::Error)
|
|
||||||
.selected_icon_color(Color::Error)
|
|
||||||
.icon(IconName::XCircle)
|
|
||||||
.icon_color(Color::Error)
|
|
||||||
.icon_size(IconSize::Small)
|
|
||||||
.icon_position(IconPosition::Start)
|
|
||||||
.tooltip(move |cx| {
|
|
||||||
Tooltip::with_meta(
|
|
||||||
"Error interacting with language model",
|
|
||||||
None,
|
|
||||||
"Click for more details",
|
|
||||||
cx,
|
|
||||||
)
|
|
||||||
});
|
|
||||||
h_flex()
|
h_flex()
|
||||||
.id(("message_header", message_id.as_u64()))
|
.id(("message_header", message_id.as_u64()))
|
||||||
.pl(cx.gutter_dimensions.full_width())
|
.pl(cx.gutter_dimensions.full_width())
|
||||||
|
@ -3066,22 +3050,63 @@ impl ContextEditor {
|
||||||
.relative()
|
.relative()
|
||||||
.gap_1()
|
.gap_1()
|
||||||
.child(sender)
|
.child(sender)
|
||||||
.children(
|
.children(match &message.status {
|
||||||
if let MessageStatus::Error(error) = message.status.clone() {
|
MessageStatus::Error(error) => {
|
||||||
|
let error_popover_trigger =
|
||||||
|
Button::new("show-error", "Error")
|
||||||
|
.color(Color::Error)
|
||||||
|
.selected_label_color(Color::Error)
|
||||||
|
.selected_icon_color(Color::Error)
|
||||||
|
.icon(IconName::XCircle)
|
||||||
|
.icon_color(Color::Error)
|
||||||
|
.icon_size(IconSize::Small)
|
||||||
|
.icon_position(IconPosition::Start)
|
||||||
|
.tooltip(move |cx| {
|
||||||
|
Tooltip::with_meta(
|
||||||
|
"Error interacting with language model",
|
||||||
|
None,
|
||||||
|
"Click for more details",
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
Some(
|
Some(
|
||||||
PopoverMenu::new("show-error-popover")
|
PopoverMenu::new("show-error-popover")
|
||||||
.menu(move |cx| {
|
.menu({
|
||||||
Some(cx.new_view(|cx| ErrorPopover {
|
let error = error.clone();
|
||||||
error: error.clone(),
|
move |cx| {
|
||||||
focus_handle: cx.focus_handle(),
|
Some(cx.new_view(|cx| ErrorPopover {
|
||||||
}))
|
error: error.clone(),
|
||||||
|
focus_handle: cx.focus_handle(),
|
||||||
|
}))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.trigger(trigger),
|
.trigger(error_popover_trigger)
|
||||||
|
.into_any_element(),
|
||||||
)
|
)
|
||||||
} else {
|
}
|
||||||
None
|
MessageStatus::Canceled => Some(
|
||||||
},
|
ButtonLike::new("canceled")
|
||||||
)
|
.child(
|
||||||
|
Icon::new(IconName::XCircle).color(Color::Disabled),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
Label::new("Canceled")
|
||||||
|
.size(LabelSize::Small)
|
||||||
|
.color(Color::Disabled),
|
||||||
|
)
|
||||||
|
.tooltip(move |cx| {
|
||||||
|
Tooltip::with_meta(
|
||||||
|
"Canceled",
|
||||||
|
None,
|
||||||
|
"Interaction with the assistant was canceled",
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.into_any_element(),
|
||||||
|
),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
.into_any_element()
|
.into_any_element()
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -401,6 +401,7 @@ impl PartialEq for ImageAnchor {
|
||||||
|
|
||||||
struct PendingCompletion {
|
struct PendingCompletion {
|
||||||
id: usize,
|
id: usize,
|
||||||
|
assistant_message_id: MessageId,
|
||||||
_task: Task<()>,
|
_task: Task<()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1806,6 +1807,7 @@ impl Context {
|
||||||
|
|
||||||
self.pending_completions.push(PendingCompletion {
|
self.pending_completions.push(PendingCompletion {
|
||||||
id: post_inc(&mut self.completion_count),
|
id: post_inc(&mut self.completion_count),
|
||||||
|
assistant_message_id: assistant_message.id,
|
||||||
_task: task,
|
_task: task,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1827,8 +1829,15 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cancel_last_assist(&mut self) -> bool {
|
pub fn cancel_last_assist(&mut self, cx: &mut ModelContext<Self>) -> bool {
|
||||||
self.pending_completions.pop().is_some()
|
if let Some(pending_completion) = self.pending_completions.pop() {
|
||||||
|
self.update_metadata(pending_completion.assistant_message_id, cx, |metadata| {
|
||||||
|
metadata.status = MessageStatus::Canceled;
|
||||||
|
});
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cycle_message_roles(&mut self, ids: HashSet<MessageId>, cx: &mut ModelContext<Self>) {
|
pub fn cycle_message_roles(&mut self, ids: HashSet<MessageId>, cx: &mut ModelContext<Self>) {
|
||||||
|
|
|
@ -2310,6 +2310,7 @@ message ContextMessageStatus {
|
||||||
Done done = 1;
|
Done done = 1;
|
||||||
Pending pending = 2;
|
Pending pending = 2;
|
||||||
Error error = 3;
|
Error error = 3;
|
||||||
|
Canceled canceled = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Done {}
|
message Done {}
|
||||||
|
@ -2319,6 +2320,8 @@ message ContextMessageStatus {
|
||||||
message Error {
|
message Error {
|
||||||
string message = 1;
|
string message = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message Canceled {}
|
||||||
}
|
}
|
||||||
|
|
||||||
message ContextMessage {
|
message ContextMessage {
|
||||||
|
|
Loading…
Reference in a new issue