Skip to content

Integrate local search to chat details #746

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
c12d8fc
added the commuties tab
kartikpersistent Sep 12, 2024
932ff59
Merge branch 'communities' of https://github.com/neo4j-labs/llm-graph…
kartikpersistent Sep 13, 2024
7e3816b
removed unused variables
kartikpersistent Sep 13, 2024
373ed06
Merge branch 'communities' of https://github.com/neo4j-labs/llm-graph…
kartikpersistent Sep 13, 2024
599ea77
Merge branch 'communities' of https://github.com/neo4j-labs/llm-graph…
kartikpersistent Sep 13, 2024
aa20616
Merge branch 'communities' of https://github.com/neo4j-labs/llm-graph…
prakriti-solankey Sep 13, 2024
b452981
Merge branch 'Integrate-local-search-to-chat-details' of https://gith…
prakriti-solankey Sep 13, 2024
8d01854
Merge branch 'communities' of https://github.com/neo4j-labs/llm-graph…
kartikpersistent Sep 13, 2024
89e7ee5
Merge branch 'communities' of https://github.com/neo4j-labs/llm-graph…
kartikpersistent Sep 13, 2024
9b9bf75
removed scipy libarary
kartikpersistent Sep 13, 2024
ae562e7
added the mode check
kartikpersistent Sep 13, 2024
8d3ccef
Merge branch 'communities' of https://github.com/neo4j-labs/llm-graph…
kartikpersistent Sep 13, 2024
e7565da
Integrated the communities tab
kartikpersistent Sep 16, 2024
5ddd772
added the cjheck
kartikpersistent Sep 16, 2024
995e68f
enabled the top entities mode
kartikpersistent Sep 16, 2024
045b524
tabs order rearange
kartikpersistent Sep 16, 2024
c78621c
Merge branch 'communities' into Integrate-local-search-to-chat-details
prakriti-solankey Sep 16, 2024
7cd1007
added the loader to sources tab for entity search+vector
kartikpersistent Sep 16, 2024
262e58a
Merge branch 'Integrate-local-search-to-chat-details' of https://gith…
kartikpersistent Sep 16, 2024
97b0811
fixed the chat mode per prop
kartikpersistent Sep 16, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions backend/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,6 @@ requests==2.32.3
rsa==4.9
s3transfer==0.10.1
safetensors==0.4.1
scipy==1.10.1
shapely==2.0.3
six==1.16.0
sniffio==1.3.1
Expand Down Expand Up @@ -179,4 +178,4 @@ sentence-transformers==3.0.1
google-cloud-logging==3.10.0
PyMuPDF==1.24.5
pypandoc==1.13
graphdatascience==1.10
graphdatascience==1.10
113 changes: 99 additions & 14 deletions frontend/src/components/ChatBot/ChatInfoModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ import {
Banner,
useMediaQuery,
} from '@neo4j-ndl/react';
import { DocumentDuplicateIconOutline, DocumentTextIconOutline } from '@neo4j-ndl/react/icons';
import {
DocumentDuplicateIconOutline,
DocumentTextIconOutline,
ClipboardDocumentCheckIconOutline,
GlobeAltIconOutline,
} from '@neo4j-ndl/react/icons';
import '../../styling/info.css';
import Neo4jRetrievalLogo from '../../assets/images/Neo4jRetrievalLogo.png';
import wikipedialogo from '../../assets/images/wikipedia.svg';
Expand All @@ -20,6 +25,7 @@ import gcslogo from '../../assets/images/gcs.webp';
import s3logo from '../../assets/images/s3logo.png';
import {
Chunk,
Community,
Entity,
ExtendedNode,
ExtendedRelationship,
Expand All @@ -34,10 +40,8 @@ import { chunkEntitiesAPI } from '../../services/ChunkEntitiesInfo';
import { useCredentials } from '../../context/UserCredentials';
import { calcWordColor } from '@neo4j-devtools/word-color';
import ReactMarkdown from 'react-markdown';
import { GlobeAltIconOutline } from '@neo4j-ndl/react/icons';
import { parseEntity, youtubeLinkValidation } from '../../utils/Utils';
import { getLogo, parseEntity, youtubeLinkValidation } from '../../utils/Utils';
import { ThemeWrapperContext } from '../../context/ThemeWrapper';
import { ClipboardDocumentCheckIconOutline } from '@neo4j-ndl/react/icons';
import { tokens } from '@neo4j-ndl/base';

const ChatInfoModal: React.FC<chatInfoMessage> = ({
Expand All @@ -55,6 +59,7 @@ const ChatInfoModal: React.FC<chatInfoMessage> = ({
const isTablet = useMediaQuery(`(min-width:${breakpoints.xs}) and (max-width: ${breakpoints.lg})`);
const [activeTab, setActiveTab] = useState<number>(error.length ? 10 : mode === 'graph' ? 4 : 3);
const [infoEntities, setInfoEntities] = useState<Entity[]>([]);
const [communities, setCommunities] = useState<Community[]>([]);
const [loading, setLoading] = useState<boolean>(false);
const { userCredentials } = useCredentials();
const [nodes, setNodes] = useState<ExtendedNode[]>([]);
Expand Down Expand Up @@ -86,14 +91,25 @@ const ChatInfoModal: React.FC<chatInfoMessage> = ({
],
[copiedText, cypher_query]
);

useEffect(() => {
if (mode != 'graph' || error?.trim() !== '') {
setLoading(true);
chunkEntitiesAPI(userCredentials as UserCredentials, chunk_ids.map((c) => c.id).join(','))
.then((response) => {
(async () => {
setLoading(true);
try {
const response = await chunkEntitiesAPI(
userCredentials as UserCredentials,
chunk_ids.map((c) => c.id).join(','),
userCredentials?.database,
mode === 'entity search+vector'
);
if (response.data.status === 'Failure') {
throw new Error(response.data.error);
}
setInfoEntities(response.data.data.nodes);
setNodes(response.data.data.nodes);
setRelationships(response.data.data.relationships);
setCommunities(response.data.data.community_data);
const chunks = response.data.data.chunk_data.map((chunk: any) => {
const chunkScore = chunk_ids.find((chunkdetail) => chunkdetail.id === chunk.id);
return {
Expand All @@ -104,17 +120,17 @@ const ChatInfoModal: React.FC<chatInfoMessage> = ({
const sortedchunks = chunks.sort((a: any, b: any) => b.score - a.score);
setChunks(sortedchunks);
setLoading(false);
})
.catch((error) => {
} catch (error) {
console.error('Error fetching entities:', error);
setLoading(false);
});
}
})();
}

() => {
setcopiedText(false);
};
}, [chunk_ids, mode, error]);

const groupedEntities = useMemo<{ [key: string]: GroupedEntity }>(() => {
return infoEntities.reduce((acc, entity) => {
const { label, text } = parseEntity(entity);
Expand All @@ -126,9 +142,11 @@ const ChatInfoModal: React.FC<chatInfoMessage> = ({
return acc;
}, {} as Record<string, { texts: Set<string>; color: string }>);
}, [infoEntities]);

const onChangeTabs = (tabId: number) => {
setActiveTab(tabId);
};

const labelCounts = useMemo(() => {
const counts: { [label: string]: number } = {};
for (let index = 0; index < infoEntities.length; index++) {
Expand All @@ -139,6 +157,7 @@ const ChatInfoModal: React.FC<chatInfoMessage> = ({
}
return counts;
}, [infoEntities]);

const sortedLabels = useMemo(() => {
return Object.keys(labelCounts).sort((a, b) => labelCounts[b] - labelCounts[a]);
}, [labelCounts]);
Expand All @@ -153,6 +172,7 @@ const ChatInfoModal: React.FC<chatInfoMessage> = ({
return '';
}
};

return (
<Box className='n-bg-palette-neutral-bg-weak p-4'>
<Box className='flex flex-row pb-6 items-center mb-2'>
Expand All @@ -176,7 +196,11 @@ const ChatInfoModal: React.FC<chatInfoMessage> = ({
) : (
<Tabs size='large' fill='underline' onChange={onChangeTabs} value={activeTab}>
{mode != 'graph' ? <Tabs.Tab tabId={3}>Sources used</Tabs.Tab> : <></>}
{mode === 'graph+vector' || mode === 'graph' || mode === 'graph+vector+fulltext' ? (
{mode != 'graph' ? <Tabs.Tab tabId={5}>Chunks</Tabs.Tab> : <></>}
{mode === 'graph+vector' ||
mode === 'graph' ||
mode === 'graph+vector+fulltext' ||
mode === 'entity search+vector' ? (
<Tabs.Tab tabId={4}>Top Entities used</Tabs.Tab>
) : (
<></>
Expand All @@ -186,12 +210,46 @@ const ChatInfoModal: React.FC<chatInfoMessage> = ({
) : (
<></>
)}
{mode != 'graph' ? <Tabs.Tab tabId={5}>Chunks</Tabs.Tab> : <></>}
{mode === 'entity search+vector' ? <Tabs.Tab tabId={7}>Communities</Tabs.Tab> : <></>}
</Tabs>
)}
<Flex className='p-4'>
<Tabs.TabPanel className='n-flex n-flex-col n-gap-token-4 n-p-token-6' value={activeTab} tabId={3}>
{sources.length ? (
{loading ? (
<Box className='flex justify-center items-center'>
<LoadingSpinner size='small' />
</Box>
) : mode === 'entity search+vector' && chunks.length ? (
<ul>
{chunks
.map((c) => ({ fileName: c.fileName, fileSource: c.fileType }))
.map((s, index) => {
return (
<li key={index} className='flex flex-row inline-block justify-between items-center p-2'>
<div className='flex flex-row inline-block justify-between items-center'>
{s.fileSource === 'local file' ? (
<DocumentTextIconOutline className='n-size-token-7 mr-2' />
) : (
<img
src={getLogo(themeUtils.colorMode)[s.fileSource]}
width={20}
height={20}
className='mr-2'
alt='S3 Logo'
/>
)}
<Typography
variant='body-medium'
className='text-ellipsis whitespace-nowrap overflow-hidden max-w-lg'
>
{s.fileName}
</Typography>
</div>
</li>
);
})}
</ul>
) : sources.length ? (
<ul className='list-class list-none'>
{sources.map((link, index) => {
return (
Expand Down Expand Up @@ -436,6 +494,33 @@ const ChatInfoModal: React.FC<chatInfoMessage> = ({
className='min-h-40'
/>
</Tabs.TabPanel>
{mode === 'entity search+vector' ? (
<Tabs.TabPanel value={activeTab} tabId={7}>
{loading ? (
<Box className='flex justify-center items-center'>
<LoadingSpinner size='small' />
</Box>
) : (
<div className='p-4 h-80 overflow-auto'>
<ul className='list-disc list-inside'>
{communities.map((community, index) => (
<li key={`${community.id}${index}`} className='mb-2'>
<div>
<Flex flexDirection='row' gap='2'>
<Typography variant='subheading-medium'>ID : </Typography>
<Typography variant='subheading-medium'>{community.id}</Typography>
</Flex>
<ReactMarkdown>{community.summary}</ReactMarkdown>
</div>
</li>
))}
</ul>
</div>
)}
</Tabs.TabPanel>
) : (
<></>
)}
</Flex>
{activeTab == 4 && nodes.length && relationships.length ? (
<Box className='button-container flex mt-2 justify-center'>
Expand Down
10 changes: 9 additions & 1 deletion frontend/src/components/ChatBot/Chatbot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ const Chatbot: FC<ChatbotProps> = (props) => {
cypher_query?: string;
graphonly_entities?: [];
error?: string;
entitiysearchonly_entities?: chunk[];
},
index = 0
) => {
Expand Down Expand Up @@ -119,6 +120,7 @@ const Chatbot: FC<ChatbotProps> = (props) => {
cypher_query: response?.cypher_query,
graphonly_entities: response?.graphonly_entities,
error: response.error,
entitiysearchonly_entities: response.entitiysearchonly_entities,
},
]);
} else {
Expand All @@ -141,6 +143,7 @@ const Chatbot: FC<ChatbotProps> = (props) => {
lastmsg.cypher_query = response.cypher_query;
lastmsg.graphonly_entities = response.graphonly_entities;
lastmsg.error = response.error;
lastmsg.entities = response.entitiysearchonly_entities;
return msgs.map((msg, index) => {
if (index === msgs.length - 1) {
return lastmsg;
Expand Down Expand Up @@ -174,6 +177,7 @@ const Chatbot: FC<ChatbotProps> = (props) => {
let cypher_query;
let graphonly_entities;
let error;
let entitiysearchonly_entities;
const datetime = `${date.toLocaleDateString()} ${date.toLocaleTimeString()}`;
const userMessage = { id: Date.now(), user: 'user', message: inputMessage, datetime: datetime };
setListMessages([...listMessages, userMessage]);
Expand All @@ -198,6 +202,7 @@ const Chatbot: FC<ChatbotProps> = (props) => {
chatingMode = chatresponse?.data?.data?.info?.mode;
cypher_query = chatresponse?.data?.data?.info?.cypher_query ?? '';
graphonly_entities = chatresponse?.data.data.info.context ?? [];
entitiysearchonly_entities = chatresponse?.data.data.info.entities;
error = chatresponse.data.data.info.error ?? '';
const finalbotReply = {
reply: chatbotReply,
Expand All @@ -212,6 +217,7 @@ const Chatbot: FC<ChatbotProps> = (props) => {
cypher_query,
graphonly_entities,
error,
entitiysearchonly_entities,
};
simulateTypingEffect(finalbotReply);
} catch (error) {
Expand Down Expand Up @@ -349,7 +355,9 @@ const Chatbot: FC<ChatbotProps> = (props) => {
setModelModal(chat.model ?? '');
setSourcesModal(chat.sources ?? []);
setResponseTime(chat.response_time ?? 0);
setChunkModal(chat.chunk_ids ?? []);
setChunkModal(
chat.mode === 'entity search+vector' ? chat.entities ?? [] : chat.chunk_ids ?? []
);
setTokensUsed(chat.total_tokens ?? 0);
setcypherQuery(chat.cypher_query ?? '');
setShowInfoModal(true);
Expand Down
Loading