Skip to content

Commit f744be7

Browse files
authored
Merge pull request #396 from Integration-Automation/dev
Release: round-13 batch 4 (3 features, v178-v180)
2 parents a50e808 + fbe54d8 commit f744be7

25 files changed

Lines changed: 1055 additions & 0 deletions

README/WHATS_NEW_zh-CN.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
11
# 本次更新 — AutoControl
22

3+
## 本次更新 (2026-06-24) — 匹配前安定门 + 命中稳定性
4+
5+
避免在动画进行中匹配,并确认命中跨帧维持稳定。完整参考:[`docs/source/Zh/doc/new_features/v180_features_doc.rst`](../docs/source/Zh/doc/new_features/v180_features_doc.rst)
6+
7+
- **`region_stability` / `match_persistence`**(`AC_region_stability``AC_match_persistence`):`smart_waits.wait_until_screen_stable` 以布尔门控实时循环——无法对可注入帧序列评分稳定度,也无法检查某*命中*是否维持。`region_stability` 以相邻帧 SSIM 评分(`{stable, mean_ssim, min_ssim}`);`match_persistence` 确认 template 在*每一*帧都找到且中心于 `agree_px` 内一致(`{persisted, n_hits, jitter}`)。重用 `ssim` + `visual_match` + `grounding_consensus`;帧可注入;不导入 `PySide6`
8+
9+
## 本次更新 (2026-06-24) — 色彩感知模板匹配(HSV)
10+
11+
区分形状相同的红色与绿色状态点。完整参考:[`docs/source/Zh/doc/new_features/v179_features_doc.rst`](../docs/source/Zh/doc/new_features/v179_features_doc.rst)
12+
13+
- **`match_color` / `match_color_all`**(`AC_match_color``AC_match_color_all`):`visual_match` 每个匹配器都先转灰阶,故形状相同的红 vs 绿无法区分;`color_region` 找已知颜色的 blob 却无法对多色字形做模板匹配。本功能在 HSV 色相/饱和度上以色彩*距离*度量(`TM_SQDIFF_NORMED`——相关会把绝对色相正规化掉,使红→绿边与黑→蓝边同分)。重用 `color_region` 的 RGB 加载器 + `visual_match` 的 resize/NMS/`Match``channels` 默认 `("h","s")`(平坦饱和度目标用 `("h",)`);纯色 blob 请用 `find_color_region`。不导入 `PySide6`
14+
15+
## 本次更新 (2026-06-24) — 多模板共识匹配
16+
17+
把同一目标的多个参考裁切投票成单一可信位置。完整参考:[`docs/source/Zh/doc/new_features/v178_features_doc.rst`](../docs/source/Zh/doc/new_features/v178_features_doc.rst)
18+
19+
- **`match_ensemble` / `vote_centers`**(`AC_match_ensemble``AC_vote_centers`):一个按钮以多种状态呈现(默认/悬停/按下)但是单一逻辑目标;`ab_locator` 只选一个策略、`match_template(scales=...)` 只扫一个模板——两者都不融合多参考。本功能匹配每个参考,聚类命中中心,只有在 ≥ `min_votes` 个于 `agree_px` 内一致时才接受,返回 `{point, votes, n_candidates, spread}`——减少换肤/动画 UI 的误判。重用 `visual_match.match_template` + `grounding_consensus`;`vote_centers` 为纯投票核心。不导入 `PySide6`
20+
321
## 本次更新 (2026-06-24) — 逐步评审特征 + 规则式步骤评分
422

523
把为代理步骤评分所需的证据打包,并内建规则式评分器。完整参考:[`docs/source/Zh/doc/new_features/v177_features_doc.rst`](../docs/source/Zh/doc/new_features/v177_features_doc.rst)

README/WHATS_NEW_zh-TW.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
11
# 本次更新 — AutoControl
22

3+
## 本次更新 (2026-06-24) — 比對前安定閘 + 命中穩定性
4+
5+
避免在動畫進行中比對,並確認命中跨幀維持穩定。完整參考:[`docs/source/Zh/doc/new_features/v180_features_doc.rst`](../docs/source/Zh/doc/new_features/v180_features_doc.rst)
6+
7+
- **`region_stability` / `match_persistence`**(`AC_region_stability``AC_match_persistence`):`smart_waits.wait_until_screen_stable` 以布林閘控即時迴圈——無法對可注入幀序列評分穩定度,也無法檢查某*命中*是否維持。`region_stability` 以相鄰幀 SSIM 評分(`{stable, mean_ssim, min_ssim}`);`match_persistence` 確認 template 在*每一*幀都找到且中心於 `agree_px` 內一致(`{persisted, n_hits, jitter}`)。重用 `ssim` + `visual_match` + `grounding_consensus`;幀可注入;不匯入 `PySide6`
8+
9+
## 本次更新 (2026-06-24) — 色彩感知樣板比對(HSV)
10+
11+
區分形狀相同的紅色與綠色狀態點。完整參考:[`docs/source/Zh/doc/new_features/v179_features_doc.rst`](../docs/source/Zh/doc/new_features/v179_features_doc.rst)
12+
13+
- **`match_color` / `match_color_all`**(`AC_match_color``AC_match_color_all`):`visual_match` 每個比對器都先轉灰階,故形狀相同的紅 vs 綠無法區分;`color_region` 找已知顏色的 blob 卻無法對多色字形做樣板比對。本功能在 HSV 色相/飽和度上以色彩*距離*度量(`TM_SQDIFF_NORMED`——相關會把絕對色相正規化掉,使紅→綠邊與黑→藍邊同分)。重用 `color_region` 的 RGB 載入器 + `visual_match` 的 resize/NMS/`Match``channels` 預設 `("h","s")`(平坦飽和度目標用 `("h",)`);純色 blob 請用 `find_color_region`。不匯入 `PySide6`
14+
15+
## 本次更新 (2026-06-24) — 多模板共識比對
16+
17+
把同一目標的多個參考裁切投票成單一可信位置。完整參考:[`docs/source/Zh/doc/new_features/v178_features_doc.rst`](../docs/source/Zh/doc/new_features/v178_features_doc.rst)
18+
19+
- **`match_ensemble` / `vote_centers`**(`AC_match_ensemble``AC_vote_centers`):一個按鈕以多種狀態呈現(預設/懸停/按下)但是單一邏輯目標;`ab_locator` 只選一個策略、`match_template(scales=...)` 只掃一個模板——兩者都不融合多參考。本功能比對每個參考,聚類命中中心,只有在 ≥ `min_votes` 個於 `agree_px` 內一致時才接受,回傳 `{point, votes, n_candidates, spread}`——減少換膚/動畫 UI 的誤判。重用 `visual_match.match_template` + `grounding_consensus`;`vote_centers` 為純投票核心。不匯入 `PySide6`
20+
321
## 本次更新 (2026-06-24) — 逐步評審特徵 + 規則式步驟評分
422

523
把為代理步驟評分所需的證據打包,並內建規則式評分器。完整參考:[`docs/source/Zh/doc/new_features/v177_features_doc.rst`](../docs/source/Zh/doc/new_features/v177_features_doc.rst)

WHATS_NEW.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
11
# What's New — AutoControl
22

3+
## What's new (2026-06-24) — Pre-Match Settle Gating + Match Persistence
4+
5+
Avoid matching mid-animation, and confirm a hit holds steady across frames. Full reference: [`docs/source/Eng/doc/new_features/v180_features_doc.rst`](docs/source/Eng/doc/new_features/v180_features_doc.rst).
6+
7+
- **`region_stability` / `match_persistence`** (`AC_region_stability`, `AC_match_persistence`): `smart_waits.wait_until_screen_stable` gates a live loop with a boolean — it can't score stability on an injectable frame sequence or check whether a *match* held steady. `region_stability` scores consecutive-frame SSIM (`{stable, mean_ssim, min_ssim}`); `match_persistence` confirms a template is found in *every* frame with the centres agreeing within `agree_px` (`{persisted, n_hits, jitter}`). Reuses `ssim` + `visual_match` + `grounding_consensus`; injectable frames; no `PySide6`.
8+
9+
## What's new (2026-06-24) — Colour-Aware Template Matching (HSV)
10+
11+
Tell a red status dot from a green one of identical shape. Full reference: [`docs/source/Eng/doc/new_features/v179_features_doc.rst`](docs/source/Eng/doc/new_features/v179_features_doc.rst).
12+
13+
- **`match_color` / `match_color_all`** (`AC_match_color`, `AC_match_color_all`): every `visual_match` matcher grayscales first, so red vs green of identical shape is indistinguishable; `color_region` finds known-colour blobs but can't template-match a multi-colour glyph. This matches on HSV hue/saturation with a colour-*distance* metric (`TM_SQDIFF_NORMED` — correlation would normalise away the absolute hue, scoring a red→green edge same as black→blue). Reuses `color_region`'s RGB loaders + `visual_match`'s resize/NMS/`Match`. `channels` default `("h","s")` (use `("h",)` for flat-saturation targets); for solid blobs use `find_color_region`. No `PySide6`.
14+
15+
## What's new (2026-06-24) — Multi-Template Consensus Matching
16+
17+
Vote several reference crops of one target into a single trustworthy location. Full reference: [`docs/source/Eng/doc/new_features/v178_features_doc.rst`](docs/source/Eng/doc/new_features/v178_features_doc.rst).
18+
19+
- **`match_ensemble` / `vote_centers`** (`AC_match_ensemble`, `AC_vote_centers`): a button renders in several states (default/hover/pressed) but is one logical target; `ab_locator` picks one strategy and `match_template(scales=...)` sweeps one template — neither fuses multiple references. This matches each reference, clusters the hit centres, and accepts a target only when ≥ `min_votes` agree within `agree_px`, returning `{point, votes, n_candidates, spread}` — cutting false positives on themed/animated UI. Reuses `visual_match.match_template` + `grounding_consensus`; `vote_centers` is the pure voting core. No `PySide6`.
20+
321
## What's new (2026-06-24) — Per-Step Critic Features + Rule-Based Step Scorer
422

523
Bundle the evidence to score an agent step, with a built-in rule-based scorer. Full reference: [`docs/source/Eng/doc/new_features/v177_features_doc.rst`](docs/source/Eng/doc/new_features/v177_features_doc.rst).
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
Multi-Template Consensus Matching
2+
=================================
3+
4+
A button often renders in several states — default / hover / pressed / disabled — yet it is a
5+
single logical target. ``ab_locator`` A/B-tests *which single strategy wins* and
6+
``match_template(scales=...)`` sweeps *one* template across scales — neither fuses *multiple
7+
reference crops* into one vote. ``match_ensemble`` matches each reference, clusters the hit
8+
centres and accepts a target only when at least ``min_votes`` references agree within
9+
``agree_px`` — sharply cutting false positives on themed / animated UI.
10+
11+
The voting core (``vote_centers``) is pure-stdlib and reuses ``grounding_consensus`` for the
12+
clustering, so it is unit-testable with no image; only ``match_ensemble`` itself calls
13+
``visual_match.match_template`` (testable on a synthetic injected ``haystack``). Imports no
14+
``PySide6``.
15+
16+
Headless API
17+
------------
18+
19+
.. code-block:: python
20+
21+
from je_auto_control import match_ensemble, vote_centers
22+
23+
# three reference crops of the same button (default / hover / pressed)
24+
result = match_ensemble(["btn_default.png", "btn_hover.png", "btn_pressed.png"],
25+
min_score=0.8, agree_px=10, min_votes=2)
26+
if result:
27+
click(*result["point"]) # {point, votes, n_candidates, spread}
28+
29+
# or vote hit centres you already have
30+
vote_centers([[100, 100], [102, 98], [400, 400]], agree_px=10, min_votes=2)
31+
32+
``match_ensemble`` returns ``{point, votes, n_candidates, spread}`` for the consensus location,
33+
or ``None`` if fewer than ``min_votes`` references agree. ``vote_centers`` is the pure voting
34+
step over candidate centres you supply.
35+
36+
Executor commands
37+
-----------------
38+
39+
``AC_match_ensemble`` (``templates`` / ``min_score`` / ``agree_px`` / ``min_votes`` /
40+
``region`` → ``{found, result}``) and ``AC_vote_centers`` (``centers`` / ``agree_px`` /
41+
``min_votes`` → ``{found, result}``). They are exposed as the MCP tools ``ac_match_ensemble`` /
42+
``ac_vote_centers`` (read-only) and as the Script Builder commands **Match Ensemble (vote
43+
references)** / **Vote Centers (consensus)** under **Image**.
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
Colour-Aware Template Matching (HSV)
2+
====================================
3+
4+
Every matcher in ``visual_match`` converts to grayscale first, so a red versus green status
5+
indicator of identical shape is *indistinguishable* to ``match_template`` — the discriminating
6+
signal is thrown away. ``color_region`` finds blobs of a *known* colour but cannot
7+
template-match a multi-colour glyph by appearance. ``color_match`` matches on the HSV
8+
hue / saturation channels using a colour-*distance* metric (``TM_SQDIFF_NORMED``, not a
9+
correlation — correlation normalises away the absolute hue, so a red→green edge and a
10+
black→blue edge would score the same), locating colour-discriminated targets that grayscale
11+
matching collapses.
12+
13+
It reuses ``color_region``'s RGB loaders and ``visual_match``'s resize / NMS / ``Match``. The
14+
``haystack`` is injectable; the search is unit-testable on synthetic arrays. Imports no
15+
``PySide6``.
16+
17+
Note: like any window metric, a *flat* single-colour patch has no per-channel variance — for
18+
solid colour blobs use ``find_color_region``; ``color_match`` is for targets with colour
19+
*structure*.
20+
21+
Headless API
22+
------------
23+
24+
.. code-block:: python
25+
26+
from je_auto_control import match_color, match_color_all
27+
28+
# locate a red status chip, not the green one of the same shape
29+
hit = match_color("status_red.png", channels=("h", "s"), min_score=0.7)
30+
if hit:
31+
click(*hit.center)
32+
33+
for m in match_color_all("tag_green.png", channels=("h",)):
34+
print(m.center, m.score)
35+
36+
``match_color`` returns the best ``Match`` over the chosen ``channels`` (default ``("h", "s")``;
37+
use ``("h",)`` for flat-saturation targets), or ``None``. ``match_color_all`` returns every
38+
match at or above ``min_score`` with overlaps removed by NMS.
39+
40+
Executor commands
41+
-----------------
42+
43+
``AC_match_color`` (``template`` / ``channels`` / ``min_score`` / ``scales`` / ``region`` →
44+
``{found, match}``) and ``AC_match_color_all`` (adds ``max_results`` / ``nms_iou`` →
45+
``{count, matches}``). They are exposed as the MCP tools ``ac_match_color`` /
46+
``ac_match_color_all`` (read-only) and as the Script Builder commands **Match Template
47+
(colour/HSV)** / **Match Template All (colour/HSV)** under **Image**.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
Pre-Match Settle Gating + Match Persistence
2+
===========================================
3+
4+
Matching mid-animation is a top flakiness source: the spinner is still spinning, a transition
5+
is half-done, and the matcher fires on a transient. ``smart_waits.wait_until_screen_stable``
6+
gates a *live polling loop* and returns a boolean — it cannot score stability on an *injectable*
7+
sequence of frames, nor tell you whether a *match* held steady across them. ``match_stability``
8+
adds both, on injected frames so it is unit-testable: ``region_stability`` scores how settled a
9+
frame sequence is (consecutive-frame SSIM), and ``match_persistence`` checks that a template's
10+
hit holds at the same place across the frames (low jitter), not just in one lucky frame.
11+
12+
It reuses ``ssim.ssim_compare``, ``visual_match.match_template`` and
13+
``grounding_consensus.consensus_point`` — no new matching code. The frames are injectable
14+
(ndarray / path / PIL). Imports no ``PySide6``.
15+
16+
Headless API
17+
------------
18+
19+
.. code-block:: python
20+
21+
from je_auto_control import region_stability, match_persistence
22+
23+
frames = [grab(), grab(), grab()] # a few snapshots of the same region
24+
if region_stability(frames, settle_threshold=0.99)["stable"]:
25+
do_the_match()
26+
27+
result = match_persistence("button.png", frames, min_score=0.8, agree_px=8)
28+
if result["persisted"]:
29+
print("steady hit, jitter", result["jitter"])
30+
31+
``region_stability`` returns ``{stable, mean_ssim, min_ssim}`` — ``stable`` when the lowest
32+
consecutive-frame SSIM clears ``settle_threshold``. ``match_persistence`` returns
33+
``{persisted, n_hits, jitter}`` — ``persisted`` when the template is found in *every* frame and
34+
the hit centres agree within ``agree_px`` (``jitter`` is their spread; 0 = rock steady).
35+
36+
Executor commands
37+
-----------------
38+
39+
``AC_region_stability`` (``frames`` / ``settle_threshold`` → ``{stable, mean_ssim, min_ssim}``)
40+
and ``AC_match_persistence`` (``template`` / ``frames`` / ``min_score`` / ``agree_px`` →
41+
``{persisted, n_hits, jitter}``). They are exposed as the MCP tools ``ac_region_stability`` /
42+
``ac_match_persistence`` (read-only) and as the Script Builder commands **Region Stability
43+
(frames)** / **Match Persistence (frames)** under **Image**.

docs/source/Eng/eng_index.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,9 @@ Comprehensive guides for all AutoControl features.
200200
doc/new_features/v175_features_doc
201201
doc/new_features/v176_features_doc
202202
doc/new_features/v177_features_doc
203+
doc/new_features/v178_features_doc
204+
doc/new_features/v179_features_doc
205+
doc/new_features/v180_features_doc
203206
doc/ocr_backends/ocr_backends_doc
204207
doc/observability/observability_doc
205208
doc/operations_layer/operations_layer_doc
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
多模板共識比對
2+
==============
3+
4+
一個按鈕常以多種狀態呈現——預設 / 懸停 / 按下 / 停用——但它是單一邏輯目標。``ab_locator``
5+
A/B 測試*哪個單一策略勝出*,``match_template(scales=...)`` 跨縮放掃描*一個*模板——兩者都不把
6+
*多個參考裁切*融合成一次投票。``match_ensemble`` 比對每個參考,聚類命中中心,只有在至少
7+
``min_votes`` 個參考於 ``agree_px`` 內一致時才接受目標——大幅減少換膚 / 動畫 UI 上的誤判。
8+
9+
投票核心(``vote_centers``)為純標準函式庫,並重用 ``grounding_consensus`` 做聚類,因此可在
10+
無影像下單元測試;只有 ``match_ensemble`` 本身呼叫 ``visual_match.match_template``(可於注入的
11+
合成 ``haystack`` 上測試)。不匯入 ``PySide6``。
12+
13+
無頭 API
14+
--------
15+
16+
.. code-block:: python
17+
18+
from je_auto_control import match_ensemble, vote_centers
19+
20+
# 同一按鈕的三個參考裁切(預設 / 懸停 / 按下)
21+
result = match_ensemble(["btn_default.png", "btn_hover.png", "btn_pressed.png"],
22+
min_score=0.8, agree_px=10, min_votes=2)
23+
if result:
24+
click(*result["point"]) # {point, votes, n_candidates, spread}
25+
26+
# 或對你已有的命中中心投票
27+
vote_centers([[100, 100], [102, 98], [400, 400]], agree_px=10, min_votes=2)
28+
29+
``match_ensemble`` 回傳共識位置的 ``{point, votes, n_candidates, spread}``,或在少於
30+
``min_votes`` 個參考一致時回傳 ``None``。``vote_centers`` 是對你提供的候選中心的純投票步驟。
31+
32+
執行器指令
33+
----------
34+
35+
``AC_match_ensemble``(``templates`` / ``min_score`` / ``agree_px`` / ``min_votes`` /
36+
``region`` → ``{found, result}``)與 ``AC_vote_centers``(``centers`` / ``agree_px`` /
37+
``min_votes`` → ``{found, result}``)。兩者以 MCP 工具 ``ac_match_ensemble`` /
38+
``ac_vote_centers``(唯讀)及 Script Builder 指令 **Match Ensemble (vote references)** /
39+
**Vote Centers (consensus)**(位於 **Image** 分類下)形式提供。
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
色彩感知樣板比對(HSV)
2+
========================
3+
4+
``visual_match`` 的每個比對器都先轉灰階,因此形狀相同的紅色與綠色狀態指示燈對
5+
``match_template`` 而言*無法區分*——具辨別力的訊號被丟棄了。``color_region`` 找*已知*顏色的
6+
blob,卻無法以外觀對多色字形做樣板比對。``color_match`` 在 HSV 色相 / 飽和度通道上以色彩
7+
*距離*度量(``TM_SQDIFF_NORMED``,而非相關——相關會把絕對色相正規化掉,使紅→綠邊與黑→藍邊
8+
得分相同)進行比對,定位灰階比對會塌掉的色彩辨識目標。
9+
10+
本功能重用 ``color_region`` 的 RGB 載入器與 ``visual_match`` 的 resize / NMS / ``Match``。
11+
``haystack`` 可注入;搜尋可在合成陣列上單元測試。不匯入 ``PySide6``。
12+
13+
註:如同任何視窗度量,*平坦*的單色 patch 在各通道無變異——純色 blob 請用
14+
``find_color_region``;``color_match`` 適用於有色彩*結構*的目標。
15+
16+
無頭 API
17+
--------
18+
19+
.. code-block:: python
20+
21+
from je_auto_control import match_color, match_color_all
22+
23+
# 定位紅色狀態 chip,而非同形狀的綠色
24+
hit = match_color("status_red.png", channels=("h", "s"), min_score=0.7)
25+
if hit:
26+
click(*hit.center)
27+
28+
for m in match_color_all("tag_green.png", channels=("h",)):
29+
print(m.center, m.score)
30+
31+
``match_color`` 在選定 ``channels``(預設 ``("h", "s")``;平坦飽和度目標用 ``("h",)``)中回傳
32+
最佳 ``Match``,或 ``None``。``match_color_all`` 回傳所有達到 ``min_score`` 的匹配,重疊以 NMS
33+
移除。
34+
35+
執行器指令
36+
----------
37+
38+
``AC_match_color``(``template`` / ``channels`` / ``min_score`` / ``scales`` / ``region`` →
39+
``{found, match}``)與 ``AC_match_color_all``(另加 ``max_results`` / ``nms_iou`` →
40+
``{count, matches}``)。兩者以 MCP 工具 ``ac_match_color`` / ``ac_match_color_all``(唯讀)及
41+
Script Builder 指令 **Match Template (colour/HSV)** / **Match Template All (colour/HSV)**
42+
(位於 **Image** 分類下)形式提供。

0 commit comments

Comments
 (0)