Repository navigation
[agentloop] P0:评论 identity 行补上真实 engine/model,不再假装 Claude Code #28
Description
🤖 AI Agent @ wangshijun-mac-studio · runner:wangshijun · skills@394ba052e-dirty
背景
agentloop 插件现在评论头的身份行(scripts/agent-identity.sh --header)只有三段:@ <hostname> · runner:<runner> · skills@<hash>,没有记录这条评论是 Claude 还是 Codex 产出的、用的哪个型号。
同时,issue-review、pr-review、pr-sweep 三个 skill 里各手写死了一句 — Claude Code(<model>) 拼在评论末尾——这句是 agent 凭自己的自我认知手打的字符串,不是脚本产出。在 Codex 下跑这几个 skill 时,还是会错误自称 "Claude Code",这正是 #18 验收项之一("comment header 自动记录真实 runtime/model,不伪报 Claude Code")点名的 bug。
本 issue 只对应 #18 的这一条验收项,是一个独立可交付的小范围任务,不涉及 #18 其余的调用语法/工具名能力表/模型分层措辞等大范围重写。
关键约束:model 不是总能拿到,别瞎猜
fleet/driver.ts 的 resolveEngine() 里这一行:
const model = e.model ?? (e.kind === "claude" ? cfg.model : undefined);legacy 顶层 cfg.model 只对 claude 生效,codex 永远拿不到它(两边型号 id 命名空间不重叠,把 claude-sonnet-5 传给 codex exec -m 会直接传错型号)。所以 codex 引擎在没有显式配置 engine.model 时,model 就是真 undefined——不是"没查到",是"CLI 用了自己的默认值,driver 全程不知道具体是哪个"。
这不是纸上谈兵的边界情况,本机 ~/.agentloop-fleet/ 的真实配置就命中这个分支:
// deployment.json
{ "model": "claude-sonnet-5", "engine": { "kind": "codex" } }
// repos.json 里 ArcBlock/arcblock-site
{ "engine": { "kind": "codex" } } // 没设 repo 级 modelarcblock-site 这条:e.kind 是 "codex",顶层 cfg.model 对它不生效,model 解析成 undefined。
结论:engine.kind 永远有值(resolveEngine 默认兜底 {kind:"claude"}),必须精确;model 缺失时只印 engine:<kind> 单独一段,绝不猜测或印占位符——印一个看似确定实则可能错的型号,比"老实说不知道"风险更大。也不需要去读 ~/.codex/config.toml / ~/.claude/settings.json 猜 CLI 自己的默认值,那样精确复刻每个 CLI 的 precedence 规则,做错的代价大于收益,不在本 issue 范围内。
具体改动
1. fleet/driver.ts — runEnv()(现在的 Pick<PlannedRun, "skillLocal" | "checkoutPath" | "root" | "runner" | "concurrency" | "setupCommand"> 需要加上 "engine"):
merged.ARC_AGENT_ENGINE = run.engine.kind; // 总是有值
if (run.engine.model) merged.ARC_AGENT_MODEL = run.engine.model; // 可能未配置,别猜2. fleet/driver.ts — executeRun() 的 detail 字段(现在 driver.ts:1353 只记 kind,不记 model):
detail: `checkout ${co.action}; ${run.engine.kind}${run.engine.model ? `/${run.engine.model}` : ""} exit ${exitCode}`,3. scripts/agent-identity.sh(canonical 脚本;vendored 副本 .claude/plugins/agentloop/scripts/agent-identity.sh 同步改,两处逐字节一致):
加 --engine/--model flag,优先级:显式 flag > env(ARC_AGENT_ENGINE/ARC_AGENT_MODEL)> 缺省不显示。输出规则:
- kind 已知、model 未知 → 追加
· engine:<kind> - kind、model 都已知 → 追加
· engine:<kind>/<model> - kind 未知(理论上只会发生在手动跑脚本且未传参、也没有 env 的场景)→ 整段不显示
示例:
@ vm · runner:robert · skills@a2298a3b · engine:codex/gpt-5-codex
@ vm · runner:robert · skills@a2298a3b · engine:codex
4. .claude/verify/identity.test.ts:IDENTITY_RE 放开,允许可选的尾段 · engine:\S+;新增用例覆盖:显式 --engine codex --model gpt-5-codex、只有 env 没有 flag、engine 已知但 model 缺失(对应上面的真实场景)三种分支。
5. 删除 3 处硬编码 — Claude Code(<model>)(脚本现在自己会带 engine 信息,这句手写文字变成多余且会出错):
skills/issue-review/SKILL.md:493skills/pr-review/SKILL.md:374skills/pr-sweep/SKILL.md:253
6. 版本 bump:按插件自己 CLAUDE.md 的规矩,任何内容改动必须 bump .claude-plugin/plugin.json 的 version,一步跑完用 bash scripts/publish-agentloop.sh --bump patch,同步发布到本仓库(agent-skills)镜像。
验收标准
-
runEnv()无条件写ARC_AGENT_ENGINE,仅当run.engine.model存在时写ARC_AGENT_MODEL -
agent-identity.sh --engine codex --model gpt-5-codex→ 输出含· engine:codex/gpt-5-codex -
agent-identity.sh --engine codex(无 model)→ 输出含· engine:codex,不含/ -
identity.test.ts新增以上分支用例,全绿 - 3 处硬编码
Claude Code(<model>)已删除 -
plugin.jsonversion 已 bump,且已跑publish-agentloop.sh --bump patch同步 -
cd .claude/plugins/agentloop && bun test lib/ skills/全绿(不破坏既有金测)
范围边界(明确排除,别在本 issue 顺手做)
- 不读取 CLI 自身配置文件猜测未指定时的真实默认型号(已讨论,收益小于风险)。
- 不做 [agentloop] 建立 Claude Code × Codex runtime capability contract #18 剩余部分(调用语法双写
/agentloop:xvs$agentloop:x、工具名能力表、Opus/Sonnet 模型分层措辞、静态 lint、无人值守 hook 敞口文档、双引擎冒烟测试)——这些留在 [agentloop] 建立 Claude Code × Codex runtime capability contract #18 或各自的 spinoff issue 里。
实现位置
PR 提到 ArcBlock/arc 仓库的 .claude/plugins/agentloop/——该插件自己的 CLAUDE.md 写明这里是唯一真相源,ArcBlock/agent-skills(本仓库)是单向发布镜像,不要直接改镜像 clone。
Activity