Skip to content
Open
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
35d3b2c
Build canonical evaluation and optimization kernel
varunursekar Jul 15, 2026
631f1c2
Add generic optimization runtime and coding-agent gateway
varunursekar Jul 15, 2026
1279b78
Migrate coding agents to canonical runtime
varunursekar Jul 15, 2026
e27988e
Add canonical program optimization CLI
varunursekar Jul 15, 2026
6365e8a
Extract Python task protocol from legacy core
varunursekar Jul 15, 2026
f4da52b
Enforce external Python evaluation boundaries
varunursekar Jul 15, 2026
8cb3fba
Migrate benchmarking to canonical runtime
varunursekar Jul 15, 2026
997ae68
Add Harbor evaluation backend
varunursekar Jul 15, 2026
44e8192
Add canonical Harbor sidecar and verifier
varunursekar Jul 15, 2026
73d983d
Expose Harbor sidecar HTTP and CLI surfaces
varunursekar Jul 15, 2026
818e3cc
Compile canonical Harbor optimization tasks
varunursekar Jul 15, 2026
50f95e4
Exclude generated Harbor compiler caches
varunursekar Jul 15, 2026
95cd51d
Refresh benchmarking lock for Harbor extra
varunursekar Jul 15, 2026
bfaea83
Remove paper-era implementation from v0.5
varunursekar Jul 15, 2026
f38dfba
Harden generic program optimization workflow
varunursekar Jul 15, 2026
b0ae83d
Resolve concurrency and persistence review findings
varunursekar Jul 15, 2026
68f58a6
Support isolated sandbox execution
varunursekar Jul 15, 2026
34982ce
Separate candidate and evaluation limits
varunursekar Jul 15, 2026
5dd4f26
Harden evaluation persistence and process cleanup
varunursekar Jul 15, 2026
9c95d96
Support nested Harbor evaluation on Modal
varunursekar Jul 15, 2026
4b3f2c7
Document nested Modal Harbor workflow
varunursekar Jul 15, 2026
2f48d80
Add durable candidate repositories
varunursekar Jul 16, 2026
e5b96d3
Restore evaluation retries and reject ignored controls
varunursekar Jul 16, 2026
b61e7a1
Expose authorized context to optimization agents
varunursekar Jul 16, 2026
fed6a51
Harden agent and Harbor end-to-end execution
varunursekar Jul 16, 2026
e9b45f6
Implement multi-evaluation optimization protocol
varunursekar Jul 17, 2026
3db69df
Restore failed-case evaluation semantics
varunursekar Jul 17, 2026
aa7744a
Pass Harbor objectives to coding agents
varunursekar Jul 17, 2026
5255f5d
Add circle packing optimization benchmark
varunursekar Jul 17, 2026
272c772
Add self-contained experiment reports
varunursekar Jul 17, 2026
aef04eb
Add Harbor-native GAIA optimization benchmark
varunursekar Jul 17, 2026
55609a0
Rename benchmark suite to program-opt-bench
varunursekar Jul 17, 2026
5df8360
Add durable Harbor optimization workflows
varunursekar Jul 17, 2026
1e3d93c
Drain in-flight evaluations before Harbor finalization
varunursekar Jul 17, 2026
e467616
Add durable Harbor evaluation jobs
varunursekar Jul 17, 2026
df700a7
Allow GPT-5.5 for GAIA optimization
varunursekar Jul 17, 2026
3a3031d
harbor: lock the admin token to the trusted verifier (0o400 file, 0o7…
varunursekar Jul 17, 2026
9533e99
harbor: offload verifier finalize's atomic write to a thread
varunursekar Jul 17, 2026
96ffbb4
harbor: ${...} run-time parameters in build YAML (no rebuild to vary …
varunursekar Jul 18, 2026
4918ea3
harbor: document the soft fixed-target guarantee at the gateway allow…
varunursekar Jul 18, 2026
bb9930a
native: remove token-limit hook; bump openai-agents 0.13.6 -> 0.18.3
varunursekar Jul 18, 2026
87c3ccb
native: rebuild VeroAgent on SandboxAgent; drop run_agent_with_json_s…
varunursekar Jul 18, 2026
5e149f7
native: delete replaced tools + filesystem ACL; strip ClaudeCodeAgent…
varunursekar Jul 18, 2026
98d7303
native: drive VeroAgent via the OpenAI Responses API (SandboxAgent ne…
varunursekar Jul 18, 2026
616e8db
native: single model-agnostic path — function tools over a sandbox se…
varunursekar Jul 18, 2026
219a5fb
optimization: GenerationBackend seam over candidate production
varunursekar Jul 18, 2026
5bd572f
optimization: EvolutionaryStrategy (population-based, N offspring/round)
varunursekar Jul 18, 2026
0a4a95c
runtime: stream agent activity to the event bus (observability)
varunursekar Jul 18, 2026
e78f8b8
cleanup: remove vestigial classes/functions orphaned by the refactor
varunursekar Jul 18, 2026
975caa8
chore: gitignore harbor jobs/ output directory
varunursekar Jul 18, 2026
837c855
chore: move matmul-{kernel,eval} examples to vero-tasks
varunursekar Jul 18, 2026
1a642e3
examples: add a Harbor outer-loop / simple inner-loop example
varunursekar Jul 18, 2026
41e0eb7
docs: rewrite the agent setup guide for the current architecture
varunursekar Jul 18, 2026
473d5b8
docs: refresh README for the modernized native runner
varunursekar Jul 18, 2026
629063c
docs: frame VeRO as optimizing programs, text, AND agents
varunursekar Jul 18, 2026
69ece41
docs: add badges, mermaid figures, highlights, and a callout to the R…
varunursekar Jul 18, 2026
36c190e
docs: stop advertising `pip install scale-vero` (squatted PyPI name)
varunursekar Jul 18, 2026
7719ec0
chore: add gitignored runs/ dir for local GAIA/harbor run outputs
varunursekar Jul 18, 2026
12a99b9
Add Claude optimizer support + injectable insights bundle to Harbor
varunursekar Jul 19, 2026
fe92b38
README: lead with Harbor and break up the text walls
varunursekar Jul 19, 2026
88cc42f
README: break up the remaining text walls
varunursekar Jul 19, 2026
0932d2d
Unblock tau3 (and other env-declaring tasks) via non-interactive sub-…
varunursekar Jul 19, 2026
6968e7a
Add DarwinGodelStrategy: open-ended archive evolution
varunursekar Jul 19, 2026
282f5c8
tau3: collapse to a single host-side agent; delete runner.py + cred f…
varunursekar Jul 19, 2026
8bd5655
harbor: add disclose_budget toggle for budget-blind optimization
varunursekar Jul 19, 2026
3c106b1
harbor: route task-owned eval LLM services to upstream (fix tau3 user…
varunursekar Jul 19, 2026
f53ce9b
harbor: give the trusted eval-sidecar the upstream for task_services_…
varunursekar Jul 19, 2026
2cdd60e
program-opt-bench: add ALE-Bench (program optimization) task
varunursekar Jul 19, 2026
d285d63
program-opt-bench: add OfficeQA (grounded-reasoning agent benchmark)
varunursekar Jul 19, 2026
2ff7e95
Reserve a finalization inference budget so re-scoring cannot be starved
varunursekar Jul 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Python-generated files
__pycache__/
.pytest_cache/
*.py[oc]
build/
dist/
Expand Down
130 changes: 40 additions & 90 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,122 +1,72 @@
# VeRO: Versioning Rewards and Observations
# VeRO: a harness for agents to optimize programs

[![Paper](https://img.shields.io/badge/arXiv-2602.22480-b31b1b.svg)](https://arxiv.org/abs/2602.22480)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

VeRO is an evaluation harness for using coding agents to optimize LLM-based agents and workflows. It treats agent code as a versioned artifact — making changes, evaluating results, and hill-climbing toward better performance using git version control.
VeRO gives a coding agent a program to edit, an evaluation boundary, and durable
memory of every candidate it tried. The target can be an agent, a prompt, a
compiler pass, a CUDA kernel, a matrix multiplication function, or any other
Git-versioned program.

> **Paper**: [VeRO: An Evaluation Harness for Agents to Optimize Agents](https://arxiv.org/abs/2602.22480)

## Repository Structure

```
vero/
├── vero/ # Core library (scale-vero)
├── vero-agents/ # Agent implementations (benchmarking targets)
├── vero-benchmarking/ # Benchmarking scripts and analysis
└── LICENSE
```

### [vero/](vero/)

The core optimization framework. Provides:

- **Policy** — orchestrates the optimization loop (agent + evaluator + git)
- **Agents** — VeroAgent (OpenAI Agents SDK) and ClaudeCodeAgent (Claude Agent SDK)
- **Evaluator** — runs task evaluations in isolated subprocess environments
- **Tools** — MCP-based tools for agents (bash, file I/O, experiment runner, dataset viewer, etc.)
- **Traces** — session analysis and LLM-based trace interpretation

```bash
cd vero && uv sync --extra optimize
```text
strategy -> candidate producers -> evaluation backends -> selection
| |
isolated workspaces versioned reports
```

See [vero/README.md](vero/README.md) for full documentation.

### [vero-agents/](vero-agents/)
The target and evaluator do not need to be Python. External evaluators and
candidate producers connect through command protocols; Python benchmarks can
use the optional, optimizer-independent `scale-vero-tasks` package.

Agent implementations used as optimization targets:
Targets may live locally or in an isolated sandbox. VeRO keeps optimization
state and experiment tracking on the host while running Git worktrees, producer
commands, builds, and evaluation commands in the target sandbox. The core guide
includes a no-bind-mount `DockerSandbox` example.

| Agent | Description |
|-------|-------------|
| **generic-agent** | General-purpose agent for MATH, GPQA, GAIA, GSM8K, etc. |
| **web_search_agent** | Web search agent for SimpleQA, Facts Search |
| **KIRA** | Terminal task agent for Terminal Bench 2.0 |
| **tau-bench** | Customer service tool-use agent |
| **pharma_summarizer** | Document summarization agent |
## Repository layout

See [vero-agents/README.md](vero-agents/README.md) for details.
| Directory | Purpose |
| --- | --- |
| [`vero/`](vero/) | The `scale-vero` optimization kernel, runtime, CLI, and coding-agent adapters |
| [`vero-tasks/`](vero-tasks/) | Narrow Python task types and schema-v1 evaluation runner |
| [`vero-agents/`](vero-agents/) | Benchmark target programs; not part of the optimizer runtime |
| [`vero-benchmarking/`](vero-benchmarking/) | Reproducible experiment configurations and drivers |

### [vero-benchmarking/](vero-benchmarking/)

Scripts and infrastructure for running optimization experiments:
Start with the [generic C matrix-multiplication quickstart](vero/examples/c-matmul/)
or the [core guide](vero/README.md). The C target has no Python or VeRO
dependency; it is compiled, checked, benchmarked, and optimized through the
language-neutral command protocol.

```bash
cd vero-benchmarking && uv sync --all-extras

# Run an optimization experiment
uv run python scripts/run_benchmark.py --scaffold claude-code-vmf --model sonnet --task math

# Build datasets
./scripts/build_datasets.sh
cd vero
uv sync --all-extras
uv run vero --help
```

See [vero-benchmarking/README.md](vero-benchmarking/README.md) for full documentation.

## Quick Start

### Prerequisites
## Paper reproduction

- Python 3.11+
- [uv](https://docs.astral.sh/uv/getting-started/installation/)
- Git
- Access to an LLM provider (via LiteLLM, OpenAI, Anthropic, etc.)
VeRO was introduced in [*VeRO: A Harness for Agents to Optimize
Agents*](https://arxiv.org/abs/2602.22480), accepted at ICML 2026. The current
library generalizes that version/evaluate/select loop from agents to programs.

### Install
The exact paper implementation is frozen separately from the v0.5 redesign:

```bash
git clone <repo-url> && cd vero

# Install core library
cd vero && uv sync --extra optimize

# Install benchmarking tools
cd ../vero-benchmarking && uv sync --all-extras
git checkout paper-v1
```

### Run Your First Optimization

```python
from agents import Agent as OAIAgent
from vero.policy import Policy
from vero.agents.vero import VeroAgent

policy = Policy(
project_path="/path/to/my-agent",
dataset="/path/to/my-dataset",
agent=VeroAgent(
oai_agent=OAIAgent(name="VeroAgent", model="anthropic/claude-sonnet-4-5-20250929"),
),
task="main",
train_budget=10,
max_turns=200,
)

best = await policy.run()
print(f"Best commit: {best.commit}, score: {best.score}")
```
Use the `paper/v1` branch or `paper-v1` tag for reproduction. Development of
the generic program optimizer continues on the `v0.5` branch.

## Citation

```bibtex
@article{ursekar2026vero,
title={VeRO: An Evaluation Harness for Agents to Optimize Agents},
title={VeRO: A Harness for Agents to Optimize Agents},
author={Ursekar, Varun and Shanker, Apaar and Chatrath, Veronica and Xue, Yuan (Emily) and Denton, Sam},
journal={arXiv preprint arXiv:2602.22480},
year={2026}
}
```

## License

[MIT](LICENSE)
VeRO is licensed under the [MIT License](LICENSE).
30 changes: 19 additions & 11 deletions vero-agents/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
# Vero Agents
# VeRO benchmark targets

A collection of Python-based agent implementations optimizable with [VeRO](../vero/). Each agent is a self-contained `uv` package with its own dependencies and evaluation tasks.
This directory is VeRO's benchmark corpus: Python programs used as optimization
targets in the paper and in end-to-end tests. Agents are one important kind of
target program, but they are not part of the optimizer runtime.

Each target is a self-contained uv project. It depends on the narrow
[`scale-vero-tasks`](../vero-tasks/) protocol for Python evaluation ergonomics,
not on `scale-vero` itself.

## Agents

Expand All @@ -25,24 +31,26 @@ vero-agents/
└── pyproject.toml
```

Each agent contains:
- `pyproject.toml` with dependencies and a dev dependency on `scale-vero`
Each target contains:

- `pyproject.toml` with its own runtime dependencies and `scale-vero-tasks`
- Source code under `src/<agent_name>/` or `<agent_name>/`
- A `vero_tasks/` module defining evaluation tasks for VeRO
- A `vero_tasks/` module defining inference and scoring functions

## Adding a New Agent
## Adding a new target

1. Create a directory under `agents/`
2. Initialize a `uv` package with `pyproject.toml`
3. Add `scale-vero` as a dev dependency:
3. Add the task protocol:

```toml
[dependency-groups]
dev = ["scale-vero[evaluate]"]
[project]
dependencies = ["scale-vero-tasks>=0.1.0"]

[tool.uv.sources]
scale-vero = { path = "../../../vero", editable = true }
scale-vero-tasks = { path = "../../../vero-tasks", editable = true }
```
4. Create a `vero_tasks/` module with inference and evaluation functions (see `vero init tasks`)
4. Create a `vero_tasks/` module with inference and evaluation functions
5. Register the task in `vero-benchmarking/src/vero_benchmarking/tasks/`

## Running Evaluations
Expand Down
8 changes: 2 additions & 6 deletions vero-agents/agents/KIRA/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,9 @@ dependencies = [
"datasets",
"harbor",
"litellm",
"scale-vero-tasks>=0.1.0",
"tenacity",
]

[dependency-groups]
dev = [
"scale-vero[evaluate]",
]

[tool.uv.sources]
scale-vero = { path = "../../../vero", editable = true }
scale-vero-tasks = { path = "../../../vero-tasks", editable = true }
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@
from __future__ import annotations

from harbor import Job
from vero.core.db.result import TaskResult
from vero.core.evaluation import EvaluationParameters
from vero.core.task import create_task
from vero_tasks import TaskContext, TaskResult, create_task

from terminus_kira.vero_tasks.utils import (
TerminalBenchTask,
Expand All @@ -25,7 +23,7 @@


@terminal_bench_2("run_inference")
async def run_inference(task: TerminalBenchTask, evaluation_parameters: EvaluationParameters):
async def run_inference(task: TerminalBenchTask, evaluation_parameters: TaskContext):
"""No-op — Harbor handles inference and evaluation together."""
return None

Expand All @@ -34,7 +32,7 @@ async def run_inference(task: TerminalBenchTask, evaluation_parameters: Evaluati
async def run_evaluation(
tasks: list[TerminalBenchTask],
outputs: list[None],
evaluation_parameters: EvaluationParameters,
evaluation_parameters: TaskContext,
) -> list[TaskResult]:
"""Run a Harbor Job for a batch of Terminal-Bench tasks.

Expand Down
5 changes: 2 additions & 3 deletions vero-agents/agents/KIRA/terminus_kira/vero_tasks/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@
from harbor.models.trial.config import AgentConfig, EnvironmentConfig
from harbor.models.trial.result import TrialResult
from pydantic import Field
from vero.core.db.result import TaskResult
from vero.core.evaluation import EvaluationParameters, TaskParameters
from vero_tasks import TaskContext, TaskParameters, TaskResult


def load_trial_results(job_dir: Path) -> list[TrialResult]:
Expand Down Expand Up @@ -65,7 +64,7 @@ class KiraParameters(TaskParameters):

def build_job_config(
tasks: list[TerminalBenchTask],
evaluation_parameters: EvaluationParameters,
evaluation_parameters: TaskContext,
) -> JobConfig:
"""Build a Harbor JobConfig from vero evaluation parameters.

Expand Down
4 changes: 2 additions & 2 deletions vero-agents/agents/generic-agent/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ authors = [
requires-python = ">=3.11"
dependencies = [
"openai-agents[litellm]>=0.10",
"scale-vero-tasks>=0.1.0",
"sympy>=1.14.0",
"tree-sitter>=0.25.2",
]
Expand All @@ -25,8 +26,7 @@ dev = [
"pytest>=9.0.2",
"pytest-asyncio>=1.3.0",
"pytest-json-report>=1.5.0",
"scale-vero[evaluate]",
]

[tool.uv.sources]
scale-vero = { path = "../../../vero", editable = true }
scale-vero-tasks = { path = "../../../vero-tasks", editable = true }
10 changes: 0 additions & 10 deletions vero-agents/agents/generic-agent/src/generic_agent/prompts.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,30 @@
from collections.abc import Callable
from typing import Any

from vero.core.resource import resource

PromptFormatter = Callable[..., str]


@resource(namespace="gsm8k", name="prompt")
def get_gsm8k_prompt(question: str, **kwargs: Any) -> str:
"""Format prompt for GSM8K benchmark."""
GSM8K_DEFAULT_PROMPT = """{question}
Generate an answer to this question. At the end, provide the final answer in the format "Answer is <number>", where <number> is a single number."""
return GSM8K_DEFAULT_PROMPT.format(question=question)


@resource(namespace="math", name="prompt")
def get_math_prompt(question: str, **kwargs: Any) -> str:
"""Format prompt for MATH benchmark."""
MATH_DEFAULT_PROMPT = """{question}
Please generate a solution for the problem. At the end, provide the final answer in the format "\\boxed{{<number>}}", where <number> is a math answer(an expression or number), without any additional information or explanation."""
return MATH_DEFAULT_PROMPT.format(question=question)


@resource(namespace="hotpotqa", name="prompt")
def get_hotpotqa_prompt(question: str, context: str, **kwargs: Any) -> str:
"""Format prompt for HotpotQA benchmark."""
HOTPOTQA_DEFAULT_PROMPT = "Context: {context}\n\nQuestion: {question}\n\nAnswer:"
return HOTPOTQA_DEFAULT_PROMPT.format(question=question, context=context)


@resource(namespace="drop", name="prompt")
def get_drop_prompt(question: str, passage: str, **kwargs: Any) -> str:
"""Format prompt for DROP benchmark."""
DROP_DEFAULT_PROMPT = """Given a question and a passage, please answer the question.
Expand All @@ -40,22 +35,19 @@ def get_drop_prompt(question: str, passage: str, **kwargs: Any) -> str:
return DROP_DEFAULT_PROMPT.format(question=question, passage=passage)


@resource(namespace="humaneval", name="prompt")
def get_humaneval_prompt(question: str, **kwargs: Any) -> str:
"""Format prompt for HumanEval benchmark."""
HUMANEVAL_DEFAULT_PROMPT = """{question}
Generate an answer to this question, without any additional test cases."""
return HUMANEVAL_DEFAULT_PROMPT.format(question=question)


@resource(namespace="mbpp", name="prompt")
def get_mbpp_prompt(question: str, test_list: str, **kwargs: Any) -> str:
"""Format prompt for MBPP benchmark."""
MBPP_DEFAULT_PROMPT = """You are an expert Python programmer, and here is your task: {question} Your code should pass these tests:\n\n{test_list}\n"""
return MBPP_DEFAULT_PROMPT.format(question=question, test_list=test_list)


@resource(namespace="gpqa", name="prompt")
def get_gpqa_prompt(question: str, options: str, **kwargs: Any) -> str:
"""Format prompt for GPQA benchmark."""
GPQA_TEMPLATE = """Answer the following multiple choice question. The last line of your response should be of the following format: ‘Answer: $LETTER’ (without quotes) where LETTER is one of ABCD. Think step by step before answering.
Expand All @@ -72,7 +64,6 @@ def get_gpqa_prompt(question: str, options: str, **kwargs: Any) -> str:
return GPQA_TEMPLATE.format(**kwargs)


@resource(namespace="gaia", name="prompt")
def get_gaia_prompt(question: str, file_path: str | None = None, **kwargs: Any) -> str:
"""
Format prompt for GAIA benchmark.
Expand All @@ -94,7 +85,6 @@ def get_gaia_prompt(question: str, file_path: str | None = None, **kwargs: Any)
return prompt


@resource(namespace="default", name="prompt")
def get_default_prompt(**kwargs: Any) -> str:
"""
Default formatting function.
Expand Down
Loading