feat: Add InvokeNode #1908 (#3081)

### What problem does this PR solve?

feat: Add InvokeNode #1908

### Type of change

- [ ] Bug Fix (non-breaking change which fixes an issue)
- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu 2024-10-29 16:39:56 +08:00 committed by GitHub
parent 2d1fbefdb5
commit 3ed096fd3f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 72 additions and 8 deletions

View File

@ -78,7 +78,7 @@ export const EditableCell: React.FC<EditableCellProps> = ({
if (editable) {
childNode = editing ? (
<Form.Item
style={{ margin: 0, width: 100 }}
style={{ margin: 0, width: 70 }}
name={dataIndex}
rules={[
{
@ -95,7 +95,7 @@ export const EditableCell: React.FC<EditableCellProps> = ({
// style={{ paddingRight: 24 }}
onClick={toggleEdit}
>
<Text ellipsis={{ tooltip: children }} style={{ width: 100 }}>
<Text ellipsis={{ tooltip: children }} style={{ width: 70 }}>
{children}
</Text>
</div>

View File

@ -1023,6 +1023,7 @@ The above is the content you need to summarize.`,
method: 'Method',
timeout: 'Timeout',
headers: 'Headers',
cleanHtml: 'Clean html',
},
footer: {
profile: 'All rights reserved @ React',

View File

@ -972,6 +972,7 @@ export default {
method: '方法',
timeout: '超時',
headers: '請求頭',
cleanHtml: '清除 html',
},
footer: {
profile: '“保留所有權利 @ react”',

View File

@ -992,6 +992,7 @@ export default {
method: '方法',
timeout: '超时',
headers: '请求头',
cleanHtml: '清除 html',
},
footer: {
profile: 'All rights reserved @ React',

View File

@ -23,6 +23,7 @@ import { RagNode } from './node';
import { BeginNode } from './node/begin-node';
import { CategorizeNode } from './node/categorize-node';
import { GenerateNode } from './node/generate-node';
import { InvokeNode } from './node/invoke-node';
import { KeywordNode } from './node/keyword-node';
import { LogicNode } from './node/logic-node';
import { MessageNode } from './node/message-node';
@ -45,6 +46,7 @@ const nodeTypes = {
messageNode: MessageNode,
rewriteNode: RewriteNode,
keywordNode: KeywordNode,
invokeNode: InvokeNode,
};
const edgeTypes = {

View File

@ -0,0 +1,56 @@
import { Flex } from 'antd';
import classNames from 'classnames';
import { get } from 'lodash';
import { useTranslation } from 'react-i18next';
import { Handle, NodeProps, Position } from 'reactflow';
import { NodeData } from '../../interface';
import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
import styles from './index.less';
import NodeHeader from './node-header';
import NodePopover from './popover';
export function InvokeNode({
id,
data,
isConnectable = true,
selected,
}: NodeProps<NodeData>) {
const { t } = useTranslation();
const url = get(data, 'form.url');
return (
<NodePopover nodeId={id}>
<section
className={classNames(styles.ragNode, {
[styles.selectedNode]: selected,
})}
>
<Handle
id="c"
type="source"
position={Position.Left}
isConnectable={isConnectable}
className={styles.handle}
style={LeftHandleStyle}
></Handle>
<Handle
type="source"
position={Position.Right}
isConnectable={isConnectable}
className={styles.handle}
id="b"
style={RightHandleStyle}
></Handle>
<NodeHeader
id={id}
name={data.name}
label={data.label}
className={styles.nodeHeader}
></NodeHeader>
<Flex vertical>
<div>{t('flow.url')}</div>
<div className={styles.nodeText}>{url}</div>
</Flex>
</section>
</NodePopover>
);
}

View File

@ -528,6 +528,7 @@ export const initialInvokeValues = {
"Connection": "keep-alive"
}`,
proxy: 'http://',
clean_html: false,
};
export const CategorizeAnchorPointPositions = [
@ -643,7 +644,7 @@ export const NodeMap = {
[Operator.TuShare]: 'ragNode',
[Operator.Note]: 'noteNode',
[Operator.Crawler]: 'ragNode',
[Operator.Invoke]: 'ragNode',
[Operator.Invoke]: 'invokeNode',
};
export const LanguageOptions = [

View File

@ -76,8 +76,8 @@ const FormMap = {
[Operator.TuShare]: TuShareForm,
[Operator.Crawler]: CrawlerForm,
[Operator.Invoke]: InvokeForm,
[Operator.Concentrator]: <></>,
[Operator.Note]: <></>,
[Operator.Concentrator]: () => <></>,
[Operator.Note]: () => <></>,
};
const EmptyContent = () => <div></div>;
@ -135,7 +135,7 @@ const FlowDrawer = ({
open={visible}
getContainer={false}
mask={false}
width={470}
width={500}
closeIcon={null}
>
<section className={styles.formWrapper}>

View File

@ -38,7 +38,6 @@ const DynamicVariables = ({ nodeId }: IProps) => {
title: t('key'),
dataIndex: 'key',
key: 'key',
// width: 40,
onCell: (record: IInvokeVariable) => ({
record,
editable: true,

View File

@ -1,5 +1,5 @@
import Editor from '@monaco-editor/react';
import { Form, Input, InputNumber, Select, Space } from 'antd';
import { Form, Input, InputNumber, Select, Space, Switch } from 'antd';
import { useTranslation } from 'react-i18next';
import { useSetLlmSetting } from '../../hooks';
import { IOperatorForm } from '../../interface';
@ -63,6 +63,9 @@ const InvokeForm = ({ onValuesChange, form, node }: IOperatorForm) => {
<Form.Item name={'proxy'} label={t('flow.proxy')}>
<Input />
</Form.Item>
<Form.Item name={'clean_html'} label={t('flow.cleanHtml')}>
<Switch />
</Form.Item>
<DynamicVariables nodeId={node?.id}></DynamicVariables>
</Form>
</>