winter-super-cli 2026.6.14 → 2026.6.15
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 +1 -1
- package/src/ai/providers.js +25 -1
package/package.json
CHANGED
package/src/ai/providers.js
CHANGED
|
@@ -614,11 +614,15 @@ export class AIProviderManager {
|
|
|
614
614
|
|
|
615
615
|
const decoder = new TextDecoder();
|
|
616
616
|
let buffer = '';
|
|
617
|
+
let rawText = '';
|
|
618
|
+
let yieldedAny = false;
|
|
617
619
|
|
|
618
620
|
for await (const chunk of response.body) {
|
|
619
621
|
if (timeout.resetTimer) timeout.resetTimer();
|
|
620
622
|
|
|
621
|
-
|
|
623
|
+
const decoded = decoder.decode(chunk, { stream: true });
|
|
624
|
+
rawText += decoded;
|
|
625
|
+
buffer += decoded;
|
|
622
626
|
const lines = buffer.split(/\r?\n/);
|
|
623
627
|
buffer = lines.pop() || '';
|
|
624
628
|
|
|
@@ -638,6 +642,7 @@ export class AIProviderManager {
|
|
|
638
642
|
|
|
639
643
|
const choice = data.choices?.[0] || {};
|
|
640
644
|
const content = choice.delta?.content ?? choice.message?.content ?? choice.text ?? '';
|
|
645
|
+
yieldedAny = true;
|
|
641
646
|
yield {
|
|
642
647
|
content,
|
|
643
648
|
usage: data.usage,
|
|
@@ -653,6 +658,7 @@ export class AIProviderManager {
|
|
|
653
658
|
try {
|
|
654
659
|
const data = JSON.parse(payload);
|
|
655
660
|
const choice = data.choices?.[0] || {};
|
|
661
|
+
yieldedAny = true;
|
|
656
662
|
yield {
|
|
657
663
|
content: choice.delta?.content ?? choice.message?.content ?? choice.text ?? '',
|
|
658
664
|
usage: data.usage,
|
|
@@ -661,6 +667,24 @@ export class AIProviderManager {
|
|
|
661
667
|
} catch {}
|
|
662
668
|
}
|
|
663
669
|
}
|
|
670
|
+
|
|
671
|
+
if (!yieldedAny) {
|
|
672
|
+
try {
|
|
673
|
+
const data = JSON.parse(rawText.trim());
|
|
674
|
+
const choice = data.choices?.[0] || {};
|
|
675
|
+
const content = choice.delta?.content ?? choice.message?.content ?? choice.text ?? '';
|
|
676
|
+
if (content || data.usage || choice.finish_reason) {
|
|
677
|
+
yield {
|
|
678
|
+
content,
|
|
679
|
+
usage: data.usage,
|
|
680
|
+
raw: data,
|
|
681
|
+
};
|
|
682
|
+
}
|
|
683
|
+
} catch {
|
|
684
|
+
// Some OpenAI-compatible servers return 200 with a non-SSE/non-JSON body
|
|
685
|
+
// when streaming is requested. Let the caller fall back to non-streaming.
|
|
686
|
+
}
|
|
687
|
+
}
|
|
664
688
|
} catch (error) {
|
|
665
689
|
throw normalizeFetchError(error, provider, timeoutMs, true, timeout.timedOut());
|
|
666
690
|
} finally {
|