CoolFace
Apppublic

Vaishnavi-279/sql-debugger-env

sourceHugging Faceupdated 5mo agoView on Hugging Face
0likes
App README

πŸ› οΈ 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

PropertyValue
Max steps per episode5
Reward range0.0 – 1.0
Tasks3 (easy β†’ medium β†’ hard)
DatabaseIn-memory SQLite (zero deps)
Server port8000
TerminationPerfect match OR max attempts reached

πŸ” Action Space

json
{
  "sql": "SELECT name, salary FROM employees WHERE dept='Engineering' ORDER BY salary DESC"
}
FieldTypeDescription
sqlstringA corrected SQL SELECT statement to execute

πŸ‘οΈ Observation Space

FieldTypeDescription
task_idstringTask identifier
difficultystringeasy / medium / hard
task_descriptionstringWhat the query must return
schema_ddlstringCREATE TABLE + INSERT statements
broken_querystringThe original broken query to fix
error_messagestringSQLite error from last attempt (empty if none)
execution_resultlist\nullRows from last submitted query
expected_resultlistGround-truth rows to match exactly
attemptintAttempts made this episode
max_attemptsintMax allowed (5)
hintstring\nullOptional bug-type hint
doneboolEpisode ended
rewardfloatReward from last step

πŸ† Reward Function

ConditionReward
Query errored / no output0.0
Wrong row count0.3
Right count, wrong values0.6
Right values, wrong order0.8
Perfect match`1.0`
Efficiency penalty (per wasted attempt)-0.05 Γ— (attemptβˆ’1)

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

sql
-- 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)

sql
-- 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

sql
-- 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:

bash
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:

cmd
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

bash
# 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:latest

Test the server

Linux / Mac:

bash
# 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):

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:

bash
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.py

Windows (Command Prompt):

cmd
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.py

Windows (PowerShell):

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.py

Expected 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.253

Validate

bash
cd my-openenv/sql_debugger_env
openenv validate
# Expected: [OK] sql_debugger: Ready for multi-mode deployment

πŸ€— Deploy to HuggingFace Spaces

  1. 1.Go to huggingface.co/new-space β†’ SDK = Docker
  2. 2.Push your repo:
bash
git remote add hf https://huggingface.co/spaces/YOUR_HF_USERNAME/sql-debugger-env
git push hf main
  1. 1.In Space Settings β†’ Variables and secrets, add:
VariableValue
HF_TOKENYour HuggingFace token
API_BASE_URLhttps://router.huggingface.co/v1
MODEL_NAMEQwen/Qwen2.5-72B-Instruct
IMAGE_NAMEsql_debugger_env-env:latest
  1. 1.Wait for the Space to show "Running" before submitting.

πŸ“Š Baseline Scores

Qwen/Qwen2.5-72B-Instruct Β· 5 steps max Β· temperature 0.2

TaskDifficultyExpected Score
task_easy_syntax🟒 Easy~0.85
task_medium_join🟑 Medium~0.65
task_hard_complexπŸ”΄ Hard~0.40
Overall~0.63

πŸ—‚οΈ 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

πŸ”Œ API Endpoints

MethodEndpointDescription
GET/health{"status": "healthy"}
GET/metadataName, description, version
GET/schemaAction + Observation schemas
POST/resetStart new episode
POST/stepSubmit {"action": {"sql": "..."}}
GET/stateEpisode state (id, step count)

βš™οΈ Environment Variables

VariableRequiredDefaultDescription
HF_TOKENβœ…β€”HuggingFace token (or OPENAI_API_KEY)
API_BASE_URL❌https://router.huggingface.co/v1LLM endpoint
MODEL_NAME❌Qwen/Qwen2.5-72B-InstructModel identifier
IMAGE_NAME❌sql_debugger_env-env:latestDocker image
SQL_DEBUGGER_TASK❌task_easy_syntaxWhich task to serve
PORT❌8000Server port