koishi-plugin-virtual-pet
Version:
虚拟宠物插件,具有记忆功能,可以监听群聊并智能回复
214 lines (212 loc) • 7.48 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MemoryService = void 0;
class MemoryService {
constructor(config, ctx) {
this.memories = new Map();
this.config = config;
this.ctx = ctx;
}
/**
* 添加用户消息到记忆中
*/
async addMessage(session) {
const groupId = session.guildId;
const memory = this.getOrCreateMemory(groupId);
const message = {
role: 'user',
content: session.content,
timestamp: new Date(),
userId: session.userId,
userName: session.author?.nickname || session.username || '未知用户'
};
memory.messages.push(message);
memory.messageCount++;
// 限制消息数量,删除最旧的消息
if (memory.messages.length > this.config.memory.maxMessages) {
memory.messages = memory.messages.slice(-this.config.memory.maxMessages);
}
this.ctx.logger('virtual-pet').debug(`添加消息到群组 ${groupId} 的记忆中,用户: ${message.userName}, 内容: ${message.content}, 当前消息数: ${memory.messages.length}`);
}
/**
* 添加机器人回复到记忆中
*/
async addBotMessage(content, session) {
const groupId = session.guildId;
const memory = this.getOrCreateMemory(groupId);
const message = {
role: 'assistant',
content: content,
timestamp: new Date(),
userId: 'bot',
userName: this.config.pet.name
};
memory.messages.push(message);
memory.messageCount++;
// 限制消息数量
if (memory.messages.length > this.config.memory.maxMessages) {
memory.messages = memory.messages.slice(-this.config.memory.maxMessages);
}
this.ctx.logger('virtual-pet').debug(`添加机器人回复到群组 ${groupId} 的记忆中`);
}
/**
* 获取最近的消息
*/
getRecentMessages(groupId) {
if (!groupId) {
// 如果没有指定群组,返回所有群组的最新消息
const allMessages = [];
for (const memory of this.memories.values()) {
allMessages.push(...memory.messages);
}
return allMessages.sort((a, b) => (a.timestamp?.getTime() || 0) - (b.timestamp?.getTime() || 0));
}
const memory = this.memories.get(groupId);
return memory ? memory.messages : [];
}
/**
* 检查是否需要总结记忆
*/
shouldSummarize(groupId) {
if (!groupId) {
// 检查是否有任何群组需要总结
for (const [id, memory] of this.memories.entries()) {
if (memory.messageCount >= this.config.memory.summaryInterval) {
return true;
}
}
return false;
}
const memory = this.memories.get(groupId);
if (!memory)
return false;
return memory.messageCount >= this.config.memory.summaryInterval;
}
/**
* 总结记忆
*/
async summarizeMemory(aiService, groupId) {
const groupsToSummarize = groupId ? [groupId] : Array.from(this.memories.keys());
for (const gid of groupsToSummarize) {
const memory = this.memories.get(gid);
if (!memory || memory.messageCount < this.config.memory.summaryInterval) {
continue;
}
try {
const newSummary = await aiService.summarizeMemory(memory.messages, memory.summary);
// 更新记忆
memory.summary = newSummary;
memory.lastSummarized = Date.now();
memory.messageCount = 0;
// 保留最近的一些消息作为上下文
memory.messages = memory.messages.slice(-20);
this.ctx.logger('virtual-pet').info(`群组 ${gid} 记忆总结完成`);
}
catch (error) {
this.ctx.logger('virtual-pet').error(`群组 ${gid} 记忆总结失败:`, error);
}
}
}
/**
* 获取宠物状态
*/
async getPetStatus(groupId) {
if (groupId) {
const memory = this.memories.get(groupId);
if (!memory) {
return '还没有任何记忆呢~';
}
return `
📊 记忆统计:
- 当前消息数:${memory.messages.length}
- 总消息数:${memory.messageCount}
- 上次总结:${memory.lastSummarized ? new Date(memory.lastSummarized).toLocaleString() : '从未总结'}
📝 记忆摘要:
${memory.summary || '暂无记忆摘要'}
💭 最近话题:
${this.getRecentTopics(memory.messages)}
`.trim();
}
else {
// 返回所有群组的总体状态
const totalMessages = Array.from(this.memories.values())
.reduce((sum, memory) => sum + memory.messages.length, 0);
const totalSummaries = Array.from(this.memories.values())
.filter(memory => memory.summary).length;
return `
🌟 全局状态:
- 监控群组数:${this.memories.size}
- 总消息数:${totalMessages}
- 已总结群组:${totalSummaries}/${this.memories.size}
`.trim();
}
}
/**
* 清除记忆
*/
async clearMemory(groupId) {
if (groupId) {
this.memories.delete(groupId);
this.ctx.logger('virtual-pet').info(`已清除群组 ${groupId} 的记忆`);
}
else {
this.memories.clear();
this.ctx.logger('virtual-pet').info('已清除所有群组的记忆');
}
}
/**
* 获取或创建群组记忆
*/
getOrCreateMemory(groupId) {
if (!this.memories.has(groupId)) {
this.memories.set(groupId, {
groupId,
messages: [],
summary: '',
lastSummarized: 0,
messageCount: 0
});
}
return this.memories.get(groupId);
}
/**
* 获取最近话题
*/
getRecentTopics(messages) {
const recentMessages = messages.slice(-5);
if (recentMessages.length === 0) {
return '暂无最近话题';
}
return recentMessages
.map(msg => `${msg.userName}: ${msg.content.substring(0, 50)}${msg.content.length > 50 ? '...' : ''}`)
.join('\n');
}
/**
* 获取记忆数据(用于持久化)
*/
getMemoryData() {
const data = {};
for (const [groupId, memory] of this.memories.entries()) {
data[groupId] = { ...memory };
}
return data;
}
/**
* 恢复记忆数据(用于持久化)
*/
restoreMemoryData(data) {
this.memories.clear();
for (const [groupId, memory] of Object.entries(data)) {
this.memories.set(groupId, {
...memory,
messages: memory.messages.map(msg => ({
...msg,
timestamp: msg.timestamp ? new Date(msg.timestamp) : new Date()
}))
});
}
this.ctx.logger('virtual-pet').info(`恢复了 ${this.memories.size} 个群组的记忆数据`);
}
}
exports.MemoryService = MemoryService;
//# sourceMappingURL=memory.js.map