opencode-qwen-cli-auth 2.3.3 → 2.3.4

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.
Files changed (2) hide show
  1. package/dist/index.js +42 -61
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -22,7 +22,7 @@ import { PROVIDER_ID, AUTH_LABELS, DEVICE_FLOW, PORTAL_HEADERS } from "./lib/con
22
22
  import { logError, logInfo, logWarn, LOGGING_ENABLED } from "./lib/logger.js";
23
23
 
24
24
  /** Request timeout for chat completions in milliseconds */
25
- const CHAT_REQUEST_TIMEOUT_MS = 120000;
25
+ const CHAT_REQUEST_TIMEOUT_MS = 30000;
26
26
  /** Maximum number of retry attempts for failed requests */
27
27
  const CHAT_MAX_RETRIES = 3;
28
28
  /** Output token cap for coder-model (64K tokens) */
@@ -415,19 +415,19 @@ function sanitizeOutgoingPayload(payload) {
415
415
  function createQuotaDegradedPayload(payload) {
416
416
  const degraded = { ...payload };
417
417
  let changed = false;
418
- // Remove tool-related fields (skip removing tools so Agents don't break)
419
- // if ("tools" in degraded) {
420
- // delete degraded.tools;
421
- // changed = true;
422
- // }
423
- // if ("tool_choice" in degraded) {
424
- // delete degraded.tool_choice;
425
- // changed = true;
426
- // }
427
- // if ("parallel_tool_calls" in degraded) {
428
- // delete degraded.parallel_tool_calls;
429
- // changed = true;
430
- // }
418
+ // Remove tool-related fields
419
+ if ("tools" in degraded) {
420
+ delete degraded.tools;
421
+ changed = true;
422
+ }
423
+ if ("tool_choice" in degraded) {
424
+ delete degraded.tool_choice;
425
+ changed = true;
426
+ }
427
+ if ("parallel_tool_calls" in degraded) {
428
+ delete degraded.parallel_tool_calls;
429
+ changed = true;
430
+ }
431
431
  // Disable streaming
432
432
  if (degraded.stream !== false) {
433
433
  degraded.stream = false;
@@ -595,7 +595,7 @@ function createSseResponseChunk(data) {
595
595
  * @param {boolean} streamMode - Whether to return streaming response
596
596
  * @returns {Response} Formatted completion response
597
597
  */
598
- function makeQwenCliCompletionResponse(model, content, context, streamMode, abortSignal) {
598
+ function makeQwenCliCompletionResponse(model, content, context, streamMode) {
599
599
  if (LOGGING_ENABLED) {
600
600
  logInfo("Qwen CLI fallback returned completion", {
601
601
  request_id: context.requestId,
@@ -609,7 +609,7 @@ function makeQwenCliCompletionResponse(model, content, context, streamMode, abor
609
609
  const encoder = new TextEncoder();
610
610
  const stream = new ReadableStream({
611
611
  start(controller) {
612
- // Send first chunk with empty content
612
+ // Send first chunk with content
613
613
  controller.enqueue(encoder.encode(createSseResponseChunk({
614
614
  id: completionId,
615
615
  object: "chat.completion.chunk",
@@ -618,51 +618,28 @@ function makeQwenCliCompletionResponse(model, content, context, streamMode, abor
618
618
  choices: [
619
619
  {
620
620
  index: 0,
621
- delta: { role: "assistant", content: "" },
621
+ delta: { role: "assistant", content },
622
622
  finish_reason: null,
623
623
  },
624
624
  ],
625
625
  })));
626
-
627
- const CHUNK_SIZE = 15;
628
- const DELAY_MS = 20;
629
- let position = 0;
630
-
631
- function pushNextChunk() {
632
- if (abortSignal?.aborted) {
633
- try { controller.close(); } catch (e) { }
634
- return;
635
- }
636
-
637
- if (position >= content.length) {
638
- // Send stop chunk
639
- controller.enqueue(encoder.encode(createSseResponseChunk({
640
- id: completionId,
641
- object: "chat.completion.chunk",
642
- created,
643
- model,
644
- choices: [{ index: 0, delta: {}, finish_reason: "stop" }],
645
- })));
646
- controller.enqueue(encoder.encode("data: [DONE]\n\n"));
647
- try { controller.close(); } catch (e) { }
648
- return;
649
- }
650
-
651
- const nextSlice = content.slice(position, position + CHUNK_SIZE);
652
- position += CHUNK_SIZE;
653
-
654
- controller.enqueue(encoder.encode(createSseResponseChunk({
655
- id: completionId,
656
- object: "chat.completion.chunk",
657
- created,
658
- model,
659
- choices: [{ index: 0, delta: { content: nextSlice }, finish_reason: null }],
660
- })));
661
-
662
- setTimeout(pushNextChunk, DELAY_MS);
663
- }
664
-
665
- pushNextChunk();
626
+ // Send stop chunk
627
+ controller.enqueue(encoder.encode(createSseResponseChunk({
628
+ id: completionId,
629
+ object: "chat.completion.chunk",
630
+ created,
631
+ model,
632
+ choices: [
633
+ {
634
+ index: 0,
635
+ delta: {},
636
+ finish_reason: "stop",
637
+ },
638
+ ],
639
+ })));
640
+ // Send DONE marker
641
+ controller.enqueue(encoder.encode("data: [DONE]\n\n"));
642
+ controller.close();
666
643
  },
667
644
  });
668
645
  return new Response(stream, {
@@ -724,8 +701,12 @@ async function runQwenCliFallback(payload, context, abortSignal) {
724
701
  command: QWEN_CLI_COMMAND,
725
702
  });
726
703
  }
727
- // Use secure spawn logic across ALL OS, allowing .cmd locally on Windows by injecting shell correctly.
728
- const isShellRequired = requiresShellExecution(QWEN_CLI_COMMAND);
704
+ if (requiresShellExecution(QWEN_CLI_COMMAND)) {
705
+ return {
706
+ ok: false,
707
+ reason: "cli_shell_execution_blocked_for_security",
708
+ };
709
+ }
729
710
  return await new Promise((resolve) => {
730
711
  let settled = false;
731
712
  let stdout = "";
@@ -755,7 +736,7 @@ async function runQwenCliFallback(payload, context, abortSignal) {
755
736
  }
756
737
  try {
757
738
  child = spawn(QWEN_CLI_COMMAND, args, {
758
- shell: isShellRequired,
739
+ shell: false,
759
740
  windowsHide: true,
760
741
  stdio: ["ignore", "pipe", "pipe"],
761
742
  });
@@ -810,7 +791,7 @@ async function runQwenCliFallback(payload, context, abortSignal) {
810
791
  if (content) {
811
792
  finalize({
812
793
  ok: true,
813
- response: makeQwenCliCompletionResponse(model, content, context, streamMode, abortSignal),
794
+ response: makeQwenCliCompletionResponse(model, content, context, streamMode),
814
795
  });
815
796
  return;
816
797
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-qwen-cli-auth",
3
- "version": "2.3.3",
3
+ "version": "2.3.4",
4
4
  "description": "Qwen OAuth authentication plugin for opencode - use your Qwen account instead of API keys",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",