Proxy API local compatível com OpenAI que roteia requisições para os modelos do Qwen (chat.qwen.ai) via automação de navegador com Playwright. Suporte a múltiplas contas com rotação automática, execução de ferramentas, modo de pensamento (reasoning), persistência de sessão e armazenamento em SQLite.
- OpenAI API Compatible — Interface compatível com
/v1/chat/completions,/v1/modelse/v1/upload. - Multi-Account — Gerencie múltiplas contas Qwen com rotação round-robin e cooldown automático.
- Guest Mode — Modo convidado sem necessidade de login, usando a API pública do Qwen.
- SQLite Storage — Contas salvas em banco de dados SQLite (WAL mode) para performance e confiabilidade.
- Reasoning Support — Suporte completo ao modo de pensamento (thinking) dos modelos Qwen.
- Multimodal Upload — Envio de imagens, vídeos, áudios e documentos via
/v1/uploadcom integração ao OSS do Qwen. - Tool Execution — Sistema de execução de ferramentas locais integrado ao fluxo do chat.
- Session Persistence — Perfil de navegador persistente por conta em
qwen_profiles/. - Auto-Login — Login automático via credenciais com recuperação de sessão.
- Browser Selection — Escolha entre Chromium, Chrome, Firefox, Edge ou WebKit.
- Monitoring — Health check, métricas Prometheus e watchdog integrados.
- CLI Binary — Instale globalmente via npm e use o comando
qwenproxydiretamente. - Docker Ready — Deploy para VPS com Docker, volumes persistentes e graceful shutdown.
graph TD
Client[Cliente OpenAI/SDK] -->|HTTP| Proxy[QwenProxy - Hono]
Proxy -->|/v1/chat/completions| Handler[Chat Handler]
Proxy -->|/v1/models| Models[Models API]
Handler --> AccountMgr[Account Manager]
AccountMgr -->|Round-Robin| Accounts[(SQLite)]
AccountMgr --> Playwright[Playwright Service]
Playwright --> Browser1[Browser - Conta 1]
Playwright --> Browser2[Browser - Conta 2]
Playwright --> BrowserN[Browser - Conta N]
Handler --> QwenAPI[chat.qwen.ai]
Handler --> Tools[Tool Parser]
subgraph "Persistência"
Accounts
Profiles[qwen_profiles/]
end
| Dependência | Versão Mínima | Instalação |
|---|---|---|
| Node.js | v20.x | nvm |
| npm | v9.x | Incluído com Node.js |
| Playwright | - | npx playwright install |
| Docker (opcional) | v24.x | Docker Docs |
npm install -g @pedrofariasx/qwenproxy
npx playwright install
qwenproxygit clone https://github.com/pedrofariasx/qwenproxy.git
cd qwenproxy
npm install
npx playwright installdocker-compose up -dCrie o arquivo .env na raiz do projeto (veja .env.example):
# Porta do servidor (default: 3000)
PORT=3000
# Host do servidor (default: 0.0.0.0)
HOST=0.0.0.0
# Chave de API para proteger os endpoints (opcional)
API_KEY=sua-chave-secreta-aqui
# Credenciais Qwen para login automático (modo single-account)
QWEN_EMAIL=seu-email@exemplo.com
QWEN_PASSWORD=sua-senha-aqui
# Modo convidado - sem login, usa API pública (default: false)
QWEN_GUEST_MODE_ONLY=false
# Navegador (chromium, firefox, chrome, edge, webkit)
BROWSER=chromium
# Executar navegador sem interface gráfica (default: true)
HEADLESS=true
# Timeouts (milissegundos)
NAVIGATION_TIMEOUT=45000
PAGE_TIMEOUT=30000
HTTP_TIMEOUT=30000
HEADERS_TIMEOUT=60000
CHAT_TIMEOUT=120000
STREAM_IDLE_TIMEOUT=180000As contas são armazenadas em SQLite (data/qwenproxy.db). Use o CLI interativo para gerenciar:
# Abrir o gerenciador de contas
npm run login
# Com navegador específico
npm run login:firefox
npm run login:chrome
npm run login:edgeO menu interativo permite:
- [A] Adicionar conta com credenciais (email + senha)
- [M] Adicionar conta via login manual no navegador
- [R] Remover uma conta
- [L] Login em todas as contas (inicializar sessões)
Na primeira execução, se existir um
accounts.jsonantigo, as contas serão migradas automaticamente para SQLite.
npm start # Chromium (padrão)
npm run start:chrome # Google Chrome
npm run start:firefox # Firefox
npm run start:edge # Microsoft EdgeO servidor inicia em http://localhost:3000 com as seguintes rotas:
| Rota | Método | Descrição |
|---|---|---|
/v1/chat/completions |
POST | Chat completions (streaming + non-streaming) |
/v1/chat/completions/stop |
POST | Abortar uma geração ativa |
/v1/models |
GET | Listar modelos disponíveis |
/v1/models/:model |
GET | Informações de um modelo específico |
/v1/upload |
POST | Upload de arquivos multimodais (imagens, vídeos, áudios, documentos) |
/health |
GET | Health check com status do sistema |
/metrics |
GET | Métricas no formato Prometheus |
import OpenAI from 'openai';
const openai = new OpenAI({
baseURL: 'http://localhost:3000/v1',
apiKey: process.env.API_KEY || 'sk-no-key-required'
});
const completion = await openai.chat.completions.create({
model: 'qwen-plus',
messages: [{ role: 'user', content: 'Explique como funciona o Playwright.' }]
});
console.log(completion.choices[0].message.content);curl http://localhost:3000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sua-chave" \
-d '{
"model": "qwen-plus",
"messages": [{"role": "user", "content": "Hello!"}],
"stream": true
}'services:
qwenproxy:
build: .
container_name: qwenproxy
ports:
- "${PORT:-3000}:3000"
env_file:
- .env
volumes:
- qwenproxy_data:/app/data
- qwenproxy_profiles:/app/qwen_profiles
restart: unless-stopped
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
volumes:
qwenproxy_data:
qwenproxy_profiles:| Volume | Conteúdo |
|---|---|
qwenproxy_data |
Banco SQLite com as contas (qwenproxy.db) |
qwenproxy_profiles |
Perfis de navegador por conta (cookies, sessões) |
O container ajusta automaticamente as permissões desses volumes no startup. Se usar bind mounts locais em vez dos volumes nomeados acima, garanta que os diretórios montados sejam graváveis pelo container.
qwenproxy/
├── bin/
│ └── qwenproxy.mjs # Entry point do CLI binário
├── src/
│ ├── index.ts # Entry point do servidor
│ ├── login.ts # CLI de gerenciamento de contas
│ ├── api/
│ │ ├── models.ts # Endpoints /v1/models
│ │ └── server.ts # Servidor Hono + startup
│ ├── cache/
│ │ └── memory-cache.ts # Cache em memória com TTL
│ ├── core/
│ │ ├── account-manager.ts # Rotação round-robin + cooldowns
│ │ ├── accounts.ts # CRUD de contas (SQLite)
│ │ ├── config.ts # Configuração com Zod
│ │ ├── crypto-utils.ts # Criptografia de senhas em repouso
│ │ ├── database.ts # Conexão e migrations SQLite
│ │ ├── logger.ts # Logger estruturado
│ │ ├── metrics.ts # Coleta de métricas Prometheus
│ │ ├── model-registry.ts # Registro de modelos e context windows
│ │ ├── stream-registry.ts # Tracking de streams ativos
│ │ └── watchdog.ts # Health monitoring
│ ├── routes/
│ │ ├── chat.ts # Handler /v1/chat/completions
│ │ ├── sse-parser.ts # Parser incremental de SSE + delta
│ │ ├── stream-handler.ts # Orquestração de streaming SSE
│ │ ├── tool-handler.ts # Execução de tools locais
│ │ └── upload.ts # Handler /v1/upload (multimodal)
│ ├── services/
│ │ ├── browser-manager.ts # Ciclo de vida de browsers/contexts
│ │ ├── error-handler.ts # Tipagem e retry de erros Qwen
│ │ ├── header-interceptor.ts # Captura de cookies/headers via CDP
│ │ ├── playwright.ts # Fachada do serviço Playwright
│ │ ├── qwen.ts # Integração com API do Qwen
│ │ ├── stealth.ts # Script anti-detecção
│ │ ├── stream-bridge.ts # Ponte de stream browser → Node
│ │ ├── stream-creator.ts # Criação de chats e streams Qwen
│ │ └── warm-pool.ts # Pool de chats pré-aquecidos
│ ├── tests/ # Testes automatizados (node:test)
│ ├── tools/
│ │ ├── parser.ts # Parser de <tool_call> tags
│ │ ├── registry.ts # Registro de tools
│ │ ├── schema.ts # Validação JSON Schema
│ │ └── types.ts # Tipos do sistema de tools
│ └── utils/
│ ├── context-truncation.ts # Truncamento de contexto
│ ├── json.ts # Parser JSON robusto
│ ├── qwen-stream-parser.ts # Parser de streams SSE do Qwen
│ └── types.ts # Re-exports de tipos
├── data/ # Banco SQLite (gitignored)
├── qwen_profiles/ # Perfis de navegador por conta (gitignored)
├── Dockerfile
├── docker-compose.yml
├── tsconfig.json
├── tsconfig.build.json
└── package.json
| Problema | Solução |
|---|---|
| Porta em uso | Altere PORT no .env ou encerre o processo na porta 3000 |
| Navegador não abre | Execute npx playwright install |
| Sessão expirada | Execute npm run login para renovar cookies |
| Rate limit em todas as contas | Adicione mais contas via npm run login |
| Banco corrompido | Apague data/qwenproxy.db e re-adicione as contas |
Este projeto é fornecido estritamente para fins educacionais e de pesquisa.
Os autores não incentivam ou endossam:
- Violação dos Termos de Serviço da plataforma Qwen.
- Automação não autorizada em larga escala.
- Uso para atividades maliciosas.
Use por sua conta e risco.