diff --git "a/app.py" "b/app.py" new file mode 100644--- /dev/null +++ "b/app.py" @@ -0,0 +1,2084 @@ +import gradio as gr +import requests +import os +import json +import pandas as pd +import time +from langchain.schema import SystemMessage +from langchain_community.chat_models.gigachat import GigaChat +from openpyxl import load_workbook +import base64 +from together import Together +import pymorphy2 +import re +import string + +morph = pymorphy2.MorphAnalyzer() + +# Установка ключа API для OpenAI, GigaChat и Mistral +openai_api_key = os.getenv('GPT_KEY') +gc_key = os.getenv('GC_KEY') +token = os.getenv('GITHUB_TOKEN') +TOGETHER_API_KEY = os.getenv('TOGETHER_API_KEY') + +# Инициализация клиента для Together +client = Together(api_key=TOGETHER_API_KEY) + +# Авторизация в сервисе GigaChat +chat_pro = GigaChat(credentials=gc_key, model='GigaChat-Pro', max_tokens=68, temperature=1, verify_ssl_certs=False) +chat_lite = GigaChat(credentials=gc_key, model='GigaChat', max_tokens=68, temperature=1, verify_ssl_certs=False) +chat_plus = GigaChat(credentials=gc_key, model='GigaChat-Plus', max_tokens=68, temperature=1, verify_ssl_certs=False) + +# Экземпляры моделей для объяснений +chat_pro_explain = GigaChat(credentials=gc_key, model='GigaChat-Pro', temperature=1, verify_ssl_certs=False) +chat_lite_explain = GigaChat(credentials=gc_key, model='GigaChat', temperature=1, verify_ssl_certs=False) +chat_plus_explain = GigaChat(credentials=gc_key, model='GigaChat-Plus', temperature=1, verify_ssl_certs=False) + +# Загрузка данных из Excel-файла +try: + data = pd.read_excel('Признаки.xlsx', sheet_name=None) +except Exception as e: + print(f"Ошибка при загрузке Excel-файла: {e}") + data = {} + +# Создание списка признаков и их значений +features = {} +for sheet_name, df in data.items(): + try: + if sheet_name == "Пол Поколение Психотип": + # Создаем словарь, где ключи — это кортежи (Пол, Поколение, Психотип), а значения — инструкции + features[sheet_name] = df.set_index(['Пол', 'Поколение', 'Психотип'])['Инструкция'].to_dict() + else: + features[sheet_name] = df.set_index(df.columns[0]).to_dict()[df.columns[1]] + except Exception as e: + print(f"Ошибка при обработке данных листа {sheet_name}: {e}") + features[sheet_name] = {} + + +current_request_index = -1 # Изначально указывает на последний запрос + + +def correct_dash_usage(text): + # Step 1: Replace any dash with long dash if surrounded by spaces + text = re.sub(r'\s[-–—]\s', ' — ', text) + + # Step 2: Replace any dash with short dash if surrounded by numbers without spaces + text = re.sub(r'(?<=\d)[-–—](?=\d)', '–', text) + + # Step 3: Replace any dash with hyphen if surrounded by letters or a combination of letters and digits + text = re.sub(r'(?<=[a-zA-Zа-яА-Я0-9])[-–—](?=[a-zA-Zа-яА-Я0-9])', '-', text) + + return text + + +def save_user_request_to_github(description, advantages, key_message, approach, personalization_params): + + global current_request_index # Используем глобальную переменную + current_request_index = -1 # Сбрасываем позицию к последнему запросу + + # Собираем все данные в один словарь + data_to_save = { + "description": description, + "advantages": advantages, + "key_message": key_message, + "approach": approach, + "personalization_params": personalization_params, + "timestamp": time.time() + } + + # Преобразуем контент в JSON-строку и кодируем в base64 + file_content_encoded = base64.b64encode(json.dumps(data_to_save).encode()).decode() + + # Параметры для GitHub API + repo = "fruitpicker01/Storage_dev" + path = f"user_request_{int(time.time())}.json" + url = f"https://api.github.com/repos/{repo}/contents/{path}" + headers = { + "Authorization": f"token {token}", + "Content-Type": "application/json" + } + data = { + "message": f"Добавлен новый файл {path}", + "content": file_content_encoded + } + + # Отправка POST-запроса на GitHub API для создания файла в репозитории + response = requests.put(url, headers=headers, data=json.dumps(data)) + if response.status_code == 201: + print("Данные успешно сохранены на GitHub") + else: + print(f"Ошибка при сохранении данных на GitHub: {response.status_code} {response.text}") + +def load_previous_user_request_from_github(): + global current_request_index # Используем глобальную переменную + + repo = "fruitpicker01/Storage_dev" + url = f"https://api.github.com/repos/{repo}/contents" + headers = { + "Authorization": f"token {token}", + "Content-Type": "application/json" + } + + # Получаем список файлов в репозитории + response = requests.get(url, headers=headers) + if response.status_code == 200: + files = response.json() + json_files = [file for file in files if file['name'].startswith("user_request_")] + + if not json_files: + print("Нет сохраненных запросов.") + return "", "", "", "", "", "", "", "", "", "", None, None, None, None, None, None + + # Определяем новый индекс для загрузки предыдущего файла + current_request_index -= 1 + + # Если достигли начала списка, остаёмся на первой записи + if abs(current_request_index) > len(json_files): + current_request_index = -len(json_files) + + # Находим файл с нужным индексом + target_file = json_files[current_request_index] + file_url = target_file['download_url'] + + # Загружаем и декодируем содержимое файла + file_response = requests.get(file_url) + if file_response.status_code == 200: + data = json.loads(file_response.text) + description = data.get('description', "") + advantages = data.get('advantages', "") + key_message = data.get('key_message', "") # Load key message + approach = data.get('approach', "") # Load approach + personalization_params = data.get('personalization_params', [None] * 6) # Убедитесь, что размер списка соответствует количеству полей + + # Возвращаем данные по отдельности для каждого компонента Gradio + return description, advantages, key_message, approach, *personalization_params + else: + print(f"Ошибка при загрузке файла: {file_response.status_code}") + return "", "", "", "", "", "", "", "", "", "", None, None, None, None, None, None + else: + print(f"Ошибка при обращении к GitHub: {response.status_code}") + return "", "", "", "", "", "", "", "", "", "", None, None, None, None, None, None + + +# Функция для генерации стандартного промпта +def generate_standard_prompt(description, advantages, key_message, approach, *selected_values): + + if approach == "Призыв к действию": + prompt = "Сгенерируй смс-сообщение для клиента. Начни сообщение с призыва к действию с продуктом.\n" + elif approach == "Указание на пользу": + prompt = "Сгенерируй смс-сообщение для клиента. Начни сообщение с указания на пользу продукта. Используй глагол в побудительном наклонении.\n" + elif approach == "Вопрос": + prompt = "Сгенерируй смс-сообщение для клиента. Начни сообщение с вопроса, который указывает на пользу продукта для клиента.\n" + elif approach == "None": + prompt = "Сгенерируй смс-сообщение для клиента.\n" + + + prompt += ( + f"Описание предложения: {description}\n" + f"Преимущества: {advantages}\n" + "В тексте смс запрещено использование:\n" + "- Запрещенные слова: № один, номер один, № 1, вкусный, дешёвый, продукт, спам, доступный, банкротство, долги, займ, срочно, сейчас, лучший, главный, номер 1, гарантия, успех, лидер;\n" + "- Обращение к клиенту;\n" + "- Приветствие клиента;\n" + "- Обещания и гарантии;\n" + "- Использовать составные конструкции из двух глаголов;\n" + "- Причастия и причастные обороты;\n" + "- Деепричастия и деепричастные обороты;\n" + "- Превосходная степень прилагательных;\n" + "- Страдательный залог;\n" + "- Порядковые числительные от 10 прописью;\n" + "- Цепочки с придаточными предложениями;\n" + "- Разделительные повторяющиеся союзы;\n" + "- Вводные конструкции;\n" + "- Усилители;\n" + "- Паразиты времени;\n" + "- Несколько существительных подряд, в том числе отглагольных;\n" + "- Производные предлоги;\n" + "- Сложные предложения, в которых нет связи между частями;\n" + "- Сложноподчинённые предложения;\n" + "- Даты прописью;\n" + "- Близкие по смыслу однородные члены предложения;\n" + "- Шокирующие, экстравагантные, кликбейтные фразы;\n" + "- Абстрактные заявления без поддержки фактами и отсутствие доказательства пользы для клиента;\n" + "- Гарантирующие фразы;\n" + "- Узкоспециализированные термины;\n" + "- Фразы, способные создать двойственное ощущение, обидеть;\n" + "- Речевые клише, рекламные штампы, канцеляризмы;\n" + "Убедись, что в готовом тексте до 250 знаков с пробелами.\n" + ) + + if approach == "Призыв к действию": + prompt += "Убедись, что готовый текст начинается с призыва к действию с продуктом.\n" + elif approach == "Указание на пользу": + prompt += "Убедись, что готовый текст начинается с указания на пользу продукта и использования глагола в побудительном наклонении.\n" + elif approach == "Вопрос": + prompt += "Убедись, что готовый текст начинается с вопроса, который указывает на пользу продукта для клиента.\n" + elif approach == "None": + prompt += "" + + if key_message.strip(): + prompt += f"Убедись, что в готовом тексте есть следующая ключевая информация: {key_message.strip()}" + + return prompt + +# Функции для генерации сообщений +def generate_message_gpt4o(prompt): + try: + headers = { + "Content-Type": "application/json", + "Authorization": f"Bearer {openai_api_key}" + } + data = { + "model": "chatgpt-4o-latest", + "messages": [{"role": "system", "content": prompt}], + "max_tokens": 101, + "temperature": 1.1 + } + response = requests.post("https://api.openai.com/v1/chat/completions", json=data, headers=headers) + response_data = response.json() + return response_data["choices"][0]["message"]["content"].strip() + except Exception as e: + return f"Ошибка при обращении к ChatGPT-4o-Latest: {e}" + +def clean_message(message): + # Если сообщение не заканчивается на точку, восклицательный знак или вопросительный знак, обрезаем его до последнего такого знака + if not message.endswith(('.', '!', '?')): + last_period = max(message.rfind('.'), message.rfind('!'), message.rfind('?')) + if last_period != -1: + message = message[:last_period + 1] + return message + +# Обновленные функции генерации сообщений с учетом обрезки незаконченных предложений +def generate_message_gigachat_pro(prompt): + try: + messages = [SystemMessage(content=prompt)] + res = chat_pro(messages) + cleaned_message = clean_message(res.content.strip()) + return cleaned_message + except Exception as e: + return f"Ошибка при обращении к GigaChat-Pro: {e}" + +def generate_message_gigachat_lite(prompt): + try: + time.sleep(2) + messages = [SystemMessage(content=prompt)] + res = chat_lite(messages) + cleaned_message = clean_message(res.content.strip()) + return cleaned_message + except Exception as e: + return f"Ошибка при обращении к GigaChat-Lite: {e}" + +def generate_message_gigachat_plus(prompt): + try: + time.sleep(2) + messages = [SystemMessage(content=prompt)] + res = chat_plus(messages) + cleaned_message = clean_message(res.content.strip()) + return cleaned_message + except Exception as e: + return f"Ошибка при обращении к GigaChat-Plus: {e}" + +def generate_message_meta_llama_3_1_405b(prompt): + try: + response = client.chat.completions.create( + model="meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo", + messages=[{"role": "user", "content": prompt}], + max_tokens=74, + temperature=0.8 + ) + cleaned_message = clean_message(response.choices[0].message.content.strip()) + return cleaned_message + except Exception as e: + return f"Ошибка при обращении к Meta-Llama-3.1-405B: {e}" + +def generate_message_gpt4o_with_retry(prompt): + for _ in range(10): # Максимум 10 попыток + message = generate_message_gpt4o(prompt) + if len(message) <= 250: + return correct_dash_usage(message) + return message # Возвращаем последнее сгенерированное сообщение, если все попытки не удались + +def generate_message_gigachat_pro_with_retry(prompt): + for _ in range(10): + message = generate_message_gigachat_pro(prompt) + if len(message) <= 250: + return correct_dash_usage(message) + return message + +def generate_message_gigachat_lite_with_retry(prompt): + for _ in range(10): + message = generate_message_gigachat_lite(prompt) + if len(message) <= 250: + return correct_dash_usage(message) + return message + +def generate_message_gigachat_plus_with_retry(prompt): + for _ in range(10): + message = generate_message_gigachat_plus(prompt) + if len(message) <= 250: + return correct_dash_usage(message) + return message + +def generate_message_meta_llama_3_1_405b_with_retry(prompt): + for _ in range(10): + message = generate_message_meta_llama_3_1_405b(prompt) + if len(message) <= 250: + return correct_dash_usage(message) + return message + + +def generate_messages(description, advantages, key_message, approach, *selected_values): + + save_user_request_to_github(description, advantages, key_message, approach, selected_values) + + standard_prompt = generate_standard_prompt(description, advantages, key_message, approach, *selected_values) + + results = { + "prompt": standard_prompt, + "gigachat_pro": None, + "gigachat_lite": None, + "gigachat_plus": None, + "gpt4o": None, + "meta_llama_3_1_405b": None + } + + yield results["prompt"], "", "", "", "", "" + + # Generating messages using existing models (as before) + results["gigachat_pro"] = generate_message_gigachat_pro_with_retry(standard_prompt) + gigachat_pro_length = len(results["gigachat_pro"]) + gigachat_pro_display = f"{results['gigachat_pro']}\n\n------\nКоличество знаков: {gigachat_pro_length}" + yield results["prompt"], gigachat_pro_display, "", "", "", "" + + results["gigachat_lite"] = generate_message_gigachat_lite_with_retry(standard_prompt) + gigachat_lite_length = len(results["gigachat_lite"]) + gigachat_lite_display = f"{results['gigachat_lite']}\n\n------\nКоличество знаков: {gigachat_lite_length}" + yield results["prompt"], gigachat_pro_display, gigachat_lite_display, "", "", "" + + time.sleep(2) + + results["gigachat_plus"] = generate_message_gigachat_plus_with_retry(standard_prompt) + gigachat_plus_length = len(results["gigachat_plus"]) + gigachat_plus_display = f"{results['gigachat_plus']}\n\n------\nКоличество знаков: {gigachat_plus_length}" + yield results["prompt"], gigachat_pro_display, gigachat_lite_display, gigachat_plus_display, "", "" + + time.sleep(2) + + results["gpt4o"] = generate_message_gpt4o_with_retry(standard_prompt) + gpt4o_length = len(results["gpt4o"]) + gpt4o_display = f"{results['gpt4o']}\n\n------\nКоличество знаков: {gpt4o_length}" + yield results["prompt"], gigachat_pro_display, gigachat_lite_display, gigachat_plus_display, gpt4o_display, "" + + time.sleep(2) + + results["meta_llama_3_1_405b"] = generate_message_meta_llama_3_1_405b_with_retry(standard_prompt) + meta_llama_405b_length = len(results["meta_llama_3_1_405b"]) + meta_llama_405b_display = f"{results['meta_llama_3_1_405b']}\n\n------\nКоличество знаков: {meta_llama_405b_length}" + yield results["prompt"], gigachat_pro_display, gigachat_lite_display, gigachat_plus_display, gpt4o_display, meta_llama_405b_display + + time.sleep(2) + + return results + + +# Функция для генерации персонализированного промпта +def generate_personalization_prompt(key_message, approach, *selected_values): + prompt = "Адаптируй, не превышая длину сообщения в 250 знаков с пробелами, текст с учетом следующих особенностей:\n" + gender, generation, psychotype = selected_values[0], selected_values[1], selected_values[2] + combined_instruction = "" + additional_instructions = "" + + print(f"Выбранные значения: Пол={gender}, Поколение={generation}, Психотип={psychotype}") + + # Проверяем, выбраны ли ��се три параметра: Пол, Поколение, Психотип + if gender and generation and psychotype: + # Получаем данные с листа "Пол Поколение Психотип" + sheet = features.get("Пол Поколение Психотип", {}) + + # Ищем ключ, соответствующий комбинации "Пол", "Поколение", "Психотип" + key = (gender, generation, psychotype) + if key in sheet: + combined_instruction = sheet[key] + print(f"Найдена комбинированная инструкция: {combined_instruction}") + else: + print(f"Комбинированная инструкция для ключа {key} не найдена.") + + # Если не найдена комбинированная инструкция, добавляем индивидуальные инструкции + if not combined_instruction: + print("Добавляем индивидуальные инструкции для Пол, Поколение, Психотип.") + for i, feature in enumerate(["Пол", "Поколение", "Психотип"]): + if selected_values[i]: + try: + instruction = features[feature][selected_values[i]] + additional_instructions += f"{instruction}\n" + print(f"Добавлена инструкция из {feature}: {instruction}") + except KeyError: + return f"Ошибка: выбранное значение {selected_values[i]} не найдено в данных." + + # Добавляем инструкции для остальных параметров (например, Отрасль) + for i, feature in enumerate(features.keys()): + if feature not in ["Пол", "Поколение", "Психотип", "Пол Поколение Психотип"]: + if i < len(selected_values) and selected_values[i]: + try: + instruction = features[feature][selected_values[i]] + additional_instructions += f"{instruction}\n" + print(f"Добавлена инструкция из {feature}: {instruction}") + except KeyError: + return f"Ошибка: выбранное значение {selected_values[i]} не найдено в данных." + + # Формируем итоговый промпт + if combined_instruction: + prompt += combined_instruction # Добавляем комбинированную инструкцию, если она есть + if additional_instructions: + prompt += additional_instructions # Добавляем остальные инструкции + + prompt += "Убедись, что в готовом тексте до 250 знаков с пробелами.\n" + + if approach == "Призыв к действию": + prompt += "Убедись, что готовый текст начинается с призыва к действию с продуктом.\n" + elif approach == "Указание на пользу": + prompt += "Убедись, что готовый текст начинается с указания на пользу продукта и использования глагола в побудительном наклонении.\n" + elif approach == "Вопрос": + prompt += "Убедись, что готовый текст начинается с вопроса, который указывает на пользу продукта для клиента.\n" + elif approach == "None": + prompt += "" + + prompt += f"Убедись, что в готовом тексте есть следующая ключевая информация: {key_message.strip()}" + + if "призыва к действию" in prompt and "минимум прямых призывов к действию" in prompt: + prompt = re.sub(r"Убедись, что готовый текст начинается с призыва к действию с продуктом.\n", "", prompt) + + return prompt.strip() + + +# Функция для выполнения персонализации на основе сгенерированного промпта и сообщения +def perform_personalization(standard_message, personalization_prompt): + full_prompt = f"{personalization_prompt}\n\nТекст для адаптации:\n{standard_message}" + return generate_message_gpt4o_with_retry(full_prompt) + +# Также обновляем функции персонализации +def perform_personalization_gigachat(standard_message, personalization_prompt, model): + full_prompt = f"{personalization_prompt}\n\nТекст для адаптации:\n{standard_message}" + if model == "gigachat_pro": + result = generate_message_gigachat_pro_with_retry(full_prompt) + elif model == "gigachat_lite": + result = generate_message_gigachat_lite_with_retry(full_prompt) + elif model == "gigachat_plus": + result = generate_message_gigachat_plus_with_retry(full_prompt) + return clean_message(result) + +def perform_personalization_meta_llama_405b(standard_message, personalization_prompt): + full_prompt = f"{personalization_prompt}\n\nТекст для адаптации:\n{standard_message}" + return generate_message_meta_llama_3_1_405b_with_retry(full_prompt) + +# Updated function to include additional models in personalization +def personalize_messages_with_yield( + gigachat_pro_message, + gigachat_lite_message, + gigachat_plus_message, + gpt4o_message, + meta_llama_405b_message, + key_message, + approach, + *selected_values +): + + personalization_prompt = generate_personalization_prompt(key_message, approach, *selected_values) + yield personalization_prompt, "", "", "", "", "" + + personalized_message_gigachat_pro = perform_personalization_gigachat(gigachat_pro_message, personalization_prompt, "gigachat_pro") + gigachat_pro_length = len(personalized_message_gigachat_pro) + gigachat_pro_display = f"{personalized_message_gigachat_pro}\n\n------\nКоличество знаков: {gigachat_pro_length}" + yield personalization_prompt, gigachat_pro_display, "", "", "", "" + + personalized_message_gigachat_lite = perform_personalization_gigachat(gigachat_lite_message, personalization_prompt, "gigachat_lite") + gigachat_lite_length = len(personalized_message_gigachat_lite) + gigachat_lite_display = f"{personalized_message_gigachat_lite}\n\n------\nКоличество знаков: {gigachat_lite_length}" + yield personalization_prompt, gigachat_pro_display, gigachat_lite_display, "", "", "" + + personalized_message_gigachat_plus = perform_personalization_gigachat(gigachat_plus_message, personalization_prompt, "gigachat_plus") + gigachat_plus_length = len(personalized_message_gigachat_plus) + gigachat_plus_display = f"{personalized_message_gigachat_plus}\n\n------\nКоличество знаков: {gigachat_plus_length}" + yield personalization_prompt, gigachat_pro_display, gigachat_lite_display, gigachat_plus_display, "", "" + + personalized_message_gpt4o = perform_personalization(gpt4o_message, personalization_prompt) + gpt4o_length = len(personalized_message_gpt4o) + gpt4o_display = f"{personalized_message_gpt4o}\n\n------\nКоличество знаков: {gpt4o_length}" + yield personalization_prompt, gigachat_pro_display, gigachat_lite_display, gigachat_plus_display, gpt4o_display, "" + + personalized_message_meta_llama_405b = perform_personalization_meta_llama_405b(meta_llama_405b_message, personalization_prompt) + meta_llama_405b_length = len(personalized_message_meta_llama_405b) + meta_llama_405b_display = f"{personalized_message_meta_llama_405b}\n\n------\nКоличество знаков: {meta_llama_405b_length}" + yield personalization_prompt, gigachat_pro_display, gigachat_lite_display, gigachat_plus_display, gpt4o_display, meta_llama_405b_display + + # Добавьте проверки в personalize_messages_with_yield + is_valid_gigachat_pro = check_forbidden_words(personalized_message_gigachat_pro) + is_valid_gigachat_lite = check_forbidden_words(personalized_message_gigachat_lite) + is_valid_gigachat_plus = check_forbidden_words(personalized_message_gigachat_plus) + is_valid_gpt4o = check_forbidden_words(personalized_message_gpt4o) + is_valid_meta_llama_405b = check_forbidden_words(personalized_message_meta_llama_405b) + + +# Функция для генерации промпта проверки текста +def generate_error_check_prompt(): + prompt = ( + "Проверь текст SMS-сообщения на соответствие установленным правилам и ограничениям, касающимся его формирования. На основе выявленных несоответствий предоставь рекомендации по исправлению текста. " + "Особое внимание удели проверке: количества символов в тексте SMS-сообщения, орфографическим и пунктуационным ошибкам, определению частей речи (причастия, деепричастия, причастный оборот, деепричастный оборот). " + "Анализируй только текст SMS-сообщения, ничего не придумывай и не добавляй лишнего. " + "Правила и ограничения, которым должен соответствовать текст SMS-сообщения:\n" + "1. Количество символов в SMS-сообщении должно быть до 250 знаков с учетом пробелов.\n" + "2. В тексте должен быть призыв к действию с использованием глагола в повелительном наклонении (например: оформите, получите, разместите, размещайте, откройте, подключите, подайте заявку).\n" + "3. Должно соблюдаться соответствие фактов о продукте.\n" + "4. В генерациях смс запрещено использовать обещания и гарантии.\n" + "5. В генерациях смс запрещено использовать составные конструкции из двух глаголов.\n" + "6. В генерациях смс запрещено использовать причастия и причастные обороты.\n" + "7. В генерациях смс запрещено использовать деепричастия и деепричастные обороты.\n" + "8. В генерациях смс запрещено использовать превосходную степень прилагательных.\n" + "9. В генерациях смс запрещено использовать страдательный залог.\n" + "10. В генерациях смс запрещено использовать порядковые числительные от 10 прописью.\n" + "11. В генерациях смс запрещено использовать цепочки с придаточными предложениями.\n" + "12. В генерациях смс запрещено использовать разделительные повторяющиеся союзы.\n" + "13. В генерациях смс запрещено использовать вводные конструкции.\n" + "14. В генерациях смс запрещено использовать усилители.\n" + "15. В генерациях смс запрещено использовать паразиты времени.\n" + "16. В генерациях смс запрещено использовать несколько существительных подряд, в том числе отглагольных.\n" + "17. В генерациях смс запрещено использовать производные предлоги.\n" + "18. В генерациях смс запрещено использовать сложные предложения, в которых нет связи между частями.\n" + "19. В генерациях смс запрещено использовать сложноподчинённые предложения.\n" + "20. В генерациях смс запрещено использовать даты прописью.\n" + "21. В генерациях смс запрещено использовать близкие по смыслу однородные члены.\n" + "22. В генерациях смс запрещено использовать шокирующие, экстравагантные, кликбейтные фразы.\n" + "23. В генерациях смс запрещено использовать абстрактные заявления без поддержки фактами и отсутствие доказательства пользы для клиента.\n" + "24. В генерациях смс запрещено использовать гарантирующие фразы.\n" + "25. В генерациях смс запрещено использовать узкоспециализированные термины.\n" + "26. В генерациях смс запрещено использовать фразы, способные создать двойственное ощущение, обидеть.\n" + "27. В генерациях смс запрещено использовать речевые клише, рекламные штампы, канцеляризмы.\n" + "28. В генерациях смс запрещено использовать запрещенные слова: № один, номер один, № 1, вкусный, дешёвый, продукт, спам, банкротство, долги, займ, срочно, лучший, главный, номер 1, успех, лидер.\n" + "29. Сообщение должно быть написано без орфографических и грамматических ошибок.\n" + "30. Запрещены повторы слов.\n" + "31. В тексте должны использоваться правильные знаки препинания.\n" + "32. Если в тексте используются кавычки, они должны быть в форме «кавычки-ёлочки».\n" + "33. В тексте SMS ��ообщения должны обязательно присутствовать: название продукта, условия использования продукта / Преимущества продукта / Шаги для подключения или начала использования / Условия акции (если предложение по продукту акционное).\n" + "Форма ответа: [Ответ должен быть кратким, должен содержать только рекомендации по устранению найденных несоответствий, соответствия каждому пункту правил описывать категорически запрещено]." + ) + return prompt + + +def save_to_github(personalized_message, model_name, comment, corrected_message, description, advantages, non_personalized_prompt, non_personalized_message, personalization_prompt, gender, generation, psychotype, business_stage, industry, legal_form, key_message, approach): + # Собираем все данные в один словарь + data_to_save = { + "Модель": model_name, + "Персонализированное сообщение": personalized_message, + "Комментарий": comment, + "Откорректированное сообщение": corrected_message, + "Описание предложения": description, + "Преимущества": advantages, + "Ключевое сообщение": key_message, # Save key message + "Подход": approach, # Save approach + "Неперсонализированный промпт": non_personalized_prompt, + "Неперсонализированное сообщение": non_personalized_message, + "Персонализированный промпт": personalization_prompt, # Добавляем персонализированный промпт + "Пол": gender, + "Поколение": generation, + "Психотип": psychotype, + "Стадия бизнеса": business_stage, + "Отрасль": industry, + "ОПФ": legal_form + } + + # Преобразуем контент в JSON-строку и кодируем в base64 + file_content_encoded = base64.b64encode(json.dumps(data_to_save).encode()).decode() + + # Параметры для GitHub API + repo = "fruitpicker01/Storage_dev" + path = f"file_{int(time.time())}.json" + url = f"https://api.github.com/repos/{repo}/contents/{path}" + headers = { + "Authorization": f"token {token}", + "Content-Type": "application/json" + } + data = { + "message": f"Добавлен новый файл {path}", + "content": file_content_encoded + } + + # Отправка POST-запроса на GitHub API для создания файла в репозитории + response = requests.put(url, headers=headers, data=json.dumps(data)) + + +def personalize_and_save( + gigachat_pro_message, + gigachat_lite_message, + gigachat_plus_message, + gpt4o_message, + meta_llama_405b_message, + description, + advantages, + key_message, + approach, + *selected_values +): + # Персонализация с использованием yield для последовательного вывода + personalization_generator = personalize_messages_with_yield( + gigachat_pro_message, + gigachat_lite_message, + gigachat_plus_message, + gpt4o_message, + meta_llama_405b_message, + key_message, + approach, + *selected_values + ) + + last_personalization_result = None + for personalization_result in personalization_generator: + last_personalization_result = personalization_result + yield ( + personalization_result[0], # personalization_prompt + personalization_result[1], # gigachat_pro_message + personalization_result[2], # gigachat_lite_message + personalization_result[3], # gigachat_plus_message + personalization_result[4], # gpt4o_message + personalization_result[5], # meta_llama_405b_message + "", "", "", "", "" # Пустые строки для проверок + ) + + # После завершения персонализации, сохраняем результаты + if last_personalization_result: + checks_gigachat_pro = perform_checks(last_personalization_result[1]) + checks_gigachat_lite = perform_checks(last_personalization_result[2]) + checks_gigachat_plus = perform_checks(last_personalization_result[3]) + checks_gpt4o = perform_checks(last_personalization_result[4]) + checks_meta_llama_405b = perform_checks(last_personalization_result[5]) + + # Форматирование результатов проверок + formatted_checks = [ + format_checks(checks_gigachat_pro), + format_checks(checks_gigachat_lite), + format_checks(checks_gigachat_plus), + format_checks(checks_gpt4o), + format_checks(checks_meta_llama_405b) + ] + + yield ( + last_personalization_result[0], # personalization_prompt + last_personalization_result[1], # gigachat_pro_message + last_personalization_result[2], # gigachat_lite_message + last_personalization_result[3], # gigachat_plus_message + last_personalization_result[4], # gpt4o_message + last_personalization_result[5], # meta_llama_405b_message + formatted_checks[0], # validation_display_1 + formatted_checks[1], # validation_display_2 + formatted_checks[2], # validation_display_3 + formatted_checks[3], # validation_display_4 + formatted_checks[4] # validation_display_5 + ) + + save_user_request_to_github(description, advantages, key_message, approach, selected_values) + + +def clear_fields(): + return ( + "", "", "", "", "", # personalized outputs and prompts + "", "", "", "", "", # comment fields + "", "", "", "", "", # corrected message fields + "", "", "", "", "", # анализ персонализации + ) + + +def clear_personalization_fields(): + return ( + "", "", "", "", "", # personalized outputs + "", "", "", "", "", # comment fields + "", "", "", "", "", # corrected message fields + "", "", "", "", "", # анализ персонализации + "" + ) + +def clear_on_change(): + return ( + "", "", "", "", "", # очистка всех полей для промптов и сообщений + "", "", "", "", "", # комментарии + "", "", "", "", "", # откорректированные сообщения + "", "", "", "", "", # результаты проверок + "", "", "", "", "", + ) + +def clear_on_change_pers(): + return ( + "", "", "", "", "", # очистка всех полей для промптов и сообщений + "", "", "", "", "", # комментарии + "", "", "", "", "", # откорректированные сообщения + "", "", "", "", "" # результаты проверок + ) + +def clear_unnecessary_fields(): + return ( + "", "", "", "", "", # personalized outputs and prompts + "", "", "", "", "", # comment fields + "", "", "", "", "", # corrected message fields + "", "", "", "", "", # оставшиеся поля + "", "", # Дополнительное пустое значение + "", "", "", "", "", # поля анализа персонализации + ) + +def prepare_button_text(): + return gr.update(value="Сохраняется...", visible=True) + +def update_button_text(): + return gr.update(value="Сохранено!", visible=True) + +def reset_button_text(): + time.sleep(2) # Задержка в 2 секунды + return gr.update(value="Сохранить в базу", visible=True) + +def regen_message_gpt4o(description, advantages, key_message, approach, *selected_values): + standard_prompt = generate_standard_prompt(description, advantages, key_message, approach, *selected_values) + gpt4o_message = generate_message_gpt4o_with_retry(standard_prompt) + gpt4o_length = len(gpt4o_message) + return f"{gpt4o_message}\n\n------\nКоличество знаков: {gpt4o_length}" + +def regen_message_gigachat_pro(description, advantages, key_message, approach, *selected_values): + standard_prompt = generate_standard_prompt(description, advantages, key_message, approach, *selected_values) + gigachat_pro_message = generate_message_gigachat_pro_with_retry(standard_prompt) + gigachat_pro_length = len(gigachat_pro_message) + return f"{gigachat_pro_message}\n\n------\nКоличество знаков: {gigachat_pro_length}" + +def regen_message_gigachat_lite(description, advantages, key_message, approach, *selected_values): + standard_prompt = generate_standard_prompt(description, advantages, key_message, approach, *selected_values) + gigachat_lite_message = generate_message_gigachat_lite_with_retry(standard_prompt) + gigachat_lite_length = len(gigachat_lite_message) + return f"{gigachat_lite_message}\n\n------\nКоличество знаков: {gigachat_lite_length}" + +def regen_message_gigachat_plus(description, advantages, key_message, approach, *selected_values): + standard_prompt = generate_standard_prompt(description, advantages, key_message, approach, *selected_values) + gigachat_plus_message = generate_message_gigachat_plus_with_retry(standard_prompt) + gigachat_plus_length = len(gigachat_plus_message) + return f"{gigachat_plus_message}\n\n------\nКоличество знаков: {gigachat_plus_length}" + +def regen_message_meta_llama_405b(description, advantages, key_message, approach, *selected_values): + standard_prompt = generate_standard_prompt(description, advantages, key_message, approach, *selected_values) + meta_llama_405b_message = generate_message_meta_llama_3_1_405b_with_retry(standard_prompt) + meta_llama_405b_length = len(meta_llama_405b_message) + return f"{meta_llama_405b_message}\n\n------\nКоличество знаков: {meta_llama_405b_length}" + +def personalize_message_gigachat_pro(gigachat_pro_message, key_message, approach, *selected_values): + personalization_prompt = generate_personalization_prompt(key_message, approach, *selected_values) + personalized_message = perform_personalization_gigachat(gigachat_pro_message, personalization_prompt, "gigachat_pro") + gigachat_pro_length = len(personalized_message) + + # Выполняем проверку сгенерированного сообщения + checks = perform_checks(personalized_message) + formatted_checks = format_checks(checks) + + return f"{personalized_message}\n\n------\nКоличество знаков: {gigachat_pro_length}", formatted_checks + +def personalize_message_gigachat_lite(gigachat_lite_message, key_message, approach, *selected_values): + personalization_prompt = generate_personalization_prompt(key_message, approach, *selected_values) + personalized_message = perform_personalization_gigachat(gigachat_lite_message, personalization_prompt, "gigachat_lite") + gigachat_lite_length = len(personalized_message) + + # Выполняем проверку сгенерированного сообщения + checks = perform_checks(personalized_message) + formatted_checks = format_checks(checks) + + return f"{personalized_message}\n\n------\nКоличество знаков: {gigachat_lite_length}", formatted_checks + +def personalize_message_gigachat_plus(gigachat_plus_message, key_message, approach, *selected_values): + personalization_prompt = generate_personalization_prompt(key_message, approach, *selected_values) + personalized_message = perform_personalization_gigachat(gigachat_plus_message, personalization_prompt, "gigachat_plus") + gigachat_plus_length = len(personalized_message) + + # Выполняем проверку сгенерированного сообщения + checks = perform_checks(personalized_message) + formatted_checks = format_checks(checks) + + return f"{personalized_message}\n\n------\nКоличество знаков: {gigachat_plus_length}", formatted_checks + +def personalize_message_gpt4o(gpt4o_message, key_message, approach, *selected_values): + personalization_prompt = generate_personalization_prompt(key_message, approach, *selected_values) + personalized_message = perform_personalization(gpt4o_message, personalization_prompt) + gpt4o_length = len(personalized_message) + + # Выполняем проверку сгенерированного сообщения + checks = perform_checks(personalized_message) + formatted_checks = format_checks(checks) + + return f"{personalized_message}\n\n------\nКоличество знаков: {gpt4o_length}", formatted_checks + +def personalize_message_meta_llama_405b(meta_llama_405b_message, key_message, approach, *selected_values): + personalization_prompt = generate_personalization_prompt(key_message, approach, *selected_values) + personalized_message = perform_personalization_meta_llama_405b(meta_llama_405b_message, personalization_prompt) + meta_llama_405b_length = len(personalized_message) + + # Выполняем проверку сгенерированного сообщения + checks = perform_checks(personalized_message) + formatted_checks = format_checks(checks) + + return f"{personalized_message}\n\n------\nКоличество знаков: {meta_llama_405b_length}", formatted_checks + + +def generate_explanation_gigachat_pro(prompt): + messages = [SystemMessage(content=prompt)] + res = chat_pro_explain(messages) + return res.content.strip() + +def generate_explanation_gigachat_lite(prompt): + messages = [SystemMessage(content=prompt)] + res = chat_lite_explain(messages) + return res.content.strip() + +def generate_explanation_gigachat_plus(prompt): + messages = [SystemMessage(content=prompt)] + res = chat_plus_explain(messages) + return res.content.strip() + +def generate_explanation_gpt4o(prompt): + try: + headers = { + "Content-Type": "application/json", + "Authorization": f"Bearer {openai_api_key}" + } + data = { + "model": "chatgpt-4o-latest", + "messages": [{"role": "system", "content": prompt}], + "temperature": 1.1 + } + response = requests.post("https://api.openai.com/v1/chat/completions", json=data, headers=headers) + response_data = response.json() + return response_data["choices"][0]["message"]["content"].strip() + except Exception as e: + return f"Ошибка при обращении к ChatGPT-4o-Latest: {e}" + +def generate_explanation_meta_llama_405b(prompt): + response = client.chat.completions.create( + model="meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo", + messages=[{"role": "user", "content": prompt}], + temperature=0.8 + ) + return response.choices[0].message.content.strip() + + +def explain_compliance_gigachat_pro(personalized_message, personalization_prompt): + prompt = ( + f"Есть инструкция по персонализации: {personalization_prompt}\n" + "Сообщи, учтены ли данные инструкции в тексте ниже, и укажи как они были учтены:\n" + f"Текст сообщения: {personalized_message}\n" + ) + return generate_explanation_gigachat_pro(prompt) + +def explain_compliance_gigachat_lite(personalized_message, personalization_prompt): + prompt = ( + f"Есть инструкция по персонализации: {personalization_prompt}\n" + "Сообщи, учтены ли данные инструкции в тексте ниже, и укажи как они были учтены:\n" + f"Текст сообщения: {personalized_message}\n" + ) + return generate_explanation_gigachat_lite(prompt) + +def explain_compliance_gigachat_plus(personalized_message, personalization_prompt): + prompt = ( + f"Есть инструкция по персонализации: {personalization_prompt}\n" + "Сообщи, учтены ли данные инструкции в тексте ниже, и укажи как они были учтены:\n" + f"Текст сообщения: {personalized_message}\n" + ) + return generate_explanation_gigachat_plus(prompt) + +def explain_compliance_gpt4o(personalized_message, personalization_prompt): + prompt = ( + f"Есть инструкция по персонализации: {personalization_prompt}\n" + "Сообщи, учтены ли данные инструкции в тексте ниже, и укажи как они были учтены:\n" + f"Текст сообщения: {personalized_message}\n" + ) + return generate_explanation_gpt4o(prompt) + +def explain_compliance_meta_llama_405b(personalized_message, personalization_prompt): + prompt = ( + f"Есть инструкция по персонализации: {personalization_prompt}\n" + "Сообщи, учтены ли данные инструкции в тексте ниже, и укажи как они были учтены:\n" + f"Текст сообщения: {personalized_message}\n" + ) + return generate_explanation_meta_llama_405b(prompt) + +def perform_analysis_with_yield( + gigachat_pro_message, + gigachat_lite_message, + gigachat_plus_message, + gpt4o_message, + meta_llama_405b_message, + personalization_prompt +): + # Start yielding results progressively + gigachat_pro_analysis = explain_compliance_gigachat_pro(gigachat_pro_message, personalization_prompt) + yield gigachat_pro_analysis, "", "", "", "" + + gigachat_lite_analysis = explain_compliance_gigachat_lite(gigachat_lite_message, personalization_prompt) + yield gigachat_pro_analysis, gigachat_lite_analysis, "", "", "" + + gigachat_plus_analysis = explain_compliance_gigachat_plus(gigachat_plus_message, personalization_prompt) + yield gigachat_pro_analysis, gigachat_lite_analysis, gigachat_plus_analysis, "", "" + + gpt4o_analysis = explain_compliance_gpt4o(gpt4o_message, personalization_prompt) + yield gigachat_pro_analysis, gigachat_lite_analysis, gigachat_plus_analysis, gpt4o_analysis, "" + + meta_llama_405b_analysis = explain_compliance_meta_llama_405b(meta_llama_405b_message, personalization_prompt) + yield gigachat_pro_analysis, gigachat_lite_analysis, gigachat_plus_analysis, gpt4o_analysis, meta_llama_405b_analysis + +# ФУНКЦИИ ПРОВЕРОК (НАЧАЛО) + +# 1. Запрещенные слова + +def check_forbidden_words(message): + morph = pymorphy2.MorphAnalyzer() + + # Перечень запрещённых слов и фраз + forbidden_patterns = [ + r'№\s?1\b', r'номер\sодин\b', r'номер\s1\b', + r'вкусный', r'дешёвый', r'продукт', + r'спам', r'доступный', r'банкротство', r'долг[и]?', r'займ', + r'срочный', r'сейчас', r'главный', + r'гарантия', r'успех', r'лидер' + ] + + # Удаляем знаки препинания для корректного анализа + message_without_punctuation = message.translate(str.maketrans('', '', string.punctuation)) + + # Проверка на наличие подстроки "лучш" (без учета регистра) + if re.search(r'лучш', message_without_punctuation, re.IGNORECASE): + return False + + # Лемматизация слов сообщения + words = message_without_punctuation.split() + lemmas = [morph.parse(word)[0].normal_form for word in words] + normalized_message = ' '.join(lemmas) + + # Проверка на запрещённые фразы и леммы + for pattern in forbidden_patterns: + if re.search(pattern, normalized_message, re.IGNORECASE): + return False + + return True + + +# 2 и #3. Обращение к клиенту и приветствие клиента + +def check_no_greeting(message): + morph = pymorphy2.MorphAnalyzer() + # Список типичных обращений и приветствий + greeting_patterns = [ + r"привет\b", r"здравствуй", r"добрый\s(день|вечер|утро)", + r"дорогой\b", r"уважаемый\b", r"дорогая\b", r"уважаемая\b", + r"господин\b", r"госпожа\b", r"друг\b", r"коллега\b", + r"товарищ\b", r"приятель\b", r"друг\b", r"подруга\b" + ] + + # Компилируем все шаблоны в один регулярное выражение + greeting_regex = re.compile('|'.join(greeting_patterns), re.IGNORECASE) + + # Проверяем, начинается ли сообщение с шаблона приветствия или обращения + if greeting_regex.search(message.strip()): + return False + return True + +# 4. Обещания и гарантии + +def check_no_promises(message): + morph = pymorphy2.MorphAnalyzer() + promise_patterns = [ + "обещать", "гарантировать", "обязаться" + ] + + words = message.split() + lemmas = [morph.parse(word)[0].normal_form for word in words] + + for pattern in promise_patterns: + if pattern in lemmas: + return False + return True + +# 5. Составные конструкции из двух глаголов + +def check_no_double_verbs(message): + morph = pymorphy2.MorphAnalyzer() + words = message.split() + morphs = [morph.parse(word)[0] for word in words] + + for i in range(len(morphs) - 1): + if morphs[i].tag.POS == 'INFN' and morphs[i+1].tag.POS == 'INFN': + return False + return True + +# 6. Причастия и причастные обороты + +def check_no_participles(message): + morph = pymorphy2.MorphAnalyzer() + words = message.split() + morphs = [morph.parse(word)[0] for word in words] + + for morph in morphs: + if 'PRTF' in morph.tag: + return False + return True + +# 7. Деепричастия и деепричастные обороты + +def check_no_adverbial_participles(message): + morph = pymorphy2.MorphAnalyzer() + words = message.split() + morphs = [morph.parse(word)[0] for word in words] + + for morph in morphs: + if 'GRND' in morph.tag: + return False + return True + +# 8. Превосходная степень прилагательных + +def check_no_superlative_adjectives(message): + morph = pymorphy2.MorphAnalyzer() + words = message.split() + morphs = [morph.parse(word)[0] for word in words] + + for morph in morphs: + if 'COMP' in morph.tag or 'Supr' in morph.tag: + return False + return True + +# 9. Страдательный залог + +def check_no_passive_voice(message): + morph = pymorphy2.MorphAnalyzer() + words = message.split() + morphs = [morph.parse(word)[0] for word in words] + + for morph in morphs: + if 'PRTF' in morph.tag and ('passive' in morph.tag or 'в' in morph.tag): + return False + return True + +# 10. Порядковые числительные от 10 прописью + +def check_no_written_out_ordinals(message): + morph = pymorphy2.MorphAnalyzer() + ordinal_words = [ + "десятый", "одиннадцатый", "двенадцатый", "тринадцатый", "четырнадцатый", "пятнадцатый", + "шестнадцатый", "семнадцатый", "восемнадцатый", "девятнадцатый", "двадцатый" + ] + + words = message.split() + lemmas = [morph.parse(word)[0].normal_form for word in words] + + for word in ordinal_words: + if word in lemmas: + return False + return True + +# 11. Цепочки с придаточными предложениями + +def check_no_subordinate_clauses_chain(message): + # Регулярное выражение, которое ищет последовательности придаточных предложений + subordinate_clause_patterns = [ + r'\b(который|которая|которое|которые)\b', + r'\b(если|потому что|так как|что|когда)\b', + r'\b(хотя|несмотря на то что)\b' + ] + + count = 0 + for pattern in subordinate_clause_patterns: + if re.search(pattern, message): + count += 1 + + # Если в предложении найдено более одного придаточного предложения подряд, возвращаем False + return count < 2 + +# 12. Разделительные повторяющиеся союзы + +def check_no_repeating_conjunctions(message): + repeating_conjunctions_patterns = r'\b(и|или|но|также)\s+\1\b' + + if re.search(repeating_conjunctions_patterns, message, re.IGNORECASE): + return False + return True + +# 13. Вводные конструкции + +def check_no_introductory_phrases(message): + introductory_phrases = [ + r'\b(во-первых|во-вторых|с одной стороны|по сути|по правде говоря)\b', + r'\b(может быть|кстати|конечно|естественно|безусловно|возможно)\b' + ] + + for pattern in introductory_phrases: + if re.search(pattern, message, re.IGNORECASE): + return False + return True + +# 14. Усилители + +def check_no_amplifiers(message): + amplifiers = [ + r'\b(очень|крайне|чрезвычайно|совсем|абсолютно|полностью|чисто)\b' + ] + + for pattern in amplifiers: + if re.search(pattern, message, re.IGNORECASE): + return False + return True + +# 15. Паразиты времени + +def check_no_time_parasites(message): + time_parasites = [ + r'\b(сейчас|немедленно|срочно|в данный момент|теперь)\b' + ] + + for pattern in time_parasites: + if re.search(pattern, message, re.IGNORECASE): + return False + return True + +# 16. Несколько существительных подряд + +def check_no_multiple_nouns(message): + noun_count = 0 + words = message.split() + morph = pymorphy2.MorphAnalyzer() + + for word in words: + parsed_word = morph.parse(word)[0] + + # Если слово — существительное + if 'NOUN' in parsed_word.tag: + noun_count += 1 + # Если встречен союз или предлог, обнуляем счетчик + elif parsed_word.tag.POS in {'CONJ', 'PREP'}: + noun_count = 0 + else: + noun_count = 0 + + if noun_count > 2: + return False + return True + + +# 17. Производные предлоги + +def check_no_derived_prepositions(message): + derived_prepositions = [ + r'\b(в течение|в ходе|вследствие|в связи с|по мере|при помощи|согласно)\b' + ] + + for pattern in derived_prepositions: + if re.search(pattern, message, re.IGNORECASE): + return False + return True + +# 19. Сложноподчиненные предложения + +def check_no_compound_sentences(message): + subordinating_conjunctions = [ + r'\bкогда\b', r'\bкак только\b', r'\bпока\b', r'\bпосле того как\b', + r'\bпотому что\b', r'\bтак как\b', r'\bоттого что\b', r'\bблагодаря тому что\b', + r'\bчтобы\b', r'\bдля того чтобы\b', r'\bесли\b', r'\bкогда бы\b', r'\bесли бы\b', + r'\bхотя\b', r'\bнесмотря на то что\b', r'\bкак\b', r'\bбудто\b', r'\bсловно\b', r'\bкак будто\b', + r'\bчто\b' + ] + + # Убедимся, что слово "как" используется не в вопросе + for pattern in subordinating_conjunctions: + if re.search(pattern, message) and not re.search(r'\?', message): + return False + return True + +# 20. Даты прописью + +def check_no_dates_written_out(message): + # Ищем упоминания месяцев или слов, связанных с датами + months = [ + "января", "февраля", "марта", "апреля", "мая", "июня", + "июля", "августа", "сентября", "октября", "ноября", "декабря" + ] + + # Слова для проверки чисел прописью + date_written_out_patterns = [ + r'\b(первого|второго|третьего|четвертого|пятого|шестого|седьмого|восьмого|девятого|десятого|одиннадцатого|двенадцатого|тринадцатого|четырнадцатого|пятнадцатого|шестнадцатого|семнадцатого|восемнадцатого|девятнадцатого|двадцатого|двадцать первого|двадцать второго|двадцать третьего|двадцать четвертого|двадцать пятого|двадцать шестого|двадцать седьмого|двадцать восьмого|двадцать девятого|тридцатого|тридцать первого)\b' + ] + + for month in months: + for pattern in date_written_out_patterns: + if re.search(f'{pattern}\\s{month}', message, re.IGNORECASE): + return False + + return True + +# ФУНКЦИИ ПРОВЕРОК (КОНЕЦ) + +def perform_checks(message): + checks = { + "forbidden_words": check_forbidden_words(message), + "client_addressing": check_no_greeting(message), + "promises": check_no_promises(message), + "double_verbs": check_no_double_verbs(message), + "participles": check_no_participles(message), + "adverbial_participles": check_no_adverbial_participles(message), + "superlative_adjectives": check_no_superlative_adjectives(message), + "passive_voice": check_no_passive_voice(message), + "written_out_ordinals": check_no_written_out_ordinals(message), + "subordinate_clauses_chain": check_no_subordinate_clauses_chain(message), + "repeating_conjunctions": check_no_repeating_conjunctions(message), + "introductory_phrases": check_no_introductory_phrases(message), + "amplifiers": check_no_amplifiers(message), + "time_parasites": check_no_time_parasites(message), + "multiple_nouns": check_no_multiple_nouns(message), + "derived_prepositions": check_no_derived_prepositions(message), + "compound_sentences": check_no_compound_sentences(message), + "dates_written_out": check_no_dates_written_out(message) + } + return checks + + +def format_checks(checks): + translation = { + "forbidden_words": "Запрещенные слова", + "client_addressing": "Обращение к клиенту", + "promises": "Обещания и гарантии", + "double_verbs": "Два глагола подряд", + "participles": "Причастия", + "adverbial_participles": "Деепричастия", + "superlative_adjectives": "Превосходная степень", + "passive_voice": "Страдательный залог", + "written_out_ordinals": "Порядковые числительные", + "subordinate_clauses_chain": "Цепочки с придаточными предложениями", + "repeating_conjunctions": "Разделительные повторяющиеся союзы", + "introductory_phrases": "Вводные конструкции", + "amplifiers": "Усилители", + "time_parasites": "Паразиты времени", + "multiple_nouns": "Несколько существительных подряд", + "derived_prepositions": "Производные предлоги", + "compound_sentences": "Сложноподчиненные предложения", + "dates_written_out": "Даты прописью" + } + return " \n".join([f"{translation[rule]}: {'✔️' if result else '❌'}" for rule, result in checks.items()]) + + +# Создание интерфейса Gradio +with gr.Blocks() as demo: + gr.Markdown("# Генерация SMS-сообщений по заданным признакам") + + with gr.Row(): + with gr.Column(scale=1): + description_input = gr.Textbox( + label="Описание предложения (предзаполненный пример можно поменять на свой)", + lines=13, + value=( + "Необходимо предложить клиенту оформить дебетовую премиальную бизнес-карту Mastercard Preffered. " + "Обслуживание карты стоит 700 рублей в месяц, но клиент может пользоваться ей бесплатно. " + "Что необходимо сделать, чтобы воспользоваться предложением:\n" + "1. Оформить премиальную бизнес-карту в офисе банка или онлайн в интернет-банке СберБизнес.\n" + "2. Забрать карту.\n" + "3. В течение календарного месяца совершить по ней покупки на сумму от 100 000 рублей.\n" + "4. В течение следующего месяца пользоваться ей бесплатно." + ) + ) + + advantages_input = gr.Textbox( + label="Преимущества (предзаполненный пример можно поменять на свой)", + lines=6, + value=( + "Предложение по бесплатному обслуживанию — бессрочное.\n" + "Оплата покупок без отчётов и платёжных поручений.\n" + "Платёжные документы без комиссии.\n" + "Лимиты на расходы сотрудников.\n" + "Мгновенные переводы на карты любых банков." + ) + ) + + key_message_input = gr.Textbox( + label="Ключевое сообщение (предзаполненный пример можно поменять на свой)", + lines=3, + value="Бесплатное обслуживание при покупках от 100 000 рублей в месяц." + ) + + approach_input = gr.Dropdown( + label="Подход", + choices=["None", "Призыв к действию", "Указание на пользу", "Вопрос"], + value="None" # Default value + ) + + + selections = [] + gr.Markdown("**Персонализация**") + for feature in features.keys(): + if feature not in ["Пол Поколение Психотип"]: # Исключаем этот лист из выбора + selections.append(gr.Dropdown(choices=[None] + list(features[feature].keys()), label=f"Выберите {feature}")) + + with gr.Column(scale=2): + prompt_display = gr.Textbox( + label="Неперсонализированный промпт", + lines=41, + value=( + "Сгенерируй смс-сообщение для клиента.\n" + "Описание предложения: " + "Необходимо предложить клиенту оформить дебетовую премиальную бизнес-карту Mastercard Preffered. " + "Обслуживание карты стоит 700 рублей в месяц, но клиент может пользоваться ей бесплатно. " + "Что необходимо сделать, чтобы воспользоваться предложением:\n" + "1. Оформить премиальную бизнес-карту в офисе банка или онлайн в интернет-банке СберБизнес.\n" + "2. Забрать карту.\n" + "3. В течение календарного месяца совершить по ней покупки на сумму от 100 000 рублей.\n" + "4. В течение следующего месяца пользоваться ей бесплатно.\n" + "Преимущества: " + "Предложение по бесплатному обслуживанию — бессрочное.\n" + "Оплата покупок без отчётов и платёжных поручений.\n" + "Платёжные документы без комиссии.\n" + "Лимиты на расходы сотрудников.\n" + "Мгновенные переводы на карты любых банков.\n " + "В тексте смс запрещено использование:\n" + "- Запрещенные слова: № один, номер один, № 1, вкусный, дешёвый, продукт, спам, доступный, банкротство, долги, займ, срочно, сейчас, лучший, главный, номер 1, гарантия, успех, лидер;\n" + "- Обращение к клиенту;\n" + "- Приветствие клиента;\n" + "- Обещания и гарантии;\n" + "- Использовать составные конструкции из двух глаголов;\n" + "- Причастия и причастные обороты;\n" + "- Деепричастия и деепричастные обороты;\n" + "- Превосходная степень прилагательных;\n" + "- Страдательный залог;\n" + "- Порядковые числительные от 10 прописью;\n" + "- Цепочки с придаточными предложениями;\n" + "- Разделительные повторяющиеся союзы;\n" + "- Вводные конструкции;\n" + "- Усилители;\n" + "- Паразиты времени;\n" + "- Несколько существительных подряд, в том чи��ле отглагольных;\n" + "- Производные предлоги;\n" + "- Сложные предложения, в которых нет связи между частями;\n" + "- Сложноподчинённые предложения;\n" + "- Даты прописью;\n" + "- Близкие по смыслу однородные члены предложения;\n" + "- Шокирующие, экстравагантные, кликбейтные фразы;\n" + "- Абстрактные заявления без поддержки фактами и отсутствие доказательства пользы для клиента;\n" + "- Гарантирующие фразы;\n" + "- Узкоспециализированные термины;\n" + "- Фразы, способные создать двойственное ощущение, обидеть;\n" + "- Речевые клише, рекламные штампы, канцеляризмы;\n" + "Убедись, что в готовом тексте до 250 знаков с пробелами.\n" + "Убедись, что готовый текст начинается с призыва к действию с продуктом.\n" + "Убедись, что в готовом тексте есть следующая ключевая информация: Бесплатное обслуживание при покупках от 100 000 рублей в месяц." + ), + interactive=False) + personalization_prompt = gr.Textbox(label="Персонализированный промпт", lines=23, interactive=False) + + with gr.Row(): + submit_btn = gr.Button("1. Создать неперсонализированное сообщение") + personalize_btn = gr.Button("2. Выполнить персонализацию (нажимать только после кнопки 1)", elem_id="personalize_button") + load_btn = gr.Button("Вернуть параметры предыдущего запроса") + + gr.Markdown("---") # Добавляет горизонтальную линию + + # Ряд кнопок "Перегенерировать" + with gr.Row(): + regen_gigachat_pro_btn = gr.Button("Перегенерировать") + regen_gigachat_lite_btn = gr.Button("Перегенерировать") + regen_gigachat_plus_btn = gr.Button("Перегенерировать") + regen_gpt4o_btn = gr.Button("Перегенерировать") + regen_meta_llama_405b_btn = gr.Button("Перегенерировать") + + # Первый ряд: неперсонализированные сообщения + with gr.Row(): + output_text_gigachat_pro = gr.Textbox(label="Неперсонализированное сообщение 1", lines=3, interactive=False) + output_text_gigachat_lite = gr.Textbox(label="Неперсонализированное сообщение 2", lines=3, interactive=False) + output_text_gigachat_plus = gr.Textbox(label="Неперсонализированное сообщение 3", lines=3, interactive=False) + output_text_gpt4o = gr.Textbox(label="Неперсонализированное сообщение 4", lines=3, interactive=False) + output_text_meta_llama_405b = gr.Textbox(label="Неперсонализированное сообщение 5", lines=3, interactive=False) + + # Ряд кнопок "Персонализировать" + with gr.Row(): + personalize_gigachat_pro_btn = gr.Button("Персонализировать") + personalize_gigachat_lite_btn = gr.Button("Персонализировать") + personalize_gigachat_plus_btn = gr.Button("Персонализировать") + personalize_gpt4o_btn = gr.Button("Персонализировать") + personalize_meta_llama_405b_btn = gr.Button("Персонализировать") + + # Второй ряд: персонализированные сообщения + with gr.Row(): + personalized_output_text_gigachat_pro = gr.Textbox(label="Персонализированное сообщение 1", lines=3, interactive=False) + personalized_output_text_gigachat_lite = gr.Textbox(label="Персонализированное сообщение 2", lines=3, interactive=False) + personalized_output_text_gigachat_plus = gr.Textbox(label="Персонализированное сообщение 3", lines=3, interactive=False) + personalized_output_text_gpt4o = gr.Textbox(label="Персонализированное сообщение 4", lines=3, interactive=False) + personalized_output_text_meta_llama_405b = gr.Textbox(label="Пе��сонализированное сообщение 5", lines=3, interactive=False) + + # Третий ряд: комментарии + with gr.Row(): + comment_gigachat_pro = gr.Textbox(label="Комментарий к сообщению 1", lines=3) + comment_gigachat_lite = gr.Textbox(label="Комментарий к сообщению 2", lines=3) + comment_gigachat_plus = gr.Textbox(label="Комментарий к сообщению 3", lines=3) + comment_gpt4o = gr.Textbox(label="Комментарий к сообщению 4", lines=3) + comment_meta_llama_405b = gr.Textbox(label="Комментарий к сообщению 5", lines=3) + + # Четвертый ряд: откорректированные сообщения + with gr.Row(): + corrected_gigachat_pro = gr.Textbox(label="Откорректированное сообщение 1", lines=3) + corrected_gigachat_lite = gr.Textbox(label="Откорректированное сообщение 2", lines=3) + corrected_gigachat_plus = gr.Textbox(label="Откорректированное сообщение 3", lines=3) + corrected_gpt4o = gr.Textbox(label="Откорректированное сообщение 4", lines=3) + corrected_meta_llama_405b = gr.Textbox(label="Откорректированное сообщение 5", lines=3) + + # Пятый ряд: кнопки сохранения + with gr.Row(): + save_gigachat_pro_btn = gr.Button("Сохранить в базу") + save_gigachat_lite_btn = gr.Button("Сохранить в базу") + save_gigachat_plus_btn = gr.Button("Сохранить в базу") + save_gpt4o_btn = gr.Button("Сохранить в базу") + save_meta_llama_405b_btn = gr.Button("Сохранить в базу") + + gr.Markdown("---") + + with gr.Row(): + validation_display_1 = gr.Markdown() + validation_display_2 = gr.Markdown() + validation_display_3 = gr.Markdown() + validation_display_4 = gr.Markdown() + validation_display_5 = gr.Markdown() + + gr.Markdown("---") + + # Очистка всех полей кроме prompt_display + description_input.change( + fn=clear_on_change, # Сначала вызываем функцию очистки полей + inputs=[], + outputs=[ + output_text_gigachat_pro, + output_text_gigachat_lite, + output_text_gigachat_plus, + output_text_gpt4o, + output_text_meta_llama_405b, + personalized_output_text_gigachat_pro, + personalized_output_text_gigachat_lite, + personalized_output_text_gigachat_plus, + personalized_output_text_gpt4o, + personalized_output_text_meta_llama_405b, + comment_gigachat_pro, + corrected_gigachat_pro, + comment_gigachat_lite, + corrected_gigachat_lite, + comment_gigachat_plus, + corrected_gigachat_plus, + comment_gpt4o, + corrected_gpt4o, + comment_meta_llama_405b, + corrected_meta_llama_405b, + validation_display_1, + validation_display_2, + validation_display_3, + validation_display_4, + validation_display_5 + ] + ).then( + fn=generate_standard_prompt, # После очистки вызываем функцию для обновления промпта + inputs=[description_input, advantages_input, key_message_input, approach_input] + selections, + outputs=prompt_display # Мгновенно обновляем поле неперсонализированного промпта + ) + + # Очистка всех полей кроме prompt_display + advantages_input.change( + fn=clear_on_change, # Сначала вызываем функцию очистки полей + inputs=[], + outputs=[ + output_text_gigachat_pro, + output_text_gigachat_lite, + output_text_gigachat_plus, + output_text_gpt4o, + output_text_meta_llama_405b, + personalized_output_text_gigachat_pro, + personalized_output_text_gigachat_lite, + personalized_output_text_gigachat_plus, + personalized_output_text_gpt4o, + personalized_output_text_meta_llama_405b, + comment_gigachat_pro, + corrected_gigachat_pro, + comment_gigachat_lite, + corrected_gigachat_lite, + comment_gigachat_plus, + corrected_gigachat_plus, + comment_gpt4o, + corrected_gpt4o, + comment_meta_llama_405b, + corrected_meta_llama_405b, + validation_display_1, + validation_display_2, + validation_display_3, + validation_display_4, + validation_display_5 + ] + ).then( + fn=generate_standard_prompt, # После очистки вызываем функцию для обновления промпта + inputs=[description_input, advantages_input, key_message_input, approach_input] + selections, + outputs=prompt_display # Мгновенно обновляем поле неперсонализированного промпта + ) + + # Очистка всех полей кроме prompt_display + key_message_input.change( + fn=clear_on_change, # Сначала вызываем функцию очистки полей + inputs=[], + outputs=[ + output_text_gigachat_pro, + output_text_gigachat_lite, + output_text_gigachat_plus, + output_text_gpt4o, + output_text_meta_llama_405b, + personalized_output_text_gigachat_pro, + personalized_output_text_gigachat_lite, + personalized_output_text_gigachat_plus, + personalized_output_text_gpt4o, + personalized_output_text_meta_llama_405b, + comment_gigachat_pro, + corrected_gigachat_pro, + comment_gigachat_lite, + corrected_gigachat_lite, + comment_gigachat_plus, + corrected_gigachat_plus, + comment_gpt4o, + corrected_gpt4o, + comment_meta_llama_405b, + corrected_meta_llama_405b, + validation_display_1, + validation_display_2, + validation_display_3, + validation_display_4, + validation_display_5 + ] + ).then( + fn=generate_standard_prompt, # После очистки вызываем функцию для обновления промпта + inputs=[description_input, advantages_input, key_message_input, approach_input] + selections, + outputs=prompt_display # Мгновенно обновляем поле неперсонализированного промпта + ) + + # Очистка всех полей кроме prompt_display + approach_input.change( + fn=clear_on_change, # Сначала вызываем функцию очистки полей + inputs=[], + outputs=[ + output_text_gigachat_pro, + output_text_gigachat_lite, + output_text_gigachat_plus, + output_text_gpt4o, + output_text_meta_llama_405b, + personalized_output_text_gigachat_pro, + personalized_output_text_gigachat_lite, + personalized_output_text_gigachat_plus, + personalized_output_text_gpt4o, + personalized_output_text_meta_llama_405b, + comment_gigachat_pro, + corrected_gigachat_pro, + comment_gigachat_lite, + corrected_gigachat_lite, + comment_gigachat_plus, + corrected_gigachat_plus, + comment_gpt4o, + corrected_gpt4o, + comment_meta_llama_405b, + corrected_meta_llama_405b, + validation_display_1, + validation_display_2, + validation_display_3, + validation_display_4, + validation_display_5 + ] + ).then( + fn=generate_standard_prompt, # После очистки вызываем функцию для обновления промпта + inputs=[description_input, advantages_input, key_message_input, approach_input] + selections, + outputs=prompt_display # Мгновенно обновляем поле неперсонализированного промпта + ).then( + fn=generate_personalization_prompt, # Вызываем генерацию персонализированного промпта после изменения + inputs=[key_message_input, approach_input] + selections, # Передаем все нужные параметры + outputs=personalization_prompt # Обновляем поле с персонализированным промптом + ) + + + # Добавляем обработчики для каждого поля в selections + for selection in selections: + # Очищаем все персонализированные сообщения и результаты проверок + selection.change( + fn=clear_on_change_pers, + inputs=[], + outputs=[ + personalized_output_text_gigachat_pro, + personalized_output_text_gigachat_lite, + personalized_output_text_gigachat_plus, + personalized_output_text_gpt4o, + personalized_output_text_meta_llama_405b, + comment_gigachat_pro, + corrected_gigachat_pro, + comment_gigachat_lite, + corrected_gigachat_lite, + comment_gigachat_plus, + corrected_gigachat_plus, + comment_gpt4o, + corrected_gpt4o, + comment_meta_llama_405b, + corrected_meta_llama_405b, + validation_display_1, + validation_display_2, + validation_display_3, + validation_display_4, + validation_display_5 + ] + ).then( + fn=generate_personalization_prompt, # Вызываем генерацию персонализированного промпта после изменения + inputs=[key_message_input, approach_input] + selections, # Передаем все нужные параметры + outputs=personalization_prompt # Обновляем поле с персонализированным промптом + ) + + +# analyze_btn = gr.Button("Выполнить анализ персонализации (экспериментальная фича)") + +# with gr.Row(): +# analysis_gigachat_pro = gr.Textbox(label="Анализ персонализации сообщения 1", lines=4, interactive=False) +# analysis_gigachat_lite = gr.Textbox(label="Анализ персонализации сообщения 2", lines=4, interactive=False) +# analysis_gigachat_plus = gr.Textbox(label="Анализ персонализации сообщения 3", lines=4, interactive=False) +# analysis_gpt4o = gr.Textbox(label="Анализ персонализации сообщения 4", lines=4, interactive=False) +# analysis_meta_llama_405b = gr.Textbox(label="Анализ персонализации сообщения 5", lines=4, interactive=False) + + + # Добавление функционала для кнопок + submit_btn.click( + clear_fields, + inputs=[], + outputs=[ + personalized_output_text_gigachat_pro, + personalized_output_text_gigachat_lite, + personalized_output_text_gigachat_plus, + personalized_output_text_gpt4o, + personalized_output_text_meta_llama_405b, + comment_gigachat_pro, + corrected_gigachat_pro, + comment_gigachat_lite, + corrected_gigachat_lite, + comment_gigachat_plus, + corrected_gigachat_plus, + comment_gpt4o, + corrected_gpt4o, + comment_meta_llama_405b, + corrected_meta_llama_405b, + validation_display_1, # Очистка результатов проверок + validation_display_2, + validation_display_3, + validation_display_4, + validation_display_5 + ] + ) + + submit_btn.click( + generate_messages, + inputs=[description_input, advantages_input, key_message_input, approach_input] + selections, + outputs=[ + prompt_display, + output_text_gigachat_pro, + output_text_gigachat_lite, + output_text_gigachat_plus, + output_text_gpt4o, + output_text_meta_llama_405b + ] + ) + + + personalize_btn.click( + fn=clear_personalization_fields, + inputs=[], + outputs=[ + personalized_output_text_gigachat_pro, + personalized_output_text_gigachat_lite, + personalized_output_text_gigachat_plus, + personalized_output_text_gpt4o, + personalized_output_text_meta_llama_405b, + comment_gigachat_pro, + corrected_gigachat_pro, + comment_gigachat_lite, + corrected_gigachat_lite, + comment_gigachat_plus, + corrected_gigachat_plus, + comment_gpt4o, + corrected_gpt4o, + comment_meta_llama_405b, + corrected_meta_llama_405b + ] + ) + + personalize_btn.click( + fn=personalize_and_save, + inputs=[ + output_text_gigachat_pro, + output_text_gigachat_lite, + output_text_gigachat_plus, + output_text_gpt4o, + output_text_meta_llama_405b, + description_input, + advantages_input, + key_message_input, + approach_input, + ] + selections, + outputs=[ + personalization_prompt, + personalized_output_text_gigachat_pro, + personalized_output_text_gigachat_lite, + personalized_output_text_gigachat_plus, + personalized_output_text_gpt4o, + personalized_output_text_meta_llama_405b, + validation_display_1, + validation_display_2, + validation_display_3, + validation_display_4, + validation_display_5, + ] + ) + + + # Обработка клика по кнопке восстановления + load_btn.click( + fn=lambda: load_previous_user_request_from_github(), + inputs=[], + outputs=[ + description_input, # Описание предложения + advantages_input, # Преимущества + key_message_input, # Ключевое сообщение + approach_input, # Подход + *selections, # Параметры персонализации (Пол, Поколение и т.д.) + ] + ).then( + fn=clear_unnecessary_fields, + inputs=[], + outputs=[ + prompt_display, + personalization_prompt, # Очищаем personalization_prompt + output_text_gigachat_pro, + output_text_gigachat_lite, + output_text_gigachat_plus, + output_text_gpt4o, + output_text_meta_llama_405b, + personalized_output_text_gigachat_pro, + personalized_output_text_gigachat_lite, + personalized_output_text_gigachat_plus, + personalized_output_text_gpt4o, + personalized_output_text_meta_llama_405b, + comment_gigachat_pro, + corrected_gigachat_pro, + comment_gigachat_lite, + corrected_gigachat_lite, + comment_gigachat_plus, + corrected_gigachat_plus, + comment_gpt4o, + corrected_gpt4o, + comment_meta_llama_405b, + corrected_meta_llama_405b, + validation_display_1, # Очистка результатов проверок + validation_display_2, + validation_display_3, + validation_display_4, + validation_display_5 + ] + ).then( + fn=generate_standard_prompt, # Генерация неперсонализированного промпта на основе загруженных данных + inputs=[description_input, advantages_input, key_message_input, approach_input] + selections, + outputs=prompt_display # Обновляем поле с неперсонализированным промптом + ).then( + fn=generate_personalization_prompt, # Генерация персонализированного промпта + inputs=[key_message_input, approach_input] + selections, + outputs=personalization_prompt # Обновляем поле с персонализированным промптом + ) + + + regen_gigachat_pro_btn.click( + fn=lambda: ("", ""), # Очищаем текст персонализированного сообщения и проверку + inputs=[], + outputs=[personalized_output_text_gigachat_pro, validation_display_1] + ).then( + fn=regen_message_gigachat_pro, + inputs=[description_input, advantages_input, key_message_input, approach_input] + selections, + outputs=output_text_gigachat_pro + ) + + + regen_gigachat_lite_btn.click( + fn=lambda: ("", ""), # Очищаем текст персонализированного сообщения и проверку + inputs=[], + outputs=[personalized_output_text_gigachat_lite, validation_display_2] + ).then( + fn=regen_message_gigachat_lite, + inputs=[description_input, advantages_input, key_message_input, approach_input] + selections, + outputs=output_text_gigachat_lite + ) + + regen_gigachat_plus_btn.click( + fn=lambda: ("", ""), # Очищаем текст персонализированного сообщения и проверку + inputs=[], + outputs=[personalized_output_text_gigachat_plus, validation_display_3] + ).then( + fn=regen_message_gigachat_plus, + inputs=[description_input, advantages_input, key_message_input, approach_input] + selections, + outputs=output_text_gigachat_plus + ) + + regen_gpt4o_btn.click( + fn=lambda: ("", ""), # Очищаем текст персонализированного сообщения и проверку + inputs=[], + outputs=[personalized_output_text_gpt4o, validation_display_4] + ).then( + fn=regen_message_gpt4o, + inputs=[description_input, advantages_input, key_message_input, approach_input] + selections, + outputs=output_text_gpt4o + ) + + regen_meta_llama_405b_btn.click( + fn=lambda: ("", ""), # Очищаем текст персонализированного сообщения и проверку + inputs=[], + outputs=[personalized_output_text_meta_llama_405b, validation_display_5] + ).then( + fn=regen_message_meta_llama_405b, + inputs=[description_input, advantages_input, key_message_input, approach_input] + selections, + outputs=output_text_meta_llama_405b + ) + + personalize_gigachat_pro_btn.click( + personalize_message_gigachat_pro, + inputs=[output_text_gigachat_pro, key_message_input, approach_input] + selections, + outputs=[personalized_output_text_gigachat_pro, validation_display_1] + ).then( + fn=generate_personalization_prompt, # Вызов генерации промпта + inputs=[key_message_input, approach_input] + selections, # Передача нужных данных + outputs=personalization_prompt # Вывод в поле с промптом + ) + + personalize_gigachat_lite_btn.click( + personalize_message_gigachat_lite, + inputs=[output_text_gigachat_lite, key_message_input, approach_input] + selections, + outputs=[personalized_output_text_gigachat_lite, validation_display_2] # Поле для проверки + ).then( + fn=generate_personalization_prompt, # Вызов генерации промпта + inputs=[key_message_input, approach_input] + selections, # Передача нужных данных + outputs=personalization_prompt # Вывод в поле с промптом + ) + + personalize_gigachat_plus_btn.click( + personalize_message_gigachat_plus, + inputs=[output_text_gigachat_plus, key_message_input, approach_input] + selections, + outputs=[personalized_output_text_gigachat_plus, validation_display_3] # Добавляем результат проверки + ).then( + fn=generate_personalization_prompt, # Вызов генерации промпта + inputs=[key_message_input, approach_input] + selections, # Передача нужных данных + outputs=personalization_prompt # Вывод в поле с промптом + ) + + personalize_gpt4o_btn.click( + personalize_message_gpt4o, + inputs=[output_text_gpt4o, key_message_input, approach_input] + selections, + outputs=[personalized_output_text_gpt4o, validation_display_4] # Добавляем результат проверки + ).then( + fn=generate_personalization_prompt, # Вызов генерации промпта + inputs=[key_message_input, approach_input] + selections, # Передача нужных данных + outputs=personalization_prompt # Вывод в поле с промптом + ) + + personalize_meta_llama_405b_btn.click( + personalize_message_meta_llama_405b, + inputs=[output_text_meta_llama_405b, key_message_input, approach_input] + selections, + outputs=[personalized_output_text_meta_llama_405b, validation_display_5] # Добавляем результат проверки + ).then( + fn=generate_personalization_prompt, # Вызов генерации промпта + inputs=[key_message_input, approach_input] + selections, # Передача нужных данных + outputs=personalization_prompt # Вывод в поле с промптом + ) + + + # Привязка кнопок к функциям сохранения + save_gigachat_pro_btn.click( + fn=prepare_button_text, + inputs=[], + outputs=[save_gigachat_pro_btn] + ).then( + fn=lambda personalized_message, comment, corrected_message, description, advantages, non_personalized_prompt, non_personalized_message, personalization_prompt, gender, generation, psychotype, business_stage, industry, legal_form, key_message, approach: + save_to_github(personalized_message, "GigaChat-Pro", comment, corrected_message, description, advantages, non_personalized_prompt, non_personalized_message, personalization_prompt, gender, generation, psychotype, business_stage, industry, legal_form, key_message, approach), + inputs=[ + personalized_output_text_gigachat_pro, + comment_gigachat_pro, + corrected_gigachat_pro, + description_input, + advantages_input, + prompt_display, + output_text_gigachat_pro, + personalization_prompt, + selections[0], # Пол + selections[1], # Поколение + selections[2], # Психотип + selections[3], # Стадия бизнеса + selections[4], # Отрасль + selections[5], # ОПФ + key_message_input, # Ключевое сообщение + approach_input # Подход + ], + outputs=None + ).then( + fn=update_button_text, + outputs=[save_gigachat_pro_btn] + ).then( + fn=reset_button_text, + outputs=[save_gigachat_pro_btn] + ) + + # Повторяем аналогично для других кнопок: + save_gigachat_lite_btn.click( + fn=prepare_button_text, + inputs=[], + outputs=[save_gigachat_lite_btn] + ).then( + fn=lambda personalized_message, comment, corrected_message, description, advantages, non_personalized_prompt, non_personalized_message, personalization_prompt, gender, generation, psychotype, business_stage, industry, legal_form, key_message, approach: + save_to_github(personalized_message, "GigaChat-Lite", comment, corrected_message, description, advantages, non_personalized_prompt, non_personalized_message, personalization_prompt, gender, generation, psychotype, business_stage, industry, legal_form, key_message, approach), + inputs=[ + personalized_output_text_gigachat_lite, + comment_gigachat_lite, + corrected_gigachat_lite, + description_input, + advantages_input, + prompt_display, + output_text_gigachat_lite, + personalization_prompt, + selections[0], # Пол + selections[1], # Поколение + selections[2], # Психотип + selections[3], # Стадия бизнеса + selections[4], # Отрасль + selections[5], # ОПФ + key_message_input, # Ключевое сообщение + approach_input # Подход + ], + outputs=None + ).then( + fn=update_button_text, + outputs=[save_gigachat_lite_btn] + ).then( + fn=reset_button_text, + outputs=[save_gigachat_lite_btn] + ) + + + save_gigachat_plus_btn.click( + fn=prepare_button_text, + inputs=[], + outputs=[save_gigachat_plus_btn] + ).then( + fn=lambda personalized_message, comment, corrected_message, description, advantages, non_personalized_prompt, non_personalized_message, personalization_prompt, gender, generation, psychotype, business_stage, industry, legal_form, key_message, approach: + save_to_github(personalized_message, "GigaChat-Lite+", comment, corrected_message, description, advantages, non_personalized_prompt, non_personalized_message, personalization_prompt, gender, generation, psychotype, business_stage, industry, legal_form, key_message, approach), + inputs=[ + personalized_output_text_gigachat_plus, + comment_gigachat_plus, + corrected_gigachat_plus, + description_input, + advantages_input, + prompt_display, + output_text_gigachat_plus, + personalization_prompt, + selections[0], # Пол + selections[1], # Поколение + selections[2], # Психотип + selections[3], # Стадия бизнеса + selections[4], # Отрасль + selections[5], # ОПФ + key_message_input, # Ключевое сообщение + approach_input # Подход + ], + outputs=None + ).then( + fn=update_button_text, + outputs=[save_gigachat_plus_btn] + ).then( + fn=reset_button_text, + outputs=[save_gigachat_plus_btn] + ) + + save_gpt4o_btn.click( + fn=prepare_button_text, # Сначала меняем текст на "Сохраняется..." + inputs=[], + outputs=[save_gpt4o_btn] + ).then( + fn=lambda personalized_message, comment, corrected_message, description, advantages, non_personalized_prompt, non_personalized_message, personalization_prompt, gender, generation, psychotype, business_stage, industry, legal_form, key_message, approach: + save_to_github(personalized_message, "GPT-4o", comment, corrected_message, description, advantages, non_personalized_prompt, non_personalized_message, personalization_prompt, gender, generation, psychotype, business_stage, industry, legal_form, key_message, approach), + inputs=[ + personalized_output_text_gpt4o, + comment_gpt4o, + corrected_gpt4o, + description_input, + advantages_input, + prompt_display, + output_text_gpt4o, + personalization_prompt, + selections[0], # Пол + selections[1], # Поколение + selections[2], # Психотип + selections[3], # Стадия бизнеса + selections[4], # Отрасль + selections[5], # ОПФ + key_message_input, # Ключевое сообщение + approach_input # Подход + ], + outputs=None + ).then( + fn=update_button_text, # Обновляем текст на "Сохранено!" после сохранения + outputs=[save_gpt4o_btn] + ).then( + fn=reset_button_text, # Возвращаем текст на кнопке обратно через 3 секунды + outputs=[save_gpt4o_btn] + ) + + save_meta_llama_405b_btn.click( + fn=prepare_button_text, + inputs=[], + outputs=[save_meta_llama_405b_btn] + ).then( + fn=lambda personalized_message, comment, corrected_message, description, advantages, non_personalized_prompt, non_personalized_message, personalization_prompt, gender, generation, psychotype, business_stage, industry, legal_form, key_message, approach: + save_to_github(personalized_message, "Meta-Llama-3.1-405B", comment, corrected_message, description, advantages, non_personalized_prompt, non_personalized_message, personalization_prompt, gender, generation, psychotype, business_stage, industry, legal_form, key_message, approach), + inputs=[ + personalized_output_text_meta_llama_405b, + comment_meta_llama_405b, + corrected_meta_llama_405b, + description_input, + advantages_input, + prompt_display, + output_text_meta_llama_405b, + personalization_prompt, + selections[0], # Пол + selections[1], # Поколение + selections[2], # Психотип + selections[3], # Стадия бизнеса + selections[4], # Отрасль + selections[5], # ОПФ + key_message_input, # Ключевое сообщение + approach_input # Подход + ], + outputs=None + ).then( + fn=update_button_text, + outputs=[save_meta_llama_405b_btn] + ).then( + fn=reset_button_text, + outputs=[save_meta_llama_405b_btn] + ) + + # Обработчик нажатия кнопки +# analyze_btn.click( +# fn=perform_analysis_with_yield, +# inputs=[ +# output_text_gigachat_pro, +# output_text_gigachat_lite, +# output_text_gigachat_plus, +# output_text_gpt4o, +# output_text_meta_llama_405b, +# personalization_prompt +# ], +# outputs=[ +# analysis_gigachat_pro, +# analysis_gigachat_lite, +# analysis_gigachat_plus, +# analysis_gpt4o, +# analysis_meta_llama_405b +# ] +# ) + + + demo.launch() \ No newline at end of file