Skip to content

Add chat.agent.autoAccept setting to auto-accept agent changes#307685

Draft
pierceboggan wants to merge 7 commits intomainfrom
pierceboggan/auto-accept-agent-changes
Draft

Add chat.agent.autoAccept setting to auto-accept agent changes#307685
pierceboggan wants to merge 7 commits intomainfrom
pierceboggan/auto-accept-agent-changes

Conversation

@pierceboggan
Copy link
Copy Markdown
Contributor

@pierceboggan pierceboggan commented Apr 3, 2026

Summary

Adds a new boolean setting chat.agent.autoAccept (default: false) that, when enabled, removes the Keep/Undo review UX and immediately auto-accepts all agent changes when a request completes.

Experience before/after shown here:

Auto-Accept.mov

Motivation

Users who trust agent changes and don't want to manually review each edit can enable this setting to streamline their workflow — changes are applied and accepted automatically without requiring interaction with the Keep/Undo UI.

Approach

Auto-accept logic (chatEditingModifiedFileEntry.ts): When the setting is enabled, reviewMode is set to false and the auto-accept timeout is set to 0, causing changes to be accepted immediately when the agent turn completes.

Hide Keep/Undo buttons across all surfaces:

  • Chat panel (chatEditingActions.ts): Keep All, Undo All, and per-file Keep/Undo buttons are hidden via config.chat.agent.autoAccept when-clause guards
  • Editor overlay: Already gated by ctxReviewModeEnabled, which becomes false automatically
  • Multi-diff editor (chatEditingEditorActions.ts): Keep/Undo in the EditorTitle toolbar and per-file MultiDiffEditorFileToolbar are hidden

Preserve files-changed bar (chatInputPart.ts): The bar above the chat input (showing changed files + Explain button) is kept visible after auto-accept by including Accepted entries in the file list, not just Modified ones.

Snapshot line counts (chatEditingModifiedFileEntry.ts, chatEditingService.ts): When accept() fires, _doAccept() resets the diff (original = modified), zeroing out linesAdded/linesRemoved. To preserve accurate counts in the UI, line counts are snapshotted on the entry in acceptDeferred() before the diff reset. The UI reads snapshotLinesAdded/snapshotLinesRemoved as fallback values.

How to test

  1. Open Settings, search for chat.agent.autoAccept, enable it
  2. Send an agent request that modifies files
  3. Verify:
    • No Keep/Undo buttons appear in the chat panel, editor overlay, or multi-diff editor
    • Changes are auto-accepted when the agent turn completes
    • The files-changed bar persists with correct +N -M line counts
    • The Explain button and file list remain visible

pierceboggan and others added 7 commits April 3, 2026 11:16
When enabled, this setting:
- Immediately auto-accepts all agent changes when the request completes
- Disables review mode so the editor Keep/Undo overlay buttons are hidden
- Hides Keep/Undo buttons in the chat panel (both per-file and Accept/Undo All)

The setting works alongside the existing chat.editing.autoAcceptDelay (which provides
a countdown-based auto-accept). When autoAccept is true, it takes precedence.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When autoAccept is on, include all entries (not just Modified) in the
files-changed bar above the chat input. This preserves the file list
and Explain button while still hiding Keep/Undo buttons.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The entries observable returns readonly IModifiedFileEntry[] which
isn't assignable to the mutable array type. Use spread operator to
create a mutable copy.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When auto-accept fires, the diff is reset (original matches modified),
so linesAdded/linesRemoved go to 0. Cache the values while the entry
is still Modified so the files-changed bar shows accurate counts.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The cachedDiffMeta map was local to renderChatEditingSessionState,
getting recreated on each call. Move it to a class-level field so
cached line counts survive when the method is called again after
auto-accept triggers a re-render.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Instead of caching at the UI layer, snapshot linesAdded/linesRemoved
directly on the entry in acceptDeferred() before _doAccept() resets
the diff. The UI reads snapshotLinesAdded/snapshotLinesRemoved as
fallback values when the live diff returns 0 after acceptance.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add autoAccept guard to:
- MultiDiffAcceptDiscardAction (EditorTitle toolbar)
- Per-file Accept/Discard in MultiDiffEditorFileToolbar

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new chat.agent.autoAccept boolean setting to automatically accept agent-applied edits (removing the Keep/Undo review UX) and adjusts UI surfaces to remain useful after auto-accept (e.g., preserving file change counts).

Changes:

  • Introduces chat.agent.autoAccept configuration and wires it into chat editing review/auto-accept behavior.
  • Hides Keep/Undo actions in chat editing toolbars and multi-diff editor toolbars when auto-accept is enabled.
  • Preserves the files-changed bar (+/- line counts) after accept by snapshotting counts before accept resets the diff and by including accepted entries in the list.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/vs/workbench/contrib/chat/common/editing/chatEditingService.ts Extends IModifiedFileEntry with snapshot line-count observables for post-accept display.
src/vs/workbench/contrib/chat/common/constants.ts Adds ChatConfiguration.AutoAccept key for chat.agent.autoAccept.
src/vs/workbench/contrib/chat/browser/widget/input/chatInputPart.ts Keeps the “files changed” bar populated after auto-accept and uses snapshot counts as fallback.
src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingModifiedFileEntry.ts Applies auto-accept setting to review mode/timeout and snapshots line counts on accept.
src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingEditorActions.ts Hides multi-diff “Keep/Undo All” editor title actions when auto-accept is enabled.
src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingActions.ts Hides Keep/Undo actions across chat editing widget and multi-diff file toolbars when auto-accept is enabled.
src/vs/workbench/contrib/chat/browser/chat.contribution.ts Registers the new chat.agent.autoAccept setting in configuration.

Comment on lines +2816 to 2828
const autoAcceptEnabled = this.configurationService.getValue<boolean>(ChatConfiguration.AutoAccept);

const modifiedEntries = derivedOpts<IModifiedFileEntry[]>({ equalsFn: arraysEqual }, r => {
// Background chat sessions render the working set based on the session files, and not the editing session
const sessionResource = chatEditingSession?.chatSessionResource ?? this._widget?.viewModel?.model.sessionResource;
if (sessionResource && getChatSessionType(sessionResource) === AgentSessionProviders.Background) {
return [];
}

if (autoAcceptEnabled) {
return [...(chatEditingSession?.entries.read(r) || [])];
}
return chatEditingSession?.entries.read(r).filter(entry => entry.state.read(r) === ModifiedFileEntryState.Modified) || [];
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

autoAcceptEnabled is read once via configurationService.getValue(...) and then captured by the derived observables below. Because it isn’t an observable, toggling chat.agent.autoAccept at runtime won’t cause modifiedEntries / editSessionEntries to recompute, so the files-changed bar can get stuck showing the wrong set of entries until something else triggers a full re-render. Consider using an observable config (e.g. observableConfigValue(ChatConfiguration.AutoAccept, ...)) or wiring onDidChangeConfiguration into an observable that the derived computations read.

Copilot uses AI. Check for mistakes.
Comment on lines +2842 to +2843
const snapshotAdded = entry.snapshotLinesAdded?.read(reader);
const snapshotRemoved = entry.snapshotLinesRemoved?.read(reader);
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

snapshotLinesAdded/Removed are used as an unconditional fallback for all states. If a file is accepted (snapshots set) and then later receives additional edits (entry transitions back to Modified), the stale snapshot values will continue to override the live linesAdded/linesRemoved values, causing incorrect +/- counts until the next accept. Suggested fix: only prefer snapshot values when state === ModifiedFileEntryState.Accepted (or clear the snapshot observables when the entry returns to Modified).

Suggested change
const snapshotAdded = entry.snapshotLinesAdded?.read(reader);
const snapshotRemoved = entry.snapshotLinesRemoved?.read(reader);
const useSnapshotDiff = state === ModifiedFileEntryState.Accepted;
const snapshotAdded = useSnapshotDiff ? entry.snapshotLinesAdded?.read(reader) : undefined;
const snapshotRemoved = useSnapshotDiff ? entry.snapshotLinesRemoved?.read(reader) : undefined;

Copilot uses AI. Check for mistakes.
Comment on lines +248 to +252
// Snapshot line counts before accept resets the diff
const self = this as IModifiedFileEntry;
this._snapshotLinesAdded.set(self.linesAdded?.get() ?? 0, undefined);
this._snapshotLinesRemoved.set(self.linesRemoved?.get() ?? 0, undefined);

Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new snapshot observables are written on accept, but they are never cleared. Entries can transition back to Modified when additional agent edits arrive (several acceptAgentEdits implementations set _stateObs back to Modified unconditionally), which risks stale snapshot values being reused for subsequent edit cycles. Consider clearing _snapshotLinesAdded/_snapshotLinesRemoved whenever the entry goes back to Modified (e.g. at the start of acceptAgentEdits in concrete entry types) or only treating snapshots as valid while in Accepted state.

Copilot uses AI. Check for mistakes.
Comment on lines +422 to +431
/**
* Snapshot of lines added, captured before accept resets the diff.
*/
readonly snapshotLinesAdded?: IObservable<number | undefined>;

/**
* Snapshot of lines removed, captured before accept resets the diff.
*/
readonly snapshotLinesRemoved?: IObservable<number | undefined>;

Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

linesAdded/linesRemoved are derived from the current diff and become 0 after accept() resets the models (e.g. keep() makes original === modified). With auto-accept enabled, this means any code that computes session stats after acceptance (e.g. awaitStatsForSession in chat/common/chat.ts) will likely report 0/undefined changes. If these snapshot observables are the new source of truth post-accept, consider updating the stats aggregation (and any other summaries) to use snapshotLinesAdded/Removed when available and the entry is Accepted.

Copilot uses AI. Check for mistakes.
@amunger
Copy link
Copy Markdown
Collaborator

amunger commented Apr 3, 2026

it would be nice if we could just modify chat.editing.autoAcceptDelay instead of adding a new setting: 0 could mean accept immediately, and make -1 turn it off. currently, 0 means off

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants