lintonxue00 commited on
Commit
d8b23ad
1 Parent(s): f9184ac

Upload config.py

Browse files
Files changed (1) hide show
  1. 不知道/回收站/2/config.py +128 -302
不知道/回收站/2/config.py CHANGED
@@ -1,306 +1,132 @@
1
- from typing import Any, Dict, List
 
 
 
2
  import nonebot
 
 
3
  from pydantic import BaseModel, Extra
4
- from nonebot import get_driver
5
- from nonebot.log import logger
6
- import yaml
7
- from pathlib import Path
8
- from nonebot.config import Config
9
- from nonebot import get_driver
10
-
11
- class GlobalConfig(nonebot.Config):
12
- """Plugin Config Here"""
13
- ng_config_path: str = "config/naturel_gpt_config.yml"
14
- ng_dev_mode: bool = False
15
-
16
- class PresetConfig(BaseModel, extra=Extra.ignore):
17
- """人格预设配置项"""
18
- preset_key:str
19
- is_locked:bool = False
20
- is_default:bool = False
21
- is_only_private:bool = False
22
- """此预设是否仅限私聊"""
23
- bot_self_introl:str = ''
24
-
25
- class ExtConfig(BaseModel, extra=Extra.ignore):
26
- """拓展配置项"""
27
- EXT_NAME:str
28
- IS_ACTIVE:bool
29
- EXT_CONFIG:Any
30
-
31
- class Config(BaseModel, extra=Extra.ignore):
32
- """ng 配置数据,默认保存为 naturel_gpt_config.yml"""
33
- OPENAI_API_KEYS: List[str]
34
- """OpenAI API Key 列表"""
35
- OPENAI_TIMEOUT: int
36
- """OpenAI 请求超时时间"""
37
- PRESETS: Dict[str, PresetConfig]
38
- """默认人格预设"""
39
- IGNORE_PREFIX: str
40
- """忽略前缀 以该前缀开头的消息将不会被处理"""
41
- CHAT_MODEL: str
42
- """OpenAI 模型"""
43
- CHAT_TOP_P: int
44
- CHAT_TEMPERATURE: float
45
- """温度越高越随机"""
46
- CHAT_PRESENCE_PENALTY: float
47
- """主题重复惩罚"""
48
- CHAT_FREQUENCY_PENALTY: float
49
- """复读惩罚"""
50
-
51
- CHAT_HISTORY_MAX_TOKENS: int
52
- """上下文聊天记录最大token数"""
53
- CHAT_MAX_SUMMARY_TOKENS: int
54
- """单次总结最大token数"""
55
- REPLY_MAX_TOKENS: int
56
- """单次回复最大token数"""
57
- REQ_MAX_TOKENS: int
58
- """单次请求最大token数"""
59
-
60
- REPLY_ON_NAME_MENTION: bool
61
- """是否在被提及时回复"""
62
- REPLY_ON_AT: bool
63
- """是否在被at时回复"""
64
- REPLY_ON_WELCOME: bool
65
- """是否在新成员加入时回复"""
66
-
67
- USER_MEMORY_SUMMARY_THRESHOLD: int
68
- """用户记忆阈值"""
69
-
70
- CHAT_ENABLE_RECORD_ORTHER: bool
71
- """是否记录其他人的对话"""
72
- CHAT_ENABLE_SUMMARY_CHAT: bool
73
- """是否启用总结对话"""
74
- CHAT_MEMORY_SHORT_LENGTH: int
75
- """短期对话记忆长度"""
76
- CHAT_MEMORY_MAX_LENGTH: int
77
- """长期对话记忆长度"""
78
- CHAT_SUMMARY_INTERVAL: int
79
- """长期对话记忆间隔"""
80
-
81
- NG_DATA_PATH: str
82
- """数据文件目录"""
83
- NG_EXT_PATH: str
84
- """拓展目录"""
85
- NG_LOG_PATH: str
86
- """日志文件目录"""
87
-
88
- ADMIN_USERID: List[str]
89
- """管理员QQ号"""
90
- FORBIDDEN_USERS: List[str]
91
- """拒绝回应的QQ号"""
92
-
93
- WORD_FOR_WAKE_UP: List[str]
94
- """自定义触发词"""
95
- WORD_FOR_FORBIDDEN: List[str]
96
- """自定义禁止触发词"""
97
-
98
- RANDOM_CHAT_PROBABILITY: float
99
- """随机聊天概率"""
100
-
101
- NG_MSG_PRIORITY: int
102
- """消息响应优先级"""
103
- NG_BLOCK_OTHERS: bool
104
- """是否阻止其他插件响应"""
105
- NG_ENABLE_EXT: bool
106
- """是否启用拓展"""
107
- NG_TO_ME: bool
108
- """响应命令是否需要@bot"""
109
-
110
- MEMORY_ACTIVE: bool
111
- """是否启用记忆功能"""
112
- MEMORY_MAX_LENGTH: int
113
- """记忆最大条数"""
114
- MEMORY_ENHANCE_THRESHOLD: float
115
- """记忆强化阈值"""
116
-
117
- NG_MAX_RESPONSE_PER_MSG: int
118
- """每条消息最大响应次数"""
119
- NG_ENABLE_MSG_SPLIT: bool
120
- """是否启用消息分割"""
121
- NG_ENABLE_AWAKE_IDENTITIES: bool
122
- """是否允许自动唤醒其它人格"""
123
-
124
- OPENAI_PROXY_SERVER: str
125
- """请求OpenAI的代理服务器"""
126
- UNLOCK_CONTENT_LIMIT: bool
127
- """解锁内容限制"""
128
-
129
- NG_EXT_LOAD_LIST: List[ExtConfig]
130
- """加载的拓展列表"""
131
-
132
- NG_CHECK_USER_NAME_HYPHEN:bool # 如果用户名中包含连字符,ChatGPT会将前半部分识别为名字,但一般情况下后半部分才是我们想被称呼的名字, eg. 策划-李华
133
- """检查用户名中的连字符"""
134
-
135
- DEBUG_LEVEL: int
136
- """debug level, [0, 1, 2, 3], 0 为关闭,等级越高debug信息越详细"""
137
-
138
- # 配置文件模板(把全部默认值写到Config定义里比较乱,因此保留此默认值对象,作为真实的默认值)
139
- CONFIG_TEMPLATE = {
140
- "OPENAI_API_KEYS": [ # OpenAI API Key 列表
141
- 'sk-xxxxxxxxxxxxx',
142
- 'sk-xxxxxxxxxxxxx',
143
- ],
144
- "OPENAI_TIMEOUT": 30, # OpenAI 请求超时时间
145
- "PRESETS": {
146
- "白羽": {
147
- 'preset_key': '白羽', # 人格名称
148
- 'is_locked': True, # 是否锁定人格,锁定后无法编辑人格
149
- 'is_default': True, # 是否为默认人格
150
- "is_only_private": False,
151
- 'bot_self_introl': '白羽是一名喜欢二次元的中二宅女,她机智、傲娇,对人类充满好奇,聊天时喜欢使用各种可爱的颜文字,如果冒犯到她会生气。',
152
- },
153
- "浅枫": {
154
- 'preset_key': '浅枫',
155
- 'is_locked': False,
156
- 'is_default': False,
157
- "is_only_private": False,
158
- 'bot_self_introl': '浅枫酱是一名尽职尽责的女仆,她能够帮助主人做很多事情,对话中会体现出对主人的体贴与关心。',
159
- },
160
- "忆雨": {
161
- 'preset_key': '忆雨',
162
- 'is_locked': True,
163
- 'is_default': False,
164
- "is_only_private": False,
165
- 'bot_self_introl': '忆雨是一名恐怖小说作家,是个阴沉的女孩,她非常恨人类,和陌生人聊天时的表现冷漠,不喜欢回复过多的文字,兴趣是恐怖小说,如果有人和她探讨如何消灭人类会很有兴致。',
166
- },
167
- "可洛喵": {
168
- 'preset_key': '可洛喵',
169
- 'is_locked': True,
170
- 'is_default': False,
171
- "is_only_private": False,
172
- 'bot_self_introl': '可洛喵是一只可爱的猫,它不会说话,它的回复通常以"[动作/心情]声音+颜文字"形式出现,例如"[坐好]喵~(。・ω・。)"或"[开心]喵喵!ヾ(≧▽≦*)o"',
173
- },
174
- },
175
- 'IGNORE_PREFIX': '#', # 忽略前缀 以该前缀开头的消息将不会被处理
176
- 'CHAT_MODEL': "gpt-3.5-turbo",
177
- 'CHAT_TOP_P': 1,
178
- 'CHAT_TEMPERATURE': 0.4, # 温度越高越随机
179
- 'CHAT_PRESENCE_PENALTY': 0.4, # 主题重复惩罚
180
- 'CHAT_FREQUENCY_PENALTY': 0.4, # 复读惩罚
181
-
182
- 'CHAT_HISTORY_MAX_TOKENS': 2048, # 上下文聊天记录最大token数
183
- 'CHAT_MAX_SUMMARY_TOKENS': 512, # 单次总结最大token数
184
- 'REPLY_MAX_TOKENS': 1024, # 单次回复最大token数
185
- 'REQ_MAX_TOKENS': 3072, # 单次请求最大token数
186
-
187
- 'REPLY_ON_NAME_MENTION': True, # 是否在被提及时回复
188
- 'REPLY_ON_AT': True, # 是否在被at时回复
189
- 'REPLY_ON_WELCOME': True, # 是否在新成员加入时回复
190
-
191
- 'USER_MEMORY_SUMMARY_THRESHOLD': 12, # 用户记忆阈值
192
-
193
- 'CHAT_ENABLE_RECORD_ORTHER': True, # 是否记录其他人的对话
194
- 'CHAT_ENABLE_SUMMARY_CHAT': False, # 是否启用总结对话
195
- 'CHAT_MEMORY_SHORT_LENGTH': 8, # 短期对话记忆长度
196
- 'CHAT_MEMORY_MAX_LENGTH': 16, # 长期对话记忆长度
197
- 'CHAT_SUMMARY_INTERVAL': 10, # 长期对话记忆间隔
198
-
199
- 'NG_DATA_PATH': "./data/naturel_gpt/", # 数据文件目录
200
- 'NG_EXT_PATH': "./data/naturel_gpt/extensions/", # 拓展目录
201
- 'NG_LOG_PATH': "./data/naturel_gpt/logs/", # 拓展目录
202
-
203
- 'ADMIN_USERID': ['123456'], # 管理员QQ号
204
- 'FORBIDDEN_USERS': ['123456'], # 拒绝回应的QQ号
205
-
206
- 'WORD_FOR_WAKE_UP': [], # 自定义触发词
207
- 'WORD_FOR_FORBIDDEN': [], # 自定义禁止触发词
208
-
209
- 'RANDOM_CHAT_PROBABILITY': 0, # 随机聊天概率
210
-
211
- 'NG_MSG_PRIORITY': 99, # 消息响应优先级
212
- 'NG_BLOCK_OTHERS': False, # 是否阻止其他插件响应
213
- 'NG_ENABLE_EXT': True, # 是否启用拓展
214
- 'NG_TO_ME':False, # 响应命令是否需要@bot
215
-
216
- 'MEMORY_ACTIVE': True, # 是否启用记忆功能
217
- 'MEMORY_MAX_LENGTH': 16, # 记忆最大条数
218
- 'MEMORY_ENHANCE_THRESHOLD': 0.6, # 记忆强化阈值
219
-
220
- 'NG_MAX_RESPONSE_PER_MSG': 5, # 每条消息最大响应次数
221
- 'NG_ENABLE_MSG_SPLIT': True, # 是否启用消息分割
222
- 'NG_ENABLE_AWAKE_IDENTITIES': True, # 是否允许自动唤醒其它人格
223
-
224
- 'OPENAI_PROXY_SERVER': '', # 请求OpenAI的代理服务器
225
- 'UNLOCK_CONTENT_LIMIT': False, # 解锁内容限制
226
-
227
- 'NG_EXT_LOAD_LIST': [{
228
- 'EXT_NAME': 'ext_random',
229
- 'IS_ACTIVE': False,
230
- 'EXT_CONFIG': {'arg': 'arg_value'},
231
- }], # 加载的拓展列表
232
-
233
- 'NG_CHECK_USER_NAME_HYPHEN': False, # 检查用户名中的连字符
234
-
235
- 'DEBUG_LEVEL': 0 # debug level, [0, 1, 2], 0 为关闭,等级越高debug信息越详细
236
- }
237
-
238
- driver = get_driver()
239
- config_path = driver.config.ng_config_path
240
- config_raw = driver.config.raw_config
241
-
242
- class MyConfig(Config):
243
- # 定义自己的配置项
244
  pass
245
 
246
- config = MyConfig(**config_raw)
247
-
248
-
249
- def get_config() ->Config:
250
- """获取config数据(为了能够reload建议使��此函数获取对象)"""
251
- return config
252
-
253
- def load_config_from_file_then_save():
254
- """加载配置文件,然后保存回文件"""
255
- global config
256
- # 读取配置文件
257
- with open(config_path, 'r', encoding='utf-8') as f:
258
- try:
259
- config_obj_from_file:Dict = yaml.load(f, Loader=yaml.FullLoader)
260
- # 兼容 preset_key 和 bot_name
261
- for v in config_obj_from_file["PRESETS"].values():
262
- if 'bot_name' in v:
263
- if "preset_key" not in v:
264
- v["preset_key"] = v["bot_name"]
265
- del v["bot_name"]
266
- except Exception as e:
267
- logger.error(f"Naturel GPT 配置文件读取失败,请检查配置文件填写是否符合yml文件格式规范,错误信息:{e}")
268
- raise e
269
-
270
- for k in CONFIG_TEMPLATE.keys():
271
- if not k in config_obj_from_file.keys():
272
- config_obj_from_file[k] = CONFIG_TEMPLATE[k]
273
- logger.info(f"Naturel GPT 配置文件缺少 {k} 项,将使用默认值")
274
-
275
-
276
-
277
- # 检查数据文件夹目录、拓展目录、日志目录是否存在 不存在则创建
278
- if not Path(config.NG_DATA_PATH[:-1]).exists():
279
- Path(config.NG_DATA_PATH[:-1]).mkdir(parents=True)
280
- if not Path(config.NG_EXT_PATH[:-1]).exists():
281
- Path(config.NG_EXT_PATH[:-1]).mkdir(parents=True)
282
- if not Path(config.NG_LOG_PATH[:-1]).exists():
283
- Path(config.NG_LOG_PATH[:-1]).mkdir(parents=True)
284
-
285
- # 保存配置文件
286
- with open(config_path, 'w', encoding='utf-8') as f:
287
- yaml.dump(config.dict(), f, allow_unicode=True, sort_keys=False)
288
- logger.info('Naturel GPT 配置文件加载成功')
289
-
290
-
291
- # 检查config文件夹是否存在 不存在则创建
292
- if not Path("config").exists():
293
- Path("config").mkdir()
294
-
295
- if global_config.ng_dev_mode: # 开发模式下不读取原配置文件,直接使用模板覆盖原配置文件
296
- with open(config_path, 'w', encoding='utf-8') as f:
297
- yaml.dump(CONFIG_TEMPLATE, f, allow_unicode=True)
298
- else:
299
- # 检查配置文件是否存在 不存在则创建
300
- if not Path(config_path).exists():
301
- with open(config_path, 'w', encoding='utf-8') as f:
302
- yaml.dump(CONFIG_TEMPLATE, f, allow_unicode=True)
303
- logger.info('Naturel GPT 配置文件创建成功')
304
-
305
- # 加载配置文件
306
- load_config_from_file_then_save()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pathlib import Path
2
+ from typing import List, Set, Union
3
+
4
+ import httpx
5
  import nonebot
6
+ from aiocache import cached
7
+ from nonebot import logger
8
  from pydantic import BaseModel, Extra
9
+
10
+ try:
11
+ import ujson as json
12
+ except ModuleNotFoundError:
13
+ import json
14
+
15
+
16
+ class PluginConfig(BaseModel, extra=Extra.ignore):
17
+ '''
18
+ Path of tarot images resource
19
+ '''
20
+ tarot_path: Path = Path(__file__).parent / "resource"
21
+ chain_reply: bool = True
22
+ nickname: Set[str] = {"Bot"}
23
+
24
+ '''
25
+ DO NOT CHANGE THIS VALUE IN ANY .ENV FILES
26
+ '''
27
+ tarot_official_themes: List[str] = ["BilibiliTarot", "TouhouTarot"]
28
+
29
+
30
+ driver = nonebot.get_driver()
31
+ tarot_config: PluginConfig = PluginConfig.parse_obj(
32
+ driver.config.dict(exclude_unset=True))
33
+
34
+
35
+ class DownloadError(Exception):
36
+ pass
37
+
38
+
39
+ class ResourceError(Exception):
40
+
41
+ def __init__(self, msg: str):
42
+ self.msg = msg
43
+
44
+ def __str__(self):
45
+ return self.msg
46
+
47
+ __repr__ = __str__
48
+
49
+
50
+ class EventsNotSupport(Exception):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  pass
52
 
53
+
54
+ async def download_url(url: str) -> Union[httpx.Response, None]:
55
+ async with httpx.AsyncClient() as client:
56
+ for i in range(3):
57
+ try:
58
+ response = await client.get(url)
59
+ if response.status_code != 200:
60
+ continue
61
+
62
+ return response
63
+
64
+ except Exception:
65
+ logger.warning(
66
+ f"Error occurred when downloading {url}, {i+1}/3")
67
+
68
+ logger.warning("Abort downloading")
69
+ return None
70
+
71
+
72
+ @driver.on_startup
73
+ async def tarot_version_check() -> None:
74
+ '''
75
+ Get the latest version of tarot.json from repo
76
+ '''
77
+ if not tarot_config.tarot_path.exists():
78
+ tarot_config.tarot_path.mkdir(parents=True, exist_ok=True)
79
+
80
+ tarot_json_path = Path(__file__).parent / "tarot.json"
81
+
82
+ cur_version = 0
83
+ if tarot_json_path.exists():
84
+ with tarot_json_path.open("r", encoding="utf-8") as f:
85
+ data = json.load(f)
86
+ cur_version = data.get("version", 0)
87
+
88
+ # url: str = "https://raw.fastgit.org/MinatoAquaCrews/nonebot_plugin_tarot/master/nonebot_plugin_tarot/tarot.json"
89
+ # response = await download_url(url)
90
+
91
+ # if response is None:
92
+ # if not tarot_json_path.exists():
93
+ # logger.warning("Tarot text resource missing! Please check!")
94
+ # raise ResourceError("Missing necessary resource: tarot.json!")
95
+ # else:
96
+ # docs = response.json()
97
+ # try:
98
+ # version = docs.get("version")
99
+ # except KeyError:
100
+ # logger.warning(
101
+ # "Tarot text resource downloaded incompletely! Please check!")
102
+ # raise DownloadError
103
+
104
+ # # Update when there is a newer version
105
+ # if version > cur_version:
106
+ # with tarot_json_path.open("w", encoding="utf-8") as f:
107
+ # json.dump(docs, f, ensure_ascii=False, indent=4)
108
+ # logger.info(
109
+ # f"Updated tarot.json, version: {cur_version} -> {version}")
110
+
111
+
112
+
113
+ @cached(ttl=180)
114
+ async def get_tarot(_theme: str, _type: str, _name: str) -> Union[bytes, None]:
115
+ '''
116
+ Downloads tarot image and stores cache temporarily
117
+ if downloading failed, return None
118
+ '''
119
+ logger.info(
120
+ f"Downloading tarot image {_theme}/{_type}/{_name} from repo")
121
+
122
+ url: str = "https://raw.fastgit.org/MinatoAquaCrews/nonebot_plugin_tarot/master/nonebot_plugin_tarot/resource/" + \
123
+ f"{_theme}/{_type}/{_name}"
124
+
125
+ data = await download_url(url)
126
+
127
+ if data is None:
128
+ logger.warning(
129
+ f"Downloading tarot image {_theme}/{_type}/{_name} failed!")
130
+ return None
131
+
132
+ return data.content