balibabu commited on
Commit
023bae0
·
1 Parent(s): ee39a70

feat: create blank canvas #918 (#1356)

Browse files

### What problem does this PR solve?

feat: create blank canvas #918

### Type of change


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

graph/test/dsl_examples/{intergreper.json → interpreter.json} RENAMED
File without changes
web/src/assets/svg/nothing.svg ADDED
web/src/hooks/flow-hooks.ts CHANGED
@@ -5,6 +5,44 @@ import flowService from '@/services/flow-service';
5
  import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
6
  import { message } from 'antd';
7
  import { useParams } from 'umi';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
  export const useFetchFlowTemplates = (): ResponseType<IFlowTemplate[]> => {
10
  const { data } = useQuery({
@@ -12,6 +50,14 @@ export const useFetchFlowTemplates = (): ResponseType<IFlowTemplate[]> => {
12
  initialData: [],
13
  queryFn: async () => {
14
  const { data } = await flowService.listTemplates();
 
 
 
 
 
 
 
 
15
 
16
  return data;
17
  },
 
5
  import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
6
  import { message } from 'antd';
7
  import { useParams } from 'umi';
8
+ import { v4 as uuid } from 'uuid';
9
+
10
+ export const EmptyDsl = {
11
+ graph: {
12
+ nodes: [
13
+ {
14
+ id: 'Begin',
15
+ type: 'beginNode',
16
+ position: {
17
+ x: 50,
18
+ y: 200,
19
+ },
20
+ data: {
21
+ label: 'Begin',
22
+ name: 'begin',
23
+ },
24
+ sourcePosition: 'left',
25
+ targetPosition: 'right',
26
+ },
27
+ ],
28
+ edges: [],
29
+ },
30
+ components: {
31
+ begin: {
32
+ obj: {
33
+ component_name: 'Begin',
34
+ params: {},
35
+ },
36
+ downstream: ['Answer:China'], // other edge target is downstream, edge source is current node id
37
+ upstream: [], // edge source is upstream, edge target is current node id
38
+ },
39
+ },
40
+ messages: [],
41
+ reference: [],
42
+ history: [],
43
+ path: [],
44
+ answer: [],
45
+ };
46
 
47
  export const useFetchFlowTemplates = (): ResponseType<IFlowTemplate[]> => {
48
  const { data } = useQuery({
 
50
  initialData: [],
51
  queryFn: async () => {
52
  const { data } = await flowService.listTemplates();
53
+ if (Array.isArray(data?.data)) {
54
+ data.data.unshift({
55
+ id: uuid(),
56
+ title: 'Blank',
57
+ description: 'Create from nothing',
58
+ dsl: EmptyDsl,
59
+ });
60
+ }
61
 
62
  return data;
63
  },
web/src/pages/flow/hooks.ts CHANGED
@@ -253,7 +253,7 @@ export const useValidateConnection = () => {
253
  // restricted lines cannot be connected successfully.
254
  const isValidConnection = useCallback(
255
  (connection: Connection) => {
256
- // limit there to be only one line between two nodes
257
  const hasLine = edges.some(
258
  (x) => x.source === connection.source && x.target === connection.target,
259
  );
 
253
  // restricted lines cannot be connected successfully.
254
  const isValidConnection = useCallback(
255
  (connection: Connection) => {
256
+ // limit the connection between two nodes to only one connection line in one direction
257
  const hasLine = edges.some(
258
  (x) => x.source === connection.source && x.target === connection.target,
259
  );
web/src/pages/flow/interpreter.json ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "edges": [
3
+ {
4
+ "id": "c87c7805-8cf0-4cd4-b45b-152031811020",
5
+ "label": "",
6
+ "source": "begin",
7
+ "target": "answer:0"
8
+ },
9
+ {
10
+ "id": "e30320bb-601b-4885-acb3-79becdc49f08",
11
+ "label": "",
12
+ "source": "generate:0",
13
+ "target": "answer:0"
14
+ },
15
+ {
16
+ "id": "83927e42-739a-402a-9f75-a88d4fab37ed",
17
+ "label": "",
18
+ "source": "answer:0",
19
+ "target": "generate:0"
20
+ }
21
+ ],
22
+ "nodes": [
23
+ {
24
+ "id": "begin",
25
+ "type": "beginNode",
26
+ "position": {
27
+ "x": 0,
28
+ "y": 0
29
+ },
30
+ "data": {
31
+ "label": "Begin",
32
+ "name": "FruityPianosSend",
33
+ "form": {
34
+ "prologue": "Hi there! Please enter the text you want to translate in format like: 'text you want to translate' => target language. For an example: 您好! => English"
35
+ }
36
+ },
37
+ "sourcePosition": "left",
38
+ "targetPosition": "right"
39
+ },
40
+ {
41
+ "id": "answer:0",
42
+ "type": "ragNode",
43
+ "position": {
44
+ "x": 0,
45
+ "y": 0
46
+ },
47
+ "data": {
48
+ "label": "Answer",
49
+ "name": "YummyBoatsFlow",
50
+ "form": {}
51
+ },
52
+ "sourcePosition": "left",
53
+ "targetPosition": "right"
54
+ },
55
+ {
56
+ "id": "generate:0",
57
+ "type": "ragNode",
58
+ "position": {
59
+ "x": 0,
60
+ "y": 0
61
+ },
62
+ "data": {
63
+ "label": "Generate",
64
+ "name": "SwiftTramsDrop",
65
+ "form": {
66
+ "llm_id": "deepseek-chat",
67
+ "prompt": "You are an professional interpreter.\n- Role: an professional interpreter.\n- Input format: content need to be translated => target language. \n- Answer format: => translated content in target language. \n- Examples:\n - user: 您好! => English. assistant: => How are you doing!\n - user: You look good today. => Japanese. assistant: => 今日は調子がいいですね 。\n",
68
+ "temperature": 0.5
69
+ }
70
+ },
71
+ "sourcePosition": "left",
72
+ "targetPosition": "right"
73
+ }
74
+ ]
75
+ }
web/src/pages/flow/list/create-flow-modal.tsx CHANGED
@@ -1,8 +1,8 @@
 
1
  import { IModalManagerChildrenProps } from '@/components/modal-manager';
2
  import { useTranslate } from '@/hooks/commonHooks';
3
  import { useFetchFlowTemplates } from '@/hooks/flow-hooks';
4
  import { useSelectItem } from '@/hooks/logicHooks';
5
- import { UserOutlined } from '@ant-design/icons';
6
  import {
7
  Avatar,
8
  Card,
@@ -79,7 +79,7 @@ const CreateFlowModal = ({
79
  <Input />
80
  </Form.Item>
81
  </Form>
82
- <Title level={5}>Choose from templates</Title>
83
  <Flex vertical gap={16}>
84
  {list?.map((x) => (
85
  <Card
@@ -90,7 +90,11 @@ const CreateFlowModal = ({
90
  onClick={handleItemClick(x.id)}
91
  >
92
  <Space size={'middle'}>
93
- <Avatar size={40} icon={<UserOutlined />} src={x.avatar} />
 
 
 
 
94
  <b>{x.title}</b>
95
  </Space>
96
  <p>{x.description}</p>
 
1
+ import { ReactComponent as NothingIcon } from '@/assets/svg/nothing.svg';
2
  import { IModalManagerChildrenProps } from '@/components/modal-manager';
3
  import { useTranslate } from '@/hooks/commonHooks';
4
  import { useFetchFlowTemplates } from '@/hooks/flow-hooks';
5
  import { useSelectItem } from '@/hooks/logicHooks';
 
6
  import {
7
  Avatar,
8
  Card,
 
79
  <Input />
80
  </Form.Item>
81
  </Form>
82
+ <Title level={5}>Create from templates</Title>
83
  <Flex vertical gap={16}>
84
  {list?.map((x) => (
85
  <Card
 
90
  onClick={handleItemClick(x.id)}
91
  >
92
  <Space size={'middle'}>
93
+ {x.avatar ? (
94
+ <Avatar size={40} icon={<NothingIcon />} src={x.avatar} />
95
+ ) : (
96
+ <NothingIcon width={40} height={30} />
97
+ )}
98
  <b>{x.title}</b>
99
  </Space>
100
  <p>{x.description}</p>
web/src/pages/flow/list/hooks.ts CHANGED
@@ -11,6 +11,8 @@ import { useNavigate } from 'umi';
11
  // import dslJson from '../../../../../dls.json';
12
  // import customerServiceBase from '../../../../../graph/test/dsl_examples/customer_service.json';
13
  // import customerService from '../customer_service.json';
 
 
14
 
15
  export const useFetchDataOnMount = () => {
16
  const { data, loading } = useFetchFlowList();
@@ -41,7 +43,7 @@ export const useSaveFlow = () => {
41
  title,
42
  dsl,
43
  // dsl: dslJson,
44
- // dsl: { ...customerServiceBase, graph: customerService },
45
  });
46
 
47
  if (ret?.retcode === 0) {
 
11
  // import dslJson from '../../../../../dls.json';
12
  // import customerServiceBase from '../../../../../graph/test/dsl_examples/customer_service.json';
13
  // import customerService from '../customer_service.json';
14
+ // import interpreterBase from '../../../../../graph/test/dsl_examples/interpreter.json';
15
+ // import interpreter from '../interpreter.json';
16
 
17
  export const useFetchDataOnMount = () => {
18
  const { data, loading } = useFetchFlowList();
 
43
  title,
44
  dsl,
45
  // dsl: dslJson,
46
+ // dsl: { ...interpreterBase, graph: interpreter },
47
  });
48
 
49
  if (ret?.retcode === 0) {
web/src/pages/flow/message-form/index.tsx CHANGED
@@ -54,7 +54,8 @@ const MessageForm = ({ onValuesChange, form }: IOperatorForm) => {
54
  ]}
55
  noStyle
56
  >
57
- <Input
 
58
  placeholder={t('messagePlaceholder')}
59
  style={{ width: '80%' }}
60
  />
 
54
  ]}
55
  noStyle
56
  >
57
+ <Input.TextArea
58
+ rows={4}
59
  placeholder={t('messagePlaceholder')}
60
  style={{ width: '80%' }}
61
  />
web/src/pages/flow/utils.test.ts CHANGED
@@ -2,6 +2,7 @@ import fs from 'fs';
2
  import path from 'path';
3
  import customer_service from '../../../../graph/test/dsl_examples/customer_service.json';
4
  import headhunter_zh from '../../../../graph/test/dsl_examples/headhunter_zh.json';
 
5
  import { dsl } from './mock';
6
  import { buildNodesAndEdgesFromDSLComponents } from './utils';
7
 
@@ -68,3 +69,21 @@ test('build nodes and edges from customer_service dsl', () => {
68
  }
69
  expect(nodes.length).toEqual(12);
70
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  import path from 'path';
3
  import customer_service from '../../../../graph/test/dsl_examples/customer_service.json';
4
  import headhunter_zh from '../../../../graph/test/dsl_examples/headhunter_zh.json';
5
+ import interpreter from '../../../../graph/test/dsl_examples/interpreter.json';
6
  import { dsl } from './mock';
7
  import { buildNodesAndEdgesFromDSLComponents } from './utils';
8
 
 
69
  }
70
  expect(nodes.length).toEqual(12);
71
  });
72
+
73
+ test('build nodes and edges from interpreter dsl', () => {
74
+ const { edges, nodes } = buildNodesAndEdgesFromDSLComponents(
75
+ interpreter.components,
76
+ );
77
+ console.info('node length', nodes.length);
78
+ console.info('edge length', edges.length);
79
+ try {
80
+ fs.writeFileSync(
81
+ path.join(__dirname, 'interpreter.json'),
82
+ JSON.stringify({ edges, nodes }, null, 4),
83
+ );
84
+ console.log('JSON data is saved.');
85
+ } catch (error) {
86
+ console.warn(error);
87
+ }
88
+ expect(nodes.length).toEqual(12);
89
+ });