Skip to content

Commit 4e6e53d

Browse files
committed
Follow the agent into a tab it opened to work in
browser_open_tab created the page with activate: false, so the agent worked in a tab the user could not see while the panel sat on a page where nothing was happening. The panel now follows a tab the agent deliberately opened. Scoped to that tool only. A page spawning its own tab (popup, target=_blank) is the site grabbing the view rather than the agent choosing a workspace, and stays in the background as before — two existing tests pin that and caught the first version of this change, which moved both. A tab the user claimed still wins over both: the work starts in the background instead of pulling the page out from under them mid-read.
1 parent 50aa8f9 commit 4e6e53d

3 files changed

Lines changed: 34 additions & 4 deletions

File tree

apps/desktop/src/main/browser-agent/driver.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1910,7 +1910,8 @@ async function executeToolInner(
19101910
}
19111911
}
19121912
assertCurrentExecution()
1913-
const tab = session.addAutomationTab()
1913+
// The agent chose to open this page to work in, so the panel follows it.
1914+
const tab = session.addAutomationTab({ reveal: true })
19141915
const contents = tab.view.webContents
19151916
if (url) {
19161917
assertCurrentExecution()

apps/desktop/src/main/browser-agent/session.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1715,6 +1715,21 @@ describe('browser-agent session', () => {
17151715
expect(contents.loadURL).not.toHaveBeenCalled()
17161716
})
17171717

1718+
it('brings an agent-opened working tab into view, unless the user claimed the visible one', () => {
1719+
// browser_open_tab is the agent choosing a page to work in — the panel
1720+
// follows it so the work is visible, which a popup deliberately does not.
1721+
const first = session.ensureTab()
1722+
const working = session.addAutomationTab({ reveal: true })
1723+
expect(session.activeTab()).toBe(working)
1724+
expect(working.id).not.toBe(first.id)
1725+
1726+
// Once the user claims what they are looking at, the next agent tab opens
1727+
// behind it rather than yanking the page out from under them.
1728+
session.claimActiveTabForUser()
1729+
const background = session.addAutomationTab({ reveal: true })
1730+
expect(session.activeTab()).not.toBe(background)
1731+
})
1732+
17181733
it('keeps agent popups in the background and context-menu links user-owned', () => {
17191734
const onTabCreated = vi.fn()
17201735
session = freshSession(win, { onTabCreated })

apps/desktop/src/main/browser-agent/session.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,10 +1590,24 @@ export function addTab(): AgentTab {
15901590
return addTabInternal()
15911591
}
15921592

1593-
/** Opens a tab for agent work without replacing the page the user is viewing. */
1594-
export function addAutomationTab(): AgentTab {
1593+
/**
1594+
* Opens a tab for agent work.
1595+
*
1596+
* `reveal` is for the agent deliberately opening a page to work in
1597+
* (`browser_open_tab`): the panel follows it, so the user watches the work
1598+
* instead of staring at a page where nothing is happening. It is NOT set when a
1599+
* page spawns a tab on its own (popups, `target="_blank"`) — that is the site
1600+
* grabbing the view, not the agent choosing a workspace.
1601+
*
1602+
* Even with `reveal`, a tab the user claimed themselves wins: pulling the view
1603+
* off the page they are reading is the same interruption as a window stealing
1604+
* focus mid-sentence. The work still starts, just in the background, and the
1605+
* tab strip shows it arriving.
1606+
*/
1607+
export function addAutomationTab({ reveal = false }: { reveal?: boolean } = {}): AgentTab {
15951608
restoreBrowserSession()
1596-
const tab = addTabInternal({ activate: false, notify: false })
1609+
const followTheWork = reveal && !currentScope.visibleTabUserSelected
1610+
const tab = addTabInternal({ activate: followTheWork, notify: false })
15971611
currentScope.automationTabId = tab.id
15981612
applyActiveTabThrottling()
15991613
persistBrowserSession()

0 commit comments

Comments
 (0)