From df8b97017a67d1bb77f836254480c66c7215c066 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=82=96=E6=B3=BD=E6=B6=9B?= Date: Tue, 24 Feb 2026 14:22:11 +0800 Subject: [PATCH] feat(web): add collapsible source panel with kb and web groups --- web/src/components/AgentChatComponent.vue | 15 +- .../components/ConversationSourcesPanel.vue | 120 ++++ web/src/components/KnowledgeSourceSection.vue | 28 + .../tools/KnowledgeBaseTool.vue | 511 +----------------- .../ToolCallingResult/tools/WebSearchTool.vue | 122 +---- web/src/components/WebSearchSourceSection.vue | 28 + .../components/sources/KbChunkDetailModal.vue | 96 ++++ .../sources/KbResultGroupedList.vue | 298 ++++++++++ .../sources/WebSearchResultList.vue | 114 ++++ web/src/utils/messageProcessor.js | 171 +++++- 10 files changed, 900 insertions(+), 603 deletions(-) create mode 100644 web/src/components/ConversationSourcesPanel.vue create mode 100644 web/src/components/KnowledgeSourceSection.vue create mode 100644 web/src/components/WebSearchSourceSection.vue create mode 100644 web/src/components/sources/KbChunkDetailModal.vue create mode 100644 web/src/components/sources/KbResultGroupedList.vue create mode 100644 web/src/components/sources/WebSearchResultList.vue diff --git a/web/src/components/AgentChatComponent.vue b/web/src/components/AgentChatComponent.vue index b2468efa..39157311 100644 --- a/web/src/components/AgentChatComponent.vue +++ b/web/src/components/AgentChatComponent.vue @@ -87,6 +87,10 @@ :show-refs="['model', 'copy']" :is-latest-message="false" /> + @@ -215,6 +219,7 @@ import HumanApprovalModal from '@/components/HumanApprovalModal.vue' import { useApproval } from '@/composables/useApproval' import { useAgentStreamHandler } from '@/composables/useAgentStreamHandler' import AgentPanel from '@/components/AgentPanel.vue' +import ConversationSourcesPanel from '@/components/ConversationSourcesPanel.vue' // ==================== PROPS & EMITS ==================== const props = defineProps({ @@ -692,7 +697,9 @@ const fetchAgentState = async (agentId, threadId) => { const newTs = getThreadState(threadId) if (newTs) newTs.agentState = res.agent_state || null } - } catch (error) {} + } catch { + // 忽略状态拉取失败,不阻塞主流程 + } } const fetchMentionResources = async () => { @@ -716,7 +723,7 @@ const ensureActiveThread = async (title = '新的对话') => { chatState.currentThreadId = newThread.id return newThread.id } - } catch (error) { + } catch { // createThread 已处理错误提示 } return null @@ -1187,6 +1194,10 @@ const showMsgRefs = (msg) => { return false } +const getConversationSources = (conv) => { + return MessageProcessor.extractSourcesFromConversation(conv, availableKnowledgeBases.value) +} + // ==================== LIFECYCLE & WATCHERS ==================== const loadChatsList = async () => { const agentId = currentAgentId.value diff --git a/web/src/components/ConversationSourcesPanel.vue b/web/src/components/ConversationSourcesPanel.vue new file mode 100644 index 00000000..9b7ae43f --- /dev/null +++ b/web/src/components/ConversationSourcesPanel.vue @@ -0,0 +1,120 @@ + + + + + diff --git a/web/src/components/KnowledgeSourceSection.vue b/web/src/components/KnowledgeSourceSection.vue new file mode 100644 index 00000000..512e83ec --- /dev/null +++ b/web/src/components/KnowledgeSourceSection.vue @@ -0,0 +1,28 @@ + + + + + diff --git a/web/src/components/ToolCallingResult/tools/KnowledgeBaseTool.vue b/web/src/components/ToolCallingResult/tools/KnowledgeBaseTool.vue index b57bfede..f39f8b38 100644 --- a/web/src/components/ToolCallingResult/tools/KnowledgeBaseTool.vue +++ b/web/src/components/ToolCallingResult/tools/KnowledgeBaseTool.vue @@ -10,129 +10,16 @@ - diff --git a/web/src/components/ToolCallingResult/tools/WebSearchTool.vue b/web/src/components/ToolCallingResult/tools/WebSearchTool.vue index fc1b9b1e..ed838fea 100644 --- a/web/src/components/ToolCallingResult/tools/WebSearchTool.vue +++ b/web/src/components/ToolCallingResult/tools/WebSearchTool.vue @@ -9,36 +9,10 @@