qwenproxy-cli 1.6.1 → 1.6.2
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 +7 -3
- package/dist/delete-chats.js +325 -8
- package/dist/index.js +667 -94
- package/dist/login.js +383 -9
- package/dist/reset-cooldowns.js +17 -3
- package/package.json +3 -3
- package/src/core/accounts.ts +1 -1
- package/src/core/version.ts +1 -1
- package/src/login.ts +90 -4
- package/src/routes/chat/account.ts +11 -4
- package/src/routes/chat/retry-policy.ts +45 -3
- package/src/routes/chat/streaming.ts +27 -0
- package/src/services/playwright.ts +378 -4
- package/src/services/qwen.ts +22 -6
- package/src/tui/views/accounts-view.ts +313 -96
- package/src/utils/overload-detector.ts +55 -0
package/dist/clean-cache.js
CHANGED
|
@@ -781,7 +781,7 @@ function addAccountsBatch(entries) {
|
|
|
781
781
|
}
|
|
782
782
|
return { added, skipped, invalid };
|
|
783
783
|
}
|
|
784
|
-
function addAccount(email, password, id) {
|
|
784
|
+
function addAccount(email, password = "", id) {
|
|
785
785
|
if (!email || typeof email !== "string" || email.trim().length === 0) {
|
|
786
786
|
throw new Error("Email is required");
|
|
787
787
|
}
|
|
@@ -2963,6 +2963,10 @@ async function clearVisibleChallenge(page) {
|
|
|
2963
2963
|
"button[aria-label*='Close' i]",
|
|
2964
2964
|
"button[aria-label*='Fechar' i]",
|
|
2965
2965
|
".index-module__whats-new-modal-close",
|
|
2966
|
+
".age-confirmation-modal button",
|
|
2967
|
+
".age-confirmation-modal .qwen-chat-v2-btn-black",
|
|
2968
|
+
"button:has-text('Continuar')",
|
|
2969
|
+
"button:has-text('Continue')",
|
|
2966
2970
|
"button:has-text('Cancel')",
|
|
2967
2971
|
"button:has-text('Cancelar')",
|
|
2968
2972
|
"button:has-text('I understand')",
|
|
@@ -5322,8 +5326,8 @@ var init_playwright = __esm({
|
|
|
5322
5326
|
PLAYWRIGHT_MUTEX_WAIT_MS = 6e4;
|
|
5323
5327
|
ACCOUNT_PAGE_OPERATION_TIMEOUT_MS = config.timeouts.page;
|
|
5324
5328
|
SESSION_PROBE_NAVIGATION_TIMEOUT_MS = 15e3;
|
|
5325
|
-
HEADER_CAPTURE_TRIGGER_GRACE_MS =
|
|
5326
|
-
FIRST_TRIGGER_GRACE_MS =
|
|
5329
|
+
HEADER_CAPTURE_TRIGGER_GRACE_MS = 2e4;
|
|
5330
|
+
FIRST_TRIGGER_GRACE_MS = 12e3;
|
|
5327
5331
|
HEADER_CAPTURE_TRIGGER_ATTEMPTS = 3;
|
|
5328
5332
|
CHAT_INPUT_APPEAR_TIMEOUT_MS = 15e3;
|
|
5329
5333
|
CHAT_INPUT_ACTION_TIMEOUT_MS = 1e4;
|
package/dist/delete-chats.js
CHANGED
|
@@ -819,7 +819,7 @@ function addAccountsBatch(entries) {
|
|
|
819
819
|
}
|
|
820
820
|
return { added, skipped, invalid };
|
|
821
821
|
}
|
|
822
|
-
function addAccount(email, password, id) {
|
|
822
|
+
function addAccount(email, password = "", id) {
|
|
823
823
|
if (!email || typeof email !== "string" || email.trim().length === 0) {
|
|
824
824
|
throw new Error("Email is required");
|
|
825
825
|
}
|
|
@@ -3160,6 +3160,7 @@ var playwright_exports = {};
|
|
|
3160
3160
|
__export(playwright_exports, {
|
|
3161
3161
|
assertAntiBotHeaders: () => assertAntiBotHeaders,
|
|
3162
3162
|
buildChromiumLaunchArgs: () => buildChromiumLaunchArgs,
|
|
3163
|
+
cancelEmailOtpLogin: () => cancelEmailOtpLogin,
|
|
3163
3164
|
captureQwenHeaders: () => captureQwenHeaders,
|
|
3164
3165
|
classifyQwenAuthError: () => classifyQwenAuthError,
|
|
3165
3166
|
cleanupOrphanProfiles: () => cleanupOrphanProfiles,
|
|
@@ -3200,8 +3201,10 @@ __export(playwright_exports, {
|
|
|
3200
3201
|
removePlaywrightProfile: () => removePlaywrightProfile,
|
|
3201
3202
|
saveStorageState: () => saveStorageState,
|
|
3202
3203
|
schedulePlaywrightProfileReset: () => schedulePlaywrightProfileReset,
|
|
3204
|
+
startEmailOtpLogin: () => startEmailOtpLogin,
|
|
3203
3205
|
unregisterPlaywrightAccountForTests: () => unregisterPlaywrightAccountForTests,
|
|
3204
3206
|
validateAccountLogin: () => validateAccountLogin,
|
|
3207
|
+
verifyEmailOtpLogin: () => verifyEmailOtpLogin,
|
|
3205
3208
|
withAccountPage: () => withAccountPage
|
|
3206
3209
|
});
|
|
3207
3210
|
import { chromium as chromium2 } from "patchright";
|
|
@@ -3543,6 +3546,10 @@ async function clearVisibleChallenge(page) {
|
|
|
3543
3546
|
"button[aria-label*='Close' i]",
|
|
3544
3547
|
"button[aria-label*='Fechar' i]",
|
|
3545
3548
|
".index-module__whats-new-modal-close",
|
|
3549
|
+
".age-confirmation-modal button",
|
|
3550
|
+
".age-confirmation-modal .qwen-chat-v2-btn-black",
|
|
3551
|
+
"button:has-text('Continuar')",
|
|
3552
|
+
"button:has-text('Continue')",
|
|
3546
3553
|
"button:has-text('Cancel')",
|
|
3547
3554
|
"button:has-text('Cancelar')",
|
|
3548
3555
|
"button:has-text('I understand')",
|
|
@@ -4737,6 +4744,292 @@ async function validateAccountLogin(rawAccount, headless = true, browserType = "
|
|
|
4737
4744
|
release();
|
|
4738
4745
|
}
|
|
4739
4746
|
}
|
|
4747
|
+
async function startEmailOtpLogin(email, options = {}) {
|
|
4748
|
+
const normalizedEmail = email.trim().toLowerCase();
|
|
4749
|
+
if (!normalizedEmail || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(normalizedEmail)) {
|
|
4750
|
+
return { success: false, error: "Formato de e-mail inv\xE1lido" };
|
|
4751
|
+
}
|
|
4752
|
+
const { listAccounts: listAccounts2 } = await Promise.resolve().then(() => (init_accounts(), accounts_exports));
|
|
4753
|
+
if (listAccounts2().some((a) => a.email.toLowerCase() === normalizedEmail)) {
|
|
4754
|
+
return {
|
|
4755
|
+
success: false,
|
|
4756
|
+
error: `Uma conta com o e-mail "${normalizedEmail}" j\xE1 est\xE1 cadastrada.`
|
|
4757
|
+
};
|
|
4758
|
+
}
|
|
4759
|
+
if (process.env.TEST_MOCK_QWEN_AUTH === "true" && process.env.NODE_ENV !== "production") {
|
|
4760
|
+
const mockSessionId = "mock-otp-" + Date.now();
|
|
4761
|
+
mockOtpSessions.set(mockSessionId, normalizedEmail);
|
|
4762
|
+
return { success: true, sessionId: mockSessionId };
|
|
4763
|
+
}
|
|
4764
|
+
const accountId = crypto3.randomUUID();
|
|
4765
|
+
const sessionId = accountId;
|
|
4766
|
+
const profilePath = getAccountProfilePath(accountId);
|
|
4767
|
+
const fingerprint = getFingerprintProfile(accountId);
|
|
4768
|
+
const browserType = options.browserType ?? config.playwright.browser;
|
|
4769
|
+
const { engine, channel } = resolveBrowserEngine(browserType);
|
|
4770
|
+
const headless = options.headless ?? config.playwright.headless;
|
|
4771
|
+
const launchOptions = {
|
|
4772
|
+
headless,
|
|
4773
|
+
channel,
|
|
4774
|
+
userAgent: fingerprint.userAgent,
|
|
4775
|
+
locale: fingerprint.locale,
|
|
4776
|
+
timezoneId: fingerprint.timezoneId,
|
|
4777
|
+
viewport: fingerprint.viewport,
|
|
4778
|
+
screen: fingerprint.viewport,
|
|
4779
|
+
deviceScaleFactor: 1,
|
|
4780
|
+
isMobile: false,
|
|
4781
|
+
hasTouch: false,
|
|
4782
|
+
colorScheme: "light",
|
|
4783
|
+
extraHTTPHeaders: {
|
|
4784
|
+
"sec-ch-ua": fingerprint.secChUa,
|
|
4785
|
+
"sec-ch-ua-mobile": "?0",
|
|
4786
|
+
"sec-ch-ua-platform": '"Windows"'
|
|
4787
|
+
},
|
|
4788
|
+
ignoreDefaultArgs: ["--enable-automation", "--enable-blink-features"],
|
|
4789
|
+
args: buildChromiumLaunchArgs(fingerprint.viewport)
|
|
4790
|
+
};
|
|
4791
|
+
let acctContext;
|
|
4792
|
+
try {
|
|
4793
|
+
acctContext = await withTimeout(
|
|
4794
|
+
engine.launchPersistentContext(profilePath, launchOptions),
|
|
4795
|
+
3e4,
|
|
4796
|
+
`O navegador n\xE3o iniciou em 30s para a conta ${maskEmail(normalizedEmail)}.`
|
|
4797
|
+
);
|
|
4798
|
+
} catch (launchErr) {
|
|
4799
|
+
if (launchErr?.message?.includes("Executable doesn't exist")) {
|
|
4800
|
+
autoInstallPlaywrightChromium();
|
|
4801
|
+
acctContext = await withTimeout(
|
|
4802
|
+
engine.launchPersistentContext(profilePath, launchOptions),
|
|
4803
|
+
3e4,
|
|
4804
|
+
`O navegador n\xE3o iniciou em 30s para a conta ${maskEmail(normalizedEmail)}.`
|
|
4805
|
+
);
|
|
4806
|
+
} else {
|
|
4807
|
+
return { success: false, error: launchErr?.message || String(launchErr) };
|
|
4808
|
+
}
|
|
4809
|
+
}
|
|
4810
|
+
try {
|
|
4811
|
+
await acctContext.addInitScript(getStealthScript(fingerprint));
|
|
4812
|
+
const existingPages = acctContext.pages().filter((p) => !p.isClosed());
|
|
4813
|
+
const acctPage = existingPages.find((p) => p.url().startsWith(qwenOrigin())) ?? existingPages[0] ?? await acctContext.newPage();
|
|
4814
|
+
await acctPage.goto(qwenUrl("/auth?mode=register"), {
|
|
4815
|
+
waitUntil: "domcontentloaded",
|
|
4816
|
+
timeout: Math.min(config.timeouts.navigation, 2e4)
|
|
4817
|
+
}).catch(() => {
|
|
4818
|
+
});
|
|
4819
|
+
await sleep2(1e3);
|
|
4820
|
+
await clearVisibleChallenge(acctPage);
|
|
4821
|
+
const requestId = crypto3.randomUUID();
|
|
4822
|
+
const evalRes = await acctPage.evaluate(
|
|
4823
|
+
async ({ email: email2, requestId: requestId2, version, timezone }) => {
|
|
4824
|
+
try {
|
|
4825
|
+
const response = await fetch("https://auth.qwen.ai/api/v2/auths/otp/email/request", {
|
|
4826
|
+
method: "POST",
|
|
4827
|
+
credentials: "include",
|
|
4828
|
+
headers: {
|
|
4829
|
+
accept: "application/json, text/plain, */*",
|
|
4830
|
+
"content-type": "application/json",
|
|
4831
|
+
source: "web",
|
|
4832
|
+
version,
|
|
4833
|
+
"x-request-origin": "https://chat.qwen.ai",
|
|
4834
|
+
timezone,
|
|
4835
|
+
"x-request-id": requestId2
|
|
4836
|
+
},
|
|
4837
|
+
body: JSON.stringify({
|
|
4838
|
+
identifier: email2,
|
|
4839
|
+
accept_terms: true,
|
|
4840
|
+
language: "pt-BR"
|
|
4841
|
+
})
|
|
4842
|
+
});
|
|
4843
|
+
const json = await response.json().catch(() => null);
|
|
4844
|
+
return { ok: response.ok, status: response.status, data: json };
|
|
4845
|
+
} catch (e) {
|
|
4846
|
+
return { ok: false, error: e.message };
|
|
4847
|
+
}
|
|
4848
|
+
},
|
|
4849
|
+
{
|
|
4850
|
+
email: normalizedEmail,
|
|
4851
|
+
requestId,
|
|
4852
|
+
version: getQwenWebVersion() || "0.3.12",
|
|
4853
|
+
timezone: (/* @__PURE__ */ new Date()).toString().split(" (")[0]
|
|
4854
|
+
}
|
|
4855
|
+
).catch((err) => ({ ok: false, error: err?.message || String(err) }));
|
|
4856
|
+
if (!evalRes.ok || evalRes.data?.success !== true) {
|
|
4857
|
+
const errorMsg = evalRes.data?.data?.details || evalRes.data?.data?.message || evalRes.data?.message || evalRes.error || "Falha ao solicitar c\xF3digo de verifica\xE7\xE3o";
|
|
4858
|
+
await closePlaywrightContextBestEffort(accountId, acctContext).catch(() => {
|
|
4859
|
+
});
|
|
4860
|
+
cleanupPlaywrightAccountState(accountId);
|
|
4861
|
+
return { success: false, error: errorMsg };
|
|
4862
|
+
}
|
|
4863
|
+
const timer = setTimeout(async () => {
|
|
4864
|
+
activeOtpSessions.delete(sessionId);
|
|
4865
|
+
await closePlaywrightContextBestEffort(accountId, acctContext).catch(() => {
|
|
4866
|
+
});
|
|
4867
|
+
cleanupPlaywrightAccountState(accountId);
|
|
4868
|
+
}, 5 * 60 * 1e3);
|
|
4869
|
+
timer.unref?.();
|
|
4870
|
+
activeOtpSessions.set(sessionId, {
|
|
4871
|
+
sessionId,
|
|
4872
|
+
accountId,
|
|
4873
|
+
email: normalizedEmail,
|
|
4874
|
+
context: acctContext,
|
|
4875
|
+
page: acctPage,
|
|
4876
|
+
fingerprint,
|
|
4877
|
+
createdAt: Date.now(),
|
|
4878
|
+
timer
|
|
4879
|
+
});
|
|
4880
|
+
return { success: true, sessionId };
|
|
4881
|
+
} catch (err) {
|
|
4882
|
+
await closePlaywrightContextBestEffort(accountId, acctContext).catch(() => {
|
|
4883
|
+
});
|
|
4884
|
+
cleanupPlaywrightAccountState(accountId);
|
|
4885
|
+
return { success: false, error: err?.message || String(err) };
|
|
4886
|
+
}
|
|
4887
|
+
}
|
|
4888
|
+
async function verifyEmailOtpLogin(sessionId, code) {
|
|
4889
|
+
const cleanCode = code.trim();
|
|
4890
|
+
if (!cleanCode) {
|
|
4891
|
+
return { success: false, error: "C\xF3digo de verifica\xE7\xE3o \xE9 obrigat\xF3rio" };
|
|
4892
|
+
}
|
|
4893
|
+
if (process.env.TEST_MOCK_QWEN_AUTH === "true" && process.env.NODE_ENV !== "production") {
|
|
4894
|
+
const mockEmail = mockOtpSessions.get(sessionId);
|
|
4895
|
+
if (!mockEmail) {
|
|
4896
|
+
return { success: false, error: "Sess\xE3o OTP inv\xE1lida ou expirada" };
|
|
4897
|
+
}
|
|
4898
|
+
if (cleanCode === "000000") {
|
|
4899
|
+
return { success: false, error: "C\xF3digo de verifica\xE7\xE3o incorreto ou expirado" };
|
|
4900
|
+
}
|
|
4901
|
+
const { addAccount: addAccount2 } = await Promise.resolve().then(() => (init_accounts(), accounts_exports));
|
|
4902
|
+
const mockAccId = "mock-otp-acc-" + Date.now();
|
|
4903
|
+
const newAccount = addAccount2(mockEmail, "", mockAccId);
|
|
4904
|
+
mockOtpSessions.delete(sessionId);
|
|
4905
|
+
return { success: true, account: newAccount };
|
|
4906
|
+
}
|
|
4907
|
+
const session = activeOtpSessions.get(sessionId);
|
|
4908
|
+
if (!session) {
|
|
4909
|
+
return { success: false, error: "Sess\xE3o OTP expirada ou n\xE3o encontrada. Solicite um novo c\xF3digo." };
|
|
4910
|
+
}
|
|
4911
|
+
if (session.page.isClosed()) {
|
|
4912
|
+
activeOtpSessions.delete(sessionId);
|
|
4913
|
+
return { success: false, error: "Navegador foi fechado. Solicite um novo c\xF3digo." };
|
|
4914
|
+
}
|
|
4915
|
+
const requestId = crypto3.randomUUID();
|
|
4916
|
+
const evalRes = await session.page.evaluate(
|
|
4917
|
+
async ({ email, code: code2, requestId: requestId2, version, timezone }) => {
|
|
4918
|
+
try {
|
|
4919
|
+
const response = await fetch("https://auth.qwen.ai/api/v2/auths/otp/email/verify", {
|
|
4920
|
+
method: "POST",
|
|
4921
|
+
credentials: "include",
|
|
4922
|
+
headers: {
|
|
4923
|
+
accept: "application/json, text/plain, */*",
|
|
4924
|
+
"content-type": "application/json",
|
|
4925
|
+
source: "web",
|
|
4926
|
+
version,
|
|
4927
|
+
"x-request-origin": "https://chat.qwen.ai",
|
|
4928
|
+
timezone,
|
|
4929
|
+
"x-request-id": requestId2
|
|
4930
|
+
},
|
|
4931
|
+
body: JSON.stringify({
|
|
4932
|
+
identifier: email,
|
|
4933
|
+
code: code2,
|
|
4934
|
+
name: null
|
|
4935
|
+
})
|
|
4936
|
+
});
|
|
4937
|
+
const json = await response.json().catch(() => null);
|
|
4938
|
+
return { ok: response.ok, status: response.status, data: json };
|
|
4939
|
+
} catch (e) {
|
|
4940
|
+
return { ok: false, error: e.message };
|
|
4941
|
+
}
|
|
4942
|
+
},
|
|
4943
|
+
{
|
|
4944
|
+
email: session.email,
|
|
4945
|
+
code: cleanCode,
|
|
4946
|
+
requestId,
|
|
4947
|
+
version: getQwenWebVersion() || "0.3.12",
|
|
4948
|
+
timezone: (/* @__PURE__ */ new Date()).toString().split(" (")[0]
|
|
4949
|
+
}
|
|
4950
|
+
).catch((err) => ({ ok: false, error: err?.message || String(err) }));
|
|
4951
|
+
if (!evalRes.ok || evalRes.data?.success !== true || !evalRes.data?.data) {
|
|
4952
|
+
const errorMsg = evalRes.data?.data?.details || evalRes.data?.data?.message || evalRes.data?.message || evalRes.error || "C\xF3digo de verifica\xE7\xE3o incorreto ou expirado";
|
|
4953
|
+
return { success: false, error: errorMsg };
|
|
4954
|
+
}
|
|
4955
|
+
const resData = evalRes.data.data;
|
|
4956
|
+
const accessToken = resData.access_token || resData.token;
|
|
4957
|
+
const refreshToken = resData.refresh_token;
|
|
4958
|
+
const userId = resData.id;
|
|
4959
|
+
try {
|
|
4960
|
+
await session.page.evaluate(({ token, rTok }) => {
|
|
4961
|
+
try {
|
|
4962
|
+
localStorage.setItem("token", token);
|
|
4963
|
+
localStorage.setItem("access_token", token);
|
|
4964
|
+
if (rTok) localStorage.setItem("refresh_token", rTok);
|
|
4965
|
+
document.cookie = `token=${encodeURIComponent(token)}; path=/; domain=.qwen.ai; max-age=31536000`;
|
|
4966
|
+
} catch {
|
|
4967
|
+
}
|
|
4968
|
+
}, { token: accessToken, rTok: refreshToken });
|
|
4969
|
+
await session.context.addCookies([
|
|
4970
|
+
{
|
|
4971
|
+
name: "token",
|
|
4972
|
+
value: accessToken,
|
|
4973
|
+
domain: ".qwen.ai",
|
|
4974
|
+
path: "/",
|
|
4975
|
+
expires: Math.floor(Date.now() / 1e3) + 31536e3,
|
|
4976
|
+
httpOnly: false,
|
|
4977
|
+
secure: true,
|
|
4978
|
+
sameSite: "Lax"
|
|
4979
|
+
}
|
|
4980
|
+
]);
|
|
4981
|
+
await session.page.goto(qwenUrl("/"), {
|
|
4982
|
+
waitUntil: "domcontentloaded",
|
|
4983
|
+
timeout: Math.min(config.timeouts.navigation, 15e3)
|
|
4984
|
+
}).catch(() => {
|
|
4985
|
+
});
|
|
4986
|
+
await sleep2(1e3);
|
|
4987
|
+
await saveStorageState(session.context, session.accountId);
|
|
4988
|
+
const { saveAuthSession: saveAuthSession2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
4989
|
+
const { parseJwtExpiry: parseJwtExpiry2 } = await Promise.resolve().then(() => (init_jwt(), jwt_exports));
|
|
4990
|
+
const exp = parseJwtExpiry2(accessToken);
|
|
4991
|
+
saveAuthSession2(session.accountId, {
|
|
4992
|
+
cookie: `token=${accessToken}`,
|
|
4993
|
+
userAgent: session.fingerprint.userAgent,
|
|
4994
|
+
bxV: "2.5.37",
|
|
4995
|
+
version: getQwenWebVersion() || "0.3.12",
|
|
4996
|
+
userId: userId || void 0,
|
|
4997
|
+
tokenExpiresAt: exp || void 0,
|
|
4998
|
+
refreshToken: refreshToken || void 0,
|
|
4999
|
+
capturedAt: Date.now()
|
|
5000
|
+
});
|
|
5001
|
+
const { addAccount: addAccount2 } = await Promise.resolve().then(() => (init_accounts(), accounts_exports));
|
|
5002
|
+
const newAccount = addAccount2(session.email, "", session.accountId);
|
|
5003
|
+
clearTimeout(session.timer);
|
|
5004
|
+
activeOtpSessions.delete(sessionId);
|
|
5005
|
+
await closePlaywrightContextBestEffort(session.accountId, session.context).catch(() => {
|
|
5006
|
+
});
|
|
5007
|
+
cleanupPlaywrightAccountState(session.accountId);
|
|
5008
|
+
return { success: true, account: newAccount };
|
|
5009
|
+
} catch (err) {
|
|
5010
|
+
clearTimeout(session.timer);
|
|
5011
|
+
activeOtpSessions.delete(sessionId);
|
|
5012
|
+
await closePlaywrightContextBestEffort(session.accountId, session.context).catch(() => {
|
|
5013
|
+
});
|
|
5014
|
+
cleanupPlaywrightAccountState(session.accountId);
|
|
5015
|
+
return { success: false, error: err?.message || String(err) };
|
|
5016
|
+
}
|
|
5017
|
+
}
|
|
5018
|
+
async function cancelEmailOtpLogin(sessionId) {
|
|
5019
|
+
if (process.env.TEST_MOCK_QWEN_AUTH === "true" && process.env.NODE_ENV !== "production") {
|
|
5020
|
+
mockOtpSessions.delete(sessionId);
|
|
5021
|
+
return;
|
|
5022
|
+
}
|
|
5023
|
+
const session = activeOtpSessions.get(sessionId);
|
|
5024
|
+
if (!session) return;
|
|
5025
|
+
clearTimeout(session.timer);
|
|
5026
|
+
activeOtpSessions.delete(sessionId);
|
|
5027
|
+
await closePlaywrightContextBestEffort(session.accountId, session.context).catch(() => {
|
|
5028
|
+
});
|
|
5029
|
+
cleanupPlaywrightAccountState(session.accountId);
|
|
5030
|
+
const { wipeAccountSessionFiles: wipeAccountSessionFiles2 } = await Promise.resolve().then(() => (init_accounts(), accounts_exports));
|
|
5031
|
+
wipeAccountSessionFiles2(session.accountId);
|
|
5032
|
+
}
|
|
4740
5033
|
function classifyQwenAuthError(code, details) {
|
|
4741
5034
|
const c = (code || "").trim().toLowerCase();
|
|
4742
5035
|
const d = (details || "").trim().toLowerCase();
|
|
@@ -6105,7 +6398,7 @@ async function withAccountPage(accountId, fn, timeoutMs = ACCOUNT_PAGE_OPERATION
|
|
|
6105
6398
|
return result;
|
|
6106
6399
|
} catch (error) {
|
|
6107
6400
|
const message = getErrorMessage(error);
|
|
6108
|
-
if (recoverOnTimeout && message.includes("Playwright page operation timed out")) {
|
|
6401
|
+
if (recoverOnTimeout && message.includes("Playwright page operation timed out") && (!page || page.isClosed())) {
|
|
6109
6402
|
console.warn(
|
|
6110
6403
|
`\u23F1\uFE0F [Playwright] Resetting account context after a stuck page operation: ${accountId}`
|
|
6111
6404
|
);
|
|
@@ -6654,7 +6947,7 @@ async function getTokenDiagnostics(accountId) {
|
|
|
6654
6947
|
}
|
|
6655
6948
|
};
|
|
6656
6949
|
}
|
|
6657
|
-
var requireLocal, contextInitHooks, ACCOUNT_MUTEX_MAX_HOLD_MS, accountMutexes, accountContexts, accountPages, cachedUserAgents, inFlightAccountInits, sharedBrowser, sharedBrowserPromise, headerCaches, HEADER_CACHE_TTL, HEADER_REFRESH_THRESHOLD, 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;
|
|
6950
|
+
var requireLocal, contextInitHooks, ACCOUNT_MUTEX_MAX_HOLD_MS, accountMutexes, accountContexts, accountPages, cachedUserAgents, inFlightAccountInits, sharedBrowser, sharedBrowserPromise, headerCaches, HEADER_CACHE_TTL, HEADER_REFRESH_THRESHOLD, 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, activeOtpSessions, mockOtpSessions, PROFILE_RESET_TIMEOUT_MS;
|
|
6658
6951
|
var init_playwright = __esm({
|
|
6659
6952
|
"src/services/playwright.ts"() {
|
|
6660
6953
|
"use strict";
|
|
@@ -6699,11 +6992,13 @@ var init_playwright = __esm({
|
|
|
6699
6992
|
PLAYWRIGHT_MUTEX_WAIT_MS = 6e4;
|
|
6700
6993
|
ACCOUNT_PAGE_OPERATION_TIMEOUT_MS = config.timeouts.page;
|
|
6701
6994
|
SESSION_PROBE_NAVIGATION_TIMEOUT_MS = 15e3;
|
|
6702
|
-
HEADER_CAPTURE_TRIGGER_GRACE_MS =
|
|
6703
|
-
FIRST_TRIGGER_GRACE_MS =
|
|
6995
|
+
HEADER_CAPTURE_TRIGGER_GRACE_MS = 2e4;
|
|
6996
|
+
FIRST_TRIGGER_GRACE_MS = 12e3;
|
|
6704
6997
|
HEADER_CAPTURE_TRIGGER_ATTEMPTS = 3;
|
|
6705
6998
|
CHAT_INPUT_APPEAR_TIMEOUT_MS = 15e3;
|
|
6706
6999
|
CHAT_INPUT_ACTION_TIMEOUT_MS = 1e4;
|
|
7000
|
+
activeOtpSessions = /* @__PURE__ */ new Map();
|
|
7001
|
+
mockOtpSessions = /* @__PURE__ */ new Map();
|
|
6707
7002
|
PROFILE_RESET_TIMEOUT_MS = Math.max(9e4, config.timeouts.headers);
|
|
6708
7003
|
setWafContextResetListener((accountId) => {
|
|
6709
7004
|
if (!accountPages.has(accountId)) return;
|
|
@@ -7715,6 +8010,15 @@ var init_helpers = __esm({
|
|
|
7715
8010
|
}
|
|
7716
8011
|
});
|
|
7717
8012
|
|
|
8013
|
+
// src/utils/overload-detector.ts
|
|
8014
|
+
var OVERLOAD_COOLDOWN_MS;
|
|
8015
|
+
var init_overload_detector = __esm({
|
|
8016
|
+
"src/utils/overload-detector.ts"() {
|
|
8017
|
+
"use strict";
|
|
8018
|
+
OVERLOAD_COOLDOWN_MS = 5 * 60 * 1e3;
|
|
8019
|
+
}
|
|
8020
|
+
});
|
|
8021
|
+
|
|
7718
8022
|
// src/routes/chat/retry-policy.ts
|
|
7719
8023
|
var init_retry_policy = __esm({
|
|
7720
8024
|
"src/routes/chat/retry-policy.ts"() {
|
|
@@ -7725,6 +8029,7 @@ var init_retry_policy = __esm({
|
|
|
7725
8029
|
init_qwen();
|
|
7726
8030
|
init_errors();
|
|
7727
8031
|
init_helpers();
|
|
8032
|
+
init_overload_detector();
|
|
7728
8033
|
init_account_manager();
|
|
7729
8034
|
}
|
|
7730
8035
|
});
|
|
@@ -8688,7 +8993,8 @@ async function requestQwenPersonalizationInBrowser(accountId, method, path6, hea
|
|
|
8688
8993
|
payload === void 0 ? void 0 : JSON.stringify(payload),
|
|
8689
8994
|
{
|
|
8690
8995
|
settingsPage: true,
|
|
8691
|
-
referrer: qwenUrl("/settings/personalization")
|
|
8996
|
+
referrer: qwenUrl("/settings/personalization"),
|
|
8997
|
+
noMutexRecovery: true
|
|
8692
8998
|
}
|
|
8693
8999
|
);
|
|
8694
9000
|
const { raw, json } = await readJsonTextResponse(response);
|
|
@@ -9189,8 +9495,9 @@ async function syncQwenRequestPersonalizationInternal(instruction, accountId, me
|
|
|
9189
9495
|
const returnedInstruction = json?.data?.personalization?.instruction;
|
|
9190
9496
|
const returned = textSize(returnedInstruction);
|
|
9191
9497
|
let stored = { chars: null, bytes: null, hash: null };
|
|
9498
|
+
const matchReturned = isEmptyInstruction && (!returnedInstruction || returned.chars === 0) || returned.hash !== null && returned.hash === sent.hash;
|
|
9192
9499
|
let verifyData = null;
|
|
9193
|
-
if (config.qwen.personalizationVerifyGet) {
|
|
9500
|
+
if (config.qwen.personalizationVerifyGet && !matchReturned) {
|
|
9194
9501
|
const { json: verifyJson } = await requestQwenPersonalizationInBrowser(
|
|
9195
9502
|
accountId,
|
|
9196
9503
|
"GET",
|
|
@@ -9200,7 +9507,6 @@ async function syncQwenRequestPersonalizationInternal(instruction, accountId, me
|
|
|
9200
9507
|
verifyData = verifyJson?.data?.personalization;
|
|
9201
9508
|
stored = textSize(verifyData?.instruction);
|
|
9202
9509
|
}
|
|
9203
|
-
const matchReturned = isEmptyInstruction && (!returnedInstruction || returned.chars === 0) || returned.hash !== null && returned.hash === sent.hash;
|
|
9204
9510
|
const matchStored = stored.hash === null ? null : isEmptyInstruction && (!verifyData?.instruction || stored.chars === 0) || stored.hash === sent.hash;
|
|
9205
9511
|
const applied = matchReturned || matchStored === true;
|
|
9206
9512
|
if (syncHash && applied) {
|
|
@@ -9574,6 +9880,17 @@ async function fetchQwenModels(accountId) {
|
|
|
9574
9880
|
);
|
|
9575
9881
|
return cached.models;
|
|
9576
9882
|
}
|
|
9883
|
+
if (accountId && !isAuthMockEnabled() && !isPlaywrightInitialized(accountId)) {
|
|
9884
|
+
for (const [, entry] of modelsCache.entries()) {
|
|
9885
|
+
if (entry && now - entry.fetchedAt < MODEL_CACHE_TTL_MS * 4) {
|
|
9886
|
+
syncModelMetadata(
|
|
9887
|
+
entry.models,
|
|
9888
|
+
accountId
|
|
9889
|
+
);
|
|
9890
|
+
return entry.models;
|
|
9891
|
+
}
|
|
9892
|
+
}
|
|
9893
|
+
}
|
|
9577
9894
|
if (accountId && !isAuthMockEnabled() && isAccountBusy(accountId)) {
|
|
9578
9895
|
try {
|
|
9579
9896
|
const result = await withAccountPage(
|