qwenproxy-cli 1.0.17 → 1.0.18
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 +1 -1
- package/src/index.ts +26 -32
- package/src/services/playwright.ts +27 -10
- package/src/tools/parser.ts +1 -1
- package/src/tui/index.ts +8 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "qwenproxy-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.18",
|
|
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/index.ts
CHANGED
|
@@ -14,41 +14,35 @@ if (fs.existsSync(envPath)) {
|
|
|
14
14
|
dotenv.config({ quiet: true })
|
|
15
15
|
}
|
|
16
16
|
// Prevent benign asynchronous driver/browser teardown exceptions from crashing the server
|
|
17
|
-
process.on('uncaughtException', (error: unknown) => {
|
|
18
|
-
const
|
|
19
|
-
if (
|
|
20
|
-
msg
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
) {
|
|
29
|
-
console.warn(`⚠️ [Playwright] Handled benign driver teardown exception: ${msg}`)
|
|
30
|
-
return
|
|
17
|
+
process.on('uncaughtException', async (error: unknown) => {
|
|
18
|
+
const { isPlaywrightAlreadyClosedError } = await import('./services/playwright.ts');
|
|
19
|
+
if (isPlaywrightAlreadyClosedError(error)) {
|
|
20
|
+
const msg =
|
|
21
|
+
error instanceof Error
|
|
22
|
+
? error.message
|
|
23
|
+
: typeof error === 'object' && error !== null && 'message' in error
|
|
24
|
+
? String((error as any).message)
|
|
25
|
+
: String(error);
|
|
26
|
+
console.warn(`⚠️ [Playwright] Handled benign driver teardown exception: ${msg}`);
|
|
27
|
+
return;
|
|
31
28
|
}
|
|
32
|
-
console.error('❌ [Process] Uncaught Exception:', error)
|
|
33
|
-
})
|
|
29
|
+
console.error('❌ [Process] Uncaught Exception:', error);
|
|
30
|
+
});
|
|
34
31
|
|
|
35
|
-
process.on('unhandledRejection', (reason: unknown) => {
|
|
36
|
-
const
|
|
37
|
-
if (
|
|
38
|
-
msg
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
) {
|
|
47
|
-
console.warn(`⚠️ [Playwright] Handled benign driver teardown rejection: ${msg}`)
|
|
48
|
-
return
|
|
32
|
+
process.on('unhandledRejection', async (reason: unknown) => {
|
|
33
|
+
const { isPlaywrightAlreadyClosedError } = await import('./services/playwright.ts');
|
|
34
|
+
if (isPlaywrightAlreadyClosedError(reason)) {
|
|
35
|
+
const msg =
|
|
36
|
+
reason instanceof Error
|
|
37
|
+
? reason.message
|
|
38
|
+
: typeof reason === 'object' && reason !== null && 'message' in reason
|
|
39
|
+
? String((reason as any).message)
|
|
40
|
+
: String(reason);
|
|
41
|
+
console.warn(`⚠️ [Playwright] Handled benign driver teardown rejection: ${msg}`);
|
|
42
|
+
return;
|
|
49
43
|
}
|
|
50
|
-
console.error('❌ [Process] Unhandled Rejection:', reason)
|
|
51
|
-
})
|
|
44
|
+
console.error('❌ [Process] Unhandled Rejection:', reason);
|
|
45
|
+
});
|
|
52
46
|
import { startServer } from './api/server.js'
|
|
53
47
|
const isTui = process.argv.includes('--tui') || process.env.QWEN_TUI === 'true'
|
|
54
48
|
|
|
@@ -492,7 +492,7 @@ function isAccountServingStream(accountId: string): boolean {
|
|
|
492
492
|
return true;
|
|
493
493
|
}
|
|
494
494
|
|
|
495
|
-
function getStealthScript(profile: FingerprintProfile): string {
|
|
495
|
+
export function getStealthScript(profile: FingerprintProfile): string {
|
|
496
496
|
const profileJson = JSON.stringify(profile).replace(/</g, "\\u003c");
|
|
497
497
|
return `
|
|
498
498
|
(function() {
|
|
@@ -740,6 +740,14 @@ function getStealthScript(profile: FingerprintProfile): string {
|
|
|
740
740
|
function makeMime(desc, suffixes, type) {
|
|
741
741
|
return { description: desc, suffixes: suffixes, type: type };
|
|
742
742
|
}
|
|
743
|
+
function attachPlugin(mime, plugin) {
|
|
744
|
+
Object.defineProperty(mime, 'enabledPlugin', {
|
|
745
|
+
value: plugin,
|
|
746
|
+
enumerable: false,
|
|
747
|
+
configurable: true,
|
|
748
|
+
writable: true,
|
|
749
|
+
});
|
|
750
|
+
}
|
|
743
751
|
const pdfMime = makeMime('Portable Document Format', 'pdf', 'application/pdf');
|
|
744
752
|
const pdfxMime = makeMime('Portable Document Format', 'pdf', 'text/pdf');
|
|
745
753
|
const pdfPlugin = {
|
|
@@ -750,8 +758,8 @@ function getStealthScript(profile: FingerprintProfile): string {
|
|
|
750
758
|
0: pdfMime,
|
|
751
759
|
1: pdfxMime,
|
|
752
760
|
};
|
|
753
|
-
pdfMime
|
|
754
|
-
pdfxMime
|
|
761
|
+
attachPlugin(pdfMime, pdfPlugin);
|
|
762
|
+
attachPlugin(pdfxMime, pdfPlugin);
|
|
755
763
|
|
|
756
764
|
const chromePdfMime = makeMime('Portable Document Format', 'pdf', 'application/pdf');
|
|
757
765
|
const chromePdfMime2 = makeMime('Portable Document Format', 'pdf', 'text/pdf');
|
|
@@ -763,8 +771,8 @@ function getStealthScript(profile: FingerprintProfile): string {
|
|
|
763
771
|
0: chromePdfMime,
|
|
764
772
|
1: chromePdfMime2,
|
|
765
773
|
};
|
|
766
|
-
chromePdfMime
|
|
767
|
-
chromePdfMime2
|
|
774
|
+
attachPlugin(chromePdfMime, chromePdfPlugin);
|
|
775
|
+
attachPlugin(chromePdfMime2, chromePdfPlugin);
|
|
768
776
|
|
|
769
777
|
const nativePlugin = {
|
|
770
778
|
name: 'Native Client',
|
|
@@ -774,9 +782,8 @@ function getStealthScript(profile: FingerprintProfile): string {
|
|
|
774
782
|
0: makeMime('Native Client Executable', '', 'application/x-nacl'),
|
|
775
783
|
1: makeMime('Portable Native Client Executable', '', 'application/x-pnacl'),
|
|
776
784
|
};
|
|
777
|
-
nativePlugin[0]
|
|
778
|
-
nativePlugin[1]
|
|
779
|
-
|
|
785
|
+
attachPlugin(nativePlugin[0], nativePlugin);
|
|
786
|
+
attachPlugin(nativePlugin[1], nativePlugin);
|
|
780
787
|
const pluginsList = [pdfPlugin, chromePdfPlugin, nativePlugin];
|
|
781
788
|
const mimeList = [pdfMime, pdfxMime, chromePdfMime, chromePdfMime2, nativePlugin[0], nativePlugin[1]];
|
|
782
789
|
|
|
@@ -3078,7 +3085,13 @@ async function closePlaywrightForAccountLocked(
|
|
|
3078
3085
|
* that must not be logged as keep-alive failures.
|
|
3079
3086
|
*/
|
|
3080
3087
|
export function isPlaywrightAlreadyClosedError(error: unknown): boolean {
|
|
3081
|
-
|
|
3088
|
+
if (!error) return false;
|
|
3089
|
+
const message =
|
|
3090
|
+
error instanceof Error
|
|
3091
|
+
? error.message
|
|
3092
|
+
: typeof error === "object" && "message" in error
|
|
3093
|
+
? String((error as any).message)
|
|
3094
|
+
: String(error);
|
|
3082
3095
|
return (
|
|
3083
3096
|
message.includes("Target page, context or browser has been closed") ||
|
|
3084
3097
|
message.includes("Browser has been closed") ||
|
|
@@ -3087,7 +3100,11 @@ export function isPlaywrightAlreadyClosedError(error: unknown): boolean {
|
|
|
3087
3100
|
message.includes("Page crashed") ||
|
|
3088
3101
|
message.includes("Assertion error") ||
|
|
3089
3102
|
message.includes("Cannot find parent object") ||
|
|
3090
|
-
message.includes("Connection closed")
|
|
3103
|
+
message.includes("Connection closed") ||
|
|
3104
|
+
message.includes("session closed") ||
|
|
3105
|
+
message.includes("Session closed") ||
|
|
3106
|
+
message.includes("Network.setCacheDisabled") ||
|
|
3107
|
+
message.includes("Protocol error")
|
|
3091
3108
|
);
|
|
3092
3109
|
}
|
|
3093
3110
|
|
package/src/tools/parser.ts
CHANGED
|
@@ -962,7 +962,7 @@ function repairCommonMalformedToolJson(content: string): string {
|
|
|
962
962
|
// a bare-word value, so inserting the quote is safe (true/false/null and
|
|
963
963
|
// numbers are excluded). The trailing `\"` escapes are preserved, so the
|
|
964
964
|
// model's closing quote still terminates the string.
|
|
965
|
-
/([,{]\s*"[a-zA-Z_][a-zA-Z0-9_]*"\s*:\s*)(?=(?!true|false|null)[
|
|
965
|
+
/([,{]\s*"[a-zA-Z_][a-zA-Z0-9_]*"\s*:\s*)(?=(?!true|false|null|\d|\[|\{|")[^\s])/g,
|
|
966
966
|
'$1"',
|
|
967
967
|
);
|
|
968
968
|
return repairMissingArrayClose(repaired);
|
package/src/tui/index.ts
CHANGED
|
@@ -37,6 +37,10 @@ async function main() {
|
|
|
37
37
|
const app = new TuiApp(initialTab);
|
|
38
38
|
|
|
39
39
|
process.on("uncaughtException", async (err) => {
|
|
40
|
+
const { isPlaywrightAlreadyClosedError } = await import("../services/playwright.ts");
|
|
41
|
+
if (isPlaywrightAlreadyClosedError(err)) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
40
44
|
try {
|
|
41
45
|
await app.stop();
|
|
42
46
|
} catch {}
|
|
@@ -45,6 +49,10 @@ async function main() {
|
|
|
45
49
|
});
|
|
46
50
|
|
|
47
51
|
process.on("unhandledRejection", async (err) => {
|
|
52
|
+
const { isPlaywrightAlreadyClosedError } = await import("../services/playwright.ts");
|
|
53
|
+
if (isPlaywrightAlreadyClosedError(err)) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
48
56
|
try {
|
|
49
57
|
await app.stop();
|
|
50
58
|
} catch {}
|