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/hoverElementTool.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 HoverElementToolData: IToolData = {
17
id: 'hover_element',
18
toolReferenceName: BrowserChatToolReferenceName.HoverElement,
19
displayName: localize('hoverElementTool.displayName', 'Hover Element'),
20
userDescription: localize('hoverElementTool.userDescription', 'Hover over an element in a browser page'),
21
modelDescription: 'Hover over an element in a browser page. Provide either a Playwright selector or an element reference.',
22
icon: Codicon.cursor,
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
ref: {
32
type: 'string',
33
description: 'Element reference to hover over.'
34
},
35
selector: {
36
type: 'string',
37
description: 'Playwright selector of the element to hover over when "ref" is not available.'
38
},
39
element: {
40
type: 'string',
41
description: 'Human-readable description of the element to hover over (e.g., "navigation menu", "tooltip trigger").'
42
},
43
},
44
required: ['pageId', 'element'],
45
$comment: 'One of "ref" or "selector" is required.',
46
},
47
};
48
49
interface IHoverElementToolParams {
50
pageId: string;
51
ref?: string;
52
selector?: string;
53
element?: string;
54
}
55
56
export class HoverElementTool implements IToolImpl {
57
constructor(
58
@IPlaywrightService private readonly playwrightService: IPlaywrightService,
59
) { }
60
61
async prepareToolInvocation(_context: IToolInvocationPreparationContext, _token: CancellationToken): Promise<IPreparedToolInvocation | undefined> {
62
const params = _context.parameters as IHoverElementToolParams;
63
const link = createBrowserPageLink(params.pageId);
64
const element = escapeMarkdownSyntaxTokens(params.element ?? DEFAULT_ELEMENT_LABEL);
65
return {
66
invocationMessage: new MarkdownString(localize('browser.hover.invocation', "Hovering over {0} in {1}", element, link)),
67
pastTenseMessage: new MarkdownString(localize('browser.hover.past', "Hovered over {0} in {1}", element, link)),
68
};
69
}
70
71
async invoke(invocation: IToolInvocation, _countTokens: CountTokensCallback, _progress: ToolProgress, _token: CancellationToken): Promise<IToolResult> {
72
const params = invocation.parameters as IHoverElementToolParams;
73
74
if (!params.pageId) {
75
return errorResult(`No page ID provided. Use '${OpenPageToolId}' first.`);
76
}
77
78
let selector = params.selector;
79
if (params.ref) {
80
selector = `aria-ref=${params.ref}`;
81
}
82
83
if (!selector) {
84
return errorResult('Either a "ref" or "selector" parameter is required.');
85
}
86
87
return playwrightInvoke(this.playwrightService, params.pageId, (page, sel) => page.locator(sel).hover(), selector);
88
}
89
}
90
91