agent: Refine feedback message input (#27948)

<img
src="https://github.com/user-attachments/assets/cde37a88-9973-4c27-80b7-459f5e986c74"
width="650" />

Release Notes:

- N/A

---------

Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
This commit is contained in:
Danilo Leal 2025-04-02 17:41:07 -03:00 committed by GitHub
parent b9f10c0adb
commit d23c2d4b02
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 105 additions and 76 deletions

View file

@ -657,6 +657,15 @@
"alt-enter": "editor::Newline"
}
},
{
"context": "AgentFeedbackMessageEditor > Editor",
"use_key_equivalents": true,
"bindings": {
"escape": "menu::Cancel",
"enter": "menu::Confirm",
"alt-enter": "editor::Newline"
}
},
{
"context": "ContextStrip",
"bindings": {

View file

@ -317,6 +317,15 @@
"alt-enter": "editor::Newline"
}
},
{
"context": "AgentFeedbackMessageEditor > Editor",
"use_key_equivalents": true,
"bindings": {
"escape": "menu::Cancel",
"enter": "menu::Confirm",
"alt-enter": "editor::Newline"
}
},
{
"context": "ContextStrip",
"use_key_equivalents": true,

View file

@ -55,8 +55,7 @@ pub struct ActiveThread {
notifications: Vec<WindowHandle<AgentNotification>>,
_subscriptions: Vec<Subscription>,
notification_subscriptions: HashMap<WindowHandle<AgentNotification>, Vec<Subscription>>,
showing_feedback_comments: bool,
feedback_comments_editor: Option<Entity<Editor>>,
feedback_message_editor: Option<Entity<Editor>>,
}
struct RenderedMessage {
@ -371,8 +370,7 @@ impl ActiveThread {
notifications: Vec::new(),
_subscriptions: subscriptions,
notification_subscriptions: HashMap::default(),
showing_feedback_comments: false,
feedback_comments_editor: None,
feedback_message_editor: None,
};
for message in thread.read(cx).messages().cloned().collect::<Vec<_>>() {
@ -923,37 +921,37 @@ impl ActiveThread {
}
fn handle_show_feedback_comments(&mut self, window: &mut Window, cx: &mut Context<Self>) {
self.showing_feedback_comments = true;
if self.feedback_comments_editor.is_none() {
let buffer = cx.new(|cx| {
let empty_string = String::new();
MultiBuffer::singleton(cx.new(|cx| Buffer::local(empty_string, cx)), cx)
});
let editor = cx.new(|cx| {
Editor::new(
editor::EditorMode::AutoHeight { max_lines: 4 },
buffer,
None,
window,
cx,
)
});
self.feedback_comments_editor = Some(editor);
if self.feedback_message_editor.is_some() {
return;
}
let buffer = cx.new(|cx| {
let empty_string = String::new();
MultiBuffer::singleton(cx.new(|cx| Buffer::local(empty_string, cx)), cx)
});
let editor = cx.new(|cx| {
let mut editor = Editor::new(
editor::EditorMode::AutoHeight { max_lines: 4 },
buffer,
None,
window,
cx,
);
editor.set_placeholder_text(
"What went wrong? Share your feedback so we can improve.",
cx,
);
editor
});
editor.read(cx).focus_handle(cx).focus(window);
self.feedback_message_editor = Some(editor);
cx.notify();
}
fn handle_submit_comments(
&mut self,
_: &ClickEvent,
_window: &mut Window,
cx: &mut Context<Self>,
) {
let Some(editor) = self.feedback_comments_editor.clone() else {
fn submit_feedback_message(&mut self, cx: &mut Context<Self>) {
let Some(editor) = self.feedback_message_editor.clone() else {
return;
};
@ -968,8 +966,7 @@ impl ActiveThread {
telemetry::event!("Assistant Thread Feedback Comments", thread_id, comments);
}
self.showing_feedback_comments = false;
self.feedback_comments_editor = None;
self.feedback_message_editor = None;
let this = cx.entity().downgrade();
cx.spawn(async move |_, cx| {
@ -979,17 +976,6 @@ impl ActiveThread {
.detach_and_log_err(cx);
}
fn handle_cancel_comments(
&mut self,
_: &ClickEvent,
_window: &mut Window,
cx: &mut Context<Self>,
) {
self.showing_feedback_comments = false;
self.feedback_comments_editor = None;
cx.notify();
}
fn render_message(&self, ix: usize, window: &mut Window, cx: &mut Context<Self>) -> AnyElement {
let message_id = self.messages[ix];
let Some(message) = self.thread.read(cx).message(message_id) else {
@ -1398,51 +1384,76 @@ impl ActiveThread {
.when(
show_feedback && !self.thread.read(cx).is_generating(),
|parent| {
parent
.child(feedback_items)
.when(self.showing_feedback_comments, |parent| {
parent.child(feedback_items).when_some(
self.feedback_message_editor.clone(),
|parent, feedback_editor| {
let focus_handle = feedback_editor.focus_handle(cx);
parent.child(
v_flex()
.gap_1()
.px_4()
.child(
Label::new(
"Please share your feedback to help us improve:",
)
.size(LabelSize::Small),
)
.child(
div()
.p_2()
.rounded_md()
.border_1()
.border_color(cx.theme().colors().border)
.bg(cx.theme().colors().editor_background)
.child(
self.feedback_comments_editor
.as_ref()
.unwrap()
.clone(),
),
)
.key_context("AgentFeedbackMessageEditor")
.on_action(cx.listener(|this, _: &menu::Cancel, _, cx| {
this.feedback_message_editor = None;
cx.notify();
}))
.on_action(cx.listener(|this, _: &menu::Confirm, _, cx| {
this.submit_feedback_message(cx);
cx.notify();
}))
.on_action(cx.listener(Self::confirm_editing_message))
.mx_4()
.mb_3()
.p_2()
.rounded_md()
.border_1()
.border_color(cx.theme().colors().border)
.bg(cx.theme().colors().editor_background)
.child(feedback_editor)
.child(
h_flex()
.gap_1()
.justify_end()
.pb_2()
.child(
Button::new("cancel-comments", "Cancel").on_click(
cx.listener(Self::handle_cancel_comments),
),
Button::new("dismiss-feedback-message", "Cancel")
.label_size(LabelSize::Small)
.key_binding(
KeyBinding::for_action_in(
&menu::Cancel,
&focus_handle,
window,
cx,
)
.map(|kb| kb.size(rems_from_px(10.))),
)
.on_click(cx.listener(|this, _, _, cx| {
this.feedback_message_editor = None;
cx.notify();
})),
)
.child(
Button::new("submit-comments", "Submit").on_click(
cx.listener(Self::handle_submit_comments),
),
Button::new(
"submit-feedback-message",
"Share Feedback",
)
.style(ButtonStyle::Tinted(ui::TintColor::Accent))
.label_size(LabelSize::Small)
.key_binding(
KeyBinding::for_action_in(
&menu::Confirm,
&focus_handle,
window,
cx,
)
.map(|kb| kb.size(rems_from_px(10.))),
)
.on_click(cx.listener(|this, _, _, cx| {
this.submit_feedback_message(cx);
cx.notify();
})),
),
),
)
})
},
)
},
)
.into_any()