From 179dc418e0cf7d7e0bdabffd54acde3692a2188b Mon Sep 17 00:00:00 2001 From: pablodanswer Date: Sun, 27 Oct 2024 11:48:30 -0700 Subject: [PATCH] Onboarding nits (#2907) * temporary stash * welcome flow * minor update * k * minor updates to welcome flow --- .../one_shot_answer/answer_question.py | 14 ++++- web/src/app/assistants/gallery/page.tsx | 2 +- web/src/app/assistants/mine/page.tsx | 6 +- web/src/app/chat/ChatPage.tsx | 4 +- web/src/app/search/page.tsx | 24 ++------ .../chat_search/UnconfiguredProviderText.tsx | 45 ++++++++++----- .../initialSetup/search/NoSourcesModal.tsx | 55 ------------------- .../initialSetup/welcome/WelcomeModal.tsx | 4 ++ web/src/components/llm/ApiKeyModal.tsx | 9 ++- web/src/components/search/SearchSection.tsx | 2 + 10 files changed, 65 insertions(+), 100 deletions(-) delete mode 100644 web/src/components/initialSetup/search/NoSourcesModal.tsx diff --git a/backend/danswer/one_shot_answer/answer_question.py b/backend/danswer/one_shot_answer/answer_question.py index f051da82f14..1bfac570aee 100644 --- a/backend/danswer/one_shot_answer/answer_question.py +++ b/backend/danswer/one_shot_answer/answer_question.py @@ -129,7 +129,19 @@ def stream_answer_objects( persona = temporary_persona if temporary_persona else chat_session.persona - llm, fast_llm = get_llms_for_persona(persona=persona) + try: + llm, fast_llm = get_llms_for_persona(persona=persona) + except ValueError as e: + logger.error( + f"Failed to initialize LLMs for persona '{persona.name}': {str(e)}" + ) + if "No LLM provider" in str(e): + raise ValueError( + "Please configure a Generative AI model to use this feature." + ) from e + raise ValueError( + "Failed to initialize the AI model. Please check your configuration and try again." + ) from e llm_tokenizer = get_tokenizer( model_name=llm.config.model_name, diff --git a/web/src/app/assistants/gallery/page.tsx b/web/src/app/assistants/gallery/page.tsx index 1ae928c598f..fd261fbcae8 100644 --- a/web/src/app/assistants/gallery/page.tsx +++ b/web/src/app/assistants/gallery/page.tsx @@ -24,8 +24,8 @@ export default async function GalleryPage({ chatSessions, folders, openedFolders, - shouldShowWelcomeModal, toggleSidebar, + shouldShowWelcomeModal, } = data; return ( diff --git a/web/src/app/assistants/mine/page.tsx b/web/src/app/assistants/mine/page.tsx index d14de250bae..5761a8c48e5 100644 --- a/web/src/app/assistants/mine/page.tsx +++ b/web/src/app/assistants/mine/page.tsx @@ -1,10 +1,10 @@ import { InstantSSRAutoRefresh } from "@/components/SSRAutoRefresh"; -import { WelcomeModal } from "@/components/initialSetup/welcome/WelcomeModalWrapper"; + import { fetchChatData } from "@/lib/chat/fetchChatData"; import { unstable_noStore as noStore } from "next/cache"; import { redirect } from "next/navigation"; import WrappedAssistantsMine from "./WrappedAssistantsMine"; -import { AssistantsProvider } from "@/components/context/AssistantsContext"; +import { WelcomeModal } from "@/components/initialSetup/welcome/WelcomeModalWrapper"; export default async function GalleryPage({ searchParams, @@ -24,8 +24,8 @@ export default async function GalleryPage({ chatSessions, folders, openedFolders, - shouldShowWelcomeModal, toggleSidebar, + shouldShowWelcomeModal, } = data; return ( diff --git a/web/src/app/chat/ChatPage.tsx b/web/src/app/chat/ChatPage.tsx index e4fcccd9047..056aa181548 100644 --- a/web/src/app/chat/ChatPage.tsx +++ b/web/src/app/chat/ChatPage.tsx @@ -135,7 +135,9 @@ export function ChatPage({ const { assistants: availableAssistants, finalAssistants } = useAssistants(); - const [showApiKeyModal, setShowApiKeyModal] = useState(true); + const [showApiKeyModal, setShowApiKeyModal] = useState( + !shouldShowWelcomeModal + ); const { user, isAdmin, isLoadingUser } = useUser(); diff --git a/web/src/app/search/page.tsx b/web/src/app/search/page.tsx index cfbc72e564b..8bd743fe763 100644 --- a/web/src/app/search/page.tsx +++ b/web/src/app/search/page.tsx @@ -10,16 +10,10 @@ import { CCPairBasicInfo, DocumentSet, Tag, User } from "@/lib/types"; import { cookies } from "next/headers"; import { SearchType } from "@/lib/search/interfaces"; import { Persona } from "../admin/assistants/interfaces"; -import { - WelcomeModal, - hasCompletedWelcomeFlowSS, -} from "@/components/initialSetup/welcome/WelcomeModalWrapper"; import { unstable_noStore as noStore } from "next/cache"; import { InstantSSRAutoRefresh } from "@/components/SSRAutoRefresh"; import { personaComparator } from "../admin/assistants/lib"; import { FullEmbeddingModelResponse } from "@/components/embedding/interfaces"; -import { NoSourcesModal } from "@/components/initialSetup/search/NoSourcesModal"; -import { NoCompleteSourcesModal } from "@/components/initialSetup/search/NoCompleteSourceModal"; import { ChatPopup } from "../chat/ChatPopup"; import { FetchAssistantsResponse, @@ -38,6 +32,10 @@ import { fetchLLMProvidersSS } from "@/lib/llm/fetchLLMs"; import { LLMProviderDescriptor } from "../admin/configuration/llm/interfaces"; import { AssistantsProvider } from "@/components/context/AssistantsContext"; import { headers } from "next/headers"; +import { + hasCompletedWelcomeFlowSS, + WelcomeModal, +} from "@/components/initialSetup/welcome/WelcomeModalWrapper"; export default async function Home({ searchParams, @@ -170,14 +168,6 @@ export default async function Home({ ccPairs.length === 0 && !shouldShowWelcomeModal; - const shouldDisplaySourcesIncompleteModal = - !ccPairs.some( - (ccPair) => ccPair.has_successful_run && ccPair.docs_indexed > 0 - ) && - !shouldDisplayNoSourcesModal && - !shouldShowWelcomeModal && - (!user || user.role == "admin"); - const sidebarToggled = cookies().get(SIDEBAR_TOGGLED_COOKIE_NAME); const agenticSearchToggle = cookies().get(AGENTIC_SEARCH_TYPE_COOKIE_NAME); @@ -192,12 +182,8 @@ export default async function Home({ return ( <> - {shouldShowWelcomeModal && } - {shouldDisplayNoSourcesModal && } - {shouldDisplaySourcesIncompleteModal && ( - - )} + {shouldShowWelcomeModal && } {/* ChatPopup is a custom popup that displays a admin-specified message on initial user visit. Only used in the EE version of the app. */} diff --git a/web/src/components/chat_search/UnconfiguredProviderText.tsx b/web/src/components/chat_search/UnconfiguredProviderText.tsx index e990eecd610..53d65176aa2 100644 --- a/web/src/components/chat_search/UnconfiguredProviderText.tsx +++ b/web/src/components/chat_search/UnconfiguredProviderText.tsx @@ -2,26 +2,41 @@ import { useProviderStatus } from "./ProviderContext"; export default function CredentialNotConfigured({ showConfigureAPIKey, + noSources, }: { showConfigureAPIKey: () => void; + noSources?: boolean; }) { const { shouldShowConfigurationNeeded } = useProviderStatus(); - if (!shouldShowConfigurationNeeded) { - return null; - } - return ( -

- Please note that you have not yet configured an LLM provider. You can - configure one{" "} - - . -

+ <> + {noSources ? ( +

+ You have not yet added any sources. Please add{" "} + + a source + {" "} + to continue. +

+ ) : ( + shouldShowConfigurationNeeded && ( +

+ Please note that you have not yet configured an LLM provider. You + can configure one{" "} + + . +

+ ) + )} + ); } diff --git a/web/src/components/initialSetup/search/NoSourcesModal.tsx b/web/src/components/initialSetup/search/NoSourcesModal.tsx deleted file mode 100644 index b4f6ec004ab..00000000000 --- a/web/src/components/initialSetup/search/NoSourcesModal.tsx +++ /dev/null @@ -1,55 +0,0 @@ -"use client"; - -import { Button, Divider, Text } from "@tremor/react"; -import { Modal } from "../../Modal"; -import Link from "next/link"; -import { FiMessageSquare, FiShare2 } from "react-icons/fi"; -import { useContext, useState } from "react"; -import { SettingsContext } from "@/components/settings/SettingsProvider"; - -export function NoSourcesModal() { - const settings = useContext(SettingsContext); - const [isHidden, setIsHidden] = useState( - !settings?.settings.search_page_enabled - ); - - if (isHidden) { - return null; - } - - return ( - setIsHidden(true)} - > -
-
- - Before using Search you'll need to connect at least one source. - Without any connected knowledge sources, there isn't anything - to search over. - - - - - -
- - Or, if you're looking for a pure ChatGPT-like experience - without any organization specific knowledge, then you can head - over to the Chat page and start chatting with Danswer right away! - - - - -
-
-
-
- ); -} diff --git a/web/src/components/initialSetup/welcome/WelcomeModal.tsx b/web/src/components/initialSetup/welcome/WelcomeModal.tsx index 81496edb8f9..cd3dd8ff268 100644 --- a/web/src/components/initialSetup/welcome/WelcomeModal.tsx +++ b/web/src/components/initialSetup/welcome/WelcomeModal.tsx @@ -58,6 +58,10 @@ export function _WelcomeModal({ user }: { user: User | null }) { {popup} { + setWelcomeFlowComplete(); + router.refresh(); + }} title={"Welcome to Danswer!"} width="w-full max-h-[900px] overflow-y-scroll max-w-3xl" > diff --git a/web/src/components/llm/ApiKeyModal.tsx b/web/src/components/llm/ApiKeyModal.tsx index d401036e493..775c6ac9cd5 100644 --- a/web/src/components/llm/ApiKeyModal.tsx +++ b/web/src/components/llm/ApiKeyModal.tsx @@ -26,18 +26,17 @@ export const ApiKeyModal = ({ } return ( hide()} > <>
- Please provide an API Key below in order to start using Danswer – you - can always change this later. + Please provide an API Key – you can always change this or switch + models later.
- If you'd rather look around first, you can + If you would rather look around first, you can{" "} hide()} className="text-link cursor-pointer"> - {" "} skip this step . diff --git a/web/src/components/search/SearchSection.tsx b/web/src/components/search/SearchSection.tsx index 9f49e4715cf..66b5cb481ed 100644 --- a/web/src/components/search/SearchSection.tsx +++ b/web/src/components/search/SearchSection.tsx @@ -44,6 +44,7 @@ import UnconfiguredProviderText from "../chat_search/UnconfiguredProviderText"; import { DateRangePickerValue } from "@tremor/react"; import { Tag } from "@/lib/types"; import { isEqual } from "lodash"; +import { WelcomeModal } from "../initialSetup/welcome/WelcomeModalWrapper"; export type searchState = | "input" @@ -783,6 +784,7 @@ export const SearchSection = ({
setShowApiKeyModal(true)} />