qwenproxy-cli 1.0.12 → 1.0.13

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/bin/qwenproxy.js CHANGED
@@ -46,9 +46,7 @@ if (rawArgs.includes("-h") || rawArgs.includes("--help") || firstArg === "help")
46
46
  QwenProxy — High-performance AI Coding Gateway & Management TUI
47
47
 
48
48
  Usage:
49
- qwenproxy [options] [command]
50
49
  qpx [options] [command]
51
-
52
50
  Commands:
53
51
  (default) Launch interactive TUI management dashboard and proxy
54
52
  start Run headless HTTP/SSE proxy server
package/package.json CHANGED
@@ -1,10 +1,9 @@
1
1
  {
2
2
  "name": "qwenproxy-cli",
3
- "version": "1.0.12",
3
+ "version": "1.0.13",
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": {
7
- "qwenproxy": "bin/qwenproxy.js",
8
7
  "qpx": "bin/qwenproxy.js"
9
8
  },
10
9
  "files": [
package/src/api/server.ts CHANGED
@@ -721,13 +721,13 @@ export async function startServer(options?: {
721
721
 
722
722
  for (const account of remainingAccounts) {
723
723
  try {
724
- // Validate login in background
724
+ const creds = getAccountCredentials(account.id) ?? account;
725
+ // Validate login in background with real unmasked credentials
725
726
  const ok = await validateAccountLogin(
726
- account,
727
+ creds,
727
728
  config.playwright.headless,
728
729
  config.playwright.browser,
729
730
  );
730
-
731
731
  if (ok) {
732
732
  // Add to priority list only once validated
733
733
  ensureAccountInPriority(account.id);
@@ -1194,11 +1194,26 @@ export async function getBasicHeaders(accountId: string): Promise<{
1194
1194
  }
1195
1195
  }
1196
1196
 
1197
+ async function resolveAccountCredentials(account: QwenAccount): Promise<QwenAccount> {
1198
+ if (account.password && account.password !== "***") {
1199
+ return account;
1200
+ }
1201
+ try {
1202
+ const { getAccountCredentials } = await import("../core/accounts.ts");
1203
+ const creds = getAccountCredentials(account.id);
1204
+ if (creds && creds.password && creds.password !== "***") {
1205
+ return creds;
1206
+ }
1207
+ } catch {}
1208
+ return account;
1209
+ }
1210
+
1197
1211
  export async function initPlaywrightForAccount(
1198
- account: QwenAccount,
1212
+ rawAccount: QwenAccount,
1199
1213
  headless = true,
1200
1214
  browserType: BrowserType = "chromium",
1201
1215
  ): Promise<void> {
1216
+ const account = await resolveAccountCredentials(rawAccount);
1202
1217
  if (accountPages.has(account.id)) {
1203
1218
  console.log(
1204
1219
  `[Playwright] Already initialized for ${maskEmail(account.email)}`,
@@ -1404,10 +1419,11 @@ export async function initPlaywrightForAccount(
1404
1419
  * This is much lighter than full initPlaywrightForAccount (no header capture).
1405
1420
  */
1406
1421
  export async function validateAccountLogin(
1407
- account: QwenAccount,
1422
+ rawAccount: QwenAccount,
1408
1423
  headless = true,
1409
1424
  browserType: BrowserType = "chromium",
1410
1425
  ): Promise<boolean> {
1426
+ const account = await resolveAccountCredentials(rawAccount);
1411
1427
  if (accountPages.has(account.id)) {
1412
1428
  // Already initialized, no need to validate
1413
1429
  return true;
@@ -1596,6 +1612,22 @@ async function loginToQwen(
1596
1612
  email: string,
1597
1613
  password: string,
1598
1614
  ): Promise<boolean> {
1615
+ if (!password || password === "***") {
1616
+ try {
1617
+ const { getAccountCredentials } = await import("../core/accounts.ts");
1618
+ const creds = getAccountCredentials(accountId);
1619
+ if (creds && creds.password && creds.password !== "***") {
1620
+ password = creds.password;
1621
+ } else {
1622
+ console.error(
1623
+ `❌ [Playwright] Cannot login for ${maskEmail(email)}: password is masked ('***') and real credentials not found in store`,
1624
+ );
1625
+ return false;
1626
+ }
1627
+ } catch {
1628
+ return false;
1629
+ }
1630
+ }
1599
1631
  const page = accountPages.get(accountId);
1600
1632
  if (!page) return false;
1601
1633
 
@@ -1827,6 +1859,12 @@ async function loginViaUi(
1827
1859
  }
1828
1860
  await sleep(3000);
1829
1861
 
1862
+ // If a slider puzzle captcha appeared after submit, solve it automatically
1863
+ await solveBaxiaCaptcha(page, {
1864
+ waitForMs: 2000,
1865
+ maxAttempts: config.captcha.maxAttempts,
1866
+ retryDelayMs: config.captcha.retryDelayMs,
1867
+ }).catch(() => {});
1830
1868
  // Check for UI error elements in DOM (Ant Design errors, alerts, toasts)
1831
1869
  const errorSelector = [
1832
1870
  ".ant-form-item-explain-error",