import os import threading from fastapi import FastAPI, Response from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import RedirectResponse from pydantic import BaseModel from typing import Optional from .agent import ShoppingAgent from .feedback import salvar_feedback from .logger import salvar_log_busca def _cors_origins(): base = [ "http://127.0.0.1:5173", "http://localhost:5173", "http://127.0.0.1:3000", "http://localhost:3000", ] extra = os.getenv("CORS_ORIGINS", "") if extra.strip(): base.extend(o.strip() for o in extra.split(",") if o.strip()) return base app = FastAPI(title="TCC2 Agent API") app.add_middleware( CORSMiddleware, allow_origins=_cors_origins(), allow_origin_regex=r"https://.*\.hf\.space$", allow_credentials=True, 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 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 @app.get("/health") def health(): return {"status": "ok", "agent_ready": agent is not None} @app.get("/", include_in_schema=False) def root(): return RedirectResponse(url="/docs") @app.get("/favicon.ico", include_in_schema=False) def favicon(): return Response(status_code=204) @app.post("/chat") 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 @app.post("/feedback") def feedback(request: FeedbackRequest): return salvar_feedback( query=request.query, product_id=request.product_id, product_name=request.product_name, rating=request.rating, is_helpful=request.is_helpful )