File size: 4,713 Bytes
3973360
 
 
 
ec6867d
 
 
 
 
 
 
 
 
 
 
 
ef0145e
ec6867d
 
 
ef0145e
ec6867d
58d41ff
ef0145e
 
 
3973360
 
ef0145e
3973360
 
 
 
 
 
 
ec6867d
3973360
ec6867d
3973360
ec6867d
 
 
ef0145e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e35675d
 
 
 
 
 
 
 
 
4082d98
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ec6867d
4082d98
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
from typing import List, Dict, Any
import aiohttp
from fastapi import HTTPException
from src.utils.logger import logger
import json
from src.langgraph.langchain.prompt import (
    routing_recommender_chain,
    characteristic_extractor_chain,
    RoutingRecommender,
    CharacteristicExtractor,
)
from src.apis.controllers.location_controller import (
    get_lat_long_location,
    get_places,
)
from src.langgraph.config.constant import available_categories
from src.utils.logger import logger


async def destination_suggestion_controller(
    question: str, user_id: str, top_k: int = 5
) -> List[Dict[str, Any]]:
    url = f"https://abao77-triventure-personalize.hf.space/model/get_destinations_list_by_question/{question}/{top_k}"
    if user_id:
        url += f"/{user_id}"
        logger.info("Call recommend with user_id")
    async with aiohttp.ClientSession() as session:
        try:
            async with session.get(url) as response:
                if response.status == 200:
                    data = await response.json()
                    logger.info(f"Destination suggestion for question: {data}")
                    return data["destinations_list"]
                else:
                    raise HTTPException(
                        status_code=response.status,
                        detail=f"Destinations request failed with status {response.status}",
                    )

        except aiohttp.ClientError as e:
            raise HTTPException(status_code=500, detail=f"Request failed: {str(e)}")


async def destination_recommendation_func(
    query, user_id: str, top_k=5, tool_chat=False
):
    routing: RoutingRecommender = await routing_recommender_chain.ainvoke(
        {"query": query}
    )
    print("routing", routing)
    if routing.label == "invalid":
        if tool_chat:
            return "the input message is not related to travel or destination"
        raise HTTPException(
            status_code=400,
            detail="The input is not related to travel or destination recommendations. Please provide a travel-related query.",
        )
    elif routing.label == "characteristic":
        output = await destination_suggestion_controller(query, user_id, top_k)
        if tool_chat:
            return output
        output = [
            {
                "name": i,
                "map_url": "https://www.google.com/maps/search/109.23333,13.76667",
            }
            for i in output
        ]
        return {"characteristic": output, "geoapify": []}
    else:
        import asyncio

        # Define async tasks for both operations
        async def get_geoapify_results():
            characteristic_extract_response: CharacteristicExtractor = (
                await characteristic_extractor_chain.ainvoke({"query": query})
            )
            lat, lon = get_lat_long_location(characteristic_extract_response.main_place)
            response = get_places(
                lat,
                lon,
                5000,
                available_categories.get(characteristic_extract_response.kind, None),
                top_k,
            )
            output_geo = json.loads(response.body)
            if tool_chat:
                output_geo = [
                    {
                        "name": i["name"],
                        "address": i["address"],
                        "distance_km": i["distance_km"],
                    }
                    for i in output_geo
                ]
            return output_geo

        async def get_characteristic_results():
            output_characteristic = await destination_suggestion_controller(
                query, user_id, top_k
            )
            output_characteristic = [
                {
                    "name": i,
                    "map_url": "https://www.google.com/maps/search/109.23333,13.76667",
                }
                for i in output_characteristic
            ]
            return output_characteristic

        # Run both tasks concurrently
        output_geo_task = asyncio.create_task(get_geoapify_results())
        output_characteristic_task = asyncio.create_task(get_characteristic_results())

        # Wait for both tasks to complete
        output_geo, output_characteristic = await asyncio.gather(
            output_geo_task, output_characteristic_task
        )

        # If tool_chat mode, return just the geoapify results
        if tool_chat:
            return output_geo

        logger.info(f"output_geo {output_geo}")
        logger.info(f"output_characteristic {output_characteristic}")

        return {
            "geoapify": output_geo,
            "characteristic": output_characteristic,
        }