AstrBot 4.5.1__py3-none-any.whl → 4.5.3__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 +4 -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 +12 -10
  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 +42 -27
  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 +32 -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 +77 -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 +16 -8
  181. astrbot/core/provider/sources/xinference_stt_provider.py +35 -25
  182. astrbot/core/star/__init__.py +16 -11
  183. astrbot/core/star/config.py +10 -15
  184. astrbot/core/star/context.py +97 -75
  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 +56 -53
  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.1.dist-info → astrbot-4.5.3.dist-info}/METADATA +2 -1
  240. astrbot-4.5.3.dist-info/RECORD +261 -0
  241. astrbot-4.5.1.dist-info/RECORD +0 -260
  242. {astrbot-4.5.1.dist-info → astrbot-4.5.3.dist-info}/WHEEL +0 -0
  243. {astrbot-4.5.1.dist-info → astrbot-4.5.3.dist-info}/entry_points.txt +0 -0
  244. {astrbot-4.5.1.dist-info → astrbot-4.5.3.dist-info}/licenses/LICENSE +0 -0
@@ -1,43 +1,46 @@
1
+ import logging
1
2
  from asyncio import Queue
3
+ from collections.abc import Awaitable, Callable
4
+ from typing import Any
2
5
 
3
- from astrbot.core.provider.provider import (
4
- Provider,
5
- TTSProvider,
6
- STTProvider,
7
- EmbeddingProvider,
8
- RerankProvider,
9
- )
10
- from astrbot.core.provider.entities import ProviderType
11
- from astrbot.core.db import BaseDatabase
6
+ from deprecated import deprecated
7
+
8
+ from astrbot.core.astrbot_config_mgr import AstrBotConfigManager
12
9
  from astrbot.core.config.astrbot_config import AstrBotConfig
13
- from astrbot.core.provider.func_tool_manager import FunctionToolManager, FunctionTool
14
- from astrbot.core.platform.astr_message_event import MessageSesion
10
+ from astrbot.core.conversation_mgr import ConversationManager
11
+ from astrbot.core.db import BaseDatabase
12
+ from astrbot.core.knowledge_base.kb_mgr import KnowledgeBaseManager
15
13
  from astrbot.core.message.message_event_result import MessageChain
16
- from astrbot.core.provider.manager import ProviderManager
14
+ from astrbot.core.persona_mgr import PersonaManager
17
15
  from astrbot.core.platform import Platform
16
+ from astrbot.core.platform.astr_message_event import MessageSesion
18
17
  from astrbot.core.platform.manager import PlatformManager
19
18
  from astrbot.core.platform_message_history_mgr import PlatformMessageHistoryManager
20
- from astrbot.core.astrbot_config_mgr import AstrBotConfigManager
21
- from astrbot.core.knowledge_base.kb_mgr import KnowledgeBaseManager
22
- from astrbot.core.persona_mgr import PersonaManager
23
- from .star import star_registry, StarMetadata, star_map
24
- from .star_handler import star_handlers_registry, StarHandlerMetadata, EventType
25
- from .filter.command import CommandFilter
26
- from .filter.regex import RegexFilter
27
- from typing import Any
28
- from collections.abc import Awaitable, Callable
29
- from astrbot.core.conversation_mgr import ConversationManager
19
+ from astrbot.core.provider.entities import ProviderType
20
+ from astrbot.core.provider.func_tool_manager import FunctionTool, FunctionToolManager
21
+ from astrbot.core.provider.manager import ProviderManager
22
+ from astrbot.core.provider.provider import (
23
+ EmbeddingProvider,
24
+ Provider,
25
+ RerankProvider,
26
+ STTProvider,
27
+ TTSProvider,
28
+ )
30
29
  from astrbot.core.star.filter.platform_adapter_type import (
31
- PlatformAdapterType,
32
30
  ADAPTER_NAME_2_TYPE,
31
+ PlatformAdapterType,
33
32
  )
34
- from deprecated import deprecated
33
+
34
+ from .filter.command import CommandFilter
35
+ from .filter.regex import RegexFilter
36
+ from .star import StarMetadata, star_map, star_registry
37
+ from .star_handler import EventType, StarHandlerMetadata, star_handlers_registry
38
+
39
+ logger = logging.getLogger("astrbot")
35
40
 
36
41
 
37
42
  class Context:
38
- """
39
- 暴露给插件的接口上下文。
40
- """
43
+ """暴露给插件的接口上下文。"""
41
44
 
42
45
  registered_web_apis: list = []
43
46
 
@@ -91,6 +94,7 @@ class Context:
91
94
 
92
95
  Returns:
93
96
  如果没找到,会返回 False
97
+
94
98
  """
95
99
  return self.provider_manager.llm_tools.activate_llm_tool(name, star_map)
96
100
 
@@ -98,17 +102,18 @@ class Context:
98
102
  """停用一个已经注册的函数调用工具。
99
103
 
100
104
  Returns:
101
- 如果没找到,会返回 False"""
105
+ 如果没找到,会返回 False
106
+
107
+ """
102
108
  return self.provider_manager.llm_tools.deactivate_llm_tool(name)
103
109
 
104
110
  def register_provider(self, provider: Provider):
105
- """
106
- 注册一个 LLM Provider(Chat_Completion 类型)。
107
- """
111
+ """注册一个 LLM Provider(Chat_Completion 类型)。"""
108
112
  self.provider_manager.provider_insts.append(provider)
109
113
 
110
114
  def get_provider_by_id(
111
- self, provider_id: str
115
+ self,
116
+ provider_id: str,
112
117
  ) -> (
113
118
  Provider | TTSProvider | STTProvider | EmbeddingProvider | RerankProvider | None
114
119
  ):
@@ -133,11 +138,11 @@ class Context:
133
138
  return self.provider_manager.embedding_provider_insts
134
139
 
135
140
  def get_using_provider(self, umo: str | None = None) -> Provider | None:
136
- """
137
- 获取当前使用的用于文本生成任务的 LLM Provider(Chat_Completion 类型)。通过 /provider 指令切换。
141
+ """获取当前使用的用于文本生成任务的 LLM Provider(Chat_Completion 类型)。通过 /provider 指令切换。
138
142
 
139
143
  Args:
140
144
  umo(str): unified_message_origin 值,如果传入并且用户启用了提供商会话隔离,则使用该会话偏好的提供商。
145
+
141
146
  """
142
147
  prov = self.provider_manager.get_using_provider(
143
148
  provider_type=ProviderType.CHAT_COMPLETION,
@@ -148,11 +153,11 @@ class Context:
148
153
  return prov
149
154
 
150
155
  def get_using_tts_provider(self, umo: str | None = None) -> TTSProvider | None:
151
- """
152
- 获取当前使用的用于 TTS 任务的 Provider。
156
+ """获取当前使用的用于 TTS 任务的 Provider。
153
157
 
154
158
  Args:
155
159
  umo(str): unified_message_origin 值,如果传入,则使用该会话偏好的提供商。
160
+
156
161
  """
157
162
  prov = self.provider_manager.get_using_provider(
158
163
  provider_type=ProviderType.TEXT_TO_SPEECH,
@@ -163,11 +168,11 @@ class Context:
163
168
  return prov
164
169
 
165
170
  def get_using_stt_provider(self, umo: str | None = None) -> STTProvider | None:
166
- """
167
- 获取当前使用的用于 STT 任务的 Provider。
171
+ """获取当前使用的用于 STT 任务的 Provider。
168
172
 
169
173
  Args:
170
174
  umo(str): unified_message_origin 值,如果传入,则使用该会话偏好的提供商。
175
+
171
176
  """
172
177
  prov = self.provider_manager.get_using_provider(
173
178
  provider_type=ProviderType.SPEECH_TO_TEXT,
@@ -182,23 +187,19 @@ class Context:
182
187
  if not umo:
183
188
  # using default config
184
189
  return self._config
185
- else:
186
- return self.astrbot_config_mgr.get_conf(umo)
190
+ return self.astrbot_config_mgr.get_conf(umo)
187
191
 
188
192
  def get_db(self) -> BaseDatabase:
189
193
  """获取 AstrBot 数据库。"""
190
194
  return self._db
191
195
 
192
196
  def get_event_queue(self) -> Queue:
193
- """
194
- 获取事件队列。
195
- """
197
+ """获取事件队列。"""
196
198
  return self._event_queue
197
199
 
198
200
  @deprecated(version="4.0.0", reason="Use get_platform_inst instead")
199
201
  def get_platform(self, platform_type: PlatformAdapterType | str) -> Platform | None:
200
- """
201
- 获取指定类型的平台适配器。
202
+ """获取指定类型的平台适配器。
202
203
 
203
204
  该方法已经过时,请使用 get_platform_inst 方法。(>= AstrBot v4.0.0)
204
205
  """
@@ -207,32 +208,32 @@ class Context:
207
208
  if isinstance(platform_type, str):
208
209
  if name == platform_type:
209
210
  return platform
210
- else:
211
- if (
212
- name in ADAPTER_NAME_2_TYPE
213
- and ADAPTER_NAME_2_TYPE[name] & platform_type
214
- ):
215
- return platform
211
+ elif (
212
+ name in ADAPTER_NAME_2_TYPE
213
+ and ADAPTER_NAME_2_TYPE[name] & platform_type
214
+ ):
215
+ return platform
216
216
 
217
217
  def get_platform_inst(self, platform_id: str) -> Platform | None:
218
- """
219
- 获取指定 ID 的平台适配器实例。
218
+ """获取指定 ID 的平台适配器实例。
220
219
 
221
220
  Args:
222
221
  platform_id (str): 平台适配器的唯一标识符。你可以通过 event.get_platform_id() 获取。
223
222
 
224
223
  Returns:
225
224
  Platform: 平台适配器实例,如果未找到则返回 None。
225
+
226
226
  """
227
227
  for platform in self.platform_manager.platform_insts:
228
228
  if platform.meta().id == platform_id:
229
229
  return platform
230
230
 
231
231
  async def send_message(
232
- self, session: str | MessageSesion, message_chain: MessageChain
232
+ self,
233
+ session: str | MessageSesion,
234
+ message_chain: MessageChain,
233
235
  ) -> bool:
234
- """
235
- 根据 session(unified_msg_origin) 主动发送消息。
236
+ """根据 session(unified_msg_origin) 主动发送消息。
236
237
 
237
238
  @param session: 消息会话。通过 event.session 或者 event.unified_msg_origin 获取。
238
239
  @param message_chain: 消息链。
@@ -243,7 +244,6 @@ class Context:
243
244
 
244
245
  NOTE: qq_official(QQ 官方 API 平台) 不支持此方法
245
246
  """
246
-
247
247
  if isinstance(session, str):
248
248
  try:
249
249
  session = MessageSesion.from_str(session)
@@ -258,9 +258,44 @@ class Context:
258
258
 
259
259
  def add_llm_tools(self, *tools: FunctionTool) -> None:
260
260
  """添加 LLM 工具。"""
261
+ tool_name = {tool.name for tool in self.provider_manager.llm_tools.func_list}
262
+ module_path = ""
261
263
  for tool in tools:
264
+ if not module_path:
265
+ _parts = []
266
+ module_part = tool.__module__.split(".")
267
+ flags = ["packages", "plugins"]
268
+ for i, part in enumerate(module_part):
269
+ _parts.append(part)
270
+ if part in flags and i + 1 < len(module_part):
271
+ _parts.append(module_part[i + 1])
272
+ break
273
+ tool.handler_module_path = ".".join(_parts)
274
+ module_path = tool.handler_module_path
275
+ else:
276
+ tool.handler_module_path = module_path
277
+ logger.info(
278
+ f"plugin(module_path {module_path}) added LLM tool: {tool.name}"
279
+ )
280
+
281
+ if tool.name in tool_name:
282
+ logger.warning("替换已存在的 LLM 工具: " + tool.name)
283
+ self.provider_manager.llm_tools.remove_func(tool.name)
262
284
  self.provider_manager.llm_tools.func_list.append(tool)
263
285
 
286
+ def register_web_api(
287
+ self,
288
+ route: str,
289
+ view_handler: Awaitable,
290
+ methods: list,
291
+ desc: str,
292
+ ):
293
+ for idx, api in enumerate(self.registered_web_apis):
294
+ if api[0] == route and methods == api[2]:
295
+ self.registered_web_apis[idx] = (route, view_handler, methods, desc)
296
+ return
297
+ self.registered_web_apis.append((route, view_handler, methods, desc))
298
+
264
299
  """
265
300
  以下的方法已经不推荐使用。请从 AstrBot 文档查看更好的注册方式。
266
301
  """
@@ -272,8 +307,7 @@ class Context:
272
307
  desc: str,
273
308
  func_obj: Callable[..., Awaitable[Any]],
274
309
  ) -> None:
275
- """
276
- 为函数调用(function-calling / tools-use)添加工具。
310
+ """[DEPRECATED]为函数调用(function-calling / tools-use)添加工具。
277
311
 
278
312
  @param name: 函数名
279
313
  @param func_args: 函数参数列表,格式为 [{"type": "string", "name": "arg_name", "description": "arg_description"}, ...]
@@ -295,7 +329,7 @@ class Context:
295
329
  self.provider_manager.llm_tools.add_func(name, func_args, desc, func_obj)
296
330
 
297
331
  def unregister_llm_tool(self, name: str) -> None:
298
- """删除一个函数调用工具。如果再要启用,需要重新注册。"""
332
+ """[DEPRECATED]删除一个函数调用工具。如果再要启用,需要重新注册。"""
299
333
  self.provider_manager.llm_tools.remove_func(name)
300
334
 
301
335
  def register_commands(
@@ -308,8 +342,7 @@ class Context:
308
342
  use_regex=False,
309
343
  ignore_prefix=False,
310
344
  ):
311
- """
312
- 注册一个命令。
345
+ """注册一个命令。
313
346
 
314
347
  [Deprecated] 推荐使用装饰器注册指令。该方法将在未来的版本中被移除。
315
348
 
@@ -333,21 +366,10 @@ class Context:
333
366
  md.event_filters.append(RegexFilter(regex=command_name))
334
367
  else:
335
368
  md.event_filters.append(
336
- CommandFilter(command_name=command_name, handler_md=md)
369
+ CommandFilter(command_name=command_name, handler_md=md),
337
370
  )
338
371
  star_handlers_registry.append(md)
339
372
 
340
373
  def register_task(self, task: Awaitable, desc: str):
341
- """
342
- 注册一个异步任务。
343
- """
374
+ """[DEPRECATED]注册一个异步任务。"""
344
375
  self._register_tasks.append(task)
345
-
346
- def register_web_api(
347
- self, route: str, view_handler: Awaitable, methods: list, desc: str
348
- ):
349
- for idx, api in enumerate(self.registered_web_apis):
350
- if api[0] == route and methods == api[2]:
351
- self.registered_web_apis[idx] = (route, view_handler, methods, desc)
352
- return
353
- self.registered_web_apis.append((route, view_handler, methods, desc))
@@ -1,7 +1,8 @@
1
1
  import abc
2
- from astrbot.core.platform.message_type import MessageType
3
- from astrbot.core.platform.astr_message_event import AstrMessageEvent
2
+
4
3
  from astrbot.core.config import AstrBotConfig
4
+ from astrbot.core.platform.astr_message_event import AstrMessageEvent
5
+ from astrbot.core.platform.message_type import MessageType
5
6
 
6
7
 
7
8
  class HandlerFilter(abc.ABC):
@@ -11,4 +12,4 @@ class HandlerFilter(abc.ABC):
11
12
  raise NotImplementedError
12
13
 
13
14
 
14
- __all__ = ["HandlerFilter", "MessageType", "AstrMessageEvent", "AstrBotConfig"]
15
+ __all__ = ["AstrBotConfig", "AstrMessageEvent", "HandlerFilter", "MessageType"]
@@ -1,20 +1,20 @@
1
- import re
2
1
  import inspect
2
+ import re
3
3
  import types
4
4
  import typing
5
- from typing import List, Any, Type, Dict
6
- from . import HandlerFilter
7
- from astrbot.core.platform.astr_message_event import AstrMessageEvent
5
+ from typing import Any
6
+
8
7
  from astrbot.core.config import AstrBotConfig
9
- from .custom_filter import CustomFilter
8
+ from astrbot.core.platform.astr_message_event import AstrMessageEvent
9
+
10
10
  from ..star_handler import StarHandlerMetadata
11
+ from . import HandlerFilter
12
+ from .custom_filter import CustomFilter
11
13
 
12
14
 
13
15
  class GreedyStr(str):
14
16
  """标记指令完成其他参数接收后的所有剩余文本。"""
15
17
 
16
- pass
17
-
18
18
 
19
19
  def unwrap_optional(annotation) -> tuple:
20
20
  """去掉 Optional[T] / Union[T, None] / T|None,返回 T"""
@@ -22,10 +22,9 @@ def unwrap_optional(annotation) -> tuple:
22
22
  non_none_args = [a for a in args if a is not type(None)]
23
23
  if len(non_none_args) == 1:
24
24
  return (non_none_args[0],)
25
- elif len(non_none_args) > 1:
25
+ if len(non_none_args) > 1:
26
26
  return tuple(non_none_args)
27
- else:
28
- return ()
27
+ return ()
29
28
 
30
29
 
31
30
  # 标准指令受到 wake_prefix 的制约。
@@ -37,28 +36,30 @@ class CommandFilter(HandlerFilter):
37
36
  command_name: str,
38
37
  alias: set | None = None,
39
38
  handler_md: StarHandlerMetadata | None = None,
40
- parent_command_names: List[str] = [""],
39
+ parent_command_names: list[str] | None = None,
41
40
  ):
42
41
  self.command_name = command_name
43
42
  self.alias = alias if alias else set()
44
- self.parent_command_names = parent_command_names
43
+ self.parent_command_names = (
44
+ parent_command_names if parent_command_names is not None else [""]
45
+ )
45
46
  if handler_md:
46
47
  self.init_handler_md(handler_md)
47
- self.custom_filter_list: List[CustomFilter] = []
48
+ self.custom_filter_list: list[CustomFilter] = []
48
49
 
49
50
  # Cache for complete command names list
50
51
  self._cmpl_cmd_names: list | None = None
51
52
 
52
53
  def print_types(self):
53
- result = ""
54
+ parts = []
54
55
  for k, v in self.handler_params.items():
55
56
  if isinstance(v, type):
56
- result += f"{k}({v.__name__}),"
57
+ parts.append(f"{k}({v.__name__}),")
57
58
  elif isinstance(v, types.UnionType) or typing.get_origin(v) is typing.Union:
58
- result += f"{k}({v}),"
59
+ parts.append(f"{k}({v}),")
59
60
  else:
60
- result += f"{k}({type(v).__name__})={v},"
61
- result = result.rstrip(",")
61
+ parts.append(f"{k}({type(v).__name__})={v},")
62
+ result = "".join(parts).rstrip(",")
62
63
  return result
63
64
 
64
65
  def init_handler_md(self, handle_md: StarHandlerMetadata):
@@ -89,8 +90,10 @@ class CommandFilter(HandlerFilter):
89
90
  return True
90
91
 
91
92
  def validate_and_convert_params(
92
- self, params: List[Any], param_type: Dict[str, Type]
93
- ) -> Dict[str, Any]:
93
+ self,
94
+ params: list[Any],
95
+ param_type: dict[str, type],
96
+ ) -> dict[str, Any]:
94
97
  """将参数列表 params 根据 param_type 转换为参数字典。"""
95
98
  result = {}
96
99
  param_items = list(param_type.items())
@@ -101,7 +104,7 @@ class CommandFilter(HandlerFilter):
101
104
  # GreedyStr 必须是最后一个参数
102
105
  if i != len(param_items) - 1:
103
106
  raise ValueError(
104
- f"参数 '{param_name}' (GreedyStr) 必须是最后一个参数。"
107
+ f"参数 '{param_name}' (GreedyStr) 必须是最后一个参数。",
105
108
  )
106
109
 
107
110
  # 将剩余的所有部分合并成一个字符串
@@ -111,17 +114,16 @@ class CommandFilter(HandlerFilter):
111
114
  # 没有 GreedyStr 的情况
112
115
  if i >= len(params):
113
116
  if (
114
- isinstance(param_type_or_default_val, (Type, types.UnionType))
117
+ isinstance(param_type_or_default_val, (type, types.UnionType))
115
118
  or typing.get_origin(param_type_or_default_val) is typing.Union
116
119
  or param_type_or_default_val is inspect.Parameter.empty
117
120
  ):
118
121
  # 是类型
119
122
  raise ValueError(
120
- f"必要参数缺失。该指令完整参数: {self.print_types()}"
123
+ f"必要参数缺失。该指令完整参数: {self.print_types()}",
121
124
  )
122
- else:
123
- # 是默认值
124
- result[param_name] = param_type_or_default_val
125
+ # 是默认值
126
+ result[param_name] = param_type_or_default_val
125
127
  else:
126
128
  # 尝试强制转换
127
129
  try:
@@ -142,7 +144,7 @@ class CommandFilter(HandlerFilter):
142
144
  result[param_name] = False
143
145
  else:
144
146
  raise ValueError(
145
- f"参数 {param_name} 必须是布尔值(true/false, yes/no, 1/0)。"
147
+ f"参数 {param_name} 必须是布尔值(true/false, yes/no, 1/0)。",
146
148
  )
147
149
  elif isinstance(param_type_or_default_val, int):
148
150
  result[param_name] = int(params[i])
@@ -165,7 +167,7 @@ class CommandFilter(HandlerFilter):
165
167
  result[param_name] = param_type_or_default_val(params[i])
166
168
  except ValueError:
167
169
  raise ValueError(
168
- f"参数 {param_name} 类型错误。完整参数: {self.print_types()}"
170
+ f"参数 {param_name} 类型错误。完整参数: {self.print_types()}",
169
171
  )
170
172
  return result
171
173
 
@@ -1,10 +1,10 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import List, Union
3
+ from astrbot.core.config import AstrBotConfig
4
+ from astrbot.core.platform.astr_message_event import AstrMessageEvent
5
+
4
6
  from . import HandlerFilter
5
7
  from .command import CommandFilter
6
- from astrbot.core.platform.astr_message_event import AstrMessageEvent
7
- from astrbot.core.config import AstrBotConfig
8
8
  from .custom_filter import CustomFilter
9
9
 
10
10
 
@@ -18,25 +18,27 @@ class CommandGroupFilter(HandlerFilter):
18
18
  ):
19
19
  self.group_name = group_name
20
20
  self.alias = alias if alias else set()
21
- self.sub_command_filters: List[Union[CommandFilter, CommandGroupFilter]] = []
22
- self.custom_filter_list: List[CustomFilter] = []
21
+ self.sub_command_filters: list[CommandFilter | CommandGroupFilter] = []
22
+ self.custom_filter_list: list[CustomFilter] = []
23
23
  self.parent_group = parent_group
24
24
 
25
25
  # Cache for complete command names list
26
26
  self._cmpl_cmd_names: list | None = None
27
27
 
28
28
  def add_sub_command_filter(
29
- self, sub_command_filter: Union[CommandFilter, CommandGroupFilter]
29
+ self,
30
+ sub_command_filter: CommandFilter | CommandGroupFilter,
30
31
  ):
31
32
  self.sub_command_filters.append(sub_command_filter)
32
33
 
33
34
  def add_custom_filter(self, custom_filter: CustomFilter):
34
35
  self.custom_filter_list.append(custom_filter)
35
36
 
36
- def get_complete_command_names(self) -> List[str]:
37
+ def get_complete_command_names(self) -> list[str]:
37
38
  """遍历父节点获取完整的指令名。
38
39
 
39
- 新版本 v3.4.29 采用预编译指令,不再从指令组递归遍历子指令,因此这个方法是返回包括别名在内的整个指令名列表。"""
40
+ 新版本 v3.4.29 采用预编译指令,不再从指令组递归遍历子指令,因此这个方法是返回包括别名在内的整个指令名列表。
41
+ """
40
42
  if self._cmpl_cmd_names is not None:
41
43
  return self._cmpl_cmd_names
42
44
 
@@ -59,12 +61,12 @@ class CommandGroupFilter(HandlerFilter):
59
61
  # 以树的形式打印出来
60
62
  def print_cmd_tree(
61
63
  self,
62
- sub_command_filters: List[Union[CommandFilter, CommandGroupFilter]],
64
+ sub_command_filters: list[CommandFilter | CommandGroupFilter],
63
65
  prefix: str = "",
64
66
  event: AstrMessageEvent | None = None,
65
67
  cfg: AstrBotConfig | None = None,
66
68
  ) -> str:
67
- result = ""
69
+ parts = []
68
70
  for sub_filter in sub_command_filters:
69
71
  if isinstance(sub_filter, CommandFilter):
70
72
  custom_filter_pass = True
@@ -72,31 +74,32 @@ class CommandGroupFilter(HandlerFilter):
72
74
  custom_filter_pass = sub_filter.custom_filter_ok(event, cfg)
73
75
  if custom_filter_pass:
74
76
  cmd_th = sub_filter.print_types()
75
- result += f"{prefix}├── {sub_filter.command_name}"
77
+ line = f"{prefix}├── {sub_filter.command_name}"
76
78
  if cmd_th:
77
- result += f" ({cmd_th})"
79
+ line += f" ({cmd_th})"
78
80
  else:
79
- result += " (无参数指令)"
81
+ line += " (无参数指令)"
80
82
 
81
83
  if sub_filter.handler_md and sub_filter.handler_md.desc:
82
- result += f": {sub_filter.handler_md.desc}"
84
+ line += f": {sub_filter.handler_md.desc}"
83
85
 
84
- result += "\n"
86
+ parts.append(line + "\n")
85
87
  elif isinstance(sub_filter, CommandGroupFilter):
86
88
  custom_filter_pass = True
87
89
  if event and cfg:
88
90
  custom_filter_pass = sub_filter.custom_filter_ok(event, cfg)
89
91
  if custom_filter_pass:
90
- result += f"{prefix}├── {sub_filter.group_name}"
91
- result += "\n"
92
- result += sub_filter.print_cmd_tree(
93
- sub_filter.sub_command_filters,
94
- prefix + "│ ",
95
- event=event,
96
- cfg=cfg,
92
+ parts.append(f"{prefix}├── {sub_filter.group_name}\n")
93
+ parts.append(
94
+ sub_filter.print_cmd_tree(
95
+ sub_filter.sub_command_filters,
96
+ prefix + "│ ",
97
+ event=event,
98
+ cfg=cfg,
99
+ )
97
100
  )
98
101
 
99
- return result
102
+ return "".join(parts)
100
103
 
101
104
  def custom_filter_ok(self, event: AstrMessageEvent, cfg: AstrBotConfig) -> bool:
102
105
  for custom_filter in self.custom_filter_list:
@@ -125,7 +128,7 @@ class CommandGroupFilter(HandlerFilter):
125
128
  + self.print_cmd_tree(self.sub_command_filters, event=event, cfg=cfg)
126
129
  )
127
130
  raise ValueError(
128
- f"参数不足。{self.group_name} 指令组下有如下指令,请参考:\n" + tree
131
+ f"参数不足。{self.group_name} 指令组下有如下指令,请参考:\n" + tree,
129
132
  )
130
133
 
131
134
  return self.startswith(event.message_str)
@@ -1,8 +1,9 @@
1
- from abc import abstractmethod, ABCMeta
1
+ from abc import ABCMeta, abstractmethod
2
2
 
3
- from . import HandlerFilter
4
- from astrbot.core.platform.astr_message_event import AstrMessageEvent
5
3
  from astrbot.core.config import AstrBotConfig
4
+ from astrbot.core.platform.astr_message_event import AstrMessageEvent
5
+
6
+ from . import HandlerFilter
6
7
 
7
8
 
8
9
  class CustomFilterMeta(ABCMeta):
@@ -38,7 +39,7 @@ class CustomFilterOr(CustomFilter):
38
39
  super().__init__()
39
40
  if not isinstance(filter1, (CustomFilter, CustomFilterAnd, CustomFilterOr)):
40
41
  raise ValueError(
41
- "CustomFilter lass can only operate with other CustomFilter."
42
+ "CustomFilter lass can only operate with other CustomFilter.",
42
43
  )
43
44
  self.filter1 = filter1
44
45
  self.filter2 = filter2
@@ -52,7 +53,7 @@ class CustomFilterAnd(CustomFilter):
52
53
  super().__init__()
53
54
  if not isinstance(filter1, (CustomFilter, CustomFilterAnd, CustomFilterOr)):
54
55
  raise ValueError(
55
- "CustomFilter lass can only operate with other CustomFilter."
56
+ "CustomFilter lass can only operate with other CustomFilter.",
56
57
  )
57
58
  self.filter1 = filter1
58
59
  self.filter2 = filter2
@@ -1,9 +1,11 @@
1
1
  import enum
2
- from . import HandlerFilter
3
- from astrbot.core.platform.astr_message_event import AstrMessageEvent
2
+
4
3
  from astrbot.core.config import AstrBotConfig
4
+ from astrbot.core.platform.astr_message_event import AstrMessageEvent
5
5
  from astrbot.core.platform.message_type import MessageType
6
6
 
7
+ from . import HandlerFilter
8
+
7
9
 
8
10
  class EventMessageType(enum.Flag):
9
11
  GROUP_MESSAGE = enum.auto()
@@ -1,7 +1,9 @@
1
1
  import enum
2
- from . import HandlerFilter
3
- from astrbot.core.platform.astr_message_event import AstrMessageEvent
2
+
4
3
  from astrbot.core.config import AstrBotConfig
4
+ from astrbot.core.platform.astr_message_event import AstrMessageEvent
5
+
6
+ from . import HandlerFilter
5
7
 
6
8
 
7
9
  class PermissionType(enum.Flag):
@@ -1,7 +1,9 @@
1
1
  import enum
2
- from . import HandlerFilter
3
- from astrbot.core.platform.astr_message_event import AstrMessageEvent
2
+
4
3
  from astrbot.core.config import AstrBotConfig
4
+ from astrbot.core.platform.astr_message_event import AstrMessageEvent
5
+
6
+ from . import HandlerFilter
5
7
 
6
8
 
7
9
  class PlatformAdapterType(enum.Flag):