diff --git a/core/web_terminal.py b/core/web_terminal.py index 7f7cbbd..964574d 100644 --- a/core/web_terminal.py +++ b/core/web_terminal.py @@ -393,10 +393,10 @@ class WebTerminal(MainTerminal): "message": f"加载对话异常: {e}" } - def get_conversations_list(self, limit: int = 20, offset: int = 0, non_empty: bool = False) -> Dict: + def get_conversations_list(self, limit: int = 20, offset: int = 0, non_empty: bool = False, multi_agent_mode: Optional[bool] = None) -> Dict: """获取对话列表(Web版本)""" try: - result = self.context_manager.get_conversation_list(limit=limit, offset=offset, non_empty=non_empty) + result = self.context_manager.get_conversation_list(limit=limit, offset=offset, non_empty=non_empty, multi_agent_mode=multi_agent_mode) return { "success": True, "data": result diff --git a/server/conversation.py b/server/conversation.py index 4d97d5d..3c4db1c 100644 --- a/server/conversation.py +++ b/server/conversation.py @@ -525,6 +525,14 @@ def get_conversations(terminal: WebTerminal, workspace: UserWorkspace, username: limit = request.args.get('limit', 20, type=int) offset = request.args.get('offset', 0, type=int) non_empty = request.args.get('non_empty', '0') in ('1', 'true', 'True') + # multi_agent_mode: '1' 仅多智能体模式对话;'0' 仅常规对话;未传 None 不过滤 + ma_param = request.args.get('multi_agent_mode', None) + if ma_param in ('1', 'true', 'True'): + multi_agent_filter: Optional[bool] = True + elif ma_param in ('0', 'false', 'False'): + multi_agent_filter = False + else: + multi_agent_filter = None target_workspace_id = request.args.get('workspace_id', '', type=str).strip() # 限制参数范围 @@ -541,7 +549,7 @@ def get_conversations(terminal: WebTerminal, workspace: UserWorkspace, username: except RuntimeError as exc: return jsonify({"success": False, "error": str(exc)}), 503 - result = terminal.get_conversations_list(limit=limit, offset=offset, non_empty=non_empty) + result = terminal.get_conversations_list(limit=limit, offset=offset, non_empty=non_empty, multi_agent_mode=multi_agent_filter) cm = getattr(getattr(terminal, "context_manager", None), "conversation_manager", None) write_host_workspace_debug( "sidebar-debug-api", diff --git a/static/src/app/methods/conversation/load.ts b/static/src/app/methods/conversation/load.ts index 50c172f..d0cbbd3 100644 --- a/static/src/app/methods/conversation/load.ts +++ b/static/src/app/methods/conversation/load.ts @@ -14,7 +14,9 @@ export const loadMethods = { const requestSeq = ++this.conversationListRequestSeq; this.conversationsLoading = true; try { - const response = await fetch(`/api/conversations?limit=${queryLimit}&offset=${queryOffset}`); + // 多智能体模式下只加载多智能体对话记录;常规模式排除多智能体对话 + const maParam = this.multiAgentMode ? '&multi_agent_mode=1' : '&multi_agent_mode=0'; + const response = await fetch(`/api/conversations?limit=${queryLimit}&offset=${queryOffset}${maParam}`); const data = await response.json(); if (data.success) { @@ -284,7 +286,8 @@ export const loadMethods = { if (group.loading || group.loadingMore) return; group.loading = true; try { - const response = await fetch(`/api/conversations?workspace_id=${encodeURIComponent(workspaceId)}&limit=${group.limit}&offset=${group.offset}`); + const maParam = this.multiAgentMode ? '&multi_agent_mode=1' : '&multi_agent_mode=0'; + const response = await fetch(`/api/conversations?workspace_id=${encodeURIComponent(workspaceId)}&limit=${group.limit}&offset=${group.offset}${maParam}`); const data = await response.json(); if (data.success) { const items = (data.data?.conversations || []).map((conv: any) => ({ diff --git a/utils/context_manager/conversation_mixin.py b/utils/context_manager/conversation_mixin.py index 91e8cf2..d9b95f7 100644 --- a/utils/context_manager/conversation_mixin.py +++ b/utils/context_manager/conversation_mixin.py @@ -325,9 +325,9 @@ class ConversationMixin: except Exception as e: print(f"⌘ 自动保存异常: {e}") - def get_conversation_list(self, limit: int = 50, offset: int = 0, non_empty: bool = False) -> Dict: + def get_conversation_list(self, limit: int = 50, offset: int = 0, non_empty: bool = False, multi_agent_mode: Optional[bool] = None) -> Dict: """获取对话列表""" - return self.conversation_manager.get_conversation_list(limit=limit, offset=offset, non_empty=non_empty) + return self.conversation_manager.get_conversation_list(limit=limit, offset=offset, non_empty=non_empty, multi_agent_mode=multi_agent_mode) def delete_conversation_by_id(self, conversation_id: str) -> bool: """删除指定对话""" diff --git a/utils/conversation_manager/list_search_mixin.py b/utils/conversation_manager/list_search_mixin.py index f5c3fe1..9edea48 100644 --- a/utils/conversation_manager/list_search_mixin.py +++ b/utils/conversation_manager/list_search_mixin.py @@ -47,7 +47,7 @@ class ConversationMetadata: class ListSearchMixin: """ConversationManager list search mixin 能力 mixin。""" - def get_conversation_list(self, limit: int = 50, offset: int = 0, non_empty: bool = False) -> Dict: + def get_conversation_list(self, limit: int = 50, offset: int = 0, non_empty: bool = False, multi_agent_mode: Optional[bool] = None) -> Dict: """ 获取对话列表 @@ -55,14 +55,26 @@ class ListSearchMixin: limit: 限制数量 offset: 偏移量 non_empty: 仅返回有内容(total_messages > 0)的对话,分页基于过滤后的结果 + multi_agent_mode: 若为 True 仅返回多智能体模式对话;若为 False 仅返回常规对话;None 不过滤 Returns: Dict: 包含对话列表和统计信息 """ t0 = time.perf_counter() if perf_log: - perf_log("get_conversation_list enter", extra={"limit": limit, "offset": offset, "non_empty": non_empty}) + perf_log("get_conversation_list enter", extra={"limit": limit, "offset": offset, "non_empty": non_empty, "multi_agent_mode": multi_agent_mode}) try: + def _filter_by_multi_agent(items): + """按 multi_agent_mode 元数据过滤。""" + if multi_agent_mode is None: + return items + result = [] + for conv_id, meta in items: + conv_ma = bool(meta.get("multi_agent_mode", False)) + if conv_ma == multi_agent_mode: + result.append((conv_id, meta)) + return result + if non_empty: # 过滤模式:全量加载后剔除空对话,再在过滤结果上分页, # 保证 total / has_more 与"有内容对话"的真实数量一致。 @@ -76,6 +88,8 @@ class ListSearchMixin: item for item in sorted_conversations if (item[1].get("total_messages", 0) or 0) > 0 ] + if multi_agent_mode is not None: + sorted_conversations = _filter_by_multi_agent(sorted_conversations) total = len(sorted_conversations) conversations = sorted_conversations[offset:offset + limit] else: @@ -91,8 +105,11 @@ class ListSearchMixin: reverse=True ) + if multi_agent_mode is not None: + sorted_conversations = _filter_by_multi_agent(sorted_conversations) + # 分页 - total = max(len(sorted_conversations), total_files) + total = max(len(sorted_conversations), total_files if multi_agent_mode is None else len(sorted_conversations)) conversations = sorted_conversations[offset:offset+limit] # 格式化结果 @@ -108,7 +125,8 @@ class ListSearchMixin: "thinking_mode": metadata.get("thinking_mode", False), "total_messages": metadata.get("total_messages", 0), "total_tools": metadata.get("total_tools", 0), - "status": metadata.get("status", "active") + "status": metadata.get("status", "active"), + "multi_agent_mode": bool(metadata.get("multi_agent_mode", False)) }) elapsed_ms = (time.perf_counter() - t0) * 1000