mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-20 06:34:55 +00:00
(feature)(supersonic-fe) add memory manage (#1287)
This commit is contained in:
@@ -277,7 +277,7 @@ const AgentForm: React.FC<Props> = ({ editAgent, onSaveAgent, onCreateToolBtnCli
|
||||
{
|
||||
label: '记忆管理',
|
||||
key: 'memory',
|
||||
children: <MemorySection />,
|
||||
children: <MemorySection agentId={editAgent!.id!} />,
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@@ -3,16 +3,22 @@ import { EditableProTable } from '@ant-design/pro-components';
|
||||
import React, { useState } from 'react';
|
||||
import { MemoryType, ReviewEnum, StatusEnum } from './type';
|
||||
import { getMemeoryList, saveMemory } from './service';
|
||||
import { Popover, Input, Badge, Radio } from 'antd';
|
||||
import { Popover, Input, Badge, Radio, Select } from 'antd';
|
||||
import styles from './style.less';
|
||||
|
||||
const { TextArea } = Input;
|
||||
const { TextArea, Search } = Input;
|
||||
const RadioGroup = Radio.Group;
|
||||
|
||||
const MemorySection = () => {
|
||||
type Props = {
|
||||
agentId: number;
|
||||
};
|
||||
|
||||
const MemorySection = ({ agentId }: Props) => {
|
||||
const [editableKeys, setEditableRowKeys] = useState<React.Key[]>([]);
|
||||
const [dataSource, setDataSource] = useState<readonly MemoryType[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [filters, setFilters] = useState<any>({});
|
||||
const { question, status, llmReviewRet, humanReviewRet } = filters;
|
||||
|
||||
const columns: ProColumns<MemoryType>[] = [
|
||||
{
|
||||
@@ -23,7 +29,7 @@ const MemorySection = () => {
|
||||
{
|
||||
title: 'Schema映射',
|
||||
dataIndex: 'dbSchema',
|
||||
width: 300,
|
||||
width: 220,
|
||||
valueType: 'textarea',
|
||||
renderFormItem: (_, { record }) => (
|
||||
<TextArea rows={3} disabled={record?.status === StatusEnum.ENABLED} />
|
||||
@@ -32,7 +38,7 @@ const MemorySection = () => {
|
||||
{
|
||||
title: '大模型解析SQL',
|
||||
dataIndex: 's2sql',
|
||||
width: 300,
|
||||
width: 220,
|
||||
valueType: 'textarea',
|
||||
renderFormItem: (_, { record }) => (
|
||||
<TextArea rows={3} disabled={record?.status === StatusEnum.ENABLED} />
|
||||
@@ -42,6 +48,7 @@ const MemorySection = () => {
|
||||
title: '大模型评估意见',
|
||||
dataIndex: 'llmReviewCmt',
|
||||
readonly: true,
|
||||
width: 200,
|
||||
render: (value) => {
|
||||
return (
|
||||
<Popover trigger="hover" content={<div className={styles.commentPopover}>{value}</div>}>
|
||||
@@ -155,9 +162,12 @@ const MemorySection = () => {
|
||||
},
|
||||
];
|
||||
|
||||
const loadMemoryList = async () => {
|
||||
const loadMemoryList = async ({
|
||||
filtersValue,
|
||||
current,
|
||||
}: { filtersValue?: any; current?: number } = {}) => {
|
||||
setLoading(true);
|
||||
const res = await getMemeoryList();
|
||||
const res = await getMemeoryList(agentId, filtersValue || filters, current || 1);
|
||||
setLoading(false);
|
||||
const { list, total } = res.data;
|
||||
return {
|
||||
@@ -171,25 +181,100 @@ const MemorySection = () => {
|
||||
await saveMemory(data);
|
||||
};
|
||||
|
||||
const onSearch = () => {
|
||||
loadMemoryList();
|
||||
};
|
||||
|
||||
return (
|
||||
<EditableProTable<MemoryType>
|
||||
rowKey="id"
|
||||
className={styles.memorySection}
|
||||
recordCreatorProps={false}
|
||||
loading={loading}
|
||||
columns={columns}
|
||||
request={loadMemoryList}
|
||||
value={dataSource}
|
||||
onChange={setDataSource}
|
||||
pagination={{}}
|
||||
editable={{
|
||||
type: 'multiple',
|
||||
editableKeys,
|
||||
actionRender: (row, config, defaultDom) => [defaultDom.save, defaultDom.cancel],
|
||||
onSave,
|
||||
onChange: setEditableRowKeys,
|
||||
}}
|
||||
/>
|
||||
<div className={styles.memorySection}>
|
||||
<div className={styles.filterSection}>
|
||||
<div className={styles.filterItem}>
|
||||
<div className={styles.filterItemTitle}>用户问题</div>
|
||||
<Search
|
||||
className={styles.filterItemControl}
|
||||
placeholder="请输入用户问题"
|
||||
value={question}
|
||||
onChange={(e) => {
|
||||
setFilters({ ...filters, question: e.target.value });
|
||||
}}
|
||||
onSearch={onSearch}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.filterItem}>
|
||||
<div className={styles.filterItemTitle}>大模型评估结果</div>
|
||||
<Select
|
||||
className={styles.filterItemControl}
|
||||
placeholder="请选择大模型评估结果"
|
||||
options={[
|
||||
{ label: '正确', value: ReviewEnum.POSITIVE },
|
||||
{ label: '错误', value: ReviewEnum.NEGATIVE },
|
||||
]}
|
||||
value={llmReviewRet}
|
||||
allowClear
|
||||
onChange={(value: ReviewEnum) => {
|
||||
const filtersValue = { ...filters, llmReviewRet: value };
|
||||
setFilters(filtersValue);
|
||||
loadMemoryList({ filtersValue });
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.filterItem}>
|
||||
<div className={styles.filterItemTitle}>管理员评估结果</div>
|
||||
<Select
|
||||
className={styles.filterItemControl}
|
||||
placeholder="请选择管理员评估结果"
|
||||
options={[
|
||||
{ label: '正确', value: ReviewEnum.POSITIVE },
|
||||
{ label: '错误', value: ReviewEnum.NEGATIVE },
|
||||
]}
|
||||
value={humanReviewRet}
|
||||
allowClear
|
||||
onChange={(value: ReviewEnum) => {
|
||||
const filtersValue = { ...filters, humanReviewRet: value };
|
||||
setFilters(filtersValue);
|
||||
loadMemoryList({ filtersValue });
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.filterItem}>
|
||||
<div className={styles.filterItemTitle}>状态</div>
|
||||
<Select
|
||||
className={styles.filterItemControl}
|
||||
placeholder="请选择状态"
|
||||
options={[
|
||||
{ label: '待定', value: StatusEnum.PENDING },
|
||||
{ label: '已启用', value: StatusEnum.ENABLED },
|
||||
{ label: '已禁用', value: StatusEnum.DISABLED },
|
||||
]}
|
||||
value={status}
|
||||
allowClear
|
||||
onChange={(value: ReviewEnum) => {
|
||||
const filtersValue = { ...filters, status: value };
|
||||
setFilters(filtersValue);
|
||||
loadMemoryList({ filtersValue });
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<EditableProTable<MemoryType>
|
||||
rowKey="id"
|
||||
recordCreatorProps={false}
|
||||
loading={loading}
|
||||
columns={columns}
|
||||
request={loadMemoryList}
|
||||
value={dataSource}
|
||||
onChange={setDataSource}
|
||||
pagination={{ pageSize: 10 }}
|
||||
sticky={{ offsetHeader: 0 }}
|
||||
editable={{
|
||||
type: 'multiple',
|
||||
editableKeys,
|
||||
actionRender: (row, config, defaultDom) => [defaultDom.save, defaultDom.cancel],
|
||||
onSave,
|
||||
onChange: setEditableRowKeys,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -42,12 +42,14 @@ export function testLLMConn(data: any) {
|
||||
});
|
||||
}
|
||||
|
||||
export function getMemeoryList() {
|
||||
export function getMemeoryList(agentId: number, chatMemoryFilter: any, current: number) {
|
||||
return request<Result<{ list: MetricType[] }>>('/api/chat/memory/pageMemories', {
|
||||
method: 'POST',
|
||||
data: {
|
||||
current: 1,
|
||||
pageSize: 2000,
|
||||
agentId,
|
||||
chatMemoryFilter,
|
||||
current,
|
||||
pageSize: 10,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -325,10 +325,40 @@
|
||||
.ant-pro-card-body {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.ant-input-search-button {
|
||||
width: 42px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.filterSection {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
row-gap: 12px;
|
||||
column-gap: 20px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.filterItem {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
column-gap: 12px;
|
||||
width: 22vw;
|
||||
|
||||
.filterItemTitle {
|
||||
margin-right: 6px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.filterItemControl {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.reviewComment {
|
||||
white-space: nowrap;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 4;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
}
|
||||
|
||||
.filterItemControl {
|
||||
// width: 20vw;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user