From 1338cab61b2393aa82c67fb5256dd37b139e20a8 Mon Sep 17 00:00:00 2001 From: Soulter <905617992@qq.com> Date: Sun, 23 Nov 2025 21:53:56 +0800 Subject: [PATCH] feat: add configuration selector for session management and enhance session handling in chat components --- astrbot/core/umop_config_router.py | 19 ++ astrbot/dashboard/routes/chat.py | 14 +- dashboard/src/components/chat/Chat.vue | 2 + dashboard/src/components/chat/ChatInput.vue | 32 +- .../src/components/chat/ConfigSelector.vue | 311 ++++++++++++++++++ .../components/chat/ProviderModelSelector.vue | 1 + dashboard/src/composables/useSessions.ts | 8 +- dashboard/src/views/ProviderPage.vue | 11 +- 8 files changed, 388 insertions(+), 10 deletions(-) create mode 100644 dashboard/src/components/chat/ConfigSelector.vue diff --git a/astrbot/core/umop_config_router.py b/astrbot/core/umop_config_router.py index 07858da5..27f6232a 100644 --- a/astrbot/core/umop_config_router.py +++ b/astrbot/core/umop_config_router.py @@ -85,3 +85,22 @@ class UmopConfigRouter: self.umop_to_conf_id[umo] = conf_id await self.sp.global_put("umop_config_routing", self.umop_to_conf_id) + + async def delete_route(self, umo: str): + """删除一条路由 + + Args: + umo (str): 需要删除的 UMO 字符串 + + Raises: + ValueError: 当 umo 格式不正确时抛出 + """ + + if not isinstance(umo, str) or len(umo.split(":")) != 3: + raise ValueError( + "umop must be a string in the format [platform_id]:[message_type]:[session_id], with optional wildcards * or empty for all", + ) + + if umo in self.umop_to_conf_id: + del self.umop_to_conf_id[umo] + await self.sp.global_put("umop_config_routing", self.umop_to_conf_id) diff --git a/astrbot/dashboard/routes/chat.py b/astrbot/dashboard/routes/chat.py index 1ad78956..5381b564 100644 --- a/astrbot/dashboard/routes/chat.py +++ b/astrbot/dashboard/routes/chat.py @@ -56,6 +56,7 @@ class ChatRoute(Route): self.conv_mgr = core_lifecycle.conversation_manager self.platform_history_mgr = core_lifecycle.platform_message_history_manager self.db = db + self.umop_config_router = core_lifecycle.umop_config_router self.running_convs: dict[str, bool] = {} @@ -266,7 +267,8 @@ class ChatRoute(Route): return Response().error("Permission denied").__dict__ # 删除该会话下的所有对话 - unified_msg_origin = f"{session.platform_id}:FriendMessage:{session.platform_id}!{username}!{session_id}" + message_type = "GroupMessage" if session.is_group else "FriendMessage" + unified_msg_origin = f"{session.platform_id}:{message_type}:{session.platform_id}!{username}!{session_id}" await self.conv_mgr.delete_conversations_by_user_id(unified_msg_origin) # 删除消息历史 @@ -276,6 +278,16 @@ class ChatRoute(Route): offset_sec=99999999, ) + # 删除与会话关联的配置路由 + try: + await self.umop_config_router.delete_route(unified_msg_origin) + except ValueError as exc: + logger.warning( + "Failed to delete UMO route %s during session cleanup: %s", + unified_msg_origin, + exc, + ) + # 清理队列(仅对 webchat) if session.platform_id == "webchat": webchat_queue_mgr.remove_queues(session_id) diff --git a/dashboard/src/components/chat/Chat.vue b/dashboard/src/components/chat/Chat.vue index 09acd1b7..ff034940 100644 --- a/dashboard/src/components/chat/Chat.vue +++ b/dashboard/src/components/chat/Chat.vue @@ -87,6 +87,8 @@ :disabled="isStreaming || isConvRunning" :enableStreaming="enableStreaming" :isRecording="isRecording" + :session-id="currSessionId || null" + :current-session="getCurrentSession" @send="handleSendMessage" @toggleStreaming="toggleStreaming" @removeImage="removeImage" diff --git a/dashboard/src/components/chat/ChatInput.vue b/dashboard/src/components/chat/ChatInput.vue index 7ca0ec94..cad1b720 100644 --- a/dashboard/src/components/chat/ChatInput.vue +++ b/dashboard/src/components/chat/ChatInput.vue @@ -11,7 +11,13 @@ style="width: 100%; resize: none; outline: none; border: 1px solid var(--v-theme-border); border-radius: 12px; padding: 8px 16px; min-height: 40px; font-family: inherit; font-size: 16px; background-color: var(--v-theme-surface);">