koishi-plugin-cocoyyy-console 1.1.3-alpha.4 → 1.1.3-alpha.6

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 CHANGED
@@ -9,6 +9,7 @@ export interface Config {
9
9
  tag_config?: my_config.SaveConfig;
10
10
  repeat_config?: my_config.RepeatConfig;
11
11
  son_config?: my_config.ShitOrNotConfig;
12
+ wish_config?: my_config.WishConfig;
12
13
  game_config?: my_config.GameConfig;
13
14
  test?: string;
14
15
  }
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 import_koishi14 = require("koishi");
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;
@@ -572,7 +580,7 @@ function registerMenuCommands(ctx, connected, functionConfig) {
572
580
  __name(registerMenuCommands, "registerMenuCommands");
573
581
 
574
582
  // src/services/tag_func/tag_commands.ts
575
- var import_koishi10 = require("koishi");
583
+ var import_koishi11 = require("koishi");
576
584
 
577
585
  // src/services/tag_func/tag_service.ts
578
586
  var import_sequelize4 = require("sequelize");
@@ -580,7 +588,7 @@ var import_fs3 = require("fs");
580
588
  var import_path3 = require("path");
581
589
 
582
590
  // src/services/tag_func/img_service.ts
583
- var import_koishi9 = require("koishi");
591
+ var import_koishi10 = require("koishi");
584
592
  var import_path2 = require("path");
585
593
  var import_fs2 = require("fs");
586
594
  async function loadImageFromUrl(ctx, url) {
@@ -655,7 +663,7 @@ async function randomImgByTag(tag_name, guild_id) {
655
663
  if (ImgList.length <= 0) {
656
664
  throw new Error("Don't have image!");
657
665
  }
658
- const random = new import_koishi9.Random(() => Math.random());
666
+ const random = new import_koishi10.Random(() => Math.random());
659
667
  let result = ImgList[random.int(0, ImgList.length)];
660
668
  const filePath = result.get("img_url");
661
669
  return filePath;
@@ -900,7 +908,7 @@ function registerTagCommands(ctx, connected, savePath2) {
900
908
  if (!exec)
901
909
  return `获取图片失败`;
902
910
  let path2 = (0, import_url.pathToFileURL)(exec).href;
903
- return import_koishi10.h.image(path2);
911
+ return import_koishi11.h.image(path2);
904
912
  });
905
913
  ctx.command("bind <参数>", "标签绑定别名").action(async ({ session }, ...args) => {
906
914
  if (!dev_mode) {
@@ -1043,7 +1051,7 @@ function registerRepeatMiddleware(ctx, config) {
1043
1051
  __name(registerRepeatMiddleware, "registerRepeatMiddleware");
1044
1052
 
1045
1053
  // src/services/rbq_func/rbq_command.ts
1046
- var import_koishi11 = require("koishi");
1054
+ var import_koishi12 = require("koishi");
1047
1055
 
1048
1056
  // src/models/rbq_persons.ts
1049
1057
  var import_sequelize5 = require("sequelize");
@@ -1368,7 +1376,7 @@ function registerRbqCommands(ctx, connected) {
1368
1376
  if (!list || list.length === 0) {
1369
1377
  return "当前群聊还没有设置任何rbq";
1370
1378
  }
1371
- return "当前群聊rbq列表:\n" + list.map((item) => (0, import_koishi11.h)("at", { id: item })).join(",");
1379
+ return "当前群聊rbq列表:\n" + list.map((item) => (0, import_koishi12.h)("at", { id: item })).join(",");
1372
1380
  });
1373
1381
  ctx.command("rbqadd <参数>", "添加rbq").action(async ({ session }, ...args) => {
1374
1382
  if (!dev_mode) {
@@ -1386,7 +1394,7 @@ function registerRbqCommands(ctx, connected) {
1386
1394
  exec = await create_person(session.guildId, uid);
1387
1395
  if (!exec.result)
1388
1396
  return `添加rbq失败: ${exec.error}`;
1389
- return "已添加rbq:" + (0, import_koishi11.h)("at", { id: uid });
1397
+ return "已添加rbq:" + (0, import_koishi12.h)("at", { id: uid });
1390
1398
  });
1391
1399
  ctx.command("rbqinstead <参数>", "替换rbq").action(async ({ session }, ...args) => {
1392
1400
  if (!dev_mode) {
@@ -1411,12 +1419,12 @@ function registerRbqCommands(ctx, connected) {
1411
1419
  exec = await instead_person(session.guildId, source_uid, new_target);
1412
1420
  if (!exec.result)
1413
1421
  return `替换rbq失败:${exec.error}`;
1414
- return "倒反天罡!进去吧你,已替换rbq:\n" + (0, import_koishi11.h)("at", { id: source_uid }) + " -> " + (0, import_koishi11.h)("at", { id: new_target });
1422
+ return "倒反天罡!进去吧你,已替换rbq:\n" + (0, import_koishi12.h)("at", { id: source_uid }) + " -> " + (0, import_koishi12.h)("at", { id: new_target });
1415
1423
  }
1416
1424
  exec = await instead_person(session.guildId, source_uid, target_uid);
1417
1425
  if (!exec.result)
1418
1426
  return `替换rbq失败:${exec.error}`;
1419
- return (0, import_koishi11.h)("p", "已替换rbq:", (0, import_koishi11.h)("at", { id: source_uid }), " -> ", (0, import_koishi11.h)("at", { id: target_uid }));
1427
+ return (0, import_koishi12.h)("p", "已替换rbq:", (0, import_koishi12.h)("at", { id: source_uid }), " -> ", (0, import_koishi12.h)("at", { id: target_uid }));
1420
1428
  });
1421
1429
  ctx.command("rbqadd_txt <参数>", "添加自定义文本").action(async ({ session }, ...args) => {
1422
1430
  if (!dev_mode) {
@@ -1443,10 +1451,10 @@ function registerRbqCommands(ctx, connected) {
1443
1451
  const contents = await get_content_list(session.guildId, target_uid);
1444
1452
  let content2 = "*死你";
1445
1453
  if (contents && contents.length > 0) {
1446
- const random = new import_koishi11.Random(() => Math.random());
1454
+ const random = new import_koishi12.Random(() => Math.random());
1447
1455
  content2 = contents[random.int(0, contents.length)];
1448
1456
  }
1449
- return (0, import_koishi11.h)("at", { id: target_uid }) + "还想自己加文本?!\n" + content2;
1457
+ return (0, import_koishi12.h)("at", { id: target_uid }) + "还想自己加文本?!\n" + content2;
1450
1458
  } catch (error) {
1451
1459
  logger.error("[rbq rbqadd_txt] Error:", error);
1452
1460
  return "不能给自己设置文本,请输入其他qq号";
@@ -1476,10 +1484,10 @@ function registerRbqCommands(ctx, connected) {
1476
1484
  const contents = await get_content_list(guildId, matchedUid);
1477
1485
  let content = "*死你";
1478
1486
  if (contents && contents.length > 0) {
1479
- const random = new import_koishi11.Random(() => Math.random());
1487
+ const random = new import_koishi12.Random(() => Math.random());
1480
1488
  content = contents[random.int(0, contents.length)];
1481
1489
  }
1482
- return (0, import_koishi11.h)("at", { id: matchedUid }) + " " + content;
1490
+ return (0, import_koishi12.h)("at", { id: matchedUid }) + " " + content;
1483
1491
  } catch (error) {
1484
1492
  logger.error("[rbq middleware] Error:", error);
1485
1493
  return next();
@@ -1528,14 +1536,19 @@ var import_tesseract2 = require("tesseract.js");
1528
1536
 
1529
1537
  // src/utils/ai_axios.ts
1530
1538
  var import_axios = __toESM(require("axios"));
1531
- async function callOpenRouter(api_url, api_key, api_model = "gpt-4o-mini", messages) {
1539
+ async function callOpenRouter(api_url, api_key, api_model = "gpt-4o-mini", messages, tools2, tool_choice) {
1532
1540
  try {
1541
+ const requestBody = {
1542
+ model: api_model,
1543
+ messages
1544
+ };
1545
+ if (tools2 && tools2.length > 0) {
1546
+ requestBody.tools = tools2;
1547
+ requestBody.tool_choice = tool_choice ?? "auto";
1548
+ }
1533
1549
  const { data } = await import_axios.default.post(
1534
1550
  api_url,
1535
- {
1536
- model: api_model,
1537
- messages
1538
- },
1551
+ requestBody,
1539
1552
  {
1540
1553
  headers: {
1541
1554
  Authorization: `Bearer ${api_key}`,
@@ -1544,7 +1557,17 @@ async function callOpenRouter(api_url, api_key, api_model = "gpt-4o-mini", messa
1544
1557
  }
1545
1558
  );
1546
1559
  const choices = data?.choices ?? [];
1547
- const reply = choices[0]?.message?.content;
1560
+ const message = choices[0]?.message;
1561
+ const reply = message?.content;
1562
+ const tool_calls = message?.tool_calls;
1563
+ if (tool_calls && tool_calls.length > 0) {
1564
+ const firstToolCall = tool_calls[0];
1565
+ return {
1566
+ err: null,
1567
+ resp: firstToolCall.function.arguments,
1568
+ tool_calls
1569
+ };
1570
+ }
1548
1571
  let responseText;
1549
1572
  let err = null;
1550
1573
  if (typeof reply === "string") {
@@ -1557,20 +1580,46 @@ async function callOpenRouter(api_url, api_key, api_model = "gpt-4o-mini", messa
1557
1580
  if (!responseText) {
1558
1581
  err = "OpenRouter 返回空内容";
1559
1582
  }
1583
+ } else if (reply === null) {
1584
+ err = "OpenRouter 返回空内容";
1585
+ responseText = "";
1560
1586
  } else {
1561
1587
  err = "OpenRouter 返回了未知格式,请检查日志";
1588
+ responseText = "";
1562
1589
  }
1563
- return { err, resp: responseText };
1590
+ return { err, resp: responseText, tool_calls: void 0 };
1564
1591
  } catch (error) {
1565
1592
  const err = error;
1566
1593
  const status = err.response?.status;
1567
- const detail = err.response?.data?.error || err.response?.data?.message || err.message;
1594
+ const responseData = err.response?.data;
1595
+ let detail = responseData?.error || responseData?.message || err.message;
1596
+ let errorCode = responseData?.code;
1597
+ if (typeof detail === "object" && detail !== null) {
1598
+ const errorMsg = detail.message || detail.error || JSON.stringify(detail);
1599
+ errorCode = detail.code || errorCode;
1600
+ detail = errorMsg;
1601
+ }
1568
1602
  logger.error("[callOpenRouter Error]: OpenRouter 请求失败", {
1569
1603
  status,
1604
+ code: errorCode,
1570
1605
  detail,
1571
- url: err.config?.url
1606
+ url: err.config?.url,
1607
+ model: api_model,
1608
+ hasTools: tools2 && tools2.length > 0,
1609
+ requestBody: tools2 && tools2.length > 0 ? {
1610
+ model: api_model,
1611
+ hasTools: true,
1612
+ tool_choice: tool_choice ?? "auto"
1613
+ } : void 0
1572
1614
  });
1573
- const errorMessage = `test error${status ? `(${status})` : ""}: ${detail}`;
1615
+ if (status === 404 && tools2 && tools2.length > 0) {
1616
+ const toolErrorHint = `模型 "${api_model}" 可能不支持工具调用,或模型名称格式不正确(应包含 provider 前缀,如 "deepseek/deepseek-chat-v3.1")。请检查模型配置。`;
1617
+ return {
1618
+ err: `OpenRouter error(${status}): ${detail}. ${toolErrorHint}`,
1619
+ resp: null
1620
+ };
1621
+ }
1622
+ const errorMessage = `OpenRouter error${status ? `(${status})` : ""}: ${detail}`;
1574
1623
  return { err: errorMessage, resp: null };
1575
1624
  }
1576
1625
  }
@@ -1692,7 +1741,7 @@ __name(is_at_bot_quote, "is_at_bot_quote");
1692
1741
 
1693
1742
  // src/services/himg_func/himg_service.ts
1694
1743
  var import_axios2 = __toESM(require("axios"));
1695
- var import_koishi12 = require("koishi");
1744
+ var import_koishi13 = require("koishi");
1696
1745
  async function randomHImg(keywords, ...args) {
1697
1746
  try {
1698
1747
  const r18 = keywords?.[0];
@@ -1700,7 +1749,7 @@ async function randomHImg(keywords, ...args) {
1700
1749
  const params = new URLSearchParams();
1701
1750
  params.append("excludeAI", "true");
1702
1751
  params.append("size", "regular");
1703
- const random = new import_koishi12.Random(() => Math.random());
1752
+ const random = new import_koishi13.Random(() => Math.random());
1704
1753
  if (r18) {
1705
1754
  if (r18.toLowerCase() === "r18") {
1706
1755
  params.append("r18", "1");
@@ -1721,7 +1770,7 @@ async function randomHImg(keywords, ...args) {
1721
1770
  let author = item.author;
1722
1771
  let url = item.urls.regular;
1723
1772
  let tags2 = item.tags;
1724
- result_content += "作者: " + author + "\n标签: \n[" + tags2.join(",") + "]\n" + import_koishi12.h.image(url) + "\n";
1773
+ result_content += "作者: " + author + "\n标签: \n[" + tags2.join(",") + "]\n" + import_koishi13.h.image(url) + "\n";
1725
1774
  }
1726
1775
  return {
1727
1776
  result: result_content,
@@ -1777,6 +1826,172 @@ function registerHImgCommands(ctx) {
1777
1826
  }
1778
1827
  __name(registerHImgCommands, "registerHImgCommands");
1779
1828
 
1829
+ // src/services/wish_func/wish_command.ts
1830
+ var import_koishi14 = require("koishi");
1831
+
1832
+ // src/services/wish_func/wish_service.ts
1833
+ var chatHistory2 = [];
1834
+ var tools = [
1835
+ {
1836
+ type: "function",
1837
+ function: {
1838
+ name: "wish_audit_result",
1839
+ description: "对用户愿望进行合规审计并返回结构化结果",
1840
+ parameters: {
1841
+ type: "object",
1842
+ properties: {
1843
+ category: {
1844
+ type: "string",
1845
+ enum: ["block", "allow"],
1846
+ description: "是否允许该愿望"
1847
+ },
1848
+ reason: {
1849
+ type: "string",
1850
+ description: "block:说明触犯的禁忌类型;allow:说明内容合规"
1851
+ },
1852
+ wish: {
1853
+ type: "string",
1854
+ description: "allow:复述用户愿望(去除语气词);block:必须为空字符串"
1855
+ }
1856
+ },
1857
+ required: ["category", "reason", "wish"],
1858
+ additionalProperties: false
1859
+ }
1860
+ }
1861
+ },
1862
+ {
1863
+ type: "function",
1864
+ function: {
1865
+ name: "wish_generation_result",
1866
+ description: "生成愿望实现的场景",
1867
+ parameters: {
1868
+ type: "object",
1869
+ properties: {
1870
+ scenario: {
1871
+ type: "string",
1872
+ description: "愿望实现的场景"
1873
+ }
1874
+ },
1875
+ required: ["scenario"],
1876
+ additionalProperties: false
1877
+ }
1878
+ }
1879
+ }
1880
+ ];
1881
+ async function checkAudit(local_config4, wish_content, config, wish_config) {
1882
+ let prompt_msg = "";
1883
+ if (!local_config4) return { result: false, reason: "未加载配置文件,请查看日志" };
1884
+ prompt_msg = local_config4.wish_config?.prompts["audit"];
1885
+ if (!prompt_msg) return { result: false, reason: "未找到prompt,请查看日志" };
1886
+ try {
1887
+ prompt_msg = prompt_msg.replace("{{USER_TEXT}}", wish_content);
1888
+ chatHistory2 = [];
1889
+ chatHistory2.push({ role: "system", content: [{ type: "text", text: prompt_msg }] });
1890
+ const using_model = wish_config.api_model || config.api_model;
1891
+ const { err, resp } = await callOpenRouter(
1892
+ config.api_url,
1893
+ config.api_key,
1894
+ using_model,
1895
+ chatHistory2,
1896
+ tools,
1897
+ { type: "function", function: { name: "wish_audit_result" } }
1898
+ );
1899
+ if (err != null) {
1900
+ logger.error("[checkAudit Error]: " + err);
1901
+ return { result: false, reason: err };
1902
+ }
1903
+ if (!resp) {
1904
+ logger.error("[checkAudit Error]: API返回为空");
1905
+ return { result: false, reason: "API返回为空" };
1906
+ }
1907
+ const json = JSON.parse(resp);
1908
+ if (json.category == "block") {
1909
+ logger.info("[checkAudit Info]: 愿望被拒绝,原因: " + json.reason);
1910
+ return { result: false, reason: json.reason };
1911
+ }
1912
+ if (json.category == "allow" || json.category == "review") {
1913
+ return { result: true, reason: json.reason };
1914
+ }
1915
+ logger.error("[checkAudit Error]: API返回有误,未触发block或allow/review: " + resp);
1916
+ return { result: false, reason: "API返回有误,未触发block或allow/review" };
1917
+ } catch (e) {
1918
+ logger.error("[checkAudit Error]: " + e);
1919
+ return { result: false, reason: "未知错误,请查看日志" };
1920
+ }
1921
+ }
1922
+ __name(checkAudit, "checkAudit");
1923
+ async function gernerationSoluation(local_config4, wish_content, config, wish_config) {
1924
+ let prompt_msg = "";
1925
+ if (!local_config4) return "未加载配置文件,请查看日志";
1926
+ prompt_msg = local_config4.wish_config?.prompts["generation"];
1927
+ if (!prompt_msg) return "未找到prompt,请查看日志";
1928
+ try {
1929
+ prompt_msg = prompt_msg.replace("{{USER_TEXT}}", wish_content);
1930
+ chatHistory2 = [];
1931
+ chatHistory2.push({ role: "system", content: [{ type: "text", text: prompt_msg }] });
1932
+ const using_model = wish_config.api_model || config.api_model;
1933
+ const { err, resp } = await callOpenRouter(
1934
+ config.api_url,
1935
+ config.api_key,
1936
+ using_model,
1937
+ chatHistory2,
1938
+ tools,
1939
+ { type: "function", function: { name: "wish_generation_result" } }
1940
+ );
1941
+ if (err != null) {
1942
+ logger.error("[gernerationSoluation Error]: " + err);
1943
+ return null;
1944
+ }
1945
+ const json = JSON.parse(resp);
1946
+ const scenario = json.scenario;
1947
+ if (!scenario) {
1948
+ logger.info("[gernerationSoluation Info]: API返回有误: " + resp);
1949
+ return null;
1950
+ }
1951
+ return scenario;
1952
+ } catch (e) {
1953
+ logger.error("[gernerationSoluation Error]: " + e);
1954
+ return null;
1955
+ }
1956
+ }
1957
+ __name(gernerationSoluation, "gernerationSoluation");
1958
+
1959
+ // src/services/wish_func/wish_command.ts
1960
+ var local_config2 = null;
1961
+ var think_flag2 = false;
1962
+ function registerWishCommands(ctx, ai_config, wish_config) {
1963
+ if (wish_config?.config_path) {
1964
+ local_config2 = loadYamlConfig(wish_config.config_path);
1965
+ if (local_config2) {
1966
+ logger.info("[loadYamlConfig Info]: Wish 成功加载配置文件");
1967
+ } else {
1968
+ logger.error("[loadYamlConfig Error]: Wish 配置文件加载失败,将使用默认配置");
1969
+ }
1970
+ } else {
1971
+ logger.error("[loadYamlConfig Error]: 未配置 Wish 配置文件路径");
1972
+ }
1973
+ ctx.command("wish <参数>", "许愿").action(async ({ session }, ...args) => {
1974
+ if (!dev_mode) {
1975
+ if (!is_at_bot(session)) return "请提供正确格式,如: @bot wish [愿望消息(不要超过80字)]";
1976
+ }
1977
+ if (think_flag2) return "请等待上一位的祈祷结果";
1978
+ const wish_content = args?.[0];
1979
+ if (!wish_content) return "输入愿望消息,不要超过80字";
1980
+ await session.send("已收到,正在祈祷中...");
1981
+ think_flag2 = true;
1982
+ try {
1983
+ let exec = await checkAudit(local_config2, wish_content, ai_config, wish_config);
1984
+ if (!exec) return "愿望不合规被拒绝,请重新许愿";
1985
+ let exec_generation = await gernerationSoluation(local_config2, wish_content, ai_config, wish_config);
1986
+ if (!exec_generation) return "愿望实现失败,请重新许愿";
1987
+ return (0, import_koishi14.h)("at", { id: session.userId }) + "\n" + exec_generation;
1988
+ } finally {
1989
+ think_flag2 = false;
1990
+ }
1991
+ });
1992
+ }
1993
+ __name(registerWishCommands, "registerWishCommands");
1994
+
1780
1995
  // src/services/kuro_func/kuro_service.ts
1781
1996
  var import_axios3 = __toESM(require("axios"));
1782
1997
  var import_qs = __toESM(require("qs"));
@@ -2186,7 +2401,7 @@ function registerKuroCommands(ctx, connected) {
2186
2401
  __name(registerKuroCommands, "registerKuroCommands");
2187
2402
 
2188
2403
  // src/services/game_func/game_command.ts
2189
- var import_koishi13 = require("koishi");
2404
+ var import_koishi15 = require("koishi");
2190
2405
 
2191
2406
  // src/services/game_func/game_service.ts
2192
2407
  var gameTimeout = null;
@@ -2215,11 +2430,11 @@ __name(clearGameTimeout, "clearGameTimeout");
2215
2430
  // src/services/game_func/games/game_turtlesoup_service.ts
2216
2431
  var is_gaming = false;
2217
2432
  var chatPrompt = [];
2218
- var chatHistory2 = [];
2433
+ var chatHistory3 = [];
2219
2434
  async function startSituationPuzzle(config) {
2220
2435
  chatPrompt = [];
2221
- chatHistory2 = [];
2222
- const prompt_start = local_config2?.game?.situation_puzzle;
2436
+ chatHistory3 = [];
2437
+ const prompt_start = local_config3?.game?.situation_puzzle;
2223
2438
  chatPrompt.push({ role: "system", content: [{ type: "text", text: prompt_start }] });
2224
2439
  const { err, resp } = await callOpenRouter(config.api_url, config.api_key, config.api_model, chatPrompt);
2225
2440
  if (err != null) {
@@ -2234,7 +2449,7 @@ async function startSituationPuzzle(config) {
2234
2449
  logger.info(`[SituationPuzzle Timeout]: 游戏已超时(${GAME_TIMEOUT_MINUTES}分钟),自动结束游戏`);
2235
2450
  is_gaming = false;
2236
2451
  chatPrompt = [];
2237
- chatHistory2 = [];
2452
+ chatHistory3 = [];
2238
2453
  setGameTimeout(null);
2239
2454
  }, GAME_TIMEOUT_MINUTES * 60 * 1e3);
2240
2455
  logger.info("[startSituationPuzzle Info]: ai api send message success");
@@ -2242,9 +2457,9 @@ async function startSituationPuzzle(config) {
2242
2457
  }
2243
2458
  __name(startSituationPuzzle, "startSituationPuzzle");
2244
2459
  async function questSituationPuzzle(content, config) {
2245
- chatHistory2 = [...chatPrompt];
2246
- chatHistory2.push({ role: "user", content: [{ type: "text", text: content }] });
2247
- const { err, resp } = await callOpenRouter(config.api_url, config.api_key, config.api_model, chatHistory2);
2460
+ chatHistory3 = [...chatPrompt];
2461
+ chatHistory3.push({ role: "user", content: [{ type: "text", text: content }] });
2462
+ const { err, resp } = await callOpenRouter(config.api_url, config.api_key, config.api_model, chatHistory3);
2248
2463
  if (err != null) {
2249
2464
  logger.error("[questSituationPuzzle Error]: " + err);
2250
2465
  return null;
@@ -2253,7 +2468,7 @@ async function questSituationPuzzle(content, config) {
2253
2468
  if (resp.includes("猜中了")) {
2254
2469
  is_gaming = false;
2255
2470
  chatPrompt = [];
2256
- chatHistory2 = [];
2471
+ chatHistory3 = [];
2257
2472
  clearGameTimeout();
2258
2473
  } else {
2259
2474
  clearGameTimeout();
@@ -2261,7 +2476,7 @@ async function questSituationPuzzle(content, config) {
2261
2476
  logger.info(`[SituationPuzzle Timeout]: 游戏已超时(${GAME_TIMEOUT_MINUTES}分钟),自动结束游戏`);
2262
2477
  is_gaming = false;
2263
2478
  chatPrompt = [];
2264
- chatHistory2 = [];
2479
+ chatHistory3 = [];
2265
2480
  setGameTimeout(null);
2266
2481
  }, GAME_TIMEOUT_MINUTES * 60 * 1e3);
2267
2482
  }
@@ -2270,9 +2485,9 @@ async function questSituationPuzzle(content, config) {
2270
2485
  __name(questSituationPuzzle, "questSituationPuzzle");
2271
2486
  async function endSituationPuzzle(config) {
2272
2487
  is_gaming = false;
2273
- chatHistory2 = [...chatPrompt];
2274
- chatHistory2.push({ role: "user", content: [{ type: "text", text: "结束游戏,请给出答案" }] });
2275
- const { err, resp } = await callOpenRouter(config.api_url, config.api_key, config.api_model, chatHistory2);
2488
+ chatHistory3 = [...chatPrompt];
2489
+ chatHistory3.push({ role: "user", content: [{ type: "text", text: "结束游戏,请给出答案" }] });
2490
+ const { err, resp } = await callOpenRouter(config.api_url, config.api_key, config.api_model, chatHistory3);
2276
2491
  if (err != null) {
2277
2492
  logger.error("[endSituationPuzzle Error]: " + err);
2278
2493
  return null;
@@ -2283,16 +2498,16 @@ async function endSituationPuzzle(config) {
2283
2498
  }
2284
2499
  __name(endSituationPuzzle, "endSituationPuzzle");
2285
2500
  async function rerollSituationPuzzle(config) {
2286
- chatHistory2 = [...chatPrompt];
2287
- chatHistory2.push({ role: "user", content: [{ type: "text", text: "重新生成新谜题" }] });
2288
- const { err, resp } = await callOpenRouter(config.api_url, config.api_key, config.api_model, chatHistory2);
2501
+ chatHistory3 = [...chatPrompt];
2502
+ chatHistory3.push({ role: "user", content: [{ type: "text", text: "重新生成新谜题" }] });
2503
+ const { err, resp } = await callOpenRouter(config.api_url, config.api_key, config.api_model, chatHistory3);
2289
2504
  if (err != null) {
2290
2505
  logger.error("[rerollSituationPuzzle Error]: " + err);
2291
2506
  chatPrompt.pop();
2292
2507
  return null;
2293
2508
  }
2294
2509
  chatPrompt = [];
2295
- const prompt_start = local_config2?.game?.situation_puzzle;
2510
+ const prompt_start = local_config3?.game?.situation_puzzle;
2296
2511
  chatPrompt.push({ role: "system", content: [{ type: "text", text: prompt_start }] });
2297
2512
  chatPrompt.push({ role: "assistant", content: [{ type: "text", text: resp }] });
2298
2513
  is_gaming = true;
@@ -2301,7 +2516,7 @@ async function rerollSituationPuzzle(config) {
2301
2516
  logger.info(`[SituationPuzzle Timeout]: 游戏已超时(${GAME_TIMEOUT_MINUTES}分钟),自动结束游戏`);
2302
2517
  is_gaming = false;
2303
2518
  chatPrompt = [];
2304
- chatHistory2 = [];
2519
+ chatHistory3 = [];
2305
2520
  setGameTimeout(null);
2306
2521
  }, GAME_TIMEOUT_MINUTES * 60 * 1e3);
2307
2522
  logger.info("[rerollSituationPuzzle Info]: ai api send message success");
@@ -2411,7 +2626,7 @@ function getSolution() {
2411
2626
  __name(getSolution, "getSolution");
2412
2627
 
2413
2628
  // src/services/game_func/game_command.ts
2414
- var local_config2 = null;
2629
+ var local_config3 = null;
2415
2630
  var is_thinking = false;
2416
2631
  var now_game = null;
2417
2632
  var gameList = [
@@ -2428,12 +2643,13 @@ var gameList = [
2428
2643
  ];
2429
2644
  var commandList = [
2430
2645
  "gamelist",
2431
- "startgame"
2646
+ "startgame",
2647
+ "endgame"
2432
2648
  ];
2433
2649
  function registerGameCommands(ctx, game_config, ai_config) {
2434
2650
  if (game_config?.config_path) {
2435
- local_config2 = loadYamlConfig(game_config.config_path);
2436
- if (local_config2) {
2651
+ local_config3 = loadYamlConfig(game_config.config_path);
2652
+ if (local_config3) {
2437
2653
  logger.info("[loadYamlConfig Info]: Game 成功加载配置文件");
2438
2654
  } else {
2439
2655
  logger.error("[loadYamlConfig Error]: Game 配置文件加载失败,将使用默认配置");
@@ -2442,7 +2658,7 @@ function registerGameCommands(ctx, game_config, ai_config) {
2442
2658
  logger.error("[loadYamlConfig Error]: 未配置 Game 配置文件路径");
2443
2659
  }
2444
2660
  if (GAME_TIMEOUT_MINUTES <= 0) {
2445
- setGameTimeoutMinutes(local_config2?.game?.timeout_minutes || 10);
2661
+ setGameTimeoutMinutes(local_config3?.game?.timeout_minutes || 10);
2446
2662
  }
2447
2663
  ctx.command("gamelist", "查看所有游戏").action(async ({}) => {
2448
2664
  return `[所有命令都需要@bot]
@@ -2493,7 +2709,6 @@ function registerGameCommands(ctx, game_config, ai_config) {
2493
2709
  let resp_text = "";
2494
2710
  switch (now_game) {
2495
2711
  case gameList[0].command:
2496
- await session.send("正在结束游戏...");
2497
2712
  resp_text = await endSituationPuzzle(ai_config);
2498
2713
  now_game = null;
2499
2714
  return checkResp(resp_text);
@@ -2539,6 +2754,7 @@ async function situationPuzzleMiddleware(session, ai_config) {
2539
2754
  const withoutTags = content.replace(/<[^>]+>/g, " ");
2540
2755
  const text = withoutTags.replace(/\s+/g, " ").trim();
2541
2756
  try {
2757
+ if (is_thinking) return "正在思考,请耐心等待...";
2542
2758
  is_thinking = true;
2543
2759
  if (text.includes("reroll")) {
2544
2760
  const resp2 = await rerollSituationPuzzle(ai_config);
@@ -2551,7 +2767,7 @@ async function situationPuzzleMiddleware(session, ai_config) {
2551
2767
  return checkResp(resp2);
2552
2768
  }
2553
2769
  const resp = await questSituationPuzzle(text, ai_config);
2554
- return (0, import_koishi13.h)("at", { id: userId }) + " " + checkResp(resp);
2770
+ return (0, import_koishi15.h)("at", { id: userId }) + " " + checkResp(resp);
2555
2771
  } finally {
2556
2772
  is_thinking = false;
2557
2773
  }
@@ -2568,17 +2784,18 @@ __name(checkResp, "checkResp");
2568
2784
  // src/index.ts
2569
2785
  var name = "cocoyyy-console";
2570
2786
  var dev_mode;
2571
- var Config = import_koishi14.Schema.object({
2787
+ var Config = import_koishi16.Schema.object({
2572
2788
  function_config: FunctionConfigSchema.description("功能开关配置"),
2573
2789
  ai_config: AiAPIConfigSchema.description("AI API配置"),
2574
2790
  mysql_config: MysqlConfigSchema.description("MySQL 数据库配置"),
2575
2791
  tag_config: SaveConfigSchema.description("tag图片保存配置"),
2576
2792
  repeat_config: RepeatConfigSchema.description("复读配置"),
2577
2793
  son_config: ShitOrNotConfigSchema.description("SON配置"),
2794
+ wish_config: WishConfigSchema.description("许愿配置"),
2578
2795
  game_config: GameConfigSchema.description("游戏配置"),
2579
- test: import_koishi14.Schema.string().description("测试")
2796
+ test: import_koishi16.Schema.string().description("测试")
2580
2797
  });
2581
- var logger = new import_koishi14.Logger(name);
2798
+ var logger = new import_koishi16.Logger(name);
2582
2799
  var savePath = null;
2583
2800
  async function apply(ctx, config) {
2584
2801
  ctx = ctx.guild();
@@ -2602,6 +2819,8 @@ async function apply(ctx, config) {
2602
2819
  registerShitOrNotCommands(ctx, config?.ai_config, config?.son_config);
2603
2820
  if (config.function_config.setu_flag)
2604
2821
  registerHImgCommands(ctx);
2822
+ if (config.function_config.wish_flag)
2823
+ registerWishCommands(ctx, config?.ai_config, config?.wish_config);
2605
2824
  if (config.function_config.game_flag) {
2606
2825
  registerGameCommands(ctx, config?.game_config, config?.ai_config);
2607
2826
  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 };
@@ -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 {};
@@ -6,3 +6,4 @@ export * from './configs/redis_config';
6
6
  export * from './configs/son_config';
7
7
  export * from './configs/game_config';
8
8
  export * from './configs/ai_config';
9
+ export * from './configs/wish_config';
@@ -7,6 +7,7 @@ interface FunctionConfig {
7
7
  rbq_flag: boolean;
8
8
  son_flag: boolean;
9
9
  setu_flag: boolean;
10
+ wish_flag: boolean;
10
11
  game_flag: boolean;
11
12
  kuro_flag: boolean;
12
13
  }
@@ -0,0 +1,7 @@
1
+ import { Schema } from 'koishi';
2
+ interface WishConfig {
3
+ config_path?: string;
4
+ api_model?: string;
5
+ }
6
+ declare const WishConfigSchema: Schema<WishConfig>;
7
+ export { WishConfig, WishConfigSchema, };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-cocoyyy-console",
3
3
  "description": "自用koishi插件,功能包含复读,记录黑历史,*人等",
4
- "version": "1.1.3-alpha.4",
4
+ "version": "1.1.3-alpha.6",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "contributors": [