Files
tg_bot_language/bot/handlers/admin.py
mamonov.ep eb666ec9bc feat: мульти-провайдер AI, выбор типов заданий, настройка количества
- Добавлена поддержка нескольких AI провайдеров (OpenAI, Google Gemini)
- Добавлена админ-панель (/admin) для переключения AI моделей
- Добавлен AIModelService для управления моделями в БД
- Добавлен выбор типа заданий (микс, перевод слов, подстановка, перевод предложений)
- Добавлена настройка количества заданий (5-15)
- ai_service динамически выбирает провайдера на основе активной модели
- Обработка ограничений моделей (temperature, response_format)
- Очистка markdown обёртки из ответов Gemini

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 15:16:24 +03:00

103 lines
3.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from aiogram import Router, F
from aiogram.filters import Command
from aiogram.types import Message, CallbackQuery, InlineKeyboardMarkup, InlineKeyboardButton
from config.settings import settings
from database.db import async_session_maker
from database.models import AIProvider
from services.ai_model_service import AIModelService
router = Router()
def get_admin_ids() -> set:
"""Получить множество ID админов"""
if not settings.admin_ids:
return set()
return set(int(x.strip()) for x in settings.admin_ids.split(",") if x.strip())
def is_admin(user_id: int) -> bool:
"""Проверить, является ли пользователь админом"""
return user_id in get_admin_ids()
async def get_model_keyboard() -> InlineKeyboardMarkup:
"""Создать клавиатуру выбора AI модели"""
async with async_session_maker() as session:
models = await AIModelService.get_all_models(session)
keyboard = []
for model in models:
marker = "" if model.is_active else ""
provider_emoji = "🟢" if model.provider == AIProvider.openai else "🔵"
keyboard.append([InlineKeyboardButton(
text=f"{marker}{provider_emoji} {model.display_name}",
callback_data=f"admin_model_{model.id}"
)])
keyboard.append([InlineKeyboardButton(text="❌ Закрыть", callback_data="admin_close")])
return InlineKeyboardMarkup(inline_keyboard=keyboard)
@router.message(Command("admin"))
async def cmd_admin(message: Message):
"""Админская панель"""
if not is_admin(message.from_user.id):
return
# Убеждаемся что дефолтные модели созданы
async with async_session_maker() as session:
await AIModelService.ensure_default_models(session)
active_model = await AIModelService.get_active_model(session)
active_name = active_model.display_name if active_model else "Не выбрана"
text = (
"🔧 <b>Админ-панель</b>\n\n"
f"🤖 Текущая AI модель: <b>{active_name}</b>\n\n"
"Выберите модель для генерации:"
)
keyboard = await get_model_keyboard()
await message.answer(text, reply_markup=keyboard)
@router.callback_query(F.data.startswith("admin_model_"))
async def set_admin_model(callback: CallbackQuery):
"""Установить AI модель"""
if not is_admin(callback.from_user.id):
await callback.answer("⛔ Доступ запрещен", show_alert=True)
return
model_id = int(callback.data.split("_")[-1])
async with async_session_maker() as session:
success = await AIModelService.set_active_model(session, model_id)
if success:
active_model = await AIModelService.get_active_model(session)
await callback.answer(f"✅ Модель изменена: {active_model.display_name}")
text = (
"🔧 <b>Админ-панель</b>\n\n"
f"🤖 Текущая AI модель: <b>{active_model.display_name}</b>\n\n"
"Выберите модель для генерации:"
)
else:
await callback.answer("❌ Ошибка при смене модели", show_alert=True)
text = "🔧 <b>Админ-панель</b>\n\n❌ Ошибка при смене модели"
keyboard = await get_model_keyboard()
await callback.message.edit_text(text, reply_markup=keyboard)
@router.callback_query(F.data == "admin_close")
async def admin_close(callback: CallbackQuery):
"""Закрыть админ-панель"""
if not is_admin(callback.from_user.id):
return
await callback.message.delete()
await callback.answer()