qwenproxy-cli 1.0.31 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.es.md +269 -0
- package/README.md +175 -782
- package/README.pt-BR.md +1033 -0
- package/package.json +4 -4
- package/src/api/server.ts +18 -2
- package/src/core/accounts.ts +130 -0
- package/src/core/config.ts +95 -4
- package/src/index.ts +3 -0
- package/src/routes/chat/context.ts +9 -9
- package/src/routes/chat/index.ts +15 -6
- package/src/services/qwen-chat-pool.ts +4 -5
- package/src/services/qwen.ts +2 -5
- package/src/sync/index.ts +124 -80
- package/src/tui/app.ts +8 -9
- package/src/tui/index.ts +3 -0
- package/src/tui/proxy-client.ts +3 -2
- package/src/tui/screen.ts +10 -3
- package/src/tui/settings.ts +2 -0
- package/src/tui/theme.ts +1 -0
- package/src/tui/types.ts +1 -0
- package/src/tui/views/accounts-view.ts +343 -23
- package/src/tui/views/chat-view.ts +209 -14
- package/src/tui/views/status-view.ts +34 -3
package/README.md
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
|
|
3
2
|
<img src="docs/banner.webp" alt="QwenProxy" width="100%">
|
|
3
|
+
</p>
|
|
4
4
|
|
|
5
|
+
<p align="center">
|
|
6
|
+
<b>English</b> ·
|
|
7
|
+
<a href="README.pt-BR.md">Português</a> ·
|
|
8
|
+
<a href="README.es.md">Español</a>
|
|
5
9
|
</p>
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
High-performance OpenAI- and Anthropic-compatible API gateway that bridges modern AI coding agents and clients (Claude Code CLI, OpenAI Codex, OpenCode, Cursor, OMP, Zed, Grok) to **Qwen (`chat.qwen.ai`)** with multi-account rotation, intelligent failover, robust tool calling, thread-native delta execution, image & video generation, **full OpenAI Responses API with persistent memory**, and durable sessions. Powered by stealth headless Chromium, transient retry ladders, public base/`-fast`/`-thinking` variants, compressed caching, dynamic model capability registry, and full observability.
|
|
8
12
|
|
|
9
13
|
[](https://github.com/johngbl/QwenProxy/actions/workflows/ci.yml)
|
|
10
14
|
[](https://www.npmjs.com/package/qwenproxy-cli)
|
|
@@ -15,48 +19,42 @@ Gateway e API de alta performance compatível com **OpenAI** e **Anthropic** que
|
|
|
15
19
|
[](https://github.com/sponsors/johngbl)
|
|
16
20
|
[](https://ko-fi.com/johngbl)
|
|
17
21
|
|
|
18
|
-
## ❤️
|
|
22
|
+
## ❤️ Support the Project
|
|
19
23
|
|
|
20
|
-
|
|
24
|
+
If **QwenProxy** is helping you or your team and you would like to support continuous maintenance, new client integrations, live probes, and rapid upstream patches, consider voluntary sponsorship:
|
|
21
25
|
|
|
22
|
-
<a href="https://github.com/sponsors/johngbl" target="_blank"><img src="https://img.shields.io/badge/Sponsor%
|
|
26
|
+
<a href="https://github.com/sponsors/johngbl" target="_blank"><img src="https://img.shields.io/badge/Sponsor%20on%20GitHub-ea4aaa?style=for-the-badge&logo=githubsponsors&logoColor=white" alt="GitHub Sponsors"></a> <a href="https://ko-fi.com/johngbl" target="_blank"><img src="https://img.shields.io/badge/Donate%20via%20Ko--fi-ff5e5b?style=for-the-badge&logo=kofi&logoColor=white" alt="Ko-fi"></a>
|
|
23
27
|
|
|
24
|
-
|
|
28
|
+
Every contribution helps cover infrastructure costs, proxy bandwidth, and test accounts!
|
|
25
29
|
|
|
26
30
|
---
|
|
27
31
|
|
|
28
|
-
##
|
|
29
|
-
|
|
30
|
-
- **
|
|
31
|
-
- **
|
|
32
|
-
- **
|
|
33
|
-
- **
|
|
34
|
-
- **
|
|
35
|
-
- **
|
|
36
|
-
- **
|
|
37
|
-
- **
|
|
38
|
-
- **
|
|
39
|
-
- **
|
|
40
|
-
- **
|
|
41
|
-
- **
|
|
42
|
-
- **
|
|
43
|
-
- **Modelos atuais** — catálogo live da família `qwen3.x` (incluindo `qwen3.8-max`) + variantes sintéticas `-fast`/`-thinking` para todos os modelos + registro de capabilities (vision, thinking, modalities)
|
|
44
|
-
- **Thinking nativo** — raciocínio chega via `phase: thinking_summary` do upstream, sem sanitização de tags; o modelo é instruído a nunca emitir `<think>` no conteúdo visível
|
|
45
|
-
- **Observabilidade** — `/health`, `/metrics` (Prometheus), watchdog e logs com emojis.
|
|
46
|
-
- **Deploy simples** — `npm`, Docker e graceful shutdown.
|
|
47
|
-
- **Geração de fotos e vídeos** — `/v1/images/generations` e `/v1/videos/generations` com modelos de ponta (`qwen-image-3.0-pro`, `qwen-image-3.0`, `wan2.7-image-pro`, `wan3.0-video` até 30s 1080P, `z-image-turbo`). Intercepta também pelo chat completions devolvendo Markdown renderizável.
|
|
48
|
-
- **Logs padronizados e unificados** — Exatamente 1 par limpo (`📥 Incoming` e `📤 Request`) por turno em todos os protocolos (`[Chat]`, `[Anthropic]`, `[Responses]`, `[Completions]`).
|
|
32
|
+
## 🚀 Key Features
|
|
33
|
+
|
|
34
|
+
- **Native OpenAI & Anthropic Compatibility** — `/v1/chat/completions`, `/v1/models`, `/v1/messages` (**native Anthropic Messages API** for **Claude Code CLI** and official `@anthropic-ai/sdk`), `/v1/messages/count_tokens`, **OpenAI Responses API** (`/v1/responses`), and `/v1/completions` (legacy adapter).
|
|
35
|
+
- **Full 4-Mode Conversation Matrix** — `thread` (default persistent), `thread-temp` (delta ~1KB ephemeral, recommended for coding agents), `stateless-temp` (OpenAI official stateless standard, ephemeral), and `stateless` (OpenAI official stateless standard, saved to web account).
|
|
36
|
+
- **Real-Time Dynamic Mode Switching** — Switch the global proxy API mode instantly via TUI (`M` on the status screen or `F4` in Chat) or via `/v1/chat/mode` HTTP endpoint, without restarting the server.
|
|
37
|
+
- **Full Terminal Dashboard TUI (`qpx`)** — Interactive monospace UI with full mouse support (hover, click, drag, and scroll), vertical model/mode selectors, and native `QwenProxy` terminal window title.
|
|
38
|
+
- **Batch Account Import (`B`)** — Paste dozens of accounts in seconds (`email:password`, `.env` format, tab, pipe). Stored with at-rest encryption in a single SQLite transaction (<10ms) with deduplication and live count badges.
|
|
39
|
+
- **Dynamic Viewport Scrolling** — Smooth list navigation across 50+ accounts without layout overflow or column misalignment.
|
|
40
|
+
- **1-Click Coding Agent Sync (`qpx sync`)** — Automated setup for Claude Code, OpenAI Codex, OpenCode, Cline, OMP, Zed, Kilo Code, and Hermes with 1-click backup rollback.
|
|
41
|
+
- **Ultra-Light Single Chromium Instance** — 1 shared browser process with hardware WebGL acceleration and isolated `BrowserContext` storage states (~200MB RAM across all accounts, >65% resource reduction).
|
|
42
|
+
- **On-Demand Warmup & Multi-Account Pool** — Boots instantly with the **primary account ready**; standby accounts remain idle and warm up lazily on demand (during failover or rotation).
|
|
43
|
+
- **Clean Personalization Synchronization** — System prompts and tools ride account personalization (`/settings/personalization`), mirroring the official web client and avoiding WAF bot triggers.
|
|
44
|
+
- **Self-Healing Tool Call Parser** — Handles fragmented streams, broken JSON parameters, unified `<qpx_call>` tags, fuzzy name matching (`readFile` → `read_file`), and intelligent auto-retry ladders.
|
|
45
|
+
- **Image & Video Generation** — Dedicated `/v1/images/generations` and `/v1/videos/generations` endpoints with flagship models (`qwen-image-3.0-pro`, `wan3.0-video`, `wan2.7-image-pro`).
|
|
46
|
+
- **Observability & Health Monitoring** — Real-time metrics at `/health`, `/metrics` (Prometheus), RSS watchdog, and unified clean log pairs per turn.
|
|
49
47
|
|
|
50
48
|
---
|
|
51
49
|
|
|
52
|
-
##
|
|
50
|
+
## 🏛️ Architecture
|
|
53
51
|
|
|
54
52
|
```mermaid
|
|
55
53
|
flowchart TD
|
|
56
|
-
Client["
|
|
54
|
+
Client["Client: Claude Code / Codex / OpenCode / Cursor / OMP"] -->|HTTP / SSE| Proxy["QwenProxy - Hono"]
|
|
57
55
|
Proxy --> Chat["/v1/chat/completions"]
|
|
58
56
|
Proxy --> Anthropic["/v1/messages"]
|
|
59
|
-
Proxy --> Completions["/v1/completions (
|
|
57
|
+
Proxy --> Completions["/v1/completions (legacy)"]
|
|
60
58
|
Proxy --> Responses["/v1/responses"]
|
|
61
59
|
Proxy --> Media["/v1/images | /v1/videos"]
|
|
62
60
|
Proxy --> Models["/v1/models"]
|
|
@@ -81,708 +79,204 @@ flowchart TD
|
|
|
81
79
|
|
|
82
80
|
---
|
|
83
81
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
**
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
```bash
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
Modelos e janelas de contexto são sincronizados em tempo real pelo catálogo `/api/models` do Qwen, separadamente para cada conta. O QwenProxy não mantém uma tabela de nomes/capabilities: modelos novos aparecem automaticamente em `/v1/models`, e o objeto `info.meta` recebido do upstream é preservado.
|
|
117
|
-
|
|
118
|
-
Exemplos do catálogo atual (podem mudar sem release do proxy):
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
| Modelo | Contexto | Output máximo | Thinking | Vision |
|
|
122
|
-
| ------------------------- | -------------: | -------------: | :--------: | :------: |
|
|
123
|
-
| `qwen3.8-max` | 1.000.000 | 131.072 | ✅ | ✅ |
|
|
124
|
-
| `qwen3.7-plus` | 1.000.000 | 65.536 | ✅ | ✅ |
|
|
125
|
-
| `qwen3.7-max` | 1.000.000 | 65.536 | ✅ | ❌ |
|
|
126
|
-
| **Fallback desconhecido** | **1.048.576** | **65.536** | — | — |
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
O fallback é usado somente quando a conta ainda não sincronizou o catálogo ou o endpoint upstream está indisponível. Depois da sincronização, contexto, output, thinking, modalidades, `think_skip`, `chat_type`, `mcp`, status ativo e demais metadata vêm do Qwen.
|
|
130
|
-
|
|
131
|
-
> **Nota:** O endpoint `/v1/models` retorna capabilities dinâmicas (formato OpenAI).
|
|
132
|
-
|
|
133
|
-
### Capabilities
|
|
134
|
-
|
|
135
|
-
Cada modelo tem um registro `ModelCapabilities` em `src/core/model-registry.ts`:
|
|
136
|
-
|
|
137
|
-
```ts
|
|
138
|
-
interface ModelCapabilities {
|
|
139
|
-
maxOutputTokens: number;
|
|
140
|
-
maxThinkingTokens: number;
|
|
141
|
-
supportsThinking: boolean;
|
|
142
|
-
supportsVision: boolean;
|
|
143
|
-
canSkipThinking: boolean;
|
|
144
|
-
supportsDocument: boolean;
|
|
145
|
-
supportsAudio: boolean;
|
|
146
|
-
supportsVideo: boolean;
|
|
147
|
-
supportsCitations: boolean;
|
|
148
|
-
supportsCodeExecution: boolean;
|
|
149
|
-
supportsStructuredOutputs: boolean;
|
|
150
|
-
modalities: string[];
|
|
151
|
-
chatTypes: string[];
|
|
152
|
-
mcp: string[];
|
|
153
|
-
isActive: boolean;
|
|
154
|
-
}
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
**Destaque `qwen3.8-max`**: modelo flagship com suporte a visão (o `qwen3.7-max` não suporta). Permite desativar thinking (`canSkipThinking: true`).
|
|
158
|
-
|
|
159
|
-
### Variantes sintéticas
|
|
160
|
-
|
|
161
|
-
- modelo base — modo **Auto** (o Qwen decide se raciocina), ex.: `qwen3.7-plus`
|
|
162
|
-
- `-fast` — Fast com thinking desativado, ex.: `qwen3.7-plus-fast`
|
|
163
|
-
- `-thinking` — Thinking forçado, ex.: `qwen3.7-plus-thinking`
|
|
164
|
-
|
|
165
|
-
As variantes usam a mesma janela de contexto e o mesmo modelo upstream do modelo base; o modo de raciocínio é selecionado pelo `feature_config` do Qwen (Auto/Fast/Thinking). O ID antigo `-no-thinking` não é publicado; é apenas normalizado internamente para `-fast` por compatibilidade legada.
|
|
166
|
-
|
|
167
|
-
### `reasoning_effort` no Chat Completions
|
|
168
|
-
|
|
169
|
-
O campo OpenAI `reasoning_effort` (`none`/`minimal`/`low`/`medium`/`high`/`xhigh`/`max`) também é aceito em `/v1/chat/completions`:
|
|
170
|
-
|
|
171
|
-
- `low`/`none`/`minimal` → força Fast (thinking OFF) quando o modelo **não** tem sufixo
|
|
172
|
-
- `medium`/`high`/`xhigh`/`max` → mantém Auto (o Qwen decide, como hoje)
|
|
173
|
-
- **Precedência:** um sufixo explícito no modelo (`-fast`/`-thinking`) sempre vence o `reasoning_effort`; ausente o campo, comportamento idêntico ao anterior (no-op)
|
|
174
|
-
|
|
175
|
-
---
|
|
176
|
-
|
|
177
|
-
## Responses API (`/v1/responses`)
|
|
178
|
-
|
|
179
|
-
Implementação completa da OpenAI Responses API com extensões para clientes agentic (Codex, Grok CLI, Cursor).
|
|
180
|
-
|
|
181
|
-
### Features
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
| Feature | Descrição |
|
|
185
|
-
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
186
|
-
| **SSE fiel** | `event: <type>` + `data: {...}` com `sequence_number` incremental em todos os eventos |
|
|
187
|
-
| **Memória persistente** | `previous_response_id` com store SQLite durável (sobrevive restarts, TTL 7 dias) |
|
|
188
|
-
| `**last_response_id**` | Retornado em toda response para encadeamento pelo cliente |
|
|
189
|
-
| **Reasoning effort** | `reasoning.effort` aceita qualquer string; normaliza `xhigh`/`max`/`fast`/`none`/numérico para thinking ON/OFF |
|
|
190
|
-
| **Multimodal** | `input_image` → `image_url`, `input_file` → `file_url` no chat interno |
|
|
191
|
-
| **Usage real** | `stream_options.include_usage: true`; upstream sobrescreve estimativas; `input_tokens_details` e `output_tokens_details` **sempre** presentes (fix Grok/serde) |
|
|
192
|
-
| **Reasoning lifecycle** | `reasoning_summary_part.added` → `reasoning_summary_text.delta` → `reasoning_summary_text.done` → `reasoning_summary_part.done` |
|
|
193
|
-
| **Error envelope** | Formato OpenAI: `{ error: { message, type, param, code } }` |
|
|
194
|
-
| **Store** | `store: false` desativa persistência; GET/DELETE `/v1/responses/:id` para recuperar/remover |
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
### Reasoning effort mapping
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
| Client effort | Normalizado | Qwen `feature_config` |
|
|
201
|
-
| ------------------------------------------------------ | ----------- | -------------------------------------------------------------------- |
|
|
202
|
-
| `max`, `high`, `xhigh`, `thinking`, `ultra`, `deep` | high | `thinking_enabled: true`, `thinking_mode: "Thinking"` |
|
|
203
|
-
| `medium`, `med`, `default` | medium | thinking ON (mesmo que high) |
|
|
204
|
-
| `fast`, `none`, `low`, `off`, `minimal`, `no-thinking` | low | `thinking_enabled: false`, `thinking_mode: "Fast"` e modelo `*-fast` |
|
|
205
|
-
| numérico 0–33 | low | thinking OFF |
|
|
206
|
-
| numérico 34–66 | medium | thinking ON |
|
|
207
|
-
| numérico 67–100 | high | thinking ON |
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
> **Nota:** effort `low` sempre seleciona a variante pública `*-fast`; o catálogo pode informar `think_skip`, mas esse metadado não limita a publicação da variante.
|
|
211
|
-
|
|
212
|
-
### Exemplo: Responses API com memória
|
|
213
|
-
|
|
214
|
-
```bash
|
|
215
|
-
# Primeira request
|
|
216
|
-
curl http://localhost:7936/v1/responses \
|
|
217
|
-
-H "Authorization: Bearer local" \
|
|
218
|
-
-H "Content-Type: application/json" \
|
|
219
|
-
-d '{"model":"qwen3.8-max","input":"Meu nome é João","stream":true}'
|
|
220
|
-
|
|
221
|
-
# Resposta inclui last_response_id: "resp_abc123..."
|
|
222
|
-
|
|
223
|
-
# Segunda request com memória
|
|
224
|
-
curl http://localhost:7936/v1/responses \
|
|
225
|
-
-H "Authorization: Bearer local" \
|
|
226
|
-
-H "Content-Type: application/json" \
|
|
227
|
-
-d '{"model":"qwen3.8-max","input":"Qual meu nome?","previous_response_id":"resp_abc123...","stream":true}'
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
### Exemplo: effort com Codex/Grok
|
|
231
|
-
|
|
232
|
-
```bash
|
|
233
|
-
curl http://localhost:7936/v1/responses \
|
|
234
|
-
-H "Authorization: Bearer local" \
|
|
235
|
-
-H "Content-Type: application/json" \
|
|
236
|
-
-d '{"model":"qwen3.7-max","input":"hi","reasoning":{"effort":"xhigh"},"max_output_tokens":30}'
|
|
237
|
-
```
|
|
82
|
+
## 🔄 Conversation Modes
|
|
83
|
+
|
|
84
|
+
QwenProxy provides a complete matrix of **4 conversation modes**, letting you choose the exact balance between token efficiency, latency, and history organization:
|
|
85
|
+
|
|
86
|
+
| Mode | Payload Strategy | Upstream Qwen Mode | Saved to Web Account? | Recommended Use Case |
|
|
87
|
+
| :--- | :--- | :--- | :---: | :--- |
|
|
88
|
+
| **`thread-temp`** ⭐ | **Delta (~1KB)** | `chat_mode: "local"` | ❌ No (Zero pollution) | **The best mode for daily development.** Recommended for Claude Code, Codex, OpenCode, and Cursor. Maximum speed, ultra-low TTFB, and zero sidebar clutter on `chat.qwen.ai`. |
|
|
89
|
+
| **`stateless-temp`** | **Full History** | `chat_mode: "local"` | ❌ No (Zero pollution) | **Official API Standard (OpenAI/Anthropic).** Resends full message history on every turn. Ideal if your client edits, prunes, or re-orders past turns mid-session. |
|
|
90
|
+
| **`thread`** *(Default)* | **Delta (~1KB)** | `chat_mode: "normal"` | ✅ Yes (Saved to web) | Perfect if you want to inspect or continue your agent's conversation later directly inside the official `chat.qwen.ai` mobile app or desktop browser. |
|
|
91
|
+
| **`stateless`** | **Full History** | `chat_mode: "normal"` | ✅ Yes (Saved to web) | Resends full message history on every turn while persisting every chat session into your Qwen account history. |
|
|
92
|
+
|
|
93
|
+
### How to Switch Modes:
|
|
94
|
+
|
|
95
|
+
1. **Via Interactive TUI (Real-Time Global Switch):**
|
|
96
|
+
- **On `[1] Status` screen:** Press **`M`** (or click `[ M ] Alternar Modo`) to cycle the global API mode instantly.
|
|
97
|
+
- **On `[2] Chat` screen:** Press **`F4`** (or click the `[ Modo ]` header button) to open the vertical modal selector.
|
|
98
|
+
2. **Via Remote HTTP Endpoint:**
|
|
99
|
+
```bash
|
|
100
|
+
# Inspect active mode:
|
|
101
|
+
curl http://127.0.0.1:7936/v1/chat/mode
|
|
102
|
+
|
|
103
|
+
# Update mode globally in real time:
|
|
104
|
+
curl -X POST http://127.0.0.1:7936/v1/chat/mode \
|
|
105
|
+
-H "Content-Type: application/json" \
|
|
106
|
+
-d '{"mode":"thread-temp"}'
|
|
107
|
+
```
|
|
108
|
+
3. **Per-Request Header Override:**
|
|
109
|
+
Send `X-QwenProxy-Chat-Mode: thread-temp` (or `stateless-temp`, `thread`, `stateless`) in individual HTTP requests.
|
|
110
|
+
4. **Via `.env` Configuration (Boot Default):**
|
|
111
|
+
```env
|
|
112
|
+
QWEN_CHAT_MODE=thread
|
|
113
|
+
```
|
|
238
114
|
|
|
239
115
|
---
|
|
240
116
|
|
|
241
|
-
##
|
|
242
|
-
|
|
117
|
+
## 📖 Step-by-Step: Getting Started
|
|
243
118
|
|
|
244
|
-
|
|
245
|
-
| ----------- | -------------: | ------------------------------------ |
|
|
246
|
-
| Node.js | 22+ | Conforme `engines` do `package.json` |
|
|
247
|
-
| npm | 9+ | Incluído com Node |
|
|
248
|
-
| Playwright | - | `npx playwright install chromium` |
|
|
249
|
-
| Docker | opcional | Deploy em container |
|
|
119
|
+
### 1. Installation
|
|
250
120
|
|
|
121
|
+
Install the QwenProxy CLI globally on your workstation:
|
|
251
122
|
|
|
252
|
-
---
|
|
253
|
-
|
|
254
|
-
## Instalação e Execução
|
|
255
|
-
|
|
256
|
-
O QwenProxy pode ser instalado globalmente, executado instantaneamente via `npx`/`bunx`, ou clonado localmente:
|
|
257
|
-
|
|
258
|
-
### Opção 1: Instalação Global (Recomendado)
|
|
259
|
-
Instale uma única vez para ter acesso ao comando rápido **`qpx`** de qualquer lugar do terminal:
|
|
260
123
|
```bash
|
|
261
124
|
# Via npm:
|
|
262
125
|
npm install -g qwenproxy-cli
|
|
263
126
|
|
|
264
|
-
#
|
|
127
|
+
# Or via pnpm / bun:
|
|
265
128
|
pnpm add -g qwenproxy-cli
|
|
266
|
-
|
|
267
|
-
# Ou via bun:
|
|
268
|
-
bun add -g qwenproxy-cli
|
|
129
|
+
# bun add -g qwenproxy-cli
|
|
269
130
|
```
|
|
270
|
-
Após instalar, basta abrir o terminal e digitar:
|
|
271
|
-
```bash
|
|
272
|
-
qpx
|
|
273
|
-
# ou: qwenproxy
|
|
274
|
-
```
|
|
275
|
-
*(Abre diretamente o dashboard interativo da TUI com o servidor e proxy integrados).*
|
|
276
|
-
|
|
277
|
-
#### Comandos Rápidos do CLI (`qpx`)
|
|
278
131
|
|
|
279
|
-
|
|
280
|
-
| :--- | :--- |
|
|
281
|
-
| `qpx` *(ou `qwenproxy`)* | Abre o dashboard visual interativo da TUI com servidor proxy integrado |
|
|
282
|
-
| `qpx start` *(ou `--server`)* | Inicia apenas o servidor HTTP/SSE em modo headless (sem interface gráfica) |
|
|
283
|
-
| `qpx update` | Verifica e atualiza o QwenProxy automaticamente via npm/pnpm/bun |
|
|
284
|
-
| `qpx login` | Abre navegador visível para autenticar novas contas interativamente |
|
|
285
|
-
| `qpx sync` | Configura e sincroniza clientes (Claude Code, Codex, OpenCode, OMP) |
|
|
286
|
-
| `qpx clean` | Limpa caches temporários dos perfis Chromium (~4.5MB por conta) |
|
|
287
|
-
| `qpx clean:all` | Limpa caches e remove versões antigas de navegadores órfãos em disco |
|
|
288
|
-
| `qpx purge` | Limpa o histórico de conversas remotas no Qwen de todas as contas |
|
|
289
|
-
| `qpx reset` | Reseta cooldowns e rate limits salvos no banco de dados |
|
|
290
|
-
### Opção 2: Execução Instantânea (Zero Instalação)
|
|
291
|
-
Experimente ou execute pontualmente sem instalar nada permanentemente:
|
|
292
|
-
```bash
|
|
293
|
-
npx qwenproxy-cli
|
|
294
|
-
# ou: bunx qwenproxy-cli
|
|
295
|
-
```
|
|
132
|
+
### 2. Launch the Interactive Dashboard (TUI)
|
|
296
133
|
|
|
297
|
-
|
|
298
|
-
```bash
|
|
299
|
-
git clone https://github.com/johngbl/qwenproxy.git
|
|
300
|
-
cd qwenproxy
|
|
301
|
-
npm install
|
|
302
|
-
npm run tui # Abre a TUI interativa
|
|
303
|
-
# ou: npm start # Inicia apenas o servidor HTTP headless
|
|
304
|
-
```
|
|
134
|
+
Open your terminal and run:
|
|
305
135
|
|
|
306
|
-
### Opção 4: Via Docker
|
|
307
136
|
```bash
|
|
308
|
-
|
|
137
|
+
qpx
|
|
309
138
|
```
|
|
310
|
-
---
|
|
311
139
|
|
|
312
|
-
|
|
140
|
+
QwenProxy launches the high-performance proxy server in the background and opens the interactive dashboard. The terminal window title will automatically update to **`QwenProxy`**.
|
|
313
141
|
|
|
314
|
-
|
|
142
|
+
### 3. Add Qwen Accounts
|
|
315
143
|
|
|
316
|
-
|
|
144
|
+
Inside the TUI, navigate to tab **`[5] Accounts`** to manage credentials:
|
|
317
145
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
HOST=127.0.0.1
|
|
322
|
-
```
|
|
146
|
+
- **Batch Import (`B`):** Press **`B`** (or click `[ B ] Em Lote`). Paste your account credentials in bulk (`email:password` per line, raw `.env` string with commas, or spreadsheet paste). The parser calculates valid accounts in real time, handles special password characters safely, skips duplicates, and commits encrypted credentials to SQLite in a single transaction (<10ms).
|
|
147
|
+
- **Single Account (`A`):** Press **`A`** to manually type email and password.
|
|
148
|
+
- **Browser Login:** If you prefer visual login with manual captcha solving: `qpx login`.
|
|
323
149
|
|
|
324
|
-
|
|
325
|
-
> Senhas com `:`, `#` e espaços são aceitas.
|
|
150
|
+
### 4. Synchronize AI Coding Agents
|
|
326
151
|
|
|
327
|
-
|
|
152
|
+
To automatically configure your installed coding agents to route through QwenProxy:
|
|
328
153
|
|
|
329
154
|
```bash
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
> **Nota:** o servidor não inicia sem pelo menos uma conta configurada (via `.env`/`QWEN_ACCOUNTS`, `npm run login` ou banco de contas).
|
|
334
|
-
|
|
335
|
-
1. O servidor inicia instantaneamente com a **primeira conta pronta** para responder requisições imediatamente.
|
|
336
|
-
2. Com `PLAYWRIGHT_PREPARE_ALL_ON_STARTUP=false` (padrão econômico), as contas adicionais permanecem em **Standby**, com credenciais validadas no banco, sendo inicializadas apenas sob demanda (failover ou rotação), poupando RAM e CPU.
|
|
337
|
-
3. Todas as contas ativas compartilham a mesma instância Chromium única, mantendo sessões isoladas via `BrowserContext` e arquivos leves de estado `storage_state.json`.
|
|
338
|
-
4. O watchdog RSS do sistema monitora a pressão de memória e fecha contextos ociosos automaticamente.
|
|
339
|
-
Exemplo de log:
|
|
340
|
-
|
|
341
|
-
```text
|
|
342
|
-
✅ [Server] Account ready (1/6): us***@example.com
|
|
343
|
-
🪶 [Server] Preparing 5 standby account(s) in background
|
|
344
|
-
✅ [Server] Account ready (2/6): us***@example.com
|
|
345
|
-
...
|
|
346
|
-
|
|
347
|
-
+----------------------------------------------------------+
|
|
348
|
-
| QwenProxy |
|
|
349
|
-
| OpenAI & Anthropic Compatible API |
|
|
350
|
-
| Endpoint http://127.0.0.1:7936/v1 |
|
|
351
|
-
| Accounts 1/6 warm |
|
|
352
|
-
| Status ● Online |
|
|
353
|
-
+----------------------------------------------------------+
|
|
354
|
-
```
|
|
355
|
-
|
|
356
|
-
---
|
|
357
|
-
|
|
358
|
-
## Testes
|
|
155
|
+
# Automatically sync all detected agents:
|
|
156
|
+
qpx sync
|
|
359
157
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
npm run test:mock # suite mock (sem browser real de contas)
|
|
363
|
-
npm run test:live # stress/concurrency reais
|
|
364
|
-
npm run typecheck # tipos
|
|
158
|
+
# Or target specific agents:
|
|
159
|
+
qpx sync claude codex opencode
|
|
365
160
|
```
|
|
366
161
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
| Variável | Default | Descrição |
|
|
375
|
-
| --------- | --------- | -------------------------------- |
|
|
376
|
-
| `PORT` | `7936` | Porta HTTP (padrão QWEN: 7936). Configurável via .env |
|
|
377
|
-
| `HOST` | `0.0.0.0` | Bind host. Local: `127.0.0.1` |
|
|
378
|
-
| `API_KEY` | vazio | Protege `/v1/*` com Bearer token |
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
### Contas e sessão
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
| Variável | Default | Descrição |
|
|
385
|
-
| ----------------------------------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
386
|
-
| `QWEN_ACCOUNTS` | vazio | `email1:senha1;email2:senha2` |
|
|
387
|
-
| `DELETE_ALL_CHATS_ON_SHUTDOWN` | `false` | Limpa chats no shutdown |
|
|
388
|
-
| `QWEN_PERSONALIZATION_FROM_REQUEST` | `true` | Envia system + tools via `/settings/personalization` |
|
|
389
|
-
| `QWEN_PERSONALIZATION_VERIFY_GET` | `true` | Confirma personalization com GET |
|
|
390
|
-
| `QWEN_MAX_PERSONALIZATION_BYTES` | `200000` | Teto UTF-8 para personalization por request; acima disso as instruções seguem inline |
|
|
391
|
-
| `QWEN_CHAT_POOL_SIZE` | `1` | Warm pool de chats por modelo; fica desativado quando personalization por request está ativa |
|
|
392
|
-
| `QWEN_CHAT_POOL_MODELS` | `qwen3.7-plus` | Modelos aquecidos no warm pool |
|
|
393
|
-
| `QWEN_CHAT_MODE` | `thread` | Modo de conversa: `thread` (reutiliza o chat upstream via `parent_id` e envia o delta), `temp-thread` (chat efêmero `chat_mode:"local"` com contexto contínuo, zero poluição no Qwen Web) ou `temp` (stateless padrão OpenAI, novo chat efêmero por requisição). Override por request via header `X-QwenProxy-Chat-Mode: thread/temp/temp-thread` |
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
### Playwright / processos
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
| Variável | Default | Descrição |
|
|
400
|
-
| ------------------------------------------- | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
401
|
-
| `PLAYWRIGHT_HEADLESS` | `true` | Browser sem janela |
|
|
402
|
-
| `PLAYWRIGHT_BROWSER` | `chromium` | `chromium` / `chrome` / `edge` |
|
|
403
|
-
| `PLAYWRIGHT_INIT_BATCH_SIZE` | `1` | Contas em paralelo no background init |
|
|
404
|
-
| `PLAYWRIGHT_PREPARE_ALL_ON_STARTUP` | `false` | Prepara somente a primeira conta no boot (`false` = modo econômico sob demanda; `true` = aquece todas) |
|
|
405
|
-
| `PLAYWRIGHT_MAX_ACTIVE_CONTEXTS` | `2` | Contextos idle mantidos quentes ({principal + reserva}); streams ativos nunca são fechados; uso simultâneo abre mais. Contas em cooldown (rate limit) ficam idle e são evictadas |
|
|
406
|
-
| `PLAYWRIGHT_CONTEXT_CLOSE_TIMEOUT_MS` | `10000` | Timeout de close antes do kill |
|
|
407
|
-
| `PLAYWRIGHT_IDLE_CONTEXT_TTL_MS` | `60000` | Fecha contextos idle acima do cap (`0` desativa) |
|
|
408
|
-
| `PLAYWRIGHT_JS_HEAP_MB` | `256` | Cap V8 do Chromium (`--max-old-space-size`) |
|
|
409
|
-
| `PLAYWRIGHT_LOW_MEMORY_FLAGS` | `true` | Flags de baixa RAM (heap cap, cache mínimo, renderer limit) |
|
|
410
|
-
| `OSS_MULTIPART_THRESHOLD_MB` | `5` | Acima disso usa multipart OSS; abaixo `putStream` |
|
|
411
|
-
| `SESSION_KEEP_ALIVE_ENABLED` | `true` | Simula navegações leves periódicas a cada 3min para manter sessões ativas sem desconectar |
|
|
412
|
-
| `SESSION_KEEP_ALIVE_INTERVAL_MS` | `180000` | Intervalo do ciclo de keep-alive/cleanup |
|
|
413
|
-
| `SESSION_KEEP_ALIVE_IDLE_MS` | `120000` | Idle mínimo para keep-alive |
|
|
414
|
-
| `SESSION_KEEP_ALIVE_NAVIGATION_INTERVAL_MS` | `480000` | Intervalo de navegação leve |
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
### CAPTCHA automático
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
| Variável | Default | Descrição |
|
|
421
|
-
| ------------------------------- | -------- | -------------------------------------------------------------------------------------- |
|
|
422
|
-
| `CAPTCHA_SOLVER_ENABLED` | `true` | Solver Baxia/TMD ativo por padrão; use `false` somente como desligamento de emergência |
|
|
423
|
-
| `CAPTCHA_SOLVER_MAX_ATTEMPTS` | `3` | Máximo de arrastos por challenge |
|
|
424
|
-
| `CAPTCHA_SOLVER_TIMEOUT_MS` | `15000` | Tempo para o iframe Baxia aparecer |
|
|
425
|
-
| `CAPTCHA_SOLVER_RETRY_DELAY_MS` | `1000` | Espera entre tentativas do slider |
|
|
426
|
-
| `CAPTCHA_SOLVER_SETTLE_MS` | `2000` | Tempo para confirmar cookies/DOM após o arrasto |
|
|
427
|
-
| `CAPTCHA_ACCOUNT_COOLDOWN_MS` | `120000` | Cooldown da conta quando o desafio não pôde ser resolvido; `0` desliga |
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
### Headers anti-bot
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
| Variável | Default | Descrição |
|
|
434
|
-
| ----------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------- |
|
|
435
|
-
| `USER_AGENT` | Chrome 149 Windows | UA fallback |
|
|
436
|
-
| `QWEN_BX_V` | `2.5.37` | `bx-v` fallback; `bx-ua`/`bx-umidtoken` **não** são enviados como headers (o cliente real os carrega como cookies WAF) |
|
|
437
|
-
| `QWEN_SEND_BX_UA` | `false` | `true` restaura o comportamento legado de injetar `bx-ua`/`bx-umidtoken` capturados como headers |
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
Fingerprint estável por conta (UA, locale, viewport, hardware/WebGL) é aplicado automaticamente.
|
|
441
|
-
|
|
442
|
-
### Delays e retry
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
| Variável | Default | Descrição |
|
|
446
|
-
| ----------------------------------- | -------- | ------------------------------------------------------------------------------------------------ |
|
|
447
|
-
| `RETRY_BASE_DELAY_MS` | `1000` | Base do exponential backoff |
|
|
448
|
-
| `RETRY_MAX_DELAY_MS` | `10000` | Cap do backoff |
|
|
449
|
-
| `RETRY_MAX_ATTEMPTS` | `3` | Tentativas por request (create-stream + mid-stream) |
|
|
450
|
-
| `RETRY_MAX_ACCOUNT_SWITCHES` | `2` | Máximo de trocas de conta por request |
|
|
451
|
-
| `RETRY_ON_UNKNOWN_UPSTREAM` | `true` | Retry/troca automática em erros upstream desconhecidos (denylist só para erros locais terminais) |
|
|
452
|
-
| `RETRY_AUTO_MALFORMED_TOOLS` | `true` | Auto-retry quando todos os tool calls da resposta vêm malformados |
|
|
453
|
-
| `RETRY_AUTO_MALFORMED_TOOLS_MAX` | `2` | Máximo de retries de tool calls malformados por resposta |
|
|
454
|
-
| `MAX_TOOL_CALLS_PER_TURN` | `8` | Teto de tool calls por turno (0 desativa); calls duplicadas idênticas também são descartadas |
|
|
455
|
-
| `CHAT_IN_PROGRESS_RETRY_DELAY_MS` | `2000` | Espera antes de repetir no mesmo chat após `chat_in_progress` |
|
|
456
|
-
| `CHAT_IN_PROGRESS_BUSY_MS` | `4000` | Janela busy da conta após `chat_in_progress` (absorve o settle do upstream) |
|
|
457
|
-
| `MID_STREAM_FAILOVER_THRESHOLD` | `2` | Falhas de rede mid-stream nesta janela marcam a conta temporarily busy |
|
|
458
|
-
| `MID_STREAM_FAILOVER_BUSY_MS` | `60000` | Duração do busy após o threshold mid-stream |
|
|
459
|
-
| `ACQUIRE_DEADLINE_MS` | `120000` | Deadline por tentativa de acquire do stream (falha visível → troca de conta) |
|
|
460
|
-
| `ACCOUNT_QUEUE_WAIT_FOREVER_CAP_MS` | `120000` | Cap de espera na fila "sem deadline" de contas |
|
|
461
|
-
| `ACCOUNT_LEASE_MAX_DURATION_MS` | `600000` | Vida máxima de uma lease de conta |
|
|
462
|
-
| `ACCOUNT_INIT_FAILURE_COOLDOWN_MS` | `300000` | Cooldown após falha de init de conta |
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
### Timeouts
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
| Variável | Default | Descrição |
|
|
469
|
-
| -------------------------- | -------- | ------------------------------------------------------------------------------------------------ |
|
|
470
|
-
| `HTTP_TIMEOUT` | `10000` | HTTP genérico |
|
|
471
|
-
| `CHAT_TIMEOUT` | `120000` | Timeout de chat |
|
|
472
|
-
| `NAVIGATION_TIMEOUT` | `60000` | Navegação Playwright |
|
|
473
|
-
| `PAGE_TIMEOUT` | `60000` | Operações de página |
|
|
474
|
-
| `HEADERS_TIMEOUT` | `60000` | Captura de headers |
|
|
475
|
-
| `TIME_TO_FIRST_BYTE` | `60000` | Janela de primeiro byte (teto com piso de 15s no metadata) |
|
|
476
|
-
| `IDLE_STREAM_TIMEOUT` | `60000` | Stream sem dados (modelos não-reasoning) |
|
|
477
|
-
| `TOTAL_REQUEST_TIMEOUT` | `600000` | Teto de geração |
|
|
478
|
-
| `REASONING_MODEL_TIMEOUT` | `180000` | Silêncio mid-stream para modelos reasoning (chunks fluidos resetam; zero bytes por 3min = morto) |
|
|
479
|
-
| `QWEN_FIRST_CHUNK_TIMEOUT` | `180000` | Deadline do PRIMEIRO chunk (thought = 0 bytes por 3min aborta retryável) |
|
|
162
|
+
The synchronizer configures:
|
|
163
|
+
- **Claude Code CLI** (`~/.claude/settings.json`) — Native Anthropic protocol (`/v1/messages`).
|
|
164
|
+
- **OpenAI Codex CLI** (`~/.codex/config.toml`) — Native Responses protocol (`/v1/responses`).
|
|
165
|
+
- **OpenCode** (`~/.config/opencode/opencode.jsonc`) — OpenAI-compatible provider.
|
|
166
|
+
- **Cline, OMP, Zed, Kilo Code, and Hermes Agent**.
|
|
480
167
|
|
|
168
|
+
> **Rollback tip:** Restore previous client configuration backups anytime with `qpx sync -- --restore`.
|
|
481
169
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
### Cache e contexto
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
| Variável | Default | Descrição |
|
|
488
|
-
| ----------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------- |
|
|
489
|
-
| `CACHE_TTL` | `3600` | TTL do cache (s) |
|
|
490
|
-
| `CACHE_COMPRESSION_ENABLED` | `true` | Compressão Brotli |
|
|
491
|
-
| `QWEN_MAX_PROMPT_BYTES` | `0` | Teto opcional local UTF-8 do prompt (`0` desativa); não é a janela de tokens. O payload total continua limitado a 50 MiB |
|
|
492
|
-
| `CONTEXT_METER_ENABLED` | `true` | Medição do histórico completo, delta/replay, payload Qwen e percentuais de contexto; já vem ativa por padrão |
|
|
493
|
-
| `CONTEXT_METER_WINDOW_TOKENS` | `0` | Janela usada pelo medidor (`0` usa a janela real registrada para o modelo) |
|
|
494
|
-
| `CONTEXT_METER_REPORT_USAGE` | `true` | Reporta em `usage.prompt_tokens` o valor real `input_tokens` do Qwen quando disponível; só usa a estimativa como fallback |
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
O medidor de contexto é padrão e não exige nenhuma variável no `.env`. Ele não é um tokenizer nativo do Zed/Cline nem substitui o tokenizer privado do Qwen: calcula uma estimativa local do histórico completo recebido pelo proxy, registra o prompt delta/replay efetivamente enviado e preserva `usage.context_meter` com `measurementSource=qwen` quando o Qwen devolve `input_tokens`, ou `measurementSource=local_estimate` quando não devolve. A janela do modelo é sincronizada automaticamente pelo `/api/models`, e são emitidos headers `X-QwenProxy-Context-*` e logs estruturados. As três variáveis podem ser usadas somente como overrides avançados; por padrão o valor real do Qwen é preferido e a estimativa só é fallback.
|
|
498
|
-
|
|
499
|
-
### Observabilidade
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
| Variável | Default | Descrição |
|
|
503
|
-
| --------------------- | -------- | ------------------------------------------------------------------------------- |
|
|
504
|
-
| `CHAT_REQUEST_LOG` | `false` | Logs detalhados de request |
|
|
505
|
-
| `LOG_LEVEL` | `warn` | Nível do logger (`debug`/`info`/`warn`/`error`); `TOOLCALL_DEBUG=1` força debug |
|
|
506
|
-
| `METRICS_INTERVAL` | `10000` | Intervalo de métricas |
|
|
507
|
-
| `WATCHDOG_INTERVAL` | `5000` | Intervalo do watchdog |
|
|
508
|
-
| `RAM_WARNING` | `80` | % RSS warning (RSS / totalmem) |
|
|
509
|
-
| `RAM_CRITICAL` | `95` | % RSS critical (RSS / totalmem) |
|
|
510
|
-
| `RATE_LIMIT_REQUESTS` | `5000` | Header estático `x-ratelimit-limit-requests` (não impõe quota) |
|
|
511
|
-
| `RATE_LIMIT_TOKENS` | `200000` | Header estático `x-ratelimit-limit-tokens` (não impõe quota) |
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
---
|
|
515
|
-
|
|
516
|
-
## Retries e resiliência
|
|
517
|
-
|
|
518
|
-
O proxy tenta recuperar erros transitórios sem quebrar thread-native/tools:
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
| Situação | Comportamento |
|
|
522
|
-
| ------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
523
|
-
| `502` / `503` / `504` | Retry com delay curto |
|
|
524
|
-
| `fetch failed`, `ECONNREFUSED`, `ETIMEDOUT`, `ENOTFOUND` | Retry de rede |
|
|
525
|
-
| Anti-bot (`FAIL_SYS_USER_VALIDATE`, captcha, WAF HTML, etc.) | Com solver Baxia habilitado: preserva a página, tenta resolver uma vez, atualiza headers e repete na mesma conta; sem solver, mantém o retry simples |
|
|
526
|
-
| Quota / rate limit | Cooldown categorizado (`RateLimited`, `RateLimitTemporary`, …) |
|
|
527
|
-
| `invalid_input` (“entrada ou anexo inválido”) | Retry forçando **novo chat** + contexto completo |
|
|
528
|
-
| Chat not exist / session stale | Força novo chat na sessão lógica |
|
|
529
|
-
| Tool calls malformados (todos inválidos) | Reparo local do JSON; se não resolver, auto-retry na mesma conta com novo chat e correção enviada ao modelo (até `RETRY_AUTO_MALFORMED_TOOLS_MAX`) |
|
|
530
|
-
| `INVALID_FIRST_MSG` / histórico corrompido | Novo chat + contexto completo na **mesma conta** (a corrupção é da cadeia de parent, não da conta); o thread lógico contaminado é invalidado |
|
|
170
|
+
### 5. Start Coding!
|
|
531
171
|
|
|
172
|
+
Launch your favorite coding tool as you normally would:
|
|
173
|
+
```bash
|
|
174
|
+
# Run Claude Code:
|
|
175
|
+
claude
|
|
532
176
|
|
|
533
|
-
|
|
177
|
+
# Run Codex CLI:
|
|
178
|
+
codex
|
|
534
179
|
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
"ui": { "autoTags": false, "largeTextAsFile": false, "splitLargeChunks": false },
|
|
538
|
-
"mcp_remind": false,
|
|
539
|
-
"memory": { "enable_memory": false, "enable_history_memory": false },
|
|
540
|
-
"tools_enabled": { "web_search": false, "code_interpreter": false }
|
|
541
|
-
}
|
|
180
|
+
# Run OpenCode:
|
|
181
|
+
opencode
|
|
542
182
|
```
|
|
183
|
+
All completions and tool calls will flow through your local QwenProxy gateway with zero external API fees, high context windows, and automatic multi-account rotation!
|
|
543
184
|
|
|
544
185
|
---
|
|
545
186
|
|
|
546
|
-
##
|
|
547
|
-
|
|
548
|
-
Detecta, entre outros:
|
|
549
|
-
|
|
550
|
-
- `FAIL_SYS_USER_VALIDATE`
|
|
551
|
-
- `RGV587_ERROR`
|
|
552
|
-
- mensagens de captcha / human verification
|
|
553
|
-
|
|
554
|
-
**Fluxo:**
|
|
555
|
-
|
|
556
|
-
1. Identifica o WAF/captcha sem expor o HTML do desafio ao cliente
|
|
557
|
-
2. Se `CAPTCHA_SOLVER_ENABLED=true`, detecta o diálogo Baxia já visível e procura o iframe aninhado, o iframe legado ou o documento NC diretamente na página da mesma conta
|
|
558
|
-
3. Se nada estiver visível — o caso normal, porque o completion roda como `fetch` em background e o WAF responde o documento de punish ao XHR em vez de renderizar algo — extrai a URL do desafio do corpo da resposta e abre essa URL na própria página da conta; sem URL utilizável, recarrega a página de chat para forçar o desafio a aparecer. Só a origem configurada em `QWEN_BASE_URL` pode ser aberta
|
|
559
|
-
4. Executa o slider com limite de tentativas e volta a página para `/c/new-chat`
|
|
560
|
-
5. Após sucesso, captura novamente cookies/headers e repete a requisição original na mesma conta
|
|
561
|
-
6. Se o solver falhar, a conta entra em cooldown por `CAPTCHA_ACCOUNT_COOLDOWN_MS` e a requisição é encaminhada para **uma** outra conta; percorrer o pool inteiro apenas faria o WAF desafiar todas as contas
|
|
562
|
-
7. Uma recuperação que falhou é ignorada por 30s na mesma conta, para o retry loop não gastar o orçamento do solver em cada tentativa
|
|
563
|
-
|
|
564
|
-
Com Playwright, cada conta usa fingerprint e headers capturados do browser real.
|
|
565
|
-
|
|
566
|
-
O solver Baxia/TMD fica ativo por padrão e cobre o slider NC visível em iframe ou documento direto. O proxy não salva HTML, screenshot, cookies ou tokens do challenge; desafios não suportados continuam no fluxo sanitizado de retry na mesma conta.
|
|
567
|
-
|
|
568
|
-
---
|
|
569
|
-
|
|
570
|
-
## Compatibilidade real das rotas
|
|
571
|
-
|
|
572
|
-
O README descreve o uso operacional. Para detalhes técnicos da API (schemas, exemplos, headers), veja:
|
|
573
|
-
|
|
574
|
-
- [`docs/openapi.yaml`](docs/openapi.yaml) — OpenAPI 3.1 spec com todas as rotas (Chat, Completions, Responses, Models, Upload, Health)
|
|
575
|
-
|
|
576
|
-
> **Nota:** A spec OpenAPI é mantida atualizada com as mudanças recentes (auth Bearer + x-api-key, health heap detalhado).
|
|
577
|
-
|
|
578
|
-
---
|
|
579
|
-
|
|
580
|
-
## Endpoints
|
|
581
|
-
|
|
582
|
-
### OpenAI Compatible
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
| Rota | Método | Descrição |
|
|
586
|
-
| --------------------------- | ------ | ----------------------------------------- |
|
|
587
|
-
| `/v1/chat/completions` | POST | Chat completions (stream + non-stream) |
|
|
588
|
-
| `/v1/completions` | POST | Completions legado (adapter sobre o chat) |
|
|
589
|
-
| `/v1/chat/completions/stop` | POST | Abortar geração |
|
|
590
|
-
| `/v1/models` | GET | Listar modelos |
|
|
591
|
-
| `/v1/models/:id` | GET | Modelo específico |
|
|
592
|
-
| `/v1/responses` | POST | OpenAI Responses API |
|
|
593
|
-
| `/v1/responses/:id` | GET | Recuperar response armazenada |
|
|
594
|
-
| `/v1/responses/:id` | DELETE | Deletar response |
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
### Anthropic Compatible (Claude Code CLI / Anthropic SDK)
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
| Rota | Método | Descrição |
|
|
601
|
-
| --------------------------- | ------ | ------------------------------------------------------------- |
|
|
602
|
-
| `/v1/messages` | POST | Anthropic Messages API (stream, thinking, tools, Claude Code) |
|
|
603
|
-
| `/v1/messages/count_tokens` | POST | Contagem de tokens compatível com Anthropic |
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
### Geração de Mídia (Fotos e Vídeos)
|
|
187
|
+
## 💡 Production Tips & Best Practices
|
|
607
188
|
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
### Utilidades
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
| Rota | Método | Descrição |
|
|
620
|
-
| ------------ | ------ | ------------------------------------------------- |
|
|
621
|
-
| `/health` | GET | Health check |
|
|
622
|
-
| `/metrics` | GET | Prometheus (protegido por API key se configurada) |
|
|
623
|
-
| `/v1/upload` | POST | Upload multimodal |
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
> Rotas sem o prefixo `/v1` (ex.: `/chat/completions`) são redirecionadas com 308 preservando método e corpo. Respostas incluem headers OpenAI (`openai-version`, `openai-processing-ms`, `x-ratelimit-*`).
|
|
189
|
+
1. **Use `thread-temp` for Agentic Coding Work:**
|
|
190
|
+
Coding agents generate dozens of turns and tool calls per minute. Running in `thread-temp` keeps your Qwen account clean while delivering blazing-fast ~0.6s–1.2s TTFB.
|
|
191
|
+
2. **Multi-Account Quota Reset (00:00 UTC):**
|
|
192
|
+
Configure 2 or more accounts. Qwen Web daily quotas reset strictly at **00:00 UTC**. When an account reaches its limit, the proxy parks it until midnight and seamlessly promotes the next healthy standby account.
|
|
193
|
+
3. **Profile Disk Pruning (`qpx clean`):**
|
|
194
|
+
Over time, Chromium contexts accumulate transient V8 and GPU caches. Run `qpx clean` to shrink profiles from ~300MB down to **~4.5MB per account**, while preserving cookies and authenticated sessions intact.
|
|
195
|
+
4. **Instant Cooldown Reset:**
|
|
196
|
+
To immediately unpark accounts on cooldown, press **`Z`** on the `[1] Status` screen or run `qpx reset`.
|
|
627
197
|
|
|
628
198
|
---
|
|
629
199
|
|
|
630
|
-
##
|
|
631
|
-
|
|
632
|
-
### OpenAI SDK (Node.js)
|
|
633
|
-
|
|
634
|
-
```typescript
|
|
635
|
-
import OpenAI from "openai";
|
|
636
|
-
|
|
637
|
-
const client = new OpenAI({
|
|
638
|
-
baseURL: "http://localhost:7936/v1",
|
|
639
|
-
apiKey: "sua-api-key",
|
|
640
|
-
});
|
|
641
|
-
|
|
642
|
-
const completion = await client.chat.completions.create({
|
|
643
|
-
model: "qwen3.7-plus",
|
|
644
|
-
messages: [{ role: "user", content: "Hello!" }],
|
|
645
|
-
});
|
|
646
|
-
|
|
647
|
-
console.log(completion.choices[0].message.content);
|
|
648
|
-
```
|
|
649
|
-
|
|
650
|
-
### Anthropic SDK / Claude Code CLI
|
|
200
|
+
## 📦 Models & Capabilities
|
|
651
201
|
|
|
652
|
-
|
|
202
|
+
Models and context windows are synchronized dynamically from Qwen's live `/api/models` catalog per account. Capabilities and metadata are resolved automatically:
|
|
653
203
|
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
claude
|
|
661
|
-
```
|
|
662
|
-
|
|
663
|
-
```typescript
|
|
664
|
-
import Anthropic from "@anthropic-ai/sdk";
|
|
665
|
-
|
|
666
|
-
const anthropic = new Anthropic({
|
|
667
|
-
baseURL: "http://localhost:7936",
|
|
668
|
-
apiKey: "sua-api-key",
|
|
669
|
-
});
|
|
670
|
-
|
|
671
|
-
const message = await anthropic.messages.create({
|
|
672
|
-
model: "claude-3-7-sonnet-20250219", // ou "qwen3.8-max"
|
|
673
|
-
max_tokens: 1024,
|
|
674
|
-
messages: [{ role: "user", content: "Olá!" }],
|
|
675
|
-
});
|
|
676
|
-
|
|
677
|
-
console.log(message.content[0]);
|
|
678
|
-
```
|
|
679
|
-
|
|
680
|
-
### OpenAI Responses API (Codex / Grok CLI)
|
|
681
|
-
|
|
682
|
-
```typescript
|
|
683
|
-
import OpenAI from "openai";
|
|
684
|
-
|
|
685
|
-
const client = new OpenAI({
|
|
686
|
-
baseURL: "http://localhost:7936/v1",
|
|
687
|
-
apiKey: "sua-api-key",
|
|
688
|
-
});
|
|
689
|
-
|
|
690
|
-
// Streaming com reasoning effort
|
|
691
|
-
const stream = await client.responses.create({
|
|
692
|
-
model: "qwen3.8-max",
|
|
693
|
-
input: "Explique computação quântica",
|
|
694
|
-
reasoning: { effort: "high" },
|
|
695
|
-
stream: true,
|
|
696
|
-
});
|
|
697
|
-
|
|
698
|
-
for await (const event of stream) {
|
|
699
|
-
if (event.type === "response.output_text.delta") {
|
|
700
|
-
process.stdout.write(event.delta);
|
|
701
|
-
}
|
|
702
|
-
}
|
|
703
|
-
```
|
|
704
|
-
|
|
705
|
-
### Geração de Imagens (`/v1/images/generations`)
|
|
706
|
-
|
|
707
|
-
```bash
|
|
708
|
-
curl http://localhost:7936/v1/images/generations \
|
|
709
|
-
-H "Content-Type: application/json" \
|
|
710
|
-
-H "Authorization: Bearer sua-api-key" \
|
|
711
|
-
-d '{
|
|
712
|
-
"model": "qwen-image-3.0-pro",
|
|
713
|
-
"prompt": "A futuristic cyberpunk city in the rain, ultra-detailed, cinematic lighting",
|
|
714
|
-
"size": "16:9"
|
|
715
|
-
}'
|
|
716
|
-
```
|
|
717
|
-
|
|
718
|
-
### Geração de Vídeos (`/v1/videos/generations`)
|
|
719
|
-
|
|
720
|
-
```bash
|
|
721
|
-
curl http://localhost:7936/v1/videos/generations \
|
|
722
|
-
-H "Content-Type: application/json" \
|
|
723
|
-
-H "Authorization: Bearer sua-api-key" \
|
|
724
|
-
-d '{
|
|
725
|
-
"model": "wan3.0-video",
|
|
726
|
-
"prompt": "Drone shot flying over a misty pine forest at sunrise",
|
|
727
|
-
"size": "16:9",
|
|
728
|
-
"wait": true
|
|
729
|
-
}'
|
|
730
|
-
```
|
|
731
|
-
|
|
732
|
-
---
|
|
204
|
+
| Model | Context Window | Max Output | Thinking | Vision |
|
|
205
|
+
| :--- | :---: | :---: | :---: | :---: |
|
|
206
|
+
| `qwen3.8-max` | 1,000,000 | 131,072 | ✅ Yes | ✅ Yes |
|
|
207
|
+
| `qwen3.7-plus` | 1,000,000 | 65,536 | ✅ Yes | ✅ Yes |
|
|
208
|
+
| `qwen3.7-max` | 1,000,000 | 65,536 | ✅ Yes | ❌ No |
|
|
209
|
+
| **Fallback** | **1,048,576** | **65,536** | — | — |
|
|
733
210
|
|
|
734
|
-
###
|
|
211
|
+
### Synthetic Variants
|
|
735
212
|
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
-H "Authorization: Bearer sua-api-key" \
|
|
740
|
-
-d '{
|
|
741
|
-
"model": "qwen3.7-plus",
|
|
742
|
-
"messages": [{"role": "user", "content": "Hello!"}],
|
|
743
|
-
"stream": true
|
|
744
|
-
}'
|
|
745
|
-
```
|
|
213
|
+
- Base Model — **Auto mode** (Qwen decides whether to reason), e.g.: `qwen3.8-max`
|
|
214
|
+
- `-fast` — Thinking disabled for rapid generation, e.g.: `qwen3.8-max-fast`
|
|
215
|
+
- `-thinking` — Thinking forced ON, e.g.: `qwen3.8-max-thinking`
|
|
746
216
|
|
|
747
|
-
###
|
|
217
|
+
### `reasoning_effort` Parameter
|
|
748
218
|
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
base_url = "http://127.0.0.1:7936/v1"
|
|
753
|
-
```
|
|
219
|
+
Standard OpenAI `reasoning_effort` values (`low`, `medium`, `high`) are supported:
|
|
220
|
+
- `low` / `none` → forces Fast mode (thinking OFF).
|
|
221
|
+
- `medium` / `high` / `max` → enables thinking.
|
|
754
222
|
|
|
755
223
|
---
|
|
756
224
|
|
|
757
|
-
##
|
|
758
|
-
|
|
759
|
-
O parser suporta:
|
|
225
|
+
## 🌐 Supported Endpoints
|
|
760
226
|
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
227
|
+
### OpenAI Compatible
|
|
228
|
+
| Endpoint | Method | Description |
|
|
229
|
+
| :--- | :---: | :--- |
|
|
230
|
+
| `/v1/chat/completions` | POST | Chat completions (streaming & non-streaming) |
|
|
231
|
+
| `/v1/chat/completions/stop` | POST | Abort an active generation |
|
|
232
|
+
| `/v1/chat/mode` | GET / POST | Inspect or update the global conversation mode in real time |
|
|
233
|
+
| `/v1/models` | GET | List available models and capabilities |
|
|
234
|
+
| `/v1/models/:id` | GET | Model details |
|
|
235
|
+
| `/v1/responses` | POST | Full OpenAI Responses API with persistent memory |
|
|
236
|
+
| `/v1/responses/:id` | GET / DELETE | Retrieve or delete stored response context |
|
|
237
|
+
| `/v1/completions` | POST | Legacy completions adapter |
|
|
238
|
+
|
|
239
|
+
### Anthropic Compatible
|
|
240
|
+
| Endpoint | Method | Description |
|
|
241
|
+
| :--- | :---: | :--- |
|
|
242
|
+
| `/v1/messages` | POST | Native Anthropic Messages API (Claude Code CLI, SDK) |
|
|
243
|
+
| `/v1/messages/count_tokens` | POST | Token counting endpoint |
|
|
244
|
+
|
|
245
|
+
### Media Generation (Images & Videos)
|
|
246
|
+
| Endpoint | Method | Description |
|
|
247
|
+
| :--- | :---: | :--- |
|
|
248
|
+
| `/v1/images/generations` | POST | Image generation (`qwen-image-3.0-pro`, `wan2.7-image-pro`) |
|
|
249
|
+
| `/v1/videos/generations` | POST | Video generation (`wan3.0-video` up to 1080P, `wan2.7-t2v`) |
|
|
250
|
+
| `/v1/tasks/status/:taskId` | GET | Check asynchronous video task progress |
|
|
251
|
+
|
|
252
|
+
### Diagnostics & Monitoring
|
|
253
|
+
| Endpoint | Method | Description |
|
|
254
|
+
| :--- | :---: | :--- |
|
|
255
|
+
| `/health` | GET | System health check and active stream metrics |
|
|
256
|
+
| `/metrics` | GET | Prometheus exposition |
|
|
257
|
+
| `/v1/upload` | POST | Multimodal asset upload |
|
|
771
258
|
|
|
772
259
|
---
|
|
773
260
|
|
|
774
|
-
##
|
|
775
|
-
|
|
776
|
-
O proxy envia o id do modelo ao Qwen **como está**. Apenas os sufixos de raciocínio são normalizados antes de subir (via `stripThinkingSuffix`):
|
|
261
|
+
## 🛠️ CLI Commands & NPM Scripts
|
|
777
262
|
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
263
|
+
| Command | Description |
|
|
264
|
+
| :--- | :--- |
|
|
265
|
+
| `qpx` *(or `npm run tui`)* | Open interactive TUI dashboard with integrated server |
|
|
266
|
+
| `qpx start` *(or `npm start`)* | Start headless proxy server (no UI) |
|
|
267
|
+
| `qpx sync` *(or `npm run sync`)* | Auto-configure coding agents (Claude Code, Codex, OpenCode, Cline, OMP) |
|
|
268
|
+
| `qpx clean` | Prune transient Chromium profile caches (~4.5MB per account) |
|
|
269
|
+
| `qpx clean:all` | Reclaim disk space from obsolete browser downloads (~4GB) |
|
|
270
|
+
| `qpx reset` | Reset rate-limit and error cooldowns in database |
|
|
271
|
+
| `qpx login` | Authenticate new accounts via visible browser |
|
|
272
|
+
| `qpx purge` | Delete remote chat history across configured accounts |
|
|
273
|
+
| `qpx update` | Automatically update QwenProxy to the latest version |
|
|
274
|
+
| `npm test` | Run complete test suite (mock & live suites) |
|
|
275
|
+
| `npm run typecheck` | Strict TypeScript verification (0 errors required) |
|
|
782
276
|
|
|
783
277
|
---
|
|
784
278
|
|
|
785
|
-
##
|
|
279
|
+
## 🐳 Docker Deployment
|
|
786
280
|
|
|
787
281
|
```yaml
|
|
788
282
|
services:
|
|
@@ -796,6 +290,7 @@ services:
|
|
|
796
290
|
volumes:
|
|
797
291
|
- ./data:/app/data
|
|
798
292
|
restart: unless-stopped
|
|
293
|
+
shm_size: "2gb"
|
|
799
294
|
logging:
|
|
800
295
|
driver: "json-file"
|
|
801
296
|
options:
|
|
@@ -803,116 +298,14 @@ services:
|
|
|
803
298
|
max-file: "3"
|
|
804
299
|
```
|
|
805
300
|
|
|
806
|
-
O container ajusta permissões de `data/db` e `data/qwen_profiles` no startup.
|
|
807
|
-
|
|
808
|
-
---
|
|
809
|
-
|
|
810
|
-
## Estrutura do projeto
|
|
811
|
-
|
|
812
|
-
```
|
|
813
|
-
QwenProxy/
|
|
814
|
-
├── src/
|
|
815
|
-
│ ├── api/ # Server Hono, models, errors
|
|
816
|
-
│ ├── benchmarks/ # Baseline de latência do proxy
|
|
817
|
-
│ ├── cache/ # Memory cache + Brotli
|
|
818
|
-
│ ├── core/ # Config, accounts, DB, metrics, cooldowns, model-registry
|
|
819
|
-
│ ├── routes/
|
|
820
|
-
│ │ ├── chat/ # Completions, streaming, account acquire, retry-policy
|
|
821
|
-
│ │ └── responses/ # OpenAI Responses API (state, streaming, adapter)
|
|
822
|
-
│ ├── services/
|
|
823
|
-
│ │ ├── playwright.ts # Browser + headers + cleanup
|
|
824
|
-
│ │ ├── qwen.ts # Upstream Qwen + personalization + idle timeout
|
|
825
|
-
│ │ ├── session-keeper.ts
|
|
826
|
-
│ │ ├── fingerprint.ts
|
|
827
|
-
│ │ └── human-behavior.ts
|
|
828
|
-
│ ├── tools/ # Parser e instruções de tools
|
|
829
|
-
│ ├── tests/
|
|
830
|
-
│ └── utils/
|
|
831
|
-
├── data/ # SQLite, key e profiles (gitignored)
|
|
832
|
-
├── Dockerfile
|
|
833
|
-
├── docker-compose.yml
|
|
834
|
-
└── package.json
|
|
835
|
-
```
|
|
836
|
-
|
|
837
|
-
---
|
|
838
|
-
|
|
839
|
-
## Scripts úteis
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
| Comando | Descrição |
|
|
843
|
-
| ------------------- | ----------------------------------------------------------------------- |
|
|
844
|
-
| `npm run tui` | Abrir o dashboard interativo da TUI com proxy embutido |
|
|
845
|
-
| `npm start` | Iniciar apenas o servidor QwenProxy em modo headless |
|
|
846
|
-
| `npm run sync` | Sincronizar clientes (Claude Code, Codex, OpenCode, OMP) com backup |
|
|
847
|
-
| `npm run clean` | Limpar caches temporários dos perfis Chromium (~4.5MB por conta) |
|
|
848
|
-
| `npm run clean:all` | Limpar caches + remover navegadores órfãos e versões antigas em disco |
|
|
849
|
-
| `npm run reset` | Zerar cooldowns de contas no banco de dados |
|
|
850
|
-
| `npm run login` | Adicionar/autenticar novas contas visualmente no navegador |
|
|
851
|
-
| `npm run purge` | Limpar chats remotos do Qwen nas contas configuradas |
|
|
852
|
-
| `npm test` | Executar suíte de testes completa |
|
|
853
|
-
| `npm run typecheck` | Checagem estrita de tipos do TypeScript |
|
|
854
|
-
---
|
|
855
|
-
|
|
856
|
-
## Scripts de instalação, início e atualização
|
|
857
|
-
|
|
858
|
-
A pasta `scripts/` contém atalhos para instalar, iniciar e atualizar o projeto sem digitar os comandos manualmente.
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
| Script | Windows | Linux/macOS | O que faz |
|
|
862
|
-
| ----------- | --------------------- | ---------------------- | -------------------------------------------------------------------------------------------- |
|
|
863
|
-
| Instalador | `scripts\install.bat` | `./scripts/install.sh` | Verifica Node 22+, roda `npm install`, cria `.env` a partir de `.env.example` se não existir |
|
|
864
|
-
| Iniciador | `scripts\start.bat` | `./scripts/start.sh` | Verifica dependências e `.env`, inicia o servidor com `npm start` |
|
|
865
|
-
| Atualizador | `scripts\update.bat` | `./scripts/update.sh` | `git pull` (se for repositório), `npm install` e `npx playwright install chromium` |
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
No Linux/macOS, dê permissão de execução na primeira vez:
|
|
869
|
-
|
|
870
|
-
```bash
|
|
871
|
-
chmod +x scripts/*.sh
|
|
872
|
-
```
|
|
873
|
-
|
|
874
301
|
---
|
|
875
302
|
|
|
876
|
-
##
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
| Problema | Solução |
|
|
880
|
-
| --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
881
|
-
| Anti-bot / captcha | Solver Baxia automático por padrão (`CAPTCHA_SOLVER_ENABLED=true`); se falhar, a conta entra em cooldown (`CAPTCHA_ACCOUNT_COOLDOWN_MS`) e a request roda em outra conta |
|
|
882
|
-
| Quota exceeded | Mais contas ou esperar cooldown |
|
|
883
|
-
| `502 Bad Gateway` / `fetch failed` | Normalmente upstream/rede; o proxy faz retry automático |
|
|
884
|
-
| `invalid_input` (anexo inválido) | Retry com chat novo; settings `largeTextAsFile=false` ajudam |
|
|
885
|
-
| `context_length_exceeded` | O proxy bloqueou o prompt localmente antes de qualquer retry; reduza/resuma o histórico ou ajuste `QWEN_MAX_PROMPT_BYTES` |
|
|
886
|
-
| HTML/WAF no lugar do stream | O Bridge identifica o desafio e aciona o solver; se persistir, reduza o tamanho/frequência do payload e verifique a sessão |
|
|
887
|
-
| `Model not found` | Use um id do catálogo de `/v1/models` (ex.: `qwen3.8-max`) |
|
|
888
|
-
| Vários Chromes abertos / RAM alta | `SESSION_KEEP_ALIVE_ENABLED=false`, idle cleanup on, `PLAYWRIGHT_INIT_BATCH_SIZE=1`, `PLAYWRIGHT_JS_HEAP_MB`, watchdog RSS fecha idle sob pressão |
|
|
889
|
-
| Watchdog “RAM critical” falso | Baseado em RSS (`memory.rss.usage_percent`); confira `/health` |
|
|
890
|
-
| Timeout em requests grandes | Aumente `TOTAL_REQUEST_TIMEOUT` / `REASONING_MODEL_TIMEOUT` |
|
|
891
|
-
| `stream_aborted` em modelo reasoning | Idle timeout: zero bytes por `REASONING_MODEL_TIMEOUT` (180s default) fecha o stream retryável; aumente se necessário |
|
|
892
|
-
| `canSkipThinking: false` | O catálogo não informa `think_skip`; a variante pública `-fast` continua disponível e usa o payload Fast do Qwen |
|
|
893
|
-
| Grok CLI `missing field input_tokens_details` | Corrigido: usage sempre inclui `input_tokens_details` e `output_tokens_details` |
|
|
894
|
-
| Responses `previous_response_id` not found | Store SQLite com TTL 7 dias; verifique se `store: false` não foi enviado |
|
|
895
|
-
| Playwright não inicia | `npx playwright install chromium` |
|
|
896
|
-
| Porta em uso | Altere `PORT` no `.env` |
|
|
897
|
-
| Sessão expirada | `npm run login` ou deixe o refresh automático reautenticar |
|
|
898
|
-
| API aberta em `0.0.0.0` sem key | Defina `API_KEY` e/ou `HOST=127.0.0.1` |
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
---
|
|
902
|
-
|
|
903
|
-
## Créditos e Agradecimentos
|
|
904
|
-
|
|
905
|
-
O **QwenProxy** é desenvolvido e mantido por **johngbl**, construído sobre as fundações de código aberto originalmente criadas por **Pedro Farias** sob a licença [ISC](LICENSE).
|
|
906
|
-
|
|
907
|
-
---
|
|
908
|
-
## Disclaimer
|
|
303
|
+
## ⚖️ Disclaimer
|
|
909
304
|
|
|
910
|
-
**
|
|
305
|
+
**This software is provided "as is", without warranty of any kind, express or implied.**
|
|
911
306
|
|
|
912
|
-
- **
|
|
913
|
-
- **
|
|
914
|
-
- **
|
|
915
|
-
- **Exclusão total do mantenedor:** nos limites máximos da lei, o autor e os contribuidores **não respondem** por quaisquer danos diretos, indiretos, incidentais, especiais ou consequenciais (perda de lucros, dados, contas, quota ou receita) decorrentes do uso ou da incapacidade de uso deste software, nem por mudanças, quebras ou bloqueios do serviço upstream, que podem ocorrer a qualquer momento e sem aviso prévio.
|
|
916
|
-
- **Sem prestação de serviço:** projeto voluntário, sem SLA e sem obrigação de atualizar ou corrigir.
|
|
307
|
+
- **No Affiliation:** QwenProxy is an independent open-source project and is not affiliated with, endorsed, or sponsored by Alibaba, Qwen, OpenAI, Anthropic, or any mentioned provider.
|
|
308
|
+
- **Educational & Personal Use:** Intended for technical research and local development. Users are solely responsible for adhering to upstream Terms of Service, managing their own credentials, and complying with applicable laws.
|
|
309
|
+
- **User Responsibility:** The user assumes full responsibility for account rate limits, security challenges, and content generated.
|
|
917
310
|
|
|
918
|
-
|
|
311
|
+
Developed and maintained by **johngbl**, built on open-source foundations originally authored by **Pedro Farias** under the [ISC License](LICENSE).
|