koishi-plugin-cocoyyy-console 1.0.16-beta.1 → 1.0.16-beta.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.d.ts +2 -0
- package/lib/index.js +281 -28
- package/lib/services/son_func/shit_or_not_command.d.ts +4 -0
- package/lib/services/son_func/shit_or_not_service.d.ts +5 -0
- package/lib/services/test_command.d.ts +3 -1
- package/lib/utils/ai_axios.d.ts +15 -0
- package/lib/utils/config.d.ts +1 -0
- package/lib/utils/configs/function_config.d.ts +1 -0
- package/lib/utils/configs/son_config.d.ts +9 -0
- package/package.json +5 -3
package/lib/index.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export interface Config {
|
|
|
8
8
|
mysql_config?: my_config.MysqlConfig;
|
|
9
9
|
tag_config?: my_config.SaveConfig;
|
|
10
10
|
repeat_config?: my_config.RepeatConfig;
|
|
11
|
+
son_config?: my_config.ShitOrNotConfig;
|
|
12
|
+
test?: string;
|
|
11
13
|
}
|
|
12
14
|
export declare const Config: Schema<Config>;
|
|
13
15
|
export declare let logger: Logger;
|
package/lib/index.js
CHANGED
|
@@ -38,7 +38,7 @@ __export(src_exports, {
|
|
|
38
38
|
savePath: () => savePath
|
|
39
39
|
});
|
|
40
40
|
module.exports = __toCommonJS(src_exports);
|
|
41
|
-
var
|
|
41
|
+
var import_koishi10 = require("koishi");
|
|
42
42
|
|
|
43
43
|
// src/utils/configs/function_config.ts
|
|
44
44
|
var import_koishi = require("koishi");
|
|
@@ -47,6 +47,7 @@ var FunctionConfigSchema = import_koishi.Schema.object({
|
|
|
47
47
|
tag_flag: import_koishi.Schema.boolean().default(true).description("标签功能是否启用"),
|
|
48
48
|
repeat_flag: import_koishi.Schema.boolean().default(true).description("复读功能是否启用"),
|
|
49
49
|
rbq_flag: import_koishi.Schema.boolean().default(true).description("*人功能是否启用"),
|
|
50
|
+
son_flag: import_koishi.Schema.boolean().default(true).description("鉴别史消息功能是否启用"),
|
|
50
51
|
kuro_flag: import_koishi.Schema.boolean().default(true).description("鸣潮功能是否启用")
|
|
51
52
|
});
|
|
52
53
|
|
|
@@ -86,6 +87,15 @@ var RedisConfigSchema = import_koishi5.Schema.object({
|
|
|
86
87
|
redis_url: import_koishi5.Schema.string().default("127.0.0.1:6379").description("Redis连接字符串")
|
|
87
88
|
});
|
|
88
89
|
|
|
90
|
+
// src/utils/configs/son_config.ts
|
|
91
|
+
var import_koishi6 = require("koishi");
|
|
92
|
+
var ShitOrNotConfigSchema = import_koishi6.Schema.object({
|
|
93
|
+
api_url: import_koishi6.Schema.string().default("").description("Api接口Url"),
|
|
94
|
+
api_model: import_koishi6.Schema.string().default("").description("AI模型"),
|
|
95
|
+
api_key: import_koishi6.Schema.string().default("").description("API Key"),
|
|
96
|
+
config_path: import_koishi6.Schema.string().default("").description("配置文件路径")
|
|
97
|
+
});
|
|
98
|
+
|
|
89
99
|
// src/infra/mysql_init.ts
|
|
90
100
|
var import_sequelize = require("sequelize");
|
|
91
101
|
var sequelize = null;
|
|
@@ -290,6 +300,11 @@ var menuList = [
|
|
|
290
300
|
description: "*人功能,用于*人",
|
|
291
301
|
command: "无"
|
|
292
302
|
},
|
|
303
|
+
{
|
|
304
|
+
name: "son",
|
|
305
|
+
description: "shit_or_not功能,用于鉴别史消息",
|
|
306
|
+
command: "无"
|
|
307
|
+
},
|
|
293
308
|
{
|
|
294
309
|
name: "kuro",
|
|
295
310
|
description: "库洛相关功能,用于鸣潮相关功能",
|
|
@@ -313,6 +328,10 @@ function getMenuList(command = null, functionConfig) {
|
|
|
313
328
|
if (!functionConfig.rbq_flag)
|
|
314
329
|
return "*人功能已关闭";
|
|
315
330
|
return getRbqFuncMenu(command);
|
|
331
|
+
case "son":
|
|
332
|
+
if (!functionConfig.son_flag)
|
|
333
|
+
return "son功能已关闭";
|
|
334
|
+
return getSonFuncMenu(command);
|
|
316
335
|
case "kuro":
|
|
317
336
|
if (!functionConfig.kuro_flag)
|
|
318
337
|
return "库洛相关功能已关闭";
|
|
@@ -321,7 +340,7 @@ function getMenuList(command = null, functionConfig) {
|
|
|
321
340
|
return `[所有命令都需要@bot]
|
|
322
341
|
当前可用功能列表:
|
|
323
342
|
${menuList.map((item) => item.name + ": " + item.description).join("\n ")}
|
|
324
|
-
输入"help 功能名"查看特定功能的指令和使用示例。`;
|
|
343
|
+
输入"help [功能名]"查看特定功能的指令和使用示例。`;
|
|
325
344
|
}
|
|
326
345
|
}
|
|
327
346
|
__name(getMenuList, "getMenuList");
|
|
@@ -403,6 +422,25 @@ function getRbqFuncMenu(command = null) {
|
|
|
403
422
|
输入对应指令使用*人功能,如果遇到问题请联系开发人员。`;
|
|
404
423
|
}
|
|
405
424
|
__name(getRbqFuncMenu, "getRbqFuncMenu");
|
|
425
|
+
var sonFuncMenuList = [
|
|
426
|
+
{
|
|
427
|
+
name: "sonlist",
|
|
428
|
+
description: "查看son判断模式列表",
|
|
429
|
+
command: "sonlist"
|
|
430
|
+
},
|
|
431
|
+
{
|
|
432
|
+
name: "son",
|
|
433
|
+
description: "判断是否为史",
|
|
434
|
+
command: "son [判断模式]"
|
|
435
|
+
}
|
|
436
|
+
];
|
|
437
|
+
function getSonFuncMenu(command = null) {
|
|
438
|
+
return `[所有命令都需要@bot]
|
|
439
|
+
son功能菜单:
|
|
440
|
+
${sonFuncMenuList.map((item) => item.command + ": " + item.description).join("\n ")}
|
|
441
|
+
输入对应指令使用son功能,如果遇到问题请联系开发人员。`;
|
|
442
|
+
}
|
|
443
|
+
__name(getSonFuncMenu, "getSonFuncMenu");
|
|
406
444
|
var kuroFuncMenuList = [
|
|
407
445
|
{
|
|
408
446
|
name: "login",
|
|
@@ -435,7 +473,7 @@ function registerMenuCommands(ctx, connected, functionConfig) {
|
|
|
435
473
|
__name(registerMenuCommands, "registerMenuCommands");
|
|
436
474
|
|
|
437
475
|
// src/services/tag_func/tag_commands.ts
|
|
438
|
-
var
|
|
476
|
+
var import_koishi8 = require("koishi");
|
|
439
477
|
|
|
440
478
|
// src/services/tag_func/tag_service.ts
|
|
441
479
|
var import_sequelize4 = require("sequelize");
|
|
@@ -443,7 +481,7 @@ var import_fs2 = require("fs");
|
|
|
443
481
|
var import_path2 = require("path");
|
|
444
482
|
|
|
445
483
|
// src/services/tag_func/img_service.ts
|
|
446
|
-
var
|
|
484
|
+
var import_koishi7 = require("koishi");
|
|
447
485
|
var import_path = require("path");
|
|
448
486
|
var import_fs = require("fs");
|
|
449
487
|
async function loadImageFromUrl(ctx, url) {
|
|
@@ -518,7 +556,7 @@ async function randomImgByTag(tag_name, guild_id) {
|
|
|
518
556
|
if (ImgList.length <= 0) {
|
|
519
557
|
throw new Error("Don't have image!");
|
|
520
558
|
}
|
|
521
|
-
const random = new
|
|
559
|
+
const random = new import_koishi7.Random(() => Math.random());
|
|
522
560
|
let result = ImgList[random.int(0, ImgList.length)];
|
|
523
561
|
const filePath = result.get("img_url");
|
|
524
562
|
return filePath;
|
|
@@ -762,8 +800,8 @@ function registerTagCommands(ctx, connected, savePath2) {
|
|
|
762
800
|
let exec = await randomImgByTag(tag, session.guildId);
|
|
763
801
|
if (!exec)
|
|
764
802
|
return `获取图片失败`;
|
|
765
|
-
let
|
|
766
|
-
return
|
|
803
|
+
let path2 = (0, import_url.pathToFileURL)(exec).href;
|
|
804
|
+
return import_koishi8.h.image(path2);
|
|
767
805
|
});
|
|
768
806
|
ctx.command("bind <参数>", "标签绑定别名").action(async ({ session }, ...args) => {
|
|
769
807
|
if (!dev_mode) {
|
|
@@ -906,7 +944,7 @@ function registerRepeatMiddleware(ctx, config) {
|
|
|
906
944
|
__name(registerRepeatMiddleware, "registerRepeatMiddleware");
|
|
907
945
|
|
|
908
946
|
// src/services/rbq_func/rbq_command.ts
|
|
909
|
-
var
|
|
947
|
+
var import_koishi9 = require("koishi");
|
|
910
948
|
|
|
911
949
|
// src/models/rbq_persons.ts
|
|
912
950
|
var import_sequelize5 = require("sequelize");
|
|
@@ -1231,7 +1269,7 @@ function registerRbqCommands(ctx, connected) {
|
|
|
1231
1269
|
if (!list || list.length === 0) {
|
|
1232
1270
|
return "当前群聊还没有设置任何rbq";
|
|
1233
1271
|
}
|
|
1234
|
-
return "当前群聊rbq列表:\n" + list.map((item) => (0,
|
|
1272
|
+
return "当前群聊rbq列表:\n" + list.map((item) => (0, import_koishi9.h)("at", { id: item })).join(",");
|
|
1235
1273
|
});
|
|
1236
1274
|
ctx.command("rbqadd <参数>", "添加rbq").action(async ({ session }, ...args) => {
|
|
1237
1275
|
if (!dev_mode) {
|
|
@@ -1249,7 +1287,7 @@ function registerRbqCommands(ctx, connected) {
|
|
|
1249
1287
|
exec = await create_person(session.guildId, uid);
|
|
1250
1288
|
if (!exec.result)
|
|
1251
1289
|
return `添加rbq失败: ${exec.error}`;
|
|
1252
|
-
return "已添加rbq:" + (0,
|
|
1290
|
+
return "已添加rbq:" + (0, import_koishi9.h)("at", { id: uid });
|
|
1253
1291
|
});
|
|
1254
1292
|
ctx.command("rbqinstead <参数>", "替换rbq").action(async ({ session }, ...args) => {
|
|
1255
1293
|
if (!dev_mode) {
|
|
@@ -1274,12 +1312,12 @@ function registerRbqCommands(ctx, connected) {
|
|
|
1274
1312
|
exec = await instead_person(session.guildId, source_uid, new_target);
|
|
1275
1313
|
if (!exec.result)
|
|
1276
1314
|
return `替换rbq失败:${exec.error}`;
|
|
1277
|
-
return "倒反天罡!进去吧你,已替换rbq:\n" + (0,
|
|
1315
|
+
return "倒反天罡!进去吧你,已替换rbq:\n" + (0, import_koishi9.h)("at", { id: source_uid }) + " -> " + (0, import_koishi9.h)("at", { id: new_target });
|
|
1278
1316
|
}
|
|
1279
1317
|
exec = await instead_person(session.guildId, source_uid, target_uid);
|
|
1280
1318
|
if (!exec.result)
|
|
1281
1319
|
return `替换rbq失败:${exec.error}`;
|
|
1282
|
-
return (0,
|
|
1320
|
+
return (0, import_koishi9.h)("p", "已替换rbq:", (0, import_koishi9.h)("at", { id: source_uid }), " -> ", (0, import_koishi9.h)("at", { id: target_uid }));
|
|
1283
1321
|
});
|
|
1284
1322
|
ctx.command("rbqadd_txt <参数>", "添加自定义文本").action(async ({ session }, ...args) => {
|
|
1285
1323
|
if (!dev_mode) {
|
|
@@ -1306,10 +1344,10 @@ function registerRbqCommands(ctx, connected) {
|
|
|
1306
1344
|
const contents = await get_content_list(session.guildId, target_uid);
|
|
1307
1345
|
let content2 = "*死你";
|
|
1308
1346
|
if (contents && contents.length > 0) {
|
|
1309
|
-
const random = new
|
|
1347
|
+
const random = new import_koishi9.Random(() => Math.random());
|
|
1310
1348
|
content2 = contents[random.int(0, contents.length)];
|
|
1311
1349
|
}
|
|
1312
|
-
return (0,
|
|
1350
|
+
return (0, import_koishi9.h)("at", { id: target_uid }) + "还想自己加文本?!\n" + content2;
|
|
1313
1351
|
} catch (error) {
|
|
1314
1352
|
logger.error("[rbq rbqadd_txt] Error:", error);
|
|
1315
1353
|
return "不能给自己设置文本,请输入其他qq号";
|
|
@@ -1339,10 +1377,10 @@ function registerRbqCommands(ctx, connected) {
|
|
|
1339
1377
|
const contents = await get_content_list(guildId, matchedUid);
|
|
1340
1378
|
let content = "*死你";
|
|
1341
1379
|
if (contents && contents.length > 0) {
|
|
1342
|
-
const random = new
|
|
1380
|
+
const random = new import_koishi9.Random(() => Math.random());
|
|
1343
1381
|
content = contents[random.int(0, contents.length)];
|
|
1344
1382
|
}
|
|
1345
|
-
return (0,
|
|
1383
|
+
return (0, import_koishi9.h)("at", { id: matchedUid }) + " " + content;
|
|
1346
1384
|
} catch (error) {
|
|
1347
1385
|
logger.error("[rbq middleware] Error:", error);
|
|
1348
1386
|
return next();
|
|
@@ -1352,19 +1390,230 @@ function registerRbqCommands(ctx, connected) {
|
|
|
1352
1390
|
__name(registerRbqCommands, "registerRbqCommands");
|
|
1353
1391
|
|
|
1354
1392
|
// src/services/test_command.ts
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1393
|
+
var import_tesseract = require("tesseract.js");
|
|
1394
|
+
function registerTestCommands(ctx, config) {
|
|
1395
|
+
ctx.command("test1 <prompt:text>", "调用 OpenRouter 模型进行测试").action(async ({ session }, prompt) => {
|
|
1396
|
+
const apiKey = config?.test || process.env.OPENROUTER_API_KEY;
|
|
1397
|
+
if (!apiKey) return "未配置 OpenRouter API Key(config.test 或环境变量 OPENROUTER_API_KEY)";
|
|
1398
|
+
const content = prompt?.trim();
|
|
1399
|
+
if (!content) return "请输入要测试的内容";
|
|
1400
|
+
});
|
|
1401
|
+
ctx.command("test <path>", "测试用").action(async ({ session }, path2) => {
|
|
1402
|
+
const { content, uid, userId } = session;
|
|
1403
|
+
if (session.quote) {
|
|
1404
|
+
const quoteContent = session.quote.content;
|
|
1405
|
+
const quoteUserId = session.quote.user.id;
|
|
1406
|
+
logger.error(`command: quoteContent: ${quoteContent}, quoteUserId: ${quoteUserId},content: ${content} userId: ${userId}`);
|
|
1407
|
+
} else {
|
|
1408
|
+
logger.error(`command: content: ${content} userId: ${userId}`);
|
|
1409
|
+
}
|
|
1410
|
+
});
|
|
1411
|
+
ctx.middleware((session, next) => {
|
|
1412
|
+
const { content, uid, userId } = session;
|
|
1413
|
+
const cid = session.cid;
|
|
1414
|
+
if (session.guildId != "829263238") return next();
|
|
1415
|
+
if (ctx.bots[uid]) return next();
|
|
1416
|
+
if (session.quote) {
|
|
1417
|
+
const quoteContent = session.quote.content;
|
|
1418
|
+
const quoteUserId = session.quote.user.id;
|
|
1419
|
+
logger.error(`quoteContent: ${quoteContent}, quoteUserId: ${quoteUserId},content: ${content} userId: ${userId}`);
|
|
1420
|
+
} else {
|
|
1421
|
+
logger.error(`content: ${content} userId: ${userId}`);
|
|
1361
1422
|
}
|
|
1362
1423
|
});
|
|
1363
1424
|
}
|
|
1364
1425
|
__name(registerTestCommands, "registerTestCommands");
|
|
1365
1426
|
|
|
1366
|
-
// src/services/
|
|
1427
|
+
// src/services/son_func/shit_or_not_command.ts
|
|
1428
|
+
var import_fs3 = require("fs");
|
|
1429
|
+
var yaml = __toESM(require("js-yaml"));
|
|
1430
|
+
var import_path3 = __toESM(require("path"));
|
|
1431
|
+
|
|
1432
|
+
// src/services/son_func/shit_or_not_service.ts
|
|
1433
|
+
var import_tesseract2 = require("tesseract.js");
|
|
1434
|
+
|
|
1435
|
+
// src/utils/ai_axios.ts
|
|
1367
1436
|
var import_axios = __toESM(require("axios"));
|
|
1437
|
+
async function callOpenRouter(api_url, api_key, api_model = "gpt-4o-mini", messages) {
|
|
1438
|
+
try {
|
|
1439
|
+
const { data } = await import_axios.default.post(
|
|
1440
|
+
api_url,
|
|
1441
|
+
{
|
|
1442
|
+
model: api_model,
|
|
1443
|
+
messages
|
|
1444
|
+
},
|
|
1445
|
+
{
|
|
1446
|
+
headers: {
|
|
1447
|
+
Authorization: `Bearer ${api_key}`,
|
|
1448
|
+
"Content-Type": "application/json"
|
|
1449
|
+
}
|
|
1450
|
+
}
|
|
1451
|
+
);
|
|
1452
|
+
const choices = data?.choices ?? [];
|
|
1453
|
+
const reply = choices[0]?.message?.content;
|
|
1454
|
+
let responseText;
|
|
1455
|
+
let err = null;
|
|
1456
|
+
if (typeof reply === "string") {
|
|
1457
|
+
responseText = reply.trim();
|
|
1458
|
+
} else if (Array.isArray(reply)) {
|
|
1459
|
+
responseText = reply.map((part) => part?.text ?? "").join("").trim();
|
|
1460
|
+
if (!responseText) {
|
|
1461
|
+
err = "OpenRouter 返回空内容";
|
|
1462
|
+
}
|
|
1463
|
+
} else {
|
|
1464
|
+
err = "OpenRouter 返回了未知格式,请检查日志";
|
|
1465
|
+
}
|
|
1466
|
+
return { err, resp: responseText };
|
|
1467
|
+
} catch (error) {
|
|
1468
|
+
const err = error;
|
|
1469
|
+
const status = err.response?.status;
|
|
1470
|
+
const detail = err.response?.data?.error || err.response?.data?.message || err.message;
|
|
1471
|
+
logger.error("[callOpenRouter Error]: OpenRouter 请求失败", {
|
|
1472
|
+
status,
|
|
1473
|
+
detail,
|
|
1474
|
+
url: err.config?.url,
|
|
1475
|
+
payload: err.config?.data
|
|
1476
|
+
});
|
|
1477
|
+
const errorMessage = `test error${status ? `(${status})` : ""}: ${detail}`;
|
|
1478
|
+
return { err: errorMessage, resp: null };
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
__name(callOpenRouter, "callOpenRouter");
|
|
1482
|
+
|
|
1483
|
+
// src/services/son_func/shit_or_not_service.ts
|
|
1484
|
+
var chatHistory = [];
|
|
1485
|
+
function decodeHtmlEntities2(value) {
|
|
1486
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'");
|
|
1487
|
+
}
|
|
1488
|
+
__name(decodeHtmlEntities2, "decodeHtmlEntities");
|
|
1489
|
+
function extractImageAndText(content) {
|
|
1490
|
+
const imageUrls = [];
|
|
1491
|
+
const imgTagRegex = /<img\b[^>]*>/gi;
|
|
1492
|
+
const stripped = content.replace(imgTagRegex, (tag) => {
|
|
1493
|
+
const srcMatch = tag.match(/src=["']([^"']+)["']/i);
|
|
1494
|
+
if (srcMatch?.[1]) {
|
|
1495
|
+
imageUrls.push(decodeHtmlEntities2(srcMatch[1]));
|
|
1496
|
+
}
|
|
1497
|
+
return " ";
|
|
1498
|
+
});
|
|
1499
|
+
const withoutTags = stripped.replace(/<[^>]+>/g, " ");
|
|
1500
|
+
const text = withoutTags.replace(/\s+/g, " ").trim();
|
|
1501
|
+
return { imageUrls, text };
|
|
1502
|
+
}
|
|
1503
|
+
__name(extractImageAndText, "extractImageAndText");
|
|
1504
|
+
async function checkShitOrNot(session, parttern_msg, config) {
|
|
1505
|
+
chatHistory = [];
|
|
1506
|
+
chatHistory.push({ role: "user", content: [{ type: "text", text: parttern_msg }] });
|
|
1507
|
+
const { err, resp } = await callOpenRouter(config.api_url, config.api_key, config.api_model, chatHistory);
|
|
1508
|
+
if (err != null) {
|
|
1509
|
+
logger.error("[callOpenRouter Error 1]: " + err);
|
|
1510
|
+
return null;
|
|
1511
|
+
}
|
|
1512
|
+
chatHistory.push({ role: "assistant", content: [{ type: "text", text: resp }] });
|
|
1513
|
+
const quoteContent = session.quote.content;
|
|
1514
|
+
const { imageUrls, text } = extractImageAndText(quoteContent);
|
|
1515
|
+
if (!text && imageUrls.length === 0) {
|
|
1516
|
+
logger.warn("[checkShitOrNot Warn]: 引用消息中未发现文本或图片");
|
|
1517
|
+
return "引用消息中未发现文本或图片";
|
|
1518
|
+
}
|
|
1519
|
+
const targetContent = [
|
|
1520
|
+
...text ? [{ type: "text", text }] : [],
|
|
1521
|
+
...imageUrls.map((url) => ({ type: "image_url", image_url: { url } }))
|
|
1522
|
+
];
|
|
1523
|
+
chatHistory.push({ role: "user", content: targetContent });
|
|
1524
|
+
const { err: err2, resp: resp2 } = await callOpenRouter(config.api_url, config.api_key, config.api_model, chatHistory);
|
|
1525
|
+
if (err2 != null) {
|
|
1526
|
+
logger.error("[callOpenRouter Error 2]: " + err2);
|
|
1527
|
+
return null;
|
|
1528
|
+
}
|
|
1529
|
+
return resp2;
|
|
1530
|
+
}
|
|
1531
|
+
__name(checkShitOrNot, "checkShitOrNot");
|
|
1532
|
+
|
|
1533
|
+
// src/services/son_func/shit_or_not_command.ts
|
|
1534
|
+
var local_config = null;
|
|
1535
|
+
function registerShitOrNotCommands(ctx, config) {
|
|
1536
|
+
if (config?.config_path) {
|
|
1537
|
+
local_config = loadYamlConfig(config.config_path);
|
|
1538
|
+
if (local_config) {
|
|
1539
|
+
logger.info("[loadYamlConfig Info]: SON 成功加载配置文件");
|
|
1540
|
+
} else {
|
|
1541
|
+
logger.error("[loadYamlConfig Error]: SON 配置文件加载失败,将使用默认配置");
|
|
1542
|
+
}
|
|
1543
|
+
} else {
|
|
1544
|
+
logger.error("[loadYamlConfig Error]: 未配置 SON 配置文件路径");
|
|
1545
|
+
}
|
|
1546
|
+
ctx.command("sonlist <参数>", "查看son判断模式列表").action(async ({ session }) => {
|
|
1547
|
+
if (!dev_mode) {
|
|
1548
|
+
if (!is_at_bot(session)) return;
|
|
1549
|
+
}
|
|
1550
|
+
if (!local_config) return "未加载配置文件,请查看日志";
|
|
1551
|
+
const mode_intro = local_config?.menu;
|
|
1552
|
+
if (!mode_intro) return "未找到判断模式列表,请查看日志";
|
|
1553
|
+
return `[所有命令都需要@bot]
|
|
1554
|
+
son判断模式列表:
|
|
1555
|
+
${Object.keys(mode_intro).map((item) => item + ": " + mode_intro[item]).join("\n ")}`;
|
|
1556
|
+
});
|
|
1557
|
+
ctx.command("son <参数>", "判定是否为史").action(async ({ session }, ...args) => {
|
|
1558
|
+
if (!dev_mode) {
|
|
1559
|
+
if (!is_at_bot_quote(session)) return "请提供正确格式,如: [引用消息] @bot son [判断模式]";
|
|
1560
|
+
} else {
|
|
1561
|
+
if (!session.quote) return "请引用消息后使用功能";
|
|
1562
|
+
}
|
|
1563
|
+
const parttern = args?.[0];
|
|
1564
|
+
if (!parttern) return "请提供正确判断模式,如: [引用消息] @bot son [判断模式]";
|
|
1565
|
+
if (!local_config) return "未加载配置文件,请查看日志";
|
|
1566
|
+
const parttern_msg = local_config.shit_or_not?.prompts[parttern];
|
|
1567
|
+
if (!parttern_msg) return "未找到判断模式,请查看日志";
|
|
1568
|
+
let exec = await checkShitOrNot(session, parttern_msg, config);
|
|
1569
|
+
return exec;
|
|
1570
|
+
});
|
|
1571
|
+
}
|
|
1572
|
+
__name(registerShitOrNotCommands, "registerShitOrNotCommands");
|
|
1573
|
+
function loadYamlConfig(configPath) {
|
|
1574
|
+
if (!configPath) {
|
|
1575
|
+
logger.error("[loadYamlConfig Error]: SON 配置文件路径未配置");
|
|
1576
|
+
return null;
|
|
1577
|
+
}
|
|
1578
|
+
try {
|
|
1579
|
+
const trimmedPath = configPath.trim();
|
|
1580
|
+
const fullPath = import_path3.default.isAbsolute(trimmedPath) ? trimmedPath : import_path3.default.resolve(process.cwd(), trimmedPath);
|
|
1581
|
+
if (!(0, import_fs3.existsSync)(fullPath)) {
|
|
1582
|
+
logger.error(`[loadYamlConfig Error]: SON 配置文件不存在: ${fullPath}`);
|
|
1583
|
+
return null;
|
|
1584
|
+
}
|
|
1585
|
+
const fileContent = (0, import_fs3.readFileSync)(fullPath, "utf-8");
|
|
1586
|
+
const config = yaml.load(fileContent);
|
|
1587
|
+
return config;
|
|
1588
|
+
} catch (error) {
|
|
1589
|
+
logger.error(`[loadYamlConfig Error]: SON 读取配置文件失败: ${configPath}`, error);
|
|
1590
|
+
return null;
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
__name(loadYamlConfig, "loadYamlConfig");
|
|
1594
|
+
function extractAtId(content) {
|
|
1595
|
+
const match = content.match(/<at\b[^>]*id=["']?(\d+)["']?[^>]*>/i);
|
|
1596
|
+
return match ? match[1] : null;
|
|
1597
|
+
}
|
|
1598
|
+
__name(extractAtId, "extractAtId");
|
|
1599
|
+
function is_at_bot_quote(session) {
|
|
1600
|
+
if (!session.quote)
|
|
1601
|
+
return false;
|
|
1602
|
+
const { content, userId } = session;
|
|
1603
|
+
const quote = session.quote;
|
|
1604
|
+
const quoteUserId = quote.user.id;
|
|
1605
|
+
const quoteContent = quote.content;
|
|
1606
|
+
const botId = session?.bot?.selfId ?? session?.selfId;
|
|
1607
|
+
const elements = quote.elements || [];
|
|
1608
|
+
const atId = extractAtId(session.content);
|
|
1609
|
+
if (atId === botId)
|
|
1610
|
+
return true;
|
|
1611
|
+
return false;
|
|
1612
|
+
}
|
|
1613
|
+
__name(is_at_bot_quote, "is_at_bot_quote");
|
|
1614
|
+
|
|
1615
|
+
// src/services/kuro_func/kuro_service.ts
|
|
1616
|
+
var import_axios2 = __toESM(require("axios"));
|
|
1368
1617
|
var import_qs = __toESM(require("qs"));
|
|
1369
1618
|
|
|
1370
1619
|
// src/models/kuro_user.ts
|
|
@@ -1497,7 +1746,7 @@ var CONSTANTS = {
|
|
|
1497
1746
|
"source": "ios"
|
|
1498
1747
|
}
|
|
1499
1748
|
};
|
|
1500
|
-
var wavesApi =
|
|
1749
|
+
var wavesApi = import_axios2.default.create();
|
|
1501
1750
|
wavesApi.interceptors.request.use(
|
|
1502
1751
|
async (config) => {
|
|
1503
1752
|
if (config.url.startsWith("/")) {
|
|
@@ -1774,14 +2023,16 @@ __name(registerKuroCommands, "registerKuroCommands");
|
|
|
1774
2023
|
// src/index.ts
|
|
1775
2024
|
var name = "cocoyyy-console";
|
|
1776
2025
|
var dev_mode;
|
|
1777
|
-
var Config =
|
|
2026
|
+
var Config = import_koishi10.Schema.object({
|
|
1778
2027
|
function_config: FunctionConfigSchema.description("功能开关配置"),
|
|
1779
2028
|
redis_config: RedisConfigSchema.description("Redis配置"),
|
|
1780
2029
|
mysql_config: MysqlConfigSchema.description("MySQL 数据库配置"),
|
|
1781
2030
|
tag_config: SaveConfigSchema.description("tag图片保存配置"),
|
|
1782
|
-
repeat_config: RepeatConfigSchema.description("复读配置")
|
|
2031
|
+
repeat_config: RepeatConfigSchema.description("复读配置"),
|
|
2032
|
+
son_config: ShitOrNotConfigSchema.description("SON配置"),
|
|
2033
|
+
test: import_koishi10.Schema.string().description("测试")
|
|
1783
2034
|
});
|
|
1784
|
-
var logger = new
|
|
2035
|
+
var logger = new import_koishi10.Logger(name);
|
|
1785
2036
|
var savePath = null;
|
|
1786
2037
|
async function apply(ctx, config) {
|
|
1787
2038
|
ctx = ctx.guild();
|
|
@@ -1801,12 +2052,14 @@ async function apply(ctx, config) {
|
|
|
1801
2052
|
registerTagCommands(ctx, connected, savePath);
|
|
1802
2053
|
if (config.function_config.repeat_flag)
|
|
1803
2054
|
registerRepeatMiddleware(ctx, config?.repeat_config);
|
|
2055
|
+
if (config.function_config.son_flag)
|
|
2056
|
+
registerShitOrNotCommands(ctx, config?.son_config);
|
|
1804
2057
|
if (config.function_config.rbq_flag)
|
|
1805
2058
|
registerRbqCommands(ctx, connected);
|
|
1806
2059
|
if (config.function_config)
|
|
1807
2060
|
registerKuroCommands(ctx, connected);
|
|
1808
2061
|
if (dev_mode)
|
|
1809
|
-
registerTestCommands(ctx);
|
|
2062
|
+
registerTestCommands(ctx, config);
|
|
1810
2063
|
}
|
|
1811
2064
|
__name(apply, "apply");
|
|
1812
2065
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Session } from 'koishi';
|
|
2
|
+
import { ShitOrNotConfig } from '../../utils/config';
|
|
3
|
+
declare function ocrImage(buffer: Buffer): Promise<string>;
|
|
4
|
+
declare function checkShitOrNot(session: Session, parttern_msg: string, config: ShitOrNotConfig): Promise<string>;
|
|
5
|
+
export { checkShitOrNot, ocrImage };
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import { Context } from 'koishi';
|
|
2
|
-
|
|
2
|
+
import { Config } from '..';
|
|
3
|
+
declare function registerTestCommands(ctx: Context, config: Config): void;
|
|
4
|
+
export declare function ocrImage(buffer: Buffer): Promise<string>;
|
|
3
5
|
export { registerTestCommands };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface OpenRouterMessage {
|
|
2
|
+
role: 'system' | 'user' | 'assistant';
|
|
3
|
+
content: Array<{
|
|
4
|
+
type: 'text' | 'image_url';
|
|
5
|
+
text?: string;
|
|
6
|
+
image_url?: {
|
|
7
|
+
url: string;
|
|
8
|
+
};
|
|
9
|
+
}>;
|
|
10
|
+
}
|
|
11
|
+
export interface OpenRouterResult {
|
|
12
|
+
err: string | null;
|
|
13
|
+
resp: string | null;
|
|
14
|
+
}
|
|
15
|
+
export declare function callOpenRouter(api_url: string, api_key: string, api_model: string, messages: OpenRouterMessage[]): Promise<OpenRouterResult>;
|
package/lib/utils/config.d.ts
CHANGED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Schema } from 'koishi';
|
|
2
|
+
interface ShitOrNotConfig {
|
|
3
|
+
api_url?: string;
|
|
4
|
+
api_model?: string;
|
|
5
|
+
api_key?: string;
|
|
6
|
+
config_path?: string;
|
|
7
|
+
}
|
|
8
|
+
declare const ShitOrNotConfigSchema: Schema<ShitOrNotConfig>;
|
|
9
|
+
export { ShitOrNotConfig, ShitOrNotConfigSchema, };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koishi-plugin-cocoyyy-console",
|
|
3
3
|
"description": "自用koishi插件,功能包含复读,记录黑历史,*人等",
|
|
4
|
-
"version": "1.0.16-beta.
|
|
4
|
+
"version": "1.0.16-beta.11",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
7
7
|
"contributors": [
|
|
@@ -25,6 +25,8 @@
|
|
|
25
25
|
"mysql2": "^3.11.0",
|
|
26
26
|
"qs": "^6.14.0",
|
|
27
27
|
"sequelize": "^6.37.3",
|
|
28
|
-
"ioredis": "^5.8.2"
|
|
28
|
+
"ioredis": "^5.8.2",
|
|
29
|
+
"tesseract.js": "^5.1.0",
|
|
30
|
+
"js-yaml": "^4.1.1"
|
|
29
31
|
}
|
|
30
|
-
}
|
|
32
|
+
}
|