Files
plane-agentd/docs/usage.md
T

10 KiB
Raw Blame History

使用说明:在 Plane 上派活给各机器上的 agent

核对依据:agentd/core.py、agentd/webhook.py、config/agentd.yaml、LXC 上的实际状态、Plane GWENT 项目的标签和成员(2026-10-22)。代码或配置改了要同步改这里。

1. 派单需要的字段

  • 必填:状态设为 Todo,指派人里至少有一个终端账号(window10 或 oregon)。标题加描述就是任务书,原样进入 prompt。标签可选,模块与调度无关。
  • 有多个指派人时,按 Plane 返回的顺序,第一个能对上终端的账号生效(core.py 的 route())。所以"kappiee + window10"会派到 win10。
  • 只指派 kappiee、指派 mac(暂无终端)或不指派:route() 返回空,这一项被静默跳过。Plane 上不会有任何评论,只在 heartbeat.json 的 skipped 里记一条 no route for assignee kappiee,agentd.log 里在原因第一次出现时记一行。
  • 只有 Todo 状态的项会被拾起(pick())。Backlog、Waiting、Review 永远不会自动执行。唯一例外是处于 In Progress、等待临时性重试的项。

2. 终端、执行器和默认值

Plane 指派人 终端 执行器 默认模型 / effort / 档位 运行目录(日志和输出)
window10 win10(Warpgate + Windows 计划任务) codex(codex exec,workspace-write) gpt-6.1-sol / medium / fast C:\…\gwent\runtime\agentd\<run_id>\(prompt.md run.ps1 events.jsonl last.md stderr.txt exit.txt)
oregon oregon(Warpgate + setsid nohup) claude-code(claude -p --permission-mode acceptEdits) sonnet / (不传 effort)/ — /home/ubuntu/.gwent-board/agentd-runs/<run_id>/(out.json 等)
kappiee / mac / 无人 不派 — — —
  • 两个终端的并发都是 1,按终端计数,跨项目共享。
  • win10 设了 busy_processes: [codex]:agentd 自己在 win10 上没有在途运行、却发现有 codex.exe 在跑时,不派单(busy_process codex (… not started by agentd))。
  • oregon 的运行直接在 /home/ubuntu/Documents/wjj/project/gwent 里改文件。这正是指挥所用的 checkout。

3. 代码里实际生效的标签

Plane 里目前只建了 4 个标签:model:astra、model:sol、effort:high、needs-game。其余前缀的标签要先在 Plane 里建出来才能挂上。

标签 效果(route())
model:astra 改用 gpt-6-astra,effort high(来自 by_label 配置)
model:sol 改用 gpt-6.1-sol,tier fast
model:<x>(其他任意) 模型名原样改成 x,例如 oregon 上的 model:opus。模型名与执行器相关:model:astra 挂在 oregon 的项上会让 claude 失败
effort:<x> 只对 codex 生效。claude 的命令模板里没有 {effort},所以被忽略
tier:<x> / tier:none 只对 codex 生效,改档位或去掉档位参数
needs-game 串行组 game:同组同时只跑一项;env 类失败会暂停整组,直到该项离开 Waiting。needs-* 不是通用前缀,只有配置里写了的才生效
exec:<executor> 要求同名执行器存在且终端支持。现在每个终端只有一个执行器,例如 exec:codex 挂在 oregon 上只会得到 executor codex not available 跳过,等于没用
cap:<x> 终端的 capabilities 里必须有 x。win10 有 [android, game],oregon 没有,不满足就跳过
budget:2h / budget:90m 覆盖超时时间,默认 4 h

多个标签按顺序处理,后面的覆盖前面的。

4. 一轮的完整流程

  1. 触发:Plane 的工作区级 webhook(issue 和 issue_comment 事件)约 1 s 内送到 http://10.77.10.249:8790/plane。
    • 接收端用 HMAC 校验签名,只认 GWENT 项目,其他项目返回 202 忽略。
    • 等 3 s,把这期间的投递合并成一次 tick。tick 跑的就是 cron 脚本。
    • tick 运行中又来投递时,结束后再补跑一次。锁被占用(退出码 75)时每 15 s 重试,最多 2 min。
    • 兜底:cron 每 2 分钟一次 tick,同一把 cron.lock。
    • agentd 自己回帖、改状态也会产生投递,所以每个有动作的 tick 后面都会多一次空 tick(实测 11.1 s)。
  2. tick 的步骤:先 poll 所有在途运行(每次中继调用约 10 s),再按编号从小到大挑 Todo 项。依次检查:中继是否通、并发槽位、串行组、busy 进程。
    • 启动前先把 launching 标记落盘,防止重复启动。
    • 启动后把项改为 In Progress 并指派给终端账号,以终端账号发评论 [worker] 第 k 轮开始:codex / gpt-6-astra / high @ win10,新线程,run=GW-26-1。
  3. 实测耗时(runbook 记录和 LXC 的 webhook.log):
    • 建项到投递约 1 s,再加 3 s 合并窗口。
    • win10 启动的那次 tick 91.4 s(GW-26:建项 01:25:14,开工评论 01:26:49)。
    • oregon 启动的 tick 约 72 s。
    • 空 tick 4.6–4.8 s。
    • 瓶颈在中继调用(PAD-12),与触发方式无关。
  4. 结束时:以终端账号回帖。
    • 第一行是 [codex] 第 k 轮结束(exit=…,run=…,终端 win10,日志 <运行目录>),下面是 agent 的最后消息原文(<pre> 包裹,超过 6000 字截断,并注明全文所在路径)。
    • 再按最后消息首行的标签流转(transition()):
首行 状态 / 指派人
[review] Review,指派 oregon(reviewer)
[question] / [blocked] Waiting,指派 oregon(answerer)
[progress] 回到 Todo,留在原终端,下一 tick 续同一线程。连续 12 轮后转 Waiting
没有标签但 exit=0 按 review 处理,并注明"未按协议标注首行"

注意:Waiting 和 Review 都指派给 oregon,不是 kappiee。没有任何东西会自动处理这两个状态,由指挥(或你)介入。 5. 失败:回帖 [worker] 第 k 轮失败:类型=crash|timeout|env|logic,run,exit,重试 n/3。… 并附上最后一帧输出。

  • 临时性错误(stderr 尾部匹配超时、429、5xx、连接被拒等)自动重试,退避 2/5/10 min,续原线程,状态保持 In Progress。
  • 续线程那一轮出现非临时性失败时,立即在新线程重跑一次,并附交接摘要。
  • 其余情况转 Waiting,指派 oregon。超时会先 kill 进程树。逻辑类失败永不自动重试。

5. 回答问题和续跑

  1. 在项上发评论回答,开头不要写 [worker],这类评论永远会被跳过。
  2. 把状态改回 Todo,并把指派人改回原终端(例如 window10)。这一步是坑:如果指派人还是 oregon 就改 Todo,会派给 oregon 的 Claude。因为终端或执行器变了,会重建线程并附交接摘要。
  3. 同一终端、同一执行器、线程续了不到 8 轮时,走 codex exec resume 或 claude --resume,只发送上次之后的新评论(按评论 ID 判断)。
  4. 单发评论只会触发一次空 tick,不会让 agent 动起来,必须改回 Todo。运行期间发的评论,跑着的那一轮看不到,下一轮才带上。

6. 取消和停止

  • 把运行中的项移出 In Progress(改成 Waiting、Backlog、Cancelled 都可以)。下一 tick 会 kill 进程树,回帖 [worker] 运行已取消:工作项状态被改为 X(run=…),释放槽位和串行组,保留线程 ID(cancel())。
  • 如果移到的是 Todo:同一 tick 里先取消,再立刻按新一轮重新派发(续原线程),相当于"带上新评论重启"。
  • 运行已经结束时(exit.txt 已写)再移动:结果照常回帖,但不再改状态,也不重试。
  • 暂停整个终端:把它的 concurrency 设为 0(需要改配置,不能在 Plane 里操作)。

7. 日志和状态的位置(LXC)

  • /var/log/plane-agentd/{agentd.log, cron.log, webhook.log}
  • /var/lib/plane-agentd/{agentd-state.json, heartbeat.json}:heartbeat 里有 skipped 及原因、inflight、down。
  • 健康检查:GET http://10.77.10.249:8790/healthz
  • 任务产出本身在终端的 repo 里,gwent 的惯例是 win10 的 runtime/edits/GW-k/。

8. 用手机试一下(冒烟测试,5 步)

  1. GWENT 新建工作项,标题 冒烟 oregon 往返。描述:只回复一行 [review] ok;不要读写或修改任何文件,不要运行命令。 oregon 的 Claude 是 acceptEdits,并且在指挥用的 checkout 里运行,所以这句必须写。
  2. 指派人只选 oregon,不加标签(默认 sonnet),状态设为 Todo。
  3. 约 1–1.5 分钟后:状态变成 In Progress,出现 oregon 发的评论 [worker] 第 1 轮开始:claude-code / sonnet @ oregon,新线程,run=GW-n-1。
  4. 再过约 1–3 分钟(历次冒烟 1.5–3 min):出现评论 [claude-code] 第 1 轮结束(exit=0 …) 加 [review] ok,状态变为 Review、指派 oregon。
  5. 可选,测续线程:评论 请只回复 [review] ok 2,状态改回 Todo(指派保持 oregon)。开始评论会写"续线程 xxxx",结束后回 [review] ok 2。最后手动改成 Done。
    • 超过 3 分钟没动静:看 heartbeat 的 skipped,常见原因是 oregon 槽位被占,或指派人不对。

9. 通知和手机 App(2026-10-22 核实)

  • Plane 官方手机 App 可以登录自建的 Commercial 版(选 "Self hosted sign in",填 https://plane.kappiee.com)。plane.kappiee.com 只对内网和 tailnet 开放,手机要开 Tailscale。
  • 自建实例没有手机推送:Plane 文档原文 "Push notifications are currently available only for Plane Cloud users."(docs.plane.so/devices/mobile)。App 里只能在收件箱看到通知。
  • 收件箱只收你被指派、被 @、创建或订阅的项。Waiting 和 Review 现在都指派给 oregon,不会进你的收件箱。需要你处理的项,由指挥改成指派 kappiee 或 @你。
  • 真正推到手机要走外部渠道:给 Plane 配 SMTP 发邮件,或用 ntfy 之类。计划放在最后(PAD-13)。agentd 里现在的 notify: {kind: none} 是空钩子。