Spaces:
Sleeping
Sleeping
| """ | |
| 🍕 Чат-бот для піцерії "Мама Міа" - 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""" | |
| <div class="header-banner"> | |
| <h1 style="color: white; margin: 0; font-size: 2.5em;">🍕 {self.restaurant_name}</h1> | |
| <h3 style="color: white; margin: 15px 0; font-size: 1.3em;"> | |
| Привіт! Я AI-помічник, готовий допомогти з замовленням 😊 | |
| </h3> | |
| <p style="color: white; margin: 0; font-size: 1.1em;"> | |
| Запитайте про меню, ціни, доставку або зробіть замовлення! | |
| </p> | |
| </div> | |
| """) | |
| # Основний чат | |
| 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(""" | |
| <div class="info-card"> | |
| <h4 style="margin-top: 0; color: #333;">📋 Основна інформація:</h4> | |
| <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 15px;"> | |
| <div> | |
| <strong>📍 Адреса:</strong><br> | |
| вул. Хрещатик, 25, Київ | |
| </div> | |
| <div> | |
| <strong>📞 Телефон:</strong><br> | |
| +38 (044) 123-45-67 | |
| </div> | |
| <div> | |
| <strong>⏰ Режим роботи:</strong><br> | |
| Щодня 11:00 - 23:00 | |
| </div> | |
| <div> | |
| <strong>🚚 Доставка:</strong><br> | |
| Безкоштовно від 400 грн | |
| </div> | |
| </div> | |
| </div> | |
| """) | |
| # Обробники подій | |
| def user_message(message, history): | |
| """Додає повідомлення користувача до чату""" | |
| if message.strip(): | |
| return "", history + [[message, None]] | |
| return message, history | |
| def bot_response(history): | |
| """Генерує відповідь бота""" | |
| if history and history[-1][0]: | |
| message = history[-1][0] | |
| response = self.chat_response(message, history[:-1]) | |
| history[-1][1] = response | |
| return history | |
| def clear_chat(): | |
| """Очищає історію чату""" | |
| return [] | |
| # Прив'язування подій | |
| msg.submit( | |
| user_message, | |
| [msg, chatbot], | |
| [msg, chatbot], | |
| queue=False | |
| ).then( | |
| bot_response, | |
| chatbot, | |
| chatbot | |
| ) | |
| send_btn.click( | |
| user_message, | |
| [msg, chatbot], | |
| [msg, chatbot], | |
| queue=False | |
| ).then( | |
| bot_response, | |
| chatbot, | |
| chatbot | |
| ) | |
| clear_btn.click(clear_chat, None, chatbot, queue=False) | |
| return interface | |
| def main(): | |
| """Головна функція для запуску на Hugging Face Spaces""" | |
| print("🚀 Ініціалізація піца-чат-боту для Hugging Face...") | |
| # Створення екземпляру чат-боту | |
| bot = PizzaChatBot() | |
| # Створення інтерфейсу | |
| interface = bot.create_interface() | |
| print("✅ Інтерфейс створено, запускаємо...") | |
| return interface | |
| # Запуск для Hugging Face Spaces | |
| if __name__ == "__main__": | |
| demo = main() | |
| demo.launch( | |
| server_name="0.0.0.0", # Для Hugging Face | |
| server_port=7860, # Стандартний порт HF | |
| share=False, # HF автоматично надає публічний доступ | |
| debug=False # Вимкнути debug в продакшені | |
| ) |