alemonjs-aichat 1.0.12 → 1.0.13
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/lib/api.js +40 -0
- package/lib/config.js +51 -0
- package/lib/data/help.json.js +1 -1
- package/lib/response/config/res.js +1 -1
- package/lib/response/setting/res.js +28 -3
- package/lib/response/zreply/res.js +20 -14
- package/package.json +3 -3
package/lib/api.js
CHANGED
|
@@ -230,6 +230,7 @@ const availableTools = {
|
|
|
230
230
|
return images;
|
|
231
231
|
}
|
|
232
232
|
},
|
|
233
|
+
/** 使用 Stable Diffusion 将图片转换为提示词 */
|
|
233
234
|
StableDiffusionImageToPrompt: async ({ image_url }) => {
|
|
234
235
|
// 先查看redis中是否有这张图的缓存
|
|
235
236
|
const cacheKey = `image:caption:${image_url}`;
|
|
@@ -287,6 +288,45 @@ const availableTools = {
|
|
|
287
288
|
console.log("图片提示词:", prompt);
|
|
288
289
|
return prompt;
|
|
289
290
|
},
|
|
291
|
+
/** 搜索survivalcraft(生存战争)论坛的帖子 */
|
|
292
|
+
SearchScbbsPost: async ({ keyword }) => {
|
|
293
|
+
const api = `https://m.suancaixianyu.cn/api/post/list?title=${encodeURIComponent(keyword)}`;
|
|
294
|
+
try {
|
|
295
|
+
const response = await fetch(api);
|
|
296
|
+
if (!response.ok) {
|
|
297
|
+
return [];
|
|
298
|
+
}
|
|
299
|
+
const data = await response.json();
|
|
300
|
+
return data.data.list.map((item) => ({
|
|
301
|
+
viewUrl: `https://test.suancaixianyu.cn/#/postDetails/${item.id}`,
|
|
302
|
+
...item,
|
|
303
|
+
}));
|
|
304
|
+
}
|
|
305
|
+
catch (error) {
|
|
306
|
+
console.error("Error searching posts:", error);
|
|
307
|
+
return [];
|
|
308
|
+
}
|
|
309
|
+
},
|
|
310
|
+
/** 使用搜索引擎搜索网页 */
|
|
311
|
+
SearchWeb: async ({ keyword, engine = "baidu", cc = "CN", type = "organic_results", }) => {
|
|
312
|
+
const apikey = value.searchApiKey ||
|
|
313
|
+
"63706fc3e6827a90e8219913297b510ff053d5238b24f64251a066e4ecea7408";
|
|
314
|
+
const api = `https://serpapi.com/search.json?engine=${engine}&q=${encodeURIComponent(keyword)}&cc=${cc}&api_key=${apikey}`;
|
|
315
|
+
try {
|
|
316
|
+
const response = await fetch(api);
|
|
317
|
+
if (!response.ok) {
|
|
318
|
+
return [];
|
|
319
|
+
}
|
|
320
|
+
const data = await response.json();
|
|
321
|
+
console.log("搜索结果", data);
|
|
322
|
+
const results = data[type] || [];
|
|
323
|
+
return type === "organic_results" ? results.slice(0, 7) : results;
|
|
324
|
+
}
|
|
325
|
+
catch (error) {
|
|
326
|
+
console.error("Error searching web:", error);
|
|
327
|
+
return [];
|
|
328
|
+
}
|
|
329
|
+
},
|
|
290
330
|
};
|
|
291
331
|
|
|
292
332
|
export { TTSClient, availableTools, getTimeString, uploadImage };
|
package/lib/config.js
CHANGED
|
@@ -226,6 +226,57 @@ const tools = [
|
|
|
226
226
|
},
|
|
227
227
|
},
|
|
228
228
|
},
|
|
229
|
+
{
|
|
230
|
+
type: "function",
|
|
231
|
+
function: {
|
|
232
|
+
name: "SearchScbbsPost",
|
|
233
|
+
description: "搜索《survivalcraft》(译名《生存战争》,也简称sc)论坛的帖子, 搜索时请尽量提供精确的关键词, 关键词最好只有一个. 在这里可以搜索到sc这个游戏相关的各种模组等资源或教程帖子和更新公告等内容, 但请注意不要搜索与游戏无关的内容, 否则可能会得到不相关的结果,若是搜索不到请减少关键词的数量或更换关键词",
|
|
234
|
+
parameters: {
|
|
235
|
+
type: "object",
|
|
236
|
+
properties: {
|
|
237
|
+
keyword: {
|
|
238
|
+
type: "string",
|
|
239
|
+
description: "搜索关键词",
|
|
240
|
+
},
|
|
241
|
+
},
|
|
242
|
+
required: ["keyword"],
|
|
243
|
+
},
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
type: "function",
|
|
248
|
+
function: {
|
|
249
|
+
name: "SearchWeb",
|
|
250
|
+
description: "使用搜索引擎搜索网页内容, 你可以使用这个工具来获取最新的资讯或数据, 但请注意不要搜索敏感或违法的内容, 否则可能会得到不相关的结果, 此外,不推荐使用该工具搜索与sc这个游戏相关的内容, 因为搜索引擎的结果可能不如专门的游戏论坛或社区来的准确和有用, 在搜索时请尽量提供精确的关键词, 关键词最好只有一个. 如果你想搜索与游戏相关的内容, 建议使用SearchScbbsPost工具来搜索survivalcraft(生存战争)论坛的帖子",
|
|
251
|
+
parameters: {
|
|
252
|
+
type: "object",
|
|
253
|
+
properties: {
|
|
254
|
+
keyword: {
|
|
255
|
+
type: "string",
|
|
256
|
+
description: "搜索关键词",
|
|
257
|
+
},
|
|
258
|
+
engine: {
|
|
259
|
+
type: "string",
|
|
260
|
+
description: "选择搜索引擎",
|
|
261
|
+
enum: ["bing", "google", "baidu"],
|
|
262
|
+
default: "baidu",
|
|
263
|
+
},
|
|
264
|
+
cc: {
|
|
265
|
+
type: "string",
|
|
266
|
+
description: "搜索国家/地区代码, 例如搜索美国就填us, 搜索中国就填cn, 搜索日本就填jp, 这个参数会影响搜索结果的地域性",
|
|
267
|
+
default: "CN",
|
|
268
|
+
},
|
|
269
|
+
type: {
|
|
270
|
+
type: "string",
|
|
271
|
+
description: "选择结果类型, 搜索后获取对应结果, 建议使用自然结果organic_results, 其他选项可能不存在",
|
|
272
|
+
enum: ["organic_results", "related_questions", "related_searches"],
|
|
273
|
+
default: "organic_results",
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
required: ["keyword"],
|
|
277
|
+
},
|
|
278
|
+
},
|
|
279
|
+
},
|
|
229
280
|
];
|
|
230
281
|
|
|
231
282
|
export { addAI, addAIChatHistory, addPrompt, affectionSwitch, clearAIChatHistory, defaultAIConfig, deleteAI, deletePrompt, getAIChatHistory, getAIConfig, getAIList, getAffectionLevel, getAffectionLevelAll, getPromptList, incrementAffectionLevel, resetAffectionLevel, resetAllAffectionLevels, setAffectionLevel, setBotID, switchAI, switchPrompt, systemPrompt, tools };
|
package/lib/data/help.json.js
CHANGED
|
@@ -3,7 +3,7 @@ import { useMessage, Text } from 'alemonjs';
|
|
|
3
3
|
import { Regular } from 'alemonjs/utils';
|
|
4
4
|
|
|
5
5
|
const selects = onSelects(["message.create", "private.message.create"]);
|
|
6
|
-
const regular$1 =
|
|
6
|
+
const regular$1 = /^(\/|#)(ai配置|当前提示词|查看提示词)$/i;
|
|
7
7
|
const regular$2 = /(\/|#)ai列表$/i;
|
|
8
8
|
const regular$3 = /(\/|#)提示词列表$/i;
|
|
9
9
|
const regular$4 = /(\/|#)清空对话$/i;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { addAI, switchAI, addPrompt, deletePrompt, switchPrompt, deleteAI, affectionSwitch, getAIList, getAIConfig } from '../../config.js';
|
|
2
2
|
import { redis } from '../../redis.js';
|
|
3
|
-
import { useMessage, Text
|
|
3
|
+
import { useMessage, Text } from 'alemonjs';
|
|
4
4
|
import { Regular } from 'alemonjs/utils';
|
|
5
5
|
|
|
6
6
|
const selects = onSelects(["message.create", "private.message.create"]);
|
|
@@ -18,8 +18,9 @@ const regular$13 = /(\/|#)(开启|关闭)聊天$/i;
|
|
|
18
18
|
const regular$14 = /(\/|#)(开启|关闭)语音回复$/i;
|
|
19
19
|
const regular$15 = /(\/|#)(开启|关闭)(MCP)?工具$/i;
|
|
20
20
|
const regular$16 = /(\/|#)切换图床(.*)$/i;
|
|
21
|
+
const regular$17 = /(\/|#)修改 ?(.+) ?模型 ?(.+)$/i;
|
|
21
22
|
const test = /(\/|#)测试$/i;
|
|
22
|
-
const regular = Regular.or(regular$1, regular$2, regular$3, regular$4, regular$5, regular$6, regular$7, regular$8, regular$10, regular$11, regular$13, regular$14, regular$15, regular$16, test);
|
|
23
|
+
const regular = Regular.or(regular$1, regular$2, regular$3, regular$4, regular$5, regular$6, regular$7, regular$8, regular$10, regular$11, regular$13, regular$14, regular$15, regular$16, regular$17, test);
|
|
23
24
|
var res = onResponse(selects, async (e, next) => {
|
|
24
25
|
// 创建
|
|
25
26
|
const [message] = useMessage(e);
|
|
@@ -28,7 +29,7 @@ var res = onResponse(selects, async (e, next) => {
|
|
|
28
29
|
// uploadImageToR2("./public/image_out/1769259547338.jpg").then((url) => {
|
|
29
30
|
// console.log("上传成功,图片URL:", url);
|
|
30
31
|
// });
|
|
31
|
-
message.send(format(Text("测试消息")
|
|
32
|
+
message.send(format(Text("测试消息")));
|
|
32
33
|
// const a = await availableTools.StableDiffusionGenerateImage({
|
|
33
34
|
// prompt: "a cat playing with a ball",
|
|
34
35
|
// });
|
|
@@ -217,6 +218,30 @@ var res = onResponse(selects, async (e, next) => {
|
|
|
217
218
|
message.send(format(Text(`已切换图床至 ${bedName.trim()} !`)));
|
|
218
219
|
return;
|
|
219
220
|
}
|
|
221
|
+
// 修改指定ai的模型
|
|
222
|
+
if (regular$17.test(e.msg)) {
|
|
223
|
+
const match = e.msg.match(regular$17);
|
|
224
|
+
if (!match) {
|
|
225
|
+
message.send(format(Text("格式错误,请按照 格式:/修改 <AI名称> 模型 <模型名称> 进行设置")));
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
const [, , aiName, modelName] = match;
|
|
229
|
+
const aiList = await getAIList();
|
|
230
|
+
if (!aiList.includes(aiName.trim())) {
|
|
231
|
+
message.send(format(Text(`未找到 AI ${aiName.trim()} !`)));
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
await switchAI(e.guid, aiName.trim());
|
|
235
|
+
const aiInfo = await getAIConfig(e.guid);
|
|
236
|
+
if (!aiInfo.model) {
|
|
237
|
+
message.send(format(Text(`切换失败,未找到 AI ${aiName.trim()} !`)));
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
aiInfo.model = modelName.trim();
|
|
241
|
+
await addAI(e.guid, aiName.trim(), aiInfo.host, aiInfo.key, modelName.trim());
|
|
242
|
+
message.send(format(Text(`已将 AI ${aiName.trim()} 的模型修改为 ${modelName.trim()} !`)));
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
220
245
|
// 无匹配则继续下一个响应器
|
|
221
246
|
next();
|
|
222
247
|
});
|
|
@@ -247,7 +247,7 @@ var res = onResponse(selects, async (e, next) => {
|
|
|
247
247
|
}
|
|
248
248
|
// 记录对话
|
|
249
249
|
await addAIChatHistory(e.guid, res.choices?.[0].message);
|
|
250
|
-
const isOpenTTSReply = (await redis.get(`
|
|
250
|
+
const isOpenTTSReply = (await redis.get(`chat:tts:response:${e.guid}`)) || "0";
|
|
251
251
|
if (isOpenTTSReply === "1") {
|
|
252
252
|
ttsClient = new TTSClient();
|
|
253
253
|
await ttsClient.setModel("三月七", "生气");
|
|
@@ -290,6 +290,7 @@ var res = onResponse(selects, async (e, next) => {
|
|
|
290
290
|
}
|
|
291
291
|
catch (error) {
|
|
292
292
|
console.log("解析AI回复失败,发送原始内容");
|
|
293
|
+
console.log(error);
|
|
293
294
|
const msg = reply
|
|
294
295
|
.replace(/\[CQ:[^\]]+\]/, "")
|
|
295
296
|
.replace(/"}]/, "")
|
|
@@ -306,20 +307,25 @@ function sendTTSMessage(message, e, ttsClient) {
|
|
|
306
307
|
ttsClient.getAudio(message).then(async (audio) => {
|
|
307
308
|
console.log("audio", audio);
|
|
308
309
|
if (audio) {
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
310
|
+
try {
|
|
311
|
+
if (e.Platform == "onebot") {
|
|
312
|
+
const [client] = useClient(e, API);
|
|
313
|
+
await client.sendMessage({
|
|
314
|
+
message_type: e.value.message_type,
|
|
315
|
+
group_id: e.value.group_id ?? undefined,
|
|
316
|
+
message: [
|
|
317
|
+
{
|
|
318
|
+
type: "record",
|
|
319
|
+
data: {
|
|
320
|
+
file: audio.audio_url,
|
|
321
|
+
},
|
|
319
322
|
},
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
}
|
|
323
|
+
],
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
catch (error) {
|
|
328
|
+
console.log(error);
|
|
323
329
|
}
|
|
324
330
|
}
|
|
325
331
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "alemonjs-aichat",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.13",
|
|
4
4
|
"description": "alemonjs-aichat",
|
|
5
5
|
"author": "suancaixianyu",
|
|
6
6
|
"license": "MIT",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"@alemonjs/db": "^0.0.13",
|
|
21
21
|
"@alemonjs/onebot": "^2.1.0-alpha.14",
|
|
22
22
|
"@types/node": "^22",
|
|
23
|
-
"alemonjs": "2.1.
|
|
23
|
+
"alemonjs": "2.1.18",
|
|
24
24
|
"cssnano": "^7",
|
|
25
25
|
"jsxp": "^1.2.3",
|
|
26
26
|
"lvyjs": "^0.2.25",
|
|
@@ -72,4 +72,4 @@
|
|
|
72
72
|
"mime-types": "^3.0.2",
|
|
73
73
|
"openai": "^6.16.0"
|
|
74
74
|
}
|
|
75
|
-
}
|
|
75
|
+
}
|