Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions packages/global/core/workflow/type/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,11 +256,27 @@ export const NodeTemplateListTypeSchema = z.array(
);
export type NodeTemplateListType = z.infer<typeof NodeTemplateListTypeSchema>;

export const WorkflowCheckIssueLevelSchema = z.enum(['error', 'warning']);
export type WorkflowCheckIssueLevel = z.infer<typeof WorkflowCheckIssueLevelSchema>;

export const WorkflowCheckIssueSchema = z.object({
nodeId: z.string(),
nodeName: z.string().optional(),
nodeType: z.enum(FlowNodeTypeEnum),
level: WorkflowCheckIssueLevelSchema,
code: z.string(),
message: z.string(),
inputKey: z.string().optional()
});
export type WorkflowCheckIssue = z.infer<typeof WorkflowCheckIssueSchema>;
export type WorkflowCheckNodeIssueMap = Record<string, WorkflowCheckIssue[]>;

// react flow node type
export const FlowNodeItemSchema = FlowNodeTemplateTypeSchema.extend({
nodeId: z.string(),
parentNodeId: z.string().optional(),
isError: BoolSchema.optional(),
workflowCheckIssues: z.array(WorkflowCheckIssueSchema).optional(),
searchedText: z.string().optional(),
debugResult: z
.object({
Expand Down
19 changes: 19 additions & 0 deletions packages/web/i18n/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,25 @@
"core.plugin.Get Plugin Module Detail Failed": "Failed to Retrieve Plugin Information",
"core.tip.leave page": "Content has been modified, confirm to leave the page?",
"core.workflow.Can not delete node": "This Node Cannot Be Deleted",
"core.workflow.check.status.pending_handle": "To handle",
"core.workflow.check.status.pending_improve": "To complete",
"core.workflow.check.required_input_empty": "Please fill in required field {{inputName}}",
"core.workflow.check.no_upstream": "Not connected to other nodes",
"core.workflow.check.invalid_reference": "{{inputName}} references an invalid variable, please delete",
"core.workflow.check.if_else_incomplete": "Incomplete condition configuration, please complete",
"core.workflow.check.user_select_empty": "Configure at least one option",
"core.workflow.check.user_select_value_empty": "Option cannot be empty",
"core.workflow.check.form_input_empty": "Configure at least one field",
"core.workflow.check.classify_question_empty": "Configure at least one category",
"core.workflow.check.classify_question_value_empty": "Category value cannot be empty",
"core.workflow.check.code_input_incomplete": "Incomplete input variable configuration, please complete",
"core.workflow.check.http_url_empty": "Configure request URL",
"core.workflow.check.context_extract_empty": "Configure at least one target field",
"core.workflow.check.tool_call_empty": "Configure a tool or enable virtual machine",
"core.workflow.check.tool_inactive": "This tool is not activated yet, please activate it",
"core.workflow.check.tool_missing": "This tool does not exist, please delete it",
"core.workflow.check.tool_no_permission": "Current account has no permission to access this resource",
"core.workflow.check.tool_offline": "This tool has been deactivated, please delete it",
"core.workflow.Check Failed": "Workflow verification failed, please check whether the value is missing, and whether the connection is normal.",
"core.workflow.Confirm stop debug": "Confirm to Stop Debugging? Debug Information Will Not Be Retained.",
"core.workflow.Copy node": "Node Copied",
Expand Down
19 changes: 19 additions & 0 deletions packages/web/i18n/zh-CN/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,25 @@
"core.plugin.Get Plugin Module Detail Failed": "加载插件异常",
"core.tip.leave page": "内容已修改,确认离开页面吗?",
"core.workflow.Can not delete node": "该节点不允许删除",
"core.workflow.check.status.pending_handle": "待处理",
"core.workflow.check.status.pending_improve": "待完善",
"core.workflow.check.required_input_empty": "需填写必填项 {{inputName}}",
"core.workflow.check.no_upstream": "未与其他节点连线",
"core.workflow.check.invalid_reference": "{{inputName}} 引用了无效变量,需删除",
"core.workflow.check.if_else_incomplete": "存在未完成的条件配置,请完善",
"core.workflow.check.user_select_empty": "需配置至少一个选项",
"core.workflow.check.user_select_value_empty": "选项不可为空",
"core.workflow.check.form_input_empty": "需配置至少一个字段",
"core.workflow.check.classify_question_empty": "需配置至少一个分类",
"core.workflow.check.classify_question_value_empty": "分类值不可为空",
"core.workflow.check.code_input_incomplete": "存在未完成的输入变量配置,请完善",
"core.workflow.check.http_url_empty": "需配置请求地址",
"core.workflow.check.context_extract_empty": "需配置至少一个目标字段",
"core.workflow.check.tool_call_empty": "需配置工具或开启虚拟机",
"core.workflow.check.tool_inactive": "该工具尚未激活,请激活使用",
"core.workflow.check.tool_missing": "该工具不存在,请删除",
"core.workflow.check.tool_no_permission": "当前账号无权限访问该资源",
"core.workflow.check.tool_offline": "该工具已停用,请删除",
"core.workflow.Check Failed": "工作流校验失败,请检查是否缺失、缺值,连线是否正常",
"core.workflow.Confirm stop debug": "确认终止调试?调试信息将会不保留。",
"core.workflow.Copy node": "已复制节点",
Expand Down
19 changes: 19 additions & 0 deletions packages/web/i18n/zh-Hant/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,25 @@
"core.plugin.Get Plugin Module Detail Failed": "取得外掛程式資訊失敗",
"core.tip.leave page": "內容已修改,確認離開頁面嗎?",
"core.workflow.Can not delete node": "此節點不允許刪除",
"core.workflow.check.status.pending_handle": "待處理",
"core.workflow.check.status.pending_improve": "待完善",
"core.workflow.check.required_input_empty": "需填寫必填項 {{inputName}}",
"core.workflow.check.no_upstream": "未與其他節點連線",
"core.workflow.check.invalid_reference": "{{inputName}} 引用了無效變量,需刪除",
"core.workflow.check.if_else_incomplete": "存在未完成的條件配置,請完善",
"core.workflow.check.user_select_empty": "需配置至少一個選項",
"core.workflow.check.user_select_value_empty": "選項不可為空",
"core.workflow.check.form_input_empty": "需配置至少一個字段",
"core.workflow.check.classify_question_empty": "需配置至少一個分類",
"core.workflow.check.classify_question_value_empty": "分類值不可為空",
"core.workflow.check.code_input_incomplete": "存在未完成的輸入變量配置,請完善",
"core.workflow.check.http_url_empty": "需配置請求地址",
"core.workflow.check.context_extract_empty": "需配置至少一個目標字段",
"core.workflow.check.tool_call_empty": "需配置工具或開啟虛擬機",
"core.workflow.check.tool_inactive": "該工具尚未激活,請激活使用",
"core.workflow.check.tool_missing": "該工具不存在,請刪除",
"core.workflow.check.tool_no_permission": "當前帳號無權限存取該資源",
"core.workflow.check.tool_offline": "該工具已停用,請刪除",
"core.workflow.Check Failed": "工作流校驗失敗,請檢查是否遺失、缺值,連線是否正常",
"core.workflow.Confirm stop debug": "確認停止除錯?除錯資訊將不會保留。",
"core.workflow.Copy node": "已複製節點",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import {
type StoreEdgeItemType
} from '@fastgpt/global/core/workflow/type/edge';
import { useCallback, useState, useMemo } from 'react';
import { checkWorkflowNodeAndConnection, getNodeAllSource } from '@/web/core/workflow/utils';
import { useReactFlow } from 'reactflow';
import { checkWorkflowBeforeRunOrPublish, getNodeAllSource } from '@/web/core/workflow/utils';
import { useToast } from '@fastgpt/web/hooks/useToast';
import { uiWorkflow2StoreWorkflow } from '../../utils';
import { type RuntimeNodeItemType } from '@fastgpt/global/core/workflow/runtime/type';
Expand Down Expand Up @@ -58,7 +59,11 @@ export const useDebug = () => {
WorkflowBufferDataContext,
(v) => v.childrenNodeIdListMap
);
const { onUpdateNodeError, onRemoveError } = useContextSelector(WorkflowActionsContext, (v) => v);
const { fitView } = useReactFlow();
const { onUpdateNodeError, onRemoveError, onSyncWorkflowCheckIssues } = useContextSelector(
WorkflowActionsContext,
(v) => v
);
const onStartNodeDebug = useContextSelector(WorkflowDebugContext, (v) => v.onStartNodeDebug);

const appDetail = useContextSelector(AppContext, (v) => v.appDetail);
Expand Down Expand Up @@ -94,22 +99,48 @@ export const useDebug = () => {
const flowData2StoreDataAndCheck = useCallback(async () => {
const nodes = getNodes();

const checkResults = checkWorkflowNodeAndConnection({ nodes, edges });
if (!checkResults) {
const { issueMap, hasError, firstErrorNodeId } = checkWorkflowBeforeRunOrPublish({
nodes,
edges,
t: workflowT
});

if (!hasError) {
onRemoveError();
const storeNodes = uiWorkflow2StoreWorkflow({ nodes, edges });

return JSON.stringify(storeNodes);
} else {
checkResults.forEach((nodeId) => onUpdateNodeError(nodeId, true));
}

toast({
status: 'warning',
title: t('common:core.workflow.Check Failed')
});
return Promise.reject();
onSyncWorkflowCheckIssues(issueMap);

if (firstErrorNodeId) {
onUpdateNodeError(firstErrorNodeId, true);
const firstErrorNode = nodes.find((node) => node.data.nodeId === firstErrorNodeId);
if (firstErrorNode) {
fitView({
nodes: [firstErrorNode],
padding: 0.3
});
}
}
}, [edges, getNodes, onRemoveError, onUpdateNodeError, t, toast]);

toast({
status: 'warning',
title: t('common:core.workflow.Check Failed')
});
return Promise.reject();
}, [
edges,
fitView,
getNodes,
onRemoveError,
onSyncWorkflowCheckIssues,
onUpdateNodeError,
t,
toast,
workflowT
]);

const openDebugNode = useCallback(
async ({ entryNodeId }: { entryNodeId: string }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,10 @@ export const useWorkflow = () => {
} = useContextSelector(WorkflowBufferDataContext, (state) => state);
const selectedNodesMap = useContextSelector(WorkflowNodeDataContext, (v) => v.selectedNodesMap);

const { setConnectingEdge, onChangeNode } = useContextSelector(WorkflowActionsContext, (v) => v);
const { setConnectingEdge, onChangeNode, onUpdateNodeError } = useContextSelector(
WorkflowActionsContext,
(v) => v
);
const pushPastSnapshot = useContextSelector(WorkflowSnapshotContext, (v) => v.pushPastSnapshot);

const { setHoverEdgeId, setMenu } = useContextSelector(WorkflowUIContext, (v) => v);
Expand Down Expand Up @@ -662,8 +665,16 @@ export const useWorkflow = () => {
change.selected = true;
}

// 错误节点失焦(取消选中)时清除标红,与原版点击节点取消标红行为一致。
if (!change.selected) {
const node = getRawNodeById(change.id);
if (node?.data.isError) {
onUpdateNodeError(node.data.nodeId, false);
}
return;
}

// 父子互斥(后操作优先): 选父则取消其已选 children;选子则取消已选父。
if (!change.selected) return;
const node = getRawNodeById(change.id);
if (!node) return;

Expand Down
Loading