koishi-plugin-satori-ai 1.2.0-beta.2 → 1.2.1
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/api.d.ts +4 -0
- package/lib/index.js +42 -19
- package/lib/types.d.ts +2 -2
- package/lib/userportrait.d.ts +16 -0
- package/package.json +1 -1
package/lib/api.d.ts
CHANGED
|
@@ -13,6 +13,10 @@ export declare class APIClient {
|
|
|
13
13
|
content: string;
|
|
14
14
|
error: boolean;
|
|
15
15
|
}>;
|
|
16
|
+
generateUserPortrait(user: User, messages: Sat.Msg[]): Promise<{
|
|
17
|
+
content: string;
|
|
18
|
+
error: boolean;
|
|
19
|
+
}>;
|
|
16
20
|
private createPayload;
|
|
17
21
|
private createAuxiliaryPayload;
|
|
18
22
|
private tryRequest;
|
package/lib/index.js
CHANGED
|
@@ -137,7 +137,7 @@ function processPrompt(prompt) {
|
|
|
137
137
|
}
|
|
138
138
|
__name(processPrompt, "processPrompt");
|
|
139
139
|
function filterResponse(prompt, words) {
|
|
140
|
-
const parts = prompt.split(/[(
|
|
140
|
+
const parts = prompt.split(/([((][^))]*[))])/g);
|
|
141
141
|
const filtered = parts.map((part) => {
|
|
142
142
|
if (part.startsWith("(") && part.endsWith(")") || part.startsWith("(") && part.endsWith(")")) {
|
|
143
143
|
return words.some((word) => part.includes(word)) ? "" : part;
|
|
@@ -176,7 +176,7 @@ var APIClient = class {
|
|
|
176
176
|
// 发送聊天请求
|
|
177
177
|
async chat(user, messages) {
|
|
178
178
|
if (user.userid == "Alice")
|
|
179
|
-
return { content: "(系统)
|
|
179
|
+
return { content: "(系统)(abc)测试", error: false };
|
|
180
180
|
const enableUserKey = user?.items?.["地灵殿通行证"]?.description && user.items["地灵殿通行证"].description == "on";
|
|
181
181
|
let keys;
|
|
182
182
|
let modle;
|
|
@@ -205,7 +205,7 @@ var APIClient = class {
|
|
|
205
205
|
}
|
|
206
206
|
// 发送辅助聊天请求
|
|
207
207
|
async auxiliaryChat(messages) {
|
|
208
|
-
const AuxiliaryPayload = this.createAuxiliaryPayload(messages);
|
|
208
|
+
const AuxiliaryPayload = this.createAuxiliaryPayload(messages, this.config.auxiliary_LLM);
|
|
209
209
|
for (let i = 0; i < this.config.keys.length; i++) {
|
|
210
210
|
try {
|
|
211
211
|
return await this.tryRequest(this.config.auxiliary_LLM_URL, AuxiliaryPayload, this.config.auxiliary_LLM_key);
|
|
@@ -217,6 +217,34 @@ var APIClient = class {
|
|
|
217
217
|
}
|
|
218
218
|
}
|
|
219
219
|
}
|
|
220
|
+
// 发送生成用户画像请求
|
|
221
|
+
async generateUserPortrait(user, messages) {
|
|
222
|
+
const enableUserKey = user?.items?.["地灵殿通行证"]?.description && user.items["地灵殿通行证"].description == "on";
|
|
223
|
+
let keys;
|
|
224
|
+
let modle;
|
|
225
|
+
let baseURL;
|
|
226
|
+
if (enableUserKey) {
|
|
227
|
+
const key = user.items["地灵殿通行证"].metadata?.key;
|
|
228
|
+
keys = [key];
|
|
229
|
+
modle = user.items["地灵殿通行证"].metadata?.model;
|
|
230
|
+
baseURL = user.items["地灵殿通行证"].metadata?.baseURL;
|
|
231
|
+
} else {
|
|
232
|
+
keys = this.config.keys;
|
|
233
|
+
modle = this.config.appointModel;
|
|
234
|
+
baseURL = this.config.baseURL;
|
|
235
|
+
}
|
|
236
|
+
const payload = this.createAuxiliaryPayload(messages, modle);
|
|
237
|
+
for (let i = 0; i < keys.length; i++) {
|
|
238
|
+
try {
|
|
239
|
+
return await this.tryRequest(baseURL, payload, keys);
|
|
240
|
+
} catch (error) {
|
|
241
|
+
if (i == keys.length - 1) {
|
|
242
|
+
return this.handleAPIError(error);
|
|
243
|
+
}
|
|
244
|
+
this.rotateKey();
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
220
248
|
// 生成请求体
|
|
221
249
|
createPayload(messages, model) {
|
|
222
250
|
return {
|
|
@@ -230,9 +258,9 @@ var APIClient = class {
|
|
|
230
258
|
};
|
|
231
259
|
}
|
|
232
260
|
// 生成辅助请求体
|
|
233
|
-
createAuxiliaryPayload(messages) {
|
|
261
|
+
createAuxiliaryPayload(messages, model) {
|
|
234
262
|
return {
|
|
235
|
-
model
|
|
263
|
+
model,
|
|
236
264
|
messages,
|
|
237
265
|
temperature: 0.1
|
|
238
266
|
};
|
|
@@ -360,7 +388,7 @@ var MemoryManager = class {
|
|
|
360
388
|
}
|
|
361
389
|
// 是否应当记忆
|
|
362
390
|
shouldRemember(content) {
|
|
363
|
-
return content.length >= this.config.remember_min_length && !this.config.memory_block_words.some((word) => content.includes(word));
|
|
391
|
+
return (content.length >= this.config.remember_min_length || content.includes("记住")) && !this.config.memory_block_words.some((word) => content.includes(word));
|
|
364
392
|
}
|
|
365
393
|
// 更新频道对话
|
|
366
394
|
async updateChannelDialogue(session, prompt, name) {
|
|
@@ -987,7 +1015,7 @@ var Sat = class extends import_koishi5.Service {
|
|
|
987
1015
|
import_koishi5.Schema.object({
|
|
988
1016
|
alias: import_koishi5.Schema.array(String).default(["ai"]).description("触发命令;别名"),
|
|
989
1017
|
authority: import_koishi5.Schema.number().role("slider").min(0).max(5).step(1).description("允许使用的最低权限").default(1),
|
|
990
|
-
no_system_prompt: import_koishi5.Schema.boolean().default(false).description("是否将系统提示的system替换为user
|
|
1018
|
+
no_system_prompt: import_koishi5.Schema.boolean().default(false).description("是否将系统提示的system替换为user(用于具有思维链的模型或一些特殊的api格式,例如硅基流动)"),
|
|
991
1019
|
max_tokens: import_koishi5.Schema.number().description("最大请求长度(字符数)").default(100),
|
|
992
1020
|
content_max_tokens: import_koishi5.Schema.number().description("最大回答长度(思维链+输出token)").default(4096),
|
|
993
1021
|
content_max_length: import_koishi5.Schema.number().description("最大回答长度(仅输出,字符数)").default(100),
|
|
@@ -1031,7 +1059,9 @@ var Sat = class extends import_koishi5.Service {
|
|
|
1031
1059
|
randnum: import_koishi5.Schema.number().role("slider").min(0).max(1).step(0.01).default(0).description("在群聊中随机触发对话的概率,如需关闭可设置为 0"),
|
|
1032
1060
|
sentences_divide: import_koishi5.Schema.boolean().default(true).description("是否分句发送"),
|
|
1033
1061
|
time_interval: import_koishi5.Schema.number().default(1e3).description("每句话的时间间隔"),
|
|
1034
|
-
reply_pointing: import_koishi5.Schema.boolean().default(true).description("是否在与多人同时对话时显示回复指向")
|
|
1062
|
+
reply_pointing: import_koishi5.Schema.boolean().default(true).description("是否在与多人同时对话时显示回复指向"),
|
|
1063
|
+
enable_user_portrait: import_koishi5.Schema.boolean().default(true).description("是否启用用户画像功能"),
|
|
1064
|
+
portrait_min_dialogues: import_koishi5.Schema.number().default(100).description("触发画像生成的最小对话条数")
|
|
1035
1065
|
}).description("对话设置"),
|
|
1036
1066
|
import_koishi5.Schema.object({
|
|
1037
1067
|
enable_favorability: import_koishi5.Schema.boolean().default(false).description("是否开启好感度系统(每次对话默认+1好感度)"),
|
|
@@ -1056,11 +1086,7 @@ var Sat = class extends import_koishi5.Service {
|
|
|
1056
1086
|
import_koishi5.Schema.object({
|
|
1057
1087
|
enable_game: import_koishi5.Schema.boolean().default(false).description("是否开启游戏模块"),
|
|
1058
1088
|
enable_gobang: import_koishi5.Schema.boolean().default(false).description("是否开启五子棋游戏")
|
|
1059
|
-
}).description("拓展模块-游戏设置(开发中)")
|
|
1060
|
-
import_koishi5.Schema.object({
|
|
1061
|
-
blockuser: import_koishi5.Schema.array(String).default([]).description("屏蔽的用户"),
|
|
1062
|
-
blockchannel: import_koishi5.Schema.array(String).default([]).description("屏蔽的频道")
|
|
1063
|
-
}).description("过滤器")
|
|
1089
|
+
}).description("拓展模块-游戏设置(开发中)")
|
|
1064
1090
|
]);
|
|
1065
1091
|
})(Sat || (Sat = {}));
|
|
1066
1092
|
|
|
@@ -1084,6 +1110,7 @@ var SAT = class extends Sat {
|
|
|
1084
1110
|
}
|
|
1085
1111
|
apiClient;
|
|
1086
1112
|
memoryManager;
|
|
1113
|
+
//private portraitManager: UserPortraitManager
|
|
1087
1114
|
ChannelParallelCount = /* @__PURE__ */ new Map();
|
|
1088
1115
|
onlineUsers = [];
|
|
1089
1116
|
getAPIConfig() {
|
|
@@ -1239,10 +1266,6 @@ var SAT = class extends Sat {
|
|
|
1239
1266
|
}
|
|
1240
1267
|
// 前置检查
|
|
1241
1268
|
performPreChecks(session, prompt) {
|
|
1242
|
-
if (this.config.blockuser.includes(session.userId))
|
|
1243
|
-
return "";
|
|
1244
|
-
if (this.config.blockchannel.includes(session.channelId))
|
|
1245
|
-
return "";
|
|
1246
1269
|
if (!prompt)
|
|
1247
1270
|
return session.text("commands.sat.messages.no-prompt");
|
|
1248
1271
|
if (prompt.length > this.config.max_tokens)
|
|
@@ -1286,9 +1309,9 @@ var SAT = class extends Sat {
|
|
|
1286
1309
|
}
|
|
1287
1310
|
// 对话次数检查
|
|
1288
1311
|
async checkUserDialogueCount(session, user, adjustment = 1) {
|
|
1312
|
+
const usage = await updateUserUsage(this.ctx, user, adjustment);
|
|
1289
1313
|
if (user?.items?.["地灵殿通行证"]?.description && user.items["地灵殿通行证"].description === "on")
|
|
1290
1314
|
return null;
|
|
1291
|
-
const usage = await updateUserUsage(this.ctx, user, adjustment);
|
|
1292
1315
|
const level = user.userlevel || 0;
|
|
1293
1316
|
const usageLimit = this.config.max_usage[level] || 0;
|
|
1294
1317
|
if (usage && usageLimit != 0 && usage > usageLimit) {
|
|
@@ -1380,7 +1403,7 @@ ${payload}`);
|
|
|
1380
1403
|
if (this.config.enable_favorability) {
|
|
1381
1404
|
systemPrompt += generateLevelPrompt(getFavorabilityLevel(user, this.getFavorabilityConfig()), this.getFavorabilityConfig(), user);
|
|
1382
1405
|
}
|
|
1383
|
-
if (this.config.
|
|
1406
|
+
if (this.config.no_system_prompt)
|
|
1384
1407
|
systemPrompt += "如果你明白以上内容,请回复“已明确对话要求”";
|
|
1385
1408
|
return systemPrompt;
|
|
1386
1409
|
}
|
package/lib/types.d.ts
CHANGED
|
@@ -189,6 +189,8 @@ export declare namespace Sat {
|
|
|
189
189
|
time_interval: number;
|
|
190
190
|
max_parallel_count: number;
|
|
191
191
|
reply_pointing: boolean;
|
|
192
|
+
enable_user_portrait: boolean;
|
|
193
|
+
portrait_min_dialogues: number;
|
|
192
194
|
enable_favorability: boolean;
|
|
193
195
|
max_favorability_perday: number;
|
|
194
196
|
input_censor_favorability: boolean;
|
|
@@ -207,8 +209,6 @@ export declare namespace Sat {
|
|
|
207
209
|
prompt_3: string;
|
|
208
210
|
favorability_div_4: number;
|
|
209
211
|
prompt_4: string;
|
|
210
|
-
blockuser: string[];
|
|
211
|
-
blockchannel: string[];
|
|
212
212
|
maxRetryTimes: number;
|
|
213
213
|
retry_delay_time: number;
|
|
214
214
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Context, Session } from 'koishi';
|
|
2
|
+
import { Sat, User } from './types';
|
|
3
|
+
import { APIClient } from './api';
|
|
4
|
+
export declare class UserPortraitManager {
|
|
5
|
+
private ctx;
|
|
6
|
+
private config;
|
|
7
|
+
constructor(ctx: Context, config: Sat.Config);
|
|
8
|
+
private getPortraitPath;
|
|
9
|
+
hasPortrait(userId: string): boolean;
|
|
10
|
+
readPortrait(userId: string): string;
|
|
11
|
+
private processDialogues;
|
|
12
|
+
private buildPrompt;
|
|
13
|
+
generatePortrait(session: Session, user: User, apiClient: APIClient): Promise<void>;
|
|
14
|
+
enhanceSystemPrompt(session: Session): string;
|
|
15
|
+
private getFavorabilityConfig;
|
|
16
|
+
}
|