Skip to content

Adding Links to get neighboring nodes #796

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 23 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
49d86c5
addition of link
prakriti-solankey Sep 30, 2024
1e27bea
added neighbours query
vasanthasaikalluri Oct 9, 2024
a7ea2e4
implemented with driver
vasanthasaikalluri Oct 10, 2024
98789c8
updated the query
vasanthasaikalluri Oct 11, 2024
9f33c8a
Merge branch 'DEV' of https://github.com/neo4j-labs/llm-graph-builder…
prakriti-solankey Oct 11, 2024
f9a6288
communitiesInfo name change
prakriti-solankey Oct 11, 2024
0d9dd8b
communities.tsx removed
prakriti-solankey Oct 11, 2024
6a8a41c
Merge branch 'get_neighbours' of https://github.com/neo4j-labs/llm-gr…
prakriti-solankey Oct 11, 2024
90d868d
api integration
prakriti-solankey Oct 11, 2024
8e24f96
modified response
vasanthasaikalluri Oct 14, 2024
7244a8e
entities change
prakriti-solankey Oct 15, 2024
ee03d21
Merge branch 'DEV' of https://github.com/neo4j-labs/llm-graph-builder…
prakriti-solankey Oct 15, 2024
35f6199
Merge branch 'DEV' of https://github.com/neo4j-labs/llm-graph-builder…
prakriti-solankey Oct 15, 2024
eccfcc7
chunk and communities
prakriti-solankey Oct 15, 2024
b5f5697
chunk space removal
prakriti-solankey Oct 16, 2024
086f95f
added element id to chunks
vasanthasaikalluri Oct 16, 2024
8eb41c6
loading on click
prakriti-solankey Oct 16, 2024
586cbf4
format changes
prakriti-solankey Oct 16, 2024
cd4174e
added file name for Dcoumrnt node
vasanthasaikalluri Oct 17, 2024
6ceaca0
chat token cut off model name update
vasanthasaikalluri Oct 17, 2024
dd306fd
icon change
prakriti-solankey Oct 18, 2024
29c0fc6
duplicate sources removal
prakriti-solankey Oct 18, 2024
16f9657
Entity change
prakriti-solankey Oct 18, 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
20 changes: 20 additions & 0 deletions backend/score.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from src.post_processing import create_vector_fulltext_indexes, create_entity_embedding
from sse_starlette.sse import EventSourceResponse
from src.communities import create_communities
from src.neighbours import get_neighbour_nodes
import json
from typing import List, Mapping
from starlette.middleware.sessions import SessionMiddleware
Expand Down Expand Up @@ -343,6 +344,25 @@ async def chunk_entities(uri=Form(),userName=Form(), password=Form(), database=F
finally:
gc.collect()

@app.post("/get_neighbours")
async def get_neighbours(uri=Form(),userName=Form(), password=Form(), database=Form(), elementId=Form(None)):
try:
start = time.time()
result = await asyncio.to_thread(get_neighbour_nodes,uri=uri, username=userName, password=password,database=database, element_id=elementId)
end = time.time()
elapsed_time = end - start
json_obj = {'api_name':'get_neighbours','db_url':uri, 'logging_time': formatted_time(datetime.now(timezone.utc)), 'elapsed_api_time':f'{elapsed_time:.2f}'}
logger.log_struct(json_obj, "INFO")
return create_api_response('Success',data=result,message=f"Total elapsed API time {elapsed_time:.2f}")
except Exception as e:
job_status = "Failed"
message="Unable to extract neighbour nodes for given element ID"
error_message = str(e)
logging.exception(f'Exception in get neighbours :{error_message}')
return create_api_response(job_status, message=message, error=error_message)
finally:
gc.collect()

@app.post("/graph_query")
async def graph_query(
uri: str = Form(),
Expand Down
13 changes: 11 additions & 2 deletions backend/src/chunkid_entities.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging
from src.graph_query import *
from src.shared.constants import *
import re

def process_records(records):
"""
Expand Down Expand Up @@ -191,7 +192,11 @@ def get_entities_from_chunkids(uri, username, password, database ,nodedetails,en
if "entitydetails" in nodedetails and nodedetails["entitydetails"]:
entity_ids = [item["id"] for item in nodedetails["entitydetails"]]
logging.info(f"chunkid_entities module: Starting for entity ids: {entity_ids}")
return process_entityids(driver, entity_ids)
result = process_entityids(driver, entity_ids)
if "chunk_data" in result.keys():
for chunk in result["chunk_data"]:
chunk["text"] = re.sub(r'\s+', ' ', chunk["text"])
return result
else:
logging.info("chunkid_entities module: No entity ids are passed")
return default_response
Expand All @@ -201,7 +206,11 @@ def get_entities_from_chunkids(uri, username, password, database ,nodedetails,en
if "chunkdetails" in nodedetails and nodedetails["chunkdetails"]:
chunk_ids = [item["id"] for item in nodedetails["chunkdetails"]]
logging.info(f"chunkid_entities module: Starting for chunk ids: {chunk_ids}")
return process_chunkids(driver, chunk_ids, entities)
result = process_chunkids(driver, chunk_ids, entities)
if "chunk_data" in result.keys():
for chunk in result["chunk_data"]:
chunk["text"] = re.sub(r'\s+', ' ', chunk["text"])
return result
else:
logging.info("chunkid_entities module: No chunk ids are passed")
return default_response
Expand Down
63 changes: 63 additions & 0 deletions backend/src/neighbours.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import logging
from src.graph_query import *

NEIGHBOURS_FROM_ELEMENT_ID_QUERY = """
MATCH (n)
WHERE elementId(n) = $element_id

MATCH (n)<-[rels]->(m)
WITH n,
([n] + COLLECT(DISTINCT m)) AS allNodes,
COLLECT(DISTINCT rels) AS allRels

RETURN
[node IN allNodes |
node {
.*,
embedding: null,
text: null,
summary: null,
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
}
}
] AS nodes,

[r IN allRels |
{
start_node_element_id: elementId(startNode(r)),
end_node_element_id: elementId(endNode(r)),
type: type(r),
element_id: elementId(r)
}
] AS relationships
"""


def get_neighbour_nodes(uri, username, password, database, element_id, query=NEIGHBOURS_FROM_ELEMENT_ID_QUERY):
driver = None

try:
logging.info(f"Querying neighbours for element_id: {element_id}")
driver = get_graphDB_driver(uri, username, password, database)
driver.verify_connectivity()
logging.info("Database connectivity verified.")

records, summary, keys = driver.execute_query(query,element_id=element_id)
nodes = records[0].get("nodes", [])
relationships = records[0].get("relationships", [])
result = {"nodes": nodes, "relationships": relationships}

logging.info(f"Successfully retrieved neighbours for element_id: {element_id}")
return result

except Exception as e:
logging.error(f"Error retrieving neighbours for element_id: {element_id}: {e}")
return {"nodes": [], "relationships": []}

finally:
if driver is not None:
driver.close()
logging.info("Database driver closed.")
16 changes: 9 additions & 7 deletions backend/src/shared/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@
RETURN
d AS doc,
[chunk IN chunks |
chunk {.*, embedding: null}
chunk {.*, embedding: null, element_id: elementId(chunk)}
] AS chunks,
[
node IN nodes |
Expand Down Expand Up @@ -168,10 +168,10 @@
CHAT_EMBEDDING_FILTER_SCORE_THRESHOLD = 0.10

CHAT_TOKEN_CUT_OFF = {
("openai-gpt-3.5",'azure_ai_gpt_35',"gemini-1.0-pro","gemini-1.5-pro", "gemini-1.5-flash","groq-llama3",'groq_llama3_70b','anthropic_claude_3_5_sonnet','fireworks_llama_v3_70b','bedrock_claude_3_5_sonnet', ) : 4,
("openai-gpt-4","diffbot" ,'azure_ai_gpt_4o',"openai-gpt-4o", "openai-gpt-4o-mini") : 28,
('openai_gpt_3.5','azure_ai_gpt_35',"gemini_1.0_pro","gemini_1.5_pro", "gemini_1.5_flash","groq-llama3",'groq_llama3_70b','anthropic_claude_3_5_sonnet','fireworks_llama_v3_70b','bedrock_claude_3_5_sonnet', ) : 4,
("openai-gpt-4","diffbot" ,'azure_ai_gpt_4o',"openai_gpt_4o", "openai_gpt_4o_mini") : 28,
("ollama_llama3") : 2
}
}

### CHAT TEMPLATES
CHAT_SYSTEM_TEMPLATE = """
Expand Down Expand Up @@ -473,14 +473,16 @@
.*,
embedding: null,
fileName: d.fileName,
fileSource: d.fileSource
fileSource: d.fileSource,
element_id: elementId(c)
}
] AS chunks,
[
community IN communities WHERE community IS NOT NULL |
community {
.*,
embedding: null
embedding: null,
element_id:elementId(community)
}
] AS communities,
[
Expand Down Expand Up @@ -551,7 +553,7 @@
WHERE elementId(community) IN $communityids
WITH collect(distinct community) AS communities
RETURN [community IN communities |
community {.*, embedding: null, elementid: elementId(community)}] AS communities
community {.*, embedding: null, element_id: elementId(community)}] AS communities
"""

## CHAT MODES
Expand Down
13 changes: 10 additions & 3 deletions frontend/src/components/ChatBot/ChatInfoModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { tokens } from '@neo4j-ndl/base';
import ChunkInfo from './ChunkInfo';
import EntitiesInfo from './EntitiesInfo';
import SourcesInfo from './SourcesInfo';
import CommunitiesInfo from './Communities';
import CommunitiesInfo from './CommunitiesInfo';
import { chatModeLables, supportedLLmsForRagas } from '../../utils/Constants';
import { Relationship } from '@neo4j-nvl/base';
import { getChatMetrics } from '../../services/GetRagasMetric';
Expand Down Expand Up @@ -74,6 +74,8 @@ const ChatInfoModal: React.FC<chatInfoMessage> = ({
const [copiedText, setcopiedText] = useState<boolean>(false);
const [showMetricsTable, setShowMetricsTable] = useState<boolean>(Boolean(metricDetails));

console.log('node', nodeDetails);

const actions: CypherCodeBlockProps['actions'] = useMemo(
() => [
{
Expand Down Expand Up @@ -348,9 +350,14 @@ const ChatInfoModal: React.FC<chatInfoMessage> = ({
<></>
)}
</Flex>
{activeTab == 4 && nodes?.length && relationships?.length ? (
{activeTab == 4 && nodes?.length && relationships?.length && mode !== chatModeLables.graph ? (
<Box className='button-container flex mt-2 justify-center'>
<GraphViewButton nodeValues={nodes} relationshipValues={relationships} />
<GraphViewButton
nodeValues={nodes}
relationshipValues={relationships}
label='Graph Entities used for Answer Generation'
viewType='chatInfoView'
/>
</Box>
) : (
<></>
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/components/ChatBot/ChatModesSwitch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export default function ChatModesSwitch({
size='small'
clean
onClick={() => switchToOtherMode(currentModeIndex - 1)}
aria-label='left'
>
<ChevronLeftIconSolid />
</IconButton>
Expand All @@ -39,6 +40,7 @@ export default function ChatModesSwitch({
size='small'
clean
onClick={() => switchToOtherMode(currentModeIndex + 1)}
aria-label='right'
>
<ChevronRightIconSolid />
</IconButton>
Expand Down
Loading