From 481ad8dddce01bdebc8a59b35fd847dc293e200d Mon Sep 17 00:00:00 2001 From: mirivlad Date: Tue, 17 Mar 2026 03:20:34 +0800 Subject: [PATCH] =?UTF-8?q?=D0=AD=D1=82=D0=B0=D0=BF=201:=20=D0=91=D0=B0?= =?UTF-8?q?=D0=B7=D0=BE=D0=B2=D1=8B=D0=B9=20Telegram-=D0=B1=D0=BE=D1=82=20?= =?UTF-8?q?=D1=81=20=D0=BF=D1=80=D0=BE=D0=BA=D1=81=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 33 ++++++++++++++++++++++++++ .gitignore | 35 ++++++++++++++++++++++++++++ config/__init__.py | 0 config/config.py | 40 ++++++++++++++++++++++++++++++++ requirements.txt | 12 ++++++++++ src/__init__.py | 0 src/bot/__init__.py | 0 src/bot/main.py | 56 +++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 176 insertions(+) create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 config/__init__.py create mode 100644 config/config.py create mode 100644 requirements.txt create mode 100644 src/__init__.py create mode 100644 src/bot/__init__.py create mode 100644 src/bot/main.py diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..92e37f2 --- /dev/null +++ b/.env.example @@ -0,0 +1,33 @@ +# Telegram +TELEGRAM_BOT_TOKEN=your_bot_token_here +TELEGRAM_PROXY_URL=socks5://user:pass@proxy:port +TELEGRAM_PROXY_TYPE=socks5 + +# Access control +ALLOWED_USERNAMES=user1,user2 +BOT_NAME=Валера + +# Tools +DEFAULT_TOOL=opencode +QWEN_COMMAND=qwen-code +OPENCODE_COMMAND=opencode +TOOL_TIMEOUT=120 + +# Memory +MEMORY_MESSAGES_COUNT=10 +CHROMA_PERSIST_DIR=./chroma_db + +# Scheduler +SCHEDULER_ENABLED=true +IDEA_INTERVAL_HOURS=4 + +# Speech-to-text +STT_ENABLED=true +STT_MODEL=vosk + +# Russian LLM (optional) +GIGACHAT_CREDENTIALS= +YANDEX_API_KEY= + +# Database +DATABASE_URL=sqlite+aiosqlite:///./valera.db diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..97b43ca --- /dev/null +++ b/.gitignore @@ -0,0 +1,35 @@ +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +.env +.venv +env/ +venv/ +ENV/ + +chroma_db/ +*.db +*.db-journal + +.DS_Store +.idea/ +.vscode/ +*.log diff --git a/config/__init__.py b/config/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/config/config.py b/config/config.py new file mode 100644 index 0000000..46bc135 --- /dev/null +++ b/config/config.py @@ -0,0 +1,40 @@ +from pydantic_settings import BaseSettings +from functools import lru_cache +from typing import Optional + + +class Settings(BaseSettings): + telegram_bot_token: str = "" + telegram_proxy_url: Optional[str] = None + telegram_proxy_type: str = "socks5" + + allowed_usernames: str = "" + bot_name: str = "Валера" + + default_tool: str = "opencode" + qwen_command: str = "qwen-code" + opencode_command: str = "opencode" + tool_timeout: int = 120 + + memory_messages_count: int = 10 + chroma_persist_dir: str = "./chroma_db" + + scheduler_enabled: bool = True + idea_interval_hours: int = 4 + + stt_enabled: bool = True + stt_model: str = "vosk" + + gigachat_credentials: Optional[str] = None + yandex_api_key: Optional[str] = None + + database_url: str = "sqlite+aiosqlite:///./valera.db" + + class Config: + env_file = ".env" + extra = "allow" + + +@lru_cache() +def get_settings() -> Settings: + return Settings() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..449a0d2 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,12 @@ +python-telegram-bot>=20.0 +python-dotenv>=1.0.0 +pydantic>=2.0.0 +aiofiles>=23.0.0 +chromadb>=0.4.0 +sentence-transformers>=2.2.0 +apscheduler>=3.10.0 +ffmpeg-python>=0.2.0 +vosk>=0.3.45 +faster-whisper>=0.10.0 +gigachat>=0.2.0 +requests>=2.31.0 diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/bot/__init__.py b/src/bot/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/bot/main.py b/src/bot/main.py new file mode 100644 index 0000000..2a12e74 --- /dev/null +++ b/src/bot/main.py @@ -0,0 +1,56 @@ +import asyncio +import logging +from telegram import Update +from telegram.ext import Application, CommandHandler, MessageHandler, filters, ContextTypes +from config.config import get_settings + +logging.basicConfig( + format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", + level=logging.INFO +) +logger = logging.getLogger(__name__) + +settings = get_settings() + + +async def start(update: Update, context: ContextTypes.DEFAULT_TYPE): + await update.message.reply_text( + f"Привет! Я {settings.bot_name}, ваш ИИ-ассистент.\n" + "Я помогу вам с программированием и не только." + ) + + +async def echo(update: Update, context: ContextTypes.DEFAULT_TYPE): + await update.message.reply_text(update.message.text) + + +async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE): + help_text = ( + f"Я {settings.bot_name}, ваш ИИ-ассистент.\n\n" + "Доступные команды:\n" + "/start - Начать работу\n" + "/help - Показать эту справку\n" + ) + await update.message.reply_text(help_text) + + +def main(): + builder = Application.builder() + builder.token(settings.telegram_bot_token) + + if settings.telegram_proxy_url: + builder.proxy_url(settings.telegram_proxy_url) + builder.proxy_type(settings.telegram_proxy_type) + + application = builder.build() + + application.add_handler(CommandHandler("start", start)) + application.add_handler(CommandHandler("help", help_command)) + application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, echo)) + + logger.info("Бот запущен") + application.run_polling(allowed_updates=Update.ALL_TYPES) + + +if __name__ == "__main__": + main()