feat: admin add custom plugin (#2582)

* feat: admin add custom plugin

* refresh plugins

* plugin input box ui

* fix: run plugin varialbes error

* perf: comment

* fix: ts
This commit is contained in:
Archer
2024-08-30 22:45:35 +08:00
committed by GitHub
parent 9d5fd24085
commit 060492dbf7
18 changed files with 127 additions and 84 deletions

View File

@@ -24,7 +24,8 @@ const SystemPluginSchema = new Schema({
currentCost: {
type: Number,
default: 0
}
},
customConfig: Object
});
SystemPluginSchema.index({ pluginId: 1 });

View File

@@ -1,4 +1,8 @@
import { SystemPluginTemplateItemType } from '@fastgpt/global/core/workflow/type';
import { FlowNodeTemplateTypeEnum } from '@fastgpt/global/core/workflow/constants';
import {
SystemPluginTemplateItemType,
WorkflowTemplateBasicType
} from '@fastgpt/global/core/workflow/type';
export type SystemPluginConfigSchemaType = {
pluginId: string;
@@ -7,4 +11,14 @@ export type SystemPluginConfigSchemaType = {
currentCost: number;
isActive: boolean;
inputConfig: SystemPluginTemplateItemType['inputConfig'];
customConfig?: {
name: string;
avatar: string;
intro?: string;
version: string;
weight?: number;
workflow: WorkflowTemplateBasicType;
templateType: FlowNodeTemplateTypeEnum;
};
};

View File

@@ -1,6 +1,7 @@
/* Abandoned */
import type { ChatItemType } from '@fastgpt/global/core/chat/type.d';
import type { ModuleDispatchProps } from '@fastgpt/global/core/workflow/runtime/type';
import { SelectAppItemType } from '@fastgpt/global/core/workflow/template/system/runApp/type';
import { SelectAppItemType } from '@fastgpt/global/core/workflow/template/system/abandoned/runApp/type';
import { dispatchWorkFlow } from '../index';
import { ChatRoleEnum } from '@fastgpt/global/core/chat/constants';
import { SseResponseEventEnum } from '@fastgpt/global/core/workflow/runtime/constants';

View File

@@ -11,7 +11,7 @@ import {
} from '@fastgpt/global/core/workflow/runtime/utils';
import { NodeInputKeyEnum, NodeOutputKeyEnum } from '@fastgpt/global/core/workflow/constants';
import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants';
import { getHistories } from '../utils';
import { filterSystemVariables, getHistories } from '../utils';
import { chatValue2RuntimePrompt, runtimePrompt2ChatsValue } from '@fastgpt/global/core/chat/adapt';
import { DispatchNodeResultType } from '@fastgpt/global/core/workflow/runtime/type';
import { authAppByTmbId } from '../../../../support/permission/app/auth';
@@ -34,10 +34,11 @@ export const dispatchRunAppNode = async (props: Props): Promise<Response> => {
query,
node: { pluginId },
workflowStreamResponse,
params
params,
variables
} = props;
const { userChatInput, history, ...variables } = params;
const { userChatInput, history, ...childrenAppVariables } = params;
if (!userChatInput) {
return Promise.reject('Input is empty');
}
@@ -63,6 +64,13 @@ export const dispatchRunAppNode = async (props: Props): Promise<Response> => {
const chatHistories = getHistories(history, histories);
const { files } = chatValue2RuntimePrompt(query);
// Concat variables
const systemVariables = filterSystemVariables(variables);
const childrenRunVariables = {
...systemVariables,
...childrenAppVariables
};
const { flowResponses, flowUsages, assistantResponses } = await dispatchWorkFlow({
...props,
app: appData,
@@ -76,7 +84,7 @@ export const dispatchRunAppNode = async (props: Props): Promise<Response> => {
files,
text: userChatInput
}),
variables: variables
variables: childrenRunVariables
});
const completeMessages = chatHistories.concat([

View File

@@ -31,7 +31,7 @@ import { dispatchAnswer } from './tools/answer';
import { dispatchClassifyQuestion } from './agent/classifyQuestion';
import { dispatchContentExtract } from './agent/extract';
import { dispatchHttp468Request } from './tools/http468';
import { dispatchAppRequest } from './tools/runApp';
import { dispatchAppRequest } from './abandoned/runApp';
import { dispatchQueryExtension } from './tools/queryExternsion';
import { dispatchRunPlugin } from './plugin/run';
import { dispatchPluginInput } from './plugin/runInput';
@@ -63,7 +63,7 @@ import {
InteractiveNodeResponseItemType,
UserSelectInteractive
} from '@fastgpt/global/core/workflow/template/system/userSelect/type';
import { dispatchRunAppNode } from './agent/runAppModule';
import { dispatchRunAppNode } from './agent/runApp';
const callbackMap: Record<FlowNodeTypeEnum, Function> = {
[FlowNodeTypeEnum.workflowStart]: dispatchWorkflowStart,
@@ -74,7 +74,6 @@ const callbackMap: Record<FlowNodeTypeEnum, Function> = {
[FlowNodeTypeEnum.classifyQuestion]: dispatchClassifyQuestion,
[FlowNodeTypeEnum.contentExtract]: dispatchContentExtract,
[FlowNodeTypeEnum.httpRequest468]: dispatchHttp468Request,
[FlowNodeTypeEnum.runApp]: dispatchAppRequest,
[FlowNodeTypeEnum.appModule]: dispatchRunAppNode,
[FlowNodeTypeEnum.pluginModule]: dispatchRunPlugin,
[FlowNodeTypeEnum.pluginInput]: dispatchPluginInput,
@@ -95,7 +94,9 @@ const callbackMap: Record<FlowNodeTypeEnum, Function> = {
[FlowNodeTypeEnum.systemConfig]: dispatchSystemConfig,
[FlowNodeTypeEnum.pluginConfig]: () => Promise.resolve(),
[FlowNodeTypeEnum.emptyNode]: () => Promise.resolve(),
[FlowNodeTypeEnum.globalVariable]: () => Promise.resolve()
[FlowNodeTypeEnum.globalVariable]: () => Promise.resolve(),
[FlowNodeTypeEnum.runApp]: dispatchAppRequest // abandoned
};
type Props = ChatDispatchProps & {

View File

@@ -9,10 +9,10 @@ import {
storeNodes2RuntimeNodes
} from '@fastgpt/global/core/workflow/runtime/utils';
import { DispatchNodeResultType } from '@fastgpt/global/core/workflow/runtime/type';
import { updateToolInputValue } from '../agent/runTool/utils';
import { authPluginByTmbId } from '../../../../support/permission/app/auth';
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
import { computedPluginUsage } from '../../../app/plugin/utils';
import { filterSystemVariables } from '../utils';
type RunPluginProps = ModuleDispatchProps<{
[key: string]: any;
@@ -25,7 +25,7 @@ export const dispatchRunPlugin = async (props: RunPluginProps): Promise<RunPlugi
app: workflowApp,
mode,
teamId,
params: data
params: data // Plugin input
} = props;
if (!pluginId) {
@@ -41,32 +41,31 @@ export const dispatchRunPlugin = async (props: RunPluginProps): Promise<RunPlugi
const plugin = await getPluginRuntimeById(pluginId);
// concat dynamic inputs
const inputModule = plugin.nodes.find(
(item) => item.flowNodeType === FlowNodeTypeEnum.pluginInput
);
if (!inputModule) return Promise.reject('Plugin error, It has no set input.');
const runtimeNodes = storeNodes2RuntimeNodes(
plugin.nodes,
getWorkflowEntryNodeIds(plugin.nodes)
).map((node) => {
// Update plugin input value
if (node.flowNodeType === FlowNodeTypeEnum.pluginInput) {
return {
...node,
showStatus: false,
inputs: node.inputs.map((input) => ({
...input,
value: data[input.key] ?? input.value
}))
};
}
return {
...node,
showStatus: false
};
});
const { flowResponses, flowUsages, assistantResponses } = await dispatchWorkFlow({
...props,
runtimeNodes: storeNodes2RuntimeNodes(plugin.nodes, getWorkflowEntryNodeIds(plugin.nodes)).map(
(node) => {
if (node.flowNodeType === FlowNodeTypeEnum.pluginInput) {
return {
...node,
showStatus: false,
inputs: updateToolInputValue({
inputs: node.inputs,
params: data
})
};
}
return {
...node,
showStatus: false
};
}
),
variables: filterSystemVariables(props.variables),
runtimeNodes,
runtimeEdges: initWorkflowEdgeStatus(plugin.edges)
});

View File

@@ -144,6 +144,15 @@ export const removeSystemVariable = (variables: Record<string, any>) => {
return copyVariables;
};
export const filterSystemVariables = (variables: Record<string, any>) => {
return {
appId: variables.appId,
chatId: variables.chatId,
responseChatItemId: variables.responseChatItemId,
histories: variables.histories,
cTime: variables.cTime
};
};
export const formatHttpError = (error: any) => {
return {