feat: add form input node (#2773)

* add node

* dispatch

* extract InputTypeConfig component

* question tip

* fix build

* fix

* fix
This commit is contained in:
heheer
2024-09-26 13:48:03 +08:00
committed by GitHub
parent edebfdf5ef
commit 1cf76ee7df
34 changed files with 1326 additions and 419 deletions

View File

@@ -64,11 +64,12 @@ import { dispatchUserSelect } from './interactive/userSelect';
import {
InteractiveNodeResponseItemType,
UserSelectInteractive
} from '@fastgpt/global/core/workflow/template/system/userSelect/type';
} from '@fastgpt/global/core/workflow/template/system/interactive/type';
import { dispatchRunAppNode } from './plugin/runApp';
import { dispatchLoop } from './loop/runLoop';
import { dispatchLoopEnd } from './loop/runLoopEnd';
import { dispatchLoopStart } from './loop/runLoopStart';
import { dispatchFormInput } from './interactive/formInput';
const callbackMap: Record<FlowNodeTypeEnum, Function> = {
[FlowNodeTypeEnum.workflowStart]: dispatchWorkflowStart,
@@ -97,6 +98,7 @@ const callbackMap: Record<FlowNodeTypeEnum, Function> = {
[FlowNodeTypeEnum.loop]: dispatchLoop,
[FlowNodeTypeEnum.loopStart]: dispatchLoopStart,
[FlowNodeTypeEnum.loopEnd]: dispatchLoopEnd,
[FlowNodeTypeEnum.formInput]: dispatchFormInput,
// none
[FlowNodeTypeEnum.systemConfig]: dispatchSystemConfig,
@@ -584,7 +586,10 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
// reset entry
runtimeNodes.forEach((item) => {
// Interactive node is not the entry node, return interactive result
if (item.flowNodeType !== FlowNodeTypeEnum.userSelect) {
if (
item.flowNodeType !== FlowNodeTypeEnum.userSelect &&
item.flowNodeType !== FlowNodeTypeEnum.formInput
) {
item.isEntry = false;
}
});

View File

@@ -0,0 +1,63 @@
import { chatValue2RuntimePrompt } from '@fastgpt/global/core/chat/adapt';
import { NodeInputKeyEnum, NodeOutputKeyEnum } from '@fastgpt/global/core/workflow/constants';
import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants';
import {
DispatchNodeResultType,
ModuleDispatchProps
} from '@fastgpt/global/core/workflow/runtime/type';
import {
UserInputFormItemType,
UserInputInteractive
} from '@fastgpt/global/core/workflow/template/system/interactive/type';
type Props = ModuleDispatchProps<{
[NodeInputKeyEnum.description]: string;
[NodeInputKeyEnum.userInputForms]: UserInputFormItemType[];
}>;
type FormInputResponse = DispatchNodeResultType<{
[DispatchNodeResponseKeyEnum.interactive]?: UserInputInteractive;
[NodeOutputKeyEnum.formInputResult]?: Record<string, any>;
}>;
export const dispatchFormInput = async (props: Props): Promise<FormInputResponse> => {
const {
histories,
node,
params: { description, userInputForms },
query
} = props;
const { isEntry } = node;
// Interactive node is not the entry node, return interactive result
if (!isEntry) {
return {
[DispatchNodeResponseKeyEnum.interactive]: {
type: 'userInput',
params: {
description,
inputForm: userInputForms
}
}
};
}
node.isEntry = false;
const { text } = chatValue2RuntimePrompt(query);
const userInputVal = (() => {
try {
return JSON.parse(text);
} catch (error) {
return text;
}
})();
return {
[DispatchNodeResponseKeyEnum.rewriteHistories]: histories.slice(0, -2), // Removes the current session record as the history of subsequent nodes
...userInputVal,
[NodeOutputKeyEnum.formInputResult]: userInputVal,
[DispatchNodeResponseKeyEnum.nodeResponse]: {
formInputResult: userInputVal
}
};
};

View File

@@ -8,7 +8,7 @@ import { getHandleId } from '@fastgpt/global/core/workflow/utils';
import type {
UserSelectInteractive,
UserSelectOptionItemType
} from '@fastgpt/global/core/workflow/template/system/userSelect/type';
} from '@fastgpt/global/core/workflow/template/system/interactive/type';
import { chatValue2RuntimePrompt } from '@fastgpt/global/core/chat/adapt';
type Props = ModuleDispatchProps<{