Тест-мод: под-режим «1 — тест проверка фото» внутри штатного фото-режима

This commit is contained in:
Hermes Bot
2026-08-20 13:06:35 +07:00
parent 633eb27450
commit 1ea42a9197
4 changed files with 43 additions and 13 deletions
+7 -4
View File
@@ -89,13 +89,16 @@ ENABLE_INSTRUCT = True # Модуль инструкций (Trueconf,
ENABLE_LK = True # Личный кабинет сотрудника (отпуска, расчетные листки, справки) ENABLE_LK = True # Личный кабинет сотрудника (отпуска, расчетные листки, справки)
# ========================================================= # =========================================================
# 1.1 ТЕСТОВЫЙ МОД ФОТО-БОТА # 1.1 ТЕСТОВЫЙ ПОД-РЕЖИМ ФОТО-БОТА («1 — тест проверка фото»)
# Фото уходит НАПРЯМУЮ в ИИ (llama.cpp, тот же endpoint и промпт, # При включённом флаге в меню «Режим обновления фото профиля»
# появляется пункт «1 — тест проверка фото». Внутри под-режима
# фото уходит НАПРЯМУЮ в ИИ (llama.cpp, тот же endpoint и промпт,
# что в SibCemProfile/PhotoApp/photo_validator.py), результат # что в SibCemProfile/PhotoApp/photo_validator.py), результат
# показывается пользователю. Само фото никуда НЕ ДОСЫЛАЕТСЯ # показывается пользователю. Само фото никуда НЕ ДОСЫЛАЕТСЯ
# не применяется (ни в AD, ни в API, ни на модерацию). # (ни в AD, ни в API, ни на модерацию). Штатный поток
# (фото → превью → публикация) работает параллельно.
# ========================================================= # =========================================================
PHOTO_TEST_MODE = False # True — тест-мод: фото напрямую в ИИ, результат показывается, фото никуда не публикуется PHOTO_TEST_MODE = False # True — в меню фото-режима доступен пункт «тест проверка фото»
PHOTO_TEST_AI_URL = "http://srvkem-ii-03:8083/v1/chat/completions" PHOTO_TEST_AI_URL = "http://srvkem-ii-03:8083/v1/chat/completions"
PHOTO_TEST_AI_MODEL = "/opt/llama.cpp-cpu/build/bin/models/gemma-4-E4B-mtp/gemma-4-E4B-it-UD-Q4_K_XL.gguf" PHOTO_TEST_AI_MODEL = "/opt/llama.cpp-cpu/build/bin/models/gemma-4-E4B-mtp/gemma-4-E4B-it-UD-Q4_K_XL.gguf"
PHOTO_TEST_AI_TIMEOUT = 180.0 # Таймаут обращения к ИИ, сек PHOTO_TEST_AI_TIMEOUT = 180.0 # Таймаут обращения к ИИ, сек
+2 -2
View File
@@ -137,9 +137,9 @@ async def main_menu(msg: Message):
return return
set_state(user_id, "PHOTO_MODE") set_state(user_id, "PHOTO_MODE")
log_menu_stats(user_id, "Photo Bot (TEST)" if PHOTO_TEST_MODE else "Photo Bot", "Вход") log_menu_stats(user_id, "Photo Bot (TEST)" if PHOTO_TEST_MODE else "Photo Bot", "Вход")
from utils.texts import PHOTO_TEST_WELCOME_TEXT from utils.texts import PHOTO_TEST_ENTRY_TEXT
await msg.answer( await msg.answer(
PHOTO_TEST_WELCOME_TEXT if PHOTO_TEST_MODE else PHOTO_MAIN_MENU_TEXT, PHOTO_TEST_ENTRY_TEXT if PHOTO_TEST_MODE else PHOTO_MAIN_MENU_TEXT,
parse_mode="html" parse_mode="html"
) )
return return
+28 -4
View File
@@ -32,7 +32,6 @@ from utils.texts import (
photo_moderation_pending, photo_moderation_pending,
PHOTO_TEST_WELCOME_TEXT, PHOTO_TEST_WELCOME_TEXT,
PHOTO_TEST_PREVIEW_TEXT, PHOTO_TEST_PREVIEW_TEXT,
PHOTO_TEST_RECEIVING_TEXT,
PHOTO_TEST_AI_CHECKING_TEXT, PHOTO_TEST_AI_CHECKING_TEXT,
photo_test_result, photo_test_result,
photo_test_ai_error, photo_test_ai_error,
@@ -48,6 +47,16 @@ router = Router()
# Формат: {user_id: {'path': '/tmp/orig_user.jpg', 'coords': (x1,y1,x2,y2)}} # Формат: {user_id: {'path': '/tmp/orig_user.jpg', 'coords': (x1,y1,x2,y2)}}
pending_photos = {} pending_photos = {}
# Пользователи, находящиеся в под-режиме «тест проверка фото»
test_submode_users = set()
def in_test_submode(user_id: str) -> bool:
"""Проверяет, находится ли пользователь в под-режиме тест-проверки фото"""
if user_id not in test_submode_users:
return False
# Если сессия истекла (состояние сброшено) — под-режим тоже недействителен
return states.get_state(user_id) == "PHOTO_MODE"
# ========================================================= # =========================================================
# СИСТЕМА ОБРАБОТКИ ОШИБОК И ЛОГИРОВАНИЯ # СИСТЕМА ОБРАБОТКИ ОШИБОК И ЛОГИРОВАНИЯ
# ========================================================= # =========================================================
@@ -170,6 +179,7 @@ async def photo_module_handler(msg: Message):
if cmd in ["0", "9", "/start", "меню"]: if cmd in ["0", "9", "/start", "меню"]:
log_menu_stats(user_id, "Photo Bot", "Выход в главное меню") log_menu_stats(user_id, "Photo Bot", "Выход в главное меню")
states.clear_state(user_id) states.clear_state(user_id)
test_submode_users.discard(user_id)
if user_id in pending_photos: if user_id in pending_photos:
photo_data = pending_photos[user_id] photo_data = pending_photos[user_id]
if os.path.exists(photo_data['path']): if os.path.exists(photo_data['path']):
@@ -196,8 +206,22 @@ async def photo_module_handler(msg: Message):
# Ошибка проверки — не блокируем, просто логируем # Ошибка проверки — не блокируем, просто логируем
logger.warning(f"Не удалось проверить статус модерации для {user_id}: {status.get('reason')}") logger.warning(f"Не удалось проверить статус модерации для {user_id}: {status.get('reason')}")
# --- ТЕСТОВЫЙ МОД: кнопка 1 отправляет фото НАПРЯМУЮ в ИИ, фото никуда не публикуется --- # --- ТЕСТ-ПОД-РЕЖИМ: нет висящего фото — на любой текст повторяем тест-приветствие ---
if not is_attachment and user_id in pending_photos and config.PHOTO_TEST_MODE: if not is_attachment and user_id not in pending_photos and in_test_submode(user_id):
await msg.answer(PHOTO_TEST_WELCOME_TEXT, parse_mode="html")
return
# --- ВХОД В ТЕСТ-ПОД-РЕЖИМ: кнопка 1 в меню фото-режима (тест включен) ---
if (not is_attachment and user_id not in pending_photos
and not in_test_submode(user_id)
and config.PHOTO_TEST_MODE and cmd == "1"):
test_submode_users.add(user_id)
log_menu_stats(user_id, "Photo Bot (TEST)", "Вход в тест-под-режим")
await msg.answer(PHOTO_TEST_WELCOME_TEXT, parse_mode="html")
return
# --- ТЕСТ-ПОД-РЕЖИМ: кнопка 1 отправляет фото НАПРЯМУЮ в ИИ, фото никуда не публикуется ---
if not is_attachment and user_id in pending_photos and in_test_submode(user_id):
if cmd == "1": if cmd == "1":
photo_data = pending_photos[user_id] photo_data = pending_photos[user_id]
original_path = photo_data['path'] original_path = photo_data['path']
@@ -393,7 +417,7 @@ async def photo_module_handler(msg: Message):
log_menu_stats(user_id, "Photo Bot", "Загрузка и обработка нового фото") log_menu_stats(user_id, "Photo Bot", "Загрузка и обработка нового фото")
await asyncio.sleep(0.5) await asyncio.sleep(0.5)
if config.PHOTO_TEST_MODE: if in_test_submode(user_id):
await msg.answer( await msg.answer(
PHOTO_TEST_PREVIEW_TEXT, PHOTO_TEST_PREVIEW_TEXT,
parse_mode="html" parse_mode="html"
+6 -3
View File
@@ -202,14 +202,16 @@ def sd_file_upload_error() -> str:
# --- Private functions (Internal logic) --- # --- Private functions (Internal logic) ---
def _photo_welcome(emojis: dict) -> str: def _photo_welcome(emojis: dict, show_test: bool = False) -> str:
return ( text = (
f"🖼 <b>Режим обновления фото профиля</b>\n\n" f"🖼 <b>Режим обновления фото профиля</b>\n\n"
f"📸 Пришлите мне вашу фотографию.\n\n" f"📸 Пришлите мне вашу фотографию.\n\n"
f"Бот автоматически найдёт лицо, покажет превью\n" f"Бот автоматически найдёт лицо, покажет превью\n"
f"и отправит фото на публикацию в ваши корпоративные сервисы.\n\n" f"и отправит фото на публикацию в ваши корпоративные сервисы.\n\n"
f"{emojis['0']}В главное меню"
) )
if show_test:
text += f"{emojis['1']} — тест проверка фото\n"
return text + f"{emojis['0']}В главное меню"
def _photo_unknown(emojis: dict) -> str: def _photo_unknown(emojis: dict) -> str:
return ( return (
@@ -338,6 +340,7 @@ def _photo_cancel(emojis: dict) -> str:
# --- Public constants and functions --- # --- Public constants and functions ---
PHOTO_MAIN_MENU_TEXT = _photo_welcome(EMOJI_DIGITS) PHOTO_MAIN_MENU_TEXT = _photo_welcome(EMOJI_DIGITS)
PHOTO_TEST_ENTRY_TEXT = _photo_welcome(EMOJI_DIGITS, show_test=True)
PHOTO_UNKNOWN_CMD_TEXT = _photo_unknown(EMOJI_DIGITS) PHOTO_UNKNOWN_CMD_TEXT = _photo_unknown(EMOJI_DIGITS)
def photo_error_handling() -> str: def photo_error_handling() -> str: