Do not react on already observed buffer edits' versions (#46308)

If I apply

```diff
diff --git a/crates/action_log/src/action_log.rs b/crates/action_log/src/action_log.rs
index 404fb3616d..ece063c34f 100644
--- a/crates/action_log/src/action_log.rs
+++ b/crates/action_log/src/action_log.rs
@@ -223,6 +223,7 @@ impl ActionLog {
             futures::select_biased! {
                 buffer_update = buffer_updates.next() => {
                     if let Some((author, buffer_snapshot)) = buffer_update {
+                        dbg!(&author);
                         Self::track_edits(&this, &buffer, author, buffer_snapshot, cx).await?;
                     } else {
                         break;
```

on top of `main`, `User` and `Agent` will always interleave.

This happens because `action_log` does updates on `Entity<Buffer>` which
is a current editor's buffer, tracked, and updated by agent output (acp
or regular threads) — those updates come back as `BufferEvent::Edited`
event after each agent's edit and forces unnecessary computations.

Instead, update tracked buffer's version after each agent update report
to only react on one, `Agent`-authored, edit events.

Release Notes:

- N/A
This commit is contained in:
Kirill Bulatov 2026-01-08 19:09:24 +02:00 committed by GitHub
parent 8bbc3c36c4
commit 31343566e7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -131,7 +131,16 @@ impl ActionLog {
cx: &mut Context<Self>,
) {
match event {
BufferEvent::Edited => self.handle_buffer_edited(buffer, cx),
BufferEvent::Edited => {
let Some(tracked_buffer) = self.tracked_buffers.get_mut(&buffer) else {
return;
};
let buffer_version = buffer.read(cx).version();
if !buffer_version.changed_since(&tracked_buffer.version) {
return;
}
self.handle_buffer_edited(buffer, cx);
}
BufferEvent::FileHandleChanged => {
self.handle_buffer_file_changed(buffer, cx);
}
@ -464,10 +473,13 @@ impl ActionLog {
/// Mark a buffer as edited by agent, so we can refresh it in the context
pub fn buffer_edited(&mut self, buffer: Entity<Buffer>, cx: &mut Context<Self>) {
let new_version = buffer.read(cx).version();
let tracked_buffer = self.track_buffer_internal(buffer, false, cx);
if let TrackedBufferStatus::Deleted = tracked_buffer.status {
tracked_buffer.status = TrackedBufferStatus::Modified;
}
tracked_buffer.version = new_version;
tracked_buffer.schedule_diff_update(ChangeAuthor::Agent, cx);
}
@ -954,6 +966,7 @@ enum ChangeAuthor {
Agent,
}
#[derive(Debug)]
enum TrackedBufferStatus {
Created { existing_file_content: Option<Rope> },
Modified,