Compare commits
11 Commits
publish2.4
...
publish2.5
| Author | SHA1 | Date | |
|---|---|---|---|
| a833812738 | |||
| b557bc1ec7 | |||
| 8ea7f42a1f | |||
| 9d553145ca | |||
| a38f3b9c28 | |||
| 9122b33fd0 | |||
| 91c6767522 | |||
| 5cf8df572a | |||
| 64bfac00a9 | |||
| 7407ac0ce1 | |||
| 0bb0493404 |
@@ -1,3 +1,6 @@
|
||||
# 2023/3/2 已支持官方ChatGPT API,性能更好!!!
|
||||
|
||||
|
||||
## ⭐体验
|
||||
|
||||
使用手机QQ扫码加入QQ频道(频道名: GPT机器人 | 频道号: x42d56aki2)
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
from revChatGPT.V1 import Chatbot
|
||||
|
||||
class revChatGPT:
|
||||
def __init__(self, config):
|
||||
|
||||
print("[RevChatGPT] 逆向库初始化:"+str(config))
|
||||
config['password'] = str(config['password'])
|
||||
self.chatbot = Chatbot(config=config)
|
||||
|
||||
def chat(self, prompt):
|
||||
resp = ''
|
||||
|
||||
err_count = 0
|
||||
retry_count = 5
|
||||
|
||||
while err_count < retry_count:
|
||||
try:
|
||||
for data in self.chatbot.ask(prompt):
|
||||
resp = data["message"]
|
||||
break
|
||||
except BaseException as e:
|
||||
print(e)
|
||||
print("[RevChatGPT] 请求出现了一些问题, 正在重试。次数"+str(err_count))
|
||||
err_count += 1
|
||||
if err_count == retry_count:
|
||||
raise e
|
||||
|
||||
print("[RevChatGPT] "+str(resp))
|
||||
return resp
|
||||
@@ -0,0 +1,42 @@
|
||||
openai:
|
||||
# 注意:在1.7版本已支持多key自动切换,方法:
|
||||
# key:
|
||||
# - xxxxx
|
||||
# - xxxxxx
|
||||
# 在下方非注释的地方使用以上格式
|
||||
key:
|
||||
-
|
||||
|
||||
chatGPTConfigs:
|
||||
engine: "gpt-3.5-turbo"
|
||||
max_tokens: 1000
|
||||
temperature: 0.9
|
||||
top_p: 1
|
||||
frequency_penalty: 0
|
||||
presence_penalty: 0
|
||||
|
||||
total_tokens_limit: 2000
|
||||
qqbot:
|
||||
appid:
|
||||
token:
|
||||
|
||||
# 设置是否一个人一个会话
|
||||
uniqueSessionMode: false
|
||||
|
||||
# QChannelBot 的版本,请勿修改此字段,否则可能产生一些bug
|
||||
version: 2.4 RealChatGPT Ver.
|
||||
|
||||
# [Beta] 转储历史记录时间间隔(分钟)
|
||||
dump_history_interval: 10
|
||||
|
||||
# 一个用户只能在time秒内发送count条消息
|
||||
limit:
|
||||
time: 60
|
||||
count: 5
|
||||
# 公告
|
||||
notice: "此机器人由Github项目QQChannelChatGPT驱动。"
|
||||
|
||||
# 是否打开私信功能
|
||||
# 设置为true则频道成员可以私聊机器人。
|
||||
# 设置为false则频道成员不能私聊机器人。
|
||||
direct_message_mode: true
|
||||
+44
-10
@@ -1,21 +1,27 @@
|
||||
# 如果你不知道怎么部署,请务必查看https://soulter.top/posts/qpdg.html
|
||||
|
||||
# 注意:已支持多key自动切换,方法:
|
||||
# key:
|
||||
# - sk-xxxxxx
|
||||
# - sk-xxxxxx
|
||||
# 在下方非注释的地方使用以上格式
|
||||
openai:
|
||||
# 注意:在1.7版本已支持多key自动切换,方法:
|
||||
# key:
|
||||
# - xxxxx
|
||||
# - xxxxxx
|
||||
# 在下方非注释的地方使用以上格式
|
||||
key:
|
||||
-
|
||||
|
||||
# 这里是GPT配置,语言模型默认使用gpt-3.5-turbo
|
||||
chatGPTConfigs:
|
||||
engine: "gpt-3.5-turbo"
|
||||
max_tokens: 1000
|
||||
model: gpt-3.5-turbo
|
||||
max_tokens: 1500
|
||||
temperature: 0.9
|
||||
top_p: 1
|
||||
frequency_penalty: 0
|
||||
presence_penalty: 0
|
||||
|
||||
total_tokens_limit: 2000
|
||||
total_tokens_limit: 2800
|
||||
|
||||
# QQ开放平台的appid和令牌
|
||||
# q.qq.com
|
||||
qqbot:
|
||||
appid:
|
||||
token:
|
||||
@@ -24,7 +30,7 @@ qqbot:
|
||||
uniqueSessionMode: false
|
||||
|
||||
# QChannelBot 的版本,请勿修改此字段,否则可能产生一些bug
|
||||
version: 2.4 RealChatGPT Ver.
|
||||
version: 2.5 RealChatGPT Ver.
|
||||
|
||||
# [Beta] 转储历史记录时间间隔(分钟)
|
||||
dump_history_interval: 10
|
||||
@@ -39,4 +45,32 @@ notice: "此机器人由Github项目QQChannelChatGPT驱动。"
|
||||
# 是否打开私信功能
|
||||
# 设置为true则频道成员可以私聊机器人。
|
||||
# 设置为false则频道成员不能私聊机器人。
|
||||
direct_message_mode: true
|
||||
direct_message_mode: true
|
||||
|
||||
################外带程序(插件)################
|
||||
|
||||
# 逆向ChatGPT库
|
||||
# https://github.com/acheong08/ChatGPT
|
||||
# 优点:免费(无免费额度限制);
|
||||
# 缺点:速度相对慢。OpenAI 速率限制:免费帐户每小时 50 个请求。您可以通过多帐户循环来绕过它
|
||||
# enable设置为true后,将会停止使用上面正常的官方API调用而使用本逆向项目
|
||||
#
|
||||
# 多账户可以保证每个请求都能得到及时的回复。
|
||||
# 关于account的格式
|
||||
# account:
|
||||
# - email: 第1个账户
|
||||
# password: 第1个账户密码
|
||||
# - email: 第2个账户
|
||||
# password: 第2个账户密码
|
||||
# - ....
|
||||
# 请严格按照上面这个格式填写。
|
||||
# 这里我免费提供2个账号给大家,不过用的人一定会很多的,所以会造成一些bug,因此还是用自己的账号好一点。
|
||||
# 需要账号可以联系我。QQ905617992
|
||||
|
||||
rev_ChatGPT:
|
||||
enable: false
|
||||
account:
|
||||
- email: d.o.m.her.ry61.7@gmail.com
|
||||
password: 11111111
|
||||
- email: ca.it.li.nal.o.i.si.o91@gmail.com
|
||||
password: 11111111
|
||||
+9
-11
@@ -12,24 +12,22 @@ abs_path = os.path.dirname(os.path.realpath(sys.argv[0])) + '/'
|
||||
key_record_path = abs_path+'chatgpt_key_record'
|
||||
|
||||
class ChatGPT:
|
||||
def __init__(self):
|
||||
def __init__(self, cfg):
|
||||
self.key_list = []
|
||||
with open(abs_path+"configs/config.yaml", 'r', encoding='utf-8') as ymlfile:
|
||||
cfg = yaml.safe_load(ymlfile)
|
||||
if cfg['openai']['key'] != '' or cfg['openai']['key'] != '修改我!!':
|
||||
print("[System] 读取ChatGPT Key成功")
|
||||
self.key_list = cfg['openai']['key']
|
||||
# openai.api_key = cfg['openai']['key']
|
||||
else:
|
||||
input("[System] 请先去完善ChatGPT的Key。详情请前往https://beta.openai.com/account/api-keys")
|
||||
if cfg['key'] != '' or cfg['key'] != '修改我!!':
|
||||
print("[System] 读取ChatGPT Key成功")
|
||||
self.key_list = cfg['key']
|
||||
# openai.api_key = cfg['key']
|
||||
else:
|
||||
input("[System] 请先去完善ChatGPT的Key。详情请前往https://beta.openai.com/account/api-keys")
|
||||
|
||||
# init key record
|
||||
self.init_key_record()
|
||||
|
||||
chatGPT_configs = cfg['openai']['chatGPTConfigs']
|
||||
chatGPT_configs = cfg['chatGPTConfigs']
|
||||
print(f'[System] 加载ChatGPTConfigs: {chatGPT_configs}')
|
||||
self.chatGPT_configs = chatGPT_configs
|
||||
self.openai_configs = cfg['openai']
|
||||
self.openai_configs = cfg
|
||||
|
||||
def chat(self, prompt, image_mode = False):
|
||||
# ChatGPT API 2023/3/2
|
||||
|
||||
+220
-166
@@ -61,6 +61,14 @@ abs_path = os.path.dirname(os.path.realpath(sys.argv[0])) + '/'
|
||||
# 版本
|
||||
version = '2.4 RealChatGPT Ver.'
|
||||
|
||||
# 语言模型提供商
|
||||
REV_CHATGPT = 'rev_chatgpt'
|
||||
OPENAI_OFFICIAL = 'openai_official'
|
||||
provider = ''
|
||||
|
||||
# 逆向库对象及负载均衡
|
||||
rev_chatgpt = []
|
||||
|
||||
# gpt配置信息
|
||||
gpt_config = {}
|
||||
|
||||
@@ -131,6 +139,7 @@ def dump_history():
|
||||
# 上传统计信息并检查更新
|
||||
def upload():
|
||||
global object_id
|
||||
global version
|
||||
while True:
|
||||
addr = ''
|
||||
try:
|
||||
@@ -147,7 +156,7 @@ def upload():
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
key_stat = chatgpt.get_key_stat()
|
||||
d = {"data": {"guild_count": guild_count, "guild_msg_count": guild_msg_count, "guild_direct_msg_count": guild_direct_msg_count, "session_count": session_count, 'addr': addr, 'winver': '2.3', 'key_stat':key_stat}}
|
||||
d = {"data": {"guild_count": guild_count, "guild_msg_count": guild_msg_count, "guild_direct_msg_count": guild_direct_msg_count, "session_count": session_count, 'addr': addr, 'winver': version, 'key_stat':key_stat}}
|
||||
d = json.dumps(d).encode("utf-8")
|
||||
res = requests.put(f'https://uqfxtww1.lc-cn-n1-shared.com/1.1/classes/bot_record/{object_id}', headers = headers, data = d)
|
||||
if json.loads(res.text)['code'] == 1:
|
||||
@@ -166,41 +175,64 @@ def upload():
|
||||
'''
|
||||
初始化机器人
|
||||
'''
|
||||
def initBot(chatgpt_inst):
|
||||
global chatgpt
|
||||
chatgpt = chatgpt_inst
|
||||
global max_tokens
|
||||
max_tokens = int(chatgpt_inst.getConfigs()['total_tokens_limit'])
|
||||
global now_personality
|
||||
def initBot(cfg, prov):
|
||||
global chatgpt, provider, rev_chatgpt
|
||||
global now_personality, gpt_config, config, uniqueSession, history_dump_interval, frequency_count, frequency_time,announcement, direct_message_mode, version
|
||||
|
||||
provider = prov
|
||||
config = cfg
|
||||
|
||||
# 读取历史记录 Soulter
|
||||
try:
|
||||
db1 = dbConn()
|
||||
for session in db1.get_all_session():
|
||||
session_dict[session[0]] = json.loads(session[1])['data']
|
||||
print("[System] 历史记录读取成功喵")
|
||||
except BaseException as e:
|
||||
print("[System] 历史记录读取失败: " + str(e))
|
||||
# 语言模型提供商
|
||||
if prov == REV_CHATGPT:
|
||||
if 'account' in cfg['rev_ChatGPT']:
|
||||
from addons.revChatGPT.revchatgpt import revChatGPT
|
||||
for i in range(0, len(cfg['rev_ChatGPT']['account'])):
|
||||
print(f"[System] 正在创建rev_ChatGPT负载{str(i)}: " + cfg['rev_ChatGPT']['account'][i]['email'])
|
||||
revstat = {
|
||||
'obj': revChatGPT(cfg['rev_ChatGPT']['account'][i]),
|
||||
'busy': False
|
||||
}
|
||||
rev_chatgpt.append(revstat)
|
||||
else:
|
||||
input("[System-err] 请退出本程序, 然后在配置文件中填写rev_ChatGPT的email和password")
|
||||
elif prov == OPENAI_OFFICIAL:
|
||||
from cores.openai.core import ChatGPT
|
||||
chatgpt = ChatGPT(cfg['openai'])
|
||||
global max_tokens
|
||||
max_tokens = int(chatgpt.getConfigs()['total_tokens_limit'])
|
||||
|
||||
# 读取历史记录 Soulter
|
||||
try:
|
||||
db1 = dbConn()
|
||||
for session in db1.get_all_session():
|
||||
session_dict[session[0]] = json.loads(session[1])['data']
|
||||
print("[System] 历史记录读取成功喵")
|
||||
except BaseException as e:
|
||||
print("[System] 历史记录读取失败: " + str(e))
|
||||
|
||||
# 读统计信息
|
||||
global stat_file
|
||||
if not os.path.exists(abs_path+"configs/stat"):
|
||||
with open(abs_path+"configs/stat", 'w', encoding='utf-8') as f:
|
||||
json.dump({}, f)
|
||||
stat_file = open(abs_path+"configs/stat", 'r', encoding='utf-8')
|
||||
global count
|
||||
res = stat_file.read()
|
||||
if res == '':
|
||||
count = {}
|
||||
else:
|
||||
try:
|
||||
count = json.loads(res)
|
||||
except BaseException:
|
||||
pass
|
||||
# 创建转储定时器线程
|
||||
threading.Thread(target=dump_history, daemon=True).start()
|
||||
# 读统计信息
|
||||
global stat_file
|
||||
if not os.path.exists(abs_path+"configs/stat"):
|
||||
with open(abs_path+"configs/stat", 'w', encoding='utf-8') as f:
|
||||
json.dump({}, f)
|
||||
stat_file = open(abs_path+"configs/stat", 'r', encoding='utf-8')
|
||||
global count
|
||||
res = stat_file.read()
|
||||
if res == '':
|
||||
count = {}
|
||||
else:
|
||||
try:
|
||||
count = json.loads(res)
|
||||
except BaseException:
|
||||
pass
|
||||
# 创建转储定时器线程
|
||||
threading.Thread(target=dump_history, daemon=True).start()
|
||||
|
||||
# 得到GPT配置信息
|
||||
if 'openai' in cfg and 'chatGPTConfigs' in cfg['openai']:
|
||||
gpt_config = cfg['openai']['chatGPTConfigs']
|
||||
|
||||
# 统计上传
|
||||
if is_upload_log:
|
||||
# 读取object_id
|
||||
global object_id
|
||||
@@ -212,61 +244,52 @@ def initBot(chatgpt_inst):
|
||||
object_id_file.close()
|
||||
# 创建上传定时器线程
|
||||
threading.Thread(target=upload, daemon=True).start()
|
||||
|
||||
# 得到私聊模式配置
|
||||
if 'direct_message_mode' in cfg:
|
||||
direct_message_mode = cfg['direct_message_mode']
|
||||
print("[System] 私聊功能: "+str(direct_message_mode))
|
||||
|
||||
global gpt_config, config, uniqueSession, history_dump_interval, frequency_count, frequency_time,announcement, direct_message_mode, version
|
||||
with open(abs_path+"configs/config.yaml", 'r', encoding='utf-8') as ymlfile:
|
||||
cfg = yaml.safe_load(ymlfile)
|
||||
config = cfg
|
||||
|
||||
# 得到私聊模式配置
|
||||
if 'direct_message_mode' in cfg:
|
||||
direct_message_mode = cfg['direct_message_mode']
|
||||
print("[System] 私聊功能: "+str(direct_message_mode))
|
||||
|
||||
# 得到GPT配置信息
|
||||
if 'openai' in cfg and 'chatGPTConfigs' in cfg['openai']:
|
||||
gpt_config = cfg['openai']['chatGPTConfigs']
|
||||
# 得到版本
|
||||
if 'version' in cfg:
|
||||
version = cfg['version']
|
||||
print("[System] QQChannelChatGPT版本: "+str(version))
|
||||
|
||||
# 得到版本
|
||||
if 'version' in cfg:
|
||||
version = cfg['version']
|
||||
print("[System] QQChannelChatGPT版本: "+str(version))
|
||||
# 得到发言频率配置
|
||||
if 'limit' in cfg:
|
||||
print('[System] 发言频率配置: '+str(cfg['limit']))
|
||||
if 'count' in cfg['limit']:
|
||||
frequency_count = cfg['limit']['count']
|
||||
if 'time' in cfg['limit']:
|
||||
frequency_time = cfg['limit']['time']
|
||||
|
||||
announcement += '[QQChannelChatGPT项目]\n所有回答与腾讯公司无关。出现问题请前往[GPT机器人]官方频道\n\n'
|
||||
# 得到公告配置
|
||||
if 'notice' in cfg:
|
||||
print('[System] 公告配置: '+cfg['notice'])
|
||||
announcement += cfg['notice']
|
||||
try:
|
||||
if 'uniqueSessionMode' in cfg and cfg['uniqueSessionMode']:
|
||||
uniqueSession = True
|
||||
else:
|
||||
uniqueSession = False
|
||||
print("[System] 独立会话: " + str(uniqueSession))
|
||||
if 'dump_history_interval' in cfg:
|
||||
history_dump_interval = int(cfg['dump_history_interval'])
|
||||
print("[System] 历史记录转储时间周期: " + str(history_dump_interval) + "分钟")
|
||||
except BaseException:
|
||||
print("[System-Error] 读取uniqueSessionMode/version/dump_history_interval配置文件失败, 使用默认值。")
|
||||
|
||||
# 得到发言频率配置
|
||||
if 'limit' in cfg:
|
||||
print('[System] 发言频率配置: '+str(cfg['limit']))
|
||||
if 'count' in cfg['limit']:
|
||||
frequency_count = cfg['limit']['count']
|
||||
if 'time' in cfg['limit']:
|
||||
frequency_time = cfg['limit']['time']
|
||||
|
||||
announcement += '[QQChannelChatGPT项目]\n所有回答与腾讯公司无关。出现问题请前往[GPT机器人]官方频道\n\n'
|
||||
# 得到公告配置
|
||||
if 'notice' in cfg:
|
||||
print('[System] 公告配置: '+cfg['notice'])
|
||||
announcement += cfg['notice']
|
||||
try:
|
||||
if 'uniqueSessionMode' in cfg and cfg['uniqueSessionMode']:
|
||||
uniqueSession = True
|
||||
else:
|
||||
uniqueSession = False
|
||||
print("[System] 独立会话: " + str(uniqueSession))
|
||||
if 'dump_history_interval' in cfg:
|
||||
history_dump_interval = int(cfg['dump_history_interval'])
|
||||
print("[System] 历史记录转储时间周期: " + str(history_dump_interval) + "分钟")
|
||||
except BaseException:
|
||||
print("[System-Error] 读取uniqueSessionMode/version/dump_history_interval配置文件失败, 使用默认值。")
|
||||
print(f"[System] QQ开放平台AppID: {cfg['qqbot']['appid']} 令牌: {cfg['qqbot']['token']}")
|
||||
|
||||
print(f"[System] QQ开放平台AppID: {cfg['qqbot']['appid']} 令牌: {cfg['qqbot']['token']}")
|
||||
|
||||
print("\n[System] 如果有任何问题,请在https://github.com/Soulter/QQChannelChatGPT上提交issue说明问题!或者添加QQ:905617992")
|
||||
print("[System] 请给https://github.com/Soulter/QQChannelChatGPT点个star!")
|
||||
print("[System] 请给https://github.com/Soulter/QQChannelChatGPT点个star!")
|
||||
input("\n仔细阅读完以上信息后,输入任意信息并回车以继续")
|
||||
try:
|
||||
run_bot(cfg['qqbot']['appid'], cfg['qqbot']['token'])
|
||||
except BaseException as e:
|
||||
input(f"\n[System-Error] 启动QQ机器人时出现错误,原因如下:{e}\n可能是没有填写QQBOT appid和token?请在config中完善你的appid和token\n配置教程:https://soulter.top/posts/qpdg.html\n")
|
||||
print("\n[System] 如果有任何问题,请在https://github.com/Soulter/QQChannelChatGPT上提交issue说明问题!或者添加QQ:905617992")
|
||||
print("[System] 请给https://github.com/Soulter/QQChannelChatGPT点个star!")
|
||||
print("[System] 请给https://github.com/Soulter/QQChannelChatGPT点个star!")
|
||||
input("\n仔细阅读完以上信息后,输入任意信息并回车以继续")
|
||||
try:
|
||||
run_bot(cfg['qqbot']['appid'], cfg['qqbot']['token'])
|
||||
except BaseException as e:
|
||||
input(f"\n[System-Error] 启动QQ机器人时出现错误,原因如下:{e}\n可能是没有填写QQBOT appid和token?请在config中完善你的appid和token\n配置教程:https://soulter.top/posts/qpdg.html\n")
|
||||
|
||||
|
||||
'''
|
||||
@@ -279,7 +302,7 @@ def run_bot(appid, token):
|
||||
client.run(appid=appid, token=token)
|
||||
|
||||
'''
|
||||
得到OpenAI的回复
|
||||
得到OpenAI官方API的回复
|
||||
'''
|
||||
def get_chatGPT_response(prompts_str, image_mode=False):
|
||||
res = ''
|
||||
@@ -293,6 +316,26 @@ def get_chatGPT_response(prompts_str, image_mode=False):
|
||||
res = chatgpt.chat(prompts_str, image_mode = True)
|
||||
return res
|
||||
|
||||
'''
|
||||
负载均衡,得到逆向ChatGPT回复
|
||||
'''
|
||||
def get_rev_ChatGPT_response(prompts_str):
|
||||
res = ''
|
||||
print("[Debug] "+str(rev_chatgpt))
|
||||
for revstat in rev_chatgpt:
|
||||
if not revstat['busy']:
|
||||
revstat['busy'] = True
|
||||
print("[Debug] 使用逆向ChatGPT回复ing", end='')
|
||||
res = revstat['obj'].chat(prompts_str)
|
||||
print("OK")
|
||||
revstat['busy'] = False
|
||||
# 处理结果文本
|
||||
chatgpt_res = res.strip()
|
||||
return res
|
||||
res = '所有的OpenAI账号都有负载, 请稍后再试~'
|
||||
return res
|
||||
|
||||
|
||||
'''
|
||||
回复QQ消息
|
||||
'''
|
||||
@@ -300,8 +343,8 @@ def send_qq_msg(message, res, image_mode=False):
|
||||
if not image_mode:
|
||||
try:
|
||||
asyncio.run_coroutine_threadsafe(message.reply(content=res), client.loop)
|
||||
except BaseException as e:
|
||||
raise e
|
||||
except:
|
||||
raise
|
||||
else:
|
||||
asyncio.run_coroutine_threadsafe(message.reply(image=res, content=""), client.loop)
|
||||
|
||||
@@ -356,7 +399,7 @@ def check_frequency(id) -> bool:
|
||||
处理消息
|
||||
'''
|
||||
def oper_msg(message, at=False, loop=None):
|
||||
global session_dict
|
||||
global session_dict, provider
|
||||
print("[QQBOT] 接收到消息:"+ str(message.content))
|
||||
qq_msg = ''
|
||||
session_id = ''
|
||||
@@ -407,20 +450,6 @@ def oper_msg(message, at=False, loop=None):
|
||||
if command_type == 1 and 'prompt' in now_personality:
|
||||
# 设置人格
|
||||
qq_msg = now_personality['prompt']
|
||||
|
||||
# if qq_msg[0:6] == '/draw ':
|
||||
# # TODO 未完全实现
|
||||
# prompt = qq_msg[6:]
|
||||
# url = get_chatGPT_response(prompt, image_mode = True)
|
||||
# resp = requests.get(url)
|
||||
# filename = './images/' + str(int(time.time())) + '.jpg'
|
||||
# print(url)
|
||||
# with open(filename, 'wb') as f:
|
||||
# f.write(resp.content)
|
||||
# qiniu_url = cores.database.qiniu.put_img(filename)
|
||||
# print(qiniu_url)
|
||||
# send_qq_msg(message, qiniu_url, image_mode=True)
|
||||
# return
|
||||
|
||||
# 这里是预设,你可以按需更改
|
||||
if qq_msg.strip() == 'hello' or qq_msg.strip() == '你好' or qq_msg.strip() == '':
|
||||
@@ -434,12 +463,13 @@ def oper_msg(message, at=False, loop=None):
|
||||
# if '台湾' in qq_msg or 'taiwan' in qq_msg:
|
||||
# send_qq_msg(message, "声明:台湾是中国的一部分。\n下面否定此结论的回答全部无效。")
|
||||
|
||||
# 拦截不合适的词请求
|
||||
# 关键词拦截器
|
||||
for i in uw.unfit_words_q:
|
||||
if i in qq_msg.strip():
|
||||
send_qq_msg(message, f"你的提问中有不太合适的内容😭\n请更换措辞~")
|
||||
return
|
||||
|
||||
|
||||
# 会话机制
|
||||
if session_id not in session_dict:
|
||||
session_dict[session_id] = []
|
||||
|
||||
@@ -456,31 +486,78 @@ def oper_msg(message, at=False, loop=None):
|
||||
f.write(json.dumps(fjson))
|
||||
f.flush()
|
||||
f.close()
|
||||
|
||||
chatgpt_res = "[Error] 占位符"
|
||||
if provider == OPENAI_OFFICIAL:
|
||||
|
||||
# 获取缓存
|
||||
cache_prompt = ''
|
||||
cache_data_list = session_dict[session_id]
|
||||
cache_prompt = get_prompts_by_cache_list(cache_data_list)
|
||||
cache_prompt += "\nHuman: "+ qq_msg + "\nAI: "
|
||||
# 请求chatGPT获得结果
|
||||
try:
|
||||
chatgpt_res, current_usage_tokens = get_chatGPT_response(prompts_str=cache_prompt)
|
||||
except (PromptExceededError) as e:
|
||||
print("token超限, 清空对应缓存")
|
||||
session_dict[session_id] = []
|
||||
cache_data_list = []
|
||||
cache_prompt = "Human: "+ qq_msg + "\nAI: "
|
||||
chatgpt_res, current_usage_tokens = get_chatGPT_response(prompts_str=cache_prompt)
|
||||
except (BaseException) as e:
|
||||
print("OpenAI API错误:(")
|
||||
if 'exceeded' in str(e):
|
||||
send_qq_msg(message, f"OpenAI API错误。原因:\n{str(e)} \n超额了。您可自己搭建一个机器人(Github仓库:QQChannelChatGPT)")
|
||||
else:
|
||||
send_qq_msg(message, f"OpenAI API错误。原因如下:\n{str(e)} \n前往官方频道反馈~")
|
||||
return
|
||||
# 获取缓存
|
||||
cache_prompt = ''
|
||||
cache_data_list = session_dict[session_id]
|
||||
cache_prompt = get_prompts_by_cache_list(cache_data_list)
|
||||
cache_prompt += "\nHuman: "+ qq_msg + "\nAI: "
|
||||
|
||||
logf.write("[GPT] "+ str(chatgpt_res)+'\n')
|
||||
logf.flush()
|
||||
# 请求chatGPT获得结果
|
||||
try:
|
||||
chatgpt_res, current_usage_tokens = get_chatGPT_response(prompts_str=cache_prompt)
|
||||
except (BaseException) as e:
|
||||
print("[System-Err] OpenAI API错误。原因如下:\n"+str(e))
|
||||
if 'maximum context length' in str(e):
|
||||
print("token超限, 清空对应缓存")
|
||||
session_dict[session_id] = []
|
||||
cache_data_list = []
|
||||
cache_prompt = "Human: "+ qq_msg + "\nAI: "
|
||||
chatgpt_res, current_usage_tokens = get_chatGPT_response(prompts_str=cache_prompt)
|
||||
elif 'exceeded' in str(e):
|
||||
send_qq_msg(message, f"OpenAI API错误。原因:\n{str(e)} \n超额了。可自己搭建一个机器人(Github仓库:QQChannelChatGPT)")
|
||||
else:
|
||||
send_qq_msg(message, f"OpenAI API错误。原因如下:\n{str(e)} \n前往官方频道反馈~")
|
||||
return
|
||||
|
||||
# 超过指定tokens, 尽可能的保留最多的条目,直到小于max_tokens
|
||||
if current_usage_tokens > max_tokens:
|
||||
t = current_usage_tokens
|
||||
index = 0
|
||||
while t > max_tokens:
|
||||
if index >= len(cache_data_list):
|
||||
break
|
||||
if 'level' in cache_data_list[index] and cache_data_list[index]['level'] != 'max':
|
||||
t -= int(cache_data_list[index]['single_tokens'])
|
||||
del cache_data_list[index]
|
||||
else:
|
||||
index += 1
|
||||
# 删除完后更新相关字段
|
||||
session_dict[session_id] = cache_data_list
|
||||
cache_prompt = get_prompts_by_cache_list(cache_data_list)
|
||||
|
||||
# 添加新条目进入缓存的prompt
|
||||
if command_type == 1:
|
||||
level = 'max'
|
||||
else:
|
||||
level = 'normal'
|
||||
if len(cache_data_list) > 0:
|
||||
single_record = {
|
||||
"prompt": f'Human: {qq_msg}\nAI: {chatgpt_res}\n',
|
||||
"usage_tokens": current_usage_tokens,
|
||||
"single_tokens": current_usage_tokens - int(cache_data_list[-1]['usage_tokens']),
|
||||
"level": level
|
||||
}
|
||||
else:
|
||||
single_record = {
|
||||
"prompt": f'Human: {qq_msg}\nAI: {chatgpt_res}\n',
|
||||
"usage_tokens": current_usage_tokens,
|
||||
"single_tokens": current_usage_tokens,
|
||||
"level": level
|
||||
}
|
||||
cache_data_list.append(single_record)
|
||||
session_dict[session_id] = cache_data_list
|
||||
|
||||
elif provider == REV_CHATGPT:
|
||||
try:
|
||||
chatgpt_res = "[Rev]"+str(get_rev_ChatGPT_response(qq_msg))
|
||||
except BaseException as e:
|
||||
print("[System-Err] Rev ChatGPT API错误。原因如下:\n"+str(e))
|
||||
send_qq_msg(message, f"Rev ChatGPT API错误。原因如下:\n{str(e)} \n前往官方频道反馈~")
|
||||
return
|
||||
|
||||
# 发送qq信息
|
||||
try:
|
||||
@@ -494,7 +571,7 @@ def oper_msg(message, at=False, loop=None):
|
||||
gap_chatgpt_res = gap_chatgpt_res.replace(i, "***")
|
||||
# 发送信息
|
||||
send_qq_msg(message, ''+gap_chatgpt_res)
|
||||
except BaseException as e:
|
||||
except:
|
||||
print("QQ频道API错误: \n"+str(e))
|
||||
f_res = ""
|
||||
for t in chatgpt_res:
|
||||
@@ -502,50 +579,17 @@ def oper_msg(message, at=False, loop=None):
|
||||
try:
|
||||
send_qq_msg(message, ''+f_res)
|
||||
# send(message, f"QQ频道API错误:{str(e)}\n下面是格式化后的回答:\n{f_res}")
|
||||
except BaseException as e:
|
||||
except:
|
||||
# 如果还是不行则过滤url
|
||||
f_res = re.sub(r'(https|http)?:\/\/(\w|\.|\/|\?|\=|\&|\%)*\b', '', f_res, flags=re.MULTILINE)
|
||||
f_res = f_res.replace(".", "·")
|
||||
send_qq_msg(message, ''+f_res)
|
||||
# send(message, f"QQ频道API错误:{str(e)}\n下面是格式化后的回答:\n{f_res}")
|
||||
|
||||
# 超过指定tokens, 尽可能的保留最多的条目,直到小于max_tokens
|
||||
if current_usage_tokens > max_tokens:
|
||||
t = current_usage_tokens
|
||||
index = 0
|
||||
while t > max_tokens:
|
||||
if index >= len(cache_data_list):
|
||||
break
|
||||
if 'level' in cache_data_list[index] and cache_data_list[index]['level'] != 'max':
|
||||
t -= int(cache_data_list[index]['single_tokens'])
|
||||
del cache_data_list[index]
|
||||
else:
|
||||
index += 1
|
||||
# 删除完后更新相关字段
|
||||
session_dict[session_id] = cache_data_list
|
||||
cache_prompt = get_prompts_by_cache_list(cache_data_list)
|
||||
# 记录日志
|
||||
logf.write("[GPT] "+ str(chatgpt_res)+'\n')
|
||||
logf.flush()
|
||||
|
||||
# 添加新条目进入缓存的prompt
|
||||
if command_type == 1:
|
||||
level = 'max'
|
||||
else:
|
||||
level = 'normal'
|
||||
if len(cache_data_list) > 0:
|
||||
single_record = {
|
||||
"prompt": f'Human: {qq_msg}\nAI: {chatgpt_res}\n',
|
||||
"usage_tokens": current_usage_tokens,
|
||||
"single_tokens": current_usage_tokens - int(cache_data_list[-1]['usage_tokens']),
|
||||
"level": level
|
||||
}
|
||||
else:
|
||||
single_record = {
|
||||
"prompt": f'Human: {qq_msg}\nAI: {chatgpt_res}\n',
|
||||
"usage_tokens": current_usage_tokens,
|
||||
"single_tokens": current_usage_tokens,
|
||||
"level": level
|
||||
}
|
||||
cache_data_list.append(single_record)
|
||||
session_dict[session_id] = cache_data_list
|
||||
|
||||
'''
|
||||
获取统计信息
|
||||
@@ -581,7 +625,7 @@ def get_stat():
|
||||
def command_oper(qq_msg, message, session_id, name, user_id, user_name, at):
|
||||
go = False # 是否处理完指令后继续执行msg_oper后面的代码
|
||||
msg = ''
|
||||
global session_dict, now_personality
|
||||
global session_dict, now_personality, provider
|
||||
|
||||
# 指令返回值,/set设置人格是1
|
||||
type = -1
|
||||
@@ -596,6 +640,9 @@ def command_oper(qq_msg, message, session_id, name, user_id, user_name, at):
|
||||
msg = f"你的历史记录重置成功"
|
||||
|
||||
if qq_msg[:4] == "/his":
|
||||
if provider == REV_CHATGPT:
|
||||
msg = "[QQChannelChatGPT]当前使用的语言模型提供商是Rev_ChatGPT, 不支持查看历史记录"
|
||||
return msg, go, type
|
||||
#分页,每页5条
|
||||
msg = ''
|
||||
size_per_page = 3
|
||||
@@ -614,6 +661,9 @@ def command_oper(qq_msg, message, session_id, name, user_id, user_name, at):
|
||||
msg=f"历史记录如下:\n{p}\n第{page}页 | 共{max_page}页\n*输入/his 2跳转到第2页\n\n{announcement}"
|
||||
|
||||
if qq_msg == "/token":
|
||||
if provider == REV_CHATGPT:
|
||||
msg = "[QQChannelChatGPT]当前使用的语言模型提供商是Rev_ChatGPT, 不支持使用此指令"
|
||||
return msg, go, type
|
||||
msg = ''
|
||||
if at:
|
||||
msg=f"{name} 会话的token数: {get_user_usage_tokens(session_dict[session_id])}\n系统最大缓存token数: {max_tokens}"
|
||||
@@ -621,10 +671,14 @@ def command_oper(qq_msg, message, session_id, name, user_id, user_name, at):
|
||||
msg=f"会话的token数: {get_user_usage_tokens(session_dict[session_id])}\n系统最大缓存token数: {max_tokens}"
|
||||
|
||||
if qq_msg == '/gpt':
|
||||
if provider == REV_CHATGPT:
|
||||
msg = "[QQChannelChatGPT]当前使用的语言模型提供商是Rev_ChatGPT, 不支持使用此指令"
|
||||
return msg, go, type
|
||||
global gpt_config
|
||||
msg=f"OpenAI GPT配置:\n {gpt_config}"
|
||||
|
||||
if qq_msg == "/status" or qq_msg == "/状态":
|
||||
|
||||
chatgpt_cfg_str = ""
|
||||
key_stat = chatgpt.get_key_stat()
|
||||
key_list = chatgpt.get_key_list()
|
||||
@@ -661,7 +715,7 @@ def command_oper(qq_msg, message, session_id, name, user_id, user_name, at):
|
||||
|
||||
if qq_msg[:4] == "/key":
|
||||
if len(qq_msg) == 4:
|
||||
msg = "感谢您赞助key。请以以下格式赞助:\n/key xxxxx"
|
||||
msg = "感谢您赞助key,key为官方API使用,请以以下格式赞助:\n/key xxxxx"
|
||||
key = qq_msg[5:]
|
||||
send_qq_msg(message, "收到!正在核验...")
|
||||
if chatgpt.check_key(key):
|
||||
|
||||
@@ -5,19 +5,27 @@ import os, sys
|
||||
import signal
|
||||
import requests,json
|
||||
|
||||
# 是否是windows打包。一般人不需要改这个,这个只是我为了方便加上的。
|
||||
win_compile_mode = False
|
||||
|
||||
abs_path = os.path.dirname(os.path.realpath(sys.argv[0])) + '/'
|
||||
|
||||
|
||||
|
||||
def main(loop, event):
|
||||
import cores.qqbot.core as qqBot
|
||||
from cores.openai.core import ChatGPT
|
||||
#实例化ChatGPT
|
||||
chatgpt = ChatGPT()
|
||||
# #执行qqBot
|
||||
qqBot.initBot(chatgpt)
|
||||
import yaml
|
||||
|
||||
ymlfile = open(abs_path+"configs/config.yaml", 'r', encoding='utf-8')
|
||||
cfg = yaml.safe_load(ymlfile)
|
||||
provider = privider_chooser(cfg)
|
||||
print('[System] 当前语言模型提供商: ' + provider)
|
||||
# 执行Bot
|
||||
qqBot.initBot(cfg, provider)
|
||||
|
||||
# 语言模型提供商选择器
|
||||
# 目前有:OpenAI官方API、逆向库
|
||||
def privider_chooser(cfg):
|
||||
if 'rev_ChatGPT' in cfg and cfg['rev_ChatGPT']['enable']:
|
||||
return 'rev_chatgpt'
|
||||
else:
|
||||
return 'openai_official'
|
||||
|
||||
# 仅支持linux
|
||||
def hot_update(ver):
|
||||
@@ -77,10 +85,9 @@ def hot_update(ver):
|
||||
time.sleep(60*20)
|
||||
except BaseException as e:
|
||||
print(e)
|
||||
print("upd出现异常,请联系QQ905617992")
|
||||
print("upd出现异常, 请联系QQ905617992")
|
||||
time.sleep(60*20)
|
||||
|
||||
|
||||
def update_version(ver):
|
||||
if not os.path.exists('update_record'):
|
||||
object_id = ''
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
requests~=2.27.1
|
||||
openai~=0.26.5
|
||||
openai~=0.27.0
|
||||
qq-botpy~=1.1.2
|
||||
|
||||
Reference in New Issue
Block a user