diff --git a/web/src/api/memory.ts b/web/src/api/memory.ts index 1a496961..750f559c 100644 --- a/web/src/api/memory.ts +++ b/web/src/api/memory.ts @@ -157,11 +157,11 @@ export const deleteMemoryConfig = (config_id: number) => { } // 遗忘引擎-获取配置 export const getMemoryForgetConfig = (config_id: number | string) => { - return request.get('/memory-storage/read_config_forget', { config_id }) + return request.get('/memory/forget/read_config', { config_id }) } // 遗忘引擎-更新配置 export const updateMemoryForgetConfig = (values: ForgetConfigForm) => { - return request.post('/memory-storage/update_config_forget', values) + return request.post('/memory/forget/update_config', values) } // 记忆萃取引擎-获取配置 export const getMemoryExtractionConfig = (config_id: number | string) => { diff --git a/web/src/views/ForgettingEngine/components/LineChart.tsx b/web/src/views/ForgettingEngine/components/LineChart.tsx index c6a0dfc0..6a77141f 100644 --- a/web/src/views/ForgettingEngine/components/LineChart.tsx +++ b/web/src/views/ForgettingEngine/components/LineChart.tsx @@ -3,6 +3,39 @@ import { useTranslation } from 'react-i18next' import ReactEcharts from 'echarts-for-react'; import type { ConfigForm } from '../types' +// 定义当前数据类型 +type CurrentDataItem = { + name: string; + data: number[]; + config: ConfigForm | {}; + type: string; + smooth: boolean; + lineStyle: { width: number }; + showSymbol: boolean; + label: { show: boolean; position: string }; + emphasis: { focus: string }; +}; + +// 定义图表系列数据类型 +type SeriesDataItem = { + name: string; + data: number[]; + config: ChartConfig; + type: string; + smooth: boolean; + lineStyle: { width: number }; + showSymbol: boolean; + label: { show: boolean; position: string }; + emphasis: { focus: string }; +}; + +// 定义简化的配置类型,只包含图表计算需要的属性 +interface ChartConfig { + lambda_mem: number; + lambda_time: number; + offset: number; +} + interface LineCardProps { config: ConfigForm } @@ -29,14 +62,14 @@ const Colors = ['#155EEF', '#4DA8FF', '#FFB048'] const LineChart: FC = ({ config }) => { const { t } = useTranslation() const chartRef = useRef(null); - const debounceRef = useRef() + const debounceRef = useRef() const resizeScheduledRef = useRef(false) const xAxisData = [1, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60] - const [initialData, setInitialData] = useState([]) - const [currentData, setCurrentData] = useState({ + const [initialData, setInitialData] = useState([]) + const [currentData, setCurrentData] = useState({ ...SeriesConfig, name: `${t('forgettingEngine.currentConfig')}(λ_time=${config?.lambda_mem})`, - data: [], + data: [] as number[], config: {} }) const seriesData = useMemo(() => [ @@ -44,19 +77,26 @@ const LineChart: FC = ({ config }) => { ...SeriesConfig, name: `${t('forgettingEngine.quicklyForget')}(λ_time=0.3)`, data: [], - config: {lambda_mem: 0.3, lambda_time: 1, offset: 0.05} + config: {lambda_mem: 0.3, lambda_time: 1, offset: 0.05} as ChartConfig }, { ...SeriesConfig, name: `${t('forgettingEngine.slowForgetting')}(λ_time=1)`, data: [], - config: {lambda_mem: 1, lambda_time: 0.3, offset: 0.2} + config: {lambda_mem: 1, lambda_time: 0.3, offset: 0.2} as ChartConfig } ], [t]) useEffect(() => { getInitData() - }, []) + }, [t]) + + useEffect(() => { + // 语言切换时重新生成数据 + if (config) { + getCaculateData(config) + } + }, [t, config]) useEffect(() => { const handleResize = () => { @@ -101,14 +141,14 @@ const LineChart: FC = ({ config }) => { setInitialData(list) }, [seriesData]) - const calculateSeriesData = useCallback((days: number, data: ConfigForm) => { + const calculateSeriesData = useCallback((days: number, data: ChartConfig | ConfigForm) => { const offset = Number(data.offset) const lambda_time = Number(data.lambda_time) const lambda_mem = Number(data.lambda_mem) // R = offset + (1 - offset) × e^(-λtime × t / (λmem × S)) return +(offset + (1 - offset) * Math.exp(-lambda_time * days / lambda_mem)).toFixed(4) }, []) - const formatData = useCallback((data: ConfigForm) => { + const formatData = useCallback((data: ChartConfig | ConfigForm) => { return xAxisData.map(days => Number(calculateSeriesData(days, data))) }, [calculateSeriesData]) diff --git a/web/src/views/ForgettingEngine/index.tsx b/web/src/views/ForgettingEngine/index.tsx index 7c940c1b..fed71da1 100644 --- a/web/src/views/ForgettingEngine/index.tsx +++ b/web/src/views/ForgettingEngine/index.tsx @@ -1,5 +1,5 @@ import React, { useState, useEffect } from 'react'; -import { Row, Col, Form, Slider, Button, Space, message } from 'antd'; +import { Row, Col, Form, Slider, Button, Space, message, Switch } from 'antd'; import { useParams } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import RbCard from '@/components/RbCard/Card'; @@ -18,19 +18,72 @@ const configList = [ { key: 'forgettingRate', name: 'lambda_mem', - range: [0, 1], + range: [0.01, 1], type: 'decimal', }, { key: 'offset', name: 'offset', + range: [0, 1], type: 'decimal', - } + }, + { + key: 'decay_constant', + name: 'decay_constant', + range: [0, 1], + type: 'decimal', + hiddenDesc: true, + }, + { + key: 'max_history_length', + name: 'max_history_length', + type: 'decimal', + step: 1, + range: [10, 1000], + hiddenDesc: true, + }, + { + key: 'forgetting_threshold', + name: 'forgetting_threshold', + type: 'decimal', + range: [0, 1], + hiddenDesc: true, + }, + { + key: 'min_days_since_access', + name: 'min_days_since_access', + type: 'decimal', + step: 1, + range: [1, 365], + hiddenDesc: true, + }, + { + key: 'enable_llm_summary', + name: 'enable_llm_summary', + type: 'button', + hiddenDesc: true, + }, + { + key: 'max_merge_batch_size', + name: 'max_merge_batch_size', + type: 'decimal', + step: 1, + range: [1, 1000], + hiddenDesc: true, + }, + { + key: 'forgetting_interval_hours', + name: 'forgetting_interval_hours', + type: 'decimal', + step: 1, + range: [1, 168], + hiddenDesc: true, + }, ] const ForgettingEngine: React.FC = () => { const { t } = useTranslation(); - const params = useParams(); + const { id } = useParams(); const [configData, setConfigData] = useState(); const [form] = Form.useForm(); const [messageApi, contextHolder] = message.useMessage(); @@ -43,7 +96,7 @@ const ForgettingEngine: React.FC = () => { }, []) const getConfigData = () => { - getMemoryForgetConfig(params.id) + getMemoryForgetConfig(id as string) .then((res) => { const response = res as ConfigForm const initialValues = { @@ -60,12 +113,12 @@ const ForgettingEngine: React.FC = () => { }) } const handleReset = () => { - form.setFieldsValue(configData); + form.setFieldsValue(configData || {}); } const handleSave = () => { setLoading(true) updateMemoryForgetConfig({ - config_id: params.id, + config_id: id, ...values }) .then(() => { @@ -83,7 +136,7 @@ const ForgettingEngine: React.FC = () => { - + {t('forgettingEngine.forgettingEngineConfigParams')} } @@ -99,28 +152,60 @@ const ForgettingEngine: React.FC = () => { }} > - {configList.map(config => ( -
-
- {t(`forgettingEngine.${config.key}`)} + {configList.map(config => { + if (config.type === 'button') { + return ( +
+
+
+ {t(`forgettingEngine.${config.key}`)} +
+ + + +
+
+ + {config.range && {t(`forgettingEngine.range`)}: {config.range?.join('-')}} + {config.type && {t(`forgettingEngine.type`)}: {config.type}} + +
+
+ ) + } + return ( +
+
+ {t(`forgettingEngine.${config.key}`)} +
+ {!config.hiddenDesc &&
+ {t(`forgettingEngine.${config.key}Desc`)} +
} + + + {config.type === 'decimal' + ? + : config.type === 'button' + ? + : null + } + +
+ + {config.range && {t(`forgettingEngine.range`)}: {config.range?.join('-')}} + {config.type && {t(`forgettingEngine.type`)}: {config.type}} + + <>{t('forgettingEngine.CurrentValue')}: {values?.[config.name] || 0} +
-
- {t(`forgettingEngine.${config.key}Desc`)} -
- - - -
- - {config.range && {t(`forgettingEngine.range`)}: {config.range?.join('-')}} - {config.type && {t(`forgettingEngine.type`)}: {config.type}} - - <>{t('forgettingEngine.CurrentValue')}: {values?.[config.name] || 0} -
-
- ))} + ) + })} @@ -135,7 +220,6 @@ const ForgettingEngine: React.FC = () => {