@pedrofariasx/qwenproxy 1.3.1 → 1.3.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pedrofariasx/qwenproxy",
3
- "version": "1.3.1",
3
+ "version": "1.3.3",
4
4
  "description": "Local OpenAI-compatible proxy API that routes requests to Qwen (chat.qwen.ai) via Playwright browser automation.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -16,9 +16,7 @@ function getClientHintsHeaders(): Record<string, string> {
16
16
  };
17
17
  }
18
18
 
19
- function getRandomDelay(): number {
20
- return 200 + Math.floor(Math.random() * 600);
21
- }
19
+
22
20
 
23
21
  export class RetryableQwenStreamError extends Error {
24
22
  readonly retryAfterMs: number;
@@ -85,7 +83,7 @@ const warmPool: Map<string, WarmPoolEntry[]> = new Map();
85
83
 
86
84
  const refillPromises: Map<string, Promise<void>> = new Map();
87
85
 
88
- const WARM_POOL_SIZE = 5;
86
+ const WARM_POOL_SIZE = 10;
89
87
  const WARM_POOL_TTL_MS = 10 * 60 * 1000;
90
88
 
91
89
  function cleanupStalePool(accountId: string) {
@@ -152,18 +150,7 @@ async function refillPoolForAccount(accountId: string) {
152
150
  let headers: Record<string, string>;
153
151
  try {
154
152
  const acctId = accountId === 'global' ? undefined : accountId;
155
- try {
156
- const { headers: fullHeaders } = await getQwenHeaders(false, acctId);
157
- headers = {
158
- cookie: fullHeaders['cookie'] || '',
159
- 'user-agent': fullHeaders['user-agent'] || '',
160
- 'bx-v': fullHeaders['bx-v'] || '',
161
- 'bx-ua': fullHeaders['bx-ua'] || '',
162
- 'bx-umidtoken': fullHeaders['bx-umidtoken'] || '',
163
- };
164
- } catch {
165
- headers = await getBasicQwenHeaders(acctId);
166
- }
153
+ headers = await getBasicQwenHeaders(acctId);
167
154
  } catch (err) {
168
155
  console.error(`[WarmPool] header fetch failed for ${accountId}:`, (err as Error).message);
169
156
  return;
@@ -198,7 +185,7 @@ export async function getWarmedChat(accountId?: string) {
198
185
  }
199
186
  if (pool.length === 0) {
200
187
  // Retry once with short backoff if pool is still empty after first refill attempt
201
- await new Promise(r => setTimeout(r, 1000));
188
+ await new Promise(r => setTimeout(r, 200));
202
189
  if (!refillPromises.has(key)) {
203
190
  refillPromises.set(key, refillPoolForAccount(key).finally(() => refillPromises.delete(key)));
204
191
  }
@@ -500,7 +487,6 @@ export async function createQwenStream(
500
487
  const url = `https://chat.qwen.ai/api/v2/chat/completions?chat_id=${chatId}`;
501
488
  const controller = new AbortController();
502
489
  const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
503
- await sleep(getRandomDelay());
504
490
  const response = await fetch(url, {
505
491
  method: 'POST',
506
492
  headers: {
@@ -528,14 +514,13 @@ export async function createQwenStream(
528
514
  clearTimeout(timeoutId);
529
515
 
530
516
  const responseContentType = response.headers.get('content-type') || '';
531
- if (response.ok && responseContentType.includes('application/json') && response.body) {
532
- const cloned = response.clone();
533
- const peekText = await cloned.text().catch(() => '');
517
+ if (response.ok && !responseContentType.includes('text/event-stream') && response.body) {
518
+ const peekText = await response.clone().text().catch(() => '');
534
519
  if (peekText.includes('FAIL_SYS_USER_VALIDATE') || peekText.includes('_____tmd_____') || peekText.includes('RGV587_ERROR')) {
535
520
  console.warn('[Qwen] TMD challenge detected, refreshing headers and retrying...');
536
521
  try {
537
522
  const { headers: freshHeaders } = await getQwenHeaders(true, accountId);
538
- await sleep(1000 + Math.floor(Math.random() * 2000));
523
+ await sleep(500 + Math.floor(Math.random() * 1000));
539
524
  const retryController = new AbortController();
540
525
  const retryTimeoutId = setTimeout(() => retryController.abort(), timeoutMs);
541
526
  const retryResponse = await fetch(url, {