(feature)(supersonic-fe) add memory manage (#1279)

This commit is contained in:
williamhliu
2024-06-29 14:56:40 +08:00
committed by GitHub
parent a45fe183d2
commit ee86924205
7 changed files with 16717 additions and 14292 deletions

View File

@@ -183,5 +183,5 @@ export default defineConfig({
alias: {
'supersonic-chat-sdk': path.resolve(__dirname, '../../chat-sdk/src/'),
},
// esbuildMinifyIIFE: true,
esbuildMinifyIIFE: true,
});

View File

@@ -20,6 +20,7 @@ import { uuid, jsonParse, encryptPassword, decryptPassword } from '@/utils/utils
import ToolsSection from './ToolsSection';
import globalStyles from '@/global.less';
import { testLLMConn } from './service';
import MemorySection from './MemorySection';
const FormItem = Form.Item;
const { TextArea } = Input;
@@ -273,6 +274,11 @@ const AgentForm: React.FC<Props> = ({ editAgent, onSaveAgent, onCreateToolBtnCli
key: 'tools',
children: <ToolsSection currentAgent={editAgent} onSaveAgent={onSaveAgent} />,
},
{
label: '记忆管理',
key: 'memory',
children: <MemorySection />,
},
];
return (
@@ -288,6 +294,7 @@ const AgentForm: React.FC<Props> = ({ editAgent, onSaveAgent, onCreateToolBtnCli
<Tabs
tabBarExtraContent={
<Space>
{activeKey !== 'memory' && (
<Button
type="primary"
loading={saveLoading}
@@ -297,6 +304,7 @@ const AgentForm: React.FC<Props> = ({ editAgent, onSaveAgent, onCreateToolBtnCli
>
</Button>
)}
{activeKey === 'tools' && (
<Button
type="primary"

View File

@@ -0,0 +1,176 @@
import type { ProColumns } from '@ant-design/pro-components';
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 } from 'antd';
import styles from './style.less';
const { TextArea } = Input;
const MemorySection = () => {
const [editableKeys, setEditableRowKeys] = useState<React.Key[]>([]);
const [dataSource, setDataSource] = useState<readonly MemoryType[]>([]);
const [loading, setLoading] = useState(false);
const columns: ProColumns<MemoryType>[] = [
{
title: '用户问题',
dataIndex: 'question',
readonly: true,
},
{
title: 'Schema映射',
dataIndex: 'dbSchema',
width: 300,
valueType: 'textarea',
},
{
title: '大模型解析SQL',
dataIndex: 's2sql',
width: 300,
valueType: 'textarea',
},
{
title: '大模型评估意见',
dataIndex: 'llmReviewCmt',
readonly: true,
render: (value) => {
return (
<Popover trigger="hover" content={<div className={styles.commentPopover}>{value}</div>}>
<div className={styles.reviewComment}>{value}</div>
</Popover>
);
},
},
{
title: '大模型评估结果',
key: 'llmReviewRet',
dataIndex: 'llmReviewRet',
readonly: true,
width: 150,
valueEnum: {
[ReviewEnum.POSITIVE]: {
text: '正确',
status: 'Success',
},
[ReviewEnum.NEGATIVE]: {
text: '错误',
status: 'Error',
},
},
},
{
title: '管理员评估意见',
dataIndex: 'humanReviewCmt',
valueType: 'textarea',
renderFormItem: () => <TextArea rows={12} />,
render: (value) => {
return value === '-' ? (
'-'
) : (
<Popover trigger="hover" content={<div className={styles.commentPopover}>{value}</div>}>
<div className={styles.reviewComment}>{value}</div>
</Popover>
);
},
},
{
title: '管理员评估结果',
key: 'humanReviewRet',
dataIndex: 'humanReviewRet',
width: 150,
valueType: 'radio',
valueEnum: {
[ReviewEnum.POSITIVE]: {
text: '正确',
status: 'Success',
},
[ReviewEnum.NEGATIVE]: {
text: '错误',
status: 'Error',
},
},
},
{
title: '状态',
key: 'status',
dataIndex: 'status',
valueType: 'radio',
width: 120,
valueEnum: {
[StatusEnum.PENDING]: { text: '待定' },
[StatusEnum.ENABLED]: {
text: '启用',
},
[StatusEnum.DISABLED]: {
text: '禁用',
},
},
render: (_, record) => {
const { status } = record;
if (status === StatusEnum.PENDING) {
return <Badge status="default" text="待定" />;
} else if (status === StatusEnum.ENABLED) {
return <Badge status="success" text="已启用" />;
} else {
return <Badge status="error" text="已禁用" />;
}
},
},
{
title: '操作',
valueType: 'option',
width: 150,
render: (text, record, _, action) => [
<a
key="editable"
onClick={() => {
action?.startEditable?.(record.id);
}}
>
</a>,
],
},
];
const loadMemoryList = async () => {
setLoading(true);
const res = await getMemeoryList();
setLoading(false);
const { list, total } = res.data;
return {
data: list,
total: total,
success: true,
};
};
const onSave = async (_: any, data: any) => {
await saveMemory(data);
};
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,
}}
/>
);
};
export default MemorySection;

View File

@@ -1,5 +1,5 @@
import { request } from 'umi';
import { AgentType, MetricType, ModelType } from './type';
import { AgentType, MemoryType, MetricType, ModelType } from './type';
export function getAgentList() {
return request<Result<AgentType[]>>('/api/chat/agent/getAgentList');
@@ -41,3 +41,20 @@ export function testLLMConn(data: any) {
data,
});
}
export function getMemeoryList() {
return request<Result<{ list: MetricType[] }>>('/api/chat/memory/pageMemories', {
method: 'POST',
data: {
current: 1,
pageSize: 2000,
},
});
}
export function saveMemory(data: MemoryType) {
return request<Result<string>>('/api/chat/memory/updateMemory', {
method: 'POST',
data,
});
}

View File

@@ -112,7 +112,7 @@
overflow: hidden;
font-size: 12px;
margin-top: 4px;
color: var(--text-color-third)
color: var(--text-color-third);
}
}
}
@@ -316,3 +316,24 @@
align-items: center;
column-gap: 12px;
}
.memorySection {
margin-top: 10px;
margin-bottom: 30px;
:global {
.ant-pro-card-body {
padding: 0;
}
}
.reviewComment {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
}
.commentPopover {
width: 400px;
}

View File

@@ -102,3 +102,31 @@ export type MetricType = {
name: string;
bizName: string;
};
export enum StatusEnum {
PENDING = 'PENDING',
ENABLED = 'ENABLED',
DISABLED = 'DISABLED',
}
export enum ReviewEnum {
POSITIVE = 'POSITIVE',
NEGATIVE = 'NEGATIVE',
}
export type MemoryType = {
id: number;
question: string;
agent_id: number;
db_schema: string;
s2_sql: string;
status: StatusEnum;
llm_review: ReviewEnum;
llm_comment: string;
human_review: ReviewEnum;
human_comment: string;
created_at: string;
updated_at: string;
created_by: string;
updated_by: string;
};

30735
webapp/pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff