* feat(subagents): add Codex executor and native agent builtins * fix(subagents): enforce native grants and retain Codex results * fix(subagents): preserve native outcomes and parent permissions
6.2 KiB
Codex 子代理执行器
问题和基准
PR #11003 引入共享外部子代理执行器及 Claude Code ACP 实现。本改动基于该接口,
避免维护第二套分发和任务生命周期。基准为 PR #11003 squash 合入 main 的提交
89da433888c02e2bcc1e5293161c2ba7eea27778。
行为和范围
新增内置 claude-code 和 codex 定义,默认前台执行,也可显式后台运行。
Claude Code 选择已有 ACP 执行器和已安装的 claude-agent-acp 适配器;Codex
选择新执行器,使用已安装的 codex app-server --stdio。不会自动下载程序,
两者均使用各自的认证和模型设置。
已有自定义定义仍优先于这些内置名称,项目或用户层级的同名自定义定义可以删除, 不会移除内置代理。
自定义定义使用已有 executor 字段,kind 接受 acp 或 codex,
command 仍为必填,args 提供程序参数。Codex 省略参数时默认使用
app-server --stdio。已有 Qwen 模型覆盖及不支持的宿主工具限制仍明确拒绝。
Codex 将渲染后的代理指令与独立任务发送到新的原生临时线程,通过共享事件和 记录链路返回最终答案。本次不投射原生工具活动或 token 用量。Codex 仅执行一次, 不能接收消息、恢复或通过 Stop hook 继续。Claude ACP 保留已有事件、审批及 存活期间的继续输入。两者均保留基准对工作流、团队、fork 历史的限制。 worktree 启动沿用公共隔离生命周期,并在派生的工作目录中执行。 不新增 daemon 路由或 UI 组件。
接入和设计决策
扩展已有执行器规范和 CLI 注入工厂。在 packages/cli/src/external-agents
实现 Codex,不新增 SDK 包或依赖。复用共享进程注册表完成清理。
执行器契约新增可选 continuationBlockedReason,仅 Codex 设置,Qwen 和 ACP
保持缺省。Agent 将其复制到已有任务恢复阻断字段,跳过消息/monitor 接线和常驻
保留;Stop hook 请求再次执行时显示警告。注册表拒绝向被阻断任务排入输入。
已有元数据记录执行器类型,阻止重启后按 Qwen 对话恢复。
涉及 frontmatter schema 和内置定义、执行器契约、CLI 工厂和 Codex 实现、任务 输入及继续执行守卫、持久化执行器来源。发现、调度、通知、记录和用户任务控制 沿用基准实现。
权限和生命周期
原生内置代理要求可信工作目录,safe mode 下不可用。两个执行器均支持 macOS/Linux(包括 WSL);原生 Windows 启动会在创建进程前失败并给出平台指引。
Agent 在 manager 构造执行器前解析 Codex 权限。穿过派生 Config 层读取实时会话 模式,包括嵌套、worktree 和恢复的代理;中间 Qwen 代理的 auto-edit 或 fork 的 yolo 不授予原生访问权限。只有 Codex 定义或会话本身能授予该权限。没有代理覆盖 设置时,Codex 继承 会话模式,但不使用进程内代理的 auto-edit 回退:default/plan/auto 均映射为只读。 原生执行不会经过 Qwen 的 AUTO 分类器。工作区写入及无人值守的工作区命令执行 必须由代理或会话显式授予 auto-edit;yolo 授予原生沙箱绕过。会话已处于 auto-edit 或 yolo 时,仍优先于更严格的代理定义。其他有效模式在启动前失败。审批请求和 人工输入一律拒绝;原生工具权限不等于 Qwen 工具规则的执行保障。Qwen 和 ACP 保留已有权限解析方式。外部执行器的权限覆盖保留已解析的模式,但不获取或恢复父级 PermissionManager 的 Qwen AUTO 规则;普通 Qwen 子代理仍使用原有 AUTO 规则生命周期。
验证初始化响应、临时线程确认、关联的线程/轮次 ID 及成功终止结果。缺失答案、
其他轮次结果和完成前的协议错误不能算成功。收到终态通知后冻结通知和答案,但仍需
验证待决的 turn/start 响应;后续输出不能覆盖结果。终态通知之后忽略非法的顶层
输出,即使必需响应尚未到达;必需响应本身的无效结果仍须报错。初始化限时 10 秒,可选
runConfig.max_time_minutes 限制执行时间。已取消的调用不能启动产品。取消、
超时和失败释放待决请求,并在执行器返回前等待进程清理。根进程退出后,读取剩余
输出的等待最多为 10 秒。清理期间取消仍保留已完成的答案,任务状态保持取消。
如果取消或超时已使运行结束,真正的清理失败保留该中断类型,并将清理错误追加到
最终文本。对于其他结果,真正的清理失败仍以错误传递到公共生命周期,错误文本保留
已验证完成的答案。初始进程树快照竞争保留原有例外:沿用 ACP 的处理,报告无法证明
进程树已清理的诊断,并保留原任务结果。取消不会撤销工作目录修改。
验证和验收
测试计划位于 .qwen/e2e-tests/codex-subagent-executor.md。先使用全局 Qwen
确认能力缺口,再用隔离模型和原生协议替身验证重新构建的 CLI。覆盖两个内置定义、
实际 Codex 分发、前后台结果、完成通知、消息和恢复拒绝、Stop hook 行为、权限
约束、缺失程序、错误协议、取消、超时及进程清理,并回归 Claude ACP 和普通
Qwen 执行。明确区分协议替身与真实原生产品运行。
执行构建、类型检查、bundle 和定向包测试。审阅完整增量 diff,直到连续两轮未
发现可确认问题。验收要求 #11474 仅展示基于 #11003 的改动,旧版本的 backend
分发、Claude SDK 包和重复任务生命周期均已移除。
风险和待定事项
已安装 Codex 版本可能改变 app-server 协议。原生产品设置和文件系统影响仍由产品 自身负责。继承的后台 registry 会在取消五秒后发送兜底通知,因此通知可能先于 进程清理完成,也可能不包含迟到的清理诊断;本增量不改变该公共时序。 平台清理结论必须区分已执行测试和源码审阅。没有待定设计问题,实际验证结果 另行记录。