mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-06-04 12:56:02 +00:00
Compare commits
42 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dce134d08d | ||
|
|
cca471d068 | ||
|
|
ddb211b74a | ||
|
|
cef70751ff | ||
|
|
2d2219fc6e | ||
|
|
514a6b4192 | ||
|
|
7a552b3434 | ||
|
|
ecebd1b0e0 | ||
|
|
8dc34d2a88 | ||
|
|
d52644ceec | ||
|
|
3052510591 | ||
|
|
777a5617db | ||
|
|
e17c1087e9 | ||
|
|
633695175a | ||
|
|
9e78bf3d21 | ||
|
|
43aa68a55d | ||
|
|
b8308f8c57 | ||
|
|
466bfbddeb | ||
|
|
b6da07b225 | ||
|
|
2f2159239a | ||
|
|
67d1ca8a65 | ||
|
|
497a393e83 | ||
|
|
782c0e22ea | ||
|
|
2932fc6dfd | ||
|
|
0a9eab2113 | ||
|
|
50a673a8ec | ||
|
|
9e25d0f9e4 | ||
|
|
23cd7be711 | ||
|
|
025b9e33f1 | ||
|
|
bab2f64913 | ||
|
|
b00e09aa9c | ||
|
|
0b109fdc7a | ||
|
|
018fea2ddb | ||
|
|
f8a3cc4352 | ||
|
|
6ab853acc1 | ||
|
|
e825dea02f | ||
|
|
cf8740d16e | ||
|
|
9c4809e26f | ||
|
|
0a232fd9ef | ||
|
|
23016a0791 | ||
|
|
cdcc67ff23 | ||
|
|
92274bfc34 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -25,3 +25,4 @@ bin/
|
|||||||
.vscode
|
.vscode
|
||||||
test_*
|
test_*
|
||||||
venv/
|
venv/
|
||||||
|
hugchat.json
|
||||||
15
README.md
15
README.md
@@ -7,18 +7,22 @@
|
|||||||
[English](README_en.md) | 简体中文
|
[English](README_en.md) | 简体中文
|
||||||
|
|
||||||
[](https://github.com/RockChinQ/QChatGPT/releases/latest)
|
[](https://github.com/RockChinQ/QChatGPT/releases/latest)
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
> 2023/4/27 正在对纯Python实现的QQ登录框架、YAML配置文件、异步编程等功能进行概念验证,欢迎体验[LightQChat](https://github.com/RockChinQ/LightQChat)项目
|
|
||||||
> 2023/4/24 支持使用go-cqhttp登录QQ,请查看[此文档](https://github.com/RockChinQ/QChatGPT/wiki/go-cqhttp%E9%85%8D%E7%BD%AE)
|
> 2023/4/24 支持使用go-cqhttp登录QQ,请查看[此文档](https://github.com/RockChinQ/QChatGPT/wiki/go-cqhttp%E9%85%8D%E7%BD%AE)
|
||||||
> 2023/3/18 现已支持GPT-4 API(内测),请查看`config-template.py`中的`completion_api_params`
|
> 2023/3/18 现已支持GPT-4 API(内测),请查看`config-template.py`中的`completion_api_params`
|
||||||
> 2023/3/15 逆向库已支持New Bing,使用方法查看[插件文档](https://github.com/RockChinQ/revLibs)
|
> 2023/3/15 逆向库已支持New Bing,使用方法查看[插件文档](https://github.com/RockChinQ/revLibs)
|
||||||
|
|
||||||
|
|
||||||
|
**QChatGPT需要Python版本>=3.9**
|
||||||
- 到[项目Wiki](https://github.com/RockChinQ/QChatGPT/wiki)可了解项目详细信息
|
- 到[项目Wiki](https://github.com/RockChinQ/QChatGPT/wiki)可了解项目详细信息
|
||||||
- 官方交流、答疑群: 656285629
|
- 官方交流、答疑群: 656285629
|
||||||
- **进群提问前请您`确保`已经找遍文档和issue均无法解决**
|
- **进群提问前请您`确保`已经找遍文档和issue均无法解决**
|
||||||
- 社区群(内有一键部署包、图形化界面等资源): 362515018
|
- 社区群(内有一键部署包、图形化界面等资源): 362515018
|
||||||
- QQ频道机器人见[QQChannelChatGPT](https://github.com/Soulter/QQChannelChatGPT)
|
- QQ频道机器人见[QQChannelChatGPT](https://github.com/Soulter/QQChannelChatGPT)
|
||||||
- 欢迎各种形式的贡献,请查看[贡献指引](CONTRIBUTING.md)
|
- 欢迎各种形式的贡献,请查看[贡献指引](CONTRIBUTING.md)
|
||||||
|
- 购买ChatGPT账号: [此链接](http://fk.kimi.asia)
|
||||||
|
|
||||||
## 🍺模型适配一览
|
## 🍺模型适配一览
|
||||||
|
|
||||||
@@ -33,7 +37,7 @@
|
|||||||
- ChatGPT网页版GPT-3.5模型, 由[插件](https://github.com/RockChinQ/revLibs)接入
|
- ChatGPT网页版GPT-3.5模型, 由[插件](https://github.com/RockChinQ/revLibs)接入
|
||||||
- ChatGPT网页版GPT-4模型, 目前需要ChatGPT Plus订阅, 由[插件](https://github.com/RockChinQ/revLibs)接入
|
- ChatGPT网页版GPT-4模型, 目前需要ChatGPT Plus订阅, 由[插件](https://github.com/RockChinQ/revLibs)接入
|
||||||
- New Bing逆向库, 由[插件](https://github.com/RockChinQ/revLibs)接入
|
- New Bing逆向库, 由[插件](https://github.com/RockChinQ/revLibs)接入
|
||||||
- HuggingChat, 由[插件](https://github.com/RockChinQ/revLibs)接入, 无需账号,仅支持英文
|
- HuggingChat, 由[插件](https://github.com/RockChinQ/revLibs)接入, 仅支持英文
|
||||||
|
|
||||||
### 故事续写
|
### 故事续写
|
||||||
|
|
||||||
@@ -161,6 +165,9 @@
|
|||||||
|
|
||||||
### - 注册OpenAI账号
|
### - 注册OpenAI账号
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>点此查看步骤</summary>
|
||||||
|
|
||||||
> 若您要直接使用非OpenAI的模型(如New Bing),可跳过此步骤,直接进行之后的部署,完成后按照相关插件的文档进行配置即可
|
> 若您要直接使用非OpenAI的模型(如New Bing),可跳过此步骤,直接进行之后的部署,完成后按照相关插件的文档进行配置即可
|
||||||
|
|
||||||
参考以下文章自行注册
|
参考以下文章自行注册
|
||||||
@@ -171,6 +178,8 @@
|
|||||||
注册成功后请前往[个人中心查看](https://beta.openai.com/account/api-keys)api_key
|
注册成功后请前往[个人中心查看](https://beta.openai.com/account/api-keys)api_key
|
||||||
完成注册后,使用以下自动化或手动部署步骤
|
完成注册后,使用以下自动化或手动部署步骤
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
### - 自动化部署
|
### - 自动化部署
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
@@ -284,7 +293,7 @@ python3 main.py
|
|||||||
|
|
||||||
### 更多
|
### 更多
|
||||||
|
|
||||||
欢迎提交新的插件
|
[插件列表](https://github.com/stars/RockChinQ/lists/qchatgpt-%E6%8F%92%E4%BB%B6),欢迎提出issue以提交新的插件
|
||||||
|
|
||||||
- [revLibs](https://github.com/RockChinQ/revLibs) - 将ChatGPT网页版接入此项目,关于[官方接口和网页版有什么区别](https://github.com/RockChinQ/QChatGPT/wiki/%E5%AE%98%E6%96%B9%E6%8E%A5%E5%8F%A3%E3%80%81ChatGPT%E7%BD%91%E9%A1%B5%E7%89%88%E3%80%81ChatGPT-API%E5%8C%BA%E5%88%AB)
|
- [revLibs](https://github.com/RockChinQ/revLibs) - 将ChatGPT网页版接入此项目,关于[官方接口和网页版有什么区别](https://github.com/RockChinQ/QChatGPT/wiki/%E5%AE%98%E6%96%B9%E6%8E%A5%E5%8F%A3%E3%80%81ChatGPT%E7%BD%91%E9%A1%B5%E7%89%88%E3%80%81ChatGPT-API%E5%8C%BA%E5%88%AB)
|
||||||
- [Switcher](https://github.com/RockChinQ/Switcher) - 支持通过指令切换使用的模型
|
- [Switcher](https://github.com/RockChinQ/Switcher) - 支持通过指令切换使用的模型
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
English | [简体中文](README.md)
|
English | [简体中文](README.md)
|
||||||
|
|
||||||
[](https://github.com/RockChinQ/QChatGPT/releases/latest)
|
[](https://github.com/RockChinQ/QChatGPT/releases/latest)
|
||||||
|

|
||||||
|
|
||||||
- Refer to [Wiki](https://github.com/RockChinQ/QChatGPT/wiki) to get further information.
|
- Refer to [Wiki](https://github.com/RockChinQ/QChatGPT/wiki) to get further information.
|
||||||
- Official QQ group: 656285629
|
- Official QQ group: 656285629
|
||||||
@@ -27,7 +28,7 @@ English | [简体中文](README.md)
|
|||||||
- ChatGPT website edition (GPT-3.5), see [revLibs plugin](https://github.com/RockChinQ/revLibs)
|
- ChatGPT website edition (GPT-3.5), see [revLibs plugin](https://github.com/RockChinQ/revLibs)
|
||||||
- ChatGPT website edition (GPT-4), ChatGPT plus subscription required, see [revLibs plugin](https://github.com/RockChinQ/revLibs)
|
- ChatGPT website edition (GPT-4), ChatGPT plus subscription required, see [revLibs plugin](https://github.com/RockChinQ/revLibs)
|
||||||
- New Bing, see [revLibs plugin](https://github.com/RockChinQ/revLibs)
|
- New Bing, see [revLibs plugin](https://github.com/RockChinQ/revLibs)
|
||||||
- HuggingChat, see [revLibs plugin](https://github.com/RockChinQ/revLibs), no accounts required, English only
|
- HuggingChat, see [revLibs plugin](https://github.com/RockChinQ/revLibs), English only
|
||||||
|
|
||||||
### Story
|
### Story
|
||||||
|
|
||||||
|
|||||||
@@ -195,16 +195,22 @@ encourage_sponsor_at_start = True
|
|||||||
# 注意:较大的prompt_submit_length会导致OpenAI账户额度消耗更快
|
# 注意:较大的prompt_submit_length会导致OpenAI账户额度消耗更快
|
||||||
prompt_submit_length = 2048
|
prompt_submit_length = 2048
|
||||||
|
|
||||||
|
# 是否在token超限报错时自动重置会话
|
||||||
|
# 可在tips.py中编辑提示语
|
||||||
|
auto_reset = True
|
||||||
|
|
||||||
# OpenAI补全API的参数
|
# OpenAI补全API的参数
|
||||||
# 请在下方填写模型,程序自动选择接口
|
# 请在下方填写模型,程序自动选择接口
|
||||||
# 现已支持的模型有:
|
# 现已支持的模型有:
|
||||||
#
|
#
|
||||||
# 'gpt-4'
|
# 'gpt-4'
|
||||||
# 'gpt-4-0314'
|
# 'gpt-4-0613'
|
||||||
# 'gpt-4-32k'
|
# 'gpt-4-32k'
|
||||||
# 'gpt-4-32k-0314'
|
# 'gpt-4-32k-0613'
|
||||||
# 'gpt-3.5-turbo'
|
# 'gpt-3.5-turbo'
|
||||||
# 'gpt-3.5-turbo-0301'
|
# 'gpt-3.5-turbo-16k'
|
||||||
|
# 'gpt-3.5-turbo-0613'
|
||||||
|
# 'gpt-3.5-turbo-16k-0613'
|
||||||
# 'text-davinci-003'
|
# 'text-davinci-003'
|
||||||
# 'text-davinci-002'
|
# 'text-davinci-002'
|
||||||
# 'code-davinci-002'
|
# 'code-davinci-002'
|
||||||
|
|||||||
248
main.py
248
main.py
@@ -134,127 +134,139 @@ def start(first_time_init=False):
|
|||||||
|
|
||||||
known_exception_caught = False
|
known_exception_caught = False
|
||||||
try:
|
try:
|
||||||
|
|
||||||
sh = reset_logging()
|
|
||||||
pkg.utils.context.context['logger_handler'] = sh
|
|
||||||
|
|
||||||
# 检查是否设置了管理员
|
|
||||||
if not (hasattr(config, 'admin_qq') and config.admin_qq != 0):
|
|
||||||
# logging.warning("未设置管理员QQ,管理员权限指令及运行告警将无法使用,如需设置请修改config.py中的admin_qq字段")
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
config.admin_qq = int(input("未设置管理员QQ,管理员权限指令及运行告警将无法使用,请输入管理员QQ号: "))
|
|
||||||
# 写入到文件
|
|
||||||
|
|
||||||
# 读取文件
|
|
||||||
config_file_str = ""
|
|
||||||
with open("config.py", "r", encoding="utf-8") as f:
|
|
||||||
config_file_str = f.read()
|
|
||||||
# 替换
|
|
||||||
config_file_str = config_file_str.replace("admin_qq = 0", "admin_qq = " + str(config.admin_qq))
|
|
||||||
# 写入
|
|
||||||
with open("config.py", "w", encoding="utf-8") as f:
|
|
||||||
f.write(config_file_str)
|
|
||||||
|
|
||||||
print("管理员QQ已设置,如需修改请修改config.py中的admin_qq字段")
|
|
||||||
time.sleep(4)
|
|
||||||
break
|
|
||||||
except ValueError:
|
|
||||||
print("请输入数字")
|
|
||||||
|
|
||||||
import pkg.openai.manager
|
|
||||||
import pkg.database.manager
|
|
||||||
import pkg.openai.session
|
|
||||||
import pkg.qqbot.manager
|
|
||||||
import pkg.openai.dprompt
|
|
||||||
import pkg.qqbot.cmds.aamgr
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
pkg.openai.dprompt.register_all()
|
|
||||||
pkg.qqbot.cmds.aamgr.register_all()
|
sh = reset_logging()
|
||||||
pkg.qqbot.cmds.aamgr.apply_privileges()
|
pkg.utils.context.context['logger_handler'] = sh
|
||||||
|
|
||||||
|
# 检查是否设置了管理员
|
||||||
|
if not (hasattr(config, 'admin_qq') and config.admin_qq != 0):
|
||||||
|
# logging.warning("未设置管理员QQ,管理员权限指令及运行告警将无法使用,如需设置请修改config.py中的admin_qq字段")
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
config.admin_qq = int(input("未设置管理员QQ,管理员权限指令及运行告警将无法使用,请输入管理员QQ号: "))
|
||||||
|
# 写入到文件
|
||||||
|
|
||||||
|
# 读取文件
|
||||||
|
config_file_str = ""
|
||||||
|
with open("config.py", "r", encoding="utf-8") as f:
|
||||||
|
config_file_str = f.read()
|
||||||
|
# 替换
|
||||||
|
config_file_str = config_file_str.replace("admin_qq = 0", "admin_qq = " + str(config.admin_qq))
|
||||||
|
# 写入
|
||||||
|
with open("config.py", "w", encoding="utf-8") as f:
|
||||||
|
f.write(config_file_str)
|
||||||
|
|
||||||
|
print("管理员QQ已设置,如需修改请修改config.py中的admin_qq字段")
|
||||||
|
time.sleep(4)
|
||||||
|
break
|
||||||
|
except ValueError:
|
||||||
|
print("请输入数字")
|
||||||
|
|
||||||
|
import pkg.openai.manager
|
||||||
|
import pkg.database.manager
|
||||||
|
import pkg.openai.session
|
||||||
|
import pkg.qqbot.manager
|
||||||
|
import pkg.openai.dprompt
|
||||||
|
import pkg.qqbot.cmds.aamgr
|
||||||
|
|
||||||
|
try:
|
||||||
|
pkg.openai.dprompt.register_all()
|
||||||
|
pkg.qqbot.cmds.aamgr.register_all()
|
||||||
|
pkg.qqbot.cmds.aamgr.apply_privileges()
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(e)
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
|
# 配置openai api_base
|
||||||
|
if "reverse_proxy" in config.openai_config and config.openai_config["reverse_proxy"] is not None:
|
||||||
|
import openai
|
||||||
|
openai.api_base = config.openai_config["reverse_proxy"]
|
||||||
|
|
||||||
|
# 主启动流程
|
||||||
|
database = pkg.database.manager.DatabaseManager()
|
||||||
|
|
||||||
|
database.initialize_database()
|
||||||
|
|
||||||
|
openai_interact = pkg.openai.manager.OpenAIInteract(config.openai_config['api_key'])
|
||||||
|
|
||||||
|
# 加载所有未超时的session
|
||||||
|
pkg.openai.session.load_sessions()
|
||||||
|
|
||||||
|
# 初始化qq机器人
|
||||||
|
qqbot = pkg.qqbot.manager.QQBotManager(first_time_init=first_time_init)
|
||||||
|
|
||||||
|
# 加载插件
|
||||||
|
import pkg.plugin.host
|
||||||
|
pkg.plugin.host.load_plugins()
|
||||||
|
|
||||||
|
pkg.plugin.host.initialize_plugins()
|
||||||
|
|
||||||
|
if first_time_init: # 不是热重载之后的启动,则启动新的bot线程
|
||||||
|
|
||||||
|
import mirai.exceptions
|
||||||
|
|
||||||
|
def run_bot_wrapper():
|
||||||
|
global known_exception_caught
|
||||||
|
try:
|
||||||
|
logging.info("使用账号: {}".format(qqbot.bot_account_id))
|
||||||
|
qqbot.adapter.run_sync()
|
||||||
|
except TypeError as e:
|
||||||
|
if str(e).__contains__("argument 'debug'"):
|
||||||
|
logging.error(
|
||||||
|
"连接bot失败:{}, 解决方案: https://github.com/RockChinQ/QChatGPT/issues/82".format(e))
|
||||||
|
known_exception_caught = True
|
||||||
|
elif str(e).__contains__("As of 3.10, the *loop*"):
|
||||||
|
logging.error(
|
||||||
|
"Websockets版本过低:{}, 解决方案: https://github.com/RockChinQ/QChatGPT/issues/5".format(e))
|
||||||
|
known_exception_caught = True
|
||||||
|
|
||||||
|
except websockets.exceptions.InvalidStatus as e:
|
||||||
|
logging.error(
|
||||||
|
"mirai-api-http端口无法使用:{}, 解决方案: https://github.com/RockChinQ/QChatGPT/issues/22".format(
|
||||||
|
e))
|
||||||
|
known_exception_caught = True
|
||||||
|
except mirai.exceptions.NetworkError as e:
|
||||||
|
logging.error("连接mirai-api-http失败:{}, 请检查是否已按照文档启动mirai".format(e))
|
||||||
|
known_exception_caught = True
|
||||||
|
except Exception as e:
|
||||||
|
if str(e).__contains__("404"):
|
||||||
|
logging.error(
|
||||||
|
"mirai-api-http端口无法使用:{}, 解决方案: https://github.com/RockChinQ/QChatGPT/issues/22".format(
|
||||||
|
e))
|
||||||
|
known_exception_caught = True
|
||||||
|
elif str(e).__contains__("signal only works in main thread"):
|
||||||
|
logging.error(
|
||||||
|
"hypercorn异常:{}, 解决方案: https://github.com/RockChinQ/QChatGPT/issues/86".format(
|
||||||
|
e))
|
||||||
|
known_exception_caught = True
|
||||||
|
elif str(e).__contains__("did not receive a valid HTTP"):
|
||||||
|
logging.error(
|
||||||
|
"mirai-api-http端口无法使用:{}, 解决方案: https://github.com/RockChinQ/QChatGPT/issues/22".format(
|
||||||
|
e))
|
||||||
|
else:
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
logging.error(
|
||||||
|
"捕捉到未知异常:{}, 请前往 https://github.com/RockChinQ/QChatGPT/issues 查找或提issue".format(e))
|
||||||
|
known_exception_caught = True
|
||||||
|
raise e
|
||||||
|
finally:
|
||||||
|
time.sleep(12)
|
||||||
|
threading.Thread(
|
||||||
|
target=run_bot_wrapper
|
||||||
|
).start()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error(e)
|
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
if isinstance(e, KeyboardInterrupt):
|
||||||
# 配置openai api_base
|
logging.info("程序被用户中止")
|
||||||
if "reverse_proxy" in config.openai_config and config.openai_config["reverse_proxy"] is not None:
|
sys.exit(0)
|
||||||
import openai
|
elif isinstance(e, SyntaxError):
|
||||||
openai.api_base = config.openai_config["reverse_proxy"]
|
logging.error("配置文件存在语法错误,请检查配置文件:\n1. 是否存在中文符号\n2. 是否已按照文件中的说明填写正确")
|
||||||
|
sys.exit(1)
|
||||||
# 主启动流程
|
else:
|
||||||
database = pkg.database.manager.DatabaseManager()
|
logging.error("初始化失败:{}".format(e))
|
||||||
|
sys.exit(1)
|
||||||
database.initialize_database()
|
|
||||||
|
|
||||||
openai_interact = pkg.openai.manager.OpenAIInteract(config.openai_config['api_key'])
|
|
||||||
|
|
||||||
# 加载所有未超时的session
|
|
||||||
pkg.openai.session.load_sessions()
|
|
||||||
|
|
||||||
# 初始化qq机器人
|
|
||||||
qqbot = pkg.qqbot.manager.QQBotManager(first_time_init=first_time_init)
|
|
||||||
|
|
||||||
# 加载插件
|
|
||||||
import pkg.plugin.host
|
|
||||||
pkg.plugin.host.load_plugins()
|
|
||||||
|
|
||||||
pkg.plugin.host.initialize_plugins()
|
|
||||||
|
|
||||||
if first_time_init: # 不是热重载之后的启动,则启动新的bot线程
|
|
||||||
|
|
||||||
import mirai.exceptions
|
|
||||||
|
|
||||||
def run_bot_wrapper():
|
|
||||||
global known_exception_caught
|
|
||||||
try:
|
|
||||||
logging.info("使用账号: {}".format(qqbot.bot_account_id))
|
|
||||||
qqbot.adapter.run_sync()
|
|
||||||
except TypeError as e:
|
|
||||||
if str(e).__contains__("argument 'debug'"):
|
|
||||||
logging.error(
|
|
||||||
"连接bot失败:{}, 解决方案: https://github.com/RockChinQ/QChatGPT/issues/82".format(e))
|
|
||||||
known_exception_caught = True
|
|
||||||
elif str(e).__contains__("As of 3.10, the *loop*"):
|
|
||||||
logging.error(
|
|
||||||
"Websockets版本过低:{}, 解决方案: https://github.com/RockChinQ/QChatGPT/issues/5".format(e))
|
|
||||||
known_exception_caught = True
|
|
||||||
|
|
||||||
except websockets.exceptions.InvalidStatus as e:
|
|
||||||
logging.error(
|
|
||||||
"mirai-api-http端口无法使用:{}, 解决方案: https://github.com/RockChinQ/QChatGPT/issues/22".format(
|
|
||||||
e))
|
|
||||||
known_exception_caught = True
|
|
||||||
except mirai.exceptions.NetworkError as e:
|
|
||||||
logging.error("连接mirai-api-http失败:{}, 请检查是否已按照文档启动mirai".format(e))
|
|
||||||
known_exception_caught = True
|
|
||||||
except Exception as e:
|
|
||||||
if str(e).__contains__("404"):
|
|
||||||
logging.error(
|
|
||||||
"mirai-api-http端口无法使用:{}, 解决方案: https://github.com/RockChinQ/QChatGPT/issues/22".format(
|
|
||||||
e))
|
|
||||||
known_exception_caught = True
|
|
||||||
elif str(e).__contains__("signal only works in main thread"):
|
|
||||||
logging.error(
|
|
||||||
"hypercorn异常:{}, 解决方案: https://github.com/RockChinQ/QChatGPT/issues/86".format(
|
|
||||||
e))
|
|
||||||
known_exception_caught = True
|
|
||||||
elif str(e).__contains__("did not receive a valid HTTP"):
|
|
||||||
logging.error(
|
|
||||||
"mirai-api-http端口无法使用:{}, 解决方案: https://github.com/RockChinQ/QChatGPT/issues/22".format(
|
|
||||||
e))
|
|
||||||
else:
|
|
||||||
import traceback
|
|
||||||
traceback.print_exc()
|
|
||||||
logging.error(
|
|
||||||
"捕捉到未知异常:{}, 请前往 https://github.com/RockChinQ/QChatGPT/issues 查找或提issue".format(e))
|
|
||||||
known_exception_caught = True
|
|
||||||
raise e
|
|
||||||
finally:
|
|
||||||
time.sleep(12)
|
|
||||||
threading.Thread(
|
|
||||||
target=run_bot_wrapper
|
|
||||||
).start()
|
|
||||||
finally:
|
finally:
|
||||||
# 判断若是Windows,输出选择模式可能会暂停程序的警告
|
# 判断若是Windows,输出选择模式可能会暂停程序的警告
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
|
|||||||
@@ -53,6 +53,7 @@
|
|||||||
"inappropriate_message_tips": "[百度云]请珍惜机器人,当前返回内容不合规",
|
"inappropriate_message_tips": "[百度云]请珍惜机器人,当前返回内容不合规",
|
||||||
"encourage_sponsor_at_start": true,
|
"encourage_sponsor_at_start": true,
|
||||||
"prompt_submit_length": 2048,
|
"prompt_submit_length": 2048,
|
||||||
|
"auto_reset": true,
|
||||||
"completion_api_params": {
|
"completion_api_params": {
|
||||||
"model": "gpt-3.5-turbo",
|
"model": "gpt-3.5-turbo",
|
||||||
"temperature": 0.9,
|
"temperature": 0.9,
|
||||||
|
|||||||
@@ -20,11 +20,14 @@ COMPLETION_MODELS = {
|
|||||||
|
|
||||||
CHAT_COMPLETION_MODELS = {
|
CHAT_COMPLETION_MODELS = {
|
||||||
'gpt-3.5-turbo',
|
'gpt-3.5-turbo',
|
||||||
'gpt-3.5-turbo-0301',
|
'gpt-3.5-turbo-16k',
|
||||||
|
'gpt-3.5-turbo-0613',
|
||||||
|
'gpt-3.5-turbo-16k-0613',
|
||||||
|
# 'gpt-3.5-turbo-0301',
|
||||||
'gpt-4',
|
'gpt-4',
|
||||||
'gpt-4-0314',
|
'gpt-4-0613',
|
||||||
'gpt-4-32k',
|
'gpt-4-32k',
|
||||||
'gpt-4-32k-0314'
|
'gpt-4-32k-0613'
|
||||||
}
|
}
|
||||||
|
|
||||||
EDIT_MODELS = {
|
EDIT_MODELS = {
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ def load_sessions():
|
|||||||
|
|
||||||
|
|
||||||
# 获取指定名称的session,如果不存在则创建一个新的
|
# 获取指定名称的session,如果不存在则创建一个新的
|
||||||
def get_session(session_name: str):
|
def get_session(session_name: str) -> 'Session':
|
||||||
global sessions
|
global sessions
|
||||||
if session_name not in sessions:
|
if session_name not in sessions:
|
||||||
sessions[session_name] = Session(session_name)
|
sessions[session_name] = Session(session_name)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ def config_operation(cmd, params):
|
|||||||
config = pkg.utils.context.get_config()
|
config = pkg.utils.context.get_config()
|
||||||
reply_str = ""
|
reply_str = ""
|
||||||
if len(params) == 0:
|
if len(params) == 0:
|
||||||
reply = ["[bot]err:请输入配置项"]
|
reply = ["[bot]err:请输入!cmd cfg查看使用方法"]
|
||||||
else:
|
else:
|
||||||
cfg_name = params[0]
|
cfg_name = params[0]
|
||||||
if cfg_name == 'all':
|
if cfg_name == 'all':
|
||||||
@@ -26,45 +26,61 @@ def config_operation(cmd, params):
|
|||||||
else:
|
else:
|
||||||
reply_str += "{}: {}\n".format(cfg, getattr(config, cfg))
|
reply_str += "{}: {}\n".format(cfg, getattr(config, cfg))
|
||||||
reply = [reply_str]
|
reply = [reply_str]
|
||||||
elif cfg_name in dir(config):
|
|
||||||
if len(params) == 1:
|
|
||||||
# 按照配置项类型进行格式化
|
|
||||||
if isinstance(getattr(config, cfg_name), str):
|
|
||||||
reply_str = "[bot]配置项{}: \"{}\"\n".format(cfg_name, getattr(config, cfg_name))
|
|
||||||
elif isinstance(getattr(config, cfg_name), dict):
|
|
||||||
reply_str = "[bot]配置项{}: {}\n".format(cfg_name,
|
|
||||||
json.dumps(getattr(config, cfg_name),
|
|
||||||
ensure_ascii=False, indent=4))
|
|
||||||
else:
|
|
||||||
reply_str = "[bot]配置项{}: {}\n".format(cfg_name, getattr(config, cfg_name))
|
|
||||||
reply = [reply_str]
|
|
||||||
else:
|
|
||||||
cfg_value = " ".join(params[1:])
|
|
||||||
# 类型转换,如果是json则转换为字典
|
|
||||||
if cfg_value == 'true':
|
|
||||||
cfg_value = True
|
|
||||||
elif cfg_value == 'false':
|
|
||||||
cfg_value = False
|
|
||||||
elif cfg_value.isdigit():
|
|
||||||
cfg_value = int(cfg_value)
|
|
||||||
elif cfg_value.startswith('{') and cfg_value.endswith('}'):
|
|
||||||
cfg_value = json.loads(cfg_value)
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
cfg_value = float(cfg_value)
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# 检查类型是否匹配
|
|
||||||
if isinstance(getattr(config, cfg_name), type(cfg_value)):
|
|
||||||
setattr(config, cfg_name, cfg_value)
|
|
||||||
pkg.utils.context.set_config(config)
|
|
||||||
reply = ["[bot]配置项{}修改成功".format(cfg_name)]
|
|
||||||
else:
|
|
||||||
reply = ["[bot]err:配置项{}类型不匹配".format(cfg_name)]
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
reply = ["[bot]err:未找到配置项 {}".format(cfg_name)]
|
cfg_entry_path = cfg_name.split('.')
|
||||||
|
|
||||||
|
try:
|
||||||
|
if len(params) == 1:
|
||||||
|
cfg_entry = getattr(config, cfg_entry_path[0])
|
||||||
|
if len(cfg_entry_path) > 1:
|
||||||
|
for i in range(1, len(cfg_entry_path)):
|
||||||
|
cfg_entry = cfg_entry[cfg_entry_path[i]]
|
||||||
|
|
||||||
|
if isinstance(cfg_entry, str):
|
||||||
|
reply_str = "[bot]配置项{}: \"{}\"\n".format(cfg_name, cfg_entry)
|
||||||
|
elif isinstance(cfg_entry, dict):
|
||||||
|
reply_str = "[bot]配置项{}: {}\n".format(cfg_name,
|
||||||
|
json.dumps(cfg_entry,
|
||||||
|
ensure_ascii=False, indent=4))
|
||||||
|
else:
|
||||||
|
reply_str = "[bot]配置项{}: {}\n".format(cfg_name, cfg_entry)
|
||||||
|
reply = [reply_str]
|
||||||
|
else:
|
||||||
|
cfg_value = " ".join(params[1:])
|
||||||
|
# 类型转换,如果是json则转换为字典
|
||||||
|
# if cfg_value == 'true':
|
||||||
|
# cfg_value = True
|
||||||
|
# elif cfg_value == 'false':
|
||||||
|
# cfg_value = False
|
||||||
|
# elif cfg_value.isdigit():
|
||||||
|
# cfg_value = int(cfg_value)
|
||||||
|
# elif cfg_value.startswith('{') and cfg_value.endswith('}'):
|
||||||
|
# cfg_value = json.loads(cfg_value)
|
||||||
|
# else:
|
||||||
|
# try:
|
||||||
|
# cfg_value = float(cfg_value)
|
||||||
|
# except ValueError:
|
||||||
|
# pass
|
||||||
|
cfg_value = eval(cfg_value)
|
||||||
|
|
||||||
|
cfg_entry = getattr(config, cfg_entry_path[0])
|
||||||
|
if len(cfg_entry_path) > 1:
|
||||||
|
for i in range(1, len(cfg_entry_path) - 1):
|
||||||
|
cfg_entry = cfg_entry[cfg_entry_path[i]]
|
||||||
|
if isinstance(cfg_entry[cfg_entry_path[-1]], type(cfg_value)):
|
||||||
|
cfg_entry[cfg_entry_path[-1]] = cfg_value
|
||||||
|
reply = ["[bot]配置项{}修改成功".format(cfg_name)]
|
||||||
|
else:
|
||||||
|
reply = ["[bot]err:配置项{}类型不匹配".format(cfg_name)]
|
||||||
|
else:
|
||||||
|
setattr(config, cfg_entry_path[0], cfg_value)
|
||||||
|
reply = ["[bot]配置项{}修改成功".format(cfg_name)]
|
||||||
|
except AttributeError:
|
||||||
|
reply = ["[bot]err:未找到配置项 {}".format(cfg_name)]
|
||||||
|
except ValueError:
|
||||||
|
reply = ["[bot]err:未找到配置项 {}".format(cfg_name)]
|
||||||
|
# else:
|
||||||
|
# reply = ["[bot]err:未找到配置项 {}".format(cfg_name)]
|
||||||
|
|
||||||
return reply
|
return reply
|
||||||
|
|
||||||
|
|||||||
@@ -102,6 +102,9 @@ class QQBotManager:
|
|||||||
|
|
||||||
enable_banlist = False
|
enable_banlist = False
|
||||||
|
|
||||||
|
enable_private = True
|
||||||
|
enable_group = True
|
||||||
|
|
||||||
ban_person = []
|
ban_person = []
|
||||||
ban_group = []
|
ban_group = []
|
||||||
|
|
||||||
@@ -242,6 +245,11 @@ class QQBotManager:
|
|||||||
self.ban_group = banlist.group
|
self.ban_group = banlist.group
|
||||||
logging.info("加载禁用列表: person: {}, group: {}".format(self.ban_person, self.ban_group))
|
logging.info("加载禁用列表: person: {}, group: {}".format(self.ban_person, self.ban_group))
|
||||||
|
|
||||||
|
if hasattr(banlist, "enable_private"):
|
||||||
|
self.enable_private = banlist.enable_private
|
||||||
|
if hasattr(banlist, "enable_group"):
|
||||||
|
self.enable_group = banlist.enable_group
|
||||||
|
|
||||||
config = pkg.utils.context.get_config()
|
config = pkg.utils.context.get_config()
|
||||||
if os.path.exists("sensitive.json") \
|
if os.path.exists("sensitive.json") \
|
||||||
and config.sensitive_word_filter is not None \
|
and config.sensitive_word_filter is not None \
|
||||||
@@ -269,7 +277,9 @@ class QQBotManager:
|
|||||||
import config
|
import config
|
||||||
reply = ''
|
reply = ''
|
||||||
|
|
||||||
if event.sender.id == self.bot_account_id:
|
if not self.enable_private:
|
||||||
|
logging.debug("已在banlist.py中禁用所有私聊")
|
||||||
|
elif event.sender.id == self.bot_account_id:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
if Image in event.message_chain:
|
if Image in event.message_chain:
|
||||||
@@ -342,8 +352,10 @@ class QQBotManager:
|
|||||||
replys = [tips_custom.replys_message]
|
replys = [tips_custom.replys_message]
|
||||||
|
|
||||||
return replys
|
return replys
|
||||||
|
|
||||||
if Image in event.message_chain:
|
if not self.enable_group:
|
||||||
|
logging.debug("已在banlist.py中禁用所有群聊")
|
||||||
|
elif Image in event.message_chain:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
if At(self.bot_account_id) in event.message_chain and response_at(event.group.id):
|
if At(self.bot_account_id) in event.message_chain and response_at(event.group.id):
|
||||||
|
|||||||
@@ -114,8 +114,12 @@ def process_normal_message(text_message: str, mgr, config, launcher_type: str,
|
|||||||
reply = handle_exception("{}会话调用API失败:{}".format(session_name, e),
|
reply = handle_exception("{}会话调用API失败:{}".format(session_name, e),
|
||||||
"[bot]err:RateLimitError,请重试或联系作者,或等待修复")
|
"[bot]err:RateLimitError,请重试或联系作者,或等待修复")
|
||||||
except openai.error.InvalidRequestError as e:
|
except openai.error.InvalidRequestError as e:
|
||||||
reply = handle_exception("{}API调用参数错误:{}\n".format(
|
if config.auto_reset and "This model's maximum context length is" in str(e):
|
||||||
session_name, e), "[bot]err:API调用参数错误,请联系管理员,或等待修复")
|
session.reset()
|
||||||
|
reply = [tips_custom.session_auto_reset_message]
|
||||||
|
else:
|
||||||
|
reply = handle_exception("{}API调用参数错误:{}\n".format(
|
||||||
|
session_name, e), "[bot]err:API调用参数错误,请联系管理员,或等待修复")
|
||||||
except openai.error.ServiceUnavailableError as e:
|
except openai.error.ServiceUnavailableError as e:
|
||||||
reply = handle_exception("{}API调用服务不可用:{}".format(session_name, e), "[bot]err:API调用服务不可用,请重试或联系管理员,或等待修复")
|
reply = handle_exception("{}API调用服务不可用:{}".format(session_name, e), "[bot]err:API调用服务不可用,请重试或联系管理员,或等待修复")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ def process_message(launcher_type: str, launcher_id: int, text_message: str, mes
|
|||||||
import config
|
import config
|
||||||
if config.income_msg_check:
|
if config.income_msg_check:
|
||||||
if mgr.reply_filter.is_illegal(text_message):
|
if mgr.reply_filter.is_illegal(text_message):
|
||||||
return MessageChain(Plain("[bot] 你的提问中有不合适的内容, 请更换措辞~"))
|
return MessageChain(Plain("[bot] 消息中存在不合适的内容, 请更换措辞"))
|
||||||
|
|
||||||
pkg.openai.session.get_session(session_name).acquire_response_lock()
|
pkg.openai.session.get_session(session_name).acquire_response_lock()
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -34,13 +34,18 @@ def pull_latest(repo_path: str) -> bool:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def is_newer_ignored_bugfix_ver(new_tag: str, old_tag: str):
|
def is_newer(new_tag: str, old_tag: str):
|
||||||
"""判断版本是否更新,忽略第四位版本"""
|
"""判断版本是否更新,忽略第四位版本和第一位版本"""
|
||||||
if new_tag == old_tag:
|
if new_tag == old_tag:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
new_tag = new_tag.split(".")
|
new_tag = new_tag.split(".")
|
||||||
old_tag = old_tag.split(".")
|
old_tag = old_tag.split(".")
|
||||||
|
|
||||||
|
# 判断主版本是否相同
|
||||||
|
if new_tag[0] != old_tag[0]:
|
||||||
|
return False
|
||||||
|
|
||||||
if len(new_tag) < 4:
|
if len(new_tag) < 4:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -97,7 +102,7 @@ def update_all(cli: bool = False) -> bool:
|
|||||||
else:
|
else:
|
||||||
print("更新日志: {}".format(rls_notes))
|
print("更新日志: {}".format(rls_notes))
|
||||||
|
|
||||||
if latest_rls == {} and not is_newer_ignored_bugfix_ver(latest_tag_name, current_tag): # 没有新版本
|
if latest_rls == {} and not is_newer(latest_tag_name, current_tag): # 没有新版本
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# 下载最新版本的zip到temp目录
|
# 下载最新版本的zip到temp目录
|
||||||
@@ -254,7 +259,7 @@ def is_new_version_available() -> bool:
|
|||||||
latest_tag_name = rls['tag_name']
|
latest_tag_name = rls['tag_name']
|
||||||
break
|
break
|
||||||
|
|
||||||
return is_newer_ignored_bugfix_ver(latest_tag_name, current_tag)
|
return is_newer(latest_tag_name, current_tag)
|
||||||
|
|
||||||
|
|
||||||
def get_rls_notes() -> list:
|
def get_rls_notes() -> list:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
requests~=2.28.1
|
requests~=2.31.0
|
||||||
openai~=0.27.6
|
openai~=0.27.8
|
||||||
dulwich~=0.21.5
|
dulwich~=0.21.5
|
||||||
colorlog~=6.6.0
|
colorlog~=6.6.0
|
||||||
yiri-mirai~=0.2.7
|
yiri-mirai~=0.2.7
|
||||||
|
|||||||
@@ -4,5 +4,11 @@
|
|||||||
"time": "2023-04-24 16:05:20",
|
"time": "2023-04-24 16:05:20",
|
||||||
"timestamp": 1682323520,
|
"timestamp": 1682323520,
|
||||||
"content": "现已支持使用go-cqhttp替换mirai作为QQ登录框架, 请更新并查看 https://github.com/RockChinQ/QChatGPT/wiki/go-cqhttp%E9%85%8D%E7%BD%AE"
|
"content": "现已支持使用go-cqhttp替换mirai作为QQ登录框架, 请更新并查看 https://github.com/RockChinQ/QChatGPT/wiki/go-cqhttp%E9%85%8D%E7%BD%AE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"time": "2023-05-21 17:33:18",
|
||||||
|
"timestamp": 1684661598,
|
||||||
|
"content": "NewBing不再需要鉴权,若您正在使用revLibs逆向库插件,请立即使用!plugin update revLibs命令更新插件到最新版。"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -1,3 +1,13 @@
|
|||||||
|
# 是否处理群聊消息
|
||||||
|
# 为False时忽略所有群聊消息
|
||||||
|
# 优先级高于下方禁用列表
|
||||||
|
enable_group = True
|
||||||
|
|
||||||
|
# 是否处理私聊消息
|
||||||
|
# 为False时忽略所有私聊消息
|
||||||
|
# 优先级高于下方禁用列表
|
||||||
|
enable_private = True
|
||||||
|
|
||||||
# 是否启用禁用列表
|
# 是否启用禁用列表
|
||||||
enable = True
|
enable = True
|
||||||
|
|
||||||
|
|||||||
@@ -225,7 +225,7 @@
|
|||||||
格式: `!cfg <配置项名称> <配置项新值>`
|
格式: `!cfg <配置项名称> <配置项新值>`
|
||||||
以修改`default_prompt`示例
|
以修改`default_prompt`示例
|
||||||
```
|
```
|
||||||
!cfg default_prompt 我是Rock Chin
|
!cfg default_prompt "我是Rock Chin"
|
||||||
```
|
```
|
||||||
|
|
||||||
输出示例
|
输出示例
|
||||||
@@ -243,7 +243,15 @@
|
|||||||
```
|
```
|
||||||
!~all
|
!~all
|
||||||
!~default_prompt
|
!~default_prompt
|
||||||
!~default_prompt 我是Rock Chin
|
!~default_prompt "我是Rock Chin"
|
||||||
|
```
|
||||||
|
|
||||||
|
5. 配置项名称支持使用点号(.)拼接以索引子配置项
|
||||||
|
|
||||||
|
例如: `openai_config.api_key`将索引`config`字典中的`openai_config`字典中的`api_key`字段,可以通过这个方式查看或修改此子配置项
|
||||||
|
|
||||||
|
```
|
||||||
|
!~openai_config.api_key
|
||||||
```
|
```
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
@@ -367,4 +375,5 @@ prompt_submit_length = <模型单次请求token数上限> - 情景预设中token
|
|||||||
|
|
||||||
### 加入黑名单
|
### 加入黑名单
|
||||||
|
|
||||||
编辑`banlist.py`,设置`enable = True`,并在其中的`person`或`group`列表中加入要封禁的人或群聊,修改完成后重启程序或进行热重载
|
- 支持禁用所有`私聊`或`群聊`,请查看`banlist.py`中的`enable_private`和`enable_group`字段
|
||||||
|
- 编辑`banlist.py`,设置`enable = True`,并在其中的`person`或`group`列表中加入要封禁的人或群聊,修改完成后重启程序或进行热重载
|
||||||
@@ -30,5 +30,8 @@ command_admin_message = "[bot]err:权限不足: "
|
|||||||
command_err_message = "[bot]err:指令不存在:"
|
command_err_message = "[bot]err:指令不存在:"
|
||||||
|
|
||||||
# 会话重置提示
|
# 会话重置提示
|
||||||
command_reset_message = "[bot]:会话已重置"
|
command_reset_message = "[bot]会话已重置"
|
||||||
command_reset_name_message = "[bot]:会话已重置,使用场景预设:"
|
command_reset_name_message = "[bot]会话已重置,使用场景预设:"
|
||||||
|
|
||||||
|
# 会话自动重置时的提示
|
||||||
|
session_auto_reset_message = "[bot]会话token超限,已自动重置,请重新发送消息"
|
||||||
|
|||||||
Reference in New Issue
Block a user