Skip to content

Commit

Permalink
App run node update (#2542)
Browse files Browse the repository at this point in the history
* feat(workflow): allow apps to be invoked like plugins (#2521)

* feat(workflow): allow apps to be invoked like plugins

* fix type

* Encapsulate SSE response methods (#2530)

* perf: sse response fn

* perf: sse response

* fix: ts

* perf: not ssl copy

* perf: myselect auto scroll

* perf: run app code

* fix: app plugin (#2538)

---------

Co-authored-by: heheer <[email protected]>
  • Loading branch information
c121914yu and newfish-cmyk authored Aug 27, 2024
1 parent 67445b4 commit 450167c
Show file tree
Hide file tree
Showing 67 changed files with 704 additions and 4,897 deletions.
4 changes: 3 additions & 1 deletion docSite/content/zh-cn/docs/development/upgrading/4811.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@ weight: 813
1.
2. 新增 - 插件自定义输入支持单选框
3. 新增 - 插件输出,支持指定某些字段为工具调用结果
4. 新增 - 插件支持配置使用引导、全局变量和文件输入
4. 新增 - 插件支持配置使用引导、全局变量和文件输入
5. 优化 - SSE 响应代码。
6. 优化 - 非 HTTPS 环境下支持复制(除非 textarea 复制也不支持)
1 change: 1 addition & 0 deletions packages/global/core/workflow/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ export enum NodeInputKeyEnum {

// read files
fileUrlList = 'fileUrlList',

// user select
userSelectOptions = 'userSelectOptions'
}
Expand Down
1 change: 1 addition & 0 deletions packages/global/core/workflow/node/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ export enum FlowNodeTypeEnum {
contentExtract = 'contentExtract',
httpRequest468 = 'httpRequest468',
runApp = 'app',
appModule = 'appModule',
pluginModule = 'pluginModule',
pluginInput = 'pluginInput',
pluginOutput = 'pluginOutput',
Expand Down
3 changes: 2 additions & 1 deletion packages/global/core/workflow/runtime/type.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { RuntimeNodeItemType } from '../runtime/type';
import { RuntimeEdgeItemType } from './edge';
import { ReadFileNodeResponse } from '../template/system/readFiles/type';
import { UserSelectOptionType } from '../template/system/userSelect/type';
import { WorkflowResponseType } from '../../../../service/core/workflow/dispatch/type';

/* workflow props */
export type ChatDispatchProps = {
Expand All @@ -36,9 +37,9 @@ export type ChatDispatchProps = {
query: UserChatItemValueItemType[]; // trigger query
chatConfig: AppSchema['chatConfig'];
stream: boolean;
detail: boolean; // response detail
maxRunTimes: number;
isToolCall?: boolean;
workflowStreamResponse?: WorkflowResponseType;
};

export type ModuleDispatchProps<T> = ChatDispatchProps & {
Expand Down
4 changes: 2 additions & 2 deletions packages/global/core/workflow/runtime/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ export const textAdaptGptResponse = ({
finish_reason?: null | 'stop';
extraData?: Object;
}) => {
return JSON.stringify({
return {
...extraData,
id: '',
object: '',
Expand All @@ -252,7 +252,7 @@ export const textAdaptGptResponse = ({
finish_reason
}
]
});
};
};

/* Update runtimeNode's outputs with interactive data from history */
Expand Down
8 changes: 5 additions & 3 deletions packages/global/core/workflow/template/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { RunAppModule } from './system/runApp/index';
import { PluginInputModule } from './system/pluginInput';
import { PluginOutputModule } from './system/pluginOutput';
import { RunPluginModule } from './system/runPlugin';
import { RunAppPluginModule } from './system/runAppPlugin';
import { AiQueryExtension } from './system/queryExtension';

import type { FlowNodeTemplateType } from '../type/node';
Expand Down Expand Up @@ -44,8 +45,8 @@ const systemNodes: FlowNodeTemplateType[] = [
LafModule,
IfElseNode,
VariableUpdateNode,
CodeNode,
RunAppModule
CodeNode
// RunAppModule
];
/* app flow module templates */
export const appSystemModuleTemplates: FlowNodeTemplateType[] = [
Expand All @@ -70,5 +71,6 @@ export const moduleTemplatesFlat: FlowNodeTemplateType[] = [
)
),
EmptyNode,
RunPluginModule
RunPluginModule,
RunAppPluginModule
];
9 changes: 9 additions & 0 deletions packages/global/core/workflow/template/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,12 @@ export const Input_Template_Text_Quote: FlowNodeInputItemType = {
description: i18nT('app:document_quote_tip'),
valueType: WorkflowIOValueTypeEnum.string
};
export const Input_Template_File_Link: FlowNodeInputItemType = {
key: NodeInputKeyEnum.fileUrlList,
renderTypeList: [FlowNodeInputTypeEnum.reference],
required: true,
label: i18nT('app:workflow.user_file_input'),
debugLabel: i18nT('app:workflow.user_file_input'),
description: i18nT('app:workflow.user_file_input_desc'),
valueType: WorkflowIOValueTypeEnum.arrayString
};
19 changes: 19 additions & 0 deletions packages/global/core/workflow/template/system/runAppPlugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { FlowNodeTemplateTypeEnum } from '../../constants';
import { FlowNodeTypeEnum } from '../../node/constant';
import { FlowNodeTemplateType } from '../../type/node';
import { getHandleConfig } from '../utils';

export const RunAppPluginModule: FlowNodeTemplateType = {
id: FlowNodeTypeEnum.appModule,
templateType: FlowNodeTemplateTypeEnum.other,
flowNodeType: FlowNodeTypeEnum.appModule,
sourceHandle: getHandleConfig(true, true, true, true),
targetHandle: getHandleConfig(true, true, true, true),
intro: '',
name: '',
showStatus: false,
isTool: false,
version: '481',
inputs: [], // [{key:'pluginId'},...]
outputs: []
};
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,3 @@ type UserSelectInteractive = {
};

export type InteractiveNodeResponseItemType = InteractiveBasicType & UserSelectInteractive;

export type UserInteractiveType = UserSelectInteractive;
93 changes: 88 additions & 5 deletions packages/global/core/workflow/utils.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import { FlowNodeInputTypeEnum, FlowNodeOutputTypeEnum, FlowNodeTypeEnum } from './node/constant';
import {
chatHistoryValueDesc,
FlowNodeInputTypeEnum,
FlowNodeOutputTypeEnum,
FlowNodeTypeEnum
} from './node/constant';
import {
WorkflowIOValueTypeEnum,
NodeInputKeyEnum,
VariableInputEnum,
variableMap,
VARIABLE_NODE_ID
VARIABLE_NODE_ID,
NodeOutputKeyEnum
} from './constants';
import { FlowNodeInputItemType, FlowNodeOutputItemType, ReferenceValueProps } from './type/io.d';
import { StoreNodeItemType } from './type/node';
Expand All @@ -25,6 +31,7 @@ import {
import { IfElseResultEnum } from './template/system/ifElse/constant';
import { RuntimeNodeItemType } from './runtime/type';
import { getReferenceVariableValue } from './runtime/utils';
import { Input_Template_History, Input_Template_UserChatInput } from './template/input';

export const getHandleId = (nodeId: string, type: 'source' | 'target', key: string) => {
return `${nodeId}-${type}-${key}`;
Expand Down Expand Up @@ -147,9 +154,11 @@ export const getModuleInputUiField = (input: FlowNodeInputItemType) => {
return {};
};

export const pluginData2FlowNodeIO = (
nodes: StoreNodeItemType[]
): {
export const pluginData2FlowNodeIO = ({
nodes
}: {
nodes: StoreNodeItemType[];
}): {
inputs: FlowNodeInputItemType[];
outputs: FlowNodeOutputItemType[];
} => {
Expand Down Expand Up @@ -180,6 +189,80 @@ export const pluginData2FlowNodeIO = (
};
};

export const appData2FlowNodeIO = ({
chatConfig
}: {
chatConfig?: AppChatConfigType;
}): {
inputs: FlowNodeInputItemType[];
outputs: FlowNodeOutputItemType[];
} => {
const variableInput = !chatConfig?.variables
? []
: chatConfig.variables.map((item) => {
const renderTypeMap = {
[VariableInputEnum.input]: [FlowNodeInputTypeEnum.input, FlowNodeInputTypeEnum.reference],
[VariableInputEnum.textarea]: [
FlowNodeInputTypeEnum.textarea,
FlowNodeInputTypeEnum.reference
],
[VariableInputEnum.select]: [FlowNodeInputTypeEnum.select],
[VariableInputEnum.custom]: [
FlowNodeInputTypeEnum.input,
FlowNodeInputTypeEnum.reference
],
default: [FlowNodeInputTypeEnum.reference]
};

return {
key: item.key,
renderTypeList: renderTypeMap[item.type] || renderTypeMap.default,
label: item.label,
debugLabel: item.label,
description: '',
valueType: WorkflowIOValueTypeEnum.any,
required: item.required,
list: item.enums.map((enumItem) => ({
label: enumItem.value,
value: enumItem.value
}))
};
});

// const showFileLink =
// chatConfig?.fileSelectConfig?.canSelectFile || chatConfig?.fileSelectConfig?.canSelectImg;

return {
inputs: [
Input_Template_History,
Input_Template_UserChatInput,
// ...(showFileLink ? [Input_Template_File_Link] : []),
...variableInput
],
outputs: [
{
id: NodeOutputKeyEnum.history,
key: NodeOutputKeyEnum.history,
required: true,
label: 'core.module.output.label.New context',
description: 'core.module.output.description.New context',
valueType: WorkflowIOValueTypeEnum.chatHistory,
valueDesc: chatHistoryValueDesc,
type: FlowNodeOutputTypeEnum.static
},
{
id: NodeOutputKeyEnum.answerText,
key: NodeOutputKeyEnum.answerText,
required: false,
label: 'core.module.output.label.Ai response content',
description: 'core.module.output.description.Ai response content',
valueType: WorkflowIOValueTypeEnum.string,
type: FlowNodeOutputTypeEnum.static
}
]
};
};

export const formatEditorVariablePickerIcon = (
variables: { key: string; label: string; type?: `${VariableInputEnum}`; required?: boolean }[]
): EditorVariablePickerType[] => {
Expand Down
17 changes: 11 additions & 6 deletions packages/service/core/app/plugin/controller.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { FlowNodeTemplateType } from '@fastgpt/global/core/workflow/type/node.d';
import { FlowNodeTypeEnum, defaultNodeVersion } from '@fastgpt/global/core/workflow/node/constant';
import { pluginData2FlowNodeIO } from '@fastgpt/global/core/workflow/utils';
import { appData2FlowNodeIO, pluginData2FlowNodeIO } from '@fastgpt/global/core/workflow/utils';
import { PluginSourceEnum } from '@fastgpt/global/core/plugin/constants';
import type { PluginRuntimeType } from '@fastgpt/global/core/workflow/runtime/type';
import { FlowNodeTemplateTypeEnum } from '@fastgpt/global/core/workflow/constants';
Expand Down Expand Up @@ -52,10 +52,10 @@ const getPluginTemplateById = async (
showStatus: true,
workflow: {
nodes: item.modules,
edges: item.edges
edges: item.edges,
chatConfig: item.chatConfig
},
templateType: FlowNodeTemplateTypeEnum.teamApp,
isTool: true,
version: item?.pluginData?.nodeVersion || defaultNodeVersion,
originCost: 0,
currentCost: 0
Expand All @@ -71,22 +71,27 @@ const getPluginTemplateById = async (
/* format plugin modules to plugin preview module */
export async function getPluginPreviewNode({ id }: { id: string }): Promise<FlowNodeTemplateType> {
const plugin = await getPluginTemplateById(id);
const isPlugin = !!plugin.workflow.nodes.find(
(node) => node.flowNodeType === FlowNodeTypeEnum.pluginInput
);

return {
id: getNanoid(),
pluginId: plugin.id,
templateType: plugin.templateType,
flowNodeType: FlowNodeTypeEnum.pluginModule,
flowNodeType: isPlugin ? FlowNodeTypeEnum.pluginModule : FlowNodeTypeEnum.appModule,
avatar: plugin.avatar,
name: plugin.name,
intro: plugin.intro,
inputExplanationUrl: plugin.inputExplanationUrl,
showStatus: plugin.showStatus,
isTool: plugin.isTool,
isTool: isPlugin,
version: plugin.version,
sourceHandle: getHandleConfig(true, true, true, true),
targetHandle: getHandleConfig(true, true, true, true),
...pluginData2FlowNodeIO(plugin.workflow.nodes)
...(isPlugin
? pluginData2FlowNodeIO({ nodes: plugin.workflow.nodes })
: appData2FlowNodeIO({ chatConfig: plugin.workflow.chatConfig }))
};
}

Expand Down
Loading

0 comments on commit 450167c

Please sign in to comment.