AstrBot 3.5.6__py3-none-any.whl → 4.7.0__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 (288) hide show
  1. astrbot/api/__init__.py +16 -4
  2. astrbot/api/all.py +2 -1
  3. astrbot/api/event/__init__.py +5 -6
  4. astrbot/api/event/filter/__init__.py +37 -34
  5. astrbot/api/platform/__init__.py +7 -8
  6. astrbot/api/provider/__init__.py +8 -7
  7. astrbot/api/star/__init__.py +3 -4
  8. astrbot/api/util/__init__.py +2 -2
  9. astrbot/cli/__init__.py +1 -0
  10. astrbot/cli/__main__.py +18 -197
  11. astrbot/cli/commands/__init__.py +6 -0
  12. astrbot/cli/commands/cmd_conf.py +209 -0
  13. astrbot/cli/commands/cmd_init.py +56 -0
  14. astrbot/cli/commands/cmd_plug.py +245 -0
  15. astrbot/cli/commands/cmd_run.py +62 -0
  16. astrbot/cli/utils/__init__.py +18 -0
  17. astrbot/cli/utils/basic.py +76 -0
  18. astrbot/cli/utils/plugin.py +246 -0
  19. astrbot/cli/utils/version_comparator.py +90 -0
  20. astrbot/core/__init__.py +17 -19
  21. astrbot/core/agent/agent.py +14 -0
  22. astrbot/core/agent/handoff.py +38 -0
  23. astrbot/core/agent/hooks.py +30 -0
  24. astrbot/core/agent/mcp_client.py +385 -0
  25. astrbot/core/agent/message.py +175 -0
  26. astrbot/core/agent/response.py +14 -0
  27. astrbot/core/agent/run_context.py +22 -0
  28. astrbot/core/agent/runners/__init__.py +3 -0
  29. astrbot/core/agent/runners/base.py +65 -0
  30. astrbot/core/agent/runners/coze/coze_agent_runner.py +367 -0
  31. astrbot/core/agent/runners/coze/coze_api_client.py +324 -0
  32. astrbot/core/agent/runners/dashscope/dashscope_agent_runner.py +403 -0
  33. astrbot/core/agent/runners/dify/dify_agent_runner.py +336 -0
  34. astrbot/core/agent/runners/dify/dify_api_client.py +195 -0
  35. astrbot/core/agent/runners/tool_loop_agent_runner.py +400 -0
  36. astrbot/core/agent/tool.py +285 -0
  37. astrbot/core/agent/tool_executor.py +17 -0
  38. astrbot/core/astr_agent_context.py +19 -0
  39. astrbot/core/astr_agent_hooks.py +36 -0
  40. astrbot/core/astr_agent_run_util.py +80 -0
  41. astrbot/core/astr_agent_tool_exec.py +246 -0
  42. astrbot/core/astrbot_config_mgr.py +275 -0
  43. astrbot/core/config/__init__.py +2 -2
  44. astrbot/core/config/astrbot_config.py +60 -20
  45. astrbot/core/config/default.py +1972 -453
  46. astrbot/core/config/i18n_utils.py +110 -0
  47. astrbot/core/conversation_mgr.py +285 -75
  48. astrbot/core/core_lifecycle.py +167 -62
  49. astrbot/core/db/__init__.py +305 -102
  50. astrbot/core/db/migration/helper.py +69 -0
  51. astrbot/core/db/migration/migra_3_to_4.py +357 -0
  52. astrbot/core/db/migration/migra_45_to_46.py +44 -0
  53. astrbot/core/db/migration/migra_webchat_session.py +131 -0
  54. astrbot/core/db/migration/shared_preferences_v3.py +48 -0
  55. astrbot/core/db/migration/sqlite_v3.py +497 -0
  56. astrbot/core/db/po.py +259 -55
  57. astrbot/core/db/sqlite.py +773 -528
  58. astrbot/core/db/vec_db/base.py +73 -0
  59. astrbot/core/db/vec_db/faiss_impl/__init__.py +3 -0
  60. astrbot/core/db/vec_db/faiss_impl/document_storage.py +392 -0
  61. astrbot/core/db/vec_db/faiss_impl/embedding_storage.py +93 -0
  62. astrbot/core/db/vec_db/faiss_impl/sqlite_init.sql +17 -0
  63. astrbot/core/db/vec_db/faiss_impl/vec_db.py +204 -0
  64. astrbot/core/event_bus.py +26 -22
  65. astrbot/core/exceptions.py +9 -0
  66. astrbot/core/file_token_service.py +98 -0
  67. astrbot/core/initial_loader.py +19 -10
  68. astrbot/core/knowledge_base/chunking/__init__.py +9 -0
  69. astrbot/core/knowledge_base/chunking/base.py +25 -0
  70. astrbot/core/knowledge_base/chunking/fixed_size.py +59 -0
  71. astrbot/core/knowledge_base/chunking/recursive.py +161 -0
  72. astrbot/core/knowledge_base/kb_db_sqlite.py +301 -0
  73. astrbot/core/knowledge_base/kb_helper.py +642 -0
  74. astrbot/core/knowledge_base/kb_mgr.py +330 -0
  75. astrbot/core/knowledge_base/models.py +120 -0
  76. astrbot/core/knowledge_base/parsers/__init__.py +13 -0
  77. astrbot/core/knowledge_base/parsers/base.py +51 -0
  78. astrbot/core/knowledge_base/parsers/markitdown_parser.py +26 -0
  79. astrbot/core/knowledge_base/parsers/pdf_parser.py +101 -0
  80. astrbot/core/knowledge_base/parsers/text_parser.py +42 -0
  81. astrbot/core/knowledge_base/parsers/url_parser.py +103 -0
  82. astrbot/core/knowledge_base/parsers/util.py +13 -0
  83. astrbot/core/knowledge_base/prompts.py +65 -0
  84. astrbot/core/knowledge_base/retrieval/__init__.py +14 -0
  85. astrbot/core/knowledge_base/retrieval/hit_stopwords.txt +767 -0
  86. astrbot/core/knowledge_base/retrieval/manager.py +276 -0
  87. astrbot/core/knowledge_base/retrieval/rank_fusion.py +142 -0
  88. astrbot/core/knowledge_base/retrieval/sparse_retriever.py +136 -0
  89. astrbot/core/log.py +21 -15
  90. astrbot/core/message/components.py +413 -287
  91. astrbot/core/message/message_event_result.py +35 -24
  92. astrbot/core/persona_mgr.py +192 -0
  93. astrbot/core/pipeline/__init__.py +14 -14
  94. astrbot/core/pipeline/content_safety_check/stage.py +13 -9
  95. astrbot/core/pipeline/content_safety_check/strategies/__init__.py +1 -2
  96. astrbot/core/pipeline/content_safety_check/strategies/baidu_aip.py +13 -14
  97. astrbot/core/pipeline/content_safety_check/strategies/keywords.py +2 -1
  98. astrbot/core/pipeline/content_safety_check/strategies/strategy.py +6 -6
  99. astrbot/core/pipeline/context.py +7 -1
  100. astrbot/core/pipeline/context_utils.py +107 -0
  101. astrbot/core/pipeline/preprocess_stage/stage.py +63 -36
  102. astrbot/core/pipeline/process_stage/method/agent_request.py +48 -0
  103. astrbot/core/pipeline/process_stage/method/agent_sub_stages/internal.py +464 -0
  104. astrbot/core/pipeline/process_stage/method/agent_sub_stages/third_party.py +202 -0
  105. astrbot/core/pipeline/process_stage/method/star_request.py +26 -32
  106. astrbot/core/pipeline/process_stage/stage.py +21 -15
  107. astrbot/core/pipeline/process_stage/utils.py +125 -0
  108. astrbot/core/pipeline/rate_limit_check/stage.py +34 -36
  109. astrbot/core/pipeline/respond/stage.py +142 -101
  110. astrbot/core/pipeline/result_decorate/stage.py +124 -57
  111. astrbot/core/pipeline/scheduler.py +21 -16
  112. astrbot/core/pipeline/session_status_check/stage.py +37 -0
  113. astrbot/core/pipeline/stage.py +11 -76
  114. astrbot/core/pipeline/waking_check/stage.py +69 -33
  115. astrbot/core/pipeline/whitelist_check/stage.py +10 -7
  116. astrbot/core/platform/__init__.py +6 -6
  117. astrbot/core/platform/astr_message_event.py +107 -129
  118. astrbot/core/platform/astrbot_message.py +32 -12
  119. astrbot/core/platform/manager.py +62 -18
  120. astrbot/core/platform/message_session.py +30 -0
  121. astrbot/core/platform/platform.py +16 -24
  122. astrbot/core/platform/platform_metadata.py +9 -4
  123. astrbot/core/platform/register.py +12 -7
  124. astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py +136 -60
  125. astrbot/core/platform/sources/aiocqhttp/aiocqhttp_platform_adapter.py +126 -46
  126. astrbot/core/platform/sources/dingtalk/dingtalk_adapter.py +63 -31
  127. astrbot/core/platform/sources/dingtalk/dingtalk_event.py +30 -26
  128. astrbot/core/platform/sources/discord/client.py +129 -0
  129. astrbot/core/platform/sources/discord/components.py +139 -0
  130. astrbot/core/platform/sources/discord/discord_platform_adapter.py +473 -0
  131. astrbot/core/platform/sources/discord/discord_platform_event.py +313 -0
  132. astrbot/core/platform/sources/lark/lark_adapter.py +27 -18
  133. astrbot/core/platform/sources/lark/lark_event.py +39 -13
  134. astrbot/core/platform/sources/misskey/misskey_adapter.py +770 -0
  135. astrbot/core/platform/sources/misskey/misskey_api.py +964 -0
  136. astrbot/core/platform/sources/misskey/misskey_event.py +163 -0
  137. astrbot/core/platform/sources/misskey/misskey_utils.py +550 -0
  138. astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py +149 -33
  139. astrbot/core/platform/sources/qqofficial/qqofficial_platform_adapter.py +41 -26
  140. astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_adapter.py +36 -17
  141. astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_event.py +3 -1
  142. astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_server.py +14 -8
  143. astrbot/core/platform/sources/satori/satori_adapter.py +792 -0
  144. astrbot/core/platform/sources/satori/satori_event.py +432 -0
  145. astrbot/core/platform/sources/slack/client.py +164 -0
  146. astrbot/core/platform/sources/slack/slack_adapter.py +416 -0
  147. astrbot/core/platform/sources/slack/slack_event.py +253 -0
  148. astrbot/core/platform/sources/telegram/tg_adapter.py +100 -43
  149. astrbot/core/platform/sources/telegram/tg_event.py +136 -36
  150. astrbot/core/platform/sources/webchat/webchat_adapter.py +72 -22
  151. astrbot/core/platform/sources/webchat/webchat_event.py +46 -22
  152. astrbot/core/platform/sources/webchat/webchat_queue_mgr.py +35 -0
  153. astrbot/core/platform/sources/wechatpadpro/wechatpadpro_adapter.py +926 -0
  154. astrbot/core/platform/sources/wechatpadpro/wechatpadpro_message_event.py +178 -0
  155. astrbot/core/platform/sources/wechatpadpro/xml_data_parser.py +159 -0
  156. astrbot/core/platform/sources/wecom/wecom_adapter.py +169 -27
  157. astrbot/core/platform/sources/wecom/wecom_event.py +162 -77
  158. astrbot/core/platform/sources/wecom/wecom_kf.py +279 -0
  159. astrbot/core/platform/sources/wecom/wecom_kf_message.py +196 -0
  160. astrbot/core/platform/sources/wecom_ai_bot/WXBizJsonMsgCrypt.py +297 -0
  161. astrbot/core/platform/sources/wecom_ai_bot/__init__.py +15 -0
  162. astrbot/core/platform/sources/wecom_ai_bot/ierror.py +19 -0
  163. astrbot/core/platform/sources/wecom_ai_bot/wecomai_adapter.py +472 -0
  164. astrbot/core/platform/sources/wecom_ai_bot/wecomai_api.py +417 -0
  165. astrbot/core/platform/sources/wecom_ai_bot/wecomai_event.py +152 -0
  166. astrbot/core/platform/sources/wecom_ai_bot/wecomai_queue_mgr.py +153 -0
  167. astrbot/core/platform/sources/wecom_ai_bot/wecomai_server.py +168 -0
  168. astrbot/core/platform/sources/wecom_ai_bot/wecomai_utils.py +209 -0
  169. astrbot/core/platform/sources/weixin_official_account/weixin_offacc_adapter.py +306 -0
  170. astrbot/core/platform/sources/weixin_official_account/weixin_offacc_event.py +186 -0
  171. astrbot/core/platform_message_history_mgr.py +49 -0
  172. astrbot/core/provider/__init__.py +2 -3
  173. astrbot/core/provider/entites.py +8 -8
  174. astrbot/core/provider/entities.py +154 -98
  175. astrbot/core/provider/func_tool_manager.py +446 -458
  176. astrbot/core/provider/manager.py +345 -207
  177. astrbot/core/provider/provider.py +188 -73
  178. astrbot/core/provider/register.py +9 -7
  179. astrbot/core/provider/sources/anthropic_source.py +295 -115
  180. astrbot/core/provider/sources/azure_tts_source.py +224 -0
  181. astrbot/core/provider/sources/bailian_rerank_source.py +236 -0
  182. astrbot/core/provider/sources/dashscope_tts.py +138 -14
  183. astrbot/core/provider/sources/edge_tts_source.py +24 -19
  184. astrbot/core/provider/sources/fishaudio_tts_api_source.py +58 -13
  185. astrbot/core/provider/sources/gemini_embedding_source.py +61 -0
  186. astrbot/core/provider/sources/gemini_source.py +310 -132
  187. astrbot/core/provider/sources/gemini_tts_source.py +81 -0
  188. astrbot/core/provider/sources/groq_source.py +15 -0
  189. astrbot/core/provider/sources/gsv_selfhosted_source.py +151 -0
  190. astrbot/core/provider/sources/gsvi_tts_source.py +14 -7
  191. astrbot/core/provider/sources/minimax_tts_api_source.py +159 -0
  192. astrbot/core/provider/sources/openai_embedding_source.py +40 -0
  193. astrbot/core/provider/sources/openai_source.py +241 -145
  194. astrbot/core/provider/sources/openai_tts_api_source.py +18 -7
  195. astrbot/core/provider/sources/sensevoice_selfhosted_source.py +13 -11
  196. astrbot/core/provider/sources/vllm_rerank_source.py +71 -0
  197. astrbot/core/provider/sources/volcengine_tts.py +115 -0
  198. astrbot/core/provider/sources/whisper_api_source.py +18 -13
  199. astrbot/core/provider/sources/whisper_selfhosted_source.py +19 -12
  200. astrbot/core/provider/sources/xinference_rerank_source.py +116 -0
  201. astrbot/core/provider/sources/xinference_stt_provider.py +197 -0
  202. astrbot/core/provider/sources/zhipu_source.py +6 -73
  203. astrbot/core/star/__init__.py +43 -11
  204. astrbot/core/star/config.py +17 -18
  205. astrbot/core/star/context.py +362 -138
  206. astrbot/core/star/filter/__init__.py +4 -3
  207. astrbot/core/star/filter/command.py +111 -35
  208. astrbot/core/star/filter/command_group.py +46 -34
  209. astrbot/core/star/filter/custom_filter.py +6 -5
  210. astrbot/core/star/filter/event_message_type.py +4 -2
  211. astrbot/core/star/filter/permission.py +4 -2
  212. astrbot/core/star/filter/platform_adapter_type.py +45 -12
  213. astrbot/core/star/filter/regex.py +4 -2
  214. astrbot/core/star/register/__init__.py +19 -15
  215. astrbot/core/star/register/star.py +41 -13
  216. astrbot/core/star/register/star_handler.py +236 -86
  217. astrbot/core/star/session_llm_manager.py +280 -0
  218. astrbot/core/star/session_plugin_manager.py +170 -0
  219. astrbot/core/star/star.py +36 -43
  220. astrbot/core/star/star_handler.py +47 -85
  221. astrbot/core/star/star_manager.py +442 -260
  222. astrbot/core/star/star_tools.py +167 -45
  223. astrbot/core/star/updator.py +17 -20
  224. astrbot/core/umop_config_router.py +106 -0
  225. astrbot/core/updator.py +38 -13
  226. astrbot/core/utils/astrbot_path.py +39 -0
  227. astrbot/core/utils/command_parser.py +1 -1
  228. astrbot/core/utils/io.py +119 -60
  229. astrbot/core/utils/log_pipe.py +1 -1
  230. astrbot/core/utils/metrics.py +11 -10
  231. astrbot/core/utils/migra_helper.py +73 -0
  232. astrbot/core/utils/path_util.py +63 -62
  233. astrbot/core/utils/pip_installer.py +37 -15
  234. astrbot/core/utils/session_lock.py +29 -0
  235. astrbot/core/utils/session_waiter.py +19 -20
  236. astrbot/core/utils/shared_preferences.py +174 -34
  237. astrbot/core/utils/t2i/__init__.py +4 -1
  238. astrbot/core/utils/t2i/local_strategy.py +386 -238
  239. astrbot/core/utils/t2i/network_strategy.py +109 -49
  240. astrbot/core/utils/t2i/renderer.py +29 -14
  241. astrbot/core/utils/t2i/template/astrbot_powershell.html +184 -0
  242. astrbot/core/utils/t2i/template_manager.py +111 -0
  243. astrbot/core/utils/tencent_record_helper.py +115 -1
  244. astrbot/core/utils/version_comparator.py +10 -13
  245. astrbot/core/zip_updator.py +112 -65
  246. astrbot/dashboard/routes/__init__.py +20 -13
  247. astrbot/dashboard/routes/auth.py +20 -9
  248. astrbot/dashboard/routes/chat.py +297 -141
  249. astrbot/dashboard/routes/config.py +652 -55
  250. astrbot/dashboard/routes/conversation.py +107 -37
  251. astrbot/dashboard/routes/file.py +26 -0
  252. astrbot/dashboard/routes/knowledge_base.py +1244 -0
  253. astrbot/dashboard/routes/log.py +27 -2
  254. astrbot/dashboard/routes/persona.py +202 -0
  255. astrbot/dashboard/routes/plugin.py +197 -139
  256. astrbot/dashboard/routes/route.py +27 -7
  257. astrbot/dashboard/routes/session_management.py +354 -0
  258. astrbot/dashboard/routes/stat.py +85 -18
  259. astrbot/dashboard/routes/static_file.py +5 -2
  260. astrbot/dashboard/routes/t2i.py +233 -0
  261. astrbot/dashboard/routes/tools.py +184 -120
  262. astrbot/dashboard/routes/update.py +59 -36
  263. astrbot/dashboard/server.py +96 -36
  264. astrbot/dashboard/utils.py +165 -0
  265. astrbot-4.7.0.dist-info/METADATA +294 -0
  266. astrbot-4.7.0.dist-info/RECORD +274 -0
  267. {astrbot-3.5.6.dist-info → astrbot-4.7.0.dist-info}/WHEEL +1 -1
  268. astrbot/core/db/plugin/sqlite_impl.py +0 -112
  269. astrbot/core/db/sqlite_init.sql +0 -50
  270. astrbot/core/pipeline/platform_compatibility/stage.py +0 -56
  271. astrbot/core/pipeline/process_stage/method/llm_request.py +0 -606
  272. astrbot/core/platform/sources/gewechat/client.py +0 -806
  273. astrbot/core/platform/sources/gewechat/downloader.py +0 -55
  274. astrbot/core/platform/sources/gewechat/gewechat_event.py +0 -255
  275. astrbot/core/platform/sources/gewechat/gewechat_platform_adapter.py +0 -103
  276. astrbot/core/platform/sources/gewechat/xml_data_parser.py +0 -110
  277. astrbot/core/provider/sources/dashscope_source.py +0 -203
  278. astrbot/core/provider/sources/dify_source.py +0 -281
  279. astrbot/core/provider/sources/llmtuner_source.py +0 -132
  280. astrbot/core/rag/embedding/openai_source.py +0 -20
  281. astrbot/core/rag/knowledge_db_mgr.py +0 -94
  282. astrbot/core/rag/store/__init__.py +0 -9
  283. astrbot/core/rag/store/chroma_db.py +0 -42
  284. astrbot/core/utils/dify_api_client.py +0 -152
  285. astrbot-3.5.6.dist-info/METADATA +0 -249
  286. astrbot-3.5.6.dist-info/RECORD +0 -158
  287. {astrbot-3.5.6.dist-info → astrbot-4.7.0.dist-info}/entry_points.txt +0 -0
  288. {astrbot-3.5.6.dist-info → astrbot-4.7.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,9 +1,11 @@
1
+ from collections.abc import AsyncGenerator
2
+
3
+ from astrbot.core import logger
4
+ from astrbot.core.platform import AstrMessageEvent
5
+
1
6
  from . import STAGES_ORDER
2
- from .stage import registered_stages
3
7
  from .context import PipelineContext
4
- from typing import AsyncGenerator
5
- from astrbot.core.platform import AstrMessageEvent
6
- from astrbot.core import logger
8
+ from .stage import registered_stages
7
9
 
8
10
 
9
11
  class PipelineScheduler:
@@ -11,16 +13,17 @@ class PipelineScheduler:
11
13
 
12
14
  def __init__(self, context: PipelineContext):
13
15
  registered_stages.sort(
14
- key=lambda x: STAGES_ORDER.index(x.__class__.__name__)
16
+ key=lambda x: STAGES_ORDER.index(x.__name__),
15
17
  ) # 按照顺序排序
16
18
  self.ctx = context # 上下文对象
19
+ self.stages = [] # 存储阶段实例
17
20
 
18
21
  async def initialize(self):
19
22
  """初始化管道调度器时, 初始化所有阶段"""
20
- for stage in registered_stages:
21
- # logger.debug(f"初始化阶段 {stage.__class__ .__name__}")
22
-
23
- await stage.initialize(self.ctx)
23
+ for stage_cls in registered_stages:
24
+ stage_instance = stage_cls() # 创建实例
25
+ await stage_instance.initialize(self.ctx)
26
+ self.stages.append(stage_instance)
24
27
 
25
28
  async def _process_stages(self, event: AstrMessageEvent, from_stage=0):
26
29
  """依次执行各个阶段
@@ -28,12 +31,13 @@ class PipelineScheduler:
28
31
  Args:
29
32
  event (AstrMessageEvent): 事件对象
30
33
  from_stage (int): 从第几个阶段开始执行, 默认从0开始
34
+
31
35
  """
32
- for i in range(from_stage, len(registered_stages)):
33
- stage = registered_stages[i] # 获取当前要执行的阶段
34
- # logger.debug(f"执行阶段 {stage.__class__ .__name__}")
36
+ for i in range(from_stage, len(self.stages)):
37
+ stage = self.stages[i] # 获取当前要执行的阶段
38
+ # logger.debug(f"执行阶段 {stage.__class__.__name__}")
35
39
  coroutine = stage.process(
36
- event
40
+ event,
37
41
  ) # 调用阶段的process方法, 返回协程或者异步生成器
38
42
 
39
43
  if isinstance(coroutine, AsyncGenerator):
@@ -42,7 +46,7 @@ class PipelineScheduler:
42
46
  # 此处是前置处理完成后的暂停点(yield), 下面开始执行后续阶段
43
47
  if event.is_stopped():
44
48
  logger.debug(
45
- f"阶段 {stage.__class__.__name__} 已终止事件传播。"
49
+ f"阶段 {stage.__class__.__name__} 已终止事件传播。",
46
50
  )
47
51
  break
48
52
 
@@ -52,7 +56,7 @@ class PipelineScheduler:
52
56
  # 此处是后续所有阶段处理完毕后返回的点, 执行后置处理
53
57
  if event.is_stopped():
54
58
  logger.debug(
55
- f"阶段 {stage.__class__.__name__} 已终止事件传播。"
59
+ f"阶段 {stage.__class__.__name__} 已终止事件传播。",
56
60
  )
57
61
  break
58
62
  else:
@@ -69,11 +73,12 @@ class PipelineScheduler:
69
73
 
70
74
  Args:
71
75
  event (AstrMessageEvent): 事件对象
76
+
72
77
  """
73
78
  await self._process_stages(event)
74
79
 
75
80
  # 如果没有发送操作, 则发送一个空消息, 以便于后续的处理
76
- if not event._has_send_oper and event.get_platform_name() == "webchat":
81
+ if event.get_platform_name() in ["webchat", "wecom_ai_bot"]:
77
82
  await event.send(None)
78
83
 
79
84
  logger.debug("pipeline 执行完毕。")
@@ -0,0 +1,37 @@
1
+ from collections.abc import AsyncGenerator
2
+
3
+ from astrbot.core import logger
4
+ from astrbot.core.platform.astr_message_event import AstrMessageEvent
5
+ from astrbot.core.star.session_llm_manager import SessionServiceManager
6
+
7
+ from ..context import PipelineContext
8
+ from ..stage import Stage, register_stage
9
+
10
+
11
+ @register_stage
12
+ class SessionStatusCheckStage(Stage):
13
+ """检查会话是否整体启用"""
14
+
15
+ async def initialize(self, ctx: PipelineContext) -> None:
16
+ self.ctx = ctx
17
+ self.conv_mgr = ctx.plugin_manager.context.conversation_manager
18
+
19
+ async def process(
20
+ self,
21
+ event: AstrMessageEvent,
22
+ ) -> None | AsyncGenerator[None, None]:
23
+ # 检查会话是否整体启用
24
+ if not SessionServiceManager.is_session_enabled(event.unified_msg_origin):
25
+ logger.debug(f"会话 {event.unified_msg_origin} 已被关闭,已终止事件传播。")
26
+
27
+ # workaround for #2309
28
+ conv_id = await self.conv_mgr.get_curr_conversation_id(
29
+ event.unified_msg_origin,
30
+ )
31
+ if not conv_id:
32
+ await self.conv_mgr.new_conversation(
33
+ event.unified_msg_origin,
34
+ platform_id=event.get_platform_id(),
35
+ )
36
+
37
+ event.stop_event()
@@ -1,19 +1,18 @@
1
1
  from __future__ import annotations
2
+
2
3
  import abc
3
- import inspect
4
- import traceback
5
- from astrbot.api import logger
6
- from typing import List, AsyncGenerator, Union, Awaitable
4
+ from collections.abc import AsyncGenerator
5
+
7
6
  from astrbot.core.platform.astr_message_event import AstrMessageEvent
7
+
8
8
  from .context import PipelineContext
9
- from astrbot.core.message.message_event_result import MessageEventResult, CommandResult
10
9
 
11
- registered_stages: List[Stage] = [] # 维护了所有已注册的 Stage 实现类
10
+ registered_stages: list[type[Stage]] = [] # 维护了所有已注册的 Stage 实现类类型
12
11
 
13
12
 
14
13
  def register_stage(cls):
15
14
  """一个简单的装饰器,用于注册 pipeline 包下的 Stage 实现类"""
16
- registered_stages.append(cls())
15
+ registered_stages.append(cls)
17
16
  return cls
18
17
 
19
18
 
@@ -26,85 +25,21 @@ class Stage(abc.ABC):
26
25
 
27
26
  Args:
28
27
  ctx (PipelineContext): 消息管道上下文对象, 包括配置和插件管理器
28
+
29
29
  """
30
30
  raise NotImplementedError
31
31
 
32
32
  @abc.abstractmethod
33
33
  async def process(
34
- self, event: AstrMessageEvent
35
- ) -> Union[None, AsyncGenerator[None, None]]:
34
+ self,
35
+ event: AstrMessageEvent,
36
+ ) -> None | AsyncGenerator[None, None]:
36
37
  """处理事件
37
38
 
38
39
  Args:
39
40
  event (AstrMessageEvent): 事件对象,包含事件的相关信息
40
41
  Returns:
41
42
  Union[None, AsyncGenerator[None, None]]: 处理结果,可能是 None 或者异步生成器, 如果为 None 则表示不需要继续处理, 如果为异步生成器则表示需要继续处理(进入下一个阶段)
42
- """
43
- raise NotImplementedError
44
43
 
45
- async def _call_handler(
46
- self,
47
- ctx: PipelineContext,
48
- event: AstrMessageEvent,
49
- handler: Awaitable,
50
- *args,
51
- **kwargs,
52
- ) -> AsyncGenerator[None, None]:
53
- """执行事件处理函数并处理其返回结果
54
-
55
- 该方法负责调用处理函数并处理不同类型的返回值。它支持两种类型的处理函数:
56
- 1. 异步生成器: 实现洋葱模型,每次yield都会将控制权交回上层
57
- 2. 协程: 执行一次并处理返回值
58
-
59
- Args:
60
- ctx (PipelineContext): 消息管道上下文对象
61
- event (AstrMessageEvent): 待处理的事件对象
62
- handler (Awaitable): 事件处理函数
63
- *args: 传递给handler的位置参数
64
- **kwargs: 传递给handler的关键字参数
65
-
66
- Returns:
67
- AsyncGenerator[None, None]: 异步生成器,用于在管道中传递控制流
68
44
  """
69
- ready_to_call = None # 一个协程或者异步生成器(async def)
70
-
71
- trace_ = None
72
-
73
- try:
74
- ready_to_call = handler(event, *args, **kwargs)
75
- except TypeError as _:
76
- # 向下兼容
77
- trace_ = traceback.format_exc()
78
- # 以前的handler会额外传入一个参数, 但是context对象实际上在插件实例中有一份
79
- ready_to_call = handler(event, ctx.plugin_manager.context, *args, **kwargs)
80
-
81
- if isinstance(ready_to_call, AsyncGenerator):
82
- # 如果是一个异步生成器, 进入洋葱模型
83
- _has_yielded = False # 是否返回过值
84
- try:
85
- async for ret in ready_to_call:
86
- # 这里逐步执行异步生成器, 对于每个yield返回的ret, 执行下面的代码
87
- # 返回值只能是 MessageEventResult 或者 None(无返回值)
88
- _has_yielded = True
89
- if isinstance(ret, (MessageEventResult, CommandResult)):
90
- # 如果返回值是 MessageEventResult, 设置结果并继续
91
- event.set_result(ret)
92
- yield # 传递控制权给上一层的process函数
93
- else:
94
- # 如果返回值是 None, 则不设置结果并继续
95
- # 继续执行后续阶段
96
- yield ret # 传递控制权给上一层的process函数
97
- if not _has_yielded:
98
- # 如果这个异步生成器没有执行到yield分支
99
- yield
100
- except Exception as e:
101
- logger.error(f"Previous Error: {trace_}")
102
- raise e
103
- elif inspect.iscoroutine(ready_to_call):
104
- # 如果只是一个协程, 直接执行
105
- ret = await ready_to_call
106
- if isinstance(ret, (MessageEventResult, CommandResult)):
107
- event.set_result(ret)
108
- yield # 传递控制权给上一层的process函数
109
- else:
110
- yield ret # 传递控制权给上一层的process函数
45
+ raise NotImplementedError
@@ -1,13 +1,17 @@
1
- from ..stage import Stage, register_stage
2
- from ..context import PipelineContext
1
+ from collections.abc import AsyncGenerator
2
+
3
3
  from astrbot import logger
4
- from typing import Union, AsyncGenerator
4
+ from astrbot.core.message.components import At, AtAll, Reply
5
+ from astrbot.core.message.message_event_result import MessageChain, MessageEventResult
5
6
  from astrbot.core.platform.astr_message_event import AstrMessageEvent
6
- from astrbot.core.message.message_event_result import MessageEventResult, MessageChain
7
- from astrbot.core.message.components import At
8
- from astrbot.core.star.star_handler import star_handlers_registry, EventType
9
- from astrbot.core.star.star import star_map
7
+ from astrbot.core.star.filter.command_group import CommandGroupFilter
10
8
  from astrbot.core.star.filter.permission import PermissionTypeFilter
9
+ from astrbot.core.star.session_plugin_manager import SessionPluginManager
10
+ from astrbot.core.star.star import star_map
11
+ from astrbot.core.star.star_handler import EventType, star_handlers_registry
12
+
13
+ from ..context import PipelineContext
14
+ from ..stage import Stage, register_stage
11
15
 
12
16
 
13
17
  @register_stage
@@ -26,10 +30,12 @@ class WakingCheckStage(Stage):
26
30
 
27
31
  Args:
28
32
  ctx (PipelineContext): 消息管道上下文对象, 包括配置和插件管理器
33
+
29
34
  """
30
35
  self.ctx = ctx
31
36
  self.no_permission_reply = self.ctx.astrbot_config["platform_settings"].get(
32
- "no_permission_reply", True
37
+ "no_permission_reply",
38
+ True,
33
39
  )
34
40
  # 私聊是否需要 wake_prefix 才能唤醒机器人
35
41
  self.friend_message_needs_wake_prefix = self.ctx.astrbot_config[
@@ -37,12 +43,18 @@ class WakingCheckStage(Stage):
37
43
  ].get("friend_message_needs_wake_prefix", False)
38
44
  # 是否忽略机器人自己发送的消息
39
45
  self.ignore_bot_self_message = self.ctx.astrbot_config["platform_settings"].get(
40
- "ignore_bot_self_message", False
46
+ "ignore_bot_self_message",
47
+ False,
48
+ )
49
+ self.ignore_at_all = self.ctx.astrbot_config["platform_settings"].get(
50
+ "ignore_at_all",
51
+ False,
41
52
  )
42
53
 
43
54
  async def process(
44
- self, event: AstrMessageEvent
45
- ) -> Union[None, AsyncGenerator[None, None]]:
55
+ self,
56
+ event: AstrMessageEvent,
57
+ ) -> None | AsyncGenerator[None, None]:
46
58
  if (
47
59
  self.ignore_bot_self_message
48
60
  and event.get_self_id() == event.get_sender_id()
@@ -77,11 +89,18 @@ class WakingCheckStage(Stage):
77
89
  event.message_str = event.message_str[len(wake_prefix) :].strip()
78
90
  break
79
91
  if not is_wake:
80
- # 检查是否有 at 消息
92
+ # 检查是否有at消息 / at全体成员消息 / 引用了bot的消息
81
93
  for message in messages:
82
- if isinstance(message, At) and (
83
- str(message.qq) == str(event.get_self_id())
84
- or str(message.qq) == "all"
94
+ if (
95
+ (
96
+ isinstance(message, At)
97
+ and (str(message.qq) == str(event.get_self_id()))
98
+ )
99
+ or (isinstance(message, AtAll) and not self.ignore_at_all)
100
+ or (
101
+ isinstance(message, Reply)
102
+ and str(message.sender_id) == str(event.get_self_id())
103
+ )
85
104
  ):
86
105
  is_wake = True
87
106
  event.is_wake = True
@@ -99,8 +118,18 @@ class WakingCheckStage(Stage):
99
118
  activated_handlers = []
100
119
  handlers_parsed_params = {} # 注册了指令的 handler
101
120
 
121
+ # 将 plugins_name 设置到 event 中
122
+ enabled_plugins_name = self.ctx.astrbot_config.get("plugin_set", ["*"])
123
+ if enabled_plugins_name == ["*"]:
124
+ # 如果是 *,则表示所有插件都启用
125
+ event.plugins_name = None
126
+ else:
127
+ event.plugins_name = enabled_plugins_name
128
+ logger.debug(f"enabled_plugins_name: {enabled_plugins_name}")
129
+
102
130
  for handler in star_handlers_registry.get_handlers_by_event_type(
103
- EventType.AdapterMessageEvent
131
+ EventType.AdapterMessageEvent,
132
+ plugins_name=event.plugins_name,
104
133
  ):
105
134
  # filter 需满足 AND 逻辑关系
106
135
  passed = True
@@ -115,17 +144,15 @@ class WakingCheckStage(Stage):
115
144
  if not filter.filter(event, self.ctx.astrbot_config):
116
145
  permission_not_pass = True
117
146
  permission_filter_raise_error = filter.raise_error
118
- else:
119
- if not filter.filter(event, self.ctx.astrbot_config):
120
- passed = False
121
- break
147
+ elif not filter.filter(event, self.ctx.astrbot_config):
148
+ passed = False
149
+ break
122
150
  except Exception as e:
123
151
  await event.send(
124
152
  MessageEventResult().message(
125
- f"插件 {star_map[handler.handler_module_path].name}: {e}"
126
- )
153
+ f"插件 {star_map[handler.handler_module_path].name}: {e}",
154
+ ),
127
155
  )
128
- await event._post_send()
129
156
  event.stop_event()
130
157
  passed = False
131
158
  break
@@ -137,12 +164,11 @@ class WakingCheckStage(Stage):
137
164
  if self.no_permission_reply:
138
165
  await event.send(
139
166
  MessageChain().message(
140
- f"ID {event.get_sender_id()} 权限不足。通过 /sid 获取 ID 并请管理员添加。"
141
- )
167
+ f"您(ID: {event.get_sender_id()})的权限不足以使用此指令。通过 /sid 获取 ID 并请管理员添加。",
168
+ ),
142
169
  )
143
- await event._post_send()
144
170
  logger.info(
145
- f"触发 {star_map[handler.handler_module_path].name} 时, 用户(ID={event.get_sender_id()}) 权限不足。"
171
+ f"触发 {star_map[handler.handler_module_path].name} 时, 用户(ID={event.get_sender_id()}) 权限不足。",
146
172
  )
147
173
  event.stop_event()
148
174
  return
@@ -150,13 +176,23 @@ class WakingCheckStage(Stage):
150
176
  is_wake = True
151
177
  event.is_wake = True
152
178
 
153
- activated_handlers.append(handler)
154
- if "parsed_params" in event.get_extra():
155
- handlers_parsed_params[handler.handler_full_name] = event.get_extra(
156
- "parsed_params"
157
- )
179
+ is_group_cmd_handler = any(
180
+ isinstance(f, CommandGroupFilter) for f in handler.event_filters
181
+ )
182
+ if not is_group_cmd_handler:
183
+ activated_handlers.append(handler)
184
+ if "parsed_params" in event.get_extra(default={}):
185
+ handlers_parsed_params[handler.handler_full_name] = (
186
+ event.get_extra("parsed_params")
187
+ )
158
188
 
159
- event.clear_extra()
189
+ event._extras.pop("parsed_params", None)
190
+
191
+ # 根据会话配置过滤插件处理器
192
+ activated_handlers = SessionPluginManager.filter_handlers_by_session(
193
+ event,
194
+ activated_handlers,
195
+ )
160
196
 
161
197
  event.set_extra("activated_handlers", activated_handlers)
162
198
  event.set_extra("handlers_parsed_params", handlers_parsed_params)
@@ -1,9 +1,11 @@
1
- from ..stage import Stage, register_stage
2
- from ..context import PipelineContext
3
- from typing import AsyncGenerator, Union
1
+ from collections.abc import AsyncGenerator
2
+
3
+ from astrbot.core import logger
4
4
  from astrbot.core.platform.astr_message_event import AstrMessageEvent
5
5
  from astrbot.core.platform.message_type import MessageType
6
- from astrbot.core import logger
6
+
7
+ from ..context import PipelineContext
8
+ from ..stage import Stage, register_stage
7
9
 
8
10
 
9
11
  @register_stage
@@ -27,8 +29,9 @@ class WhitelistCheckStage(Stage):
27
29
  self.wl_log = ctx.astrbot_config["platform_settings"]["id_whitelist_log"]
28
30
 
29
31
  async def process(
30
- self, event: AstrMessageEvent
31
- ) -> Union[None, AsyncGenerator[None, None]]:
32
+ self,
33
+ event: AstrMessageEvent,
34
+ ) -> None | AsyncGenerator[None, None]:
32
35
  if not self.enable_whitelist_check:
33
36
  # 白名单检查未启用
34
37
  return
@@ -60,6 +63,6 @@ class WhitelistCheckStage(Stage):
60
63
  ):
61
64
  if self.wl_log:
62
65
  logger.info(
63
- f"会话 ID {event.unified_msg_origin} 不在会话白名单中,已终止事件传播。请在配置文件中添加该会话 ID 到白名单。"
66
+ f"会话 ID {event.unified_msg_origin} 不在会话白名单中,已终止事件传播。请在配置文件中添加该会话 ID 到白名单。",
64
67
  )
65
68
  event.stop_event()
@@ -1,14 +1,14 @@
1
- from .platform import Platform
2
1
  from .astr_message_event import AstrMessageEvent
2
+ from .astrbot_message import AstrBotMessage, Group, MessageMember, MessageType
3
+ from .platform import Platform
3
4
  from .platform_metadata import PlatformMetadata
4
- from .astrbot_message import AstrBotMessage, MessageMember, MessageType, Group
5
5
 
6
6
  __all__ = [
7
- "Platform",
8
- "AstrMessageEvent",
9
- "PlatformMetadata",
10
7
  "AstrBotMessage",
8
+ "AstrMessageEvent",
9
+ "Group",
11
10
  "MessageMember",
12
11
  "MessageType",
13
- "Group",
12
+ "Platform",
13
+ "PlatformMetadata",
14
14
  ]