Skip to content

fix: forward per-run agent env (--ae) to the optimizer's harbor run#48

Closed
shehabyasser-scale wants to merge 1 commit into
pr2-add-verofrom
fix/forward-agent-env-to-optimizer
Closed

fix: forward per-run agent env (--ae) to the optimizer's harbor run#48
shehabyasser-scale wants to merge 1 commit into
pr2-add-verofrom
fix/forward-agent-env-to-optimizer

Conversation

@shehabyasser-scale

@shehabyasser-scale shehabyasser-scale commented Jul 24, 2026

Copy link
Copy Markdown
Collaborator

Root cause

When vero runs the optimizer it shells out to uvx ... harbor run to launch the coding agent (codex / mini-swe-agent). There was no supported way to pass environment variables into that optimizer agent's setup/install shell from the build config.

  • run_command in vero/src/vero/harbor/cli.py builds the optimizer's harbor command from a fixed list + -m model + the click extra passthrough (@click.argument("extra", nargs=-1)). It never reads any per-run agent env.
  • config.extra_harbor_args (the only env-adjacent knob) is compiled solely into the evaluation sub-run the sidecar fires: the compiler writes it into serve.json (vero/src/vero/harbor/build/compiler.py), consumed by the sidecar backend (vero/src/vero/harbor/backend.py). That is a different harbor run with a different agent, so args there never reach the optimizer agent's install shell.
  • Downstream harbor is already correct: harbor's --ae/--agent-env flag (cli/trials.py) populates the agent's extra_env, and harbor injects that env into the agent's setup/install exec by wrapping install() in scoped_exec_env(agent.extra_env) (trial/trial.py). So if vero rendered --ae KEY=VALUE onto the optimizer command, it would work; it just never did.

Concrete motivation

There was no way to set e.g. UV_TOOL_BIN_DIR for the optimizer agent's install (needed on non-root sandboxes so uv tool install doesn't try to symlink into root-owned /usr/local/bin). Passing it via extra_harbor_args silently did nothing (wrong sub-run).

Fix

  • Add a dedicated build-config field agent_env: dict[str, str] = {} on HarborBuildConfig (alongside extra_harbor_args), documented as "environment variables injected into the optimizer agent's shell (setup/install and run), rendered as harbor --ae KEY=VALUE".
  • In run_command, after appending -m model and before the extra passthrough, render config.agent_env as repeated --ae KEY=VALUE args, sorted by key for a deterministic command line. config is already in scope in run_command, so no threading was needed.
  • Added a focused unit test in tests/test_v05_harbor_build.py asserting run_command with agent_env={"UV_TOOL_BIN_DIR": "/home/agent/.local/bin"} produces --ae UV_TOOL_BIN_DIR=/home/agent/.local/bin on the harbor command.

extra_harbor_args is intentionally left unchanged to avoid overloading its meaning (it means "eval sub-run args"). This keeps the two concerns cleanly separate.

Base branch note

This targets pr2-add-vero rather than main: the redesigned VeRO harbor code (src/vero/harbor/cli.py, build/config.py, build/compiler.py, backend.py) is introduced by PR #45 (pr2-add-vero) and does not exist on main yet. The bug lives entirely in that code.

Testing

  • New test passes: tests/test_v05_harbor_build.py::test_run_command_forwards_agent_env_as_harbor_ae.
  • Full tests/test_v05_harbor_build.py is green (21 passed, 4 skipped for the harness-engineering-bench gate). Two secret-check tests only fail when OPENAI_API_KEY/OPENAI_BASE_URL are unset; that is pre-existing on the base branch and unrelated to this change.
  • ruff check passes on all three changed files. Env pinned to Python 3.12 (3.14 fails to build litellm/pyo3, see PR fix: cap requires-python <3.14 so uv can't pick a Python that fails to build litellm/pyo3 #47).

🤖 Generated with Claude Code

Greptile Summary

This PR adds a dedicated agent_env: dict[str, str] field to HarborBuildConfig and renders it as repeated --ae KEY=VALUE args on the optimizer's harbor run command, fixing a gap where there was no supported channel to inject environment variables (e.g. UV_TOOL_BIN_DIR) into the optimizer agent's setup/install shell.

  • build/config.py: Adds the agent_env field, clearly documented as distinct from extra_harbor_args (eval sub-run) and task_environment, with a default_factory=dict default so existing configs are unaffected.
  • cli.py: In run_command, iterates config.agent_env sorted by key and extends the harbor command with --ae KEY=VALUE pairs, placed before the extra passthrough so CLI-provided args can override them.
  • test_v05_harbor_build.py: Adds a focused integration-style test monkeypatching subprocess.run and compile_harbor_task to verify the correct --ae args appear in sorted order.

Confidence Score: 5/5

Safe to merge — the change is additive, backward-compatible (default empty dict), and correctly threaded through an already-available config reference in run_command.

The addition is minimal: a new optional field on the config dataclass and a sorted loop in run_command that produces no output when agent_env is empty. Subprocess invocation uses a list (not a shell string), so values with spaces or special characters are passed safely. The test covers both the presence and the sort order of the generated args. No existing behavior is changed.

No files require special attention.

Important Files Changed

Filename Overview
vero/src/vero/harbor/build/config.py Adds agent_env: dict[str, str] field with clear doc comment and default_factory=dict; backward-compatible and well-scoped.
vero/src/vero/harbor/cli.py Renders config.agent_env as --ae KEY=VALUE args in sorted key order before the extra passthrough; placement and logic are correct.
vero/tests/test_v05_harbor_build.py New test uses monkeypatching to verify --ae args appear in the harbor command in sorted key order; assertions are correct for the chosen test values.

Sequence Diagram

sequenceDiagram
    participant User
    participant CLI as vero harbor run (cli.py)
    participant Config as HarborBuildConfig (config.py)
    participant Harbor as harbor run (optimizer agent)
    participant Sidecar as eval sub-run (harbor sidecar)

    User->>CLI: vero harbor run --config build.yaml
    CLI->>Config: load_harbor_build_config()
    Config-->>CLI: config (incl. agent_env, extra_harbor_args)
    CLI->>CLI: build command list
    note over CLI: append -m model
    note over CLI: append --ae KEY=VALUE (from agent_env, sorted)
    note over CLI: append extra passthrough args
    CLI->>Harbor: "subprocess.run([uvx, harbor, run, ..., --ae KEY=VALUE])"
    Harbor->>Harbor: scoped_exec_env(agent.extra_env) on install/setup
    note over Harbor: agent_env vars available here
    Harbor->>Sidecar: launch eval sub-run (from serve.json)
    note over Sidecar: extra_harbor_args flow here (separate channel)
Loading

Reviews (1): Last reviewed commit: "fix: forward per-run agent env (--ae) to..." | Re-trigger Greptile

Add a `agent_env` build-config field and render it as harbor `--ae KEY=VALUE`
on the optimizer's `harbor run`, so env vars reach the optimizer agent's own
setup/install exec.

Root cause: `run_command` in vero/src/vero/harbor/cli.py builds the optimizer's
harbor command from a fixed list + `-m model` + the click `extra` passthrough
and never reads any per-run agent env. `extra_harbor_args` was the only
env-adjacent knob, but it is compiled solely into the eval sub-run
(compiler.py writes it into serve.json, consumed by backend.py), a different
`harbor run` with a different agent, so it never reaches the optimizer agent's
install shell. Harbor's `--ae/--agent-env` flag populates the agent's extra_env,
which harbor injects into the agent's setup/install exec via scoped_exec_env, so
rendering `--ae` here is the supported channel.

Motivation: there was no way to set e.g. UV_TOOL_BIN_DIR for the optimizer
agent's install on a non-root sandbox (so `uv tool install` doesn't try to
symlink into root-owned /usr/local/bin). Passing it via extra_harbor_args
silently did nothing.

`extra_harbor_args` is intentionally left unchanged to avoid overloading its
meaning (eval sub-run args).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
varunursekar added a commit that referenced this pull request Jul 24, 2026
The SimpleNamespace config stubs in test_v05_harbor_http.py predate #48's
agent_env field; run_command now reads config.agent_env, so give the
stubs the same defaulted-empty field the real HarborBuildConfig has.
@varunursekar

Copy link
Copy Markdown
Collaborator

Landed on pr2-add-vero via cherry-pick as f4e2057 (your authorship preserved). Closing since GitHub won't auto-detect the cherry-picked SHA.

One small follow-up from consolidating it into the SSoT branch: two pre-existing run_command tests in test_v05_harbor_http.py build minimal SimpleNamespace config stubs that predate the agent_env field, so they tripped on the new sorted(config.agent_env) loop. Fixed in a separate commit (cc464ce) by giving those stubs the same defaulted-empty agent_env the real HarborBuildConfig has — no change to your code. Full suite green; pr3 rebased on top.

Note it's a no-op for the current benchmark configs (none declare agent_env), so it's latent capability rather than load-bearing yet — but the channel gap it closes is real (extra_harbor_args only reaches the eval sub-run, never the optimizer agent's install exec), so good to have in place for the non-root/Modal-sandbox uv tool install case.

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.

2 participants