qwenproxy-cli 1.6.8 → 1.6.10
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/dist/clean-cache.js +163 -44
- package/dist/delete-chats.js +166 -50
- package/dist/index.js +167 -51
- package/dist/login.js +163 -47
- package/dist/reset-cooldowns.js +163 -44
- package/dist/sync-clients.js +1 -1
- package/package.json +1 -1
- package/src/core/config.ts +1 -1
- package/src/core/version.ts +1 -1
- package/src/services/auth-playwright.ts +1 -1
- package/src/services/playwright.ts +174 -49
- package/src/services/qwen.ts +3 -3
|
@@ -365,7 +365,24 @@ export async function isPageLoggedIn(
|
|
|
365
365
|
return false;
|
|
366
366
|
}
|
|
367
367
|
|
|
368
|
-
|
|
368
|
+
// In Qwen Web 0.3.26+, UI login stores the JWT in localStorage("token")
|
|
369
|
+
// without setting a "token=" cookie in document.cookie. Sync it so
|
|
370
|
+
// same-origin probes and context.cookies() always include it.
|
|
371
|
+
const lsToken = (localStorage.getItem("token") || "").trim();
|
|
372
|
+
if (lsToken && !/(?:^|;\s*)token=/.test(document.cookie || "")) {
|
|
373
|
+
try {
|
|
374
|
+
document.cookie = `token=${encodeURIComponent(lsToken)}; path=/; domain=.qwen.ai; max-age=31536000`;
|
|
375
|
+
} catch {}
|
|
376
|
+
}
|
|
377
|
+
const authHeaders: Record<string, string> = lsToken
|
|
378
|
+
? { Authorization: `Bearer ${lsToken}` }
|
|
379
|
+
: {};
|
|
380
|
+
|
|
381
|
+
const res = await fetch("/api/v1/auths/", {
|
|
382
|
+
method: "GET",
|
|
383
|
+
headers: authHeaders,
|
|
384
|
+
credentials: "include",
|
|
385
|
+
});
|
|
369
386
|
if (res.status !== 200) return false;
|
|
370
387
|
const json: any = await res.json().catch(() => null);
|
|
371
388
|
if (!json) return false;
|
|
@@ -398,6 +415,7 @@ export async function isPageLoggedIn(
|
|
|
398
415
|
try {
|
|
399
416
|
const settingsRes = await fetch("/api/v2/users/user/settings", {
|
|
400
417
|
method: "GET",
|
|
418
|
+
headers: authHeaders,
|
|
401
419
|
credentials: "include",
|
|
402
420
|
signal: AbortSignal.timeout(3000),
|
|
403
421
|
});
|
|
@@ -1819,8 +1837,15 @@ export async function initPlaywrightForAccount(
|
|
|
1819
1837
|
c.name.toLowerCase().includes("session"),
|
|
1820
1838
|
);
|
|
1821
1839
|
|
|
1840
|
+
let initialLoginAttempted = false;
|
|
1822
1841
|
if (!hasAuthCookie && account.email && account.password) {
|
|
1823
|
-
|
|
1842
|
+
initialLoginAttempted = true;
|
|
1843
|
+
const loggedIn = await loginToQwen(account.id, account.email, account.password);
|
|
1844
|
+
if (!loggedIn) {
|
|
1845
|
+
throw new Error(
|
|
1846
|
+
`Authentication failed for account ${maskEmail(account.email)}`,
|
|
1847
|
+
);
|
|
1848
|
+
}
|
|
1824
1849
|
}
|
|
1825
1850
|
|
|
1826
1851
|
// Initial navigation to chat home
|
|
@@ -1832,13 +1857,21 @@ export async function initPlaywrightForAccount(
|
|
|
1832
1857
|
await sleep(1500);
|
|
1833
1858
|
const currentUrl = acctPage.url();
|
|
1834
1859
|
const isAuthUrl = currentUrl.includes("/auth") || currentUrl.includes("/login");
|
|
1835
|
-
if (isAuthUrl && account.email && account.password) {
|
|
1860
|
+
if (isAuthUrl && !initialLoginAttempted && account.email && account.password) {
|
|
1836
1861
|
console.log(
|
|
1837
1862
|
`[Playwright] Initial login needed for ${maskEmail(account.email)}, authenticating...`,
|
|
1838
1863
|
);
|
|
1839
|
-
await loginToQwen(account.id, account.email, account.password);
|
|
1864
|
+
const loggedIn = await loginToQwen(account.id, account.email, account.password);
|
|
1865
|
+
if (!loggedIn) {
|
|
1866
|
+
throw new Error(
|
|
1867
|
+
`Authentication failed for account ${maskEmail(account.email)}`,
|
|
1868
|
+
);
|
|
1869
|
+
}
|
|
1840
1870
|
}
|
|
1841
1871
|
} catch (err: any) {
|
|
1872
|
+
if (err?.message?.includes("Authentication failed for account")) {
|
|
1873
|
+
throw err;
|
|
1874
|
+
}
|
|
1842
1875
|
console.warn(
|
|
1843
1876
|
`⚠️ [Playwright] Initial navigation check for ${maskEmail(account.email)}: ${err.message}`,
|
|
1844
1877
|
);
|
|
@@ -2193,7 +2226,7 @@ export async function startEmailOtpLogin(
|
|
|
2193
2226
|
{
|
|
2194
2227
|
email: normalizedEmail,
|
|
2195
2228
|
requestId,
|
|
2196
|
-
version: getQwenWebVersion() || "0.3.
|
|
2229
|
+
version: getQwenWebVersion() || "0.3.26",
|
|
2197
2230
|
timezone: formatAsciiTimezone(),
|
|
2198
2231
|
},
|
|
2199
2232
|
).catch((err: any) => ({ ok: false, error: err?.message || String(err) }));
|
|
@@ -2305,7 +2338,7 @@ export async function verifyEmailOtpLogin(
|
|
|
2305
2338
|
email: session.email,
|
|
2306
2339
|
code: cleanCode,
|
|
2307
2340
|
requestId,
|
|
2308
|
-
version: getQwenWebVersion() || "0.3.
|
|
2341
|
+
version: getQwenWebVersion() || "0.3.26",
|
|
2309
2342
|
timezone: formatAsciiTimezone(),
|
|
2310
2343
|
},
|
|
2311
2344
|
).catch((err: any) => ({ ok: false, error: err?.message || String(err) }));
|
|
@@ -2363,7 +2396,7 @@ export async function verifyEmailOtpLogin(
|
|
|
2363
2396
|
cookie: `token=${accessToken}`,
|
|
2364
2397
|
userAgent: session.fingerprint.userAgent,
|
|
2365
2398
|
bxV: "2.5.37",
|
|
2366
|
-
version: getQwenWebVersion() || "0.3.
|
|
2399
|
+
version: getQwenWebVersion() || "0.3.26",
|
|
2367
2400
|
userId: userId || undefined,
|
|
2368
2401
|
tokenExpiresAt: exp || undefined,
|
|
2369
2402
|
refreshToken: refreshToken || undefined,
|
|
@@ -2551,10 +2584,31 @@ async function loginToQwen(
|
|
|
2551
2584
|
const uiResult = await loginViaUi(page, email, password);
|
|
2552
2585
|
if (uiResult.success) {
|
|
2553
2586
|
cookieCaches.delete(accountId);
|
|
2554
|
-
await saveStorageState(page.context(), accountId);
|
|
2555
2587
|
try {
|
|
2556
|
-
|
|
2557
|
-
|
|
2588
|
+
let liveCookies = await page.context().cookies();
|
|
2589
|
+
let tokenCookie = liveCookies.find((c) => c.name === "token");
|
|
2590
|
+
if (!tokenCookie) {
|
|
2591
|
+
const lsTok =
|
|
2592
|
+
uiResult.token ||
|
|
2593
|
+
(await page.evaluate(() => (localStorage.getItem("token") || "").trim()).catch(() => ""));
|
|
2594
|
+
if (lsTok) {
|
|
2595
|
+
await page.context().addCookies([
|
|
2596
|
+
{
|
|
2597
|
+
name: "token",
|
|
2598
|
+
value: lsTok,
|
|
2599
|
+
domain: ".qwen.ai",
|
|
2600
|
+
path: "/",
|
|
2601
|
+
expires: Math.floor(Date.now() / 1000) + 31536000,
|
|
2602
|
+
httpOnly: false,
|
|
2603
|
+
secure: true,
|
|
2604
|
+
sameSite: "Lax",
|
|
2605
|
+
},
|
|
2606
|
+
]).catch(() => {});
|
|
2607
|
+
liveCookies = await page.context().cookies();
|
|
2608
|
+
tokenCookie = liveCookies.find((c) => c.name === "token");
|
|
2609
|
+
}
|
|
2610
|
+
}
|
|
2611
|
+
await saveStorageState(page.context(), accountId);
|
|
2558
2612
|
if (tokenCookie) {
|
|
2559
2613
|
const cookieStr = liveCookies.map((c) => `${c.name}=${c.value}`).join("; ");
|
|
2560
2614
|
const cache = getHeaderCache(accountId);
|
|
@@ -2563,7 +2617,9 @@ async function loginToQwen(
|
|
|
2563
2617
|
markAccountHeadersReady(accountId);
|
|
2564
2618
|
const { saveAuthSession } = await import("../core/database.ts");
|
|
2565
2619
|
const exp = parseJwtExpiry(tokenCookie.value);
|
|
2566
|
-
let rTok =
|
|
2620
|
+
let rTok =
|
|
2621
|
+
uiResult.refreshToken ||
|
|
2622
|
+
liveCookies.find((c) => c.name === "refresh_token")?.value;
|
|
2567
2623
|
if (!rTok) {
|
|
2568
2624
|
try {
|
|
2569
2625
|
rTok = (await page.evaluate(() => localStorage.getItem("refresh_token") || "")) || undefined;
|
|
@@ -2657,10 +2713,11 @@ async function loginViaApi(
|
|
|
2657
2713
|
|
|
2658
2714
|
const signinUrl = "https://auth.qwen.ai/api/v2/auths/signin";
|
|
2659
2715
|
const requestId = crypto.randomUUID();
|
|
2716
|
+
const webVersion = getQwenWebVersion() || "0.3.26";
|
|
2660
2717
|
|
|
2661
2718
|
const evalRes = await page
|
|
2662
2719
|
.evaluate(
|
|
2663
|
-
async ({ email, password, signinUrl, requestId, tz }) => {
|
|
2720
|
+
async ({ email, password, signinUrl, requestId, tz, version }) => {
|
|
2664
2721
|
try {
|
|
2665
2722
|
const response = await fetch(signinUrl, {
|
|
2666
2723
|
method: "POST",
|
|
@@ -2670,7 +2727,7 @@ async function loginViaApi(
|
|
|
2670
2727
|
accept: "application/json, text/plain, */*",
|
|
2671
2728
|
"content-type": "application/json",
|
|
2672
2729
|
source: "web",
|
|
2673
|
-
version
|
|
2730
|
+
version,
|
|
2674
2731
|
"x-request-origin": "https://chat.qwen.ai",
|
|
2675
2732
|
timezone: tz,
|
|
2676
2733
|
"x-request-id": requestId,
|
|
@@ -2683,7 +2740,14 @@ async function loginViaApi(
|
|
|
2683
2740
|
return { ok: false, error: e.message };
|
|
2684
2741
|
}
|
|
2685
2742
|
},
|
|
2686
|
-
{
|
|
2743
|
+
{
|
|
2744
|
+
email,
|
|
2745
|
+
password: hashedPassword,
|
|
2746
|
+
signinUrl,
|
|
2747
|
+
requestId,
|
|
2748
|
+
tz: formatAsciiTimezone(),
|
|
2749
|
+
version: webVersion,
|
|
2750
|
+
},
|
|
2687
2751
|
)
|
|
2688
2752
|
.catch(() => null);
|
|
2689
2753
|
|
|
@@ -2701,7 +2765,7 @@ async function loginViaApi(
|
|
|
2701
2765
|
const fallbackUrl = qwenUrl("/api/v2/auths/signin");
|
|
2702
2766
|
const fallbackRes = await page
|
|
2703
2767
|
.evaluate(
|
|
2704
|
-
async ({ email, password, fallbackUrl, requestId, tz }) => {
|
|
2768
|
+
async ({ email, password, fallbackUrl, requestId, tz, version }) => {
|
|
2705
2769
|
try {
|
|
2706
2770
|
const response = await fetch(fallbackUrl, {
|
|
2707
2771
|
method: "POST",
|
|
@@ -2711,7 +2775,7 @@ async function loginViaApi(
|
|
|
2711
2775
|
accept: "application/json, text/plain, */*",
|
|
2712
2776
|
"content-type": "application/json",
|
|
2713
2777
|
source: "web",
|
|
2714
|
-
version
|
|
2778
|
+
version,
|
|
2715
2779
|
timezone: tz,
|
|
2716
2780
|
"x-request-id": requestId,
|
|
2717
2781
|
},
|
|
@@ -2723,7 +2787,14 @@ async function loginViaApi(
|
|
|
2723
2787
|
return { ok: false, error: e.message };
|
|
2724
2788
|
}
|
|
2725
2789
|
},
|
|
2726
|
-
{
|
|
2790
|
+
{
|
|
2791
|
+
email,
|
|
2792
|
+
password: hashedPassword,
|
|
2793
|
+
fallbackUrl,
|
|
2794
|
+
requestId,
|
|
2795
|
+
tz: formatAsciiTimezone(),
|
|
2796
|
+
version: webVersion,
|
|
2797
|
+
},
|
|
2727
2798
|
)
|
|
2728
2799
|
.catch(() => null);
|
|
2729
2800
|
|
|
@@ -3009,30 +3080,37 @@ async function loginViaUi(
|
|
|
3009
3080
|
|
|
3010
3081
|
await sleep(500);
|
|
3011
3082
|
|
|
3012
|
-
//
|
|
3083
|
+
// Submit the form: click the submit button if visible; only press Enter as fallback
|
|
3084
|
+
// (pressing Enter inside <form> after clicking submit triggers a native HTML form reload on Qwen 0.3.26).
|
|
3013
3085
|
const submitSelector =
|
|
3014
3086
|
'button.qwenchat-auth-pc-submit-button, button[type="submit"], button:has-text("Log in"), button:has-text("Sign in"), button:has-text("Fazer login"), button:has-text("Entrar"), button:has-text("Iniciar sesión"), button:has-text("登录")';
|
|
3015
3087
|
const submitButton = page.locator(submitSelector).first();
|
|
3016
3088
|
|
|
3017
|
-
|
|
3018
|
-
try {
|
|
3019
|
-
const btn = document.querySelector(sel) as HTMLButtonElement | null;
|
|
3020
|
-
if (btn) {
|
|
3021
|
-
btn.removeAttribute("disabled");
|
|
3022
|
-
btn.classList.remove("ant-btn-disabled");
|
|
3023
|
-
btn.click();
|
|
3024
|
-
}
|
|
3025
|
-
} catch {}
|
|
3026
|
-
}, submitSelector).catch(() => {});
|
|
3027
|
-
|
|
3089
|
+
let submitted = false;
|
|
3028
3090
|
try {
|
|
3029
3091
|
if (await submitButton.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
3030
|
-
await submitButton.click({
|
|
3092
|
+
await submitButton.click({ timeout: 2000 }).catch(() => {});
|
|
3093
|
+
submitted = true;
|
|
3031
3094
|
}
|
|
3032
3095
|
} catch {}
|
|
3033
3096
|
|
|
3034
|
-
|
|
3035
|
-
|
|
3097
|
+
if (!submitted) {
|
|
3098
|
+
await page.evaluate(() => {
|
|
3099
|
+
try {
|
|
3100
|
+
const btn = document.querySelector(
|
|
3101
|
+
'button.qwenchat-auth-pc-submit-button, button[type="submit"]',
|
|
3102
|
+
) as HTMLButtonElement | null;
|
|
3103
|
+
if (btn) {
|
|
3104
|
+
btn.removeAttribute("disabled");
|
|
3105
|
+
btn.classList.remove("ant-btn-disabled");
|
|
3106
|
+
btn.click();
|
|
3107
|
+
}
|
|
3108
|
+
} catch {}
|
|
3109
|
+
}).catch(() => {});
|
|
3110
|
+
|
|
3111
|
+
const passInput = page.locator(passwordSelector).first();
|
|
3112
|
+
await passInput.press("Enter", { timeout: 2000 }).catch(() => {});
|
|
3113
|
+
}
|
|
3036
3114
|
// Post-submit verification loop: wait up to 15s for captcha, redirect, cookies, or errors
|
|
3037
3115
|
const postSubmitDeadline = Date.now() + 15_000;
|
|
3038
3116
|
while (Date.now() < postSubmitDeadline) {
|
|
@@ -3054,9 +3132,12 @@ async function loginViaUi(
|
|
|
3054
3132
|
".ant-form-item-explain-error",
|
|
3055
3133
|
".ant-message-error",
|
|
3056
3134
|
".ant-message-notice",
|
|
3135
|
+
".ant-message-custom-content",
|
|
3136
|
+
".ant-notification-notice",
|
|
3057
3137
|
'[role="alert"]',
|
|
3058
3138
|
".qwenchat-auth-error",
|
|
3059
3139
|
".auth-error-message",
|
|
3140
|
+
".qwenchat-toast",
|
|
3060
3141
|
].join(", ");
|
|
3061
3142
|
const errorEl = page.locator(errorSelector).first();
|
|
3062
3143
|
if (await errorEl.isVisible().catch(() => false)) {
|
|
@@ -3072,8 +3153,15 @@ async function loginViaUi(
|
|
|
3072
3153
|
}
|
|
3073
3154
|
|
|
3074
3155
|
// Check if an OTP code verification screen appeared (e.g. 2FA / email verification code)
|
|
3075
|
-
const codeSelector =
|
|
3076
|
-
'input[placeholder*="code" i],
|
|
3156
|
+
const codeSelector = [
|
|
3157
|
+
'input[placeholder*="code" i]',
|
|
3158
|
+
'input[placeholder*="código" i]',
|
|
3159
|
+
'input[name*="code" i]',
|
|
3160
|
+
".qwenchat-verification-code-input",
|
|
3161
|
+
".qwenchat-verification-code-input-cell",
|
|
3162
|
+
'[aria-label*="Verification code" i]',
|
|
3163
|
+
'[aria-label*="código de verificação" i]',
|
|
3164
|
+
].join(", ");
|
|
3077
3165
|
const codeInput = page.locator(codeSelector).first();
|
|
3078
3166
|
if (await codeInput.isVisible().catch(() => false)) {
|
|
3079
3167
|
return {
|
|
@@ -3082,21 +3170,50 @@ async function loginViaUi(
|
|
|
3082
3170
|
};
|
|
3083
3171
|
}
|
|
3084
3172
|
|
|
3085
|
-
// Check if auth cookie 'token' appeared
|
|
3173
|
+
// Check if auth cookie 'token' appeared or localStorage 'token' was populated (Qwen 0.3.26+)
|
|
3086
3174
|
try {
|
|
3087
3175
|
const liveCookies = await page.context().cookies();
|
|
3088
|
-
|
|
3089
|
-
|
|
3176
|
+
const rTokCookie = liveCookies.find((c) => c.name === "refresh_token")?.value;
|
|
3177
|
+
const tokCookie = liveCookies.find((c) => c.name === "token")?.value;
|
|
3178
|
+
if (tokCookie) {
|
|
3179
|
+
return { success: true, token: tokCookie, refreshToken: rTokCookie };
|
|
3090
3180
|
}
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3181
|
+
const currentUrl = page.url();
|
|
3182
|
+
if (!currentUrl.includes("/auth") && !currentUrl.includes("/login")) {
|
|
3183
|
+
const lsTok = await page
|
|
3184
|
+
.evaluate(() => {
|
|
3185
|
+
const t = (localStorage.getItem("token") || "").trim();
|
|
3186
|
+
if (t) {
|
|
3187
|
+
try {
|
|
3188
|
+
document.cookie = `token=${encodeURIComponent(t)}; path=/; domain=.qwen.ai; max-age=31536000`;
|
|
3189
|
+
} catch {}
|
|
3190
|
+
}
|
|
3191
|
+
return t;
|
|
3192
|
+
})
|
|
3193
|
+
.catch(() => "");
|
|
3194
|
+
if (lsTok) {
|
|
3195
|
+
await page
|
|
3196
|
+
.context()
|
|
3197
|
+
.addCookies([
|
|
3198
|
+
{
|
|
3199
|
+
name: "token",
|
|
3200
|
+
value: lsTok,
|
|
3201
|
+
domain: ".qwen.ai",
|
|
3202
|
+
path: "/",
|
|
3203
|
+
expires: Math.floor(Date.now() / 1000) + 31536000,
|
|
3204
|
+
httpOnly: false,
|
|
3205
|
+
secure: true,
|
|
3206
|
+
sameSite: "Lax",
|
|
3207
|
+
},
|
|
3208
|
+
])
|
|
3209
|
+
.catch(() => {});
|
|
3210
|
+
return { success: true, token: lsTok, refreshToken: rTokCookie };
|
|
3211
|
+
}
|
|
3212
|
+
if (await isPageLoggedIn(page, 3000)) {
|
|
3213
|
+
return { success: true, refreshToken: rTokCookie };
|
|
3214
|
+
}
|
|
3098
3215
|
}
|
|
3099
|
-
}
|
|
3216
|
+
} catch {}
|
|
3100
3217
|
|
|
3101
3218
|
await sleep(1000);
|
|
3102
3219
|
}
|
|
@@ -3128,7 +3245,7 @@ export async function refreshAccountToken(
|
|
|
3128
3245
|
return { success: false, error: "Account page not active" };
|
|
3129
3246
|
}
|
|
3130
3247
|
|
|
3131
|
-
// 1. Get refresh token from SQLite session or
|
|
3248
|
+
// 1. Get refresh token from SQLite session, localStorage, or browser cookies (Qwen 0.3.26+)
|
|
3132
3249
|
const { getValidAuthSession, saveAuthSession } = await import("../core/database.ts");
|
|
3133
3250
|
const session = getValidAuthSession(accountId);
|
|
3134
3251
|
let refreshToken = session?.refreshToken;
|
|
@@ -3141,11 +3258,19 @@ export async function refreshAccountToken(
|
|
|
3141
3258
|
} catch {}
|
|
3142
3259
|
}
|
|
3143
3260
|
|
|
3261
|
+
if (!refreshToken) {
|
|
3262
|
+
try {
|
|
3263
|
+
const liveCookies = await page.context().cookies();
|
|
3264
|
+
refreshToken = liveCookies.find((c) => c.name === "refresh_token")?.value;
|
|
3265
|
+
} catch {}
|
|
3266
|
+
}
|
|
3267
|
+
|
|
3144
3268
|
// 2. If we have a refresh token, invoke the working refresh endpoint in-page
|
|
3145
3269
|
if (refreshToken) {
|
|
3146
3270
|
try {
|
|
3271
|
+
const webVersion = getQwenWebVersion() || "0.3.26";
|
|
3147
3272
|
const refreshResult = await page.evaluate(
|
|
3148
|
-
async ({ rTok, tz }) => {
|
|
3273
|
+
async ({ rTok, tz, version }) => {
|
|
3149
3274
|
try {
|
|
3150
3275
|
const response = await fetch("https://auth.qwen.ai/api/v2/auths/refresh", {
|
|
3151
3276
|
method: "GET",
|
|
@@ -3153,7 +3278,7 @@ export async function refreshAccountToken(
|
|
|
3153
3278
|
headers: {
|
|
3154
3279
|
accept: "application/json, text/plain, */*",
|
|
3155
3280
|
source: "web",
|
|
3156
|
-
version
|
|
3281
|
+
version,
|
|
3157
3282
|
"x-request-origin": "https://chat.qwen.ai",
|
|
3158
3283
|
timezone: tz,
|
|
3159
3284
|
authorization: `Bearer ${rTok}`,
|
|
@@ -3165,7 +3290,7 @@ export async function refreshAccountToken(
|
|
|
3165
3290
|
return { ok: false, error: e.message };
|
|
3166
3291
|
}
|
|
3167
3292
|
},
|
|
3168
|
-
{ rTok: refreshToken, tz: formatAsciiTimezone() },
|
|
3293
|
+
{ rTok: refreshToken, tz: formatAsciiTimezone(), version: webVersion },
|
|
3169
3294
|
);
|
|
3170
3295
|
|
|
3171
3296
|
const json = refreshResult?.data;
|
package/src/services/qwen.ts
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
UpstreamRateLimit,
|
|
11
11
|
ClientAbortedError,
|
|
12
12
|
} from "../core/errors.ts";
|
|
13
|
-
import { buildQwenRequestHeaders } from "./qwen-headers.ts";
|
|
13
|
+
import { buildQwenRequestHeaders, getQwenWebVersion } from "./qwen-headers.ts";
|
|
14
14
|
import { qwenOrigin, qwenUrl } from "./qwen-url.ts";
|
|
15
15
|
import { config, type ChatMode, isLocalChatMode } from "../core/config.ts";
|
|
16
16
|
import { logger } from "../core/logger.ts";
|
|
@@ -2369,7 +2369,7 @@ export async function deleteSingleQwenChat(
|
|
|
2369
2369
|
|
|
2370
2370
|
const requestHeaders: Record<string, string> = {
|
|
2371
2371
|
source: "web",
|
|
2372
|
-
version: "0.
|
|
2372
|
+
version: getQwenWebVersion() || "0.3.26",
|
|
2373
2373
|
timezone: formatAsciiTimezone(),
|
|
2374
2374
|
"x-request-id": crypto.randomUUID(),
|
|
2375
2375
|
Referer: qwenUrl(`/c/${encodeURIComponent(chatId)}`),
|
|
@@ -2422,7 +2422,7 @@ export async function fetchRemoteQwenChats(
|
|
|
2422
2422
|
}
|
|
2423
2423
|
|
|
2424
2424
|
const requestHeaders: Record<string, string> = {
|
|
2425
|
-
version: "0.
|
|
2425
|
+
version: getQwenWebVersion() || "0.3.26",
|
|
2426
2426
|
timezone: formatAsciiTimezone(),
|
|
2427
2427
|
"x-request-id": crypto.randomUUID(),
|
|
2428
2428
|
Referer: qwenUrl("/settings/chats"),
|