demo-aiagent / app.py
diogofpedrosa's picture
Update app.py
625836b verified
Raw
History Blame Contribute Delete
14.4 kB
import os
import json
import gradio as gr
from dotenv import load_dotenv
import openai
from datetime import datetime
load_dotenv()
client = openai.OpenAI(
api_key=os.environ.get("GROQ_API_KEY"),
base_url="https://api.groq.com/openai/v1"
)
# Hotel information
HOTEL_INFO = """
**AP Hotel & Resorts**
☎️ **Contacto**: +351 289 540 100 (Chamada para a Rede Fixa Nacional) | book@ap-hotelsresorts.com
** Hoteis do grupo **:
- AP Adriana Beach Resort | Albufeira
- AP Cabanas Beach & Nature | Tavira
- AP Eva Senses | Faro
- AP Oriental Beach | Portimão
- AP Maria Nova Lounge | Tavira
- AP Victoria Sports & Beach | Albufeira
- AP Dona Aninhas | Viana do Castelo
- AP Lago Montargil Conference & Spa | Montargil
- AP Sines | Costa Alentejana
🏨 **Quartos Disponiveis**:
- Quantidade: 1, 2 ou 3.
- Quantos Adultos: 1 a 8.
- Quantas Crianças: 0 a 4.
- Quantos Bébes: 0 a 2.
**Tipos de Reservas**
- Alojamento e Pequeno Almoço.
- Meia-Pensão (includes Breakfast and Dinner (Beverages not included). Set Menu (Chef's Suggestion)).
- Pensão-Completa (includes breakfast, lunch, and dinner (drinks not included). Set Menu (chef's suggestion)).
🎯 **Serviços e Comodidades**:
- Wi-Fi grátis em todo o resort
- 2 piscinas exteriores para adultos
- 2 piscinas exteriores para crianças
- Acesso direto à praia
- Campo de futebol, basquete, tiro ao arco, vólei de praia, ténis, minigolfe e petanca.
- Ginásio com acesso grátis
- SPA
- Música ao vivo
- Espetáculos
- Clube infantil
⏰ **Horários**:
- Check-in: 14:00
- Check-out: 11h00
- Pequeno-almoço: 07:30 - 10:30
🐕 **Animais**: Aceites em certas áreas de alguns hóteis.
"""
CHATBOT_SYSTEM_PROMPT = f"""
És um agente de Inteligência Aritificial do grupo AP Hotels & Resorts, especializado em ajudar clientes com informações e reservas.
*** Princípio Fundamental e Regras Inquebráveis ***
1. **REGRA DE OURO: A tua única fonte de verdade é a "Informação do Hotel" fornecida abaixo de `Informação do Hotw`.** És estritamente e absolutamente proibido de usar qualquer conhecimento externo ou pré-treinado.
2. **SE A RESPOSTA NÃO ESTIVER NO CONTEXTO:** Se um cliente perguntar algo cuja resposta não se encontra explicitamente no `{{context}}`, a tua resposta OBRIGATÓRIA deve ser uma variação de: "Peço desculpa, mas não encontro essa informação específica nos detalhes que tenho sobre o hotel. Posso ajudar com outra questão, talvez sobre os nossos tipos de quarto ou regimes de pensão?" Nunca inventes ou faças suposições.
3. **NÃO FAÇAS PROMESSSAS EXTERNAS:** Não menciones serviços, parcerias ou eventos que não estejam listados no `{{context}}`.
**Informação do Hotel**:
{{context}}
**Tuas Responsabilidades**:
1. Responder a perguntas sobre o hotel, serviços, etc.
2. Ajudar com simulações de reservas (sempre confirma disponibilidade primeiro)
3. Fornecer informações sobre preços, tipos de quartos e comodidades
4. Ser cordial, profissional e prestável em português europeu
5. Se não souberes algo, admite e oferece alternativas
**Formato de Conversação**:
- Usa emojis ocasionalmente para tornar a conversa mais amigável
- Quando falares de reservas, pede sempre: datas, tipo de quarto, número de pessoas
- Se o cliente quiser fazer uma reserva, recolhe TODOS os dados necessários antes de confirmar:
* Nome completo
* Email
* Telefone
* NIF ou CC
* Hotel
* Data check-in e check-out
* Numero de noites
* Quantas pessoas
* Número de crianças
* Pedidos especiais (opcional)
* Board (esclarecendo sempre os 3 tipos de board)
**Regras Importantes**:
- Baseia as tuas respostas no contexto fornecido acima
- Se perguntarem sobre disponibilidade, simula uma verificação e confirma (para fins de demo)
- Calcula automaticamente o número de noites e o preço total
- A data atual é {datetime.now().strftime('%d de %B de %Y')}
- Oferece sempre upgrades ou serviços adicionais quando relevante
**Tom**: Profissional, caloroso, prestável e eficiente.
"""
WELCOME_MESSAGE = """👋 **Bem-vindo ao AP Hotel & Resorts!**
Sou o teu agente de IA e estou aqui para ajudar-te com:
• 🏨 Informações sobre quartos e preços
• 📅 Disponibilidade e reservas
• 🍽️ Restaurantes e serviços
• 🎯 Comodidades do hotel
**Como posso ajudá-lo hoje?**"""
def chat_with_bot(message, history):
"""Process chat messages with the hotel bot"""
if not message or message.strip() == "":
return history
try:
context = HOTEL_INFO
# Build conversation history
messages = [
{"role": "system", "content": CHATBOT_SYSTEM_PROMPT.format(context=context)}
]
# Add chat history (skip the welcome message)
for user_msg, assistant_msg in history:
if user_msg:
messages.append({"role": "user", "content": user_msg})
messages.append({"role": "assistant", "content": assistant_msg})
# Add current message
messages.append({"role": "user", "content": message})
# Get response from LLM
response = client.chat.completions.create(
model="openai/gpt-oss-120b",
messages=messages,
temperature=0.4,
max_tokens=1000
)
bot_response = response.choices[0].message.content
history.append((message, bot_response))
return history
except Exception as e:
error_message = f"❌ Desculpe, ocorreu um erro: {str(e)}"
history.append((message, error_message))
return history
# Create Gradio Interface
with gr.Blocks(
theme=gr.themes.Ocean(),
title="AP Hotel & Resorts",
css="""
.main-title {text-align: center; margin-bottom: 0.5rem;}
.subtitle {
text-align: center;
margin: 0 auto 0 auto;
font-size: 1.05em;
line-height: 1.6;
width: 80%;
color: var(--body-text-color);
}
.logo-image {
margin: 0 auto;
display: block;
}
.chatbot-container {
border-radius: 12px;
}
.info-box {
background-color: #f0f4f8;
padding: 1.5rem;
border-radius: 12px;
border-left: 4px solid #8b7a77;
margin: 1rem 0;
}
.info-box h3 {
margin-top: 0;
color: #8b7a77;
}
/* Custom button colors - More specific selectors */
.primary, button.primary, .gradio-button.primary {
background: #8b7a77 !important;
background-color: #8b7a77 !important;
border-color: #8b7a77 !important;
color: white !important;
}
.primary:hover, button.primary:hover, .gradio-button.primary:hover {
background: #7a6966 !important;
background-color: #7a6966 !important;
border-color: #7a6966 !important;
}
.secondary, button.secondary, .gradio-button.secondary {
background: #8b7a77 !important;
background-color: #8b7a77 !important;
border-color: #8b7a77 !important;
color: white !important;
}
.secondary:hover, button.secondary:hover, .gradio-button.secondary:hover {
background: #7a6966 !important;
background-color: #7a6966 !important;
border-color: #7a6966 !important;
}
/* Targeting all buttons to ensure color change */
button[variant="primary"] {
background: #8b7a77 !important;
background-color: #8b7a77 !important;
border-color: #8b7a77 !important;
}
button[variant="secondary"] {
background: #8b7a77 !important;
background-color: #8b7a77 !important;
border-color: #8b7a77 !important;
}
"""
) as demo:
# Header
logo = gr.Image(
value="logo-ap.png",
label="",
show_label=False,
show_download_button=False,
show_share_button=False,
show_fullscreen_button=False,
height=100,
container=False,
elem_classes="logo-image"
)
gr.Markdown("# 🏨 Agente de IA", elem_classes="main-title")
gr.Markdown(
"""
Este é um agente de inteligência artificial demonstrativo. Ele utiliza a informação disponível sobre o hotel para responder de forma inteligente às tuas perguntas. Testa as suas capacidades!
""",
elem_classes="subtitle"
)
# Tabs
with gr.Tabs():
# Tab 1: Chatbot
with gr.Tab("💬 Agente de IA"):
chatbot = gr.Chatbot(
height=500,
label="",
avatar_images=("logo-ap.png", "logo-ap.png"),
type="tuples",
elem_classes="chatbot-container",
show_label=False,
value=[(None, WELCOME_MESSAGE)]
)
with gr.Row():
msg = gr.Textbox(
placeholder="💬 Escreve a tua mensagem aqui...",
show_label=False,
scale=9,
container=False
)
submit_btn = gr.Button("Enviar", variant="primary", scale=1, elem_classes="primary")
clear_btn = gr.Button("🗑️ Limpar Conversa", variant="secondary", size="sm", elem_classes="secondary")
# Tab 2: Hotel Information
with gr.Tab("📋 Informações do Hotel"):
gr.Markdown("## 🏨 AP Hotel & Resorts")
gr.Markdown("""
<div class="info-box">
<h3>📍 Contacto</h3>
<p><strong>Telefone:</strong> +351 289 540 100 (Chamada para a Rede Fixa Nacional)</p>
<p><strong>Email:</strong> book@ap-hotelsresorts.com</p>
</div>
""")
gr.Markdown("""
<div class="info-box">
<h3>🏨 Hotéis do Grupo</h3>
<p>🏖️ <strong>AP Adriana Beach Resort</strong> | Albufeira</p>
<p>🌿 <strong>AP Cabanas Beach & Nature</strong> | Tavira</p>
<p>✨ <strong>AP Eva Senses</strong> | Faro</p>
<p>🌊 <strong>AP Oriental Beach</strong> | Portimão</p>
<p>🎭 <strong>AP Maria Nova Lounge</strong> | Tavira</p>
<p>⚽ <strong>AP Victoria Sports & Beach</strong> | Albufeira</p>
<p>🏰 <strong>AP Dona Aninhas</strong> | Viana do Castelo</p>
<p>🏞️ <strong>AP Lago Montargil Conference & Spa</strong> | Montargil</p>
<p>🌅 <strong>AP Sines</strong> | Costa Alentejana</p>
</div>
""")
gr.Markdown("""
<div class="info-box">
<h3>🏨 Quartos Disponíveis</h3>
<p><strong>Quantidade:</strong> 1, 2 ou 3 quartos</p>
<p><strong>Adultos:</strong> 1 a 8 pessoas</p>
<p><strong>Crianças:</strong> 0 a 4</p>
<p><strong>Bebés:</strong> 0 a 2</p>
</div>
""")
gr.Markdown("""
<div class="info-box">
<h3>🍽️ Tipos de Reservas</h3>
<p>🛏️ <strong>Alojamento e Pequeno Almoço</strong><br>
<small>Inclui pequeno-almoço</small></p>
<p>🍴 <strong>Meia Pensão</strong><br>
<small>Inclui pequeno-almoço e jantar (bebidas não incluídas). Menu do dia (sugestão do Chef)</small></p>
<p>🍽️ <strong>Pensão Completa</strong><br>
<small>Inclui pequeno-almoço, almoço e jantar (bebidas não incluídas). Menu do dia (sugestão do Chef)</small></p>
</div>
""")
gr.Markdown("""
<div class="info-box">
<h3>⏰ Horários</h3>
<p><strong>Check-in:</strong> 14:00</p>
<p><strong>Check-out:</strong> 11:00</p>
<p><strong>Pequeno-almoço:</strong> 07:30 - 10:30</p>
</div>
""")
gr.Markdown("""
<div class="info-box">
<h3>🎯 Serviços e Comodidades</h3>
<p>📶 Wi-Fi grátis em todo o resort</p>
<p>🏊 2 piscinas exteriores para adultos</p>
<p>👶 2 piscinas exteriores para crianças</p>
<p>🏖️ Acesso direto à praia</p>
<p>⚽ Campo de futebol</p>
<p>🏀 Basquete</p>
<p>🎯 Tiro ao arco</p>
<p>🏐 Vólei de praia</p>
<p>🎾 Ténis</p>
<p>⛳ Minigolfe</p>
<p>🎱 Petanca</p>
<p>🏋️ Ginásio com acesso grátis</p>
<p>💆 SPA</p>
<p>🎵 Música ao vivo</p>
<p>🎭 Espetáculos</p>
<p>🎪 Clube infantil</p>
</div>
""")
gr.Markdown("""
<div class="info-box">
<h3>🐕 Política de Animais</h3>
<p>Animais aceites em certas áreas de alguns hotéis.</p>
<p><small>* Consulte condições específicas na receção do hotel escolhido</small></p>
</div>
""")
gr.HTML("""
<div style='
text-align:center;
padding:20px;
margin-top:30px;
font-size:0.95em;
color:#555;
border-top:1px solid #ddd;
'>
© 2025 Timestamp — Todos os direitos reservados
</div>
""")
# Event handlers - Submit message
msg.submit(
chat_with_bot,
[msg, chatbot],
[chatbot]
).then(
lambda: "",
None,
[msg]
)
submit_btn.click(
chat_with_bot,
[msg, chatbot],
[chatbot]
).then(
lambda: "",
None,
[msg]
)
clear_btn.click(lambda: [(None, WELCOME_MESSAGE)], None, chatbot)
if __name__ == "__main__":
demo.launch(share=True)