koishi-plugin-cocoyyy-console 1.1.3-alpha.5 → 1.1.3
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 +1 -0
- package/lib/index.js +308 -75
- package/lib/services/wish_func/wish_command.d.ts +5 -0
- package/lib/services/wish_func/wish_service.d.ts +8 -0
- package/lib/utils/ai_axios.d.ts +30 -1
- package/lib/utils/config.d.ts +1 -0
- package/lib/utils/configs/function_config.d.ts +1 -0
- package/lib/utils/configs/wish_config.d.ts +7 -0
- package/package.json +1 -1
package/lib/index.d.ts
CHANGED
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_koishi16 = require("koishi");
|
|
42
42
|
|
|
43
43
|
// src/utils/configs/function_config.ts
|
|
44
44
|
var import_koishi = require("koishi");
|
|
@@ -50,6 +50,7 @@ var FunctionConfigSchema = import_koishi.Schema.object({
|
|
|
50
50
|
rbq_flag: import_koishi.Schema.boolean().default(true).description("*人功能是否启用"),
|
|
51
51
|
son_flag: import_koishi.Schema.boolean().default(true).description("鉴别史消息功能是否启用"),
|
|
52
52
|
setu_flag: import_koishi.Schema.boolean().default(true).description("随机涩图功能是否启用"),
|
|
53
|
+
wish_flag: import_koishi.Schema.boolean().default(true).description("许愿功能是否启用"),
|
|
53
54
|
game_flag: import_koishi.Schema.boolean().default(true).description("游戏功能是否启用"),
|
|
54
55
|
kuro_flag: import_koishi.Schema.boolean().default(true).description("鸣潮功能是否启用")
|
|
55
56
|
});
|
|
@@ -110,6 +111,13 @@ var AiAPIConfigSchema = import_koishi8.Schema.object({
|
|
|
110
111
|
api_key: import_koishi8.Schema.string().default("").description("API Key")
|
|
111
112
|
});
|
|
112
113
|
|
|
114
|
+
// src/utils/configs/wish_config.ts
|
|
115
|
+
var import_koishi9 = require("koishi");
|
|
116
|
+
var WishConfigSchema = import_koishi9.Schema.object({
|
|
117
|
+
config_path: import_koishi9.Schema.string().default("").description("配置文件路径"),
|
|
118
|
+
api_model: import_koishi9.Schema.string().default("").description("AI模型")
|
|
119
|
+
});
|
|
120
|
+
|
|
113
121
|
// src/infra/mysql_init.ts
|
|
114
122
|
var import_sequelize = require("sequelize");
|
|
115
123
|
var sequelize = null;
|
|
@@ -325,70 +333,71 @@ __name(loadYamlConfig, "loadYamlConfig");
|
|
|
325
333
|
var menuList = [
|
|
326
334
|
{
|
|
327
335
|
name: "tag",
|
|
328
|
-
description: "标签功能,用于记录黑历史"
|
|
329
|
-
command: "maketag [标签]"
|
|
336
|
+
description: "标签功能,用于记录黑历史"
|
|
330
337
|
},
|
|
331
338
|
{
|
|
332
339
|
name: "repeat",
|
|
333
|
-
description: "复读功能,用于复读"
|
|
334
|
-
command: "无"
|
|
340
|
+
description: "复读功能,用于复读"
|
|
335
341
|
},
|
|
336
342
|
{
|
|
337
343
|
name: "rbq",
|
|
338
|
-
description: "*人功能,用于*人"
|
|
339
|
-
command: "无"
|
|
344
|
+
description: "*人功能,用于*人"
|
|
340
345
|
},
|
|
341
346
|
{
|
|
342
347
|
name: "son",
|
|
343
|
-
description: "shit_or_not功能,用于鉴别史消息"
|
|
344
|
-
command: "无"
|
|
348
|
+
description: "shit_or_not功能,用于鉴别史消息"
|
|
345
349
|
},
|
|
346
350
|
{
|
|
347
351
|
name: "setu",
|
|
348
|
-
description: "随机涩图功能,用于获取涩图"
|
|
349
|
-
|
|
352
|
+
description: "随机涩图功能,用于获取涩图"
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
name: "wish",
|
|
356
|
+
description: "许愿功能,用于许愿"
|
|
350
357
|
},
|
|
351
358
|
{
|
|
352
359
|
name: "game",
|
|
353
|
-
description: "游戏功能,用于游玩游戏"
|
|
354
|
-
command: "无"
|
|
360
|
+
description: "游戏功能,用于游玩游戏"
|
|
355
361
|
},
|
|
356
362
|
{
|
|
357
363
|
name: "kuro",
|
|
358
|
-
description: "库洛相关功能,用于鸣潮相关功能"
|
|
359
|
-
command: "无"
|
|
364
|
+
description: "库洛相关功能,用于鸣潮相关功能"
|
|
360
365
|
}
|
|
361
366
|
];
|
|
362
367
|
function getMenuList(command = null, functionConfig) {
|
|
363
368
|
switch (command) {
|
|
364
|
-
case
|
|
369
|
+
case menuList[0].name:
|
|
365
370
|
if (!functionConfig.tag_flag)
|
|
366
371
|
return "标签功能已关闭";
|
|
367
372
|
return getTagFuncMenu(command);
|
|
368
|
-
case
|
|
373
|
+
case menuList[1].name:
|
|
369
374
|
if (!functionConfig.repeat_flag)
|
|
370
375
|
return "复读功能已关闭";
|
|
371
376
|
return `[所有命令都需要@bot]
|
|
372
377
|
复读功能菜单:
|
|
373
378
|
群内重复一定次数的消息会进行复读
|
|
374
379
|
如果遇到问题请联系开发人员。`;
|
|
375
|
-
case
|
|
380
|
+
case menuList[2].name:
|
|
376
381
|
if (!functionConfig.rbq_flag)
|
|
377
382
|
return "*人功能已关闭";
|
|
378
383
|
return getRbqFuncMenu(command);
|
|
379
|
-
case
|
|
384
|
+
case menuList[3].name:
|
|
380
385
|
if (!functionConfig.son_flag)
|
|
381
386
|
return "son功能已关闭";
|
|
382
387
|
return getSonFuncMenu(command);
|
|
383
|
-
case
|
|
388
|
+
case menuList[4].name:
|
|
384
389
|
if (!functionConfig.setu_flag)
|
|
385
390
|
return "son功能已关闭";
|
|
386
391
|
return getSetuFuncMenu(command);
|
|
387
|
-
case
|
|
392
|
+
case menuList[5].name:
|
|
393
|
+
if (!functionConfig.wish_flag)
|
|
394
|
+
return "许愿功能已关闭";
|
|
395
|
+
return getWishFuncMenu(command);
|
|
396
|
+
case menuList[6].name:
|
|
388
397
|
if (!functionConfig.game_flag)
|
|
389
398
|
return "游戏功能已关闭";
|
|
390
399
|
return getGameFuncMenu(command);
|
|
391
|
-
case
|
|
400
|
+
case menuList[7].name:
|
|
392
401
|
if (!functionConfig.kuro_flag)
|
|
393
402
|
return "库洛相关功能已关闭";
|
|
394
403
|
return getKuroFuncMenu(command);
|
|
@@ -516,6 +525,20 @@ setu功能菜单:
|
|
|
516
525
|
输入对应指令使用setu功能,如果遇到问题请联系开发人员。`;
|
|
517
526
|
}
|
|
518
527
|
__name(getSetuFuncMenu, "getSetuFuncMenu");
|
|
528
|
+
var wishFuncMenuList = [
|
|
529
|
+
{
|
|
530
|
+
name: "wish",
|
|
531
|
+
description: "许愿功能",
|
|
532
|
+
command: "wish [愿望消息(不要超过80字)]"
|
|
533
|
+
}
|
|
534
|
+
];
|
|
535
|
+
function getWishFuncMenu(command = null) {
|
|
536
|
+
return `[所有命令都需要@bot]
|
|
537
|
+
许愿功能菜单:
|
|
538
|
+
${wishFuncMenuList.map((item) => item.command + ": " + item.description).join("\n ")}
|
|
539
|
+
输入对应指令使用许愿功能,如果遇到问题请联系开发人员。`;
|
|
540
|
+
}
|
|
541
|
+
__name(getWishFuncMenu, "getWishFuncMenu");
|
|
519
542
|
var gameFuncMenuList = [
|
|
520
543
|
{
|
|
521
544
|
name: "gamelist",
|
|
@@ -572,7 +595,7 @@ function registerMenuCommands(ctx, connected, functionConfig) {
|
|
|
572
595
|
__name(registerMenuCommands, "registerMenuCommands");
|
|
573
596
|
|
|
574
597
|
// src/services/tag_func/tag_commands.ts
|
|
575
|
-
var
|
|
598
|
+
var import_koishi11 = require("koishi");
|
|
576
599
|
|
|
577
600
|
// src/services/tag_func/tag_service.ts
|
|
578
601
|
var import_sequelize4 = require("sequelize");
|
|
@@ -580,7 +603,7 @@ var import_fs3 = require("fs");
|
|
|
580
603
|
var import_path3 = require("path");
|
|
581
604
|
|
|
582
605
|
// src/services/tag_func/img_service.ts
|
|
583
|
-
var
|
|
606
|
+
var import_koishi10 = require("koishi");
|
|
584
607
|
var import_path2 = require("path");
|
|
585
608
|
var import_fs2 = require("fs");
|
|
586
609
|
async function loadImageFromUrl(ctx, url) {
|
|
@@ -655,7 +678,7 @@ async function randomImgByTag(tag_name, guild_id) {
|
|
|
655
678
|
if (ImgList.length <= 0) {
|
|
656
679
|
throw new Error("Don't have image!");
|
|
657
680
|
}
|
|
658
|
-
const random = new
|
|
681
|
+
const random = new import_koishi10.Random(() => Math.random());
|
|
659
682
|
let result = ImgList[random.int(0, ImgList.length)];
|
|
660
683
|
const filePath = result.get("img_url");
|
|
661
684
|
return filePath;
|
|
@@ -900,7 +923,7 @@ function registerTagCommands(ctx, connected, savePath2) {
|
|
|
900
923
|
if (!exec)
|
|
901
924
|
return `获取图片失败`;
|
|
902
925
|
let path2 = (0, import_url.pathToFileURL)(exec).href;
|
|
903
|
-
return
|
|
926
|
+
return import_koishi11.h.image(path2);
|
|
904
927
|
});
|
|
905
928
|
ctx.command("bind <参数>", "标签绑定别名").action(async ({ session }, ...args) => {
|
|
906
929
|
if (!dev_mode) {
|
|
@@ -1043,7 +1066,7 @@ function registerRepeatMiddleware(ctx, config) {
|
|
|
1043
1066
|
__name(registerRepeatMiddleware, "registerRepeatMiddleware");
|
|
1044
1067
|
|
|
1045
1068
|
// src/services/rbq_func/rbq_command.ts
|
|
1046
|
-
var
|
|
1069
|
+
var import_koishi12 = require("koishi");
|
|
1047
1070
|
|
|
1048
1071
|
// src/models/rbq_persons.ts
|
|
1049
1072
|
var import_sequelize5 = require("sequelize");
|
|
@@ -1368,7 +1391,7 @@ function registerRbqCommands(ctx, connected) {
|
|
|
1368
1391
|
if (!list || list.length === 0) {
|
|
1369
1392
|
return "当前群聊还没有设置任何rbq";
|
|
1370
1393
|
}
|
|
1371
|
-
return "当前群聊rbq列表:\n" + list.map((item) => (0,
|
|
1394
|
+
return "当前群聊rbq列表:\n" + list.map((item) => (0, import_koishi12.h)("at", { id: item })).join(",");
|
|
1372
1395
|
});
|
|
1373
1396
|
ctx.command("rbqadd <参数>", "添加rbq").action(async ({ session }, ...args) => {
|
|
1374
1397
|
if (!dev_mode) {
|
|
@@ -1386,7 +1409,7 @@ function registerRbqCommands(ctx, connected) {
|
|
|
1386
1409
|
exec = await create_person(session.guildId, uid);
|
|
1387
1410
|
if (!exec.result)
|
|
1388
1411
|
return `添加rbq失败: ${exec.error}`;
|
|
1389
|
-
return "已添加rbq:" + (0,
|
|
1412
|
+
return "已添加rbq:" + (0, import_koishi12.h)("at", { id: uid });
|
|
1390
1413
|
});
|
|
1391
1414
|
ctx.command("rbqinstead <参数>", "替换rbq").action(async ({ session }, ...args) => {
|
|
1392
1415
|
if (!dev_mode) {
|
|
@@ -1411,12 +1434,12 @@ function registerRbqCommands(ctx, connected) {
|
|
|
1411
1434
|
exec = await instead_person(session.guildId, source_uid, new_target);
|
|
1412
1435
|
if (!exec.result)
|
|
1413
1436
|
return `替换rbq失败:${exec.error}`;
|
|
1414
|
-
return "倒反天罡!进去吧你,已替换rbq:\n" + (0,
|
|
1437
|
+
return "倒反天罡!进去吧你,已替换rbq:\n" + (0, import_koishi12.h)("at", { id: source_uid }) + " -> " + (0, import_koishi12.h)("at", { id: new_target });
|
|
1415
1438
|
}
|
|
1416
1439
|
exec = await instead_person(session.guildId, source_uid, target_uid);
|
|
1417
1440
|
if (!exec.result)
|
|
1418
1441
|
return `替换rbq失败:${exec.error}`;
|
|
1419
|
-
return (0,
|
|
1442
|
+
return (0, import_koishi12.h)("p", "已替换rbq:", (0, import_koishi12.h)("at", { id: source_uid }), " -> ", (0, import_koishi12.h)("at", { id: target_uid }));
|
|
1420
1443
|
});
|
|
1421
1444
|
ctx.command("rbqadd_txt <参数>", "添加自定义文本").action(async ({ session }, ...args) => {
|
|
1422
1445
|
if (!dev_mode) {
|
|
@@ -1443,10 +1466,10 @@ function registerRbqCommands(ctx, connected) {
|
|
|
1443
1466
|
const contents = await get_content_list(session.guildId, target_uid);
|
|
1444
1467
|
let content2 = "*死你";
|
|
1445
1468
|
if (contents && contents.length > 0) {
|
|
1446
|
-
const random = new
|
|
1469
|
+
const random = new import_koishi12.Random(() => Math.random());
|
|
1447
1470
|
content2 = contents[random.int(0, contents.length)];
|
|
1448
1471
|
}
|
|
1449
|
-
return (0,
|
|
1472
|
+
return (0, import_koishi12.h)("at", { id: target_uid }) + "还想自己加文本?!\n" + content2;
|
|
1450
1473
|
} catch (error) {
|
|
1451
1474
|
logger.error("[rbq rbqadd_txt] Error:", error);
|
|
1452
1475
|
return "不能给自己设置文本,请输入其他qq号";
|
|
@@ -1476,10 +1499,10 @@ function registerRbqCommands(ctx, connected) {
|
|
|
1476
1499
|
const contents = await get_content_list(guildId, matchedUid);
|
|
1477
1500
|
let content = "*死你";
|
|
1478
1501
|
if (contents && contents.length > 0) {
|
|
1479
|
-
const random = new
|
|
1502
|
+
const random = new import_koishi12.Random(() => Math.random());
|
|
1480
1503
|
content = contents[random.int(0, contents.length)];
|
|
1481
1504
|
}
|
|
1482
|
-
return (0,
|
|
1505
|
+
return (0, import_koishi12.h)("at", { id: matchedUid }) + " " + content;
|
|
1483
1506
|
} catch (error) {
|
|
1484
1507
|
logger.error("[rbq middleware] Error:", error);
|
|
1485
1508
|
return next();
|
|
@@ -1528,14 +1551,19 @@ var import_tesseract2 = require("tesseract.js");
|
|
|
1528
1551
|
|
|
1529
1552
|
// src/utils/ai_axios.ts
|
|
1530
1553
|
var import_axios = __toESM(require("axios"));
|
|
1531
|
-
async function callOpenRouter(api_url, api_key, api_model = "gpt-4o-mini", messages) {
|
|
1554
|
+
async function callOpenRouter(api_url, api_key, api_model = "gpt-4o-mini", messages, tools2, tool_choice) {
|
|
1532
1555
|
try {
|
|
1556
|
+
const requestBody = {
|
|
1557
|
+
model: api_model,
|
|
1558
|
+
messages
|
|
1559
|
+
};
|
|
1560
|
+
if (tools2 && tools2.length > 0) {
|
|
1561
|
+
requestBody.tools = tools2;
|
|
1562
|
+
requestBody.tool_choice = tool_choice ?? "auto";
|
|
1563
|
+
}
|
|
1533
1564
|
const { data } = await import_axios.default.post(
|
|
1534
1565
|
api_url,
|
|
1535
|
-
|
|
1536
|
-
model: api_model,
|
|
1537
|
-
messages
|
|
1538
|
-
},
|
|
1566
|
+
requestBody,
|
|
1539
1567
|
{
|
|
1540
1568
|
headers: {
|
|
1541
1569
|
Authorization: `Bearer ${api_key}`,
|
|
@@ -1544,7 +1572,17 @@ async function callOpenRouter(api_url, api_key, api_model = "gpt-4o-mini", messa
|
|
|
1544
1572
|
}
|
|
1545
1573
|
);
|
|
1546
1574
|
const choices = data?.choices ?? [];
|
|
1547
|
-
const
|
|
1575
|
+
const message = choices[0]?.message;
|
|
1576
|
+
const reply = message?.content;
|
|
1577
|
+
const tool_calls = message?.tool_calls;
|
|
1578
|
+
if (tool_calls && tool_calls.length > 0) {
|
|
1579
|
+
const firstToolCall = tool_calls[0];
|
|
1580
|
+
return {
|
|
1581
|
+
err: null,
|
|
1582
|
+
resp: firstToolCall.function.arguments,
|
|
1583
|
+
tool_calls
|
|
1584
|
+
};
|
|
1585
|
+
}
|
|
1548
1586
|
let responseText;
|
|
1549
1587
|
let err = null;
|
|
1550
1588
|
if (typeof reply === "string") {
|
|
@@ -1557,20 +1595,46 @@ async function callOpenRouter(api_url, api_key, api_model = "gpt-4o-mini", messa
|
|
|
1557
1595
|
if (!responseText) {
|
|
1558
1596
|
err = "OpenRouter 返回空内容";
|
|
1559
1597
|
}
|
|
1598
|
+
} else if (reply === null) {
|
|
1599
|
+
err = "OpenRouter 返回空内容";
|
|
1600
|
+
responseText = "";
|
|
1560
1601
|
} else {
|
|
1561
1602
|
err = "OpenRouter 返回了未知格式,请检查日志";
|
|
1603
|
+
responseText = "";
|
|
1562
1604
|
}
|
|
1563
|
-
return { err, resp: responseText };
|
|
1605
|
+
return { err, resp: responseText, tool_calls: void 0 };
|
|
1564
1606
|
} catch (error) {
|
|
1565
1607
|
const err = error;
|
|
1566
1608
|
const status = err.response?.status;
|
|
1567
|
-
const
|
|
1609
|
+
const responseData = err.response?.data;
|
|
1610
|
+
let detail = responseData?.error || responseData?.message || err.message;
|
|
1611
|
+
let errorCode = responseData?.code;
|
|
1612
|
+
if (typeof detail === "object" && detail !== null) {
|
|
1613
|
+
const errorMsg = detail.message || detail.error || JSON.stringify(detail);
|
|
1614
|
+
errorCode = detail.code || errorCode;
|
|
1615
|
+
detail = errorMsg;
|
|
1616
|
+
}
|
|
1568
1617
|
logger.error("[callOpenRouter Error]: OpenRouter 请求失败", {
|
|
1569
1618
|
status,
|
|
1619
|
+
code: errorCode,
|
|
1570
1620
|
detail,
|
|
1571
|
-
url: err.config?.url
|
|
1621
|
+
url: err.config?.url,
|
|
1622
|
+
model: api_model,
|
|
1623
|
+
hasTools: tools2 && tools2.length > 0,
|
|
1624
|
+
requestBody: tools2 && tools2.length > 0 ? {
|
|
1625
|
+
model: api_model,
|
|
1626
|
+
hasTools: true,
|
|
1627
|
+
tool_choice: tool_choice ?? "auto"
|
|
1628
|
+
} : void 0
|
|
1572
1629
|
});
|
|
1573
|
-
|
|
1630
|
+
if (status === 404 && tools2 && tools2.length > 0) {
|
|
1631
|
+
const toolErrorHint = `模型 "${api_model}" 可能不支持工具调用,或模型名称格式不正确(应包含 provider 前缀,如 "deepseek/deepseek-chat-v3.1")。请检查模型配置。`;
|
|
1632
|
+
return {
|
|
1633
|
+
err: `OpenRouter error(${status}): ${detail}. ${toolErrorHint}`,
|
|
1634
|
+
resp: null
|
|
1635
|
+
};
|
|
1636
|
+
}
|
|
1637
|
+
const errorMessage = `OpenRouter error${status ? `(${status})` : ""}: ${detail}`;
|
|
1574
1638
|
return { err: errorMessage, resp: null };
|
|
1575
1639
|
}
|
|
1576
1640
|
}
|
|
@@ -1692,7 +1756,7 @@ __name(is_at_bot_quote, "is_at_bot_quote");
|
|
|
1692
1756
|
|
|
1693
1757
|
// src/services/himg_func/himg_service.ts
|
|
1694
1758
|
var import_axios2 = __toESM(require("axios"));
|
|
1695
|
-
var
|
|
1759
|
+
var import_koishi13 = require("koishi");
|
|
1696
1760
|
async function randomHImg(keywords, ...args) {
|
|
1697
1761
|
try {
|
|
1698
1762
|
const r18 = keywords?.[0];
|
|
@@ -1700,13 +1764,14 @@ async function randomHImg(keywords, ...args) {
|
|
|
1700
1764
|
const params = new URLSearchParams();
|
|
1701
1765
|
params.append("excludeAI", "true");
|
|
1702
1766
|
params.append("size", "regular");
|
|
1703
|
-
|
|
1767
|
+
let r18_flag = 0;
|
|
1704
1768
|
if (r18) {
|
|
1705
1769
|
if (r18.toLowerCase() === "r18") {
|
|
1706
|
-
|
|
1770
|
+
r18_flag = 1;
|
|
1707
1771
|
tags = keywords?.slice(1);
|
|
1708
1772
|
}
|
|
1709
1773
|
}
|
|
1774
|
+
params.append("r18", r18_flag.toString());
|
|
1710
1775
|
if (args[0]) {
|
|
1711
1776
|
params.append("num", args[0].toString());
|
|
1712
1777
|
}
|
|
@@ -1721,7 +1786,7 @@ async function randomHImg(keywords, ...args) {
|
|
|
1721
1786
|
let author = item.author;
|
|
1722
1787
|
let url = item.urls.regular;
|
|
1723
1788
|
let tags2 = item.tags;
|
|
1724
|
-
result_content += "作者: " + author + "\n标签: \n[" + tags2.join(",") + "]\n" +
|
|
1789
|
+
result_content += "作者: " + author + "\n标签: \n[" + tags2.join(",") + "]\n" + import_koishi13.h.image(url) + "\n";
|
|
1725
1790
|
}
|
|
1726
1791
|
return {
|
|
1727
1792
|
result: result_content,
|
|
@@ -1777,6 +1842,171 @@ function registerHImgCommands(ctx) {
|
|
|
1777
1842
|
}
|
|
1778
1843
|
__name(registerHImgCommands, "registerHImgCommands");
|
|
1779
1844
|
|
|
1845
|
+
// src/services/wish_func/wish_command.ts
|
|
1846
|
+
var import_koishi14 = require("koishi");
|
|
1847
|
+
|
|
1848
|
+
// src/services/wish_func/wish_service.ts
|
|
1849
|
+
var chatHistory2 = [];
|
|
1850
|
+
var tools = [
|
|
1851
|
+
{
|
|
1852
|
+
type: "function",
|
|
1853
|
+
function: {
|
|
1854
|
+
name: "wish_audit_result",
|
|
1855
|
+
description: "对用户愿望进行合规审计并返回结构化结果",
|
|
1856
|
+
parameters: {
|
|
1857
|
+
type: "object",
|
|
1858
|
+
properties: {
|
|
1859
|
+
category: {
|
|
1860
|
+
type: "string",
|
|
1861
|
+
enum: ["block", "allow"],
|
|
1862
|
+
description: "是否允许该愿望"
|
|
1863
|
+
},
|
|
1864
|
+
reason: {
|
|
1865
|
+
type: "string",
|
|
1866
|
+
description: "block:说明触犯的禁忌类型;allow:说明内容合规"
|
|
1867
|
+
},
|
|
1868
|
+
wish: {
|
|
1869
|
+
type: "string",
|
|
1870
|
+
description: "allow:复述用户愿望(去除语气词);block:必须为空字符串"
|
|
1871
|
+
}
|
|
1872
|
+
},
|
|
1873
|
+
required: ["category", "reason", "wish"],
|
|
1874
|
+
additionalProperties: false
|
|
1875
|
+
}
|
|
1876
|
+
}
|
|
1877
|
+
},
|
|
1878
|
+
{
|
|
1879
|
+
type: "function",
|
|
1880
|
+
function: {
|
|
1881
|
+
name: "wish_generation_result",
|
|
1882
|
+
description: "生成愿望实现的场景",
|
|
1883
|
+
parameters: {
|
|
1884
|
+
type: "object",
|
|
1885
|
+
properties: {
|
|
1886
|
+
scenario: {
|
|
1887
|
+
type: "string",
|
|
1888
|
+
description: "愿望实现的场景"
|
|
1889
|
+
}
|
|
1890
|
+
},
|
|
1891
|
+
required: ["scenario"],
|
|
1892
|
+
additionalProperties: false
|
|
1893
|
+
}
|
|
1894
|
+
}
|
|
1895
|
+
}
|
|
1896
|
+
];
|
|
1897
|
+
async function checkAudit(local_config4, wish_content, config, wish_config) {
|
|
1898
|
+
let prompt_msg = "";
|
|
1899
|
+
if (!local_config4) return { result: false, reason: "未加载配置文件,请查看日志" };
|
|
1900
|
+
prompt_msg = local_config4.wish_config?.prompts["audit"];
|
|
1901
|
+
if (!prompt_msg) return { result: false, reason: "未找到prompt,请查看日志" };
|
|
1902
|
+
try {
|
|
1903
|
+
prompt_msg = prompt_msg.replace("{{USER_TEXT}}", wish_content);
|
|
1904
|
+
chatHistory2 = [];
|
|
1905
|
+
chatHistory2.push({ role: "system", content: [{ type: "text", text: prompt_msg }] });
|
|
1906
|
+
const using_model = wish_config.api_model || config.api_model;
|
|
1907
|
+
const { err, resp } = await callOpenRouter(
|
|
1908
|
+
config.api_url,
|
|
1909
|
+
config.api_key,
|
|
1910
|
+
using_model,
|
|
1911
|
+
chatHistory2,
|
|
1912
|
+
tools,
|
|
1913
|
+
{ type: "function", function: { name: "wish_audit_result" } }
|
|
1914
|
+
);
|
|
1915
|
+
if (err != null) {
|
|
1916
|
+
logger.error("[checkAudit Error]: " + err);
|
|
1917
|
+
return { result: false, reason: err };
|
|
1918
|
+
}
|
|
1919
|
+
if (!resp) {
|
|
1920
|
+
logger.error("[checkAudit Error]: API返回为空");
|
|
1921
|
+
return { result: false, reason: "API返回为空" };
|
|
1922
|
+
}
|
|
1923
|
+
const json = JSON.parse(resp);
|
|
1924
|
+
if (json.category == "block") {
|
|
1925
|
+
logger.info("[checkAudit Info]: 愿望被拒绝,原因: " + json.reason);
|
|
1926
|
+
return { result: false, reason: json.reason };
|
|
1927
|
+
}
|
|
1928
|
+
if (json.category == "allow" || json.category == "review") {
|
|
1929
|
+
return { result: true, reason: json.reason };
|
|
1930
|
+
}
|
|
1931
|
+
logger.error("[checkAudit Error]: API返回有误,未触发block或allow/review: " + resp);
|
|
1932
|
+
return { result: false, reason: "API返回有误,未触发block或allow/review" };
|
|
1933
|
+
} catch (e) {
|
|
1934
|
+
logger.error("[checkAudit Error]: " + e);
|
|
1935
|
+
return { result: false, reason: "未知错误,请查看日志" };
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
__name(checkAudit, "checkAudit");
|
|
1939
|
+
async function gernerationSoluation(local_config4, wish_content, config, wish_config) {
|
|
1940
|
+
let prompt_msg = "";
|
|
1941
|
+
if (!local_config4) return "未加载配置文件,请查看日志";
|
|
1942
|
+
prompt_msg = local_config4.wish_config?.prompts["generation"];
|
|
1943
|
+
if (!prompt_msg) return "未找到prompt,请查看日志";
|
|
1944
|
+
try {
|
|
1945
|
+
prompt_msg = prompt_msg.replace("{{USER_TEXT}}", wish_content);
|
|
1946
|
+
chatHistory2 = [];
|
|
1947
|
+
chatHistory2.push({ role: "system", content: [{ type: "text", text: prompt_msg }] });
|
|
1948
|
+
const using_model = wish_config.api_model || config.api_model;
|
|
1949
|
+
const { err, resp } = await callOpenRouter(
|
|
1950
|
+
config.api_url,
|
|
1951
|
+
config.api_key,
|
|
1952
|
+
using_model,
|
|
1953
|
+
chatHistory2,
|
|
1954
|
+
tools,
|
|
1955
|
+
{ type: "function", function: { name: "wish_generation_result" } }
|
|
1956
|
+
);
|
|
1957
|
+
if (err != null) {
|
|
1958
|
+
logger.error("[gernerationSoluation Error]: " + err);
|
|
1959
|
+
return null;
|
|
1960
|
+
}
|
|
1961
|
+
const json = JSON.parse(resp);
|
|
1962
|
+
const scenario = json.scenario;
|
|
1963
|
+
if (!scenario) {
|
|
1964
|
+
logger.info("[gernerationSoluation Info]: API返回有误: " + resp);
|
|
1965
|
+
return null;
|
|
1966
|
+
}
|
|
1967
|
+
return scenario;
|
|
1968
|
+
} catch (e) {
|
|
1969
|
+
logger.error("[gernerationSoluation Error]: " + e);
|
|
1970
|
+
return null;
|
|
1971
|
+
}
|
|
1972
|
+
}
|
|
1973
|
+
__name(gernerationSoluation, "gernerationSoluation");
|
|
1974
|
+
|
|
1975
|
+
// src/services/wish_func/wish_command.ts
|
|
1976
|
+
var local_config2 = null;
|
|
1977
|
+
var think_flag2 = false;
|
|
1978
|
+
function registerWishCommands(ctx, ai_config, wish_config) {
|
|
1979
|
+
if (wish_config?.config_path) {
|
|
1980
|
+
local_config2 = loadYamlConfig(wish_config.config_path);
|
|
1981
|
+
if (local_config2) {
|
|
1982
|
+
logger.info("[loadYamlConfig Info]: Wish 成功加载配置文件");
|
|
1983
|
+
} else {
|
|
1984
|
+
logger.error("[loadYamlConfig Error]: Wish 配置文件加载失败,将使用默认配置");
|
|
1985
|
+
}
|
|
1986
|
+
} else {
|
|
1987
|
+
logger.error("[loadYamlConfig Error]: 未配置 Wish 配置文件路径");
|
|
1988
|
+
}
|
|
1989
|
+
ctx.command("wish <参数>", "许愿").action(async ({ session }, ...args) => {
|
|
1990
|
+
if (!dev_mode) {
|
|
1991
|
+
if (!is_at_bot(session)) return "请提供正确格式,如: @bot wish [愿望消息(不要超过80字)]";
|
|
1992
|
+
}
|
|
1993
|
+
const wish_content = args?.[0];
|
|
1994
|
+
if (!wish_content) return "输入愿望消息,不要超过80字";
|
|
1995
|
+
await session.send("已收到,正在祈祷中...");
|
|
1996
|
+
think_flag2 = true;
|
|
1997
|
+
try {
|
|
1998
|
+
let exec = await checkAudit(local_config2, wish_content, ai_config, wish_config);
|
|
1999
|
+
if (!exec) return "愿望不合规被拒绝,请重新许愿";
|
|
2000
|
+
let exec_generation = await gernerationSoluation(local_config2, wish_content, ai_config, wish_config);
|
|
2001
|
+
if (!exec_generation) return "愿望实现失败,请重新许愿";
|
|
2002
|
+
return (0, import_koishi14.h)("at", { id: session.userId }) + " 祈祷成功,愿梦想成真!\n" + exec_generation;
|
|
2003
|
+
} finally {
|
|
2004
|
+
think_flag2 = false;
|
|
2005
|
+
}
|
|
2006
|
+
});
|
|
2007
|
+
}
|
|
2008
|
+
__name(registerWishCommands, "registerWishCommands");
|
|
2009
|
+
|
|
1780
2010
|
// src/services/kuro_func/kuro_service.ts
|
|
1781
2011
|
var import_axios3 = __toESM(require("axios"));
|
|
1782
2012
|
var import_qs = __toESM(require("qs"));
|
|
@@ -2186,7 +2416,7 @@ function registerKuroCommands(ctx, connected) {
|
|
|
2186
2416
|
__name(registerKuroCommands, "registerKuroCommands");
|
|
2187
2417
|
|
|
2188
2418
|
// src/services/game_func/game_command.ts
|
|
2189
|
-
var
|
|
2419
|
+
var import_koishi15 = require("koishi");
|
|
2190
2420
|
|
|
2191
2421
|
// src/services/game_func/game_service.ts
|
|
2192
2422
|
var gameTimeout = null;
|
|
@@ -2215,11 +2445,11 @@ __name(clearGameTimeout, "clearGameTimeout");
|
|
|
2215
2445
|
// src/services/game_func/games/game_turtlesoup_service.ts
|
|
2216
2446
|
var is_gaming = false;
|
|
2217
2447
|
var chatPrompt = [];
|
|
2218
|
-
var
|
|
2448
|
+
var chatHistory3 = [];
|
|
2219
2449
|
async function startSituationPuzzle(config) {
|
|
2220
2450
|
chatPrompt = [];
|
|
2221
|
-
|
|
2222
|
-
const prompt_start =
|
|
2451
|
+
chatHistory3 = [];
|
|
2452
|
+
const prompt_start = local_config3?.game?.situation_puzzle;
|
|
2223
2453
|
chatPrompt.push({ role: "system", content: [{ type: "text", text: prompt_start }] });
|
|
2224
2454
|
const { err, resp } = await callOpenRouter(config.api_url, config.api_key, config.api_model, chatPrompt);
|
|
2225
2455
|
if (err != null) {
|
|
@@ -2234,7 +2464,7 @@ async function startSituationPuzzle(config) {
|
|
|
2234
2464
|
logger.info(`[SituationPuzzle Timeout]: 游戏已超时(${GAME_TIMEOUT_MINUTES}分钟),自动结束游戏`);
|
|
2235
2465
|
is_gaming = false;
|
|
2236
2466
|
chatPrompt = [];
|
|
2237
|
-
|
|
2467
|
+
chatHistory3 = [];
|
|
2238
2468
|
setGameTimeout(null);
|
|
2239
2469
|
}, GAME_TIMEOUT_MINUTES * 60 * 1e3);
|
|
2240
2470
|
logger.info("[startSituationPuzzle Info]: ai api send message success");
|
|
@@ -2242,9 +2472,9 @@ async function startSituationPuzzle(config) {
|
|
|
2242
2472
|
}
|
|
2243
2473
|
__name(startSituationPuzzle, "startSituationPuzzle");
|
|
2244
2474
|
async function questSituationPuzzle(content, config) {
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
const { err, resp } = await callOpenRouter(config.api_url, config.api_key, config.api_model,
|
|
2475
|
+
chatHistory3 = [...chatPrompt];
|
|
2476
|
+
chatHistory3.push({ role: "user", content: [{ type: "text", text: content }] });
|
|
2477
|
+
const { err, resp } = await callOpenRouter(config.api_url, config.api_key, config.api_model, chatHistory3);
|
|
2248
2478
|
if (err != null) {
|
|
2249
2479
|
logger.error("[questSituationPuzzle Error]: " + err);
|
|
2250
2480
|
return null;
|
|
@@ -2253,7 +2483,7 @@ async function questSituationPuzzle(content, config) {
|
|
|
2253
2483
|
if (resp.includes("猜中了")) {
|
|
2254
2484
|
is_gaming = false;
|
|
2255
2485
|
chatPrompt = [];
|
|
2256
|
-
|
|
2486
|
+
chatHistory3 = [];
|
|
2257
2487
|
clearGameTimeout();
|
|
2258
2488
|
} else {
|
|
2259
2489
|
clearGameTimeout();
|
|
@@ -2261,7 +2491,7 @@ async function questSituationPuzzle(content, config) {
|
|
|
2261
2491
|
logger.info(`[SituationPuzzle Timeout]: 游戏已超时(${GAME_TIMEOUT_MINUTES}分钟),自动结束游戏`);
|
|
2262
2492
|
is_gaming = false;
|
|
2263
2493
|
chatPrompt = [];
|
|
2264
|
-
|
|
2494
|
+
chatHistory3 = [];
|
|
2265
2495
|
setGameTimeout(null);
|
|
2266
2496
|
}, GAME_TIMEOUT_MINUTES * 60 * 1e3);
|
|
2267
2497
|
}
|
|
@@ -2270,9 +2500,9 @@ async function questSituationPuzzle(content, config) {
|
|
|
2270
2500
|
__name(questSituationPuzzle, "questSituationPuzzle");
|
|
2271
2501
|
async function endSituationPuzzle(config) {
|
|
2272
2502
|
is_gaming = false;
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
const { err, resp } = await callOpenRouter(config.api_url, config.api_key, config.api_model,
|
|
2503
|
+
chatHistory3 = [...chatPrompt];
|
|
2504
|
+
chatHistory3.push({ role: "user", content: [{ type: "text", text: "结束游戏,请给出答案" }] });
|
|
2505
|
+
const { err, resp } = await callOpenRouter(config.api_url, config.api_key, config.api_model, chatHistory3);
|
|
2276
2506
|
if (err != null) {
|
|
2277
2507
|
logger.error("[endSituationPuzzle Error]: " + err);
|
|
2278
2508
|
return null;
|
|
@@ -2283,16 +2513,16 @@ async function endSituationPuzzle(config) {
|
|
|
2283
2513
|
}
|
|
2284
2514
|
__name(endSituationPuzzle, "endSituationPuzzle");
|
|
2285
2515
|
async function rerollSituationPuzzle(config) {
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
const { err, resp } = await callOpenRouter(config.api_url, config.api_key, config.api_model,
|
|
2516
|
+
chatHistory3 = [...chatPrompt];
|
|
2517
|
+
chatHistory3.push({ role: "user", content: [{ type: "text", text: "重新生成新谜题" }] });
|
|
2518
|
+
const { err, resp } = await callOpenRouter(config.api_url, config.api_key, config.api_model, chatHistory3);
|
|
2289
2519
|
if (err != null) {
|
|
2290
2520
|
logger.error("[rerollSituationPuzzle Error]: " + err);
|
|
2291
2521
|
chatPrompt.pop();
|
|
2292
2522
|
return null;
|
|
2293
2523
|
}
|
|
2294
2524
|
chatPrompt = [];
|
|
2295
|
-
const prompt_start =
|
|
2525
|
+
const prompt_start = local_config3?.game?.situation_puzzle;
|
|
2296
2526
|
chatPrompt.push({ role: "system", content: [{ type: "text", text: prompt_start }] });
|
|
2297
2527
|
chatPrompt.push({ role: "assistant", content: [{ type: "text", text: resp }] });
|
|
2298
2528
|
is_gaming = true;
|
|
@@ -2301,7 +2531,7 @@ async function rerollSituationPuzzle(config) {
|
|
|
2301
2531
|
logger.info(`[SituationPuzzle Timeout]: 游戏已超时(${GAME_TIMEOUT_MINUTES}分钟),自动结束游戏`);
|
|
2302
2532
|
is_gaming = false;
|
|
2303
2533
|
chatPrompt = [];
|
|
2304
|
-
|
|
2534
|
+
chatHistory3 = [];
|
|
2305
2535
|
setGameTimeout(null);
|
|
2306
2536
|
}, GAME_TIMEOUT_MINUTES * 60 * 1e3);
|
|
2307
2537
|
logger.info("[rerollSituationPuzzle Info]: ai api send message success");
|
|
@@ -2411,7 +2641,7 @@ function getSolution() {
|
|
|
2411
2641
|
__name(getSolution, "getSolution");
|
|
2412
2642
|
|
|
2413
2643
|
// src/services/game_func/game_command.ts
|
|
2414
|
-
var
|
|
2644
|
+
var local_config3 = null;
|
|
2415
2645
|
var is_thinking = false;
|
|
2416
2646
|
var now_game = null;
|
|
2417
2647
|
var gameList = [
|
|
@@ -2433,8 +2663,8 @@ var commandList = [
|
|
|
2433
2663
|
];
|
|
2434
2664
|
function registerGameCommands(ctx, game_config, ai_config) {
|
|
2435
2665
|
if (game_config?.config_path) {
|
|
2436
|
-
|
|
2437
|
-
if (
|
|
2666
|
+
local_config3 = loadYamlConfig(game_config.config_path);
|
|
2667
|
+
if (local_config3) {
|
|
2438
2668
|
logger.info("[loadYamlConfig Info]: Game 成功加载配置文件");
|
|
2439
2669
|
} else {
|
|
2440
2670
|
logger.error("[loadYamlConfig Error]: Game 配置文件加载失败,将使用默认配置");
|
|
@@ -2443,7 +2673,7 @@ function registerGameCommands(ctx, game_config, ai_config) {
|
|
|
2443
2673
|
logger.error("[loadYamlConfig Error]: 未配置 Game 配置文件路径");
|
|
2444
2674
|
}
|
|
2445
2675
|
if (GAME_TIMEOUT_MINUTES <= 0) {
|
|
2446
|
-
setGameTimeoutMinutes(
|
|
2676
|
+
setGameTimeoutMinutes(local_config3?.game?.timeout_minutes || 10);
|
|
2447
2677
|
}
|
|
2448
2678
|
ctx.command("gamelist", "查看所有游戏").action(async ({}) => {
|
|
2449
2679
|
return `[所有命令都需要@bot]
|
|
@@ -2552,7 +2782,7 @@ async function situationPuzzleMiddleware(session, ai_config) {
|
|
|
2552
2782
|
return checkResp(resp2);
|
|
2553
2783
|
}
|
|
2554
2784
|
const resp = await questSituationPuzzle(text, ai_config);
|
|
2555
|
-
return (0,
|
|
2785
|
+
return (0, import_koishi15.h)("at", { id: userId }) + " " + checkResp(resp);
|
|
2556
2786
|
} finally {
|
|
2557
2787
|
is_thinking = false;
|
|
2558
2788
|
}
|
|
@@ -2569,17 +2799,18 @@ __name(checkResp, "checkResp");
|
|
|
2569
2799
|
// src/index.ts
|
|
2570
2800
|
var name = "cocoyyy-console";
|
|
2571
2801
|
var dev_mode;
|
|
2572
|
-
var Config =
|
|
2802
|
+
var Config = import_koishi16.Schema.object({
|
|
2573
2803
|
function_config: FunctionConfigSchema.description("功能开关配置"),
|
|
2574
2804
|
ai_config: AiAPIConfigSchema.description("AI API配置"),
|
|
2575
2805
|
mysql_config: MysqlConfigSchema.description("MySQL 数据库配置"),
|
|
2576
2806
|
tag_config: SaveConfigSchema.description("tag图片保存配置"),
|
|
2577
2807
|
repeat_config: RepeatConfigSchema.description("复读配置"),
|
|
2578
2808
|
son_config: ShitOrNotConfigSchema.description("SON配置"),
|
|
2809
|
+
wish_config: WishConfigSchema.description("许愿配置"),
|
|
2579
2810
|
game_config: GameConfigSchema.description("游戏配置"),
|
|
2580
|
-
test:
|
|
2811
|
+
test: import_koishi16.Schema.string().description("测试")
|
|
2581
2812
|
});
|
|
2582
|
-
var logger = new
|
|
2813
|
+
var logger = new import_koishi16.Logger(name);
|
|
2583
2814
|
var savePath = null;
|
|
2584
2815
|
async function apply(ctx, config) {
|
|
2585
2816
|
ctx = ctx.guild();
|
|
@@ -2603,6 +2834,8 @@ async function apply(ctx, config) {
|
|
|
2603
2834
|
registerShitOrNotCommands(ctx, config?.ai_config, config?.son_config);
|
|
2604
2835
|
if (config.function_config.setu_flag)
|
|
2605
2836
|
registerHImgCommands(ctx);
|
|
2837
|
+
if (config.function_config.wish_flag)
|
|
2838
|
+
registerWishCommands(ctx, config?.ai_config, config?.wish_config);
|
|
2606
2839
|
if (config.function_config.game_flag) {
|
|
2607
2840
|
registerGameCommands(ctx, config?.game_config, config?.ai_config);
|
|
2608
2841
|
registerGameMiddleware(ctx, config?.ai_config);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Context } from 'koishi';
|
|
2
|
+
import { AiAPIConfig } from '../../utils/configs/ai_config';
|
|
3
|
+
import { WishConfig } from '../../utils/configs/wish_config';
|
|
4
|
+
declare function registerWishCommands(ctx: Context, ai_config: AiAPIConfig, wish_config: WishConfig): void;
|
|
5
|
+
export { registerWishCommands };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { AiAPIConfig } from '../../utils/configs/ai_config';
|
|
2
|
+
import { WishConfig } from '../../utils/configs/wish_config';
|
|
3
|
+
declare function checkAudit(local_config: any, wish_content: string, config: AiAPIConfig, wish_config: WishConfig): Promise<{
|
|
4
|
+
result: boolean;
|
|
5
|
+
reason: string;
|
|
6
|
+
}>;
|
|
7
|
+
declare function gernerationSoluation(local_config: any, wish_content: string, config: AiAPIConfig, wish_config: WishConfig): Promise<any>;
|
|
8
|
+
export { checkAudit, gernerationSoluation };
|
package/lib/utils/ai_axios.d.ts
CHANGED
|
@@ -8,8 +8,37 @@ export interface OpenRouterMessage {
|
|
|
8
8
|
};
|
|
9
9
|
}>;
|
|
10
10
|
}
|
|
11
|
+
export interface OpenRouterTool {
|
|
12
|
+
type: 'function';
|
|
13
|
+
function: {
|
|
14
|
+
name: string;
|
|
15
|
+
description: string;
|
|
16
|
+
parameters: {
|
|
17
|
+
type: string;
|
|
18
|
+
properties?: Record<string, any>;
|
|
19
|
+
required?: string[];
|
|
20
|
+
additionalProperties?: boolean;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export type OpenRouterToolChoice = 'none' | 'auto' | 'required' | {
|
|
25
|
+
type: 'function';
|
|
26
|
+
function: {
|
|
27
|
+
name: string;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
interface OpenRouterToolCall {
|
|
31
|
+
id: string;
|
|
32
|
+
type: 'function';
|
|
33
|
+
function: {
|
|
34
|
+
name: string;
|
|
35
|
+
arguments: string;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
11
38
|
export interface OpenRouterResult {
|
|
12
39
|
err: string | null;
|
|
13
40
|
resp: string | null;
|
|
41
|
+
tool_calls?: OpenRouterToolCall[];
|
|
14
42
|
}
|
|
15
|
-
export declare function callOpenRouter(api_url: string, api_key: string, api_model: string, messages: OpenRouterMessage[]): Promise<OpenRouterResult>;
|
|
43
|
+
export declare function callOpenRouter(api_url: string, api_key: string, api_model: string, messages: OpenRouterMessage[], tools?: OpenRouterTool[], tool_choice?: OpenRouterToolChoice): Promise<OpenRouterResult>;
|
|
44
|
+
export {};
|
package/lib/utils/config.d.ts
CHANGED