移动端行为
vp run mobile:behavior 检查 iOS 应用的行为,依据的是它自身的状态,而不是像素:滚动位置、掉帧、Composer(编写器)草稿与焦点、状态标签,以及打开的是哪条对话线程(thread)。它从 Simlock 池租用一台 iPhone 18 Pro 和一台 iPad Pro 13,并在两台设备上并行运行这些用例。它与 vp run mobile:e2e 配套,后者检查布局。
不运行任何模型。每台设备有自己的服务器,其上唯一的提供方(provider)evalbot 是一个由 fake-fx.ts 支撑的 Fx 实例。消息中的 [[eval:…]] 标记用来选定脚本化回复:一段按节奏推进的流、一个被挂起的回合(turn)、一个提问、两个子智能体,或一次失败。每台设备还有自己的 Metro,并把仅用于开发的探针(behavior-probe.ts)编译进去。探针通过 Metro 的 Hermes 检查器读取应用状态,由 agent-device 驱动触摸。
运行
需要 SIMLOCK_AGENT_DEVICE_URL 和 AGENT_DEVICE_DAEMON_AUTH_TOKEN,与 mobile:e2e 相同。
vp run mobile:behavior # both devices, 3 samples per case
vp run mobile:behavior --device iphone-18-pro --samples 1 --case scroll-up-never-teleports
vp run mobile:behavior --list # devices and cases输出写入 artifacts/mobile-behavior/<run>/:summary.md 是记分板。每台设备的文件夹中有 results.jsonl(每个用例样本一行)、run.log、metro.log,以及 env/ 下的服务器。完整运行一轮大约需要 15 分钟。
当已评分样本中有一半或更多失败时,该用例失败;当错误数多于已评分样本时,记为 incomplete。guard 或 control 用例失败或不完整时,这一轮运行失败。bad 用例用来复现已知缺陷,在这些缺陷修复之前都会失败。
指标
- 滚动。 探针在每一个 JS 帧上读取对话线程列表的状态,并记录每个可见行在屏幕上的 y。
backwardPx是逆着拖动方向的最大位移。teleports统计超过 400 pt 的单帧位移,这比真实的甩动更快。maxFromEndPx是距离最新消息的距离。 - 卡顿。 JS 线程的帧来自探针中的
requestAnimationFrame,UI 线程的帧来自一段 worklet 循环。模拟器以 60 Hz 渲染,注入的滑动会占用模拟器的 UI 线程,因此滑动用例只对 JS 帧评分。 - Composer(编写器)。 草稿存储、无障碍树中的编辑器文本、是否已展开,以及键盘是否弹起。
- 状态。 主页每一行的状态来自应用自身的
resolveThreadListV2Status,以及「正在工作」搁架上的数量,并与服务器状态对照。
添加用例
用例是 cases.ts 中的数据:一个 id、一个 kind(bad 目前会在 main 上失败,guard 必须保持通过,control 是日常使用)、它的 source 问题、产出其指标的 scenario、一项 key 指标,以及 checks。新的流程写在 scenarios.ts 中。在修复之前先添加用例,这样缺陷仍在时,它会在 main 上失败;修复落地后,把它从 bad 改为 guard。
尚未覆盖:Live Activities 和通知点击(它们需要 T3 Connect 中继(relay)以及已送达的推送)、原生编辑器滚动、后台工作胶囊和异步提问(Fx 没有后台任务),以及 120 Hz 节奏。