doomiaichat 7.1.29 → 7.1.31

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.
Files changed (65) hide show
  1. package/dist/index.esm.js +16 -0
  2. package/dist/index.js +16 -28
  3. package/dist/{aimp.d.ts → types/aimp.d.ts} +1 -0
  4. package/dist/types/aimp.d.ts.map +1 -0
  5. package/dist/{azureai.d.ts → types/azureai.d.ts} +1 -0
  6. package/dist/types/azureai.d.ts.map +1 -0
  7. package/dist/{corzauthorization.d.ts → types/corzauthorization.d.ts} +1 -0
  8. package/dist/types/corzauthorization.d.ts.map +1 -0
  9. package/dist/{corzbot.d.ts → types/corzbot.d.ts} +1 -0
  10. package/dist/types/corzbot.d.ts.map +1 -0
  11. package/dist/{declare.d.ts → types/declare.d.ts} +2 -1
  12. package/dist/types/declare.d.ts.map +1 -0
  13. package/dist/{doubaoai.d.ts → types/doubaoai.d.ts} +1 -0
  14. package/dist/types/doubaoai.d.ts.map +1 -0
  15. package/dist/{gptbase.d.ts → types/gptbase.d.ts} +1 -1
  16. package/dist/types/gptbase.d.ts.map +1 -0
  17. package/dist/{gptprovider.d.ts → types/gptprovider.d.ts} +2 -7
  18. package/dist/types/gptprovider.d.ts.map +1 -0
  19. package/dist/{index.d.ts → types/index.d.ts} +1 -0
  20. package/dist/types/index.d.ts.map +1 -0
  21. package/dist/{openai.d.ts → types/openai.d.ts} +1 -0
  22. package/dist/types/openai.d.ts.map +1 -0
  23. package/dist/{openaibase.d.ts → types/openaibase.d.ts} +1 -0
  24. package/dist/types/openaibase.d.ts.map +1 -0
  25. package/dist/{openaiproxy.d.ts → types/openaiproxy.d.ts} +1 -0
  26. package/dist/types/openaiproxy.d.ts.map +1 -0
  27. package/package.json +16 -4
  28. package/dist/aimp.js +0 -162
  29. package/dist/azureai.js +0 -220
  30. package/dist/baiduai.d.ts +0 -28
  31. package/dist/baiduai.js +0 -92
  32. package/dist/corzauthorization.js +0 -79
  33. package/dist/corzbot.js +0 -490
  34. package/dist/declare.js +0 -51
  35. package/dist/deepseek.d.ts +0 -5
  36. package/dist/deepseek.js +0 -16
  37. package/dist/doubaoai.js +0 -149
  38. package/dist/gptbase.js +0 -58
  39. package/dist/gptprovider.js +0 -80
  40. package/dist/openai.js +0 -184
  41. package/dist/openaibase.js +0 -20
  42. package/dist/openaiprovider.d.ts +0 -20
  43. package/dist/openaiprovider.js +0 -43
  44. package/dist/openaiproxy.js +0 -108
  45. package/dist/stabilityai.d.ts +0 -18
  46. package/dist/stabilityai.js +0 -75
  47. package/dist/stabilityplusai.d.ts +0 -11
  48. package/dist/stabilityplusai.js +0 -86
  49. package/src/aimp.ts +0 -125
  50. package/src/azureai.ts +0 -180
  51. package/src/baiduai.ts +0 -86
  52. package/src/corzauthorization.ts +0 -59
  53. package/src/corzbot.ts +0 -434
  54. package/src/declare.ts +0 -152
  55. package/src/deepseek.ts +0 -11
  56. package/src/doubaoai.ts +0 -129
  57. package/src/gptbase.ts +0 -52
  58. package/src/gptprovider.ts +0 -74
  59. package/src/index.ts +0 -2
  60. package/src/openai.ts +0 -136
  61. package/src/openaibase.ts +0 -30
  62. package/src/openaiproxy.ts +0 -97
  63. package/src/stabilityai.ts +0 -67
  64. package/src/stabilityplusai.ts +0 -77
  65. package/tsconfig.json +0 -31
package/src/baiduai.ts DELETED
@@ -1,86 +0,0 @@
1
- import { ApiResult, CacheProvider, request } from "./declare";
2
- import GptBase from "./gptbase"
3
- const TOKEN_CACHE_KEY = "key:_doomisoft:baiduwenxin:"
4
- export default class BaiduWenXinAI extends GptBase {
5
-
6
- protected credential: ApiCredential;
7
- private Cacher: CacheProvider|undefined;
8
- /**
9
- *
10
- * @param credential 调用OpenAI 的key
11
- * @param cacher 用作accesstoken的缓存
12
- * @param apiOption 用作accesstoken的缓存
13
- */
14
- constructor(credential: ApiCredential, cacher?:CacheProvider) {
15
- super();
16
- this.credential = credential;
17
- this.Cacher = cacher;
18
- }
19
- /**
20
- * 获取调用Api的Token
21
- */
22
- async getAccessToken():Promise<AccessTokenResult>{
23
- ////如果当前应用是一个委托到第三方的
24
- ///公众号或小程序,则需要用关联的第三方平台来获取api调用的accesstoken
25
- ////如果是需要缓存token,则首先看缓存中是否有AccessToken
26
- const accesstoken = this.Cacher ? (await this.Cacher.get(TOKEN_CACHE_KEY+this.credential.apikey)):null;
27
- if (accesstoken) return { successed: true, access_token: accesstoken };
28
- const option = {
29
- url: `https://wenxin.baidu.com/moduleApi/portal/api/oauth/token?grant_type=client_credentials&client_id=${this.credential.apikey}&client_secret=${this.credential.securitykey}`,
30
- method:"post",
31
- };
32
- const tokenData = await request(option);
33
- if (tokenData.successed == true && !tokenData.data.code) {
34
- ///把api accesstoken缓存起来
35
- if (this.Cacher){
36
- this.Cacher.set(TOKEN_CACHE_KEY + this.credential.apikey, tokenData.data.data,3600*20);
37
- }
38
- return { successed: true, access_token: tokenData.data.data };
39
- }
40
- return { successed: false, error: tokenData.data.msg }
41
- }
42
-
43
- /**
44
- * 请求GPT接口
45
- */
46
- public async chatRequest(chatText: string | Array<any>, _paramOption: any, axiosOption: any = {}): Promise<ApiResult> {
47
- console.log('call baidu')
48
- if (!chatText) return { successed: false, error: { errcode: 2, errmsg: '缺失聊天的内容' } };
49
- const accessToken = await this.getAccessToken();
50
- if (!accessToken.successed || !accessToken.access_token) return {successed:false,error:'accesstoken get failed'}
51
- try {
52
- let param = {
53
- ...axiosOption,
54
- method: "post",
55
- data: {
56
- text: `问题:${chatText}\n回答:`,
57
- seq_len: 512,
58
- topp: 0.5,
59
- penalty_score: 1.2,
60
- min_dec_len: 12,
61
- min_dec_penalty_text: "。?:![<S>]",
62
- task_prompt: "qa",
63
- mask_type: "paragraph"
64
- },
65
- url:`https://wenxin.baidu.com/moduleApi/portal/api/rest/1.0/ernie/3.0.25/zeus?access_token=${accessToken.access_token}`
66
- };
67
- console.log('param', param)
68
- const response = await request(param)
69
- if (response.successed && !response.data.code) {
70
- return { successed: true, ...response.data };
71
- }
72
- return { successed: false, ...response.data };
73
- } catch (error) {
74
- console.log('result is error ', error)
75
- return { successed: false, error };
76
- }
77
-
78
- }
79
- }
80
- export interface AccessTokenResult extends ApiResult {
81
- 'access_token'?: string
82
- }
83
- export interface ApiCredential{
84
- 'apikey':string,
85
- 'securitykey': string
86
- }
@@ -1,59 +0,0 @@
1
- import fs from 'fs';
2
- import path from 'path';
3
- import { getJWTToken, COZE_CN_BASE_URL } from '@coze/api';
4
- export class CorzAuthorization {
5
- private accessToken: string | null |undefined;
6
- private expiresAt: number = 0;
7
- private pemfile: string;
8
- private secret: string;
9
- private sessionName: string;
10
- constructor(public appid: string,setting:Record<string,any>) {
11
- this.secret = setting["keyid"];
12
- this.pemfile = setting["pemfile"] || "private.pem"
13
- this.sessionName = setting["sessionName"] || "default";
14
- }
15
- /**
16
- * 获取授权令牌
17
- * @returns
18
- */
19
- async getAccessToken():Promise<string|null> {
20
- // 检查令牌是否存在且未过期,如果有效直接放回
21
- if (this.accessToken && Date.now() < this.expiresAt) return this.accessToken;
22
- // 开始新的授权
23
- const result = await this.doAuthorize();
24
- if (!result.successed) return null;
25
- // 缓存授权令牌和过期时间
26
- this.accessToken = result.accessToken!;
27
- // 将 expires_in 转换为绝对时间戳
28
- this.expiresAt = result.expires_in! * 1000; // 将秒转换为毫秒
29
- return this.accessToken;
30
- }
31
- /**
32
- * 进行授权
33
- * @returns
34
- */
35
- private async doAuthorize(): Promise<{ successed: boolean, accessToken?: string, expires_in?: number,error?:any }> {
36
- try {
37
- // 提取您的 COZE API 授权参数
38
- //const keyid = "H7rAk-5s0TPOs9-rXnCr7pvkPhpJZGArT__UuMyhbkg";
39
- const aud = "api.coze.cn";
40
- // 读取私钥
41
- const fileFullPath =path.join(process.cwd(), this.pemfile);
42
- if (!fs.existsSync(fileFullPath)) return { successed: false, error: `${fileFullPath} not existed`}
43
- const privateKey = fs.readFileSync(fileFullPath).toString();
44
-
45
- // 获取JWT令牌
46
- const result = await getJWTToken({
47
- baseURL: COZE_CN_BASE_URL,
48
- appId:this.appid,
49
- aud,
50
- keyid:this.secret,
51
- privateKey,
52
- sessionName:this.sessionName,
53
- });
54
- return {successed: true, accessToken: result.access_token, expires_in: result.expires_in}
55
- } catch (error) {
56
- return { successed: true, error }
57
- }
58
- }
59
- }
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
- }