AstrBot 4.5.0__py3-none-any.whl → 4.5.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (244) hide show
  1. astrbot/api/__init__.py +10 -11
  2. astrbot/api/event/__init__.py +5 -6
  3. astrbot/api/event/filter/__init__.py +37 -36
  4. astrbot/api/platform/__init__.py +7 -8
  5. astrbot/api/provider/__init__.py +7 -7
  6. astrbot/api/star/__init__.py +3 -4
  7. astrbot/api/util/__init__.py +2 -2
  8. astrbot/cli/__main__.py +5 -5
  9. astrbot/cli/commands/__init__.py +3 -3
  10. astrbot/cli/commands/cmd_conf.py +19 -16
  11. astrbot/cli/commands/cmd_init.py +3 -2
  12. astrbot/cli/commands/cmd_plug.py +8 -10
  13. astrbot/cli/commands/cmd_run.py +5 -6
  14. astrbot/cli/utils/__init__.py +6 -6
  15. astrbot/cli/utils/basic.py +14 -14
  16. astrbot/cli/utils/plugin.py +24 -15
  17. astrbot/cli/utils/version_comparator.py +10 -12
  18. astrbot/core/__init__.py +8 -6
  19. astrbot/core/agent/agent.py +3 -2
  20. astrbot/core/agent/handoff.py +6 -2
  21. astrbot/core/agent/hooks.py +9 -6
  22. astrbot/core/agent/mcp_client.py +50 -15
  23. astrbot/core/agent/message.py +168 -0
  24. astrbot/core/agent/response.py +2 -1
  25. astrbot/core/agent/run_context.py +2 -3
  26. astrbot/core/agent/runners/base.py +10 -13
  27. astrbot/core/agent/runners/tool_loop_agent_runner.py +52 -51
  28. astrbot/core/agent/tool.py +60 -41
  29. astrbot/core/agent/tool_executor.py +9 -3
  30. astrbot/core/astr_agent_context.py +3 -1
  31. astrbot/core/astrbot_config_mgr.py +29 -9
  32. astrbot/core/config/__init__.py +2 -2
  33. astrbot/core/config/astrbot_config.py +28 -26
  34. astrbot/core/config/default.py +44 -6
  35. astrbot/core/conversation_mgr.py +105 -36
  36. astrbot/core/core_lifecycle.py +68 -54
  37. astrbot/core/db/__init__.py +33 -18
  38. astrbot/core/db/migration/helper.py +18 -13
  39. astrbot/core/db/migration/migra_3_to_4.py +53 -34
  40. astrbot/core/db/migration/migra_45_to_46.py +1 -1
  41. astrbot/core/db/migration/shared_preferences_v3.py +2 -1
  42. astrbot/core/db/migration/sqlite_v3.py +26 -23
  43. astrbot/core/db/po.py +27 -18
  44. astrbot/core/db/sqlite.py +74 -45
  45. astrbot/core/db/vec_db/base.py +10 -14
  46. astrbot/core/db/vec_db/faiss_impl/document_storage.py +90 -77
  47. astrbot/core/db/vec_db/faiss_impl/embedding_storage.py +9 -3
  48. astrbot/core/db/vec_db/faiss_impl/vec_db.py +36 -31
  49. astrbot/core/event_bus.py +8 -6
  50. astrbot/core/file_token_service.py +6 -5
  51. astrbot/core/initial_loader.py +7 -5
  52. astrbot/core/knowledge_base/chunking/__init__.py +1 -3
  53. astrbot/core/knowledge_base/chunking/base.py +1 -0
  54. astrbot/core/knowledge_base/chunking/fixed_size.py +2 -0
  55. astrbot/core/knowledge_base/chunking/recursive.py +16 -10
  56. astrbot/core/knowledge_base/kb_db_sqlite.py +50 -48
  57. astrbot/core/knowledge_base/kb_helper.py +30 -17
  58. astrbot/core/knowledge_base/kb_mgr.py +6 -7
  59. astrbot/core/knowledge_base/models.py +10 -4
  60. astrbot/core/knowledge_base/parsers/__init__.py +3 -5
  61. astrbot/core/knowledge_base/parsers/base.py +1 -0
  62. astrbot/core/knowledge_base/parsers/markitdown_parser.py +2 -1
  63. astrbot/core/knowledge_base/parsers/pdf_parser.py +2 -1
  64. astrbot/core/knowledge_base/parsers/text_parser.py +1 -0
  65. astrbot/core/knowledge_base/parsers/util.py +1 -1
  66. astrbot/core/knowledge_base/retrieval/__init__.py +6 -8
  67. astrbot/core/knowledge_base/retrieval/manager.py +17 -14
  68. astrbot/core/knowledge_base/retrieval/rank_fusion.py +7 -3
  69. astrbot/core/knowledge_base/retrieval/sparse_retriever.py +11 -5
  70. astrbot/core/log.py +21 -13
  71. astrbot/core/message/components.py +123 -217
  72. astrbot/core/message/message_event_result.py +24 -24
  73. astrbot/core/persona_mgr.py +20 -11
  74. astrbot/core/pipeline/__init__.py +7 -7
  75. astrbot/core/pipeline/content_safety_check/stage.py +13 -9
  76. astrbot/core/pipeline/content_safety_check/strategies/__init__.py +1 -2
  77. astrbot/core/pipeline/content_safety_check/strategies/baidu_aip.py +12 -13
  78. astrbot/core/pipeline/content_safety_check/strategies/keywords.py +1 -0
  79. astrbot/core/pipeline/content_safety_check/strategies/strategy.py +6 -6
  80. astrbot/core/pipeline/context.py +4 -1
  81. astrbot/core/pipeline/context_utils.py +77 -7
  82. astrbot/core/pipeline/preprocess_stage/stage.py +12 -9
  83. astrbot/core/pipeline/process_stage/method/llm_request.py +125 -72
  84. astrbot/core/pipeline/process_stage/method/star_request.py +19 -17
  85. astrbot/core/pipeline/process_stage/stage.py +13 -10
  86. astrbot/core/pipeline/process_stage/utils.py +6 -5
  87. astrbot/core/pipeline/rate_limit_check/stage.py +37 -36
  88. astrbot/core/pipeline/respond/stage.py +23 -20
  89. astrbot/core/pipeline/result_decorate/stage.py +31 -23
  90. astrbot/core/pipeline/scheduler.py +12 -8
  91. astrbot/core/pipeline/session_status_check/stage.py +12 -8
  92. astrbot/core/pipeline/stage.py +10 -4
  93. astrbot/core/pipeline/waking_check/stage.py +24 -18
  94. astrbot/core/pipeline/whitelist_check/stage.py +10 -7
  95. astrbot/core/platform/__init__.py +6 -6
  96. astrbot/core/platform/astr_message_event.py +76 -110
  97. astrbot/core/platform/astrbot_message.py +11 -13
  98. astrbot/core/platform/manager.py +16 -15
  99. astrbot/core/platform/message_session.py +5 -3
  100. astrbot/core/platform/platform.py +16 -24
  101. astrbot/core/platform/platform_metadata.py +4 -4
  102. astrbot/core/platform/register.py +8 -8
  103. astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py +23 -15
  104. astrbot/core/platform/sources/aiocqhttp/aiocqhttp_platform_adapter.py +51 -33
  105. astrbot/core/platform/sources/dingtalk/dingtalk_adapter.py +47 -29
  106. astrbot/core/platform/sources/dingtalk/dingtalk_event.py +7 -3
  107. astrbot/core/platform/sources/discord/client.py +9 -6
  108. astrbot/core/platform/sources/discord/components.py +18 -14
  109. astrbot/core/platform/sources/discord/discord_platform_adapter.py +45 -30
  110. astrbot/core/platform/sources/discord/discord_platform_event.py +38 -30
  111. astrbot/core/platform/sources/lark/lark_adapter.py +23 -17
  112. astrbot/core/platform/sources/lark/lark_event.py +21 -14
  113. astrbot/core/platform/sources/misskey/misskey_adapter.py +107 -67
  114. astrbot/core/platform/sources/misskey/misskey_api.py +153 -129
  115. astrbot/core/platform/sources/misskey/misskey_event.py +20 -15
  116. astrbot/core/platform/sources/misskey/misskey_utils.py +74 -62
  117. astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py +63 -44
  118. astrbot/core/platform/sources/qqofficial/qqofficial_platform_adapter.py +41 -26
  119. astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_adapter.py +36 -17
  120. astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_event.py +3 -1
  121. astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_server.py +12 -7
  122. astrbot/core/platform/sources/satori/satori_adapter.py +56 -38
  123. astrbot/core/platform/sources/satori/satori_event.py +34 -25
  124. astrbot/core/platform/sources/slack/client.py +11 -9
  125. astrbot/core/platform/sources/slack/slack_adapter.py +52 -36
  126. astrbot/core/platform/sources/slack/slack_event.py +34 -24
  127. astrbot/core/platform/sources/telegram/tg_adapter.py +38 -18
  128. astrbot/core/platform/sources/telegram/tg_event.py +32 -18
  129. astrbot/core/platform/sources/webchat/webchat_adapter.py +27 -17
  130. astrbot/core/platform/sources/webchat/webchat_event.py +14 -10
  131. astrbot/core/platform/sources/wechatpadpro/wechatpadpro_adapter.py +115 -120
  132. astrbot/core/platform/sources/wechatpadpro/wechatpadpro_message_event.py +9 -8
  133. astrbot/core/platform/sources/wechatpadpro/xml_data_parser.py +15 -16
  134. astrbot/core/platform/sources/wecom/wecom_adapter.py +35 -18
  135. astrbot/core/platform/sources/wecom/wecom_event.py +55 -48
  136. astrbot/core/platform/sources/wecom/wecom_kf.py +34 -44
  137. astrbot/core/platform/sources/wecom/wecom_kf_message.py +26 -10
  138. astrbot/core/platform/sources/wecom_ai_bot/WXBizJsonMsgCrypt.py +18 -10
  139. astrbot/core/platform/sources/wecom_ai_bot/__init__.py +3 -5
  140. astrbot/core/platform/sources/wecom_ai_bot/ierror.py +0 -1
  141. astrbot/core/platform/sources/wecom_ai_bot/wecomai_adapter.py +61 -37
  142. astrbot/core/platform/sources/wecom_ai_bot/wecomai_api.py +67 -28
  143. astrbot/core/platform/sources/wecom_ai_bot/wecomai_event.py +8 -9
  144. astrbot/core/platform/sources/wecom_ai_bot/wecomai_queue_mgr.py +18 -9
  145. astrbot/core/platform/sources/wecom_ai_bot/wecomai_server.py +14 -12
  146. astrbot/core/platform/sources/wecom_ai_bot/wecomai_utils.py +22 -12
  147. astrbot/core/platform/sources/weixin_official_account/weixin_offacc_adapter.py +40 -26
  148. astrbot/core/platform/sources/weixin_official_account/weixin_offacc_event.py +47 -45
  149. astrbot/core/platform_message_history_mgr.py +5 -3
  150. astrbot/core/provider/__init__.py +2 -3
  151. astrbot/core/provider/entites.py +8 -8
  152. astrbot/core/provider/entities.py +61 -75
  153. astrbot/core/provider/func_tool_manager.py +59 -55
  154. astrbot/core/provider/manager.py +40 -22
  155. astrbot/core/provider/provider.py +72 -46
  156. astrbot/core/provider/register.py +7 -7
  157. astrbot/core/provider/sources/anthropic_source.py +48 -30
  158. astrbot/core/provider/sources/azure_tts_source.py +17 -13
  159. astrbot/core/provider/sources/coze_api_client.py +27 -17
  160. astrbot/core/provider/sources/coze_source.py +104 -87
  161. astrbot/core/provider/sources/dashscope_source.py +18 -11
  162. astrbot/core/provider/sources/dashscope_tts.py +36 -23
  163. astrbot/core/provider/sources/dify_source.py +25 -20
  164. astrbot/core/provider/sources/edge_tts_source.py +21 -17
  165. astrbot/core/provider/sources/fishaudio_tts_api_source.py +22 -14
  166. astrbot/core/provider/sources/gemini_embedding_source.py +12 -13
  167. astrbot/core/provider/sources/gemini_source.py +72 -58
  168. astrbot/core/provider/sources/gemini_tts_source.py +8 -6
  169. astrbot/core/provider/sources/gsv_selfhosted_source.py +17 -14
  170. astrbot/core/provider/sources/gsvi_tts_source.py +11 -7
  171. astrbot/core/provider/sources/minimax_tts_api_source.py +50 -40
  172. astrbot/core/provider/sources/openai_embedding_source.py +6 -8
  173. astrbot/core/provider/sources/openai_source.py +102 -69
  174. astrbot/core/provider/sources/openai_tts_api_source.py +14 -6
  175. astrbot/core/provider/sources/sensevoice_selfhosted_source.py +13 -11
  176. astrbot/core/provider/sources/vllm_rerank_source.py +10 -4
  177. astrbot/core/provider/sources/volcengine_tts.py +38 -31
  178. astrbot/core/provider/sources/whisper_api_source.py +14 -12
  179. astrbot/core/provider/sources/whisper_selfhosted_source.py +15 -11
  180. astrbot/core/provider/sources/xinference_rerank_source.py +116 -0
  181. astrbot/core/provider/sources/xinference_stt_provider.py +197 -0
  182. astrbot/core/star/__init__.py +16 -11
  183. astrbot/core/star/config.py +10 -15
  184. astrbot/core/star/context.py +109 -84
  185. astrbot/core/star/filter/__init__.py +4 -3
  186. astrbot/core/star/filter/command.py +30 -28
  187. astrbot/core/star/filter/command_group.py +27 -24
  188. astrbot/core/star/filter/custom_filter.py +6 -5
  189. astrbot/core/star/filter/event_message_type.py +4 -2
  190. astrbot/core/star/filter/permission.py +4 -2
  191. astrbot/core/star/filter/platform_adapter_type.py +4 -2
  192. astrbot/core/star/filter/regex.py +4 -2
  193. astrbot/core/star/register/__init__.py +19 -19
  194. astrbot/core/star/register/star.py +6 -2
  195. astrbot/core/star/register/star_handler.py +96 -73
  196. astrbot/core/star/session_llm_manager.py +48 -14
  197. astrbot/core/star/session_plugin_manager.py +29 -15
  198. astrbot/core/star/star.py +1 -2
  199. astrbot/core/star/star_handler.py +13 -8
  200. astrbot/core/star/star_manager.py +151 -59
  201. astrbot/core/star/star_tools.py +44 -37
  202. astrbot/core/star/updator.py +10 -10
  203. astrbot/core/umop_config_router.py +10 -4
  204. astrbot/core/updator.py +13 -5
  205. astrbot/core/utils/astrbot_path.py +3 -5
  206. astrbot/core/utils/dify_api_client.py +33 -15
  207. astrbot/core/utils/io.py +66 -42
  208. astrbot/core/utils/log_pipe.py +1 -1
  209. astrbot/core/utils/metrics.py +7 -7
  210. astrbot/core/utils/path_util.py +15 -16
  211. astrbot/core/utils/pip_installer.py +5 -5
  212. astrbot/core/utils/session_waiter.py +19 -20
  213. astrbot/core/utils/shared_preferences.py +45 -20
  214. astrbot/core/utils/t2i/__init__.py +4 -1
  215. astrbot/core/utils/t2i/network_strategy.py +35 -26
  216. astrbot/core/utils/t2i/renderer.py +11 -5
  217. astrbot/core/utils/t2i/template_manager.py +14 -15
  218. astrbot/core/utils/tencent_record_helper.py +19 -13
  219. astrbot/core/utils/version_comparator.py +10 -13
  220. astrbot/core/zip_updator.py +43 -40
  221. astrbot/dashboard/routes/__init__.py +18 -18
  222. astrbot/dashboard/routes/auth.py +10 -8
  223. astrbot/dashboard/routes/chat.py +30 -21
  224. astrbot/dashboard/routes/config.py +92 -75
  225. astrbot/dashboard/routes/conversation.py +46 -39
  226. astrbot/dashboard/routes/file.py +4 -2
  227. astrbot/dashboard/routes/knowledge_base.py +47 -40
  228. astrbot/dashboard/routes/log.py +9 -4
  229. astrbot/dashboard/routes/persona.py +19 -16
  230. astrbot/dashboard/routes/plugin.py +69 -55
  231. astrbot/dashboard/routes/route.py +3 -1
  232. astrbot/dashboard/routes/session_management.py +130 -116
  233. astrbot/dashboard/routes/stat.py +34 -34
  234. astrbot/dashboard/routes/t2i.py +15 -12
  235. astrbot/dashboard/routes/tools.py +47 -52
  236. astrbot/dashboard/routes/update.py +32 -28
  237. astrbot/dashboard/server.py +30 -26
  238. astrbot/dashboard/utils.py +8 -4
  239. {astrbot-4.5.0.dist-info → astrbot-4.5.2.dist-info}/METADATA +4 -2
  240. astrbot-4.5.2.dist-info/RECORD +261 -0
  241. astrbot-4.5.0.dist-info/RECORD +0 -258
  242. {astrbot-4.5.0.dist-info → astrbot-4.5.2.dist-info}/WHEEL +0 -0
  243. {astrbot-4.5.0.dist-info → astrbot-4.5.2.dist-info}/entry_points.txt +0 -0
  244. {astrbot-4.5.0.dist-info → astrbot-4.5.2.dist-info}/licenses/LICENSE +0 -0
@@ -1,30 +1,31 @@
1
1
  import abc
2
2
  import asyncio
3
- import re
4
3
  import hashlib
4
+ import re
5
5
  import uuid
6
-
7
- from typing import List, Union, Optional, AsyncGenerator, Any
6
+ from collections.abc import AsyncGenerator
7
+ from typing import Any
8
8
 
9
9
  from astrbot import logger
10
10
  from astrbot.core.db.po import Conversation
11
11
  from astrbot.core.message.components import (
12
- Plain,
13
- Image,
14
- BaseMessageComponent,
15
- Face,
16
12
  At,
17
13
  AtAll,
14
+ BaseMessageComponent,
15
+ Face,
18
16
  Forward,
17
+ Image,
18
+ Plain,
19
19
  Reply,
20
20
  )
21
- from astrbot.core.message.message_event_result import MessageEventResult, MessageChain
21
+ from astrbot.core.message.message_event_result import MessageChain, MessageEventResult
22
22
  from astrbot.core.platform.message_type import MessageType
23
23
  from astrbot.core.provider.entities import ProviderRequest
24
24
  from astrbot.core.utils.metrics import Metric
25
+
25
26
  from .astrbot_message import AstrBotMessage, Group
27
+ from .message_session import MessageSesion, MessageSession # noqa
26
28
  from .platform_metadata import PlatformMetadata
27
- from .message_session import MessageSession, MessageSesion # noqa
28
29
 
29
30
 
30
31
  class AstrMessageEvent(abc.ABC):
@@ -74,7 +75,8 @@ class AstrMessageEvent(abc.ABC):
74
75
  def get_platform_name(self):
75
76
  """获取这个事件所属的平台的类型(如 aiocqhttp, slack, discord 等)。
76
77
 
77
- NOTE: 用户可能会同时运行多个相同类型的平台适配器。"""
78
+ NOTE: 用户可能会同时运行多个相同类型的平台适配器。
79
+ """
78
80
  return self.platform_meta.name
79
81
 
80
82
  def get_platform_id(self):
@@ -85,133 +87,103 @@ class AstrMessageEvent(abc.ABC):
85
87
  return self.platform_meta.id
86
88
 
87
89
  def get_message_str(self) -> str:
88
- """
89
- 获取消息字符串。
90
- """
90
+ """获取消息字符串。"""
91
91
  return self.message_str
92
92
 
93
- def _outline_chain(self, chain: Optional[List[BaseMessageComponent]]) -> str:
94
- outline = ""
93
+ def _outline_chain(self, chain: list[BaseMessageComponent] | None) -> str:
95
94
  if not chain:
96
- return outline
95
+ return ""
96
+
97
+ parts = []
97
98
  for i in chain:
98
99
  if isinstance(i, Plain):
99
- outline += i.text
100
+ parts.append(i.text)
100
101
  elif isinstance(i, Image):
101
- outline += "[图片]"
102
+ parts.append("[图片]")
102
103
  elif isinstance(i, Face):
103
- outline += f"[表情:{i.id}]"
104
+ parts.append(f"[表情:{i.id}]")
104
105
  elif isinstance(i, At):
105
- outline += f"[At:{i.qq}]"
106
+ parts.append(f"[At:{i.qq}]")
106
107
  elif isinstance(i, AtAll):
107
- outline += "[At:全体成员]"
108
+ parts.append("[At:全体成员]")
108
109
  elif isinstance(i, Forward):
109
110
  # 转发消息
110
- outline += "[转发消息]"
111
+ parts.append("[转发消息]")
111
112
  elif isinstance(i, Reply):
112
113
  # 引用回复
113
114
  if i.message_str:
114
- outline += f"[引用消息({i.sender_nickname}: {i.message_str})]"
115
+ parts.append(f"[引用消息({i.sender_nickname}: {i.message_str})]")
115
116
  else:
116
- outline += "[引用消息]"
117
+ parts.append("[引用消息]")
117
118
  else:
118
- outline += f"[{i.type}]"
119
- outline += " "
120
- return outline
119
+ parts.append(f"[{i.type}]")
120
+ parts.append(" ")
121
+ return "".join(parts)
121
122
 
122
123
  def get_message_outline(self) -> str:
123
- """
124
- 获取消息概要。
124
+ """获取消息概要。
125
125
 
126
126
  除了文本消息外,其他消息类型会被转换为对应的占位符。如图片消息会被转换为 [图片]。
127
127
  """
128
128
  return self._outline_chain(self.message_obj.message)
129
129
 
130
- def get_messages(self) -> List[BaseMessageComponent]:
131
- """
132
- 获取消息链。
133
- """
130
+ def get_messages(self) -> list[BaseMessageComponent]:
131
+ """获取消息链。"""
134
132
  return self.message_obj.message
135
133
 
136
134
  def get_message_type(self) -> MessageType:
137
- """
138
- 获取消息类型。
139
- """
135
+ """获取消息类型。"""
140
136
  return self.message_obj.type
141
137
 
142
138
  def get_session_id(self) -> str:
143
- """
144
- 获取会话id。
145
- """
139
+ """获取会话id。"""
146
140
  return self.session_id
147
141
 
148
142
  def get_group_id(self) -> str:
149
- """
150
- 获取群组id。如果不是群组消息,返回空字符串。
151
- """
143
+ """获取群组id。如果不是群组消息,返回空字符串。"""
152
144
  return self.message_obj.group_id
153
145
 
154
146
  def get_self_id(self) -> str:
155
- """
156
- 获取机器人自身的id。
157
- """
147
+ """获取机器人自身的id。"""
158
148
  return self.message_obj.self_id
159
149
 
160
150
  def get_sender_id(self) -> str:
161
- """
162
- 获取消息发送者的id。
163
- """
151
+ """获取消息发送者的id。"""
164
152
  return self.message_obj.sender.user_id
165
153
 
166
154
  def get_sender_name(self) -> str:
167
- """
168
- 获取消息发送者的名称。(可能会返回空字符串)
169
- """
155
+ """获取消息发送者的名称。(可能会返回空字符串)"""
170
156
  return self.message_obj.sender.nickname
171
157
 
172
158
  def set_extra(self, key, value):
173
- """
174
- 设置额外的信息。
175
- """
159
+ """设置额外的信息。"""
176
160
  self._extras[key] = value
177
161
 
178
162
  def get_extra(self, key: str | None = None, default=None) -> Any:
179
- """
180
- 获取额外的信息。
181
- """
163
+ """获取额外的信息。"""
182
164
  if key is None:
183
165
  return self._extras
184
166
  return self._extras.get(key, default)
185
167
 
186
168
  def clear_extra(self):
187
- """
188
- 清除额外的信息。
189
- """
169
+ """清除额外的信息。"""
190
170
  logger.info(f"清除 {self.get_platform_name()} 的额外信息: {self._extras}")
191
171
  self._extras.clear()
192
172
 
193
173
  def is_private_chat(self) -> bool:
194
- """
195
- 是否是私聊。
196
- """
174
+ """是否是私聊。"""
197
175
  return self.message_obj.type.value == (MessageType.FRIEND_MESSAGE).value
198
176
 
199
177
  def is_wake_up(self) -> bool:
200
- """
201
- 是否是唤醒机器人的事件。
202
- """
178
+ """是否是唤醒机器人的事件。"""
203
179
  return self.is_wake
204
180
 
205
181
  def is_admin(self) -> bool:
206
- """
207
- 是否是管理员。
208
- """
182
+ """是否是管理员。"""
209
183
  return self.role == "admin"
210
184
 
211
185
  async def process_buffer(self, buffer: str, pattern: re.Pattern) -> str:
212
- """
213
- 将消息缓冲区中的文本按指定正则表达式分割后发送至消息平台,作为不支持流式输出平台的Fallback。
214
- """
186
+ """将消息缓冲区中的文本按指定正则表达式分割后发送至消息平台,作为不支持流式输出平台的Fallback。"""
215
187
  while True:
216
188
  match = re.search(pattern, buffer)
217
189
  if not match:
@@ -223,14 +195,16 @@ class AstrMessageEvent(abc.ABC):
223
195
  return buffer
224
196
 
225
197
  async def send_streaming(
226
- self, generator: AsyncGenerator[MessageChain, None], use_fallback: bool = False
198
+ self,
199
+ generator: AsyncGenerator[MessageChain, None],
200
+ use_fallback: bool = False,
227
201
  ):
228
202
  """发送流式消息到消息平台,使用异步生成器。
229
203
  目前仅支持: telegram,qq official 私聊。
230
204
  Fallback仅支持 aiocqhttp。
231
205
  """
232
206
  asyncio.create_task(
233
- Metric.upload(msg_event_tick=1, adapter_name=self.platform_meta.name)
207
+ Metric.upload(msg_event_tick=1, adapter_name=self.platform_meta.name),
234
208
  )
235
209
  self._has_send_oper = True
236
210
 
@@ -240,7 +214,7 @@ class AstrMessageEvent(abc.ABC):
240
214
  async def _post_send(self):
241
215
  """调度器会在执行 send() 后调用该方法 deprecated in v3.5.18"""
242
216
 
243
- def set_result(self, result: Union[MessageEventResult, str]):
217
+ def set_result(self, result: MessageEventResult | str):
244
218
  """设置消息事件的结果。
245
219
 
246
220
  Note:
@@ -260,6 +234,7 @@ class AstrMessageEvent(abc.ABC):
260
234
  event.set_result(MessageEventResult().set_console_log("数量已增加", logging.DEBUG).set_result_type(EventResultType.CONTINUE))
261
235
  return
262
236
  ```
237
+
263
238
  """
264
239
  if isinstance(result, str):
265
240
  result = MessageEventResult().message(result)
@@ -283,41 +258,32 @@ class AstrMessageEvent(abc.ABC):
283
258
  self._result.continue_event()
284
259
 
285
260
  def is_stopped(self) -> bool:
286
- """
287
- 是否终止事件传播。
288
- """
261
+ """是否终止事件传播。"""
289
262
  if self._result is None:
290
263
  return False # 默认是继续传播
291
264
  return self._result.is_stopped()
292
265
 
293
266
  def should_call_llm(self, call_llm: bool):
294
- """
295
- 是否在此消息事件中禁止默认的 LLM 请求。
267
+ """是否在此消息事件中禁止默认的 LLM 请求。
296
268
 
297
269
  只会阻止 AstrBot 默认的 LLM 请求链路,不会阻止插件中的 LLM 请求。
298
270
  """
299
271
  self.call_llm = call_llm
300
272
 
301
273
  def get_result(self) -> MessageEventResult:
302
- """
303
- 获取消息事件的结果。
304
- """
274
+ """获取消息事件的结果。"""
305
275
  return self._result
306
276
 
307
277
  def clear_result(self):
308
- """
309
- 清除消息事件的结果。
310
- """
278
+ """清除消息事件的结果。"""
311
279
  self._result = None
312
280
 
313
281
  """消息链相关"""
314
282
 
315
283
  def make_result(self) -> MessageEventResult:
316
- """
317
- 创建一个空的消息事件结果。
284
+ """创建一个空的消息事件结果。
318
285
 
319
286
  Example:
320
-
321
287
  ```python
322
288
  # 纯文本回复
323
289
  yield event.make_result().message("Hi")
@@ -325,18 +291,16 @@ class AstrMessageEvent(abc.ABC):
325
291
  yield event.make_result().url_image("https://example.com/image.jpg")
326
292
  yield event.make_result().file_image("image.jpg")
327
293
  ```
294
+
328
295
  """
329
296
  return MessageEventResult()
330
297
 
331
298
  def plain_result(self, text: str) -> MessageEventResult:
332
- """
333
- 创建一个空的消息事件结果,只包含一条文本消息。
334
- """
299
+ """创建一个空的消息事件结果,只包含一条文本消息。"""
335
300
  return MessageEventResult().message(text)
336
301
 
337
302
  def image_result(self, url_or_path: str) -> MessageEventResult:
338
- """
339
- 创建一个空的消息事件结果,只包含一条图片消息。
303
+ """创建一个空的消息事件结果,只包含一条图片消息。
340
304
 
341
305
  根据开头是否包含 http 来判断是网络图片还是本地图片。
342
306
  """
@@ -344,10 +308,8 @@ class AstrMessageEvent(abc.ABC):
344
308
  return MessageEventResult().url_image(url_or_path)
345
309
  return MessageEventResult().file_image(url_or_path)
346
310
 
347
- def chain_result(self, chain: List[BaseMessageComponent]) -> MessageEventResult:
348
- """
349
- 创建一个空的消息事件结果,包含指定的消息链。
350
- """
311
+ def chain_result(self, chain: list[BaseMessageComponent]) -> MessageEventResult:
312
+ """创建一个空的消息事件结果,包含指定的消息链。"""
351
313
  mer = MessageEventResult()
352
314
  mer.chain = chain
353
315
  return mer
@@ -359,13 +321,12 @@ class AstrMessageEvent(abc.ABC):
359
321
  prompt: str,
360
322
  func_tool_manager=None,
361
323
  session_id: str = None,
362
- image_urls: List[str] = [],
363
- contexts: List = [],
324
+ image_urls: list[str] | None = None,
325
+ contexts: list | None = None,
364
326
  system_prompt: str = "",
365
- conversation: Conversation = None,
327
+ conversation: Conversation | None = None,
366
328
  ) -> ProviderRequest:
367
- """
368
- 创建一个 LLM 请求。
329
+ """创建一个 LLM 请求。
369
330
 
370
331
  Examples:
371
332
  ```py
@@ -384,8 +345,12 @@ class AstrMessageEvent(abc.ABC):
384
345
  func_tool_manager: 函数工具管理器,用于调用函数工具。用 self.context.get_llm_tool_manager() 获取。
385
346
 
386
347
  conversation: 可选。如果指定,将在指定的对话中进行 LLM 请求。对话的人格会被用于 LLM 请求,并且结果将会被记录到对话中。
387
- """
388
348
 
349
+ """
350
+ if image_urls is None:
351
+ image_urls = []
352
+ if contexts is None:
353
+ contexts = []
389
354
  if len(contexts) > 0 and conversation:
390
355
  conversation = None
391
356
 
@@ -406,20 +371,22 @@ class AstrMessageEvent(abc.ABC):
406
371
 
407
372
  Args:
408
373
  message (MessageChain): 消息链,具体使用方式请参考文档。
374
+
409
375
  """
410
376
  # Leverage BLAKE2 hash function to generate a non-reversible hash of the sender ID for privacy.
411
377
  hash_obj = hashlib.blake2b(self.get_sender_id().encode("utf-8"), digest_size=16)
412
378
  sid = str(uuid.UUID(bytes=hash_obj.digest()))
413
379
  asyncio.create_task(
414
380
  Metric.upload(
415
- msg_event_tick=1, adapter_name=self.platform_meta.name, sid=sid
416
- )
381
+ msg_event_tick=1,
382
+ adapter_name=self.platform_meta.name,
383
+ sid=sid,
384
+ ),
417
385
  )
418
386
  self._has_send_oper = True
419
387
 
420
388
  async def react(self, emoji: str):
421
- """
422
- 对消息添加表情回应。
389
+ """对消息添加表情回应。
423
390
 
424
391
  默认实现为发送一条包含该表情的消息。
425
392
  注意:此实现并不一定符合所有平台的原生“表情回应”行为。
@@ -427,11 +394,10 @@ class AstrMessageEvent(abc.ABC):
427
394
  """
428
395
  await self.send(MessageChain([Plain(emoji)]))
429
396
 
430
- async def get_group(self, group_id: str = None, **kwargs) -> Optional[Group]:
397
+ async def get_group(self, group_id: str | None = None, **kwargs) -> Group | None:
431
398
  """获取一个群聊的数据, 如果不填写 group_id: 如果是私聊消息,返回 None。如果是群聊消息,返回当前群聊的数据。
432
399
 
433
400
  适配情况:
434
401
 
435
402
  - aiocqhttp(OneBotv11)
436
403
  """
437
- ...
@@ -1,14 +1,15 @@
1
1
  import time
2
- from typing import List
3
2
  from dataclasses import dataclass
3
+
4
4
  from astrbot.core.message.components import BaseMessageComponent
5
+
5
6
  from .message_type import MessageType
6
7
 
7
8
 
8
9
  @dataclass
9
10
  class MessageMember:
10
11
  user_id: str # 发送者id
11
- nickname: str = None
12
+ nickname: str | None = None
12
13
 
13
14
  def __str__(self):
14
15
  # 使用 f-string 来构建返回的字符串表示形式
@@ -22,15 +23,15 @@ class MessageMember:
22
23
  class Group:
23
24
  group_id: str
24
25
  """群号"""
25
- group_name: str = None
26
+ group_name: str | None = None
26
27
  """群名称"""
27
- group_avatar: str = None
28
+ group_avatar: str | None = None
28
29
  """群头像"""
29
- group_owner: str = None
30
+ group_owner: str | None = None
30
31
  """群主 id"""
31
- group_admins: List[str] = None
32
+ group_admins: list[str] | None = None
32
33
  """群管理员 id"""
33
- members: List[MessageMember] = None
34
+ members: list[MessageMember] | None = None
34
35
  """所有群成员"""
35
36
 
36
37
  def __str__(self):
@@ -47,9 +48,7 @@ class Group:
47
48
 
48
49
 
49
50
  class AstrBotMessage:
50
- """
51
- AstrBot 的消息对象
52
- """
51
+ """AstrBot 的消息对象"""
53
52
 
54
53
  type: MessageType # 消息类型
55
54
  self_id: str # 机器人的识别id
@@ -57,7 +56,7 @@ class AstrBotMessage:
57
56
  message_id: str # 消息id
58
57
  group: Group # 群组
59
58
  sender: MessageMember # 发送者
60
- message: List[BaseMessageComponent] # 消息链使用 Nakuru 的消息链格式
59
+ message: list[BaseMessageComponent] # 消息链使用 Nakuru 的消息链格式
61
60
  message_str: str # 最直观的纯文本消息字符串
62
61
  raw_message: object
63
62
  timestamp: int # 消息时间戳
@@ -71,8 +70,7 @@ class AstrBotMessage:
71
70
 
72
71
  @property
73
72
  def group_id(self) -> str:
74
- """
75
- 向后兼容的 group_id 属性
73
+ """向后兼容的 group_id 属性
76
74
  群组id,如果为私聊,则为空
77
75
  """
78
76
  if self.group:
@@ -1,18 +1,19 @@
1
- import traceback
2
1
  import asyncio
2
+ import traceback
3
+ from asyncio import Queue
4
+
5
+ from astrbot.core import logger
3
6
  from astrbot.core.config.astrbot_config import AstrBotConfig
7
+ from astrbot.core.star.star_handler import EventType, star_handlers_registry, star_map
8
+
4
9
  from .platform import Platform
5
- from typing import List
6
- from asyncio import Queue
7
10
  from .register import platform_cls_map
8
- from astrbot.core import logger
9
- from astrbot.core.star.star_handler import star_handlers_registry, star_map, EventType
10
11
  from .sources.webchat.webchat_adapter import WebChatAdapter
11
12
 
12
13
 
13
14
  class PlatformManager:
14
15
  def __init__(self, config: AstrBotConfig, event_queue: Queue):
15
- self.platform_insts: List[Platform] = []
16
+ self.platform_insts: list[Platform] = []
16
17
  """加载的 Platform 的实例"""
17
18
 
18
19
  self._inst_map = {}
@@ -36,7 +37,7 @@ class PlatformManager:
36
37
  webchat_inst = WebChatAdapter({}, self.settings, self.event_queue)
37
38
  self.platform_insts.append(webchat_inst)
38
39
  asyncio.create_task(
39
- self._task_wrapper(asyncio.create_task(webchat_inst.run(), name="webchat"))
40
+ self._task_wrapper(asyncio.create_task(webchat_inst.run(), name="webchat")),
40
41
  )
41
42
 
42
43
  async def load_platform(self, platform_config: dict):
@@ -47,7 +48,7 @@ class PlatformManager:
47
48
  return
48
49
 
49
50
  logger.info(
50
- f"载入 {platform_config['type']}({platform_config['id']}) 平台适配器 ..."
51
+ f"载入 {platform_config['type']}({platform_config['id']}) 平台适配器 ...",
51
52
  )
52
53
  match platform_config["type"]:
53
54
  case "aiocqhttp":
@@ -106,14 +107,14 @@ class PlatformManager:
106
107
  )
107
108
  except (ImportError, ModuleNotFoundError) as e:
108
109
  logger.error(
109
- f"加载平台适配器 {platform_config['type']} 失败,原因:{e}。请检查依赖库是否安装。提示:可以在 管理面板->控制台->安装Pip库 中安装依赖库。"
110
+ f"加载平台适配器 {platform_config['type']} 失败,原因:{e}。请检查依赖库是否安装。提示:可以在 管理面板->控制台->安装Pip库 中安装依赖库。",
110
111
  )
111
112
  except Exception as e:
112
113
  logger.error(f"加载平台适配器 {platform_config['type']} 失败,原因:{e}。")
113
114
 
114
115
  if platform_config["type"] not in platform_cls_map:
115
116
  logger.error(
116
- f"未找到适用于 {platform_config['type']}({platform_config['id']}) 平台适配器,请检查是否已经安装或者名称填写错误"
117
+ f"未找到适用于 {platform_config['type']}({platform_config['id']}) 平台适配器,请检查是否已经安装或者名称填写错误",
117
118
  )
118
119
  return
119
120
  cls_type = platform_cls_map[platform_config["type"]]
@@ -129,16 +130,16 @@ class PlatformManager:
129
130
  asyncio.create_task(
130
131
  inst.run(),
131
132
  name=f"platform_{platform_config['type']}_{platform_config['id']}",
132
- )
133
- )
133
+ ),
134
+ ),
134
135
  )
135
136
  handlers = star_handlers_registry.get_handlers_by_event_type(
136
- EventType.OnPlatformLoadedEvent
137
+ EventType.OnPlatformLoadedEvent,
137
138
  )
138
139
  for handler in handlers:
139
140
  try:
140
141
  logger.info(
141
- f"hook(on_platform_loaded) -> {star_map[handler.handler_module_path].name} - {handler.handler_name}"
142
+ f"hook(on_platform_loaded) -> {star_map[handler.handler_module_path].name} - {handler.handler_name}",
142
143
  )
143
144
  await handler.handler()
144
145
  except Exception:
@@ -180,7 +181,7 @@ class PlatformManager:
180
181
  inst
181
182
  for inst in self.platform_insts
182
183
  if inst.client_self_id == client_id
183
- )
184
+ ),
184
185
  )
185
186
  except Exception:
186
187
  logger.warning(f"可能未完全移除 {platform_id} 平台适配器")
@@ -1,17 +1,19 @@
1
- from astrbot.core.platform.message_type import MessageType
2
1
  from dataclasses import dataclass
3
2
 
3
+ from astrbot.core.platform.message_type import MessageType
4
+
4
5
 
5
6
  @dataclass
6
7
  class MessageSession:
7
8
  """描述一条消息在 AstrBot 中对应的会话的唯一标识。
8
- 如果您需要实例化 MessageSession,请不要给 platform_id 赋值(或者同时给 platform_name 和 platform_id 赋值相同值)。它会在 __post_init__ 中自动设置为 platform_name 的值。"""
9
+ 如果您需要实例化 MessageSession,请不要给 platform_id 赋值(或者同时给 platform_name 和 platform_id 赋值相同值)。它会在 __post_init__ 中自动设置为 platform_name 的值。
10
+ """
9
11
 
10
12
  platform_name: str
11
13
  """平台适配器实例的唯一标识符。自 AstrBot v4.0.0 起,该字段实际为 platform_id。"""
12
14
  message_type: MessageType
13
15
  session_id: str
14
- platform_id: str = None
16
+ platform_id: str | None = None
15
17
 
16
18
  def __str__(self):
17
19
  return f"{self.platform_id}:{self.message_type.value}:{self.session_id}"
@@ -1,13 +1,16 @@
1
1
  import abc
2
2
  import uuid
3
- from typing import Awaitable, Any
4
3
  from asyncio import Queue
5
- from .platform_metadata import PlatformMetadata
6
- from .astr_message_event import AstrMessageEvent
4
+ from collections.abc import Awaitable
5
+ from typing import Any
6
+
7
7
  from astrbot.core.message.message_event_result import MessageChain
8
- from .message_session import MessageSesion
9
8
  from astrbot.core.utils.metrics import Metric
10
9
 
10
+ from .astr_message_event import AstrMessageEvent
11
+ from .message_session import MessageSesion
12
+ from .platform_metadata import PlatformMetadata
13
+
11
14
 
12
15
  class Platform(abc.ABC):
13
16
  def __init__(self, event_queue: Queue):
@@ -18,42 +21,31 @@ class Platform(abc.ABC):
18
21
 
19
22
  @abc.abstractmethod
20
23
  def run(self) -> Awaitable[Any]:
21
- """
22
- 得到一个平台的运行实例,需要返回一个协程对象。
23
- """
24
+ """得到一个平台的运行实例,需要返回一个协程对象。"""
24
25
  raise NotImplementedError
25
26
 
26
27
  async def terminate(self):
27
- """
28
- 终止一个平台的运行实例。
29
- """
30
- ...
28
+ """终止一个平台的运行实例。"""
31
29
 
32
30
  @abc.abstractmethod
33
31
  def meta(self) -> PlatformMetadata:
34
- """
35
- 得到一个平台的元数据。
36
- """
32
+ """得到一个平台的元数据。"""
37
33
  raise NotImplementedError
38
34
 
39
35
  async def send_by_session(
40
- self, session: MessageSesion, message_chain: MessageChain
36
+ self,
37
+ session: MessageSesion,
38
+ message_chain: MessageChain,
41
39
  ) -> Awaitable[Any]:
42
- """
43
- 通过会话发送消息。该方法旨在让插件能够直接通过**可持久化的会话数据**发送消息,而不需要保存 event 对象。
40
+ """通过会话发送消息。该方法旨在让插件能够直接通过**可持久化的会话数据**发送消息,而不需要保存 event 对象。
44
41
 
45
42
  异步方法。
46
43
  """
47
44
  await Metric.upload(msg_event_tick=1, adapter_name=self.meta().name)
48
45
 
49
46
  def commit_event(self, event: AstrMessageEvent):
50
- """
51
- 提交一个事件到事件队列。
52
- """
47
+ """提交一个事件到事件队列。"""
53
48
  self._event_queue.put_nowait(event)
54
49
 
55
50
  def get_client(self):
56
- """
57
- 获取平台的客户端对象。
58
- """
59
- pass
51
+ """获取平台的客户端对象。"""
@@ -7,12 +7,12 @@ class PlatformMetadata:
7
7
  """平台的名称,即平台的类型,如 aiocqhttp, discord, slack"""
8
8
  description: str
9
9
  """平台的描述"""
10
- id: str = None
10
+ id: str | None = None
11
11
  """平台的唯一标识符,用于配置中识别特定平台"""
12
12
 
13
- default_config_tmpl: dict = None
13
+ default_config_tmpl: dict | None = None
14
14
  """平台的默认配置模板"""
15
- adapter_display_name: str = None
15
+ adapter_display_name: str | None = None
16
16
  """显示在 WebUI 配置页中的平台名称,如空则是 name"""
17
- logo_path: str = None
17
+ logo_path: str | None = None
18
18
  """平台适配器的 logo 文件路径(相对于插件目录)"""