Make thread context wait on detailed summary + remove "Summarizing context..." (#29564)

This moves summarization task management out of `context_store`. The
code there was draining a Vec of tasks to block on, but this is no
longer a good fit for message_editor's context loading. It needs to be
able to repeatedly await on the thread summarization tasks involved in
the context.

Discussed with Danilo, and he thinks it'd be good to remove the current
"Summarizing context" anyway since it causes layout shift. If message
send is blocked on summarizing, the pulsing context pill is sufficient
for now. This UI change made this overall change more straightforward.

Release Notes:

- N/A
This commit is contained in:
Michael Sloan 2025-04-28 15:21:20 -06:00 committed by GitHub
parent 99df1190a9
commit bbc66748dd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 160 additions and 197 deletions

View file

@ -4,7 +4,6 @@ use std::sync::Arc;
use anyhow::{Result, anyhow};
use collections::{HashSet, IndexSet};
use futures::future::join_all;
use futures::{self, FutureExt};
use gpui::{App, Context, Entity, Image, SharedString, Task, WeakEntity};
use language::Buffer;
@ -13,7 +12,6 @@ use project::{Project, ProjectItem, ProjectPath, Symbol};
use prompt_store::UserPromptId;
use ref_cast::RefCast as _;
use text::{Anchor, OffsetRangeExt};
use util::ResultExt as _;
use crate::ThreadStore;
use crate::context::{
@ -27,7 +25,6 @@ use crate::thread::{Thread, ThreadId};
pub struct ContextStore {
project: WeakEntity<Project>,
thread_store: Option<WeakEntity<ThreadStore>>,
thread_summary_tasks: Vec<Task<()>>,
next_context_id: ContextId,
context_set: IndexSet<AgentContextKey>,
context_thread_ids: HashSet<ThreadId>,
@ -41,7 +38,6 @@ impl ContextStore {
Self {
project,
thread_store,
thread_summary_tasks: Vec::new(),
next_context_id: ContextId::zero(),
context_set: IndexSet::default(),
context_thread_ids: HashSet::default(),
@ -201,41 +197,6 @@ impl ContextStore {
}
}
fn start_summarizing_thread_if_needed(
&mut self,
thread: &Entity<Thread>,
cx: &mut Context<Self>,
) {
if let Some(summary_task) =
thread.update(cx, |thread, cx| thread.generate_detailed_summary(cx))
{
let thread = thread.clone();
let thread_store = self.thread_store.clone();
self.thread_summary_tasks.push(cx.spawn(async move |_, cx| {
summary_task.await;
if let Some(thread_store) = thread_store {
// Save thread so its summary can be reused later
let save_task = thread_store
.update(cx, |thread_store, cx| thread_store.save_thread(&thread, cx));
if let Some(save_task) = save_task.ok() {
save_task.await.log_err();
}
}
}));
}
}
pub fn wait_for_summaries(&mut self, cx: &App) -> Task<()> {
let tasks = std::mem::take(&mut self.thread_summary_tasks);
cx.spawn(async move |_cx| {
join_all(tasks).await;
})
}
pub fn add_rules(
&mut self,
prompt_id: UserPromptId,
@ -331,9 +292,15 @@ impl ContextStore {
fn insert_context(&mut self, context: AgentContextHandle, cx: &mut Context<Self>) -> bool {
match &context {
AgentContextHandle::Thread(thread_context) => {
self.context_thread_ids
.insert(thread_context.thread.read(cx).id().clone());
self.start_summarizing_thread_if_needed(&thread_context.thread, cx);
if let Some(thread_store) = self.thread_store.clone() {
thread_context.thread.update(cx, |thread, cx| {
thread.start_generating_detailed_summary_if_needed(thread_store, cx);
});
self.context_thread_ids
.insert(thread_context.thread.read(cx).id().clone());
} else {
return false;
}
}
_ => {}
}