fix: упрощение работы с Qwen Code
Изменения: - Использование флага -p для передачи задачи - Простой текстовый вывод вместо stream-json - Каждый запрос запускает новый процесс qwen - Убрано сложное управление сессиями - Edit сообщения вместо новых сообщений Теперь /ai работает стабильнее Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
parent
5d451ff870
commit
cac597688d
36
bot.py
36
bot.py
|
|
@ -2687,41 +2687,33 @@ async def ai_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
|||
return
|
||||
|
||||
# Отправляем задачу в ИИ
|
||||
await update.message.reply_text("⏳ 🤖 Думаю...", parse_mode="Markdown")
|
||||
status_msg = await update.message.reply_text("⏳ 🤖 Думаю...", parse_mode="Markdown")
|
||||
|
||||
output_buffer = []
|
||||
oauth_url_sent = False
|
||||
|
||||
def on_output(text: str):
|
||||
output_buffer.append(text)
|
||||
|
||||
def on_oauth_url(url: str):
|
||||
nonlocal oauth_url_sent
|
||||
if not oauth_url_sent:
|
||||
oauth_url_sent = True
|
||||
asyncio.create_task(update.message.reply_text(
|
||||
f"🔐 *Требуется авторизация Qwen Code*\n\n"
|
||||
f"Откройте ссылку для авторизации:\n"
|
||||
f"{url}\n\n"
|
||||
f"После авторизации отправьте команду снова.",
|
||||
parse_mode="Markdown"
|
||||
))
|
||||
pass # OAuth обрабатывается автоматически при первом запуске
|
||||
|
||||
# Выполняем задачу
|
||||
result = await qwen_manager.run_task(user_id, task, on_output, on_oauth_url)
|
||||
|
||||
# Если это не OAuth — показываем результат
|
||||
if not oauth_url_sent:
|
||||
full_output = "".join(output_buffer)
|
||||
# Показываем результат
|
||||
full_output = "".join(output_buffer).strip()
|
||||
|
||||
if len(full_output) > 4000:
|
||||
full_output = full_output[:4000] + "\n... (вывод обрезан)"
|
||||
if not full_output:
|
||||
full_output = result
|
||||
|
||||
await update.message.reply_text(
|
||||
f"🤖 *Результат:*\n\n"
|
||||
f"```\n{full_output if full_output else result}\n```",
|
||||
parse_mode="Markdown"
|
||||
)
|
||||
if len(full_output) > 4000:
|
||||
full_output = full_output[:4000] + "\n... (вывод обрезан)"
|
||||
|
||||
await status_msg.edit_text(
|
||||
f"🤖 *Результат:*\n\n"
|
||||
f"```\n{full_output}\n```",
|
||||
parse_mode="Markdown"
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
|
|
|
|||
|
|
@ -88,30 +88,17 @@ class QwenCodeManager:
|
|||
on_oauth_url: Callable[[str], Any]) -> str:
|
||||
"""
|
||||
Выполнить задачу в Qwen Code.
|
||||
|
||||
Args:
|
||||
user_id: ID пользователя
|
||||
task: Задача для выполнения
|
||||
on_output: Callback для вывода (вызывается при появлении вывода)
|
||||
on_oauth_url: Callback для OAuth URL (вызывается если нужна авторизация)
|
||||
|
||||
Returns:
|
||||
Результат выполнения
|
||||
Для простоты каждый раз запускаем новый процесс.
|
||||
"""
|
||||
# Создаём временную сессию для отслеживания
|
||||
session = self.get_session(user_id)
|
||||
|
||||
# Если сессии нет или она в ошибке — создаём новую
|
||||
if not session or session.state == QwenSessionState.ERROR:
|
||||
if not session:
|
||||
session = self.create_session(user_id)
|
||||
|
||||
session.last_activity = datetime.now()
|
||||
session.pending_task = task
|
||||
|
||||
# Если сессия ещё не готова (ожидает OAuth или запуска)
|
||||
if session.state in [QwenSessionState.STARTING, QwenSessionState.WAITING_FOR_OAUTH]:
|
||||
return await self._start_session(session, on_output, on_oauth_url, task)
|
||||
|
||||
# Если сессия готова — выполняем задачу
|
||||
# Просто выполняем задачу через -p флаг
|
||||
return await self._execute_task(session, task, on_output)
|
||||
|
||||
async def _start_session(self, session: QwenSession,
|
||||
|
|
@ -208,11 +195,29 @@ class QwenCodeManager:
|
|||
session.output_buffer = ""
|
||||
|
||||
try:
|
||||
# Отправляем задачу
|
||||
session.process.stdin.write(task + "\n")
|
||||
session.process.stdin.flush()
|
||||
# Для неинтерактивного режима используем -p
|
||||
env = os.environ.copy()
|
||||
env["FORCE_COLOR"] = "0"
|
||||
|
||||
# Читаем ответ
|
||||
cmd = [
|
||||
self._qwen_command,
|
||||
"-p", task, # Передаём задачу через флаг -p
|
||||
"--output-format", "text", # Простой текстовый вывод
|
||||
]
|
||||
|
||||
logger.info(f"Выполнение задачи: {' '.join(cmd)}")
|
||||
|
||||
process = subprocess.Popen(
|
||||
cmd,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
cwd=self._working_dir,
|
||||
env=env,
|
||||
text=True,
|
||||
bufsize=1
|
||||
)
|
||||
|
||||
# Читаем вывод
|
||||
output = ""
|
||||
timeout = 300 # 5 минут на выполнение
|
||||
|
||||
|
|
@ -222,31 +227,32 @@ class QwenCodeManager:
|
|||
# Проверяем таймаут
|
||||
if (datetime.now() - start_time).total_seconds() > timeout:
|
||||
output += "\n\n⚠️ Таймаут выполнения (5 минут)"
|
||||
process.terminate()
|
||||
break
|
||||
|
||||
# Проверяем процесс
|
||||
if session.process.poll() is not None:
|
||||
if process.poll() is not None:
|
||||
# Процесс завершился
|
||||
remaining = session.process.stdout.read()
|
||||
remaining = process.stdout.read()
|
||||
if remaining:
|
||||
output += remaining
|
||||
on_output(remaining)
|
||||
break
|
||||
|
||||
# Читаем вывод
|
||||
line = session.process.stdout.readline()
|
||||
line = process.stdout.readline()
|
||||
if line:
|
||||
output += line
|
||||
session.output_buffer += line
|
||||
on_output(line)
|
||||
|
||||
# Небольшая пауза чтобы не блокировать
|
||||
# Небольшая пауза
|
||||
await asyncio.sleep(0.1)
|
||||
|
||||
session.state = QwenSessionState.READY
|
||||
session.last_activity = datetime.now()
|
||||
|
||||
return self._parse_output(output)
|
||||
return output.strip()
|
||||
|
||||
except Exception as e:
|
||||
session.state = QwenSessionState.ERROR
|
||||
|
|
|
|||
Loading…
Reference in New Issue