Spaces:
Sleeping
Sleeping
| import logging | |
| from fastapi import APIRouter, HTTPException, Request | |
| from app.config import settings | |
| from app.models.schemas import ChatRequest, ChatResponse | |
| from app.services import rag_service | |
| from app.services.limits import SlidingWindowLimiter | |
| logger = logging.getLogger(__name__) | |
| router = APIRouter() | |
| _chat_limiter = SlidingWindowLimiter(settings.rate_limit_chat_per_minute, 60) | |
| def _client_ip(request: Request) -> str: | |
| # Behind Vercel/HF proxies the real client is in X-Forwarded-For | |
| fwd = request.headers.get("x-forwarded-for") | |
| if fwd: | |
| return fwd.split(",")[0].strip() | |
| return request.client.host if request.client else "unknown" | |
| async def chat_endpoint(request: ChatRequest, http_request: Request): | |
| if not request.message.strip(): | |
| raise HTTPException(status_code=400, detail="Message cannot be empty") | |
| if not _chat_limiter.allow(_client_ip(http_request)): | |
| raise HTTPException( | |
| status_code=429, | |
| detail="Too many requests — please wait a minute and try again.", | |
| ) | |
| try: | |
| answer, sources, response_type, structured_data, token_usage, model_used, rate_limit = \ | |
| await rag_service.chat( | |
| request.session_id, | |
| request.message, | |
| request.model, | |
| request.email_action, | |
| request.email_payload, | |
| ) | |
| return ChatResponse( | |
| answer=answer, | |
| sources=sources, | |
| session_id=request.session_id, | |
| response_type=response_type, | |
| structured_data=structured_data, | |
| token_usage=token_usage, | |
| model_used=model_used, | |
| rate_limit=rate_limit, | |
| ) | |
| except Exception: | |
| # Full details go to the server log only — never to the client. | |
| logger.exception("Chat request failed (session=%s)", request.session_id) | |
| raise HTTPException( | |
| status_code=500, | |
| detail="Something went wrong while processing your request. Please try again.", | |
| ) | |
| async def clear_session(session_id: str): | |
| rag_service.clear_session(session_id) | |
| return {"cleared": session_id} | |