Skip to content

Commit 50132e8

Browse files
authored
Merge pull request #97 from triepod-ai/feat/add-tool-annotations
feat: Add tool annotations for improved LLM tool understanding
2 parents 34918a7 + eb4b454 commit 50132e8

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed

browser_tools.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ const calculate_cdp_endpoint = async country=>{
5252
let scraping_browser_navigate = {
5353
name: 'scraping_browser_navigate',
5454
description: 'Navigate a scraping browser session to a new URL',
55+
annotations: {
56+
title: 'Browser Navigate',
57+
destructiveHint: true,
58+
openWorldHint: true,
59+
},
5560
parameters: z.object({
5661
url: z.string().describe('The URL to navigate to'),
5762
country: z.string().regex(/^[A-Za-z]{2}$/)
@@ -83,6 +88,10 @@ let scraping_browser_navigate = {
8388
let scraping_browser_go_back = {
8489
name: 'scraping_browser_go_back',
8590
description: 'Go back to the previous page',
91+
annotations: {
92+
title: 'Browser Go Back',
93+
destructiveHint: true,
94+
},
8695
parameters: z.object({}),
8796
execute: async()=>{
8897
const page = await (await require_browser()).get_page();
@@ -102,6 +111,10 @@ let scraping_browser_go_back = {
102111
const scraping_browser_go_forward = {
103112
name: 'scraping_browser_go_forward',
104113
description: 'Go forward to the next page',
114+
annotations: {
115+
title: 'Browser Go Forward',
116+
destructiveHint: true,
117+
},
105118
parameters: z.object({}),
106119
execute: async()=>{
107120
const page = await (await require_browser()).get_page();
@@ -128,6 +141,10 @@ let scraping_browser_snapshot = {
128141
'Use this before interacting with elements to get proper refs instead '
129142
+'of guessing selectors.'
130143
].join('\n'),
144+
annotations: {
145+
title: 'Browser Snapshot',
146+
readOnlyHint: true,
147+
},
131148
parameters: z.object({
132149
filtered: z.boolean().optional().describe(
133150
'Whether to apply filtering/compaction (default: false). '
@@ -166,6 +183,10 @@ let scraping_browser_click_ref = {
166183
'Use scraping_browser_snapshot first to get the correct ref values.',
167184
'This is more reliable than CSS selectors.'
168185
].join('\n'),
186+
annotations: {
187+
title: 'Browser Click Element',
188+
destructiveHint: true,
189+
},
169190
parameters: z.object({
170191
ref: z.string().describe('The ref attribute from the ARIA snapshot (e.g., "23")'),
171192
element: z.string().describe('Description of the element being clicked for context'),
@@ -189,6 +210,10 @@ let scraping_browser_type_ref = {
189210
'Use scraping_browser_snapshot first to get the correct ref values.',
190211
'This is more reliable than CSS selectors.'
191212
].join('\n'),
213+
annotations: {
214+
title: 'Browser Type Text',
215+
destructiveHint: true,
216+
},
192217
parameters: z.object({
193218
ref: z.string().describe('The ref attribute from the ARIA snapshot (e.g., "23")'),
194219
element: z.string().describe('Description of the element being typed into for context'),
@@ -215,6 +240,10 @@ let scraping_browser_type_ref = {
215240
let scraping_browser_screenshot = {
216241
name: 'scraping_browser_screenshot',
217242
description: 'Take a screenshot of the current page',
243+
annotations: {
244+
title: 'Browser Screenshot',
245+
readOnlyHint: true,
246+
},
218247
parameters: z.object({
219248
full_page: z.boolean().optional().describe([
220249
'Whether to screenshot the full page (default: false)',
@@ -238,6 +267,10 @@ let scraping_browser_get_html = {
238267
description: 'Get the HTML content of the current page. Avoid using this '
239268
+'tool and if used, use full_page option unless it is important to see '
240269
+'things like script tags since this can be large',
270+
annotations: {
271+
title: 'Browser Get HTML',
272+
readOnlyHint: true,
273+
},
241274
parameters: z.object({
242275
full_page: z.boolean().optional().describe([
243276
'Whether to get the full page HTML including head and script tags',
@@ -263,6 +296,10 @@ let scraping_browser_get_html = {
263296
let scraping_browser_get_text = {
264297
name: 'scraping_browser_get_text',
265298
description: 'Get the text content of the current page',
299+
annotations: {
300+
title: 'Browser Get Text',
301+
readOnlyHint: true,
302+
},
266303
parameters: z.object({}),
267304
execute: async()=>{
268305
const page = await (await require_browser()).get_page();
@@ -274,6 +311,10 @@ let scraping_browser_get_text = {
274311
let scraping_browser_scroll = {
275312
name: 'scraping_browser_scroll',
276313
description: 'Scroll to the bottom of the current page',
314+
annotations: {
315+
title: 'Browser Scroll',
316+
destructiveHint: true,
317+
},
277318
parameters: z.object({}),
278319
execute: async()=>{
279320
const page = await (await require_browser()).get_page();
@@ -295,6 +336,10 @@ let scraping_browser_scroll_to_ref = {
295336
'Use scraping_browser_snapshot first to get the correct ref values.',
296337
'This is more reliable than CSS selectors.'
297338
].join('\n'),
339+
annotations: {
340+
title: 'Browser Scroll to Element',
341+
destructiveHint: true,
342+
},
298343
parameters: z.object({
299344
ref: z.string().describe('The ref attribute from the ARIA snapshot (e.g., "23")'),
300345
element: z.string().describe('Description of the element to scroll to'),
@@ -320,6 +365,10 @@ let scraping_browser_network_requests = {
320365
'Useful for debugging API calls, tracking data fetching, and '
321366
+'understanding page behavior.'
322367
].join('\n'),
368+
annotations: {
369+
title: 'Browser Network Requests',
370+
readOnlyHint: true,
371+
},
323372
parameters: z.object({}),
324373
execute: async()=>{
325374
const browser_session = await require_browser();
@@ -356,6 +405,10 @@ let scraping_browser_wait_for_ref = {
356405
'Use scraping_browser_snapshot first to get the correct ref values.',
357406
'This is more reliable than CSS selectors.'
358407
].join('\n'),
408+
annotations: {
409+
title: 'Browser Wait for Element',
410+
readOnlyHint: true,
411+
},
359412
parameters: z.object({
360413
ref: z.string().describe('The ref attribute from the ARIA snapshot (e.g., "23")'),
361414
element: z.string().describe('Description of the element being waited for'),

server.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,11 @@ addTool({
176176
description: 'Scrape search results from Google, Bing or Yandex. Returns '
177177
+'SERP results in JSON or Markdown (URL, title, description), Ideal for'
178178
+'gathering current information, news, and detailed search results.',
179+
annotations: {
180+
title: 'Search Engine',
181+
readOnlyHint: true,
182+
openWorldHint: true,
183+
},
179184
parameters: z.object({
180185
query: z.string(),
181186
engine: z.enum(['google', 'bing', 'yandex'])
@@ -220,6 +225,11 @@ addTool({
220225
+'content extraction and get back the results in MarkDown language. '
221226
+'This tool can unlock any webpage even if it uses bot detection or '
222227
+'CAPTCHA.',
228+
annotations: {
229+
title: 'Scrape as Markdown',
230+
readOnlyHint: true,
231+
openWorldHint: true,
232+
},
223233
parameters: z.object({url: z.string().url()}),
224234
execute: tool_fn('scrape_as_markdown', async({url}, ctx)=>{
225235
let response = await axios({
@@ -246,6 +256,11 @@ addTool({
246256
name: 'search_engine_batch',
247257
description: 'Run multiple search queries simultaneously. Returns '
248258
+'JSON for Google, Markdown for Bing/Yandex.',
259+
annotations: {
260+
title: 'Search Engine Batch',
261+
readOnlyHint: true,
262+
openWorldHint: true,
263+
},
249264
parameters: z.object({
250265
queries: z.array(z.object({
251266
query: z.string(),
@@ -309,6 +324,11 @@ addTool({
309324
+'content extraction and get back the results in MarkDown language. '
310325
+'This tool can unlock any webpage even if it uses bot detection or '
311326
+'CAPTCHA.',
327+
annotations: {
328+
title: 'Scrape Batch',
329+
readOnlyHint: true,
330+
openWorldHint: true,
331+
},
312332
parameters: z.object({
313333
urls: z.array(z.string().url()).min(1).max(10).describe('Array of URLs to scrape (max 10)')
314334
}),
@@ -342,6 +362,11 @@ addTool({
342362
+'content extraction and get back the results in HTML. '
343363
+'This tool can unlock any webpage even if it uses bot detection or '
344364
+'CAPTCHA.',
365+
annotations: {
366+
title: 'Scrape as HTML',
367+
readOnlyHint: true,
368+
openWorldHint: true,
369+
},
345370
parameters: z.object({url: z.string().url()}),
346371
execute: tool_fn('scrape_as_html', async({url}, ctx)=>{
347372
let response = await axios({
@@ -365,6 +390,11 @@ addTool({
365390
+ 'First scrapes the page as markdown, then uses AI sampling to convert '
366391
+ 'it to structured JSON format. This tool can unlock any webpage even '
367392
+ 'if it uses bot detection or CAPTCHA.',
393+
annotations: {
394+
title: 'Extract Structured Data',
395+
readOnlyHint: true,
396+
openWorldHint: true,
397+
},
368398
parameters: z.object({
369399
url: z.string().url(),
370400
extraction_prompt: z.string().optional().describe(
@@ -419,6 +449,10 @@ addTool({
419449
addTool({
420450
name: 'session_stats',
421451
description: 'Tell the user about the tool usage during this session',
452+
annotations: {
453+
title: 'Session Stats',
454+
readOnlyHint: true,
455+
},
422456
parameters: z.object({}),
423457
execute: tool_fn('session_stats', async()=>{
424458
let used_tools = Object.entries(debug_stats.tool_calls);
@@ -826,6 +860,12 @@ const datasets = [{
826860
].join('\n'),
827861
inputs: ['url'],
828862
}];
863+
const dataset_id_to_title = id=>{
864+
return id.split('_')
865+
.map(word=>word.charAt(0).toUpperCase()+word.slice(1))
866+
.join(' ');
867+
};
868+
829869
for (let {dataset_id, id, description, inputs, defaults = {}, fixed_values = {}} of datasets)
830870
{
831871
const tool_name = `web_data_${id}`;
@@ -839,6 +879,11 @@ for (let {dataset_id, id, description, inputs, defaults = {}, fixed_values = {}}
839879
addTool({
840880
name: tool_name,
841881
description,
882+
annotations: {
883+
title: dataset_id_to_title(id),
884+
readOnlyHint: true,
885+
openWorldHint: true,
886+
},
842887
parameters: z.object(parameters),
843888
execute: tool_fn(tool_name, async(data, ctx)=>{
844889
data = {...data, ...fixed_values};

0 commit comments

Comments
 (0)