Skip to content

fix(computer-use): surface app=… filter no-match instead of silently using frontmost (#24170 bug 1)#24324

Closed
briandevans wants to merge 1 commit into
NousResearch:mainfrom
briandevans:fix/computer-use-capture-app-filter-no-match-24170
Closed

fix(computer-use): surface app=… filter no-match instead of silently using frontmost (#24170 bug 1)#24324
briandevans wants to merge 1 commit into
NousResearch:mainfrom
briandevans:fix/computer-use-capture-app-filter-no-match-24170

Conversation

@briandevans

@briandevans briandevans commented May 12, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

CuaDriverBackend.capture(app=X) and focus_app(app=X) silently fell back to the frontmost on-screen window when X matched no app — typically a menu-bar utility (e.g. "Fuwari" in the bug reporter's case) rather than the requested app. The agent then received UI elements for the wrong app and clicked/typed into it.

list_windows returns the macOS-localized app_name (e.g. "計算機" on a Chinese/Japanese system) but callers naturally pass the English name ("Calculator"). The substring filter doesn't match, and the code falls through — capture() silently keeps all windows; focus_app() silently uses the frontmost. The agent receives UI elements for the wrong window with no signal that the app= filter was effectively dropped.

The fix: capture(app=…) returns a CaptureResult with empty app/elements and a diagnostic window_title pointing the caller at list_apps and noting the localized-name convention. _active_pid / _active_window_id are left untouched. focus_app(app=…) sets target = None so the existing ActionResult(ok=False, "No on-screen window found for app …") path fires instead of falsely reporting success on the frontmost window. 26 prod lines (mostly comments), 134 test lines, 2 files. No cross-locale name resolution attempted — that would be a larger change; list_apps already exposes the localized names the caller needs.

Related Issue

Fixes bug 1 from #24170

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • tools/computer_use/cua_backend.pycapture(app=…) returns empty CaptureResult with diagnostic window_title when filter matches nothing; focus_app(app=…) sets target = None to surface the existing ok=False path.
  • tests/tools/test_computer_use.pyTestCaptureAppFilterNoMatch (3 cases) + TestFocusAppFilterNoMatch (2 cases).

How to Test

  1. uv run --with pytest --with pytest-xdist --with pytest-asyncio python3 -m pytest tests/tools/test_computer_use.py -v
  2. Expected: 49 passed.
  3. Regression guard: stash production fix, the new tests fail with the exact symptom from the bug report (AssertionError: 'Fuwari' == ''). Restore — green.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run focused tests for the touched code and all pass (49/49)
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: macOS 15.x

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — CUA backend is macOS-only; behavior change is independent of locale
  • I've updated tool descriptions/schemas if I changed tool behavior — N/A, response shape unchanged (empty fields, not new keys)

Related / Positioning

Addresses bug 1 from #24170. Bugs 2 & 5 are addressed in #24242 (Bartok9); bugs 3 & 4 in #24181 (liuhao1024).

PR Bug from #24170 Scope
#24181 (liuhao1024) bug 3, bug 4 type_text_charstype_text; implement drag
#24232 (iceTruth) bug 3 (alternate) also type_text_chars rename
#24242 (Bartok9) bug 2, bug 5 _last_app to preserve app for capture_after; _ELEMENT_LINE_RE for v0.1.6 id=Label format
this PR bug 1 surface no-match for app= filter — orthogonal to Bartok9's _last_app change, no merge conflict expected

Bartok9's PR body explicitly notes that bug 1 is tracked separately.

Audited siblings: the app= filter pattern exists only in capture() and focus_app() within cua_backend.py. No widening needed.

Copilot AI review requested due to automatic review settings May 12, 2026 11:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a correctness issue in the macOS cua-driver backend where capture(app=...) and focus_app(app=...) would silently fall back to the frontmost window when the requested app filter matched no running app (commonly due to macOS returning localized app names from list_windows). The change ensures the no-match case is explicitly surfaced so the agent doesn’t interact with the wrong application.

Changes:

  • Update CuaDriverBackend.capture() to return an explicit empty CaptureResult with a diagnostic window_title when app= matches no windows (instead of capturing the frontmost window).
  • Update CuaDriverBackend.focus_app() to fail (ok=False) when app= matches no windows (instead of selecting the frontmost window).
  • Add regression tests covering both behaviors for match and no-match cases.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
tools/computer_use/cua_backend.py Prevent silent fallback to the frontmost window when an app= filter matches nothing in capture() and focus_app().
tests/tools/test_computer_use.py Add regression tests ensuring app= no-match is surfaced (capture returns empty + diagnostic; focus_app returns not-ok).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@alt-glitch alt-glitch added type/bug Something isn't working comp/tools Tool registry, model_tools, toolsets P2 Medium — degraded but workaround exists labels May 12, 2026
@briandevans briandevans force-pushed the fix/computer-use-capture-app-filter-no-match-24170 branch from 62ef46e to 88017a0 Compare May 14, 2026 20:12
…using frontmost (NousResearch#24170 bug 1)

`CuaDriverBackend.capture(app=X)` and `focus_app(app=X)` silently fell back
to the frontmost on-screen window when X matched no app — typically a
menu-bar utility (e.g. "Fuwari" in the bug reporter's case) rather than
the requested app. The agent then received UI elements for the wrong app
and clicked / typed into it.

The root cause is a localized macOS app name mismatch: `list_windows`
returns the localized `app_name` (e.g. "計算機" on a Japanese/Chinese
system) but callers naturally pass the English name ("Calculator"). The
substring filter doesn't match, and the code falls through to picking the
frontmost window with no signal that the filter was effectively dropped.

Fix:

- `capture(app=…)`: when the filter matches nothing, return a
  `CaptureResult` with empty `app`/`elements` and a diagnostic
  `window_title` pointing the caller at `list_apps` and noting the
  localized-name convention. `_active_pid` / `_active_window_id` are left
  untouched so a subsequent action doesn't inadvertently hit the wrong
  process.
- `focus_app(app=…)`: when the filter matches nothing, set `target = None`
  and let the existing `return ActionResult(ok=False, …, "No on-screen
  window found for app …")` path fire instead of falsely reporting success
  on the frontmost window.

This addresses bug 1 only from NousResearch#24170. Bugs 2 & 5 are addressed in
NousResearch#24242, bugs 3 & 4 in NousResearch#24181.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@teknium1

Copy link
Copy Markdown
Contributor

Salvaged via PR #30051 (commit 5aa4727 on main). Your commit was cherry-picked onto current main with your authorship preserved. Thanks for the fix! Closes #24170 bug 1 (silent frontmost fallback on app= no-match).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/tools Tool registry, model_tools, toolsets 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.

4 participants