| """ |
| AgentDebuggerEnv β FastAPI Server |
| =================================== |
| Exposes the environment as REST endpoints: |
| POST /reset β Start a fresh episode |
| POST /step β Submit one action |
| GET /state β Full internal state |
| GET /health β Deployment health check (must return 200) |
| """ |
|
|
| from fastapi import FastAPI, HTTPException |
| from fastapi.responses import JSONResponse |
| from pydantic import BaseModel |
| from typing import Optional |
|
|
| from env.environment import DebuggerEnvironment |
| from env.models import Action |
| from env.tasks.registry import list_tasks |
|
|
| app = FastAPI( |
| title="AgentDebuggerEnv", |
| description="An OpenEnv-compliant debugging environment for AI agents", |
| version="1.0.0", |
| ) |
|
|
| |
| env = DebuggerEnvironment() |
|
|
|
|
| class ResetRequest(BaseModel): |
| task_id: str |
|
|
|
|
| @app.get("/health") |
| async def health(): |
| """Health check β must return HTTP 200 always. Critical for hackathon Phase 1.""" |
| return {"status": "ok", "environment": "agentdebugger-env", "version": "1.0.0"} |
|
|
|
|
| @app.post("/reset") |
| async def reset(request: ResetRequest): |
| """Start a fresh episode. Returns initial Observation.""" |
| try: |
| observation = env.reset(request.task_id) |
| return JSONResponse(content=observation, status_code=200) |
| except ValueError as e: |
| return JSONResponse( |
| content={"error": str(e), "available_tasks": list_tasks()}, |
| status_code=400, |
| ) |
| except Exception as e: |
| return JSONResponse( |
| content={"error": f"Internal error during reset: {str(e)}"}, |
| status_code=200, |
| ) |
|
|
|
|
| @app.post("/step") |
| async def step(action: Action): |
| """Submit one action. Returns {observation, reward, done, info}. Always HTTP 200.""" |
| try: |
| result = env.step(action) |
| return JSONResponse(content=result, status_code=200) |
| except Exception as e: |
| |
| return JSONResponse( |
| content={ |
| "observation": {}, |
| "reward": { |
| "step_reward": 0.0, |
| "cumulative_reward": 0.0, |
| "grader_score": 0.0, |
| "breakdown": {}, |
| }, |
| "done": False, |
| "info": {"error": f"Internal error: {str(e)}"}, |
| }, |
| status_code=200, |
| ) |
|
|
|
|
| @app.get("/state") |
| async def get_state(): |
| """Return full internal environment state as a plain dict.""" |
| try: |
| state = env.state() |
| return JSONResponse(content=state, status_code=200) |
| except Exception as e: |
| return JSONResponse( |
| content={"error": f"Internal error: {str(e)}"}, |
| status_code=200, |
| ) |
|
|