92 lines
2.4 KiB
TypeScript
92 lines
2.4 KiB
TypeScript
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<any>) {
|
|
return BaseClientService.get(`${this.basePath}/model/list`, config)
|
|
}
|
|
}
|