Go to file
mirivlad 90f1c6ebaf Fix Qwen OAuth HTTP request format 2026-04-09 01:25:59 +08:00
bot Fix Qwen OAuth: use http.client, correct endpoints, remove API key mode 2026-04-08 12:52:18 +00:00
serv Fix Qwen OAuth HTTP request format 2026-04-09 01:25:59 +08:00
.gitignore Fix Qwen OAuth: use http.client, correct endpoints, remove API key mode 2026-04-08 12:52:18 +00:00
README.md Add Telegram proxy support 2026-04-08 13:49:23 +08:00
TODO.md Serialize chat jobs and add cancel flow 2026-04-08 11:48:21 +08:00

README.md

new-qwen

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

  • serv отвечает за OAuth, сессии, маршрутизацию к model provider-ам и вызов инструментов.
  • bot отвечает за Telegram и пересылку сообщений на сервер.

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

Архитектура

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

На стороне serv теперь есть отдельные слои:

  • model_router.py - выбор провайдера и fallback policy
  • llm.py - агентный цикл поверх абстракции провайдера
  • oauth.py - auth only для Qwen path
  • gigachat.py - token management для GigaChat

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

  • Qwen OAuth Device Flow, совместимый с qwen-code
  • хранение токенов в ~/.qwen/oauth_creds.json
  • HTTP API сервера
  • агентный цикл с tool calling
  • инструменты: list_files, glob_search, grep_text, stat_path, read_file, web_search, append_file, apply_unified_diff, replace_in_file, write_file, make_directory, delete_path, move_path, copy_path, git_status, git_diff, 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
  • provider-based web search с приоритетом DashScope через Qwen OAuth
  • model router с qwen как первым провайдером и fallback-ready архитектурой для gigachat и yandexgpt
  • router умеет fallback не только по конфигу, но и при runtime-ошибке провайдера
  • реальный adapter для gigachat с token fetch и нормализацией function calling под внутренний agent loop

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

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

Roadmap

Текущий список работ вынесен в TODO.md.

Ближайший фокус:

  • сериализация jobs на один Telegram chat
  • cancel flow между bot и serv
  • выравнивание approval semantics для всех chat API

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

Сервер:

cp serv/.env.example serv/.env

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

  • NEW_QWEN_STATE_DIR - где хранить jobs и pending OAuth flows
  • NEW_QWEN_DEFAULT_PROVIDER - основной model provider, сейчас по умолчанию qwen
  • NEW_QWEN_FALLBACK_PROVIDERS - fallback-цепочка провайдеров через запятую
  • NEW_QWEN_GIGACHAT_MODEL - имя модели GigaChat
  • NEW_QWEN_GIGACHAT_AUTH_KEY - ключ авторизации GigaChat для Authorization: Basic ...
  • NEW_QWEN_GIGACHAT_SCOPE - scope для получения access token, по умолчанию GIGACHAT_API_PERS
  • NEW_QWEN_GIGACHAT_API_BASE_URL - базовый URL inference API GigaChat
  • NEW_QWEN_GIGACHAT_OAUTH_URL - URL получения access token GigaChat
  • NEW_QWEN_YANDEXGPT_MODEL - имя модели для будущего YandexGPT adapter
  • NEW_QWEN_TELEGRAM_PROXY - необязательный HTTPS прокси для доступа Telegram (например http://127.0.0.1:7890)
  • 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
  • NEW_QWEN_TAVILY_API_KEY - опциональный Tavily provider
  • NEW_QWEN_GOOGLE_SEARCH_API_KEY и NEW_QWEN_GOOGLE_SEARCH_ENGINE_ID - опциональный Google Custom Search provider

Бот:

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/chat/cancel
  • POST /api/v1/approval/respond

GET /api/v1/auth/status теперь также показывает:

  • ready
  • available_providers
  • default_provider
  • fallback_providers
  • список providers с availability и capabilities

Telegram Approval Flow

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

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

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

Управление job:

  • /cancel - отменить активный запрос и очистить очередь сообщений в чате