agent: Show title generation error in tooltip (#60982)
Closes #57117 <img width="305" height="84" alt="image" src="https://github.com/user-attachments/assets/5626040c-5c3f-4f3f-8931-31331406015e" /> Release Notes: - agent: Show actual error message when title generation fails --------- Co-authored-by: Martin Ye <martin@zed.dev>
This commit is contained in:
1 parent
b4018f4c7e
commit
75aeecfbf3
3 files changed
+41
-19
No files matched your search
@@ -3842,6 +3842,11 @@ async fn test_title_generation_failure_allows_retry(cx: &mut TestAppContext) {
|
||||
thread.read_with(cx, |thread, _| {
|
||||
assert_eq!(thread.title(), None);
|
||||
assert!(thread.has_failed_title_generation());
|
||||
assert!(
|
||||
thread
|
||||
.title_generation_error()
|
||||
.is_some_and(|error| error.contains("Internal server error"))
|
||||
);
|
||||
assert!(!thread.is_generating_title());
|
||||
});
|
||||
|
||||
@@ -3852,6 +3857,7 @@ async fn test_title_generation_failure_allows_retry(cx: &mut TestAppContext) {
|
||||
|
||||
thread.read_with(cx, |thread, _| {
|
||||
assert!(!thread.has_failed_title_generation());
|
||||
assert_eq!(thread.title_generation_error(), None);
|
||||
assert!(thread.is_generating_title());
|
||||
});
|
||||
|
||||
@@ -3862,6 +3868,7 @@ async fn test_title_generation_failure_allows_retry(cx: &mut TestAppContext) {
|
||||
thread.read_with(cx, |thread, _| {
|
||||
assert_eq!(thread.title(), Some("Retried title".into()));
|
||||
assert!(!thread.has_failed_title_generation());
|
||||
assert_eq!(thread.title_generation_error(), None);
|
||||
assert!(!thread.is_generating_title());
|
||||
});
|
||||
}
|
||||
|
||||
+23
-15
@@ -1219,7 +1219,7 @@ pub struct Thread {
|
||||
updated_at: DateTime<Utc>,
|
||||
title: Option<SharedString>,
|
||||
pending_title_generation: Option<Task<()>>,
|
||||
title_generation_failed: bool,
|
||||
title_generation_error: Option<SharedString>,
|
||||
pending_summary_generation: Option<Shared<Task<Option<SharedString>>>>,
|
||||
summary: Option<SharedString>,
|
||||
messages: Vec<Arc<Message>>,
|
||||
@@ -1369,7 +1369,7 @@ impl Thread {
|
||||
updated_at: Utc::now(),
|
||||
title: None,
|
||||
pending_title_generation: None,
|
||||
title_generation_failed: false,
|
||||
title_generation_error: None,
|
||||
pending_summary_generation: None,
|
||||
summary: None,
|
||||
messages: Vec::new(),
|
||||
@@ -1748,7 +1748,7 @@ impl Thread {
|
||||
Some(db_thread.title.clone())
|
||||
},
|
||||
pending_title_generation: None,
|
||||
title_generation_failed: false,
|
||||
title_generation_error: None,
|
||||
pending_summary_generation: None,
|
||||
summary: db_thread.detailed_summary,
|
||||
messages: db_thread.messages,
|
||||
@@ -3751,7 +3751,11 @@ impl Thread {
|
||||
}
|
||||
|
||||
pub fn has_failed_title_generation(&self) -> bool {
|
||||
self.title_generation_failed
|
||||
self.title_generation_error.is_some()
|
||||
}
|
||||
|
||||
pub fn title_generation_error(&self) -> Option<SharedString> {
|
||||
self.title_generation_error.clone()
|
||||
}
|
||||
|
||||
pub fn can_generate_title(&self) -> bool {
|
||||
@@ -3854,7 +3858,7 @@ impl Thread {
|
||||
on_generated_title: Option<Box<dyn FnOnce(SharedString, &mut Context<Self>)>>,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.title_generation_failed = false;
|
||||
self.title_generation_error = None;
|
||||
log::debug!("Generating title with model: {:?}", model.name());
|
||||
|
||||
let temperature = AgentSettings::temperature_for_model(&model, cx);
|
||||
@@ -3865,22 +3869,26 @@ impl Thread {
|
||||
.await
|
||||
.context("failed to generate thread title")
|
||||
.map(SharedString::from)
|
||||
.log_err()
|
||||
});
|
||||
|
||||
self.pending_title_generation = Some(cx.spawn(async move |this, cx| {
|
||||
let title = title_generation.await;
|
||||
_ = this.update(cx, |this, cx| {
|
||||
this.pending_title_generation = None;
|
||||
if let Some(title) = title {
|
||||
this.set_title(title.clone(), cx);
|
||||
if let Some(on_generated_title) = on_generated_title {
|
||||
on_generated_title(title, cx);
|
||||
match title {
|
||||
Ok(title) => {
|
||||
this.set_title(title.clone(), cx);
|
||||
if let Some(on_generated_title) = on_generated_title {
|
||||
on_generated_title(title, cx);
|
||||
}
|
||||
}
|
||||
Err(error) => {
|
||||
let error = format!("{error:#}");
|
||||
log::error!("{error}");
|
||||
this.title_generation_error = Some(error.into());
|
||||
cx.emit(TitleUpdated);
|
||||
cx.notify();
|
||||
}
|
||||
} else {
|
||||
this.title_generation_failed = true;
|
||||
cx.emit(TitleUpdated);
|
||||
cx.notify();
|
||||
}
|
||||
});
|
||||
}));
|
||||
@@ -3889,7 +3897,7 @@ impl Thread {
|
||||
|
||||
pub fn set_title(&mut self, title: SharedString, cx: &mut Context<Self>) {
|
||||
self.pending_title_generation = None;
|
||||
self.title_generation_failed = false;
|
||||
self.title_generation_error = None;
|
||||
if Some(&title) != self.title.as_ref() {
|
||||
self.title = Some(title);
|
||||
cx.emit(TitleUpdated);
|
||||
|
||||
@@ -5333,9 +5333,9 @@ impl AgentPanel {
|
||||
let is_generating_title = native_thread
|
||||
.as_ref()
|
||||
.is_some_and(|thread| thread.read(cx).is_generating_title());
|
||||
let title_generation_failed = native_thread
|
||||
let title_generation_error = native_thread
|
||||
.as_ref()
|
||||
.is_some_and(|thread| thread.read(cx).has_failed_title_generation());
|
||||
.and_then(|thread| thread.read(cx).title_generation_error());
|
||||
|
||||
if let Some(title_editor) = server_view_ref
|
||||
.root_thread_view()
|
||||
@@ -5374,7 +5374,7 @@ impl AgentPanel {
|
||||
})
|
||||
.child(title_editor);
|
||||
|
||||
if title_generation_failed {
|
||||
if let Some(title_generation_error) = title_generation_error {
|
||||
h_flex()
|
||||
.w_full()
|
||||
.gap_1()
|
||||
@@ -5383,7 +5383,14 @@ impl AgentPanel {
|
||||
IconButton::new("retry-thread-title", IconName::XCircle)
|
||||
.icon_color(Color::Error)
|
||||
.icon_size(IconSize::Small)
|
||||
.tooltip(Tooltip::text("Title generation failed. Retry"))
|
||||
.tooltip(move |_window, cx| {
|
||||
Tooltip::with_meta(
|
||||
"Title generation failed. Click to retry.",
|
||||
None,
|
||||
title_generation_error.clone(),
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.on_click({
|
||||
let conversation_view = conversation_view.clone();
|
||||
let workspace = self.workspace.clone();
|
||||
|
||||
Reference in new issue
Block a user