""" 🍕 Чат-бот для піцерії "Мама Міа" - Hugging Face версія Використовує файл menu.txt для завантаження меню """ import os import gradio as gr from openai import OpenAI class PizzaChatBot: """Основний клас чат-боту для піцерії""" def __init__(self): """Ініціалізація чат-боту""" # Отримуємо API ключ з змінних середовища (HF Secrets) self.api_key = os.getenv('OPENROUTER_API_KEY') self.base_url = "https://openrouter.ai/api/v1" self.model = "openai/gpt-oss-20b:free" self.restaurant_name = "Піцерія 'Мама Міа'" self.menu = self.load_menu() # Ініціалізація OpenAI клієнта для OpenRouter if self.api_key and self.api_key != 'your_api_key_here': self.client = OpenAI( base_url=self.base_url, api_key=self.api_key ) print(f"✅ {self.restaurant_name} чат-бот ініціалізовано") else: self.client = None print("⚠️ API ключ не налаштовано - використовується демо режим") def load_menu(self): """Завантажує меню з файлу menu.txt""" try: with open('menu.txt', 'r', encoding='utf-8') as file: content = file.read() print(f"✅ Меню завантажено з файлу ({len(content)} символів)") return content except FileNotFoundError: print("❌ Файл menu.txt не знайдено - використовується базове меню") return self.get_fallback_menu() except Exception as e: print(f"❌ Помилка завантаження меню: {e}") return self.get_fallback_menu() def get_fallback_menu(self): """Резервне меню, якщо файл не завантажується""" return """🍕 ПІЦЕРІЯ "МАМА МІА" 🍕 📋 ОСНОВНЕ МЕНЮ: 🍕 Маргарита (30см) - 250 грн 🍕 Пепероні (30см) - 320 грн 🍕 Барбекю Чікен (30см) - 450 грн 🍕 Морська (30см) - 520 грн 🥗 Салат Цезар - 180 грн 🥤 Кока-кола - 35 грн 🍰 Тірамісу - 120 грн ⏰ РЕЖИМ РОБОТИ: 11:00 - 23:00 🚚 ДОСТАВКА: Безкоштовно від 400 грн 📞 ТЕЛЕФОН: +38 (044) 123-45-67""" def get_system_prompt(self): """Створює системний промпт для LLM""" return f"""Ти - дружелюбний помічник піцерії "{self.restaurant_name}". Твоя роль: - Допомагати клієнтам з вибором піци та страв з меню - Надавати точну інформацію про ціни та інгредієнти - Розповідати про режим роботи, доставку та акції - Приймати замовлення та відповідати на запитання - Бути ввічливим, корисним та дружелюбним Важливі правила: - Завжди говори українською мовою - Використовуй емодзі для дружнього спілкування 🍕😊 - Базуйся тільки на інформації з меню - Якщо не знаєш відповіді - направляй до телефону - Пропонуй популярні страви та акції Ось повне меню та інформація про піцерію: {self.menu} Починай кожну розмову привітно та будь готовий допомогти!""" def chat_response(self, message, history): """Обробляє повідомлення користувача та повертає відповідь""" # Якщо немає API ключа - демо режим if not self.client: return self.demo_response(message) try: # Формуємо історію розмови для API messages = [{"role": "system", "content": self.get_system_prompt()}] # Додаємо історію розмови (останні 10 повідомлень для економії токенів) recent_history = history[-10:] if len(history) > 10 else history for human, assistant in recent_history: if human and assistant: messages.append({"role": "user", "content": human}) messages.append({"role": "assistant", "content": assistant}) # Додаємо поточне повідомлення messages.append({"role": "user", "content": message}) # Отримуємо відповідь від LLM через OpenRouter response = self.client.chat.completions.create( model=self.model, messages=messages, max_tokens=800, temperature=0.7 ) return response.choices[0].message.content except Exception as e: print(f"❌ Помилка API: {e}") return f"Вибачте, виникла технічна проблема 😔 Зателефонуйте нам: +38 (044) 123-45-67" def demo_response(self, message): """Демо відповіді без API""" message_lower = message.lower() if any(word in message_lower for word in ['меню', 'піца', 'страв']): return """🍕 Ось наше меню: **ПІЦИ:** • Маргарита (30см) - 250 грн • Пепероні (30см) - 320 грн • Барбекю Чікен (30см) - 450 грн • Морська (30см) - 520 грн Що вас цікавить? 😊""" elif any(word in message_lower for word in ['ціна', 'скільки', 'коштує']): return "💰 Ціни на піци від 250 до 520 грн. Безкоштовна доставка від 400 грн! Що саме вас цікавить?" elif any(word in message_lower for word in ['доставка', 'час', 'швидко']): return "🚚 Доставка 30-45 хвилин. Безкоштовно від 400 грн, інакше 50 грн. Працюємо з 11:00 до 23:00!" elif any(word in message_lower for word in ['телефон', 'контакт', 'адреса']): return "📞 Телефон: +38 (044) 123-45-67\n📍 Адреса: вул. Хрещатик, 25, Київ\n⏰ Режим: 11:00 - 23:00" else: return f"""Привіт! 👋 Я помічник піцерії "Мама Міа". Можу допомогти з: 🍕 Меню та цінами 📞 Інформацією про доставку ⏰ Режимом роботи 📋 Оформленням замовлення Що вас цікавить? 😊 *Примітка: Зараз працює демо-режим. Для повного функціоналу потрібен API ключ.*""" def create_interface(self): """Створює Gradio інтерфейс для Hugging Face""" # Кастомні стилі custom_css = """ .gradio-container { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } .header-banner { background: linear-gradient(135deg, #ff6b6b, #feca57, #48cab2); border-radius: 15px; padding: 25px; text-align: center; margin-bottom: 20px; box-shadow: 0 4px 15px rgba(0,0,0,0.1); } .info-card { background-color: #f8f9fa; border-radius: 10px; padding: 15px; margin-top: 15px; border-left: 4px solid #ff6b6b; } """ with gr.Blocks( css=custom_css, title=f"{self.restaurant_name} - AI Чат-бот", theme=gr.themes.Soft() ) as interface: # Заголовок з градієнтом gr.HTML(f"""
""") # Основний чат chatbot = gr.Chatbot( height=500, placeholder="🍕 Привіт! Що вас цікавить сьогодні?", label="💬 Розмова з піца-ботом", avatar_images=("👤", "🤖") ) # Поле вводу та кнопка відправки with gr.Row(): msg = gr.Textbox( placeholder="Введіть ваше повідомлення тут...", label="", lines=2, scale=4, container=False ) send_btn = gr.Button( "Відправити 📤", variant="primary", scale=1, size="lg" ) # Додаткові кнопки with gr.Row(): clear_btn = gr.Button("Очистити чат 🗑️", variant="secondary") # Швидкі запитання gr.Examples( examples=[ "Покажіть меню піци", "Яка найпопулярніша піца?", "Скільки коштує доставка?", "Режим роботи піцерії", "Хочу замовити 2 піци Маргарита", "Які у вас акції?" ], inputs=msg, label="💡 Швидкі запитання (натисніть для вибору):" ) # Інформаційна картка gr.HTML("""