Создано: - bot/handlers/settings.py - обработчик команды /settings Реализовано: ✅ /settings - настройки пользователя - Выбор уровня английского (A1-C2) - Выбор языка интерфейса (RU/EN) - Интерактивные inline-кнопки ✅ Новый тип заданий - заполнение пропусков - AI генерирует предложение с пропуском - Показывает перевод для контекста - Проверка ответа через AI ✅ Смешанные задания - Случайное чередование типов (переводы + fill-in) - Более разнообразная практика Изменено: - services/ai_service.py - метод generate_fill_in_sentence() - services/task_service.py - метод generate_mixed_tasks() - services/user_service.py - методы обновления настроек - bot/handlers/tasks.py - использование смешанных заданий - main.py - регистрация роутера настроек Теперь бот предлагает: - Перевод EN→RU - Перевод RU→EN - Заполнение пропусков в предложениях 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
177 lines
7.1 KiB
Python
177 lines
7.1 KiB
Python
from openai import AsyncOpenAI
|
||
from config.settings import settings
|
||
from typing import Dict, List
|
||
|
||
|
||
class AIService:
|
||
"""Сервис для работы с OpenAI API через Cloudflare Gateway"""
|
||
|
||
def __init__(self):
|
||
# Проверяем, настроен ли Cloudflare AI Gateway
|
||
if settings.cloudflare_account_id:
|
||
# Используем Cloudflare AI Gateway
|
||
base_url = (
|
||
f"https://gateway.ai.cloudflare.com/v1/"
|
||
f"{settings.cloudflare_account_id}/"
|
||
f"{settings.cloudflare_gateway_id}/"
|
||
f"compat"
|
||
)
|
||
self.client = AsyncOpenAI(
|
||
api_key=settings.openai_api_key,
|
||
base_url=base_url
|
||
)
|
||
else:
|
||
# Прямое подключение к OpenAI
|
||
self.client = AsyncOpenAI(api_key=settings.openai_api_key)
|
||
|
||
async def translate_word(self, word: str, target_lang: str = "ru") -> Dict:
|
||
"""
|
||
Перевести слово и получить дополнительную информацию
|
||
|
||
Args:
|
||
word: Слово для перевода
|
||
target_lang: Язык перевода (по умолчанию русский)
|
||
|
||
Returns:
|
||
Dict с переводом, транскрипцией и примерами
|
||
"""
|
||
prompt = f"""Переведи английское слово/фразу "{word}" на русский язык.
|
||
|
||
Верни ответ строго в формате JSON:
|
||
{{
|
||
"word": "{word}",
|
||
"translation": "перевод",
|
||
"transcription": "транскрипция в IPA",
|
||
"examples": [
|
||
{{"en": "пример на английском", "ru": "перевод примера"}},
|
||
{{"en": "ещё один пример", "ru": "перевод примера"}}
|
||
],
|
||
"category": "категория слова (работа, еда, путешествия и т.д.)",
|
||
"difficulty": "уровень сложности (A1/A2/B1/B2/C1/C2)"
|
||
}}
|
||
|
||
Важно: верни только JSON, без дополнительного текста."""
|
||
|
||
try:
|
||
response = await self.client.chat.completions.create(
|
||
model="gpt-4o-mini",
|
||
messages=[
|
||
{"role": "system", "content": "Ты - помощник для изучения английского языка. Отвечай только в формате JSON."},
|
||
{"role": "user", "content": prompt}
|
||
],
|
||
temperature=0.3,
|
||
response_format={"type": "json_object"}
|
||
)
|
||
|
||
import json
|
||
result = json.loads(response.choices[0].message.content)
|
||
return result
|
||
|
||
except Exception as e:
|
||
# Fallback в случае ошибки
|
||
return {
|
||
"word": word,
|
||
"translation": "Ошибка перевода",
|
||
"transcription": "",
|
||
"examples": [],
|
||
"category": "unknown",
|
||
"difficulty": "A1"
|
||
}
|
||
|
||
async def check_answer(self, question: str, correct_answer: str, user_answer: str) -> Dict:
|
||
"""
|
||
Проверить ответ пользователя с помощью ИИ
|
||
|
||
Args:
|
||
question: Вопрос задания
|
||
correct_answer: Правильный ответ
|
||
user_answer: Ответ пользователя
|
||
|
||
Returns:
|
||
Dict с результатом проверки и обратной связью
|
||
"""
|
||
prompt = f"""Проверь ответ пользователя на задание по английскому языку.
|
||
|
||
Задание: {question}
|
||
Правильный ответ: {correct_answer}
|
||
Ответ пользователя: {user_answer}
|
||
|
||
Верни ответ в формате JSON:
|
||
{{
|
||
"is_correct": true/false,
|
||
"feedback": "краткое объяснение (если ответ неверный, объясни ошибку и дай правильный вариант)",
|
||
"score": 0-100
|
||
}}
|
||
|
||
Учитывай возможные вариации ответа. Если смысл передан правильно, даже с небольшими грамматическими неточностями, засчитывай ответ."""
|
||
|
||
try:
|
||
response = await self.client.chat.completions.create(
|
||
model="gpt-4o-mini",
|
||
messages=[
|
||
{"role": "system", "content": "Ты - преподаватель английского языка. Проверяй ответы справедливо, учитывая контекст."},
|
||
{"role": "user", "content": prompt}
|
||
],
|
||
temperature=0.3,
|
||
response_format={"type": "json_object"}
|
||
)
|
||
|
||
import json
|
||
result = json.loads(response.choices[0].message.content)
|
||
return result
|
||
|
||
except Exception as e:
|
||
return {
|
||
"is_correct": False,
|
||
"feedback": "Ошибка проверки ответа",
|
||
"score": 0
|
||
}
|
||
|
||
async def generate_fill_in_sentence(self, word: str) -> Dict:
|
||
"""
|
||
Сгенерировать предложение с пропуском для заданного слова
|
||
|
||
Args:
|
||
word: Слово, для которого нужно создать предложение
|
||
|
||
Returns:
|
||
Dict с предложением и правильным ответом
|
||
"""
|
||
prompt = f"""Создай предложение на английском языке, используя слово "{word}".
|
||
Замени это слово на пропуск "___".
|
||
|
||
Верни ответ в формате JSON:
|
||
{{
|
||
"sentence": "предложение с пропуском ___",
|
||
"answer": "{word}",
|
||
"translation": "перевод предложения на русский"
|
||
}}
|
||
|
||
Предложение должно быть простым и естественным. Контекст должен четко подсказывать правильное слово."""
|
||
|
||
try:
|
||
response = await self.client.chat.completions.create(
|
||
model="gpt-4o-mini",
|
||
messages=[
|
||
{"role": "system", "content": "Ты - преподаватель английского языка. Создавай простые и понятные упражнения."},
|
||
{"role": "user", "content": prompt}
|
||
],
|
||
temperature=0.7,
|
||
response_format={"type": "json_object"}
|
||
)
|
||
|
||
import json
|
||
result = json.loads(response.choices[0].message.content)
|
||
return result
|
||
|
||
except Exception as e:
|
||
return {
|
||
"sentence": f"I like to ___ every day.",
|
||
"answer": word,
|
||
"translation": f"Мне нравится {word} каждый день."
|
||
}
|
||
|
||
|
||
# Глобальный экземпляр сервиса
|
||
ai_service = AIService()
|