#12378: feat: expose download and waitForDownload actions in browser agent tool
agents
stale
Cluster:
Browser Enhancements and Fixes
## 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
#11692: feat: add standalone browser CLI for Linux users
by shipitirl · 2026-02-08
76.6%
#14728: fix(browser): add targetUrl description and improve error messages ...
by lailoo · 2026-02-12
75.9%
#8303: fix(browser): enable downloads via CDP Browser.setDownloadBehavior
by gavinbmoore · 2026-02-03
75.8%
#23075: fix(browser): merge top-level ref/targetId into act request body
by Remixer33 · 2026-02-22
73.9%
#10367: CLI/Ops: resilient browser fill + failover hardening + operations t...
by cluster2600 · 2026-02-06
73.7%
#12075: feat(browser): session-aware context isolation for multi-agent brow...
by xiaoyaner0201 · 2026-02-08
73.6%
#8718: fix: sanitize download filenames to prevent path traversal (CWE-22)
by DevZenPro · 2026-02-04
73.3%
#7982: Save API Usage: Use Atlas Browser ChatGPT Capabilities
by yaoshengwang · 2026-02-03
72.9%
#7589: Tests: accept browser profiles auth option
by justinhuangcode · 2026-02-03
72.8%
#3794: fix(browser-tool): disallow close without targetId to avoid unsafe ...
by JaydenLiang · 2026-01-29
72.5%