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,5 +1,4 @@
1
- """
2
- 插件开发工具集
1
+ """插件开发工具集
3
2
  封装了许多常用的操作,方便插件开发者使用
4
3
 
5
4
  说明:
@@ -21,47 +20,49 @@
21
20
  import inspect
22
21
  import os
23
22
  import uuid
23
+ from collections.abc import Awaitable, Callable
24
24
  from pathlib import Path
25
- from typing import Union, Awaitable, Callable, Any, List, Optional, ClassVar
25
+ from typing import Any, ClassVar
26
+
27
+ from astrbot.api.platform import AstrBotMessage, MessageMember, MessageType
26
28
  from astrbot.core.message.components import BaseMessageComponent
27
29
  from astrbot.core.message.message_event_result import MessageChain
28
- from astrbot.api.platform import MessageMember, AstrBotMessage, MessageType
29
30
  from astrbot.core.platform.astr_message_event import MessageSesion
30
- from astrbot.core.star.context import Context
31
- from astrbot.core.star.star import star_map
32
- from astrbot.core.utils.astrbot_path import get_astrbot_data_path
33
31
  from astrbot.core.platform.sources.aiocqhttp.aiocqhttp_message_event import (
34
32
  AiocqhttpMessageEvent,
35
33
  )
36
34
  from astrbot.core.platform.sources.aiocqhttp.aiocqhttp_platform_adapter import (
37
35
  AiocqhttpAdapter,
38
36
  )
37
+ from astrbot.core.star.context import Context
38
+ from astrbot.core.star.star import star_map
39
+ from astrbot.core.utils.astrbot_path import get_astrbot_data_path
39
40
 
40
41
 
41
42
  class StarTools:
42
- """
43
- 提供给插件使用的便捷工具函数集合
43
+ """提供给插件使用的便捷工具函数集合
44
44
  这些方法封装了一些常用操作,使插件开发更加简单便捷!
45
45
  """
46
46
 
47
- _context: ClassVar[Optional[Context]] = None
47
+ _context: ClassVar[Context | None] = None
48
48
 
49
49
  @classmethod
50
50
  def initialize(cls, context: Context) -> None:
51
- """
52
- 初始化StarTools,设置context引用
51
+ """初始化StarTools,设置context引用
53
52
 
54
53
  Args:
55
54
  context: 暴露给插件的上下文
55
+
56
56
  """
57
57
  cls._context = context
58
58
 
59
59
  @classmethod
60
60
  async def send_message(
61
- cls, session: Union[str, MessageSesion], message_chain: MessageChain
61
+ cls,
62
+ session: str | MessageSesion,
63
+ message_chain: MessageChain,
62
64
  ) -> bool:
63
- """
64
- 根据session(unified_msg_origin)主动发送消息
65
+ """根据session(unified_msg_origin)主动发送消息
65
66
 
66
67
  Args:
67
68
  session: 消息会话。通过event.session或者event.unified_msg_origin获取
@@ -75,6 +76,7 @@ class StarTools:
75
76
 
76
77
  Note:
77
78
  qq_official(QQ官方API平台)不支持此方法
79
+
78
80
  """
79
81
  if cls._context is None:
80
82
  raise ValueError("StarTools not initialized")
@@ -88,21 +90,22 @@ class StarTools:
88
90
  message_chain: MessageChain,
89
91
  platform: str = "aiocqhttp",
90
92
  ):
91
- """
92
- 根据 id(例如qq号, 群号等) 直接, 主动地发送消息
93
+ """根据 id(例如qq号, 群号等) 直接, 主动地发送消息
93
94
 
94
95
  Args:
95
96
  type (str): 消息类型, 可选: PrivateMessage, GroupMessage
96
97
  id (str): 目标ID, 例如QQ号, 群号等
97
98
  message_chain (MessageChain): 消息链
98
99
  platform (str): 可选的平台名称,默认平台(aiocqhttp), 目前只支持 aiocqhttp
100
+
99
101
  """
100
102
  if cls._context is None:
101
103
  raise ValueError("StarTools not initialized")
102
104
  platforms = cls._context.platform_manager.get_insts()
103
105
  if platform == "aiocqhttp":
104
106
  adapter = next(
105
- (p for p in platforms if isinstance(p, AiocqhttpAdapter)), None
107
+ (p for p in platforms if isinstance(p, AiocqhttpAdapter)),
108
+ None,
106
109
  )
107
110
  if adapter is None:
108
111
  raise ValueError("未找到适配器: AiocqhttpAdapter")
@@ -122,14 +125,13 @@ class StarTools:
122
125
  self_id: str,
123
126
  session_id: str,
124
127
  sender: MessageMember,
125
- message: List[BaseMessageComponent],
128
+ message: list[BaseMessageComponent],
126
129
  message_str: str,
127
130
  message_id: str = "",
128
131
  raw_message: object = None,
129
132
  group_id: str = "",
130
133
  ) -> AstrBotMessage:
131
- """
132
- 创建一个AstrBot消息对象
134
+ """创建一个AstrBot消息对象
133
135
 
134
136
  Args:
135
137
  type (str): 消息类型, 例如 "GroupMessage" "FriendMessage" "OtherMessage"
@@ -145,6 +147,7 @@ class StarTools:
145
147
 
146
148
  Returns:
147
149
  AstrBotMessage: 创建的消息对象
150
+
148
151
  """
149
152
  abm = AstrBotMessage()
150
153
  abm.type = MessageType(type)
@@ -162,23 +165,27 @@ class StarTools:
162
165
 
163
166
  @classmethod
164
167
  async def create_event(
165
- cls, abm: AstrBotMessage, platform: str = "aiocqhttp", is_wake: bool = True
168
+ cls,
169
+ abm: AstrBotMessage,
170
+ platform: str = "aiocqhttp",
171
+ is_wake: bool = True,
166
172
  ) -> None:
167
- """
168
- 创建并提交事件到指定平台
173
+ """创建并提交事件到指定平台
169
174
  当有需要创建一个事件, 触发某些处理流程时, 使用该方法
170
175
 
171
176
  Args:
172
177
  abm (AstrBotMessage): 要提交的消息对象, 请先使用 create_message 创建
173
178
  platform (str): 可选的平台名称,默认平台(aiocqhttp), 目前只支持 aiocqhttp
174
179
  is_wake (bool): 是否标记为唤醒事件, 默认为 True, 只有唤醒事件才会被 llm 响应
180
+
175
181
  """
176
182
  if cls._context is None:
177
183
  raise ValueError("StarTools not initialized")
178
184
  platforms = cls._context.platform_manager.get_insts()
179
185
  if platform == "aiocqhttp":
180
186
  adapter = next(
181
- (p for p in platforms if isinstance(p, AiocqhttpAdapter)), None
187
+ (p for p in platforms if isinstance(p, AiocqhttpAdapter)),
188
+ None,
182
189
  )
183
190
  if adapter is None:
184
191
  raise ValueError("未找到适配器: AiocqhttpAdapter")
@@ -196,12 +203,12 @@ class StarTools:
196
203
 
197
204
  @classmethod
198
205
  def activate_llm_tool(cls, name: str) -> bool:
199
- """
200
- 激活一个已经注册的函数调用工具
206
+ """激活一个已经注册的函数调用工具
201
207
  注册的工具默认是激活状态
202
208
 
203
209
  Args:
204
210
  name (str): 工具名称
211
+
205
212
  """
206
213
  if cls._context is None:
207
214
  raise ValueError("StarTools not initialized")
@@ -209,11 +216,11 @@ class StarTools:
209
216
 
210
217
  @classmethod
211
218
  def deactivate_llm_tool(cls, name: str) -> bool:
212
- """
213
- 停用一个已经注册的函数调用工具
219
+ """停用一个已经注册的函数调用工具
214
220
 
215
221
  Args:
216
222
  name (str): 工具名称
223
+
217
224
  """
218
225
  if cls._context is None:
219
226
  raise ValueError("StarTools not initialized")
@@ -227,14 +234,14 @@ class StarTools:
227
234
  desc: str,
228
235
  func_obj: Callable[..., Awaitable[Any]],
229
236
  ) -> None:
230
- """
231
- 为函数调用(function-calling/tools-use)添加工具
237
+ """为函数调用(function-calling/tools-use)添加工具
232
238
 
233
239
  Args:
234
240
  name (str): 工具名称
235
241
  func_args (list): 函数参数列表
236
242
  desc (str): 工具描述
237
243
  func_obj (Awaitable): 函数对象,必须是异步函数
244
+
238
245
  """
239
246
  if cls._context is None:
240
247
  raise ValueError("StarTools not initialized")
@@ -242,21 +249,20 @@ class StarTools:
242
249
 
243
250
  @classmethod
244
251
  def unregister_llm_tool(cls, name: str) -> None:
245
- """
246
- 删除一个函数调用工具
252
+ """删除一个函数调用工具
247
253
  如果再要启用,需要重新注册
248
254
 
249
255
  Args:
250
256
  name (str): 工具名称
257
+
251
258
  """
252
259
  if cls._context is None:
253
260
  raise ValueError("StarTools not initialized")
254
261
  cls._context.unregister_llm_tool(name)
255
262
 
256
263
  @classmethod
257
- def get_data_dir(cls, plugin_name: Optional[str] = None) -> Path:
258
- """
259
- 返回插件数据目录的绝对路径。
264
+ def get_data_dir(cls, plugin_name: str | None = None) -> Path:
265
+ """返回插件数据目录的绝对路径。
260
266
 
261
267
  此方法会在 data/plugin_data 目录下为插件创建一个专属的数据目录。如果未提供插件名称,
262
268
  会自动从调用栈中获取插件信息。
@@ -272,6 +278,7 @@ class StarTools:
272
278
  - 无法获取调用者模块信息
273
279
  - 无法获取模块的元数据信息
274
280
  - 创建目录失败(权限不足或其他IO错误)
281
+
275
282
  """
276
283
  if not plugin_name:
277
284
  frame = inspect.currentframe()
@@ -294,7 +301,7 @@ class StarTools:
294
301
  raise ValueError("无法获取插件名称")
295
302
 
296
303
  data_dir = Path(
297
- os.path.join(get_astrbot_data_path(), "plugin_data", plugin_name)
304
+ os.path.join(get_astrbot_data_path(), "plugin_data", plugin_name),
298
305
  )
299
306
 
300
307
  try:
@@ -1,12 +1,13 @@
1
1
  import os
2
- import zipfile
3
2
  import shutil
3
+ import zipfile
4
4
 
5
- from ..updator import RepoZipUpdator
6
- from astrbot.core.utils.io import remove_dir, on_error
7
- from ..star.star import StarMetadata
8
5
  from astrbot.core import logger
9
6
  from astrbot.core.utils.astrbot_path import get_astrbot_plugin_path
7
+ from astrbot.core.utils.io import on_error, remove_dir
8
+
9
+ from ..star.star import StarMetadata
10
+ from ..updator import RepoZipUpdator
10
11
 
11
12
 
12
13
  class PluginUpdator(RepoZipUpdator):
@@ -44,7 +45,7 @@ class PluginUpdator(RepoZipUpdator):
44
45
  remove_dir(plugin_path)
45
46
  except BaseException as e:
46
47
  logger.error(
47
- f"删除旧版本插件 {plugin_path} 文件夹失败: {str(e)},使用覆盖安装。"
48
+ f"删除旧版本插件 {plugin_path} 文件夹失败: {e!s},使用覆盖安装。",
48
49
  )
49
50
 
50
51
  self.unzip_file(plugin_path + ".zip", plugin_path)
@@ -64,18 +65,17 @@ class PluginUpdator(RepoZipUpdator):
64
65
  if os.path.isdir(os.path.join(target_dir, update_dir, f)):
65
66
  if os.path.exists(os.path.join(target_dir, f)):
66
67
  shutil.rmtree(os.path.join(target_dir, f), onerror=on_error)
67
- else:
68
- if os.path.exists(os.path.join(target_dir, f)):
69
- os.remove(os.path.join(target_dir, f))
68
+ elif os.path.exists(os.path.join(target_dir, f)):
69
+ os.remove(os.path.join(target_dir, f))
70
70
  shutil.move(os.path.join(target_dir, update_dir, f), target_dir)
71
71
 
72
72
  try:
73
73
  logger.info(
74
- f"删除临时文件: {zip_path} 和 {os.path.join(target_dir, update_dir)}"
74
+ f"删除临时文件: {zip_path} 和 {os.path.join(target_dir, update_dir)}",
75
75
  )
76
76
  shutil.rmtree(os.path.join(target_dir, update_dir), onerror=on_error)
77
77
  os.remove(zip_path)
78
78
  except BaseException:
79
79
  logger.warning(
80
- f"删除更新文件失败,可以手动删除 {zip_path} 和 {os.path.join(target_dir, update_dir)}"
80
+ f"删除更新文件失败,可以手动删除 {zip_path} 和 {os.path.join(target_dir, update_dir)}",
81
81
  )
@@ -15,7 +15,10 @@ class UmopConfigRouter:
15
15
  """加载路由表"""
16
16
  # 从 SharedPreferences 中加载 umop_to_conf_id 映射
17
17
  sp_data = self.sp.get(
18
- "umop_config_routing", {}, scope="global", scope_id="global"
18
+ "umop_config_routing",
19
+ {},
20
+ scope="global",
21
+ scope_id="global",
19
22
  )
20
23
  self.umop_to_conf_id = sp_data
21
24
 
@@ -37,6 +40,7 @@ class UmopConfigRouter:
37
40
 
38
41
  Returns:
39
42
  str | None: 配置文件 ID,如果没有找到则返回 None
43
+
40
44
  """
41
45
  for pattern, conf_id in self.umop_to_conf_id.items():
42
46
  if self._is_umo_match(pattern, umo):
@@ -52,11 +56,12 @@ class UmopConfigRouter:
52
56
 
53
57
  Raises:
54
58
  ValueError: 如果 new_routing 中的 key 格式不正确
59
+
55
60
  """
56
- for part in new_routing.keys():
61
+ for part in new_routing:
57
62
  if not isinstance(part, str) or len(part.split(":")) != 3:
58
63
  raise ValueError(
59
- "umop keys must be strings in the format [platform_id]:[message_type]:[session_id], with optional wildcards * or empty for all"
64
+ "umop keys must be strings in the format [platform_id]:[message_type]:[session_id], with optional wildcards * or empty for all",
60
65
  )
61
66
 
62
67
  self.umop_to_conf_id = new_routing
@@ -71,10 +76,11 @@ class UmopConfigRouter:
71
76
 
72
77
  Raises:
73
78
  ValueError: 如果 umo 格式不正确
79
+
74
80
  """
75
81
  if not isinstance(umo, str) or len(umo.split(":")) != 3:
76
82
  raise ValueError(
77
- "umop must be a string in the format [platform_id]:[message_type]:[session_id], with optional wildcards * or empty for all"
83
+ "umop must be a string in the format [platform_id]:[message_type]:[session_id], with optional wildcards * or empty for all",
78
84
  )
79
85
 
80
86
  self.umop_to_conf_id[umo] = conf_id
astrbot/core/updator.py CHANGED
@@ -1,12 +1,15 @@
1
1
  import os
2
- import psutil
3
2
  import sys
4
3
  import time
5
- from .zip_updator import ReleaseInfo, RepoZipUpdator
4
+
5
+ import psutil
6
+
6
7
  from astrbot.core import logger
7
8
  from astrbot.core.config.default import VERSION
8
- from astrbot.core.utils.io import download_file
9
9
  from astrbot.core.utils.astrbot_path import get_astrbot_path
10
+ from astrbot.core.utils.io import download_file
11
+
12
+ from .zip_updator import ReleaseInfo, RepoZipUpdator
10
13
 
11
14
 
12
15
  class AstrBotUpdator(RepoZipUpdator):
@@ -67,11 +70,16 @@ class AstrBotUpdator(RepoZipUpdator):
67
70
  raise e
68
71
 
69
72
  async def check_update(
70
- self, url: str, current_version: str, consider_prerelease: bool = True
73
+ self,
74
+ url: str,
75
+ current_version: str,
76
+ consider_prerelease: bool = True,
71
77
  ) -> ReleaseInfo:
72
78
  """检查更新"""
73
79
  return await super().check_update(
74
- self.ASTRBOT_RELEASE_API, VERSION, consider_prerelease
80
+ self.ASTRBOT_RELEASE_API,
81
+ VERSION,
82
+ consider_prerelease,
75
83
  )
76
84
 
77
85
  async def get_releases(self) -> list:
@@ -1,5 +1,4 @@
1
- """
2
- Astrbot统一路径获取
1
+ """Astrbot统一路径获取
3
2
 
4
3
  项目路径:固定为源码所在路径
5
4
  根目录路径:默认为当前工作目录,可通过环境变量 ASTRBOT_ROOT 指定
@@ -14,7 +13,7 @@ import os
14
13
  def get_astrbot_path() -> str:
15
14
  """获取Astrbot项目路径"""
16
15
  return os.path.realpath(
17
- os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../../")
16
+ os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../../"),
18
17
  )
19
18
 
20
19
 
@@ -22,8 +21,7 @@ def get_astrbot_root() -> str:
22
21
  """获取Astrbot根目录路径"""
23
22
  if path := os.environ.get("ASTRBOT_ROOT"):
24
23
  return os.path.realpath(path)
25
- else:
26
- return os.path.realpath(os.getcwd())
24
+ return os.path.realpath(os.getcwd())
27
25
 
28
26
 
29
27
  def get_astrbot_data_path() -> str:
@@ -1,8 +1,11 @@
1
1
  import codecs
2
2
  import json
3
+ from collections.abc import AsyncGenerator
4
+ from typing import Any
5
+
6
+ from aiohttp import ClientResponse, ClientSession
7
+
3
8
  from astrbot.core import logger
4
- from aiohttp import ClientSession, ClientResponse
5
- from typing import Dict, List, Any, AsyncGenerator
6
9
 
7
10
 
8
11
  async def _stream_sse(resp: ClientResponse) -> AsyncGenerator[dict, None]:
@@ -25,7 +28,6 @@ async def _stream_sse(resp: ClientResponse) -> AsyncGenerator[dict, None]:
25
28
  yield json.loads(buffer[5:])
26
29
  except json.JSONDecodeError:
27
30
  logger.warning(f"Drop invalid dify json data: {buffer[5:]}")
28
- pass
29
31
 
30
32
 
31
33
  class DifyAPIClient:
@@ -39,50 +41,60 @@ class DifyAPIClient:
39
41
 
40
42
  async def chat_messages(
41
43
  self,
42
- inputs: Dict,
44
+ inputs: dict,
43
45
  query: str,
44
46
  user: str,
45
47
  response_mode: str = "streaming",
46
48
  conversation_id: str = "",
47
- files: List[Dict[str, Any]] = [],
49
+ files: list[dict[str, Any]] | None = None,
48
50
  timeout: float = 60,
49
- ) -> AsyncGenerator[Dict[str, Any], None]:
51
+ ) -> AsyncGenerator[dict[str, Any], None]:
52
+ if files is None:
53
+ files = []
50
54
  url = f"{self.api_base}/chat-messages"
51
55
  payload = locals()
52
56
  payload.pop("self")
53
57
  payload.pop("timeout")
54
58
  logger.info(f"chat_messages payload: {payload}")
55
59
  async with self.session.post(
56
- url, json=payload, headers=self.headers, timeout=timeout
60
+ url,
61
+ json=payload,
62
+ headers=self.headers,
63
+ timeout=timeout,
57
64
  ) as resp:
58
65
  if resp.status != 200:
59
66
  text = await resp.text()
60
67
  raise Exception(
61
- f"Dify /chat-messages 接口请求失败:{resp.status}. {text}"
68
+ f"Dify /chat-messages 接口请求失败:{resp.status}. {text}",
62
69
  )
63
70
  async for event in _stream_sse(resp):
64
71
  yield event
65
72
 
66
73
  async def workflow_run(
67
74
  self,
68
- inputs: Dict,
75
+ inputs: dict,
69
76
  user: str,
70
77
  response_mode: str = "streaming",
71
- files: List[Dict[str, Any]] = [],
78
+ files: list[dict[str, Any]] | None = None,
72
79
  timeout: float = 60,
73
80
  ):
81
+ if files is None:
82
+ files = []
74
83
  url = f"{self.api_base}/workflows/run"
75
84
  payload = locals()
76
85
  payload.pop("self")
77
86
  payload.pop("timeout")
78
87
  logger.info(f"workflow_run payload: {payload}")
79
88
  async with self.session.post(
80
- url, json=payload, headers=self.headers, timeout=timeout
89
+ url,
90
+ json=payload,
91
+ headers=self.headers,
92
+ timeout=timeout,
81
93
  ) as resp:
82
94
  if resp.status != 200:
83
95
  text = await resp.text()
84
96
  raise Exception(
85
- f"Dify /workflows/run 接口请求失败:{resp.status}. {text}"
97
+ f"Dify /workflows/run 接口请求失败:{resp.status}. {text}",
86
98
  )
87
99
  async for event in _stream_sse(resp):
88
100
  yield event
@@ -91,7 +103,7 @@ class DifyAPIClient:
91
103
  self,
92
104
  file_path: str,
93
105
  user: str,
94
- ) -> Dict[str, Any]:
106
+ ) -> dict[str, Any]:
95
107
  url = f"{self.api_base}/files/upload"
96
108
  with open(file_path, "rb") as f:
97
109
  payload = {
@@ -99,7 +111,9 @@ class DifyAPIClient:
99
111
  "file": f,
100
112
  }
101
113
  async with self.session.post(
102
- url, data=payload, headers=self.headers
114
+ url,
115
+ data=payload,
116
+ headers=self.headers,
103
117
  ) as resp:
104
118
  return await resp.json() # {"id": "xxx", ...}
105
119
 
@@ -126,7 +140,11 @@ class DifyAPIClient:
126
140
  return await resp.json()
127
141
 
128
142
  async def rename(
129
- self, conversation_id: str, name: str, user: str, auto_generate: bool = False
143
+ self,
144
+ conversation_id: str,
145
+ name: str,
146
+ user: str,
147
+ auto_generate: bool = False,
130
148
  ):
131
149
  # /conversations/:conversation_id/name
132
150
  url = f"{self.api_base}/conversations/{conversation_id}/name"