Path: blob/main/src/vs/workbench/contrib/chat/browser/promptSyntax/promptCodingAgentActionOverlay.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { Disposable } from '../../../../../base/common/lifecycle.js';6import { ICodeEditor, IOverlayWidget, IOverlayWidgetPosition, OverlayWidgetPositionPreference } from '../../../../../editor/browser/editorBrowser.js';7import { ICommandService } from '../../../../../platform/commands/common/commands.js';8import { IContextKeyService } from '../../../../../platform/contextkey/common/contextkey.js';9import { ChatContextKeys } from '../../common/chatContextKeys.js';10import { IRemoteCodingAgentsService } from '../../../remoteCodingAgents/common/remoteCodingAgentsService.js';11import { localize } from '../../../../../nls.js';12import { Button } from '../../../../../base/browser/ui/button/button.js';13import { getPromptCommandName } from '../../common/promptSyntax/service/promptsServiceImpl.js';14import { PROMPT_LANGUAGE_ID } from '../../common/promptSyntax/promptTypes.js';15import { $ } from '../../../../../base/browser/dom.js';1617export class PromptCodingAgentActionOverlayWidget extends Disposable implements IOverlayWidget {1819private static readonly ID = 'promptCodingAgentActionOverlay';2021private readonly _domNode: HTMLElement;22private readonly _button: Button;23private _isVisible: boolean = false;2425constructor(26private readonly _editor: ICodeEditor,27@ICommandService private readonly _commandService: ICommandService,28@IContextKeyService private readonly _contextKeyService: IContextKeyService,29@IRemoteCodingAgentsService private readonly _remoteCodingAgentService: IRemoteCodingAgentsService30) {31super();3233this._domNode = $('.prompt-coding-agent-action-overlay');3435this._button = this._register(new Button(this._domNode, {36supportIcons: true,37title: localize('runPromptWithCodingAgent', "Run prompt file in a remote coding agent")38}));3940this._button.element.style.background = 'var(--vscode-button-background)';41this._button.element.style.color = 'var(--vscode-button-foreground)';42this._button.label = localize('runWithCodingAgent.label', "{0} Delegate to Copilot coding agent", '$(cloud-upload)');4344this._register(this._button.onDidClick(async () => {45await this._execute();46}));47this._register(this._contextKeyService.onDidChangeContext(() => {48this._updateVisibility();49}));50this._register(this._editor.onDidChangeModel(() => {51this._updateVisibility();52}));53this._register(this._editor.onDidLayoutChange(() => {54if (this._isVisible) {55this._editor.layoutOverlayWidget(this);56}57}));5859// initial visibility60this._updateVisibility();61}6263getId(): string {64return PromptCodingAgentActionOverlayWidget.ID;65}6667getDomNode(): HTMLElement {68return this._domNode;69}7071getPosition(): IOverlayWidgetPosition | null {72if (!this._isVisible) {73return null;74}7576return {77preference: OverlayWidgetPositionPreference.BOTTOM_RIGHT_CORNER,78};79}8081private _updateVisibility(): void {82const enableRemoteCodingAgentPromptFileOverlay = ChatContextKeys.enableRemoteCodingAgentPromptFileOverlay.getValue(this._contextKeyService);83const hasRemoteCodingAgent = ChatContextKeys.hasRemoteCodingAgent.getValue(this._contextKeyService);84const model = this._editor.getModel();85const isPromptFile = model?.getLanguageId() === PROMPT_LANGUAGE_ID;86const shouldBeVisible = !!(isPromptFile && enableRemoteCodingAgentPromptFileOverlay && hasRemoteCodingAgent);8788if (shouldBeVisible !== this._isVisible) {89this._isVisible = shouldBeVisible;90if (this._isVisible) {91this._editor.addOverlayWidget(this);92} else {93this._editor.removeOverlayWidget(this);94}95}96}9798private async _execute(): Promise<void> {99const model = this._editor.getModel();100if (!model) {101return;102}103104this._button.enabled = false;105try {106const promptContent = model.getValue();107const promptName = getPromptCommandName(model.uri.path);108109const agents = this._remoteCodingAgentService.getAvailableAgents();110const agent = agents[0]; // Use the first available agent111if (!agent) {112return;113}114115await this._commandService.executeCommand(agent.command, {116userPrompt: promptName,117summary: promptContent,118source: 'prompt',119});120} finally {121this._button.enabled = true;122}123}124125override dispose(): void {126if (this._isVisible) {127this._editor.removeOverlayWidget(this);128}129super.dispose();130}131}132133134