feat(任务): 录制手势改成**纯录制回放**(真手指轨迹)+ 手机端 getevent 录制
用户反馈:录制出来的滑动又被套上滑动那套逻辑(方向/幅度/拟人重新生成),
"导致滑动还是不顺畅"。录制就该是录制——按录下的路径与时间原样重放。
- 新步骤 `gesture`「录制手势」:存完整轨迹点列 `[[x,y,t_ms],…]`,
回放时原样交给设备(`d.swipe_points(points, duration)`),不做任何加工。
与 `swipe` 是两套东西(滑动是参数化的,录制是点列)。
- core/gesture.py(新):
· 手机端录制 `PhoneRecorder`:`getevent` 读**真触屏**设备(自动挑 fts_ts 这类、
排除 uinput/vitural-sar 等合成节点),解析两套协议(BTN_TOUCH / ABS_MT_TRACKING_ID);
**合成的注入事件不会出现在真触屏节点上**(实测),所以录到的只有人手的动作;
· 点列清洗:按 ≥16ms 抽稀但**末点必留**(快划时不能把收尾丢了);
· 回放**一次调用**而不是逐点注入:实测这台设备单次触摸 RPC ≈190ms,
逐点回放 20 点要 3.8 秒——只能让设备自己插值,"时间"由点密度还原。
- 接口:POST /api/gesture/record/{start,stop}(需设备权限;重复开始返回 409)。
- 「录制手势」步骤卡片:录到就回填(手机上录 / 网页上录),显示点数/时长;
**滑动步骤上的「录制手势」按钮已移除**(按用户要求,录制不再走滑动逻辑)。
- 录制前自动唤醒设备:**息屏时 u2 抓 UI 树会从 3 秒退化到 65 秒**(实测),
截图也是黑的——这是本次排查最耗时的坑,已写进文档。
自测:假设备单测(点列/时长/抽稀/失败退回直线,10 项);
无头浏览器 + CDP 真模拟拖动 → 录到 14 点/605ms 并按实际轨迹回填;
手机录制接口起停/重复拦截;
真机回放:用录下的轨迹跑任务 → 步骤 `gesture ok`。
⚠️ 手机端"真手指轨迹"这一段需要人真的去划才能端到端验证(我没有手指)。
文档:TASK_DEV §3.2(两套东西对比 + 三个坑)、步骤表 21 种、API、README。
This commit is contained in:
+1
-1
@@ -184,7 +184,7 @@ mcp_agent.Agent.run_stream(prompt, serial, history, on_delta, on_tool, on_usage,
|
||||
从本轮**成功**的步骤轨迹里提炼命名动作(如「打开抖音」)。硬约束:
|
||||
|
||||
- **禁坐标**:带 `click_xy` 的步骤不会被沉淀(坐标换个设备/分辨率就失效)
|
||||
- 白名单步骤类型(20 种去掉 `click_xy`、`keep_screen`)
|
||||
- 白名单步骤类型(21 种去掉 `click_xy`、`keep_screen`、`gesture`)
|
||||
- 每类型有必填参数校验(如 `click` 必须有选择器)
|
||||
- 输入/产出限量:最多 10 步输入、最多 3 个动作 × 4 步
|
||||
- 保存时服务端**再校验一次**,含坐标的提交直接 400
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@
|
||||
|
||||
平台已有两套能力,但互不相通:
|
||||
- **AI 控制台**:一句话 + 选设备 → 多模态 Agent(DeepSeek)通过 20 个 `de_*` 工具在手机上「边看边做」(截图看屏、`de_ui_tree` 拿元素树、`de_tap_element/de_tap_text` 语义点按),流式回放步骤。
|
||||
- **任务系统 + 步骤编辑器**:`generic_steps` 任务 = 一棵可嵌套步骤树(open_app/click/swipe/loop/group/if_el…20 种节点),在编辑器里拖拽编排、单步试跑、定时调度。
|
||||
- **任务系统 + 步骤编辑器**:`generic_steps` 任务 = 一棵可嵌套步骤树(open_app/click/swipe/loop/group/if_el…21 种节点),在编辑器里拖拽编排、单步试跑、定时调度。
|
||||
|
||||
目标:让**非工程用户用一句自然语言需求**(例:「创建一个每日养号刷视频的任务,每天 8:00-9:00 在 100.100.10.13 跑」)得到**一条可直接调度、可继续在现有步骤编辑器里手改的任务**。AI 先自己在设备上打开 App、看 UI 树、确认可点元素,再直接撰写编辑器的步骤 JSON。
|
||||
|
||||
|
||||
@@ -126,6 +126,8 @@
|
||||
| DELETE | `/api/custom_actions/<action_id>` | T | 删除自定义动作 |
|
||||
| GET | `/api/step_defaults` | L | 步骤默认值(生效值 + 出厂值 + 字段规格,供「动作配置」页画表单) |
|
||||
| POST | `/api/step_defaults` | T | 保存步骤默认值(只落与出厂值不同的字段) |
|
||||
| POST | `/api/gesture/record/start` | D | 开始录制手势(手机端 getevent,返回 token) |
|
||||
| POST | `/api/gesture/record/stop` | D | 停止录制并取回轨迹 `gestures:[[[x,y,t_ms],…]]` |
|
||||
| GET | `/api/uiauto/status` | L | uiautodev 服务是否在跑 |
|
||||
| GET | `/api/uiauto/devices` | D | 抓元素可选设备 |
|
||||
| GET | `/api/uiauto/elements` | D | 设备 UI 元素树 |
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
| [ARCHITECTURE.md](ARCHITECTURE.md) | **架构详解**:分层、启动装配顺序、线程与并发模型、设备生命周期、任务调度链路、状态机、关键设计决策与扩展点 | 所有开发者(先读这篇) |
|
||||
| [DATA_MODEL.md](DATA_MODEL.md) | **数据模型**:SQLite 表与字段、schema 迁移、非模型表、`app_meta` 配置键、数据目录、备份覆盖清单 | 后端开发、运维 |
|
||||
| [API.md](API.md) | **HTTP 接口全量**:按蓝图分组的路由表、鉴权、请求/响应示例、非 JSON 响应、错误分支 | 前端开发、外部接入 |
|
||||
| [TASK_DEV.md](TASK_DEV.md) | **任务与步骤开发**:TaskType/TaskJob 概念、20 种步骤全表、公共巡检、选择器与定位、自定义动作、新增任务类型模板 | 写任务的开发 |
|
||||
| [TASK_DEV.md](TASK_DEV.md) | **任务与步骤开发**:TaskType/TaskJob 概念、21 种步骤全表、公共巡检、选择器与定位、自定义动作、新增任务类型模板 | 写任务的开发 |
|
||||
| [MCP.md](MCP.md) | **MCP 手机控制手册**:20 个 `de_*` 工具用法、写操作门控、坐标换算、接入示例 | 接入方、数字员工 |
|
||||
| [MCP_DESIGN.md](MCP_DESIGN.md) | **MCP 设计文档**:边界划分、错误码、白名单/审计设计、演进方向 | 平台开发者 |
|
||||
| [AI_CONSOLE.md](AI_CONSOLE.md) | **AI 控制台**:会话/SSE、经验库、动作库、巡检、Markdown 渲染、推理链、token 统计 | 使用者、平台开发者 |
|
||||
|
||||
+35
-2
@@ -10,7 +10,7 @@
|
||||
|
||||
- [1. 核心概念](#1-核心概念)
|
||||
- [2. 通用步骤任务 generic_steps](#2-通用步骤任务-generic_steps)
|
||||
- [3. 20 种步骤全表](#3-20-种步骤全表)(含 [3.1 步骤默认值与动作录制](#31-步骤默认值与动作录制任务--动作配置))
|
||||
- [3. 21 种步骤全表](#3-21-种步骤全表)(含 [3.1 步骤默认值与动作录制](#31-步骤默认值与动作录制任务--动作配置))
|
||||
- [4. 容器步骤与公共参数](#4-容器步骤与公共参数)(含 [4.5 公共巡检](#45-公共巡检任务级独立于步骤画布))
|
||||
- [5. 选择器与元素定位](#5-选择器与元素定位)
|
||||
- [6. 自定义动作](#6-自定义动作)
|
||||
@@ -108,7 +108,7 @@ from .generic import task # 触发 @register_task(当前唯一任务类型)
|
||||
|
||||
---
|
||||
|
||||
## 3. 20 种步骤全表
|
||||
## 3. 21 种步骤全表
|
||||
|
||||
> 参数与默认值以 `tasks/generic/task.py` 为准;前端 `STEP_LIB`(`static/admin/editor.js`)负责在编辑器里呈现这些字段。
|
||||
|
||||
@@ -134,6 +134,39 @@ from .generic import task # 触发 @register_task(当前唯一任务类型)
|
||||
| 18 | `if_el` | 条件判断 | `selector_type`、`selector_value`、`timeout`(3) | `ocr_click`(False) | `then` / `else` | 见 §4.2;条件类型除元素/OCR 外还支持 **屏幕状态**、**前台App** |
|
||||
| 19 | `notify` | 发通知 | — | `title`("")、`message`("")、`level`("info") | — | 推一条**自定义**通知(事件 `task.notify.custom`):标题正文自己写,支持 `{device} {serial} {job} {time} {app} {screen}`;谁收到取决于 webhook 的事件订阅。两者都空则跳过 |
|
||||
| 20 | `stop_self` | 停止本设备 | — | `reason`("") | — | 只停**本设备**的任务(其它设备照跑):置 worker 停止位,后续步骤不再执行,任务记成**被停止而不是失败**(不触发重试) |
|
||||
| 21 | `gesture` | 录制手势 | `points`(录出来的) | `speed`(1.0) | — | **纯录制回放**:把录下的轨迹点列 `[[x,y,t_ms],…]` 按原路径与时长交给设备插值,不做弧线/抖动/手速加工。与「滑动」是两套东西,见 §3.2 |
|
||||
|
||||
### 3.2 录制手势:**纯录制、纯回放**(`core/gesture.py`)
|
||||
|
||||
「滑动」和「录制手势」是**两套东西**,别混:
|
||||
|
||||
| | `swipe` 步骤 | `gesture` 步骤 |
|
||||
|---|---|---|
|
||||
| 存什么 | 方向 + 幅度 + 时长区间 | **完整轨迹点列** `[[x,y,t_ms], …]` |
|
||||
| 回放时 | 每次重新生成(弧线/抖动/本设备手速) | **照录制的路径与时长**,不做任何修饰 |
|
||||
| 适合 | 通用滑动,换设备也能用 | 你亲手划的、要求一模一样的手势 |
|
||||
|
||||
**为什么录制的不能走滑动那套**:滑动是"参数化"的——它按方向+幅度重新生成轨迹并叠
|
||||
拟人抖动,录下来的路径就被丢掉了。要"完全按我划的重放",就只能存点列、回放点列。
|
||||
|
||||
**两个录制来源**(都在「录制手势」步骤的卡片上):
|
||||
|
||||
| 来源 | 做法 | 特点 |
|
||||
|---|---|---|
|
||||
| ● 手机上录 | 点开始后**用手指在真机上划**,后端读 `getevent` 抓真触屏 | 最真实:录的是人手的原始轨迹。合成注入不会出现在真触屏节点上(实测),所以录到的只有人手 |
|
||||
| ● 网页上录 | 在弹窗画面里按住鼠标拖,前端按 8ms/3px 采样 | 不用碰手机,但有鼠标的机械感 |
|
||||
|
||||
要点与坑:
|
||||
|
||||
- **录制前必须唤醒设备**:息屏时 u2 抓 UI 树会从 3 秒退化到 **65 秒**(实测),截图还是黑的。
|
||||
前端在选好设备后会自动调一次亮屏(`/api/device/screen_all`)。
|
||||
- **回放是一次调用**(`d.swipe_points(points, duration)`),不是逐点注入:实测这台设备
|
||||
**单次触摸注入 RPC ≈190ms**,逐点回放 20 个点要 3.8 秒,比录的手势慢一个数量级。
|
||||
所以只能让设备自己插值——"时间"靠**点密度**还原(手指慢的地方采样点更密)。
|
||||
- 回放点数**抽稀到 40 个**(`MAX_REPLAY_POINTS`):这台设备每个点开销大,40 是画质/耗时折中;
|
||||
首尾点一定保留。
|
||||
- 轨迹是**屏幕绝对像素**:换分辨率不同的设备可能偏,同型号/同分辨率最稳。
|
||||
- 点列存在步骤 JSON 里(一条 0.5s 的手势约 25 点 / 400 字节),不新建表。
|
||||
|
||||
### 3.1 步骤默认值与动作录制(任务 → 动作配置)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user