File size: 7,359 Bytes
3fe95d4
2c9c370
37f19e6
3fe95d4
 
 
2c9c370
5030a6d
bf2c98f
b7fea89
 
29671ec
 
 
 
 
 
 
 
 
 
 
afe8500
29671ec
 
 
 
 
 
 
 
 
afe8500
29671ec
 
 
 
b7fea89
29671ec
b7fea89
 
29671ec
b7fea89
 
 
29671ec
 
b7fea89
29671ec
ac9ebe0
29671ec
b7fea89
 
2c9c370
006d52c
29671ec
006d52c
 
 
daefa98
006d52c
29671ec
 
5ec14a8
006d52c
a365e85
 
5ec14a8
006d52c
 
b7fea89
006d52c
b7fea89
29671ec
006d52c
 
b7fea89
 
 
 
 
 
006d52c
daefa98
 
 
27f7014
006d52c
73fca82
27f7014
29671ec
b7fea89
c263614
9878e3d
15dc418
 
 
 
 
 
 
 
 
 
1391702
cc55644
79d5441
 
cc55644
b7fea89
0a39a3e
 
 
 
 
 
 
b7fea89
006d52c
d0b6807
c263614
1391702
 
8816885
0735fc8
ac9ebe0
dea724c
0735fc8
5ea6f99
e44ec40
73a9aaf
f3e4894
d7916b4
73a9aaf
1391702
f3e4894
d8ae436
f69630b
afe8500
d8ae436
 
afe8500
daefa98
afe8500
d40b8f6
 
1391702
 
daefa98
 
 
9cd7770
99d97c8
88dbe5e
daefa98
 
 
e44ec40
b7fea89
d40b8f6
9cd7770
 
d40b8f6
8503034
 
 
 
 
 
 
afe8500
9cd7770
afe8500
8503034
 
d40b8f6
8503034
d40b8f6
afe8500
8503034
 
 
 
 
9cd7770
3fbe701
006d52c
3fbe701
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
import os
import gradio as gr
from groq import Groq
import langdetect
import requests
import random


GROQ_API_KEY = os.getenv("GROQ_API_KEY")
client = Groq(api_key=GROQ_API_KEY)

MODEL_ID = "llama-3.3-70b-versatile"

# Multilingual UI setup
translations = {
    "en": {
        "welcome": "Hey! I'm FlightAI. Tell me your travel plans or pick a button below!",
        "questions": [
            "Trip recommendations",
            "Send me somewhere!",
            "1-week planned vacations"
        ],
        "system_prompt": "You help users plan trips. Keep responses clear. If a user asks specifically about booking a flight, hotel, or reservation, try to find a relevant link, else don't. Be friendly.",
        "input_placeholder": "Type your travel question here..."
    },
    "fr": {
        "welcome": "Salut ! Je suis FlightAI. Dis-moi ton projet de voyage ou choisis un bouton ci-dessous !",
        "questions": [
            "Recommandations de voyage",
            "Envoyez-moi quelque part !",
            "Voyage d'une semaine planifié"
        ],
        "system_prompt": "Vous aidez les utilisateurs à planifier des voyages. Réponses précises. Fournissez un lien si on vous demande spécifiquement une réservation. Si ce n'est pas nécessaire, ne le faites pas. Soyez amical.",
        "input_placeholder": "Tapez votre question de voyage ici..."
    }
}

def detect_language(text):
    """Detects whether the input text is in French, English, or Spanish."""
    try:
        lang = langdetect.detect(text)
        return lang if lang in translations else "en"
    except:
        return "en"

def handle_button_click(button_text, lang):
    """Handles button clicks by sending predefined queries."""
    options = {
        translations[lang]["questions"][0]: "What are the top travel spots right now?",
        translations[lang]["questions"][1]: "Pick a place in the world for me.",
        translations[lang]["questions"][2]: "Plan a 1-week trip for me."
    }
    return options.get(button_text, "")

def chat_with_bot(message, history, lang="en"):
    """Handles user queries and maintains chat memory."""
    
    if lang == "auto":
        lang = detect_language(message)

    # If the message is from a button click, replace it with the corresponding query
    if message in translations[lang]["questions"]:
        message = handle_button_click(message, lang)

    # Initialize history if empty
    if history is None or not isinstance(history, list):
        history = []

    # Add user message to history
    history.append((message, "")) 

    # Call AI model
    response = client.chat.completions.create(
        model=MODEL_ID,
        messages=[{"role": "system", "content": translations[lang]["system_prompt"]}] +
                 [{"role": "user", "content": msg[0]} if msg[1] == "" else {"role": "assistant", "content": msg[1]} for msg in history],
        temperature=0.7,
        max_tokens=1024,
        top_p=1
    )

    bot_reply = response.choices[0].message.content
    history[-1] = (message, bot_reply)  

    return history, ""

def reset_chat():
    return [( "", translations["en"]["welcome"])], ""

    
# Gradio UI
with gr.Blocks(css="""
    body { background-color: #A9B5DF; }
    .gradio-container { background-color: #A9B5DF; }

    .gradio-button {
        background-color: #7886C7 !important;
        color: white !important;
        font-weight: bold !important;
    }

    .gradio-button:hover {
        background-color: #5f6bb4 !important;
    }
    
    #chat-container {
        height: 50vh !important;  
        max-height: 50vh !important;
    }
""") as demo:
    gr.Markdown("""
    # 🌍 ***FlightAI - Your Travel Assistant / Votre Assistant de Voyage*** ✈️
    
    **EN:** Welcome to FlightAI! This chatbot helps you plan your trips effortlessly. You can ask for travel recommendations, request a surprise destination, or get a detailed one-week itinerary. Simply type your query in the chat box or use one of the predefined buttons below.
    
    **FR:** Bienvenue sur FlightAI ! Ce chatbot vous aide à organiser vos voyages facilement. Vous pouvez demander des recommandations de voyage, choisir une destination surprise ou obtenir un itinéraire détaillé pour une semaine. Tapez votre question dans la boîte de dialogue ou utilisez l'un des boutons prédéfinis ci-dessous.
    """)
    
    chatbot = gr.Chatbot(value=[("", translations["en"]["welcome"])], elem_id="chat-container")


    state = gr.State([])  # Store conversation history
    
    with gr.Row():
        btn1 = gr.Button("Trip recommendations / Recommendations de Voyage", elem_classes=["gradio-button"])
        btn2 = gr.Button("Send me somewhere! / Envoyez-moi quelque part!", elem_classes=["gradio-button"])
        btn3 = gr.Button("1 week planned vacation / Voyage d'une semaine planifié", elem_classes=["gradio-button"])

    with gr.Row():
        user_input = gr.Textbox(placeholder="Type your travel question here...", interactive=True, scale=9)
        send_button = gr.Button("Send", scale=1, elem_classes=["gradio-button"])

    with gr.Column(elem_classes=["centered"]):
        reset_button = gr.Button("Reset Chat", elem_classes=["gradio-button"])
        
    def submit_msg(message, history):
        if not message.strip():
            return chat_with_bot("", history)
        
        if not isinstance(history, list):
            history = []
    
        updated_history, _ = chat_with_bot(message, history)
    
        return gr.update(value=updated_history), ""



    def button_click(btn_text, history):
        updated_history, _ = chat_with_bot(btn_text, history)
        return updated_history, ""

    user_input.submit(submit_msg, inputs=[user_input, chatbot], outputs=[chatbot, user_input])
    send_button.click(submit_msg, inputs=[user_input, chatbot], outputs=[chatbot, user_input], queue=False)
    btn1.click(button_click, inputs=[btn1, chatbot], outputs=[chatbot, user_input])
    btn2.click(button_click, inputs=[btn2, chatbot], outputs=[chatbot, user_input])
    btn3.click(button_click, inputs=[btn3, chatbot], outputs=[chatbot, user_input])
    reset_button.click(reset_chat, inputs=[], outputs=[chatbot, user_input])


    gr.HTML("""
        <script>
        function scrollToLatestMessage() {
            let chatContainer = document.getElementById('chat-container');
            if (chatContainer) {
                let messages = chatContainer.getElementsByClassName('message');
                if (messages.length > 0) {
                    let lastMessage = messages[messages.length - 1];
                    lastMessage.scrollIntoView({ behavior: 'smooth', block: 'end' });
                }
            }
        }
    
        function observeChatUpdates() {
            let chatContainer = document.getElementById('chat-container');
            if (chatContainer) {
                let observer = new MutationObserver(scrollToLatestMessage);
                observer.observe(chatContainer, { childList: true, subtree: true });
            }
        }
    
        // Ensure scroll happens every time a new message appears
        document.addEventListener("DOMContentLoaded", observeChatUpdates);
        setInterval(observeChatUpdates, 1000); // Reattach observer in case of UI updates
        </script>
    """)
        
    demo.launch()