Skip to content

feat(computer-use): complete cua-driver integration with passing integration tests - #15328

Closed
ddupont808 wants to merge 2 commits into
NousResearch:hermes/hermes-34b3f52dfrom
ddupont808:cua-driver/background-focus-fixes
Closed

feat(computer-use): complete cua-driver integration with passing integration tests#15328
ddupont808 wants to merge 2 commits into
NousResearch:hermes/hermes-34b3f52dfrom
ddupont808:cua-driver/background-focus-fixes

Conversation

@ddupont808

Copy link
Copy Markdown
Contributor

Summary

Completes the cua-driver integration introduced in #14817. All backend methods are wired up to the correct cua-driver MCP tools, and a 9-test integration suite passes end-to-end against a real macOS Safari instance.

Paired cua-driver changes: trycua/cua#1375

Changes

cua_backend.py

Window-aware capture() — replaces the original implementation with list_windows + get_window_state. Prefers structuredContent.windows (MCP 2024-11-05+ cua-driver) for zero-parse window enumeration; falls back to regex-parsed text for older builds. Stores (pid, window_id) as sticky context reused by action tools.

Action routingclick, scroll, type_text, key now pass the sticky pid/window_id to the correct cua-driver tools. type_text routes through type_text_chars (synthesised key events) — WebKit AXTextFields reject AX attribute writes from non-frontmost processes.

Key parsing_parse_key_combo splits cmd+s-style strings into (key, [modifiers]) and dispatches to hotkey or press_key, matching cua-driver's actual tool names.

set_value(value, element) — new method calls the cua-driver set_value MCP tool. Required for AXPopUpButton / HTML <select> in backgrounded Safari: AXPress opens the native popup which closes immediately when the window is non-frontmost; set_value selects the matching option directly without a popup.

focus_app — reimplemented as a window-selector via list_windows (updates sticky pid/window_id).

list_apps — fixed tool name listAppslist_apps.

Structured-content extraction_extract_tool_result now surfaces structuredContent from MCP results.

Helpers_parse_windows_from_text, _parse_elements_from_tree, _split_tree_text, _parse_key_combo extracted as module-level functions.

schema.py

Added set_value to the action enum + value field for its payload.

tool.py

Routed set_value through _dispatchbackend.set_value. Added set_value to _DESTRUCTIVE_ACTIONS. Fixed MIME detection in _capture_response: detect JPEG vs PNG from base64 magic bytes rather than hardcoding image/png.

agent/display.py + run_agent.py

Guard failure detection and result-preview/logging against non-string function_result — multimodal dict results (_multimodal=True) are not string-sliceable.

Validation

Test Result
test_hermes_form_fill.py — 9 input types (text, password, email, number, textarea, checkbox, select, radio, submit) in backgrounded Safari 9/9 pass
test_overlay_z_order.py — agent cursor overlay z-ordering pass

Caveats

  • Requires cua-driver ≥ 0.0.4 for set_value and structuredContent on list_windows/launch_app.
  • drag is not implemented — cua-driver does not expose a drag tool.

Loading
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 sweeper:implemented-on-main Sweeper: behavior already present on current main type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants