plain-design 1.0.0-beta.150 → 1.0.0-beta.151
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -13,6 +13,11 @@ import {toArray} from "@peryl/utils/toArray";
|
|
|
13
13
|
|
|
14
14
|
export const $ai = (() => {
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* 获取模型服务信息
|
|
18
|
+
* @author 韦胜健
|
|
19
|
+
* @date 2025/5/20 19:26
|
|
20
|
+
*/
|
|
16
21
|
const getConfig = (): iAiConfiguration => {
|
|
17
22
|
const aiConfig = $configuration.get('aiConfig');
|
|
18
23
|
if (!aiConfig) {
|
|
@@ -22,6 +27,11 @@ export const $ai = (() => {
|
|
|
22
27
|
|
|
23
28
|
};
|
|
24
29
|
|
|
30
|
+
/**
|
|
31
|
+
* 带对话历史的模型调用
|
|
32
|
+
* @author 韦胜健
|
|
33
|
+
* @date 2025/5/20 19:26
|
|
34
|
+
*/
|
|
25
35
|
const chatHistories = async (histories: iAiHistory[], _aiConfig?: iAiConfiguration): Promise<{ message: string, chatData: iAiChatResponse }> => {
|
|
26
36
|
const axios = Axios.create();
|
|
27
37
|
const aiConfig = _aiConfig || getConfig();
|
|
@@ -54,6 +64,11 @@ export const $ai = (() => {
|
|
|
54
64
|
}
|
|
55
65
|
};
|
|
56
66
|
|
|
67
|
+
/**
|
|
68
|
+
* 带提示词的模型调用
|
|
69
|
+
* @author 韦胜健
|
|
70
|
+
* @date 2025/5/20 19:26
|
|
71
|
+
*/
|
|
57
72
|
const chatSystem = async (userContent: string, systemContent?: string, _aiConfig?: iAiConfiguration) => {
|
|
58
73
|
const messages = [{ "role": "user", "content": userContent }];
|
|
59
74
|
if (!!systemContent) {
|
|
@@ -62,10 +77,121 @@ export const $ai = (() => {
|
|
|
62
77
|
return chatHistories(messages, _aiConfig);
|
|
63
78
|
};
|
|
64
79
|
|
|
80
|
+
/**
|
|
81
|
+
* 基础的模型调用
|
|
82
|
+
* @author 韦胜健
|
|
83
|
+
* @date 2025/5/20 19:27
|
|
84
|
+
*/
|
|
65
85
|
const chat = async (userContent: string, _aiConfig?: iAiConfiguration): Promise<{ message: string, chatData: iAiChatResponse }> => {
|
|
66
86
|
return chatSystem(userContent, '', _aiConfig);
|
|
67
87
|
};
|
|
68
88
|
|
|
89
|
+
/**
|
|
90
|
+
* 流式调用
|
|
91
|
+
* @author 韦胜健
|
|
92
|
+
* @date 2025/5/20 19:27
|
|
93
|
+
*/
|
|
94
|
+
const chatStream = async (
|
|
95
|
+
{
|
|
96
|
+
aiConfig: _aiConfig,
|
|
97
|
+
messages,
|
|
98
|
+
onReceiving,
|
|
99
|
+
onFinish,
|
|
100
|
+
onThinking,
|
|
101
|
+
onThinkEnd,
|
|
102
|
+
onThinkStart,
|
|
103
|
+
}: {
|
|
104
|
+
aiConfig?: iAiConfiguration,
|
|
105
|
+
messages: iAiHistory[],
|
|
106
|
+
onReceiving: (data: { fullText: string, chunkText: string }) => void,
|
|
107
|
+
onFinish?: (fullText: string) => void,
|
|
108
|
+
onThinking?: (thinkText: string) => void,
|
|
109
|
+
onThinkStart?: () => void,
|
|
110
|
+
onThinkEnd?: () => void,
|
|
111
|
+
}
|
|
112
|
+
) => {
|
|
113
|
+
const aiConfig = _aiConfig ?? getConfig();
|
|
114
|
+
// 发送请求
|
|
115
|
+
const response = await fetch(aiConfig.url, {
|
|
116
|
+
method: 'POST',
|
|
117
|
+
headers: {
|
|
118
|
+
'Authorization': `Bearer ${aiConfig.key}`,
|
|
119
|
+
"Content-Type": 'application/json'
|
|
120
|
+
},
|
|
121
|
+
body: JSON.stringify({
|
|
122
|
+
"model": aiConfig.model,
|
|
123
|
+
"messages": messages,
|
|
124
|
+
// "messages": [{ role: 'user', content: '你好' }],
|
|
125
|
+
stream: true // 请求流式响应
|
|
126
|
+
})
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
if (!response.ok || !response.body) {throw response;}
|
|
130
|
+
|
|
131
|
+
// 创建一个解码器来处理UTF-8文本
|
|
132
|
+
const decoder = new TextDecoder("utf-8");
|
|
133
|
+
|
|
134
|
+
let isThinking = false;
|
|
135
|
+
let thinkText = '';
|
|
136
|
+
let fullText = '';
|
|
137
|
+
|
|
138
|
+
// 读取响应流
|
|
139
|
+
const reader = response.body.getReader();
|
|
140
|
+
let done = false;
|
|
141
|
+
|
|
142
|
+
while (!done) {
|
|
143
|
+
const { value, done: readerDone } = await reader.read();
|
|
144
|
+
done = readerDone;
|
|
145
|
+
if (done) {
|
|
146
|
+
console.log('Chat stream done...');
|
|
147
|
+
onFinish?.(fullText);
|
|
148
|
+
}
|
|
149
|
+
if (!value?.length) {
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const receiveText = (() => {
|
|
154
|
+
let text = '';
|
|
155
|
+
let chunk = decoder.decode(value, { stream: true });
|
|
156
|
+
const pattern = /data: (.*)/g;
|
|
157
|
+
let match = pattern.exec(chunk);
|
|
158
|
+
while (match) {
|
|
159
|
+
if (match[1] === '[DONE]') {
|
|
160
|
+
return text;
|
|
161
|
+
} else {
|
|
162
|
+
const obj = JSON.parse(match[1]);
|
|
163
|
+
text += obj.choices[0].delta.content ?? '';
|
|
164
|
+
}
|
|
165
|
+
match = pattern.exec(chunk);
|
|
166
|
+
}
|
|
167
|
+
return text;
|
|
168
|
+
})();
|
|
169
|
+
|
|
170
|
+
if (receiveText.slice(0, 8) === '<think>') {
|
|
171
|
+
isThinking = true;
|
|
172
|
+
// thinkText += receiveText;
|
|
173
|
+
onThinkStart?.();
|
|
174
|
+
onThinking?.(thinkText);
|
|
175
|
+
} else if (receiveText.slice(-8) === '</think>') {
|
|
176
|
+
isThinking = false;
|
|
177
|
+
// thinkText += receiveText;
|
|
178
|
+
onThinkEnd?.();
|
|
179
|
+
onThinking?.(thinkText);
|
|
180
|
+
} else {
|
|
181
|
+
|
|
182
|
+
if (isThinking) {
|
|
183
|
+
thinkText += receiveText;
|
|
184
|
+
onThinking?.(thinkText);
|
|
185
|
+
} else {
|
|
186
|
+
fullText += receiveText;
|
|
187
|
+
onReceiving({ fullText: fullText, chunkText: receiveText });
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return response;
|
|
193
|
+
};
|
|
194
|
+
|
|
69
195
|
|
|
70
196
|
/**
|
|
71
197
|
* 根据ai对话,将用户描述转化为表单数据对象,
|
|
@@ -139,6 +265,7 @@ export const $ai = (() => {
|
|
|
139
265
|
chatHistories,
|
|
140
266
|
getConfig,
|
|
141
267
|
getFormDataByChat,
|
|
268
|
+
chatStream,
|
|
142
269
|
};
|
|
143
270
|
})();
|
|
144
271
|
|