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
|
@@ -47,7 +47,10 @@ class SessionManagementRoute(Route):
|
|
|
47
47
|
|
|
48
48
|
# 获取活跃的会话数据(处于对话内的会话)
|
|
49
49
|
sessions_data, total = await self.db_helper.get_session_conversations(
|
|
50
|
-
page,
|
|
50
|
+
page,
|
|
51
|
+
page_size,
|
|
52
|
+
search_query,
|
|
53
|
+
platform,
|
|
51
54
|
)
|
|
52
55
|
|
|
53
56
|
provider_manager = self.core_lifecycle.provider_manager
|
|
@@ -80,13 +83,13 @@ class SessionManagementRoute(Route):
|
|
|
80
83
|
"stt_provider_id": None,
|
|
81
84
|
"tts_provider_id": None,
|
|
82
85
|
"session_enabled": SessionServiceManager.is_session_enabled(
|
|
83
|
-
session_id
|
|
86
|
+
session_id,
|
|
84
87
|
),
|
|
85
88
|
"llm_enabled": SessionServiceManager.is_llm_enabled_for_session(
|
|
86
|
-
session_id
|
|
89
|
+
session_id,
|
|
87
90
|
),
|
|
88
91
|
"tts_enabled": SessionServiceManager.is_tts_enabled_for_session(
|
|
89
|
-
session_id
|
|
92
|
+
session_id,
|
|
90
93
|
),
|
|
91
94
|
"platform": session_id.split(":")[0]
|
|
92
95
|
if ":" in session_id
|
|
@@ -95,7 +98,7 @@ class SessionManagementRoute(Route):
|
|
|
95
98
|
if session_id.count(":") >= 1
|
|
96
99
|
else "unknown",
|
|
97
100
|
"session_name": SessionServiceManager.get_session_display_name(
|
|
98
|
-
session_id
|
|
101
|
+
session_id,
|
|
99
102
|
),
|
|
100
103
|
"session_raw_name": session_id.split(":")[2]
|
|
101
104
|
if session_id.count(":") >= 2
|
|
@@ -105,13 +108,16 @@ class SessionManagementRoute(Route):
|
|
|
105
108
|
|
|
106
109
|
# 获取 provider 信息
|
|
107
110
|
chat_provider = provider_manager.get_using_provider(
|
|
108
|
-
provider_type=ProviderType.CHAT_COMPLETION,
|
|
111
|
+
provider_type=ProviderType.CHAT_COMPLETION,
|
|
112
|
+
umo=session_id,
|
|
109
113
|
)
|
|
110
114
|
tts_provider = provider_manager.get_using_provider(
|
|
111
|
-
provider_type=ProviderType.TEXT_TO_SPEECH,
|
|
115
|
+
provider_type=ProviderType.TEXT_TO_SPEECH,
|
|
116
|
+
umo=session_id,
|
|
112
117
|
)
|
|
113
118
|
stt_provider = provider_manager.get_using_provider(
|
|
114
|
-
provider_type=ProviderType.SPEECH_TO_TEXT,
|
|
119
|
+
provider_type=ProviderType.SPEECH_TO_TEXT,
|
|
120
|
+
umo=session_id,
|
|
115
121
|
)
|
|
116
122
|
if chat_provider:
|
|
117
123
|
meta = chat_provider.meta()
|
|
@@ -139,7 +145,7 @@ class SessionManagementRoute(Route):
|
|
|
139
145
|
"name": meta.id,
|
|
140
146
|
"model": meta.model,
|
|
141
147
|
"type": meta.type,
|
|
142
|
-
}
|
|
148
|
+
},
|
|
143
149
|
)
|
|
144
150
|
|
|
145
151
|
available_stt_providers = []
|
|
@@ -151,7 +157,7 @@ class SessionManagementRoute(Route):
|
|
|
151
157
|
"name": meta.id,
|
|
152
158
|
"model": meta.model,
|
|
153
159
|
"type": meta.type,
|
|
154
|
-
}
|
|
160
|
+
},
|
|
155
161
|
)
|
|
156
162
|
|
|
157
163
|
available_tts_providers = []
|
|
@@ -163,7 +169,7 @@ class SessionManagementRoute(Route):
|
|
|
163
169
|
"name": meta.id,
|
|
164
170
|
"model": meta.model,
|
|
165
171
|
"type": meta.type,
|
|
166
|
-
}
|
|
172
|
+
},
|
|
167
173
|
)
|
|
168
174
|
|
|
169
175
|
result = {
|
|
@@ -185,15 +191,15 @@ class SessionManagementRoute(Route):
|
|
|
185
191
|
return Response().ok(result).__dict__
|
|
186
192
|
|
|
187
193
|
except Exception as e:
|
|
188
|
-
error_msg = f"获取会话列表失败: {
|
|
194
|
+
error_msg = f"获取会话列表失败: {e!s}\n{traceback.format_exc()}"
|
|
189
195
|
logger.error(error_msg)
|
|
190
|
-
return Response().error(f"获取会话列表失败: {
|
|
196
|
+
return Response().error(f"获取会话列表失败: {e!s}").__dict__
|
|
191
197
|
|
|
192
198
|
async def _update_single_session_persona(self, session_id: str, persona_name: str):
|
|
193
199
|
"""更新单个会话的 persona 的内部方法"""
|
|
194
200
|
conversation_manager = self.core_lifecycle.star_context.conversation_manager
|
|
195
201
|
conversation_id = await conversation_manager.get_curr_conversation_id(
|
|
196
|
-
session_id
|
|
202
|
+
session_id,
|
|
197
203
|
)
|
|
198
204
|
|
|
199
205
|
conv = None
|
|
@@ -207,11 +213,16 @@ class SessionManagementRoute(Route):
|
|
|
207
213
|
|
|
208
214
|
# 更新 persona
|
|
209
215
|
await conversation_manager.update_conversation_persona_id(
|
|
210
|
-
session_id,
|
|
216
|
+
session_id,
|
|
217
|
+
persona_name,
|
|
211
218
|
)
|
|
212
219
|
|
|
213
220
|
async def _handle_batch_operation(
|
|
214
|
-
self,
|
|
221
|
+
self,
|
|
222
|
+
session_ids: list,
|
|
223
|
+
operation_func,
|
|
224
|
+
operation_name: str,
|
|
225
|
+
**kwargs,
|
|
215
226
|
):
|
|
216
227
|
"""通用的批量操作处理方法"""
|
|
217
228
|
success_count = 0
|
|
@@ -222,7 +233,7 @@ class SessionManagementRoute(Route):
|
|
|
222
233
|
await operation_func(session_id, **kwargs)
|
|
223
234
|
success_count += 1
|
|
224
235
|
except Exception as e:
|
|
225
|
-
logger.error(f"批量{operation_name} 会话 {session_id} 失败: {
|
|
236
|
+
logger.error(f"批量{operation_name} 会话 {session_id} 失败: {e!s}")
|
|
226
237
|
error_sessions.append(session_id)
|
|
227
238
|
|
|
228
239
|
if error_sessions:
|
|
@@ -234,21 +245,20 @@ class SessionManagementRoute(Route):
|
|
|
234
245
|
"success_count": success_count,
|
|
235
246
|
"error_count": len(error_sessions),
|
|
236
247
|
"error_sessions": error_sessions,
|
|
237
|
-
}
|
|
248
|
+
},
|
|
238
249
|
)
|
|
239
250
|
.__dict__
|
|
240
251
|
)
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
{
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
}
|
|
249
|
-
)
|
|
250
|
-
.__dict__
|
|
252
|
+
return (
|
|
253
|
+
Response()
|
|
254
|
+
.ok(
|
|
255
|
+
{
|
|
256
|
+
"message": f"成功批量{operation_name} {success_count} 个会话",
|
|
257
|
+
"success_count": success_count,
|
|
258
|
+
},
|
|
251
259
|
)
|
|
260
|
+
.__dict__
|
|
261
|
+
)
|
|
252
262
|
|
|
253
263
|
async def update_session_persona(self):
|
|
254
264
|
"""更新指定会话的 persona,支持批量操作"""
|
|
@@ -271,29 +281,31 @@ class SessionManagementRoute(Route):
|
|
|
271
281
|
"更新人格",
|
|
272
282
|
persona_name=persona_name,
|
|
273
283
|
)
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
return Response().error("缺少必要参数: session_id").__dict__
|
|
284
|
+
session_id = data.get("session_id")
|
|
285
|
+
if not session_id:
|
|
286
|
+
return Response().error("缺少必要参数: session_id").__dict__
|
|
278
287
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
)
|
|
287
|
-
.__dict__
|
|
288
|
+
await self._update_single_session_persona(session_id, persona_name)
|
|
289
|
+
return (
|
|
290
|
+
Response()
|
|
291
|
+
.ok(
|
|
292
|
+
{
|
|
293
|
+
"message": f"成功更新会话 {session_id} 的人格为 {persona_name}",
|
|
294
|
+
},
|
|
288
295
|
)
|
|
296
|
+
.__dict__
|
|
297
|
+
)
|
|
289
298
|
|
|
290
299
|
except Exception as e:
|
|
291
|
-
error_msg = f"更新会话人格失败: {
|
|
300
|
+
error_msg = f"更新会话人格失败: {e!s}\n{traceback.format_exc()}"
|
|
292
301
|
logger.error(error_msg)
|
|
293
|
-
return Response().error(f"更新会话人格失败: {
|
|
302
|
+
return Response().error(f"更新会话人格失败: {e!s}").__dict__
|
|
294
303
|
|
|
295
304
|
async def _update_single_session_provider(
|
|
296
|
-
self,
|
|
305
|
+
self,
|
|
306
|
+
session_id: str,
|
|
307
|
+
provider_id: str,
|
|
308
|
+
provider_type_enum,
|
|
297
309
|
):
|
|
298
310
|
"""更新单个会话的 provider 的内部方法"""
|
|
299
311
|
provider_manager = self.core_lifecycle.star_context.provider_manager
|
|
@@ -344,28 +356,29 @@ class SessionManagementRoute(Route):
|
|
|
344
356
|
provider_id=provider_id,
|
|
345
357
|
provider_type_enum=provider_type_enum,
|
|
346
358
|
)
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
return Response().error("缺少必要参数: session_id").__dict__
|
|
359
|
+
session_id = data.get("session_id")
|
|
360
|
+
if not session_id:
|
|
361
|
+
return Response().error("缺少必要参数: session_id").__dict__
|
|
351
362
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
+
await self._update_single_session_provider(
|
|
364
|
+
session_id,
|
|
365
|
+
provider_id,
|
|
366
|
+
provider_type_enum,
|
|
367
|
+
)
|
|
368
|
+
return (
|
|
369
|
+
Response()
|
|
370
|
+
.ok(
|
|
371
|
+
{
|
|
372
|
+
"message": f"成功更新会话 {session_id} 的 {provider_type} 提供商为 {provider_id}",
|
|
373
|
+
},
|
|
363
374
|
)
|
|
375
|
+
.__dict__
|
|
376
|
+
)
|
|
364
377
|
|
|
365
378
|
except Exception as e:
|
|
366
|
-
error_msg = f"更新会话提供商失败: {
|
|
379
|
+
error_msg = f"更新会话提供商失败: {e!s}\n{traceback.format_exc()}"
|
|
367
380
|
logger.error(error_msg)
|
|
368
|
-
return Response().error(f"更新会话提供商失败: {
|
|
381
|
+
return Response().error(f"更新会话提供商失败: {e!s}").__dict__
|
|
369
382
|
|
|
370
383
|
async def get_session_plugins(self):
|
|
371
384
|
"""获取指定会话的插件配置信息"""
|
|
@@ -384,7 +397,8 @@ class SessionManagementRoute(Route):
|
|
|
384
397
|
if plugin.activated and not plugin.reserved:
|
|
385
398
|
plugin_name = plugin.name or ""
|
|
386
399
|
plugin_enabled = SessionPluginManager.is_plugin_enabled_for_session(
|
|
387
|
-
session_id,
|
|
400
|
+
session_id,
|
|
401
|
+
plugin_name,
|
|
388
402
|
)
|
|
389
403
|
|
|
390
404
|
all_plugins.append(
|
|
@@ -393,7 +407,7 @@ class SessionManagementRoute(Route):
|
|
|
393
407
|
"author": plugin.author,
|
|
394
408
|
"desc": plugin.desc,
|
|
395
409
|
"enabled": plugin_enabled,
|
|
396
|
-
}
|
|
410
|
+
},
|
|
397
411
|
)
|
|
398
412
|
|
|
399
413
|
return (
|
|
@@ -402,15 +416,15 @@ class SessionManagementRoute(Route):
|
|
|
402
416
|
{
|
|
403
417
|
"session_id": session_id,
|
|
404
418
|
"plugins": all_plugins,
|
|
405
|
-
}
|
|
419
|
+
},
|
|
406
420
|
)
|
|
407
421
|
.__dict__
|
|
408
422
|
)
|
|
409
423
|
|
|
410
424
|
except Exception as e:
|
|
411
|
-
error_msg = f"获取会话插件配置失败: {
|
|
425
|
+
error_msg = f"获取会话插件配置失败: {e!s}\n{traceback.format_exc()}"
|
|
412
426
|
logger.error(error_msg)
|
|
413
|
-
return Response().error(f"获取会话插件配置失败: {
|
|
427
|
+
return Response().error(f"获取会话插件配置失败: {e!s}").__dict__
|
|
414
428
|
|
|
415
429
|
async def update_session_plugin(self):
|
|
416
430
|
"""更新指定会话的插件启停状态"""
|
|
@@ -448,7 +462,9 @@ class SessionManagementRoute(Route):
|
|
|
448
462
|
|
|
449
463
|
# 使用 SessionPluginManager 更新插件状态
|
|
450
464
|
SessionPluginManager.set_plugin_status_for_session(
|
|
451
|
-
session_id,
|
|
465
|
+
session_id,
|
|
466
|
+
plugin_name,
|
|
467
|
+
enabled,
|
|
452
468
|
)
|
|
453
469
|
|
|
454
470
|
return (
|
|
@@ -459,15 +475,15 @@ class SessionManagementRoute(Route):
|
|
|
459
475
|
"session_id": session_id,
|
|
460
476
|
"plugin_name": plugin_name,
|
|
461
477
|
"enabled": enabled,
|
|
462
|
-
}
|
|
478
|
+
},
|
|
463
479
|
)
|
|
464
480
|
.__dict__
|
|
465
481
|
)
|
|
466
482
|
|
|
467
483
|
except Exception as e:
|
|
468
|
-
error_msg = f"更新会话插件状态失败: {
|
|
484
|
+
error_msg = f"更新会话插件状态失败: {e!s}\n{traceback.format_exc()}"
|
|
469
485
|
logger.error(error_msg)
|
|
470
|
-
return Response().error(f"更新会话插件状态失败: {
|
|
486
|
+
return Response().error(f"更新会话插件状态失败: {e!s}").__dict__
|
|
471
487
|
|
|
472
488
|
async def _update_single_session_llm(self, session_id: str, enabled: bool):
|
|
473
489
|
"""更新单个会话的LLM状态的内部方法"""
|
|
@@ -495,28 +511,27 @@ class SessionManagementRoute(Route):
|
|
|
495
511
|
enabled=enabled,
|
|
496
512
|
)
|
|
497
513
|
return result
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
return Response().error("缺少必要参数: session_id").__dict__
|
|
514
|
+
session_id = data.get("session_id")
|
|
515
|
+
if not session_id:
|
|
516
|
+
return Response().error("缺少必要参数: session_id").__dict__
|
|
502
517
|
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
)
|
|
513
|
-
.__dict__
|
|
518
|
+
await self._update_single_session_llm(session_id, enabled)
|
|
519
|
+
return (
|
|
520
|
+
Response()
|
|
521
|
+
.ok(
|
|
522
|
+
{
|
|
523
|
+
"message": f"LLM已{'启用' if enabled else '禁用'}",
|
|
524
|
+
"session_id": session_id,
|
|
525
|
+
"llm_enabled": enabled,
|
|
526
|
+
},
|
|
514
527
|
)
|
|
528
|
+
.__dict__
|
|
529
|
+
)
|
|
515
530
|
|
|
516
531
|
except Exception as e:
|
|
517
|
-
error_msg = f"更新会话LLM状态失败: {
|
|
532
|
+
error_msg = f"更新会话LLM状态失败: {e!s}\n{traceback.format_exc()}"
|
|
518
533
|
logger.error(error_msg)
|
|
519
|
-
return Response().error(f"更新会话LLM状态失败: {
|
|
534
|
+
return Response().error(f"更新会话LLM状态失败: {e!s}").__dict__
|
|
520
535
|
|
|
521
536
|
async def _update_single_session_tts(self, session_id: str, enabled: bool):
|
|
522
537
|
"""更新单个会话的TTS状态的内部方法"""
|
|
@@ -544,28 +559,27 @@ class SessionManagementRoute(Route):
|
|
|
544
559
|
enabled=enabled,
|
|
545
560
|
)
|
|
546
561
|
return result
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
return Response().error("缺少必要参数: session_id").__dict__
|
|
562
|
+
session_id = data.get("session_id")
|
|
563
|
+
if not session_id:
|
|
564
|
+
return Response().error("缺少必要参数: session_id").__dict__
|
|
551
565
|
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
)
|
|
562
|
-
.__dict__
|
|
566
|
+
await self._update_single_session_tts(session_id, enabled)
|
|
567
|
+
return (
|
|
568
|
+
Response()
|
|
569
|
+
.ok(
|
|
570
|
+
{
|
|
571
|
+
"message": f"TTS已{'启用' if enabled else '禁用'}",
|
|
572
|
+
"session_id": session_id,
|
|
573
|
+
"tts_enabled": enabled,
|
|
574
|
+
},
|
|
563
575
|
)
|
|
576
|
+
.__dict__
|
|
577
|
+
)
|
|
564
578
|
|
|
565
579
|
except Exception as e:
|
|
566
|
-
error_msg = f"更新会话TTS状态失败: {
|
|
580
|
+
error_msg = f"更新会话TTS状态失败: {e!s}\n{traceback.format_exc()}"
|
|
567
581
|
logger.error(error_msg)
|
|
568
|
-
return Response().error(f"更新会话TTS状态失败: {
|
|
582
|
+
return Response().error(f"更新会话TTS状态失败: {e!s}").__dict__
|
|
569
583
|
|
|
570
584
|
async def update_session_name(self):
|
|
571
585
|
"""更新指定会话的自定义名称"""
|
|
@@ -588,17 +602,17 @@ class SessionManagementRoute(Route):
|
|
|
588
602
|
"session_id": session_id,
|
|
589
603
|
"custom_name": custom_name,
|
|
590
604
|
"display_name": SessionServiceManager.get_session_display_name(
|
|
591
|
-
session_id
|
|
605
|
+
session_id,
|
|
592
606
|
),
|
|
593
|
-
}
|
|
607
|
+
},
|
|
594
608
|
)
|
|
595
609
|
.__dict__
|
|
596
610
|
)
|
|
597
611
|
|
|
598
612
|
except Exception as e:
|
|
599
|
-
error_msg = f"更新会话名称失败: {
|
|
613
|
+
error_msg = f"更新会话名称失败: {e!s}\n{traceback.format_exc()}"
|
|
600
614
|
logger.error(error_msg)
|
|
601
|
-
return Response().error(f"更新会话名称失败: {
|
|
615
|
+
return Response().error(f"更新会话名称失败: {e!s}").__dict__
|
|
602
616
|
|
|
603
617
|
async def update_session_status(self):
|
|
604
618
|
"""更新指定会话的整体启停状态"""
|
|
@@ -623,15 +637,15 @@ class SessionManagementRoute(Route):
|
|
|
623
637
|
"message": f"会话整体状态已更新为: {'启用' if session_enabled else '禁用'}",
|
|
624
638
|
"session_id": session_id,
|
|
625
639
|
"session_enabled": session_enabled,
|
|
626
|
-
}
|
|
640
|
+
},
|
|
627
641
|
)
|
|
628
642
|
.__dict__
|
|
629
643
|
)
|
|
630
644
|
|
|
631
645
|
except Exception as e:
|
|
632
|
-
error_msg = f"更新会话整体状态失败: {
|
|
646
|
+
error_msg = f"更新会话整体状态失败: {e!s}\n{traceback.format_exc()}"
|
|
633
647
|
logger.error(error_msg)
|
|
634
|
-
return Response().error(f"更新会话整体状态失败: {
|
|
648
|
+
return Response().error(f"更新会话整体状态失败: {e!s}").__dict__
|
|
635
649
|
|
|
636
650
|
async def delete_session(self):
|
|
637
651
|
"""删除指定会话及其所有相关数据"""
|
|
@@ -649,13 +663,13 @@ class SessionManagementRoute(Route):
|
|
|
649
663
|
try:
|
|
650
664
|
await conversation_manager.delete_conversations_by_user_id(session_id)
|
|
651
665
|
except Exception as e:
|
|
652
|
-
logger.warning(f"删除会话 {session_id} 的对话失败: {
|
|
666
|
+
logger.warning(f"删除会话 {session_id} 的对话失败: {e!s}")
|
|
653
667
|
|
|
654
668
|
# 2. 清除会话的偏好设置数据(清空该会话的所有配置)
|
|
655
669
|
try:
|
|
656
670
|
await sp.clear_async("umo", session_id)
|
|
657
671
|
except Exception as e:
|
|
658
|
-
logger.warning(f"清除会话 {session_id} 的偏好设置失败: {
|
|
672
|
+
logger.warning(f"清除会话 {session_id} 的偏好设置失败: {e!s}")
|
|
659
673
|
|
|
660
674
|
return (
|
|
661
675
|
Response()
|
|
@@ -663,12 +677,12 @@ class SessionManagementRoute(Route):
|
|
|
663
677
|
{
|
|
664
678
|
"message": f"会话 {session_id} 及其相关所有对话数据已成功删除",
|
|
665
679
|
"session_id": session_id,
|
|
666
|
-
}
|
|
680
|
+
},
|
|
667
681
|
)
|
|
668
682
|
.__dict__
|
|
669
683
|
)
|
|
670
684
|
|
|
671
685
|
except Exception as e:
|
|
672
|
-
error_msg = f"删除会话失败: {
|
|
686
|
+
error_msg = f"删除会话失败: {e!s}\n{traceback.format_exc()}"
|
|
673
687
|
logger.error(error_msg)
|
|
674
|
-
return Response().error(f"删除会话失败: {
|
|
688
|
+
return Response().error(f"删除会话失败: {e!s}").__dict__
|
astrbot/dashboard/routes/stat.py
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
import traceback
|
|
2
|
-
import psutil
|
|
3
|
-
import time
|
|
4
1
|
import threading
|
|
2
|
+
import time
|
|
3
|
+
import traceback
|
|
4
|
+
|
|
5
5
|
import aiohttp
|
|
6
|
-
|
|
7
|
-
from astrbot.core import logger
|
|
6
|
+
import psutil
|
|
8
7
|
from quart import request
|
|
8
|
+
|
|
9
|
+
from astrbot.core import DEMO_MODE, logger
|
|
10
|
+
from astrbot.core.config import VERSION
|
|
9
11
|
from astrbot.core.core_lifecycle import AstrBotCoreLifecycle
|
|
10
12
|
from astrbot.core.db import BaseDatabase
|
|
11
|
-
from astrbot.core.config import VERSION
|
|
12
|
-
from astrbot.core.utils.io import get_dashboard_version
|
|
13
|
-
from astrbot.core import DEMO_MODE
|
|
14
13
|
from astrbot.core.db.migration.helper import check_migration_needed_v4
|
|
14
|
+
from astrbot.core.utils.io import get_dashboard_version
|
|
15
|
+
|
|
16
|
+
from .route import Response, Route, RouteContext
|
|
15
17
|
|
|
16
18
|
|
|
17
19
|
class StatRoute(Route):
|
|
@@ -70,7 +72,7 @@ class StatRoute(Route):
|
|
|
70
72
|
"dashboard_version": await get_dashboard_version(),
|
|
71
73
|
"change_pwd_hint": self.is_default_cred(),
|
|
72
74
|
"need_migration": need_migration,
|
|
73
|
-
}
|
|
75
|
+
},
|
|
74
76
|
)
|
|
75
77
|
.__dict__
|
|
76
78
|
)
|
|
@@ -116,17 +118,17 @@ class StatRoute(Route):
|
|
|
116
118
|
|
|
117
119
|
# 计算运行时长组件
|
|
118
120
|
running_time = self._get_running_time_components(
|
|
119
|
-
int(time.time()) - self.core_lifecycle.start_time
|
|
121
|
+
int(time.time()) - self.core_lifecycle.start_time,
|
|
120
122
|
)
|
|
121
123
|
|
|
122
124
|
stat_dict.update(
|
|
123
125
|
{
|
|
124
126
|
"platform": self.db_helper.get_grouped_base_stats(
|
|
125
|
-
offset_sec
|
|
127
|
+
offset_sec,
|
|
126
128
|
).platform,
|
|
127
129
|
"message_count": self.db_helper.get_total_message_count() or 0,
|
|
128
130
|
"platform_count": len(
|
|
129
|
-
self.core_lifecycle.platform_manager.get_insts()
|
|
131
|
+
self.core_lifecycle.platform_manager.get_insts(),
|
|
130
132
|
),
|
|
131
133
|
"plugin_count": len(plugins),
|
|
132
134
|
"plugins": plugin_info,
|
|
@@ -139,7 +141,7 @@ class StatRoute(Route):
|
|
|
139
141
|
"cpu_percent": round(cpu_percent, 1),
|
|
140
142
|
"thread_count": thread_count,
|
|
141
143
|
"start_time": self.core_lifecycle.start_time,
|
|
142
|
-
}
|
|
144
|
+
},
|
|
143
145
|
)
|
|
144
146
|
|
|
145
147
|
return Response().ok(stat_dict).__dict__
|
|
@@ -148,9 +150,7 @@ class StatRoute(Route):
|
|
|
148
150
|
return Response().error(e.__str__()).__dict__
|
|
149
151
|
|
|
150
152
|
async def test_ghproxy_connection(self):
|
|
151
|
-
"""
|
|
152
|
-
测试 GitHub 代理连接是否可用。
|
|
153
|
-
"""
|
|
153
|
+
"""测试 GitHub 代理连接是否可用。"""
|
|
154
154
|
try:
|
|
155
155
|
data = await request.get_json()
|
|
156
156
|
proxy_url: str = data.get("proxy_url")
|
|
@@ -163,23 +163,23 @@ class StatRoute(Route):
|
|
|
163
163
|
test_url = f"{proxy_url}/https://github.com/AstrBotDevs/AstrBot/raw/refs/heads/master/.python-version"
|
|
164
164
|
start_time = time.time()
|
|
165
165
|
|
|
166
|
-
async with
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
166
|
+
async with (
|
|
167
|
+
aiohttp.ClientSession() as session,
|
|
168
|
+
session.get(
|
|
169
|
+
test_url,
|
|
170
|
+
timeout=aiohttp.ClientTimeout(total=10),
|
|
171
|
+
) as response,
|
|
172
|
+
):
|
|
173
|
+
if response.status == 200:
|
|
174
|
+
end_time = time.time()
|
|
175
|
+
_ = await response.text()
|
|
176
|
+
ret = {
|
|
177
|
+
"latency": round((end_time - start_time) * 1000, 2),
|
|
178
|
+
}
|
|
179
|
+
return Response().ok(data=ret).__dict__
|
|
180
|
+
return (
|
|
181
|
+
Response().error(f"Failed. Status code: {response.status}").__dict__
|
|
182
|
+
)
|
|
183
183
|
except Exception as e:
|
|
184
184
|
logger.error(traceback.format_exc())
|
|
185
|
-
return Response().error(f"Error: {
|
|
185
|
+
return Response().error(f"Error: {e!s}").__dict__
|