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