doomiaichat 7.1.9 → 7.1.11
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/dist/corzbot.d.ts +15 -3
- package/dist/corzbot.js +128 -110
- package/package.json +1 -1
- package/src/corzbot.ts +129 -115
package/dist/corzbot.d.ts
CHANGED
|
@@ -8,10 +8,10 @@ import { ApiResult } from './declare';
|
|
|
8
8
|
export default class CorzBot extends GptBase {
|
|
9
9
|
private authorizationProvider;
|
|
10
10
|
private setting;
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
private botid;
|
|
12
|
+
private workflowid;
|
|
13
|
+
private talkflowid;
|
|
13
14
|
private apiKey;
|
|
14
|
-
private lastThinkingMessage;
|
|
15
15
|
/**
|
|
16
16
|
*
|
|
17
17
|
* @param apikey 调用AI中台 的key
|
|
@@ -23,6 +23,11 @@ export default class CorzBot extends GptBase {
|
|
|
23
23
|
* 发起一次会话
|
|
24
24
|
*/
|
|
25
25
|
createCoversation(client?: CozeAPI): Promise<string | null>;
|
|
26
|
+
/**
|
|
27
|
+
* 设置Coze的变量
|
|
28
|
+
* @param params
|
|
29
|
+
* @returns
|
|
30
|
+
*/
|
|
26
31
|
setVariables(params: any): Promise<ApiResult>;
|
|
27
32
|
/**
|
|
28
33
|
* 获取设置的变量
|
|
@@ -50,6 +55,13 @@ export default class CorzBot extends GptBase {
|
|
|
50
55
|
* @param _axiosOption
|
|
51
56
|
*/
|
|
52
57
|
chatRequest(message: any[] | string, callChatOption?: any, _axiosOption?: any): Promise<any>;
|
|
58
|
+
/**
|
|
59
|
+
* 提取XML标签中间的内容,
|
|
60
|
+
* @param xmlStr
|
|
61
|
+
* @param tagName
|
|
62
|
+
* @returns
|
|
63
|
+
*/
|
|
64
|
+
extractXmlContent(xmlStr: string, tagName: string): string;
|
|
53
65
|
/**
|
|
54
66
|
* 解析深度思考的JSON内容
|
|
55
67
|
* @param content
|
package/dist/corzbot.js
CHANGED
|
@@ -25,23 +25,23 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
25
25
|
const api_1 = require("@coze/api");
|
|
26
26
|
const gptbase_1 = __importDefault(require("./gptbase"));
|
|
27
27
|
const querystring_1 = require("querystring");
|
|
28
|
-
//
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
28
|
+
// 定义深度思考的动作标签
|
|
29
|
+
// 这是小鹭里面专用的几个思考动作标签
|
|
30
|
+
const DeepThinkingAction = {
|
|
31
|
+
thinking: { start: '<xiaolu-think>', end: '</xiaolu-think>', tag: 'xiaolu-think' },
|
|
32
|
+
reasoning: { start: '<xiaolu-reason>', end: '</xiaolu-reason>', tag: 'xiaolu-reason' },
|
|
33
|
+
card: { start: '<xiaolu-card>', end: '</xiaolu-card>', tag: 'xiaolu-card' },
|
|
34
|
+
};
|
|
35
35
|
// 定义深度思考的状态
|
|
36
36
|
var DeepThinkingStatus;
|
|
37
37
|
(function (DeepThinkingStatus) {
|
|
38
38
|
DeepThinkingStatus[DeepThinkingStatus["None"] = 0] = "None";
|
|
39
39
|
DeepThinkingStatus[DeepThinkingStatus["Thinking"] = 1] = "Thinking";
|
|
40
|
-
|
|
41
|
-
DeepThinkingStatus[DeepThinkingStatus["ThinkingOver"] =
|
|
40
|
+
// ContentOutput,
|
|
41
|
+
DeepThinkingStatus[DeepThinkingStatus["ThinkingOver"] = 2] = "ThinkingOver";
|
|
42
42
|
})(DeepThinkingStatus || (DeepThinkingStatus = {}));
|
|
43
|
+
// type TThinkingMessage = { action: string, textposition: number }
|
|
43
44
|
class CorzBot extends gptbase_1.default {
|
|
44
|
-
// protected client: CozeAPI;
|
|
45
45
|
/**
|
|
46
46
|
*
|
|
47
47
|
* @param apikey 调用AI中台 的key
|
|
@@ -51,10 +51,18 @@ class CorzBot extends gptbase_1.default {
|
|
|
51
51
|
super();
|
|
52
52
|
this.authorizationProvider = authorizationProvider;
|
|
53
53
|
this.setting = setting;
|
|
54
|
-
this.
|
|
54
|
+
this.botid = null; // 智能体id
|
|
55
|
+
this.workflowid = null; // 工作流id
|
|
56
|
+
this.talkflowid = null; // 对话流id
|
|
55
57
|
////初始化扣子客户端
|
|
56
|
-
|
|
57
|
-
|
|
58
|
+
if (this.setting.workflowid)
|
|
59
|
+
this.workflowid = this.setting.workflowid;
|
|
60
|
+
else if (this.setting.talkflowid)
|
|
61
|
+
this.talkflowid = this.setting.talkflowid;
|
|
62
|
+
else if (this.setting.botid || this.setting.botID)
|
|
63
|
+
this.botid = this.setting.botid || this.setting.botID;
|
|
64
|
+
else
|
|
65
|
+
throw new Error('no botid or talkflowid or workflowid setting for coze');
|
|
58
66
|
this.apiKey = this.setting['apiKey'];
|
|
59
67
|
}
|
|
60
68
|
createClient() {
|
|
@@ -85,6 +93,11 @@ class CorzBot extends gptbase_1.default {
|
|
|
85
93
|
}
|
|
86
94
|
});
|
|
87
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* 设置Coze的变量
|
|
98
|
+
* @param params
|
|
99
|
+
* @returns
|
|
100
|
+
*/
|
|
88
101
|
setVariables(params) {
|
|
89
102
|
return __awaiter(this, void 0, void 0, function* () {
|
|
90
103
|
const client = yield this.createClient();
|
|
@@ -115,27 +128,38 @@ class CorzBot extends gptbase_1.default {
|
|
|
115
128
|
* @param _axiosOption
|
|
116
129
|
*/
|
|
117
130
|
getRequestStream(client, message, callChatOption = {}) {
|
|
118
|
-
var _a;
|
|
131
|
+
var _a, _b;
|
|
119
132
|
return __awaiter(this, void 0, void 0, function* () {
|
|
120
133
|
//简单的对话请求
|
|
121
134
|
const conversation_id = (_a = callChatOption.session_id) !== null && _a !== void 0 ? _a : yield this.createCoversation(client);
|
|
122
|
-
if (
|
|
135
|
+
if (this.botid) {
|
|
123
136
|
const req = {
|
|
124
137
|
bot_id: this.botid,
|
|
125
138
|
additional_messages: message,
|
|
126
139
|
user_id: callChatOption.userid || callChatOption.cozeUserID,
|
|
127
|
-
conversation_id
|
|
140
|
+
conversation_id,
|
|
141
|
+
parameters: Object.assign({ request_src: 1 }, callChatOption.parameters || {}),
|
|
128
142
|
};
|
|
129
143
|
req.custom_variables = Object.assign({}, this.setting.customVariables || {}, callChatOption.customVariables || {});
|
|
130
144
|
return req;
|
|
131
145
|
}
|
|
146
|
+
if (this.workflowid) {
|
|
147
|
+
const worflowreq = {
|
|
148
|
+
ext: callChatOption.ext,
|
|
149
|
+
workflow_id: this.workflowid,
|
|
150
|
+
is_async: false,
|
|
151
|
+
// parameters: Object.assign({ input: message[0]?.content }, this.setting.customVariables || {}, callChatOption.customVariables || {}),
|
|
152
|
+
parameters: Object.assign({ request_src: 1 }, callChatOption.parameters || {}, { input: (_b = message[0]) === null || _b === void 0 ? void 0 : _b.content })
|
|
153
|
+
};
|
|
154
|
+
return worflowreq;
|
|
155
|
+
}
|
|
132
156
|
const worflowreq = {
|
|
133
|
-
bot_id: this.botid,
|
|
134
157
|
additional_messages: message,
|
|
135
158
|
ext: callChatOption.ext,
|
|
136
|
-
workflow_id: this.
|
|
159
|
+
workflow_id: this.talkflowid,
|
|
137
160
|
conversation_id,
|
|
138
|
-
parameters: Object.assign({}, this.setting.customVariables || {}, callChatOption.customVariables || {}),
|
|
161
|
+
parameters: Object.assign({ request_src: 1 }, callChatOption.parameters || {}) //Object.assign({}, this.setting.customVariables || {}, callChatOption.customVariables || {}),
|
|
162
|
+
//parameters: { input: message[0]?.content }
|
|
139
163
|
};
|
|
140
164
|
return worflowreq;
|
|
141
165
|
});
|
|
@@ -182,7 +206,7 @@ class CorzBot extends gptbase_1.default {
|
|
|
182
206
|
////如果参数中用的是Workflow,则调用对话流来输出结果
|
|
183
207
|
////否则用智能体的对话来输出结果
|
|
184
208
|
const params = yield this.getRequestStream(client, message, callChatOption);
|
|
185
|
-
const response =
|
|
209
|
+
const response = this.botid ? yield client.chat.create(params) : yield client.workflows.runs.create(params);
|
|
186
210
|
if (this.workflowid && response.msg === 'Success') {
|
|
187
211
|
const resp = response.data;
|
|
188
212
|
try {
|
|
@@ -207,68 +231,57 @@ class CorzBot extends gptbase_1.default {
|
|
|
207
231
|
return { successed: false, error: { message: '聊天未完成' } };
|
|
208
232
|
});
|
|
209
233
|
}
|
|
234
|
+
/**
|
|
235
|
+
* 提取XML标签中间的内容,
|
|
236
|
+
* @param xmlStr
|
|
237
|
+
* @param tagName
|
|
238
|
+
* @returns
|
|
239
|
+
*/
|
|
240
|
+
extractXmlContent(xmlStr, tagName) {
|
|
241
|
+
// 构建匹配标签的正则(支持任意空白字符和大小写)
|
|
242
|
+
const regex = new RegExp(`<\\s*${tagName}\\s*>([\\s\\S]*?)<\\s*\\/\\s*${tagName}\\s*>`, 'i');
|
|
243
|
+
const match = xmlStr.match(regex);
|
|
244
|
+
if (match && match[1])
|
|
245
|
+
return match[1].trim();
|
|
246
|
+
return ''; // 未找到标签或内容
|
|
247
|
+
}
|
|
210
248
|
/**
|
|
211
249
|
* 解析深度思考的JSON内容
|
|
212
250
|
* @param content
|
|
213
251
|
* @param status
|
|
214
252
|
* @returns
|
|
215
253
|
*/
|
|
216
|
-
parseDeepThinkingJson(content
|
|
254
|
+
parseDeepThinkingJson(content) {
|
|
217
255
|
// const thinkingStartIndex = status === DeepThinkingStatus.Thinking ? content.indexOf("{\"process_msg") :
|
|
218
256
|
// (status===DeepThinkingStatus.ReasonOutput ? content.indexOf("{\"reasoning_content") : content.indexOf("{\"card_resource")) ;
|
|
219
|
-
const
|
|
220
|
-
content.indexOf(
|
|
221
|
-
content.indexOf(
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
try {
|
|
229
|
-
jsonStr = content.substring(thinkingStartIndex, thinkingEndIndex >= 0 ? thinkingEndIndex : undefined) + "\"}";
|
|
230
|
-
// 转换JSON的时候需要将非法字符过滤掉
|
|
231
|
-
const thinkingObject = JSON.parse(jsonStr.replace(/[\x00-\x1F\x7F]/g, ''));
|
|
232
|
-
const thinkingAction = Object.keys(thinkingObject)[0];
|
|
233
|
-
// 需要将内容的原文返回
|
|
234
|
-
const originalContent = jsonStr.split('":"')[1];
|
|
235
|
-
// 如果正确的解析JSON,并且当前有包含JSON结束的字符,则把当前思考的JSON内容替换掉
|
|
236
|
-
if (thinkingEndIndex >= 0)
|
|
237
|
-
content = content.substring(thinkingEndIndex + 2);
|
|
238
|
-
// 如果正常输出了卡片资源,并且json结束 card_resource 只有一个,所以一旦结束,则整个思考过程完毕
|
|
239
|
-
// if (status === DeepThinkingStatus.ContentOutput && thinkingEndIndex >= 0) status = DeepThinkingStatus.ThinkingOver;
|
|
240
|
-
// 判断整个思考过程是否到达等待卡片资源(有可能智能体输出不了卡片资源) reasoning_content 只有一个,所以一旦结束,则进入下一个阶段 card_resource
|
|
241
|
-
//if (status === DeepThinkingStatus.ContentOutput && thinkingEndIndex >= 0) status = DeepThinkingStatus.ContentOutput;
|
|
242
|
-
// 判断当前是否从前期思考切换到思考内容输出
|
|
243
|
-
if (status === DeepThinkingStatus.Thinking && thinkingAction !== DeepThinkingAction.process)
|
|
244
|
-
status = DeepThinkingStatus.ContentOutput;
|
|
245
|
-
//if (status === DeepThinkingStatus.Thinking && content.indexOf("{\"reasoning_content") >= 0) status=DeepThinkingStatus.ReasonOutput;
|
|
246
|
-
//const removeOutputContent = content.replace(originalContent!.substring(1, originalContent!.length - 2),"")
|
|
247
|
-
let thinkingContent = originalContent === null || originalContent === void 0 ? void 0 : originalContent.substring(0, originalContent.length - 2);
|
|
248
|
-
const outputLength = (thinkingContent === null || thinkingContent === void 0 ? void 0 : thinkingContent.length) || 0;
|
|
249
|
-
// 用lastThinkingMessage来记录上一次的思考内容,避免重复输出内容,导致的网络传输内容过多
|
|
250
|
-
if (this.lastThinkingMessage.action === thinkingAction && this.lastThinkingMessage.textposition) {
|
|
251
|
-
thinkingContent = thinkingContent.substring(this.lastThinkingMessage.textposition);
|
|
257
|
+
const xmlTagLocation = [content.indexOf(DeepThinkingAction.thinking.start),
|
|
258
|
+
content.indexOf(DeepThinkingAction.reasoning.start),
|
|
259
|
+
content.indexOf(DeepThinkingAction.card.start)];
|
|
260
|
+
let minLocation = 10000, minIndex = -1;
|
|
261
|
+
// 找到最小的并且大于0 的位置的下标
|
|
262
|
+
xmlTagLocation.forEach((x, index) => {
|
|
263
|
+
if (x >= 0 && x < minLocation) {
|
|
264
|
+
minLocation = x;
|
|
265
|
+
minIndex = index;
|
|
252
266
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
}
|
|
267
|
+
});
|
|
268
|
+
// const tagLocation = xmlTagLocation.filter(x => x >= 0);
|
|
269
|
+
const thinkingStartIndex = minIndex >= 0 ? minLocation : -1; //tagLocation.length > 0 ? Math.min(...tagLocation) : -1;
|
|
270
|
+
if (thinkingStartIndex < 0)
|
|
271
|
+
return { content, status: DeepThinkingStatus.ThinkingOver };
|
|
272
|
+
const currentAction = [DeepThinkingAction.thinking, DeepThinkingAction.reasoning, DeepThinkingAction.card][minIndex];
|
|
273
|
+
const currentActionIsOver = content.indexOf(currentAction.end, thinkingStartIndex);
|
|
274
|
+
const thinkingEndIndex = currentActionIsOver >= 0 ? currentActionIsOver : content.indexOf('</', thinkingStartIndex);
|
|
275
|
+
const thinkingContent = this.extractXmlContent(content.substring(thinkingStartIndex, thinkingEndIndex >= 0 ? thinkingEndIndex : undefined) + currentAction.end, currentAction.tag); //"\"}";
|
|
276
|
+
if (currentActionIsOver >= 0)
|
|
277
|
+
content = content.substring(currentActionIsOver + currentAction.end.length);
|
|
278
|
+
return {
|
|
279
|
+
thinking: {
|
|
280
|
+
action: currentAction,
|
|
281
|
+
text: thinkingContent,
|
|
282
|
+
completed: currentActionIsOver >= 0
|
|
283
|
+
}, content
|
|
284
|
+
};
|
|
272
285
|
}
|
|
273
286
|
/**
|
|
274
287
|
* 流式传输聊天请求
|
|
@@ -280,6 +293,7 @@ class CorzBot extends gptbase_1.default {
|
|
|
280
293
|
*/
|
|
281
294
|
chatRequestInStream(message, callChatOption = {}, attach, _axiosOption) {
|
|
282
295
|
var _a, e_1, _b, _c;
|
|
296
|
+
var _d, _e, _f;
|
|
283
297
|
return __awaiter(this, void 0, void 0, function* () {
|
|
284
298
|
if (!message)
|
|
285
299
|
this.emit('chaterror', { successed: false, error: 'no message in chat' });
|
|
@@ -297,56 +311,59 @@ class CorzBot extends gptbase_1.default {
|
|
|
297
311
|
////否则用智能体的对话来输出结果
|
|
298
312
|
let requestid = Math.ceil(Math.random() * (new Date().getTime() * Math.random()) / 1000), index = 0;
|
|
299
313
|
const params = yield this.getRequestStream(client, message, callChatOption);
|
|
300
|
-
const stream =
|
|
314
|
+
const stream = this.botid ? client.chat.stream(params) :
|
|
315
|
+
(this.workflowid ? client.workflows.runs.stream(params) :
|
|
316
|
+
client.workflows.chat.stream(params));
|
|
301
317
|
let deltaindex = 0, fullanswer = [], followup = [], cardData = [];
|
|
302
318
|
let deepThinking = '', thinkingStatus = DeepThinkingStatus.None, cardResource = ''; // 是否在深度思考中
|
|
303
319
|
try {
|
|
304
|
-
for (var
|
|
320
|
+
for (var _g = true, stream_1 = __asyncValues(stream), stream_1_1; stream_1_1 = yield stream_1.next(), _a = stream_1_1.done, !_a;) {
|
|
305
321
|
_c = stream_1_1.value;
|
|
306
|
-
|
|
322
|
+
_g = false;
|
|
307
323
|
try {
|
|
308
324
|
const part = _c;
|
|
309
325
|
if (part.event === api_1.ChatEventType.ERROR)
|
|
310
326
|
return this.emit('chaterror', { successed: false, error: 'call failed' });
|
|
311
|
-
if (part.event === api_1.ChatEventType.CONVERSATION_MESSAGE_DELTA
|
|
312
|
-
|
|
327
|
+
if (part.event === api_1.ChatEventType.CONVERSATION_MESSAGE_DELTA ||
|
|
328
|
+
part.event === api_1.WorkflowEventType.MESSAGE) {
|
|
329
|
+
let { conversation_id, content_type, type = 'answer', role = 'assistant', content, reasoning_content: reasoning } = part.data;
|
|
330
|
+
if (!content && reasoning) {
|
|
331
|
+
this.emit('chatthinking', { text: reasoning, completed: false, action: 'deep-thinking' });
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
313
334
|
// 如果存在深度思考,则一开始就会带有相关的关键信息
|
|
314
|
-
if (deltaindex === 0 && content.startsWith("
|
|
335
|
+
if (deltaindex === 0 && content.startsWith("<xiaolu-")) {
|
|
315
336
|
thinkingStatus = DeepThinkingStatus.Thinking;
|
|
316
337
|
deltaindex++;
|
|
317
338
|
}
|
|
318
339
|
// 如果在深度思考中,则不输出消息
|
|
319
|
-
if (thinkingStatus
|
|
320
|
-
&& thinkingStatus !== DeepThinkingStatus.ThinkingOver) {
|
|
340
|
+
if (thinkingStatus === DeepThinkingStatus.Thinking) {
|
|
321
341
|
deepThinking += content;
|
|
322
|
-
const result = this.parseDeepThinkingJson(deepThinking
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
cardData.push({ type: Number(cardinfo.type), tag: cardinfo.tag });
|
|
336
|
-
}
|
|
337
|
-
// 将卡片资源返回给客户端
|
|
338
|
-
this.emit('chatcard', cardData);
|
|
342
|
+
const result = this.parseDeepThinkingJson(deepThinking);
|
|
343
|
+
const thinking = result.thinking;
|
|
344
|
+
if (thinking) {
|
|
345
|
+
deepThinking = result.content;
|
|
346
|
+
if (thinking.action === DeepThinkingAction.card) {
|
|
347
|
+
cardResource += result.thinking.text;
|
|
348
|
+
// 卡片流结束,解析卡片资源数据
|
|
349
|
+
if (result.thinking.completed) {
|
|
350
|
+
const allCards = cardResource.replace(/[\x00-\x1F\x7F]/g, '').split('|');
|
|
351
|
+
for (const item of allCards) {
|
|
352
|
+
const cardinfo = (0, querystring_1.parse)(item);
|
|
353
|
+
if (cardinfo.type && cardinfo.tag)
|
|
354
|
+
cardData.push({ type: Number(cardinfo.type), tag: cardinfo.tag });
|
|
339
355
|
}
|
|
356
|
+
// 将卡片资源返回给客户端
|
|
357
|
+
this.emit('chatcard', cardData);
|
|
340
358
|
}
|
|
341
|
-
else {
|
|
342
|
-
this.emit('chatthinking', result.thinking);
|
|
343
|
-
}
|
|
344
359
|
}
|
|
345
|
-
|
|
360
|
+
else {
|
|
361
|
+
this.emit('chatthinking', { text: result.thinking.text, completed: result.thinking.completed, action: (_d = thinking.action) === null || _d === void 0 ? void 0 : _d.tag });
|
|
362
|
+
}
|
|
346
363
|
}
|
|
347
|
-
if (
|
|
364
|
+
if (result.status != DeepThinkingStatus.ThinkingOver)
|
|
348
365
|
continue;
|
|
349
|
-
|
|
366
|
+
thinkingStatus = DeepThinkingStatus.ThinkingOver;
|
|
350
367
|
// 将排除了thinking之后的消息内容要带下去成为正式的输出内容
|
|
351
368
|
content = deepThinking;
|
|
352
369
|
}
|
|
@@ -358,28 +375,29 @@ class CorzBot extends gptbase_1.default {
|
|
|
358
375
|
}
|
|
359
376
|
////在流式传输中,提取相关推荐问题
|
|
360
377
|
if (part.event === api_1.ChatEventType.CONVERSATION_MESSAGE_COMPLETED) {
|
|
361
|
-
const { type, content } = part.data;
|
|
378
|
+
const { type, content } = (_e = part.data) !== null && _e !== void 0 ? _e : {};
|
|
362
379
|
if (type === 'follow_up')
|
|
363
380
|
followup.push(content);
|
|
364
381
|
}
|
|
365
382
|
///整个对话结束
|
|
366
|
-
if (part.event === api_1.ChatEventType.CONVERSATION_CHAT_COMPLETED
|
|
367
|
-
|
|
368
|
-
|
|
383
|
+
if (part.event === api_1.ChatEventType.CONVERSATION_CHAT_COMPLETED ||
|
|
384
|
+
part.event === api_1.WorkflowEventType.DONE) {
|
|
385
|
+
const { conversation_id, content } = (_f = (part.data)) !== null && _f !== void 0 ? _f : {};
|
|
386
|
+
let output = { successed: true, cards: cardData.length ? cardData : null, followup, type: 'answer', content_type: 'text', role: api_1.RoleType.Assistant, requestid, segment: null, text: content !== null && content !== void 0 ? content : fullanswer.join(''), index: index++, session_id: conversation_id };
|
|
369
387
|
if (attach)
|
|
370
388
|
output = Object.assign({}, output, attach);
|
|
371
389
|
this.emit('chatdone', output);
|
|
372
390
|
}
|
|
373
391
|
}
|
|
374
392
|
finally {
|
|
375
|
-
|
|
393
|
+
_g = true;
|
|
376
394
|
}
|
|
377
395
|
}
|
|
378
396
|
}
|
|
379
397
|
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
380
398
|
finally {
|
|
381
399
|
try {
|
|
382
|
-
if (!
|
|
400
|
+
if (!_g && !_a && (_b = stream_1.return)) yield _b.call(stream_1);
|
|
383
401
|
}
|
|
384
402
|
finally { if (e_1) throw e_1.error; }
|
|
385
403
|
}
|
package/package.json
CHANGED
package/src/corzbot.ts
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
RoleType,
|
|
9
9
|
StreamChatReq,
|
|
10
10
|
EnterMessage,
|
|
11
|
-
ChatWorkflowReq,
|
|
11
|
+
// ChatWorkflowReq,
|
|
12
12
|
// CreateChatReq,
|
|
13
13
|
// ChatStatus,
|
|
14
14
|
VariableUpdateReq,
|
|
@@ -17,35 +17,37 @@ import {
|
|
|
17
17
|
RunWorkflowReq,
|
|
18
18
|
RunWorkflowData,
|
|
19
19
|
CreateChatData,
|
|
20
|
-
ChatStatus
|
|
20
|
+
ChatStatus,
|
|
21
|
+
WorkflowEventType,
|
|
22
|
+
ChatWorkflowReq
|
|
21
23
|
} from '@coze/api';
|
|
22
24
|
import GptBase from "./gptbase"
|
|
23
25
|
import { CorzAuthorization } from './corzauthorization';
|
|
24
26
|
import { parse } from 'querystring'
|
|
25
27
|
import { ApiResult } from './declare';
|
|
26
28
|
|
|
27
|
-
//
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
// 定义深度思考的动作标签
|
|
30
|
+
// 这是小鹭里面专用的几个思考动作标签
|
|
31
|
+
const DeepThinkingAction: any = {
|
|
32
|
+
thinking: { start: '<xiaolu-think>', end: '</xiaolu-think>', tag: 'xiaolu-think' },
|
|
33
|
+
reasoning: { start: '<xiaolu-reason>', end: '</xiaolu-reason>', tag: 'xiaolu-reason' },
|
|
34
|
+
card: { start: '<xiaolu-card>', end: '</xiaolu-card>', tag: 'xiaolu-card' },
|
|
32
35
|
}
|
|
33
36
|
// 定义深度思考的状态
|
|
34
37
|
enum DeepThinkingStatus {
|
|
35
38
|
None,
|
|
36
39
|
Thinking,
|
|
37
|
-
ContentOutput,
|
|
40
|
+
// ContentOutput,
|
|
38
41
|
ThinkingOver
|
|
39
42
|
}
|
|
40
43
|
// 智能体思考时输出的动作
|
|
41
44
|
type CardType = { type: number, tag: string }
|
|
42
|
-
type TThinkingMessage = { action: string, textposition: number }
|
|
45
|
+
// type TThinkingMessage = { action: string, textposition: number }
|
|
43
46
|
export default class CorzBot extends GptBase {
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
private botid: string | null = null; // 智能体id
|
|
48
|
+
private workflowid: string | null = null; // 工作流id
|
|
49
|
+
private talkflowid: string | null = null; // 对话流id
|
|
46
50
|
private apiKey: string;
|
|
47
|
-
private lastThinkingMessage: TThinkingMessage = { action: '', textposition: 0 };
|
|
48
|
-
// protected client: CozeAPI;
|
|
49
51
|
/**
|
|
50
52
|
*
|
|
51
53
|
* @param apikey 调用AI中台 的key
|
|
@@ -54,8 +56,15 @@ export default class CorzBot extends GptBase {
|
|
|
54
56
|
constructor(private authorizationProvider: CorzAuthorization, private setting: any = {}) {
|
|
55
57
|
super();
|
|
56
58
|
////初始化扣子客户端
|
|
57
|
-
|
|
58
|
-
|
|
59
|
+
|
|
60
|
+
if (this.setting.workflowid)
|
|
61
|
+
this.workflowid = this.setting.workflowid;
|
|
62
|
+
else if (this.setting.talkflowid)
|
|
63
|
+
this.talkflowid = this.setting.talkflowid;
|
|
64
|
+
else if (this.setting.botid || this.setting.botID)
|
|
65
|
+
this.botid = this.setting.botid || this.setting.botID;
|
|
66
|
+
else
|
|
67
|
+
throw new Error('no botid or talkflowid or workflowid setting for coze');
|
|
59
68
|
this.apiKey = this.setting['apiKey'];
|
|
60
69
|
}
|
|
61
70
|
private async createClient(): Promise<CozeAPI> {
|
|
@@ -79,7 +88,11 @@ export default class CorzBot extends GptBase {
|
|
|
79
88
|
return null;
|
|
80
89
|
}
|
|
81
90
|
}
|
|
82
|
-
|
|
91
|
+
/**
|
|
92
|
+
* 设置Coze的变量
|
|
93
|
+
* @param params
|
|
94
|
+
* @returns
|
|
95
|
+
*/
|
|
83
96
|
override async setVariables(params: any): Promise<ApiResult> {
|
|
84
97
|
const client = await this.createClient();
|
|
85
98
|
const cozeParams: VariableUpdateReq = Object.assign({}, this.botid ? { bot_id: this.botid } : {}, params);
|
|
@@ -107,23 +120,34 @@ export default class CorzBot extends GptBase {
|
|
|
107
120
|
async getRequestStream<T>(client: CozeAPI, message: EnterMessage[], callChatOption: any = {}): Promise<T> {
|
|
108
121
|
//简单的对话请求
|
|
109
122
|
const conversation_id = callChatOption.session_id ?? await this.createCoversation(client);
|
|
110
|
-
if (
|
|
123
|
+
if (this.botid) {
|
|
111
124
|
const req: StreamChatReq = {
|
|
112
125
|
bot_id: this.botid,
|
|
113
126
|
additional_messages: message,
|
|
114
127
|
user_id: callChatOption.userid || callChatOption.cozeUserID,
|
|
115
|
-
conversation_id
|
|
128
|
+
conversation_id,
|
|
129
|
+
parameters: Object.assign({ request_src:1 }, callChatOption.parameters || {}),
|
|
116
130
|
}
|
|
117
131
|
req.custom_variables = Object.assign({}, this.setting.customVariables || {}, callChatOption.customVariables || {});
|
|
118
132
|
return req as T;
|
|
119
133
|
}
|
|
134
|
+
if (this.workflowid){
|
|
135
|
+
const worflowreq: RunWorkflowReq = {
|
|
136
|
+
ext: callChatOption.ext,
|
|
137
|
+
workflow_id: this.workflowid,//callChatOption.workflowid,
|
|
138
|
+
is_async: false,
|
|
139
|
+
// parameters: Object.assign({ input: message[0]?.content }, this.setting.customVariables || {}, callChatOption.customVariables || {}),
|
|
140
|
+
parameters: Object.assign({ request_src :1},callChatOption.parameters || {}, { input: message[0]?.content})
|
|
141
|
+
}
|
|
142
|
+
return worflowreq as T;
|
|
143
|
+
}
|
|
120
144
|
const worflowreq: ChatWorkflowReq = {
|
|
121
|
-
bot_id: this.botid,
|
|
122
145
|
additional_messages: message,
|
|
123
146
|
ext: callChatOption.ext,
|
|
124
|
-
workflow_id: this.
|
|
147
|
+
workflow_id: this.talkflowid!,//callChatOption.workflowid,
|
|
125
148
|
conversation_id,
|
|
126
|
-
parameters: Object.assign({}, this.setting.customVariables || {}, callChatOption.customVariables || {}),
|
|
149
|
+
parameters: Object.assign({request_src:1},callChatOption.parameters || {}) //Object.assign({}, this.setting.customVariables || {}, callChatOption.customVariables || {}),
|
|
150
|
+
//parameters: { input: message[0]?.content }
|
|
127
151
|
}
|
|
128
152
|
return worflowreq as T;
|
|
129
153
|
}
|
|
@@ -138,10 +162,10 @@ export default class CorzBot extends GptBase {
|
|
|
138
162
|
while ((Date.now() - startTime) < maxWaitTime) {
|
|
139
163
|
const chatinfo = await client.chat.retrieve(conversation_id, chatid);
|
|
140
164
|
// 状态已经是完成了,可以去获取对话的内容了
|
|
141
|
-
if (chatinfo.status === ChatStatus.COMPLETED)
|
|
165
|
+
if (chatinfo.status === ChatStatus.COMPLETED) return { usage: chatinfo.usage, messages: await client.chat.messages.list(conversation_id, chatid) };
|
|
142
166
|
await new Promise(resolve => setTimeout(resolve, 1500)); // 等待1500ms
|
|
143
167
|
}
|
|
144
|
-
return null;
|
|
168
|
+
return null;
|
|
145
169
|
}
|
|
146
170
|
/**
|
|
147
171
|
* 非流式传输聊天请求
|
|
@@ -160,15 +184,15 @@ export default class CorzBot extends GptBase {
|
|
|
160
184
|
}
|
|
161
185
|
];
|
|
162
186
|
const client = await this.createClient();
|
|
163
|
-
|
|
187
|
+
|
|
164
188
|
////如果参数中用的是Workflow,则调用对话流来输出结果
|
|
165
189
|
////否则用智能体的对话来输出结果
|
|
166
190
|
const params = await this.getRequestStream(client, message, callChatOption);
|
|
167
|
-
const response =
|
|
191
|
+
const response = this.botid ? await client.chat.create(params as CreateChatReq) :await client.workflows.runs.create(params as RunWorkflowReq);
|
|
168
192
|
if (this.workflowid && (response as RunWorkflowData).msg === 'Success') {
|
|
169
193
|
const resp = (response as RunWorkflowData).data;
|
|
170
194
|
try {
|
|
171
|
-
return { successed: true, message: [{ role: 'assistant', type:'answer', content: JSON.parse(resp).data }]};
|
|
195
|
+
return { successed: true, message: [{ role: 'assistant', type: 'answer', content: JSON.parse(resp).data }] };
|
|
172
196
|
} catch (error) {
|
|
173
197
|
return { successed: true, message: [{ role: 'assistant', type: 'answer', content: resp }] };
|
|
174
198
|
}
|
|
@@ -176,17 +200,30 @@ export default class CorzBot extends GptBase {
|
|
|
176
200
|
if (!this.workflowid && (response as CreateChatData).conversation_id && (response as CreateChatData).id) {
|
|
177
201
|
const ccd = response as CreateChatData;
|
|
178
202
|
const chatData = await this.getChatDetail(client, ccd.conversation_id, ccd.id);
|
|
179
|
-
if (chatData){
|
|
203
|
+
if (chatData) {
|
|
180
204
|
const message = chatData.messages.filter(x => x.type === 'answer').map(item => ({
|
|
181
205
|
role: item.role,
|
|
182
206
|
type: item.type,
|
|
183
207
|
content: item.content,
|
|
184
208
|
}));
|
|
185
|
-
return { successed: true, message, usage: chatData.usage,session_id:ccd.conversation_id };
|
|
209
|
+
return { successed: true, message, usage: chatData.usage, session_id: ccd.conversation_id };
|
|
186
210
|
}
|
|
187
211
|
}
|
|
188
212
|
return { successed: false, error: { message: '聊天未完成' } };
|
|
189
|
-
|
|
213
|
+
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* 提取XML标签中间的内容,
|
|
217
|
+
* @param xmlStr
|
|
218
|
+
* @param tagName
|
|
219
|
+
* @returns
|
|
220
|
+
*/
|
|
221
|
+
extractXmlContent(xmlStr: string, tagName: string): string {
|
|
222
|
+
// 构建匹配标签的正则(支持任意空白字符和大小写)
|
|
223
|
+
const regex = new RegExp(`<\\s*${tagName}\\s*>([\\s\\S]*?)<\\s*\\/\\s*${tagName}\\s*>`, 'i');
|
|
224
|
+
const match = xmlStr.match(regex);
|
|
225
|
+
if (match && match[1]) return match[1].trim();
|
|
226
|
+
return ''; // 未找到标签或内容
|
|
190
227
|
}
|
|
191
228
|
/**
|
|
192
229
|
* 解析深度思考的JSON内容
|
|
@@ -194,63 +231,35 @@ export default class CorzBot extends GptBase {
|
|
|
194
231
|
* @param status
|
|
195
232
|
* @returns
|
|
196
233
|
*/
|
|
197
|
-
private parseDeepThinkingJson(content: string
|
|
198
|
-
|
|
234
|
+
private parseDeepThinkingJson(content: string) {
|
|
199
235
|
// const thinkingStartIndex = status === DeepThinkingStatus.Thinking ? content.indexOf("{\"process_msg") :
|
|
200
236
|
// (status===DeepThinkingStatus.ReasonOutput ? content.indexOf("{\"reasoning_content") : content.indexOf("{\"card_resource")) ;
|
|
201
|
-
const
|
|
202
|
-
content.indexOf(
|
|
203
|
-
content.indexOf(
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
jsonStr = content.substring(thinkingStartIndex, thinkingEndIndex >= 0 ? thinkingEndIndex : undefined) + "\"}";
|
|
211
|
-
// 转换JSON的时候需要将非法字符过滤掉
|
|
212
|
-
const thinkingObject = JSON.parse(jsonStr.replace(/[\x00-\x1F\x7F]/g, ''));
|
|
213
|
-
const thinkingAction = Object.keys(thinkingObject)[0];
|
|
214
|
-
// 需要将内容的原文返回
|
|
215
|
-
const originalContent = jsonStr.split('":"')[1];
|
|
216
|
-
// 如果正确的解析JSON,并且当前有包含JSON结束的字符,则把当前思考的JSON内容替换掉
|
|
217
|
-
if (thinkingEndIndex >= 0) content = content.substring(thinkingEndIndex + 2);
|
|
218
|
-
// 如果正常输出了卡片资源,并且json结束 card_resource 只有一个,所以一旦结束,则整个思考过程完毕
|
|
219
|
-
// if (status === DeepThinkingStatus.ContentOutput && thinkingEndIndex >= 0) status = DeepThinkingStatus.ThinkingOver;
|
|
220
|
-
// 判断整个思考过程是否到达等待卡片资源(有可能智能体输出不了卡片资源) reasoning_content 只有一个,所以一旦结束,则进入下一个阶段 card_resource
|
|
221
|
-
//if (status === DeepThinkingStatus.ContentOutput && thinkingEndIndex >= 0) status = DeepThinkingStatus.ContentOutput;
|
|
222
|
-
// 判断当前是否从前期思考切换到思考内容输出
|
|
223
|
-
if (status === DeepThinkingStatus.Thinking && thinkingAction !== DeepThinkingAction.process)
|
|
224
|
-
status = DeepThinkingStatus.ContentOutput;
|
|
225
|
-
//if (status === DeepThinkingStatus.Thinking && content.indexOf("{\"reasoning_content") >= 0) status=DeepThinkingStatus.ReasonOutput;
|
|
226
|
-
//const removeOutputContent = content.replace(originalContent!.substring(1, originalContent!.length - 2),"")
|
|
227
|
-
let thinkingContent = originalContent?.substring(0, originalContent.length - 2)
|
|
228
|
-
const outputLength = thinkingContent?.length || 0;
|
|
229
|
-
|
|
230
|
-
// 用lastThinkingMessage来记录上一次的思考内容,避免重复输出内容,导致的网络传输内容过多
|
|
231
|
-
if (this.lastThinkingMessage.action === thinkingAction && this.lastThinkingMessage.textposition) {
|
|
232
|
-
thinkingContent = thinkingContent!.substring(this.lastThinkingMessage.textposition)
|
|
237
|
+
const xmlTagLocation = [content.indexOf(DeepThinkingAction.thinking.start),
|
|
238
|
+
content.indexOf(DeepThinkingAction.reasoning.start),
|
|
239
|
+
content.indexOf(DeepThinkingAction.card.start)];
|
|
240
|
+
let minLocation = 10000, minIndex = -1;
|
|
241
|
+
// 找到最小的并且大于0 的位置的下标
|
|
242
|
+
xmlTagLocation.forEach((x, index) => {
|
|
243
|
+
if (x >= 0 && x < minLocation) {
|
|
244
|
+
minLocation = x;
|
|
245
|
+
minIndex = index;
|
|
233
246
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
console.error('解析JSON出错了:', jsonStr, status)
|
|
251
|
-
// 当前解析出错,等待下一次解析
|
|
252
|
-
return { successed: false, content, status }
|
|
253
|
-
}
|
|
247
|
+
});
|
|
248
|
+
// const tagLocation = xmlTagLocation.filter(x => x >= 0);
|
|
249
|
+
const thinkingStartIndex = minIndex >= 0 ? minLocation : -1; //tagLocation.length > 0 ? Math.min(...tagLocation) : -1;
|
|
250
|
+
if (thinkingStartIndex < 0) return { content, status: DeepThinkingStatus.ThinkingOver };
|
|
251
|
+
const currentAction = [DeepThinkingAction.thinking, DeepThinkingAction.reasoning, DeepThinkingAction.card][minIndex];
|
|
252
|
+
const currentActionIsOver = content.indexOf(currentAction.end, thinkingStartIndex);
|
|
253
|
+
const thinkingEndIndex = currentActionIsOver >= 0 ? currentActionIsOver: content.indexOf('</', thinkingStartIndex);
|
|
254
|
+
const thinkingContent = this.extractXmlContent(content.substring(thinkingStartIndex, thinkingEndIndex >= 0 ? thinkingEndIndex : undefined) + currentAction.end, currentAction.tag); //"\"}";
|
|
255
|
+
if (currentActionIsOver >= 0) content = content.substring(currentActionIsOver + currentAction.end.length);
|
|
256
|
+
return {
|
|
257
|
+
thinking: {
|
|
258
|
+
action: currentAction,
|
|
259
|
+
text: thinkingContent,//Object.values(thinkingObject)[0]
|
|
260
|
+
completed: currentActionIsOver >= 0
|
|
261
|
+
}, content};
|
|
262
|
+
|
|
254
263
|
}
|
|
255
264
|
/**
|
|
256
265
|
* 流式传输聊天请求
|
|
@@ -275,48 +284,51 @@ export default class CorzBot extends GptBase {
|
|
|
275
284
|
////否则用智能体的对话来输出结果
|
|
276
285
|
let requestid = Math.ceil(Math.random() * (new Date().getTime() * Math.random()) / 1000), index = 0;
|
|
277
286
|
const params = await this.getRequestStream(client, message, callChatOption);
|
|
278
|
-
const stream =
|
|
287
|
+
const stream = this.botid ? client.chat.stream(params as StreamChatReq) :
|
|
288
|
+
(this.workflowid ? client.workflows.runs.stream(params as RunWorkflowReq) :
|
|
289
|
+
client.workflows.chat.stream(params as ChatWorkflowReq)) ;
|
|
279
290
|
let deltaindex = 0, fullanswer: string[] = [], followup: string[] = [], cardData: CardType[] = [];
|
|
280
291
|
let deepThinking = '', thinkingStatus = DeepThinkingStatus.None, cardResource = ''; // 是否在深度思考中
|
|
281
292
|
for await (const part of stream) {
|
|
282
293
|
if (part.event === ChatEventType.ERROR) return this.emit('chaterror', { successed: false, error: 'call failed' });
|
|
283
|
-
if (part.event === ChatEventType.CONVERSATION_MESSAGE_DELTA
|
|
284
|
-
|
|
294
|
+
if (part.event === ChatEventType.CONVERSATION_MESSAGE_DELTA ||
|
|
295
|
+
part.event === WorkflowEventType.MESSAGE
|
|
296
|
+
) {
|
|
297
|
+
let { conversation_id, content_type, type = 'answer', role = 'assistant', content, reasoning_content: reasoning } = part.data as any;
|
|
298
|
+
if (!content&& reasoning) {
|
|
299
|
+
this.emit('chatthinking', { text: reasoning, completed: false, action: 'deep-thinking' });
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
285
302
|
// 如果存在深度思考,则一开始就会带有相关的关键信息
|
|
286
|
-
if (deltaindex === 0 && content.startsWith("
|
|
303
|
+
if (deltaindex === 0 && content.startsWith("<xiaolu-")) {
|
|
287
304
|
thinkingStatus = DeepThinkingStatus.Thinking;
|
|
288
305
|
deltaindex++;
|
|
289
306
|
}
|
|
290
307
|
// 如果在深度思考中,则不输出消息
|
|
291
|
-
if (thinkingStatus
|
|
292
|
-
&& thinkingStatus !== DeepThinkingStatus.ThinkingOver
|
|
293
|
-
) {
|
|
308
|
+
if (thinkingStatus === DeepThinkingStatus.Thinking) {
|
|
294
309
|
deepThinking += content;
|
|
295
|
-
const result = this.parseDeepThinkingJson(deepThinking
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
if (cardinfo.type && cardinfo.tag) cardData.push({ type: Number(cardinfo.type), tag: cardinfo.tag })
|
|
308
|
-
}
|
|
309
|
-
// 将卡片资源返回给客户端
|
|
310
|
-
this.emit('chatcard', cardData);
|
|
310
|
+
const result = this.parseDeepThinkingJson(deepThinking)
|
|
311
|
+
const thinking = result.thinking;
|
|
312
|
+
if (thinking) {
|
|
313
|
+
deepThinking = result.content;
|
|
314
|
+
if (thinking.action === DeepThinkingAction.card) {
|
|
315
|
+
cardResource += result.thinking.text;
|
|
316
|
+
// 卡片流结束,解析卡片资源数据
|
|
317
|
+
if (result.thinking.completed) {
|
|
318
|
+
const allCards = cardResource.replace(/[\x00-\x1F\x7F]/g, '').split('|')
|
|
319
|
+
for (const item of allCards) {
|
|
320
|
+
const cardinfo: any = parse(item);
|
|
321
|
+
if (cardinfo.type && cardinfo.tag) cardData.push({ type: Number(cardinfo.type), tag: cardinfo.tag })
|
|
311
322
|
}
|
|
312
|
-
|
|
313
|
-
this.emit('
|
|
323
|
+
// 将卡片资源返回给客户端
|
|
324
|
+
this.emit('chatcard', cardData);
|
|
314
325
|
}
|
|
326
|
+
} else {
|
|
327
|
+
this.emit('chatthinking', { text: result.thinking.text, completed: result.thinking.completed, action: thinking.action?.tag });
|
|
315
328
|
}
|
|
316
|
-
thinkingStatus = result.status;
|
|
317
329
|
}
|
|
318
|
-
if (
|
|
319
|
-
|
|
330
|
+
if (result.status != DeepThinkingStatus.ThinkingOver) continue;
|
|
331
|
+
thinkingStatus = DeepThinkingStatus.ThinkingOver;
|
|
320
332
|
// 将排除了thinking之后的消息内容要带下去成为正式的输出内容
|
|
321
333
|
content = deepThinking;
|
|
322
334
|
}
|
|
@@ -327,13 +339,15 @@ export default class CorzBot extends GptBase {
|
|
|
327
339
|
}
|
|
328
340
|
////在流式传输中,提取相关推荐问题
|
|
329
341
|
if (part.event === ChatEventType.CONVERSATION_MESSAGE_COMPLETED) {
|
|
330
|
-
const { type, content } = part.data;
|
|
342
|
+
const { type, content } = part.data ?? {};
|
|
331
343
|
if (type === 'follow_up') followup.push(content);
|
|
332
344
|
}
|
|
333
345
|
///整个对话结束
|
|
334
|
-
if (part.event === ChatEventType.CONVERSATION_CHAT_COMPLETED
|
|
335
|
-
|
|
336
|
-
|
|
346
|
+
if (part.event === ChatEventType.CONVERSATION_CHAT_COMPLETED ||
|
|
347
|
+
part.event === WorkflowEventType.DONE
|
|
348
|
+
) {
|
|
349
|
+
const { conversation_id, content } =( part.data )?? {} as any;
|
|
350
|
+
let output = { successed: true, cards: cardData.length ? cardData : null, followup, type: 'answer', content_type: 'text', role: RoleType.Assistant, requestid, segment: null, text: content??fullanswer.join(''), index: index++, session_id: conversation_id };
|
|
337
351
|
if (attach) output = Object.assign({}, output, attach);
|
|
338
352
|
this.emit('chatdone', output)
|
|
339
353
|
}
|