Spaces:
Sleeping
Sleeping
| import os | |
| import threading | |
| from pathlib import Path | |
| from fastapi import FastAPI, Response | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from fastapi.responses import FileResponse, RedirectResponse | |
| from pydantic import BaseModel | |
| from typing import Optional | |
| from .agent import ShoppingAgent | |
| from .feedback import caminho_feedback, salvar_feedback | |
| from .logger import salvar_log_busca | |
| from .memory import caminho_memoria_negativa | |
| EMBEDDING_PROVIDER = os.getenv("EMBEDDING_PROVIDER", "transformers").strip().lower() | |
| HF_MODEL_REPO = os.getenv("HF_MODEL_REPO", "Ana2012/bertimbau-buscador").strip() | |
| def _env_flag(name, default="true"): | |
| return os.getenv(name, default).strip().lower() in {"1", "true", "yes", "on"} | |
| PRELOAD_AGENT = _env_flag("PRELOAD_AGENT", "true") | |
| LOGS_DIR = os.getenv("LOGS_DIR", "/data/logs") | |
| DATA_DIR = "/data" | |
| app = FastAPI(title="TCC2 Agent API") | |
| app.add_middleware( | |
| CORSMiddleware, | |
| # Libera temporariamente a comunicacao entre frontend na Cloudflare e backend no Fly.io. | |
| allow_origins=["*"], | |
| allow_credentials=False, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| agent = None | |
| agent_lock = threading.Lock() | |
| def get_agent(): | |
| global agent | |
| if agent is None: | |
| with agent_lock: | |
| if agent is None: | |
| agent = ShoppingAgent() | |
| return agent | |
| def preload_agent(): | |
| if PRELOAD_AGENT: | |
| get_agent() | |
| class ChatRequest(BaseModel): | |
| query: Optional[str] = None | |
| message: Optional[str] = None | |
| top_k: int = 5 | |
| class FeedbackRequest(BaseModel): | |
| query: str | |
| product_id: str | |
| product_name: str | |
| rating: Optional[int] = None | |
| is_helpful: Optional[bool] = None | |
| def health(): | |
| runtime = get_agent().runtime_info() if agent is not None else None | |
| return { | |
| "status": "ok", | |
| "agent_ready": agent is not None, | |
| "embedding_provider": EMBEDDING_PROVIDER, | |
| "model_repo": HF_MODEL_REPO, | |
| "preload_agent": PRELOAD_AGENT, | |
| "runtime": runtime, | |
| } | |
| def root(): | |
| return RedirectResponse(url="/docs") | |
| def favicon(): | |
| return Response(status_code=204) | |
| def debug_files(): | |
| data_path = Path(DATA_DIR) | |
| logs_path = Path(LOGS_DIR) | |
| feedback_path = Path(caminho_feedback()) | |
| memory_path = Path(caminho_memoria_negativa()) | |
| return { | |
| "data_exists": data_path.exists(), | |
| "logs_exists": logs_path.exists(), | |
| "feedback_exists": feedback_path.exists(), | |
| "negative_memory_exists": memory_path.exists(), | |
| "data_files": sorted(p.name for p in data_path.iterdir()) if data_path.exists() else [], | |
| "logs_files": sorted(p.name for p in logs_path.iterdir()) if logs_path.exists() else [], | |
| "feedback_file": str(feedback_path), | |
| "negative_memory_file": str(memory_path), | |
| } | |
| def debug_feedback(): | |
| feedback_path = Path(caminho_feedback()) | |
| if not feedback_path.exists(): | |
| return {"error": "arquivo nao existe"} | |
| return {"conteudo": feedback_path.read_text(encoding="utf-8")} | |
| def download_feedback(): | |
| feedback_path = caminho_feedback() | |
| if not os.path.exists(feedback_path): | |
| return {"error": "arquivo nao existe"} | |
| return FileResponse(feedback_path, filename="feedback.csv") | |
| def debug_memory(): | |
| memory_path = Path(caminho_memoria_negativa()) | |
| if not memory_path.exists(): | |
| return {"status": "missing", "file": str(memory_path)} | |
| return { | |
| "status": "ok", | |
| "file": str(memory_path), | |
| "content": memory_path.read_text(encoding="utf-8"), | |
| } | |
| def chat(request: ChatRequest): | |
| texto = request.query or request.message | |
| if not texto: | |
| return {"error": "query ou message deve ser informado"} | |
| resultado = get_agent().responder(texto, top_k=request.top_k) | |
| salvar_log_busca(resultado) | |
| return resultado | |
| def feedback(request: FeedbackRequest): | |
| feedback_file = caminho_feedback() | |
| print( | |
| "Salvando feedback:", | |
| { | |
| "query": request.query, | |
| "product_id": request.product_id, | |
| "feedback_file": feedback_file, | |
| "logs_dir_exists": os.path.exists(LOGS_DIR), | |
| }, | |
| ) | |
| try: | |
| return salvar_feedback( | |
| query=request.query, | |
| product_id=request.product_id, | |
| product_name=request.product_name, | |
| rating=request.rating, | |
| is_helpful=request.is_helpful | |
| ) | |
| except Exception as exc: | |
| return { | |
| "status": "error", | |
| "message": "Erro ao salvar feedback.", | |
| "detail": str(exc), | |
| "feedback_file": feedback_file, | |
| "logs_dir_exists": os.path.exists(LOGS_DIR), | |
| } | |