Spaces:
Sleeping
Sleeping
File size: 3,412 Bytes
2ce1061 ceba2ab 2ce1061 ceba2ab 2ce1061 ceba2ab e1f5917 ceba2ab e1f5917 ceba2ab e1f5917 2ce1061 ceba2ab 2ce1061 ceba2ab 2ce1061 ceba2ab 2ce1061 ceba2ab 2ce1061 ceba2ab 2ce1061 0944271 ceba2ab | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | # server/app.py
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import HTMLResponse
from typing import Optional
from pydantic import BaseModel
import os
from server.environment import CodeDebugEnvironment
from models import DebugAction, DebugObservation, DebugState
app = FastAPI(
title="Code Debug Environment",
description=(
"An OpenEnv environment where LLM agents fix buggy Python code. "
"3 difficulty levels: easy (1 bug), medium (2 bugs), hard (algorithmic + explanation)."
),
version="1.0.0",
)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
)
env = CodeDebugEnvironment()
@app.get("/", response_class=HTMLResponse)
async def root():
"""Homepage with live tester UI."""
html_path = os.path.join(os.path.dirname(__file__), "static", "index.html")
with open(html_path, "r", encoding="utf-8") as f:
return f.read()
@app.get("/health")
async def health():
return {"status": "ok", "environment": "code-debug-env", "version": "1.0.0"}
class ResetRequest(BaseModel):
difficulty: Optional[str] = None
class StepRequest(BaseModel):
fixed_code: str
explanation: Optional[str] = None
class StepResponse(BaseModel):
observation: dict
reward: float
done: bool
@app.post("/reset")
async def reset(request: ResetRequest = ResetRequest()) -> dict:
try:
observation = env.reset(difficulty=request.difficulty)
return {"observation": observation.model_dump(), "reward": 0.0, "done": False}
except Exception as e:
raise HTTPException(status_code=500, detail=f"Reset failed: {str(e)}")
@app.post("/step")
async def step(request: StepRequest) -> StepResponse:
if not request.fixed_code or not request.fixed_code.strip():
raise HTTPException(status_code=400, detail="fixed_code must not be empty.")
try:
action = DebugAction(fixed_code=request.fixed_code, explanation=request.explanation)
observation = env.step(action)
return StepResponse(
observation=observation.model_dump(),
reward=observation.reward or 0.0,
done=observation.done,
)
except Exception as e:
raise HTTPException(status_code=500, detail=f"Step failed: {str(e)}")
@app.get("/state")
async def state() -> dict:
try:
return env.state.model_dump()
except Exception as e:
raise HTTPException(status_code=500, detail=f"State failed: {str(e)}")
@app.get("/tasks")
async def list_tasks() -> dict:
from server.tasks.task_easy import EASY_TASKS
from server.tasks.task_medium import MEDIUM_TASKS
from server.tasks.task_hard import HARD_TASKS
return {
"easy": [t["task_id"] for t in EASY_TASKS],
"medium": [t["task_id"] for t in MEDIUM_TASKS],
"hard": [t["task_id"] for t in HARD_TASKS],
"total": len(EASY_TASKS) + len(MEDIUM_TASKS) + len(HARD_TASKS),
}
# βββ Run directly with: python server/app.py βββββββββββββββββββββββββββββββββ
if __name__ == "__main__":
import sys
import uvicorn
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
uvicorn.run("server.app:app", host="127.0.0.1", port=7860, reload=True) |