AI 脚本 JSON 生成规范
定义 WeMod 编辑器的 JSON 数据结构和字段约束,让 AI 可以输出可直接粘贴导入的脚本 JSON。完整 JSON Schema 覆盖 Script、ActionBlock、ActionNode、ScriptAction 及 ActionConfig。
概述
本页定义 WeMod 编辑器脚本的 JSON 数据结构,供 AI(如 ChatGPT、Claude、DeepSeek 等)在生成脚本时参考。
AI 生成的目标格式是编辑器「粘贴 JSON」功能可导入的 JSON 字符串。编辑器支持两种格式:原生节点结构和 AI 简化格式。
AI 应优先输出原生节点结构(最高兼容性),当不确定字段细节时可使用简化格式。编辑器会自动兜底解析。
- 原生格式:直接对应 ActionNode/ActionBlock 的 kotlinx.serialization 序列化结果,字段精确。
- 简化格式:AI 不熟悉完整字段时输出简写 steps 数组,由 AiScriptAdapter 适配器展开为原生节点。
- 粘贴方法:在编辑器侧边工具栏点击「粘贴 JSON」按钮,粘贴 JSON 字符串后确认。
脚本根结构(Script)
脚本的 JSON 根对象包含以下字段:
id(必填):字符串 UUID,如 "a1b2c3d4-..."
name(必填):脚本名称,如 "自动签到"
root(必填):ActionBlock 对象,脚本的根节点列表
settings(可选):ScriptSettings 对象,脚本全局设置
consoleVariables(可选):控制台变量列表
virtualControls(可选):虚拟控件定义列表
baseScreenWidth(可选):基准屏幕宽度,默认 0(自适应)
baseScreenHeight(可选):基准屏幕高度,默认 0(自适应)
AI 可以只提供 id、name 和 root 三个字段,其余使用默认值。
ActionBlock(节点列表容器)
ActionBlock 是节点的线性列表容器,执行顺序为列表顺序。
结构:{"nodes": [ActionNode, ...]}
root 字段和 if/thenBlock/elseBlock/while/block 等嵌套字段都使用 ActionBlock。
ActionNode 通用字段
所有 ActionNode 共享以下可选字段:
enabled:布尔值,是否启用,默认 true
id:字符串 UUID,建议每个节点生成唯一 ID(不提供则会自动注入)
displayName:展示名称,用于编辑器显示
comment:注释说明,如 "点击登录按钮"
jumpLabel:跳转目标标签名,配合 Goto 节点使用
- type 字段决定节点类型,通过 @SerialName 值区分。
- 主要节点类型:action、if、repeat、while_var、while_vision、try_catch、race、var_switch、set_var、inc_var、label、goto、break、continue、block、subflow_def、call_subflow、event_listener。
action 节点(原子动作)
最常用的节点类型,包含一个原子动作 ScriptAction 和可选通用配置 ActionConfig。
{"type": "action", "action": ScriptAction, "config": ActionConfig}
- action 字段是必填的 ScriptAction 对象。
- config 字段是可选 ActionConfig,设置重试、延迟等。
ScriptAction 动作类型
{"type": "tap", "x": 540, "y": 1100, "duration": 50}
{"type": "multi_tap", "x": 540, "y": 1100, "count": 2, "intervalMs": 80}
{"type": "touch_down", "x": 540, "y": 1100, "pointerId": 1}
{"type": "touch_up", "pointerId": 1}
{"type": "move_pointer", "points": [{"x": 540, "y": 1100}], "duration": 240}
{"type": "long_press", "x": 540, "y": 1100, "duration": 1000}
{"type": "swipe", "fromX": 200, "fromY": 800, "toX": 200, "toY": 400}
各动作字段详解见触控动作节点文档。
视觉与定位动作(ScriptAction)
{"type": "click_text", "condition": {"type": "text_exists", "text": "确认", "left": 0, "top": 0, "right": 1080, "bottom": 2400}}
{"type": "click_image", "condition": {"type": "template_match", "templateBase64": "..."}}
{"type": "click_color", "condition": {"type": "color_at", "x": 100, "y": 100, "color": 4294967295, "tolerance": 10}}
{"type": "wait_for_vision", "condition": {...}, "timeoutMillis": 10000}
{"type": "check_vision", "condition": {...}}
{"type": "find_and_click", "targetText": "按钮文字"}
{"type": "find_and_input", "targetText": "输入框", "inputText": "内容"}
{"type": "scroll_to_find", "text": "目标文字", "maxScrolls": 5}
{"type": "delay", "millis": 2000}
控件节点动作(ScriptAction)
无障碍控件节点通过 NodeSelector 定位:
{"type": "node_click", "selector": {"text": "按钮", "className": "Button"}}
{"type": "node_input", "selector": {...}, "inputText": "内容"}
{"type": "wait_node", "selector": {...}, "appear": true, "timeoutMs": 5000}
{"type": "node_swipe", "selector": {...}, "direction": "UP", "distanceRatio": 0.2}
NodeSelector 字段:text(文本)、className(类名)、packageName(包名)、desc(描述)、depth(深度)、instanceIndex(实例索引)、scrollable(是否可滚动)等。
if 节点(条件分支)
条件分支节点:
{"type": "if", "condition": VisionCondition, "thenBlock": ActionBlock, "elseBlock": ActionBlock}
condition 字段可选:视觉条件(VisionCondition)、时间条件(TimeCondition)、变量条件(VarCondition)或 ConditionGroup。
thenBlock 为条件成立时执行;elseBlock 可选,为条件不成立时执行。
循环与重复节点
{"type": "repeat", "times": 3, "block": ActionBlock, "intervalMillis": 200}
{"type": "while_var", "key": "i", "op": "LT", "value": 5.0, "block": ActionBlock}
{"type": "while_vision", "condition": VisionCondition, "block": ActionBlock}
CompareOp 枚举:LT(<)、LE(<=)、EQ(==)、NE(!=)、GE(>=)、GT(>)。
while_var 的 maxIterations 字段建议设置避免无限循环。
变量操作节点
{"type": "set_var", "key": "count", "value": 0}
{"type": "inc_var", "key": "count", "delta": 1}
value 支持数字、字符串、布尔值和 null。
跳转与标签节点
{"type": "label", "name": "loop_start"}
{"type": "goto", "target": "loop_start"}
{"type": "break"}
{"type": "continue"}
label 和 goto 配合使用实现流程跳转。
其他结构节点
{"type": "try_catch", "tryBlock": ActionBlock, "catchBlock": ActionBlock}
{"type": "race", "leftBlock": ActionBlock, "rightBlock": ActionBlock}
{"type": "var_switch", "key": "status", "cases": [{"matchValue": "ok", "block": ActionBlock}], "defaultBlock": ActionBlock}
{"type": "block", "block": ActionBlock, "displayName": "逻辑块"}
{"type": "subflow_def", "name": "子流程1", "block": ActionBlock}
{"type": "call_subflow", "targetName": "子流程1"}
{"type": "event_listener", "eventName": "事件A", "targetSubFlow": "子流程1"}
视觉动作(Vision Actions)
基于视觉识别的动作,依赖 VisionCondition 对象:
{"type": "click_color", "condition": {"type": "color_at", "x": 100, "y": 100, "color": 4294967295, "tolerance": 10}}
{"type": "click_image", "condition": {"type": "template_match", "templateBase64": "base64字符串"}}
{"type": "scroll_until_vision", "condition": {...}, "maxScrolls": 10, "direction": "DOWN"}
{"type": "check_vision", "condition": {...}}
{"type": "no_control_input", "inputText": "内容", "focusX": 300, "focusY": 900, "pasteX": 520, "pasteY": 700}
- scroll_until_vision 的 direction 可选 DOWN / UP / LEFT / RIGHT。
- no_control_input 用于游戏无控件场景,通过剪贴板+粘贴完成输入。
控件节点动作(Node Actions)
基于无障碍节点选择器的动作,通过 NodeSelector 定位控件:
{"type": "node_double_click", "selector": {...}}
{"type": "node_swipe", "selector": {...}, "direction": "UP", "distanceRatio": 0.2}
{"type": "node_clear_input", "selector": {...}}
{"type": "node_focus", "selector": {...}}
{"type": "node_set_checked", "selector": {...}, "checked": true}
NodeSelector 控件选择器字段
NodeSelector 用于定位无障碍控件节点,支持以下筛选字段:
text:控件的文本内容,如 "确认"
className:控件类名,如 "Button"、"EditText"、"TextView"
packageName:应用包名,如 "com.example.app"
desc:控件的内容描述(contentDescription)
depth:节点在视图树中的深度
instanceIndex:同类型控件中的第几个实例(从 0 开始)
scrollable:是否可滚动,布尔值
多点触控与手势动作
支持复杂的多点触控链路:
{"type": "touch_down", "x": 540, "y": 1100, "pointerId": 1}
{"type": "move_pointer", "touchDownRefId": "...", "points": [{"x": 600, "y": 1200}], "duration": 240}
{"type": "touch_up", "pointerId": 1}
{"type": "single_touch", "points": [{"x": 540, "y": 1200}, {"x": 600, "y": 800}], "duration": 180}
{"type": "multi_touch", "touchPointers": [{"points": [{"x": 260, "y": 900}], "duration": 120}, {"points": [{"x": 820, "y": 900}], "duration": 120}]}
{"type": "drag_to_target", "startX": 200, "startY": 800, "endX": 200, "endY": 400, "duration": 300}
- touch_down/touch_up 成对使用,通过 pointerId 配对。
- move_pointer 续接已按下的触点到目标位置。
- single_touch 定义一条完整的触点移动路径。
- multi_touch 同时触发两个以上触点(双指缩放等)。
- drag_to_target 是拖拽快捷动作,从起点拖到终点。
系统与运行控制动作
操作系统级和运行控制类动作:
{"type": "global_action", "action": "HOME"} // 可选 HOME / BACK / RECENT_APPS / NOTIFICATIONS / QUICK_SETTINGS / POWER_DIALOG / LOCK_SCREEN / SCREENSHOT / SPLIT_SCREEN / TOGGLE_SPLIT_SCREEN
{"type": "open_app", "packageName": "com.example.app"}
{"type": "open_link", "uri": "https://example.com"}
{"type": "prompt", "displayType": "SIMPLE", "title": "提示", "message": "请手动操作", "confirmText": "完成", "cancelText": "取消"}
{"type": "run_script", "scriptId": "other-script-id"}
{"type": "run_control", "controlType": "PAUSE"} // PAUSE / STOP / RESTART / CONTINUE
{"type": "switch_virtual_control_scheme", "schemeId": "scheme-1"}
{"type": "trigger_virtual_button", "controlId": "btn-a"}
{"type": "http_request", "method": "GET", "url": "https://api.example.com/data", "statusCodeBindToVar": "http_status", "responseBindToVar": "http_resp"}
{"type": "ensure_screen_on"}
{"type": "take_screenshot", "saveToPath": "/sdcard/weMod/screenshot.png", "bindToVar": "screenshot"}
- http_request 支持 GET/POST/PUT/DELETE/PATCH/HEAD。支持自定义请求头(headers 字段,映射对象)、请求体(body,仅 POST/PUT/PATCH)、Content-Type(text/json/form-url-encoded)、超时(timeoutMs,默认 10000)、重试(retryTimes)、结果绑定到变量(responseBindToVar/statusCodeBindToVar)。
- http_request 的 url 和 body 支持从变量读取(urlVarKey/bodyVarKey),方便脚本执行中动态替换。
- http_request 执行前会弹窗确认,可在应用设置中关闭(网络请求确认开关)。
- {"type": "http_request", "method": "GET", "url": "https://api.example.com/data", "headers": {"Authorization": "Bearer xxx"}, "timeoutMs": 15000, "statusCodeBindToVar": "http_status", "responseBindToVar": "http_resp"}
- {"type": "http_request", "method": "POST", "url": "https://api.example.com/submit", "body": "{\"key\": \"value\"}", "bodyType": "JSON", "responseBindToVar": "result"}
- prompt 的 displayType 可选 SIMPLE / CONFIRM / INPUT / LIST / CUSTOM。
- run_control 用于脚本运行中暂停、停止、继续或重启当前脚本。
- run_script 切换到另一个脚本执行。
- trigger_virtual_button 触发虚拟控件中定义的按钮。
- ensure_screen_on 唤醒设备屏幕(需 WAKE_LOCK 权限)。可用条件 screen_on / screen_locked 在 if 节点中检测屏幕状态。
- take_screenshot 截取当前屏幕并保存到文件或绑定 Base64 到变量。依赖 MediaProjection 授权。
文件操作动作
文件操作动作允许脚本对设备文件系统进行增删改查。支持读取、写入、追加、删除、检查存在、列出目录和确保路径存在等操作。
{"type": "file_action", "op": "READ", "path": "/sdcard/weMod/data.txt", "bindToVar": "file_content"}
- FileOpType 枚举:READ(读取文件内容并绑定到变量)、WRITE(覆盖写入,自动创建父目录)、APPEND(追加写入)、DELETE(删除文件或空目录)、EXISTS(检查文件是否存在,绑定 true/false)、LIST_DIR(列出目录下所有文件名,绑定换行分隔列表)、ENSURE_PATH(确保路径存在,自动推断创建类型)。
- ENSURE_PATH 推断规则:路径以 / 结尾或无扩展名 → 创建目录(mkdirs);有文件扩展名(如 .txt/.json)→ 创建空文件(createNewFile)。
- WRITE/APPEND 的写入内容支持直接文本(content)或从变量读取(contentVarKey)。
- 路径支持从变量读取(pathVarKey),适合循环动态切换文件。
- 编码(encoding)默认 UTF-8,支持修改。
- 文件操作支持任意绝对路径(包括 /sdcard/...),Android 11+ 需「所有文件访问权限」。首次执行时若路径在应用私有目录外且无权限,会输出引导提示。
- 文件操作执行前会弹窗确认操作类型与文件名,可在应用设置中关闭(文件操作确认开关)。
- {"type": "file_action", "op": "WRITE", "path": "/sdcard/weMod/config.json", "content": "{\"version\": 1}", "encoding": "UTF-8"}
- {"type": "file_action", "op": "ENSURE_PATH", "path": "/sdcard/weMod/backups/"}
- {"type": "file_action", "op": "LIST_DIR", "path": "/sdcard/weMod/", "bindToVar": "file_list"}
VisionCondition 视觉条件类型
视觉条件用于 if 节点和 click_text/click_image 等动作:
{"type": "text_exists", "left": 0, "top": 0, "right": 1080, "bottom": 2400, "text": "确认"} // 文字存在判断
{"type": "image_exists", "templateBase64": "...", "threshold": 0.8} // 图片匹配判断
{"type": "color_at", "x": 500, "y": 1000, "color": 4289542144, "tolerance": 15} // 坐标颜色判断
{"type": "text_color_at", "x": 500, "y": 1000, "text": "确认", "color": 4289542144, "tolerance": 15} // 文字颜色同时判断
时间条件与变量条件
可用于 if 节点的非视觉条件:
TimeCondition:{"type": "time", "timeCondition": {"startTime": "08:00", "endTime": "22:00", "daysOfWeek": [1,2,3,4,5,6,7]}}
VarCondition:{"type": "var", "varCondition": {"key": "count", "op": "EQ", "value": 5.0}}
ConditionGroup(复合条件组合):{"type": "and", "conditions": [TimeCondition, VarCondition, ...]}
CompareOp 枚举:LT(<)、LE(<=)、EQ(==)、NE(!=)、GE(>=)、GT(>)。
虚拟控件(Virtual Controls)
虚拟控件自动录方案用于录制回放场景。定义方式:
VirtualControlDefinition:{ "id": "btn-a", "type": "BUTTON", "label": "攻击", "bounds": {"x": 100, "y": 800, "width": 200, "height": 100} }
VirtualControlScheme:{ "id": "scheme-1", "name": "默认方案", "controls": ["btn-a", ...] }
在 Script 的 virtualControls 和 virtualControlSchemes 字段中定义。
ScriptSettings 脚本设置
ScriptSettings 控制脚本的全局行为:
ScriptSettings 主要字段:
repeatMode:重复模式(NONE / REPEAT_COUNT / REPEAT_UNTIL_STOP)
repeatCount:重复次数(repeatMode=REPEAT_COUNT 时生效)
stopOnError:出错是否停止
maxRuntimeSec:最大运行时间(秒),超时自动停止
runOnAppStart:应用启动时是否自动运行
ActionConfig 通用配置
每个 action 节点可附加通用配置:
"config": {"preDelayMs": 0, "postDelayMs": 200, "retryTimes": 3, "retryIntervalMs": 500}
- preDelayMs:动作前等待(毫秒),默认 0
- postDelayMs:动作后等待(毫秒),默认 200
- retryTimes:失败重试次数,-1 表示直到成功,默认 0
- retryIntervalMs:重试间隔(毫秒),默认 200
- coordJitterMinPx/coordJitterMaxPx:坐标随机偏移范围
- runtimeConditions:运行时条件组,可附加视觉/时间/变量条件
AI 简化格式(Alternate Format)
如果 AI 不熟悉完整的 ActionNode 字段结构,可以使用简化 steps 格式,编辑器会自动转换为原生节点。
{"steps": [{"action": "tap", "x": 540, "y": 1100, "desc": "打开微信"}]}
- 支持动作类型:tap、click、double_tap、long_press、swipe、wait、delay、find_and_tap、click_text、text_tap、find_and_input、text_input、find_and_swipe、swipe_to_text、if_find、if_text、repeat、loop、wait_vision、wait_until。
- 坐标字段兼容多种命名:x/y、from_x/from_y/to_x/to_y、x1/y1/x2/y2。
- desc/description:注释说明,便于阅读。
- text:视觉查找目标文字。
- input/value:输入文本。
- retry/max_retries:重试次数。
- ms/delay_ms:等待毫秒数。
- times/count:循环次数。
- 简化格式不支持嵌套结构(if_else、repeat 等只有空壳),AI 应优先使用原生格式。
AI 生成注意事项
所有节点建议生成唯一 id(UUID),不生成则由编辑器自动注入。
坐标值应基于 1080x2400 的基准分辨率,编辑器会自动适配。
百分比字段(xPct/yPct)取值范围 0~100,无效值设为 -1。
所有时间字段单位统一为毫秒(ms)。
避免生成编辑器不支持的字段:ignoreUnknownKeys=true 会忽略未知字段。
复杂脚本建议生成 try_catch + 子流程的模块化结构,便于调试。
生成后用户可在编辑器中进行二次调整。
完整示例
以下是一个完整的打开应用→等待加载→点击登录→输入账号密码→确认的 JSON 示例:
{ "id": "demo-script-001", "name": "登录示例", "root": { "nodes": [ { "type": "action", "id": "n1", "comment": "打开微信", "action": { "type": "open_app", "packageName": "com.tencent.mm" }, "config": { "postDelayMs": 2000 } }, { "type": "action", "id": "n2", "comment": "等待加载完成", "action": { "type": "delay", "millis": 3000 } }, { "type": "action", "id": "n3", "comment": "点击登录按钮", "action": { "type": "find_and_click", "text": "登录" }, "config": { "retryTimes": 5 } }, { "type": "action", "id": "n4", "comment": "输入账号", "action": { "type": "node_input", "selector": { "className": "EditText", "index": 0 }, "inputText": "user123" } }, { "type": "action", "id": "n5", "comment": "输入密码", "action": { "type": "node_input", "selector": { "className": "EditText", "index": 1 }, "inputText": "pass456" } }, { "type": "action", "id": "n6", "comment": "点击确认", "action": { "type": "click_text", "condition": { "type": "text_exists", "left": 0, "top": 0, "right": 1080, "bottom": 2400, "text": "确认" } } } ] } }
简化格式示例
适合 AI 不确定完整字段时的输出格式:
{ "steps": [ {"action": "tap", "x": 540, "y": 1800, "desc": "打开微信"}, {"action": "wait", "ms": 3000}, {"action": "find_and_tap", "text": "通讯录", "retry": 5}, {"action": "find_and_tap", "text": "张三"}, {"action": "find_and_input", "text": "输入框", "input": "你好"}, {"action": "find_and_tap", "text": "发送"} ] }