balibabu commited on
Commit
04225e2
·
1 Parent(s): de7c780

feat: add DynamicCategorize #918 (#1273)

Browse files

### What problem does this PR solve?

feat: add DynamicCategorize #918

### Type of change

- [x] New Feature (non-breaking change which adds functionality)

web/src/components/llm-select/index.tsx CHANGED
@@ -10,12 +10,7 @@ const LLMSelect = () => {
10
 
11
  return (
12
  <Popover content={content} trigger="click" placement="left" arrow={false}>
13
- {/* <Button>Click me</Button> */}
14
- <Select
15
- defaultValue="lucy"
16
- style={{ width: '100%' }}
17
- dropdownStyle={{ display: 'none' }}
18
- />
19
  </Popover>
20
  );
21
  };
 
10
 
11
  return (
12
  <Popover content={content} trigger="click" placement="left" arrow={false}>
13
+ <Select style={{ width: '100%' }} dropdownStyle={{ display: 'none' }} />
 
 
 
 
 
14
  </Popover>
15
  );
16
  };
web/src/layouts/components/right-toolbar/index.tsx CHANGED
@@ -25,7 +25,9 @@ const handleGithubCLick = () => {
25
  const RightToolBar = () => {
26
  const { t } = useTranslate('common');
27
  const changeLanguage = useChangeLanguage();
28
- const { language = '' } = useSelector((state) => state.settingModel.userInfo);
 
 
29
 
30
  const handleItemClick: MenuProps['onClick'] = ({ key }) => {
31
  changeLanguage(key);
 
25
  const RightToolBar = () => {
26
  const { t } = useTranslate('common');
27
  const changeLanguage = useChangeLanguage();
28
+ const { language = 'en' } = useSelector(
29
+ (state) => state.settingModel.userInfo,
30
+ );
31
 
32
  const handleItemClick: MenuProps['onClick'] = ({ key }) => {
33
  changeLanguage(key);
web/src/locales/zh-traditional.ts CHANGED
@@ -505,6 +505,7 @@ export default {
505
  preview: '預覽',
506
  fileError: '文件錯誤',
507
  },
 
508
  footer: {
509
  profile: '“保留所有權利 @ react”',
510
  },
 
505
  preview: '預覽',
506
  fileError: '文件錯誤',
507
  },
508
+ flow: { cite: '引用', citeTip: 'citeTip' },
509
  footer: {
510
  profile: '“保留所有權利 @ react”',
511
  },
web/src/locales/zh.ts CHANGED
@@ -523,6 +523,7 @@ export default {
523
  preview: '预览',
524
  fileError: '文件错误',
525
  },
 
526
  footer: {
527
  profile: 'All rights reserved @ React',
528
  },
 
523
  preview: '预览',
524
  fileError: '文件错误',
525
  },
526
+ flow: { cite: '引用', citeTip: 'citeTip' },
527
  footer: {
528
  profile: 'All rights reserved @ React',
529
  },
web/src/pages/flow/canvas/node/index.tsx CHANGED
@@ -7,6 +7,7 @@ import { Flex, MenuProps, Space, Typography } from 'antd';
7
  import { useCallback } from 'react';
8
  import { useTranslation } from 'react-i18next';
9
  import { Operator, operatorMap } from '../../constant';
 
10
  import OperatorIcon from '../../operator-icon';
11
  import useGraphStore from '../../store';
12
  import styles from './index.less';
@@ -18,7 +19,7 @@ export function RagNode({
18
  data,
19
  isConnectable = true,
20
  selected,
21
- }: NodeProps<{ label: string }>) {
22
  const { t } = useTranslation();
23
  const deleteNodeById = useGraphStore((store) => store.deleteNodeById);
24
  const duplicateNodeById = useGraphStore((store) => store.duplicateNode);
@@ -78,7 +79,7 @@ export function RagNode({
78
  name={data.label as Operator}
79
  fontSize={12}
80
  ></OperatorIcon>
81
- <span>{data.label}</span>
82
  </Space>
83
  <OperateDropdown
84
  iconFontSize={14}
 
7
  import { useCallback } from 'react';
8
  import { useTranslation } from 'react-i18next';
9
  import { Operator, operatorMap } from '../../constant';
10
+ import { NodeData } from '../../interface';
11
  import OperatorIcon from '../../operator-icon';
12
  import useGraphStore from '../../store';
13
  import styles from './index.less';
 
19
  data,
20
  isConnectable = true,
21
  selected,
22
+ }: NodeProps<NodeData>) {
23
  const { t } = useTranslation();
24
  const deleteNodeById = useGraphStore((store) => store.deleteNodeById);
25
  const duplicateNodeById = useGraphStore((store) => store.duplicateNode);
 
79
  name={data.label as Operator}
80
  fontSize={12}
81
  ></OperatorIcon>
82
+ <span>{id}</span>
83
  </Space>
84
  <OperateDropdown
85
  iconFontSize={14}
web/src/pages/flow/categorize-form/dynamic-categorize.tsx ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { CloseOutlined } from '@ant-design/icons';
2
+ import { Button, Card, Form, Input, Select, Typography } from 'antd';
3
+ import { useBuildCategorizeToOptions } from './hooks';
4
+
5
+ const DynamicCategorize = () => {
6
+ const form = Form.useFormInstance();
7
+ const options = useBuildCategorizeToOptions();
8
+
9
+ return (
10
+ <>
11
+ <Form.List name="items">
12
+ {(fields, { add, remove }) => (
13
+ <div style={{ display: 'flex', rowGap: 16, flexDirection: 'column' }}>
14
+ {fields.map((field) => (
15
+ <Card
16
+ size="small"
17
+ key={field.key}
18
+ extra={
19
+ <CloseOutlined
20
+ onClick={() => {
21
+ remove(field.name);
22
+ }}
23
+ />
24
+ }
25
+ >
26
+ <Form.Item
27
+ label="name"
28
+ name={[field.name, 'name']}
29
+ initialValue={`Categorize ${field.name + 1}`}
30
+ rules={[
31
+ { required: true, message: 'Please input your name!' },
32
+ ]}
33
+ >
34
+ <Input />
35
+ </Form.Item>
36
+ <Form.Item
37
+ label="description"
38
+ name={[field.name, 'description']}
39
+ >
40
+ <Input.TextArea rows={3} />
41
+ </Form.Item>
42
+ <Form.Item label="examples" name={[field.name, 'examples']}>
43
+ <Input.TextArea rows={3} />
44
+ </Form.Item>
45
+ <Form.Item label="to" name={[field.name, 'to']}>
46
+ <Select options={options} />
47
+ </Form.Item>
48
+ </Card>
49
+ ))}
50
+
51
+ <Button type="dashed" onClick={() => add()} block>
52
+ + Add Item
53
+ </Button>
54
+ </div>
55
+ )}
56
+ </Form.List>
57
+
58
+ <Form.Item noStyle shouldUpdate>
59
+ {() => (
60
+ <Typography>
61
+ <pre>{JSON.stringify(form.getFieldsValue(), null, 2)}</pre>
62
+ </Typography>
63
+ )}
64
+ </Form.Item>
65
+ </>
66
+ );
67
+ };
68
+
69
+ export default DynamicCategorize;
web/src/pages/flow/categorize-form/hooks.ts ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Operator } from '../constant';
2
+ import useGraphStore from '../store';
3
+
4
+ // exclude some nodes downstream of the classification node
5
+ const excludedNodes = [Operator.Categorize, Operator.Answer, Operator.Begin];
6
+
7
+ export const useBuildCategorizeToOptions = () => {
8
+ const nodes = useGraphStore((state) => state.nodes);
9
+
10
+ return nodes
11
+ .filter((x) => excludedNodes.every((y) => y !== x.data.label))
12
+ .map((x) => ({ label: x.id, value: x.id }));
13
+ };
web/src/pages/flow/categorize-form/index.tsx CHANGED
@@ -1,10 +1,28 @@
1
  import LLMSelect from '@/components/llm-select';
 
 
 
 
 
 
 
2
 
3
- const CategorizeForm = () => {
4
  return (
5
- <section>
6
- <LLMSelect></LLMSelect>
7
- </section>
 
 
 
 
 
 
 
 
 
 
 
 
8
  );
9
  };
10
 
 
1
  import LLMSelect from '@/components/llm-select';
2
+ import { useTranslate } from '@/hooks/commonHooks';
3
+ import { Form } from 'antd';
4
+ import { IOperatorForm } from '../interface';
5
+ import DynamicCategorize from './dynamic-categorize';
6
+
7
+ const CategorizeForm = ({ form, onValuesChange }: IOperatorForm) => {
8
+ const { t } = useTranslate('flow');
9
 
 
10
  return (
11
+ <Form
12
+ name="basic"
13
+ labelCol={{ span: 9 }}
14
+ wrapperCol={{ span: 15 }}
15
+ autoComplete="off"
16
+ form={form}
17
+ onValuesChange={onValuesChange}
18
+ initialValues={{ items: [{}] }}
19
+ // layout={'vertical'}
20
+ >
21
+ <Form.Item name={['cite']} label={t('cite')} tooltip={t('citeTip')}>
22
+ <LLMSelect></LLMSelect>
23
+ </Form.Item>
24
+ <DynamicCategorize></DynamicCategorize>
25
+ </Form>
26
  );
27
  };
28
 
web/src/pages/flow/constant.tsx CHANGED
@@ -80,4 +80,5 @@ export const initialFormValuesMap = {
80
  [Operator.Retrieval]: initialRetrievalValues,
81
  [Operator.Generate]: initialGenerateValues,
82
  [Operator.Answer]: {},
 
83
  };
 
80
  [Operator.Retrieval]: initialRetrievalValues,
81
  [Operator.Generate]: initialGenerateValues,
82
  [Operator.Answer]: {},
83
+ [Operator.Categorize]: {},
84
  };