AstrBot 4.5.1__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 +4 -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 +12 -10
- 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 +42 -27
- 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 +32 -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 +77 -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 +16 -8
- astrbot/core/provider/sources/xinference_stt_provider.py +35 -25
- astrbot/core/star/__init__.py +16 -11
- astrbot/core/star/config.py +10 -15
- astrbot/core/star/context.py +97 -75
- 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.1.dist-info → astrbot-4.5.2.dist-info}/METADATA +2 -1
- astrbot-4.5.2.dist-info/RECORD +261 -0
- astrbot-4.5.1.dist-info/RECORD +0 -260
- {astrbot-4.5.1.dist-info → astrbot-4.5.2.dist-info}/WHEEL +0 -0
- {astrbot-4.5.1.dist-info → astrbot-4.5.2.dist-info}/entry_points.txt +0 -0
- {astrbot-4.5.1.dist-info → astrbot-4.5.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -4,18 +4,17 @@
|
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
6
|
import time
|
|
7
|
-
|
|
8
7
|
from dataclasses import dataclass
|
|
9
|
-
from typing import List
|
|
10
8
|
|
|
9
|
+
from astrbot import logger
|
|
10
|
+
from astrbot.core.db.vec_db.base import Result
|
|
11
|
+
from astrbot.core.db.vec_db.faiss_impl import FaissVecDB
|
|
11
12
|
from astrbot.core.knowledge_base.kb_db_sqlite import KBSQLiteDatabase
|
|
12
13
|
from astrbot.core.knowledge_base.retrieval.rank_fusion import RankFusion
|
|
13
14
|
from astrbot.core.knowledge_base.retrieval.sparse_retriever import SparseRetriever
|
|
14
15
|
from astrbot.core.provider.provider import RerankProvider
|
|
15
|
-
|
|
16
|
-
from astrbot.core.db.vec_db.faiss_impl import FaissVecDB
|
|
16
|
+
|
|
17
17
|
from ..kb_helper import KBHelper
|
|
18
|
-
from astrbot import logger
|
|
19
18
|
|
|
20
19
|
|
|
21
20
|
@dataclass
|
|
@@ -53,6 +52,7 @@ class RetrievalManager:
|
|
|
53
52
|
sparse_retriever: 稀疏检索器
|
|
54
53
|
rank_fusion: 结果融合器
|
|
55
54
|
kb_db: 知识库数据库实例
|
|
55
|
+
|
|
56
56
|
"""
|
|
57
57
|
self.sparse_retriever = sparse_retriever
|
|
58
58
|
self.rank_fusion = rank_fusion
|
|
@@ -61,11 +61,11 @@ class RetrievalManager:
|
|
|
61
61
|
async def retrieve(
|
|
62
62
|
self,
|
|
63
63
|
query: str,
|
|
64
|
-
kb_ids:
|
|
64
|
+
kb_ids: list[str],
|
|
65
65
|
kb_id_helper_map: dict[str, KBHelper],
|
|
66
66
|
top_k_fusion: int = 20,
|
|
67
67
|
top_m_final: int = 5,
|
|
68
|
-
) ->
|
|
68
|
+
) -> list[RetrievalResult]:
|
|
69
69
|
"""混合检索
|
|
70
70
|
|
|
71
71
|
流程:
|
|
@@ -82,6 +82,7 @@ class RetrievalManager:
|
|
|
82
82
|
|
|
83
83
|
Returns:
|
|
84
84
|
List[RetrievalResult]: 检索结果列表
|
|
85
|
+
|
|
85
86
|
"""
|
|
86
87
|
if not kb_ids:
|
|
87
88
|
return []
|
|
@@ -114,7 +115,7 @@ class RetrievalManager:
|
|
|
114
115
|
)
|
|
115
116
|
time_end = time.time()
|
|
116
117
|
logger.debug(
|
|
117
|
-
f"Dense retrieval across {len(kb_ids)} bases took {time_end - time_start:.2f}s and returned {len(dense_results)} results."
|
|
118
|
+
f"Dense retrieval across {len(kb_ids)} bases took {time_end - time_start:.2f}s and returned {len(dense_results)} results.",
|
|
118
119
|
)
|
|
119
120
|
|
|
120
121
|
# 2. 稀疏检索
|
|
@@ -126,7 +127,7 @@ class RetrievalManager:
|
|
|
126
127
|
)
|
|
127
128
|
time_end = time.time()
|
|
128
129
|
logger.debug(
|
|
129
|
-
f"Sparse retrieval across {len(kb_ids)} bases took {time_end - time_start:.2f}s and returned {len(sparse_results)} results."
|
|
130
|
+
f"Sparse retrieval across {len(kb_ids)} bases took {time_end - time_start:.2f}s and returned {len(sparse_results)} results.",
|
|
130
131
|
)
|
|
131
132
|
|
|
132
133
|
# 3. 结果融合
|
|
@@ -138,7 +139,7 @@ class RetrievalManager:
|
|
|
138
139
|
)
|
|
139
140
|
time_end = time.time()
|
|
140
141
|
logger.debug(
|
|
141
|
-
f"Rank fusion took {time_end - time_start:.2f}s and returned {len(fused_results)} results."
|
|
142
|
+
f"Rank fusion took {time_end - time_start:.2f}s and returned {len(fused_results)} results.",
|
|
142
143
|
)
|
|
143
144
|
|
|
144
145
|
# 4. 转换为 RetrievalResult (获取元数据)
|
|
@@ -159,7 +160,7 @@ class RetrievalManager:
|
|
|
159
160
|
"chunk_index": fr.chunk_index,
|
|
160
161
|
"char_count": len(fr.content),
|
|
161
162
|
},
|
|
162
|
-
)
|
|
163
|
+
),
|
|
163
164
|
)
|
|
164
165
|
|
|
165
166
|
# 5. Rerank
|
|
@@ -188,7 +189,7 @@ class RetrievalManager:
|
|
|
188
189
|
async def _dense_retrieve(
|
|
189
190
|
self,
|
|
190
191
|
query: str,
|
|
191
|
-
kb_ids:
|
|
192
|
+
kb_ids: list[str],
|
|
192
193
|
kb_options: dict,
|
|
193
194
|
):
|
|
194
195
|
"""稠密检索 (向量相似度)
|
|
@@ -202,6 +203,7 @@ class RetrievalManager:
|
|
|
202
203
|
|
|
203
204
|
Returns:
|
|
204
205
|
List[Result]: 检索结果列表
|
|
206
|
+
|
|
205
207
|
"""
|
|
206
208
|
all_results: list[Result] = []
|
|
207
209
|
for kb_id in kb_ids:
|
|
@@ -233,10 +235,10 @@ class RetrievalManager:
|
|
|
233
235
|
async def _rerank(
|
|
234
236
|
self,
|
|
235
237
|
query: str,
|
|
236
|
-
results:
|
|
238
|
+
results: list[RetrievalResult],
|
|
237
239
|
top_k: int,
|
|
238
240
|
rerank_provider: RerankProvider,
|
|
239
|
-
) ->
|
|
241
|
+
) -> list[RetrievalResult]:
|
|
240
242
|
"""Rerank 重排序
|
|
241
243
|
|
|
242
244
|
Args:
|
|
@@ -246,6 +248,7 @@ class RetrievalManager:
|
|
|
246
248
|
|
|
247
249
|
Returns:
|
|
248
250
|
List[RetrievalResult]: 重排序后的结果列表
|
|
251
|
+
|
|
249
252
|
"""
|
|
250
253
|
if not results:
|
|
251
254
|
return []
|
|
@@ -37,6 +37,7 @@ class RankFusion:
|
|
|
37
37
|
Args:
|
|
38
38
|
kb_db: 知识库数据库实例
|
|
39
39
|
k: RRF 参数,用于平滑排名
|
|
40
|
+
|
|
40
41
|
"""
|
|
41
42
|
self.kb_db = kb_db
|
|
42
43
|
self.k = k
|
|
@@ -59,6 +60,7 @@ class RankFusion:
|
|
|
59
60
|
|
|
60
61
|
Returns:
|
|
61
62
|
List[FusedResult]: 融合后的结果列表
|
|
63
|
+
|
|
62
64
|
"""
|
|
63
65
|
# 1. 构建排名映射
|
|
64
66
|
dense_ranks = {
|
|
@@ -101,7 +103,9 @@ class RankFusion:
|
|
|
101
103
|
|
|
102
104
|
# 4. 排序
|
|
103
105
|
sorted_ids = sorted(
|
|
104
|
-
rrf_scores.keys(),
|
|
106
|
+
rrf_scores.keys(),
|
|
107
|
+
key=lambda cid: rrf_scores[cid],
|
|
108
|
+
reverse=True,
|
|
105
109
|
)[:top_k]
|
|
106
110
|
|
|
107
111
|
# 5. 构建融合结果
|
|
@@ -118,7 +122,7 @@ class RankFusion:
|
|
|
118
122
|
kb_id=sr.kb_id,
|
|
119
123
|
content=sr.content,
|
|
120
124
|
score=rrf_scores[identifier],
|
|
121
|
-
)
|
|
125
|
+
),
|
|
122
126
|
)
|
|
123
127
|
elif identifier in vec_doc_id_to_dense:
|
|
124
128
|
# 从向量检索获取信息,需要从数据库获取块的详细信息
|
|
@@ -132,7 +136,7 @@ class RankFusion:
|
|
|
132
136
|
kb_id=chunk_md["kb_id"],
|
|
133
137
|
content=vec_result.data["text"],
|
|
134
138
|
score=rrf_scores[identifier],
|
|
135
|
-
)
|
|
139
|
+
),
|
|
136
140
|
)
|
|
137
141
|
|
|
138
142
|
return fused_results
|
|
@@ -3,13 +3,15 @@
|
|
|
3
3
|
使用 BM25 算法进行基于关键词的文档检索
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
|
-
import jieba
|
|
7
|
-
import os
|
|
8
6
|
import json
|
|
7
|
+
import os
|
|
9
8
|
from dataclasses import dataclass
|
|
9
|
+
|
|
10
|
+
import jieba
|
|
10
11
|
from rank_bm25 import BM25Okapi
|
|
11
|
-
|
|
12
|
+
|
|
12
13
|
from astrbot.core.db.vec_db.faiss_impl import FaissVecDB
|
|
14
|
+
from astrbot.core.knowledge_base.kb_db_sqlite import KBSQLiteDatabase
|
|
13
15
|
|
|
14
16
|
|
|
15
17
|
@dataclass
|
|
@@ -37,6 +39,7 @@ class SparseRetriever:
|
|
|
37
39
|
|
|
38
40
|
Args:
|
|
39
41
|
kb_db: 知识库数据库实例
|
|
42
|
+
|
|
40
43
|
"""
|
|
41
44
|
self.kb_db = kb_db
|
|
42
45
|
self._index_cache = {} # 缓存 BM25 索引
|
|
@@ -64,6 +67,7 @@ class SparseRetriever:
|
|
|
64
67
|
|
|
65
68
|
Returns:
|
|
66
69
|
List[SparseResult]: 检索结果列表
|
|
70
|
+
|
|
67
71
|
"""
|
|
68
72
|
# 1. 获取所有相关块
|
|
69
73
|
top_k_sparse = 0
|
|
@@ -73,7 +77,9 @@ class SparseRetriever:
|
|
|
73
77
|
if not vec_db:
|
|
74
78
|
continue
|
|
75
79
|
result = await vec_db.document_storage.get_documents(
|
|
76
|
-
metadata_filters={},
|
|
80
|
+
metadata_filters={},
|
|
81
|
+
limit=None,
|
|
82
|
+
offset=None,
|
|
77
83
|
)
|
|
78
84
|
chunk_mds = [json.loads(doc["metadata"]) for doc in result]
|
|
79
85
|
result = [
|
|
@@ -122,7 +128,7 @@ class SparseRetriever:
|
|
|
122
128
|
kb_id=chunk["kb_id"],
|
|
123
129
|
content=chunk["text"],
|
|
124
130
|
score=float(score),
|
|
125
|
-
)
|
|
131
|
+
),
|
|
126
132
|
)
|
|
127
133
|
|
|
128
134
|
results.sort(key=lambda x: x.score, reverse=True)
|
astrbot/core/log.py
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
"""
|
|
2
|
-
日志系统, 用于支持核心组件和插件的日志记录, 提供了日志订阅功能
|
|
1
|
+
"""日志系统, 用于支持核心组件和插件的日志记录, 提供了日志订阅功能
|
|
3
2
|
|
|
4
3
|
const:
|
|
5
4
|
CACHED_SIZE: 日志缓存大小, 用于限制缓存的日志数量
|
|
@@ -21,14 +20,14 @@ function:
|
|
|
21
20
|
4. 订阅者可以使用 register() 方法注册到 LogBroker, 订阅日志流
|
|
22
21
|
"""
|
|
23
22
|
|
|
24
|
-
import logging
|
|
25
|
-
import colorlog
|
|
26
23
|
import asyncio
|
|
24
|
+
import logging
|
|
27
25
|
import os
|
|
28
26
|
import sys
|
|
29
|
-
from collections import deque
|
|
30
27
|
from asyncio import Queue
|
|
31
|
-
from
|
|
28
|
+
from collections import deque
|
|
29
|
+
|
|
30
|
+
import colorlog
|
|
32
31
|
|
|
33
32
|
# 日志缓存大小
|
|
34
33
|
CACHED_SIZE = 200
|
|
@@ -52,6 +51,7 @@ def is_plugin_path(pathname):
|
|
|
52
51
|
|
|
53
52
|
Returns:
|
|
54
53
|
bool: 如果路径来自插件目录,则返回 True,否则返回 False
|
|
54
|
+
|
|
55
55
|
"""
|
|
56
56
|
if not pathname:
|
|
57
57
|
return False
|
|
@@ -68,6 +68,7 @@ def get_short_level_name(level_name):
|
|
|
68
68
|
|
|
69
69
|
Returns:
|
|
70
70
|
str: 四个字母的日志级别缩写
|
|
71
|
+
|
|
71
72
|
"""
|
|
72
73
|
level_map = {
|
|
73
74
|
"DEBUG": "DBUG",
|
|
@@ -87,13 +88,14 @@ class LogBroker:
|
|
|
87
88
|
|
|
88
89
|
def __init__(self):
|
|
89
90
|
self.log_cache = deque(maxlen=CACHED_SIZE) # 环形缓冲区, 保存最近的日志
|
|
90
|
-
self.subscribers:
|
|
91
|
+
self.subscribers: list[Queue] = [] # 订阅者列表
|
|
91
92
|
|
|
92
93
|
def register(self) -> Queue:
|
|
93
94
|
"""注册新的订阅者, 并给每个订阅者返回一个带有日志缓存的队列
|
|
94
95
|
|
|
95
96
|
Returns:
|
|
96
97
|
Queue: 订阅者的队列, 可用于接收日志消息
|
|
98
|
+
|
|
97
99
|
"""
|
|
98
100
|
q = Queue(maxsize=CACHED_SIZE + 10)
|
|
99
101
|
self.subscribers.append(q)
|
|
@@ -104,6 +106,7 @@ class LogBroker:
|
|
|
104
106
|
|
|
105
107
|
Args:
|
|
106
108
|
q (Queue): 需要取消订阅的队列
|
|
109
|
+
|
|
107
110
|
"""
|
|
108
111
|
self.subscribers.remove(q)
|
|
109
112
|
|
|
@@ -113,6 +116,7 @@ class LogBroker:
|
|
|
113
116
|
Args:
|
|
114
117
|
log_entry (dict): 日志消息, 包含日志级别和日志内容.
|
|
115
118
|
example: {"level": "INFO", "data": "This is a log message.", "time": "2023-10-01 12:00:00"}
|
|
119
|
+
|
|
116
120
|
"""
|
|
117
121
|
self.log_cache.append(log_entry)
|
|
118
122
|
for q in self.subscribers:
|
|
@@ -138,6 +142,7 @@ class LogQueueHandler(logging.Handler):
|
|
|
138
142
|
|
|
139
143
|
Args:
|
|
140
144
|
record (logging.LogRecord): 日志记录对象, 包含日志信息
|
|
145
|
+
|
|
141
146
|
"""
|
|
142
147
|
log_entry = self.format(record)
|
|
143
148
|
self.log_broker.publish(
|
|
@@ -145,7 +150,7 @@ class LogQueueHandler(logging.Handler):
|
|
|
145
150
|
"level": record.levelname,
|
|
146
151
|
"time": record.asctime,
|
|
147
152
|
"data": log_entry,
|
|
148
|
-
}
|
|
153
|
+
},
|
|
149
154
|
)
|
|
150
155
|
|
|
151
156
|
|
|
@@ -164,6 +169,7 @@ class LogManager:
|
|
|
164
169
|
|
|
165
170
|
Returns:
|
|
166
171
|
logging.Logger: 返回配置好的日志记录器
|
|
172
|
+
|
|
167
173
|
"""
|
|
168
174
|
logger = logging.getLogger(log_name)
|
|
169
175
|
# 检查该logger或父级logger是否已经有处理器, 如果已经有处理器, 直接返回该logger, 避免重复配置
|
|
@@ -171,10 +177,10 @@ class LogManager:
|
|
|
171
177
|
return logger
|
|
172
178
|
# 如果logger没有处理器
|
|
173
179
|
console_handler = logging.StreamHandler(
|
|
174
|
-
sys.stdout
|
|
180
|
+
sys.stdout,
|
|
175
181
|
) # 创建一个StreamHandler用于控制台输出
|
|
176
182
|
console_handler.setLevel(
|
|
177
|
-
logging.DEBUG
|
|
183
|
+
logging.DEBUG,
|
|
178
184
|
) # 将日志级别设置为DEBUG(最低级别, 显示所有日志), *如果插件没有设置级别, 默认为DEBUG
|
|
179
185
|
|
|
180
186
|
# 创建彩色日志格式化器, 输出日志格式为: [时间] [插件标签] [日志级别] [文件名:行号]: 日志消息
|
|
@@ -195,7 +201,8 @@ class LogManager:
|
|
|
195
201
|
|
|
196
202
|
class FileNameFilter(logging.Filter):
|
|
197
203
|
"""文件名过滤器类, 用于修改日志记录的文件名格式
|
|
198
|
-
例如: 将文件路径 /path/to/file.py 转换为 file.<file> 格式
|
|
204
|
+
例如: 将文件路径 /path/to/file.py 转换为 file.<file> 格式
|
|
205
|
+
"""
|
|
199
206
|
|
|
200
207
|
# 获取这个文件和父文件夹的名字:<folder>.<file> 并且去除 .py
|
|
201
208
|
def filter(self, record):
|
|
@@ -231,6 +238,7 @@ class LogManager:
|
|
|
231
238
|
Args:
|
|
232
239
|
logger (logging.Logger): 日志记录器
|
|
233
240
|
log_broker (LogBroker): 日志代理类, 用于缓存和分发日志消息
|
|
241
|
+
|
|
234
242
|
"""
|
|
235
243
|
handler = LogQueueHandler(log_broker)
|
|
236
244
|
handler.setLevel(logging.DEBUG)
|
|
@@ -240,7 +248,7 @@ class LogManager:
|
|
|
240
248
|
# 为队列处理器设置相同格式的formatter
|
|
241
249
|
handler.setFormatter(
|
|
242
250
|
logging.Formatter(
|
|
243
|
-
"[%(asctime)s] [%(short_levelname)s] %(plugin_tag)s[%(filename)s:%(lineno)d]: %(message)s"
|
|
244
|
-
)
|
|
251
|
+
"[%(asctime)s] [%(short_levelname)s] %(plugin_tag)s[%(filename)s:%(lineno)d]: %(message)s",
|
|
252
|
+
),
|
|
245
253
|
)
|
|
246
254
|
logger.addHandler(handler)
|