4.6.8-production (#822)

* Json completion (#16)

* json-completion

* fix duplicate

* fix

* fix: config json

* feat: query extension

* perf: i18n

* 468 doc

* json editor

* perf: doc

* perf: default extension model

* docker file

* doc

* perf: token count

* perf: search extension

* format

* perf: some constants data

---------

Co-authored-by: heheer <71265218+newfish-cmyk@users.noreply.github.com>
This commit is contained in:
Archer
2024-02-05 00:51:46 +08:00
committed by GitHub
parent ec8e2512bc
commit 51bbdf26a3
68 changed files with 4118 additions and 3787 deletions

View File

@@ -34,14 +34,12 @@ const AIChatSettingsModal = ({
onClose,
onSuccess,
defaultData,
simpleModeTemplate = SimpleModeTemplate_FastGPT_Universal,
pickerMenu = []
}: {
isAdEdit?: boolean;
onClose: () => void;
onSuccess: (e: AIChatModuleProps) => void;
defaultData: AIChatModuleProps;
simpleModeTemplate?: AppSimpleEditConfigTemplateType;
pickerMenu?: EditorVariablePickerType[];
}) => {
const { t } = useTranslation();
@@ -160,119 +158,112 @@ const AIChatSettingsModal = ({
</Box>
</Flex>
)}
{simpleModeTemplate?.systemForm?.aiSettings?.temperature && (
<Flex mb={10} mt={isAdEdit ? 8 : 6}>
<Box {...LabelStyles} mr={2} w={'80px'}>
{t('core.app.Temperature')}
</Box>
<Box flex={1} ml={'10px'}>
<MySlider
markList={[
{ label: t('core.app.deterministic'), value: 0 },
{ label: t('core.app.Random'), value: 10 }
]}
width={'95%'}
min={0}
max={10}
value={getValues(ModuleInputKeyEnum.aiChatTemperature)}
onChange={(e) => {
setValue(ModuleInputKeyEnum.aiChatTemperature, e);
setRefresh(!refresh);
}}
/>
</Box>
</Flex>
)}
{simpleModeTemplate?.systemForm?.aiSettings?.maxToken && (
<Flex mt={5} mb={5}>
<Box {...LabelStyles} mr={2} w={'80px'}>
{t('core.app.Max tokens')}
</Box>
<Box flex={1} ml={'10px'}>
<MySlider
markList={[
{ label: '100', value: 100 },
{ label: `${tokenLimit}`, value: tokenLimit }
]}
width={'95%'}
min={100}
max={tokenLimit}
step={50}
value={getValues(ModuleInputKeyEnum.aiChatMaxToken)}
onChange={(val) => {
setValue(ModuleInputKeyEnum.aiChatMaxToken, val);
setRefresh(!refresh);
}}
/>
</Box>
</Flex>
)}
<Flex mb={10} mt={isAdEdit ? 8 : 6}>
<Box {...LabelStyles} mr={2} w={'80px'}>
{t('core.app.Temperature')}
</Box>
<Box flex={1} ml={'10px'}>
<MySlider
markList={[
{ label: t('core.app.deterministic'), value: 0 },
{ label: t('core.app.Random'), value: 10 }
]}
width={'95%'}
min={0}
max={10}
value={getValues(ModuleInputKeyEnum.aiChatTemperature)}
onChange={(e) => {
setValue(ModuleInputKeyEnum.aiChatTemperature, e);
setRefresh(!refresh);
}}
/>
</Box>
</Flex>
<Flex mt={5} mb={5}>
<Box {...LabelStyles} mr={2} w={'80px'}>
{t('core.app.Max tokens')}
</Box>
<Box flex={1} ml={'10px'}>
<MySlider
markList={[
{ label: '100', value: 100 },
{ label: `${tokenLimit}`, value: tokenLimit }
]}
width={'95%'}
min={100}
max={tokenLimit}
step={50}
value={getValues(ModuleInputKeyEnum.aiChatMaxToken)}
onChange={(val) => {
setValue(ModuleInputKeyEnum.aiChatMaxToken, val);
setRefresh(!refresh);
}}
/>
</Box>
</Flex>
{simpleModeTemplate?.systemForm?.aiSettings?.quoteTemplate && (
<Box>
<Flex {...LabelStyles} mb={1}>
{t('core.app.Quote templates')}
<MyTooltip
label={t('template.Quote Content Tip', {
default: Prompt_QuoteTemplateList[0].value
})}
forceShow
>
<QuestionOutlineIcon display={['none', 'inline']} ml={1} />
</MyTooltip>
<Box flex={1} />
<Box
{...selectTemplateBtn}
onClick={() =>
setSelectTemplateData({
title: t('core.app.Select quote template'),
templates: Prompt_QuoteTemplateList
})
}
>
{t('common.Select template')}
</Box>
</Flex>
<PromptEditor
variables={quoteTemplateVariables}
title={t('core.app.Quote templates')}
placeholder={t('template.Quote Content Tip', {
<Box>
<Flex {...LabelStyles} mb={1}>
{t('core.app.Quote templates')}
<MyTooltip
label={t('template.Quote Content Tip', {
default: Prompt_QuoteTemplateList[0].value
})}
value={aiChatQuoteTemplate}
onChange={(e) => {
setValue(ModuleInputKeyEnum.aiChatQuoteTemplate, e);
// setRefresh(!refresh);
}}
/>
</Box>
)}
{simpleModeTemplate?.systemForm?.aiSettings?.quotePrompt && (
<Box mt={4}>
<Flex {...LabelStyles} mb={1}>
{t('core.app.Quote prompt')}
<MyTooltip
label={t('template.Quote Prompt Tip', { default: Prompt_QuotePromptList[0].value })}
forceShow
>
<QuestionOutlineIcon display={['none', 'inline']} ml={1} />
</MyTooltip>
</Flex>
<PromptEditor
variables={quotePromptVariables}
title={t('core.app.Quote prompt')}
h={220}
placeholder={t('template.Quote Prompt Tip', {
default: Prompt_QuotePromptList[0].value
})}
value={aiChatQuotePrompt}
onChange={(e) => {
setValue(ModuleInputKeyEnum.aiChatQuotePrompt, e);
}}
/>
</Box>
)}
forceShow
>
<QuestionOutlineIcon display={['none', 'inline']} ml={1} />
</MyTooltip>
<Box flex={1} />
<Box
{...selectTemplateBtn}
onClick={() =>
setSelectTemplateData({
title: t('core.app.Select quote template'),
templates: Prompt_QuoteTemplateList
})
}
>
{t('common.Select template')}
</Box>
</Flex>
<PromptEditor
variables={quoteTemplateVariables}
h={160}
title={t('core.app.Quote templates')}
placeholder={t('template.Quote Content Tip', {
default: Prompt_QuoteTemplateList[0].value
})}
value={aiChatQuoteTemplate}
onChange={(e) => {
setValue(ModuleInputKeyEnum.aiChatQuoteTemplate, e);
// setRefresh(!refresh);
}}
/>
</Box>
<Box mt={4}>
<Flex {...LabelStyles} mb={1}>
{t('core.app.Quote prompt')}
<MyTooltip
label={t('template.Quote Prompt Tip', { default: Prompt_QuotePromptList[0].value })}
forceShow
>
<QuestionOutlineIcon display={['none', 'inline']} ml={1} />
</MyTooltip>
</Flex>
<PromptEditor
variables={quotePromptVariables}
title={t('core.app.Quote prompt')}
h={230}
placeholder={t('template.Quote Prompt Tip', {
default: Prompt_QuotePromptList[0].value
})}
value={aiChatQuotePrompt}
onChange={(e) => {
setValue(ModuleInputKeyEnum.aiChatQuotePrompt, e);
}}
/>
</Box>
</ModalBody>
<ModalFooter>
<Button variant={'whiteBase'} onClick={onClose}>

View File

@@ -7,6 +7,7 @@ import {
Flex,
ModalBody,
ModalFooter,
Switch,
Textarea,
useTheme
} from '@chakra-ui/react';
@@ -23,15 +24,27 @@ import { ModuleInputKeyEnum } from '@fastgpt/global/core/module/constants';
import { DatasetSearchModeMap } from '@fastgpt/global/core/dataset/constants';
import MyRadio from '@/components/common/MyRadio';
import MyIcon from '@fastgpt/web/components/common/Icon';
import Tabs from '@/components/Tabs';
import PromptEditor from '@fastgpt/web/components/common/Textarea/PromptEditor';
import SelectAiModel from '@/components/Select/SelectAiModel';
type DatasetParamsProps = {
export type DatasetParamsProps = {
searchMode: `${DatasetSearchModeEnum}`;
searchEmptyText?: string;
limit?: number;
similarity?: number;
usingReRank?: boolean;
datasetSearchUsingExtensionQuery?: boolean;
datasetSearchExtensionModel?: string;
datasetSearchExtensionBg?: string;
maxTokens?: number;
searchEmptyText?: string;
};
enum SearchSettingTabEnum {
searchMode = 'searchMode',
limit = 'limit',
queryExtension = 'queryExtension'
}
const DatasetParamsModal = ({
searchMode = DatasetSearchModeEnum.embedding,
@@ -40,22 +53,39 @@ const DatasetParamsModal = ({
similarity,
usingReRank,
maxTokens = 3000,
datasetSearchUsingExtensionQuery,
datasetSearchExtensionModel,
datasetSearchExtensionBg,
onClose,
onSuccess
}: DatasetParamsProps & { onClose: () => void; onSuccess: (e: DatasetParamsProps) => void }) => {
const { t } = useTranslation();
const theme = useTheme();
const { reRankModelList } = useSystemStore();
const { reRankModelList, llmModelList } = useSystemStore();
const [refresh, setRefresh] = useState(false);
const { register, setValue, getValues, handleSubmit } = useForm<DatasetParamsProps>({
const [currentTabType, setCurrentTabType] = useState(SearchSettingTabEnum.searchMode);
const { register, setValue, getValues, handleSubmit, watch } = useForm<DatasetParamsProps>({
defaultValues: {
searchEmptyText,
limit,
similarity,
searchMode,
usingReRank
usingReRank,
datasetSearchUsingExtensionQuery,
datasetSearchExtensionModel: datasetSearchExtensionModel ?? llmModelList[0]?.model,
datasetSearchExtensionBg
}
});
const datasetSearchUsingCfrForm = watch('datasetSearchUsingExtensionQuery');
const queryExtensionModel = watch('datasetSearchExtensionModel');
const cfbBgDesc = watch('datasetSearchExtensionBg');
const chatModelSelectList = (() =>
llmModelList.map((item) => ({
value: item.model,
label: item.name
})))();
const searchModeList = useMemo(() => {
const list = Object.values(DatasetSearchModeMap);
@@ -82,125 +112,209 @@ const DatasetParamsModal = ({
iconSrc="/imgs/modal/params.svg"
title={t('core.dataset.search.Dataset Search Params')}
w={['90vw', '550px']}
h={['90vh', 'auto']}
isCentered={searchEmptyText !== undefined}
>
<ModalBody flex={['1 0 0', 'auto']} overflow={'auto'}>
<MyRadio
gridGap={2}
gridTemplateColumns={'repeat(1,1fr)'}
list={searchModeList}
value={getValues('searchMode')}
onChange={(e) => {
setValue('searchMode', e as `${DatasetSearchModeEnum}`);
setRefresh(!refresh);
}}
<ModalBody flex={'auto'} overflow={'auto'}>
<Tabs
mb={3}
list={[
{
icon: 'modal/setting',
label: t('core.dataset.search.search mode'),
id: SearchSettingTabEnum.searchMode
},
{
icon: 'support/outlink/apikeyFill',
label: t('core.dataset.search.Filter'),
id: SearchSettingTabEnum.limit
},
{
label: t('core.module.template.Query extension'),
id: SearchSettingTabEnum.queryExtension,
icon: '/imgs/module/cfr.svg'
}
]}
activeId={currentTabType}
onChange={(e) => setCurrentTabType(e as any)}
/>
{usingReRank !== undefined && reRankModelList.length > 0 && (
{currentTabType === SearchSettingTabEnum.searchMode && (
<>
<Divider my={4} />
<Flex
alignItems={'center'}
cursor={'pointer'}
userSelect={'none'}
py={3}
pl={'14px'}
pr={'16px'}
border={theme.borders.sm}
borderWidth={'1.5px'}
borderRadius={'md'}
position={'relative'}
{...(getValues('usingReRank')
? {
borderColor: 'primary.400'
}
: {})}
onClick={(e) => {
setValue('usingReRank', !getValues('usingReRank'));
setRefresh((state) => !state);
<MyRadio
gridGap={2}
gridTemplateColumns={'repeat(1,1fr)'}
list={searchModeList}
value={getValues('searchMode')}
onChange={(e) => {
setValue('searchMode', e as `${DatasetSearchModeEnum}`);
setRefresh(!refresh);
}}
>
<MyIcon name="core/dataset/rerank" w={'18px'} mr={'14px'} />
<Box pr={2} color={'myGray.800'} flex={'1 0 0'}>
<Box>{t('core.dataset.search.ReRank')}</Box>
<Box fontSize={['xs', 'sm']} color={'myGray.500'}>
{t('core.dataset.search.ReRank desc')}
</Box>
</Box>
<Box position={'relative'} w={'18px'} h={'18px'}>
<Checkbox colorScheme="primary" isChecked={getValues('usingReRank')} size="lg" />
<Box position={'absolute'} top={0} right={0} bottom={0} left={0} zIndex={1}></Box>
</Box>
</Flex>
/>
{usingReRank !== undefined && reRankModelList.length > 0 && (
<>
<Divider my={4} />
<Flex
alignItems={'center'}
cursor={'pointer'}
userSelect={'none'}
py={3}
pl={'14px'}
pr={'16px'}
border={theme.borders.sm}
borderWidth={'1.5px'}
borderRadius={'md'}
position={'relative'}
{...(getValues('usingReRank')
? {
borderColor: 'primary.400'
}
: {})}
onClick={(e) => {
setValue('usingReRank', !getValues('usingReRank'));
setRefresh((state) => !state);
}}
>
<MyIcon name="core/dataset/rerank" w={'18px'} mr={'14px'} />
<Box pr={2} color={'myGray.800'} flex={'1 0 0'}>
<Box>{t('core.dataset.search.ReRank')}</Box>
<Box fontSize={['xs', 'sm']} color={'myGray.500'}>
{t('core.dataset.search.ReRank desc')}
</Box>
</Box>
<Box position={'relative'} w={'18px'} h={'18px'}>
<Checkbox
colorScheme="primary"
isChecked={getValues('usingReRank')}
size="lg"
/>
<Box
position={'absolute'}
top={0}
right={0}
bottom={0}
left={0}
zIndex={1}
></Box>
</Box>
</Flex>
</>
)}
</>
)}
{limit !== undefined && (
<Box display={['block', 'flex']} mt={5}>
<Box flex={'0 0 120px'} mb={[8, 0]}>
{t('core.dataset.search.Max Tokens')}
<MyTooltip label={t('core.dataset.search.Max Tokens Tips')} forceShow>
<QuestionOutlineIcon ml={1} />
</MyTooltip>
</Box>
<Box flex={1} mx={4}>
<MySlider
markList={[
{ label: '100', value: 100 },
{ label: maxTokens, value: maxTokens }
]}
min={100}
max={maxTokens}
step={50}
value={getValues(ModuleInputKeyEnum.datasetMaxTokens) ?? 1000}
onChange={(val) => {
setValue(ModuleInputKeyEnum.datasetMaxTokens, val);
setRefresh(!refresh);
}}
/>
</Box>
{currentTabType === SearchSettingTabEnum.limit && (
<Box pt={5}>
{limit !== undefined && (
<Box display={['block', 'flex']}>
<Box flex={'0 0 120px'} mb={[8, 0]}>
{t('core.dataset.search.Max Tokens')}
<MyTooltip label={t('core.dataset.search.Max Tokens Tips')} forceShow>
<QuestionOutlineIcon ml={1} />
</MyTooltip>
</Box>
<Box flex={1} mx={4}>
<MySlider
markList={[
{ label: '100', value: 100 },
{ label: maxTokens, value: maxTokens }
]}
min={100}
max={maxTokens}
step={50}
value={getValues(ModuleInputKeyEnum.datasetMaxTokens) ?? 1000}
onChange={(val) => {
setValue(ModuleInputKeyEnum.datasetMaxTokens, val);
setRefresh(!refresh);
}}
/>
</Box>
</Box>
)}
{showSimilarity && (
<Box display={['block', 'flex']} mt={10}>
<Box flex={'0 0 120px'} mb={[8, 0]}>
{t('core.dataset.search.Min Similarity')}
<MyTooltip label={t('core.dataset.search.Min Similarity Tips')} forceShow>
<QuestionOutlineIcon ml={1} />
</MyTooltip>
</Box>
<Box flex={1} mx={4}>
<MySlider
markList={[
{ label: '0', value: 0 },
{ label: '1', value: 1 }
]}
min={0}
max={1}
step={0.01}
value={getValues(ModuleInputKeyEnum.datasetSimilarity) ?? 0.5}
onChange={(val) => {
setValue(ModuleInputKeyEnum.datasetSimilarity, val);
setRefresh(!refresh);
}}
/>
</Box>
</Box>
)}
{searchEmptyText !== undefined && (
<Box display={['block', 'flex']} pt={3}>
<Box flex={'0 0 120px'} mb={[2, 0]}>
{t('core.dataset.search.Empty result response')}
</Box>
<Box flex={1}>
<Textarea
rows={5}
maxLength={500}
placeholder={t('core.dataset.search.Empty result response Tips')}
{...register('searchEmptyText')}
></Textarea>
</Box>
</Box>
)}
</Box>
)}
{showSimilarity && (
<Box display={['block', 'flex']} mt={5}>
<Box flex={'0 0 120px'} mb={[8, 0]}>
{t('core.dataset.search.Min Similarity')}
<MyTooltip label={t('core.dataset.search.Min Similarity Tips')} forceShow>
<QuestionOutlineIcon ml={1} />
</MyTooltip>
</Box>
<Box flex={1} mx={4}>
<MySlider
markList={[
{ label: '0', value: 0 },
{ label: '1', value: 1 }
]}
min={0}
max={1}
step={0.01}
value={getValues(ModuleInputKeyEnum.datasetSimilarity) ?? 0.5}
onChange={(val) => {
setValue(ModuleInputKeyEnum.datasetSimilarity, val);
setRefresh(!refresh);
}}
/>
</Box>
</Box>
)}
{searchEmptyText !== undefined && (
<Box display={['block', 'flex']} pt={3}>
<Box flex={'0 0 120px'} mb={[2, 0]}>
{t('core.dataset.search.Empty result response')}
</Box>
<Box flex={1}>
<Textarea
rows={5}
maxLength={500}
placeholder={t('core.dataset.search.Empty result response Tips')}
{...register('searchEmptyText')}
></Textarea>
{currentTabType === SearchSettingTabEnum.queryExtension && (
<Box>
<Box fontSize={'xs'} color={'myGray.500'}>
{t('core.module.template.Query extension intro')}
</Box>
<Flex mt={3} alignItems={'center'}>
<Box flex={'1 0 0'}>{t('core.dataset.search.Using query extension')}</Box>
<Switch {...register('datasetSearchUsingExtensionQuery')} />
</Flex>
{datasetSearchUsingCfrForm === true && (
<>
<Flex mt={4} alignItems={'center'}>
<Box flex={'0 0 100px'}>{t('core.ai.Model')}</Box>
<Box flex={'1 0 0'}>
<SelectAiModel
width={'100%'}
value={queryExtensionModel}
list={chatModelSelectList}
onchange={(val: any) => {
setValue('datasetSearchExtensionModel', val);
}}
/>
</Box>
</Flex>
<Box mt={3}>
<Flex alignItems={'center'}>
{t('core.app.edit.Query extension background prompt')}
<MyTooltip label={t('core.app.edit.Query extension background tip')} forceShow>
<QuestionOutlineIcon display={['none', 'inline']} ml={1} />
</MyTooltip>
</Flex>
<Box mt={1}>
<PromptEditor
h={200}
showOpenModal={false}
placeholder={t('core.module.QueryExtension.placeholder')}
value={cfbBgDesc}
onChange={(e) => {
setValue('datasetSearchExtensionBg', e);
}}
/>
</Box>
</Box>
</>
)}
</Box>
)}
</ModalBody>

View File

@@ -53,8 +53,8 @@ const TTSSelect = ({
if (e === TTSTypeEnum.none || e === TTSTypeEnum.web) {
onChange({ type: e as `${TTSTypeEnum}` });
} else {
const audioModel = audioSpeechModelList.find(
(item) => item.voices?.find((voice) => voice.value === e)
const audioModel = audioSpeechModelList.find((item) =>
item.voices?.find((voice) => voice.value === e)
);
if (!audioModel) {
return;

View File

@@ -0,0 +1,26 @@
import React from 'react';
import { NodeProps } from 'reactflow';
import NodeCard from '../render/NodeCard';
import { FlowModuleItemType } from '@fastgpt/global/core/module/type.d';
import Divider from '../modules/Divider';
import Container from '../modules/Container';
import RenderInput from '../render/RenderInput';
import RenderOutput from '../render/RenderOutput';
const NodeHttp = ({ data, selected }: NodeProps<FlowModuleItemType>) => {
const { moduleId, inputs, outputs } = data;
return (
<NodeCard minW={'350px'} selected={selected} {...data}>
<Divider text="Input" />
<Container>
<RenderInput moduleId={moduleId} flowInputList={inputs} />
</Container>
<Divider text="Output" />
<Container>
<RenderOutput moduleId={moduleId} flowOutputList={outputs} />
</Container>
</NodeCard>
);
};
export default React.memo(NodeHttp);

View File

@@ -61,8 +61,9 @@ const NodeCard = (props: Props) => {
icon: 'common/refreshLight',
label: t('plugin.Synchronous version'),
onClick: () => {
const pluginId = inputs.find((item) => item.key === ModuleInputKeyEnum.pluginId)
?.value;
const pluginId = inputs.find(
(item) => item.key === ModuleInputKeyEnum.pluginId
)?.value;
if (!pluginId) return;
openConfirm(async () => {
try {

View File

@@ -1,11 +1,34 @@
import React, { useCallback } from 'react';
import React, { useCallback, useMemo } from 'react';
import type { RenderInputProps } from '../type';
import { onChangeNode } from '../../../../FlowProvider';
import { onChangeNode, useFlowProviderStore } from '../../../../FlowProvider';
import { useTranslation } from 'next-i18next';
import JSONEditor from '@fastgpt/web/components/common/Textarea/JsonEditor';
import {
formatEditorVariablePickerIcon,
getGuideModule,
splitGuideModule
} from '@fastgpt/global/core/module/utils';
const JsonEditor = ({ item, moduleId }: RenderInputProps) => {
const JsonEditor = ({ inputs = [], item, moduleId }: RenderInputProps) => {
const { t } = useTranslation();
const { nodes } = useFlowProviderStore();
// get variable
const variables = useMemo(() => {
const globalVariables = formatEditorVariablePickerIcon(
splitGuideModule(getGuideModule(nodes.map((node) => node.data)))?.variableModules || []
);
const moduleVariables = formatEditorVariablePickerIcon(
inputs
.filter((input) => input.edit)
.map((item) => ({
key: item.key,
label: item.label
}))
);
return [...globalVariables, ...moduleVariables];
}, [inputs, nodes]);
const update = useCallback(
(value: string) => {
@@ -28,10 +51,11 @@ const JsonEditor = ({ item, moduleId }: RenderInputProps) => {
bg={'myWhite.400'}
placeholder={t(item.placeholder || '')}
resize
defaultValue={item.value}
value={item.value}
onChange={(e) => {
update(e);
}}
variables={variables}
/>
);
};

View File

@@ -7,19 +7,24 @@ import { DatasetSearchModeEnum } from '@fastgpt/global/core/dataset/constants';
import { FlowNodeTypeEnum } from '@fastgpt/global/core/module/node/constant';
import { ModuleInputKeyEnum } from '@fastgpt/global/core/module/constants';
import MyIcon from '@fastgpt/web/components/common/Icon';
import DatasetParamsModal from '@/components/core/module/DatasetParamsModal';
import DatasetParamsModal, {
DatasetParamsProps
} from '@/components/core/module/DatasetParamsModal';
import { useSystemStore } from '@/web/common/system/useSystemStore';
const SelectDatasetParam = ({ inputs = [], moduleId }: RenderInputProps) => {
const { nodes } = useFlowProviderStore();
const { t } = useTranslation();
const { llmModelList } = useSystemStore();
const [data, setData] = useState({
const [data, setData] = useState<DatasetParamsProps>({
searchMode: DatasetSearchModeEnum.embedding,
limit: 5,
similarity: 0.5,
usingReRank: false
usingReRank: false,
datasetSearchUsingExtensionQuery: true,
datasetSearchExtensionModel: llmModelList[0]?.model,
datasetSearchExtensionBg: ''
});
const tokenLimit = useMemo(() => {
@@ -69,6 +74,7 @@ const SelectDatasetParam = ({ inputs = [], moduleId }: RenderInputProps) => {
maxTokens={tokenLimit}
onClose={onClose}
onSuccess={(e) => {
setData(e);
for (let key in e) {
const item = inputs.find((input) => input.key === key);
if (!item) continue;

View File

@@ -25,7 +25,7 @@ const nodeTypes: Record<`${FlowNodeTypeEnum}`, any> = {
[FlowNodeTypeEnum.answerNode]: dynamic(() => import('./components/nodes/NodeAnswer')),
[FlowNodeTypeEnum.classifyQuestion]: dynamic(() => import('./components/nodes/NodeCQNode')),
[FlowNodeTypeEnum.contentExtract]: dynamic(() => import('./components/nodes/NodeExtract')),
[FlowNodeTypeEnum.httpRequest]: NodeSimple,
[FlowNodeTypeEnum.httpRequest]: dynamic(() => import('./components/nodes/NodeHttp')),
[FlowNodeTypeEnum.runApp]: NodeSimple,
[FlowNodeTypeEnum.pluginInput]: dynamic(() => import('./components/nodes/NodePluginInput')),
[FlowNodeTypeEnum.pluginOutput]: dynamic(() => import('./components/nodes/NodePluginOutput')),