39 lines
2.7 KiB
JavaScript
39 lines
2.7 KiB
JavaScript
const BROWSER_ACTIONS = ['navigate', 'snapshot', 'click', 'type', 'press', 'scroll', 'wait'];
|
|
|
|
export function createBrowserTools({ browser } = {}) {
|
|
return [{
|
|
name: 'browser',
|
|
permission: 'read',
|
|
description: 'The only web tool. Drive the headed Jarvis Chromium window. Not computer-use and not web_search or web_fetch; those are removed. To search, navigate to https://duckduckgo.com/?q=QUERY or https://www.google.com/search?q=QUERY, then snapshot and click a result ref. action: navigate (url, returns page text), snapshot, click (ref from the last snapshot), type (ref + text, optional submit), press (key), scroll (dy), wait (ms). Always snapshot or navigate before click or type; refs change after every action. Read the text field, then think. Cookie banners: snapshot, then click Accept by ref. If challenge is true, ask the user to finish the visible Jarvis browser window, then snapshot again. Public IP: navigate to https://ifconfig.me/ip. Private and localhost urls are blocked. Do not speak refs or JSON. Do not use curl, wget, cu_observe, or cu_click for websites.',
|
|
parameters: {
|
|
type: 'object',
|
|
properties: {
|
|
action: {
|
|
type: 'string',
|
|
enum: BROWSER_ACTIONS,
|
|
description: 'navigate opens url. snapshot lists numbered refs. click/type need ref from that snapshot. press needs key. scroll uses dy. wait uses ms.',
|
|
},
|
|
url: { type: 'string', description: 'Public http or https url for navigate.' },
|
|
ref: { type: 'string', description: 'Numbered control from the last snapshot, for click or type.' },
|
|
text: { type: 'string', description: 'Text to type into ref, or a click-by-label fallback, or wait-for text.' },
|
|
key: { type: 'string', description: 'Key or chord for press, such as Enter, Tab, Escape, Control+l.' },
|
|
selector: { type: 'string', description: 'Optional CSS selector when a snapshot ref is missing.' },
|
|
dy: { type: 'number', description: 'Vertical scroll pixels. Positive scrolls down.' },
|
|
dx: { type: 'number', description: 'Horizontal scroll pixels.' },
|
|
ms: { type: 'number', description: 'Milliseconds to wait, cap 20000.' },
|
|
submit: { type: 'boolean', description: 'After type, press Enter.' },
|
|
},
|
|
required: ['action'],
|
|
},
|
|
execute: async (input = {}) => {
|
|
if (!browser || typeof browser.call !== 'function') throw new Error('Jarvis browser helper unavailable');
|
|
const action = String(input.action || '').trim();
|
|
if (!action) throw new Error('action required');
|
|
const { action: _ignored, ...payload } = input;
|
|
return browser.call(action, payload);
|
|
},
|
|
}];
|
|
}
|
|
|
|
export { BROWSER_ACTIONS };
|