import logging import httpx from decouple import config logger = logging.getLogger(__name__) RAG_API_URL = config("RAG_API_URL", default="http://api:8080").rstrip("/") HTTP_TIMEOUT = httpx.Timeout(120.0, connect=20.0) def build_history_payload(messages: list) -> list[dict]: payload = [] for message in messages[-6:]: payload.append( { "role": message.role, "content": message.content, } ) return payload async def ask_rag_answer( *, user_id: int, question: str, category: str | None, region: str | None, user_type: str | None, consultation_id: int | None = None, history: list | None = None, top_k: int = 5, ) -> dict: payload = { "user_id": user_id, "consultation_id": consultation_id, "save_history": True, "question": question, "category": category, "region": region, "user_type": user_type, "history": build_history_payload(history or []), "top_k": top_k, } try: async with httpx.AsyncClient(timeout=HTTP_TIMEOUT) as client: response = await client.post( f"{RAG_API_URL}/api/v1/rag/answer", json=payload, ) response.raise_for_status() return response.json() except httpx.HTTPStatusError as exc: detail = "" try: detail = exc.response.json().get("detail", "") except Exception: detail = exc.response.text if "No reliable law chunks" in detail: detail = ( "Я не нашел в базе надежную норму по этому вопросу. " "Попробуйте уточнить ситуацию и задать вопрос еще раз." ) elif "User was not found" in detail: detail = ( "Профиль пользователя не найден в базе. " "Нажмите /start и попробуйте еще раз." ) elif "Consultation was not found" in detail: detail = ( "Не удалось найти выбранную консультацию. " "Откройте историю заново или начните новую консультацию." ) logger.warning("RAG API returned %s: %s", exc.response.status_code, detail) raise RuntimeError(detail or "Сервис анализа вернул ошибку.") except httpx.HTTPError as exc: logger.exception("RAG API request failed") raise RuntimeError("Не удалось связаться с сервисом анализа. Попробуйте позже.") from exc