doomiaichat 7.1.29 → 7.1.30
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 +3 -2
- package/src/aimp.ts +0 -125
- package/src/azureai.ts +0 -180
- package/src/baiduai.ts +0 -86
- package/src/corzauthorization.ts +0 -59
- package/src/corzbot.ts +0 -434
- package/src/declare.ts +0 -152
- package/src/deepseek.ts +0 -11
- package/src/doubaoai.ts +0 -129
- package/src/gptbase.ts +0 -52
- package/src/gptprovider.ts +0 -74
- package/src/index.ts +0 -2
- package/src/openai.ts +0 -136
- package/src/openaibase.ts +0 -30
- package/src/openaiproxy.ts +0 -97
- package/src/stabilityai.ts +0 -67
- package/src/stabilityplusai.ts +0 -77
- package/tsconfig.json +0 -31
package/src/corzbot.ts
DELETED
|
@@ -1,434 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 扣子智能体
|
|
3
|
-
*/
|
|
4
|
-
import {
|
|
5
|
-
CozeAPI,
|
|
6
|
-
COZE_CN_BASE_URL,
|
|
7
|
-
ChatEventType,
|
|
8
|
-
RoleType,
|
|
9
|
-
StreamChatReq,
|
|
10
|
-
EnterMessage,
|
|
11
|
-
// ChatWorkflowReq,
|
|
12
|
-
// CreateChatReq,
|
|
13
|
-
// ChatStatus,
|
|
14
|
-
VariableUpdateReq,
|
|
15
|
-
VariableRetrieveReq,
|
|
16
|
-
CreateChatReq,
|
|
17
|
-
RunWorkflowReq,
|
|
18
|
-
RunWorkflowData,
|
|
19
|
-
CreateChatData,
|
|
20
|
-
ChatStatus,
|
|
21
|
-
WorkflowEventType,
|
|
22
|
-
ChatWorkflowReq
|
|
23
|
-
} from '@coze/api';
|
|
24
|
-
import GptBase from "./gptbase"
|
|
25
|
-
import { CorzAuthorization } from './corzauthorization';
|
|
26
|
-
import { parse } from 'querystring'
|
|
27
|
-
import { ApiResult } from './declare';
|
|
28
|
-
import {createWriteStream,mkdirSync} from 'fs';
|
|
29
|
-
import {resolve,join} from 'path';
|
|
30
|
-
// 定义深度思考的动作标签
|
|
31
|
-
// 这是小鹭里面专用的几个思考动作标签
|
|
32
|
-
const DeepThinkingAction: any = {
|
|
33
|
-
thinking: { start: '<xiaolu-think>', end: '</xiaolu-think>', tag: 'xiaolu-think' },
|
|
34
|
-
reasoning: { start: '<xiaolu-reason>', end: '</xiaolu-reason>', tag: 'xiaolu-reason' },
|
|
35
|
-
card: { start: '<xiaolu-card>', end: '</xiaolu-card>', tag: 'xiaolu-card' },
|
|
36
|
-
preresponse: { start: '<xiaolu-preresponse>', end: '</xiaolu-preresponse>', tag: 'xiaolu-preresponse' },
|
|
37
|
-
}
|
|
38
|
-
// 定义深度思考的状态
|
|
39
|
-
enum DeepThinkingStatus {
|
|
40
|
-
None,
|
|
41
|
-
Thinking,
|
|
42
|
-
// ContentOutput,
|
|
43
|
-
ThinkingOver
|
|
44
|
-
}
|
|
45
|
-
// 智能体思考时输出的动作
|
|
46
|
-
type CardType = { type: number, tag: string }
|
|
47
|
-
// type TThinkingMessage = { action: string, textposition: number }
|
|
48
|
-
export default class CorzBot extends GptBase {
|
|
49
|
-
private botid: string | null = null; // 智能体id
|
|
50
|
-
private workflowid: string | null = null; // 工作流id
|
|
51
|
-
private talkflowid: string | null = null; // 对话流id
|
|
52
|
-
private apiKey: string;
|
|
53
|
-
private debugDir: string = '';
|
|
54
|
-
private debug: boolean = false;
|
|
55
|
-
/**
|
|
56
|
-
*
|
|
57
|
-
* @param apikey 调用AI中台 的key
|
|
58
|
-
* @param botid 智能体信息
|
|
59
|
-
*/
|
|
60
|
-
constructor(private authorizationProvider: CorzAuthorization, private setting: any = {}) {
|
|
61
|
-
super();
|
|
62
|
-
////初始化扣子客户端
|
|
63
|
-
|
|
64
|
-
if (this.setting.workflowid)
|
|
65
|
-
this.workflowid = this.setting.workflowid;
|
|
66
|
-
else if (this.setting.talkflowid)
|
|
67
|
-
this.talkflowid = this.setting.talkflowid;
|
|
68
|
-
else if (this.setting.botid || this.setting.botID)
|
|
69
|
-
this.botid = this.setting.botid || this.setting.botID;
|
|
70
|
-
else
|
|
71
|
-
throw new Error('no botid or talkflowid or workflowid setting for coze');
|
|
72
|
-
/// 如果开启debug模式,则创建记录日志的目录,将日志输出到该目录
|
|
73
|
-
if (setting.debug === true) {
|
|
74
|
-
this.debug = true;
|
|
75
|
-
this.debugDir = join(setting.logPath || resolve(process.cwd(), './cozedebug'),this.setting.model || 'chat');
|
|
76
|
-
mkdirSync(this.debugDir!, { recursive: true });
|
|
77
|
-
}
|
|
78
|
-
this.apiKey = this.setting['apiKey'];
|
|
79
|
-
}
|
|
80
|
-
private async createClient(): Promise<CozeAPI> {
|
|
81
|
-
// 存在AppKey则使用AppKey进行认证
|
|
82
|
-
if (this.apiKey) return new CozeAPI({ baseURL: COZE_CN_BASE_URL, token: this.apiKey });
|
|
83
|
-
const accessToken = await this.authorizationProvider.getAccessToken();
|
|
84
|
-
if (!accessToken) throw new Error('get access token failed');
|
|
85
|
-
return new CozeAPI({ baseURL: COZE_CN_BASE_URL, token: accessToken });
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* 发起一次会话
|
|
89
|
-
*/
|
|
90
|
-
override async createCoversation(client?: CozeAPI): Promise<string | null> {
|
|
91
|
-
try {
|
|
92
|
-
const czApi = client ?? await this.createClient();
|
|
93
|
-
const params = this.botid ? { bot_id: this.botid } : {};
|
|
94
|
-
const result = await czApi.conversations.create(params)
|
|
95
|
-
return result.id;
|
|
96
|
-
} catch (error) {
|
|
97
|
-
console.error('createCoversation error in coze api');
|
|
98
|
-
return null;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* 设置Coze的变量
|
|
103
|
-
* @param params
|
|
104
|
-
* @returns
|
|
105
|
-
*/
|
|
106
|
-
override async setVariables(params: any = {}): Promise<ApiResult> {
|
|
107
|
-
const client = await this.createClient();
|
|
108
|
-
!params.type && (params.type='app');
|
|
109
|
-
const cozeParams: VariableUpdateReq = { data: params.data };
|
|
110
|
-
params.type === 'app' && (cozeParams.app_id = this.authorizationProvider.appid);
|
|
111
|
-
params.type === 'bot' && this.botid && (cozeParams.bot_id = this.botid);
|
|
112
|
-
params.user_id && (cozeParams.connector_uid = params.user_id);
|
|
113
|
-
//Object.assign({ connector_uid: params?.user_id||'123456' }, params.type==='app'?{app_id:this.authorizationProvider.appid}:(params.type==='bot' ? { bot_id: this.botid } : {}), params);
|
|
114
|
-
const result = await client.variables.update(cozeParams, { debug : true })
|
|
115
|
-
console.log('setVariables result', result);
|
|
116
|
-
return { successed: true };
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* 获取设置的变量
|
|
120
|
-
* @returns
|
|
121
|
-
*/
|
|
122
|
-
override async getVariables(params: any): Promise<any> {
|
|
123
|
-
const client = await this.createClient();
|
|
124
|
-
const cozeParams: VariableRetrieveReq = Object.assign({}, { bot_id: this.botid }, params);
|
|
125
|
-
const data = await client.variables.retrieve(cozeParams);
|
|
126
|
-
if (data) return { successed: true, ...data }
|
|
127
|
-
return { successed: false, error: 'get variables failed' };
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* 组装请求参数
|
|
131
|
-
* @param message
|
|
132
|
-
* @param callChatOption
|
|
133
|
-
* @param attach
|
|
134
|
-
* @param _axiosOption
|
|
135
|
-
*/
|
|
136
|
-
async getRequestStream<T>(client: CozeAPI, message: EnterMessage[], callChatOption: any = {}): Promise<T> {
|
|
137
|
-
//简单的对话请求
|
|
138
|
-
if (this.botid) {
|
|
139
|
-
const req: StreamChatReq = {
|
|
140
|
-
bot_id: this.botid,
|
|
141
|
-
additional_messages: message,
|
|
142
|
-
user_id: callChatOption.userid || callChatOption.cozeUserID,
|
|
143
|
-
conversation_id: callChatOption.session_id ?? await this.createCoversation(client),
|
|
144
|
-
parameters: Object.assign({ request_src: 1 }, callChatOption.parameters || {}),
|
|
145
|
-
}
|
|
146
|
-
req.custom_variables = Object.assign({}, this.setting.customVariables || {}, callChatOption.customVariables || {});
|
|
147
|
-
return req as T;
|
|
148
|
-
}
|
|
149
|
-
if (this.workflowid) {
|
|
150
|
-
const worflowreq: RunWorkflowReq = {
|
|
151
|
-
ext: callChatOption.ext,
|
|
152
|
-
workflow_id: this.workflowid,//callChatOption.workflowid,
|
|
153
|
-
is_async: false,
|
|
154
|
-
// parameters: Object.assign({ input: message[0]?.content }, this.setting.customVariables || {}, callChatOption.customVariables || {}),
|
|
155
|
-
// parameters: Object.assign({ request_src: 1 }, callChatOption.parameters || {}, { input: message[0]?.content })
|
|
156
|
-
parameters: Object.assign({ request_src: 1 }, callChatOption.parameters || {}, { input: message})
|
|
157
|
-
}
|
|
158
|
-
if (callChatOption.userid || callChatOption.cozeUserID) worflowreq.ext = Object.assign({}, worflowreq.ext || {}, { user_id: callChatOption.userid || callChatOption.cozeUserID });
|
|
159
|
-
return worflowreq as T;
|
|
160
|
-
}
|
|
161
|
-
const worflowreq: ChatWorkflowReq = {
|
|
162
|
-
additional_messages: message,
|
|
163
|
-
ext: {user_id:'12345678'},
|
|
164
|
-
workflow_id: this.talkflowid!,//callChatOption.workflowid,
|
|
165
|
-
conversation_id: callChatOption.session_id ?? await this.createCoversation(client),
|
|
166
|
-
parameters: Object.assign({ request_src: 1 }, callChatOption.parameters || {}) //Object.assign({}, this.setting.customVariables || {}, callChatOption.customVariables || {}),
|
|
167
|
-
}
|
|
168
|
-
if (callChatOption.userid || callChatOption.cozeUserID) worflowreq.ext = Object.assign({}, worflowreq.ext||{}, { user_id: callChatOption.userid || callChatOption.cozeUserID });
|
|
169
|
-
return worflowreq as T;
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* 同步调用的问答请求需要获取会话详情
|
|
173
|
-
* @param chatid
|
|
174
|
-
* @param conversation_id
|
|
175
|
-
*/
|
|
176
|
-
private async getChatDetail(client: CozeAPI, conversation_id: string, chatid: string) {
|
|
177
|
-
const maxWaitTime = 120000; // 最大等待120秒
|
|
178
|
-
const startTime = Date.now();
|
|
179
|
-
while ((Date.now() - startTime) < maxWaitTime) {
|
|
180
|
-
const chatinfo = await client.chat.retrieve(conversation_id, chatid);
|
|
181
|
-
// 状态已经是完成了,可以去获取对话的内容了
|
|
182
|
-
if (chatinfo.status === ChatStatus.COMPLETED) return { usage: chatinfo.usage, messages: await client.chat.messages.list(conversation_id, chatid) };
|
|
183
|
-
await new Promise(resolve => setTimeout(resolve, 1500)); // 等待1500ms
|
|
184
|
-
}
|
|
185
|
-
return null;
|
|
186
|
-
}
|
|
187
|
-
/**
|
|
188
|
-
* 非流式传输聊天请求
|
|
189
|
-
* @param chatText
|
|
190
|
-
* @param callChatOption
|
|
191
|
-
* @param _axiosOption
|
|
192
|
-
*/
|
|
193
|
-
public async chatRequest(message: any[] | string, callChatOption: any = {}, _axiosOption: any = {}): Promise<any> {
|
|
194
|
-
if (!message) this.emit('chaterror', { successed: false, error: 'no message in chat' });
|
|
195
|
-
///如果是字符,则组装成API需要的消息
|
|
196
|
-
if (typeof message === 'string') message = [
|
|
197
|
-
{
|
|
198
|
-
role: RoleType.User,
|
|
199
|
-
content_type: 'text',
|
|
200
|
-
content: message
|
|
201
|
-
}
|
|
202
|
-
];
|
|
203
|
-
const client = await this.createClient();
|
|
204
|
-
const debugStream = this.debug ? createWriteStream(join(this.debugDir, `sync_${this.formatDateWithMs()}.log`), { flags: 'a' }) : null;
|
|
205
|
-
////如果参数中用的是Workflow,则调用对话流来输出结果
|
|
206
|
-
////否则用智能体的对话来输出结果
|
|
207
|
-
const params = await this.getRequestStream(client, message, callChatOption);
|
|
208
|
-
if (debugStream) {
|
|
209
|
-
debugStream.write(`callChatOption:${JSON.stringify(callChatOption)}\n`);
|
|
210
|
-
debugStream.write(`parameters:${JSON.stringify(params)}\n`);
|
|
211
|
-
}
|
|
212
|
-
const response = this.botid ? await client.chat.create(params as CreateChatReq) : await client.workflows.runs.create(params as RunWorkflowReq);
|
|
213
|
-
if (this.workflowid) {
|
|
214
|
-
const workflowResp = response as RunWorkflowData;
|
|
215
|
-
if (workflowResp.msg === 'Success' || (!workflowResp.msg && workflowResp.data)){
|
|
216
|
-
const resp = workflowResp.data;
|
|
217
|
-
debugStream && debugStream.end(resp);
|
|
218
|
-
return { successed: true, message: [{ role: 'assistant', type: 'answer', content: resp }] };
|
|
219
|
-
}
|
|
220
|
-
debugStream && debugStream.end('workflow run failed');
|
|
221
|
-
console.error('workflow run failed', workflowResp.msg, workflowResp)
|
|
222
|
-
}
|
|
223
|
-
if (!this.workflowid && (response as CreateChatData).conversation_id && (response as CreateChatData).id) {
|
|
224
|
-
const ccd = response as CreateChatData;
|
|
225
|
-
const chatData = await this.getChatDetail(client, ccd.conversation_id, ccd.id);
|
|
226
|
-
if (chatData) {
|
|
227
|
-
const message = chatData.messages.filter(x => x.type === 'answer').map(item => ({
|
|
228
|
-
role: item.role,
|
|
229
|
-
type: item.type,
|
|
230
|
-
content: item.content,
|
|
231
|
-
}));
|
|
232
|
-
return { successed: true, message, usage: chatData.usage, session_id: ccd.conversation_id };
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
debugStream && debugStream.end('聊天未完成');
|
|
236
|
-
return { successed: false, error: { message: '聊天未完成' } };
|
|
237
|
-
|
|
238
|
-
}
|
|
239
|
-
/**
|
|
240
|
-
* 提取XML标签中间的内容,
|
|
241
|
-
* @param xmlStr
|
|
242
|
-
* @param tagName
|
|
243
|
-
* @returns
|
|
244
|
-
*/
|
|
245
|
-
extractXmlContent(xmlStr: string, tagName: string): string {
|
|
246
|
-
// 构建匹配标签的正则(支持任意空白字符和大小写)
|
|
247
|
-
const regex = new RegExp(`<\\s*${tagName}\\s*>([\\s\\S]*?)<\\s*\\/\\s*${tagName}\\s*>`, 'i');
|
|
248
|
-
const match = xmlStr.match(regex);
|
|
249
|
-
if (match && match[1]) return match[1].trim();
|
|
250
|
-
return ''; // 未找到标签或内容
|
|
251
|
-
}
|
|
252
|
-
/**
|
|
253
|
-
* 解析深度思考的JSON内容
|
|
254
|
-
* @param content
|
|
255
|
-
* @param status
|
|
256
|
-
* @returns
|
|
257
|
-
*/
|
|
258
|
-
private parseDeepThinkingJson(content: string) {
|
|
259
|
-
// const thinkingStartIndex = status === DeepThinkingStatus.Thinking ? content.indexOf("{\"process_msg") :
|
|
260
|
-
// (status===DeepThinkingStatus.ReasonOutput ? content.indexOf("{\"reasoning_content") : content.indexOf("{\"card_resource")) ;
|
|
261
|
-
const xmlTagLocation = [content.indexOf(DeepThinkingAction.thinking.start),
|
|
262
|
-
content.indexOf(DeepThinkingAction.reasoning.start),
|
|
263
|
-
content.indexOf(DeepThinkingAction.card.start),
|
|
264
|
-
content.indexOf(DeepThinkingAction.preresponse.start)];
|
|
265
|
-
let minLocation = 10000, minIndex = -1;
|
|
266
|
-
// 找到最小的并且大于0 的位置的下标
|
|
267
|
-
xmlTagLocation.forEach((x, index) => {
|
|
268
|
-
if (x >= 0 && x < minLocation) {
|
|
269
|
-
minLocation = x;
|
|
270
|
-
minIndex = index;
|
|
271
|
-
}
|
|
272
|
-
});
|
|
273
|
-
// const tagLocation = xmlTagLocation.filter(x => x >= 0);
|
|
274
|
-
const thinkingStartIndex = minIndex >= 0 ? minLocation : -1; //tagLocation.length > 0 ? Math.min(...tagLocation) : -1;
|
|
275
|
-
if (thinkingStartIndex < 0) return { content, status: DeepThinkingStatus.ThinkingOver };
|
|
276
|
-
const currentAction = [DeepThinkingAction.thinking, DeepThinkingAction.reasoning, DeepThinkingAction.card, DeepThinkingAction.preresponse][minIndex];
|
|
277
|
-
const currentActionIsOver = content.indexOf(currentAction.end, thinkingStartIndex);
|
|
278
|
-
const thinkingEndIndex = currentActionIsOver >= 0 ? currentActionIsOver : content.indexOf('</', thinkingStartIndex);
|
|
279
|
-
const thinkingContent = this.extractXmlContent(content.substring(thinkingStartIndex, thinkingEndIndex >= 0 ? thinkingEndIndex : undefined) + currentAction.end, currentAction.tag); //"\"}";
|
|
280
|
-
if (currentActionIsOver >= 0) content = content.substring(currentActionIsOver + currentAction.end.length);
|
|
281
|
-
return {
|
|
282
|
-
thinking: {
|
|
283
|
-
action: currentAction,
|
|
284
|
-
text: thinkingContent,//Object.values(thinkingObject)[0]
|
|
285
|
-
completed: currentActionIsOver >= 0
|
|
286
|
-
}, content
|
|
287
|
-
};
|
|
288
|
-
|
|
289
|
-
}
|
|
290
|
-
/**
|
|
291
|
-
*
|
|
292
|
-
* @param date
|
|
293
|
-
* @returns
|
|
294
|
-
*/
|
|
295
|
-
private formatDateWithMs(date = new Date()) {
|
|
296
|
-
// 获取各时间部分
|
|
297
|
-
const year = date.getFullYear(); // 年(4位)
|
|
298
|
-
const month = String(date.getMonth() + 1).padStart(2, '0'); // 月(补0,2位)
|
|
299
|
-
const day = String(date.getDate()).padStart(2, '0'); // 日(补0,2位)
|
|
300
|
-
const hours = String(date.getHours()).padStart(2, '0'); // 时(补0,2位)
|
|
301
|
-
const minutes = String(date.getMinutes()).padStart(2, '0'); // 分(补0,2位)
|
|
302
|
-
const seconds = String(date.getSeconds()).padStart(2, '0'); // 秒(补0,2位)
|
|
303
|
-
const milliseconds = String(date.getMilliseconds()).padStart(3, '0'); // 毫秒(补0,3位)
|
|
304
|
-
|
|
305
|
-
// 拼接成 yyyymmddhhmmssSSS 格式
|
|
306
|
-
return `${year}${month}${day}${hours}${minutes}${seconds}${milliseconds}`;
|
|
307
|
-
}
|
|
308
|
-
/**
|
|
309
|
-
* 流式传输聊天请求
|
|
310
|
-
* @param chatText
|
|
311
|
-
* @param callChatOption
|
|
312
|
-
* @param attach
|
|
313
|
-
* @param _axiosOption
|
|
314
|
-
* @returns
|
|
315
|
-
*/
|
|
316
|
-
override async chatRequestInStream(message: any[] | string, callChatOption: any = {}, attach?: any, _axiosOption?: any): Promise<any> {
|
|
317
|
-
if (!message) this.emit('chaterror', { successed: false, error: 'no message in chat' });
|
|
318
|
-
///如果是字符,则组装成API需要的消息
|
|
319
|
-
if (typeof message === 'string') message = [
|
|
320
|
-
{
|
|
321
|
-
role: RoleType.User,
|
|
322
|
-
content_type: 'text',
|
|
323
|
-
content: message
|
|
324
|
-
}
|
|
325
|
-
];
|
|
326
|
-
const client = await this.createClient();
|
|
327
|
-
////如果参数中用的是Workflow,则调用对话流来输出结果
|
|
328
|
-
////否则用智能体的对话来输出结果
|
|
329
|
-
let requestid = Math.ceil(Math.random() * (new Date().getTime() * Math.random()) / 1000), index = 0;
|
|
330
|
-
const debugStream = this.debug ? createWriteStream(join(this.debugDir, `${this.formatDateWithMs()}.log`), { flags: 'a' }) : null;
|
|
331
|
-
const params = await this.getRequestStream(client, message, callChatOption);
|
|
332
|
-
if (debugStream) {
|
|
333
|
-
debugStream.write(`callChatOption:${JSON.stringify(callChatOption)}\n`);
|
|
334
|
-
debugStream.write(`attach:${attach ? JSON.stringify(attach) : 'null'}\n`);
|
|
335
|
-
debugStream.write(`parameters:${JSON.stringify(params)}\n`);
|
|
336
|
-
}
|
|
337
|
-
const stream = this.botid ? client.chat.stream(params as StreamChatReq) :
|
|
338
|
-
(this.workflowid ? client.workflows.runs.stream(params as RunWorkflowReq) :
|
|
339
|
-
client.workflows.chat.stream(params as ChatWorkflowReq));
|
|
340
|
-
let deltaindex = 0, fullanswer: string[] = [],cardfollowup: string[] = [], followup: string[] = [], cardData: CardType[] = [];
|
|
341
|
-
let deepThinking = '', thinkingStatus = DeepThinkingStatus.None, cardResource = '', preresponseText=''; // 是否在深度思考中
|
|
342
|
-
for await (const part of stream) {
|
|
343
|
-
if (part.event === ChatEventType.ERROR) {
|
|
344
|
-
if (debugStream) debugStream.write('chat error:');
|
|
345
|
-
return this.emit('chaterror', { successed: false, error: 'call failed' });
|
|
346
|
-
}
|
|
347
|
-
if (part.event === ChatEventType.CONVERSATION_MESSAGE_DELTA ||
|
|
348
|
-
part.event === WorkflowEventType.MESSAGE
|
|
349
|
-
) {
|
|
350
|
-
let { conversation_id, content_type, type = 'answer', role = 'assistant', content, reasoning_content: reasoning } = part.data as any;
|
|
351
|
-
if (debugStream) debugStream.write(content);
|
|
352
|
-
if (content === 'Default') continue;
|
|
353
|
-
if (!content && reasoning) {
|
|
354
|
-
this.emit('chatthinking', { text: reasoning, completed: false, action: 'deep-thinking' });
|
|
355
|
-
continue;
|
|
356
|
-
}
|
|
357
|
-
// 如果存在深度思考,则一开始就会带有相关的关键信息
|
|
358
|
-
if (deltaindex === 0 && content.startsWith("<xiaolu-")) {
|
|
359
|
-
thinkingStatus = DeepThinkingStatus.Thinking;
|
|
360
|
-
deltaindex++;
|
|
361
|
-
}
|
|
362
|
-
// 如果在深度思考中,则不输出消息
|
|
363
|
-
if (thinkingStatus === DeepThinkingStatus.Thinking) {
|
|
364
|
-
deepThinking += content;
|
|
365
|
-
const result = this.parseDeepThinkingJson(deepThinking)
|
|
366
|
-
const thinking = result.thinking;
|
|
367
|
-
if (thinking) {
|
|
368
|
-
deepThinking = result.content;
|
|
369
|
-
if (thinking.action === DeepThinkingAction.card) {
|
|
370
|
-
cardResource += result.thinking.text;
|
|
371
|
-
// 卡片流结束,解析卡片资源数据
|
|
372
|
-
if (result.thinking.completed) {
|
|
373
|
-
const allCards = cardResource.replace(/[\x00-\x1F\x7F]/g, '').split('|')
|
|
374
|
-
cardResource='';
|
|
375
|
-
for (const item of allCards) {
|
|
376
|
-
const cardinfo: any = parse(item);
|
|
377
|
-
if (cardinfo.type && cardinfo.tag) {
|
|
378
|
-
if (cardinfo.type === 'follow_up')
|
|
379
|
-
cardfollowup.push(cardinfo.tag);
|
|
380
|
-
else{
|
|
381
|
-
const tags = cardinfo.tag.split(',');
|
|
382
|
-
for (const tag of tags) cardData.push({ type: cardinfo.type, tag })
|
|
383
|
-
//cardData.push({ ...cardinfo })
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
// 将卡片资源返回给客户端
|
|
388
|
-
this.emit('chatcard', cardData);
|
|
389
|
-
}
|
|
390
|
-
} else if(thinking.action === DeepThinkingAction.preresponse){
|
|
391
|
-
/// 当正文一样输出
|
|
392
|
-
const spiltPreresponse = result.thinking.text.slice(preresponseText.length)
|
|
393
|
-
preresponseText = result.thinking.text;
|
|
394
|
-
fullanswer.push(spiltPreresponse);// = [result.thinking.text];// .push(result.thinking.text);
|
|
395
|
-
let output = { successed: true, type, content_type, role, requestid, segment: spiltPreresponse, text: fullanswer.join(''), index: index++, session_id: conversation_id, preresponse: true, preresponseover: result.thinking.completed };
|
|
396
|
-
if (attach) output = Object.assign({}, output, attach);
|
|
397
|
-
this.emit('chattext', output)
|
|
398
|
-
}
|
|
399
|
-
else {
|
|
400
|
-
this.emit('chatthinking', { text: result.thinking.text, completed: result.thinking.completed, action: thinking.action?.tag });
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
if (result.status != DeepThinkingStatus.ThinkingOver) continue;
|
|
404
|
-
thinkingStatus = DeepThinkingStatus.ThinkingOver;
|
|
405
|
-
// 将排除了thinking之后的消息内容要带下去成为正式的输出内容
|
|
406
|
-
content = deepThinking;
|
|
407
|
-
}
|
|
408
|
-
fullanswer.push(content);
|
|
409
|
-
let output = { successed: true, type, content_type, role, requestid, segment: content, text: fullanswer.join(''), index: index++, session_id: conversation_id };
|
|
410
|
-
if (attach) output = Object.assign({}, output, attach);
|
|
411
|
-
this.emit('chattext', output)
|
|
412
|
-
}
|
|
413
|
-
////在流式传输中,提取相关推荐问题
|
|
414
|
-
if (part.event === ChatEventType.CONVERSATION_MESSAGE_COMPLETED) {
|
|
415
|
-
const { type, content } = part.data ?? {};
|
|
416
|
-
if (type === 'follow_up') {
|
|
417
|
-
if (debugStream) debugStream.write('followup:' + content);
|
|
418
|
-
followup.push(content);
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
///整个对话结束
|
|
422
|
-
if (part.event === ChatEventType.CONVERSATION_CHAT_COMPLETED ||
|
|
423
|
-
part.event === WorkflowEventType.DONE
|
|
424
|
-
) {
|
|
425
|
-
const { conversation_id, content } = (part.data) ?? {} as any;
|
|
426
|
-
let output = { successed: true, cards: cardData.length ? cardData : null, cardfollowup: cardfollowup.filter(x=>typeof x === 'string' && x.length > 0), followup, type: 'answer', content_type: 'text', role: RoleType.Assistant, requestid, segment: null, text: content ?? fullanswer.join(''), index: index++, session_id: conversation_id };
|
|
427
|
-
if (attach) output = Object.assign({}, output, attach);
|
|
428
|
-
if (debugStream) debugStream.end('chat completed');
|
|
429
|
-
this.emit('chatdone', output)
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
return { successed: true, requestid }
|
|
433
|
-
}
|
|
434
|
-
}
|
package/src/declare.ts
DELETED
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { EmbeddingItem } from '@azure/openai';
|
|
3
|
-
import axios from 'axios';
|
|
4
|
-
|
|
5
|
-
export interface ApiResult {
|
|
6
|
-
/**
|
|
7
|
-
* return the result of api called
|
|
8
|
-
* @type {boolean}
|
|
9
|
-
*/
|
|
10
|
-
'successed': boolean
|
|
11
|
-
/**
|
|
12
|
-
* The error info
|
|
13
|
-
* @type {any}
|
|
14
|
-
* @memberof ChatReponse
|
|
15
|
-
*/
|
|
16
|
-
'error'?: any;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Api封装后的返回结果
|
|
20
|
-
*/
|
|
21
|
-
export interface ChatReponse extends ApiResult {
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* The name of the user in a multi-user chat
|
|
25
|
-
* @type {Array<any>}
|
|
26
|
-
* @memberof ChatReponse
|
|
27
|
-
*/
|
|
28
|
-
'message'?: Array<any>;
|
|
29
|
-
'usage'?: any;
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* 调用OpenAI Api的参数约定
|
|
33
|
-
*/
|
|
34
|
-
export interface OpenAIApiParameters {
|
|
35
|
-
'embedding'?: string, ///模型引擎,兼容Azure
|
|
36
|
-
'model'?: string, ///模型名称
|
|
37
|
-
'maxtoken'?: number; ///返回的最大token
|
|
38
|
-
'temperature'?: number;
|
|
39
|
-
'top_p'?: number;
|
|
40
|
-
'presence_penalty'?: number;
|
|
41
|
-
'frequency_penalty'?: number;
|
|
42
|
-
'replyCounts'?: number; ///返回多少答案
|
|
43
|
-
'tools'?: Array<any>,
|
|
44
|
-
'tool_choice'?: string,
|
|
45
|
-
'enableToolCall'?: number ///是否允许调用toolfunction
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Azure 上的OpenAI的链接参数
|
|
49
|
-
*/
|
|
50
|
-
export interface ProxyPatameters {
|
|
51
|
-
'serviceurl': string; ///端点
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* OpenAI Proxy 链接参数
|
|
56
|
-
*/
|
|
57
|
-
export interface AzureOpenAIPatameters {
|
|
58
|
-
'endpoint': string; ///端点
|
|
59
|
-
'engine': string; ///GPT部署的项目名称
|
|
60
|
-
'embedding'?: string; ///向量引擎项目名称
|
|
61
|
-
'version'?: string; ///Api 版本
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* 调用OpenAI Api的向量约定
|
|
66
|
-
*/
|
|
67
|
-
export interface EmbeddingResult extends ApiResult {
|
|
68
|
-
'embedding'?: EmbeddingItem[],
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* 远程请求的返回
|
|
72
|
-
*/
|
|
73
|
-
export interface RpcResult extends ApiResult {
|
|
74
|
-
'data'?: any;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Axios远程请求封装
|
|
79
|
-
* @param opts
|
|
80
|
-
* @returns
|
|
81
|
-
*/
|
|
82
|
-
export async function request(opts: any = {}): Promise<RpcResult> {
|
|
83
|
-
if (!opts.data) opts.data = opts.body;
|
|
84
|
-
try {
|
|
85
|
-
let result = await axios(opts);
|
|
86
|
-
return { successed: true, data: result.data }
|
|
87
|
-
} catch (err) {
|
|
88
|
-
return { successed: false, error: err, data: err }
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
*
|
|
93
|
-
* @param opts
|
|
94
|
-
* @returns
|
|
95
|
-
*/
|
|
96
|
-
export function requestStream(opts: any = {},processChunkData:Function) {
|
|
97
|
-
if (!opts.data) opts.data = opts.body;
|
|
98
|
-
axios(opts)
|
|
99
|
-
.then((res: any) => {
|
|
100
|
-
res.data.on('data', (chunk: any) => {
|
|
101
|
-
processChunkData(chunk);
|
|
102
|
-
});
|
|
103
|
-
})
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* 数据缓存提供者接口
|
|
109
|
-
*/
|
|
110
|
-
export interface CacheProvider {
|
|
111
|
-
/**
|
|
112
|
-
* 缓存数据
|
|
113
|
-
* @param key 数据的键名称
|
|
114
|
-
* @param value 数据的键值
|
|
115
|
-
*/
|
|
116
|
-
set(key: string, value: string | object, exp?: number): void;
|
|
117
|
-
/**
|
|
118
|
-
* 从缓存中读取数据
|
|
119
|
-
* @param key 数据的键名称
|
|
120
|
-
*/
|
|
121
|
-
get(key: string): Promise<string | null>;
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* 删除缓存信息
|
|
126
|
-
* @param key 数据的键名称
|
|
127
|
-
*/
|
|
128
|
-
delete(key: string): void;
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
export interface StabilityOption {
|
|
134
|
-
'cfg_scale'?: number,
|
|
135
|
-
'clip_guidance_preset'?: string,
|
|
136
|
-
'height'?: number,
|
|
137
|
-
'width'?: number,
|
|
138
|
-
'samples'?: number,
|
|
139
|
-
'seed'?: number,
|
|
140
|
-
'steps'?: number,
|
|
141
|
-
'sampler'?: string,
|
|
142
|
-
'negative'?: string,
|
|
143
|
-
'engine'?: string,
|
|
144
|
-
'endpoint'?: string
|
|
145
|
-
'denoising_strength'?: number,
|
|
146
|
-
'hr_scale'?: number
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
export interface StabilityResult extends ApiResult {
|
|
150
|
-
'data'?: any;
|
|
151
|
-
'type'?: string;
|
|
152
|
-
}
|
package/src/deepseek.ts
DELETED