donobu
Version:
Create browser automations with an LLM agent and replay them as Playwright scripts.
117 lines • 5.67 kB
JavaScript
;
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