feat(tester): initialize agent target from Orca selectors
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
# Tester Agent 执行目标
|
||||
|
||||
只在用户要运行测试时读取本文件。测试目录仍由发起运行的项目决定;`execution`
|
||||
不再单独作为终端配置。`agent` 统一决定使用哪个 Agent、在哪个 Orca 环境、哪个
|
||||
项目/目录中执行。
|
||||
|
||||
## 配置
|
||||
|
||||
`catalog.yaml` 提供可提交的默认值,`.pouch/tester/local.yaml` 可以覆盖同名字段。
|
||||
机器名、远程环境、项目路径和 Agent 选择优先写在 `local.yaml`,不要把个人机器路径
|
||||
或临时 Agent 选择提交到项目。
|
||||
|
||||
```yaml
|
||||
agent:
|
||||
environment: "" # Orca 保存的远程环境;空值表示当前环境
|
||||
host: local # 该环境中的目标 host
|
||||
project: "" # Orca project id 或名称;可由 terminal id 反查填入
|
||||
path: "" # 目标机器上的项目绝对路径;为空表示当前项目
|
||||
role: test # tester 固定为 test
|
||||
cli: codex # codex/cursor-agent/grok/omp/pi
|
||||
tier: standard # standard/strong
|
||||
model: null # 精确模型 ID;null 表示使用该 CLI 的默认模型
|
||||
reasoningEffort: medium # low/medium/high/xhigh 或 null
|
||||
permissionMode: workspace-write # read-only/workspace-write
|
||||
```
|
||||
|
||||
`HOST` 仍然是被测服务地址,不能用来表示执行机器。执行目标没有配置时,使用当前
|
||||
项目根目录和默认 test Agent,但仍然创建一个全新的 terminal;不查找、不复用已有
|
||||
terminal。
|
||||
|
||||
旧版 `execution` 配置仍可读取并迁移为 `agent` 的环境、host、path 字段,但新配置
|
||||
不再保存自由 `command` 或 `wait`。Agent CLI 的启动参数由 tester/Orca 的可信映射
|
||||
生成,不能从项目文本中拼接 shell 命令。
|
||||
|
||||
## 解析 Agent、项目和目录
|
||||
|
||||
用户可以直接给 tester 以下任一种定位信息:
|
||||
|
||||
- Orca project id 或项目名称;
|
||||
- Orca terminal id,例如 `term_...`;
|
||||
- 不提供定位信息,使用当前项目。
|
||||
|
||||
有定位信息时优先使用解析脚本,避免手工拼接 Orca JSON:
|
||||
|
||||
```bash
|
||||
python3 <skill-dir>/scripts/resolve_agent.py \
|
||||
--root <project-root> --terminal <terminal-handle> [--environment <name>] --write
|
||||
|
||||
python3 <skill-dir>/scripts/resolve_agent.py \
|
||||
--root <project-root> --project <project-id-or-name> [--environment <name>] --write
|
||||
|
||||
python3 <skill-dir>/scripts/resolve_agent.py \
|
||||
--root <project-root> --project <project-id-or-name> \
|
||||
--environment <name> --path <absolute-target-path> --write
|
||||
```
|
||||
|
||||
脚本会跨已保存的 environment 查询 terminal/project,写入
|
||||
`.pouch/tester/local.yaml` 的 `agent` mapping,并打印配置更新列表。没有 `--write` 时只解析
|
||||
和预览,适合先检查结果。
|
||||
|
||||
1. 如果给出 terminal id,枚举当前和已保存的 Orca environment,调用
|
||||
`orca terminal show --environment <env> --terminal <handle> --json`。从结果读取
|
||||
`executionHostId`、`worktreeId`、`worktreePath`、`agentIdentity`,terminal id 只
|
||||
用于定位,不能作为本轮执行 terminal 复用。
|
||||
2. 如果给出 project id/名称,枚举对应 environment 的 project 和 worktree,先精确匹配
|
||||
project id/name,再精确匹配 worktree id/name/path。一个项目有多个 worktree 时,
|
||||
展示候选并停下;用户可以补充 `--path` 或改用 terminal id,不按分支或路径猜测。
|
||||
3. 将解析结果写入 `local.yaml.agent`。保留用户已有的 `HOST`、授权和其它字段;只
|
||||
更新 agent 配置。terminal 推导出的 `cli` 只在 metadata 明确提供
|
||||
`agentIdentity` 时覆盖已有值。模型、reasoning、权限等无法从 Orca 证明的字段,
|
||||
优先保留已有配置,否则使用 tester 模板默认值,并在更新列表中明确展示;不能把它们
|
||||
伪装成 terminal 的真实 metadata。
|
||||
4. `path` 为空时解析为发起运行的项目根目录;配置了远程 environment 时,必须解析
|
||||
为该远程环境上的绝对路径。
|
||||
5. 用 Orca 查询目标项目/worktree 是否已注册,匹配必须是
|
||||
`environment + host + 规范化 path` 的精确匹配,不得按标题、分支或模糊路径猜测。
|
||||
6. 找不到 Orca 项目记录时,直接为该已有目录建立项目记录:
|
||||
|
||||
- 当前环境的 Git 目录:`orca repo add --path <path> --json`
|
||||
- 保存的远程环境:在命令上加 `--environment <agent.environment>`。
|
||||
|
||||
`host` 不是当前环境的 local 时,先用 `orca host list --json` 确认目标主机;如果
|
||||
该目录只能通过已有 project setup 导入,则使用 `orca project setup-existing-folder`
|
||||
为该 project/host 建立 setup,再重新查询 worktree。不能把一个 local worktree
|
||||
当成远程 host 的项目使用。
|
||||
|
||||
之后重新查询并取得 `worktree` selector。项目准备失败要记为
|
||||
`environment-fail`,不要继续创建 terminal。
|
||||
|
||||
这里的“没有项目就创建”指创建/登记 Orca 的项目记录,不是删除或重建用户目录,
|
||||
也不是创建新的 Git worktree。目标目录必须已经存在且包含待测项目;如果目录本身
|
||||
不存在,停止并说明需要先在目标机器准备项目。
|
||||
|
||||
## 配置更新结果
|
||||
|
||||
完成解析和 `local.yaml.agent` 初始化后,立即向用户展示更新后的生效配置列表。
|
||||
这是配置更新结果,不是测试启动前的人工确认门槛。列表至少包含:
|
||||
|
||||
```text
|
||||
## tester Agent 配置更新结果
|
||||
|
||||
来源: terminal:<handle> | project:<selector> | current-project
|
||||
Agent: <cli>
|
||||
角色 / 档位: test / standard
|
||||
模型: <model 或 n/a>
|
||||
推理强度: <reasoningEffort 或 n/a>
|
||||
权限: <read-only | workspace-write>
|
||||
Orca 环境: <environment>
|
||||
执行节点: <host>
|
||||
项目: <project id>(<项目名称>)
|
||||
目录: <absolute path>
|
||||
Worktree: <worktree id>
|
||||
Terminal: 每轮新建,结束后关闭,不复用当前 terminal
|
||||
|
||||
以上是本次更新后的 Agent 生效配置;如需调整,直接修改 `local.yaml.agent` 后重新运行 tester。
|
||||
```
|
||||
|
||||
只有项目或目录存在多个候选时才标记 `待确认` 并停下,要求补充 `--path` 或 terminal
|
||||
id,不能按分支或路径猜测。配置更新本身不创建 terminal,也不产生测试副作用。
|
||||
|
||||
## Terminal 生命周期
|
||||
|
||||
每次 tester 运行只创建一个新的 terminal,整轮用完后关闭。不能为了方便复用已有
|
||||
terminal,也不能关闭运行开始前已经存在的 terminal。
|
||||
|
||||
创建命令的形状如下。`<worktree-selector>` 必须是上一步按环境、主机和路径精确解析
|
||||
出的 worktree selector;不要直接用可能跨机器冲突的 `path:<target-path>` 猜测。
|
||||
Agent 的 CLI、模型、推理强度和权限必须来自 `agent` 的结构化字段,由 Orca/Agent
|
||||
启动映射转换为实际启动参数;不要把自由 `command`、argv 或 shell 片段写入配置。
|
||||
如果当前 Orca 版本只有 `orca terminal create --command` 接口,也只能使用 skill
|
||||
维护的 CLI allowlist 映射生成这个参数,不能把配置中的任意字符串直接作为命令执行。
|
||||
从 JSON 读取返回的 `handle`,后续只使用这个 handle;不要重新 list 后凭预览选择
|
||||
terminal。
|
||||
|
||||
- 脚本、浏览器、移动模拟器都交给新建的 test Agent;发送简短的用例范围和执行要求,
|
||||
目标 Agent 在目标目录读取 tester catalog。不要把完整 `cases/` 塞进 prompt。
|
||||
- `permissionMode=read-only` 只能执行不产生测试产物的用例;需要写运行快照、构建或
|
||||
设备状态变更时使用 `workspace-write`,但仍受 tester 的风险授权约束。
|
||||
- terminal 创建成功后,无论测试通过、失败、超时、用户中断还是读取输出失败,
|
||||
都必须执行清理:
|
||||
|
||||
```text
|
||||
orca terminal close --terminal <created-handle> --json
|
||||
```
|
||||
|
||||
`close` 是删除本次临时 terminal 的操作,不是删除项目或 worktree。清理失败时
|
||||
保留 handle,向用户报告 `cleanup-fail`,不得换一个 handle 再关闭。
|
||||
|
||||
如果创建失败,没有 terminal 需要清理,直接报告 `environment-fail`。如果创建成功
|
||||
但中途出现异常,把清理放在 finally 语义的收尾步骤中,再生成运行记录。
|
||||
|
||||
## 运行记录
|
||||
|
||||
在运行快照顶层保存本次 Agent 执行目标,至少包含:
|
||||
|
||||
```yaml
|
||||
agent:
|
||||
environment: ""
|
||||
host: local
|
||||
project: "..."
|
||||
path: /absolute/project/path
|
||||
role: test
|
||||
cli: codex
|
||||
tier: standard
|
||||
model: null
|
||||
reasoningEffort: medium
|
||||
permissionMode: workspace-write
|
||||
worktree_id: "..."
|
||||
terminal_handle: "..."
|
||||
terminal_created: true
|
||||
terminal_closed: true
|
||||
```
|
||||
|
||||
不要把 token、配对码或完整环境变量写入快照。terminal 输出只保留能支持结果判定
|
||||
的摘要;测试结果仍按主运行规范使用 `pass`、`fail`、`environment-fail`、`skipped`
|
||||
和 `not-run`。
|
||||
@@ -2,6 +2,20 @@
|
||||
|
||||
只在用户要跑测试时读本文件。
|
||||
|
||||
Agent、执行目标和临时 terminal 的完整协议见 [execution.md](execution.md)。每轮运行
|
||||
都要先解析并更新 `agent`,输出生效配置列表,准备目标项目并创建一个全新的 terminal;不能复用
|
||||
已有 terminal。
|
||||
测试结束、失败、超时或中断时,都要关闭本轮创建的 terminal。
|
||||
|
||||
## 0. 准备执行目标
|
||||
|
||||
先按 `execution.md` 处理目标机器和项目目录,输出配置更新结果,再进入测试流程。目标项目必须包含
|
||||
可读取的 `.pouch/tester/`;如果目标目录没有测试目录,记为 `environment-fail`,不要
|
||||
偷偷回退到当前项目,也不要把测试文件复制过去。
|
||||
|
||||
`catalog.py select` 输出的 `agent` 是本轮使用的配置快照。记录中要保留 Agent、目标
|
||||
环境、主机、项目、路径、worktree id、terminal handle,以及 terminal 是否成功关闭。
|
||||
|
||||
## 1. 选范围
|
||||
|
||||
未指定范围 → `--tag smoke`,风险上限 = `default_max_risk`,`automation` 默认只跑 `automated`。
|
||||
@@ -42,6 +56,66 @@ python3 <skill-dir>/scripts/catalog.py select --root <root> \
|
||||
- 探测不可达:用它的分类标 environment-fail,其余分类照跑。
|
||||
- 命中 `stop_if`:把用它的分类标 environment-fail 并记 `observed` 值,其余分类照跑;所有选中分类都被挡住时,整轮结论才是 environment-fail。
|
||||
|
||||
## 2.1 移动端平台环境闸门与用户引导
|
||||
|
||||
`driver=mobile` 不是一个可以互换的平台。运行前必须根据 catalog session、用例变量或用户指定,明确本轮是 Android 还是 iOS;无法判断时先停下询问平台,不得猜测。两类平台分别执行以下闸门:
|
||||
|
||||
### Android
|
||||
|
||||
按顺序确认:
|
||||
|
||||
1. `adb` 可执行,且版本与当前 SDK 配置一致。
|
||||
2. `adb devices -l` 至少有一个状态为 `device` 的目标;`unauthorized`、`offline` 或空列表都不能继续。多个目标时必须显式设置 `ANDROID_SERIAL`。
|
||||
3. 被测 APK 已安装,包名与 catalog 的变量一致;可用 `adb -s "$ANDROID_SERIAL" shell pm path "$PACKAGE"` 验证。
|
||||
4. 测试所需的 HOST、端口、局域网/DNS 和权限可从设备访问。
|
||||
|
||||
### iOS
|
||||
|
||||
按顺序确认:
|
||||
|
||||
1. 运行节点是 macOS,并且 `xcrun`、Xcode Command Line Tools 和 `simctl` 可用。Linux/Windows 节点不能伪装成 iOS 环境;需要 macOS 或可访问的远程 Mac。
|
||||
2. 模拟器用 `xcrun simctl list devices available` 确认目标存在且已启动,再用 `xcrun simctl bootstatus <UDID> -b` 确认完成启动;真机用 `xcrun xctrace list devices` 确认已连接、已信任且允许开发。
|
||||
3. 被测 IPA/App 已安装,Bundle ID 与 catalog 的变量一致;模拟器可用 `xcrun simctl get_app_container <UDID> <BUNDLE_ID>` 验证。
|
||||
4. 测试所需的 HOST、端口、局域网/DNS 和权限可从该模拟器/真机访问。
|
||||
|
||||
任一项不满足,都要在执行记录中把受影响的移动用例标为 `environment-fail`,不能改成 API 测试、不能把它们标成产品 `fail`,也不要继续初始化后续移动 session。记录实际探测命令及简短输出,不要把整段设备日志塞进对话。
|
||||
|
||||
### 环境缺失时的用户引导
|
||||
|
||||
对话中必须输出一段可执行的引导,至少包含以下字段:
|
||||
|
||||
```text
|
||||
## tester 环境引导:需要补齐
|
||||
|
||||
平台: Android | iOS
|
||||
状态: environment-fail
|
||||
缺失: <具体探测项和观测结果>
|
||||
|
||||
请完成:
|
||||
1. <修复动作;不要只写“检查设备”>
|
||||
2. <如需连接/启动/安装,写出动作>
|
||||
|
||||
验证:
|
||||
<一条或多条可复制的验证命令>
|
||||
|
||||
完成后: 回复“环境已就绪”,然后重跑原 tester 命令。
|
||||
```
|
||||
|
||||
可按实际缺失替换为以下平台化提示:
|
||||
|
||||
- Android 无设备:提示用户连接并解锁设备、开启 USB 调试、接受 RSA 授权;多个设备时设置 `ANDROID_SERIAL`;再运行 `adb devices -l`,直到目标状态为 `device`。
|
||||
- Android 未安装 APK:提示用户构建/安装与当前测试环境匹配的 APK,并用 `adb -s "$ANDROID_SERIAL" shell pm path "$PACKAGE"` 验证包名。
|
||||
- iOS 非 macOS 或无 Xcode:明确说明 iOS 测试需要 macOS + Xcode/Command Line Tools,提示用户切换到本机 Mac 或配置可访问的远程 Mac;不要建议在 Linux 上安装一个同名命令来绕过检查。
|
||||
- iOS 模拟器未启动:提示用户在 Xcode 或 `simctl` 中创建/启动可用设备,使用 `xcrun simctl bootstatus <UDID> -b` 验证。
|
||||
- iOS 真机未就绪:提示用户连接数据线、解锁并信任此电脑、开启开发者模式并确认设备出现在 `xcrun xctrace list devices`。
|
||||
|
||||
以下是两个可复现的引导示例,测试 skill 行为时应得到同类结果:
|
||||
|
||||
1. Android:`adb devices -l` 只有 `List of devices attached`。期望状态为 `environment-fail`,引导连接/授权设备并给出 `adb devices -l` 验证命令。
|
||||
2. iOS:Linux 节点没有 `xcrun`。期望状态为 `environment-fail`,引导切换到 macOS + Xcode 节点,并说明不能用 API 或 Android session 代替。
|
||||
|
||||
环境引导只负责让用户补齐前置条件;除 catalog 已明确授权的 session 初始化外,不自动安装 SDK、配对真机、修改系统安全设置或上传产物。
|
||||
|
||||
## 3. Session
|
||||
|
||||
看命中条用到的 `session` 键:
|
||||
@@ -71,7 +145,11 @@ python3 <skill-dir>/scripts/catalog.py select --root <root> \
|
||||
python3 <skill-dir>/scripts/catalog.py run-script --root <root> --id <id>
|
||||
```
|
||||
|
||||
`run-script` 只跑命令,返回 `executed` + stdout/exit(或 skipped / environment-fail)。**pass/fail 仍由 Agent 对照 `expected` 判定**,不要把 curl 退出码 0 当成产品通过。
|
||||
这个命令必须发送到本轮创建的 terminal 中执行;`<root>` 是目标机器上的项目根,
|
||||
不是发起端当前目录。远程目标上的 skill 脚本不可用时,直接在该 terminal 中执行
|
||||
`how.run` 展开后的命令,并保留同样的 stdout/exit 证据。`run-script` 只跑命令,返回
|
||||
`executed` + stdout/exit(或 skipped / environment-fail)。**pass/fail 仍由 Agent 对照
|
||||
`expected` 判定**,不要把 curl 退出码 0 当成产品通过。
|
||||
|
||||
没有 `run`:按 `how.steps` 做,证据对照 `expected`。不要发明 steps 里没有的调用。
|
||||
|
||||
@@ -100,6 +178,9 @@ python3 <skill-dir>/scripts/generate_run_csv.py --root <root> --run <yaml>
|
||||
范围: …
|
||||
风险上限: …
|
||||
session: browser=复用|新开|未用;mobile=…
|
||||
Agent: <cli> / <model> / <permissionMode>
|
||||
执行目标: <environment>/<host>:<project>:<path>
|
||||
terminal: 新建 <handle>,已关闭|清理失败
|
||||
计数: pass=N fail=N environment-fail=N skipped=N not-run=N
|
||||
失败: id + 一句证据
|
||||
跳过: id + 原因
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
项目根 `.pouch/tester/`:
|
||||
|
||||
```
|
||||
catalog.yaml 分类、风险阶梯、session、变量
|
||||
local.yaml.example HOST 与授权开关模板(默认 127.0.0.1)
|
||||
catalog.yaml 分类、风险阶梯、session、变量、默认 Agent 目标
|
||||
local.yaml.example HOST、授权开关和 Agent 目标模板(默认 127.0.0.1)
|
||||
local.yaml 本机覆盖,不提交
|
||||
cases/<category>.yaml 一个分类一个文件(执行源)
|
||||
cases.csv 给人看的扁平清单;只由 cases/*.yaml 生成,不包含运行结果
|
||||
@@ -33,6 +33,31 @@ runs/*.csv 同一次运行的成绩单;generate_run_csv.py 从对
|
||||
`127.0.0.1`;远程目标必须显式覆盖。查找顺序:环境变量 > `local.yaml` >
|
||||
`catalog.yaml` 的 vars。也认 `HX_TEST_HOST` 作为 `HOST`。
|
||||
|
||||
## agent
|
||||
|
||||
`catalog.yaml.agent` 是可提交的默认 Agent 目标,`local.yaml.agent` 对其做浅层覆盖。
|
||||
它不参与 `HOST` 变量解析,也不会把远程机器路径写入环境变量。机器路径和临时 Agent
|
||||
选择优先写在不提交的 `local.yaml`。
|
||||
|
||||
| 字段 | 含义 |
|
||||
|------|------|
|
||||
| `environment` | Orca 保存的远程环境选择器;空值使用当前环境 |
|
||||
| `host` | 目标机器标识,默认 `local` |
|
||||
| `project` | Orca project id 或名称;也可由 terminal id 自动解析 |
|
||||
| `path` | 目标机器上的项目路径;空值表示当前项目根目录 |
|
||||
| `role` | Agent 角色,tester 固定为 `test` |
|
||||
| `cli` | `codex` / `cursor-agent` / `grok` / `omp` / `pi` |
|
||||
| `tier` | `standard` / `strong` |
|
||||
| `model` | 精确模型 ID;`null` 表示使用 CLI 默认模型 |
|
||||
| `reasoningEffort` | `low` / `medium` / `high` / `xhigh` 或 `null` |
|
||||
| `permissionMode` | `read-only` / `workspace-write` |
|
||||
|
||||
用户给 project id、项目名称或 terminal id 时,tester 先解析并写入 `local.yaml.agent`,
|
||||
再展示更新后的 Agent/环境/项目/目录生效列表。每轮创建新 terminal,不复用既有
|
||||
terminal;运行结束用 `orca terminal close --terminal <handle>` 关闭本轮创建的 terminal。
|
||||
运行快照保存解析后的 Agent、目标、worktree 和 terminal handle。旧版 `execution` 字段
|
||||
只作为兼容输入读取,不再作为新配置写出。详见 [execution.md](execution.md)。
|
||||
|
||||
运行记录使用 UTC 时间加随机后缀命名,例如
|
||||
`20260920T101530Z-smoke-a13f9c.yaml`,并在 YAML 顶层保存同一个 `runId`。
|
||||
不要使用固定的 `latest.yaml` 或覆盖已有运行文件。
|
||||
|
||||
Reference in New Issue
Block a user