Update from task 72dd9581-013a-4bf0-8b6a-8d7207ad4a13 |
||
|---|---|---|
| bot | ||
| serv | ||
| .gitignore | ||
| README.md | ||
| TODO.md | ||
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 policyllm.py- агентный цикл поверх абстракции провайдераoauth.py- auth only для Qwen pathgigachat.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 flowsNEW_QWEN_DEFAULT_PROVIDER- основной model provider, сейчас по умолчаниюqwenNEW_QWEN_FALLBACK_PROVIDERS- fallback-цепочка провайдеров через запятуюNEW_QWEN_GIGACHAT_MODEL- имя модели GigaChatNEW_QWEN_GIGACHAT_AUTH_KEY- ключ авторизации GigaChat дляAuthorization: Basic ...NEW_QWEN_GIGACHAT_SCOPE- scope для получения access token, по умолчаниюGIGACHAT_API_PERSNEW_QWEN_GIGACHAT_API_BASE_URL- базовый URL inference API GigaChatNEW_QWEN_GIGACHAT_OAUTH_URL- URL получения access token GigaChatNEW_QWEN_YANDEXGPT_MODEL- имя модели для будущего YandexGPT adapterNEW_QWEN_TELEGRAM_PROXY- необязательный HTTPS прокси для доступа Telegram (напримерhttp://127.0.0.1:7890)NEW_QWEN_TOOL_POLICY- режим инструментов:full-access- все инструментыworkspace-write- безexec_commandread-only- только чтение и поискask-shell- shell только после подтвержденияask-write- shell и записи только после подтвержденияask-all- любой инструмент только после подтвержденияNEW_QWEN_APPROVAL_TIMEOUT_SECONDS- сколько сервер ждёт решения по approvalNEW_QWEN_JOBS_RETENTION_SECONDS- сколько хранить завершённые/failed jobsNEW_QWEN_APPROVALS_RETENTION_SECONDS- сколько хранить завершённые approvalsNEW_QWEN_TAVILY_API_KEY- опциональный Tavily providerNEW_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
- Отправить боту
/auth - Открыть ссылку подтверждения
- Бот сам дождётся завершения OAuth и продолжит работу
Если пользователь отправит обычное сообщение до завершения OAuth, бот поставит его в очередь и автоматически отправит на сервер после успешной авторизации.
Либо можно вызвать API сервера напрямую:
curl -X POST http://127.0.0.1:8080/api/v1/auth/device/start
API
GET /healthGET /api/v1/auth/statusPOST /api/v1/auth/device/startPOST /api/v1/auth/device/pollGET /api/v1/sessionsGET /api/v1/approvalsPOST /api/v1/session/getPOST /api/v1/session/clearPOST /api/v1/chatPOST /api/v1/chat/startPOST /api/v1/chat/pollPOST /api/v1/chat/cancelPOST /api/v1/approval/respond
GET /api/v1/auth/status теперь также показывает:
readyavailable_providersdefault_providerfallback_providers- список
providersс availability и capabilities
Telegram Approval Flow
Если политика инструментов настроена как ask-shell, ask-write или ask-all, бот пришлёт запрос на подтверждение с approval_id.
Дальше можно ответить одной из команд:
/approve <approval_id>/reject <approval_id>
Управление job:
/cancel- отменить активный запрос и очистить очередь сообщений в чате