输入“/”快速插入内容

COW插件说明

2024年9月5日修改
插件化初衷
之前未插件化的代码耦合程度高,如果要定制一些个性化功能(如流量控制、接入NovelAI画图平台等),需要了解代码主体,避免影响到其他的功能。多个功能同时存在时,无法调整功能的优先级顺序,功能配置项也非常混乱。
此时插件化应声而出。
插件化: 在保证主体功能是ChatGPT的前提下,我们推荐将主体功能外的功能利用插件的方式实现。
可根据功能需要,下载不同插件。
插件开发成本低,仅需了解插件触发事件,并按照插件定义接口编写插件。
插件化能够自由开关和调整优先级。
每个插件可在插件文件夹内维护独立的配置文件,方便代码的测试和调试,可以在独立的仓库开发插件。
插件安装方法
在本仓库中预置了一些插件,如果要安装其他仓库的插件,有两种方法。
第一种方法是在将下载的插件文件都解压到"plugins"文件夹的一个单独的文件夹,最终插件的代码都位于"plugins/PLUGIN_NAME/*"中。启动程序后,如果插件的目录结构正确,插件会自动被扫描加载。除此以外,注意你还需要安装文件夹中requirements.txt中的依赖。
第二种方法是Godcmd插件,它是预置的管理员插件,能够让程序在运行时就能安装插件,它能够自动安装依赖。
安装插件的命令是"#installp 仓库源记录的插件名/仓库地址"。这是管理员命令,认证方法在这里
安装仓库源记录的插件:#installp sdwebui
安装指定仓库的插件:#installp https://github.com/lanvent/plugin_sdwebui.git
在安装之后,需要执行"#scanp"命令来扫描加载新安装的插件(或者重新启动程序)。
安装插件后需要注意有些插件有自己的配置模板,一般要去掉".template"新建一个配置文件。
插件化实现
插件化实现是在收到消息到发送回复的各个步骤之间插入触发事件实现的。
消息处理过程
在了解插件触发事件前,首先需要了解程序收到消息到发送回复的整个过程。
插件化版本中,消息处理过程可以分为4个步骤:
代码块
1.收到消息 ---> 2.产生回复 ---> 3.包装回复 ---> 4.发送回复
以下是它们的默认处理逻辑(太长不看,可跳到插件编写示例):
注意以下包含的代码是v1.1.0中的片段,已过时,只可用于理解事件,最新的默认代码逻辑请参考chat_channel
1.
收到消息
负责接收用户消息,根据用户的配置,判断本条消息是否触发机器人。如果触发,则会判断该消息的类型(声音、文本、画图命令等),将消息包装成如下的Context交付给下一个步骤。
代码块
class ContextType (Enum):
TEXT = 1 # 文本消息
VOICE = 2 # 音频消息
IMAGE_CREATE = 3 # 创建图片命令
class Context:
def __init__(self, type : ContextType = None , content = None, kwargs = dict()):
self.type = type
self.content = content
self.kwargs = kwargs
def __getitem__(self, key):
return self.kwargs[key]
Context中除了存放消息类型和内容外,还存放了一些与会话相关的参数。
例如,当收到用户私聊消息时,会存放以下的会话参数。
context.kwargs = {'isgroup': False, 'msg': msg, 'receiver': other_user_id, 'session_id': other_user_id}
isgroup: Context是否是群聊消息。
msg: itchat中原始的消息对象。
receiver: 需要回复消息的对象ID。
session_id: 会话ID(一般是发送触发bot消息的用户ID,如果在群聊中并且conf里设置了group_chat_in_one_session,那么此处便是群聊ID)
2.
产生回复
处理消息并产生回复。目前默认处理逻辑是根据Context的类型交付给对应的bot,并产生回复Reply。 如果本步骤没有产生任何回复,那么会跳过之后的所有步骤。
代码块
if context.type == ContextType.TEXT or context.type == ContextType.IMAGE_CREATE:
reply = super().build_reply_content(context.content, context) #文字跟画图交付给chatgpt
elif context.type == ContextType.VOICE: # 声音先进行语音转文字后,修改Context类型为文字后,再交付给chatgpt
cmsg = context['msg']
cmsg.prepare()
file_name = context.content
reply = super().build_voice_to_text(file_name)
if reply.type != ReplyType.ERROR and reply.type != ReplyType.INFO:
context.content = reply.content # 语音转文字后,将文字内容作为新的context
context.type = ContextType.TEXT
reply = super().build_reply_content(context.content, context)
if reply.type == ReplyType.TEXT:
if conf().get('voice_reply_voice'):
reply = super().build_text_to_voice(reply.content)