diff --git a/docSite/content/zh-cn/docs/development/upgrading/4811.md b/docSite/content/zh-cn/docs/development/upgrading/4811.md index bf4b38972a5..a30802178ed 100644 --- a/docSite/content/zh-cn/docs/development/upgrading/4811.md +++ b/docSite/content/zh-cn/docs/development/upgrading/4811.md @@ -95,17 +95,19 @@ weight: 813 7. 新增 - 支持 Openai o1 模型,需增加模型的 `defaultConfig` 配置,覆盖 `temperature`、`max_tokens` 和 `stream`配置,o1 不支持 stream 模式, 详细可重新拉取 `config.json` 配置文件查看。 8. 新增 - AI 对话节点知识库引用,支持配置 role=system 和 role=user,已配置的过自定义提示词的节点将会保持 user 模式,其余用户将转成 system 模式。 9. 新增 - 插件支持上传系统文件。 -10. 新增 - 插件输出,支持指定字段作为工具响应。 -11. 新增 - 支持工作流嵌套子应用时,可以设置`非流模式`,同时简易模式也可以选择工作流作为插件了,简易模式调用子应用时,都将强制使用非流模式。 -12. 新增 - 调试模式下,子应用调用,支持返回详细运行数据。 -13. 新增 - 保留所有模式下子应用嵌套调用的日志。 -14. 优化 - 工作流嵌套层级限制 20 层,避免因编排不合理导致的无限死循环。 -15. 优化 - 工作流 handler 性能优化。 -16. 优化 - 工作流快捷键,避免调试测试时也会触发复制和回退。 -17. 优化 - 流输出,切换浏览器 Tab 后仍可以继续输出。 -18. 优化 - 完善外部文件知识库相关 API -19. 修复 - 知识库选择权限问题。 -20. 修复 - 空 chatId 发起对话,首轮携带用户选择时会异常。 -21. 修复 - createDataset 接口,intro 为赋值。 -22. 修复 - 对话框渲染性能问题。 -23. 修复 - 工具调用历史记录存储不正确。 +10. 新增 - 子应用嵌套调用时,版本锁定。主应用未主动更新版本时,不会取最新版进行执行,保证主应用服务稳定。 +11. 新增 - 插件输出,支持指定字段作为工具响应。 +12. 新增 - 支持工作流嵌套子应用时,可以设置`非流模式`,同时简易模式也可以选择工作流作为插件了,简易模式调用子应用时,都将强制使用非流模式。 +13. 新增 - 调试模式下,子应用调用,支持返回详细运行数据。 +14. 新增 - 保留所有模式下子应用嵌套调用的日志。 +15. 优化 - 工作流嵌套层级限制 20 层,避免因编排不合理导致的无限死循环。 +16. 优化 - 工作流 handler 性能优化。 +17. 优化 - 工作流快捷键,避免调试测试时也会触发复制和回退。 +18. 修复 - 工作流工具调用中修改全局变量后,无法传递到后续流程。 +19. 优化 - 流输出,切换浏览器 Tab 后仍可以继续输出。 +20. 优化 - 完善外部文件知识库相关 API +21. 修复 - 知识库选择权限问题。 +22. 修复 - 空 chatId 发起对话,首轮携带用户选择时会异常。 +23. 修复 - createDataset 接口,intro 为赋值。 +24. 修复 - 对话框渲染性能问题。 +25. 修复 - 工具调用历史记录存储不正确。 diff --git a/packages/global/core/workflow/runtime/type.d.ts b/packages/global/core/workflow/runtime/type.d.ts index 68334c1bca4..bf0e40cc7cd 100644 --- a/packages/global/core/workflow/runtime/type.d.ts +++ b/packages/global/core/workflow/runtime/type.d.ts @@ -79,6 +79,7 @@ export type RuntimeNodeItemType = { outputs: FlowNodeOutputItemType[]; pluginId?: string; // workflow id / plugin id + version: string; }; export type PluginRuntimeType = { diff --git a/packages/global/core/workflow/runtime/utils.ts b/packages/global/core/workflow/runtime/utils.ts index 83c7859cac0..967e71e107b 100644 --- a/packages/global/core/workflow/runtime/utils.ts +++ b/packages/global/core/workflow/runtime/utils.ts @@ -124,7 +124,8 @@ export const storeNodes2RuntimeNodes = ( isEntry: entryNodeIds.includes(node.nodeId), inputs: node.inputs, outputs: node.outputs, - pluginId: node.pluginId + pluginId: node.pluginId, + version: node.version }; }) || [] ); diff --git a/packages/service/core/ai/rerank/index.ts b/packages/service/core/ai/rerank/index.ts index b7eb54588f7..0027fb82f3e 100644 --- a/packages/service/core/ai/rerank/index.ts +++ b/packages/service/core/ai/rerank/index.ts @@ -51,6 +51,7 @@ export function reRankRecall({ })); }) .catch((err) => { + console.log(err); addLog.error('rerank error', err); return []; diff --git a/packages/service/core/app/controller.ts b/packages/service/core/app/controller.ts index d8feb39dff8..75e26625593 100644 --- a/packages/service/core/app/controller.ts +++ b/packages/service/core/app/controller.ts @@ -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 = ({ @@ -46,30 +45,6 @@ export const beforeUpdateAppFormat = { - 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, diff --git a/packages/service/core/app/plugin/controller.ts b/packages/service/core/app/plugin/controller.ts index 14a808ae714..9b2e7d9a38f 100644 --- a/packages/service/core/app/plugin/controller.ts +++ b/packages/service/core/app/plugin/controller.ts @@ -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 => { - const { source, pluginId } = await splitCombinePluginId(id); +type ChildAppType = SystemPluginTemplateItemType & { teamId?: string }; +const getSystemPluginTemplateById = async ( + pluginId: string +): Promise => { + 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 { - 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 { - 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 { + 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, diff --git a/packages/service/core/app/version/controller.ts b/packages/service/core/app/version/controller.ts new file mode 100644 index 00000000000..936a3bb92b3 --- /dev/null +++ b/packages/service/core/app/version/controller.ts @@ -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); +}; diff --git a/packages/service/core/workflow/dispatch/agent/runTool/index.ts b/packages/service/core/workflow/dispatch/agent/runTool/index.ts index d429b09f815..72236ecdc8a 100644 --- a/packages/service/core/workflow/dispatch/agent/runTool/index.ts +++ b/packages/service/core/workflow/dispatch/agent/runTool/index.ts @@ -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 = props.variables; + const childToolResponse = dispatchFlowResponse + .map((item) => { + // Computed new variables + newVariables = { + ...newVariables, + ...item.newVariables + }; + + return item.flowResponses; + }) + .flat(); // concat tool usage const totalPointsUsage = diff --git a/packages/service/core/workflow/dispatch/loop/runLoop.ts b/packages/service/core/workflow/dispatch/loop/runLoop.ts index aed47541c83..350ba6c681c 100644 --- a/packages/service/core/workflow/dispatch/loop/runLoop.ts +++ b/packages/service/core/workflow/dispatch/loop/runLoop.ts @@ -38,7 +38,7 @@ export const dispatchLoop = async (props: Props): Promise => { const loopDetail: ChatHistoryItemResType[] = []; let assistantResponses: AIChatItemValueItemType[] = []; let totalPoints = 0; - let newVariables: Record = {}; + let newVariables: Record = props.variables; for await (const item of loopInputArray) { const response = await dispatchWorkFlow({ diff --git a/packages/service/core/workflow/dispatch/plugin/run.ts b/packages/service/core/workflow/dispatch/plugin/run.ts index 9c9c03f991c..19f53aed021 100644 --- a/packages/service/core/workflow/dispatch/plugin/run.ts +++ b/packages/service/core/workflow/dispatch/plugin/run.ts @@ -26,7 +26,7 @@ type RunPluginResponse = DispatchNodeResultType<{}>; export const dispatchRunPlugin = async (props: RunPluginProps): Promise => { 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 => { runningAppInfo, histories, query, - mode, - node: { pluginId }, + node: { pluginId: appId, version }, workflowStreamResponse, params, variables @@ -45,19 +44,23 @@ export const dispatchRunAppNode = async (props: Props): Promise => { 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?.({ diff --git a/packages/service/support/wallet/sub/schema.ts b/packages/service/support/wallet/sub/schema.ts index 25a9c155c8a..c731410fb38 100644 --- a/packages/service/support/wallet/sub/schema.ts +++ b/packages/service/support/wallet/sub/schema.ts @@ -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); } diff --git a/packages/web/i18n/en/app.json b/packages/web/i18n/en/app.json index 6462b2997bb..e611213b069 100644 --- a/packages/web/i18n/en/app.json +++ b/packages/web/i18n/en/app.json @@ -67,7 +67,6 @@ "logs_message_total": "Total Messages", "logs_title": "Title", "mark_count": "Number of Marked Answers", - "module.Confirm Sync": "Will update to the latest template configuration. Fields not in the template will be deleted (including all custom fields). It is recommended to copy a node first, then update the original node version.", "module.Custom Title Tip": "This title will be displayed during the conversation.", "module.No Modules": "No Plugins Found", "module.type": "\"{{type}}\" type\n{{description}}", diff --git a/packages/web/i18n/en/workflow.json b/packages/web/i18n/en/workflow.json index 30934e4441a..315ab92ad61 100644 --- a/packages/web/i18n/en/workflow.json +++ b/packages/web/i18n/en/workflow.json @@ -1,6 +1,7 @@ { "Array_element": "Array element", "Code": "Code", + "Confirm_sync_node": "It will be updated to the latest node configuration and fields that do not exist in the template will be deleted (including all custom fields).\n\nIf the fields are complex, it is recommended that you copy a node first and then update the original node to facilitate parameter copying.", "Quote_prompt_setting": "Quote prompt", "add_new_input": "Add New Input", "add_new_output": "New output", diff --git a/packages/web/i18n/zh/app.json b/packages/web/i18n/zh/app.json index 5b56f42f513..8e11b8a852f 100644 --- a/packages/web/i18n/zh/app.json +++ b/packages/web/i18n/zh/app.json @@ -67,7 +67,6 @@ "logs_message_total": "消息总数", "logs_title": "标题", "mark_count": "标注答案数量", - "module.Confirm Sync": "将会更新至最新的模板配置,不存在模板中的字段将会被删除(包括所有自定义字段),建议您先复制一份节点,再更新原来节点的版本。", "module.Custom Title Tip": "该标题名字会展示在对话过程中", "module.No Modules": "没找到插件", "module.type": "\"{{type}}\"类型\n{{description}}", diff --git a/packages/web/i18n/zh/workflow.json b/packages/web/i18n/zh/workflow.json index 753b3d669c2..cc878ae315e 100644 --- a/packages/web/i18n/zh/workflow.json +++ b/packages/web/i18n/zh/workflow.json @@ -1,6 +1,7 @@ { "Array_element": "数组元素", "Code": "代码", + "Confirm_sync_node": "将会更新至最新的节点配置,不存在模板中的字段将会被删除(包括所有自定义字段)。\n如果字段较为复杂,建议您先复制一份节点,再更新原来的节点,便于参数复制。", "Quote_prompt_setting": "引用提示词配置", "add_new_input": "新增输入", "add_new_output": "新增输出", diff --git a/projects/app/src/components/Select/I18nLngSelector.tsx b/projects/app/src/components/Select/I18nLngSelector.tsx index 42c34a3550b..18e5f17ccfe 100644 --- a/projects/app/src/components/Select/I18nLngSelector.tsx +++ b/projects/app/src/components/Select/I18nLngSelector.tsx @@ -24,9 +24,6 @@ const I18nLngSelector = () => { return ( { diff --git a/projects/app/src/pages/api/core/app/version/latest.ts b/projects/app/src/pages/api/core/app/version/latest.ts index df0e5e87b83..0669a823812 100644 --- a/projects/app/src/pages/api/core/app/version/latest.ts +++ b/projects/app/src/pages/api/core/app/version/latest.ts @@ -2,7 +2,7 @@ import type { ApiRequestProps, ApiResponseType } from '@fastgpt/service/type/nex import { NextAPI } from '@/service/middleware/entry'; import { authApp } from '@fastgpt/service/support/permission/app/auth'; import { WritePermissionVal } from '@fastgpt/global/support/permission/constant'; -import { getAppLatestVersion } from '@fastgpt/service/core/app/controller'; +import { getAppLatestVersion } from '@fastgpt/service/core/app/version/controller'; import { AppChatConfigType } from '@fastgpt/global/core/app/type'; import { StoreEdgeItemType } from '@fastgpt/global/core/workflow/type/edge'; import { StoreNodeItemType } from '@fastgpt/global/core/workflow/type/node'; diff --git a/projects/app/src/pages/api/core/app/version/publish.ts b/projects/app/src/pages/api/core/app/version/publish.ts index 47fe70e2df1..44273342032 100644 --- a/projects/app/src/pages/api/core/app/version/publish.ts +++ b/projects/app/src/pages/api/core/app/version/publish.ts @@ -21,7 +21,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse): Promise< versionName } = req.body as PostPublishAppProps; - const { app, tmbId } = await authApp({ appId, req, per: WritePermissionVal, authToken: true }); + const { tmbId } = await authApp({ appId, req, per: WritePermissionVal, authToken: true }); const { nodes: formatNodes } = beforeUpdateAppFormat({ nodes }); diff --git a/projects/app/src/pages/api/core/chat/init.ts b/projects/app/src/pages/api/core/chat/init.ts index 2f96ca3ace0..d0b1a581e39 100644 --- a/projects/app/src/pages/api/core/chat/init.ts +++ b/projects/app/src/pages/api/core/chat/init.ts @@ -6,7 +6,7 @@ import { getChatModelNameListByModules } from '@/service/core/app/workflow'; import type { InitChatProps, InitChatResponse } from '@/global/core/chat/api.d'; import { MongoChat } from '@fastgpt/service/core/chat/chatSchema'; import { ChatErrEnum } from '@fastgpt/global/common/error/code/chat'; -import { getAppLatestVersion } from '@fastgpt/service/core/app/controller'; +import { getAppLatestVersion } from '@fastgpt/service/core/app/version/controller'; import { NextAPI } from '@/service/middleware/entry'; import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant'; import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant'; @@ -15,7 +15,7 @@ async function handler( req: NextApiRequest, res: NextApiResponse ): Promise { - let { appId, chatId, loadCustomFeedbacks } = req.query as InitChatProps; + let { appId, chatId } = req.query as InitChatProps; if (!appId) { return jsonRes(res, { diff --git a/projects/app/src/pages/api/core/chat/outLink/init.ts b/projects/app/src/pages/api/core/chat/outLink/init.ts index cfa9e24012f..fa78d67c70f 100644 --- a/projects/app/src/pages/api/core/chat/outLink/init.ts +++ b/projects/app/src/pages/api/core/chat/outLink/init.ts @@ -9,7 +9,7 @@ import { MongoApp } from '@fastgpt/service/core/app/schema'; import { AppErrEnum } from '@fastgpt/global/common/error/code/app'; import { MongoChat } from '@fastgpt/service/core/chat/chatSchema'; import { ChatErrEnum } from '@fastgpt/global/common/error/code/chat'; -import { getAppLatestVersion } from '@fastgpt/service/core/app/controller'; +import { getAppLatestVersion } from '@fastgpt/service/core/app/version/controller'; import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant'; import { NextAPI } from '@/service/middleware/entry'; diff --git a/projects/app/src/pages/api/core/chat/team/init.ts b/projects/app/src/pages/api/core/chat/team/init.ts index 17079d97894..32bdd1976b9 100644 --- a/projects/app/src/pages/api/core/chat/team/init.ts +++ b/projects/app/src/pages/api/core/chat/team/init.ts @@ -9,7 +9,7 @@ import { AppErrEnum } from '@fastgpt/global/common/error/code/app'; import { authTeamSpaceToken } from '@/service/support/permission/auth/team'; import { MongoTeam } from '@fastgpt/service/support/user/team/teamSchema'; import { ChatErrEnum } from '@fastgpt/global/common/error/code/chat'; -import { getAppLatestVersion } from '@fastgpt/service/core/app/controller'; +import { getAppLatestVersion } from '@fastgpt/service/core/app/version/controller'; import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant'; import { NextAPI } from '@/service/middleware/entry'; diff --git a/projects/app/src/pages/api/v1/chat/completions.ts b/projects/app/src/pages/api/v1/chat/completions.ts index 0b5e8ca4e55..3d4d3e67ddb 100644 --- a/projects/app/src/pages/api/v1/chat/completions.ts +++ b/projects/app/src/pages/api/v1/chat/completions.ts @@ -46,7 +46,7 @@ import { AIChatItemType, UserChatItemType } from '@fastgpt/global/core/chat/type import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants'; import { NextAPI } from '@/service/middleware/entry'; -import { getAppLatestVersion } from '@fastgpt/service/core/app/controller'; +import { getAppLatestVersion } from '@fastgpt/service/core/app/version/controller'; import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant'; import { AppTypeEnum } from '@fastgpt/global/core/app/constants'; import { diff --git a/projects/app/src/pages/app/detail/components/Workflow/components/SaveButton.tsx b/projects/app/src/pages/app/detail/components/Workflow/components/SaveButton.tsx index 7caedfe545a..e84175f4ab3 100644 --- a/projects/app/src/pages/app/detail/components/Workflow/components/SaveButton.tsx +++ b/projects/app/src/pages/app/detail/components/Workflow/components/SaveButton.tsx @@ -72,7 +72,8 @@ const SaveButton = ({ toast({ status: 'success', title: t('app:saved_success'), - position: 'top-right' + position: 'top-right', + isClosable: true }); onClose(); setIsSave(false); diff --git a/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/render/NodeCard.tsx b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/render/NodeCard.tsx index 88dadc3cfe8..cb5997c07e1 100644 --- a/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/render/NodeCard.tsx +++ b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/render/NodeCard.tsx @@ -92,10 +92,6 @@ const NodeCard = (props: Props) => { return { node, parentNode }; }, [nodeList, nodeId]); - const { openConfirm: onOpenConfirmSync, ConfirmModal: ConfirmSyncModal } = useConfirm({ - content: t('app:module.Confirm Sync') - }); - const { data: nodeTemplate, runAsync: getNodeLatestTemplate } = useRequest2( async () => { if ( @@ -125,6 +121,10 @@ const NodeCard = (props: Props) => { manual: false } ); + + const { openConfirm: onOpenConfirmSync, ConfirmModal: ConfirmSyncModal } = useConfirm({ + content: t('workflow:Confirm_sync_node') + }); const hasNewVersion = nodeTemplate && nodeTemplate.version !== node?.version; const { runAsync: onClickSyncVersion } = useRequest2( @@ -264,7 +264,6 @@ const NodeCard = (props: Props) => { - ); }, [ @@ -282,11 +281,11 @@ const NodeCard = (props: Props) => { menuForbid, nodeList, intro, - ConfirmSyncModal, onChangeNode, onOpenCustomTitleModal, toast ]); + const RenderHandle = useMemo(() => { return ( <> @@ -342,6 +341,7 @@ const NodeCard = (props: Props) => { {RenderHandle} {RenderToolHandle} + ); @@ -384,7 +384,12 @@ const MenuRender = React.memo(function MenuRender({ pluginId: node.data.pluginId, version: node.data.version }; - return state.concat( + + return [ + ...state.map((item) => ({ + ...item, + selected: false + })), storeNode2FlowNode({ item: { flowNodeType: template.flowNodeType, @@ -403,7 +408,7 @@ const MenuRender = React.memo(function MenuRender({ parentNodeId: undefined, t }) - ); + ]; }); }, [computedNewNodeName, setNodes, t] diff --git a/projects/app/src/pages/login/index.tsx b/projects/app/src/pages/login/index.tsx index 6c27d44d07a..1a8a1888ab9 100644 --- a/projects/app/src/pages/login/index.tsx +++ b/projects/app/src/pages/login/index.tsx @@ -55,17 +55,6 @@ const Login = ({ ChineseRedirectUrl }: { ChineseRedirectUrl: string }) => { defaultValue: true }); - const checkIpInChina = useCallback( - () => - GET(ipDetectURL).then((res: any) => { - const country = res?.country; - if (country && country === '中国' && res.city !== '中国香港') { - onOpenRedirect(); - } - }), - [onOpenRedirect] - ); - const loginSuccess = useCallback( (res: ResLogin) => { // init store @@ -101,10 +90,27 @@ const Login = ({ ChineseRedirectUrl }: { ChineseRedirectUrl: string }) => { ); }, [feConfigs.oauth]); + const checkIpInChina = useCallback(async () => { + try { + const res = await GET(ipDetectURL); + const country = res?.country; + if ( + country && + country === '中国' && + res.prov !== '中国香港' && + res.prov !== '中国澳门' && + res.prov !== '中国台湾' + ) { + onOpenRedirect(); + } + } catch (error) { + console.log(error); + } + }, [onOpenRedirect]); useMount(() => { clearToken(); - ChineseRedirectUrl && showRedirect && checkIpInChina(); router.prefetch('/app/list'); + ChineseRedirectUrl && showRedirect && checkIpInChina(); }); return ( diff --git a/projects/app/src/service/core/app/workflow.ts b/projects/app/src/service/core/app/workflow.ts index d227a7c4e82..1940605240d 100644 --- a/projects/app/src/service/core/app/workflow.ts +++ b/projects/app/src/service/core/app/workflow.ts @@ -2,10 +2,12 @@ import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants'; import type { StoreNodeItemType } from '@fastgpt/global/core/workflow/type/node.d'; export const getChatModelNameListByModules = (nodes: StoreNodeItemType[]): string[] => { - return nodes + const modelList = nodes .map((item) => { const model = item.inputs.find((input) => input.key === NodeInputKeyEnum.aiModel)?.value; return global.llmModels.find((item) => item.model === model)?.name || ''; }) .filter(Boolean); + + return Array.from(new Set(modelList)); }; diff --git a/projects/app/src/types/index.d.ts b/projects/app/src/types/index.d.ts index f388be3508a..f96bb1827e1 100644 --- a/projects/app/src/types/index.d.ts +++ b/projects/app/src/types/index.d.ts @@ -22,7 +22,7 @@ export type RequestPaging = { pageNum: number; pageSize: number; [key]: any }; declare global { var qaQueueLen: number; var vectorQueueLen: number; - var geoip2: any; + interface Window { grecaptcha: any; QRCode: any; diff --git a/projects/app/src/web/core/app/utils.ts b/projects/app/src/web/core/app/utils.ts index e035a2a5ae9..92d7a3d72ff 100644 --- a/projects/app/src/web/core/app/utils.ts +++ b/projects/app/src/web/core/app/utils.ts @@ -7,6 +7,7 @@ import { import { StoreNodeItemType } from '@fastgpt/global/core/workflow/type/node.d'; import { chatHistoryValueDesc, + defaultNodeVersion, FlowNodeInputTypeEnum, FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant'; @@ -195,7 +196,7 @@ export function form2AppWorkflow( x: 918.5901682164496, y: -227.11542247619582 }, - version: '481', + version: DatasetSearchModule.version, inputs: [ { key: 'datasets', @@ -377,7 +378,8 @@ export function form2AppWorkflow( x: 500 + 500 * (i + 1), y: 545 }, - version: tool.version, + // 这里不需要固定版本,给一个不存在的版本,每次都会用最新版 + version: defaultNodeVersion, inputs: tool.inputs.map((input) => { // Special key value if (input.key === NodeInputKeyEnum.forbidStream) { diff --git a/python/suryaocr/Dockerfile b/python/ocr/surya/Dockerfile similarity index 100% rename from python/suryaocr/Dockerfile rename to python/ocr/surya/Dockerfile diff --git a/python/ocr/surya/README.md b/python/ocr/surya/README.md new file mode 100644 index 00000000000..c22806175e1 --- /dev/null +++ b/python/ocr/surya/README.md @@ -0,0 +1,110 @@ +# 接入Surya OCR文本检测 + +## 源码部署 + +### 1. 安装环境 + +- Python 3.9+ +- CUDA 11.8 +- 科学上网环境 + +### 2. 安装依赖 + +```bash +pip install -r requirements.txt +``` + +### 3. 下载模型 + +代码首次运行时会自动从huggingface下载模型,可跳过以下步骤。 +也可以手动下载模型,在对应代码目录下clone模型 + +```sh +mkdir vikp && cd vikp + +git lfs install + +git clone https://huggingface.co/vikp/surya_det3 +# 镜像下载 https://hf-mirror.com/vikp/surya_det3 + +git clone https://huggingface.co/vikp/surya_rec2 +# 镜像下载 https://hf-mirror.com/vikp/surya_rec2 +``` + +最终手动下载的目录结构如下: + +``` +vikp/surya_det3 +vikp/surya_rec2 +app.py +Dockerfile +requirements.txt +``` + +### 4. 运行代码 + +```bash +python app.py +``` + +对应请求地址为 +`http://0.0.0.0:7230/v1/ocr/text` + +### 5. 测试 + +```python +curl --location --request POST 'http://localhost:7230/v1/ocr/text' \ +--header 'Authorization: Bearer your_access_token' \ +--header 'User-Agent: Apifox/1.0.0 (https://apifox.com)' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "images":[ + "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94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94dx7w7gZf7w7j3h3MQ94d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" + ], + "sort": true +}' +``` + +## docker部署 + +### 镜像获取 + +**本地编译镜像:** +```bash +docker build -t surya_ocr:v0.1 . +``` + +**或拉取线上镜像:** +Todo:待发布 + +### docker-compose.yml示例 +```yaml +version: '3' +services: + surya-ocr: + image: surya_ocr:v0.1 + container_name: surya-ocr + # GPU运行环境,如果宿主机未安装,将deploy配置隐藏即可 + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: all + capabilities: [gpu] + ports: + - 7230:7230 + environment: + - BATCH_SIZE=32 + - ACCESS_TOKEN=YOUR_ACCESS_TOKEN + - LANGS='["zh","en"]' +``` + +**环境变量:** + +``` +BATCH_SIZE:根据实际内存/显存情况配置,每个batch约占用40MB的VRAM,cpu默认32,mps默认64,cuda默认512 +ACCESS_TOKEN:服务的access_token +LANGS:支持的语言列表,默认["zh","en"] +``` + diff --git a/python/suryaocr/app.py b/python/ocr/surya/app.py similarity index 75% rename from python/suryaocr/app.py rename to python/ocr/surya/app.py index 59384ee8c80..f6326beb4fc 100644 --- a/python/suryaocr/app.py +++ b/python/ocr/surya/app.py @@ -19,7 +19,8 @@ from surya.model.recognition.processor import load_processor as load_rec_processor from surya.ocr import run_ocr from surya.schema import OCRResult - +import warnings +warnings.filterwarnings("ignore", category=FutureWarning, module="transformers") app = FastAPI() security = HTTPBearer() env_bearer_token = None @@ -100,40 +101,53 @@ def sort_text_by_bbox(original_data: List[dict]) -> str: return string_result def query_ocr(self, image_base64: str, - sorted: bool) -> List[OCRResult] | str: + sorted: bool) -> str: if image_base64 is None or len(image_base64) == 0: - return [] - image = Chat.base64_to_image(image_base64) - - ocr_result = self.surya.run(image) - result = [] - - for text_line in ocr_result[0].text_lines: - result.append({"text": text_line.text, "bbox": text_line.bbox}) - if sorted: - result = Chat.sort_text_by_bbox(result) - - torch_gc() - return result - - -@app.post('/v1/surya_ocr') + return "" + try: + image = Chat.base64_to_image(image_base64) + ocr_result = self.surya.run(image) + result = [] + + for text_line in ocr_result[0].text_lines: + result.append(text_line.text) + + if sorted: + result = self.sort_text_lines(result) + + # 将所有文本行合并成一个字符串,用换行符分隔 + final_result = "\n".join(result) + + torch_gc() + return final_result + except Exception as e: + logging.error(f"OCR 处理失败: {e}") + raise HTTPException(status_code=400, detail=f"OCR 处理失败: {str(e)}") + + @staticmethod + def sort_text_lines(text_lines: List[str]) -> List[str]: + # 这里可以实现自定义的排序逻辑 + # 目前只是简单地返回原始列表,因为我们没有位置信息来进行排序 + return text_lines + +@app.post('/v1/ocr/text') async def handle_post_request( image_req: ImageReq, credentials: HTTPAuthorizationCredentials = Security(security)): token = credentials.credentials if env_bearer_token is not None and token != env_bearer_token: - raise HTTPException(status_code=401, detail="Invalid token") + raise HTTPException(status_code=401, detail="无效的令牌") chat = Chat() try: results = [] for image_base64 in image_req.images: results.append(chat.query_ocr(image_base64, image_req.sorted)) - return {"error": "success", "results": results} + return {"error": None, "results": results} + except HTTPException as he: + raise he except Exception as e: logging.error(f"识别报错:{e}") - return {"error": "识别出错"} - + raise HTTPException(status_code=500, detail=f"识别出错: {str(e)}") if __name__ == "__main__": env_bearer_token = os.getenv("ACCESS_TOKEN") diff --git a/python/suryaocr/requirements.txt b/python/ocr/surya/requirements.txt similarity index 100% rename from python/suryaocr/requirements.txt rename to python/ocr/surya/requirements.txt diff --git a/python/suryaocr/README.md b/python/suryaocr/README.md deleted file mode 100644 index 0029ed07c4a..00000000000 --- a/python/suryaocr/README.md +++ /dev/null @@ -1,120 +0,0 @@ -# 接入Surya OCR文本检测 - -## 源码部署 - -### 1. 安装环境 - -- Python 3.9+ -- CUDA 11.8 -- 科学上网环境 - -### 2. 安装依赖 - -```bash -pip install -r requirements.txt -``` - -### 3. 下载模型 - -代码首次运行时会自动从huggingface下载模型,可跳过以下步骤。 -也可以手动下载模型,在对应代码目录下clone模型 - -```sh -mkdir vikp && cd vikp - -git lfs install - -git clone https://huggingface.co/vikp/surya_det3 -# 镜像下载 https://hf-mirror.com/vikp/surya_det3 - -git clone https://huggingface.co/vikp/surya_rec2 -# 镜像下载 https://hf-mirror.com/vikp/surya_rec2 -``` - -最终手动下载的目录结构如下: - -``` -vikp/surya_det3 -vikp/surya_rec2 -app.py -Dockerfile -requirements.txt -``` - -### 4. 运行代码 - -```bash -python app.py -``` - -对应请求地址为 -`http://0.0.0.0:7230/v1/surya_ocr` - -### 5. 测试 - -```python -import requests -import base64 - -IMAGE_PATH = "your/path/to/image.png" -ACCESS_TOKEN = "your_access_token" - -with open(IMAGE_PATH, 'rb') as img_file: - encoded_string = base64.b64encode(img_file.read()) - encoded_image = encoded_string.decode('utf-8') -data = {"images": [encoded_image], "sorted": True} -headers = { - "Content-Type": "application/json", - "Authorization": f"Bearer {ACCESS_TOKEN}" -} -res = requests.post(url="http://0.0.0.0:7230/v1/surya_ocr", - headers=headers, - json=data) - -print(res.text) -``` - -## docker部署 - -### 镜像获取 - -**本地编译镜像:** -```bash -docker build -t surya_ocr:v0.1 . -``` - -**或拉取线上镜像:** -Todo:待发布 - -### docker-compose.yml示例 -```yaml -version: '3' -services: - surya-ocr: - image: surya_ocr:v0.1 - container_name: surya-ocr - # GPU运行环境,如果宿主机未安装,将deploy配置隐藏即可 - deploy: - resources: - reservations: - devices: - - driver: nvidia - count: all - capabilities: [gpu] - ports: - - 7230:7230 - environment: - - BATCH_SIZE=32 - - ACCESS_TOKEN=YOUR_ACCESS_TOKEN - - LANGS='["zh","en"]' -``` -**环境变量:** -``` -BATCH_SIZE:根据实际内存/显存情况配置,每个batch约占用40MB的VRAM,cpu默认32,mps默认64,cuda默认512 -ACCESS_TOKEN:服务的access_token -LANGS:支持的语言列表,默认["zh","en"] -``` - -## 接入FastGPT - -Todo: 待补充 \ No newline at end of file