incognitolm commited on
Commit ·
d04bf99
1
Parent(s): c317b28
Update chatStream.js
Browse files- server/chatStream.js +18 -3
server/chatStream.js
CHANGED
|
@@ -192,9 +192,24 @@ export async function websocketChatStream(body, headers, onToken, abortSignal) {
|
|
| 192 |
let finished = false;
|
| 193 |
|
| 194 |
return new Promise((resolve, reject) => {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 195 |
const cleanup = () => {
|
| 196 |
activeStreamHandlers.delete(currentRequestId);
|
| 197 |
errorHandlers.delete(currentRequestId);
|
|
|
|
| 198 |
if (abortSignal) {
|
| 199 |
abortSignal.removeEventListener("abort", abortHandler);
|
| 200 |
}
|
|
@@ -220,12 +235,12 @@ export async function websocketChatStream(body, headers, onToken, abortSignal) {
|
|
| 220 |
return;
|
| 221 |
}
|
| 222 |
|
| 223 |
-
//
|
| 224 |
-
if (payload.error) {
|
| 225 |
console.error("[WS PAYLOAD ERROR]", payload.error);
|
| 226 |
if (onToken) onToken(`[ERROR] ${payload.error}`);
|
| 227 |
|
| 228 |
-
// Mark as finished to end the stream
|
| 229 |
if (!finished) {
|
| 230 |
finished = true;
|
| 231 |
cleanup();
|
|
|
|
| 192 |
let finished = false;
|
| 193 |
|
| 194 |
return new Promise((resolve, reject) => {
|
| 195 |
+
// Timeout fallback - resolve after 120 seconds if no finish_reason
|
| 196 |
+
const timeoutId = setTimeout(() => {
|
| 197 |
+
if (!finished) {
|
| 198 |
+
finished = true;
|
| 199 |
+
cleanup();
|
| 200 |
+
const toolCalls = [...toolCallBuffer.values()].map((t) => ({
|
| 201 |
+
id: t.id || `call_${crypto.randomUUID()}`,
|
| 202 |
+
type: "function",
|
| 203 |
+
function: { name: t.name, arguments: t.arguments },
|
| 204 |
+
}));
|
| 205 |
+
resolve({ assistantText, toolCalls });
|
| 206 |
+
}
|
| 207 |
+
}, 120000);
|
| 208 |
+
|
| 209 |
const cleanup = () => {
|
| 210 |
activeStreamHandlers.delete(currentRequestId);
|
| 211 |
errorHandlers.delete(currentRequestId);
|
| 212 |
+
clearTimeout(timeoutId);
|
| 213 |
if (abortSignal) {
|
| 214 |
abortSignal.removeEventListener("abort", abortHandler);
|
| 215 |
}
|
|
|
|
| 235 |
return;
|
| 236 |
}
|
| 237 |
|
| 238 |
+
// Only treat as fatal error if it's a structured error response (not delta data with error field)
|
| 239 |
+
if (payload.error && !payload.choices) {
|
| 240 |
console.error("[WS PAYLOAD ERROR]", payload.error);
|
| 241 |
if (onToken) onToken(`[ERROR] ${payload.error}`);
|
| 242 |
|
| 243 |
+
// Mark as finished to end the stream on fatal errors only
|
| 244 |
if (!finished) {
|
| 245 |
finished = true;
|
| 246 |
cleanup();
|