qwenproxy-cli 1.6.10 → 1.6.11
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 +40 -12
- package/dist/delete-chats.js +110 -35
- package/dist/index.js +131 -45
- package/dist/login.js +44 -24
- package/dist/reset-cooldowns.js +40 -12
- package/package.json +2 -2
- package/src/api/server.ts +8 -4
- package/src/core/version.ts +1 -1
- package/src/core/watchdog.ts +4 -3
- package/src/routes/chat/account.ts +12 -0
- package/src/routes/chat/streaming.ts +18 -2
- package/src/services/captcha-coordinator.ts +36 -8
- package/src/services/chat-cleanup.ts +11 -2
- package/src/services/playwright.ts +73 -28
- package/src/services/qwen.ts +29 -3
package/dist/clean-cache.js
CHANGED
|
@@ -2035,6 +2035,26 @@ function clearAccountCooldown(accountId) {
|
|
|
2035
2035
|
}
|
|
2036
2036
|
}
|
|
2037
2037
|
}
|
|
2038
|
+
function getAccountCooldownInfo(accountId) {
|
|
2039
|
+
const entry = cooldowns.get(accountId);
|
|
2040
|
+
if (!entry) return null;
|
|
2041
|
+
const remaining = entry.until - Date.now();
|
|
2042
|
+
if (remaining <= 0) {
|
|
2043
|
+
cooldowns.delete(accountId);
|
|
2044
|
+
if (accountId !== "global") {
|
|
2045
|
+
try {
|
|
2046
|
+
updateAccountCooldown(accountId, 0, null);
|
|
2047
|
+
} catch (err) {
|
|
2048
|
+
console.error(
|
|
2049
|
+
`\u274C [AccountManager] Failed to clear expired cooldown in DB:`,
|
|
2050
|
+
err.message
|
|
2051
|
+
);
|
|
2052
|
+
}
|
|
2053
|
+
}
|
|
2054
|
+
return null;
|
|
2055
|
+
}
|
|
2056
|
+
return { onCooldown: true, remainingMs: remaining, reason: entry.reason };
|
|
2057
|
+
}
|
|
2038
2058
|
function markAccountHeadersReady(accountId) {
|
|
2039
2059
|
if (!accountId || accountId === "global") return;
|
|
2040
2060
|
headersReadyAccounts.add(accountId);
|
|
@@ -3623,8 +3643,12 @@ async function initPlaywrightForAccount(rawAccount, headless = config.playwright
|
|
|
3623
3643
|
if (accountPages.has(account.id)) {
|
|
3624
3644
|
return;
|
|
3625
3645
|
}
|
|
3626
|
-
|
|
3627
|
-
|
|
3646
|
+
if (config.playwright.maxActiveContexts > 0) {
|
|
3647
|
+
await evictIdlePlaywrightContextsToLimit(
|
|
3648
|
+
Math.max(1, config.playwright.maxActiveContexts - 1)
|
|
3649
|
+
).catch(() => {
|
|
3650
|
+
});
|
|
3651
|
+
}
|
|
3628
3652
|
const profilePath = getAccountProfilePath(account.id);
|
|
3629
3653
|
const fingerprint = getFingerprintProfile(account.id);
|
|
3630
3654
|
const { engine, channel } = resolveBrowserEngine(browserType);
|
|
@@ -3893,7 +3917,7 @@ async function initPlaywrightForAccount(rawAccount, headless = config.playwright
|
|
|
3893
3917
|
if (!acctPage.isClosed()) {
|
|
3894
3918
|
try {
|
|
3895
3919
|
const currentUrl = new URL(acctPage.url());
|
|
3896
|
-
if (currentUrl.origin !== qwenOrigin() || currentUrl.pathname
|
|
3920
|
+
if (currentUrl.origin !== qwenOrigin() || currentUrl.pathname.includes("/auth") || currentUrl.pathname.includes("/login") || currentUrl.pathname.includes("_____tmd_____")) {
|
|
3897
3921
|
await acctPage.goto(qwenUrl("/"), {
|
|
3898
3922
|
waitUntil: "domcontentloaded",
|
|
3899
3923
|
timeout: config.timeouts.navigation
|
|
@@ -3911,6 +3935,8 @@ async function initPlaywrightForAccount(rawAccount, headless = config.playwright
|
|
|
3911
3935
|
} finally {
|
|
3912
3936
|
release();
|
|
3913
3937
|
}
|
|
3938
|
+
await evictIdlePlaywrightContextsToLimit().catch(() => {
|
|
3939
|
+
});
|
|
3914
3940
|
})();
|
|
3915
3941
|
try {
|
|
3916
3942
|
await initPromise;
|
|
@@ -5413,7 +5439,11 @@ function priorityOrderForEviction(accountIds) {
|
|
|
5413
5439
|
const ranked = getAccountsByPriority(accountIds.map((id) => ({ id })));
|
|
5414
5440
|
const rank = /* @__PURE__ */ new Map();
|
|
5415
5441
|
for (const [index, account] of ranked.entries()) {
|
|
5416
|
-
|
|
5442
|
+
if (getAccountCooldownInfo(account.id)) {
|
|
5443
|
+
rank.set(account.id, Number.MAX_SAFE_INTEGER);
|
|
5444
|
+
} else {
|
|
5445
|
+
rank.set(account.id, index);
|
|
5446
|
+
}
|
|
5417
5447
|
}
|
|
5418
5448
|
return orderContextsForEviction(
|
|
5419
5449
|
accountIds,
|
|
@@ -5421,14 +5451,15 @@ function priorityOrderForEviction(accountIds) {
|
|
|
5421
5451
|
(id) => lastAccountActivity.get(id) ?? 0
|
|
5422
5452
|
);
|
|
5423
5453
|
}
|
|
5424
|
-
async function evictIdlePlaywrightContextsToLimit() {
|
|
5425
|
-
const
|
|
5426
|
-
if (
|
|
5454
|
+
async function evictIdlePlaywrightContextsToLimit(targetLimit) {
|
|
5455
|
+
const configuredMax = config.playwright.maxActiveContexts;
|
|
5456
|
+
if (configuredMax <= 0) return 0;
|
|
5457
|
+
const max = targetLimit !== void 0 ? Math.max(0, targetLimit) : configuredMax;
|
|
5427
5458
|
if (accountPages.size <= max) return 0;
|
|
5428
5459
|
const candidates = priorityOrderForEviction(
|
|
5429
5460
|
Array.from(accountPages.keys()).filter((accountId) => {
|
|
5430
5461
|
if (isAccountServingStream(accountId)) return false;
|
|
5431
|
-
if (
|
|
5462
|
+
if (hasActiveAccountLease(accountId)) return false;
|
|
5432
5463
|
const mutex = accountMutexes.get(accountId);
|
|
5433
5464
|
return mutex?.isIdle();
|
|
5434
5465
|
})
|
|
@@ -5441,6 +5472,7 @@ async function evictIdlePlaywrightContextsToLimit() {
|
|
|
5441
5472
|
for (const candidate of candidates) {
|
|
5442
5473
|
if (accountPages.size <= max) break;
|
|
5443
5474
|
if (isAccountServingStream(candidate.accountId)) continue;
|
|
5475
|
+
if (hasActiveAccountLease(candidate.accountId)) continue;
|
|
5444
5476
|
const mutex = accountMutexes.get(candidate.accountId);
|
|
5445
5477
|
if (!mutex?.isIdle()) continue;
|
|
5446
5478
|
await closePlaywrightForAccount(candidate.accountId).catch((error) => {
|
|
@@ -5543,10 +5575,6 @@ async function closePlaywrightForAccount(accountId) {
|
|
|
5543
5575
|
release();
|
|
5544
5576
|
}
|
|
5545
5577
|
}
|
|
5546
|
-
function isAccountRecentlyActive(accountId, maxIdleMs = 3e5) {
|
|
5547
|
-
const last = lastAccountActivity.get(accountId) ?? 0;
|
|
5548
|
-
return last > 0 && Date.now() - last < maxIdleMs;
|
|
5549
|
-
}
|
|
5550
5578
|
var requireLocal, contextInitHooks, ACCOUNT_MUTEX_MAX_HOLD_MS, accountMutexes, accountContexts, accountPages, inFlightAccountInits, headerCaches, HEADER_CACHE_TTL, COOKIE_CACHE_TTL, cookieCaches, lastAccountActivity, lastKeepAliveNavigation, lastProactiveTokenRefresh, profileResetQueue, profileResetChain, closingAllPlaywright, sleep2, HEADER_CAPTURE_SETTLE_MS, PLAYWRIGHT_MUTEX_WAIT_MS, ACCOUNT_PAGE_OPERATION_TIMEOUT_MS, SESSION_PROBE_NAVIGATION_TIMEOUT_MS, HEADER_CAPTURE_TRIGGER_GRACE_MS, FIRST_TRIGGER_GRACE_MS, HEADER_CAPTURE_TRIGGER_ATTEMPTS, CHAT_INPUT_APPEAR_TIMEOUT_MS, CHAT_INPUT_ACTION_TIMEOUT_MS, PROFILE_RESET_TIMEOUT_MS;
|
|
5551
5579
|
var init_playwright = __esm({
|
|
5552
5580
|
"src/services/playwright.ts"() {
|
package/dist/delete-chats.js
CHANGED
|
@@ -2185,6 +2185,26 @@ function clearAccountCooldown(accountId) {
|
|
|
2185
2185
|
}
|
|
2186
2186
|
}
|
|
2187
2187
|
}
|
|
2188
|
+
function getAccountCooldownInfo(accountId) {
|
|
2189
|
+
const entry = cooldowns.get(accountId);
|
|
2190
|
+
if (!entry) return null;
|
|
2191
|
+
const remaining = entry.until - Date.now();
|
|
2192
|
+
if (remaining <= 0) {
|
|
2193
|
+
cooldowns.delete(accountId);
|
|
2194
|
+
if (accountId !== "global") {
|
|
2195
|
+
try {
|
|
2196
|
+
updateAccountCooldown(accountId, 0, null);
|
|
2197
|
+
} catch (err) {
|
|
2198
|
+
console.error(
|
|
2199
|
+
`\u274C [AccountManager] Failed to clear expired cooldown in DB:`,
|
|
2200
|
+
err.message
|
|
2201
|
+
);
|
|
2202
|
+
}
|
|
2203
|
+
}
|
|
2204
|
+
return null;
|
|
2205
|
+
}
|
|
2206
|
+
return { onCooldown: true, remainingMs: remaining, reason: entry.reason };
|
|
2207
|
+
}
|
|
2188
2208
|
function markAccountHeadersReady(accountId) {
|
|
2189
2209
|
if (!accountId || accountId === "global") return;
|
|
2190
2210
|
headersReadyAccounts.add(accountId);
|
|
@@ -4337,14 +4357,15 @@ async function getBasicHeaders(accountId) {
|
|
|
4337
4357
|
`\u26A0\uFE0F [Playwright] Header refresh failed for ${accountId}; retaining the previous valid cache: ${getErrorMessage(error)}`
|
|
4338
4358
|
);
|
|
4339
4359
|
}
|
|
4340
|
-
} else if (hadUsableHeaders && headersAge > HEADER_CACHE_TTL * HEADER_REFRESH_THRESHOLD && !cache.refreshInProgress
|
|
4341
|
-
|
|
4360
|
+
} else if (hadUsableHeaders && headersAge > HEADER_CACHE_TTL * HEADER_REFRESH_THRESHOLD && !cache.refreshInProgress && // Header capture types into the chat input and sends a probe message on
|
|
4361
|
+
// the account's page. Doing that while the account is serving a stream
|
|
4362
|
+
// would mutate the live conversation (and can navigate the SPA), so the
|
|
4363
|
+
// proactive refresh waits until the account has no active lease.
|
|
4364
|
+
!hasActiveAccountLease(accountId)) {
|
|
4342
4365
|
refreshHeadersInternal(accountId).catch((error) => {
|
|
4343
4366
|
console.warn(
|
|
4344
4367
|
`\u26A0\uFE0F [Playwright] Background header refresh failed for ${accountId}: ${getErrorMessage(error)}`
|
|
4345
4368
|
);
|
|
4346
|
-
}).finally(() => {
|
|
4347
|
-
cache.refreshInProgress = false;
|
|
4348
4369
|
});
|
|
4349
4370
|
}
|
|
4350
4371
|
if (!hasRequiredQwenHeaders(cache.headers)) {
|
|
@@ -4482,8 +4503,12 @@ async function initPlaywrightForAccount(rawAccount, headless = config.playwright
|
|
|
4482
4503
|
if (accountPages.has(account.id)) {
|
|
4483
4504
|
return;
|
|
4484
4505
|
}
|
|
4485
|
-
|
|
4486
|
-
|
|
4506
|
+
if (config.playwright.maxActiveContexts > 0) {
|
|
4507
|
+
await evictIdlePlaywrightContextsToLimit(
|
|
4508
|
+
Math.max(1, config.playwright.maxActiveContexts - 1)
|
|
4509
|
+
).catch(() => {
|
|
4510
|
+
});
|
|
4511
|
+
}
|
|
4487
4512
|
const profilePath = getAccountProfilePath(account.id);
|
|
4488
4513
|
const fingerprint = getFingerprintProfile(account.id);
|
|
4489
4514
|
const { engine, channel } = resolveBrowserEngine(browserType);
|
|
@@ -4752,7 +4777,7 @@ async function initPlaywrightForAccount(rawAccount, headless = config.playwright
|
|
|
4752
4777
|
if (!acctPage.isClosed()) {
|
|
4753
4778
|
try {
|
|
4754
4779
|
const currentUrl = new URL(acctPage.url());
|
|
4755
|
-
if (currentUrl.origin !== qwenOrigin() || currentUrl.pathname
|
|
4780
|
+
if (currentUrl.origin !== qwenOrigin() || currentUrl.pathname.includes("/auth") || currentUrl.pathname.includes("/login") || currentUrl.pathname.includes("_____tmd_____")) {
|
|
4756
4781
|
await acctPage.goto(qwenUrl("/"), {
|
|
4757
4782
|
waitUntil: "domcontentloaded",
|
|
4758
4783
|
timeout: config.timeouts.navigation
|
|
@@ -4770,6 +4795,8 @@ async function initPlaywrightForAccount(rawAccount, headless = config.playwright
|
|
|
4770
4795
|
} finally {
|
|
4771
4796
|
release();
|
|
4772
4797
|
}
|
|
4798
|
+
await evictIdlePlaywrightContextsToLimit().catch(() => {
|
|
4799
|
+
});
|
|
4773
4800
|
})();
|
|
4774
4801
|
try {
|
|
4775
4802
|
await initPromise;
|
|
@@ -6538,19 +6565,26 @@ async function refreshHeadersInternal(accountId, timeoutMs = config.timeouts.hea
|
|
|
6538
6565
|
await executeReauth();
|
|
6539
6566
|
} else {
|
|
6540
6567
|
try {
|
|
6541
|
-
|
|
6542
|
-
|
|
6543
|
-
|
|
6544
|
-
|
|
6545
|
-
|
|
6546
|
-
|
|
6547
|
-
|
|
6548
|
-
|
|
6549
|
-
|
|
6550
|
-
|
|
6568
|
+
const currentUrl = typeof page.url === "function" ? page.url() : "";
|
|
6569
|
+
const needsNavigation = !currentUrl.startsWith(qwenOrigin()) || currentUrl.includes("/auth") || currentUrl.includes("/login") || currentUrl.includes("_____tmd_____");
|
|
6570
|
+
if (needsNavigation) {
|
|
6571
|
+
await page.goto(qwenUrl("/"), {
|
|
6572
|
+
waitUntil: "domcontentloaded",
|
|
6573
|
+
timeout: Math.min(
|
|
6574
|
+
config.timeouts.navigation,
|
|
6575
|
+
boundedTimeoutMs,
|
|
6576
|
+
SESSION_PROBE_NAVIGATION_TIMEOUT_MS
|
|
6577
|
+
)
|
|
6578
|
+
});
|
|
6579
|
+
await sleep2(2e3);
|
|
6580
|
+
}
|
|
6581
|
+
const url = typeof page.url === "function" ? page.url() : "";
|
|
6551
6582
|
const isAuthUrl = url.includes("auth") || url.includes("login");
|
|
6552
6583
|
if (isAuthUrl) {
|
|
6553
|
-
await
|
|
6584
|
+
const refreshed = await refreshAccountToken(accountId);
|
|
6585
|
+
if (!refreshed.success) {
|
|
6586
|
+
await executeReauth();
|
|
6587
|
+
}
|
|
6554
6588
|
}
|
|
6555
6589
|
} catch (navErr) {
|
|
6556
6590
|
console.warn(
|
|
@@ -6607,7 +6641,7 @@ async function refreshHeadersInternal(accountId, timeoutMs = config.timeouts.hea
|
|
|
6607
6641
|
if (capturedPage && !capturedPage.isClosed()) {
|
|
6608
6642
|
try {
|
|
6609
6643
|
const currentUrl = new URL(capturedPage.url());
|
|
6610
|
-
if (currentUrl.origin !== qwenOrigin() || currentUrl.pathname
|
|
6644
|
+
if (currentUrl.origin !== qwenOrigin() || currentUrl.pathname.includes("/auth") || currentUrl.pathname.includes("/login") || currentUrl.pathname.includes("_____tmd_____")) {
|
|
6611
6645
|
await capturedPage.goto(qwenUrl("/"), {
|
|
6612
6646
|
waitUntil: "domcontentloaded",
|
|
6613
6647
|
timeout: Math.min(config.timeouts.navigation, boundedTimeoutMs)
|
|
@@ -6923,7 +6957,11 @@ function priorityOrderForEviction(accountIds) {
|
|
|
6923
6957
|
const ranked = getAccountsByPriority(accountIds.map((id) => ({ id })));
|
|
6924
6958
|
const rank = /* @__PURE__ */ new Map();
|
|
6925
6959
|
for (const [index, account] of ranked.entries()) {
|
|
6926
|
-
|
|
6960
|
+
if (getAccountCooldownInfo(account.id)) {
|
|
6961
|
+
rank.set(account.id, Number.MAX_SAFE_INTEGER);
|
|
6962
|
+
} else {
|
|
6963
|
+
rank.set(account.id, index);
|
|
6964
|
+
}
|
|
6927
6965
|
}
|
|
6928
6966
|
return orderContextsForEviction(
|
|
6929
6967
|
accountIds,
|
|
@@ -6960,14 +6998,15 @@ async function closeIdlePlaywrightAccounts(idleMs) {
|
|
|
6960
6998
|
}
|
|
6961
6999
|
return closed;
|
|
6962
7000
|
}
|
|
6963
|
-
async function evictIdlePlaywrightContextsToLimit() {
|
|
6964
|
-
const
|
|
6965
|
-
if (
|
|
7001
|
+
async function evictIdlePlaywrightContextsToLimit(targetLimit) {
|
|
7002
|
+
const configuredMax = config.playwright.maxActiveContexts;
|
|
7003
|
+
if (configuredMax <= 0) return 0;
|
|
7004
|
+
const max = targetLimit !== void 0 ? Math.max(0, targetLimit) : configuredMax;
|
|
6966
7005
|
if (accountPages.size <= max) return 0;
|
|
6967
7006
|
const candidates = priorityOrderForEviction(
|
|
6968
7007
|
Array.from(accountPages.keys()).filter((accountId) => {
|
|
6969
7008
|
if (isAccountServingStream(accountId)) return false;
|
|
6970
|
-
if (
|
|
7009
|
+
if (hasActiveAccountLease(accountId)) return false;
|
|
6971
7010
|
const mutex = accountMutexes.get(accountId);
|
|
6972
7011
|
return mutex?.isIdle();
|
|
6973
7012
|
})
|
|
@@ -6980,6 +7019,7 @@ async function evictIdlePlaywrightContextsToLimit() {
|
|
|
6980
7019
|
for (const candidate of candidates) {
|
|
6981
7020
|
if (accountPages.size <= max) break;
|
|
6982
7021
|
if (isAccountServingStream(candidate.accountId)) continue;
|
|
7022
|
+
if (hasActiveAccountLease(candidate.accountId)) continue;
|
|
6983
7023
|
const mutex = accountMutexes.get(candidate.accountId);
|
|
6984
7024
|
if (!mutex?.isIdle()) continue;
|
|
6985
7025
|
await closePlaywrightForAccount(candidate.accountId).catch((error) => {
|
|
@@ -7818,6 +7858,7 @@ var init_model_registry = __esm({
|
|
|
7818
7858
|
var captcha_coordinator_exports = {};
|
|
7819
7859
|
__export(captcha_coordinator_exports, {
|
|
7820
7860
|
isCaptchaRecoveryActive: () => isCaptchaRecoveryActive,
|
|
7861
|
+
isCaptchaRecoveryInBackoff: () => isCaptchaRecoveryInBackoff,
|
|
7821
7862
|
recoverBaxiaCaptcha: () => recoverBaxiaCaptcha,
|
|
7822
7863
|
solveChallengeOnPage: () => solveChallengeOnPage
|
|
7823
7864
|
});
|
|
@@ -7856,6 +7897,11 @@ async function solveChallengeOnPage(page, challengeUrl, waitForMs = config.captc
|
|
|
7856
7897
|
}
|
|
7857
7898
|
}
|
|
7858
7899
|
}
|
|
7900
|
+
function isCaptchaRecoveryInBackoff(accountId) {
|
|
7901
|
+
if (!accountId) return false;
|
|
7902
|
+
const lastFailure = lastFailedRecoveryAt.get(accountId) ?? 0;
|
|
7903
|
+
return Date.now() - lastFailure < FAILED_RECOVERY_BACKOFF_MS;
|
|
7904
|
+
}
|
|
7859
7905
|
async function recoverBaxiaCaptcha(accountId, label, options = {}) {
|
|
7860
7906
|
if (!config.captcha.enabled || !accountId) return false;
|
|
7861
7907
|
const solver = "baxia";
|
|
@@ -7873,17 +7919,34 @@ async function recoverBaxiaCaptcha(accountId, label, options = {}) {
|
|
|
7873
7919
|
const challengeUrl = options.challengeBody ? extractBaxiaChallengeUrl(options.challengeBody, config.qwen.baseUrl) : null;
|
|
7874
7920
|
activeCaptchaRecoveries.add(accountId);
|
|
7875
7921
|
try {
|
|
7876
|
-
const {
|
|
7877
|
-
|
|
7878
|
-
accountId,
|
|
7879
|
-
"Account stream interrupted by captcha challenge recovery"
|
|
7880
|
-
);
|
|
7881
|
-
} catch {
|
|
7882
|
-
}
|
|
7883
|
-
try {
|
|
7922
|
+
const { hasActiveBrowserStreamsForAccount: hasActiveBrowserStreamsForAccount2 } = await Promise.resolve().then(() => (init_qwen(), qwen_exports));
|
|
7923
|
+
const hasConcurrentStream = hasActiveBrowserStreamsForAccount2(accountId);
|
|
7884
7924
|
const solved = await withAccountPage(
|
|
7885
7925
|
accountId,
|
|
7886
|
-
(page) =>
|
|
7926
|
+
async (page) => {
|
|
7927
|
+
if (hasConcurrentStream) {
|
|
7928
|
+
const solverOptions = {
|
|
7929
|
+
maxAttempts: config.captcha.maxAttempts,
|
|
7930
|
+
retryDelayMs: config.captcha.retryDelayMs,
|
|
7931
|
+
settleMs: config.captcha.settleMs
|
|
7932
|
+
};
|
|
7933
|
+
if (await solveBaxiaCaptcha(page, { ...solverOptions, waitForMs: 0 })) {
|
|
7934
|
+
return true;
|
|
7935
|
+
}
|
|
7936
|
+
const ctx = typeof page.context === "function" ? page.context() : null;
|
|
7937
|
+
if (ctx && typeof ctx.newPage === "function") {
|
|
7938
|
+
const tempPage = await ctx.newPage();
|
|
7939
|
+
try {
|
|
7940
|
+
return await solveChallengeOnPage(tempPage, challengeUrl);
|
|
7941
|
+
} finally {
|
|
7942
|
+
await tempPage.close({ runBeforeUnload: false }).catch(() => {
|
|
7943
|
+
});
|
|
7944
|
+
}
|
|
7945
|
+
}
|
|
7946
|
+
return false;
|
|
7947
|
+
}
|
|
7948
|
+
return await solveChallengeOnPage(page, challengeUrl);
|
|
7949
|
+
},
|
|
7887
7950
|
solverOperationTimeoutMs,
|
|
7888
7951
|
solverOperationTimeoutMs,
|
|
7889
7952
|
false
|
|
@@ -8682,6 +8745,7 @@ __export(qwen_exports, {
|
|
|
8682
8745
|
getLogicalThreadState: () => getLogicalThreadState,
|
|
8683
8746
|
getQwenErrorCode: () => getQwenErrorCode,
|
|
8684
8747
|
getSessionParent: () => getSessionParent,
|
|
8748
|
+
hasActiveBrowserStreamsForAccount: () => hasActiveBrowserStreamsForAccount,
|
|
8685
8749
|
invalidateLogicalThreadParent: () => invalidateLogicalThreadParent,
|
|
8686
8750
|
isChatSessionActive: () => isChatSessionActive,
|
|
8687
8751
|
isRetryableFetchErrorMessage: () => isRetryableFetchErrorMessage,
|
|
@@ -8703,6 +8767,14 @@ __export(qwen_exports, {
|
|
|
8703
8767
|
});
|
|
8704
8768
|
import crypto5 from "crypto";
|
|
8705
8769
|
import { v4 as uuidv43 } from "uuid";
|
|
8770
|
+
function hasActiveBrowserStreamsForAccount(accountId) {
|
|
8771
|
+
for (const state of browserStreamStates.values()) {
|
|
8772
|
+
if (state.accountId === accountId && !state.done) {
|
|
8773
|
+
return true;
|
|
8774
|
+
}
|
|
8775
|
+
}
|
|
8776
|
+
return false;
|
|
8777
|
+
}
|
|
8706
8778
|
function abortActiveBrowserStreamsForAccount(accountId, reason = "Account browser stream interrupted (page context unloaded)") {
|
|
8707
8779
|
let count = 0;
|
|
8708
8780
|
for (const [requestId, state] of browserStreamStates) {
|
|
@@ -9480,7 +9552,7 @@ async function createQwenBrowserResponse(accountId, url, method, headers, body,
|
|
|
9480
9552
|
const onFrameNavigated = (frame) => {
|
|
9481
9553
|
if (!settled && typeof page.mainFrame === "function" && frame === page.mainFrame()) {
|
|
9482
9554
|
const url2 = typeof frame.url === "function" ? frame.url() : String(frame.url || "");
|
|
9483
|
-
if (url2.startsWith(qwenOrigin()) && !url2.includes("/auth") && !url2.includes("_____tmd_____") && !url2.includes("/punish")) {
|
|
9555
|
+
if (url2.startsWith(qwenOrigin()) && !url2.includes("/auth") && !url2.includes("/login") && !url2.includes("_____tmd_____") && !url2.includes("/punish")) {
|
|
9484
9556
|
return;
|
|
9485
9557
|
}
|
|
9486
9558
|
handleBrowserStreamEvent(requestId, {
|
|
@@ -9501,10 +9573,12 @@ async function createQwenBrowserResponse(accountId, url, method, headers, body,
|
|
|
9501
9573
|
};
|
|
9502
9574
|
page.on("framenavigated", onFrameNavigated);
|
|
9503
9575
|
page.on("close", onPageClosed);
|
|
9576
|
+
page.on("crash", onPageClosed);
|
|
9504
9577
|
pageCleanup = () => {
|
|
9505
9578
|
try {
|
|
9506
9579
|
page.off?.("framenavigated", onFrameNavigated);
|
|
9507
9580
|
page.off?.("close", onPageClosed);
|
|
9581
|
+
page.off?.("crash", onPageClosed);
|
|
9508
9582
|
} catch {
|
|
9509
9583
|
}
|
|
9510
9584
|
};
|
|
@@ -11292,6 +11366,7 @@ async function deleteChatsForConfiguredAccounts(keepBrowserOpen = false) {
|
|
|
11292
11366
|
const account = accounts[i];
|
|
11293
11367
|
const currentIdx = i + 1;
|
|
11294
11368
|
const totalCount = accounts.length;
|
|
11369
|
+
const wasInitialized = isPlaywrightInitialized(account.id);
|
|
11295
11370
|
try {
|
|
11296
11371
|
const ok = await deleteChatsForAccount(account, currentIdx, totalCount);
|
|
11297
11372
|
if (ok) succeeded++;
|
|
@@ -11301,7 +11376,7 @@ async function deleteChatsForConfiguredAccounts(keepBrowserOpen = false) {
|
|
|
11301
11376
|
error instanceof Error ? error.message : String(error)
|
|
11302
11377
|
);
|
|
11303
11378
|
} finally {
|
|
11304
|
-
if (!keepBrowserOpen) {
|
|
11379
|
+
if ((!keepBrowserOpen || !wasInitialized) && !isAuthMockEnabled()) {
|
|
11305
11380
|
const { closePlaywrightForAccount: closePlaywrightForAccount2 } = await Promise.resolve().then(() => (init_playwright(), playwright_exports));
|
|
11306
11381
|
await closePlaywrightForAccount2(account.id).catch(() => {
|
|
11307
11382
|
});
|