From 25f5d31fab005d6d542d20f33a725020ff6cea5d Mon Sep 17 00:00:00 2001 From: Neko Ayaka Date: Tue, 3 Dec 2024 23:49:24 +0800 Subject: [PATCH] fix: unable to parse the result due to not check data: frame for sse --- packages/stream-text/src/index.ts | 36 ++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/packages/stream-text/src/index.ts b/packages/stream-text/src/index.ts index 4d2c815..629cfc1 100644 --- a/packages/stream-text/src/index.ts +++ b/packages/stream-text/src/index.ts @@ -42,6 +42,9 @@ export interface StreamTextResponse { usage?: StreamTextResponseUsage } +const dataHeaderPrefix = 'data: ' +const dataErrorPrefix = `{"error":` + /** * @experimental * WIP, currently only returns `textStream`, does not support function calling (tools). @@ -64,20 +67,33 @@ export const streamText = async (options: StreamTextOptions): Promise { for (const line of decoder.decode(chunk).split('\n').filter(line => line)) { - if (line !== 'data: [DONE]') { - const data: StreamTextResponse = JSON.parse(line.slice(6)) + // Some cases: + // - Empty chunk + // - :ROUTER PROCESSING from OpenRouter + if (!line || !line.startsWith(dataHeaderPrefix)) { + continue + } - controller.enqueue(data) + if (line.startsWith(dataErrorPrefix)) { + // About controller error: https://developer.mozilla.org/en-US/docs/Web/API/TransformStreamDefaultController/error + controller.error(new Error(`Error from server: ${line}`)) + continue + } - if (data.choices[0].finish_reason) { - finishReason = data.choices[0].finish_reason - } + const lineWithoutPrefix = line.slice(dataHeaderPrefix.length) + if (lineWithoutPrefix === '[DONE]') { + controller.terminate() + continue + } + + const data: StreamTextResponse = JSON.parse(line.slice(6)) + controller.enqueue(data) - if (data.usage) - usage = data.usage + if (data.choices[0].finish_reason) { + finishReason = data.choices[0].finish_reason } - else { - controller.terminate() + if (data.usage) { + usage = data.usage } } },