Skip to content

Commit

Permalink
Merge pull request #117 from SciPhi-AI/Nolan/SidebarPlusIndex
Browse files Browse the repository at this point in the history
Refactor Sidebar, KG Management
  • Loading branch information
NolanTrem authored Oct 30, 2024
2 parents 2287ba5 + 7730b0f commit 698006a
Show file tree
Hide file tree
Showing 16 changed files with 1,232 additions and 195 deletions.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
"force-graph": "^1.43.5",
"framer-motion": "^11.3.8",
"fs": "0.0.1-security",
"js": "^0.1.0",
"lucide-react": "^0.395.0",
"neo4j-driver": "^5.22.0",
"next": "14.2.5",
Expand All @@ -91,7 +92,8 @@
"pnpm": "^9.5.0",
"postcss": "^8.4.39",
"posthog-js": "^1.148.0",
"r2r-js": "^0.3.11",
"r2r": "0.0.0-beta.0",
"r2r-js": "^0.3.12",
"radix-ui": "^1.0.1",
"react": "18.3.1",
"react-chartjs-2": "^5.2.0",
Expand Down
290 changes: 244 additions & 46 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

20 changes: 10 additions & 10 deletions src/components/ChatDemo/CreateDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import {
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input'; // Assuming you have this
import { Textarea } from '@/components/ui/textarea'; // Assuming you have this
import { Input } from '@/components/ui/input';
import { Textarea } from '@/components/ui/textarea';

interface CreateDialogProps {
isOpen: boolean;
Expand Down Expand Up @@ -63,13 +63,13 @@ export const CreateDialog: React.FC<CreateDialogProps> = ({
};

const handleMetadataChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
const value = e.target.value;
const { value } = e.target;
setMetadata(value);
validateMetadata(value);
};

const handleDocumentIdChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value;
const { value } = e.target;
setDocumentId(value);
validateDocumentId(value);
};
Expand Down Expand Up @@ -127,9 +127,9 @@ export const CreateDialog: React.FC<CreateDialogProps> = ({
onChange={handleDocumentIdChange}
placeholder="Optional UUID"
className={`${
!isDocumentIdValid
? 'border-red-500 focus:ring-red-500 focus:border-red-500'
: ''
isDocumentIdValid
? ''
: 'border-red-500 focus:ring-red-500 focus:border-red-500'
}`}
/>
{!isDocumentIdValid && (
Expand Down Expand Up @@ -181,9 +181,9 @@ export const CreateDialog: React.FC<CreateDialogProps> = ({
placeholder='Optional JSON: {"key": "value"}'
rows={4}
className={`${
!isMetadataValid
? 'border-red-500 focus:ring-red-500 focus:border-red-500'
: ''
isMetadataValid
? ''
: 'border-red-500 focus:ring-red-500 focus:border-red-500'
}`}
/>
{!isMetadataValid && (
Expand Down
220 changes: 220 additions & 0 deletions src/components/ChatDemo/GraphDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
// GraphDialog.tsx
import { Upload, X } from 'lucide-react';
import { KGRunType } from 'r2r-js';
import React, { useState, useEffect } from 'react';

import { Button } from '@/components/ui/Button';
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import { useUserContext } from '@/context/UserContext';

export type GraphOperationType = 'create' | 'enrich';

interface GraphDialogProps {
isOpen: boolean;
onClose: () => void;
collectionId: string;
operationType: GraphOperationType;
showToast: any;
}

interface EstimateResults {
message: string;
document_count: number;
number_of_jobs_created: number;
total_chunks: number;
estimated_entities: string;
estimated_triples: string;
estimated_llm_calls: string;
estimated_total_in_out_tokens_in_millions: string;
estimated_total_time_in_minutes: string;
estimated_cost_in_usd: string;
}

export const GraphDialog: React.FC<GraphDialogProps> = ({
isOpen,
onClose,
collectionId,
operationType,
showToast,
}) => {
const { getClient } = useUserContext();
const [estimate, setEstimate] = useState<EstimateResults | null>(null);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);

const isCreateOperation = operationType === 'create';
const titleText = isCreateOperation
? 'Create Knowledge Graph'
: 'Enrich Knowledge Graph';
const loadingText = isCreateOperation
? 'Creating Graph...'
: 'Enriching Graph...';
const actionText = isCreateOperation ? 'Create Graph' : 'Enrich Graph';

useEffect(() => {
if (isOpen) {
getEstimate();
}
}, [isOpen]);

const getEstimate = async () => {
setIsLoading(true);
setError(null);
try {
const client = await getClient();
if (!client) {
throw new Error('Failed to get authenticated client');
}

const response = await (isCreateOperation
? client.createGraph(collectionId, KGRunType.ESTIMATE)
: client.enrichGraph(collectionId, KGRunType.ESTIMATE));
setEstimate(response.results);
} catch (err: any) {
// Handle specific 500 error for enrich graph
if (err?.message?.includes('Status 500')) {
const match = err.message.match(
/Status 500: An error '(.+?)' occurred/
);
setError(match ? match[1] : 'An unexpected error occurred');
} else {
setError(
err instanceof Error
? err.message
: `Failed to get ${operationType} estimate`
);
}
} finally {
setIsLoading(false);
}
};

const handleAction = async () => {
setIsLoading(true);
setError(null);
try {
const client = await getClient();
if (!client) {
throw new Error('Failed to get authenticated client');
}

(isCreateOperation
? client.createGraph(collectionId, KGRunType.RUN)
: client.enrichGraph(collectionId, KGRunType.RUN)
).catch((err) => {
showToast({
variant: 'destructive',
title: `${isCreateOperation ? 'Graph Creation' : 'Graph Enrichment'} Failed`,
description:
err instanceof Error ? err.message : 'An unexpected error occurred',
});
});

showToast({
variant: 'success',
title: `${isCreateOperation ? 'Creating' : 'Enriching'} Knowledge Graph`,
description: `The process has started and will continue in the background. You can monitor progress in the Documents tab.`,
});
onClose();
} catch (err) {
setError(
err instanceof Error ? err.message : `Failed to ${operationType} graph`
);
} finally {
setIsLoading(false);
}
};

const handleClose = () => {
setEstimate(null);
setError(null);
onClose();
};

return (
<Dialog open={isOpen} onOpenChange={handleClose}>
<DialogContent className="max-w-2xl bg-background border shadow-md">
<DialogHeader>
<DialogTitle>{titleText}</DialogTitle>
</DialogHeader>

<div className="space-y-4">
{isLoading && !estimate && (
<div className="text-center py-4">
<div className="animate-spin rounded-full h-8 w-8 border-t-2 border-primary mx-auto mb-2" />
<p>Getting estimate...</p>
</div>
)}

{error && (
<div className="bg-destructive/10 text-destructive rounded-md p-4">
{error}
</div>
)}

{estimate && !error && (
<div className="space-y-4">
<div className="grid grid-cols-2 gap-4">
<div className="space-y-2">
<p className="text-sm text-muted-foreground">Documents</p>
<p className="font-medium">{estimate.document_count}</p>
</div>
<div className="space-y-2">
<p className="text-sm text-muted-foreground">Total Chunks</p>
<p className="font-medium">{estimate.total_chunks}</p>
</div>
<div className="space-y-2">
<p className="text-sm text-muted-foreground">
Estimated Entities
</p>
<p className="font-medium">{estimate.estimated_entities}</p>
</div>
<div className="space-y-2">
<p className="text-sm text-muted-foreground">
Estimated Triples
</p>
<p className="font-medium">{estimate.estimated_triples}</p>
</div>
<div className="space-y-2">
<p className="text-sm text-muted-foreground">
Estimated Time
</p>
<p className="font-medium">
{estimate.estimated_total_time_in_minutes}
</p>
</div>
<div className="space-y-2">
<p className="text-sm text-muted-foreground">
Estimated Cost
</p>
<p className="font-medium">
${estimate.estimated_cost_in_usd}
</p>
</div>
</div>

<div className="pt-4">
<p className="text-sm text-muted-foreground mb-2">
{estimate.message}
</p>
<Button
onClick={handleAction}
disabled={isLoading}
color="filled"
className="w-full"
>
{isLoading ? loadingText : actionText}
</Button>
</div>
</div>
)}
</div>
</DialogContent>
</Dialog>
);
};
Loading

0 comments on commit 698006a

Please sign in to comment.