qwenproxy-cli 1.6.11 → 1.6.12
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 +350 -18
- package/dist/delete-chats.js +900 -474
- package/dist/index.js +484 -58
- package/dist/login.js +373 -27
- package/dist/reset-cooldowns.js +684 -350
- package/dist/sync-clients.js +4 -1
- package/package.json +1 -1
- package/src/core/config.ts +4 -1
- package/src/core/model-alias.ts +1 -0
- package/src/core/version.ts +1 -1
- package/src/services/auth-playwright.ts +3 -2
- package/src/services/captcha-coordinator.ts +6 -4
- package/src/services/captcha-solver.ts +400 -2
- package/src/services/playwright.ts +62 -22
- package/src/services/qwen-chat-pool.ts +52 -9
- package/src/services/qwen-headers.ts +18 -1
- package/src/services/qwen.ts +6 -4
- package/src/services/session-keeper.ts +70 -8
package/dist/index.js
CHANGED
|
@@ -266,7 +266,7 @@ var init_config = __esm({
|
|
|
266
266
|
// Version header on Qwen API requests = the deployed web bundle version
|
|
267
267
|
// (fallback when dynamic DOM detection is not yet completed).
|
|
268
268
|
// Override via env when Qwen ships a new bundle.
|
|
269
|
-
QWEN_WEB_VERSION: z.string().default("0.3.
|
|
269
|
+
QWEN_WEB_VERSION: z.string().default("0.3.43"),
|
|
270
270
|
// Controls bx-ua/bx-umidtoken injection on the GENERAL API paths
|
|
271
271
|
// (chats/new, settings): those work without them (live-probed). The
|
|
272
272
|
// completions path is the exception — the 0.2.86 HAR shows the real
|
|
@@ -309,6 +309,7 @@ var init_config = __esm({
|
|
|
309
309
|
CAPTCHA_SOLVER_ENABLED: z.string().default("true"),
|
|
310
310
|
CAPTCHA_SOLVER_MAX_ATTEMPTS: z.string().default("3"),
|
|
311
311
|
CAPTCHA_SOLVER_TIMEOUT_MS: z.string().default("15000"),
|
|
312
|
+
CAPTCHA_SLIDER_TIMEOUT_MS: z.string().default("8000"),
|
|
312
313
|
CAPTCHA_SOLVER_RETRY_DELAY_MS: z.string().default("1000"),
|
|
313
314
|
CAPTCHA_SOLVER_SETTLE_MS: z.string().default("2000"),
|
|
314
315
|
CAPTCHA_ACCOUNT_COOLDOWN_MS: z.string().default("120000"),
|
|
@@ -460,6 +461,8 @@ var init_config = __esm({
|
|
|
460
461
|
enabled: env.CAPTCHA_SOLVER_ENABLED === "true",
|
|
461
462
|
maxAttempts: Math.max(1, Math.min(5, parseInt(env.CAPTCHA_SOLVER_MAX_ATTEMPTS))),
|
|
462
463
|
timeoutMs: Math.max(0, parseInt(env.CAPTCHA_SOLVER_TIMEOUT_MS)),
|
|
464
|
+
/** Max wait for a challenge slider to become visible (slow WAF renders). */
|
|
465
|
+
sliderTimeoutMs: Math.max(500, parseInt(env.CAPTCHA_SLIDER_TIMEOUT_MS)),
|
|
463
466
|
retryDelayMs: Math.max(0, parseInt(env.CAPTCHA_SOLVER_RETRY_DELAY_MS)),
|
|
464
467
|
settleMs: Math.max(0, parseInt(env.CAPTCHA_SOLVER_SETTLE_MS)),
|
|
465
468
|
/** Rest an account whose challenge could not be cleared before reusing it. */
|
|
@@ -3619,6 +3622,294 @@ function extractBaxiaChallengeUrl(body, baseUrl) {
|
|
|
3619
3622
|
}
|
|
3620
3623
|
return null;
|
|
3621
3624
|
}
|
|
3625
|
+
async function findVisibleLocatorWithin(page, selectors, timeoutMs) {
|
|
3626
|
+
const deadline = Date.now() + Math.max(0, timeoutMs);
|
|
3627
|
+
while (true) {
|
|
3628
|
+
const found = await findVisibleLocator(page, selectors);
|
|
3629
|
+
if (found) return found;
|
|
3630
|
+
if (Date.now() >= deadline) return null;
|
|
3631
|
+
await sleep(Math.min(150, Math.max(1, deadline - Date.now())));
|
|
3632
|
+
}
|
|
3633
|
+
}
|
|
3634
|
+
async function waitForHidden(locator, timeoutMs) {
|
|
3635
|
+
const deadline = Date.now() + Math.max(0, timeoutMs);
|
|
3636
|
+
while (true) {
|
|
3637
|
+
if (!await isVisible(locator)) return true;
|
|
3638
|
+
if (Date.now() >= deadline) return false;
|
|
3639
|
+
await sleep(Math.min(100, Math.max(1, deadline - Date.now())));
|
|
3640
|
+
}
|
|
3641
|
+
}
|
|
3642
|
+
async function computeAliyunPuzzleOffset(page) {
|
|
3643
|
+
return page.evaluate(() => {
|
|
3644
|
+
const background = document.querySelector(
|
|
3645
|
+
"#aliyunCaptcha-img"
|
|
3646
|
+
);
|
|
3647
|
+
const piece = document.querySelector(
|
|
3648
|
+
"#aliyunCaptcha-puzzle"
|
|
3649
|
+
);
|
|
3650
|
+
if (!background || !piece) {
|
|
3651
|
+
return Promise.resolve({ ok: false, reason: "missing puzzle images" });
|
|
3652
|
+
}
|
|
3653
|
+
const compute = () => {
|
|
3654
|
+
try {
|
|
3655
|
+
const width = background.naturalWidth;
|
|
3656
|
+
const height = background.naturalHeight;
|
|
3657
|
+
const pieceWidth = piece.naturalWidth;
|
|
3658
|
+
const pieceHeight = piece.naturalHeight;
|
|
3659
|
+
if (!width || !height || !pieceWidth || !pieceHeight) {
|
|
3660
|
+
return { ok: false, reason: "image dimensions unavailable" };
|
|
3661
|
+
}
|
|
3662
|
+
const backgroundCanvas = document.createElement("canvas");
|
|
3663
|
+
backgroundCanvas.id = "captcha-solver-canvas";
|
|
3664
|
+
backgroundCanvas.width = width;
|
|
3665
|
+
backgroundCanvas.height = height;
|
|
3666
|
+
const backgroundContext = backgroundCanvas.getContext("2d");
|
|
3667
|
+
if (!backgroundContext) {
|
|
3668
|
+
return { ok: false, reason: "no background context" };
|
|
3669
|
+
}
|
|
3670
|
+
const pieceCanvas = document.createElement("canvas");
|
|
3671
|
+
pieceCanvas.id = "captcha-solver-canvas";
|
|
3672
|
+
pieceCanvas.width = pieceWidth;
|
|
3673
|
+
pieceCanvas.height = pieceHeight;
|
|
3674
|
+
const pieceContext = pieceCanvas.getContext("2d");
|
|
3675
|
+
if (!pieceContext) {
|
|
3676
|
+
return { ok: false, reason: "no piece context" };
|
|
3677
|
+
}
|
|
3678
|
+
try {
|
|
3679
|
+
backgroundContext.drawImage(background, 0, 0);
|
|
3680
|
+
} catch {
|
|
3681
|
+
return { ok: false, reason: "background canvas tainted" };
|
|
3682
|
+
}
|
|
3683
|
+
try {
|
|
3684
|
+
pieceContext.drawImage(piece, 0, 0);
|
|
3685
|
+
} catch {
|
|
3686
|
+
return { ok: false, reason: "puzzle canvas tainted" };
|
|
3687
|
+
}
|
|
3688
|
+
const backgroundData = backgroundContext.getImageData(
|
|
3689
|
+
0,
|
|
3690
|
+
0,
|
|
3691
|
+
width,
|
|
3692
|
+
height
|
|
3693
|
+
).data;
|
|
3694
|
+
const pieceData = pieceContext.getImageData(
|
|
3695
|
+
0,
|
|
3696
|
+
0,
|
|
3697
|
+
pieceWidth,
|
|
3698
|
+
pieceHeight
|
|
3699
|
+
).data;
|
|
3700
|
+
let pieceMinX = pieceWidth;
|
|
3701
|
+
let pieceMaxX = -1;
|
|
3702
|
+
let pieceMinY = pieceHeight;
|
|
3703
|
+
let pieceMaxY = -1;
|
|
3704
|
+
for (let y = 0; y < pieceHeight; y++) {
|
|
3705
|
+
for (let x = 0; x < pieceWidth; x++) {
|
|
3706
|
+
if (pieceData[(y * pieceWidth + x) * 4 + 3] > 100) {
|
|
3707
|
+
if (x < pieceMinX) pieceMinX = x;
|
|
3708
|
+
if (x > pieceMaxX) pieceMaxX = x;
|
|
3709
|
+
if (y < pieceMinY) pieceMinY = y;
|
|
3710
|
+
if (y > pieceMaxY) pieceMaxY = y;
|
|
3711
|
+
}
|
|
3712
|
+
}
|
|
3713
|
+
}
|
|
3714
|
+
const puzzleWidth = pieceMaxX - pieceMinX + 1;
|
|
3715
|
+
if (puzzleWidth <= 0) {
|
|
3716
|
+
return { ok: false, reason: "empty puzzle piece" };
|
|
3717
|
+
}
|
|
3718
|
+
const yStart = Math.max(1, Math.min(height - 2, pieceMinY + 5));
|
|
3719
|
+
const yEnd = Math.max(
|
|
3720
|
+
yStart,
|
|
3721
|
+
Math.min(height - 2, pieceMaxY - 5)
|
|
3722
|
+
);
|
|
3723
|
+
const columnGradients = new Float32Array(width);
|
|
3724
|
+
for (let x = 1; x < width - 1; x++) {
|
|
3725
|
+
let gradient = 0;
|
|
3726
|
+
for (let y = yStart; y <= yEnd; y++) {
|
|
3727
|
+
const left = (y * width + x - 1) * 4;
|
|
3728
|
+
const right = (y * width + x + 1) * 4;
|
|
3729
|
+
gradient += Math.abs(backgroundData[right] - backgroundData[left]) + Math.abs(backgroundData[right + 1] - backgroundData[left + 1]) + Math.abs(backgroundData[right + 2] - backgroundData[left + 2]);
|
|
3730
|
+
}
|
|
3731
|
+
columnGradients[x] = gradient;
|
|
3732
|
+
}
|
|
3733
|
+
let bestX = 0;
|
|
3734
|
+
let bestScore = 0;
|
|
3735
|
+
const minCandidateX = 30;
|
|
3736
|
+
const maxCandidateX = width - puzzleWidth - 20;
|
|
3737
|
+
for (let candidateX = minCandidateX; candidateX <= maxCandidateX; candidateX++) {
|
|
3738
|
+
let leftMax = 0;
|
|
3739
|
+
for (let dx = -2; dx <= 2; dx++) {
|
|
3740
|
+
const value = columnGradients[candidateX + pieceMinX + dx] || 0;
|
|
3741
|
+
if (value > leftMax) leftMax = value;
|
|
3742
|
+
}
|
|
3743
|
+
let rightMax = 0;
|
|
3744
|
+
for (let dx = -3; dx <= 1; dx++) {
|
|
3745
|
+
const value = columnGradients[candidateX + pieceMaxX + dx] || 0;
|
|
3746
|
+
if (value > rightMax) rightMax = value;
|
|
3747
|
+
}
|
|
3748
|
+
const score = Math.sqrt(leftMax * rightMax);
|
|
3749
|
+
if (score > bestScore) {
|
|
3750
|
+
bestScore = score;
|
|
3751
|
+
bestX = candidateX;
|
|
3752
|
+
}
|
|
3753
|
+
}
|
|
3754
|
+
if (bestScore <= 0) {
|
|
3755
|
+
return { ok: false, reason: "no matching hole edge" };
|
|
3756
|
+
}
|
|
3757
|
+
return {
|
|
3758
|
+
ok: true,
|
|
3759
|
+
offsetX: bestX - pieceMinX,
|
|
3760
|
+
naturalWidth: width
|
|
3761
|
+
};
|
|
3762
|
+
} catch (error) {
|
|
3763
|
+
return {
|
|
3764
|
+
ok: false,
|
|
3765
|
+
reason: error instanceof Error ? error.message : String(error)
|
|
3766
|
+
};
|
|
3767
|
+
}
|
|
3768
|
+
};
|
|
3769
|
+
return new Promise((resolve) => {
|
|
3770
|
+
if (background.complete && piece.complete) {
|
|
3771
|
+
resolve(compute());
|
|
3772
|
+
return;
|
|
3773
|
+
}
|
|
3774
|
+
let settled = false;
|
|
3775
|
+
const finish = () => {
|
|
3776
|
+
if (settled) return;
|
|
3777
|
+
settled = true;
|
|
3778
|
+
resolve(compute());
|
|
3779
|
+
};
|
|
3780
|
+
const fail = () => {
|
|
3781
|
+
if (settled) return;
|
|
3782
|
+
settled = true;
|
|
3783
|
+
resolve({ ok: false, reason: "puzzle image load error" });
|
|
3784
|
+
};
|
|
3785
|
+
background.addEventListener("load", finish, { once: true });
|
|
3786
|
+
piece.addEventListener("load", finish, { once: true });
|
|
3787
|
+
background.addEventListener("error", fail, { once: true });
|
|
3788
|
+
piece.addEventListener("error", fail, { once: true });
|
|
3789
|
+
setTimeout(() => {
|
|
3790
|
+
if (settled) return;
|
|
3791
|
+
settled = true;
|
|
3792
|
+
resolve({ ok: false, reason: "puzzle image load timeout" });
|
|
3793
|
+
}, 2e3);
|
|
3794
|
+
});
|
|
3795
|
+
});
|
|
3796
|
+
}
|
|
3797
|
+
async function solveAliyunWafCaptcha(page, options = {}) {
|
|
3798
|
+
const waitForMs = Math.max(0, options.waitForMs ?? 0);
|
|
3799
|
+
const maxAttempts = Math.max(
|
|
3800
|
+
1,
|
|
3801
|
+
Math.min(5, options.maxAttempts ?? DEFAULT_MAX_ATTEMPTS)
|
|
3802
|
+
);
|
|
3803
|
+
const retryDelayMs = Math.max(
|
|
3804
|
+
0,
|
|
3805
|
+
options.retryDelayMs ?? DEFAULT_RETRY_DELAY_MS
|
|
3806
|
+
);
|
|
3807
|
+
const settleMs = Math.max(0, options.settleMs ?? DEFAULT_SETTLE_MS);
|
|
3808
|
+
const sliderTimeoutMs = Math.max(
|
|
3809
|
+
500,
|
|
3810
|
+
options.sliderTimeoutMs ?? DEFAULT_SLIDER_TIMEOUT_MS
|
|
3811
|
+
);
|
|
3812
|
+
const detected = await findVisibleLocatorWithin(
|
|
3813
|
+
page,
|
|
3814
|
+
ALIYUN_WAF_BLOCK_SELECTORS,
|
|
3815
|
+
waitForMs
|
|
3816
|
+
);
|
|
3817
|
+
if (!detected) return false;
|
|
3818
|
+
return withCaptchaMouseLock(async () => {
|
|
3819
|
+
const block = detected.locator;
|
|
3820
|
+
if (!await isVisible(block)) return false;
|
|
3821
|
+
logBaxiaCaptcha("aliyun_detected", { selector: detected.selector });
|
|
3822
|
+
let lastReason = "unknown";
|
|
3823
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
3824
|
+
try {
|
|
3825
|
+
const offset = await computeAliyunPuzzleOffset(page);
|
|
3826
|
+
if (!offset.ok || typeof offset.offsetX !== "number" || typeof offset.naturalWidth !== "number" || offset.naturalWidth <= 0) {
|
|
3827
|
+
lastReason = offset.reason || "offset_unavailable";
|
|
3828
|
+
logBaxiaCaptcha("aliyun_offset_failed", {
|
|
3829
|
+
attempt,
|
|
3830
|
+
reason: lastReason
|
|
3831
|
+
});
|
|
3832
|
+
} else {
|
|
3833
|
+
const slider = page.locator(ALIYUN_PUZZLE_SLIDER_SELECTOR).first();
|
|
3834
|
+
const track = page.locator(ALIYUN_PUZZLE_TRACK_SELECTOR).first();
|
|
3835
|
+
await slider.waitFor({ state: "visible", timeout: sliderTimeoutMs });
|
|
3836
|
+
const [sliderBox, trackBox] = await Promise.all([
|
|
3837
|
+
slider.boundingBox(),
|
|
3838
|
+
track.boundingBox()
|
|
3839
|
+
]);
|
|
3840
|
+
if (!sliderBox || !trackBox || trackBox.width <= 0) {
|
|
3841
|
+
lastReason = "bounds_unavailable";
|
|
3842
|
+
logBaxiaCaptcha("aliyun_offset_failed", {
|
|
3843
|
+
attempt,
|
|
3844
|
+
reason: lastReason
|
|
3845
|
+
});
|
|
3846
|
+
} else {
|
|
3847
|
+
const scale = trackBox.width / offset.naturalWidth;
|
|
3848
|
+
const dragDistance = Math.round(offset.offsetX * scale);
|
|
3849
|
+
logBaxiaCaptcha("aliyun_geometry", {
|
|
3850
|
+
attempt,
|
|
3851
|
+
offset: offset.offsetX,
|
|
3852
|
+
scale: Number(scale.toFixed(2)),
|
|
3853
|
+
distance: dragDistance
|
|
3854
|
+
});
|
|
3855
|
+
if (dragDistance <= 0) {
|
|
3856
|
+
lastReason = "non_positive_distance";
|
|
3857
|
+
} else {
|
|
3858
|
+
const startX = sliderBox.x + sliderBox.width / 2;
|
|
3859
|
+
const startY = sliderBox.y + sliderBox.height / 2;
|
|
3860
|
+
await humanDrag(
|
|
3861
|
+
page,
|
|
3862
|
+
startX,
|
|
3863
|
+
startY,
|
|
3864
|
+
startX + dragDistance,
|
|
3865
|
+
startY
|
|
3866
|
+
);
|
|
3867
|
+
if (await waitForHidden(block, settleMs)) {
|
|
3868
|
+
logBaxiaCaptcha(
|
|
3869
|
+
"aliyun_solve_succeeded",
|
|
3870
|
+
{ attempt, distance: dragDistance },
|
|
3871
|
+
true
|
|
3872
|
+
);
|
|
3873
|
+
return true;
|
|
3874
|
+
}
|
|
3875
|
+
lastReason = "not_solved";
|
|
3876
|
+
}
|
|
3877
|
+
}
|
|
3878
|
+
}
|
|
3879
|
+
} catch (error) {
|
|
3880
|
+
lastReason = error instanceof Error ? error.name : "UnknownError";
|
|
3881
|
+
logBaxiaCaptcha("aliyun_offset_failed", {
|
|
3882
|
+
attempt,
|
|
3883
|
+
error: lastReason,
|
|
3884
|
+
detail: sanitizeCaptchaErrorDetail(error)
|
|
3885
|
+
});
|
|
3886
|
+
}
|
|
3887
|
+
if (attempt < maxAttempts && retryDelayMs > 0) {
|
|
3888
|
+
await sleep(retryDelayMs);
|
|
3889
|
+
}
|
|
3890
|
+
}
|
|
3891
|
+
logBaxiaCaptcha(
|
|
3892
|
+
"aliyun_solve_failed",
|
|
3893
|
+
{ attempts: maxAttempts, reason: lastReason },
|
|
3894
|
+
true
|
|
3895
|
+
);
|
|
3896
|
+
return false;
|
|
3897
|
+
});
|
|
3898
|
+
}
|
|
3899
|
+
async function solveVisibleCaptcha(page, options = {}) {
|
|
3900
|
+
if (typeof page.isClosed === "function" && page.isClosed()) return false;
|
|
3901
|
+
const totalWaitMs = Math.max(0, options.waitForMs ?? 0);
|
|
3902
|
+
const aliyunWaitMs = Math.min(totalWaitMs, ALIYUN_PROBE_MAX_WAIT_MS);
|
|
3903
|
+
const startedAt = Date.now();
|
|
3904
|
+
if (await solveAliyunWafCaptcha(page, { ...options, waitForMs: aliyunWaitMs })) {
|
|
3905
|
+
return true;
|
|
3906
|
+
}
|
|
3907
|
+
const remainingWaitMs = Math.max(
|
|
3908
|
+
0,
|
|
3909
|
+
totalWaitMs - (Date.now() - startedAt)
|
|
3910
|
+
);
|
|
3911
|
+
return solveBaxiaCaptcha(page, { ...options, waitForMs: remainingWaitMs });
|
|
3912
|
+
}
|
|
3622
3913
|
async function isVisible(locator) {
|
|
3623
3914
|
return locator.isVisible().catch(() => false);
|
|
3624
3915
|
}
|
|
@@ -3888,7 +4179,7 @@ function startBaxiaCaptchaWatcher(page, timeoutMs, options = {}) {
|
|
|
3888
4179
|
promise
|
|
3889
4180
|
};
|
|
3890
4181
|
}
|
|
3891
|
-
var BAXIA_DIALOG_SELECTOR, BAXIA_CONTENT_SELECTOR, CAPTCHA_EVENT_EMOJI, captchaDebugEnabled, BAXIA_IFRAME_SELECTORS, BAXIA_DOCUMENT_SELECTORS, BAXIA_IFRAME_SELECTOR, BAXIA_SLIDER_SELECTOR, BAXIA_TRACK_SELECTOR, BAXIA_SUCCESS_SELECTOR, BAXIA_RELOAD_SELECTOR, DEFAULT_MAX_ATTEMPTS, DEFAULT_RETRY_DELAY_MS, DEFAULT_SETTLE_MS, DEFAULT_SLIDER_TIMEOUT_MS, captchaMouseLock;
|
|
4182
|
+
var BAXIA_DIALOG_SELECTOR, BAXIA_CONTENT_SELECTOR, CAPTCHA_EVENT_EMOJI, captchaDebugEnabled, BAXIA_IFRAME_SELECTORS, BAXIA_DOCUMENT_SELECTORS, BAXIA_IFRAME_SELECTOR, BAXIA_SLIDER_SELECTOR, BAXIA_TRACK_SELECTOR, BAXIA_SUCCESS_SELECTOR, BAXIA_RELOAD_SELECTOR, DEFAULT_MAX_ATTEMPTS, DEFAULT_RETRY_DELAY_MS, DEFAULT_SETTLE_MS, DEFAULT_SLIDER_TIMEOUT_MS, ALIYUN_WAF_CAPTCHA_SELECTOR, ALIYUN_WAF_CAPTCHA_WIDGET, ALIYUN_WAF_BLOCK_SELECTORS, ALIYUN_PUZZLE_SLIDER_SELECTOR, ALIYUN_PUZZLE_TRACK_SELECTOR, ALIYUN_PROBE_MAX_WAIT_MS, captchaMouseLock;
|
|
3892
4183
|
var init_captcha_solver = __esm({
|
|
3893
4184
|
"src/services/captcha-solver.ts"() {
|
|
3894
4185
|
"use strict";
|
|
@@ -3914,14 +4205,20 @@ var init_captcha_solver = __esm({
|
|
|
3914
4205
|
solve_failed: "\u274C",
|
|
3915
4206
|
recovery_succeeded: "\u2705",
|
|
3916
4207
|
recovery_not_solved: "\u26A0\uFE0F",
|
|
3917
|
-
recovery_failed: "\u274C"
|
|
4208
|
+
recovery_failed: "\u274C",
|
|
4209
|
+
aliyun_detected: "\u{1F9E9}",
|
|
4210
|
+
aliyun_offset_failed: "\u{1F4D0}",
|
|
4211
|
+
aliyun_geometry: "\u{1F4D0}",
|
|
4212
|
+
aliyun_solve_succeeded: "\u2705",
|
|
4213
|
+
aliyun_solve_failed: "\u274C"
|
|
3918
4214
|
};
|
|
3919
4215
|
captchaDebugEnabled = process.env.CAPTCHA_DEBUG === "true";
|
|
3920
4216
|
BAXIA_IFRAME_SELECTORS = [
|
|
3921
4217
|
`${BAXIA_DIALOG_SELECTOR} ${BAXIA_CONTENT_SELECTOR} iframe`,
|
|
3922
4218
|
`${BAXIA_CONTENT_SELECTOR} iframe`,
|
|
3923
4219
|
"iframe#baxia-dialog-content",
|
|
3924
|
-
'iframe[src*="_____tmd_____/punish"]'
|
|
4220
|
+
'iframe[src*="_____tmd_____/punish"]',
|
|
4221
|
+
'iframe[src*="nocaptcha"]'
|
|
3925
4222
|
];
|
|
3926
4223
|
BAXIA_DOCUMENT_SELECTORS = [
|
|
3927
4224
|
"#nocaptcha",
|
|
@@ -3929,14 +4226,23 @@ var init_captcha_solver = __esm({
|
|
|
3929
4226
|
"#baxia-punish"
|
|
3930
4227
|
];
|
|
3931
4228
|
BAXIA_IFRAME_SELECTOR = BAXIA_IFRAME_SELECTORS.join(", ");
|
|
3932
|
-
BAXIA_SLIDER_SELECTOR =
|
|
3933
|
-
BAXIA_TRACK_SELECTOR =
|
|
4229
|
+
BAXIA_SLIDER_SELECTOR = '#nc_1_n1z, .nc_1_n1z, .btn_slide, .nc_iconfont.btn_slide, span[id*="_n1z"], .nc_wrapper .btn_slide, ._nc .btn_slide, .nc-container .btn_slide';
|
|
4230
|
+
BAXIA_TRACK_SELECTOR = '#nc_1_n1t, .nc_scale, span[id*="_n1t"], .nc_wrapper .nc_scale, ._nc .nc_scale, .nc-container .nc_scale';
|
|
3934
4231
|
BAXIA_SUCCESS_SELECTOR = '.btn_ok, .nc_ok, .nc_success, .nc_result, .nc_wrapper.nc-success, .nc_wrapper.success, [data-nc-lang="SUCCESS"], [data-nc-lang="success"], #nc-loading-circle';
|
|
3935
4232
|
BAXIA_RELOAD_SELECTOR = '#nc_1_refresh1, .errloading a, .nc-container .errloading a, .btn_refresh, .clickCaptcha_text .btn_refresh, [data-nc-lang="REFRESH"], a[id*="refresh"]';
|
|
3936
4233
|
DEFAULT_MAX_ATTEMPTS = 3;
|
|
3937
4234
|
DEFAULT_RETRY_DELAY_MS = 1e3;
|
|
3938
4235
|
DEFAULT_SETTLE_MS = 2e3;
|
|
3939
4236
|
DEFAULT_SLIDER_TIMEOUT_MS = 8e3;
|
|
4237
|
+
ALIYUN_WAF_CAPTCHA_SELECTOR = "#waf_nc_block";
|
|
4238
|
+
ALIYUN_WAF_CAPTCHA_WIDGET = "#aliyunCaptcha-window-embed";
|
|
4239
|
+
ALIYUN_WAF_BLOCK_SELECTORS = [
|
|
4240
|
+
ALIYUN_WAF_CAPTCHA_SELECTOR,
|
|
4241
|
+
ALIYUN_WAF_CAPTCHA_WIDGET
|
|
4242
|
+
];
|
|
4243
|
+
ALIYUN_PUZZLE_SLIDER_SELECTOR = "#aliyunCaptcha-sliding-slider";
|
|
4244
|
+
ALIYUN_PUZZLE_TRACK_SELECTOR = "#aliyunCaptcha-sliding-body";
|
|
4245
|
+
ALIYUN_PROBE_MAX_WAIT_MS = 2e3;
|
|
3940
4246
|
captchaMouseLock = Promise.resolve();
|
|
3941
4247
|
}
|
|
3942
4248
|
});
|
|
@@ -4090,6 +4396,14 @@ function updateQwenWebVersion(version) {
|
|
|
4090
4396
|
function getQwenWebVersion() {
|
|
4091
4397
|
return dynamicWebVersion || config.qwen.webVersion;
|
|
4092
4398
|
}
|
|
4399
|
+
function updateQwenBxVersion(version) {
|
|
4400
|
+
if (version && typeof version === "string" && /^\d+\.\d+\.\d+/.test(version)) {
|
|
4401
|
+
dynamicBxVersion = version.trim();
|
|
4402
|
+
}
|
|
4403
|
+
}
|
|
4404
|
+
function getQwenBxVersion() {
|
|
4405
|
+
return dynamicBxVersion || config.auth.bxV;
|
|
4406
|
+
}
|
|
4093
4407
|
function buildQwenRequestHeaders(opts) {
|
|
4094
4408
|
const headers = {
|
|
4095
4409
|
...opts.extra ?? {},
|
|
@@ -4106,7 +4420,7 @@ function buildQwenRequestHeaders(opts) {
|
|
|
4106
4420
|
Connection: "keep-alive",
|
|
4107
4421
|
"User-Agent": opts.userAgent || getDefaultQwenUserAgent(),
|
|
4108
4422
|
"X-Request-Id": uuidv4(),
|
|
4109
|
-
"bx-v": opts.bxV ||
|
|
4423
|
+
"bx-v": opts.bxV || getQwenBxVersion(),
|
|
4110
4424
|
source: "web",
|
|
4111
4425
|
version: opts.version || getQwenWebVersion(),
|
|
4112
4426
|
timezone: opts.extra?.timezone || opts.extra?.Timezone || formatAsciiTimezone(),
|
|
@@ -4130,7 +4444,7 @@ function buildQwenRequestHeaders(opts) {
|
|
|
4130
4444
|
}
|
|
4131
4445
|
return headers;
|
|
4132
4446
|
}
|
|
4133
|
-
var dynamicWebVersion, QWEN_WEB_VERSION, DEFAULT_QWEN_USER_AGENT, QWEN_TIMEZONE_HEADER;
|
|
4447
|
+
var dynamicWebVersion, dynamicBxVersion, QWEN_WEB_VERSION, DEFAULT_QWEN_USER_AGENT, QWEN_TIMEZONE_HEADER;
|
|
4134
4448
|
var init_qwen_headers = __esm({
|
|
4135
4449
|
"src/services/qwen-headers.ts"() {
|
|
4136
4450
|
"use strict";
|
|
@@ -4139,6 +4453,7 @@ var init_qwen_headers = __esm({
|
|
|
4139
4453
|
init_fingerprint();
|
|
4140
4454
|
init_timezone();
|
|
4141
4455
|
dynamicWebVersion = null;
|
|
4456
|
+
dynamicBxVersion = null;
|
|
4142
4457
|
QWEN_WEB_VERSION = config.qwen.webVersion;
|
|
4143
4458
|
DEFAULT_QWEN_USER_AGENT = getDefaultQwenUserAgent(151);
|
|
4144
4459
|
QWEN_TIMEZONE_HEADER = (/* @__PURE__ */ new Date()).toString().split(" (")[0];
|
|
@@ -4752,11 +5067,12 @@ async function getOrLaunchSharedBrowser(browserType = "chromium", headless = con
|
|
|
4752
5067
|
async function clearVisibleChallenge(page) {
|
|
4753
5068
|
if (page.isClosed()) return;
|
|
4754
5069
|
if (config.captcha.enabled) {
|
|
4755
|
-
await
|
|
5070
|
+
await solveVisibleCaptcha(page, {
|
|
4756
5071
|
waitForMs: 0,
|
|
4757
5072
|
maxAttempts: config.captcha.maxAttempts,
|
|
4758
5073
|
retryDelayMs: config.captcha.retryDelayMs,
|
|
4759
|
-
settleMs: config.captcha.settleMs
|
|
5074
|
+
settleMs: config.captcha.settleMs,
|
|
5075
|
+
sliderTimeoutMs: config.captcha.sliderTimeoutMs
|
|
4760
5076
|
}).catch(() => false);
|
|
4761
5077
|
}
|
|
4762
5078
|
try {
|
|
@@ -5369,6 +5685,7 @@ async function getBasicHeaders(accountId) {
|
|
|
5369
5685
|
mobile = data.mobile ? "?1" : "?0";
|
|
5370
5686
|
}
|
|
5371
5687
|
let bundleVersion = null;
|
|
5688
|
+
let baxiaVersion = null;
|
|
5372
5689
|
try {
|
|
5373
5690
|
const el = document.querySelector('link[href*="qwen-chat-fe"], script[src*="qwen-chat-fe"], img[src*="qwen-chat-fe"]');
|
|
5374
5691
|
const src = el ? el.getAttribute("href") || el.getAttribute("src") || "" : "";
|
|
@@ -5376,7 +5693,14 @@ async function getBasicHeaders(accountId) {
|
|
|
5376
5693
|
if (match) bundleVersion = match[1];
|
|
5377
5694
|
} catch {
|
|
5378
5695
|
}
|
|
5379
|
-
|
|
5696
|
+
try {
|
|
5697
|
+
const baxia = window.baxiaCommon;
|
|
5698
|
+
if (typeof baxia?.version === "string") {
|
|
5699
|
+
baxiaVersion = baxia.version;
|
|
5700
|
+
}
|
|
5701
|
+
} catch {
|
|
5702
|
+
}
|
|
5703
|
+
return { ua, secChUa, platform, mobile, bundleVersion, baxiaVersion };
|
|
5380
5704
|
}),
|
|
5381
5705
|
config.timeouts.page,
|
|
5382
5706
|
`User-agent lookup timed out for ${accountId}`
|
|
@@ -5385,6 +5709,9 @@ async function getBasicHeaders(accountId) {
|
|
|
5385
5709
|
if (nav.bundleVersion) {
|
|
5386
5710
|
updateQwenWebVersion(nav.bundleVersion);
|
|
5387
5711
|
}
|
|
5712
|
+
if (nav.baxiaVersion) {
|
|
5713
|
+
updateQwenBxVersion(nav.baxiaVersion);
|
|
5714
|
+
}
|
|
5388
5715
|
cachedUserAgents.set(accountId, userAgent);
|
|
5389
5716
|
const hints = getHeaderCache(accountId).headers;
|
|
5390
5717
|
clientHints = {
|
|
@@ -5416,7 +5743,7 @@ async function getBasicHeaders(accountId) {
|
|
|
5416
5743
|
markAccountHeadersReady(accountId);
|
|
5417
5744
|
const bxUa2 = cache3.headers["bx-ua"];
|
|
5418
5745
|
const bxUmidtoken2 = cache3.headers["bx-umidtoken"];
|
|
5419
|
-
const bxV2 = cache3.headers["bx-v"] ||
|
|
5746
|
+
const bxV2 = cache3.headers["bx-v"] || getQwenBxVersion();
|
|
5420
5747
|
const cookie2 = await getCookies(accountId);
|
|
5421
5748
|
return { cookie: cookie2, userAgent, bxV: bxV2, bxUa: bxUa2, bxUmidtoken: bxUmidtoken2, ...clientHints };
|
|
5422
5749
|
}
|
|
@@ -5427,7 +5754,7 @@ async function getBasicHeaders(accountId) {
|
|
|
5427
5754
|
cookieCaches.set(accountId, { cookie: cookie2, timestamp: Date.now() });
|
|
5428
5755
|
const bxUa2 = cache3.headers["bx-ua"];
|
|
5429
5756
|
const bxUmidtoken2 = cache3.headers["bx-umidtoken"];
|
|
5430
|
-
const bxV2 = cache3.headers["bx-v"] ||
|
|
5757
|
+
const bxV2 = cache3.headers["bx-v"] || getQwenBxVersion();
|
|
5431
5758
|
cache3.lastRefresh = Date.now();
|
|
5432
5759
|
markAccountHeadersReady(accountId);
|
|
5433
5760
|
console.log(
|
|
@@ -5502,6 +5829,9 @@ async function getBasicHeaders(accountId) {
|
|
|
5502
5829
|
if (persisted.version) {
|
|
5503
5830
|
updateQwenWebVersion(persisted.version);
|
|
5504
5831
|
}
|
|
5832
|
+
if (persisted.bxV) {
|
|
5833
|
+
updateQwenBxVersion(persisted.bxV);
|
|
5834
|
+
}
|
|
5505
5835
|
cache3.lastRefresh = persisted.capturedAt;
|
|
5506
5836
|
markAccountHeadersReady(accountId);
|
|
5507
5837
|
}
|
|
@@ -5529,7 +5859,7 @@ async function getBasicHeaders(accountId) {
|
|
|
5529
5859
|
markAccountHeadersReady(accountId);
|
|
5530
5860
|
const bxUa = cache3.headers["bx-ua"];
|
|
5531
5861
|
const bxUmidtoken = cache3.headers["bx-umidtoken"];
|
|
5532
|
-
const bxV = cache3.headers["bx-v"] ||
|
|
5862
|
+
const bxV = cache3.headers["bx-v"] || getQwenBxVersion();
|
|
5533
5863
|
cookieCaches.delete(accountId);
|
|
5534
5864
|
const cookie = await getCookies(accountId, true);
|
|
5535
5865
|
if (cache3.headers) {
|
|
@@ -5774,6 +6104,9 @@ async function initPlaywrightForAccount(rawAccount, headless = config.playwright
|
|
|
5774
6104
|
if (persisted.version) {
|
|
5775
6105
|
updateQwenWebVersion(persisted.version);
|
|
5776
6106
|
}
|
|
6107
|
+
if (persisted.bxV) {
|
|
6108
|
+
updateQwenBxVersion(persisted.bxV);
|
|
6109
|
+
}
|
|
5777
6110
|
cache3.lastRefresh = persisted.capturedAt;
|
|
5778
6111
|
markAccountHeadersReady(account.id);
|
|
5779
6112
|
restoredFromDb = true;
|
|
@@ -6123,7 +6456,7 @@ async function startEmailOtpLogin(email, options = {}) {
|
|
|
6123
6456
|
{
|
|
6124
6457
|
email: normalizedEmail,
|
|
6125
6458
|
requestId,
|
|
6126
|
-
version: getQwenWebVersion()
|
|
6459
|
+
version: getQwenWebVersion(),
|
|
6127
6460
|
timezone: formatAsciiTimezone()
|
|
6128
6461
|
}
|
|
6129
6462
|
).catch((err) => ({ ok: false, error: err?.message || String(err) }));
|
|
@@ -6218,7 +6551,7 @@ async function verifyEmailOtpLogin(sessionId, code) {
|
|
|
6218
6551
|
email: session.email,
|
|
6219
6552
|
code: cleanCode,
|
|
6220
6553
|
requestId,
|
|
6221
|
-
version: getQwenWebVersion()
|
|
6554
|
+
version: getQwenWebVersion(),
|
|
6222
6555
|
timezone: formatAsciiTimezone()
|
|
6223
6556
|
}
|
|
6224
6557
|
).catch((err) => ({ ok: false, error: err?.message || String(err) }));
|
|
@@ -6265,8 +6598,8 @@ async function verifyEmailOtpLogin(sessionId, code) {
|
|
|
6265
6598
|
saveAuthSession2(session.accountId, {
|
|
6266
6599
|
cookie: `token=${accessToken}`,
|
|
6267
6600
|
userAgent: session.fingerprint.userAgent,
|
|
6268
|
-
bxV:
|
|
6269
|
-
version: getQwenWebVersion()
|
|
6601
|
+
bxV: getQwenBxVersion(),
|
|
6602
|
+
version: getQwenWebVersion(),
|
|
6270
6603
|
userId: userId || void 0,
|
|
6271
6604
|
tokenExpiresAt: exp || void 0,
|
|
6272
6605
|
refreshToken: refreshToken || void 0,
|
|
@@ -6376,7 +6709,7 @@ async function loginToQwen(accountId, email, password) {
|
|
|
6376
6709
|
saveAuthSession2(accountId, {
|
|
6377
6710
|
cookie: cookieStr,
|
|
6378
6711
|
userAgent: cache3.headers["user-agent"] || "",
|
|
6379
|
-
bxV: cache3.headers["bx-v"] ||
|
|
6712
|
+
bxV: cache3.headers["bx-v"] || getQwenBxVersion(),
|
|
6380
6713
|
bxUa: cache3.headers["bx-ua"] || "",
|
|
6381
6714
|
bxUmidtoken: cache3.headers["bx-umidtoken"] || "",
|
|
6382
6715
|
secChUa: cache3.headers["sec-ch-ua"] || void 0,
|
|
@@ -6448,7 +6781,7 @@ async function loginToQwen(accountId, email, password) {
|
|
|
6448
6781
|
saveAuthSession2(accountId, {
|
|
6449
6782
|
cookie: cookieStr,
|
|
6450
6783
|
userAgent: cache3.headers["user-agent"] || "",
|
|
6451
|
-
bxV: cache3.headers["bx-v"] ||
|
|
6784
|
+
bxV: cache3.headers["bx-v"] || getQwenBxVersion(),
|
|
6452
6785
|
bxUa: cache3.headers["bx-ua"] || "",
|
|
6453
6786
|
bxUmidtoken: cache3.headers["bx-umidtoken"] || "",
|
|
6454
6787
|
secChUa: cache3.headers["sec-ch-ua"] || void 0,
|
|
@@ -6519,7 +6852,7 @@ async function loginViaApi(page, email, password) {
|
|
|
6519
6852
|
}
|
|
6520
6853
|
const signinUrl = "https://auth.qwen.ai/api/v2/auths/signin";
|
|
6521
6854
|
const requestId = crypto5.randomUUID();
|
|
6522
|
-
const webVersion = getQwenWebVersion()
|
|
6855
|
+
const webVersion = getQwenWebVersion();
|
|
6523
6856
|
const evalRes = await page.evaluate(
|
|
6524
6857
|
async ({ email: email2, password: password2, signinUrl: signinUrl2, requestId: requestId2, tz, version }) => {
|
|
6525
6858
|
try {
|
|
@@ -6691,6 +7024,15 @@ async function loginViaUi(page, email, password) {
|
|
|
6691
7024
|
if (!page.url().includes("/auth") && await isPageLoggedIn(page, 3e3).catch(() => false)) {
|
|
6692
7025
|
return { success: true };
|
|
6693
7026
|
}
|
|
7027
|
+
if (config.captcha.enabled) {
|
|
7028
|
+
await solveVisibleCaptcha(page, {
|
|
7029
|
+
waitForMs: 1500,
|
|
7030
|
+
maxAttempts: config.captcha.maxAttempts,
|
|
7031
|
+
retryDelayMs: config.captcha.retryDelayMs,
|
|
7032
|
+
settleMs: config.captcha.settleMs,
|
|
7033
|
+
sliderTimeoutMs: config.captcha.sliderTimeoutMs
|
|
7034
|
+
}).catch(() => false);
|
|
7035
|
+
}
|
|
6694
7036
|
const emailSelector = [
|
|
6695
7037
|
'input[type="email"]',
|
|
6696
7038
|
'input[name="email"]',
|
|
@@ -6846,10 +7188,11 @@ async function loginViaUi(page, email, password) {
|
|
|
6846
7188
|
while (Date.now() < postSubmitDeadline) {
|
|
6847
7189
|
if (page.isClosed()) break;
|
|
6848
7190
|
if (config.captcha.enabled) {
|
|
6849
|
-
await
|
|
7191
|
+
await solveVisibleCaptcha(page, {
|
|
6850
7192
|
waitForMs: 1500,
|
|
6851
7193
|
maxAttempts: config.captcha.maxAttempts,
|
|
6852
|
-
retryDelayMs: config.captcha.retryDelayMs
|
|
7194
|
+
retryDelayMs: config.captcha.retryDelayMs,
|
|
7195
|
+
sliderTimeoutMs: config.captcha.sliderTimeoutMs
|
|
6853
7196
|
}).catch(() => {
|
|
6854
7197
|
});
|
|
6855
7198
|
}
|
|
@@ -6972,7 +7315,7 @@ async function refreshAccountToken(accountId) {
|
|
|
6972
7315
|
}
|
|
6973
7316
|
if (refreshToken) {
|
|
6974
7317
|
try {
|
|
6975
|
-
const webVersion = getQwenWebVersion()
|
|
7318
|
+
const webVersion = getQwenWebVersion();
|
|
6976
7319
|
const refreshResult = await page.evaluate(
|
|
6977
7320
|
async ({ rTok, tz, version }) => {
|
|
6978
7321
|
try {
|
|
@@ -7037,7 +7380,7 @@ async function refreshAccountToken(accountId) {
|
|
|
7037
7380
|
saveAuthSession2(accountId, {
|
|
7038
7381
|
cookie: cookieStr,
|
|
7039
7382
|
userAgent: cache3.headers["user-agent"] || session?.userAgent || "",
|
|
7040
|
-
bxV: cache3.headers["bx-v"] || session?.bxV ||
|
|
7383
|
+
bxV: cache3.headers["bx-v"] || session?.bxV || getQwenBxVersion(),
|
|
7041
7384
|
bxUa: cache3.headers["bx-ua"] || session?.bxUa || "",
|
|
7042
7385
|
bxUmidtoken: cache3.headers["bx-umidtoken"] || session?.bxUmidtoken || "",
|
|
7043
7386
|
secChUa: cache3.headers["sec-ch-ua"] || session?.secChUa,
|
|
@@ -7072,7 +7415,7 @@ async function refreshAccountToken(accountId) {
|
|
|
7072
7415
|
saveAuthSession2(accountId, {
|
|
7073
7416
|
cookie: cookieStr,
|
|
7074
7417
|
userAgent: cache3.headers["user-agent"] || session?.userAgent || "",
|
|
7075
|
-
bxV: cache3.headers["bx-v"] || session?.bxV ||
|
|
7418
|
+
bxV: cache3.headers["bx-v"] || session?.bxV || getQwenBxVersion(),
|
|
7076
7419
|
bxUa: cache3.headers["bx-ua"] || session?.bxUa || "",
|
|
7077
7420
|
bxUmidtoken: cache3.headers["bx-umidtoken"] || session?.bxUmidtoken || "",
|
|
7078
7421
|
secChUa: cache3.headers["sec-ch-ua"] || session?.secChUa,
|
|
@@ -7220,7 +7563,7 @@ async function captureQwenHeaders(accountId, pageOverride, timeoutMs = config.ti
|
|
|
7220
7563
|
cookie: reqHeaders["cookie"] || "",
|
|
7221
7564
|
"bx-ua": reqHeaders["bx-ua"] || "",
|
|
7222
7565
|
"bx-umidtoken": reqHeaders["bx-umidtoken"] || "",
|
|
7223
|
-
"bx-v": reqHeaders["bx-v"] ||
|
|
7566
|
+
"bx-v": reqHeaders["bx-v"] || getQwenBxVersion(),
|
|
7224
7567
|
"user-agent": reqHeaders["user-agent"] || "",
|
|
7225
7568
|
"x-request-id": reqHeaders["x-request-id"] || "",
|
|
7226
7569
|
"version": reqHeaders["version"] || "",
|
|
@@ -7252,6 +7595,9 @@ async function captureQwenHeaders(accountId, pageOverride, timeoutMs = config.ti
|
|
|
7252
7595
|
if (capturedHeaders["version"]) {
|
|
7253
7596
|
updateQwenWebVersion(capturedHeaders["version"]);
|
|
7254
7597
|
}
|
|
7598
|
+
if (capturedHeaders["bx-v"]) {
|
|
7599
|
+
updateQwenBxVersion(capturedHeaders["bx-v"]);
|
|
7600
|
+
}
|
|
7255
7601
|
markAccountHeadersReady(accountId);
|
|
7256
7602
|
cache3.lastRefresh = Date.now();
|
|
7257
7603
|
cookieCaches.delete(accountId);
|
|
@@ -7709,7 +8055,7 @@ async function refreshHeadersInternal(accountId, timeoutMs = config.timeouts.hea
|
|
|
7709
8055
|
saveAuthSession2(accountId, {
|
|
7710
8056
|
cookie: cookieStr,
|
|
7711
8057
|
userAgent: cache3.headers["user-agent"] || "",
|
|
7712
|
-
bxV: cache3.headers["bx-v"] ||
|
|
8058
|
+
bxV: cache3.headers["bx-v"] || getQwenBxVersion(),
|
|
7713
8059
|
bxUa: cache3.headers["bx-ua"] || "",
|
|
7714
8060
|
bxUmidtoken: cache3.headers["bx-umidtoken"] || "",
|
|
7715
8061
|
secChUa: cache3.headers["sec-ch-ua"] || void 0,
|
|
@@ -8712,13 +9058,13 @@ async function getBasicHeaders2(accountId) {
|
|
|
8712
9058
|
return {
|
|
8713
9059
|
cookie: "token=mock",
|
|
8714
9060
|
userAgent: "mock",
|
|
8715
|
-
bxV:
|
|
9061
|
+
bxV: getQwenBxVersion(),
|
|
8716
9062
|
bxUa: "mock-bx-ua",
|
|
8717
9063
|
bxUmidtoken: "mock-bx-umidtoken",
|
|
8718
9064
|
secChUa: "",
|
|
8719
9065
|
secChUaMobile: "?0",
|
|
8720
9066
|
secChUaPlatform: "",
|
|
8721
|
-
version:
|
|
9067
|
+
version: getQwenWebVersion()
|
|
8722
9068
|
};
|
|
8723
9069
|
}
|
|
8724
9070
|
const resolvedAccountId = accountId ?? loadAccounts()[0]?.id;
|
|
@@ -8779,6 +9125,7 @@ var init_auth_playwright = __esm({
|
|
|
8779
9125
|
init_errors();
|
|
8780
9126
|
init_accounts();
|
|
8781
9127
|
init_config();
|
|
9128
|
+
init_qwen_headers();
|
|
8782
9129
|
init_playwright();
|
|
8783
9130
|
init_jwt();
|
|
8784
9131
|
}
|
|
@@ -8903,6 +9250,7 @@ var init_model_alias = __esm({
|
|
|
8903
9250
|
DEFAULT_FALLBACK_MODELS = [
|
|
8904
9251
|
"qwen3.8-max",
|
|
8905
9252
|
"qwen3.7-plus",
|
|
9253
|
+
"qwen4.0-max-preview",
|
|
8906
9254
|
"qwen3.8-omni-flash",
|
|
8907
9255
|
"qwen3.7-max",
|
|
8908
9256
|
"qwen3.6-plus",
|
|
@@ -9249,9 +9597,10 @@ async function solveChallengeOnPage(page, challengeUrl, waitForMs = config.captc
|
|
|
9249
9597
|
const solverOptions = {
|
|
9250
9598
|
maxAttempts: config.captcha.maxAttempts,
|
|
9251
9599
|
retryDelayMs: config.captcha.retryDelayMs,
|
|
9252
|
-
settleMs: config.captcha.settleMs
|
|
9600
|
+
settleMs: config.captcha.settleMs,
|
|
9601
|
+
sliderTimeoutMs: config.captcha.sliderTimeoutMs
|
|
9253
9602
|
};
|
|
9254
|
-
if (await
|
|
9603
|
+
if (await solveVisibleCaptcha(page, { ...solverOptions, waitForMs: 0 })) {
|
|
9255
9604
|
return true;
|
|
9256
9605
|
}
|
|
9257
9606
|
logBaxiaCaptcha(
|
|
@@ -9261,7 +9610,7 @@ async function solveChallengeOnPage(page, challengeUrl, waitForMs = config.captc
|
|
|
9261
9610
|
);
|
|
9262
9611
|
await gotoBestEffort(page, challengeUrl ?? qwenUrl("/"));
|
|
9263
9612
|
try {
|
|
9264
|
-
return await
|
|
9613
|
+
return await solveVisibleCaptcha(page, { ...solverOptions, waitForMs });
|
|
9265
9614
|
} finally {
|
|
9266
9615
|
if (page.url().includes(CHALLENGE_PATH_MARKER)) {
|
|
9267
9616
|
await gotoBestEffort(page, qwenUrl("/"));
|
|
@@ -9299,9 +9648,10 @@ async function recoverBaxiaCaptcha(accountId, label, options = {}) {
|
|
|
9299
9648
|
const solverOptions = {
|
|
9300
9649
|
maxAttempts: config.captcha.maxAttempts,
|
|
9301
9650
|
retryDelayMs: config.captcha.retryDelayMs,
|
|
9302
|
-
settleMs: config.captcha.settleMs
|
|
9651
|
+
settleMs: config.captcha.settleMs,
|
|
9652
|
+
sliderTimeoutMs: config.captcha.sliderTimeoutMs
|
|
9303
9653
|
};
|
|
9304
|
-
if (await
|
|
9654
|
+
if (await solveVisibleCaptcha(page, { ...solverOptions, waitForMs: 0 })) {
|
|
9305
9655
|
return true;
|
|
9306
9656
|
}
|
|
9307
9657
|
const ctx = typeof page.context === "function" ? page.context() : null;
|
|
@@ -11618,7 +11968,7 @@ var init_media_generation = __esm({
|
|
|
11618
11968
|
|
|
11619
11969
|
// src/services/qwen-chat-pool.ts
|
|
11620
11970
|
import crypto6 from "crypto";
|
|
11621
|
-
async function createQwenChatSession(headers, model, accountId, chatMode = "thread") {
|
|
11971
|
+
async function createQwenChatSession(headers, model, accountId, chatMode = "thread", captchaRecoveryAttempts = 1) {
|
|
11622
11972
|
if (isAuthMockEnabled()) {
|
|
11623
11973
|
return process.env.TEST_SESSION_ID || "mock-session";
|
|
11624
11974
|
}
|
|
@@ -11646,16 +11996,29 @@ async function createQwenChatSession(headers, model, accountId, chatMode = "thre
|
|
|
11646
11996
|
if (!chatId || typeof chatId !== "string") {
|
|
11647
11997
|
const rawLower = raw.toLowerCase();
|
|
11648
11998
|
if (looksLikeAntiBotChallengeText(raw)) {
|
|
11649
|
-
|
|
11650
|
-
|
|
11651
|
-
|
|
11652
|
-
|
|
11653
|
-
|
|
11654
|
-
|
|
11655
|
-
|
|
11999
|
+
if (captchaRecoveryAttempts > 0) {
|
|
12000
|
+
try {
|
|
12001
|
+
const { recoverBaxiaCaptcha: recoverBaxiaCaptcha2 } = await Promise.resolve().then(() => (init_captcha_coordinator(), captcha_coordinator_exports));
|
|
12002
|
+
const solved = await recoverBaxiaCaptcha2(accountId, "createQwenChatSession", {
|
|
12003
|
+
challengeBody: raw
|
|
12004
|
+
});
|
|
12005
|
+
if (solved) {
|
|
12006
|
+
return createQwenChatSession(
|
|
12007
|
+
headers,
|
|
12008
|
+
model,
|
|
12009
|
+
accountId,
|
|
12010
|
+
chatMode,
|
|
12011
|
+
captchaRecoveryAttempts - 1
|
|
12012
|
+
);
|
|
12013
|
+
}
|
|
12014
|
+
} catch {
|
|
11656
12015
|
}
|
|
11657
|
-
} catch {
|
|
11658
12016
|
}
|
|
12017
|
+
throw new QwenUpstreamError(
|
|
12018
|
+
`Qwen create chat blocked by WAF challenge: ${raw.substring(0, 300)}`,
|
|
12019
|
+
"FAIL_SYS_USER_VALIDATE",
|
|
12020
|
+
403
|
|
12021
|
+
);
|
|
11659
12022
|
}
|
|
11660
12023
|
const isUnauthorized = json?.data?.code?.toLowerCase() === "unauthorized" || json?.code?.toLowerCase() === "unauthorized" || rawLower.includes("unauthorized") || rawLower.includes("permission to access") || rawLower.includes("token has expired") || rawLower.includes("401");
|
|
11661
12024
|
if (isUnauthorized) {
|
|
@@ -11832,6 +12195,20 @@ async function refillQwenChatPool(headers, model, accountId) {
|
|
|
11832
12195
|
console.warn(
|
|
11833
12196
|
`[WarmPool] Account ${accountId || "global"} rate-limited during chat creation. Marked for cooldown.`
|
|
11834
12197
|
);
|
|
12198
|
+
} else if (accountId && (err.upstreamCode === "FAIL_SYS_USER_VALIDATE" || err.upstreamCode === "RGV587_ERROR" || /_____tmd_____|rgv587_error|fail_sys_user_validate/i.test(
|
|
12199
|
+
err.message
|
|
12200
|
+
))) {
|
|
12201
|
+
const existing = getAccountCooldownInfo(accountId);
|
|
12202
|
+
if (existing?.reason === "WafChallenge") {
|
|
12203
|
+
console.warn(
|
|
12204
|
+
`[WarmPool] Account ${accountId} still on WAF quarantine (${Math.ceil(existing.remainingMs / 1e3)}s left); skipping re-escalation.`
|
|
12205
|
+
);
|
|
12206
|
+
} else {
|
|
12207
|
+
const block = recordWafHardBlock(accountId);
|
|
12208
|
+
console.warn(
|
|
12209
|
+
`[WarmPool] Unsolved WAF challenge on ${accountId} during chat creation; quarantined ${Math.ceil(block.cooldownMs / 1e3)}s and rotated the fingerprint.`
|
|
12210
|
+
);
|
|
12211
|
+
}
|
|
11835
12212
|
}
|
|
11836
12213
|
}
|
|
11837
12214
|
if (isToolcallDebugEnabled()) {
|
|
@@ -11867,6 +12244,7 @@ var init_qwen_chat_pool = __esm({
|
|
|
11867
12244
|
init_config();
|
|
11868
12245
|
init_logger();
|
|
11869
12246
|
init_account_manager();
|
|
12247
|
+
init_waf_isolation();
|
|
11870
12248
|
init_model_alias();
|
|
11871
12249
|
init_qwen_url();
|
|
11872
12250
|
init_qwen_errors();
|
|
@@ -12436,7 +12814,7 @@ async function requestQwenTextInBrowser(accountId, method, path21, headers, body
|
|
|
12436
12814
|
browserHeaders["Content-Type"] = "application/json";
|
|
12437
12815
|
}
|
|
12438
12816
|
const evaluateRequest = (page) => page.evaluate(
|
|
12439
|
-
async ({ url: url2, method: method2, headers: headers2, body: body2, referrer, timeoutMs, tz }) => {
|
|
12817
|
+
async ({ url: url2, method: method2, headers: headers2, body: body2, referrer, timeoutMs, tz, version }) => {
|
|
12440
12818
|
const controller = new AbortController();
|
|
12441
12819
|
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
12442
12820
|
try {
|
|
@@ -12458,7 +12836,7 @@ async function requestQwenTextInBrowser(accountId, method, path21, headers, body
|
|
|
12458
12836
|
headers: {
|
|
12459
12837
|
accept: "application/json, text/plain, */*",
|
|
12460
12838
|
source: "web",
|
|
12461
|
-
version
|
|
12839
|
+
version,
|
|
12462
12840
|
"x-request-origin": "https://chat.qwen.ai",
|
|
12463
12841
|
timezone: tz,
|
|
12464
12842
|
authorization: `Bearer ${rTok}`
|
|
@@ -12506,7 +12884,8 @@ async function requestQwenTextInBrowser(accountId, method, path21, headers, body
|
|
|
12506
12884
|
body,
|
|
12507
12885
|
referrer: options.referrer,
|
|
12508
12886
|
timeoutMs: options.timeoutMs ?? Math.min(config.timeouts.page, 2e4),
|
|
12509
|
-
tz: formatAsciiTimezone()
|
|
12887
|
+
tz: formatAsciiTimezone(),
|
|
12888
|
+
version: getQwenWebVersion()
|
|
12510
12889
|
}
|
|
12511
12890
|
);
|
|
12512
12891
|
const recoverOnTimeout = !options.noMutexRecovery;
|
|
@@ -13463,7 +13842,7 @@ async function deleteSingleQwenChat(accountId, chatId) {
|
|
|
13463
13842
|
}
|
|
13464
13843
|
const requestHeaders = {
|
|
13465
13844
|
source: "web",
|
|
13466
|
-
version: getQwenWebVersion()
|
|
13845
|
+
version: getQwenWebVersion(),
|
|
13467
13846
|
timezone: formatAsciiTimezone(),
|
|
13468
13847
|
"x-request-id": crypto7.randomUUID(),
|
|
13469
13848
|
Referer: qwenUrl(`/c/${encodeURIComponent(chatId)}`)
|
|
@@ -13507,7 +13886,7 @@ async function fetchRemoteQwenChats(accountId) {
|
|
|
13507
13886
|
return [];
|
|
13508
13887
|
}
|
|
13509
13888
|
const requestHeaders = {
|
|
13510
|
-
version: getQwenWebVersion()
|
|
13889
|
+
version: getQwenWebVersion(),
|
|
13511
13890
|
timezone: formatAsciiTimezone(),
|
|
13512
13891
|
"x-request-id": crypto7.randomUUID(),
|
|
13513
13892
|
Referer: qwenUrl("/settings/chats")
|
|
@@ -27196,11 +27575,42 @@ var init_server_log_buffer = __esm({
|
|
|
27196
27575
|
// src/services/session-keeper.ts
|
|
27197
27576
|
var session_keeper_exports = {};
|
|
27198
27577
|
__export(session_keeper_exports, {
|
|
27578
|
+
computeSessionKeeperBackoffMs: () => computeSessionKeeperBackoffMs,
|
|
27579
|
+
isSessionKeeperAccountBackedOff: () => isSessionKeeperAccountBackedOff,
|
|
27199
27580
|
isSessionKeeperRunning: () => isSessionKeeperRunning,
|
|
27581
|
+
resetSessionKeeperRetryStateForTests: () => resetSessionKeeperRetryStateForTests,
|
|
27200
27582
|
runSessionKeeperOnceForTesting: () => runSessionKeeperOnceForTesting,
|
|
27201
27583
|
startSessionKeeper: () => startSessionKeeper,
|
|
27202
27584
|
stopSessionKeeper: () => stopSessionKeeper
|
|
27203
27585
|
});
|
|
27586
|
+
function computeSessionKeeperBackoffMs(failures) {
|
|
27587
|
+
const exponent = Math.max(0, Math.min(failures - 1, 8));
|
|
27588
|
+
return Math.min(
|
|
27589
|
+
KEEP_ALIVE_BACKOFF_MAX_MS,
|
|
27590
|
+
KEEP_ALIVE_BACKOFF_BASE_MS * 2 ** exponent
|
|
27591
|
+
);
|
|
27592
|
+
}
|
|
27593
|
+
function isKeepAliveBackedOff(accountId) {
|
|
27594
|
+
const state = keepAliveRetries.get(accountId);
|
|
27595
|
+
return Boolean(state && Date.now() < state.nextAttemptAt);
|
|
27596
|
+
}
|
|
27597
|
+
function recordKeepAliveFailure(accountId) {
|
|
27598
|
+
const state = keepAliveRetries.get(accountId) ?? {
|
|
27599
|
+
failures: 0,
|
|
27600
|
+
nextAttemptAt: 0
|
|
27601
|
+
};
|
|
27602
|
+
state.failures += 1;
|
|
27603
|
+
const backoffMs = computeSessionKeeperBackoffMs(state.failures);
|
|
27604
|
+
state.nextAttemptAt = Date.now() + backoffMs;
|
|
27605
|
+
keepAliveRetries.set(accountId, state);
|
|
27606
|
+
return backoffMs;
|
|
27607
|
+
}
|
|
27608
|
+
function resetSessionKeeperRetryStateForTests() {
|
|
27609
|
+
keepAliveRetries.clear();
|
|
27610
|
+
}
|
|
27611
|
+
function isSessionKeeperAccountBackedOff(accountId) {
|
|
27612
|
+
return isKeepAliveBackedOff(accountId);
|
|
27613
|
+
}
|
|
27204
27614
|
function isSessionKeeperRunning() {
|
|
27205
27615
|
return running;
|
|
27206
27616
|
}
|
|
@@ -27211,13 +27621,25 @@ async function runKeepAliveCycle() {
|
|
|
27211
27621
|
if (config.sessionKeeper.enabled) {
|
|
27212
27622
|
const accountIds = getActivePlaywrightAccountIds();
|
|
27213
27623
|
for (const accountId of accountIds) {
|
|
27214
|
-
|
|
27215
|
-
|
|
27216
|
-
|
|
27217
|
-
|
|
27218
|
-
|
|
27219
|
-
)
|
|
27220
|
-
|
|
27624
|
+
if (isKeepAliveBackedOff(accountId)) {
|
|
27625
|
+
continue;
|
|
27626
|
+
}
|
|
27627
|
+
try {
|
|
27628
|
+
const keptAlive = await keepAlivePlaywrightAccount(accountId);
|
|
27629
|
+
if (keptAlive) {
|
|
27630
|
+
keepAliveRetries.delete(accountId);
|
|
27631
|
+
}
|
|
27632
|
+
} catch (error) {
|
|
27633
|
+
if (isPlaywrightAlreadyClosedError(error)) {
|
|
27634
|
+
keepAliveRetries.delete(accountId);
|
|
27635
|
+
} else {
|
|
27636
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
27637
|
+
const backoffMs = recordKeepAliveFailure(accountId);
|
|
27638
|
+
console.warn(
|
|
27639
|
+
`[SessionKeeper] Keep-alive failed for ${accountId}: ${message} (retry in ${Math.round(backoffMs / 1e3)}s)`
|
|
27640
|
+
);
|
|
27641
|
+
}
|
|
27642
|
+
}
|
|
27221
27643
|
await sleep(humanDelay(250, 900));
|
|
27222
27644
|
}
|
|
27223
27645
|
}
|
|
@@ -27257,11 +27679,12 @@ function stopSessionKeeper() {
|
|
|
27257
27679
|
intervalId = null;
|
|
27258
27680
|
}
|
|
27259
27681
|
cycleInProgress = false;
|
|
27682
|
+
keepAliveRetries.clear();
|
|
27260
27683
|
}
|
|
27261
27684
|
async function runSessionKeeperOnceForTesting() {
|
|
27262
27685
|
await runKeepAliveCycle();
|
|
27263
27686
|
}
|
|
27264
|
-
var running, intervalId, cycleInProgress;
|
|
27687
|
+
var running, intervalId, cycleInProgress, KEEP_ALIVE_BACKOFF_BASE_MS, KEEP_ALIVE_BACKOFF_MAX_MS, keepAliveRetries;
|
|
27265
27688
|
var init_session_keeper = __esm({
|
|
27266
27689
|
"src/services/session-keeper.ts"() {
|
|
27267
27690
|
"use strict";
|
|
@@ -27271,6 +27694,9 @@ var init_session_keeper = __esm({
|
|
|
27271
27694
|
running = false;
|
|
27272
27695
|
intervalId = null;
|
|
27273
27696
|
cycleInProgress = false;
|
|
27697
|
+
KEEP_ALIVE_BACKOFF_BASE_MS = 2e3;
|
|
27698
|
+
KEEP_ALIVE_BACKOFF_MAX_MS = 5 * 6e4;
|
|
27699
|
+
keepAliveRetries = /* @__PURE__ */ new Map();
|
|
27274
27700
|
}
|
|
27275
27701
|
});
|
|
27276
27702
|
|
|
@@ -27296,7 +27722,7 @@ function getAppVersion() {
|
|
|
27296
27722
|
}
|
|
27297
27723
|
} catch {
|
|
27298
27724
|
}
|
|
27299
|
-
cachedVersion = "v1.6.
|
|
27725
|
+
cachedVersion = "v1.6.12";
|
|
27300
27726
|
return cachedVersion;
|
|
27301
27727
|
}
|
|
27302
27728
|
var cachedVersion;
|