balibabu commited on
Commit
f9e19e4
·
1 Parent(s): 22978e1

feat: Fetch mind map in search page #2247 (#2292)

Browse files

### What problem does this PR solve?
feat: Fetch mind map in search page #2247

### Type of change


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

web/src/components/indented-tree/indented-tree.tsx CHANGED
@@ -16,7 +16,7 @@ import {
16
  } from '@antv/g6';
17
  import { TreeData } from '@antv/g6/lib/types';
18
  import isEmpty from 'lodash/isEmpty';
19
- import { useCallback, useEffect, useRef } from 'react';
20
 
21
  const rootId = 'root';
22
 
@@ -294,9 +294,10 @@ register(
294
  interface IProps {
295
  data: TreeData;
296
  show: boolean;
 
297
  }
298
 
299
- const IndentedTree = ({ data, show }: IProps) => {
300
  const containerRef = useRef<HTMLDivElement>(null);
301
  const graphRef = useRef<Graph | null>(null);
302
 
@@ -388,6 +389,7 @@ const IndentedTree = ({ data, show }: IProps) => {
388
  width: '90vw',
389
  height: '80vh',
390
  display: show ? 'block' : 'none',
 
391
  }}
392
  />
393
  );
 
16
  } from '@antv/g6';
17
  import { TreeData } from '@antv/g6/lib/types';
18
  import isEmpty from 'lodash/isEmpty';
19
+ import React, { useCallback, useEffect, useRef } from 'react';
20
 
21
  const rootId = 'root';
22
 
 
294
  interface IProps {
295
  data: TreeData;
296
  show: boolean;
297
+ style?: React.CSSProperties;
298
  }
299
 
300
+ const IndentedTree = ({ data, show, style = {} }: IProps) => {
301
  const containerRef = useRef<HTMLDivElement>(null);
302
  const graphRef = useRef<Graph | null>(null);
303
 
 
389
  width: '90vw',
390
  height: '80vh',
391
  display: show ? 'block' : 'none',
392
+ ...style,
393
  }}
394
  />
395
  );
web/src/hooks/chat-hooks.ts CHANGED
@@ -490,13 +490,32 @@ export const useFetchMindMap = () => {
490
  mutateAsync,
491
  } = useMutation({
492
  mutationKey: ['fetchMindMap'],
 
493
  mutationFn: async (params: IAskRequestBody) => {
494
  const { data } = await chatService.getMindMap(params);
495
 
496
- return data;
497
  },
498
  });
499
 
500
  return { data, loading, fetchMindMap: mutateAsync };
501
  };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
502
  //#endregion
 
490
  mutateAsync,
491
  } = useMutation({
492
  mutationKey: ['fetchMindMap'],
493
+ gcTime: 0,
494
  mutationFn: async (params: IAskRequestBody) => {
495
  const { data } = await chatService.getMindMap(params);
496
 
497
+ return data?.data ?? [];
498
  },
499
  });
500
 
501
  return { data, loading, fetchMindMap: mutateAsync };
502
  };
503
+
504
+ export const useFetchRelatedQuestions = () => {
505
+ const {
506
+ data,
507
+ isPending: loading,
508
+ mutateAsync,
509
+ } = useMutation({
510
+ mutationKey: ['fetchRelatedQuestions'],
511
+ gcTime: 0,
512
+ mutationFn: async (question: string): Promise<string[]> => {
513
+ const { data } = await chatService.getRelatedQuestions({ question });
514
+
515
+ return data?.data ?? [];
516
+ },
517
+ });
518
+
519
+ return { data, loading, fetchRelatedQuestions: mutateAsync };
520
+ };
521
  //#endregion
web/src/hooks/flow-hooks.ts CHANGED
@@ -57,7 +57,7 @@ export const useFetchFlowTemplates = (): ResponseType<IFlowTemplate[]> => {
57
  data.data.unshift({
58
  id: uuid(),
59
  title: 'Blank',
60
- description: 'Create from nothing',
61
  dsl: EmptyDsl,
62
  });
63
  }
 
57
  data.data.unshift({
58
  id: uuid(),
59
  title: 'Blank',
60
+ description: 'Create your agent from scratch',
61
  dsl: EmptyDsl,
62
  });
63
  }
web/src/interfaces/request/chat.ts CHANGED
@@ -5,6 +5,6 @@ export interface IFeedbackRequestBody {
5
  }
6
 
7
  export interface IAskRequestBody {
8
- questionkb_ids: string;
9
  kb_ids: string[];
10
  }
 
5
  }
6
 
7
  export interface IAskRequestBody {
8
+ question: string;
9
  kb_ids: string[];
10
  }
web/src/layouts/components/header/index.tsx CHANGED
@@ -9,7 +9,7 @@ import { useLocation } from 'umi';
9
  import Toolbar from '../right-toolbar';
10
 
11
  import { useFetchAppConf } from '@/hooks/logic-hooks';
12
- import { MessageOutlined } from '@ant-design/icons';
13
  import styles from './index.less';
14
 
15
  const { Header } = Layout;
@@ -26,8 +26,8 @@ const RagHeader = () => {
26
  const tagsData = useMemo(
27
  () => [
28
  { path: '/knowledge', name: t('knowledgeBase'), icon: KnowledgeBaseIcon },
29
- { path: '/chat', name: t('chat'), icon: MessageOutlined },
30
- // { path: '/search', name: t('search'), icon: SearchOutlined },
31
  { path: '/flow', name: t('flow'), icon: GraphIcon },
32
  { path: '/file', name: t('fileManager'), icon: FileIcon },
33
  ],
 
9
  import Toolbar from '../right-toolbar';
10
 
11
  import { useFetchAppConf } from '@/hooks/logic-hooks';
12
+ import { SearchOutlined } from '@ant-design/icons';
13
  import styles from './index.less';
14
 
15
  const { Header } = Layout;
 
26
  const tagsData = useMemo(
27
  () => [
28
  { path: '/knowledge', name: t('knowledgeBase'), icon: KnowledgeBaseIcon },
29
+ // { path: '/chat', name: t('chat'), icon: MessageOutlined },
30
+ { path: '/search', name: t('search'), icon: SearchOutlined },
31
  { path: '/flow', name: t('flow'), icon: GraphIcon },
32
  { path: '/file', name: t('fileManager'), icon: FileIcon },
33
  ],
web/src/locales/en.ts CHANGED
@@ -634,6 +634,7 @@ The above is the content you need to summarize.`,
634
  messagePlaceholder: 'message',
635
  messageMsg: 'Please input message or delete this field.',
636
  addField: 'Add field',
 
637
  loop: 'Loop',
638
  loopTip:
639
  'Loop is the upper limit of the number of loops of the current component, when the number of loops exceeds the value of loop, it means that the component can not complete the current task, please re-optimize agent',
@@ -672,7 +673,7 @@ The above is the content you need to summarize.`,
672
  begin: 'Begin',
673
  message: 'Message',
674
  blank: 'Blank',
675
- createFromNothing: 'Create from nothing',
676
  addItem: 'Add Item',
677
  addSubItem: 'Add Sub Item',
678
  nameRequiredMsg: 'Name is required',
 
634
  messagePlaceholder: 'message',
635
  messageMsg: 'Please input message or delete this field.',
636
  addField: 'Add field',
637
+ addMessage: 'Add message',
638
  loop: 'Loop',
639
  loopTip:
640
  'Loop is the upper limit of the number of loops of the current component, when the number of loops exceeds the value of loop, it means that the component can not complete the current task, please re-optimize agent',
 
673
  begin: 'Begin',
674
  message: 'Message',
675
  blank: 'Blank',
676
+ createFromNothing: 'Create your agent from scratch',
677
  addItem: 'Add Item',
678
  addSubItem: 'Add Sub Item',
679
  nameRequiredMsg: 'Name is required',
web/src/locales/zh-traditional.ts CHANGED
@@ -590,6 +590,7 @@ export default {
590
  messagePlaceholder: '訊息',
591
  messageMsg: '請輸入訊息或刪除此欄位。',
592
  addField: '新增字段',
 
593
  loop: '循環上限',
594
  loopTip:
595
  'loop為目前元件循環次數上限,當循環次數超過loop的值時,表示元件無法完成目前任務,請重新最佳化agent',
 
590
  messagePlaceholder: '訊息',
591
  messageMsg: '請輸入訊息或刪除此欄位。',
592
  addField: '新增字段',
593
+ addMessage: '新增訊息',
594
  loop: '循環上限',
595
  loopTip:
596
  'loop為目前元件循環次數上限,當循環次數超過loop的值時,表示元件無法完成目前任務,請重新最佳化agent',
web/src/locales/zh.ts CHANGED
@@ -609,6 +609,7 @@ export default {
609
  messagePlaceholder: '消息',
610
  messageMsg: '请输入消息或删除此字段。',
611
  addField: '新增字段',
 
612
  loop: '循环上限',
613
  loopTip:
614
  'loop为当前组件循环次数上限,当循环次数超过loop的值时,说明组件不能完成当前任务,请重新优化agent',
 
609
  messagePlaceholder: '消息',
610
  messageMsg: '请输入消息或删除此字段。',
611
  addField: '新增字段',
612
+ addMessage: '新增消息',
613
  loop: '循环上限',
614
  loopTip:
615
  'loop为当前组件循环次数上限,当循环次数超过loop的值时,说明组件不能完成当前任务,请重新优化agent',
web/src/pages/chat/chat-configuration-modal/assistant-setting.tsx CHANGED
@@ -90,7 +90,7 @@ const AssistantSetting = ({ show }: ISegmentedContentProps) => {
90
  >
91
  <Switch />
92
  </Form.Item>
93
- <Form.Item
94
  label={t('selfRag')}
95
  valuePropName="checked"
96
  name={['prompt_config', 'self_rag']}
@@ -98,7 +98,7 @@ const AssistantSetting = ({ show }: ISegmentedContentProps) => {
98
  initialValue={false}
99
  >
100
  <Switch />
101
- </Form.Item>
102
  {/* <Form.Item
103
  label={t('tts')}
104
  valuePropName="checked"
 
90
  >
91
  <Switch />
92
  </Form.Item>
93
+ {/* <Form.Item
94
  label={t('selfRag')}
95
  valuePropName="checked"
96
  name={['prompt_config', 'self_rag']}
 
98
  initialValue={false}
99
  >
100
  <Switch />
101
+ </Form.Item> */}
102
  {/* <Form.Item
103
  label={t('tts')}
104
  valuePropName="checked"
web/src/pages/flow/message-form/index.tsx CHANGED
@@ -74,7 +74,7 @@ const MessageForm = ({ onValuesChange, form }: IOperatorForm) => {
74
  style={{ width: '80%' }}
75
  icon={<PlusOutlined />}
76
  >
77
- {t('addField')}
78
  </Button>
79
  </Form.Item>
80
  </>
 
74
  style={{ width: '80%' }}
75
  icon={<PlusOutlined />}
76
  >
77
+ {t('addMessage')}
78
  </Button>
79
  </Form.Item>
80
  </>
web/src/pages/force-graph/index.tsx CHANGED
@@ -1,112 +1,3 @@
1
- import { Graph } from '@antv/g6';
2
- import { useSize } from 'ahooks';
3
- import { useEffect, useRef } from 'react';
4
- import { graphData } from './constant';
5
  import InputWithUpload from './input-upload';
6
 
7
- import styles from './index.less';
8
- import { Converter } from './util';
9
-
10
- const converter = new Converter();
11
-
12
- const nextData = converter.buildNodesAndCombos(
13
- graphData.nodes,
14
- graphData.edges,
15
- );
16
- console.log('🚀 ~ nextData:', nextData);
17
-
18
- const finalData = { ...graphData, ...nextData };
19
-
20
- const ForceGraph = () => {
21
- const containerRef = useRef<HTMLDivElement>(null);
22
- const size = useSize(containerRef);
23
- let graph: Graph;
24
-
25
- const render = () => {
26
- graph = new Graph({
27
- container: containerRef.current!,
28
- autoFit: 'view',
29
- behaviors: [
30
- 'drag-element',
31
- 'drag-canvas',
32
- 'zoom-canvas',
33
- 'collapse-expand',
34
- {
35
- type: 'hover-activate',
36
- degree: 1, // 👈🏻 Activate relations.
37
- },
38
- ],
39
- plugins: [
40
- {
41
- type: 'tooltip',
42
- getContent: (e, items) => {
43
- if (items.every((x) => x?.description)) {
44
- let result = ``;
45
- items.forEach((item) => {
46
- if (item?.description) {
47
- result += `<p>${item?.description}</p>`;
48
- }
49
- });
50
- return result;
51
- }
52
- return undefined;
53
- },
54
- },
55
- ],
56
- layout: {
57
- type: 'combo-combined',
58
- preventOverlap: true,
59
- comboPadding: 1,
60
- spacing: 20,
61
- },
62
- node: {
63
- style: {
64
- size: 20,
65
- labelText: (d) => d.id,
66
- labelPadding: 30,
67
- // labelOffsetX: 20,
68
- // labelOffsetY: 5,
69
- labelPlacement: 'center',
70
- labelWordWrap: true,
71
- },
72
- palette: {
73
- type: 'group',
74
- field: (d) => d.combo,
75
- },
76
- // state: {
77
- // highlight: {
78
- // fill: '#D580FF',
79
- // halo: true,
80
- // lineWidth: 0,
81
- // },
82
- // dim: {
83
- // fill: '#99ADD1',
84
- // },
85
- // },
86
- },
87
- edge: {
88
- style: (model) => {
89
- const { size, color } = model.data;
90
- return {
91
- stroke: color || '#99ADD1',
92
- lineWidth: size || 1,
93
- };
94
- },
95
- },
96
- // data: graphData,
97
- });
98
-
99
- graph.setData(finalData);
100
-
101
- graph.render();
102
- };
103
-
104
- useEffect(() => {
105
- console.info('rendered');
106
- render();
107
- }, []);
108
-
109
- return <div ref={containerRef} className={styles.container} />;
110
- };
111
-
112
  export default InputWithUpload;
 
 
 
 
 
1
  import InputWithUpload from './input-upload';
2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  export default InputWithUpload;
web/src/pages/search/hooks.ts CHANGED
@@ -1,3 +1,4 @@
 
1
  import { useTestChunkRetrieval } from '@/hooks/knowledge-hooks';
2
  import { useSendMessageWithSse } from '@/hooks/logic-hooks';
3
  import { IAnswer } from '@/interfaces/database/chat';
@@ -10,6 +11,13 @@ export const useSendQuestion = (kbIds: string[]) => {
10
  const { testChunk, loading } = useTestChunkRetrieval();
11
  const [sendingLoading, setSendingLoading] = useState(false);
12
  const [currentAnswer, setCurrentAnswer] = useState({} as IAnswer);
 
 
 
 
 
 
 
13
 
14
  const sendQuestion = useCallback(
15
  (question: string) => {
@@ -17,8 +25,13 @@ export const useSendQuestion = (kbIds: string[]) => {
17
  setSendingLoading(true);
18
  send({ kb_ids: kbIds, question });
19
  testChunk({ kb_id: kbIds, highlight: true, question });
 
 
 
 
 
20
  },
21
- [send, testChunk, kbIds],
22
  );
23
 
24
  useEffect(() => {
@@ -33,5 +46,13 @@ export const useSendQuestion = (kbIds: string[]) => {
33
  }
34
  }, [done]);
35
 
36
- return { sendQuestion, loading, sendingLoading, answer: currentAnswer };
 
 
 
 
 
 
 
 
37
  };
 
1
+ import { useFetchMindMap, useFetchRelatedQuestions } from '@/hooks/chat-hooks';
2
  import { useTestChunkRetrieval } from '@/hooks/knowledge-hooks';
3
  import { useSendMessageWithSse } from '@/hooks/logic-hooks';
4
  import { IAnswer } from '@/interfaces/database/chat';
 
11
  const { testChunk, loading } = useTestChunkRetrieval();
12
  const [sendingLoading, setSendingLoading] = useState(false);
13
  const [currentAnswer, setCurrentAnswer] = useState({} as IAnswer);
14
+ const { fetchRelatedQuestions, data: relatedQuestions } =
15
+ useFetchRelatedQuestions();
16
+ const {
17
+ fetchMindMap,
18
+ data: mindMap,
19
+ loading: mindMapLoading,
20
+ } = useFetchMindMap();
21
 
22
  const sendQuestion = useCallback(
23
  (question: string) => {
 
25
  setSendingLoading(true);
26
  send({ kb_ids: kbIds, question });
27
  testChunk({ kb_id: kbIds, highlight: true, question });
28
+ fetchMindMap({
29
+ question,
30
+ kb_ids: kbIds,
31
+ });
32
+ fetchRelatedQuestions(question);
33
  },
34
+ [send, testChunk, kbIds, fetchRelatedQuestions, fetchMindMap],
35
  );
36
 
37
  useEffect(() => {
 
46
  }
47
  }, [done]);
48
 
49
+ return {
50
+ sendQuestion,
51
+ loading,
52
+ sendingLoading,
53
+ answer: currentAnswer,
54
+ relatedQuestions: relatedQuestions?.slice(0, 5) ?? [],
55
+ mindMap,
56
+ mindMapLoading,
57
+ };
58
  };
web/src/pages/search/index.less CHANGED
@@ -2,6 +2,10 @@
2
  .card {
3
  width: 100%;
4
  }
 
 
 
 
5
  }
6
 
7
  .searchSide {
@@ -49,6 +53,6 @@
49
 
50
  .graph {
51
  width: 40%;
52
- background-color: bisque;
53
  }
54
  }
 
2
  .card {
3
  width: 100%;
4
  }
5
+ .tag {
6
+ padding: 4px 8px;
7
+ font-size: 14px;
8
+ }
9
  }
10
 
11
  .searchSide {
 
53
 
54
  .graph {
55
  width: 40%;
56
+ padding-right: 10px;
57
  }
58
  }
web/src/pages/search/index.tsx CHANGED
@@ -2,12 +2,13 @@ import HightLightMarkdown from '@/components/highlight-markdown';
2
  import { ImageWithPopover } from '@/components/image';
3
  import { useSelectTestingResult } from '@/hooks/knowledge-hooks';
4
  import { IReference } from '@/interfaces/database/chat';
5
- import { Card, Flex, Input, Layout, List, Space } from 'antd';
6
  import { useState } from 'react';
7
  import MarkdownContent from '../chat/markdown-content';
8
  import { useSendQuestion } from './hooks';
9
  import SearchSidebar from './sidebar';
10
 
 
11
  import styles from './index.less';
12
 
13
  const { Content } = Layout;
@@ -16,7 +17,14 @@ const { Search } = Input;
16
  const SearchPage = () => {
17
  const [checkedList, setCheckedList] = useState<string[]>([]);
18
  const list = useSelectTestingResult();
19
- const { sendQuestion, answer, sendingLoading } = useSendQuestion(checkedList);
 
 
 
 
 
 
 
20
 
21
  return (
22
  <Layout className={styles.searchPage}>
@@ -56,8 +64,29 @@ const SearchPage = () => {
56
  </List.Item>
57
  )}
58
  />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  </section>
60
- <section className={styles.graph}></section>
61
  </Flex>
62
  </Content>
63
  </Layout>
 
2
  import { ImageWithPopover } from '@/components/image';
3
  import { useSelectTestingResult } from '@/hooks/knowledge-hooks';
4
  import { IReference } from '@/interfaces/database/chat';
5
+ import { Card, Flex, Input, Layout, List, Skeleton, Space, Tag } from 'antd';
6
  import { useState } from 'react';
7
  import MarkdownContent from '../chat/markdown-content';
8
  import { useSendQuestion } from './hooks';
9
  import SearchSidebar from './sidebar';
10
 
11
+ import IndentedTree from '@/components/indented-tree/indented-tree';
12
  import styles from './index.less';
13
 
14
  const { Content } = Layout;
 
17
  const SearchPage = () => {
18
  const [checkedList, setCheckedList] = useState<string[]>([]);
19
  const list = useSelectTestingResult();
20
+ const {
21
+ sendQuestion,
22
+ answer,
23
+ sendingLoading,
24
+ relatedQuestions,
25
+ mindMap,
26
+ mindMapLoading,
27
+ } = useSendQuestion(checkedList);
28
 
29
  return (
30
  <Layout className={styles.searchPage}>
 
64
  </List.Item>
65
  )}
66
  />
67
+ {relatedQuestions?.length > 0 && (
68
+ <Card>
69
+ <Flex wrap="wrap" gap={'10px 0'}>
70
+ {relatedQuestions?.map((x, idx) => (
71
+ <Tag key={idx} className={styles.tag}>
72
+ {x}
73
+ </Tag>
74
+ ))}
75
+ </Flex>
76
+ </Card>
77
+ )}
78
+ </section>
79
+ <section className={styles.graph}>
80
+ {mindMapLoading ? (
81
+ <Skeleton active />
82
+ ) : (
83
+ <IndentedTree
84
+ data={mindMap}
85
+ show
86
+ style={{ width: '100%', height: '100%' }}
87
+ ></IndentedTree>
88
+ )}
89
  </section>
 
90
  </Flex>
91
  </Content>
92
  </Layout>
web/src/pages/search/sidebar.tsx CHANGED
@@ -30,20 +30,23 @@ const SearchSidebar = ({ checkedList, setCheckedList }: IProps) => {
30
  const indeterminate =
31
  checkedList.length > 0 && checkedList.length < list.length;
32
 
33
- const onChange = useCallback((list: CheckboxValueType[]) => {
34
- setCheckedList(list as string[]);
35
- }, []);
 
 
 
36
 
37
  const onCheckAllChange: CheckboxProps['onChange'] = useCallback(
38
  (e: CheckboxChangeEvent) => {
39
  setCheckedList(e.target.checked ? ids : []);
40
  },
41
- [ids],
42
  );
43
 
44
  useEffect(() => {
45
  setCheckedList(ids);
46
- }, [ids]);
47
 
48
  return (
49
  <Sider className={styles.searchSide} theme={'light'} width={240}>
@@ -53,7 +56,7 @@ const SearchSidebar = ({ checkedList, setCheckedList }: IProps) => {
53
  onChange={onCheckAllChange}
54
  checked={checkAll}
55
  >
56
- Check all
57
  </Checkbox>
58
  <Checkbox.Group
59
  className={styles.checkGroup}
 
30
  const indeterminate =
31
  checkedList.length > 0 && checkedList.length < list.length;
32
 
33
+ const onChange = useCallback(
34
+ (list: CheckboxValueType[]) => {
35
+ setCheckedList(list as string[]);
36
+ },
37
+ [setCheckedList],
38
+ );
39
 
40
  const onCheckAllChange: CheckboxProps['onChange'] = useCallback(
41
  (e: CheckboxChangeEvent) => {
42
  setCheckedList(e.target.checked ? ids : []);
43
  },
44
+ [ids, setCheckedList],
45
  );
46
 
47
  useEffect(() => {
48
  setCheckedList(ids);
49
+ }, [ids, setCheckedList]);
50
 
51
  return (
52
  <Sider className={styles.searchSide} theme={'light'} width={240}>
 
56
  onChange={onCheckAllChange}
57
  checked={checkAll}
58
  >
59
+ All
60
  </Checkbox>
61
  <Checkbox.Group
62
  className={styles.checkGroup}
web/src/services/chat-service.ts CHANGED
@@ -25,6 +25,7 @@ const {
25
  tts,
26
  ask,
27
  mindmap,
 
28
  } = api;
29
 
30
  const methods = {
@@ -116,6 +117,10 @@ const methods = {
116
  url: mindmap,
117
  method: 'post',
118
  },
 
 
 
 
119
  } as const;
120
 
121
  const chatService = registerServer<keyof typeof methods>(methods, request);
 
25
  tts,
26
  ask,
27
  mindmap,
28
+ getRelatedQuestions,
29
  } = api;
30
 
31
  const methods = {
 
117
  url: mindmap,
118
  method: 'post',
119
  },
120
+ getRelatedQuestions: {
121
+ url: getRelatedQuestions,
122
+ method: 'post',
123
+ },
124
  } as const;
125
 
126
  const chatService = registerServer<keyof typeof methods>(methods, request);
web/src/utils/api.ts CHANGED
@@ -68,6 +68,7 @@ export default {
68
  tts: `${api_host}/conversation/tts`,
69
  ask: `${api_host}/conversation/ask`,
70
  mindmap: `${api_host}/conversation/mindmap`,
 
71
  // chat for external
72
  createToken: `${api_host}/api/new_token`,
73
  listToken: `${api_host}/api/token_list`,
 
68
  tts: `${api_host}/conversation/tts`,
69
  ask: `${api_host}/conversation/ask`,
70
  mindmap: `${api_host}/conversation/mindmap`,
71
+ getRelatedQuestions: `${api_host}/conversation/related_questions`,
72
  // chat for external
73
  createToken: `${api_host}/api/new_token`,
74
  listToken: `${api_host}/api/token_list`,