You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(browser): sharper computer use for the desktop browser agent (#8283)
* fix(browser): press chord modifiers as real keys
A chord such as Control+Shift+Y was sent as one key-down with a modifier
bitmask, so pages that track held keys never saw Control or Shift go down.
Modifiers are now pressed in order before the main key and released in
reverse, as a physical keyboard delivers them, and a bare modifier key can be
pressed on its own.
* feat(browser): let clicks press and hold
Clicks released the button immediately, so press-and-hold controls could not
be operated. A click now accepts holdMs (0 to 10000, single clicks only) and
keeps the button down that long before release.
* fix(browser): read disablePortal modals hidden with their app root
MUI hides every <body> child except a modal's mount node; a disablePortal
modal mounts inside the app root it just hid, so every node had an aria-hidden
ancestor and the snapshot came back empty while the dialog was on screen.
Visibility checks now skip aria-hidden only on ancestors above the single
topmost modal hidden that way; portaled modals and other hidden regions are
unchanged.
* fix(browser): stage agent downloads synchronously so Electron never opens a Save dialog
The save path was set only after an asynchronous non-conflicting-name lookup.
When Electron's own path step won that race it opened a native Save dialog, so
an agent download stalled forever at full size (and a user would see a
surprise dialog). Downloads now write to a hidden staging file set during
will-download and are renamed to the allocated name when they complete.
* feat(browser): mark snapshot elements that appeared since the previous snapshot
After an action the agent saw a fresh snapshot but no hint of what changed, so
a popup, suggestion list, or validation message looked like any other line.
The page now remembers which elements an earlier snapshot of the document
listed, and later snapshots mark the rest new (the first snapshot marks
nothing).
* refactor(browser): tighten the computer-use desktop changes
- Modifier aliases (Ctrl, Cmd, Command, Option) share one descriptor with their
canonical key, so a bare alias sets its own flag; a bare modifier's key-up
reports it released.
- The framed-control fallback no longer treats a held click as a plain click,
and a batch refuses press-and-hold so eight holds cannot outlast its watchdog.
- installPageHelpers caches the modal lookup per invocation, and one
serializePageCall builds the page expression for the driver and the tests.
- Download completion drops a branch whose state was never published.
* fix(browser): close the edge cases review found in the desktop agent changes
- A held right-click renews its agent context-menu marker before release, so
Windows' release-time menu stays suppressed after a hold over one second.
- A failed chord releases only the keys whose press was attempted.
- A disk probe that resolves after a download completed can no longer cancel it.
- A disablePortal modal nested inside another open modal is picked as topmost.
- holdMs is an integer bounded to 0-10000 in the tool contract.
* fix(browser): harden holds, modal exemption, and download moves
- An aborted press-and-hold rejects and releases the button at once instead of
staying held into the next action.
- The disablePortal exemption applies only when a <body> child hides the modal
(MUI's mechanism), so a dialog the app hid itself stays hidden, and it is
looked up per document so same-origin iframes get it too.
- A completed download's move retries transient EBUSY/EPERM/EACCES errors, as
Chromium's own final rename does, instead of discarding the file.
- Keyboard docs describe the separate modifier presses; the partial-release
test covers a failure at the first modifier.
* fix(browser): claim agent download names on disk while bytes stage
The allocated destination gets an empty placeholder created with O_EXCL, as
Firefox does, so another program picking a name sees it taken and the final
rename only ever replaces Sim's own placeholder. A name that something else
grabbed first stops the download instead of being overwritten. Teardown and
failures remove the placeholder once, so a late-settling download cannot delete
a name a newer download has claimed.
* fix(browser): close cancellation and teardown races in holds and downloads
- An already-aborted click presses nothing, and a held click marks its outcome
pending before dispatch, so cancelling mid-hold reports an unknown outcome
with doNotRetry instead of an error that invites a retry.
- The disablePortal exemption resets when a visibility walk crosses from an
iframe into its host page, where the host's own aria-hidden applies.
- Teardown keeps a download's name reserved until its placeholder claim
settles, so a newer download cannot be handed a name the claim then takes.
- Downloads are paused before the staging path is set, as on staging, so a
pause failure leaves no staging file behind.
@@ -3261,7 +3284,7 @@ async function executeToolInner(
3261
3284
}else{
3262
3285
if(!isPrimaryClick(click)){
3263
3286
thrownewToolError(
3264
-
'This framed control has no reliable pointer position, so only a plain left click can activate it. Use browser_screenshot and browser_click_at for other buttons, click counts, or modifiers.'
3287
+
'This framed control has no reliable pointer position, so only a plain left click can activate it. Use browser_screenshot and browser_click_at for other buttons, click counts, holds, or modifiers.'
3265
3288
)
3266
3289
}
3267
3290
constactivationKey=prepared.activationKey
@@ -4622,8 +4645,9 @@ async function executeToolInner(
0 commit comments