Test version (#4792)

* plugin node version select (#4760)

* plugin node version select

* type

* fix

* fix

* perf: version list

* fix node version (#4787)

* change my select

* fix-ui

* fix test

* add test

* fix

* remove invalid version field

* filter deprecated field

* fix: claude tool call

* fix: test

---------

Co-authored-by: heheer <heheer@sealos.io>
This commit is contained in:
Archer
2025-05-12 22:27:01 +08:00
committed by GitHub
parent 3cc6b8a17a
commit 0ef3d40296
69 changed files with 1024 additions and 599 deletions

View File

@@ -1,5 +1,5 @@
import { type FlowNodeTemplateType } from '@fastgpt/global/core/workflow/type/node.d';
import { FlowNodeTypeEnum, defaultNodeVersion } from '@fastgpt/global/core/workflow/node/constant';
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
import {
appData2FlowNodeIO,
pluginData2FlowNodeIO,
@@ -14,10 +14,16 @@ import { cloneDeep } from 'lodash';
import { MongoApp } from '../schema';
import { type SystemPluginTemplateItemType } from '@fastgpt/global/core/workflow/type';
import { getSystemPluginTemplates } from '../../../../plugins/register';
import { getAppLatestVersion, getAppVersionById } from '../version/controller';
import {
checkIsLatestVersion,
getAppLatestVersion,
getAppVersionById
} from '../version/controller';
import { type PluginRuntimeType } from '@fastgpt/global/core/plugin/type';
import { MongoSystemPlugin } from './systemPluginSchema';
import { PluginErrEnum } from '@fastgpt/global/common/error/code/plugin';
import { MongoAppVersion } from '../version/schema';
import { i18nT } from '../../../../web/i18n/utils';
/*
plugin id rule:
@@ -90,20 +96,34 @@ const getSystemPluginTemplateById = async (
/* Format plugin to workflow preview node data */
export async function getChildAppPreviewNode({
id
appId,
versionId
}: {
id: string;
appId: string;
versionId?: string;
}): Promise<FlowNodeTemplateType> {
const app: ChildAppType = await (async () => {
const { source, pluginId } = await splitCombinePluginId(id);
const { source, pluginId } = await splitCombinePluginId(appId);
if (source === PluginSourceEnum.personal) {
const item = await MongoApp.findById(id).lean();
const item = await MongoApp.findById(appId).lean();
if (!item) return Promise.reject('plugin not found');
const version = await getAppLatestVersion(id, item);
const version = await getAppVersionById({ appId, versionId, app: item });
if (!version.versionId) return Promise.reject('App version not found');
if (!version.versionId) return Promise.reject(i18nT('common:app_not_version'));
const versionData = await MongoAppVersion.findById(
version.versionId,
'_id versionName appId time'
).lean();
const isLatest = versionData
? await checkIsLatestVersion({
appId,
versionId: versionData._id
})
: true;
return {
id: String(item._id),
@@ -118,7 +138,11 @@ export async function getChildAppPreviewNode({
chatConfig: version.chatConfig
},
templateType: FlowNodeTemplateTypeEnum.teamApp,
version: version.versionId,
versionLabel: versionData?.versionName || '',
isLatestVersion: isLatest,
originCost: 0,
currentCost: 0,
hasTokenFee: false,
@@ -175,7 +199,11 @@ export async function getChildAppPreviewNode({
userGuide: app.userGuide,
showStatus: app.showStatus,
isTool: true,
version: app.version,
versionLabel: app.versionLabel,
isLatestVersion: app.isLatestVersion,
sourceHandle: isToolSet
? getHandleConfig(false, false, false, false)
: getHandleConfig(true, true, true, true),
@@ -224,7 +252,7 @@ export async function getChildAppRuntimeById(
templateType: FlowNodeTemplateTypeEnum.teamApp,
// 用不到
version: item?.pluginData?.nodeVersion || defaultNodeVersion,
version: item?.pluginData?.nodeVersion,
originCost: 0,
currentCost: 0,
hasTokenFee: false,

View File

@@ -1,8 +1,14 @@
import { MongoDataset } from '../dataset/schema';
import { getEmbeddingModel } from '../ai/model';
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
import {
AppNodeFlowNodeTypeMap,
FlowNodeTypeEnum
} from '@fastgpt/global/core/workflow/node/constant';
import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants';
import type { StoreNodeItemType } from '@fastgpt/global/core/workflow/type/node';
import { MongoAppVersion } from './version/schema';
import { checkIsLatestVersion } from './version/controller';
import { Types } from '../../common/mongo';
export async function listAppDatasetDataByTeamIdAndDatasetIds({
teamId,
@@ -35,6 +41,45 @@ export async function rewriteAppWorkflowToDetail({
}) {
const datasetIdSet = new Set<string>();
// Add node(App Type) versionlabel and latest sign
const appNodes = nodes.filter((node) => AppNodeFlowNodeTypeMap[node.flowNodeType]);
const versionIds = appNodes
.filter((node) => node.version && Types.ObjectId.isValid(node.version))
.map((node) => node.version);
if (versionIds.length > 0) {
const versionDataList = await MongoAppVersion.find(
{
_id: { $in: versionIds }
},
'_id versionName appId time'
).lean();
const versionMap: Record<string, any> = {};
const isLatestChecks = await Promise.all(
versionDataList.map(async (version) => {
const isLatest = await checkIsLatestVersion({
appId: version.appId,
versionId: version._id
});
return { versionId: String(version._id), isLatest };
})
);
const isLatestMap = new Map(isLatestChecks.map((item) => [item.versionId, item.isLatest]));
versionDataList.forEach((version) => {
versionMap[String(version._id)] = version;
});
appNodes.forEach((node) => {
if (!node.version) return;
const versionData = versionMap[String(node.version)];
if (versionData) {
node.versionLabel = versionData.versionName;
node.isLatestVersion = isLatestMap.get(String(node.version)) || false;
}
});
}
// Get all dataset ids from nodes
nodes.forEach((node) => {
if (node.flowNodeType !== FlowNodeTypeEnum.datasetSearchNode) return;

View File

@@ -57,3 +57,22 @@ export const getAppVersionById = async ({
// If the version does not exist, the latest version is returned
return getAppLatestVersion(appId, app);
};
export const checkIsLatestVersion = async ({
appId,
versionId
}: {
appId: string;
versionId: string;
}) => {
const version = await MongoAppVersion.findOne(
{
appId,
isPublish: true,
_id: { $gt: versionId }
},
'_id'
).lean();
return !version;
};

View File

@@ -723,8 +723,8 @@ async function streamResponse({
}
// Parse tool calls
if (responseChoice?.tool_calls?.length) {
responseChoice.tool_calls.forEach((toolCall) => {
const index = toolCall.index;
responseChoice.tool_calls.forEach((toolCall, i) => {
const index = toolCall.index ?? i;
// Call new tool
if (toolCall.id || callingTool) {

View File

@@ -464,7 +464,7 @@ async function getChatMessages({
aiChatQuoteRole: AiChatQuoteRoleType; // user: replace user prompt; system: replace system prompt
datasetQuotePrompt?: string;
datasetQuoteText: string;
version: string;
version?: string;
useDatasetQuote: boolean;
histories: ChatItemType[];

View File

@@ -11,6 +11,7 @@ import type {
SystemVariablesType
} from '@fastgpt/global/core/workflow/runtime/type';
import type { RuntimeNodeItemType } from '@fastgpt/global/core/workflow/runtime/type.d';
import type { FlowNodeOutputItemType } from '@fastgpt/global/core/workflow/type/io.d';
import type {
AIChatItemValueItemType,
ChatHistoryItemResType,
@@ -549,7 +550,7 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
// Skip some special key
if (
[NodeInputKeyEnum.childrenNodeIdList, NodeInputKeyEnum.httpJsonBody].includes(
input.key as any
input.key as NodeInputKeyEnum
)
) {
params[input.key] = input.value;