Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/AI/AI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ export class AI {
privilege: Privilege;

// 下面是临时变量,用于处理消息
stream: {
stream: { // 用于流式输出相关
id: string,
reply: string,
toolCallStatus: boolean
}

bucket: {
bucket: { // 触发次数令牌桶
count: number,
lastTime: number
}
Expand Down
31 changes: 22 additions & 9 deletions src/AI/memory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,19 @@ export interface MemoryInfo {
export class Memory {
persona: string;
memoryMap: { [key: string]: MemoryInfo };
shortMemory: string[];
useShortMemory: boolean;
shortMemoryList: string[];

constructor() {
this.persona = '无';
this.memoryMap = {};
this.shortMemory = [];
this.useShortMemory = false;
this.shortMemoryList = [];
}

static reviver(value: any): Memory {
const memory = new Memory();
const validKeys = ['persona', 'memoryMap', 'shortMemory'];
const validKeys = ['persona', 'memoryMap', 'useShortMemory', 'shortMemory'];

for (const k in value) {
if (validKeys.includes(k)) {
Expand Down Expand Up @@ -108,7 +110,7 @@ export class Memory {
}

clearShortMemory() {
this.shortMemory = [];
this.shortMemoryList = [];
}

limitMemory() {
Expand Down Expand Up @@ -139,15 +141,26 @@ export class Memory {

limitShortMemory() {
const { shortMemoryLimit } = ConfigManager.memory;
if (this.shortMemory.length > shortMemoryLimit) {
this.shortMemory.splice(0, this.shortMemory.length - shortMemoryLimit);
if (this.shortMemoryList.length > shortMemoryLimit) {
this.shortMemoryList.splice(0, this.shortMemoryList.length - shortMemoryLimit);
}
}

async updateShortMemory(ctx: seal.MsgContext, msg: seal.Message, ai: AI, sumMessages: Message[]) {
const { url, apiKey } = ConfigManager.request;
if (!this.useShortMemory) {
return;
}

const { url: chatUrl, apiKey: chatApiKey } = ConfigManager.request;
const { roleSettingTemplate, isPrefix, showNumber, showMsgId } = ConfigManager.message;
const { memoryBodyTemplate, memoryPromptTemplate } = ConfigManager.memory;
const { memoryUrl, memoryApiKey, memoryBodyTemplate, memoryPromptTemplate } = ConfigManager.memory;

let url = chatUrl;
let apiKey = chatApiKey;
if (memoryUrl.trim()) {
url = memoryUrl;
apiKey = memoryApiKey;
}

try {
let [roleSettingIndex, _] = seal.vars.intGet(ctx, "$gSYSPROMPT");
Expand Down Expand Up @@ -217,7 +230,7 @@ export class Memory {
};


this.shortMemory.push(memoryData.content);
this.shortMemoryList.push(memoryData.content);
this.limitShortMemory();

memoryData.memories.forEach(m => {
Expand Down
6 changes: 3 additions & 3 deletions src/config/config_backend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ export class BackendConfig {

seal.ext.registerStringConfig(BackendConfig.ext, "流式输出", "http://localhost:3010", '自行搭建或使用他人提供的后端');
seal.ext.registerStringConfig(BackendConfig.ext, "图片转base64", "https://urltobase64.白鱼.chat", '可自行搭建');
seal.ext.registerStringConfig(BackendConfig.ext, "联网搜索", "https://searxng.白鱼.chat", '可自行搭建');
seal.ext.registerStringConfig(BackendConfig.ext, "网页读取", "https://webread.白鱼.chat", '可自行搭建');
seal.ext.registerStringConfig(BackendConfig.ext, "用量图表", "http://error.白鱼.chat:3009", '可自行搭建');
seal.ext.registerStringConfig(BackendConfig.ext, "联网搜索", "https://searxng.fishwhite.top", '可自行搭建');
seal.ext.registerStringConfig(BackendConfig.ext, "网页读取", "https://webread.fishwhite.top", '可自行搭建');
seal.ext.registerStringConfig(BackendConfig.ext, "用量图表", "http://localhost:3009", '可自行搭建');
}

static get() {
Expand Down
4 changes: 4 additions & 0 deletions src/config/config_memory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ export class MemoryConfig {
seal.ext.registerBoolConfig(MemoryConfig.ext, "是否启用短期记忆", true, "");
seal.ext.registerIntConfig(MemoryConfig.ext, "短期记忆上限", 10, "");
seal.ext.registerIntConfig(MemoryConfig.ext, "短期记忆总结轮数", 10, "");
seal.ext.registerStringConfig(MemoryConfig.ext, "记忆总结 url地址", "", '为空时,默认使用对话接口');
seal.ext.registerStringConfig(MemoryConfig.ext, "记忆总结 API Key", "你的API Key", '若使用对话接口无需填写');
seal.ext.registerTemplateConfig(MemoryConfig.ext, "记忆总结 body", [
`"model":"deepseek-chat"`,
`"max_tokens":1024`,
Expand Down Expand Up @@ -114,6 +116,8 @@ export class MemoryConfig {
isShortMemory: seal.ext.getBoolConfig(MemoryConfig.ext, "是否启用短期记忆"),
shortMemoryLimit: seal.ext.getIntConfig(MemoryConfig.ext, "短期记忆上限"),
shortMemorySummaryRound: seal.ext.getIntConfig(MemoryConfig.ext, "短期记忆总结轮数"),
memoryUrl: seal.ext.getStringConfig(MemoryConfig.ext, "记忆总结 url地址"),
memoryApiKey: seal.ext.getStringConfig(MemoryConfig.ext, "记忆总结 API Key"),
memoryBodyTemplate: seal.ext.getTemplateConfig(MemoryConfig.ext, "记忆总结 body"),
memoryPromptTemplate: seal.ext.getTemplateConfig(MemoryConfig.ext, "记忆总结prompt模板")
}
Expand Down
71 changes: 52 additions & 19 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,27 @@ function main() {
const ai2 = AIManager.getAI(muid);
const val2 = cmdArgs.getArgN(2);
switch (val2) {
case 'status': {
let ai3 = ai;
if (cmdArgs.at.length > 0 && (cmdArgs.at.length !== 1 || cmdArgs.at[0].userId !== ctx.endPoint.userId)) {
ai3 = ai2;
}

const { isMemory, isShortMemory } = ConfigManager.memory;

const keywords = new Set<string>();
for (const key in ai3.memory.memoryMap) {
ai3.memory.memoryMap[key].keywords.forEach(kw => keywords.add(kw));
}

seal.replyToSender(ctx, msg, `${ai3.id}
长期记忆开启状态: ${isMemory ? '是' : '否'}
长期记忆条数: ${Object.keys(ai3.memory.memoryMap).length}
关键词库: ${Array.from(keywords).join('、')}
短期记忆开启状态: ${(isShortMemory && ai3.memory.useShortMemory) ? '是' : '否'}
短期记忆条数: ${ai3.memory.shortMemoryList.length}`);
return ret;
}
case 'p':
case 'private': {
const val3 = cmdArgs.getArgN(3);
Expand Down Expand Up @@ -398,11 +419,6 @@ function main() {
}
}
}
case 'show': {
const s = ai2.memory.buildMemory(true, mctx.player.name, mctx.player.userId, '', '');
seal.replyToSender(ctx, msg, s || '无');
return ret;
}
case 'del': {
const idList = cmdArgs.args.slice(3);
const kw = cmdArgs.kwargs.map(item => item.name);
Expand All @@ -416,6 +432,11 @@ function main() {
AIManager.saveAI(muid);
return ret;
}
case 'show': {
const s = ai2.memory.buildMemory(true, mctx.player.name, mctx.player.userId, '', '');
seal.replyToSender(ctx, msg, s || '无');
return ret;
}
case 'clr': {
ai2.memory.clearMemory();
seal.replyToSender(ctx, msg, '个人记忆已清除');
Expand Down Expand Up @@ -466,11 +487,6 @@ function main() {
}
}
}
case 'show': {
const s = ai.memory.buildMemory(false, '', '', ctx.group.groupName, ctx.group.groupId);
seal.replyToSender(ctx, msg, s || '无');
return ret;
}
case 'del': {
const idList = cmdArgs.args.slice(3);
const kw = cmdArgs.kwargs.map(item => item.name);
Expand All @@ -484,6 +500,11 @@ function main() {
AIManager.saveAI(id);
return ret;
}
case 'show': {
const s = ai.memory.buildMemory(false, '', '', ctx.group.groupName, ctx.group.groupId);
seal.replyToSender(ctx, msg, s || '无');
return ret;
}
case 'clr': {
ai.memory.clearMemory();
seal.replyToSender(ctx, msg, '群聊记忆已清除');
Expand All @@ -500,14 +521,26 @@ function main() {
case 'short': {
const val3 = cmdArgs.getArgN(3);
switch (val3) {
case 'on': {
ai.memory.useShortMemory = true;
seal.replyToSender(ctx, msg, '短期记忆已开启');
AIManager.saveAI(id);
return ret;
}
case 'off': {
ai.memory.useShortMemory = false;
seal.replyToSender(ctx, msg, '短期记忆已关闭');
AIManager.saveAI(id);
return ret;
}
case 'show': {
const s = ai.memory.shortMemory.map((item, index) => `${index + 1}. ${item}`).join('\n');
const s = ai.memory.shortMemoryList.map((item, index) => `${index + 1}. ${item}`).join('\n');
seal.replyToSender(ctx, msg, s || '无');
return ret;
}
case 'clr': {
ai.memory.clearShortMemory();
seal.replyToSender(ctx, msg, '群聊记忆已清除');
seal.replyToSender(ctx, msg, '短期记忆已清除');
AIManager.saveAI(id);
return ret;
}
Expand All @@ -522,21 +555,21 @@ function main() {
ai.context.summaryCounter = 0;
ai.memory.updateShortMemory(ctx, msg, ai, ai.context.messages.slice(0, shortMemorySummaryRound))
.then(() => {
const s = ai.memory.shortMemory.map((item, index) => `${index + 1}. ${item}`).join('\n');
const s = ai.memory.shortMemoryList.map((item, index) => `${index + 1}. ${item}`).join('\n');
seal.replyToSender(ctx, msg, s || '无');
});
return ret;
}
default: {
seal.replyToSender(ctx, msg, `帮助:
【.ai memo status (@xxx)】查看记忆状态,@为查看个人记忆状态
【.ai memo [p/g] st <内容>】设置个人/群聊设定
【.ai memo [p/g] st clr】清除个人/群聊设定
【.ai memo [p/g] show】展示个人/群聊记忆
【.ai memo [p/g] del <ID1> <ID2> --关键词1 --关键词2】删除个人/群聊记忆
【.ai memo [p/g] clr】清除个人/群聊记忆
【.ai memo s show】展示短期记忆
【.ai memo s clr】清除短期记忆
【.ai memo sum】总结短期记忆`);
【.ai memo [p/g/s] show】展示个人/群聊/短期记忆
【.ai memo [p/g/s] clr】清除个人/群聊/短期记忆
【.ai memo s [on/off]】开启/关闭短期记忆
【.ai memo sum】立即总结一次短期记忆`);
return ret;
}
}
Expand Down Expand Up @@ -1141,7 +1174,7 @@ ${Object.keys(tool.info.function.parameters.properties).map(key => {
cmdImage.name = 'img'; // 指令名字,可用中文
cmdImage.help = `盗图指南:
【.img draw [stl/lcl/save/all]】随机抽取偷的图片/本地图片/保存的图片/全部
【.img stl (on/off)】偷图 开启/关闭
【.img stl [on/off]】偷图 开启/关闭
【.img f [stl/save/all]】遗忘偷的图片/保存的图片/全部
【.img itt [图片/ran] (附加提示词)】图片转文字
【.img list [show/send]】展示保存的图片列表/展示并发送所有保存的图片
Expand Down
8 changes: 6 additions & 2 deletions src/update.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
// 版本更新日志,格式为 "版本号": "更新内容",版本号格式为 "x.y.z",按照时间顺序从新到旧排列。
export const updateInfo = {
"4.10.1": `- 修复了构建ctx时,isPrivate始终为0的问题
"4.10.1": `
- 可能修复了非指令无法响应的问题
- 修复了构建ctx时,isPrivate始终为0的问题
- 新增保存图片功能
- 重构了定时任务的执行`,
- 重构了定时任务的执行
- 新增短期记忆单独控制开启
- 新增memo status命令`,
"4.10.0": `- 新增了全局待机模式配置项
- 修改了部分正则和部分默认配置项
- 修复了无法调用内置指令
Expand Down
6 changes: 3 additions & 3 deletions src/utils/utils_message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ export function buildSystemMessage(ctx: seal.MsgContext, ai: AI): Message {

// 短期记忆
let shortMemoryPrompt = '';
if (isShortMemory) {
shortMemoryPrompt = ai.memory.shortMemory.map((item, index) => `${index + 1}. ${item}`).join('\n');
if (isShortMemory && ai.memory.useShortMemory) {
shortMemoryPrompt = ai.memory.shortMemoryList.map((item, index) => `${index + 1}. ${item}`).join('\n');
}

// 调用函数
Expand All @@ -72,7 +72,7 @@ export function buildSystemMessage(ctx: seal.MsgContext, ai: AI): Message {
"可发送图片列表": sandableImagesPrompt,
"开启长期记忆": isMemory && memoryPrompt,
"记忆信息": memoryPrompt,
"开启短期记忆": isShortMemory && shortMemoryPrompt,
"开启短期记忆": isShortMemory && ai.memory.useShortMemory && shortMemoryPrompt,
"短期记忆信息": shortMemoryPrompt,
"开启工具函数提示词": isTool && usePromptEngineering,
"函数列表": toolsPrompt
Expand Down