feat(compact): expose upload_file - #2678
Conversation
|
@alectimison-maker is attempting to deploy a commit to the esokullu's projects Team on Vercel. A member of the Team first needs to authorize it. |
There was a problem hiding this comment.
Pull request overview
Exposes a platform-specific upload_file workflow to Compact Act mode across Chrome and Firefox.
Changes:
- Adds narrow Compact upload schemas and prompt guidance.
- Preserves Ask mode and excludes download workflows.
- Adds cross-browser tool-boundary and guidance tests.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/chrome/src/agent/tools.js |
Adds Chrome Compact upload support. |
src/firefox/src/agent/tools.js |
Adds Firefox Compact upload and picker support. |
test/run.js |
Tests Compact upload schemas, prompts, and boundaries. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| 'click', 'type_text', 'press_keys', | ||
| 'navigate', 'new_tab', 'wait_for_element', | ||
| 'fetch_url', | ||
| 'upload_file', |
| 'click', 'type_text', 'press_keys', | ||
| 'navigate', 'new_tab', 'wait_for_element', | ||
| 'fetch_url', | ||
| 'upload_file', |
|
PR 2678 — feat(compact): expose upload_file What it does: adds upload_file to COMPACT_TOOL_NAMES in both browsers, and rewrites the tool schema for the compact tier only (via compactUploadFileTool) so the model sees a narrower parameter set — Chrome: selector/attachmentId/filePath; Firefox: selector/attachmentId. downloadId is hidden in both. Compact prompts get a matching upload_file line, and the attachment-notice test flips to expect upload guidance in compact. The tier-scoped schema override is a nice pattern — the notice builder (agent.js:20313) already derives canUseUploadTool from the live tool catalog, so the [UNTRUSTED USER ATTACHMENTS] handles start appearing in compact automatically with no extra wiring. Blocking: compact has no way out of the ambiguous-selector gate upload_file sets a per-tab recovery latch on an ambiguous selector, and the only thing that clears it is a successful get_interactive_elements returning a file-input record:
get_interactive_elements is not in COMPACT_TOOL_NAMES (tools.js:1697-1705). So in compact, one ambiguous selector permanently bricks uploads for that tab until a page replacement, and the error text instructs the model to call a tool it doesn't have — the exact "point at an unavailable tool" problem the PR's schema work is trying to avoid. Also note agent.js:17028 (input-not-found) names get_interactive_elements and get_accessibility_tree; the latter is in compact, so that one is only half-wrong. Pick one:
Either way it needs a test — the new test only asserts schema/prompt shape, never exercises the handler. Security: drop filePath from the Chrome compact schema Compact has no downloads, no list_downloads, no read_downloaded_file — so there is no legitimate in-run source for a local path other than the user literally typing one. Meanwhile compact drops the full-tier hardening that exists precisely to stop invented paths (tools.js:1562, the /Users/Shared/… failure note). filePath on Chrome is a CDP-backed arbitrary local-file read that lands in a page input on an untrusted site; compact Act is also the tier most exposed to page-content injection. The schema string "explicitly supplied by the user" is guidance, not enforcement. Recommendation: make compact attachmentId-only on Chrome, matching Firefox. That is a one-line schema change and the compact prompt line loses |filePath. If you keep it, add an explicit "never construct or guess a path; only a path the user typed in this conversation" clause. Related, weaker point: hiding downloadId from the compact schema is prompt-level only — _executeTool still honors it if the model emits it. Harmless today (no downloadIds exist in compact), but it's a soft boundary, not a real one, and the test name (must hide downloadId) reads stronger than what's enforced. Smaller notes
|
An ambiguous selector latches upload_file until get_interactive_elements returns a verified file-input selector, and nothing else clears it. That tool was not in the compact catalog, so one ambiguous selector left compact unable to upload for the rest of the page's life while the handler kept asking for a tool the model had not been given. Compact now carries get_interactive_elements, and the tool description and prompt bullet name it as the recovery path. A test asserts the coupling for every tier that ships upload_file. Compact also no longer advertises filePath. It has no download tools, so the only file it can legitimately reach is the one the user attached to this run; a path could only come from the model inventing one, and on Chrome filePath is a CDP-backed read of any local file into an untrusted page's input. Hidden parameters are now deleted from the base schema rather than rebuilt, so a future upload_file parameter still reaches compact. Prompt assertions moved off character-distance regexes onto the upload_file bullet itself. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The ambiguity test proved the latch clears but stopped there. Assert the step it exists for: after get_interactive_elements supplies a unique selector, the corrected upload dispatches and leaves the latch clear. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Pushed three commits to this branch addressing the ambiguity dead-end and tightening the compact schema. Copilot flagged the same recovery problem on both The dead-end. An ambiguous selector latches I checked whether the latch could clear on something compact already had. It can't: So it's in
While there I switched the transform from rebuilding Tests. The character-distance regexes ( Copilot also asked for coverage of the ambiguous-selector retry itself. The existing handler test proved the latch clears but stopped there, so I extended it through the step the recovery exists for: after the inspection supplies a unique selector, the corrected upload dispatches and leaves the latch clear. Full suite 1451 passed, security corpus 60/60. The one failure is the pre-existing One judgment call worth a second opinion: adding |
Summary
upload_fileto Compact Act in both Chrome and FirefoxCloses #413.
Design notes
Compact gains only
upload_file; Ask and the rest of the Compact tool boundary stay unchanged. Chrome accepts a current userattachmentIdor an absolutefilePathexplicitly supplied by the user. Firefox accepts a currentattachmentIdor falls back to WebBrain's existing picker. Neither Compact schema exposesdownloadIdor points the model towarddownload_files/list_downloads.The Compact prompts direct the model to use an existing file input first, avoid generic selectors when multiple inputs exist, allow one guarded initializer click for a lazy widget, and verify the page attachment before submitting.
Testing
node --check src/chrome/src/agent/tools.jsnode --check src/firefox/src/agent/tools.jsnode --check test/run.jsnode test/run.js— 1450 passed; the sole unrelated failure is the existingpackage.json26.0.10 vs newest CHANGELOG 26.0.0 mismatchnpm run test:security— 60/60 checks passed