assistant edit tool: Reliability improvements (#27431)

- Add instructions in description to read before editing
- Add instructions in edit prefix to explicitly ask for reads
- Fix `connection error: delay between messages too long` by processing
chunks off a channel

Release Notes:

- N/A
This commit is contained in:
Agus Zubiaga 2025-03-25 12:34:01 -03:00 committed by GitHub
parent 2414855121
commit 408e157d0f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 23 additions and 7 deletions

View file

@ -6,8 +6,8 @@ use anyhow::{anyhow, Context, Result};
use assistant_tool::{ActionLog, Tool};
use collections::HashSet;
use edit_action::{EditAction, EditActionParser};
use futures::StreamExt;
use gpui::{App, AsyncApp, Entity, Task};
use futures::{channel::mpsc, SinkExt, StreamExt};
use gpui::{App, AppContext, AsyncApp, Entity, Task};
use language_model::{
LanguageModelRegistry, LanguageModelRequest, LanguageModelRequestMessage, MessageContent, Role,
};
@ -225,12 +225,24 @@ impl EditToolRequest {
temperature: Some(0.0),
};
let (mut tx, mut rx) = mpsc::channel::<String>(32);
let stream = model.stream_completion_text(llm_request, &cx);
let mut chunks = stream.await?;
let reader_task = cx.background_spawn(async move {
let mut chunks = stream.await?;
while let Some(chunk) = chunks.stream.next().await {
if let Some(chunk) = chunk.log_err() {
// we don't process here because the API fails
// if we take too long between reads
tx.send(chunk).await?
}
}
tx.close().await?;
anyhow::Ok(())
});
let mut request = Self {
parser: EditActionParser::new(),
// we start with the success header so we don't need to shift the output in the common case
output: Self::SUCCESS_OUTPUT_HEADER.to_string(),
changed_buffers: HashSet::default(),
bad_searches: Vec::new(),
@ -239,10 +251,12 @@ impl EditToolRequest {
tool_log,
};
while let Some(chunk) = chunks.stream.next().await {
request.process_response_chunk(&chunk?, cx).await?;
while let Some(chunk) = rx.next().await {
request.process_response_chunk(&chunk, cx).await?;
}
reader_task.await?;
request.finalize(cx).await
})
}