From eff592c447ba123a5aad8362cb66b37d6a543ece Mon Sep 17 00:00:00 2001 From: Danilo Leal <67129314+danilo-leal@users.noreply.github.com> Date: Mon, 24 Nov 2025 11:13:38 -0300 Subject: [PATCH] agent_ui: Refine "reject"/"keep" behavior when regenerating previous prompts (#43347) Closes https://github.com/zed-industries/zed/issues/42753 Consider the following flow: you submit prompt A. Prompt A generates some edits. You don't click on either "reject" or "keep"; they stay in a pending state. You then submit prompt B, but before the agent outputs any response, you click to edit prompt B, thus submitting a regeneration. Before this PR, the above flow would make the edits originated from prompt A to be auto-rejected. This feels very incorrect and can surprise users when they see that the edits that were pending got rejected. It feels more correct to only auto-reject changes if you're regenerating the prompt that directly generated those edits in the first place. Then, it also feels more correct to assume that if there was a follow-up prompt after some edits were made, those edits were passively "accepted". So, this is what this PR is doing. Consider the following flow to get a picture of the behavior change: - You submit prompt A. - Prompt A generates some edits. - You don't click on either "reject" or "keep"; they're pending. - You then submit prompt B, but before the agents outputs anything, you click to edit prompt B, submitting a regeneration. - Now, edits from prompt A will be auto-kept. Release Notes: - agent: Improved the "reject"/"keep" behavior when regenerating older prompts by auto-keeping pending edits that don't originate from the prompt to-be-regenerated. --- crates/agent_ui/src/acp/thread_view.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/crates/agent_ui/src/acp/thread_view.rs b/crates/agent_ui/src/acp/thread_view.rs index 3d387fc87c3377aed0278756b1c12644757e687d..92765140f5101034a30fc95db675ff335f2cb324 100644 --- a/crates/agent_ui/src/acp/thread_view.rs +++ b/crates/agent_ui/src/acp/thread_view.rs @@ -1273,6 +1273,28 @@ impl AcpThreadView { }; cx.spawn_in(window, async move |this, cx| { + // Check if there are any edits from prompts before the one being regenerated. + // + // If there are, we keep/accept them since we're not regenerating the prompt that created them. + // + // If editing the prompt that generated the edits, they are auto-rejected + // through the `rewind` function in the `acp_thread`. + let has_earlier_edits = thread.read_with(cx, |thread, _| { + thread + .entries() + .iter() + .take(entry_ix) + .any(|entry| entry.diffs().next().is_some()) + })?; + + if has_earlier_edits { + thread.update(cx, |thread, cx| { + thread.action_log().update(cx, |action_log, cx| { + action_log.keep_all_edits(None, cx); + }); + })?; + } + thread .update(cx, |thread, cx| thread.rewind(user_message_id, cx))? .await?;