feat: 群聊上下文记录功能beta

This commit is contained in:
ikechan8370 2023-03-26 18:40:12 +08:00
parent d8999c77e6
commit 6653188a8f
5 changed files with 121 additions and 36 deletions

View file

@ -1,6 +1,6 @@
import plugin from '../../../lib/plugins/plugin.js'
import _ from 'lodash'
import { Config, defaultOpenAIAPI, defaultOpenAIReverseProxy } from '../utils/config.js'
import { Config, defaultOpenAIAPI } from '../utils/config.js'
import { v4 as uuid } from 'uuid'
import delay from 'delay'
import { ChatGPTAPI } from 'chatgpt'
@ -10,10 +10,10 @@ import {
render,
getMessageById,
makeForwardMsg,
tryTimes,
upsertMessage,
randomString,
getDefaultUserSetting, isCN
, formatDate
} from '../utils/common.js'
import { ChatGPTPuppeteer } from '../utils/browser.js'
import { KeyvFile } from 'keyv-file'
@ -50,8 +50,8 @@ const defaultPropmtPrefix = ', a large language model trained by OpenAI. You ans
const newFetch = (url, options = {}) => {
const defaultOptions = Config.proxy
? {
agent: proxy(Config.proxy)
}
agent: proxy(Config.proxy)
}
: {}
const mergedOptions = {
...defaultOptions,
@ -61,7 +61,7 @@ const newFetch = (url, options = {}) => {
return fetch(url, mergedOptions)
}
export class chatgpt extends plugin {
constructor() {
constructor () {
let toggleMode = Config.toggleMode
super({
/** 功能名称 */
@ -73,6 +73,11 @@ export class chatgpt extends plugin {
/** 优先级,数字越小等级越高 */
priority: 1144,
rule: [
{
/** 学习群友聊天 **/
reg: '^[^#][sS]*',
fnc: 'recordChat'
},
{
/** 命令正则匹配 */
reg: '^#chat3[sS]*',
@ -175,7 +180,7 @@ export class chatgpt extends plugin {
* @param e
* @returns {Promise<void>}
*/
async getConversations(e) {
async getConversations (e) {
// todo 根据use返回不同的对话列表
let keys = await redis.keys('CHATGPT:CONVERSATIONS:*')
if (!keys || keys.length === 0) {
@ -198,7 +203,7 @@ export class chatgpt extends plugin {
* @param e
* @returns {Promise<void>}
*/
async destroyConversations(e) {
async destroyConversations (e) {
let ats = e.message.filter(m => m.type === 'at')
let use = await redis.get('CHATGPT:USE')
if (ats.length === 0) {
@ -308,7 +313,7 @@ export class chatgpt extends plugin {
}
}
async endAllConversations(e) {
async endAllConversations (e) {
let use = await redis.get('CHATGPT:USE') || 'api'
let deleted = 0
switch (use) {
@ -362,7 +367,7 @@ export class chatgpt extends plugin {
await this.reply(`结束了${deleted}个用户的对话。`, true)
}
async deleteConversation(e) {
async deleteConversation (e) {
let ats = e.message.filter(m => m.type === 'at')
let use = await redis.get('CHATGPT:USE') || 'api'
if (use !== 'api3') {
@ -420,7 +425,7 @@ export class chatgpt extends plugin {
}
}
async switch2Picture(e) {
async switch2Picture (e) {
let userSetting = await redis.get(`CHATGPT:USER:${e.sender.user_id}`)
if (!userSetting) {
userSetting = getDefaultUserSetting()
@ -433,7 +438,7 @@ export class chatgpt extends plugin {
await this.reply('ChatGPT回复已转换为图片模式')
}
async switch2Text(e) {
async switch2Text (e) {
let userSetting = await redis.get(`CHATGPT:USER:${e.sender.user_id}`)
if (!userSetting) {
userSetting = getDefaultUserSetting()
@ -446,7 +451,7 @@ export class chatgpt extends plugin {
await this.reply('ChatGPT回复已转换为文字模式')
}
async switch2Audio(e) {
async switch2Audio (e) {
if (!Config.ttsSpace) {
await this.reply('您没有配置VITS API请前往锅巴面板进行配置')
return
@ -462,7 +467,7 @@ export class chatgpt extends plugin {
await this.reply('ChatGPT回复已转换为语音模式')
}
async setDefaultRole(e) {
async setDefaultRole (e) {
if (!Config.ttsSpace) {
await this.reply('您没有配置VITS API请前往锅巴面板进行配置')
return
@ -489,7 +494,7 @@ export class chatgpt extends plugin {
* #chatgpt
* @param e oicq传递的事件参数e
*/
async chatgpt(e) {
async chatgpt (e) {
let prompt
if (this.toggleMode === 'at') {
if (!e.msg || e.msg.startsWith('#')) {
@ -522,7 +527,7 @@ export class chatgpt extends plugin {
await this.abstractChat(e, prompt, use)
}
async abstractChat(e, prompt, use) {
async abstractChat (e, prompt, use) {
let userSetting = await redis.get(`CHATGPT:USER:${e.sender.user_id}`)
if (userSetting) {
userSetting = JSON.parse(userSetting)
@ -813,7 +818,7 @@ export class chatgpt extends plugin {
}
}
async chatgpt1(e) {
async chatgpt1 (e) {
if (!Config.allowOtherMode) {
return false
}
@ -832,7 +837,7 @@ export class chatgpt extends plugin {
return true
}
async chatgpt3(e) {
async chatgpt3 (e) {
if (!Config.allowOtherMode) {
return false
}
@ -851,7 +856,7 @@ export class chatgpt extends plugin {
return true
}
async chatglm(e) {
async chatglm (e) {
if (!Config.allowOtherMode) {
return false
}
@ -870,7 +875,7 @@ export class chatgpt extends plugin {
return true
}
async bing(e) {
async bing (e) {
if (!Config.allowOtherMode) {
return false
}
@ -889,7 +894,7 @@ export class chatgpt extends plugin {
return true
}
async renderImage(e, template, content, prompt, quote = [], cache = false) {
async renderImage (e, template, content, prompt, quote = [], cache = false) {
let cacheData = { file: '', cacheUrl: Config.cacheUrl }
if (cache) {
if (Config.cacheEntry) cacheData.file = randomString()
@ -931,7 +936,7 @@ export class chatgpt extends plugin {
}, { retType: Config.quoteReply ? 'base64' : '' }), e.isGroup && Config.quoteReply)
}
async sendMessage(prompt, conversation = {}, use, e) {
async sendMessage (prompt, conversation = {}, use, e) {
if (!conversation) {
conversation = {
timeoutMs: Config.defaultTimeoutMs
@ -965,7 +970,7 @@ export class chatgpt extends plugin {
debug: Config.debug,
cache: cacheOptions,
user: e.sender.user_id,
proxy: Config.proxy,
proxy: Config.proxy
})
// Sydney不实现上下文传递删除上下文索引
delete conversation.clientId
@ -993,6 +998,12 @@ export class chatgpt extends plugin {
let opt = _.cloneDeep(conversation) || {}
opt.toneStyle = Config.toneStyle
opt.context = Config.sydneyContext
if (Config.enableGroupContext && e.isGroup) {
opt.groupId = e.group_id
opt.qq = e.sender.user_id
opt.nickname = e.sender.card
opt.groupName = e.group.name
}
response = await bingAIClient.sendMessage(prompt, opt, (token) => {
reply += token
})
@ -1122,12 +1133,12 @@ export class chatgpt extends plugin {
}
}
async emptyQueue(e) {
async emptyQueue (e) {
await redis.lTrim('CHATGPT:CHAT_QUEUE', 1, 0)
await this.reply('已清空当前等待队列')
}
async removeQueueFirst(e) {
async removeQueueFirst (e) {
let uid = await redis.lPop('CHATGPT:CHAT_QUEUE', 0)
if (!uid) {
await this.reply('当前等待队列为空')
@ -1136,7 +1147,7 @@ export class chatgpt extends plugin {
}
}
async getAllConversations(e) {
async getAllConversations (e) {
const use = await redis.get('CHATGPT:USE')
if (use === 'api3') {
let conversations = await getConversations(e.sender.user_id, newFetch)
@ -1157,7 +1168,7 @@ export class chatgpt extends plugin {
}
}
async joinConversation(e) {
async joinConversation (e) {
let ats = e.message.filter(m => m.type === 'at')
let use = await redis.get('CHATGPT:USE') || 'api'
// if (use !== 'api3') {
@ -1188,7 +1199,7 @@ export class chatgpt extends plugin {
}
}
async attachConversation(e) {
async attachConversation (e) {
const use = await redis.get('CHATGPT:USE')
if (use !== 'api3') {
await this.reply('该功能目前仅支持API3模式')
@ -1205,7 +1216,7 @@ export class chatgpt extends plugin {
}
}
async totalAvailable(e) {
async totalAvailable (e) {
if (!Config.apiKey) {
this.reply('当前未配置OpenAI API key请在锅巴面板或插件配置文件config/config.js中配置。若使用免费的API3则无需关心计费。')
return false
@ -1238,7 +1249,7 @@ export class chatgpt extends plugin {
* @param prompt 问题
* @param conversation 对话
*/
async chatgptBrowserBased(prompt, conversation) {
async chatgptBrowserBased (prompt, conversation) {
let option = { markdown: true }
if (Config['2captchaToken']) {
option.captchaToken = Config['2captchaToken']
@ -1256,4 +1267,26 @@ export class chatgpt extends plugin {
}
return await this.chatGPTApi.sendMessage(prompt, sendMessageOption)
}
async recordChat (e) {
// let gl = await this.e.group.getMemberMap()
if (e.isGroup && e.msg) {
const chat = {
sender: e.sender.card,
senderId: e.sender.user_id,
senderSex: e.sender.sex,
msg: e.msg,
role: e.sender.role,
area: e.sender.area,
age: e.sender.age,
time: formatDate(new Date())
}
// console.log(chat)
await redis.rPush('CHATGPT:LATEST_CHAT_RECORD:' + e.group_id, JSON.stringify(chat))
if (await redis.lLen('CHATGPT:LATEST_CHAT_RECORD:' + e.group_id) > Config.groupContextLength) {
await redis.lPop('CHATGPT:LATEST_CHAT_RECORD:' + e.group_id)
}
}
return false
}
}