qwenproxy-cli 1.0.14 → 1.0.16
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.
|
|
3
|
+
"version": "1.0.16",
|
|
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": {
|
|
@@ -216,7 +216,10 @@ export function shouldRetryChatInProgressOnSameAccount(
|
|
|
216
216
|
|
|
217
217
|
export function isAccountInitializationError(err: unknown): boolean {
|
|
218
218
|
const message = errMessage(err).toLowerCase();
|
|
219
|
+
const code = errCode(err).toLowerCase();
|
|
219
220
|
return (
|
|
221
|
+
code === "acquire_deadline" ||
|
|
222
|
+
message.includes("acquire deadline") ||
|
|
220
223
|
message.includes("header capture returned incomplete anti-fraud headers") ||
|
|
221
224
|
message.includes("required qwen anti-fraud headers are unavailable") ||
|
|
222
225
|
message.includes("playwright not initialized for account") ||
|
|
@@ -265,6 +265,7 @@ export function loadStorageState(accountId: string): string | undefined {
|
|
|
265
265
|
export async function saveStorageState(
|
|
266
266
|
context: BrowserContext,
|
|
267
267
|
accountId: string,
|
|
268
|
+
timeoutMs = 5_000,
|
|
268
269
|
): Promise<void> {
|
|
269
270
|
try {
|
|
270
271
|
const stateFile = getStorageStatePath(accountId);
|
|
@@ -272,7 +273,11 @@ export async function saveStorageState(
|
|
|
272
273
|
if (!fs.existsSync(dir)) {
|
|
273
274
|
fs.mkdirSync(dir, { recursive: true });
|
|
274
275
|
}
|
|
275
|
-
await
|
|
276
|
+
await withTimeout(
|
|
277
|
+
context.storageState({ path: stateFile }),
|
|
278
|
+
timeoutMs,
|
|
279
|
+
`storageState timed out after ${timeoutMs}ms`,
|
|
280
|
+
);
|
|
276
281
|
} catch (error) {
|
|
277
282
|
console.warn(
|
|
278
283
|
`[Playwright] Failed to save storage state for ${accountId}: ${getErrorMessage(error)}`,
|
|
@@ -280,9 +285,13 @@ export async function saveStorageState(
|
|
|
280
285
|
}
|
|
281
286
|
}
|
|
282
287
|
|
|
283
|
-
async function hasValidAuthCookie(context: BrowserContext): Promise<boolean> {
|
|
288
|
+
async function hasValidAuthCookie(context: BrowserContext, timeoutMs = 3_000): Promise<boolean> {
|
|
284
289
|
try {
|
|
285
|
-
const cookies = await
|
|
290
|
+
const cookies = await withTimeout(
|
|
291
|
+
context.cookies(),
|
|
292
|
+
timeoutMs,
|
|
293
|
+
`cookies check timed out after ${timeoutMs}ms`,
|
|
294
|
+
);
|
|
286
295
|
return cookies.some(
|
|
287
296
|
(c) =>
|
|
288
297
|
(c.name.toLowerCase().includes("token") || c.name.toLowerCase().includes("session")) &&
|
|
@@ -145,7 +145,7 @@ export class AccountsView implements TuiView {
|
|
|
145
145
|
public async handleKey(key: KeyEvent): Promise<boolean | void> {
|
|
146
146
|
// 0. Confirm Dialog Active
|
|
147
147
|
if (this.confirmDialog) {
|
|
148
|
-
if (key.name === "s" || key.name === "S"
|
|
148
|
+
if (key.name === "s" || key.name === "S") {
|
|
149
149
|
const dialog = this.confirmDialog;
|
|
150
150
|
this.confirmDialog = null;
|
|
151
151
|
this.confirmDialogHovered = null;
|
|
@@ -158,17 +158,40 @@ export class AccountsView implements TuiView {
|
|
|
158
158
|
this.setStatusMessage(theme.muted("Ação cancelada"));
|
|
159
159
|
return true;
|
|
160
160
|
}
|
|
161
|
+
if (key.name === "enter" || key.name === "return") {
|
|
162
|
+
if (this.confirmDialogHovered === "cancel") {
|
|
163
|
+
this.confirmDialog = null;
|
|
164
|
+
this.confirmDialogHovered = null;
|
|
165
|
+
this.setStatusMessage(theme.muted("Ação cancelada"));
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
const dialog = this.confirmDialog;
|
|
169
|
+
this.confirmDialog = null;
|
|
170
|
+
this.confirmDialogHovered = null;
|
|
171
|
+
await dialog.onConfirm();
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
if (key.name === "left" || key.name === "right" || key.name === "tab") {
|
|
175
|
+
this.confirmDialogHovered = this.confirmDialogHovered === "cancel" ? "confirm" : "cancel";
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
161
178
|
if (key.name === "hover" && key.mouse) {
|
|
162
179
|
const { row, col } = key.mouse;
|
|
163
|
-
const btnRow = this.lastConfirmModalStartRow +
|
|
164
|
-
if (row === btnRow) {
|
|
165
|
-
const
|
|
166
|
-
if (
|
|
167
|
-
this.confirmDialogHovered
|
|
180
|
+
const btnRow = (this.lastConfirmModalStartRow || 4) + 5;
|
|
181
|
+
if (row === btnRow || row === btnRow - 1) {
|
|
182
|
+
const relCol = col - (this.lastConfirmModalLeftPad || 0);
|
|
183
|
+
if (relCol >= 2 && relCol <= 34) {
|
|
184
|
+
if (this.confirmDialogHovered !== "confirm") {
|
|
185
|
+
this.confirmDialogHovered = "confirm";
|
|
186
|
+
return true;
|
|
187
|
+
}
|
|
168
188
|
return true;
|
|
169
189
|
}
|
|
170
|
-
if (
|
|
171
|
-
this.confirmDialogHovered
|
|
190
|
+
if (relCol >= 35 && relCol <= 60) {
|
|
191
|
+
if (this.confirmDialogHovered !== "cancel") {
|
|
192
|
+
this.confirmDialogHovered = "cancel";
|
|
193
|
+
return true;
|
|
194
|
+
}
|
|
172
195
|
return true;
|
|
173
196
|
}
|
|
174
197
|
}
|
|
@@ -179,17 +202,17 @@ export class AccountsView implements TuiView {
|
|
|
179
202
|
}
|
|
180
203
|
if (key.name === "click" && key.mouse) {
|
|
181
204
|
const { row, col } = key.mouse;
|
|
182
|
-
const btnRow = this.lastConfirmModalStartRow +
|
|
183
|
-
if (row === btnRow) {
|
|
184
|
-
const
|
|
185
|
-
if (
|
|
205
|
+
const btnRow = (this.lastConfirmModalStartRow || 4) + 5;
|
|
206
|
+
if (row === btnRow || row === btnRow - 1) {
|
|
207
|
+
const relCol = col - (this.lastConfirmModalLeftPad || 0);
|
|
208
|
+
if (relCol >= 2 && relCol <= 34) {
|
|
186
209
|
const dialog = this.confirmDialog;
|
|
187
210
|
this.confirmDialog = null;
|
|
188
211
|
this.confirmDialogHovered = null;
|
|
189
212
|
await dialog.onConfirm();
|
|
190
213
|
return true;
|
|
191
214
|
}
|
|
192
|
-
if (
|
|
215
|
+
if (relCol >= 35 && relCol <= 60) {
|
|
193
216
|
this.confirmDialog = null;
|
|
194
217
|
this.confirmDialogHovered = null;
|
|
195
218
|
this.setStatusMessage(theme.muted("Ação cancelada"));
|
|
@@ -804,14 +827,15 @@ export class AccountsView implements TuiView {
|
|
|
804
827
|
if (this.confirmDialog) {
|
|
805
828
|
const modalW = Math.min(width - 4, 66);
|
|
806
829
|
this.lastConfirmModalLeftPad = Math.max(0, Math.floor((width - modalW) / 2));
|
|
830
|
+
this.lastConfirmModalStartRow = 4;
|
|
807
831
|
const confirmBtn =
|
|
808
832
|
this.confirmDialogHovered === "confirm"
|
|
809
833
|
? theme.bgHover(theme.red(" [ S / Enter ] Sim, Confirmar "))
|
|
810
|
-
: theme.red("[ S / Enter ] Sim, Confirmar")
|
|
834
|
+
: ` ${theme.red("[ S / Enter ] Sim, Confirmar")} `;
|
|
811
835
|
const cancelBtn =
|
|
812
836
|
this.confirmDialogHovered === "cancel"
|
|
813
837
|
? theme.bgHover(theme.green(" [ N / Esc ] Cancelar "))
|
|
814
|
-
: theme.green("[ N / Esc ] Cancelar")
|
|
838
|
+
: ` ${theme.green("[ N / Esc ] Cancelar")} `;
|
|
815
839
|
|
|
816
840
|
const modalContent = [
|
|
817
841
|
"",
|
|
@@ -126,7 +126,7 @@ export class StorageView implements TuiView {
|
|
|
126
126
|
public async handleKey(key: KeyEvent): Promise<boolean | void> {
|
|
127
127
|
// 0. Confirm Dialog Active
|
|
128
128
|
if (this.confirmDialog) {
|
|
129
|
-
if (key.name === "s" || key.name === "S"
|
|
129
|
+
if (key.name === "s" || key.name === "S") {
|
|
130
130
|
const dialog = this.confirmDialog;
|
|
131
131
|
this.confirmDialog = null;
|
|
132
132
|
this.confirmDialogHovered = null;
|
|
@@ -139,17 +139,40 @@ export class StorageView implements TuiView {
|
|
|
139
139
|
this.addLog(theme.muted("Ação cancelada"));
|
|
140
140
|
return true;
|
|
141
141
|
}
|
|
142
|
+
if (key.name === "enter" || key.name === "return") {
|
|
143
|
+
if (this.confirmDialogHovered === "cancel") {
|
|
144
|
+
this.confirmDialog = null;
|
|
145
|
+
this.confirmDialogHovered = null;
|
|
146
|
+
this.addLog(theme.muted("Ação cancelada"));
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
const dialog = this.confirmDialog;
|
|
150
|
+
this.confirmDialog = null;
|
|
151
|
+
this.confirmDialogHovered = null;
|
|
152
|
+
await dialog.onConfirm();
|
|
153
|
+
return true;
|
|
154
|
+
}
|
|
155
|
+
if (key.name === "left" || key.name === "right" || key.name === "tab") {
|
|
156
|
+
this.confirmDialogHovered = this.confirmDialogHovered === "cancel" ? "confirm" : "cancel";
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
142
159
|
if (key.name === "hover" && key.mouse) {
|
|
143
160
|
const { row, col } = key.mouse;
|
|
144
|
-
const btnRow = this.lastConfirmModalStartRow +
|
|
145
|
-
if (row === btnRow) {
|
|
146
|
-
const
|
|
147
|
-
if (
|
|
148
|
-
this.confirmDialogHovered
|
|
161
|
+
const btnRow = (this.lastConfirmModalStartRow || 4) + 5;
|
|
162
|
+
if (row === btnRow || row === btnRow - 1) {
|
|
163
|
+
const relCol = col - (this.lastConfirmModalLeftPad || 0);
|
|
164
|
+
if (relCol >= 2 && relCol <= 34) {
|
|
165
|
+
if (this.confirmDialogHovered !== "confirm") {
|
|
166
|
+
this.confirmDialogHovered = "confirm";
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
149
169
|
return true;
|
|
150
170
|
}
|
|
151
|
-
if (
|
|
152
|
-
this.confirmDialogHovered
|
|
171
|
+
if (relCol >= 35 && relCol <= 60) {
|
|
172
|
+
if (this.confirmDialogHovered !== "cancel") {
|
|
173
|
+
this.confirmDialogHovered = "cancel";
|
|
174
|
+
return true;
|
|
175
|
+
}
|
|
153
176
|
return true;
|
|
154
177
|
}
|
|
155
178
|
}
|
|
@@ -160,17 +183,17 @@ export class StorageView implements TuiView {
|
|
|
160
183
|
}
|
|
161
184
|
if (key.name === "click" && key.mouse) {
|
|
162
185
|
const { row, col } = key.mouse;
|
|
163
|
-
const btnRow = this.lastConfirmModalStartRow +
|
|
164
|
-
if (row === btnRow) {
|
|
165
|
-
const
|
|
166
|
-
if (
|
|
186
|
+
const btnRow = (this.lastConfirmModalStartRow || 4) + 5;
|
|
187
|
+
if (row === btnRow || row === btnRow - 1) {
|
|
188
|
+
const relCol = col - (this.lastConfirmModalLeftPad || 0);
|
|
189
|
+
if (relCol >= 2 && relCol <= 34) {
|
|
167
190
|
const dialog = this.confirmDialog;
|
|
168
191
|
this.confirmDialog = null;
|
|
169
192
|
this.confirmDialogHovered = null;
|
|
170
193
|
await dialog.onConfirm();
|
|
171
194
|
return true;
|
|
172
195
|
}
|
|
173
|
-
if (
|
|
196
|
+
if (relCol >= 35 && relCol <= 60) {
|
|
174
197
|
this.confirmDialog = null;
|
|
175
198
|
this.confirmDialogHovered = null;
|
|
176
199
|
this.addLog(theme.muted("Ação cancelada"));
|
|
@@ -409,14 +432,15 @@ export class StorageView implements TuiView {
|
|
|
409
432
|
if (this.confirmDialog) {
|
|
410
433
|
const modalW = Math.min(width - 4, 66);
|
|
411
434
|
this.lastConfirmModalLeftPad = Math.max(0, Math.floor((width - modalW) / 2));
|
|
435
|
+
this.lastConfirmModalStartRow = 4;
|
|
412
436
|
const confirmBtn =
|
|
413
437
|
this.confirmDialogHovered === "confirm"
|
|
414
438
|
? theme.bgHover(theme.red(" [ S / Enter ] Sim, Confirmar "))
|
|
415
|
-
: theme.red("[ S / Enter ] Sim, Confirmar")
|
|
439
|
+
: ` ${theme.red("[ S / Enter ] Sim, Confirmar")} `;
|
|
416
440
|
const cancelBtn =
|
|
417
441
|
this.confirmDialogHovered === "cancel"
|
|
418
442
|
? theme.bgHover(theme.green(" [ N / Esc ] Cancelar "))
|
|
419
|
-
: theme.green("[ N / Esc ] Cancelar")
|
|
443
|
+
: ` ${theme.green("[ N / Esc ] Cancelar")} `;
|
|
420
444
|
|
|
421
445
|
const modalContent = [
|
|
422
446
|
"",
|