qwenproxy-cli 1.2.1 → 1.2.2
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.2.
|
|
3
|
+
"version": "1.2.2",
|
|
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": {
|
|
@@ -105,6 +105,9 @@ app.post("/v1/messages", async (c) => {
|
|
|
105
105
|
"Content-Type": "application/json",
|
|
106
106
|
Authorization: `Bearer ${process.env.API_KEY || config.apiKey || ""}`,
|
|
107
107
|
"x-qwenproxy-route": "Anthropic",
|
|
108
|
+
...(c.req.header("x-qwenproxy-chat-mode")
|
|
109
|
+
? { "x-qwenproxy-chat-mode": c.req.header("x-qwenproxy-chat-mode")! }
|
|
110
|
+
: {}),
|
|
108
111
|
},
|
|
109
112
|
body: JSON.stringify({
|
|
110
113
|
...openaiRequest,
|
|
@@ -87,16 +87,17 @@ export async function buildFinalContext(
|
|
|
87
87
|
? false
|
|
88
88
|
: useThreadNative && (hasExplicitConversationKey || !isNewSession); // has assistant messages = continuation of existing chat
|
|
89
89
|
|
|
90
|
-
// Compute sessionId:
|
|
91
|
-
//
|
|
92
|
-
//
|
|
93
|
-
//
|
|
90
|
+
// Compute sessionId: deterministic session ID derived from the conversation
|
|
91
|
+
// key (or "implicit-thread") + system instructions + first user message.
|
|
92
|
+
// Including completeInstructions in ALL modes (not just explicit keys)
|
|
93
|
+
// prevents cross-project session collisions when different projects share
|
|
94
|
+
// the same first user message but have different system prompts / tools.
|
|
94
95
|
const sessionId = isStateless
|
|
95
96
|
? null
|
|
96
97
|
: (conversationKey || useThreadNative)
|
|
97
98
|
? deriveSessionId(
|
|
98
99
|
messages,
|
|
99
|
-
|
|
100
|
+
completeInstructions,
|
|
100
101
|
conversationKey ?? "implicit-thread",
|
|
101
102
|
)
|
|
102
103
|
: null;
|
|
@@ -136,6 +136,9 @@ app.post("/v1/responses", async (c) => {
|
|
|
136
136
|
"Content-Type": "application/json",
|
|
137
137
|
Authorization: `Bearer ${process.env.API_KEY || config.apiKey || ""}`,
|
|
138
138
|
"x-qwenproxy-route": "Responses",
|
|
139
|
+
...(c.req.header("x-qwenproxy-chat-mode")
|
|
140
|
+
? { "x-qwenproxy-chat-mode": c.req.header("x-qwenproxy-chat-mode")! }
|
|
141
|
+
: {}),
|
|
139
142
|
},
|
|
140
143
|
body: JSON.stringify({
|
|
141
144
|
...chatRequest,
|
|
@@ -300,6 +303,9 @@ app.post("/v1/responses", async (c) => {
|
|
|
300
303
|
"Content-Type": "application/json",
|
|
301
304
|
Authorization: `Bearer ${process.env.API_KEY || config.apiKey || ""}`,
|
|
302
305
|
"x-qwenproxy-route": "Responses",
|
|
306
|
+
...(c.req.header("x-qwenproxy-chat-mode")
|
|
307
|
+
? { "x-qwenproxy-chat-mode": c.req.header("x-qwenproxy-chat-mode")! }
|
|
308
|
+
: {}),
|
|
303
309
|
},
|
|
304
310
|
body: JSON.stringify(chatRequest),
|
|
305
311
|
},
|
|
@@ -3353,6 +3353,10 @@ export function isPlaywrightInitialized(accountId: string): boolean {
|
|
|
3353
3353
|
return accountPages.has(accountId);
|
|
3354
3354
|
}
|
|
3355
3355
|
|
|
3356
|
+
export function isPlaywrightInitializing(accountId: string): boolean {
|
|
3357
|
+
return inFlightAccountInits.has(accountId);
|
|
3358
|
+
}
|
|
3359
|
+
|
|
3356
3360
|
export function isAccountRecentlyActive(
|
|
3357
3361
|
accountId: string,
|
|
3358
3362
|
maxIdleMs = 300_000,
|
package/src/services/qwen.ts
CHANGED
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
syncModelMetadata,
|
|
28
28
|
} from "../core/model-registry.ts";
|
|
29
29
|
import { type Page, type BrowserContext } from "patchright";
|
|
30
|
-
import { withAccountPage, assertAntiBotHeaders, onBrowserContextCreated } from "./playwright.ts";
|
|
30
|
+
import { withAccountPage, assertAntiBotHeaders, onBrowserContextCreated, isPlaywrightInitializing } from "./playwright.ts";
|
|
31
31
|
import { recoverBaxiaCaptcha } from "./captcha-coordinator.ts";
|
|
32
32
|
import { startBaxiaCaptchaWatcher } from "./captcha-solver.ts";
|
|
33
33
|
import { isAccountBusy } from "../core/account-concurrency.ts";
|
|
@@ -1767,6 +1767,14 @@ export async function disableNativeTools(accountId?: string): Promise<void> {
|
|
|
1767
1767
|
) {
|
|
1768
1768
|
return;
|
|
1769
1769
|
}
|
|
1770
|
+
// Defer if the account's Playwright browser is still initializing: the
|
|
1771
|
+
// settings POST requires the page mutex, and init legitimately holds it for
|
|
1772
|
+
// 20-30s (navigation + bx SDK + header capture). Attempting to acquire the
|
|
1773
|
+
// mutex now would time out (5s default in withQwenBrowserPage) and log a
|
|
1774
|
+
// spurious WARN. The startup flow calls us again after init finishes.
|
|
1775
|
+
if (accountId && isPlaywrightInitializing(accountId)) {
|
|
1776
|
+
return;
|
|
1777
|
+
}
|
|
1770
1778
|
disablingNativeToolsInProgress.add(cacheKey);
|
|
1771
1779
|
|
|
1772
1780
|
try {
|
|
@@ -2827,7 +2835,7 @@ async function createQwenStreamInternal(
|
|
|
2827
2835
|
auto_thinking: mode === "auto",
|
|
2828
2836
|
thinking_mode: thinkingMode,
|
|
2829
2837
|
...(thinkingEnabled ? { thinking_format: "summary" } : {}),
|
|
2830
|
-
auto_search:
|
|
2838
|
+
auto_search: false,
|
|
2831
2839
|
};
|
|
2832
2840
|
})(),
|
|
2833
2841
|
extra: {
|
package/src/tools/parser.ts
CHANGED
|
@@ -1703,6 +1703,12 @@ export class StreamingToolParser {
|
|
|
1703
1703
|
result.text += literalBlock;
|
|
1704
1704
|
}
|
|
1705
1705
|
|
|
1706
|
+
// Count undeclared/malformed tool calls toward the per-turn cap.
|
|
1707
|
+
// Without this, the model can generate unlimited undeclared tool calls
|
|
1708
|
+
// (e.g. Qwen-native WebSearch/WebFetch) that bypass the cap entirely,
|
|
1709
|
+
// causing infinite generation until TOTAL_REQUEST_TIMEOUT (10 min).
|
|
1710
|
+
this.emittedToolCallCount++;
|
|
1711
|
+
|
|
1706
1712
|
this.advanceMarkdownState(literalBlock);
|
|
1707
1713
|
this.pendingLeadIn = "";
|
|
1708
1714
|
}
|