Path: blob/main/src/vs/workbench/contrib/chat/browser/promptSyntax/promptCodingAgentActionOverlay.ts
5257 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/actions/chatContextKeys.js';10import { IRemoteCodingAgentsService } from '../../../remoteCodingAgents/common/remoteCodingAgentsService.js';11import { localize } from '../../../../../nls.js';12import { Button } from '../../../../../base/browser/ui/button/button.js';13import { PROMPT_LANGUAGE_ID } from '../../common/promptSyntax/promptTypes.js';14import { $ } from '../../../../../base/browser/dom.js';15import { IPromptsService } from '../../common/promptSyntax/service/promptsService.js';16import { CancellationToken } from '../../../../../base/common/cancellation.js';1718export class PromptCodingAgentActionOverlayWidget extends Disposable implements IOverlayWidget {1920private static readonly ID = 'promptCodingAgentActionOverlay';2122private readonly _domNode: HTMLElement;23private readonly _button: Button;24private _isVisible: boolean = false;2526constructor(27private readonly _editor: ICodeEditor,28@ICommandService private readonly _commandService: ICommandService,29@IContextKeyService private readonly _contextKeyService: IContextKeyService,30@IRemoteCodingAgentsService private readonly _remoteCodingAgentService: IRemoteCodingAgentsService,31@IPromptsService private readonly _promptsService: IPromptsService,32) {33super();3435this._domNode = $('.prompt-coding-agent-action-overlay');3637this._button = this._register(new Button(this._domNode, {38supportIcons: true,39title: localize('runPromptWithCodingAgent', "Run prompt file in a remote coding agent")40}));4142this._button.element.style.background = 'var(--vscode-button-background)';43this._button.element.style.color = 'var(--vscode-button-foreground)';44this._button.label = localize('runWithCodingAgent.label', "{0} Delegate to Copilot coding agent", '$(cloud-upload)');4546this._register(this._button.onDidClick(async () => {47await this._execute();48}));49this._register(this._contextKeyService.onDidChangeContext(() => {50this._updateVisibility();51}));52this._register(this._editor.onDidChangeModel(() => {53this._updateVisibility();54}));55this._register(this._editor.onDidLayoutChange(() => {56if (this._isVisible) {57this._editor.layoutOverlayWidget(this);58}59}));6061// initial visibility62this._updateVisibility();63}6465getId(): string {66return PromptCodingAgentActionOverlayWidget.ID;67}6869getDomNode(): HTMLElement {70return this._domNode;71}7273getPosition(): IOverlayWidgetPosition | null {74if (!this._isVisible) {75return null;76}7778return {79preference: OverlayWidgetPositionPreference.BOTTOM_RIGHT_CORNER,80};81}8283private _updateVisibility(): void {84const enableRemoteCodingAgentPromptFileOverlay = ChatContextKeys.enableRemoteCodingAgentPromptFileOverlay.getValue(this._contextKeyService);85const hasRemoteCodingAgent = ChatContextKeys.hasRemoteCodingAgent.getValue(this._contextKeyService);86const model = this._editor.getModel();87const isPromptFile = model?.getLanguageId() === PROMPT_LANGUAGE_ID;88const shouldBeVisible = !!(isPromptFile && enableRemoteCodingAgentPromptFileOverlay && hasRemoteCodingAgent);8990if (shouldBeVisible !== this._isVisible) {91this._isVisible = shouldBeVisible;92if (this._isVisible) {93this._editor.addOverlayWidget(this);94} else {95this._editor.removeOverlayWidget(this);96}97}98}99100private async _execute(): Promise<void> {101const model = this._editor.getModel();102if (!model) {103return;104}105106this._button.enabled = false;107try {108const promptContent = model.getValue();109const promptName = await this._promptsService.getPromptSlashCommandName(model.uri, CancellationToken.None);110111const agents = this._remoteCodingAgentService.getAvailableAgents();112const agent = agents[0]; // Use the first available agent113if (!agent) {114return;115}116117await this._commandService.executeCommand(agent.command, {118userPrompt: promptName,119summary: promptContent,120source: 'prompt',121});122} finally {123this._button.enabled = true;124}125}126127override dispose(): void {128if (this._isVisible) {129this._editor.removeOverlayWidget(this);130}131super.dispose();132}133}134135136