Тест-режим: проверка через /api/photo-bot/check/ сайта (CV+гримасы+ИИ), метрики из llama.cpp, удаление прямого llama.cpp-клиента

This commit is contained in:
dddennnisss
2026-08-22 20:47:57 +07:00
parent ab58203982
commit f18c564ead
9 changed files with 117 additions and 205 deletions
Binary file not shown.
+64 -37
View File
@@ -283,7 +283,7 @@ def _photo_test_preview(emojis: dict) -> str:
return (
f"🧪 <b>Тестовый режим</b>\n\n"
f"Кадр получен. Фото никуда не публикуется.\n\n"
f"{emojis['1']} — отправлю фото напрямую в ИИ\n"
f"{emojis['1']} — отправлю фото на проверку по сайту\n"
f"{emojis['2']} — Загрузить другое фото\n"
f"{emojis['9']} — Назад\n"
f"{emojis['0']}В главное меню"
@@ -291,59 +291,85 @@ def _photo_test_preview(emojis: dict) -> str:
def _photo_test_ai_checking(emojis: dict) -> str:
return (
"🧪 <i>Отправляю фото напрямую в ИИ (тестовый режим)...\n"
"🧪 <i>Отправляю фото на проверку по сайту (тестовый режим)...\n"
"Фото проходят полный контроль: CV, гримасы, ИИ.\n"
"Обычно это занимает 1-3 минуты. Пожалуйста, подождите...</i>"
)
def _photo_test_receiving(emojis: dict) -> str:
return "🧪 <i>Ищу лицо на фото (тестовый режим), пожалуйста, подождите...</i>"
def _photo_test_result(verdict: str, reason: str, mimi: str = '', grafika: str = '',
ai_metrics: dict = None, emojis: dict = None) -> str:
def _photo_test_result(verdict: str, reason: str, cv_approved=None, cv_reason: str = '',
forced=None, timings: dict = None, ai_metrics: dict = None,
emojis: dict = None) -> str:
emojis = emojis or {}
icons = {"Прошел": "", "Не прошел": "", "На модерацию": ""}
icon = icons.get(verdict, "")
lines = []
if mimi:
lines.append(f"🙂 <b>Мимика:</b> {mimi}")
if grafika:
lines.append(f"🖼 <b>Графика:</b> {grafika}")
if lines:
detail = "\n".join(lines) + "\n\n"
parts = [
"🧪 <b>Тестовый режим: результат проверки</b>\n",
f"{icon} <b>Вердикт:</b> {verdict}\n",
]
if reason:
parts.append(f"📝 <b>Причина (ИИ):</b> {reason}\n")
# Детерминированный слой (MediaPipe CV + ARKit-формы)
if cv_approved is True:
line = "🎯 <b>CV-проверка:</b> ✅ пройдена"
if cv_reason:
line += f" — <i>{cv_reason}</i>"
parts.append(line + "\n")
elif cv_approved is False:
parts.append("🎯 <b>CV-проверка:</b> ❌ отклонена\n")
if cv_reason:
parts.append(f"↳ <i>{cv_reason}</i>\n")
else:
detail = ""
metrics_block = ''
parts.append("🎯 <b>CV-проверка:</b> —\n")
if forced:
parts.append("️ <i>На сайте включён режим принудительной модерации: в реальном режиме фото ушло бы модератору, а не было опубликовано сразу.</i>\n")
# Тайминги этапов
if timings:
names = [
('cv', "CV (геометрия)"),
('expression', "Гримасы (ARKit-формы)"),
('ai', "ИИ (llama.cpp)"),
('total', "Всего"),
]
tl = ["📊 <b>Технические показатели (по этапам)</b>"]
for k, name in names:
v = timings.get(k)
if v is not None:
tl.append(f"{name}: <b>{float(v):.2f} сек</b>")
if len(tl) > 1:
parts.append("\n".join(tl) + "\n")
# Токены и скорость (сайт передаёт их из ответа llama.cpp)
if ai_metrics:
ml = ["📊 <b>Технические показатели</b>"]
tt = ai_metrics.get('total_time')
if tt is not None:
ml.append(f"⏱ Время ответа: <b>{tt:.2f} сек</b>")
ml = ["🔢 <b>ИИ: токены и скорость</b>"]
pt = ai_metrics.get('prompt_tokens')
gps = ai_metrics.get('prompt_per_second')
if pt is not None:
s = f"⬇️ Приём (промпт): <b>{pt} токенов</b>"
if gps is not None:
s += f"{gps:.1f} ток/сек"
s += f"{float(gps):.1f} ток/сек"
ml.append(s)
ct = ai_metrics.get('completion_tokens')
ggs = ai_metrics.get('predicted_per_second')
if ct is not None:
s = f"⬆️ Отдача (генерация): <b>{ct} токенов</b>"
if ggs is not None:
s += f"{ggs:.1f} ток/сек"
s += f"{float(ggs):.1f} ток/сек"
ml.append(s)
if len(ml) > 1:
metrics_block = "\n".join(ml) + "\n\n"
return (
f"🧪 <b>Тестовый режим: вердикт ИИ</b>\n\n"
f"{icon} <b>Вердикт:</b> {verdict}\n"
f"{detail}"
f"📝 <b>Причина:</b> {reason}\n\n"
f"{metrics_block}"
f"⚠️ <i>Тестовый режим: фото не публиковалось и никуда не отправлялось.</i>\n\n"
f"{emojis.get('2', '2')} — Загрузить другое фото\n"
f"{emojis.get('0', '0')}В главное меню"
)
parts.append("\n".join(ml) + "\n")
parts.append("⚠️ <i>Тестовый режим: фото не публиковалось и никуда не отправлялось.</i>\n\n")
parts.append(f"{emojis.get('2', '2')} — Загрузить другое фото\n")
parts.append(f"{emojis.get('9', '9')} — Назад\n")
parts.append(f"{emojis.get('0', '0')}В главное меню")
return "\n".join(parts)
def _photo_test_ai_error(emojis: dict, error: str = '', elapsed: float = None) -> str:
detail = ''
@@ -355,9 +381,9 @@ def _photo_test_ai_error(emojis: dict, error: str = '', elapsed: float = None) -
if elapsed is not None:
detail += f"⏱ Время до ошибки: <b>{elapsed:.1f} сек</b>\n"
return (
f"❌ <b>Ошибка обращения к ИИ.</b>\n\n"
f"❌ <b>Ошибка проверки фото.</b>\n\n"
f"{detail}\n"
f"Проверьте доступность ИИ-сервиса. Повторите попытку позже.\n\n"
f"Сервис проверки временно недоступен. Повторите попытку позже.\n\n"
f"{emojis['1']} — Повторить проверку\n"
f"{emojis['2']} — Загрузить другое фото\n"
f"{emojis['0']}В главное меню"
@@ -448,12 +474,13 @@ PHOTO_TEST_PREVIEW_TEXT = _photo_test_preview(EMOJI_DIGITS)
PHOTO_TEST_AI_CHECKING_TEXT = _photo_test_ai_checking(EMOJI_DIGITS)
PHOTO_TEST_RECEIVING_TEXT = _photo_test_receiving(EMOJI_DIGITS)
def photo_test_result(verdict: str, reason: str, mimi: str = '', grafika: str = '',
ai_metrics: dict = None) -> str:
return _photo_test_result(verdict, reason, mimi, grafika, ai_metrics, EMOJI_DIGITS)
def photo_test_result(verdict: str, ai_reason: str = '', cv_approved=None, cv_reason: str = '',
forced=None, timings: dict = None, ai_metrics: dict = None) -> str:
return _photo_test_result(verdict, ai_reason, cv_approved, cv_reason,
forced, timings, ai_metrics, EMOJI_DIGITS)
def photo_test_ai_error(error: str = '', elapsed: float = None) -> str:
return _photo_test_ai_error(EMOJI_DIGITS, error, elapsed)
def photo_test_ai_error(error: str = '') -> str:
return _photo_test_ai_error(EMOJI_DIGITS, error)
# =========================================================