Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/chat/browser/promptSyntax/promptCodingAgentActionOverlay.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { Disposable } from '../../../../../base/common/lifecycle.js';
7
import { ICodeEditor, IOverlayWidget, IOverlayWidgetPosition, OverlayWidgetPositionPreference } from '../../../../../editor/browser/editorBrowser.js';
8
import { ICommandService } from '../../../../../platform/commands/common/commands.js';
9
import { IContextKeyService } from '../../../../../platform/contextkey/common/contextkey.js';
10
import { ChatContextKeys } from '../../common/chatContextKeys.js';
11
import { IRemoteCodingAgentsService } from '../../../remoteCodingAgents/common/remoteCodingAgentsService.js';
12
import { localize } from '../../../../../nls.js';
13
import { Button } from '../../../../../base/browser/ui/button/button.js';
14
import { getPromptCommandName } from '../../common/promptSyntax/service/promptsServiceImpl.js';
15
import { PROMPT_LANGUAGE_ID } from '../../common/promptSyntax/promptTypes.js';
16
import { $ } from '../../../../../base/browser/dom.js';
17
18
export class PromptCodingAgentActionOverlayWidget extends Disposable implements IOverlayWidget {
19
20
private static readonly ID = 'promptCodingAgentActionOverlay';
21
22
private readonly _domNode: HTMLElement;
23
private readonly _button: Button;
24
private _isVisible: boolean = false;
25
26
constructor(
27
private readonly _editor: ICodeEditor,
28
@ICommandService private readonly _commandService: ICommandService,
29
@IContextKeyService private readonly _contextKeyService: IContextKeyService,
30
@IRemoteCodingAgentsService private readonly _remoteCodingAgentService: IRemoteCodingAgentsService
31
) {
32
super();
33
34
this._domNode = $('.prompt-coding-agent-action-overlay');
35
36
this._button = this._register(new Button(this._domNode, {
37
supportIcons: true,
38
title: localize('runPromptWithCodingAgent', "Run prompt file in a remote coding agent")
39
}));
40
41
this._button.element.style.background = 'var(--vscode-button-background)';
42
this._button.element.style.color = 'var(--vscode-button-foreground)';
43
this._button.label = localize('runWithCodingAgent.label', "{0} Delegate to Copilot coding agent", '$(cloud-upload)');
44
45
this._register(this._button.onDidClick(async () => {
46
await this._execute();
47
}));
48
this._register(this._contextKeyService.onDidChangeContext(() => {
49
this._updateVisibility();
50
}));
51
this._register(this._editor.onDidChangeModel(() => {
52
this._updateVisibility();
53
}));
54
this._register(this._editor.onDidLayoutChange(() => {
55
if (this._isVisible) {
56
this._editor.layoutOverlayWidget(this);
57
}
58
}));
59
60
// initial visibility
61
this._updateVisibility();
62
}
63
64
getId(): string {
65
return PromptCodingAgentActionOverlayWidget.ID;
66
}
67
68
getDomNode(): HTMLElement {
69
return this._domNode;
70
}
71
72
getPosition(): IOverlayWidgetPosition | null {
73
if (!this._isVisible) {
74
return null;
75
}
76
77
return {
78
preference: OverlayWidgetPositionPreference.BOTTOM_RIGHT_CORNER,
79
};
80
}
81
82
private _updateVisibility(): void {
83
const enableRemoteCodingAgentPromptFileOverlay = ChatContextKeys.enableRemoteCodingAgentPromptFileOverlay.getValue(this._contextKeyService);
84
const hasRemoteCodingAgent = ChatContextKeys.hasRemoteCodingAgent.getValue(this._contextKeyService);
85
const model = this._editor.getModel();
86
const isPromptFile = model?.getLanguageId() === PROMPT_LANGUAGE_ID;
87
const shouldBeVisible = !!(isPromptFile && enableRemoteCodingAgentPromptFileOverlay && hasRemoteCodingAgent);
88
89
if (shouldBeVisible !== this._isVisible) {
90
this._isVisible = shouldBeVisible;
91
if (this._isVisible) {
92
this._editor.addOverlayWidget(this);
93
} else {
94
this._editor.removeOverlayWidget(this);
95
}
96
}
97
}
98
99
private async _execute(): Promise<void> {
100
const model = this._editor.getModel();
101
if (!model) {
102
return;
103
}
104
105
this._button.enabled = false;
106
try {
107
const promptContent = model.getValue();
108
const promptName = getPromptCommandName(model.uri.path);
109
110
const agents = this._remoteCodingAgentService.getAvailableAgents();
111
const agent = agents[0]; // Use the first available agent
112
if (!agent) {
113
return;
114
}
115
116
await this._commandService.executeCommand(agent.command, {
117
userPrompt: promptName,
118
summary: promptContent,
119
source: 'prompt',
120
});
121
} finally {
122
this._button.enabled = true;
123
}
124
}
125
126
override dispose(): void {
127
if (this._isVisible) {
128
this._editor.removeOverlayWidget(this);
129
}
130
super.dispose();
131
}
132
}
133
134