This is a template framework for creating and evaluating AI agent tasks. It provides a structured approach to:
- Define coding tasks with clear specifications
- Grade agent solutions automatically using test-based validation
- Manage multiple task difficulties (easy, medium, hard)
- Run tasks in isolated environments with proper grading
.
├── src/hud_controller/ # Main framework code
│ ├── env.py # HUD v6 environment (ssh + two-yield template)
│ ├── app.py # validate_problem CLI for imagectl3 -v
│ ├── prompts.py # Problem prompt helpers
│ ├── spec.py # Core specifications (Problem, Grade)
│ ├── grading_runner.py # Test execution and grading logic
│ ├── utils.py # Utility functions
│ ├── setup.py # Environment setup
│ ├── problems/ # Task definitions by difficulty
│ │ ├── basic.py # Easy difficulty tasks
├── run_eval.py # Local Docker eval driver (HUD v6)
├── tasks.py # Generated task rows (imagectl3 -j)
├── pyproject.toml # Python package configuration
├── Dockerfile # Container setup
└── README.md # This file
Problems are defined using the ProblemSpec data class with these key fields:
ProblemSpec(
id="simple_counter", # the unique ID of the problem
description="""Please implement a simple synchronous counter that with reset, enable, and load functionality.
Inputs:
clk - Clock signal (triggers on rising edge)
rst - Synchronous reset signal
ena - Enable signal (allows counting)
set - Load signal (sets counter to a specific value)
din - 8-bit data input (value to load when set is high)
Output:
counter - 8-bit counter value
""", # What you want the agent to do
difficulty="easy", # how difficult the problem is
# the branch names
base="simple_counter_baseline",
test="simple_counter_test",
golden="simple_counter_golden",
test_files=["tests/test_simple_counter_hidden.py"]
)Tasks are graded by:
- Copying the repository (including whatever changes the agent made) to a clean workspace
- Applying the agent's solution patch
- Applying a test patch on top of what the agent did (adds tests that would fail in an unmodified repo)
- Running
pytest <test files>to test the build
You need three branches in your target repository (the one that we clone in the dockerfile):
- baseline - Starting state with the bug/missing feature
- test - Adds tests that should fail on baseline, and pass in golden branch
- golden - Contains the correct solution (for reference). Notably, this should not contain the tests.
We currently only have src/hud_controller/problems/basic.py, but feel free to make more files in the subdirectory. Once you do that, you can add a problem to the registry as follows:
PROBLEM_REGISTRY.append(
ProblemSpec(
id="simple_counter",
description="""Please implement a simple synchronous counter that with reset, enable, and load functionality.
Inputs:
clk - Clock signal (triggers on rising edge)
rst - Synchronous reset signal
ena - Enable signal (allows counting)
set - Load signal (sets counter to a specific value)
din - 8-bit data input (value to load when set is high)
Output:
counter - 8-bit counter value
""",
difficulty="easy",
base="simple_counter_baseline",
test="simple_counter_test",
golden="simple_counter_golden",
test_files=["tests/test_simple_counter_hidden.py"],
)
)The base, test, and golden branches must correspond to the branches you created in the first step.
It's important to ensure that your problems pass a basic sanity check:
- All tests at the baseline branch should pass
- When we apply the hidden test set, the hidden tests should fail
- When we apply the golden patch and then apply the hidden test set, all tests should pass
To help you with this, we have a script called utils/imagectl3.py.
To run and build the images you can do:
uv run utils/imagectl3.py --build --validateYou can specify the exact image you want to test with the --ids flag.
You can also make this easier to type by using the shorform -b flag for --build and the shortform -v flag for --validate.
uv run utils/imagectl3.py -bv --ids simple_counterNote: ensure your image is built before you try to validate it.
uv syncuv run utils/imagectl3.py verilog_ -bvjThis builds Docker images with prefix verilog_, validates patch logic, and writes tasks.py.
For many problems, use parallel jobs:
uv run utils/imagectl3.py verilog_ -bvj --jobs 4Each problem runs in its own Docker image via run_eval.py:
uv run python run_eval.py --ids simple_counter --agent claude \
--model claude-sonnet-4-5 --max-steps 150 --group-size 10Use --full to run all tasks in tasks.py with max-steps 100.
uv run utils/imagectl3.py govindhud/verilog_ -bvjp --jobs 4Hosted HUD v6 eval (hud deploy + hud sync tasks) is not wired up in this template yet.
The framework clones a target Verilog repository that contains the problems to be solved. This is configured in two places:
-
Dockerfile (line ~109): Specifies which repo to clone
RUN git clone https://github.com/hud-evals/example-verilog-codebase /home/ubuntu/example-codebase -
grading_runner.py (line 46): Path where the cloned repo lives
self.original_repo_path = "/home/ubuntu/example-codebase"
Important: When making changes to the remote repository, ALWAYS increment the random variable in the Dockerfile (line ~108) to force Docker to re-clone:
ENV random=random6 # Increment this number!Key environment variables:
PROBLEM_ID- The specific problem baked into each Docker imageHINTS- Hint level for the problem (noneorall)
The included Dockerfile sets up the complete environment:
- Base system with required tools
- Verilog toolchain (iverilog, verilator)
- Python test framework (pytest, cocotb)
- VNC for GUI testing (if needed)
- Clear Descriptions: Provide detailed, unambiguous task descriptions
- Focused Scope: Each task should test one concept or skill
- Realistic Scenarios: Base tasks on real-world debugging/development scenarios
- Fair Hints: If providing hints, ensure they guide without giving away the solution
- Comprehensive Coverage: Tests should fully validate the requirement
- Clear Failures: Test failures should clearly indicate what's wrong
- Minimal Changes: Test patches should only add tests, not modify existing code
- Isolation: Tests should not depend on external state
- Clean Baseline: Baseline should be stable and buildable
- Minimal Test Patch: Only add tests that verify the specific requirement
- Correct Golden: Golden solution should be minimal and idiomatic