feat(AI 建任务): AI 自己在真机探索 → 写出可调度任务 → 人工确认入库
AI 控制台下新增子分栏「🧭 AI 建任务」:描述要做什么(例:建一个跑 2 小时的任务、自动刷
某 App、随机点赞),AI 用 de_* 工具自己在设备上探索(看屏/读元素树/点按验证),把走通的
路径写成一条任务草稿,经服务端校验后交人在步骤编辑器里核对/手改/试跑,保存才入库。
链路:POST /api/agent/run{mode:"designer", settings}
→ Agent 自探 → 本地工具 submit_task(draft)
→ core/task_draft 校验(失败把 errors 回灌模型让它改)
→ 只暂存(运行态 + app_meta.agent_task_draft,**不落库**)
→ SSE done{mode,draft,warnings} → 页面草稿预览 → openTaskModal(null, prefill) 预填
关键实现
- core/task_draft.py(新):把执行器的"静默跳过点"(未知 type/空 selector/空 children/
嵌套>5/节点>60/cron 非法/必填缺失)前移成显式 error——POST /api/jobs 对 params 是盲存的,
执行器又静默跳过错误步骤,没有这道闸门就是"任务建好了、跑起来什么都没做"。
归一化兜底任务名/target/schedule/retry/时长;页面填的设置以 overrides 优先于模型。
故意**不比执行器更严**:loop_mode 近义值归一(count→rounds)、缺 max_iterations 补默认 10
(执行器本来就默认)——实测卡太死会把一轮探索耗在改字段上。
有副作用的步骤(评论/发送/购买/删除…)只警告并把触发概率压到 30%(编辑器可改回)。
- mcp_agent/agent.py:双系统提示词(CHAT/DESIGNER)+ 平台级本地工具
(LOCAL_TOOL_SPECS,不进 MCP)+ 每工具调用上限 40 + designer 输出上限 8192 +
**json.loads 容错**(草稿被截断时给模型可读错误,而不是整轮失败)。
- web/agent_api.py:mode/settings 透传、submit_task 处理器(app_context 内校验+暂存)、
done 带 draft、GET /api/agent/task_draft{,+POST,/clear}(草稿走 app_meta,不新建表)。
- 前端:static/admin/taskgen.js + #agent-sub-taskgen 子面板(showSubTab 机制);
tasks.js 的 openTaskModal(jobId, prefill) + 信封归一化 + 唯一 draftKey;
agent.js 按 mode 门控(一个 run 只有一个事件队列,两个 EventSource 会互相瓜分事件)。
顺带修掉一个 chat 也踩的协议 bug:一轮里同时调 de_screenshot 与别的工具时,截图图像会被
插在两条 tool 消息之间 → 模型侧判"工具回应不足"直接 400。改为本轮 tool 消息发完再附图像,
_repair_tool_messages 也改成只数**连续**的 tool 消息。
真机实测(Redmi 22120RN86C,设置页):8 步探索(含 tap_text 验证)→ submit_task 一次通过 →
草稿 8 个顶层步骤(screen_on/open_app/wait_el/click/wait/key_event…)、max_duration 1800、
无 click_xy、3 条 evidence;页面恢复草稿 + 预填编辑器 + 提示块渲染均正常,无 JS 报错。
自测数据已清理(草稿已丢弃、未创建任何任务)。
文档:AI_TASK_GEN.md 状态改「P0 已实现」+ §10 实现记录(差异/护栏/未做项)、AI_CONSOLE.md
(子分栏、designer 分支、SSE done 负载、app_meta 键)、API.md、DATA_MODEL.md、ARCHITECTURE.md、
DEVELOPMENT.md(自测入口)、README.md 索引、backlog 勾掉 P0。
This commit is contained in:
+17
-2
@@ -198,8 +198,8 @@
|
||||
|------|------|------|
|
||||
| GET/POST | `/api/agent/config` | 读写 AI 配置(key 打码回显) |
|
||||
| GET | `/api/agent/devices` | AI 可用设备(含名称与 busy 标记) |
|
||||
| POST | `/api/agent/run` | 启动一轮 AI 会话 |
|
||||
| GET | `/api/agent/run` | 运行状态(刷新恢复用) |
|
||||
| POST | `/api/agent/run` | 启动一轮 AI 会话(`mode:"chat"`=聊天 / `"designer"`=AI 建任务) |
|
||||
| GET | `/api/agent/run` | 运行状态(刷新恢复用;含 `mode`/`draft`) |
|
||||
| GET | `/api/agent/stream` | **SSE 事件流** |
|
||||
| POST | `/api/agent/stop` | 中断当前运行 |
|
||||
| POST | `/api/agent/clear` | 清空对话历史 |
|
||||
@@ -213,6 +213,21 @@
|
||||
| GET | `/api/agent/actions` | 动作库列表 |
|
||||
| POST | `/api/agent/actions/save` | 新增/编辑动作(禁坐标) |
|
||||
| POST | `/api/agent/actions/delete` | 删除动作 |
|
||||
| GET | `/api/agent/task_draft` | **AI 建任务**:读回最近一份草稿(`{saved, running, mode, run_id, draft, draft_error}`) |
|
||||
| POST | `/api/agent/task_draft` | 回存草稿并**重新校验**(不通过返回 400 + `errors`) |
|
||||
| POST | `/api/agent/task_draft/clear` | 丢弃草稿 |
|
||||
|
||||
**AI 建任务(designer 模式)要点**(详见 [AI_TASK_GEN.md](AI_TASK_GEN.md)):
|
||||
|
||||
- `POST /api/agent/run` 额外接受 `mode:"designer"` 与 `settings`(页面上的任务设置,作为草稿
|
||||
的 overrides:`name`/`target_mode`/`group_name`/`serial`/`schedule`/`max_duration`)。
|
||||
designer 跑**不绑会话**(单轮,不吃聊天历史、也不污染会话)。
|
||||
- designer 模式下 Agent 多一个**平台级本地工具** `submit_task(draft)`(**不在 MCP 层**):
|
||||
服务端用 `core/task_draft.validate_draft` 校验,失败把 `errors` 回灌给模型让它改;
|
||||
通过也只**暂存**(运行态 + `app_meta.agent_task_draft`),**不落库**——入库仍要用户在
|
||||
步骤编辑器里确认后走 `POST /api/jobs`。
|
||||
- `done` 事件在 designer 下多带 `{mode, draft, warnings, draft_error}`。
|
||||
- 设备忙 409、单实例运行、权限同聊天模式。
|
||||
|
||||
### 2.10 system(`web/system_api.py`,全部 Admin)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user