🚀 Auto-deploy: BotVPS atualizado em 24/03/2026 11:57:55
This commit is contained in:
42
main.py
42
main.py
@@ -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", "")
|
||||
|
||||
Reference in New Issue
Block a user