Path: blob/main/src/vs/workbench/contrib/browserView/electron-browser/tools/hoverElementTool.ts
13405 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 type { CancellationToken } from '../../../../../base/common/cancellation.js';6import { Codicon } from '../../../../../base/common/codicons.js';7import { escapeMarkdownSyntaxTokens, MarkdownString } from '../../../../../base/common/htmlContent.js';8import { localize } from '../../../../../nls.js';9import { IPlaywrightService } from '../../../../../platform/browserView/common/playwrightService.js';10import { ToolDataSource, type CountTokensCallback, type IPreparedToolInvocation, type IToolData, type IToolImpl, type IToolInvocation, type IToolInvocationPreparationContext, type IToolResult, type ToolProgress } from '../../../chat/common/tools/languageModelToolsService.js';11import { createBrowserPageLink, DEFAULT_ELEMENT_LABEL, errorResult, playwrightInvoke } from './browserToolHelpers.js';12import { BrowserChatToolReferenceName } from '../../common/browserChatToolReferenceNames.js';13import { OpenPageToolId } from './openBrowserTool.js';1415export const HoverElementToolData: IToolData = {16id: 'hover_element',17toolReferenceName: BrowserChatToolReferenceName.HoverElement,18displayName: localize('hoverElementTool.displayName', 'Hover Element'),19userDescription: localize('hoverElementTool.userDescription', 'Hover over an element in a browser page'),20modelDescription: 'Hover over an element in a browser page. Provide either a Playwright selector or an element reference.',21icon: Codicon.cursor,22source: ToolDataSource.Internal,23inputSchema: {24type: 'object',25properties: {26pageId: {27type: 'string',28description: `The browser page ID, acquired from context or the open tool.`29},30ref: {31type: 'string',32description: 'Element reference to hover over.'33},34selector: {35type: 'string',36description: 'Playwright selector of the element to hover over when "ref" is not available.'37},38element: {39type: 'string',40description: 'Human-readable description of the element to hover over (e.g., "navigation menu", "tooltip trigger").'41},42},43required: ['pageId', 'element'],44$comment: 'One of "ref" or "selector" is required.',45},46};4748interface IHoverElementToolParams {49pageId: string;50ref?: string;51selector?: string;52element?: string;53}5455export class HoverElementTool implements IToolImpl {56constructor(57@IPlaywrightService private readonly playwrightService: IPlaywrightService,58) { }5960async prepareToolInvocation(_context: IToolInvocationPreparationContext, _token: CancellationToken): Promise<IPreparedToolInvocation | undefined> {61const params = _context.parameters as IHoverElementToolParams;62const link = createBrowserPageLink(params.pageId);63const element = escapeMarkdownSyntaxTokens(params.element ?? DEFAULT_ELEMENT_LABEL);64return {65invocationMessage: new MarkdownString(localize('browser.hover.invocation', "Hovering over {0} in {1}", element, link)),66pastTenseMessage: new MarkdownString(localize('browser.hover.past', "Hovered over {0} in {1}", element, link)),67};68}6970async invoke(invocation: IToolInvocation, _countTokens: CountTokensCallback, _progress: ToolProgress, _token: CancellationToken): Promise<IToolResult> {71const params = invocation.parameters as IHoverElementToolParams;7273if (!params.pageId) {74return errorResult(`No page ID provided. Use '${OpenPageToolId}' first.`);75}7677let selector = params.selector;78if (params.ref) {79selector = `aria-ref=${params.ref}`;80}8182if (!selector) {83return errorResult('Either a "ref" or "selector" parameter is required.');84}8586return playwrightInvoke(this.playwrightService, params.pageId, (page, sel) => page.locator(sel).hover(), selector);87}88}899091