@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 +1 -1
- package/src/services/qwen.ts +7 -22
package/package.json
CHANGED
package/src/services/qwen.ts
CHANGED
|
@@ -16,9 +16,7 @@ function getClientHintsHeaders(): Record<string, string> {
|
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
|
|
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 =
|
|
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
|
-
|
|
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,
|
|
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('
|
|
532
|
-
const
|
|
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(
|
|
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, {
|