import * as plugins from './plugins.js'; import * as interfaces from './smartagent.interfaces.js'; import { BaseToolWrapper } from './smartagent.tools.base.js'; /** * Browser tool for web page interaction * Wraps @push.rocks/smartbrowser (Puppeteer-based) */ export class BrowserTool extends BaseToolWrapper { public name = 'browser'; public description = 'Interact with web pages - take screenshots, generate PDFs, and execute JavaScript on pages'; public actions: interfaces.IToolAction[] = [ { name: 'screenshot', description: 'Take a screenshot of a webpage', parameters: { type: 'object', properties: { url: { type: 'string', description: 'URL of the page to screenshot' }, }, required: ['url'], }, }, { name: 'pdf', description: 'Generate a PDF from a webpage', parameters: { type: 'object', properties: { url: { type: 'string', description: 'URL of the page to convert to PDF' }, }, required: ['url'], }, }, { name: 'evaluate', description: 'Execute JavaScript code on a webpage and return the result. The script runs in the browser context.', parameters: { type: 'object', properties: { url: { type: 'string', description: 'URL of the page to run the script on' }, script: { type: 'string', description: 'JavaScript code to execute. Must be a valid expression or statements that return a value.', }, }, required: ['url', 'script'], }, }, { name: 'getPageContent', description: 'Get the text content and title of a webpage', parameters: { type: 'object', properties: { url: { type: 'string', description: 'URL of the page to get content from' }, }, required: ['url'], }, }, ]; private smartbrowser!: plugins.smartbrowser.SmartBrowser; public async initialize(): Promise { this.smartbrowser = new plugins.smartbrowser.SmartBrowser(); await this.smartbrowser.start(); this.isInitialized = true; } public async cleanup(): Promise { if (this.smartbrowser) { await this.smartbrowser.stop(); } this.isInitialized = false; } public async execute( action: string, params: Record ): Promise { this.validateAction(action); this.ensureInitialized(); try { switch (action) { case 'screenshot': { const result = await this.smartbrowser.screenshotFromPage(params.url as string); return { success: true, result: { url: params.url, name: result.name, id: result.id, bufferBase64: Buffer.from(result.buffer).toString('base64'), bufferLength: result.buffer.length, type: 'screenshot', }, }; } case 'pdf': { const result = await this.smartbrowser.pdfFromPage(params.url as string); return { success: true, result: { url: params.url, name: result.name, id: result.id, bufferBase64: Buffer.from(result.buffer).toString('base64'), bufferLength: result.buffer.length, type: 'pdf', }, }; } case 'evaluate': { const script = params.script as string; // Create an async function from the script // The script should be valid JavaScript that returns a value const result = await this.smartbrowser.evaluateOnPage(params.url as string, async () => { // This runs in the browser context // We need to evaluate the script string dynamically // eslint-disable-next-line no-eval return eval(script); }); return { success: true, result: { url: params.url, script: script.substring(0, 200) + (script.length > 200 ? '...' : ''), evaluationResult: result, }, }; } case 'getPageContent': { const result = await this.smartbrowser.evaluateOnPage(params.url as string, async () => { return { title: document.title, textContent: document.body?.innerText || '', url: window.location.href, }; }); return { success: true, result: { url: params.url, title: result.title, textContent: result.textContent.length > 10000 ? result.textContent.substring(0, 10000) + '... [truncated]' : result.textContent, actualUrl: result.url, }, }; } default: return { success: false, error: `Unknown action: ${action}`, }; } } catch (error) { return { success: false, error: error instanceof Error ? error.message : String(error), }; } } public getCallSummary(action: string, params: Record): string { switch (action) { case 'screenshot': return `Take screenshot of "${params.url}"`; case 'pdf': return `Generate PDF from "${params.url}"`; case 'evaluate': { const script = params.script as string; const preview = script.length > 100 ? script.substring(0, 100) + '...' : script; return `Execute JavaScript on "${params.url}": "${preview}"`; } case 'getPageContent': return `Get text content and title from "${params.url}"`; default: return `Unknown action: ${action}`; } } }