doomiaichat 7.1.10 → 7.1.12
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 +132 -116
- package/package.json +1 -1
- package/src/corzbot.ts +133 -120
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();
|
|
@@ -119,24 +132,33 @@ class CorzBot extends gptbase_1.default {
|
|
|
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
|
-
|
|
139
|
-
parameters: Object.assign({ input: (_b = message[0]) === null || _b === void 0 ? void 0 : _b.content }, this.setting.customVariables || {}, callChatOption.customVariables || {}),
|
|
161
|
+
parameters: Object.assign({ request_src: 1 }, callChatOption.parameters || {}) //Object.assign({}, this.setting.customVariables || {}, callChatOption.customVariables || {}),
|
|
140
162
|
//parameters: { input: message[0]?.content }
|
|
141
163
|
};
|
|
142
164
|
return worflowreq;
|
|
@@ -184,15 +206,15 @@ class CorzBot extends gptbase_1.default {
|
|
|
184
206
|
////如果参数中用的是Workflow,则调用对话流来输出结果
|
|
185
207
|
////否则用智能体的对话来输出结果
|
|
186
208
|
const params = yield this.getRequestStream(client, message, callChatOption);
|
|
187
|
-
const response =
|
|
209
|
+
const response = this.botid ? yield client.chat.create(params) : yield client.workflows.runs.create(params);
|
|
188
210
|
if (this.workflowid && response.msg === 'Success') {
|
|
189
211
|
const resp = response.data;
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
}
|
|
193
|
-
catch (error) {
|
|
194
|
-
|
|
195
|
-
}
|
|
212
|
+
return { successed: true, message: [{ role: 'assistant', type: 'answer', content: resp }] };
|
|
213
|
+
// try {
|
|
214
|
+
// return { successed: true, message: [{ role: 'assistant', type: 'answer', content: JSON.parse(resp).data }] };
|
|
215
|
+
// } catch (error) {
|
|
216
|
+
// return { successed: true, message: [{ role: 'assistant', type: 'answer', content: resp }] };
|
|
217
|
+
// }
|
|
196
218
|
}
|
|
197
219
|
if (!this.workflowid && response.conversation_id && response.id) {
|
|
198
220
|
const ccd = response;
|
|
@@ -209,68 +231,57 @@ class CorzBot extends gptbase_1.default {
|
|
|
209
231
|
return { successed: false, error: { message: '聊天未完成' } };
|
|
210
232
|
});
|
|
211
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
|
+
}
|
|
212
248
|
/**
|
|
213
249
|
* 解析深度思考的JSON内容
|
|
214
250
|
* @param content
|
|
215
251
|
* @param status
|
|
216
252
|
* @returns
|
|
217
253
|
*/
|
|
218
|
-
parseDeepThinkingJson(content
|
|
254
|
+
parseDeepThinkingJson(content) {
|
|
219
255
|
// const thinkingStartIndex = status === DeepThinkingStatus.Thinking ? content.indexOf("{\"process_msg") :
|
|
220
256
|
// (status===DeepThinkingStatus.ReasonOutput ? content.indexOf("{\"reasoning_content") : content.indexOf("{\"card_resource")) ;
|
|
221
|
-
const
|
|
222
|
-
content.indexOf(
|
|
223
|
-
content.indexOf(
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
try {
|
|
231
|
-
jsonStr = content.substring(thinkingStartIndex, thinkingEndIndex >= 0 ? thinkingEndIndex : undefined) + "\"}";
|
|
232
|
-
// 转换JSON的时候需要将非法字符过滤掉
|
|
233
|
-
const thinkingObject = JSON.parse(jsonStr.replace(/[\x00-\x1F\x7F]/g, ''));
|
|
234
|
-
const thinkingAction = Object.keys(thinkingObject)[0];
|
|
235
|
-
// 需要将内容的原文返回
|
|
236
|
-
const originalContent = jsonStr.split('":"')[1];
|
|
237
|
-
// 如果正确的解析JSON,并且当前有包含JSON结束的字符,则把当前思考的JSON内容替换掉
|
|
238
|
-
if (thinkingEndIndex >= 0)
|
|
239
|
-
content = content.substring(thinkingEndIndex + 2);
|
|
240
|
-
// 如果正常输出了卡片资源,并且json结束 card_resource 只有一个,所以一旦结束,则整个思考过程完毕
|
|
241
|
-
// if (status === DeepThinkingStatus.ContentOutput && thinkingEndIndex >= 0) status = DeepThinkingStatus.ThinkingOver;
|
|
242
|
-
// 判断整个思考过程是否到达等待卡片资源(有可能智能体输出不了卡片资源) reasoning_content 只有一个,所以一旦结束,则进入下一个阶段 card_resource
|
|
243
|
-
//if (status === DeepThinkingStatus.ContentOutput && thinkingEndIndex >= 0) status = DeepThinkingStatus.ContentOutput;
|
|
244
|
-
// 判断当前是否从前期思考切换到思考内容输出
|
|
245
|
-
if (status === DeepThinkingStatus.Thinking && thinkingAction !== DeepThinkingAction.process)
|
|
246
|
-
status = DeepThinkingStatus.ContentOutput;
|
|
247
|
-
//if (status === DeepThinkingStatus.Thinking && content.indexOf("{\"reasoning_content") >= 0) status=DeepThinkingStatus.ReasonOutput;
|
|
248
|
-
//const removeOutputContent = content.replace(originalContent!.substring(1, originalContent!.length - 2),"")
|
|
249
|
-
let thinkingContent = originalContent === null || originalContent === void 0 ? void 0 : originalContent.substring(0, originalContent.length - 2);
|
|
250
|
-
const outputLength = (thinkingContent === null || thinkingContent === void 0 ? void 0 : thinkingContent.length) || 0;
|
|
251
|
-
// 用lastThinkingMessage来记录上一次的思考内容,避免重复输出内容,导致的网络传输内容过多
|
|
252
|
-
if (this.lastThinkingMessage.action === thinkingAction && this.lastThinkingMessage.textposition) {
|
|
253
|
-
thinkingContent = thinkingContent.substring(this.lastThinkingMessage.textposition);
|
|
254
|
-
}
|
|
255
|
-
this.lastThinkingMessage = thinkingEndIndex >= 0 ? { action: thinkingAction, textposition: 0 } : { action: thinkingAction, textposition: outputLength };
|
|
256
|
-
return {
|
|
257
|
-
successed: true, thinking: {
|
|
258
|
-
action: thinkingAction,
|
|
259
|
-
text: thinkingContent,
|
|
260
|
-
completed: thinkingEndIndex >= 0
|
|
261
|
-
}, content, status
|
|
262
|
-
};
|
|
263
|
-
}
|
|
264
|
-
catch (error) {
|
|
265
|
-
// 如果在content之后发生了错误,可能该智能体输出不了卡片类型的数据,则输出的内容已经是正文了
|
|
266
|
-
if (status === DeepThinkingStatus.ContentOutput) {
|
|
267
|
-
status = DeepThinkingStatus.ThinkingOver;
|
|
268
|
-
return { successed: true, content, status };
|
|
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;
|
|
269
266
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
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
|
+
};
|
|
274
285
|
}
|
|
275
286
|
/**
|
|
276
287
|
* 流式传输聊天请求
|
|
@@ -282,6 +293,7 @@ class CorzBot extends gptbase_1.default {
|
|
|
282
293
|
*/
|
|
283
294
|
chatRequestInStream(message, callChatOption = {}, attach, _axiosOption) {
|
|
284
295
|
var _a, e_1, _b, _c;
|
|
296
|
+
var _d, _e, _f;
|
|
285
297
|
return __awaiter(this, void 0, void 0, function* () {
|
|
286
298
|
if (!message)
|
|
287
299
|
this.emit('chaterror', { successed: false, error: 'no message in chat' });
|
|
@@ -299,56 +311,59 @@ class CorzBot extends gptbase_1.default {
|
|
|
299
311
|
////否则用智能体的对话来输出结果
|
|
300
312
|
let requestid = Math.ceil(Math.random() * (new Date().getTime() * Math.random()) / 1000), index = 0;
|
|
301
313
|
const params = yield this.getRequestStream(client, message, callChatOption);
|
|
302
|
-
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));
|
|
303
317
|
let deltaindex = 0, fullanswer = [], followup = [], cardData = [];
|
|
304
318
|
let deepThinking = '', thinkingStatus = DeepThinkingStatus.None, cardResource = ''; // 是否在深度思考中
|
|
305
319
|
try {
|
|
306
|
-
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;) {
|
|
307
321
|
_c = stream_1_1.value;
|
|
308
|
-
|
|
322
|
+
_g = false;
|
|
309
323
|
try {
|
|
310
324
|
const part = _c;
|
|
311
325
|
if (part.event === api_1.ChatEventType.ERROR)
|
|
312
326
|
return this.emit('chaterror', { successed: false, error: 'call failed' });
|
|
313
|
-
if (part.event === api_1.ChatEventType.CONVERSATION_MESSAGE_DELTA
|
|
314
|
-
|
|
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
|
+
}
|
|
315
334
|
// 如果存在深度思考,则一开始就会带有相关的关键信息
|
|
316
|
-
if (deltaindex === 0 && content.startsWith("
|
|
335
|
+
if (deltaindex === 0 && content.startsWith("<xiaolu-")) {
|
|
317
336
|
thinkingStatus = DeepThinkingStatus.Thinking;
|
|
318
337
|
deltaindex++;
|
|
319
338
|
}
|
|
320
339
|
// 如果在深度思考中,则不输出消息
|
|
321
|
-
if (thinkingStatus
|
|
322
|
-
&& thinkingStatus !== DeepThinkingStatus.ThinkingOver) {
|
|
340
|
+
if (thinkingStatus === DeepThinkingStatus.Thinking) {
|
|
323
341
|
deepThinking += content;
|
|
324
|
-
const result = this.parseDeepThinkingJson(deepThinking
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
cardData.push({ type: Number(cardinfo.type), tag: cardinfo.tag });
|
|
338
|
-
}
|
|
339
|
-
// 将卡片资源返回给客户端
|
|
340
|
-
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 });
|
|
341
355
|
}
|
|
356
|
+
// 将卡片资源返回给客户端
|
|
357
|
+
this.emit('chatcard', cardData);
|
|
342
358
|
}
|
|
343
|
-
else {
|
|
344
|
-
this.emit('chatthinking', result.thinking);
|
|
345
|
-
}
|
|
346
359
|
}
|
|
347
|
-
|
|
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
|
+
}
|
|
348
363
|
}
|
|
349
|
-
if (
|
|
364
|
+
if (result.status != DeepThinkingStatus.ThinkingOver)
|
|
350
365
|
continue;
|
|
351
|
-
|
|
366
|
+
thinkingStatus = DeepThinkingStatus.ThinkingOver;
|
|
352
367
|
// 将排除了thinking之后的消息内容要带下去成为正式的输出内容
|
|
353
368
|
content = deepThinking;
|
|
354
369
|
}
|
|
@@ -360,28 +375,29 @@ class CorzBot extends gptbase_1.default {
|
|
|
360
375
|
}
|
|
361
376
|
////在流式传输中,提取相关推荐问题
|
|
362
377
|
if (part.event === api_1.ChatEventType.CONVERSATION_MESSAGE_COMPLETED) {
|
|
363
|
-
const { type, content } = part.data;
|
|
378
|
+
const { type, content } = (_e = part.data) !== null && _e !== void 0 ? _e : {};
|
|
364
379
|
if (type === 'follow_up')
|
|
365
380
|
followup.push(content);
|
|
366
381
|
}
|
|
367
382
|
///整个对话结束
|
|
368
|
-
if (part.event === api_1.ChatEventType.CONVERSATION_CHAT_COMPLETED
|
|
369
|
-
|
|
370
|
-
|
|
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 };
|
|
371
387
|
if (attach)
|
|
372
388
|
output = Object.assign({}, output, attach);
|
|
373
389
|
this.emit('chatdone', output);
|
|
374
390
|
}
|
|
375
391
|
}
|
|
376
392
|
finally {
|
|
377
|
-
|
|
393
|
+
_g = true;
|
|
378
394
|
}
|
|
379
395
|
}
|
|
380
396
|
}
|
|
381
397
|
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
382
398
|
finally {
|
|
383
399
|
try {
|
|
384
|
-
if (!
|
|
400
|
+
if (!_g && !_a && (_b = stream_1.return)) yield _b.call(stream_1);
|
|
385
401
|
}
|
|
386
402
|
finally { if (e_1) throw e_1.error; }
|
|
387
403
|
}
|
package/package.json
CHANGED
package/src/corzbot.ts
CHANGED
|
@@ -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,24 +120,33 @@ 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
|
}
|
|
120
|
-
|
|
121
|
-
|
|
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
|
+
}
|
|
144
|
+
const worflowreq: ChatWorkflowReq = {
|
|
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
|
-
|
|
127
|
-
parameters: Object.assign({ input: message[0]?.content }, this.setting.customVariables || {}, callChatOption.customVariables || {}),
|
|
149
|
+
parameters: Object.assign({request_src:1},callChatOption.parameters || {}) //Object.assign({}, this.setting.customVariables || {}, callChatOption.customVariables || {}),
|
|
128
150
|
//parameters: { input: message[0]?.content }
|
|
129
151
|
}
|
|
130
152
|
return worflowreq as T;
|
|
@@ -140,10 +162,10 @@ export default class CorzBot extends GptBase {
|
|
|
140
162
|
while ((Date.now() - startTime) < maxWaitTime) {
|
|
141
163
|
const chatinfo = await client.chat.retrieve(conversation_id, chatid);
|
|
142
164
|
// 状态已经是完成了,可以去获取对话的内容了
|
|
143
|
-
if (chatinfo.status === ChatStatus.COMPLETED)
|
|
165
|
+
if (chatinfo.status === ChatStatus.COMPLETED) return { usage: chatinfo.usage, messages: await client.chat.messages.list(conversation_id, chatid) };
|
|
144
166
|
await new Promise(resolve => setTimeout(resolve, 1500)); // 等待1500ms
|
|
145
167
|
}
|
|
146
|
-
return null;
|
|
168
|
+
return null;
|
|
147
169
|
}
|
|
148
170
|
/**
|
|
149
171
|
* 非流式传输聊天请求
|
|
@@ -162,33 +184,47 @@ export default class CorzBot extends GptBase {
|
|
|
162
184
|
}
|
|
163
185
|
];
|
|
164
186
|
const client = await this.createClient();
|
|
165
|
-
|
|
187
|
+
|
|
166
188
|
////如果参数中用的是Workflow,则调用对话流来输出结果
|
|
167
189
|
////否则用智能体的对话来输出结果
|
|
168
190
|
const params = await this.getRequestStream(client, message, callChatOption);
|
|
169
|
-
const response =
|
|
191
|
+
const response = this.botid ? await client.chat.create(params as CreateChatReq) :await client.workflows.runs.create(params as RunWorkflowReq);
|
|
170
192
|
if (this.workflowid && (response as RunWorkflowData).msg === 'Success') {
|
|
171
193
|
const resp = (response as RunWorkflowData).data;
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
}
|
|
194
|
+
return { successed: true, message: [{ role: 'assistant', type: 'answer', content: resp }] };
|
|
195
|
+
// try {
|
|
196
|
+
// return { successed: true, message: [{ role: 'assistant', type: 'answer', content: JSON.parse(resp).data }] };
|
|
197
|
+
// } catch (error) {
|
|
198
|
+
// return { successed: true, message: [{ role: 'assistant', type: 'answer', content: resp }] };
|
|
199
|
+
// }
|
|
177
200
|
}
|
|
178
201
|
if (!this.workflowid && (response as CreateChatData).conversation_id && (response as CreateChatData).id) {
|
|
179
202
|
const ccd = response as CreateChatData;
|
|
180
203
|
const chatData = await this.getChatDetail(client, ccd.conversation_id, ccd.id);
|
|
181
|
-
if (chatData){
|
|
204
|
+
if (chatData) {
|
|
182
205
|
const message = chatData.messages.filter(x => x.type === 'answer').map(item => ({
|
|
183
206
|
role: item.role,
|
|
184
207
|
type: item.type,
|
|
185
208
|
content: item.content,
|
|
186
209
|
}));
|
|
187
|
-
return { successed: true, message, usage: chatData.usage,session_id:ccd.conversation_id };
|
|
210
|
+
return { successed: true, message, usage: chatData.usage, session_id: ccd.conversation_id };
|
|
188
211
|
}
|
|
189
212
|
}
|
|
190
213
|
return { successed: false, error: { message: '聊天未完成' } };
|
|
191
|
-
|
|
214
|
+
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* 提取XML标签中间的内容,
|
|
218
|
+
* @param xmlStr
|
|
219
|
+
* @param tagName
|
|
220
|
+
* @returns
|
|
221
|
+
*/
|
|
222
|
+
extractXmlContent(xmlStr: string, tagName: string): string {
|
|
223
|
+
// 构建匹配标签的正则(支持任意空白字符和大小写)
|
|
224
|
+
const regex = new RegExp(`<\\s*${tagName}\\s*>([\\s\\S]*?)<\\s*\\/\\s*${tagName}\\s*>`, 'i');
|
|
225
|
+
const match = xmlStr.match(regex);
|
|
226
|
+
if (match && match[1]) return match[1].trim();
|
|
227
|
+
return ''; // 未找到标签或内容
|
|
192
228
|
}
|
|
193
229
|
/**
|
|
194
230
|
* 解析深度思考的JSON内容
|
|
@@ -196,63 +232,35 @@ export default class CorzBot extends GptBase {
|
|
|
196
232
|
* @param status
|
|
197
233
|
* @returns
|
|
198
234
|
*/
|
|
199
|
-
private parseDeepThinkingJson(content: string
|
|
200
|
-
|
|
235
|
+
private parseDeepThinkingJson(content: string) {
|
|
201
236
|
// const thinkingStartIndex = status === DeepThinkingStatus.Thinking ? content.indexOf("{\"process_msg") :
|
|
202
237
|
// (status===DeepThinkingStatus.ReasonOutput ? content.indexOf("{\"reasoning_content") : content.indexOf("{\"card_resource")) ;
|
|
203
|
-
const
|
|
204
|
-
content.indexOf(
|
|
205
|
-
content.indexOf(
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
jsonStr = content.substring(thinkingStartIndex, thinkingEndIndex >= 0 ? thinkingEndIndex : undefined) + "\"}";
|
|
213
|
-
// 转换JSON的时候需要将非法字符过滤掉
|
|
214
|
-
const thinkingObject = JSON.parse(jsonStr.replace(/[\x00-\x1F\x7F]/g, ''));
|
|
215
|
-
const thinkingAction = Object.keys(thinkingObject)[0];
|
|
216
|
-
// 需要将内容的原文返回
|
|
217
|
-
const originalContent = jsonStr.split('":"')[1];
|
|
218
|
-
// 如果正确的解析JSON,并且当前有包含JSON结束的字符,则把当前思考的JSON内容替换掉
|
|
219
|
-
if (thinkingEndIndex >= 0) content = content.substring(thinkingEndIndex + 2);
|
|
220
|
-
// 如果正常输出了卡片资源,并且json结束 card_resource 只有一个,所以一旦结束,则整个思考过程完毕
|
|
221
|
-
// if (status === DeepThinkingStatus.ContentOutput && thinkingEndIndex >= 0) status = DeepThinkingStatus.ThinkingOver;
|
|
222
|
-
// 判断整个思考过程是否到达等待卡片资源(有可能智能体输出不了卡片资源) reasoning_content 只有一个,所以一旦结束,则进入下一个阶段 card_resource
|
|
223
|
-
//if (status === DeepThinkingStatus.ContentOutput && thinkingEndIndex >= 0) status = DeepThinkingStatus.ContentOutput;
|
|
224
|
-
// 判断当前是否从前期思考切换到思考内容输出
|
|
225
|
-
if (status === DeepThinkingStatus.Thinking && thinkingAction !== DeepThinkingAction.process)
|
|
226
|
-
status = DeepThinkingStatus.ContentOutput;
|
|
227
|
-
//if (status === DeepThinkingStatus.Thinking && content.indexOf("{\"reasoning_content") >= 0) status=DeepThinkingStatus.ReasonOutput;
|
|
228
|
-
//const removeOutputContent = content.replace(originalContent!.substring(1, originalContent!.length - 2),"")
|
|
229
|
-
let thinkingContent = originalContent?.substring(0, originalContent.length - 2)
|
|
230
|
-
const outputLength = thinkingContent?.length || 0;
|
|
231
|
-
|
|
232
|
-
// 用lastThinkingMessage来记录上一次的思考内容,避免重复输出内容,导致的网络传输内容过多
|
|
233
|
-
if (this.lastThinkingMessage.action === thinkingAction && this.lastThinkingMessage.textposition) {
|
|
234
|
-
thinkingContent = thinkingContent!.substring(this.lastThinkingMessage.textposition)
|
|
238
|
+
const xmlTagLocation = [content.indexOf(DeepThinkingAction.thinking.start),
|
|
239
|
+
content.indexOf(DeepThinkingAction.reasoning.start),
|
|
240
|
+
content.indexOf(DeepThinkingAction.card.start)];
|
|
241
|
+
let minLocation = 10000, minIndex = -1;
|
|
242
|
+
// 找到最小的并且大于0 的位置的下标
|
|
243
|
+
xmlTagLocation.forEach((x, index) => {
|
|
244
|
+
if (x >= 0 && x < minLocation) {
|
|
245
|
+
minLocation = x;
|
|
246
|
+
minIndex = index;
|
|
235
247
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
console.error('解析JSON出错了:', jsonStr, status)
|
|
253
|
-
// 当前解析出错,等待下一次解析
|
|
254
|
-
return { successed: false, content, status }
|
|
255
|
-
}
|
|
248
|
+
});
|
|
249
|
+
// const tagLocation = xmlTagLocation.filter(x => x >= 0);
|
|
250
|
+
const thinkingStartIndex = minIndex >= 0 ? minLocation : -1; //tagLocation.length > 0 ? Math.min(...tagLocation) : -1;
|
|
251
|
+
if (thinkingStartIndex < 0) return { content, status: DeepThinkingStatus.ThinkingOver };
|
|
252
|
+
const currentAction = [DeepThinkingAction.thinking, DeepThinkingAction.reasoning, DeepThinkingAction.card][minIndex];
|
|
253
|
+
const currentActionIsOver = content.indexOf(currentAction.end, thinkingStartIndex);
|
|
254
|
+
const thinkingEndIndex = currentActionIsOver >= 0 ? currentActionIsOver: content.indexOf('</', thinkingStartIndex);
|
|
255
|
+
const thinkingContent = this.extractXmlContent(content.substring(thinkingStartIndex, thinkingEndIndex >= 0 ? thinkingEndIndex : undefined) + currentAction.end, currentAction.tag); //"\"}";
|
|
256
|
+
if (currentActionIsOver >= 0) content = content.substring(currentActionIsOver + currentAction.end.length);
|
|
257
|
+
return {
|
|
258
|
+
thinking: {
|
|
259
|
+
action: currentAction,
|
|
260
|
+
text: thinkingContent,//Object.values(thinkingObject)[0]
|
|
261
|
+
completed: currentActionIsOver >= 0
|
|
262
|
+
}, content};
|
|
263
|
+
|
|
256
264
|
}
|
|
257
265
|
/**
|
|
258
266
|
* 流式传输聊天请求
|
|
@@ -277,48 +285,51 @@ export default class CorzBot extends GptBase {
|
|
|
277
285
|
////否则用智能体的对话来输出结果
|
|
278
286
|
let requestid = Math.ceil(Math.random() * (new Date().getTime() * Math.random()) / 1000), index = 0;
|
|
279
287
|
const params = await this.getRequestStream(client, message, callChatOption);
|
|
280
|
-
const stream =
|
|
288
|
+
const stream = this.botid ? client.chat.stream(params as StreamChatReq) :
|
|
289
|
+
(this.workflowid ? client.workflows.runs.stream(params as RunWorkflowReq) :
|
|
290
|
+
client.workflows.chat.stream(params as ChatWorkflowReq)) ;
|
|
281
291
|
let deltaindex = 0, fullanswer: string[] = [], followup: string[] = [], cardData: CardType[] = [];
|
|
282
292
|
let deepThinking = '', thinkingStatus = DeepThinkingStatus.None, cardResource = ''; // 是否在深度思考中
|
|
283
293
|
for await (const part of stream) {
|
|
284
294
|
if (part.event === ChatEventType.ERROR) return this.emit('chaterror', { successed: false, error: 'call failed' });
|
|
285
|
-
if (part.event === ChatEventType.CONVERSATION_MESSAGE_DELTA
|
|
286
|
-
|
|
295
|
+
if (part.event === ChatEventType.CONVERSATION_MESSAGE_DELTA ||
|
|
296
|
+
part.event === WorkflowEventType.MESSAGE
|
|
297
|
+
) {
|
|
298
|
+
let { conversation_id, content_type, type = 'answer', role = 'assistant', content, reasoning_content: reasoning } = part.data as any;
|
|
299
|
+
if (!content&& reasoning) {
|
|
300
|
+
this.emit('chatthinking', { text: reasoning, completed: false, action: 'deep-thinking' });
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
287
303
|
// 如果存在深度思考,则一开始就会带有相关的关键信息
|
|
288
|
-
if (deltaindex === 0 && content.startsWith("
|
|
304
|
+
if (deltaindex === 0 && content.startsWith("<xiaolu-")) {
|
|
289
305
|
thinkingStatus = DeepThinkingStatus.Thinking;
|
|
290
306
|
deltaindex++;
|
|
291
307
|
}
|
|
292
308
|
// 如果在深度思考中,则不输出消息
|
|
293
|
-
if (thinkingStatus
|
|
294
|
-
&& thinkingStatus !== DeepThinkingStatus.ThinkingOver
|
|
295
|
-
) {
|
|
309
|
+
if (thinkingStatus === DeepThinkingStatus.Thinking) {
|
|
296
310
|
deepThinking += content;
|
|
297
|
-
const result = this.parseDeepThinkingJson(deepThinking
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
if (cardinfo.type && cardinfo.tag) cardData.push({ type: Number(cardinfo.type), tag: cardinfo.tag })
|
|
310
|
-
}
|
|
311
|
-
// 将卡片资源返回给客户端
|
|
312
|
-
this.emit('chatcard', cardData);
|
|
311
|
+
const result = this.parseDeepThinkingJson(deepThinking)
|
|
312
|
+
const thinking = result.thinking;
|
|
313
|
+
if (thinking) {
|
|
314
|
+
deepThinking = result.content;
|
|
315
|
+
if (thinking.action === DeepThinkingAction.card) {
|
|
316
|
+
cardResource += result.thinking.text;
|
|
317
|
+
// 卡片流结束,解析卡片资源数据
|
|
318
|
+
if (result.thinking.completed) {
|
|
319
|
+
const allCards = cardResource.replace(/[\x00-\x1F\x7F]/g, '').split('|')
|
|
320
|
+
for (const item of allCards) {
|
|
321
|
+
const cardinfo: any = parse(item);
|
|
322
|
+
if (cardinfo.type && cardinfo.tag) cardData.push({ type: Number(cardinfo.type), tag: cardinfo.tag })
|
|
313
323
|
}
|
|
314
|
-
|
|
315
|
-
this.emit('
|
|
324
|
+
// 将卡片资源返回给客户端
|
|
325
|
+
this.emit('chatcard', cardData);
|
|
316
326
|
}
|
|
327
|
+
} else {
|
|
328
|
+
this.emit('chatthinking', { text: result.thinking.text, completed: result.thinking.completed, action: thinking.action?.tag });
|
|
317
329
|
}
|
|
318
|
-
thinkingStatus = result.status;
|
|
319
330
|
}
|
|
320
|
-
if (
|
|
321
|
-
|
|
331
|
+
if (result.status != DeepThinkingStatus.ThinkingOver) continue;
|
|
332
|
+
thinkingStatus = DeepThinkingStatus.ThinkingOver;
|
|
322
333
|
// 将排除了thinking之后的消息内容要带下去成为正式的输出内容
|
|
323
334
|
content = deepThinking;
|
|
324
335
|
}
|
|
@@ -329,13 +340,15 @@ export default class CorzBot extends GptBase {
|
|
|
329
340
|
}
|
|
330
341
|
////在流式传输中,提取相关推荐问题
|
|
331
342
|
if (part.event === ChatEventType.CONVERSATION_MESSAGE_COMPLETED) {
|
|
332
|
-
const { type, content } = part.data;
|
|
343
|
+
const { type, content } = part.data ?? {};
|
|
333
344
|
if (type === 'follow_up') followup.push(content);
|
|
334
345
|
}
|
|
335
346
|
///整个对话结束
|
|
336
|
-
if (part.event === ChatEventType.CONVERSATION_CHAT_COMPLETED
|
|
337
|
-
|
|
338
|
-
|
|
347
|
+
if (part.event === ChatEventType.CONVERSATION_CHAT_COMPLETED ||
|
|
348
|
+
part.event === WorkflowEventType.DONE
|
|
349
|
+
) {
|
|
350
|
+
const { conversation_id, content } =( part.data )?? {} as any;
|
|
351
|
+
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 };
|
|
339
352
|
if (attach) output = Object.assign({}, output, attach);
|
|
340
353
|
this.emit('chatdone', output)
|
|
341
354
|
}
|