import type { AxiosRequestConfig } from "axios" import type { IChatWithLLMRequest } from "@/interfaces" import BaseClientService, { BaseUrl } from "./base_service.ts" export class ChatService { public static basePath = BaseUrl /** Chat with LLM */ public static async ChatWithLLM( accessToken: string, request: IChatWithLLMRequest, onProgress: (content: string) => void, ) { let response let buffer = "" let accumulatedContent = "" try { response = await fetch("/v1/chat/completions", { method: "POST", headers: { "Authorization": `Bearer ${accessToken}`, "Content-Type": "application/json", }, body: JSON.stringify(request), }) if (!response.ok) { // eslint-disable-next-line unicorn/error-message throw new Error() } const reader = response.body?.getReader() const decoder = new TextDecoder() while (true) { const { done, value } = await reader!.read() if (done) break // 将二进制数据转为字符串并存入缓冲区 buffer += decoder.decode(value) // 查找换行符分割数据 const lines = buffer.split("\n") // 保留未处理完的部分 buffer = lines.pop() || "" // 处理每一行 for (const line of lines) { const trimmedLine = line.trim() if (!trimmedLine) continue if (trimmedLine.startsWith("data: ")) { const jsonStr = trimmedLine.slice(6) // 处理结束标记 if (jsonStr === "[DONE]") { onProgress(accumulatedContent) // 最终更新 return } try { const data = JSON.parse(jsonStr) if (data.choices?.[0]?.delta?.content) { // 累积内容 accumulatedContent += data.choices[0].delta.content // 触发回调 onProgress(accumulatedContent) } } catch (err) { console.error("JSON解析失败:", err) } } } } } catch (err) { console.error("Error:", err) } } // 获取模型列表 public static GetModelList(config?: AxiosRequestConfig) { return BaseClientService.get(`${this.basePath}/model/list`, config) } }