Concat textinput to input type (#2963)

* perf: toast position

* concat textinput to input
This commit is contained in:
Archer
2024-10-22 12:04:16 +08:00
committed by GitHub
parent 3f34c33d4c
commit 618729a254
17 changed files with 47 additions and 94 deletions

View File

@@ -9,13 +9,16 @@ weight: 812
## 更新说明 ## 更新说明
1. 新增 - 全局变量支持数字类型,并且支持配置默认值和部分输入框参数。 1. 新增 - 全局变量支持数字类型,支持配置默认值和部分输入框参数。
2. 新增 - FE_DOMAIN 环境变量,配置该环境变量后,上传文件/图片会补全后缀后得到完整地址。(可解决 docx 文件图片链接,有时会无法被模型识别问题) 2. 新增 - 插件自定义输入,文本输入框、数字输入框、选择框、开关,默认都支持作为变量引用。
3. 新增 - 工具调用支持交互模式 3. 新增 - FE_DOMAIN 环境变量,配置该环境变量后,上传文件/图片会补全后缀后得到完整地址。(可解决 docx 文件图片链接,有时会无法被模型识别问题)
4. 新增 - Debug 模式支持输入全局变量 4. 新增 - 工具调用支持交互模式
5. 新增 - chat openapi 文档 5. 新增 - Debug 模式支持输入全局变量
6. 新增 - wiki 搜索插件 6. 新增 - chat OpenAPI 文档
7. 新增 - Cookie 隐私协议提示 7. 新增 - wiki 搜索插件
8. 修复 - 文件后缀判断,去除 query 影响。 8. 新增 - Google 搜索插件
9. 修复 - AI 响应为空时,会造成 LLM 历史记录合并。 9. 新增 - 数据库连接和操作插件
10. 修复 - 用户交互节点未阻塞流程。 10. 新增 - Cookie 隐私协议提示
11. 修复 - 文件后缀判断,去除 query 影响。
12. 修复 - AI 响应为空时,会造成 LLM 历史记录合并。
13. 修复 - 用户交互节点未阻塞流程。

View File

@@ -267,7 +267,6 @@ export enum NodeOutputKeyEnum {
export enum VariableInputEnum { export enum VariableInputEnum {
input = 'input', input = 'input',
textarea = 'textarea', textarea = 'textarea',
textInput = 'textInput',
numberInput = 'numberInput', numberInput = 'numberInput',
select = 'select', select = 'select',
custom = 'custom' custom = 'custom'
@@ -284,7 +283,7 @@ export const variableMap: Record<
> = { > = {
[VariableInputEnum.input]: { [VariableInputEnum.input]: {
icon: 'core/workflow/inputType/input', icon: 'core/workflow/inputType/input',
label: i18nT('common:core.workflow.inputType.input'), label: i18nT('common:core.workflow.inputType.textInput'),
value: VariableInputEnum.input, value: VariableInputEnum.input,
defaultValueType: WorkflowIOValueTypeEnum.string defaultValueType: WorkflowIOValueTypeEnum.string
}, },
@@ -295,12 +294,6 @@ export const variableMap: Record<
defaultValueType: WorkflowIOValueTypeEnum.string, defaultValueType: WorkflowIOValueTypeEnum.string,
description: i18nT('app:variable.textarea_type_desc') description: i18nT('app:variable.textarea_type_desc')
}, },
[VariableInputEnum.textInput]: {
icon: 'core/workflow/inputType/input',
label: i18nT('common:core.workflow.inputType.textInput'),
value: VariableInputEnum.textInput,
defaultValueType: WorkflowIOValueTypeEnum.string
},
[VariableInputEnum.numberInput]: { [VariableInputEnum.numberInput]: {
icon: 'core/workflow/inputType/numberInput', icon: 'core/workflow/inputType/numberInput',
label: i18nT('common:core.workflow.inputType.number input'), label: i18nT('common:core.workflow.inputType.number input'),

View File

@@ -1,8 +1,9 @@
import { WorkflowIOValueTypeEnum } from '../constants'; import { WorkflowIOValueTypeEnum } from '../constants';
import { i18nT } from '../../../../web/i18n/utils'; import { i18nT } from '../../../../web/i18n/utils';
export enum FlowNodeInputTypeEnum { // render ui export enum FlowNodeInputTypeEnum { // render ui
textInput = 'textInput',
reference = 'reference', // reference to other node output reference = 'reference', // reference to other node output
input = 'input', // one line input
textarea = 'textarea',
numberInput = 'numberInput', numberInput = 'numberInput',
switch = 'switch', // true/false switch = 'switch', // true/false
select = 'select', select = 'select',
@@ -26,11 +27,7 @@ export enum FlowNodeInputTypeEnum { // render ui
settingDatasetQuotePrompt = 'settingDatasetQuotePrompt', settingDatasetQuotePrompt = 'settingDatasetQuotePrompt',
hidden = 'hidden', hidden = 'hidden',
custom = 'custom', custom = 'custom'
// deprecated
input = 'input', // one line input
textarea = 'textarea'
} }
export const FlowNodeInputMap: Record< export const FlowNodeInputMap: Record<
FlowNodeInputTypeEnum, FlowNodeInputTypeEnum,
@@ -38,9 +35,6 @@ export const FlowNodeInputMap: Record<
icon: string; icon: string;
} }
> = { > = {
[FlowNodeInputTypeEnum.textInput]: {
icon: 'core/workflow/inputType/input'
},
[FlowNodeInputTypeEnum.reference]: { [FlowNodeInputTypeEnum.reference]: {
icon: 'core/workflow/inputType/reference' icon: 'core/workflow/inputType/reference'
}, },

View File

@@ -230,10 +230,6 @@ export const appData2FlowNodeIO = ({
FlowNodeInputTypeEnum.textarea, FlowNodeInputTypeEnum.textarea,
FlowNodeInputTypeEnum.reference FlowNodeInputTypeEnum.reference
], ],
[VariableInputEnum.textInput]: [
FlowNodeInputTypeEnum.textInput,
FlowNodeInputTypeEnum.reference
],
[VariableInputEnum.numberInput]: [FlowNodeInputTypeEnum.numberInput], [VariableInputEnum.numberInput]: [FlowNodeInputTypeEnum.numberInput],
[VariableInputEnum.select]: [FlowNodeInputTypeEnum.select], [VariableInputEnum.select]: [FlowNodeInputTypeEnum.select],
[VariableInputEnum.custom]: [ [VariableInputEnum.custom]: [

View File

@@ -60,11 +60,10 @@ const main = async ({
// 使用类型断言来处理错误 // 使用类型断言来处理错误
if (error instanceof Error) { if (error instanceof Error) {
console.error('Database query error:', error.message); console.error('Database query error:', error.message);
throw new Error(error.message); return Promise.reject(error.message);
} else {
console.error('Database query error:', error);
throw new Error('An unknown error occurred');
} }
console.error('Database query error:', error);
return Promise.reject('An unknown error occurred');
} }
}; };

View File

@@ -152,8 +152,8 @@ export const dispatchRunTools = async (props: DispatchToolModuleProps): Promise<
} = await (async () => { } = await (async () => {
const adaptMessages = chats2GPTMessages({ const adaptMessages = chats2GPTMessages({
messages, messages,
reserveId: false, reserveId: false
reserveTool: !!toolModel.toolChoice // reserveTool: !!toolModel.toolChoice
}); });
if (toolModel.toolChoice) { if (toolModel.toolChoice) {

View File

@@ -36,11 +36,6 @@ const NodeInputSelect = ({
icon: FlowNodeInputMap[FlowNodeInputTypeEnum.input].icon, icon: FlowNodeInputMap[FlowNodeInputTypeEnum.input].icon,
title: t('common:core.workflow.inputType.Manual input') title: t('common:core.workflow.inputType.Manual input')
}, },
{
type: FlowNodeInputTypeEnum.textInput,
icon: FlowNodeInputMap[FlowNodeInputTypeEnum.input].icon,
title: t('common:core.workflow.inputType.Manual input')
},
{ {
type: FlowNodeInputTypeEnum.numberInput, type: FlowNodeInputTypeEnum.numberInput,
icon: FlowNodeInputMap[FlowNodeInputTypeEnum.numberInput].icon, icon: FlowNodeInputMap[FlowNodeInputTypeEnum.numberInput].icon,

View File

@@ -36,7 +36,7 @@ export const defaultVariable: VariableItemType = {
id: nanoid(), id: nanoid(),
key: '', key: '',
label: '', label: '',
type: VariableInputEnum.textInput, type: VariableInputEnum.input,
description: '', description: '',
required: true, required: true,
valueType: WorkflowIOValueTypeEnum.string valueType: WorkflowIOValueTypeEnum.string
@@ -73,10 +73,7 @@ const VariableEdit = ({
const inputTypeList = useMemo( const inputTypeList = useMemo(
() => () =>
Object.values(variableMap) Object.values(variableMap)
.filter( .filter((item) => item.value !== VariableInputEnum.textarea)
(item) =>
item.value !== VariableInputEnum.input && item.value !== VariableInputEnum.textarea
)
.map((item) => ({ .map((item) => ({
icon: item.icon, icon: item.icon,
label: t(item.label as any), label: t(item.label as any),

View File

@@ -60,12 +60,13 @@ export const VariableInputItem = ({
{item.description && <QuestionTip ml={1} label={item.description} />} {item.description && <QuestionTip ml={1} label={item.description} />}
</Box> </Box>
{item.type === VariableInputEnum.input && ( {item.type === VariableInputEnum.input && (
<Input <PromptEditor
maxLength={item.maxLength || 4000} value={item.defaultValue}
onChange={(e) => setValue(item.key, e)}
bg={'myGray.50'} bg={'myGray.50'}
{...register(item.key, { minH={40}
required: item.required maxH={150}
})} showOpenModal={false}
/> />
)} )}
{item.type === VariableInputEnum.textarea && ( {item.type === VariableInputEnum.textarea && (
@@ -78,16 +79,7 @@ export const VariableInputItem = ({
maxLength={item.maxLength || 4000} maxLength={item.maxLength || 4000}
/> />
)} )}
{item.type === VariableInputEnum.textInput && (
<PromptEditor
value={item.defaultValue}
onChange={(e) => setValue(item.key, e)}
bg={'myGray.50'}
minH={50}
maxH={150}
showOpenModal={false}
/>
)}
{item.type === VariableInputEnum.select && ( {item.type === VariableInputEnum.select && (
<Controller <Controller
key={item.key} key={item.key}

View File

@@ -221,13 +221,12 @@ const RenderUserFormInteractive = React.memo(function RenderFormInput({
{input.description && <QuestionTip ml={1} label={input.description} />} {input.description && <QuestionTip ml={1} label={input.description} />}
</Flex> </Flex>
{input.type === FlowNodeInputTypeEnum.input && ( {input.type === FlowNodeInputTypeEnum.input && (
<Input <PromptEditor
bg={'white'} value={input.value}
maxLength={input.maxLength} onChange={(e) => setValue(input.label, e)}
isDisabled={interactive.params.submitted} minH={40}
{...register(input.label, { maxH={100}
required: input.required showOpenModal={false}
})}
/> />
)} )}
{input.type === FlowNodeInputTypeEnum.textarea && ( {input.type === FlowNodeInputTypeEnum.textarea && (
@@ -241,15 +240,6 @@ const RenderUserFormInteractive = React.memo(function RenderFormInput({
maxLength={input.maxLength || 4000} maxLength={input.maxLength || 4000}
/> />
)} )}
{input.type === FlowNodeInputTypeEnum.textInput && (
<PromptEditor
value={input.value}
onChange={(e) => setValue(input.label, e)}
minH={40}
maxH={100}
showOpenModal={false}
/>
)}
{input.type === FlowNodeInputTypeEnum.numberInput && ( {input.type === FlowNodeInputTypeEnum.numberInput && (
<NumberInput <NumberInput
step={1} step={1}

View File

@@ -27,7 +27,7 @@ const SaveButton = ({
const [isSave, setIsSave] = useState(false); const [isSave, setIsSave] = useState(false);
const { toast } = useToast({ const { toast } = useToast({
containerStyle: { containerStyle: {
mt: 20, mt: '60px',
fontSize: 'sm' fontSize: 'sm'
} }
}); });

View File

@@ -22,7 +22,7 @@ const SaveAndPublishModal = ({
const { t } = useTranslation(); const { t } = useTranslation();
const { toast } = useToast({ const { toast } = useToast({
containerStyle: { containerStyle: {
mt: 20, mt: '60px',
fontSize: 'sm' fontSize: 'sm'
} }
}); });

View File

@@ -11,7 +11,7 @@ import { useToast } from '@fastgpt/web/hooks/useToast';
import InputTypeConfig from '../NodePluginIO/InputTypeConfig'; import InputTypeConfig from '../NodePluginIO/InputTypeConfig';
export const defaultFormInput: UserInputFormItemType = { export const defaultFormInput: UserInputFormItemType = {
type: FlowNodeInputTypeEnum.textInput, type: FlowNodeInputTypeEnum.input,
key: '', key: '',
label: '', label: '',
description: '', description: '',
@@ -55,7 +55,7 @@ const InputFormEditModal = ({
{ {
icon: 'core/workflow/inputType/input', icon: 'core/workflow/inputType/input',
label: t('common:core.workflow.inputType.textInput'), label: t('common:core.workflow.inputType.textInput'),
value: FlowNodeInputTypeEnum.textInput, value: FlowNodeInputTypeEnum.input,
defaultValueType: WorkflowIOValueTypeEnum.string defaultValueType: WorkflowIOValueTypeEnum.string
}, },
{ {

View File

@@ -55,7 +55,7 @@ const FieldEditModal = ({
{ {
icon: 'core/workflow/inputType/input', icon: 'core/workflow/inputType/input',
label: t('common:core.workflow.inputType.textInput'), label: t('common:core.workflow.inputType.textInput'),
value: FlowNodeInputTypeEnum.textInput, value: FlowNodeInputTypeEnum.input,
defaultValueType: WorkflowIOValueTypeEnum.string defaultValueType: WorkflowIOValueTypeEnum.string
}, },
{ {

View File

@@ -137,7 +137,7 @@ const InputTypeConfig = ({
}, [inputType]); }, [inputType]);
const showMaxLenInput = useMemo(() => { const showMaxLenInput = useMemo(() => {
const list = [FlowNodeInputTypeEnum.textInput]; const list = [FlowNodeInputTypeEnum.input];
return list.includes(inputType as FlowNodeInputTypeEnum); return list.includes(inputType as FlowNodeInputTypeEnum);
}, [inputType]); }, [inputType]);
@@ -148,7 +148,7 @@ const InputTypeConfig = ({
const showDefaultValue = useMemo(() => { const showDefaultValue = useMemo(() => {
const list = [ const list = [
FlowNodeInputTypeEnum.textInput, FlowNodeInputTypeEnum.input,
FlowNodeInputTypeEnum.JSONEditor, FlowNodeInputTypeEnum.JSONEditor,
FlowNodeInputTypeEnum.numberInput, FlowNodeInputTypeEnum.numberInput,
FlowNodeInputTypeEnum.switch, FlowNodeInputTypeEnum.switch,
@@ -323,7 +323,7 @@ const InputTypeConfig = ({
</NumberInputStepper> </NumberInputStepper>
</NumberInput> </NumberInput>
)} )}
{inputType === FlowNodeInputTypeEnum.textInput && ( {inputType === FlowNodeInputTypeEnum.input && (
<PromptEditor <PromptEditor
value={defaultValue} value={defaultValue}
onChange={(e) => { onChange={(e) => {

View File

@@ -28,10 +28,6 @@ const RenderList: {
types: [FlowNodeInputTypeEnum.switch], types: [FlowNodeInputTypeEnum.switch],
Component: dynamic(() => import('./templates/Switch')) Component: dynamic(() => import('./templates/Switch'))
}, },
{
types: [FlowNodeInputTypeEnum.textInput],
Component: dynamic(() => import('./templates/TextInput'))
},
{ {
types: [FlowNodeInputTypeEnum.selectApp], types: [FlowNodeInputTypeEnum.selectApp],
Component: dynamic(() => import('./templates/SelectApp')) Component: dynamic(() => import('./templates/SelectApp'))

View File

@@ -10,9 +10,7 @@ import { getEditorVariables } from '../../../../../utils';
const TextInputRender = ({ inputs = [], item, nodeId }: RenderInputProps) => { const TextInputRender = ({ inputs = [], item, nodeId }: RenderInputProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
const nodeList = useContextSelector(WorkflowContext, (v) => v.nodeList); const { nodeList, edges, onChangeNode } = useContextSelector(WorkflowContext, (v) => v);
const edges = useContextSelector(WorkflowContext, (v) => v.edges);
const onChangeNode = useContextSelector(WorkflowContext, (v) => v.onChangeNode);
const { appDetail } = useContextSelector(AppContext, (v) => v); const { appDetail } = useContextSelector(AppContext, (v) => v);
@@ -51,7 +49,7 @@ const TextInputRender = ({ inputs = [], item, nodeId }: RenderInputProps) => {
maxLength={item.maxLength} maxLength={item.maxLength}
minH={40} minH={40}
maxH={120} maxH={120}
placeholder={t((item.placeholder as any) || '')} placeholder={t(item.placeholder as any)}
value={item.value} value={item.value}
onChange={onChange} onChange={onChange}
isFlow={true} isFlow={true}