mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-23 13:03:50 +00:00
feat: add form input node (#2773)
* add node * dispatch * extract InputTypeConfig component * question tip * fix build * fix * fix
This commit is contained in:
3
packages/global/core/ai/type.d.ts
vendored
3
packages/global/core/ai/type.d.ts
vendored
@@ -9,8 +9,7 @@ import type {
|
||||
ChatCompletionUserMessageParam as SdkChatCompletionUserMessageParam
|
||||
} from 'openai/resources';
|
||||
import { ChatMessageTypeEnum } from './constants';
|
||||
import { InteractiveNodeResponseItemType } from '../workflow/template/system/userSelect/type';
|
||||
|
||||
import { InteractiveNodeResponseItemType } from '../workflow/template/system/interactive/type';
|
||||
export * from 'openai/resources';
|
||||
|
||||
// Extension of ChatCompletionMessageParam, Add file url type
|
||||
|
2
packages/global/core/chat/type.d.ts
vendored
2
packages/global/core/chat/type.d.ts
vendored
@@ -15,7 +15,7 @@ import type { AppSchema as AppType } from '@fastgpt/global/core/app/type.d';
|
||||
import { DatasetSearchModeEnum } from '../dataset/constants';
|
||||
import { DispatchNodeResponseType } from '../workflow/runtime/type.d';
|
||||
import { ChatBoxInputType } from '../../../../projects/app/src/components/core/chat/ChatContainer/ChatBox/type';
|
||||
import { InteractiveNodeResponseItemType } from '../workflow/template/system/userSelect/type';
|
||||
import { InteractiveNodeResponseItemType } from '../workflow/template/system/interactive/type';
|
||||
|
||||
export type ChatSchema = {
|
||||
_id: string;
|
||||
|
@@ -148,7 +148,10 @@ export enum NodeInputKeyEnum {
|
||||
// loop start
|
||||
loopStartInput = 'loopStartInput',
|
||||
// loop end
|
||||
loopEndInput = 'loopEndInput'
|
||||
loopEndInput = 'loopEndInput',
|
||||
|
||||
// form input
|
||||
userInputForms = 'userInputForms'
|
||||
}
|
||||
|
||||
export enum NodeOutputKeyEnum {
|
||||
@@ -197,7 +200,10 @@ export enum NodeOutputKeyEnum {
|
||||
loopArray = 'loopArray',
|
||||
|
||||
// loop start
|
||||
loopStartInput = 'loopStartInput'
|
||||
loopStartInput = 'loopStartInput',
|
||||
|
||||
// form input
|
||||
formInputResult = 'formInputResult'
|
||||
}
|
||||
|
||||
export enum VariableInputEnum {
|
||||
|
@@ -128,7 +128,8 @@ export enum FlowNodeTypeEnum {
|
||||
userSelect = 'userSelect',
|
||||
loop = 'loop',
|
||||
loopStart = 'loopStart',
|
||||
loopEnd = 'loopEnd'
|
||||
loopEnd = 'loopEnd',
|
||||
formInput = 'formInput'
|
||||
}
|
||||
|
||||
// node IO value type
|
||||
|
@@ -182,6 +182,9 @@ export type DispatchNodeResponseType = {
|
||||
loopInputValue?: any;
|
||||
// loop end
|
||||
loopOutputValue?: any;
|
||||
|
||||
// form input
|
||||
formInputResult?: string;
|
||||
};
|
||||
|
||||
export type DispatchNodeResultType<T = {}> = {
|
||||
|
@@ -54,6 +54,11 @@ export const getLastInteractiveValue = (histories: ChatItemType[]) => {
|
||||
) {
|
||||
return lastValue.interactive;
|
||||
}
|
||||
|
||||
// Check is user input
|
||||
if (lastValue.interactive.type === 'userInput' && !lastValue.interactive.params.submitted) {
|
||||
return lastValue.interactive;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@@ -28,10 +28,11 @@ import { CodeNode } from './system/sandbox';
|
||||
import { TextEditorNode } from './system/textEditor';
|
||||
import { CustomFeedbackNode } from './system/customFeedback';
|
||||
import { ReadFilesNode } from './system/readFiles';
|
||||
import { UserSelectNode } from './system/userSelect/index';
|
||||
import { UserSelectNode } from './system/interactive/userSelect';
|
||||
import { LoopNode } from './system/loop/loop';
|
||||
import { LoopStartNode } from './system/loop/loopStart';
|
||||
import { LoopEndNode } from './system/loop/loopEnd';
|
||||
import { FormInputNode } from './system/interactive/formInput';
|
||||
|
||||
const systemNodes: FlowNodeTemplateType[] = [
|
||||
AiChatModule,
|
||||
@@ -58,7 +59,8 @@ export const appSystemModuleTemplates: FlowNodeTemplateType[] = [
|
||||
WorkflowStart,
|
||||
...systemNodes,
|
||||
CustomFeedbackNode,
|
||||
UserSelectNode
|
||||
UserSelectNode,
|
||||
FormInputNode
|
||||
];
|
||||
/* plugin flow module templates */
|
||||
export const pluginSystemModuleTemplates: FlowNodeTemplateType[] = [
|
||||
|
@@ -0,0 +1,55 @@
|
||||
import { i18nT } from '../../../../../../web/i18n/utils';
|
||||
import {
|
||||
FlowNodeTemplateTypeEnum,
|
||||
NodeInputKeyEnum,
|
||||
NodeOutputKeyEnum,
|
||||
WorkflowIOValueTypeEnum
|
||||
} from '../../../constants';
|
||||
import {
|
||||
FlowNodeInputTypeEnum,
|
||||
FlowNodeOutputTypeEnum,
|
||||
FlowNodeTypeEnum
|
||||
} from '../../../node/constant';
|
||||
import { FlowNodeTemplateType } from '../../../type/node';
|
||||
import { getHandleConfig } from '../../utils';
|
||||
|
||||
export const FormInputNode: FlowNodeTemplateType = {
|
||||
id: FlowNodeTypeEnum.formInput,
|
||||
templateType: FlowNodeTemplateTypeEnum.interactive,
|
||||
flowNodeType: FlowNodeTypeEnum.formInput,
|
||||
sourceHandle: getHandleConfig(true, true, true, true),
|
||||
targetHandle: getHandleConfig(true, true, true, true),
|
||||
avatar: 'core/workflow/template/formInput',
|
||||
name: i18nT('app:workflow.form_input'),
|
||||
intro: i18nT(`app:workflow.form_input_tip`),
|
||||
showStatus: true,
|
||||
version: '4811',
|
||||
inputs: [
|
||||
{
|
||||
key: NodeInputKeyEnum.description,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.textarea],
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
label: i18nT('app:workflow.select_description'),
|
||||
description: i18nT('app:workflow.input_description_tip'),
|
||||
placeholder: i18nT('app:workflow.form_input_description_placeholder')
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.userInputForms,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.custom],
|
||||
valueType: WorkflowIOValueTypeEnum.any,
|
||||
label: '',
|
||||
value: []
|
||||
}
|
||||
],
|
||||
outputs: [
|
||||
{
|
||||
id: NodeOutputKeyEnum.formInputResult,
|
||||
key: NodeOutputKeyEnum.formInputResult,
|
||||
required: true,
|
||||
label: i18nT('app:workflow.form_input_result'),
|
||||
description: i18nT('app:workflow.form_input_result_tip'),
|
||||
valueType: WorkflowIOValueTypeEnum.object,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
}
|
||||
]
|
||||
};
|
56
packages/global/core/workflow/template/system/interactive/type.d.ts
vendored
Normal file
56
packages/global/core/workflow/template/system/interactive/type.d.ts
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
import { NodeOutputItemType } from '../../../../chat/type';
|
||||
import { FlowNodeOutputItemType } from '../../../type/io';
|
||||
import { RuntimeEdgeItemType } from '../../../runtime/type';
|
||||
import { FlowNodeInputTypeEnum } from 'core/workflow/node/constant';
|
||||
import { WorkflowIOValueTypeEnum } from 'core/workflow/constants';
|
||||
|
||||
export type UserSelectOptionItemType = {
|
||||
key: string;
|
||||
value: string;
|
||||
};
|
||||
|
||||
export type UserInputFormItemType = {
|
||||
type: FlowNodeInputTypeEnum;
|
||||
key: string;
|
||||
label: string;
|
||||
value: any;
|
||||
valueType: WorkflowIOValueTypeEnum;
|
||||
description?: string;
|
||||
defaultValue?: any;
|
||||
required: boolean;
|
||||
|
||||
// input & textarea
|
||||
maxLength?: number;
|
||||
// numberInput
|
||||
max?: number;
|
||||
min?: number;
|
||||
// select
|
||||
list?: { label: string; value: string }[];
|
||||
};
|
||||
|
||||
type InteractiveBasicType = {
|
||||
entryNodeIds: string[];
|
||||
memoryEdges: RuntimeEdgeItemType[];
|
||||
nodeOutputs: NodeOutputItemType[];
|
||||
};
|
||||
|
||||
type UserSelectInteractive = {
|
||||
type: 'userSelect';
|
||||
params: {
|
||||
description: string;
|
||||
userSelectOptions: UserSelectOptionItemType[];
|
||||
userSelectedVal?: string;
|
||||
};
|
||||
};
|
||||
|
||||
type UserInputInteractive = {
|
||||
type: 'userInput';
|
||||
params: {
|
||||
description: string;
|
||||
inputForm: UserInputFormItemType[];
|
||||
submitted?: boolean;
|
||||
};
|
||||
};
|
||||
|
||||
export type InteractiveNodeResponseItemType = InteractiveBasicType &
|
||||
(UserSelectInteractive | UserInputInteractive);
|
@@ -1,24 +0,0 @@
|
||||
import { NodeOutputItemType } from '../../../../chat/type';
|
||||
import { FlowNodeOutputItemType } from '../../../type/io';
|
||||
import { RuntimeEdgeItemType } from '../../../runtime/type';
|
||||
|
||||
export type UserSelectOptionItemType = {
|
||||
key: string;
|
||||
value: string;
|
||||
};
|
||||
|
||||
type InteractiveBasicType = {
|
||||
entryNodeIds: string[];
|
||||
memoryEdges: RuntimeEdgeItemType[];
|
||||
nodeOutputs: NodeOutputItemType[];
|
||||
};
|
||||
type UserSelectInteractive = {
|
||||
type: 'userSelect';
|
||||
params: {
|
||||
description: string;
|
||||
userSelectOptions: UserSelectOptionItemType[];
|
||||
userSelectedVal?: string;
|
||||
};
|
||||
};
|
||||
|
||||
export type InteractiveNodeResponseItemType = InteractiveBasicType & UserSelectInteractive;
|
Reference in New Issue
Block a user