qwenproxy-cli 1.6.8 → 1.6.10
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 +163 -44
- package/dist/delete-chats.js +166 -50
- package/dist/index.js +167 -51
- package/dist/login.js +163 -47
- package/dist/reset-cooldowns.js +163 -44
- package/dist/sync-clients.js +1 -1
- package/package.json +1 -1
- package/src/core/config.ts +1 -1
- package/src/core/version.ts +1 -1
- package/src/services/auth-playwright.ts +1 -1
- package/src/services/playwright.ts +174 -49
- package/src/services/qwen.ts +3 -3
package/dist/reset-cooldowns.js
CHANGED
|
@@ -1334,7 +1334,7 @@ var init_config = __esm({
|
|
|
1334
1334
|
// Version header on Qwen API requests = the deployed web bundle version
|
|
1335
1335
|
// (fallback when dynamic DOM detection is not yet completed).
|
|
1336
1336
|
// Override via env when Qwen ships a new bundle.
|
|
1337
|
-
QWEN_WEB_VERSION: z.string().default("0.
|
|
1337
|
+
QWEN_WEB_VERSION: z.string().default("0.3.26"),
|
|
1338
1338
|
// Controls bx-ua/bx-umidtoken injection on the GENERAL API paths
|
|
1339
1339
|
// (chats/new, settings): those work without them (live-probed). The
|
|
1340
1340
|
// completions path is the exception — the 0.2.86 HAR shows the real
|
|
@@ -2768,6 +2768,9 @@ function updateQwenWebVersion(version) {
|
|
|
2768
2768
|
dynamicWebVersion = version.trim();
|
|
2769
2769
|
}
|
|
2770
2770
|
}
|
|
2771
|
+
function getQwenWebVersion() {
|
|
2772
|
+
return dynamicWebVersion || config.qwen.webVersion;
|
|
2773
|
+
}
|
|
2771
2774
|
var dynamicWebVersion, QWEN_WEB_VERSION, DEFAULT_QWEN_USER_AGENT, QWEN_TIMEZONE_HEADER;
|
|
2772
2775
|
var init_qwen_headers = __esm({
|
|
2773
2776
|
"src/services/qwen-headers.ts"() {
|
|
@@ -3253,7 +3256,19 @@ async function isPageLoggedIn(page, timeoutMs = SESSION_PROBE_NAVIGATION_TIMEOUT
|
|
|
3253
3256
|
if (localStorage.getItem("qwen_token_logged_out_marker")) {
|
|
3254
3257
|
return false;
|
|
3255
3258
|
}
|
|
3256
|
-
const
|
|
3259
|
+
const lsToken = (localStorage.getItem("token") || "").trim();
|
|
3260
|
+
if (lsToken && !/(?:^|;\s*)token=/.test(document.cookie || "")) {
|
|
3261
|
+
try {
|
|
3262
|
+
document.cookie = `token=${encodeURIComponent(lsToken)}; path=/; domain=.qwen.ai; max-age=31536000`;
|
|
3263
|
+
} catch {
|
|
3264
|
+
}
|
|
3265
|
+
}
|
|
3266
|
+
const authHeaders = lsToken ? { Authorization: `Bearer ${lsToken}` } : {};
|
|
3267
|
+
const res = await fetch("/api/v1/auths/", {
|
|
3268
|
+
method: "GET",
|
|
3269
|
+
headers: authHeaders,
|
|
3270
|
+
credentials: "include"
|
|
3271
|
+
});
|
|
3257
3272
|
if (res.status !== 200) return false;
|
|
3258
3273
|
const json = await res.json().catch(() => null);
|
|
3259
3274
|
if (!json) return false;
|
|
@@ -3271,6 +3286,7 @@ async function isPageLoggedIn(page, timeoutMs = SESSION_PROBE_NAVIGATION_TIMEOUT
|
|
|
3271
3286
|
try {
|
|
3272
3287
|
const settingsRes = await fetch("/api/v2/users/user/settings", {
|
|
3273
3288
|
method: "GET",
|
|
3289
|
+
headers: authHeaders,
|
|
3274
3290
|
credentials: "include",
|
|
3275
3291
|
signal: AbortSignal.timeout(3e3)
|
|
3276
3292
|
});
|
|
@@ -4099,8 +4115,15 @@ async function initPlaywrightForAccount(rawAccount, headless = config.playwright
|
|
|
4099
4115
|
const hasAuthCookie = cookies.some(
|
|
4100
4116
|
(c) => c.name.toLowerCase().includes("token") || c.name.toLowerCase().includes("session")
|
|
4101
4117
|
);
|
|
4118
|
+
let initialLoginAttempted = false;
|
|
4102
4119
|
if (!hasAuthCookie && account.email && account.password) {
|
|
4103
|
-
|
|
4120
|
+
initialLoginAttempted = true;
|
|
4121
|
+
const loggedIn = await loginToQwen(account.id, account.email, account.password);
|
|
4122
|
+
if (!loggedIn) {
|
|
4123
|
+
throw new Error(
|
|
4124
|
+
`Authentication failed for account ${maskEmail(account.email)}`
|
|
4125
|
+
);
|
|
4126
|
+
}
|
|
4104
4127
|
}
|
|
4105
4128
|
try {
|
|
4106
4129
|
await acctPage.goto(qwenUrl("/"), {
|
|
@@ -4110,13 +4133,21 @@ async function initPlaywrightForAccount(rawAccount, headless = config.playwright
|
|
|
4110
4133
|
await sleep2(1500);
|
|
4111
4134
|
const currentUrl = acctPage.url();
|
|
4112
4135
|
const isAuthUrl = currentUrl.includes("/auth") || currentUrl.includes("/login");
|
|
4113
|
-
if (isAuthUrl && account.email && account.password) {
|
|
4136
|
+
if (isAuthUrl && !initialLoginAttempted && account.email && account.password) {
|
|
4114
4137
|
console.log(
|
|
4115
4138
|
`[Playwright] Initial login needed for ${maskEmail(account.email)}, authenticating...`
|
|
4116
4139
|
);
|
|
4117
|
-
await loginToQwen(account.id, account.email, account.password);
|
|
4140
|
+
const loggedIn = await loginToQwen(account.id, account.email, account.password);
|
|
4141
|
+
if (!loggedIn) {
|
|
4142
|
+
throw new Error(
|
|
4143
|
+
`Authentication failed for account ${maskEmail(account.email)}`
|
|
4144
|
+
);
|
|
4145
|
+
}
|
|
4118
4146
|
}
|
|
4119
4147
|
} catch (err) {
|
|
4148
|
+
if (err?.message?.includes("Authentication failed for account")) {
|
|
4149
|
+
throw err;
|
|
4150
|
+
}
|
|
4120
4151
|
console.warn(
|
|
4121
4152
|
`\u26A0\uFE0F [Playwright] Initial navigation check for ${maskEmail(account.email)}: ${err.message}`
|
|
4122
4153
|
);
|
|
@@ -4259,10 +4290,30 @@ async function loginToQwen(accountId, email, password) {
|
|
|
4259
4290
|
const uiResult = await loginViaUi(page, email, password);
|
|
4260
4291
|
if (uiResult.success) {
|
|
4261
4292
|
cookieCaches.delete(accountId);
|
|
4262
|
-
await saveStorageState(page.context(), accountId);
|
|
4263
4293
|
try {
|
|
4264
|
-
|
|
4265
|
-
|
|
4294
|
+
let liveCookies = await page.context().cookies();
|
|
4295
|
+
let tokenCookie = liveCookies.find((c) => c.name === "token");
|
|
4296
|
+
if (!tokenCookie) {
|
|
4297
|
+
const lsTok = uiResult.token || await page.evaluate(() => (localStorage.getItem("token") || "").trim()).catch(() => "");
|
|
4298
|
+
if (lsTok) {
|
|
4299
|
+
await page.context().addCookies([
|
|
4300
|
+
{
|
|
4301
|
+
name: "token",
|
|
4302
|
+
value: lsTok,
|
|
4303
|
+
domain: ".qwen.ai",
|
|
4304
|
+
path: "/",
|
|
4305
|
+
expires: Math.floor(Date.now() / 1e3) + 31536e3,
|
|
4306
|
+
httpOnly: false,
|
|
4307
|
+
secure: true,
|
|
4308
|
+
sameSite: "Lax"
|
|
4309
|
+
}
|
|
4310
|
+
]).catch(() => {
|
|
4311
|
+
});
|
|
4312
|
+
liveCookies = await page.context().cookies();
|
|
4313
|
+
tokenCookie = liveCookies.find((c) => c.name === "token");
|
|
4314
|
+
}
|
|
4315
|
+
}
|
|
4316
|
+
await saveStorageState(page.context(), accountId);
|
|
4266
4317
|
if (tokenCookie) {
|
|
4267
4318
|
const cookieStr = liveCookies.map((c) => `${c.name}=${c.value}`).join("; ");
|
|
4268
4319
|
const cache = getHeaderCache(accountId);
|
|
@@ -4271,7 +4322,7 @@ async function loginToQwen(accountId, email, password) {
|
|
|
4271
4322
|
markAccountHeadersReady(accountId);
|
|
4272
4323
|
const { saveAuthSession: saveAuthSession2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
4273
4324
|
const exp = parseJwtExpiry(tokenCookie.value);
|
|
4274
|
-
let rTok = uiResult.refreshToken;
|
|
4325
|
+
let rTok = uiResult.refreshToken || liveCookies.find((c) => c.name === "refresh_token")?.value;
|
|
4275
4326
|
if (!rTok) {
|
|
4276
4327
|
try {
|
|
4277
4328
|
rTok = await page.evaluate(() => localStorage.getItem("refresh_token") || "") || void 0;
|
|
@@ -4352,8 +4403,9 @@ async function loginViaApi(page, email, password) {
|
|
|
4352
4403
|
}
|
|
4353
4404
|
const signinUrl = "https://auth.qwen.ai/api/v2/auths/signin";
|
|
4354
4405
|
const requestId = crypto3.randomUUID();
|
|
4406
|
+
const webVersion = getQwenWebVersion() || "0.3.26";
|
|
4355
4407
|
const evalRes = await page.evaluate(
|
|
4356
|
-
async ({ email: email2, password: password2, signinUrl: signinUrl2, requestId: requestId2, tz }) => {
|
|
4408
|
+
async ({ email: email2, password: password2, signinUrl: signinUrl2, requestId: requestId2, tz, version }) => {
|
|
4357
4409
|
try {
|
|
4358
4410
|
const response = await fetch(signinUrl2, {
|
|
4359
4411
|
method: "POST",
|
|
@@ -4363,7 +4415,7 @@ async function loginViaApi(page, email, password) {
|
|
|
4363
4415
|
accept: "application/json, text/plain, */*",
|
|
4364
4416
|
"content-type": "application/json",
|
|
4365
4417
|
source: "web",
|
|
4366
|
-
version
|
|
4418
|
+
version,
|
|
4367
4419
|
"x-request-origin": "https://chat.qwen.ai",
|
|
4368
4420
|
timezone: tz,
|
|
4369
4421
|
"x-request-id": requestId2
|
|
@@ -4376,7 +4428,14 @@ async function loginViaApi(page, email, password) {
|
|
|
4376
4428
|
return { ok: false, error: e.message };
|
|
4377
4429
|
}
|
|
4378
4430
|
},
|
|
4379
|
-
{
|
|
4431
|
+
{
|
|
4432
|
+
email,
|
|
4433
|
+
password: hashedPassword,
|
|
4434
|
+
signinUrl,
|
|
4435
|
+
requestId,
|
|
4436
|
+
tz: formatAsciiTimezone(),
|
|
4437
|
+
version: webVersion
|
|
4438
|
+
}
|
|
4380
4439
|
).catch(() => null);
|
|
4381
4440
|
let data = evalRes?.data;
|
|
4382
4441
|
let signinSuccess = Boolean(
|
|
@@ -4385,7 +4444,7 @@ async function loginViaApi(page, email, password) {
|
|
|
4385
4444
|
if (!signinSuccess && !data?.data?.code) {
|
|
4386
4445
|
const fallbackUrl = qwenUrl("/api/v2/auths/signin");
|
|
4387
4446
|
const fallbackRes = await page.evaluate(
|
|
4388
|
-
async ({ email: email2, password: password2, fallbackUrl: fallbackUrl2, requestId: requestId2, tz }) => {
|
|
4447
|
+
async ({ email: email2, password: password2, fallbackUrl: fallbackUrl2, requestId: requestId2, tz, version }) => {
|
|
4389
4448
|
try {
|
|
4390
4449
|
const response = await fetch(fallbackUrl2, {
|
|
4391
4450
|
method: "POST",
|
|
@@ -4395,7 +4454,7 @@ async function loginViaApi(page, email, password) {
|
|
|
4395
4454
|
accept: "application/json, text/plain, */*",
|
|
4396
4455
|
"content-type": "application/json",
|
|
4397
4456
|
source: "web",
|
|
4398
|
-
version
|
|
4457
|
+
version,
|
|
4399
4458
|
timezone: tz,
|
|
4400
4459
|
"x-request-id": requestId2
|
|
4401
4460
|
},
|
|
@@ -4407,7 +4466,14 @@ async function loginViaApi(page, email, password) {
|
|
|
4407
4466
|
return { ok: false, error: e.message };
|
|
4408
4467
|
}
|
|
4409
4468
|
},
|
|
4410
|
-
{
|
|
4469
|
+
{
|
|
4470
|
+
email,
|
|
4471
|
+
password: hashedPassword,
|
|
4472
|
+
fallbackUrl,
|
|
4473
|
+
requestId,
|
|
4474
|
+
tz: formatAsciiTimezone(),
|
|
4475
|
+
version: webVersion
|
|
4476
|
+
}
|
|
4411
4477
|
).catch(() => null);
|
|
4412
4478
|
if (fallbackRes?.data) {
|
|
4413
4479
|
data = fallbackRes.data;
|
|
@@ -4632,28 +4698,34 @@ async function loginViaUi(page, email, password) {
|
|
|
4632
4698
|
await sleep2(500);
|
|
4633
4699
|
const submitSelector = 'button.qwenchat-auth-pc-submit-button, button[type="submit"], button:has-text("Log in"), button:has-text("Sign in"), button:has-text("Fazer login"), button:has-text("Entrar"), button:has-text("Iniciar sesi\xF3n"), button:has-text("\u767B\u5F55")';
|
|
4634
4700
|
const submitButton = page.locator(submitSelector).first();
|
|
4635
|
-
|
|
4636
|
-
try {
|
|
4637
|
-
const btn = document.querySelector(sel);
|
|
4638
|
-
if (btn) {
|
|
4639
|
-
btn.removeAttribute("disabled");
|
|
4640
|
-
btn.classList.remove("ant-btn-disabled");
|
|
4641
|
-
btn.click();
|
|
4642
|
-
}
|
|
4643
|
-
} catch {
|
|
4644
|
-
}
|
|
4645
|
-
}, submitSelector).catch(() => {
|
|
4646
|
-
});
|
|
4701
|
+
let submitted = false;
|
|
4647
4702
|
try {
|
|
4648
4703
|
if (await submitButton.isVisible({ timeout: 2e3 }).catch(() => false)) {
|
|
4649
|
-
await submitButton.click({
|
|
4704
|
+
await submitButton.click({ timeout: 2e3 }).catch(() => {
|
|
4650
4705
|
});
|
|
4706
|
+
submitted = true;
|
|
4651
4707
|
}
|
|
4652
4708
|
} catch {
|
|
4653
4709
|
}
|
|
4654
|
-
|
|
4655
|
-
|
|
4656
|
-
|
|
4710
|
+
if (!submitted) {
|
|
4711
|
+
await page.evaluate(() => {
|
|
4712
|
+
try {
|
|
4713
|
+
const btn = document.querySelector(
|
|
4714
|
+
'button.qwenchat-auth-pc-submit-button, button[type="submit"]'
|
|
4715
|
+
);
|
|
4716
|
+
if (btn) {
|
|
4717
|
+
btn.removeAttribute("disabled");
|
|
4718
|
+
btn.classList.remove("ant-btn-disabled");
|
|
4719
|
+
btn.click();
|
|
4720
|
+
}
|
|
4721
|
+
} catch {
|
|
4722
|
+
}
|
|
4723
|
+
}).catch(() => {
|
|
4724
|
+
});
|
|
4725
|
+
const passInput = page.locator(passwordSelector).first();
|
|
4726
|
+
await passInput.press("Enter", { timeout: 2e3 }).catch(() => {
|
|
4727
|
+
});
|
|
4728
|
+
}
|
|
4657
4729
|
const postSubmitDeadline = Date.now() + 15e3;
|
|
4658
4730
|
while (Date.now() < postSubmitDeadline) {
|
|
4659
4731
|
if (page.isClosed()) break;
|
|
@@ -4671,9 +4743,12 @@ async function loginViaUi(page, email, password) {
|
|
|
4671
4743
|
".ant-form-item-explain-error",
|
|
4672
4744
|
".ant-message-error",
|
|
4673
4745
|
".ant-message-notice",
|
|
4746
|
+
".ant-message-custom-content",
|
|
4747
|
+
".ant-notification-notice",
|
|
4674
4748
|
'[role="alert"]',
|
|
4675
4749
|
".qwenchat-auth-error",
|
|
4676
|
-
".auth-error-message"
|
|
4750
|
+
".auth-error-message",
|
|
4751
|
+
".qwenchat-toast"
|
|
4677
4752
|
].join(", ");
|
|
4678
4753
|
const errorEl = page.locator(errorSelector).first();
|
|
4679
4754
|
if (await errorEl.isVisible().catch(() => false)) {
|
|
@@ -4687,7 +4762,15 @@ async function loginViaUi(page, email, password) {
|
|
|
4687
4762
|
};
|
|
4688
4763
|
}
|
|
4689
4764
|
}
|
|
4690
|
-
const codeSelector =
|
|
4765
|
+
const codeSelector = [
|
|
4766
|
+
'input[placeholder*="code" i]',
|
|
4767
|
+
'input[placeholder*="c\xF3digo" i]',
|
|
4768
|
+
'input[name*="code" i]',
|
|
4769
|
+
".qwenchat-verification-code-input",
|
|
4770
|
+
".qwenchat-verification-code-input-cell",
|
|
4771
|
+
'[aria-label*="Verification code" i]',
|
|
4772
|
+
'[aria-label*="c\xF3digo de verifica\xE7\xE3o" i]'
|
|
4773
|
+
].join(", ");
|
|
4691
4774
|
const codeInput = page.locator(codeSelector).first();
|
|
4692
4775
|
if (await codeInput.isVisible().catch(() => false)) {
|
|
4693
4776
|
return {
|
|
@@ -4697,16 +4780,44 @@ async function loginViaUi(page, email, password) {
|
|
|
4697
4780
|
}
|
|
4698
4781
|
try {
|
|
4699
4782
|
const liveCookies = await page.context().cookies();
|
|
4700
|
-
|
|
4701
|
-
|
|
4783
|
+
const rTokCookie = liveCookies.find((c) => c.name === "refresh_token")?.value;
|
|
4784
|
+
const tokCookie = liveCookies.find((c) => c.name === "token")?.value;
|
|
4785
|
+
if (tokCookie) {
|
|
4786
|
+
return { success: true, token: tokCookie, refreshToken: rTokCookie };
|
|
4702
4787
|
}
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
|
|
4708
|
-
|
|
4788
|
+
const currentUrl = page.url();
|
|
4789
|
+
if (!currentUrl.includes("/auth") && !currentUrl.includes("/login")) {
|
|
4790
|
+
const lsTok = await page.evaluate(() => {
|
|
4791
|
+
const t = (localStorage.getItem("token") || "").trim();
|
|
4792
|
+
if (t) {
|
|
4793
|
+
try {
|
|
4794
|
+
document.cookie = `token=${encodeURIComponent(t)}; path=/; domain=.qwen.ai; max-age=31536000`;
|
|
4795
|
+
} catch {
|
|
4796
|
+
}
|
|
4797
|
+
}
|
|
4798
|
+
return t;
|
|
4799
|
+
}).catch(() => "");
|
|
4800
|
+
if (lsTok) {
|
|
4801
|
+
await page.context().addCookies([
|
|
4802
|
+
{
|
|
4803
|
+
name: "token",
|
|
4804
|
+
value: lsTok,
|
|
4805
|
+
domain: ".qwen.ai",
|
|
4806
|
+
path: "/",
|
|
4807
|
+
expires: Math.floor(Date.now() / 1e3) + 31536e3,
|
|
4808
|
+
httpOnly: false,
|
|
4809
|
+
secure: true,
|
|
4810
|
+
sameSite: "Lax"
|
|
4811
|
+
}
|
|
4812
|
+
]).catch(() => {
|
|
4813
|
+
});
|
|
4814
|
+
return { success: true, token: lsTok, refreshToken: rTokCookie };
|
|
4815
|
+
}
|
|
4816
|
+
if (await isPageLoggedIn(page, 3e3)) {
|
|
4817
|
+
return { success: true, refreshToken: rTokCookie };
|
|
4818
|
+
}
|
|
4709
4819
|
}
|
|
4820
|
+
} catch {
|
|
4710
4821
|
}
|
|
4711
4822
|
await sleep2(1e3);
|
|
4712
4823
|
}
|
|
@@ -4736,10 +4847,18 @@ async function refreshAccountToken(accountId) {
|
|
|
4736
4847
|
} catch {
|
|
4737
4848
|
}
|
|
4738
4849
|
}
|
|
4850
|
+
if (!refreshToken) {
|
|
4851
|
+
try {
|
|
4852
|
+
const liveCookies = await page.context().cookies();
|
|
4853
|
+
refreshToken = liveCookies.find((c) => c.name === "refresh_token")?.value;
|
|
4854
|
+
} catch {
|
|
4855
|
+
}
|
|
4856
|
+
}
|
|
4739
4857
|
if (refreshToken) {
|
|
4740
4858
|
try {
|
|
4859
|
+
const webVersion = getQwenWebVersion() || "0.3.26";
|
|
4741
4860
|
const refreshResult = await page.evaluate(
|
|
4742
|
-
async ({ rTok, tz }) => {
|
|
4861
|
+
async ({ rTok, tz, version }) => {
|
|
4743
4862
|
try {
|
|
4744
4863
|
const response = await fetch("https://auth.qwen.ai/api/v2/auths/refresh", {
|
|
4745
4864
|
method: "GET",
|
|
@@ -4747,7 +4866,7 @@ async function refreshAccountToken(accountId) {
|
|
|
4747
4866
|
headers: {
|
|
4748
4867
|
accept: "application/json, text/plain, */*",
|
|
4749
4868
|
source: "web",
|
|
4750
|
-
version
|
|
4869
|
+
version,
|
|
4751
4870
|
"x-request-origin": "https://chat.qwen.ai",
|
|
4752
4871
|
timezone: tz,
|
|
4753
4872
|
authorization: `Bearer ${rTok}`
|
|
@@ -4759,7 +4878,7 @@ async function refreshAccountToken(accountId) {
|
|
|
4759
4878
|
return { ok: false, error: e.message };
|
|
4760
4879
|
}
|
|
4761
4880
|
},
|
|
4762
|
-
{ rTok: refreshToken, tz: formatAsciiTimezone() }
|
|
4881
|
+
{ rTok: refreshToken, tz: formatAsciiTimezone(), version: webVersion }
|
|
4763
4882
|
);
|
|
4764
4883
|
const json = refreshResult?.data;
|
|
4765
4884
|
if (json && json.success === true && json.data) {
|
package/dist/sync-clients.js
CHANGED
|
@@ -119,7 +119,7 @@ var envSchema = z.object({
|
|
|
119
119
|
// Version header on Qwen API requests = the deployed web bundle version
|
|
120
120
|
// (fallback when dynamic DOM detection is not yet completed).
|
|
121
121
|
// Override via env when Qwen ships a new bundle.
|
|
122
|
-
QWEN_WEB_VERSION: z.string().default("0.
|
|
122
|
+
QWEN_WEB_VERSION: z.string().default("0.3.26"),
|
|
123
123
|
// Controls bx-ua/bx-umidtoken injection on the GENERAL API paths
|
|
124
124
|
// (chats/new, settings): those work without them (live-probed). The
|
|
125
125
|
// completions path is the exception — the 0.2.86 HAR shows the real
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "qwenproxy-cli",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.10",
|
|
4
4
|
"description": "High-performance OpenAI & Anthropic compatible API gateway for Qwen with multi-account rotation, interactive TUI, and resilient tool calling.",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"bin": {
|
package/src/core/config.ts
CHANGED
|
@@ -34,7 +34,7 @@ const envSchema = z
|
|
|
34
34
|
// Version header on Qwen API requests = the deployed web bundle version
|
|
35
35
|
// (fallback when dynamic DOM detection is not yet completed).
|
|
36
36
|
// Override via env when Qwen ships a new bundle.
|
|
37
|
-
QWEN_WEB_VERSION: z.string().default("0.
|
|
37
|
+
QWEN_WEB_VERSION: z.string().default("0.3.26"),
|
|
38
38
|
// Controls bx-ua/bx-umidtoken injection on the GENERAL API paths
|
|
39
39
|
// (chats/new, settings): those work without them (live-probed). The
|
|
40
40
|
// completions path is the exception — the 0.2.86 HAR shows the real
|
package/src/core/version.ts
CHANGED