koishi-plugin-satori-ai 1.3.7 → 1.3.8

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.js CHANGED
@@ -46,8 +46,8 @@ __export(src_exports, {
46
46
  refreshPuppeteer: () => refreshPuppeteer
47
47
  });
48
48
  module.exports = __toCommonJS(src_exports);
49
- var import_koishi14 = require("koishi");
50
- var path7 = __toESM(require("path"));
49
+ var import_koishi13 = require("koishi");
50
+ var path6 = __toESM(require("path"));
51
51
 
52
52
  // src/api.ts
53
53
  var import_koishi2 = require("koishi");
@@ -347,6 +347,12 @@ function countCommonChars(str1, str2) {
347
347
  const count2 = chars2.get(char) || 0;
348
348
  commonCount += Math.min(count1, count2);
349
349
  }
350
+ const countDigits = /* @__PURE__ */ __name((s) => (s.match(/\d/g) || []).length, "countDigits");
351
+ const digits1 = countDigits(str1);
352
+ const digits2 = countDigits(str2);
353
+ if (digits1 >= 3 || digits2 >= 3) {
354
+ return Math.max(commonCount, 2);
355
+ }
350
356
  return commonCount;
351
357
  }
352
358
  __name(countCommonChars, "countCommonChars");
@@ -451,7 +457,7 @@ var APIClient = class {
451
457
  if (i == this.config.maxRetryTimes) {
452
458
  return this.handleAPIError(error);
453
459
  }
454
- await new Promise((resolve3) => setTimeout(resolve3, this.config.retry_delay_time || 5e3));
460
+ await new Promise((resolve2) => setTimeout(resolve2, this.config.retry_delay_time || 5e3));
455
461
  logger2.warn(`生成画像时API请求失败(${error}),重试(第${i}次)中...`);
456
462
  continue;
457
463
  }
@@ -508,7 +514,7 @@ var APIClient = class {
508
514
  if (i == this.config.maxRetryTimes) {
509
515
  return this.handleAPIError(error);
510
516
  }
511
- await new Promise((resolve3) => setTimeout(resolve3, this.config.retry_delay_time || 5e3));
517
+ await new Promise((resolve2) => setTimeout(resolve2, this.config.retry_delay_time || 5e3));
512
518
  logger2.warn(`API请求失败(${error}),重试(第${i}次)中...`);
513
519
  continue;
514
520
  }
@@ -582,7 +588,7 @@ var MemoryManager = class {
582
588
  }
583
589
  channelMemories = /* @__PURE__ */ new Map();
584
590
  channelDialogues = /* @__PURE__ */ new Map();
585
- charactersToRemove = ["的", "一", "是", "了", "什", "么", "我", "谁", "不", "人", "在", "他", "有", "这", "个", "上", "们", "来", "到", "时", "大", "地", "为", "子", "中", "你", "说", "生", "国", "年", "着", "就", "那", "和", "要", "她", "出", "也", "得", "里", "后", "自", "以", "会", "id=", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"];
591
+ charactersToRemove = ["的", "一", "是", "了", "什", "么", "我", "谁", "不", "人", "在", "他", "有", "这", "个", "上", "们", "来", "到", "时", "大", "地", "为", "子", "中", "你", "说", "生", "国", "年", "着", "就", "那", "和", "要", "她", "出", "也", "得", "里", "后", "自", "以", "会", "id="];
586
592
  MAX_MEMORY_LENGTH = 5e3;
587
593
  // 更新记忆
588
594
  async updateMemories(session, prompt, config, response) {
@@ -617,7 +623,7 @@ var MemoryManager = class {
617
623
  if (!this.config.channel_dialogues)
618
624
  return "";
619
625
  const Dialogue = this.channelDialogues[session.channelId]?.join("\n") || "";
620
- const result = "以下是群聊内群友最近的聊天记录,当用户话题涉及其中内容时你可以参考这些信息:{\n" + Dialogue + "\n}\n";
626
+ const result = "以下是群聊内最近的包括所有人的聊天记录,当当前对话涉及其中内容时你可以参考这些信息,但是要注意分辨发言人是谁:{\n" + Dialogue + "\n}\n";
621
627
  return result;
622
628
  }
623
629
  // 括号引号过滤
@@ -1255,9 +1261,6 @@ var Sat = class extends import_koishi5.Service {
1255
1261
  import_koishi5.Schema.object({
1256
1262
  enable_game: import_koishi5.Schema.boolean().default(false).description("是否开启游戏模块"),
1257
1263
  game_block_channel: import_koishi5.Schema.array(String).description("不提供游戏的频道id"),
1258
- enable_gobang: import_koishi5.Schema.boolean().default(false).description("是否开启五子棋游戏(需要puppeteer支持)"),
1259
- channel_id_for_gobang: import_koishi5.Schema.array(String).description("启用五子棋的游戏频道id(不建议太多,第一个会被公示)"),
1260
- cd_for_gobang: import_koishi5.Schema.number().default(3600).description("每人五子棋游戏cd时间(秒)"),
1261
1264
  enable_OneTouch: import_koishi5.Schema.boolean().default(false).description("是否开启一碰一游戏(需要puppeteer支持)"),
1262
1265
  cd_for_OneTouch: import_koishi5.Schema.number().default(600).description("每人一碰一游戏cd时间(秒)"),
1263
1266
  enable_fencing: import_koishi5.Schema.boolean().default(false).description("是否开启击剑游戏(无效,开发中)")
@@ -1309,7 +1312,7 @@ var UserPortraitManager = class {
1309
1312
  });
1310
1313
  fs5.writeFileSync(memoryPath, JSON.stringify(replacedContent, null, 2));
1311
1314
  const validEntries = replacedContent.filter((entry) => entry.role !== "user").map((entry) => {
1312
- const timeMatch = entry.role.match(/对话日期和时间:(\d{4}\/\d{1,2}\/\d{1,2} \d{2}:\d{2}:\d{2})/);
1315
+ const timeMatch = entry.role.match(/对话日期和时间:(\d{1,2}\/\d{1,2}\/\d{4}), (\d{1,2}:\d{2}:\d{2} [AP]M)/);
1313
1316
  if (!timeMatch)
1314
1317
  return null;
1315
1318
  return {
@@ -1323,11 +1326,11 @@ var UserPortraitManager = class {
1323
1326
  return validEntries.slice(0, maxEntries).map((entry) => `${entry.content}${entry.role}`);
1324
1327
  }
1325
1328
  // 生成提示词模板
1326
- buildMessage(level, history, existingPortrait, user) {
1329
+ buildFirstMessage(level, history, user) {
1327
1330
  return [{
1328
1331
  role: "user",
1329
- content: `你是一个角色扮演智能体工作流中的一环,请根据以下信息更新用户画像。需包括:
1330
- 1. 基本信息(性别、年龄、生日等,不要遗漏或改动已有的信息)
1332
+ content: `你是一个角色扮演智能体工作流中的一环,请根据以下信息生成户画像。可选内容包括:
1333
+ 1. 基本信息(性别、年龄、生日等)
1331
1334
  2. 生活习惯(作息等)
1332
1335
  3. 反感点(如有)
1333
1336
  4. 对AI的期望(从对话历史中推断)
@@ -1335,21 +1338,47 @@ var UserPortraitManager = class {
1335
1338
 
1336
1339
  用户名:${user.usersname}
1337
1340
  你与用户的关系:${level}
1338
- 历史画像:
1339
- ${existingPortrait ? "无" : existingPortrait}
1340
-
1341
1341
  近期的用户发言记录:
1342
1342
  ${history}
1343
1343
 
1344
1344
  注意事项:
1345
+ ·没有涉及到的信息注为无
1345
1346
  ·用户一定是人类,其他情况是角色扮演
1346
- ·根据发言修正历史画像内容,但是历史画像中与发言无关的部分必须保留
1347
1347
  ·尤其注意用户说“记住”的部分,可能是用户希望记录的信息
1348
1348
  ·因为在角色扮演中,用户可能会说出不符合事实的信息,需要根据事实推断,避免盲目相信或主观臆测
1349
1349
  ·使用尽可能简洁的表达
1350
1350
  ·保留不确定性的表述(如"可能"、"似乎"、"用户自称")
1351
1351
  ·保持中立和客观,避免带有个人情感色彩的描述,不要添加评价或建议
1352
1352
  ·仅给出画像内容,不要添加额外的描述、建议、评价、注解等任何内容
1353
+ ·不使用markdown等标记语言,直接书写即可`
1354
+ }];
1355
+ }
1356
+ buildSecondMessage(level, NewPortrait, existingPortrait, user) {
1357
+ return [{
1358
+ role: "user",
1359
+ content: `你是一个角色扮演智能体工作流中的一环,请根据以下信息合并用户画像。内容包括:
1360
+ 1. 基本信息(性别、年龄、生日等,不要遗漏或改动已有的信息)
1361
+ 2. 生活习惯(作息等)
1362
+ 3. 反感点(如有)
1363
+ 4. 对AI的期望(从对话历史中推断)
1364
+ 5. 用户希望记住的信息(如有)
1365
+
1366
+ 用户名:${user.usersname}
1367
+ 你与用户的关系:${level}
1368
+ 已有画像:
1369
+ ${existingPortrait ? "无" : existingPortrait}
1370
+
1371
+ 新补充信息:
1372
+ ${NewPortrait}
1373
+
1374
+ 注意事项:
1375
+ ·用户一定是人类,其他情况是角色扮演
1376
+ ·根据已有画像,补充新信息,避免重复,并且不要遗漏你认为重要信息
1377
+ ·你认为不太重要的信息可以删除
1378
+ ·使用尽可能简洁的表达
1379
+ ·保留不确定性的表述(如"可能"、"似乎"、"用户自称")
1380
+ ·保持中立和客观,避免带有个人情感色彩的描述,不要添加评价或建议
1381
+ ·仅给出画像内容,不要添加额外的描述、建议、评价、注解等任何内容
1353
1382
  ·不使用markdown等标记语言,直接书写即可`
1354
1383
  }];
1355
1384
  }
@@ -1364,10 +1393,12 @@ ${history}
1364
1393
  const dialogues = await this.getDialogues(user);
1365
1394
  const existing = this.readPortrait(user.userid);
1366
1395
  const userlevel = getFavorabilityLevel(user, this.getFavorabilityConfig());
1367
- const messages = this.buildMessage(userlevel, dialogues.join("\n"), existing, user);
1368
1396
  logger5.info(`用户 ${user.userid} 画像生成中...`);
1369
1397
  try {
1370
- const response = await apiClient.generateUserPortrait(user, messages);
1398
+ const FirstMessages = this.buildFirstMessage(userlevel, dialogues.join("\n"), user);
1399
+ const NewPortrait = await apiClient.generateUserPortrait(user, FirstMessages);
1400
+ const SecondMessages = this.buildSecondMessage(userlevel, NewPortrait.content, existing, user);
1401
+ const response = await apiClient.generateUserPortrait(user, SecondMessages);
1371
1402
  if (response && !response.error) {
1372
1403
  this.savePortrait(user, response.content);
1373
1404
  if (user.usage > this.config.portrait_usage - 1)
@@ -1647,9 +1678,9 @@ ${this.config.mood_prompt_2}
1647
1678
  };
1648
1679
 
1649
1680
  // src/game.ts
1650
- var import_koishi12 = require("koishi");
1681
+ var import_koishi11 = require("koishi");
1651
1682
 
1652
- // src/gamegobang.ts
1683
+ // src/gamefencing.ts
1653
1684
  var import_koishi9 = require("koishi");
1654
1685
 
1655
1686
  // src/abstractGame.ts
@@ -1753,270 +1784,8 @@ var abstractGame = class {
1753
1784
  }
1754
1785
  };
1755
1786
 
1756
- // src/gamegobang.ts
1757
- var import_child_process = require("child_process");
1758
- var path6 = __toESM(require("path"));
1759
- var logger8 = new import_koishi9.Logger("satori-game-gobang");
1760
- var BOARD_SIZE = 14;
1761
- var inspireSearchLength = 10;
1762
- var Coordinate = class {
1763
- static {
1764
- __name(this, "Coordinate");
1765
- }
1766
- x;
1767
- y;
1768
- score;
1769
- constructor(a = 0, b = 0, s = 0) {
1770
- this.x = a;
1771
- this.y = b;
1772
- this.score = s;
1773
- }
1774
- };
1775
- async function wrapInHTML(str) {
1776
- if (!puppeteer) {
1777
- logger8.warn("puppeteer未就绪");
1778
- return "出现错误,请联系管理员";
1779
- }
1780
- return puppeteer.render(`<html><body>${str.replaceAll(/\n/g, "<BR>")}</body>
1781
- <style>
1782
- body {
1783
- padding: 10px;
1784
- display: inline-block;
1785
- }
1786
- </style>
1787
- </html>`);
1788
- }
1789
- __name(wrapInHTML, "wrapInHTML");
1790
- var goBangSingleGame = class extends abstractGameSingleGame {
1791
- static {
1792
- __name(this, "goBangSingleGame");
1793
- }
1794
- playerFlag;
1795
- // 玩家棋子颜色(1: 黑棋,2: 白棋)
1796
- winningFlag = 4 /* pending */;
1797
- // 当前胜负状态
1798
- level;
1799
- // AI 难度等级
1800
- board = [];
1801
- // BOARD_SIZExBOARD_SIZE 棋盘状态
1802
- lastScore = 0;
1803
- // 上次评分
1804
- turnsCount = 0;
1805
- // 回合数
1806
- constructor(disposeListener, session) {
1807
- super(disposeListener, session);
1808
- }
1809
- // 初始化棋盘,随机决定玩家先手
1810
- startGame = () => {
1811
- super.startGame();
1812
- this.board = Array.from({ length: BOARD_SIZE }, () => Array(BOARD_SIZE).fill(0));
1813
- this.turnsCount = 0;
1814
- this.playerFlag = Math.round(Math.random()) + 1;
1815
- const getCornerCoordinate = /* @__PURE__ */ __name((i) => {
1816
- const quarter = i < 0.5 ? 0.2 : 0.7;
1817
- const base = Math.round(BOARD_SIZE * quarter);
1818
- return base;
1819
- }, "getCornerCoordinate");
1820
- for (let i = 0; i <= 1; i++) {
1821
- for (let j = 0; j <= 1; j++) {
1822
- const randomX = getCornerCoordinate(i) + 1 - 2 * i;
1823
- const randomY = getCornerCoordinate(j);
1824
- const player = Math.round(Math.random()) + 1;
1825
- this.board[randomX][randomY] = player;
1826
- this.board[randomX + i * 2 - 1][randomY - j * 2 + 1] = 3 - player;
1827
- }
1828
- }
1829
- if (this.playerFlag === 1) {
1830
- this.board[BOARD_SIZE / 2][BOARD_SIZE / 2] = 1;
1831
- this.board[BOARD_SIZE / 2 + (Math.round(Math.random()) ? -1 : 1)][BOARD_SIZE / 2 + (Math.round(Math.random()) ? -1 : 1)] = 2;
1832
- return wrapInHTML("游戏开始,你随机到了先手(黑)\n输入两个数字以下棋,先行后列,例如:“0 13”\n" + this.printBoard());
1833
- } else {
1834
- this.board[BOARD_SIZE / 2][BOARD_SIZE / 2] = 1;
1835
- this.board[BOARD_SIZE / 2 + (Math.round(Math.random()) ? -1 : 1)][BOARD_SIZE / 2 + (Math.round(Math.random()) ? -1 : 1)] = 2;
1836
- this.board[BOARD_SIZE / 2][BOARD_SIZE / 2 + (Math.round(Math.random()) ? -1 : 1)] = 1;
1837
- return wrapInHTML("游戏开始,你随机到了后手(白)\n输入两个数字以下棋,先行后列,例如:“0 13”\n" + this.printBoard());
1838
- }
1839
- };
1840
- // 结束游戏,返回结果
1841
- endGame = async () => {
1842
- super.endGame();
1843
- let bonusLevel = this.level;
1844
- if (this.winningFlag === 1 /* win */ && this.playerFlag === 1) {
1845
- bonusLevel -= 1;
1846
- } else if (this.winningFlag === 2 /* lose */ && this.playerFlag === 1) {
1847
- bonusLevel += 1;
1848
- }
1849
- return { message: `${bonusLevel}`, win: this.winningFlag, gameName: "五子棋", playerID: this.session.userId };
1850
- };
1851
- /**
1852
- * 处理玩家输入(落子坐标)
1853
- * @param str 输入内容,格式为 "x y"
1854
- */
1855
- async processInput(str) {
1856
- const [x, y] = str.split(" ").map((a) => {
1857
- return parseInt(a);
1858
- });
1859
- if (isNaN(x) || isNaN(y))
1860
- return;
1861
- if (x < 0 || x >= BOARD_SIZE || y < 0 || y >= BOARD_SIZE)
1862
- return "坐标超出范围了";
1863
- if (this.board[x][y] !== 0)
1864
- return "这个位置已经有棋子了,别想耍赖";
1865
- if (this.winningFlag !== 4 /* pending */)
1866
- return "游戏已结束";
1867
- this.lastActionTime = Date.now();
1868
- this.board[x][y] = this.playerFlag;
1869
- logger8.info(`level: ${this.level}, player: x: ${x}, y: ${y}`);
1870
- if (this.checkWin(x, y))
1871
- return wrapInHTML(this.printBoard() + "\n游戏已结束,发送结束游戏退出");
1872
- const starttime = Date.now();
1873
- const aiMove = this.getAIMove();
1874
- const endtime = Date.now();
1875
- if (aiMove.x === -1 || aiMove.y === -1) {
1876
- this.winningFlag = 3 /* draw */;
1877
- return "计算失败,视为平局,发送结束游戏退出";
1878
- }
1879
- if (this.turnsCount > 50) {
1880
- this.winningFlag = 3 /* draw */;
1881
- return "平局,发送结束游戏退出";
1882
- }
1883
- logger8.info(`AI 落子坐标: ${aiMove.x} ${aiMove.y},得分: ${aiMove.score},AI 落子耗时: ${endtime - starttime}ms`);
1884
- this.board[aiMove.x][aiMove.y] = 3 - this.playerFlag;
1885
- if (this.turnsCount > 5) {
1886
- setTimeout(() => {
1887
- this.session.send(this.generateChat(aiMove.score));
1888
- }, 1e3);
1889
- }
1890
- this.lastScore = aiMove.score;
1891
- this.turnsCount++;
1892
- if (this.checkWin(aiMove.x, aiMove.y))
1893
- return wrapInHTML(this.printBoard() + "\n游戏已结束,发送结束游戏退出");
1894
- return wrapInHTML(this.printBoard() + "\n我这一步下在这里哦(" + aiMove.x + " " + aiMove.y + " 用时" + (endtime - starttime) + "ms)");
1895
- }
1896
- getAIMove() {
1897
- try {
1898
- const boardStr = this.board.map((row) => row.join(" ")).join(" ");
1899
- const exePath = path6.resolve(__dirname, "../lib/gobang_ai.exe");
1900
- const level = this.turnsCount > 3 ? this.level : Math.min(5, this.level);
1901
- const stdout = (0, import_child_process.execSync)(
1902
- `"${exePath}" "${boardStr}" ${this.playerFlag} ${level} ${inspireSearchLength}`,
1903
- { timeout: 18e5 }
1904
- // 设置1800秒超时
1905
- ).toString().trim();
1906
- const [x, y, score] = stdout.split(" ").map(Number);
1907
- return new Coordinate(x, y, score);
1908
- } catch (error) {
1909
- logger8.error(`AI计算失败: ${error}`);
1910
- }
1911
- return new Coordinate(-1, -1, -1);
1912
- }
1913
- // 检查是否连成五子
1914
- checkWin(x, y) {
1915
- const directions = [[1, 0], [0, 1], [1, 1], [1, -1]];
1916
- for (const [dx, dy] of directions) {
1917
- let count = 1;
1918
- for (let i = 1; i < 5; i++) {
1919
- if (this.checkDirection(x, y, dx, dy, i))
1920
- count++;
1921
- else
1922
- break;
1923
- }
1924
- for (let i = 1; i < 5; i++) {
1925
- if (this.checkDirection(x, y, -dx, -dy, i))
1926
- count++;
1927
- else
1928
- break;
1929
- }
1930
- if (count >= 5) {
1931
- this.winningFlag = this.board[x][y] === this.playerFlag ? 1 /* win */ : 2 /* lose */;
1932
- return true;
1933
- }
1934
- }
1935
- return false;
1936
- }
1937
- // 辅助方法:检查指定方向是否有连续棋子
1938
- checkDirection(x, y, dx, dy, step) {
1939
- const nx = x + dx * step, ny = y + dy * step;
1940
- return nx >= 0 && nx < BOARD_SIZE && ny >= 0 && ny < BOARD_SIZE && this.board[nx][ny] === this.board[x][y];
1941
- }
1942
- // 生成带表情符号的棋盘字符串
1943
- printBoard() {
1944
- const numberEmojis = ["0️⃣", "1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣", "6️⃣", "7️⃣", "8️⃣", "9️⃣", "🔟", "🔢", "🔢", "🔢", "🔢"];
1945
- let res = "🟨" + numberEmojis.slice(0, BOARD_SIZE).join("") + "🟨\n";
1946
- for (let i = 0; i < BOARD_SIZE; i++) {
1947
- res += numberEmojis[i];
1948
- for (let j = 0; j < BOARD_SIZE; j++) {
1949
- res += this.board[i][j] === 0 ? "🟨" : this.board[i][j] === 1 ? "⚫" : "⚪";
1950
- }
1951
- res += numberEmojis[i];
1952
- res += "\n";
1953
- }
1954
- res += "🟨" + numberEmojis.slice(0, BOARD_SIZE).join("") + "🟨\n";
1955
- return res;
1956
- }
1957
- generateChat(Score) {
1958
- if (this.lastScore < 5e6 && Score > 5e6 && this.level > 3) {
1959
- return "我觉得你要输了哦~";
1960
- }
1961
- if (this.lastScore < 1e6 && Score > 1e6) {
1962
- return "只能下在这里了~";
1963
- }
1964
- if (4e3 <= Score && Score < 1e4) {
1965
- return "这招怎么样?";
1966
- }
1967
- if (2e3 <= Score && Score < 4e3 && Math.random() < 0.5) {
1968
- return {
1969
- 0: "有点意思哦~",
1970
- 1: "真是焦灼的局面",
1971
- 2: "势均力敌呢~",
1972
- 3: "你在想什么呢?",
1973
- 4: "走这里会不会太冒险了?"
1974
- }[Math.floor(Math.random() * 5)];
1975
- }
1976
- if (Score < -1e6) {
1977
- return "好猛烈的攻击啊~";
1978
- }
1979
- if (Score < 0 && Math.random() < 0.5) {
1980
- return "你还真是厉害呢~";
1981
- }
1982
- if (Score < 100) {
1983
- return "出乎意料的一手啊";
1984
- }
1985
- }
1986
- };
1987
- var goBang = class extends abstractGame {
1988
- static {
1989
- __name(this, "goBang");
1990
- }
1991
- constructor() {
1992
- super(goBangSingleGame);
1993
- }
1994
- // 启动游戏时可传入难度参数
1995
- async startGame(session, ctx, args) {
1996
- let level;
1997
- if (!isNaN(parseInt(args[0])))
1998
- level = parseInt(args[0]);
1999
- else {
2000
- setTimeout(() => {
2001
- session.send("未输入难度等级(2-6),默认设为3");
2002
- }, 500);
2003
- level = 3;
2004
- }
2005
- if (level < 2 || level > 6) {
2006
- level = level < 2 ? 2 : 6;
2007
- setTimeout(() => {
2008
- session.send("难度等级必须在2到6之间,已调整为" + level);
2009
- }, 500);
2010
- }
2011
- const game = await super.startGame(session, ctx, args);
2012
- game.level = level;
2013
- return game;
2014
- }
2015
- };
2016
-
2017
1787
  // src/gamefencing.ts
2018
- var import_koishi10 = require("koishi");
2019
- var logger9 = new import_koishi10.Logger("satori-game-fencing");
1788
+ var logger8 = new import_koishi9.Logger("satori-game-fencing");
2020
1789
  var fencingSingleGame = class _fencingSingleGame extends abstractGameSingleGame {
2021
1790
  static {
2022
1791
  __name(this, "fencingSingleGame");
@@ -2198,8 +1967,8 @@ var fencing = class extends abstractGame {
2198
1967
  };
2199
1968
 
2200
1969
  // src/gameOneTouch.ts
2201
- var import_koishi11 = require("koishi");
2202
- var logger10 = new import_koishi11.Logger("satori-game-onetouch");
1970
+ var import_koishi10 = require("koishi");
1971
+ var logger9 = new import_koishi10.Logger("satori-game-onetouch");
2203
1972
  var SKILL_MAP = {
2204
1973
  // 基础技能
2205
1974
  "-1": {},
@@ -2290,7 +2059,7 @@ var OneTouchSingleGame = class extends abstractGameSingleGame {
2290
2059
  hp: this.baseHP,
2291
2060
  status: 0 /* Normal */
2292
2061
  };
2293
- return await wrapInHTML2(`游戏开始!
2062
+ return await wrapInHTML(`游戏开始!
2294
2063
  对方的手势:左${this.ai.left} 右${this.ai.right}
2295
2064
  你的手势:左${this.player.left} 右${this.player.right}
2296
2065
  输入格式"左 右"选择要触碰的手
@@ -2340,9 +2109,9 @@ var OneTouchSingleGame = class extends abstractGameSingleGame {
2340
2109
  }
2341
2110
  async processInput(input) {
2342
2111
  if (input === "游戏规则")
2343
- return await wrapInHTML2(this.instuction);
2112
+ return await wrapInHTML(this.instuction);
2344
2113
  if (input === "技能列表")
2345
- return await wrapInHTML2(this.skillList);
2114
+ return await wrapInHTML(this.skillList);
2346
2115
  if (this.turnCount === 0)
2347
2116
  this.initState(this.level);
2348
2117
  this.turnCount++;
@@ -2383,7 +2152,7 @@ var OneTouchSingleGame = class extends abstractGameSingleGame {
2383
2152
  statusIcon(this.player.vulnerablility, "💔"),
2384
2153
  this.player.status === 1 /* Stunned */ ? "💫 眩晕" : ""
2385
2154
  ].filter(Boolean).join(" | ");
2386
- return wrapInHTML2(`▶️你的行动:${result}
2155
+ return wrapInHTML(`▶️你的行动:${result}
2387
2156
 
2388
2157
  ▶️我的行动:${aiResult}
2389
2158
 
@@ -2768,7 +2537,7 @@ ${bonusMessage}` : "");
2768
2537
  bestMove = move;
2769
2538
  }
2770
2539
  }
2771
- logger10.info(`AI选择的动作:${bestMove[0]}碰${bestMove[1]}, 分数:${bestScore}`);
2540
+ logger9.info(`AI选择的动作:${bestMove[0]}碰${bestMove[1]}, 分数:${bestScore}`);
2772
2541
  if (this.turnCount > 5)
2773
2542
  this.session.sendQueued(this.generateChat(bestScore), 1e3);
2774
2543
  this.lastScore = bestScore;
@@ -2994,9 +2763,9 @@ var OneTouchGame = class extends abstractGame {
2994
2763
  return game;
2995
2764
  }
2996
2765
  };
2997
- async function wrapInHTML2(str) {
2766
+ async function wrapInHTML(str) {
2998
2767
  if (!puppeteer) {
2999
- logger10.warn("puppeteer未就绪");
2768
+ logger9.warn("puppeteer未就绪");
3000
2769
  return "出现错误,请联系管理员";
3001
2770
  }
3002
2771
  return puppeteer.render(`<html><body>${str.replaceAll(/\n/g, "<BR>")}</body>
@@ -3008,15 +2777,15 @@ async function wrapInHTML2(str) {
3008
2777
  </style>
3009
2778
  </html>`);
3010
2779
  }
3011
- __name(wrapInHTML2, "wrapInHTML");
2780
+ __name(wrapInHTML, "wrapInHTML");
3012
2781
 
3013
2782
  // src/game.ts
3014
- var logger11 = new import_koishi12.Logger("satori-game");
2783
+ var logger10 = new import_koishi11.Logger("satori-game");
3015
2784
  var Game = class {
3016
2785
  static {
3017
2786
  __name(this, "Game");
3018
2787
  }
3019
- GAMES = ["五子棋", "击剑", "一碰一"];
2788
+ GAMES = ["一碰一"];
3020
2789
  // 支持的游戏列表
3021
2790
  channelGames = /* @__PURE__ */ new Map();
3022
2791
  // 频道ID到游戏名称的映射
@@ -3030,9 +2799,6 @@ var Game = class {
3030
2799
  this.context = ctx;
3031
2800
  this.config = cfg;
3032
2801
  this.sat = sat;
3033
- if (this.config.enable_gobang) {
3034
- this.availableGames.set("五子棋", new goBang());
3035
- }
3036
2802
  if (this.config.enable_fencing) {
3037
2803
  this.availableGames.set("击剑", new fencing());
3038
2804
  }
@@ -3051,8 +2817,6 @@ var Game = class {
3051
2817
  }
3052
2818
  // 启动指定游戏
3053
2819
  async startGame(session, gameName, args) {
3054
- if (this.config.game_block_channel.includes(session.channelId))
3055
- return "本群不支持游戏哦" + (this.config.channel_id_for_gobang[0] ? ",想玩请加群" + this.config.channel_id_for_gobang[0] : "");
3056
2820
  if (this.channelGames.get(session.channelId))
3057
2821
  return "当前频道已经有游戏在进行中";
3058
2822
  if (gameName == "")
@@ -3062,9 +2826,6 @@ var Game = class {
3062
2826
  const game = this.availableGames.get(gameName);
3063
2827
  if (!game)
3064
2828
  return "没有这个游戏哦";
3065
- if (gameName === "五子棋" && !this.config.channel_id_for_gobang.includes(session.channelId)) {
3066
- return "本群不支持五子棋哦,想玩请加群" + this.config.channel_id_for_gobang[0];
3067
- }
3068
2829
  const user = await ensureUserExists(this.context, session.userId, session.username);
3069
2830
  const lastUsage = this.userUsage.get(`${session.userId}-${gameName}`);
3070
2831
  if (lastUsage && user.userlevel < 4) {
@@ -3079,7 +2840,7 @@ var Game = class {
3079
2840
  refreshPuppeteer(this.context);
3080
2841
  game.startGame(session, this.context, args);
3081
2842
  this.channelGames.set(session.channelId, gameName);
3082
- logger11.info(`游戏${gameName}已开始于${session.channelId}`);
2843
+ logger10.info(`游戏${gameName}已开始于${session.channelId}`);
3083
2844
  }
3084
2845
  // 结束当前游戏
3085
2846
  async endGame(session) {
@@ -3088,7 +2849,7 @@ var Game = class {
3088
2849
  return "当前频道没有游戏在进行中";
3089
2850
  if (await this.availableGames.get(gameName).endGame(session, this.context)) {
3090
2851
  this.channelGames.delete(session.channelId);
3091
- logger11.info(`${session.channelId}的游戏已结束`);
2852
+ logger10.info(`${session.channelId}的游戏已结束`);
3092
2853
  }
3093
2854
  }
3094
2855
  async chat(session, gameName, prompt) {
@@ -3101,8 +2862,6 @@ var Game = class {
3101
2862
  }
3102
2863
  getGameCd(gameName) {
3103
2864
  switch (gameName) {
3104
- case "五子棋":
3105
- return this.config.cd_for_gobang;
3106
2865
  case "一碰一":
3107
2866
  return this.config.cd_for_OneTouch;
3108
2867
  default:
@@ -3114,7 +2873,7 @@ var Game = class {
3114
2873
  this.GAMES.forEach((game) => {
3115
2874
  list += game + "\n";
3116
2875
  });
3117
- logger11.info(list);
2876
+ logger10.info(list);
3118
2877
  return list;
3119
2878
  }
3120
2879
  async resultJudge(result, ctx, session) {
@@ -3160,8 +2919,8 @@ var Game = class {
3160
2919
  };
3161
2920
 
3162
2921
  // src/broadcast.ts
3163
- var import_koishi13 = require("koishi");
3164
- var logger12 = new import_koishi13.Logger("satori-ai-broadcast");
2922
+ var import_koishi12 = require("koishi");
2923
+ var logger11 = new import_koishi12.Logger("satori-ai-broadcast");
3165
2924
  var BroadcastManager = class {
3166
2925
  static {
3167
2926
  __name(this, "BroadcastManager");
@@ -3191,16 +2950,16 @@ var BroadcastManager = class {
3191
2950
  const id = `broadcast-${this.idCounter++}`;
3192
2951
  const broadcast = new broadcastMessage(this.ctx, this.config, message, img);
3193
2952
  this.broadcastMessages.set(id, broadcast);
3194
- logger12.info(`广播已创建 ID: ${id}`);
2953
+ logger11.info(`广播已创建 ID: ${id}`);
3195
2954
  return `广播已创建 ID: ${id}`;
3196
2955
  }
3197
2956
  async deleteBroadcast(id) {
3198
2957
  if (this.broadcastMessages.has(id)) {
3199
2958
  this.broadcastMessages.delete(id);
3200
- logger12.info(`广播已删除 ID: ${id}`);
2959
+ logger11.info(`广播已删除 ID: ${id}`);
3201
2960
  return "已删除广播:" + id;
3202
2961
  } else {
3203
- logger12.warn(`未找到广播 ID: ${id}`);
2962
+ logger11.warn(`未找到广播 ID: ${id}`);
3204
2963
  return "未找到该广播";
3205
2964
  }
3206
2965
  }
@@ -3208,7 +2967,7 @@ var BroadcastManager = class {
3208
2967
  for (const [id, broadcast] of this.broadcastMessages.entries()) {
3209
2968
  if (broadcast.setTime.getTime() + 1e3 * 60 * this.config.waiting_time < Date.now()) {
3210
2969
  this.broadcastMessages.delete(id);
3211
- logger12.info(`广播已过期 ID: ${id}`);
2970
+ logger11.info(`广播已过期 ID: ${id}`);
3212
2971
  continue;
3213
2972
  }
3214
2973
  await broadcast.sendMessage(session);
@@ -3236,7 +2995,7 @@ ${alreadySentChannels}
3236
2995
  }
3237
2996
  }
3238
2997
  const result = list.length > 0 ? list.join("\n") : null;
3239
- return result ? wrapInHTML3(result) : null;
2998
+ return result ? wrapInHTML2(result) : null;
3240
2999
  }
3241
3000
  };
3242
3001
  var broadcastMessage = class {
@@ -3267,13 +3026,13 @@ var broadcastMessage = class {
3267
3026
  try {
3268
3027
  this.alreadySentChannels.add(channelId);
3269
3028
  if (this.img) {
3270
- session.send(await wrapInHTML3(this.message));
3029
+ session.send(await wrapInHTML2(this.message));
3271
3030
  } else {
3272
3031
  session.send(this.message);
3273
3032
  }
3274
- logger12.info(`向群 ${channelId} 广播: ${this.message}`);
3033
+ logger11.info(`向群 ${channelId} 广播: ${this.message}`);
3275
3034
  } catch (error) {
3276
- logger12.error(`广播失败 ${channelId}: ${error}`);
3035
+ logger11.error(`广播失败 ${channelId}: ${error}`);
3277
3036
  }
3278
3037
  }
3279
3038
  getAlreadySentChannels() {
@@ -3281,9 +3040,9 @@ var broadcastMessage = class {
3281
3040
  return alreadySentChannels.length > 0 ? alreadySentChannels.join("\n") : "无";
3282
3041
  }
3283
3042
  };
3284
- async function wrapInHTML3(str) {
3043
+ async function wrapInHTML2(str) {
3285
3044
  if (!puppeteer) {
3286
- logger12.warn("puppeteer未就绪");
3045
+ logger11.warn("puppeteer未就绪");
3287
3046
  return str;
3288
3047
  }
3289
3048
  return puppeteer.render(`<html><body>${str.replaceAll(/\n/g, "<BR>")}</body>
@@ -3295,16 +3054,16 @@ async function wrapInHTML3(str) {
3295
3054
  </style>
3296
3055
  </html>`);
3297
3056
  }
3298
- __name(wrapInHTML3, "wrapInHTML");
3057
+ __name(wrapInHTML2, "wrapInHTML");
3299
3058
 
3300
3059
  // src/index.tsx
3301
- var logger13 = new import_koishi14.Logger("satori-ai");
3060
+ var logger12 = new import_koishi13.Logger("satori-ai");
3302
3061
  var puppeteer = null;
3303
3062
  function refreshPuppeteer(ctx) {
3304
3063
  if (ctx.puppeteer) {
3305
3064
  puppeteer = ctx.puppeteer;
3306
3065
  } else {
3307
- logger13.warn("puppeteer未就绪");
3066
+ logger12.warn("puppeteer未就绪");
3308
3067
  }
3309
3068
  }
3310
3069
  __name(refreshPuppeteer, "refreshPuppeteer");
@@ -3492,9 +3251,9 @@ var SAT = class extends Sat {
3492
3251
  const messages = generateAuxiliaryPrompt(prompt, response.content, user, this.getFavorabilityConfig());
3493
3252
  const result = await this.apiClient.auxiliaryChat(messages);
3494
3253
  if (result.error) {
3495
- logger13.error(`辅助判断失败:${result.content}`);
3254
+ logger12.error(`辅助判断失败:${result.content}`);
3496
3255
  } else {
3497
- logger13.info(`辅助判断:${result.content}`);
3256
+ logger12.info(`辅助判断:${result.content}`);
3498
3257
  return handleAuxiliaryResult(this.ctx, session, this.getFavorabilityConfig(), result.content);
3499
3258
  }
3500
3259
  }
@@ -3581,21 +3340,21 @@ var SAT = class extends Sat {
3581
3340
  await inputContentCheck(this.ctx, censored, session.userId, this.getFavorabilityConfig(), session, this.moodManager);
3582
3341
  }
3583
3342
  if (this.config.log_ask_response)
3584
- logger13.info(`用户 ${session.username}:${processedPrompt}`);
3343
+ logger12.info(`用户 ${session.username}:${processedPrompt}`);
3585
3344
  return censored;
3586
3345
  }
3587
3346
  // 生成回复
3588
3347
  async generateResponse(session, prompt) {
3589
3348
  if (this.getChannelParallelCount(session) > this.config.max_parallel_count) {
3590
- logger13.info(`频道 ${session.channelId} 并发数过高(${this.getChannelParallelCount(session)}),${session.username}等待中...`);
3349
+ logger12.info(`频道 ${session.channelId} 并发数过高(${this.getChannelParallelCount(session)}),${session.username}等待中...`);
3591
3350
  }
3592
3351
  while (this.getChannelParallelCount(session) > this.config.max_parallel_count) {
3593
3352
  this.updateChannelParallelCount(session, -1);
3594
- await new Promise((resolve3) => setTimeout(resolve3, 1e3));
3353
+ await new Promise((resolve2) => setTimeout(resolve2, 1e3));
3595
3354
  this.updateChannelParallelCount(session, 1);
3596
3355
  }
3597
3356
  const messages = await this.buildMessages(session, prompt);
3598
- logger13.info(`频道 ${session.channelId} 处理:${session.userId},剩余${this.getChannelParallelCount(session)}并发`);
3357
+ logger12.info(`频道 ${session.channelId} 处理:${session.userId},剩余${this.getChannelParallelCount(session)}并发`);
3599
3358
  const user = await getUser(this.ctx, session.userId);
3600
3359
  let response = await this.getChatResponse(user, messages);
3601
3360
  if (response.error)
@@ -3609,9 +3368,9 @@ var SAT = class extends Sat {
3609
3368
  let response = await this.apiClient.chat(user, messages);
3610
3369
  if (this.config.log_ask_response) {
3611
3370
  if (this.config.enable_favorability && this.config.enable_mood)
3612
- logger13.info(`Satori AI:(心情值:${this.moodManager.getMoodValue(user.userid)})${response.content}`);
3371
+ logger12.info(`Satori AI:(心情值:${this.moodManager.getMoodValue(user.userid)})${response.content}`);
3613
3372
  else
3614
- logger13.info(`Satori AI:${response.content}`);
3373
+ logger12.info(`Satori AI:${response.content}`);
3615
3374
  }
3616
3375
  if (this.config.reasoner_filter && !response.error)
3617
3376
  response = filterResponse(response.content, this.config.reasoner_filter_word.split("-"));
@@ -3635,7 +3394,7 @@ var SAT = class extends Sat {
3635
3394
  messages.push({ role: "user", content: prompt });
3636
3395
  let payload = messages.map((msg) => msg.role + ":" + msg.content).join("\n");
3637
3396
  if (this.config.log_system_prompt)
3638
- logger13.info(`系统提示:
3397
+ logger12.info(`系统提示:
3639
3398
  ${payload}`);
3640
3399
  return messages;
3641
3400
  }
@@ -3740,10 +3499,10 @@ ${useNoReasoner ? promptForNoReasoner : promptForReasoner}
3740
3499
  response = `@${session.username} ` + response;
3741
3500
  }
3742
3501
  if (this.config.sentences_divide && response.length > 10) {
3743
- const sentences = splitSentences(response, this.config.min_sentences_length, this.config.max_sentences_length).map((text) => import_koishi14.h.text(text));
3502
+ const sentences = splitSentences(response, this.config.min_sentences_length, this.config.max_sentences_length).map((text) => import_koishi13.h.text(text));
3744
3503
  for (const sentence of sentences) {
3745
3504
  await session.send(sentence);
3746
- await new Promise((resolve3) => setTimeout(resolve3, this.config.time_interval));
3505
+ await new Promise((resolve2) => setTimeout(resolve2, this.config.time_interval));
3747
3506
  }
3748
3507
  return null;
3749
3508
  }
@@ -3753,7 +3512,7 @@ ${useNoReasoner ? promptForNoReasoner : promptForReasoner}
3753
3512
  if (!this.config.enable_warning)
3754
3513
  return;
3755
3514
  if (auxiliaryResult.includes("好感↓")) {
3756
- logger13.info(`在群${session.channelId}中,${session.username}骚扰我!`);
3515
+ logger12.info(`在群${session.channelId}中,${session.username}骚扰我!`);
3757
3516
  this.usersToWarn.set(session.channelId, session.username);
3758
3517
  }
3759
3518
  }
@@ -3793,7 +3552,7 @@ ${useNoReasoner ? promptForNoReasoner : promptForReasoner}
3793
3552
  async addCommonSense(session, content) {
3794
3553
  if (!content)
3795
3554
  return session.text("commands.sat.common_sense.messages.no-prompt");
3796
- const filePath = path7.join(this.config.dataDir, "common_sense.txt");
3555
+ const filePath = path6.join(this.config.dataDir, "common_sense.txt");
3797
3556
  await this.memoryManager.saveLongTermMemory(session, [{
3798
3557
  role: "user",
3799
3558
  content: content.replace(/\"/g, "'").trim()
package/lib/types.d.ts CHANGED
@@ -244,9 +244,6 @@ export declare namespace Sat {
244
244
  waiting_time: number;
245
245
  enable_game: boolean;
246
246
  game_block_channel: string[];
247
- enable_gobang: boolean;
248
- channel_id_for_gobang: string[];
249
- cd_for_gobang: number;
250
247
  enable_fencing: boolean;
251
248
  enable_OneTouch: boolean;
252
249
  cd_for_OneTouch: number;
@@ -9,7 +9,8 @@ export declare class UserPortraitManager {
9
9
  hasPortrait(userId: string): boolean;
10
10
  readPortrait(userId: string): string;
11
11
  private getDialogues;
12
- private buildMessage;
12
+ private buildFirstMessage;
13
+ private buildSecondMessage;
13
14
  generatePortrait(session: Session, user: User, apiClient: APIClient): Promise<void>;
14
15
  private savePortrait;
15
16
  private ensurePortraitFile;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-satori-ai",
3
3
  "description": "基于 Satori 适配器的智能对话插件,具备用户画像、长期记忆、常识管理和好感度系统",
4
- "version": "1.3.7",
4
+ "version": "1.3.8",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "types": "lib/index.d.ts",
package/lib/gobang_ai.exe DELETED
Binary file