diff --git a/.gitignore b/.gitignore
index e9a9cf3..5679094 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/README.md b/README.md
index c3d0f09..e895a6f 100644
--- a/README.md
+++ b/README.md
@@ -126,6 +126,12 @@
- 目前已支持正向代理访问接口
- 详细请查看config.py中的`openai_config`的说明
+
+✅支持自定义提示内容
+
+ - 允许用户自定义报错、帮助等提示信息
+ - 请查看`tips.py`
+
详情请查看[Wiki功能使用页](https://github.com/RockChinQ/QChatGPT/wiki/%E5%8A%9F%E8%83%BD%E4%BD%BF%E7%94%A8#%E5%8A%9F%E8%83%BD%E7%82%B9%E5%88%97%E4%B8%BE)
diff --git a/config-template.py b/config-template.py
index 2550e19..fb905f3 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'
@@ -226,11 +226,6 @@ retry_times = 3
# 设置为False时,向用户及管理员发送错误详细信息
hide_exce_info_to_user = False
-# 消息处理出错时向用户发送的提示信息
-# 仅当hide_exce_info_to_user为True时生效
-# 设置为空字符串时,不发送提示信息
-alter_tip_message = '出错了,请稍后再试'
-
# 线程池相关配置
# 该参数决定机器人可以同时处理几个人的消息,超出线程池数量的请求会被阻塞,不会被丢弃
# 如果你不清楚该参数的意义,请不要更改
@@ -259,11 +254,6 @@ rate_limitation = 60
# - "drop": 此分钟内,若对话次数超过限速次数,则丢弃之后的对话,每自然分钟重置
rate_limit_strategy = "wait"
-# drop策略时,超过限速均值时,丢弃的对话的提示信息
-# 仅当rate_limitation_strategy为"drop"时生效
-# 若设置为空字符串,则不发送提示信息
-rate_limit_drop_tip = "本分钟对话次数超过限速次数,此对话被丢弃"
-
# 是否在启动时进行依赖库更新
upgrade_dependencies = True
@@ -274,8 +264,3 @@ report_usage = True
# 日志级别
logging_level = logging.INFO
-
-# 定制帮助消息
-help_message = """此机器人通过调用大型语言模型生成回复,不具有情感。
-你可以用自然语言与其交流,回复的消息中[GPT]开头的为模型生成的语言,[bot]开头的为程序提示。
-欢迎到github.com/RockChinQ/QChatGPT 给个star"""
\ No newline at end of file
diff --git a/main.py b/main.py
index 4f35bac..b4dc40f 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之后会被执行"""
@@ -356,12 +375,6 @@ def stop():
def check_file():
- # 配置文件存在性校验
- if not os.path.exists('config.py'):
- shutil.copy('config-template.py', 'config.py')
- print('请先在config.py中填写配置')
- sys.exit(0)
-
# 检查是否有banlist.py,如果没有就把banlist-template.py复制一份
if not os.path.exists('banlist.py'):
shutil.copy('res/templates/banlist-template.py', 'banlist.py')
@@ -378,6 +391,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/")
@@ -388,6 +405,12 @@ def check_file():
if not os.path.exists(path):
os.mkdir(path)
+ # 配置文件存在性校验
+ if not os.path.exists('config.py'):
+ shutil.copy('config-template.py', 'config.py')
+ print('请先在config.py中填写配置')
+ sys.exit(0)
+
def main():
# 初始化相关文件
@@ -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 88bc890..d60a580 100644
--- a/override-all.json
+++ b/override-all.json
@@ -63,16 +63,13 @@
"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,
- "help_message": "此机器人通过调用大型语言模型生成回复,不具有情感。\n你可以用自然语言与其交流,回复的消息中[GPT]开头的为模型生成的语言,[bot]开头的为程序提示。\n欢迎到github.com/RockChinQ/QChatGPT 给个star"
+ "logging_level": 20
}
\ No newline at end of file
diff --git a/pkg/qqbot/cmds/aamgr.py b/pkg/qqbot/cmds/aamgr.py
index 65066ce..d380a9c 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 5e5ba68..87be5a9 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/cmds/system/cmds.py b/pkg/qqbot/cmds/system/cmds.py
deleted file mode 100644
index 40d1cc2..0000000
--- a/pkg/qqbot/cmds/system/cmds.py
+++ /dev/null
@@ -1,39 +0,0 @@
-from ..aamgr import AbstractCommandNode, Context, __command_list__
-
-
-@AbstractCommandNode.register(
- parent=None,
- name="cmd",
- description="显示指令列表",
- usage="!help\n!help <指令名称>",
- aliases=[],
- privilege=1
-)
-class CmdCommand(AbstractCommandNode):
- @classmethod
- def process(cls, ctx: Context) -> tuple[bool, list]:
- command_list = __command_list__
-
- reply = []
-
- if len(ctx.params) == 0:
- reply_str = "[bot]当前所有指令:\n\n"
-
- # 遍历顶级指令
- for key in command_list:
- command = command_list[key]
- if command['parent'] is None:
- reply_str += "!{} - {}\n".format(key, command['description'])
-
- reply_str += "\n请使用 !cmd <指令名称> 来查看指令的详细信息"
-
- reply = [reply_str]
- else:
- command_name = ctx.params[0]
- if command_name in command_list:
- reply = [command_list[command_name]['cls'].help()]
- else:
- reply = ["[bot]指令 {} 不存在".format(command_name)]
-
- return True, reply
-
\ No newline at end of file
diff --git a/pkg/qqbot/cmds/system/help.py b/pkg/qqbot/cmds/system/help.py
index 72e06d7..798cbf5 100644
--- a/pkg/qqbot/cmds/system/help.py
+++ b/pkg/qqbot/cmds/system/help.py
@@ -12,8 +12,13 @@ from ..aamgr import AbstractCommandNode, Context
class HelpCommand(AbstractCommandNode):
@classmethod
def process(cls, ctx: Context) -> tuple[bool, list]:
+ import tips
+ reply = ["[bot] "+tips.help_message + "\n请输入 !cmd 查看指令列表"]
+
+ # 警告config.help_message过时
import config
- reply = [(config.help_message) + "\n请输入 !cmds 查看指令列表"]
+ if hasattr(config, "help_message"):
+ reply[0] += "\n\n警告:config.py中的help_message已过时,不再生效,请使用tips.py中的help_message替代"
return True, reply
\ No newline at end of file
diff --git a/pkg/qqbot/command.py b/pkg/qqbot/command.py
index dbb7bd3..5b3e3eb 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 77634ec..b8b9a71 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 b1eb611..4fb6b99 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 4106c9f..bf45c8a 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 f0df8b2..f116e08 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/res/wiki/功能使用.md b/res/wiki/功能使用.md
index 9f96dfe..493e303 100644
--- a/res/wiki/功能使用.md
+++ b/res/wiki/功能使用.md
@@ -96,6 +96,12 @@
- “丢弃”策略:此分钟内对话次数达到限制时,丢弃之后的对话
- 详细请查看config.py中的相关配置
+
+✅支持自定义提示内容
+
+ - 允许用户自定义报错、帮助等提示信息
+ - 请查看`tips.py`
+
## 限制
diff --git a/tips-custom-template.py b/tips-custom-template.py
new file mode 100644
index 0000000..f61adcb
--- /dev/null
+++ b/tips-custom-template.py
@@ -0,0 +1,31 @@
+import config
+# ---------------------------------------------自定义提示语---------------------------------------------
+
+# 消息处理出错时向用户发送的提示信息,仅当config.py中hide_exce_info_to_user为True时生效
+# 设置为空字符串时,不发送提示信息
+alter_tip_message = '[bot]err:出错了,请稍后再试'
+
+# drop策略时,超过限速均值时,丢弃的对话的提示信息,仅当config.py中rate_limitation_strategy为"drop"时生效
+# 若设置为空字符串,则不发送提示信息
+rate_limit_drop_tip = "本分钟对话次数超过限速次数,此对话被丢弃"
+
+# 指令!help帮助消息
+# config.py,line:279
+# pkg/qqbot/process.py,line:122
+help_message = """此机器人通过调用大型语言模型生成回复,不具有情感。
+你可以用自然语言与其交流,回复的消息中[GPT]开头的为模型生成的语言,[bot]开头的为程序提示。
+欢迎到github.com/RockChinQ/QChatGPT 给个star"""
+
+# 私聊消息超时提示
+reply_message = "[bot]err:请求超时"
+# 群聊消息超时提示
+replys_message = "[bot]err:请求超时"
+
+# 指令权限不足提示
+command_admin_message = "[bot]err:权限不足: "
+# 指令无效提示
+command_err_message = "[bot]err:指令执行出错:"
+
+# 会话重置提示
+command_reset_message = "[bot]:会话已重置"
+command_reset_name_message = "[bot]:会话已重置,使用场景预设:"