koishi-plugin-satori-ai 1.2.9 → 1.2.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/database.d.ts +1 -0
- package/lib/favorability.d.ts +3 -2
- package/lib/game.d.ts +3 -1
- package/lib/index.d.ts +11 -2
- package/lib/index.js +463 -180
- package/lib/mood.d.ts +19 -0
- package/lib/types.d.ts +26 -4
- package/lib/utils.d.ts +8 -3
- package/package.json +1 -1
- package/wasm/gobang.cpp +18 -8
- package/wasm/gobang.js +21 -21
- package/wasm/gobang.wasm +0 -0
package/lib/database.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export declare function updateFavorability(ctx: Context, user: User, adjustment:
|
|
|
11
11
|
export declare function updateUserLevel(ctx: Context, user: User, level: number): Promise<void>;
|
|
12
12
|
export declare function updateUserUsage(ctx: Context, user: User, adjustment?: number): Promise<number | void>;
|
|
13
13
|
export declare function updateUserItems(ctx: Context, user: User): Promise<void>;
|
|
14
|
+
export declare function updateUserP(ctx: Context, user: User, adjustment: number): Promise<void>;
|
|
14
15
|
export declare function getUser(ctx: Context, userId: string): Promise<User | null>;
|
|
15
16
|
export declare function ensureUserExists(ctx: Context, userId: string, username: string): Promise<User>;
|
|
16
17
|
export declare function extendDatabase(ctx: Context): void;
|
package/lib/favorability.d.ts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { Context, Session } from 'koishi';
|
|
2
2
|
import { User, FavorabilityLevel, FavorabilityConfig } from './types';
|
|
3
|
+
import { MoodManager } from './mood';
|
|
3
4
|
import { Sat } from './types';
|
|
4
5
|
export declare function handleFavorabilitySystem(ctx: Context, session: Session, config: FavorabilityConfig): Promise<string | void>;
|
|
5
6
|
export declare function getFavorabilityLevel(user: User, config: FavorabilityConfig): FavorabilityLevel;
|
|
6
7
|
export declare function generateLevelPrompt(level: FavorabilityLevel, config: FavorabilityConfig, user: User): string;
|
|
7
8
|
export declare function generateAuxiliaryPrompt(prompt: string, responseContent: string, user: User, config: FavorabilityConfig): Sat.Msg[];
|
|
8
9
|
export declare function handleAuxiliaryResult(ctx: Context, session: Session, config: FavorabilityConfig, responseContent: string): Promise<string | void>;
|
|
9
|
-
export declare function inputContentCheck(ctx: Context, content: string, userid: string, config: FavorabilityConfig, session: Session): Promise<number>;
|
|
10
|
+
export declare function inputContentCheck(ctx: Context, content: string, userid: string, config: FavorabilityConfig, session: Session, moodManager: MoodManager): Promise<number>;
|
|
10
11
|
export declare function outputContentCheck(ctx: Context, response: {
|
|
11
12
|
content: string;
|
|
12
13
|
error: boolean;
|
|
13
|
-
}, userid: string, config: FavorabilityConfig, session: Session): Promise<number>;
|
|
14
|
+
}, userid: string, config: FavorabilityConfig, session: Session, moodManager: MoodManager): Promise<number>;
|
|
14
15
|
export declare function ensureCensorFileExists(basePath: string): Promise<void>;
|
|
15
16
|
export declare function applyFavorabilityEffect(ctx: Context, user: User, effect: number, session: Session): Promise<void>;
|
package/lib/game.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Session, Context } from 'koishi';
|
|
2
2
|
import { Sat } from './types';
|
|
3
|
+
import { SAT } from './index';
|
|
3
4
|
/**
|
|
4
5
|
* 游戏总控类,管理所有可用游戏和命令
|
|
5
6
|
*/
|
|
@@ -10,9 +11,10 @@ export declare class Game {
|
|
|
10
11
|
private context;
|
|
11
12
|
private config;
|
|
12
13
|
private sat;
|
|
13
|
-
constructor(ctx: Context, cfg: Sat.Config, sat:
|
|
14
|
+
constructor(ctx: Context, cfg: Sat.Config, sat: SAT);
|
|
14
15
|
private registerCommands;
|
|
15
16
|
startGame(session: Session, gameName: string, args: string[]): Promise<"当前频道已经有游戏在进行中" | "没有这个游戏哦">;
|
|
16
17
|
endGame(session: Session): Promise<string>;
|
|
17
18
|
private selectGame;
|
|
19
|
+
private chat;
|
|
18
20
|
}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Context, Session } from 'koishi';
|
|
2
|
-
import { Sat } from './types';
|
|
2
|
+
import { Sat, User } from './types';
|
|
3
3
|
export declare class SAT extends Sat {
|
|
4
4
|
config: Sat.Config;
|
|
5
5
|
private apiClient;
|
|
@@ -7,6 +7,7 @@ export declare class SAT extends Sat {
|
|
|
7
7
|
private portraitManager;
|
|
8
8
|
private ChannelParallelCount;
|
|
9
9
|
private onlineUsers;
|
|
10
|
+
private moodManager;
|
|
10
11
|
private game;
|
|
11
12
|
constructor(ctx: Context, config: Sat.Config);
|
|
12
13
|
private getAPIConfig;
|
|
@@ -24,9 +25,17 @@ export declare class SAT extends Sat {
|
|
|
24
25
|
private updateChannelParallelCount;
|
|
25
26
|
private getChannelParallelCount;
|
|
26
27
|
private processInput;
|
|
27
|
-
|
|
28
|
+
generateResponse(session: Session, prompt: string): Promise<{
|
|
29
|
+
content: string;
|
|
30
|
+
error: boolean;
|
|
31
|
+
}>;
|
|
32
|
+
getChatResponse(user: User, messages: Sat.Msg[]): Promise<{
|
|
33
|
+
content: string;
|
|
34
|
+
error: boolean;
|
|
35
|
+
}>;
|
|
28
36
|
private buildMessages;
|
|
29
37
|
private buildSystemPrompt;
|
|
38
|
+
private getThinkingPrompt;
|
|
30
39
|
private formatResponse;
|
|
31
40
|
private clearSession;
|
|
32
41
|
private addCommonSense;
|
package/lib/index.js
CHANGED
|
@@ -33,7 +33,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
33
33
|
// src/locales/zh.yml
|
|
34
34
|
var require_zh = __commonJS({
|
|
35
35
|
"src/locales/zh.yml"(exports, module2) {
|
|
36
|
-
module2.exports = { commands: { sat: { description: "AI聊天", messages: { "no-prompt": "你好。使用说明可以看我的空间哦。", tooManyEnglishLetters: "请不要用这么多英文......", err: "寄!{0}", tooLong: "你的话太多了。", content_tooLong: "这个问题有点复杂,你还是去问别人吧。", "duplicate-dialogue": "这个刚刚说过了吧......", online: "思考中,请再等一会!", "no-response": "我不知道你在说什么……", update_level_succeed: "用户等级已更新为{0}", exceeds: "已经差不多够了吧?请明天再来。", usage: "今日次数{0}/{1}", hatMan: "叮!帽子先生保护了你的好感度,快说谢谢帽子先生吧!", rockBottom: "叮!谷底小石保护了你的好感度,快说谢谢谷底小石吧!", block1: "我讨厌你!", block2: "我讨厌你们!" } }, "sat.clear": { description: "清空当前频道会话", messages: { clean: "已清空当前会话。", Allclean: "已清空所有会话。" } }, "sat.common_sense": { description: "添加常识", messages: { "no-prompt": "你想让我知道什么?", succeed: "我知道了,{0}" } } } };
|
|
36
|
+
module2.exports = { commands: { sat: { description: "AI聊天", messages: { "no-prompt": "你好。使用说明可以看我的空间哦。", tooManyEnglishLetters: "请不要用这么多英文......", err: "寄!{0}", tooLong: "你的话太多了。", content_tooLong: "这个问题有点复杂,你还是去问别人吧。", "duplicate-dialogue": "这个刚刚说过了吧......", online: "思考中,请再等一会!", "no-response": "我不知道你在说什么……", update_level_succeed: "用户等级已更新为{0}", exceeds: "已经差不多够了吧?请明天再来。", usage: "今日次数{0}/{1}", hatMan: "叮!帽子先生保护了你的好感度,快说谢谢帽子先生吧!", rockBottom: "叮!谷底小石保护了你的好感度,快说谢谢谷底小石吧!", not_good_mood: "别得寸进尺……(好感↓)", pocket_money: "心情不错,给你点零花钱吧~(获得了{0}p点)", block1: "我讨厌你!", block2: "我讨厌你们!" } }, "sat.clear": { description: "清空当前频道会话", messages: { clean: "已清空当前会话。", Allclean: "已清空所有会话。" } }, "sat.common_sense": { description: "添加常识", messages: { "no-prompt": "你想让我知道什么?", succeed: "我知道了,{0}" } } } };
|
|
37
37
|
}
|
|
38
38
|
});
|
|
39
39
|
|
|
@@ -44,7 +44,7 @@ __export(src_exports, {
|
|
|
44
44
|
default: () => src_default
|
|
45
45
|
});
|
|
46
46
|
module.exports = __toCommonJS(src_exports);
|
|
47
|
-
var
|
|
47
|
+
var import_koishi8 = require("koishi");
|
|
48
48
|
var path6 = __toESM(require("path"));
|
|
49
49
|
|
|
50
50
|
// src/api.ts
|
|
@@ -52,6 +52,107 @@ var import_koishi2 = require("koishi");
|
|
|
52
52
|
|
|
53
53
|
// src/utils.ts
|
|
54
54
|
var import_koishi = require("koishi");
|
|
55
|
+
|
|
56
|
+
// src/database.ts
|
|
57
|
+
async function isTargetIdNotExists(ctx, userId) {
|
|
58
|
+
const users = await ctx.database.get("p_system", { userid: userId });
|
|
59
|
+
return users.length === 0;
|
|
60
|
+
}
|
|
61
|
+
__name(isTargetIdNotExists, "isTargetIdNotExists");
|
|
62
|
+
async function createUser(ctx, user) {
|
|
63
|
+
await ctx.database.create("p_system", {
|
|
64
|
+
userid: user.userid || "",
|
|
65
|
+
usersname: user.usersname || "",
|
|
66
|
+
p: user.p || 0,
|
|
67
|
+
favorability: user.favorability || 0,
|
|
68
|
+
userlevel: user.userlevel || 0,
|
|
69
|
+
usage: user.usage || 0,
|
|
70
|
+
lastChatTime: user.lastChatTime || (/* @__PURE__ */ new Date()).getDate(),
|
|
71
|
+
items: user.items || {}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
__name(createUser, "createUser");
|
|
75
|
+
async function updateFavorability(ctx, user, adjustment) {
|
|
76
|
+
if (!user)
|
|
77
|
+
return;
|
|
78
|
+
let newValue;
|
|
79
|
+
if (typeof adjustment === "number")
|
|
80
|
+
newValue = user.favorability + adjustment;
|
|
81
|
+
else
|
|
82
|
+
newValue = user.favorability;
|
|
83
|
+
await ctx.database.set("p_system", { userid: user.userid }, { favorability: newValue });
|
|
84
|
+
}
|
|
85
|
+
__name(updateFavorability, "updateFavorability");
|
|
86
|
+
async function updateUserLevel(ctx, user, level) {
|
|
87
|
+
if (!user)
|
|
88
|
+
return;
|
|
89
|
+
level = level < 5 ? level : 4;
|
|
90
|
+
await ctx.database.set("p_system", { userid: user.userid }, { userlevel: level });
|
|
91
|
+
}
|
|
92
|
+
__name(updateUserLevel, "updateUserLevel");
|
|
93
|
+
async function updateUserUsage(ctx, user, adjustment = 1) {
|
|
94
|
+
if (!user)
|
|
95
|
+
return;
|
|
96
|
+
if (user.lastChatTime && (/* @__PURE__ */ new Date()).getDate() !== user.lastChatTime)
|
|
97
|
+
user.usage = 0;
|
|
98
|
+
await ctx.database.set("p_system", { userid: user.userid }, { usage: user.usage + adjustment });
|
|
99
|
+
await ctx.database.set("p_system", { userid: user.userid }, { lastChatTime: (/* @__PURE__ */ new Date()).getDate() });
|
|
100
|
+
return user.usage + adjustment;
|
|
101
|
+
}
|
|
102
|
+
__name(updateUserUsage, "updateUserUsage");
|
|
103
|
+
async function updateUserItems(ctx, user) {
|
|
104
|
+
if (!user)
|
|
105
|
+
return;
|
|
106
|
+
await ctx.database.set("p_system", { userid: user.userid }, { items: user.items });
|
|
107
|
+
}
|
|
108
|
+
__name(updateUserItems, "updateUserItems");
|
|
109
|
+
async function updateUserP(ctx, user, adjustment) {
|
|
110
|
+
if (!user)
|
|
111
|
+
return;
|
|
112
|
+
user.p = await ctx.database.get("p_system", { userid: user.userid })[0]?.p || user.p;
|
|
113
|
+
if (user.p + adjustment < 0)
|
|
114
|
+
adjustment = -user.p;
|
|
115
|
+
await ctx.database.set("p_system", { userid: user.userid }, { p: user.p + adjustment });
|
|
116
|
+
}
|
|
117
|
+
__name(updateUserP, "updateUserP");
|
|
118
|
+
async function getUser(ctx, userId) {
|
|
119
|
+
const users = await ctx.database.get("p_system", { userid: userId });
|
|
120
|
+
return users[0] || null;
|
|
121
|
+
}
|
|
122
|
+
__name(getUser, "getUser");
|
|
123
|
+
async function ensureUserExists(ctx, userId, username) {
|
|
124
|
+
const notExists = await isTargetIdNotExists(ctx, userId);
|
|
125
|
+
if (notExists) {
|
|
126
|
+
await createUser(ctx, {
|
|
127
|
+
userid: userId,
|
|
128
|
+
usersname: username,
|
|
129
|
+
p: 0,
|
|
130
|
+
favorability: 0,
|
|
131
|
+
userlevel: 0,
|
|
132
|
+
usage: 0,
|
|
133
|
+
lastChatTime: (/* @__PURE__ */ new Date()).getDate(),
|
|
134
|
+
items: {}
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
return getUser(ctx, userId);
|
|
138
|
+
}
|
|
139
|
+
__name(ensureUserExists, "ensureUserExists");
|
|
140
|
+
function extendDatabase(ctx) {
|
|
141
|
+
ctx.model.extend("p_system", {
|
|
142
|
+
id: "unsigned",
|
|
143
|
+
userid: "string",
|
|
144
|
+
usersname: "string",
|
|
145
|
+
p: "integer",
|
|
146
|
+
favorability: "integer",
|
|
147
|
+
userlevel: "integer",
|
|
148
|
+
usage: "integer",
|
|
149
|
+
lastChatTime: "integer",
|
|
150
|
+
items: "object"
|
|
151
|
+
}, { autoInc: true });
|
|
152
|
+
}
|
|
153
|
+
__name(extendDatabase, "extendDatabase");
|
|
154
|
+
|
|
155
|
+
// src/utils.ts
|
|
55
156
|
var fs = __toESM(require("fs"));
|
|
56
157
|
var path = __toESM(require("path"));
|
|
57
158
|
var logger = new import_koishi.Logger("satori-utils");
|
|
@@ -89,39 +190,50 @@ function trimSlash(url) {
|
|
|
89
190
|
return url.replace(/\/$/, "");
|
|
90
191
|
}
|
|
91
192
|
__name(trimSlash, "trimSlash");
|
|
92
|
-
function splitSentences(text) {
|
|
93
|
-
const
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
193
|
+
function splitSentences(text, MIN_LENGTH, MAX_LENGTH) {
|
|
194
|
+
const PUNCTUATION_REGEX = /([。!?!?…]+)/g;
|
|
195
|
+
const rawSegments = text.split(PUNCTUATION_REGEX);
|
|
196
|
+
const initialSentences = [];
|
|
197
|
+
for (let i = 0; i < rawSegments.length; i += 2) {
|
|
198
|
+
const sentence = rawSegments[i]?.trim() || "";
|
|
199
|
+
const punctuation = rawSegments[i + 1]?.trim() || "";
|
|
200
|
+
if (sentence)
|
|
201
|
+
initialSentences.push(sentence + punctuation);
|
|
202
|
+
}
|
|
203
|
+
const finalSentences = [];
|
|
204
|
+
let currentSentence = "";
|
|
205
|
+
for (const sentence of initialSentences) {
|
|
206
|
+
const potentialLength = currentSentence.length + sentence.length;
|
|
207
|
+
if (sentence.length > MAX_LENGTH) {
|
|
208
|
+
if (currentSentence)
|
|
209
|
+
finalSentences.push(currentSentence);
|
|
210
|
+
finalSentences.push(sentence);
|
|
211
|
+
currentSentence = "";
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
if (potentialLength <= MAX_LENGTH) {
|
|
215
|
+
currentSentence += sentence;
|
|
216
|
+
if (currentSentence.length >= MIN_LENGTH && potentialLength >= MAX_LENGTH * 0.8) {
|
|
217
|
+
finalSentences.push(currentSentence);
|
|
218
|
+
currentSentence = "";
|
|
219
|
+
}
|
|
99
220
|
} else {
|
|
100
|
-
|
|
101
|
-
|
|
221
|
+
finalSentences.push(currentSentence);
|
|
222
|
+
currentSentence = sentence;
|
|
102
223
|
}
|
|
103
224
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const result = [];
|
|
110
|
-
let temp = "";
|
|
111
|
-
for (let i = 0; i < sentences.length; i++) {
|
|
112
|
-
if (i === sentences.length - 2) {
|
|
113
|
-
temp = sentences[i] + sentences[i + 1];
|
|
114
|
-
result.push(temp);
|
|
115
|
-
break;
|
|
225
|
+
if (currentSentence)
|
|
226
|
+
finalSentences.push(currentSentence);
|
|
227
|
+
return finalSentences.reduce((result, sentence) => {
|
|
228
|
+
if (sentence.length < MIN_LENGTH && result.length > 0) {
|
|
229
|
+
result[result.length - 1] += sentence;
|
|
116
230
|
} else {
|
|
117
|
-
|
|
118
|
-
result.push(temp);
|
|
119
|
-
temp = "";
|
|
231
|
+
result.push(sentence);
|
|
120
232
|
}
|
|
121
|
-
|
|
122
|
-
|
|
233
|
+
return result;
|
|
234
|
+
}, []);
|
|
123
235
|
}
|
|
124
|
-
__name(
|
|
236
|
+
__name(splitSentences, "splitSentences");
|
|
125
237
|
function probabilisticCheck(probability) {
|
|
126
238
|
return Math.random() < probability;
|
|
127
239
|
}
|
|
@@ -138,6 +250,9 @@ function processPrompt(prompt) {
|
|
|
138
250
|
prompt = prompt.replace(/<[^>]*?avatar[^>]*>/g, "。回复:");
|
|
139
251
|
prompt = prompt.replace(/<[^>]*?img[^>]*>/g, "[图片]");
|
|
140
252
|
prompt = prompt.replace(/<[^>]*?name="([^\"]*)"[^>]*>/g, (_, name) => `@${name}`);
|
|
253
|
+
prompt = prompt.replace(/\*\*/g, "");
|
|
254
|
+
if (!prompt)
|
|
255
|
+
return "**";
|
|
141
256
|
return prompt;
|
|
142
257
|
}
|
|
143
258
|
__name(processPrompt, "processPrompt");
|
|
@@ -149,12 +264,14 @@ function filterResponse(prompt, words) {
|
|
|
149
264
|
}
|
|
150
265
|
return part;
|
|
151
266
|
}).join("");
|
|
267
|
+
if (filtered.includes("<think>") && !filtered.includes("</think>"))
|
|
268
|
+
return { content: "……", error: true };
|
|
152
269
|
const regex = /<think>[\s\S]*?<\/think>/g;
|
|
153
270
|
const filteredThink = filtered.replace(regex, "");
|
|
154
271
|
const regex2 = /<think>|<\/think>/g;
|
|
155
272
|
const filtered2 = filteredThink.replace(regex2, "");
|
|
156
273
|
const trimmedResult = filtered2.trim();
|
|
157
|
-
return trimmedResult === "" ? "……" : trimmedResult;
|
|
274
|
+
return trimmedResult === "" ? { content: "……", error: true } : { content: trimmedResult, error: false };
|
|
158
275
|
}
|
|
159
276
|
__name(filterResponse, "filterResponse");
|
|
160
277
|
function addOutputCensor(session, word, baseURL) {
|
|
@@ -169,6 +286,14 @@ function addOutputCensor(session, word, baseURL) {
|
|
|
169
286
|
session.send(`添加"${word}"成功`);
|
|
170
287
|
}
|
|
171
288
|
__name(addOutputCensor, "addOutputCensor");
|
|
289
|
+
async function updateUserPWithTicket(ctx, user, adjustment) {
|
|
290
|
+
if (!user)
|
|
291
|
+
return;
|
|
292
|
+
if (user?.items?.["地灵殿通行证"]?.description && user.items["地灵殿通行证"].description === "on") {
|
|
293
|
+
await updateUserP(ctx, user, adjustment);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
__name(updateUserPWithTicket, "updateUserPWithTicket");
|
|
172
297
|
|
|
173
298
|
// src/api.ts
|
|
174
299
|
var logger2 = new import_koishi2.Logger("satori-api");
|
|
@@ -185,20 +310,26 @@ var APIClient = class {
|
|
|
185
310
|
// 发送聊天请求
|
|
186
311
|
async chat(user, messages) {
|
|
187
312
|
if (user.userid == "Alice")
|
|
188
|
-
return { content: "(系统)
|
|
313
|
+
return { content: "(系统)这是一个测试句子。这个句子稍长一些,包含多个标点符号!这是一个特别长的句子,需要超过最大长度限制的句子应该被保留原样,但这种情况在实际使用中应该尽量避免。最后?这是一个需要合并的短句!;", error: false };
|
|
189
314
|
const enableUserKey = user?.items?.["地灵殿通行证"]?.description && user.items["地灵殿通行证"].description == "on";
|
|
190
315
|
let keys;
|
|
191
316
|
let modle;
|
|
192
317
|
let baseURL;
|
|
193
318
|
if (enableUserKey) {
|
|
194
|
-
const
|
|
195
|
-
keys = [key];
|
|
196
|
-
modle =
|
|
197
|
-
baseURL =
|
|
319
|
+
const ticket = user.items["地灵殿通行证"].metadata;
|
|
320
|
+
keys = [ticket?.key];
|
|
321
|
+
modle = ticket?.model;
|
|
322
|
+
baseURL = ticket?.baseURL;
|
|
323
|
+
const not_reasoner_model = ticket?.not_reasoner_model;
|
|
324
|
+
const length = ticket?.use_not_reasoner_LLM_length;
|
|
325
|
+
if (not_reasoner_model && length && messages[messages.length - 1].content.length <= length)
|
|
326
|
+
modle = not_reasoner_model;
|
|
198
327
|
} else {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
328
|
+
const config = this.config;
|
|
329
|
+
const useNotReasoner = messages[messages.length - 1].content.length <= config.use_not_reasoner_LLM_length;
|
|
330
|
+
keys = useNotReasoner ? config.not_reasoner_LLM_key : config.keys;
|
|
331
|
+
modle = useNotReasoner ? config.not_reasoner_LLM : config.appointModel;
|
|
332
|
+
baseURL = useNotReasoner ? config.not_reasoner_LLM_URL : config.baseURL;
|
|
202
333
|
}
|
|
203
334
|
const payload = this.createPayload(messages, modle);
|
|
204
335
|
for (let i = 0; i < keys.length; i++) {
|
|
@@ -276,7 +407,6 @@ var APIClient = class {
|
|
|
276
407
|
return {
|
|
277
408
|
model,
|
|
278
409
|
messages,
|
|
279
|
-
max_tokens: this.config.content_max_tokens,
|
|
280
410
|
temperature: this.config.temperature,
|
|
281
411
|
top_p: 1,
|
|
282
412
|
frequency_penalty: this.config.frequency_penalty,
|
|
@@ -300,19 +430,13 @@ var APIClient = class {
|
|
|
300
430
|
try {
|
|
301
431
|
const response = await this.ctx.http.post(url, payload, { headers, timeout: 36e5 });
|
|
302
432
|
content = response.choices[0].message.content;
|
|
303
|
-
const reasoning_content = response.choices[0].message.reasoning_content;
|
|
433
|
+
const reasoning_content = response.choices[0].message.reasoning_content || "无";
|
|
304
434
|
if (this.config.reasoning_content)
|
|
305
|
-
logger2.info(`思维链: ${reasoning_content
|
|
435
|
+
logger2.info(`思维链: ${reasoning_content}`);
|
|
306
436
|
if (!content && reasoning_content) {
|
|
307
437
|
logger2.warn("返回内容为空,但存在推理内容");
|
|
308
438
|
content = response.choices[0].message.reasoning_content;
|
|
309
439
|
}
|
|
310
|
-
if (content.length > this.config.content_max_length) {
|
|
311
|
-
logger2.warn(`返回内容超过最大长度(${content.length} > ${this.config.content_max_length})`);
|
|
312
|
-
if (i >= 2)
|
|
313
|
-
return { content: "返回内容超过最大长度", error: true };
|
|
314
|
-
continue;
|
|
315
|
-
}
|
|
316
440
|
const responseMsg = { role: "assistant", content };
|
|
317
441
|
if (payload.messages.some((msg) => msg === responseMsg) && content.length > 5) {
|
|
318
442
|
const lastMsg = payload.messages[payload.messages.length - 1];
|
|
@@ -388,98 +512,6 @@ var APIClient = class {
|
|
|
388
512
|
var import_koishi3 = require("koishi");
|
|
389
513
|
var fs2 = __toESM(require("fs"));
|
|
390
514
|
var path2 = __toESM(require("path"));
|
|
391
|
-
|
|
392
|
-
// src/database.ts
|
|
393
|
-
async function isTargetIdNotExists(ctx, userId) {
|
|
394
|
-
const users = await ctx.database.get("p_system", { userid: userId });
|
|
395
|
-
return users.length === 0;
|
|
396
|
-
}
|
|
397
|
-
__name(isTargetIdNotExists, "isTargetIdNotExists");
|
|
398
|
-
async function createUser(ctx, user) {
|
|
399
|
-
await ctx.database.create("p_system", {
|
|
400
|
-
userid: user.userid || "",
|
|
401
|
-
usersname: user.usersname || "",
|
|
402
|
-
p: user.p || 0,
|
|
403
|
-
favorability: user.favorability || 0,
|
|
404
|
-
userlevel: user.userlevel || 0,
|
|
405
|
-
usage: user.usage || 0,
|
|
406
|
-
lastChatTime: user.lastChatTime || (/* @__PURE__ */ new Date()).getDate(),
|
|
407
|
-
items: user.items || {}
|
|
408
|
-
});
|
|
409
|
-
}
|
|
410
|
-
__name(createUser, "createUser");
|
|
411
|
-
async function updateFavorability(ctx, user, adjustment) {
|
|
412
|
-
if (!user)
|
|
413
|
-
return;
|
|
414
|
-
let newValue;
|
|
415
|
-
if (typeof adjustment === "number")
|
|
416
|
-
newValue = user.favorability + adjustment;
|
|
417
|
-
else
|
|
418
|
-
newValue = user.favorability;
|
|
419
|
-
await ctx.database.set("p_system", { userid: user.userid }, { favorability: newValue });
|
|
420
|
-
}
|
|
421
|
-
__name(updateFavorability, "updateFavorability");
|
|
422
|
-
async function updateUserLevel(ctx, user, level) {
|
|
423
|
-
if (!user)
|
|
424
|
-
return;
|
|
425
|
-
level = level < 5 ? level : 4;
|
|
426
|
-
await ctx.database.set("p_system", { userid: user.userid }, { userlevel: level });
|
|
427
|
-
}
|
|
428
|
-
__name(updateUserLevel, "updateUserLevel");
|
|
429
|
-
async function updateUserUsage(ctx, user, adjustment = 1) {
|
|
430
|
-
if (!user)
|
|
431
|
-
return;
|
|
432
|
-
if (user.lastChatTime && (/* @__PURE__ */ new Date()).getDate() !== user.lastChatTime)
|
|
433
|
-
user.usage = 0;
|
|
434
|
-
await ctx.database.set("p_system", { userid: user.userid }, { usage: user.usage + adjustment });
|
|
435
|
-
await ctx.database.set("p_system", { userid: user.userid }, { lastChatTime: (/* @__PURE__ */ new Date()).getDate() });
|
|
436
|
-
return user.usage + adjustment;
|
|
437
|
-
}
|
|
438
|
-
__name(updateUserUsage, "updateUserUsage");
|
|
439
|
-
async function updateUserItems(ctx, user) {
|
|
440
|
-
if (!user)
|
|
441
|
-
return;
|
|
442
|
-
await ctx.database.set("p_system", { userid: user.userid }, { items: user.items });
|
|
443
|
-
}
|
|
444
|
-
__name(updateUserItems, "updateUserItems");
|
|
445
|
-
async function getUser(ctx, userId) {
|
|
446
|
-
const users = await ctx.database.get("p_system", { userid: userId });
|
|
447
|
-
return users[0] || null;
|
|
448
|
-
}
|
|
449
|
-
__name(getUser, "getUser");
|
|
450
|
-
async function ensureUserExists(ctx, userId, username) {
|
|
451
|
-
const notExists = await isTargetIdNotExists(ctx, userId);
|
|
452
|
-
if (notExists) {
|
|
453
|
-
await createUser(ctx, {
|
|
454
|
-
userid: userId,
|
|
455
|
-
usersname: username,
|
|
456
|
-
p: 0,
|
|
457
|
-
favorability: 0,
|
|
458
|
-
userlevel: 0,
|
|
459
|
-
usage: 0,
|
|
460
|
-
lastChatTime: (/* @__PURE__ */ new Date()).getDate(),
|
|
461
|
-
items: {}
|
|
462
|
-
});
|
|
463
|
-
}
|
|
464
|
-
return getUser(ctx, userId);
|
|
465
|
-
}
|
|
466
|
-
__name(ensureUserExists, "ensureUserExists");
|
|
467
|
-
function extendDatabase(ctx) {
|
|
468
|
-
ctx.model.extend("p_system", {
|
|
469
|
-
id: "unsigned",
|
|
470
|
-
userid: "string",
|
|
471
|
-
usersname: "string",
|
|
472
|
-
p: "integer",
|
|
473
|
-
favorability: "integer",
|
|
474
|
-
userlevel: "integer",
|
|
475
|
-
usage: "integer",
|
|
476
|
-
lastChatTime: "integer",
|
|
477
|
-
items: "object"
|
|
478
|
-
}, { autoInc: true });
|
|
479
|
-
}
|
|
480
|
-
__name(extendDatabase, "extendDatabase");
|
|
481
|
-
|
|
482
|
-
// src/memory.ts
|
|
483
515
|
var logger3 = new import_koishi3.Logger("satori-memory");
|
|
484
516
|
var MemoryManager = class {
|
|
485
517
|
constructor(ctx, config) {
|
|
@@ -886,24 +918,25 @@ async function handleAuxiliaryResult(ctx, session, config, responseContent) {
|
|
|
886
918
|
return;
|
|
887
919
|
}
|
|
888
920
|
__name(handleAuxiliaryResult, "handleAuxiliaryResult");
|
|
889
|
-
async function inputContentCheck(ctx, content, userid, config, session) {
|
|
921
|
+
async function inputContentCheck(ctx, content, userid, config, session, moodManager) {
|
|
890
922
|
const user = await getUser(ctx, userid);
|
|
891
923
|
if (!user)
|
|
892
924
|
return 0;
|
|
893
925
|
const regex = /\*\*/g;
|
|
894
926
|
const hasCensor = regex.test(content);
|
|
895
927
|
if (hasCensor && config.input_censor_favorability) {
|
|
928
|
+
moodManager.handleInputMoodChange(user);
|
|
896
929
|
await applyFavorabilityEffect(ctx, user, -1 * config.value_of_input_favorability, session);
|
|
897
930
|
return -1 * config.value_of_input_favorability;
|
|
898
931
|
}
|
|
899
|
-
|
|
932
|
+
moodManager.applyMoodChange(user, 1);
|
|
933
|
+
if (config.enable_auxiliary_LLM || user.usage > config.max_favorability_perday)
|
|
900
934
|
return 0;
|
|
901
|
-
}
|
|
902
935
|
await applyFavorabilityEffect(ctx, user, 1, session);
|
|
903
936
|
return 1;
|
|
904
937
|
}
|
|
905
938
|
__name(inputContentCheck, "inputContentCheck");
|
|
906
|
-
async function outputContentCheck(ctx, response, userid, config, session) {
|
|
939
|
+
async function outputContentCheck(ctx, response, userid, config, session, moodManager) {
|
|
907
940
|
if (response.error)
|
|
908
941
|
return 0;
|
|
909
942
|
const user = await getUser(ctx, userid);
|
|
@@ -919,9 +952,18 @@ async function outputContentCheck(ctx, response, userid, config, session) {
|
|
|
919
952
|
const censoredContent = censorWords.reduce((acc, cur) => acc.replace(cur, "**"), content);
|
|
920
953
|
const regex = /\*\*/g;
|
|
921
954
|
const hasCensor = regex.test(censoredContent);
|
|
955
|
+
const moodLevel = moodManager.getMoodLevel(user.userid);
|
|
922
956
|
if (hasCensor) {
|
|
957
|
+
const mood = moodManager.getMoodValue(user.userid);
|
|
958
|
+
moodManager.handleOutputMoodChange(user);
|
|
959
|
+
if (mood <= 0) {
|
|
960
|
+
await applyFavorabilityEffect(ctx, user, -1 * config.value_of_output_favorability, session);
|
|
961
|
+
return -config.value_of_output_favorability;
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
if (moodLevel === "angry") {
|
|
923
965
|
await applyFavorabilityEffect(ctx, user, -1 * config.value_of_output_favorability, session);
|
|
924
|
-
return -
|
|
966
|
+
return -config.value_of_output_favorability;
|
|
925
967
|
}
|
|
926
968
|
}
|
|
927
969
|
return 0;
|
|
@@ -1031,27 +1073,34 @@ var Sat = class extends import_koishi5.Service {
|
|
|
1031
1073
|
((Sat2) => {
|
|
1032
1074
|
Sat2.Config = import_koishi5.Schema.intersect([
|
|
1033
1075
|
import_koishi5.Schema.object({
|
|
1034
|
-
baseURL: import_koishi5.Schema.string().default("https://api.deepseek.com").description("
|
|
1076
|
+
baseURL: import_koishi5.Schema.string().default("https://api.deepseek.com").description("深度思考模型请求地址"),
|
|
1035
1077
|
key: import_koishi5.Schema.union([
|
|
1036
1078
|
import_koishi5.Schema.array(String).role("secret"),
|
|
1037
1079
|
import_koishi5.Schema.transform(String, (value) => [value])
|
|
1038
|
-
]).default([]).role("secret").description("api_key"),
|
|
1039
|
-
appointModel: import_koishi5.Schema.string().default("deepseek-reasoner").description("
|
|
1080
|
+
]).default([]).role("secret").description("深度思考模型api_key"),
|
|
1081
|
+
appointModel: import_koishi5.Schema.string().default("deepseek-reasoner").description("深度思考模型"),
|
|
1082
|
+
not_reasoner_LLM_URL: import_koishi5.Schema.string().default("https://api.deepseek.com").description("非深度思考模型请求地址"),
|
|
1083
|
+
not_reasoner_LLM: import_koishi5.Schema.string().default("deepseek-chat").description("非深度思考模型(用于节省成本"),
|
|
1084
|
+
not_reasoner_LLM_key: import_koishi5.Schema.union([
|
|
1085
|
+
import_koishi5.Schema.array(String).role("secret"),
|
|
1086
|
+
import_koishi5.Schema.transform(String, (value) => [value])
|
|
1087
|
+
]).default([]).role("secret").description("非深度思考模型api_key"),
|
|
1088
|
+
use_not_reasoner_LLM_length: import_koishi5.Schema.number().default(8).description("触发使用非深度思考模型的字数(输入少于此字数时),如果你希望始终使用非深度思考模型进行对话,请将此值设置成一个较大的值,反之亦然"),
|
|
1089
|
+
enable_reasoner_like: import_koishi5.Schema.boolean().default(true).description("是否启用非深度思考模型模仿思维链(可以在节省成本的同时提高效果)"),
|
|
1040
1090
|
auxiliary_LLM_URL: import_koishi5.Schema.string().default("https://api.deepseek.com").description("辅助模型请求地址"),
|
|
1041
1091
|
auxiliary_LLM: import_koishi5.Schema.string().default("deepseek-chat").description("辅助模型(用于好感度调整等功能,如不需要可不填,建议使用低成本模型"),
|
|
1042
1092
|
auxiliary_LLM_key: import_koishi5.Schema.union([
|
|
1043
1093
|
import_koishi5.Schema.array(String).role("secret"),
|
|
1044
1094
|
import_koishi5.Schema.transform(String, (value) => [value])
|
|
1045
1095
|
]).default([]).role("secret").description("辅助模型api_key"),
|
|
1046
|
-
prompt: import_koishi5.Schema.string().role("textarea").description("人格设定")
|
|
1096
|
+
prompt: import_koishi5.Schema.string().role("textarea").description("人格设定"),
|
|
1097
|
+
reasoner_prompt: import_koishi5.Schema.string().role("textarea").description("思考提示词(对于深度思考模型和非深度思考模型模仿思维链时生效)").default("你在思考时应当逐步分析以下内容:1.当前对话的禁止事项;2.是否与群聊中其他人的发言有关联;3.是否与当前用户之前说的话有关联;4.对话的具体要求;5.用户的意图如何;6.最终的发言的主要内容。")
|
|
1047
1098
|
}).description("基础设置"),
|
|
1048
1099
|
import_koishi5.Schema.object({
|
|
1049
1100
|
alias: import_koishi5.Schema.array(String).default(["ai"]).description("触发命令;别名"),
|
|
1050
1101
|
authority: import_koishi5.Schema.number().role("slider").min(0).max(5).step(1).description("允许使用的最低权限").default(1),
|
|
1051
|
-
no_system_prompt: import_koishi5.Schema.boolean().default(false).description("是否将系统提示的system替换为user
|
|
1102
|
+
no_system_prompt: import_koishi5.Schema.boolean().default(false).description("是否将系统提示的system替换为user(用于具有思维链的模型)"),
|
|
1052
1103
|
max_tokens: import_koishi5.Schema.number().description("最大请求长度(字符数)").default(100),
|
|
1053
|
-
content_max_tokens: import_koishi5.Schema.number().description("最大回答长度(思维链+输出token)").default(4096),
|
|
1054
|
-
content_max_length: import_koishi5.Schema.number().description("最大回答长度(仅输出,字符数)").default(100),
|
|
1055
1104
|
message_max_length: import_koishi5.Schema.number().description("最大频道上下文长度(条数)").default(10),
|
|
1056
1105
|
temperature: import_koishi5.Schema.number().role("slider").min(0).max(2).step(0.01).default(0.5).description("温度"),
|
|
1057
1106
|
frequency_penalty: import_koishi5.Schema.number().default(0).description("频率惩罚"),
|
|
@@ -1080,7 +1129,7 @@ var Sat = class extends import_koishi5.Service {
|
|
|
1080
1129
|
import_koishi5.Schema.object({
|
|
1081
1130
|
max_usage: import_koishi5.Schema.tuple([Number, Number, Number, Number, Number]).default([40, 240, 3e3, 9999, 0]).description("每日最大使用次数(对应用户level0~level4)(0为不限制)"),
|
|
1082
1131
|
private: import_koishi5.Schema.boolean().default(false).description("开启后私聊AI可触发对话, 不需要使用指令"),
|
|
1083
|
-
nick_name: import_koishi5.Schema.boolean().default(true).description("
|
|
1132
|
+
nick_name: import_koishi5.Schema.boolean().default(true).description("是否使用昵称触发对话(发言中含有昵称时)(把qq号加入昵称可以被at和戳一戳触发)"),
|
|
1084
1133
|
nick_name_list: import_koishi5.Schema.array(String).default(["昵称1"]).description("昵称列表"),
|
|
1085
1134
|
nick_name_block_words: import_koishi5.Schema.array(String).default(["屏蔽词1"]).description("昵称屏蔽词(含有屏蔽词的消息不会触发昵称对话)"),
|
|
1086
1135
|
input_prompt: import_koishi5.Schema.string().role("textarea").default("(注意专注对话主题,遵守对话要求,不要复读)").description("每轮对话前的补充提示(可用于强调要求)不需要时可不填"),
|
|
@@ -1091,6 +1140,8 @@ var Sat = class extends import_koishi5.Service {
|
|
|
1091
1140
|
random_min_tokens: import_koishi5.Schema.number().default(20).description("随机触发对话的最小长度"),
|
|
1092
1141
|
randnum: import_koishi5.Schema.number().role("slider").min(0).max(1).step(0.01).default(0).description("在群聊中随机触发对话的概率,如需关闭可设置为 0"),
|
|
1093
1142
|
sentences_divide: import_koishi5.Schema.boolean().default(true).description("是否分句发送"),
|
|
1143
|
+
min_sentences_length: import_koishi5.Schema.number().default(10).description("每个分句的最小长度"),
|
|
1144
|
+
max_sentences_length: import_koishi5.Schema.number().default(20).description("每个分句的最大长度"),
|
|
1094
1145
|
time_interval: import_koishi5.Schema.number().default(1e3).description("每句话的时间间隔"),
|
|
1095
1146
|
reply_pointing: import_koishi5.Schema.boolean().default(true).description("是否在与多人同时对话时显示回复指向")
|
|
1096
1147
|
}).description("对话设置"),
|
|
@@ -1098,9 +1149,9 @@ var Sat = class extends import_koishi5.Service {
|
|
|
1098
1149
|
enable_favorability: import_koishi5.Schema.boolean().default(false).description("是否开启好感度系统(每次对话默认+1好感度)"),
|
|
1099
1150
|
max_favorability_perday: import_koishi5.Schema.number().default(100).description("每日有效(引发好感度增长)对话次数上限"),
|
|
1100
1151
|
input_censor_favorability: import_koishi5.Schema.boolean().default(false).description("是否开启好感度审查(通过输入屏蔽词扣除好感)"),
|
|
1101
|
-
value_of_input_favorability: import_koishi5.Schema.number().default(15).description("
|
|
1152
|
+
value_of_input_favorability: import_koishi5.Schema.number().default(15).description("输入触发输入屏蔽词每次扣除的好感度"),
|
|
1102
1153
|
output_censor_favorability: import_koishi5.Schema.boolean().default(false).description("通过输出屏蔽词扣除好感,在dataDir中的output_censor.txt修改)"),
|
|
1103
|
-
value_of_output_favorability: import_koishi5.Schema.number().default(15).description("
|
|
1154
|
+
value_of_output_favorability: import_koishi5.Schema.number().default(15).description("输出触发输出屏蔽词每次扣除的好感度"),
|
|
1104
1155
|
enable_auxiliary_LLM: import_koishi5.Schema.boolean().default(false).description("是否使用辅助大模型判断好感度增减(量与输入屏蔽词每次扣除的好感度相关,不稳定,慎用)"),
|
|
1105
1156
|
offset_of_fafavorability: import_koishi5.Schema.number().default(3.5).description("辅助大模型好感度偏移量(越大越容易扣好感度)"),
|
|
1106
1157
|
visible_favorability: import_koishi5.Schema.boolean().default(true).description("是否开启好感度升降显示"),
|
|
@@ -1118,6 +1169,22 @@ var Sat = class extends import_koishi5.Service {
|
|
|
1118
1169
|
favorability_div_4: import_koishi5.Schema.number().default(1e3).description("思慕-恋慕分界线"),
|
|
1119
1170
|
prompt_4: import_koishi5.Schema.string().role("textarea").description("恋慕好感补充设定")
|
|
1120
1171
|
}).description("好感度设置"),
|
|
1172
|
+
import_koishi5.Schema.object({
|
|
1173
|
+
enable_mood: import_koishi5.Schema.boolean().default(false).description("是否开启心情系统(通过屏蔽词降低心情,正常聊天心情+1,每天重置为mood_div_1 + value_of_output_mood)"),
|
|
1174
|
+
max_mood: import_koishi5.Schema.number().default(5).description("心情上限"),
|
|
1175
|
+
value_of_input_mood: import_koishi5.Schema.number().default(6).description("输入触发屏蔽词每次扣除的心情"),
|
|
1176
|
+
value_of_output_mood: import_koishi5.Schema.number().default(3).description("输出触发屏蔽词每次扣除的心情,若当时心情大于0,此次不扣好感度"),
|
|
1177
|
+
visible_mood: import_koishi5.Schema.boolean().default(false).description("是否开启心情状态显示"),
|
|
1178
|
+
mood_prompt_2: import_koishi5.Schema.string().role("textarea").default("你现在的心情十分愉悦").description("心情达到最高补充设定"),
|
|
1179
|
+
mood_div_1: import_koishi5.Schema.number().default(-1).description("心情正常-烦躁分界线"),
|
|
1180
|
+
mood_prompt_0: import_koishi5.Schema.string().role("textarea").default("你现在的心情是:有点烦躁").description("烦躁心情补充设定"),
|
|
1181
|
+
mood_div_2: import_koishi5.Schema.number().default(-5).description("烦躁-生气分界线"),
|
|
1182
|
+
mood_prompt_1: import_koishi5.Schema.string().role("textarea").default("你现在的心情是:非常生气").description("生气心情补充设定"),
|
|
1183
|
+
enable_pocket_money: import_koishi5.Schema.boolean().default(false).description("开启要零花钱指令(通过消耗心情换随机数量p点)"),
|
|
1184
|
+
min_pocket_money: import_koishi5.Schema.number().default(100).description("随机p点最小值"),
|
|
1185
|
+
max_pocket_money: import_koishi5.Schema.number().default(400).description("随机p点最大值"),
|
|
1186
|
+
pocket_money_cost: import_koishi5.Schema.number().default(2).description("消耗心情换p点的心情值")
|
|
1187
|
+
}).description("好感度拓展:心情设置(需要开启好感度模块才能生效)"),
|
|
1121
1188
|
import_koishi5.Schema.object({
|
|
1122
1189
|
enable_game: import_koishi5.Schema.boolean().default(false).description("是否开启游戏模块"),
|
|
1123
1190
|
enable_gobang: import_koishi5.Schema.boolean().default(false).description("是否开启五子棋游戏")
|
|
@@ -1204,8 +1271,8 @@ ${history}
|
|
|
1204
1271
|
|
|
1205
1272
|
注意事项:
|
|
1206
1273
|
·用户一定是人类,其他情况是角色扮演
|
|
1207
|
-
|
|
1208
|
-
|
|
1274
|
+
·若有历史画像则需要根据发言修正历史画像内容,以发言为准,但是历史画像中不需要修改的部分必须保留
|
|
1275
|
+
·除非用户要求,否则不要改动基本信息中的内容
|
|
1209
1276
|
·及时删除历史画像中明确错误或多余的信息
|
|
1210
1277
|
·尤其注意用户说“记住”的部分,可能是用户希望记录的信息
|
|
1211
1278
|
·历史画像中的需要短期记忆的信息不需要保留,只需要删除旧的添加新的
|
|
@@ -1298,8 +1365,165 @@ ${portrait}
|
|
|
1298
1365
|
}
|
|
1299
1366
|
};
|
|
1300
1367
|
|
|
1368
|
+
// src/mood.ts
|
|
1369
|
+
var import_koishi7 = require("koishi");
|
|
1370
|
+
var import_crypto = require("crypto");
|
|
1371
|
+
var logger6 = new import_koishi7.Logger("satori-ai-mood");
|
|
1372
|
+
var MoodManager = class {
|
|
1373
|
+
static {
|
|
1374
|
+
__name(this, "MoodManager");
|
|
1375
|
+
}
|
|
1376
|
+
ctx;
|
|
1377
|
+
config;
|
|
1378
|
+
moodMap = /* @__PURE__ */ new Map();
|
|
1379
|
+
constructor(ctx, config) {
|
|
1380
|
+
this.ctx = ctx;
|
|
1381
|
+
this.config = config;
|
|
1382
|
+
}
|
|
1383
|
+
// 初始化用户心情
|
|
1384
|
+
initUser(userId) {
|
|
1385
|
+
this.moodMap.set(userId, {
|
|
1386
|
+
mood: this.config.mood_div_1 + this.config.value_of_output_mood,
|
|
1387
|
+
lastUpdate: Date.now()
|
|
1388
|
+
});
|
|
1389
|
+
}
|
|
1390
|
+
// 每日重置检查
|
|
1391
|
+
checkDailyReset(userId) {
|
|
1392
|
+
const data = this.moodMap.get(userId);
|
|
1393
|
+
if (!data)
|
|
1394
|
+
return;
|
|
1395
|
+
const lastDate = new Date(data.lastUpdate);
|
|
1396
|
+
const now = /* @__PURE__ */ new Date();
|
|
1397
|
+
if (lastDate.getDate() !== now.getDate() || lastDate.getMonth() !== now.getMonth() || lastDate.getFullYear() !== now.getFullYear()) {
|
|
1398
|
+
this.moodMap.set(userId, { mood: 0, lastUpdate: Date.now() });
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
// 处理输入内容心情变化
|
|
1402
|
+
async handleInputMoodChange(user) {
|
|
1403
|
+
if (!this.config.enable_mood)
|
|
1404
|
+
return;
|
|
1405
|
+
const userId = user.userid;
|
|
1406
|
+
if (!this.moodMap.has(userId))
|
|
1407
|
+
this.initUser(userId);
|
|
1408
|
+
this.checkDailyReset(userId);
|
|
1409
|
+
this.applyMoodChange(user, -this.config.value_of_input_mood);
|
|
1410
|
+
return;
|
|
1411
|
+
}
|
|
1412
|
+
// 处理输出内容心情变化
|
|
1413
|
+
async handleOutputMoodChange(user) {
|
|
1414
|
+
if (!this.config.enable_mood)
|
|
1415
|
+
return;
|
|
1416
|
+
const userId = user.userid;
|
|
1417
|
+
if (!this.moodMap.has(userId))
|
|
1418
|
+
this.initUser(userId);
|
|
1419
|
+
this.checkDailyReset(userId);
|
|
1420
|
+
this.applyMoodChange(user, -this.config.value_of_output_mood);
|
|
1421
|
+
return;
|
|
1422
|
+
}
|
|
1423
|
+
// 应用心情变化
|
|
1424
|
+
applyMoodChange(user, delta) {
|
|
1425
|
+
if (!this.config.enable_mood)
|
|
1426
|
+
return;
|
|
1427
|
+
const userId = user.userid;
|
|
1428
|
+
let data = this.moodMap.get(userId);
|
|
1429
|
+
if (!data) {
|
|
1430
|
+
this.initUser(userId);
|
|
1431
|
+
data = this.moodMap.get(userId);
|
|
1432
|
+
}
|
|
1433
|
+
const newMood = Math.min(this.config.max_mood, data.mood + delta);
|
|
1434
|
+
this.moodMap.set(userId, {
|
|
1435
|
+
mood: newMood,
|
|
1436
|
+
lastUpdate: Date.now()
|
|
1437
|
+
});
|
|
1438
|
+
return;
|
|
1439
|
+
}
|
|
1440
|
+
// 获取心情等级
|
|
1441
|
+
getMoodLevel(userId) {
|
|
1442
|
+
if (!this.config.enable_mood)
|
|
1443
|
+
return "normal";
|
|
1444
|
+
const data = this.moodMap.get(userId);
|
|
1445
|
+
if (!data) {
|
|
1446
|
+
this.initUser(userId);
|
|
1447
|
+
return "normal";
|
|
1448
|
+
}
|
|
1449
|
+
if (data.mood == this.config.max_mood)
|
|
1450
|
+
return "happy";
|
|
1451
|
+
if (data.mood <= this.config.mood_div_2)
|
|
1452
|
+
return "angry";
|
|
1453
|
+
if (data.mood <= this.config.mood_div_1)
|
|
1454
|
+
return "upset";
|
|
1455
|
+
return "normal";
|
|
1456
|
+
}
|
|
1457
|
+
// 获取心情值
|
|
1458
|
+
getMoodValue(userId) {
|
|
1459
|
+
if (!this.config.enable_mood)
|
|
1460
|
+
return 0;
|
|
1461
|
+
const data = this.moodMap.get(userId);
|
|
1462
|
+
if (!data) {
|
|
1463
|
+
this.initUser(userId);
|
|
1464
|
+
return 0;
|
|
1465
|
+
}
|
|
1466
|
+
return data.mood;
|
|
1467
|
+
}
|
|
1468
|
+
// 生成心情提示
|
|
1469
|
+
generateMoodPrompt(userId) {
|
|
1470
|
+
const level = this.getMoodLevel(userId);
|
|
1471
|
+
return {
|
|
1472
|
+
"upset": `
|
|
1473
|
+
${this.config.mood_prompt_0}
|
|
1474
|
+
`,
|
|
1475
|
+
"angry": `
|
|
1476
|
+
${this.config.mood_prompt_1}
|
|
1477
|
+
`,
|
|
1478
|
+
"happy": `
|
|
1479
|
+
${this.config.mood_prompt_2}
|
|
1480
|
+
`,
|
|
1481
|
+
"normal": "你现在的心情很平淡"
|
|
1482
|
+
}[level];
|
|
1483
|
+
}
|
|
1484
|
+
async handlePocketMoney(session) {
|
|
1485
|
+
const user = await ensureUserExists(this.ctx, session.userId, session.username);
|
|
1486
|
+
const mood = this.getMoodValue(user.userid);
|
|
1487
|
+
if (mood < this.config.max_mood / 2) {
|
|
1488
|
+
updateFavorability(this.ctx, user, -this.config.value_of_output_favorability);
|
|
1489
|
+
return session.text("commands.sat.messages.not_good_mood");
|
|
1490
|
+
}
|
|
1491
|
+
this.applyMoodChange(user, -this.config.pocket_money_cost);
|
|
1492
|
+
const pocketMoney = (0, import_crypto.randomInt)(this.config.min_pocket_money, this.config.max_pocket_money + 1);
|
|
1493
|
+
updateUserP(this.ctx, user, pocketMoney);
|
|
1494
|
+
return session.text("commands.sat.messages.pocket_money", [pocketMoney]);
|
|
1495
|
+
}
|
|
1496
|
+
setMood(id, mood) {
|
|
1497
|
+
this.moodMap.set(id, {
|
|
1498
|
+
mood: Math.min(this.config.max_mood, mood),
|
|
1499
|
+
lastUpdate: Date.now()
|
|
1500
|
+
});
|
|
1501
|
+
return "已设置" + id + "心情值为" + mood;
|
|
1502
|
+
}
|
|
1503
|
+
viewMood(session, id) {
|
|
1504
|
+
if (!this.config.enable_mood)
|
|
1505
|
+
return "normal";
|
|
1506
|
+
const level = this.getMoodLevel(id);
|
|
1507
|
+
if (id === session.userId) {
|
|
1508
|
+
switch (level) {
|
|
1509
|
+
case "upset":
|
|
1510
|
+
return `!`;
|
|
1511
|
+
case "angry":
|
|
1512
|
+
return `滚`;
|
|
1513
|
+
case "happy":
|
|
1514
|
+
return `♥`;
|
|
1515
|
+
case "normal":
|
|
1516
|
+
return `~`;
|
|
1517
|
+
default:
|
|
1518
|
+
return `你的心情等级为 ${level}`;
|
|
1519
|
+
}
|
|
1520
|
+
} else
|
|
1521
|
+
return `用户 ${id} 的心情等级为 ${level}`;
|
|
1522
|
+
}
|
|
1523
|
+
};
|
|
1524
|
+
|
|
1301
1525
|
// src/index.tsx
|
|
1302
|
-
var
|
|
1526
|
+
var logger7 = new import_koishi8.Logger("satori-ai");
|
|
1303
1527
|
var SAT = class extends Sat {
|
|
1304
1528
|
// 重写构造函数
|
|
1305
1529
|
constructor(ctx, config) {
|
|
@@ -1310,6 +1534,7 @@ var SAT = class extends Sat {
|
|
|
1310
1534
|
this.apiClient = new APIClient(ctx, this.getAPIConfig());
|
|
1311
1535
|
this.memoryManager = new MemoryManager(ctx, this.getMemoryConfig());
|
|
1312
1536
|
this.portraitManager = new UserPortraitManager(ctx, config);
|
|
1537
|
+
this.moodManager = new MoodManager(ctx, config);
|
|
1313
1538
|
ensureCensorFileExists(this.config.dataDir);
|
|
1314
1539
|
ctx.middleware(createMiddleware(ctx, this, this.getMiddlewareConfig()));
|
|
1315
1540
|
this.registerCommands(ctx);
|
|
@@ -1322,17 +1547,20 @@ var SAT = class extends Sat {
|
|
|
1322
1547
|
portraitManager;
|
|
1323
1548
|
ChannelParallelCount = /* @__PURE__ */ new Map();
|
|
1324
1549
|
onlineUsers = [];
|
|
1550
|
+
moodManager;
|
|
1325
1551
|
game;
|
|
1326
1552
|
getAPIConfig() {
|
|
1327
1553
|
return {
|
|
1328
1554
|
baseURL: this.config.baseURL,
|
|
1329
1555
|
keys: this.config.key,
|
|
1330
1556
|
appointModel: this.config.appointModel,
|
|
1557
|
+
not_reasoner_LLM_URL: this.config.not_reasoner_LLM_URL,
|
|
1558
|
+
not_reasoner_LLM: this.config.not_reasoner_LLM,
|
|
1559
|
+
not_reasoner_LLM_key: this.config.not_reasoner_LLM_key,
|
|
1560
|
+
use_not_reasoner_LLM_length: this.config.use_not_reasoner_LLM_length,
|
|
1331
1561
|
auxiliary_LLM_URL: this.config.auxiliary_LLM_URL,
|
|
1332
1562
|
auxiliary_LLM: this.config.auxiliary_LLM,
|
|
1333
1563
|
auxiliary_LLM_key: this.config.auxiliary_LLM_key,
|
|
1334
|
-
content_max_tokens: this.config.content_max_tokens,
|
|
1335
|
-
content_max_length: this.config.content_max_length,
|
|
1336
1564
|
maxRetryTimes: this.config.maxRetryTimes,
|
|
1337
1565
|
retry_delay_time: this.config.retry_delay_time,
|
|
1338
1566
|
temperature: this.config.temperature,
|
|
@@ -1416,6 +1644,11 @@ var SAT = class extends Sat {
|
|
|
1416
1644
|
ctx.command("sat.user_usage", "查看用户使用次数").alias("查询次数").action(async ({ session }) => this.handleUserUsage(session));
|
|
1417
1645
|
ctx.command("sat.add_output_censor <text:text>", "添加输出敏感词", { authority: 4 }).alias("添加输出屏蔽词").action(async ({ session }, word) => addOutputCensor(session, word, this.config.dataDir));
|
|
1418
1646
|
ctx.command("sat.get_user_portrait <text:text>", "查看用户画像", { authority: 4 }).alias("查看画像").action(async ({}, userId) => this.portraitManager.getUserPortraitById(userId));
|
|
1647
|
+
if (this.config.enable_mood && this.config.enable_favorability && this.config.enable_pocket_money) {
|
|
1648
|
+
ctx.command("sat.pocket_money", "消耗心情值换取p点").alias("要零花钱").action(async ({ session }) => this.moodManager.handlePocketMoney(session));
|
|
1649
|
+
ctx.command("sat.set_mood", "设置心情值", { authority: 4 }).alias("设置心情").option("id", "-i <id:string>", { authority: 4 }).option("value", "-v <value:number>", { authority: 4 }).action(async ({ session, options }) => this.moodManager.setMood(options.id || session.userId, options.value || 0));
|
|
1650
|
+
ctx.command("sat.get_mood", "查看心情状态").alias("查看心情").option("id", "-i <id:string>", { authority: 4 }).action(async ({ session, options }) => this.moodManager.viewMood(session, options.id || session.userId));
|
|
1651
|
+
}
|
|
1419
1652
|
}
|
|
1420
1653
|
async handleSatCommand(session, prompt) {
|
|
1421
1654
|
const user = await ensureUserExists(this.ctx, session.userId, session.username);
|
|
@@ -1441,16 +1674,18 @@ var SAT = class extends Sat {
|
|
|
1441
1674
|
const response = await this.generateResponse(session, processedPrompt);
|
|
1442
1675
|
const auxiliaryResult = await this.handleAuxiliaryDialogue(session, processedPrompt, response);
|
|
1443
1676
|
await this.memoryManager.updateMemories(session, processedPrompt, this.getMemoryConfig(), response);
|
|
1677
|
+
if (!response.error)
|
|
1678
|
+
await updateUserPWithTicket(this.ctx, user, 10);
|
|
1444
1679
|
if (user.usage == this.config.portrait_usage - 1)
|
|
1445
1680
|
this.portraitManager.generatePortrait(session, user, this.apiClient);
|
|
1446
1681
|
return await this.formatResponse(session, response.content, auxiliaryResult);
|
|
1447
1682
|
}
|
|
1448
1683
|
// 处理辅助判断
|
|
1449
1684
|
async handleAuxiliaryDialogue(session, prompt, response) {
|
|
1450
|
-
if (response.error)
|
|
1685
|
+
if (response.error || !this.config.enable_favorability)
|
|
1451
1686
|
return null;
|
|
1452
1687
|
const user = await getUser(this.ctx, session.userId);
|
|
1453
|
-
const outputCheck = await outputContentCheck(this.ctx, response, session.userId, this.getFavorabilityConfig(), session);
|
|
1688
|
+
const outputCheck = await outputContentCheck(this.ctx, response, session.userId, this.getFavorabilityConfig(), session, this.moodManager);
|
|
1454
1689
|
const regex = /\*\*/g;
|
|
1455
1690
|
const inputCensor = prompt.match(regex)?.length;
|
|
1456
1691
|
const outputCensor = outputCheck < 0;
|
|
@@ -1462,9 +1697,9 @@ var SAT = class extends Sat {
|
|
|
1462
1697
|
const messages = generateAuxiliaryPrompt(prompt, response.content, user, this.getFavorabilityConfig());
|
|
1463
1698
|
const result = await this.apiClient.auxiliaryChat(messages);
|
|
1464
1699
|
if (result.error) {
|
|
1465
|
-
|
|
1700
|
+
logger7.error(`辅助判断失败:${result.content}`);
|
|
1466
1701
|
} else {
|
|
1467
|
-
|
|
1702
|
+
logger7.info(`辅助判断:${result.content}`);
|
|
1468
1703
|
return handleAuxiliaryResult(this.ctx, session, this.getFavorabilityConfig(), result.content);
|
|
1469
1704
|
}
|
|
1470
1705
|
}
|
|
@@ -1496,7 +1731,7 @@ var SAT = class extends Sat {
|
|
|
1496
1731
|
if (!duplicateDialogue)
|
|
1497
1732
|
return null;
|
|
1498
1733
|
if (this.config.enable_favorability) {
|
|
1499
|
-
updateFavorability(this.ctx, user, -
|
|
1734
|
+
updateFavorability(this.ctx, user, -5);
|
|
1500
1735
|
return session.text("commands.sat.messages.duplicate-dialogue") + " (好感↓)";
|
|
1501
1736
|
}
|
|
1502
1737
|
return session.text("commands.sat.messages.duplicate-dialogue");
|
|
@@ -1548,30 +1783,43 @@ var SAT = class extends Sat {
|
|
|
1548
1783
|
censored = await this.ctx.censor.transform(processedPrompt, session);
|
|
1549
1784
|
}
|
|
1550
1785
|
if (this.config.enable_favorability) {
|
|
1551
|
-
await inputContentCheck(this.ctx, censored, session.userId, this.getFavorabilityConfig(), session);
|
|
1786
|
+
await inputContentCheck(this.ctx, censored, session.userId, this.getFavorabilityConfig(), session, this.moodManager);
|
|
1552
1787
|
}
|
|
1553
1788
|
if (this.config.log_ask_response)
|
|
1554
|
-
|
|
1789
|
+
logger7.info(`用户 ${session.username}:${processedPrompt}`);
|
|
1555
1790
|
return censored;
|
|
1556
1791
|
}
|
|
1557
1792
|
// 生成回复
|
|
1558
1793
|
async generateResponse(session, prompt) {
|
|
1559
1794
|
if (this.getChannelParallelCount(session) > this.config.max_parallel_count) {
|
|
1560
|
-
|
|
1795
|
+
logger7.info(`频道 ${session.channelId} 并发数过高(${this.getChannelParallelCount(session)}),${session.username}等待中...`);
|
|
1561
1796
|
}
|
|
1562
1797
|
while (this.getChannelParallelCount(session) > this.config.max_parallel_count) {
|
|
1563
1798
|
this.updateChannelParallelCount(session, -1);
|
|
1564
1799
|
await new Promise((resolve2) => setTimeout(resolve2, 1e3));
|
|
1565
1800
|
this.updateChannelParallelCount(session, 1);
|
|
1566
1801
|
}
|
|
1567
|
-
const messages = this.buildMessages(session, prompt);
|
|
1568
|
-
|
|
1802
|
+
const messages = await this.buildMessages(session, prompt);
|
|
1803
|
+
logger7.info(`频道 ${session.channelId} 处理:${session.userId},剩余${this.getChannelParallelCount(session)}并发`);
|
|
1569
1804
|
const user = await getUser(this.ctx, session.userId);
|
|
1570
|
-
let response = await this.
|
|
1571
|
-
if (
|
|
1572
|
-
|
|
1805
|
+
let response = await this.getChatResponse(user, messages);
|
|
1806
|
+
if (response.error)
|
|
1807
|
+
response = await this.getChatResponse(user, messages);
|
|
1808
|
+
if (response.error)
|
|
1809
|
+
updateUserUsage(this.ctx, user, -1);
|
|
1810
|
+
return response;
|
|
1811
|
+
}
|
|
1812
|
+
// 获取聊天回复
|
|
1813
|
+
async getChatResponse(user, messages) {
|
|
1814
|
+
let response = await this.apiClient.chat(user, messages);
|
|
1815
|
+
if (this.config.log_ask_response) {
|
|
1816
|
+
if (this.config.enable_favorability && this.config.enable_mood)
|
|
1817
|
+
logger7.info(`Satori AI:(心情值:${this.moodManager.getMoodValue(user.userid)})${response.content}`);
|
|
1818
|
+
else
|
|
1819
|
+
logger7.info(`Satori AI:${response.content}`);
|
|
1820
|
+
}
|
|
1573
1821
|
if (this.config.reasoner_filter)
|
|
1574
|
-
response
|
|
1822
|
+
response = filterResponse(response.content, this.config.reasoner_filter_word.split("-"));
|
|
1575
1823
|
return response;
|
|
1576
1824
|
}
|
|
1577
1825
|
// 构建消息
|
|
@@ -1592,7 +1840,7 @@ var SAT = class extends Sat {
|
|
|
1592
1840
|
messages.push({ role: "user", content: prompt });
|
|
1593
1841
|
let payload = messages.map((msg) => msg.role + ":" + msg.content).join("\n");
|
|
1594
1842
|
if (this.config.log_system_prompt)
|
|
1595
|
-
|
|
1843
|
+
logger7.info(`系统提示:
|
|
1596
1844
|
${payload}`);
|
|
1597
1845
|
return messages;
|
|
1598
1846
|
}
|
|
@@ -1603,6 +1851,7 @@ ${payload}`);
|
|
|
1603
1851
|
const channelDialogue = await this.memoryManager.getChannelDialogue(session);
|
|
1604
1852
|
const userMemory = await this.memoryManager.searchMemories(session, prompt);
|
|
1605
1853
|
const user = await getUser(this.ctx, session.userId);
|
|
1854
|
+
systemPrompt += this.getThinkingPrompt(user, prompt);
|
|
1606
1855
|
if (user?.items?.["觉的衣柜"]?.count) {
|
|
1607
1856
|
const clothes = user?.items?.["觉的衣柜"]?.metadata?.clothes;
|
|
1608
1857
|
if (clothes)
|
|
@@ -1614,17 +1863,47 @@ ${payload}`);
|
|
|
1614
1863
|
systemPrompt += channelDialogue;
|
|
1615
1864
|
systemPrompt += userMemory;
|
|
1616
1865
|
systemPrompt += this.portraitManager.getUserPortrait(session);
|
|
1617
|
-
const nickName = user.items["情侣合照"]?.metadata?.userNickName;
|
|
1618
1866
|
systemPrompt += `用户的名字是:${session.username}, id是:${session.userId}`;
|
|
1867
|
+
const nickName = user.items["情侣合照"]?.metadata?.userNickName;
|
|
1619
1868
|
if (nickName)
|
|
1620
1869
|
systemPrompt += `, 昵称是:${nickName},称呼用户时请优先使用昵称`;
|
|
1621
1870
|
if (this.config.enable_favorability) {
|
|
1622
|
-
|
|
1871
|
+
const favorabilityLevel = getFavorabilityLevel(user, this.getFavorabilityConfig());
|
|
1872
|
+
if (this.config.enable_mood) {
|
|
1873
|
+
const moodLevel = this.moodManager.getMoodLevel(user.userid);
|
|
1874
|
+
if (moodLevel == "normal" || favorabilityLevel == "厌恶")
|
|
1875
|
+
systemPrompt += generateLevelPrompt(favorabilityLevel, this.getFavorabilityConfig(), user);
|
|
1876
|
+
const moodPrompt = this.moodManager.generateMoodPrompt(user.userid);
|
|
1877
|
+
systemPrompt += `
|
|
1878
|
+
${moodPrompt}
|
|
1879
|
+
`;
|
|
1880
|
+
} else {
|
|
1881
|
+
systemPrompt += generateLevelPrompt(favorabilityLevel, this.getFavorabilityConfig(), user);
|
|
1882
|
+
}
|
|
1623
1883
|
}
|
|
1624
1884
|
if (this.config.no_system_prompt)
|
|
1625
1885
|
systemPrompt += "如果你明白以上内容,请回复“已明确对话要求”";
|
|
1626
1886
|
return systemPrompt;
|
|
1627
1887
|
}
|
|
1888
|
+
// 思考提示
|
|
1889
|
+
getThinkingPrompt(user, prompt) {
|
|
1890
|
+
const reasonerPrompt = this.config.reasoner_prompt;
|
|
1891
|
+
const promptForNoReasoner = `请你在回复时先进行分析思考并输出思考内容,所有思考内容必须使用<think>和</think>包裹输出,而后在最后输出正式的回复内容。${reasonerPrompt}
|
|
1892
|
+
`;
|
|
1893
|
+
const promptForReasoner = `你必须将所有思考内容使用<think>和</think>标签包裹并输出在思维链中,注意不要在最终的输出内包含思考内容。${reasonerPrompt}
|
|
1894
|
+
`;
|
|
1895
|
+
const hasTicket = user?.items?.["地灵殿通行证"]?.description && user.items["地灵殿通行证"].description === "on";
|
|
1896
|
+
const maxLength = hasTicket ? user?.items?.["地灵殿通行证"]?.metadata?.use_not_reasoner_LLM_length : this.config.use_not_reasoner_LLM_length;
|
|
1897
|
+
const useNoReasoner = prompt.length <= maxLength;
|
|
1898
|
+
if (!this.config.enable_reasoner_like && useNoReasoner)
|
|
1899
|
+
return "";
|
|
1900
|
+
const reasonerText = `
|
|
1901
|
+
以下是你的【思考要求】:{
|
|
1902
|
+
${useNoReasoner ? promptForNoReasoner : promptForReasoner}
|
|
1903
|
+
}
|
|
1904
|
+
`;
|
|
1905
|
+
return reasonerText;
|
|
1906
|
+
}
|
|
1628
1907
|
// 处理回复
|
|
1629
1908
|
async formatResponse(session, response, auxiliaryResult) {
|
|
1630
1909
|
const user = await getUser(this.ctx, session.userId);
|
|
@@ -1640,13 +1919,20 @@ ${payload}`);
|
|
|
1640
1919
|
response += " 喵~";
|
|
1641
1920
|
if (fumo)
|
|
1642
1921
|
response += "\nfumofumo";
|
|
1922
|
+
if (this.config.enable_mood && this.config.enable_favorability && this.config.visible_mood) {
|
|
1923
|
+
const moodLevel = this.moodManager.getMoodLevel(user.userid);
|
|
1924
|
+
if (moodLevel == "angry")
|
|
1925
|
+
response += "(怒)";
|
|
1926
|
+
if (moodLevel == "upset")
|
|
1927
|
+
response += "(烦躁)";
|
|
1928
|
+
}
|
|
1643
1929
|
if (auxiliaryResult && this.config.visible_favorability && !ring)
|
|
1644
1930
|
response += auxiliaryResult;
|
|
1645
1931
|
if (replyPointing) {
|
|
1646
1932
|
response = `@${session.username} ` + response;
|
|
1647
1933
|
}
|
|
1648
1934
|
if (this.config.sentences_divide && response.length > 10) {
|
|
1649
|
-
const sentences = splitSentences(response).map((text) =>
|
|
1935
|
+
const sentences = splitSentences(response, this.config.min_sentences_length, this.config.max_sentences_length).map((text) => import_koishi8.h.text(text));
|
|
1650
1936
|
for (const sentence of sentences) {
|
|
1651
1937
|
await session.send(sentence);
|
|
1652
1938
|
await new Promise((resolve2) => setTimeout(resolve2, this.config.time_interval));
|
|
@@ -1728,9 +2014,6 @@ ${payload}`);
|
|
|
1728
2014
|
// 昵称中间件转接
|
|
1729
2015
|
async handleNickNameMiddleware(session, prompt) {
|
|
1730
2016
|
const user = await getUser(this.ctx, session.userId);
|
|
1731
|
-
const processedPrompt = processPrompt(session.content);
|
|
1732
|
-
if (this.performPreChecks(session, processedPrompt))
|
|
1733
|
-
return null;
|
|
1734
2017
|
if (await this.checkUserDialogueCount(session, user, 0))
|
|
1735
2018
|
return null;
|
|
1736
2019
|
if (await this.checkFavorabilityBlock(session))
|
package/lib/mood.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Context, Session } from 'koishi';
|
|
2
|
+
import { User, Sat } from './types';
|
|
3
|
+
export declare class MoodManager {
|
|
4
|
+
private ctx;
|
|
5
|
+
private config;
|
|
6
|
+
private moodMap;
|
|
7
|
+
constructor(ctx: Context, config: Sat.Config);
|
|
8
|
+
private initUser;
|
|
9
|
+
private checkDailyReset;
|
|
10
|
+
handleInputMoodChange(user: User): Promise<void>;
|
|
11
|
+
handleOutputMoodChange(user: User): Promise<void>;
|
|
12
|
+
applyMoodChange(user: User, delta: number): void;
|
|
13
|
+
getMoodLevel(userId: string): string;
|
|
14
|
+
getMoodValue(userId: string): number;
|
|
15
|
+
generateMoodPrompt(userId: string): string;
|
|
16
|
+
handlePocketMoney(session: Session): Promise<string>;
|
|
17
|
+
setMood(id: string, mood: number): string;
|
|
18
|
+
viewMood(session: Session, id: string): string;
|
|
19
|
+
}
|
package/lib/types.d.ts
CHANGED
|
@@ -87,11 +87,13 @@ export interface APIConfig {
|
|
|
87
87
|
baseURL: string;
|
|
88
88
|
keys: string[];
|
|
89
89
|
appointModel: string;
|
|
90
|
+
not_reasoner_LLM_URL: string;
|
|
91
|
+
not_reasoner_LLM: string;
|
|
92
|
+
not_reasoner_LLM_key: string[];
|
|
93
|
+
use_not_reasoner_LLM_length: number;
|
|
90
94
|
auxiliary_LLM_URL: string;
|
|
91
95
|
auxiliary_LLM: string;
|
|
92
96
|
auxiliary_LLM_key: string[];
|
|
93
|
-
content_max_tokens: number;
|
|
94
|
-
content_max_length: number;
|
|
95
97
|
temperature: number;
|
|
96
98
|
frequency_penalty: number;
|
|
97
99
|
presence_penalty: number;
|
|
@@ -143,14 +145,17 @@ export declare namespace Sat {
|
|
|
143
145
|
baseURL: string;
|
|
144
146
|
key: string[];
|
|
145
147
|
appointModel: string;
|
|
148
|
+
not_reasoner_LLM_URL: string;
|
|
149
|
+
not_reasoner_LLM: string;
|
|
150
|
+
not_reasoner_LLM_key: string[];
|
|
151
|
+
use_not_reasoner_LLM_length: number;
|
|
146
152
|
auxiliary_LLM_URL: string;
|
|
147
153
|
auxiliary_LLM: string;
|
|
148
154
|
auxiliary_LLM_key: string[];
|
|
149
155
|
prompt: string;
|
|
156
|
+
reasoner_prompt: string;
|
|
150
157
|
no_system_prompt: boolean;
|
|
151
158
|
max_tokens: number;
|
|
152
|
-
content_max_tokens: number;
|
|
153
|
-
content_max_length: number;
|
|
154
159
|
message_max_length: number;
|
|
155
160
|
remember_min_length: number;
|
|
156
161
|
temperature: number;
|
|
@@ -172,6 +177,7 @@ export declare namespace Sat {
|
|
|
172
177
|
common_topN: number;
|
|
173
178
|
dailogues_topN: number;
|
|
174
179
|
enable_fixed_dialogues: boolean;
|
|
180
|
+
enable_reasoner_like: boolean;
|
|
175
181
|
max_usage: number[];
|
|
176
182
|
private: boolean;
|
|
177
183
|
nick_name: boolean;
|
|
@@ -185,9 +191,25 @@ export declare namespace Sat {
|
|
|
185
191
|
random_min_tokens: number;
|
|
186
192
|
randnum: number;
|
|
187
193
|
sentences_divide: boolean;
|
|
194
|
+
min_sentences_length: number;
|
|
195
|
+
max_sentences_length: number;
|
|
188
196
|
time_interval: number;
|
|
189
197
|
max_parallel_count: number;
|
|
190
198
|
reply_pointing: boolean;
|
|
199
|
+
enable_mood: boolean;
|
|
200
|
+
max_mood: number;
|
|
201
|
+
value_of_input_mood: number;
|
|
202
|
+
value_of_output_mood: number;
|
|
203
|
+
visible_mood: boolean;
|
|
204
|
+
mood_div_1: number;
|
|
205
|
+
mood_prompt_0: string;
|
|
206
|
+
mood_div_2: number;
|
|
207
|
+
mood_prompt_1: string;
|
|
208
|
+
mood_prompt_2: string;
|
|
209
|
+
enable_pocket_money: boolean;
|
|
210
|
+
min_pocket_money: number;
|
|
211
|
+
max_pocket_money: number;
|
|
212
|
+
pocket_money_cost: number;
|
|
191
213
|
enable_favorability: boolean;
|
|
192
214
|
max_favorability_perday: number;
|
|
193
215
|
input_censor_favorability: boolean;
|
package/lib/utils.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { Session } from 'koishi';
|
|
1
|
+
import { Context, Session } from 'koishi';
|
|
2
|
+
import { User } from './types';
|
|
2
3
|
export declare function escapeRegExp(str: string): string;
|
|
3
4
|
export declare function parseTimeToMinutes(timeStr: string): number;
|
|
4
5
|
export declare function parseTime(timestamp: number): number;
|
|
5
6
|
export declare function getTimeOfDay(hours: number): string;
|
|
6
7
|
export declare function detectEnglishLetters(text: string): number;
|
|
7
8
|
export declare function trimSlash(url: string): string;
|
|
8
|
-
export declare function splitSentences(text: string): string[];
|
|
9
|
+
export declare function splitSentences(text: string, MIN_LENGTH: number, MAX_LENGTH: number): string[];
|
|
9
10
|
export declare function shouldFilterContent(content: string, blockWords: string[]): boolean;
|
|
10
11
|
export declare function probabilisticCheck(probability: number): boolean;
|
|
11
12
|
export declare function isErrorWithMessage(error: unknown): error is {
|
|
@@ -22,5 +23,9 @@ export declare function processPrompt(prompt: string): string;
|
|
|
22
23
|
* @param words 需要过滤的关键词
|
|
23
24
|
* @returns 处理后的字符串,删除含有关键词的部分
|
|
24
25
|
*/
|
|
25
|
-
export declare function filterResponse(prompt: string, words: string[]):
|
|
26
|
+
export declare function filterResponse(prompt: string, words: string[]): {
|
|
27
|
+
content: string;
|
|
28
|
+
error: boolean;
|
|
29
|
+
};
|
|
26
30
|
export declare function addOutputCensor(session: Session, word: string, baseURL: string): void;
|
|
31
|
+
export declare function updateUserPWithTicket(ctx: Context, user: User, adjustment: number): Promise<void>;
|
package/package.json
CHANGED
package/wasm/gobang.cpp
CHANGED
|
@@ -460,8 +460,7 @@ int wholeScore(int player, const Game &game) {
|
|
|
460
460
|
if (temp.score == 0)
|
|
461
461
|
continue;
|
|
462
462
|
if (temp.score == player) {
|
|
463
|
-
|
|
464
|
-
Score += singleScore(temp, player, game); // 己方落子的单点分相加
|
|
463
|
+
Score += singleScore(temp, player, game); // 己方落子的单点分相加
|
|
465
464
|
} else
|
|
466
465
|
Score -= singleScore(temp, 3 - player, game); // 对方落子的单点分相加
|
|
467
466
|
}
|
|
@@ -475,11 +474,10 @@ int inspireSearch(coordinate *scoreBoard, int player, Game &game) {
|
|
|
475
474
|
for (int j = 0; j < BOARD_SIZE; j++) {
|
|
476
475
|
if (game.MAP.board[i][j] == 0) {
|
|
477
476
|
coordinate temp = {i, j, 0};
|
|
478
|
-
if (hasNeighbor(temp,
|
|
477
|
+
if (hasNeighbor(temp, 3, game)) {
|
|
479
478
|
scoreBoard[length] = temp;
|
|
480
479
|
scoreBoard[length].score = singleScore(temp, 3 - player, game);
|
|
481
|
-
|
|
482
|
-
scoreBoard[length].score += singleScore(temp, player, game);
|
|
480
|
+
scoreBoard[length].score += singleScore(temp, player, game);
|
|
483
481
|
length++;
|
|
484
482
|
}
|
|
485
483
|
}
|
|
@@ -561,8 +559,15 @@ coordinate entrance(int depth, int alpha, int beta, int player, coordinate comma
|
|
|
561
559
|
* @param myFlag: 我方棋子颜色
|
|
562
560
|
* @param depth: 搜索深度
|
|
563
561
|
* @return: 返回落子位置
|
|
562
|
+
* @outX: 落子横坐标指针
|
|
563
|
+
* @outY: 落子纵坐标指针
|
|
564
|
+
* @outScore: 落子分数指针
|
|
565
|
+
* outX: 落子横坐标
|
|
566
|
+
* outY: 落子纵坐标
|
|
567
|
+
* outScore: 落子分数
|
|
568
|
+
* -1: 游戏平局
|
|
564
569
|
*/
|
|
565
|
-
extern "C"
|
|
570
|
+
extern "C" void decideMove(const int board[BOARD_SIZE * BOARD_SIZE], int myFlag, int depth, int* outX, int* outY, int* outScore) {
|
|
566
571
|
Game localGame;
|
|
567
572
|
for (int i = 0; i < BOARD_SIZE; i++) {
|
|
568
573
|
for (int j = 0; j < BOARD_SIZE; j++) {
|
|
@@ -576,7 +581,12 @@ extern "C" int decideMove(const int board[BOARD_SIZE * BOARD_SIZE], int myFlag,
|
|
|
576
581
|
coordinate cmd, current;
|
|
577
582
|
coordinate result = entrance(depth, _INF, INF, localGame.myFlag, cmd, current, localGame);
|
|
578
583
|
if (localGame.draw) {
|
|
579
|
-
|
|
584
|
+
*outX = -1;
|
|
585
|
+
*outY = -1;
|
|
586
|
+
*outScore = -1;
|
|
587
|
+
return;
|
|
580
588
|
}
|
|
581
|
-
|
|
589
|
+
*outX = result.x;
|
|
590
|
+
*outY = result.y;
|
|
591
|
+
*outScore = result.score;
|
|
582
592
|
}
|
package/wasm/gobang.js
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
var Module = (() => {
|
|
2
|
-
var _scriptName = typeof document != 'undefined' ? document.currentScript?.src : undefined;
|
|
3
|
-
if (typeof __filename != 'undefined') _scriptName = _scriptName || __filename;
|
|
4
|
-
return (
|
|
5
|
-
async function(moduleArg = {}) {
|
|
6
|
-
var moduleRtn;
|
|
7
|
-
|
|
8
|
-
var Module=moduleArg;var readyPromiseResolve,readyPromiseReject;var readyPromise=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject});var ENVIRONMENT_IS_NODE=true;if(ENVIRONMENT_IS_NODE){}var moduleOverrides={...Module};var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var readAsync,readBinary;if(ENVIRONMENT_IS_NODE){var fs=require("fs");var nodePath=require("path");scriptDirectory=__dirname+"/";readBinary=filename=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename);return ret};readAsync=async(filename,binary=true)=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename,binary?undefined:"utf8");return ret};if(!Module["thisProgram"]&&process.argv.length>1){thisProgram=process.argv[1].replace(/\\/g,"/")}arguments_=process.argv.slice(2);quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.error.bind(console);Object.assign(Module,moduleOverrides);moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];var wasmBinary=Module["wasmBinary"];var wasmMemory;var ABORT=false;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAP64,HEAPU64,HEAPF64;var runtimeInitialized=false;var isFileURI=filename=>filename.startsWith("file://");function updateMemoryViews(){var b=wasmMemory.buffer;Module["HEAP8"]=HEAP8=new Int8Array(b);Module["HEAP16"]=HEAP16=new Int16Array(b);Module["HEAPU8"]=HEAPU8=new Uint8Array(b);Module["HEAPU16"]=HEAPU16=new Uint16Array(b);Module["HEAP32"]=HEAP32=new Int32Array(b);Module["HEAPU32"]=HEAPU32=new Uint32Array(b);Module["HEAPF32"]=HEAPF32=new Float32Array(b);Module["HEAPF64"]=HEAPF64=new Float64Array(b);Module["HEAP64"]=HEAP64=new BigInt64Array(b);Module["HEAPU64"]=HEAPU64=new BigUint64Array(b)}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(onPreRuns)}function initRuntime(){runtimeInitialized=true;wasmExports["c"]()}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(onPostRuns)}var runDependencies=0;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;Module["monitorRunDependencies"]?.(runDependencies)}function removeRunDependency(id){runDependencies--;Module["monitorRunDependencies"]?.(runDependencies);if(runDependencies==0){if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}function abort(what){Module["onAbort"]?.(what);what="Aborted("+what+")";err(what);ABORT=true;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject(e);throw e}var wasmBinaryFile;function findWasmBinary(){return locateFile("gobang.wasm")}function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}async function getWasmBinary(binaryFile){if(!wasmBinary){try{var response=await readAsync(binaryFile);return new Uint8Array(response)}catch{}}return getBinarySync(binaryFile)}async function instantiateArrayBuffer(binaryFile,imports){try{var binary=await getWasmBinary(binaryFile);var instance=await WebAssembly.instantiate(binary,imports);return instance}catch(reason){err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)}}async function instantiateAsync(binary,binaryFile,imports){if(!binary&&typeof WebAssembly.instantiateStreaming=="function"&&!ENVIRONMENT_IS_NODE){try{var response=fetch(binaryFile,{credentials:"same-origin"});var instantiationResult=await WebAssembly.instantiateStreaming(response,imports);return instantiationResult}catch(reason){err(`wasm streaming compile failed: ${reason}`);err("falling back to ArrayBuffer instantiation")}}return instantiateArrayBuffer(binaryFile,imports)}function getWasmImports(){return{a:wasmImports}}async function createWasm(){function receiveInstance(instance,module){wasmExports=instance.exports;wasmMemory=wasmExports["b"];updateMemoryViews();removeRunDependency("wasm-instantiate");return wasmExports}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){return receiveInstance(result["instance"])}var info=getWasmImports();if(Module["instantiateWasm"]){return new Promise((resolve,reject)=>{Module["instantiateWasm"](info,(mod,inst)=>{receiveInstance(mod,inst);resolve(mod.exports)})})}wasmBinaryFile??=findWasmBinary();try{var result=await instantiateAsync(wasmBinary,wasmBinaryFile,info);var exports=receiveInstantiationResult(result);return exports}catch(e){readyPromiseReject(e);return Promise.reject(e)}}class ExitStatus{name="ExitStatus";constructor(status){this.message=`Program terminated with exit(${status})`;this.status=status}}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var onPostRuns=[];var addOnPostRun=cb=>onPostRuns.unshift(cb);var onPreRuns=[];var addOnPreRun=cb=>onPreRuns.unshift(cb);var noExitRuntime=Module["noExitRuntime"]||true;var abortOnCannotGrowMemory=requestedSize=>{abort("OOM")};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;abortOnCannotGrowMemory(requestedSize)};var wasmImports={a:_emscripten_resize_heap};var wasmExports=await createWasm();var ___wasm_call_ctors=wasmExports["c"];var _decideMove=Module["_decideMove"]=wasmExports["d"];var _malloc=Module["_malloc"]=wasmExports["f"];var _free=Module["_free"]=wasmExports["g"];function run(){if(runDependencies>0){dependenciesFulfilled=run;return}preRun();if(runDependencies>0){dependenciesFulfilled=run;return}function doRun(){Module["calledRun"]=true;if(ABORT)return;initRuntime();readyPromiseResolve(Module);Module["onRuntimeInitialized"]?.();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(()=>{setTimeout(()=>Module["setStatus"](""),1);doRun()},1)}else{doRun()}}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}run();moduleRtn=readyPromise;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
return moduleRtn;
|
|
12
|
-
}
|
|
13
|
-
);
|
|
14
|
-
})();
|
|
15
|
-
if (typeof exports === 'object' && typeof module === 'object') {
|
|
16
|
-
module.exports = Module;
|
|
17
|
-
// This default export looks redundant, but it allows TS to import this
|
|
18
|
-
// commonjs style module.
|
|
19
|
-
module.exports.default = Module;
|
|
20
|
-
} else if (typeof define === 'function' && define['amd'])
|
|
21
|
-
define([], () => Module);
|
|
1
|
+
var Module = (() => {
|
|
2
|
+
var _scriptName = typeof document != 'undefined' ? document.currentScript?.src : undefined;
|
|
3
|
+
if (typeof __filename != 'undefined') _scriptName = _scriptName || __filename;
|
|
4
|
+
return (
|
|
5
|
+
async function(moduleArg = {}) {
|
|
6
|
+
var moduleRtn;
|
|
7
|
+
|
|
8
|
+
var Module=moduleArg;var readyPromiseResolve,readyPromiseReject;var readyPromise=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject});var ENVIRONMENT_IS_NODE=true;if(ENVIRONMENT_IS_NODE){}var moduleOverrides={...Module};var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var readAsync,readBinary;if(ENVIRONMENT_IS_NODE){var fs=require("fs");var nodePath=require("path");scriptDirectory=__dirname+"/";readBinary=filename=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename);return ret};readAsync=async(filename,binary=true)=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename,binary?undefined:"utf8");return ret};if(!Module["thisProgram"]&&process.argv.length>1){thisProgram=process.argv[1].replace(/\\/g,"/")}arguments_=process.argv.slice(2);quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.error.bind(console);Object.assign(Module,moduleOverrides);moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];var wasmBinary=Module["wasmBinary"];var wasmMemory;var ABORT=false;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAP64,HEAPU64,HEAPF64;var runtimeInitialized=false;var isFileURI=filename=>filename.startsWith("file://");function updateMemoryViews(){var b=wasmMemory.buffer;Module["HEAP8"]=HEAP8=new Int8Array(b);Module["HEAP16"]=HEAP16=new Int16Array(b);Module["HEAPU8"]=HEAPU8=new Uint8Array(b);Module["HEAPU16"]=HEAPU16=new Uint16Array(b);Module["HEAP32"]=HEAP32=new Int32Array(b);Module["HEAPU32"]=HEAPU32=new Uint32Array(b);Module["HEAPF32"]=HEAPF32=new Float32Array(b);Module["HEAPF64"]=HEAPF64=new Float64Array(b);Module["HEAP64"]=HEAP64=new BigInt64Array(b);Module["HEAPU64"]=HEAPU64=new BigUint64Array(b)}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(onPreRuns)}function initRuntime(){runtimeInitialized=true;wasmExports["c"]()}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(onPostRuns)}var runDependencies=0;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;Module["monitorRunDependencies"]?.(runDependencies)}function removeRunDependency(id){runDependencies--;Module["monitorRunDependencies"]?.(runDependencies);if(runDependencies==0){if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}function abort(what){Module["onAbort"]?.(what);what="Aborted("+what+")";err(what);ABORT=true;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject(e);throw e}var wasmBinaryFile;function findWasmBinary(){return locateFile("gobang.wasm")}function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}async function getWasmBinary(binaryFile){if(!wasmBinary){try{var response=await readAsync(binaryFile);return new Uint8Array(response)}catch{}}return getBinarySync(binaryFile)}async function instantiateArrayBuffer(binaryFile,imports){try{var binary=await getWasmBinary(binaryFile);var instance=await WebAssembly.instantiate(binary,imports);return instance}catch(reason){err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)}}async function instantiateAsync(binary,binaryFile,imports){if(!binary&&typeof WebAssembly.instantiateStreaming=="function"&&!ENVIRONMENT_IS_NODE){try{var response=fetch(binaryFile,{credentials:"same-origin"});var instantiationResult=await WebAssembly.instantiateStreaming(response,imports);return instantiationResult}catch(reason){err(`wasm streaming compile failed: ${reason}`);err("falling back to ArrayBuffer instantiation")}}return instantiateArrayBuffer(binaryFile,imports)}function getWasmImports(){return{a:wasmImports}}async function createWasm(){function receiveInstance(instance,module){wasmExports=instance.exports;wasmMemory=wasmExports["b"];updateMemoryViews();removeRunDependency("wasm-instantiate");return wasmExports}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){return receiveInstance(result["instance"])}var info=getWasmImports();if(Module["instantiateWasm"]){return new Promise((resolve,reject)=>{Module["instantiateWasm"](info,(mod,inst)=>{receiveInstance(mod,inst);resolve(mod.exports)})})}wasmBinaryFile??=findWasmBinary();try{var result=await instantiateAsync(wasmBinary,wasmBinaryFile,info);var exports=receiveInstantiationResult(result);return exports}catch(e){readyPromiseReject(e);return Promise.reject(e)}}class ExitStatus{name="ExitStatus";constructor(status){this.message=`Program terminated with exit(${status})`;this.status=status}}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var onPostRuns=[];var addOnPostRun=cb=>onPostRuns.unshift(cb);var onPreRuns=[];var addOnPreRun=cb=>onPreRuns.unshift(cb);var noExitRuntime=Module["noExitRuntime"]||true;var abortOnCannotGrowMemory=requestedSize=>{abort("OOM")};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;abortOnCannotGrowMemory(requestedSize)};var wasmImports={a:_emscripten_resize_heap};var wasmExports=await createWasm();var ___wasm_call_ctors=wasmExports["c"];var _decideMove=Module["_decideMove"]=wasmExports["d"];var _malloc=Module["_malloc"]=wasmExports["f"];var _free=Module["_free"]=wasmExports["g"];function run(){if(runDependencies>0){dependenciesFulfilled=run;return}preRun();if(runDependencies>0){dependenciesFulfilled=run;return}function doRun(){Module["calledRun"]=true;if(ABORT)return;initRuntime();readyPromiseResolve(Module);Module["onRuntimeInitialized"]?.();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(()=>{setTimeout(()=>Module["setStatus"](""),1);doRun()},1)}else{doRun()}}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}run();moduleRtn=readyPromise;
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
return moduleRtn;
|
|
12
|
+
}
|
|
13
|
+
);
|
|
14
|
+
})();
|
|
15
|
+
if (typeof exports === 'object' && typeof module === 'object') {
|
|
16
|
+
module.exports = Module;
|
|
17
|
+
// This default export looks redundant, but it allows TS to import this
|
|
18
|
+
// commonjs style module.
|
|
19
|
+
module.exports.default = Module;
|
|
20
|
+
} else if (typeof define === 'function' && define['amd'])
|
|
21
|
+
define([], () => Module);
|
package/wasm/gobang.wasm
CHANGED
|
Binary file
|