4.8.11 perf (#2832)

* save toast

* perf: surya ocr

* perf: remove same model name

* fix: indexes

* perf: ip check

* feat: Fixed the version number of the subapplication

* feat: simple app get latest child version

* perf: update child dispatch variables

* feat: variables update doc
This commit is contained in:
Archer
2024-09-28 15:31:25 +08:00
committed by GitHub
parent f7a8203454
commit f2749cbb00
34 changed files with 393 additions and 263 deletions

View File

@@ -51,6 +51,7 @@ export function reRankRecall({
}));
})
.catch((err) => {
console.log(err);
addLog.error('rerank error', err);
return [];

View File

@@ -2,7 +2,6 @@ import { AppSchema } from '@fastgpt/global/core/app/type';
import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants';
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
import { getLLMModel } from '../ai/model';
import { MongoAppVersion } from './version/schema';
import { MongoApp } from './schema';
export const beforeUpdateAppFormat = <T extends AppSchema['modules'] | undefined>({
@@ -46,30 +45,6 @@ export const beforeUpdateAppFormat = <T extends AppSchema['modules'] | undefined
};
};
export const getAppLatestVersion = async (appId: string, app?: AppSchema) => {
const version = await MongoAppVersion.findOne({
appId,
isPublish: true
})
.sort({
time: -1
})
.lean();
if (version) {
return {
nodes: version.nodes,
edges: version.edges,
chatConfig: version.chatConfig || app?.chatConfig || {}
};
}
return {
nodes: app?.modules || [],
edges: app?.edges || [],
chatConfig: app?.chatConfig || {}
};
};
/* Get apps */
export async function findAppAndAllChildren({
teamId,

View File

@@ -10,6 +10,7 @@ import { cloneDeep } from 'lodash';
import { MongoApp } from '../schema';
import { SystemPluginTemplateItemType } from '@fastgpt/global/core/workflow/type';
import { getSystemPluginTemplates } from '../../../../plugins/register';
import { getAppLatestVersion, getAppVersionById } from '../version/controller';
/*
plugin id rule:
@@ -34,38 +35,14 @@ export async function splitCombinePluginId(id: string) {
return { source, pluginId: id };
}
const getChildAppTemplateById = async (
id: string
): Promise<SystemPluginTemplateItemType & { teamId?: string }> => {
const { source, pluginId } = await splitCombinePluginId(id);
type ChildAppType = SystemPluginTemplateItemType & { teamId?: string };
const getSystemPluginTemplateById = async (
pluginId: string
): Promise<SystemPluginTemplateItemType> => {
const item = getSystemPluginTemplates().find((plugin) => plugin.id === pluginId);
if (!item) return Promise.reject('plugin not found');
if (source === PluginSourceEnum.personal) {
const item = await MongoApp.findById(id).lean();
if (!item) return Promise.reject('plugin not found');
return {
id: String(item._id),
teamId: String(item.teamId),
name: item.name,
avatar: item.avatar,
intro: item.intro,
showStatus: true,
workflow: {
nodes: item.modules,
edges: item.edges,
chatConfig: item.chatConfig
},
templateType: FlowNodeTemplateTypeEnum.teamApp,
version: item?.pluginData?.nodeVersion || defaultNodeVersion,
originCost: 0,
currentCost: 0
};
} else {
const item = getSystemPluginTemplates().find((plugin) => plugin.id === pluginId);
if (!item) return Promise.reject('plugin not found');
return cloneDeep(item);
}
return cloneDeep(item);
};
/* format plugin modules to plugin preview module */
@@ -74,7 +51,39 @@ export async function getChildAppPreviewNode({
}: {
id: string;
}): Promise<FlowNodeTemplateType> {
const app = await getChildAppTemplateById(id);
const app: ChildAppType = await (async () => {
const { source, pluginId } = await splitCombinePluginId(id);
if (source === PluginSourceEnum.personal) {
const item = await MongoApp.findById(id).lean();
if (!item) return Promise.reject('plugin not found');
const version = await getAppLatestVersion(id, item);
if (!version.versionId) return Promise.reject('App version not found');
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: version.versionId,
originCost: 0,
currentCost: 0
};
} else {
return getSystemPluginTemplateById(pluginId);
}
})();
const isPlugin = !!app.workflow.nodes.find(
(node) => node.flowNodeType === FlowNodeTypeEnum.pluginInput
);
@@ -99,9 +108,51 @@ export async function getChildAppPreviewNode({
};
}
/* run plugin time */
export async function getChildAppRuntimeById(id: string): Promise<PluginRuntimeType> {
const app = await getChildAppTemplateById(id);
/*
Get runtime plugin data
System plugin: plugin id
Personal plugin: Version id
*/
export async function getChildAppRuntimeById(
id: string,
versionId?: string
): Promise<PluginRuntimeType> {
const app: ChildAppType = await (async () => {
const { source, pluginId } = await splitCombinePluginId(id);
if (source === PluginSourceEnum.personal) {
const item = await MongoApp.findById(id).lean();
if (!item) return Promise.reject('plugin not found');
const version = await getAppVersionById({
appId: id,
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: item?.pluginData?.nodeVersion || defaultNodeVersion,
originCost: 0,
currentCost: 0
};
} else {
return getSystemPluginTemplateById(pluginId);
}
})();
return {
id: app.id,

View File

@@ -0,0 +1,59 @@
import { AppSchema } from '@fastgpt/global/core/app/type';
import { MongoAppVersion } from './schema';
import { Types } from '../../../common/mongo';
export const getAppLatestVersion = async (appId: string, app?: AppSchema) => {
const version = await MongoAppVersion.findOne({
appId,
isPublish: true
})
.sort({
time: -1
})
.lean();
if (version) {
return {
versionId: version._id,
nodes: version.nodes,
edges: version.edges,
chatConfig: version.chatConfig || app?.chatConfig || {}
};
}
return {
versionId: app?.pluginData?.nodeVersion,
nodes: app?.modules || [],
edges: app?.edges || [],
chatConfig: app?.chatConfig || {}
};
};
export const getAppVersionById = async ({
appId,
versionId,
app
}: {
appId: string;
versionId?: string;
app?: AppSchema;
}) => {
// 检查 versionId 是否符合 ObjectId 格式
if (versionId && Types.ObjectId.isValid(versionId)) {
const version = await MongoAppVersion.findOne({
_id: versionId,
appId
}).lean();
if (version) {
return {
versionId: version._id,
nodes: version.nodes,
edges: version.edges,
chatConfig: version.chatConfig || app?.chatConfig || {}
};
}
}
// If the version does not exist, the latest version is returned
return getAppLatestVersion(appId, app);
};

View File

@@ -183,8 +183,18 @@ export const dispatchRunTools = async (props: DispatchToolModuleProps): Promise<
});
// flat child tool response
const childToolResponse = dispatchFlowResponse.map((item) => item.flowResponses).flat();
const newVariables = dispatchFlowResponse[dispatchFlowResponse.length - 1]?.newVariables;
let newVariables: Record<string, any> = props.variables;
const childToolResponse = dispatchFlowResponse
.map((item) => {
// Computed new variables
newVariables = {
...newVariables,
...item.newVariables
};
return item.flowResponses;
})
.flat();
// concat tool usage
const totalPointsUsage =

View File

@@ -38,7 +38,7 @@ export const dispatchLoop = async (props: Props): Promise<Response> => {
const loopDetail: ChatHistoryItemResType[] = [];
let assistantResponses: AIChatItemValueItemType[] = [];
let totalPoints = 0;
let newVariables: Record<string, any> = {};
let newVariables: Record<string, any> = props.variables;
for await (const item of loopInputArray) {
const response = await dispatchWorkFlow({

View File

@@ -26,7 +26,7 @@ type RunPluginResponse = DispatchNodeResultType<{}>;
export const dispatchRunPlugin = async (props: RunPluginProps): Promise<RunPluginResponse> => {
const {
node: { pluginId },
node: { pluginId, version },
runningAppInfo,
query,
params: { system_forbid_stream = false, ...data } // Plugin input
@@ -45,7 +45,7 @@ export const dispatchRunPlugin = async (props: RunPluginProps): Promise<RunPlugi
per: ReadPermissionVal
});
const plugin = await getChildAppRuntimeById(pluginId);
const plugin = await getChildAppRuntimeById(pluginId, version);
const outputFilterMap =
plugin.nodes

View File

@@ -16,7 +16,7 @@ import { chatValue2RuntimePrompt, runtimePrompt2ChatsValue } from '@fastgpt/glob
import { DispatchNodeResultType } from '@fastgpt/global/core/workflow/runtime/type';
import { authAppByTmbId } from '../../../../support/permission/app/auth';
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
import { getAppLatestVersion } from '../../../app/controller';
import { getAppVersionById } from '../../../app/version/controller';
type Props = ModuleDispatchProps<{
[NodeInputKeyEnum.userChatInput]: string;
@@ -34,8 +34,7 @@ export const dispatchRunAppNode = async (props: Props): Promise<Response> => {
runningAppInfo,
histories,
query,
mode,
node: { pluginId },
node: { pluginId: appId, version },
workflowStreamResponse,
params,
variables
@@ -45,19 +44,23 @@ export const dispatchRunAppNode = async (props: Props): Promise<Response> => {
if (!userChatInput) {
return Promise.reject('Input is empty');
}
if (!pluginId) {
if (!appId) {
return Promise.reject('pluginId is empty');
}
// Auth the app by tmbId(Not the user, but the workflow user)
const { app: appData } = await authAppByTmbId({
appId: pluginId,
appId: appId,
tmbId: runningAppInfo.tmbId,
per: ReadPermissionVal
});
const { nodes, edges, chatConfig } = await getAppLatestVersion(pluginId);
const childStreamResponse = system_forbid_stream ? false : props.stream;
const { nodes, edges, chatConfig } = await getAppVersionById({
appId,
versionId: version,
app: appData
});
const childStreamResponse = system_forbid_stream ? false : props.stream;
// Auto line
if (childStreamResponse) {
workflowStreamResponse?.({

View File

@@ -77,8 +77,18 @@ try {
// timer task. Get standard plan;Get free plan;Clear expired extract plan
SubSchema.index({ type: 1, expiredTime: -1, currentSubLevel: 1 });
// unique
SubSchema.index({ teamId: 1, type: 1, currentSubLevel: 1 }, { unique: true });
// 修改后的唯一索引
SubSchema.index(
{
teamId: 1,
type: 1,
currentSubLevel: 1
},
{
unique: true,
partialFilterExpression: { type: SubTypeEnum.standard }
}
);
} catch (error) {
console.log(error);
}