From 52ae914e1711923086fd694c9832605a72220612 Mon Sep 17 00:00:00 2001 From: zhaoying Date: Tue, 31 Mar 2026 15:43:18 +0800 Subject: [PATCH] feat(web): rag content api --- web/src/assets/images/conversation/ai.png | Bin 0 -> 6364 bytes web/src/assets/images/conversation/user.png | Bin 0 -> 7990 bytes web/src/components/PageScrollList/index.tsx | 16 ++++-- web/src/components/RbModal/index.css | 3 ++ web/src/i18n/en.ts | 7 +++ web/src/i18n/zh.ts | 6 +++ web/src/views/UserMemoryDetail/Rag.tsx | 6 +-- .../components/ConversationMemory.tsx | 48 ++++++++++++++---- 8 files changed, 68 insertions(+), 18 deletions(-) create mode 100644 web/src/assets/images/conversation/ai.png create mode 100644 web/src/assets/images/conversation/user.png diff --git a/web/src/assets/images/conversation/ai.png b/web/src/assets/images/conversation/ai.png new file mode 100644 index 0000000000000000000000000000000000000000..3783a5436736da0e92bf5c19a27081878ca1ec33 GIT binary patch literal 6364 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 { /** API endpoint URL */ url: string; /** Function to render each list item */ - renderItem: (item: T) => React.ReactNode; + renderItem: (item: T, index: number) => React.ReactNode; /** Query parameters for API request */ query?: Q; /** Number of columns in grid layout */ @@ -57,6 +57,8 @@ interface PageScrollListProps> { className?: string; needLoading?: boolean; heightClass?: string; + gutter?: [number, number] | number; + onTotalChange?: (total: number) => void; } const defaultHeightClass = 'rb:h-[calc(100vh-116px)]!'; @@ -70,6 +72,8 @@ const PageScrollList = forwardRef(>({ className = '', needLoading = true, heightClass, + gutter = [12, 12], + onTotalChange, }: PageScrollListProps, ref: React.Ref) => { /** Expose refresh method to parent component */ useImperativeHandle(ref, () => ({ @@ -88,6 +92,7 @@ const PageScrollList = forwardRef(>({ const pageRef = useRef(1); const loadingRef = useRef(false); const hasMoreRef = useRef(true); + const [total, setTotal] = useState(0); /** Load more data from API with pagination */ const loadMoreData = (reset?: boolean) => { @@ -107,6 +112,9 @@ const PageScrollList = forwardRef(>({ setData(prev => reset ? results : [...prev, ...results]); hasMoreRef.current = response.page?.hasnext; setHasMore(response.page?.hasnext); + const newTotal = response.page?.total || 0; + setTotal(newTotal); + onTotalChange?.(newTotal); }) .catch(() => { hasMoreRef.current = false; @@ -156,11 +164,11 @@ const PageScrollList = forwardRef(>({ {/* Render grid list or empty state */} {data.length > 0 ? ( {data.map((item, index) => ( - {renderItem(item)} + {renderItem(item, index)} ))} diff --git a/web/src/components/RbModal/index.css b/web/src/components/RbModal/index.css index 8dabc4ab..56d95248 100644 --- a/web/src/components/RbModal/index.css +++ b/web/src/components/RbModal/index.css @@ -1,3 +1,6 @@ +.rb-modal { + top: 40px; +} .rb-modal .ant-modal-footer .ant-btn { height: 32px !important; padding: 0 15px !important; diff --git a/web/src/i18n/en.ts b/web/src/i18n/en.ts index 2975796a..294b9bae 100644 --- a/web/src/i18n/en.ts +++ b/web/src/i18n/en.ts @@ -627,6 +627,8 @@ export const en = { vision: 'Vision', audio: 'Audio', video: 'Video', + thinking: 'Deep Thinking', + is_thinking: 'Deep Thinking Support', }, knowledgeBase: { home: 'Home', @@ -1421,6 +1423,7 @@ export const en = { citation: 'Citation and Attribution', citation_desc: 'Display the attribution of source documents and generated content', invalidVariablesTitle: "The following undefined variables are referenced in the conversation opening. Do you want to save the opening configuration?", + deep_thinking: 'Enable Deep Thinking', apps: 'My Apps', sharing: 'Sharing', @@ -1594,6 +1597,8 @@ export const en = { core_entities: 'Core Entities', communityDetailEmptyDesc: 'Click on a community in the chart on the left to view details', communityLoadingTip: 'Generating community graph', + assistant: 'AI Assistant', + totalRagMemory: 'Total number of memories', }, space: { createSpace: 'Create Space', @@ -1828,6 +1833,8 @@ Memory Bear: After the rebellion, regional warlordism intensified for several re memoryTipTitle: 'Are you sure you want to enable conversation memory? Conversations will be saved to the memory store.', stopAudioRecorder: 'Stop Recording', startAudioRecorder: 'Start Recording', + citations: 'Citations', + reasoning_content: 'Deep reasoning Content', }, login: { title: 'Red Bear Memory Science', diff --git a/web/src/i18n/zh.ts b/web/src/i18n/zh.ts index 3edd84e3..38b2a76a 100644 --- a/web/src/i18n/zh.ts +++ b/web/src/i18n/zh.ts @@ -795,6 +795,7 @@ export const zh = { citation: '引用和归属', citation_desc: '显示源文档和生成内容的归属部分', invalidVariablesTitle: "对话开场白中引用了以下未定义的变量,是否保存开场白配置?", + deep_thinking: '开启深度思考', apps: '我的应用', sharing: '共享', @@ -1274,6 +1275,8 @@ export const zh = { vision: '视觉', audio: '音频', video: '视频', + thinking: '深度思考', + is_thinking: '支持深度思考', }, timezones: { 'Asia/Shanghai': '中国标准时间 (UTC+8)', @@ -1592,6 +1595,8 @@ export const zh = { core_entities: '核心实体', communityDetailEmptyDesc: '点击左侧图表中的社区查看详情', communityLoadingTip: '社区图谱生成中', + assistant: 'AI 助手', + totalRagMemory: '记忆总数', }, space: { createSpace: '创建空间', @@ -1825,6 +1830,7 @@ export const zh = { stopAudioRecorder: '停止录音', startAudioRecorder: '开始录音', citations: '引用', + reasoning_content: '深度思考内容', }, login: { title: '红熊记忆科学', diff --git a/web/src/views/UserMemoryDetail/Rag.tsx b/web/src/views/UserMemoryDetail/Rag.tsx index f770fafc..a11d4295 100644 --- a/web/src/views/UserMemoryDetail/Rag.tsx +++ b/web/src/views/UserMemoryDetail/Rag.tsx @@ -2,7 +2,7 @@ * @Author: ZhaoYing * @Date: 2026-02-03 17:57:11 * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-03-27 10:26:31 + * @Last Modified time: 2026-03-31 15:29:45 */ /** * RAG User Memory Detail View @@ -114,7 +114,7 @@ const Rag: FC = () => { } return ( - + { - + diff --git a/web/src/views/UserMemoryDetail/components/ConversationMemory.tsx b/web/src/views/UserMemoryDetail/components/ConversationMemory.tsx index f956eca4..c209274b 100644 --- a/web/src/views/UserMemoryDetail/components/ConversationMemory.tsx +++ b/web/src/views/UserMemoryDetail/components/ConversationMemory.tsx @@ -2,38 +2,64 @@ * @Author: ZhaoYing * @Date: 2026-02-03 18:34:04 * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-03-27 10:28:53 + * @Last Modified time: 2026-03-31 15:35:13 */ -import { type FC } from 'react' +import { type FC, useState } from 'react' import { useTranslation } from 'react-i18next' import { useParams } from 'react-router-dom' +import { Divider, Flex } from 'antd' +import clsx from 'clsx' import RbCard from '@/components/RbCard/Card' import PageScrollList from '@/components/PageScrollList' import Markdown from '@/components/Markdown' import { getRagContentUrl } from '@/api/memory' +interface DataItem { + role: 'user' | 'assistant'; + content: string; +} + const ConversationMemory: FC = () => { const { t } = useTranslation() const { id } = useParams() + const [total, setTotal] = useState(0) return ( {t('userMemory.conversationMemory')}} headerType="borderless" - headerClassName="rb:min-h-[54px]! rb:pt-0! rb:mb-0! rb:font-[MiSans-Bold] rb:font-bold" - bodyClassName="rb:p-4! rb:pt-0! rb:h-[calc(100%-54px)]!" + headerClassName="rb:min-h-[54px]! rb:pt-0! rb:mb-0!" + bodyClassName="rb:p-4! rb:pt-0! rb:pb-1! rb:h-[calc(100%-54px)]!" className="rb:h-full!" + extra={
{t('userMemory.totalRagMemory')}: {total}
} > - + url={getRagContentUrl} query={{ end_user_id: id }} column={1} - renderItem={(item: string) => ( -
- + gutter={0} + onTotalChange={setTotal} + renderItem={(item, index) => ( +
+ {index !== 0 && } + +
+
+
+ {item.role === 'assistant' ? t('userMemory.assistant') : t('userMemory.user')} +
+ +
+
)} className="rb:h-full!"