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/core_lifecycle.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
"""
|
|
2
|
-
|
|
1
|
+
"""Astrbot 核心生命周期管理类, 负责管理 AstrBot 的启动、停止、重启等操作.
|
|
2
|
+
|
|
3
3
|
该类负责初始化各个组件, 包括 ProviderManager、PlatformManager、ConversationManager、PluginManager、PipelineScheduler、EventBus等。
|
|
4
4
|
该类还负责加载和执行插件, 以及处理事件总线的分发。
|
|
5
5
|
|
|
@@ -9,44 +9,44 @@ Astrbot 核心生命周期管理类, 负责管理 AstrBot 的启动、停止、
|
|
|
9
9
|
3. 执行启动完成事件钩子
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
|
-
import traceback
|
|
13
12
|
import asyncio
|
|
14
|
-
import time
|
|
15
|
-
import threading
|
|
16
13
|
import os
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
import threading
|
|
15
|
+
import time
|
|
16
|
+
import traceback
|
|
19
17
|
from asyncio import Queue
|
|
20
|
-
|
|
21
|
-
from astrbot.core
|
|
22
|
-
from astrbot.core.
|
|
23
|
-
from astrbot.core.star.context import Context
|
|
24
|
-
from astrbot.core.persona_mgr import PersonaManager
|
|
25
|
-
from astrbot.core.provider.manager import ProviderManager
|
|
26
|
-
from astrbot.core import LogBroker
|
|
27
|
-
from astrbot.core.db import BaseDatabase
|
|
28
|
-
from astrbot.core.db.migration.migra_45_to_46 import migrate_45_to_46
|
|
29
|
-
from astrbot.core.updator import AstrBotUpdator
|
|
30
|
-
from astrbot.core import logger, sp
|
|
18
|
+
|
|
19
|
+
from astrbot.core import LogBroker, logger, sp
|
|
20
|
+
from astrbot.core.astrbot_config_mgr import AstrBotConfigManager
|
|
31
21
|
from astrbot.core.config.default import VERSION
|
|
32
22
|
from astrbot.core.conversation_mgr import ConversationManager
|
|
23
|
+
from astrbot.core.db import BaseDatabase
|
|
24
|
+
from astrbot.core.db.migration.migra_45_to_46 import migrate_45_to_46
|
|
25
|
+
from astrbot.core.knowledge_base.kb_mgr import KnowledgeBaseManager
|
|
26
|
+
from astrbot.core.persona_mgr import PersonaManager
|
|
27
|
+
from astrbot.core.pipeline.scheduler import PipelineContext, PipelineScheduler
|
|
28
|
+
from astrbot.core.platform.manager import PlatformManager
|
|
33
29
|
from astrbot.core.platform_message_history_mgr import PlatformMessageHistoryManager
|
|
30
|
+
from astrbot.core.provider.manager import ProviderManager
|
|
31
|
+
from astrbot.core.star import PluginManager
|
|
32
|
+
from astrbot.core.star.context import Context
|
|
33
|
+
from astrbot.core.star.star_handler import EventType, star_handlers_registry, star_map
|
|
34
34
|
from astrbot.core.umop_config_router import UmopConfigRouter
|
|
35
|
-
from astrbot.core.
|
|
36
|
-
|
|
37
|
-
from
|
|
38
|
-
from
|
|
35
|
+
from astrbot.core.updator import AstrBotUpdator
|
|
36
|
+
|
|
37
|
+
from . import astrbot_config, html_renderer
|
|
38
|
+
from .event_bus import EventBus
|
|
39
39
|
|
|
40
40
|
|
|
41
41
|
class AstrBotCoreLifecycle:
|
|
42
|
-
"""
|
|
43
|
-
|
|
42
|
+
"""AstrBot 核心生命周期管理类, 负责管理 AstrBot 的启动、停止、重启等操作.
|
|
43
|
+
|
|
44
44
|
该类负责初始化各个组件, 包括 ProviderManager、PlatformManager、ConversationManager、PluginManager、PipelineScheduler、
|
|
45
45
|
EventBus 等。
|
|
46
46
|
该类还负责加载和执行插件, 以及处理事件总线的分发。
|
|
47
47
|
"""
|
|
48
48
|
|
|
49
|
-
def __init__(self, log_broker: LogBroker, db: BaseDatabase):
|
|
49
|
+
def __init__(self, log_broker: LogBroker, db: BaseDatabase) -> None:
|
|
50
50
|
self.log_broker = log_broker # 初始化日志代理
|
|
51
51
|
self.astrbot_config = astrbot_config # 初始化配置
|
|
52
52
|
self.db = db # 初始化数据库
|
|
@@ -70,11 +70,11 @@ class AstrBotCoreLifecycle:
|
|
|
70
70
|
del os.environ["no_proxy"]
|
|
71
71
|
logger.debug("HTTP proxy cleared")
|
|
72
72
|
|
|
73
|
-
async def initialize(self):
|
|
74
|
-
"""
|
|
75
|
-
初始化 AstrBot 核心生命周期管理类, 负责初始化各个组件, 包括 ProviderManager、PlatformManager、ConversationManager、PluginManager、PipelineScheduler、EventBus、AstrBotUpdator等。
|
|
76
|
-
"""
|
|
73
|
+
async def initialize(self) -> None:
|
|
74
|
+
"""初始化 AstrBot 核心生命周期管理类.
|
|
77
75
|
|
|
76
|
+
负责初始化各个组件, 包括 ProviderManager、PlatformManager、ConversationManager、PluginManager、PipelineScheduler、EventBus、AstrBotUpdator等。
|
|
77
|
+
"""
|
|
78
78
|
# 初始化日志代理
|
|
79
79
|
logger.info("AstrBot v" + VERSION)
|
|
80
80
|
if os.environ.get("TESTING", ""):
|
|
@@ -91,7 +91,9 @@ class AstrBotCoreLifecycle:
|
|
|
91
91
|
|
|
92
92
|
# 初始化 AstrBot 配置管理器
|
|
93
93
|
self.astrbot_config_mgr = AstrBotConfigManager(
|
|
94
|
-
default_config=self.astrbot_config,
|
|
94
|
+
default_config=self.astrbot_config,
|
|
95
|
+
ucr=self.umop_config_router,
|
|
96
|
+
sp=sp,
|
|
95
97
|
)
|
|
96
98
|
|
|
97
99
|
# 4.5 to 4.6 migration for umop_config_router
|
|
@@ -110,7 +112,9 @@ class AstrBotCoreLifecycle:
|
|
|
110
112
|
|
|
111
113
|
# 初始化供应商管理器
|
|
112
114
|
self.provider_manager = ProviderManager(
|
|
113
|
-
self.astrbot_config_mgr,
|
|
115
|
+
self.astrbot_config_mgr,
|
|
116
|
+
self.db,
|
|
117
|
+
self.persona_mgr,
|
|
114
118
|
)
|
|
115
119
|
|
|
116
120
|
# 初始化平台管理器
|
|
@@ -158,7 +162,9 @@ class AstrBotCoreLifecycle:
|
|
|
158
162
|
|
|
159
163
|
# 初始化事件总线
|
|
160
164
|
self.event_bus = EventBus(
|
|
161
|
-
self.event_queue,
|
|
165
|
+
self.event_queue,
|
|
166
|
+
self.pipeline_scheduler_mapping,
|
|
167
|
+
self.astrbot_config_mgr,
|
|
162
168
|
)
|
|
163
169
|
|
|
164
170
|
# 记录启动时间
|
|
@@ -173,13 +179,13 @@ class AstrBotCoreLifecycle:
|
|
|
173
179
|
# 初始化关闭控制面板的事件
|
|
174
180
|
self.dashboard_shutdown_event = asyncio.Event()
|
|
175
181
|
|
|
176
|
-
def _load(self):
|
|
177
|
-
"""
|
|
178
|
-
|
|
182
|
+
def _load(self) -> None:
|
|
183
|
+
"""加载事件总线和任务并初始化."""
|
|
179
184
|
# 创建一个异步任务来执行事件总线的 dispatch() 方法
|
|
180
185
|
# dispatch是一个无限循环的协程, 从事件队列中获取事件并处理
|
|
181
186
|
event_bus_task = asyncio.create_task(
|
|
182
|
-
self.event_bus.dispatch(),
|
|
187
|
+
self.event_bus.dispatch(),
|
|
188
|
+
name="event_bus",
|
|
183
189
|
)
|
|
184
190
|
|
|
185
191
|
# 把插件中注册的所有协程函数注册到事件总线中并执行
|
|
@@ -190,16 +196,17 @@ class AstrBotCoreLifecycle:
|
|
|
190
196
|
tasks_ = [event_bus_task, *extra_tasks]
|
|
191
197
|
for task in tasks_:
|
|
192
198
|
self.curr_tasks.append(
|
|
193
|
-
asyncio.create_task(self._task_wrapper(task), name=task.get_name())
|
|
199
|
+
asyncio.create_task(self._task_wrapper(task), name=task.get_name()),
|
|
194
200
|
)
|
|
195
201
|
|
|
196
202
|
self.start_time = int(time.time())
|
|
197
203
|
|
|
198
|
-
async def _task_wrapper(self, task: asyncio.Task):
|
|
199
|
-
"""异步任务包装器,
|
|
204
|
+
async def _task_wrapper(self, task: asyncio.Task) -> None:
|
|
205
|
+
"""异步任务包装器, 用于处理异步任务执行中出现的各种异常.
|
|
200
206
|
|
|
201
207
|
Args:
|
|
202
208
|
task (asyncio.Task): 要执行的异步任务
|
|
209
|
+
|
|
203
210
|
"""
|
|
204
211
|
try:
|
|
205
212
|
await task
|
|
@@ -212,19 +219,22 @@ class AstrBotCoreLifecycle:
|
|
|
212
219
|
logger.error(f"| {line}")
|
|
213
220
|
logger.error("-------")
|
|
214
221
|
|
|
215
|
-
async def start(self):
|
|
216
|
-
"""启动 AstrBot
|
|
222
|
+
async def start(self) -> None:
|
|
223
|
+
"""启动 AstrBot 核心生命周期管理类.
|
|
224
|
+
|
|
225
|
+
用load加载事件总线和任务并初始化, 执行启动完成事件钩子
|
|
226
|
+
"""
|
|
217
227
|
self._load()
|
|
218
228
|
logger.info("AstrBot 启动完成。")
|
|
219
229
|
|
|
220
230
|
# 执行启动完成事件钩子
|
|
221
231
|
handlers = star_handlers_registry.get_handlers_by_event_type(
|
|
222
|
-
EventType.OnAstrBotLoadedEvent
|
|
232
|
+
EventType.OnAstrBotLoadedEvent,
|
|
223
233
|
)
|
|
224
234
|
for handler in handlers:
|
|
225
235
|
try:
|
|
226
236
|
logger.info(
|
|
227
|
-
f"hook(on_astrbot_loaded) -> {star_map[handler.handler_module_path].name} - {handler.handler_name}"
|
|
237
|
+
f"hook(on_astrbot_loaded) -> {star_map[handler.handler_module_path].name} - {handler.handler_name}",
|
|
228
238
|
)
|
|
229
239
|
await handler.handler()
|
|
230
240
|
except BaseException:
|
|
@@ -233,8 +243,8 @@ class AstrBotCoreLifecycle:
|
|
|
233
243
|
# 同时运行curr_tasks中的所有任务
|
|
234
244
|
await asyncio.gather(*self.curr_tasks, return_exceptions=True)
|
|
235
245
|
|
|
236
|
-
async def stop(self):
|
|
237
|
-
"""停止 AstrBot 核心生命周期管理类,
|
|
246
|
+
async def stop(self) -> None:
|
|
247
|
+
"""停止 AstrBot 核心生命周期管理类, 取消所有当前任务并终止各个管理器."""
|
|
238
248
|
# 请求停止所有正在运行的异步任务
|
|
239
249
|
for task in self.curr_tasks:
|
|
240
250
|
task.cancel()
|
|
@@ -245,7 +255,7 @@ class AstrBotCoreLifecycle:
|
|
|
245
255
|
except Exception as e:
|
|
246
256
|
logger.warning(traceback.format_exc())
|
|
247
257
|
logger.warning(
|
|
248
|
-
f"插件 {plugin.name} 未被正常终止 {e!s}, 可能会导致资源泄露等问题。"
|
|
258
|
+
f"插件 {plugin.name} 未被正常终止 {e!s}, 可能会导致资源泄露等问题。",
|
|
249
259
|
)
|
|
250
260
|
|
|
251
261
|
await self.provider_manager.terminate()
|
|
@@ -262,14 +272,16 @@ class AstrBotCoreLifecycle:
|
|
|
262
272
|
except Exception as e:
|
|
263
273
|
logger.error(f"任务 {task.get_name()} 发生错误: {e}")
|
|
264
274
|
|
|
265
|
-
async def restart(self):
|
|
275
|
+
async def restart(self) -> None:
|
|
266
276
|
"""重启 AstrBot 核心生命周期管理类, 终止各个管理器并重新加载平台实例"""
|
|
267
277
|
await self.provider_manager.terminate()
|
|
268
278
|
await self.platform_manager.terminate()
|
|
269
279
|
await self.kb_manager.terminate()
|
|
270
280
|
self.dashboard_shutdown_event.set()
|
|
271
281
|
threading.Thread(
|
|
272
|
-
target=self.astrbot_updator._reboot,
|
|
282
|
+
target=self.astrbot_updator._reboot,
|
|
283
|
+
name="restart",
|
|
284
|
+
daemon=True,
|
|
273
285
|
).start()
|
|
274
286
|
|
|
275
287
|
def load_platform(self) -> list[asyncio.Task]:
|
|
@@ -281,36 +293,38 @@ class AstrBotCoreLifecycle:
|
|
|
281
293
|
asyncio.create_task(
|
|
282
294
|
platform_inst.run(),
|
|
283
295
|
name=f"{platform_inst.meta().id}({platform_inst.meta().name})",
|
|
284
|
-
)
|
|
296
|
+
),
|
|
285
297
|
)
|
|
286
298
|
return tasks
|
|
287
299
|
|
|
288
300
|
async def load_pipeline_scheduler(self) -> dict[str, PipelineScheduler]:
|
|
289
|
-
"""
|
|
301
|
+
"""加载消息事件流水线调度器.
|
|
290
302
|
|
|
291
303
|
Returns:
|
|
292
304
|
dict[str, PipelineScheduler]: 平台 ID 到流水线调度器的映射
|
|
305
|
+
|
|
293
306
|
"""
|
|
294
307
|
mapping = {}
|
|
295
308
|
for conf_id, ab_config in self.astrbot_config_mgr.confs.items():
|
|
296
309
|
scheduler = PipelineScheduler(
|
|
297
|
-
PipelineContext(ab_config, self.plugin_manager, conf_id)
|
|
310
|
+
PipelineContext(ab_config, self.plugin_manager, conf_id),
|
|
298
311
|
)
|
|
299
312
|
await scheduler.initialize()
|
|
300
313
|
mapping[conf_id] = scheduler
|
|
301
314
|
return mapping
|
|
302
315
|
|
|
303
|
-
async def reload_pipeline_scheduler(self, conf_id: str):
|
|
304
|
-
"""
|
|
316
|
+
async def reload_pipeline_scheduler(self, conf_id: str) -> None:
|
|
317
|
+
"""重新加载消息事件流水线调度器.
|
|
305
318
|
|
|
306
319
|
Returns:
|
|
307
320
|
dict[str, PipelineScheduler]: 平台 ID 到流水线调度器的映射
|
|
321
|
+
|
|
308
322
|
"""
|
|
309
323
|
ab_config = self.astrbot_config_mgr.confs.get(conf_id)
|
|
310
324
|
if not ab_config:
|
|
311
325
|
raise ValueError(f"配置文件 {conf_id} 不存在")
|
|
312
326
|
scheduler = PipelineScheduler(
|
|
313
|
-
PipelineContext(ab_config, self.plugin_manager, conf_id)
|
|
327
|
+
PipelineContext(ab_config, self.plugin_manager, conf_id),
|
|
314
328
|
)
|
|
315
329
|
await scheduler.initialize()
|
|
316
330
|
self.pipeline_scheduler_mapping[conf_id] = scheduler
|
astrbot/core/db/__init__.py
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
import abc
|
|
2
2
|
import datetime
|
|
3
3
|
import typing as T
|
|
4
|
-
from
|
|
4
|
+
from contextlib import asynccontextmanager
|
|
5
5
|
from dataclasses import dataclass
|
|
6
|
+
|
|
7
|
+
from deprecated import deprecated
|
|
8
|
+
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
|
|
9
|
+
from sqlalchemy.orm import sessionmaker
|
|
10
|
+
|
|
6
11
|
from astrbot.core.db.po import (
|
|
7
|
-
Stats,
|
|
8
|
-
PlatformStat,
|
|
9
|
-
ConversationV2,
|
|
10
|
-
PlatformMessageHistory,
|
|
11
12
|
Attachment,
|
|
13
|
+
ConversationV2,
|
|
12
14
|
Persona,
|
|
15
|
+
PlatformMessageHistory,
|
|
16
|
+
PlatformStat,
|
|
13
17
|
Preference,
|
|
18
|
+
Stats,
|
|
14
19
|
)
|
|
15
|
-
from contextlib import asynccontextmanager
|
|
16
|
-
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
|
|
17
|
-
from sqlalchemy.orm import sessionmaker
|
|
18
20
|
|
|
19
21
|
|
|
20
22
|
@dataclass
|
|
21
23
|
class BaseDatabase(abc.ABC):
|
|
22
|
-
"""
|
|
23
|
-
数据库基类
|
|
24
|
-
"""
|
|
24
|
+
"""数据库基类"""
|
|
25
25
|
|
|
26
26
|
DATABASE_URL = ""
|
|
27
27
|
|
|
@@ -32,12 +32,13 @@ class BaseDatabase(abc.ABC):
|
|
|
32
32
|
future=True,
|
|
33
33
|
)
|
|
34
34
|
self.AsyncSessionLocal = sessionmaker(
|
|
35
|
-
self.engine,
|
|
35
|
+
self.engine,
|
|
36
|
+
class_=AsyncSession,
|
|
37
|
+
expire_on_commit=False,
|
|
36
38
|
)
|
|
37
39
|
|
|
38
40
|
async def initialize(self):
|
|
39
41
|
"""初始化数据库连接"""
|
|
40
|
-
pass
|
|
41
42
|
|
|
42
43
|
@asynccontextmanager
|
|
43
44
|
async def get_db(self) -> T.AsyncGenerator[AsyncSession, None]:
|
|
@@ -91,7 +92,9 @@ class BaseDatabase(abc.ABC):
|
|
|
91
92
|
|
|
92
93
|
@abc.abstractmethod
|
|
93
94
|
async def get_conversations(
|
|
94
|
-
self,
|
|
95
|
+
self,
|
|
96
|
+
user_id: str | None = None,
|
|
97
|
+
platform_id: str | None = None,
|
|
95
98
|
) -> list[ConversationV2]:
|
|
96
99
|
"""Get all conversations for a specific user and platform_id(optional).
|
|
97
100
|
|
|
@@ -106,7 +109,9 @@ class BaseDatabase(abc.ABC):
|
|
|
106
109
|
|
|
107
110
|
@abc.abstractmethod
|
|
108
111
|
async def get_all_conversations(
|
|
109
|
-
self,
|
|
112
|
+
self,
|
|
113
|
+
page: int = 1,
|
|
114
|
+
page_size: int = 20,
|
|
110
115
|
) -> list[ConversationV2]:
|
|
111
116
|
"""Get all conversations with pagination."""
|
|
112
117
|
...
|
|
@@ -173,7 +178,10 @@ class BaseDatabase(abc.ABC):
|
|
|
173
178
|
|
|
174
179
|
@abc.abstractmethod
|
|
175
180
|
async def delete_platform_message_offset(
|
|
176
|
-
self,
|
|
181
|
+
self,
|
|
182
|
+
platform_id: str,
|
|
183
|
+
user_id: str,
|
|
184
|
+
offset_sec: int = 86400,
|
|
177
185
|
) -> None:
|
|
178
186
|
"""Delete platform message history records older than the specified offset."""
|
|
179
187
|
...
|
|
@@ -243,7 +251,11 @@ class BaseDatabase(abc.ABC):
|
|
|
243
251
|
|
|
244
252
|
@abc.abstractmethod
|
|
245
253
|
async def insert_preference_or_update(
|
|
246
|
-
self,
|
|
254
|
+
self,
|
|
255
|
+
scope: str,
|
|
256
|
+
scope_id: str,
|
|
257
|
+
key: str,
|
|
258
|
+
value: dict,
|
|
247
259
|
) -> Preference:
|
|
248
260
|
"""Insert a new preference record."""
|
|
249
261
|
...
|
|
@@ -255,7 +267,10 @@ class BaseDatabase(abc.ABC):
|
|
|
255
267
|
|
|
256
268
|
@abc.abstractmethod
|
|
257
269
|
async def get_preferences(
|
|
258
|
-
self,
|
|
270
|
+
self,
|
|
271
|
+
scope: str,
|
|
272
|
+
scope_id: str | None = None,
|
|
273
|
+
key: str | None = None,
|
|
259
274
|
) -> list[Preference]:
|
|
260
275
|
"""Get all preferences for a specific scope ID or key."""
|
|
261
276
|
...
|
|
@@ -1,27 +1,33 @@
|
|
|
1
1
|
import os
|
|
2
|
-
|
|
3
|
-
from astrbot.core.db import BaseDatabase
|
|
4
|
-
from astrbot.core.config import AstrBotConfig
|
|
2
|
+
|
|
5
3
|
from astrbot.api import logger, sp
|
|
4
|
+
from astrbot.core.config import AstrBotConfig
|
|
5
|
+
from astrbot.core.db import BaseDatabase
|
|
6
|
+
from astrbot.core.utils.astrbot_path import get_astrbot_data_path
|
|
7
|
+
|
|
6
8
|
from .migra_3_to_4 import (
|
|
7
9
|
migration_conversation_table,
|
|
8
|
-
migration_platform_table,
|
|
9
|
-
migration_webchat_data,
|
|
10
10
|
migration_persona_data,
|
|
11
|
+
migration_platform_table,
|
|
11
12
|
migration_preferences,
|
|
13
|
+
migration_webchat_data,
|
|
12
14
|
)
|
|
13
15
|
|
|
14
16
|
|
|
15
17
|
async def check_migration_needed_v4(db_helper: BaseDatabase) -> bool:
|
|
16
|
-
"""
|
|
17
|
-
检查是否需要进行数据库迁移
|
|
18
|
+
"""检查是否需要进行数据库迁移
|
|
18
19
|
如果存在 data_v3.db 并且 preference 中没有 migration_done_v4,则需要进行迁移。
|
|
19
20
|
"""
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
# 仅当 data 目录下存在旧版本数据(data_v3.db 文件)时才考虑迁移
|
|
22
|
+
data_dir = get_astrbot_data_path()
|
|
23
|
+
data_v3_db = os.path.join(data_dir, "data_v3.db")
|
|
24
|
+
|
|
25
|
+
if not os.path.exists(data_v3_db):
|
|
22
26
|
return False
|
|
23
27
|
migration_done = await db_helper.get_preference(
|
|
24
|
-
"global",
|
|
28
|
+
"global",
|
|
29
|
+
"global",
|
|
30
|
+
"migration_done_v4",
|
|
25
31
|
)
|
|
26
32
|
if migration_done:
|
|
27
33
|
return False
|
|
@@ -32,9 +38,8 @@ async def do_migration_v4(
|
|
|
32
38
|
db_helper: BaseDatabase,
|
|
33
39
|
platform_id_map: dict[str, dict[str, str]],
|
|
34
40
|
astrbot_config: AstrBotConfig,
|
|
35
|
-
):
|
|
36
|
-
"""
|
|
37
|
-
执行数据库迁移
|
|
41
|
+
) -> None:
|
|
42
|
+
"""执行数据库迁移
|
|
38
43
|
迁移旧的 webchat_conversation 表到新的 conversation 表。
|
|
39
44
|
迁移旧的 platform 到新的 platform_stats 表。
|
|
40
45
|
"""
|
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
import json
|
|
2
1
|
import datetime
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
from
|
|
6
|
-
from
|
|
2
|
+
import json
|
|
3
|
+
|
|
4
|
+
from sqlalchemy import text
|
|
5
|
+
from sqlalchemy.ext.asyncio import AsyncSession
|
|
6
|
+
|
|
7
7
|
from astrbot.api import logger, sp
|
|
8
8
|
from astrbot.core.config import AstrBotConfig
|
|
9
|
-
from astrbot.core.
|
|
10
|
-
from sqlalchemy.ext.asyncio import AsyncSession
|
|
9
|
+
from astrbot.core.config.default import DB_PATH
|
|
11
10
|
from astrbot.core.db.po import ConversationV2, PlatformMessageHistory
|
|
12
|
-
from
|
|
11
|
+
from astrbot.core.platform.astr_message_event import MessageSesion
|
|
12
|
+
|
|
13
|
+
from .. import BaseDatabase
|
|
14
|
+
from .shared_preferences_v3 import sp as sp_v3
|
|
15
|
+
from .sqlite_v3 import SQLiteDatabase as SQLiteV3DatabaseV3
|
|
13
16
|
|
|
14
17
|
"""
|
|
15
18
|
1. 迁移旧的 webchat_conversation 表到新的 conversation 表。
|
|
@@ -18,7 +21,8 @@ from sqlalchemy import text
|
|
|
18
21
|
|
|
19
22
|
|
|
20
23
|
def get_platform_id(
|
|
21
|
-
platform_id_map: dict[str, dict[str, str]],
|
|
24
|
+
platform_id_map: dict[str, dict[str, str]],
|
|
25
|
+
old_platform_name: str,
|
|
22
26
|
) -> str:
|
|
23
27
|
return platform_id_map.get(
|
|
24
28
|
old_platform_name,
|
|
@@ -27,7 +31,8 @@ def get_platform_id(
|
|
|
27
31
|
|
|
28
32
|
|
|
29
33
|
def get_platform_type(
|
|
30
|
-
platform_id_map: dict[str, dict[str, str]],
|
|
34
|
+
platform_id_map: dict[str, dict[str, str]],
|
|
35
|
+
old_platform_name: str,
|
|
31
36
|
) -> str:
|
|
32
37
|
return platform_id_map.get(
|
|
33
38
|
old_platform_name,
|
|
@@ -36,13 +41,15 @@ def get_platform_type(
|
|
|
36
41
|
|
|
37
42
|
|
|
38
43
|
async def migration_conversation_table(
|
|
39
|
-
db_helper: BaseDatabase,
|
|
44
|
+
db_helper: BaseDatabase,
|
|
45
|
+
platform_id_map: dict[str, dict[str, str]],
|
|
40
46
|
):
|
|
41
47
|
db_helper_v3 = SQLiteV3DatabaseV3(
|
|
42
|
-
db_path=DB_PATH.replace("data_v4.db", "data_v3.db")
|
|
48
|
+
db_path=DB_PATH.replace("data_v4.db", "data_v3.db"),
|
|
43
49
|
)
|
|
44
50
|
conversations, total_cnt = db_helper_v3.get_all_conversations(
|
|
45
|
-
page=1,
|
|
51
|
+
page=1,
|
|
52
|
+
page_size=10000000,
|
|
46
53
|
)
|
|
47
54
|
logger.info(f"迁移 {total_cnt} 条旧的会话数据到新的表中...")
|
|
48
55
|
|
|
@@ -61,13 +68,14 @@ async def migration_conversation_table(
|
|
|
61
68
|
)
|
|
62
69
|
if not conv:
|
|
63
70
|
logger.info(
|
|
64
|
-
f"未找到该条旧会话对应的具体数据: {conversation}, 跳过。"
|
|
71
|
+
f"未找到该条旧会话对应的具体数据: {conversation}, 跳过。",
|
|
65
72
|
)
|
|
66
73
|
if ":" not in conv.user_id:
|
|
67
74
|
continue
|
|
68
75
|
session = MessageSesion.from_str(session_str=conv.user_id)
|
|
69
76
|
platform_id = get_platform_id(
|
|
70
|
-
platform_id_map,
|
|
77
|
+
platform_id_map,
|
|
78
|
+
session.platform_name,
|
|
71
79
|
)
|
|
72
80
|
session.platform_id = platform_id # 更新平台名称为新的 ID
|
|
73
81
|
conv_v2 = ConversationV2(
|
|
@@ -90,10 +98,11 @@ async def migration_conversation_table(
|
|
|
90
98
|
|
|
91
99
|
|
|
92
100
|
async def migration_platform_table(
|
|
93
|
-
db_helper: BaseDatabase,
|
|
101
|
+
db_helper: BaseDatabase,
|
|
102
|
+
platform_id_map: dict[str, dict[str, str]],
|
|
94
103
|
):
|
|
95
104
|
db_helper_v3 = SQLiteV3DatabaseV3(
|
|
96
|
-
db_path=DB_PATH.replace("data_v4.db", "data_v3.db")
|
|
105
|
+
db_path=DB_PATH.replace("data_v4.db", "data_v3.db"),
|
|
97
106
|
)
|
|
98
107
|
secs_from_2023_4_10_to_now = (
|
|
99
108
|
datetime.datetime.now(datetime.timezone.utc)
|
|
@@ -134,10 +143,12 @@ async def migration_platform_table(
|
|
|
134
143
|
if cnt == 0:
|
|
135
144
|
continue
|
|
136
145
|
platform_id = get_platform_id(
|
|
137
|
-
platform_id_map,
|
|
146
|
+
platform_id_map,
|
|
147
|
+
platform_stats_v3[idx].name,
|
|
138
148
|
)
|
|
139
149
|
platform_type = get_platform_type(
|
|
140
|
-
platform_id_map,
|
|
150
|
+
platform_id_map,
|
|
151
|
+
platform_stats_v3[idx].name,
|
|
141
152
|
)
|
|
142
153
|
try:
|
|
143
154
|
await dbsession.execute(
|
|
@@ -149,7 +160,8 @@ async def migration_platform_table(
|
|
|
149
160
|
"""),
|
|
150
161
|
{
|
|
151
162
|
"timestamp": datetime.datetime.fromtimestamp(
|
|
152
|
-
bucket_end,
|
|
163
|
+
bucket_end,
|
|
164
|
+
tz=datetime.timezone.utc,
|
|
153
165
|
),
|
|
154
166
|
"platform_id": platform_id,
|
|
155
167
|
"platform_type": platform_type,
|
|
@@ -165,14 +177,16 @@ async def migration_platform_table(
|
|
|
165
177
|
|
|
166
178
|
|
|
167
179
|
async def migration_webchat_data(
|
|
168
|
-
db_helper: BaseDatabase,
|
|
180
|
+
db_helper: BaseDatabase,
|
|
181
|
+
platform_id_map: dict[str, dict[str, str]],
|
|
169
182
|
):
|
|
170
183
|
"""迁移 WebChat 的历史记录到新的 PlatformMessageHistory 表中"""
|
|
171
184
|
db_helper_v3 = SQLiteV3DatabaseV3(
|
|
172
|
-
db_path=DB_PATH.replace("data_v4.db", "data_v3.db")
|
|
185
|
+
db_path=DB_PATH.replace("data_v4.db", "data_v3.db"),
|
|
173
186
|
)
|
|
174
187
|
conversations, total_cnt = db_helper_v3.get_all_conversations(
|
|
175
|
-
page=1,
|
|
188
|
+
page=1,
|
|
189
|
+
page_size=10000000,
|
|
176
190
|
)
|
|
177
191
|
logger.info(f"迁移 {total_cnt} 条旧的 WebChat 会话数据到新的表中...")
|
|
178
192
|
|
|
@@ -191,7 +205,7 @@ async def migration_webchat_data(
|
|
|
191
205
|
)
|
|
192
206
|
if not conv:
|
|
193
207
|
logger.info(
|
|
194
|
-
f"未找到该条旧会话对应的具体数据: {conversation}, 跳过。"
|
|
208
|
+
f"未找到该条旧会话对应的具体数据: {conversation}, 跳过。",
|
|
195
209
|
)
|
|
196
210
|
if ":" in conv.user_id:
|
|
197
211
|
continue
|
|
@@ -218,10 +232,10 @@ async def migration_webchat_data(
|
|
|
218
232
|
|
|
219
233
|
|
|
220
234
|
async def migration_persona_data(
|
|
221
|
-
db_helper: BaseDatabase,
|
|
235
|
+
db_helper: BaseDatabase,
|
|
236
|
+
astrbot_config: AstrBotConfig,
|
|
222
237
|
):
|
|
223
|
-
"""
|
|
224
|
-
迁移 Persona 数据到新的表中。
|
|
238
|
+
"""迁移 Persona 数据到新的表中。
|
|
225
239
|
旧的 Persona 数据存储在 preference 中,新的 Persona 数据存储在 persona 表中。
|
|
226
240
|
"""
|
|
227
241
|
v3_persona_config: list[dict] = astrbot_config.get("persona", [])
|
|
@@ -236,14 +250,15 @@ async def migration_persona_data(
|
|
|
236
250
|
try:
|
|
237
251
|
begin_dialogs = persona.get("begin_dialogs", [])
|
|
238
252
|
mood_imitation_dialogs = persona.get("mood_imitation_dialogs", [])
|
|
239
|
-
|
|
253
|
+
parts = []
|
|
240
254
|
user_turn = True
|
|
241
255
|
for mood_dialog in mood_imitation_dialogs:
|
|
242
256
|
if user_turn:
|
|
243
|
-
|
|
257
|
+
parts.append(f"A: {mood_dialog}\n")
|
|
244
258
|
else:
|
|
245
|
-
|
|
259
|
+
parts.append(f"B: {mood_dialog}\n")
|
|
246
260
|
user_turn = not user_turn
|
|
261
|
+
mood_prompt = "".join(parts)
|
|
247
262
|
system_prompt = persona.get("prompt", "")
|
|
248
263
|
if mood_prompt:
|
|
249
264
|
system_prompt += f"Here are few shots of dialogs, you need to imitate the tone of 'B' in the following dialogs to respond:\n {mood_prompt}"
|
|
@@ -253,14 +268,15 @@ async def migration_persona_data(
|
|
|
253
268
|
begin_dialogs=begin_dialogs,
|
|
254
269
|
)
|
|
255
270
|
logger.info(
|
|
256
|
-
f"迁移 Persona {persona['name']}({persona_new.system_prompt[:30]}...) 到新表成功。"
|
|
271
|
+
f"迁移 Persona {persona['name']}({persona_new.system_prompt[:30]}...) 到新表成功。",
|
|
257
272
|
)
|
|
258
273
|
except Exception as e:
|
|
259
274
|
logger.error(f"解析 Persona 配置失败:{e}")
|
|
260
275
|
|
|
261
276
|
|
|
262
277
|
async def migration_preferences(
|
|
263
|
-
db_helper: BaseDatabase,
|
|
278
|
+
db_helper: BaseDatabase,
|
|
279
|
+
platform_id_map: dict[str, dict[str, str]],
|
|
264
280
|
):
|
|
265
281
|
# 1. global scope migration
|
|
266
282
|
keys = [
|
|
@@ -329,10 +345,13 @@ async def migration_preferences(
|
|
|
329
345
|
|
|
330
346
|
for provider_type, provider_id in perf.items():
|
|
331
347
|
await sp.put_async(
|
|
332
|
-
"umo",
|
|
348
|
+
"umo",
|
|
349
|
+
str(session),
|
|
350
|
+
f"provider_perf_{provider_type}",
|
|
351
|
+
provider_id,
|
|
333
352
|
)
|
|
334
353
|
logger.info(
|
|
335
|
-
f"迁移会话 {umo} 的提供商偏好到新表成功,平台 ID: {platform_id}"
|
|
354
|
+
f"迁移会话 {umo} 的提供商偏好到新表成功,平台 ID: {platform_id}",
|
|
336
355
|
)
|
|
337
356
|
except Exception as e:
|
|
338
357
|
logger.error(f"迁移会话 {umo} 的提供商偏好失败: {e}", exc_info=True)
|
|
@@ -9,7 +9,7 @@ async def migrate_45_to_46(acm: AstrBotConfigManager, ucr: UmopConfigRouter):
|
|
|
9
9
|
if not isinstance(abconf_data, dict):
|
|
10
10
|
# should be unreachable
|
|
11
11
|
logger.warning(
|
|
12
|
-
f"migrate_45_to_46: abconf_data is not a dict (type={type(abconf_data)}). Value: {abconf_data!r}"
|
|
12
|
+
f"migrate_45_to_46: abconf_data is not a dict (type={type(abconf_data)}). Value: {abconf_data!r}",
|
|
13
13
|
)
|
|
14
14
|
return
|
|
15
15
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import os
|
|
3
3
|
from typing import TypeVar
|
|
4
|
+
|
|
4
5
|
from astrbot.core.utils.astrbot_path import get_astrbot_data_path
|
|
5
6
|
|
|
6
7
|
_VT = TypeVar("_VT")
|
|
@@ -16,7 +17,7 @@ class SharedPreferences:
|
|
|
16
17
|
def _load_preferences(self):
|
|
17
18
|
if os.path.exists(self.path):
|
|
18
19
|
try:
|
|
19
|
-
with open(self.path
|
|
20
|
+
with open(self.path) as f:
|
|
20
21
|
return json.load(f)
|
|
21
22
|
except json.JSONDecodeError:
|
|
22
23
|
os.remove(self.path)
|