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,45 +1,33 @@
|
|
|
1
1
|
import abc
|
|
2
2
|
import asyncio
|
|
3
|
-
import re
|
|
4
3
|
import hashlib
|
|
4
|
+
import re
|
|
5
5
|
import uuid
|
|
6
|
-
from
|
|
7
|
-
from typing import
|
|
6
|
+
from collections.abc import AsyncGenerator
|
|
7
|
+
from typing import Any
|
|
8
8
|
|
|
9
|
+
from astrbot import logger
|
|
9
10
|
from astrbot.core.db.po import Conversation
|
|
10
11
|
from astrbot.core.message.components import (
|
|
11
|
-
Plain,
|
|
12
|
-
Image,
|
|
13
|
-
BaseMessageComponent,
|
|
14
|
-
Face,
|
|
15
12
|
At,
|
|
16
13
|
AtAll,
|
|
14
|
+
BaseMessageComponent,
|
|
15
|
+
Face,
|
|
17
16
|
Forward,
|
|
17
|
+
Image,
|
|
18
|
+
Plain,
|
|
18
19
|
Reply,
|
|
19
20
|
)
|
|
20
|
-
from astrbot.core.message.message_event_result import
|
|
21
|
+
from astrbot.core.message.message_event_result import MessageChain, MessageEventResult
|
|
21
22
|
from astrbot.core.platform.message_type import MessageType
|
|
22
23
|
from astrbot.core.provider.entities import ProviderRequest
|
|
23
24
|
from astrbot.core.utils.metrics import Metric
|
|
25
|
+
|
|
24
26
|
from .astrbot_message import AstrBotMessage, Group
|
|
27
|
+
from .message_session import MessageSesion, MessageSession # noqa
|
|
25
28
|
from .platform_metadata import PlatformMetadata
|
|
26
29
|
|
|
27
30
|
|
|
28
|
-
@dataclass
|
|
29
|
-
class MessageSesion:
|
|
30
|
-
platform_name: str
|
|
31
|
-
message_type: MessageType
|
|
32
|
-
session_id: str
|
|
33
|
-
|
|
34
|
-
def __str__(self):
|
|
35
|
-
return f"{self.platform_name}:{self.message_type.value}:{self.session_id}"
|
|
36
|
-
|
|
37
|
-
@staticmethod
|
|
38
|
-
def from_str(session_str: str):
|
|
39
|
-
platform_name, message_type, session_id = session_str.split(":")
|
|
40
|
-
return MessageSesion(platform_name, MessageType(message_type), session_id)
|
|
41
|
-
|
|
42
|
-
|
|
43
31
|
class AstrMessageEvent(abc.ABC):
|
|
44
32
|
def __init__(
|
|
45
33
|
self,
|
|
@@ -62,15 +50,15 @@ class AstrMessageEvent(abc.ABC):
|
|
|
62
50
|
"""是否唤醒(是否通过 WakingStage)"""
|
|
63
51
|
self.is_at_or_wake_command = False
|
|
64
52
|
"""是否是 At 机器人或者带有唤醒词或者是私聊(插件注册的事件监听器会让 is_wake 设为 True, 但是不会让这个属性置为 True)"""
|
|
65
|
-
self._extras = {}
|
|
53
|
+
self._extras: dict[str, Any] = {}
|
|
66
54
|
self.session = MessageSesion(
|
|
67
|
-
platform_name=platform_meta.
|
|
55
|
+
platform_name=platform_meta.id,
|
|
68
56
|
message_type=message_obj.type,
|
|
69
57
|
session_id=session_id,
|
|
70
58
|
)
|
|
71
59
|
self.unified_msg_origin = str(self.session)
|
|
72
60
|
"""统一的消息来源字符串。格式为 platform_name:message_type:session_id"""
|
|
73
|
-
self._result: MessageEventResult = None
|
|
61
|
+
self._result: MessageEventResult | None = None
|
|
74
62
|
"""消息事件的结果"""
|
|
75
63
|
|
|
76
64
|
self._has_send_oper = False
|
|
@@ -78,140 +66,124 @@ class AstrMessageEvent(abc.ABC):
|
|
|
78
66
|
self.call_llm = False
|
|
79
67
|
"""是否在此消息事件中禁止默认的 LLM 请求"""
|
|
80
68
|
|
|
69
|
+
self.plugins_name: list[str] | None = None
|
|
70
|
+
"""该事件启用的插件名称列表。None 表示所有插件都启用。空列表表示没有启用任何插件。"""
|
|
71
|
+
|
|
81
72
|
# back_compability
|
|
82
73
|
self.platform = platform_meta
|
|
83
74
|
|
|
84
75
|
def get_platform_name(self):
|
|
76
|
+
"""获取这个事件所属的平台的类型(如 aiocqhttp, slack, discord 等)。
|
|
77
|
+
|
|
78
|
+
NOTE: 用户可能会同时运行多个相同类型的平台适配器。
|
|
79
|
+
"""
|
|
85
80
|
return self.platform_meta.name
|
|
86
81
|
|
|
87
82
|
def get_platform_id(self):
|
|
83
|
+
"""获取这个事件所属的平台的 ID。
|
|
84
|
+
|
|
85
|
+
NOTE: 用户可能会同时运行多个相同类型的平台适配器,但能确定的是 ID 是唯一的。
|
|
86
|
+
"""
|
|
88
87
|
return self.platform_meta.id
|
|
89
88
|
|
|
90
89
|
def get_message_str(self) -> str:
|
|
91
|
-
"""
|
|
92
|
-
获取消息字符串。
|
|
93
|
-
"""
|
|
90
|
+
"""获取消息字符串。"""
|
|
94
91
|
return self.message_str
|
|
95
92
|
|
|
96
|
-
def _outline_chain(self, chain:
|
|
97
|
-
|
|
93
|
+
def _outline_chain(self, chain: list[BaseMessageComponent] | None) -> str:
|
|
94
|
+
if not chain:
|
|
95
|
+
return ""
|
|
96
|
+
|
|
97
|
+
parts = []
|
|
98
98
|
for i in chain:
|
|
99
99
|
if isinstance(i, Plain):
|
|
100
|
-
|
|
100
|
+
parts.append(i.text)
|
|
101
101
|
elif isinstance(i, Image):
|
|
102
|
-
|
|
102
|
+
parts.append("[图片]")
|
|
103
103
|
elif isinstance(i, Face):
|
|
104
|
-
|
|
104
|
+
parts.append(f"[表情:{i.id}]")
|
|
105
105
|
elif isinstance(i, At):
|
|
106
|
-
|
|
106
|
+
parts.append(f"[At:{i.qq}]")
|
|
107
107
|
elif isinstance(i, AtAll):
|
|
108
|
-
|
|
108
|
+
parts.append("[At:全体成员]")
|
|
109
109
|
elif isinstance(i, Forward):
|
|
110
110
|
# 转发消息
|
|
111
|
-
|
|
111
|
+
parts.append("[转发消息]")
|
|
112
112
|
elif isinstance(i, Reply):
|
|
113
113
|
# 引用回复
|
|
114
114
|
if i.message_str:
|
|
115
|
-
|
|
115
|
+
parts.append(f"[引用消息({i.sender_nickname}: {i.message_str})]")
|
|
116
116
|
else:
|
|
117
|
-
|
|
117
|
+
parts.append("[引用消息]")
|
|
118
118
|
else:
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
return
|
|
119
|
+
parts.append(f"[{i.type}]")
|
|
120
|
+
parts.append(" ")
|
|
121
|
+
return "".join(parts)
|
|
122
122
|
|
|
123
123
|
def get_message_outline(self) -> str:
|
|
124
|
-
"""
|
|
125
|
-
获取消息概要。
|
|
124
|
+
"""获取消息概要。
|
|
126
125
|
|
|
127
126
|
除了文本消息外,其他消息类型会被转换为对应的占位符。如图片消息会被转换为 [图片]。
|
|
128
127
|
"""
|
|
129
128
|
return self._outline_chain(self.message_obj.message)
|
|
130
129
|
|
|
131
|
-
def get_messages(self) ->
|
|
132
|
-
"""
|
|
133
|
-
获取消息链。
|
|
134
|
-
"""
|
|
130
|
+
def get_messages(self) -> list[BaseMessageComponent]:
|
|
131
|
+
"""获取消息链。"""
|
|
135
132
|
return self.message_obj.message
|
|
136
133
|
|
|
137
134
|
def get_message_type(self) -> MessageType:
|
|
138
|
-
"""
|
|
139
|
-
获取消息类型。
|
|
140
|
-
"""
|
|
135
|
+
"""获取消息类型。"""
|
|
141
136
|
return self.message_obj.type
|
|
142
137
|
|
|
143
138
|
def get_session_id(self) -> str:
|
|
144
|
-
"""
|
|
145
|
-
获取会话id。
|
|
146
|
-
"""
|
|
139
|
+
"""获取会话id。"""
|
|
147
140
|
return self.session_id
|
|
148
141
|
|
|
149
142
|
def get_group_id(self) -> str:
|
|
150
|
-
"""
|
|
151
|
-
获取群组id。如果不是群组消息,返回空字符串。
|
|
152
|
-
"""
|
|
143
|
+
"""获取群组id。如果不是群组消息,返回空字符串。"""
|
|
153
144
|
return self.message_obj.group_id
|
|
154
145
|
|
|
155
146
|
def get_self_id(self) -> str:
|
|
156
|
-
"""
|
|
157
|
-
获取机器人自身的id。
|
|
158
|
-
"""
|
|
147
|
+
"""获取机器人自身的id。"""
|
|
159
148
|
return self.message_obj.self_id
|
|
160
149
|
|
|
161
150
|
def get_sender_id(self) -> str:
|
|
162
|
-
"""
|
|
163
|
-
获取消息发送者的id。
|
|
164
|
-
"""
|
|
151
|
+
"""获取消息发送者的id。"""
|
|
165
152
|
return self.message_obj.sender.user_id
|
|
166
153
|
|
|
167
154
|
def get_sender_name(self) -> str:
|
|
168
|
-
"""
|
|
169
|
-
获取消息发送者的名称。(可能会返回空字符串)
|
|
170
|
-
"""
|
|
155
|
+
"""获取消息发送者的名称。(可能会返回空字符串)"""
|
|
171
156
|
return self.message_obj.sender.nickname
|
|
172
157
|
|
|
173
158
|
def set_extra(self, key, value):
|
|
174
|
-
"""
|
|
175
|
-
设置额外的信息。
|
|
176
|
-
"""
|
|
159
|
+
"""设置额外的信息。"""
|
|
177
160
|
self._extras[key] = value
|
|
178
161
|
|
|
179
|
-
def get_extra(self, key=None):
|
|
180
|
-
"""
|
|
181
|
-
获取额外的信息。
|
|
182
|
-
"""
|
|
162
|
+
def get_extra(self, key: str | None = None, default=None) -> Any:
|
|
163
|
+
"""获取额外的信息。"""
|
|
183
164
|
if key is None:
|
|
184
165
|
return self._extras
|
|
185
|
-
return self._extras.get(key,
|
|
166
|
+
return self._extras.get(key, default)
|
|
186
167
|
|
|
187
168
|
def clear_extra(self):
|
|
188
|
-
"""
|
|
189
|
-
|
|
190
|
-
"""
|
|
169
|
+
"""清除额外的信息。"""
|
|
170
|
+
logger.info(f"清除 {self.get_platform_name()} 的额外信息: {self._extras}")
|
|
191
171
|
self._extras.clear()
|
|
192
172
|
|
|
193
173
|
def is_private_chat(self) -> bool:
|
|
194
|
-
"""
|
|
195
|
-
是否是私聊。
|
|
196
|
-
"""
|
|
174
|
+
"""是否是私聊。"""
|
|
197
175
|
return self.message_obj.type.value == (MessageType.FRIEND_MESSAGE).value
|
|
198
176
|
|
|
199
177
|
def is_wake_up(self) -> bool:
|
|
200
|
-
"""
|
|
201
|
-
是否是唤醒机器人的事件。
|
|
202
|
-
"""
|
|
178
|
+
"""是否是唤醒机器人的事件。"""
|
|
203
179
|
return self.is_wake
|
|
204
180
|
|
|
205
181
|
def is_admin(self) -> bool:
|
|
206
|
-
"""
|
|
207
|
-
是否是管理员。
|
|
208
|
-
"""
|
|
182
|
+
"""是否是管理员。"""
|
|
209
183
|
return self.role == "admin"
|
|
210
184
|
|
|
211
185
|
async def process_buffer(self, buffer: str, pattern: re.Pattern) -> str:
|
|
212
|
-
"""
|
|
213
|
-
将消息缓冲区中的文本按指定正则表达式分割后发送至消息平台,作为不支持流式输出平台的Fallback。
|
|
214
|
-
"""
|
|
186
|
+
"""将消息缓冲区中的文本按指定正则表达式分割后发送至消息平台,作为不支持流式输出平台的Fallback。"""
|
|
215
187
|
while True:
|
|
216
188
|
match = re.search(pattern, buffer)
|
|
217
189
|
if not match:
|
|
@@ -223,24 +195,26 @@ class AstrMessageEvent(abc.ABC):
|
|
|
223
195
|
return buffer
|
|
224
196
|
|
|
225
197
|
async def send_streaming(
|
|
226
|
-
self,
|
|
198
|
+
self,
|
|
199
|
+
generator: AsyncGenerator[MessageChain, None],
|
|
200
|
+
use_fallback: bool = False,
|
|
227
201
|
):
|
|
228
202
|
"""发送流式消息到消息平台,使用异步生成器。
|
|
229
203
|
目前仅支持: telegram,qq official 私聊。
|
|
230
|
-
Fallback仅支持 aiocqhttp
|
|
204
|
+
Fallback仅支持 aiocqhttp。
|
|
231
205
|
"""
|
|
232
206
|
asyncio.create_task(
|
|
233
|
-
Metric.upload(msg_event_tick=1, adapter_name=self.platform_meta.name)
|
|
207
|
+
Metric.upload(msg_event_tick=1, adapter_name=self.platform_meta.name),
|
|
234
208
|
)
|
|
235
209
|
self._has_send_oper = True
|
|
236
210
|
|
|
237
211
|
async def _pre_send(self):
|
|
238
|
-
"""调度器会在执行 send() 前调用该方法"""
|
|
212
|
+
"""调度器会在执行 send() 前调用该方法 deprecated in v3.5.18"""
|
|
239
213
|
|
|
240
214
|
async def _post_send(self):
|
|
241
|
-
"""调度器会在执行 send() 后调用该方法"""
|
|
215
|
+
"""调度器会在执行 send() 后调用该方法 deprecated in v3.5.18"""
|
|
242
216
|
|
|
243
|
-
def set_result(self, result:
|
|
217
|
+
def set_result(self, result: MessageEventResult | str):
|
|
244
218
|
"""设置消息事件的结果。
|
|
245
219
|
|
|
246
220
|
Note:
|
|
@@ -260,9 +234,13 @@ class AstrMessageEvent(abc.ABC):
|
|
|
260
234
|
event.set_result(MessageEventResult().set_console_log("数量已增加", logging.DEBUG).set_result_type(EventResultType.CONTINUE))
|
|
261
235
|
return
|
|
262
236
|
```
|
|
237
|
+
|
|
263
238
|
"""
|
|
264
239
|
if isinstance(result, str):
|
|
265
240
|
result = MessageEventResult().message(result)
|
|
241
|
+
# 兼容外部插件或调用方传入的 chain=None 的情况,确保为可迭代列表
|
|
242
|
+
if isinstance(result, MessageEventResult) and result.chain is None:
|
|
243
|
+
result.chain = []
|
|
266
244
|
self._result = result
|
|
267
245
|
|
|
268
246
|
def stop_event(self):
|
|
@@ -280,41 +258,32 @@ class AstrMessageEvent(abc.ABC):
|
|
|
280
258
|
self._result.continue_event()
|
|
281
259
|
|
|
282
260
|
def is_stopped(self) -> bool:
|
|
283
|
-
"""
|
|
284
|
-
是否终止事件传播。
|
|
285
|
-
"""
|
|
261
|
+
"""是否终止事件传播。"""
|
|
286
262
|
if self._result is None:
|
|
287
263
|
return False # 默认是继续传播
|
|
288
264
|
return self._result.is_stopped()
|
|
289
265
|
|
|
290
266
|
def should_call_llm(self, call_llm: bool):
|
|
291
|
-
"""
|
|
292
|
-
是否在此消息事件中禁止默认的 LLM 请求。
|
|
267
|
+
"""是否在此消息事件中禁止默认的 LLM 请求。
|
|
293
268
|
|
|
294
269
|
只会阻止 AstrBot 默认的 LLM 请求链路,不会阻止插件中的 LLM 请求。
|
|
295
270
|
"""
|
|
296
271
|
self.call_llm = call_llm
|
|
297
272
|
|
|
298
273
|
def get_result(self) -> MessageEventResult:
|
|
299
|
-
"""
|
|
300
|
-
获取消息事件的结果。
|
|
301
|
-
"""
|
|
274
|
+
"""获取消息事件的结果。"""
|
|
302
275
|
return self._result
|
|
303
276
|
|
|
304
277
|
def clear_result(self):
|
|
305
|
-
"""
|
|
306
|
-
清除消息事件的结果。
|
|
307
|
-
"""
|
|
278
|
+
"""清除消息事件的结果。"""
|
|
308
279
|
self._result = None
|
|
309
280
|
|
|
310
281
|
"""消息链相关"""
|
|
311
282
|
|
|
312
283
|
def make_result(self) -> MessageEventResult:
|
|
313
|
-
"""
|
|
314
|
-
创建一个空的消息事件结果。
|
|
284
|
+
"""创建一个空的消息事件结果。
|
|
315
285
|
|
|
316
286
|
Example:
|
|
317
|
-
|
|
318
287
|
```python
|
|
319
288
|
# 纯文本回复
|
|
320
289
|
yield event.make_result().message("Hi")
|
|
@@ -322,18 +291,16 @@ class AstrMessageEvent(abc.ABC):
|
|
|
322
291
|
yield event.make_result().url_image("https://example.com/image.jpg")
|
|
323
292
|
yield event.make_result().file_image("image.jpg")
|
|
324
293
|
```
|
|
294
|
+
|
|
325
295
|
"""
|
|
326
296
|
return MessageEventResult()
|
|
327
297
|
|
|
328
298
|
def plain_result(self, text: str) -> MessageEventResult:
|
|
329
|
-
"""
|
|
330
|
-
创建一个空的消息事件结果,只包含一条文本消息。
|
|
331
|
-
"""
|
|
299
|
+
"""创建一个空的消息事件结果,只包含一条文本消息。"""
|
|
332
300
|
return MessageEventResult().message(text)
|
|
333
301
|
|
|
334
302
|
def image_result(self, url_or_path: str) -> MessageEventResult:
|
|
335
|
-
"""
|
|
336
|
-
创建一个空的消息事件结果,只包含一条图片消息。
|
|
303
|
+
"""创建一个空的消息事件结果,只包含一条图片消息。
|
|
337
304
|
|
|
338
305
|
根据开头是否包含 http 来判断是网络图片还是本地图片。
|
|
339
306
|
"""
|
|
@@ -341,10 +308,8 @@ class AstrMessageEvent(abc.ABC):
|
|
|
341
308
|
return MessageEventResult().url_image(url_or_path)
|
|
342
309
|
return MessageEventResult().file_image(url_or_path)
|
|
343
310
|
|
|
344
|
-
def chain_result(self, chain:
|
|
345
|
-
"""
|
|
346
|
-
创建一个空的消息事件结果,包含指定的消息链。
|
|
347
|
-
"""
|
|
311
|
+
def chain_result(self, chain: list[BaseMessageComponent]) -> MessageEventResult:
|
|
312
|
+
"""创建一个空的消息事件结果,包含指定的消息链。"""
|
|
348
313
|
mer = MessageEventResult()
|
|
349
314
|
mer.chain = chain
|
|
350
315
|
return mer
|
|
@@ -356,13 +321,12 @@ class AstrMessageEvent(abc.ABC):
|
|
|
356
321
|
prompt: str,
|
|
357
322
|
func_tool_manager=None,
|
|
358
323
|
session_id: str = None,
|
|
359
|
-
image_urls:
|
|
360
|
-
contexts:
|
|
324
|
+
image_urls: list[str] | None = None,
|
|
325
|
+
contexts: list | None = None,
|
|
361
326
|
system_prompt: str = "",
|
|
362
|
-
conversation: Conversation = None,
|
|
327
|
+
conversation: Conversation | None = None,
|
|
363
328
|
) -> ProviderRequest:
|
|
364
|
-
"""
|
|
365
|
-
创建一个 LLM 请求。
|
|
329
|
+
"""创建一个 LLM 请求。
|
|
366
330
|
|
|
367
331
|
Examples:
|
|
368
332
|
```py
|
|
@@ -381,8 +345,12 @@ class AstrMessageEvent(abc.ABC):
|
|
|
381
345
|
func_tool_manager: 函数工具管理器,用于调用函数工具。用 self.context.get_llm_tool_manager() 获取。
|
|
382
346
|
|
|
383
347
|
conversation: 可选。如果指定,将在指定的对话中进行 LLM 请求。对话的人格会被用于 LLM 请求,并且结果将会被记录到对话中。
|
|
384
|
-
"""
|
|
385
348
|
|
|
349
|
+
"""
|
|
350
|
+
if image_urls is None:
|
|
351
|
+
image_urls = []
|
|
352
|
+
if contexts is None:
|
|
353
|
+
contexts = []
|
|
386
354
|
if len(contexts) > 0 and conversation:
|
|
387
355
|
conversation = None
|
|
388
356
|
|
|
@@ -403,23 +371,33 @@ class AstrMessageEvent(abc.ABC):
|
|
|
403
371
|
|
|
404
372
|
Args:
|
|
405
373
|
message (MessageChain): 消息链,具体使用方式请参考文档。
|
|
374
|
+
|
|
406
375
|
"""
|
|
407
376
|
# Leverage BLAKE2 hash function to generate a non-reversible hash of the sender ID for privacy.
|
|
408
377
|
hash_obj = hashlib.blake2b(self.get_sender_id().encode("utf-8"), digest_size=16)
|
|
409
378
|
sid = str(uuid.UUID(bytes=hash_obj.digest()))
|
|
410
379
|
asyncio.create_task(
|
|
411
380
|
Metric.upload(
|
|
412
|
-
msg_event_tick=1,
|
|
413
|
-
|
|
381
|
+
msg_event_tick=1,
|
|
382
|
+
adapter_name=self.platform_meta.name,
|
|
383
|
+
sid=sid,
|
|
384
|
+
),
|
|
414
385
|
)
|
|
415
386
|
self._has_send_oper = True
|
|
416
387
|
|
|
417
|
-
async def
|
|
388
|
+
async def react(self, emoji: str):
|
|
389
|
+
"""对消息添加表情回应。
|
|
390
|
+
|
|
391
|
+
默认实现为发送一条包含该表情的消息。
|
|
392
|
+
注意:此实现并不一定符合所有平台的原生“表情回应”行为。
|
|
393
|
+
如需支持平台原生的消息反应功能,请在对应平台的子类中重写本方法。
|
|
394
|
+
"""
|
|
395
|
+
await self.send(MessageChain([Plain(emoji)]))
|
|
396
|
+
|
|
397
|
+
async def get_group(self, group_id: str | None = None, **kwargs) -> Group | None:
|
|
418
398
|
"""获取一个群聊的数据, 如果不填写 group_id: 如果是私聊消息,返回 None。如果是群聊消息,返回当前群聊的数据。
|
|
419
399
|
|
|
420
400
|
适配情况:
|
|
421
401
|
|
|
422
|
-
- gewechat
|
|
423
402
|
- aiocqhttp(OneBotv11)
|
|
424
403
|
"""
|
|
425
|
-
...
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import time
|
|
2
|
-
from typing import List
|
|
3
2
|
from dataclasses import dataclass
|
|
3
|
+
|
|
4
4
|
from astrbot.core.message.components import BaseMessageComponent
|
|
5
|
+
|
|
5
6
|
from .message_type import MessageType
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
@dataclass
|
|
9
10
|
class MessageMember:
|
|
10
11
|
user_id: str # 发送者id
|
|
11
|
-
nickname: str = None
|
|
12
|
+
nickname: str | None = None
|
|
12
13
|
|
|
13
14
|
def __str__(self):
|
|
14
15
|
# 使用 f-string 来构建返回的字符串表示形式
|
|
@@ -22,15 +23,15 @@ class MessageMember:
|
|
|
22
23
|
class Group:
|
|
23
24
|
group_id: str
|
|
24
25
|
"""群号"""
|
|
25
|
-
group_name: str = None
|
|
26
|
+
group_name: str | None = None
|
|
26
27
|
"""群名称"""
|
|
27
|
-
group_avatar: str = None
|
|
28
|
+
group_avatar: str | None = None
|
|
28
29
|
"""群头像"""
|
|
29
|
-
group_owner: str = None
|
|
30
|
+
group_owner: str | None = None
|
|
30
31
|
"""群主 id"""
|
|
31
|
-
group_admins:
|
|
32
|
+
group_admins: list[str] | None = None
|
|
32
33
|
"""群管理员 id"""
|
|
33
|
-
members:
|
|
34
|
+
members: list[MessageMember] | None = None
|
|
34
35
|
"""所有群成员"""
|
|
35
36
|
|
|
36
37
|
def __str__(self):
|
|
@@ -47,23 +48,42 @@ class Group:
|
|
|
47
48
|
|
|
48
49
|
|
|
49
50
|
class AstrBotMessage:
|
|
50
|
-
"""
|
|
51
|
-
AstrBot 的消息对象
|
|
52
|
-
"""
|
|
51
|
+
"""AstrBot 的消息对象"""
|
|
53
52
|
|
|
54
53
|
type: MessageType # 消息类型
|
|
55
54
|
self_id: str # 机器人的识别id
|
|
56
55
|
session_id: str # 会话id。取决于 unique_session 的设置。
|
|
57
56
|
message_id: str # 消息id
|
|
58
|
-
|
|
57
|
+
group: Group # 群组
|
|
59
58
|
sender: MessageMember # 发送者
|
|
60
|
-
message:
|
|
59
|
+
message: list[BaseMessageComponent] # 消息链使用 Nakuru 的消息链格式
|
|
61
60
|
message_str: str # 最直观的纯文本消息字符串
|
|
62
61
|
raw_message: object
|
|
63
62
|
timestamp: int # 消息时间戳
|
|
64
63
|
|
|
65
64
|
def __init__(self) -> None:
|
|
66
65
|
self.timestamp = int(time.time())
|
|
66
|
+
self.group = None
|
|
67
67
|
|
|
68
68
|
def __str__(self) -> str:
|
|
69
69
|
return str(self.__dict__)
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def group_id(self) -> str:
|
|
73
|
+
"""向后兼容的 group_id 属性
|
|
74
|
+
群组id,如果为私聊,则为空
|
|
75
|
+
"""
|
|
76
|
+
if self.group:
|
|
77
|
+
return self.group.group_id
|
|
78
|
+
return ""
|
|
79
|
+
|
|
80
|
+
@group_id.setter
|
|
81
|
+
def group_id(self, value: str):
|
|
82
|
+
"""设置 group_id"""
|
|
83
|
+
if value:
|
|
84
|
+
if self.group:
|
|
85
|
+
self.group.group_id = value
|
|
86
|
+
else:
|
|
87
|
+
self.group = Group(group_id=value)
|
|
88
|
+
else:
|
|
89
|
+
self.group = None
|