balibabu
commited on
Commit
·
8441328
1
Parent(s):
907a1f4
feat: add OperateDropdown and send debug message #918 (#1095)
Browse files### What problem does this PR solve?
feat: add OperateDropdown
feat: send debug message #918
### Type of change
- [x] New Feature (non-breaking change which adds functionality)
- web/src/components/operate-dropdown/index.less +3 -0
- web/src/components/operate-dropdown/index.tsx +61 -0
- web/src/hooks/flow-hooks.ts +1 -1
- web/src/hooks/logicHooks.ts +3 -3
- web/src/interfaces/database/flow.ts +4 -7
- web/src/pages/chat/utils.ts +2 -2
- web/src/pages/flow/chat/box.tsx +17 -25
- web/src/pages/flow/chat/drawer.tsx +21 -0
- web/src/pages/flow/chat/hooks.ts +50 -101
- web/src/pages/flow/chat/index.less +2 -1
- web/src/pages/flow/header/index.less +1 -1
- web/src/pages/flow/header/index.tsx +39 -14
- web/src/pages/flow/hooks.ts +2 -2
- web/src/pages/flow/list/flow-card/index.tsx +7 -47
- web/src/pages/flow/list/hooks.ts +5 -2
- web/src/pages/flow/mock.tsx +113 -111
- web/src/pages/flow/utils.ts +0 -5
- web/src/pages/knowledge/knowledge-card/index.tsx +4 -40
- web/src/utils/api.ts +1 -1
web/src/components/operate-dropdown/index.less
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
.delete {
|
2 |
+
height: 24px;
|
3 |
+
}
|
web/src/components/operate-dropdown/index.tsx
ADDED
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { ReactComponent as MoreIcon } from '@/assets/svg/more.svg';
|
2 |
+
import { useShowDeleteConfirm } from '@/hooks/commonHooks';
|
3 |
+
import { DeleteOutlined } from '@ant-design/icons';
|
4 |
+
import { Dropdown, MenuProps, Space } from 'antd';
|
5 |
+
import { useTranslation } from 'react-i18next';
|
6 |
+
|
7 |
+
import React from 'react';
|
8 |
+
import styles from './index.less';
|
9 |
+
|
10 |
+
interface IProps {
|
11 |
+
deleteItem: () => Promise<any>;
|
12 |
+
}
|
13 |
+
|
14 |
+
const OperateDropdown = ({
|
15 |
+
deleteItem,
|
16 |
+
children,
|
17 |
+
}: React.PropsWithChildren<IProps>) => {
|
18 |
+
const { t } = useTranslation();
|
19 |
+
const showDeleteConfirm = useShowDeleteConfirm();
|
20 |
+
|
21 |
+
const handleDelete = () => {
|
22 |
+
showDeleteConfirm({ onOk: deleteItem });
|
23 |
+
};
|
24 |
+
|
25 |
+
const handleDropdownMenuClick: MenuProps['onClick'] = ({ domEvent, key }) => {
|
26 |
+
domEvent.preventDefault();
|
27 |
+
domEvent.stopPropagation();
|
28 |
+
if (key === '1') {
|
29 |
+
handleDelete();
|
30 |
+
}
|
31 |
+
};
|
32 |
+
|
33 |
+
const items: MenuProps['items'] = [
|
34 |
+
{
|
35 |
+
key: '1',
|
36 |
+
label: (
|
37 |
+
<Space>
|
38 |
+
{t('common.delete')}
|
39 |
+
<DeleteOutlined />
|
40 |
+
</Space>
|
41 |
+
),
|
42 |
+
},
|
43 |
+
];
|
44 |
+
|
45 |
+
return (
|
46 |
+
<Dropdown
|
47 |
+
menu={{
|
48 |
+
items,
|
49 |
+
onClick: handleDropdownMenuClick,
|
50 |
+
}}
|
51 |
+
>
|
52 |
+
{children || (
|
53 |
+
<span className={styles.delete}>
|
54 |
+
<MoreIcon />
|
55 |
+
</span>
|
56 |
+
)}
|
57 |
+
</Dropdown>
|
58 |
+
);
|
59 |
+
};
|
60 |
+
|
61 |
+
export default OperateDropdown;
|
web/src/hooks/flow-hooks.ts
CHANGED
@@ -64,7 +64,7 @@ export const useSetFlow = () => {
|
|
64 |
);
|
65 |
queryClient.invalidateQueries({ queryKey: ['fetchFlowList'] });
|
66 |
}
|
67 |
-
return data
|
68 |
},
|
69 |
});
|
70 |
|
|
|
64 |
);
|
65 |
queryClient.invalidateQueries({ queryKey: ['fetchFlowList'] });
|
66 |
}
|
67 |
+
return data;
|
68 |
},
|
69 |
});
|
70 |
|
web/src/hooks/logicHooks.ts
CHANGED
@@ -206,14 +206,14 @@ export const useSendMessageWithSse = (
|
|
206 |
|
207 |
//#region chat hooks
|
208 |
|
209 |
-
export const useScrollToBottom = (
|
210 |
const ref = useRef<HTMLDivElement>(null);
|
211 |
|
212 |
const scrollToBottom = useCallback(() => {
|
213 |
-
if (
|
214 |
ref.current?.scrollIntoView({ behavior: 'instant' });
|
215 |
}
|
216 |
-
}, [
|
217 |
|
218 |
useEffect(() => {
|
219 |
scrollToBottom();
|
|
|
206 |
|
207 |
//#region chat hooks
|
208 |
|
209 |
+
export const useScrollToBottom = (messages?: unknown) => {
|
210 |
const ref = useRef<HTMLDivElement>(null);
|
211 |
|
212 |
const scrollToBottom = useCallback(() => {
|
213 |
+
if (messages) {
|
214 |
ref.current?.scrollIntoView({ behavior: 'instant' });
|
215 |
}
|
216 |
+
}, [messages]); // If the message changes, scroll to the bottom
|
217 |
|
218 |
useEffect(() => {
|
219 |
scrollToBottom();
|
web/src/interfaces/database/flow.ts
CHANGED
@@ -1,4 +1,5 @@
|
|
1 |
import { Edge, Node } from 'reactflow';
|
|
|
2 |
|
3 |
export type DSLComponents = Record<string, IOperator>;
|
4 |
|
@@ -8,6 +9,8 @@ export interface DSL {
|
|
8 |
path?: string[];
|
9 |
answer?: any[];
|
10 |
graph?: IGraph;
|
|
|
|
|
11 |
}
|
12 |
|
13 |
export interface IOperator {
|
@@ -32,13 +35,7 @@ export interface IFlow {
|
|
32 |
create_date: string;
|
33 |
create_time: number;
|
34 |
description: null;
|
35 |
-
dsl:
|
36 |
-
answer: any[];
|
37 |
-
components: DSLComponents;
|
38 |
-
graph: IGraph;
|
39 |
-
history: any[];
|
40 |
-
path: string[];
|
41 |
-
};
|
42 |
id: string;
|
43 |
title: string;
|
44 |
update_date: string;
|
|
|
1 |
import { Edge, Node } from 'reactflow';
|
2 |
+
import { IReference, Message } from './chat';
|
3 |
|
4 |
export type DSLComponents = Record<string, IOperator>;
|
5 |
|
|
|
9 |
path?: string[];
|
10 |
answer?: any[];
|
11 |
graph?: IGraph;
|
12 |
+
messages: Message[];
|
13 |
+
reference: IReference[];
|
14 |
}
|
15 |
|
16 |
export interface IOperator {
|
|
|
35 |
create_date: string;
|
36 |
create_time: number;
|
37 |
description: null;
|
38 |
+
dsl: DSL;
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
id: string;
|
40 |
title: string;
|
41 |
update_date: string;
|
web/src/pages/chat/utils.ts
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
import { MessageType } from '@/constants/chat';
|
2 |
import { IConversation, IReference } from '@/interfaces/database/chat';
|
3 |
import { EmptyConversationId } from './constants';
|
4 |
-
import {
|
5 |
|
6 |
export const isConversationIdExist = (conversationId: string) => {
|
7 |
return conversationId !== EmptyConversationId && conversationId !== '';
|
@@ -25,7 +25,7 @@ export const getDocumentIdsFromConversionReference = (data: IConversation) => {
|
|
25 |
};
|
26 |
|
27 |
export const buildMessageItemReference = (
|
28 |
-
conversation:
|
29 |
message: IMessage,
|
30 |
) => {
|
31 |
const assistantMessages = conversation.message
|
|
|
1 |
import { MessageType } from '@/constants/chat';
|
2 |
import { IConversation, IReference } from '@/interfaces/database/chat';
|
3 |
import { EmptyConversationId } from './constants';
|
4 |
+
import { IMessage } from './interface';
|
5 |
|
6 |
export const isConversationIdExist = (conversationId: string) => {
|
7 |
return conversationId !== EmptyConversationId && conversationId !== '';
|
|
|
25 |
};
|
26 |
|
27 |
export const buildMessageItemReference = (
|
28 |
+
conversation: { message: IMessage[]; reference: IReference[] },
|
29 |
message: IMessage,
|
30 |
) => {
|
31 |
const assistantMessages = conversation.message
|
web/src/pages/flow/chat/box.tsx
CHANGED
@@ -2,43 +2,34 @@ import MessageItem from '@/components/message-item';
|
|
2 |
import DocumentPreviewer from '@/components/pdf-previewer';
|
3 |
import { MessageType } from '@/constants/chat';
|
4 |
import { useTranslate } from '@/hooks/commonHooks';
|
5 |
-
import {
|
6 |
-
useClickDrawer,
|
7 |
-
useFetchConversationOnMount,
|
8 |
-
useGetFileIcon,
|
9 |
-
useGetSendButtonDisabled,
|
10 |
-
useSelectConversationLoading,
|
11 |
-
useSendMessage,
|
12 |
-
} from '@/pages/chat/hooks';
|
13 |
import { buildMessageItemReference } from '@/pages/chat/utils';
|
14 |
import { Button, Drawer, Flex, Input, Spin } from 'antd';
|
15 |
|
|
|
|
|
16 |
import styles from './index.less';
|
17 |
|
18 |
const FlowChatBox = () => {
|
19 |
const {
|
20 |
ref,
|
21 |
-
|
22 |
-
|
23 |
-
removeLatestMessage,
|
24 |
addNewestAnswer,
|
25 |
-
|
|
|
|
|
|
|
|
|
26 |
const {
|
27 |
handleInputChange,
|
28 |
handlePressEnter,
|
29 |
value,
|
30 |
loading: sendLoading,
|
31 |
-
} = useSendMessage(
|
32 |
-
conversation,
|
33 |
-
addNewestConversation,
|
34 |
-
removeLatestMessage,
|
35 |
-
addNewestAnswer,
|
36 |
-
);
|
37 |
const { visible, hideModal, documentId, selectedChunk, clickDocumentButton } =
|
38 |
useClickDrawer();
|
39 |
-
const disabled = useGetSendButtonDisabled();
|
40 |
useGetFileIcon();
|
41 |
-
const loading = useSelectConversationLoading();
|
42 |
const { t } = useTranslate('chat');
|
43 |
|
44 |
return (
|
@@ -47,17 +38,20 @@ const FlowChatBox = () => {
|
|
47 |
<Flex flex={1} vertical className={styles.messageContainer}>
|
48 |
<div>
|
49 |
<Spin spinning={loading}>
|
50 |
-
{
|
51 |
return (
|
52 |
<MessageItem
|
53 |
loading={
|
54 |
message.role === MessageType.Assistant &&
|
55 |
sendLoading &&
|
56 |
-
|
57 |
}
|
58 |
key={message.id}
|
59 |
item={message}
|
60 |
-
reference={buildMessageItemReference(
|
|
|
|
|
|
|
61 |
clickDocumentButton={clickDocumentButton}
|
62 |
></MessageItem>
|
63 |
);
|
@@ -70,13 +64,11 @@ const FlowChatBox = () => {
|
|
70 |
size="large"
|
71 |
placeholder={t('sendPlaceholder')}
|
72 |
value={value}
|
73 |
-
disabled={disabled}
|
74 |
suffix={
|
75 |
<Button
|
76 |
type="primary"
|
77 |
onClick={handlePressEnter}
|
78 |
loading={sendLoading}
|
79 |
-
disabled={disabled}
|
80 |
>
|
81 |
{t('send')}
|
82 |
</Button>
|
|
|
2 |
import DocumentPreviewer from '@/components/pdf-previewer';
|
3 |
import { MessageType } from '@/constants/chat';
|
4 |
import { useTranslate } from '@/hooks/commonHooks';
|
5 |
+
import { useClickDrawer, useGetFileIcon } from '@/pages/chat/hooks';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
import { buildMessageItemReference } from '@/pages/chat/utils';
|
7 |
import { Button, Drawer, Flex, Input, Spin } from 'antd';
|
8 |
|
9 |
+
import { useSelectCurrentMessages, useSendMessage } from './hooks';
|
10 |
+
|
11 |
import styles from './index.less';
|
12 |
|
13 |
const FlowChatBox = () => {
|
14 |
const {
|
15 |
ref,
|
16 |
+
currentMessages,
|
17 |
+
reference,
|
|
|
18 |
addNewestAnswer,
|
19 |
+
addNewestQuestion,
|
20 |
+
removeLatestMessage,
|
21 |
+
loading,
|
22 |
+
} = useSelectCurrentMessages();
|
23 |
+
|
24 |
const {
|
25 |
handleInputChange,
|
26 |
handlePressEnter,
|
27 |
value,
|
28 |
loading: sendLoading,
|
29 |
+
} = useSendMessage(addNewestQuestion, removeLatestMessage, addNewestAnswer);
|
|
|
|
|
|
|
|
|
|
|
30 |
const { visible, hideModal, documentId, selectedChunk, clickDocumentButton } =
|
31 |
useClickDrawer();
|
|
|
32 |
useGetFileIcon();
|
|
|
33 |
const { t } = useTranslate('chat');
|
34 |
|
35 |
return (
|
|
|
38 |
<Flex flex={1} vertical className={styles.messageContainer}>
|
39 |
<div>
|
40 |
<Spin spinning={loading}>
|
41 |
+
{currentMessages?.map((message, i) => {
|
42 |
return (
|
43 |
<MessageItem
|
44 |
loading={
|
45 |
message.role === MessageType.Assistant &&
|
46 |
sendLoading &&
|
47 |
+
currentMessages.length - 1 === i
|
48 |
}
|
49 |
key={message.id}
|
50 |
item={message}
|
51 |
+
reference={buildMessageItemReference(
|
52 |
+
{ message: currentMessages, reference },
|
53 |
+
message,
|
54 |
+
)}
|
55 |
clickDocumentButton={clickDocumentButton}
|
56 |
></MessageItem>
|
57 |
);
|
|
|
64 |
size="large"
|
65 |
placeholder={t('sendPlaceholder')}
|
66 |
value={value}
|
|
|
67 |
suffix={
|
68 |
<Button
|
69 |
type="primary"
|
70 |
onClick={handlePressEnter}
|
71 |
loading={sendLoading}
|
|
|
72 |
>
|
73 |
{t('send')}
|
74 |
</Button>
|
web/src/pages/flow/chat/drawer.tsx
CHANGED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { IModalProps } from '@/interfaces/common';
|
2 |
+
import { Drawer } from 'antd';
|
3 |
+
import FlowChatBox from './box';
|
4 |
+
|
5 |
+
const ChatDrawer = ({ visible, hideModal }: IModalProps<any>) => {
|
6 |
+
return (
|
7 |
+
<Drawer
|
8 |
+
title="Debug"
|
9 |
+
placement="right"
|
10 |
+
onClose={hideModal}
|
11 |
+
open={visible}
|
12 |
+
getContainer={false}
|
13 |
+
width={470}
|
14 |
+
zIndex={10000}
|
15 |
+
>
|
16 |
+
<FlowChatBox></FlowChatBox>
|
17 |
+
</Drawer>
|
18 |
+
);
|
19 |
+
};
|
20 |
+
|
21 |
+
export default ChatDrawer;
|
web/src/pages/flow/chat/hooks.ts
CHANGED
@@ -2,27 +2,25 @@ import { MessageType } from '@/constants/chat';
|
|
2 |
import { useFetchFlow } from '@/hooks/flow-hooks';
|
3 |
import {
|
4 |
useHandleMessageInputChange,
|
5 |
-
|
6 |
useSendMessageWithSse,
|
7 |
} from '@/hooks/logicHooks';
|
8 |
import { IAnswer } from '@/interfaces/database/chat';
|
9 |
import { IMessage } from '@/pages/chat/interface';
|
10 |
-
import
|
11 |
import { useCallback, useEffect, useState } from 'react';
|
12 |
import { useParams } from 'umi';
|
13 |
import { v4 as uuid } from 'uuid';
|
14 |
-
import { Operator } from '../constant';
|
15 |
-
import useGraphStore from '../store';
|
16 |
|
17 |
-
export const
|
18 |
const { id: id } = useParams();
|
19 |
-
const findNodeByName = useGraphStore((state) => state.findNodeByName);
|
20 |
const [currentMessages, setCurrentMessages] = useState<IMessage[]>([]);
|
21 |
|
22 |
-
const { data: flowDetail } = useFetchFlow();
|
23 |
-
const messages = flowDetail.dsl.
|
|
|
24 |
|
25 |
-
const
|
26 |
|
27 |
const addNewestQuestion = useCallback(
|
28 |
(message: string, answer: string = '') => {
|
@@ -45,121 +43,71 @@ export const useSelectCurrentConversation = () => {
|
|
45 |
[],
|
46 |
);
|
47 |
|
48 |
-
const addNewestAnswer = useCallback(
|
49 |
-
(
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
},
|
66 |
-
[currentMessages],
|
67 |
-
);
|
68 |
|
69 |
const removeLatestMessage = useCallback(() => {
|
70 |
setCurrentMessages((pre) => {
|
71 |
const nextMessages = pre?.slice(0, -2) ?? [];
|
|
|
72 |
return [...pre, ...nextMessages];
|
73 |
});
|
74 |
}, []);
|
75 |
|
76 |
-
const addPrologue = useCallback(() => {
|
77 |
-
if (id === '') {
|
78 |
-
const nextMessage = {
|
79 |
-
role: MessageType.Assistant,
|
80 |
-
content: prologue,
|
81 |
-
id: uuid(),
|
82 |
-
} as IMessage;
|
83 |
-
|
84 |
-
setCurrentMessages({
|
85 |
-
id: '',
|
86 |
-
reference: [],
|
87 |
-
message: [nextMessage],
|
88 |
-
} as any);
|
89 |
-
}
|
90 |
-
}, [id, prologue]);
|
91 |
-
|
92 |
-
useEffect(() => {
|
93 |
-
addPrologue();
|
94 |
-
}, [addPrologue]);
|
95 |
-
|
96 |
useEffect(() => {
|
97 |
if (id) {
|
98 |
-
|
|
|
99 |
}
|
100 |
}, [messages, id]);
|
101 |
|
102 |
return {
|
103 |
-
|
|
|
104 |
addNewestQuestion,
|
105 |
removeLatestMessage,
|
106 |
addNewestAnswer,
|
|
|
|
|
107 |
};
|
108 |
};
|
109 |
|
110 |
-
// export const useFetchConversationOnMount = () => {
|
111 |
-
// const { conversationId } = useGetChatSearchParams();
|
112 |
-
// const fetchConversation = useFetchConversation();
|
113 |
-
// const {
|
114 |
-
// currentConversation,
|
115 |
-
// addNewestQuestion,
|
116 |
-
// removeLatestMessage,
|
117 |
-
// addNewestAnswer,
|
118 |
-
// } = useSelectCurrentConversation();
|
119 |
-
// const ref = useScrollToBottom(currentConversation);
|
120 |
-
|
121 |
-
// const fetchConversationOnMount = useCallback(() => {
|
122 |
-
// if (isConversationIdExist(conversationId)) {
|
123 |
-
// fetchConversation(conversationId);
|
124 |
-
// }
|
125 |
-
// }, [fetchConversation, conversationId]);
|
126 |
-
|
127 |
-
// useEffect(() => {
|
128 |
-
// fetchConversationOnMount();
|
129 |
-
// }, [fetchConversationOnMount]);
|
130 |
-
|
131 |
-
// return {
|
132 |
-
// currentConversation,
|
133 |
-
// addNewestQuestion,
|
134 |
-
// ref,
|
135 |
-
// removeLatestMessage,
|
136 |
-
// addNewestAnswer,
|
137 |
-
// };
|
138 |
-
// };
|
139 |
-
|
140 |
export const useSendMessage = (
|
141 |
-
conversation: any,
|
142 |
addNewestQuestion: (message: string, answer?: string) => void,
|
143 |
removeLatestMessage: () => void,
|
144 |
addNewestAnswer: (answer: IAnswer) => void,
|
145 |
) => {
|
146 |
-
const { id:
|
147 |
const { handleInputChange, value, setValue } = useHandleMessageInputChange();
|
|
|
|
|
148 |
|
149 |
-
const { send, answer, done } = useSendMessageWithSse();
|
150 |
|
151 |
const sendMessage = useCallback(
|
152 |
async (message: string, id?: string) => {
|
153 |
-
const
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
},
|
161 |
-
],
|
162 |
-
});
|
163 |
|
164 |
if (res?.status !== 200) {
|
165 |
// cancel loading
|
@@ -167,13 +115,7 @@ export const useSendMessage = (
|
|
167 |
removeLatestMessage();
|
168 |
}
|
169 |
},
|
170 |
-
[
|
171 |
-
conversation?.message,
|
172 |
-
conversationId,
|
173 |
-
removeLatestMessage,
|
174 |
-
setValue,
|
175 |
-
send,
|
176 |
-
],
|
177 |
);
|
178 |
|
179 |
const handleSendMessage = useCallback(
|
@@ -189,6 +131,13 @@ export const useSendMessage = (
|
|
189 |
}
|
190 |
}, [answer, addNewestAnswer]);
|
191 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
192 |
const handlePressEnter = useCallback(() => {
|
193 |
if (done) {
|
194 |
setValue('');
|
|
|
2 |
import { useFetchFlow } from '@/hooks/flow-hooks';
|
3 |
import {
|
4 |
useHandleMessageInputChange,
|
5 |
+
useScrollToBottom,
|
6 |
useSendMessageWithSse,
|
7 |
} from '@/hooks/logicHooks';
|
8 |
import { IAnswer } from '@/interfaces/database/chat';
|
9 |
import { IMessage } from '@/pages/chat/interface';
|
10 |
+
import api from '@/utils/api';
|
11 |
import { useCallback, useEffect, useState } from 'react';
|
12 |
import { useParams } from 'umi';
|
13 |
import { v4 as uuid } from 'uuid';
|
|
|
|
|
14 |
|
15 |
+
export const useSelectCurrentMessages = () => {
|
16 |
const { id: id } = useParams();
|
|
|
17 |
const [currentMessages, setCurrentMessages] = useState<IMessage[]>([]);
|
18 |
|
19 |
+
const { data: flowDetail, loading } = useFetchFlow();
|
20 |
+
const messages = flowDetail.dsl.messages;
|
21 |
+
const reference = flowDetail.dsl.reference;
|
22 |
|
23 |
+
const ref = useScrollToBottom(currentMessages);
|
24 |
|
25 |
const addNewestQuestion = useCallback(
|
26 |
(message: string, answer: string = '') => {
|
|
|
43 |
[],
|
44 |
);
|
45 |
|
46 |
+
const addNewestAnswer = useCallback((answer: IAnswer) => {
|
47 |
+
setCurrentMessages((pre) => {
|
48 |
+
const latestMessage = pre?.at(-1);
|
49 |
+
|
50 |
+
if (latestMessage) {
|
51 |
+
return [
|
52 |
+
...pre.slice(0, -1),
|
53 |
+
{
|
54 |
+
...latestMessage,
|
55 |
+
content: answer.answer,
|
56 |
+
reference: answer.reference,
|
57 |
+
},
|
58 |
+
];
|
59 |
+
}
|
60 |
+
return pre;
|
61 |
+
});
|
62 |
+
}, []);
|
|
|
|
|
|
|
63 |
|
64 |
const removeLatestMessage = useCallback(() => {
|
65 |
setCurrentMessages((pre) => {
|
66 |
const nextMessages = pre?.slice(0, -2) ?? [];
|
67 |
+
return nextMessages;
|
68 |
return [...pre, ...nextMessages];
|
69 |
});
|
70 |
}, []);
|
71 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
72 |
useEffect(() => {
|
73 |
if (id) {
|
74 |
+
const nextMessages = messages.map((x) => ({ ...x, id: uuid() }));
|
75 |
+
setCurrentMessages(nextMessages);
|
76 |
}
|
77 |
}, [messages, id]);
|
78 |
|
79 |
return {
|
80 |
+
currentMessages,
|
81 |
+
reference,
|
82 |
addNewestQuestion,
|
83 |
removeLatestMessage,
|
84 |
addNewestAnswer,
|
85 |
+
ref,
|
86 |
+
loading,
|
87 |
};
|
88 |
};
|
89 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
90 |
export const useSendMessage = (
|
|
|
91 |
addNewestQuestion: (message: string, answer?: string) => void,
|
92 |
removeLatestMessage: () => void,
|
93 |
addNewestAnswer: (answer: IAnswer) => void,
|
94 |
) => {
|
95 |
+
const { id: flowId } = useParams();
|
96 |
const { handleInputChange, value, setValue } = useHandleMessageInputChange();
|
97 |
+
const { data: flowDetail } = useFetchFlow();
|
98 |
+
const messages = flowDetail.dsl.messages;
|
99 |
|
100 |
+
const { send, answer, done } = useSendMessageWithSse(api.runCanvas);
|
101 |
|
102 |
const sendMessage = useCallback(
|
103 |
async (message: string, id?: string) => {
|
104 |
+
const params: Record<string, unknown> = {
|
105 |
+
id: flowId,
|
106 |
+
};
|
107 |
+
if (message) {
|
108 |
+
params.message = message;
|
109 |
+
}
|
110 |
+
const res: Response | undefined = await send(params);
|
|
|
|
|
|
|
111 |
|
112 |
if (res?.status !== 200) {
|
113 |
// cancel loading
|
|
|
115 |
removeLatestMessage();
|
116 |
}
|
117 |
},
|
118 |
+
[flowId, removeLatestMessage, setValue, send],
|
|
|
|
|
|
|
|
|
|
|
|
|
119 |
);
|
120 |
|
121 |
const handleSendMessage = useCallback(
|
|
|
131 |
}
|
132 |
}, [answer, addNewestAnswer]);
|
133 |
|
134 |
+
useEffect(() => {
|
135 |
+
// fetch prologue
|
136 |
+
if (messages.length === 0) {
|
137 |
+
sendMessage('');
|
138 |
+
}
|
139 |
+
}, [sendMessage, messages]);
|
140 |
+
|
141 |
const handlePressEnter = useCallback(() => {
|
142 |
if (done) {
|
143 |
setValue('');
|
web/src/pages/flow/chat/index.less
CHANGED
@@ -1,5 +1,6 @@
|
|
1 |
.chatContainer {
|
2 |
-
padding: 0
|
|
|
3 |
.messageContainer {
|
4 |
overflow-y: auto;
|
5 |
padding-right: 24px;
|
|
|
1 |
.chatContainer {
|
2 |
+
padding: 0;
|
3 |
+
height: 100%;
|
4 |
.messageContainer {
|
5 |
overflow-y: auto;
|
6 |
padding-right: 24px;
|
web/src/pages/flow/header/index.less
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
.flowHeader {
|
2 |
-
padding: 20px;
|
3 |
}
|
|
|
1 |
.flowHeader {
|
2 |
+
padding: 0 20px;
|
3 |
}
|
web/src/pages/flow/header/index.tsx
CHANGED
@@ -1,26 +1,51 @@
|
|
1 |
-
import { Button, Flex } from 'antd';
|
2 |
|
|
|
|
|
|
|
|
|
|
|
3 |
import { useRunGraph, useSaveGraph } from '../hooks';
|
4 |
import styles from './index.less';
|
5 |
|
6 |
const FlowHeader = () => {
|
7 |
const { saveGraph } = useSaveGraph();
|
8 |
const { runGraph } = useRunGraph();
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
|
10 |
return (
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
<
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
);
|
25 |
};
|
26 |
|
|
|
1 |
+
import { Button, Flex, Space } from 'antd';
|
2 |
|
3 |
+
import { useSetModalState } from '@/hooks/commonHooks';
|
4 |
+
import { useFetchFlow } from '@/hooks/flow-hooks';
|
5 |
+
import { ArrowLeftOutlined } from '@ant-design/icons';
|
6 |
+
import { Link } from 'umi';
|
7 |
+
import ChatDrawer from '../chat/drawer';
|
8 |
import { useRunGraph, useSaveGraph } from '../hooks';
|
9 |
import styles from './index.less';
|
10 |
|
11 |
const FlowHeader = () => {
|
12 |
const { saveGraph } = useSaveGraph();
|
13 |
const { runGraph } = useRunGraph();
|
14 |
+
const {
|
15 |
+
visible: chatDrawerVisible,
|
16 |
+
hideModal: hideChatDrawer,
|
17 |
+
showModal: showChatDrawer,
|
18 |
+
} = useSetModalState();
|
19 |
+
const { data } = useFetchFlow();
|
20 |
|
21 |
return (
|
22 |
+
<>
|
23 |
+
<Flex
|
24 |
+
align="center"
|
25 |
+
justify={'space-between'}
|
26 |
+
gap={'large'}
|
27 |
+
className={styles.flowHeader}
|
28 |
+
>
|
29 |
+
<Space size={'large'}>
|
30 |
+
<Link to={`/flow`}>
|
31 |
+
<ArrowLeftOutlined />
|
32 |
+
</Link>
|
33 |
+
<h3>{data.title}</h3>
|
34 |
+
</Space>
|
35 |
+
<Space size={'large'}>
|
36 |
+
<Button onClick={showChatDrawer}>
|
37 |
+
<b>Debug</b>
|
38 |
+
</Button>
|
39 |
+
<Button type="primary" onClick={saveGraph}>
|
40 |
+
<b>Save</b>
|
41 |
+
</Button>
|
42 |
+
</Space>
|
43 |
+
</Flex>
|
44 |
+
<ChatDrawer
|
45 |
+
visible={chatDrawerVisible}
|
46 |
+
hideModal={hideChatDrawer}
|
47 |
+
></ChatDrawer>
|
48 |
+
</>
|
49 |
);
|
50 |
};
|
51 |
|
web/src/pages/flow/hooks.ts
CHANGED
@@ -187,7 +187,7 @@ const useSetGraphInfo = () => {
|
|
187 |
const { setEdges, setNodes } = useGraphStore((state) => state);
|
188 |
const setGraphInfo = useCallback(
|
189 |
({ nodes = [], edges = [] }: IGraph) => {
|
190 |
-
if (nodes.length
|
191 |
setNodes(nodes);
|
192 |
setEdges(edges);
|
193 |
}
|
@@ -202,7 +202,7 @@ export const useFetchDataOnMount = () => {
|
|
202 |
const setGraphInfo = useSetGraphInfo();
|
203 |
|
204 |
useEffect(() => {
|
205 |
-
setGraphInfo(data?.dsl?.graph ?? {});
|
206 |
}, [setGraphInfo, data?.dsl?.graph]);
|
207 |
|
208 |
useWatchGraphChange();
|
|
|
187 |
const { setEdges, setNodes } = useGraphStore((state) => state);
|
188 |
const setGraphInfo = useCallback(
|
189 |
({ nodes = [], edges = [] }: IGraph) => {
|
190 |
+
if (nodes.length || edges.length) {
|
191 |
setNodes(nodes);
|
192 |
setEdges(edges);
|
193 |
}
|
|
|
202 |
const setGraphInfo = useSetGraphInfo();
|
203 |
|
204 |
useEffect(() => {
|
205 |
+
setGraphInfo(data?.dsl?.graph ?? ({} as IGraph));
|
206 |
}, [setGraphInfo, data?.dsl?.graph]);
|
207 |
|
208 |
useWatchGraphChange();
|
web/src/pages/flow/list/flow-card/index.tsx
CHANGED
@@ -1,17 +1,12 @@
|
|
1 |
-
import { ReactComponent as MoreIcon } from '@/assets/svg/more.svg';
|
2 |
-
import { useShowDeleteConfirm } from '@/hooks/commonHooks';
|
3 |
import { formatDate } from '@/utils/date';
|
4 |
-
import {
|
5 |
-
|
6 |
-
DeleteOutlined,
|
7 |
-
UserOutlined,
|
8 |
-
} from '@ant-design/icons';
|
9 |
-
import { Avatar, Card, Dropdown, MenuProps, Space } from 'antd';
|
10 |
-
import { useTranslation } from 'react-i18next';
|
11 |
import { useNavigate } from 'umi';
|
12 |
|
|
|
13 |
import { useDeleteFlow } from '@/hooks/flow-hooks';
|
14 |
import { IFlow } from '@/interfaces/database/flow';
|
|
|
15 |
import styles from './index.less';
|
16 |
|
17 |
interface IProps {
|
@@ -20,37 +15,11 @@ interface IProps {
|
|
20 |
|
21 |
const FlowCard = ({ item }: IProps) => {
|
22 |
const navigate = useNavigate();
|
23 |
-
const showDeleteConfirm = useShowDeleteConfirm();
|
24 |
-
const { t } = useTranslation();
|
25 |
const { deleteFlow } = useDeleteFlow();
|
26 |
|
27 |
-
const
|
28 |
return deleteFlow([item.id]);
|
29 |
-
};
|
30 |
-
|
31 |
-
const handleDelete = () => {
|
32 |
-
showDeleteConfirm({ onOk: removeKnowledge });
|
33 |
-
};
|
34 |
-
|
35 |
-
const items: MenuProps['items'] = [
|
36 |
-
{
|
37 |
-
key: '1',
|
38 |
-
label: (
|
39 |
-
<Space>
|
40 |
-
{t('common.delete')}
|
41 |
-
<DeleteOutlined />
|
42 |
-
</Space>
|
43 |
-
),
|
44 |
-
},
|
45 |
-
];
|
46 |
-
|
47 |
-
const handleDropdownMenuClick: MenuProps['onClick'] = ({ domEvent, key }) => {
|
48 |
-
domEvent.preventDefault();
|
49 |
-
domEvent.stopPropagation();
|
50 |
-
if (key === '1') {
|
51 |
-
handleDelete();
|
52 |
-
}
|
53 |
-
};
|
54 |
|
55 |
const handleCardClick = () => {
|
56 |
navigate(`/flow/${item.id}`);
|
@@ -61,16 +30,7 @@ const FlowCard = ({ item }: IProps) => {
|
|
61 |
<div className={styles.container}>
|
62 |
<div className={styles.content}>
|
63 |
<Avatar size={34} icon={<UserOutlined />} src={item.avatar} />
|
64 |
-
<
|
65 |
-
menu={{
|
66 |
-
items,
|
67 |
-
onClick: handleDropdownMenuClick,
|
68 |
-
}}
|
69 |
-
>
|
70 |
-
<span className={styles.delete}>
|
71 |
-
<MoreIcon />
|
72 |
-
</span>
|
73 |
-
</Dropdown>
|
74 |
</div>
|
75 |
<div className={styles.titleWrapper}>
|
76 |
<span className={styles.title}>{item.title}</span>
|
|
|
|
|
|
|
1 |
import { formatDate } from '@/utils/date';
|
2 |
+
import { CalendarOutlined, UserOutlined } from '@ant-design/icons';
|
3 |
+
import { Avatar, Card } from 'antd';
|
|
|
|
|
|
|
|
|
|
|
4 |
import { useNavigate } from 'umi';
|
5 |
|
6 |
+
import OperateDropdown from '@/components/operate-dropdown';
|
7 |
import { useDeleteFlow } from '@/hooks/flow-hooks';
|
8 |
import { IFlow } from '@/interfaces/database/flow';
|
9 |
+
import { useCallback } from 'react';
|
10 |
import styles from './index.less';
|
11 |
|
12 |
interface IProps {
|
|
|
15 |
|
16 |
const FlowCard = ({ item }: IProps) => {
|
17 |
const navigate = useNavigate();
|
|
|
|
|
18 |
const { deleteFlow } = useDeleteFlow();
|
19 |
|
20 |
+
const removeFlow = useCallback(() => {
|
21 |
return deleteFlow([item.id]);
|
22 |
+
}, [deleteFlow, item]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
|
24 |
const handleCardClick = () => {
|
25 |
navigate(`/flow/${item.id}`);
|
|
|
30 |
<div className={styles.container}>
|
31 |
<div className={styles.content}>
|
32 |
<Avatar size={34} icon={<UserOutlined />} src={item.avatar} />
|
33 |
+
<OperateDropdown deleteItem={removeFlow}></OperateDropdown>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
</div>
|
35 |
<div className={styles.titleWrapper}>
|
36 |
<span className={styles.title}>{item.title}</span>
|
web/src/pages/flow/list/hooks.ts
CHANGED
@@ -1,6 +1,7 @@
|
|
1 |
import { useSetModalState } from '@/hooks/commonHooks';
|
2 |
import { useFetchFlowList, useSetFlow } from '@/hooks/flow-hooks';
|
3 |
import { useCallback, useState } from 'react';
|
|
|
4 |
import { dsl } from '../mock';
|
5 |
|
6 |
export const useFetchDataOnMount = () => {
|
@@ -17,16 +18,18 @@ export const useSaveFlow = () => {
|
|
17 |
showModal: showFileRenameModal,
|
18 |
} = useSetModalState();
|
19 |
const { loading, setFlow } = useSetFlow();
|
|
|
20 |
|
21 |
const onFlowOk = useCallback(
|
22 |
async (title: string) => {
|
23 |
const ret = await setFlow({ title, dsl });
|
24 |
|
25 |
-
if (ret === 0) {
|
26 |
hideFlowSettingModal();
|
|
|
27 |
}
|
28 |
},
|
29 |
-
[setFlow, hideFlowSettingModal],
|
30 |
);
|
31 |
|
32 |
const handleShowFlowSettingModal = useCallback(
|
|
|
1 |
import { useSetModalState } from '@/hooks/commonHooks';
|
2 |
import { useFetchFlowList, useSetFlow } from '@/hooks/flow-hooks';
|
3 |
import { useCallback, useState } from 'react';
|
4 |
+
import { useNavigate } from 'umi';
|
5 |
import { dsl } from '../mock';
|
6 |
|
7 |
export const useFetchDataOnMount = () => {
|
|
|
18 |
showModal: showFileRenameModal,
|
19 |
} = useSetModalState();
|
20 |
const { loading, setFlow } = useSetFlow();
|
21 |
+
const navigate = useNavigate();
|
22 |
|
23 |
const onFlowOk = useCallback(
|
24 |
async (title: string) => {
|
25 |
const ret = await setFlow({ title, dsl });
|
26 |
|
27 |
+
if (ret?.retcode === 0) {
|
28 |
hideFlowSettingModal();
|
29 |
+
navigate(`/flow/${ret.data.id}`);
|
30 |
}
|
31 |
},
|
32 |
+
[setFlow, hideFlowSettingModal, navigate],
|
33 |
);
|
34 |
|
35 |
const handleShowFlowSettingModal = useCallback(
|
web/src/pages/flow/mock.tsx
CHANGED
@@ -49,83 +49,83 @@ export const dsl = {
|
|
49 |
sourcePosition: 'left',
|
50 |
targetPosition: 'right',
|
51 |
},
|
52 |
-
{
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
},
|
65 |
-
{
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
},
|
78 |
-
{
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
},
|
91 |
],
|
92 |
edges: [
|
93 |
-
{
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
},
|
102 |
-
{
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
},
|
111 |
-
{
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
},
|
120 |
-
{
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
},
|
129 |
],
|
130 |
},
|
131 |
components: {
|
@@ -137,43 +137,45 @@ export const dsl = {
|
|
137 |
downstream: ['Answer:China'], // other edge target is downstream, edge source is current node id
|
138 |
upstream: [], // edge source is upstream, edge target is current node id
|
139 |
},
|
140 |
-
'Answer:China': {
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
},
|
148 |
-
'Retrieval:China': {
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
},
|
163 |
-
'Generate:China': {
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
},
|
176 |
},
|
|
|
|
|
177 |
history: [],
|
178 |
path: [],
|
179 |
answer: [],
|
|
|
49 |
sourcePosition: 'left',
|
50 |
targetPosition: 'right',
|
51 |
},
|
52 |
+
// {
|
53 |
+
// id: 'Answer:China',
|
54 |
+
// type: 'textUpdater',
|
55 |
+
// position: {
|
56 |
+
// x: 150,
|
57 |
+
// y: 200,
|
58 |
+
// },
|
59 |
+
// data: {
|
60 |
+
// label: 'Answer',
|
61 |
+
// },
|
62 |
+
// sourcePosition: 'left',
|
63 |
+
// targetPosition: 'right',
|
64 |
+
// },
|
65 |
+
// {
|
66 |
+
// id: 'Retrieval:China',
|
67 |
+
// type: 'textUpdater',
|
68 |
+
// position: {
|
69 |
+
// x: 250,
|
70 |
+
// y: 200,
|
71 |
+
// },
|
72 |
+
// data: {
|
73 |
+
// label: 'Retrieval',
|
74 |
+
// },
|
75 |
+
// sourcePosition: 'left',
|
76 |
+
// targetPosition: 'right',
|
77 |
+
// },
|
78 |
+
// {
|
79 |
+
// id: 'Generate:China',
|
80 |
+
// type: 'textUpdater',
|
81 |
+
// position: {
|
82 |
+
// x: 100,
|
83 |
+
// y: 100,
|
84 |
+
// },
|
85 |
+
// data: {
|
86 |
+
// label: 'Generate',
|
87 |
+
// },
|
88 |
+
// sourcePosition: 'left',
|
89 |
+
// targetPosition: 'right',
|
90 |
+
// },
|
91 |
],
|
92 |
edges: [
|
93 |
+
// {
|
94 |
+
// id: '7facb53d-65c9-43b3-ac55-339c445d3891',
|
95 |
+
// label: '',
|
96 |
+
// source: 'begin',
|
97 |
+
// target: 'Answer:China',
|
98 |
+
// markerEnd: {
|
99 |
+
// type: 'arrow',
|
100 |
+
// },
|
101 |
+
// },
|
102 |
+
// {
|
103 |
+
// id: '7ac83631-502d-410f-a6e7-bec6866a5e99',
|
104 |
+
// label: '',
|
105 |
+
// source: 'Generate:China',
|
106 |
+
// target: 'Answer:China',
|
107 |
+
// markerEnd: {
|
108 |
+
// type: 'arrow',
|
109 |
+
// },
|
110 |
+
// },
|
111 |
+
// {
|
112 |
+
// id: '0aaab297-5779-43ed-9281-2c4d3741566f',
|
113 |
+
// label: '',
|
114 |
+
// source: 'Answer:China',
|
115 |
+
// target: 'Retrieval:China',
|
116 |
+
// markerEnd: {
|
117 |
+
// type: 'arrow',
|
118 |
+
// },
|
119 |
+
// },
|
120 |
+
// {
|
121 |
+
// id: '3477f9f3-0a7d-400e-af96-a11ea7673183',
|
122 |
+
// label: '',
|
123 |
+
// source: 'Retrieval:China',
|
124 |
+
// target: 'Generate:China',
|
125 |
+
// markerEnd: {
|
126 |
+
// type: 'arrow',
|
127 |
+
// },
|
128 |
+
// },
|
129 |
],
|
130 |
},
|
131 |
components: {
|
|
|
137 |
downstream: ['Answer:China'], // other edge target is downstream, edge source is current node id
|
138 |
upstream: [], // edge source is upstream, edge target is current node id
|
139 |
},
|
140 |
+
// 'Answer:China': {
|
141 |
+
// obj: {
|
142 |
+
// component_name: 'Answer',
|
143 |
+
// params: {},
|
144 |
+
// },
|
145 |
+
// downstream: ['Retrieval:China'],
|
146 |
+
// upstream: ['begin', 'Generate:China'],
|
147 |
+
// },
|
148 |
+
// 'Retrieval:China': {
|
149 |
+
// obj: {
|
150 |
+
// component_name: 'Retrieval',
|
151 |
+
// params: {
|
152 |
+
// similarity_threshold: 0.2,
|
153 |
+
// keywords_similarity_weight: 0.3,
|
154 |
+
// top_n: 6,
|
155 |
+
// top_k: 1024,
|
156 |
+
// rerank_id: 'BAAI/bge-reranker-v2-m3',
|
157 |
+
// kb_ids: ['568aa82603b611efa9d9fa163e197198'],
|
158 |
+
// },
|
159 |
+
// },
|
160 |
+
// downstream: ['Generate:China'],
|
161 |
+
// upstream: ['Answer:China'],
|
162 |
+
// },
|
163 |
+
// 'Generate:China': {
|
164 |
+
// obj: {
|
165 |
+
// component_name: 'Generate',
|
166 |
+
// params: {
|
167 |
+
// llm_id: 'deepseek-chat',
|
168 |
+
// prompt:
|
169 |
+
// 'You are an intelligent assistant. Please summarize the content of the knowledge base to answer the question. Please list the data in the knowledge base and answer in detail. When all knowledge base content is irrelevant to the question, your answer must include the sentence "The answer you are looking for is not found in the knowledge base!" Answers need to consider chat history.\n Here is the knowledge base:\n {input}\n The above is the knowledge base.',
|
170 |
+
// temperature: 0.2,
|
171 |
+
// },
|
172 |
+
// },
|
173 |
+
// downstream: ['Answer:China'],
|
174 |
+
// upstream: ['Retrieval:China'],
|
175 |
+
// },
|
176 |
},
|
177 |
+
messages: [],
|
178 |
+
reference: [],
|
179 |
history: [],
|
180 |
path: [],
|
181 |
answer: [],
|
web/src/pages/flow/utils.ts
CHANGED
@@ -147,11 +147,6 @@ export const buildDslComponentsByGraph = (
|
|
147 |
components[id] = {
|
148 |
obj: {
|
149 |
component_name: operatorName,
|
150 |
-
// params:
|
151 |
-
// removeUselessDataInTheOperator(
|
152 |
-
// operatorName,
|
153 |
-
// x.data.form as Record<string, unknown>,
|
154 |
-
// ) ?? {},
|
155 |
params:
|
156 |
buildOperatorParams(operatorName)(
|
157 |
x.data.form as Record<string, unknown>,
|
|
|
147 |
components[id] = {
|
148 |
obj: {
|
149 |
component_name: operatorName,
|
|
|
|
|
|
|
|
|
|
|
150 |
params:
|
151 |
buildOperatorParams(operatorName)(
|
152 |
x.data.form as Record<string, unknown>,
|
web/src/pages/knowledge/knowledge-card/index.tsx
CHANGED
@@ -1,18 +1,16 @@
|
|
1 |
-
import { ReactComponent as MoreIcon } from '@/assets/svg/more.svg';
|
2 |
import { KnowledgeRouteKey } from '@/constants/knowledge';
|
3 |
-
import { useShowDeleteConfirm } from '@/hooks/commonHooks';
|
4 |
import { IKnowledge } from '@/interfaces/database/knowledge';
|
5 |
import { formatDate } from '@/utils/date';
|
6 |
import {
|
7 |
CalendarOutlined,
|
8 |
-
DeleteOutlined,
|
9 |
FileTextOutlined,
|
10 |
UserOutlined,
|
11 |
} from '@ant-design/icons';
|
12 |
-
import { Avatar, Card,
|
13 |
import { useTranslation } from 'react-i18next';
|
14 |
import { useDispatch, useNavigate } from 'umi';
|
15 |
|
|
|
16 |
import styles from './index.less';
|
17 |
|
18 |
interface IProps {
|
@@ -22,10 +20,9 @@ interface IProps {
|
|
22 |
const KnowledgeCard = ({ item }: IProps) => {
|
23 |
const navigate = useNavigate();
|
24 |
const dispatch = useDispatch();
|
25 |
-
const showDeleteConfirm = useShowDeleteConfirm();
|
26 |
const { t } = useTranslation();
|
27 |
|
28 |
-
const removeKnowledge = () => {
|
29 |
return dispatch({
|
30 |
type: 'knowledgeModel/rmKb',
|
31 |
payload: {
|
@@ -34,30 +31,6 @@ const KnowledgeCard = ({ item }: IProps) => {
|
|
34 |
});
|
35 |
};
|
36 |
|
37 |
-
const handleDelete = () => {
|
38 |
-
showDeleteConfirm({ onOk: removeKnowledge });
|
39 |
-
};
|
40 |
-
|
41 |
-
const items: MenuProps['items'] = [
|
42 |
-
{
|
43 |
-
key: '1',
|
44 |
-
label: (
|
45 |
-
<Space>
|
46 |
-
{t('common.delete')}
|
47 |
-
<DeleteOutlined />
|
48 |
-
</Space>
|
49 |
-
),
|
50 |
-
},
|
51 |
-
];
|
52 |
-
|
53 |
-
const handleDropdownMenuClick: MenuProps['onClick'] = ({ domEvent, key }) => {
|
54 |
-
domEvent.preventDefault();
|
55 |
-
domEvent.stopPropagation();
|
56 |
-
if (key === '1') {
|
57 |
-
handleDelete();
|
58 |
-
}
|
59 |
-
};
|
60 |
-
|
61 |
const handleCardClick = () => {
|
62 |
navigate(`/knowledge/${KnowledgeRouteKey.Dataset}?id=${item.id}`, {
|
63 |
state: { from: 'list' },
|
@@ -69,16 +42,7 @@ const KnowledgeCard = ({ item }: IProps) => {
|
|
69 |
<div className={styles.container}>
|
70 |
<div className={styles.content}>
|
71 |
<Avatar size={34} icon={<UserOutlined />} src={item.avatar} />
|
72 |
-
<
|
73 |
-
menu={{
|
74 |
-
items,
|
75 |
-
onClick: handleDropdownMenuClick,
|
76 |
-
}}
|
77 |
-
>
|
78 |
-
<span className={styles.delete}>
|
79 |
-
<MoreIcon />
|
80 |
-
</span>
|
81 |
-
</Dropdown>
|
82 |
</div>
|
83 |
<div className={styles.titleWrapper}>
|
84 |
<span className={styles.title}>{item.name}</span>
|
|
|
|
|
1 |
import { KnowledgeRouteKey } from '@/constants/knowledge';
|
|
|
2 |
import { IKnowledge } from '@/interfaces/database/knowledge';
|
3 |
import { formatDate } from '@/utils/date';
|
4 |
import {
|
5 |
CalendarOutlined,
|
|
|
6 |
FileTextOutlined,
|
7 |
UserOutlined,
|
8 |
} from '@ant-design/icons';
|
9 |
+
import { Avatar, Card, Space } from 'antd';
|
10 |
import { useTranslation } from 'react-i18next';
|
11 |
import { useDispatch, useNavigate } from 'umi';
|
12 |
|
13 |
+
import OperateDropdown from '@/components/operate-dropdown';
|
14 |
import styles from './index.less';
|
15 |
|
16 |
interface IProps {
|
|
|
20 |
const KnowledgeCard = ({ item }: IProps) => {
|
21 |
const navigate = useNavigate();
|
22 |
const dispatch = useDispatch();
|
|
|
23 |
const { t } = useTranslation();
|
24 |
|
25 |
+
const removeKnowledge = async () => {
|
26 |
return dispatch({
|
27 |
type: 'knowledgeModel/rmKb',
|
28 |
payload: {
|
|
|
31 |
});
|
32 |
};
|
33 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
const handleCardClick = () => {
|
35 |
navigate(`/knowledge/${KnowledgeRouteKey.Dataset}?id=${item.id}`, {
|
36 |
state: { from: 'list' },
|
|
|
42 |
<div className={styles.container}>
|
43 |
<div className={styles.content}>
|
44 |
<Avatar size={34} icon={<UserOutlined />} src={item.avatar} />
|
45 |
+
<OperateDropdown deleteItem={removeKnowledge}></OperateDropdown>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
</div>
|
47 |
<div className={styles.titleWrapper}>
|
48 |
<span className={styles.title}>{item.name}</span>
|
web/src/utils/api.ts
CHANGED
@@ -89,5 +89,5 @@ export default {
|
|
89 |
removeCanvas: `${api_host}/canvas/rm`,
|
90 |
setCanvas: `${api_host}/canvas/set`,
|
91 |
resetCanvas: `${api_host}/canvas/reset`,
|
92 |
-
runCanvas: `${api_host}/canvas/
|
93 |
};
|
|
|
89 |
removeCanvas: `${api_host}/canvas/rm`,
|
90 |
setCanvas: `${api_host}/canvas/set`,
|
91 |
resetCanvas: `${api_host}/canvas/reset`,
|
92 |
+
runCanvas: `${api_host}/canvas/completion`,
|
93 |
};
|