AstrBot 4.5.0__py3-none-any.whl → 4.5.2__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 +10 -11
- astrbot/api/event/__init__.py +5 -6
- astrbot/api/event/filter/__init__.py +37 -36
- astrbot/api/platform/__init__.py +7 -8
- astrbot/api/provider/__init__.py +7 -7
- astrbot/api/star/__init__.py +3 -4
- astrbot/api/util/__init__.py +2 -2
- astrbot/cli/__main__.py +5 -5
- astrbot/cli/commands/__init__.py +3 -3
- astrbot/cli/commands/cmd_conf.py +19 -16
- astrbot/cli/commands/cmd_init.py +3 -2
- astrbot/cli/commands/cmd_plug.py +8 -10
- astrbot/cli/commands/cmd_run.py +5 -6
- astrbot/cli/utils/__init__.py +6 -6
- astrbot/cli/utils/basic.py +14 -14
- astrbot/cli/utils/plugin.py +24 -15
- astrbot/cli/utils/version_comparator.py +10 -12
- astrbot/core/__init__.py +8 -6
- astrbot/core/agent/agent.py +3 -2
- astrbot/core/agent/handoff.py +6 -2
- astrbot/core/agent/hooks.py +9 -6
- astrbot/core/agent/mcp_client.py +50 -15
- astrbot/core/agent/message.py +168 -0
- astrbot/core/agent/response.py +2 -1
- astrbot/core/agent/run_context.py +2 -3
- astrbot/core/agent/runners/base.py +10 -13
- astrbot/core/agent/runners/tool_loop_agent_runner.py +52 -51
- astrbot/core/agent/tool.py +60 -41
- astrbot/core/agent/tool_executor.py +9 -3
- astrbot/core/astr_agent_context.py +3 -1
- astrbot/core/astrbot_config_mgr.py +29 -9
- astrbot/core/config/__init__.py +2 -2
- astrbot/core/config/astrbot_config.py +28 -26
- astrbot/core/config/default.py +44 -6
- astrbot/core/conversation_mgr.py +105 -36
- astrbot/core/core_lifecycle.py +68 -54
- astrbot/core/db/__init__.py +33 -18
- astrbot/core/db/migration/helper.py +18 -13
- astrbot/core/db/migration/migra_3_to_4.py +53 -34
- astrbot/core/db/migration/migra_45_to_46.py +1 -1
- astrbot/core/db/migration/shared_preferences_v3.py +2 -1
- astrbot/core/db/migration/sqlite_v3.py +26 -23
- astrbot/core/db/po.py +27 -18
- astrbot/core/db/sqlite.py +74 -45
- astrbot/core/db/vec_db/base.py +10 -14
- astrbot/core/db/vec_db/faiss_impl/document_storage.py +90 -77
- astrbot/core/db/vec_db/faiss_impl/embedding_storage.py +9 -3
- astrbot/core/db/vec_db/faiss_impl/vec_db.py +36 -31
- astrbot/core/event_bus.py +8 -6
- astrbot/core/file_token_service.py +6 -5
- astrbot/core/initial_loader.py +7 -5
- astrbot/core/knowledge_base/chunking/__init__.py +1 -3
- astrbot/core/knowledge_base/chunking/base.py +1 -0
- astrbot/core/knowledge_base/chunking/fixed_size.py +2 -0
- astrbot/core/knowledge_base/chunking/recursive.py +16 -10
- astrbot/core/knowledge_base/kb_db_sqlite.py +50 -48
- astrbot/core/knowledge_base/kb_helper.py +30 -17
- astrbot/core/knowledge_base/kb_mgr.py +6 -7
- astrbot/core/knowledge_base/models.py +10 -4
- astrbot/core/knowledge_base/parsers/__init__.py +3 -5
- astrbot/core/knowledge_base/parsers/base.py +1 -0
- astrbot/core/knowledge_base/parsers/markitdown_parser.py +2 -1
- astrbot/core/knowledge_base/parsers/pdf_parser.py +2 -1
- astrbot/core/knowledge_base/parsers/text_parser.py +1 -0
- astrbot/core/knowledge_base/parsers/util.py +1 -1
- astrbot/core/knowledge_base/retrieval/__init__.py +6 -8
- astrbot/core/knowledge_base/retrieval/manager.py +17 -14
- astrbot/core/knowledge_base/retrieval/rank_fusion.py +7 -3
- astrbot/core/knowledge_base/retrieval/sparse_retriever.py +11 -5
- astrbot/core/log.py +21 -13
- astrbot/core/message/components.py +123 -217
- astrbot/core/message/message_event_result.py +24 -24
- astrbot/core/persona_mgr.py +20 -11
- astrbot/core/pipeline/__init__.py +7 -7
- 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 +12 -13
- astrbot/core/pipeline/content_safety_check/strategies/keywords.py +1 -0
- astrbot/core/pipeline/content_safety_check/strategies/strategy.py +6 -6
- astrbot/core/pipeline/context.py +4 -1
- astrbot/core/pipeline/context_utils.py +77 -7
- astrbot/core/pipeline/preprocess_stage/stage.py +12 -9
- astrbot/core/pipeline/process_stage/method/llm_request.py +125 -72
- astrbot/core/pipeline/process_stage/method/star_request.py +19 -17
- astrbot/core/pipeline/process_stage/stage.py +13 -10
- astrbot/core/pipeline/process_stage/utils.py +6 -5
- astrbot/core/pipeline/rate_limit_check/stage.py +37 -36
- astrbot/core/pipeline/respond/stage.py +23 -20
- astrbot/core/pipeline/result_decorate/stage.py +31 -23
- astrbot/core/pipeline/scheduler.py +12 -8
- astrbot/core/pipeline/session_status_check/stage.py +12 -8
- astrbot/core/pipeline/stage.py +10 -4
- astrbot/core/pipeline/waking_check/stage.py +24 -18
- astrbot/core/pipeline/whitelist_check/stage.py +10 -7
- astrbot/core/platform/__init__.py +6 -6
- astrbot/core/platform/astr_message_event.py +76 -110
- astrbot/core/platform/astrbot_message.py +11 -13
- astrbot/core/platform/manager.py +16 -15
- astrbot/core/platform/message_session.py +5 -3
- astrbot/core/platform/platform.py +16 -24
- astrbot/core/platform/platform_metadata.py +4 -4
- astrbot/core/platform/register.py +8 -8
- astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py +23 -15
- astrbot/core/platform/sources/aiocqhttp/aiocqhttp_platform_adapter.py +51 -33
- astrbot/core/platform/sources/dingtalk/dingtalk_adapter.py +47 -29
- astrbot/core/platform/sources/dingtalk/dingtalk_event.py +7 -3
- astrbot/core/platform/sources/discord/client.py +9 -6
- astrbot/core/platform/sources/discord/components.py +18 -14
- astrbot/core/platform/sources/discord/discord_platform_adapter.py +45 -30
- astrbot/core/platform/sources/discord/discord_platform_event.py +38 -30
- astrbot/core/platform/sources/lark/lark_adapter.py +23 -17
- astrbot/core/platform/sources/lark/lark_event.py +21 -14
- astrbot/core/platform/sources/misskey/misskey_adapter.py +107 -67
- astrbot/core/platform/sources/misskey/misskey_api.py +153 -129
- astrbot/core/platform/sources/misskey/misskey_event.py +20 -15
- astrbot/core/platform/sources/misskey/misskey_utils.py +74 -62
- astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py +63 -44
- 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 +12 -7
- astrbot/core/platform/sources/satori/satori_adapter.py +56 -38
- astrbot/core/platform/sources/satori/satori_event.py +34 -25
- astrbot/core/platform/sources/slack/client.py +11 -9
- astrbot/core/platform/sources/slack/slack_adapter.py +52 -36
- astrbot/core/platform/sources/slack/slack_event.py +34 -24
- astrbot/core/platform/sources/telegram/tg_adapter.py +38 -18
- astrbot/core/platform/sources/telegram/tg_event.py +32 -18
- astrbot/core/platform/sources/webchat/webchat_adapter.py +27 -17
- astrbot/core/platform/sources/webchat/webchat_event.py +14 -10
- astrbot/core/platform/sources/wechatpadpro/wechatpadpro_adapter.py +115 -120
- astrbot/core/platform/sources/wechatpadpro/wechatpadpro_message_event.py +9 -8
- astrbot/core/platform/sources/wechatpadpro/xml_data_parser.py +15 -16
- astrbot/core/platform/sources/wecom/wecom_adapter.py +35 -18
- astrbot/core/platform/sources/wecom/wecom_event.py +55 -48
- astrbot/core/platform/sources/wecom/wecom_kf.py +34 -44
- astrbot/core/platform/sources/wecom/wecom_kf_message.py +26 -10
- astrbot/core/platform/sources/wecom_ai_bot/WXBizJsonMsgCrypt.py +18 -10
- astrbot/core/platform/sources/wecom_ai_bot/__init__.py +3 -5
- astrbot/core/platform/sources/wecom_ai_bot/ierror.py +0 -1
- astrbot/core/platform/sources/wecom_ai_bot/wecomai_adapter.py +61 -37
- astrbot/core/platform/sources/wecom_ai_bot/wecomai_api.py +67 -28
- astrbot/core/platform/sources/wecom_ai_bot/wecomai_event.py +8 -9
- astrbot/core/platform/sources/wecom_ai_bot/wecomai_queue_mgr.py +18 -9
- astrbot/core/platform/sources/wecom_ai_bot/wecomai_server.py +14 -12
- astrbot/core/platform/sources/wecom_ai_bot/wecomai_utils.py +22 -12
- astrbot/core/platform/sources/weixin_official_account/weixin_offacc_adapter.py +40 -26
- astrbot/core/platform/sources/weixin_official_account/weixin_offacc_event.py +47 -45
- astrbot/core/platform_message_history_mgr.py +5 -3
- astrbot/core/provider/__init__.py +2 -3
- astrbot/core/provider/entites.py +8 -8
- astrbot/core/provider/entities.py +61 -75
- astrbot/core/provider/func_tool_manager.py +59 -55
- astrbot/core/provider/manager.py +40 -22
- astrbot/core/provider/provider.py +72 -46
- astrbot/core/provider/register.py +7 -7
- astrbot/core/provider/sources/anthropic_source.py +48 -30
- astrbot/core/provider/sources/azure_tts_source.py +17 -13
- astrbot/core/provider/sources/coze_api_client.py +27 -17
- astrbot/core/provider/sources/coze_source.py +104 -87
- astrbot/core/provider/sources/dashscope_source.py +18 -11
- astrbot/core/provider/sources/dashscope_tts.py +36 -23
- astrbot/core/provider/sources/dify_source.py +25 -20
- astrbot/core/provider/sources/edge_tts_source.py +21 -17
- astrbot/core/provider/sources/fishaudio_tts_api_source.py +22 -14
- astrbot/core/provider/sources/gemini_embedding_source.py +12 -13
- astrbot/core/provider/sources/gemini_source.py +72 -58
- astrbot/core/provider/sources/gemini_tts_source.py +8 -6
- astrbot/core/provider/sources/gsv_selfhosted_source.py +17 -14
- astrbot/core/provider/sources/gsvi_tts_source.py +11 -7
- astrbot/core/provider/sources/minimax_tts_api_source.py +50 -40
- astrbot/core/provider/sources/openai_embedding_source.py +6 -8
- astrbot/core/provider/sources/openai_source.py +102 -69
- astrbot/core/provider/sources/openai_tts_api_source.py +14 -6
- astrbot/core/provider/sources/sensevoice_selfhosted_source.py +13 -11
- astrbot/core/provider/sources/vllm_rerank_source.py +10 -4
- astrbot/core/provider/sources/volcengine_tts.py +38 -31
- astrbot/core/provider/sources/whisper_api_source.py +14 -12
- astrbot/core/provider/sources/whisper_selfhosted_source.py +15 -11
- astrbot/core/provider/sources/xinference_rerank_source.py +116 -0
- astrbot/core/provider/sources/xinference_stt_provider.py +197 -0
- astrbot/core/star/__init__.py +16 -11
- astrbot/core/star/config.py +10 -15
- astrbot/core/star/context.py +109 -84
- astrbot/core/star/filter/__init__.py +4 -3
- astrbot/core/star/filter/command.py +30 -28
- astrbot/core/star/filter/command_group.py +27 -24
- 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 +4 -2
- astrbot/core/star/filter/regex.py +4 -2
- astrbot/core/star/register/__init__.py +19 -19
- astrbot/core/star/register/star.py +6 -2
- astrbot/core/star/register/star_handler.py +96 -73
- astrbot/core/star/session_llm_manager.py +48 -14
- astrbot/core/star/session_plugin_manager.py +29 -15
- astrbot/core/star/star.py +1 -2
- astrbot/core/star/star_handler.py +13 -8
- astrbot/core/star/star_manager.py +151 -59
- astrbot/core/star/star_tools.py +44 -37
- astrbot/core/star/updator.py +10 -10
- astrbot/core/umop_config_router.py +10 -4
- astrbot/core/updator.py +13 -5
- astrbot/core/utils/astrbot_path.py +3 -5
- astrbot/core/utils/dify_api_client.py +33 -15
- astrbot/core/utils/io.py +66 -42
- astrbot/core/utils/log_pipe.py +1 -1
- astrbot/core/utils/metrics.py +7 -7
- astrbot/core/utils/path_util.py +15 -16
- astrbot/core/utils/pip_installer.py +5 -5
- astrbot/core/utils/session_waiter.py +19 -20
- astrbot/core/utils/shared_preferences.py +45 -20
- astrbot/core/utils/t2i/__init__.py +4 -1
- astrbot/core/utils/t2i/network_strategy.py +35 -26
- astrbot/core/utils/t2i/renderer.py +11 -5
- astrbot/core/utils/t2i/template_manager.py +14 -15
- astrbot/core/utils/tencent_record_helper.py +19 -13
- astrbot/core/utils/version_comparator.py +10 -13
- astrbot/core/zip_updator.py +43 -40
- astrbot/dashboard/routes/__init__.py +18 -18
- astrbot/dashboard/routes/auth.py +10 -8
- astrbot/dashboard/routes/chat.py +30 -21
- astrbot/dashboard/routes/config.py +92 -75
- astrbot/dashboard/routes/conversation.py +46 -39
- astrbot/dashboard/routes/file.py +4 -2
- astrbot/dashboard/routes/knowledge_base.py +47 -40
- astrbot/dashboard/routes/log.py +9 -4
- astrbot/dashboard/routes/persona.py +19 -16
- astrbot/dashboard/routes/plugin.py +69 -55
- astrbot/dashboard/routes/route.py +3 -1
- astrbot/dashboard/routes/session_management.py +130 -116
- astrbot/dashboard/routes/stat.py +34 -34
- astrbot/dashboard/routes/t2i.py +15 -12
- astrbot/dashboard/routes/tools.py +47 -52
- astrbot/dashboard/routes/update.py +32 -28
- astrbot/dashboard/server.py +30 -26
- astrbot/dashboard/utils.py +8 -4
- {astrbot-4.5.0.dist-info → astrbot-4.5.2.dist-info}/METADATA +4 -2
- astrbot-4.5.2.dist-info/RECORD +261 -0
- astrbot-4.5.0.dist-info/RECORD +0 -258
- {astrbot-4.5.0.dist-info → astrbot-4.5.2.dist-info}/WHEEL +0 -0
- {astrbot-4.5.0.dist-info → astrbot-4.5.2.dist-info}/entry_points.txt +0 -0
- {astrbot-4.5.0.dist-info → astrbot-4.5.2.dist-info}/licenses/LICENSE +0 -0
astrbot/core/star/config.py
CHANGED
|
@@ -1,23 +1,20 @@
|
|
|
1
|
-
"""
|
|
2
|
-
此功能已过时,参考 https://astrbot.app/dev/plugin.html#%E6%B3%A8%E5%86%8C%E6%8F%92%E4%BB%B6%E9%85%8D%E7%BD%AE-beta
|
|
3
|
-
"""
|
|
1
|
+
"""此功能已过时,参考 https://astrbot.app/dev/plugin.html#%E6%B3%A8%E5%86%8C%E6%8F%92%E4%BB%B6%E9%85%8D%E7%BD%AE-beta"""
|
|
4
2
|
|
|
5
|
-
from typing import Union
|
|
6
|
-
import os
|
|
7
3
|
import json
|
|
4
|
+
import os
|
|
5
|
+
|
|
8
6
|
from astrbot.core.utils.astrbot_path import get_astrbot_data_path
|
|
9
7
|
|
|
10
8
|
|
|
11
|
-
def load_config(namespace: str) ->
|
|
12
|
-
"""
|
|
13
|
-
从配置文件中加载配置。
|
|
9
|
+
def load_config(namespace: str) -> dict | bool:
|
|
10
|
+
"""从配置文件中加载配置。
|
|
14
11
|
namespace: str, 配置的唯一识别符,也就是配置文件的名字。
|
|
15
12
|
返回值: 当配置文件存在时,返回 namespace 对应配置文件的内容dict,否则返回 False。
|
|
16
13
|
"""
|
|
17
14
|
path = os.path.join(get_astrbot_data_path(), "config", f"{namespace}.json")
|
|
18
15
|
if not os.path.exists(path):
|
|
19
16
|
return False
|
|
20
|
-
with open(path,
|
|
17
|
+
with open(path, encoding="utf-8-sig") as f:
|
|
21
18
|
ret = {}
|
|
22
19
|
data = json.load(f)
|
|
23
20
|
for k in data:
|
|
@@ -26,8 +23,7 @@ def load_config(namespace: str) -> Union[dict, bool]:
|
|
|
26
23
|
|
|
27
24
|
|
|
28
25
|
def put_config(namespace: str, name: str, key: str, value, description: str):
|
|
29
|
-
"""
|
|
30
|
-
将配置项写入以namespace为名字的配置文件,如果key不存在于目标配置文件中。当前 value 仅支持 str, int, float, bool, list 类型(暂不支持 dict)。
|
|
26
|
+
"""将配置项写入以namespace为名字的配置文件,如果key不存在于目标配置文件中。当前 value 仅支持 str, int, float, bool, list 类型(暂不支持 dict)。
|
|
31
27
|
namespace: str, 配置的唯一识别符,也就是配置文件的名字。
|
|
32
28
|
name: str, 配置项的显示名字。
|
|
33
29
|
key: str, 配置项的键。
|
|
@@ -51,7 +47,7 @@ def put_config(namespace: str, name: str, key: str, value, description: str):
|
|
|
51
47
|
if not os.path.exists(path):
|
|
52
48
|
with open(path, "w", encoding="utf-8-sig") as f:
|
|
53
49
|
f.write("{}")
|
|
54
|
-
with open(path,
|
|
50
|
+
with open(path, encoding="utf-8-sig") as f:
|
|
55
51
|
d = json.load(f)
|
|
56
52
|
assert isinstance(d, dict)
|
|
57
53
|
if key not in d:
|
|
@@ -69,8 +65,7 @@ def put_config(namespace: str, name: str, key: str, value, description: str):
|
|
|
69
65
|
|
|
70
66
|
|
|
71
67
|
def update_config(namespace: str, key: str, value):
|
|
72
|
-
"""
|
|
73
|
-
更新配置文件中的配置项。
|
|
68
|
+
"""更新配置文件中的配置项。
|
|
74
69
|
namespace: str, 配置的唯一识别符,也就是配置文件的名字。
|
|
75
70
|
key: str, 配置项的键。
|
|
76
71
|
value: str, int, float, bool, list, 配置项的值。
|
|
@@ -78,7 +73,7 @@ def update_config(namespace: str, key: str, value):
|
|
|
78
73
|
path = os.path.join(get_astrbot_data_path(), "config", f"{namespace}.json")
|
|
79
74
|
if not os.path.exists(path):
|
|
80
75
|
raise FileNotFoundError(f"配置文件 {namespace}.json 不存在。")
|
|
81
|
-
with open(path,
|
|
76
|
+
with open(path, encoding="utf-8-sig") as f:
|
|
82
77
|
d = json.load(f)
|
|
83
78
|
assert isinstance(d, dict)
|
|
84
79
|
if key not in d:
|
astrbot/core/star/context.py
CHANGED
|
@@ -1,48 +1,51 @@
|
|
|
1
|
+
import logging
|
|
1
2
|
from asyncio import Queue
|
|
2
|
-
from
|
|
3
|
+
from collections.abc import Awaitable, Callable
|
|
4
|
+
from typing import Any
|
|
3
5
|
|
|
4
|
-
from
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
STTProvider,
|
|
8
|
-
EmbeddingProvider,
|
|
9
|
-
RerankProvider,
|
|
10
|
-
)
|
|
11
|
-
from astrbot.core.provider.entities import ProviderType
|
|
12
|
-
from astrbot.core.db import BaseDatabase
|
|
6
|
+
from deprecated import deprecated
|
|
7
|
+
|
|
8
|
+
from astrbot.core.astrbot_config_mgr import AstrBotConfigManager
|
|
13
9
|
from astrbot.core.config.astrbot_config import AstrBotConfig
|
|
14
|
-
from astrbot.core.
|
|
15
|
-
from astrbot.core.
|
|
10
|
+
from astrbot.core.conversation_mgr import ConversationManager
|
|
11
|
+
from astrbot.core.db import BaseDatabase
|
|
12
|
+
from astrbot.core.knowledge_base.kb_mgr import KnowledgeBaseManager
|
|
16
13
|
from astrbot.core.message.message_event_result import MessageChain
|
|
17
|
-
from astrbot.core.
|
|
14
|
+
from astrbot.core.persona_mgr import PersonaManager
|
|
18
15
|
from astrbot.core.platform import Platform
|
|
16
|
+
from astrbot.core.platform.astr_message_event import MessageSesion
|
|
19
17
|
from astrbot.core.platform.manager import PlatformManager
|
|
20
18
|
from astrbot.core.platform_message_history_mgr import PlatformMessageHistoryManager
|
|
21
|
-
from astrbot.core.
|
|
22
|
-
from astrbot.core.
|
|
23
|
-
from astrbot.core.
|
|
24
|
-
from .
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
19
|
+
from astrbot.core.provider.entities import ProviderType
|
|
20
|
+
from astrbot.core.provider.func_tool_manager import FunctionTool, FunctionToolManager
|
|
21
|
+
from astrbot.core.provider.manager import ProviderManager
|
|
22
|
+
from astrbot.core.provider.provider import (
|
|
23
|
+
EmbeddingProvider,
|
|
24
|
+
Provider,
|
|
25
|
+
RerankProvider,
|
|
26
|
+
STTProvider,
|
|
27
|
+
TTSProvider,
|
|
28
|
+
)
|
|
30
29
|
from astrbot.core.star.filter.platform_adapter_type import (
|
|
31
|
-
PlatformAdapterType,
|
|
32
30
|
ADAPTER_NAME_2_TYPE,
|
|
31
|
+
PlatformAdapterType,
|
|
33
32
|
)
|
|
34
|
-
|
|
33
|
+
|
|
34
|
+
from .filter.command import CommandFilter
|
|
35
|
+
from .filter.regex import RegexFilter
|
|
36
|
+
from .star import StarMetadata, star_map, star_registry
|
|
37
|
+
from .star_handler import EventType, StarHandlerMetadata, star_handlers_registry
|
|
38
|
+
|
|
39
|
+
logger = logging.getLogger("astrbot")
|
|
35
40
|
|
|
36
41
|
|
|
37
42
|
class Context:
|
|
38
|
-
"""
|
|
39
|
-
暴露给插件的接口上下文。
|
|
40
|
-
"""
|
|
43
|
+
"""暴露给插件的接口上下文。"""
|
|
41
44
|
|
|
42
45
|
registered_web_apis: list = []
|
|
43
46
|
|
|
44
47
|
# back compatibility
|
|
45
|
-
_register_tasks:
|
|
48
|
+
_register_tasks: list[Awaitable] = []
|
|
46
49
|
_star_manager = None
|
|
47
50
|
|
|
48
51
|
def __init__(
|
|
@@ -78,7 +81,7 @@ class Context:
|
|
|
78
81
|
if star.name == star_name:
|
|
79
82
|
return star
|
|
80
83
|
|
|
81
|
-
def get_all_stars(self) ->
|
|
84
|
+
def get_all_stars(self) -> list[StarMetadata]:
|
|
82
85
|
"""获取当前载入的所有插件 Metadata 的列表"""
|
|
83
86
|
return star_registry
|
|
84
87
|
|
|
@@ -91,6 +94,7 @@ class Context:
|
|
|
91
94
|
|
|
92
95
|
Returns:
|
|
93
96
|
如果没找到,会返回 False
|
|
97
|
+
|
|
94
98
|
"""
|
|
95
99
|
return self.provider_manager.llm_tools.activate_llm_tool(name, star_map)
|
|
96
100
|
|
|
@@ -98,17 +102,18 @@ class Context:
|
|
|
98
102
|
"""停用一个已经注册的函数调用工具。
|
|
99
103
|
|
|
100
104
|
Returns:
|
|
101
|
-
如果没找到,会返回 False
|
|
105
|
+
如果没找到,会返回 False
|
|
106
|
+
|
|
107
|
+
"""
|
|
102
108
|
return self.provider_manager.llm_tools.deactivate_llm_tool(name)
|
|
103
109
|
|
|
104
110
|
def register_provider(self, provider: Provider):
|
|
105
|
-
"""
|
|
106
|
-
注册一个 LLM Provider(Chat_Completion 类型)。
|
|
107
|
-
"""
|
|
111
|
+
"""注册一个 LLM Provider(Chat_Completion 类型)。"""
|
|
108
112
|
self.provider_manager.provider_insts.append(provider)
|
|
109
113
|
|
|
110
114
|
def get_provider_by_id(
|
|
111
|
-
self,
|
|
115
|
+
self,
|
|
116
|
+
provider_id: str,
|
|
112
117
|
) -> (
|
|
113
118
|
Provider | TTSProvider | STTProvider | EmbeddingProvider | RerankProvider | None
|
|
114
119
|
):
|
|
@@ -116,28 +121,28 @@ class Context:
|
|
|
116
121
|
prov = self.provider_manager.inst_map.get(provider_id)
|
|
117
122
|
return prov
|
|
118
123
|
|
|
119
|
-
def get_all_providers(self) ->
|
|
124
|
+
def get_all_providers(self) -> list[Provider]:
|
|
120
125
|
"""获取所有用于文本生成任务的 LLM Provider(Chat_Completion 类型)。"""
|
|
121
126
|
return self.provider_manager.provider_insts
|
|
122
127
|
|
|
123
|
-
def get_all_tts_providers(self) ->
|
|
128
|
+
def get_all_tts_providers(self) -> list[TTSProvider]:
|
|
124
129
|
"""获取所有用于 TTS 任务的 Provider。"""
|
|
125
130
|
return self.provider_manager.tts_provider_insts
|
|
126
131
|
|
|
127
|
-
def get_all_stt_providers(self) ->
|
|
132
|
+
def get_all_stt_providers(self) -> list[STTProvider]:
|
|
128
133
|
"""获取所有用于 STT 任务的 Provider。"""
|
|
129
134
|
return self.provider_manager.stt_provider_insts
|
|
130
135
|
|
|
131
|
-
def get_all_embedding_providers(self) ->
|
|
136
|
+
def get_all_embedding_providers(self) -> list[EmbeddingProvider]:
|
|
132
137
|
"""获取所有用于 Embedding 任务的 Provider。"""
|
|
133
138
|
return self.provider_manager.embedding_provider_insts
|
|
134
139
|
|
|
135
140
|
def get_using_provider(self, umo: str | None = None) -> Provider | None:
|
|
136
|
-
"""
|
|
137
|
-
获取当前使用的用于文本生成任务的 LLM Provider(Chat_Completion 类型)。通过 /provider 指令切换。
|
|
141
|
+
"""获取当前使用的用于文本生成任务的 LLM Provider(Chat_Completion 类型)。通过 /provider 指令切换。
|
|
138
142
|
|
|
139
143
|
Args:
|
|
140
144
|
umo(str): unified_message_origin 值,如果传入并且用户启用了提供商会话隔离,则使用该会话偏好的提供商。
|
|
145
|
+
|
|
141
146
|
"""
|
|
142
147
|
prov = self.provider_manager.get_using_provider(
|
|
143
148
|
provider_type=ProviderType.CHAT_COMPLETION,
|
|
@@ -148,11 +153,11 @@ class Context:
|
|
|
148
153
|
return prov
|
|
149
154
|
|
|
150
155
|
def get_using_tts_provider(self, umo: str | None = None) -> TTSProvider | None:
|
|
151
|
-
"""
|
|
152
|
-
获取当前使用的用于 TTS 任务的 Provider。
|
|
156
|
+
"""获取当前使用的用于 TTS 任务的 Provider。
|
|
153
157
|
|
|
154
158
|
Args:
|
|
155
159
|
umo(str): unified_message_origin 值,如果传入,则使用该会话偏好的提供商。
|
|
160
|
+
|
|
156
161
|
"""
|
|
157
162
|
prov = self.provider_manager.get_using_provider(
|
|
158
163
|
provider_type=ProviderType.TEXT_TO_SPEECH,
|
|
@@ -163,11 +168,11 @@ class Context:
|
|
|
163
168
|
return prov
|
|
164
169
|
|
|
165
170
|
def get_using_stt_provider(self, umo: str | None = None) -> STTProvider | None:
|
|
166
|
-
"""
|
|
167
|
-
获取当前使用的用于 STT 任务的 Provider。
|
|
171
|
+
"""获取当前使用的用于 STT 任务的 Provider。
|
|
168
172
|
|
|
169
173
|
Args:
|
|
170
174
|
umo(str): unified_message_origin 值,如果传入,则使用该会话偏好的提供商。
|
|
175
|
+
|
|
171
176
|
"""
|
|
172
177
|
prov = self.provider_manager.get_using_provider(
|
|
173
178
|
provider_type=ProviderType.SPEECH_TO_TEXT,
|
|
@@ -182,25 +187,19 @@ class Context:
|
|
|
182
187
|
if not umo:
|
|
183
188
|
# using default config
|
|
184
189
|
return self._config
|
|
185
|
-
|
|
186
|
-
return self.astrbot_config_mgr.get_conf(umo)
|
|
190
|
+
return self.astrbot_config_mgr.get_conf(umo)
|
|
187
191
|
|
|
188
192
|
def get_db(self) -> BaseDatabase:
|
|
189
193
|
"""获取 AstrBot 数据库。"""
|
|
190
194
|
return self._db
|
|
191
195
|
|
|
192
196
|
def get_event_queue(self) -> Queue:
|
|
193
|
-
"""
|
|
194
|
-
获取事件队列。
|
|
195
|
-
"""
|
|
197
|
+
"""获取事件队列。"""
|
|
196
198
|
return self._event_queue
|
|
197
199
|
|
|
198
200
|
@deprecated(version="4.0.0", reason="Use get_platform_inst instead")
|
|
199
|
-
def get_platform(
|
|
200
|
-
|
|
201
|
-
) -> Platform | None:
|
|
202
|
-
"""
|
|
203
|
-
获取指定类型的平台适配器。
|
|
201
|
+
def get_platform(self, platform_type: PlatformAdapterType | str) -> Platform | None:
|
|
202
|
+
"""获取指定类型的平台适配器。
|
|
204
203
|
|
|
205
204
|
该方法已经过时,请使用 get_platform_inst 方法。(>= AstrBot v4.0.0)
|
|
206
205
|
"""
|
|
@@ -209,32 +208,32 @@ class Context:
|
|
|
209
208
|
if isinstance(platform_type, str):
|
|
210
209
|
if name == platform_type:
|
|
211
210
|
return platform
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
return platform
|
|
211
|
+
elif (
|
|
212
|
+
name in ADAPTER_NAME_2_TYPE
|
|
213
|
+
and ADAPTER_NAME_2_TYPE[name] & platform_type
|
|
214
|
+
):
|
|
215
|
+
return platform
|
|
218
216
|
|
|
219
217
|
def get_platform_inst(self, platform_id: str) -> Platform | None:
|
|
220
|
-
"""
|
|
221
|
-
获取指定 ID 的平台适配器实例。
|
|
218
|
+
"""获取指定 ID 的平台适配器实例。
|
|
222
219
|
|
|
223
220
|
Args:
|
|
224
221
|
platform_id (str): 平台适配器的唯一标识符。你可以通过 event.get_platform_id() 获取。
|
|
225
222
|
|
|
226
223
|
Returns:
|
|
227
224
|
Platform: 平台适配器实例,如果未找到则返回 None。
|
|
225
|
+
|
|
228
226
|
"""
|
|
229
227
|
for platform in self.platform_manager.platform_insts:
|
|
230
228
|
if platform.meta().id == platform_id:
|
|
231
229
|
return platform
|
|
232
230
|
|
|
233
231
|
async def send_message(
|
|
234
|
-
self,
|
|
232
|
+
self,
|
|
233
|
+
session: str | MessageSesion,
|
|
234
|
+
message_chain: MessageChain,
|
|
235
235
|
) -> bool:
|
|
236
|
-
"""
|
|
237
|
-
根据 session(unified_msg_origin) 主动发送消息。
|
|
236
|
+
"""根据 session(unified_msg_origin) 主动发送消息。
|
|
238
237
|
|
|
239
238
|
@param session: 消息会话。通过 event.session 或者 event.unified_msg_origin 获取。
|
|
240
239
|
@param message_chain: 消息链。
|
|
@@ -245,7 +244,6 @@ class Context:
|
|
|
245
244
|
|
|
246
245
|
NOTE: qq_official(QQ 官方 API 平台) 不支持此方法
|
|
247
246
|
"""
|
|
248
|
-
|
|
249
247
|
if isinstance(session, str):
|
|
250
248
|
try:
|
|
251
249
|
session = MessageSesion.from_str(session)
|
|
@@ -258,6 +256,46 @@ class Context:
|
|
|
258
256
|
return True
|
|
259
257
|
return False
|
|
260
258
|
|
|
259
|
+
def add_llm_tools(self, *tools: FunctionTool) -> None:
|
|
260
|
+
"""添加 LLM 工具。"""
|
|
261
|
+
tool_name = {tool.name for tool in self.provider_manager.llm_tools.func_list}
|
|
262
|
+
module_path = ""
|
|
263
|
+
for tool in tools:
|
|
264
|
+
if not module_path:
|
|
265
|
+
_parts = []
|
|
266
|
+
module_part = tool.__module__.split(".")
|
|
267
|
+
flags = ["packages", "plugins"]
|
|
268
|
+
for i, part in enumerate(module_part):
|
|
269
|
+
_parts.append(part)
|
|
270
|
+
if part in flags and i + 1 < len(module_part):
|
|
271
|
+
_parts.append(module_part[i + 1])
|
|
272
|
+
break
|
|
273
|
+
tool.handler_module_path = ".".join(_parts)
|
|
274
|
+
module_path = tool.handler_module_path
|
|
275
|
+
else:
|
|
276
|
+
tool.handler_module_path = module_path
|
|
277
|
+
logger.info(
|
|
278
|
+
f"plugin(module_path {module_path}) added LLM tool: {tool.name}"
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
if tool.name in tool_name:
|
|
282
|
+
logger.warning("替换已存在的 LLM 工具: " + tool.name)
|
|
283
|
+
self.provider_manager.llm_tools.remove_func(tool.name)
|
|
284
|
+
self.provider_manager.llm_tools.func_list.append(tool)
|
|
285
|
+
|
|
286
|
+
def register_web_api(
|
|
287
|
+
self,
|
|
288
|
+
route: str,
|
|
289
|
+
view_handler: Awaitable,
|
|
290
|
+
methods: list,
|
|
291
|
+
desc: str,
|
|
292
|
+
):
|
|
293
|
+
for idx, api in enumerate(self.registered_web_apis):
|
|
294
|
+
if api[0] == route and methods == api[2]:
|
|
295
|
+
self.registered_web_apis[idx] = (route, view_handler, methods, desc)
|
|
296
|
+
return
|
|
297
|
+
self.registered_web_apis.append((route, view_handler, methods, desc))
|
|
298
|
+
|
|
261
299
|
"""
|
|
262
300
|
以下的方法已经不推荐使用。请从 AstrBot 文档查看更好的注册方式。
|
|
263
301
|
"""
|
|
@@ -269,8 +307,7 @@ class Context:
|
|
|
269
307
|
desc: str,
|
|
270
308
|
func_obj: Callable[..., Awaitable[Any]],
|
|
271
309
|
) -> None:
|
|
272
|
-
"""
|
|
273
|
-
为函数调用(function-calling / tools-use)添加工具。
|
|
310
|
+
"""[DEPRECATED]为函数调用(function-calling / tools-use)添加工具。
|
|
274
311
|
|
|
275
312
|
@param name: 函数名
|
|
276
313
|
@param func_args: 函数参数列表,格式为 [{"type": "string", "name": "arg_name", "description": "arg_description"}, ...]
|
|
@@ -292,7 +329,7 @@ class Context:
|
|
|
292
329
|
self.provider_manager.llm_tools.add_func(name, func_args, desc, func_obj)
|
|
293
330
|
|
|
294
331
|
def unregister_llm_tool(self, name: str) -> None:
|
|
295
|
-
"""删除一个函数调用工具。如果再要启用,需要重新注册。"""
|
|
332
|
+
"""[DEPRECATED]删除一个函数调用工具。如果再要启用,需要重新注册。"""
|
|
296
333
|
self.provider_manager.llm_tools.remove_func(name)
|
|
297
334
|
|
|
298
335
|
def register_commands(
|
|
@@ -305,8 +342,7 @@ class Context:
|
|
|
305
342
|
use_regex=False,
|
|
306
343
|
ignore_prefix=False,
|
|
307
344
|
):
|
|
308
|
-
"""
|
|
309
|
-
注册一个命令。
|
|
345
|
+
"""注册一个命令。
|
|
310
346
|
|
|
311
347
|
[Deprecated] 推荐使用装饰器注册指令。该方法将在未来的版本中被移除。
|
|
312
348
|
|
|
@@ -330,21 +366,10 @@ class Context:
|
|
|
330
366
|
md.event_filters.append(RegexFilter(regex=command_name))
|
|
331
367
|
else:
|
|
332
368
|
md.event_filters.append(
|
|
333
|
-
CommandFilter(command_name=command_name, handler_md=md)
|
|
369
|
+
CommandFilter(command_name=command_name, handler_md=md),
|
|
334
370
|
)
|
|
335
371
|
star_handlers_registry.append(md)
|
|
336
372
|
|
|
337
373
|
def register_task(self, task: Awaitable, desc: str):
|
|
338
|
-
"""
|
|
339
|
-
注册一个异步任务。
|
|
340
|
-
"""
|
|
374
|
+
"""[DEPRECATED]注册一个异步任务。"""
|
|
341
375
|
self._register_tasks.append(task)
|
|
342
|
-
|
|
343
|
-
def register_web_api(
|
|
344
|
-
self, route: str, view_handler: Awaitable, methods: list, desc: str
|
|
345
|
-
):
|
|
346
|
-
for idx, api in enumerate(self.registered_web_apis):
|
|
347
|
-
if api[0] == route and methods == api[2]:
|
|
348
|
-
self.registered_web_apis[idx] = (route, view_handler, methods, desc)
|
|
349
|
-
return
|
|
350
|
-
self.registered_web_apis.append((route, view_handler, methods, desc))
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import abc
|
|
2
|
-
|
|
3
|
-
from astrbot.core.platform.astr_message_event import AstrMessageEvent
|
|
2
|
+
|
|
4
3
|
from astrbot.core.config import AstrBotConfig
|
|
4
|
+
from astrbot.core.platform.astr_message_event import AstrMessageEvent
|
|
5
|
+
from astrbot.core.platform.message_type import MessageType
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
class HandlerFilter(abc.ABC):
|
|
@@ -11,4 +12,4 @@ class HandlerFilter(abc.ABC):
|
|
|
11
12
|
raise NotImplementedError
|
|
12
13
|
|
|
13
14
|
|
|
14
|
-
__all__ = ["
|
|
15
|
+
__all__ = ["AstrBotConfig", "AstrMessageEvent", "HandlerFilter", "MessageType"]
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import re
|
|
2
1
|
import inspect
|
|
2
|
+
import re
|
|
3
3
|
import types
|
|
4
4
|
import typing
|
|
5
|
-
from typing import
|
|
6
|
-
|
|
7
|
-
from astrbot.core.platform.astr_message_event import AstrMessageEvent
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
8
7
|
from astrbot.core.config import AstrBotConfig
|
|
9
|
-
from .
|
|
8
|
+
from astrbot.core.platform.astr_message_event import AstrMessageEvent
|
|
9
|
+
|
|
10
10
|
from ..star_handler import StarHandlerMetadata
|
|
11
|
+
from . import HandlerFilter
|
|
12
|
+
from .custom_filter import CustomFilter
|
|
11
13
|
|
|
12
14
|
|
|
13
15
|
class GreedyStr(str):
|
|
14
16
|
"""标记指令完成其他参数接收后的所有剩余文本。"""
|
|
15
17
|
|
|
16
|
-
pass
|
|
17
|
-
|
|
18
18
|
|
|
19
19
|
def unwrap_optional(annotation) -> tuple:
|
|
20
20
|
"""去掉 Optional[T] / Union[T, None] / T|None,返回 T"""
|
|
@@ -22,10 +22,9 @@ def unwrap_optional(annotation) -> tuple:
|
|
|
22
22
|
non_none_args = [a for a in args if a is not type(None)]
|
|
23
23
|
if len(non_none_args) == 1:
|
|
24
24
|
return (non_none_args[0],)
|
|
25
|
-
|
|
25
|
+
if len(non_none_args) > 1:
|
|
26
26
|
return tuple(non_none_args)
|
|
27
|
-
|
|
28
|
-
return ()
|
|
27
|
+
return ()
|
|
29
28
|
|
|
30
29
|
|
|
31
30
|
# 标准指令受到 wake_prefix 的制约。
|
|
@@ -37,28 +36,30 @@ class CommandFilter(HandlerFilter):
|
|
|
37
36
|
command_name: str,
|
|
38
37
|
alias: set | None = None,
|
|
39
38
|
handler_md: StarHandlerMetadata | None = None,
|
|
40
|
-
parent_command_names:
|
|
39
|
+
parent_command_names: list[str] | None = None,
|
|
41
40
|
):
|
|
42
41
|
self.command_name = command_name
|
|
43
42
|
self.alias = alias if alias else set()
|
|
44
|
-
self.parent_command_names =
|
|
43
|
+
self.parent_command_names = (
|
|
44
|
+
parent_command_names if parent_command_names is not None else [""]
|
|
45
|
+
)
|
|
45
46
|
if handler_md:
|
|
46
47
|
self.init_handler_md(handler_md)
|
|
47
|
-
self.custom_filter_list:
|
|
48
|
+
self.custom_filter_list: list[CustomFilter] = []
|
|
48
49
|
|
|
49
50
|
# Cache for complete command names list
|
|
50
51
|
self._cmpl_cmd_names: list | None = None
|
|
51
52
|
|
|
52
53
|
def print_types(self):
|
|
53
|
-
|
|
54
|
+
parts = []
|
|
54
55
|
for k, v in self.handler_params.items():
|
|
55
56
|
if isinstance(v, type):
|
|
56
|
-
|
|
57
|
+
parts.append(f"{k}({v.__name__}),")
|
|
57
58
|
elif isinstance(v, types.UnionType) or typing.get_origin(v) is typing.Union:
|
|
58
|
-
|
|
59
|
+
parts.append(f"{k}({v}),")
|
|
59
60
|
else:
|
|
60
|
-
|
|
61
|
-
result =
|
|
61
|
+
parts.append(f"{k}({type(v).__name__})={v},")
|
|
62
|
+
result = "".join(parts).rstrip(",")
|
|
62
63
|
return result
|
|
63
64
|
|
|
64
65
|
def init_handler_md(self, handle_md: StarHandlerMetadata):
|
|
@@ -89,8 +90,10 @@ class CommandFilter(HandlerFilter):
|
|
|
89
90
|
return True
|
|
90
91
|
|
|
91
92
|
def validate_and_convert_params(
|
|
92
|
-
self,
|
|
93
|
-
|
|
93
|
+
self,
|
|
94
|
+
params: list[Any],
|
|
95
|
+
param_type: dict[str, type],
|
|
96
|
+
) -> dict[str, Any]:
|
|
94
97
|
"""将参数列表 params 根据 param_type 转换为参数字典。"""
|
|
95
98
|
result = {}
|
|
96
99
|
param_items = list(param_type.items())
|
|
@@ -101,7 +104,7 @@ class CommandFilter(HandlerFilter):
|
|
|
101
104
|
# GreedyStr 必须是最后一个参数
|
|
102
105
|
if i != len(param_items) - 1:
|
|
103
106
|
raise ValueError(
|
|
104
|
-
f"参数 '{param_name}' (GreedyStr) 必须是最后一个参数。"
|
|
107
|
+
f"参数 '{param_name}' (GreedyStr) 必须是最后一个参数。",
|
|
105
108
|
)
|
|
106
109
|
|
|
107
110
|
# 将剩余的所有部分合并成一个字符串
|
|
@@ -111,17 +114,16 @@ class CommandFilter(HandlerFilter):
|
|
|
111
114
|
# 没有 GreedyStr 的情况
|
|
112
115
|
if i >= len(params):
|
|
113
116
|
if (
|
|
114
|
-
isinstance(param_type_or_default_val, (
|
|
117
|
+
isinstance(param_type_or_default_val, (type, types.UnionType))
|
|
115
118
|
or typing.get_origin(param_type_or_default_val) is typing.Union
|
|
116
119
|
or param_type_or_default_val is inspect.Parameter.empty
|
|
117
120
|
):
|
|
118
121
|
# 是类型
|
|
119
122
|
raise ValueError(
|
|
120
|
-
f"必要参数缺失。该指令完整参数: {self.print_types()}"
|
|
123
|
+
f"必要参数缺失。该指令完整参数: {self.print_types()}",
|
|
121
124
|
)
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
result[param_name] = param_type_or_default_val
|
|
125
|
+
# 是默认值
|
|
126
|
+
result[param_name] = param_type_or_default_val
|
|
125
127
|
else:
|
|
126
128
|
# 尝试强制转换
|
|
127
129
|
try:
|
|
@@ -142,7 +144,7 @@ class CommandFilter(HandlerFilter):
|
|
|
142
144
|
result[param_name] = False
|
|
143
145
|
else:
|
|
144
146
|
raise ValueError(
|
|
145
|
-
f"参数 {param_name} 必须是布尔值(true/false, yes/no, 1/0)。"
|
|
147
|
+
f"参数 {param_name} 必须是布尔值(true/false, yes/no, 1/0)。",
|
|
146
148
|
)
|
|
147
149
|
elif isinstance(param_type_or_default_val, int):
|
|
148
150
|
result[param_name] = int(params[i])
|
|
@@ -165,7 +167,7 @@ class CommandFilter(HandlerFilter):
|
|
|
165
167
|
result[param_name] = param_type_or_default_val(params[i])
|
|
166
168
|
except ValueError:
|
|
167
169
|
raise ValueError(
|
|
168
|
-
f"参数 {param_name} 类型错误。完整参数: {self.print_types()}"
|
|
170
|
+
f"参数 {param_name} 类型错误。完整参数: {self.print_types()}",
|
|
169
171
|
)
|
|
170
172
|
return result
|
|
171
173
|
|