qwenproxy-cli 1.5.3 → 1.6.0
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 +205 -22
- package/dist/delete-chats.js +151 -33
- package/dist/index.js +441 -51
- package/dist/login.js +95 -24
- package/dist/reset-cooldowns.js +205 -22
- package/package.json +3 -3
- package/src/api/server.ts +1 -0
- package/src/core/daily-usage.ts +276 -0
- package/src/core/database.ts +27 -1
- package/src/core/version.ts +1 -1
- package/src/routes/chat/account.ts +33 -5
- package/src/routes/chat/index.ts +1 -1
- package/src/routes/chat/streaming.ts +31 -3
- package/src/services/captcha-coordinator.ts +12 -7
- package/src/services/playwright.ts +76 -24
- package/src/services/qwen.ts +65 -9
- package/src/tui/proxy-client.ts +11 -1
- package/src/tui/types.ts +11 -0
- package/src/tui/views/accounts-view.ts +19 -2
- package/src/tui/views/status-view.ts +37 -4
package/dist/clean-cache.js
CHANGED
|
@@ -296,7 +296,26 @@ function runMigrations(db2) {
|
|
|
296
296
|
instruction_hash TEXT NOT NULL,
|
|
297
297
|
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
298
298
|
);
|
|
299
|
+
|
|
300
|
+
CREATE TABLE IF NOT EXISTS account_daily_usage (
|
|
301
|
+
account_id TEXT NOT NULL,
|
|
302
|
+
date_utc TEXT NOT NULL,
|
|
303
|
+
prompt_tokens INTEGER NOT NULL DEFAULT 0,
|
|
304
|
+
completion_tokens INTEGER NOT NULL DEFAULT 0,
|
|
305
|
+
weighted_tokens REAL NOT NULL DEFAULT 0,
|
|
306
|
+
total_tokens INTEGER NOT NULL DEFAULT 0,
|
|
307
|
+
turns_count INTEGER NOT NULL DEFAULT 0,
|
|
308
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
309
|
+
PRIMARY KEY (account_id, date_utc)
|
|
310
|
+
);
|
|
311
|
+
|
|
312
|
+
CREATE INDEX IF NOT EXISTS idx_daily_usage_date ON account_daily_usage(date_utc);
|
|
299
313
|
`);
|
|
314
|
+
try {
|
|
315
|
+
db2.exec(`ALTER TABLE account_daily_usage ADD COLUMN weighted_tokens REAL DEFAULT 0;`);
|
|
316
|
+
} catch (err) {
|
|
317
|
+
if (!isDuplicateColumnError(err)) throw err;
|
|
318
|
+
}
|
|
300
319
|
try {
|
|
301
320
|
db2.exec(
|
|
302
321
|
`ALTER TABLE accounts ADD COLUMN cooldown_until INTEGER DEFAULT 0;`
|
|
@@ -397,7 +416,11 @@ function saveAuthSession(accountId, session) {
|
|
|
397
416
|
) VALUES (
|
|
398
417
|
?, ?, ?, ?, ?, ?,
|
|
399
418
|
?, ?, ?, ?,
|
|
400
|
-
?,
|
|
419
|
+
COALESCE(?, (SELECT user_id FROM qwen_auth_sessions WHERE account_id = ?)),
|
|
420
|
+
?,
|
|
421
|
+
COALESCE(?, (SELECT refresh_token FROM qwen_auth_sessions WHERE account_id = ?)),
|
|
422
|
+
?,
|
|
423
|
+
datetime('now')
|
|
401
424
|
)
|
|
402
425
|
`);
|
|
403
426
|
stmt.run(
|
|
@@ -412,8 +435,10 @@ function saveAuthSession(accountId, session) {
|
|
|
412
435
|
session.secChUaPlatform || null,
|
|
413
436
|
session.version || null,
|
|
414
437
|
session.userId || null,
|
|
438
|
+
accountId,
|
|
415
439
|
session.tokenExpiresAt || null,
|
|
416
440
|
session.refreshToken || null,
|
|
441
|
+
accountId,
|
|
417
442
|
session.capturedAt ?? Date.now()
|
|
418
443
|
);
|
|
419
444
|
}
|
|
@@ -4306,6 +4331,137 @@ async function loginViaUi(page, email, password) {
|
|
|
4306
4331
|
return { success: false, reason: err?.message || String(err) };
|
|
4307
4332
|
}
|
|
4308
4333
|
}
|
|
4334
|
+
async function refreshAccountToken(accountId) {
|
|
4335
|
+
const page = accountPages.get(accountId);
|
|
4336
|
+
if (!page || page.isClosed()) {
|
|
4337
|
+
return { success: false, error: "Account page not active" };
|
|
4338
|
+
}
|
|
4339
|
+
const { getValidAuthSession: getValidAuthSession2, saveAuthSession: saveAuthSession2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
4340
|
+
const session = getValidAuthSession2(accountId);
|
|
4341
|
+
let refreshToken = session?.refreshToken;
|
|
4342
|
+
if (!refreshToken) {
|
|
4343
|
+
try {
|
|
4344
|
+
refreshToken = await page.evaluate(() => localStorage.getItem("refresh_token") || "") || void 0;
|
|
4345
|
+
} catch {
|
|
4346
|
+
}
|
|
4347
|
+
}
|
|
4348
|
+
if (refreshToken) {
|
|
4349
|
+
try {
|
|
4350
|
+
const refreshResult = await page.evaluate(
|
|
4351
|
+
async ({ rTok }) => {
|
|
4352
|
+
try {
|
|
4353
|
+
const response = await fetch("https://auth.qwen.ai/api/v2/auths/refresh", {
|
|
4354
|
+
method: "GET",
|
|
4355
|
+
credentials: "include",
|
|
4356
|
+
headers: {
|
|
4357
|
+
accept: "application/json, text/plain, */*",
|
|
4358
|
+
source: "web",
|
|
4359
|
+
version: "0.3.11",
|
|
4360
|
+
"x-request-origin": "https://chat.qwen.ai",
|
|
4361
|
+
timezone: (/* @__PURE__ */ new Date()).toString().split(" (")[0],
|
|
4362
|
+
authorization: `Bearer ${rTok}`
|
|
4363
|
+
}
|
|
4364
|
+
});
|
|
4365
|
+
const json2 = await response.json().catch(() => null);
|
|
4366
|
+
return { ok: response.ok, status: response.status, data: json2 };
|
|
4367
|
+
} catch (e) {
|
|
4368
|
+
return { ok: false, error: e.message };
|
|
4369
|
+
}
|
|
4370
|
+
},
|
|
4371
|
+
{ rTok: refreshToken }
|
|
4372
|
+
);
|
|
4373
|
+
const json = refreshResult?.data;
|
|
4374
|
+
if (json && json.success === true && json.data) {
|
|
4375
|
+
const newAccessToken = json.data.access_token || json.data.token;
|
|
4376
|
+
const newRefreshToken = json.data.refresh_token || refreshToken;
|
|
4377
|
+
if (newAccessToken) {
|
|
4378
|
+
await page.context().addCookies([
|
|
4379
|
+
{
|
|
4380
|
+
name: "token",
|
|
4381
|
+
value: newAccessToken,
|
|
4382
|
+
domain: ".qwen.ai",
|
|
4383
|
+
path: "/",
|
|
4384
|
+
expires: Math.floor(Date.now() / 1e3) + 31536e3,
|
|
4385
|
+
httpOnly: false,
|
|
4386
|
+
secure: true,
|
|
4387
|
+
sameSite: "Lax"
|
|
4388
|
+
}
|
|
4389
|
+
]);
|
|
4390
|
+
await page.evaluate(
|
|
4391
|
+
({ tok, rTok }) => {
|
|
4392
|
+
try {
|
|
4393
|
+
localStorage.removeItem("qwen_token_logged_out_marker");
|
|
4394
|
+
localStorage.setItem("token", tok);
|
|
4395
|
+
localStorage.setItem("access_token", tok);
|
|
4396
|
+
if (rTok) localStorage.setItem("refresh_token", rTok);
|
|
4397
|
+
document.cookie = `token=${encodeURIComponent(tok)}; path=/; domain=.qwen.ai; max-age=31536000`;
|
|
4398
|
+
} catch {
|
|
4399
|
+
}
|
|
4400
|
+
},
|
|
4401
|
+
{ tok: newAccessToken, rTok: newRefreshToken }
|
|
4402
|
+
).catch(() => {
|
|
4403
|
+
});
|
|
4404
|
+
const liveCookies = await page.context().cookies();
|
|
4405
|
+
const cookieStr = liveCookies.map((c) => `${c.name}=${c.value}`).join("; ");
|
|
4406
|
+
const cache = getHeaderCache(accountId);
|
|
4407
|
+
cache.headers.cookie = cookieStr;
|
|
4408
|
+
cache.lastRefresh = Date.now();
|
|
4409
|
+
markAccountHeadersReady(accountId);
|
|
4410
|
+
saveAuthSession2(accountId, {
|
|
4411
|
+
cookie: cookieStr,
|
|
4412
|
+
userAgent: cache.headers["user-agent"] || session?.userAgent || "",
|
|
4413
|
+
bxV: cache.headers["bx-v"] || session?.bxV || "2.5.37",
|
|
4414
|
+
bxUa: cache.headers["bx-ua"] || session?.bxUa || "",
|
|
4415
|
+
bxUmidtoken: cache.headers["bx-umidtoken"] || session?.bxUmidtoken || "",
|
|
4416
|
+
secChUa: cache.headers["sec-ch-ua"] || session?.secChUa,
|
|
4417
|
+
secChUaMobile: cache.headers["sec-ch-ua-mobile"] || session?.secChUaMobile,
|
|
4418
|
+
secChUaPlatform: cache.headers["sec-ch-ua-platform"] || session?.secChUaPlatform,
|
|
4419
|
+
version: cache.headers["version"] || session?.version,
|
|
4420
|
+
userId: session?.userId,
|
|
4421
|
+
tokenExpiresAt: parseJwtExpiry(newAccessToken) || void 0,
|
|
4422
|
+
refreshToken: newRefreshToken,
|
|
4423
|
+
capturedAt: Date.now()
|
|
4424
|
+
});
|
|
4425
|
+
return { success: true, token: newAccessToken };
|
|
4426
|
+
}
|
|
4427
|
+
}
|
|
4428
|
+
} catch {
|
|
4429
|
+
}
|
|
4430
|
+
}
|
|
4431
|
+
const { getAccountCredentials: getAccountCredentials2 } = await Promise.resolve().then(() => (init_accounts(), accounts_exports));
|
|
4432
|
+
const creds = getAccountCredentials2(accountId);
|
|
4433
|
+
if (creds && creds.email && creds.password) {
|
|
4434
|
+
const apiResult = await loginViaApi(page, creds.email, creds.password);
|
|
4435
|
+
if (apiResult.success) {
|
|
4436
|
+
const liveCookies = await page.context().cookies();
|
|
4437
|
+
const tokenCookie = liveCookies.find((c) => c.name === "token");
|
|
4438
|
+
if (tokenCookie) {
|
|
4439
|
+
const cookieStr = liveCookies.map((c) => `${c.name}=${c.value}`).join("; ");
|
|
4440
|
+
const cache = getHeaderCache(accountId);
|
|
4441
|
+
cache.headers.cookie = cookieStr;
|
|
4442
|
+
cache.lastRefresh = Date.now();
|
|
4443
|
+
markAccountHeadersReady(accountId);
|
|
4444
|
+
saveAuthSession2(accountId, {
|
|
4445
|
+
cookie: cookieStr,
|
|
4446
|
+
userAgent: cache.headers["user-agent"] || session?.userAgent || "",
|
|
4447
|
+
bxV: cache.headers["bx-v"] || session?.bxV || "2.5.37",
|
|
4448
|
+
bxUa: cache.headers["bx-ua"] || session?.bxUa || "",
|
|
4449
|
+
bxUmidtoken: cache.headers["bx-umidtoken"] || session?.bxUmidtoken || "",
|
|
4450
|
+
secChUa: cache.headers["sec-ch-ua"] || session?.secChUa,
|
|
4451
|
+
secChUaMobile: cache.headers["sec-ch-ua-mobile"] || session?.secChUaMobile,
|
|
4452
|
+
secChUaPlatform: cache.headers["sec-ch-ua-platform"] || session?.secChUaPlatform,
|
|
4453
|
+
version: cache.headers["version"] || session?.version,
|
|
4454
|
+
userId: session?.userId,
|
|
4455
|
+
tokenExpiresAt: parseJwtExpiry(tokenCookie.value) || void 0,
|
|
4456
|
+
refreshToken: apiResult.refreshToken,
|
|
4457
|
+
capturedAt: Date.now()
|
|
4458
|
+
});
|
|
4459
|
+
return { success: true, token: tokenCookie.value };
|
|
4460
|
+
}
|
|
4461
|
+
}
|
|
4462
|
+
}
|
|
4463
|
+
return { success: false, error: "Could not refresh or re-authenticate token" };
|
|
4464
|
+
}
|
|
4309
4465
|
async function captureQwenHeaders(accountId, pageOverride, timeoutMs = config.timeouts.headers, triggerGraceMs = HEADER_CAPTURE_TRIGGER_GRACE_MS) {
|
|
4310
4466
|
const page = pageOverride ?? accountPages.get(accountId);
|
|
4311
4467
|
if (!page || page.isClosed()) {
|
|
@@ -4459,6 +4615,11 @@ async function captureQwenHeaders(accountId, pageOverride, timeoutMs = config.ti
|
|
|
4459
4615
|
const { saveAuthSession: saveAuthSession2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
4460
4616
|
const { parseJwtExpiry: parseJwtExpiry2 } = await Promise.resolve().then(() => (init_jwt(), jwt_exports));
|
|
4461
4617
|
const tokenExpiry = parseJwtExpiry2(capturedHeaders.cookie);
|
|
4618
|
+
let rTok;
|
|
4619
|
+
try {
|
|
4620
|
+
rTok = (await page.evaluate(() => localStorage.getItem("refresh_token") || "")).trim() || void 0;
|
|
4621
|
+
} catch {
|
|
4622
|
+
}
|
|
4462
4623
|
saveAuthSession2(accountId, {
|
|
4463
4624
|
cookie: capturedHeaders.cookie,
|
|
4464
4625
|
userAgent: capturedHeaders["user-agent"],
|
|
@@ -4470,6 +4631,7 @@ async function captureQwenHeaders(accountId, pageOverride, timeoutMs = config.ti
|
|
|
4470
4631
|
secChUaPlatform: capturedHeaders["sec-ch-ua-platform"],
|
|
4471
4632
|
version: capturedHeaders["version"],
|
|
4472
4633
|
tokenExpiresAt: tokenExpiry || void 0,
|
|
4634
|
+
refreshToken: rTok,
|
|
4473
4635
|
capturedAt: Date.now()
|
|
4474
4636
|
});
|
|
4475
4637
|
} catch {
|
|
@@ -4501,38 +4663,57 @@ async function captureQwenHeaders(accountId, pageOverride, timeoutMs = config.ti
|
|
|
4501
4663
|
const isAuthUrl = currentUrl.includes("/auth") || currentUrl.includes("/login");
|
|
4502
4664
|
const isSuspectedGuest = isAuthUrl || attempt >= 2 && !await isPageLoggedIn(page, 5e3);
|
|
4503
4665
|
if (isSuspectedGuest) {
|
|
4504
|
-
const
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
`\u26A0\uFE0F [Playwright] Session expired or guest state detected during header capture for ${accountId}; re-authenticating...`
|
|
4666
|
+
const silentRefresh = await refreshAccountToken(accountId);
|
|
4667
|
+
if (silentRefresh.success) {
|
|
4668
|
+
console.log(
|
|
4669
|
+
`\u26A1 [Playwright] Token refreshed silently during header capture for ${accountId}`
|
|
4509
4670
|
);
|
|
4510
|
-
|
|
4511
|
-
const ok = await loginToQwen(accountId, creds.email, creds.password);
|
|
4512
|
-
if (ok) {
|
|
4671
|
+
if (isAuthUrl) {
|
|
4513
4672
|
await page.goto(qwenUrl("/"), {
|
|
4514
4673
|
waitUntil: "domcontentloaded",
|
|
4515
4674
|
timeout: Math.min(config.timeouts.navigation, timeoutMs)
|
|
4516
4675
|
});
|
|
4517
|
-
await sleep2(
|
|
4676
|
+
await sleep2(1500);
|
|
4677
|
+
}
|
|
4678
|
+
if (await isPageLoggedIn(page, 5e3)) {
|
|
4679
|
+
armOverallDeadline();
|
|
4518
4680
|
}
|
|
4519
|
-
|
|
4681
|
+
}
|
|
4682
|
+
const stillSuspected = !silentRefresh.success || !await isPageLoggedIn(page, 2e3);
|
|
4683
|
+
if (stillSuspected) {
|
|
4684
|
+
const { getAccountCredentials: getAccountCredentials2 } = await Promise.resolve().then(() => (init_accounts(), accounts_exports));
|
|
4685
|
+
const creds = getAccountCredentials2(accountId);
|
|
4686
|
+
if (creds && creds.email && creds.password) {
|
|
4687
|
+
console.warn(
|
|
4688
|
+
`\u26A0\uFE0F [Playwright] Session expired or guest state detected during header capture for ${accountId}; re-authenticating...`
|
|
4689
|
+
);
|
|
4690
|
+
armOverallDeadline();
|
|
4691
|
+
const ok = await loginToQwen(accountId, creds.email, creds.password);
|
|
4692
|
+
if (ok) {
|
|
4693
|
+
await page.goto(qwenUrl("/"), {
|
|
4694
|
+
waitUntil: "domcontentloaded",
|
|
4695
|
+
timeout: Math.min(config.timeouts.navigation, timeoutMs)
|
|
4696
|
+
});
|
|
4697
|
+
await sleep2(2e3);
|
|
4698
|
+
}
|
|
4699
|
+
if (!ok || !await isPageLoggedIn(page, 6e3)) {
|
|
4700
|
+
settle(
|
|
4701
|
+
new Error(
|
|
4702
|
+
`Header capture failed for ${accountId}: re-login after session expiry did not succeed`
|
|
4703
|
+
)
|
|
4704
|
+
);
|
|
4705
|
+
return;
|
|
4706
|
+
}
|
|
4707
|
+
armOverallDeadline();
|
|
4708
|
+
if (settled || page.isClosed()) return;
|
|
4709
|
+
} else {
|
|
4520
4710
|
settle(
|
|
4521
4711
|
new Error(
|
|
4522
|
-
`Header capture failed for ${accountId}: re-login
|
|
4712
|
+
`Header capture failed for ${accountId}: session expired and no credentials available for re-login (run 'qpx login')`
|
|
4523
4713
|
)
|
|
4524
4714
|
);
|
|
4525
4715
|
return;
|
|
4526
4716
|
}
|
|
4527
|
-
armOverallDeadline();
|
|
4528
|
-
if (settled || page.isClosed()) return;
|
|
4529
|
-
} else {
|
|
4530
|
-
settle(
|
|
4531
|
-
new Error(
|
|
4532
|
-
`Header capture failed for ${accountId}: session expired and no credentials available for re-login (run 'qpx login')`
|
|
4533
|
-
)
|
|
4534
|
-
);
|
|
4535
|
-
return;
|
|
4536
4717
|
}
|
|
4537
4718
|
}
|
|
4538
4719
|
if (settled || page.isClosed()) return;
|
|
@@ -5022,6 +5203,7 @@ function cleanupPlaywrightAccountState(accountId) {
|
|
|
5022
5203
|
cookieCaches.delete(accountId);
|
|
5023
5204
|
lastAccountActivity.delete(accountId);
|
|
5024
5205
|
lastKeepAliveNavigation.delete(accountId);
|
|
5206
|
+
lastProactiveTokenRefresh.delete(accountId);
|
|
5025
5207
|
clearFingerprintCache(accountId);
|
|
5026
5208
|
unmarkAccountHeadersReady(accountId);
|
|
5027
5209
|
}
|
|
@@ -5096,7 +5278,7 @@ async function closePlaywrightForAccount(accountId) {
|
|
|
5096
5278
|
release();
|
|
5097
5279
|
}
|
|
5098
5280
|
}
|
|
5099
|
-
var requireLocal, contextInitHooks, ACCOUNT_MUTEX_MAX_HOLD_MS, accountMutexes, accountContexts, accountPages, inFlightAccountInits, headerCaches, HEADER_CACHE_TTL, COOKIE_CACHE_TTL, cookieCaches, lastAccountActivity, lastKeepAliveNavigation, 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;
|
|
5281
|
+
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;
|
|
5100
5282
|
var init_playwright = __esm({
|
|
5101
5283
|
"src/services/playwright.ts"() {
|
|
5102
5284
|
"use strict";
|
|
@@ -5128,6 +5310,7 @@ var init_playwright = __esm({
|
|
|
5128
5310
|
cookieCaches = /* @__PURE__ */ new Map();
|
|
5129
5311
|
lastAccountActivity = /* @__PURE__ */ new Map();
|
|
5130
5312
|
lastKeepAliveNavigation = /* @__PURE__ */ new Map();
|
|
5313
|
+
lastProactiveTokenRefresh = /* @__PURE__ */ new Map();
|
|
5131
5314
|
profileResetQueue = /* @__PURE__ */ new Map();
|
|
5132
5315
|
profileResetChain = Promise.resolve();
|
|
5133
5316
|
closingAllPlaywright = false;
|
package/dist/delete-chats.js
CHANGED
|
@@ -296,7 +296,26 @@ function runMigrations(db2) {
|
|
|
296
296
|
instruction_hash TEXT NOT NULL,
|
|
297
297
|
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
298
298
|
);
|
|
299
|
+
|
|
300
|
+
CREATE TABLE IF NOT EXISTS account_daily_usage (
|
|
301
|
+
account_id TEXT NOT NULL,
|
|
302
|
+
date_utc TEXT NOT NULL,
|
|
303
|
+
prompt_tokens INTEGER NOT NULL DEFAULT 0,
|
|
304
|
+
completion_tokens INTEGER NOT NULL DEFAULT 0,
|
|
305
|
+
weighted_tokens REAL NOT NULL DEFAULT 0,
|
|
306
|
+
total_tokens INTEGER NOT NULL DEFAULT 0,
|
|
307
|
+
turns_count INTEGER NOT NULL DEFAULT 0,
|
|
308
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
309
|
+
PRIMARY KEY (account_id, date_utc)
|
|
310
|
+
);
|
|
311
|
+
|
|
312
|
+
CREATE INDEX IF NOT EXISTS idx_daily_usage_date ON account_daily_usage(date_utc);
|
|
299
313
|
`);
|
|
314
|
+
try {
|
|
315
|
+
db2.exec(`ALTER TABLE account_daily_usage ADD COLUMN weighted_tokens REAL DEFAULT 0;`);
|
|
316
|
+
} catch (err) {
|
|
317
|
+
if (!isDuplicateColumnError(err)) throw err;
|
|
318
|
+
}
|
|
300
319
|
try {
|
|
301
320
|
db2.exec(
|
|
302
321
|
`ALTER TABLE accounts ADD COLUMN cooldown_until INTEGER DEFAULT 0;`
|
|
@@ -397,7 +416,11 @@ function saveAuthSession(accountId, session) {
|
|
|
397
416
|
) VALUES (
|
|
398
417
|
?, ?, ?, ?, ?, ?,
|
|
399
418
|
?, ?, ?, ?,
|
|
400
|
-
?,
|
|
419
|
+
COALESCE(?, (SELECT user_id FROM qwen_auth_sessions WHERE account_id = ?)),
|
|
420
|
+
?,
|
|
421
|
+
COALESCE(?, (SELECT refresh_token FROM qwen_auth_sessions WHERE account_id = ?)),
|
|
422
|
+
?,
|
|
423
|
+
datetime('now')
|
|
401
424
|
)
|
|
402
425
|
`);
|
|
403
426
|
stmt.run(
|
|
@@ -412,8 +435,10 @@ function saveAuthSession(accountId, session) {
|
|
|
412
435
|
session.secChUaPlatform || null,
|
|
413
436
|
session.version || null,
|
|
414
437
|
session.userId || null,
|
|
438
|
+
accountId,
|
|
415
439
|
session.tokenExpiresAt || null,
|
|
416
440
|
session.refreshToken || null,
|
|
441
|
+
accountId,
|
|
417
442
|
session.capturedAt ?? Date.now()
|
|
418
443
|
);
|
|
419
444
|
}
|
|
@@ -4039,6 +4064,11 @@ async function getBasicHeaders(accountId) {
|
|
|
4039
4064
|
if (!page) {
|
|
4040
4065
|
throw new Error(`Playwright not initialized for account: ${accountId}`);
|
|
4041
4066
|
}
|
|
4067
|
+
const inFlightInit = inFlightAccountInits.get(accountId);
|
|
4068
|
+
if (inFlightInit) {
|
|
4069
|
+
await inFlightInit.catch(() => {
|
|
4070
|
+
});
|
|
4071
|
+
}
|
|
4042
4072
|
const release = await acquireAccountMutex(
|
|
4043
4073
|
accountId,
|
|
4044
4074
|
`headers:${accountId.substring(0, 12)}`
|
|
@@ -5513,6 +5543,11 @@ async function captureQwenHeaders(accountId, pageOverride, timeoutMs = config.ti
|
|
|
5513
5543
|
const { saveAuthSession: saveAuthSession2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
5514
5544
|
const { parseJwtExpiry: parseJwtExpiry2 } = await Promise.resolve().then(() => (init_jwt(), jwt_exports));
|
|
5515
5545
|
const tokenExpiry = parseJwtExpiry2(capturedHeaders.cookie);
|
|
5546
|
+
let rTok;
|
|
5547
|
+
try {
|
|
5548
|
+
rTok = (await page.evaluate(() => localStorage.getItem("refresh_token") || "")).trim() || void 0;
|
|
5549
|
+
} catch {
|
|
5550
|
+
}
|
|
5516
5551
|
saveAuthSession2(accountId, {
|
|
5517
5552
|
cookie: capturedHeaders.cookie,
|
|
5518
5553
|
userAgent: capturedHeaders["user-agent"],
|
|
@@ -5524,6 +5559,7 @@ async function captureQwenHeaders(accountId, pageOverride, timeoutMs = config.ti
|
|
|
5524
5559
|
secChUaPlatform: capturedHeaders["sec-ch-ua-platform"],
|
|
5525
5560
|
version: capturedHeaders["version"],
|
|
5526
5561
|
tokenExpiresAt: tokenExpiry || void 0,
|
|
5562
|
+
refreshToken: rTok,
|
|
5527
5563
|
capturedAt: Date.now()
|
|
5528
5564
|
});
|
|
5529
5565
|
} catch {
|
|
@@ -5555,38 +5591,57 @@ async function captureQwenHeaders(accountId, pageOverride, timeoutMs = config.ti
|
|
|
5555
5591
|
const isAuthUrl = currentUrl.includes("/auth") || currentUrl.includes("/login");
|
|
5556
5592
|
const isSuspectedGuest = isAuthUrl || attempt >= 2 && !await isPageLoggedIn(page, 5e3);
|
|
5557
5593
|
if (isSuspectedGuest) {
|
|
5558
|
-
const
|
|
5559
|
-
|
|
5560
|
-
|
|
5561
|
-
|
|
5562
|
-
`\u26A0\uFE0F [Playwright] Session expired or guest state detected during header capture for ${accountId}; re-authenticating...`
|
|
5594
|
+
const silentRefresh = await refreshAccountToken(accountId);
|
|
5595
|
+
if (silentRefresh.success) {
|
|
5596
|
+
console.log(
|
|
5597
|
+
`\u26A1 [Playwright] Token refreshed silently during header capture for ${accountId}`
|
|
5563
5598
|
);
|
|
5564
|
-
|
|
5565
|
-
const ok = await loginToQwen(accountId, creds.email, creds.password);
|
|
5566
|
-
if (ok) {
|
|
5599
|
+
if (isAuthUrl) {
|
|
5567
5600
|
await page.goto(qwenUrl("/"), {
|
|
5568
5601
|
waitUntil: "domcontentloaded",
|
|
5569
5602
|
timeout: Math.min(config.timeouts.navigation, timeoutMs)
|
|
5570
5603
|
});
|
|
5571
|
-
await sleep2(
|
|
5604
|
+
await sleep2(1500);
|
|
5572
5605
|
}
|
|
5573
|
-
if (
|
|
5606
|
+
if (await isPageLoggedIn(page, 5e3)) {
|
|
5607
|
+
armOverallDeadline();
|
|
5608
|
+
}
|
|
5609
|
+
}
|
|
5610
|
+
const stillSuspected = !silentRefresh.success || !await isPageLoggedIn(page, 2e3);
|
|
5611
|
+
if (stillSuspected) {
|
|
5612
|
+
const { getAccountCredentials: getAccountCredentials2 } = await Promise.resolve().then(() => (init_accounts(), accounts_exports));
|
|
5613
|
+
const creds = getAccountCredentials2(accountId);
|
|
5614
|
+
if (creds && creds.email && creds.password) {
|
|
5615
|
+
console.warn(
|
|
5616
|
+
`\u26A0\uFE0F [Playwright] Session expired or guest state detected during header capture for ${accountId}; re-authenticating...`
|
|
5617
|
+
);
|
|
5618
|
+
armOverallDeadline();
|
|
5619
|
+
const ok = await loginToQwen(accountId, creds.email, creds.password);
|
|
5620
|
+
if (ok) {
|
|
5621
|
+
await page.goto(qwenUrl("/"), {
|
|
5622
|
+
waitUntil: "domcontentloaded",
|
|
5623
|
+
timeout: Math.min(config.timeouts.navigation, timeoutMs)
|
|
5624
|
+
});
|
|
5625
|
+
await sleep2(2e3);
|
|
5626
|
+
}
|
|
5627
|
+
if (!ok || !await isPageLoggedIn(page, 6e3)) {
|
|
5628
|
+
settle(
|
|
5629
|
+
new Error(
|
|
5630
|
+
`Header capture failed for ${accountId}: re-login after session expiry did not succeed`
|
|
5631
|
+
)
|
|
5632
|
+
);
|
|
5633
|
+
return;
|
|
5634
|
+
}
|
|
5635
|
+
armOverallDeadline();
|
|
5636
|
+
if (settled || page.isClosed()) return;
|
|
5637
|
+
} else {
|
|
5574
5638
|
settle(
|
|
5575
5639
|
new Error(
|
|
5576
|
-
`Header capture failed for ${accountId}: re-login
|
|
5640
|
+
`Header capture failed for ${accountId}: session expired and no credentials available for re-login (run 'qpx login')`
|
|
5577
5641
|
)
|
|
5578
5642
|
);
|
|
5579
5643
|
return;
|
|
5580
5644
|
}
|
|
5581
|
-
armOverallDeadline();
|
|
5582
|
-
if (settled || page.isClosed()) return;
|
|
5583
|
-
} else {
|
|
5584
|
-
settle(
|
|
5585
|
-
new Error(
|
|
5586
|
-
`Header capture failed for ${accountId}: session expired and no credentials available for re-login (run 'qpx login')`
|
|
5587
|
-
)
|
|
5588
|
-
);
|
|
5589
|
-
return;
|
|
5590
5645
|
}
|
|
5591
5646
|
}
|
|
5592
5647
|
if (settled || page.isClosed()) return;
|
|
@@ -5902,7 +5957,13 @@ async function refreshHeadersInternal(accountId, timeoutMs = config.timeouts.hea
|
|
|
5902
5957
|
`[Playwright] Navigation check failed during refresh for ${accountId}:`,
|
|
5903
5958
|
navErr.message
|
|
5904
5959
|
);
|
|
5905
|
-
await
|
|
5960
|
+
if (await isPageLoggedIn(page, 3e3)) {
|
|
5961
|
+
} else {
|
|
5962
|
+
const refreshed = await refreshAccountToken(accountId);
|
|
5963
|
+
if (!refreshed.success) {
|
|
5964
|
+
await executeReauth();
|
|
5965
|
+
}
|
|
5966
|
+
}
|
|
5906
5967
|
}
|
|
5907
5968
|
}
|
|
5908
5969
|
if (hasRequiredQwenHeaders(cache.headers)) {
|
|
@@ -5916,6 +5977,11 @@ async function refreshHeadersInternal(accountId, timeoutMs = config.timeouts.hea
|
|
|
5916
5977
|
const { saveAuthSession: saveAuthSession2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
5917
5978
|
const tokenCookie = liveCookies.find((c) => c.name === "token");
|
|
5918
5979
|
const exp = tokenCookie ? parseJwtExpiry(tokenCookie.value) : void 0;
|
|
5980
|
+
let rTok;
|
|
5981
|
+
try {
|
|
5982
|
+
rTok = (await page.evaluate(() => localStorage.getItem("refresh_token") || "")).trim() || void 0;
|
|
5983
|
+
} catch {
|
|
5984
|
+
}
|
|
5919
5985
|
saveAuthSession2(accountId, {
|
|
5920
5986
|
cookie: cookieStr,
|
|
5921
5987
|
userAgent: cache.headers["user-agent"] || "",
|
|
@@ -5927,6 +5993,7 @@ async function refreshHeadersInternal(accountId, timeoutMs = config.timeouts.hea
|
|
|
5927
5993
|
secChUaPlatform: cache.headers["sec-ch-ua-platform"] || void 0,
|
|
5928
5994
|
version: cache.headers["version"] || void 0,
|
|
5929
5995
|
tokenExpiresAt: exp || void 0,
|
|
5996
|
+
refreshToken: rTok,
|
|
5930
5997
|
capturedAt: Date.now()
|
|
5931
5998
|
});
|
|
5932
5999
|
} catch {
|
|
@@ -6313,8 +6380,10 @@ async function keepAlivePlaywrightAccount(accountId) {
|
|
|
6313
6380
|
if (!page || page.isClosed()) return false;
|
|
6314
6381
|
const now = Date.now();
|
|
6315
6382
|
const currentUrl = page.url();
|
|
6383
|
+
const lastRefreshAttempt = lastProactiveTokenRefresh.get(accountId) ?? 0;
|
|
6316
6384
|
const cookie = await getCookies(accountId);
|
|
6317
|
-
if (cookie && isTokenExpiringSoon(cookie, 5)) {
|
|
6385
|
+
if (cookie && isTokenExpiringSoon(cookie, 5) && now - lastRefreshAttempt > 6e4) {
|
|
6386
|
+
lastProactiveTokenRefresh.set(accountId, now);
|
|
6318
6387
|
console.log(
|
|
6319
6388
|
`\u{1F493} [SessionKeeper] Account ${accountId} access token expiring soon (<5m); silently refreshing...`
|
|
6320
6389
|
);
|
|
@@ -6358,6 +6427,7 @@ function cleanupPlaywrightAccountState(accountId) {
|
|
|
6358
6427
|
cookieCaches.delete(accountId);
|
|
6359
6428
|
lastAccountActivity.delete(accountId);
|
|
6360
6429
|
lastKeepAliveNavigation.delete(accountId);
|
|
6430
|
+
lastProactiveTokenRefresh.delete(accountId);
|
|
6361
6431
|
clearFingerprintCache(accountId);
|
|
6362
6432
|
unmarkAccountHeadersReady(accountId);
|
|
6363
6433
|
}
|
|
@@ -6541,7 +6611,7 @@ async function getTokenDiagnostics(accountId) {
|
|
|
6541
6611
|
}
|
|
6542
6612
|
};
|
|
6543
6613
|
}
|
|
6544
|
-
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, 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;
|
|
6614
|
+
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;
|
|
6545
6615
|
var init_playwright = __esm({
|
|
6546
6616
|
"src/services/playwright.ts"() {
|
|
6547
6617
|
"use strict";
|
|
@@ -6577,6 +6647,7 @@ var init_playwright = __esm({
|
|
|
6577
6647
|
cookieCaches = /* @__PURE__ */ new Map();
|
|
6578
6648
|
lastAccountActivity = /* @__PURE__ */ new Map();
|
|
6579
6649
|
lastKeepAliveNavigation = /* @__PURE__ */ new Map();
|
|
6650
|
+
lastProactiveTokenRefresh = /* @__PURE__ */ new Map();
|
|
6580
6651
|
profileResetQueue = /* @__PURE__ */ new Map();
|
|
6581
6652
|
profileResetChain = Promise.resolve();
|
|
6582
6653
|
closingAllPlaywright = false;
|
|
@@ -7112,9 +7183,13 @@ var init_model_registry = __esm({
|
|
|
7112
7183
|
// src/services/captcha-coordinator.ts
|
|
7113
7184
|
var captcha_coordinator_exports = {};
|
|
7114
7185
|
__export(captcha_coordinator_exports, {
|
|
7186
|
+
isCaptchaRecoveryActive: () => isCaptchaRecoveryActive,
|
|
7115
7187
|
recoverBaxiaCaptcha: () => recoverBaxiaCaptcha,
|
|
7116
7188
|
solveChallengeOnPage: () => solveChallengeOnPage
|
|
7117
7189
|
});
|
|
7190
|
+
function isCaptchaRecoveryActive(accountId) {
|
|
7191
|
+
return activeCaptchaRecoveries.has(accountId);
|
|
7192
|
+
}
|
|
7118
7193
|
async function gotoBestEffort(page, url) {
|
|
7119
7194
|
await page.goto(url, {
|
|
7120
7195
|
waitUntil: "domcontentloaded",
|
|
@@ -7157,11 +7232,12 @@ async function recoverBaxiaCaptcha(accountId, label, options = {}) {
|
|
|
7157
7232
|
return false;
|
|
7158
7233
|
}
|
|
7159
7234
|
metrics.increment("captcha.challenges.detected", 1, { solver });
|
|
7160
|
-
const challengeUrl = options.challengeBody ? extractBaxiaChallengeUrl(options.challengeBody, config.qwen.baseUrl) : null;
|
|
7161
7235
|
const solverOperationTimeoutMs = Math.max(
|
|
7162
7236
|
15e3,
|
|
7163
7237
|
config.captcha.timeoutMs + config.captcha.maxAttempts * (3e3 + config.captcha.retryDelayMs + config.captcha.settleMs) + 2 * CHALLENGE_NAVIGATION_TIMEOUT_MS
|
|
7164
7238
|
);
|
|
7239
|
+
const challengeUrl = options.challengeBody ? extractBaxiaChallengeUrl(options.challengeBody, config.qwen.baseUrl) : null;
|
|
7240
|
+
activeCaptchaRecoveries.add(accountId);
|
|
7165
7241
|
try {
|
|
7166
7242
|
const solved = await withAccountPage(
|
|
7167
7243
|
accountId,
|
|
@@ -7194,9 +7270,11 @@ async function recoverBaxiaCaptcha(accountId, label, options = {}) {
|
|
|
7194
7270
|
detail
|
|
7195
7271
|
});
|
|
7196
7272
|
return false;
|
|
7273
|
+
} finally {
|
|
7274
|
+
activeCaptchaRecoveries.delete(accountId);
|
|
7197
7275
|
}
|
|
7198
7276
|
}
|
|
7199
|
-
var CHALLENGE_NAVIGATION_TIMEOUT_MS, CHALLENGE_PATH_MARKER, FAILED_RECOVERY_BACKOFF_MS, lastFailedRecoveryAt;
|
|
7277
|
+
var CHALLENGE_NAVIGATION_TIMEOUT_MS, CHALLENGE_PATH_MARKER, FAILED_RECOVERY_BACKOFF_MS, lastFailedRecoveryAt, activeCaptchaRecoveries;
|
|
7200
7278
|
var init_captcha_coordinator = __esm({
|
|
7201
7279
|
"src/services/captcha-coordinator.ts"() {
|
|
7202
7280
|
"use strict";
|
|
@@ -7209,6 +7287,7 @@ var init_captcha_coordinator = __esm({
|
|
|
7209
7287
|
CHALLENGE_PATH_MARKER = "_____tmd_____";
|
|
7210
7288
|
FAILED_RECOVERY_BACKOFF_MS = 3e4;
|
|
7211
7289
|
lastFailedRecoveryAt = /* @__PURE__ */ new Map();
|
|
7290
|
+
activeCaptchaRecoveries = /* @__PURE__ */ new Set();
|
|
7212
7291
|
}
|
|
7213
7292
|
});
|
|
7214
7293
|
|
|
@@ -7941,6 +8020,7 @@ __export(qwen_exports, {
|
|
|
7941
8020
|
fetchRemoteQwenChats: () => fetchRemoteQwenChats,
|
|
7942
8021
|
flushLogicalThreadState: () => flushLogicalThreadState,
|
|
7943
8022
|
getAnyCachedQwenModels: () => getAnyCachedQwenModels,
|
|
8023
|
+
getInFlightPersonalizationCount: () => getInFlightPersonalizationCount,
|
|
7944
8024
|
getLogicalThreadState: () => getLogicalThreadState,
|
|
7945
8025
|
getQwenErrorCode: () => getQwenErrorCode,
|
|
7946
8026
|
getSessionParent: () => getSessionParent,
|
|
@@ -8873,12 +8953,51 @@ async function createQwenBrowserResponse(accountId, url, method, headers, body,
|
|
|
8873
8953
|
captchaWatcher?.stop();
|
|
8874
8954
|
}
|
|
8875
8955
|
}
|
|
8956
|
+
function getInFlightPersonalizationCount() {
|
|
8957
|
+
return inFlightPersonalizationSyncs.size;
|
|
8958
|
+
}
|
|
8876
8959
|
async function syncQwenRequestPersonalization(instruction, accountId, metadata = {}) {
|
|
8877
|
-
if (isAuthMockEnabled()) {
|
|
8878
|
-
if (process.env.TEST_PERSONALIZATION_SYNC_FAIL === "true") return false;
|
|
8879
|
-
return true;
|
|
8880
|
-
}
|
|
8881
8960
|
const cacheKey = accountId || "global";
|
|
8961
|
+
const sent = textSize(instruction);
|
|
8962
|
+
const syncHash = sent.hash ? `${sent.hash}:${QWEN_SAFE_SETTINGS_HASH}` : null;
|
|
8963
|
+
const inFlightKey = `${cacheKey}:${syncHash || "empty"}`;
|
|
8964
|
+
const existingInFlight = inFlightPersonalizationSyncs.get(inFlightKey);
|
|
8965
|
+
if (existingInFlight) {
|
|
8966
|
+
logger.debug("[Qwen] Personalization sync already in flight, sharing promise", {
|
|
8967
|
+
accountId: cacheKey
|
|
8968
|
+
});
|
|
8969
|
+
return existingInFlight;
|
|
8970
|
+
}
|
|
8971
|
+
let syncPromise;
|
|
8972
|
+
syncPromise = (async () => {
|
|
8973
|
+
await Promise.resolve();
|
|
8974
|
+
try {
|
|
8975
|
+
if (isAuthMockEnabled()) {
|
|
8976
|
+
const delay = parseInt(process.env.TEST_PERSONALIZATION_DELAY_MS || "0", 10);
|
|
8977
|
+
if (delay > 0) {
|
|
8978
|
+
await sleep4(delay);
|
|
8979
|
+
}
|
|
8980
|
+
if (process.env.TEST_PERSONALIZATION_SYNC_FAIL === "true") return false;
|
|
8981
|
+
return true;
|
|
8982
|
+
}
|
|
8983
|
+
return await syncQwenRequestPersonalizationInternal(
|
|
8984
|
+
instruction,
|
|
8985
|
+
accountId,
|
|
8986
|
+
metadata,
|
|
8987
|
+
cacheKey,
|
|
8988
|
+
sent,
|
|
8989
|
+
syncHash
|
|
8990
|
+
);
|
|
8991
|
+
} finally {
|
|
8992
|
+
if (inFlightPersonalizationSyncs.get(inFlightKey) === syncPromise) {
|
|
8993
|
+
inFlightPersonalizationSyncs.delete(inFlightKey);
|
|
8994
|
+
}
|
|
8995
|
+
}
|
|
8996
|
+
})();
|
|
8997
|
+
inFlightPersonalizationSyncs.set(inFlightKey, syncPromise);
|
|
8998
|
+
return syncPromise;
|
|
8999
|
+
}
|
|
9000
|
+
async function syncQwenRequestPersonalizationInternal(instruction, accountId, metadata, cacheKey, sent, syncHash) {
|
|
8882
9001
|
let forceRefresh = false;
|
|
8883
9002
|
try {
|
|
8884
9003
|
const basic = await getBasicHeaders2(accountId);
|
|
@@ -8896,8 +9015,6 @@ async function syncQwenRequestPersonalization(instruction, accountId, metadata =
|
|
|
8896
9015
|
});
|
|
8897
9016
|
let currentSettings = null;
|
|
8898
9017
|
let payload = buildQwenSettingsUpdatePayload(currentSettings, instruction);
|
|
8899
|
-
const sent = textSize(instruction);
|
|
8900
|
-
const syncHash = sent.hash ? `${sent.hash}:${QWEN_SAFE_SETTINGS_HASH}` : null;
|
|
8901
9018
|
const bypassCache = metadata.forceSync === true;
|
|
8902
9019
|
const cachedHash = lastSyncedPersonalizationHashes.get(cacheKey);
|
|
8903
9020
|
if (!bypassCache && syncHash && cachedHash === syncHash) {
|
|
@@ -10242,7 +10359,7 @@ async function createQwenStreamInternal(prompt, enableThinking, modelId, forcedP
|
|
|
10242
10359
|
clearTimeout(timeoutId);
|
|
10243
10360
|
}
|
|
10244
10361
|
}
|
|
10245
|
-
var sleep4, BROWSER_STREAM_BINDING, BROWSER_ABORTERS_KEY, BROWSER_STREAM_FLUSH_BYTES, BROWSER_STREAM_FLUSH_MS, METADATA_TIMEOUT_PER_PAYLOAD_MB_MS, POST_CAPTCHA_METADATA_GRACE_MS, browserStreamStates, browserStreamBindingPages, browserStreamBindingContexts, MODEL_CACHE_TTL_MS, modelsCache, nativeToolsDisabled, disablingNativeToolsInProgress, lastSyncedPersonalizationHashes, directSettingsFetchConsecutiveFailures, DIRECT_SETTINGS_FETCH_BLOCK_THRESHOLD, directSettingsFetchBlocked, DIRECT_SETTINGS_FETCH_TIMEOUT_MS, activePersonalizationByAccount, accountStreamMutexes, QWEN_SAFE_SETTINGS_PATCH, QWEN_SAFE_SETTINGS_HASH, DISABLE_TOOLS_MAX_RETRIES, DISABLE_TOOLS_BACKOFF_MS, UPSTREAM_RESPONSE_PREVIEW_BYTES;
|
|
10362
|
+
var sleep4, BROWSER_STREAM_BINDING, BROWSER_ABORTERS_KEY, BROWSER_STREAM_FLUSH_BYTES, BROWSER_STREAM_FLUSH_MS, METADATA_TIMEOUT_PER_PAYLOAD_MB_MS, POST_CAPTCHA_METADATA_GRACE_MS, browserStreamStates, browserStreamBindingPages, browserStreamBindingContexts, MODEL_CACHE_TTL_MS, modelsCache, nativeToolsDisabled, disablingNativeToolsInProgress, lastSyncedPersonalizationHashes, directSettingsFetchConsecutiveFailures, DIRECT_SETTINGS_FETCH_BLOCK_THRESHOLD, directSettingsFetchBlocked, DIRECT_SETTINGS_FETCH_TIMEOUT_MS, activePersonalizationByAccount, accountStreamMutexes, QWEN_SAFE_SETTINGS_PATCH, QWEN_SAFE_SETTINGS_HASH, inFlightPersonalizationSyncs, DISABLE_TOOLS_MAX_RETRIES, DISABLE_TOOLS_BACKOFF_MS, UPSTREAM_RESPONSE_PREVIEW_BYTES;
|
|
10246
10363
|
var init_qwen = __esm({
|
|
10247
10364
|
"src/services/qwen.ts"() {
|
|
10248
10365
|
"use strict";
|
|
@@ -10329,6 +10446,7 @@ var init_qwen = __esm({
|
|
|
10329
10446
|
}
|
|
10330
10447
|
};
|
|
10331
10448
|
QWEN_SAFE_SETTINGS_HASH = crypto5.createHash("sha256").update(JSON.stringify(QWEN_SAFE_SETTINGS_PATCH)).digest("hex").slice(0, 12);
|
|
10449
|
+
inFlightPersonalizationSyncs = /* @__PURE__ */ new Map();
|
|
10332
10450
|
DISABLE_TOOLS_MAX_RETRIES = 3;
|
|
10333
10451
|
DISABLE_TOOLS_BACKOFF_MS = 2e3;
|
|
10334
10452
|
UPSTREAM_RESPONSE_PREVIEW_BYTES = 8 * 1024;
|