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,73 +1,101 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
from collections.abc import Awaitable, Callable
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
2
7
|
import docstring_parser
|
|
3
8
|
|
|
4
|
-
from
|
|
9
|
+
from astrbot.core import logger
|
|
10
|
+
from astrbot.core.agent.agent import Agent
|
|
11
|
+
from astrbot.core.agent.handoff import HandoffTool
|
|
12
|
+
from astrbot.core.agent.hooks import BaseAgentRunHooks
|
|
13
|
+
from astrbot.core.agent.tool import FunctionTool
|
|
14
|
+
from astrbot.core.astr_agent_context import AstrAgentContext
|
|
15
|
+
from astrbot.core.provider.func_tool_manager import PY_TO_JSON_TYPE, SUPPORTED_TYPES
|
|
16
|
+
from astrbot.core.provider.register import llm_tools
|
|
17
|
+
|
|
5
18
|
from ..filter.command import CommandFilter
|
|
6
19
|
from ..filter.command_group import CommandGroupFilter
|
|
7
|
-
from ..filter.
|
|
20
|
+
from ..filter.custom_filter import CustomFilterAnd, CustomFilterOr
|
|
21
|
+
from ..filter.event_message_type import EventMessageType, EventMessageTypeFilter
|
|
22
|
+
from ..filter.permission import PermissionType, PermissionTypeFilter
|
|
8
23
|
from ..filter.platform_adapter_type import (
|
|
9
|
-
PlatformAdapterTypeFilter,
|
|
10
24
|
PlatformAdapterType,
|
|
25
|
+
PlatformAdapterTypeFilter,
|
|
11
26
|
)
|
|
12
|
-
from ..filter.permission import PermissionTypeFilter, PermissionType
|
|
13
|
-
from ..filter.custom_filter import CustomFilterAnd, CustomFilterOr
|
|
14
27
|
from ..filter.regex import RegexFilter
|
|
15
|
-
from
|
|
16
|
-
from astrbot.core.provider.func_tool_manager import SUPPORTED_TYPES
|
|
17
|
-
from astrbot.core.provider.register import llm_tools
|
|
28
|
+
from ..star_handler import EventType, StarHandlerMetadata, star_handlers_registry
|
|
18
29
|
|
|
19
30
|
|
|
20
|
-
def get_handler_full_name(awaitable: Awaitable) -> str:
|
|
31
|
+
def get_handler_full_name(awaitable: Callable[..., Awaitable[Any]]) -> str:
|
|
21
32
|
"""获取 Handler 的全名"""
|
|
22
33
|
return f"{awaitable.__module__}_{awaitable.__name__}"
|
|
23
34
|
|
|
24
35
|
|
|
25
36
|
def get_handler_or_create(
|
|
26
|
-
handler: Awaitable,
|
|
37
|
+
handler: Callable[..., Awaitable[Any]],
|
|
38
|
+
event_type: EventType,
|
|
39
|
+
dont_add=False,
|
|
40
|
+
**kwargs,
|
|
27
41
|
) -> StarHandlerMetadata:
|
|
28
42
|
"""获取 Handler 或者创建一个新的 Handler"""
|
|
29
43
|
handler_full_name = get_handler_full_name(handler)
|
|
30
44
|
md = star_handlers_registry.get_handler_by_full_name(handler_full_name)
|
|
31
45
|
if md:
|
|
32
46
|
return md
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
return md
|
|
47
|
+
md = StarHandlerMetadata(
|
|
48
|
+
event_type=event_type,
|
|
49
|
+
handler_full_name=handler_full_name,
|
|
50
|
+
handler_name=handler.__name__,
|
|
51
|
+
handler_module_path=handler.__module__,
|
|
52
|
+
handler=handler,
|
|
53
|
+
event_filters=[],
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
# 插件handler的附加额外信息
|
|
57
|
+
if handler.__doc__:
|
|
58
|
+
md.desc = handler.__doc__.strip()
|
|
59
|
+
if "desc" in kwargs:
|
|
60
|
+
md.desc = kwargs["desc"]
|
|
61
|
+
del kwargs["desc"]
|
|
62
|
+
md.extras_configs = kwargs
|
|
63
|
+
|
|
64
|
+
if not dont_add:
|
|
65
|
+
star_handlers_registry.append(md)
|
|
66
|
+
return md
|
|
54
67
|
|
|
55
68
|
|
|
56
69
|
def register_command(
|
|
57
|
-
command_name: str
|
|
70
|
+
command_name: str | None = None,
|
|
71
|
+
sub_command: str | None = None,
|
|
72
|
+
alias: set | None = None,
|
|
73
|
+
**kwargs,
|
|
58
74
|
):
|
|
59
75
|
"""注册一个 Command."""
|
|
60
76
|
new_command = None
|
|
61
77
|
add_to_event_filters = False
|
|
62
78
|
if isinstance(command_name, RegisteringCommandable):
|
|
63
79
|
# 子指令
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
80
|
+
if sub_command is not None:
|
|
81
|
+
parent_command_names = (
|
|
82
|
+
command_name.parent_group.get_complete_command_names()
|
|
83
|
+
)
|
|
84
|
+
new_command = CommandFilter(
|
|
85
|
+
sub_command,
|
|
86
|
+
alias,
|
|
87
|
+
None,
|
|
88
|
+
parent_command_names=parent_command_names,
|
|
89
|
+
)
|
|
90
|
+
command_name.parent_group.add_sub_command_filter(new_command)
|
|
91
|
+
else:
|
|
92
|
+
logger.warning(
|
|
93
|
+
f"注册指令{command_name} 的子指令时未提供 sub_command 参数。",
|
|
94
|
+
)
|
|
95
|
+
# 裸指令
|
|
96
|
+
elif command_name is None:
|
|
97
|
+
logger.warning("注册裸指令时未提供 command_name 参数。")
|
|
69
98
|
else:
|
|
70
|
-
# 裸指令
|
|
71
99
|
new_command = CommandFilter(command_name, alias, None)
|
|
72
100
|
add_to_event_filters = True
|
|
73
101
|
|
|
@@ -77,10 +105,13 @@ def register_command(
|
|
|
77
105
|
True # 打一个标记,表示这是一个子指令,再 wakingstage 阶段这个 handler 将会直接被跳过(其父指令会接管)
|
|
78
106
|
)
|
|
79
107
|
handler_md = get_handler_or_create(
|
|
80
|
-
awaitable,
|
|
108
|
+
awaitable,
|
|
109
|
+
EventType.AdapterMessageEvent,
|
|
110
|
+
**kwargs,
|
|
81
111
|
)
|
|
82
|
-
new_command
|
|
83
|
-
|
|
112
|
+
if new_command:
|
|
113
|
+
new_command.init_handler_md(handler_md)
|
|
114
|
+
handler_md.event_filters.append(new_command)
|
|
84
115
|
return awaitable
|
|
85
116
|
|
|
86
117
|
return decorator
|
|
@@ -93,6 +124,7 @@ def register_custom_filter(custom_type_filter, *args, **kwargs):
|
|
|
93
124
|
custom_type_filter: 在裸指令时为CustomFilter对象
|
|
94
125
|
在指令组时为父指令的RegisteringCommandable对象,即self或者command_group的返回
|
|
95
126
|
raise_error: 如果没有权限,是否抛出错误到消息平台,并且停止事件传播。默认为 True
|
|
127
|
+
|
|
96
128
|
"""
|
|
97
129
|
add_to_event_filters = False
|
|
98
130
|
raise_error = True
|
|
@@ -117,19 +149,20 @@ def register_custom_filter(custom_type_filter, *args, **kwargs):
|
|
|
117
149
|
def decorator(awaitable):
|
|
118
150
|
# 裸指令,子指令与指令组的区分,指令组会因为标记跳过wake。
|
|
119
151
|
if (
|
|
120
|
-
not add_to_event_filters
|
|
121
|
-
|
|
122
|
-
or (add_to_event_filters and isinstance(awaitable, RegisteringCommandable))
|
|
123
|
-
):
|
|
152
|
+
not add_to_event_filters and isinstance(awaitable, RegisteringCommandable)
|
|
153
|
+
) or (add_to_event_filters and isinstance(awaitable, RegisteringCommandable)):
|
|
124
154
|
# 指令组 与 根指令组,添加到本层的grouphandle中一起判断
|
|
125
155
|
awaitable.parent_group.add_custom_filter(custom_filter)
|
|
126
156
|
else:
|
|
127
157
|
handler_md = get_handler_or_create(
|
|
128
|
-
awaitable,
|
|
158
|
+
awaitable,
|
|
159
|
+
EventType.AdapterMessageEvent,
|
|
160
|
+
**kwargs,
|
|
129
161
|
)
|
|
130
162
|
|
|
131
163
|
if not add_to_event_filters and not isinstance(
|
|
132
|
-
awaitable,
|
|
164
|
+
awaitable,
|
|
165
|
+
RegisteringCommandable,
|
|
133
166
|
):
|
|
134
167
|
# 底层子指令
|
|
135
168
|
handle_full_name = get_handler_full_name(awaitable)
|
|
@@ -148,7 +181,9 @@ def register_custom_filter(custom_type_filter, *args, **kwargs):
|
|
|
148
181
|
else:
|
|
149
182
|
# 裸指令
|
|
150
183
|
handler_md = get_handler_or_create(
|
|
151
|
-
awaitable,
|
|
184
|
+
awaitable,
|
|
185
|
+
EventType.AdapterMessageEvent,
|
|
186
|
+
**kwargs,
|
|
152
187
|
)
|
|
153
188
|
handler_md.event_filters.append(custom_filter)
|
|
154
189
|
|
|
@@ -158,26 +193,41 @@ def register_custom_filter(custom_type_filter, *args, **kwargs):
|
|
|
158
193
|
|
|
159
194
|
|
|
160
195
|
def register_command_group(
|
|
161
|
-
command_group_name: str
|
|
196
|
+
command_group_name: str | None = None,
|
|
197
|
+
sub_command: str | None = None,
|
|
198
|
+
alias: set | None = None,
|
|
199
|
+
**kwargs,
|
|
162
200
|
):
|
|
163
201
|
"""注册一个 CommandGroup"""
|
|
164
202
|
new_group = None
|
|
165
203
|
if isinstance(command_group_name, RegisteringCommandable):
|
|
166
204
|
# 子指令组
|
|
167
|
-
|
|
168
|
-
sub_command
|
|
169
|
-
|
|
170
|
-
|
|
205
|
+
if sub_command is None:
|
|
206
|
+
logger.warning(f"{command_group_name} 指令组的子指令组 sub_command 未指定")
|
|
207
|
+
else:
|
|
208
|
+
new_group = CommandGroupFilter(
|
|
209
|
+
sub_command,
|
|
210
|
+
alias,
|
|
211
|
+
parent_group=command_group_name.parent_group,
|
|
212
|
+
)
|
|
213
|
+
command_group_name.parent_group.add_sub_command_filter(new_group)
|
|
214
|
+
# 根指令组
|
|
215
|
+
elif command_group_name is None:
|
|
216
|
+
logger.warning("根指令组的名称未指定")
|
|
171
217
|
else:
|
|
172
|
-
# 根指令组
|
|
173
218
|
new_group = CommandGroupFilter(command_group_name, alias)
|
|
174
219
|
|
|
175
220
|
def decorator(obj):
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
221
|
+
if new_group:
|
|
222
|
+
handler_md = get_handler_or_create(
|
|
223
|
+
obj,
|
|
224
|
+
EventType.AdapterMessageEvent,
|
|
225
|
+
**kwargs,
|
|
226
|
+
)
|
|
227
|
+
handler_md.event_filters.append(new_group)
|
|
179
228
|
|
|
180
|
-
|
|
229
|
+
return RegisteringCommandable(new_group)
|
|
230
|
+
raise ValueError("注册指令组失败。")
|
|
181
231
|
|
|
182
232
|
return decorator
|
|
183
233
|
|
|
@@ -185,9 +235,9 @@ def register_command_group(
|
|
|
185
235
|
class RegisteringCommandable:
|
|
186
236
|
"""用于指令组级联注册"""
|
|
187
237
|
|
|
188
|
-
group:
|
|
189
|
-
command:
|
|
190
|
-
custom_filter = register_custom_filter
|
|
238
|
+
group: Callable[..., Callable[..., RegisteringCommandable]] = register_command_group
|
|
239
|
+
command: Callable[..., Callable[..., None]] = register_command
|
|
240
|
+
custom_filter: Callable[..., Callable[..., None]] = register_custom_filter
|
|
191
241
|
|
|
192
242
|
def __init__(self, parent_group: CommandGroupFilter):
|
|
193
243
|
self.parent_group = parent_group
|
|
@@ -198,7 +248,9 @@ def register_event_message_type(event_message_type: EventMessageType, **kwargs):
|
|
|
198
248
|
|
|
199
249
|
def decorator(awaitable):
|
|
200
250
|
handler_md = get_handler_or_create(
|
|
201
|
-
awaitable,
|
|
251
|
+
awaitable,
|
|
252
|
+
EventType.AdapterMessageEvent,
|
|
253
|
+
**kwargs,
|
|
202
254
|
)
|
|
203
255
|
handler_md.event_filters.append(EventMessageTypeFilter(event_message_type))
|
|
204
256
|
return awaitable
|
|
@@ -207,14 +259,15 @@ def register_event_message_type(event_message_type: EventMessageType, **kwargs):
|
|
|
207
259
|
|
|
208
260
|
|
|
209
261
|
def register_platform_adapter_type(
|
|
210
|
-
platform_adapter_type: PlatformAdapterType,
|
|
262
|
+
platform_adapter_type: PlatformAdapterType,
|
|
263
|
+
**kwargs,
|
|
211
264
|
):
|
|
212
265
|
"""注册一个 PlatformAdapterType"""
|
|
213
266
|
|
|
214
267
|
def decorator(awaitable):
|
|
215
268
|
handler_md = get_handler_or_create(awaitable, EventType.AdapterMessageEvent)
|
|
216
269
|
handler_md.event_filters.append(
|
|
217
|
-
PlatformAdapterTypeFilter(platform_adapter_type)
|
|
270
|
+
PlatformAdapterTypeFilter(platform_adapter_type),
|
|
218
271
|
)
|
|
219
272
|
return awaitable
|
|
220
273
|
|
|
@@ -226,7 +279,9 @@ def register_regex(regex: str, **kwargs):
|
|
|
226
279
|
|
|
227
280
|
def decorator(awaitable):
|
|
228
281
|
handler_md = get_handler_or_create(
|
|
229
|
-
awaitable,
|
|
282
|
+
awaitable,
|
|
283
|
+
EventType.AdapterMessageEvent,
|
|
284
|
+
**kwargs,
|
|
230
285
|
)
|
|
231
286
|
handler_md.event_filters.append(RegexFilter(regex))
|
|
232
287
|
return awaitable
|
|
@@ -240,12 +295,13 @@ def register_permission_type(permission_type: PermissionType, raise_error: bool
|
|
|
240
295
|
Args:
|
|
241
296
|
permission_type: PermissionType
|
|
242
297
|
raise_error: 如果没有权限,是否抛出错误到消息平台,并且停止事件传播。默认为 True
|
|
298
|
+
|
|
243
299
|
"""
|
|
244
300
|
|
|
245
301
|
def decorator(awaitable):
|
|
246
302
|
handler_md = get_handler_or_create(awaitable, EventType.AdapterMessageEvent)
|
|
247
303
|
handler_md.event_filters.append(
|
|
248
|
-
PermissionTypeFilter(permission_type, raise_error)
|
|
304
|
+
PermissionTypeFilter(permission_type, raise_error),
|
|
249
305
|
)
|
|
250
306
|
return awaitable
|
|
251
307
|
|
|
@@ -262,6 +318,16 @@ def register_on_astrbot_loaded(**kwargs):
|
|
|
262
318
|
return decorator
|
|
263
319
|
|
|
264
320
|
|
|
321
|
+
def register_on_platform_loaded(**kwargs):
|
|
322
|
+
"""当平台加载完成时"""
|
|
323
|
+
|
|
324
|
+
def decorator(awaitable):
|
|
325
|
+
_ = get_handler_or_create(awaitable, EventType.OnPlatformLoadedEvent, **kwargs)
|
|
326
|
+
return awaitable
|
|
327
|
+
|
|
328
|
+
return decorator
|
|
329
|
+
|
|
330
|
+
|
|
265
331
|
def register_on_llm_request(**kwargs):
|
|
266
332
|
"""当有 LLM 请求时的事件
|
|
267
333
|
|
|
@@ -275,6 +341,7 @@ def register_on_llm_request(**kwargs):
|
|
|
275
341
|
```
|
|
276
342
|
|
|
277
343
|
请务必接收两个参数:event, request
|
|
344
|
+
|
|
278
345
|
"""
|
|
279
346
|
|
|
280
347
|
def decorator(awaitable):
|
|
@@ -297,6 +364,7 @@ def register_on_llm_response(**kwargs):
|
|
|
297
364
|
```
|
|
298
365
|
|
|
299
366
|
请务必接收两个参数:event, request
|
|
367
|
+
|
|
300
368
|
"""
|
|
301
369
|
|
|
302
370
|
def decorator(awaitable):
|
|
@@ -306,7 +374,7 @@ def register_on_llm_response(**kwargs):
|
|
|
306
374
|
return decorator
|
|
307
375
|
|
|
308
376
|
|
|
309
|
-
def register_llm_tool(name: str = None):
|
|
377
|
+
def register_llm_tool(name: str | None = None, **kwargs):
|
|
310
378
|
"""为函数调用(function-calling / tools-use)添加工具。
|
|
311
379
|
|
|
312
380
|
请务必按照以下格式编写一个工具(包括函数注释,AstrBot 会尝试解析该函数注释)
|
|
@@ -316,7 +384,7 @@ def register_llm_tool(name: str = None):
|
|
|
316
384
|
async def get_weather(event: AstrMessageEvent, location: str):
|
|
317
385
|
\'\'\'获取天气信息。
|
|
318
386
|
|
|
319
|
-
|
|
387
|
+
Args:
|
|
320
388
|
location(string): 地点
|
|
321
389
|
\'\'\'
|
|
322
390
|
# 处理逻辑
|
|
@@ -337,41 +405,121 @@ def register_llm_tool(name: str = None):
|
|
|
337
405
|
event.stop_event()
|
|
338
406
|
yield
|
|
339
407
|
```
|
|
340
|
-
"""
|
|
341
408
|
|
|
409
|
+
"""
|
|
342
410
|
name_ = name
|
|
411
|
+
registering_agent = None
|
|
412
|
+
if kwargs.get("registering_agent"):
|
|
413
|
+
registering_agent = kwargs["registering_agent"]
|
|
343
414
|
|
|
344
|
-
def decorator(awaitable: Awaitable):
|
|
415
|
+
def decorator(awaitable: Callable[..., Awaitable[Any]]):
|
|
345
416
|
llm_tool_name = name_ if name_ else awaitable.__name__
|
|
346
|
-
|
|
417
|
+
func_doc = awaitable.__doc__ or ""
|
|
418
|
+
docstring = docstring_parser.parse(func_doc)
|
|
347
419
|
args = []
|
|
348
420
|
for arg in docstring.params:
|
|
349
|
-
|
|
421
|
+
sub_type_name = None
|
|
422
|
+
type_name = arg.type_name
|
|
423
|
+
if not type_name:
|
|
350
424
|
raise ValueError(
|
|
351
|
-
f"LLM 函数工具 {awaitable.__module__}_{llm_tool_name}
|
|
425
|
+
f"LLM 函数工具 {awaitable.__module__}_{llm_tool_name} 的参数 {arg.arg_name} 缺少类型注释。",
|
|
352
426
|
)
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
427
|
+
# parse type_name to handle cases like "list[string]"
|
|
428
|
+
match = re.match(r"(\w+)\[(\w+)\]", type_name)
|
|
429
|
+
if match:
|
|
430
|
+
type_name = match.group(1)
|
|
431
|
+
sub_type_name = match.group(2)
|
|
432
|
+
type_name = PY_TO_JSON_TYPE.get(type_name, type_name)
|
|
433
|
+
if sub_type_name:
|
|
434
|
+
sub_type_name = PY_TO_JSON_TYPE.get(sub_type_name, sub_type_name)
|
|
435
|
+
if type_name not in SUPPORTED_TYPES or (
|
|
436
|
+
sub_type_name and sub_type_name not in SUPPORTED_TYPES
|
|
437
|
+
):
|
|
438
|
+
raise ValueError(
|
|
439
|
+
f"LLM 函数工具 {awaitable.__module__}_{llm_tool_name} 不支持的参数类型:{arg.type_name}",
|
|
440
|
+
)
|
|
441
|
+
|
|
442
|
+
arg_json_schema = {
|
|
443
|
+
"type": type_name,
|
|
444
|
+
"name": arg.arg_name,
|
|
445
|
+
"description": arg.description,
|
|
446
|
+
}
|
|
447
|
+
if sub_type_name:
|
|
448
|
+
if type_name == "array":
|
|
449
|
+
arg_json_schema["items"] = {"type": sub_type_name}
|
|
450
|
+
args.append(arg_json_schema)
|
|
451
|
+
|
|
452
|
+
if not registering_agent:
|
|
453
|
+
doc_desc = docstring.description.strip() if docstring.description else ""
|
|
454
|
+
md = get_handler_or_create(awaitable, EventType.OnCallingFuncToolEvent)
|
|
455
|
+
llm_tools.add_func(llm_tool_name, args, doc_desc, md.handler)
|
|
456
|
+
else:
|
|
457
|
+
assert isinstance(registering_agent, RegisteringAgent)
|
|
458
|
+
# print(f"Registering tool {llm_tool_name} for agent", registering_agent._agent.name)
|
|
459
|
+
if registering_agent._agent.tools is None:
|
|
460
|
+
registering_agent._agent.tools = []
|
|
461
|
+
|
|
462
|
+
desc = docstring.description.strip() if docstring.description else ""
|
|
463
|
+
tool = llm_tools.spec_to_func(llm_tool_name, args, desc, awaitable)
|
|
464
|
+
registering_agent._agent.tools.append(tool)
|
|
465
|
+
|
|
364
466
|
return awaitable
|
|
365
467
|
|
|
366
468
|
return decorator
|
|
367
469
|
|
|
368
470
|
|
|
471
|
+
class RegisteringAgent:
|
|
472
|
+
"""用于 Agent 注册"""
|
|
473
|
+
|
|
474
|
+
def llm_tool(self, *args, **kwargs):
|
|
475
|
+
kwargs["registering_agent"] = self
|
|
476
|
+
return register_llm_tool(*args, **kwargs)
|
|
477
|
+
|
|
478
|
+
def __init__(self, agent: Agent[AstrAgentContext]):
|
|
479
|
+
self._agent = agent
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
def register_agent(
|
|
483
|
+
name: str,
|
|
484
|
+
instruction: str,
|
|
485
|
+
tools: list[str | FunctionTool] | None = None,
|
|
486
|
+
run_hooks: BaseAgentRunHooks[AstrAgentContext] | None = None,
|
|
487
|
+
):
|
|
488
|
+
"""注册一个 Agent
|
|
489
|
+
|
|
490
|
+
Args:
|
|
491
|
+
name: Agent 的名称
|
|
492
|
+
instruction: Agent 的指令
|
|
493
|
+
tools: Agent 使用的工具列表
|
|
494
|
+
run_hooks: Agent 运行时的钩子函数
|
|
495
|
+
|
|
496
|
+
"""
|
|
497
|
+
tools_ = tools or []
|
|
498
|
+
|
|
499
|
+
def decorator(awaitable: Callable[..., Awaitable[Any]]):
|
|
500
|
+
AstrAgent = Agent[AstrAgentContext]
|
|
501
|
+
agent = AstrAgent(
|
|
502
|
+
name=name,
|
|
503
|
+
instructions=instruction,
|
|
504
|
+
tools=tools_,
|
|
505
|
+
run_hooks=run_hooks or BaseAgentRunHooks[AstrAgentContext](),
|
|
506
|
+
)
|
|
507
|
+
handoff_tool = HandoffTool(agent=agent)
|
|
508
|
+
handoff_tool.handler = awaitable
|
|
509
|
+
llm_tools.func_list.append(handoff_tool)
|
|
510
|
+
return RegisteringAgent(agent)
|
|
511
|
+
|
|
512
|
+
return decorator
|
|
513
|
+
|
|
514
|
+
|
|
369
515
|
def register_on_decorating_result(**kwargs):
|
|
370
516
|
"""在发送消息前的事件"""
|
|
371
517
|
|
|
372
518
|
def decorator(awaitable):
|
|
373
519
|
_ = get_handler_or_create(
|
|
374
|
-
awaitable,
|
|
520
|
+
awaitable,
|
|
521
|
+
EventType.OnDecoratingResultEvent,
|
|
522
|
+
**kwargs,
|
|
375
523
|
)
|
|
376
524
|
return awaitable
|
|
377
525
|
|
|
@@ -383,7 +531,9 @@ def register_after_message_sent(**kwargs):
|
|
|
383
531
|
|
|
384
532
|
def decorator(awaitable):
|
|
385
533
|
_ = get_handler_or_create(
|
|
386
|
-
awaitable,
|
|
534
|
+
awaitable,
|
|
535
|
+
EventType.OnAfterMessageSentEvent,
|
|
536
|
+
**kwargs,
|
|
387
537
|
)
|
|
388
538
|
return awaitable
|
|
389
539
|
|