diff --git a/packages/global/core/chat/adapt.ts b/packages/global/core/chat/adapt.ts index d13980c30e92..0426f617aab4 100644 --- a/packages/global/core/chat/adapt.ts +++ b/packages/global/core/chat/adapt.ts @@ -151,12 +151,23 @@ export const GPTMessages2Chats = ( obj === ChatRoleEnum.System && item.role === ChatCompletionRequestMessageRoleEnum.System ) { - value.push({ - type: ChatItemValueTypeEnum.text, - text: { - content: item.content - } - }); + if (Array.isArray(item.content)) { + item.content.forEach((item) => [ + value.push({ + type: ChatItemValueTypeEnum.text, + text: { + content: item.text + } + }) + ]); + } else { + value.push({ + type: ChatItemValueTypeEnum.text, + text: { + content: item.content + } + }); + } } else if ( obj === ChatRoleEnum.Human && item.role === ChatCompletionRequestMessageRoleEnum.User diff --git a/packages/global/core/workflow/runtime/type.d.ts b/packages/global/core/workflow/runtime/type.d.ts index d164d3f5b7ff..2de90ada4ed6 100644 --- a/packages/global/core/workflow/runtime/type.d.ts +++ b/packages/global/core/workflow/runtime/type.d.ts @@ -26,10 +26,15 @@ export type ChatDispatchProps = { res?: NextApiResponse; requestOrigin?: string; mode: 'test' | 'chat' | 'debug'; - teamId: string; // App teamId - tmbId: string; // App tmbId user: UserModelSchema; - app: AppDetailType | AppSchema; + + runningAppInfo: { + id: string; // May be the id of the system plug-in (cannot be used directly to look up the table) + teamId: string; + tmbId: string; // App tmbId + }; + uid: string; // Who run this workflow + chatId?: string; responseChatItemId?: string; histories: ChatItemType[]; @@ -50,10 +55,12 @@ export type ModuleDispatchProps = ChatDispatchProps & { }; export type SystemVariablesType = { + userId: string; appId: string; chatId?: string; responseChatItemId?: string; histories: ChatItemType[]; + cTime: string; }; /* node props */ @@ -69,7 +76,7 @@ export type RuntimeNodeItemType = { inputs: FlowNodeInputItemType[]; outputs: FlowNodeOutputItemType[]; - pluginId?: string; + pluginId?: string; // workflow id / plugin id }; export type PluginRuntimeType = { diff --git a/packages/global/core/workflow/template/constants.ts b/packages/global/core/workflow/template/constants.ts index b39030942943..2d2dcb038fc4 100644 --- a/packages/global/core/workflow/template/constants.ts +++ b/packages/global/core/workflow/template/constants.ts @@ -17,7 +17,7 @@ import { RunAppModule } from './system/abandoned/runApp/index'; import { PluginInputModule } from './system/pluginInput'; import { PluginOutputModule } from './system/pluginOutput'; import { RunPluginModule } from './system/runPlugin'; -import { RunAppPluginModule } from './system/runAppPlugin'; +import { RunAppNode } from './system/runApp'; import { AiQueryExtension } from './system/queryExtension'; import type { FlowNodeTemplateType } from '../type/node'; @@ -73,6 +73,6 @@ export const moduleTemplatesFlat: FlowNodeTemplateType[] = [ ), EmptyNode, RunPluginModule, - RunAppPluginModule, + RunAppNode, RunAppModule ]; diff --git a/packages/global/core/workflow/template/system/runAppPlugin.ts b/packages/global/core/workflow/template/system/runApp.ts similarity index 91% rename from packages/global/core/workflow/template/system/runAppPlugin.ts rename to packages/global/core/workflow/template/system/runApp.ts index cdf724661e4d..fa1eb0e38c6d 100644 --- a/packages/global/core/workflow/template/system/runAppPlugin.ts +++ b/packages/global/core/workflow/template/system/runApp.ts @@ -3,7 +3,7 @@ import { FlowNodeTypeEnum } from '../../node/constant'; import { FlowNodeTemplateType } from '../../type/node'; import { getHandleConfig } from '../utils'; -export const RunAppPluginModule: FlowNodeTemplateType = { +export const RunAppNode: FlowNodeTemplateType = { id: FlowNodeTypeEnum.appModule, templateType: FlowNodeTemplateTypeEnum.other, flowNodeType: FlowNodeTypeEnum.appModule, diff --git a/packages/global/core/workflow/utils.ts b/packages/global/core/workflow/utils.ts index 323ebafdd474..43661656d447 100644 --- a/packages/global/core/workflow/utils.ts +++ b/packages/global/core/workflow/utils.ts @@ -326,27 +326,6 @@ export const updatePluginInputByVariables = ( ); }; -/* Remove pluginInput variables from global variables - (completions api: Plugin input get value from global variables) -*/ -export const removePluginInputVariables = ( - variables: Record, - nodes: RuntimeNodeItemType[] -) => { - const pluginInputNode = nodes.find((node) => node.flowNodeType === FlowNodeTypeEnum.pluginInput); - - if (!pluginInputNode) return variables; - return Object.keys(variables).reduce( - (acc, key) => { - if (!pluginInputNode.inputs.find((input) => input.key === key)) { - acc[key] = variables[key]; - } - return acc; - }, - {} as Record - ); -}; - // replace {{$xx.xx$}} variables for text export function replaceEditorVariable({ text, diff --git a/packages/global/package.json b/packages/global/package.json index ca6a5cf50b52..6852d7777b15 100644 --- a/packages/global/package.json +++ b/packages/global/package.json @@ -11,7 +11,7 @@ "jschardet": "3.1.1", "nanoid": "^4.0.1", "next": "14.2.5", - "openai": "4.53.0", + "openai": "4.57.0", "openapi-types": "^12.1.3", "timezones-list": "^3.0.2" }, diff --git a/packages/service/core/chat/utils.ts b/packages/service/core/chat/utils.ts index a01999781462..7e9725b4a6c0 100644 --- a/packages/service/core/chat/utils.ts +++ b/packages/service/core/chat/utils.ts @@ -121,46 +121,22 @@ export const loadRequestMessages = async ({ const imageRegex = /(https?:\/\/[^\s/$.?#].[^\s]*\.(?:png|jpe?g|gif|webp|bmp|tiff?|svg|ico|heic|avif))/i; - const result: { type: 'text' | 'image'; value: string }[] = []; - let lastIndex = 0; - let match; - - // 使用正则表达式查找所有匹配项 - while ((match = imageRegex.exec(input.slice(lastIndex))) !== null) { - const textBefore = input.slice(lastIndex, lastIndex + match.index); - - // 如果图片URL前有文本,添加文本部分 - if (textBefore) { - result.push({ type: 'text', value: textBefore }); - } - - // 添加图片URL - result.push({ type: 'image', value: match[0] }); - - lastIndex += match.index + match[0].length; - } - - // 添加剩余的文本(如果有的话) - if (lastIndex < input.length) { - result.push({ type: 'text', value: input.slice(lastIndex) }); - } - - return result - .map((item) => { - if (item.type === 'text') { - return { type: 'text', text: item.value }; - } - if (item.type === 'image') { - return { - type: 'image_url', - image_url: { - url: item.value - } - }; + const result: ChatCompletionContentPart[] = []; + + // 提取所有HTTPS图片URL并添加到result开头 + const httpsImages = input.match(imageRegex) || []; + httpsImages.forEach((url) => { + result.push({ + type: 'image_url', + image_url: { + url: url } - return { type: 'text', text: item.value }; - }) - .filter(Boolean) as ChatCompletionContentPart[]; + }); + }); + + // 添加原始input作为文本 + result.push({ type: 'text', text: input }); + return result; } // Load image const parseUserContent = async (content: string | ChatCompletionContentPart[]) => { diff --git a/packages/service/core/workflow/dispatch/abandoned/runApp.ts b/packages/service/core/workflow/dispatch/abandoned/runApp.ts index 48fc74415ad7..a8fb32ef8257 100644 --- a/packages/service/core/workflow/dispatch/abandoned/runApp.ts +++ b/packages/service/core/workflow/dispatch/abandoned/runApp.ts @@ -31,7 +31,7 @@ type Response = DispatchNodeResultType<{ export const dispatchAppRequest = async (props: Props): Promise => { const { - app: workflowApp, + runningAppInfo, workflowStreamResponse, histories, query, @@ -45,7 +45,7 @@ export const dispatchAppRequest = async (props: Props): Promise => { // 检查该工作流的tmb是否有调用该app的权限(不是校验对话的人,是否有权限) const { app: appData } = await authAppByTmbId({ appId: app.id, - tmbId: workflowApp.tmbId, + tmbId: runningAppInfo.tmbId, per: ReadPermissionVal }); @@ -61,7 +61,11 @@ export const dispatchAppRequest = async (props: Props): Promise => { const { flowResponses, flowUsages, assistantResponses } = await dispatchWorkFlow({ ...props, - app: appData, + runningAppInfo: { + id: String(appData._id), + teamId: String(appData.teamId), + tmbId: String(appData.tmbId) + }, runtimeNodes: storeNodes2RuntimeNodes( appData.modules, getWorkflowEntryNodeIds(appData.modules) diff --git a/packages/service/core/workflow/dispatch/dataset/search.ts b/packages/service/core/workflow/dispatch/dataset/search.ts index c5abff3c30bb..04f119527a6f 100644 --- a/packages/service/core/workflow/dispatch/dataset/search.ts +++ b/packages/service/core/workflow/dispatch/dataset/search.ts @@ -37,7 +37,7 @@ export async function dispatchDatasetSearch( props: DatasetSearchProps ): Promise { const { - teamId, + runningAppInfo: { teamId }, histories, node, params: { diff --git a/packages/service/core/workflow/dispatch/index.ts b/packages/service/core/workflow/dispatch/index.ts index b4238d14200b..c4f97e1c1574 100644 --- a/packages/service/core/workflow/dispatch/index.ts +++ b/packages/service/core/workflow/dispatch/index.ts @@ -6,7 +6,8 @@ import { import { NodeOutputKeyEnum } from '@fastgpt/global/core/workflow/constants'; import type { ChatDispatchProps, - ModuleDispatchProps + ModuleDispatchProps, + SystemVariablesType } from '@fastgpt/global/core/workflow/runtime/type'; import type { RuntimeNodeItemType } from '@fastgpt/global/core/workflow/runtime/type.d'; import type { @@ -554,13 +555,15 @@ export async function dispatchWorkFlow(data: Props): Promise => { const { workflowStreamResponse, - app: { _id: appId }, + runningAppInfo: { id: appId }, chatId, node: { nodeId, isEntry }, params: { description, userSelectOptions }, diff --git a/packages/service/core/workflow/dispatch/plugin/run.ts b/packages/service/core/workflow/dispatch/plugin/run.ts index c9354d4961d3..9dccc4bad98b 100644 --- a/packages/service/core/workflow/dispatch/plugin/run.ts +++ b/packages/service/core/workflow/dispatch/plugin/run.ts @@ -13,6 +13,7 @@ import { authPluginByTmbId } from '../../../../support/permission/app/auth'; import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant'; import { computedPluginUsage } from '../../../app/plugin/utils'; import { filterSystemVariables } from '../utils'; +import { getPluginRunUserQuery } from '../../utils'; type RunPluginProps = ModuleDispatchProps<{ [key: string]: any; @@ -22,9 +23,8 @@ type RunPluginResponse = DispatchNodeResultType<{}>; export const dispatchRunPlugin = async (props: RunPluginProps): Promise => { const { node: { pluginId }, - app: workflowApp, + runningAppInfo, mode, - teamId, params: data // Plugin input } = props; @@ -33,9 +33,9 @@ export const dispatchRunPlugin = async (props: RunPluginProps): Promise { const filterArr = [FlowNodeTypeEnum.pluginOutput]; return !filterArr.includes(item.moduleType as any); diff --git a/packages/service/core/workflow/dispatch/plugin/runApp.ts b/packages/service/core/workflow/dispatch/plugin/runApp.ts index 90e75abc0b6c..4280ead74643 100644 --- a/packages/service/core/workflow/dispatch/plugin/runApp.ts +++ b/packages/service/core/workflow/dispatch/plugin/runApp.ts @@ -16,6 +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'; type Props = ModuleDispatchProps<{ [NodeInputKeyEnum.userChatInput]: string; @@ -29,7 +30,7 @@ type Response = DispatchNodeResultType<{ export const dispatchRunAppNode = async (props: Props): Promise => { const { - app: workflowApp, + runningAppInfo, histories, query, node: { pluginId }, @@ -49,9 +50,10 @@ export const dispatchRunAppNode = async (props: Props): Promise => { // Auth the app by tmbId(Not the user, but the workflow user) const { app: appData } = await authAppByTmbId({ appId: pluginId, - tmbId: workflowApp.tmbId, + tmbId: runningAppInfo.tmbId, per: ReadPermissionVal }); + const { nodes, edges, chatConfig } = await getAppLatestVersion(pluginId); // Auto line workflowStreamResponse?.({ @@ -64,27 +66,31 @@ export const dispatchRunAppNode = async (props: Props): Promise => { const chatHistories = getHistories(history, histories); const { files } = chatValue2RuntimePrompt(query); - // Concat variables + // Rewrite children app variables const systemVariables = filterSystemVariables(variables); const childrenRunVariables = { ...systemVariables, - ...childrenAppVariables + ...childrenAppVariables, + histories: chatHistories, + appId: String(appData._id) }; const { flowResponses, flowUsages, assistantResponses } = await dispatchWorkFlow({ ...props, - app: appData, - runtimeNodes: storeNodes2RuntimeNodes( - appData.modules, - getWorkflowEntryNodeIds(appData.modules) - ), - runtimeEdges: initWorkflowEdgeStatus(appData.edges), + runningAppInfo: { + id: String(appData._id), + teamId: String(appData.teamId), + tmbId: String(appData.tmbId) + }, + runtimeNodes: storeNodes2RuntimeNodes(nodes, getWorkflowEntryNodeIds(nodes)), + runtimeEdges: initWorkflowEdgeStatus(edges), histories: chatHistories, + variables: childrenRunVariables, query: runtimePrompt2ChatsValue({ files, text: userChatInput }), - variables: childrenRunVariables + chatConfig }); const completeMessages = chatHistories.concat([ diff --git a/packages/service/core/workflow/dispatch/tools/customFeedback.ts b/packages/service/core/workflow/dispatch/tools/customFeedback.ts index 4d17b4295c0e..a4a46833a579 100644 --- a/packages/service/core/workflow/dispatch/tools/customFeedback.ts +++ b/packages/service/core/workflow/dispatch/tools/customFeedback.ts @@ -15,7 +15,7 @@ type Response = DispatchNodeResultType<{}>; export const dispatchCustomFeedback = (props: Record): Response => { const { - app: { _id: appId }, + runningAppInfo: { id: appId }, chatId, responseChatItemId: chatItemId, stream, diff --git a/packages/service/core/workflow/dispatch/tools/http468.ts b/packages/service/core/workflow/dispatch/tools/http468.ts index 4ad678cc6ed2..c0e9fdc157c1 100644 --- a/packages/service/core/workflow/dispatch/tools/http468.ts +++ b/packages/service/core/workflow/dispatch/tools/http468.ts @@ -42,7 +42,7 @@ const UNDEFINED_SIGN = 'UNDEFINED_SIGN'; export const dispatchHttp468Request = async (props: HttpRequestProps): Promise => { let { - app: { _id: appId }, + runningAppInfo: { id: appId }, chatId, responseChatItemId, variables, diff --git a/packages/service/core/workflow/dispatch/tools/readFiles.ts b/packages/service/core/workflow/dispatch/tools/readFiles.ts index ce5401c16f21..cdf46f62399f 100644 --- a/packages/service/core/workflow/dispatch/tools/readFiles.ts +++ b/packages/service/core/workflow/dispatch/tools/readFiles.ts @@ -44,7 +44,7 @@ ${content.slice(0, 100)}${content.length > 100 ? '......' : ''} export const dispatchReadFiles = async (props: Props): Promise => { const { requestOrigin, - teamId, + runningAppInfo: { teamId }, histories, chatConfig, params: { fileUrlList = [] } diff --git a/packages/service/core/workflow/dispatch/tools/runLaf.ts b/packages/service/core/workflow/dispatch/tools/runLaf.ts index da577e11a915..badfaf47272a 100644 --- a/packages/service/core/workflow/dispatch/tools/runLaf.ts +++ b/packages/service/core/workflow/dispatch/tools/runLaf.ts @@ -21,7 +21,7 @@ const UNDEFINED_SIGN = 'UNDEFINED_SIGN'; export const dispatchLafRequest = async (props: LafRequestProps): Promise => { let { - app: { _id: appId }, + runningAppInfo: { id: appId }, chatId, responseChatItemId, variables, diff --git a/packages/service/core/workflow/dispatch/utils.ts b/packages/service/core/workflow/dispatch/utils.ts index 1cf3be52ce29..3daeaeb65959 100644 --- a/packages/service/core/workflow/dispatch/utils.ts +++ b/packages/service/core/workflow/dispatch/utils.ts @@ -5,7 +5,10 @@ import { WorkflowIOValueTypeEnum, NodeOutputKeyEnum } from '@fastgpt/global/core/workflow/constants'; -import { RuntimeEdgeItemType } from '@fastgpt/global/core/workflow/runtime/type'; +import { + RuntimeEdgeItemType, + SystemVariablesType +} from '@fastgpt/global/core/workflow/runtime/type'; import { responseWrite } from '../../../common/response'; import { NextApiResponse } from 'next'; import { SseResponseEventEnum } from '@fastgpt/global/core/workflow/runtime/constants'; @@ -144,8 +147,9 @@ export const removeSystemVariable = (variables: Record) => { return copyVariables; }; -export const filterSystemVariables = (variables: Record) => { +export const filterSystemVariables = (variables: Record): SystemVariablesType => { return { + userId: variables.userId, appId: variables.appId, chatId: variables.chatId, responseChatItemId: variables.responseChatItemId, diff --git a/packages/service/core/workflow/utils.ts b/packages/service/core/workflow/utils.ts index 6e5ec8cfb3e5..3c53bbd1219c 100644 --- a/packages/service/core/workflow/utils.ts +++ b/packages/service/core/workflow/utils.ts @@ -1,5 +1,13 @@ import { SearchDataResponseItemType } from '@fastgpt/global/core/dataset/type'; import { countPromptTokens } from '../../common/string/tiktoken/index'; +import { getNanoid } from '@fastgpt/global/common/string/tools'; +import { ChatItemValueTypeEnum, ChatRoleEnum } from '@fastgpt/global/core/chat/constants'; +import { + getPluginInputsFromStoreNodes, + getPluginRunContent +} from '@fastgpt/global/core/app/plugin/utils'; +import { StoreNodeItemType } from '@fastgpt/global/core/workflow/type/node'; +import { UserChatItemType } from '@fastgpt/global/core/chat/type'; /* filter search result */ export const filterSearchResultsByMaxChars = async ( @@ -23,3 +31,25 @@ export const filterSearchResultsByMaxChars = async ( return results.length === 0 ? list.slice(0, 1) : results; }; + +/* Get plugin runtime input user query */ +export const getPluginRunUserQuery = ( + nodes: StoreNodeItemType[], + variables: Record +): UserChatItemType & { dataId: string } => { + return { + dataId: getNanoid(24), + obj: ChatRoleEnum.Human, + value: [ + { + type: ChatItemValueTypeEnum.text, + text: { + content: getPluginRunContent({ + pluginInputs: getPluginInputsFromStoreNodes(nodes), + variables + }) + } + } + ] + }; +}; diff --git a/packages/service/support/permission/app/auth.ts b/packages/service/support/permission/app/auth.ts index 5ba1a8518f6c..03bc7a83ea42 100644 --- a/packages/service/support/permission/app/auth.ts +++ b/packages/service/support/permission/app/auth.ts @@ -25,11 +25,13 @@ export const authPluginByTmbId = async ({ }) => { const { source } = await splitCombinePluginId(appId); if (source === PluginSourceEnum.personal) { - await authAppByTmbId({ + const { app } = await authAppByTmbId({ appId, tmbId, per }); + + return app; } }; diff --git a/packages/web/components/common/Textarea/PromptEditor/type.d.ts b/packages/web/components/common/Textarea/PromptEditor/type.d.ts index 6453bde7b935..939c4d45e801 100644 --- a/packages/web/components/common/Textarea/PromptEditor/type.d.ts +++ b/packages/web/components/common/Textarea/PromptEditor/type.d.ts @@ -6,6 +6,7 @@ export type EditorVariablePickerType = { required?: boolean; icon?: string; valueType?: WorkflowIOValueTypeEnum; + valueDesc?: string; }; export type EditorVariableLabelPickerType = { diff --git a/packages/web/i18n/en/workflow.json b/packages/web/i18n/en/workflow.json index 46ae22d1d0d0..a9e3f36b272b 100644 --- a/packages/web/i18n/en/workflow.json +++ b/packages/web/i18n/en/workflow.json @@ -1,4 +1,11 @@ { + " i18nT('workflow": { + "use_user_id'),\n required": { + "workflow": { + "use_user_id": "" + } + } + }, "Code": "Code", "about_xxx_question": "Questions about xxx", "add_new_input": "Add input", @@ -123,6 +130,7 @@ "select_another_application_to_call": "You can choose another application to call", "special_array_format": "Special array format, when the search result is empty, an empty array is returned.", "start_with": "Start with", + "system_variables": "System variables", "target_fields_description": "A target field is composed of 'description' and 'key', and multiple target fields can be extracted.", "template": { "ai_chat": "LLM chat", @@ -143,6 +151,7 @@ "trigger_after_application_completion": "will be triggered after the application has completely ended", "update_link_error": "Update link exception", "update_specified_node_output_or_global_variable": "You can update the output value of the specified node or update global variables", + "use_user_id": "User ID", "user_question": "User issues", "variable_picker_tips": "enter node name or variable name to search", "variable_update": "variable update", diff --git a/packages/web/i18n/zh/workflow.json b/packages/web/i18n/zh/workflow.json index c848ad32fe14..476823b2e973 100644 --- a/packages/web/i18n/zh/workflow.json +++ b/packages/web/i18n/zh/workflow.json @@ -1,4 +1,11 @@ { + " i18nT('workflow": { + "use_user_id'),\n required": { + "workflow": { + "use_user_id": "使用者 ID" + } + } + }, "Code": "代码", "about_xxx_question": "关于 xxx 的问题", "add_new_input": "新增输入", @@ -123,6 +130,7 @@ "select_another_application_to_call": "可以选择一个其他应用进行调用", "special_array_format": "特殊数组格式,搜索结果为空时,返回空数组。", "start_with": "开始为", + "system_variables": "系统变量", "target_fields_description": "由 '描述' 和 'key' 组成一个目标字段,可提取多个目标字段", "template": { "ai_chat": "AI 对话", @@ -143,6 +151,7 @@ "trigger_after_application_completion": "将在应用完全结束后触发", "update_link_error": "更新链接异常", "update_specified_node_output_or_global_variable": "可以更新指定节点的输出值或更新全局变量", + "use_user_id": "使用者 ID", "user_question": "用户问题", "variable_picker_tips": "可输入节点名或变量名搜索", "variable_update": "变量更新", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7e334f8cdbe8..180d6b1018e9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -63,8 +63,8 @@ importers: specifier: 14.2.5 version: 14.2.5(@babel/core@7.24.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8) openai: - specifier: 4.53.0 - version: 4.53.0(encoding@0.1.13) + specifier: 4.57.0 + version: 4.57.0(encoding@0.1.13) openapi-types: specifier: ^12.1.3 version: 12.1.3 @@ -657,12 +657,6 @@ importers: specifier: ^5.1.3 version: 5.5.3 - scripts/i18n: - devDependencies: - '@phenomnomnominal/tsquery': - specifier: ^6.1.3 - version: 6.1.3(typescript@5.5.3) - scripts/icon: dependencies: express: @@ -2820,11 +2814,6 @@ packages: '@petamoriken/float16@3.8.7': resolution: {integrity: sha512-/Ri4xDDpe12NT6Ex/DRgHzLlobiQXEW/hmG08w1wj/YU7hLemk97c+zHQFp0iZQ9r7YqgLEXZR2sls4HxBf9NA==} - '@phenomnomnominal/tsquery@6.1.3': - resolution: {integrity: sha512-CEqpJ872StsxRmwv9ePCZ4BCisrJSlREUC5XxIRYxhvODt4aQoJFFmjTgaP6meyKiiXxxN/VWPZ58j4yHXRkmw==} - peerDependencies: - typescript: ^3 || ^4 || ^5 - '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -3240,9 +3229,6 @@ packages: '@types/eslint@8.56.10': resolution: {integrity: sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==} - '@types/esquery@1.5.4': - resolution: {integrity: sha512-yYO4Q8H+KJHKW1rEeSzHxcZi90durqYgWVfnh5K6ZADVBjBv2e1NEveYX5yT2bffgN7RqzH3k9930m+i2yBoMA==} - '@types/estree-jsx@1.0.5': resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} @@ -6978,9 +6964,14 @@ packages: resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} engines: {node: '>=12'} - openai@4.53.0: - resolution: {integrity: sha512-XoMaJsSLuedW5eoMEMmZbdNoXgML3ujcU5KfwRnC6rnbmZkHE2Q4J/SArwhqCxQRqJwHnQUj1LpiROmKPExZJA==} + openai@4.57.0: + resolution: {integrity: sha512-JnwBSIYqiZ3jYjB5f2in8hQ0PRA092c6m+/6dYB0MzK0BEbn+0dioxZsPLBm5idJbg9xzLNOiGVm2OSuhZ+BdQ==} hasBin: true + peerDependencies: + zod: ^3.23.8 + peerDependenciesMeta: + zod: + optional: true openapi-types@12.1.3: resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} @@ -8661,10 +8652,6 @@ packages: web-namespaces@2.0.1: resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} - web-streams-polyfill@3.3.3: - resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} - engines: {node: '>= 8'} - web-streams-polyfill@4.0.0-beta.3: resolution: {integrity: sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==} engines: {node: '>= 14'} @@ -11503,12 +11490,6 @@ snapshots: '@petamoriken/float16@3.8.7': {} - '@phenomnomnominal/tsquery@6.1.3(typescript@5.5.3)': - dependencies: - '@types/esquery': 1.5.4 - esquery: 1.6.0 - typescript: 5.5.3 - '@pkgjs/parseargs@0.11.0': optional: true @@ -11967,10 +11948,6 @@ snapshots: '@types/estree': 1.0.5 '@types/json-schema': 7.0.15 - '@types/esquery@1.5.4': - dependencies: - '@types/estree': 1.0.5 - '@types/estree-jsx@1.0.5': dependencies: '@types/estree': 1.0.5 @@ -16845,16 +16822,17 @@ snapshots: dependencies: mimic-fn: 4.0.0 - openai@4.53.0(encoding@0.1.13): + openai@4.57.0(encoding@0.1.13): dependencies: '@types/node': 18.19.40 '@types/node-fetch': 2.6.11 + '@types/qs': 6.9.15 abort-controller: 3.0.0 agentkeepalive: 4.5.0 form-data-encoder: 1.7.2 formdata-node: 4.4.1 node-fetch: 2.7.0(encoding@0.1.13) - web-streams-polyfill: 3.3.3 + qs: 6.12.3 transitivePeerDependencies: - encoding @@ -18699,8 +18677,6 @@ snapshots: web-namespaces@2.0.1: {} - web-streams-polyfill@3.3.3: {} - web-streams-polyfill@4.0.0-beta.3: {} web-worker@1.3.0: {} diff --git a/projects/app/src/components/Markdown/index.tsx b/projects/app/src/components/Markdown/index.tsx index 1f65bed4a41d..26eaec3e2171 100644 --- a/projects/app/src/components/Markdown/index.tsx +++ b/projects/app/src/components/Markdown/index.tsx @@ -48,7 +48,10 @@ const Markdown = ({ const formatSource = useMemo(() => { const formatSource = source - .replace(/(http[s]?:\/\/[^\s,。]+)([。,])/g, '$1 $2') // Follow the link with a space + .replace( + /([\u4e00-\u9fa5\u3000-\u303f])([\w\u0020-\u007e])|([a-zA-Z0-9\u0020-\u007e])([\u4e00-\u9fa5\u3000-\u303f])/g, + '$1$3 $2$4' + ) // Chinese and english chars separated by space .replace(/\n*(\[QUOTE SIGN\]\(.*\))/g, '$1'); return formatSource; diff --git a/projects/app/src/pages/api/core/chat/chatTest.ts b/projects/app/src/pages/api/core/chat/chatTest.ts index c59493dc08e1..ad029650d81f 100644 --- a/projects/app/src/pages/api/core/chat/chatTest.ts +++ b/projects/app/src/pages/api/core/chat/chatTest.ts @@ -13,10 +13,7 @@ import { StoreEdgeItemType } from '@fastgpt/global/core/workflow/type/edge'; import { removeEmptyUserInput } from '@fastgpt/global/core/chat/utils'; import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant'; import { AppTypeEnum } from '@fastgpt/global/core/app/constants'; -import { - removePluginInputVariables, - updatePluginInputByVariables -} from '@fastgpt/global/core/workflow/utils'; +import { updatePluginInputByVariables } from '@fastgpt/global/core/workflow/utils'; import { NextAPI } from '@/service/middleware/entry'; import { GPTMessages2Chats } from '@fastgpt/global/core/chat/adapt'; import { ChatCompletionMessageParam } from '@fastgpt/global/core/ai/type'; @@ -89,7 +86,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { // Plugin need to replace inputs if (isPlugin) { runtimeNodes = updatePluginInputByVariables(runtimeNodes, variables); - variables = removePluginInputVariables(variables, runtimeNodes); + variables = {}; } else { if (!userInput) { throw new Error('Params Error'); @@ -109,10 +106,13 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { res, requestOrigin: req.headers.origin, mode: 'test', - teamId, - tmbId, + runningAppInfo: { + id: appId, + teamId, + tmbId + }, + uid: tmbId, user, - app, runtimeNodes, runtimeEdges: initWorkflowEdgeStatus(edges, chatMessages), variables, diff --git a/projects/app/src/pages/api/core/workflow/debug.ts b/projects/app/src/pages/api/core/workflow/debug.ts index 29482913f262..a75fa3c14165 100644 --- a/projects/app/src/pages/api/core/workflow/debug.ts +++ b/projects/app/src/pages/api/core/workflow/debug.ts @@ -43,10 +43,13 @@ async function handler( res, requestOrigin: req.headers.origin, mode: 'debug', - teamId, - tmbId, + runningAppInfo: { + id: appId, + teamId, + tmbId + }, + uid: tmbId, user, - app, runtimeNodes: nodes, runtimeEdges: edges, variables, diff --git a/projects/app/src/pages/api/v1/chat/completions.ts b/projects/app/src/pages/api/v1/chat/completions.ts index a5b2df4baca7..b022a0bb119d 100644 --- a/projects/app/src/pages/api/v1/chat/completions.ts +++ b/projects/app/src/pages/api/v1/chat/completions.ts @@ -52,18 +52,12 @@ import { NextAPI } from '@/service/middleware/entry'; import { getAppLatestVersion } from '@fastgpt/service/core/app/controller'; import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant'; import { AppTypeEnum } from '@fastgpt/global/core/app/constants'; -import { - removePluginInputVariables, - updatePluginInputByVariables -} from '@fastgpt/global/core/workflow/utils'; +import { updatePluginInputByVariables } from '@fastgpt/global/core/workflow/utils'; import { getNanoid } from '@fastgpt/global/common/string/tools'; -import { - getPluginInputsFromStoreNodes, - getPluginRunContent -} from '@fastgpt/global/core/app/plugin/utils'; import { getSystemTime } from '@fastgpt/global/common/time/timezone'; import { rewriteNodeOutputByHistories } from '@fastgpt/global/core/workflow/runtime/utils'; import { getWorkflowResponseWrite } from '@fastgpt/service/core/workflow/dispatch/utils'; +import { getPluginRunUserQuery } from '@fastgpt/service/core/workflow/utils'; type FastGptWebChatProps = { chatId?: string; // undefined: get histories from messages, '': new chat, 'xxxxx': get histories from db @@ -193,21 +187,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { // Get obj=Human history const userQuestion: UserChatItemType = (() => { if (isPlugin) { - return { - dataId: getNanoid(24), - obj: ChatRoleEnum.Human, - value: [ - { - type: ChatItemValueTypeEnum.text, - text: { - content: getPluginRunContent({ - pluginInputs: getPluginInputsFromStoreNodes(app.modules), - variables - }) - } - } - ] - }; + return getPluginRunUserQuery(app.modules, variables); } const latestHumanChat = chatMessages.pop() as UserChatItemType | undefined; @@ -246,8 +226,8 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { if (isPlugin) { // Assign values to runtimeNodes using variables runtimeNodes = updatePluginInputByVariables(runtimeNodes, variables); - // Remove pluginInput fields from variables (they are not global variables) - variables = removePluginInputVariables(variables, runtimeNodes); + // Plugin runtime does not need global variables(It has been injected into the pluginInputNode) + variables = {}; } runtimeNodes = rewriteNodeOutputByHistories(newHistories, runtimeNodes); @@ -266,9 +246,14 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { requestOrigin: req.headers.origin, mode: 'chat', user, - teamId: String(teamId), - tmbId: String(tmbId), - app, + + runningAppInfo: { + id: String(app._id), + teamId: String(app.teamId), + tmbId: String(app.tmbId) + }, + uid: String(outLinkUserId || tmbId), + chatId, responseChatItemId, runtimeNodes, diff --git a/projects/app/src/pages/app/detail/components/Publish/FeiShu/index.tsx b/projects/app/src/pages/app/detail/components/Publish/FeiShu/index.tsx index d6a0d6311f27..6e89f2c646e7 100644 --- a/projects/app/src/pages/app/detail/components/Publish/FeiShu/index.tsx +++ b/projects/app/src/pages/app/detail/components/Publish/FeiShu/index.tsx @@ -11,7 +11,8 @@ import { Td, Tbody, useDisclosure, - Link + Link, + HStack } from '@chakra-ui/react'; import MyIcon from '@fastgpt/web/components/common/Icon'; import { useLoading } from '@fastgpt/web/hooks/useLoading'; @@ -66,26 +67,24 @@ const FeiShu = ({ appId }: { appId: string }) => { return ( - + {t('common:core.app.publish.Fei shu bot publish')} - {feConfigs?.docUrl && ( - + {t('common:common.Read document')} )} - +