balibabu commited on
Commit
b1ea792
·
1 Parent(s): fe9e315

Feat: The Begin and IterationStart operators cannot be deleted using shortcut keys #4287 (#4288)

Browse files

### What problem does this PR solve?

Feat: The Begin and IterationStart operators cannot be deleted using
shortcut keys #4287

### Type of change


- [x] New Feature (non-breaking change which adds functionality)

Files changed (42) hide show
  1. web/package-lock.json +55 -26
  2. web/package.json +1 -1
  3. web/src/interfaces/database/flow.ts +117 -6
  4. web/src/pages/flow/canvas/context-menu/index.tsx +1 -1
  5. web/src/pages/flow/canvas/edge/index.tsx +1 -1
  6. web/src/pages/flow/canvas/index.tsx +11 -5
  7. web/src/pages/flow/canvas/node/begin-node.tsx +4 -3
  8. web/src/pages/flow/canvas/node/categorize-handle.tsx +1 -1
  9. web/src/pages/flow/canvas/node/categorize-node.tsx +7 -3
  10. web/src/pages/flow/canvas/node/email-node.tsx +3 -3
  11. web/src/pages/flow/canvas/node/generate-node.tsx +4 -3
  12. web/src/pages/flow/canvas/node/handle-icon.tsx +2 -2
  13. web/src/pages/flow/canvas/node/hooks.ts +6 -5
  14. web/src/pages/flow/canvas/node/index.tsx +3 -3
  15. web/src/pages/flow/canvas/node/invoke-node.tsx +3 -3
  16. web/src/pages/flow/canvas/node/iteration-node.tsx +13 -5
  17. web/src/pages/flow/canvas/node/keyword-node.tsx +3 -3
  18. web/src/pages/flow/canvas/node/logic-node.tsx +3 -3
  19. web/src/pages/flow/canvas/node/message-node.tsx +3 -3
  20. web/src/pages/flow/canvas/node/note-node.tsx +3 -3
  21. web/src/pages/flow/canvas/node/relevant-node.tsx +3 -3
  22. web/src/pages/flow/canvas/node/retrieval-node.tsx +3 -3
  23. web/src/pages/flow/canvas/node/rewrite-node.tsx +3 -3
  24. web/src/pages/flow/canvas/node/switch-node.tsx +3 -3
  25. web/src/pages/flow/canvas/node/template-node.tsx +4 -3
  26. web/src/pages/flow/flow-drawer/index.tsx +3 -3
  27. web/src/pages/flow/form/categorize-form/dynamic-categorize.tsx +1 -1
  28. web/src/pages/flow/form/components/dynamic-input-variable.tsx +2 -3
  29. web/src/pages/flow/form/generate-form/dynamic-parameters.tsx +2 -3
  30. web/src/pages/flow/form/invoke-form/dynamic-variables.tsx +2 -3
  31. web/src/pages/flow/form/relevant-form/hooks.ts +1 -1
  32. web/src/pages/flow/hooks.tsx +21 -12
  33. web/src/pages/flow/hooks/use-before-delete.tsx +57 -0
  34. web/src/pages/flow/hooks/use-build-dsl.ts +2 -2
  35. web/src/pages/flow/hooks/use-get-begin-query.tsx +2 -3
  36. web/src/pages/flow/hooks/use-save-graph.ts +3 -3
  37. web/src/pages/flow/hooks/use-show-drawer.tsx +1 -1
  38. web/src/pages/flow/index.tsx +1 -1
  39. web/src/pages/flow/interface.ts +2 -83
  40. web/src/pages/flow/mock.tsx +1 -1
  41. web/src/pages/flow/store.ts +18 -20
  42. web/src/pages/flow/utils.ts +12 -8
web/package-lock.json CHANGED
@@ -35,6 +35,7 @@
35
  "@tanstack/react-query-devtools": "^5.51.5",
36
  "@tanstack/react-table": "^8.20.5",
37
  "@uiw/react-markdown-preview": "^5.1.3",
 
38
  "ahooks": "^3.7.10",
39
  "antd": "^5.12.7",
40
  "axios": "^1.6.3",
@@ -68,7 +69,7 @@
68
  "react-string-replace": "^1.1.1",
69
  "react-syntax-highlighter": "^15.5.0",
70
  "react18-json-view": "^0.2.8",
71
- "reactflow": "^11.11.2",
72
  "recharts": "^2.12.4",
73
  "rehype-katex": "^7.0.1",
74
  "rehype-raw": "^7.0.0",
@@ -5469,12 +5470,12 @@
5469
  "node": ">=12.0.0"
5470
  }
5471
  },
5472
- "node_modules/@reactflow/background": {
5473
  "version": "11.3.12",
5474
- "resolved": "https://registry.npmmirror.com/@reactflow/background/-/background-11.3.12.tgz",
5475
  "integrity": "sha512-jBuWVb43JQy5h4WOS7G0PU8voGTEJNA+qDmx8/jyBtrjbasTesLNfQvboTGjnQYYiJco6mw5vrtQItAJDNoIqw==",
5476
  "dependencies": {
5477
- "@reactflow/core": "11.11.2",
5478
  "classcat": "^5.0.3",
5479
  "zustand": "^4.4.1"
5480
  },
@@ -5483,12 +5484,12 @@
5483
  "react-dom": ">=17"
5484
  }
5485
  },
5486
- "node_modules/@reactflow/controls": {
5487
  "version": "11.2.12",
5488
- "resolved": "https://registry.npmmirror.com/@reactflow/controls/-/controls-11.2.12.tgz",
5489
  "integrity": "sha512-L9F3+avFRShoprdT+5oOijm5gVsz2rqWCXBzOAgD923L1XFGIspdiHLLf8IlPGsT+mfl0GxbptZhaEeEzl1e3g==",
5490
  "dependencies": {
5491
- "@reactflow/core": "11.11.2",
5492
  "classcat": "^5.0.3",
5493
  "zustand": "^4.4.1"
5494
  },
@@ -5497,9 +5498,9 @@
5497
  "react-dom": ">=17"
5498
  }
5499
  },
5500
- "node_modules/@reactflow/core": {
5501
  "version": "11.11.2",
5502
- "resolved": "https://registry.npmmirror.com/@reactflow/core/-/core-11.11.2.tgz",
5503
  "integrity": "sha512-+GfgyskweL1PsgRSguUwfrT2eDotlFgaKfDLm7x0brdzzPJY2qbCzVetaxedaiJmIli3817iYbILvE9qLKwbRA==",
5504
  "dependencies": {
5505
  "@types/d3": "^7.4.0",
@@ -5517,12 +5518,12 @@
5517
  "react-dom": ">=17"
5518
  }
5519
  },
5520
- "node_modules/@reactflow/minimap": {
5521
  "version": "11.7.12",
5522
- "resolved": "https://registry.npmmirror.com/@reactflow/minimap/-/minimap-11.7.12.tgz",
5523
  "integrity": "sha512-SRDU77c2PCF54PV/MQfkz7VOW46q7V1LZNOQlXAp7dkNyAOI6R+tb9qBUtUJOvILB+TCN6pRfD9fQ+2T99bW3Q==",
5524
  "dependencies": {
5525
- "@reactflow/core": "11.11.2",
5526
  "@types/d3-selection": "^3.0.3",
5527
  "@types/d3-zoom": "^3.0.1",
5528
  "classcat": "^5.0.3",
@@ -5535,12 +5536,12 @@
5535
  "react-dom": ">=17"
5536
  }
5537
  },
5538
- "node_modules/@reactflow/node-resizer": {
5539
  "version": "2.2.12",
5540
- "resolved": "https://registry.npmmirror.com/@reactflow/node-resizer/-/node-resizer-2.2.12.tgz",
5541
  "integrity": "sha512-6LHJGuI1zHyRrZHw5gGlVLIWnvVxid9WIqw8FMFSg+oF2DuS3pAPwSoZwypy7W22/gDNl9eD1Dcl/OtFtDFQ+w==",
5542
  "dependencies": {
5543
- "@reactflow/core": "11.11.2",
5544
  "classcat": "^5.0.4",
5545
  "d3-drag": "^3.0.0",
5546
  "d3-selection": "^3.0.0",
@@ -5551,12 +5552,12 @@
5551
  "react-dom": ">=17"
5552
  }
5553
  },
5554
- "node_modules/@reactflow/node-toolbar": {
5555
  "version": "1.3.12",
5556
- "resolved": "https://registry.npmmirror.com/@reactflow/node-toolbar/-/node-toolbar-1.3.12.tgz",
5557
  "integrity": "sha512-4kJRvNna/E3y2MZW9/80wTKwkhw4pLJiz3D5eQrD13XcmojSb1rArO9CiwyrI+rMvs5gn6NlCFB4iN1F+Q+lxQ==",
5558
  "dependencies": {
5559
- "@reactflow/core": "11.11.2",
5560
  "classcat": "^5.0.3",
5561
  "zustand": "^4.4.1"
5562
  },
@@ -8954,6 +8955,34 @@
8954
  "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
8955
  "peer": true
8956
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8957
  "node_modules/3d-force-graph": {
8958
  "version": "1.73.3",
8959
  "resolved": "https://registry.npmmirror.com/3d-force-graph/-/3d-force-graph-1.73.3.tgz",
@@ -25533,17 +25562,17 @@
25533
  "lodash": "^4.0.1"
25534
  }
25535
  },
25536
- "node_modules/reactflow": {
25537
  "version": "11.11.2",
25538
- "resolved": "https://registry.npmmirror.com/reactflow/-/reactflow-11.11.2.tgz",
25539
  "integrity": "sha512-o1fT3stSdhzW+SedCGNSmEvZvULZygZIMLyW67NcWNZrgwx1wuJfzLg5fuQ0Nzf389wItumZX/zP3zdaPX7lEw==",
25540
  "dependencies": {
25541
- "@reactflow/background": "11.3.12",
25542
- "@reactflow/controls": "11.2.12",
25543
- "@reactflow/core": "11.11.2",
25544
- "@reactflow/minimap": "11.7.12",
25545
- "@reactflow/node-resizer": "2.2.12",
25546
- "@reactflow/node-toolbar": "1.3.12"
25547
  },
25548
  "peerDependencies": {
25549
  "react": ">=17",
 
35
  "@tanstack/react-query-devtools": "^5.51.5",
36
  "@tanstack/react-table": "^8.20.5",
37
  "@uiw/react-markdown-preview": "^5.1.3",
38
+ "@xyflow/react": "^12.3.6",
39
  "ahooks": "^3.7.10",
40
  "antd": "^5.12.7",
41
  "axios": "^1.6.3",
 
69
  "react-string-replace": "^1.1.1",
70
  "react-syntax-highlighter": "^15.5.0",
71
  "react18-json-view": "^0.2.8",
72
+ "@xyflow/react": "^11.11.2",
73
  "recharts": "^2.12.4",
74
  "rehype-katex": "^7.0.1",
75
  "rehype-raw": "^7.0.0",
 
5470
  "node": ">=12.0.0"
5471
  }
5472
  },
5473
+ "node_modules/@@xyflow/react/background": {
5474
  "version": "11.3.12",
5475
+ "resolved": "https://registry.npmmirror.com/@@xyflow/react/background/-/background-11.3.12.tgz",
5476
  "integrity": "sha512-jBuWVb43JQy5h4WOS7G0PU8voGTEJNA+qDmx8/jyBtrjbasTesLNfQvboTGjnQYYiJco6mw5vrtQItAJDNoIqw==",
5477
  "dependencies": {
5478
+ "@@xyflow/react/core": "11.11.2",
5479
  "classcat": "^5.0.3",
5480
  "zustand": "^4.4.1"
5481
  },
 
5484
  "react-dom": ">=17"
5485
  }
5486
  },
5487
+ "node_modules/@@xyflow/react/controls": {
5488
  "version": "11.2.12",
5489
+ "resolved": "https://registry.npmmirror.com/@@xyflow/react/controls/-/controls-11.2.12.tgz",
5490
  "integrity": "sha512-L9F3+avFRShoprdT+5oOijm5gVsz2rqWCXBzOAgD923L1XFGIspdiHLLf8IlPGsT+mfl0GxbptZhaEeEzl1e3g==",
5491
  "dependencies": {
5492
+ "@@xyflow/react/core": "11.11.2",
5493
  "classcat": "^5.0.3",
5494
  "zustand": "^4.4.1"
5495
  },
 
5498
  "react-dom": ">=17"
5499
  }
5500
  },
5501
+ "node_modules/@@xyflow/react/core": {
5502
  "version": "11.11.2",
5503
+ "resolved": "https://registry.npmmirror.com/@@xyflow/react/core/-/core-11.11.2.tgz",
5504
  "integrity": "sha512-+GfgyskweL1PsgRSguUwfrT2eDotlFgaKfDLm7x0brdzzPJY2qbCzVetaxedaiJmIli3817iYbILvE9qLKwbRA==",
5505
  "dependencies": {
5506
  "@types/d3": "^7.4.0",
 
5518
  "react-dom": ">=17"
5519
  }
5520
  },
5521
+ "node_modules/@@xyflow/react/minimap": {
5522
  "version": "11.7.12",
5523
+ "resolved": "https://registry.npmmirror.com/@@xyflow/react/minimap/-/minimap-11.7.12.tgz",
5524
  "integrity": "sha512-SRDU77c2PCF54PV/MQfkz7VOW46q7V1LZNOQlXAp7dkNyAOI6R+tb9qBUtUJOvILB+TCN6pRfD9fQ+2T99bW3Q==",
5525
  "dependencies": {
5526
+ "@@xyflow/react/core": "11.11.2",
5527
  "@types/d3-selection": "^3.0.3",
5528
  "@types/d3-zoom": "^3.0.1",
5529
  "classcat": "^5.0.3",
 
5536
  "react-dom": ">=17"
5537
  }
5538
  },
5539
+ "node_modules/@@xyflow/react/node-resizer": {
5540
  "version": "2.2.12",
5541
+ "resolved": "https://registry.npmmirror.com/@@xyflow/react/node-resizer/-/node-resizer-2.2.12.tgz",
5542
  "integrity": "sha512-6LHJGuI1zHyRrZHw5gGlVLIWnvVxid9WIqw8FMFSg+oF2DuS3pAPwSoZwypy7W22/gDNl9eD1Dcl/OtFtDFQ+w==",
5543
  "dependencies": {
5544
+ "@@xyflow/react/core": "11.11.2",
5545
  "classcat": "^5.0.4",
5546
  "d3-drag": "^3.0.0",
5547
  "d3-selection": "^3.0.0",
 
5552
  "react-dom": ">=17"
5553
  }
5554
  },
5555
+ "node_modules/@@xyflow/react/node-toolbar": {
5556
  "version": "1.3.12",
5557
+ "resolved": "https://registry.npmmirror.com/@@xyflow/react/node-toolbar/-/node-toolbar-1.3.12.tgz",
5558
  "integrity": "sha512-4kJRvNna/E3y2MZW9/80wTKwkhw4pLJiz3D5eQrD13XcmojSb1rArO9CiwyrI+rMvs5gn6NlCFB4iN1F+Q+lxQ==",
5559
  "dependencies": {
5560
+ "@@xyflow/react/core": "11.11.2",
5561
  "classcat": "^5.0.3",
5562
  "zustand": "^4.4.1"
5563
  },
 
8955
  "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
8956
  "peer": true
8957
  },
8958
+ "node_modules/@xyflow/react": {
8959
+ "version": "12.3.6",
8960
+ "resolved": "https://registry.npmmirror.com/@xyflow/react/-/react-12.3.6.tgz",
8961
+ "integrity": "sha512-9GS+cz8hDZahpvTrVCmySAEgKUL8oN4b2q1DluHrKtkqhAMWfH2s7kblhbM4Y4Y4SUnH2lt4drXKZ/4/Lot/2Q==",
8962
+ "dependencies": {
8963
+ "@xyflow/system": "0.0.47",
8964
+ "classcat": "^5.0.3",
8965
+ "zustand": "^4.4.0"
8966
+ },
8967
+ "peerDependencies": {
8968
+ "react": ">=17",
8969
+ "react-dom": ">=17"
8970
+ }
8971
+ },
8972
+ "node_modules/@xyflow/system": {
8973
+ "version": "0.0.47",
8974
+ "resolved": "https://registry.npmmirror.com/@xyflow/system/-/system-0.0.47.tgz",
8975
+ "integrity": "sha512-aUXJPIvsCFxGX70ccRG8LPsR+A8ExYXfh/noYNpqn8udKerrLdSHxMG2VsvUrQ1PGex10fOpbJwFU4A+I/Xv8w==",
8976
+ "dependencies": {
8977
+ "@types/d3-drag": "^3.0.7",
8978
+ "@types/d3-selection": "^3.0.10",
8979
+ "@types/d3-transition": "^3.0.8",
8980
+ "@types/d3-zoom": "^3.0.8",
8981
+ "d3-drag": "^3.0.0",
8982
+ "d3-selection": "^3.0.0",
8983
+ "d3-zoom": "^3.0.0"
8984
+ }
8985
+ },
8986
  "node_modules/3d-force-graph": {
8987
  "version": "1.73.3",
8988
  "resolved": "https://registry.npmmirror.com/3d-force-graph/-/3d-force-graph-1.73.3.tgz",
 
25562
  "lodash": "^4.0.1"
25563
  }
25564
  },
25565
+ "node_modules/@xyflow/react": {
25566
  "version": "11.11.2",
25567
+ "resolved": "https://registry.npmmirror.com/@xyflow/react/-/@xyflow/react-11.11.2.tgz",
25568
  "integrity": "sha512-o1fT3stSdhzW+SedCGNSmEvZvULZygZIMLyW67NcWNZrgwx1wuJfzLg5fuQ0Nzf389wItumZX/zP3zdaPX7lEw==",
25569
  "dependencies": {
25570
+ "@@xyflow/react/background": "11.3.12",
25571
+ "@@xyflow/react/controls": "11.2.12",
25572
+ "@@xyflow/react/core": "11.11.2",
25573
+ "@@xyflow/react/minimap": "11.7.12",
25574
+ "@@xyflow/react/node-resizer": "2.2.12",
25575
+ "@@xyflow/react/node-toolbar": "1.3.12"
25576
  },
25577
  "peerDependencies": {
25578
  "react": ">=17",
web/package.json CHANGED
@@ -46,6 +46,7 @@
46
  "@tanstack/react-query-devtools": "^5.51.5",
47
  "@tanstack/react-table": "^8.20.5",
48
  "@uiw/react-markdown-preview": "^5.1.3",
 
49
  "ahooks": "^3.7.10",
50
  "antd": "^5.12.7",
51
  "axios": "^1.6.3",
@@ -79,7 +80,6 @@
79
  "react-string-replace": "^1.1.1",
80
  "react-syntax-highlighter": "^15.5.0",
81
  "react18-json-view": "^0.2.8",
82
- "reactflow": "^11.11.2",
83
  "recharts": "^2.12.4",
84
  "rehype-katex": "^7.0.1",
85
  "rehype-raw": "^7.0.0",
 
46
  "@tanstack/react-query-devtools": "^5.51.5",
47
  "@tanstack/react-table": "^8.20.5",
48
  "@uiw/react-markdown-preview": "^5.1.3",
49
+ "@xyflow/react": "^11.11.2",
50
  "ahooks": "^3.7.10",
51
  "antd": "^5.12.7",
52
  "axios": "^1.6.3",
 
80
  "react-string-replace": "^1.1.1",
81
  "react-syntax-highlighter": "^15.5.0",
82
  "react18-json-view": "^0.2.8",
 
83
  "recharts": "^2.12.4",
84
  "rehype-katex": "^7.0.1",
85
  "rehype-raw": "^7.0.0",
web/src/interfaces/database/flow.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Edge, Node } from 'reactflow';
2
  import { IReference, Message } from './chat';
3
 
4
  export type DSLComponents = Record<string, IOperator>;
@@ -25,11 +25,6 @@ export interface IOperatorNode {
25
  params: Record<string, unknown>;
26
  }
27
 
28
- export interface IGraph {
29
- nodes: Node[];
30
- edges: Edge[];
31
- }
32
-
33
  export declare interface IFlow {
34
  avatar?: null | string;
35
  canvas_type: null;
@@ -56,3 +51,119 @@ export interface IFlowTemplate {
56
  update_date: string;
57
  update_time: number;
58
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Edge, Node } from '@xyflow/react';
2
  import { IReference, Message } from './chat';
3
 
4
  export type DSLComponents = Record<string, IOperator>;
 
25
  params: Record<string, unknown>;
26
  }
27
 
 
 
 
 
 
28
  export declare interface IFlow {
29
  avatar?: null | string;
30
  canvas_type: null;
 
51
  update_date: string;
52
  update_time: number;
53
  }
54
+
55
+ export type ICategorizeItemResult = Record<
56
+ string,
57
+ Omit<ICategorizeItem, 'name'>
58
+ >;
59
+
60
+ export interface IGenerateForm {
61
+ max_tokens?: number;
62
+ temperature?: number;
63
+ top_p?: number;
64
+ presence_penalty?: number;
65
+ frequency_penalty?: number;
66
+ cite?: boolean;
67
+ prompt: number;
68
+ llm_id: string;
69
+ parameters: { key: string; component_id: string };
70
+ }
71
+ export interface ICategorizeItem {
72
+ name: string;
73
+ description?: string;
74
+ examples?: string;
75
+ to?: string;
76
+ index: number;
77
+ }
78
+
79
+ export interface ICategorizeForm extends IGenerateForm {
80
+ category_description: ICategorizeItemResult;
81
+ }
82
+
83
+ export interface IRelevantForm extends IGenerateForm {
84
+ yes: string;
85
+ no: string;
86
+ }
87
+
88
+ export interface ISwitchCondition {
89
+ items: ISwitchItem[];
90
+ logical_operator: string;
91
+ to: string;
92
+ }
93
+
94
+ export interface ISwitchItem {
95
+ cpn_id: string;
96
+ operator: string;
97
+ value: string;
98
+ }
99
+
100
+ export interface ISwitchForm {
101
+ conditions: ISwitchCondition[];
102
+ end_cpn_id: string;
103
+ no: string;
104
+ }
105
+
106
+ export interface IBeginForm {
107
+ prologue?: string;
108
+ }
109
+
110
+ export interface IRetrievalForm {
111
+ similarity_threshold?: number;
112
+ keywords_similarity_weight?: number;
113
+ top_n?: number;
114
+ top_k?: number;
115
+ rerank_id?: string;
116
+ empty_response?: string;
117
+ kb_ids: string[];
118
+ }
119
+
120
+ export type BaseNodeData<TForm extends any> = {
121
+ label: string; // operator type
122
+ name: string; // operator name
123
+ color?: string;
124
+ form?: TForm;
125
+ };
126
+
127
+ export type BaseNode<T = any> = Node<BaseNodeData<T>>;
128
+
129
+ export type IBeginNode = BaseNode<IBeginForm>;
130
+ export type IRetrievalNode = BaseNode<IRetrievalForm>;
131
+ export type IGenerateNode = BaseNode<IGenerateForm>;
132
+ export type ICategorizeNode = BaseNode<ICategorizeForm>;
133
+ export type ISwitchNode = BaseNode<ISwitchForm>;
134
+ export type IRagNode = BaseNode;
135
+ export type IRelevantNode = BaseNode;
136
+ export type ILogicNode = BaseNode;
137
+ export type INoteNode = BaseNode;
138
+ export type IMessageNode = BaseNode;
139
+ export type IRewriteNode = BaseNode;
140
+ export type IInvokeNode = BaseNode;
141
+ export type ITemplateNode = BaseNode;
142
+ export type IEmailNode = BaseNode;
143
+ export type IIterationNode = BaseNode;
144
+ export type IIterationStartNode = BaseNode;
145
+ export type IKeywordNode = BaseNode;
146
+
147
+ export type RAGFlowNodeType =
148
+ | IBeginNode
149
+ | IRetrievalNode
150
+ | IGenerateNode
151
+ | ICategorizeNode
152
+ | ISwitchNode
153
+ | IRagNode
154
+ | IRelevantNode
155
+ | ILogicNode
156
+ | INoteNode
157
+ | IMessageNode
158
+ | IRewriteNode
159
+ | IInvokeNode
160
+ | ITemplateNode
161
+ | IEmailNode
162
+ | IIterationNode
163
+ | IIterationStartNode
164
+ | IKeywordNode;
165
+
166
+ export interface IGraph {
167
+ nodes: RAGFlowNodeType[];
168
+ edges: Edge[];
169
+ }
web/src/pages/flow/canvas/context-menu/index.tsx CHANGED
@@ -1,5 +1,5 @@
 
1
  import { useCallback, useRef, useState } from 'react';
2
- import { NodeMouseHandler, useReactFlow } from 'reactflow';
3
 
4
  import styles from './index.less';
5
 
 
1
+ import { NodeMouseHandler, useReactFlow } from '@xyflow/react';
2
  import { useCallback, useRef, useState } from 'react';
 
3
 
4
  import styles from './index.less';
5
 
web/src/pages/flow/canvas/edge/index.tsx CHANGED
@@ -3,7 +3,7 @@ import {
3
  EdgeLabelRenderer,
4
  EdgeProps,
5
  getBezierPath,
6
- } from 'reactflow';
7
  import useGraphStore from '../../store';
8
 
9
  import { useTheme } from '@/components/theme-provider';
 
3
  EdgeLabelRenderer,
4
  EdgeProps,
5
  getBezierPath,
6
+ } from '@xyflow/react';
7
  import useGraphStore from '../../store';
8
 
9
  import { useTheme } from '@/components/theme-provider';
web/src/pages/flow/canvas/index.tsx CHANGED
@@ -4,14 +4,16 @@ import {
4
  TooltipProvider,
5
  TooltipTrigger,
6
  } from '@/components/ui/tooltip';
7
- import { FolderInput, FolderOutput } from 'lucide-react';
8
- import ReactFlow, {
9
  Background,
10
  ConnectionMode,
11
  ControlButton,
12
  Controls,
13
- } from 'reactflow';
14
- import 'reactflow/dist/style.css';
 
 
 
15
  import ChatDrawer from '../chat/drawer';
16
  import FormDrawer from '../flow-drawer';
17
  import {
@@ -20,6 +22,7 @@ import {
20
  useValidateConnection,
21
  useWatchNodeFormDataChange,
22
  } from '../hooks';
 
23
  import { useHandleExportOrImportJsonFile } from '../hooks/use-export-json';
24
  import { useShowDrawer } from '../hooks/use-show-drawer';
25
  import JsonUploadModal from '../json-upload-modal';
@@ -43,7 +46,7 @@ import { RewriteNode } from './node/rewrite-node';
43
  import { SwitchNode } from './node/switch-node';
44
  import { TemplateNode } from './node/template-node';
45
 
46
- const nodeTypes = {
47
  ragNode: RagNode,
48
  categorizeNode: CategorizeNode,
49
  beginNode: BeginNode,
@@ -113,6 +116,8 @@ function FlowCanvas({ drawerVisible, hideDrawer }: IProps) {
113
  hideDrawer,
114
  });
115
 
 
 
116
  useWatchNodeFormDataChange();
117
 
118
  return (
@@ -165,6 +170,7 @@ function FlowCanvas({ drawerVisible, hideDrawer }: IProps) {
165
  zIndex: 1001, // https://github.com/xyflow/xyflow/discussions/3498
166
  }}
167
  deleteKeyCode={['Delete', 'Backspace']}
 
168
  >
169
  <Background />
170
  <Controls>
 
4
  TooltipProvider,
5
  TooltipTrigger,
6
  } from '@/components/ui/tooltip';
7
+ import {
 
8
  Background,
9
  ConnectionMode,
10
  ControlButton,
11
  Controls,
12
+ NodeTypes,
13
+ ReactFlow,
14
+ } from '@xyflow/react';
15
+ import '@xyflow/react/dist/style.css';
16
+ import { FolderInput, FolderOutput } from 'lucide-react';
17
  import ChatDrawer from '../chat/drawer';
18
  import FormDrawer from '../flow-drawer';
19
  import {
 
22
  useValidateConnection,
23
  useWatchNodeFormDataChange,
24
  } from '../hooks';
25
+ import { useBeforeDelete } from '../hooks/use-before-delete';
26
  import { useHandleExportOrImportJsonFile } from '../hooks/use-export-json';
27
  import { useShowDrawer } from '../hooks/use-show-drawer';
28
  import JsonUploadModal from '../json-upload-modal';
 
46
  import { SwitchNode } from './node/switch-node';
47
  import { TemplateNode } from './node/template-node';
48
 
49
+ const nodeTypes: NodeTypes = {
50
  ragNode: RagNode,
51
  categorizeNode: CategorizeNode,
52
  beginNode: BeginNode,
 
116
  hideDrawer,
117
  });
118
 
119
+ const { handleBeforeDelete } = useBeforeDelete();
120
+
121
  useWatchNodeFormDataChange();
122
 
123
  return (
 
170
  zIndex: 1001, // https://github.com/xyflow/xyflow/discussions/3498
171
  }}
172
  deleteKeyCode={['Delete', 'Backspace']}
173
+ onBeforeDelete={handleBeforeDelete}
174
  >
175
  <Background />
176
  <Controls>
web/src/pages/flow/canvas/node/begin-node.tsx CHANGED
@@ -1,22 +1,23 @@
1
  import { useTheme } from '@/components/theme-provider';
 
 
2
  import { Flex } from 'antd';
3
  import classNames from 'classnames';
4
  import get from 'lodash/get';
5
  import { useTranslation } from 'react-i18next';
6
- import { Handle, NodeProps, Position } from 'reactflow';
7
  import {
8
  BeginQueryType,
9
  BeginQueryTypeIconMap,
10
  Operator,
11
  operatorMap,
12
  } from '../../constant';
13
- import { BeginQuery, NodeData } from '../../interface';
14
  import OperatorIcon from '../../operator-icon';
15
  import { RightHandleStyle } from './handle-icon';
16
  import styles from './index.less';
17
 
18
  // TODO: do not allow other nodes to connect to this node
19
- export function BeginNode({ selected, data }: NodeProps<NodeData>) {
20
  const { t } = useTranslation();
21
  const query: BeginQuery[] = get(data, 'form.query', []);
22
  const { theme } = useTheme();
 
1
  import { useTheme } from '@/components/theme-provider';
2
+ import { IBeginNode } from '@/interfaces/database/flow';
3
+ import { Handle, NodeProps, Position } from '@xyflow/react';
4
  import { Flex } from 'antd';
5
  import classNames from 'classnames';
6
  import get from 'lodash/get';
7
  import { useTranslation } from 'react-i18next';
 
8
  import {
9
  BeginQueryType,
10
  BeginQueryTypeIconMap,
11
  Operator,
12
  operatorMap,
13
  } from '../../constant';
14
+ import { BeginQuery } from '../../interface';
15
  import OperatorIcon from '../../operator-icon';
16
  import { RightHandleStyle } from './handle-icon';
17
  import styles from './index.less';
18
 
19
  // TODO: do not allow other nodes to connect to this node
20
+ export function BeginNode({ selected, data }: NodeProps<IBeginNode>) {
21
  const { t } = useTranslation();
22
  const query: BeginQuery[] = get(data, 'form.query', []);
23
  const { theme } = useTheme();
web/src/pages/flow/canvas/node/categorize-handle.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import { Handle, Position } from 'reactflow';
2
 
3
  import React from 'react';
4
  import styles from './index.less';
 
1
+ import { Handle, Position } from '@xyflow/react';
2
 
3
  import React from 'react';
4
  import styles from './index.less';
web/src/pages/flow/canvas/node/categorize-node.tsx CHANGED
@@ -1,16 +1,20 @@
1
  import LLMLabel from '@/components/llm-select/llm-label';
2
  import { useTheme } from '@/components/theme-provider';
 
 
3
  import { Flex } from 'antd';
4
  import classNames from 'classnames';
5
  import { get } from 'lodash';
6
- import { Handle, NodeProps, Position } from 'reactflow';
7
- import { NodeData } from '../../interface';
8
  import { RightHandleStyle } from './handle-icon';
9
  import { useBuildCategorizeHandlePositions } from './hooks';
10
  import styles from './index.less';
11
  import NodeHeader from './node-header';
12
 
13
- export function CategorizeNode({ id, data, selected }: NodeProps<NodeData>) {
 
 
 
 
14
  const { positions } = useBuildCategorizeHandlePositions({ data, id });
15
  const { theme } = useTheme();
16
  return (
 
1
  import LLMLabel from '@/components/llm-select/llm-label';
2
  import { useTheme } from '@/components/theme-provider';
3
+ import { ICategorizeNode } from '@/interfaces/database/flow';
4
+ import { Handle, NodeProps, Position } from '@xyflow/react';
5
  import { Flex } from 'antd';
6
  import classNames from 'classnames';
7
  import { get } from 'lodash';
 
 
8
  import { RightHandleStyle } from './handle-icon';
9
  import { useBuildCategorizeHandlePositions } from './hooks';
10
  import styles from './index.less';
11
  import NodeHeader from './node-header';
12
 
13
+ export function CategorizeNode({
14
+ id,
15
+ data,
16
+ selected,
17
+ }: NodeProps<ICategorizeNode>) {
18
  const { positions } = useBuildCategorizeHandlePositions({ data, id });
19
  const { theme } = useTheme();
20
  return (
web/src/pages/flow/canvas/node/email-node.tsx CHANGED
@@ -1,8 +1,8 @@
 
 
1
  import { Flex } from 'antd';
2
  import classNames from 'classnames';
3
  import { useState } from 'react';
4
- import { Handle, NodeProps, Position } from 'reactflow';
5
- import { NodeData } from '../../interface';
6
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
7
  import styles from './index.less';
8
  import NodeHeader from './node-header';
@@ -12,7 +12,7 @@ export function EmailNode({
12
  data,
13
  isConnectable = true,
14
  selected,
15
- }: NodeProps<NodeData>) {
16
  const [showDetails, setShowDetails] = useState(false);
17
 
18
  return (
 
1
+ import { IEmailNode } from '@/interfaces/database/flow';
2
+ import { Handle, NodeProps, Position } from '@xyflow/react';
3
  import { Flex } from 'antd';
4
  import classNames from 'classnames';
5
  import { useState } from 'react';
 
 
6
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
7
  import styles from './index.less';
8
  import NodeHeader from './node-header';
 
12
  data,
13
  isConnectable = true,
14
  selected,
15
+ }: NodeProps<IEmailNode>) {
16
  const [showDetails, setShowDetails] = useState(false);
17
 
18
  return (
web/src/pages/flow/canvas/node/generate-node.tsx CHANGED
@@ -1,11 +1,12 @@
1
  import LLMLabel from '@/components/llm-select/llm-label';
2
  import { useTheme } from '@/components/theme-provider';
 
 
3
  import { Flex } from 'antd';
4
  import classNames from 'classnames';
5
  import { get } from 'lodash';
6
- import { Handle, NodeProps, Position } from 'reactflow';
7
  import { useGetComponentLabelByValue } from '../../hooks/use-get-begin-query';
8
- import { IGenerateParameter, NodeData } from '../../interface';
9
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
10
  import styles from './index.less';
11
  import NodeHeader from './node-header';
@@ -15,7 +16,7 @@ export function GenerateNode({
15
  data,
16
  isConnectable = true,
17
  selected,
18
- }: NodeProps<NodeData>) {
19
  const parameters: IGenerateParameter[] = get(data, 'form.parameters', []);
20
  const getLabel = useGetComponentLabelByValue(id);
21
  const { theme } = useTheme();
 
1
  import LLMLabel from '@/components/llm-select/llm-label';
2
  import { useTheme } from '@/components/theme-provider';
3
+ import { IGenerateNode } from '@/interfaces/database/flow';
4
+ import { Handle, NodeProps, Position } from '@xyflow/react';
5
  import { Flex } from 'antd';
6
  import classNames from 'classnames';
7
  import { get } from 'lodash';
 
8
  import { useGetComponentLabelByValue } from '../../hooks/use-get-begin-query';
9
+ import { IGenerateParameter } from '../../interface';
10
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
11
  import styles from './index.less';
12
  import NodeHeader from './node-header';
 
16
  data,
17
  isConnectable = true,
18
  selected,
19
+ }: NodeProps<IGenerateNode>) {
20
  const parameters: IGenerateParameter[] = get(data, 'form.parameters', []);
21
  const getLabel = useGetComponentLabelByValue(id);
22
  const { theme } = useTheme();
web/src/pages/flow/canvas/node/handle-icon.tsx CHANGED
@@ -10,11 +10,11 @@ export const HandleIcon = () => {
10
  };
11
 
12
  export const RightHandleStyle: CSSProperties = {
13
- right: -5,
14
  };
15
 
16
  export const LeftHandleStyle: CSSProperties = {
17
- left: -7,
18
  };
19
 
20
  export default HandleIcon;
 
10
  };
11
 
12
  export const RightHandleStyle: CSSProperties = {
13
+ right: 0,
14
  };
15
 
16
  export const LeftHandleStyle: CSSProperties = {
17
+ left: 0,
18
  };
19
 
20
  export default HandleIcon;
web/src/pages/flow/canvas/node/hooks.ts CHANGED
@@ -1,12 +1,13 @@
 
1
  import get from 'lodash/get';
2
  import { useEffect, useMemo } from 'react';
3
- import { useUpdateNodeInternals } from 'reactflow';
4
  import { SwitchElseTo } from '../../constant';
 
5
  import {
6
  ICategorizeItemResult,
7
  ISwitchCondition,
8
- NodeData,
9
- } from '../../interface';
10
  import { generateSwitchHandleText } from '../../utils';
11
 
12
  export const useBuildCategorizeHandlePositions = ({
@@ -14,7 +15,7 @@ export const useBuildCategorizeHandlePositions = ({
14
  id,
15
  }: {
16
  id: string;
17
- data: NodeData;
18
  }) => {
19
  const updateNodeInternals = useUpdateNodeInternals();
20
 
@@ -54,7 +55,7 @@ export const useBuildSwitchHandlePositions = ({
54
  id,
55
  }: {
56
  id: string;
57
- data: NodeData;
58
  }) => {
59
  const updateNodeInternals = useUpdateNodeInternals();
60
 
 
1
+ import { useUpdateNodeInternals } from '@xyflow/react';
2
  import get from 'lodash/get';
3
  import { useEffect, useMemo } from 'react';
 
4
  import { SwitchElseTo } from '../../constant';
5
+
6
  import {
7
  ICategorizeItemResult,
8
  ISwitchCondition,
9
+ RAGFlowNodeType,
10
+ } from '@/interfaces/database/flow';
11
  import { generateSwitchHandleText } from '../../utils';
12
 
13
  export const useBuildCategorizeHandlePositions = ({
 
15
  id,
16
  }: {
17
  id: string;
18
+ data: RAGFlowNodeType['data'];
19
  }) => {
20
  const updateNodeInternals = useUpdateNodeInternals();
21
 
 
55
  id,
56
  }: {
57
  id: string;
58
+ data: RAGFlowNodeType['data'];
59
  }) => {
60
  const updateNodeInternals = useUpdateNodeInternals();
61
 
web/src/pages/flow/canvas/node/index.tsx CHANGED
@@ -1,7 +1,7 @@
1
  import { useTheme } from '@/components/theme-provider';
 
 
2
  import classNames from 'classnames';
3
- import { Handle, NodeProps, Position } from 'reactflow';
4
- import { NodeData } from '../../interface';
5
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
6
  import styles from './index.less';
7
  import NodeHeader from './node-header';
@@ -11,7 +11,7 @@ export function RagNode({
11
  data,
12
  isConnectable = true,
13
  selected,
14
- }: NodeProps<NodeData>) {
15
  const { theme } = useTheme();
16
  return (
17
  <section
 
1
  import { useTheme } from '@/components/theme-provider';
2
+ import { IRagNode } from '@/interfaces/database/flow';
3
+ import { Handle, NodeProps, Position } from '@xyflow/react';
4
  import classNames from 'classnames';
 
 
5
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
6
  import styles from './index.less';
7
  import NodeHeader from './node-header';
 
11
  data,
12
  isConnectable = true,
13
  selected,
14
+ }: NodeProps<IRagNode>) {
15
  const { theme } = useTheme();
16
  return (
17
  <section
web/src/pages/flow/canvas/node/invoke-node.tsx CHANGED
@@ -1,10 +1,10 @@
1
  import { useTheme } from '@/components/theme-provider';
 
 
2
  import { Flex } from 'antd';
3
  import classNames from 'classnames';
4
  import { get } from 'lodash';
5
  import { useTranslation } from 'react-i18next';
6
- import { Handle, NodeProps, Position } from 'reactflow';
7
- import { NodeData } from '../../interface';
8
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
9
  import styles from './index.less';
10
  import NodeHeader from './node-header';
@@ -14,7 +14,7 @@ export function InvokeNode({
14
  data,
15
  isConnectable = true,
16
  selected,
17
- }: NodeProps<NodeData>) {
18
  const { t } = useTranslation();
19
  const { theme } = useTheme();
20
  const url = get(data, 'form.url');
 
1
  import { useTheme } from '@/components/theme-provider';
2
+ import { IInvokeNode } from '@/interfaces/database/flow';
3
+ import { Handle, NodeProps, Position } from '@xyflow/react';
4
  import { Flex } from 'antd';
5
  import classNames from 'classnames';
6
  import { get } from 'lodash';
7
  import { useTranslation } from 'react-i18next';
 
 
8
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
9
  import styles from './index.less';
10
  import NodeHeader from './node-header';
 
14
  data,
15
  isConnectable = true,
16
  selected,
17
+ }: NodeProps<IInvokeNode>) {
18
  const { t } = useTranslation();
19
  const { theme } = useTheme();
20
  const url = get(data, 'form.url');
web/src/pages/flow/canvas/node/iteration-node.tsx CHANGED
@@ -1,8 +1,11 @@
1
  import { useTheme } from '@/components/theme-provider';
 
 
 
 
2
  import { cn } from '@/lib/utils';
 
3
  import { ListRestart } from 'lucide-react';
4
- import { Handle, NodeProps, NodeResizeControl, Position } from 'reactflow';
5
- import { NodeData } from '../../interface';
6
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
7
  import styles from './index.less';
8
  import NodeHeader from './node-header';
@@ -19,7 +22,11 @@ function ResizeIcon() {
19
  fill="none"
20
  strokeLinecap="round"
21
  strokeLinejoin="round"
22
- style={{ position: 'absolute', right: 5, bottom: 5 }}
 
 
 
 
23
  >
24
  <path stroke="none" d="M0 0h24v24H0z" fill="none" />
25
  <polyline points="16 20 20 20 20 16" />
@@ -33,6 +40,7 @@ function ResizeIcon() {
33
  const controlStyle = {
34
  background: 'transparent',
35
  border: 'none',
 
36
  };
37
 
38
  export function IterationNode({
@@ -40,7 +48,7 @@ export function IterationNode({
40
  data,
41
  isConnectable = true,
42
  selected,
43
- }: NodeProps<NodeData>) {
44
  const { theme } = useTheme();
45
 
46
  return (
@@ -93,7 +101,7 @@ export function IterationNode({
93
  export function IterationStartNode({
94
  isConnectable = true,
95
  selected,
96
- }: NodeProps<NodeData>) {
97
  const { theme } = useTheme();
98
 
99
  return (
 
1
  import { useTheme } from '@/components/theme-provider';
2
+ import {
3
+ IIterationNode,
4
+ IIterationStartNode,
5
+ } from '@/interfaces/database/flow';
6
  import { cn } from '@/lib/utils';
7
+ import { Handle, NodeProps, NodeResizeControl, Position } from '@xyflow/react';
8
  import { ListRestart } from 'lucide-react';
 
 
9
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
10
  import styles from './index.less';
11
  import NodeHeader from './node-header';
 
22
  fill="none"
23
  strokeLinecap="round"
24
  strokeLinejoin="round"
25
+ style={{
26
+ position: 'absolute',
27
+ right: 5,
28
+ bottom: 5,
29
+ }}
30
  >
31
  <path stroke="none" d="M0 0h24v24H0z" fill="none" />
32
  <polyline points="16 20 20 20 20 16" />
 
40
  const controlStyle = {
41
  background: 'transparent',
42
  border: 'none',
43
+ cursor: 'nwse-resize',
44
  };
45
 
46
  export function IterationNode({
 
48
  data,
49
  isConnectable = true,
50
  selected,
51
+ }: NodeProps<IIterationNode>) {
52
  const { theme } = useTheme();
53
 
54
  return (
 
101
  export function IterationStartNode({
102
  isConnectable = true,
103
  selected,
104
+ }: NodeProps<IIterationStartNode>) {
105
  const { theme } = useTheme();
106
 
107
  return (
web/src/pages/flow/canvas/node/keyword-node.tsx CHANGED
@@ -1,9 +1,9 @@
1
  import LLMLabel from '@/components/llm-select/llm-label';
2
  import { useTheme } from '@/components/theme-provider';
 
 
3
  import classNames from 'classnames';
4
  import { get } from 'lodash';
5
- import { Handle, NodeProps, Position } from 'reactflow';
6
- import { NodeData } from '../../interface';
7
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
8
  import styles from './index.less';
9
  import NodeHeader from './node-header';
@@ -13,7 +13,7 @@ export function KeywordNode({
13
  data,
14
  isConnectable = true,
15
  selected,
16
- }: NodeProps<NodeData>) {
17
  const { theme } = useTheme();
18
  return (
19
  <section
 
1
  import LLMLabel from '@/components/llm-select/llm-label';
2
  import { useTheme } from '@/components/theme-provider';
3
+ import { IKeywordNode } from '@/interfaces/database/flow';
4
+ import { Handle, NodeProps, Position } from '@xyflow/react';
5
  import classNames from 'classnames';
6
  import { get } from 'lodash';
 
 
7
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
8
  import styles from './index.less';
9
  import NodeHeader from './node-header';
 
13
  data,
14
  isConnectable = true,
15
  selected,
16
+ }: NodeProps<IKeywordNode>) {
17
  const { theme } = useTheme();
18
  return (
19
  <section
web/src/pages/flow/canvas/node/logic-node.tsx CHANGED
@@ -1,7 +1,7 @@
1
  import { useTheme } from '@/components/theme-provider';
 
 
2
  import classNames from 'classnames';
3
- import { Handle, NodeProps, Position } from 'reactflow';
4
- import { NodeData } from '../../interface';
5
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
6
  import styles from './index.less';
7
  import NodeHeader from './node-header';
@@ -11,7 +11,7 @@ export function LogicNode({
11
  data,
12
  isConnectable = true,
13
  selected,
14
- }: NodeProps<NodeData>) {
15
  const { theme } = useTheme();
16
  return (
17
  <section
 
1
  import { useTheme } from '@/components/theme-provider';
2
+ import { ILogicNode } from '@/interfaces/database/flow';
3
+ import { Handle, NodeProps, Position } from '@xyflow/react';
4
  import classNames from 'classnames';
 
 
5
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
6
  import styles from './index.less';
7
  import NodeHeader from './node-header';
 
11
  data,
12
  isConnectable = true,
13
  selected,
14
+ }: NodeProps<ILogicNode>) {
15
  const { theme } = useTheme();
16
  return (
17
  <section
web/src/pages/flow/canvas/node/message-node.tsx CHANGED
@@ -1,9 +1,9 @@
1
  import { useTheme } from '@/components/theme-provider';
 
 
2
  import { Flex } from 'antd';
3
  import classNames from 'classnames';
4
  import { get } from 'lodash';
5
- import { Handle, NodeProps, Position } from 'reactflow';
6
- import { NodeData } from '../../interface';
7
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
8
  import styles from './index.less';
9
  import NodeHeader from './node-header';
@@ -13,7 +13,7 @@ export function MessageNode({
13
  data,
14
  isConnectable = true,
15
  selected,
16
- }: NodeProps<NodeData>) {
17
  const messages: string[] = get(data, 'form.messages', []);
18
  const { theme } = useTheme();
19
  return (
 
1
  import { useTheme } from '@/components/theme-provider';
2
+ import { IMessageNode } from '@/interfaces/database/flow';
3
+ import { Handle, NodeProps, Position } from '@xyflow/react';
4
  import { Flex } from 'antd';
5
  import classNames from 'classnames';
6
  import { get } from 'lodash';
 
 
7
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
8
  import styles from './index.less';
9
  import NodeHeader from './node-header';
 
13
  data,
14
  isConnectable = true,
15
  selected,
16
+ }: NodeProps<IMessageNode>) {
17
  const messages: string[] = get(data, 'form.messages', []);
18
  const { theme } = useTheme();
19
  return (
web/src/pages/flow/canvas/node/note-node.tsx CHANGED
@@ -1,11 +1,11 @@
 
1
  import { Flex, Form, Input } from 'antd';
2
  import classNames from 'classnames';
3
- import { NodeProps, NodeResizeControl } from 'reactflow';
4
- import { NodeData } from '../../interface';
5
  import NodeDropdown from './dropdown';
6
 
7
  import SvgIcon from '@/components/svg-icon';
8
  import { useTheme } from '@/components/theme-provider';
 
9
  import { memo, useEffect } from 'react';
10
  import { useTranslation } from 'react-i18next';
11
  import {
@@ -21,7 +21,7 @@ const controlStyle = {
21
  border: 'none',
22
  };
23
 
24
- function NoteNode({ data, id }: NodeProps<NodeData>) {
25
  const { t } = useTranslation();
26
  const [form] = Form.useForm();
27
  const { theme } = useTheme();
 
1
+ import { NodeProps, NodeResizeControl } from '@xyflow/react';
2
  import { Flex, Form, Input } from 'antd';
3
  import classNames from 'classnames';
 
 
4
  import NodeDropdown from './dropdown';
5
 
6
  import SvgIcon from '@/components/svg-icon';
7
  import { useTheme } from '@/components/theme-provider';
8
+ import { INoteNode } from '@/interfaces/database/flow';
9
  import { memo, useEffect } from 'react';
10
  import { useTranslation } from 'react-i18next';
11
  import {
 
21
  border: 'none',
22
  };
23
 
24
+ function NoteNode({ data, id }: NodeProps<INoteNode>) {
25
  const { t } = useTranslation();
26
  const [form] = Form.useForm();
27
  const { theme } = useTheme();
web/src/pages/flow/canvas/node/relevant-node.tsx CHANGED
@@ -1,16 +1,16 @@
 
1
  import { Flex } from 'antd';
2
  import classNames from 'classnames';
3
- import { Handle, NodeProps, Position } from 'reactflow';
4
- import { NodeData } from '../../interface';
5
  import { RightHandleStyle } from './handle-icon';
6
 
7
  import { useTheme } from '@/components/theme-provider';
 
8
  import { get } from 'lodash';
9
  import { useReplaceIdWithName } from '../../hooks';
10
  import styles from './index.less';
11
  import NodeHeader from './node-header';
12
 
13
- export function RelevantNode({ id, data, selected }: NodeProps<NodeData>) {
14
  const yes = get(data, 'form.yes');
15
  const no = get(data, 'form.no');
16
  const replaceIdWithName = useReplaceIdWithName();
 
1
+ import { Handle, NodeProps, Position } from '@xyflow/react';
2
  import { Flex } from 'antd';
3
  import classNames from 'classnames';
 
 
4
  import { RightHandleStyle } from './handle-icon';
5
 
6
  import { useTheme } from '@/components/theme-provider';
7
+ import { IRelevantNode } from '@/interfaces/database/flow';
8
  import { get } from 'lodash';
9
  import { useReplaceIdWithName } from '../../hooks';
10
  import styles from './index.less';
11
  import NodeHeader from './node-header';
12
 
13
+ export function RelevantNode({ id, data, selected }: NodeProps<IRelevantNode>) {
14
  const yes = get(data, 'form.yes');
15
  const no = get(data, 'form.no');
16
  const replaceIdWithName = useReplaceIdWithName();
web/src/pages/flow/canvas/node/retrieval-node.tsx CHANGED
@@ -1,12 +1,12 @@
1
  import { useTheme } from '@/components/theme-provider';
2
  import { useFetchKnowledgeList } from '@/hooks/knowledge-hooks';
 
3
  import { UserOutlined } from '@ant-design/icons';
 
4
  import { Avatar, Flex } from 'antd';
5
  import classNames from 'classnames';
6
  import { get } from 'lodash';
7
  import { useMemo } from 'react';
8
- import { Handle, NodeProps, Position } from 'reactflow';
9
- import { NodeData } from '../../interface';
10
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
11
  import styles from './index.less';
12
  import NodeHeader from './node-header';
@@ -16,7 +16,7 @@ export function RetrievalNode({
16
  data,
17
  isConnectable = true,
18
  selected,
19
- }: NodeProps<NodeData>) {
20
  const knowledgeBaseIds: string[] = get(data, 'form.kb_ids', []);
21
  const { theme } = useTheme();
22
  const { list: knowledgeList } = useFetchKnowledgeList(true);
 
1
  import { useTheme } from '@/components/theme-provider';
2
  import { useFetchKnowledgeList } from '@/hooks/knowledge-hooks';
3
+ import { IRetrievalNode } from '@/interfaces/database/flow';
4
  import { UserOutlined } from '@ant-design/icons';
5
+ import { Handle, NodeProps, Position } from '@xyflow/react';
6
  import { Avatar, Flex } from 'antd';
7
  import classNames from 'classnames';
8
  import { get } from 'lodash';
9
  import { useMemo } from 'react';
 
 
10
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
11
  import styles from './index.less';
12
  import NodeHeader from './node-header';
 
16
  data,
17
  isConnectable = true,
18
  selected,
19
+ }: NodeProps<IRetrievalNode>) {
20
  const knowledgeBaseIds: string[] = get(data, 'form.kb_ids', []);
21
  const { theme } = useTheme();
22
  const { list: knowledgeList } = useFetchKnowledgeList(true);
web/src/pages/flow/canvas/node/rewrite-node.tsx CHANGED
@@ -1,9 +1,9 @@
1
  import LLMLabel from '@/components/llm-select/llm-label';
2
  import { useTheme } from '@/components/theme-provider';
 
 
3
  import classNames from 'classnames';
4
  import { get } from 'lodash';
5
- import { Handle, NodeProps, Position } from 'reactflow';
6
- import { NodeData } from '../../interface';
7
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
8
  import styles from './index.less';
9
  import NodeHeader from './node-header';
@@ -13,7 +13,7 @@ export function RewriteNode({
13
  data,
14
  isConnectable = true,
15
  selected,
16
- }: NodeProps<NodeData>) {
17
  const { theme } = useTheme();
18
  return (
19
  <section
 
1
  import LLMLabel from '@/components/llm-select/llm-label';
2
  import { useTheme } from '@/components/theme-provider';
3
+ import { IRewriteNode } from '@/interfaces/database/flow';
4
+ import { Handle, NodeProps, Position } from '@xyflow/react';
5
  import classNames from 'classnames';
6
  import { get } from 'lodash';
 
 
7
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
8
  import styles from './index.less';
9
  import NodeHeader from './node-header';
 
13
  data,
14
  isConnectable = true,
15
  selected,
16
+ }: NodeProps<IRewriteNode>) {
17
  const { theme } = useTheme();
18
  return (
19
  <section
web/src/pages/flow/canvas/node/switch-node.tsx CHANGED
@@ -1,9 +1,9 @@
1
  import { useTheme } from '@/components/theme-provider';
 
 
2
  import { Divider, Flex } from 'antd';
3
  import classNames from 'classnames';
4
- import { Handle, NodeProps, Position } from 'reactflow';
5
  import { useGetComponentLabelByValue } from '../../hooks/use-get-begin-query';
6
- import { ISwitchCondition, NodeData } from '../../interface';
7
  import { RightHandleStyle } from './handle-icon';
8
  import { useBuildSwitchHandlePositions } from './hooks';
9
  import styles from './index.less';
@@ -54,7 +54,7 @@ const ConditionBlock = ({
54
  );
55
  };
56
 
57
- export function SwitchNode({ id, data, selected }: NodeProps<NodeData>) {
58
  const { positions } = useBuildSwitchHandlePositions({ data, id });
59
  const { theme } = useTheme();
60
  return (
 
1
  import { useTheme } from '@/components/theme-provider';
2
+ import { ISwitchCondition, ISwitchNode } from '@/interfaces/database/flow';
3
+ import { Handle, NodeProps, Position } from '@xyflow/react';
4
  import { Divider, Flex } from 'antd';
5
  import classNames from 'classnames';
 
6
  import { useGetComponentLabelByValue } from '../../hooks/use-get-begin-query';
 
7
  import { RightHandleStyle } from './handle-icon';
8
  import { useBuildSwitchHandlePositions } from './hooks';
9
  import styles from './index.less';
 
54
  );
55
  };
56
 
57
+ export function SwitchNode({ id, data, selected }: NodeProps<ISwitchNode>) {
58
  const { positions } = useBuildSwitchHandlePositions({ data, id });
59
  const { theme } = useTheme();
60
  return (
web/src/pages/flow/canvas/node/template-node.tsx CHANGED
@@ -1,13 +1,14 @@
1
  import { useTheme } from '@/components/theme-provider';
 
2
  import { Flex } from 'antd';
3
  import classNames from 'classnames';
4
  import { get } from 'lodash';
5
- import { Handle, NodeProps, Position } from 'reactflow';
6
  import { useGetComponentLabelByValue } from '../../hooks/use-get-begin-query';
7
- import { IGenerateParameter, NodeData } from '../../interface';
8
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
9
  import NodeHeader from './node-header';
10
 
 
11
  import styles from './index.less';
12
 
13
  export function TemplateNode({
@@ -15,7 +16,7 @@ export function TemplateNode({
15
  data,
16
  isConnectable = true,
17
  selected,
18
- }: NodeProps<NodeData>) {
19
  const parameters: IGenerateParameter[] = get(data, 'form.parameters', []);
20
  const getLabel = useGetComponentLabelByValue(id);
21
  const { theme } = useTheme();
 
1
  import { useTheme } from '@/components/theme-provider';
2
+ import { Handle, NodeProps, Position } from '@xyflow/react';
3
  import { Flex } from 'antd';
4
  import classNames from 'classnames';
5
  import { get } from 'lodash';
 
6
  import { useGetComponentLabelByValue } from '../../hooks/use-get-begin-query';
7
+ import { IGenerateParameter } from '../../interface';
8
  import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
9
  import NodeHeader from './node-header';
10
 
11
+ import { ITemplateNode } from '@/interfaces/database/flow';
12
  import styles from './index.less';
13
 
14
  export function TemplateNode({
 
16
  data,
17
  isConnectable = true,
18
  selected,
19
+ }: NodeProps<ITemplateNode>) {
20
  const parameters: IGenerateParameter[] = get(data, 'form.parameters', []);
21
  const getLabel = useGetComponentLabelByValue(id);
22
  const { theme } = useTheme();
web/src/pages/flow/flow-drawer/index.tsx CHANGED
@@ -5,7 +5,6 @@ import { Drawer, Flex, Form, Input } from 'antd';
5
  import { lowerFirst } from 'lodash';
6
  import { Play } from 'lucide-react';
7
  import { useEffect, useRef } from 'react';
8
- import { Node } from 'reactflow';
9
  import { BeginId, Operator, operatorMap } from '../constant';
10
  import AkShareForm from '../form/akshare-form';
11
  import AnswerForm from '../form/answer-form';
@@ -44,12 +43,13 @@ import OperatorIcon from '../operator-icon';
44
  import { getDrawerWidth, needsSingleStepDebugging } from '../utils';
45
  import SingleDebugDrawer from './single-debug-drawer';
46
 
 
47
  import { RunTooltip } from '../flow-tooltip';
48
  import IterationForm from '../form/iteration-from';
49
  import styles from './index.less';
50
 
51
  interface IProps {
52
- node?: Node;
53
  singleDebugDrawerVisible: IModalProps<any>['visible'];
54
  hideSingleDebugDrawer: IModalProps<any>['hideModal'];
55
  showSingleDebugDrawer: IModalProps<any>['showModal'];
@@ -104,7 +104,7 @@ const FormDrawer = ({
104
  hideSingleDebugDrawer,
105
  showSingleDebugDrawer,
106
  }: IModalProps<any> & IProps) => {
107
- const operatorName: Operator = node?.data.label;
108
  const OperatorForm = FormMap[operatorName] ?? EmptyContent;
109
  const [form] = Form.useForm();
110
  const { name, handleNameBlur, handleNameChange } = useHandleNodeNameChange({
 
5
  import { lowerFirst } from 'lodash';
6
  import { Play } from 'lucide-react';
7
  import { useEffect, useRef } from 'react';
 
8
  import { BeginId, Operator, operatorMap } from '../constant';
9
  import AkShareForm from '../form/akshare-form';
10
  import AnswerForm from '../form/answer-form';
 
43
  import { getDrawerWidth, needsSingleStepDebugging } from '../utils';
44
  import SingleDebugDrawer from './single-debug-drawer';
45
 
46
+ import { RAGFlowNodeType } from '@/interfaces/database/flow';
47
  import { RunTooltip } from '../flow-tooltip';
48
  import IterationForm from '../form/iteration-from';
49
  import styles from './index.less';
50
 
51
  interface IProps {
52
+ node?: RAGFlowNodeType;
53
  singleDebugDrawerVisible: IModalProps<any>['visible'];
54
  hideSingleDebugDrawer: IModalProps<any>['hideModal'];
55
  showSingleDebugDrawer: IModalProps<any>['showModal'];
 
104
  hideSingleDebugDrawer,
105
  showSingleDebugDrawer,
106
  }: IModalProps<any> & IProps) => {
107
+ const operatorName: Operator = node?.data.label as Operator;
108
  const OperatorForm = FormMap[operatorName] ?? EmptyContent;
109
  const [form] = Form.useForm();
110
  const { name, handleNameBlur, handleNameChange } = useHandleNodeNameChange({
web/src/pages/flow/form/categorize-form/dynamic-categorize.tsx CHANGED
@@ -1,5 +1,6 @@
1
  import { useTranslate } from '@/hooks/common-hooks';
2
  import { CloseOutlined, PlusOutlined } from '@ant-design/icons';
 
3
  import {
4
  Button,
5
  Card,
@@ -19,7 +20,6 @@ import {
19
  useEffect,
20
  useState,
21
  } from 'react';
22
- import { useUpdateNodeInternals } from 'reactflow';
23
  import { Operator } from '../../constant';
24
  import { useBuildFormSelectOptions } from '../../form-hooks';
25
 
 
1
  import { useTranslate } from '@/hooks/common-hooks';
2
  import { CloseOutlined, PlusOutlined } from '@ant-design/icons';
3
+ import { useUpdateNodeInternals } from '@xyflow/react';
4
  import {
5
  Button,
6
  Card,
 
20
  useEffect,
21
  useState,
22
  } from 'react';
 
23
  import { Operator } from '../../constant';
24
  import { useBuildFormSelectOptions } from '../../form-hooks';
25
 
web/src/pages/flow/form/components/dynamic-input-variable.tsx CHANGED
@@ -2,14 +2,13 @@ import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
2
  import { Button, Collapse, Flex, Form, Input, Select } from 'antd';
3
  import { PropsWithChildren, useCallback } from 'react';
4
  import { useTranslation } from 'react-i18next';
5
- import { Node } from 'reactflow';
6
  import { useBuildComponentIdSelectOptions } from '../../hooks/use-get-begin-query';
7
- import { NodeData } from '../../interface';
8
 
 
9
  import styles from './index.less';
10
 
11
  interface IProps {
12
- node?: Node<NodeData>;
13
  }
14
 
15
  enum VariableType {
 
2
  import { Button, Collapse, Flex, Form, Input, Select } from 'antd';
3
  import { PropsWithChildren, useCallback } from 'react';
4
  import { useTranslation } from 'react-i18next';
 
5
  import { useBuildComponentIdSelectOptions } from '../../hooks/use-get-begin-query';
 
6
 
7
+ import { RAGFlowNodeType } from '../../interface';
8
  import styles from './index.less';
9
 
10
  interface IProps {
11
+ node?: RAGFlowNodeType;
12
  }
13
 
14
  enum VariableType {
web/src/pages/flow/form/generate-form/dynamic-parameters.tsx CHANGED
@@ -2,14 +2,13 @@ import { EditableCell, EditableRow } from '@/components/editable-cell';
2
  import { useTranslate } from '@/hooks/common-hooks';
3
  import { DeleteOutlined } from '@ant-design/icons';
4
  import { Button, Flex, Select, Table, TableProps } from 'antd';
5
- import { Node } from 'reactflow';
6
  import { useBuildComponentIdSelectOptions } from '../../hooks/use-get-begin-query';
7
- import { IGenerateParameter, NodeData } from '../../interface';
8
  import { useHandleOperateParameters } from './hooks';
9
 
10
  import styles from './index.less';
11
  interface IProps {
12
- node?: Node<NodeData>;
13
  }
14
 
15
  const components = {
 
2
  import { useTranslate } from '@/hooks/common-hooks';
3
  import { DeleteOutlined } from '@ant-design/icons';
4
  import { Button, Flex, Select, Table, TableProps } from 'antd';
 
5
  import { useBuildComponentIdSelectOptions } from '../../hooks/use-get-begin-query';
6
+ import { IGenerateParameter, RAGFlowNodeType } from '../../interface';
7
  import { useHandleOperateParameters } from './hooks';
8
 
9
  import styles from './index.less';
10
  interface IProps {
11
+ node?: RAGFlowNodeType;
12
  }
13
 
14
  const components = {
web/src/pages/flow/form/invoke-form/dynamic-variables.tsx CHANGED
@@ -4,14 +4,13 @@ import { DeleteOutlined } from '@ant-design/icons';
4
  import { Button, Collapse, Flex, Input, Select, Table, TableProps } from 'antd';
5
  import { trim } from 'lodash';
6
  import { useBuildComponentIdSelectOptions } from '../../hooks/use-get-begin-query';
7
- import { IInvokeVariable, NodeData } from '../../interface';
8
  import { useHandleOperateParameters } from './hooks';
9
 
10
- import { Node } from 'reactflow';
11
  import styles from './index.less';
12
 
13
  interface IProps {
14
- node?: Node<NodeData>;
15
  }
16
 
17
  const components = {
 
4
  import { Button, Collapse, Flex, Input, Select, Table, TableProps } from 'antd';
5
  import { trim } from 'lodash';
6
  import { useBuildComponentIdSelectOptions } from '../../hooks/use-get-begin-query';
7
+ import { IInvokeVariable, RAGFlowNodeType } from '../../interface';
8
  import { useHandleOperateParameters } from './hooks';
9
 
 
10
  import styles from './index.less';
11
 
12
  interface IProps {
13
+ node?: RAGFlowNodeType;
14
  }
15
 
16
  const components = {
web/src/pages/flow/form/relevant-form/hooks.ts CHANGED
@@ -1,6 +1,6 @@
 
1
  import pick from 'lodash/pick';
2
  import { useCallback, useEffect } from 'react';
3
- import { Edge } from 'reactflow';
4
  import { IOperatorForm } from '../../interface';
5
  import useGraphStore from '../../store';
6
 
 
1
+ import { Edge } from '@xyflow/react';
2
  import pick from 'lodash/pick';
3
  import { useCallback, useEffect } from 'react';
 
4
  import { IOperatorForm } from '../../interface';
5
  import useGraphStore from '../../store';
6
 
web/src/pages/flow/hooks.tsx CHANGED
@@ -1,3 +1,10 @@
 
 
 
 
 
 
 
1
  import React, {
2
  ChangeEvent,
3
  useCallback,
@@ -5,7 +12,6 @@ import React, {
5
  useMemo,
6
  useState,
7
  } from 'react';
8
- import { Connection, Edge, Node, Position, ReactFlowInstance } from 'reactflow';
9
  // import { shallow } from 'zustand/shallow';
10
  import { variableEnabledFieldMap } from '@/constants/chat';
11
  import {
@@ -14,6 +20,12 @@ import {
14
  } from '@/constants/knowledge';
15
  import { useFetchModelId } from '@/hooks/logic-hooks';
16
  import { Variable } from '@/interfaces/database/chat';
 
 
 
 
 
 
17
  import { FormInstance, message } from 'antd';
18
  import { humanId } from 'human-id';
19
  import { get, isEmpty, lowerFirst, pick } from 'lodash';
@@ -60,7 +72,6 @@ import {
60
  initialWikipediaValues,
61
  initialYahooFinanceValues,
62
  } from './constant';
63
- import { ICategorizeForm, IRelevantForm, ISwitchForm } from './interface';
64
  import useGraphStore, { RFState } from './store';
65
  import {
66
  generateNodeNamesWithIncreasingIndex,
@@ -149,7 +160,7 @@ export const useInitializeOperatorParams = () => {
149
  export const useHandleDrag = () => {
150
  const handleDragStart = useCallback(
151
  (operatorId: string) => (ev: React.DragEvent<HTMLDivElement>) => {
152
- ev.dataTransfer.setData('application/reactflow', operatorId);
153
  ev.dataTransfer.effectAllowed = 'move';
154
  },
155
  [],
@@ -184,7 +195,7 @@ export const useHandleDrop = () => {
184
  (event: React.DragEvent<HTMLDivElement>) => {
185
  event.preventDefault();
186
 
187
- const type = event.dataTransfer.getData('application/reactflow');
188
 
189
  // check if the dropped element is valid
190
  if (typeof type === 'undefined' || !type) {
@@ -193,7 +204,7 @@ export const useHandleDrop = () => {
193
 
194
  // reactFlowInstance.project was renamed to reactFlowInstance.screenToFlowPosition
195
  // and you don't need to subtract the reactFlowBounds.left/top anymore
196
- // details: https://reactflow.dev/whats-new/2023-11-10
197
  const position = reactFlowInstance?.screenToFlowPosition({
198
  x: event.clientX,
199
  y: event.clientY,
@@ -216,10 +227,8 @@ export const useHandleDrop = () => {
216
  };
217
 
218
  if (type === Operator.Iteration) {
219
- newNode.style = {
220
- width: 500,
221
- height: 250,
222
- };
223
  const iterationStartNode: Node<any> = {
224
  id: `${Operator.IterationStart}:${humanId()}`,
225
  type: 'iterationStartNode',
@@ -320,7 +329,7 @@ export const useValidateConnection = () => {
320
  );
321
 
322
  const isSameNodeChild = useCallback(
323
- (connection: Connection) => {
324
  const sourceParentId = getParentIdById(connection.source);
325
  const targetParentId = getParentIdById(connection.target);
326
  if (sourceParentId || targetParentId) {
@@ -333,7 +342,7 @@ export const useValidateConnection = () => {
333
 
334
  // restricted lines cannot be connected successfully.
335
  const isValidConnection = useCallback(
336
- (connection: Connection) => {
337
  // node cannot connect to itself
338
  const isSelfConnected = connection.target === connection.source;
339
 
@@ -567,7 +576,7 @@ export const useCopyPaste = () => {
567
  (event: ClipboardEvent) => {
568
  const nodes = JSON.parse(
569
  event.clipboardData?.getData('agent:nodes') || '[]',
570
- ) as Node[] | undefined;
571
 
572
  if (Array.isArray(nodes) && nodes.length) {
573
  event.preventDefault();
 
1
+ import {
2
+ Connection,
3
+ Edge,
4
+ Node,
5
+ Position,
6
+ ReactFlowInstance,
7
+ } from '@xyflow/react';
8
  import React, {
9
  ChangeEvent,
10
  useCallback,
 
12
  useMemo,
13
  useState,
14
  } from 'react';
 
15
  // import { shallow } from 'zustand/shallow';
16
  import { variableEnabledFieldMap } from '@/constants/chat';
17
  import {
 
20
  } from '@/constants/knowledge';
21
  import { useFetchModelId } from '@/hooks/logic-hooks';
22
  import { Variable } from '@/interfaces/database/chat';
23
+ import {
24
+ ICategorizeForm,
25
+ IRelevantForm,
26
+ ISwitchForm,
27
+ RAGFlowNodeType,
28
+ } from '@/interfaces/database/flow';
29
  import { FormInstance, message } from 'antd';
30
  import { humanId } from 'human-id';
31
  import { get, isEmpty, lowerFirst, pick } from 'lodash';
 
72
  initialWikipediaValues,
73
  initialYahooFinanceValues,
74
  } from './constant';
 
75
  import useGraphStore, { RFState } from './store';
76
  import {
77
  generateNodeNamesWithIncreasingIndex,
 
160
  export const useHandleDrag = () => {
161
  const handleDragStart = useCallback(
162
  (operatorId: string) => (ev: React.DragEvent<HTMLDivElement>) => {
163
+ ev.dataTransfer.setData('application/@xyflow/react', operatorId);
164
  ev.dataTransfer.effectAllowed = 'move';
165
  },
166
  [],
 
195
  (event: React.DragEvent<HTMLDivElement>) => {
196
  event.preventDefault();
197
 
198
+ const type = event.dataTransfer.getData('application/@xyflow/react');
199
 
200
  // check if the dropped element is valid
201
  if (typeof type === 'undefined' || !type) {
 
204
 
205
  // reactFlowInstance.project was renamed to reactFlowInstance.screenToFlowPosition
206
  // and you don't need to subtract the reactFlowBounds.left/top anymore
207
+ // details: https://@xyflow/react.dev/whats-new/2023-11-10
208
  const position = reactFlowInstance?.screenToFlowPosition({
209
  x: event.clientX,
210
  y: event.clientY,
 
227
  };
228
 
229
  if (type === Operator.Iteration) {
230
+ newNode.width = 500;
231
+ newNode.height = 250;
 
 
232
  const iterationStartNode: Node<any> = {
233
  id: `${Operator.IterationStart}:${humanId()}`,
234
  type: 'iterationStartNode',
 
329
  );
330
 
331
  const isSameNodeChild = useCallback(
332
+ (connection: Connection | Edge) => {
333
  const sourceParentId = getParentIdById(connection.source);
334
  const targetParentId = getParentIdById(connection.target);
335
  if (sourceParentId || targetParentId) {
 
342
 
343
  // restricted lines cannot be connected successfully.
344
  const isValidConnection = useCallback(
345
+ (connection: Connection | Edge) => {
346
  // node cannot connect to itself
347
  const isSelfConnected = connection.target === connection.source;
348
 
 
576
  (event: ClipboardEvent) => {
577
  const nodes = JSON.parse(
578
  event.clipboardData?.getData('agent:nodes') || '[]',
579
+ ) as RAGFlowNodeType[] | undefined;
580
 
581
  if (Array.isArray(nodes) && nodes.length) {
582
  event.preventDefault();
web/src/pages/flow/hooks/use-before-delete.tsx ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { RAGFlowNodeType } from '@/interfaces/database/flow';
2
+ import { OnBeforeDelete } from '@xyflow/react';
3
+ import { Operator } from '../constant';
4
+ import useGraphStore from '../store';
5
+
6
+ const UndeletableNodes = [Operator.Begin, Operator.IterationStart];
7
+
8
+ export function useBeforeDelete() {
9
+ const getOperatorTypeFromId = useGraphStore(
10
+ (state) => state.getOperatorTypeFromId,
11
+ );
12
+ const handleBeforeDelete: OnBeforeDelete<RAGFlowNodeType> = async ({
13
+ nodes, // Nodes to be deleted
14
+ edges, // Edges to be deleted
15
+ }) => {
16
+ const toBeDeletedNodes = nodes.filter((node) => {
17
+ const operatorType = node.data?.label as Operator;
18
+ if (operatorType === Operator.Begin) {
19
+ return false;
20
+ }
21
+
22
+ if (
23
+ operatorType === Operator.IterationStart &&
24
+ !nodes.some((x) => x.id === node.parentId)
25
+ ) {
26
+ return false;
27
+ }
28
+
29
+ return true;
30
+ });
31
+
32
+ const toBeDeletedEdges = edges.filter((edge) => {
33
+ const sourceType = getOperatorTypeFromId(edge.source) as Operator;
34
+ const downStreamNodes = nodes.filter((x) => x.id === edge.target);
35
+
36
+ // This edge does not need to be deleted, the range of edges that do not need to be deleted is smaller, so consider the case where it does not need to be deleted
37
+ if (
38
+ UndeletableNodes.includes(sourceType) && // Upstream node is Begin or IterationStart
39
+ downStreamNodes.length === 0 // Downstream node does not exist in the nodes to be deleted
40
+ ) {
41
+ if (!nodes.some((x) => x.id === edge.source)) {
42
+ return true; // Can be deleted
43
+ }
44
+ return false; // Cannot be deleted
45
+ }
46
+
47
+ return true;
48
+ });
49
+
50
+ return {
51
+ nodes: toBeDeletedNodes,
52
+ edges: toBeDeletedEdges,
53
+ };
54
+ };
55
+
56
+ return { handleBeforeDelete };
57
+ }
web/src/pages/flow/hooks/use-build-dsl.ts CHANGED
@@ -1,6 +1,6 @@
1
  import { useFetchFlow } from '@/hooks/flow-hooks';
 
2
  import { useCallback } from 'react';
3
- import { Node } from 'reactflow';
4
  import useGraphStore from '../store';
5
  import { buildDslComponentsByGraph } from '../utils';
6
 
@@ -9,7 +9,7 @@ export const useBuildDslData = () => {
9
  const { nodes, edges } = useGraphStore((state) => state);
10
 
11
  const buildDslData = useCallback(
12
- (currentNodes?: Node[]) => {
13
  const dslComponents = buildDslComponentsByGraph(
14
  currentNodes ?? nodes,
15
  edges,
 
1
  import { useFetchFlow } from '@/hooks/flow-hooks';
2
+ import { RAGFlowNodeType } from '@/interfaces/database/flow';
3
  import { useCallback } from 'react';
 
4
  import useGraphStore from '../store';
5
  import { buildDslComponentsByGraph } from '../utils';
6
 
 
9
  const { nodes, edges } = useGraphStore((state) => state);
10
 
11
  const buildDslData = useCallback(
12
+ (currentNodes?: RAGFlowNodeType[]) => {
13
  const dslComponents = buildDslComponentsByGraph(
14
  currentNodes ?? nodes,
15
  edges,
web/src/pages/flow/hooks/use-get-begin-query.tsx CHANGED
@@ -1,9 +1,8 @@
1
  import { DefaultOptionType } from 'antd/es/select';
2
  import get from 'lodash/get';
3
  import { useCallback, useEffect, useMemo, useState } from 'react';
4
- import { Node } from 'reactflow';
5
  import { BeginId, Operator } from '../constant';
6
- import { BeginQuery, NodeData } from '../interface';
7
  import useGraphStore from '../store';
8
 
9
  export const useGetBeginNodeDataQuery = () => {
@@ -48,7 +47,7 @@ export const useBuildComponentIdSelectOptions = (
48
 
49
  // Limit the nodes inside iteration to only reference peer nodes with the same parentId and other external nodes other than their parent nodes
50
  const filterChildNodesToSameParentOrExternal = useCallback(
51
- (node: Node<NodeData>) => {
52
  // Node inside iteration
53
  if (parentId) {
54
  return (
 
1
  import { DefaultOptionType } from 'antd/es/select';
2
  import get from 'lodash/get';
3
  import { useCallback, useEffect, useMemo, useState } from 'react';
 
4
  import { BeginId, Operator } from '../constant';
5
+ import { BeginQuery, RAGFlowNodeType } from '../interface';
6
  import useGraphStore from '../store';
7
 
8
  export const useGetBeginNodeDataQuery = () => {
 
47
 
48
  // Limit the nodes inside iteration to only reference peer nodes with the same parentId and other external nodes other than their parent nodes
49
  const filterChildNodesToSameParentOrExternal = useCallback(
50
+ (node: RAGFlowNodeType) => {
51
  // Node inside iteration
52
  if (parentId) {
53
  return (
web/src/pages/flow/hooks/use-save-graph.ts CHANGED
@@ -1,8 +1,8 @@
1
  import { useFetchFlow, useResetFlow, useSetFlow } from '@/hooks/flow-hooks';
 
2
  import { useDebounceEffect } from 'ahooks';
3
  import dayjs from 'dayjs';
4
  import { useCallback, useEffect, useState } from 'react';
5
- import { Node } from 'reactflow';
6
  import { useParams } from 'umi';
7
  import useGraphStore from '../store';
8
  import { useBuildDslData } from './use-build-dsl';
@@ -14,7 +14,7 @@ export const useSaveGraph = () => {
14
  const { buildDslData } = useBuildDslData();
15
 
16
  const saveGraph = useCallback(
17
- async (currentNodes?: Node[]) => {
18
  return setFlow({
19
  id,
20
  title: data.title,
@@ -32,7 +32,7 @@ export const useSaveGraphBeforeOpeningDebugDrawer = (show: () => void) => {
32
  const { resetFlow } = useResetFlow();
33
 
34
  const handleRun = useCallback(
35
- async (nextNodes?: Node[]) => {
36
  const saveRet = await saveGraph(nextNodes);
37
  if (saveRet?.code === 0) {
38
  // Call the reset api before opening the run drawer each time
 
1
  import { useFetchFlow, useResetFlow, useSetFlow } from '@/hooks/flow-hooks';
2
+ import { RAGFlowNodeType } from '@/interfaces/database/flow';
3
  import { useDebounceEffect } from 'ahooks';
4
  import dayjs from 'dayjs';
5
  import { useCallback, useEffect, useState } from 'react';
 
6
  import { useParams } from 'umi';
7
  import useGraphStore from '../store';
8
  import { useBuildDslData } from './use-build-dsl';
 
14
  const { buildDslData } = useBuildDslData();
15
 
16
  const saveGraph = useCallback(
17
+ async (currentNodes?: RAGFlowNodeType[]) => {
18
  return setFlow({
19
  id,
20
  title: data.title,
 
32
  const { resetFlow } = useResetFlow();
33
 
34
  const handleRun = useCallback(
35
+ async (nextNodes?: RAGFlowNodeType[]) => {
36
  const saveRet = await saveGraph(nextNodes);
37
  if (saveRet?.code === 0) {
38
  // Call the reset api before opening the run drawer each time
web/src/pages/flow/hooks/use-show-drawer.tsx CHANGED
@@ -1,7 +1,7 @@
1
  import { useSetModalState } from '@/hooks/common-hooks';
 
2
  import get from 'lodash/get';
3
  import { useCallback, useEffect } from 'react';
4
- import { Node, NodeMouseHandler } from 'reactflow';
5
  import { Operator } from '../constant';
6
  import { BeginQuery } from '../interface';
7
  import useGraphStore from '../store';
 
1
  import { useSetModalState } from '@/hooks/common-hooks';
2
+ import { Node, NodeMouseHandler } from '@xyflow/react';
3
  import get from 'lodash/get';
4
  import { useCallback, useEffect } from 'react';
 
5
  import { Operator } from '../constant';
6
  import { BeginQuery } from '../interface';
7
  import useGraphStore from '../store';
web/src/pages/flow/index.tsx CHANGED
@@ -1,7 +1,7 @@
1
  import { useSetModalState } from '@/hooks/common-hooks';
 
2
  import { Layout } from 'antd';
3
  import { useState } from 'react';
4
- import { ReactFlowProvider } from 'reactflow';
5
  import FlowCanvas from './canvas';
6
  import Sider from './flow-sider';
7
  import FlowHeader from './header';
 
1
  import { useSetModalState } from '@/hooks/common-hooks';
2
+ import { ReactFlowProvider } from '@xyflow/react';
3
  import { Layout } from 'antd';
4
  import { useState } from 'react';
 
5
  import FlowCanvas from './canvas';
6
  import Sider from './flow-sider';
7
  import FlowHeader from './header';
web/src/pages/flow/interface.ts CHANGED
@@ -1,51 +1,13 @@
 
1
  import { FormInstance } from 'antd';
2
- import { Node } from 'reactflow';
3
-
4
- export interface DSLComponentList {
5
- id: string;
6
- name: string;
7
- }
8
 
9
  export interface IOperatorForm {
10
  onValuesChange?(changedValues: any, values: any): void;
11
  form?: FormInstance;
12
- node?: Node<NodeData>;
13
  nodeId?: string;
14
  }
15
 
16
- export interface IBeginForm {
17
- prologue?: string;
18
- }
19
-
20
- export interface IRetrievalForm {
21
- similarity_threshold?: number;
22
- keywords_similarity_weight?: number;
23
- top_n?: number;
24
- top_k?: number;
25
- rerank_id?: string;
26
- empty_response?: string;
27
- kb_ids: string[];
28
- }
29
-
30
- export interface IGenerateForm {
31
- max_tokens?: number;
32
- temperature?: number;
33
- top_p?: number;
34
- presence_penalty?: number;
35
- frequency_penalty?: number;
36
- cite?: boolean;
37
- prompt: number;
38
- llm_id: string;
39
- parameters: { key: string; component_id: string };
40
- }
41
- export interface ICategorizeItem {
42
- name: string;
43
- description?: string;
44
- examples?: string;
45
- to?: string;
46
- index: number;
47
- }
48
-
49
  export interface IGenerateParameter {
50
  id?: string;
51
  key: string;
@@ -56,49 +18,6 @@ export interface IInvokeVariable extends IGenerateParameter {
56
  value?: string;
57
  }
58
 
59
- export type ICategorizeItemResult = Record<
60
- string,
61
- Omit<ICategorizeItem, 'name'>
62
- >;
63
- export interface ICategorizeForm extends IGenerateForm {
64
- category_description: ICategorizeItemResult;
65
- }
66
-
67
- export interface IRelevantForm extends IGenerateForm {
68
- yes: string;
69
- no: string;
70
- }
71
-
72
- export interface ISwitchCondition {
73
- items: ISwitchItem[];
74
- logical_operator: string;
75
- to: string;
76
- }
77
-
78
- export interface ISwitchItem {
79
- cpn_id: string;
80
- operator: string;
81
- value: string;
82
- }
83
-
84
- export interface ISwitchForm {
85
- conditions: ISwitchCondition[];
86
- end_cpn_id: string;
87
- no: string;
88
- }
89
-
90
- export type NodeData = {
91
- label: string; // operator type
92
- name: string; // operator name
93
- color?: string;
94
- form:
95
- | IBeginForm
96
- | IRetrievalForm
97
- | IGenerateForm
98
- | ICategorizeForm
99
- | ISwitchForm;
100
- };
101
-
102
  export type IPosition = { top: number; right: number; idx: number };
103
 
104
  export interface BeginQuery {
 
1
+ import { RAGFlowNodeType } from '@/interfaces/database/flow';
2
  import { FormInstance } from 'antd';
 
 
 
 
 
 
3
 
4
  export interface IOperatorForm {
5
  onValuesChange?(changedValues: any, values: any): void;
6
  form?: FormInstance;
7
+ node?: RAGFlowNodeType;
8
  nodeId?: string;
9
  }
10
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  export interface IGenerateParameter {
12
  id?: string;
13
  key: string;
 
18
  value?: string;
19
  }
20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  export type IPosition = { top: number; right: number; idx: number };
22
 
23
  export interface BeginQuery {
web/src/pages/flow/mock.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import { Position } from 'reactflow';
2
 
3
  export const initialNodes = [
4
  {
 
1
+ import { Position } from '@xyflow/react';
2
 
3
  export const initialNodes = [
4
  {
web/src/pages/flow/store.ts CHANGED
@@ -1,14 +1,9 @@
 
1
  import type {} from '@redux-devtools/extension';
2
- import { omit } from 'lodash';
3
- import differenceWith from 'lodash/differenceWith';
4
- import intersectionWith from 'lodash/intersectionWith';
5
- import lodashSet from 'lodash/set';
6
  import {
7
  Connection,
8
  Edge,
9
  EdgeChange,
10
- Node,
11
- NodeChange,
12
  OnConnect,
13
  OnEdgesChange,
14
  OnNodesChange,
@@ -17,12 +12,15 @@ import {
17
  addEdge,
18
  applyEdgeChanges,
19
  applyNodeChanges,
20
- } from 'reactflow';
 
 
 
 
21
  import { create } from 'zustand';
22
  import { devtools } from 'zustand/middleware';
23
  import { immer } from 'zustand/middleware/immer';
24
  import { Operator, SwitchElseTo } from './constant';
25
- import { NodeData } from './interface';
26
  import {
27
  duplicateNodeForm,
28
  generateDuplicateNode,
@@ -32,25 +30,25 @@ import {
32
  } from './utils';
33
 
34
  export type RFState = {
35
- nodes: Node<NodeData>[];
36
  edges: Edge[];
37
  selectedNodeIds: string[];
38
  selectedEdgeIds: string[];
39
  clickedNodeId: string; // currently selected node
40
- onNodesChange: OnNodesChange;
41
  onEdgesChange: OnEdgesChange;
42
  onConnect: OnConnect;
43
- setNodes: (nodes: Node[]) => void;
44
  setEdges: (edges: Edge[]) => void;
45
  setEdgesByNodeId: (nodeId: string, edges: Edge[]) => void;
46
  updateNodeForm: (
47
  nodeId: string,
48
  values: any,
49
  path?: (string | number)[],
50
- ) => Node[];
51
  onSelectionChange: OnSelectionChangeFunc;
52
- addNode: (nodes: Node) => void;
53
- getNode: (id?: string | null) => Node<NodeData> | undefined;
54
  addEdge: (connection: Connection) => void;
55
  getEdge: (id: string) => Edge | undefined;
56
  updateFormDataOnConnect: (connection: Connection) => void;
@@ -67,7 +65,7 @@ export type RFState = {
67
  deleteNodeById: (id: string) => void;
68
  deleteIterationNodeById: (id: string) => void;
69
  deleteEdgeBySourceAndSourceHandle: (connection: Partial<Connection>) => void;
70
- findNodeByName: (operatorName: Operator) => Node | undefined;
71
  updateMutableNodeFormItem: (id: string, field: string, value: any) => void;
72
  getOperatorTypeFromId: (id?: string | null) => string | undefined;
73
  getParentIdById: (id?: string | null) => string | undefined;
@@ -80,12 +78,12 @@ export type RFState = {
80
  const useGraphStore = create<RFState>()(
81
  devtools(
82
  immer((set, get) => ({
83
- nodes: [] as Node[],
84
  edges: [] as Edge[],
85
  selectedNodeIds: [] as string[],
86
  selectedEdgeIds: [] as string[],
87
  clickedNodeId: '',
88
- onNodesChange: (changes: NodeChange[]) => {
89
  set({
90
  nodes: applyNodeChanges(changes, get().nodes),
91
  });
@@ -112,7 +110,7 @@ const useGraphStore = create<RFState>()(
112
  selectedNodeIds: nodes.map((x) => x.id),
113
  });
114
  },
115
- setNodes: (nodes: Node[]) => {
116
  set({ nodes });
117
  },
118
  setEdges: (edges: Edge[]) => {
@@ -164,7 +162,7 @@ const useGraphStore = create<RFState>()(
164
  ]);
165
  }
166
  },
167
- addNode: (node: Node) => {
168
  set({ nodes: get().nodes.concat(node) });
169
  },
170
  getNode: (id?: string | null) => {
@@ -262,7 +260,7 @@ const useGraphStore = create<RFState>()(
262
  const { getNode, generateNodeName, nodes } = get();
263
  const node = getNode(id);
264
 
265
- const iterationNode: Node<NodeData> = {
266
  ...(node || {}),
267
  data: {
268
  ...(node?.data || { label: Operator.Iteration, form: {} }),
 
1
+ import { RAGFlowNodeType } from '@/interfaces/database/flow';
2
  import type {} from '@redux-devtools/extension';
 
 
 
 
3
  import {
4
  Connection,
5
  Edge,
6
  EdgeChange,
 
 
7
  OnConnect,
8
  OnEdgesChange,
9
  OnNodesChange,
 
12
  addEdge,
13
  applyEdgeChanges,
14
  applyNodeChanges,
15
+ } from '@xyflow/react';
16
+ import { omit } from 'lodash';
17
+ import differenceWith from 'lodash/differenceWith';
18
+ import intersectionWith from 'lodash/intersectionWith';
19
+ import lodashSet from 'lodash/set';
20
  import { create } from 'zustand';
21
  import { devtools } from 'zustand/middleware';
22
  import { immer } from 'zustand/middleware/immer';
23
  import { Operator, SwitchElseTo } from './constant';
 
24
  import {
25
  duplicateNodeForm,
26
  generateDuplicateNode,
 
30
  } from './utils';
31
 
32
  export type RFState = {
33
+ nodes: RAGFlowNodeType[];
34
  edges: Edge[];
35
  selectedNodeIds: string[];
36
  selectedEdgeIds: string[];
37
  clickedNodeId: string; // currently selected node
38
+ onNodesChange: OnNodesChange<RAGFlowNodeType>;
39
  onEdgesChange: OnEdgesChange;
40
  onConnect: OnConnect;
41
+ setNodes: (nodes: RAGFlowNodeType[]) => void;
42
  setEdges: (edges: Edge[]) => void;
43
  setEdgesByNodeId: (nodeId: string, edges: Edge[]) => void;
44
  updateNodeForm: (
45
  nodeId: string,
46
  values: any,
47
  path?: (string | number)[],
48
+ ) => RAGFlowNodeType[];
49
  onSelectionChange: OnSelectionChangeFunc;
50
+ addNode: (nodes: RAGFlowNodeType) => void;
51
+ getNode: (id?: string | null) => RAGFlowNodeType | undefined;
52
  addEdge: (connection: Connection) => void;
53
  getEdge: (id: string) => Edge | undefined;
54
  updateFormDataOnConnect: (connection: Connection) => void;
 
65
  deleteNodeById: (id: string) => void;
66
  deleteIterationNodeById: (id: string) => void;
67
  deleteEdgeBySourceAndSourceHandle: (connection: Partial<Connection>) => void;
68
+ findNodeByName: (operatorName: Operator) => RAGFlowNodeType | undefined;
69
  updateMutableNodeFormItem: (id: string, field: string, value: any) => void;
70
  getOperatorTypeFromId: (id?: string | null) => string | undefined;
71
  getParentIdById: (id?: string | null) => string | undefined;
 
78
  const useGraphStore = create<RFState>()(
79
  devtools(
80
  immer((set, get) => ({
81
+ nodes: [] as RAGFlowNodeType[],
82
  edges: [] as Edge[],
83
  selectedNodeIds: [] as string[],
84
  selectedEdgeIds: [] as string[],
85
  clickedNodeId: '',
86
+ onNodesChange: (changes) => {
87
  set({
88
  nodes: applyNodeChanges(changes, get().nodes),
89
  });
 
110
  selectedNodeIds: nodes.map((x) => x.id),
111
  });
112
  },
113
+ setNodes: (nodes: RAGFlowNodeType[]) => {
114
  set({ nodes });
115
  },
116
  setEdges: (edges: Edge[]) => {
 
162
  ]);
163
  }
164
  },
165
+ addNode: (node: RAGFlowNodeType) => {
166
  set({ nodes: get().nodes.concat(node) });
167
  },
168
  getNode: (id?: string | null) => {
 
260
  const { getNode, generateNodeName, nodes } = get();
261
  const node = getNode(id);
262
 
263
+ const iterationNode: RAGFlowNodeType = {
264
  ...(node || {}),
265
  data: {
266
  ...(node?.data || { label: Operator.Iteration, form: {} }),
web/src/pages/flow/utils.ts CHANGED
@@ -1,11 +1,15 @@
1
- import { DSLComponents } from '@/interfaces/database/flow';
 
 
 
 
2
  import { removeUselessFieldsFromValues } from '@/utils/form';
 
3
  import { FormInstance, FormListFieldData } from 'antd';
4
  import { humanId } from 'human-id';
5
  import { curry, get, intersectionWith, isEqual, sample } from 'lodash';
6
  import pipe from 'lodash/fp/pipe';
7
  import isObject from 'lodash/isObject';
8
- import { Edge, Node, Position, XYPosition } from 'reactflow';
9
  import { v4 as uuidv4 } from 'uuid';
10
  import {
11
  CategorizeAnchorPointPositions,
@@ -13,7 +17,7 @@ import {
13
  NodeMap,
14
  Operator,
15
  } from './constant';
16
- import { ICategorizeItemResult, IPosition, NodeData } from './interface';
17
 
18
  const buildEdges = (
19
  operatorIds: string[],
@@ -122,7 +126,7 @@ const buildOperatorParams = (operatorName: string) =>
122
 
123
  // construct a dsl based on the node information of the graph
124
  export const buildDslComponentsByGraph = (
125
- nodes: Node<NodeData>[],
126
  edges: Edge[],
127
  oldDslComponents: DSLComponents,
128
  ): DSLComponents => {
@@ -260,7 +264,7 @@ const splitName = (name: string) => {
260
 
261
  export const generateNodeNamesWithIncreasingIndex = (
262
  name: string,
263
- nodes: Node[],
264
  ) => {
265
  const templateNameList = nodes
266
  .filter((x) => {
@@ -298,7 +302,7 @@ export const generateNodeNamesWithIncreasingIndex = (
298
  return `${name}_${index}`;
299
  };
300
 
301
- export const duplicateNodeForm = (nodeData?: NodeData) => {
302
  const form: Record<string, any> = { ...(nodeData?.form ?? {}) };
303
 
304
  // Delete the downstream node corresponding to the to field of the Categorize operator
@@ -321,7 +325,7 @@ export const duplicateNodeForm = (nodeData?: NodeData) => {
321
  }
322
 
323
  return {
324
- ...(nodeData ?? {}),
325
  form,
326
  };
327
  };
@@ -336,7 +340,7 @@ export const needsSingleStepDebugging = (label: string) => {
336
 
337
  // Get the coordinates of the node relative to the Iteration node
338
  export function getRelativePositionToIterationNode(
339
- nodes: Node<NodeData>[],
340
  position?: XYPosition, // relative position
341
  ) {
342
  if (!position) {
 
1
+ import {
2
+ DSLComponents,
3
+ ICategorizeItemResult,
4
+ RAGFlowNodeType,
5
+ } from '@/interfaces/database/flow';
6
  import { removeUselessFieldsFromValues } from '@/utils/form';
7
+ import { Edge, Node, Position, XYPosition } from '@xyflow/react';
8
  import { FormInstance, FormListFieldData } from 'antd';
9
  import { humanId } from 'human-id';
10
  import { curry, get, intersectionWith, isEqual, sample } from 'lodash';
11
  import pipe from 'lodash/fp/pipe';
12
  import isObject from 'lodash/isObject';
 
13
  import { v4 as uuidv4 } from 'uuid';
14
  import {
15
  CategorizeAnchorPointPositions,
 
17
  NodeMap,
18
  Operator,
19
  } from './constant';
20
+ import { IPosition } from './interface';
21
 
22
  const buildEdges = (
23
  operatorIds: string[],
 
126
 
127
  // construct a dsl based on the node information of the graph
128
  export const buildDslComponentsByGraph = (
129
+ nodes: RAGFlowNodeType[],
130
  edges: Edge[],
131
  oldDslComponents: DSLComponents,
132
  ): DSLComponents => {
 
264
 
265
  export const generateNodeNamesWithIncreasingIndex = (
266
  name: string,
267
+ nodes: RAGFlowNodeType[],
268
  ) => {
269
  const templateNameList = nodes
270
  .filter((x) => {
 
302
  return `${name}_${index}`;
303
  };
304
 
305
+ export const duplicateNodeForm = (nodeData?: RAGFlowNodeType['data']) => {
306
  const form: Record<string, any> = { ...(nodeData?.form ?? {}) };
307
 
308
  // Delete the downstream node corresponding to the to field of the Categorize operator
 
325
  }
326
 
327
  return {
328
+ ...(nodeData ?? { label: '' }),
329
  form,
330
  };
331
  };
 
340
 
341
  // Get the coordinates of the node relative to the Iteration node
342
  export function getRelativePositionToIterationNode(
343
+ nodes: RAGFlowNodeType[],
344
  position?: XYPosition, // relative position
345
  ) {
346
  if (!position) {