Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/browserView/electron-browser/tools/dragElementTool.ts
13405 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 type { CancellationToken } from '../../../../../base/common/cancellation.js';
7
import { Codicon } from '../../../../../base/common/codicons.js';
8
import { escapeMarkdownSyntaxTokens, MarkdownString } from '../../../../../base/common/htmlContent.js';
9
import { localize } from '../../../../../nls.js';
10
import { IPlaywrightService } from '../../../../../platform/browserView/common/playwrightService.js';
11
import { ToolDataSource, type CountTokensCallback, type IPreparedToolInvocation, type IToolData, type IToolImpl, type IToolInvocation, type IToolInvocationPreparationContext, type IToolResult, type ToolProgress } from '../../../chat/common/tools/languageModelToolsService.js';
12
import { createBrowserPageLink, DEFAULT_ELEMENT_LABEL, errorResult, playwrightInvoke } from './browserToolHelpers.js';
13
import { BrowserChatToolReferenceName } from '../../common/browserChatToolReferenceNames.js';
14
import { OpenPageToolId } from './openBrowserTool.js';
15
16
export const DragElementToolData: IToolData = {
17
id: 'drag_element',
18
toolReferenceName: BrowserChatToolReferenceName.DragElement,
19
displayName: localize('dragElementTool.displayName', 'Drag Element'),
20
userDescription: localize('dragElementTool.userDescription', 'Drag an element over another element'),
21
modelDescription: 'Drag an element over another element in a browser page.',
22
icon: Codicon.move,
23
source: ToolDataSource.Internal,
24
inputSchema: {
25
type: 'object',
26
properties: {
27
pageId: {
28
type: 'string',
29
description: `The browser page ID, acquired from context or the open tool.`
30
},
31
fromRef: {
32
type: 'string',
33
description: 'Element reference of the element to drag.'
34
},
35
fromSelector: {
36
type: 'string',
37
description: 'Playwright selector of the element to drag when "fromRef" is not available.'
38
},
39
fromElement: {
40
type: 'string',
41
description: 'Human-readable description of the element to drag (e.g., "file item", "draggable card").'
42
},
43
toRef: {
44
type: 'string',
45
description: 'Element reference of the element to drop onto.'
46
},
47
toSelector: {
48
type: 'string',
49
description: 'Playwright selector of the element to drop onto when "toRef" is not available.'
50
},
51
toElement: {
52
type: 'string',
53
description: 'Human-readable description of the element to drop onto (e.g., "drop zone", "target folder").'
54
},
55
},
56
required: ['pageId', 'fromElement', 'toElement'],
57
$comment: 'One of "fromRef" or "fromSelector" is required, and one of "toRef" or "toSelector" is required.',
58
},
59
};
60
61
interface IDragElementToolParams {
62
pageId: string;
63
fromRef?: string;
64
fromSelector?: string;
65
fromElement?: string;
66
toRef?: string;
67
toSelector?: string;
68
toElement?: string;
69
}
70
71
export class DragElementTool implements IToolImpl {
72
constructor(
73
@IPlaywrightService private readonly playwrightService: IPlaywrightService,
74
) { }
75
76
async prepareToolInvocation(_context: IToolInvocationPreparationContext, _token: CancellationToken): Promise<IPreparedToolInvocation | undefined> {
77
const params = _context.parameters as IDragElementToolParams;
78
const link = createBrowserPageLink(params.pageId);
79
const fromElement = escapeMarkdownSyntaxTokens(params.fromElement ?? DEFAULT_ELEMENT_LABEL);
80
const toElement = escapeMarkdownSyntaxTokens(params.toElement ?? DEFAULT_ELEMENT_LABEL);
81
return {
82
invocationMessage: new MarkdownString(localize('browser.drag.invocation', "Dragging {0} to {1} in {2}", fromElement, toElement, link)),
83
pastTenseMessage: new MarkdownString(localize('browser.drag.past', "Dragged {0} to {1} in {2}", fromElement, toElement, link)),
84
};
85
}
86
87
async invoke(invocation: IToolInvocation, _countTokens: CountTokensCallback, _progress: ToolProgress, _token: CancellationToken): Promise<IToolResult> {
88
const params = invocation.parameters as IDragElementToolParams;
89
90
if (!params.pageId) {
91
return errorResult(`No page ID provided. Use '${OpenPageToolId}' first.`);
92
}
93
94
let fromSelector = params.fromSelector;
95
if (params.fromRef) {
96
fromSelector = `aria-ref=${params.fromRef}`;
97
}
98
if (!fromSelector) {
99
return errorResult('Either a "fromRef" or "fromSelector" parameter is required for the source element.');
100
}
101
102
let toSelector = params.toSelector;
103
if (params.toRef) {
104
toSelector = `aria-ref=${params.toRef}`;
105
}
106
if (!toSelector) {
107
return errorResult('Either a "toRef" or "toSelector" parameter is required for the target element.');
108
}
109
110
return playwrightInvoke(this.playwrightService, params.pageId, (page, from, to) => page.dragAndDrop(from, to), fromSelector, toSelector);
111
}
112
}
113
114