diff --git a/packages/global/core/workflow/template/system/aiChat/index.ts b/packages/global/core/workflow/template/system/aiChat/index.ts index 99c606939b9..0bc4e19abef 100644 --- a/packages/global/core/workflow/template/system/aiChat/index.ts +++ b/packages/global/core/workflow/template/system/aiChat/index.ts @@ -54,6 +54,7 @@ export const AiChatModule: FlowNodeTemplateType = { intro: i18nT('workflow:template.ai_chat_intro'), showStatus: true, isTool: true, + courseUrl: '/docs/workflow/modules/ai_chat/', version: '481', inputs: [ Input_Template_SettingAiModel, diff --git a/packages/global/core/workflow/template/system/assignedAnswer.ts b/packages/global/core/workflow/template/system/assignedAnswer.ts index d0eae9c70c8..14f344be40d 100644 --- a/packages/global/core/workflow/template/system/assignedAnswer.ts +++ b/packages/global/core/workflow/template/system/assignedAnswer.ts @@ -17,7 +17,7 @@ export const AssignedAnswerModule: FlowNodeTemplateType = { avatar: 'core/workflow/template/reply', name: i18nT('workflow:assigned_reply'), intro: i18nT('workflow:intro_assigned_reply'), - + courseUrl: '/docs/workflow/modules/reply/', version: '481', isTool: true, inputs: [ diff --git a/packages/global/core/workflow/template/system/classifyQuestion/index.ts b/packages/global/core/workflow/template/system/classifyQuestion/index.ts index c0531f0f18e..8326d823a40 100644 --- a/packages/global/core/workflow/template/system/classifyQuestion/index.ts +++ b/packages/global/core/workflow/template/system/classifyQuestion/index.ts @@ -31,6 +31,7 @@ export const ClassifyQuestionModule: FlowNodeTemplateType = { intro: i18nT('workflow:intro_question_classification'), showStatus: true, version: '481', + courseUrl: '/docs/workflow/modules/question_classify/', inputs: [ { ...Input_Template_SelectAIModel, diff --git a/packages/global/core/workflow/template/system/contextExtract/index.ts b/packages/global/core/workflow/template/system/contextExtract/index.ts index 073173ea005..5d0333c421f 100644 --- a/packages/global/core/workflow/template/system/contextExtract/index.ts +++ b/packages/global/core/workflow/template/system/contextExtract/index.ts @@ -26,6 +26,7 @@ export const ContextExtractModule: FlowNodeTemplateType = { intro: i18nT('workflow:intro_text_content_extraction'), showStatus: true, isTool: true, + courseUrl: '/docs/workflow/modules/content_extract/', version: '481', inputs: [ { diff --git a/packages/global/core/workflow/template/system/customFeedback.ts b/packages/global/core/workflow/template/system/customFeedback.ts index 811ce9540b2..f3d5dd9c397 100644 --- a/packages/global/core/workflow/template/system/customFeedback.ts +++ b/packages/global/core/workflow/template/system/customFeedback.ts @@ -17,6 +17,7 @@ export const CustomFeedbackNode: FlowNodeTemplateType = { avatar: 'core/workflow/template/customFeedback', name: i18nT('workflow:custom_feedback'), intro: i18nT('workflow:intro_custom_feedback'), + courseUrl: '/docs/workflow/modules/custom_feedback/', version: '486', inputs: [ { diff --git a/packages/global/core/workflow/template/system/datasetSearch.ts b/packages/global/core/workflow/template/system/datasetSearch.ts index bb89f4a9b4d..d83cf2f8222 100644 --- a/packages/global/core/workflow/template/system/datasetSearch.ts +++ b/packages/global/core/workflow/template/system/datasetSearch.ts @@ -29,6 +29,7 @@ export const DatasetSearchModule: FlowNodeTemplateType = { intro: Dataset_SEARCH_DESC, showStatus: true, isTool: true, + courseUrl: '/docs/workflow/modules/dataset_search/', version: '481', inputs: [ { diff --git a/packages/global/core/workflow/template/system/http468.ts b/packages/global/core/workflow/template/system/http468.ts index fab83fe6b38..a31a9cbefbc 100644 --- a/packages/global/core/workflow/template/system/http468.ts +++ b/packages/global/core/workflow/template/system/http468.ts @@ -27,6 +27,7 @@ export const HttpNode468: FlowNodeTemplateType = { intro: i18nT('workflow:intro_http_request'), showStatus: true, isTool: true, + courseUrl: '/docs/workflow/modules/http/', version: '481', inputs: [ { diff --git a/packages/global/core/workflow/template/system/ifElse/index.ts b/packages/global/core/workflow/template/system/ifElse/index.ts index fd0c490768c..b50e9989f93 100644 --- a/packages/global/core/workflow/template/system/ifElse/index.ts +++ b/packages/global/core/workflow/template/system/ifElse/index.ts @@ -23,6 +23,7 @@ export const IfElseNode: FlowNodeTemplateType = { name: i18nT('workflow:condition_checker'), intro: i18nT('workflow:execute_different_branches_based_on_conditions'), showStatus: true, + courseUrl: '/docs/workflow/modules/tfswitch/', version: '481', inputs: [ { diff --git a/packages/global/core/workflow/template/system/laf.ts b/packages/global/core/workflow/template/system/laf.ts index 0b2d9a3d5d1..61dadb1912e 100644 --- a/packages/global/core/workflow/template/system/laf.ts +++ b/packages/global/core/workflow/template/system/laf.ts @@ -32,6 +32,7 @@ export const LafModule: FlowNodeTemplateType = { intro: i18nT('workflow:intro_laf_function_call'), showStatus: true, isTool: true, + courseUrl: '/docs/workflow/modules/laf/', version: '481', inputs: [ { diff --git a/packages/global/core/workflow/template/system/sandbox/index.ts b/packages/global/core/workflow/template/system/sandbox/index.ts index 5a9614a56a8..b66ac4bccab 100644 --- a/packages/global/core/workflow/template/system/sandbox/index.ts +++ b/packages/global/core/workflow/template/system/sandbox/index.ts @@ -26,6 +26,7 @@ export const CodeNode: FlowNodeTemplateType = { name: i18nT('workflow:code_execution'), intro: i18nT('workflow:execute_a_simple_script_code_usually_for_complex_data_processing'), showStatus: true, + courseUrl: '/docs/workflow/modules/sandbox/', version: '482', inputs: [ { diff --git a/packages/global/core/workflow/template/system/textEditor.ts b/packages/global/core/workflow/template/system/textEditor.ts index 1dc17a2b1ab..c7f97d2e9a3 100644 --- a/packages/global/core/workflow/template/system/textEditor.ts +++ b/packages/global/core/workflow/template/system/textEditor.ts @@ -23,6 +23,7 @@ export const TextEditorNode: FlowNodeTemplateType = { avatar: 'core/workflow/template/textConcat', name: i18nT('workflow:text_concatenation'), intro: i18nT('workflow:intro_text_concatenation'), + courseUrl: '/docs/workflow/modules/text_editor/', version: '486', inputs: [ { diff --git a/packages/global/core/workflow/template/system/tools.ts b/packages/global/core/workflow/template/system/tools.ts index 6c3315abbbb..fdfe1945409 100644 --- a/packages/global/core/workflow/template/system/tools.ts +++ b/packages/global/core/workflow/template/system/tools.ts @@ -31,6 +31,7 @@ export const ToolModule: FlowNodeTemplateType = { name: i18nT('workflow:template.tool_call'), intro: i18nT('workflow:template.tool_call_intro'), showStatus: true, + courseUrl: '/docs/workflow/modules/input/', version: '481', inputs: [ { diff --git a/packages/global/core/workflow/template/system/workflowStart.ts b/packages/global/core/workflow/template/system/workflowStart.ts index 5f14b5aa97a..930ced6ca1c 100644 --- a/packages/global/core/workflow/template/system/workflowStart.ts +++ b/packages/global/core/workflow/template/system/workflowStart.ts @@ -30,6 +30,7 @@ export const WorkflowStart: FlowNodeTemplateType = { intro: '', forbidDelete: true, unique: true, + courseUrl: '/docs/workflow/modules/input/', version: '481', inputs: [{ ...Input_Template_UserChatInput, toolDescription: i18nT('workflow:user_question') }], outputs: [ diff --git a/packages/global/core/workflow/type/index.d.ts b/packages/global/core/workflow/type/index.d.ts index 3c300a47032..99b1f67a81a 100644 --- a/packages/global/core/workflow/type/index.d.ts +++ b/packages/global/core/workflow/type/index.d.ts @@ -35,7 +35,7 @@ export type WorkflowTemplateType = { avatar: string; intro?: string; author?: string; - inputExplanationUrl?: string; + courseUrl?: string; version: string; showStatus?: boolean; diff --git a/packages/global/core/workflow/type/node.d.ts b/packages/global/core/workflow/type/node.d.ts index 332c4c1190b..227e9f4f26c 100644 --- a/packages/global/core/workflow/type/node.d.ts +++ b/packages/global/core/workflow/type/node.d.ts @@ -32,7 +32,6 @@ export type FlowNodeCommonType = { avatar?: string; name: string; intro?: string; // template list intro - inputExplanationUrl?: string; showStatus?: boolean; // chatting response step status version: string; @@ -69,6 +68,7 @@ export type FlowNodeTemplateType = FlowNodeCommonType & { unique?: boolean; diagram?: string; // diagram url + courseUrl?: string; // course url }; export type NodeTemplateListItemType = { diff --git a/packages/plugins/src/Doc2X/FileImg2text/template.json b/packages/plugins/src/Doc2X/FileImg2text/template.json index f47b89853b4..37d992a3f8b 100644 --- a/packages/plugins/src/Doc2X/FileImg2text/template.json +++ b/packages/plugins/src/Doc2X/FileImg2text/template.json @@ -4,7 +4,7 @@ "name": "Doc2X 图像(文件)识别", "avatar": "plugins/doc2x", "intro": "将上传的图片文件发送至Doc2X进行解析,返回带LaTeX公式的markdown格式的文本", - "inputExplanationUrl": "https://fael3z0zfze.feishu.cn/wiki/Rkc5witXWiJoi5kORd2cofh6nDg?fromScene=spaceOverview", + "courseUrl": "https://fael3z0zfze.feishu.cn/wiki/Rkc5witXWiJoi5kORd2cofh6nDg?fromScene=spaceOverview", "showStatus": true, "weight": 10, diff --git a/packages/plugins/src/Doc2X/FilePDF2text/template.json b/packages/plugins/src/Doc2X/FilePDF2text/template.json index 575060c6bf7..4fa3f0908ab 100644 --- a/packages/plugins/src/Doc2X/FilePDF2text/template.json +++ b/packages/plugins/src/Doc2X/FilePDF2text/template.json @@ -4,7 +4,7 @@ "name": "Doc2X PDF文件(文件)识别", "avatar": "plugins/doc2x", "intro": "将上传的PDF文件发送至Doc2X进行解析,返回带LaTeX公式的markdown格式的文本", - "inputExplanationUrl": "https://fael3z0zfze.feishu.cn/wiki/Rkc5witXWiJoi5kORd2cofh6nDg?fromScene=spaceOverview", + "courseUrl": "https://fael3z0zfze.feishu.cn/wiki/Rkc5witXWiJoi5kORd2cofh6nDg?fromScene=spaceOverview", "showStatus": true, "weight": 10, diff --git a/packages/plugins/src/Doc2X/URLImg2text/template.json b/packages/plugins/src/Doc2X/URLImg2text/template.json index f3ea27508fc..6afbb76bf59 100644 --- a/packages/plugins/src/Doc2X/URLImg2text/template.json +++ b/packages/plugins/src/Doc2X/URLImg2text/template.json @@ -4,7 +4,7 @@ "name": "Doc2X 图像(URL)识别", "avatar": "plugins/doc2x", "intro": "从URL下载图片并发送至Doc2X进行解析,返回带LaTeX公式的markdown格式的文本", - "inputExplanationUrl": "https://fael3z0zfze.feishu.cn/wiki/Rkc5witXWiJoi5kORd2cofh6nDg?fromScene=spaceOverview", + "courseUrl": "https://fael3z0zfze.feishu.cn/wiki/Rkc5witXWiJoi5kORd2cofh6nDg?fromScene=spaceOverview", "showStatus": true, "weight": 10, diff --git a/packages/plugins/src/Doc2X/URLPDF2text/template.json b/packages/plugins/src/Doc2X/URLPDF2text/template.json index 32db81c90c5..6d0496d0597 100644 --- a/packages/plugins/src/Doc2X/URLPDF2text/template.json +++ b/packages/plugins/src/Doc2X/URLPDF2text/template.json @@ -4,7 +4,7 @@ "name": "Doc2X PDF文件(URL)识别", "avatar": "plugins/doc2x", "intro": "从URL下载PDF文件,并发送至Doc2X进行解析,返回带LaTeX公式的markdown格式的文本", - "inputExplanationUrl": "https://fael3z0zfze.feishu.cn/wiki/Rkc5witXWiJoi5kORd2cofh6nDg?fromScene=spaceOverview", + "courseUrl": "https://fael3z0zfze.feishu.cn/wiki/Rkc5witXWiJoi5kORd2cofh6nDg?fromScene=spaceOverview", "showStatus": true, "weight": 10, diff --git a/packages/plugins/src/feishu/template.json b/packages/plugins/src/feishu/template.json index 8728f579010..947eb4793ef 100644 --- a/packages/plugins/src/feishu/template.json +++ b/packages/plugins/src/feishu/template.json @@ -4,7 +4,7 @@ "name": "飞书机器人 webhook", "avatar": "/appMarketTemplates/plugin-feishu/avatar.svg", "intro": "向飞书机器人发起 webhook 请求。", - "inputExplanationUrl": "https://open.feishu.cn/document/client-docs/bot-v3/add-custom-bot#f62e72d5", + "courseUrl": "https://open.feishu.cn/document/client-docs/bot-v3/add-custom-bot#f62e72d5", "showStatus": false, "weight": 10, diff --git a/packages/service/core/app/plugin/controller.ts b/packages/service/core/app/plugin/controller.ts index 9b2e7d9a38f..e94ce67a059 100644 --- a/packages/service/core/app/plugin/controller.ts +++ b/packages/service/core/app/plugin/controller.ts @@ -96,7 +96,7 @@ export async function getChildAppPreviewNode({ avatar: app.avatar, name: app.name, intro: app.intro, - inputExplanationUrl: app.inputExplanationUrl, + courseUrl: app.courseUrl, showStatus: app.showStatus, isTool: true, version: app.version, diff --git a/packages/web/i18n/en/workflow.json b/packages/web/i18n/en/workflow.json index 6d870d989f2..338a5909c19 100644 --- a/packages/web/i18n/en/workflow.json +++ b/packages/web/i18n/en/workflow.json @@ -3,6 +3,7 @@ "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.", "Node_variables": "Node variables", + "Node.Open_Node_Course": "Open node course", "Quote_prompt_setting": "Quote prompt", "Variable.Variable type": "Variable type", "Variable_name": "Variable name", diff --git a/packages/web/i18n/zh/workflow.json b/packages/web/i18n/zh/workflow.json index 549a310560c..4b5f5dc1681 100644 --- a/packages/web/i18n/zh/workflow.json +++ b/packages/web/i18n/zh/workflow.json @@ -3,6 +3,7 @@ "Code": "代码", "Confirm_sync_node": "将会更新至最新的节点配置,不存在模板中的字段将会被删除(包括所有自定义字段)。\n如果字段较为复杂,建议您先复制一份节点,再更新原来的节点,便于参数复制。", "Node_variables": "节点变量", + "Node.Open_Node_Course": "查看节点教程", "Quote_prompt_setting": "引用提示词配置", "Variable.Variable type": "变量类型", "Variable_name": "变量名", diff --git a/projects/app/src/pages/app/detail/components/SimpleApp/components/ToolSelectModal.tsx b/projects/app/src/pages/app/detail/components/SimpleApp/components/ToolSelectModal.tsx index 474fc2310d3..ed258b57100 100644 --- a/projects/app/src/pages/app/detail/components/SimpleApp/components/ToolSelectModal.tsx +++ b/projects/app/src/pages/app/detail/components/SimpleApp/components/ToolSelectModal.tsx @@ -354,11 +354,11 @@ const RenderList = React.memo(function RenderList({ {t('app:tool_input_param_tip')} - {configTool.inputExplanationUrl && ( + {configTool.courseUrl && ( window.open(configTool.inputExplanationUrl, '_blank')} + onClick={() => window.open(configTool.courseUrl, '_blank')} > {t('app:workflow.Input guide')} diff --git a/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/components/IOTitle.tsx b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/components/IOTitle.tsx index 475f10259c4..b75fe37d602 100644 --- a/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/components/IOTitle.tsx +++ b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/components/IOTitle.tsx @@ -1,29 +1,12 @@ import React from 'react'; import { Box, StackProps, HStack } from '@chakra-ui/react'; -import { useTranslation } from 'next-i18next'; - -const IOTitle = ({ - text, - inputExplanationUrl, - ...props -}: { text?: 'Input' | 'Output' | string; inputExplanationUrl?: string } & StackProps) => { - const { t } = useTranslation(); +import MyIcon from '@fastgpt/web/components/common/Icon'; +const IOTitle = ({ text, ...props }: { text?: 'Input' | 'Output' | string } & StackProps) => { return ( {text} - - - {inputExplanationUrl && ( - window.open(inputExplanationUrl, '_blank')} - > - {t('app:workflow.Input guide')} - - )} ); }; diff --git a/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/NodeSimple.tsx b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/NodeSimple.tsx index 0d9e6d66167..f2f018b0b66 100644 --- a/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/NodeSimple.tsx +++ b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/NodeSimple.tsx @@ -38,10 +38,7 @@ const NodeSimple = ({ {filterHiddenInputs.length > 0 && ( <> - + 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 3a18c962feb..5cda53bc3d6 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 @@ -25,6 +25,8 @@ import MyTooltip from '@fastgpt/web/components/common/MyTooltip'; import { useRequest2 } from '@fastgpt/web/hooks/useRequest'; import { useWorkflowUtils } from '../../hooks/useUtils'; import { WholeResponseContent } from '@/components/core/chat/components/WholeResponseModal'; +import { useSystemStore } from '@/web/common/system/useSystemStore'; +import { getDocPath } from '@/web/common/system/doc'; type Props = FlowNodeItemType & { children?: React.ReactNode | React.ReactNode[] | string; @@ -65,7 +67,6 @@ const NodeCard = (props: Props) => { isFolded, ...customStyle } = props; - const nodeList = useContextSelector(WorkflowContext, (v) => v.nodeList); const setHoverNodeId = useContextSelector(WorkflowContext, (v) => v.setHoverNodeId); const onUpdateNodeError = useContextSelector(WorkflowContext, (v) => v.onUpdateNodeError); @@ -102,14 +103,6 @@ const NodeCard = (props: Props) => { if (!node?.pluginId) return; const template = await getPreviewPluginNode({ appId: node.pluginId }); - // Focus update plugin latest inputExplanationUrl - onChangeNode({ - nodeId, - type: 'attr', - key: 'inputExplanationUrl', - value: template.inputExplanationUrl - }); - return template; } else { const template = moduleTemplatesFlat.find( @@ -275,6 +268,24 @@ const NodeCard = (props: Props) => { )} + {!!nodeTemplate?.diagram && node?.courseUrl && ( + + )} + {node?.courseUrl && !hasNewVersion && ( + + window.open(getDocPath(node.courseUrl || ''), '_blank')} + /> + + )} @@ -295,6 +306,7 @@ const NodeCard = (props: Props) => { onOpenConfirmSync, onClickSyncVersion, nodeTemplate?.diagram, + node?.courseUrl, intro, menuForbid, nodeList,