UNPKG

donobu

Version:

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

127 lines 5.99 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.RememberPageTextTool = exports.RememberPageTextToolGptSchema = exports.RememberPageTextNonGptSchema = void 0; const v4_1 = require("zod/v4"); const ElementSelector_1 = require("../models/ElementSelector"); const ToolSchema_1 = require("../models/ToolSchema"); const Logger_1 = require("../utils/Logger"); const PlaywrightUtils_1 = require("../utils/PlaywrightUtils"); const TargetUtils_1 = require("../utils/TargetUtils"); const ReplayableInteraction_1 = require("./ReplayableInteraction"); const Tool_1 = require("./Tool"); exports.RememberPageTextNonGptSchema = v4_1.z.object({ name: v4_1.z.string(), selector: ElementSelector_1.ElementSelectorSchema, }); exports.RememberPageTextToolGptSchema = v4_1.z.object({ ...ToolSchema_1.BaseGptArgsSchema.shape, name: v4_1.z .string() .describe('The name for the text to save to the flow env data. The name should be in UPPER_SNAKE_CASE, like you would name an environment variable.'), text: v4_1.z.string().describe('The raw text to save to the flow env data.'), }); /** * Persists text from the current page into the flow env data so subsequent tools can reference it. * - `call` is driven by an explicit selector to extract text from the page. * - `callFromGpt` is driven by provided text and attempts to infer selectors for replayability. */ class RememberPageTextTool extends Tool_1.Tool { constructor() { super(RememberPageTextTool.NAME, `Update the flow env data to remember text from the current webpage.`, exports.RememberPageTextNonGptSchema, exports.RememberPageTextToolGptSchema, false, undefined, ['web']); } async call(context, parameters) { const page = (0, TargetUtils_1.webPage)(context); let labelData = null; const locators = await ReplayableInteraction_1.ReplayableInteraction.getLocatorsOrderedByMatchCount(page, parameters.selector); for (const selectorLocator of locators) { let count = 0; try { count = await selectorLocator.locator.count(); } catch (locatorError) { Logger_1.appLogger.error(`Failed to get selector count for '${selectorLocator.selector}'`, locatorError); } for (let i = 0; i < count && labelData === null; ++i) { try { const originalLocator = selectorLocator.locator.nth(i); const element = (await ReplayableInteraction_1.ReplayableInteraction.getLocatorOrItsLabel(originalLocator)).first(); const text = await element.textContent(); if (text) { labelData = { name: parameters.name, text: text, element: parameters.selector.element, frame: parameters.selector.frame, }; } } catch (elementError) { Logger_1.appLogger.error(`Failed to extract text for ${selectorLocator.selector}[${i}]`, elementError); } } } if (!labelData) { return { isSuccessful: false, forLlm: `Unable to extract '${parameters.name}' from the page!`, metadata: labelData, }; } else { context.envData[parameters.name] = labelData.text; const ref = `{{$.env.${parameters.name}}}`; return { isSuccessful: true, forLlm: `Saved '${parameters.name}' to the flow context. Reference its value by: ${ref}`, metadata: labelData, }; } } async callFromGpt(context, parameters) { const page = (0, TargetUtils_1.webPage)(context); let elementSelector = null; for (const frame of page.frames()) { if (frame.isDetached()) { continue; } let count = 0; let locator; try { locator = frame.getByText(parameters.text); count = await locator.count(); } catch (locatorError) { Logger_1.appLogger.error(`Failed to get locator count for text '${parameters.text}' in frame`, locatorError); continue; } for (let i = 0; i < count && elementSelector === null; ++i) { try { const selectorCandidates = await PlaywrightUtils_1.PlaywrightUtils.generateSelectors(locator.nth(i)); const frameSelector = frame.parentFrame() === null ? null : (await PlaywrightUtils_1.PlaywrightUtils.generateSelectors(await frame.frameElement()))[0]; elementSelector = { element: selectorCandidates, frame: frameSelector, }; } catch (error) { Logger_1.appLogger.warn(`Failed to generate selectors for locator ${i + 1} of ${count} for the text '${parameters.text}', will try other locators if possible.`, error); } } } context.envData[parameters.name] = parameters.text; if (!elementSelector) { Logger_1.appLogger.error(`Unable to generate selectors for extracting the text '${parameters.text}'`); } const ref = `{{$.env.${parameters.name}}}`; return { isSuccessful: true, forLlm: `Saved '${parameters.name}' to the flow context. Reference its value by: ${ref}`, metadata: elementSelector, }; } } exports.RememberPageTextTool = RememberPageTextTool; RememberPageTextTool.NAME = 'rememberPageText'; //# sourceMappingURL=RememberPageTextTool.js.map