thincoder 0.12.14 → 0.12.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/provider/sse.mjs +30 -17
package/package.json
CHANGED
package/src/provider/sse.mjs
CHANGED
|
@@ -3,6 +3,25 @@
|
|
|
3
3
|
* Extracted from core.mjs. Parses Server-Sent Events for LLM chat responses.
|
|
4
4
|
*/
|
|
5
5
|
export async function readSSE(response, { onToken, onReasoning, rules, signal, firedPatterns: sharedFired }) {
|
|
6
|
+
// Early intercept: non-SSE responses are error bodies, not streams.
|
|
7
|
+
// Read as text to preserve the full error detail (status + body).
|
|
8
|
+
const contentType = response.headers.get("content-type") || ""
|
|
9
|
+
if (!contentType.includes("event-stream")) {
|
|
10
|
+
const body = await response.text().catch(() => "")
|
|
11
|
+
let errorMsg = ""
|
|
12
|
+
try {
|
|
13
|
+
const parsed = JSON.parse(body)
|
|
14
|
+
errorMsg = parsed?.error?.message
|
|
15
|
+
|| parsed?.base_resp?.status_msg
|
|
16
|
+
|| parsed?.detail
|
|
17
|
+
|| parsed?.message
|
|
18
|
+
|| parsed?.msg
|
|
19
|
+
|| (typeof parsed.error === "string" ? parsed.error : "")
|
|
20
|
+
} catch { /* not JSON */ }
|
|
21
|
+
if (!errorMsg) errorMsg = body.slice(0, 500) // fallback: show raw body preview
|
|
22
|
+
throw new Error(`API error: HTTP ${response.status} — ${errorMsg}`)
|
|
23
|
+
}
|
|
24
|
+
|
|
6
25
|
const result = { content: "", reasoning: "", toolCalls: [], usage: null, finishReason: null }
|
|
7
26
|
const decoder = new TextDecoder()
|
|
8
27
|
let buffer = ""
|
|
@@ -86,26 +105,20 @@ export async function readSSE(response, { onToken, onReasoning, rules, signal, f
|
|
|
86
105
|
}
|
|
87
106
|
|
|
88
107
|
if (!hasChoices) {
|
|
89
|
-
|
|
108
|
+
// Stream started as SSE but no choices were parsed — unusual. Include status for debugging.
|
|
109
|
+
const raw = buffer.trim()
|
|
90
110
|
let errorMsg = ""
|
|
91
111
|
try {
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|| parsed?.msg
|
|
100
|
-
|| (typeof parsed.error === "string" ? parsed.error : "")
|
|
101
|
-
}
|
|
112
|
+
const parsed = raw ? JSON.parse(raw) : null
|
|
113
|
+
errorMsg = parsed?.error?.message
|
|
114
|
+
|| parsed?.base_resp?.status_msg
|
|
115
|
+
|| parsed?.detail
|
|
116
|
+
|| parsed?.message
|
|
117
|
+
|| parsed?.msg
|
|
118
|
+
|| (typeof parsed.error === "string" ? parsed.error : "")
|
|
102
119
|
} catch { /* not JSON */ }
|
|
103
|
-
if (!errorMsg
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
if (errorMsg) {
|
|
107
|
-
throw new Error(`API error: ${errorMsg}`)
|
|
108
|
-
}
|
|
120
|
+
if (!errorMsg) errorMsg = `SSE stream contained no choices (HTTP ${response.status})`
|
|
121
|
+
throw new Error(`API error: ${errorMsg}`)
|
|
109
122
|
}
|
|
110
123
|
|
|
111
124
|
return result
|