Stability: CPU fix with psutil interval and LLM timeouts
This commit is contained in:
129
main.py
129
main.py
@@ -52,7 +52,7 @@ async def check_login(is_auth: bool = Depends(verify_password)):
|
||||
async def get_system_status(is_auth: bool = Depends(verify_password)):
|
||||
"""Retorna o status do sistema (CPU, RAM, Disco) sem travar o loop."""
|
||||
def get_stats():
|
||||
cpu_percent = psutil.cpu_percent(interval=0.1)
|
||||
cpu_percent = psutil.cpu_percent(interval=0.5)
|
||||
vm = psutil.virtual_memory()
|
||||
disk = psutil.disk_usage('/')
|
||||
return {
|
||||
@@ -190,6 +190,133 @@ async def telegram_webhook(request: Request):
|
||||
print("Update recebido do Telegram:", update)
|
||||
return {"ok": True}
|
||||
|
||||
# ============================================================
|
||||
# NOVOS ENDPOINTS - ORQUESTRADOR
|
||||
# ============================================================
|
||||
from orchestrator import (
|
||||
orchestrate, handle_message, get_orchestrator_status,
|
||||
get_llm_config, set_llm_config, format_confirmation_message,
|
||||
format_completion_message
|
||||
)
|
||||
from llm_providers import get_available_models
|
||||
from credential_manager import sync_credentials
|
||||
|
||||
@app.post("/api/orchestrate")
|
||||
async def orchestrate_task(task_data: dict, is_auth: bool = Depends(verify_password)):
|
||||
"""
|
||||
Executa tarefa orquestrada.
|
||||
|
||||
POST /api/orchestrate
|
||||
{
|
||||
"task": "faz deploy do app X",
|
||||
"confirmed": false
|
||||
}
|
||||
|
||||
Response:
|
||||
{
|
||||
"status": "needs_confirmation" | "completed",
|
||||
"plan": {...},
|
||||
"confirmation_needed_for": [...],
|
||||
"message": "..." (para display)
|
||||
}
|
||||
"""
|
||||
task = task_data.get("task", "")
|
||||
confirmed = task_data.get("confirmed", False)
|
||||
|
||||
if not task:
|
||||
return JSONResponse(content={"status": "error", "message": "Task vazia"}, status_code=400)
|
||||
|
||||
result = orchestrate(task, user_confirmed=confirmed)
|
||||
|
||||
# Formata mensagem para display
|
||||
if result["status"] == "needs_confirmation":
|
||||
message = format_confirmation_message(result)
|
||||
return JSONResponse(content={
|
||||
"status": "needs_confirmation",
|
||||
"plan": result["plan"],
|
||||
"confirmation_needed_for": result["confirmation_needed_for"],
|
||||
"message": message
|
||||
})
|
||||
|
||||
return JSONResponse(content={
|
||||
"status": "completed",
|
||||
"plan": result["plan"],
|
||||
"results": result.get("results", []),
|
||||
"message": format_completion_message(result) if 'format_completion_message' in dir() else "Concluído"
|
||||
})
|
||||
|
||||
@app.get("/api/orchestrator-status")
|
||||
async def get_orch_status(is_auth: bool = Depends(verify_password)):
|
||||
"""Retorna status do orquestrador."""
|
||||
return JSONResponse(content=get_orchestrator_status())
|
||||
|
||||
@app.get("/api/llm-config")
|
||||
async def get_llm_configuration(is_auth: bool = Depends(verify_password)):
|
||||
"""Retorna configuração atual de LLMs."""
|
||||
return JSONResponse(content=get_llm_config())
|
||||
|
||||
@app.post("/api/llm-config")
|
||||
async def update_llm_configuration(config_data: dict, is_auth: bool = Depends(verify_password)):
|
||||
"""Atualiza configuração de LLMs."""
|
||||
planner_provider = config_data.get("planner_provider") or None
|
||||
planner_model = config_data.get("planner_model") or None
|
||||
executor_provider = config_data.get("executor_provider") or None
|
||||
executor_model = config_data.get("executor_model") or None
|
||||
|
||||
changes = set_llm_config(
|
||||
planner_provider=planner_provider,
|
||||
planner_model=planner_model,
|
||||
executor_provider=executor_provider,
|
||||
executor_model=executor_model
|
||||
)
|
||||
|
||||
return JSONResponse(content={"status": "success", "changes": changes})
|
||||
|
||||
@app.get("/api/llm-models")
|
||||
async def list_llm_models(is_auth: bool = Depends(verify_password)):
|
||||
"""Lista modelos disponíveis para cada provider."""
|
||||
models = get_available_models()
|
||||
return JSONResponse(content={"models": models})
|
||||
|
||||
@app.post("/api/sync-credentials")
|
||||
async def sync_creds(is_auth: bool = Depends(verify_password)):
|
||||
"""Força sincronização de credenciais."""
|
||||
result = sync_credentials()
|
||||
return JSONResponse(content=result)
|
||||
|
||||
@app.get("/api/tools")
|
||||
async def list_tools(is_auth: bool = Depends(verify_password)):
|
||||
"""Lista todas as ferramentas disponíveis."""
|
||||
from tools_v2 import get_tools_by_danger
|
||||
return JSONResponse(content={
|
||||
"tools": {
|
||||
"safe": get_tools_by_danger("safe"),
|
||||
"medium": get_tools_by_danger("medium"),
|
||||
"dangerous": get_tools_by_danger("dangerous")
|
||||
}
|
||||
})
|
||||
|
||||
@app.post("/api/handle-message")
|
||||
async def handle_web_message(message: dict, is_auth: bool = Depends(verify_password)):
|
||||
"""
|
||||
Manipula mensagem do usuário (alternativa ao chat normal).
|
||||
Suporta confirmação de ações perigosas.
|
||||
|
||||
POST /api/handle-message
|
||||
{
|
||||
"text": "faz deploy do app",
|
||||
"confirmed": false
|
||||
}
|
||||
"""
|
||||
text = message.get("text", "")
|
||||
confirmed = message.get("confirmed", False)
|
||||
|
||||
if not text:
|
||||
return JSONResponse(content={"reply": "Mensagem vazia"})
|
||||
|
||||
reply = await run_in_threadpool(handle_message, text=text, confirmed=confirmed)
|
||||
return JSONResponse(content={"reply": reply})
|
||||
|
||||
if __name__ == "__main__":
|
||||
import uvicorn
|
||||
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
|
||||
|
||||
Reference in New Issue
Block a user