Improve claude tools (#36538)

- Return unified diff from `Edit` tool so model can see the final state
- Format on save if enabled
- Provide `Write` tool
- Disable `MultiEdit` tool
- Better prompting

Release Notes:

- N/A
This commit is contained in:
Agus Zubiaga 2025-08-19 22:42:11 -03:00 committed by GitHub
parent 714c36fa7b
commit 7c7043947b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 606 additions and 302 deletions

View file

@ -3,9 +3,12 @@ mod diff;
mod mention;
mod terminal;
use collections::HashSet;
pub use connection::*;
pub use diff::*;
use language::language_settings::FormatOnSave;
pub use mention::*;
use project::lsp_store::{FormatTrigger, LspFormatTarget};
use serde::{Deserialize, Serialize};
pub use terminal::*;
@ -1051,6 +1054,22 @@ impl AcpThread {
})
}
pub fn tool_call(&mut self, id: &acp::ToolCallId) -> Option<(usize, &ToolCall)> {
self.entries
.iter()
.enumerate()
.rev()
.find_map(|(index, tool_call)| {
if let AgentThreadEntry::ToolCall(tool_call) = tool_call
&& &tool_call.id == id
{
Some((index, tool_call))
} else {
None
}
})
}
pub fn resolve_locations(&mut self, id: acp::ToolCallId, cx: &mut Context<Self>) {
let project = self.project.clone();
let Some((_, tool_call)) = self.tool_call_mut(&id) else {
@ -1601,30 +1620,59 @@ impl AcpThread {
.collect::<Vec<_>>()
})
.await;
cx.update(|cx| {
project.update(cx, |project, cx| {
project.set_agent_location(
Some(AgentLocation {
buffer: buffer.downgrade(),
position: edits
.last()
.map(|(range, _)| range.end)
.unwrap_or(Anchor::MIN),
}),
cx,
);
});
project.update(cx, |project, cx| {
project.set_agent_location(
Some(AgentLocation {
buffer: buffer.downgrade(),
position: edits
.last()
.map(|(range, _)| range.end)
.unwrap_or(Anchor::MIN),
}),
cx,
);
})?;
let format_on_save = cx.update(|cx| {
action_log.update(cx, |action_log, cx| {
action_log.buffer_read(buffer.clone(), cx);
});
buffer.update(cx, |buffer, cx| {
let format_on_save = buffer.update(cx, |buffer, cx| {
buffer.edit(edits, None, cx);
let settings = language::language_settings::language_settings(
buffer.language().map(|l| l.name()),
buffer.file(),
cx,
);
settings.format_on_save != FormatOnSave::Off
});
action_log.update(cx, |action_log, cx| {
action_log.buffer_edited(buffer.clone(), cx);
});
format_on_save
})?;
if format_on_save {
let format_task = project.update(cx, |project, cx| {
project.format(
HashSet::from_iter([buffer.clone()]),
LspFormatTarget::Buffers,
false,
FormatTrigger::Save,
cx,
)
})?;
format_task.await.log_err();
action_log.update(cx, |action_log, cx| {
action_log.buffer_edited(buffer.clone(), cx);
})?;
}
project
.update(cx, |project, cx| project.save_buffer(buffer, cx))?
.await