426e9eeabd
Voice Workbench / headless workbench (mocked backends) (push) Has been cancelled
Voice Workbench / real acoustic lane (nightly, provisioned only) (push) Has been cancelled
ci / test (push) Has been cancelled
ci / lint-and-format (push) Has been cancelled
ci / build (push) Has been cancelled
ci / dev-startup (push) Has been cancelled
gitleaks / gitleaks (push) Has been cancelled
Markdown Links / Relative Markdown Links (push) Has been cancelled
Quality (Extended) / Homepage Build (PR smoke) (push) Has been cancelled
Quality (Extended) / Comment-only diff guard (push) Has been cancelled
Quality (Extended) / Format + Type Safety Ratchet (push) Has been cancelled
Quality (Extended) / Develop Gate (secret scan + UI determinism) (push) Has been cancelled
Quality (Extended) / Develop Gate (lint) (push) Has been cancelled
Chat shell gestures / Chat shell gesture + parity e2e (push) Has been cancelled
Cloud Gateway Discord / Test (push) Has been cancelled
Benchmark Bridge Tests / benchmark (bunx @biomejs/biome check packages/lifeops-bench/src, benchmark-lint) (push) Has been cancelled
Benchmark Bridge Tests / benchmark (bunx vitest run --config packages/lifeops-bench/vitest.config.ts --root packages/lifeops-bench --passWithNoTests, benchmark-tests) (push) Has been cancelled
Build Agent Image / build-and-push (push) Has been cancelled
Dev Smoke / bun run dev onboarding chat (push) Has been cancelled
Dev Smoke / Vite HMR dependency-level smoke (push) Has been cancelled
Electrobun Submodule Guard / electrobun gitlink is fetchable (push) Has been cancelled
Publish @elizaos/example-code / check_npm (push) Has been cancelled
Publish @elizaos/example-code / publish_npm (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / verify_version (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / publish_npm (push) Has been cancelled
Sandbox Live Smoke / Sandbox live smoke (push) Has been cancelled
Snap Build & Test / Build Snap (amd64) (push) Has been cancelled
Snap Build & Test / Build Snap (arm64) (push) Has been cancelled
Test Packaging / elizaos CLI global-install smoke (node + bun) (push) Has been cancelled
Cloud Gateway Webhook / Test (push) Has been cancelled
Cloud Tests / lint-and-types (push) Has been cancelled
Cloud Tests / unit-tests (push) Has been cancelled
Cloud Tests / integration-tests (push) Has been cancelled
Cloud Tests / e2e-tests (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Deploy Apps Worker (Product 2) / Determine environment (push) Has been cancelled
Deploy Apps Worker (Product 2) / Deploy apps worker to apps-control host (${{ needs.determine-env.outputs.environment }}) (push) Has been cancelled
Deploy Eliza Provisioning Worker / Determine environment (push) Has been cancelled
Deploy Eliza Provisioning Worker / Deploy worker to Hetzner host (${{ needs.determine-env.outputs.environment }} @ ${{ needs.determine-env.outputs.deployment_sha }}) (push) Has been cancelled
Dev Smoke / Classify changed paths (push) Has been cancelled
supply-chain / sbom (push) Has been cancelled
supply-chain / vulnerability-scan (push) Has been cancelled
Build, Push & Deploy to Phala Cloud / build-and-push (push) Has been cancelled
Test Packaging / Validate Packaging Configs (push) Has been cancelled
Test Packaging / Build & Test PyPI Package (push) Has been cancelled
Test Packaging / PyPI on Python ${{ matrix.python }} (push) Has been cancelled
Test Packaging / Pack & Test JS Tarballs (push) Has been cancelled
UI Fixture E2E / ui-fixture-e2e (push) Has been cancelled
UI Fixture E2E / fixture-e2e (push) Has been cancelled
UI Story Gate / story-gate (push) Has been cancelled
vault-ci / test (macos-latest) (push) Has been cancelled
vault-ci / test (ubuntu-latest) (push) Has been cancelled
vault-ci / test (windows-latest) (push) Has been cancelled
vault-ci / app-core wiring tests (push) Has been cancelled
verify-patches / verify patches/CHECKSUMS.sha256 (push) Has been cancelled
Voice Benchmark Smoke / voice-emotion fixture smoke (push) Has been cancelled
Voice Benchmark Smoke / voiceagentbench fixture smoke (push) Has been cancelled
Voice Benchmark Smoke / voicebench-quality unit smoke (push) Has been cancelled
Voice Benchmark Smoke / voicebench TypeScript unit (no audio) (push) Has been cancelled
Voice Benchmark Smoke / voice bench smoke summary (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/app-core test bun run --cwd packages/elizaos test bun run --cwd packages/cloud/shared test], app-and-cli) (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/scenario-runner test bun run --cwd packages/vault test bun run --cwd packages/security test bun run --cwd plugins/plugin-coding-tools test], framework-packages) (push) Has been cancelled
Windows CI / windows ([bun run --cwd plugins/plugin-elizacloud test bun run --cwd plugins/plugin-discord test bun run --cwd plugins/plugin-anthropic test bun run --cwd plugins/plugin-openai test bun run --cwd plugins/plugin-app-control test bun run --cwd plugins/pl… (push) Has been cancelled
Windows CI / windows ([node packages/scripts/run-turbo.mjs run build --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/agent --concurrency=4 node packages/scripts/run-bash-linux-only.mjs scripts/verify-riscv64-buildpaths.sh node packages/scripts/run… (push) Has been cancelled
Windows CI / windows ([node packages/scripts/run-turbo.mjs run typecheck --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/cloud-shared --concurrency=4 bun run --cwd packages/core test bun run --cwd packages/shared test], core-runtime, 75) (push) Has been cancelled
177 lines
15 KiB
Markdown
177 lines
15 KiB
Markdown
# Computer-Use × Vision — trycua/cua parity audit (current state)
|
||
|
||
Authoritative, **current-state** review of where elizaOS `plugin-computeruse` +
|
||
`plugin-vision` stand against [trycua/cua](https://github.com/trycua/cua) and the
|
||
six other computer-use / OCR references, refreshed **after M3 / M3.5 / M4a / M5 /
|
||
M6 / M7 / M8** landed on `develop` (the older `reports/trycua-*.txt` snapshot
|
||
predates M7+M8 and is stale).
|
||
|
||
- Tracking issues: **#9105** (EPIC — integration) and **#9170** (parity + tests
|
||
on Windows/Linux/macOS/AOSP).
|
||
- Test-lane reference: [`TEST_LANES_COMPUTERUSE_VISION.md`](./TEST_LANES_COMPUTERUSE_VISION.md).
|
||
- Raw research snapshots: `reports/cua-external-summary.txt`,
|
||
`reports/trycua-matrix.txt`, `reports/trycua-gaps.txt`.
|
||
|
||
---
|
||
|
||
## 1. External-repo review (what to adopt, what is N/A)
|
||
|
||
| Repo | What it is | OCR | Local vision model | Continuous/low-token screen | Net takeaway for us |
|
||
|------|-----------|-----|--------------------|------------------------------|---------------------|
|
||
| **trycua/cua** | ~50-verb computer-server (WS/HTTP/MCP) over 6 VM/sandbox providers + agent SDK (loop registry, predict_step/predict_click, Set-of-Marks/OmniParser grounding, callback middleware) | model-side (hosted) | no | discrete capture→act loop | **The parity target.** Verb gaps are small/additive; the real work is the architecture: loop registry (M10), SoM overlay (M9), provider/RPC matrix (M13), eval harness (M14). |
|
||
| **coasty-ai/open-computer-use** (Apache-2.0) | OSS+SaaS CUA; web + Electron + MCP | classical (pytesseract, Linux VM only) | no (hosted "Coasty CUA") | discrete loop, JPEG q70, HD price penalty | **Adopt:** cross-platform input-correctness (DPI scale, off-primary cursor) — *already taken in M3.5*; predict/ground separation — *M5*; stateful session to cut tokens; avoid runtime-compiled inline C# in the PS fallback (AMSI fingerprint). |
|
||
| **injaneity/pi-computer-use** (MIT) | macOS-only; AX-tree grounding, **no vision/OCR** | none (AX tree + CDP) | none | pull-based AX snapshots | **Adopt:** accessibility-tree grounding tier to skip OCR for most clicks — *partially in scene a11y-provider*; stale-ref reacquisition; batched multi-action → one post-state; GET_SCREEN envelope with explicit scale/coordinateSpace/stateId. |
|
||
| **domdomegg/computer-use-mcp** (MIT) | thin local MCP mirror of Anthropic's computer-use tool | none (model does it) | none | pull-based, downscaled | **Adopt:** cursor-crosshair drawn into the frame; hard-cap to 1568px/~1.15MP + re-encode before any cloud model; validated bidirectional image↔logical scale; `xdotool --clearmodifiers`. |
|
||
| **vercel-labs/ai-sdk-computer-use** (no license — reference only) | Next.js demo, Claude drives a Vercel Sandbox | none | none (cloud Claude) | noVNC live for human; pull screenshots for model | **Adopt (patterns, not code):** `prunedMessages()` token-frugal history (redact prior frames, keep latest) — *aligns with M3 dHash + M11*; pull-based, skip re-screenshot after blind type/key; typed image tool-results; Anthropic `cacheControl` on the stable preamble; provider-defined-tool path when the model is Anthropic. |
|
||
| **bracesproul/gen-ui-computer-use** (MIT) | LangGraph Generative-UI showcase over OpenAI CUA + Scrapybara | none | none (OpenAI CUA) | hosted VNC iframe + per-action audit shots | **Adopt:** before/after action hooks streaming typed UI cards; clean live-view vs audit-trail split; content-addressed screenshot store (we already have the better sha256 media-store) + collapsed-by-default frames; live pause/approve/abort controls. |
|
||
| **baidu/Unlimited-OCR** (MIT) | one-shot long-horizon **document** OCR (DeepSeek-OCR + DeepSeek-V2 MoE, GGUF-able) | VLM end-to-end | yes (3B/0.5B-active) | n/a (batch doc parser) | **Adopt later:** a candidate **local** OCR/VLM for `plugin-vision` once exposed as GGUF — fits the "local, token-frugal" goal. **Not** a screen/CUA tool; document-parsing only. |
|
||
|
||
**Cross-cutting design conclusions already encoded in our roadmap:** OCR + element
|
||
detection belong in `plugin-vision` and feed `plugin-computeruse` through the
|
||
`CoordOcrProvider` seam (M1); screen understanding must be **local + token-frugal**
|
||
(GGUF only, no ONNX) with dHash-gated re-description (M3); a `GET_SCREEN` action
|
||
returns a typed image + structured elements (M2).
|
||
|
||
---
|
||
|
||
## 2. Verb / capability parity matrix (vs trycua/cua, on `develop` today)
|
||
|
||
Legend: ✅ have · 🟡 partial · ❌ missing · ⛔ N/A (deliberately not chased)
|
||
|
||
### Pointer / keyboard / screen (host drivers)
|
||
| trycua capability | elizaOS status | Where |
|
||
|---|---|---|
|
||
| screenshot (per-display, native res, quality/downscale) | ✅ | `platform/capture.ts`, `screenshot-quality.ts` |
|
||
| click / right_click / double_click | ✅ | `COMPUTER_USE` |
|
||
| **middle_click** | ✅ (M8) | `nut-driver.ts` `nutMiddleClick` |
|
||
| click_with_modifiers | ✅ | |
|
||
| mouse_move | ✅ | |
|
||
| **mouse_down / mouse_up** (button-param press-hold) | ✅ (M8) | `driver.ts` `driverMouseDown/Up(x,y,button)` |
|
||
| **key_down / key_up** (press-hold; bare modifiers) | ✅ (M8 + #9189) | `resolveKeyCode` now maps `MODIFIER_KEYS` |
|
||
| type / key / key_combo | ✅ | |
|
||
| scroll (per-notch + raw) | ✅ (M3.5 per-notch pacing = parity-plus) | |
|
||
| drag (start→end) | ✅ | |
|
||
| **drag (multi-point polyline path)** | ✅ (M8) | `driver.ts` `driverDragPath` → `nutDragPath`/`densifyDragPath` |
|
||
| get_cursor_position | ✅ (M3.5) | win32 uses `System.Windows.Forms.Cursor` (nutjs getPosition is stale) |
|
||
| get_screen_size / to_screen(shot)_coordinates | ✅ | multi-display + DPI transforms |
|
||
| get_environment / desktop info | 🟡 | `get_environment` yes; `get_desktop_environment` (for driver selection) ❌ minor |
|
||
|
||
### Vision / grounding
|
||
| trycua capability | elizaOS status | Where |
|
||
|---|---|---|
|
||
| **ocr** (full-screen, coord-bearing) | ✅ (M7) | `COMPUTER_USE ocr` → `getCoordOcrProvider()` (plugin-vision OCR) |
|
||
| **detect_elements** | ✅ (M7) | routes through scene element registry + CoordOcr |
|
||
| **GET_SCREEN action** (typed image + elements, token-frugal) | ✅ (M2) | `plugin-vision/src/get-screen.ts`, `get-screen-elements.ts` |
|
||
| low-token continuous description | ✅ (M3) | dHash-gated `DirtyTileDescriber` + frame-dHash skip + token counters |
|
||
| predict / ground split (cheap ground vs full predict) | 🟡 (M5) | `OcrCoordinateGroundingActor` + per-Scene grounding cache; no model-string registry yet |
|
||
| accessibility-tree grounding tier | ✅ | scene `a11y-provider` (Win UIA / macOS AX / Linux AT-SPI) |
|
||
| OmniParser/icon detection (GGUF, no ONNX) | 🟡 | `yolo-detector.ts` (YOLOv8n COCO GGUF via `native/yolo.cpp`) |
|
||
| **Set-of-Marks (numbered overlay) grounding** | ✅ (M9) | `plugin-vision/src/som.ts` + `set-of-marks-provider.ts`; registered via `registerSetOfMarksProvider` seam in `mobile/ocr-provider.ts` |
|
||
|
||
### Windows / files / process / shell
|
||
| trycua capability | elizaOS status | Where |
|
||
|---|---|---|
|
||
| window list/focus/switch/arrange/move/min/max/restore/close | ✅ | `WINDOW` action |
|
||
| get_current_window_id / get_application_windows(app) | ❌ (M12) | `scene.focused_window` is adjacent but no discrete getter verb |
|
||
| get_window_size / get_window_position / set_window_size | ❌ (M12) | `WINDOW_MOVE` sets position only |
|
||
| open(target) / launch(app,args)→pid | ❌ (M12) | |
|
||
| filesystem verbs (exists/list/read_text/write_text/read_bytes/write_bytes/delete/create_dir/get_file_size) | 🟡 (M12) | internal `file-ops.ts` + docker-backend wire ops; **not** exposed as `COMPUTER_USE` verbs |
|
||
| run_command (CommandResult) | 🟡 (M12) | `terminal.ts` one-shot + docker-backend; not a host `COMPUTER_USE` verb by design |
|
||
| PTY / interactive terminal | ❌ low-pri | one-shot only |
|
||
| clipboard read/write | ✅ (M3.5) | `CLIPBOARD` action |
|
||
|
||
### Architecture / platform
|
||
| trycua capability | elizaOS status | Notes |
|
||
|---|---|---|
|
||
| agent-loop registry (model-string → loop) | 🟡 (M10) | hardcoded Brain→Cascade→Actor→dispatch |
|
||
| callback middleware (budget/image-retention/trajectory/operator-normalize) | 🟡 (M11) | approval-manager + token counters + log-line trajectory events |
|
||
| VM/sandbox provider matrix | 🟡 (M13) | Docker backend only; WSB + QEMU are the opt-in targets worth adding |
|
||
| daemon/RPC seam (`{command,params}→{success,result}`) | ❌ (M13) | in-process service; routes only for approvals |
|
||
| MCP server seam | ❌ | one optional MCP seam is the relevant subset of cua's 2 servers / 35 tools |
|
||
| eval harness (ScreenSpot / OSWorld / GET-commands matrix) | 🟡 (M14) | `osworld/` adapter + `benchmarks/eliza-1/vision-cua-e2e`; not yet per-OS scenario-wired |
|
||
| AOSP touch + hardware keys + multitouch | 🟡 | Capacitor bridge tap/swipe + globalAction(back/home/recents); `multitouch_gesture` ❌ |
|
||
|
||
### Explicitly N/A (do not chase)
|
||
`set_wallpaper` (niche) · `playwright_exec` / `browser_execute` (**unconditionally
|
||
disabled**, GHSA-rcvr-766c-4phv) · cloud managed sandbox · the full 2-MCP-server /
|
||
35-driver-tool surface · PII anonymization · AOSP gRPC `:8554` backend (CI-only).
|
||
|
||
---
|
||
|
||
## 3. Test-coverage matrix (every-verb, by lane and platform)
|
||
|
||
Lanes: **unit** = default Vitest (runs on all OSes), **real** = `*.real.test.ts`
|
||
gated `platform()==="win32"` and excluded from the default run (Windows only),
|
||
**e2e**, **scenario** (scenario-runner / issue-evidence), **probe** = standalone
|
||
`bun` driver check.
|
||
|
||
| Capability group | unit (all OS) | Windows real/probe | Linux | macOS | AOSP |
|
||
|---|---|---|---|---|---|
|
||
| pointer click family + modifiers | `cua-parity-surface`, `computer-interface`, `dispatch`, `use-computer-action` | `cua-parity-input.real`, `computeruse.real`, `service.real`, probes | ⚠️ no real lane | ⚠️ no real lane | n/a |
|
||
| M8 middle/down-up + key down-up + drag-path | `cua-parity-surface`, `nut-driver-input` (incl. modifier guard) | `cua-parity-input.real` + this-session probe (**verified**) | ⚠️ no real lane | ⚠️ no real lane | n/a |
|
||
| ocr / detect_elements (M7) | `ocr-adapter-coord-seam`, `ocr-with-coords`, `computeruse-ocr-bridge` | `service.real`, OCR bridge | unit only | `ocr-service-apple-vision` (unit) | n/a |
|
||
| GET_SCREEN / scene / dHash (M2/M3) | `get-screen`, `get-screen-elements`, `dirty-tile-describer`, `screen-state`, `dhash`, `scene-*` | scene multimon/probe | unit only | unit only | `android-scene` |
|
||
| windows / clipboard / cursor | `platform-capabilities`, `windows-powershell-safety` (static) | `windows-list.real`, `clipboard` (win32), cursor probe | unit only | unit only | n/a |
|
||
| files / terminal | `security-file-target` | `file-ops.real`, `terminal.real` | unit only | unit only | n/a |
|
||
| OCR engines | `ocr-service`, `ocr-service-windows`, `yolo-detector` | `ocr-service-windows` (win32) | `ocr-service` (docTR) | `ocr-service-apple-vision` | n/a |
|
||
| autonomous loop | `cascade`, `brain`, `dispatch`, `computer-use-agent` | `computer-use-agent.real`, `runtime.live.e2e` | unit only | unit only | `mobile-cascade`, `aosp-input-actor` |
|
||
| benchmarks | `osworld-action-converter` | `benchmark/osworld-*.real` | — | — | — |
|
||
| approvals / progress | `computer-use-approval-relay` | `routes-e2e` | scenario `8912-computeruse-progress-approvals-*` | — | — |
|
||
| mobile/AOSP | — | — | — | — | `android-bridge`, `android-trajectory`, `ios-*`, device-evidence manifests |
|
||
|
||
### The single biggest "tests on all platforms" hole
|
||
The real-driver lane is **`win32`-only** (`const RUN = platform()==="win32"`). The
|
||
nutjs + legacy `xdotool`/`cliclick` code paths exist for Linux/macOS but **no
|
||
equivalent real-driver lane executes them** — and because the gate skips silently,
|
||
a Linux/macOS regression would not turn a lane red. This is exactly how the M8
|
||
`key_down("shift")` bug (fixed in #9189) reached `develop`: M8's real test was
|
||
authored on a host without a Windows machine, so the gated case never ran.
|
||
|
||
**Recommended (M14):** a Linux Xvfb headful lane and a macOS headful lane that run
|
||
the parity verbs against the real driver, plus a machine-checkable matrix derived
|
||
from the action enum so a newly-added trycua verb that lacks a per-OS test fails CI.
|
||
|
||
---
|
||
|
||
## 4. Per-platform verification status
|
||
|
||
| OS | Driver | Status |
|
||
|----|--------|--------|
|
||
| **Windows 11** | nutjs (default) + legacy PowerShell | **Primary, verified.** All M8 verbs + key_down modifier fix dispatched against the live desktop this cycle (cursor read back via WinForms). OCR via `Windows.Media.Ocr` (M4a). |
|
||
| **Linux** | nutjs + legacy `xdotool` (X11; AT-SPI/Wayland fallback) | Code paths present + unit-tested; **no real-driver lane runs** → needs Xvfb headful CI. Clipboard needs `wl-clipboard`/`xclip` (asserts clear error when absent). |
|
||
| **macOS** | nutjs + legacy `cliclick`; retina backing-store 2× transforms | Code paths present + unit-tested (incl. Apple Vision OCR); **no real-driver lane runs** → needs headful macOS CI; assert retina coordinate transforms. |
|
||
| **AOSP / Android** | Capacitor bridge + `MobileComputerInterface` | tap/swipe + globalAction(back/home/recents) implemented + unit-tested; device-evidence manifests exist; `multitouch_gesture` missing; system-app path is CI-only. |
|
||
|
||
---
|
||
|
||
## 5. Remaining roadmap (prioritized)
|
||
|
||
1. **M14 cross-platform real lanes** *(highest leverage for the stated goal)* —
|
||
The enum-derived parity coverage guard (`cua-parity-coverage.test.ts`) is
|
||
**landed** and runs on all platforms in the default lane, and the real lane is
|
||
no longer win32-hardcoded. The remaining piece is the **Linux Xvfb + macOS
|
||
headful CI lanes** that actually invoke the real config (requires a
|
||
`.github/workflows/**` change / `workflow` token scope). Until those exist,
|
||
real-driver *actuation* is verified on Windows only.
|
||
2. **M12 additive verbs** — window getters (`get_current_window_id`,
|
||
`get_application_windows`, `get/set_window_size`, `get_window_position`),
|
||
`open`/`launch`, and the filesystem/`run_command` verbs (wrap the existing
|
||
internal `file-ops.ts`/`terminal.ts` as gated `COMPUTER_USE` verbs).
|
||
3. **M10 agent-loop registry** + predict_step/predict_click split (extend the Actor
|
||
registry; keep approval gating).
|
||
4. **M11 callback middleware** — budget cap, image-retention (only-N-recent, aligns
|
||
with M3), operator-normalizer, trajectory.
|
||
5. **M13 provider matrix + RPC seam** — Windows Sandbox (WSB) + QEMU behind a
|
||
remote-guest `{command,params}→{success,result}` RPC over the route/WS seam.
|
||
6. **AOSP `multitouch_gesture`** (MT-Protocol-B) + an optional MCP server seam.
|
||
|
||
**Done since this audit was first written:** M9 Set-of-Marks (numbered-overlay
|
||
grounding) landed — `plugin-vision/src/som.ts` + `set-of-marks-provider.ts`,
|
||
registered via the `registerSetOfMarksProvider` seam; 23/23 unit tests green on
|
||
Windows.
|
||
|
||
> **Process note for contributors:** the `*.real.test.ts` lanes only execute on a
|
||
> Windows host. Before trusting any newly-landed computeruse milestone, run its
|
||
> verbs against the real driver on Windows (or the future Linux/macOS lanes) — a
|
||
> green default-lane run does **not** mean the platform paths work. See §3.
|