from fastapi import FastAPI, HTTPException from .config import ServerSettings from .grid import GridManager from .models import ActionPayload, GridDescriptor, GridInitRequest from .planner import GridPlanner settings = ServerSettings() manager = GridManager(settings) planner = GridPlanner() app = FastAPI( title="Clickthrough", description="Grid-aware surface that lets an agent plan clicks, drags, and typing on a fake screenshot", version="0.2.0", ) @app.get("/health") def health_check() -> dict[str, str]: return {"status": "ok", "grid_count": str(manager.grid_count)} @app.post("/grid/init", response_model=GridDescriptor) def init_grid(request: GridInitRequest) -> GridDescriptor: grid = manager.create_grid(request) return grid.describe() @app.post("/grid/action") def apply_action(payload: ActionPayload): try: grid = manager.get_grid(payload.grid_id) except KeyError as exc: raise HTTPException(status_code=404, detail=str(exc)) from exc return grid.apply_action(payload) @app.get("/grid/{grid_id}/summary") def grid_summary(grid_id: str): try: grid = manager.get_grid(grid_id) except KeyError as exc: raise HTTPException(status_code=404, detail=str(exc)) from exc descriptor = grid.describe() return { "grid_id": grid_id, "summary": planner.describe(descriptor), "details": grid.summary(), "descriptor": descriptor, } @app.get("/grid/{grid_id}/history") def grid_history(grid_id: str): try: history = manager.get_history(grid_id) except KeyError as exc: raise HTTPException(status_code=404, detail=str(exc)) from exc return {"grid_id": grid_id, "history": history}