Skip to content

Commit

Permalink
feat: add customize toolkit (#3205)
Browse files Browse the repository at this point in the history
* chaoyang

* fix-auth

* add toolkit

* add order

* plugin usage

* fix

* delete console:
  • Loading branch information
newfish-cmyk authored and c121914yu committed Nov 27, 2024
1 parent 5fa2e3c commit 14c7e01
Show file tree
Hide file tree
Showing 48 changed files with 955 additions and 189 deletions.
6 changes: 6 additions & 0 deletions packages/global/core/app/type.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,9 @@ export type AppFileSelectConfigType = {
canSelectImg: boolean;
maxFiles: number;
};

export type SystemPluginListItemType = {
_id: string;
name: string;
avatar: string;
};
4 changes: 4 additions & 0 deletions packages/global/core/plugin/type.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,15 @@ export type PluginTemplateType = PluginRuntimeType & {
};

export type PluginRuntimeType = {
id: string;
teamId?: string;
name: string;
avatar: string;
showStatus?: boolean;
isTool?: boolean;
nodes: StoreNodeItemType[];
edges: StoreEdgeItemType[];
currentCost?: number;
hasTokenFee?: boolean;
pluginOrder?: number;
};
11 changes: 0 additions & 11 deletions packages/global/core/workflow/runtime/type.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,17 +82,6 @@ export type RuntimeNodeItemType = {
version: string;
};

export type PluginRuntimeType = {
id: string;
teamId?: string;
name: string;
avatar: string;
showStatus?: boolean;
currentCost?: number;
nodes: StoreNodeItemType[];
edges: StoreEdgeItemType[];
};

export type RuntimeEdgeItemType = StoreEdgeItemType & {
status: 'waiting' | 'active' | 'skipped';
};
Expand Down
7 changes: 6 additions & 1 deletion packages/global/core/workflow/type/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,20 @@ export type TemplateMarketListItemType = {
// system plugin
export type SystemPluginTemplateItemType = WorkflowTemplateType & {
customWorkflow?: string;
associatedPluginId?: string;
userGuide?: string;

templateType: FlowNodeTemplateTypeEnum;
templateType: string;
isTool?: boolean;

// commercial plugin config
originCost: number; // n points/one time
currentCost: number;
hasTokenFee: boolean;
pluginOrder: number;

isActive?: boolean;
isOfficial?: boolean;
inputConfig?: {
// Render config input form. Find the corresponding node and replace the variable directly
key: string;
Expand Down
8 changes: 5 additions & 3 deletions packages/global/core/workflow/type/node.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ type HandleType = {
// system template
export type FlowNodeTemplateType = FlowNodeCommonType & {
id: string; // node id, unique
templateType: FlowNodeTemplateTypeEnum;
templateType: string;

// show handle
sourceHandle?: HandleType;
Expand All @@ -76,7 +76,7 @@ export type NodeTemplateListItemType = {
flowNodeType: FlowNodeTypeEnum; // render node card
parentId?: ParentIdType;
isFolder?: boolean;
templateType: FlowNodeTemplateTypeEnum;
templateType: string;
avatar?: string;
name: string;
intro?: string; // template list intro
Expand All @@ -85,10 +85,12 @@ export type NodeTemplateListItemType = {
author?: string;
unique?: boolean; // 唯一的
currentCost?: number; // 当前积分消耗
hasTokenFee?: boolean; // 是否配置积分
instructions?: string; // 使用说明
};

export type NodeTemplateListType = {
type: FlowNodeTemplateTypeEnum;
type: string;
label: string;
list: NodeTemplateListItemType[];
}[];
Expand Down
3 changes: 2 additions & 1 deletion packages/plugins/register.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ export const getCommunityPlugins = () => {
id: `${PluginSourceEnum.community}-${name}`,
isFolder,
parentId,
isActive: true
isActive: true,
isOfficial: true
};
});
};
Expand Down
2 changes: 2 additions & 0 deletions packages/plugins/type.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { PluginTemplateType } from '@fastgpt/global/core/plugin/type.d';
import { systemPluginResponseEnum } from '@fastgpt/global/core/workflow/runtime/constants';
import { SystemPluginTemplateItemType } from '@fastgpt/global/core/workflow/type';
import { PluginGroupSchemaType } from '@fastgpt/service/core/app/store/type';

export type SystemPluginResponseType = Promise<Record<string, any>>;
export type SystemPluginSpecialResponse = {
Expand All @@ -10,6 +11,7 @@ export type SystemPluginSpecialResponse = {
};

declare global {
var pluginGroups: PluginGroupSchemaType[];
var systemPlugins: SystemPluginTemplateItemType[];
var systemPluginCb: Record<string, (e: any) => SystemPluginResponseType>;
}
60 changes: 56 additions & 4 deletions packages/service/core/app/plugin/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { FlowNodeTemplateType } from '@fastgpt/global/core/workflow/type/node.d'
import { FlowNodeTypeEnum, defaultNodeVersion } from '@fastgpt/global/core/workflow/node/constant';
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';
import { getHandleConfig } from '@fastgpt/global/core/workflow/template/utils';
import { getNanoid } from '@fastgpt/global/common/string/tools';
Expand All @@ -11,6 +10,7 @@ import { MongoApp } from '../schema';
import { SystemPluginTemplateItemType } from '@fastgpt/global/core/workflow/type';
import { getSystemPluginTemplates } from '../../../../plugins/register';
import { getAppLatestVersion, getAppVersionById } from '../version/controller';
import { PluginRuntimeType } from '@fastgpt/global/core/plugin/type';

/*
plugin id rule:
Expand Down Expand Up @@ -77,13 +77,29 @@ export async function getChildAppPreviewNode({
templateType: FlowNodeTemplateTypeEnum.teamApp,
version: version.versionId,
originCost: 0,
currentCost: 0
currentCost: 0,
hasTokenFee: false,
pluginOrder: 0
};
} else {
return getSystemPluginTemplateById(pluginId);
}
})();

if (app.associatedPluginId) {
const item = await MongoApp.findById(app.associatedPluginId).lean();
if (!item) return Promise.reject('plugin not found');

const version = await getAppLatestVersion(app.associatedPluginId, item);

if (!version.versionId) return Promise.reject('App version not found');
app.workflow = {
nodes: version.nodes,
edges: version.edges,
chatConfig: version.chatConfig
};
}

const isPlugin = !!app.workflow.nodes.find(
(node) => node.flowNodeType === FlowNodeTypeEnum.pluginInput
);
Expand Down Expand Up @@ -147,7 +163,41 @@ export async function getChildAppRuntimeById(
// 用不到
version: item?.pluginData?.nodeVersion || defaultNodeVersion,
originCost: 0,
currentCost: 0
currentCost: 0,
hasTokenFee: false,
pluginOrder: 0
};
} else if (source === PluginSourceEnum.commercial) {
const pluginTemplate = getSystemPluginTemplates().find((plugin) => plugin.id === pluginId);
if (!pluginTemplate?.associatedPluginId) return Promise.reject('plugin not found');

const item = await MongoApp.findById(pluginTemplate.associatedPluginId).lean();
if (!item) return Promise.reject('plugin not found');

const version = await getAppVersionById({
appId: pluginTemplate.associatedPluginId,
versionId,
app: item
});

return {
id: String(item._id),
teamId: String(item.teamId),
name: item.name,
avatar: item.avatar,
intro: item.intro,
showStatus: true,
workflow: {
nodes: version.nodes,
edges: version.edges,
chatConfig: version.chatConfig
},
templateType: FlowNodeTemplateTypeEnum.teamApp,
version: pluginTemplate.version,
originCost: pluginTemplate.originCost,
currentCost: pluginTemplate.currentCost,
hasTokenFee: pluginTemplate.hasTokenFee,
pluginOrder: pluginTemplate.pluginOrder
};
} else {
return getSystemPluginTemplateById(pluginId);
Expand All @@ -162,6 +212,8 @@ export async function getChildAppRuntimeById(
showStatus: app.showStatus,
currentCost: app.currentCost,
nodes: app.workflow.nodes,
edges: app.workflow.edges
edges: app.workflow.edges,
hasTokenFee: app.hasTokenFee,
pluginOrder: app.pluginOrder
};
}
8 changes: 8 additions & 0 deletions packages/service/core/app/plugin/systemPluginSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ const SystemPluginSchema = new Schema({
type: Number,
default: 0
},
hasTokenFee: {
type: Boolean,
default: false
},
pluginOrder: {
type: Number,
default: 0
},
customConfig: Object
});

Expand Down
7 changes: 6 additions & 1 deletion packages/service/core/app/plugin/type.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { SystemPluginListItemType } from '@fastgpt/global/core/app/type';
import { FlowNodeTemplateTypeEnum } from '@fastgpt/global/core/workflow/constants';
import {
SystemPluginTemplateItemType,
Expand All @@ -9,7 +10,9 @@ export type SystemPluginConfigSchemaType = {

originCost: number; // n points/one time
currentCost: number;
hasTokenFee: boolean;
isActive: boolean;
pluginOrder: number;
inputConfig: SystemPluginTemplateItemType['inputConfig'];

customConfig?: {
Expand All @@ -19,6 +22,8 @@ export type SystemPluginConfigSchemaType = {
version: string;
weight?: number;
workflow: WorkflowTemplateBasicType;
templateType: FlowNodeTemplateTypeEnum;
templateType: string;
associatedPluginId: string;
userGuide: string;
};
};
24 changes: 12 additions & 12 deletions packages/service/core/app/plugin/utils.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { PluginRuntimeType } from '@fastgpt/global/core/workflow/runtime/type';
import { ChatNodeUsageType } from '@fastgpt/global/support/wallet/bill/type';
import { splitCombinePluginId } from './controller';
import { PluginSourceEnum } from '@fastgpt/global/core/plugin/constants';
import { PluginRuntimeType } from '@fastgpt/global/core/plugin/type';

/*
1. Commercial plugin: n points per times
2. Other plugin: sum of children points
Plugin points calculation:
1. Return 0 if error
2. Add configured points if commercial plugin
3. Add sum of child nodes points
*/
export const computedPluginUsage = async ({
plugin,
Expand All @@ -16,13 +16,13 @@ export const computedPluginUsage = async ({
childrenUsage: ChatNodeUsageType[];
error?: boolean;
}) => {
const { source } = await splitCombinePluginId(plugin.id);

// Commercial plugin: n points per times
if (source === PluginSourceEnum.commercial) {
if (error) return 0;
return plugin.currentCost ?? 0;
if (error) {
return 0;
}

return childrenUsage.reduce((sum, item) => sum + (item.totalPoints || 0), 0);
const childrenIUsages = childrenUsage.reduce((sum, item) => sum + (item.totalPoints || 0), 0);

const pluginCurrentCose = plugin.currentCost ?? 0;

return plugin.hasTokenFee ? pluginCurrentCose + childrenIUsages : pluginCurrentCose;
};
31 changes: 31 additions & 0 deletions packages/service/core/app/store/pluginGroupSchema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { connectionMongo, getMongoModel } from '../../../common/mongo/index';
import { PluginGroupSchemaType, TGroupType } from './type';
const { Schema } = connectionMongo;

export const collectionName = 'app_plugin_groups';

const PluginGroupSchema = new Schema({
groupAvatar: {
type: String,
default: ''
},
groupName: {
type: String,
required: true
},
groupTypes: {
type: Array<TGroupType>,
default: []
},
groupOrder: {
type: Number,
default: 0
}
});

PluginGroupSchema.index({ groupName: 1 });

export const MongoPluginGroupsSchema = getMongoModel<PluginGroupSchemaType>(
collectionName,
PluginGroupSchema
);
11 changes: 11 additions & 0 deletions packages/service/core/app/store/type.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export type PluginGroupSchemaType = {
groupAvatar: string;
groupName: string;
groupTypes: TGroupType[];
groupOrder: number;
};

export type TGroupType = {
typeName: string;
typeId: string;
};
7 changes: 0 additions & 7 deletions packages/service/core/workflow/dispatch/plugin/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,13 @@ type RunPluginProps = ModuleDispatchProps<{
[key: string]: any;
}>;
type RunPluginResponse = DispatchNodeResultType<{}>;

export const dispatchRunPlugin = async (props: RunPluginProps): Promise<RunPluginResponse> => {
const {
node: { pluginId, version },
runningAppInfo,
query,
params: { system_forbid_stream = false, ...data } // Plugin input
} = props;

if (!pluginId) {
return Promise.reject('pluginId can not find');
}
Expand All @@ -54,7 +52,6 @@ export const dispatchRunPlugin = async (props: RunPluginProps): Promise<RunPlugi
acc[cur.key] = cur.isToolOutput === false ? false : true;
return acc;
}, {}) ?? {};

const runtimeNodes = storeNodes2RuntimeNodes(
plugin.nodes,
getWorkflowEntryNodeIds(plugin.nodes)
Expand All @@ -79,7 +76,6 @@ export const dispatchRunPlugin = async (props: RunPluginProps): Promise<RunPlugi
...filterSystemVariables(props.variables),
appId: String(plugin.id)
};

const { flowResponses, flowUsages, assistantResponses, runTimes } = await dispatchWorkFlow({
...props,
// Rewrite stream mode
Expand All @@ -105,9 +101,7 @@ export const dispatchRunPlugin = async (props: RunPluginProps): Promise<RunPlugi
runtimeNodes,
runtimeEdges: initWorkflowEdgeStatus(plugin.edges)
});

const output = flowResponses.find((item) => item.moduleType === FlowNodeTypeEnum.pluginOutput);

if (output) {
output.moduleLogo = plugin.avatar;
}
Expand All @@ -117,7 +111,6 @@ export const dispatchRunPlugin = async (props: RunPluginProps): Promise<RunPlugi
childrenUsage: flowUsages,
error: !!output?.pluginOutput?.error
});

return {
// 嵌套运行时,如果 childApp stream=false,实际上不会有任何内容输出给用户,所以不需要存储
assistantResponses: system_forbid_stream ? [] : assistantResponses,
Expand Down
Loading

0 comments on commit 14c7e01

Please sign in to comment.