qwenproxy-cli 1.6.4 → 1.6.5
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 +73 -10
- package/dist/delete-chats.js +172 -44
- package/dist/index.js +234 -58
- package/dist/login.js +81 -15
- package/dist/reset-cooldowns.js +76 -11
- package/package.json +1 -1
- package/src/core/mutex.ts +4 -0
- package/src/core/version.ts +1 -1
- package/src/routes/anthropic/translate.ts +15 -7
- package/src/routes/chat/helpers.ts +4 -2
- package/src/routes/chat/streaming.ts +32 -10
- package/src/routes/responses/adapter.ts +4 -1
- package/src/services/context-meter.ts +1 -1
- package/src/services/playwright.ts +41 -15
- package/src/services/qwen-headers.ts +3 -2
- package/src/services/qwen.ts +87 -30
- package/src/tools/tool-call-heuristics.ts +88 -0
- package/src/utils/timezone.ts +56 -0
package/dist/clean-cache.js
CHANGED
|
@@ -1814,6 +1814,7 @@ var init_mutex = __esm({
|
|
|
1814
1814
|
locked = false;
|
|
1815
1815
|
lockedAt = 0;
|
|
1816
1816
|
lockedByKey = "";
|
|
1817
|
+
epoch = 0;
|
|
1817
1818
|
async acquire(timeoutMs = 3e5, key = "") {
|
|
1818
1819
|
const holdLimitMs = this.maxHoldMs;
|
|
1819
1820
|
if (this.locked && Date.now() - this.lockedAt > holdLimitMs) {
|
|
@@ -1824,6 +1825,7 @@ var init_mutex = __esm({
|
|
|
1824
1825
|
this.locked = false;
|
|
1825
1826
|
this.lockedAt = 0;
|
|
1826
1827
|
this.lockedByKey = "";
|
|
1828
|
+
this.epoch++;
|
|
1827
1829
|
}
|
|
1828
1830
|
if (!this.locked) {
|
|
1829
1831
|
this.locked = true;
|
|
@@ -1862,10 +1864,12 @@ var init_mutex = __esm({
|
|
|
1862
1864
|
}
|
|
1863
1865
|
}
|
|
1864
1866
|
createRelease() {
|
|
1867
|
+
const epoch = this.epoch;
|
|
1865
1868
|
let released = false;
|
|
1866
1869
|
return () => {
|
|
1867
1870
|
if (released) return;
|
|
1868
1871
|
released = true;
|
|
1872
|
+
if (epoch !== this.epoch) return;
|
|
1869
1873
|
this.release();
|
|
1870
1874
|
};
|
|
1871
1875
|
}
|
|
@@ -2673,6 +2677,45 @@ var init_waf_isolation = __esm({
|
|
|
2673
2677
|
}
|
|
2674
2678
|
});
|
|
2675
2679
|
|
|
2680
|
+
// src/utils/timezone.ts
|
|
2681
|
+
function formatAsciiTimezone(date = /* @__PURE__ */ new Date()) {
|
|
2682
|
+
const dayName = DAYS[date.getDay()];
|
|
2683
|
+
const monthName = MONTHS[date.getMonth()];
|
|
2684
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
2685
|
+
const year = date.getFullYear();
|
|
2686
|
+
const hours = String(date.getHours()).padStart(2, "0");
|
|
2687
|
+
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
2688
|
+
const seconds = String(date.getSeconds()).padStart(2, "0");
|
|
2689
|
+
const offsetMinutes = -date.getTimezoneOffset();
|
|
2690
|
+
const sign = offsetMinutes >= 0 ? "+" : "-";
|
|
2691
|
+
const absOffset = Math.abs(offsetMinutes);
|
|
2692
|
+
const offsetHours = String(Math.floor(absOffset / 60)).padStart(2, "0");
|
|
2693
|
+
const offsetMins = String(absOffset % 60).padStart(2, "0");
|
|
2694
|
+
const tzOffset = `GMT${sign}${offsetHours}${offsetMins}`;
|
|
2695
|
+
return `${dayName} ${monthName} ${day} ${year} ${hours}:${minutes}:${seconds} ${tzOffset}`;
|
|
2696
|
+
}
|
|
2697
|
+
var DAYS, MONTHS;
|
|
2698
|
+
var init_timezone = __esm({
|
|
2699
|
+
"src/utils/timezone.ts"() {
|
|
2700
|
+
"use strict";
|
|
2701
|
+
DAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
2702
|
+
MONTHS = [
|
|
2703
|
+
"Jan",
|
|
2704
|
+
"Feb",
|
|
2705
|
+
"Mar",
|
|
2706
|
+
"Apr",
|
|
2707
|
+
"May",
|
|
2708
|
+
"Jun",
|
|
2709
|
+
"Jul",
|
|
2710
|
+
"Aug",
|
|
2711
|
+
"Sep",
|
|
2712
|
+
"Oct",
|
|
2713
|
+
"Nov",
|
|
2714
|
+
"Dec"
|
|
2715
|
+
];
|
|
2716
|
+
}
|
|
2717
|
+
});
|
|
2718
|
+
|
|
2676
2719
|
// src/services/qwen-headers.ts
|
|
2677
2720
|
import { v4 as uuidv4 } from "uuid";
|
|
2678
2721
|
function getDefaultQwenUserAgent(major = getChromeMajor()) {
|
|
@@ -2690,6 +2733,7 @@ var init_qwen_headers = __esm({
|
|
|
2690
2733
|
init_qwen_url();
|
|
2691
2734
|
init_config();
|
|
2692
2735
|
init_fingerprint();
|
|
2736
|
+
init_timezone();
|
|
2693
2737
|
dynamicWebVersion = null;
|
|
2694
2738
|
QWEN_WEB_VERSION = config.qwen.webVersion;
|
|
2695
2739
|
DEFAULT_QWEN_USER_AGENT = getDefaultQwenUserAgent(151);
|
|
@@ -3758,6 +3802,22 @@ async function initPlaywrightForAccount(rawAccount, headless = config.playwright
|
|
|
3758
3802
|
}
|
|
3759
3803
|
}
|
|
3760
3804
|
}
|
|
3805
|
+
const currentCache = getHeaderCache(account.id);
|
|
3806
|
+
const currentCookie = currentCache?.headers?.cookie || "";
|
|
3807
|
+
if (currentCookie && isTokenExpiringSoon(currentCookie, 5)) {
|
|
3808
|
+
try {
|
|
3809
|
+
const refreshRes = await refreshAccountToken(account.id);
|
|
3810
|
+
if (refreshRes.success) {
|
|
3811
|
+
console.log(
|
|
3812
|
+
`\u26A1 [Playwright] Silently refreshed expired token restored from DB for ${maskEmail(account.email)}`
|
|
3813
|
+
);
|
|
3814
|
+
}
|
|
3815
|
+
} catch (err) {
|
|
3816
|
+
console.warn(
|
|
3817
|
+
`\u26A0\uFE0F [Playwright] Failed to proactively refresh expired token from DB for ${maskEmail(account.email)}: ${err?.message || err}`
|
|
3818
|
+
);
|
|
3819
|
+
}
|
|
3820
|
+
}
|
|
3761
3821
|
return;
|
|
3762
3822
|
}
|
|
3763
3823
|
const cookies = await acctContext.cookies();
|
|
@@ -4015,7 +4075,7 @@ async function loginViaApi(page, email, password) {
|
|
|
4015
4075
|
const signinUrl = "https://auth.qwen.ai/api/v2/auths/signin";
|
|
4016
4076
|
const requestId = crypto3.randomUUID();
|
|
4017
4077
|
const evalRes = await page.evaluate(
|
|
4018
|
-
async ({ email: email2, password: password2, signinUrl: signinUrl2, requestId: requestId2 }) => {
|
|
4078
|
+
async ({ email: email2, password: password2, signinUrl: signinUrl2, requestId: requestId2, tz }) => {
|
|
4019
4079
|
try {
|
|
4020
4080
|
const response = await fetch(signinUrl2, {
|
|
4021
4081
|
method: "POST",
|
|
@@ -4027,7 +4087,7 @@ async function loginViaApi(page, email, password) {
|
|
|
4027
4087
|
source: "web",
|
|
4028
4088
|
version: "0.3.11",
|
|
4029
4089
|
"x-request-origin": "https://chat.qwen.ai",
|
|
4030
|
-
timezone:
|
|
4090
|
+
timezone: tz,
|
|
4031
4091
|
"x-request-id": requestId2
|
|
4032
4092
|
},
|
|
4033
4093
|
body: JSON.stringify({ email: email2, password: password2 })
|
|
@@ -4038,7 +4098,7 @@ async function loginViaApi(page, email, password) {
|
|
|
4038
4098
|
return { ok: false, error: e.message };
|
|
4039
4099
|
}
|
|
4040
4100
|
},
|
|
4041
|
-
{ email, password: hashedPassword, signinUrl, requestId }
|
|
4101
|
+
{ email, password: hashedPassword, signinUrl, requestId, tz: formatAsciiTimezone() }
|
|
4042
4102
|
).catch(() => null);
|
|
4043
4103
|
let data = evalRes?.data;
|
|
4044
4104
|
let signinSuccess = Boolean(
|
|
@@ -4047,7 +4107,7 @@ async function loginViaApi(page, email, password) {
|
|
|
4047
4107
|
if (!signinSuccess && !data?.data?.code) {
|
|
4048
4108
|
const fallbackUrl = qwenUrl("/api/v2/auths/signin");
|
|
4049
4109
|
const fallbackRes = await page.evaluate(
|
|
4050
|
-
async ({ email: email2, password: password2, fallbackUrl: fallbackUrl2, requestId: requestId2 }) => {
|
|
4110
|
+
async ({ email: email2, password: password2, fallbackUrl: fallbackUrl2, requestId: requestId2, tz }) => {
|
|
4051
4111
|
try {
|
|
4052
4112
|
const response = await fetch(fallbackUrl2, {
|
|
4053
4113
|
method: "POST",
|
|
@@ -4058,7 +4118,7 @@ async function loginViaApi(page, email, password) {
|
|
|
4058
4118
|
"content-type": "application/json",
|
|
4059
4119
|
source: "web",
|
|
4060
4120
|
version: "0.3.11",
|
|
4061
|
-
timezone:
|
|
4121
|
+
timezone: tz,
|
|
4062
4122
|
"x-request-id": requestId2
|
|
4063
4123
|
},
|
|
4064
4124
|
body: JSON.stringify({ email: email2, password: password2 })
|
|
@@ -4069,7 +4129,7 @@ async function loginViaApi(page, email, password) {
|
|
|
4069
4129
|
return { ok: false, error: e.message };
|
|
4070
4130
|
}
|
|
4071
4131
|
},
|
|
4072
|
-
{ email, password: hashedPassword, fallbackUrl, requestId }
|
|
4132
|
+
{ email, password: hashedPassword, fallbackUrl, requestId, tz: formatAsciiTimezone() }
|
|
4073
4133
|
).catch(() => null);
|
|
4074
4134
|
if (fallbackRes?.data) {
|
|
4075
4135
|
data = fallbackRes.data;
|
|
@@ -4401,7 +4461,7 @@ async function refreshAccountToken(accountId) {
|
|
|
4401
4461
|
if (refreshToken) {
|
|
4402
4462
|
try {
|
|
4403
4463
|
const refreshResult = await page.evaluate(
|
|
4404
|
-
async ({ rTok }) => {
|
|
4464
|
+
async ({ rTok, tz }) => {
|
|
4405
4465
|
try {
|
|
4406
4466
|
const response = await fetch("https://auth.qwen.ai/api/v2/auths/refresh", {
|
|
4407
4467
|
method: "GET",
|
|
@@ -4411,7 +4471,7 @@ async function refreshAccountToken(accountId) {
|
|
|
4411
4471
|
source: "web",
|
|
4412
4472
|
version: "0.3.11",
|
|
4413
4473
|
"x-request-origin": "https://chat.qwen.ai",
|
|
4414
|
-
timezone:
|
|
4474
|
+
timezone: tz,
|
|
4415
4475
|
authorization: `Bearer ${rTok}`
|
|
4416
4476
|
}
|
|
4417
4477
|
});
|
|
@@ -4421,7 +4481,7 @@ async function refreshAccountToken(accountId) {
|
|
|
4421
4481
|
return { ok: false, error: e.message };
|
|
4422
4482
|
}
|
|
4423
4483
|
},
|
|
4424
|
-
{ rTok: refreshToken }
|
|
4484
|
+
{ rTok: refreshToken, tz: formatAsciiTimezone() }
|
|
4425
4485
|
);
|
|
4426
4486
|
const json = refreshResult?.data;
|
|
4427
4487
|
if (json && json.success === true && json.data) {
|
|
@@ -4459,6 +4519,7 @@ async function refreshAccountToken(accountId) {
|
|
|
4459
4519
|
const cache = getHeaderCache(accountId);
|
|
4460
4520
|
cache.headers.cookie = cookieStr;
|
|
4461
4521
|
cache.lastRefresh = Date.now();
|
|
4522
|
+
cookieCaches.set(accountId, { cookie: cookieStr, timestamp: Date.now() });
|
|
4462
4523
|
markAccountHeadersReady(accountId);
|
|
4463
4524
|
saveAuthSession2(accountId, {
|
|
4464
4525
|
cookie: cookieStr,
|
|
@@ -4493,6 +4554,7 @@ async function refreshAccountToken(accountId) {
|
|
|
4493
4554
|
const cache = getHeaderCache(accountId);
|
|
4494
4555
|
cache.headers.cookie = cookieStr;
|
|
4495
4556
|
cache.lastRefresh = Date.now();
|
|
4557
|
+
cookieCaches.set(accountId, { cookie: cookieStr, timestamp: Date.now() });
|
|
4496
4558
|
markAccountHeadersReady(accountId);
|
|
4497
4559
|
saveAuthSession2(accountId, {
|
|
4498
4560
|
cookie: cookieStr,
|
|
@@ -5373,6 +5435,7 @@ var init_playwright = __esm({
|
|
|
5373
5435
|
init_qwen_headers();
|
|
5374
5436
|
init_paths();
|
|
5375
5437
|
init_jwt();
|
|
5438
|
+
init_timezone();
|
|
5376
5439
|
requireLocal = createRequire(import.meta.url);
|
|
5377
5440
|
contextInitHooks = [];
|
|
5378
5441
|
ACCOUNT_MUTEX_MAX_HOLD_MS = 18e4;
|
|
@@ -5382,7 +5445,7 @@ var init_playwright = __esm({
|
|
|
5382
5445
|
inFlightAccountInits = /* @__PURE__ */ new Map();
|
|
5383
5446
|
headerCaches = /* @__PURE__ */ new Map();
|
|
5384
5447
|
HEADER_CACHE_TTL = 24 * 60 * 60 * 1e3;
|
|
5385
|
-
COOKIE_CACHE_TTL =
|
|
5448
|
+
COOKIE_CACHE_TTL = 60 * 1e3;
|
|
5386
5449
|
cookieCaches = /* @__PURE__ */ new Map();
|
|
5387
5450
|
lastAccountActivity = /* @__PURE__ */ new Map();
|
|
5388
5451
|
lastKeepAliveNavigation = /* @__PURE__ */ new Map();
|