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.
- astrbot/api/__init__.py +16 -4
- astrbot/api/all.py +2 -1
- astrbot/api/event/__init__.py +5 -6
- astrbot/api/event/filter/__init__.py +37 -34
- astrbot/api/platform/__init__.py +7 -8
- astrbot/api/provider/__init__.py +8 -7
- astrbot/api/star/__init__.py +3 -4
- astrbot/api/util/__init__.py +2 -2
- astrbot/cli/__init__.py +1 -0
- astrbot/cli/__main__.py +18 -197
- astrbot/cli/commands/__init__.py +6 -0
- astrbot/cli/commands/cmd_conf.py +209 -0
- astrbot/cli/commands/cmd_init.py +56 -0
- astrbot/cli/commands/cmd_plug.py +245 -0
- astrbot/cli/commands/cmd_run.py +62 -0
- astrbot/cli/utils/__init__.py +18 -0
- astrbot/cli/utils/basic.py +76 -0
- astrbot/cli/utils/plugin.py +246 -0
- astrbot/cli/utils/version_comparator.py +90 -0
- astrbot/core/__init__.py +17 -19
- astrbot/core/agent/agent.py +14 -0
- astrbot/core/agent/handoff.py +38 -0
- astrbot/core/agent/hooks.py +30 -0
- astrbot/core/agent/mcp_client.py +385 -0
- astrbot/core/agent/message.py +175 -0
- astrbot/core/agent/response.py +14 -0
- astrbot/core/agent/run_context.py +22 -0
- astrbot/core/agent/runners/__init__.py +3 -0
- astrbot/core/agent/runners/base.py +65 -0
- astrbot/core/agent/runners/coze/coze_agent_runner.py +367 -0
- astrbot/core/agent/runners/coze/coze_api_client.py +324 -0
- astrbot/core/agent/runners/dashscope/dashscope_agent_runner.py +403 -0
- astrbot/core/agent/runners/dify/dify_agent_runner.py +336 -0
- astrbot/core/agent/runners/dify/dify_api_client.py +195 -0
- astrbot/core/agent/runners/tool_loop_agent_runner.py +400 -0
- astrbot/core/agent/tool.py +285 -0
- astrbot/core/agent/tool_executor.py +17 -0
- astrbot/core/astr_agent_context.py +19 -0
- astrbot/core/astr_agent_hooks.py +36 -0
- astrbot/core/astr_agent_run_util.py +80 -0
- astrbot/core/astr_agent_tool_exec.py +246 -0
- astrbot/core/astrbot_config_mgr.py +275 -0
- astrbot/core/config/__init__.py +2 -2
- astrbot/core/config/astrbot_config.py +60 -20
- astrbot/core/config/default.py +1972 -453
- astrbot/core/config/i18n_utils.py +110 -0
- astrbot/core/conversation_mgr.py +285 -75
- astrbot/core/core_lifecycle.py +167 -62
- astrbot/core/db/__init__.py +305 -102
- astrbot/core/db/migration/helper.py +69 -0
- astrbot/core/db/migration/migra_3_to_4.py +357 -0
- astrbot/core/db/migration/migra_45_to_46.py +44 -0
- astrbot/core/db/migration/migra_webchat_session.py +131 -0
- astrbot/core/db/migration/shared_preferences_v3.py +48 -0
- astrbot/core/db/migration/sqlite_v3.py +497 -0
- astrbot/core/db/po.py +259 -55
- astrbot/core/db/sqlite.py +773 -528
- astrbot/core/db/vec_db/base.py +73 -0
- astrbot/core/db/vec_db/faiss_impl/__init__.py +3 -0
- astrbot/core/db/vec_db/faiss_impl/document_storage.py +392 -0
- astrbot/core/db/vec_db/faiss_impl/embedding_storage.py +93 -0
- astrbot/core/db/vec_db/faiss_impl/sqlite_init.sql +17 -0
- astrbot/core/db/vec_db/faiss_impl/vec_db.py +204 -0
- astrbot/core/event_bus.py +26 -22
- astrbot/core/exceptions.py +9 -0
- astrbot/core/file_token_service.py +98 -0
- astrbot/core/initial_loader.py +19 -10
- astrbot/core/knowledge_base/chunking/__init__.py +9 -0
- astrbot/core/knowledge_base/chunking/base.py +25 -0
- astrbot/core/knowledge_base/chunking/fixed_size.py +59 -0
- astrbot/core/knowledge_base/chunking/recursive.py +161 -0
- astrbot/core/knowledge_base/kb_db_sqlite.py +301 -0
- astrbot/core/knowledge_base/kb_helper.py +642 -0
- astrbot/core/knowledge_base/kb_mgr.py +330 -0
- astrbot/core/knowledge_base/models.py +120 -0
- astrbot/core/knowledge_base/parsers/__init__.py +13 -0
- astrbot/core/knowledge_base/parsers/base.py +51 -0
- astrbot/core/knowledge_base/parsers/markitdown_parser.py +26 -0
- astrbot/core/knowledge_base/parsers/pdf_parser.py +101 -0
- astrbot/core/knowledge_base/parsers/text_parser.py +42 -0
- astrbot/core/knowledge_base/parsers/url_parser.py +103 -0
- astrbot/core/knowledge_base/parsers/util.py +13 -0
- astrbot/core/knowledge_base/prompts.py +65 -0
- astrbot/core/knowledge_base/retrieval/__init__.py +14 -0
- astrbot/core/knowledge_base/retrieval/hit_stopwords.txt +767 -0
- astrbot/core/knowledge_base/retrieval/manager.py +276 -0
- astrbot/core/knowledge_base/retrieval/rank_fusion.py +142 -0
- astrbot/core/knowledge_base/retrieval/sparse_retriever.py +136 -0
- astrbot/core/log.py +21 -15
- astrbot/core/message/components.py +413 -287
- astrbot/core/message/message_event_result.py +35 -24
- astrbot/core/persona_mgr.py +192 -0
- astrbot/core/pipeline/__init__.py +14 -14
- astrbot/core/pipeline/content_safety_check/stage.py +13 -9
- astrbot/core/pipeline/content_safety_check/strategies/__init__.py +1 -2
- astrbot/core/pipeline/content_safety_check/strategies/baidu_aip.py +13 -14
- astrbot/core/pipeline/content_safety_check/strategies/keywords.py +2 -1
- astrbot/core/pipeline/content_safety_check/strategies/strategy.py +6 -6
- astrbot/core/pipeline/context.py +7 -1
- astrbot/core/pipeline/context_utils.py +107 -0
- astrbot/core/pipeline/preprocess_stage/stage.py +63 -36
- astrbot/core/pipeline/process_stage/method/agent_request.py +48 -0
- astrbot/core/pipeline/process_stage/method/agent_sub_stages/internal.py +464 -0
- astrbot/core/pipeline/process_stage/method/agent_sub_stages/third_party.py +202 -0
- astrbot/core/pipeline/process_stage/method/star_request.py +26 -32
- astrbot/core/pipeline/process_stage/stage.py +21 -15
- astrbot/core/pipeline/process_stage/utils.py +125 -0
- astrbot/core/pipeline/rate_limit_check/stage.py +34 -36
- astrbot/core/pipeline/respond/stage.py +142 -101
- astrbot/core/pipeline/result_decorate/stage.py +124 -57
- astrbot/core/pipeline/scheduler.py +21 -16
- astrbot/core/pipeline/session_status_check/stage.py +37 -0
- astrbot/core/pipeline/stage.py +11 -76
- astrbot/core/pipeline/waking_check/stage.py +69 -33
- astrbot/core/pipeline/whitelist_check/stage.py +10 -7
- astrbot/core/platform/__init__.py +6 -6
- astrbot/core/platform/astr_message_event.py +107 -129
- astrbot/core/platform/astrbot_message.py +32 -12
- astrbot/core/platform/manager.py +62 -18
- astrbot/core/platform/message_session.py +30 -0
- astrbot/core/platform/platform.py +16 -24
- astrbot/core/platform/platform_metadata.py +9 -4
- astrbot/core/platform/register.py +12 -7
- astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py +136 -60
- astrbot/core/platform/sources/aiocqhttp/aiocqhttp_platform_adapter.py +126 -46
- astrbot/core/platform/sources/dingtalk/dingtalk_adapter.py +63 -31
- astrbot/core/platform/sources/dingtalk/dingtalk_event.py +30 -26
- astrbot/core/platform/sources/discord/client.py +129 -0
- astrbot/core/platform/sources/discord/components.py +139 -0
- astrbot/core/platform/sources/discord/discord_platform_adapter.py +473 -0
- astrbot/core/platform/sources/discord/discord_platform_event.py +313 -0
- astrbot/core/platform/sources/lark/lark_adapter.py +27 -18
- astrbot/core/platform/sources/lark/lark_event.py +39 -13
- astrbot/core/platform/sources/misskey/misskey_adapter.py +770 -0
- astrbot/core/platform/sources/misskey/misskey_api.py +964 -0
- astrbot/core/platform/sources/misskey/misskey_event.py +163 -0
- astrbot/core/platform/sources/misskey/misskey_utils.py +550 -0
- astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py +149 -33
- astrbot/core/platform/sources/qqofficial/qqofficial_platform_adapter.py +41 -26
- astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_adapter.py +36 -17
- astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_event.py +3 -1
- astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_server.py +14 -8
- astrbot/core/platform/sources/satori/satori_adapter.py +792 -0
- astrbot/core/platform/sources/satori/satori_event.py +432 -0
- astrbot/core/platform/sources/slack/client.py +164 -0
- astrbot/core/platform/sources/slack/slack_adapter.py +416 -0
- astrbot/core/platform/sources/slack/slack_event.py +253 -0
- astrbot/core/platform/sources/telegram/tg_adapter.py +100 -43
- astrbot/core/platform/sources/telegram/tg_event.py +136 -36
- astrbot/core/platform/sources/webchat/webchat_adapter.py +72 -22
- astrbot/core/platform/sources/webchat/webchat_event.py +46 -22
- astrbot/core/platform/sources/webchat/webchat_queue_mgr.py +35 -0
- astrbot/core/platform/sources/wechatpadpro/wechatpadpro_adapter.py +926 -0
- astrbot/core/platform/sources/wechatpadpro/wechatpadpro_message_event.py +178 -0
- astrbot/core/platform/sources/wechatpadpro/xml_data_parser.py +159 -0
- astrbot/core/platform/sources/wecom/wecom_adapter.py +169 -27
- astrbot/core/platform/sources/wecom/wecom_event.py +162 -77
- astrbot/core/platform/sources/wecom/wecom_kf.py +279 -0
- astrbot/core/platform/sources/wecom/wecom_kf_message.py +196 -0
- astrbot/core/platform/sources/wecom_ai_bot/WXBizJsonMsgCrypt.py +297 -0
- astrbot/core/platform/sources/wecom_ai_bot/__init__.py +15 -0
- astrbot/core/platform/sources/wecom_ai_bot/ierror.py +19 -0
- astrbot/core/platform/sources/wecom_ai_bot/wecomai_adapter.py +472 -0
- astrbot/core/platform/sources/wecom_ai_bot/wecomai_api.py +417 -0
- astrbot/core/platform/sources/wecom_ai_bot/wecomai_event.py +152 -0
- astrbot/core/platform/sources/wecom_ai_bot/wecomai_queue_mgr.py +153 -0
- astrbot/core/platform/sources/wecom_ai_bot/wecomai_server.py +168 -0
- astrbot/core/platform/sources/wecom_ai_bot/wecomai_utils.py +209 -0
- astrbot/core/platform/sources/weixin_official_account/weixin_offacc_adapter.py +306 -0
- astrbot/core/platform/sources/weixin_official_account/weixin_offacc_event.py +186 -0
- astrbot/core/platform_message_history_mgr.py +49 -0
- astrbot/core/provider/__init__.py +2 -3
- astrbot/core/provider/entites.py +8 -8
- astrbot/core/provider/entities.py +154 -98
- astrbot/core/provider/func_tool_manager.py +446 -458
- astrbot/core/provider/manager.py +345 -207
- astrbot/core/provider/provider.py +188 -73
- astrbot/core/provider/register.py +9 -7
- astrbot/core/provider/sources/anthropic_source.py +295 -115
- astrbot/core/provider/sources/azure_tts_source.py +224 -0
- astrbot/core/provider/sources/bailian_rerank_source.py +236 -0
- astrbot/core/provider/sources/dashscope_tts.py +138 -14
- astrbot/core/provider/sources/edge_tts_source.py +24 -19
- astrbot/core/provider/sources/fishaudio_tts_api_source.py +58 -13
- astrbot/core/provider/sources/gemini_embedding_source.py +61 -0
- astrbot/core/provider/sources/gemini_source.py +310 -132
- astrbot/core/provider/sources/gemini_tts_source.py +81 -0
- astrbot/core/provider/sources/groq_source.py +15 -0
- astrbot/core/provider/sources/gsv_selfhosted_source.py +151 -0
- astrbot/core/provider/sources/gsvi_tts_source.py +14 -7
- astrbot/core/provider/sources/minimax_tts_api_source.py +159 -0
- astrbot/core/provider/sources/openai_embedding_source.py +40 -0
- astrbot/core/provider/sources/openai_source.py +241 -145
- astrbot/core/provider/sources/openai_tts_api_source.py +18 -7
- astrbot/core/provider/sources/sensevoice_selfhosted_source.py +13 -11
- astrbot/core/provider/sources/vllm_rerank_source.py +71 -0
- astrbot/core/provider/sources/volcengine_tts.py +115 -0
- astrbot/core/provider/sources/whisper_api_source.py +18 -13
- astrbot/core/provider/sources/whisper_selfhosted_source.py +19 -12
- astrbot/core/provider/sources/xinference_rerank_source.py +116 -0
- astrbot/core/provider/sources/xinference_stt_provider.py +197 -0
- astrbot/core/provider/sources/zhipu_source.py +6 -73
- astrbot/core/star/__init__.py +43 -11
- astrbot/core/star/config.py +17 -18
- astrbot/core/star/context.py +362 -138
- astrbot/core/star/filter/__init__.py +4 -3
- astrbot/core/star/filter/command.py +111 -35
- astrbot/core/star/filter/command_group.py +46 -34
- astrbot/core/star/filter/custom_filter.py +6 -5
- astrbot/core/star/filter/event_message_type.py +4 -2
- astrbot/core/star/filter/permission.py +4 -2
- astrbot/core/star/filter/platform_adapter_type.py +45 -12
- astrbot/core/star/filter/regex.py +4 -2
- astrbot/core/star/register/__init__.py +19 -15
- astrbot/core/star/register/star.py +41 -13
- astrbot/core/star/register/star_handler.py +236 -86
- astrbot/core/star/session_llm_manager.py +280 -0
- astrbot/core/star/session_plugin_manager.py +170 -0
- astrbot/core/star/star.py +36 -43
- astrbot/core/star/star_handler.py +47 -85
- astrbot/core/star/star_manager.py +442 -260
- astrbot/core/star/star_tools.py +167 -45
- astrbot/core/star/updator.py +17 -20
- astrbot/core/umop_config_router.py +106 -0
- astrbot/core/updator.py +38 -13
- astrbot/core/utils/astrbot_path.py +39 -0
- astrbot/core/utils/command_parser.py +1 -1
- astrbot/core/utils/io.py +119 -60
- astrbot/core/utils/log_pipe.py +1 -1
- astrbot/core/utils/metrics.py +11 -10
- astrbot/core/utils/migra_helper.py +73 -0
- astrbot/core/utils/path_util.py +63 -62
- astrbot/core/utils/pip_installer.py +37 -15
- astrbot/core/utils/session_lock.py +29 -0
- astrbot/core/utils/session_waiter.py +19 -20
- astrbot/core/utils/shared_preferences.py +174 -34
- astrbot/core/utils/t2i/__init__.py +4 -1
- astrbot/core/utils/t2i/local_strategy.py +386 -238
- astrbot/core/utils/t2i/network_strategy.py +109 -49
- astrbot/core/utils/t2i/renderer.py +29 -14
- astrbot/core/utils/t2i/template/astrbot_powershell.html +184 -0
- astrbot/core/utils/t2i/template_manager.py +111 -0
- astrbot/core/utils/tencent_record_helper.py +115 -1
- astrbot/core/utils/version_comparator.py +10 -13
- astrbot/core/zip_updator.py +112 -65
- astrbot/dashboard/routes/__init__.py +20 -13
- astrbot/dashboard/routes/auth.py +20 -9
- astrbot/dashboard/routes/chat.py +297 -141
- astrbot/dashboard/routes/config.py +652 -55
- astrbot/dashboard/routes/conversation.py +107 -37
- astrbot/dashboard/routes/file.py +26 -0
- astrbot/dashboard/routes/knowledge_base.py +1244 -0
- astrbot/dashboard/routes/log.py +27 -2
- astrbot/dashboard/routes/persona.py +202 -0
- astrbot/dashboard/routes/plugin.py +197 -139
- astrbot/dashboard/routes/route.py +27 -7
- astrbot/dashboard/routes/session_management.py +354 -0
- astrbot/dashboard/routes/stat.py +85 -18
- astrbot/dashboard/routes/static_file.py +5 -2
- astrbot/dashboard/routes/t2i.py +233 -0
- astrbot/dashboard/routes/tools.py +184 -120
- astrbot/dashboard/routes/update.py +59 -36
- astrbot/dashboard/server.py +96 -36
- astrbot/dashboard/utils.py +165 -0
- astrbot-4.7.0.dist-info/METADATA +294 -0
- astrbot-4.7.0.dist-info/RECORD +274 -0
- {astrbot-3.5.6.dist-info → astrbot-4.7.0.dist-info}/WHEEL +1 -1
- astrbot/core/db/plugin/sqlite_impl.py +0 -112
- astrbot/core/db/sqlite_init.sql +0 -50
- astrbot/core/pipeline/platform_compatibility/stage.py +0 -56
- astrbot/core/pipeline/process_stage/method/llm_request.py +0 -606
- astrbot/core/platform/sources/gewechat/client.py +0 -806
- astrbot/core/platform/sources/gewechat/downloader.py +0 -55
- astrbot/core/platform/sources/gewechat/gewechat_event.py +0 -255
- astrbot/core/platform/sources/gewechat/gewechat_platform_adapter.py +0 -103
- astrbot/core/platform/sources/gewechat/xml_data_parser.py +0 -110
- astrbot/core/provider/sources/dashscope_source.py +0 -203
- astrbot/core/provider/sources/dify_source.py +0 -281
- astrbot/core/provider/sources/llmtuner_source.py +0 -132
- astrbot/core/rag/embedding/openai_source.py +0 -20
- astrbot/core/rag/knowledge_db_mgr.py +0 -94
- astrbot/core/rag/store/__init__.py +0 -9
- astrbot/core/rag/store/chroma_db.py +0 -42
- astrbot/core/utils/dify_api_client.py +0 -152
- astrbot-3.5.6.dist-info/METADATA +0 -249
- astrbot-3.5.6.dist-info/RECORD +0 -158
- {astrbot-3.5.6.dist-info → astrbot-4.7.0.dist-info}/entry_points.txt +0 -0
- {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
|
|
8
|
-
|
|
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
|
-
|
|
11
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
"""
|
|
28
|
-
desc: str = ""
|
|
29
|
-
"""提供商适配器描述."""
|
|
41
|
+
"""the name of the provider adapter, such as openai, ollama"""
|
|
30
42
|
provider_type: ProviderType = ProviderType.CHAT_COMPLETION
|
|
31
|
-
|
|
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
|
|
41
|
-
"""
|
|
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
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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:
|
|
66
|
+
tool_calls_result: list[ToolCallMessageSegment]
|
|
81
67
|
"""函数调用的结果"""
|
|
82
68
|
|
|
83
|
-
def to_openai_messages(self) ->
|
|
69
|
+
def to_openai_messages(self) -> list[dict]:
|
|
84
70
|
ret = [
|
|
85
|
-
self.tool_calls_info.
|
|
86
|
-
*[item.
|
|
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:
|
|
91
|
+
image_urls: list[str] = field(default_factory=list)
|
|
98
92
|
"""图片 URL 列表"""
|
|
99
|
-
func_tool:
|
|
93
|
+
func_tool: ToolSet | None = None
|
|
100
94
|
"""可用的函数工具"""
|
|
101
|
-
contexts:
|
|
102
|
-
"""
|
|
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
|
|
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) ->
|
|
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": [
|
|
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
|
-
|
|
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
|
-
"""
|
|
193
|
-
result_chain: MessageChain = None
|
|
194
|
-
"""
|
|
195
|
-
tools_call_args:
|
|
196
|
-
"""
|
|
197
|
-
tools_call_name:
|
|
198
|
-
"""
|
|
199
|
-
tools_call_ids:
|
|
200
|
-
"""
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
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
|
-
"""
|
|
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:
|
|
216
|
-
tools_call_name:
|
|
217
|
-
tools_call_ids:
|
|
218
|
-
|
|
219
|
-
|
|
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) ->
|
|
268
|
-
"""
|
|
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
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
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
|
+
"""相关性分数"""
|