Skip to content
Merged

Dev #1073

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
26581db
Read only mode for unauthenticated users (#1046)
kartikpersistent Jan 30, 2025
449552d
langchain updates (#1048)
prakriti-solankey Jan 30, 2025
2d86c5c
testing script changed for better logging errors and results of vario…
kaustubh-darekar Jan 30, 2025
578efad
Deepseek models integration (#1051)
kaustubh-darekar Jan 30, 2025
339488a
fixed top-line of drop-area (#1049)
kartikpersistent Jan 30, 2025
1dbd902
Schema viz (#1035)
prakriti-solankey Jan 30, 2025
6f3f863
updated to new ndl minor version and fixed sources modal display for …
kartikpersistent Feb 3, 2025
38eb72e
Chunk size overlap config (#1059)
prakriti-solankey Feb 7, 2025
6e60361
fix-load-existing-schema (#1061)
dhiaaeddine16 Feb 10, 2025
228ab9b
added bug report feature request and format fixes
kartikpersistent Feb 11, 2025
fbd9d3e
configured dependenabot for python
kartikpersistent Feb 11, 2025
6893a26
configuration fix
kartikpersistent Feb 11, 2025
4b831df
Fixed the logging time issue
praveshkumar1988 Feb 11, 2025
d53ba43
Backend connection config (#1060)
prakriti-solankey Feb 11, 2025
71e013e
Unable to get the status of document node resolved due to leading spa…
kaustubh-darekar Feb 11, 2025
d9a89f8
updated dependency
kartikpersistent Feb 11, 2025
2c8fe2a
Merge branch 'dev' of https://github.com/neo4j-labs/llm-graph-builder…
kartikpersistent Feb 11, 2025
192a1bc
always show schema button
prakriti-solankey Feb 11, 2025
e8e576f
always show schema button
prakriti-solankey Feb 11, 2025
ed69115
uri
prakriti-solankey Feb 11, 2025
3624feb
Update README.md
kartikpersistent Feb 11, 2025
738eecc
Update README.md
kartikpersistent Feb 11, 2025
69a1003
Update README.md
kartikpersistent Feb 12, 2025
4c48124
Update README.md
kartikpersistent Feb 12, 2025
bd917ae
Fixed the create community issue for backend connection configuration
praveshkumar1988 Feb 12, 2025
8b8368b
removal of unused code
prakriti-solankey Feb 12, 2025
5591741
Support added for gpt 3o mini & gemini flash 2.0 in dev (#1069)
kaustubh-darekar Feb 12, 2025
6762367
Cancelling the API's on Unmounting phase (#1068)
kartikpersistent Feb 13, 2025
7f075d5
Merge branch 'staging' into dev
prakriti-solankey Feb 13, 2025
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: 15 additions & 5 deletions frontend/src/API/Index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,21 @@ const api = axios.create({

export const createDefaultFormData = (userCredentials: UserCredentials) => {
const formData = new FormData();
if (userCredentials?.uri) formData.append('uri', userCredentials?.uri);
if (userCredentials?.database) formData.append('database', userCredentials?.database);
if (userCredentials?.userName) formData.append('userName', userCredentials?.userName);
if (userCredentials?.password) formData.append('password', userCredentials?.password);
if (userCredentials?.email) formData.append('email', userCredentials?.email);
if (userCredentials?.uri) {
formData.append('uri', userCredentials?.uri);
}
if (userCredentials?.database) {
formData.append('database', userCredentials?.database);
}
if (userCredentials?.userName) {
formData.append('userName', userCredentials?.userName);
}
if (userCredentials?.password) {
formData.append('password', userCredentials?.password);
}
if (userCredentials?.email) {
formData.append('email', userCredentials?.email);
}
api.interceptors.request.use(
(config) => {
if (config.data instanceof FormData) {
Expand Down
9 changes: 3 additions & 6 deletions frontend/src/components/ChatBot/ChatInfoModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ const ChatInfoModal: React.FC<chatInfoMessage> = ({
? false
: null
);

const actions: React.ComponentProps<typeof IconButton<'button'>>[] = useMemo(
() => [
{
Expand All @@ -132,18 +131,15 @@ const ChatInfoModal: React.FC<chatInfoMessage> = ({
);

useEffect(() => {
const abortcontroller = new AbortController();
if (
(mode != chatModeLables.graph || error?.trim() !== '') &&
(!nodes.length || !infoEntities.length || !chunks.length)
) {
(async () => {
toggleInfoLoading();
try {
const response = await chunkEntitiesAPI(
nodeDetails,
entities_ids,
mode,
);
const response = await chunkEntitiesAPI(nodeDetails, entities_ids, mode, abortcontroller.signal);
if (response.data.status === 'Failure') {
throw new Error(response.data.error);
}
Expand Down Expand Up @@ -195,6 +191,7 @@ const ChatInfoModal: React.FC<chatInfoMessage> = ({
if (metricsLoading) {
toggleMetricsLoading();
}
abortcontroller.abort();
};
}, [nodeDetails, mode, error, metricsLoading]);

Expand Down
3 changes: 1 addition & 2 deletions frontend/src/components/ChatBot/ChatOnlyComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ const ChatContent: React.FC<ChatProps> = ({ chatMessages }) => {
} else {
setOpenConnection((prev) => ({ ...prev, openPopUp: true }));
}
}
else {
} else {
const credentialsForAPI: UserCredentials = {
uri,
userName: user,
Expand Down
33 changes: 16 additions & 17 deletions frontend/src/components/Content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ const Content: React.FC<ContentProps> = ({
const [currentPage, setCurrentPage] = useState<number>(0);
const [totalPageCount, setTotalPageCount] = useState<number | null>(null);
const [textChunks, setTextChunks] = useState<chunkdata[]>([]);
const chunksTextAbortController = useRef<AbortController>();

const [alertStateForRetry, setAlertStateForRetry] = useState<BannerAlertProps>({
showAlert: false,
Expand Down Expand Up @@ -103,9 +104,9 @@ const Content: React.FC<ContentProps> = ({
additionalInstructions,
setAdditionalInstructions,
} = useFileContext();
const [viewPoint, setViewPoint] = useState<'tableView' | 'showGraphView' | 'chatInfoView' | 'neighborView'|'showSchemaView'>(
'tableView'
);
const [viewPoint, setViewPoint] = useState<
'tableView' | 'showGraphView' | 'chatInfoView' | 'neighborView' | 'showSchemaView'
>('tableView');
const [showDeletePopUp, setShowDeletePopUp] = useState<boolean>(false);
const [deleteLoading, setIsDeleteLoading] = useState<boolean>(false);

Expand Down Expand Up @@ -221,8 +222,9 @@ const Content: React.FC<ContentProps> = ({
});
};
const getChunks = async (name: string, pageNo: number) => {
chunksTextAbortController.current = new AbortController();
toggleChunksLoading();
const response = await getChunkText(name, pageNo);
const response = await getChunkText(name, pageNo, chunksTextAbortController.current.signal);
setTextChunks(response.data.data.pageitems);
if (!totalPageCount) {
setTotalPageCount(response.data.data.total_pages);
Expand Down Expand Up @@ -271,11 +273,7 @@ const Content: React.FC<ContentProps> = ({
});
if (fileItem.name != undefined && userCredentials != null) {
const { name } = fileItem;
triggerStatusUpdateAPI(
name as string,
userCredentials,
updateStatusForLargeFiles
);
triggerStatusUpdateAPI(name as string, userCredentials, updateStatusForLargeFiles);
}

const apiResponse = await extractAPI(
Expand Down Expand Up @@ -544,12 +542,14 @@ const Content: React.FC<ContentProps> = ({
let finalUrl = bloomUrl;
if (userCredentials?.database && userCredentials.uri && userCredentials.userName) {
const uriCoded = userCredentials.uri.replace(/:\d+$/, '');
const connectURL = `${uriCoded.split('//')[0]}//${userCredentials.userName}@${uriCoded.split('//')[1]}:${userCredentials.port ?? '7687'}`;
const connectURL = `${uriCoded.split('//')[0]}//${userCredentials.userName}@${uriCoded.split('//')[1]}:${
userCredentials.port ?? '7687'
}`;
const encodedURL = encodeURIComponent(connectURL);
finalUrl = bloomUrl?.replace('{CONNECT_URL}', encodedURL);
}
window.open(finalUrl, '_blank');
};
};

const handleGraphView = () => {
setOpenGraphView(true);
Expand Down Expand Up @@ -855,7 +855,10 @@ const Content: React.FC<ContentProps> = ({
{showChunkPopup && (
<ChunkPopUp
chunksLoading={chunksLoading}
onClose={() => toggleChunkPopup()}
onClose={() => {
chunksTextAbortController.current?.abort();
toggleChunkPopup();
}}
showChunkPopup={showChunkPopup}
chunks={textChunks}
incrementPage={incrementPage}
Expand Down Expand Up @@ -885,11 +888,7 @@ const Content: React.FC<ContentProps> = ({
<div className='connectionstatus__container'>
<span className='h6 px-1'>Neo4j connection {isReadOnlyUser ? '(Read only Mode)' : ''}</span>
<Typography variant='body-medium'>
<DatabaseStatusIcon
isConnected={connectionStatus}
isGdsActive={isGdsActive}
uri={userCredentials?.uri}
/>
<DatabaseStatusIcon isConnected={connectionStatus} isGdsActive={isGdsActive} uri={userCredentials?.uri} />
<div className='pt-1 flex gap-1 items-center'>
<div>{!hasSelections ? <StatusIndicator type='danger' /> : <StatusIndicator type='success' />}</div>
<div>
Expand Down
11 changes: 10 additions & 1 deletion frontend/src/components/Dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { OptionType, ReusableDropdownProps } from '../types';
import { memo, useMemo } from 'react';
import { capitalize, capitalizeWithUnderscore } from '../utils/Utils';
import { prodllms } from '../utils/Constants';
import { InformationCircleIconOutline } from '@neo4j-ndl/react/icons';

const DropdownComponent: React.FC<ReusableDropdownProps> = ({
options,
placeholder,
Expand All @@ -29,7 +31,14 @@ const DropdownComponent: React.FC<ReusableDropdownProps> = ({
<Select
type='select'
label='LLM Models'
helpText={<div className='!w-max'> LLM Model used for Extraction & Chat</div>}
helpText={
<div className='!w-max flex gap-1 items-center'>
<span>
<InformationCircleIconOutline title='info' aria-label='infoicon' className='n-size-token-6' />
</span>
<span>LLM Model used for Extraction & Chat</span>
</div>
}
selectProps={{
onChange: handleChange,
// @ts-ignore
Expand Down
13 changes: 2 additions & 11 deletions frontend/src/components/FileTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -683,20 +683,11 @@ const FileTable: ForwardRefRenderFunction<ChildRef, FileTableProps> = (props, re
};

const handleSmallFile = (item: SourceNode, userCredentials: UserCredentials) => {
subscribe(
item.fileName,
userCredentials,
updatestatus,
updateProgress
).catch(handleFileUploadError);
subscribe(item.fileName, userCredentials, updatestatus, updateProgress).catch(handleFileUploadError);
};

const handleLargeFile = (item: SourceNode, userCredentials: UserCredentials) => {
triggerStatusUpdateAPI(
item.fileName,
userCredentials,
updateStatusForLargeFiles
);
triggerStatusUpdateAPI(item.fileName, userCredentials, updateStatusForLargeFiles);
};
useEffect(() => {
const waitingQueue: CustomFile[] = JSON.parse(
Expand Down
12 changes: 10 additions & 2 deletions frontend/src/components/Graph/GraphViewModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ const GraphViewModal: React.FunctionComponent<GraphViewModalProps> = ({
const [disableRefresh, setDisableRefresh] = useState<boolean>(false);
const [selected, setSelected] = useState<{ type: EntityType; id: string } | undefined>(undefined);
const [mode, setMode] = useState<boolean>(false);
const graphQueryAbortControllerRef = useRef<AbortController>();

const graphQuery: string =
graphType.includes('DocumentChunk') && graphType.includes('Entities')
Expand Down Expand Up @@ -109,17 +110,23 @@ const GraphViewModal: React.FunctionComponent<GraphViewModalProps> = ({
}, [allNodes]);

const fetchData = useCallback(async () => {
graphQueryAbortControllerRef.current = new AbortController();
try {
let nodeRelationshipData;
if (viewPoint === graphLabels.showGraphView) {
nodeRelationshipData = await graphQueryAPI(
graphQuery,
selectedRows?.map((f) => f.name)
selectedRows?.map((f) => f.name),
graphQueryAbortControllerRef.current.signal
);
} else if (viewPoint === graphLabels.showSchemaView) {
nodeRelationshipData = await getGraphSchema();
} else {
nodeRelationshipData = await graphQueryAPI(graphQuery, [inspectedName ?? '']);
nodeRelationshipData = await graphQueryAPI(
graphQuery,
[inspectedName ?? ''],
graphQueryAbortControllerRef.current.signal
);
}
return nodeRelationshipData;
} catch (error: any) {
Expand Down Expand Up @@ -310,6 +317,7 @@ const GraphViewModal: React.FunctionComponent<GraphViewModalProps> = ({

// when modal closes reset all states to default
const onClose = () => {
graphQueryAbortControllerRef?.current?.abort();
setStatus('unknown');
setStatusMessage('');
setGraphViewOpen(false);
Expand Down
13 changes: 5 additions & 8 deletions frontend/src/components/Layout/PageLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,22 +115,21 @@ const PageLayout: React.FC = () => {
email: user?.email ?? '',
connection: 'backendApi',
};
//setChunksToBeProces(credentials.chunksTobeProcess);
// setChunksToBeProces(credentials.chunksTobeProcess);
setIsGCSActive(credentials.isGCSActive);
setUserCredentials(credentials);
createDefaultFormData({ uri: credentials.uri, email: credentials.email ?? '' });
setGdsActive(credentials.isgdsActive);
setConnectionStatus(Boolean(connectionData.data.graph_connection));
setIsReadOnlyUser(connectionData.data.isReadonlyUser);
handleDisconnectButtonState(false);
}
else if (!connectionData.data && connectionData.status === 'Success') {
} else if (!connectionData.data && connectionData.status === 'Success') {
const storedCredentials = localStorage.getItem('neo4j.connection');
if (storedCredentials) {
const credentials = JSON.parse(storedCredentials);
setUserCredentials({ ...credentials, password: atob(credentials.password) });
createDefaultFormData({ ...credentials, password: atob(credentials.password) });
//setChunksToBeProces(credentials.chunksTobeProcess);
// setChunksToBeProces(credentials.chunksTobeProcess);
setIsGCSActive(credentials.isGCSActive);
setGdsActive(credentials.isgdsActive);
setConnectionStatus(Boolean(credentials.connection === 'connectAPI'));
Expand All @@ -144,7 +143,7 @@ const PageLayout: React.FC = () => {
setErrorMessage(backendApiResponse?.data?.error);
setOpenConnection((prev) => ({ ...prev, openPopUp: true }));
handleDisconnectButtonState(true);
console.log('from else cndition error is there')
console.log('from else cndition error is there');
}
} catch (error) {
if (error instanceof Error) {
Expand All @@ -160,9 +159,7 @@ const PageLayout: React.FC = () => {
setClearHistoryData(true);
setIsDeleteChatLoading(true);
cancel();
const response = await clearChatAPI(
sessionStorage.getItem('session_id') ?? ''
);
const response = await clearChatAPI(sessionStorage.getItem('session_id') ?? '');
setIsDeleteChatLoading(false);
if (response.data.status === 'Success') {
const date = new Date();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ export default function ConnectionModal({
isGCSActive,
chunksTobeProcess,
email: user?.email ?? '',
connection:'connectAPI',
connection: 'connectAPI',
})
);
setUserDbVectorIndex(response.data.data.db_vector_dimension);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,12 @@ export default function DeduplicationTab() {
const [viewPoint, setViewPoint] = useState('');
const [nodesCount, setNodesCount] = useState<number>(0);
const { colorMode } = useContext(ThemeWrapperContext);
const abortRef = useRef<AbortController>();

const fetchDuplicateNodes = useCallback(async () => {
try {
setLoading(true);
const duplicateNodesData = await getDuplicateNodes();
const duplicateNodesData = await getDuplicateNodes(abortRef?.current?.signal as AbortSignal);
setLoading(false);
if (duplicateNodesData.data.status === 'Failed') {
throw new Error(duplicateNodesData.data.error);
Expand All @@ -71,11 +72,15 @@ export default function DeduplicationTab() {
}, [userCredentials]);

useEffect(() => {
abortRef.current = new AbortController();
if (userCredentials != null) {
(async () => {
await fetchDuplicateNodes();
})();
}
return () => {
abortRef.current?.abort();
};
}, [userCredentials]);

const clickHandler = async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ export default function DeletePopUpForOrphanNodes({
const [openGraphView, setOpenGraphView] = useState(false);
const [viewPoint, setViewPoint] = useState('');
const { colorMode } = useContext(ThemeWrapperContext);

const ref = useRef<AbortController>();
const fetchOrphanNodes = useCallback(async () => {
try {
setLoading(true);
const apiresponse = await getOrphanNodes();
const apiresponse = await getOrphanNodes(ref.current?.signal as AbortSignal);
setLoading(false);
if (apiresponse.data.data.length) {
setOrphanNodes(apiresponse.data.data);
Expand All @@ -65,6 +65,7 @@ export default function DeletePopUpForOrphanNodes({
}, []);

useEffect(() => {
ref.current = new AbortController();
if (userCredentials != null) {
(async () => {
await fetchOrphanNodes();
Expand All @@ -73,6 +74,7 @@ export default function DeletePopUpForOrphanNodes({
return () => {
setOrphanNodes([]);
setTotalOrphanNodes(0);
ref?.current?.abort();
};
}, [userCredentials]);
const columnHelper = createColumnHelper<orphanNodeProps>();
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/services/ChunkEntitiesInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const chunkEntitiesAPI = async (
nodeDetails: nodeDetailsProps,
entities: string[],
mode: string,
signal: AbortSignal
) => {
try {
const formData = new FormData();
Expand All @@ -16,6 +17,7 @@ const chunkEntitiesAPI = async (
headers: {
'Content-Type': 'multipart/form-data',
},
signal,
});
return response;
} catch (error) {
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/services/GetDuplicateNodes.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { duplicateNodesData } from '../types';
import api from '../API/Index';

export const getDuplicateNodes = async () => {
export const getDuplicateNodes = async (signal: AbortSignal) => {
const formData = new FormData();
try {
const response = await api.post<duplicateNodesData>(`/get_duplicate_nodes`, formData);
const response = await api.post<duplicateNodesData>(`/get_duplicate_nodes`, formData, { signal });
return response;
} catch (error) {
console.log(error);
Expand Down
Loading