125 lines
4.2 KiB
Markdown
125 lines
4.2 KiB
Markdown
# new-qwen
|
||
|
||
Клиент-серверная замена локального агента `qwen-code`.
|
||
|
||
- `serv` отвечает за OAuth, сессии, работу с Qwen LLM и вызов инструментов.
|
||
- `bot` отвечает за Telegram и пересылку сообщений на сервер.
|
||
|
||
Проект написан на Python stdlib, чтобы не зависеть от Node/npm в текущем окружении.
|
||
|
||
## Архитектура
|
||
|
||
```text
|
||
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
|
||
|
||
## Переменные окружения
|
||
|
||
Сервер:
|
||
|
||
```bash
|
||
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
|
||
|
||
Бот:
|
||
|
||
```bash
|
||
cp bot/.env.example bot/.env
|
||
```
|
||
|
||
## Запуск
|
||
|
||
Сервер:
|
||
|
||
```bash
|
||
python3 serv/app.py
|
||
```
|
||
|
||
Бот:
|
||
|
||
```bash
|
||
python3 bot/app.py
|
||
```
|
||
|
||
## Авторизация Qwen OAuth
|
||
|
||
1. Отправить боту `/auth`
|
||
2. Открыть ссылку подтверждения
|
||
3. Бот сам дождётся завершения OAuth и продолжит работу
|
||
|
||
Если пользователь отправит обычное сообщение до завершения OAuth, бот поставит его в очередь и автоматически отправит на сервер после успешной авторизации.
|
||
|
||
Либо можно вызвать API сервера напрямую:
|
||
|
||
```bash
|
||
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>`
|