opencode-qwen-cli-auth 2.2.5 → 2.2.6
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 +88 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -17,7 +17,7 @@ const CHAT_REQUEST_TIMEOUT_MS = 30000;
|
|
|
17
17
|
const CHAT_MAX_RETRIES = 0;
|
|
18
18
|
const MAX_CONSECUTIVE_POLL_FAILURES = 3;
|
|
19
19
|
const QUOTA_DEGRADE_MAX_TOKENS = 1024;
|
|
20
|
-
const CLI_FALLBACK_TIMEOUT_MS =
|
|
20
|
+
const CLI_FALLBACK_TIMEOUT_MS = 8000;
|
|
21
21
|
const CLI_FALLBACK_MAX_BUFFER_CHARS = 1024 * 1024;
|
|
22
22
|
const PLUGIN_USER_AGENT = "opencode-qwen-cli-auth/2.2.1";
|
|
23
23
|
const CLIENT_ONLY_BODY_FIELDS = new Set([
|
|
@@ -309,7 +309,10 @@ function extractQwenCliText(events) {
|
|
|
309
309
|
}
|
|
310
310
|
return null;
|
|
311
311
|
}
|
|
312
|
-
function
|
|
312
|
+
function createSseResponseChunk(data) {
|
|
313
|
+
return `data: ${JSON.stringify(data)}\n\n`;
|
|
314
|
+
}
|
|
315
|
+
function makeQwenCliCompletionResponse(model, content, context, streamMode) {
|
|
313
316
|
if (LOGGING_ENABLED) {
|
|
314
317
|
logInfo("Qwen CLI fallback returned completion", {
|
|
315
318
|
request_id: context.requestId,
|
|
@@ -317,6 +320,51 @@ function makeQwenCliCompletionResponse(model, content, context) {
|
|
|
317
320
|
modelID: model,
|
|
318
321
|
});
|
|
319
322
|
}
|
|
323
|
+
if (streamMode) {
|
|
324
|
+
const completionId = `chatcmpl-${randomUUID()}`;
|
|
325
|
+
const created = Math.floor(Date.now() / 1000);
|
|
326
|
+
const encoder = new TextEncoder();
|
|
327
|
+
const stream = new ReadableStream({
|
|
328
|
+
start(controller) {
|
|
329
|
+
controller.enqueue(encoder.encode(createSseResponseChunk({
|
|
330
|
+
id: completionId,
|
|
331
|
+
object: "chat.completion.chunk",
|
|
332
|
+
created,
|
|
333
|
+
model,
|
|
334
|
+
choices: [
|
|
335
|
+
{
|
|
336
|
+
index: 0,
|
|
337
|
+
delta: { role: "assistant", content },
|
|
338
|
+
finish_reason: null,
|
|
339
|
+
},
|
|
340
|
+
],
|
|
341
|
+
})));
|
|
342
|
+
controller.enqueue(encoder.encode(createSseResponseChunk({
|
|
343
|
+
id: completionId,
|
|
344
|
+
object: "chat.completion.chunk",
|
|
345
|
+
created,
|
|
346
|
+
model,
|
|
347
|
+
choices: [
|
|
348
|
+
{
|
|
349
|
+
index: 0,
|
|
350
|
+
delta: {},
|
|
351
|
+
finish_reason: "stop",
|
|
352
|
+
},
|
|
353
|
+
],
|
|
354
|
+
})));
|
|
355
|
+
controller.enqueue(encoder.encode("data: [DONE]\n\n"));
|
|
356
|
+
controller.close();
|
|
357
|
+
},
|
|
358
|
+
});
|
|
359
|
+
return new Response(stream, {
|
|
360
|
+
status: 200,
|
|
361
|
+
headers: {
|
|
362
|
+
"content-type": "text/event-stream; charset=utf-8",
|
|
363
|
+
"cache-control": "no-cache",
|
|
364
|
+
"x-qwen-cli-fallback": "1",
|
|
365
|
+
},
|
|
366
|
+
});
|
|
367
|
+
}
|
|
320
368
|
const body = {
|
|
321
369
|
id: `chatcmpl-${randomUUID()}`,
|
|
322
370
|
object: "chat.completion",
|
|
@@ -346,8 +394,9 @@ function makeQwenCliCompletionResponse(model, content, context) {
|
|
|
346
394
|
},
|
|
347
395
|
});
|
|
348
396
|
}
|
|
349
|
-
async function runQwenCliFallback(payload, context) {
|
|
397
|
+
async function runQwenCliFallback(payload, context, abortSignal) {
|
|
350
398
|
const model = typeof payload?.model === "string" && payload.model.length > 0 ? payload.model : "coder-model";
|
|
399
|
+
const streamMode = payload?.stream === true;
|
|
351
400
|
const prompt = buildQwenCliPrompt(payload);
|
|
352
401
|
const args = [prompt, "-o", "json", "--max-session-turns", "1", "--model", model];
|
|
353
402
|
if (LOGGING_ENABLED) {
|
|
@@ -363,6 +412,8 @@ async function runQwenCliFallback(payload, context) {
|
|
|
363
412
|
let stdout = "";
|
|
364
413
|
let stderr = "";
|
|
365
414
|
let timer = null;
|
|
415
|
+
let child = undefined;
|
|
416
|
+
let abortHandler = undefined;
|
|
366
417
|
const useShell = shouldUseShell(QWEN_CLI_COMMAND);
|
|
367
418
|
const finalize = (result) => {
|
|
368
419
|
if (settled) {
|
|
@@ -372,9 +423,18 @@ async function runQwenCliFallback(payload, context) {
|
|
|
372
423
|
if (timer) {
|
|
373
424
|
clearTimeout(timer);
|
|
374
425
|
}
|
|
426
|
+
if (abortSignal && abortHandler) {
|
|
427
|
+
abortSignal.removeEventListener("abort", abortHandler);
|
|
428
|
+
}
|
|
375
429
|
resolve(result);
|
|
376
430
|
};
|
|
377
|
-
|
|
431
|
+
if (abortSignal?.aborted) {
|
|
432
|
+
finalize({
|
|
433
|
+
ok: false,
|
|
434
|
+
reason: "cli_aborted",
|
|
435
|
+
});
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
378
438
|
try {
|
|
379
439
|
child = spawn(QWEN_CLI_COMMAND, args, {
|
|
380
440
|
shell: useShell,
|
|
@@ -389,6 +449,20 @@ async function runQwenCliFallback(payload, context) {
|
|
|
389
449
|
});
|
|
390
450
|
return;
|
|
391
451
|
}
|
|
452
|
+
if (abortSignal) {
|
|
453
|
+
abortHandler = () => {
|
|
454
|
+
try {
|
|
455
|
+
child?.kill();
|
|
456
|
+
}
|
|
457
|
+
catch (_killError) {
|
|
458
|
+
}
|
|
459
|
+
finalize({
|
|
460
|
+
ok: false,
|
|
461
|
+
reason: "cli_aborted",
|
|
462
|
+
});
|
|
463
|
+
};
|
|
464
|
+
abortSignal.addEventListener("abort", abortHandler, { once: true });
|
|
465
|
+
}
|
|
392
466
|
timer = setTimeout(() => {
|
|
393
467
|
try {
|
|
394
468
|
child.kill();
|
|
@@ -418,7 +492,7 @@ async function runQwenCliFallback(payload, context) {
|
|
|
418
492
|
if (content) {
|
|
419
493
|
finalize({
|
|
420
494
|
ok: true,
|
|
421
|
-
response: makeQwenCliCompletionResponse(model, content, context),
|
|
495
|
+
response: makeQwenCliCompletionResponse(model, content, context, streamMode),
|
|
422
496
|
});
|
|
423
497
|
return;
|
|
424
498
|
}
|
|
@@ -470,6 +544,7 @@ async function sendWithTimeout(input, requestInit) {
|
|
|
470
544
|
}
|
|
471
545
|
async function failFastFetch(input, init) {
|
|
472
546
|
const requestInit = init ? { ...init } : {};
|
|
547
|
+
const sourceSignal = requestInit.signal;
|
|
473
548
|
const rawPayload = parseJsonRequestBody(requestInit);
|
|
474
549
|
const sessionID = typeof rawPayload?.sessionID === "string" ? rawPayload.sessionID : undefined;
|
|
475
550
|
let payload = rawPayload;
|
|
@@ -532,10 +607,13 @@ async function failFastFetch(input, init) {
|
|
|
532
607
|
return response;
|
|
533
608
|
}
|
|
534
609
|
const fallbackBody = await response.text().catch(() => "");
|
|
535
|
-
const cliFallback = await runQwenCliFallback(payload, context);
|
|
610
|
+
const cliFallback = await runQwenCliFallback(payload, context, sourceSignal);
|
|
536
611
|
if (cliFallback.ok) {
|
|
537
612
|
return cliFallback.response;
|
|
538
613
|
}
|
|
614
|
+
if (cliFallback.reason === "cli_aborted") {
|
|
615
|
+
return makeFailFastErrorResponse(400, "request_aborted", "Qwen request was aborted");
|
|
616
|
+
}
|
|
539
617
|
if (LOGGING_ENABLED) {
|
|
540
618
|
logWarn("Qwen CLI fallback failed", {
|
|
541
619
|
request_id: context.requestId,
|
|
@@ -547,10 +625,13 @@ async function failFastFetch(input, init) {
|
|
|
547
625
|
}
|
|
548
626
|
return makeQuotaFailFastResponse(fallbackBody, response.headers, context);
|
|
549
627
|
}
|
|
550
|
-
const cliFallback = await runQwenCliFallback(payload, context);
|
|
628
|
+
const cliFallback = await runQwenCliFallback(payload, context, sourceSignal);
|
|
551
629
|
if (cliFallback.ok) {
|
|
552
630
|
return cliFallback.response;
|
|
553
631
|
}
|
|
632
|
+
if (cliFallback.reason === "cli_aborted") {
|
|
633
|
+
return makeFailFastErrorResponse(400, "request_aborted", "Qwen request was aborted");
|
|
634
|
+
}
|
|
554
635
|
if (LOGGING_ENABLED) {
|
|
555
636
|
logWarn("Qwen CLI fallback failed", {
|
|
556
637
|
request_id: context.requestId,
|
package/package.json
CHANGED