Skip to content

Commit

Permalink
feat: search content to create AI chat (#340)
Browse files Browse the repository at this point in the history
* feat: search content to create chat AI

* fix: unify navbar options

* feat: improve search within folder

* fixes
  • Loading branch information
paulclindo authored Jun 17, 2024
1 parent cfad0de commit 8bcfb01
Show file tree
Hide file tree
Showing 12 changed files with 523 additions and 575 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -202,53 +202,55 @@ export const KnowledgeSearchDrawer = ({

<Form {...searchVectorFSForm}>
<form
className="mb-4 flex flex-1 shrink-0 items-center gap-2 pt-4"
className="flex shrink-0 flex-col items-center gap-2 pt-4"
onSubmit={searchVectorFSForm.handleSubmit(onSubmit)}
>
<FormField
control={searchVectorFSForm.control}
name="searchQuery"
render={({ field }) => (
<div className="relative flex h-10 w-full flex-1 items-center">
<Input
autoFocus
className="placeholder-gray-80 !h-[50px] bg-gray-200 py-2 pl-10"
onChange={field.onChange}
placeholder="Search anything..."
value={field.value}
/>
<SearchIcon className="absolute left-4 top-1/2 -z-[1px] h-4 w-4 -translate-y-1/2 bg-gray-300" />
{currentSearchQuery && (
<Button
className="absolute right-1 h-8 w-8 bg-gray-200 p-2"
onClick={() => {
searchVectorFSForm.reset({ searchQuery: '' });
setIsSearchEntered(false);
}}
size="auto"
type="button"
variant="ghost"
>
<XIcon />
<span className="sr-only">Clear Search</span>
</Button>
)}
</div>
)}
/>
<Button
className="h-12 w-12 rounded-lg"
disabled={isPending && isLoading}
isLoading={isPending && isLoading}
size="icon"
type="submit"
>
<SearchIcon />
<span className="sr-only">Search</span>
</Button>
<div className="flex w-full flex-1 items-center gap-2">
<FormField
control={searchVectorFSForm.control}
name="searchQuery"
render={({ field }) => (
<div className="relative flex-1">
<Input
autoFocus
className="placeholder-gray-80 !h-[50px] bg-gray-200 py-2 pl-10"
onChange={field.onChange}
placeholder="Search anything..."
value={field.value}
/>
<SearchIcon className="absolute left-4 top-1/2 -z-[1px] h-4 w-4 -translate-y-1/2 bg-gray-300" />
{currentSearchQuery && (
<Button
className="absolute right-1 top-2 h-8 w-8 bg-gray-200 p-2"
onClick={() => {
searchVectorFSForm.reset({ searchQuery: '' });
setIsSearchEntered(false);
}}
size="auto"
type="button"
variant="ghost"
>
<XIcon />
<span className="sr-only">Clear Search</span>
</Button>
)}
</div>
)}
/>
<Button
className="h-[48px] w-[48px] shrink-0 rounded-xl p-3.5"
disabled={isPending && isLoading}
isLoading={isPending && isLoading}
size="auto"
type="submit"
>
<SearchIcon />
<span className="sr-only">Search</span>
</Button>
</div>
</form>
</Form>
<ScrollArea className="h-[calc(100vh-340px)] pr-4 [&>div>div]:!block">
<ScrollArea className="h-[calc(100vh-340px)] pr-4 [&>div>div]:!block">
{isSearchEntered &&
isPending &&
Array.from({ length: 4 }).map((_, idx) => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
VectorFsFolderCreateShareableAction,
VectorFsFolderDeleteAction,
VectorFsFolderMoveAction,
VectorFsFolderSearchKnowledgeAction,
VectorFsFolderUnshareAction,
} from './vector-fs-folder-options';
import {
Expand Down Expand Up @@ -66,7 +65,6 @@ export enum VectorFsFolderAction {
Move = 'move-folder',
Copy = 'copy-folder',
Delete = 'delete-folder',
SearchKnowledge = 'search-knowledge-folder',
CreateShareable = 'create-shareable-folder',
Unshare = 'unshare-folder',
}
Expand Down Expand Up @@ -105,8 +103,6 @@ const VectorFSDrawerContent = ({
return <VectorFsFolderCopyAction />;
case VectorFsFolderAction.Delete:
return <VectorFsFolderDeleteAction />;
case VectorFsFolderAction.SearchKnowledge:
return <VectorFsFolderSearchKnowledgeAction />;
case VectorFsFolderAction.CreateShareable:
return <VectorFsFolderCreateShareableAction />;
case VectorFsFolderAction.Unshare:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,27 @@ import {
ShareFolderFormSchema,
shareFolderFormSchema,
} from '@shinkai_network/shinkai-node-state/forms/vector-fs/folder';
import {
SearchVectorFormSchema,
searchVectorFormSchema,
} from '@shinkai_network/shinkai-node-state/forms/vector-fs/vector-search';
import { useCopyVrFolder } from '@shinkai_network/shinkai-node-state/lib/mutations/copyVRFolder/useCopyVrFolder';
import { useCreateShareableFolder } from '@shinkai_network/shinkai-node-state/lib/mutations/createShareableFolder/useCreateShareableFolder';
import { useDeleteVrFolder } from '@shinkai_network/shinkai-node-state/lib/mutations/deleteVRFolder/useDeleteVRFolder';
import { useMoveVrFolder } from '@shinkai_network/shinkai-node-state/lib/mutations/moveVRFolder/useMoveVRFolder';
import { useUnshareFolder } from '@shinkai_network/shinkai-node-state/lib/mutations/unshareFolder/useUnshareFolder';
import { useGetVRSeachSimplified } from '@shinkai_network/shinkai-node-state/lib/queries/getVRSearchSimplified/useGetSearchVRItems';
import {
Alert,
AlertDescription,
AlertTitle,
Button,
Form,
FormField,
Input,
ScrollArea,
SheetDescription,
SheetFooter,
SheetHeader,
SheetTitle,
TextField,
} from '@shinkai_network/shinkai-ui';
import { AlertCircle, SearchIcon, XIcon } from 'lucide-react';
import React, { useState } from 'react';
import { useForm, useWatch } from 'react-hook-form';
import { Link } from 'react-router-dom';
import { AlertCircle } from 'lucide-react';
import React from 'react';
import { useForm } from 'react-hook-form';
import { toast } from 'sonner';

import { useAuth } from '../../../store/auth';
Expand Down Expand Up @@ -222,159 +214,6 @@ export const VectorFsFolderCopyAction = () => {
);
};

export const VectorFsFolderSearchKnowledgeAction = () => {
const selectedFolder = useVectorFsStore((state) => state.selectedFolder);
const auth = useAuth((state) => state.auth);
const [isSearchEntered, setIsSearchEntered] = useState(false);
const [search, setSearch] = useState('');
const closeDrawerMenu = useVectorFsStore((state) => state.closeDrawerMenu);
const searchVectorFSForm = useForm<SearchVectorFormSchema>({
resolver: zodResolver(searchVectorFormSchema),
defaultValues: {
searchQuery: '',
},
});
const currentSearchQuery = useWatch({
control: searchVectorFSForm.control,
name: 'searchQuery',
});

const { isPending, isLoading, isSuccess, data } = useGetVRSeachSimplified(
{
nodeAddress: auth?.node_address ?? '',
search: search,
shinkaiIdentity: auth?.shinkai_identity ?? '',
profile: auth?.profile ?? '',
my_device_encryption_sk: auth?.my_device_encryption_sk ?? '',
my_device_identity_sk: auth?.my_device_identity_sk ?? '',
node_encryption_pk: auth?.node_encryption_pk ?? '',
profile_encryption_sk: auth?.profile_encryption_sk ?? '',
profile_identity_sk: auth?.profile_identity_sk ?? '',
path: selectedFolder?.path,
},
{
enabled: isSearchEntered || !!search,
refetchOnWindowFocus: false,
},
);

const onSubmit = async (data: SearchVectorFormSchema) => {
if (!data.searchQuery) return;
setIsSearchEntered(true);
setSearch(data.searchQuery);
};

return (
<React.Fragment>
<SheetHeader>
<SheetTitle className="font-normal">
AI Files Content Search within
<span className="font-medium">
{' '}
&quot;{selectedFolder?.name}&quot;
</span>{' '}
</SheetTitle>
</SheetHeader>
<p className="text-gray-80 my-3 text-sm">
Search to find content across all files in your AI Files easily
</p>
<Form {...searchVectorFSForm}>
<form
className="mb-4 flex shrink-0 flex-col items-center gap-2 pt-4"
onSubmit={searchVectorFSForm.handleSubmit(onSubmit)}
>
<FormField
control={searchVectorFSForm.control}
name="searchQuery"
render={({ field }) => (
<div className="relative flex h-10 w-full flex-1 items-center">
<Input
autoFocus
className="placeholder-gray-80 !h-[50px] bg-gray-200 py-2 pl-10"
onChange={field.onChange}
placeholder="Search anything..."
value={field.value}
/>
<SearchIcon className="absolute left-4 top-1/2 -z-[1px] h-4 w-4 -translate-y-1/2 bg-gray-300" />
{currentSearchQuery && (
<Button
className="absolute right-1 h-8 w-8 bg-gray-200 p-2"
onClick={() => {
searchVectorFSForm.reset({ searchQuery: '' });
}}
size="auto"
type="button"
variant="ghost"
>
<XIcon />
<span className="sr-only">Clear Search</span>
</Button>
)}
</div>
)}
/>
<Button
className="w-full"
disabled={isPending && isLoading}
isLoading={isPending && isLoading}
size="default"
type="submit"
>
<span className="">Search</span>
</Button>
</form>
</Form>
<ScrollArea className="h-[60vh] pr-4 [&>div>div]:!block">
{isSearchEntered &&
isPending &&
Array.from({ length: 4 }).map((_, idx) => (
<div
className="mb-1 flex h-[69px] items-center justify-between gap-2 rounded-lg bg-gray-400 py-3"
key={idx}
/>
))}
{isSearchEntered && isSuccess && (
<div>
<h2 className="text-gray-80 p-2 font-medium">
Found {data?.length} results
</h2>
<div className="flex flex-col gap-2 divide-y divide-slate-600">
{data?.map(([content, pathList, score], idx) => (
<div className="flex flex-col gap-1 px-2 py-3" key={idx}>
<p className="text-sm text-white">{content}</p>
<div className="text-gray-80 flex justify-between text-xs">
<div className="flex items-center gap-1">
<span>Source:</span>
<Link
className={'underline'}
onClick={() => {
closeDrawerMenu();
}}
to={{
pathname: '/node-files',
search: `?path=${encodeURIComponent(
pathList.join('/'),
)}`,
}}
>
{pathList.join('/')}
</Link>
</div>
<div className="flex items-center gap-1">
<span>Accuracy:</span>
<span>{parseFloat(score.toFixed(2)) * 100 + '%'}</span>
</div>
</div>
</div>
))}
</div>
</div>
)}
</ScrollArea>
</React.Fragment>
);
};

export const VectorFsFolderCreateShareableAction = () => {
const selectedFolder = useVectorFsStore((state) => state.selectedFolder);
const closeDrawerMenu = useVectorFsStore((state) => state.closeDrawerMenu);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ import {
TrashIcon,
} from 'lucide-react';
import React from 'react';
import { useNavigate } from 'react-router-dom';

import { useVectorFsStore,VectorFSLayout } from '../context/vector-fs-context';
import { useVectorFsStore, VectorFSLayout } from '../context/vector-fs-context';
import { VectorFsFolderAction } from './vector-fs-drawer';

export const VectorFsFolderInfo = ({
Expand Down Expand Up @@ -68,6 +69,7 @@ const VectorFsFolder = ({
const setActiveDrawerMenuOption = useVectorFsStore(
(state) => state.setActiveDrawerMenuOption,
);
const navigate = useNavigate();
const setSelectedFolder = useVectorFsStore(
(state) => state.setSelectedFolder,
);
Expand Down Expand Up @@ -161,7 +163,11 @@ const VectorFsFolder = ({
name: 'Search within folder',
icon: <AISearchContentIcon className="mr-3 h-4 w-4" />,
onClick: () => {
setActiveDrawerMenuOption(VectorFsFolderAction.SearchKnowledge);
navigate('/vector-search', {
state: {
folderPath: folder.path,
},
});
},
},
{
Expand Down
Loading

0 comments on commit 8bcfb01

Please sign in to comment.