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,49 +1,56 @@
1
+ import logging
1
2
  from asyncio import Queue
2
- from typing import List, Union
3
+ from collections.abc import Awaitable, Callable
4
+ from typing import Any
3
5
 
4
- from astrbot.core import sp
5
- from astrbot.core.provider.provider import Provider, TTSProvider, STTProvider
6
- from astrbot.core.db import BaseDatabase
6
+ from deprecated import deprecated
7
+
8
+ from astrbot.core.agent.hooks import BaseAgentRunHooks
9
+ from astrbot.core.agent.message import Message
10
+ from astrbot.core.agent.runners.tool_loop_agent_runner import ToolLoopAgentRunner
11
+ from astrbot.core.agent.tool import ToolSet
12
+ from astrbot.core.astrbot_config_mgr import AstrBotConfigManager
7
13
  from astrbot.core.config.astrbot_config import AstrBotConfig
8
- from astrbot.core.provider.func_tool_manager import FuncCall
9
- from astrbot.core.platform.astr_message_event import MessageSesion
14
+ from astrbot.core.conversation_mgr import ConversationManager
15
+ from astrbot.core.db import BaseDatabase
16
+ from astrbot.core.knowledge_base.kb_mgr import KnowledgeBaseManager
10
17
  from astrbot.core.message.message_event_result import MessageChain
11
- from astrbot.core.provider.manager import ProviderManager
18
+ from astrbot.core.persona_mgr import PersonaManager
12
19
  from astrbot.core.platform import Platform
20
+ from astrbot.core.platform.astr_message_event import AstrMessageEvent, MessageSesion
13
21
  from astrbot.core.platform.manager import PlatformManager
14
- from .star import star_registry, StarMetadata, star_map
15
- from .star_handler import star_handlers_registry, StarHandlerMetadata, EventType
16
- from .filter.command import CommandFilter
17
- from .filter.regex import RegexFilter
18
- from typing import Awaitable
19
- from astrbot.core.rag.knowledge_db_mgr import KnowledgeDBManager
20
- from astrbot.core.conversation_mgr import ConversationManager
22
+ from astrbot.core.platform_message_history_mgr import PlatformMessageHistoryManager
23
+ from astrbot.core.provider.entities import LLMResponse, ProviderRequest, ProviderType
24
+ from astrbot.core.provider.func_tool_manager import FunctionTool, FunctionToolManager
25
+ from astrbot.core.provider.manager import ProviderManager
26
+ from astrbot.core.provider.provider import (
27
+ EmbeddingProvider,
28
+ Provider,
29
+ RerankProvider,
30
+ STTProvider,
31
+ TTSProvider,
32
+ )
21
33
  from astrbot.core.star.filter.platform_adapter_type import (
22
- PlatformAdapterType,
23
34
  ADAPTER_NAME_2_TYPE,
35
+ PlatformAdapterType,
24
36
  )
25
37
 
38
+ from ..exceptions import ProviderNotFoundError
39
+ from .filter.command import CommandFilter
40
+ from .filter.regex import RegexFilter
41
+ from .star import StarMetadata, star_map, star_registry
42
+ from .star_handler import EventType, StarHandlerMetadata, star_handlers_registry
26
43
 
27
- class Context:
28
- """
29
- 暴露给插件的接口上下文。
30
- """
31
-
32
- _event_queue: Queue = None
33
- """事件队列。消息平台通过事件队列传递消息事件。"""
34
-
35
- _config: AstrBotConfig = None
36
- """AstrBot 配置信息"""
44
+ logger = logging.getLogger("astrbot")
37
45
 
38
- _db: BaseDatabase = None
39
- """AstrBot 数据库"""
40
46
 
41
- provider_manager: ProviderManager = None
47
+ class Context:
48
+ """暴露给插件的接口上下文。"""
42
49
 
43
- platform_manager: PlatformManager = None
50
+ registered_web_apis: list = []
44
51
 
45
52
  # back compatibility
46
- _register_tasks: List[Awaitable] = []
53
+ _register_tasks: list[Awaitable] = []
47
54
  _star_manager = None
48
55
 
49
56
  def __init__(
@@ -51,30 +58,186 @@ class Context:
51
58
  event_queue: Queue,
52
59
  config: AstrBotConfig,
53
60
  db: BaseDatabase,
54
- provider_manager: ProviderManager = None,
55
- platform_manager: PlatformManager = None,
56
- conversation_manager: ConversationManager = None,
57
- knowledge_db_manager: KnowledgeDBManager = None,
61
+ provider_manager: ProviderManager,
62
+ platform_manager: PlatformManager,
63
+ conversation_manager: ConversationManager,
64
+ message_history_manager: PlatformMessageHistoryManager,
65
+ persona_manager: PersonaManager,
66
+ astrbot_config_mgr: AstrBotConfigManager,
67
+ knowledge_base_manager: KnowledgeBaseManager,
58
68
  ):
59
69
  self._event_queue = event_queue
70
+ """事件队列。消息平台通过事件队列传递消息事件。"""
60
71
  self._config = config
72
+ """AstrBot 默认配置"""
61
73
  self._db = db
74
+ """AstrBot 数据库"""
62
75
  self.provider_manager = provider_manager
63
76
  self.platform_manager = platform_manager
64
- self.knowledge_db_manager = knowledge_db_manager
65
77
  self.conversation_manager = conversation_manager
78
+ self.message_history_manager = message_history_manager
79
+ self.persona_manager = persona_manager
80
+ self.astrbot_config_mgr = astrbot_config_mgr
81
+ self.kb_manager = knowledge_base_manager
82
+
83
+ async def llm_generate(
84
+ self,
85
+ *,
86
+ chat_provider_id: str,
87
+ prompt: str | None = None,
88
+ image_urls: list[str] | None = None,
89
+ tools: ToolSet | None = None,
90
+ system_prompt: str | None = None,
91
+ contexts: list[Message] | None = None,
92
+ **kwargs: Any,
93
+ ) -> LLMResponse:
94
+ """Call the LLM to generate a response. The method will not automatically execute tool calls. If you want to use tool calls, please use `tool_loop_agent()`.
95
+
96
+ .. versionadded:: 4.5.7 (sdk)
97
+
98
+ Args:
99
+ chat_provider_id: The chat provider ID to use.
100
+ prompt: The prompt to send to the LLM, if `contexts` and `prompt` are both provided, `prompt` will be appended as the last user message
101
+ image_urls: List of image URLs to include in the prompt, if `contexts` and `prompt` are both provided, `image_urls` will be appended to the last user message
102
+ tools: ToolSet of tools available to the LLM
103
+ system_prompt: System prompt to guide the LLM's behavior, if provided, it will always insert as the first system message in the context
104
+ contexts: context messages for the LLM
105
+ **kwargs: Additional keyword arguments for LLM generation, OpenAI compatible
106
+
107
+ Raises:
108
+ ChatProviderNotFoundError: If the specified chat provider ID is not found
109
+ Exception: For other errors during LLM generation
110
+ """
111
+ prov = await self.provider_manager.get_provider_by_id(chat_provider_id)
112
+ if not prov or not isinstance(prov, Provider):
113
+ raise ProviderNotFoundError(f"Provider {chat_provider_id} not found")
114
+ llm_resp = await prov.text_chat(
115
+ prompt=prompt,
116
+ image_urls=image_urls,
117
+ func_tool=tools,
118
+ contexts=contexts,
119
+ system_prompt=system_prompt,
120
+ **kwargs,
121
+ )
122
+ return llm_resp
123
+
124
+ async def tool_loop_agent(
125
+ self,
126
+ *,
127
+ event: AstrMessageEvent,
128
+ chat_provider_id: str,
129
+ prompt: str | None = None,
130
+ image_urls: list[str] | None = None,
131
+ tools: ToolSet | None = None,
132
+ system_prompt: str | None = None,
133
+ contexts: list[Message] | None = None,
134
+ max_steps: int = 30,
135
+ tool_call_timeout: int = 60,
136
+ **kwargs: Any,
137
+ ) -> LLMResponse:
138
+ """Run an agent loop that allows the LLM to call tools iteratively until a final answer is produced.
139
+ If you do not pass the agent_context parameter, the method will recreate a new agent context.
140
+
141
+ .. versionadded:: 4.5.7 (sdk)
142
+
143
+ Args:
144
+ chat_provider_id: The chat provider ID to use.
145
+ prompt: The prompt to send to the LLM, if `contexts` and `prompt` are both provided, `prompt` will be appended as the last user message
146
+ image_urls: List of image URLs to include in the prompt, if `contexts` and `prompt` are both provided, `image_urls` will be appended to the last user message
147
+ tools: ToolSet of tools available to the LLM
148
+ system_prompt: System prompt to guide the LLM's behavior, if provided, it will always insert as the first system message in the context
149
+ contexts: context messages for the LLM
150
+ max_steps: Maximum number of tool calls before stopping the loop
151
+ **kwargs: Additional keyword arguments. The kwargs will not be passed to the LLM directly for now, but can include:
152
+ agent_hooks: BaseAgentRunHooks[AstrAgentContext] - hooks to run during agent execution
153
+ agent_context: AstrAgentContext - context to use for the agent
154
+
155
+ Returns:
156
+ The final LLMResponse after tool calls are completed.
157
+
158
+ Raises:
159
+ ChatProviderNotFoundError: If the specified chat provider ID is not found
160
+ Exception: For other errors during LLM generation
161
+ """
162
+ # Import here to avoid circular imports
163
+ from astrbot.core.astr_agent_context import (
164
+ AgentContextWrapper,
165
+ AstrAgentContext,
166
+ )
167
+ from astrbot.core.astr_agent_tool_exec import FunctionToolExecutor
66
168
 
67
- def get_registered_star(self, star_name: str) -> StarMetadata:
169
+ prov = await self.provider_manager.get_provider_by_id(chat_provider_id)
170
+ if not prov or not isinstance(prov, Provider):
171
+ raise ProviderNotFoundError(f"Provider {chat_provider_id} not found")
172
+
173
+ agent_hooks = kwargs.get("agent_hooks") or BaseAgentRunHooks[AstrAgentContext]()
174
+ agent_context = kwargs.get("agent_context")
175
+
176
+ context_ = []
177
+ for msg in contexts or []:
178
+ if isinstance(msg, Message):
179
+ context_.append(msg.model_dump())
180
+ else:
181
+ context_.append(msg)
182
+
183
+ request = ProviderRequest(
184
+ prompt=prompt,
185
+ image_urls=image_urls or [],
186
+ func_tool=tools,
187
+ contexts=context_,
188
+ system_prompt=system_prompt or "",
189
+ )
190
+ if agent_context is None:
191
+ agent_context = AstrAgentContext(
192
+ context=self,
193
+ event=event,
194
+ )
195
+ agent_runner = ToolLoopAgentRunner()
196
+ tool_executor = FunctionToolExecutor()
197
+ await agent_runner.reset(
198
+ provider=prov,
199
+ request=request,
200
+ run_context=AgentContextWrapper(
201
+ context=agent_context,
202
+ tool_call_timeout=tool_call_timeout,
203
+ ),
204
+ tool_executor=tool_executor,
205
+ agent_hooks=agent_hooks,
206
+ streaming=kwargs.get("stream", False),
207
+ )
208
+ async for _ in agent_runner.step_until_done(max_steps):
209
+ pass
210
+ llm_resp = agent_runner.get_final_llm_resp()
211
+ if not llm_resp:
212
+ raise Exception("Agent did not produce a final LLM response")
213
+ return llm_resp
214
+
215
+ async def get_current_chat_provider_id(self, umo: str) -> str:
216
+ """Get the ID of the currently used chat provider.
217
+
218
+ Args:
219
+ umo(str): unified_message_origin value, if provided and user has enabled provider session isolation, the provider preferred by that session will be used.
220
+
221
+ Raises:
222
+ ProviderNotFoundError: If the specified chat provider is not found
223
+
224
+ """
225
+ prov = self.get_using_provider(umo)
226
+ if not prov:
227
+ raise ProviderNotFoundError("Provider not found")
228
+ return prov.meta().id
229
+
230
+ def get_registered_star(self, star_name: str) -> StarMetadata | None:
68
231
  """根据插件名获取插件的 Metadata"""
69
232
  for star in star_registry:
70
233
  if star.name == star_name:
71
234
  return star
72
235
 
73
- def get_all_stars(self) -> List[StarMetadata]:
236
+ def get_all_stars(self) -> list[StarMetadata]:
74
237
  """获取当前载入的所有插件 Metadata 的列表"""
75
238
  return star_registry
76
239
 
77
- def get_llm_tool_manager(self) -> FuncCall:
240
+ def get_llm_tool_manager(self) -> FunctionToolManager:
78
241
  """获取 LLM Tool Manager,其用于管理注册的所有的 Function-calling tools"""
79
242
  return self.provider_manager.llm_tools
80
243
 
@@ -83,122 +246,103 @@ class Context:
83
246
 
84
247
  Returns:
85
248
  如果没找到,会返回 False
249
+
86
250
  """
87
- func_tool = self.provider_manager.llm_tools.get_func(name)
88
- if func_tool is not None:
89
- if func_tool.handler_module_path in star_map:
90
- if not star_map[func_tool.handler_module_path].activated:
91
- raise ValueError(
92
- f"此函数调用工具所属的插件 {star_map[func_tool.handler_module_path].name} 已被禁用,请先在管理面板启用再激活此工具。"
93
- )
94
-
95
- func_tool.active = True
96
-
97
- inactivated_llm_tools: list = sp.get("inactivated_llm_tools", [])
98
- if name in inactivated_llm_tools:
99
- inactivated_llm_tools.remove(name)
100
- sp.put("inactivated_llm_tools", inactivated_llm_tools)
101
-
102
- return True
103
- return False
251
+ return self.provider_manager.llm_tools.activate_llm_tool(name, star_map)
104
252
 
105
253
  def deactivate_llm_tool(self, name: str) -> bool:
106
254
  """停用一个已经注册的函数调用工具。
107
255
 
108
256
  Returns:
109
- 如果没找到,会返回 False"""
110
- func_tool = self.provider_manager.llm_tools.get_func(name)
111
- if func_tool is not None:
112
- func_tool.active = False
113
-
114
- inactivated_llm_tools: list = sp.get("inactivated_llm_tools", [])
115
- if name not in inactivated_llm_tools:
116
- inactivated_llm_tools.append(name)
117
- sp.put("inactivated_llm_tools", inactivated_llm_tools)
118
-
119
- return True
120
- return False
257
+ 如果没找到,会返回 False
121
258
 
122
- def register_provider(self, provider: Provider):
123
- """
124
- 注册一个 LLM Provider(Chat_Completion 类型)。
125
259
  """
126
- self.provider_manager.provider_insts.append(provider)
260
+ return self.provider_manager.llm_tools.deactivate_llm_tool(name)
127
261
 
128
- def get_provider_by_id(self, provider_id: str) -> Provider:
129
- """通过 ID 获取用于文本生成任务的 LLM Provider(Chat_Completion 类型)。"""
130
- for provider in self.provider_manager.provider_insts:
131
- if provider.meta().id == provider_id:
132
- return provider
133
- return None
262
+ def get_provider_by_id(
263
+ self,
264
+ provider_id: str,
265
+ ) -> (
266
+ Provider | TTSProvider | STTProvider | EmbeddingProvider | RerankProvider | None
267
+ ):
268
+ """通过 ID 获取对应的 LLM Provider。"""
269
+ prov = self.provider_manager.inst_map.get(provider_id)
270
+ return prov
134
271
 
135
- def get_all_providers(self) -> List[Provider]:
272
+ def get_all_providers(self) -> list[Provider]:
136
273
  """获取所有用于文本生成任务的 LLM Provider(Chat_Completion 类型)。"""
137
274
  return self.provider_manager.provider_insts
138
275
 
139
- def get_all_tts_providers(self) -> List[TTSProvider]:
276
+ def get_all_tts_providers(self) -> list[TTSProvider]:
140
277
  """获取所有用于 TTS 任务的 Provider。"""
141
278
  return self.provider_manager.tts_provider_insts
142
279
 
143
- def get_all_stt_providers(self) -> List[STTProvider]:
280
+ def get_all_stt_providers(self) -> list[STTProvider]:
144
281
  """获取所有用于 STT 任务的 Provider。"""
145
282
  return self.provider_manager.stt_provider_insts
146
283
 
147
- def get_using_provider(self) -> Provider:
148
- """
149
- 获取当前使用的用于文本生成任务的 LLM Provider(Chat_Completion 类型)。
284
+ def get_all_embedding_providers(self) -> list[EmbeddingProvider]:
285
+ """获取所有用于 Embedding 任务的 Provider。"""
286
+ return self.provider_manager.embedding_provider_insts
150
287
 
151
- 通过 /provider 指令切换。
152
- """
153
- return self.provider_manager.curr_provider_inst
288
+ def get_using_provider(self, umo: str | None = None) -> Provider | None:
289
+ """获取当前使用的用于文本生成任务的 LLM Provider(Chat_Completion 类型)。通过 /provider 指令切换。
154
290
 
155
- def get_using_tts_provider(self) -> TTSProvider:
156
- """
157
- 获取当前使用的用于 TTS 任务的 Provider。
158
- """
159
- return self.provider_manager.curr_tts_provider_inst
291
+ Args:
292
+ umo(str): unified_message_origin 值,如果传入并且用户启用了提供商会话隔离,则使用该会话偏好的提供商。
160
293
 
161
- def get_using_stt_provider(self) -> STTProvider:
162
- """
163
- 获取当前使用的用于 STT 任务的 Provider。
164
294
  """
165
- return self.provider_manager.curr_stt_provider_inst
295
+ prov = self.provider_manager.get_using_provider(
296
+ provider_type=ProviderType.CHAT_COMPLETION,
297
+ umo=umo,
298
+ )
299
+ if prov and not isinstance(prov, Provider):
300
+ raise ValueError("返回的 Provider 不是 Provider 类型")
301
+ return prov
166
302
 
167
- def get_config(self) -> AstrBotConfig:
168
- """获取 AstrBot 的配置。"""
169
- return self._config
303
+ def get_using_tts_provider(self, umo: str | None = None) -> TTSProvider | None:
304
+ """获取当前使用的用于 TTS 任务的 Provider。
170
305
 
171
- def get_db(self) -> BaseDatabase:
172
- """获取 AstrBot 数据库。"""
173
- return self._db
306
+ Args:
307
+ umo(str): unified_message_origin 值,如果传入,则使用该会话偏好的提供商。
174
308
 
175
- def get_event_queue(self) -> Queue:
176
- """
177
- 获取事件队列。
178
309
  """
179
- return self._event_queue
310
+ prov = self.provider_manager.get_using_provider(
311
+ provider_type=ProviderType.TEXT_TO_SPEECH,
312
+ umo=umo,
313
+ )
314
+ if prov and not isinstance(prov, TTSProvider):
315
+ raise ValueError("返回的 Provider 不是 TTSProvider 类型")
316
+ return prov
317
+
318
+ def get_using_stt_provider(self, umo: str | None = None) -> STTProvider | None:
319
+ """获取当前使用的用于 STT 任务的 Provider。
320
+
321
+ Args:
322
+ umo(str): unified_message_origin 值,如果传入,则使用该会话偏好的提供商。
180
323
 
181
- def get_platform(self, platform_type: Union[PlatformAdapterType, str]) -> Platform:
182
- """
183
- 获取指定类型的平台适配器。
184
324
  """
185
- for platform in self.platform_manager.platform_insts:
186
- name = platform.meta().name
187
- if isinstance(platform_type, str):
188
- if name == platform_type:
189
- return platform
190
- else:
191
- if (
192
- name in ADAPTER_NAME_2_TYPE
193
- and ADAPTER_NAME_2_TYPE[name] & platform_type
194
- ):
195
- return platform
325
+ prov = self.provider_manager.get_using_provider(
326
+ provider_type=ProviderType.SPEECH_TO_TEXT,
327
+ umo=umo,
328
+ )
329
+ if prov and not isinstance(prov, STTProvider):
330
+ raise ValueError("返回的 Provider 不是 STTProvider 类型")
331
+ return prov
332
+
333
+ def get_config(self, umo: str | None = None) -> AstrBotConfig:
334
+ """获取 AstrBot 的配置。"""
335
+ if not umo:
336
+ # using default config
337
+ return self._config
338
+ return self.astrbot_config_mgr.get_conf(umo)
196
339
 
197
340
  async def send_message(
198
- self, session: Union[str, MessageSesion], message_chain: MessageChain
341
+ self,
342
+ session: str | MessageSesion,
343
+ message_chain: MessageChain,
199
344
  ) -> bool:
200
- """
201
- 根据 session(unified_msg_origin) 主动发送消息。
345
+ """根据 session(unified_msg_origin) 主动发送消息。
202
346
 
203
347
  @param session: 消息会话。通过 event.session 或者 event.unified_msg_origin 获取。
204
348
  @param message_chain: 消息链。
@@ -209,7 +353,6 @@ class Context:
209
353
 
210
354
  NOTE: qq_official(QQ 官方 API 平台) 不支持此方法
211
355
  """
212
-
213
356
  if isinstance(session, str):
214
357
  try:
215
358
  session = MessageSesion.from_str(session)
@@ -217,20 +360,106 @@ class Context:
217
360
  raise ValueError("不合法的 session 字符串: " + str(e))
218
361
 
219
362
  for platform in self.platform_manager.platform_insts:
220
- if platform.meta().name == session.platform_name:
363
+ if platform.meta().id == session.platform_name:
221
364
  await platform.send_by_session(session, message_chain)
222
365
  return True
223
366
  return False
224
367
 
368
+ def add_llm_tools(self, *tools: FunctionTool) -> None:
369
+ """添加 LLM 工具。"""
370
+ tool_name = {tool.name for tool in self.provider_manager.llm_tools.func_list}
371
+ module_path = ""
372
+ for tool in tools:
373
+ if not module_path:
374
+ _parts = []
375
+ module_part = tool.__module__.split(".")
376
+ flags = ["packages", "plugins"]
377
+ for i, part in enumerate(module_part):
378
+ _parts.append(part)
379
+ if part in flags and i + 1 < len(module_part):
380
+ _parts.append(module_part[i + 1])
381
+ break
382
+ tool.handler_module_path = ".".join(_parts)
383
+ module_path = tool.handler_module_path
384
+ else:
385
+ tool.handler_module_path = module_path
386
+ logger.info(
387
+ f"plugin(module_path {module_path}) added LLM tool: {tool.name}"
388
+ )
389
+
390
+ if tool.name in tool_name:
391
+ logger.warning("替换已存在的 LLM 工具: " + tool.name)
392
+ self.provider_manager.llm_tools.remove_func(tool.name)
393
+ self.provider_manager.llm_tools.func_list.append(tool)
394
+
395
+ def register_web_api(
396
+ self,
397
+ route: str,
398
+ view_handler: Awaitable,
399
+ methods: list,
400
+ desc: str,
401
+ ):
402
+ for idx, api in enumerate(self.registered_web_apis):
403
+ if api[0] == route and methods == api[2]:
404
+ self.registered_web_apis[idx] = (route, view_handler, methods, desc)
405
+ return
406
+ self.registered_web_apis.append((route, view_handler, methods, desc))
407
+
225
408
  """
226
409
  以下的方法已经不推荐使用。请从 AstrBot 文档查看更好的注册方式。
227
410
  """
228
411
 
412
+ def get_event_queue(self) -> Queue:
413
+ """获取事件队列。"""
414
+ return self._event_queue
415
+
416
+ @deprecated(version="4.0.0", reason="Use get_platform_inst instead")
417
+ def get_platform(self, platform_type: PlatformAdapterType | str) -> Platform | None:
418
+ """获取指定类型的平台适配器。
419
+
420
+ 该方法已经过时,请使用 get_platform_inst 方法。(>= AstrBot v4.0.0)
421
+ """
422
+ for platform in self.platform_manager.platform_insts:
423
+ name = platform.meta().name
424
+ if isinstance(platform_type, str):
425
+ if name == platform_type:
426
+ return platform
427
+ elif (
428
+ name in ADAPTER_NAME_2_TYPE
429
+ and ADAPTER_NAME_2_TYPE[name] & platform_type
430
+ ):
431
+ return platform
432
+
433
+ def get_platform_inst(self, platform_id: str) -> Platform | None:
434
+ """获取指定 ID 的平台适配器实例。
435
+
436
+ Args:
437
+ platform_id (str): 平台适配器的唯一标识符。你可以通过 event.get_platform_id() 获取。
438
+
439
+ Returns:
440
+ Platform: 平台适配器实例,如果未找到则返回 None。
441
+
442
+ """
443
+ for platform in self.platform_manager.platform_insts:
444
+ if platform.meta().id == platform_id:
445
+ return platform
446
+
447
+ def get_db(self) -> BaseDatabase:
448
+ """获取 AstrBot 数据库。"""
449
+ return self._db
450
+
451
+ def register_provider(self, provider: Provider):
452
+ """注册一个 LLM Provider(Chat_Completion 类型)。"""
453
+ self.provider_manager.provider_insts.append(provider)
454
+
229
455
  def register_llm_tool(
230
- self, name: str, func_args: list, desc: str, func_obj: Awaitable
456
+ self,
457
+ name: str,
458
+ func_args: list,
459
+ desc: str,
460
+ func_obj: Callable[..., Awaitable[Any]],
231
461
  ) -> None:
232
- """
233
- 为函数调用(function-calling / tools-use)添加工具。
462
+ """[DEPRECATED]为函数调用(function-calling / tools-use)添加工具。
234
463
 
235
464
  @param name: 函数名
236
465
  @param func_args: 函数参数列表,格式为 [{"type": "string", "name": "arg_name", "description": "arg_description"}, ...]
@@ -249,12 +478,10 @@ class Context:
249
478
  desc=desc,
250
479
  )
251
480
  star_handlers_registry.append(md)
252
- self.provider_manager.llm_tools.add_func(
253
- name, func_args, desc, func_obj, func_obj
254
- )
481
+ self.provider_manager.llm_tools.add_func(name, func_args, desc, func_obj)
255
482
 
256
483
  def unregister_llm_tool(self, name: str) -> None:
257
- """删除一个函数调用工具。如果再要启用,需要重新注册。"""
484
+ """[DEPRECATED]删除一个函数调用工具。如果再要启用,需要重新注册。"""
258
485
  self.provider_manager.llm_tools.remove_func(name)
259
486
 
260
487
  def register_commands(
@@ -263,12 +490,11 @@ class Context:
263
490
  command_name: str,
264
491
  desc: str,
265
492
  priority: int,
266
- awaitable: Awaitable,
493
+ awaitable: Callable[..., Awaitable[Any]],
267
494
  use_regex=False,
268
495
  ignore_prefix=False,
269
496
  ):
270
- """
271
- 注册一个命令。
497
+ """注册一个命令。
272
498
 
273
499
  [Deprecated] 推荐使用装饰器注册指令。该方法将在未来的版本中被移除。
274
500
 
@@ -292,12 +518,10 @@ class Context:
292
518
  md.event_filters.append(RegexFilter(regex=command_name))
293
519
  else:
294
520
  md.event_filters.append(
295
- CommandFilter(command_name=command_name, handler_md=md)
521
+ CommandFilter(command_name=command_name, handler_md=md),
296
522
  )
297
523
  star_handlers_registry.append(md)
298
524
 
299
525
  def register_task(self, task: Awaitable, desc: str):
300
- """
301
- 注册一个异步任务。
302
- """
526
+ """[DEPRECATED]注册一个异步任务。"""
303
527
  self._register_tasks.append(task)
@@ -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"]