UNPKG

donobu

Version:

Create browser automations with an LLM agent and replay them as Playwright scripts.

117 lines 5.67 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.GoToGoogleMapsStreetViewTool = void 0; const Tool_1 = require("./Tool"); const ToolCallResult_1 = require("../models/ToolCallResult"); const AggregateExtractedStreetviewDataTool_1 = require("./AggregateExtractedStreetviewDataTool"); const PlaywrightUtils_1 = require("../utils/PlaywrightUtils"); const MiscUtils_1 = require("../utils/MiscUtils"); const Logger_1 = require("../utils/Logger"); /** * Attempts to verify that the given business/entity exists at the given location by using a Google * Maps street view. If the business/entity is found, then a AggregateExtractedStreetviewDataTool * tool call is queued containing the results. */ class GoToGoogleMapsStreetViewTool extends Tool_1.Tool { constructor() { super(GoToGoogleMapsStreetViewTool.NAME, 'Go to the Google Maps street view of a given business/entity by name and location.', 'GoToGoogleMapsStreetViewToolCoreParameters', 'GoToGoogleMapsStreetViewToolGptParameters'); } async call(context, parameters) { const page = context.page; const entityName = parameters.entityName.trim(); const entityLocation = parameters.entityLocation.trim(); if (!(await this.setStreetView(entityName, entityLocation, page))) { context.proposedToolCalls.length = 0; context.proposedToolCalls.push({ name: AggregateExtractedStreetviewDataTool_1.AggregateExtractedStreetviewDataTool.NAME, parameters: {}, }); return { isSuccessful: false, forLlm: 'Unable to set the street-view mode for Google Maps!', metadata: null, }; } else { await PlaywrightUtils_1.PlaywrightUtils.waitForPageStability(page); return ToolCallResult_1.ToolCallResult.successful(); } } callFromGpt(context, parameters) { return this.call(context, parameters); } async setStreetView(entityName, entityLocation, page) { const googleMapsCombinedQuery = `${entityName} ${entityLocation}`.trim(); // TODO: Try using the peg-man if these calls fail. return ((await this.setStreetViewUsingQuery(googleMapsCombinedQuery, page)) || (await this.setStreetViewUsingQuery(entityLocation, page))); } async setStreetViewUsingQuery(googleMapsQuery, page) { const encodedQuery = encodeURIComponent(googleMapsQuery); const googleMapsUrl = 'https://www.google.com/maps/search/?api=1&map_action=pano&query=' + encodedQuery; await page.goto(googleMapsUrl); await page.waitForLoadState(); const streetViewButton = page.locator('button[aria-label="Street View"]'); try { await streetViewButton.waitFor({ timeout: 10000 }); await streetViewButton.click({ delay: MiscUtils_1.MiscUtils.generateHumanLikeClickDurationInMs(), }); await page.waitForLoadState(); await page.waitForTimeout(2559); await this.cleanupUiElements(page); return true; } catch (error) { Logger_1.appLogger.error(`Failed to set street view for ${googleMapsUrl}`, error); return false; } } /** * Remove UI elements that can distract the GPT when performing an analysis. This is a fragile * script and will break depending on the device used and on the whims of Google. */ async cleanupUiElements(page) { await page.evaluate(() => { const removeElement = (element) => { if (element) { element.remove(); } }; // This is the search box. removeElement(document.querySelector('#omnibox-singlebox')); // This is miscellaneous footer data. removeElement(document.querySelector('.id-fineprint')); // This is a display card overlay. removeElement(document.querySelector('#titlecard')); // This is the picture-in-picture box. removeElement(Array.from(document.querySelectorAll('div[style]')).find((el) => el.style.marginBottom === '20px')); // Remove the "Share" and "Close" buttons. removeElement(document.querySelector('#image-header')); // Collapse the side panel. let isSidePanelCollapsed = false; // Step 1: Select the button element using the aria-label and jsaction attributes const buttonElement = document.querySelector('button[aria-label="Collapse side panel"][jsaction*="drawer.close"]'); // Check if the button element is selected if (buttonElement) { // Step 2: Find the img element within the button const imgElement = buttonElement.querySelector('img'); // Check if the img element is found within the button if (imgElement) { // Step 3: Click! imgElement.click(); isSidePanelCollapsed = true; } } if (!isSidePanelCollapsed) { // Hack it. removeElement(Array.from(document.querySelectorAll('div[style]')).find((el) => el.style.width === '480px')); } }); await page.waitForLoadState(); } } exports.GoToGoogleMapsStreetViewTool = GoToGoogleMapsStreetViewTool; GoToGoogleMapsStreetViewTool.NAME = 'goToGoogleMapsStreetView'; //# sourceMappingURL=GoToGoogleMapsStreetViewTool.js.map