Skip to content

Communities Id to Title #851

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
Nov 8, 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
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
48 changes: 33 additions & 15 deletions backend/src/communities.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,24 +107,38 @@
STORE_COMMUNITY_SUMMARIES = """
UNWIND $data AS row
MERGE (c:__Community__ {id:row.community})
SET c.summary = row.summary
SET c.summary = row.summary,
c.title = row.title
"""


COMMUNITY_SYSTEM_TEMPLATE = "Given input triples, generate the information summary. No pre-amble."

COMMUNITY_TEMPLATE = """Based on the provided nodes and relationships that belong to the same graph community,
generate a natural language summary of the provided information:
{community_info}

Summary:"""
COMMUNITY_TEMPLATE = """
Based on the provided nodes and relationships that belong to the same graph community,
generate following output in exact format
title: A concise title, no more than 4 words,
summary: A natural language summary of the information
{community_info}
Example output:
title: Example Title,
summary: This is an example summary that describes the key information of this community.
"""

PARENT_COMMUNITY_SYSTEM_TEMPLATE = "Given an input list of community summaries, generate a summary of the information"

PARENT_COMMUNITY_TEMPLATE = """Based on the provided list of community summaries that belong to the same graph community,
generate a natural language summary of the information.Include all the necessary information as possible
generate following output in exact format
title: A concise title, no more than 4 words,
summary: A natural language summary of the information. Include all the necessary information as much as possible.

{community_info}

Summary:"""
Example output:
title: Example Title,
summary: This is an example summary that describes the key information of this community.
"""


GET_COMMUNITY_DETAILS = """
Expand Down Expand Up @@ -277,8 +291,17 @@ def process_community_info(community, chain, is_parent=False):
combined_text = " ".join(f"Summary {i+1}: {summary}" for i, summary in enumerate(community.get("texts", [])))
else:
combined_text = prepare_string(community)
summary = chain.invoke({'community_info': combined_text})
return {"community": community['communityId'], "summary": summary}
summary_response = chain.invoke({'community_info': combined_text})
lines = summary_response.splitlines()
title = "Untitled Community"
summary = ""
for line in lines:
if line.lower().startswith("title"):
title = line.split(":", 1)[-1].strip()
elif line.lower().startswith("summary"):
summary = line.split(":", 1)[-1].strip()
logging.info(f"Community Title : {title}")
return {"community": community['communityId'], "title":title, "summary": summary}
except Exception as e:
logging.error(f"Failed to process community {community.get('communityId', 'unknown')}: {e}")
return None
Expand All @@ -291,7 +314,7 @@ def create_community_summaries(gds, model):
summaries = []
with ThreadPoolExecutor() as executor:
futures = [executor.submit(process_community_info, community, community_chain) for community in community_info_list.to_dict(orient="records")]

for future in as_completed(futures):
result = future.result()
if result:
Expand Down Expand Up @@ -482,8 +505,3 @@ def create_communities(uri, username, password, database,model=COMMUNITY_CREATIO
logging.warning("Failed to write communities. Constraint was not applied.")
except Exception as e:
logging.error(f"Failed to create communities: {e}")





3 changes: 2 additions & 1 deletion backend/src/neighbours.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
labels: [coalesce(apoc.coll.removeAll(labels(node), ['__Entity__'])[0], "*")],
element_id: elementId(node),
properties: {
id: CASE WHEN node.id IS NOT NULL THEN node.id ELSE node.fileName END
id: CASE WHEN node.id IS NOT NULL THEN node.id ELSE node.fileName END,
title: CASE WHEN node.title IS NOT NULL THEN node.title ELSE " " END
}
}
] AS nodes,
Expand Down
2 changes: 1 addition & 1 deletion backend/src/shared/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -730,4 +730,4 @@
value "2023-03-15"."
"## 5. Strict Compliance\n"
"Adhere to the rules strictly. Non-compliance will result in termination."
"""
"""
21 changes: 21 additions & 0 deletions backend/test_integrationqa.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,27 @@ def test_graph_website(model_name):
print("Fail: ", e)
return weburl_result

def test_graph_website(model_name):
"""Test graph creation from a Website page."""
#graph, model, source_url, source_type
source_url = 'https://www.amazon.com/'
source_type = 'web-url'
create_source_node_graph_web_url(graph, model_name, source_url, source_type)

weburl_result = extract_graph_from_web_page(URI, USERNAME, PASSWORD, DATABASE, model_name, source_url, '', '')
logging.info("WebUrl test done")
print(weburl_result)

try:
assert weburl_result['status'] == 'Completed'
assert weburl_result['nodeCount'] > 0
assert weburl_result['relationshipCount'] > 0
print("Success")
except AssertionError as e:
print("Fail: ", e)
return weburl_result


def test_graph_from_youtube_video(model_name):
"""Test graph creation from a YouTube video."""
source_url = 'https://www.youtube.com/watch?v=T-qy-zPWgqA'
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ services:
args:
- VITE_BACKEND_API_URL=${VITE_BACKEND_API_URL-http://localhost:8000}
- VITE_REACT_APP_SOURCES=${VITE_REACT_APP_SOURCES-local,wiki,s3}
- VITE_LLM_MODELS=${VITE_LLM_MODELS-}
- VITE_GOOGLE_CLIENT_ID=${VITE_GOOGLE_CLIENT_ID-}
- VITE_BLOOM_URL=${VITE_BLOOM_URL-https://workspace-preview.neo4j.io/workspace/explore?connectURL={CONNECT_URL}&search=Show+me+a+graph&featureGenAISuggestions=true&featureGenAISuggestionsInternal=true}
- VITE_TIME_PER_PAGE=${VITE_TIME_PER_PAGE-50}
Expand All @@ -62,6 +61,7 @@ services:
- VITE_ENV=${VITE_ENV-DEV}
- VITE_CHAT_MODES=${VITE_CHAT_MODES-}
- VITE_BATCH_SIZE=${VITE_BATCH_SIZE-2}
- VITE_LLM_MODELS=${VITE_LLM_MODELS-}
- VITE_LLM_MODELS_PROD=${VITE_LLM_MODELS_PROD-openai_gpt_4o,openai_gpt_4o_mini,diffbot,gemini_1.5_flash}
volumes:
- ./frontend:/app
Expand Down
1 change: 0 additions & 1 deletion example.env
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ ENTITY_EMBEDDING=True
VITE_BACKEND_API_URL="http://localhost:8000"
VITE_BLOOM_URL="https://workspace-preview.neo4j.io/workspace/explore?connectURL={CONNECT_URL}&search=Show+me+a+graph&featureGenAISuggestions=true&featureGenAISuggestionsInternal=true"
VITE_REACT_APP_SOURCES="local,youtube,wiki,s3,web"
VITE_LLM_MODELS="diffbot,openai-gpt-3.5,openai-gpt-4o" # ",ollama_llama3"
VITE_ENV="DEV"
VITE_TIME_PER_PAGE=50
VITE_CHUNK_SIZE=5242880
Expand Down
1 change: 0 additions & 1 deletion frontend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ RUN yarn install
COPY . ./
RUN VITE_BACKEND_API_URL=$VITE_BACKEND_API_URL \
VITE_REACT_APP_SOURCES=$VITE_REACT_APP_SOURCES \
VITE_LLM_MODELS=$VITE_LLM_MODELS \
VITE_GOOGLE_CLIENT_ID=$VITE_GOOGLE_CLIENT_ID \
VITE_BLOOM_URL=$VITE_BLOOM_URL \
VITE_CHUNK_SIZE=$VITE_CHUNK_SIZE \
Expand Down
13 changes: 2 additions & 11 deletions frontend/src/components/ChatBot/ChunkInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,16 @@ const ChunkInfo: FC<ChunkProps> = ({ loading, chunks, mode }) => {
const [neoRels, setNeoRels] = useState<any[]>([]);
const [openGraphView, setOpenGraphView] = useState(false);
const [viewPoint, setViewPoint] = useState('');
const [loadingGraphView, setLoadingGraphView] = useState(false);

const handleChunkClick = (elementId: string, viewMode: string) => {
setOpenGraphView(true);
setViewPoint('chatInfoView');
handleGraphNodeClick(
userCredentials as UserCredentials,
elementId,
viewMode,
setNeoNodes,
setNeoRels,
setOpenGraphView,
setViewPoint,
setLoadingGraphView
);
};

Expand Down Expand Up @@ -72,7 +70,6 @@ const ChunkInfo: FC<ChunkProps> = ({ loading, chunks, mode }) => {
<div>
<TextLink
label='Graph view'
className={`${loadingGraphView ? 'cursor-wait' : 'cursor-pointer'}`}
onClick={() => handleChunkClick(chunk.element_id, 'Chunk')}
>
{'View Graph'}
Expand Down Expand Up @@ -100,7 +97,6 @@ const ChunkInfo: FC<ChunkProps> = ({ loading, chunks, mode }) => {
<div>
<TextLink
as='small'
className={`${loadingGraphView ? 'cursor-wait' : 'cursor-pointer'}`}
label='Graph view'
onClick={() => handleChunkClick(chunk.element_id, 'Chunk')}
>
Expand All @@ -123,7 +119,6 @@ const ChunkInfo: FC<ChunkProps> = ({ loading, chunks, mode }) => {
<Typography variant='subheading-small'>Similarity Score: {chunk?.score}</Typography>
<div>
<TextLink
className={`${loadingGraphView ? 'cursor-wait' : 'cursor-pointer'}`}
label='Graph view'
onClick={() => handleChunkClick(chunk.element_id, 'Chunk')}
>
Expand All @@ -146,7 +141,6 @@ const ChunkInfo: FC<ChunkProps> = ({ loading, chunks, mode }) => {
<Typography variant='subheading-small'>Similarity Score: {chunk?.score}</Typography>
<div>
<TextLink
className={`${loadingGraphView ? 'cursor-wait' : 'cursor-pointer'}`}
label='Graph view'
onClick={() => handleChunkClick(chunk.element_id, 'Chunk')}
>
Expand All @@ -169,7 +163,6 @@ const ChunkInfo: FC<ChunkProps> = ({ loading, chunks, mode }) => {
<Typography variant='subheading-small'>Similarity Score: {chunk?.score}</Typography>
<div>
<TextLink
className={`${loadingGraphView ? 'cursor-wait' : 'cursor-pointer'}`}
label='Graph view'
onClick={() => handleChunkClick(chunk.element_id, 'Chunk')}
>
Expand All @@ -196,7 +189,6 @@ const ChunkInfo: FC<ChunkProps> = ({ loading, chunks, mode }) => {
<Typography variant='subheading-small'>Similarity Score: {chunk?.score}</Typography>
<div>
<TextLink
className={`${loadingGraphView ? 'cursor-wait' : 'cursor-pointer'}`}
label='Graph view'
onClick={() => handleChunkClick(chunk.element_id, 'Chunk')}
>
Expand Down Expand Up @@ -228,7 +220,6 @@ const ChunkInfo: FC<ChunkProps> = ({ loading, chunks, mode }) => {
</Typography>
<div>
<TextLink
className={`${loadingGraphView ? 'cursor-wait' : 'cursor-pointer'}`}
label='Graph view'
onClick={() => handleChunkClick(chunk.element_id, 'Chunk')}
>
Expand Down
8 changes: 3 additions & 5 deletions frontend/src/components/ChatBot/CommunitiesInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,17 @@ const CommunitiesInfo: FC<CommunitiesProps> = ({ loading, communities, mode }) =
const [neoRels, setNeoRels] = useState<any[]>([]);
const [openGraphView, setOpenGraphView] = useState(false);
const [viewPoint, setViewPoint] = useState('');
const [loadingGraphView, setLoadingGraphView] = useState(false);
const [graphLoading, setGraphLoading] = useState<boolean>(false);

const handleCommunityClick = (elementId: string, viewMode: string) => {
setOpenGraphView(true);
setViewPoint('chatInfoView');
handleGraphNodeClick(
userCredentials as UserCredentials,
elementId,
viewMode,
setNeoNodes,
setNeoRels,
setOpenGraphView,
setViewPoint,
setLoadingGraphView
);
};

Expand All @@ -42,7 +41,6 @@ const CommunitiesInfo: FC<CommunitiesProps> = ({ loading, communities, mode }) =
<div>
<Flex flexDirection='row' gap='2'>
<TextLink
className={`${loadingGraphView ? 'cursor-wait' : 'cursor-pointer'}`}
label={`ID : ${community.id}`}
onClick={() => handleCommunityClick(community.element_id, 'chatInfoView')}
>{`ID : ${community.id}`}</TextLink>
Expand Down
11 changes: 3 additions & 8 deletions frontend/src/components/ChatBot/EntitiesInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ const EntitiesInfo: FC<EntitiesProps> = ({ loading, mode, graphonly_entities, in
const [neoRels, setNeoRels] = useState<any[]>([]);
const [openGraphView, setOpenGraphView] = useState(false);
const [viewPoint, setViewPoint] = useState('');
const [loadingGraphView, setLoadingGraphView] = useState(false);

const groupedEntities = useMemo<{ [key: string]: GroupedEntity }>(() => {
const items = infoEntities.reduce((acc, entity) => {
Expand Down Expand Up @@ -44,15 +43,14 @@ const EntitiesInfo: FC<EntitiesProps> = ({ loading, mode, graphonly_entities, in
}, [labelCounts]);

const handleEntityClick = (elementId: string, viewMode: string) => {
setOpenGraphView(true);
setViewPoint('chatInfoView');
handleGraphNodeClick(
userCredentials as UserCredentials,
elementId,
viewMode,
setNeoNodes,
setNeoRels,
setOpenGraphView,
setViewPoint,
setLoadingGraphView
);
};

Expand All @@ -69,9 +67,7 @@ const EntitiesInfo: FC<EntitiesProps> = ({ loading, mode, graphonly_entities, in
? graphonly_entities.map((label, index) => (
<li
key={index}
className={`flex items-center mb-2 text-ellipsis whitespace-nowrap max-w-[100%] overflow-hidden ${
loadingGraphView ? 'cursor-wait' : 'cursor-pointer'
}`}
className='flex items-center mb-2 text-ellipsis whitespace-nowrap max-w-[100%] overflow-hidden'
>
<ul className='list-inside'>
{Object.keys(label).map((key) => (
Expand Down Expand Up @@ -118,7 +114,6 @@ const EntitiesInfo: FC<EntitiesProps> = ({ loading, mode, graphonly_entities, in
<span key={idx}>
<TextLink
onClick={() => handleEntityClick(textId!, 'chatInfoView')}
className={loadingGraphView ? 'cursor-wait' : 'cursor-pointer'}
>
{text}
</TextLink>
Expand Down
15 changes: 2 additions & 13 deletions frontend/src/components/ChatBot/chatInfo.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
import { getNeighbors } from '../../services/GraphQuery';
import { NeoNode, NeoRelationship, UserCredentials } from '../../types';
import { graphLabels } from '../../utils/Constants';

export const handleGraphNodeClick = async (
userCredentials: UserCredentials,
elementId: string,
viewMode: string,
setNeoNodes: React.Dispatch<React.SetStateAction<NeoNode[]>>,
setNeoRels: React.Dispatch<React.SetStateAction<NeoRelationship[]>>,
setOpenGraphView: React.Dispatch<React.SetStateAction<boolean>>,
setViewPoint: React.Dispatch<React.SetStateAction<string>>,
setLoadingGraphView?: React.Dispatch<React.SetStateAction<boolean>>
) => {
if (setLoadingGraphView) {
setLoadingGraphView(true);
}
try {
const result = await getNeighbors(userCredentials, elementId);
if (result && result.data.data.nodes.length > 0) {
let { nodes } = result.data.data;
if (viewMode === 'Chunk') {
if (viewMode === graphLabels.chatInfoView) {
nodes = nodes.filter((node: NeoNode) => node.labels.length === 1 && node.properties.id !== null);
}
const nodeIds = new Set(nodes.map((node: NeoNode) => node.element_id));
Expand All @@ -27,14 +22,8 @@ export const handleGraphNodeClick = async (
);
setNeoNodes(nodes);
setNeoRels(relationships);
setOpenGraphView(true);
setViewPoint('chatInfoView');
}
} catch (error: any) {
console.error('Error fetching neighbors:', error);
} finally {
if (setLoadingGraphView) {
setLoadingGraphView(false);
}
}
};
5 changes: 3 additions & 2 deletions frontend/src/components/Content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,11 @@ const Content: React.FC<ContentProps> = ({
setProcessedCount,
setchatModes,
} = useFileContext();
const [viewPoint, setViewPoint] = useState<'tableView' | 'showGraphView' | 'chatInfoView'>('tableView');
const [viewPoint, setViewPoint] = useState<'tableView' | 'showGraphView' | 'chatInfoView'|'neighborView'>('tableView');
const [showDeletePopUp, setshowDeletePopUp] = useState<boolean>(false);
const [deleteLoading, setdeleteLoading] = useState<boolean>(false);
const [searchParams] = useSearchParams();
const [graphLoading, setGraphLoading] = useState<boolean>(false);

const { updateStatusForLargeFiles } = useServerSideEvent(
(inMinutes, time, fileName) => {
Expand Down Expand Up @@ -992,4 +993,4 @@ const Content: React.FC<ContentProps> = ({
);
};

export default Content;
export default Content;
2 changes: 1 addition & 1 deletion frontend/src/components/FileTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -962,4 +962,4 @@ const FileTable = forwardRef<ChildRef, FileTableProps>((props, ref) => {
);
});

export default FileTable;
export default FileTable;
Loading