diff --git a/.vscode/extensions/vscode-selfhost-test-provider/src/extension.ts b/.vscode/extensions/vscode-selfhost-test-provider/src/extension.ts index cbb8d50bf99..2f9ac62abe4 100644 --- a/.vscode/extensions/vscode-selfhost-test-provider/src/extension.ts +++ b/.vscode/extensions/vscode-selfhost-test-provider/src/extension.ts @@ -45,7 +45,7 @@ export async function activate(context: vscode.ExtensionContext) { context.subscriptions.push(vscode.tests.registerTestFollowupProvider({ async provideFollowup(_result, test, taskIndex, messageIndex, _token) { return [{ - title: '$(sparkle) Fix with Copilot', + title: '$(sparkle) Fix', command: 'github.copilot.tests.fixTestFailure', arguments: [{ source: 'peekFollowup', test, message: test.taskStates[taskIndex].messages[messageIndex] }] }]; diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts b/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts index 666308c49ae..bed78771f07 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts @@ -70,7 +70,7 @@ import { ChatAgentLocation, ChatConfiguration, ChatModeKind, AGENT_SESSIONS_VIEW import { ILanguageModelChatSelector, ILanguageModelsService } from '../../common/languageModels.js'; import { CopilotUsageExtensionFeatureId } from '../../common/languageModelStats.js'; import { ILanguageModelToolsService } from '../../common/languageModelToolsService.js'; -import { ChatViewId, IChatWidget, IChatWidgetService, showChatView, showCopilotView } from '../chat.js'; +import { ChatViewId, IChatWidget, IChatWidgetService, showChatView } from '../chat.js'; import { IChatEditorOptions } from '../chatEditor.js'; import { ChatEditorInput, shouldShowClearEditingSessionConfirmation, showClearEditingSessionConfirmation } from '../chatEditorInput.js'; import { ChatViewPane } from '../chatViewPane.js'; @@ -193,6 +193,7 @@ abstract class OpenChatGlobalAction extends Action2 { const widgetService = accessor.get(IChatWidgetService); const toolsService = accessor.get(ILanguageModelToolsService); const viewsService = accessor.get(IViewsService); + const layoutService = accessor.get(IWorkbenchLayoutService); const hostService = accessor.get(IHostService); const chatAgentService = accessor.get(IChatAgentService); const instaService = accessor.get(IInstantiationService); @@ -206,7 +207,7 @@ abstract class OpenChatGlobalAction extends Action2 { // When this was invoked to switch to a mode via keybinding, and some chat widget is focused, use that one. // Otherwise, open the view. if (!this.mode || !chatWidget || !isAncestorOfActiveElement(chatWidget.domNode)) { - chatWidget = await showChatView(viewsService); + chatWidget = await showChatView(viewsService, layoutService); } if (!chatWidget) { @@ -480,7 +481,7 @@ export function registerChatActions() { this.updatePartVisibility(layoutService, chatLocation, false); } else { this.updatePartVisibility(layoutService, chatLocation, true); - (await showCopilotView(viewsService, layoutService))?.focusInput(); + (await showChatView(viewsService, layoutService))?.focusInput(); } } @@ -1158,9 +1159,10 @@ export function registerChatActions() { async run(accessor: ServicesAccessor) { const viewsService = accessor.get(IViewsService); + const layoutService = accessor.get(IWorkbenchLayoutService); // Open the chat view in the sidebar and get the widget - const chatWidget = await showChatView(viewsService); + const chatWidget = await showChatView(viewsService, layoutService); if (chatWidget) { // Clear the current chat to start a new one diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatContextActions.ts b/src/vs/workbench/contrib/chat/browser/actions/chatContextActions.ts index a9bcf5423ae..1bc9a6fa925 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatContextActions.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatContextActions.ts @@ -35,6 +35,7 @@ import { ResourceContextKey } from '../../../../common/contextkeys.js'; import { EditorResourceAccessor, isEditorCommandsContext, SideBySideEditor } from '../../../../common/editor.js'; import { IEditorGroupsService } from '../../../../services/editor/common/editorGroupsService.js'; import { IEditorService } from '../../../../services/editor/common/editorService.js'; +import { IWorkbenchLayoutService } from '../../../../services/layout/browser/layoutService.js'; import { IViewsService } from '../../../../services/views/common/viewsService.js'; import { ExplorerFolderContext } from '../../../files/common/files.js'; import { AnythingQuickAccessProvider } from '../../../search/browser/anythingQuickAccess.js'; @@ -66,10 +67,11 @@ export function registerChatContextActions() { async function withChatView(accessor: ServicesAccessor): Promise { const viewsService = accessor.get(IViewsService); const chatWidgetService = accessor.get(IChatWidgetService); + const layoutService = accessor.get(IWorkbenchLayoutService); const lastFocusedWidget = chatWidgetService.lastFocusedWidget; if (!lastFocusedWidget || lastFocusedWidget.location === ChatAgentLocation.Chat) { - return showChatView(viewsService); // only show chat view if we either have no chat view or its located in view container + return showChatView(viewsService, layoutService); // only show chat view if we either have no chat view or its located in view container } return lastFocusedWidget; } diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatGettingStarted.ts b/src/vs/workbench/contrib/chat/browser/actions/chatGettingStarted.ts index e87ed5854b6..852880b6bac 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatGettingStarted.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatGettingStarted.ts @@ -12,8 +12,8 @@ import { IExtensionManagementService, InstallOperation } from '../../../../../pl import { IStorageService, StorageScope, StorageTarget } from '../../../../../platform/storage/common/storage.js'; import { IDefaultChatAgent } from '../../../../../base/common/product.js'; import { IWorkbenchLayoutService } from '../../../../services/layout/browser/layoutService.js'; -import { showCopilotView } from '../chat.js'; import { IViewsService } from '../../../../services/views/common/viewsService.js'; +import { showChatView } from '../chat.js'; export class ChatGettingStartedContribution extends Disposable implements IWorkbenchContribution { static readonly ID = 'workbench.contrib.chatGettingStarted'; @@ -66,8 +66,8 @@ export class ChatGettingStartedContribution extends Disposable implements IWorkb private async onDidInstallChat() { - // Open Copilot view - showCopilotView(this.viewsService, this.layoutService); + // Open Chat view + showChatView(this.viewsService, this.layoutService); // Only do this once this.storageService.store(ChatGettingStartedContribution.hideWelcomeView, true, StorageScope.APPLICATION, StorageTarget.MACHINE); diff --git a/src/vs/workbench/contrib/chat/browser/chat.ts b/src/vs/workbench/contrib/chat/browser/chat.ts index a49b3f71e0d..10bbc7de8a8 100644 --- a/src/vs/workbench/contrib/chat/browser/chat.ts +++ b/src/vs/workbench/contrib/chat/browser/chat.ts @@ -66,19 +66,14 @@ export async function showChatWidgetInViewOrEditor(accessor: ServicesAccessor, w } } - -export async function showChatView(viewsService: IViewsService): Promise { - return (await viewsService.openView(ChatViewId))?.widget; -} - -export function showCopilotView(viewsService: IViewsService, layoutService: IWorkbenchLayoutService): Promise { +export async function showChatView(viewsService: IViewsService, layoutService: IWorkbenchLayoutService): Promise { // Ensure main window is in front if (layoutService.activeContainer !== layoutService.mainContainer) { layoutService.mainContainer.focus(); } - return showChatView(viewsService); + return (await viewsService.openView(ChatViewId))?.widget; } export const IQuickChatService = createDecorator('quickChatService'); diff --git a/src/vs/workbench/contrib/chat/browser/chatContentParts/chatConfirmationWidget.ts b/src/vs/workbench/contrib/chat/browser/chatContentParts/chatConfirmationWidget.ts index fd67aa14e0e..9fa0b918370 100644 --- a/src/vs/workbench/contrib/chat/browser/chatContentParts/chatConfirmationWidget.ts +++ b/src/vs/workbench/contrib/chat/browser/chatContentParts/chatConfirmationWidget.ts @@ -26,6 +26,7 @@ import { IHostService } from '../../../../services/host/browser/host.js'; import { IViewsService } from '../../../../services/views/common/viewsService.js'; import { showChatView } from '../chat.js'; import './media/chatConfirmationWidget.css'; +import { IWorkbenchLayoutService } from '../../../../services/layout/browser/layoutService.js'; export interface IChatConfirmationButton { label: string; @@ -141,6 +142,7 @@ abstract class BaseSimpleChatConfirmationWidget extends Disposable { @IHostService private readonly _hostService: IHostService, @IViewsService private readonly _viewsService: IViewsService, @IContextKeyService contextKeyService: IContextKeyService, + @IWorkbenchLayoutService private readonly _layoutService: IWorkbenchLayoutService, ) { super(); @@ -262,7 +264,7 @@ abstract class BaseSimpleChatConfirmationWidget extends Disposable { disposables.add(Event.once(notification.onClick)(() => { this._hostService.focus(targetWindow, { mode: FocusMode.Force }); - showChatView(this._viewsService); + showChatView(this._viewsService, this._layoutService); })); disposables.add(this._hostService.onDidChangeFocus(focus => { @@ -288,8 +290,9 @@ export class SimpleChatConfirmationWidget extends BaseSimpleChatConfirmationW @IHostService hostService: IHostService, @IViewsService viewsService: IViewsService, @IContextKeyService contextKeyService: IContextKeyService, + @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService, ) { - super(options, instantiationService, markdownRendererService, contextMenuService, configurationService, hostService, viewsService, contextKeyService); + super(options, instantiationService, markdownRendererService, contextMenuService, configurationService, hostService, viewsService, contextKeyService, layoutService); this.updateMessage(options.message); } @@ -349,6 +352,7 @@ abstract class BaseChatConfirmationWidget extends Disposable { @IHostService private readonly _hostService: IHostService, @IViewsService private readonly _viewsService: IViewsService, @IContextKeyService contextKeyService: IContextKeyService, + @IWorkbenchLayoutService private readonly _layoutService: IWorkbenchLayoutService, ) { super(); @@ -490,7 +494,7 @@ abstract class BaseChatConfirmationWidget extends Disposable { disposables.add(Event.once(notification.onClick)(() => { this._hostService.focus(targetWindow, { mode: FocusMode.Force }); - showChatView(this._viewsService); + showChatView(this._viewsService, this._layoutService); })); disposables.add(this._hostService.onDidChangeFocus(focus => { @@ -514,8 +518,9 @@ export class ChatConfirmationWidget extends BaseChatConfirmationWidget { @IHostService hostService: IHostService, @IViewsService viewsService: IViewsService, @IContextKeyService contextKeyService: IContextKeyService, + @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService, ) { - super(options, instantiationService, markdownRendererService, contextMenuService, configurationService, hostService, viewsService, contextKeyService); + super(options, instantiationService, markdownRendererService, contextMenuService, configurationService, hostService, viewsService, contextKeyService, layoutService); this.renderMessage(options.message, this._container); } @@ -540,8 +545,9 @@ export class ChatCustomConfirmationWidget extends BaseChatConfirmationWidget< @IHostService hostService: IHostService, @IViewsService viewsService: IViewsService, @IContextKeyService contextKeyService: IContextKeyService, + @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService, ) { - super(options, instantiationService, markdownRendererService, contextMenuService, configurationService, hostService, viewsService, contextKeyService); + super(options, instantiationService, markdownRendererService, contextMenuService, configurationService, hostService, viewsService, contextKeyService, layoutService); this.renderMessage(options.message, container); } } diff --git a/src/vs/workbench/contrib/chat/browser/chatEditing/simpleBrowserEditorOverlay.ts b/src/vs/workbench/contrib/chat/browser/chatEditing/simpleBrowserEditorOverlay.ts index 5015b2af65c..f0e9820dd0a 100644 --- a/src/vs/workbench/contrib/chat/browser/chatEditing/simpleBrowserEditorOverlay.ts +++ b/src/vs/workbench/contrib/chat/browser/chatEditing/simpleBrowserEditorOverlay.ts @@ -37,6 +37,7 @@ import { IBrowserElementsService } from '../../../../services/browserElements/br import { IContextMenuService } from '../../../../../platform/contextview/browser/contextView.js'; import { IAction, toAction } from '../../../../../base/common/actions.js'; import { BrowserType } from '../../../../../platform/browserElements/common/browserElements.js'; +import { IWorkbenchLayoutService } from '../../../../services/layout/browser/layoutService.js'; class SimpleBrowserOverlayWidget { @@ -63,6 +64,7 @@ class SimpleBrowserOverlayWidget { @IPreferencesService private readonly _preferencesService: IPreferencesService, @IBrowserElementsService private readonly _browserElementsService: IBrowserElementsService, @IContextMenuService private readonly contextMenuService: IContextMenuService, + @IWorkbenchLayoutService private readonly _layoutService: IWorkbenchLayoutService, ) { this._showStore.add(this.configurationService.onDidChangeConfiguration(e => { if (e.affectsConfiguration('chat.sendElementsToChat.enabled')) { @@ -253,7 +255,7 @@ class SimpleBrowserOverlayWidget { const bounds = elementData.bounds; const toAttach: IChatRequestVariableEntry[] = []; - const widget = await showChatView(this._viewService) ?? this._chatWidgetService.lastFocusedWidget; + const widget = await showChatView(this._viewService, this._layoutService) ?? this._chatWidgetService.lastFocusedWidget; let value = 'Attached HTML and CSS Context\n\n' + elementData.outerHTML; if (this.configurationService.getValue('chat.sendElementsToChat.attachCSS')) { value += '\n\n' + elementData.computedStyle; diff --git a/src/vs/workbench/contrib/chat/browser/chatParticipant.contribution.ts b/src/vs/workbench/contrib/chat/browser/chatParticipant.contribution.ts index f9404af1a5a..a1c2acbdd72 100644 --- a/src/vs/workbench/contrib/chat/browser/chatParticipant.contribution.ts +++ b/src/vs/workbench/contrib/chat/browser/chatParticipant.contribution.ts @@ -329,7 +329,7 @@ export class ChatCompatibilityNotifier extends Disposable implements IWorkbenchC super(); // It may be better to have some generic UI for this, for any extension that is incompatible, - // but this is only enabled for Copilot Chat now and it needs to be obvious. + // but this is only enabled for Chat now and it needs to be obvious. const isInvalid = ChatContextKeys.extensionInvalid.bindTo(contextKeyService); this._register(Event.runAndSubscribe( extensionsWorkbenchService.onDidChangeExtensionsNotification, diff --git a/src/vs/workbench/contrib/chat/browser/chatQuick.ts b/src/vs/workbench/contrib/chat/browser/chatQuick.ts index 8220b7357f8..92f7f0ffea6 100644 --- a/src/vs/workbench/contrib/chat/browser/chatQuick.ts +++ b/src/vs/workbench/contrib/chat/browser/chatQuick.ts @@ -17,13 +17,13 @@ import { MenuId } from '../../../../platform/actions/common/actions.js'; import { IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js'; import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js'; import { ServiceCollection } from '../../../../platform/instantiation/common/serviceCollection.js'; -import { ILayoutService } from '../../../../platform/layout/browser/layoutService.js'; import { IMarkdownRendererService } from '../../../../platform/markdown/browser/markdownRenderer.js'; import product from '../../../../platform/product/common/product.js'; import { IQuickInputService, IQuickWidget } from '../../../../platform/quickinput/common/quickInput.js'; import { editorBackground, inputBackground, quickInputBackground, quickInputForeground } from '../../../../platform/theme/common/colorRegistry.js'; import { EDITOR_DRAG_AND_DROP_BACKGROUND } from '../../../common/theme.js'; import { IChatEntitlementService } from '../../../services/chat/common/chatEntitlementService.js'; +import { IWorkbenchLayoutService } from '../../../services/layout/browser/layoutService.js'; import { IViewsService } from '../../../services/views/common/viewsService.js'; import { ChatModel, isCellTextEditOperation } from '../common/chatModel.js'; import { ChatMode } from '../common/chatModes.js'; @@ -160,7 +160,7 @@ class QuickChat extends Disposable { @IInstantiationService private readonly instantiationService: IInstantiationService, @IContextKeyService private readonly contextKeyService: IContextKeyService, @IChatService private readonly chatService: IChatService, - @ILayoutService private readonly layoutService: ILayoutService, + @IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService, @IViewsService private readonly viewsService: IViewsService, @IChatEntitlementService private readonly chatEntitlementService: IChatEntitlementService, @IMarkdownRendererService private readonly markdownRendererService: IMarkdownRendererService, @@ -318,7 +318,7 @@ class QuickChat extends Disposable { } async openChatView(): Promise { - const widget = await showChatView(this.viewsService); + const widget = await showChatView(this.viewsService, this.layoutService); if (!widget?.viewModel || !this.model) { return; } diff --git a/src/vs/workbench/contrib/chat/browser/chatSetup.ts b/src/vs/workbench/contrib/chat/browser/chatSetup.ts index b4a8394b149..880a3f17d9e 100644 --- a/src/vs/workbench/contrib/chat/browser/chatSetup.ts +++ b/src/vs/workbench/contrib/chat/browser/chatSetup.ts @@ -72,7 +72,7 @@ import { IChatRequestToolEntry } from '../common/chatVariableEntries.js'; import { ChatAgentLocation, ChatConfiguration, ChatModeKind } from '../common/constants.js'; import { ILanguageModelsService } from '../common/languageModels.js'; import { CHAT_CATEGORY, CHAT_OPEN_ACTION_ID, CHAT_SETUP_ACTION_ID, CHAT_SETUP_SUPPORT_ANONYMOUS_ACTION_ID } from './actions/chatActions.js'; -import { ChatViewId, IChatWidgetService, showCopilotView } from './chat.js'; +import { ChatViewId, IChatWidgetService, showChatView } from './chat.js'; import { CHAT_SIDEBAR_PANEL_ID } from './chatViewPane.js'; import { IEnvironmentService } from '../../../../platform/environment/common/environment.js'; import { chatViewsWelcomeRegistry } from './viewsWelcome/chatViewsWelcome.js'; @@ -145,7 +145,7 @@ class SetupAgent extends Disposable implements IChatAgentImplementation { break; } - return SetupAgent.doRegisterAgent(instantiationService, chatAgentService, id, `${defaultChat.provider.default.name} Copilot`, true, description, location, mode, context, controller); + return SetupAgent.doRegisterAgent(instantiationService, chatAgentService, id, `${defaultChat.provider.default.name} Copilot` /* Do NOT change, this hides the username altogether in Chat */, true, description, location, mode, context, controller); }); } @@ -277,14 +277,14 @@ class SetupAgent extends Disposable implements IChatAgentImplementation { content: new MarkdownString(localize('waitingChat', "Getting chat ready...")), }); - await this.forwardRequestToCopilot(requestModel, progress, chatService, languageModelsService, chatAgentService, chatWidgetService, languageModelToolsService); + await this.forwardRequestToChat(requestModel, progress, chatService, languageModelsService, chatAgentService, chatWidgetService, languageModelToolsService); return {}; } - private async forwardRequestToCopilot(requestModel: IChatRequestModel, progress: (part: IChatProgress) => void, chatService: IChatService, languageModelsService: ILanguageModelsService, chatAgentService: IChatAgentService, chatWidgetService: IChatWidgetService, languageModelToolsService: ILanguageModelToolsService): Promise { + private async forwardRequestToChat(requestModel: IChatRequestModel, progress: (part: IChatProgress) => void, chatService: IChatService, languageModelsService: ILanguageModelsService, chatAgentService: IChatAgentService, chatWidgetService: IChatWidgetService, languageModelToolsService: ILanguageModelToolsService): Promise { try { - await this.doForwardRequestToCopilot(requestModel, progress, chatService, languageModelsService, chatAgentService, chatWidgetService, languageModelToolsService); + await this.doForwardRequestToChat(requestModel, progress, chatService, languageModelsService, chatAgentService, chatWidgetService, languageModelToolsService); } catch (error) { progress({ kind: 'warning', @@ -293,12 +293,12 @@ class SetupAgent extends Disposable implements IChatAgentImplementation { } } - private async doForwardRequestToCopilot(requestModel: IChatRequestModel, progress: (part: IChatProgress) => void, chatService: IChatService, languageModelsService: ILanguageModelsService, chatAgentService: IChatAgentService, chatWidgetService: IChatWidgetService, languageModelToolsService: ILanguageModelToolsService): Promise { + private async doForwardRequestToChat(requestModel: IChatRequestModel, progress: (part: IChatProgress) => void, chatService: IChatService, languageModelsService: ILanguageModelsService, chatAgentService: IChatAgentService, chatWidgetService: IChatWidgetService, languageModelToolsService: ILanguageModelToolsService): Promise { if (this.pendingForwardedRequests.has(requestModel.session.sessionId)) { throw new Error('Request already in progress'); } - const forwardRequest = this.doForwardRequestToCopilotWhenReady(requestModel, progress, chatService, languageModelsService, chatAgentService, chatWidgetService, languageModelToolsService); + const forwardRequest = this.doForwardRequestToChatWhenReady(requestModel, progress, chatService, languageModelsService, chatAgentService, chatWidgetService, languageModelToolsService); this.pendingForwardedRequests.set(requestModel.session.sessionId, forwardRequest); try { @@ -308,12 +308,12 @@ class SetupAgent extends Disposable implements IChatAgentImplementation { } } - private async doForwardRequestToCopilotWhenReady(requestModel: IChatRequestModel, progress: (part: IChatProgress) => void, chatService: IChatService, languageModelsService: ILanguageModelsService, chatAgentService: IChatAgentService, chatWidgetService: IChatWidgetService, languageModelToolsService: ILanguageModelToolsService): Promise { + private async doForwardRequestToChatWhenReady(requestModel: IChatRequestModel, progress: (part: IChatProgress) => void, chatService: IChatService, languageModelsService: ILanguageModelsService, chatAgentService: IChatAgentService, chatWidgetService: IChatWidgetService, languageModelToolsService: ILanguageModelToolsService): Promise { const widget = chatWidgetService.getWidgetBySessionId(requestModel.session.sessionId); const modeInfo = widget?.input.currentModeInfo; // We need a signal to know when we can resend the request to - // Copilot. Waiting for the registration of the agent is not + // Chat. Waiting for the registration of the agent is not // enough, we also need a language/tools model to be available. let agentReady = false; @@ -366,7 +366,7 @@ class SetupAgent extends Disposable implements IChatAgentImplementation { content: new MarkdownString(warningMessage) }); - // This means Copilot is unhealthy and we cannot retry the + // This means Chat is unhealthy and we cannot retry the // request. Signal this to the outside via an event. this._onUnresolvableError.fire(); return; @@ -489,10 +489,10 @@ class SetupAgent extends Disposable implements IChatAgentImplementation { if (result.dialogSkipped) { widget?.clear(); // make room for the Chat welcome experience } else if (requestModel) { - let newRequest = this.replaceAgentInRequestModel(requestModel, chatAgentService); // Replace agent part with the actual Copilot agent... - newRequest = this.replaceToolInRequestModel(newRequest); // ...then replace any tool parts with the actual Copilot tools + let newRequest = this.replaceAgentInRequestModel(requestModel, chatAgentService); // Replace agent part with the actual Chat agent... + newRequest = this.replaceToolInRequestModel(newRequest); // ...then replace any tool parts with the actual Chat tools - await this.forwardRequestToCopilot(newRequest, progress, chatService, languageModelsService, chatAgentService, chatWidgetService, languageModelToolsService); + await this.forwardRequestToChat(newRequest, progress, chatService, languageModelsService, chatAgentService, chatWidgetService, languageModelToolsService); } } else { progress({ @@ -766,7 +766,7 @@ class ChatSetup { if (setupStrategy !== ChatSetupStrategy.Canceled && !options?.disableChatViewReveal) { // Show the chat view now to better indicate progress // while installing the extension or returning from sign in - showCopilotView(this.viewsService, this.layoutService); + showChatView(this.viewsService, this.layoutService); } let success: ChatSetupResultValue = undefined; @@ -860,7 +860,7 @@ class ChatSetup { ]); } } else { - buttons = [[localize('setupCopilotButton', "Set up Copilot"), ChatSetupStrategy.DefaultSetup, undefined]]; + buttons = [[localize('setupAIButton', "Use AI Features"), ChatSetupStrategy.DefaultSetup, undefined]]; } buttons.push([localize('skipForNow', "Skip for now"), ChatSetupStrategy.Canceled, styleButton('link-button', 'skip-button')]); @@ -871,17 +871,17 @@ class ChatSetup { private getDialogTitle(options?: { forceSignInDialog?: boolean; forceAnonymous?: ChatSetupAnonymous }): string { if (this.chatEntitlementService.anonymous) { if (options?.forceAnonymous) { - return localize('startUsing', "Start using GitHub Copilot"); + return localize('startUsing', "Start using AI Features"); } else { return localize('enableMore', "Enable more AI features"); } } if (this.context.state.entitlement === ChatEntitlement.Unknown || options?.forceSignInDialog) { - return localize('signIn', "Sign in to use GitHub Copilot"); + return localize('signIn', "Sign in to use AI Features"); } - return localize('startUsing', "Start using GitHub Copilot"); + return localize('startUsing', "Start using AI Features"); } private createDialogFooter(disposables: DisposableStore, options?: { forceAnonymous?: ChatSetupAnonymous }): HTMLElement { @@ -964,11 +964,11 @@ export class ChatSetupContribution extends Disposable implements IWorkbenchContr const panelAgentHasGuidance = chatViewsWelcomeRegistry.get().some(descriptor => this.contextKeyService.contextMatchesRules(descriptor.when)); if (panelAgentHasGuidance) { // An unresolvable error from our agent registrations means that - // Copilot is unhealthy for some reason. We clear our panel - // registration to give Copilot a chance to show a custom message + // Chat is unhealthy for some reason. We clear our panel + // registration to give Chat a chance to show a custom message // to the user from the views and stop pretending as if there was // a functional agent. - this.logService.error('[chat setup] Unresolvable error from Copilot agent registration, clearing registration.'); + this.logService.error('[chat setup] Unresolvable error from Chat agent registration, clearing registration.'); panelAgentDisposables.dispose(); } })); @@ -1045,7 +1045,7 @@ export class ChatSetupContribution extends Disposable implements IWorkbenchContr configurationService.updateValue(ChatTeardownContribution.CHAT_DISABLED_CONFIGURATION_KEY, false); if (mode) { - const chatWidget = await showCopilotView(viewsService, layoutService); + const chatWidget = await showChatView(viewsService, layoutService); chatWidget?.input.setChatMode(mode); } diff --git a/src/vs/workbench/contrib/chat/browser/chatStatus.ts b/src/vs/workbench/contrib/chat/browser/chatStatus.ts index f166fe1d0a5..64c9bcc57eb 100644 --- a/src/vs/workbench/contrib/chat/browser/chatStatus.ts +++ b/src/vs/workbench/contrib/chat/browser/chatStatus.ts @@ -182,7 +182,7 @@ export class ChatStatusBarEntry extends Disposable implements IWorkbenchContribu private getEntryProps(): IStatusbarEntry { let text = '$(copilot)'; - let ariaLabel = localize('chatStatus', "Copilot Status"); + let ariaLabel = localize('chatStatusAria', "Copilot status"); let kind: StatusbarEntryKind | undefined; if (isNewUser(this.chatEntitlementService)) { @@ -195,7 +195,7 @@ export class ChatStatusBarEntry extends Disposable implements IWorkbenchContribu isProUser(entitlement) || // user is already pro entitlement === ChatEntitlement.Free // user is already free ) { - const finishSetup = localize('copilotLaterStatus', "Finish Setup"); + const finishSetup = localize('finishSetup', "Finish Setup"); text = `$(copilot) ${finishSetup}`; ariaLabel = finishSetup; @@ -224,7 +224,7 @@ export class ChatStatusBarEntry extends Disposable implements IWorkbenchContribu // Signed out else if (this.chatEntitlementService.entitlement === ChatEntitlement.Unknown) { - const signedOutWarning = localize('notSignedIntoCopilot', "Signed out"); + const signedOutWarning = localize('notSignedIn', "Signed out"); text = `${this.chatEntitlementService.anonymous ? '$(copilot)' : '$(copilot-not-connected)'} ${signedOutWarning}`; ariaLabel = signedOutWarning; @@ -282,17 +282,17 @@ export class ChatStatusBarEntry extends Disposable implements IWorkbenchContribu } function isNewUser(chatEntitlementService: IChatEntitlementService): boolean { - return !chatEntitlementService.sentiment.installed || // copilot not installed - chatEntitlementService.entitlement === ChatEntitlement.Available; // not yet signed up to copilot + return !chatEntitlementService.sentiment.installed || // chat not installed + chatEntitlementService.entitlement === ChatEntitlement.Available; // not yet signed up to chat } -function canUseCopilot(chatEntitlementService: IChatEntitlementService): boolean { +function canUseChat(chatEntitlementService: IChatEntitlementService): boolean { if (!chatEntitlementService.sentiment.installed || chatEntitlementService.sentiment.disabled || chatEntitlementService.sentiment.untrusted) { - return false; // copilot not installed or not enabled + return false; // chat not installed or not enabled } if (chatEntitlementService.entitlement === ChatEntitlement.Unknown || chatEntitlementService.entitlement === ChatEntitlement.Available) { - return chatEntitlementService.anonymous; // signed out or not-yet-signed-up users can only use Copilot if anonymous access is allowed + return chatEntitlementService.anonymous; // signed out or not-yet-signed-up users can only use Chat if anonymous access is allowed } if (chatEntitlementService.entitlement === ChatEntitlement.Free && chatEntitlementService.quotas.chat?.percentRemaining === 0 && chatEntitlementService.quotas.completions?.percentRemaining === 0) { @@ -402,7 +402,7 @@ class ChatStatusDashboard extends Disposable { } if (this.chatEntitlementService.entitlement === ChatEntitlement.Free && (Number(chatQuota?.percentRemaining) <= 25 || Number(completionsQuota?.percentRemaining) <= 25)) { - const upgradeProButton = disposables.add(new Button(this.element, { ...defaultButtonStyles, hoverDelegate: nativeHoverDelegate, secondary: canUseCopilot(this.chatEntitlementService) /* use secondary color when copilot can still be used */ })); + const upgradeProButton = disposables.add(new Button(this.element, { ...defaultButtonStyles, hoverDelegate: nativeHoverDelegate, secondary: canUseChat(this.chatEntitlementService) /* use secondary color when chat can still be used */ })); upgradeProButton.label = localize('upgradeToCopilotPro', "Upgrade to GitHub Copilot Pro"); disposables.add(upgradeProButton.onDidClick(() => this.runCommandAndClose('workbench.action.chat.upgradePlan'))); } @@ -513,12 +513,12 @@ class ChatStatusDashboard extends Disposable { } // Completions Snooze - if (canUseCopilot(this.chatEntitlementService)) { + if (canUseChat(this.chatEntitlementService)) { const snooze = append(this.element, $('div.snooze-completions')); this.createCompletionsSnooze(snooze, localize('settings.snooze', "Snooze"), disposables); } - // New to Copilot / Signed out + // New to Chat / Signed out { const newUser = isNewUser(this.chatEntitlementService); const anonymousUser = this.chatEntitlementService.anonymous; @@ -544,13 +544,13 @@ class ChatStatusDashboard extends Disposable { let buttonLabel: string; if (newUser) { - buttonLabel = localize('activateCopilotButton', "Set up Copilot"); + buttonLabel = localize('enableAIFeatures', "Use AI Features"); } else if (anonymousUser) { - buttonLabel = localize('enableMoreCopilotButton', "Enable more AI Features"); + buttonLabel = localize('enableMoreAIFeatures', "Enable more AI Features"); } else if (disabled) { - buttonLabel = localize('enableCopilotButton', "Enable Copilot"); + buttonLabel = localize('enableCopilotButton', "Enable AI Features"); } else { - buttonLabel = localize('signInToUseCopilotButton', "Sign in to use Copilot"); + buttonLabel = localize('signInToUseAIFeatures', "Sign in to use AI Features"); } let commandId: string; @@ -755,7 +755,7 @@ class ChatStatusDashboard extends Disposable { } })); - if (!canUseCopilot(this.chatEntitlementService)) { + if (!canUseChat(this.chatEntitlementService)) { container.classList.add('disabled'); checkbox.disable(); checkbox.checked = false; @@ -817,7 +817,7 @@ class ChatStatusDashboard extends Disposable { disposables.add(this.configurationService.onDidChangeConfiguration(e => { if (e.affectsConfiguration(completionsSettingId)) { - if (completionsSettingAccessor.readSetting() && canUseCopilot(this.chatEntitlementService)) { + if (completionsSettingAccessor.readSetting() && canUseChat(this.chatEntitlementService)) { checkbox.enable(); container.classList.remove('disabled'); } else { diff --git a/src/vs/workbench/contrib/chat/browser/chatViewPane.ts b/src/vs/workbench/contrib/chat/browser/chatViewPane.ts index 983599641e0..fdde10d58f3 100644 --- a/src/vs/workbench/contrib/chat/browser/chatViewPane.ts +++ b/src/vs/workbench/contrib/chat/browser/chatViewPane.ts @@ -161,7 +161,7 @@ export class ChatViewPane extends ViewPane implements IViewWelcomeDelegate { override shouldShowWelcome(): boolean { const noPersistedSessions = !this.chatService.hasSessions(); const hasCoreAgent = this.chatAgentService.getAgents().some(agent => agent.isCore && agent.locations.includes(this.chatOptions.location)); - const hasDefaultAgent = this.chatAgentService.getDefaultAgent(this.chatOptions.location) !== undefined; // only false when Hide Copilot has run and unregistered the setup agents + const hasDefaultAgent = this.chatAgentService.getDefaultAgent(this.chatOptions.location) !== undefined; // only false when Hide AI Features has run and unregistered the setup agents const shouldShow = !hasCoreAgent && (!hasDefaultAgent || !this._widget?.viewModel && noPersistedSessions); this.logService.trace(`ChatViewPane#shouldShowWelcome(${this.chatOptions.location}) = ${shouldShow}: hasCoreAgent=${hasCoreAgent} hasDefaultAgent=${hasDefaultAgent} || noViewModel=${!this._widget?.viewModel} && noPersistedSessions=${noPersistedSessions}`); return !!shouldShow; diff --git a/src/vs/workbench/contrib/chat/browser/promptSyntax/attachInstructionsAction.ts b/src/vs/workbench/contrib/chat/browser/promptSyntax/attachInstructionsAction.ts index 28bed45e5ba..b3c3b3e7ee9 100644 --- a/src/vs/workbench/contrib/chat/browser/promptSyntax/attachInstructionsAction.ts +++ b/src/vs/workbench/contrib/chat/browser/promptSyntax/attachInstructionsAction.ts @@ -27,6 +27,7 @@ import { KeybindingWeight } from '../../../../../platform/keybinding/common/keyb import { ICodeEditorService } from '../../../../../editor/browser/services/codeEditorService.js'; import { CancellationToken } from '../../../../../base/common/cancellation.js'; import { IOpenerService } from '../../../../../platform/opener/common/opener.js'; +import { IWorkbenchLayoutService } from '../../../../services/layout/browser/layoutService.js'; /** * Action ID for the `Attach Instruction` action. @@ -95,6 +96,7 @@ class AttachInstructionsAction extends Action2 { ): Promise { const viewsService = accessor.get(IViewsService); const instaService = accessor.get(IInstantiationService); + const layoutService = accessor.get(IWorkbenchLayoutService); if (!options) { options = { @@ -108,7 +110,7 @@ class AttachInstructionsAction extends Action2 { const { skipSelectionDialog, resource } = options; - const widget = options.widget ?? (await showChatView(viewsService)); + const widget = options.widget ?? (await showChatView(viewsService, layoutService)); if (!widget) { return; } diff --git a/src/vs/workbench/contrib/chat/browser/promptSyntax/runPromptAction.ts b/src/vs/workbench/contrib/chat/browser/promptSyntax/runPromptAction.ts index 048a3b6c432..0721f33c099 100644 --- a/src/vs/workbench/contrib/chat/browser/promptSyntax/runPromptAction.ts +++ b/src/vs/workbench/contrib/chat/browser/promptSyntax/runPromptAction.ts @@ -29,6 +29,7 @@ import { Action2, MenuId, registerAction2 } from '../../../../../platform/action import { IInstantiationService } from '../../../../../platform/instantiation/common/instantiation.js'; import { IOpenerService } from '../../../../../platform/opener/common/opener.js'; import { IPromptsService } from '../../common/promptSyntax/service/promptsService.js'; +import { IWorkbenchLayoutService } from '../../../../services/layout/browser/layoutService.js'; /** * Condition for the `Run Current Prompt` action. @@ -134,6 +135,7 @@ abstract class RunPromptBaseAction extends Action2 { const viewsService = accessor.get(IViewsService); const commandService = accessor.get(ICommandService); const promptsService = accessor.get(IPromptsService); + const layoutService = accessor.get(IWorkbenchLayoutService); resource ||= getActivePromptFileUri(accessor); assertDefined( @@ -145,7 +147,7 @@ abstract class RunPromptBaseAction extends Action2 { await commandService.executeCommand(ACTION_ID_NEW_CHAT); } - const widget = await showChatView(viewsService); + const widget = await showChatView(viewsService, layoutService); if (widget) { widget.setInput(`/${await promptsService.getPromptCommandName(resource)}`); // submit the prompt immediately @@ -210,6 +212,7 @@ class RunSelectedPromptAction extends Action2 { const commandService = accessor.get(ICommandService); const instaService = accessor.get(IInstantiationService); const promptsService = accessor.get(IPromptsService); + const layoutService = accessor.get(IWorkbenchLayoutService); const pickers = instaService.createInstance(PromptFilePickers); @@ -231,7 +234,7 @@ class RunSelectedPromptAction extends Action2 { await commandService.executeCommand(ACTION_ID_NEW_CHAT); } - const widget = await showChatView(viewsService); + const widget = await showChatView(viewsService, layoutService); if (widget) { widget.setInput(`/${await promptsService.getPromptCommandName(promptFile)}`); // submit the prompt immediately diff --git a/src/vs/workbench/contrib/chat/electron-browser/actions/voiceChatActions.ts b/src/vs/workbench/contrib/chat/electron-browser/actions/voiceChatActions.ts index acadfa9722c..f71f7cd84e2 100644 --- a/src/vs/workbench/contrib/chat/electron-browser/actions/voiceChatActions.ts +++ b/src/vs/workbench/contrib/chat/electron-browser/actions/voiceChatActions.ts @@ -111,7 +111,7 @@ class VoiceChatSessionControllerFactory { return controller ?? VoiceChatSessionControllerFactory.create(accessor, 'view'); // fallback to 'view' } case 'view': { - const chatWidget = await showChatView(viewsService); + const chatWidget = await showChatView(viewsService, layoutService); if (chatWidget) { return VoiceChatSessionControllerFactory.doCreateForChatWidget('view', chatWidget); } @@ -476,6 +476,7 @@ export class HoldToVoiceChatInChatViewAction extends Action2 { const instantiationService = accessor.get(IInstantiationService); const keybindingService = accessor.get(IKeybindingService); const viewsService = accessor.get(IViewsService); + const layoutService = accessor.get(IWorkbenchLayoutService); const holdMode = keybindingService.enableKeybindingHoldMode(HoldToVoiceChatInChatViewAction.ID); @@ -488,7 +489,7 @@ export class HoldToVoiceChatInChatViewAction extends Action2 { } }, VOICE_KEY_HOLD_THRESHOLD); - (await showChatView(viewsService))?.focusInput(); + (await showChatView(viewsService, layoutService))?.focusInput(); await holdMode; handle.dispose(); diff --git a/src/vs/workbench/contrib/chat/electron-browser/chat.contribution.ts b/src/vs/workbench/contrib/chat/electron-browser/chat.contribution.ts index 3ecc2fc8bf5..0459a36db92 100644 --- a/src/vs/workbench/contrib/chat/electron-browser/chat.contribution.ts +++ b/src/vs/workbench/contrib/chat/electron-browser/chat.contribution.ts @@ -96,7 +96,7 @@ class ChatCommandLineHandler extends Disposable { attachFiles: args['add-file']?.map(file => URI.file(resolve(file))), // use `resolve` to deal with relative paths properly }; - const chatWidget = await showChatView(this.viewsService); + const chatWidget = await showChatView(this.viewsService, this.layoutService); if (args.maximize) { const location = this.contextKeyService.getContextKeyValue(ChatContextKeys.panelLocation.key); @@ -145,6 +145,7 @@ class ChatLifecycleHandler extends Disposable { @IViewsService private readonly viewsService: IViewsService, @IContextKeyService private readonly contextKeyService: IContextKeyService, @IExtensionService extensionService: IExtensionService, + @IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService, ) { super(); @@ -172,7 +173,7 @@ class ChatLifecycleHandler extends Disposable { private async doShouldVetoShutdown(reason: ShutdownReason): Promise { - showChatView(this.viewsService); + showChatView(this.viewsService, this.layoutService); let message: string; let detail: string; diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts index b20bfbdec5a..6de941f48cd 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts @@ -45,6 +45,7 @@ import { ILogService } from '../../../../platform/log/common/log.js'; import { observableConfigValue } from '../../../../platform/observable/common/platformObservableUtils.js'; import { ISharedWebContentExtractorService } from '../../../../platform/webContentExtractor/common/webContentExtractor.js'; import { IEditorService, SIDE_GROUP } from '../../../services/editor/common/editorService.js'; +import { IWorkbenchLayoutService } from '../../../services/layout/browser/layoutService.js'; import { IViewsService } from '../../../services/views/common/viewsService.js'; import { showChatView } from '../../chat/browser/chat.js'; import { IChatAttachmentResolveService } from '../../chat/browser/chatAttachmentResolveService.js'; @@ -1677,8 +1678,9 @@ async function moveToPanelChat(accessor: ServicesAccessor, model: ChatModel | un const viewsService = accessor.get(IViewsService); const chatService = accessor.get(IChatService); + const layoutService = accessor.get(IWorkbenchLayoutService); - const widget = await showChatView(viewsService); + const widget = await showChatView(viewsService, layoutService); if (widget && widget.viewModel && model) { for (const request of model.getRequests().slice()) { diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/cellDiagnostics/cellDiagnosticsActions.ts b/src/vs/workbench/contrib/notebook/browser/contrib/cellDiagnostics/cellDiagnosticsActions.ts index d41ae0fcfd4..0241529aaa2 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/cellDiagnostics/cellDiagnosticsActions.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/cellDiagnostics/cellDiagnosticsActions.ts @@ -18,6 +18,7 @@ import { NOTEBOOK_CELL_EDITOR_FOCUSED, NOTEBOOK_CELL_FOCUSED, NOTEBOOK_CELL_HAS_ import { InlineChatController } from '../../../../inlineChat/browser/inlineChatController.js'; import { showChatView } from '../../../../chat/browser/chat.js'; import { IViewsService } from '../../../../../services/views/common/viewsService.js'; +import { IWorkbenchLayoutService } from '../../../../../services/layout/browser/layoutService.js'; export const OPEN_CELL_FAILURE_ACTIONS_COMMAND_ID = 'notebook.cell.openFailureActions'; export const FIX_CELL_ERROR_COMMAND_ID = 'notebook.cell.chat.fixError'; @@ -111,7 +112,8 @@ registerAction2(class extends NotebookCellAction { const error = context.cell.executionErrorDiagnostic.get(); if (error?.message) { const viewsService = accessor.get(IViewsService); - const chatWidget = await showChatView(viewsService); + const layoutService = accessor.get(IWorkbenchLayoutService); + const chatWidget = await showChatView(viewsService, layoutService); const message = error.name ? `${error.name}: ${error.message}` : error.message; // TODO: can we add special prompt instructions? e.g. use "%pip install" chatWidget?.acceptInput('@workspace /explain ' + message,); diff --git a/src/vs/workbench/contrib/notebook/browser/controller/chat/notebook.chat.contribution.ts b/src/vs/workbench/contrib/notebook/browser/controller/chat/notebook.chat.contribution.ts index 9a22155e2d2..2d05e10fe9e 100644 --- a/src/vs/workbench/contrib/notebook/browser/controller/chat/notebook.chat.contribution.ts +++ b/src/vs/workbench/contrib/notebook/browser/controller/chat/notebook.chat.contribution.ts @@ -21,6 +21,7 @@ import { ServicesAccessor } from '../../../../../../platform/instantiation/commo import { IQuickInputService, IQuickPickItem } from '../../../../../../platform/quickinput/common/quickInput.js'; import { IWorkbenchContribution, registerWorkbenchContribution2, WorkbenchPhase } from '../../../../../common/contributions.js'; import { IEditorService } from '../../../../../services/editor/common/editorService.js'; +import { IWorkbenchLayoutService } from '../../../../../services/layout/browser/layoutService.js'; import { IViewsService } from '../../../../../services/views/common/viewsService.js'; import { IChatWidget, IChatWidgetService, showChatView } from '../../../../chat/browser/chat.js'; import { IChatContextPicker, IChatContextPickerItem, IChatContextPickerPickItem, IChatContextPickService } from '../../../../chat/browser/chatContextPickService.js'; @@ -338,6 +339,7 @@ registerAction2(class CopyCellOutputAction extends Action2 { async run(accessor: ServicesAccessor, outputContext: INotebookOutputActionContext | { outputViewModel: ICellOutputViewModel } | undefined): Promise { const notebookEditor = this.getNoteboookEditor(accessor.get(IEditorService), outputContext); const viewService = accessor.get(IViewsService); + const layoutService = accessor.get(IWorkbenchLayoutService); if (!notebookEditor) { return; @@ -389,7 +391,7 @@ registerAction2(class CopyCellOutputAction extends Action2 { } widget.attachmentModel.addContext(entry); - (await showChatView(viewService))?.focusInput(); + (await showChatView(viewService, layoutService))?.focusInput(); } } diff --git a/src/vs/workbench/contrib/scm/browser/scmHistoryChatContext.ts b/src/vs/workbench/contrib/scm/browser/scmHistoryChatContext.ts index 44c5a3ed214..7701d7dfbc5 100644 --- a/src/vs/workbench/contrib/scm/browser/scmHistoryChatContext.ts +++ b/src/vs/workbench/contrib/scm/browser/scmHistoryChatContext.ts @@ -20,6 +20,7 @@ import { Action2, MenuId, registerAction2 } from '../../../../platform/actions/c import { CodeDataTransfers } from '../../../../platform/dnd/browser/dnd.js'; import { IInstantiationService, ServicesAccessor } from '../../../../platform/instantiation/common/instantiation.js'; import { IWorkbenchContribution } from '../../../common/contributions.js'; +import { IWorkbenchLayoutService } from '../../../services/layout/browser/layoutService.js'; import { IViewsService } from '../../../services/views/common/viewsService.js'; import { IChatWidget, showChatView } from '../../chat/browser/chat.js'; import { IChatContextPickerItem, IChatContextPickerPickItem, IChatContextPickService, picksWithPromiseFn } from '../../chat/browser/chatContextPickService.js'; @@ -268,7 +269,8 @@ registerAction2(class extends Action2 { override async run(accessor: ServicesAccessor, provider: ISCMProvider, historyItem: ISCMHistoryItem): Promise { const viewsService = accessor.get(IViewsService); - const widget = await showChatView(viewsService); + const layoutService = accessor.get(IWorkbenchLayoutService); + const widget = await showChatView(viewsService, layoutService); if (!provider || !historyItem || !widget) { return; } @@ -295,7 +297,8 @@ registerAction2(class extends Action2 { override async run(accessor: ServicesAccessor, provider: ISCMProvider, historyItem: ISCMHistoryItem): Promise { const viewsService = accessor.get(IViewsService); - const widget = await showChatView(viewsService); + const layoutService = accessor.get(IWorkbenchLayoutService); + const widget = await showChatView(viewsService, layoutService); if (!provider || !historyItem || !widget) { return; } @@ -322,7 +325,8 @@ registerAction2(class extends Action2 { override async run(accessor: ServicesAccessor, historyItem: ISCMHistoryItem, historyItemChange: ISCMHistoryItemChange): Promise { const viewsService = accessor.get(IViewsService); - const widget = await showChatView(viewsService); + const layoutService = accessor.get(IWorkbenchLayoutService); + const widget = await showChatView(viewsService, layoutService); if (!historyItem || !historyItemChange.modifiedUri || !widget) { return; } diff --git a/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatController.ts b/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatController.ts index 70b2d546ee4..08304afdaf5 100644 --- a/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatController.ts +++ b/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatController.ts @@ -16,6 +16,7 @@ import { IViewsService } from '../../../../services/views/common/viewsService.js import type { ITerminalContributionContext } from '../../../terminal/browser/terminalExtensions.js'; import type { IChatModel } from '../../../chat/common/chatModel.js'; import { IChatEntitlementService } from '../../../../services/chat/common/chatEntitlementService.js'; +import { IWorkbenchLayoutService } from '../../../../services/layout/browser/layoutService.js'; export class TerminalChatController extends Disposable implements ITerminalContribution { static readonly ID = 'terminal.chat'; @@ -156,8 +157,9 @@ async function moveToPanelChat(accessor: ServicesAccessor, model: IChatModel | u const viewsService = accessor.get(IViewsService); const chatService = accessor.get(IChatService); + const layoutService = accessor.get(IWorkbenchLayoutService); - const widget = await showChatView(viewsService); + const widget = await showChatView(viewsService, layoutService); if (widget && widget.viewModel && model) { for (const request of model.getRequests().slice()) { diff --git a/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatWidget.ts b/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatWidget.ts index b531eb39c50..b9fecd30410 100644 --- a/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatWidget.ts +++ b/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatWidget.ts @@ -30,6 +30,7 @@ import { TerminalStickyScrollContribution } from '../../stickyScroll/browser/ter import './media/terminalChatWidget.css'; import { MENU_TERMINAL_CHAT_WIDGET_INPUT_SIDE_TOOLBAR, MENU_TERMINAL_CHAT_WIDGET_STATUS, TerminalChatCommandId, TerminalChatContextKeys } from './terminalChat.js'; import { ChatMode } from '../../../chat/common/chatModes.js'; +import { IWorkbenchLayoutService } from '../../../../services/layout/browser/layoutService.js'; const enum Constants { HorizontalMargin = 10, @@ -103,6 +104,7 @@ export class TerminalChatWidget extends Disposable { @IViewsService private readonly _viewsService: IViewsService, @IInstantiationService instantiationService: IInstantiationService, @IChatAgentService private readonly _chatAgentService: IChatAgentService, + @IWorkbenchLayoutService private readonly _layoutService: IWorkbenchLayoutService, ) { super(); @@ -430,7 +432,7 @@ export class TerminalChatWidget extends Disposable { } async viewInChat(): Promise { - const widget = await showChatView(this._viewsService); + const widget = await showChatView(this._viewsService, this._layoutService); const currentRequest = this._inlineChatWidget.chatWidget.viewModel?.model.getRequests().find(r => r.id === this._currentRequestId); if (!widget || !currentRequest?.response) { return; diff --git a/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/terminal.chatAgentTools.contribution.ts b/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/terminal.chatAgentTools.contribution.ts index fa9e71a2976..0c49635cd41 100644 --- a/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/terminal.chatAgentTools.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/terminal.chatAgentTools.contribution.ts @@ -11,6 +11,7 @@ import { MenuId } from '../../../../../platform/actions/common/actions.js'; import { ContextKeyExpr } from '../../../../../platform/contextkey/common/contextkey.js'; import { IInstantiationService } from '../../../../../platform/instantiation/common/instantiation.js'; import { registerWorkbenchContribution2, WorkbenchPhase, type IWorkbenchContribution } from '../../../../common/contributions.js'; +import { IWorkbenchLayoutService } from '../../../../services/layout/browser/layoutService.js'; import { IViewsService } from '../../../../services/views/common/viewsService.js'; import { IChatWidgetService, showChatView } from '../../../chat/browser/chat.js'; import { ChatContextKeys } from '../../../chat/common/chatContextKeys.js'; @@ -112,13 +113,14 @@ registerActiveInstanceAction({ run: async (activeInstance, _c, accessor) => { const viewsService = accessor.get(IViewsService); const chatWidgetService = accessor.get(IChatWidgetService); + const layoutService = accessor.get(IWorkbenchLayoutService); const selection = activeInstance.selection; if (!selection) { return; } - const chatView = chatWidgetService.lastFocusedWidget || await showChatView(viewsService); + const chatView = chatWidgetService.lastFocusedWidget || await showChatView(viewsService, layoutService); if (!chatView) { return; } diff --git a/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/runInTerminalTool.ts b/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/runInTerminalTool.ts index 0817703f554..720ed55c58f 100644 --- a/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/runInTerminalTool.ts +++ b/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/runInTerminalTool.ts @@ -1036,7 +1036,7 @@ export class TerminalProfileFetcher { }; } - // Setting icon: undefined allows the system to use the default Copilot terminal icon (not overridden or removed) + // Setting icon: undefined allows the system to use the default AI terminal icon (not overridden or removed) return { ...defaultProfile, icon: undefined }; } diff --git a/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/task/createAndRunTaskTool.ts b/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/task/createAndRunTaskTool.ts index b045488aa24..2620dab3810 100644 --- a/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/task/createAndRunTaskTool.ts +++ b/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/task/createAndRunTaskTool.ts @@ -178,8 +178,8 @@ export class CreateAndRunTaskTool implements IToolImpl { title: localize('allowTaskCreationExecution', 'Allow task creation and execution?'), message: new MarkdownString( localize( - 'copilotCreateTask', - 'Copilot will create the task \`{0}\` with command \`{1}\`{2}.', + 'createTask', + 'A task \`{0}\` with command \`{1}\`{2} will be created.', task.label, task.command, task.args?.length ? ` and args \`${task.args.join(' ')}\`` : '' diff --git a/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/task/runTaskTool.ts b/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/task/runTaskTool.ts index 6d6bbcfd7b7..8c4b3358298 100644 --- a/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/task/runTaskTool.ts +++ b/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/task/runTaskTool.ts @@ -45,12 +45,12 @@ export class RunTaskTool implements IToolImpl { const taskDefinition = getTaskDefinition(args.id); const task = await getTaskForTool(args.id, taskDefinition, args.workspaceFolder, this._configurationService, this._tasksService, true); if (!task) { - return { content: [{ kind: 'text', value: `Task not found: ${args.id}` }], toolResultMessage: new MarkdownString(localize('copilotChat.taskNotFound', 'Task not found: `{0}`', args.id)) }; + return { content: [{ kind: 'text', value: `Task not found: ${args.id}` }], toolResultMessage: new MarkdownString(localize('chat.taskNotFound', 'Task not found: `{0}`', args.id)) }; } const taskLabel = task._label; const activeTasks = await this._tasksService.getActiveTasks(); if (activeTasks.includes(task)) { - return { content: [{ kind: 'text', value: `The task ${taskLabel} is already running.` }], toolResultMessage: new MarkdownString(localize('copilotChat.taskAlreadyRunning', 'The task `{0}` is already running.', taskLabel)) }; + return { content: [{ kind: 'text', value: `The task ${taskLabel} is already running.` }], toolResultMessage: new MarkdownString(localize('chat.taskAlreadyRunning', 'The task `{0}` is already running.', taskLabel)) }; } const raceResult = await Promise.race([this._tasksService.run(task, undefined, TaskRunSource.ChatAgent), timeout(3000)]); @@ -59,11 +59,11 @@ export class RunTaskTool implements IToolImpl { const dependencyTasks = await resolveDependencyTasks(task, args.workspaceFolder, this._configurationService, this._tasksService); const resources = this._tasksService.getTerminalsForTasks(dependencyTasks ?? task); if (!resources || resources.length === 0) { - return { content: [{ kind: 'text', value: `Task started but no terminal was found for: ${taskLabel}` }], toolResultMessage: new MarkdownString(localize('copilotChat.noTerminal', 'Task started but no terminal was found for: `{0}`', taskLabel)) }; + return { content: [{ kind: 'text', value: `Task started but no terminal was found for: ${taskLabel}` }], toolResultMessage: new MarkdownString(localize('chat.noTerminal', 'Task started but no terminal was found for: `{0}`', taskLabel)) }; } const terminals = this._terminalService.instances.filter(t => resources.some(r => r.path === t.resource.path && r.scheme === t.resource.scheme)); if (terminals.length === 0) { - return { content: [{ kind: 'text', value: `Task started but no terminal was found for: ${taskLabel}` }], toolResultMessage: new MarkdownString(localize('copilotChat.noTerminal', 'Task started but no terminal was found for: `{0}`', taskLabel)) }; + return { content: [{ kind: 'text', value: `Task started but no terminal was found for: ${taskLabel}` }], toolResultMessage: new MarkdownString(localize('chat.noTerminal', 'Task started but no terminal was found for: `{0}`', taskLabel)) }; } const store = new DisposableStore(); @@ -116,29 +116,29 @@ export class RunTaskTool implements IToolImpl { const task = await getTaskForTool(args.id, taskDefinition, args.workspaceFolder, this._configurationService, this._tasksService, true); if (!task) { - return { invocationMessage: new MarkdownString(localize('copilotChat.taskNotFound', 'Task not found: `{0}`', args.id)) }; + return { invocationMessage: new MarkdownString(localize('chat.taskNotFound', 'Task not found: `{0}`', args.id)) }; } const taskLabel = task._label; const activeTasks = await this._tasksService.getActiveTasks(); if (task && activeTasks.includes(task)) { - return { invocationMessage: new MarkdownString(localize('copilotChat.taskAlreadyActive', 'The task is already running.')) }; + return { invocationMessage: new MarkdownString(localize('chat.taskAlreadyActive', 'The task is already running.')) }; } if (await this._isTaskActive(task)) { return { - invocationMessage: new MarkdownString(localize('copilotChat.taskIsAlreadyRunning', '`{0}` is already running.', taskLabel)), - pastTenseMessage: new MarkdownString(localize('copilotChat.taskWasAlreadyRunning', '`{0}` was already running.', taskLabel)), + invocationMessage: new MarkdownString(localize('chat.taskIsAlreadyRunning', '`{0}` is already running.', taskLabel)), + pastTenseMessage: new MarkdownString(localize('chat.taskWasAlreadyRunning', '`{0}` was already running.', taskLabel)), confirmationMessages: undefined }; } return { - invocationMessage: new MarkdownString(localize('copilotChat.runningTask', 'Running `{0}`', taskLabel)), + invocationMessage: new MarkdownString(localize('chat.runningTask', 'Running `{0}`', taskLabel)), pastTenseMessage: new MarkdownString(task?.configurationProperties.isBackground - ? localize('copilotChat.startedTask', 'Started `{0}`', taskLabel) - : localize('copilotChat.ranTask', 'Ran `{0}`', taskLabel)), + ? localize('chat.startedTask', 'Started `{0}`', taskLabel) + : localize('chat.ranTask', 'Ran `{0}`', taskLabel)), confirmationMessages: task - ? { title: localize('copilotChat.allowTaskRunTitle', 'Allow task run?'), message: localize('copilotChat.allowTaskRunMsg', 'Allow Copilot to run the task `{0}`?', taskLabel) } + ? { title: localize('chat.allowTaskRunTitle', 'Allow task run?'), message: localize('chat.allowTaskRunMsg', 'Allow to run the task `{0}`?', taskLabel) } : undefined }; } diff --git a/src/vs/workbench/contrib/welcomeGettingStarted/common/gettingStartedContent.ts b/src/vs/workbench/contrib/welcomeGettingStarted/common/gettingStartedContent.ts index 8264534af8d..60f47c9a8c1 100644 --- a/src/vs/workbench/contrib/welcomeGettingStarted/common/gettingStartedContent.ts +++ b/src/vs/workbench/contrib/welcomeGettingStarted/common/gettingStartedContent.ts @@ -227,10 +227,10 @@ const Button = (title: string, href: string) => `[${title}](${href})`; const CopilotStepTitle = localize('gettingStarted.copilotSetup.title', "Use AI features with Copilot for free"); const CopilotDescription = localize({ key: 'gettingStarted.copilotSetup.description', comment: ['{Locked="["}', '{Locked="]({0})"}'] }, "You can use [Copilot]({0}) to generate code across multiple files, fix errors, ask questions about your code, and much more using natural language.", defaultChat.documentationUrl ?? ''); const CopilotTermsString = localize({ key: 'gettingStarted.copilotSetup.terms', comment: ['{Locked="]({2})"}', '{Locked="]({3})"}'] }, "By continuing with {0} Copilot, you agree to {1}'s [Terms]({2}) and [Privacy Statement]({3})", defaultChat.provider.default.name, defaultChat.provider.default.name, defaultChat.termsStatementUrl, defaultChat.privacyStatementUrl); -const CopilotAnonymousButton = Button(localize('setupCopilotButton.setup', "Set up Copilot"), `command:workbench.action.chat.triggerSetupAnonymousWithoutDialog`); -const CopilotSignedOutButton = Button(localize('setupCopilotButton.setup', "Set up Copilot"), `command:workbench.action.chat.triggerSetup`); -const CopilotSignedInButton = Button(localize('setupCopilotButton.setup', "Set up Copilot"), `command:workbench.action.chat.triggerSetup`); -const CopilotCompleteButton = Button(localize('setupCopilotButton.chatWithCopilot', "Chat with Copilot"), 'command:workbench.action.chat.open'); +const CopilotAnonymousButton = Button(localize('setupCopilotButton.setup', "Use AI Features"), `command:workbench.action.chat.triggerSetupAnonymousWithoutDialog`); +const CopilotSignedOutButton = Button(localize('setupCopilotButton.setup', "Use AI Features"), `command:workbench.action.chat.triggerSetup`); +const CopilotSignedInButton = Button(localize('setupCopilotButton.setup', "Use AI Features"), `command:workbench.action.chat.triggerSetup`); +const CopilotCompleteButton = Button(localize('setupCopilotButton.chatWithCopilot', "Start to Chat"), 'command:workbench.action.chat.open'); function createCopilotSetupStep(id: string, button: string, when: string, includeTerms: boolean): BuiltinGettingStartedStep { const description = includeTerms ?