diff --git a/docSite/content/zh-cn/docs/development/upgrading/4815.md b/docSite/content/zh-cn/docs/development/upgrading/4815.md index 5e96d414d..ece081902 100644 --- a/docSite/content/zh-cn/docs/development/upgrading/4815.md +++ b/docSite/content/zh-cn/docs/development/upgrading/4815.md @@ -41,9 +41,10 @@ weight: 809 9. 优化 - 支持 Markdown 文本分割时,只有标题,无内容。 10. 优化 - 字符串变量替换,未赋值的变量会转成 undefined,而不是保留原来 id 串。 11. 优化 - 全局变量默认值在 API 生效,并且自定义变量支持默认值。 -12. 修复 - 分享链接点赞鉴权问题。 -13. 修复 - 对话页面切换自动执行应用时,会误触发非自动执行应用。 -14. 修复 - 语言播放鉴权问题。 -15. 修复 - 插件应用知识库引用上限始终为 3000 -16. 修复 - 工作流编辑记录存储上限,去掉本地存储,增加异常离开时,强制自动保存。 -17. 修复 - 工作流特殊变量替换问题。($开头的字符串无法替换) \ No newline at end of file +12. 优化 - 增加 HTTP Body 的 JSON 解析,正则将 undefined 转 null,减少 Body 解析错误。 +13. 修复 - 分享链接点赞鉴权问题。 +14. 修复 - 对话页面切换自动执行应用时,会误触发非自动执行应用。 +15. 修复 - 语言播放鉴权问题。 +16. 修复 - 插件应用知识库引用上限始终为 3000 +17. 修复 - 工作流编辑记录存储上限,去掉本地存储,增加异常离开时,强制自动保存。 +18. 修复 - 工作流特殊变量替换问题。($开头的字符串无法替换) \ No newline at end of file diff --git a/packages/global/core/workflow/runtime/utils.ts b/packages/global/core/workflow/runtime/utils.ts index d9744dfa2..54e4c372b 100644 --- a/packages/global/core/workflow/runtime/utils.ts +++ b/packages/global/core/workflow/runtime/utils.ts @@ -1,5 +1,5 @@ import { ChatCompletionRequestMessageRoleEnum } from '../../ai/constants'; -import { NodeInputKeyEnum, NodeOutputKeyEnum } from '../constants'; +import { NodeInputKeyEnum, NodeOutputKeyEnum, WorkflowIOValueTypeEnum } from '../constants'; import { FlowNodeTypeEnum } from '../node/constant'; import { StoreNodeItemType } from '../type/node'; import { StoreEdgeItemType } from '../type/edge'; @@ -279,6 +279,27 @@ export const getReferenceVariableValue = ({ return value; }; +export const formatVariableValByType = (val: any, valueType?: WorkflowIOValueTypeEnum) => { + if (!valueType) return val; + // Value type check, If valueType invalid, return undefined + if (valueType.startsWith('array') && !Array.isArray(val)) return undefined; + if (valueType === WorkflowIOValueTypeEnum.boolean && typeof val !== 'boolean') return undefined; + if (valueType === WorkflowIOValueTypeEnum.number && typeof val !== 'number') return undefined; + if (valueType === WorkflowIOValueTypeEnum.string && typeof val !== 'string') return undefined; + if ( + [ + WorkflowIOValueTypeEnum.object, + WorkflowIOValueTypeEnum.chatHistory, + WorkflowIOValueTypeEnum.datasetQuote, + WorkflowIOValueTypeEnum.selectApp, + WorkflowIOValueTypeEnum.selectDataset + ].includes(valueType) && + typeof val !== 'object' + ) + return undefined; + + return val; +}; // replace {{$xx.xx$}} variables for text export function replaceEditorVariable({ text, @@ -308,7 +329,7 @@ export function replaceEditorVariable({ if (!node) return; const output = node.outputs.find((output) => output.id === id); - if (output) return output.value; + if (output) return formatVariableValByType(output.value, output.valueType); const input = node.inputs.find((input) => input.key === id); if (input) return getReferenceVariableValue({ value: input.value, nodes, variables }); diff --git a/packages/service/core/workflow/dispatch/index.ts b/packages/service/core/workflow/dispatch/index.ts index cf1bc3906..bdff74cc3 100644 --- a/packages/service/core/workflow/dispatch/index.ts +++ b/packages/service/core/workflow/dispatch/index.ts @@ -42,7 +42,8 @@ import { filterWorkflowEdges, checkNodeRunStatus, textAdaptGptResponse, - replaceEditorVariable + replaceEditorVariable, + formatVariableValByType } from '@fastgpt/global/core/workflow/runtime/utils'; import { ChatNodeUsageType } from '@fastgpt/global/support/wallet/bill/type'; import { dispatchRunTools } from './agent/runTool/index'; @@ -72,6 +73,7 @@ import { dispatchLoopEnd } from './loop/runLoopEnd'; import { dispatchLoopStart } from './loop/runLoopStart'; import { dispatchFormInput } from './interactive/formInput'; import { dispatchToolParams } from './agent/runTool/toolParams'; +import { AppChatConfigType } from '@fastgpt/global/core/app/type'; const callbackMap: Record = { [FlowNodeTypeEnum.workflowStart]: dispatchWorkflowStart, @@ -685,7 +687,7 @@ export async function dispatchWorkFlow(data: Props): Promise { const variables = chatConfig?.variables || []; const variablesMap = variables.reduce>((acc, item) => { acc[item.key] = valueTypeFormat(item.defaultValue, item.valueType); @@ -709,10 +711,10 @@ export function getSystemVariable({ histories, cTime: getSystemTime(user.timezone) }; -} +}; /* Merge consecutive text messages into one */ -export const mergeAssistantResponseAnswerText = (response: AIChatItemValueItemType[]) => { +const mergeAssistantResponseAnswerText = (response: AIChatItemValueItemType[]) => { const result: AIChatItemValueItemType[] = []; // 合并连续的text for (let i = 0; i < response.length; i++) { diff --git a/packages/service/core/workflow/dispatch/tools/http468.ts b/packages/service/core/workflow/dispatch/tools/http468.ts index ba76fa096..e1afb480a 100644 --- a/packages/service/core/workflow/dispatch/tools/http468.ts +++ b/packages/service/core/workflow/dispatch/tools/http468.ts @@ -24,6 +24,7 @@ import { ReadFileBaseUrl } from '@fastgpt/global/common/file/constants'; import { createFileToken } from '../../../../support/permission/controller'; import { JSONPath } from 'jsonpath-plus'; import type { SystemPluginSpecialResponse } from '../../../../../plugins/type'; +import json5 from 'json5'; type PropsArrType = { key: string; @@ -103,8 +104,6 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise { return replaceVariable( replaceEditorVariable({ @@ -116,6 +115,8 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise { try { @@ -175,9 +176,11 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise import('./icons/check.svg'), checkCircle: () => import('./icons/checkCircle.svg'), closeSolid: () => import('./icons/closeSolid.svg'), + code: () => import('./icons/code.svg'), collectionLight: () => import('./icons/collectionLight.svg'), collectionSolid: () => import('./icons/collectionSolid.svg'), comment: () => import('./icons/comment.svg'), @@ -58,8 +59,6 @@ export const iconPaths = { 'common/monitor': () => import('./icons/common/monitor.svg'), 'common/more': () => import('./icons/common/more.svg'), 'common/moreFill': () => import('./icons/common/moreFill.svg'), - 'common/navbar/pluginFill': () => import('./icons/common/navbar/pluginFill.svg'), - 'common/navbar/pluginLight': () => import('./icons/common/navbar/pluginLight.svg'), 'common/openai': () => import('./icons/common/openai.svg'), 'common/overviewLight': () => import('./icons/common/overviewLight.svg'), 'common/paramsLight': () => import('./icons/common/paramsLight.svg'), @@ -94,9 +93,6 @@ export const iconPaths = { 'common/wechatFill': () => import('./icons/common/wechatFill.svg'), configmap: () => import('./icons/configmap.svg'), copy: () => import('./icons/copy.svg'), - code: () => import('./icons/code.svg'), - preview: () => import('./icons/preview.svg'), - fullScreen: () => import('./icons/fullScreen.svg'), 'core/app/aiFill': () => import('./icons/core/app/aiFill.svg'), 'core/app/aiLight': () => import('./icons/core/app/aiLight.svg'), 'core/app/aiLightSmall': () => import('./icons/core/app/aiLightSmall.svg'), @@ -129,6 +125,7 @@ export const iconPaths = { 'core/app/type/plugin': () => import('./icons/core/app/type/plugin.svg'), 'core/app/type/pluginFill': () => import('./icons/core/app/type/pluginFill.svg'), 'core/app/type/simple': () => import('./icons/core/app/type/simple.svg'), + 'core/app/type/simpleFill': () => import('./icons/core/app/type/simpleFill.svg'), 'core/app/type/workflow': () => import('./icons/core/app/type/workflow.svg'), 'core/app/type/workflowFill': () => import('./icons/core/app/type/workflowFill.svg'), 'core/app/variable/external': () => import('./icons/core/app/variable/external.svg'), @@ -320,6 +317,7 @@ export const iconPaths = { 'file/pdf': () => import('./icons/file/pdf.svg'), 'file/qaImport': () => import('./icons/file/qaImport.svg'), 'file/uploadFile': () => import('./icons/file/uploadFile.svg'), + fullScreen: () => import('./icons/fullScreen.svg'), help: () => import('./icons/help.svg'), history: () => import('./icons/history.svg'), infoRounded: () => import('./icons/infoRounded.svg'), @@ -345,6 +343,7 @@ export const iconPaths = { 'plugins/doc2x': () => import('./icons/plugins/doc2x.svg'), 'plugins/textEditor': () => import('./icons/plugins/textEditor.svg'), point: () => import('./icons/point.svg'), + preview: () => import('./icons/preview.svg'), 'price/bg': () => import('./icons/price/bg.svg'), 'price/right': () => import('./icons/price/right.svg'), save: () => import('./icons/save.svg'), diff --git a/packages/web/components/common/Icon/icons/common/navbar/pluginFill.svg b/packages/web/components/common/Icon/icons/common/navbar/pluginFill.svg deleted file mode 100644 index 58780e79a..000000000 --- a/packages/web/components/common/Icon/icons/common/navbar/pluginFill.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - \ No newline at end of file diff --git a/packages/web/components/common/Icon/icons/common/navbar/pluginLight.svg b/packages/web/components/common/Icon/icons/common/navbar/pluginLight.svg deleted file mode 100644 index 2a866c875..000000000 --- a/packages/web/components/common/Icon/icons/common/navbar/pluginLight.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/packages/web/components/common/Icon/icons/core/app/type/simpleFill.svg b/packages/web/components/common/Icon/icons/core/app/type/simpleFill.svg new file mode 100644 index 000000000..4462f99ea --- /dev/null +++ b/packages/web/components/common/Icon/icons/core/app/type/simpleFill.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/packages/web/i18n/en/common.json b/packages/web/i18n/en/common.json index 717352ac0..25119661b 100644 --- a/packages/web/i18n/en/common.json +++ b/packages/web/i18n/en/common.json @@ -751,7 +751,6 @@ "core.module.template.config_params": "Can configure application system parameters", "core.module.template.empty_plugin": "Blank plugin", "core.module.template.empty_workflow": "Blank workflow", - "core.module.template.http body placeholder": "Same syntax as Apifox", "core.module.template.self_input": "Plug-in input", "core.module.template.self_output": "Custom plug-in output", "core.module.template.system_config": "System configuration", diff --git a/packages/web/i18n/en/workflow.json b/packages/web/i18n/en/workflow.json index c43dae1d8..b1fcb7299 100644 --- a/packages/web/i18n/en/workflow.json +++ b/packages/web/i18n/en/workflow.json @@ -64,6 +64,7 @@ "full_response_data": "Full Response Data", "greater_than": "Greater Than", "greater_than_or_equal_to": "Greater Than or Equal To", + "http_body_placeholder": "Similar syntax to APIFox, variable selection can be activated via /. \nString variables need to be enclosed in double quotes, other types of variables do not need to be enclosed in double quotes. \nPlease strictly check whether it conforms to JSON format.", "http_extract_output": "Output field extraction", "http_extract_output_description": "Specified fields in the response value can be extracted through JSONPath syntax", "http_raw_response_description": "Raw HTTP response. Only accepts string or JSON type response data.", @@ -193,4 +194,4 @@ "workflow.Switch_success": "Switch Successful", "workflow.Team cloud": "Team Cloud", "workflow.exit_tips": "Your changes have not been saved. 'Exit directly' will not save your edits." -} \ No newline at end of file +} diff --git a/packages/web/i18n/zh-CN/common.json b/packages/web/i18n/zh-CN/common.json index e8113e7c9..28e0bcd10 100644 --- a/packages/web/i18n/zh-CN/common.json +++ b/packages/web/i18n/zh-CN/common.json @@ -750,7 +750,6 @@ "core.module.template.config_params": "可以配置应用的系统参数", "core.module.template.empty_plugin": "空白插件", "core.module.template.empty_workflow": "空白工作流", - "core.module.template.http body placeholder": "与 Apifox 相同的语法", "core.module.template.self_input": "插件输入", "core.module.template.self_output": "插件输出", "core.module.template.system_config": "系统配置", diff --git a/packages/web/i18n/zh-CN/workflow.json b/packages/web/i18n/zh-CN/workflow.json index 6f703f200..c23fe23b8 100644 --- a/packages/web/i18n/zh-CN/workflow.json +++ b/packages/web/i18n/zh-CN/workflow.json @@ -10,6 +10,7 @@ "Variable_name": "变量名", "add_new_input": "新增输入", "add_new_output": "新增输出", + "http_body_placeholder": "与 APIFox 类似的语法,可通过 / 来激活变量选择。字符串变量均需加双引号,其他类型变量无需加双引号。请严格检查是否符合 JSON 格式。", "append_application_reply_to_history_as_new_context": "将该应用回复内容拼接到历史记录中,作为新的上下文返回", "application_call": "应用调用", "assigned_reply": "指定回复", @@ -193,4 +194,4 @@ "workflow.Switch_success": "切换成功", "workflow.Team cloud": "团队云端", "workflow.exit_tips": "您的更改尚未保存,「直接退出」将不会保存您的编辑记录。" -} \ No newline at end of file +} diff --git a/packages/web/i18n/zh-Hant/common.json b/packages/web/i18n/zh-Hant/common.json index 2e17fdf5d..99a876d01 100644 --- a/packages/web/i18n/zh-Hant/common.json +++ b/packages/web/i18n/zh-Hant/common.json @@ -751,7 +751,6 @@ "core.module.template.config_params": "可以設定應用程式的系統參數", "core.module.template.empty_plugin": "空白外掛程式", "core.module.template.empty_workflow": "空白工作流程", - "core.module.template.http body placeholder": "與 Apifox 相同的語法", "core.module.template.self_input": "外掛程式輸入", "core.module.template.self_output": "外掛程式輸出", "core.module.template.system_config": "系統設定", diff --git a/packages/web/i18n/zh-Hant/workflow.json b/packages/web/i18n/zh-Hant/workflow.json index c21a1d691..31dbb1837 100644 --- a/packages/web/i18n/zh-Hant/workflow.json +++ b/packages/web/i18n/zh-Hant/workflow.json @@ -64,6 +64,7 @@ "full_response_data": "完整回應資料", "greater_than": "大於", "greater_than_or_equal_to": "大於或等於", + "http_body_placeholder": "與 APIFox 類似的語法,可透過 / 來啟動變數選擇。\n字串變數均需加雙引號,其他類型變數無需加雙引號。\n請嚴格檢查是否符合 JSON 格式。", "http_extract_output": "輸出欄位擷取", "http_extract_output_description": "可以透過 JSONPath 語法來擷取回應值中的指定欄位", "http_raw_response_description": "HTTP 請求的原始回應。僅接受字串或 JSON 類型回應資料。", @@ -193,4 +194,4 @@ "workflow.Switch_success": "切換成功", "workflow.Team cloud": "團隊雲端", "workflow.exit_tips": "您的變更尚未儲存,「直接結束」將不會儲存您的編輯紀錄。" -} \ No newline at end of file +} diff --git a/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/NodeHttp/index.tsx b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/NodeHttp/index.tsx index d8dda9cff..c2e9e01f9 100644 --- a/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/NodeHttp/index.tsx +++ b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/NodeHttp/index.tsx @@ -687,26 +687,24 @@ const RenderBody = ({ )} {typeInput?.value === ContentTypes.json && ( - { - startSts(() => { - onChangeNode({ - nodeId, - type: 'updateInput', - key: jsonBody.key, - value: { - ...jsonBody, - value: e - } - }); + onChangeNode({ + nodeId, + type: 'updateInput', + key: jsonBody.key, + value: { + ...jsonBody, + value: e + } }); }} - variables={variables} /> )} {(typeInput?.value === ContentTypes.xml || typeInput?.value === ContentTypes.raw) && ( @@ -714,16 +712,14 @@ const RenderBody = ({ value={jsonBody.value} placeholder={t('common:textarea_variable_picker_tip')} onChange={(e) => { - startSts(() => { - onChangeNode({ - nodeId, - type: 'updateInput', - key: jsonBody.key, - value: { - ...jsonBody, - value: e - } - }); + onChangeNode({ + nodeId, + type: 'updateInput', + key: jsonBody.key, + value: { + ...jsonBody, + value: e + } }); }} showOpenModal={false}