diff --git a/src/renderer/src/pages/home/Messages/CitationsList.tsx b/src/renderer/src/pages/home/Messages/CitationsList.tsx index 51a7ca36..216e6cdf 100644 --- a/src/renderer/src/pages/home/Messages/CitationsList.tsx +++ b/src/renderer/src/pages/home/Messages/CitationsList.tsx @@ -1,7 +1,8 @@ import Favicon from '@renderer/components/Icons/FallbackFavicon' import { HStack } from '@renderer/components/Layout' -import { FileSearch } from 'lucide-react' +import { FileSearch, Info } from 'lucide-react' import React from 'react' +import { useTranslation } from 'react-i18next' import styled from 'styled-components' interface Citation { @@ -19,11 +20,16 @@ interface CitationsListProps { } const CitationsList: React.FC = ({ citations }) => { - console.log('CitationsList', citations) + const { t } = useTranslation() + if (!citations || citations.length === 0) return null return ( + + {t('message.citations')} + + {citations.map((citation) => ( {citation.number}. @@ -83,7 +89,7 @@ const KnowledgeCitation: React.FC<{ citation: Citation }> = ({ citation }) => { const CitationsContainer = styled.div` background-color: rgb(242, 247, 253); - border-radius: 4px; + border-radius: 10px; padding: 8px 12px; margin: 12px 0; display: flex; @@ -95,6 +101,15 @@ const CitationsContainer = styled.div` } ` +const CitationsTitle = styled.div` + font-weight: 500; + margin-bottom: 4px; + color: var(--color-text-1); + display: flex; + align-items: center; + gap: 6px; +` + const CitationLink = styled.a` font-size: 14px; line-height: 1.6; diff --git a/src/renderer/src/pages/home/Messages/MessageContent.tsx b/src/renderer/src/pages/home/Messages/MessageContent.tsx index 2a4d164b..2e630192 100644 --- a/src/renderer/src/pages/home/Messages/MessageContent.tsx +++ b/src/renderer/src/pages/home/Messages/MessageContent.tsx @@ -1,4 +1,4 @@ -import { DownOutlined, InfoCircleOutlined, SyncOutlined, TranslationOutlined, UpOutlined } from '@ant-design/icons' +import { SyncOutlined, TranslationOutlined } from '@ant-design/icons' import { isOpenAIWebSearch } from '@renderer/config/models' import { getModelUniqId } from '@renderer/services/ModelService' import { Message, Model } from '@renderer/types' @@ -7,7 +7,7 @@ import { withMessageThought } from '@renderer/utils/formats' import { Divider, Flex } from 'antd' import { clone } from 'lodash' import { Search } from 'lucide-react' -import React, { Fragment, useMemo, useState } from 'react' +import React, { Fragment, useMemo } from 'react' import { useTranslation } from 'react-i18next' import BarLoader from 'react-spinners/BarLoader' import BeatLoader from 'react-spinners/BeatLoader' @@ -30,7 +30,6 @@ const MessageContent: React.FC = ({ message: _message, model }) => { const { t } = useTranslation() const message = withMessageThought(clone(_message)) const isWebCitation = model && (isOpenAIWebSearch(model) || model.provider === 'openrouter') - const [citationsCollapsed, setCitationsCollapsed] = useState(true) // HTML实体编码辅助函数 const encodeHTML = (str: string) => { @@ -140,10 +139,11 @@ const MessageContent: React.FC = ({ message: _message, model }) => { return data }, [ formattedCitations, - message?.metadata?.annotations, - message?.metadata?.groundingMetadata?.groundingChunks, - message?.metadata?.webSearch?.results, - message?.metadata?.webSearchInfo + message.metadata?.annotations, + message.metadata?.groundingMetadata?.groundingChunks, + message.metadata?.knowledge, + message.metadata?.webSearch?.results, + message.metadata?.webSearchInfo ]) // Process content to make citation numbers clickable @@ -251,83 +251,71 @@ const MessageContent: React.FC = ({ message: _message, model }) => { )} {hasCitations && ( - - setCitationsCollapsed(!citationsCollapsed)}> -
- {t('message.citations')} - -
- {citationsCollapsed ? : } -
- - {!citationsCollapsed && ( - - {message?.metadata?.groundingMetadata && message.status === 'success' && ( - <> - ({ - number: index + 1, - url: chunk?.web?.uri || '', - title: chunk?.web?.title, - showFavicon: false - })) || [] - } - /> - - - )} - {formattedCitations && ( - ({ - number: citation.number, - url: citation.url, - hostname: citation.hostname, - showFavicon: isWebCitation - }))} - /> - )} - {(message?.metadata?.webSearch || message.metadata?.knowledge) && message.status === 'success' && ( - ({ - number: index + 1, - url: result.url, - title: result.title, - showFavicon: true, - type: 'websearch' - })) || []), - ...(message.metadata.knowledge?.map((result, index) => ({ - number: (message.metadata?.webSearch?.results?.length || 0) + index + 1, - url: result.sourceUrl, - title: result.sourceUrl, - showFavicon: true, - type: 'knowledge' - })) || []) - ]} - /> - )} - {message?.metadata?.webSearchInfo && message.status === 'success' && ( - ({ + <> + {message?.metadata?.groundingMetadata && message.status === 'success' && ( + <> + ({ number: index + 1, - url: result.link || result.url, - title: result.title, - showFavicon: true - }))} - /> - )} - + url: chunk?.web?.uri || '', + title: chunk?.web?.title, + showFavicon: false + })) || [] + } + /> + + )} -
+ {formattedCitations && ( + ({ + number: citation.number, + url: citation.url, + hostname: citation.hostname, + showFavicon: isWebCitation + }))} + /> + )} + {(message?.metadata?.webSearch || message.metadata?.knowledge) && message.status === 'success' && ( + ({ + number: index + 1, + url: result.url, + title: result.title, + showFavicon: true, + type: 'websearch' + })) || []), + ...(message.metadata.knowledge?.map((result, index) => ({ + number: (message.metadata?.webSearch?.results?.length || 0) + index + 1, + url: result.sourceUrl, + title: result.sourceUrl, + showFavicon: true, + type: 'knowledge' + })) || []) + ]} + /> + )} + {message?.metadata?.webSearchInfo && message.status === 'success' && ( + ({ + number: index + 1, + url: result.link || result.url, + title: result.title, + showFavicon: true + }))} + /> + )} + )} @@ -335,30 +323,6 @@ const MessageContent: React.FC = ({ message: _message, model }) => { ) } -const CitationsContainer = styled.div` - margin-top: 12px; - border: 1px solid var(--color-border); - border-radius: 8px; - overflow: hidden; -` - -const CitationsHeader = styled.div` - display: flex; - justify-content: space-between; - align-items: center; - padding: 8px 12px; - background-color: var(--color-background-mute); - cursor: pointer; - - &:hover { - background-color: var(--color-border); - } -` - -const CitationsContent = styled.div` - padding: 10px; - background-color: var(--color-background-mute); -` const MessageContentLoading = styled.div` display: flex; flex-direction: row;