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,74 +1,60 @@
1
- import enum
2
1
  import base64
2
+ import enum
3
3
  import json
4
- from astrbot.core.utils.io import download_image_by_url
5
- from astrbot import logger
6
4
  from dataclasses import dataclass, field
7
- from typing import List, Dict, Type
8
- from .func_tool_manager import FuncCall
5
+ from typing import Any
6
+
7
+ from anthropic.types import Message as AnthropicMessage
8
+ from google.genai.types import GenerateContentResponse
9
9
  from openai.types.chat.chat_completion import ChatCompletion
10
- from openai.types.chat.chat_completion_message_tool_call import (
11
- ChatCompletionMessageToolCall,
10
+
11
+ import astrbot.core.message.components as Comp
12
+ from astrbot import logger
13
+ from astrbot.core.agent.message import (
14
+ AssistantMessageSegment,
15
+ ToolCall,
16
+ ToolCallMessageSegment,
12
17
  )
18
+ from astrbot.core.agent.tool import ToolSet
13
19
  from astrbot.core.db.po import Conversation
14
20
  from astrbot.core.message.message_event_result import MessageChain
15
- import astrbot.core.message.components as Comp
21
+ from astrbot.core.utils.io import download_image_by_url
16
22
 
17
23
 
18
24
  class ProviderType(enum.Enum):
19
25
  CHAT_COMPLETION = "chat_completion"
20
26
  SPEECH_TO_TEXT = "speech_to_text"
21
27
  TEXT_TO_SPEECH = "text_to_speech"
28
+ EMBEDDING = "embedding"
29
+ RERANK = "rerank"
22
30
 
23
31
 
24
32
  @dataclass
25
- class ProviderMetaData:
33
+ class ProviderMeta:
34
+ """The basic metadata of a provider instance."""
35
+
36
+ id: str
37
+ """the unique id of the provider instance that user configured"""
38
+ model: str | None
39
+ """the model name of the provider instance currently used"""
26
40
  type: str
27
- """提供商适配器名称,如 openai, ollama"""
28
- desc: str = ""
29
- """提供商适配器描述."""
41
+ """the name of the provider adapter, such as openai, ollama"""
30
42
  provider_type: ProviderType = ProviderType.CHAT_COMPLETION
31
- cls_type: Type = None
32
-
33
- default_config_tmpl: dict = None
34
- """平台的默认配置模板"""
35
- provider_display_name: str = None
36
- """显示在 WebUI 配置页中的提供商名称,如空则是 type"""
43
+ """the capability type of the provider adapter"""
37
44
 
38
45
 
39
46
  @dataclass
40
- class ToolCallMessageSegment:
41
- """OpenAI 格式的上下文中 role tool 的消息段。参考: https://platform.openai.com/docs/guides/function-calling"""
42
-
43
- tool_call_id: str
44
- content: str
45
- role: str = "tool"
47
+ class ProviderMetaData(ProviderMeta):
48
+ """The metadata of a provider adapter for registration."""
46
49
 
47
- def to_dict(self):
48
- return {
49
- "tool_call_id": self.tool_call_id,
50
- "content": self.content,
51
- "role": self.role,
52
- }
53
-
54
-
55
- @dataclass
56
- class AssistantMessageSegment:
57
- """OpenAI 格式的上下文中 role 为 assistant 的消息段。参考: https://platform.openai.com/docs/guides/function-calling"""
58
-
59
- content: str = None
60
- tool_calls: List[ChatCompletionMessageToolCall | Dict] = None
61
- role: str = "assistant"
62
-
63
- def to_dict(self):
64
- ret = {
65
- "role": self.role,
66
- }
67
- if self.content:
68
- ret["content"] = self.content
69
- elif self.tool_calls:
70
- ret["tool_calls"] = self.tool_calls
71
- return ret
50
+ desc: str = ""
51
+ """the short description of the provider adapter"""
52
+ cls_type: Any = None
53
+ """the class type of the provider adapter"""
54
+ default_config_tmpl: dict | None = None
55
+ """the default configuration template of the provider adapter"""
56
+ provider_display_name: str | None = None
57
+ """the display name of the provider shown in the WebUI configuration page; if empty, the type is used"""
72
58
 
73
59
 
74
60
  @dataclass
@@ -77,44 +63,70 @@ class ToolCallsResult:
77
63
 
78
64
  tool_calls_info: AssistantMessageSegment
79
65
  """函数调用的信息"""
80
- tool_calls_result: List[ToolCallMessageSegment]
66
+ tool_calls_result: list[ToolCallMessageSegment]
81
67
  """函数调用的结果"""
82
68
 
83
- def to_openai_messages(self) -> List[Dict]:
69
+ def to_openai_messages(self) -> list[dict]:
84
70
  ret = [
85
- self.tool_calls_info.to_dict(),
86
- *[item.to_dict() for item in self.tool_calls_result],
71
+ self.tool_calls_info.model_dump(),
72
+ *[item.model_dump() for item in self.tool_calls_result],
87
73
  ]
88
74
  return ret
89
75
 
76
+ def to_openai_messages_model(
77
+ self,
78
+ ) -> list[AssistantMessageSegment | ToolCallMessageSegment]:
79
+ return [
80
+ self.tool_calls_info,
81
+ *self.tool_calls_result,
82
+ ]
83
+
90
84
 
91
85
  @dataclass
92
86
  class ProviderRequest:
93
- prompt: str
87
+ prompt: str | None = None
94
88
  """提示词"""
95
- session_id: str = ""
89
+ session_id: str | None = ""
96
90
  """会话 ID"""
97
- image_urls: List[str] = None
91
+ image_urls: list[str] = field(default_factory=list)
98
92
  """图片 URL 列表"""
99
- func_tool: FuncCall = None
93
+ func_tool: ToolSet | None = None
100
94
  """可用的函数工具"""
101
- contexts: List = None
102
- """上下文。格式与 openai 的上下文格式一致:
95
+ contexts: list[dict] = field(default_factory=list)
96
+ """
97
+ OpenAI 格式上下文列表。
103
98
  参考 https://platform.openai.com/docs/api-reference/chat/create#chat-create-messages
104
99
  """
105
100
  system_prompt: str = ""
106
101
  """系统提示词"""
107
- conversation: Conversation = None
108
-
109
- tool_calls_result: ToolCallsResult = None
102
+ conversation: Conversation | None = None
103
+ """关联的对话对象"""
104
+ tool_calls_result: list[ToolCallsResult] | ToolCallsResult | None = None
110
105
  """附加的上次请求后工具调用的结果。参考: https://platform.openai.com/docs/guides/function-calling#handling-function-calls"""
106
+ model: str | None = None
107
+ """模型名称,为 None 时使用提供商的默认模型"""
111
108
 
112
109
  def __repr__(self):
113
- return f"ProviderRequest(prompt={self.prompt}, session_id={self.session_id}, image_urls={self.image_urls}, func_tool={self.func_tool}, contexts={self._print_friendly_context()}, system_prompt={self.system_prompt.strip()}, tool_calls_result={self.tool_calls_result})"
110
+ return (
111
+ f"ProviderRequest(prompt={self.prompt}, session_id={self.session_id}, "
112
+ f"image_count={len(self.image_urls or [])}, "
113
+ f"func_tool={self.func_tool}, "
114
+ f"contexts={self._print_friendly_context()}, "
115
+ f"system_prompt={self.system_prompt}, "
116
+ f"conversation_id={self.conversation.cid if self.conversation else 'N/A'}, "
117
+ )
114
118
 
115
119
  def __str__(self):
116
120
  return self.__repr__()
117
121
 
122
+ def append_tool_calls_result(self, tool_calls_result: ToolCallsResult):
123
+ """添加工具调用结果到请求中"""
124
+ if not self.tool_calls_result:
125
+ self.tool_calls_result = []
126
+ if isinstance(self.tool_calls_result, ToolCallsResult):
127
+ self.tool_calls_result = [self.tool_calls_result]
128
+ self.tool_calls_result.append(tool_calls_result)
129
+
118
130
  def _print_friendly_context(self):
119
131
  """打印友好的消息上下文。将 image_url 的值替换为 <Image>"""
120
132
  if not self.contexts:
@@ -150,12 +162,14 @@ class ProviderRequest:
150
162
 
151
163
  return result_parts
152
164
 
153
- async def assemble_context(self) -> Dict:
165
+ async def assemble_context(self) -> dict:
154
166
  """将请求(prompt 和 image_urls)包装成 OpenAI 的消息格式。"""
155
167
  if self.image_urls:
156
168
  user_content = {
157
169
  "role": "user",
158
- "content": [{"type": "text", "text": self.prompt if self.prompt else "[图片]"}],
170
+ "content": [
171
+ {"type": "text", "text": self.prompt if self.prompt else "[图片]"},
172
+ ],
159
173
  }
160
174
  for image_url in self.image_urls:
161
175
  if image_url.startswith("http"):
@@ -170,11 +184,10 @@ class ProviderRequest:
170
184
  logger.warning(f"图片 {image_url} 得到的结果为空,将忽略。")
171
185
  continue
172
186
  user_content["content"].append(
173
- {"type": "image_url", "image_url": {"url": image_data}}
187
+ {"type": "image_url", "image_url": {"url": image_data}},
174
188
  )
175
189
  return user_content
176
- else:
177
- return {"role": "user", "content": self.prompt}
190
+ return {"role": "user", "content": self.prompt}
178
191
 
179
192
  async def _encode_image_bs64(self, image_url: str) -> str:
180
193
  """将图片转换为 base64"""
@@ -189,34 +202,44 @@ class ProviderRequest:
189
202
  @dataclass
190
203
  class LLMResponse:
191
204
  role: str
192
- """角色, assistant, tool, err"""
193
- result_chain: MessageChain = None
194
- """返回的消息链"""
195
- tools_call_args: List[Dict[str, any]] = field(default_factory=list)
196
- """工具调用参数"""
197
- tools_call_name: List[str] = field(default_factory=list)
198
- """工具调用名称"""
199
- tools_call_ids: List[str] = field(default_factory=list)
200
- """工具调用 ID"""
201
-
202
- raw_completion: ChatCompletion = None
203
- _new_record: Dict[str, any] = None
205
+ """The role of the message, e.g., assistant, tool, err"""
206
+ result_chain: MessageChain | None = None
207
+ """A chain of message components representing the text completion from LLM."""
208
+ tools_call_args: list[dict[str, Any]] = field(default_factory=list)
209
+ """Tool call arguments."""
210
+ tools_call_name: list[str] = field(default_factory=list)
211
+ """Tool call names."""
212
+ tools_call_ids: list[str] = field(default_factory=list)
213
+ """Tool call IDs."""
214
+ tools_call_extra_content: dict[str, dict[str, Any]] = field(default_factory=dict)
215
+ """Tool call extra content. tool_call_id -> extra_content dict"""
216
+ reasoning_content: str = ""
217
+ """The reasoning content extracted from the LLM, if any."""
218
+
219
+ raw_completion: (
220
+ ChatCompletion | GenerateContentResponse | AnthropicMessage | None
221
+ ) = None
222
+ """The raw completion response from the LLM provider."""
204
223
 
205
224
  _completion_text: str = ""
225
+ """The plain text of the completion."""
206
226
 
207
227
  is_chunk: bool = False
208
- """是否是流式输出的单个 Chunk"""
228
+ """Indicates if the response is a chunked response."""
209
229
 
210
230
  def __init__(
211
231
  self,
212
232
  role: str,
213
233
  completion_text: str = "",
214
- result_chain: MessageChain = None,
215
- tools_call_args: List[Dict[str, any]] = None,
216
- tools_call_name: List[str] = None,
217
- tools_call_ids: List[str] = None,
218
- raw_completion: ChatCompletion = None,
219
- _new_record: Dict[str, any] = None,
234
+ result_chain: MessageChain | None = None,
235
+ tools_call_args: list[dict[str, Any]] | None = None,
236
+ tools_call_name: list[str] | None = None,
237
+ tools_call_ids: list[str] | None = None,
238
+ tools_call_extra_content: dict[str, dict[str, Any]] | None = None,
239
+ raw_completion: ChatCompletion
240
+ | GenerateContentResponse
241
+ | AnthropicMessage
242
+ | None = None,
220
243
  is_chunk: bool = False,
221
244
  ):
222
245
  """初始化 LLMResponse
@@ -228,6 +251,7 @@ class LLMResponse:
228
251
  tools_call_args (List[Dict[str, any]], optional): 工具调用参数. Defaults to None.
229
252
  tools_call_name (List[str], optional): 工具调用名称. Defaults to None.
230
253
  raw_completion (ChatCompletion, optional): 原始响应, OpenAI 格式. Defaults to None.
254
+
231
255
  """
232
256
  if tools_call_args is None:
233
257
  tools_call_args = []
@@ -235,6 +259,8 @@ class LLMResponse:
235
259
  tools_call_name = []
236
260
  if tools_call_ids is None:
237
261
  tools_call_ids = []
262
+ if tools_call_extra_content is None:
263
+ tools_call_extra_content = {}
238
264
 
239
265
  self.role = role
240
266
  self.completion_text = completion_text
@@ -242,8 +268,8 @@ class LLMResponse:
242
268
  self.tools_call_args = tools_call_args
243
269
  self.tools_call_name = tools_call_name
244
270
  self.tools_call_ids = tools_call_ids
271
+ self.tools_call_extra_content = tools_call_extra_content
245
272
  self.raw_completion = raw_completion
246
- self._new_record = _new_record
247
273
  self.is_chunk = is_chunk
248
274
 
249
275
  @property
@@ -264,18 +290,48 @@ class LLMResponse:
264
290
  else:
265
291
  self._completion_text = value
266
292
 
267
- def to_openai_tool_calls(self) -> List[Dict]:
268
- """将工具调用信息转换为 OpenAI 格式"""
293
+ def to_openai_tool_calls(self) -> list[dict]:
294
+ """Convert to OpenAI tool calls format. Deprecated, use to_openai_to_calls_model instead."""
295
+ ret = []
296
+ for idx, tool_call_arg in enumerate(self.tools_call_args):
297
+ payload = {
298
+ "id": self.tools_call_ids[idx],
299
+ "function": {
300
+ "name": self.tools_call_name[idx],
301
+ "arguments": json.dumps(tool_call_arg),
302
+ },
303
+ "type": "function",
304
+ }
305
+ if self.tools_call_extra_content.get(self.tools_call_ids[idx]):
306
+ payload["extra_content"] = self.tools_call_extra_content[
307
+ self.tools_call_ids[idx]
308
+ ]
309
+ ret.append(payload)
310
+ return ret
311
+
312
+ def to_openai_to_calls_model(self) -> list[ToolCall]:
313
+ """The same as to_openai_tool_calls but return pydantic model."""
269
314
  ret = []
270
315
  for idx, tool_call_arg in enumerate(self.tools_call_args):
271
316
  ret.append(
272
- {
273
- "id": self.tools_call_ids[idx],
274
- "function": {
275
- "name": self.tools_call_name[idx],
276
- "arguments": json.dumps(tool_call_arg),
277
- },
278
- "type": "function",
279
- }
317
+ ToolCall(
318
+ id=self.tools_call_ids[idx],
319
+ function=ToolCall.FunctionBody(
320
+ name=self.tools_call_name[idx],
321
+ arguments=json.dumps(tool_call_arg),
322
+ ),
323
+ # the extra_content will not serialize if it's None when calling ToolCall.model_dump()
324
+ extra_content=self.tools_call_extra_content.get(
325
+ self.tools_call_ids[idx]
326
+ ),
327
+ ),
280
328
  )
281
329
  return ret
330
+
331
+
332
+ @dataclass
333
+ class RerankResult:
334
+ index: int
335
+ """在候选列表中的索引位置"""
336
+ relevance_score: float
337
+ """相关性分数"""