import logging from telegram import Update from telegram.ext import ( Application, CommandHandler, InlineQueryHandler, MessageHandler, TypeHandler, filters, ) from .ai import AIClient from .auth import authentication_guard from .config import AppSettings, load_app_settings from .handlers import ( ask_command, help_command, history_command, inline_query, model_command, models_command, new_conversation_command, private_text, private_voice, start, ) from .jobs import post_init, post_shutdown from .ollama import OllamaClient from .services import SERVICES_KEY, ApplicationServices from .storage import AssistantStorage from .speech import SpeechRecognizer, SpeechTranscriber from .yandex_ai import YandexAIClient, YandexSpeechRecognizer def configure_logging() -> None: logging.basicConfig( format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO, ) logging.getLogger("httpx").setLevel(logging.WARNING) def create_services(settings: AppSettings) -> ApplicationServices: storage = AssistantStorage(settings.db_path) ai_client: AIClient speech_recognizer: SpeechTranscriber if settings.mode == "local": ai_client = OllamaClient(settings.ollama_base_url) speech_recognizer = SpeechRecognizer( model_name=settings.whisper_model, device=settings.whisper_device, compute_type=settings.whisper_compute_type, language=settings.whisper_language, ) else: folder_id = settings.yandex_cloud_folder if folder_id is None: raise RuntimeError( "YANDEX_CLOUD_FOLDER is required in yandex mode." ) ai_client = YandexAIClient(folder_id=folder_id) speech_recognizer = YandexSpeechRecognizer( folder_id=folder_id, language=settings.yandex_stt_language, model=settings.yandex_stt_model, ) return ApplicationServices( storage=storage, ai_client=ai_client, timezone=settings.timezone, speech_recognizer=speech_recognizer, voice_max_duration_seconds=settings.voice_max_duration_seconds, assistant_password=settings.assistant_password, ) def create_application(settings: AppSettings | None = None) -> Application: settings = settings or load_app_settings() application = ( Application.builder() .token(settings.bot_token) .post_init(post_init) .post_shutdown(post_shutdown) .build() ) application.bot_data[SERVICES_KEY] = create_services(settings) application.add_handler(TypeHandler(Update, authentication_guard), group=-1) application.add_handler(CommandHandler("start", start)) application.add_handler(CommandHandler("help", help_command)) application.add_handler(CommandHandler("ask", ask_command)) application.add_handler(CommandHandler("models", models_command)) application.add_handler(CommandHandler("model", model_command)) application.add_handler(CommandHandler("new", new_conversation_command)) application.add_handler(CommandHandler("history", history_command)) application.add_handler(InlineQueryHandler(inline_query)) application.add_handler( MessageHandler(filters.VOICE & filters.ChatType.PRIVATE, private_voice) ) application.add_handler( MessageHandler( filters.TEXT & filters.ChatType.PRIVATE & ~filters.COMMAND, private_text, ) ) return application def run() -> None: configure_logging() create_application().run_polling(allowed_updates=Update.ALL_TYPES)