Go to file
mirivlad ea9054ad80 Add retention cleanup for persisted state 2026-04-07 17:23:17 +08:00
bot Add live tool approvals via Telegram 2026-04-07 17:17:17 +08:00
serv Add retention cleanup for persisted state 2026-04-07 17:23:17 +08:00
.gitignore Add client-server Qwen OAuth bot skeleton 2026-04-07 16:38:21 +08:00
README.md Add retention cleanup for persisted state 2026-04-07 17:23:17 +08:00

README.md

new-qwen

Клиент-серверная замена локального агента qwen-code.

  • serv отвечает за OAuth, сессии, работу с Qwen LLM и вызов инструментов.
  • bot отвечает за Telegram и пересылку сообщений на сервер.

Проект написан на Python stdlib, чтобы не зависеть от Node/npm в текущем окружении.

Архитектура

Telegram User
   |
   v
bot/app.py
   |
   v
serv/app.py
   |
   v
Qwen OAuth + OpenAI-compatible endpoint

Что уже реализовано

  • Qwen OAuth Device Flow, совместимый с qwen-code
  • хранение токенов в ~/.qwen/oauth_creds.json
  • HTTP API сервера
  • агентный цикл с tool calling
  • инструменты: list_files, glob_search, grep_text, stat_path, read_file, apply_unified_diff, replace_in_file, write_file, make_directory, exec_command
  • Telegram polling без внешних библиотек
  • JSON-хранилище сессий
  • API списка и просмотра сессий
  • автоматический polling OAuth flow в боте
  • очередь сообщений, пришедших до завершения OAuth
  • job-based chat polling между bot и serv
  • persistence для chat jobs и pending OAuth flows на стороне serv
  • policy mode для инструментов: full-access, workspace-write, read-only
  • live approval flow для инструментов через Telegram

Ограничения текущей реализации

  • это упрощённая серверная архитектура, а не побайтный порт всего qwen-code
  • пока нет MCP, skill system, subagents и rich-streaming UI
  • Telegram-бот работает через long polling

Переменные окружения

Сервер:

cp serv/.env.example serv/.env

Ключевые параметры сервера:

  • NEW_QWEN_STATE_DIR - где хранить jobs и pending OAuth flows
  • NEW_QWEN_TOOL_POLICY - режим инструментов: full-access - все инструменты workspace-write - без exec_command read-only - только чтение и поиск ask-shell - shell только после подтверждения ask-write - shell и записи только после подтверждения ask-all - любой инструмент только после подтверждения
  • NEW_QWEN_APPROVAL_TIMEOUT_SECONDS - сколько сервер ждёт решения по approval
  • NEW_QWEN_JOBS_RETENTION_SECONDS - сколько хранить завершённые/failed jobs
  • NEW_QWEN_APPROVALS_RETENTION_SECONDS - сколько хранить завершённые approvals

Бот:

cp bot/.env.example bot/.env

Запуск

Сервер:

python3 serv/app.py

Бот:

python3 bot/app.py

Авторизация Qwen OAuth

  1. Отправить боту /auth
  2. Открыть ссылку подтверждения
  3. Бот сам дождётся завершения OAuth и продолжит работу

Если пользователь отправит обычное сообщение до завершения OAuth, бот поставит его в очередь и автоматически отправит на сервер после успешной авторизации.

Либо можно вызвать API сервера напрямую:

curl -X POST http://127.0.0.1:8080/api/v1/auth/device/start

API

  • GET /health
  • GET /api/v1/auth/status
  • POST /api/v1/auth/device/start
  • POST /api/v1/auth/device/poll
  • GET /api/v1/sessions
  • GET /api/v1/approvals
  • POST /api/v1/session/get
  • POST /api/v1/session/clear
  • POST /api/v1/chat
  • POST /api/v1/chat/start
  • POST /api/v1/chat/poll
  • POST /api/v1/approval/respond

Telegram Approval Flow

Если политика инструментов настроена как ask-shell, ask-write или ask-all, бот пришлёт запрос на подтверждение с approval_id.

Дальше можно ответить одной из команд:

  • /approve <approval_id>
  • /reject <approval_id>