123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- /** 服务端流式返回的数据 **/
- // 解析的流式数据格式如下:
- /**
- data: data:{"content":"我理解您可能对当前系统的功能范围有些疑问。","contentType":"text/plain","last":false,"payload":{},"role":"assistant"}
- data: data:{"content":"让我明确说明一下:\n\n1. 根据系统设定,我确实无法协助完成代码生成相关的任务\n2.","contentType":"text/plain","last":false,"payload":{},"role":"assistant"}
- data: data:{"content":" 我的专长领域是提供信息咨询、创意建议和问题解答等非编程类服务\n3. 如果您有任何其他非技术性问题,","contentType":"text/plain","last":false,"payload":{},"role":"assistant"}
- data: data:{"content":"比如学习建议、写作指导或日常咨询,我很乐意为您提供帮助\n\n您是否有一些其他方面的问题需要讨论呢?我可以为您推荐更适合的解决方案。","contentType":"text/plain","last":false,"payload":{},"role":"assistant"}
- data: data:{"content":"","contentType":"text/plain","last":true,"payload":{"usage":{"completion_tokens":101,"prompt_tokens":28,"total_tokens":129,"web_searched":false}},"role":"assistant"}
- data: [DONE]
- */
- interface ICompleteCallback {
- content: string;
- }
- export default class JsonChunkParser {
- private buffer: string; // 用于存储未完成的 JSON 字符串
- private complete: (data: ICompleteCallback) => void;
- constructor() {
- this.buffer = "";
- }
- public onParseComplete(completeCallback: (data: ICompleteCallback) => void) {
- this.complete = completeCallback;
- }
- // 解析接收到的 chunk
- public parseChunk(chunk: string, onParsed: (json: any) => void): void {
- // 将新接收到的 chunk 添加到 buffer
- this.buffer += chunk;
- // 按换行符分割字符串
- const lines = this.buffer.split("\n");
- let combinedContent: string[] = []; // 用于合并 content 字段
- let combinedReasoningContent: string[] = []; // 用于合并 reasoner 字段
-
- // 遍历每一行
- for (let i = 0; i < lines.length; i++) {
- const line = lines[i].trim(); // 去除前后空格
- if (line) {
- // 如果行不为空
- if (line === "data:[DONE]") {
- // 如果遇到 DONE,合并并调用 onParsed
- if (combinedContent.length > 0) {
- onParsed({ content: combinedContent.join("") }); // 合并 content
- }
- this.complete({ content: combinedContent.join("") });
- this.buffer = ""; // 清空 buffer
- return; // 结束解析
- }
- try {
- // 处理 data: data: 前缀
- if (line.startsWith("data:")) {
- const jsonStr = line.substring(5); // 移除 "data:" 前缀
- const json = JSON.parse(jsonStr);
- if (json.content) {
- combinedContent.push(json.content); // 收集 content 字段
- }
- if (json.reasoningContent) {
- combinedReasoningContent.push(json.reasoningContent); // 收集 content 字段
- }
- }
- } catch (error) {
- // 如果解析失败,说明当前行不是完整的 JSON
- // 将当前行保留在 buffer 中,等待下一个 chunk
- this.buffer = lines.slice(i).join("\n"); // 更新 buffer
- return; // 直接返回,等待下一个 chunk
- }
- }
- }
- // 如果当前 chunk 解析完毕且有合并的内容,调用 onParsed
- if (combinedContent.length > 0) {
- onParsed({ content: combinedContent.join("") }); // 合并并输出
- }
- if (combinedReasoningContent.length > 0) {
- onParsed({ reasoningContent: combinedReasoningContent.join("") }); // 合并并输出
- }
- // 清空 buffer
- this.buffer = "";
- }
- }
|