Этап 2: Интеграция с qwen-code и opencode
This commit is contained in:
parent
481ad8dddc
commit
85e702ce25
|
|
@ -3,6 +3,7 @@ import logging
|
||||||
from telegram import Update
|
from telegram import Update
|
||||||
from telegram.ext import Application, CommandHandler, MessageHandler, filters, ContextTypes
|
from telegram.ext import Application, CommandHandler, MessageHandler, filters, ContextTypes
|
||||||
from config.config import get_settings
|
from config.config import get_settings
|
||||||
|
from src.tools.tool_runner import ToolRunner
|
||||||
|
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
||||||
|
|
@ -11,6 +12,7 @@ logging.basicConfig(
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
settings = get_settings()
|
settings = get_settings()
|
||||||
|
tool_runner = ToolRunner()
|
||||||
|
|
||||||
|
|
||||||
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
|
|
@ -20,20 +22,44 @@ async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
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):
|
async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
help_text = (
|
help_text = (
|
||||||
f"Я {settings.bot_name}, ваш ИИ-ассистент.\n\n"
|
f"Я {settings.bot_name}, ваш ИИ-ассистент.\n\n"
|
||||||
"Доступные команды:\n"
|
"Доступные команды:\n"
|
||||||
"/start - Начать работу\n"
|
"/start - Начать работу\n"
|
||||||
"/help - Показать эту справку\n"
|
"/help - Показать эту справку\n"
|
||||||
|
"/qwen <текст> - Задать вопрос qwen-code\n"
|
||||||
|
"/open <текст> - Задать вопрос opencode\n"
|
||||||
)
|
)
|
||||||
await update.message.reply_text(help_text)
|
await update.message.reply_text(help_text)
|
||||||
|
|
||||||
|
|
||||||
|
async def qwen_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
|
prompt = " ".join(context.args)
|
||||||
|
if not prompt:
|
||||||
|
await update.message.reply_text("Использование: /qwen <текст>")
|
||||||
|
return
|
||||||
|
|
||||||
|
await update.message.reply_text("Думаю...")
|
||||||
|
result, success = await tool_runner.run_qwen(prompt)
|
||||||
|
await update.message.reply_text(result[:4096] if len(result) > 4096 else result)
|
||||||
|
|
||||||
|
|
||||||
|
async def open_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
|
prompt = " ".join(context.args)
|
||||||
|
if not prompt:
|
||||||
|
await update.message.reply_text("Использование: /open <текст>")
|
||||||
|
return
|
||||||
|
|
||||||
|
await update.message.reply_text("Думаю...")
|
||||||
|
result, success = await tool_runner.run_opencode(prompt)
|
||||||
|
await update.message.reply_text(result[:4096] if len(result) > 4096 else result)
|
||||||
|
|
||||||
|
|
||||||
|
async def echo(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
|
await update.message.reply_text(update.message.text)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
builder = Application.builder()
|
builder = Application.builder()
|
||||||
builder.token(settings.telegram_bot_token)
|
builder.token(settings.telegram_bot_token)
|
||||||
|
|
@ -46,6 +72,8 @@ def main():
|
||||||
|
|
||||||
application.add_handler(CommandHandler("start", start))
|
application.add_handler(CommandHandler("start", start))
|
||||||
application.add_handler(CommandHandler("help", help_command))
|
application.add_handler(CommandHandler("help", help_command))
|
||||||
|
application.add_handler(CommandHandler("qwen", qwen_command))
|
||||||
|
application.add_handler(CommandHandler("open", open_command))
|
||||||
application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, echo))
|
application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, echo))
|
||||||
|
|
||||||
logger.info("Бот запущен")
|
logger.info("Бот запущен")
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
import asyncio
|
||||||
|
import logging
|
||||||
|
from typing import Optional, Tuple
|
||||||
|
from config.config import get_settings
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
settings = get_settings()
|
||||||
|
|
||||||
|
|
||||||
|
class ToolRunner:
|
||||||
|
def __init__(self):
|
||||||
|
self.qwen_command = settings.qwen_command
|
||||||
|
self.opencode_command = settings.opencode_command
|
||||||
|
self.timeout = settings.tool_timeout
|
||||||
|
|
||||||
|
async def run_qwen(self, prompt: str) -> Tuple[str, bool]:
|
||||||
|
return await self._run_tool(self.qwen_command, prompt)
|
||||||
|
|
||||||
|
async def run_opencode(self, prompt: str) -> Tuple[str, bool]:
|
||||||
|
return await self._run_tool(self.opencode_command, prompt)
|
||||||
|
|
||||||
|
async def _run_tool(self, command: str, prompt: str) -> Tuple[str, bool]:
|
||||||
|
try:
|
||||||
|
process = await asyncio.create_subprocess_exec(
|
||||||
|
command,
|
||||||
|
prompt,
|
||||||
|
stdout=asyncio.subprocess.PIPE,
|
||||||
|
stderr=asyncio.subprocess.PIPE
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
stdout, stderr = await asyncio.wait_for(
|
||||||
|
process.communicate(),
|
||||||
|
timeout=self.timeout
|
||||||
|
)
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
process.kill()
|
||||||
|
await process.wait()
|
||||||
|
return "Превышен таймаут выполнения", False
|
||||||
|
|
||||||
|
stdout_str = stdout.decode() if stdout else ""
|
||||||
|
stderr_str = stderr.decode() if stderr else ""
|
||||||
|
|
||||||
|
if process.returncode != 0:
|
||||||
|
error_msg = stderr_str or stdout_str
|
||||||
|
return f"Ошибка выполнения: {error_msg}", False
|
||||||
|
|
||||||
|
return stdout_str, True
|
||||||
|
|
||||||
|
except FileNotFoundError:
|
||||||
|
return f"Инструмент {command} не найден. Убедитесь, что он установлен и доступен в PATH.", False
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception("Ошибка при выполнении инструмента")
|
||||||
|
return f"Ошибка: {str(e)}", False
|
||||||
|
|
||||||
|
async def run_tool(self, tool_name: str, prompt: str) -> Tuple[str, bool]:
|
||||||
|
if tool_name == "qwen":
|
||||||
|
return await self.run_qwen(prompt)
|
||||||
|
elif tool_name == "opencode":
|
||||||
|
return await self.run_opencode(prompt)
|
||||||
|
else:
|
||||||
|
return f"Неизвестный инструмент: {tool_name}", False
|
||||||
Loading…
Reference in New Issue