qwenproxy-cli 1.2.0 → 1.2.1

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.0",
3
+ "version": "1.2.1",
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": {
@@ -130,7 +130,7 @@ export async function recoverBaxiaCaptcha(
130
130
  accountId,
131
131
  (page) => solveChallengeOnPage(page, challengeUrl),
132
132
  solverOperationTimeoutMs,
133
- Math.min(config.timeouts.page, 5_000),
133
+ solverOperationTimeoutMs,
134
134
  false,
135
135
  );
136
136
 
@@ -2335,19 +2335,30 @@ export async function captureQwenHeaders(
2335
2335
  1,
2336
2336
  Math.min(CHAT_INPUT_ACTION_TIMEOUT_MS, remainingBudgetMs()),
2337
2337
  );
2338
- try {
2339
- await page.focus(inputSelector, { timeout: inputActionTimeoutMs });
2340
- if (settled || page.isClosed()) return;
2341
- await page.fill(inputSelector, "", { timeout: inputActionTimeoutMs });
2338
+ let interactionSucceeded = false;
2339
+ for (let interactionTry = 1; interactionTry <= 2; interactionTry++) {
2342
2340
  if (settled || page.isClosed()) return;
2343
- await page.type(inputSelector, "a", {
2344
- delay: 100,
2345
- timeout: inputActionTimeoutMs,
2346
- });
2347
- } catch {
2341
+ try {
2342
+ await page.focus(inputSelector, { timeout: inputActionTimeoutMs });
2343
+ if (settled || page.isClosed()) return;
2344
+ await page.fill(inputSelector, "", { timeout: inputActionTimeoutMs });
2345
+ if (settled || page.isClosed()) return;
2346
+ await page.type(inputSelector, "a", {
2347
+ delay: 100,
2348
+ timeout: inputActionTimeoutMs,
2349
+ });
2350
+ interactionSucceeded = true;
2351
+ break;
2352
+ } catch {
2353
+ if (settled || page.isClosed()) return;
2354
+ if (interactionTry === 1) {
2355
+ await sleep(300);
2356
+ }
2357
+ }
2358
+ }
2359
+ if (!interactionSucceeded) {
2348
2360
  // The input detached mid-interaction (challenge overlay, SPA
2349
- // re-render): same diagnosis as never appearing — only a fresh load
2350
- // recovers it.
2361
+ // re-render): only a fresh load recovers it.
2351
2362
  if (settled || page.isClosed()) return;
2352
2363
  console.warn(
2353
2364
  `⏱️ [Playwright] Chat input interaction failed for ${accountId} (attempt ${attempt}); reloading`,
@@ -2043,18 +2043,23 @@ export class StreamingToolParser {
2043
2043
  recoveryAttempts: truncRecoveryAttempts,
2044
2044
  });
2045
2045
  logger.warn(
2046
- "[parser] Dropping unrecoverable unclosed tool call at end of stream",
2047
- {
2048
- toolName,
2049
- category: "truncated",
2050
- contentLength: trimmed.length,
2051
- content: trimmed.substring(0, 2000),
2052
- failureReason:
2053
- "stream ended before tool_call closing tag; content too incomplete to reconstruct",
2054
- recoveryAttempts: truncRecoveryAttempts,
2055
- emittedToolCallsSoFar: this.emittedToolCallCount,
2056
- },
2046
+ `[parser] Dropping unrecoverable unclosed tool call (${toolName || "unknown"}) at end of stream: stream ended before closing tag (${trimmed.length} chars)`,
2057
2047
  );
2048
+ if (isToolcallDebugEnabled()) {
2049
+ logger.debug(
2050
+ "[parser] Unclosed tool call payload details",
2051
+ {
2052
+ toolName,
2053
+ category: "truncated",
2054
+ contentLength: trimmed.length,
2055
+ content: trimmed.substring(0, 2000),
2056
+ failureReason:
2057
+ "stream ended before tool_call closing tag; content too incomplete to reconstruct",
2058
+ recoveryAttempts: truncRecoveryAttempts,
2059
+ emittedToolCallsSoFar: this.emittedToolCallCount,
2060
+ },
2061
+ );
2062
+ }
2058
2063
  if (
2059
2064
  this.emittedToolCallCount === 0 &&
2060
2065
  this.pendingLeadIn.trim().length > 0