ProgramBench

repository·main·Indexed 21 days ago

https://github.com/facebookresearch/programbench

A benchmark for evaluating whether Language Model-based SWE-agents can rebuild complete programs from scratch using only a compiled binary and its documentation. It includes a CLI for performing inference via Docker, evaluating agent runs, managing test blobs from HuggingFace, and packaging submissions for a leaderboard.

Tokens
6.5K
Snippets
21
Records
27
Agent score
74%

What's inside ProgramBench

  1. Perform inference for ProgramBench tasks

    main

    Inference should be performed using Docker images with the task_cleanroom_v6 tag from the ProgramBench DockerHub repository.

    Important Requirements:

    • Architecture: Images are built for linux/amd64 (x86_64) only. They will not run natively on macOS or Windows; use a Linux x86_64 machine.
    • Network: The agent MUST NOT have access to the internet during inference.

    Task Image Naming Convention: To solve a task like ffmpeg__ffmpeg.360a402, the corresponding image name replaces the double underscore __ with _1776_. Example: ffmpeg_1776_ffmpeg.360a402:task_cleanroom_v6.

  2. Prepare agent submissions for evaluation

    main

    To evaluate an agent's run, the agent's produced codebase must be extracted into a .tar.gz archive and organized into a specific directory structure. Each task directory should be named using the pattern author__task_id (e.g., abishekvashok__cmatrix.5c082c6), containing a submission.tar.gz file.

    Required Directory Structure:

    my-amazing-agent-run
    ├── abishekvashok__cmatrix.5c082c6
    │   └── submission.tar.gz
    ├── agourlay__zip-password-finder.704700d
    │   └── submission.tar.gz
    └── ...
  3. Install or run ProgramBench

    main

    You can use ProgramBench without a permanent installation using uvx, or install it directly into your project or environment using pip or uv pip.

    For development, clone the repository and use uv sync to install editable and development dependencies.

    # Run without installing
    uvx programbench --help
    
    # Or install into a project
    uv pip install programbench
    
    # Or with pip
    pip install programbench
    
    # For development
    git clone https://github.com/facebookresearch/programbench.git
    cd programbench
    uv sync
  4. Use the programbench CLI

    main

    ProgramBench provides a command-line interface for evaluating LM-based SWE-agents. The main entrypoint is the programbench command, which includes subcommands for evaluation (eval), information retrieval (info), and specialized tasks via blob and submit subcommands.

    To see all available commands and help, run:

    programbench --help
  5. How to include extra statistics in a submission

    main

    The ProgramBench leaderboard supports optional statistics (e.g., cost or model calls). These cannot be entered manually; they must be recoverable from the run.

    To include extra stats:

    1. Write a script that reads each traj.json file from your trajectories.
    2. The script must emit a flat JSON map in the format {instance_id: value}.
    3. Save this output to _stats/<name>.json.
    4. Include the script in your submission (e.g., under _scripts/) to ensure reproducibility.
  6. Verify a ProgramBench submission

    main

    Auditors can verify a submission using the programbench submit verify command. There are two tiers of verification:

    • Tier-0: Recomputes the score from the local eval.json and checks it against submission.yaml. This is an instant, offline check.
    • Tier-1: Downloads the submission.tar.gz files from HuggingFace, re-runs the full evaluation, and confirms the score is reproduced from scratch. This requires Docker.

    Note: Only the score is independently verifiable via Tier-1; extra stats (like cost/calls) are considered self-reported from trajectories.

    git clone <your-submission-repo>
    cd {{ submission_id }}
    uvx programbench submit verify .          # Tier-0: recompute the score from this repo's eval.json and check it matches submission.yaml (instant, offline)
    uvx programbench submit verify . --tier1  # Tier-1: download each submission.tar.gz from HuggingFace, re-run evaluation, and confirm it reproduces the score (Docker)
  7. Reproduce a ProgramBench submission

    main

    To reproduce a ProgramBench submission, follow these steps in order. Note that per the evaluation protocol, inference must be run without internet access.

    1. Install the agent and necessary dependencies.
    2. Run inference for each task.
    3. Run the evaluation command: programbench eval <run-dir>.
    4. Submit the package: programbench submit package <run-dir> --upload-to <org>.
    # 1. install the agent / dependencies
    # 2. run inference per task (no internet, per the eval protocol)
    # 3. programbench eval <run-dir>
    # 4. programbench submit package <run-dir> --upload-to <org>
  8. Submission checklist for ProgramBench

    main

    Before submitting to the ProgramBench leaderboard, ensure you have completed the following:

    • Ran programbench eval followed by programbench submit package.
    • Filled in all submission.yaml fields (including is_os_model and is_os_scaffold).
    • Included traj.json trajectories for every task (required for agent submissions).
    • Provided solutions via an inline submission.tar.gz or a hosted submission.tar.gz.url + .sha256.
    • Generated extra stats (if any) using a trajectory-reading script.
    • Completed the System overview and Reproducing sections in the README.
    • Verified the submission with programbench submit verify ..
    • Made the fork public and opened a registration PR to the submissions repository.

    Integrity Requirements:

    • Solutions must be produced only from behavioral observation of the binary and its bundled docs (no source code, repositories, mirrors, or package registries).
    • The model must not have internet access or access to unit tests during evaluation.
  9. Run the mini-swe-agent baseline

    main

    To run the mini-swe-agent baseline for ProgramBench, you can use uvx to run the tool directly or install mini-swe-agent via pip and then use the mini-extra command. Refer to the mini-swe-agent baseline docs for specific implementation details.

    # Using uvx
    uvx --from mini-swe-agent mini-extra programbench --help
    
    # Using pip
    pip install mini-swe-agent && mini-extra programbench --help
  10. Configure ProgramBench Docker environment variables

    main

    ProgramBench uses several environment variables to configure its Docker execution environment. You can override the default settings by setting these variables in your shell or environment before running ProgramBench.

    Environment VariableDefault ValueDescription
    PROGRAMBENCH_DOCKER_EXECUTABLEdockerThe path to the Docker executable
    PROGRAMBENCH_DOCKER_CPUS10Number of CPUs allocated to Docker
    PROGRAMBENCH_DOCKER_RUN_TIMEOUT300Timeout in seconds for Docker run operations
    PROGRAMBENCH_DOCKER_CP_TIMEOUT300Timeout in seconds for Docker container pull/start operations
    PROGRAMBENCH_DOCKER_ORGprogrambenchThe Docker organization/namespace used for images
    PROGRAMBENCH_HF_REPOprogrambench/ProgramBench-TestsHugging Face repository ID
    PROGRAMBENCH_HF_REVISIONmainHugging Face repository revision/branch
  11. Understand ProgramBench evaluation JSON output

    main

    Each task in the evaluation directory produces a JSON file (e.g., task_id.eval.json). These files contain the detailed results of the evaluation pipeline.

    JSON Schema Reference:

    FieldDescription
    test_resultsA list of objects containing {name, branch, status, extra}. status is typically passed or failure. extra may include time (seconds), and on failures, message (assertion text) and text (captured output).
    error_codeTop-level error code; null if the run was clean.
    error_detailsTop-level error details; null if the run was clean.
    logAn ordered list of pipeline steps: {step, command, wall_time, output, returncode, exception_info}. Steps may optionally include a branch identifier.
    solution_branchThe name of the branch or folder holding the candidate solution (e.g., submission).
    test_branchesA list of test-branch identifiers run against the solution.
    test_branch_errorsA dictionary mapping branch $\rightarrow$ error info. Empty if all branches ran cleanly.
    executable_hashThe SHA256 hash of the built artifact under test.
    warningsA list of warning strings emitted by the harness.

    Note on Non-determinism: Some branches or tests may be ignored due to non-determinism. For a complete list of ignored items, refer to the tests.json file in the ProgramBench data folder.

    {
        "test_results": [
            {
            "name": "tests.test_foo.test_passes",
            "branch": "abc123def456",
            "status": "passed",
            "extra": { "time": 0.002 }
            }
        ],
        "error_code": null,
        "error_details": null,
        "log": [
            {
            "step": "results_read",
            "branch": "abc123def456",
            "command": "cat eval/results.xml",
            "wall_time": 0.071,
            "output": "<xml>...</xml>",
            "returncode": 0,
            "exception_info": ""
            }
        ],
        "solution_branch": "submission",
        "test_branches": ["abc123def456"],
        "test_branch_errors": {},
        "executable_hash": "980ff4f78ca130cedceaa42cec78431184827154fbc4ef95d2df5c8fee948186",
        "warnings": []
    }
  12. Troubleshoot container process leaks after timeouts

    main

    When a command executed via execute() hits a host-side timeout, Python sends a SIGKILL to the docker exec process. However, the Docker daemon does not propagate this signal to the process running inside the container, which can lead to orphaned processes competing with subsequent commands.

    ContainerEnvironment.execute() handles this automatically by attempting to sweep the container: it executes kill -KILL -1 inside the container to kill all processes except PID-1 (the long-lived sleep process). This ensures a clean environment for the next execution.