claudetool: streamline browser tools
browser_click, browser_type, browser_get_text, browser_scroll_into_view,
browser_resize, and wait_for can all be easily implemented using browser_eval,
if browser_eval is given an await parameter.
A bit of testing suggests that they are more robust in practice
that way, and that multiple tool calls can be combined
into a single browser_eval call, which reduces latency.
And Sketch does in fact use them as needed.
Also, bump up timeouts; empirically, 5 seconds is not enough.
As a bonus, fewer tools is better for context management.
Co-Authored-By: sketch <hello@sketch.dev>
Change-ID: s8d8cd418f3e97f26k
diff --git a/loop/testdata/agent_loop.httprr b/loop/testdata/agent_loop.httprr
index e485771..d3eeeae 100644
--- a/loop/testdata/agent_loop.httprr
+++ b/loop/testdata/agent_loop.httprr
@@ -1,9 +1,9 @@
httprr trace v1
-18043 2288
+15131 2320
POST https://api.anthropic.com/v1/messages HTTP/1.1
Host: api.anthropic.com
User-Agent: Go-http-client/1.1
-Content-Length: 17845
+Content-Length: 14933
Anthropic-Version: 2023-06-01
Content-Type: application/json
@@ -311,7 +311,7 @@
},
"timeout": {
"type": "string",
- "description": "Timeout as a Go duration string (default: 5s)"
+ "description": "Timeout as a Go duration string (default: 15s)"
}
},
"required": [
@@ -320,101 +320,8 @@
}
},
{
- "name": "browser_click",
- "description": "Click the first element matching a CSS selector",
- "input_schema": {
- "type": "object",
- "properties": {
- "selector": {
- "type": "string",
- "description": "CSS selector for the element to click"
- },
- "wait_visible": {
- "type": "boolean",
- "description": "Wait for the element to be visible before clicking"
- },
- "timeout": {
- "type": "string",
- "description": "Timeout as a Go duration string (default: 5s)"
- }
- },
- "required": [
- "selector"
- ]
- }
- },
- {
- "name": "browser_type",
- "description": "Type text into an input or textarea element",
- "input_schema": {
- "type": "object",
- "properties": {
- "selector": {
- "type": "string",
- "description": "CSS selector for the input element"
- },
- "text": {
- "type": "string",
- "description": "Text to type into the element"
- },
- "clear": {
- "type": "boolean",
- "description": "Clear the input field before typing"
- },
- "timeout": {
- "type": "string",
- "description": "Timeout as a Go duration string (default: 5s)"
- }
- },
- "required": [
- "selector",
- "text"
- ]
- }
- },
- {
- "name": "browser_wait_for",
- "description": "Wait for an element to be present in the DOM",
- "input_schema": {
- "type": "object",
- "properties": {
- "selector": {
- "type": "string",
- "description": "CSS selector for the element to wait for"
- },
- "timeout": {
- "type": "string",
- "description": "Timeout as a Go duration string (default: 5s)"
- }
- },
- "required": [
- "selector"
- ]
- }
- },
- {
- "name": "browser_get_text",
- "description": "Get the innerText of an element, returned in innerText tag. Can be used to read the web page.",
- "input_schema": {
- "type": "object",
- "properties": {
- "selector": {
- "type": "string",
- "description": "CSS selector for the element to get text from"
- },
- "timeout": {
- "type": "string",
- "description": "Timeout as a Go duration string (default: 5s)"
- }
- },
- "required": [
- "selector"
- ]
- }
- },
- {
"name": "browser_eval",
- "description": "Evaluate JavaScript in the browser context",
+ "description": "Evaluate JavaScript in the browser context.\nYour go-to tool for interacting with content: clicking buttons, typing, getting content, scrolling, resizing, waiting for content/selector to be ready, etc.",
"input_schema": {
"type": "object",
"properties": {
@@ -424,7 +331,11 @@
},
"timeout": {
"type": "string",
- "description": "Timeout as a Go duration string (default: 5s)"
+ "description": "Timeout as a Go duration string (default: 15s)"
+ },
+ "await": {
+ "type": "boolean",
+ "description": "If true, wait for promises to resolve and return their resolved value (default: true)"
}
},
"required": [
@@ -433,51 +344,6 @@
}
},
{
- "name": "browser_scroll_into_view",
- "description": "Scroll an element into view if it's not visible",
- "input_schema": {
- "type": "object",
- "properties": {
- "selector": {
- "type": "string",
- "description": "CSS selector for the element to scroll into view"
- },
- "timeout": {
- "type": "string",
- "description": "Timeout as a Go duration string (default: 5s)"
- }
- },
- "required": [
- "selector"
- ]
- }
- },
- {
- "name": "browser_resize",
- "description": "Resize the browser window to a specific width and height",
- "input_schema": {
- "type": "object",
- "properties": {
- "width": {
- "type": "integer",
- "description": "Window width in pixels"
- },
- "height": {
- "type": "integer",
- "description": "Window height in pixels"
- },
- "timeout": {
- "type": "string",
- "description": "Timeout as a Go duration string (default: 5s)"
- }
- },
- "required": [
- "width",
- "height"
- ]
- }
- },
- {
"name": "browser_recent_console_logs",
"description": "Get recent browser console logs",
"input_schema": {
@@ -510,7 +376,7 @@
},
"timeout": {
"type": "string",
- "description": "Timeout as a Go duration string (default: 5s)"
+ "description": "Timeout as a Go duration string (default: 15s)"
}
}
}
@@ -527,7 +393,7 @@
},
"timeout": {
"type": "string",
- "description": "Timeout as a Go duration string (default: 5s)"
+ "description": "Timeout as a Go duration string (default: 15s)"
}
},
"required": [
@@ -549,24 +415,24 @@
Anthropic-Organization-Id: 3c473a21-7208-450a-a9f8-80aebda45c1b
Anthropic-Ratelimit-Input-Tokens-Limit: 2000000
Anthropic-Ratelimit-Input-Tokens-Remaining: 2000000
-Anthropic-Ratelimit-Input-Tokens-Reset: 2025-07-31T04:47:48Z
+Anthropic-Ratelimit-Input-Tokens-Reset: 2025-07-31T04:56:24Z
Anthropic-Ratelimit-Output-Tokens-Limit: 400000
Anthropic-Ratelimit-Output-Tokens-Remaining: 400000
-Anthropic-Ratelimit-Output-Tokens-Reset: 2025-07-31T04:47:53Z
+Anthropic-Ratelimit-Output-Tokens-Reset: 2025-07-31T04:56:28Z
Anthropic-Ratelimit-Requests-Limit: 4000
Anthropic-Ratelimit-Requests-Remaining: 3999
-Anthropic-Ratelimit-Requests-Reset: 2025-07-31T04:47:47Z
+Anthropic-Ratelimit-Requests-Reset: 2025-07-31T04:56:23Z
Anthropic-Ratelimit-Tokens-Limit: 2400000
Anthropic-Ratelimit-Tokens-Remaining: 2400000
-Anthropic-Ratelimit-Tokens-Reset: 2025-07-31T04:47:48Z
+Anthropic-Ratelimit-Tokens-Reset: 2025-07-31T04:56:24Z
Cf-Cache-Status: DYNAMIC
-Cf-Ray: 967a75b2793ccf0e-SJC
+Cf-Ray: 967a824a7d62fa9e-SJC
Content-Type: application/json
-Date: Thu, 31 Jul 2025 04:47:53 GMT
-Request-Id: req_011CReVS1GWZPU1iZLUbAfLH
+Date: Thu, 31 Jul 2025 04:56:28 GMT
+Request-Id: req_011CReW62geX1vzU8VqNitZS
Server: cloudflare
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Via: 1.1 google
X-Robots-Tag: none
-{"id":"msg_01MpXPbWAfaBn5voE1Fa5THr","type":"message","role":"assistant","model":"claude-sonnet-4-20250514","content":[{"type":"text","text":"Here are the tools available to me:\n\n**File & Code Operations:**\n- `bash` - Execute shell commands\n- `patch` - Modify files with precise text edits\n- `keyword_search` - Search for files by content/concepts\n\n**Task Management:**\n- `todo_read` / `todo_write` - Track and manage task lists\n- `think` - Internal notes and planning\n\n**Development Workflow:**\n- `codereview` - Automated code review\n- `done` - Final checklist before completion\n\n**Browser Automation:**\n- `browser_navigate` - Navigate to URLs\n- `browser_click` / `browser_type` - Interact with elements\n- `browser_wait_for` / `browser_get_text` - Wait for and read content\n- `browser_eval` - Execute JavaScript\n- `browser_scroll_into_view` / `browser_resize` - View manipulation\n- `browser_take_screenshot` / `browser_recent_console_logs` - Debugging\n\n**System Info:**\n- `about_sketch` - Information about the Sketch environment\n- `read_image` - Read and encode image files"}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":3,"cache_creation_input_tokens":4135,"cache_read_input_tokens":0,"output_tokens":261,"service_tier":"standard"}}
\ No newline at end of file
+{"id":"msg_0151My8VR6BwVPfBkrvtw6ne","type":"message","role":"assistant","model":"claude-sonnet-4-20250514","content":[{"type":"text","text":"Here are the tools available to me:\n\n**File & Code Management:**\n- `bash` - Execute shell commands\n- `patch` - Modify files with precise text edits\n- `keyword_search` - Search for files using keywords and queries\n\n**Task Management:**\n- `todo_read` - Read current todo list\n- `todo_write` - Create and manage task lists\n- `think` - Record thoughts and plans\n\n**Development Workflow:**\n- `done` - Mark work complete with verification checklist\n- `codereview` - Run automated code review\n- `about_sketch` - Get information about Sketch environment\n\n**Browser Automation:**\n- `browser_navigate` - Navigate to URLs\n- `browser_eval` - Execute JavaScript in browser\n- `browser_recent_console_logs` - Get console logs\n- `browser_clear_console_logs` - Clear console logs\n- `browser_take_screenshot` - Take screenshots\n- `read_image` - Read and encode image files\n\nThese tools enable autonomous coding, testing, file management, browser automation, and project organization."}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":3,"cache_creation_input_tokens":3505,"cache_read_input_tokens":0,"output_tokens":244,"service_tier":"standard"}}
\ No newline at end of file