привет! вот код телеграм бота.
import logging
import requests
import json
import os
import re
import html
from datetime import datetime
from telegram import Update, InlineKeyboardMarkup, InlineKeyboardButton, ReplyKeyboardMarkup, KeyboardButton
from telegram.constants import ParseMode
from telegram.ext import (
    ApplicationBuilder,
    CommandHandler,
    MessageHandler,
    ContextTypes,
    filters,
    CallbackQueryHandler,
    Defaults,
)
from telegram.error import TelegramError

# Функция для загрузки конфигурации
def load_config():
    script_dir = os.path.dirname(os.path.abspath(__file__))
    config_path = os.path.join(script_dir, 'config.json')
    
    if not os.path.exists(config_path):
        raise FileNotFoundError(f"Конфигурационный файл не найден по пути: {config_path}")
    
    with open(config_path, 'r', encoding='utf-8') as f:
        return json.load(f)

# Загрузка конфигурации
try:
    config = load_config()
except FileNotFoundError as e:
    print(e)
    exit(1)

# Настройка логирования
logging.basicConfig(
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    level=logging.INFO
)
logger = logging.getLogger(__name__)

# Ваши API-эндпоинты
API_URL_TEXT = 'https://cablyai.com/v1/chat/completions'
API_URL_IMAGE = 'https://cablyai.com/v1/images/generations'  # Используем ваш актуальный URL для генерации изображений
API_HEADERS = {
    'Authorization': f"Bearer {config['api_key']}",
    'Content-Type': 'application/json'
}

# Инструкция для текстовых моделей
SYSTEM_INSTRUCTION_TEXT = config.get('system_instruction', "ты ведёшь себя как котик")

# Хранение контекста для каждой сессии и модели
context_store = {}
model_store = {}
MAX_MESSAGE_LENGTH = 4096
AUTHORIZED_USER_IDS = config.get('authorized_user_ids', [])

# Хранение режима пользователя ('message' или 'file')
user_mode_store = {}

# Создание маппинга model_id -> model_info для быстрого доступа
model_id_to_info = {}
model_id_to_name = {}
for model_name, model_info in config.get('models', {}).items():
    model_id = model_info.get('id')
    if model_id:
        model_id_to_info[model_id] = model_info
        model_id_to_name[model_id] = model_name
    else:
        logger.warning(f"Модель '{model_name}' не имеет 'id'.")

# Функция для разбивки длинного сообщения на части
def split_message(message, max_length):
    return [message[i:i + max_length] for i in range(0, len(message), max_length)]

# Функция для создания кнопок выбора модели
def get_model_buttons():
    buttons = []
    for name, model_info in config.get('models', {}).items():
        buttons.append([InlineKeyboardButton(html.escape(name), callback_data=model_info['id'])])
    return InlineKeyboardMarkup(buttons)

# Функция для создания основных кнопок: 'Сменить модель' и 'Продолжить'
def get_main_buttons():
    keyboard = [
        [
            InlineKeyboardButton("Сменить модель", callback_data='change_model'),
            InlineKeyboardButton("Продолжить", callback_data='continue_response')
        ]
    ]
    return InlineKeyboardMarkup(keyboard)

# Функция для создания кнопок главного меню
def get_menu_buttons():
    buttons = [
        [InlineKeyboardButton("Инструкция по использованию", callback_data='show_instructions')],
        [InlineKeyboardButton("Сменить модель", callback_data='change_model'),
         InlineKeyboardButton("Продолжить", callback_data='continue_response')]
    ]
    return InlineKeyboardMarkup(buttons)

# Функция для определения, является ли текст русским
def is_russian(text):
    return bool(re.search('[а-яА-Я]', text))

# Функция для перевода текста с помощью модели GPT-4
def translate_to_english(original_text):
    translation_prompt = f"Переведи следующий текст на английский язык и верни только переведенный текст:\n\n{original_text}"
    
    translation_data = {
        "model": "chatgpt-4o-latest",
        "messages": [
            {"role": "system", "content": "You are a helpful assistant that translates Russian text to English."},
            {"role": "user", "content": translation_prompt}
        ]
    }
    
    try:
        response = requests.post(API_URL_TEXT, headers=API_HEADERS, json=translation_data)
        response.raise_for_status()
        response_data = response.json()
        
        if "choices" in response_data and len(response_data["choices"]) > 0:
            translated_text = response_data["choices"][0].get('message', {}).get('content', '').strip()
            return translated_text
        else:
            logger.error("Неверная структура ответа от модели при переводе.")
            return None
    except requests.exceptions.RequestException as e:
        logger.error(f"Ошибка при переводе текста: {e}")
        return None

# Функция для преобразования Markdown в HTML
def markdown_to_html(text):
    """
    Простой конвертер Markdown в HTML.
    Обрабатывает заголовки, **жирный**, *курсив*, __подчёркивание__, ~~зачёркивание~~.
    """
    # Экранирование HTML-символов
    text = html.escape(text)
    
    # Замена заголовков: ### Заголовок -> <b>Заголовок</b>
    for i in range(6, 0, -1):  # Обрабатываем заголовки от h6 до h1
        pattern = r'^{0} (.+)$'.format('#' * i)
        replacement = r'<b>\1</b>'
        text = re.sub(pattern, replacement, text, flags=re.MULTILINE)
    
    # Замена **жирный** на <b>жирный</b>
    text = re.sub(r'\*\*(.*?)\*\*', r'<b>\1</b>', text)
    
    # Замена *курсив* на <i>курсив</i>
    text = re.sub(r'\*(.*?)\*', r'<i>\1</i>', text)
    
    # Замена __подчёркивание__ на <u>подчёркивание</u>
    text = re.sub(r'__(.*?)__', r'<u>\1</u>', text)
    
    # Замена ~~зачёркивание~~ на 
зачёркивание

    text = re.sub(r'~~(.*?)~~', r'
\1
', text)
    
    return text

# Функция для сохранения ответа в .md файл
def save_md_file(content, user_id):
    """
    Сохраняет содержимое в .md файл с уникальным именем.
    Возвращает путь к файлу.
    """
    if not os.path.exists('responses'):
        os.makedirs('responses')
    
    timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
    filename = f"responses/{user_id}_{timestamp}.md"
    
    try:
        with open(filename, 'w', encoding='utf-8') as f:
            f.write(content)
        return filename
    except Exception as e:
        logger.error(f"Ошибка при сохранении файла .md: {e}")
        return None

# Обработчик команды /set_mode
async def set_mode(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """
    Позволяет пользователю выбрать режим получения ответов:
    - message: получение текстовых сообщений
    - file: получение ответов в .md файлах
    """
    user_id = update.effective_user.id
    if user_id not in AUTHORIZED_USER_IDS:
        await update.message.reply_text('У тебя нет доступа к этому боту.')
        return
    
    if len(context.args) != 1:
        await update.message.reply_text('Использование: /set_mode [message|file]')
        return
    
    mode = context.args[0].lower()
    if mode not in ['message', 'file']:
        await update.message.reply_text('Неверный режим. Используйте "message" или "file".')
        return
    
    user_mode_store[user_id] = mode
    await update.message.reply_text(f'Режим получения ответов установлен на: <b>{mode}</b>', parse_mode=ParseMode.HTML)

# Обработчик команды /get_mode
async def get_mode(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """
    Позволяет пользователю узнать текущий режим получения ответов.
    """
    user_id = update.effective_user.id
    if user_id not in AUTHORIZED_USER_IDS:
        await update.message.reply_text('У тебя нет доступа к этому боту.')
        return
    
    mode = user_mode_store.get(user_id, 'message')  # По умолчанию 'message'
    await update.message.reply_text(f'Текущий режим получения ответов: <b>{mode}</b>', parse_mode=ParseMode.HTML)

# Обработчик команды /start
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    user_id = update.effective_user.id
    if user_id not in AUTHORIZED_USER_IDS:
        await update.message.reply_text('У тебя нет доступа к этому боту.')
        return

    chat_id = update.effective_chat.id
    # Инициализация контекста для нового пользователя
    if chat_id not in context_store:
        context_store[chat_id] = {}
    
    # Если модель ещё не выбрана, устанавливаем модель по умолчанию
    if chat_id not in model_store:
        if model_id_to_info:
            default_model_id = next(iter(model_id_to_info))
            model_store[chat_id] = default_model_id
            model_info = model_id_to_info[default_model_id]
            if model_info.get('type') == 'text':
                context_store[chat_id][default_model_id] = [{"role": "system", "content": SYSTEM_INSTRUCTION_TEXT}]
        else:
            await update.message.reply_text('Нет доступных моделей для использования.', reply_markup=get_main_buttons())
            return
    
    # Создаем основную клавиатуру с кнопкой "Меню"
    main_menu_keyboard = [
        [KeyboardButton("Меню")]
    ]
    reply_markup = ReplyKeyboardMarkup(main_menu_keyboard, resize_keyboard=True)
    
    # Кнопки для выбора модели
    if config.get('models'):
        await update.message.reply_text(
            'Привет! Выбери модель для взаимодействия:',
            reply_markup=get_model_buttons()
        )
    else:
        await update.message.reply_text(
            'Привет! Помяукай сюда. Здесь GPT-4o-latest.\n\nНет доступных моделей для выбора.',
            reply_markup=get_main_buttons()
        )

# Обработчик выбора модели через кнопки
async def select_model(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    query = update.callback_query
    await query.answer()

    user_id = update.effective_user.id
    if user_id not in AUTHORIZED_USER_IDS:
        await query.edit_message_text('У тебя нет доступа к этому боту.')
        return

    selected_model_id = query.data
    model_info = model_id_to_info.get(selected_model_id)

    if not model_info:
        await query.edit_message_text('Выбранная модель не найдена в конфигурации.')
        return

    chat_id = update.effective_chat.id
    model_store[chat_id] = selected_model_id

    model_type = model_info.get('type', 'text')

    # Инициализация контекста для выбранной модели, только если это текстовая модель
    if model_type == 'text':
        if selected_model_id not in context_store.get(chat_id, {}):
            context_store[chat_id][selected_model_id] = [{"role": "system", "content": SYSTEM_INSTRUCTION_TEXT}]
    else:
        # Для image моделей контекст не инициализируется или очищается
        if chat_id in context_store and selected_model_id in context_store[chat_id]:
            del context_store[chat_id][selected_model_id]

    model_name = html.escape(model_id_to_name.get(selected_model_id, "Неизвестная модель"))
    await query.edit_message_text(f'Модель изменена на: <b>{model_name}</b>', reply_markup=get_menu_buttons())

# Обработчик текстовых сообщений
async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    user_id = update.effective_user.id
    if user_id not in AUTHORIZED_USER_IDS:
        await update.message.reply_text('У тебя нет доступа к этому боту.')
        return

    chat_id = update.effective_chat.id
    user_message = update.message.text

    # Проверка, нажата ли кнопка "Меню"
    if user_message.lower() == "меню":
        await show_menu(update, context)
        return

    # Получаем режим пользователя, по умолчанию 'message'
    mode = user_mode_store.get(user_id, 'message')

    if chat_id not in model_store:
        await update.message.reply_text('Модель не выбрана. Используется модель по умолчанию.')
        if model_id_to_info:
            default_model_id = next(iter(model_id_to_info))
            model_store[chat_id] = default_model_id
            model_info = model_id_to_info[default_model_id]
            if model_info.get('type') == 'text':
                context_store[chat_id][default_model_id] = [{"role": "system", "content": SYSTEM_INSTRUCTION_TEXT}]
        else:
            await update.message.reply_text('Нет доступных моделей для использования.', reply_markup=get_main_buttons())
            return

    selected_model_id = model_store.get(chat_id)
    model_info = model_id_to_info.get(selected_model_id)
    if not model_info:
        await update.message.reply_text('Модель не найдена в конфигурации.', reply_markup=get_main_buttons())
        return

    selected_model_type = model_info.get('type', 'text')

    if selected_model_type == 'text':
        # Инициализация контекста для текстовой модели, если ещё не инициализирована
        if selected_model_id not in context_store.get(chat_id, {}):
            context_store[chat_id][selected_model_id] = [{"role": "system", "content": SYSTEM_INSTRUCTION_TEXT}]
        
        # Добавление сообщения пользователя в контекст
        context_store[chat_id][selected_model_id].append({"role": "user", "content": user_message})

        # Подготовка данных для API с учетом контекста
        data = {
            "model": selected_model_id,
            "messages": context_store[chat_id][selected_model_id]
        }
        api_url = API_URL_TEXT

    elif selected_model_type == 'image':
        # Проверка, является ли запрос русским
        if is_russian(user_message):
            # Сообщаем пользователю о переводе
            await update.message.reply_text('Ваш запрос на русском языке. Пожалуйста, подождите, идет перевод.')

            # Переводим запрос на английский
            translated_prompt = translate_to_english(user_message)
            if not translated_prompt:
                await update.message.reply_text('Не удалось перевести запрос. Попробуй позже.', reply_markup=get_menu_buttons())
                return

            # Используем переведенный запрос для генерации изображения
            data = {
                "model": selected_model_id,
                "prompt": translated_prompt  # Не экранируем, так как это отправка API
            }
        else:
            # Подготовка данных для API без перевода
            data = {
                "model": selected_model_id,
                "prompt": user_message  # Не экранируем, так как это отправка API
            }
        api_url = API_URL_IMAGE
    else:
        await update.message.reply_text('Неизвестный тип модели.', reply_markup=get_menu_buttons())
        return

    try:
        # Отправка запроса в API
        response = requests.post(api_url, headers=API_HEADERS, json=data)
        response.raise_for_status()  # Эта строка вызовет исключение для статусов ошибок
    except requests.exceptions.RequestException as e:
        logger.error(f"Ошибка запроса к API: {e}")
        await update.message.reply_text('API не отвечает или произошла ошибка при обработке запроса. Попробуй позже.', reply_markup=get_menu_buttons())
        return

    if response.status_code == 200:
        response_data = response.json()
        logger.info(f"Ответ API: {response_data}")

        if selected_model_type == 'text':
            # Проверка структуры ответа для текстовых моделей
            if "choices" in response_data and len(response_data["choices"]) > 0:
                answer = response_data["choices"][0].get('message', {}).get('content', 'Что-то пошло не так. Мяу :(')
                
                if mode == 'message':
                    # Преобразование Markdown в HTML
                    answer_html = markdown_to_html(answer)
                    
                    # Добавление ответа ассистента в контекст
                    context_store[chat_id][selected_model_id].append({"role": "assistant", "content": answer})
                    
                    # Разбивка длинного ответа на части и отправка
                    messages = split_message(answer_html, MAX_MESSAGE_LENGTH)
                    for msg in messages:
                        await update.message.reply_text(msg, reply_markup=get_menu_buttons())
                elif mode == 'file':
                    # Сохранение ответа в .md файл
                    file_path = save_md_file(answer, user_id)
                    if file_path:
                        # Отправка файла пользователю
                        try:
                            with open(file_path, 'rb') as f:
                                await update.message.reply_document(
                                    document=f,
                                    filename=os.path.basename(file_path),
                                    caption="Ваш ответ модели в формате Markdown.",
                                    reply_markup=get_menu_buttons()
                                )
                            
                            # Удаление файла после отправки
                            os.remove(file_path)
                        except Exception as e:
                            logger.error(f"Ошибка при отправке файла: {e}")
                            await update.message.reply_text('Не удалось отправить файл. Попробуйте позже.', reply_markup=get_menu_buttons())
                    else:
                        await update.message.reply_text('Не удалось создать файл с ответом.', reply_markup=get_menu_buttons())
            else:
                await update.message.reply_text('Что-то пошло не так. Мяу :(', reply_markup=get_menu_buttons())
        elif selected_model_type == 'image':
            # Обработка ответа для image моделей
            image_data = response_data.get('data')
            if isinstance(image_data, list) and len(image_data) > 0:
                for image in image_data:
                    image_url = image.get('url')
                    if image_url:
                        # Отправка изображения пользователю
                        await update.message.reply_photo(photo=image_url, reply_markup=get_menu_buttons())
                    else:
                        await update.message.reply_text('Не удалось получить URL изображения.', reply_markup=get_menu_buttons())
            else:
                await update.message.reply_text('Не удалось получить изображение. Попробуй позже.', reply_markup=get_menu_buttons())
    else:
        logger.error(f"Непредвиденный статус ответа API: {response.status_code}")
        await update.message.reply_text('API вернул непредвиденный ответ. Попробуй позже.', reply_markup=get_menu_buttons())

# Функция для отображения меню
async def show_menu(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """
    Отправляет пользователю список доступных команд и инструкций.
    """
    menu_text = (
        "<b>Инструкция по использованию бота:</b>\n\n"
        "/start - Запустить бота и выбрать модель для взаимодействия.\n"
        "/set_mode [message|file] - Выбрать режим получения ответов (message - текстовые сообщения, file - .md файлы).\n"
        "/get_mode - Узнать текущий выбранный режим.\n\n"
        "Также вы можете использовать кнопки ниже:\n"
        "<b>Сменить модель</b> - Выбрать другую модель для общения.\n"
        "<b>Продолжить</b> - Продолжить ответ модели."
    )

    # Создаем кнопки в меню
    menu_buttons = [
        [InlineKeyboardButton("Сменить модель", callback_data='change_model')],
        [InlineKeyboardButton("Продолжить", callback_data='continue_response')]
    ]
    reply_markup = InlineKeyboardMarkup(menu_buttons)

    await update.message.reply_text(menu_text, parse_mode=ParseMode.HTML, reply_markup=reply_markup)

# Обработчик нажатия кнопки "Сменить модель"
async def change_model_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Обрабатывает нажатие кнопки 'Сменить модель'."""
    query = update.callback_query
    await query.answer()

    user_id = update.effective_user.id
    if user_id not in AUTHORIZED_USER_IDS:
        await query.edit_message_text('У тебя нет доступа к этому боту.')
        return

    selected_model_id = query.data
    model_info = model_id_to_info.get(selected_model_id)

    if not model_info:
        await query.edit_message_text('Выбранная модель не найдена в конфигурации.')
        return

    chat_id = update.effective_chat.id
    model_store[chat_id] = selected_model_id

    model_type = model_info.get('type', 'text')

    # Инициализация контекста для выбранной модели, только если это текстовая модель
    if model_type == 'text':
        if selected_model_id not in context_store.get(chat_id, {}):
            context_store[chat_id][selected_model_id] = [{"role": "system", "content": SYSTEM_INSTRUCTION_TEXT}]
    else:
        # Для image моделей контекст не инициализируется или очищается
        if chat_id in context_store and selected_model_id in context_store[chat_id]:
            del context_store[chat_id][selected_model_id]

    model_name = html.escape(model_id_to_name.get(selected_model_id, "Неизвестная модель"))
    await query.edit_message_text(f'Модель изменена на: <b>{model_name}</b>', parse_mode=ParseMode.HTML, reply_markup=get_menu_buttons())

# Обработчик нажатия кнопки "Продолжить"
async def continue_response(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Обрабатывает нажатие кнопки 'Продолжить'."""
    query = update.callback_query
    await query.answer()

    user_id = update.effective_user.id
    if user_id not in AUTHORIZED_USER_IDS:
        await query.edit_message_text('У тебя нет доступа к этому боту.')
        return

    chat_id = update.effective_chat.id
    selected_model_id = model_store.get(chat_id)
    model_info = model_id_to_info.get(selected_model_id)

    if not model_info:
        await query.edit_message_text('Модель не найдена в конфигурации.')
        return

    selected_model_type = model_info.get('type', 'text')

    # Получаем режим пользователя
    mode = user_mode_store.get(user_id, 'message')

    if selected_model_type == 'text':
        # Добавление сообщения пользователя для продолжения
        context_store[chat_id][selected_model_id].append({"role": "user", "content": "Продолжи."})

        # Подготовка данных для API с учетом контекста
        data = {
            "model": selected_model_id,
            "messages": context_store[chat_id][selected_model_id]
        }
        api_url = API_URL_TEXT

        try:
            # Отправка запроса в API
            response = requests.post(api_url, headers=API_HEADERS, json=data)
            response.raise_for_status()
        except requests.exceptions.RequestException as e:
            logger.error(f"Ошибка запроса к API: {e}")
            await query.message.reply_text('API не отвечает или произошла ошибка при обработке запроса. Попробуй позже.', reply_markup=get_menu_buttons())
            return

        if response.status_code == 200:
            response_data = response.json()
            logger.info(f"Ответ API: {response_data}")

            # Проверка структуры ответа для текстовых моделей
            if "choices" in response_data and len(response_data["choices"]) > 0:
                answer = response_data["choices"][0].get('message', {}).get('content', 'Что-то пошло не так. Мяу :(')
                
                if mode == 'message':
                    # Преобразование Markdown в HTML
                    answer_html = markdown_to_html(answer)
                    
                    # Добавление ответа ассистента в контекст
                    context_store[chat_id][selected_model_id].append({"role": "assistant", "content": answer})
                    
                    # Разбивка длинного ответа на части и отправка
                    messages = split_message(answer_html, MAX_MESSAGE_LENGTH)
                    for msg in messages:
                        await query.message.reply_text(msg, reply_markup=get_menu_buttons())
                elif mode == 'file':
                    # Сохранение ответа в .md файл
                    file_path = save_md_file(answer, user_id)
                    if file_path:
                        # Отправка файла пользователю
                        try:
                            with open(file_path, 'rb') as f:
                                await query.message.reply_document(
                                    document=f,
                                    filename=os.path.basename(file_path),
                                    caption="Ваш ответ модели в формате Markdown.",
                                    reply_markup=get_menu_buttons()
                                )
                            
                            # Удаление файла после отправки
                            os.remove(file_path)
                        except Exception as e:
                            logger.error(f"Ошибка при отправке файла: {e}")
                            await query.message.reply_text('Не удалось отправить файл. Попробуйте позже.', reply_markup=get_menu_buttons())
                    else:
                        await query.message.reply_text('Не удалось создать файл с ответом.', reply_markup=get_menu_buttons())
            else:
                await query.message.reply_text('Что-то пошло не так. Мяу :(', reply_markup=get_menu_buttons())
        else:
            logger.error(f"Непредвиденный статус ответа API: {response.status_code}")
            await query.message.reply_text('API вернул непредвиденный ответ. Попробуй позже.', reply_markup=get_menu_buttons())
    elif selected_model_type == 'image':
        await query.message.reply_text('Функция "Продолжить" не поддерживается для выбранной модели.', reply_markup=get_menu_buttons())
    else:
        await query.message.reply_text('Неизвестный тип модели.', reply_markup=get_menu_buttons())

# Функция для отображения меню
async def show_menu(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """
    Отправляет пользователю список доступных команд и инструкций.
    """
    menu_text = (
        "<b>Инструкция по использованию бота:</b>\n\n"
        "<b>/start</b> - Запустить бота и выбрать модель для взаимодействия.\n"
        "<b>/set_mode [message|file]</b> - Выбрать режим получения ответов (message - текстовые сообщения, file - .md файлы).\n"
        "<b>/get_mode</b> - Узнать текущий выбранный режим.\n\n"
        "Также доступно использование кнопок ниже:\n"
        "<b>Сменить модель</b> - Выбрать другую модель для общения.\n"
        "<b>Продолжить</b> - Продолжить ответ модели."
    )

    # Создаем кнопки в меню
    menu_buttons = [
        [InlineKeyboardButton("Сменить модель", callback_data='change_model'),
         InlineKeyboardButton("Продолжить", callback_data='continue_response')]
    ]
    reply_markup = InlineKeyboardMarkup(menu_buttons)

    await update.message.reply_text(menu_text, parse_mode=ParseMode.HTML, reply_markup=reply_markup)

# Обработчик ошибок
async def error_handler(update: object, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Ловит все необработанные ошибки."""
    logger.error(msg="Exception while handling an update:", exc_info=context.error)
    if isinstance(update, Update) and update.effective_user:
        try:
            await update.effective_message.reply_text('Произошла ошибка. Пожалуйста, попробуйте позже.', reply_markup=get_menu_buttons())
        except TelegramError as e:
            logger.error(f"Не удалось отправить сообщение об ошибке пользователю: {e}")

# Основная функция запуска бота
def main():
    # Загрузка конфигурации уже произведена выше
    TELEGRAM_TOKEN = config.get('telegram_token')
    if not TELEGRAM_TOKEN:
        logger.error("Telegram Token не указан в config.json.")
        exit(1)
    
    # Создание экземпляра приложения с установкой ParseMode.HTML по умолчанию
    application = ApplicationBuilder().token(TELEGRAM_TOKEN).defaults(Defaults(parse_mode=ParseMode.HTML)).build()

    # Обработчики команд и сообщений
    application.add_handler(CommandHandler("start", start))
    application.add_handler(CommandHandler("set_mode", set_mode))
    application.add_handler(CommandHandler("get_mode", get_mode))
    
    # Обработчики CallbackQuery для выбора моделей и меню
    application.add_handler(CallbackQueryHandler(select_model, pattern='^[a-zA-Z0-9_-]+$'))
    application.add_handler(CallbackQueryHandler(show_menu if 'show_instructions' else None, pattern='^show_instructions$'))
    application.add_handler(CallbackQueryHandler(change_model_callback, pattern='^change_model$'))
    application.add_handler(CallbackQueryHandler(continue_response, pattern='^continue_response$'))
    
    # Обработчик текстовых сообщений для кнопки "Меню"
    application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message))
    
    # Обработчик ошибок
    application.add_error_handler(error_handler)

    # Запуск бота
    application.run_polling()

if __name__ == '__main__':
    main()
изучи код и исправь ошибку: при нажатии любых кнопок ( инструкция по использованию, сменить модель, продолжить ) бот пишет что выбранная модель не найдена в конфигурации. исправь это ( с моделью и конфигурацией всё хорошо )