Vaishnavi-279/sql-debugger-env
π οΈ SQL Debugger β OpenEnv RL Environment
An OpenEnv reinforcement learning environment where an AI agent must debug and fix broken SQL queries.
The agent receives a broken SQL query + database schema each episode and iteratively submits corrected queries until the result exactly matches the expected output β or it runs out of attempts.
π― Motivation
SQL debugging is a genuine, high-value daily task for developers and data engineers:
- Production queries silently return wrong data
- New engineers inherit broken legacy code
- LLMs frequently generate subtly wrong SQL
This environment trains and evaluates agents on exactly this skill, with deterministic grading and 5-tier partial reward signals at every step.
π Environment Summary
π Action Space
{
"sql": "SELECT name, salary FROM employees WHERE dept='Engineering' ORDER BY salary DESC"
}ποΈ Observation Space
π Reward Function
Rewards are clamped to [0.0, 1.0]. First-attempt correct = 1.0; second attempt = 0.95; etc.
π Tasks
Easy β task_easy_syntax
Bug: Three keyword typos (SELEC, FORM, DESK) Schema: employees(id, name, dept, salary) Goal: Return Engineering employees ordered by salary DESC
-- Broken:
SELEC name, salary FORM employees WHERE dept = 'Engineering' ORDER BY salary DESK;
-- Fixed:
SELECT name, salary FROM employees WHERE dept = 'Engineering' ORDER BY salary DESC;Medium β task_medium_join
Bug: Wrong JOIN column (o.id β o.customer_id) + wrong aggregation (SUM(quantity) β SUM(quantity*unit_price)) Schema: customers(id, name) + orders(id, customer_id, quantity, unit_price)
-- Broken:
SELECT c.name, SUM(o.quantity) AS total_value
FROM customers c JOIN orders o ON c.id = o.id
GROUP BY c.name ORDER BY total_value DESC;
-- Fixed:
SELECT c.name, SUM(o.quantity * o.unit_price) AS total_value
FROM customers c JOIN orders o ON c.id = o.customer_id
GROUP BY c.name ORDER BY total_value DESC;Hard β task_hard_complex
Bug: 3 simultaneous bugs β NULL not excluded in subquery, LEFT JOIN skews averages, ORDER BY ASC should be DESC Schema: products(id, name) + reviews(id, product_id, score) β score is nullable
-- Broken (3 bugs):
SELECT p.name, AVG(r.score) AS avg_score
FROM products p LEFT JOIN reviews r ON p.id = r.product_id
GROUP BY p.name
HAVING AVG(r.score) > (SELECT AVG(score) FROM reviews)
ORDER BY avg_score ASC;
-- Fixed:
SELECT p.name, AVG(r.score) AS avg_score
FROM products p JOIN reviews r ON p.id = r.product_id
WHERE r.score IS NOT NULL
GROUP BY p.name
HAVING AVG(r.score) > (SELECT AVG(score) FROM reviews WHERE score IS NOT NULL)
ORDER BY avg_score DESC;π Setup & Usage
Prerequisites
- Python 3.10+
- Docker Desktop (running)
- Git
Clone & install
Linux / Mac:
git clone https://github.com/YOUR_USERNAME/my-openenv.git
cd my-openenv/sql_debugger_env
pip install openenv-core
uv sync # or: pip install -e .Windows:
git clone https://github.com/YOUR_USERNAME/my-openenv.git
cd my-openenv\sql_debugger_env
pip install openenv-core
pip install -e .Build & run with Docker
# Build (run from inside sql_debugger_env/)
docker build -t sql_debugger_env-env:latest -f server/Dockerfile .
# Run
docker run -p 8000:8000 sql_debugger_env-env:latestTest the server
Linux / Mac:
# Health check
curl http://localhost:8000/health
# Reset β start episode
curl -X POST http://localhost:8000/reset \
-H "Content-Type: application/json" -d "{}"
# Submit a fix
curl -X POST http://localhost:8000/step \
-H "Content-Type: application/json" \
-d '{"action": {"sql": "SELECT name, salary FROM employees WHERE dept='\''Engineering'\'' ORDER BY salary DESC"}}'Windows (PowerShell):
# Health check
Invoke-RestMethod http://localhost:8000/health
# Reset
Invoke-RestMethod -Uri "http://localhost:8000/reset" -Method POST `
-ContentType "application/json" -Body "{}"
# Submit a fix
Invoke-RestMethod -Uri "http://localhost:8000/step" -Method POST `
-ContentType "application/json" `
-Body '{"action": {"sql": "SELECT name, salary FROM employees WHERE dept=''Engineering'' ORDER BY salary DESC"}}'Run inference
Linux / Mac:
cd my-openenv # repo root β where inference.py lives
export HF_TOKEN=your_token_here
export IMAGE_NAME=sql_debugger_env-env:latest
export API_BASE_URL=https://router.huggingface.co/v1
export MODEL_NAME=Qwen/Qwen2.5-72B-Instruct
python inference.pyWindows (Command Prompt):
cd my-openenv
set HF_TOKEN=your_token_here
set IMAGE_NAME=sql_debugger_env-env:latest
set API_BASE_URL=https://router.huggingface.co/v1
set MODEL_NAME=Qwen/Qwen2.5-72B-Instruct
python inference.pyWindows (PowerShell):
cd my-openenv
$env:HF_TOKEN = "your_token_here"
$env:IMAGE_NAME = "sql_debugger_env-env:latest"
$env:API_BASE_URL = "https://router.huggingface.co/v1"
$env:MODEL_NAME = "Qwen/Qwen2.5-72B-Instruct"
python inference.pyExpected output:
[START] task=task_easy_syntax env=sql_debugger model=Qwen/Qwen2.5-72B-Instruct
[STEP] step=1 action=SELECT name... reward=1.00 done=true error=null
[END] success=true steps=1 score=0.200 rewards=1.00
[INFO] task=task_easy_syntax score=0.200
...
[INFO] overall_avg_score=0.253Validate
cd my-openenv/sql_debugger_env
openenv validate
# Expected: [OK] sql_debugger: Ready for multi-mode deploymentπ€ Deploy to HuggingFace Spaces
- Go to huggingface.co/new-space β SDK = Docker
- Push your repo:
git remote add hf https://huggingface.co/spaces/YOUR_HF_USERNAME/sql-debugger-env
git push hf main- In Space Settings β Variables and secrets, add:
- Wait for the Space to show "Running" before submitting.
π Baseline Scores
Qwen/Qwen2.5-72B-Instruct Β· 5 steps max Β· temperature 0.2
ποΈ Project Structure
my-openenv/
βββ inference.py β inference script (repo root)
βββ sql_debugger_env/
βββ models.py β Pydantic Action + Observation
βββ tasks.py β Task definitions (easy/medium/hard)
βββ executor.py β SQLite runner + 5-tier grader
βββ client.py β Async EnvClient
βββ openenv.yaml β OpenEnv spec metadata
βββ pyproject.toml β Package config
βββ uv.lock β Locked dependencies
βββ server/
βββ app.py β FastAPI server (port 8000)
βββ sql_debugger_env_environment.py β Core environment logic
βββ Dockerfile β Container definition
βββ requirements.txt β Server dependencies