Skip to content

fix: default session mode experiment not applying on first session#308905

Draft
andysharman wants to merge 1 commit intomicrosoft:mainfrom
andysharman:fix/default-mode-registration
Draft

fix: default session mode experiment not applying on first session#308905
andysharman wants to merge 1 commit intomicrosoft:mainfrom
andysharman:fix/default-mode-registration

Conversation

@andysharman
Copy link
Copy Markdown
Contributor

Fix: default session mode not applying on first session

Follows up on #306532.

The chat.newSession.defaultMode experiment wasn't applying because TAS and custom modes (like Plan) load asynchronously — after
the first session was already created.

Changes:

  • Remove static config registration that competed with the TAS-driven default
  • Add listeners to re-apply the default mode when the TAS config and custom modes become available

Both listeners are scoped to the session lifecycle and only fire while the session is empty.

Copilot AI review requested due to automatic review settings April 9, 2026 23:18
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

Fixes the “default new session mode” A/B experiment not applying for the first created chat session by ensuring the default mode is re-applied once asynchronous dependencies (TAS-registered setting and custom modes) become available.

Changes:

  • Stop statically registering chat.newSession.defaultMode so it no longer competes with the TAS-driven default.
  • When a session is empty, listen for config/mode availability changes and re-run the empty-session initialization logic to apply the intended default mode.
Show a summary per file
File Description
src/vs/workbench/contrib/chat/browser/widget/input/chatInputPart.ts Adds session-scoped listeners to re-apply empty-session defaults when the setting/modes become available.
src/vs/workbench/contrib/chat/browser/chat.contribution.ts Removes the static registration of chat.newSession.defaultMode to avoid competing defaults with TAS-driven registration.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 1

Comment on lines 902 to +916
if (chatSessionIsEmpty) {
this._setEmptyModelState();

// The default mode setting may be registered asynchronously by TAS,
// and custom modes (like Plan) load asynchronously from prompt files.
// Re-apply when either becomes available.
this._modelSyncDisposables.add(this.configurationService.onDidChangeConfiguration(e => {
if (this._chatSessionIsEmpty && e.affectsConfiguration(ChatConfiguration.DefaultNewSessionMode)) {
this._setEmptyModelState();
}
}));
this._modelSyncDisposables.add(this.chatModeService.onDidChangeChatModes(() => {
if (this._chatSessionIsEmpty) {
this._setEmptyModelState();
}
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

These listeners call _setEmptyModelState() whenever the default-mode setting becomes available or chat modes change, as long as _chatSessionIsEmpty is true. That can override a mode the user manually selected before sending their first message (the session is still “empty”, but the user intent is already captured in the input model).

Consider gating this re-apply so it only runs if the user hasn’t changed mode/input state yet (e.g., only when the input model has no state yet, or track a "defaultApplied"/"userInteracted" flag).

Suggested change
if (chatSessionIsEmpty) {
this._setEmptyModelState();
// The default mode setting may be registered asynchronously by TAS,
// and custom modes (like Plan) load asynchronously from prompt files.
// Re-apply when either becomes available.
this._modelSyncDisposables.add(this.configurationService.onDidChangeConfiguration(e => {
if (this._chatSessionIsEmpty && e.affectsConfiguration(ChatConfiguration.DefaultNewSessionMode)) {
this._setEmptyModelState();
}
}));
this._modelSyncDisposables.add(this.chatModeService.onDidChangeChatModes(() => {
if (this._chatSessionIsEmpty) {
this._setEmptyModelState();
}
const canApplyEmptyModelState = () => {
return this._chatSessionIsEmpty && this._inputModel === model && !model.state.get();
};
const applyEmptyModelStateIfNeeded = () => {
if (canApplyEmptyModelState()) {
this._setEmptyModelState();
}
};
if (chatSessionIsEmpty) {
applyEmptyModelStateIfNeeded();
// The default mode setting may be registered asynchronously by TAS,
// and custom modes (like Plan) load asynchronously from prompt files.
// Re-apply when either becomes available, but only while the input
// model still has no explicit state of its own.
this._modelSyncDisposables.add(this.configurationService.onDidChangeConfiguration(e => {
if (e.affectsConfiguration(ChatConfiguration.DefaultNewSessionMode)) {
applyEmptyModelStateIfNeeded();
}
}));
this._modelSyncDisposables.add(this.chatModeService.onDidChangeChatModes(() => {
applyEmptyModelStateIfNeeded();

Copilot uses AI. Check for mistakes.
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