!! delete: 移除对逆向 ChatGPT 的所有支持。
This commit is contained in:
@@ -160,7 +160,6 @@
|
||||
- `/key` 动态添加key
|
||||
- `/set` 人格设置面板
|
||||
- `/keyword nihao 你好` 设置关键词回复。nihao->你好
|
||||
- `/revgpt` 切换为ChatGPT逆向库
|
||||
- `/画` 画画
|
||||
|
||||
#### 逆向ChatGPT库语言模型
|
||||
|
||||
+39
-73
@@ -12,15 +12,17 @@ import time
|
||||
import asyncio
|
||||
from util.plugin_dev.api.v1.config import update_config
|
||||
|
||||
|
||||
@dataclass
|
||||
class DashBoardConfig():
|
||||
config_type: str
|
||||
name: Optional[str] = None
|
||||
description: Optional[str] = None
|
||||
path: Optional[str] = None # 仅 item 才需要
|
||||
body: Optional[list['DashBoardConfig']] = None # 仅 group 才需要
|
||||
value: Optional[Union[list, dict, str, int, bool]] = None # 仅 item 才需要
|
||||
val_type: Optional[str] = None # 仅 item 才需要
|
||||
path: Optional[str] = None # 仅 item 才需要
|
||||
body: Optional[list['DashBoardConfig']] = None # 仅 group 才需要
|
||||
value: Optional[Union[list, dict, str, int, bool]] = None # 仅 item 才需要
|
||||
val_type: Optional[str] = None # 仅 item 才需要
|
||||
|
||||
|
||||
class DashBoardHelper():
|
||||
def __init__(self, global_object, config: dict):
|
||||
@@ -34,26 +36,30 @@ class DashBoardHelper():
|
||||
self.parse_default_config(dashboard_data, config)
|
||||
self.dashboard_data: DashBoardData = dashboard_data
|
||||
self.dashboard = AstrBotDashBoard(global_object)
|
||||
self.key_map = {} # key: uuid, value: config key name
|
||||
self.key_map = {} # key: uuid, value: config key name
|
||||
self.cc = CmdConfig()
|
||||
|
||||
|
||||
@self.dashboard.register("post_configs")
|
||||
def on_post_configs(post_configs: dict):
|
||||
try:
|
||||
# self.logger.log(f"收到配置更新请求", gu.LEVEL_INFO, tag="可视化面板")
|
||||
if 'base_config' in post_configs:
|
||||
self.save_config(post_configs['base_config'], namespace='') # 基础配置
|
||||
self.save_config(post_configs['config'], namespace=post_configs['namespace']) # 选定配置
|
||||
self.parse_default_config(self.dashboard_data, self.cc.get_all())
|
||||
self.save_config(
|
||||
post_configs['base_config'], namespace='') # 基础配置
|
||||
self.save_config(
|
||||
post_configs['config'], namespace=post_configs['namespace']) # 选定配置
|
||||
self.parse_default_config(
|
||||
self.dashboard_data, self.cc.get_all())
|
||||
# 重启
|
||||
threading.Thread(target=self.dashboard.shutdown_bot, args=(2,), daemon=True).start()
|
||||
threading.Thread(target=self.dashboard.shutdown_bot,
|
||||
args=(2,), daemon=True).start()
|
||||
except Exception as e:
|
||||
# self.logger.log(f"在保存配置时发生错误:{e}", gu.LEVEL_ERROR, tag="可视化面板")
|
||||
raise e
|
||||
|
||||
|
||||
# 将 config.yaml、 中的配置解析到 dashboard_data.configs 中
|
||||
def parse_default_config(self, dashboard_data: DashBoardData, config: dict):
|
||||
|
||||
|
||||
try:
|
||||
qq_official_platform_group = DashBoardConfig(
|
||||
config_type="group",
|
||||
@@ -381,48 +387,7 @@ class DashBoardHelper():
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
rev_chatgpt_accounts = config['rev_ChatGPT']['account']
|
||||
new_accs = []
|
||||
for i in rev_chatgpt_accounts:
|
||||
if isinstance(i, dict) and 'access_token' in i:
|
||||
new_accs.append(i['access_token'])
|
||||
elif isinstance(i, str):
|
||||
new_accs.append(i)
|
||||
config['rev_ChatGPT']['account'] = new_accs
|
||||
|
||||
rev_chatgpt_llm_group = DashBoardConfig(
|
||||
config_type="group",
|
||||
name="逆向语言模型服务设置",
|
||||
description="",
|
||||
body=[
|
||||
DashBoardConfig(
|
||||
config_type="item",
|
||||
val_type="bool",
|
||||
name="启用逆向语言模型服务",
|
||||
description="",
|
||||
value=config['rev_ChatGPT']['enable'],
|
||||
path="rev_ChatGPT.enable",
|
||||
),
|
||||
DashBoardConfig(
|
||||
config_type="item",
|
||||
val_type="str",
|
||||
name="终结点(Endpoint)地址",
|
||||
description="逆向服务的终结点服务器的地址。",
|
||||
value=config['CHATGPT_BASE_URL'],
|
||||
path="CHATGPT_BASE_URL",
|
||||
),
|
||||
DashBoardConfig(
|
||||
config_type="item",
|
||||
val_type="list",
|
||||
name="assess_token",
|
||||
description="assess_token",
|
||||
value=config['rev_ChatGPT']['account'],
|
||||
path="rev_ChatGPT.account",
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
baidu_aip_group = DashBoardConfig(
|
||||
config_type="group",
|
||||
name="百度内容审核",
|
||||
@@ -436,9 +401,6 @@ class DashBoardHelper():
|
||||
value=config['baidu_aip']['enable'],
|
||||
path="baidu_aip.enable"
|
||||
),
|
||||
# "app_id": null,
|
||||
# "api_key": null,
|
||||
# "secret_key": null
|
||||
DashBoardConfig(
|
||||
config_type="item",
|
||||
val_type="str",
|
||||
@@ -497,13 +459,12 @@ class DashBoardHelper():
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
dashboard_data.configs['data'] = [
|
||||
qq_official_platform_group,
|
||||
qq_gocq_platform_group,
|
||||
general_platform_detail_group,
|
||||
openai_official_llm_group,
|
||||
rev_chatgpt_llm_group,
|
||||
other_group,
|
||||
baidu_aip_group
|
||||
]
|
||||
@@ -511,13 +472,12 @@ class DashBoardHelper():
|
||||
except Exception as e:
|
||||
self.logger.log(f"配置文件解析错误:{e}", gu.LEVEL_ERROR)
|
||||
raise e
|
||||
|
||||
|
||||
|
||||
def save_config(self, post_config: list, namespace: str):
|
||||
'''
|
||||
根据 path 解析并保存配置
|
||||
'''
|
||||
|
||||
|
||||
queue = post_config
|
||||
while len(queue) > 0:
|
||||
config = queue.pop(0)
|
||||
@@ -527,23 +487,27 @@ class DashBoardHelper():
|
||||
elif config['config_type'] == "item":
|
||||
if config['path'] is None or config['path'] == "":
|
||||
continue
|
||||
|
||||
|
||||
path = config['path'].split('.')
|
||||
if len(path) == 0:
|
||||
continue
|
||||
|
||||
|
||||
if config['val_type'] == "bool":
|
||||
self._write_config(namespace, config['path'], config['value'])
|
||||
self._write_config(
|
||||
namespace, config['path'], config['value'])
|
||||
elif config['val_type'] == "str":
|
||||
self._write_config(namespace, config['path'], config['value'])
|
||||
self._write_config(
|
||||
namespace, config['path'], config['value'])
|
||||
elif config['val_type'] == "int":
|
||||
try:
|
||||
self._write_config(namespace, config['path'], int(config['value']))
|
||||
self._write_config(
|
||||
namespace, config['path'], int(config['value']))
|
||||
except:
|
||||
raise ValueError(f"配置项 {config['name']} 的值必须是整数")
|
||||
elif config['val_type'] == "float":
|
||||
try:
|
||||
self._write_config(namespace, config['path'], float(config['value']))
|
||||
self._write_config(
|
||||
namespace, config['path'], float(config['value']))
|
||||
except:
|
||||
raise ValueError(f"配置项 {config['name']} 的值必须是浮点数")
|
||||
elif config['val_type'] == "list":
|
||||
@@ -551,16 +515,18 @@ class DashBoardHelper():
|
||||
self._write_config(namespace, config['path'], [])
|
||||
elif not isinstance(config['value'], list):
|
||||
raise ValueError(f"配置项 {config['name']} 的值必须是列表")
|
||||
self._write_config(namespace, config['path'], config['value'])
|
||||
self._write_config(
|
||||
namespace, config['path'], config['value'])
|
||||
else:
|
||||
raise NotImplementedError(f"未知或者未实现的配置项类型:{config['val_type']}")
|
||||
|
||||
raise NotImplementedError(
|
||||
f"未知或者未实现的配置项类型:{config['val_type']}")
|
||||
|
||||
def _write_config(self, namespace: str, key: str, value):
|
||||
if namespace == "" or namespace.startswith("internal_"):
|
||||
# 机器人自带配置,存到 config.yaml
|
||||
self.cc.put_by_dot_str(key, value)
|
||||
else:
|
||||
update_config(namespace, key, value)
|
||||
|
||||
|
||||
def run(self):
|
||||
self.dashboard.run()
|
||||
self.dashboard.run()
|
||||
|
||||
@@ -276,6 +276,44 @@ class AstrBotDashBoard():
|
||||
message=e.__str__(),
|
||||
data=None
|
||||
).__dict__
|
||||
|
||||
@self.dashboard_be.get("/api/llm/list")
|
||||
def llm_list():
|
||||
ret = []
|
||||
for llm in self.global_object.llms:
|
||||
ret.append(llm.llm_name)
|
||||
return Response(
|
||||
status="success",
|
||||
message="",
|
||||
data=ret
|
||||
).__dict__
|
||||
|
||||
@self.dashboard_be.get("/api/llm")
|
||||
def llm():
|
||||
text = request.args["text"]
|
||||
llm = request.args["llm"]
|
||||
for llm_ in self.global_object.llms:
|
||||
if llm_.llm_name == llm:
|
||||
try:
|
||||
# ret = await llm_.llm_instance.text_chat(text)
|
||||
ret = asyncio.run_coroutine_threadsafe(llm_.llm_instance.text_chat(text), self.loop).result()
|
||||
return Response(
|
||||
status="success",
|
||||
message="",
|
||||
data=ret
|
||||
).__dict__
|
||||
except Exception as e:
|
||||
return Response(
|
||||
status="error",
|
||||
message=e.__str__(),
|
||||
data=None
|
||||
).__dict__
|
||||
|
||||
return Response(
|
||||
status="error",
|
||||
message="LLM not found.",
|
||||
data=None
|
||||
).__dict__
|
||||
|
||||
def shutdown_bot(self, delay_s: int):
|
||||
time.sleep(delay_s)
|
||||
@@ -348,12 +386,6 @@ class AstrBotDashBoard():
|
||||
"desc": "也支持使用官方接口的中转服务",
|
||||
"namespace": "internal_llm_openai_official",
|
||||
"tag": ""
|
||||
},
|
||||
{
|
||||
"title": "Rev ChatGPT",
|
||||
"desc": "早期的逆向ChatGPT,不推荐",
|
||||
"namespace": "internal_llm_rev_chatgpt",
|
||||
"tag": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+3
-20
@@ -46,7 +46,6 @@ frequency_count = 10
|
||||
version = '3.1.11'
|
||||
|
||||
# 语言模型
|
||||
REV_CHATGPT = 'rev_chatgpt'
|
||||
OPENAI_OFFICIAL = 'openai_official'
|
||||
NONE_LLM = 'none_llm'
|
||||
chosen_provider = None
|
||||
@@ -70,8 +69,6 @@ logger: Logger = Logger()
|
||||
# 语言模型选择
|
||||
def privider_chooser(cfg):
|
||||
l = []
|
||||
if 'rev_ChatGPT' in cfg and cfg['rev_ChatGPT']['enable']:
|
||||
l.append('rev_chatgpt')
|
||||
if 'openai' in cfg and len(cfg['openai']['key']) > 0 and cfg['openai']['key'][0] is not None:
|
||||
l.append('openai_official')
|
||||
return l
|
||||
@@ -113,18 +110,6 @@ def init(cfg):
|
||||
# 语言模型提供商
|
||||
logger.log("正在载入语言模型...", gu.LEVEL_INFO)
|
||||
prov = privider_chooser(cfg)
|
||||
if REV_CHATGPT in prov:
|
||||
logger.log("初始化:逆向 ChatGPT", gu.LEVEL_INFO)
|
||||
if cfg['rev_ChatGPT']['enable']:
|
||||
if 'account' in cfg['rev_ChatGPT']:
|
||||
from model.provider.rev_chatgpt import ProviderRevChatGPT
|
||||
from model.command.rev_chatgpt import CommandRevChatGPT
|
||||
llm_instance[REV_CHATGPT] = ProviderRevChatGPT(cfg['rev_ChatGPT'], base_url=cc.get("CHATGPT_BASE_URL", None))
|
||||
llm_command_instance[REV_CHATGPT] = CommandRevChatGPT(llm_instance[REV_CHATGPT], _global_object)
|
||||
chosen_provider = REV_CHATGPT
|
||||
_global_object.llms.append(RegisteredLLM(llm_name=REV_CHATGPT, llm_instance=llm_instance[REV_CHATGPT], origin="internal"))
|
||||
else:
|
||||
input("请退出本程序, 然后在配置文件中填写rev_ChatGPT相关配置")
|
||||
if OPENAI_OFFICIAL in prov:
|
||||
logger.log("初始化:OpenAI官方", gu.LEVEL_INFO)
|
||||
if cfg['openai']['key'] is not None and cfg['openai']['key'] != [None]:
|
||||
@@ -226,7 +211,7 @@ def init(cfg):
|
||||
dashboard_thread.start()
|
||||
|
||||
# 运行 monitor
|
||||
threading.Thread(target=run_monitor, args=(_global_object,), daemon=False).start()
|
||||
threading.Thread(target=run_monitor, args=(_global_object,), daemon=True).start()
|
||||
|
||||
logger.log("如果有任何问题, 请在 https://github.com/Soulter/AstrBot 上提交 issue 或加群 322154837。", gu.LEVEL_INFO)
|
||||
logger.log("请给 https://github.com/Soulter/AstrBot 点个 star。", gu.LEVEL_INFO)
|
||||
@@ -350,12 +335,10 @@ async def oper_msg(message: AstrBotMessage,
|
||||
|
||||
# 检查是否是更换语言模型的请求
|
||||
temp_switch = ""
|
||||
if message_str.startswith('/gpt') or message_str.startswith('/revgpt'):
|
||||
if message_str.startswith('/gpt'):
|
||||
target = chosen_provider
|
||||
if message_str.startswith('/gpt'):
|
||||
target = OPENAI_OFFICIAL
|
||||
elif message_str.startswith('/revgpt'):
|
||||
target = REV_CHATGPT
|
||||
l = message_str.split(' ')
|
||||
if len(l) > 1 and l[1] != "":
|
||||
# 临时对话模式,先记录下之前的语言模型,回答完毕后再切回
|
||||
@@ -412,7 +395,7 @@ async def oper_msg(message: AstrBotMessage,
|
||||
web_sch_flag = True
|
||||
else:
|
||||
message_str += " " + cc.get("llm_env_prompt", "")
|
||||
if chosen_provider == REV_CHATGPT or chosen_provider == OPENAI_OFFICIAL:
|
||||
if chosen_provider == OPENAI_OFFICIAL:
|
||||
if _global_object.web_search or web_sch_flag:
|
||||
official_fc = chosen_provider == OPENAI_OFFICIAL
|
||||
llm_result_str = await gplugin.web_search(message_str, llm_instance[chosen_provider], session_id, official_fc)
|
||||
|
||||
@@ -12,7 +12,6 @@ def main():
|
||||
try:
|
||||
import cores.astrbot.core as qqBot
|
||||
import yaml
|
||||
import util.general_utils as gu
|
||||
ymlfile = open(abs_path+"configs/config.yaml", 'r', encoding='utf-8')
|
||||
cfg = yaml.safe_load(ymlfile)
|
||||
except ImportError as import_error:
|
||||
@@ -91,6 +90,10 @@ if __name__ == "__main__":
|
||||
else:
|
||||
check_env()
|
||||
|
||||
t = threading.Thread(target=main, daemon=False)
|
||||
t = threading.Thread(target=main, daemon=True)
|
||||
t.start()
|
||||
t.join()
|
||||
try:
|
||||
t.join()
|
||||
except KeyboardInterrupt as e:
|
||||
print("退出 AstrBot。")
|
||||
exit()
|
||||
|
||||
@@ -211,8 +211,7 @@ class Command:
|
||||
"plugin": "插件安装、卸载和重载",
|
||||
"web on/off": "LLM 网页搜索能力",
|
||||
"reset": "重置 LLM 对话",
|
||||
"/gpt": "切换到 OpenAI 官方接口",
|
||||
"/revgpt": "切换到网页版ChatGPT",
|
||||
"/gpt": "切换到 OpenAI 官方接口"
|
||||
}
|
||||
|
||||
async def help_messager(self, commands: dict, platform: str, cached_plugins: List[RegisteredPlugin] = None):
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
from model.command.command import Command
|
||||
from model.provider.rev_chatgpt import ProviderRevChatGPT
|
||||
from util.personality import personalities
|
||||
from cores.astrbot.types import GlobalObject
|
||||
|
||||
class CommandRevChatGPT(Command):
|
||||
def __init__(self, provider: ProviderRevChatGPT, global_object: GlobalObject):
|
||||
self.provider = provider
|
||||
self.global_object = global_object
|
||||
self.personality_str = ""
|
||||
super().__init__(provider, global_object)
|
||||
|
||||
async def check_command(self,
|
||||
message: str,
|
||||
session_id: str,
|
||||
role: str,
|
||||
platform: str,
|
||||
message_obj):
|
||||
self.platform = platform
|
||||
hit, res = await super().check_command(
|
||||
message,
|
||||
session_id,
|
||||
role,
|
||||
platform,
|
||||
message_obj
|
||||
)
|
||||
|
||||
if hit:
|
||||
return True, res
|
||||
if self.command_start_with(message, "help", "帮助"):
|
||||
return True, await self.help()
|
||||
elif self.command_start_with(message, "reset"):
|
||||
return True, self.reset(session_id, message)
|
||||
elif self.command_start_with(message, "update"):
|
||||
return True, self.update(message, role)
|
||||
elif self.command_start_with(message, "set"):
|
||||
return True, self.set(message, session_id)
|
||||
elif self.command_start_with(message, "switch"):
|
||||
return True, self.switch(message, session_id)
|
||||
return False, None
|
||||
|
||||
def reset(self, session_id, message: str):
|
||||
l = message.split(" ")
|
||||
if len(l) == 1:
|
||||
self.provider.forget(session_id)
|
||||
return True, "重置完毕。", "reset"
|
||||
if len(l) == 2 and l[1] == "p":
|
||||
self.provider.forget(session_id)
|
||||
ret = self.provider.text_chat(self.personality_str)
|
||||
return True, f"重置完毕(保留人格)。\n\n{ret}", "reset"
|
||||
|
||||
def set(self, message: str, session_id: str):
|
||||
l = message.split(" ")
|
||||
if len(l) == 1:
|
||||
return True, f"设置人格: \n/set 人格名或人格文本。例如/set 编剧\n人格列表: /set list\n人格详细信息: \
|
||||
/set view 人格名\n重置会话(清除人格): /reset\n重置会话(保留人格): /reset p", "set"
|
||||
elif l[1] == "list":
|
||||
msg = "人格列表:\n"
|
||||
for key in personalities.keys():
|
||||
msg += f" |-{key}\n"
|
||||
msg += '\n\n*输入/set view 人格名查看人格详细信息'
|
||||
msg += '\n*不定时更新人格库,请及时更新本项目。'
|
||||
return True, msg, "set"
|
||||
elif l[1] == "view":
|
||||
if len(l) == 2:
|
||||
return True, "请输入/set view 人格名", "set"
|
||||
ps = l[2].strip()
|
||||
if ps in personalities:
|
||||
msg = f"人格【{ps}】详细信息:\n"
|
||||
msg += f"{personalities[ps]}\n"
|
||||
else:
|
||||
msg = f"人格【{ps}】不存在。"
|
||||
return True, msg, "set"
|
||||
else:
|
||||
ps = l[1].strip()
|
||||
if ps in personalities:
|
||||
self.reset(session_id, "reset")
|
||||
self.personality_str = personalities[ps]
|
||||
ret = self.provider.text_chat(self.personality_str, session_id)
|
||||
return True, f"人格【{ps}】已设置。\n\n{ret}", "set"
|
||||
else:
|
||||
self.reset(session_id, "reset")
|
||||
self.personality_str = ps
|
||||
ret = self.provider.text_chat(ps, session_id)
|
||||
return True, f"人格信息已设置。\n\n{ret}", "set"
|
||||
|
||||
def switch(self, message: str, session_id: str):
|
||||
'''
|
||||
切换账号
|
||||
'''
|
||||
l = message.split(" ")
|
||||
rev_chatgpt = self.provider.get_revchatgpt()
|
||||
if len(l) == 1:
|
||||
ret = "当前账号:\n"
|
||||
index = 0
|
||||
curr_ = None
|
||||
for revstat in rev_chatgpt:
|
||||
index += 1
|
||||
ret += f"[{index}]. {revstat['id']}\n"
|
||||
# if session_id in revstat['user']:
|
||||
# curr_ = revstat['id']
|
||||
for user in revstat['user']:
|
||||
if session_id == user['id']:
|
||||
curr_ = revstat['id']
|
||||
break
|
||||
if curr_ is None:
|
||||
ret += "当前您未选择账号。输入/switch <账号序号>切换账号。"
|
||||
else:
|
||||
ret += f"当前您选择的账号为:{curr_}。输入/switch <账号序号>切换账号。"
|
||||
return True, ret, "switch"
|
||||
elif len(l) == 2:
|
||||
try:
|
||||
index = int(l[1])
|
||||
if index > len(self.provider.rev_chatgpt) or index < 1:
|
||||
return True, "账号序号不合法。", "switch"
|
||||
else:
|
||||
# pop
|
||||
for revstat in self.provider.rev_chatgpt:
|
||||
if session_id in revstat['user']:
|
||||
revstat['user'].remove(session_id)
|
||||
# append
|
||||
self.provider.rev_chatgpt[index - 1]['user'].append(session_id)
|
||||
return True, f"切换账号成功。当前账号为:{self.provider.rev_chatgpt[index - 1]['id']}", "switch"
|
||||
except BaseException:
|
||||
return True, "账号序号不合法。", "switch"
|
||||
else:
|
||||
return True, "参数过多。", "switch"
|
||||
|
||||
async def help(self):
|
||||
commands = super().general_commands()
|
||||
commands['set'] = '设置人格'
|
||||
return True, await super().help_messager(commands, self.platform, self.global_object.cached_plugins), "help"
|
||||
@@ -1,224 +0,0 @@
|
||||
from revChatGPT.V1 import Chatbot
|
||||
from revChatGPT import typings
|
||||
from model.provider.provider import Provider
|
||||
from util import general_utils as gu
|
||||
from util import cmd_config as cc
|
||||
import time
|
||||
|
||||
|
||||
class ProviderRevChatGPT(Provider):
|
||||
def __init__(self, config, base_url = None):
|
||||
if base_url == "":
|
||||
base_url = None
|
||||
self.rev_chatgpt: list[dict] = []
|
||||
self.cc = cc.CmdConfig()
|
||||
for i in range(0, len(config['account'])):
|
||||
try:
|
||||
gu.log(f"创建逆向ChatGPT负载{str(i+1)}中...", level=gu.LEVEL_INFO, tag="RevChatGPT")
|
||||
|
||||
if isinstance(config['account'][i], str):
|
||||
# 默认是 access_token
|
||||
rev_account_config = {
|
||||
'access_token': config['account'][i],
|
||||
}
|
||||
else:
|
||||
if 'password' in config['account'][i]:
|
||||
gu.log(f"创建逆向ChatGPT负载{str(i+1)}失败: 已不支持账号密码登录,请使用access_token方式登录。", level=gu.LEVEL_ERROR, tag="RevChatGPT")
|
||||
continue
|
||||
rev_account_config = {
|
||||
'access_token': config['account'][i]['access_token'],
|
||||
}
|
||||
if self.cc.get("rev_chatgpt_model") != "":
|
||||
rev_account_config['model'] = self.cc.get("rev_chatgpt_model")
|
||||
if len(self.cc.get("rev_chatgpt_plugin_ids")) > 0:
|
||||
rev_account_config['plugin_ids'] = self.cc.get("rev_chatgpt_plugin_ids")
|
||||
if self.cc.get("rev_chatgpt_PUID") != "":
|
||||
rev_account_config['PUID'] = self.cc.get("rev_chatgpt_PUID")
|
||||
if len(self.cc.get("rev_chatgpt_unverified_plugin_domains")) > 0:
|
||||
rev_account_config['unverified_plugin_domains'] = self.cc.get("rev_chatgpt_unverified_plugin_domains")
|
||||
cb = Chatbot(config=rev_account_config, base_url=base_url)
|
||||
# cb.captcha_solver = self.__captcha_solver
|
||||
# 后八位c
|
||||
g_id = rev_account_config['access_token'][-8:]
|
||||
revstat = {
|
||||
'id': g_id,
|
||||
'obj': cb,
|
||||
'busy': False,
|
||||
'user': []
|
||||
}
|
||||
self.rev_chatgpt.append(revstat)
|
||||
except BaseException as e:
|
||||
gu.log(f"创建逆向ChatGPT负载{str(i+1)}失败: {str(e)}", level=gu.LEVEL_ERROR, tag="RevChatGPT")
|
||||
|
||||
def forget(self, session_id = None) -> bool:
|
||||
for i in self.rev_chatgpt:
|
||||
for user in i['user']:
|
||||
if session_id == user['id']:
|
||||
try:
|
||||
i['obj'].reset_chat()
|
||||
return True
|
||||
except BaseException as e:
|
||||
gu.log(f"重置RevChatGPT失败。原因: {str(e)}", level=gu.LEVEL_ERROR, tag="RevChatGPT")
|
||||
return False
|
||||
return False
|
||||
|
||||
def get_revchatgpt(self) -> list:
|
||||
return self.rev_chatgpt
|
||||
|
||||
def request_text(self, prompt: str, bot) -> str:
|
||||
resp = ''
|
||||
err_count = 0
|
||||
retry_count = 5
|
||||
|
||||
while err_count < retry_count:
|
||||
try:
|
||||
for data in bot.ask(prompt):
|
||||
resp = data["message"]
|
||||
break
|
||||
except typings.Error as e:
|
||||
if e.code == typings.ErrorType.INVALID_ACCESS_TOKEN_ERROR:
|
||||
raise e
|
||||
if e.code == typings.ErrorType.EXPIRED_ACCESS_TOKEN_ERROR:
|
||||
raise e
|
||||
if e.code == typings.ErrorType.PROHIBITED_CONCURRENT_QUERY_ERROR:
|
||||
raise e
|
||||
if "Your authentication token has expired. Please try signing in again." in str(e):
|
||||
raise e
|
||||
if "The message you submitted was too long" in str(e):
|
||||
raise e
|
||||
if "You've reached our limit of messages per hour." in str(e):
|
||||
raise e
|
||||
if "Rate limited by proxy" in str(e):
|
||||
gu.log(f"触发请求频率限制, 60秒后自动重试。", level=gu.LEVEL_WARNING, tag="RevChatGPT")
|
||||
time.sleep(60)
|
||||
|
||||
err_count += 1
|
||||
gu.log(f"请求异常: {str(e)},正在重试。({str(err_count)})", level=gu.LEVEL_WARNING, tag="RevChatGPT")
|
||||
if err_count >= retry_count:
|
||||
raise e
|
||||
except BaseException as e:
|
||||
err_count += 1
|
||||
gu.log(f"请求异常: {str(e)},正在重试。({str(err_count)})", level=gu.LEVEL_WARNING, tag="RevChatGPT")
|
||||
if err_count >= retry_count:
|
||||
raise e
|
||||
if resp == '':
|
||||
resp = "RevChatGPT请求异常。"
|
||||
|
||||
# print("[RevChatGPT] "+str(resp))
|
||||
return resp
|
||||
|
||||
def text_chat(self, prompt,
|
||||
session_id = None,
|
||||
image_url = None,
|
||||
function_call=None,
|
||||
extra_conf: dict = None,
|
||||
default_personality: dict = None) -> str:
|
||||
|
||||
# 选择一个人少的账号。
|
||||
selected_revstat = None
|
||||
min_revstat = None
|
||||
min_ = None
|
||||
new_user = False
|
||||
conversation_id = ''
|
||||
parent_id = ''
|
||||
for revstat in self.rev_chatgpt:
|
||||
for user in revstat['user']:
|
||||
if session_id == user['id']:
|
||||
selected_revstat = revstat
|
||||
conversation_id = user['conversation_id']
|
||||
parent_id = user['parent_id']
|
||||
break
|
||||
if min_ is None:
|
||||
min_ = len(revstat['user'])
|
||||
min_revstat = revstat
|
||||
elif len(revstat['user']) < min_:
|
||||
min_ = len(revstat['user'])
|
||||
min_revstat = revstat
|
||||
# if session_id in revstat['user']:
|
||||
# selected_revstat = revstat
|
||||
# break
|
||||
|
||||
if selected_revstat is None:
|
||||
selected_revstat = min_revstat
|
||||
selected_revstat['user'].append({
|
||||
'id': session_id,
|
||||
'conversation_id': '',
|
||||
'parent_id': ''
|
||||
})
|
||||
new_user = True
|
||||
|
||||
gu.log(f"选择账号{str(selected_revstat)}", tag="RevChatGPT", level=gu.LEVEL_DEBUG)
|
||||
|
||||
while selected_revstat['busy']:
|
||||
gu.log(f"账号忙碌,等待中...", tag="RevChatGPT", level=gu.LEVEL_DEBUG)
|
||||
time.sleep(1)
|
||||
selected_revstat['busy'] = True
|
||||
|
||||
if not new_user:
|
||||
# 非新用户,则使用其专用的会话
|
||||
selected_revstat['obj'].conversation_id = conversation_id
|
||||
selected_revstat['obj'].parent_id = parent_id
|
||||
else:
|
||||
# 新用户,则使用新的会话
|
||||
selected_revstat['obj'].reset_chat()
|
||||
|
||||
res = ''
|
||||
err_msg = ''
|
||||
err_cnt = 0
|
||||
while err_cnt < 15:
|
||||
try:
|
||||
res = self.request_text(prompt, selected_revstat['obj'])
|
||||
selected_revstat['busy'] = False
|
||||
# 记录新用户的会话
|
||||
if new_user:
|
||||
i = 0
|
||||
for user in selected_revstat['user']:
|
||||
if user['id'] == session_id:
|
||||
selected_revstat['user'][i]['conversation_id'] = selected_revstat['obj'].conversation_id
|
||||
selected_revstat['user'][i]['parent_id'] = selected_revstat['obj'].parent_id
|
||||
break
|
||||
i += 1
|
||||
return res.strip()
|
||||
except BaseException as e:
|
||||
if "Your authentication token has expired. Please try signing in again." in str(e):
|
||||
raise Exception(f"此账号(access_token后8位为{selected_revstat['id']})的access_token已过期,请重新获取,或者切换账号。")
|
||||
if "The message you submitted was too long" in str(e):
|
||||
raise Exception("发送的消息太长,请分段发送。")
|
||||
if "You've reached our limit of messages per hour." in str(e):
|
||||
raise Exception("触发RevChatGPT请求频率限制。请1小时后再试,或者切换账号。")
|
||||
gu.log(f"请求异常: {str(e)}", level=gu.LEVEL_WARNING, tag="RevChatGPT")
|
||||
err_cnt += 1
|
||||
time.sleep(3)
|
||||
|
||||
raise Exception(f'回复失败。原因:{err_msg}。如果您设置了多个账号,可以使用/switch指令切换账号。输入/switch查看详情。')
|
||||
|
||||
|
||||
# while self.is_all_busy():
|
||||
# time.sleep(1)
|
||||
# res = ''
|
||||
# err_msg = ''
|
||||
# cursor = 0
|
||||
# for revstat in self.rev_chatgpt:
|
||||
# cursor += 1
|
||||
# if not revstat['busy']:
|
||||
# try:
|
||||
# revstat['busy'] = True
|
||||
# res = self.request_text(prompt, revstat['obj'])
|
||||
# revstat['busy'] = False
|
||||
# return res.strip()
|
||||
# # todo: 细化错误管理
|
||||
# except BaseException as e:
|
||||
# revstat['busy'] = False
|
||||
# gu.log(f"请求出现问题: {str(e)}", level=gu.LEVEL_WARNING, tag="RevChatGPT")
|
||||
# err_msg += f"账号{cursor} - 错误原因: {str(e)}"
|
||||
# continue
|
||||
# else:
|
||||
# err_msg += f"账号{cursor} - 错误原因: 忙碌"
|
||||
# continue
|
||||
# raise Exception(f'回复失败。错误跟踪:{err_msg}')
|
||||
|
||||
def is_all_busy(self) -> bool:
|
||||
for revstat in self.rev_chatgpt:
|
||||
if not revstat['busy']:
|
||||
return False
|
||||
return True
|
||||
@@ -11,7 +11,6 @@ beautifulsoup4
|
||||
googlesearch-python
|
||||
tiktoken
|
||||
readability-lxml
|
||||
revChatGPT~=6.8.6
|
||||
baidu-aip~=4.16.9
|
||||
websockets
|
||||
flask
|
||||
|
||||
@@ -88,10 +88,6 @@ def init_astrbot_config_items():
|
||||
cc.init_attributes("qq_forward_threshold", 200)
|
||||
cc.init_attributes("qq_welcome", "欢迎加入本群!\n欢迎给https://github.com/Soulter/QQChannelChatGPT项目一个Star😊~\n输入help查看帮助~\n")
|
||||
cc.init_attributes("qq_pic_mode", False)
|
||||
cc.init_attributes("rev_chatgpt_model", "")
|
||||
cc.init_attributes("rev_chatgpt_plugin_ids", [])
|
||||
cc.init_attributes("rev_chatgpt_PUID", "")
|
||||
cc.init_attributes("rev_chatgpt_unverified_plugin_domains", [])
|
||||
cc.init_attributes("gocq_host", "127.0.0.1")
|
||||
cc.init_attributes("gocq_http_port", 5700)
|
||||
cc.init_attributes("gocq_websocket_port", 6700)
|
||||
|
||||
@@ -134,7 +134,7 @@ class Logger:
|
||||
self.history = self.history[-100:]
|
||||
print(ret[:-1])
|
||||
|
||||
log = Logger()
|
||||
log = Logger().log
|
||||
|
||||
def port_checker(port: int, host: str = "localhost"):
|
||||
sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
|
||||
|
||||
Reference in New Issue
Block a user