(feature)(supersonic-fe) add memory manage to agent (#1284)

This commit is contained in:
williamhliu
2024-06-29 16:47:14 +08:00
committed by GitHub
parent e771efba3f
commit f096c44de0
5 changed files with 79 additions and 37 deletions

View File

@@ -187,9 +187,7 @@ const SqlItem: React.FC<Props> = ({
<div className={`${prefixCls}-few-shot-content`}> <div className={`${prefixCls}-few-shot-content`}>
<div className={`${prefixCls}-few-shot-content-item`}> <div className={`${prefixCls}-few-shot-content-item`}>
<div className={`${prefixCls}-few-shot-content-title`}></div> <div className={`${prefixCls}-few-shot-content-title`}></div>
<div className={`${prefixCls}-few-shot-content-text`}> <div className={`${prefixCls}-few-shot-content-text`}>{item.question}</div>
{item.questionAugmented}
</div>
</div> </div>
<div className={`${prefixCls}-few-shot-content-item`}> <div className={`${prefixCls}-few-shot-content-item`}>
<div className={`${prefixCls}-few-shot-content-title`}>SQL</div> <div className={`${prefixCls}-few-shot-content-title`}>SQL</div>

View File

@@ -3,10 +3,11 @@ import { EditableProTable } from '@ant-design/pro-components';
import React, { useState } from 'react'; import React, { useState } from 'react';
import { MemoryType, ReviewEnum, StatusEnum } from './type'; import { MemoryType, ReviewEnum, StatusEnum } from './type';
import { getMemeoryList, saveMemory } from './service'; import { getMemeoryList, saveMemory } from './service';
import { Popover, Input, Badge } from 'antd'; import { Popover, Input, Badge, Radio } from 'antd';
import styles from './style.less'; import styles from './style.less';
const { TextArea } = Input; const { TextArea } = Input;
const RadioGroup = Radio.Group;
const MemorySection = () => { const MemorySection = () => {
const [editableKeys, setEditableRowKeys] = useState<React.Key[]>([]); const [editableKeys, setEditableRowKeys] = useState<React.Key[]>([]);
@@ -24,12 +25,18 @@ const MemorySection = () => {
dataIndex: 'dbSchema', dataIndex: 'dbSchema',
width: 300, width: 300,
valueType: 'textarea', valueType: 'textarea',
renderFormItem: (_, { record }) => (
<TextArea rows={3} disabled={record?.status === StatusEnum.ENABLED} />
),
}, },
{ {
title: '大模型解析SQL', title: '大模型解析SQL',
dataIndex: 's2sql', dataIndex: 's2sql',
width: 300, width: 300,
valueType: 'textarea', valueType: 'textarea',
renderFormItem: (_, { record }) => (
<TextArea rows={3} disabled={record?.status === StatusEnum.ENABLED} />
),
}, },
{ {
title: '大模型评估意见', title: '大模型评估意见',
@@ -64,7 +71,9 @@ const MemorySection = () => {
title: '管理员评估意见', title: '管理员评估意见',
dataIndex: 'humanReviewCmt', dataIndex: 'humanReviewCmt',
valueType: 'textarea', valueType: 'textarea',
renderFormItem: () => <TextArea rows={12} />, renderFormItem: (_, { record }) => (
<TextArea rows={12} disabled={record?.status === StatusEnum.ENABLED} />
),
render: (value) => { render: (value) => {
return value === '-' ? ( return value === '-' ? (
'-' '-'
@@ -81,6 +90,15 @@ const MemorySection = () => {
dataIndex: 'humanReviewRet', dataIndex: 'humanReviewRet',
width: 150, width: 150,
valueType: 'radio', valueType: 'radio',
renderFormItem: (_, { record }) => (
<RadioGroup
disabled={record?.status === StatusEnum.ENABLED}
options={[
{ label: '正确', value: ReviewEnum.POSITIVE },
{ label: '错误', value: ReviewEnum.NEGATIVE },
]}
/>
),
valueEnum: { valueEnum: {
[ReviewEnum.POSITIVE]: { [ReviewEnum.POSITIVE]: {
text: '正确', text: '正确',
@@ -98,6 +116,8 @@ const MemorySection = () => {
dataIndex: 'status', dataIndex: 'status',
valueType: 'radio', valueType: 'radio',
width: 120, width: 120,
tooltip:
'若启用,将会把这条记录加入到向量库中作为样例召回供大模型参考以及作为相似问题推荐给用户',
valueEnum: { valueEnum: {
[StatusEnum.PENDING]: { text: '待定' }, [StatusEnum.PENDING]: { text: '待定' },
[StatusEnum.ENABLED]: { [StatusEnum.ENABLED]: {

View File

@@ -1,6 +1,6 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { Modal, Select, Form, Input, InputNumber, message, Button, Radio, TreeSelect } from 'antd'; import { Modal, Select, Form, Input, InputNumber, message, Button, Radio, TreeSelect } from 'antd';
import { getDimensionList, getModelList, savePlugin } from './service'; import { getDataSetSchema, getModelList, savePlugin } from './service';
import { import {
DimensionType, DimensionType,
ModelType, ModelType,
@@ -27,13 +27,16 @@ type Props = {
const DetailModal: React.FC<Props> = ({ detail, onSubmit, onCancel }) => { const DetailModal: React.FC<Props> = ({ detail, onSubmit, onCancel }) => {
const [modelList, setModelList] = useState<ModelType[]>([]); const [modelList, setModelList] = useState<ModelType[]>([]);
const [modelDimensionList, setModelDimensionList] = useState<Record<number, DimensionType[]>>({}); const [dataSetDimensionList, setDataSetDimensionList] = useState<Record<number, DimensionType[]>>(
{},
);
const [confirmLoading, setConfirmLoading] = useState(false); const [confirmLoading, setConfirmLoading] = useState(false);
const [pluginType, setPluginType] = useState<PluginTypeEnum>(); const [pluginType, setPluginType] = useState<PluginTypeEnum>();
const [functionName, setFunctionName] = useState<string>(); const [functionName, setFunctionName] = useState<string>();
const [functionParams, setFunctionParams] = useState<FunctionParamFormItemType[]>([]); const [functionParams, setFunctionParams] = useState<FunctionParamFormItemType[]>([]);
const [examples, setExamples] = useState<{ id: string; question?: string }[]>([]); const [examples, setExamples] = useState<{ id: string; question?: string }[]>([]);
const [filters, setFilters] = useState<any[]>([]); const [filters, setFilters] = useState<any[]>([]);
const [dataSetList, setDataSetList] = useState<number[]>([]);
const [form] = Form.useForm(); const [form] = Form.useForm();
const initModelList = async () => { const initModelList = async () => {
@@ -52,15 +55,20 @@ const DetailModal: React.FC<Props> = ({ detail, onSubmit, onCancel }) => {
}, []); }, []);
const initModelDimensions = async (params: any) => { const initModelDimensions = async (params: any) => {
const modelIds = params const dataSetIds = params
.filter((param: any) => !!param.modelId) .filter((param: any) => !!param.dataSetId)
.map((param: any) => param.modelId); .map((param: any) => param.dataSetId);
const res = await Promise.all(modelIds.map((modelId: number) => getDimensionList(modelId))); const res = await Promise.all(
setModelDimensionList( dataSetIds.map((dataSetId: number) => getDataSetSchema(dataSetId)),
modelIds.reduce((result: Record<number, DimensionType[]>, modelId: number, index: number) => { );
result[modelId] = res[index].data.list; setDataSetDimensionList(
return result; dataSetIds.reduce(
}, {}), (result: Record<number, DimensionType[]>, dataSetId: number, index: number) => {
result[dataSetId] = res[index].data.dimensions;
return result;
},
{},
),
); );
}; };
@@ -75,6 +83,7 @@ const DetailModal: React.FC<Props> = ({ detail, onSubmit, onCancel }) => {
url: detail.config?.url, url: detail.config?.url,
height, height,
}); });
setDataSetList(detail.dataSetList || []);
if (paramOptions?.length > 0) { if (paramOptions?.length > 0) {
const params = paramOptions.filter( const params = paramOptions.filter(
(option: any) => option.paramType !== ParamTypeEnum.FORWARD, (option: any) => option.paramType !== ParamTypeEnum.FORWARD,
@@ -170,23 +179,39 @@ const DetailModal: React.FC<Props> = ({ detail, onSubmit, onCancel }) => {
}; };
const updateDimensionList = async (value: number) => { const updateDimensionList = async (value: number) => {
if (modelDimensionList[value]) { if (dataSetDimensionList[value]) {
return; return;
} }
const res = await getDimensionList(value); const res = await getDataSetSchema(value);
setModelDimensionList({ ...modelDimensionList, [value]: res.data.list }); setDataSetDimensionList({ ...dataSetDimensionList, [value]: res.data.dimensions });
};
const getDataSetList = () => {
const list: any[] = [];
traverseTree(modelList, (node: any) => {
if (node.type === 'DATASET' && dataSetList.includes(node.id)) {
list.push(node);
}
});
return list;
};
const onValuesChange = (value: PluginType) => {
if (value.dataSetList) {
setDataSetList(value.dataSetList);
}
}; };
return ( return (
<Modal <Modal
open open
title={detail ? '编辑插件' : '新建插件'} title={detail ? '编辑插件' : '新建插件'}
width={900} width={920}
confirmLoading={confirmLoading} confirmLoading={confirmLoading}
onOk={onOk} onOk={onOk}
onCancel={onCancel} onCancel={onCancel}
> >
<Form {...layout} form={form} style={{ maxWidth: 820 }}> <Form {...layout} form={form} style={{ maxWidth: 820 }} onValuesChange={onValuesChange}>
<FormItem name="dataSetList" label="数据集"> <FormItem name="dataSetList" label="数据集">
<TreeSelect <TreeSelect
treeData={modelList} treeData={modelList}
@@ -322,10 +347,10 @@ const DetailModal: React.FC<Props> = ({ detail, onSubmit, onCancel }) => {
{filter.paramType === ParamTypeEnum.SEMANTIC && ( {filter.paramType === ParamTypeEnum.SEMANTIC && (
<> <>
<Select <Select
placeholder="主题域" placeholder="数据集"
options={modelList.map((model) => ({ options={getDataSetList().map((dataSet) => ({
label: model.name, label: dataSet.name,
value: model.id, value: dataSet.id,
}))} }))}
showSearch showSearch
filterOption={(input, option) => filterOption={(input, option) =>
@@ -335,16 +360,16 @@ const DetailModal: React.FC<Props> = ({ detail, onSubmit, onCancel }) => {
} }
className={styles.filterParamName} className={styles.filterParamName}
allowClear allowClear
value={filter.modelId} value={filter.dataSetId}
onChange={(value) => { onChange={(value) => {
filter.modelId = value; filter.dataSetId = value;
setFilters([...filters]); setFilters([...filters]);
updateDimensionList(value); updateDimensionList(value);
}} }}
/> />
<Select <Select
placeholder="请选择维度,需先选择主题域" placeholder="请选择维度,需先选择数据集"
options={(modelDimensionList[filter.modelId] || []).map( options={(dataSetDimensionList[filter.dataSetId] || []).map(
(dimension) => ({ (dimension) => ({
label: dimension.name, label: dimension.name,
value: `${dimension.id}`, value: `${dimension.id}`,

View File

@@ -27,13 +27,11 @@ export function getModelList() {
}); });
} }
export function getDimensionList(modelId: number) { export function getDataSetSchema(dataSetId: number) {
return request<Result<{ list: DimensionType[] }>>('/api/semantic/dimension/queryDimension', { return request<Result<{ list: DimensionType[] }>>(
method: 'POST', `/api/chat/conf/getDataSetSchema/${dataSetId}`,
data: { {
modelIds: [modelId], method: 'GET',
current: 1,
pageSize: 2000,
}, },
}); );
} }

View File

@@ -26,6 +26,7 @@ export enum ParamTypeEnum {
export type PluginType = { export type PluginType = {
id: number; id: number;
type: PluginTypeEnum; type: PluginTypeEnum;
dataSetList: number[];
modelList: number[]; modelList: number[];
pattern: string; pattern: string;
parseMode: ParseModeEnum; parseMode: ParseModeEnum;