Skip to content

fix(computer-use): tell visited AX elements apart by identity, not address - #573

Merged
Tryanks merged 1 commit into
mainfrom
fix/cu-visited-elements
Oct 1, 2026
Merged

Tryanks merged 1 commit into
mainfrom
fix/cu-visited-elements

Conversation

@Tryanks

@Tryanks Tryanks commented Oct 1, 2026

Copy link
Copy Markdown
Owner

Changed behaviour

observe_ui dropped nodes from the macOS accessibility tree — in practice the first child of a group: the 终端 segment of the compact panel switcher, the ★ tab of the model picker's provider rail, the first approval mode. The walker's cycle guard recorded each AXUIElementRef by its address. Every child array the system hands out holds fresh objects and is released once its subtree is walked, so the next array can reuse a freed address; a node that landed on a released element's address counted as already visited and was skipped.

Visited elements are now retained for the walk and compared as AX identities (CFEqual under CFHash), so an address can neither be reused nor stand for a node.

Verified it is the observer, not GPUI or the adapter: GPUI's debug_a11y_tree_json lists the toolbar with all four toggles, and a direct AX dump (AXUIElementCopyAttributeValue from a Swift script) shows AXToolbar with 4 children. tcode --cu-smoke against the phone example's panel page: 9 nodes before, 10 after (twice each, in both orders).

Tests

New visited_elements_are_told_apart_by_identity_not_address: two references to one element are one node; 256 distinct elements made and released in turn are 256 nodes. Fails on the old address-keyed set at the first assertion (shown locally by swapping the body back).

Checks run

  • cargo fmt --all --check; cargo clippy -p computer-use-mcp --all-targets --locked -- -D warnings
  • cargo nextest run -p computer-use-mcp --locked — 35 passed

…dress

The walk deduplicated elements by the address of the AXUIElement it was
handed. Each child array is released once its subtree is walked, and the
next array the system hands out reuses freed addresses, so a node whose
reference landed on a released sibling's address was skipped: the first
child of a group, typically. Visited elements are now retained for the
walk and compared with CFEqual under CFHash.
@Tryanks
Tryanks merged commit 2a00a41 into main Oct 1, 2026
7 checks passed
@Tryanks
Tryanks deleted the fix/cu-visited-elements branch October 1, 2026 19:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant