Compare commits

...

70 Commits

Author SHA1 Message Date
Soulter f3722b31d5 Merge pull request #48 from Soulter/42-openai_api_domain_customization
fix: 解决newbing换话题的问题;解决newbing回复慢的问题
2023-03-26 20:33:28 +08:00
Soulter 673a4e2c7f fix: 解决newbing换话题的问题;解决newbing回复慢的问题 2023-03-26 20:32:59 +08:00
Soulter 1d8fba05b6 Merge pull request #46 from Soulter/42-openai_api_domain_customization
fix: 删除linux热更新
2023-03-25 11:49:28 +08:00
Soulter 7c06883975 fix: 删除linux热更新 2023-03-25 11:48:58 +08:00
Soulter 6da12b7a67 Merge pull request #45 from Soulter/42-openai_api_domain_customization
更新config
2023-03-25 11:43:22 +08:00
Soulter 0342d752e6 更新config 2023-03-25 11:41:40 +08:00
Soulter a851e34c94 Merge pull request #44 from Soulter/42-openai_api_domain_customization
feat: newbing接入
2023-03-25 11:37:46 +08:00
Soulter ad8aed5724 feat: newbing接入 2023-03-25 11:37:08 +08:00
Soulter 75101bf270 Merge pull request #43 from Soulter/42-openai_api_domain_customization
feat: 新增openai自定api_base #42
2023-03-25 10:33:04 +08:00
Soulter 43df7003d6 feat: 新增openai自定api_base 2023-03-25 10:32:15 +08:00
Soulter 502703b749 docs: 更新requirements.txt 2023-03-25 10:12:09 +08:00
Soulter 8365f39f95 docs: 更新requirements.txt 2023-03-25 10:10:23 +08:00
Soulter aa5f8db59d Merge branch 'master' of https://github.com/Soulter/QQChannelChatGPT 2023-03-25 10:09:04 +08:00
Soulter d2b60b72d9 docs: 更新requirements.txt 2023-03-25 10:07:57 +08:00
Soulter 14c36ceb52 feat:接入文心一言(完全不稳定) 2023-03-25 10:03:48 +08:00
Soulter cdc3bdd769 Update README.md 2023-03-23 19:59:48 +08:00
Soulter 48d0c2a8c8 Update README.md 2023-03-23 19:58:53 +08:00
Soulter 6923979014 Update README.md 2023-03-21 17:18:23 +08:00
Soulter 03239439c9 Update requirements.txt 2023-03-20 18:49:58 +08:00
Soulter da3381a887 Merge branch 'master' of https://github.com/Soulter/QQChannelChatGPT 2023-03-14 13:58:01 +08:00
Soulter a1253cc241 fix: 敏感词修复 2023-03-14 11:37:28 +08:00
Soulter ffe10cc5c2 Update config.yaml 2023-03-13 20:03:06 +08:00
Soulter 7093cf5ab8 Merge branch 'master' of https://github.com/Soulter/QQChannelChatGPT 2023-03-13 19:46:33 +08:00
Soulter 979a0cdd2e perf: 自有敏感词拦截器支持正则匹配 #18
fix: 修复版本显示的一些问题
2023-03-13 19:46:30 +08:00
Soulter b495a11d1f feat: 接入百度内容审核服务 2023-03-13 18:45:53 +08:00
Soulter 8698e87e51 Update README.md 2023-03-12 18:00:12 +08:00
Soulter 6d2f9e5ba8 docs: 更新逆向库版本 2023-03-12 17:49:56 +08:00
Soulter 0e24e107d6 Merge pull request #35 from waveyl/删除“正在思考”
删除“正在思考”的回复
2023-03-07 11:49:25 +08:00
waveyl 888a4e89ab 删除“正在思考”的回复 2023-03-07 11:38:15 +08:00
Soulter 1a55684ae8 Merge branch 'master' of https://github.com/Soulter/QQChannelChatGPT 2023-03-07 10:43:13 +08:00
Soulter 858712dcbc fix: 修复/help一些问题 2023-03-07 10:43:10 +08:00
Soulter ad4d068bbc Merge pull request #33 from waveyl/max_token
fix: 将max_token修改为9000000
2023-03-07 10:21:11 +08:00
wave 0f5a2101b7 fix: max_token现在为九百万 2023-03-07 09:54:45 +08:00
Soulter 7bc9d8dc7b docs: 更新依赖版本 2023-03-07 09:13:38 +08:00
Soulter 506a62e6e6 Merge pull request #32 from Soulter/30-personality-fix
fix: 修复人格的一些bug #30
2023-03-07 09:05:09 +08:00
Soulter 44e22087d8 fix: 修复人格的一些bug
feat: 自定义人格
2023-03-07 09:00:15 +08:00
Soulter d88c06578d Merge pull request #31 from Soulter/27-msg-oper-perf
fix: 修复Tokens超限后重新请求无法发送QQ信息的问题 #27
2023-03-07 08:17:47 +08:00
Soulter 93bc12a89c Merge branch '27-msg-oper-perf' of https://github.com/Soulter/QQChannelChatGPT into 27-msg-oper-perf 2023-03-07 08:15:25 +08:00
Soulter eedcb9b825 fix: 修复缓存超限后重新请求无法发送QQ消息的问题 2023-03-07 08:15:21 +08:00
Soulter b8fe50a196 Merge branch 'master' of https://github.com/Soulter/QQChannelChatGPT 2023-03-07 07:59:51 +08:00
Soulter 10b1538118 Merge branch 'master' of https://github.com/Soulter/QQChannelChatGPT 2023-03-06 23:30:25 +08:00
Soulter 09cfd18f6f feat: 回复消息引用 #28
perf: 完善逆向库中RateLimit的切换机制
perf: 其他优化
2023-03-06 23:28:01 +08:00
Soulter d01be66344 feat: 回复消息引用
perf: 完善逆向库中RateLimit的切换机制
perf: 其他优化
2023-03-06 23:23:44 +08:00
Soulter c0e4d0595b feat: 添加系统代理 2023-03-05 13:55:21 +08:00
Soulter d403323a36 Merge branch 'master' of https://github.com/Soulter/QQChannelChatGPT 2023-03-05 12:41:44 +08:00
Soulter 3092bbd210 perf: 解除启动时需要回车的限制
perf: 优化Linux自动更新的时间
2023-03-05 12:40:51 +08:00
Soulter 9d2cd27705 Merge pull request #23 from Soulter/ChatGPTAI-perf
perf: 重构ChatGPT API,更稳定。
2023-03-05 12:32:41 +08:00
Soulter ec48b57358 Merge branch 'master' into ChatGPTAI-perf 2023-03-05 12:32:09 +08:00
Soulter 54cdca01d3 perf: 重构ChatGPT API,更稳定。 2023-03-05 12:26:46 +08:00
Soulter 4b35f7f8fd Merge pull request #22 from Soulter/20-revChatGPTLoginPerf
perf: 逆向库支持access/session登录
2023-03-05 11:04:14 +08:00
Soulter 651ba7b3d6 fix: 删除一些字段 2023-03-05 11:02:32 +08:00
Soulter cd1390d449 perf: 逆向库支持access/session登录
fix: 优化对逆向库的适配
2023-03-05 10:59:31 +08:00
Soulter d478ff02b6 Delete bot24linux/configs directory 2023-03-05 09:08:42 +08:00
Soulter 1da3a19ddd Merge branch 'master' of https://github.com/Soulter/QQChannelChatGPT 2023-03-03 17:32:02 +08:00
Soulter db66cbfb9c fix: 修复逆向的一些问题 2023-03-03 17:29:22 +08:00
Soulter 51729f4a50 Update README.md 2023-03-03 16:59:00 +08:00
Soulter d739abef60 Merge branch 'master' of https://github.com/Soulter/QQChannelChatGPT 2023-03-03 12:33:35 +08:00
Soulter 2ecb3fc7cf fix:修复热重载的一些问题 2023-03-03 12:33:32 +08:00
Soulter 69c576086e Update requirements.txt 2023-03-03 12:27:47 +08:00
Soulter a833812738 feat: 逆向ChatGPT 2023-03-03 12:20:11 +08:00
Soulter b557bc1ec7 Merge branch 'master' of https://github.com/Soulter/QQChannelChatGPT 2023-03-03 12:09:41 +08:00
Soulter 8ea7f42a1f merge 2023-03-03 12:03:30 +08:00
Soulter 9d553145ca feat: 接入逆向ChatGPT库。
perf: 重构部分代码,提高代码鲁棒性。
2023-03-03 11:58:52 +08:00
Soulter a38f3b9c28 fix: 修复缓存超限报错的问题 2023-03-03 10:08:14 +08:00
Soulter 9122b33fd0 Update README.md 2023-03-02 18:15:17 +08:00
Soulter 91c6767522 Update README.md 2023-03-02 16:58:21 +08:00
Soulter 5cf8df572a Merge pull request #19 from slippersheepig/patch-1
fix: change engine to model to use chatgpt
2023-03-02 11:41:09 +08:00
sheepgreen 64bfac00a9 fix: change engine to model to use chatgpt 2023-03-02 11:39:34 +08:00
Soulter 7407ac0ce1 Update requirements.txt 2023-03-02 10:47:50 +08:00
Soulter 0bb0493404 fix: 修复了一些bug 2023-03-02 10:44:44 +08:00
9 changed files with 649 additions and 278 deletions
+8 -3
View File
@@ -2,16 +2,21 @@
使用手机QQ扫码加入QQ频道(频道名: GPT机器人 | 频道号: x42d56aki2)
![image](https://user-images.githubusercontent.com/37870767/221722540-d4b0fada-4fa2-4063-bb00-1bb3e4d9a747.png)
<img src="https://user-images.githubusercontent.com/37870767/227197121-4f1e02a4-92fd-4497-8768-9d6977a291b7.jpg" width="200"></img>
**Windows用户推荐Windows一键安装,请前往Release下载最新版本**
**详细部署教程链接**https://soulter.top/posts/qpdg.html
详细部署教程链接https://soulter.top/posts/qpdg.html
任何问题请加频道反馈
网络问题报错的请先看issue,解决不了再加频道反馈
## ⭐功能:
- 逆向ChatGPT库
- 官方ChatGPT AI
- 文心一言(即将支持,链接https://github.com/Soulter/ERNIEBot 欢迎Star
- NewBing(即将支持)
### 基本功能
<details>
<summary>✅ 回复符合上下文</summary>
+26
View File
@@ -0,0 +1,26 @@
from aip import AipContentCensor
class BaiduJudge:
def __init__(self, baidu_configs) -> None:
if 'app_id' in baidu_configs and 'api_key' in baidu_configs and 'secret_key' in baidu_configs:
self.app_id = str(baidu_configs['app_id'])
self.api_key = baidu_configs['api_key']
self.secret_key = baidu_configs['secret_key']
self.client = AipContentCensor(self.app_id, self.api_key, self.secret_key)
else:
raise ValueError("Baidu configs error! 请填写百度内容审核服务相关配置!")
def judge(self, text):
res = self.client.textCensorUserDefined(text)
if 'conclusionType' not in res:
return False, "百度审核服务未知错误"
if res['conclusionType'] == 1:
return True, "合规"
else:
if 'data' not in res:
return False, "百度审核服务未知错误"
count = len(res['data'])
info = f"百度审核服务发现 {count} 处违规:\n"
for i in res['data']:
info += f"{i['msg']}\n"
info += "\n判断结果:"+res['conclusion']
return False, info
+45
View File
@@ -0,0 +1,45 @@
from revChatGPT.V1 import Chatbot
class revChatGPT:
def __init__(self, config):
if 'password' in config:
config['password'] = str(config['password'])
self.chatbot = Chatbot(config=config)
def chat(self, prompt):
resp = ''
"""
Base class for exceptions in this module.
Error codes:
-1: User error
0: Unknown error
1: Server error
2: Rate limit error
3: Invalid request error
4: Expired access token error
5: Invalid access token error
6: Prohibited concurrent query error
"""
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:
try:
print("[RevChatGPT] 请求出现了一些问题, 正在重试。次数"+str(err_count))
err_count += 1
if err_count >= retry_count:
raise e
except BaseException:
err_count += 1
print("[RevChatGPT] "+str(resp))
return resp
+47
View File
@@ -0,0 +1,47 @@
import asyncio
from EdgeGPT import Chatbot, ConversationStyle
import json
class revEdgeGPT:
def __init__(self):
self.busy = False
self.wait_stack = []
with open('./cookies.json', 'r') as f:
cookies = json.load(f)
self.bot = Chatbot(cookies=cookies)
def is_busy(self):
return self.busy
async def reset(self):
try:
await self.bot.reset()
return False
except BaseException:
return True
async def chat(self, prompt):
if self.busy:
return
self.busy = True
resp = 'err'
err_count = 0
retry_count = 5
while err_count < retry_count:
try:
resp = await self.bot.ask(prompt=prompt, conversation_style=ConversationStyle.creative)
resp = resp['item']['messages'][len(resp['item']['messages'])-1]['text']
if resp == prompt:
resp += '\n\n如果你没有让我复述你的话,那代表我可能不想和你继续这个话题了,请输入/reset重置会话😶'
break
except BaseException as e:
print(e.with_traceback)
err_count += 1
if err_count >= retry_count:
raise e
print("[RevEdgeGPT] 请求出现了一些问题, 正在重试。次数"+str(err_count))
self.busy = False
print("[RevEdgeGPT] "+str(resp))
return resp
+71 -15
View File
@@ -1,42 +1,98 @@
# 如果你不知道怎么部署,请务必查看https://soulter.top/posts/qpdg.html
# 注意:已支持多key自动切换,方法:
# key:
# - sk-xxxxxx
# - sk-xxxxxx
# 在下方非注释的地方使用以上格式
# 关于api_base:可以使用一些云函数(如腾讯、阿里)来避免国内被墙的问题。
# 详见:
# https://github.com/Ice-Hazymoon/openai-scf-proxy
# https://github.com/Soulter/QQChannelChatGPT/issues/42
# 设置为none则表示使用官方默认api地址
openai:
# 注意:在1.7版本已支持多key自动切换,方法:
# key:
# - xxxxx
# - xxxxxx
# 在下方非注释的地方使用以上格式
key:
-
api_base: none
# 这里是GPT配置,语言模型默认使用gpt-3.5-turbo
chatGPTConfigs:
engine: "gpt-3.5-turbo"
max_tokens: 1000
model: gpt-3.5-turbo
max_tokens: 3000
temperature: 0.9
top_p: 1
frequency_penalty: 0
presence_penalty: 0
total_tokens_limit: 2000
total_tokens_limit: 5000
# QQ开放平台的appid和令牌
# q.qq.com
qqbot:
appid:
token:
# 设置是否一个人一个会话
uniqueSessionMode: false
# QChannelBot 的版本,请勿修改此字段,否则可能产生一些bug
version: 2.4 RealChatGPT Ver.
version: 2.8
# [Beta] 转储历史记录时间间隔(分钟)
dump_history_interval: 10
# 一个用户只能在time秒内发送count条消息
limit:
time: 60
count: 5
# 公告
notice: "此机器人由Github项目QQChannelChatGPT驱动。"
# 是否打开私信功能
# 设置为true则频道成员可以私聊机器人。
# 设置为false则频道成员不能私聊机器人。
direct_message_mode: true
direct_message_mode: true
# 系统代理
# http_proxy: http://localhost:7890
# https_proxy: http://localhost:7890
################外带程序(插件)################
# 百度内容审核服务
# 新用户免费5万次调用。https://cloud.baidu.com/doc/ANTIPORN/index.html
baidu_aip:
enable: false
app_id:
api_key:
secret_key:
# 逆向文心一言【暂时不可用,请勿使用】
rev_ernie:
enable: false
rev_edgegpt:
enable: false
# 逆向ChatGPT库
# https://github.com/acheong08/ChatGPT
# 优点:免费(无免费额度限制);
# 缺点:速度相对慢。OpenAI 速率限制:免费帐户每小时 50 个请求。您可以通过多帐户循环来绕过它
# enable设置为true后,将会停止使用上面正常的官方API调用而使用本逆向项目
#
# 多账户可以保证每个请求都能得到及时的回复。
# 关于account的格式
# account:
# - email: 第1个账户
# password: 第1个账户密码
# - email: 第2个账户
# password: 第2个账户密码
# - ....
# 支持使用session_token\access_token登录
# 例:
# - session_token: xxxxx
# - access_token: xxxx
# 请严格按照上面这个格式填写。
rev_ChatGPT:
enable: false
account:
- email:
password:
+33 -51
View File
@@ -12,74 +12,56 @@ 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 'api_base' in cfg and cfg['api_base'] != 'none' and cfg['api_base'] != '':
openai.api_base = cfg['api_base']
if cfg['key'] != '' and cfg['key'] != None:
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):
def chat(self, req, image_mode = False):
# ChatGPT API 2023/3/2
messages = [{"role": "user", "content": prompt}]
# messages = [{"role": "user", "content": prompt}]
try:
if not image_mode:
response = openai.ChatCompletion.create(
messages=messages,
**self.chatGPT_configs
)
else:
response = openai.Image.create(
prompt=prompt,
n=1,
size="512x512",
)
response = openai.ChatCompletion.create(
messages=req,
**self.chatGPT_configs
)
except Exception as e:
print(e)
if 'You exceeded' in str(e) or 'Billing hard limit has been reached' in str(e) or 'No API key provided.' in str(e):
print("[System] 当前Key已超额,正在切换")
if 'You exceeded' in str(e) or 'Billing hard limit has been reached' in str(e) or 'No API key provided' in str(e) or 'Incorrect API key provided' in str(e):
print("[System] 当前Key已超额或者不正常,正在切换")
self.key_stat[openai.api_key]['exceed'] = True
self.save_key_record()
response, is_switched = self.handle_switch_key(prompt)
response, is_switched = self.handle_switch_key(req)
if not is_switched:
# 所有Key都超额
# 所有Key都超额或不正常
raise e
else:
if not image_mode:
response = openai.ChatCompletion.create(
messages=messages,
**self.chatGPT_configs
)
else:
response = openai.Image.create(
prompt=prompt,
n=1,
size="512x512",
)
if not image_mode:
self.key_stat[openai.api_key]['used'] += response['usage']['total_tokens']
self.save_key_record()
print("[ChatGPT] "+str(response["choices"][0]["message"]["content"]))
return str(response["choices"][0]["message"]["content"]).strip(), response['usage']['total_tokens']
else:
return response['data'][0]['url']
response = openai.ChatCompletion.create(
messages=req,
**self.chatGPT_configs
)
self.key_stat[openai.api_key]['used'] += response['usage']['total_tokens']
self.save_key_record()
print("[ChatGPT] "+str(response["choices"][0]["message"]["content"]))
return str(response["choices"][0]["message"]["content"]).strip(), response['usage']['total_tokens']
def handle_switch_key(self, prompt):
messages = [{"role": "user", "content": prompt}]
def handle_switch_key(self, req):
# messages = [{"role": "user", "content": prompt}]
while True:
is_all_exceed = True
for key in self.key_stat:
@@ -87,10 +69,10 @@ class ChatGPT:
is_all_exceed = False
openai.api_key = key
print(f"[System] 切换到Key: {key}, 已使用token: {self.key_stat[key]['used']}")
if prompt != '':
if len(req) > 0:
try:
response = openai.ChatCompletion.create(
messages=messages,
messages=req,
**self.chatGPT_configs
)
return response, True
+379 -190
View File
@@ -1,5 +1,6 @@
import botpy
from botpy.message import Message
from botpy.types.message import Reference
import yaml
import re
from util.errors.errors import PromptExceededError
@@ -14,6 +15,7 @@ import util.unfit_words as uw
import os
import sys
from cores.qqbot.personality import personalities
from addons.baidu_aip_judge import BaiduJudge
history_dump_interval = 10
@@ -59,11 +61,25 @@ direct_message_mode = True
abs_path = os.path.dirname(os.path.realpath(sys.argv[0])) + '/'
# 版本
version = '2.4 RealChatGPT Ver.'
version = '2.9'
# 语言模型提供商
REV_CHATGPT = 'rev_chatgpt'
OPENAI_OFFICIAL = 'openai_official'
REV_ERNIE = 'rev_ernie'
REV_EDGEGPT = 'rev_edgegpt'
provider = ''
# 逆向库对象及负载均衡
rev_chatgpt = []
# gpt配置信息
gpt_config = {}
# 百度内容审核实例
baidu_judge = None
def new_sub_thread(func, args=()):
thread = threading.Thread(target=func, args=args, daemon=True)
thread.start()
@@ -72,8 +88,9 @@ class botClient(botpy.Client):
# 收到At消息
async def on_at_message_create(self, message: Message):
toggle_count(at=True, message=message)
message_reference = Reference(message_id=message.id, ignore_get_message_error=False)
# executor.submit(oper_msg, message, True)
new_sub_thread(oper_msg, (message, True))
new_sub_thread(oper_msg, (message, True, message_reference))
# await oper_msg(message=message, at=True)
# 收到私聊消息
@@ -131,6 +148,7 @@ def dump_history():
# 上传统计信息并检查更新
def upload():
global object_id
global version
while True:
addr = ''
try:
@@ -147,7 +165,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": {'version': version, "guild_count": guild_count, "guild_msg_count": guild_msg_count, "guild_direct_msg_count": guild_direct_msg_count, "session_count": session_count, 'addr': addr, '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 +184,84 @@ 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, baidu_judge, rev_ernie, rev_edgegpt
global now_personality, gpt_config, config, uniqueSession, history_dump_interval, frequency_count, frequency_time,announcement, direct_message_mode, version
provider = prov
config = cfg
# 语言模型提供商
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'])):
try:
print(f"[System] 创建rev_ChatGPT负载{str(i)}: " + str(cfg['rev_ChatGPT']['account'][i]))
revstat = {
'obj': revChatGPT(cfg['rev_ChatGPT']['account'][i]),
'busy': False
}
rev_chatgpt.append(revstat)
except:
print("[System] 创建rev_ChatGPT负载失败")
else:
input("[System-err] 请退出本程序, 然后在配置文件中填写rev_ChatGPT相关配置")
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()
# 得到GPT配置信息
if 'openai' in cfg and 'chatGPTConfigs' in cfg['openai']:
gpt_config = cfg['openai']['chatGPTConfigs']
elif prov == REV_ERNIE:
from addons.revERNIE import revernie
rev_ernie = revernie.wx
elif prov == REV_EDGEGPT:
from addons.revEdgeGPT import revedgegpt
rev_edgegpt = revedgegpt.revEdgeGPT()
# 读取历史记录 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:
# 百度内容审核
if 'baidu_aip' in cfg and 'enable' in cfg['baidu_aip'] and cfg['baidu_aip']['enable']:
try:
count = json.loads(res)
except BaseException:
pass
# 创建转储定时器线程
threading.Thread(target=dump_history, daemon=True).start()
baidu_judge = BaiduJudge(cfg['baidu_aip'])
print("[System] 百度内容审核初始化成功")
except BaseException as e:
input("[System] 百度内容审核初始化失败: " + str(e))
exit()
# 统计上传
if is_upload_log:
# 读取object_id
global object_id
@@ -212,61 +273,57 @@ 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 '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']
# 得到版本
if 'version' in cfg:
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配置文件失败, 使用默认值。")
f = open(abs_path+"version.txt", 'r', encoding='utf-8')
version = f.read()
except:
print('[System-Err] 读取更新记录文件失败')
# version = 'Unknown'
# print("[System] QQChannelChatGPT版本: "+str(version))
print(f"[System] QQ开放平台AppID: {cfg['qqbot']['appid']} 令牌: {cfg['qqbot']['token']}")
# 得到发言频率配置
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项目,觉得好用的话欢迎前往Github给Star]\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("\n[System] 如果有任何问题,请在https://github.com/Soulter/QQChannelChatGPT上提交issue说明问题!或者添加QQ905617992")
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(f"[System] QQ开放平台AppID: {cfg['qqbot']['appid']} 令牌: {cfg['qqbot']['token']}")
print("\n[System] 如果有任何问题,请在https://github.com/Soulter/QQChannelChatGPT上提交issue说明问题!或者添加QQ905617992")
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,28 +336,73 @@ def run_bot(appid, token):
client.run(appid=appid, token=token)
'''
得到OpenAI的回复
得到OpenAI官方API的回复
'''
def get_chatGPT_response(prompts_str, image_mode=False):
def get_chatGPT_response(context, request, image_mode=False):
res = ''
usage = ''
req_list = []
for i in context:
req_list.append(i['user'])
req_list.append(i['AI'])
req_list.append(request['user'])
if not image_mode:
res, usage = chatgpt.chat(prompts_str)
print("[Debug] "+ str(req_list))
res, usage = chatgpt.chat(req_list)
# 处理结果文本
chatgpt_res = res.strip()
return res, usage
else:
res = chatgpt.chat(prompts_str, image_mode = True)
res = chatgpt.chat(req_list, 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']:
try:
revstat['busy'] = True
print("[Debug] 使用逆向ChatGPT回复ing", end='', flush=True)
res = revstat['obj'].chat(prompts_str)
print("OK")
revstat['busy'] = False
# 处理结果文本
chatgpt_res = res.strip()
return res
except Exception as e:
print("[System-Error] 逆向ChatGPT回复失败" + str(e))
try:
if e.code == 2:
print("[System-Error] 频率限制,正在切换账号。"+ str(e))
continue
else:
res = '所有的非忙碌OpenAI账号经过测试都暂时出现问题,请稍后再试或者联系管理员~'
return res
except BaseException:
continue
res = '所有的OpenAI账号都有负载, 请稍后再试~'
return res
'''
回复QQ消息
'''
def send_qq_msg(message, res, image_mode=False):
def send_qq_msg(message, res, image_mode=False, msg_ref = None):
if not image_mode:
try:
asyncio.run_coroutine_threadsafe(message.reply(content=res), client.loop)
if msg_ref is not None:
res = asyncio.run_coroutine_threadsafe(message.reply(content=res, message_reference = msg_ref), client.loop)
else:
res = asyncio.run_coroutine_threadsafe(message.reply(content=res), client.loop)
res.result()
except BaseException as e:
print("[System-Error] 回复QQ消息失败")
raise e
else:
asyncio.run_coroutine_threadsafe(message.reply(image=res, content=""), client.loop)
@@ -320,10 +422,13 @@ def get_prompts_by_cache_list(cache_data_list, divide=False, paging=False, size=
page_end = len(cache_data_list)
cache_data_list = cache_data_list[page_begin:page_end]
for item in cache_data_list:
prompts += str(item['prompt'])
prompts += str(item['user']['role']) + ":\n" + str(item['user']['content']) + "\n"
prompts += str(item['AI']['role']) + ":\n" + str(item['AI']['content']) + "\n"
if divide:
prompts += "----------\n"
return prompts
def get_user_usage_tokens(cache_list):
usage_tokens = 0
@@ -355,8 +460,8 @@ def check_frequency(id) -> bool:
'''
处理消息
'''
def oper_msg(message, at=False, loop=None):
global session_dict
def oper_msg(message, at=False, msg_ref = None):
global session_dict, provider
print("[QQBOT] 接收到消息:"+ str(message.content))
qq_msg = ''
session_id = ''
@@ -407,39 +512,33 @@ 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() == '':
send_qq_msg(message, f"你好呀~")
send_qq_msg(message, f"你好呀🥰,输入/help查看指令噢", msg_ref=msg_ref)
return
# if qq_msg.strip() == '傻逼' or qq_msg.strip() == 'sb':
# send_qq_msg(message, f"好好好")
# return
# if '喜多' in qq_msg:
# send_qq_msg(message, 'http://rn2ztkeap.hn-bkt.clouddn.com/xd1.gif', True)
# 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请更换措辞~")
matches = re.match(i, qq_msg.strip(), re.I | re.M)
if matches:
send_qq_msg(message, f"你的提问得到的回复未通过【自有关键词拦截】服务,不予回复。", msg_ref=msg_ref)
return
if baidu_judge != None:
check, msg = baidu_judge.judge(qq_msg)
if not check:
send_qq_msg(message, f"你的提问得到的回复未通过【百度AI内容审核】服务,不予回复。\n\n{msg}", msg_ref=msg_ref)
return
# 会话机制
if session_id not in session_dict:
session_dict[session_id] = []
@@ -456,96 +555,164 @@ def oper_msg(message, at=False, loop=None):
f.write(json.dumps(fjson))
f.flush()
f.close()
chatgpt_res = "[Error] 占位符"
# 获取缓存
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
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: "
# 创建一个新的Record
record_obj = {
"user": {
"role": "user",
"content": qq_msg,
},
"AI": {},
'usage_tokens': 0,
}
# ChatGPT API 回复倾向(人格)
if command_type == 1:
record_obj["user"]["role"] = "system"
print("[Debug] "+ str(cache_data_list))
# 请求chatGPT获得结果
try:
chatgpt_res, current_usage_tokens = get_chatGPT_response(context=cache_data_list, request=record_obj)
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 = []
chatgpt_res, current_usage_tokens = get_chatGPT_response(context=cache_data_list, request=record_obj)
elif 'exceeded' in str(e):
send_qq_msg(message, f"OpenAI API错误。原因:\n{str(e)} \n超额了。可自己搭建一个机器人(Github仓库:QQChannelChatGPT)")
return
else:
f_res = re.sub(r'(https|http)?:\/\/(\w|\.|\/|\?|\=|\&|\%)*\b', '[被隐藏的链接]', str(e), flags=re.MULTILINE)
f_res = f_res.replace(".", "·")
send_qq_msg(message, f"OpenAI API错误。原因如下:\n{f_res} \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 'user' in cache_data_list[index] and cache_data_list[index]['user']['role'] != 'system':
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
record_obj['AI'] = {
'role': 'assistant',
'content': chatgpt_res,
}
record_obj['usage_tokens'] = current_usage_tokens
if len(cache_data_list) > 0:
record_obj['single_tokens'] = current_usage_tokens - int(cache_data_list[-1]['usage_tokens'])
else:
record_obj['single_tokens'] = current_usage_tokens
cache_data_list.append(record_obj)
# if len(cache_data_list) > 0:
# single_record = {
# 'role': 'assistant',
# "content": chatgpt_res,
# "usage_tokens": current_usage_tokens,
# "single_tokens": current_usage_tokens - int(cache_data_list[-1]['usage_tokens']),
# "level": level
# }
# else:
# single_record = {
# 'role': 'assistant',
# "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
elif provider == REV_ERNIE:
try:
chatgpt_res = "[RevERNIE]"+str(rev_ernie.chatViaSelenium(qq_msg))
except BaseException as e:
print("[System-Err] Rev ERNIE API错误。原因如下:\n"+str(e))
send_qq_msg(message, f"Rev ERNIE API错误。原因如下:\n{str(e)} \n前往官方频道反馈~")
return
elif provider == REV_EDGEGPT:
try:
if rev_edgegpt.is_busy():
send_qq_msg(message, f"[RevBing] 正忙,请稍后再试",msg_ref=msg_ref)
return
else:
chatgpt_res = "[RevBing]"
chatgpt_res += str(asyncio.run_coroutine_threadsafe(rev_edgegpt.chat(qq_msg), client.loop).result())
except BaseException as e:
print("[System-Err] Rev NewBing API错误。原因如下:\n"+str(e))
send_qq_msg(message, f"Rev NewBing API错误。原因如下:\n{str(e)} \n前往官方频道反馈~")
return
# 记录日志
logf.write("[GPT] "+ str(chatgpt_res)+'\n')
logf.flush()
# 敏感过滤
# 过滤不合适的词
judged_res = chatgpt_res
for i in uw.unfit_words:
judged_res = re.sub(i, "***", judged_res)
# 百度内容审核服务二次审核
if baidu_judge != None:
check, msg = baidu_judge.judge(judged_res)
if not check:
send_qq_msg(message, f"你的提问得到的回复【百度内容审核】未通过,不予回复。\n\n{msg}", msg_ref=msg_ref)
return
# 发送qq信息
try:
# 防止被qq频道过滤消息
gap_chatgpt_res = chatgpt_res.replace(".", " . ")
if '```' in gap_chatgpt_res:
chatgpt_res.replace('```', "")
# 过滤不合适的词
for i in uw.unfit_words:
if i in gap_chatgpt_res:
gap_chatgpt_res = gap_chatgpt_res.replace(i, "***")
gap_chatgpt_res = judged_res.replace(".", " . ")
send_qq_msg(message, ''+gap_chatgpt_res, msg_ref=msg_ref)
# 发送信息
send_qq_msg(message, ''+gap_chatgpt_res)
except BaseException as e:
print("QQ频道API错误: \n"+str(e))
f_res = ""
for t in chatgpt_res:
f_res += t + ' '
try:
send_qq_msg(message, ''+f_res)
send_qq_msg(message, ''+f_res, msg_ref=msg_ref)
# send(message, f"QQ频道API错误:{str(e)}\n下面是格式化后的回答:\n{f_res}")
except BaseException as e:
# 如果还是不行则过滤url
f_res = re.sub(r'(https|http)?:\/\/(\w|\.|\/|\?|\=|\&|\%)*\b', '', f_res, flags=re.MULTILINE)
f_res = re.sub(r'(https|http)?:\/\/(\w|\.|\/|\?|\=|\&|\%)*\b', '[被隐藏的链接]', str(e), flags=re.MULTILINE)
f_res = f_res.replace(".", "·")
send_qq_msg(message, ''+f_res)
send_qq_msg(message, ''+f_res, msg_ref=msg_ref)
# 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)
# 添加新条目进入缓存的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 +748,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, rev_edgegpt, client
# 指令返回值,/set设置人格是1
type = -1
@@ -589,13 +756,20 @@ def command_oper(qq_msg, message, session_id, name, user_id, user_name, at):
# 指令控制
if qq_msg == "/reset" or qq_msg == "/重置":
msg = ''
session_dict[session_id] = []
if provider == REV_EDGEGPT and rev_edgegpt is not None:
asyncio.run_coroutine_threadsafe(rev_edgegpt.reset(), client.loop).result()
else:
session_dict[session_id] = []
if at:
msg = f"{name}(id: {session_id})的历史记录重置成功\n\n{announcement}"
else:
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 +788,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,15 +798,19 @@ 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()
index = 1
max = 900000
max = 9000000
gg_count = 0
total = 0
tag = ''
@@ -661,7 +842,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 = "感谢您赞助keykey为官方API使用,请以以下格式赞助:\n/key xxxxx"
key = qq_msg[5:]
send_qq_msg(message, "收到!正在核验...")
if chatgpt.check_key(key):
@@ -672,7 +853,8 @@ def command_oper(qq_msg, message, session_id, name, user_id, user_name, at):
if qq_msg[:6] == "/unset":
now_personality = {}
msg = "已清除人格"
session_dict[session_id] = []
msg = "已清除人格并重置历史记录。"
if qq_msg[:4] == "/set":
if len(qq_msg) == 4:
@@ -710,5 +892,12 @@ def command_oper(qq_msg, message, session_id, name, user_id, user_name, at):
go = True
type = 1
else:
msg = f"人格{ps}不存在, 请使用/set list查看人格列表"
return msg, go, type
now_personality = {
'name': '自定义人格',
'prompt': ps
}
session_dict[session_id] = []
msg = f"你的自定义人格已设置。 \n人格信息: {ps}\n请耐心等待机器人回复第一条信息。"
go = True
type = 1
return msg, go, type
+34 -16
View File
@@ -5,22 +5,41 @@ import os, sys
import signal
import requests,json
# 是否是windows打包。一般人不需要改这个,这个只是我为了方便加上的。
win_compile_mode = False
abs_path = os.path.dirname(os.path.realpath(sys.argv[0])) + '/'
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)
if 'http_proxy' in cfg:
os.environ['HTTP_PROXY'] = cfg['http_proxy']
if 'https_proxy' in cfg:
os.environ['HTTPS_PROXY'] = cfg['https_proxy']
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'
elif 'rev_ernie' in cfg and cfg['rev_ernie']['enable']:
return 'rev_ernie'
elif 'rev_edgegpt' in cfg and cfg['rev_edgegpt']['enable']:
return 'rev_edgegpt'
else:
return 'openai_official'
# 仅支持linux
def hot_update(ver):
def hot_update():
target = 'target.tar'
time.sleep(5)
while(True):
@@ -74,12 +93,11 @@ def hot_update(ver):
print('自启动')
py = sys.executable
os.execl(py, py, *sys.argv)
time.sleep(60*20)
time.sleep(60*60*3)
except BaseException as e:
print(e)
print("upd出现异常请联系QQ905617992")
time.sleep(60*20)
print("upd出现异常, 请联系QQ905617992")
time.sleep(60*60*3)
def update_version(ver):
if not os.path.exists('update_record'):
@@ -161,8 +179,8 @@ if __name__ == "__main__":
check_env()
bot_event = threading.Event()
loop = asyncio.get_event_loop()
ma_type = get_platform()
if ma_type == 'linux':
threading.Thread(target=hot_update).start()
# ma_type = get_platform()
# if ma_type == 'linux':
# threading.Thread(target=hot_update).start()
main(loop, bot_event)
+6 -3
View File
@@ -1,3 +1,6 @@
requests~=2.27.1
openai~=0.26.5
qq-botpy~=1.1.2
requests
openai
qq-botpy
revChatGPT~=4.0.8
baidu-aip
EdgeGPT~=0.1.2