logo
0
0
WeChat Login

feat: support dynamic agent runners#27

Merged
created 1 weeks ago
dev
codex/issue-16-dynamic-runners
Edit
OverviewCommits
6
Files changed
20
Attachments

Summary

Implements Issue #16 dynamic runner foundation.

  • Adds defaultRunner, runners, credentials, credentialRefs, persistence/resource policy config fields.
  • Supports runner selection by runner id, runner type, task type, model/default runner.
  • Adds probe CLI for minimal runner health tasks.
  • Collects stdout, stderr, exit code, and configured result files.
  • Adds cnb_api_token metadata and token scrubbing for user-visible command output.
  • Hardens ACP workspace file access after review: workspace sandbox, symlink escape rejection, safer attachment upload.
  • Replaces full host env inheritance with explicit runner env allowlist + credential env injection.

Validation

  • go test ./...
  • go run ./cmd/auto-harness validate -f examples/codex-worker.yaml
  • go run ./cmd/auto-harness probe -f examples/codex-worker.yaml --runner codex --cwd /tmp
  • CNB_TOKEN=visible-secret-value go run ./cmd/auto-harness probe -f examples/codex-worker.yaml --runner remote --cwd /tmp

Review

DeepSeek-TUI review was requested on Issue #16 and blocking findings were fixed in 997860b650cfa5e909b53d4e5625a0c3199b9e14.

NPC
reviewed
NPC

配置中硬编码了敏感的模型名称 gpt-5.5review_model = "gpt-5.5",同时存在硬编码的 base_url = "${CODEX_BASE_URL:-https://token.aiedulab.cn}" 默认值,不符合安全性要求,应避免硬编码敏感信息及外部服务地址。

NPC

新增的运行阶段基础镜像为 docker.cnb.cool/examples/language/golang-1.24,但实际仅需要运行编译后的 auto-harness 二进制文件以及 Node.js 相关工具,无需 Golang 运行环境,增加了镜像体积。同时编译阶段已通过 ARG TARGETARCH 指定架构编译二进制,运行阶段未传递 TARGETARCH 参数,却通过 dpkg --print-architecture 获取架构信息下载 Node.js,若运行阶段架构与编译阶段不一致会导致二进制文件与运行环境架构不匹配,程序无法运行。

NPC

新增的 credentialsrunners 配置示例中存在敏感信息暴露风险:credentials 说明中强调 expose: "never" 用于脱敏,但示例里 env: "CNB_TOKEN" 会将凭证值注入环境变量,若进程环境信息被导出或日志打印,仍会导致敏感信息泄露;同时 runnerscommand.argv 直接使用 "$AUTO_HARNESS_PROMPT" 拼接命令,未做转义处理,存在命令注入风险。

NPC

新增的 probe 函数存在逻辑错误:在第 121 行调用 runner.RunProbe 后,若其结果 result 为 nil 且 err 也为 nil,第 123-128 行访问 result.RunnerIDresult.Stdout 等字段会直接引发空指针 panic;若 err 不为 nil,result 同样可能为 nil,访问字段仍会 panic。应先判断 err 是否为 nil,再处理 result 的字段,避免空指针异常。

NPC

新增的 codexdoagent 两个 runner 的 command.argv 仅执行 printf 打印提示信息,未实际启动对应 worker 服务(如 codex、doagent 程序),会导致任务运行时无法完成实际工作,属于严重逻辑错误。

NPC

新增的 defaultImage 函数在 spec.Image 为空且 spec.Runner(spec.DefaultRunner) 调用失败时返回空字符串,后续 renderDataImage 字段会被赋值为空,最终渲染到 compose 模板的 image: {{ .Image }} 位置会产生 image: 的无效配置,导致生成的 compose 文件无法正常运行。

NPC

ApplyDefaults 方法中,当 s.Runners 为空且 s.Command.Argv 长度大于 0 时,自动创建默认 Runner 的逻辑存在严重问题。代码使用 s.Models.Default 作为默认 ID(第 234 行),若 s.Models.Default 为空则使用 s.Name。然而,后续在 Validate 方法中(第 305-314 行)对 Runner 的校验要求 runner.Type 必须为非空,且 runner.Image 不能为空。但此处自动生成的 Runner 仅设置了 IDTypeImageCommand,未设置 runner.Mode(默认为空字符串),而 Validate 方法中对 runner.Mode 的校验逻辑(第 316 行)允许空字符串通过,这与 ApplyDefaults 中手动设置 Runner 时默认填充 ephemeral 的逻辑(第 215 行)不一致,会导致自动生成的 Runner 与手动配置的 Runner 在默认值处理上行为不一致。此外,自动生成的 Runner 未初始化 Env 字段(map[string]string 类型),而 ApplyDefaults 中手动处理 Runner 时会初始化 Env(第 211-212 行),这可能导致后续使用 runner.Env 时出现空指针问题。更严重的是,当 s.Image 为空且 s.Runners 为空时,Validate 方法会报错(第 265-267 行),但此处自动生成的 Runner 使用了 s.Image(第 241 行),若 s.Image 为空,会导致生成的 Runner 的 Image 为空,进而触发 Validate 中的错误,但此逻辑在 ApplyDefaults 中未做检查,可能导致配置加载后校验失败。

NPC

新增的defaultImage函数存在逻辑缺陷,当spec.Image为空且通过spec.Runner(spec.DefaultRunner)未找到对应runner时,返回空字符串,最终会导致Pod模板中image: {{ .Image }}渲染为空字符串,生成不符合容器规范的空镜像配置,直接引发Pod创建失败。

NPC

sessionNew函数中,当runnerID未匹配到已知Runner时,直接回退到s.spec.DefaultRunner,但未校验默认Runner是否存在。若DefaultRunner配置无效或不存在,后续使用runnerID创建Session后将导致运行时错误,应增加默认Runner的合法性校验。

NPC

collectResultFiles函数中,直接调用os.ReadFile(path)读取文件内容并转换为字符串存入results映射,未对文件大小进行限制。若selected.ResultFiles包含大文件或非文本文件,会导致内存占用过高或结果数据异常。应在读取前检查文件大小,或仅处理预期的文本类结果文件。

is using the merge method to merge into56b150a4

Successfully merged and closed

branch can be safely deleted
Reviewer
None yet
Assignee
None yet
Label
None yet
Participant