mirror of
https://github.com/ikechan8370/chatgpt-plugin.git
synced 2025-12-16 13:27:08 +00:00
feat: 提供了更多的可选配置项,包括确认开关、暗示指令覆盖、触发方式、模型名称和屏蔽词等
This commit is contained in:
parent
35b7630d76
commit
233fc7417c
4 changed files with 97 additions and 20 deletions
60
apps/chat.js
60
apps/chat.js
|
|
@ -9,7 +9,7 @@ import { ChatGPTAPI } from 'chatgpt'
|
|||
import { getMessageById, upsertMessage } from '../utils/common.js'
|
||||
// import puppeteer from '../utils/browser.js'
|
||||
// import showdownKatex from 'showdown-katex'
|
||||
const blockWords = '屏蔽词1,屏蔽词2,屏蔽词3'
|
||||
const blockWords = Config.blockWords
|
||||
const converter = new showdown.Converter({
|
||||
extensions: [
|
||||
// showdownKatex({
|
||||
|
|
@ -38,6 +38,7 @@ mjAPI.start()
|
|||
|
||||
export class chatgpt extends plugin {
|
||||
constructor () {
|
||||
let toggleMode = Config.toggleMode
|
||||
super({
|
||||
/** 功能名称 */
|
||||
name: 'chatgpt',
|
||||
|
|
@ -50,7 +51,7 @@ export class chatgpt extends plugin {
|
|||
rule: [
|
||||
{
|
||||
/** 命令正则匹配 */
|
||||
reg: '^[^#][sS]*',
|
||||
reg: toggleMode === 'at' ? '^[^#][sS]*' : '#chat[sS]*',
|
||||
/** 执行方法 */
|
||||
fnc: 'chatgpt'
|
||||
},
|
||||
|
|
@ -85,6 +86,7 @@ export class chatgpt extends plugin {
|
|||
}
|
||||
]
|
||||
})
|
||||
this.toggleMode = toggleMode
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -177,29 +179,49 @@ export class chatgpt extends plugin {
|
|||
* @param e oicq传递的事件参数e
|
||||
*/
|
||||
async chatgpt (e) {
|
||||
if (!e.msg || e.msg.startsWith('#')) {
|
||||
return
|
||||
let prompt
|
||||
if (this.toggleMode === 'at') {
|
||||
if (!e.msg || e.msg.startsWith('#')) {
|
||||
return false
|
||||
}
|
||||
if (e.isGroup && !e.atme) {
|
||||
return false
|
||||
}
|
||||
prompt = e.msg.trim()
|
||||
} else {
|
||||
prompt = _.trimStart(e.msg.trimStart(), '#chat').trim()
|
||||
if (prompt.length === 0) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if (e.isGroup && !e.atme) {
|
||||
return
|
||||
let completionParams = {}
|
||||
if (Config.model) {
|
||||
completionParams.model = Config.model
|
||||
}
|
||||
|
||||
this.chatGPTApi = new ChatGPTAPI({
|
||||
apiKey: Config.apiKey,
|
||||
debug: false,
|
||||
upsertMessage,
|
||||
getMessageById
|
||||
getMessageById,
|
||||
completionParams,
|
||||
assistantLabel: Config.assistantLabel
|
||||
})
|
||||
|
||||
let prompt = e.msg.trimStart()
|
||||
|
||||
let randomId = uuid()
|
||||
// 队列队尾插入,开始排队
|
||||
await redis.rPush('CHATGPT:CHAT_QUEUE', [randomId])
|
||||
let confirm = await redis.get('CHATGPT:CONFIRM')
|
||||
let confirmOn = confirm === 'on'
|
||||
if (await redis.lIndex('CHATGPT:CHAT_QUEUE', 0) === randomId) {
|
||||
await this.reply('我正在思考如何回复你,请稍等', true, { recallMsg: 8 })
|
||||
if (confirmOn) {
|
||||
await this.reply('我正在思考如何回复你,请稍等', true, { recallMsg: 8 })
|
||||
}
|
||||
} else {
|
||||
let length = await redis.lLen('CHATGPT:CHAT_QUEUE') - 1
|
||||
await this.reply(`我正在思考如何回复你,请稍等,当前队列前方还有${length}个问题`, true, { recallMsg: 8 })
|
||||
if (confirmOn) {
|
||||
let length = await redis.lLen('CHATGPT:CHAT_QUEUE') - 1
|
||||
await this.reply(`我正在思考如何回复你,请稍等,当前队列前方还有${length}个问题`, true, { recallMsg: 8 })
|
||||
}
|
||||
// 开始排队
|
||||
while (true) {
|
||||
if (await redis.lIndex('CHATGPT:CHAT_QUEUE', 0) === randomId) {
|
||||
|
|
@ -234,10 +256,15 @@ export class chatgpt extends plugin {
|
|||
parentMessageId: previousConversation.conversation.parentMessageId
|
||||
}
|
||||
}
|
||||
|
||||
const currentDate = new Date().toISOString().split('T')[0]
|
||||
let defaultPropmtPrefix = 'You answer as concisely as possible for each response (e.g. don’t be verbose). It is very important that you answer as concisely as possible, so please remember this. If you are generating a list, do not have too many items. Keep the number of items short.'
|
||||
let promptPrefix = `You are ${Config.assistantLabel}, a large language model trained by OpenAI. ${Config.promptPrefixOverride || defaultPropmtPrefix}
|
||||
Knowledge cutoff: 2021-09
|
||||
Current date: ${currentDate}`
|
||||
try {
|
||||
let option = {
|
||||
timeoutMs: 120000
|
||||
timeoutMs: 120000,
|
||||
promptPrefix
|
||||
}
|
||||
if (conversation) {
|
||||
option = Object.assign(option, conversation)
|
||||
|
|
@ -254,7 +281,7 @@ export class chatgpt extends plugin {
|
|||
const blockWord = blockWords.split(',').find(word => response.toLowerCase().includes(word.toLowerCase()))
|
||||
if (blockWord) {
|
||||
await this.reply('返回内容存在敏感词,我不想回答你', true)
|
||||
return
|
||||
return false
|
||||
}
|
||||
let userSetting = await redis.get(`CHATGPT:USER:${e.sender.user_id}`)
|
||||
if (userSetting) {
|
||||
|
|
@ -274,7 +301,8 @@ export class chatgpt extends plugin {
|
|||
// ) {
|
||||
await this.reply('内容有点多,我正在奋笔疾书,请再等一会', true, { recallMsg: 5 })
|
||||
option = {
|
||||
timeoutMs: 120000
|
||||
timeoutMs: 120000,
|
||||
promptPrefix
|
||||
}
|
||||
option = Object.assign(option, previousConversation.conversation)
|
||||
const responseAppend = await this.chatGPTApi.sendMessage('Continue', option)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ let helpData = [
|
|||
icon: 'text',
|
||||
title: '#chatgpt文本模式',
|
||||
desc: '机器人以文本形式回答,默认选项'
|
||||
},
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
|
|
@ -55,6 +55,11 @@ let helpData = [
|
|||
title: '#移出chat队列首位',
|
||||
desc: '移出当前对话等待队列中的首位。若前方对话卡死可使用本命令。'
|
||||
},
|
||||
{
|
||||
icon: 'destroy-other',
|
||||
title: '#chatgpt开启/关闭问题确认',
|
||||
desc: '开启或关闭机器人收到消息后的确认回复消息。私聊无效。'
|
||||
},
|
||||
{
|
||||
icon: 'help',
|
||||
title: '#chatgpt帮助',
|
||||
|
|
|
|||
32
apps/management.js
Normal file
32
apps/management.js
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
import plugin from '../../../lib/plugins/plugin.js'
|
||||
|
||||
export class ChatgptManagement extends plugin {
|
||||
constructor (e) {
|
||||
super({
|
||||
name: 'ChatGPT-Plugin管理',
|
||||
dsc: 'ChatGPT-Plugin管理',
|
||||
event: 'message',
|
||||
priority: 500,
|
||||
rule: [
|
||||
{
|
||||
reg: '#chatgpt开启(问题)?确认',
|
||||
fnc: 'turnOnConfirm'
|
||||
},
|
||||
{
|
||||
reg: '#chatgpt关闭(问题)?确认',
|
||||
fnc: 'turnOffConfirm'
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
async turnOnConfirm (e) {
|
||||
await redis.set('CHATGPT:CONFIRM', 'on')
|
||||
await this.reply('已开启消息确认', true)
|
||||
}
|
||||
|
||||
async turnOffConfirm (e) {
|
||||
await redis.set('CHATGPT:CONFIRM', 'off')
|
||||
await this.reply('已关闭消息确认', true)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,24 @@
|
|||
const PROXY = 'http://127.0.0.1:7890'
|
||||
const PROXY = ''
|
||||
const API_KEY = ''
|
||||
|
||||
export const Config = {
|
||||
// 模型名称。如无特殊需求保持默认即可,会使用chatgpt-api库提供的当前可用的最适合的默认值。
|
||||
model: '',
|
||||
// 如果回答包括屏蔽词,就不返回。例如:'屏蔽词1,屏蔽词2,屏蔽词3'
|
||||
blockWords: '',
|
||||
apiKey: API_KEY,
|
||||
// 暂时不支持proxy
|
||||
proxy: PROXY,
|
||||
// 改为true后,全局默认以图片形式回复,并自动发出Continue命令补全回答
|
||||
defaultUsePicture: true,
|
||||
defaultUsePicture: false,
|
||||
// 每个人发起的对话保留时长。超过这个时长没有进行对话,再进行对话将开启新的对话。单位:秒
|
||||
conversationPreserveTime: 0
|
||||
conversationPreserveTime: 0,
|
||||
// 触发方式 可选值:at 或 prefix 。at模式下只有at机器人才会回复。prefix模式下不需要at,但需要添加前缀#chat
|
||||
toggleMode: 'at',
|
||||
// 默认完整值:`You are ${this._assistantLabel}, a large language model trained by OpenAI. You answer as concisely as possible for each response (e.g. don’t be verbose). It is very important that you answer as concisely as possible, so please remember this. If you are generating a list, do not have too many items. Keep the number of items short. Current date: ${currentDate}\n\n
|
||||
// 此项配置会覆盖掉中间部分
|
||||
// 你可以在这里写入你希望AI回答的风格,比如希望优先回答中文,去掉尽可能简洁的要求等
|
||||
promptPrefixOverride: '',
|
||||
// AI认为的自己的名字。
|
||||
assistantLabel: 'ChatGPT'
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue