qwenproxy-cli 1.0.2 → 1.0.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qwenproxy-cli",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
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/api/server.ts CHANGED
@@ -269,6 +269,7 @@ app.get("/health", async (c) => {
269
269
  : undefined,
270
270
  timestamp: Date.now(),
271
271
  readyAccounts: (await import("../core/account-manager.js")).getHeadersReadyAccountIds(),
272
+ activeAccounts: (await import("../services/playwright.js")).getActivePlaywrightAccountIds(),
272
273
  metrics: {
273
274
  cache: await cache?.getStats(),
274
275
  },
package/src/tui/app.ts CHANGED
@@ -7,7 +7,19 @@ import type { TuiView, ProxyStatusSnapshot } from "./types.ts";
7
7
  import { theme, glyphs, drawBox, stringWidth } from "./theme.ts";
8
8
  import { fetchProxyStatus } from "./proxy-client.ts";
9
9
  import { ServerManager } from "./server-manager.ts";
10
+ import fs from "node:fs";
11
+ import path from "node:path";
12
+ import { fileURLToPath } from "node:url";
10
13
 
14
+ let cachedAppVersion = "v1.0.2";
15
+ try {
16
+ const currentDir = path.dirname(fileURLToPath(import.meta.url));
17
+ const pkgPath = path.resolve(currentDir, "../../package.json");
18
+ if (fs.existsSync(pkgPath)) {
19
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
20
+ if (pkg.version) cachedAppVersion = `v${pkg.version}`;
21
+ }
22
+ } catch {}
11
23
  import { StatusView } from "./views/status-view.ts";
12
24
  import { ChatView } from "./views/chat-view.ts";
13
25
  import { SyncView } from "./views/sync-view.ts";
@@ -240,7 +252,7 @@ export class TuiApp {
240
252
 
241
253
  const headerContent = [` ${tabsBar}`];
242
254
  const headerBox = drawBox({
243
- title: `QwenProxy v1.0.0 ${statusChip}`,
255
+ title: `QwenProxy ${cachedAppVersion} ${statusChip}`,
244
256
  width: cols,
245
257
  height: 3,
246
258
  borderColor: theme.borderActive,
@@ -10,6 +10,7 @@ import {
10
10
  clearAccountCooldown,
11
11
  isAccountHeadersReady,
12
12
  } from "../core/account-manager.ts";
13
+ import { isPlaywrightInitialized } from "../services/playwright.ts";
13
14
  import { getAccountConcurrencySnapshot } from "../core/account-concurrency.ts";
14
15
  import { getRssUsageSnapshot } from "../core/memory-usage.ts";
15
16
  import type { ProxyStatusSnapshot } from "./types.ts";
@@ -46,12 +47,14 @@ let cachedAccounts: Array<{
46
47
  onCooldown: boolean;
47
48
  remainingCooldownMs: number;
48
49
  headersReady: boolean;
50
+ isInitialized: boolean;
49
51
  }> = [];
50
52
  let lastAccountsFetch = 0;
51
53
  let isHealthCheckPending = false;
52
54
  let lastOnlineState = false;
53
55
  let lastOverallStatus = "offline";
54
56
  let lastServerReadyAccounts: Set<string> | null = null;
57
+ let lastServerActiveAccounts: Set<string> | null = null;
55
58
  export async function fetchProxyStatus(): Promise<ProxyStatusSnapshot> {
56
59
  const port = config.server?.port || 7936;
57
60
  const configuredHost = config.server?.host;
@@ -73,9 +76,13 @@ export async function fetchProxyStatus(): Promise<ProxyStatusSnapshot> {
73
76
  if (Array.isArray(data.readyAccounts)) {
74
77
  lastServerReadyAccounts = new Set(data.readyAccounts);
75
78
  }
79
+ if (Array.isArray(data.activeAccounts)) {
80
+ lastServerActiveAccounts = new Set(data.activeAccounts);
81
+ }
76
82
  } else {
77
83
  lastOnlineState = false;
78
84
  lastServerReadyAccounts = null;
85
+ lastServerActiveAccounts = null;
79
86
  }
80
87
  })
81
88
  .catch(() => {
@@ -104,6 +111,9 @@ export async function fetchProxyStatus(): Promise<ProxyStatusSnapshot> {
104
111
  const headersReady = lastServerReadyAccounts !== null
105
112
  ? lastServerReadyAccounts.has(acc.id)
106
113
  : isAccountHeadersReady(acc.id);
114
+ const isInitialized = lastServerActiveAccounts !== null
115
+ ? lastServerActiveAccounts.has(acc.id)
116
+ : isPlaywrightInitialized(acc.id);
107
117
  return {
108
118
  id: acc.id,
109
119
  emailOrName: maskAccountIdentifier(acc.email || acc.id),
@@ -112,10 +122,10 @@ export async function fetchProxyStatus(): Promise<ProxyStatusSnapshot> {
112
122
  onCooldown,
113
123
  remainingCooldownMs,
114
124
  headersReady,
125
+ isInitialized,
115
126
  };
116
127
  });
117
128
  }
118
-
119
129
  const accounts = cachedAccounts;
120
130
  const online = lastOnlineState;
121
131
  const overallStatus = lastOverallStatus;
package/src/tui/types.ts CHANGED
@@ -29,5 +29,6 @@ export interface ProxyStatusSnapshot {
29
29
  onCooldown: boolean;
30
30
  remainingCooldownMs: number;
31
31
  headersReady: boolean;
32
+ isInitialized?: boolean;
32
33
  }>;
33
34
  }
@@ -497,7 +497,9 @@ export class AccountsView implements TuiView {
497
497
  const mins = Math.max(1, Math.round(acc.remainingCooldownMs / 60000));
498
498
  status = theme.yellow(`⚠ ${mins}m cd `);
499
499
  } else if (!acc.headersReady) {
500
- status = theme.yellow(`◐ Aquecendo...`);
500
+ status = acc.isInitialized
501
+ ? theme.yellow(`◐ Aquecendo...`)
502
+ : theme.muted(`○ Standby `);
501
503
  }
502
504
 
503
505
  const line = `${pointer}${num}${name}${status}`;
@@ -550,7 +552,9 @@ export class AccountsView implements TuiView {
550
552
 
551
553
  const hStatus = selected.headersReady
552
554
  ? theme.green(`${glyphs.check} Capturados`)
553
- : theme.muted(`${glyphs.circle} Pendente`);
555
+ : selected.isInitialized
556
+ ? theme.yellow(`◐ Aquecendo...`)
557
+ : theme.muted(`${glyphs.circle} Standby (Sob Demanda)`);
554
558
  rightContent.push(` ${theme.bold("Headers:")} ${hStatus}`);
555
559
  rightContent.push("");
556
560
  rightContent.push(` ${theme.dim("─────────────────────────────────")}`);
@@ -175,7 +175,9 @@ export class StatusView implements TuiView {
175
175
  const mins = Math.max(1, Math.round(acc.remainingCooldownMs / 60000));
176
176
  status = theme.yellow(`⚠ Cooldown ${mins}m`);
177
177
  } else if (!acc.headersReady) {
178
- status = theme.yellow(`◐ Aquecendo...`);
178
+ status = acc.isInitialized
179
+ ? theme.yellow(`◐ Aquecendo...`)
180
+ : theme.muted(`○ Standby`);
179
181
  }
180
182
  rightContent.push(` ${num} ${name} ${status}`);
181
183
  });