mirror of
https://github.com/danswer-ai/danswer.git
synced 2025-09-27 12:29:41 +02:00
Proper popover behavior, no showing queries with no docs, + bubbles (#2330)
This commit is contained in:
@@ -3,7 +3,6 @@ from datetime import datetime
|
||||
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()
|
||||
)
|
||||
|
||||
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),
|
||||
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(
|
||||
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(
|
||||
|
@@ -11,8 +11,8 @@ from danswer.configs.constants import MessageType
|
||||
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
|
||||
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -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({
|
||||
)}
|
||||
|
||||
<Field
|
||||
onChange={onChange}
|
||||
as="select"
|
||||
value={value}
|
||||
name={field.name}
|
||||
|
@@ -71,7 +71,7 @@ export function AssistantTools({
|
||||
w-fit
|
||||
flex
|
||||
items-center
|
||||
${hovered ? "bg-background-300" : list ? "bg-background-125" : "bg-background-100"}`}
|
||||
${list ? "bg-background-125" : "bg-background-100"}`}
|
||||
>
|
||||
<div className="flex gap-x-1">
|
||||
<FiSearch key={ind} className="ml-1 h-3 w-3 my-auto" />
|
||||
@@ -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"}`}
|
||||
>
|
||||
<div className="flex items-center gap-x-1">
|
||||
<FiImage
|
||||
|
@@ -194,7 +194,10 @@ export function ChatSessionDisplay({
|
||||
{search ? (
|
||||
showDeleteModal && (
|
||||
<div
|
||||
onClick={() => showDeleteModal(chatSession)}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
showDeleteModal(chatSession);
|
||||
}}
|
||||
className={`p-1 -m-1 rounded ml-1`}
|
||||
>
|
||||
<FiTrash size={16} />
|
||||
@@ -202,7 +205,9 @@ export function ChatSessionDisplay({
|
||||
)
|
||||
) : (
|
||||
<div
|
||||
onClick={() => {
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
// e.stopPropagation();
|
||||
setIsMoreOptionsDropdownOpen(
|
||||
!isMoreOptionsDropdownOpen
|
||||
);
|
||||
|
@@ -78,13 +78,13 @@ export default function SearchAnswer({
|
||||
|
||||
{searchState == "generating" && (
|
||||
<div key={"generating"} className="relative inline-block">
|
||||
<span className="loading-text">Generating response...</span>
|
||||
<span className="loading-text">Generating Response...</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{searchState == "citing" && (
|
||||
<div key={"citing"} className="relative inline-block">
|
||||
<span className="loading-text">Creating citations...</span>
|
||||
<span className="loading-text">Extracting Quotes...</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
@@ -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) => {
|
||||
|
Reference in New Issue
Block a user