opencode-qwen-cli-auth 2.2.6 → 2.2.8
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/dist/index.js +99 -29
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -15,10 +15,13 @@ import { PROVIDER_ID, AUTH_LABELS, DEVICE_FLOW, PORTAL_HEADERS } from "./lib/con
|
|
|
15
15
|
import { logError, logInfo, logWarn, LOGGING_ENABLED } from "./lib/logger.js";
|
|
16
16
|
const CHAT_REQUEST_TIMEOUT_MS = 30000;
|
|
17
17
|
const CHAT_MAX_RETRIES = 0;
|
|
18
|
+
const CHAT_MAX_TOKENS_CAP = 2048;
|
|
19
|
+
const CHAT_DEFAULT_MAX_TOKENS = 2048;
|
|
18
20
|
const MAX_CONSECUTIVE_POLL_FAILURES = 3;
|
|
19
21
|
const QUOTA_DEGRADE_MAX_TOKENS = 1024;
|
|
20
22
|
const CLI_FALLBACK_TIMEOUT_MS = 8000;
|
|
21
23
|
const CLI_FALLBACK_MAX_BUFFER_CHARS = 1024 * 1024;
|
|
24
|
+
const ENABLE_CLI_FALLBACK = process.env.OPENCODE_QWEN_ENABLE_CLI_FALLBACK === "1";
|
|
22
25
|
const PLUGIN_USER_AGENT = "opencode-qwen-cli-auth/2.2.1";
|
|
23
26
|
const CLIENT_ONLY_BODY_FIELDS = new Set([
|
|
24
27
|
"providerID",
|
|
@@ -97,6 +100,34 @@ function appendLimitedText(current, chunk) {
|
|
|
97
100
|
}
|
|
98
101
|
return next.slice(next.length - CLI_FALLBACK_MAX_BUFFER_CHARS);
|
|
99
102
|
}
|
|
103
|
+
function isRequestInstance(value) {
|
|
104
|
+
return typeof Request !== "undefined" && value instanceof Request;
|
|
105
|
+
}
|
|
106
|
+
async function normalizeFetchInvocation(input, init) {
|
|
107
|
+
const requestInit = init ? { ...init } : {};
|
|
108
|
+
let requestInput = input;
|
|
109
|
+
if (!isRequestInstance(input)) {
|
|
110
|
+
return { requestInput, requestInit };
|
|
111
|
+
}
|
|
112
|
+
requestInput = input.url;
|
|
113
|
+
if (!requestInit.method) {
|
|
114
|
+
requestInit.method = input.method;
|
|
115
|
+
}
|
|
116
|
+
if (!requestInit.headers) {
|
|
117
|
+
requestInit.headers = new Headers(input.headers);
|
|
118
|
+
}
|
|
119
|
+
if (requestInit.body === undefined) {
|
|
120
|
+
try {
|
|
121
|
+
requestInit.body = await input.clone().text();
|
|
122
|
+
}
|
|
123
|
+
catch (_error) {
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (!requestInit.signal) {
|
|
127
|
+
requestInit.signal = input.signal;
|
|
128
|
+
}
|
|
129
|
+
return { requestInput, requestInit };
|
|
130
|
+
}
|
|
100
131
|
function getHeaderValue(headers, headerName) {
|
|
101
132
|
if (!headers) {
|
|
102
133
|
return undefined;
|
|
@@ -178,6 +209,14 @@ function sanitizeOutgoingPayload(payload) {
|
|
|
178
209
|
delete sanitized.stream_options;
|
|
179
210
|
changed = true;
|
|
180
211
|
}
|
|
212
|
+
if (typeof sanitized.max_tokens === "number" && sanitized.max_tokens > CHAT_MAX_TOKENS_CAP) {
|
|
213
|
+
sanitized.max_tokens = CHAT_MAX_TOKENS_CAP;
|
|
214
|
+
changed = true;
|
|
215
|
+
}
|
|
216
|
+
if (typeof sanitized.max_completion_tokens === "number" && sanitized.max_completion_tokens > CHAT_MAX_TOKENS_CAP) {
|
|
217
|
+
sanitized.max_completion_tokens = CHAT_MAX_TOKENS_CAP;
|
|
218
|
+
changed = true;
|
|
219
|
+
}
|
|
181
220
|
return changed ? sanitized : payload;
|
|
182
221
|
}
|
|
183
222
|
function createQuotaDegradedPayload(payload) {
|
|
@@ -543,7 +582,9 @@ async function sendWithTimeout(input, requestInit) {
|
|
|
543
582
|
}
|
|
544
583
|
}
|
|
545
584
|
async function failFastFetch(input, init) {
|
|
546
|
-
const
|
|
585
|
+
const normalized = await normalizeFetchInvocation(input, init);
|
|
586
|
+
const requestInput = normalized.requestInput;
|
|
587
|
+
const requestInit = normalized.requestInit;
|
|
547
588
|
const sourceSignal = requestInit.signal;
|
|
548
589
|
const rawPayload = parseJsonRequestBody(requestInit);
|
|
549
590
|
const sessionID = typeof rawPayload?.sessionID === "string" ? rawPayload.sessionID : undefined;
|
|
@@ -565,10 +606,14 @@ async function failFastFetch(input, init) {
|
|
|
565
606
|
request_id: context.requestId,
|
|
566
607
|
sessionID: context.sessionID,
|
|
567
608
|
modelID: context.modelID,
|
|
609
|
+
max_tokens: typeof payload?.max_tokens === "number" ? payload.max_tokens : undefined,
|
|
610
|
+
max_completion_tokens: typeof payload?.max_completion_tokens === "number" ? payload.max_completion_tokens : undefined,
|
|
611
|
+
message_count: Array.isArray(payload?.messages) ? payload.messages.length : undefined,
|
|
612
|
+
stream: payload?.stream === true,
|
|
568
613
|
});
|
|
569
614
|
}
|
|
570
615
|
try {
|
|
571
|
-
let response = await sendWithTimeout(
|
|
616
|
+
let response = await sendWithTimeout(requestInput, requestInit);
|
|
572
617
|
if (LOGGING_ENABLED) {
|
|
573
618
|
logInfo("Qwen request response", {
|
|
574
619
|
request_id: context.requestId,
|
|
@@ -593,7 +638,7 @@ async function failFastFetch(input, init) {
|
|
|
593
638
|
attempt: 2,
|
|
594
639
|
});
|
|
595
640
|
}
|
|
596
|
-
response = await sendWithTimeout(
|
|
641
|
+
response = await sendWithTimeout(requestInput, fallbackInit);
|
|
597
642
|
if (LOGGING_ENABLED) {
|
|
598
643
|
logInfo("Qwen request response", {
|
|
599
644
|
request_id: context.requestId,
|
|
@@ -607,6 +652,27 @@ async function failFastFetch(input, init) {
|
|
|
607
652
|
return response;
|
|
608
653
|
}
|
|
609
654
|
const fallbackBody = await response.text().catch(() => "");
|
|
655
|
+
if (ENABLE_CLI_FALLBACK) {
|
|
656
|
+
const cliFallback = await runQwenCliFallback(payload, context, sourceSignal);
|
|
657
|
+
if (cliFallback.ok) {
|
|
658
|
+
return cliFallback.response;
|
|
659
|
+
}
|
|
660
|
+
if (cliFallback.reason === "cli_aborted") {
|
|
661
|
+
return makeFailFastErrorResponse(400, "request_aborted", "Qwen request was aborted");
|
|
662
|
+
}
|
|
663
|
+
if (LOGGING_ENABLED) {
|
|
664
|
+
logWarn("Qwen CLI fallback failed", {
|
|
665
|
+
request_id: context.requestId,
|
|
666
|
+
sessionID: context.sessionID,
|
|
667
|
+
modelID: context.modelID,
|
|
668
|
+
reason: cliFallback.reason,
|
|
669
|
+
stderr: cliFallback.stderr,
|
|
670
|
+
});
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
return makeQuotaFailFastResponse(fallbackBody, response.headers, context);
|
|
674
|
+
}
|
|
675
|
+
if (ENABLE_CLI_FALLBACK) {
|
|
610
676
|
const cliFallback = await runQwenCliFallback(payload, context, sourceSignal);
|
|
611
677
|
if (cliFallback.ok) {
|
|
612
678
|
return cliFallback.response;
|
|
@@ -623,23 +689,6 @@ async function failFastFetch(input, init) {
|
|
|
623
689
|
stderr: cliFallback.stderr,
|
|
624
690
|
});
|
|
625
691
|
}
|
|
626
|
-
return makeQuotaFailFastResponse(fallbackBody, response.headers, context);
|
|
627
|
-
}
|
|
628
|
-
const cliFallback = await runQwenCliFallback(payload, context, sourceSignal);
|
|
629
|
-
if (cliFallback.ok) {
|
|
630
|
-
return cliFallback.response;
|
|
631
|
-
}
|
|
632
|
-
if (cliFallback.reason === "cli_aborted") {
|
|
633
|
-
return makeFailFastErrorResponse(400, "request_aborted", "Qwen request was aborted");
|
|
634
|
-
}
|
|
635
|
-
if (LOGGING_ENABLED) {
|
|
636
|
-
logWarn("Qwen CLI fallback failed", {
|
|
637
|
-
request_id: context.requestId,
|
|
638
|
-
sessionID: context.sessionID,
|
|
639
|
-
modelID: context.modelID,
|
|
640
|
-
reason: cliFallback.reason,
|
|
641
|
-
stderr: cliFallback.stderr,
|
|
642
|
-
});
|
|
643
692
|
}
|
|
644
693
|
}
|
|
645
694
|
return makeQuotaFailFastResponse(firstBody, response.headers, context);
|
|
@@ -872,21 +921,21 @@ export const QwenAuthPlugin = async (_input) => {
|
|
|
872
921
|
maxRetries: CHAT_MAX_RETRIES,
|
|
873
922
|
},
|
|
874
923
|
models: {
|
|
875
|
-
"coder-model": {
|
|
876
|
-
id: "coder-model",
|
|
877
|
-
name: "Qwen Coder (Qwen 3.5 Plus)",
|
|
924
|
+
"coder-model": {
|
|
925
|
+
id: "coder-model",
|
|
926
|
+
name: "Qwen Coder (Qwen 3.5 Plus)",
|
|
878
927
|
// Qwen does not support reasoning_effort from OpenCode UI
|
|
879
928
|
// Thinking is always enabled by default on server side (qwen3.5-plus)
|
|
880
929
|
reasoning: false,
|
|
881
|
-
limit: { context: 1048576, output:
|
|
930
|
+
limit: { context: 1048576, output: CHAT_MAX_TOKENS_CAP },
|
|
882
931
|
cost: { input: 0, output: 0 },
|
|
883
932
|
modalities: { input: ["text"], output: ["text"] },
|
|
884
933
|
},
|
|
885
|
-
"vision-model": {
|
|
886
|
-
id: "vision-model",
|
|
887
|
-
name: "Qwen VL Plus (vision)",
|
|
888
|
-
reasoning: false,
|
|
889
|
-
limit: { context: 131072, output:
|
|
934
|
+
"vision-model": {
|
|
935
|
+
id: "vision-model",
|
|
936
|
+
name: "Qwen VL Plus (vision)",
|
|
937
|
+
reasoning: false,
|
|
938
|
+
limit: { context: 131072, output: CHAT_MAX_TOKENS_CAP },
|
|
890
939
|
cost: { input: 0, output: 0 },
|
|
891
940
|
modalities: { input: ["text"], output: ["text"] },
|
|
892
941
|
},
|
|
@@ -901,12 +950,33 @@ export const QwenAuthPlugin = async (_input) => {
|
|
|
901
950
|
if (typeof output.options.timeout !== "number" || output.options.timeout > CHAT_REQUEST_TIMEOUT_MS) {
|
|
902
951
|
output.options.timeout = CHAT_REQUEST_TIMEOUT_MS;
|
|
903
952
|
}
|
|
953
|
+
if (typeof output.max_tokens !== "number" || output.max_tokens > CHAT_MAX_TOKENS_CAP) {
|
|
954
|
+
output.max_tokens = CHAT_DEFAULT_MAX_TOKENS;
|
|
955
|
+
}
|
|
956
|
+
if (typeof output.max_completion_tokens !== "number" || output.max_completion_tokens > CHAT_MAX_TOKENS_CAP) {
|
|
957
|
+
output.max_completion_tokens = CHAT_DEFAULT_MAX_TOKENS;
|
|
958
|
+
}
|
|
959
|
+
if (typeof output.maxTokens !== "number" || output.maxTokens > CHAT_MAX_TOKENS_CAP) {
|
|
960
|
+
output.maxTokens = CHAT_DEFAULT_MAX_TOKENS;
|
|
961
|
+
}
|
|
962
|
+
if (typeof output.options.max_tokens !== "number" || output.options.max_tokens > CHAT_MAX_TOKENS_CAP) {
|
|
963
|
+
output.options.max_tokens = CHAT_DEFAULT_MAX_TOKENS;
|
|
964
|
+
}
|
|
965
|
+
if (typeof output.options.max_completion_tokens !== "number" || output.options.max_completion_tokens > CHAT_MAX_TOKENS_CAP) {
|
|
966
|
+
output.options.max_completion_tokens = CHAT_DEFAULT_MAX_TOKENS;
|
|
967
|
+
}
|
|
968
|
+
if (typeof output.options.maxTokens !== "number" || output.options.maxTokens > CHAT_MAX_TOKENS_CAP) {
|
|
969
|
+
output.options.maxTokens = CHAT_DEFAULT_MAX_TOKENS;
|
|
970
|
+
}
|
|
904
971
|
if (LOGGING_ENABLED) {
|
|
905
972
|
logInfo("Applied chat.params hotfix", {
|
|
906
973
|
sessionID: input?.sessionID,
|
|
907
974
|
modelID: input?.model?.id,
|
|
908
975
|
timeout: output.options.timeout,
|
|
909
976
|
maxRetries: output.options.maxRetries,
|
|
977
|
+
max_tokens: output.max_tokens,
|
|
978
|
+
max_completion_tokens: output.max_completion_tokens,
|
|
979
|
+
maxTokens: output.maxTokens,
|
|
910
980
|
});
|
|
911
981
|
}
|
|
912
982
|
}
|
package/package.json
CHANGED