该代码定义了一个用于移动端(Android)UI自动化测试或交互任务的核心数据模型和枚举。它通过Pydantic模型定义了UI元素、各种操作(如点击、滑动、输入文本)及其参数、操作日志记录项以及任务执行状态。代码的核心是提供一套类型安全、结构化的数据契约,用于描述UI交互动作、记录执行过程并反馈结果状态,为上层自动化逻辑提供数据基础。
graph TD
A[上层逻辑调用] --> B{确定操作类型}
B --> C[创建对应操作参数模型]
C --> D[填充参数(如坐标、文本)]
D --> E[执行操作]
E --> F[生成操作日志]
F --> G[更新操作状态]
G --> H[返回结果给调用方]
H --> I{是否需要反思?}
I -- 是 --> J[创建反思日志项]
I -- 否 --> K[流程结束]
Enum 类型
├── ActionOp (操作类型枚举)
├── SwipeOp (滑动方向枚举)
├── Decision (决策结果枚举)
└── RunState (运行状态枚举)
Pydantic BaseModel 类型
├── AndroidElement (UI元素)
├── OpLogItem (操作日志项)
├── ReflectLogItem (反思日志项)
├── RecordLogItem (记录日志项)
├── DocContent (文档内容)
├── BaseOpParam (操作参数基类)
│ ├── TapOpParam (点击操作参数)
│ ├── TextOpParam (文本输入操作参数)
│ ├── LongPressOpParam (长按操作参数)
│ ├── SwipeOpParam (滑动操作参数)
│ ├── GridOpParam (网格操作参数)
│ └── BaseGridOpParam (网格操作参数基类)
│ ├── TapGridOpParam (网格点击参数)
│ ├── LongPressGridOpParam (网格长按参数)
│ └── SwipeGridOpParam (网格滑动参数)
├── ReflectOp (反思操作结果)
└── AndroidActionOutput (动作执行输出)UI元素的唯一标识符
类型:str
UI元素的边界框坐标,格式为((左上x, 左上y), (右下x, 右下y))
类型:tuple[tuple[int, int], tuple[int, int]]
UI元素的属性描述字符串
类型:str
操作步骤的序号
类型:int
触发操作的提示文本
类型:str
操作执行前的屏幕截图路径或标识
类型:str
操作执行后的响应文本
类型:str
反思步骤的序号
类型:int
触发反思的提示文本
类型:str
反思操作执行前的屏幕截图路径或标识
类型:str
反思操作执行后的屏幕截图路径或标识
类型:str
反思操作执行后的响应文本
类型:str
记录解析步骤的序号
类型:int
触发记录解析的提示文本
类型:str
记录解析操作执行前的屏幕截图路径或标识
类型:str
记录解析操作执行后的屏幕截图路径或标识
类型:str
记录解析操作执行后的响应文本
类型:str
点击操作的文档内容
类型:str
文本输入操作的文档内容
类型:str
垂直滑动操作的文档内容
类型:str
水平滑动操作的文档内容
类型:str
长按操作的文档内容
类型:str
操作名称
类型:str
上一个操作名称
类型:str
参数提取的状态
类型:RunState
点击操作的目标区域标识
类型:int
文本输入操作要输入的字符串
类型:str
长按操作的目标区域标识
类型:int
滑动操作的起始区域标识
类型:int
滑动操作的方向
类型:str
滑动操作的距离描述
类型:str
网格操作的操作名称
类型:str
网格操作的操作名称,通过验证器自动添加'_grid'后缀
类型:str
网格点击操作的目标区域标识
类型:int
网格点击操作的目标子区域标识
类型:str
网格长按操作的目标区域标识
类型:int
网格长按操作的目标子区域标识
类型:str
网格滑动操作的起始区域标识
类型:int
网格滑动操作的起始子区域标识
类型:str
网格滑动操作的结束区域标识
类型:int
网格滑动操作的结束子区域标识
类型:str
反思操作的决定
类型:str
反思操作的思考过程
类型:str
反思操作的文档记录
类型:str
反思操作的参数提取状态
类型:RunState
Android操作输出的数据字典
类型:dict
Android操作的整体执行状态
类型:RunState
这是一个Pydantic模型字段验证器,用于在数据赋值给act_name字段之前对其进行预处理。它的核心功能是确保所有继承自BaseGridOpParam的操作参数类,其act_name字段的值都带有“_grid”后缀,从而在语义上标识这是一个基于网格(Grid)的操作。
参数:
cls:type[BaseGridOpParam],验证器所属的类(BaseGridOpParam或其子类)act_name:str,待验证和处理的原始动作名称字符串
返回值:str,处理后的动作名称字符串,即在原始名称后附加了“_grid”后缀
flowchart TD
A[开始验证 act_name 字段] --> B{输入 act_name 是否为字符串?}
B -- 是 --> C[将 act_name 与 '_grid' 后缀拼接]
C --> D[返回拼接后的字符串]
B -- 否<br>(Pydantic 会处理类型转换或报错) --> D
D --> E[验证结束,返回值赋给字段]
@field_validator("act_name", mode="before") # 装饰器:声明这是一个针对“act_name”字段的验证器,`mode="before"`表示在校验(如类型检查)之前运行
@classmethod # 装饰器:声明这是一个类方法,第一个参数是类本身(cls)
def check_act_name(cls, act_name: str) -> str: # 方法定义:接收原始值`act_name`,返回处理后的字符串
return f"{act_name}_grid" # 核心逻辑:在输入的`act_name`字符串后添加“_grid”后缀并返回定义了移动设备UI自动化操作的基本动作类型,如点击、长按、输入文本、滑动等。
定义了滑动操作的具体方向,如上、下、左、右。
定义了任务执行过程中的决策状态,如返回、无效、继续、成功。
定义了从移动设备UI中提取出的单个UI元素的数据结构,包含唯一标识符、边界框和属性。
定义了用于记录任务执行、自我学习反思等不同场景下的日志条目数据结构。
定义了用于记录不同操作类型(如点击、输入、滑动)的文档内容的数据结构。
定义了操作或参数提取过程的执行结果状态,如成功、完成、失败。
定义了执行各类UI操作(如Tap, Text, LongPress, Swipe, Grid)所需的参数数据结构,并支持参数提取状态跟踪。
定义了自我学习反思环节的输出数据结构,包含决策、思考、文档记录和参数状态。
定义了Android自动化操作的最终输出数据结构,包含操作数据和整体动作执行状态。
SwipeOp枚举类命名与SwipeOpParam类名冲突:SwipeOp枚举定义了滑动方向(如 UP, DOWN),而SwipeOpParam类用于表示滑动操作的参数。两者名称相似但用途不同,容易在代码中引起混淆。AndroidElement.bbox字段的默认值类型不匹配:bbox字段被声明为tuple[tuple[int, int], tuple[int, int]]类型,但其默认值被设置为空字典{}。这违反了类型注解,可能导致运行时错误或类型检查工具(如 mypy)报错。BaseGridOpParam类的check_act_name验证器逻辑可能不完整:该验证器旨在为act_name添加"_grid"后缀。然而,如果act_name本身已经以"_grid"结尾,或者传入的值不是字符串类型,该逻辑可能导致重复后缀或异常。ReflectOp类的字段缺少类型注解和默认值定义:decision、thought、documentation字段仅用空字符串初始化,未使用 Pydantic 的Field进行类型和默认值的正式声明,这削弱了 Pydantic 模型的类型检查和序列化/反序列化能力。AndroidActionOutput.data字段类型过于宽泛:data字段被定义为dict类型,未指定键和值的具体类型。这使得数据结构不明确,降低了代码的可读性和可维护性,并可能隐藏潜在的类型错误。
- 重命名
SwipeOp枚举:建议将SwipeOp枚举重命名为更具描述性的名称,如SwipeDirection,以明确其表示滑动方向,避免与SwipeOpParam类名冲突。 - 修正
AndroidElement.bbox的默认值:将bbox字段的默认值改为一个合法的空元组结构,例如((0, 0), (0, 0))或使用Field(default_factory=lambda: ((0,0),(0,0))),以确保类型一致性。 - 增强
BaseGridOpParam.check_act_name验证器的健壮性:在验证器中添加逻辑,检查act_name是否已以"_grid"结尾,避免重复添加。同时,确保对输入进行适当的类型检查和异常处理。 - 为
ReflectOp类字段添加正式的类型注解:使用Field为decision、thought、documentation等字段明确定义类型(如str)和默认值(如""),以充分利用 Pydantic 的特性。 - 为
AndroidActionOutput.data字段指定更具体的类型:根据实际使用场景,使用TypedDict或 Pydantic 的模型来定义data字段的结构,例如data: Dict[str, Any]或创建一个具体的ActionData模型。这能提高代码的清晰度和类型安全性。 - 考虑使用
Literal类型替代部分字符串枚举:对于ReflectOp.decision这类字段,如果其取值来源于一个固定的集合(如Decision枚举的值),可以考虑使用typing.Literal进行更精确的类型约束。 - 统一日志模型:
OpLogItem、ReflectLogItem和RecordLogItem结构高度相似,ReflectLogItem和RecordLogItem完全相同。可以考虑创建一个基类BaseLogItem包含公共字段,然后通过继承来定义特定日志类型,以减少代码重复。
本模块旨在为Android UI自动化任务提供一个结构化的动作定义与参数管理框架。其核心设计目标包括:
- 类型安全与数据验证:利用Pydantic模型定义所有动作参数,确保输入数据的类型正确性,并通过字段验证器进行业务逻辑校验。
- 可扩展性:通过基类(如
BaseOpParam)和继承体系(如TapOpParam、SwipeOpParam)设计,支持未来轻松添加新的动作类型及其专属参数。 - 状态追踪:通过
RunState枚举和param_state字段,标准化地追踪动作参数提取及后续执行的成败状态。 - 日志结构化:定义
OpLogItem、ReflectLogItem等日志模型,为任务执行、自我学习、反思等不同场景提供标准化的日志记录格式,便于后续分析与调试。 - 代码清晰与自描述:使用枚举(如
ActionOp,SwipeOp,Decision)明确限定操作和决策的范围,增强代码可读性并减少错误。
主要约束包括:
- 依赖Pydantic库进行数据建模与验证。
- 动作参数模型主要服务于参数解析与传递,不包含具体的UI交互逻辑实现。
- 日志模型中的
image、image_before等字段预期存储为Base64字符串或文件路径,具体存储方式由使用方决定。
本模块未显式定义自定义异常类,其错误处理机制主要内建于Pydantic模型和枚举中:
- 数据验证错误:当传入的数据不符合
BaseModel字段类型定义或field_validator的校验规则时,Pydantic会抛出ValidationError异常。例如,为SwipeOpParam.swipe_orient字段传入非SwipeOp枚举值的字符串。 - 状态标识:通过
RunState枚举和BaseOpParam.param_state字段,以返回状态值(SUCCESS,FAIL)而非抛出异常的方式来标识参数提取过程的成功与失败。这是一种更适用于流程控制的错误处理方式。 - 枚举值安全:使用
Enum类定义ActionOp、Decision等,确保相关变量只能取预定义的值,避免了无效字符串的使用,从源头减少了错误。 - 默认值:模型字段大多设置了合理的默认值(如空字符串、-1、空字典),这有助于避免因字段缺失导致的处理错误,但使用方需注意区分默认值与有效值。
本模块定义了多个数据模型,它们在不同场景下构成特定的数据流:
- 动作执行流:
- 输入:原始指令或LLM响应(字符串)。
- 解析:根据
ActionOp类型,选择对应的*OpParam模型(如TapOpParam)进行参数解析与填充。param_state记录解析状态。 - 输出:填充好的参数模型实例,传递给具体的执行器(代码中未体现)来操作Android UI。
- 反馈:执行结果(成功/失败)可能通过
AndroidActionOutput.action_state或更新RunState来反馈。
- 学习与反思流:
- 记录:任务执行过程中,使用
OpLogItem记录每一步的提示词、屏幕截图、LLM响应。 - 分析:在反思阶段,使用
ReflectLogItem记录动作前后的屏幕状态、反思提示及LLM的决策与分析。 - 文档化:反思结果中的
documentation字段可被提取并结构化到DocContent模型中,用于积累知识。
- 记录:任务执行过程中,使用
- 状态转换:
RunState构成了一个简单的状态机,用于标识单次操作(如参数提取)的结果。Decision枚举则用于更高层次的流程控制决策(如继续、回退、成功)。它们共同支撑起任务执行引擎的状态管理。
- 外部依赖:
- Pydantic (>=2.0):核心依赖,用于所有数据模型的定义、序列化、反序列化及数据验证。
- Python 标准库 (enum):用于定义枚举类型。
- 接口契约(导出模型):
- 动作定义:
ActionOp,SwipeOp枚举。调用方需根据这些枚举值来指定操作类型。 - 参数模型:所有继承自
BaseOpParam的类(如TapOpParam,SwipeGridOpParam)。它们是调用方向执行器传递参数的标准数据结构。 - 决策与状态:
Decision,RunState枚举。用于模块间传递控制决策和状态信息。 - UI元素:
AndroidElement模型。定义了与UI自动化框架交互时,UI元素的标准化表示格式。 - 日志模型:
OpLogItem,ReflectLogItem,RecordLogItem。规定了不同日志场景下应记录的数据格式。 - 输出容器:
AndroidActionOutput。作为动作执行结果的标准化容器。 - 反思结果:
ReflectOp。标准化了反思步骤的输出格式。 - 文档内容:
DocContent。提供了存储累积的操作文档的结构。 - 使用方应通过实例化这些模型类并填充相应字段来与本模块交互,并遵守其字段类型和验证规则。
- 动作定义: