assistant: Insert creases for tool output (#17464)

This PR makes it so we insert creases for tool output.

Release Notes:

- N/A
This commit is contained in:
Marshall Bowers 2024-09-05 18:23:27 -04:00 committed by GitHub
parent 629a412c2e
commit b8d3af35fd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 69 additions and 9 deletions

View File

@ -2198,6 +2198,47 @@ impl ContextEditor {
}
}
}
ContextEvent::ToolFinished {
tool_use_id,
output_range,
} => {
self.editor.update(cx, |editor, cx| {
let buffer = editor.buffer().read(cx).snapshot(cx);
let (excerpt_id, _buffer_id, _) = buffer.as_singleton().unwrap();
let excerpt_id = *excerpt_id;
let placeholder = FoldPlaceholder {
render: render_fold_icon_button(
cx.view().downgrade(),
IconName::PocketKnife,
format!("Tool Result: {tool_use_id}").into(),
),
constrain_width: false,
merge_adjacent: false,
};
let render_trailer =
move |_row, _unfold, _cx: &mut WindowContext| Empty.into_any();
let start = buffer
.anchor_in_excerpt(excerpt_id, output_range.start)
.unwrap();
let end = buffer
.anchor_in_excerpt(excerpt_id, output_range.end)
.unwrap();
let buffer_row = MultiBufferRow(start.to_point(&buffer).row);
let crease = Crease::new(
start..end,
placeholder,
fold_toggle("tool-use"),
render_trailer,
);
editor.insert_creases([crease], cx);
editor.fold_at(&FoldAt { buffer_row }, cx);
});
}
ContextEvent::Operation(_) => {}
ContextEvent::ShowAssistError(error_message) => {
self.error_message = Some(error_message.clone());

View File

@ -307,6 +307,10 @@ pub enum ContextEvent {
expand_result: bool,
},
UsePendingTools,
ToolFinished {
tool_use_id: Arc<str>,
output_range: Range<language::Anchor>,
},
Operation(ContextOperation),
}
@ -1923,28 +1927,43 @@ impl Context {
pub fn insert_tool_output(
&mut self,
tool_id: Arc<str>,
tool_use_id: Arc<str>,
output: Task<Result<String>>,
cx: &mut ModelContext<Self>,
) {
let insert_output_task = cx.spawn(|this, mut cx| {
let tool_id = tool_id.clone();
let tool_use_id = tool_use_id.clone();
async move {
let output = output.await;
this.update(&mut cx, |this, cx| match output {
Ok(mut output) => {
if !output.ends_with('\n') {
output.push('\n');
const NEWLINE: char = '\n';
if !output.ends_with(NEWLINE) {
output.push(NEWLINE);
}
this.buffer.update(cx, |buffer, cx| {
let buffer_end = buffer.len().to_offset(buffer);
let anchor_range = this.buffer.update(cx, |buffer, cx| {
let insert_start = buffer.len().to_offset(buffer);
let insert_end = insert_start;
buffer.edit([(buffer_end..buffer_end, output)], None, cx);
let start = insert_start;
let end = start + output.len() - NEWLINE.len_utf8();
buffer.edit([(insert_start..insert_end, output)], None, cx);
let output_range = buffer.anchor_after(start)..buffer.anchor_after(end);
output_range
});
cx.emit(ContextEvent::ToolFinished {
tool_use_id,
output_range: anchor_range,
});
}
Err(err) => {
if let Some(tool_use) = this.pending_tool_uses_by_id.get_mut(&tool_id) {
if let Some(tool_use) = this.pending_tool_uses_by_id.get_mut(&tool_use_id) {
tool_use.status = PendingToolUseStatus::Error(err.to_string());
}
}
@ -1953,7 +1972,7 @@ impl Context {
}
});
if let Some(tool_use) = self.pending_tool_uses_by_id.get_mut(&tool_id) {
if let Some(tool_use) = self.pending_tool_uses_by_id.get_mut(&tool_use_id) {
tool_use.status = PendingToolUseStatus::Running {
_task: insert_output_task.shared(),
};