Repository navigation
feat(tools): add a browser tool - #1626
Conversation
nc-review: needs work — 1 blocking, 3 important, 1 nit@Dhirenderchoudhary — there is a blocking item below. Adds a Playwright-backed 🔴 blocking · The new image branch emits a tool-result with
The new unit test ( 🟠 important · The early return for 🟠 important ·
🟠 important · The new "emits image-data parts for tool screenshots" test asserts the converter output shape but does not exercise a provider. Combined with the unverifiable ⚪ nit · I could not fully reconcile the diff hunk 🔴 blocking · 🟠 a reviewer would ask for a change · ⚪ optional Automated code review — correctness, security, design, tests, plus duplicates and scope. A human still decides; this is not a substitute for review and is not exhaustive. The required status checks separately cover lint, formatting, types, unused dependencies, the test suite and the build. This bot never merges. Maintainers can rerun with |
|
Thanks @Dhirenderchoudhary, this is a big step and the structure is clean (lazy Playwright
Smaller: browser-page.ts caches the page forever, so a crashed browser stays broken until Happy to help with any of these. |
|
Thanks @addyCooks, pushed fixes for all four:
|
addyCooks
left a comment
There was a problem hiding this comment.
Thanks @Dhirenderchoudhary, nice turnaround.
I re-checked the new head (4f149d1) and all four points are addressed:
- openai-compatible screenshots: the tool message is now text-only and the image arrives as an
image_urlpart in a following user message. I re-ran my request-body probe against the real @ai-sdk/openai-compatible provider: the tool message is ~30 chars with no base64, and the order is valid (user > assistant > tool > user). Anthropic, Google and OpenAI Responses keep the inline path. - Host guard: I probed 18 URLs. Metadata, 10.x / 172.16.x / 192.168.x / 100.64.x, 0.0.0.0, IPv6 private and mapped forms, and hex/decimal IP encodings are blocked; localhost, 127.0.0.1, ::1 and *.localhost still work. Redirect landings are caught too.
- Models listed as text-only get the caption without the image.
- A crashed or disconnected browser relaunches on the next call.
Types, lint, format, knip and the related specs pass locally, and CI is green.
Known limits, none blocking (happy to track them as follow-ups):
- The guard checks literal hostnames only, so a public name that resolves to a private IP is not blocked. fetch_url has the same limit today, and #1662 is working on it.
- Models that models.dev doesn't list (most local ones) still receive the image, so a text-only local model may reject it.
- Localhost stays reachable in headless mode by design.
Approving 🎉
Description
Adds a built-in
browsertool so the agent can open a page, click, type, and see a screenshot. Screenshot bytes travel as image parts on the tool result, including when a subagent runs the tool. Fixes #1488.Type of Change
Changeset
pnpm changeset) describing this change for the changelogDocs-only or internal chores need no changeset (or run
pnpm changeset --emptyto note that intentionally).Testing
Automated Tests
.spec.ts/tsxfilespnpm test:allcompletes successfully)Manual Testing
Checklist