new-qwen/README.md

130 lines
4.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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`, `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
## Ограничения текущей реализации
- это упрощённая серверная архитектура, а не побайтный порт всего `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
- `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
Бот:
```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>`