from fastapi import FastAPI, HTTPException from pydantic import BaseModel from fastapi.middleware.cors import CORSMiddleware from new_parser_test import parse_request from geocoder import validate_address from database import search_database from route import build_route from ouput_chat import RouteDescriber app = FastAPI(title="AI API") # ======== FASTAPI СХЕМЫ ========== class ChatRequest(BaseModel): user_input: str conversation_history: list | None = None class ChatResponse(BaseModel): success: bool need_more_info: bool # result теперь может содержать как промежуточные данные парсера, # так и финальный маршрут с описанием result: dict conversation_history: list error: str | None = None # ================================= @app.post("/chat", response_model=ChatResponse) def chat_endpoint(request: ChatRequest): try: # 1. Вызываем парсер, чтобы извлечь информацию из диалога parser_response = parse_request(request.user_input, request.conversation_history) # 2. Проверяем условие: парсер отработал успешно и больше информации не нужно if parser_response["success"] and not parser_response["need_more_info"]: # --- Логика построения маршрута --- parsed_data = parser_response["result"] tags = parsed_data.get("tags") print(tags) user_address = parsed_data.get("user_location") print(user_address) user_time = parsed_data.get("time") print(user_time) conversation_history = parser_response["conversation_history"] # Валидация адреса val_output = validate_address('addresses.sqlite', user_address) if not val_output or not val_output['valid']: return ChatResponse( success=False, need_more_info=False, result={}, conversation_history=conversation_history, error=f"Не удалось распознать адрес: {user_address}. Пожалуйста, попробуйте указать его точнее." ) user_position = [ val_output['coordinates']['lat'], val_output['coordinates']['lon'] ] # Поиск точек в базе данных found_points, mapping = search_database('output.json', tags) if not found_points: return ChatResponse( success=False, need_more_info=False, result={}, conversation_history=conversation_history, error="К сожалению, я не смог найти подходящих мест по вашему запросу." ) print(mapping) # Построение маршрута n_nodes = len(mapping) allow_extend = any(v[1] for v in mapping.values()) route_otp = None if allow_extend: while n_nodes <= 5 and (route_otp := build_route(found_points, mapping, user_position, user_time, n_nodes,strategy='random') or route_otp): n_nodes += 1 else: route_otp= build_route(found_points, mapping, user_position, user_time, n_nodes,strategy='random') if not route_otp: return ChatResponse( success=False, need_more_info=False, result={}, conversation_history=conversation_history, error="Не удалось построить маршрут с указанными параметрами. Попробуйте изменить запрос." ) route, places = route_otp route.insert(0, user_position) # Генерация описания маршрута describer = RouteDescriber() description = describer.generate_route_description(places, conversation_history) # Финальный успешный ответ с маршрутом return ChatResponse( success=True, need_more_info=False, result={ "route": route, "description": description, "places": places }, conversation_history=conversation_history, error=None ) else: # 3. Если парсеру нужно больше информации или он завершился неуспешно, # просто возвращаем его ответ пользователю. # `ChatResponse` и словарь от `parse_request` имеют одинаковую структуру. return ChatResponse(**parser_response) except Exception as e: # Отлавливаем любые другие непредвиденные ошибки # В рабочей среде здесь лучше добавить логирование print(f"An unexpected error occurred: {e}") raise HTTPException(status_code=500, detail="Произошла внутренняя ошибка сервера.") origins = [ "http://localhost", "http://localhost:5173", "https://gorkycode.nikidze.ru" ] app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], max_age=3600 )