feat: remove KnowledgeSearching and add knowledge configuration page and add a run button to the document (#64)

* feat: add a run button to the document

* feat: add knowledge configuration page

* feat: remove KnowledgeSearching
This commit is contained in:
balibabu
2024-02-18 18:18:20 +08:00
committed by GitHub
parent 53be70c7a9
commit f3d0ebd293
22 changed files with 495 additions and 687 deletions

View File

@@ -0,0 +1,217 @@
import {
useFetchKnowledgeBaseConfiguration,
useFetchParserList,
useKnowledgeBaseId,
useSelectParserList,
} from '@/hooks/knowledgeHook';
import {
Button,
Divider,
Form,
Input,
Radio,
Select,
Space,
Typography,
Upload,
UploadFile,
} from 'antd';
import pick from 'lodash/pick';
import { useCallback, useEffect, useMemo } from 'react';
import { useDispatch, useSelector } from 'umi';
import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks';
import { IKnowledge } from '@/interfaces/database/knowledge';
import { IThirdOAIModelCollection } from '@/interfaces/database/llm';
import { PlusOutlined } from '@ant-design/icons';
import styles from './index.less';
const { Title } = Typography;
const { Option } = Select;
const Configuration = () => {
const [form] = Form.useForm();
const dispatch = useDispatch();
const knowledgeBaseId = useKnowledgeBaseId();
const loading = useOneNamespaceEffectsLoading('kSModel', ['updateKb']);
const llmInfo: IThirdOAIModelCollection = useSelector(
(state: any) => state.settingModel.llmInfo,
);
const knowledgeDetails: IKnowledge = useSelector(
(state: any) => state.kSModel.knowledgeDetails,
);
const normFile = (e: any) => {
if (Array.isArray(e)) {
return e;
}
return e?.fileList;
};
const parserList = useSelectParserList();
const embeddingModelOptions = useMemo(() => {
return Object.entries(llmInfo).map(([key, value]) => {
return {
label: key,
options: value.map((x) => ({
label: x.llm_name,
value: x.llm_name,
})),
};
});
}, [llmInfo]);
const onFinish = async (values: any) => {
console.info(values);
const fileList = values.avatar;
let avatar;
if (Array.isArray(fileList)) {
avatar = fileList[0].thumbUrl;
}
dispatch({
type: 'kSModel/updateKb',
payload: {
...values,
avatar,
kb_id: knowledgeBaseId,
},
});
};
const onFinishFailed = (errorInfo: any) => {
console.log('Failed:', errorInfo);
};
const fetchLlmList = useCallback(() => {
dispatch({
type: 'settingModel/llm_list',
payload: { model_type: 'embedding' },
});
}, [dispatch]);
useEffect(() => {
const avatar = knowledgeDetails.avatar;
let fileList: UploadFile[] = [];
if (avatar) {
fileList = [{ uid: '1', name: 'file', thumbUrl: avatar, status: 'done' }];
}
form.setFieldsValue({
...pick(knowledgeDetails, [
'description',
'name',
'permission',
'embd_id',
'parser_id',
]),
avatar: fileList,
});
}, [form, knowledgeDetails]);
useFetchParserList();
useFetchKnowledgeBaseConfiguration();
useEffect(() => {
fetchLlmList();
}, [fetchLlmList]);
return (
<div className={styles.configurationWrapper}>
<Title level={5}>Configuration</Title>
<p>Update your knowledge base details especially parsing method here.</p>
<Divider></Divider>
<Form
form={form}
name="validateOnly"
layout="vertical"
autoComplete="off"
onFinish={onFinish}
onFinishFailed={onFinishFailed}
>
<Form.Item
name="name"
label="Knowledge base name"
rules={[{ required: true }]}
>
<Input />
</Form.Item>
<Form.Item
name="avatar"
label="Knowledge base photo"
valuePropName="fileList"
getValueFromEvent={normFile}
>
<Upload
listType="picture-card"
maxCount={1}
showUploadList={{ showPreviewIcon: false, showRemoveIcon: false }}
>
<button style={{ border: 0, background: 'none' }} type="button">
<PlusOutlined />
<div style={{ marginTop: 8 }}>Upload</div>
</button>
</Upload>
</Form.Item>
<Form.Item name="description" label="Knowledge base bio">
<Input />
</Form.Item>
<Form.Item
name="permission"
label="Permissions"
rules={[{ required: true }]}
>
<Radio.Group>
<Radio value="me">Only me</Radio>
<Radio value="team">Team</Radio>
</Radio.Group>
</Form.Item>
<Form.Item
name="embd_id"
label="Embedding Model"
rules={[{ required: true }]}
>
<Select
placeholder="Please select a country"
options={embeddingModelOptions}
></Select>
</Form.Item>
<Form.Item
name="parser_id"
label="Knowledge base category"
rules={[{ required: true }]}
>
<Select placeholder="Please select a country">
{parserList.map((x) => (
<Option value={x.value} key={x.value}>
{x.label}
</Option>
))}
</Select>
</Form.Item>
<Form.Item>
<div className={styles.buttonWrapper}>
<Space>
<Button htmlType="reset" size={'middle'}>
Cancel
</Button>
<Button
htmlType="submit"
type="primary"
size={'middle'}
loading={loading}
>
Save
</Button>
</Space>
</div>
</Form.Item>
</Form>
</div>
);
};
export default Configuration;

View File

@@ -1,24 +1,30 @@
.tags {
margin-bottom: 24px;
margin-bottom: 24px;
}
.preset {
display: flex;
height: 80px;
background-color: rgba(0, 0, 0, 0.1);
border-radius: 5px;
display: flex;
height: 80px;
background-color: rgba(0, 0, 0, 0.1);
border-radius: 5px;
padding: 5px;
margin-bottom: 24px;
.left {
flex: 1;
}
.right {
width: 100px;
border-left: 1px solid rgba(0, 0, 0, 0.4);
margin: 10px 0px;
padding: 5px;
margin-bottom: 24px;
}
}
.left {
flex: 1;
}
.right {
width: 100px;
border-left: 1px solid rgba(0, 0, 0, 0.4);
margin: 10px 0px;
padding: 5px;
}
}
.configurationWrapper {
padding: 0 52px;
.buttonWrapper {
text-align: right;
}
}

View File

@@ -3,6 +3,8 @@ import { useKnowledgeBaseId } from '@/hooks/knowledgeHook';
import { Button, Form, Input, Radio, Select, Space, Tag } from 'antd';
import { useCallback, useEffect, useState } from 'react';
import { useDispatch, useNavigate, useSelector } from 'umi';
import Configuration from './configuration';
import styles from './index.less';
const { CheckableTag } = Tag;
@@ -12,7 +14,6 @@ const layout = {
labelAlign: 'left' as const,
};
const { Option } = Select;
/* eslint-disable no-template-curly-in-string */
const KnowledgeSetting = () => {
const dispatch = useDispatch();
@@ -44,7 +45,7 @@ const KnowledgeSetting = () => {
setSelectedTag(data.data.parser_id);
}
}
}, [knowledgeBaseId]);
}, [knowledgeBaseId, dispatch, form]);
const onFinish = async () => {
try {
@@ -68,10 +69,11 @@ const KnowledgeSetting = () => {
parser_id: selectedTag,
},
});
retcode === 0 &&
if (retcode === 0) {
navigate(
`/knowledge/${KnowledgeRouteKey.Dataset}?id=${knowledgeBaseId}`,
);
}
}
} catch (error) {
console.warn(error);
@@ -158,4 +160,6 @@ const KnowledgeSetting = () => {
);
};
export default KnowledgeSetting;
// export default KnowledgeSetting;
export default Configuration;

View File

@@ -1,3 +1,4 @@
import { IKnowledge } from '@/interfaces/database/knowledge';
import kbService from '@/services/kbService';
import { message } from 'antd';
import { DvaModel } from 'umi';
@@ -6,6 +7,7 @@ export interface KSModelState {
isShowPSwModal: boolean;
isShowTntModal: boolean;
tenantIfo: any;
knowledgeDetails: IKnowledge;
}
const model: DvaModel<KSModelState> = {
@@ -14,6 +16,7 @@ const model: DvaModel<KSModelState> = {
isShowPSwModal: false,
isShowTntModal: false,
tenantIfo: {},
knowledgeDetails: {} as any,
},
reducers: {
updateState(state, { payload }) {
@@ -22,31 +25,32 @@ const model: DvaModel<KSModelState> = {
...payload,
};
},
},
subscriptions: {
setup({ dispatch, history }) {
history.listen((location) => {});
setKnowledgeDetails(state, { payload }) {
return { ...state, knowledgeDetails: payload };
},
},
effects: {
*createKb({ payload = {} }, { call, put }) {
*createKb({ payload = {} }, { call }) {
const { data } = yield call(kbService.createKb, payload);
const { retcode } = data;
if (retcode === 0) {
message.success('创建知识库成功!');
message.success('Created successfully!');
}
return data;
},
*updateKb({ payload = {} }, { call, put }) {
const { data } = yield call(kbService.updateKb, payload);
const { retcode, data: res, retmsg } = data;
const { retcode } = data;
if (retcode === 0) {
message.success('更新知识库成功!');
yield put({ type: 'getKbDetail', payload: { kb_id: payload.kb_id } });
message.success('Updated successfully!');
}
},
*getKbDetail({ payload = {} }, { call, put }) {
const { data } = yield call(kbService.get_kb_detail, payload);
if (data.retcode === 0) {
yield put({ type: 'setKnowledgeDetails', payload: data.data });
}
return data;
},
},