From 04f83eb1e10450baf48aa32569e03545ae33081e Mon Sep 17 00:00:00 2001 From: pablodanswer Date: Wed, 4 Sep 2024 21:26:19 -0700 Subject: [PATCH] Proper popover behavior, no showing queries with no docs, + bubbles (#2330) --- backend/danswer/db/chat.py | 55 ++++++++++++++----- .../server/query_and_chat/query_backend.py | 15 +++-- .../[connector]/AddConnectorPage.tsx | 5 +- .../pages/ConnectorInput/SelectInput.tsx | 3 - web/src/app/assistants/ToolsDisplay.tsx | 4 +- .../sessionSidebar/ChatSessionDisplay.tsx | 9 ++- web/src/components/search/SearchAnswer.tsx | 4 +- web/src/components/search/SearchSection.tsx | 7 +-- 8 files changed, 67 insertions(+), 35 deletions(-) diff --git a/backend/danswer/db/chat.py b/backend/danswer/db/chat.py index 3cb991dd43b..55784025771 100644 --- a/backend/danswer/db/chat.py +++ b/backend/danswer/db/chat.py @@ -3,7 +3,6 @@ from datetime import timedelta from uuid import UUID -from sqlalchemy import and_ from sqlalchemy import delete from sqlalchemy import desc from sqlalchemy import func @@ -87,29 +86,57 @@ def get_chat_sessions_by_slack_thread_id( return db_session.scalars(stmt).all() -def get_first_messages_for_chat_sessions( - chat_session_ids: list[int], db_session: Session +def get_valid_messages_from_query_sessions( + chat_session_ids: list[int], + db_session: Session, ) -> dict[int, str]: - subquery = ( - select(ChatMessage.chat_session_id, func.min(ChatMessage.id).label("min_id")) + user_message_subquery = ( + select( + ChatMessage.chat_session_id, func.min(ChatMessage.id).label("user_msg_id") + ) .where( - and_( - ChatMessage.chat_session_id.in_(chat_session_ids), - ChatMessage.message_type == MessageType.USER, # Select USER messages - ) + ChatMessage.chat_session_id.in_(chat_session_ids), + ChatMessage.message_type == MessageType.USER, + ) + .group_by(ChatMessage.chat_session_id) + .subquery() + ) + + assistant_message_subquery = ( + select( + ChatMessage.chat_session_id, + func.min(ChatMessage.id).label("assistant_msg_id"), + ) + .where( + ChatMessage.chat_session_id.in_(chat_session_ids), + ChatMessage.message_type == MessageType.ASSISTANT, ) .group_by(ChatMessage.chat_session_id) .subquery() ) - query = select(ChatMessage.chat_session_id, ChatMessage.message).join( - subquery, - (ChatMessage.chat_session_id == subquery.c.chat_session_id) - & (ChatMessage.id == subquery.c.min_id), + query = ( + select(ChatMessage.chat_session_id, ChatMessage.message) + .join( + user_message_subquery, + ChatMessage.chat_session_id == user_message_subquery.c.chat_session_id, + ) + .join( + assistant_message_subquery, + ChatMessage.chat_session_id == assistant_message_subquery.c.chat_session_id, + ) + .join( + ChatMessage__SearchDoc, + ChatMessage__SearchDoc.chat_message_id + == assistant_message_subquery.c.assistant_msg_id, + ) + .where(ChatMessage.id == user_message_subquery.c.user_msg_id) ) first_messages = db_session.execute(query).all() - return dict([(row.chat_session_id, row.message) for row in first_messages]) + logger.info(f"Retrieved {len(first_messages)} first messages with documents") + + return {row.chat_session_id: row.message for row in first_messages} def get_chat_sessions_by_user( diff --git a/backend/danswer/server/query_and_chat/query_backend.py b/backend/danswer/server/query_and_chat/query_backend.py index 704b16d5eaa..e20de5a3027 100644 --- a/backend/danswer/server/query_and_chat/query_backend.py +++ b/backend/danswer/server/query_and_chat/query_backend.py @@ -11,8 +11,8 @@ from danswer.db.chat import get_chat_messages_by_session from danswer.db.chat import get_chat_session_by_id from danswer.db.chat import get_chat_sessions_by_user -from danswer.db.chat import get_first_messages_for_chat_sessions from danswer.db.chat import get_search_docs_for_chat_message +from danswer.db.chat import get_valid_messages_from_query_sessions from danswer.db.chat import translate_db_message_to_chat_message_detail from danswer.db.chat import translate_db_search_doc_to_server_search_doc from danswer.db.engine import get_session @@ -142,18 +142,20 @@ def get_user_search_sessions( raise HTTPException( status_code=404, detail="Chat session does not exist or has been deleted" ) - + # Extract IDs from search sessions search_session_ids = [chat.id for chat in search_sessions] - first_messages = get_first_messages_for_chat_sessions( + # Fetch first messages for each session, only including those with documents + sessions_with_documents = get_valid_messages_from_query_sessions( search_session_ids, db_session ) - first_messages_dict = dict(first_messages) + sessions_with_documents_dict = dict(sessions_with_documents) + # Prepare response with detailed information for each valid search session response = ChatSessionsResponse( sessions=[ ChatSessionDetails( id=search.id, - name=first_messages_dict.get(search.id, search.description), + name=sessions_with_documents_dict[search.id], persona_id=search.persona_id, time_created=search.time_created.isoformat(), shared_status=search.shared_status, @@ -161,8 +163,11 @@ def get_user_search_sessions( current_alternate_model=search.current_alternate_model, ) for search in search_sessions + if search.id + in sessions_with_documents_dict # Only include sessions with documents ] ) + return response diff --git a/web/src/app/admin/connectors/[connector]/AddConnectorPage.tsx b/web/src/app/admin/connectors/[connector]/AddConnectorPage.tsx index 3c919e64e31..f6f36f5f1a5 100644 --- a/web/src/app/admin/connectors/[connector]/AddConnectorPage.tsx +++ b/web/src/app/admin/connectors/[connector]/AddConnectorPage.tsx @@ -94,7 +94,9 @@ export default function AddConnector({ is_public: true, ...configuration.values.reduce( (acc, field) => { - if (field.type === "list") { + if (field.type === "select") { + acc[field.name] = field.default || ""; + } else if (field.type === "list") { acc[field.name] = field.default || []; } else if (field.type === "checkbox") { acc[field.name] = field.default || false; @@ -491,7 +493,6 @@ export default function AddConnector({ }} > {(formikProps) => { - console.log(formikProps.values); setFormValues(formikProps.values); handleFormStatusChange( formikProps.isValid && isFormSubmittable(formikProps.values) diff --git a/web/src/app/admin/connectors/[connector]/pages/ConnectorInput/SelectInput.tsx b/web/src/app/admin/connectors/[connector]/pages/ConnectorInput/SelectInput.tsx index e01a02dc323..553bd63abfc 100644 --- a/web/src/app/admin/connectors/[connector]/pages/ConnectorInput/SelectInput.tsx +++ b/web/src/app/admin/connectors/[connector]/pages/ConnectorInput/SelectInput.tsx @@ -5,11 +5,9 @@ import { Field } from "formik"; export default function SelectInput({ field, value, - onChange, }: { field: SelectOption; value: any; - onChange?: (e: Event) => void; }) { return ( <> @@ -27,7 +25,6 @@ export default function SelectInput({ )}
@@ -91,7 +91,7 @@ export function AssistantTools({ border-border w-fit flex - ${hovered ? "bg-background-300" : list ? "bg-background-125" : "bg-background-100"}`} + ${list ? "bg-background-125" : "bg-background-100"}`} >
showDeleteModal(chatSession)} + onClick={(e) => { + e.preventDefault(); + showDeleteModal(chatSession); + }} className={`p-1 -m-1 rounded ml-1`} > @@ -202,7 +205,9 @@ export function ChatSessionDisplay({ ) ) : (
{ + onClick={(e) => { + e.preventDefault(); + // e.stopPropagation(); setIsMoreOptionsDropdownOpen( !isMoreOptionsDropdownOpen ); diff --git a/web/src/components/search/SearchAnswer.tsx b/web/src/components/search/SearchAnswer.tsx index 359879831ec..e8645dfcea0 100644 --- a/web/src/components/search/SearchAnswer.tsx +++ b/web/src/components/search/SearchAnswer.tsx @@ -78,13 +78,13 @@ export default function SearchAnswer({ {searchState == "generating" && (
- Generating response... + Generating Response...
)} {searchState == "citing" && (
- Creating citations... + Extracting Quotes...
)} diff --git a/web/src/components/search/SearchSection.tsx b/web/src/components/search/SearchSection.tsx index 0827cbab7de..c208a9fe11e 100644 --- a/web/src/components/search/SearchSection.tsx +++ b/web/src/components/search/SearchSection.tsx @@ -268,7 +268,7 @@ export const SearchSection = ({ ...(prevState || initialSearchResponse), quotes, })); - setSearchState((searchState) => "input"); + setSearchState((searchState) => "citing"); }; const updateDocs = (documents: SearchDanswerDocument[]) => { @@ -295,7 +295,7 @@ export const SearchSection = ({ })); if (disabledAgentic) { setIsFetching(false); - setSearchState("input"); + setSearchState((searchState) => "citing"); } if (documents.length == 0) { setSearchState("input"); @@ -333,11 +333,8 @@ export const SearchSection = ({ messageId, })); router.refresh(); - // setSearchState("input"); setIsFetching(false); setSearchState((searchState) => "input"); - - // router.replace(`/search?searchId=${chat_session_id}`); }; const updateDocumentRelevance = (relevance: Relevance) => {