Skip to content

fix(desktop): stop Computer Use from silently acting on the wrong machine over a remote gateway - #90374

Open
OutThisLife wants to merge 3 commits into
mainfrom
bb/cua-remote-locality-warning
Open

fix(desktop): stop Computer Use from silently acting on the wrong machine over a remote gateway#90374
OutThisLife wants to merge 3 commits into
mainfrom
bb/cua-remote-locality-warning

Conversation

@OutThisLife

Copy link
Copy Markdown
Collaborator

When Desktop drives a remote gateway, the HUD and computer_use are on two different computers and nothing says so. This makes the gap visible — to the agent, and to the person reading the Computer Use card.

The bug

read_window_below round-trips to the desktop renderer (tools/read_window_tool.py), so it describes the window on the user's screen. computer_use resolves a process-global backend that spawns cua-driver on the gateway host (tools/computer_use/tool.py:336-342). On a local backend those are one machine; on SSH, URL, or cloud they are two.

Our own per-turn HUD note then closes the loop in the wrong direction:

Prefer carrying the work out in that same app — computer_use takes its name in app — over pulling the task into a surface of your own.

So on a remote backend that has a display, the agent identifies Figma on your Mac and clicks the same-named app on the other box. Where the remote host has no display the tool is stripped by its check_fn and the user just gets silence — reported on #61507 as "computer_use never appears, enabling it and restarting doesn't help".

The fix

Only the client can answer "is the agent on this machine" — behind an SSH tunnel the backend sees a loopback peer either way. So the renderer stamps a bare flag onto the existing window.read answer and the backend names itself. Resolved when the agent asks rather than stamped on the session, for the reason #82187 landed on: a transcript outlives whoever was watching when it was written.

  • agent-locality.ts owns the predicate, the host label, and the stamp. Local sessions carry nothing, so the common case costs no tokens.
  • read_window_below turns the flag into an agent_host the model can act on, documented in the schema.
  • The HUD note's drive-it prior defers to that answer instead of asserting reach it cannot know it has.
  • The Computer Use settings card names the machine it is describing, so a green "ready" stops reading as a verdict on the user's own screen.

This does not make Computer Use work across the gap — that is the bridge in #61507 / #61311, which is a much larger change. This is the part that should not wait for it.

Test plan

  • scripts/run_tests.sh tests/agent/test_prompt_builder.py tests/agent/test_platform_hint_desktop.py tests/tui_gateway/ tests/tools/test_read_window_tool.py — 608 passed
  • npx vitest run src/lib/agent-locality.test.ts — 10 passed, covering SSH identity over forwarded loopback port, cloud/URL labels, and that no host detail crosses the wire
  • npm run typecheck, eslint, prettier clean on changed files
  • ruff check, git diff --check clean
  • Not visually verified against a running remote-backend Desktop — the settings-card copy is one muted paragraph in the file's existing warning idiom

…er machine

read_window_below round-trips to the desktop renderer, so it describes the
user's screen. computer_use spawns cua-driver on whatever host the gateway
runs on. Those are the same computer on a local backend and two different
ones on SSH, URL, or cloud — and nothing said so, so on a remote gateway with
a display the agent would identify a window on your Mac and then click the
same-named app over there.

Only the client can answer this: behind an SSH tunnel the backend sees a
loopback peer either way. So the renderer stamps the bare flag onto the
window.read answer and the backend names itself, resolved when the agent asks
rather than stamped on the session. Local sessions send nothing, so the
common case costs no tokens.
…ng machine

The per-turn HUD note tells the model to carry work out in the app behind the
strip, naming computer_use as the way. On a remote gateway that instruction is
wrong, and it is our own prompt that issues it.

The note is built before any tool call, so it cannot know. Point it at the
answer that can — read_window_below's agent_host — rather than carrying a
locality bit that would be stale by the time anyone read it back.
The card reads /api/tools/computer-use/status from the gateway host and
frames it as "this machine", "your Mac", "drives your desktop". On a remote
backend every one of those is about a computer the user isn't sitting at, so
a green "ready" told them Computer Use worked on their own screen.
@github-actions

github-actions Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

૮ >ﻌ< ა ci review

ran on 96e411c — fix(desktop): say which machine the Computer Use card is des

⚠️ Warnings

CI timings · View report · View job

Wall time 6m49s vs 4m6s (+66.3%). 19 job(s) slower, 17 faster, 2 unchanged.

  • Python tests / Run tests slice 9/12: -37.0s
  • Python tests / Run tests slice 3/12: +35.0s
  • Python tests / Run tests slice 7/12: -30.0s
  • Python tests / Run tests slice 4/12: +18.0s
  • Python tests / Run tests slice 10/12: +16.0s

OSV vulnerability scan · View job

7 known vulnerabilities found in pinned dependencies.

How to fix:

Review the findings in the Security tab. Update the affected dependencies if a patched version is available.

@alt-glitch alt-glitch added type/bug Something isn't working comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/desktop Electron desktop app (apps/desktop/*) P2 Medium — degraded but workaround exists labels Aug 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/desktop Electron desktop app (apps/desktop/*) P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants