fruitpicker01 commited on
Commit
fa16e93
1 Parent(s): 3316769

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +86 -66
app.py CHANGED
@@ -19,6 +19,9 @@ import io
19
  from transformers import AutoTokenizer, AutoModel
20
  from utils import best_text_choice
21
 
 
 
 
22
  tokenizer = AutoTokenizer.from_pretrained("ai-forever/ru-en-RoSBERTa")
23
  model = AutoModel.from_pretrained("ai-forever/ru-en-RoSBERTa")
24
  # Load the DataFrame used in the best_text_choice function
@@ -37,24 +40,24 @@ morph = pymorphy3.MorphAnalyzer()
37
 
38
  # Авторизация в GigaChat Pro
39
  gc_key = os.getenv('GC_KEY')
40
- chat_pro = GigaChat(credentials=gc_key, model='GigaChat', max_tokens=68, temperature=1.15, verify_ssl_certs=False)
41
- chat_pro = GigaChat(
42
- credentials=gc_key,
43
- model='GigaChat-Pro-preview',
44
- base_url='https://gigachat-preview.devices.sberbank.ru/api/v1/',
45
- max_tokens=68,
46
- temperature=1.15,
47
- verify_ssl_certs=False
48
- )
49
-
50
- chat_pro_check = GigaChat(
51
- credentials=gc_key,
52
- model='GigaChat-Pro-preview',
53
- base_url='https://gigachat-preview.devices.sberbank.ru/api/v1/',
54
- max_tokens=3000,
55
- temperature=0.8,
56
- verify_ssl_certs=False
57
- )
58
 
59
  approach_stats = {
60
  "Начни сообщение с призыва к действию с продуктом. Не начинай с вопроса.": {"failed_checks": defaultdict(int), "total_attempts": 0},
@@ -189,12 +192,21 @@ def clean_message(message):
189
  # return f"Ошибка при обращении к GigaChat-Pro: {e}"
190
 
191
  #def generate_message_mistral_generate(prompt, max_retries=5):
192
- def generate_message_mistral_generate(prompt):
193
  try:
194
- messages = [SystemMessage(content=prompt)]
195
- res = chat_pro(messages)
196
- cleaned_message = clean_message(res.content.strip())
197
- return cleaned_message
 
 
 
 
 
 
 
 
 
198
  except Exception as e:
199
  return f"Ошибка при обращении к GigaChat-Pro: {e}"
200
 
@@ -229,12 +241,21 @@ def generate_message_mistral_generate(prompt):
229
  # return None
230
 
231
  #def generate_message_mistral_check(prompt, max_retries=5):
232
- def generate_message_mistral_check(prompt):
233
  try:
234
- messages = [SystemMessage(content=prompt)]
235
- res2 = chat_pro_check(messages)
236
- cleaned_message = clean_message(res2.content.strip())
237
- return cleaned_message
 
 
 
 
 
 
 
 
 
238
  except Exception as e:
239
  return f"Ошибка при обращении к GigaChat-Pro: {e}"
240
  # retries = 0
@@ -545,24 +566,22 @@ def notify_failed_checks(checks):
545
  # return last_message
546
 
547
 
548
- def generate_message_mistral_with_retry(prompt, approach_name, description, key_message, product_name, benefits):
549
  global approach_stats
550
  last_message = None
551
  for attempt in range(20):
552
  gr.Info(f"Итерация {attempt + 1}: генерируется сообщение...")
553
- message = generate_message_mistral_generate(prompt)
554
  if message is None:
555
- print("Не удалось получить сообщение от Mistral, повторная попытка...")
556
- time.sleep(1)
557
  continue
558
  message = replace_k_with_thousands(message)
559
  message = correct_dash_usage(message)
560
  message_length = len(message)
561
  if not notify_failed_length(message_length):
562
  last_message = message
563
- time.sleep(1)
564
  continue
565
- checks = perform_checks(message, description, key_message, product_name, benefits)
566
  last_message = message
567
  # Инициализируем статистику для подхода, если ее нет
568
  if approach_name not in approach_stats:
@@ -576,7 +595,6 @@ def generate_message_mistral_with_retry(prompt, approach_name, description, key_
576
  if all(checks.values()):
577
  return message
578
  prompt = append_errors_to_prompt(prompt, checks)
579
- time.sleep(1)
580
  gr.Info("Переходим к следующему циклу итераций.")
581
  return last_message
582
 
@@ -697,7 +715,7 @@ def are_messages_equal(message1, message2):
697
  return message1.strip().lower() == message2.strip().lower()
698
 
699
  # Функция для постепенной генерации всех сообщений через yield
700
- def generate_all_messages(desc, benefits, key_message, gender, generation, psychotype, business_stage, industry, opf, product_name):
701
  standard_prompt = generate_standard_prompt(desc, benefits, key_message)
702
  standard_prompt_for_display = f"Не изменяй название продукта: {product_name}.\n{standard_prompt}\nУбедись, что в готовом тексте без изменений, синонимов и перестановок слов используется наименование продукта: {product_name}.\n"
703
  approach_mapping = {
@@ -769,7 +787,7 @@ def generate_all_messages(desc, benefits, key_message, gender, generation, psych
769
  yield selected_approaches_text_content, standard_prompt_for_display, display_personalization_prompt, None, None
770
  flag += 1
771
  prompt = add_prefix_suffix(standard_prompt, current_prefix, current_suffix, product_name)
772
- non_personalized_message = generate_message_mistral_with_retry(prompt, approach_name, desc, key_message, product_name, benefits)
773
  non_personalized_length = len(non_personalized_message)
774
  non_personalized_display = f"{non_personalized_message}\n------\nКоличество знаков: {non_personalized_length}"
775
  if non_personalized_messages:
@@ -784,7 +802,7 @@ def generate_all_messages(desc, benefits, key_message, gender, generation, psych
784
  # **Добавляем перегенерацию персонализированного сообщения**
785
  personalized_message = None
786
  for attempt in range(5): # Максимум 5 попыток
787
- personalized_message_candidate = generate_message_mistral_with_retry(
788
  f"{personalization_prompt}\n\nТекст для адаптации: {non_personalized_message}",
789
  approach_name, desc, key_message, product_name, benefits
790
  )
@@ -1313,7 +1331,7 @@ def check_disconnected_sentences(message):
1313
  return None
1314
 
1315
  # 23. Проверка на близкие по смыслу однородные члены
1316
- def check_synonymous_members(message):
1317
  print()
1318
  print("Проверка 23: Проверка на близкие по смыслу однородные члены")
1319
  print()
@@ -1327,7 +1345,7 @@ def check_synonymous_members(message):
1327
  если таких слов или выражений нет, **верни только** JSON {{"decision": false, "explanation": "<пояснение>"}}.
1328
  **Не добавляй никакого дополнительного текста. Перед ответом убедись, что отвечаешь только в формате JSON с закрывающими кавычками и скобками.**'''
1329
 
1330
- response = generate_message_mistral_check(prompt)
1331
  time.sleep(3)
1332
  print("GigaChat Pro response:", response)
1333
  result = parse_json_response(response)
@@ -1341,7 +1359,7 @@ def check_synonymous_members(message):
1341
 
1342
 
1343
  # 24. Проверка на шокирующие, экстравагантные или кликбейтные фразы
1344
- def check_clickbait_phrases(message, description, benefits, key_message):
1345
  message_clean = cut_message(message)
1346
  print()
1347
  print()
@@ -1366,7 +1384,7 @@ def check_clickbait_phrases(message, description, benefits, key_message):
1366
 
1367
  **Не добавляй никакого дополнительного текста. Перед ответом убедись, что отвечаешь только в формате JSON с закрывающими кавычками и скобками.**'''
1368
 
1369
- response = generate_message_mistral_check(prompt)
1370
  time.sleep(3)
1371
  print("GigaChat Pro response:", response)
1372
  result = parse_json_response(response)
@@ -1380,7 +1398,7 @@ def check_clickbait_phrases(message, description, benefits, key_message):
1380
 
1381
 
1382
  # 25. Проверка на абстрактные заявления без поддержки фактами
1383
- def check_abstract_claims(message, description, benefits, key_message):
1384
  print()
1385
  print("Проверка 25: Проверка на абстрактные заявления без поддержки фактами")
1386
  print()
@@ -1419,7 +1437,7 @@ def check_abstract_claims(message, description, benefits, key_message):
1419
 
1420
  **Не добавляй никакого дополнительного текста. Перед ответом убедись, что отвечаешь только в формате JSON с закрывающими кавычками и скобками.**'''
1421
 
1422
- response = generate_message_mistral_check(prompt)
1423
  time.sleep(3)
1424
  print("GigaChat Pro response:", response)
1425
  result = parse_json_response(response)
@@ -1498,7 +1516,7 @@ def check_offensive_phrases(message):
1498
  return None
1499
 
1500
  # 28. Проверка на речевые клише, рекламные штампы и канцеляризмы
1501
- def check_cliches_and_bureaucratese(message, description, benefits, key_message):
1502
  print()
1503
  print("Проверка 28: Проверка на речевые клише, рекламные штампы и канцеляризмы")
1504
  print()
@@ -1531,7 +1549,7 @@ def check_cliches_and_bureaucratese(message, description, benefits, key_message)
1531
  если в тексте **есть** такие выражения, **верни только** JSON {{"decision": true, "explanation": "<пояснение>"}}.
1532
  **Не добавляй никакого дополнительного текста. Перед ответом убедись, что отвечаешь только в формате JSON с закрывающими кавычками и скобками.**'''
1533
 
1534
- response = generate_message_mistral_check(prompt)
1535
  time.sleep(3)
1536
  print("GigaChat Pro response:", response)
1537
  result = parse_json_response(response)
@@ -1544,7 +1562,7 @@ def check_cliches_and_bureaucratese(message, description, benefits, key_message)
1544
  return None
1545
 
1546
  # 29. Проверка на соответствие описанию предложения и ключевому сообщению
1547
- def check_no_contradictions(message, description, benefits, key_message):
1548
  print()
1549
  print("Проверка 29: Проверка на отсутствие противоречий с описанием предложения")
1550
  print()
@@ -1562,7 +1580,7 @@ def check_no_contradictions(message, description, benefits, key_message):
1562
  Если сообщение содержит факты, которые отсутствуют в описании предложения и ключевом сообщении, **верни только** JSON {{"decision": true, "explanation": "<описание противоречий>"}}.
1563
  **Не добавляй никакого дополнительного текста. Отвечай только в формате JSON с закрывающими кавычками и скобками.**'''
1564
 
1565
- response = generate_message_mistral_check(prompt)
1566
  time.sleep(3)
1567
  print("GigaChat Pro response:", response)
1568
  result = parse_json_response(response)
@@ -1575,7 +1593,7 @@ def check_no_contradictions(message, description, benefits, key_message):
1575
  return None
1576
 
1577
  # 30. Проверка на наличие ключевого сообщения
1578
- def check_contains_key_message(message, key_message):
1579
  print()
1580
  print("Проверка 30: Проверка на наличие ключевого сообщения")
1581
  print()
@@ -1589,7 +1607,7 @@ def check_contains_key_message(message, key_message):
1589
  Если сообщение **не содержит всю** информацию из ключевого текста, **верни только** JSON {{"decision": true, "explanation": "Ключевое текст отсутствует."}}.
1590
  **Не добавляй никакого дополнительного текста. Отвечай только в формате JSON с закрывающими кавычками и скобками.**'''
1591
 
1592
- response = generate_message_mistral_check(prompt)
1593
  time.sleep(3)
1594
  print("GigaChat Pro response:", response)
1595
  result = parse_json_response(response)
@@ -1602,7 +1620,7 @@ def check_contains_key_message(message, key_message):
1602
  return None
1603
 
1604
  # 31. Проверка на точное совпадение названий продуктов
1605
- def check_product_name_consistency(message, product_name):
1606
  print()
1607
  print("Проверка 31: Проверка на точное совпадение названий продуктов")
1608
  print()
@@ -1619,7 +1637,7 @@ def check_product_name_consistency(message, product_name):
1619
  Если название продукта **не** совпадает, **верни только** JSON {{"decision": true, "explanation": "<описание несоответствия>"}}.
1620
  **Не добавляй никакого дополнительного текста. Ответ должен быть только в формате JSON с закрывающими кавычками и скобками.**'''
1621
 
1622
- response = generate_message_mistral_check(prompt)
1623
  time.sleep(3)
1624
  print("GigaChat Pro response:", response)
1625
  result = parse_json_response(response)
@@ -1634,15 +1652,17 @@ def check_product_name_consistency(message, product_name):
1634
  # ФУНКЦИИ ПРОВЕРОК (КОНЕЦ)
1635
 
1636
 
1637
- def safe_check(func, *args):
1638
  try:
1639
- return func(*args)
 
 
 
1640
  except Exception as e:
1641
- # Optionally, you can log the exception here if needed
1642
- print(f"Ошибка в {func.__name__}: {e}")
1643
- return None # Indicate that the check could not be performed
1644
 
1645
- def perform_checks(message, description, key_message, product_name, benefits):
1646
  checks = {}
1647
 
1648
  # 2. Morphological checks using pymorphy3
@@ -1688,7 +1708,7 @@ def perform_checks(message, description, key_message, product_name, benefits):
1688
 
1689
  # Perform morphological checks
1690
  for check_name, check_func in morphological_checks:
1691
- result = safe_check(check_func, message)
1692
  checks[check_name] = result
1693
  if result is False:
1694
  return checks # Stop on first failure
@@ -1696,19 +1716,19 @@ def perform_checks(message, description, key_message, product_name, benefits):
1696
  # Perform LLM checks group 1
1697
  for check_name, check_func in llm_checks_group1:
1698
  if check_name == "no_contradictions":
1699
- result = safe_check(check_func, message, description, benefits, key_message)
1700
  elif check_name == "contains_key_message":
1701
- result = safe_check(check_func, message, key_message)
1702
  elif check_name == "product_name_consistency":
1703
- result = safe_check(check_func, message, product_name)
1704
  elif check_name == "clickbait_phrases":
1705
- result = safe_check(check_func, message, description, benefits, key_message)
1706
  elif check_name == "abstract_claims":
1707
- result = safe_check(check_func, message, description, benefits, key_message)
1708
  elif check_name == "cliches_and_bureaucratese":
1709
- result = safe_check(check_func, message, description, benefits, key_message)
1710
  else:
1711
- result = safe_check(check_func, message)
1712
  checks[check_name] = result
1713
  if result is False:
1714
  return checks
 
19
  from transformers import AutoTokenizer, AutoModel
20
  from utils import best_text_choice
21
 
22
+ import httpx
23
+ import asyncio
24
+
25
  tokenizer = AutoTokenizer.from_pretrained("ai-forever/ru-en-RoSBERTa")
26
  model = AutoModel.from_pretrained("ai-forever/ru-en-RoSBERTa")
27
  # Load the DataFrame used in the best_text_choice function
 
40
 
41
  # Авторизация в GigaChat Pro
42
  gc_key = os.getenv('GC_KEY')
43
+ #chat_pro = GigaChat(credentials=gc_key, model='GigaChat', max_tokens=68, temperature=1.15, verify_ssl_certs=False)
44
+ #chat_pro = GigaChat(
45
+ # credentials=gc_key,
46
+ # model='GigaChat-Pro-preview',
47
+ # base_url='https://gigachat-preview.devices.sberbank.ru/api/v1/',
48
+ # max_tokens=68,
49
+ # temperature=1.15,
50
+ # verify_ssl_certs=False
51
+ #)
52
+
53
+ #chat_pro_check = GigaChat(
54
+ # credentials=gc_key,
55
+ # model='GigaChat-Pro-preview',
56
+ # base_url='https://gigachat-preview.devices.sberbank.ru/api/v1/',
57
+ # max_tokens=3000,
58
+ # temperature=0.8,
59
+ # verify_ssl_certs=False
60
+ #)
61
 
62
  approach_stats = {
63
  "Начни сообщение с призыва к действию с продуктом. Не начинай с вопроса.": {"failed_checks": defaultdict(int), "total_attempts": 0},
 
192
  # return f"Ошибка при обращении к GigaChat-Pro: {e}"
193
 
194
  #def generate_message_mistral_generate(prompt, max_retries=5):
195
+ async def generate_message_mistral_generate(prompt):
196
  try:
197
+ async with httpx.AsyncClient() as client:
198
+ response = await client.post(
199
+ "https://gigachat-preview.devices.sberbank.ru/api/v1/",
200
+ headers={
201
+ "Authorization": f"Bearer {gc_key}",
202
+ "Content-Type": "application/json"
203
+ },
204
+ json={"messages": [{"role": "system", "content": prompt}]}
205
+ )
206
+ response.raise_for_status()
207
+ res = response.json()
208
+ cleaned_message = clean_message(res.get("content", "").strip())
209
+ return cleaned_message
210
  except Exception as e:
211
  return f"Ошибка при обращении к GigaChat-Pro: {e}"
212
 
 
241
  # return None
242
 
243
  #def generate_message_mistral_check(prompt, max_retries=5):
244
+ async def generate_message_mistral_check(prompt):
245
  try:
246
+ async with httpx.AsyncClient() as client:
247
+ response = await client.post(
248
+ "https://gigachat-preview.devices.sberbank.ru/api/v1/",
249
+ headers={
250
+ "Authorization": f"Bearer {gc_key}",
251
+ "Content-Type": "application/json"
252
+ },
253
+ json={"messages": [{"role": "system", "content": prompt}]}
254
+ )
255
+ response.raise_for_status()
256
+ res2 = response.json()
257
+ cleaned_message = clean_message(res2.get("content", "").strip())
258
+ return cleaned_message
259
  except Exception as e:
260
  return f"Ошибка при обращении к GigaChat-Pro: {e}"
261
  # retries = 0
 
566
  # return last_message
567
 
568
 
569
+ async def generate_message_mistral_with_retry(prompt, approach_name, description, key_message, product_name, benefits):
570
  global approach_stats
571
  last_message = None
572
  for attempt in range(20):
573
  gr.Info(f"Итерация {attempt + 1}: генерируется сообщение...")
574
+ message = await generate_message_mistral_generate(prompt)
575
  if message is None:
576
+ print("Не удалось получить с��общение от GigaChat Pro, повторная попытка...")
 
577
  continue
578
  message = replace_k_with_thousands(message)
579
  message = correct_dash_usage(message)
580
  message_length = len(message)
581
  if not notify_failed_length(message_length):
582
  last_message = message
 
583
  continue
584
+ checks = await perform_checks(message, description, key_message, product_name, benefits)
585
  last_message = message
586
  # Инициализируем статистику для подхода, если ее нет
587
  if approach_name not in approach_stats:
 
595
  if all(checks.values()):
596
  return message
597
  prompt = append_errors_to_prompt(prompt, checks)
 
598
  gr.Info("Переходим к следующему циклу итераций.")
599
  return last_message
600
 
 
715
  return message1.strip().lower() == message2.strip().lower()
716
 
717
  # Функция для постепенной генерации всех сообщений через yield
718
+ async def generate_all_messages(desc, benefits, key_message, gender, generation, psychotype, business_stage, industry, opf, product_name):
719
  standard_prompt = generate_standard_prompt(desc, benefits, key_message)
720
  standard_prompt_for_display = f"Не изменяй название продукта: {product_name}.\n{standard_prompt}\nУбедись, что в готовом тексте без изменений, синонимов и перестановок слов используется наименование продукта: {product_name}.\n"
721
  approach_mapping = {
 
787
  yield selected_approaches_text_content, standard_prompt_for_display, display_personalization_prompt, None, None
788
  flag += 1
789
  prompt = add_prefix_suffix(standard_prompt, current_prefix, current_suffix, product_name)
790
+ non_personalized_message = await generate_message_mistral_with_retry(prompt, approach_name, desc, key_message, product_name, benefits)
791
  non_personalized_length = len(non_personalized_message)
792
  non_personalized_display = f"{non_personalized_message}\n------\nКоличество знаков: {non_personalized_length}"
793
  if non_personalized_messages:
 
802
  # **Добавляем перегенерацию персонализированного сообщения**
803
  personalized_message = None
804
  for attempt in range(5): # Максимум 5 попыток
805
+ personalized_message_candidate = await generate_message_mistral_with_retry(
806
  f"{personalization_prompt}\n\nТекст для адаптации: {non_personalized_message}",
807
  approach_name, desc, key_message, product_name, benefits
808
  )
 
1331
  return None
1332
 
1333
  # 23. Проверка на близкие по смыслу однородные члены
1334
+ async def check_synonymous_members(message):
1335
  print()
1336
  print("Проверка 23: Проверка на близкие по смыслу однородные члены")
1337
  print()
 
1345
  если таких слов или выражений нет, **верни только** JSON {{"decision": false, "explanation": "<пояснение>"}}.
1346
  **Не добавляй никакого дополнительного текста. Перед ответом убедись, что отвечаешь только в формате JSON с закрывающими кавычками и скобками.**'''
1347
 
1348
+ response = await generate_message_mistral_check(prompt)
1349
  time.sleep(3)
1350
  print("GigaChat Pro response:", response)
1351
  result = parse_json_response(response)
 
1359
 
1360
 
1361
  # 24. Проверка на шокирующие, экстравагантные или кликбейтные фразы
1362
+ async def check_clickbait_phrases(message, description, benefits, key_message):
1363
  message_clean = cut_message(message)
1364
  print()
1365
  print()
 
1384
 
1385
  **Не добавляй никакого дополнительного текста. Перед ответом убедись, что отвечаешь только в формате JSON с закрывающими кавычками и скобками.**'''
1386
 
1387
+ response = await generate_message_mistral_check(prompt)
1388
  time.sleep(3)
1389
  print("GigaChat Pro response:", response)
1390
  result = parse_json_response(response)
 
1398
 
1399
 
1400
  # 25. Проверка на абстрактные заявления без поддержки фактами
1401
+ async def check_abstract_claims(message, description, benefits, key_message):
1402
  print()
1403
  print("Проверка 25: Проверка на абстрактные заявления без поддержки фактами")
1404
  print()
 
1437
 
1438
  **Не добавляй никакого дополнительного текста. Перед ответом убедись, что отвечаешь только в формате JSON с закрывающими кавычками и скобками.**'''
1439
 
1440
+ response = await generate_message_mistral_check(prompt)
1441
  time.sleep(3)
1442
  print("GigaChat Pro response:", response)
1443
  result = parse_json_response(response)
 
1516
  return None
1517
 
1518
  # 28. Проверка на речевые клише, рекламные штампы и канцеляризмы
1519
+ async def check_cliches_and_bureaucratese(message, description, benefits, key_message):
1520
  print()
1521
  print("Проверка 28: Проверка на речевые клише, рекламные штампы и канцеляризмы")
1522
  print()
 
1549
  если в тексте **есть** такие выражения, **верни только** JSON {{"decision": true, "explanation": "<пояснение>"}}.
1550
  **Не добавляй никакого дополнительного текста. Перед ответом убедись, что отвечаешь только в формате JSON с закрывающими кавычками и скобками.**'''
1551
 
1552
+ response = await generate_message_mistral_check(prompt)
1553
  time.sleep(3)
1554
  print("GigaChat Pro response:", response)
1555
  result = parse_json_response(response)
 
1562
  return None
1563
 
1564
  # 29. Проверка на соответствие описанию предложения и ключевому сообщению
1565
+ async def check_no_contradictions(message, description, benefits, key_message):
1566
  print()
1567
  print("Проверка 29: Проверка на отсутствие противоречий с описанием предложения")
1568
  print()
 
1580
  Если сообщение содержит факты, которые отсутствуют в описании предложения и ключевом сообщении, **верни только** JSON {{"decision": true, "explanation": "<описание противоречий>"}}.
1581
  **Не добавляй никакого дополнительного текста. Отвечай только в формате JSON с закрывающими кавычками и скобками.**'''
1582
 
1583
+ response = await generate_message_mistral_check(prompt)
1584
  time.sleep(3)
1585
  print("GigaChat Pro response:", response)
1586
  result = parse_json_response(response)
 
1593
  return None
1594
 
1595
  # 30. Проверка на наличие ключевого сообщения
1596
+ async def check_contains_key_message(message, key_message):
1597
  print()
1598
  print("Проверка 30: Проверка на наличие ключевого сообщения")
1599
  print()
 
1607
  Если сообщение **не содержит всю** информацию из ключевого текста, **верни только** JSON {{"decision": true, "explanation": "Ключевое текст отсутствует."}}.
1608
  **Не добавляй никакого дополнительного текста. Отвечай только в формате JSON с закрывающими кавычками и скобками.**'''
1609
 
1610
+ response = await generate_message_mistral_check(prompt)
1611
  time.sleep(3)
1612
  print("GigaChat Pro response:", response)
1613
  result = parse_json_response(response)
 
1620
  return None
1621
 
1622
  # 31. Проверка на точное совпадение названий продуктов
1623
+ async def check_product_name_consistency(message, product_name):
1624
  print()
1625
  print("Проверка 31: Проверка на точное совпадение названий продуктов")
1626
  print()
 
1637
  Если название продукта **не** совпадает, **верни только** JSON {{"decision": true, "explanation": "<описание несоответствия>"}}.
1638
  **Не добавляй никакого дополнительного текста. Ответ должен быть только в формате JSON с закрывающими кавычками и скобками.**'''
1639
 
1640
+ response = await generate_message_mistral_check(prompt)
1641
  time.sleep(3)
1642
  print("GigaChat Pro response:", response)
1643
  result = parse_json_response(response)
 
1652
  # ФУНКЦИИ ПРОВЕРОК (КОНЕЦ)
1653
 
1654
 
1655
+ async def safe_check(func, *args):
1656
  try:
1657
+ if inspect.iscoroutinefunction(func):
1658
+ return await func(*args)
1659
+ else:
1660
+ return func(*args)
1661
  except Exception as e:
1662
+ print(f"Error in {func.__name__}: {e}")
1663
+ return None
 
1664
 
1665
+ async def perform_checks(message, description, key_message, product_name, benefits):
1666
  checks = {}
1667
 
1668
  # 2. Morphological checks using pymorphy3
 
1708
 
1709
  # Perform morphological checks
1710
  for check_name, check_func in morphological_checks:
1711
+ result = await safe_check(check_func, message)
1712
  checks[check_name] = result
1713
  if result is False:
1714
  return checks # Stop on first failure
 
1716
  # Perform LLM checks group 1
1717
  for check_name, check_func in llm_checks_group1:
1718
  if check_name == "no_contradictions":
1719
+ result = await safe_check(check_func, message, description, benefits, key_message)
1720
  elif check_name == "contains_key_message":
1721
+ result = await safe_check(check_func, message, key_message)
1722
  elif check_name == "product_name_consistency":
1723
+ result = await safe_check(check_func, message, product_name)
1724
  elif check_name == "clickbait_phrases":
1725
+ result = await safe_check(check_func, message, description, benefits, key_message)
1726
  elif check_name == "abstract_claims":
1727
+ result = await safe_check(check_func, message, description, benefits, key_message)
1728
  elif check_name == "cliches_and_bureaucratese":
1729
+ result = await safe_check(check_func, message, description, benefits, key_message)
1730
  else:
1731
+ result = await safe_check(check_func, message)
1732
  checks[check_name] = result
1733
  if result is False:
1734
  return checks