parent
0bd65829f7
commit
6f6c2915b2
2 changed files with 115 additions and 13 deletions
|
@ -176,6 +176,14 @@ impl AgentThreadEntry {
|
|||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn locations(&self) -> Option<&[acp::ToolCallLocation]> {
|
||||
if let AgentThreadEntry::ToolCall(ToolCall { locations, .. }) = self {
|
||||
Some(locations)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
|
@ -925,10 +925,43 @@ impl AcpThreadView {
|
|||
.size(IconSize::Small)
|
||||
.color(Color::Muted),
|
||||
)
|
||||
.child(self.render_markdown(
|
||||
tool_call.label.clone(),
|
||||
default_markdown_style(needs_confirmation, window, cx),
|
||||
)),
|
||||
.child(if tool_call.locations.len() == 1 {
|
||||
let name = tool_call.locations[0]
|
||||
.path
|
||||
.file_name()
|
||||
.unwrap_or_default()
|
||||
.display()
|
||||
.to_string();
|
||||
|
||||
h_flex()
|
||||
.id(("open-tool-call-location", entry_ix))
|
||||
.child(name)
|
||||
.w_full()
|
||||
.max_w_full()
|
||||
.pr_1()
|
||||
.gap_0p5()
|
||||
.cursor_pointer()
|
||||
.rounded_sm()
|
||||
.opacity(0.8)
|
||||
.hover(|label| {
|
||||
label.opacity(1.).bg(cx
|
||||
.theme()
|
||||
.colors()
|
||||
.element_hover
|
||||
.opacity(0.5))
|
||||
})
|
||||
.tooltip(Tooltip::text("Jump to File"))
|
||||
.on_click(cx.listener(move |this, _, window, cx| {
|
||||
this.open_tool_call_location(entry_ix, 0, window, cx);
|
||||
}))
|
||||
.into_any_element()
|
||||
} else {
|
||||
self.render_markdown(
|
||||
tool_call.label.clone(),
|
||||
default_markdown_style(needs_confirmation, window, cx),
|
||||
)
|
||||
.into_any()
|
||||
}),
|
||||
)
|
||||
.child(
|
||||
h_flex()
|
||||
|
@ -988,15 +1021,19 @@ impl AcpThreadView {
|
|||
cx: &Context<Self>,
|
||||
) -> AnyElement {
|
||||
match content {
|
||||
ToolCallContent::Markdown { markdown } => self
|
||||
.render_markdown(markdown.clone(), default_markdown_style(false, window, cx))
|
||||
.into_any_element(),
|
||||
ToolCallContent::Markdown { markdown } => {
|
||||
div()
|
||||
.p_2()
|
||||
.child(self.render_markdown(
|
||||
markdown.clone(),
|
||||
default_markdown_style(false, window, cx),
|
||||
))
|
||||
.into_any_element()
|
||||
}
|
||||
ToolCallContent::Diff {
|
||||
diff: Diff {
|
||||
path, multibuffer, ..
|
||||
},
|
||||
diff: Diff { multibuffer, .. },
|
||||
..
|
||||
} => self.render_diff_editor(multibuffer, path),
|
||||
} => self.render_diff_editor(multibuffer),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1416,10 +1453,9 @@ impl AcpThreadView {
|
|||
}
|
||||
}
|
||||
|
||||
fn render_diff_editor(&self, multibuffer: &Entity<MultiBuffer>, path: &Path) -> AnyElement {
|
||||
fn render_diff_editor(&self, multibuffer: &Entity<MultiBuffer>) -> AnyElement {
|
||||
v_flex()
|
||||
.h_full()
|
||||
.child(path.to_string_lossy().to_string())
|
||||
.child(
|
||||
if let Some(editor) = self.diff_editors.get(&multibuffer.entity_id()) {
|
||||
editor.clone().into_any_element()
|
||||
|
@ -2076,6 +2112,64 @@ impl AcpThreadView {
|
|||
}
|
||||
}
|
||||
|
||||
fn open_tool_call_location(
|
||||
&self,
|
||||
entry_ix: usize,
|
||||
location_ix: usize,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Option<()> {
|
||||
let location = self
|
||||
.thread()?
|
||||
.read(cx)
|
||||
.entries()
|
||||
.get(entry_ix)?
|
||||
.locations()?
|
||||
.get(location_ix)?;
|
||||
|
||||
let project_path = self
|
||||
.project
|
||||
.read(cx)
|
||||
.find_project_path(&location.path, cx)?;
|
||||
|
||||
let open_task = self
|
||||
.workspace
|
||||
.update(cx, |worskpace, cx| {
|
||||
worskpace.open_path(project_path, None, true, window, cx)
|
||||
})
|
||||
.log_err()?;
|
||||
|
||||
window
|
||||
.spawn(cx, async move |cx| {
|
||||
let item = open_task.await?;
|
||||
|
||||
let Some(active_editor) = item.downcast::<Editor>() else {
|
||||
return anyhow::Ok(());
|
||||
};
|
||||
|
||||
active_editor.update_in(cx, |editor, window, cx| {
|
||||
let snapshot = editor.buffer().read(cx).snapshot(cx);
|
||||
let first_hunk = editor
|
||||
.diff_hunks_in_ranges(
|
||||
&[editor::Anchor::min()..editor::Anchor::max()],
|
||||
&snapshot,
|
||||
)
|
||||
.next();
|
||||
if let Some(first_hunk) = first_hunk {
|
||||
let first_hunk_start = first_hunk.multi_buffer_range().start;
|
||||
editor.change_selections(Default::default(), window, cx, |selections| {
|
||||
selections.select_anchor_ranges([first_hunk_start..first_hunk_start]);
|
||||
})
|
||||
}
|
||||
})?;
|
||||
|
||||
anyhow::Ok(())
|
||||
})
|
||||
.detach_and_log_err(cx);
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub fn open_thread_as_markdown(
|
||||
&self,
|
||||
workspace: Entity<Workspace>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue