← Back to PRs

#12378: feat: expose download and waitForDownload actions in browser agent tool

by vabole open 2026-02-09 06:12 View on GitHub →
agents stale
## Summary The browser download functionality was **fully implemented** at the Playwright layer (`pw-tools-core.downloads.ts`) and CLI layer (`register.files-downloads.ts`) but was **missing from the agent tool** — the interface AI agents actually use via the `browser` tool. This meant agents had no way to download files from websites, forcing workarounds like XHR/fetch interception with localStorage to capture downloads. ## Changes ### New actions in browser agent tool **`download`** — Click a ref and save the resulting download: ```json { "action": "download", "ref": "e12", "path": "/tmp/report.pdf" } ``` **`waitForDownload`** — Wait for the next download (no click): ```json { "action": "waitForDownload", "path": "/tmp/export.csv", "timeoutMs": 30000 } ``` Both return: ```json { "ok": true, "targetId": "...", "download": { "path": "/tmp/report.pdf", "url": "https://example.com/report.pdf", "suggestedFilename": "report.pdf" } } ``` ### Files changed | File | Change | |------|--------| | `browser-tool.ts` | Added `download` and `waitForDownload` case handlers following the existing `upload`/`dialog` pattern | | `browser-tool.schema.ts` | Added both actions to `BROWSER_TOOL_ACTIONS`, added `path` parameter | | `browser-tool.test.ts` | Added unit tests for both actions with proper mocks | ### Design decisions - **Follows existing patterns exactly**: Both actions mirror the `upload`/`dialog` wiring — same `proxyRequest` path for node targets, same `jsonResult` wrapping, same parameter extraction style - **`path` is required for `download`** (you must specify where to save), **optional for `waitForDownload`** (defaults to temp directory) - **No changes to Playwright layer or CLI commands**: Those already worked; this only wires them to the agent-facing tool - **`path` added as schema-level optional parameter**: Runtime enforcement handles required vs optional per action ### Testing - ✅ All 14 browser tool tests pass (12 existing + 2 new) - ✅ TypeScript build passes - ✅ No changes to existing functionality ## Agent prompt used This was implemented by Codex (gpt-5.3-codex, full-auto mode) with the following prompt: <details> <summary>Click to expand prompt</summary> ``` You are working on the OpenClaw project, a personal AI gateway. TASK: Expose the existing browser download functionality to the agent tool. CONTEXT: - The Playwright download integration already exists in `src/browser/pw-tools-core.downloads.ts` with `waitForDownloadViaPlaywright()` and `downloadViaPlaywright()` - The CLI commands already exist in `src/cli/browser-cli-actions-input/register.files-downloads.ts` (waitfordownload, download) - The agent tool is in `src/agents/tools/browser-tool.ts` - The agent tool already exposes "upload" and "dialog" actions (cases in a switch statement around line 603-680) but NOT download - The browser HTTP server that handles routes is likely in `src/browser/` - find the route handlers for `/wait/download` and `/download` WHAT TO DO: 1. Find how the existing "upload" and "dialog" agent tool actions are wired (in browser-tool.ts) — use the exact same pattern 2. Add a "download" action to the browser agent tool that clicks a ref and saves the download (like `downloadViaPlaywright`) 3. Add a "waitForDownload" action that just waits for the next download without clicking (like `waitForDownloadViaPlaywright`) 4. Both should return the file path, URL, and suggested filename 5. Add tests in `src/agents/tools/browser-tool.test.ts` following existing test patterns 6. Make sure the TypeScript compiles: run `npm run build` and fix any errors IMPORTANT: - Follow existing code patterns exactly (imports, error handling, proxyRequest pattern) - The "upload" case around line 603 is your template - Check the schema file too for any type definitions that need updating - Do NOT modify pw-tools-core.downloads.ts - that already works - Do NOT modify the CLI commands - those already work ``` </details> <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR wires existing Playwright/CLI download support into the agent-facing `browser` tool by adding two new actions: `download` (click by ref and save to a specified path) and `waitForDownload` (wait for the next download, optionally specifying a save path). It updates the browser tool schema to accept the new actions and a `path` field, and adds unit coverage that mocks the underlying `browserDownload` / `browserWaitForDownload` client-actions and asserts the tool passes through `ref`, `path`, `targetId`, `timeoutMs`, and `profile`. The change fits into the existing browser tool pattern by routing through the node browser proxy (`proxyRequest`) when available (POST `/download` and `/wait/download`) and falling back to direct client-actions calls otherwise, returning results via the existing `jsonResult` wrapper. <h3>Confidence Score: 4/5</h3> - This PR is close to safe to merge, but the new Vitest mock setup may be order-dependent and flaky in some environments. - Core tool wiring appears consistent with existing proxy/direct call patterns and matches existing server endpoints. Main concern is the new `vi.mock("../../browser/client-actions.js")` factory referencing `browserActionMocks` declared later in the file, which can break depending on Vitest hoisting/evaluation order, leading to intermittent test/runtime failures. - src/agents/tools/browser-tool.test.ts <!-- greptile_other_comments_section --> <sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub> <!-- /greptile_comment -->

Most Similar PRs