-
Notifications
You must be signed in to change notification settings - Fork 13
/
index.ts
145 lines (134 loc) · 3.15 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
type ContentResult = {
content: string
done?: never
}
type DoneResult = {
done: true
content?: never
}
type TransformResult = ContentResult | DoneResult
type TransformFunction<T = any> = (rawValue: T, ...args: any) => TransformResult
/**
* 转义处理响应值为 data: 的 json 字符串
* 如: 科大讯飞星火、Kimi Moonshot 等大模型的 response
*/
export const parseJsonLikeData = (content) => {
if (content.startsWith('data: ')) {
const dataString = content.substring(6).trim()
if (dataString === '[DONE]') {
return {
done: true
}
}
try {
return JSON.parse(dataString)
} catch (error) {
console.error('JSON parsing error:', error)
}
}
return null
}
/**
* 大模型映射列表
*/
export const LLMTypes = [
{
label: '模拟数据模型',
modelName: 'standard'
},
{
label: 'Spark 星火大模型',
modelName: 'spark'
},
{
label: 'Ollama 3 大模型',
modelName: 'ollama3'
},
{
label: 'SiliconFlow 硅基流动大模型',
modelName: 'siliconflow'
},
{
label: 'Kimi Moonshot 月之暗面大模型',
modelName: 'moonshot'
}
] as const
export type TransformStreamModelTypes = typeof LLMTypes[number]['modelName']
/**
* 用于处理不同类型流的值转换器
*/
export const transformStreamValue: Record<TransformStreamModelTypes, TransformFunction> = {
standard(readValue: Uint8Array, textDecoder: TextDecoder) {
let content = ''
if (readValue instanceof Uint8Array) {
content = textDecoder.decode(readValue, {
stream: true
})
} else {
content = readValue
}
return {
content
}
},
spark(readValue) {
const stream = parseJsonLikeData(readValue)
if (stream.done) {
return {
done: true
}
}
return {
content: stream.choices[0].delta.content || ''
}
},
siliconflow(readValue) {
// 与 spark 类似,直接复用
return this.spark(readValue)
},
moonshot(readValue) {
// 与 spark 类似,直接复用
return this.spark(readValue)
},
ollama3(readValue) {
const stream = JSON.parse(readValue)
return {
content: stream.message.content
}
}
}
const processParts = (buffer, controller: TransformStreamDefaultController, splitOn) => {
const parts = buffer.split(splitOn)
parts.slice(0, -1).forEach((part) => {
if (part.trim() !== '') {
controller.enqueue(part)
}
})
return parts[parts.length - 1]
}
export const splitStream = (splitOn) => {
let buffer = ''
return new TransformStream({
transform(chunk, controller) {
buffer += chunk
if (buffer.trim().startsWith('data:')) {
buffer = processParts(buffer, controller, splitOn)
} else {
// 尝试是否能够直接解析为 JSON
try {
JSON.parse(buffer)
buffer = processParts(buffer, controller, splitOn)
} catch (error) {
// 如果解析失败,按原文本处理
controller.enqueue(chunk)
buffer = ''
}
}
},
flush(controller) {
if (buffer.trim() !== '') {
controller.enqueue(buffer)
}
}
})
}