mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-07-19 12:03:37 +00:00
x
This commit is contained in:
@@ -3,26 +3,29 @@ import { NapCatCore } from '@/core';
|
||||
import { ActionMap } from '@/onebot/action';
|
||||
import { OB11PluginAdapter } from '@/onebot/network/plugin';
|
||||
import { OpenAI } from 'openai';
|
||||
import { ChatCompletionContentPart, ChatCompletionMessageParam } from 'openai/resources';
|
||||
import { Mutex } from 'async-mutex';
|
||||
|
||||
const API_KEY = 'sk-vDXUiGa1fx8ygDJDjAlr2rUyoz3uPhMxr8zId8n3ycMkV23i';
|
||||
const BASE_URL = 'https://api.bili2233.work/v1';
|
||||
const MODEL = 'gemini-2.0-flash-thinking-exp';
|
||||
const SHORT_TERM_MEMORY_LIMIT = 100;
|
||||
const BOT_NAME = '千千';
|
||||
const PROMPT =
|
||||
`你的名字叫千千,你现在处于一个QQ群聊之中,作为博学多识的可爱群员,热心解答各种问题和高强度水群
|
||||
记住你说的话要尽量的简洁但具有情感,不要长篇大论,一句话不宜超过五十个字。`;
|
||||
const CQCODE = `增加一下能力通过不同昵称和QQ进行区分哦,注意理清回复消息的人物, At人直接发送 [CQ:at,qq=1234] 这样可以直接at某个人喵这 回复消息需要发送[CQ:reply,id=xxx]这种格式叫CQ码,发送图片等操作你可以从聊天记录中学习哦, 如果聊天记录的image CQ码 maface类型你可以直接复制使用`
|
||||
const BOT_ADMIN = '1627126029';
|
||||
const PROMPT = `你的名字叫千千,你现在处于一个QQ群聊之中,作为博学多识的可爱群员,不要故意装可爱卖萌,而是更自然,注意少使用标点符号,热心解答各种问题和高强度水群
|
||||
记住你说的话要尽量的简洁但具有情感,不要长篇大论,一句话不宜超过五十个字但实际回复可以超过。`;
|
||||
const CQCODE = `增加一下能力通过不同昵称和QQ进行区分哦,注意理清回复消息的人物, At人直接发送 [CQ:at,qq=1234] 这样可以直接at某个人喵这 回复消息需要发送[CQ:reply,id=xxx]这种格式叫CQ码,发送图片等操作你可以从聊天记录中学习哦, 如果聊天记录的image CQ码 maface类型你可以直接复制使用`;
|
||||
const client = new OpenAI({
|
||||
apiKey: API_KEY,
|
||||
baseURL: BASE_URL
|
||||
});
|
||||
|
||||
const longTermMemory: Map<string, string> = new Map();
|
||||
const shortTermMemory: Map<string, string[]> = new Map();
|
||||
const memoryTransferCount: Map<string, number> = new Map();
|
||||
//聊天热度
|
||||
const chatHot: Map<string, number> = new Map();
|
||||
const shortTermMemory: Map<string, Array<ChatCompletionContentPart>[]> = new Map();
|
||||
const MemoryCount: Map<string, number> = new Map();
|
||||
const chatHot: Map<string, { count: number, usetime: number, usecount: number }> = new Map();
|
||||
const chatHotMutex = new Mutex();
|
||||
const memMutex = new Mutex();
|
||||
|
||||
async function createChatCompletionWithRetry(params: any, retries: number = 3): Promise<any> {
|
||||
for (let attempt = 0; attempt < retries; attempt++) {
|
||||
@@ -35,7 +38,8 @@ async function createChatCompletionWithRetry(params: any, retries: number = 3):
|
||||
}
|
||||
}
|
||||
|
||||
async function msg2string(adapter: string, msg: OB11MessageData[], group_id: string, action: ActionMap, plugin: OB11PluginAdapter): Promise<string> {
|
||||
async function messageToOpenAi(adapter: string, msg: OB11MessageData[], groupId: string, action: ActionMap, plugin: OB11PluginAdapter, message: OB11ArrayMessage) {
|
||||
const msgArray: Array<ChatCompletionContentPart> = [];
|
||||
let ret = '';
|
||||
for (const m of msg) {
|
||||
if (m.type === 'reply') {
|
||||
@@ -44,28 +48,28 @@ async function msg2string(adapter: string, msg: OB11MessageData[], group_id: str
|
||||
ret += m.data.text;
|
||||
} else if (m.type === 'at') {
|
||||
const memberInfo = await action.get('get_group_member_info')
|
||||
?.handle({ group_id: group_id, user_id: m.data.qq }, adapter, plugin.config);
|
||||
?.handle({ group_id: groupId, user_id: m.data.qq }, adapter, plugin.config);
|
||||
ret += `[CQ:at=${m.data.qq},name=${memberInfo?.data?.nickname}]`;
|
||||
} else if (m.type === 'image') {
|
||||
ret += '[CQ:image,file=' + m.data.url + ']';
|
||||
ret += `[CQ:image,file=${m.data.url}]`;
|
||||
msgArray.push({
|
||||
type: 'image_url',
|
||||
image_url: {
|
||||
url: m.data.url?.replace('https://', 'http://') || ''
|
||||
}
|
||||
});
|
||||
} else if (m.type === 'face') {
|
||||
ret += '[CQ:face,id=' + m.data.id + ']';
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
msgArray.push({
|
||||
type: 'text',
|
||||
text: `${message.sender.nickname}(${message.sender.user_id})发送了消息(消息id:${message.message_id}) :` + ret
|
||||
});
|
||||
return msgArray.reverse();
|
||||
}
|
||||
|
||||
function updateMemoryLayer(memoryLayer: Map<string, string[]>, group_id: string, newMessages: string[]) {
|
||||
const currentMemory = memoryLayer.get(group_id) || [];
|
||||
currentMemory.push(...newMessages);
|
||||
if (currentMemory.length > SHORT_TERM_MEMORY_LIMIT) {
|
||||
memoryLayer.set(group_id, currentMemory.slice(-SHORT_TERM_MEMORY_LIMIT));
|
||||
} else {
|
||||
memoryLayer.set(group_id, currentMemory);
|
||||
}
|
||||
}
|
||||
|
||||
async function mergeAndUpdateMemory(existing_memories: string, new_memory: string): Promise<string> {
|
||||
async function mergeAndUpdateMemory(existingMemories: Array<ChatCompletionContentPart>[], newMemory: Array<ChatCompletionContentPart>[]): Promise<string> {
|
||||
const prompt = `
|
||||
你是合并、更新和组织记忆的专家。当提供现有记忆和新信息时,你的任务是合并和更新记忆列表,以反映最准确和最新的信息。你还会得到每个现有记忆与新信息的匹配分数。确保利用这些信息做出明智的决定,决定哪些记忆需要更新或合并。
|
||||
指南:
|
||||
@@ -76,110 +80,163 @@ async function mergeAndUpdateMemory(existing_memories: string, new_memory: strin
|
||||
- 注意区分对应人物的记忆和印象, 不要产生混淆人物的印象和记忆。
|
||||
- 在所有记忆中保持一致且清晰的风格,确保每个条目简洁而信息丰富。
|
||||
- 如果新记忆是现有记忆的变体或扩展,更新现有记忆以反映新信息。
|
||||
以下是任务的详细信息:
|
||||
- 现有记忆:
|
||||
${existing_memories}
|
||||
- 新记忆:
|
||||
${new_memory}`;
|
||||
|
||||
`;
|
||||
const completion = await createChatCompletionWithRetry({
|
||||
messages: [{ role: 'user', content: prompt }],
|
||||
messages: await toSingleRole([
|
||||
{ role: 'user', content: [{ type: 'text', text: prompt }] },
|
||||
{ role: 'user', content: [{ type: 'text', text: '接下来是旧记忆' }] },
|
||||
...(existingMemories.map(msg => ({ role: 'user', content: msg.filter(e => e.type === 'text') }))),
|
||||
{ role: 'user', content: [{ type: 'text', text: '接下来是新记忆' }] },
|
||||
...(newMemory.map(msg => ({ role: 'user', content: msg.filter(e => e.type === 'text') })))]),
|
||||
model: MODEL
|
||||
});
|
||||
|
||||
return completion.choices[0]?.message.content || '';
|
||||
}
|
||||
|
||||
async function generateChatCompletion(content_data: string, url_image?: string[]): Promise<string> {
|
||||
const messages: any = {
|
||||
role: 'user', content: [{
|
||||
type: 'text',
|
||||
text: content_data
|
||||
}]
|
||||
};
|
||||
if (url_image && url_image.length > 0) {
|
||||
url_image.forEach(url => {
|
||||
messages.content.push({
|
||||
type: 'image_url',
|
||||
image_url: {
|
||||
url: url.replace('https://', 'http://')
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
console.log(JSON.stringify(messages, null, 2));
|
||||
async function generateChatCompletion(contentData: Array<ChatCompletionMessageParam>): Promise<string> {
|
||||
const chatCompletion = await createChatCompletionWithRetry({
|
||||
messages: [messages],
|
||||
messages: contentData,
|
||||
model: MODEL
|
||||
});
|
||||
return chatCompletion.choices[0]?.message.content || '';
|
||||
}
|
||||
|
||||
async function updateMemory(group_id: string, newMessages: string) {
|
||||
updateMemoryLayer(shortTermMemory, group_id, [newMessages]);
|
||||
const currentMemory = longTermMemory.get(group_id) || '';
|
||||
const transferCount = memoryTransferCount.get(group_id) || 0;
|
||||
|
||||
if (shortTermMemory.get(group_id)!.length >= SHORT_TERM_MEMORY_LIMIT) {
|
||||
memoryTransferCount.set(group_id, transferCount + 1);
|
||||
if (memoryTransferCount.get(group_id)! >= 1) {
|
||||
const mergedMemory = await mergeAndUpdateMemory(currentMemory, shortTermMemory.get(group_id)!.join('\n'));
|
||||
longTermMemory.set(group_id, mergedMemory);
|
||||
shortTermMemory.set(group_id, []);
|
||||
memoryTransferCount.set(group_id, 0);
|
||||
}
|
||||
async function updateMemory(groupId: string, newMessages: Array<ChatCompletionContentPart>[], core: NapCatCore) {
|
||||
const currentMemory = shortTermMemory.get(groupId) || [];
|
||||
const memCount = await memMutex.runExclusive(() => {
|
||||
const memCount = MemoryCount.get(groupId) || 0;
|
||||
MemoryCount.set(groupId, memCount + 1);
|
||||
return memCount + 1;
|
||||
});
|
||||
console.log('memCount', memCount);
|
||||
currentMemory.push(...newMessages);
|
||||
if (memCount > SHORT_TERM_MEMORY_LIMIT) {
|
||||
await memMutex.runExclusive(async () => {
|
||||
const containsBotName = currentMemory.some(messages => messages.some(msg => msg.type === 'text' && msg.text.includes(core.selfInfo.uin)));
|
||||
if (containsBotName) {
|
||||
const mergedMemory = await mergeAndUpdateMemory(currentMemory, newMessages);
|
||||
longTermMemory.set(groupId, mergedMemory);
|
||||
}
|
||||
shortTermMemory.set(groupId, currentMemory.slice(-SHORT_TERM_MEMORY_LIMIT));
|
||||
MemoryCount.set(groupId, 0);
|
||||
});
|
||||
}
|
||||
shortTermMemory.set(groupId, currentMemory);
|
||||
}
|
||||
|
||||
async function clearShortTermMemory(group_id: string) {
|
||||
shortTermMemory.set(group_id, []);
|
||||
memoryTransferCount.set(group_id, 0);
|
||||
}
|
||||
|
||||
async function clearLongTermMemory(group_id: string) {
|
||||
longTermMemory.set(group_id, '');
|
||||
}
|
||||
|
||||
async function handleClearMemoryCommand(group_id: string, type: 'short' | 'long', action: ActionMap, adapter: string, instance: OB11PluginAdapter) {
|
||||
async function clearMemory(groupId: string, type: 'short' | 'long') {
|
||||
if (type === 'short') {
|
||||
await clearShortTermMemory(group_id);
|
||||
await sendGroupMessage(group_id, '短期上下文已清理', action, adapter, instance);
|
||||
shortTermMemory.set(groupId, []);
|
||||
} else {
|
||||
await clearLongTermMemory(group_id);
|
||||
await sendGroupMessage(group_id, '长期上下文已清理', action, adapter, instance);
|
||||
longTermMemory.set(groupId, '');
|
||||
}
|
||||
}
|
||||
|
||||
async function sendGroupMessage(group_id: string, text: string, action: ActionMap, adapter: string, instance: OB11PluginAdapter) {
|
||||
async function handleClearMemoryCommand(groupId: string, type: 'short' | 'long', action: ActionMap, adapter: string, instance: OB11PluginAdapter) {
|
||||
await clearMemory(groupId, type);
|
||||
const message = type === 'short' ? '短期上下文已清理' : '长期上下文已清理';
|
||||
await sendGroupMessage(groupId, message, action, adapter, instance);
|
||||
}
|
||||
|
||||
async function sendGroupMessage(groupId: string, text: string, action: ActionMap, adapter: string, instance: OB11PluginAdapter) {
|
||||
return await action.get('send_group_msg')?.handle({
|
||||
group_id: String(group_id),
|
||||
group_id: String(groupId),
|
||||
message: text
|
||||
}, adapter, instance.config);
|
||||
}
|
||||
|
||||
async function handleMessage(message: OB11ArrayMessage, adapter: string, action: ActionMap, instance: OB11PluginAdapter): Promise<string> {
|
||||
let msg_string = '';
|
||||
try {
|
||||
msg_string += `${message.sender.nickname}(${message.sender.user_id})发送了消息(消息id:${message.message_id}) :`
|
||||
msg_string += await msg2string(adapter, message.message, message.group_id?.toString()!, action, instance);
|
||||
} catch (error) {
|
||||
if (msg_string == '') {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
return msg_string;
|
||||
async function handleMessage(message: OB11ArrayMessage, adapter: string, action: ActionMap, instance: OB11PluginAdapter) {
|
||||
return await messageToOpenAi(adapter, message.message, message.group_id?.toString()!, action, instance, message);
|
||||
}
|
||||
|
||||
async function handleChatResponse(message: OB11ArrayMessage, msg_string: string, adapter: string, action: ActionMap, instance: OB11PluginAdapter, _core: NapCatCore) {
|
||||
const longTermMemoryString = longTermMemory.get(message.group_id?.toString()!) || '';
|
||||
const shortTermMemoryString = shortTermMemory.get(message.group_id?.toString()!)?.join('\n') || '';
|
||||
const user_info = await action.get('get_group_member_info')?.handle({ group_id: message.group_id?.toString()!, user_id: message.sender.user_id }, adapter, instance.config);
|
||||
const content_data =
|
||||
`请根据下面聊天内容,继续与 ${user_info?.data?.card || user_info?.data?.nickname} 进行对话。${CQCODE},注意回复内容只用输出内容,不要提及此段话,注意一定不要使用markdown,请采用纯文本回复。你的人设:${PROMPT}长时间记忆:\n${longTermMemoryString}\n短时间记忆:\n${shortTermMemoryString}\n当前对话:\n${msg_string}\n}`;
|
||||
const msg_ret = await generateChatCompletion(content_data, message.message.filter(e => e.type === 'image').map(e => e.data.url!));
|
||||
let msg = await sendGroupMessage(message.group_id?.toString()!, msg_ret, action, adapter, instance);
|
||||
chatHot.set(message.group_id?.toString()!, (chatHot.get(message.group_id?.toString()!) || 0) + 3);
|
||||
return msg?.data?.message_id;
|
||||
async function toSingleRole(msg: Array<any>) {
|
||||
let ret = { role: 'user', content: new Array<ChatCompletionContentPart>() };
|
||||
for (const m of msg) {
|
||||
ret.content.push(...m.content as any)
|
||||
}
|
||||
console.log(JSON.stringify(ret, null, 2));
|
||||
return [ret] as Array<ChatCompletionMessageParam>;
|
||||
}
|
||||
|
||||
async function handleChatResponse(message: OB11ArrayMessage, msgArray: Array<ChatCompletionContentPart>, adapter: string, action: ActionMap, instance: OB11PluginAdapter, _core: NapCatCore, reply?: Array<ChatCompletionContentPart>) {
|
||||
const group_id = message.group_id?.toString()!;
|
||||
const longTermMemoryList = longTermMemory.get(group_id) || '';
|
||||
let shortTermMemoryList = shortTermMemory.get(group_id);
|
||||
if (!shortTermMemoryList) {
|
||||
let MemoryShort: Array<ChatCompletionContentPart>[] = [];
|
||||
shortTermMemory.set(group_id, MemoryShort);
|
||||
shortTermMemoryList = MemoryShort;
|
||||
}
|
||||
const prompt = `请根据下面聊天内容,继续与 ${message?.sender?.card || message?.sender?.nickname} 进行对话。${CQCODE},注意回复内容只用输出内容,不要提及此段话,注意一定不要使用markdown,请采用纯文本回复。你的人设:${PROMPT}`
|
||||
let data = shortTermMemoryList.map(msg => ({ role: 'user' as const, content: msg.filter(e => e.type === 'text') }));
|
||||
let contentData: Array<ChatCompletionMessageParam> = await toSingleRole([
|
||||
{ role: 'user', content: [{ type: 'text', text: prompt }] },
|
||||
{ role: 'user', content: [{ type: 'text', text: '接下来是长时间记忆' }] },
|
||||
{ role: 'user', content: [{ type: 'text', text: longTermMemoryList }] },
|
||||
{ role: 'user', content: [{ type: 'text', text: '接下来是短时间记忆' }] },
|
||||
...data,
|
||||
{ role: 'user', content: [{ type: 'text' as const, text: '接下来是本次引用消息' }] },
|
||||
...(reply ? [{ role: 'user' as const, content: reply }] : []),
|
||||
{ role: 'user', content: [{ type: 'text' as const, text: '接下来是当前对话' }] },
|
||||
{ role: 'user', content: msgArray }
|
||||
]);
|
||||
const msgRet = await generateChatCompletion(contentData);
|
||||
const sentMsg = await sendGroupMessage(group_id, msgRet, action, adapter, instance);
|
||||
return { id: sentMsg?.data?.message_id, text: msgRet };
|
||||
}
|
||||
|
||||
async function shouldRespond(message: OB11ArrayMessage, core: NapCatCore, oriMsg: any, currentHot: number, msgArray: Array<ChatCompletionContentPart>, reply?: Array<ChatCompletionContentPart>): Promise<boolean> {
|
||||
if (
|
||||
!message.raw_message.startsWith(BOT_NAME) &&
|
||||
!message.message.find(e => e.type == 'at' && e.data.qq == core.selfInfo.uin) &&
|
||||
oriMsg?.sender.user_id.toString() !== core.selfInfo.uin
|
||||
) {
|
||||
if (currentHot > 0) {
|
||||
if (msgArray.length > 0) {
|
||||
const longTermMemoryList = longTermMemory.get(message.group_id?.toString()!) || '';
|
||||
let shortTermMemoryList = shortTermMemory.get(message.group_id?.toString()!);
|
||||
let prompt = `请根据在群内聊天与 ${message.sender.card || message.sender?.nickname} 发送的聊天消息推测本次消息是否应该回应。自身无关的话题和图片不要回复,尤其减少对图片消息的回复可能性, 注意回复内容只用输出2 - 3个字, 一定注意不想回复请回应不回复三个字即可, 想回复回应回复即可, 你的人设:${PROMPT}`;
|
||||
if (!shortTermMemoryList) {
|
||||
let MemoryShort: Array<ChatCompletionContentPart>[] = [];
|
||||
shortTermMemory.set(message.group_id?.toString()!, MemoryShort);
|
||||
shortTermMemoryList = MemoryShort;
|
||||
}
|
||||
const contentData: Array<ChatCompletionMessageParam> = await toSingleRole([
|
||||
{ role: 'user', content: [{ type: 'text', text: prompt }] },
|
||||
{ role: 'user', content: [{ type: 'text', text: '接下来是长时间记忆' }] },
|
||||
{ role: 'user', content: [{ type: 'text', text: longTermMemoryList }] },
|
||||
{ role: 'user', content: [{ type: 'text', text: '接下来是短时间记忆' }] },
|
||||
|
||||
...(shortTermMemoryList.map(msg => ({ role: 'user' as const, content: msg.filter(e => e.type === 'text') }))),
|
||||
{ role: 'user', content: [{ type: 'text' as const, text: '接下来是本次引用消息' }] },
|
||||
...(reply ? [{ role: 'user' as const, content: reply }] : []),
|
||||
{ role: 'user', content: [{ type: 'text' as const, text: '接下来是当前对话' }] },
|
||||
{ role: 'user', content: msgArray }
|
||||
]);
|
||||
const msgRet = await generateChatCompletion(contentData);
|
||||
if (msgRet.indexOf('不回复') !== -1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
async function handleClearMemory(message: OB11ArrayMessage, action: ActionMap, adapter: string, instance: OB11PluginAdapter) {
|
||||
if (message.raw_message === '/清除短期上下文' && message.sender.user_id.toString() === BOT_ADMIN) {
|
||||
await handleClearMemoryCommand(message.group_id?.toString()!, 'short', action, adapter, instance);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (message.raw_message === '/清除长期上下文' && message.sender.user_id.toString() === BOT_ADMIN) {
|
||||
await handleClearMemoryCommand(message.group_id?.toString()!, 'long', action, adapter, instance);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export const plugin_onmessage = async (
|
||||
@@ -190,47 +247,47 @@ export const plugin_onmessage = async (
|
||||
action: ActionMap,
|
||||
instance: OB11PluginAdapter
|
||||
) => {
|
||||
const current_hot = chatHot.get(message.group_id?.toString()!) || 0;
|
||||
const orimsgid = message.message.find(e => e.type == 'reply')?.data.id;
|
||||
const orimsg = orimsgid ? await action.get('get_msg')?._handle({ message_id: orimsgid }, adapter, instance.config) : undefined;
|
||||
|
||||
if (message.raw_message === '/清除短期上下文') {
|
||||
await handleClearMemoryCommand(message.group_id?.toString()!, 'short', action, adapter, instance);
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.raw_message === '/清除长期上下文') {
|
||||
await handleClearMemoryCommand(message.group_id?.toString()!, 'long', action, adapter, instance);
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
!message.raw_message.startsWith(BOT_NAME) &&
|
||||
!message.message.find(e => e.type == 'at' && e.data.qq == core.selfInfo.uin) &&
|
||||
orimsg?.sender.user_id.toString() !== core.selfInfo.uin
|
||||
) {
|
||||
if (current_hot > 0) {
|
||||
const msg_string = await handleMessage(message, adapter, action, instance);
|
||||
if (msg_string) {
|
||||
const longTermMemoryString = longTermMemory.get(message.group_id?.toString()!) || '';
|
||||
const shortTermMemoryString = shortTermMemory.get(message.group_id?.toString()!)?.join('\n') || '';
|
||||
const user_info = await action.get('get_group_member_info')?.handle({ group_id: message.group_id?.toString()!, user_id: message.sender.user_id }, adapter, instance.config);
|
||||
const content_data =
|
||||
`请根据在群内聊天与 ${user_info?.data?.card || user_info?.data?.nickname} 发送的聊天消息推测本次消息是否应该回应。${CQCODE},注意回复内容只用输出内容,一定注意不想回复请回应不回复三个字即可,想回复回应回复即可,你的人设:${PROMPT}长时间记忆:\n${longTermMemoryString}\n短时间记忆:\n${shortTermMemoryString}\n当前对话:\n${msg_string}\n}`
|
||||
const msg_ret = await generateChatCompletion(content_data, message.message.filter(e => e.type === 'image').map(e => e.data.url!));
|
||||
if (msg_ret.indexOf('不回复') == -1) {
|
||||
return;
|
||||
}
|
||||
const currentHot = await chatHotMutex.runExclusive(async () => {
|
||||
const group_id = message.group_id?.toString()!;
|
||||
const chatHotData = chatHot.get(group_id);
|
||||
const currentTime = Date.now();
|
||||
if (chatHotData) {
|
||||
if (currentTime - chatHotData.usetime > 30000) {
|
||||
chatHot.set(group_id, { count: chatHotData.count, usetime: currentTime, usecount: 0 });
|
||||
} else if (chatHotData.usecount > 2) {
|
||||
chatHot.set(group_id, { count: 0, usetime: currentTime, usecount: 0 });
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
chatHot.set(group_id, { count: 0, usetime: currentTime, usecount: 0 });
|
||||
}
|
||||
return chatHot.get(group_id)!;
|
||||
});
|
||||
console.log('currentHot', currentHot);
|
||||
const oriMsgId = message.message.find(e => e.type == 'reply')?.data.id;
|
||||
const oriMsg = (oriMsgId ? await action.get('get_msg')?._handle({ message_id: oriMsgId }, adapter, instance.config) : undefined) as OB11ArrayMessage | undefined;
|
||||
const msgArray = await handleMessage(message, adapter, action, instance);
|
||||
if (!msgArray) return;
|
||||
await updateMemory(message.group_id?.toString()!, [msgArray], core);
|
||||
|
||||
if (await handleClearMemory(message, action, adapter, instance)) return;
|
||||
|
||||
const oriMsgOpenai = oriMsg ? await handleMessage(oriMsg, adapter, action, instance) : undefined;
|
||||
|
||||
if (await shouldRespond(message, core, oriMsg, currentHot?.count || 0, msgArray, oriMsgOpenai)) {
|
||||
const sentMsg = await handleChatResponse(message, msgArray, adapter, action, instance, core, oriMsgOpenai);
|
||||
await updateMemory(message.group_id?.toString()!, [[{
|
||||
type: 'text',
|
||||
text: `我(群昵称: 乔千)(${core.selfInfo.uin})发送了消息(消息id: ${sentMsg.id}) : ` + sentMsg.text
|
||||
}]], core);
|
||||
await chatHotMutex.runExclusive(() => {
|
||||
const currentTime = Date.now();
|
||||
const group_id = message.group_id?.toString()!;
|
||||
if (currentTime - currentHot.usetime < 40000) {
|
||||
chatHot.set(group_id, { count: currentHot.count + 1, usetime: currentHot.usetime, usecount: currentHot.usecount + 1 });
|
||||
} else {
|
||||
chatHot.set(group_id, { count: 0, usetime: currentTime, usecount: 0 });
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const msg_string = await handleMessage(message, adapter, action, instance);
|
||||
if (!msg_string) return;
|
||||
|
||||
await updateMemory(message.group_id?.toString()!, msg_string);
|
||||
let sended_msg = await handleChatResponse(message, msg_string, adapter, action, instance, core);
|
||||
await updateMemory(message.group_id?.toString()!, `乔千(${core.selfInfo.uin})发送了消息(消息id:${sended_msg}) :` + msg_string);
|
||||
};
|
Reference in New Issue
Block a user