wechaty-web-panel 1.6.112 → 1.6.113

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 (109) hide show
  1. package/dist/bot/chatgpt/index.js +235 -0
  2. package/dist/bot/coze/sdk/index.js +110 -0
  3. package/dist/bot/dify/sdk/index.js +461 -0
  4. package/dist/bot/dify/sdk/office.js +319 -0
  5. package/dist/bot/fastgpt/index.js +98 -0
  6. package/dist/bot/qanything/index.js +136 -0
  7. package/dist/botInstance/coze.js +167 -0
  8. package/dist/botInstance/cozev3.js +157 -0
  9. package/dist/botInstance/dify.js +160 -0
  10. package/dist/botInstance/fastgpt.js +130 -0
  11. package/dist/botInstance/gpt4v.js +95 -0
  12. package/dist/botInstance/officialOpenAi.js +186 -0
  13. package/dist/botInstance/qany.js +144 -0
  14. package/dist/botInstance/sdk/chatGPT4V.js +89 -0
  15. package/dist/botInstance/sdk/coze.js +200 -0
  16. package/dist/botInstance/sdk/difyClient.js +354 -0
  17. package/dist/botInstance/sdk/pTimeout.js +97 -0
  18. package/dist/botInstance/sdk/qanything.js +137 -0
  19. package/dist/botInstance/sdk/quick-lru.js +237 -0
  20. package/dist/common/hook.js +66 -0
  21. package/dist/common/index.js +513 -0
  22. package/dist/common/multiReply.js +158 -0
  23. package/dist/common/reply.js +23 -0
  24. package/dist/const/puppet-type.js +71 -0
  25. package/dist/db/aiDb.js +27 -0
  26. package/dist/db/aichatDb.js +84 -0
  27. package/dist/db/chatHistory.js +137 -0
  28. package/dist/db/configDb.js +97 -0
  29. package/dist/db/global.js +62 -0
  30. package/dist/db/gptConfig.js +85 -0
  31. package/dist/db/nedb.js +88 -0
  32. package/dist/db/puppetDb.js +58 -0
  33. package/dist/db/roomDb.js +83 -0
  34. package/dist/db/rssConfig.js +82 -0
  35. package/dist/db/rssHistory.js +88 -0
  36. package/dist/db/userDb.js +27 -0
  37. package/dist/handlers/on-callback-message.js +183 -0
  38. package/dist/handlers/on-error.js +5 -0
  39. package/dist/handlers/on-friend.js +62 -0
  40. package/dist/handlers/on-heartbeat.js +20 -0
  41. package/dist/handlers/on-login.js +58 -0
  42. package/dist/handlers/on-logout.js +17 -0
  43. package/dist/handlers/on-message.js +644 -0
  44. package/dist/handlers/on-ready.js +36 -0
  45. package/dist/handlers/on-record-message.js +56 -0
  46. package/dist/handlers/on-roomjoin.js +42 -0
  47. package/dist/handlers/on-roomleave.js +12 -0
  48. package/dist/handlers/on-roomtopic.js +16 -0
  49. package/dist/handlers/on-scan.js +64 -0
  50. package/dist/handlers/on-verifycode.js +42 -0
  51. package/dist/index.js +81 -69306
  52. package/dist/lib/contentCensor.js +23 -0
  53. package/dist/lib/index.js +562 -0
  54. package/dist/lib/oss.js +43 -0
  55. package/dist/lib/s3oss.js +33 -0
  56. package/dist/mcp/mcp-server.js +26 -0
  57. package/dist/mcp/src/config/database.js +51 -0
  58. package/dist/mcp/src/index.js +238 -0
  59. package/dist/mcp/src/mcp/schemas.js +178 -0
  60. package/dist/mcp/src/mcp/server.js +421 -0
  61. package/dist/mcp/src/mcp/streamable-server.js +690 -0
  62. package/dist/mcp/src/models/ChatMessage.js +151 -0
  63. package/dist/mcp/src/models/Friend.js +64 -0
  64. package/dist/mcp/src/models/Group.js +55 -0
  65. package/dist/mcp/src/models/GroupMember.js +67 -0
  66. package/dist/mcp/src/models/index.js +27 -0
  67. package/dist/mcp/src/scripts/migrate.js +21 -0
  68. package/dist/mcp/src/services/ChatDataService.js +284 -0
  69. package/dist/mcp/src/services/McpService.js +521 -0
  70. package/dist/mcp/src/services/McpTools.js +504 -0
  71. package/dist/mcp/streamable-examples.js +283 -0
  72. package/dist/mcp/streamable-server.js +79 -0
  73. package/dist/mcp/test-mcp.js +64 -0
  74. package/dist/mcp/test-streamable-server.js +86 -0
  75. package/dist/package-json.js +89 -0
  76. package/dist/proxy/aibotk.js +829 -0
  77. package/dist/proxy/api.js +431 -0
  78. package/dist/proxy/apib.js +587 -0
  79. package/dist/proxy/bot/chatgpt.js +38 -0
  80. package/dist/proxy/bot/coze.js +38 -0
  81. package/dist/proxy/bot/cozev3.js +38 -0
  82. package/dist/proxy/bot/dify.js +38 -0
  83. package/dist/proxy/bot/dispatch.js +81 -0
  84. package/dist/proxy/bot/fastgpt.js +27 -0
  85. package/dist/proxy/bot/qany.js +27 -0
  86. package/dist/proxy/config.js +14 -0
  87. package/dist/proxy/cozeAi.js +60 -0
  88. package/dist/proxy/cozeV3Ai.js +60 -0
  89. package/dist/proxy/difyAi.js +58 -0
  90. package/dist/proxy/fastgpt.js +55 -0
  91. package/dist/proxy/mqtt.js +275 -0
  92. package/dist/proxy/multimodal.js +122 -0
  93. package/dist/proxy/openAi.js +63 -0
  94. package/dist/proxy/outapi.js +62 -0
  95. package/dist/proxy/qAnyAi.js +57 -0
  96. package/dist/proxy/superagent.js +200 -0
  97. package/dist/proxy/tencent-open.js +255 -0
  98. package/dist/service/event-dispatch-service.js +309 -0
  99. package/dist/service/gpt4vService.js +45 -0
  100. package/dist/service/msg-filter-service.js +121 -0
  101. package/dist/service/msg-filters.js +645 -0
  102. package/dist/service/room-async-service.js +455 -0
  103. package/dist/task/index.js +535 -0
  104. package/dist/task/rss.js +174 -0
  105. package/package.json +2 -2
  106. package/src/package-json.js +2 -2
  107. package/tsconfig.json +3 -12
  108. package/dist/index.d.ts +0 -9
  109. package/tsconfig.cjs.json +0 -12
@@ -0,0 +1,167 @@
1
+ import { CozeAPI } from './sdk/coze.js';
2
+ import { addAichatRecord } from '../db/aichatDb.js';
3
+ import { getPromotInfo } from '../proxy/aibotk.js';
4
+ import { ContentCensor } from '../lib/contentCensor.js';
5
+ import { getPuppetEol, isWindowsPlatform } from '../const/puppet-type.js';
6
+ import dayjs from 'dayjs';
7
+ import { extractImageLinks } from '../lib/index.js';
8
+ import nodeFetch from 'node-fetch';
9
+ import { getText2Speech } from "../proxy/multimodal.js";
10
+ class CozeAi {
11
+ constructor(config = {
12
+ token: '', // api 秘钥
13
+ botId: '', // botId
14
+ proxyPass: '', // 请求地址
15
+ showQuestion: true, // 显示原文
16
+ showSuggestions: false, // 显示建议问题
17
+ timeoutMs: 180, // 超时时间 s
18
+ promotId: '',
19
+ systemMessage: '' // 预设promotion
20
+ }) {
21
+ this.cozeChat = null;
22
+ this.config = { ...config };
23
+ this.contentCensor = null;
24
+ this.chatOption = {};
25
+ this.eol = '\n';
26
+ this.iswindows = false;
27
+ }
28
+ async init() {
29
+ this.eol = await getPuppetEol();
30
+ this.iswindows = await isWindowsPlatform();
31
+ if (this.config.promotId) {
32
+ const promotInfo = await getPromotInfo(this.config.promotId);
33
+ if (promotInfo) {
34
+ this.config.systemMessage = promotInfo.promot;
35
+ }
36
+ }
37
+ if (this.config.filter) {
38
+ this.contentCensor = new ContentCensor(this.config.filterConfig);
39
+ }
40
+ const baseOptions = {
41
+ apiKey: this.config.token,
42
+ apiBaseUrl: this.config.proxyPass,
43
+ debug: !!this.config.debug,
44
+ botId: this.config.botId,
45
+ systemMessage: this.config.systemMessage || ''
46
+ };
47
+ console.log(`api请求地址:${this.config.proxyPass}`);
48
+ this.cozeChat = new CozeAPI({
49
+ ...baseOptions,
50
+ fetch: (url, options = {}) => {
51
+ const mergedOptions = {
52
+ ...options
53
+ };
54
+ return nodeFetch(url, mergedOptions);
55
+ }
56
+ });
57
+ }
58
+ /**
59
+ * 重置apikey
60
+ * @return {Promise<void>}
61
+ */
62
+ reset() {
63
+ this.cozeChat = null;
64
+ }
65
+ async getReply(content, uid, adminId = '', systemMessage = '') {
66
+ try {
67
+ if (!this.cozeChat) {
68
+ console.log('启用Coze对话平台');
69
+ await this.init();
70
+ }
71
+ if (this.config.filter) {
72
+ const censor = await this.contentCensor.checkText(content);
73
+ if (!censor) {
74
+ console.log(`问题:${content},包含违规词,已拦截`);
75
+ return [{ type: 1, content: '这个话题不适合讨论,换个话题吧。' }];
76
+ }
77
+ }
78
+ if (systemMessage || content === 'reset' || content === '重置') {
79
+ console.log('重新更新上下文对话');
80
+ this.chatOption[uid] = {};
81
+ if (content === 'reset' || content === '重置') {
82
+ return [{ type: 1, content: '上下文已重置' }];
83
+ }
84
+ }
85
+ const { conversationId, text, id, suggestions } = systemMessage ? await this.cozeChat.sendMessage(content, {
86
+ ...this.chatOption[uid],
87
+ systemMessage,
88
+ timeoutMs: this.config.timeoutMs * 1000 || 180 * 1000,
89
+ user: uid
90
+ }) : await this.cozeChat.sendMessage(content, {
91
+ ...this.chatOption[uid],
92
+ timeoutMs: this.config.timeoutMs * 1000 || 180 * 1000,
93
+ user: uid
94
+ });
95
+ if (this.config.filter) {
96
+ const censor = await this.contentCensor.checkText(text);
97
+ if (!censor) {
98
+ console.log(`回复: ${text},包含违规词,已拦截`);
99
+ return [{ type: 1, content: '这个话题不适合讨论,换个话题吧。' }];
100
+ }
101
+ }
102
+ if (this.config.record) {
103
+ void addAichatRecord({
104
+ contactId: uid,
105
+ adminId,
106
+ input: content,
107
+ output: text,
108
+ time: dayjs().format('YYYY-MM-DD HH:mm:ss')
109
+ });
110
+ }
111
+ // 保存对话id 对于同一个用户的对话不更新conversationId
112
+ this.chatOption[uid] = {
113
+ conversationId,
114
+ parentMessageId: id
115
+ };
116
+ let replys = [];
117
+ if (this.config?.openTTS) {
118
+ replys = await getText2Speech(text, this.config.ttsConfig);
119
+ if (replys.length) {
120
+ return replys;
121
+ }
122
+ }
123
+ let message;
124
+ if (this.config.showQuestion) {
125
+ message = `${content}${this.eol}-----------${this.eol}` + (this.iswindows ? text.replaceAll('\n', this.eol) : text);
126
+ }
127
+ else {
128
+ message = this.iswindows ? text.replaceAll('\n', this.eol) : text;
129
+ }
130
+ if (this.config.showSuggestions) {
131
+ console.log('suggestions', suggestions);
132
+ message = `${message}${this.eol}-----------${this.eol}建议问答:${this.eol}` + suggestions?.map(item => item.content).join(this.eol);
133
+ }
134
+ let imgs = [];
135
+ if (this.config.filterLinkContent) {
136
+ const filterRes = extractImageLinks(message, true);
137
+ imgs = filterRes.imageReplys;
138
+ message = filterRes.content;
139
+ }
140
+ else {
141
+ imgs = extractImageLinks(message);
142
+ }
143
+ while (message.length > 1500) {
144
+ replys.push(message.slice(0, 1500));
145
+ message = message.slice(1500);
146
+ }
147
+ replys.push(message);
148
+ replys = replys.map(item => {
149
+ return {
150
+ type: 1,
151
+ content: item.trim()
152
+ };
153
+ });
154
+ if (imgs.length) {
155
+ console.log('提取到内容中的图片', imgs);
156
+ replys = replys.concat(imgs);
157
+ }
158
+ return replys;
159
+ }
160
+ catch (e) {
161
+ console.log('Coze 请求报错:' + e);
162
+ return [];
163
+ }
164
+ }
165
+ }
166
+ export default CozeAi;
167
+ //# sourceMappingURL=coze.js.map
@@ -0,0 +1,157 @@
1
+ import { CozeV3Api } from '../bot/coze/sdk/index.js';
2
+ import { addAichatRecord } from '../db/aichatDb.js';
3
+ import { getPromotInfo } from '../proxy/aibotk.js';
4
+ import { ContentCensor } from '../lib/contentCensor.js';
5
+ import { getPuppetEol, isWindowsPlatform } from '../const/puppet-type.js';
6
+ import dayjs from 'dayjs';
7
+ import { extractImageLinks } from '../lib/index.js';
8
+ import { getText2Speech } from '../proxy/multimodal.js';
9
+ class CozeV3Ai {
10
+ constructor(config = {
11
+ botId: '',
12
+ isAiAgent: false, // 是否为 ai agent 模式
13
+ showDownloadUrl: false, // 显示文件下载链接
14
+ token: '', // api 秘钥
15
+ proxyPass: '', // 请求地址
16
+ showQuestion: true, // 显示原文
17
+ timeoutMs: 60, // 超时时间 s
18
+ promotId: '',
19
+ systemMessage: '', // 预设promotion
20
+ }) {
21
+ this.cozeV3Chat = null;
22
+ this.config = { showDownloadUrl: false, isAiAgent: false, ...config };
23
+ this.contentCensor = null;
24
+ this.chatOption = {};
25
+ this.eol = '\n';
26
+ this.iswindows = false;
27
+ }
28
+ async init() {
29
+ this.eol = await getPuppetEol();
30
+ this.iswindows = await isWindowsPlatform();
31
+ if (this.config.promotId) {
32
+ const promotInfo = await getPromotInfo(this.config.promotId);
33
+ if (promotInfo) {
34
+ this.config.systemMessage = promotInfo.promot;
35
+ }
36
+ }
37
+ if (this.config.filter) {
38
+ this.contentCensor = new ContentCensor(this.config.filterConfig);
39
+ }
40
+ const baseOptions = {
41
+ baseUrl: this.config.proxyPass,
42
+ apiKey: this.config.token,
43
+ botId: this.config.botId,
44
+ stream: this.config.stream,
45
+ debug: !!this.config.debug,
46
+ systemMessage: this.config.systemMessage || '',
47
+ };
48
+ console.log(`api请求地址:${this.config.proxyPass}`);
49
+ this.cozeV3Chat = new CozeV3Api({
50
+ ...baseOptions,
51
+ });
52
+ }
53
+ /**
54
+ * 重置apikey
55
+ * @return {Promise<void>}
56
+ */
57
+ reset() {
58
+ this.cozeV3Chat = null;
59
+ }
60
+ async getReply({ content, inputs, file }, id, adminId = '', systemMessage = '') {
61
+ try {
62
+ console.log('启用Coze v3版本对话平台');
63
+ if (!this.cozeV3Chat) {
64
+ await this.init();
65
+ }
66
+ if (this.config.filter) {
67
+ const censor = await this.contentCensor.checkText(content);
68
+ if (!censor) {
69
+ console.log(`问题:${content},包含违规词,已拦截`);
70
+ return [{ type: 1, content: '这个话题不适合讨论,换个话题吧。' }];
71
+ }
72
+ }
73
+ if (systemMessage || content === 'reset' || content === '重置') {
74
+ console.log('重新更新上下文对话');
75
+ this.chatOption[id] = {};
76
+ if (content === 'reset' || content === '重置') {
77
+ return [{ type: 1, content: '上下文已重置' }];
78
+ }
79
+ }
80
+ const { conversationId, text, messages } = systemMessage
81
+ ? await this.cozeV3Chat.sendMessage({ query: content, file }, { ...this.chatOption[id], variables: inputs, systemMessage, timeoutMs: this.config.timeoutMs * 1000 || 80 * 1000, user: id })
82
+ : await this.cozeV3Chat.sendMessage({ query: content, file }, { ...this.chatOption[id], variables: inputs, timeoutMs: this.config.timeoutMs * 1000 || 80 * 1000, user: id });
83
+ const allReplys = [];
84
+ for (let item of messages) {
85
+ const res = await this.setReply({ text: item, id, adminId, content, conversationId });
86
+ if (res.length) {
87
+ allReplys.push(...res);
88
+ }
89
+ }
90
+ console.log('allReplys', allReplys);
91
+ return allReplys;
92
+ }
93
+ catch (e) {
94
+ console.log('Coze V3 请求报错:' + e);
95
+ return [];
96
+ }
97
+ }
98
+ async setReply({ text, id, adminId, content, conversationId }) {
99
+ if (this.config.filter) {
100
+ const censor = await this.contentCensor.checkText(text);
101
+ if (!censor) {
102
+ console.log(`回复: ${text},包含违规词,已拦截`);
103
+ return [{ type: 1, content: '这个话题不适合讨论,换个话题吧。' }];
104
+ }
105
+ }
106
+ if (this.config.record) {
107
+ void addAichatRecord({ contactId: id, adminId, input: content, output: text, time: dayjs().format('YYYY-MM-DD HH:mm:ss') });
108
+ }
109
+ // 保存对话id 对于同一个用户的对话不更新conversationId
110
+ if (!this.chatOption[id]?.conversationId) {
111
+ this.chatOption[id] = {
112
+ conversationId,
113
+ };
114
+ }
115
+ let replys = [];
116
+ if (this.config?.openTTS) {
117
+ replys = await getText2Speech(text, this.config.ttsConfig);
118
+ if (replys.length) {
119
+ return replys;
120
+ }
121
+ }
122
+ let message;
123
+ if (this.config.showQuestion) {
124
+ message = `${content}${this.eol}-----------${this.eol}` + (this.iswindows ? text.replaceAll('\n', this.eol) : text);
125
+ }
126
+ else {
127
+ message = this.iswindows ? text.replaceAll('\n', this.eol) : text;
128
+ }
129
+ let imgs = [];
130
+ if (this.config.filterLinkContent) {
131
+ const filterRes = extractImageLinks(message, true);
132
+ imgs = filterRes.imageReplys;
133
+ message = filterRes.content;
134
+ }
135
+ else {
136
+ imgs = extractImageLinks(message);
137
+ }
138
+ while (message.length > 1500) {
139
+ replys.push(message.slice(0, 1500));
140
+ message = message.slice(1500);
141
+ }
142
+ replys.push(message);
143
+ replys = replys.map((item) => {
144
+ return {
145
+ type: 1,
146
+ content: item.trim(),
147
+ };
148
+ });
149
+ if (imgs.length) {
150
+ console.log('提取到内容中的图片', imgs);
151
+ replys = replys.concat(imgs);
152
+ }
153
+ return replys;
154
+ }
155
+ }
156
+ export default CozeV3Ai;
157
+ //# sourceMappingURL=cozev3.js.map
@@ -0,0 +1,160 @@
1
+ import { ChatClient } from "./sdk/difyClient.js";
2
+ import { addAichatRecord } from "../db/aichatDb.js";
3
+ import { getPromotInfo } from "../proxy/aibotk.js";
4
+ import { ContentCensor } from "../lib/contentCensor.js";
5
+ import { getPuppetEol, isWindowsPlatform } from '../const/puppet-type.js';
6
+ import dayjs from "dayjs";
7
+ import { extractImageLinks } from '../lib/index.js';
8
+ import { getText2Speech } from "../proxy/multimodal.js";
9
+ class DifyAi {
10
+ constructor(config = {
11
+ isAiAgent: false, // 是否为 ai agent 模式
12
+ showDownloadUrl: false, // 显示文件下载链接
13
+ token: '', // api 秘钥
14
+ proxyPass: '', // 请求地址
15
+ showQuestion: true, // 显示原文
16
+ timeoutMs: 60, // 超时时间 s
17
+ promotId: '',
18
+ systemMessage: '', // 预设promotion
19
+ }) {
20
+ this.difyChat = null;
21
+ this.config = { showDownloadUrl: false, isAiAgent: false, ...config };
22
+ this.contentCensor = null;
23
+ this.chatOption = {};
24
+ this.eol = '\n';
25
+ this.iswindows = false;
26
+ }
27
+ async init() {
28
+ this.eol = await getPuppetEol();
29
+ this.iswindows = await isWindowsPlatform();
30
+ if (this.config.promotId) {
31
+ const promotInfo = await getPromotInfo(this.config.promotId);
32
+ if (promotInfo) {
33
+ this.config.systemMessage = promotInfo.promot;
34
+ }
35
+ }
36
+ if (this.config.filter) {
37
+ this.contentCensor = new ContentCensor(this.config.filterConfig);
38
+ }
39
+ const baseOptions = {
40
+ apiKey: this.config.token,
41
+ stream: this.config.isAiAgent,
42
+ debug: !!this.config.debug,
43
+ systemMessage: this.config.systemMessage || '',
44
+ };
45
+ console.log(`api请求地址:${this.config.proxyPass}`);
46
+ this.difyChat = new ChatClient({
47
+ ...baseOptions,
48
+ baseUrl: this.config.proxyPass,
49
+ });
50
+ }
51
+ /**
52
+ * 重置apikey
53
+ * @return {Promise<void>}
54
+ */
55
+ reset() {
56
+ this.difyChat = null;
57
+ }
58
+ async getReply({ content, file, inputs }, id, adminId = '', systemMessage = '') {
59
+ try {
60
+ if (!this.difyChat) {
61
+ console.log('启用Dify对话平台');
62
+ await this.init();
63
+ }
64
+ if (this.config.filter) {
65
+ const censor = await this.contentCensor.checkText(content);
66
+ if (!censor) {
67
+ console.log(`问题:${content},包含违规词,已拦截`);
68
+ return [{ type: 1, content: '这个话题不适合讨论,换个话题吧。' }];
69
+ }
70
+ }
71
+ if (systemMessage || content === 'reset' || content === '重置') {
72
+ console.log('重新更新上下文对话');
73
+ this.chatOption[id] = {};
74
+ if (content === 'reset' || content === '重置') {
75
+ return [{ type: 1, content: '上下文已重置' }];
76
+ }
77
+ }
78
+ let { conversationId, text, files } = systemMessage ? await this.difyChat.sendMessage({ query: content, file }, { ...this.chatOption[id], inputs, systemMessage, timeoutMs: this.config.timeoutMs * 1000 || 80 * 1000, user: id }) : await this.difyChat.sendMessage({ query: content, file }, { ...this.chatOption[id], inputs, timeoutMs: this.config.timeoutMs * 1000 || 80 * 1000, user: id });
79
+ if (this.config.ignoreFiles) {
80
+ console.log('忽略dify返回的文件');
81
+ files = [];
82
+ }
83
+ if (this.config.filter) {
84
+ const censor = await this.contentCensor.checkText(text);
85
+ if (!censor) {
86
+ console.log(`回复: ${text},包含违规词,已拦截`);
87
+ return [{ type: 1, content: '这个话题不适合讨论,换个话题吧。' }];
88
+ }
89
+ }
90
+ if (this.config.record) {
91
+ void addAichatRecord({ contactId: id, adminId, input: content, output: text, time: dayjs().format('YYYY-MM-DD HH:mm:ss') });
92
+ }
93
+ // 保存对话id 对于同一个用户的对话不更新conversationId
94
+ if (!this.chatOption[id]?.conversationId) {
95
+ this.chatOption[id] = {
96
+ conversationId
97
+ };
98
+ }
99
+ let replys = [];
100
+ console.log('是否开启语音', this.config?.openTTS);
101
+ if (this.config?.openTTS) {
102
+ replys = await getText2Speech(text, this.config.ttsConfig);
103
+ if (replys.length) {
104
+ return replys;
105
+ }
106
+ }
107
+ let message;
108
+ if (this.config.showQuestion) {
109
+ message = `${content}${this.eol}-----------${this.eol}` + (this.iswindows ? text.replaceAll('\n', this.eol) : text);
110
+ }
111
+ else {
112
+ message = this.iswindows ? text.replaceAll('\n', this.eol) : text;
113
+ }
114
+ let imgs = [];
115
+ if (this.config.filterLinkContent) {
116
+ const filterRes = extractImageLinks(message, true);
117
+ imgs = filterRes.imageReplys;
118
+ message = filterRes.content;
119
+ }
120
+ else {
121
+ imgs = extractImageLinks(message);
122
+ }
123
+ while (message.length > 1500) {
124
+ replys.push(message.slice(0, 1500));
125
+ message = message.slice(1500);
126
+ }
127
+ replys.push(message);
128
+ replys = replys.map(item => {
129
+ return {
130
+ type: 1,
131
+ content: item.trim()
132
+ };
133
+ });
134
+ if (!imgs.length && files.length && this.config.showDownloadUrl) {
135
+ let downLoadUrl = `----------------${this.eol}`;
136
+ files.forEach((item, index) => {
137
+ downLoadUrl += `[下载${index + 1}]:${item}${this.eol}`;
138
+ });
139
+ replys[replys.length - 1].content = `${replys[replys.length - 1].content}${this.eol}${this.eol}${downLoadUrl}`;
140
+ }
141
+ if (imgs.length) {
142
+ console.log('提取到内容中的图片', imgs);
143
+ replys = replys.concat(imgs);
144
+ }
145
+ if (files.length) {
146
+ console.log('回复内容带文件', files);
147
+ files.forEach(item => {
148
+ replys.push({ type: 2, url: item });
149
+ });
150
+ }
151
+ return replys;
152
+ }
153
+ catch (e) {
154
+ console.log('Dify 请求报错:' + e);
155
+ return [];
156
+ }
157
+ }
158
+ }
159
+ export default DifyAi;
160
+ //# sourceMappingURL=dify.js.map
@@ -0,0 +1,130 @@
1
+ import { FastGPTAPI } from '../bot/fastgpt/index.js';
2
+ import { addAichatRecord } from '../db/aichatDb.js';
3
+ import { ContentCensor } from '../lib/contentCensor.js';
4
+ import { getPuppetEol, isWindowsPlatform } from '../const/puppet-type.js';
5
+ import { v4 as uuidv4 } from 'uuid';
6
+ import dayjs from 'dayjs';
7
+ import { extractImageLinks } from '../lib/index.js';
8
+ import { getText2Speech } from '../proxy/multimodal.js';
9
+ class FastGPTAi {
10
+ constructor(config = {
11
+ token: '', // token
12
+ debug: 0, // 开启调试
13
+ proxyPass: '', // 反向代理地址
14
+ showQuestion: true, // 显示原文
15
+ timeoutMs: 60, // 超时时间 s
16
+ }) {
17
+ this.fastGPT = null;
18
+ this.config = config;
19
+ this.contentCensor = null;
20
+ this.chatOption = {};
21
+ this.eol = '\n';
22
+ this.iswindows = false;
23
+ }
24
+ async init() {
25
+ this.eol = await getPuppetEol();
26
+ this.iswindows = await isWindowsPlatform();
27
+ if (this.config.filter) {
28
+ this.contentCensor = new ContentCensor(this.config.filterConfig);
29
+ }
30
+ console.log(`请求地址:${this.config.proxyPass}`);
31
+ const baseOptions = {
32
+ apiKey: this.config.token,
33
+ debug: this.config.debug,
34
+ apiBaseUrl: this.config.proxyPass,
35
+ };
36
+ this.fastGPT = new FastGPTAPI(baseOptions);
37
+ }
38
+ /**
39
+ * 重置apikey
40
+ * @return {Promise<void>}
41
+ */
42
+ reset() {
43
+ this.fastGPT = null;
44
+ }
45
+ async getReply({ content, file, uid, adminId = '', variables }) {
46
+ try {
47
+ if (!this.fastGPT) {
48
+ console.log('看到此消息说明已启用FastGPT');
49
+ await this.init();
50
+ }
51
+ if (this.config.filter) {
52
+ const censor = await this.contentCensor.checkText(content);
53
+ if (!censor) {
54
+ console.log(`问题:${content},包含违规词,已拦截`);
55
+ return [{ type: 1, content: '这个话题不适合讨论,换个话题吧。' }];
56
+ }
57
+ }
58
+ const resetWord = ['reset', '重置', '重置对话', '忽略上下文', '重置上下文', '重新开始', '清除对话', '清除上下文'];
59
+ if (resetWord.includes(content)) {
60
+ console.log('重新更新上下文对话');
61
+ this.chatOption[uid] = null;
62
+ return [{ type: 1, content: '上下文已重置' }];
63
+ }
64
+ if (!this.chatOption[uid]) {
65
+ this.chatOption[uid] = {
66
+ chatId: uuidv4(),
67
+ };
68
+ }
69
+ const sendParams = { ...this.chatOption[uid], variables, timeoutMs: this.config.timeoutMs * 1000 || 80 * 1000 };
70
+ console.log('FastGPT sendParams---', sendParams);
71
+ const { text, id } = await this.fastGPT.sendMessage({ text: content, file }, sendParams);
72
+ if (this.config.filter) {
73
+ const censor = await this.contentCensor.checkText(text);
74
+ if (!censor) {
75
+ console.log(`回复: ${text},包含违规词,已拦截`);
76
+ return [{ type: 1, content: '这个话题不适合讨论,换个话题吧。' }];
77
+ }
78
+ }
79
+ if (this.config.record) {
80
+ void addAichatRecord({ contactId: uid, adminId, input: content, output: text, time: dayjs().format('YYYY-MM-DD HH:mm:ss') });
81
+ }
82
+ let replys = [];
83
+ if (this.config?.openTTS) {
84
+ replys = await getText2Speech(text, this.config.ttsConfig);
85
+ if (replys.length) {
86
+ return replys;
87
+ }
88
+ }
89
+ let message;
90
+ if (this.config.showQuestion) {
91
+ message = `${content}${this.eol}-----------${this.eol}` + (this.iswindows ? text.replaceAll('\n', this.eol) : text);
92
+ }
93
+ else {
94
+ message = this.iswindows ? text.replaceAll('\n', this.eol) : text;
95
+ }
96
+ let imgs = [];
97
+ if (this.config.filterLinkContent) {
98
+ const filterRes = extractImageLinks(message, true);
99
+ imgs = filterRes.imageReplys;
100
+ message = filterRes.content;
101
+ }
102
+ else {
103
+ imgs = extractImageLinks(message);
104
+ }
105
+ console.log('imgs', imgs);
106
+ while (message.length > 1500) {
107
+ replys.push(message.slice(0, 1500));
108
+ message = message.slice(1500);
109
+ }
110
+ replys.push(message);
111
+ replys = replys.map((item) => {
112
+ return {
113
+ type: 1,
114
+ content: item.trim(),
115
+ };
116
+ });
117
+ if (imgs.length) {
118
+ console.log('提取到内容中的图片', imgs);
119
+ replys = replys.concat(imgs);
120
+ }
121
+ return replys;
122
+ }
123
+ catch (e) {
124
+ console.log('FastGPT报错:' + e);
125
+ return [];
126
+ }
127
+ }
128
+ }
129
+ export default FastGPTAi;
130
+ //# sourceMappingURL=fastgpt.js.map