Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions src/vs/sessions/contrib/chat/browser/chat.contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ import { ContextKeyExpr } from '../../../../platform/contextkey/common/contextke
import { ConfigurationScope, Extensions as ConfigurationExtensions, IConfigurationRegistry } from '../../../../platform/configuration/common/configurationRegistry.js';
import { IFileDialogService } from '../../../../platform/dialogs/common/dialogs.js';
import { IQuickInputService, IQuickPickItem, QuickPickInput } from '../../../../platform/quickinput/common/quickInput.js';
import product from '../../../../platform/product/common/product.js';
import { Registry } from '../../../../platform/registry/common/platform.js';
import { Extensions as WorkbenchConfigurationExtensions, IConfigurationMigrationRegistry } from '../../../../workbench/common/configuration.js';
import { registerWorkbenchContribution2, WorkbenchPhase } from '../../../../workbench/common/contributions.js';
import { ISessionsService } from '../../../services/sessions/browser/sessionsService.js';
import { ISessionsManagementService, inheritableSessionTarget } from '../../../services/sessions/common/sessionsManagement.js';
Expand Down Expand Up @@ -45,16 +48,16 @@ import { OpenSessionLinkOpenerContribution } from './openSessionLinkOpener.contr
import { WorktreeCreatedTaskDispatcher, AGENT_HOST_RUN_WORKTREE_CREATED_TASKS_SETTING } from './worktreeCreatedTaskDispatcher.js';
import { AGENT_SESSIONS_SCOPED_INPUT_HISTORY_SETTING } from './sessionsChatHistory.js';
import '../../sessions/browser/mobile/mobileOverlayContribution.js';
import { Registry } from '../../../../platform/registry/common/platform.js';
import { EditorAreaFocusContext, IsSessionsWindowContext, SideBarVisibleContext } from '../../../../workbench/common/contextkeys.js';
import { NEW_SESSION_ACTION_ID } from '../common/constants.js';
import { NEW_SESSION_ACTION_ID, UNIFIED_WORKSPACE_PICKER_SETTING } from '../common/constants.js';
import { SessionsChatBackgroundAvailableContext, SessionsChatBackgroundImageConfiguredContext, SessionsTitleBarNewSessionEnabledContext, SessionsWelcomeVisibleContext } from '../../../common/contextkeys.js';
import { Menus } from '../../../browser/menus.js';
import { ISessionsChatViewStateService, SessionsChatViewStateService } from './chatViewStateService.js';
import { SessionsChatResponseFileChangesService } from './sessionTurnChanges.js';
import { IChatResponseFileChangesService } from '../../../../workbench/contrib/chat/browser/chatResponseFileChangesService.js';
import { SessionsChatPetAchievementContribution } from './chatPetAchievements.js';
import { AGENT_SESSIONS_CHAT_BACKGROUND_CODICONS_PRESET, AGENT_SESSIONS_PREFERRED_DARK_CHAT_BACKGROUND_IMAGE_LAYOUT_SETTING, AGENT_SESSIONS_PREFERRED_DARK_CHAT_BACKGROUND_IMAGE_SETTING, AGENT_SESSIONS_PREFERRED_LIGHT_CHAT_BACKGROUND_IMAGE_LAYOUT_SETTING, AGENT_SESSIONS_PREFERRED_LIGHT_CHAT_BACKGROUND_IMAGE_SETTING, chatBackgroundImageLayoutValues, ChatBackgroundImageLayout, ISessionsChatBackgroundService, SessionsChatBackgroundService } from '../../../services/chatBackground/browser/chatBackgroundService.js';
import { LEGACY_UNIFIED_WORKSPACE_PICKER_SETTING, unifiedWorkspacePickerConfigurationMigration } from './unifiedWorkspacePickerConfiguration.js';

const CHANGE_AGENT_SESSIONS_CHAT_BACKGROUND_COMMAND_ID = 'workbench.action.chat.changeAgentSessionsBackground';
const CHANGE_AGENT_SESSIONS_CHAT_BACKGROUND_LAYOUT_COMMAND_ID = 'workbench.action.chat.changeAgentSessionsBackgroundLayout';
Expand Down Expand Up @@ -368,6 +371,20 @@ AccessibleViewRegistry.register(new SessionsChatAccessibilityHelp());
// register configuration
Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration).registerConfiguration({
properties: {
[LEGACY_UNIFIED_WORKSPACE_PICKER_SETTING]: {
type: 'boolean',
default: product.quality !== 'stable',
scope: ConfigurationScope.APPLICATION,
deprecationMessage: localize('chat.agentSessions.consolidatedRemoteWorkspaces.deprecated', "Deprecated. Use the unified workspace picker setting instead."),
},
[UNIFIED_WORKSPACE_PICKER_SETTING]: {
type: 'boolean',
default: product.quality !== 'stable',
scope: ConfigurationScope.APPLICATION,
description: localize('sessions.chat.unifiedWorkspacePicker.enabled', "Controls whether the Agents Window uses the unified workspace picker, which combines GitHub and remote workspaces, provides search, and, when supported, allows creating sessions with no workspace."),
tags: ['experimental'],
experiment: { mode: 'auto' },
},
[AGENT_HOST_RUN_WORKTREE_CREATED_TASKS_SETTING]: {
type: 'boolean',
default: true,
Expand Down Expand Up @@ -418,3 +435,5 @@ Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration).regis
},
},
});

Registry.as<IConfigurationMigrationRegistry>(WorkbenchConfigurationExtensions.ConfigurationMigration).registerConfigurationMigrations([unifiedWorkspacePickerConfigurationMigration]);
7 changes: 4 additions & 3 deletions src/vs/sessions/contrib/chat/browser/newChatWidget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,14 @@ import { chatInputStackClass, ChatInputStackSlot, setChatInputStackSlot } from '
import { IChatPetService } from '../../../../workbench/contrib/chat/browser/chatPetService.js';
import { IChatTipService } from '../../../../workbench/contrib/chat/browser/chatTipService.js';
import { ChatContextKeys } from '../../../../workbench/contrib/chat/common/actions/chatContextKeys.js';
import { ChatConfiguration, ChatModeKind } from '../../../../workbench/contrib/chat/common/constants.js';
import { ChatModeKind } from '../../../../workbench/contrib/chat/common/constants.js';
import { IOpenerService } from '../../../../platform/opener/common/opener.js';
import { IStorageService, StorageScope } from '../../../../platform/storage/common/storage.js';
import { TOTAL_SESSIONS_KEY } from '../../sessions/browser/sessionsLifecycleTracker.js';
import { INewSessionComposerService, NewSessionWorkspacePreselectionSource } from './newSessionComposerService.js';
import { Menus } from '../../../browser/menus.js';
import { getAdditionalFolderContextId, getAdditionalRepositoryContextId } from '../common/newChatContextIds.js';
import { UNIFIED_WORKSPACE_PICKER_SETTING } from '../common/constants.js';

// #region --- New Chat Widget ---

Expand Down Expand Up @@ -151,8 +152,8 @@ export class NewChatWidget extends Disposable {
});
this._useConsolidatedRemoteWorkspaces = observableFromEvent(
this,
Event.filter(this.configurationService.onDidChangeConfiguration, event => event.affectsConfiguration(ChatConfiguration.ConsolidatedRemoteWorkspaces)),
() => this.configurationService.getValue<boolean>(ChatConfiguration.ConsolidatedRemoteWorkspaces),
Event.filter(this.configurationService.onDidChangeConfiguration, event => event.affectsConfiguration(UNIFIED_WORKSPACE_PICKER_SETTING)),
() => this.configurationService.getValue<boolean>(UNIFIED_WORKSPACE_PICKER_SETTING),
);
this._isWorkspacePickerQuickChat = derived(this, reader => {
const session = this._session.read(reader);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,13 @@ import { markOnboardingTarget } from '../../../../workbench/contrib/onboarding/b
import { NewSessionWorkspacePreselectionSource } from './newSessionComposerService.js';
import { type IResolvedFolderWorkspace, SessionWorkspaceFallback } from './sessionWorkspaceFallback.js';
import { IChatRequestVariableEntry } from '../../../../workbench/contrib/chat/common/attachments/chatVariableEntries.js';
import { ChatConfiguration } from '../../../../workbench/contrib/chat/common/constants.js';
import { ADDITIONAL_FOLDER_CONTEXT_ID_PREFIX, ADDITIONAL_REPOSITORY_CONTEXT_ID_PREFIX, getAdditionalFolderContextId, getAdditionalRepositoryContextId } from '../common/newChatContextIds.js';
import { UNIFIED_WORKSPACE_PICKER_SETTING } from '../common/constants.js';

export type { IResolvedFolderWorkspace } from './sessionWorkspaceFallback.js';

const FILTER_THRESHOLD = 10;

export const AGENT_SESSIONS_CONSOLIDATED_REMOTE_WORKSPACES_SETTING = ChatConfiguration.ConsolidatedRemoteWorkspaces;

/**
* Fixed picker width when the categorical tab bar is shown. Keeps the tab
* row and the list aligned and prevents horizontal jitter when switching
Expand Down Expand Up @@ -1254,7 +1252,7 @@ export class WorkspacePicker extends Disposable {
}

protected _useConsolidatedRemoteWorkspaces(): boolean {
return this.configurationService.getValue<boolean>(AGENT_SESSIONS_CONSOLIDATED_REMOTE_WORKSPACES_SETTING);
return this.configurationService.getValue<boolean>(UNIFIED_WORKSPACE_PICKER_SETTING);
}

private _getTabGroup(group: string | undefined): string | undefined {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { ConfigurationKeyValuePairs, ConfigurationMigration } from '../../../../workbench/common/configuration.js';
import { UNIFIED_WORKSPACE_PICKER_SETTING } from '../common/constants.js';

export const LEGACY_UNIFIED_WORKSPACE_PICKER_SETTING = 'chat.agentSessions.consolidatedRemoteWorkspaces';

export const unifiedWorkspacePickerConfigurationMigration: ConfigurationMigration = {
key: LEGACY_UNIFIED_WORKSPACE_PICKER_SETTING,
includeApplication: true,
migrateFn: (value, accessor) => {
const pairs: ConfigurationKeyValuePairs = [[LEGACY_UNIFIED_WORKSPACE_PICKER_SETTING, { value: undefined }]];
if (accessor(UNIFIED_WORKSPACE_PICKER_SETTING) === undefined) {
pairs.push([UNIFIED_WORKSPACE_PICKER_SETTING, { value }]);
}
return pairs;
},
};
1 change: 1 addition & 0 deletions src/vs/sessions/contrib/chat/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
*--------------------------------------------------------------------------------------------*/

export const NEW_SESSION_ACTION_ID = 'workbench.action.sessions.newChat';
export const UNIFIED_WORKSPACE_PICKER_SETTING = 'sessions.chat.unifiedWorkspacePicker.enabled';
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ import { ISendRequestOptions, ISessionChangeEvent, ISessionsProvider } from '../
import { AgentHostFilterConnectionStatus, IAgentHostFilterEntry } from '../../../../services/agentHostFilter/common/agentHostFilter.js';
import { IAgentHostSessionsProvider } from '../../../../common/agentHostSessionsProvider.js';
import { ISession, ISessionWorkspace, ISessionWorkspaceBrowseAction, SessionStatus, SESSION_WORKSPACE_GROUP_GITHUB, SESSION_WORKSPACE_GROUP_LOCAL, SESSION_WORKSPACE_GROUP_REMOTE } from '../../../../services/sessions/common/session.js';
import { AGENT_SESSIONS_CONSOLIDATED_REMOTE_WORKSPACES_SETTING, IWorkspacePickerItem, IWorkspacePickerOptions, WorkspacePicker } from '../../browser/sessionWorkspacePicker.js';
import { IWorkspacePickerItem, IWorkspacePickerOptions, WorkspacePicker } from '../../browser/sessionWorkspacePicker.js';
import { UNIFIED_WORKSPACE_PICKER_SETTING } from '../../common/constants.js';
import { WebWorkspacePicker } from '../../browser/webWorkspacePicker.js';
import { NewSessionWorkspacePreselectionSource } from '../../browser/newSessionComposerService.js';
import { ISessionsRecentWorkspacesService, SessionsRecentWorkspacesService } from '../../../../services/sessions/browser/sessionsRecentWorkspacesService.js';
Expand Down Expand Up @@ -3050,7 +3051,7 @@ function createTestablePicker(
instantiationService.stub(IOutputService, {});
instantiationService.stub(IConfigurationService, new TestConfigurationService({
[RemoteAgentHostsEnabledSettingId]: remoteAgentHostsEnabled,
[AGENT_SESSIONS_CONSOLIDATED_REMOTE_WORKSPACES_SETTING]: consolidatedRemoteWorkspaces,
[UNIFIED_WORKSPACE_PICKER_SETTING]: consolidatedRemoteWorkspaces,
}));
instantiationService.stub(ICommandService, commandService);
instantiationService.stub(IFileDialogService, {});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import assert from 'assert';
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/test/common/utils.js';
import { LEGACY_UNIFIED_WORKSPACE_PICKER_SETTING, unifiedWorkspacePickerConfigurationMigration } from '../../browser/unifiedWorkspacePickerConfiguration.js';
import { UNIFIED_WORKSPACE_PICKER_SETTING } from '../../common/constants.js';

suite('UnifiedWorkspacePickerConfiguration', () => {

ensureNoDisposablesAreLeakedInTestSuite();

test('migrates application values without overwriting the new setting', async () => {
const copiedValue = await unifiedWorkspacePickerConfigurationMigration.migrateFn(true, () => undefined);
const preservedValue = await unifiedWorkspacePickerConfigurationMigration.migrateFn(false, key => key === UNIFIED_WORKSPACE_PICKER_SETTING ? true : undefined);

assert.deepStrictEqual({
key: unifiedWorkspacePickerConfigurationMigration.key,
includeApplication: unifiedWorkspacePickerConfigurationMigration.includeApplication,
copiedValue,
preservedValue,
}, {
key: LEGACY_UNIFIED_WORKSPACE_PICKER_SETTING,
includeApplication: true,
copiedValue: [
[LEGACY_UNIFIED_WORKSPACE_PICKER_SETTING, { value: undefined }],
[UNIFIED_WORKSPACE_PICKER_SETTING, { value: true }],
],
preservedValue: [
[LEGACY_UNIFIED_WORKSPACE_PICKER_SETTING, { value: undefined }],
],
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ import { registerExternalSessionsFilterMenu } from '../../../../../workbench/con
import { ICustomViewService } from '../../../../services/customView/browser/customViewService.js';
import { IAutomationService } from '../../../../../workbench/contrib/chat/common/automations/automationService.js';
import { ChatAutomationsEnabledContext } from '../../../../../workbench/contrib/chat/common/automations/automationsEnabled.js';
import { ChatConfiguration } from '../../../../../workbench/contrib/chat/common/constants.js';
import { AUTOMATIONS_CUSTOM_VIEW_ID } from '../automationsConstants.js';
import { UNIFIED_WORKSPACE_PICKER_SETTING } from '../../../chat/common/constants.js';

const CLOSE_SESSION_COMMAND_ID = 'sessionsViewPane.closeSession';
registerAction2(class CloseSessionAction extends Action2 {
Expand Down Expand Up @@ -546,7 +546,7 @@ registerAction2(class NewQuickChatAction extends Action2 {
const sessionsService = accessor.get(ISessionsService);
const sessionsPartService = accessor.get(ISessionsPartService);
let activeSession;
if (accessor.get(IConfigurationService).getValue<boolean>(ChatConfiguration.ConsolidatedRemoteWorkspaces)) {
if (accessor.get(IConfigurationService).getValue<boolean>(UNIFIED_WORKSPACE_PICKER_SETTING)) {
if (accessor.get(ISessionsManagementService).isQuickChatTargetAvailable()) {
sessionsService.unsetNewSession();
sessionsPartService.getSessionView(undefined)?.selectNoWorkspace();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import { IConfigurationService } from '../../../../../platform/configuration/com
import { TestConfigurationService } from '../../../../../platform/configuration/test/common/testConfigurationService.js';
import { TestInstantiationService } from '../../../../../platform/instantiation/test/common/instantiationServiceMock.js';
import { workbenchInstantiationService } from '../../../../../workbench/test/browser/workbenchTestServices.js';
import { ChatConfiguration } from '../../../../../workbench/contrib/chat/common/constants.js';
import { Menus } from '../../../../browser/menus.js';
import { SESSION_CONVERSATION_SIDE_CHATS_GROUP } from '../../../../browser/sessionConversationGroups.js';
import { SessionView } from '../../../../browser/parts/sessionView.js';
Expand All @@ -26,6 +25,7 @@ import { mock, upcastPartial } from '../../../../../base/test/common/mock.js';
import { SessionConversationActionsContribution } from '../../browser/sessionsActions.js';
import '../../browser/views/sessionsViewActions.js';
import { createTestSession } from './sessionsListTestUtils.js';
import { UNIFIED_WORKSPACE_PICKER_SETTING } from '../../../chat/common/constants.js';

suite('Sessions - Actions', () => {

Expand Down Expand Up @@ -136,7 +136,7 @@ suite('Sessions - Actions', () => {
let focusedSessionId: string | undefined;

instantiationService.stub(IConfigurationService, new TestConfigurationService({
[ChatConfiguration.ConsolidatedRemoteWorkspaces]: consolidatedRemoteWorkspaces,
[UNIFIED_WORKSPACE_PICKER_SETTING]: consolidatedRemoteWorkspaces,
}));
instantiationService.stub(ISessionsManagementService, new class extends mock<ISessionsManagementService>() {
override isQuickChatTargetAvailable(): boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -482,14 +482,6 @@ configurationRegistry.registerConfiguration({
experiment: { mode: 'auto' },
agentHost: { key: AgentHostShowExternalSessionsConfigKey },
},
[ChatConfiguration.ConsolidatedRemoteWorkspaces]: {
type: 'boolean',
default: product.quality !== 'stable',
scope: ConfigurationScope.APPLICATION,
description: nls.localize('chat.agentSessions.consolidatedRemoteWorkspaces', "Controls whether GitHub and remote workspaces are combined under Remote in the Agents Window workspace picker, with search always available and, when supported, a No workspace option."),
tags: ['experimental'],
experiment: { mode: 'auto' },
},
[ChatConfiguration.SaveBeforeSend]: {
type: 'boolean',
description: nls.localize('chat.saveBeforeSend', "Controls whether all dirty editors except untitled editors are saved before sending a chat message."),
Expand Down
1 change: 0 additions & 1 deletion src/vs/workbench/contrib/chat/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ export enum ChatConfiguration {
AgentSessionProjectionEnabled = 'chat.agentSessionProjection.enabled',
MigrateLegacyCopilotCliSessions = 'chat.agentSessions.migrateLegacyCopilotCli',
ShowExternalAgentSessions = 'chat.agentSessions.showExternal',
ConsolidatedRemoteWorkspaces = 'chat.agentSessions.consolidatedRemoteWorkspaces',
ExtensionToolsEnabled = 'chat.extensionTools.enabled',
RepoInfoEnabled = 'chat.repoInfo.enabled',
EditRequests = 'chat.editRequests',
Expand Down