mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-23 05:12:39 +00:00
4.8-fix (#1305)
* fix if-else find variables (#92) * fix if-else find variables * change workflow output type * fix tooltip style * fix * 4.8 (#93) * api middleware * perf: app version histories * faq * perf: value type show * fix: ts * fix: Run the same node multiple times * feat: auto save workflow * perf: auto save workflow --------- Co-authored-by: heheer <71265218+newfish-cmyk@users.noreply.github.com>
This commit is contained in:
65
packages/service/core/app/controller.ts
Normal file
65
packages/service/core/app/controller.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
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 './versionSchema';
|
||||
|
||||
export const beforeUpdateAppFormat = <T extends AppSchema['modules'] | undefined>({
|
||||
nodes
|
||||
}: {
|
||||
nodes: T;
|
||||
}) => {
|
||||
if (nodes) {
|
||||
let maxTokens = 3000;
|
||||
|
||||
nodes.forEach((item) => {
|
||||
if (
|
||||
item.flowNodeType === FlowNodeTypeEnum.chatNode ||
|
||||
item.flowNodeType === FlowNodeTypeEnum.tools
|
||||
) {
|
||||
const model =
|
||||
item.inputs.find((item) => item.key === NodeInputKeyEnum.aiModel)?.value || '';
|
||||
const chatModel = getLLMModel(model);
|
||||
const quoteMaxToken = chatModel.quoteMaxToken || 3000;
|
||||
|
||||
maxTokens = Math.max(maxTokens, quoteMaxToken);
|
||||
}
|
||||
});
|
||||
|
||||
nodes.forEach((item) => {
|
||||
if (item.flowNodeType === FlowNodeTypeEnum.datasetSearchNode) {
|
||||
item.inputs.forEach((input) => {
|
||||
if (input.key === NodeInputKeyEnum.datasetMaxTokens) {
|
||||
const val = input.value as number;
|
||||
if (val > maxTokens) {
|
||||
input.value = maxTokens;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
nodes
|
||||
};
|
||||
};
|
||||
|
||||
export const getAppLatestVersion = async (appId: string, app?: AppSchema) => {
|
||||
const version = await MongoAppVersion.findOne({
|
||||
appId
|
||||
}).sort({
|
||||
time: -1
|
||||
});
|
||||
|
||||
if (version) {
|
||||
return {
|
||||
nodes: version.nodes,
|
||||
edges: version.edges
|
||||
};
|
||||
}
|
||||
return {
|
||||
nodes: app?.modules || [],
|
||||
edges: app?.edges || []
|
||||
};
|
||||
};
|
@@ -8,7 +8,7 @@ import {
|
||||
TeamMemberCollectionName
|
||||
} from '@fastgpt/global/support/user/team/constant';
|
||||
|
||||
export const appCollectionName = 'apps';
|
||||
export const AppCollectionName = 'apps';
|
||||
|
||||
const AppSchema = new Schema({
|
||||
teamId: {
|
||||
@@ -46,6 +46,8 @@ const AppSchema = new Schema({
|
||||
type: Date,
|
||||
default: () => new Date()
|
||||
},
|
||||
|
||||
// tmp store
|
||||
modules: {
|
||||
type: Array,
|
||||
default: []
|
||||
@@ -92,6 +94,6 @@ try {
|
||||
}
|
||||
|
||||
export const MongoApp: Model<AppType> =
|
||||
models[appCollectionName] || model(appCollectionName, AppSchema);
|
||||
models[AppCollectionName] || model(AppCollectionName, AppSchema);
|
||||
|
||||
MongoApp.syncIndexes();
|
||||
|
36
packages/service/core/app/versionSchema.ts
Normal file
36
packages/service/core/app/versionSchema.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { connectionMongo, type Model } from '../../common/mongo';
|
||||
const { Schema, model, models } = connectionMongo;
|
||||
import { AppVersionSchemaType } from '@fastgpt/global/core/app/version';
|
||||
|
||||
export const AppVersionCollectionName = 'app.versions';
|
||||
|
||||
const AppVersionSchema = new Schema({
|
||||
appId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: AppVersionCollectionName,
|
||||
required: true
|
||||
},
|
||||
time: {
|
||||
type: Date,
|
||||
default: () => new Date()
|
||||
},
|
||||
nodes: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
edges: {
|
||||
type: Array,
|
||||
default: []
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
AppVersionSchema.index({ appId: 1, time: -1 });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
export const MongoAppVersion: Model<AppVersionSchemaType> =
|
||||
models[AppVersionCollectionName] || model(AppVersionCollectionName, AppVersionSchema);
|
||||
|
||||
MongoAppVersion.syncIndexes();
|
@@ -7,7 +7,7 @@ import {
|
||||
TeamCollectionName,
|
||||
TeamMemberCollectionName
|
||||
} from '@fastgpt/global/support/user/team/constant';
|
||||
import { appCollectionName } from '../app/schema';
|
||||
import { AppCollectionName } from '../app/schema';
|
||||
import { userCollectionName } from '../../support/user/schema';
|
||||
import { NodeOutputKeyEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants';
|
||||
@@ -40,7 +40,7 @@ const ChatItemSchema = new Schema({
|
||||
},
|
||||
appId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: appCollectionName,
|
||||
ref: AppCollectionName,
|
||||
required: true
|
||||
},
|
||||
time: {
|
||||
|
@@ -6,7 +6,7 @@ import {
|
||||
TeamCollectionName,
|
||||
TeamMemberCollectionName
|
||||
} from '@fastgpt/global/support/user/team/constant';
|
||||
import { appCollectionName } from '../app/schema';
|
||||
import { AppCollectionName } from '../app/schema';
|
||||
|
||||
export const chatCollectionName = 'chat';
|
||||
|
||||
@@ -31,7 +31,7 @@ const ChatSchema = new Schema({
|
||||
},
|
||||
appId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: appCollectionName,
|
||||
ref: AppCollectionName,
|
||||
required: true
|
||||
},
|
||||
updateTime: {
|
||||
|
@@ -220,9 +220,16 @@ export async function dispatchWorkFlow({
|
||||
).then((result) => {
|
||||
const flat = result.flat();
|
||||
if (flat.length === 0) return;
|
||||
// update output
|
||||
|
||||
// Update the node output at the end of the run and get the next nodes
|
||||
const nextNodes = flat.map((item) => nodeOutput(item.node, item.result)).flat();
|
||||
return checkNodeCanRun(nextNodes);
|
||||
|
||||
// Remove repeat nodes(Make sure that the node is only executed once)
|
||||
const filterNextNodes = nextNodes.filter(
|
||||
(node, index, self) => self.findIndex((t) => t.nodeId === node.nodeId) === index
|
||||
);
|
||||
|
||||
return checkNodeCanRun(filterNextNodes);
|
||||
});
|
||||
}
|
||||
// 运行完一轮后,清除连线的状态,避免污染进程
|
||||
|
@@ -8,6 +8,7 @@ import {
|
||||
} from '@fastgpt/global/core/workflow/template/system/ifElse/type';
|
||||
import { ModuleDispatchProps } from '@fastgpt/global/core/workflow/type';
|
||||
import { getHandleId } from '@fastgpt/global/core/workflow/utils';
|
||||
import { getReferenceVariableValue } from '@fastgpt/global/core/workflow/runtime/utils';
|
||||
|
||||
type Props = ModuleDispatchProps<{
|
||||
[NodeInputKeyEnum.condition]: IfElseConditionType;
|
||||
@@ -20,20 +21,21 @@ function checkCondition(condition: VariableConditionEnum, variableValue: any, va
|
||||
[VariableConditionEnum.isNotEmpty]: () => !!variableValue,
|
||||
[VariableConditionEnum.equalTo]: () => variableValue === value,
|
||||
[VariableConditionEnum.notEqual]: () => variableValue !== value,
|
||||
[VariableConditionEnum.greaterThan]: () => variableValue > Number(value),
|
||||
[VariableConditionEnum.lessThan]: () => variableValue < Number(value),
|
||||
[VariableConditionEnum.greaterThanOrEqualTo]: () => variableValue >= Number(value),
|
||||
[VariableConditionEnum.lessThanOrEqualTo]: () => variableValue <= Number(value),
|
||||
[VariableConditionEnum.include]: () => variableValue.includes(value),
|
||||
[VariableConditionEnum.notInclude]: () => !variableValue.includes(value),
|
||||
[VariableConditionEnum.startWith]: () => variableValue.startsWith(value),
|
||||
[VariableConditionEnum.endWith]: () => variableValue.endsWith(value),
|
||||
[VariableConditionEnum.lengthEqualTo]: () => variableValue.length === Number(value),
|
||||
[VariableConditionEnum.lengthNotEqualTo]: () => variableValue.length !== Number(value),
|
||||
[VariableConditionEnum.lengthGreaterThan]: () => variableValue.length > Number(value),
|
||||
[VariableConditionEnum.lengthGreaterThanOrEqualTo]: () => variableValue.length >= Number(value),
|
||||
[VariableConditionEnum.lengthLessThan]: () => variableValue.length < Number(value),
|
||||
[VariableConditionEnum.lengthLessThanOrEqualTo]: () => variableValue.length <= Number(value)
|
||||
[VariableConditionEnum.greaterThan]: () => Number(variableValue) > Number(value),
|
||||
[VariableConditionEnum.lessThan]: () => Number(variableValue) < Number(value),
|
||||
[VariableConditionEnum.greaterThanOrEqualTo]: () => Number(variableValue) >= Number(value),
|
||||
[VariableConditionEnum.lessThanOrEqualTo]: () => Number(variableValue) <= Number(value),
|
||||
[VariableConditionEnum.include]: () => variableValue?.includes(value),
|
||||
[VariableConditionEnum.notInclude]: () => !variableValue?.includes(value),
|
||||
[VariableConditionEnum.startWith]: () => variableValue?.startsWith(value),
|
||||
[VariableConditionEnum.endWith]: () => variableValue?.endsWith(value),
|
||||
[VariableConditionEnum.lengthEqualTo]: () => variableValue?.length === Number(value),
|
||||
[VariableConditionEnum.lengthNotEqualTo]: () => variableValue?.length !== Number(value),
|
||||
[VariableConditionEnum.lengthGreaterThan]: () => variableValue?.length > Number(value),
|
||||
[VariableConditionEnum.lengthGreaterThanOrEqualTo]: () =>
|
||||
variableValue?.length >= Number(value),
|
||||
[VariableConditionEnum.lengthLessThan]: () => variableValue?.length < Number(value),
|
||||
[VariableConditionEnum.lengthLessThanOrEqualTo]: () => variableValue?.length <= Number(value)
|
||||
};
|
||||
|
||||
return (operations[condition] || (() => false))();
|
||||
@@ -43,15 +45,18 @@ export const dispatchIfElse = async (props: Props): Promise<DispatchNodeResultTy
|
||||
const {
|
||||
params,
|
||||
runtimeNodes,
|
||||
variables,
|
||||
node: { nodeId }
|
||||
} = props;
|
||||
const { condition, ifElseList } = params;
|
||||
const listResult = ifElseList.map((item) => {
|
||||
const { variable, condition: variableCondition, value } = item;
|
||||
|
||||
const variableValue = runtimeNodes
|
||||
.find((node) => node.nodeId === variable[0])
|
||||
?.outputs?.find((item) => item.id === variable[1])?.value;
|
||||
const variableValue = getReferenceVariableValue({
|
||||
value: variable,
|
||||
variables,
|
||||
nodes: runtimeNodes
|
||||
});
|
||||
|
||||
return checkCondition(variableCondition as VariableConditionEnum, variableValue, value || '');
|
||||
});
|
||||
|
Reference in New Issue
Block a user