From 5193c5838ac0cac94f96efcb9368670e84ad316f Mon Sep 17 00:00:00 2001 From: n4ze3m Date: Sat, 5 Oct 2024 23:52:13 +0530 Subject: [PATCH] feat: Enable internal search for bots Adds the ability to enable internal search for bots, allowing users to search within their uploaded documents and data sources. This feature is still experimental and may not work as expected in all cases. Fixes #123 --- app/ui/src/@types/bot.ts | 1 + app/ui/src/Layout/BotLayout.tsx | 137 +++++++++++------- app/ui/src/Layout/BotPlaygroundLayout.tsx | 134 ++++++++++------- app/ui/src/components/Bot/Search/index.tsx | 16 +- .../components/Bot/Settings/SettingsBody.tsx | 2 - app/ui/src/hooks/useSettings.tsx | 6 +- app/ui/src/routes/settings/application.tsx | 10 ++ server/src/handlers/api/v1/admin/type.ts | 1 + .../handlers/api/v1/bot/bot/search.handler.ts | 11 +- server/src/handlers/api/v1/bot/bot/types.ts | 1 + .../src/handlers/api/v1/user/get.handler.ts | 1 + server/src/schema/api/v1/admin/index.ts | 2 + server/src/schema/api/v1/bot/bot/index.ts | 4 + server/src/schema/api/v1/user/index.ts | 1 + 14 files changed, 213 insertions(+), 114 deletions(-) diff --git a/app/ui/src/@types/bot.ts b/app/ui/src/@types/bot.ts index 1c6b9f02..a4186aba 100644 --- a/app/ui/src/@types/bot.ts +++ b/app/ui/src/@types/bot.ts @@ -23,6 +23,7 @@ export type BotSettings = { autoResetSession: boolean; autoSyncDataSources: boolean; internetSearchEnabled: boolean; + internalSearchEnabled: boolean; }; chatModel: { label: string; diff --git a/app/ui/src/Layout/BotLayout.tsx b/app/ui/src/Layout/BotLayout.tsx index a8dbbc99..d1dfa79e 100644 --- a/app/ui/src/Layout/BotLayout.tsx +++ b/app/ui/src/Layout/BotLayout.tsx @@ -9,49 +9,57 @@ import { PuzzlePieceIcon, EyeDropperIcon, ChatBubbleLeftRightIcon, - //MagnifyingGlassIcon, + MagnifyingGlassIcon, } from "@heroicons/react/24/outline"; import { Link, useParams, useLocation, useNavigate } from "react-router-dom"; import { useAuth } from "../context/AuthContext"; import { Tooltip } from "antd"; import { ApplicationMenu } from "./ApplicationMenu"; +import { useSettings } from "../hooks/useSettings"; const navigation = [ { name: "Playground", href: "/bot/:id", icon: SparklesIcon, + key: "playground", }, - // { - // name: "Search (Beta)", - // href: "/bot/:id/search", - // icon: MagnifyingGlassIcon, - // }, { name: "Data Sources", href: "/bot/:id/data-sources", icon: CircleStackIcon, + key: "data-sources", + }, + { + name: "Search (Beta)", + href: "/bot/:id/search", + icon: MagnifyingGlassIcon, + key: "search", }, { name: "Integrations", href: "/bot/:id/integrations", icon: PuzzlePieceIcon, + key: "integrations", }, { name: "Conversations", href: "/bot/:id/conversations", icon: ChatBubbleLeftRightIcon, + key: "conversations", }, { name: "Appearance", href: "/bot/:id/appearance", icon: EyeDropperIcon, + key: "appearance", }, { name: "Settings", href: "/bot/:id/settings", icon: CogIcon, + key: "settings", }, ]; @@ -75,6 +83,8 @@ export default function BotLayout({ const { isLogged } = useAuth(); + const settings = useSettings(); + React.useEffect(() => { if (!isLogged) { navigate("/login"); @@ -153,33 +163,41 @@ export default function BotLayout({
@@ -223,37 +241,46 @@ export default function BotLayout({
diff --git a/app/ui/src/Layout/BotPlaygroundLayout.tsx b/app/ui/src/Layout/BotPlaygroundLayout.tsx index d02450ed..e1aa93f5 100644 --- a/app/ui/src/Layout/BotPlaygroundLayout.tsx +++ b/app/ui/src/Layout/BotPlaygroundLayout.tsx @@ -9,49 +9,57 @@ import { EyeDropperIcon, SparklesIcon, ChatBubbleLeftRightIcon, - // MagnifyingGlassIcon, + MagnifyingGlassIcon, } from "@heroicons/react/24/outline"; import { Link, useParams, useLocation, useNavigate } from "react-router-dom"; import { useAuth } from "../context/AuthContext"; import { Tooltip } from "antd"; import { ApplicationMenu } from "./ApplicationMenu"; +import { useSettings } from "../hooks/useSettings"; const navigation = [ { name: "Playground", href: "/bot/:id", icon: SparklesIcon, + key: "playground", }, - // { - // name: "Search (Beta)", - // href: "/bot/:id/search", - // icon: MagnifyingGlassIcon, - // }, { name: "Data Sources", href: "/bot/:id/data-sources", icon: CircleStackIcon, + key: "data-sources", + }, + { + name: "Search (Beta)", + href: "/bot/:id/search", + icon: MagnifyingGlassIcon, + key: "search", }, { name: "Integrations", href: "/bot/:id/integrations", icon: PuzzlePieceIcon, + key: "integrations", }, { name: "Conversations", href: "/bot/:id/conversations", icon: ChatBubbleLeftRightIcon, + key: "conversations", }, { name: "Appearance", href: "/bot/:id/appearance", icon: EyeDropperIcon, + key: "appearance", }, { name: "Settings", href: "/bot/:id/settings", icon: CogIcon, + key: "settings", }, ]; @@ -72,6 +80,7 @@ export default function BotPlaygroundLayout({ const navigate = useNavigate(); const { isLogged } = useAuth(); + const settings = useSettings(); React.useEffect(() => { if (!isLogged) { @@ -151,33 +160,42 @@ export default function BotPlaygroundLayout({
@@ -193,34 +211,46 @@ export default function BotPlaygroundLayout({
diff --git a/app/ui/src/components/Bot/Search/index.tsx b/app/ui/src/components/Bot/Search/index.tsx index 5af07084..69cded54 100644 --- a/app/ui/src/components/Bot/Search/index.tsx +++ b/app/ui/src/components/Bot/Search/index.tsx @@ -8,13 +8,15 @@ import { ISearchResult } from "./types"; import { useMutation } from "@tanstack/react-query"; import { notification } from "antd"; import axios from "axios"; +import { useSettings } from "../../../hooks/useSettings"; +import { ExclamationTriangleIcon } from "@heroicons/react/24/outline"; export const BotSearchFeature = () => { const [searchQuery, setSearchQuery] = useState(""); const [defaultSearchBox, setDefaultSearchBox] = useState(true); const params = useParams<{ id: string }>(); const [data, setData] = useState([]); - + const { data: settings, status } = useSettings(); const onSearch = async (query: string) => { const res = await api.post(`/bot/${params.id}/search`, { query, @@ -36,7 +38,17 @@ export const BotSearchFeature = () => { }); }, }); - + if (status === "success" && !settings.internalSearchEnabled) { + return ( +
+ +

+ Internal search needs to be enabled by an admin in order to use this + feature. +

+
+ ); + } return (
diff --git a/app/ui/src/components/Bot/Settings/SettingsBody.tsx b/app/ui/src/components/Bot/Settings/SettingsBody.tsx index 108db2ac..7046cbcf 100644 --- a/app/ui/src/components/Bot/Settings/SettingsBody.tsx +++ b/app/ui/src/components/Bot/Settings/SettingsBody.tsx @@ -284,7 +284,6 @@ export const SettingsBody: React.FC = ({ /> - = ({ > - { const response = await api.get("/user/info"); return response.data as { isRegistrationAllowed: boolean; - + internalSearchEnabled: boolean; }; }, { suspense: true, + placeholderData: { + isRegistrationAllowed: false, + internalSearchEnabled: false, + }, } ); }; diff --git a/app/ui/src/routes/settings/application.tsx b/app/ui/src/routes/settings/application.tsx index f9f0a25f..379da533 100644 --- a/app/ui/src/routes/settings/application.tsx +++ b/app/ui/src/routes/settings/application.tsx @@ -30,6 +30,7 @@ export default function SettingsApplicationRoot() { ollamaURL: string; fileUploadSizeLimit: number; refetchDatasource: boolean; + internalSearchEnabled: boolean; }; }); @@ -184,6 +185,15 @@ export default function SettingsApplicationRoot() { > + + + +