Spaces:
Sleeping
title: Debug Env - AI Debugging Benchmark
emoji: π
colorFrom: blue
colorTo: indigo
sdk: docker
pinned: true
app_port: 7860
tags:
- openenv
- debugging
- benchmark
- ai-agents
debug-env β AI Code Debugging Benchmark
An OpenEnv benchmark where LLM agents fix broken Python code. Agents use four tools to diagnose and repair bugs across 9 tasks of increasing complexity. Rewards are shaped on test pass rate (0.0β1.0) with efficiency bonuses.
Live Space: vanshgoel1-debug-env.hf.space
GitHub: VanshGoel-1/debug-env
Environment Description
Real-world code debugging is a core developer skill and a meaningful benchmark for LLM agents. debug-env places agents inside an isolated working directory containing buggy Python code and a pytest test suite. The agent must use tools to understand the code, identify the bug, and write a corrected file β all within a fixed step budget.
The environment models genuine debugging scenarios: syntax errors, logic bugs, multi-file issues, type errors, code quality problems, and collaborative refactoring tasks. These are tasks developers do every day.
Action Space
class DebugAction(Action):
tool: str # one of: "list_files", "run_tests", "read_file", "edit_file"
args: dict # tool-specific arguments (see below)
| Tool | Args | Description |
|---|---|---|
list_files |
{} |
List all editable source files in the task workdir |
run_tests |
{} |
Run pytest and return pass rate + full output |
read_file |
{"path": "broken_code.py"} |
Read a source file |
edit_file |
{"path": "broken_code.py", "content": "..."} |
Overwrite file, then run tests |
Observation Space
class DebugObservation(Observation):
pass_rate: float # fraction of tests passing (0.0β1.0)
logs: str # test output, file content, or error message
reward: float # shaped reward for this step
done: bool # True when all tests pass (pass_rate == 1.0)
Reward Function
Defined in debug_env/server/grader.py:
reward = pass_rate
β min(max(0, (steps β 3) Γ 0.01), 0.3) # step penalty after step 3
+ 0.1 if pass_rate == 1.0 # completion bonus
+ 0.2 Γ max(0, 1 β steps/max_steps) # efficiency bonus on full solve
- Partial credit for partial test passage (not sparse)
- Penalises thrashing (many steps without progress)
- Rewards solving quickly
Tasks
| ID | Title | Difficulty | Type | Files |
|---|---|---|---|---|
| task1 | Fix Syntax Error | Easy | Bug fix | broken_code.py |
| task2 | Fix Logic Error | Medium | Bug fix | broken_code.py |
| task3 | Fix Multi-file Bug | Hard | Bug fix | broken_code.py, helper.py |
| task4 | Fix Type Errors | Medium | Type check | typed_code.py |
| task5 | Remove Dead Code | Medium | Code quality | messy_code.py |
| task6 | Architecture Refactor | Hard | Refactoring | 4 files |
| task7 | Code Review Workflow | Medium | Collaborative | auth.py |
| task8 | Cross-team Bug Investigation | Hard | Collaborative | 3 files |
| task9 | Collaborative Refactoring | Hard | Collaborative | 4 files |
Tasks 1β3 cover the mandatory competition range (easy β medium β hard). Tasks 4β9 provide additional challenge for frontier models.
Setup
Prerequisites
- Python 3.10+
- uv package manager
curl -LsSf https://astral.sh/uv/install.sh | sh
Install
git clone https://github.com/VanshGoel-1/debug-env
cd debug-env
uv sync
Configure
cp .env.example .env
# Edit .env and set:
# HF_TOKEN=hf_... (required)
# API_BASE_URL=https://router.huggingface.co/v1
# MODEL_NAME=Qwen/Qwen2.5-72B-Instruct
Verify
python verify_setup.py
# Expected: 18 passed, 0 failed
Usage
Start the server
# Terminal 1
uv run server
# Server runs at http://localhost:8000
Run the benchmark
# Terminal 2
python inference.py
# Run a specific task
TASK=task2 python inference.py
# Multiple runs for Pass@k
TASK=task1 NUMBER_OF_RUNS=3 python inference.py
Verify the server manually
curl http://localhost:8000/health
# {"status":"healthy","service":"debug-env"}
curl -X POST http://localhost:8000/reset \
-H "Content-Type: application/json" \
-d '{"task": "task1"}'
curl -X POST http://localhost:8000/step \
-H "Content-Type: application/json" \
-d '{"action": {"tool": "list_files", "args": {}}}'
Inference Script
inference.py uses the OpenAI client against any OpenAI-compatible endpoint.
Required environment variables:
| Variable | Description |
|---|---|
HF_TOKEN |
HuggingFace / API key |
API_BASE_URL |
LLM API endpoint (default: https://router.huggingface.co/v1) |
MODEL_NAME |
Model identifier (default: Qwen/Qwen2.5-72B-Instruct) |
Competition stdout format:
[START] task=task1 env=debug-env model=Qwen/Qwen2.5-72B-Instruct
[STEP] step=1 action=list_files() reward=0.00 done=false error=null
[STEP] step=2 action=run_tests() reward=0.00 done=false error=null
[STEP] step=3 action=read_file('broken_code.py') reward=0.00 done=false error=null
[STEP] step=4 action=edit_file('broken_code.py') reward=1.10 done=true error=null
[END] success=true steps=4 score=1.10 rewards=0.00,0.00,0.00,1.10
Results are saved to results_{task}_{timestamp}.json with pass@k, success_rate,
avg_steps, and avg_final_reward.
Docker
# Build
docker build -t debug-env .
# Run
docker run -p 8000:8000 debug-env
# With Docker Compose
docker-compose up --build
The Dockerfile uses a two-stage build: dependencies are installed in the builder stage
(cache-friendly), source code is copied into the runtime stage. The CMD runs uvicorn
directly against debug_env.server.app:app.
Deployment to Hugging Face Spaces
# Authenticate
huggingface-cli login
# Validate before pushing
openenv validate
# Push
openenv push --repo-id your-username/debug-env
The openenv.yaml at repo root defines the Space configuration. After push, the Space
auto-builds from Dockerfile and exposes:
GET /healthβ health checkPOST /resetβ start episodePOST /stepβ execute toolGET /tasksβ list all tasksPOST /mcpβ MCP JSON-RPC interface/webβ interactive web UI/docsβ OpenAPI docs
API Reference
Core endpoints
GET /health β {"status":"healthy","service":"debug-env"}
POST /reset {"task":"task1"} β initial observation
POST /step {"action":{"tool":...}} β observation, reward, done
GET /state β current episode state
WS /ws β persistent session (low latency)
Task endpoints
GET /tasks β paginated task list
GET /tasks/{taskId} β task metadata
GET /tasks/{taskId}/files β editable file list
POST /tasks/{taskId}/episodes β create episode
GET /tasks/{taskId}/episodes/{id} β get episode
PATCH /tasks/{taskId}/episodes/{id} β update episode status
MCP endpoint
POST /mcp {"jsonrpc":"2.0","method":"initialize","params":{"meta":{"task":"task1"}},"id":1}
POST /mcp {"jsonrpc":"2.0","method":"tools/list","id":2}
POST /mcp {"jsonrpc":"2.0","method":"tools/call","params":{"name":"run_tests","arguments":{}},"id":3}
Project Structure
debug-env/ β repo root, all commands run here
βββ pyproject.toml β single package definition
βββ uv.lock β committed lock file
βββ Dockerfile β single Dockerfile
βββ docker-compose.yml
βββ openenv.yaml β OpenEnv spec
βββ inference.py β competition entry point
βββ train.py β RL training (GRPO)
βββ verify_setup.py
βββ debug_env/
βββ models.py β DebugAction, DebugObservation
βββ client.py β DebugEnv HTTP/WS client
βββ server/
β βββ app.py β FastAPI entry point
β βββ debug_env_environment.py
β βββ grader.py β reward shaping
β βββ core/apis.py β /health
β βββ database/ β SQLAlchemy + SQLite
β βββ handlers/ β MCP JSON-RPC dispatcher
β βββ mcp/ β MCP router + tool specs
β βββ schemas/ β Pydantic schemas
β βββ tasks/ β registry, loader, API routes
β βββ tools/ β run_tests, read_file, edit_file, list_files
β β + 6 advanced analysis tools
β βββ utils/ β path validation
βββ rl/
β βββ dataset.py β curriculum dataset for GRPO
β βββ rollout.py β reward bridge for TRL
βββ tasks/
βββ task1/ β task3/ β static broken_code.py + test_code.py
βββ task4/ β task9/ β seed_data.py (generated at runtime)
RL Training (Optional)
GRPO training against the live environment using TRL + Unsloth:
uv sync --extra training
uv run server # Terminal 1 β environment must be running
python train.py # Terminal 2
# Smaller model for low VRAM:
MODEL=Qwen/Qwen2.5-1.5B-Instruct python train.py
# Easy tasks only (recommended starting point):
TASK_FILTER=easy python train.py
VRAM reference (Unsloth 4-bit QLoRA):
| Model | Min VRAM |
|---|---|
| Qwen2.5-1.5B | ~2 GB |
| Qwen2.5-7B | ~6 GB |
| Qwen2.5-14B | ~10 GB |
License
BSD 3-Clause β see LICENSE