diff --git a/.gitignore b/.gitignore index e9a9cf30..5679094d 100644 --- a/.gitignore +++ b/.gitignore @@ -17,4 +17,5 @@ scenario/ override.json cookies.json res/announcement_saved -cmdpriv.json \ No newline at end of file +cmdpriv.json +tips.py \ No newline at end of file diff --git a/config-template.py b/config-template.py index 2550e199..7ff08d26 100644 --- a/config-template.py +++ b/config-template.py @@ -33,9 +33,9 @@ mirai_http_api_config = { # }, # "http_proxy": "http://127.0.0.1:12345" # } -# +# # 现已支持反向代理,可以添加reverse_proxy字段以使用反向代理 -# 使用反向代理可以在国内使用OpenAI的API,反向代理的配置请参考 +# 使用反向代理可以在国内使用OpenAI的API,反向代理的配置请参考 # https://github.com/Ice-Hazymoon/openai-scf-proxy # # 反向代理填写示例: @@ -63,7 +63,7 @@ admin_qq = 0 # 情景预设(机器人人格) # 每个会话的预设信息,影响所有会话,无视指令重置 # 可以通过这个字段指定某些情况的回复,可直接用自然语言描述指令 -# 例如: +# 例如: # default_prompt = "如果我之后想获取帮助,请你说“输入!help获取帮助”" # 这样用户在不知所措的时候机器人就会提示其输入!help获取帮助 # 可参考 https://github.com/PlexPt/awesome-chatgpt-prompts-zh @@ -81,14 +81,14 @@ admin_qq = 0 # 例如: # !reset linux-terminal # 若不指定名称,则使用默认情景预设 -# +# # 也可以使用指令: # !default <名称> # 将指定的情景预设设置为默认情景预设 # 例如: # !default linux-terminal # 之后的会话重置时若不指定名称,则使用linux-terminal情景预设 -# +# # 还可以加载文件中的预设文字,使用方法请查看:https://github.com/RockChinQ/QChatGPT/wiki/%E5%8A%9F%E8%83%BD%E4%BD%BF%E7%94%A8#%E9%A2%84%E8%AE%BE%E6%96%87%E5%AD%97 default_prompt = { "default": "如果我之后想获取帮助,请你说“输入!help获取帮助”", @@ -160,7 +160,7 @@ prompt_submit_length = 2048 # OpenAI补全API的参数 # 请在下方填写模型,程序自动选择接口 # 现已支持的模型有: -# +# # 'gpt-4' # 'gpt-4-0314' # 'gpt-4-32k' @@ -276,6 +276,11 @@ report_usage = True logging_level = logging.INFO # 定制帮助消息 -help_message = """此机器人通过调用大型语言模型生成回复,不具有情感。 +help_message = """此机器人通过调用OpenAI的GPT-3大型语言模型生成回复,不具有情感。 你可以用自然语言与其交流,回复的消息中[GPT]开头的为模型生成的语言,[bot]开头的为程序提示。 -欢迎到github.com/RockChinQ/QChatGPT 给个star""" \ No newline at end of file +了解此项目请找QQ 1010553892 联系作者 +请不要用其生成整篇文章或大段代码,因为每次只会向模型提交少部分文字,生成大部分文字会产生偏题、前后矛盾等问题 +每次会话最后一次交互后{}分钟后会自动结束,结束后将开启新会话,如需继续前一次会话请发送 !last 重新开启 +欢迎到github.com/RockChinQ/QChatGPT 给个star + +指令帮助信息请查看: https://github.com/RockChinQ/QChatGPT/wiki/%E5%8A%9F%E8%83%BD%E4%BD%BF%E7%94%A8#%E6%9C%BA%E5%99%A8%E4%BA%BA%E6%8C%87%E4%BB%A4""".format(session_expire_time // 60) diff --git a/main.py b/main.py index 4f35bac0..c20c080c 100644 --- a/main.py +++ b/main.py @@ -108,6 +108,7 @@ def reset_logging(): # 临时函数,用于加载config和上下文,未来统一放在config类 def load_config(): + logging.info("检查config模块完整性.") # 完整性校验 is_integrity = True config_template = importlib.import_module('config-template') @@ -119,7 +120,7 @@ def load_config(): is_integrity = False if not is_integrity: - logging.warning("配置文件不完整,请依据config-template.py检查config.py") + logging.warning("配置文件不完整,您可以依据config-template.py检查config.py") # 检查override.json覆盖 if os.path.exists("override.json"): @@ -132,13 +133,31 @@ def load_config(): logging.error("无法覆写配置[{}]为[{}],该配置不存在,请检查override.json是否正确".format(key, override_json[key])) if not is_integrity: - logging.warning("以上配置已被设为默认值,将在5秒后继续启动... ") - time.sleep(5) + logging.warning("以上配置已被设为默认值,将在3秒后继续启动... ") + time.sleep(3) # 存进上下文 pkg.utils.context.set_config(config) +def complete_tips(): + """根据tips-custom-template模块补全tips模块的属性""" + is_integrity = True + logging.info("检查tips模块完整性.") + tips_template = importlib.import_module('tips-custom-template') + tips = importlib.import_module('tips') + for key in dir(tips_template): + if not key.startswith("__") and not hasattr(tips, key): + setattr(tips, key, getattr(tips_template, key)) + logging.warning("[{}]不存在".format(key)) + is_integrity = False + + if not is_integrity: + logging.warning("tips模块不完整,您可以依据tips-custom-template.py检查tips.py") + logging.warning("以上配置已被设为默认值,将在3秒后继续启动... ") + time.sleep(3) + + def start(first_time_init=False): """启动流程,reload之后会被执行""" @@ -378,6 +397,10 @@ def check_file(): if not os.path.exists("cmdpriv.json"): shutil.copy("res/templates/cmdpriv-template.json", "cmdpriv.json") + # 检查tips_custom + if not os.path.exists("tips.py"): + shutil.copy("tips-custom-template.py", "tips.py") + # 检查temp目录 if not os.path.exists("temp/"): os.mkdir("temp/") @@ -401,6 +424,9 @@ def main(): load_config() config = pkg.utils.context.get_config() + # 检查tips模块 + complete_tips() + # 配置线程池 from pkg.utils import ThreadCtl thread_ctl = ThreadCtl( diff --git a/override-all.json b/override-all.json index 88bc890a..32f7aaac 100644 --- a/override-all.json +++ b/override-all.json @@ -63,14 +63,12 @@ "font_path": "", "retry_times": 3, "hide_exce_info_to_user": false, - "alter_tip_message": "出错了,请稍后再试", "sys_pool_num": 8, "admin_pool_num": 2, "user_pool_num": 6, "session_expire_time": 1200, "rate_limitation": 60, "rate_limit_strategy": "wait", - "rate_limit_drop_tip": "本分钟对话次数超过限速次数,此对话被丢弃", "upgrade_dependencies": true, "report_usage": true, "logging_level": 20, diff --git a/pkg/qqbot/cmds/aamgr.py b/pkg/qqbot/cmds/aamgr.py index 65066ce7..d380a9c9 100644 --- a/pkg/qqbot/cmds/aamgr.py +++ b/pkg/qqbot/cmds/aamgr.py @@ -9,6 +9,9 @@ import json __command_list__ = {} + +import tips as tips_custom + """命令树 结构: @@ -262,7 +265,7 @@ def execute(context: Context) -> list: # 检查权限 if ctx.privilege < node['privilege']: - raise CommandPrivilegeError('权限不足: {}'.format(path)) + raise CommandPrivilegeError(tips_custom.command_admin_message+"{}".format(path)) # 执行 execed, reply = node['cls'].process(ctx) @@ -275,7 +278,7 @@ def execute(context: Context) -> list: path = path + '.' + ctx.crt_command except KeyError: traceback.print_exc() - raise CommandPrivilegeError('找不到指令: {}'.format(path)) + raise CommandPrivilegeError(tips_custom.command_err_message+"{}".format(path)) def register_all(): diff --git a/pkg/qqbot/cmds/session/reset.py b/pkg/qqbot/cmds/session/reset.py index 5e5ba683..87be5a9f 100644 --- a/pkg/qqbot/cmds/session/reset.py +++ b/pkg/qqbot/cmds/session/reset.py @@ -1,4 +1,5 @@ from ..aamgr import AbstractCommandNode, Context +import tips as tips_custom import pkg.openai.session import pkg.utils.context @@ -22,12 +23,12 @@ class ResetCommand(AbstractCommandNode): if len(params) == 0: pkg.openai.session.get_session(session_name).reset(explicit=True) - reply = ["[bot]会话已重置"] + reply = [tips_custom.command_reset_message] else: try: import pkg.openai.dprompt as dprompt pkg.openai.session.get_session(session_name).reset(explicit=True, use_prompt=params[0]) - reply = ["[bot]会话已重置,使用场景预设:{}".format(dprompt.mode_inst().get_full_name(params[0]))] + reply = [tips_custom.command_reset_name_message+"{}".format(dprompt.mode_inst().get_full_name(params[0]))] except Exception as e: reply = ["[bot]会话重置失败:{}".format(e)] diff --git a/pkg/qqbot/command.py b/pkg/qqbot/command.py index dbb7bd35..5b3e3ebf 100644 --- a/pkg/qqbot/command.py +++ b/pkg/qqbot/command.py @@ -54,7 +54,7 @@ def process_command(session_name: str, text_message: str, mgr, config, try: reply = cmdmgr.execute(context) except cmdmgr.CommandPrivilegeError as e: - reply = ["[bot]err:{}".format(e)] + reply = ["{}".format(e)] return reply except Exception as e: diff --git a/pkg/qqbot/manager.py b/pkg/qqbot/manager.py index 77634ecd..b8b9a71f 100644 --- a/pkg/qqbot/manager.py +++ b/pkg/qqbot/manager.py @@ -19,6 +19,7 @@ import pkg.utils.context import pkg.plugin.host as plugin_host import pkg.plugin.models as plugin_models +import tips as tips_custom # 检查消息是否符合泛响应匹配机制 @@ -264,7 +265,7 @@ class QQBotManager: if failed == self.retry: pkg.openai.session.get_session('person_{}'.format(event.sender.id)).release_response_lock() self.notify_admin("{} 请求超时".format("person_{}".format(event.sender.id))) - reply = ["[bot]err:请求超时"] + reply = [tips_custom.reply_message] if reply: return self.send(event, reply, check_quote=False) @@ -304,7 +305,7 @@ class QQBotManager: if failed == self.retry: pkg.openai.session.get_session('group_{}'.format(event.group.id)).release_response_lock() self.notify_admin("{} 请求超时".format("group_{}".format(event.group.id))) - replys = ["[bot]err:请求超时"] + replys = [tips_custom.replys_message] return replys diff --git a/pkg/qqbot/message.py b/pkg/qqbot/message.py index b1eb6119..4fb6b991 100644 --- a/pkg/qqbot/message.py +++ b/pkg/qqbot/message.py @@ -7,6 +7,7 @@ import pkg.openai.session import pkg.plugin.host as plugin_host import pkg.plugin.models as plugin_models import pkg.qqbot.blob as blob +import tips as tips_custom def handle_exception(notify_admin: str = "", set_reply: str = "") -> list: @@ -14,7 +15,7 @@ def handle_exception(notify_admin: str = "", set_reply: str = "") -> list: import config pkg.utils.context.get_qqbot_manager().notify_admin(notify_admin) if config.hide_exce_info_to_user: - return [config.alter_tip_message] if config.alter_tip_message else [] + return [tips_custom.alter_tip_message] if tips_custom.alter_tip_message else [] else: return [set_reply] diff --git a/pkg/qqbot/process.py b/pkg/qqbot/process.py index 4106c9f7..bf45c8a9 100644 --- a/pkg/qqbot/process.py +++ b/pkg/qqbot/process.py @@ -27,6 +27,7 @@ import pkg.plugin.models as plugin_models import pkg.qqbot.ignore as ignore import pkg.qqbot.banlist as banlist import pkg.qqbot.blob as blob +import tips as tips_custom processing = [] @@ -118,7 +119,8 @@ def process_message(launcher_type: str, launcher_id: int, text_message: str, mes if config.rate_limit_strategy == "drop": if ratelimit.is_reach_limit(session_name): logging.info("根据限速策略丢弃[{}]消息: {}".format(session_name, text_message)) - return MessageChain(["[bot]"+config.rate_limit_drop_tip]) if config.rate_limit_drop_tip != "" else [] + + return MessageChain(["[bot]"+tips_custom.rate_limit_drop_tip]) if tips_custom.rate_limit_drop_tip != "" else [] before = time.time() # 触发插件事件 diff --git a/pkg/utils/reloader.py b/pkg/utils/reloader.py index f0df8b29..f116e088 100644 --- a/pkg/utils/reloader.py +++ b/pkg/utils/reloader.py @@ -41,15 +41,20 @@ def reload_all(notify=True): importlib.reload(__import__('config')) importlib.reload(__import__('main')) importlib.reload(__import__('banlist')) + importlib.reload(__import__('tips')) context.context = this_context # 重载插件 import plugins walk(plugins) + # 初始化相关文件 + main.check_file() + # 执行启动流程 logging.info("执行程序启动流程") main.load_config() + main.complete_tips() context.get_thread_ctl().reload( admin_pool_num=context.get_config().admin_pool_num, user_pool_num=context.get_config().user_pool_num diff --git a/tips-custom-template.py b/tips-custom-template.py new file mode 100644 index 00000000..f2ebe57c --- /dev/null +++ b/tips-custom-template.py @@ -0,0 +1,50 @@ +import config + +# ---------------------------------------------花里胡哨参数--------------------------------------------- +# ---原config.py开始-- + +# 消息处理出错时向用户发送的提示信息,仅当hide_exce_info_to_user为True时生效 +# 设置为空字符串时,不发送提示信息 +# config.py,line:232 +# pkg/qqbot/message.py,line:19 +alter_tip_message = '出错了,请稍后再试' + +# drop策略时,超过限速均值时,丢弃的对话的提示信息,仅当rate_limitation_strategy为"drop"时生效 +# 若设置为空字符串,则不发送提示信息 +# config.py,line:265 +# pkg/qqbot/process.py,line:122 +rate_limit_drop_tip = "本分钟对话次数超过限速次数,此对话被丢弃" + +# 指令!help帮助消息 +# config.py,line:279 +# pkg/qqbot/process.py,line:122 +help_message = """【可自定义】 +此机器人通过调用OpenAI的GPT-3大型语言模型生成回复,不具有情感。 +你可以用自然语言与其交流,回复的消息中[GPT]开头的为模型生成的语言,[bot]开头的为程序提示。 +了解此项目请找QQ 1010553892 联系作者 +请不要用其生成整篇文章或大段代码,因为每次只会向模型提交少部分文字,生成大部分文字会产生偏题、前后矛盾等问题 +每次会话最后一次交互后{}分钟后会自动结束,结束后将开启新会话,如需继续前一次会话请发送 !last 重新开启 +欢迎到github.com/RockChinQ/QChatGPT 给个star +指令帮助信息请查看: https://github.com/RockChinQ/QChatGPT/wiki/%E5%8A%9F%E8%83%BD%E4%BD%BF%E7%94%A8#%E6%9C%BA%E5%99%A8%E4%BA%BA%E6%8C%87%E4%BB%A4""".format( + config.session_expire_time // 60) + +# ---原config.py结束-- + +# QChatGPT/pkg/qqbot/manager.py +# 私聊消息超时提示,line:271 +reply_message = "私聊请求超时" +# 群聊消息超时提示,line:310 +replys_message = "群聊请求超时" + +# 指令权限不足/无效提示 +# QChatGPT/pkg/qqbot/command.py,line:57 +# 更改代码 +# QChatGPT/pkg/qqbot/cmds/mgr.py +# line:266,279 +command_admin_message = "权限不足: " +command_err_message = "指令执行出错:" + +# 会话重置提示 +# pkg/qqbot/cmds/session/reset.py,line:25,31 +command_reset_message = "[bot]会话已重置" +command_reset_name_message = "[bot]会话已重置,使用场景预设:"