From 108f7aca895f80cd2ef711bf87fcd2cf69de0bf9 Mon Sep 17 00:00:00 2001 From: LaZzyMan Date: Thu, 9 Jul 2026 22:38:02 +0800 Subject: [PATCH] chore(cua-driver): update version refs to 0.7.1 + add fix doc Bump baked version in install scripts, CD workflow default, and README examples to 0.7.1 so the release pipeline picks up the correct version. Add docs/0.7.1-coord-norm-fixes.md documenting all fixes in this release. --- .github/workflows/cd-cua-driver.yml | 2 +- packages/cua-driver/README.md | 6 +- .../cua-driver/docs/0.7.1-coord-norm-fixes.md | 86 +++++++++++++++++++ packages/cua-driver/scripts/_install-rust.sh | 2 +- packages/cua-driver/scripts/install.ps1 | 2 +- 5 files changed, 92 insertions(+), 6 deletions(-) create mode 100644 packages/cua-driver/docs/0.7.1-coord-norm-fixes.md diff --git a/.github/workflows/cd-cua-driver.yml b/.github/workflows/cd-cua-driver.yml index f6e9b62b3e..bb144aca35 100644 --- a/.github/workflows/cd-cua-driver.yml +++ b/.github/workflows/cd-cua-driver.yml @@ -25,7 +25,7 @@ on: version: description: 'Version to release (without v prefix)' required: true - default: '0.6.7' + default: '0.7.1' notarize: description: 'Codesign + notarize the macOS artifacts (false to skip during iteration)' diff --git a/packages/cua-driver/README.md b/packages/cua-driver/README.md index a75e88fb4b..adca9293e5 100644 --- a/packages/cua-driver/README.md +++ b/packages/cua-driver/README.md @@ -22,12 +22,12 @@ irm https://raw.githubusercontent.com/QwenLM/qwen-code/main/packages/cua-driver/ ```bash # macOS / Linux -CUA_DRIVER_RS_VERSION=0.7.0 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/QwenLM/qwen-code/main/packages/cua-driver/scripts/install.sh)" +CUA_DRIVER_RS_VERSION=0.7.1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/QwenLM/qwen-code/main/packages/cua-driver/scripts/install.sh)" ``` ```powershell # Windows -$env:CUA_DRIVER_RS_VERSION = "0.7.0" +$env:CUA_DRIVER_RS_VERSION = "0.7.1" irm https://raw.githubusercontent.com/QwenLM/qwen-code/main/packages/cua-driver/scripts/install.ps1 | iex ``` @@ -37,7 +37,7 @@ irm https://raw.githubusercontent.com/QwenLM/qwen-code/main/packages/cua-driver/ ```bash qwen-cua-driver --version -# Expected: cua-driver 0.7.0 +# Expected: cua-driver 0.7.1 ``` ### macOS permissions diff --git a/packages/cua-driver/docs/0.7.1-coord-norm-fixes.md b/packages/cua-driver/docs/0.7.1-coord-norm-fixes.md new file mode 100644 index 0000000000..87058221ef --- /dev/null +++ b/packages/cua-driver/docs/0.7.1-coord-norm-fixes.md @@ -0,0 +1,86 @@ +# cua-driver 0.7.1 相对坐标模式修复 + +PR: https://github.com/QwenLM/qwen-code/pull/6610 + +`CUA_DRIVER_RS_COORDINATE_SPACE=1` 开启 0–1000 归一化坐标模式后,多个工具的坐标转换和描述存在缺陷。以下逐一说明。 + +--- + +## 1. get_window_state / get_desktop_state 返回的 screenshot_width/height 被篡改为 1000 + +**原因**:`normalize_result` 在归一化模式下把 `get_window_state` 和 `get_desktop_state` 返回的 `screenshot_width/height` 强制改写为 1000。设计意图是让模型把截图当作 1000×1000 虚拟网格,直接用 0–1000 坐标。但 `elements[].frame` 坐标保持真实像素值(如 x=1444),两者矛盾。 + +**表现**:模型看到 `screenshot_width=1000` 但 element frame 坐标远超 1000,拿到了两套不一致的坐标信息。`get_desktop_state` 的 `screen_width/height` 也没被改,同样矛盾。 + +**修复**:删掉 `normalize_result` 的改写逻辑,函数改为 no-op。查询类工具返回真实像素值,模型通过工具 schema 描述和 MCP instructions 知道使用 0–1000 坐标。 + +## 2. zoom 后 from_zoom 点击坐标未转换 + +**原因**:`denormalize_args` 在 `from_zoom=true` 时直接 return 跳过了整个转换逻辑。注释说"core 层没有 zoom 图片尺寸,无法转换"——但这个尺寸其实可以从 zoom 工具的返回值中缓存下来。 + +**表现**:模型发送 0–1000 归一化坐标(如中心点 500,500),被当作像素值直接传给 `zoom_to_window`,点击位置完全偏移。 + +**修复**: +- 新增 `ZOOM_SIZE_CACHE`,在 zoom 工具执行后由 `ingest_zoom_size` 缓存图片的 width/height(keyed by pid) +- `denormalize_args` 的 `from_zoom` 分支改为用缓存的 zoom 图片尺寸做反归一化 +- `ToolRegistry::invoke` 的 output hook 中增加 `ingest_zoom_size` 调用 + +## 3. from_zoom 的工具描述仍然写着 "pixel coordinates" + +**原因**:`rewrite_coord_desc` 只重写了 `input_coord_fields` 中列出的坐标字段(x/y)的描述,没有处理 `from_zoom` 字段本身的描述。 + +**表现**:click 工具的 `from_zoom` 字段描述为 "x and y are pixel coordinates in the last zoom image",模型按此发送像素坐标而非归一化坐标。即使 x/y 的描述已被改为 "0–1000 normalized",`from_zoom` 的描述与之矛盾。 + +**修复**:`rewrite_coord_desc` 中对所有含 `from_zoom` 字段的工具,将其描述改写为 "x and y are 0–{scale} normalized coordinates in the last zoom image"。 + +## 4. 缓存未命中时静默透传归一化坐标 + +**原因**:`denormalize_args` 在 `SIZE_CACHE`、`SCREEN_SIZE`、`DESKTOP_SCREENSHOT_SIZE` 未命中时用 `continue` 跳过该字段,归一化值原样传给工具。 + +**表现**:模型发送 500(归一化中心)但被当作 500 像素处理。坐标错误且不可预测,可能触发意外的误操作,且没有任何报错信息。 + +**修复**:`denormalize_args` 返回类型改为 `Result<(), String>`。缓存未命中时返回明确的错误信息,引导模型先调用对应的查询工具: +- 窗口级 → "Call get_window_state first" +- 桌面级 → "Call get_desktop_state first" +- 屏幕级 → "Call get_screen_size first" +- zoom 级 → "Call zoom first" + +`ToolRegistry::invoke` 中处理该 Result,未命中时直接返回 `ToolResult::error`。 + +## 5. scroll 工具的 x/y 坐标未做归一化转换 + +**原因**:`input_coord_fields` 的注释写着 "scroll / page / set_value carry no coordinates → excluded",但实际上 macOS 和 Windows 的 scroll 工具都有 x/y 参数,用于指定滚轮事件的触发位置(不是滚动量)。 + +**表现**:归一化模式下模型传 0–1000 坐标给 scroll 的 x/y,被当作像素值处理,滚轮事件投递到错误的位置。 + +**修复**:将 `scroll` 加入 `input_coord_fields`,window-basis。 + +## 6. Linux-only mouse 工具未做归一化转换 + +**原因**:`mouse_button_down`、`mouse_button_up`、`mouse_drag`、`parallel_mouse_drag` 四个 Linux 专用工具不在 `input_coord_fields` 中。它们的 x/y 都是 window-local 坐标。 + +**表现**:归一化模式下这些工具的坐标不转换,行为与 click/drag 不一致。 + +**修复**: +- `mouse_button_down`、`mouse_button_up`、`mouse_drag` 加入 `input_coord_fields` +- `parallel_mouse_drag` 的坐标嵌套在 `drags[]` 数组内,在 `denormalize_args` 末尾单独处理:每个 drag item 用自己的 `(pid, window_id)` 查 `SIZE_CACHE` 获取转换基准;转换 `from_x/from_y/to_x/to_y`、`path[[x,y]]`、`x_from/x_to`(fn 表达式域边界) + +## 7. type_text / press_key / hotkey 的 x/y 描述未改写 + +**原因**:这三个工具的 x/y 用于 focus-by-pixel(内部委托给 click),`input_coord_fields` 中没有列出,所以 `rewrite_coord_desc` 跳过了它们的字段描述。 + +**表现**:归一化模式下这三个工具的 x/y 描述仍然写着 "Screenshot-pixel X",模型可能据此发送像素坐标。 + +**修复**:将 `type_text`、`press_key`、`hotkey` 加入 `input_coord_fields`,使其 x/y 描述被重写,同时坐标值也会被正确转换。 + +## 8. 多个工具的顶层描述中残留像素坐标措辞 + +**原因**:`rewrite_coord_desc` 的顶层描述替换只匹配 `"window-local screenshot pixels"` 一个固定字符串,但各平台的工具描述中有多种变体:`"screenshot pixel coordinates"`、`"scaled-image coordinates"`、`"true screen pixels"`、`"zoom-image pixel coordinates"` 等。此外替换后会产生冗余尾部(如 "0–1000 normalized coordinates — the same space get_window_state returns")。 + +**表现**:zoom、drag、get_desktop_state 等工具的描述在归一化模式下仍然包含像素相关措辞,误导模型。 + +**修复**: +- 扩展替换列表覆盖所有变体 +- 增加冗余尾部清理("the same space get_window_state returns" 等) +- `rewrite_coord_desc` 不再跳过空 `input_coord_fields` 的工具,使 `parallel_mouse_drag`、`get_desktop_state` 等工具的顶层描述也能被处理 +- `protocol.rs` 的 MCP instructions 中 "issue a pixel click" 在归一化模式下改为 "issue a coordinate click" diff --git a/packages/cua-driver/scripts/_install-rust.sh b/packages/cua-driver/scripts/_install-rust.sh index b4a08a8e9d..a259a2dce9 100644 --- a/packages/cua-driver/scripts/_install-rust.sh +++ b/packages/cua-driver/scripts/_install-rust.sh @@ -513,7 +513,7 @@ done # the baked line hasn't been updated yet (dev / pre-release checkouts). # # ~~~ BAKED_VERSION: auto-updated by CD workflow after each release — do not edit ~~~ -CUA_DRIVER_RS_BAKED_VERSION="0.7.0" +CUA_DRIVER_RS_BAKED_VERSION="0.7.1" # ~~~ END_BAKED_VERSION ~~~ if [[ -n "${CUA_DRIVER_RS_VERSION:-}" ]]; then diff --git a/packages/cua-driver/scripts/install.ps1 b/packages/cua-driver/scripts/install.ps1 index 459cae2293..dfd28e0938 100644 --- a/packages/cua-driver/scripts/install.ps1 +++ b/packages/cua-driver/scripts/install.ps1 @@ -114,7 +114,7 @@ $BinaryName = "qwen-cua-driver.exe" # where the baked line hasn't been updated yet. # # ~~~ BAKED_VERSION: auto-updated by CD workflow after each release — do not edit ~~~ -$Script:CuaDriverRsBakedVersion = "0.7.0" +$Script:CuaDriverRsBakedVersion = "0.7.1" # ~~~ END_BAKED_VERSION ~~~ # ---------- Path resolution ------------------------------------------------