diff --git a/web/src/assets/images/conversation/ai.png b/web/src/assets/images/conversation/ai.png new file mode 100644 index 00000000..3783a543 Binary files /dev/null and b/web/src/assets/images/conversation/ai.png differ diff --git a/web/src/assets/images/conversation/user.png b/web/src/assets/images/conversation/user.png new file mode 100644 index 00000000..671ab044 Binary files /dev/null and b/web/src/assets/images/conversation/user.png differ diff --git a/web/src/components/PageScrollList/index.tsx b/web/src/components/PageScrollList/index.tsx index fd449848..f3ef0f86 100644 --- a/web/src/components/PageScrollList/index.tsx +++ b/web/src/components/PageScrollList/index.tsx @@ -2,7 +2,7 @@ * @Author: ZhaoYing * @Date: 2026-02-02 15:18:19 * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-03-27 15:52:37 + * @Last Modified time: 2026-03-31 15:31:18 */ /** * PageScrollList Component @@ -48,7 +48,7 @@ interface PageScrollListProps> { /** 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!"