Skip to content

Commit 178dacb

Browse files
Multiple chat modes selection (#780)
* added Multi modes selection * multimodes state mangement * fix: state handling of chat details of the default mode * Added the ChatModeSwitch Component * modes switch statemangement * added the chatmodes switch in both view * removed the copied text * Handled the error scenario * fix: speech issue between modes * fix: Handled activespeech speech and othermessage modes switch * used requestanimationframe instead of setTimeOut * removed the commented code
1 parent 83351ac commit 178dacb

File tree

11 files changed

+486
-363
lines changed

11 files changed

+486
-363
lines changed

backend/score.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ async def chat_bot(uri=Form(),model=Form(None),userName=Form(), password=Form(),
323323
message="Unable to get chat response"
324324
error_message = str(e)
325325
logging.exception(f'Exception in chat bot:{error_message}')
326-
return create_api_response(job_status, message=message, error=error_message)
326+
return create_api_response(job_status, message=message, error=error_message,data=mode)
327327
finally:
328328
gc.collect()
329329

Lines changed: 7 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,15 @@
11
{
22
"listMessages": [
3-
{
4-
"id": 1,
5-
"message": "Hi, I need help with creating a Cypher query for Neo4j.",
6-
"user": "user",
7-
"datetime": "01/01/2024 00:00:00"
8-
},
93
{
104
"id": 2,
11-
"message": " Welcome to the Neo4j Knowledge Graph Chat. You can ask questions related to documents which have been completely processed.",
12-
"user": "chatbot",
13-
"datetime": "01/01/2024 00:00:00"
14-
},
15-
{
16-
"id": 3,
17-
"message": "I need to find all employees who work in the IT department.",
18-
"user": "user",
19-
"datetime": "01/01/2024 00:00:00"
20-
},
21-
{
22-
"id": 4,
23-
"message": "Alright, you can use the following query: `MATCH (e:Employee)-[:WORKS_IN]->(d:Department {name: 'IT'}) RETURN e.name`. This query matches nodes labeled 'Employee' related to the 'IT' department and returns their names.",
24-
"user": "chatbot",
25-
"datetime": "01/01/2024 00:00:00"
26-
},
27-
{
28-
"id": 5,
29-
"message": "Thanks! And how do I get the total number of such employees?",
30-
"user": "user",
31-
"datetime": "01/01/2024 00:00:00"
32-
},
33-
{
34-
"id": 6,
35-
"message": "To get the count, use: `MATCH (e:Employee)-[:WORKS_IN]->(d:Department {name: 'IT'}) RETURN count(e)`. This counts all the distinct 'Employee' nodes related to the 'IT' department.",
5+
"modes":{
6+
"graph+vector+fulltext":{
7+
"message": " Welcome to the Neo4j Knowledge Graph Chat. You can ask questions related to documents which have been completely processed."
8+
}
9+
},
3610
"user": "chatbot",
37-
"datetime": "01/01/2024 00:00:00"
11+
"datetime": "01/01/2024 00:00:00",
12+
"currentMode":"graph+vector+fulltext"
3813
}
3914
]
4015
}

frontend/src/components/ChatBot/ChatModeToggle.tsx

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ import { StatusIndicator, Typography } from '@neo4j-ndl/react';
22
import { useMemo, useEffect } from 'react';
33
import { useFileContext } from '../../context/UsersFiles';
44
import CustomMenu from '../UI/Menu';
5-
import { chatModeLables, chatModes } from '../../utils/Constants';
5+
import { chatModeLables, chatModes as AvailableModes } from '../../utils/Constants';
66
import { capitalize } from '@mui/material';
77
import { capitalizeWithPlus } from '../../utils/Utils';
88
import { useCredentials } from '../../context/UserCredentials';
9+
910
export default function ChatModeToggle({
1011
menuAnchor,
1112
closeHandler = () => {},
@@ -19,22 +20,22 @@ export default function ChatModeToggle({
1920
anchorPortal?: boolean;
2021
disableBackdrop?: boolean;
2122
}) {
22-
const { setchatMode, chatMode, postProcessingTasks, selectedRows } = useFileContext();
23+
const { setchatModes, chatModes, postProcessingTasks, selectedRows } = useFileContext();
2324
const isCommunityAllowed = postProcessingTasks.includes('enable_communities');
2425
const { isGdsActive } = useCredentials();
2526

2627
useEffect(() => {
2728
// If rows are selected, the mode is valid (either vector or graph+vector)
2829
if (selectedRows.length > 0) {
29-
if (!(chatMode === chatModeLables.vector || chatMode === chatModeLables.graph_vector)) {
30-
setchatMode(chatModeLables.graph_vector);
30+
if (!(chatModes.includes(chatModeLables.vector) || chatModes.includes(chatModeLables.graph_vector))) {
31+
setchatModes([chatModeLables.graph_vector]);
3132
}
3233
}
33-
}, [selectedRows.length, chatMode, setchatMode]);
34+
}, [selectedRows.length, chatModes.length]);
3435
const memoizedChatModes = useMemo(() => {
3536
return isGdsActive && isCommunityAllowed
36-
? chatModes
37-
: chatModes?.filter(
37+
? AvailableModes
38+
: AvailableModes?.filter(
3839
(m) => !m.mode.includes(chatModeLables.entity_vector) && !m.mode.includes(chatModeLables.global_vector)
3940
);
4041
}, [isGdsActive, isCommunityAllowed]);
@@ -45,9 +46,11 @@ export default function ChatModeToggle({
4546
);
4647
const handleModeChange = () => {
4748
if (isDisabled) {
48-
setchatMode(chatModeLables.graph_vector);
49+
setchatModes([chatModeLables.graph_vector]);
50+
} else if (chatModes.includes(m.mode)) {
51+
setchatModes((prev) => prev.filter((i) => i != m.mode));
4952
} else {
50-
setchatMode(m.mode);
53+
setchatModes((prev) => [...prev, m.mode]);
5154
}
5255
closeHandler();
5356
};
@@ -66,7 +69,7 @@ export default function ChatModeToggle({
6669
disabledCondition: isDisabled,
6770
description: (
6871
<span>
69-
{chatMode === m.mode && (
72+
{chatModes.includes(m.mode) && (
7073
<>
7174
<StatusIndicator type='success' /> {chatModeLables.selected}
7275
</>
@@ -80,13 +83,13 @@ export default function ChatModeToggle({
8083
),
8184
};
8285
});
83-
}, [chatMode, memoizedChatModes, setchatMode, closeHandler, selectedRows]);
86+
}, [chatModes.length, memoizedChatModes, closeHandler, selectedRows]);
8487

8588
useEffect(() => {
86-
if (!selectedRows.length && !chatMode) {
87-
setchatMode(chatModeLables.graph_vector_fulltext);
89+
if (!selectedRows.length && !chatModes.length) {
90+
setchatModes([chatModeLables.graph_vector_fulltext]);
8891
}
89-
}, [setchatMode, selectedRows.length, chatMode]);
92+
}, [selectedRows.length, chatModes.length]);
9093
return (
9194
<CustomMenu
9295
closeHandler={closeHandler}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { Flex, IconButton } from '@neo4j-ndl/react';
2+
import { ChevronLeftIconSolid, ChevronRightIconSolid } from '@neo4j-ndl/react/icons';
3+
import TipWrapper from '../UI/TipWrapper';
4+
import { capitalize, capitalizeWithPlus } from '../../utils/Utils';
5+
6+
export default function ChatModesSwitch({
7+
switchToOtherMode,
8+
currentModeIndex,
9+
modescount,
10+
currentMode,
11+
isFullScreen,
12+
}: {
13+
switchToOtherMode: (index: number) => void;
14+
currentModeIndex: number;
15+
modescount: number;
16+
currentMode: string;
17+
isFullScreen: boolean;
18+
}) {
19+
const chatmodetoshow = currentMode.includes('+') ? capitalizeWithPlus(currentMode) : capitalize(currentMode);
20+
return (
21+
<Flex flexDirection='row' gap='1' alignItems='center'>
22+
<IconButton
23+
disabled={currentModeIndex === 0}
24+
size='small'
25+
clean
26+
onClick={() => switchToOtherMode(currentModeIndex - 1)}
27+
>
28+
<ChevronLeftIconSolid />
29+
</IconButton>
30+
<TipWrapper tooltip={chatmodetoshow} placement='top'>
31+
<span
32+
className={`n-body-medium ${!isFullScreen ? 'max-w-[50px] text-ellipsis text-nowrap overflow-hidden' : ''}`}
33+
>
34+
{chatmodetoshow}
35+
</span>
36+
</TipWrapper>
37+
<IconButton
38+
disabled={currentModeIndex === modescount - 1}
39+
size='small'
40+
clean
41+
onClick={() => switchToOtherMode(currentModeIndex + 1)}
42+
>
43+
<ChevronRightIconSolid />
44+
</IconButton>
45+
</Flex>
46+
);
47+
}

0 commit comments

Comments
 (0)