Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -10,6 +10,7 @@ import base64
|
|
10 |
import time
|
11 |
from openai import OpenAI
|
12 |
import string
|
|
|
13 |
|
14 |
XAI_API_KEY = os.getenv("XAI_API_KEY")
|
15 |
client = OpenAI(
|
@@ -455,21 +456,17 @@ def process_message(message, product_name):
|
|
455 |
|
456 |
return final_message
|
457 |
|
458 |
-
def
|
459 |
last_message = ""
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
last_message = msg
|
470 |
-
length = len(last_message)
|
471 |
-
last_message += f"\n\n------\nКоличество знаков: {length}"
|
472 |
-
return last_message
|
473 |
|
474 |
def update_prompts_on_params_change(description, product_name, benefits, key_message,
|
475 |
gender, generation, psychotype, business_stage, industry, opf):
|
@@ -1193,6 +1190,16 @@ def lemmatize_word(word, morph):
|
|
1193 |
best = parsed[0]
|
1194 |
return best.normal_form, best.tag.POS
|
1195 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1196 |
# 1. Запрещенные слова
|
1197 |
|
1198 |
def check_forbidden_words(message, exceptions=None):
|
@@ -1756,6 +1763,112 @@ def check_no_word_repetitions(message, key_message, exceptions=None):
|
|
1756 |
|
1757 |
# ФУНКЦИИ ПРОВЕРОК (КОНЕЦ)
|
1758 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1759 |
def cut_message(message: str):
|
1760 |
if '------' in message:
|
1761 |
message = message.split('------')[0].strip()
|
|
|
10 |
import time
|
11 |
from openai import OpenAI
|
12 |
import string
|
13 |
+
import math
|
14 |
|
15 |
XAI_API_KEY = os.getenv("XAI_API_KEY")
|
16 |
client = OpenAI(
|
|
|
456 |
|
457 |
return final_message
|
458 |
|
459 |
+
def generate_message(model_prompt, product_name):
|
460 |
last_message = ""
|
461 |
+
msg = call_model(model_prompt)
|
462 |
+
msg = correct_dash_usage(msg)
|
463 |
+
msg = clean_message(msg)
|
464 |
+
msg = process_message(msg, product_name)
|
465 |
+
length = len(msg)
|
466 |
+
last_message = msg
|
467 |
+
length = len(msg)
|
468 |
+
msg += f"\n\n------\nКоличество знаков: {length}"
|
469 |
+
return msg
|
|
|
|
|
|
|
|
|
470 |
|
471 |
def update_prompts_on_params_change(description, product_name, benefits, key_message,
|
472 |
gender, generation, psychotype, business_stage, industry, opf):
|
|
|
1190 |
best = parsed[0]
|
1191 |
return best.normal_form, best.tag.POS
|
1192 |
|
1193 |
+
# 0. Проверка на длину
|
1194 |
+
|
1195 |
+
def check_length(message):
|
1196 |
+
length = len(message)
|
1197 |
+
if 160 <= length <= 250:
|
1198 |
+
return True
|
1199 |
+
else:
|
1200 |
+
logging.warning(f"Не пройдена проверка: Длина сообщения {length} символов. Сообщение: {message}")
|
1201 |
+
return False
|
1202 |
+
|
1203 |
# 1. Запрещенные слова
|
1204 |
|
1205 |
def check_forbidden_words(message, exceptions=None):
|
|
|
1763 |
|
1764 |
# ФУНКЦИИ ПРОВЕРОК (КОНЕЦ)
|
1765 |
|
1766 |
+
CRITICAL_CHECKS = [
|
1767 |
+
"length_check",
|
1768 |
+
"forbidden_words",
|
1769 |
+
"client_addressing",
|
1770 |
+
"promises",
|
1771 |
+
"subordinate_clauses_chain",
|
1772 |
+
"introductory_phrases",
|
1773 |
+
"dates_written_out"
|
1774 |
+
]
|
1775 |
+
|
1776 |
+
NON_CRITICAL_CHECKS = [
|
1777 |
+
"double_verbs",
|
1778 |
+
"participles",
|
1779 |
+
"adverbial_participles",
|
1780 |
+
"superlative_adjectives",
|
1781 |
+
"passive_voice",
|
1782 |
+
"repeating_conjunctions",
|
1783 |
+
"amplifiers",
|
1784 |
+
"time_parasites",
|
1785 |
+
"multiple_nouns",
|
1786 |
+
"derived_prepositions",
|
1787 |
+
"compound_sentences",
|
1788 |
+
"word_repetitions",
|
1789 |
+
]
|
1790 |
+
|
1791 |
+
def run_checks_critical_and_non_critical(message: str, key_message: str) -> (bool, list):
|
1792 |
+
"""
|
1793 |
+
Возвращает (all_critical_passed: bool, failed_non_critical: list[str])
|
1794 |
+
где failed_non_critical = список названий проверок, которые не пройдены, но не являются критическими.
|
1795 |
+
"""
|
1796 |
+
checks = perform_checks(message, key_message) # ваша функция, которая возвращает dict
|
1797 |
+
|
1798 |
+
all_critical_passed = True
|
1799 |
+
failed_non_critical = []
|
1800 |
+
|
1801 |
+
for rule_name, result in checks.items():
|
1802 |
+
# result либо True/False, либо (False, reason)
|
1803 |
+
if isinstance(result, tuple):
|
1804 |
+
pass_flag = result[0]
|
1805 |
+
else:
|
1806 |
+
pass_flag = bool(result)
|
1807 |
+
|
1808 |
+
if rule_name in CRITICAL_CHECKS:
|
1809 |
+
if not pass_flag: # Критическая не пройдена
|
1810 |
+
all_critical_passed = False
|
1811 |
+
elif rule_name in NON_CRITICAL_CHECKS:
|
1812 |
+
if not pass_flag:
|
1813 |
+
failed_non_critical.append(rule_name)
|
1814 |
+
else:
|
1815 |
+
# Все проверки, которых нет ни в CRITICAL_CHECKS, ни в NON_CRITICAL_CHECKS — игнорируем
|
1816 |
+
pass
|
1817 |
+
|
1818 |
+
return all_critical_passed, failed_non_critical
|
1819 |
+
|
1820 |
+
|
1821 |
+
def attempt_generate_sms_with_checks(model_prompt: str, product_name: str, key_message: str):
|
1822 |
+
"""
|
1823 |
+
Генерирует 1 SMS + запускает run_checks_critical_and_non_critical.
|
1824 |
+
Возвращает (sms, all_critical_ok, failed_non_critical_list).
|
1825 |
+
"""
|
1826 |
+
sms = generate_message(model_prompt, product_name)
|
1827 |
+
cut_sms = cut_message(sms)
|
1828 |
+
all_critical_ok, failed_non_critical = run_checks_critical_and_non_critical(cut_sms, key_message)
|
1829 |
+
return sms, all_critical_ok, failed_non_critical
|
1830 |
+
|
1831 |
+
|
1832 |
+
def generate_sms_with_timer(model_prompt: str, product_name: str, key_message: str, max_time_sec=120):
|
1833 |
+
"""
|
1834 |
+
Псевдо-синхронный цикл с таймером 120 секунд.
|
1835 |
+
Возвращает "оптимальный" SMS,
|
1836 |
+
или строку "Не удалось за 2 минуты создать SMS, прошедшее все критические проверки".
|
1837 |
+
"""
|
1838 |
+
start = time.time()
|
1839 |
+
best_sms = None
|
1840 |
+
best_non_crit_count = math.inf # сколько некритич. проверок не пройдено (минимизируем)
|
1841 |
+
|
1842 |
+
while True:
|
1843 |
+
now = time.time()
|
1844 |
+
if now - start > max_time_sec:
|
1845 |
+
# время вышло
|
1846 |
+
break
|
1847 |
+
|
1848 |
+
sms, crit_ok, failed_non_crit = attempt_generate_sms_with_checks(model_prompt, product_name, key_message)
|
1849 |
+
|
1850 |
+
if crit_ok:
|
1851 |
+
# значит SMS прошло все критические
|
1852 |
+
non_crit_count = len(failed_non_crit)
|
1853 |
+
if non_crit_count == 0:
|
1854 |
+
# идеально
|
1855 |
+
return sms # тут же возвращаем
|
1856 |
+
# если не 0, то проверяем, лучше ли, чем best_sms
|
1857 |
+
if non_crit_count < best_non_crit_count:
|
1858 |
+
best_non_crit_count = non_crit_count
|
1859 |
+
best_sms = sms
|
1860 |
+
else:
|
1861 |
+
# crit fail => пропускаем
|
1862 |
+
pass
|
1863 |
+
|
1864 |
+
# если цикл завершился по таймеру:
|
1865 |
+
if best_sms is not None:
|
1866 |
+
# вернём лучшее, что есть
|
1867 |
+
return best_sms
|
1868 |
+
else:
|
1869 |
+
# значит не было ни одного SMS, прошедшего критические проверки
|
1870 |
+
return "Не удалось за 2 минуты создать SMS, прошедшее все критические проверки."
|
1871 |
+
|
1872 |
def cut_message(message: str):
|
1873 |
if '------' in message:
|
1874 |
message = message.split('------')[0].strip()
|