koishi-plugin-satori-ai 1.3.6 → 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");
@@ -284,11 +284,11 @@ function filterResponse(prompt, words) {
284
284
  const lastAnswer5 = answerMatches5 ? answerMatches5[answerMatches5.length - 1] : null;
285
285
  const answerContent = lastAnswer || lastDoubao || lastAnswer3 || lastAnswer4 || lastAnswer5;
286
286
  if (!answerContent) {
287
- return { content: "有点问题,稍后再来吧", error: true };
287
+ return { content: "有点问题,请重置对话", error: true };
288
288
  }
289
289
  const regex = /<p>|<\/p>|<doubaothinking>|<\/doubaothinking>|<\/p|<answer>|<\/answer>|<br>|<\/br>|<br\/>/g;
290
290
  const cleanedContent = answerContent.replace(regex, "");
291
- return cleanedContent ? { content: cleanedContent, error: false } : { content: "有点问题,稍后再来吧", error: true };
291
+ return cleanedContent ? { content: cleanedContent, error: false } : { content: "有点问题,请重置对话", error: true };
292
292
  }
293
293
  __name(filterResponse, "filterResponse");
294
294
  function addOutputCensor(session, word, baseURL) {
@@ -311,6 +311,51 @@ async function updateUserPWithTicket(ctx, user, adjustment) {
311
311
  }
312
312
  }
313
313
  __name(updateUserPWithTicket, "updateUserPWithTicket");
314
+ function findLongestCommonSubstring(str1, str2) {
315
+ if (!str1 || !str2)
316
+ return 0;
317
+ const m = str1.length;
318
+ const n = str2.length;
319
+ const dp = Array(m + 1).fill(null).map(() => Array(n + 1).fill(0));
320
+ let maxLength = 0;
321
+ for (let i = 1; i <= m; i++) {
322
+ for (let j = 1; j <= n; j++) {
323
+ if (str1[i - 1] === str2[j - 1]) {
324
+ dp[i][j] = dp[i - 1][j - 1] + 1;
325
+ maxLength = Math.max(maxLength, dp[i][j]);
326
+ }
327
+ }
328
+ }
329
+ return maxLength;
330
+ }
331
+ __name(findLongestCommonSubstring, "findLongestCommonSubstring");
332
+ function countCommonChars(str1, str2) {
333
+ const chars1 = /* @__PURE__ */ new Map();
334
+ const chars2 = /* @__PURE__ */ new Map();
335
+ for (const char of str1) {
336
+ if (/[\u4e00-\u9fff]/.test(char)) {
337
+ chars1.set(char, (chars1.get(char) || 0) + 1);
338
+ }
339
+ }
340
+ for (const char of str2) {
341
+ if (/[\u4e00-\u9fff]/.test(char)) {
342
+ chars2.set(char, (chars2.get(char) || 0) + 1);
343
+ }
344
+ }
345
+ let commonCount = 0;
346
+ for (const [char, count1] of chars1) {
347
+ const count2 = chars2.get(char) || 0;
348
+ commonCount += Math.min(count1, count2);
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
+ }
356
+ return commonCount;
357
+ }
358
+ __name(countCommonChars, "countCommonChars");
314
359
 
315
360
  // src/api.ts
316
361
  var logger2 = new import_koishi2.Logger("satori-api");
@@ -412,7 +457,7 @@ var APIClient = class {
412
457
  if (i == this.config.maxRetryTimes) {
413
458
  return this.handleAPIError(error);
414
459
  }
415
- 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));
416
461
  logger2.warn(`生成画像时API请求失败(${error}),重试(第${i}次)中...`);
417
462
  continue;
418
463
  }
@@ -469,7 +514,7 @@ var APIClient = class {
469
514
  if (i == this.config.maxRetryTimes) {
470
515
  return this.handleAPIError(error);
471
516
  }
472
- 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));
473
518
  logger2.warn(`API请求失败(${error}),重试(第${i}次)中...`);
474
519
  continue;
475
520
  }
@@ -543,7 +588,7 @@ var MemoryManager = class {
543
588
  }
544
589
  channelMemories = /* @__PURE__ */ new Map();
545
590
  channelDialogues = /* @__PURE__ */ new Map();
546
- charactersToRemove = ["的", "一", "是", "了", "什", "么", "我", "谁", "不", "人", "在", "他", "有", "这", "个", "上", "们", "来", "到", "时", "大", "地", "为", "子", "中", "你", "说", "生", "国", "年", "着", "就", "那", "和", "要", "她", "出", "也", "得", "里", "后", "自", "以", "会", "id=", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"];
591
+ charactersToRemove = ["的", "一", "是", "了", "什", "么", "我", "谁", "不", "人", "在", "他", "有", "这", "个", "上", "们", "来", "到", "时", "大", "地", "为", "子", "中", "你", "说", "生", "国", "年", "着", "就", "那", "和", "要", "她", "出", "也", "得", "里", "后", "自", "以", "会", "id="];
547
592
  MAX_MEMORY_LENGTH = 5e3;
548
593
  // 更新记忆
549
594
  async updateMemories(session, prompt, config, response) {
@@ -578,7 +623,7 @@ var MemoryManager = class {
578
623
  if (!this.config.channel_dialogues)
579
624
  return "";
580
625
  const Dialogue = this.channelDialogues[session.channelId]?.join("\n") || "";
581
- const result = "以下是群聊内群友最近的聊天记录,当用户话题涉及其中内容时你可以参考这些信息:{\n" + Dialogue + "\n}\n";
626
+ const result = "以下是群聊内最近的包括所有人的聊天记录,当当前对话涉及其中内容时你可以参考这些信息,但是要注意分辨发言人是谁:{\n" + Dialogue + "\n}\n";
582
627
  return result;
583
628
  }
584
629
  // 括号引号过滤
@@ -702,22 +747,12 @@ var MemoryManager = class {
702
747
  calculateMatchScore(content, keywords) {
703
748
  if (keywords.length === 0)
704
749
  return { score: 0, count: 0 };
705
- const escapedKeywords = keywords.map((k) => escapeRegExp(k));
706
- const regex = new RegExp(escapedKeywords.join("|"), "gi");
707
- const chineseRegex = /[\u4e00-\u9fa5]/g;
708
- const regex2 = new RegExp(`[${this.charactersToRemove.join("")}]`, "g");
709
- content = content.replace(regex2, "");
710
- const matches = content.match(regex) || [];
711
- let count = 0;
712
- matches.forEach((match) => {
713
- const chineseCount = (match.match(chineseRegex) || []).length;
714
- const englishCount = match.length - chineseCount;
715
- count += chineseCount * 2 + englishCount;
716
- });
717
- const totalChinese = (content.match(chineseRegex) || []).length;
718
- const totalEnglish = content.length - totalChinese;
719
- const totalWeight = totalChinese * 2 + totalEnglish;
720
- const ratio = totalWeight > 0 ? count / totalWeight : 0;
750
+ const regex = new RegExp(`[${this.charactersToRemove.join("")}]`, "g");
751
+ content = content.replace(regex, "");
752
+ const Keyword = keywords.map((k) => escapeRegExp(k)).join("");
753
+ const length = findLongestCommonSubstring(content, Keyword);
754
+ const count = countCommonChars(content, Keyword);
755
+ const ratio = (length * length + count) / content.length;
721
756
  return { score: ratio, count };
722
757
  }
723
758
  // 格式化匹配结果
@@ -732,7 +767,8 @@ var MemoryManager = class {
732
767
  matched = matched.slice(0, topN < matched.length ? topN : matched.length);
733
768
  if (type === "common") {
734
769
  const result = `${prefixMap[type]}{
735
- ${matched.map((entry) => entry.content).join("\n")} ${date}
770
+ ${matched.map((entry) => entry.content).join("\n")}
771
+ ${date}
736
772
  }
737
773
  `;
738
774
  return result;
@@ -1225,9 +1261,6 @@ var Sat = class extends import_koishi5.Service {
1225
1261
  import_koishi5.Schema.object({
1226
1262
  enable_game: import_koishi5.Schema.boolean().default(false).description("是否开启游戏模块"),
1227
1263
  game_block_channel: import_koishi5.Schema.array(String).description("不提供游戏的频道id"),
1228
- enable_gobang: import_koishi5.Schema.boolean().default(false).description("是否开启五子棋游戏(需要puppeteer支持)"),
1229
- channel_id_for_gobang: import_koishi5.Schema.array(String).description("启用五子棋的游戏频道id(不建议太多,第一个会被公示)"),
1230
- cd_for_gobang: import_koishi5.Schema.number().default(3600).description("每人五子棋游戏cd时间(秒)"),
1231
1264
  enable_OneTouch: import_koishi5.Schema.boolean().default(false).description("是否开启一碰一游戏(需要puppeteer支持)"),
1232
1265
  cd_for_OneTouch: import_koishi5.Schema.number().default(600).description("每人一碰一游戏cd时间(秒)"),
1233
1266
  enable_fencing: import_koishi5.Schema.boolean().default(false).description("是否开启击剑游戏(无效,开发中)")
@@ -1279,7 +1312,7 @@ var UserPortraitManager = class {
1279
1312
  });
1280
1313
  fs5.writeFileSync(memoryPath, JSON.stringify(replacedContent, null, 2));
1281
1314
  const validEntries = replacedContent.filter((entry) => entry.role !== "user").map((entry) => {
1282
- 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)/);
1283
1316
  if (!timeMatch)
1284
1317
  return null;
1285
1318
  return {
@@ -1293,11 +1326,11 @@ var UserPortraitManager = class {
1293
1326
  return validEntries.slice(0, maxEntries).map((entry) => `${entry.content}${entry.role}`);
1294
1327
  }
1295
1328
  // 生成提示词模板
1296
- buildMessage(level, history, existingPortrait, user) {
1329
+ buildFirstMessage(level, history, user) {
1297
1330
  return [{
1298
1331
  role: "user",
1299
- content: `你是一个角色扮演智能体工作流中的一环,请根据以下信息更新用户画像。需包括:
1300
- 1. 基本信息(性别、年龄、生日等,不要遗漏或改动已有的信息)
1332
+ content: `你是一个角色扮演智能体工作流中的一环,请根据以下信息生成户画像。可选内容包括:
1333
+ 1. 基本信息(性别、年龄、生日等)
1301
1334
  2. 生活习惯(作息等)
1302
1335
  3. 反感点(如有)
1303
1336
  4. 对AI的期望(从对话历史中推断)
@@ -1305,21 +1338,47 @@ var UserPortraitManager = class {
1305
1338
 
1306
1339
  用户名:${user.usersname}
1307
1340
  你与用户的关系:${level}
1308
- 历史画像:
1309
- ${existingPortrait ? "无" : existingPortrait}
1310
-
1311
1341
  近期的用户发言记录:
1312
1342
  ${history}
1313
1343
 
1314
1344
  注意事项:
1345
+ ·没有涉及到的信息注为无
1315
1346
  ·用户一定是人类,其他情况是角色扮演
1316
- ·根据发言修正历史画像内容,但是历史画像中与发言无关的部分必须保留
1317
1347
  ·尤其注意用户说“记住”的部分,可能是用户希望记录的信息
1318
1348
  ·因为在角色扮演中,用户可能会说出不符合事实的信息,需要根据事实推断,避免盲目相信或主观臆测
1319
1349
  ·使用尽可能简洁的表达
1320
1350
  ·保留不确定性的表述(如"可能"、"似乎"、"用户自称")
1321
1351
  ·保持中立和客观,避免带有个人情感色彩的描述,不要添加评价或建议
1322
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
+ ·仅给出画像内容,不要添加额外的描述、建议、评价、注解等任何内容
1323
1382
  ·不使用markdown等标记语言,直接书写即可`
1324
1383
  }];
1325
1384
  }
@@ -1334,10 +1393,12 @@ ${history}
1334
1393
  const dialogues = await this.getDialogues(user);
1335
1394
  const existing = this.readPortrait(user.userid);
1336
1395
  const userlevel = getFavorabilityLevel(user, this.getFavorabilityConfig());
1337
- const messages = this.buildMessage(userlevel, dialogues.join("\n"), existing, user);
1338
1396
  logger5.info(`用户 ${user.userid} 画像生成中...`);
1339
1397
  try {
1340
- 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);
1341
1402
  if (response && !response.error) {
1342
1403
  this.savePortrait(user, response.content);
1343
1404
  if (user.usage > this.config.portrait_usage - 1)
@@ -1617,9 +1678,9 @@ ${this.config.mood_prompt_2}
1617
1678
  };
1618
1679
 
1619
1680
  // src/game.ts
1620
- var import_koishi12 = require("koishi");
1681
+ var import_koishi11 = require("koishi");
1621
1682
 
1622
- // src/gamegobang.ts
1683
+ // src/gamefencing.ts
1623
1684
  var import_koishi9 = require("koishi");
1624
1685
 
1625
1686
  // src/abstractGame.ts
@@ -1723,270 +1784,8 @@ var abstractGame = class {
1723
1784
  }
1724
1785
  };
1725
1786
 
1726
- // src/gamegobang.ts
1727
- var import_child_process = require("child_process");
1728
- var path6 = __toESM(require("path"));
1729
- var logger8 = new import_koishi9.Logger("satori-game-gobang");
1730
- var BOARD_SIZE = 14;
1731
- var inspireSearchLength = 10;
1732
- var Coordinate = class {
1733
- static {
1734
- __name(this, "Coordinate");
1735
- }
1736
- x;
1737
- y;
1738
- score;
1739
- constructor(a = 0, b = 0, s = 0) {
1740
- this.x = a;
1741
- this.y = b;
1742
- this.score = s;
1743
- }
1744
- };
1745
- async function wrapInHTML(str) {
1746
- if (!puppeteer) {
1747
- logger8.warn("puppeteer未就绪");
1748
- return "出现错误,请联系管理员";
1749
- }
1750
- return puppeteer.render(`<html><body>${str.replaceAll(/\n/g, "<BR>")}</body>
1751
- <style>
1752
- body {
1753
- padding: 10px;
1754
- display: inline-block;
1755
- }
1756
- </style>
1757
- </html>`);
1758
- }
1759
- __name(wrapInHTML, "wrapInHTML");
1760
- var goBangSingleGame = class extends abstractGameSingleGame {
1761
- static {
1762
- __name(this, "goBangSingleGame");
1763
- }
1764
- playerFlag;
1765
- // 玩家棋子颜色(1: 黑棋,2: 白棋)
1766
- winningFlag = 4 /* pending */;
1767
- // 当前胜负状态
1768
- level;
1769
- // AI 难度等级
1770
- board = [];
1771
- // BOARD_SIZExBOARD_SIZE 棋盘状态
1772
- lastScore = 0;
1773
- // 上次评分
1774
- turnsCount = 0;
1775
- // 回合数
1776
- constructor(disposeListener, session) {
1777
- super(disposeListener, session);
1778
- }
1779
- // 初始化棋盘,随机决定玩家先手
1780
- startGame = () => {
1781
- super.startGame();
1782
- this.board = Array.from({ length: BOARD_SIZE }, () => Array(BOARD_SIZE).fill(0));
1783
- this.turnsCount = 0;
1784
- this.playerFlag = Math.round(Math.random()) + 1;
1785
- const getCornerCoordinate = /* @__PURE__ */ __name((i) => {
1786
- const quarter = i < 0.5 ? 0.2 : 0.7;
1787
- const base = Math.round(BOARD_SIZE * quarter);
1788
- return base;
1789
- }, "getCornerCoordinate");
1790
- for (let i = 0; i <= 1; i++) {
1791
- for (let j = 0; j <= 1; j++) {
1792
- const randomX = getCornerCoordinate(i) + 1 - 2 * i;
1793
- const randomY = getCornerCoordinate(j);
1794
- const player = Math.round(Math.random()) + 1;
1795
- this.board[randomX][randomY] = player;
1796
- this.board[randomX + i * 2 - 1][randomY - j * 2 + 1] = 3 - player;
1797
- }
1798
- }
1799
- if (this.playerFlag === 1) {
1800
- this.board[BOARD_SIZE / 2][BOARD_SIZE / 2] = 1;
1801
- this.board[BOARD_SIZE / 2 + (Math.round(Math.random()) ? -1 : 1)][BOARD_SIZE / 2 + (Math.round(Math.random()) ? -1 : 1)] = 2;
1802
- return wrapInHTML("游戏开始,你随机到了先手(黑)\n输入两个数字以下棋,先行后列,例如:“0 13”\n" + this.printBoard());
1803
- } else {
1804
- this.board[BOARD_SIZE / 2][BOARD_SIZE / 2] = 1;
1805
- this.board[BOARD_SIZE / 2 + (Math.round(Math.random()) ? -1 : 1)][BOARD_SIZE / 2 + (Math.round(Math.random()) ? -1 : 1)] = 2;
1806
- this.board[BOARD_SIZE / 2][BOARD_SIZE / 2 + (Math.round(Math.random()) ? -1 : 1)] = 1;
1807
- return wrapInHTML("游戏开始,你随机到了后手(白)\n输入两个数字以下棋,先行后列,例如:“0 13”\n" + this.printBoard());
1808
- }
1809
- };
1810
- // 结束游戏,返回结果
1811
- endGame = async () => {
1812
- super.endGame();
1813
- let bonusLevel = this.level;
1814
- if (this.winningFlag === 1 /* win */ && this.playerFlag === 1) {
1815
- bonusLevel -= 1;
1816
- } else if (this.winningFlag === 2 /* lose */ && this.playerFlag === 1) {
1817
- bonusLevel += 1;
1818
- }
1819
- return { message: `${bonusLevel}`, win: this.winningFlag, gameName: "五子棋", playerID: this.session.userId };
1820
- };
1821
- /**
1822
- * 处理玩家输入(落子坐标)
1823
- * @param str 输入内容,格式为 "x y"
1824
- */
1825
- async processInput(str) {
1826
- const [x, y] = str.split(" ").map((a) => {
1827
- return parseInt(a);
1828
- });
1829
- if (isNaN(x) || isNaN(y))
1830
- return;
1831
- if (x < 0 || x >= BOARD_SIZE || y < 0 || y >= BOARD_SIZE)
1832
- return "坐标超出范围了";
1833
- if (this.board[x][y] !== 0)
1834
- return "这个位置已经有棋子了,别想耍赖";
1835
- if (this.winningFlag !== 4 /* pending */)
1836
- return "游戏已结束";
1837
- this.lastActionTime = Date.now();
1838
- this.board[x][y] = this.playerFlag;
1839
- logger8.info(`level: ${this.level}, player: x: ${x}, y: ${y}`);
1840
- if (this.checkWin(x, y))
1841
- return wrapInHTML(this.printBoard() + "\n游戏已结束,发送结束游戏退出");
1842
- const starttime = Date.now();
1843
- const aiMove = this.getAIMove();
1844
- const endtime = Date.now();
1845
- if (aiMove.x === -1 || aiMove.y === -1) {
1846
- this.winningFlag = 3 /* draw */;
1847
- return "计算失败,视为平局,发送结束游戏退出";
1848
- }
1849
- if (this.turnsCount > 50) {
1850
- this.winningFlag = 3 /* draw */;
1851
- return "平局,发送结束游戏退出";
1852
- }
1853
- logger8.info(`AI 落子坐标: ${aiMove.x} ${aiMove.y},得分: ${aiMove.score},AI 落子耗时: ${endtime - starttime}ms`);
1854
- this.board[aiMove.x][aiMove.y] = 3 - this.playerFlag;
1855
- if (this.turnsCount > 5) {
1856
- setTimeout(() => {
1857
- this.session.send(this.generateChat(aiMove.score));
1858
- }, 1e3);
1859
- }
1860
- this.lastScore = aiMove.score;
1861
- this.turnsCount++;
1862
- if (this.checkWin(aiMove.x, aiMove.y))
1863
- return wrapInHTML(this.printBoard() + "\n游戏已结束,发送结束游戏退出");
1864
- return wrapInHTML(this.printBoard() + "\n我这一步下在这里哦(" + aiMove.x + " " + aiMove.y + " 用时" + (endtime - starttime) + "ms)");
1865
- }
1866
- getAIMove() {
1867
- try {
1868
- const boardStr = this.board.map((row) => row.join(" ")).join(" ");
1869
- const exePath = path6.resolve(__dirname, "../lib/gobang_ai.exe");
1870
- const level = this.turnsCount > 3 ? this.level : Math.min(5, this.level);
1871
- const stdout = (0, import_child_process.execSync)(
1872
- `"${exePath}" "${boardStr}" ${this.playerFlag} ${level} ${inspireSearchLength}`,
1873
- { timeout: 18e5 }
1874
- // 设置1800秒超时
1875
- ).toString().trim();
1876
- const [x, y, score] = stdout.split(" ").map(Number);
1877
- return new Coordinate(x, y, score);
1878
- } catch (error) {
1879
- logger8.error(`AI计算失败: ${error}`);
1880
- }
1881
- return new Coordinate(-1, -1, -1);
1882
- }
1883
- // 检查是否连成五子
1884
- checkWin(x, y) {
1885
- const directions = [[1, 0], [0, 1], [1, 1], [1, -1]];
1886
- for (const [dx, dy] of directions) {
1887
- let count = 1;
1888
- for (let i = 1; i < 5; i++) {
1889
- if (this.checkDirection(x, y, dx, dy, i))
1890
- count++;
1891
- else
1892
- break;
1893
- }
1894
- for (let i = 1; i < 5; i++) {
1895
- if (this.checkDirection(x, y, -dx, -dy, i))
1896
- count++;
1897
- else
1898
- break;
1899
- }
1900
- if (count >= 5) {
1901
- this.winningFlag = this.board[x][y] === this.playerFlag ? 1 /* win */ : 2 /* lose */;
1902
- return true;
1903
- }
1904
- }
1905
- return false;
1906
- }
1907
- // 辅助方法:检查指定方向是否有连续棋子
1908
- checkDirection(x, y, dx, dy, step) {
1909
- const nx = x + dx * step, ny = y + dy * step;
1910
- return nx >= 0 && nx < BOARD_SIZE && ny >= 0 && ny < BOARD_SIZE && this.board[nx][ny] === this.board[x][y];
1911
- }
1912
- // 生成带表情符号的棋盘字符串
1913
- printBoard() {
1914
- const numberEmojis = ["0️⃣", "1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣", "6️⃣", "7️⃣", "8️⃣", "9️⃣", "🔟", "🔢", "🔢", "🔢", "🔢"];
1915
- let res = "🟨" + numberEmojis.slice(0, BOARD_SIZE).join("") + "🟨\n";
1916
- for (let i = 0; i < BOARD_SIZE; i++) {
1917
- res += numberEmojis[i];
1918
- for (let j = 0; j < BOARD_SIZE; j++) {
1919
- res += this.board[i][j] === 0 ? "🟨" : this.board[i][j] === 1 ? "⚫" : "⚪";
1920
- }
1921
- res += numberEmojis[i];
1922
- res += "\n";
1923
- }
1924
- res += "🟨" + numberEmojis.slice(0, BOARD_SIZE).join("") + "🟨\n";
1925
- return res;
1926
- }
1927
- generateChat(Score) {
1928
- if (this.lastScore < 5e6 && Score > 5e6 && this.level > 3) {
1929
- return "我觉得你要输了哦~";
1930
- }
1931
- if (this.lastScore < 1e6 && Score > 1e6) {
1932
- return "只能下在这里了~";
1933
- }
1934
- if (4e3 <= Score && Score < 1e4) {
1935
- return "这招怎么样?";
1936
- }
1937
- if (2e3 <= Score && Score < 4e3 && Math.random() < 0.5) {
1938
- return {
1939
- 0: "有点意思哦~",
1940
- 1: "真是焦灼的局面",
1941
- 2: "势均力敌呢~",
1942
- 3: "你在想什么呢?",
1943
- 4: "走这里会不会太冒险了?"
1944
- }[Math.floor(Math.random() * 5)];
1945
- }
1946
- if (Score < -1e6) {
1947
- return "好猛烈的攻击啊~";
1948
- }
1949
- if (Score < 0 && Math.random() < 0.5) {
1950
- return "你还真是厉害呢~";
1951
- }
1952
- if (Score < 100) {
1953
- return "出乎意料的一手啊";
1954
- }
1955
- }
1956
- };
1957
- var goBang = class extends abstractGame {
1958
- static {
1959
- __name(this, "goBang");
1960
- }
1961
- constructor() {
1962
- super(goBangSingleGame);
1963
- }
1964
- // 启动游戏时可传入难度参数
1965
- async startGame(session, ctx, args) {
1966
- let level;
1967
- if (!isNaN(parseInt(args[0])))
1968
- level = parseInt(args[0]);
1969
- else {
1970
- setTimeout(() => {
1971
- session.send("未输入难度等级(2-6),默认设为3");
1972
- }, 500);
1973
- level = 3;
1974
- }
1975
- if (level < 2 || level > 6) {
1976
- level = level < 2 ? 2 : 6;
1977
- setTimeout(() => {
1978
- session.send("难度等级必须在2到6之间,已调整为" + level);
1979
- }, 500);
1980
- }
1981
- const game = await super.startGame(session, ctx, args);
1982
- game.level = level;
1983
- return game;
1984
- }
1985
- };
1986
-
1987
1787
  // src/gamefencing.ts
1988
- var import_koishi10 = require("koishi");
1989
- var logger9 = new import_koishi10.Logger("satori-game-fencing");
1788
+ var logger8 = new import_koishi9.Logger("satori-game-fencing");
1990
1789
  var fencingSingleGame = class _fencingSingleGame extends abstractGameSingleGame {
1991
1790
  static {
1992
1791
  __name(this, "fencingSingleGame");
@@ -2168,8 +1967,8 @@ var fencing = class extends abstractGame {
2168
1967
  };
2169
1968
 
2170
1969
  // src/gameOneTouch.ts
2171
- var import_koishi11 = require("koishi");
2172
- 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");
2173
1972
  var SKILL_MAP = {
2174
1973
  // 基础技能
2175
1974
  "-1": {},
@@ -2260,7 +2059,7 @@ var OneTouchSingleGame = class extends abstractGameSingleGame {
2260
2059
  hp: this.baseHP,
2261
2060
  status: 0 /* Normal */
2262
2061
  };
2263
- return await wrapInHTML2(`游戏开始!
2062
+ return await wrapInHTML(`游戏开始!
2264
2063
  对方的手势:左${this.ai.left} 右${this.ai.right}
2265
2064
  你的手势:左${this.player.left} 右${this.player.right}
2266
2065
  输入格式"左 右"选择要触碰的手
@@ -2310,9 +2109,9 @@ var OneTouchSingleGame = class extends abstractGameSingleGame {
2310
2109
  }
2311
2110
  async processInput(input) {
2312
2111
  if (input === "游戏规则")
2313
- return await wrapInHTML2(this.instuction);
2112
+ return await wrapInHTML(this.instuction);
2314
2113
  if (input === "技能列表")
2315
- return await wrapInHTML2(this.skillList);
2114
+ return await wrapInHTML(this.skillList);
2316
2115
  if (this.turnCount === 0)
2317
2116
  this.initState(this.level);
2318
2117
  this.turnCount++;
@@ -2353,7 +2152,7 @@ var OneTouchSingleGame = class extends abstractGameSingleGame {
2353
2152
  statusIcon(this.player.vulnerablility, "💔"),
2354
2153
  this.player.status === 1 /* Stunned */ ? "💫 眩晕" : ""
2355
2154
  ].filter(Boolean).join(" | ");
2356
- return wrapInHTML2(`▶️你的行动:${result}
2155
+ return wrapInHTML(`▶️你的行动:${result}
2357
2156
 
2358
2157
  ▶️我的行动:${aiResult}
2359
2158
 
@@ -2738,7 +2537,7 @@ ${bonusMessage}` : "");
2738
2537
  bestMove = move;
2739
2538
  }
2740
2539
  }
2741
- logger10.info(`AI选择的动作:${bestMove[0]}碰${bestMove[1]}, 分数:${bestScore}`);
2540
+ logger9.info(`AI选择的动作:${bestMove[0]}碰${bestMove[1]}, 分数:${bestScore}`);
2742
2541
  if (this.turnCount > 5)
2743
2542
  this.session.sendQueued(this.generateChat(bestScore), 1e3);
2744
2543
  this.lastScore = bestScore;
@@ -2964,9 +2763,9 @@ var OneTouchGame = class extends abstractGame {
2964
2763
  return game;
2965
2764
  }
2966
2765
  };
2967
- async function wrapInHTML2(str) {
2766
+ async function wrapInHTML(str) {
2968
2767
  if (!puppeteer) {
2969
- logger10.warn("puppeteer未就绪");
2768
+ logger9.warn("puppeteer未就绪");
2970
2769
  return "出现错误,请联系管理员";
2971
2770
  }
2972
2771
  return puppeteer.render(`<html><body>${str.replaceAll(/\n/g, "<BR>")}</body>
@@ -2978,15 +2777,15 @@ async function wrapInHTML2(str) {
2978
2777
  </style>
2979
2778
  </html>`);
2980
2779
  }
2981
- __name(wrapInHTML2, "wrapInHTML");
2780
+ __name(wrapInHTML, "wrapInHTML");
2982
2781
 
2983
2782
  // src/game.ts
2984
- var logger11 = new import_koishi12.Logger("satori-game");
2783
+ var logger10 = new import_koishi11.Logger("satori-game");
2985
2784
  var Game = class {
2986
2785
  static {
2987
2786
  __name(this, "Game");
2988
2787
  }
2989
- GAMES = ["五子棋", "击剑", "一碰一"];
2788
+ GAMES = ["一碰一"];
2990
2789
  // 支持的游戏列表
2991
2790
  channelGames = /* @__PURE__ */ new Map();
2992
2791
  // 频道ID到游戏名称的映射
@@ -3000,9 +2799,6 @@ var Game = class {
3000
2799
  this.context = ctx;
3001
2800
  this.config = cfg;
3002
2801
  this.sat = sat;
3003
- if (this.config.enable_gobang) {
3004
- this.availableGames.set("五子棋", new goBang());
3005
- }
3006
2802
  if (this.config.enable_fencing) {
3007
2803
  this.availableGames.set("击剑", new fencing());
3008
2804
  }
@@ -3021,8 +2817,6 @@ var Game = class {
3021
2817
  }
3022
2818
  // 启动指定游戏
3023
2819
  async startGame(session, gameName, args) {
3024
- if (this.config.game_block_channel.includes(session.channelId))
3025
- return "本群不支持游戏哦" + (this.config.channel_id_for_gobang[0] ? ",想玩请加群" + this.config.channel_id_for_gobang[0] : "");
3026
2820
  if (this.channelGames.get(session.channelId))
3027
2821
  return "当前频道已经有游戏在进行中";
3028
2822
  if (gameName == "")
@@ -3032,9 +2826,6 @@ var Game = class {
3032
2826
  const game = this.availableGames.get(gameName);
3033
2827
  if (!game)
3034
2828
  return "没有这个游戏哦";
3035
- if (gameName === "五子棋" && !this.config.channel_id_for_gobang.includes(session.channelId)) {
3036
- return "本群不支持五子棋哦,想玩请加群" + this.config.channel_id_for_gobang[0];
3037
- }
3038
2829
  const user = await ensureUserExists(this.context, session.userId, session.username);
3039
2830
  const lastUsage = this.userUsage.get(`${session.userId}-${gameName}`);
3040
2831
  if (lastUsage && user.userlevel < 4) {
@@ -3049,7 +2840,7 @@ var Game = class {
3049
2840
  refreshPuppeteer(this.context);
3050
2841
  game.startGame(session, this.context, args);
3051
2842
  this.channelGames.set(session.channelId, gameName);
3052
- logger11.info(`游戏${gameName}已开始于${session.channelId}`);
2843
+ logger10.info(`游戏${gameName}已开始于${session.channelId}`);
3053
2844
  }
3054
2845
  // 结束当前游戏
3055
2846
  async endGame(session) {
@@ -3058,7 +2849,7 @@ var Game = class {
3058
2849
  return "当前频道没有游戏在进行中";
3059
2850
  if (await this.availableGames.get(gameName).endGame(session, this.context)) {
3060
2851
  this.channelGames.delete(session.channelId);
3061
- logger11.info(`${session.channelId}的游戏已结束`);
2852
+ logger10.info(`${session.channelId}的游戏已结束`);
3062
2853
  }
3063
2854
  }
3064
2855
  async chat(session, gameName, prompt) {
@@ -3071,8 +2862,6 @@ var Game = class {
3071
2862
  }
3072
2863
  getGameCd(gameName) {
3073
2864
  switch (gameName) {
3074
- case "五子棋":
3075
- return this.config.cd_for_gobang;
3076
2865
  case "一碰一":
3077
2866
  return this.config.cd_for_OneTouch;
3078
2867
  default:
@@ -3084,7 +2873,7 @@ var Game = class {
3084
2873
  this.GAMES.forEach((game) => {
3085
2874
  list += game + "\n";
3086
2875
  });
3087
- logger11.info(list);
2876
+ logger10.info(list);
3088
2877
  return list;
3089
2878
  }
3090
2879
  async resultJudge(result, ctx, session) {
@@ -3130,8 +2919,8 @@ var Game = class {
3130
2919
  };
3131
2920
 
3132
2921
  // src/broadcast.ts
3133
- var import_koishi13 = require("koishi");
3134
- 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");
3135
2924
  var BroadcastManager = class {
3136
2925
  static {
3137
2926
  __name(this, "BroadcastManager");
@@ -3161,16 +2950,16 @@ var BroadcastManager = class {
3161
2950
  const id = `broadcast-${this.idCounter++}`;
3162
2951
  const broadcast = new broadcastMessage(this.ctx, this.config, message, img);
3163
2952
  this.broadcastMessages.set(id, broadcast);
3164
- logger12.info(`广播已创建 ID: ${id}`);
2953
+ logger11.info(`广播已创建 ID: ${id}`);
3165
2954
  return `广播已创建 ID: ${id}`;
3166
2955
  }
3167
2956
  async deleteBroadcast(id) {
3168
2957
  if (this.broadcastMessages.has(id)) {
3169
2958
  this.broadcastMessages.delete(id);
3170
- logger12.info(`广播已删除 ID: ${id}`);
2959
+ logger11.info(`广播已删除 ID: ${id}`);
3171
2960
  return "已删除广播:" + id;
3172
2961
  } else {
3173
- logger12.warn(`未找到广播 ID: ${id}`);
2962
+ logger11.warn(`未找到广播 ID: ${id}`);
3174
2963
  return "未找到该广播";
3175
2964
  }
3176
2965
  }
@@ -3178,7 +2967,7 @@ var BroadcastManager = class {
3178
2967
  for (const [id, broadcast] of this.broadcastMessages.entries()) {
3179
2968
  if (broadcast.setTime.getTime() + 1e3 * 60 * this.config.waiting_time < Date.now()) {
3180
2969
  this.broadcastMessages.delete(id);
3181
- logger12.info(`广播已过期 ID: ${id}`);
2970
+ logger11.info(`广播已过期 ID: ${id}`);
3182
2971
  continue;
3183
2972
  }
3184
2973
  await broadcast.sendMessage(session);
@@ -3206,7 +2995,7 @@ ${alreadySentChannels}
3206
2995
  }
3207
2996
  }
3208
2997
  const result = list.length > 0 ? list.join("\n") : null;
3209
- return result ? wrapInHTML3(result) : null;
2998
+ return result ? wrapInHTML2(result) : null;
3210
2999
  }
3211
3000
  };
3212
3001
  var broadcastMessage = class {
@@ -3237,13 +3026,13 @@ var broadcastMessage = class {
3237
3026
  try {
3238
3027
  this.alreadySentChannels.add(channelId);
3239
3028
  if (this.img) {
3240
- session.send(await wrapInHTML3(this.message));
3029
+ session.send(await wrapInHTML2(this.message));
3241
3030
  } else {
3242
3031
  session.send(this.message);
3243
3032
  }
3244
- logger12.info(`向群 ${channelId} 广播: ${this.message}`);
3033
+ logger11.info(`向群 ${channelId} 广播: ${this.message}`);
3245
3034
  } catch (error) {
3246
- logger12.error(`广播失败 ${channelId}: ${error}`);
3035
+ logger11.error(`广播失败 ${channelId}: ${error}`);
3247
3036
  }
3248
3037
  }
3249
3038
  getAlreadySentChannels() {
@@ -3251,9 +3040,9 @@ var broadcastMessage = class {
3251
3040
  return alreadySentChannels.length > 0 ? alreadySentChannels.join("\n") : "无";
3252
3041
  }
3253
3042
  };
3254
- async function wrapInHTML3(str) {
3043
+ async function wrapInHTML2(str) {
3255
3044
  if (!puppeteer) {
3256
- logger12.warn("puppeteer未就绪");
3045
+ logger11.warn("puppeteer未就绪");
3257
3046
  return str;
3258
3047
  }
3259
3048
  return puppeteer.render(`<html><body>${str.replaceAll(/\n/g, "<BR>")}</body>
@@ -3265,16 +3054,16 @@ async function wrapInHTML3(str) {
3265
3054
  </style>
3266
3055
  </html>`);
3267
3056
  }
3268
- __name(wrapInHTML3, "wrapInHTML");
3057
+ __name(wrapInHTML2, "wrapInHTML");
3269
3058
 
3270
3059
  // src/index.tsx
3271
- var logger13 = new import_koishi14.Logger("satori-ai");
3060
+ var logger12 = new import_koishi13.Logger("satori-ai");
3272
3061
  var puppeteer = null;
3273
3062
  function refreshPuppeteer(ctx) {
3274
3063
  if (ctx.puppeteer) {
3275
3064
  puppeteer = ctx.puppeteer;
3276
3065
  } else {
3277
- logger13.warn("puppeteer未就绪");
3066
+ logger12.warn("puppeteer未就绪");
3278
3067
  }
3279
3068
  }
3280
3069
  __name(refreshPuppeteer, "refreshPuppeteer");
@@ -3462,9 +3251,9 @@ var SAT = class extends Sat {
3462
3251
  const messages = generateAuxiliaryPrompt(prompt, response.content, user, this.getFavorabilityConfig());
3463
3252
  const result = await this.apiClient.auxiliaryChat(messages);
3464
3253
  if (result.error) {
3465
- logger13.error(`辅助判断失败:${result.content}`);
3254
+ logger12.error(`辅助判断失败:${result.content}`);
3466
3255
  } else {
3467
- logger13.info(`辅助判断:${result.content}`);
3256
+ logger12.info(`辅助判断:${result.content}`);
3468
3257
  return handleAuxiliaryResult(this.ctx, session, this.getFavorabilityConfig(), result.content);
3469
3258
  }
3470
3259
  }
@@ -3551,21 +3340,21 @@ var SAT = class extends Sat {
3551
3340
  await inputContentCheck(this.ctx, censored, session.userId, this.getFavorabilityConfig(), session, this.moodManager);
3552
3341
  }
3553
3342
  if (this.config.log_ask_response)
3554
- logger13.info(`用户 ${session.username}:${processedPrompt}`);
3343
+ logger12.info(`用户 ${session.username}:${processedPrompt}`);
3555
3344
  return censored;
3556
3345
  }
3557
3346
  // 生成回复
3558
3347
  async generateResponse(session, prompt) {
3559
3348
  if (this.getChannelParallelCount(session) > this.config.max_parallel_count) {
3560
- logger13.info(`频道 ${session.channelId} 并发数过高(${this.getChannelParallelCount(session)}),${session.username}等待中...`);
3349
+ logger12.info(`频道 ${session.channelId} 并发数过高(${this.getChannelParallelCount(session)}),${session.username}等待中...`);
3561
3350
  }
3562
3351
  while (this.getChannelParallelCount(session) > this.config.max_parallel_count) {
3563
3352
  this.updateChannelParallelCount(session, -1);
3564
- await new Promise((resolve3) => setTimeout(resolve3, 1e3));
3353
+ await new Promise((resolve2) => setTimeout(resolve2, 1e3));
3565
3354
  this.updateChannelParallelCount(session, 1);
3566
3355
  }
3567
3356
  const messages = await this.buildMessages(session, prompt);
3568
- logger13.info(`频道 ${session.channelId} 处理:${session.userId},剩余${this.getChannelParallelCount(session)}并发`);
3357
+ logger12.info(`频道 ${session.channelId} 处理:${session.userId},剩余${this.getChannelParallelCount(session)}并发`);
3569
3358
  const user = await getUser(this.ctx, session.userId);
3570
3359
  let response = await this.getChatResponse(user, messages);
3571
3360
  if (response.error)
@@ -3579,9 +3368,9 @@ var SAT = class extends Sat {
3579
3368
  let response = await this.apiClient.chat(user, messages);
3580
3369
  if (this.config.log_ask_response) {
3581
3370
  if (this.config.enable_favorability && this.config.enable_mood)
3582
- logger13.info(`Satori AI:(心情值:${this.moodManager.getMoodValue(user.userid)})${response.content}`);
3371
+ logger12.info(`Satori AI:(心情值:${this.moodManager.getMoodValue(user.userid)})${response.content}`);
3583
3372
  else
3584
- logger13.info(`Satori AI:${response.content}`);
3373
+ logger12.info(`Satori AI:${response.content}`);
3585
3374
  }
3586
3375
  if (this.config.reasoner_filter && !response.error)
3587
3376
  response = filterResponse(response.content, this.config.reasoner_filter_word.split("-"));
@@ -3605,7 +3394,7 @@ var SAT = class extends Sat {
3605
3394
  messages.push({ role: "user", content: prompt });
3606
3395
  let payload = messages.map((msg) => msg.role + ":" + msg.content).join("\n");
3607
3396
  if (this.config.log_system_prompt)
3608
- logger13.info(`系统提示:
3397
+ logger12.info(`系统提示:
3609
3398
  ${payload}`);
3610
3399
  return messages;
3611
3400
  }
@@ -3664,7 +3453,7 @@ ${payload}`);
3664
3453
  getThinkingPrompt(user, prompt) {
3665
3454
  const reasonerPrompt = this.config.reasoner_prompt;
3666
3455
  const promptForNoReasoner = `#请你在回复时先进行分析思考,并且模仿思维链的模式输出思考内容,${reasonerPrompt};
3667
- #你在思考时必须以 "<think>" 开头, "</think>" 结尾。仔细揣摩用户意图,完整输出思考内容后在输出正式的回复内容;
3456
+ #你在思考时必须以 "<think>" 开头, "</think>" 结尾。仔细揣摩用户意图,**完整输出思考内容后**再输出正式的回复内容;
3668
3457
  #注意:你的正式回复内容必须使用“<p>”开头,使用“</p>”结尾,并且无论如何都要把标签输出完整
3669
3458
  `;
3670
3459
  const promptForReasoner = `#你在思考时必须以 "嗯" 开头。仔细揣摩用户意图,思考结束后返回符合要求的回复。
@@ -3710,10 +3499,10 @@ ${useNoReasoner ? promptForNoReasoner : promptForReasoner}
3710
3499
  response = `@${session.username} ` + response;
3711
3500
  }
3712
3501
  if (this.config.sentences_divide && response.length > 10) {
3713
- 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));
3714
3503
  for (const sentence of sentences) {
3715
3504
  await session.send(sentence);
3716
- await new Promise((resolve3) => setTimeout(resolve3, this.config.time_interval));
3505
+ await new Promise((resolve2) => setTimeout(resolve2, this.config.time_interval));
3717
3506
  }
3718
3507
  return null;
3719
3508
  }
@@ -3723,7 +3512,7 @@ ${useNoReasoner ? promptForNoReasoner : promptForReasoner}
3723
3512
  if (!this.config.enable_warning)
3724
3513
  return;
3725
3514
  if (auxiliaryResult.includes("好感↓")) {
3726
- logger13.info(`在群${session.channelId}中,${session.username}骚扰我!`);
3515
+ logger12.info(`在群${session.channelId}中,${session.username}骚扰我!`);
3727
3516
  this.usersToWarn.set(session.channelId, session.username);
3728
3517
  }
3729
3518
  }
@@ -3763,10 +3552,10 @@ ${useNoReasoner ? promptForNoReasoner : promptForReasoner}
3763
3552
  async addCommonSense(session, content) {
3764
3553
  if (!content)
3765
3554
  return session.text("commands.sat.common_sense.messages.no-prompt");
3766
- const filePath = path7.join(this.config.dataDir, "common_sense.txt");
3555
+ const filePath = path6.join(this.config.dataDir, "common_sense.txt");
3767
3556
  await this.memoryManager.saveLongTermMemory(session, [{
3768
3557
  role: "user",
3769
- content
3558
+ content: content.replace(/\"/g, "'").trim()
3770
3559
  }], filePath);
3771
3560
  return session.text("commands.sat.common_sense.messages.succeed", [content]);
3772
3561
  }
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.6",
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