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
5257 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/actions/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 { PROMPT_LANGUAGE_ID } from '../../common/promptSyntax/promptTypes.js';
15
import { $ } from '../../../../../base/browser/dom.js';
16
import { IPromptsService } from '../../common/promptSyntax/service/promptsService.js';
17
import { CancellationToken } from '../../../../../base/common/cancellation.js';
18
19
export class PromptCodingAgentActionOverlayWidget extends Disposable implements IOverlayWidget {
20
21
private static readonly ID = 'promptCodingAgentActionOverlay';
22
23
private readonly _domNode: HTMLElement;
24
private readonly _button: Button;
25
private _isVisible: boolean = false;
26
27
constructor(
28
private readonly _editor: ICodeEditor,
29
@ICommandService private readonly _commandService: ICommandService,
30
@IContextKeyService private readonly _contextKeyService: IContextKeyService,
31
@IRemoteCodingAgentsService private readonly _remoteCodingAgentService: IRemoteCodingAgentsService,
32
@IPromptsService private readonly _promptsService: IPromptsService,
33
) {
34
super();
35
36
this._domNode = $('.prompt-coding-agent-action-overlay');
37
38
this._button = this._register(new Button(this._domNode, {
39
supportIcons: true,
40
title: localize('runPromptWithCodingAgent', "Run prompt file in a remote coding agent")
41
}));
42
43
this._button.element.style.background = 'var(--vscode-button-background)';
44
this._button.element.style.color = 'var(--vscode-button-foreground)';
45
this._button.label = localize('runWithCodingAgent.label', "{0} Delegate to Copilot coding agent", '$(cloud-upload)');
46
47
this._register(this._button.onDidClick(async () => {
48
await this._execute();
49
}));
50
this._register(this._contextKeyService.onDidChangeContext(() => {
51
this._updateVisibility();
52
}));
53
this._register(this._editor.onDidChangeModel(() => {
54
this._updateVisibility();
55
}));
56
this._register(this._editor.onDidLayoutChange(() => {
57
if (this._isVisible) {
58
this._editor.layoutOverlayWidget(this);
59
}
60
}));
61
62
// initial visibility
63
this._updateVisibility();
64
}
65
66
getId(): string {
67
return PromptCodingAgentActionOverlayWidget.ID;
68
}
69
70
getDomNode(): HTMLElement {
71
return this._domNode;
72
}
73
74
getPosition(): IOverlayWidgetPosition | null {
75
if (!this._isVisible) {
76
return null;
77
}
78
79
return {
80
preference: OverlayWidgetPositionPreference.BOTTOM_RIGHT_CORNER,
81
};
82
}
83
84
private _updateVisibility(): void {
85
const enableRemoteCodingAgentPromptFileOverlay = ChatContextKeys.enableRemoteCodingAgentPromptFileOverlay.getValue(this._contextKeyService);
86
const hasRemoteCodingAgent = ChatContextKeys.hasRemoteCodingAgent.getValue(this._contextKeyService);
87
const model = this._editor.getModel();
88
const isPromptFile = model?.getLanguageId() === PROMPT_LANGUAGE_ID;
89
const shouldBeVisible = !!(isPromptFile && enableRemoteCodingAgentPromptFileOverlay && hasRemoteCodingAgent);
90
91
if (shouldBeVisible !== this._isVisible) {
92
this._isVisible = shouldBeVisible;
93
if (this._isVisible) {
94
this._editor.addOverlayWidget(this);
95
} else {
96
this._editor.removeOverlayWidget(this);
97
}
98
}
99
}
100
101
private async _execute(): Promise<void> {
102
const model = this._editor.getModel();
103
if (!model) {
104
return;
105
}
106
107
this._button.enabled = false;
108
try {
109
const promptContent = model.getValue();
110
const promptName = await this._promptsService.getPromptSlashCommandName(model.uri, CancellationToken.None);
111
112
const agents = this._remoteCodingAgentService.getAvailableAgents();
113
const agent = agents[0]; // Use the first available agent
114
if (!agent) {
115
return;
116
}
117
118
await this._commandService.executeCommand(agent.command, {
119
userPrompt: promptName,
120
summary: promptContent,
121
source: 'prompt',
122
});
123
} finally {
124
this._button.enabled = true;
125
}
126
}
127
128
override dispose(): void {
129
if (this._isVisible) {
130
this._editor.removeOverlayWidget(this);
131
}
132
super.dispose();
133
}
134
}
135
136