Fix mentions roundtrip from/to database and other history bugs (#36575)

Release Notes:

- N/A
This commit is contained in:
Antonio Scandurra 2025-08-20 14:03:20 +02:00 committed by GitHub
parent f80a0ba056
commit 4ee565cd39
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 200 additions and 28 deletions

View file

@ -720,7 +720,7 @@ impl Thread {
pub fn to_db(&self, cx: &App) -> Task<DbThread> {
let initial_project_snapshot = self.initial_project_snapshot.clone();
let mut thread = DbThread {
title: self.title.clone().unwrap_or_default(),
title: self.title(),
messages: self.messages.clone(),
updated_at: self.updated_at,
detailed_summary: self.summary.clone(),
@ -870,6 +870,10 @@ impl Thread {
&self.action_log
}
pub fn is_empty(&self) -> bool {
self.messages.is_empty() && self.title.is_none()
}
pub fn model(&self) -> Option<&Arc<dyn LanguageModel>> {
self.model.as_ref()
}
@ -884,6 +888,10 @@ impl Thread {
cx.notify()
}
pub fn summarization_model(&self) -> Option<&Arc<dyn LanguageModel>> {
self.summarization_model.as_ref()
}
pub fn set_summarization_model(
&mut self,
model: Option<Arc<dyn LanguageModel>>,
@ -1068,6 +1076,7 @@ impl Thread {
event_stream: event_stream.clone(),
_task: cx.spawn(async move |this, cx| {
log::info!("Starting agent turn execution");
let mut update_title = None;
let turn_result: Result<StopReason> = async {
let mut completion_intent = CompletionIntent::UserPrompt;
loop {
@ -1122,10 +1131,15 @@ impl Thread {
this.pending_message()
.tool_results
.insert(tool_result.tool_use_id.clone(), tool_result);
})
.ok();
})?;
}
this.update(cx, |this, cx| {
if this.title.is_none() && update_title.is_none() {
update_title = Some(this.update_title(&event_stream, cx));
}
})?;
if tool_use_limit_reached {
log::info!("Tool use limit reached, completing turn");
this.update(cx, |this, _cx| this.tool_use_limit_reached = true)?;
@ -1146,10 +1160,6 @@ impl Thread {
Ok(reason) => {
log::info!("Turn execution completed: {:?}", reason);
let update_title = this
.update(cx, |this, cx| this.update_title(&event_stream, cx))
.ok()
.flatten();
if let Some(update_title) = update_title {
update_title.await.context("update title failed").log_err();
}
@ -1593,17 +1603,14 @@ impl Thread {
&mut self,
event_stream: &ThreadEventStream,
cx: &mut Context<Self>,
) -> Option<Task<Result<()>>> {
if self.title.is_some() {
log::debug!("Skipping title generation because we already have one.");
return None;
}
) -> Task<Result<()>> {
log::info!(
"Generating title with model: {:?}",
self.summarization_model.as_ref().map(|model| model.name())
);
let model = self.summarization_model.clone()?;
let Some(model) = self.summarization_model.clone() else {
return Task::ready(Ok(()));
};
let event_stream = event_stream.clone();
let mut request = LanguageModelRequest {
intent: Some(CompletionIntent::ThreadSummarization),
@ -1620,7 +1627,7 @@ impl Thread {
content: vec![SUMMARIZE_THREAD_PROMPT.into()],
cache: false,
});
Some(cx.spawn(async move |this, cx| {
cx.spawn(async move |this, cx| {
let mut title = String::new();
let mut messages = model.stream_completion(request, cx).await?;
while let Some(event) = messages.next().await {
@ -1655,7 +1662,7 @@ impl Thread {
this.title = Some(title);
cx.notify();
})
}))
})
}
fn last_user_message(&self) -> Option<&UserMessage> {
@ -2457,18 +2464,15 @@ impl From<UserMessageContent> for acp::ContentBlock {
uri: None,
}),
UserMessageContent::Mention { uri, content } => {
acp::ContentBlock::ResourceLink(acp::ResourceLink {
uri: uri.to_uri().to_string(),
name: uri.name(),
acp::ContentBlock::Resource(acp::EmbeddedResource {
resource: acp::EmbeddedResourceResource::TextResourceContents(
acp::TextResourceContents {
mime_type: None,
text: content,
uri: uri.to_uri().to_string(),
},
),
annotations: None,
description: if content.is_empty() {
None
} else {
Some(content)
},
mime_type: None,
size: None,
title: None,
})
}
}