# Workflow v1 数据格式与节点说明 本项目的自动化工作流使用 `workflow/v1`。该格式把工作流看成一个有向图:节点负责执行动作或产出数据,连线负责控制执行顺序或传递数据。 ## 顶层结构 ```json { "schema_version": "workflow/v1", "workflow_key": "notepad-demo", "name": "打开记事本并输入文本", "description": "示例", "variables": { "target_text": { "type": "string", "default": "hello", "description": "要输入的文本" } }, "settings": { "max_steps": 100, "default_timeout_ms": 30000, "on_unhandled_error": "pause_for_user", "return": {"node_id": "result_node", "output": "data"} }, "nodes": [], "edges": [] } ``` 字段说明: - `workflow_key`:可选的稳定调用 key,只能使用字母、数字、下划线和连字符;适合手机快捷指令等远程入口按 key 执行。 - `variables`:工作流变量。运行时可以通过接口传入同名变量覆盖默认值。 - `settings.max_steps`:防止流程循环或异常跳转导致无限执行。 - `settings.return`:异步任务完成后,从指定节点输出中提取 `return_data`。省略 `output` 时返回该节点的全部输出。 - `nodes`:节点实例列表。 - `edges`:节点之间的连线,包括控制流和数据流。 ## 节点结构 ```json { "id": "mouse_1", "type": "mouse.click", "title": "点击目标", "position": { "x": 360, "y": 180 }, "params": { "button": "left", "clicks": 1 }, "inputs": { "x": { "source": "node_output", "node_id": "locate_1", "output": "x" }, "y": { "source": "node_output", "node_id": "locate_1", "output": "y" } } } ``` - `type` 必须来自 `GET /api/automation/workflow-nodes` 返回的节点定义。 - `params` 是界面中固定编辑的参数。 - `inputs` 是运行时输入,可以来自固定值、变量、上游节点输出或运行时上下文。 - `position` 只影响前端画布显示。 ## 输入来源 ```json { "source": "literal", "value": 100 } { "source": "variable", "name": "target_text" } { "source": "node_output", "node_id": "node_a", "output": "x" } { "source": "runtime", "name": "current_screenshot_path" } ``` 第一版执行器支持以上四类输入。数据流连线也会在运行时转换成目标节点的输入值。 ## 连线结构 控制流连线决定执行顺序: ```json { "id": "edge_1", "kind": "control", "source": "start_1", "source_port": "next", "target": "program_1", "target_port": "run" } ``` 数据流连线把源节点输出传给目标节点输入: ```json { "id": "edge_data_x", "kind": "data", "source": "locate_1", "source_port": "x", "target": "mouse_1", "target_port": "x" } ``` ## 内置节点类型 当前内置节点由后端注册表集中提供: - `flow.start`、`flow.end`、`flow.condition` - `mouse.click`、`mouse.double_click`、`mouse.right_click`、`mouse.move`、`mouse.scroll` - `keyboard.press`、`keyboard.hotkey`、`keyboard.key_down`、`keyboard.key_up` - `text.input` - `browser.open_url` - `browser.ensure_foreground`:打开或唤起浏览器,可选打开网址并最大化窗口。 - `browser.control`:执行浏览器全屏、返回、刷新、关闭标签页等快捷控制。 - `browser.video_action`:打开 YouTube/Bilibili/抖音视频,或在抖音视频流切换下一条。 - `browser.web_search`:使用真实浏览器截图和多模态模型,完成搜索结果提取、去重排序、详情页研究和总结。 - `research.ai_web_research`:让 AI 规划查询、执行多轮视觉搜索、评估目标并按 JSON Schema 生成最终数据。 - `vision.locate_element`:截取当前屏幕,调用多模态 AI 定位目标元素的相对百分比位置,并输出换算后的屏幕坐标。 - `vision.click_target`:定位目标并立即点击,减少常见“定位节点 + 鼠标节点”的重复搭线。 - `vision.verify_page`:用多模态 AI 判断当前屏幕是否符合预期状态,并输出匹配分支。 - `vision.close_popups`:尝试识别并点击关闭、跳过、稍后再说等弹窗按钮。 - `media.control`:面向客厅遥控场景的播放暂停、全屏、静音、音量和上下条控制。 - `program.start`、`program.stop`、`program.close_opened` - `screen.screenshot` - `wait.seconds` - `human.ask_user` 每个节点类型的参数、输入、输出和控制端口以 `GET /api/automation/workflow-nodes` 为准。前端节点库和属性面板应使用该接口动态生成。 ## 异步执行 工作流只通过稳定 key 执行: ```text POST /api/automation/workflows/by-key/{workflow_key}/run ``` 接口立即返回任务 ID。所有 workflow 共用一个串行队列,任意时刻只有一个任务运行。使用以下接口读取状态和结果: ```text GET /api/automation/workflow-tasks/{task_id} GET /api/automation/workflow-tasks ``` 任务完成后同时提供完整 `result` 和按 `settings.return` 提取的 `return_data`: ```json { "id": "task-uuid", "status": "SUCCESS", "return_data": {"answer": "..."}, "result": {"status": "SUCCESS", "results": [], "outputs": {}} } ``` 如果节点需要用户判断,执行结果会返回 `status: "PAUSED"`,并包含暂停节点、问题和可选截图路径。节点失败时,后端会尽量保存当前屏幕截图到自动化错误目录,并在失败项的 `artifacts.screenshot_path` 返回路径,供前端展示给用户继续分析。 ## AI 多轮网页研究工作流 仓库提供 `workflows/ai-web-research.workflow.json`。该 workflow 的 key 为 `ai-web-research`,变量包括: - `objective`:搜索和研究目标。 - `output_schema`:最终 `data` 必须满足的 JSON Schema。 - `constraints`:语言、最少来源数、必需域名等约束。 - `max_attempts`:未达成目标时的最大搜索轮数。 节点会先让本地 AI 制定查询计划,再循环调用视觉网页搜索。每轮结束后同时执行 JSON Schema 校验、来源约束校验和 AI 语义目标判断,直到目标达成或达到次数上限。 ## 导入导出 - `POST /api/automation/workflows/import`:导入 workflow JSON,可选择遇到相同 key 时覆盖。 - `GET /api/automation/workflows/by-key/{workflow_key}/export`:导出可迁移 JSON。 - 前端自动化工作流页面提供“导入 JSON”和“导出”按钮。