feat: add DynamicCategorize #918 (#1273)

### What problem does this PR solve?

feat: add DynamicCategorize #918

### Type of change

- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu 2024-06-25 16:17:12 +08:00 committed by GitHub
parent f6ae8fcb71
commit 83b91d90fe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 114 additions and 13 deletions

View File

@ -10,12 +10,7 @@ const LLMSelect = () => {
return (
<Popover content={content} trigger="click" placement="left" arrow={false}>
{/* <Button>Click me</Button> */}
<Select
defaultValue="lucy"
style={{ width: '100%' }}
dropdownStyle={{ display: 'none' }}
/>
<Select style={{ width: '100%' }} dropdownStyle={{ display: 'none' }} />
</Popover>
);
};

View File

@ -25,7 +25,9 @@ const handleGithubCLick = () => {
const RightToolBar = () => {
const { t } = useTranslate('common');
const changeLanguage = useChangeLanguage();
const { language = '' } = useSelector((state) => state.settingModel.userInfo);
const { language = 'en' } = useSelector(
(state) => state.settingModel.userInfo,
);
const handleItemClick: MenuProps['onClick'] = ({ key }) => {
changeLanguage(key);

View File

@ -505,6 +505,7 @@ export default {
preview: '預覽',
fileError: '文件錯誤',
},
flow: { cite: '引用', citeTip: 'citeTip' },
footer: {
profile: '“保留所有權利 @ react”',
},

View File

@ -523,6 +523,7 @@ export default {
preview: '预览',
fileError: '文件错误',
},
flow: { cite: '引用', citeTip: 'citeTip' },
footer: {
profile: 'All rights reserved @ React',
},

View File

@ -7,6 +7,7 @@ import { Flex, MenuProps, Space, Typography } from 'antd';
import { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { Operator, operatorMap } from '../../constant';
import { NodeData } from '../../interface';
import OperatorIcon from '../../operator-icon';
import useGraphStore from '../../store';
import styles from './index.less';
@ -18,7 +19,7 @@ export function RagNode({
data,
isConnectable = true,
selected,
}: NodeProps<{ label: string }>) {
}: NodeProps<NodeData>) {
const { t } = useTranslation();
const deleteNodeById = useGraphStore((store) => store.deleteNodeById);
const duplicateNodeById = useGraphStore((store) => store.duplicateNode);
@ -78,7 +79,7 @@ export function RagNode({
name={data.label as Operator}
fontSize={12}
></OperatorIcon>
<span>{data.label}</span>
<span>{id}</span>
</Space>
<OperateDropdown
iconFontSize={14}

View File

@ -0,0 +1,69 @@
import { CloseOutlined } from '@ant-design/icons';
import { Button, Card, Form, Input, Select, Typography } from 'antd';
import { useBuildCategorizeToOptions } from './hooks';
const DynamicCategorize = () => {
const form = Form.useFormInstance();
const options = useBuildCategorizeToOptions();
return (
<>
<Form.List name="items">
{(fields, { add, remove }) => (
<div style={{ display: 'flex', rowGap: 16, flexDirection: 'column' }}>
{fields.map((field) => (
<Card
size="small"
key={field.key}
extra={
<CloseOutlined
onClick={() => {
remove(field.name);
}}
/>
}
>
<Form.Item
label="name"
name={[field.name, 'name']}
initialValue={`Categorize ${field.name + 1}`}
rules={[
{ required: true, message: 'Please input your name!' },
]}
>
<Input />
</Form.Item>
<Form.Item
label="description"
name={[field.name, 'description']}
>
<Input.TextArea rows={3} />
</Form.Item>
<Form.Item label="examples" name={[field.name, 'examples']}>
<Input.TextArea rows={3} />
</Form.Item>
<Form.Item label="to" name={[field.name, 'to']}>
<Select options={options} />
</Form.Item>
</Card>
))}
<Button type="dashed" onClick={() => add()} block>
+ Add Item
</Button>
</div>
)}
</Form.List>
<Form.Item noStyle shouldUpdate>
{() => (
<Typography>
<pre>{JSON.stringify(form.getFieldsValue(), null, 2)}</pre>
</Typography>
)}
</Form.Item>
</>
);
};
export default DynamicCategorize;

View File

@ -0,0 +1,13 @@
import { Operator } from '../constant';
import useGraphStore from '../store';
// exclude some nodes downstream of the classification node
const excludedNodes = [Operator.Categorize, Operator.Answer, Operator.Begin];
export const useBuildCategorizeToOptions = () => {
const nodes = useGraphStore((state) => state.nodes);
return nodes
.filter((x) => excludedNodes.every((y) => y !== x.data.label))
.map((x) => ({ label: x.id, value: x.id }));
};

View File

@ -1,10 +1,28 @@
import LLMSelect from '@/components/llm-select';
import { useTranslate } from '@/hooks/commonHooks';
import { Form } from 'antd';
import { IOperatorForm } from '../interface';
import DynamicCategorize from './dynamic-categorize';
const CategorizeForm = ({ form, onValuesChange }: IOperatorForm) => {
const { t } = useTranslate('flow');
const CategorizeForm = () => {
return (
<section>
<LLMSelect></LLMSelect>
</section>
<Form
name="basic"
labelCol={{ span: 9 }}
wrapperCol={{ span: 15 }}
autoComplete="off"
form={form}
onValuesChange={onValuesChange}
initialValues={{ items: [{}] }}
// layout={'vertical'}
>
<Form.Item name={['cite']} label={t('cite')} tooltip={t('citeTip')}>
<LLMSelect></LLMSelect>
</Form.Item>
<DynamicCategorize></DynamicCategorize>
</Form>
);
};

View File

@ -80,4 +80,5 @@ export const initialFormValuesMap = {
[Operator.Retrieval]: initialRetrievalValues,
[Operator.Generate]: initialGenerateValues,
[Operator.Answer]: {},
[Operator.Categorize]: {},
};