logo
0
0
WeChat Login

auto-harness

auto-harness 是一个用 Go 编写的可组合 harness,用于构建 AgentForge ACP worker 运行环境。它允许操作者像搭积木一样描述一个 worker:选择容器镜像、挂载 skills、选择专家智能体上下文、挂载工作区、设置启动命令,并声明定时任务。同一份 spec 可以渲染为 Docker Compose,也可以渲染为 AgentForge /api/workers 注册 payload。

当前里程碑是一个刻意保持小而可用的 MVP:

  • 校验 worker YAML spec;
  • 渲染 docker-compose.yml
  • 渲染 agentforge-worker.json
  • 选择并探测 Codex / DoAgent 等可配置 runner;
  • 以 Worker 配置统一管理 runner、环境、技能、生命周期、结果和执行记录;
  • 通过 Coordinator 从项目管理平台发现、认领任务,并调度 Worker 执行;
  • 通过 Gateway 聚合多个 Worker 的能力、健康、状态、日志和结果,并提供统一代理入口;
  • 本地启动 ACP 兼容 HTTP worker endpoint;
  • 暴露文件系统、session API、标准 worker.* JSON-RPC API 和 /gateway/rpc 代理 API,供 AgentForge、Coordinator 或外部系统调用 worker;
  • 渲染 Kubernetes Pod manifest,用于通过集群动态拉起 worker。

为什么需要它

AgentForge 已经支持 doagent 这类 HTTP ACP worker。auto-harness 在此之上增加了一层 builder:不再为每个 worker 手写运行时 endpoint 和注册 JSON,而是把 worker 从可复用的配置块组装出来,并暴露同一套 AgentForge Worker contract。

项目结构

cmd/auto-harness/          CLI 入口
internal/acp/              ACP HTTP server
internal/config/           YAML spec 模型与校验
internal/coordinator/      项目任务扫描、认领、执行记录和 Worker 调度
internal/compose/          Docker Compose 渲染器
internal/credentials/      凭证元数据与日志脱敏
internal/gateway/          Worker registry、代理、路由、健康与能力聚合
internal/harness/          AgentForge worker manifest 渲染器
internal/k8s/              Kubernetes manifest 渲染器
internal/platform/         CNB / GitHub / Jira 等平台 driver 抽象
internal/runner/           命令执行适配器
internal/worker/           Worker 实例、生命周期与 runner 适配层
examples/                  Worker spec 示例
specs/                     Issue 级设计文档

环境要求

  • Go 1.22+
  • Docker,如需运行渲染后的 Compose stack
  • AgentForge Gateway,如需注册生成的 worker
  • Kubernetes / kubectl,如需应用 k8s-pod 生成的 Pod manifest

快速开始

go mod tidy
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
go run ./cmd/auto-harness worker capabilities -f examples/codex-worker.yaml
go run ./cmd/auto-harness worker probe -f examples/codex-worker.yaml --worker codex-code-worker --cwd "$PWD"
go run ./cmd/auto-harness gateway capabilities -f examples/codex-worker.yaml
go run ./cmd/auto-harness gateway start -f examples/codex-worker.yaml --worker codex-code-worker --task-type code --title "Gateway smoke" --cwd "$PWD"
go run ./cmd/auto-harness coordinator scan -f examples/codex-worker.yaml --project auto-harness --store .auto-harness/coordinator.json
go run ./cmd/auto-harness render -f examples/codex-worker.yaml -o build/codex-worker
go run ./cmd/auto-harness k8s-pod -f examples/codex-worker.yaml --namespace agentforge-workers
go run ./cmd/auto-harness serve -f examples/codex-worker.yaml

本地 server 会监听 spec 中的 server.hostserver.port。示例配置使用:

http://127.0.0.1:9100

注册到 AgentForge

render 会写出 AgentForge worker payload:

go run ./cmd/auto-harness render \
  -f examples/codex-worker.yaml \
  -o build/codex-worker

将其注册到 AgentForge Gateway:

curl -X POST http://localhost:8001/api/workers \
  -H 'content-type: application/json' \
  -d @build/codex-worker/agentforge-worker.json

如果你的 AgentForge Gateway 需要认证,请补充对应本地认证 header。

CLI

auto-harness validate -f auto-harness.yaml
auto-harness render   -f auto-harness.yaml -o build/my-worker
auto-harness manifest -f auto-harness.yaml
auto-harness probe    -f auto-harness.yaml --runner codex
auto-harness worker capabilities -f auto-harness.yaml
auto-harness worker probe        -f auto-harness.yaml --worker codex-code-worker --cwd "$PWD"
auto-harness worker start        -f auto-harness.yaml --worker codex-code-worker --task-type code --title "任务标题" --description "任务内容" --store .auto-harness/worker-store.json
auto-harness gateway health       -f auto-harness.yaml
auto-harness gateway capabilities -f auto-harness.yaml
auto-harness gateway route        -f auto-harness.yaml --task-type code --project auto-harness --skills code-commit
auto-harness gateway start        -f auto-harness.yaml --worker codex-code-worker --task-type code --title "任务标题" --cwd "$PWD"
auto-harness gateway status       -f auto-harness.yaml --execution exec_xxx
auto-harness gateway result       -f auto-harness.yaml --execution exec_xxx
auto-harness coordinator scan     -f auto-harness.yaml --project auto-harness --store .auto-harness/coordinator.json
auto-harness coordinator claim    -f auto-harness.yaml --task task_xxx --store .auto-harness/coordinator.json --worker-store .auto-harness/worker-store.json
auto-harness coordinator dispatch -f auto-harness.yaml --execution exec_xxx --store .auto-harness/coordinator.json --worker-store .auto-harness/worker-store.json
auto-harness coordinator run      -f auto-harness.yaml --project auto-harness --store .auto-harness/coordinator.json --worker-store .auto-harness/worker-store.json
auto-harness coordinator daemon   -f auto-harness.yaml --project auto-harness --store .auto-harness/coordinator.json --worker-store .auto-harness/worker-store.json
auto-harness k8s-pod  -f auto-harness.yaml --namespace agentforge-workers
auto-harness serve    -f auto-harness.yaml
auto-harness hello --name AgentForge
auto-harness npc

hello 输出一个简单问候,适合做 wiring 和 CI smoke test。

validate 校验 worker spec。

render 写出:

  • docker-compose.yml
  • agentforge-worker.json

manifest 只打印 AgentForge worker payload。

probe 执行所选 runner 的探针命令,并以 JSON 输出 stdout、stderr、退出码和声明的结果文件内容。--runner 可以是 runner id、runner type 或 task type。

worker capabilities 输出可被 Coordinator 调度的 Worker 能力列表。

worker probe 通过 Worker 抽象探测底层 runner,可用 worker id、runtime 或 task type 选择 Worker。

worker start 创建一个本地 Worker instance,并通过当前 in-process runtime adapter 启动一次 execution;首期实现会包装现有 runner command,并输出 instance、result 和 lifecycle events。传入 --store 时会使用本地 JSON file store 持久化 instance、event 和 result,并对 active execution 做互斥校验。

gateway health 汇总 registry 中所有 Worker 后端的健康状态、可用槽位和错误信息。

gateway capabilities 聚合所有 Worker capabilities,并输出 fleet 视图,供 Coordinator 或 UI 做调度前检查。

gateway route 根据 taskTyperuntimeskillsprojectId 和 Worker 状态选择可承接任务的 Worker;也支持 --worker 定向代理。

gateway start/status/events/logs/result 通过 Gateway 代理标准 Worker API,支持本地 in-process Worker 和远程 HTTP JSON-RPC Worker;同一个 executionIdstart 会返回既有执行,避免重复派发。

coordinator scan 会按项目配置调用平台 driver 发现候选任务,映射为内部 Task,并记录 candidate / skipped 状态。

coordinator claim 会对单个内部 Task 做本地租约认领、平台认领标记、Workflow snapshot 固化和 Execution Record 创建。

coordinator dispatch 会把已创建的 Execution Record 派发给 Worker,保存 Worker instance、round、result、artifact、error 和 feedback 记录,并把结果回写平台;当 gateway.enabled: true 时,派发路径会走 Gateway,以形成 Coordinator -> Gateway -> Worker -> Gateway -> Coordinator 闭环。

coordinator run 会串起 scan、claim、dispatch 和 feedback,适合做单项目闭环 smoke test。

coordinator daemon 会按 coordinator.scanIntervalSeconds 周期性执行 run,每轮开始前会回收已超时的 active execution。

k8s-pod 打印 Kubernetes Pod manifest,用于动态拉起 worker。

serve 启动 ACP HTTP worker endpoint,并在同一进程中提供 /gateway/health/gateway/rpc

npc 运行 CNB NPC 入口,用于响应 CNB issue / PR 评论事件并调用 Codex。

Codex NPC Base Image

The project can build a Codex NPC base image directly from this repository:

docker build -t codex-npc:local .

docker run --rm codex-npc:local hello --name CodexNPC
docker run --rm --entrypoint sh codex-npc:local -lc \
  'auto-harness hello --name bin && codex --version && cnb --help >/dev/null'

The runtime image is based on docker.cnb.cool/examples/language/golang-1.24, installs Node from the official Node.js binary tarball, then installs @openai/codex and @cnbcool/cnb-cli globally. This avoids depending on Docker Hub node:* pulls and avoids Debian's large npm package dependency tree.

CNB NPC role metadata lives in .cnb/settings.yml. The matching repository-level issue.comment@npc and pull_request.comment@npc events live under $ in .cnb.yml and route recognized NPC mentions to auto-harness npc.

Using Codex NPC In CNB

The repository defines the NPC roles in .cnb/settings.yml:

  • codex: default implementation role for development tasks.
  • codex-review: review-focused role using the same runtime image.

After the latest image is published, mention the repository NPC and role in an Issue or Pull Request comment:

@aiedulab/auto-harness(codex) 请完成这个任务。

For review-focused work, use:

@aiedulab/auto-harness(codex-review) 请 review 这个变更。

The role name inside parentheses must match a role in .cnb/settings.yml. The bare form @codex only mentions a user/NPC named codex; it does not trigger this repository's custom NPC. A correctly recognized mention triggers the issue.comment@npc or pull_request.comment@npc pipeline in .cnb.yml. The pipeline runs:

auto-harness npc

The NPC pipeline sets CODEX_HOME=/workspace/.codex-npc-runtime so runtime auth and generated provider config are isolated from the repository's committed .codex/ template.

The NPC runtime is expected to:

  • generate Codex config for https://token.aiedulab.cn by default, or load a custom template from CODEX_CONFIG_TEMPLATE when explicitly configured;
  • inject runtime auth into .codex/auth.json and Codex process env from CODEX_OPENAI_API_KEY, OPENAI_API_KEY, CNB_TOKEN_FOR_CODEBUDDY, or CNB_TOKEN_FOR_AI;
  • use preinstalled CNB skills from /root/.codex/skills and /root/.agents/skills;
  • use preinstalled Superpowers skills from /root/.codex/skills and /root/.agents/skills;
  • query the current Issue or PR with cnb issues get / cnb pulls get;
  • query comments with cnb issues list-comments or cnb pulls list-comments;
  • for PRs, also query changed files, commits, and CI status before acting;
  • edit code, run verification, git commit, and push when permissions allow;
  • post the final result back with cnb issues comment or cnb pulls comment.

Required runtime credentials:

  • CNB_TOKEN: provided by CNB pipeline runtime, used for CNB API and Git/registry access. It is not used as the Codex model API key.
  • CNB_GIT_TOKEN: optional Git push token override. When present, the NPC entrypoint configures Git HTTPS credentials before starting Codex so nested worktrees and clones can push with the same CNB account. If omitted, it falls back to CNB_TOKEN, which requires CNB NPC work mode to include repo-code:rw.
  • CNB_GIT_USERNAME: optional Git username override; defaults to CNB_TOKEN_USER_NAME or cnb.
  • .codex/auth.json: committed Codex auth file used by the NPC pipeline for https://token.aiedulab.cn.
  • CNB_TOKEN_FOR_AI or CNB_TOKEN_FOR_CODEBUDDY: optional model auth token for the default https://token.aiedulab.cn endpoint.
  • CODEX_OPENAI_API_KEY or OPENAI_API_KEY: optional override for Codex model auth.
  • CODEX_BASE_URL: optional model endpoint override. When omitted, the NPC runtime uses https://token.aiedulab.cn.

Codex CLI currently requires an OpenAI Responses-compatible endpoint (wire_api = "responses"). Configure one of CODEX_API_KEY, CODEX_OPENAI_API_KEY, OPENAI_API_KEY, CNB_TOKEN_FOR_CODEBUDDY, or CNB_TOKEN_FOR_AI with a token accepted by https://token.aiedulab.cn.

Worker Spec

name: codex-worker
description: "Composable Codex worker built by auto-harness"
image: "ghcr.io/agentforge/worker-codex:latest"

server:
  host: "127.0.0.1"
  port: 9100

workspace:
  cwd: "/workspace"

models:
  default: "codex"
  available:
    - id: "codex"
      name: "Codex"

skills:
  - name: "browser-use"
    mount: "/mnt/skills/browser-use"

experts:
  - id: "senior-engineer"
    name: "Senior Engineer"
    prompt: "Focus on implementation quality, tests, and AgentForge conventions."

mounts:
  - source: "/Users/me/project"
    target: "/workspace"
    readOnly: false

env:
  AGENTFORGE_WORKER: "codex-worker"

defaultRunner: "codex"
credentials:
  - id: "cnb-ai-token"
    type: "cnb_api_token"
    source: "managed"
    expose: "never"
    env: "CNB_TOKEN"
    scopes: ["ai:invoke", "repo:read"]
    runnerRefs: ["codex", "doagent"]

runners:
  - id: "codex"
    type: "codex"
    image: "ghcr.io/agentforge/worker-codex:latest"
    mode: "persistent"
    taskTypes: ["code", "review"]
    credentialRefs: ["cnb-ai-token"]
    env:
      CODEX_HOME: "/workspace/.codex"
    command:
      argv:
        - "bash"
        - "-lc"
        - "printf '[codex] %s\n' \"$AUTO_HARNESS_PROMPT\""
      timeoutSeconds: 660
    probe:
      argv:
        - "bash"
        - "-lc"
        - "printf 'codex runner ready\n'"
      timeoutSeconds: 30

  - id: "doagent"
    type: "doagent"
    image: "ghcr.io/agentforge/worker-doagent:latest"
    mode: "ephemeral"
    taskTypes: ["remote", "ops"]
    credentialRefs: ["cnb-ai-token"]
    command:
      argv: ["bash", "-lc", "printf '[doagent] %s\n' \"$AUTO_HARNESS_PROMPT\""]
      timeoutSeconds: 660

command:
  argv:
    - "bash"
    - "-lc"
    - "printf '%s\n' \"$AUTO_HARNESS_PROMPT\""
  timeoutSeconds: 660

schedules:
  - name: "nightly-healthcheck"
    cron: "0 2 * * *"
    command:
      - "bash"
      - "-lc"
      - "go test ./..."

配置块说明

image 是渲染到 Compose 或 Kubernetes manifest 中的 worker 镜像。

skills 声明挂载到 worker 容器中的 skills。当前 MVP renderer 会把每个 skill 映射为 ./skills/<name>:<mount>:ro

experts 保存 worker spec 中的专家智能体元数据。当前 server 还不会把专家 prompt 注入命令;该字段预留给下一步 AgentForge UI 集成层。

mounts 将宿主机路径映射到 worker 容器或 Pod 中。

command.argv 是每次 AgentForge prompt 到来时执行的命令。prompt 会通过 AUTO_HARNESS_PROMPT 传入。

credentials 声明 secret 元数据而不是 secret 值。type: cnb_api_token 用于托管或运行时注入的 CNB API token,必须使用 expose: "never";用户可见 stdout、stderr、结果文件和 ACP response 都会先经过脱敏。

runners 声明可选择的智能体运行时。首期主线是 codexdoagent,CodeBuddy 作为后续可插拔 runner。请求没有显式指定 runner 时使用 defaultRunner。每个 runner 可以覆盖镜像、env、命令、probe 命令、task type 别名、credential 引用、生命周期模式和结果文件收集配置。

workers 是 Coordinator 对外调度的一等执行单元,用于声明 Worker ID、runtime、runnerRef、taskTypes、skills、工作目录、仓库/分支策略、超时、租约、并发、重试、输入/输出 schema、日志/产物存储和回调策略。没有显式 workers 时会从 legacy runners 自动生成兼容 Worker。

gateway 是 Worker fleet 的统一访问层,用于声明是否启用、认证方式、默认超时、重试、健康检查、熔断、聚合缓存和 Worker registry。registry 支持 local in-process Worker 和 http 远程 Worker;每个条目可配置 workerRefurlcredentialRefruntimetaskTypesskillslabelsprojectRefspriority

workflows 声明项目级执行规范,可以是 fileinlinemanaged;Coordinator 创建 Execution Record 时会保存 workflow snapshot,避免后续文件变化影响已启动执行。

coordinator.projects 以项目为管理单元配置平台类型、平台地址、任务来源、认领规则、默认 workflow 和 taskType 到 worker 的路由。首期内置 CNB driver,支持 Issues 和 Pull Requests 的发现、认领 marker comment 和结果 comment 回写。

schedules 声明周期性命令。MVP 会校验并保留这些定义;后续计划增加 scheduler runner。

Kubernetes Pod 渲染

k8s-pod 会从 worker spec 生成一个 Pod manifest:

go run ./cmd/auto-harness k8s-pod \
  -f examples/codex-worker.yaml \
  --namespace agentforge-workers > build/codex-worker/pod.yaml

通过 doops 部署到目标节点时,目标节点需要已经配置好 kubectl 和 Kubernetes 访问权限:

doops -session issue_9_k8s push --target gw-oilan-node --src build/codex-worker
doops -session issue_9_k8s exec --target gw-oilan-node --cmd "kubectl apply -f /root/ws/issue_9_k8s/pod.yaml"

ACP HTTP Contract

server 暴露 AgentForge 期望的 HTTP surface:

  • GET /healthz
  • POST /rpc
  • GET /events?sid=<sessionId>

支持的 JSON-RPC methods:

  • session/new
  • session/listModels
  • chat/sendMessage
  • session/artifacts
  • workspace/open
  • attachment/upload
  • fs/search
  • fs/read_text_file
  • fs/read
  • worker.health
  • worker.capabilities
  • worker.create
  • worker.start
  • worker.status
  • worker.events
  • worker.logs
  • worker.result
  • worker.continue
  • worker.cancel
  • worker.terminate

chat/sendMessage 会返回 accepted SSE delivery,并流式输出 session/update events:

  • agent_message_chunk
  • agent_message
  • turn_finished

session/newchat/sendMessage 接受可选的 runnertaskType 参数。选择顺序为 runner id、runner type、task type、session runner,然后回退到 defaultRunner

worker.* methods 使用 JSON-RPC 2.0 统一响应格式;如设置 AUTO_HARNESS_API_KEY,请求需要携带 Authorization: Bearer <token>,可选 Accept-Version: 2025-05-01

开发

go test ./...
go run ./cmd/auto-harness hello --name CNB
go run ./cmd/auto-harness validate -f examples/codex-worker.yaml
go run ./cmd/auto-harness probe -f examples/codex-worker.yaml --runner codex
go run ./cmd/auto-harness worker capabilities -f examples/codex-worker.yaml
go run ./cmd/auto-harness coordinator scan -f examples/codex-worker.yaml --project auto-harness --store .auto-harness/coordinator.json
go run ./cmd/auto-harness k8s-pod -f examples/codex-worker.yaml --namespace agentforge-workers
go run ./cmd/auto-harness serve -f examples/codex-worker.yaml

Smoke test:

curl -s http://127.0.0.1:9100/healthz

curl -s http://127.0.0.1:9100/rpc \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":"lm","method":"session/listModels","params":{}}'

curl -s http://127.0.0.1:9100/rpc \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":"wh","method":"worker.health","params":{}}'

路线图

  • schedules 增加真正的 scheduler runner。
  • 增加一等公民的镜像 preset。
  • 增加 skill 和 expert catalog。
  • 在 Compose 渲染之外增加容器生命周期管理。
  • 增加一个小型 UI / API 层,用于按配置块组装 worker。
  • 增加 artifact 发现与持久化 hook。
  • 扩展 GitHub、Jira 和自研项目管理平台 driver。

About

Composable Go harness for building AgentForge ACP worker environments