+ {/* The Question */}
+
+ {humanText}
+
+
+ {/* Main answer container */}
+
+
+
Agentic Search
+
- {docs && docs.length > 0 && (
-
-
-
- {!settings?.isMobile &&
- docs.length > 0 &&
- docs
- .slice(0, 2)
- .map((doc, ind) => (
-
- ))}
-
+ {/* Getting context section */}
+
+
+ Getting context on typical sales processes
+
+
+
- )}
-
- {content || files ? (
- <>
-
-
- {typeof content === "string" ? (
-
- {renderedMarkdown}
-
- ) : (
- content
- )}
- >
- ) : isComplete ? null : (
- <>>
- )}
+
+ {[
+ "Sales training materials",
+ "Sales playbook",
+ "Customer Journey",
+ ].map((item, index) => (
+
+ {item}
+
+ ))}
+
+
+
+
Reading
+
+ {[
+ "2024 sales process onboarding guide",
+ "2024 onyx sales playbook",
+ "Ramp customer journey record",
+ ].map((item, index) => (
+
+ {item}
+
+ ))}
+
+
- {handleFeedback &&
- (isActive ? (
-
-
-
- {includeMessageSwitcher && (
-
- {
- onMessageSelection(
- otherMessagesCanSwitchTo[
- currentMessageInd - 1
- ]
- );
- }}
- handleNext={() => {
- onMessageSelection(
- otherMessagesCanSwitchTo[
- currentMessageInd + 1
- ]
- );
- }}
- />
-
- )}
-
-
-
-
-
- }
- onClick={() => handleFeedback("like")}
- />
-
-
- }
- onClick={() => handleFeedback("dislike")}
- />
-
- {regenerate && (
-
-
-
- )}
-
+ {/* Ramp difference section */}
+
+
+ What was done differently at Ramp
+
+
+
Searching
+
+ {[
+ "Ramp sales calls",
+ "Ramp deal sales email exchanges",
+ "Ramp win/loss analysis",
+ ].map((item, index) => (
+
+ {item}
+
+ ))}
- ) : (
-
-
-
- {includeMessageSwitcher && (
-
- {
- onMessageSelection(
- otherMessagesCanSwitchTo[
- currentMessageInd - 1
- ]
- );
- }}
- handleNext={() => {
- onMessageSelection(
- otherMessagesCanSwitchTo[
- currentMessageInd + 1
- ]
- );
- }}
- />
-
- )}
-
-
-
-
-
-
- }
- onClick={() => handleFeedback("like")}
- />
-
-
-
- }
- onClick={() => handleFeedback("dislike")}
- />
-
- {regenerate && (
-
-
-
- )}
-
+
+
+
Reading
+
+ {[
+ "Sales call with Ramp 2024/5/15",
+ "Sales call with Ramp 2024/4/16",
+ "Sales call with Ramp 2024/3/12",
+ "Ramp:Onyx Regarding the deal terms",
+ "Ramp:Onyx deal progress tracker",
+ ].map((item, index) => (
+
+ {item}
+
+ ))}
- ))}
+
+
+
+
+
+ {/* Sources */}
+
+
Sources
+
+ {[
+ {
+ text: "a new in-app support experience for Ramp (recently rolled out to 50% of",
+ source: "Business Overview meeting",
+ },
+ {
+ text: "Danswer Updates!!! Shiny New Things for Ramp! General Improvements APIs for Ramp use",
+ source: "Ramp (April)",
+ },
+ {
+ text: "Existing solutions are so expensive that this isn't feasible. * Today's solutions don't meet those",
+ source: "Sales Pitch Deck Thoughts",
+ },
+ {
+ text: "Show All",
+ source: "",
+ },
+ ].map((item, index) => (
+
+
{item.text}
+ {item.source && (
+
+ )}
+
+ ))}
+
+ {/* Conclusion */}
+
+
+
+
+
+
Onyx
+
+
+ To win the deal at Ramp, the team made the product really easy
+ to access. After a successful demo...
+
+
- {(!toolCall || toolCall.tool_name === SEARCH_TOOL_NAME) &&
- !query &&
- continueGenerating && (
-
- )}
);
};
+// export const AIMessage = ({
+// regenerate,
+// overriddenModel,
+// selectedMessageForDocDisplay,
+// continueGenerating,
+// shared,
+// isActive,
+// toggleDocumentSelection,
+// alternativeAssistant,
+// docs,
+// messageId,
+// documentSelectionToggled,
+// content,
+// files,
+// selectedDocuments,
+// query,
+// citedDocuments,
+// toolCall,
+// isComplete,
+// hasDocs,
+// handleFeedback,
+// handleShowRetrieved,
+// handleSearchQueryEdit,
+// handleForceSearch,
+// retrievalDisabled,
+// currentPersona,
+// otherMessagesCanSwitchTo,
+// onMessageSelection,
+// setPresentingDocument,
+// index,
+// }: {
+// index?: number;
+// selectedMessageForDocDisplay?: number | null;
+// shared?: boolean;
+// isActive?: boolean;
+// continueGenerating?: () => void;
+// otherMessagesCanSwitchTo?: number[];
+// onMessageSelection?: (messageId: number) => void;
+// selectedDocuments?: DanswerDocument[] | null;
+// toggleDocumentSelection?: () => void;
+// docs?: DanswerDocument[] | null;
+// alternativeAssistant?: Persona | null;
+// currentPersona: Persona;
+// messageId: number | null;
+// content: string | JSX.Element;
+// documentSelectionToggled?: boolean;
+// files?: FileDescriptor[];
+// query?: string;
+// citedDocuments?: [string, DanswerDocument][] | null;
+// toolCall?: ToolCallMetadata | null;
+// isComplete?: boolean;
+// hasDocs?: boolean;
+// handleFeedback?: (feedbackType: FeedbackType) => void;
+// handleShowRetrieved?: (messageNumber: number | null) => void;
+// handleSearchQueryEdit?: (query: string) => void;
+// handleForceSearch?: () => void;
+// retrievalDisabled?: boolean;
+// overriddenModel?: string;
+// regenerate?: (modelOverRide: LlmOverride) => Promise
;
+// setPresentingDocument?: (document: DanswerDocument) => void;
+// }) => {
+// const toolCallGenerating = toolCall && !toolCall.tool_result;
+// const processContent = (content: string | JSX.Element) => {
+// if (typeof content !== "string") {
+// return content;
+// }
+
+// const codeBlockRegex = /```(\w*)\n[\s\S]*?```|```[\s\S]*?$/g;
+// const matches = content.match(codeBlockRegex);
+
+// if (matches) {
+// content = matches.reduce((acc, match) => {
+// if (!match.match(/```\w+/)) {
+// return acc.replace(match, match.replace("```", "```plaintext"));
+// }
+// return acc;
+// }, content);
+
+// const lastMatch = matches[matches.length - 1];
+// if (!lastMatch.endsWith("```")) {
+// return content;
+// }
+// }
+
+// return content + (!isComplete && !toolCallGenerating ? " [*]() " : "");
+// };
+// const finalContent = processContent(content as string);
+
+// const [isRegenerateHovered, setIsRegenerateHovered] = useState(false);
+// const [isRegenerateDropdownVisible, setIsRegenerateDropdownVisible] =
+// useState(false);
+// const { isHovering, trackedElementRef, hoverElementRef } = useMouseTracking();
+
+// const settings = useContext(SettingsContext);
+// // this is needed to give Prism a chance to load
+
+// const selectedDocumentIds =
+// selectedDocuments?.map((document) => document.document_id) || [];
+// const citedDocumentIds: string[] = [];
+
+// citedDocuments?.forEach((doc) => {
+// citedDocumentIds.push(doc[1].document_id);
+// });
+
+// if (!isComplete) {
+// const trimIncompleteCodeSection = (
+// content: string | JSX.Element
+// ): string | JSX.Element => {
+// if (typeof content === "string") {
+// const pattern = /```[a-zA-Z]+[^\s]*$/;
+// const match = content.match(pattern);
+// if (match && match.index && match.index > 3) {
+// const newContent = content.slice(0, match.index - 3);
+// return newContent;
+// }
+// return content;
+// }
+// return content;
+// };
+// content = trimIncompleteCodeSection(content);
+// }
+
+// let filteredDocs: FilteredDanswerDocument[] = [];
+
+// if (docs) {
+// filteredDocs = docs
+// .filter(
+// (doc, index, self) =>
+// doc.document_id &&
+// doc.document_id !== "" &&
+// index === self.findIndex((d) => d.document_id === doc.document_id)
+// )
+// .filter((doc) => {
+// return citedDocumentIds.includes(doc.document_id);
+// })
+// .map((doc: DanswerDocument, ind: number) => {
+// return {
+// ...doc,
+// included: selectedDocumentIds.includes(doc.document_id),
+// };
+// });
+// }
+
+// const paragraphCallback = useCallback(
+// (props: any) => {props.children},
+// []
+// );
+
+// const anchorCallback = useCallback(
+// (props: any) => (
+//
+// {props.children}
+//
+// ),
+// [docs]
+// );
+
+// const currentMessageInd = messageId
+// ? otherMessagesCanSwitchTo?.indexOf(messageId)
+// : undefined;
+
+// const uniqueSources: ValidSources[] = Array.from(
+// new Set((docs || []).map((doc) => doc.source_type))
+// ).slice(0, 3);
+
+// const markdownComponents = useMemo(
+// () => ({
+// a: anchorCallback,
+// p: paragraphCallback,
+// code: ({ node, className, children }: any) => {
+// const codeText = extractCodeText(
+// node,
+// finalContent as string,
+// children
+// );
+
+// return (
+//
+// {children}
+//
+// );
+// },
+// }),
+// [anchorCallback, paragraphCallback, finalContent]
+// );
+
+// const renderedMarkdown = useMemo(() => {
+// return (
+//
+// {finalContent as string}
+//
+// );
+// }, [finalContent, markdownComponents]);
+
+// const includeMessageSwitcher =
+// currentMessageInd !== undefined &&
+// onMessageSelection &&
+// otherMessagesCanSwitchTo &&
+// otherMessagesCanSwitchTo.length > 1;
+// return (
+//
+//
+//
+//
+//
+
+//
+//
+//
+//
+// {!toolCall || toolCall.tool_name === SEARCH_TOOL_NAME ? (
+// <>
+// {query !== undefined &&
+// handleShowRetrieved !== undefined &&
+// !retrievalDisabled && (
+//
+//
+//
+// )}
+// {handleForceSearch &&
+// content &&
+// query === undefined &&
+// !hasDocs &&
+// !retrievalDisabled && (
+//
+//
+//
+// )}
+// >
+// ) : null}
+
+// {toolCall &&
+// !TOOLS_WITH_CUSTOM_HANDLING.includes(
+// toolCall.tool_name
+// ) && (
+//
+// }
+// isRunning={!toolCall.tool_result || !content}
+// />
+// )}
+
+// {toolCall &&
+// (!files || files.length == 0) &&
+// toolCall.tool_name === IMAGE_GENERATION_TOOL_NAME &&
+// !toolCall.tool_result &&
}
+
+// {toolCall &&
+// toolCall.tool_name === INTERNET_SEARCH_TOOL_NAME && (
+//
+// }
+// isRunning={!toolCall.tool_result}
+// />
+// )}
+
+// {docs && docs.length > 0 && (
+//
+//
+//
+// {!settings?.isMobile &&
+// docs.length > 0 &&
+// docs
+// .slice(0, 2)
+// .map((doc, ind) => (
+//
+// ))}
+//
+//
+//
+//
+// )}
+
+// {content || files ? (
+// <>
+//
+
+// {typeof content === "string" ? (
+//
+// {renderedMarkdown}
+//
+// ) : (
+// content
+// )}
+// >
+// ) : isComplete ? null : (
+// <>>
+// )}
+//
+
+// {handleFeedback &&
+// (isActive ? (
+//
+//
+//
+// {includeMessageSwitcher && (
+//
+// {
+// onMessageSelection(
+// otherMessagesCanSwitchTo[
+// currentMessageInd - 1
+// ]
+// );
+// }}
+// handleNext={() => {
+// onMessageSelection(
+// otherMessagesCanSwitchTo[
+// currentMessageInd + 1
+// ]
+// );
+// }}
+// />
+//
+// )}
+//
+//
+//
+//
+//
+// }
+// onClick={() => handleFeedback("like")}
+// />
+//
+//
+// }
+// onClick={() => handleFeedback("dislike")}
+// />
+//
+// {regenerate && (
+//
+//
+//
+// )}
+//
+//
+// ) : (
+//
+//
+//
+// {includeMessageSwitcher && (
+//
+// {
+// onMessageSelection(
+// otherMessagesCanSwitchTo[
+// currentMessageInd - 1
+// ]
+// );
+// }}
+// handleNext={() => {
+// onMessageSelection(
+// otherMessagesCanSwitchTo[
+// currentMessageInd + 1
+// ]
+// );
+// }}
+// />
+//
+// )}
+//
+//
+//
+//
+
+//
+// }
+// onClick={() => handleFeedback("like")}
+// />
+//
+
+//
+// }
+// onClick={() => handleFeedback("dislike")}
+// />
+//
+// {regenerate && (
+//
+//
+//
+// )}
+//
+//
+// ))}
+//
+//
+//
+//
+//
+// {(!toolCall || toolCall.tool_name === SEARCH_TOOL_NAME) &&
+// !query &&
+// continueGenerating && (
+//
+// )}
+//
+//
+// );
+// };
+
function MessageSwitcher({
currentPage,
totalPages,
diff --git a/web/src/app/chat/sessionSidebar/ChatSessionDisplay.tsx b/web/src/app/chat/sessionSidebar/ChatSessionDisplay.tsx
index 96eaa7e2edd..fe007d5bf5a 100644
--- a/web/src/app/chat/sessionSidebar/ChatSessionDisplay.tsx
+++ b/web/src/app/chat/sessionSidebar/ChatSessionDisplay.tsx
@@ -4,7 +4,6 @@ import { useRouter } from "next/navigation";
import { ChatSession } from "../interfaces";
import { useState, useEffect, useContext } from "react";
import { getChatRetentionInfo, renameChatSession } from "../lib";
-import { BasicSelectable } from "@/components/BasicClickable";
import Link from "next/link";
import {
FiCheck,
@@ -34,8 +33,6 @@ export function ChatSessionDisplay({
chatSession: ChatSession;
isSelected: boolean;
search?: boolean;
- // needed when the parent is trying to apply some background effect
- // if not set, the gradient will still be applied and cause weirdness
skipGradient?: boolean;
closeSidebar?: () => void;
showShareModal?: (chatSession: ChatSession) => void;
@@ -73,7 +70,7 @@ export function ChatSessionDisplay({
};
if (!settings) {
- return <>>;
+ return null;
}
const { daysUntilExpiration, showRetentionWarning } = getChatRetentionInfo(
@@ -92,7 +89,11 @@ export function ChatSessionDisplay({
)}
setIsHovering(true)}
onMouseLeave={() => {
@@ -122,147 +123,135 @@ export function ChatSessionDisplay({
);
}}
>
-
- <>
-
+
+ {isRenamingChat ? (
+
setChatName(e.target.value)}
+ onKeyDown={(event) => {
+ if (event.key === "Enter") {
+ onRename();
+ event.preventDefault();
+ }
+ }}
+ className="px-1 mr-1 w-full rounded text-base font-normal leading-normal text-black border border-[#dcdad4]"
+ />
+ ) : (
+
+ {chatName || `Chat ${chatSession.id}`}
+
+ )}
+
+ {isHovering && (
+
{isRenamingChat ? (
-
setChatName(e.target.value)}
- onKeyDown={(event) => {
- if (event.key === "Enter") {
- onRename();
- event.preventDefault();
- }
- }}
- className="-my-px px-1 mr-1 w-full rounded"
- />
+ <>
+
+
+
+
{
+ setChatName(chatSession.name);
+ setIsRenamingChat(false);
+ }}
+ className="hover:bg-black/10 p-1 rounded ml-2 cursor-pointer"
+ >
+
+
+ >
) : (
-
- {chatName || `Chat ${chatSession.id}`}
-
-
- )}
-
- {isHovering &&
- (isRenamingChat ? (
-
-
+ {!showShareModal && showRetentionWarning && (
+
+ This chat will expire{" "}
+ {daysUntilExpiration < 1
+ ? "today"
+ : `in ${daysUntilExpiration} day${
+ daysUntilExpiration !== 1 ? "s" : ""
+ }`}
+
+ }
>
-
-
+
+
+
+
+ )}
+
+ {search ? (
+ showDeleteModal && (
+
{
+ e.preventDefault();
+ showDeleteModal(chatSession);
+ }}
+ className="p-1 rounded ml-1 cursor-pointer hover:bg-black/10"
+ >
+
+
+ )
+ ) : (
{
- setChatName(chatSession.name);
- setIsRenamingChat(false);
+ onClick={(e) => {
+ e.preventDefault();
+ setIsMoreOptionsDropdownOpen(
+ !isMoreOptionsDropdownOpen
+ );
}}
- className={`hover:bg-black/10 p-1 -m-1 rounded ml-2`}
+ className="-my-1 cursor-pointer"
>
-
-
-
- ) : (
-
- {!showShareModal && showRetentionWarning && (
-
+ setIsMoreOptionsDropdownOpen(open)
+ }
content={
-
- This chat will expire{" "}
- {daysUntilExpiration < 1
- ? "today"
- : `in ${daysUntilExpiration} day${
- daysUntilExpiration !== 1 ? "s" : ""
- }`}
-
+
+
+
}
- >
-
-
-
-
- )}
-
- {search ? (
- showDeleteModal && (
-
{
- e.preventDefault();
- showDeleteModal(chatSession);
- }}
- className={`p-1 -m-1 rounded ml-1`}
- >
-
+ popover={
+
+ {showShareModal && (
+ showShareModal(chatSession)}
+ />
+ )}
+ {!search && (
+ setIsRenamingChat(true)}
+ />
+ )}
+ {showDeleteModal && (
+ showDeleteModal(chatSession)}
+ />
+ )}
- )
- ) : (
-
{
- e.preventDefault();
- setIsMoreOptionsDropdownOpen(
- !isMoreOptionsDropdownOpen
- );
- }}
- className="-my-1"
- >
-
- setIsMoreOptionsDropdownOpen(open)
- }
- content={
-
-
-
- }
- popover={
-
- {showShareModal && (
- showShareModal(chatSession)}
- />
- )}
- {!search && (
- setIsRenamingChat(true)}
- />
- )}
- {showDeleteModal && (
-
- showDeleteModal(chatSession)
- }
- />
- )}
-
- }
- requiresContentPadding
- sideOffset={6}
- triggerMaxWidth
- />
-
- )}
+ }
+ requiresContentPadding
+ sideOffset={6}
+ triggerMaxWidth
+ />
-
- ))}
+ )}
+ >
+ )}
- >
-
+ )}
+
>
);
diff --git a/web/src/app/chat/sessionSidebar/HistorySidebar.tsx b/web/src/app/chat/sessionSidebar/HistorySidebar.tsx
index 88002ee005a..87fdbe53291 100644
--- a/web/src/app/chat/sessionSidebar/HistorySidebar.tsx
+++ b/web/src/app/chat/sessionSidebar/HistorySidebar.tsx
@@ -10,7 +10,6 @@ import { Folder } from "../folders/interfaces";
import { createFolder } from "../folders/FolderManagement";
import { usePopup } from "@/components/admin/connectors/Popup";
import { SettingsContext } from "@/components/settings/SettingsProvider";
-
import {
AssistantsIconSkeleton,
ClosedBookIcon,
@@ -58,19 +57,10 @@ export const HistorySidebar = forwardRef
(
) => {
const router = useRouter();
const { popup, setPopup } = usePopup();
-
- // For determining intial focus state
const [newFolderId, setNewFolderId] = useState(null);
-
const currentChatId = currentChatSession?.id;
-
- // NOTE: do not do something like the below - assume that the parent
- // will handle properly refreshing the existingChats
- // useEffect(() => {
- // router.refresh();
- // }, [currentChatId]);
-
const combinedSettings = useContext(SettingsContext);
+
if (!combinedSettings) {
return null;
}
@@ -91,17 +81,14 @@ export const HistorySidebar = forwardRef(
(
page={page}
toggleSidebar={toggleSidebar}
explicitlyUntoggle={explicitlyUntoggle}
+ // Customize LogoType if needed to match final design
/>
- {page == "chat" && (
-
+
+ {page === "chat" && (
+
{
- if (e.metaKey || e.ctrlKey) {
- return;
- }
- if (handleNewChat) {
- handleNewChat();
- }
+ if (e.metaKey || e.ctrlKey) return;
+ handleNewChat();
}}
>
-
-
New Chat
+
+
New Chat
-
-
+
+
Manage Assistants
-
-
+
+
Manage Prompts
)}
-
+
+
+
(false);
@@ -43,14 +42,14 @@ export function PagesTab({
event: React.DragEvent
) => {
event.preventDefault();
- setIsDragOver(false); // Reset drag over state on drop
+ setIsDragOver(false);
const chatSessionId = event.dataTransfer.getData(CHAT_SESSION_ID_KEY);
const folderId = event.dataTransfer.getData(FOLDER_ID_KEY);
if (folderId) {
try {
await removeChatFromFolder(parseInt(folderId, 10), chatSessionId);
- router.refresh(); // Refresh the page to reflect the changes
+ router.refresh();
} catch (error) {
setPopup({
message: "Failed to remove chat from folder",
@@ -63,10 +62,13 @@ export function PagesTab({
const isHistoryEmpty = !existingChats || existingChats.length === 0;
return (
-
+
{folders && folders.length > 0 && (
-
-
+
)}
+
{
event.preventDefault();
@@ -86,19 +89,17 @@ export function PagesTab({
}}
onDragLeave={() => setIsDragOver(false)}
onDrop={handleDropToRemoveFromFolder}
- className={`pt-1 transition duration-300 ease-in-out mr-3 ${
- isDragOver ? "bg-hover" : ""
- } rounded-md`}
+ className={`pt-3 pb-40 transition duration-300 ease-in-out ${
+ isDragOver ? "bg-[#e6e3dd] rounded-md" : ""
+ }`}
>
- {(page == "chat" || page == "search") && (
-
- {page == "chat" && "Chat "}
- {page == "search" && "Search "}
- History
+ {(page === "chat" || page === "search") && (
+
+ {page === "chat" ? "Chat History" : "Search History"}
)}
{isHistoryEmpty ? (
-
+
{page === "search"
? "Try running a search! Your search history will appear here."
: "Try sending a message! Your chat history will appear here."}
@@ -106,34 +107,31 @@ export function PagesTab({
) : (
Object.entries(groupedChatSessions).map(
([dateRange, chatSessions], ind) => {
- if (chatSessions.length > 0) {
+ const filteredSessions = chatSessions.filter(
+ (chat) => chat.folder_id === null
+ );
+ if (filteredSessions.length > 0) {
return (
-
-
+
+
{dateRange}
- {chatSessions
- .filter((chat) => chat.folder_id === null)
- .map((chat) => {
- const isSelected = currentChatId === chat.id;
- return (
-
-
-
- );
- })}
+ {filteredSessions.map((chat) => {
+ const isSelected = currentChatId === chat.id;
+ return (
+
+
+
+ );
+ })}
);
}
diff --git a/web/src/app/chat/shared_chat_search/FunctionalWrapper.tsx b/web/src/app/chat/shared_chat_search/FunctionalWrapper.tsx
index 8a58c639136..f10457733c1 100644
--- a/web/src/app/chat/shared_chat_search/FunctionalWrapper.tsx
+++ b/web/src/app/chat/shared_chat_search/FunctionalWrapper.tsx
@@ -57,7 +57,7 @@ export default function FunctionalWrapper({
return (
<>
{" "}
-
+
{content(toggledSidebar, toggle)}
>