mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-23 21:13:50 +00:00
Perf: read file woker (#1337)
* perf: read file worker * fix: Http node url input * fix: htm2md * fix: html2md * fix: ts * perf: Problem classification increases the matching order * feat: tool response answer
This commit is contained in:
@@ -51,11 +51,15 @@ const nextConfig = {
|
||||
...entries,
|
||||
'worker/htmlStr2Md': path.resolve(
|
||||
process.cwd(),
|
||||
'../../packages/service/worker/htmlStr2Md.ts'
|
||||
'../../packages/service/worker/htmlStr2Md/index.ts'
|
||||
),
|
||||
'worker/countGptMessagesTokens': path.resolve(
|
||||
process.cwd(),
|
||||
'../../packages/service/worker/tiktoken/countGptMessagesTokens.ts'
|
||||
),
|
||||
'worker/readFile': path.resolve(
|
||||
process.cwd(),
|
||||
'../../packages/service/worker/file/read.ts'
|
||||
)
|
||||
};
|
||||
}
|
||||
@@ -82,7 +86,12 @@ const nextConfig = {
|
||||
serverComponentsExternalPackages: ['mongoose', 'pg'],
|
||||
// 指定导出包优化,按需引入包模块
|
||||
optimizePackageImports: ['mongoose', 'pg'],
|
||||
outputFileTracingRoot: path.join(__dirname, '../../')
|
||||
outputFileTracingRoot: path.join(__dirname, '../../'),
|
||||
outputFileTracingIncludes: {
|
||||
'/api/common/file/previewContent.ts': [
|
||||
path.resolve(process.cwd(), '../../packages/service/worker/**/*')
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "app",
|
||||
"version": "4.7.1",
|
||||
"version": "4.8",
|
||||
"private": false,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
|
@@ -38,6 +38,7 @@ import IOTitle from '../../components/IOTitle';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
import { WorkflowContext } from '../../../context';
|
||||
import { getWorkflowGlobalVariables } from '@/web/core/workflow/utils';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
const CurlImportModal = dynamic(() => import('./CurlImportModal'));
|
||||
|
||||
export const HttpHeaders = [
|
||||
@@ -108,159 +109,136 @@ const RenderHttpMethodAndUrl = React.memo(function RenderHttpMethodAndUrl({
|
||||
const requestMethods = inputs.find((item) => item.key === NodeInputKeyEnum.httpMethod);
|
||||
const requestUrl = inputs.find((item) => item.key === NodeInputKeyEnum.httpReqUrl);
|
||||
|
||||
const onChangeUrl = useCallback(
|
||||
(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const onChangeUrl = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
onChangeNode({
|
||||
nodeId,
|
||||
type: 'updateInput',
|
||||
key: NodeInputKeyEnum.httpReqUrl,
|
||||
value: {
|
||||
...requestUrl,
|
||||
value: e.target.value
|
||||
}
|
||||
});
|
||||
};
|
||||
const onBlurUrl = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const val = e.target.value;
|
||||
// 拆分params和url
|
||||
const url = val.split('?')[0];
|
||||
const params = val.split('?')[1];
|
||||
if (params) {
|
||||
const paramsArr = params.split('&');
|
||||
const paramsObj = paramsArr.reduce((acc, cur) => {
|
||||
const [key, value] = cur.split('=');
|
||||
return {
|
||||
...acc,
|
||||
[key]: value
|
||||
};
|
||||
}, {});
|
||||
const inputParams = inputs.find((item) => item.key === NodeInputKeyEnum.httpParams);
|
||||
|
||||
if (!inputParams || Object.keys(paramsObj).length === 0) return;
|
||||
|
||||
const concatParams: PropsArrType[] = inputParams?.value || [];
|
||||
Object.entries(paramsObj).forEach(([key, value]) => {
|
||||
if (!concatParams.find((item) => item.key === key)) {
|
||||
concatParams.push({ key, value: value as string, type: 'string' });
|
||||
}
|
||||
});
|
||||
|
||||
onChangeNode({
|
||||
nodeId,
|
||||
type: 'updateInput',
|
||||
key: NodeInputKeyEnum.httpParams,
|
||||
value: {
|
||||
...inputParams,
|
||||
value: concatParams
|
||||
}
|
||||
});
|
||||
|
||||
onChangeNode({
|
||||
nodeId,
|
||||
type: 'updateInput',
|
||||
key: NodeInputKeyEnum.httpReqUrl,
|
||||
value: {
|
||||
...requestUrl,
|
||||
value: e.target.value
|
||||
value: url
|
||||
}
|
||||
});
|
||||
},
|
||||
[nodeId, onChangeNode, requestUrl]
|
||||
);
|
||||
|
||||
const onBlurUrl = useCallback(
|
||||
(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const val = e.target.value;
|
||||
// 拆分params和url
|
||||
const url = val.split('?')[0];
|
||||
const params = val.split('?')[1];
|
||||
if (params) {
|
||||
const paramsArr = params.split('&');
|
||||
const paramsObj = paramsArr.reduce((acc, cur) => {
|
||||
const [key, value] = cur.split('=');
|
||||
return {
|
||||
...acc,
|
||||
[key]: value
|
||||
};
|
||||
}, {});
|
||||
const inputParams = inputs.find((item) => item.key === NodeInputKeyEnum.httpParams);
|
||||
toast({
|
||||
status: 'success',
|
||||
title: t('core.module.http.Url and params have been split')
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
if (!inputParams || Object.keys(paramsObj).length === 0) return;
|
||||
|
||||
const concatParams: PropsArrType[] = inputParams?.value || [];
|
||||
Object.entries(paramsObj).forEach(([key, value]) => {
|
||||
if (!concatParams.find((item) => item.key === key)) {
|
||||
concatParams.push({ key, value: value as string, type: 'string' });
|
||||
}
|
||||
});
|
||||
|
||||
onChangeNode({
|
||||
nodeId,
|
||||
type: 'updateInput',
|
||||
key: NodeInputKeyEnum.httpParams,
|
||||
value: {
|
||||
...inputParams,
|
||||
value: concatParams
|
||||
}
|
||||
});
|
||||
|
||||
onChangeNode({
|
||||
nodeId,
|
||||
type: 'updateInput',
|
||||
key: NodeInputKeyEnum.httpReqUrl,
|
||||
value: {
|
||||
...requestUrl,
|
||||
value: url
|
||||
}
|
||||
});
|
||||
|
||||
toast({
|
||||
status: 'success',
|
||||
title: t('core.module.http.Url and params have been split')
|
||||
});
|
||||
}
|
||||
},
|
||||
[inputs, nodeId, onChangeNode, requestUrl, t, toast]
|
||||
);
|
||||
|
||||
const Render = useMemo(() => {
|
||||
return (
|
||||
<Box>
|
||||
<Box mb={2} display={'flex'} justifyContent={'space-between'}>
|
||||
<Box fontWeight={'medium'} color={'myGray.600'}>
|
||||
{t('core.module.Http request settings')}
|
||||
</Box>
|
||||
<Button variant={'link'} onClick={onOpenCurl}>
|
||||
{t('core.module.http.curl import')}
|
||||
</Button>
|
||||
return (
|
||||
<Box>
|
||||
<Box mb={2} display={'flex'} justifyContent={'space-between'}>
|
||||
<Box fontWeight={'medium'} color={'myGray.600'}>
|
||||
{t('core.module.Http request settings')}
|
||||
</Box>
|
||||
<Flex alignItems={'center'} className="nodrag">
|
||||
<MySelect
|
||||
h={'34px'}
|
||||
w={'88px'}
|
||||
bg={'white'}
|
||||
width={'100%'}
|
||||
value={requestMethods?.value}
|
||||
list={[
|
||||
{
|
||||
label: 'GET',
|
||||
value: 'GET'
|
||||
},
|
||||
{
|
||||
label: 'POST',
|
||||
value: 'POST'
|
||||
},
|
||||
{
|
||||
label: 'PUT',
|
||||
value: 'PUT'
|
||||
},
|
||||
{
|
||||
label: 'DELETE',
|
||||
value: 'DELETE'
|
||||
},
|
||||
{
|
||||
label: 'PATCH',
|
||||
value: 'PATCH'
|
||||
}
|
||||
]}
|
||||
onchange={(e) => {
|
||||
onChangeNode({
|
||||
nodeId,
|
||||
type: 'updateInput',
|
||||
key: NodeInputKeyEnum.httpMethod,
|
||||
value: {
|
||||
...requestMethods,
|
||||
value: e
|
||||
}
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<Input
|
||||
flex={'1 0 0'}
|
||||
ml={2}
|
||||
h={'34px'}
|
||||
bg={'white'}
|
||||
value={requestUrl?.value}
|
||||
placeholder={t('core.module.input.label.Http Request Url')}
|
||||
fontSize={'xs'}
|
||||
onChange={onChangeUrl}
|
||||
onBlur={onBlurUrl}
|
||||
/>
|
||||
</Flex>
|
||||
|
||||
{isOpenCurl && <CurlImportModal nodeId={nodeId} inputs={inputs} onClose={onCloseCurl} />}
|
||||
<Button variant={'link'} onClick={onOpenCurl}>
|
||||
{t('core.module.http.curl import')}
|
||||
</Button>
|
||||
</Box>
|
||||
);
|
||||
}, [
|
||||
inputs,
|
||||
isOpenCurl,
|
||||
nodeId,
|
||||
onBlurUrl,
|
||||
onChangeNode,
|
||||
onChangeUrl,
|
||||
onCloseCurl,
|
||||
onOpenCurl,
|
||||
requestMethods,
|
||||
requestUrl?.value,
|
||||
t
|
||||
]);
|
||||
<Flex alignItems={'center'} className="nodrag">
|
||||
<MySelect
|
||||
h={'34px'}
|
||||
w={'88px'}
|
||||
bg={'white'}
|
||||
width={'100%'}
|
||||
value={requestMethods?.value}
|
||||
list={[
|
||||
{
|
||||
label: 'GET',
|
||||
value: 'GET'
|
||||
},
|
||||
{
|
||||
label: 'POST',
|
||||
value: 'POST'
|
||||
},
|
||||
{
|
||||
label: 'PUT',
|
||||
value: 'PUT'
|
||||
},
|
||||
{
|
||||
label: 'DELETE',
|
||||
value: 'DELETE'
|
||||
},
|
||||
{
|
||||
label: 'PATCH',
|
||||
value: 'PATCH'
|
||||
}
|
||||
]}
|
||||
onchange={(e) => {
|
||||
onChangeNode({
|
||||
nodeId,
|
||||
type: 'updateInput',
|
||||
key: NodeInputKeyEnum.httpMethod,
|
||||
value: {
|
||||
...requestMethods,
|
||||
value: e
|
||||
}
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<Input
|
||||
flex={'1 0 0'}
|
||||
ml={2}
|
||||
h={'34px'}
|
||||
bg={'white'}
|
||||
value={requestUrl?.value || ''}
|
||||
placeholder={t('core.module.input.label.Http Request Url')}
|
||||
fontSize={'xs'}
|
||||
onChange={onChangeUrl}
|
||||
onBlur={onBlurUrl}
|
||||
/>
|
||||
</Flex>
|
||||
|
||||
return Render;
|
||||
{isOpenCurl && <CurlImportModal nodeId={nodeId} inputs={inputs} onClose={onCloseCurl} />}
|
||||
</Box>
|
||||
);
|
||||
});
|
||||
|
||||
export function RenderHttpProps({
|
||||
@@ -644,15 +622,17 @@ const NodeHttp = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
|
||||
const splitToolInputs = useContextSelector(WorkflowContext, (v) => v.splitToolInputs);
|
||||
const { toolInputs, commonInputs, isTool } = splitToolInputs(inputs, nodeId);
|
||||
|
||||
const CustomComponents = useMemo(
|
||||
() => ({
|
||||
[NodeInputKeyEnum.httpMethod]: () => (
|
||||
<RenderHttpMethodAndUrl nodeId={nodeId} inputs={inputs} />
|
||||
),
|
||||
[NodeInputKeyEnum.httpHeaders]: () => <RenderHttpProps nodeId={nodeId} inputs={inputs} />
|
||||
}),
|
||||
[inputs, nodeId]
|
||||
);
|
||||
const HttpMethodAndUrl = useMemoizedFn(() => (
|
||||
<RenderHttpMethodAndUrl nodeId={nodeId} inputs={inputs} />
|
||||
));
|
||||
const Headers = useMemoizedFn(() => <RenderHttpProps nodeId={nodeId} inputs={inputs} />);
|
||||
|
||||
const CustomComponents = useMemo(() => {
|
||||
return {
|
||||
[NodeInputKeyEnum.httpMethod]: HttpMethodAndUrl,
|
||||
[NodeInputKeyEnum.httpHeaders]: Headers
|
||||
};
|
||||
}, [Headers, HttpMethodAndUrl]);
|
||||
|
||||
return (
|
||||
<NodeCard minW={'350px'} selected={selected} {...data}>
|
||||
|
@@ -10,10 +10,11 @@ import { ToolSourceHandle } from './render/Handle/ToolHandle';
|
||||
import { Box } from '@chakra-ui/react';
|
||||
import IOTitle from '../components/IOTitle';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import RenderOutput from './render/RenderOutput';
|
||||
|
||||
const NodeTools = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
|
||||
const { t } = useTranslation();
|
||||
const { nodeId, inputs } = data;
|
||||
const { nodeId, inputs, outputs } = data;
|
||||
|
||||
return (
|
||||
<NodeCard minW={'350px'} selected={selected} {...data}>
|
||||
@@ -21,7 +22,10 @@ const NodeTools = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
|
||||
<IOTitle text={t('common.Input')} />
|
||||
<RenderInput nodeId={nodeId} flowInputList={inputs} />
|
||||
</Container>
|
||||
|
||||
<Container>
|
||||
<IOTitle text={t('common.Output')} />
|
||||
<RenderOutput nodeId={nodeId} flowOutputList={outputs} />
|
||||
</Container>
|
||||
<Box position={'relative'}>
|
||||
<Box borderBottomLeftRadius={'md'} borderBottomRadius={'md'} overflow={'hidden'}>
|
||||
<Divider
|
||||
|
@@ -58,7 +58,7 @@ const InputLabel = ({ nodeId, input }: Props) => {
|
||||
);
|
||||
|
||||
const RenderLabel = useMemo(() => {
|
||||
const renderType = renderTypeList[selectedTypeIndex || 0];
|
||||
const renderType = renderTypeList?.[selectedTypeIndex || 0];
|
||||
|
||||
return (
|
||||
<Flex className="nodrag" cursor={'default'} alignItems={'center'} position={'relative'}>
|
||||
|
Reference in New Issue
Block a user