主要变更: 1. 新增SSEVerifyBus实现基于推送的发送结果校验,替代原DB轮询方案 2. 移除FlowOrchestrator中的DB熔断器,避免雪崩风险 3. 重构SendTextFlow,改用SSE校验流程,删除原DB校验相关代码 4. 新增RoiSpec与ROI搜索支持,优化UI元素匹配精度 5. 更新所有分辨率配置文件,添加ROI配置与调整搜索框坐标 6. 新增WOC_DISABLE_OPENCV环境变量开关,支持纯几何定位模式 7. 清理FlowContext中废弃的before_msg_id字段
111 lines
3.6 KiB
Python
111 lines
3.6 KiB
Python
"""L2 Locator 抽象层基类:GeomSpec + RoiSpec + Selector + ElementHandle。
|
||
|
||
GeomSpec:几何定位规格(relative_to / ratio / offset)
|
||
RoiSpec:图像匹配感兴趣区域(相对窗口的比例矩形,缩小 OpenCV 搜索范围)
|
||
Selector:UI 元素选择器(kind / by_image / by_geom / roi / threshold / require_image)
|
||
ElementHandle:定位结果句柄(绝对坐标 + 置信度 + 策略)
|
||
|
||
L3 Actions 通过 Selector 描述要找的元素,LocatorRegistry 解析为
|
||
ElementHandle(图像命中或几何兜底),Actions 据此调 Backend 执行点击。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from dataclasses import dataclass
|
||
from typing import Optional
|
||
|
||
|
||
@dataclass
|
||
class GeomSpec:
|
||
"""几何定位规格。
|
||
|
||
relative_to 取值:window / window_top_left / window_bottom_right(语义占位,
|
||
实际计算统一用 ratio + offset,offset 已含正负号区分方向)。
|
||
|
||
所有字段带默认值,避免构造时必填字段顺序问题。
|
||
"""
|
||
|
||
relative_to: str = "window"
|
||
x_ratio: float = 0.0
|
||
y_ratio: float = 0.0
|
||
x_offset: int = 0
|
||
y_offset: int = 0
|
||
|
||
|
||
@dataclass
|
||
class RoiSpec:
|
||
"""图像匹配感兴趣区域(ROI),相对窗口的比例矩形。
|
||
|
||
用于将 OpenCV 模板匹配限制在窗口的某个子区域,避免误匹配到
|
||
窗口内其他视觉相似的 UI 元素。例如 input_box 只在聊天区右下角查找,
|
||
即使模板图像有缺陷也不会匹配到窗口中部。
|
||
|
||
所有字段为相对窗口宽/高的比例(0.0~1.0),由 Actions 按当前窗口几何
|
||
转换为绝对像素 ROI 传给 OpenCVBackend.find_template。
|
||
|
||
字段:
|
||
x_ratio: ROI 左上角相对窗口左上角的 X 比例
|
||
y_ratio: ROI 左上角相对窗口左上角的 Y 比例
|
||
w_ratio: ROI 宽度相对窗口宽度的比例
|
||
h_ratio: ROI 高度相对窗口高度的比例
|
||
|
||
边界由 Actions/opencv.py 做裁剪保护,YAML 中可略微宽松。
|
||
"""
|
||
|
||
x_ratio: float = 0.0
|
||
y_ratio: float = 0.0
|
||
w_ratio: float = 1.0
|
||
h_ratio: float = 1.0
|
||
|
||
|
||
@dataclass
|
||
class Selector:
|
||
"""UI 元素选择器。
|
||
|
||
kind:元素类别键(如 search_box / send_button / input_box)
|
||
by_image:图像模板名(P2 启用),非空时优先图像匹配
|
||
by_geom:几何规格,非空时图像失败或 P1 阶段走几何兜底
|
||
roi:图像匹配感兴趣区域(可选)。非空时限制 OpenCV 搜索范围;
|
||
为空时使用全窗口。用于防止模板误匹配到窗口其他相似元素。
|
||
threshold:图像匹配置信度阈值(默认 0.80)
|
||
require_image:高风险操作为 True 时,图像失败即拒绝执行
|
||
description:人类可读描述
|
||
|
||
所有字段带默认值。
|
||
"""
|
||
|
||
kind: str = ""
|
||
by_image: Optional[str] = None
|
||
by_geom: Optional[GeomSpec] = None
|
||
roi: Optional[RoiSpec] = None
|
||
threshold: float = 0.80
|
||
require_image: bool = False
|
||
description: str = ""
|
||
|
||
|
||
@dataclass
|
||
class ElementHandle:
|
||
"""定位结果句柄。
|
||
|
||
selector:来源 Selector(回溯用)
|
||
x / y:元素中心绝对坐标(点击点)
|
||
w / h:元素宽高(图像匹配时返回,几何兜底为 0)
|
||
confidence:匹配置信度(图像命中时为模型分数,几何兜底为 1.0)
|
||
strategy:定位策略 image / geom
|
||
|
||
所有字段带默认值。
|
||
"""
|
||
|
||
selector: Optional[Selector] = None
|
||
x: int = 0
|
||
y: int = 0
|
||
w: int = 0
|
||
h: int = 0
|
||
confidence: float = 1.0
|
||
strategy: str = "geom"
|
||
|
||
@property
|
||
def center(self) -> tuple[int, int]:
|
||
"""返回元素中心点(x, y)。"""
|
||
return (self.x, self.y)
|