92 lines
3.0 KiB
Python
92 lines
3.0 KiB
Python
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
|
|
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 = query_agent(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)
|