Feat: Add the iteration Node #4242 (#4247)

### What problem does this PR solve?

Feat: Add the iteration Node #4242

### Type of change


- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu
2024-12-27 11:24:17 +08:00
committed by GitHub
parent a6f4153775
commit a1a825c830
72 changed files with 1330 additions and 560 deletions

View File

@ -12,7 +12,7 @@ const AkShareForm = ({ onValuesChange, form, node }: IOperatorForm) => {
onValuesChange={onValuesChange}
layout={'vertical'}
>
<DynamicInputVariable nodeId={node?.id}></DynamicInputVariable>
<DynamicInputVariable node={node}></DynamicInputVariable>
<TopNItem initialValue={10} max={99}></TopNItem>
</Form>
);

View File

@ -23,7 +23,7 @@ const ArXivForm = ({ onValuesChange, form, node }: IOperatorForm) => {
onValuesChange={onValuesChange}
layout={'vertical'}
>
<DynamicInputVariable nodeId={node?.id}></DynamicInputVariable>
<DynamicInputVariable node={node}></DynamicInputVariable>
<TopNItem initialValue={10}></TopNItem>
<Form.Item label={t('sortBy')} name={'sort_by'}>

View File

@ -39,7 +39,7 @@ const BaiduFanyiForm = ({ onValuesChange, form, node }: IOperatorForm) => {
onValuesChange={onValuesChange}
layout={'vertical'}
>
<DynamicInputVariable nodeId={node?.id}></DynamicInputVariable>
<DynamicInputVariable node={node}></DynamicInputVariable>
<Form.Item label={t('appid')} name={'appid'}>
<Input></Input>
</Form.Item>

View File

@ -12,7 +12,7 @@ const BaiduForm = ({ onValuesChange, form, node }: IOperatorForm) => {
onValuesChange={onValuesChange}
layout={'vertical'}
>
<DynamicInputVariable nodeId={node?.id}></DynamicInputVariable>
<DynamicInputVariable node={node}></DynamicInputVariable>
<TopNItem initialValue={10}></TopNItem>
</Form>
);

View File

@ -21,7 +21,7 @@ const BingForm = ({ onValuesChange, form, node }: IOperatorForm) => {
onValuesChange={onValuesChange}
layout={'vertical'}
>
<DynamicInputVariable nodeId={node?.id}></DynamicInputVariable>
<DynamicInputVariable node={node}></DynamicInputVariable>
<TopNItem initialValue={10}></TopNItem>
<Form.Item label={t('channel')} name={'channel'}>
<Select options={options}></Select>

View File

@ -24,7 +24,7 @@ const CategorizeForm = ({ form, onValuesChange, node }: IOperatorForm) => {
initialValues={{ items: [{}] }}
layout={'vertical'}
>
<DynamicInputVariable nodeId={node?.id}></DynamicInputVariable>
<DynamicInputVariable node={node}></DynamicInputVariable>
<Form.Item
name={'llm_id'}
label={t('model', { keyPrefix: 'chat' })}

View File

@ -1,13 +1,15 @@
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
import { Button, Collapse, Flex, Form, Input, Select } from 'antd';
import { PropsWithChildren, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { useBuildComponentIdSelectOptions } from '../../hooks';
import { Node } from 'reactflow';
import { useBuildComponentIdSelectOptions } from '../../hooks/use-get-begin-query';
import { NodeData } from '../../interface';
import styles from './index.less';
interface IProps {
nodeId?: string;
node?: Node<NodeData>;
}
enum VariableType {
@ -18,9 +20,12 @@ enum VariableType {
const getVariableName = (type: string) =>
type === VariableType.Reference ? 'component_id' : 'value';
const DynamicVariableForm = ({ nodeId }: IProps) => {
const DynamicVariableForm = ({ node }: IProps) => {
const { t } = useTranslation();
const valueOptions = useBuildComponentIdSelectOptions(nodeId);
const valueOptions = useBuildComponentIdSelectOptions(
node?.id,
node?.parentId,
);
const form = Form.useFormInstance();
const options = [
@ -114,11 +119,11 @@ export function FormCollapse({
);
}
const DynamicInputVariable = ({ nodeId }: IProps) => {
const DynamicInputVariable = ({ node }: IProps) => {
const { t } = useTranslation();
return (
<FormCollapse title={t('flow.input')}>
<DynamicVariableForm nodeId={nodeId}></DynamicVariableForm>
<DynamicVariableForm node={node}></DynamicVariableForm>
</FormCollapse>
);
};

View File

@ -20,7 +20,7 @@ const CrawlerForm = ({ onValuesChange, form, node }: IOperatorForm) => {
onValuesChange={onValuesChange}
layout={'vertical'}
>
<DynamicInputVariable nodeId={node?.id}></DynamicInputVariable>
<DynamicInputVariable node={node}></DynamicInputVariable>
<Form.Item label={t('proxy')} name={'proxy'}>
<Input placeholder="like: http://127.0.0.1:8888"></Input>
</Form.Item>

View File

@ -18,7 +18,7 @@ const DeepLForm = ({ onValuesChange, form, node }: IOperatorForm) => {
onValuesChange={onValuesChange}
layout={'vertical'}
>
<DynamicInputVariable nodeId={node?.id}></DynamicInputVariable>
<DynamicInputVariable node={node}></DynamicInputVariable>
<TopNItem initialValue={5}></TopNItem>
<Form.Item label={t('authKey')} name={'auth_key'}>
<Select options={options}></Select>

View File

@ -21,7 +21,7 @@ const DuckDuckGoForm = ({ onValuesChange, form, node }: IOperatorForm) => {
onValuesChange={onValuesChange}
layout={'vertical'}
>
<DynamicInputVariable nodeId={node?.id}></DynamicInputVariable>
<DynamicInputVariable node={node}></DynamicInputVariable>
<TopNItem initialValue={10}></TopNItem>
<Form.Item
label={t('channel')}

View File

@ -14,7 +14,7 @@ const EmailForm = ({ onValuesChange, form, node }: IOperatorForm) => {
onValuesChange={onValuesChange}
layout={'vertical'}
>
<DynamicInputVariable nodeId={node?.id}></DynamicInputVariable>
<DynamicInputVariable node={node}></DynamicInputVariable>
{/* SMTP服务器配置 */}
<Form.Item label={t('smtpServer')} name={'smtp_server'}>

View File

@ -24,7 +24,7 @@ const ExeSQLForm = ({ onValuesChange, form, node }: IOperatorForm) => {
onValuesChange={onValuesChange}
layout={'vertical'}
>
<DynamicInputVariable nodeId={node?.id}></DynamicInputVariable>
<DynamicInputVariable node={node}></DynamicInputVariable>
<Form.Item
label={t('dbType')}
name={'db_type'}

View File

@ -2,14 +2,14 @@ import { EditableCell, EditableRow } from '@/components/editable-cell';
import { useTranslate } from '@/hooks/common-hooks';
import { DeleteOutlined } from '@ant-design/icons';
import { Button, Flex, Select, Table, TableProps } from 'antd';
import { IGenerateParameter } from '../../interface';
import { useBuildComponentIdSelectOptions } from '../../hooks';
import { Node } from 'reactflow';
import { useBuildComponentIdSelectOptions } from '../../hooks/use-get-begin-query';
import { IGenerateParameter, NodeData } from '../../interface';
import { useHandleOperateParameters } from './hooks';
import styles from './index.less';
import styles from './index.less';
interface IProps {
nodeId?: string;
node?: Node<NodeData>;
}
const components = {
@ -19,10 +19,11 @@ const components = {
},
};
const DynamicParameters = ({ nodeId }: IProps) => {
const DynamicParameters = ({ node }: IProps) => {
const nodeId = node?.id;
const { t } = useTranslate('flow');
const options = useBuildComponentIdSelectOptions(nodeId);
const options = useBuildComponentIdSelectOptions(nodeId, node?.parentId);
const {
dataSource,
handleAdd,

View File

@ -49,7 +49,7 @@ const GenerateForm = ({ onValuesChange, form, node }: IOperatorForm) => {
<MessageHistoryWindowSizeItem
initialValue={12}
></MessageHistoryWindowSizeItem>
<DynamicParameters nodeId={node?.id}></DynamicParameters>
<DynamicParameters node={node}></DynamicParameters>
</Form>
);
};

View File

@ -12,7 +12,7 @@ const GithubForm = ({ onValuesChange, form, node }: IOperatorForm) => {
onValuesChange={onValuesChange}
layout={'vertical'}
>
<DynamicInputVariable nodeId={node?.id}></DynamicInputVariable>
<DynamicInputVariable node={node}></DynamicInputVariable>
<TopNItem initialValue={5}></TopNItem>
</Form>
);

View File

@ -16,7 +16,7 @@ const GoogleForm = ({ onValuesChange, form, node }: IOperatorForm) => {
onValuesChange={onValuesChange}
layout={'vertical'}
>
<DynamicInputVariable nodeId={node?.id}></DynamicInputVariable>
<DynamicInputVariable node={node}></DynamicInputVariable>
<TopNItem initialValue={10}></TopNItem>
<Form.Item label={t('apiKey')} name={'api_key'}>
<Input></Input>

View File

@ -45,7 +45,7 @@ const GoogleScholarForm = ({ onValuesChange, form, node }: IOperatorForm) => {
onValuesChange={onValuesChange}
layout={'vertical'}
>
<DynamicInputVariable nodeId={node?.id}></DynamicInputVariable>
<DynamicInputVariable node={node}></DynamicInputVariable>
<TopNItem initialValue={5}></TopNItem>
<Form.Item
label={t('sortBy')}

View File

@ -2,15 +2,16 @@ import { EditableCell, EditableRow } from '@/components/editable-cell';
import { useTranslate } from '@/hooks/common-hooks';
import { DeleteOutlined } from '@ant-design/icons';
import { Button, Collapse, Flex, Input, Select, Table, TableProps } from 'antd';
import { useBuildComponentIdSelectOptions } from '../../hooks';
import { IInvokeVariable } from '../../interface';
import { trim } from 'lodash';
import { useBuildComponentIdSelectOptions } from '../../hooks/use-get-begin-query';
import { IInvokeVariable, NodeData } from '../../interface';
import { useHandleOperateParameters } from './hooks';
import { trim } from 'lodash';
import { Node } from 'reactflow';
import styles from './index.less';
interface IProps {
nodeId?: string;
node?: Node<NodeData>;
}
const components = {
@ -20,10 +21,11 @@ const components = {
},
};
const DynamicVariablesForm = ({ nodeId }: IProps) => {
const DynamicVariablesForm = ({ node }: IProps) => {
const nodeId = node?.id;
const { t } = useTranslate('flow');
const options = useBuildComponentIdSelectOptions(nodeId);
const options = useBuildComponentIdSelectOptions(nodeId, node?.parentId);
const {
dataSource,
handleAdd,

View File

@ -69,7 +69,7 @@ const InvokeForm = ({ onValuesChange, form, node }: IOperatorForm) => {
>
<Switch />
</Form.Item>
<DynamicVariablesForm nodeId={node?.id}></DynamicVariablesForm>
<DynamicVariablesForm node={node}></DynamicVariablesForm>
</Form>
</>
);

View File

@ -0,0 +1,94 @@
import { CommaIcon, SemicolonIcon } from '@/assets/icon/Icon';
import { Form, Select } from 'antd';
import {
CornerDownLeft,
IndentIncrease,
Minus,
Slash,
Underline,
} from 'lucide-react';
import { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { IOperatorForm } from '../../interface';
import DynamicInputVariable from '../components/dynamic-input-variable';
const optionList = [
{
value: ',',
icon: CommaIcon,
text: 'comma',
},
{
value: '\n',
icon: CornerDownLeft,
text: 'lineBreak',
},
{
value: 'tab',
icon: IndentIncrease,
text: 'tab',
},
{
value: '_',
icon: Underline,
text: 'underline',
},
{
value: '/',
icon: Slash,
text: 'diagonal',
},
{
value: '-',
icon: Minus,
text: 'minus',
},
{
value: ';',
icon: SemicolonIcon,
text: 'semicolon',
},
];
const IterationForm = ({ onValuesChange, form, node }: IOperatorForm) => {
const { t } = useTranslation();
const options = useMemo(() => {
return optionList.map((x) => {
let Icon = x.icon;
return {
value: x.value,
label: (
<div className="flex items-center gap-2">
<Icon className={'size-4'}></Icon>
{t(`flow.delimiterOptions.${x.text}`)}
</div>
),
};
});
}, [t]);
return (
<Form
name="basic"
autoComplete="off"
form={form}
onValuesChange={onValuesChange}
layout={'vertical'}
>
<DynamicInputVariable node={node}></DynamicInputVariable>
<Form.Item
name={['delimiter']}
label={t('knowledgeDetails.delimiter')}
initialValue={`\\n!?;。;!?`}
rules={[{ required: true }]}
tooltip={t('flow.delimiterTip')}
>
<Select options={options}></Select>
</Form.Item>
</Form>
);
};
export default IterationForm;

View File

@ -65,7 +65,7 @@ const Jin10Form = ({ onValuesChange, form, node }: IOperatorForm) => {
onValuesChange={onValuesChange}
layout={'vertical'}
>
<DynamicInputVariable nodeId={node?.id}></DynamicInputVariable>
<DynamicInputVariable node={node}></DynamicInputVariable>
<Form.Item label={t('type')} name={'type'} initialValue={'flash'}>
<Select options={jin10TypeOptions}></Select>
</Form.Item>

View File

@ -16,7 +16,7 @@ const KeywordExtractForm = ({ onValuesChange, form, node }: IOperatorForm) => {
onValuesChange={onValuesChange}
layout={'vertical'}
>
<DynamicInputVariable nodeId={node?.id}></DynamicInputVariable>
<DynamicInputVariable node={node}></DynamicInputVariable>
<Form.Item
name={'llm_id'}
label={t('model', { keyPrefix: 'chat' })}

View File

@ -15,7 +15,7 @@ const PubMedForm = ({ onValuesChange, form, node }: IOperatorForm) => {
onValuesChange={onValuesChange}
layout={'vertical'}
>
<DynamicInputVariable nodeId={node?.id}></DynamicInputVariable>
<DynamicInputVariable node={node}></DynamicInputVariable>
<TopNItem initialValue={10}></TopNItem>
<Form.Item
label={t('email')}

View File

@ -55,7 +55,7 @@ const QWeatherForm = ({ onValuesChange, form, node }: IOperatorForm) => {
onValuesChange={onValuesChange}
layout={'vertical'}
>
<DynamicInputVariable nodeId={node?.id}></DynamicInputVariable>
<DynamicInputVariable node={node}></DynamicInputVariable>
<Form.Item label={t('webApiKey')} name={'web_apikey'}>
<Input></Input>
</Form.Item>

View File

@ -32,7 +32,7 @@ const RetrievalForm = ({ onValuesChange, form, node }: IOperatorForm) => {
form={form}
layout={'vertical'}
>
<DynamicInputVariable nodeId={node?.id}></DynamicInputVariable>
<DynamicInputVariable node={node}></DynamicInputVariable>
<SimilaritySlider
isTooltipShown
vectorSimilarityWeightName="keywords_similarity_weight"

View File

@ -9,7 +9,7 @@ import {
SwitchOperatorOptions,
} from '../../constant';
import { useBuildFormSelectOptions } from '../../form-hooks';
import { useBuildComponentIdSelectOptions } from '../../hooks';
import { useBuildComponentIdSelectOptions } from '../../hooks/use-get-begin-query';
import { IOperatorForm, ISwitchForm } from '../../interface';
import { getOtherFieldValues } from '../../utils';
@ -43,7 +43,10 @@ const SwitchForm = ({ onValuesChange, node, form }: IOperatorForm) => {
}));
}, [t]);
const componentIdOptions = useBuildComponentIdSelectOptions(node?.id);
const componentIdOptions = useBuildComponentIdSelectOptions(
node?.id,
node?.parentId,
);
return (
<Form

View File

@ -18,7 +18,7 @@ const TemplateForm = ({ onValuesChange, form, node }: IOperatorForm) => {
<Input.TextArea rows={8} placeholder={t('flow.blank')} />
</Form.Item>
<DynamicParameters nodeId={node?.id}></DynamicParameters>
<DynamicParameters node={node}></DynamicParameters>
</Form>
);
};

View File

@ -56,7 +56,7 @@ const TuShareForm = ({ onValuesChange, form, node }: IOperatorForm) => {
onValuesChange={onValuesChange}
layout={'vertical'}
>
<DynamicInputVariable nodeId={node?.id}></DynamicInputVariable>
<DynamicInputVariable node={node}></DynamicInputVariable>
<Form.Item
label={t('token')}
name={'token'}

View File

@ -24,7 +24,7 @@ const WenCaiForm = ({ onValuesChange, form, node }: IOperatorForm) => {
onValuesChange={onValuesChange}
layout={'vertical'}
>
<DynamicInputVariable nodeId={node?.id}></DynamicInputVariable>
<DynamicInputVariable node={node}></DynamicInputVariable>
<TopNItem initialValue={20} max={99}></TopNItem>
<Form.Item label={t('queryType')} name={'query_type'}>
<Select options={wenCaiQueryTypeOptions}></Select>

View File

@ -16,7 +16,7 @@ const WikipediaForm = ({ onValuesChange, form, node }: IOperatorForm) => {
onValuesChange={onValuesChange}
layout={'vertical'}
>
<DynamicInputVariable nodeId={node?.id}></DynamicInputVariable>
<DynamicInputVariable node={node}></DynamicInputVariable>
<TopNItem initialValue={10}></TopNItem>
<Form.Item label={t('language')} name={'language'}>
<Select options={LanguageOptions}></Select>

View File

@ -14,7 +14,7 @@ const YahooFinanceForm = ({ onValuesChange, form, node }: IOperatorForm) => {
onValuesChange={onValuesChange}
layout={'vertical'}
>
<DynamicInputVariable nodeId={node?.id}></DynamicInputVariable>
<DynamicInputVariable node={node}></DynamicInputVariable>
<Form.Item label={t('info')} name={'info'}>
<Switch></Switch>
</Form.Item>