parent
0bd65829f7
commit
6f6c2915b2
2 changed files with 115 additions and 13 deletions
|
@ -176,6 +176,14 @@ impl AgentThreadEntry {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn locations(&self) -> Option<&[acp::ToolCallLocation]> {
|
||||||
|
if let AgentThreadEntry::ToolCall(ToolCall { locations, .. }) = self {
|
||||||
|
Some(locations)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
|
@ -925,10 +925,43 @@ impl AcpThreadView {
|
||||||
.size(IconSize::Small)
|
.size(IconSize::Small)
|
||||||
.color(Color::Muted),
|
.color(Color::Muted),
|
||||||
)
|
)
|
||||||
.child(self.render_markdown(
|
.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(),
|
tool_call.label.clone(),
|
||||||
default_markdown_style(needs_confirmation, window, cx),
|
default_markdown_style(needs_confirmation, window, cx),
|
||||||
)),
|
)
|
||||||
|
.into_any()
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
h_flex()
|
h_flex()
|
||||||
|
@ -988,15 +1021,19 @@ impl AcpThreadView {
|
||||||
cx: &Context<Self>,
|
cx: &Context<Self>,
|
||||||
) -> AnyElement {
|
) -> AnyElement {
|
||||||
match content {
|
match content {
|
||||||
ToolCallContent::Markdown { markdown } => self
|
ToolCallContent::Markdown { markdown } => {
|
||||||
.render_markdown(markdown.clone(), default_markdown_style(false, window, cx))
|
div()
|
||||||
.into_any_element(),
|
.p_2()
|
||||||
|
.child(self.render_markdown(
|
||||||
|
markdown.clone(),
|
||||||
|
default_markdown_style(false, window, cx),
|
||||||
|
))
|
||||||
|
.into_any_element()
|
||||||
|
}
|
||||||
ToolCallContent::Diff {
|
ToolCallContent::Diff {
|
||||||
diff: Diff {
|
diff: Diff { multibuffer, .. },
|
||||||
path, 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()
|
v_flex()
|
||||||
.h_full()
|
.h_full()
|
||||||
.child(path.to_string_lossy().to_string())
|
|
||||||
.child(
|
.child(
|
||||||
if let Some(editor) = self.diff_editors.get(&multibuffer.entity_id()) {
|
if let Some(editor) = self.diff_editors.get(&multibuffer.entity_id()) {
|
||||||
editor.clone().into_any_element()
|
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(
|
pub fn open_thread_as_markdown(
|
||||||
&self,
|
&self,
|
||||||
workspace: Entity<Workspace>,
|
workspace: Entity<Workspace>,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue