🚀 Auto-deploy: BotVPS atualizado em 24/03/2026 11:57:55

This commit is contained in:
2026-03-24 11:57:55 +00:00
parent 9509ea8fe8
commit c2273a13f0
3 changed files with 66 additions and 27 deletions

42
main.py
View File

@@ -4,13 +4,16 @@ import subprocess
import time
import json
import asyncio
from fastapi import FastAPI, Request, Header, Depends, HTTPException, status
from fastapi import FastAPI, Request, Header, Depends, HTTPException, status, UploadFile, File
from fastapi.responses import HTMLResponse, JSONResponse, FileResponse
from fastapi.templating import Jinja2Templates
from dotenv import load_dotenv
from starlette.concurrency import run_in_threadpool
import shutil
import uuid
from ai_agent import query_agent_async
from audio_handler import transcribe_audio, text_to_speech_async
from config import get_config, save_config
from credential_manager import fetch_from_gitea_repo_async
from orchestrator import (
@@ -134,6 +137,43 @@ async def web_chat(message: dict, is_auth: bool = Depends(verify_password)):
reply = await query_agent_async(user_text, chat_history=history)
return {"reply": reply}
@app.post("/api/chat-audio")
async def web_chat_audio(audio: UploadFile = File(...), is_auth: bool = Depends(verify_password)):
# 1. Salva o áudio vindo do navegador (/tmp)
temp_in = f"/tmp/{uuid.uuid4().hex}_{audio.filename}"
with open(temp_in, "wb") as buffer:
shutil.copyfileobj(audio.file, buffer)
try:
# 2. Transcreve (STT)
text = transcribe_audio(temp_in)
if not text:
return {"reply": "Não entendi seu áudio.", "text": ""}
# 3. Processa na IA
reply = await query_agent_async(text)
# 4. Gera áudio da resposta (TTS)
reply_clean = re.sub(r'<REFINED>.*?</REFINED>', '', reply, flags=re.DOTALL).strip()
filename = await text_to_speech_async(reply_clean)
return {
"text": text,
"reply": reply,
"audio_url": f"/api/audio/{filename}"
}
except Exception as e:
return {"reply": f"Erro Áudio: {str(e)}", "text": "Erro."}
finally:
if os.path.exists(temp_in): os.remove(temp_in)
@app.get("/api/audio/{filename}")
async def get_audio_file(filename: str):
path = os.path.join("/tmp", filename)
if os.path.exists(path):
return FileResponse(path, media_type="audio/mpeg")
return JSONResponse({"error": "File not found"}, status_code=404)
@app.post("/api/orchestrate")
async def orchestrate_task(task_data: dict, is_auth: bool = Depends(verify_password)):
task = task_data.get("task", "")