import os import psutil import subprocess import time import json import asyncio from fastapi import FastAPI, Request, Header, Depends, HTTPException, status from fastapi.responses import HTMLResponse, JSONResponse, FileResponse from fastapi.templating import Jinja2Templates from dotenv import load_dotenv from starlette.concurrency import run_in_threadpool from ai_agent import query_agent_async from config import get_config, save_config from credential_manager import fetch_from_gitea_repo_async from orchestrator import ( orchestrate_async, handle_message_async, get_orchestrator_status, get_llm_config, set_llm_config, format_confirmation_message, format_completion_message ) load_dotenv() app = FastAPI(title="BotVPS API") templates = Jinja2Templates(directory="templates") # ============================================================ # STARTUP # ============================================================ @app.on_event("startup") async def startup_event(): print("[INIT] Sincronizando credenciais...") await fetch_from_gitea_repo_async(force=True) # --- SEGURANÇA --- async def verify_password(x_web_password: str = Header(None)): cfg = get_config() if x_web_password != cfg.get("web_password", "@@Gi05Br;;"): raise HTTPException(status_code=401, detail="Não autorizado") return True # --- WEB UI --- @app.get("/", response_class=FileResponse) async def read_root(request: Request): return FileResponse("templates/index.html") @app.get("/api/status") async def get_system_status(is_auth: bool = Depends(verify_password)): vm = psutil.virtual_memory() return { "cpu": psutil.cpu_percent(), "ram": {"percent": vm.percent, "used": round(vm.used / (1024**3), 2)}, "disk": {"percent": psutil.disk_usage('/').percent} } # --- CHAT & ORCHESTRATION --- @app.post("/api/chat") async def web_chat(message: dict, is_auth: bool = Depends(verify_password)): user_text = message.get("text", "") if not user_text: return {"reply": "Vazio."} reply = await query_agent_async(user_text) return {"reply": reply} @app.post("/api/orchestrate") async def orchestrate_task(task_data: dict, is_auth: bool = Depends(verify_password)): task = task_data.get("task", "") confirmed = task_data.get("confirmed", False) result = await orchestrate_async(task, user_confirmed=confirmed) if result["status"] == "needs_confirmation": return { "status": "needs_confirmation", "plan": result["plan"], "message": format_confirmation_message(result) } return { "status": "completed", "results": result.get("results", []), "message": format_completion_message(result) } @app.get("/api/orchestrator-status") async def get_orch_status(is_auth: bool = Depends(verify_password)): return get_orchestrator_status() # --- SERVER --- if __name__ == "__main__": import uvicorn uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)