feat: add plugin global config to support docker volumes
parent
2361e3c28c
commit
954e55f4b4
26
config.py
26
config.py
|
|
@ -37,7 +37,8 @@ available_setting = {
|
||||||
"image_create_size": "256x256", # 图片大小,可选有 256x256, 512x512, 1024x1024
|
"image_create_size": "256x256", # 图片大小,可选有 256x256, 512x512, 1024x1024
|
||||||
# chatgpt会话参数
|
# chatgpt会话参数
|
||||||
"expires_in_seconds": 3600, # 无操作会话的过期时间
|
"expires_in_seconds": 3600, # 无操作会话的过期时间
|
||||||
"character_desc": "你是ChatGPT, 一个由OpenAI训练的大型语言模型, 你旨在回答并解决人们的任何问题,并且可以使用多种语言与人交流。", # 人格描述
|
# 人格描述
|
||||||
|
"character_desc": "你是ChatGPT, 一个由OpenAI训练的大型语言模型, 你旨在回答并解决人们的任何问题,并且可以使用多种语言与人交流。",
|
||||||
"conversation_max_tokens": 1000, # 支持上下文记忆的最多字符数
|
"conversation_max_tokens": 1000, # 支持上下文记忆的最多字符数
|
||||||
# chatgpt限流配置
|
# chatgpt限流配置
|
||||||
"rate_limit_chatgpt": 20, # chatgpt的调用频率限制
|
"rate_limit_chatgpt": 20, # chatgpt的调用频率限制
|
||||||
|
|
@ -228,3 +229,26 @@ def subscribe_msg():
|
||||||
trigger_prefix = conf().get("single_chat_prefix", [""])[0]
|
trigger_prefix = conf().get("single_chat_prefix", [""])[0]
|
||||||
msg = conf().get("subscribe_msg", "")
|
msg = conf().get("subscribe_msg", "")
|
||||||
return msg.format(trigger_prefix=trigger_prefix)
|
return msg.format(trigger_prefix=trigger_prefix)
|
||||||
|
|
||||||
|
|
||||||
|
# global plugin config
|
||||||
|
plugin_config = {}
|
||||||
|
|
||||||
|
|
||||||
|
def write_plugin_config(pconf: dict):
|
||||||
|
"""
|
||||||
|
写入插件全局配置
|
||||||
|
:param pconf: 全量插件配置
|
||||||
|
"""
|
||||||
|
global plugin_config
|
||||||
|
for k in pconf:
|
||||||
|
plugin_config[k.lower()] = pconf[k]
|
||||||
|
|
||||||
|
|
||||||
|
def pconf(plugin_name: str) -> dict:
|
||||||
|
"""
|
||||||
|
根据插件名称获取配置
|
||||||
|
:param plugin_name: 插件名称
|
||||||
|
:return: 该插件的配置项
|
||||||
|
"""
|
||||||
|
return plugin_config.get(plugin_name.lower())
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ class Banwords(Plugin):
|
||||||
json.dump(conf, f, indent=4)
|
json.dump(conf, f, indent=4)
|
||||||
else:
|
else:
|
||||||
with open(config_path, "r") as f:
|
with open(config_path, "r") as f:
|
||||||
conf = json.load(f)
|
conf = super().load_config() or json.load(f)
|
||||||
self.searchr = WordsSearch()
|
self.searchr = WordsSearch()
|
||||||
self.action = conf["action"]
|
self.action = conf["action"]
|
||||||
banwords_path = os.path.join(curdir, "banwords.txt")
|
banwords_path = os.path.join(curdir, "banwords.txt")
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ class BDunit(Plugin):
|
||||||
raise Exception("config.json not found")
|
raise Exception("config.json not found")
|
||||||
else:
|
else:
|
||||||
with open(config_path, "r") as f:
|
with open(config_path, "r") as f:
|
||||||
conf = json.load(f)
|
conf = super().load_config() or json.load(f)
|
||||||
self.service_id = conf["service_id"]
|
self.service_id = conf["service_id"]
|
||||||
self.api_key = conf["api_key"]
|
self.api_key = conf["api_key"]
|
||||||
self.secret_key = conf["secret_key"]
|
self.secret_key = conf["secret_key"]
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"godcmd": {
|
||||||
|
"password": "",
|
||||||
|
"admin_users": []
|
||||||
|
},
|
||||||
|
"banwords": {
|
||||||
|
"action": "replace",
|
||||||
|
"reply_filter": true,
|
||||||
|
"reply_action": "ignore"
|
||||||
|
},
|
||||||
|
"tool": {
|
||||||
|
"tools": [
|
||||||
|
"python",
|
||||||
|
"url-get",
|
||||||
|
"terminal",
|
||||||
|
"meteo-weather"
|
||||||
|
],
|
||||||
|
"kwargs": {
|
||||||
|
"top_k_results": 2,
|
||||||
|
"no_default": false,
|
||||||
|
"model_name": "gpt-3.5-turbo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -187,7 +187,7 @@ class Godcmd(Plugin):
|
||||||
json.dump(gconf, f, indent=4)
|
json.dump(gconf, f, indent=4)
|
||||||
else:
|
else:
|
||||||
with open(config_path, "r") as f:
|
with open(config_path, "r") as f:
|
||||||
gconf = json.load(f)
|
gconf = super().load_config() or json.load(f)
|
||||||
if gconf["password"] == "":
|
if gconf["password"] == "":
|
||||||
self.temp_password = "".join(random.sample(string.digits, 4))
|
self.temp_password = "".join(random.sample(string.digits, 4))
|
||||||
logger.info("[Godcmd] 因未设置口令,本次的临时口令为%s。" % self.temp_password)
|
logger.info("[Godcmd] 因未设置口令,本次的临时口令为%s。" % self.temp_password)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,16 @@
|
||||||
|
import os
|
||||||
|
from config import pconf
|
||||||
|
|
||||||
class Plugin:
|
class Plugin:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.handlers = {}
|
self.handlers = {}
|
||||||
|
|
||||||
|
def load_config(self) -> dict:
|
||||||
|
"""
|
||||||
|
加载当前插件配置
|
||||||
|
:return: 插件配置字典
|
||||||
|
"""
|
||||||
|
return pconf(self.name)
|
||||||
|
|
||||||
def get_help_text(self, **kwargs):
|
def get_help_text(self, **kwargs):
|
||||||
return "暂无帮助信息"
|
return "暂无帮助信息"
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import sys
|
||||||
from common.log import logger
|
from common.log import logger
|
||||||
from common.singleton import singleton
|
from common.singleton import singleton
|
||||||
from common.sorted_dict import SortedDict
|
from common.sorted_dict import SortedDict
|
||||||
from config import conf
|
from config import conf, write_plugin_config
|
||||||
|
|
||||||
from .event import *
|
from .event import *
|
||||||
|
|
||||||
|
|
@ -62,6 +62,28 @@ class PluginManager:
|
||||||
self.save_config()
|
self.save_config()
|
||||||
return pconf
|
return pconf
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _load_all_config():
|
||||||
|
"""
|
||||||
|
背景: 目前插件配置存放于每个插件目录的config.json下,docker运行时不方便进行映射,故增加统一管理的入口,优先
|
||||||
|
加载 plugins/config.json,原插件目录下的config.json 不受影响
|
||||||
|
|
||||||
|
从 plugins/config.json 中加载所有插件的配置并写入 config.py 的全局配置中,供插件中使用
|
||||||
|
插件实例中通过 config.pconf(plugin_name) 即可获取该插件的配置
|
||||||
|
"""
|
||||||
|
all_config_path = "./plugins/config.json"
|
||||||
|
try:
|
||||||
|
if os.path.exists(all_config_path):
|
||||||
|
# read from all plugins config
|
||||||
|
with open(all_config_path, "r", encoding="utf-8") as f:
|
||||||
|
all_conf = json.load(f)
|
||||||
|
logger.info(f"load all config from plugins/config.json: {all_conf}")
|
||||||
|
|
||||||
|
# write to global config
|
||||||
|
write_plugin_config(all_conf)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(e)
|
||||||
|
|
||||||
def scan_plugins(self):
|
def scan_plugins(self):
|
||||||
logger.info("Scaning plugins ...")
|
logger.info("Scaning plugins ...")
|
||||||
plugins_dir = "./plugins"
|
plugins_dir = "./plugins"
|
||||||
|
|
@ -88,7 +110,7 @@ class PluginManager:
|
||||||
self.loaded[plugin_path] = importlib.import_module(import_path)
|
self.loaded[plugin_path] = importlib.import_module(import_path)
|
||||||
self.current_plugin_path = None
|
self.current_plugin_path = None
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception("Failed to import plugin %s: %s" % (plugin_name, e))
|
logger.warn("Failed to import plugin %s: %s" % (plugin_name, e))
|
||||||
continue
|
continue
|
||||||
pconf = self.pconf
|
pconf = self.pconf
|
||||||
news = [self.plugins[name] for name in self.plugins]
|
news = [self.plugins[name] for name in self.plugins]
|
||||||
|
|
@ -149,6 +171,8 @@ class PluginManager:
|
||||||
def load_plugins(self):
|
def load_plugins(self):
|
||||||
self.load_config()
|
self.load_config()
|
||||||
self.scan_plugins()
|
self.scan_plugins()
|
||||||
|
# 加载全量插件配置
|
||||||
|
self._load_all_config()
|
||||||
pconf = self.pconf
|
pconf = self.pconf
|
||||||
logger.debug("plugins.json config={}".format(pconf))
|
logger.debug("plugins.json config={}".format(pconf))
|
||||||
for name, plugin in pconf["plugins"].items():
|
for name, plugin in pconf["plugins"].items():
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@ class Tool(Plugin):
|
||||||
return tool_config
|
return tool_config
|
||||||
else:
|
else:
|
||||||
with open(config_path, "r") as f:
|
with open(config_path, "r") as f:
|
||||||
tool_config = json.load(f)
|
tool_config = super().load_config() or json.load(f)
|
||||||
return tool_config
|
return tool_config
|
||||||
|
|
||||||
def _build_tool_kwargs(self, kwargs: dict):
|
def _build_tool_kwargs(self, kwargs: dict):
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue