Skip to content

feat: configurable agent harness CLI (claude default + custom template)#5

Merged
vaderyang merged 1 commit into
mainfrom
feat/configurable-harness
Jun 8, 2026
Merged

feat: configurable agent harness CLI (claude default + custom template)#5
vaderyang merged 1 commit into
mainfrom
feat/configurable-harness

Conversation

@vaderyang

Copy link
Copy Markdown
Contributor

What

Part A of "make the agent CLI configurable + qualify candidates". The 4 agent surfaces hardcoded claude (each with its own copy of the gateway-wait/retry loop). Centralised into scripts/lib/agent-harness.sh's agent_run, so the CLI is a .agent-ops.json choice:

"harness": { "kind": "custom", "command": "codex exec --model {model} < {prompt_file} > {out}", "model": "gpt-5", "health_probe": false }
  • agent_run --profile {investigate|implement|review} owns the gateway pre-flight wait + retry-on-gateway-down loop; --stream tees, --out redirects, review extras pass through. AGENT_HARNESS_DRYRUN=1 prints the built command.
  • config.sh loads .harness.{kind,command,model,health_probe} (fixes a jq // empty gotcha so health_probe:false is honored).
  • The 4 sites call agent_run, deleting their inline claude + retry blocks; run_review now also loads .agent-ops.json.
  • schema + config-reference + cookbook ("Swapping the agent CLI" + codex example + the prompt-shape known constraint) + example.
  • test_harness.py (dry-run) locks claude back-compat command construction per profile + custom substitution; wired into ci.

Back-compat (non-negotiable)

No harness block ⇒ identical claude invocations. heron + every existing consumer unaffected. test_harness.py asserts this.

Next

Part B (evals/ qualification bench) lands separately and reuses this adapter to benchmark candidate CLIs (codex → pi agent → kilo cli …) before integration.

🤖 Generated with Claude Code

The 4 agent surfaces hardcoded `claude` (+ a copy-pasted gateway-wait/retry loop
each). Centralise that into scripts/lib/agent-harness.sh's agent_run, so the CLI
is a .agent-ops.json choice:

  harness.kind = claude  (built-in default — byte-compatible with the old calls)
               | custom  (run harness.command, a template with {model}/{prompt_file}/
                          {out}/{tools}/{write}/{max_turns} placeholders → any CLI)

- agent_run --profile {investigate|implement|review} owns the gateway pre-flight
  wait + retry-on-gateway-down loop (guarded by harness.health_probe); --stream
  tees, --out redirects, review extras pass through. AGENT_HARNESS_DRYRUN=1 prints
  the built command (used by the test).
- config.sh loads .harness.{kind,command,model,health_probe}; .harness.model wins
  over .model. (Fixes a jq `// empty` gotcha so health_probe:false is honored.)
- run_triage / run_wiwi / run_revise / run_review now call agent_run, deleting
  their inline claude + retry blocks. run_review also loads .agent-ops.json now.
- schema + config-reference + cookbook ("Swapping the agent CLI" + codex example +
  the prompt-shape KNOWN CONSTRAINT) + example config.
- test_harness.py (stdlib, dry-run) locks claude back-compat command construction
  per profile + custom template substitution; wired into ci.yml.

Back-compat: no harness block ⇒ identical claude invocations; heron + existing
consumers unaffected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vaderyang
vaderyang merged commit a60865d into main Jun 8, 2026
2 checks passed
@vaderyang
vaderyang deleted the feat/configurable-harness branch June 8, 2026 03:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant