mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-14 05:43:51 +00:00
(feature)(supersonic-fe) add memory manage to agent (#1284)
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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]: {
|
||||||
|
|||||||
@@ -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}`,
|
||||||
|
|||||||
@@ -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,
|
|
||||||
},
|
},
|
||||||
});
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user