mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-22 20:37:48 +00:00
feat: add http node timeout (#2465)
* fix $ in replacement string misinterpreted as regex special character * add http timeout * delete console log
This commit is contained in:
@@ -105,6 +105,7 @@ export enum NodeInputKeyEnum {
|
|||||||
httpMethod = 'system_httpMethod',
|
httpMethod = 'system_httpMethod',
|
||||||
httpParams = 'system_httpParams',
|
httpParams = 'system_httpParams',
|
||||||
httpJsonBody = 'system_httpJsonBody',
|
httpJsonBody = 'system_httpJsonBody',
|
||||||
|
httpTimeout = 'system_httpTimeout',
|
||||||
abandon_httpUrl = 'url',
|
abandon_httpUrl = 'url',
|
||||||
|
|
||||||
// app
|
// app
|
||||||
|
@@ -44,6 +44,16 @@ export const HttpNode468: FlowNodeTemplateType = {
|
|||||||
value: 'POST',
|
value: 'POST',
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: NodeInputKeyEnum.httpTimeout,
|
||||||
|
renderTypeList: [FlowNodeInputTypeEnum.custom],
|
||||||
|
valueType: WorkflowIOValueTypeEnum.number,
|
||||||
|
label: '',
|
||||||
|
value: 120,
|
||||||
|
min: 30,
|
||||||
|
max: 600,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: NodeInputKeyEnum.httpReqUrl,
|
key: NodeInputKeyEnum.httpReqUrl,
|
||||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||||
|
@@ -57,6 +57,7 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise<H
|
|||||||
system_httpHeader: httpHeader,
|
system_httpHeader: httpHeader,
|
||||||
system_httpParams: httpParams = [],
|
system_httpParams: httpParams = [],
|
||||||
system_httpJsonBody: httpJsonBody,
|
system_httpJsonBody: httpJsonBody,
|
||||||
|
system_httpTimeout: httpTimeout,
|
||||||
[NodeInputKeyEnum.addInputParam]: dynamicInput,
|
[NodeInputKeyEnum.addInputParam]: dynamicInput,
|
||||||
...body
|
...body
|
||||||
}
|
}
|
||||||
@@ -143,7 +144,8 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise<H
|
|||||||
url: httpReqUrl,
|
url: httpReqUrl,
|
||||||
headers,
|
headers,
|
||||||
body: requestBody,
|
body: requestBody,
|
||||||
params
|
params,
|
||||||
|
timeout: httpTimeout
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
||||||
@@ -199,13 +201,15 @@ async function fetchData({
|
|||||||
url,
|
url,
|
||||||
headers,
|
headers,
|
||||||
body,
|
body,
|
||||||
params
|
params,
|
||||||
|
timeout
|
||||||
}: {
|
}: {
|
||||||
method: string;
|
method: string;
|
||||||
url: string;
|
url: string;
|
||||||
headers: Record<string, any>;
|
headers: Record<string, any>;
|
||||||
body: Record<string, any> | string;
|
body: Record<string, any> | string;
|
||||||
params: Record<string, any>;
|
params: Record<string, any>;
|
||||||
|
timeout: number;
|
||||||
}) {
|
}) {
|
||||||
const { data: response } = await axios({
|
const { data: response } = await axios({
|
||||||
method,
|
method,
|
||||||
@@ -215,7 +219,7 @@ async function fetchData({
|
|||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
...headers
|
...headers
|
||||||
},
|
},
|
||||||
timeout: 120000,
|
timeout: timeout * 1000,
|
||||||
params: params,
|
params: params,
|
||||||
data: ['POST', 'PUT', 'PATCH'].includes(method) ? body : undefined
|
data: ['POST', 'PUT', 'PATCH'].includes(method) ? body : undefined
|
||||||
});
|
});
|
||||||
@@ -308,7 +312,7 @@ function replaceVariable(text: string, obj: Record<string, any>) {
|
|||||||
replacement.startsWith('"') && replacement.endsWith('"')
|
replacement.startsWith('"') && replacement.endsWith('"')
|
||||||
? replacement.slice(1, -1)
|
? replacement.slice(1, -1)
|
||||||
: replacement;
|
: replacement;
|
||||||
text = text.replace(new RegExp(`{{(${key})}}`, 'g'), unquotedReplacement);
|
text = text.replace(new RegExp(`{{(${key})}}`, 'g'), () => unquotedReplacement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return text || '';
|
return text || '';
|
||||||
|
@@ -617,7 +617,8 @@
|
|||||||
"success": "Start syncing"
|
"success": "Start syncing"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"training": {}
|
"training": {
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"data": {
|
"data": {
|
||||||
"Auxiliary Data": "Auxiliary data",
|
"Auxiliary Data": "Auxiliary data",
|
||||||
@@ -795,6 +796,7 @@
|
|||||||
"Field Name": "Field name",
|
"Field Name": "Field name",
|
||||||
"Http request props": "Request parameters",
|
"Http request props": "Request parameters",
|
||||||
"Http request settings": "Request settings",
|
"Http request settings": "Request settings",
|
||||||
|
"Http timeout": "Timeout",
|
||||||
"Input Type": "Input type",
|
"Input Type": "Input type",
|
||||||
"Laf sync params": "Synchronize parameters",
|
"Laf sync params": "Synchronize parameters",
|
||||||
"Max Length": "Maximum length",
|
"Max Length": "Maximum length",
|
||||||
|
@@ -617,7 +617,8 @@
|
|||||||
"success": "开始同步"
|
"success": "开始同步"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"training": {}
|
"training": {
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"data": {
|
"data": {
|
||||||
"Auxiliary Data": "辅助数据",
|
"Auxiliary Data": "辅助数据",
|
||||||
@@ -795,6 +796,7 @@
|
|||||||
"Field Name": "字段名",
|
"Field Name": "字段名",
|
||||||
"Http request props": "请求参数",
|
"Http request props": "请求参数",
|
||||||
"Http request settings": "请求配置",
|
"Http request settings": "请求配置",
|
||||||
|
"Http timeout": "超时时长",
|
||||||
"Input Type": "输入类型",
|
"Input Type": "输入类型",
|
||||||
"Laf sync params": "同步参数",
|
"Laf sync params": "同步参数",
|
||||||
"Max Length": "最大长度",
|
"Max Length": "最大长度",
|
||||||
@@ -993,7 +995,6 @@
|
|||||||
"Edit Folder": "编辑文件夹",
|
"Edit Folder": "编辑文件夹",
|
||||||
"Edit Info": "编辑信息",
|
"Edit Info": "编辑信息",
|
||||||
"Export": "导出",
|
"Export": "导出",
|
||||||
"dataset_name": "知识库名称",
|
|
||||||
"Export Dataset Limit Error": "导出数据失败",
|
"Export Dataset Limit Error": "导出数据失败",
|
||||||
"Folder Name": "输入文件夹名称",
|
"Folder Name": "输入文件夹名称",
|
||||||
"Insert Data": "插入",
|
"Insert Data": "插入",
|
||||||
@@ -1031,6 +1032,7 @@
|
|||||||
},
|
},
|
||||||
"input is empty": "数据内容不能为空 "
|
"input is empty": "数据内容不能为空 "
|
||||||
},
|
},
|
||||||
|
"dataset_name": "知识库名称",
|
||||||
"deleteFolderTips": "确认删除该文件夹及其包含的所有知识库?删除后数据无法恢复,请确认!",
|
"deleteFolderTips": "确认删除该文件夹及其包含的所有知识库?删除后数据无法恢复,请确认!",
|
||||||
"test": {
|
"test": {
|
||||||
"noResult": "搜索结果为空"
|
"noResult": "搜索结果为空"
|
||||||
|
@@ -92,7 +92,6 @@ const NodeTemplatesModal = ({ isOpen, onClose }: ModuleTemplateListProps) => {
|
|||||||
const { data: basicNodes } = useRequest2(
|
const { data: basicNodes } = useRequest2(
|
||||||
async () => {
|
async () => {
|
||||||
if (templateType === TemplateTypeEnum.basic) {
|
if (templateType === TemplateTypeEnum.basic) {
|
||||||
console.log(1111);
|
|
||||||
return basicNodeTemplates
|
return basicNodeTemplates
|
||||||
.filter((item) => {
|
.filter((item) => {
|
||||||
// unique node filter
|
// unique node filter
|
||||||
|
@@ -17,7 +17,12 @@ import {
|
|||||||
Td,
|
Td,
|
||||||
TableContainer,
|
TableContainer,
|
||||||
Button,
|
Button,
|
||||||
useDisclosure
|
useDisclosure,
|
||||||
|
NumberInputField,
|
||||||
|
NumberInputStepper,
|
||||||
|
NumberIncrementStepper,
|
||||||
|
NumberDecrementStepper,
|
||||||
|
NumberInput
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants';
|
import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
@@ -372,6 +377,61 @@ export function RenderHttpProps({
|
|||||||
|
|
||||||
return Render;
|
return Render;
|
||||||
}
|
}
|
||||||
|
const RenderHttpTimeout = ({
|
||||||
|
nodeId,
|
||||||
|
inputs
|
||||||
|
}: {
|
||||||
|
nodeId: string;
|
||||||
|
inputs: FlowNodeInputItemType[];
|
||||||
|
}) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const timeout = inputs.find((item) => item.key === NodeInputKeyEnum.httpTimeout)!;
|
||||||
|
const [isEditTimeout, setIsEditTimeout] = useState(false);
|
||||||
|
const onChangeNode = useContextSelector(WorkflowContext, (v) => v.onChangeNode);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box>
|
||||||
|
<Box mb={2} display={'flex'} justifyContent={'space-between'}>
|
||||||
|
<Box fontWeight={'medium'} color={'myGray.600'}>
|
||||||
|
{t('common:core.module.Http timeout')}
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
{isEditTimeout ? (
|
||||||
|
<NumberInput
|
||||||
|
defaultValue={timeout.value}
|
||||||
|
min={timeout.min}
|
||||||
|
max={timeout.max}
|
||||||
|
onBlur={() => setIsEditTimeout(false)}
|
||||||
|
onChange={(e) => {
|
||||||
|
onChangeNode({
|
||||||
|
nodeId,
|
||||||
|
type: 'updateInput',
|
||||||
|
key: NodeInputKeyEnum.httpTimeout,
|
||||||
|
value: {
|
||||||
|
...timeout,
|
||||||
|
value: Number(e)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<NumberInputField bg={'white'} px={3} borderRadius={'sm'} />
|
||||||
|
<NumberInputStepper>
|
||||||
|
<NumberIncrementStepper />
|
||||||
|
<NumberDecrementStepper />
|
||||||
|
</NumberInputStepper>
|
||||||
|
</NumberInput>
|
||||||
|
) : (
|
||||||
|
<Button
|
||||||
|
variant={'ghost'}
|
||||||
|
color={'myGray.600'}
|
||||||
|
onClick={() => setIsEditTimeout(true)}
|
||||||
|
>{`${timeout?.value} s`}</Button>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
const RenderForm = ({
|
const RenderForm = ({
|
||||||
nodeId,
|
nodeId,
|
||||||
input,
|
input,
|
||||||
@@ -643,11 +703,13 @@ const NodeHttp = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
|
|||||||
<RenderHttpMethodAndUrl nodeId={nodeId} inputs={inputs} />
|
<RenderHttpMethodAndUrl nodeId={nodeId} inputs={inputs} />
|
||||||
));
|
));
|
||||||
const Headers = useMemoizedFn(() => <RenderHttpProps nodeId={nodeId} inputs={inputs} />);
|
const Headers = useMemoizedFn(() => <RenderHttpProps nodeId={nodeId} inputs={inputs} />);
|
||||||
|
const HttpTimeout = useMemoizedFn(() => <RenderHttpTimeout nodeId={nodeId} inputs={inputs} />);
|
||||||
|
|
||||||
const CustomComponents = useMemo(() => {
|
const CustomComponents = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
[NodeInputKeyEnum.httpMethod]: HttpMethodAndUrl,
|
[NodeInputKeyEnum.httpMethod]: HttpMethodAndUrl,
|
||||||
[NodeInputKeyEnum.httpHeaders]: Headers
|
[NodeInputKeyEnum.httpHeaders]: Headers,
|
||||||
|
[NodeInputKeyEnum.httpTimeout]: HttpTimeout
|
||||||
};
|
};
|
||||||
}, [Headers, HttpMethodAndUrl]);
|
}, [Headers, HttpMethodAndUrl]);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user