Skip to content

[agentloop] P0:评论 identity 行补上真实 engine/model,不再假装 Claude Code #28

Open

Description

@wangshijun

🤖 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 级 model

arcblock-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:493
  • skills/pr-review/SKILL.md:374
  • skills/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.json version 已 bump,且已跑 publish-agentloop.sh --bump patch 同步
  • cd .claude/plugins/agentloop && bun test lib/ skills/ 全绿(不破坏既有金测)

范围边界(明确排除,别在本 issue 顺手做)

实现位置

PR 提到 ArcBlock/arc 仓库的 .claude/plugins/agentloop/——该插件自己的 CLAUDE.md 写明这里是唯一真相源,ArcBlock/agent-skills(本仓库)是单向发布镜像,不要直接改镜像 clone。

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High priorityenhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions