UNPKG

chrome-devtools-frontend

Version:
123 lines (105 loc) 3.82 kB
// Copyright 2026 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import * as Host from '../../../core/host/host.js'; import * as i18n from '../../../core/i18n/i18n.js'; import type * as Platform from '../../../core/platform/platform.js'; import {canResourceContentsBeReadForTrace} from '../AiOrigins.js'; import {PerformanceTraceContext} from '../contexts/PerformanceTraceContext.js'; import { type BaseToolCapability, type DataHandlerResult, type DataTool, type ToolArgs, ToolName, } from './Tool.js'; const UIStringsNotTranslate = { lookingUpFunctionCode: 'Looking up function code', } as const; const lockedString = i18n.i18n.lockedString; export interface GetFunctionCodeArgs extends ToolArgs { scriptUrl: string; line: number; column: number; } export class GetFunctionCodeTool implements DataTool<GetFunctionCodeArgs, string, BaseToolCapability> { readonly name = ToolName.GET_FUNCTION_CODE; readonly description = 'Returns the code for a function defined at the given location. The result is annotated with the runtime performance of each line of code.'; readonly parameters: Host.AidaClient.FunctionObjectParam<keyof GetFunctionCodeArgs> = { type: Host.AidaClient.ParametersTypes.OBJECT, description: 'Arguments for looking up function code.', nullable: false, properties: { scriptUrl: { type: Host.AidaClient.ParametersTypes.STRING, description: 'The url of the function.', nullable: false, }, line: { type: Host.AidaClient.ParametersTypes.INTEGER, description: 'The line number where the function is defined.', nullable: false, }, column: { type: Host.AidaClient.ParametersTypes.INTEGER, description: 'The column number where the function is defined.', nullable: false, }, }, required: ['scriptUrl', 'line', 'column'], }; displayInfoFromArgs(params: GetFunctionCodeArgs): { title: string, action: string, } { return { title: lockedString(UIStringsNotTranslate.lookingUpFunctionCode), action: `getFunctionCode('${params.scriptUrl}', ${params.line}, ${params.column})`, }; } async handler( params: GetFunctionCodeArgs, capabilities: BaseToolCapability, ): Promise<DataHandlerResult<string>> { const conversationContext = capabilities.conversationContext; if (!conversationContext || !(conversationContext instanceof PerformanceTraceContext)) { return {error: 'Performance trace context is not available.'}; } if (conversationContext.getOrigin().startsWith('imported-trace://')) { return {error: 'Cannot use this tool on an imported file.'}; } if (!params.scriptUrl) { return {error: 'Missing arg: scriptUrl'}; } const allowedOrigin = conversationContext.getOrigin(); if (!canResourceContentsBeReadForTrace(params.scriptUrl, allowedOrigin)) { return {error: 'Script not found'}; } if (params.line === undefined) { return {error: 'Missing arg: line'}; } if (params.column === undefined) { return {error: 'Missing arg: column'}; } const formatter = conversationContext.createFormatter(); const url = params.scriptUrl as Platform.DevToolsPath.UrlString; const code = await formatter.resolveFunctionCodeAtLocation(url, params.line, params.column); if (!code) { return {error: 'Could not find code'}; } const result = formatter.formatFunctionCode(code); return { result, widgets: [{ name: 'SOURCE_CODE', data: { url, line: params.line, column: params.column, code: code.code, }, }], }; } }