Fix stale edits (#42895)

Closes #34069

<img width="532" height="880" alt="Screenshot 2025-11-17 at 11 14 19 AM"
src="https://github.com/user-attachments/assets/abc50c32-d54d-4310-a6e6-83008db7ed81"
/>

<img width="525" height="863" alt="Screenshot 2025-11-17 at 12 22 50 PM"
src="https://github.com/user-attachments/assets/15a69792-c2c7-4727-add9-c1f9baa5e665"
/>

Release Notes:

- Agent file edits now error if the file has changed since last read
(allowing the agent to read changes and avoid overwriting changes made
outside Zed)
This commit is contained in:
Richard Feldman
2025-11-17 12:23:18 -05:00
committed by GitHub
parent 4b050b651a
commit 23872b0523
6 changed files with 613 additions and 13 deletions
@@ -2,11 +2,12 @@
/// The tests in this file assume that server_cx is running on Windows too.
/// We neead to find a way to test Windows-Non-Windows interactions.
use crate::headless_project::HeadlessProject;
use agent::{AgentTool, ReadFileTool, ReadFileToolInput, ToolCallEventStream};
use agent::{AgentTool, ReadFileTool, ReadFileToolInput, Templates, Thread, ToolCallEventStream};
use client::{Client, UserStore};
use clock::FakeSystemClock;
use collections::{HashMap, HashSet};
use language_model::LanguageModelToolResultContent;
use language_model::{LanguageModelToolResultContent, fake_provider::FakeLanguageModel};
use prompt_store::ProjectContext;
use extension::ExtensionHostProxy;
use fs::{FakeFs, Fs};
@@ -1722,12 +1723,27 @@ async fn test_remote_agent_fs_tool_calls(cx: &mut TestAppContext, server_cx: &mu
let action_log = cx.new(|_| action_log::ActionLog::new(project.clone()));
// Create a minimal thread for the ReadFileTool
let context_server_registry =
cx.new(|cx| agent::ContextServerRegistry::new(project.read(cx).context_server_store(), cx));
let model = Arc::new(FakeLanguageModel::default());
let thread = cx.new(|cx| {
Thread::new(
project.clone(),
cx.new(|_cx| ProjectContext::default()),
context_server_registry,
Templates::new(),
Some(model),
cx,
)
});
let input = ReadFileToolInput {
path: "project/b.txt".into(),
start_line: None,
end_line: None,
};
let read_tool = Arc::new(ReadFileTool::new(project, action_log));
let read_tool = Arc::new(ReadFileTool::new(thread.downgrade(), project, action_log));
let (event_stream, _) = ToolCallEventStream::test();
let exists_result = cx.update(|cx| read_tool.clone().run(input, event_stream.clone(), cx));