Skip to content

Commit

Permalink
Update citations in shared chat display (#3487)
Browse files Browse the repository at this point in the history
* update shared chat display

* Change Copy

* fix icon

* remove secret!

---------

Co-authored-by: Yuhong Sun <[email protected]>
  • Loading branch information
pablonyx and yuhongsun96 authored Dec 20, 2024
1 parent 59c7743 commit 9011b8a
Show file tree
Hide file tree
Showing 17 changed files with 345 additions and 127 deletions.
11 changes: 7 additions & 4 deletions backend/onyx/server/query_and_chat/chat_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,12 +182,15 @@ def get_chat_session(
description=chat_session.description,
persona_id=chat_session.persona_id,
persona_name=chat_session.persona.name if chat_session.persona else None,
persona_icon_color=chat_session.persona.icon_color
if chat_session.persona
else None,
persona_icon_shape=chat_session.persona.icon_shape
if chat_session.persona
else None,
current_alternate_model=chat_session.current_alternate_model,
messages=[
translate_db_message_to_chat_message_detail(
msg, remove_doc_content=is_shared # if shared, don't leak doc content
)
for msg in session_messages
translate_db_message_to_chat_message_detail(msg) for msg in session_messages
],
time_created=chat_session.time_created,
shared_status=chat_session.shared_status,
Expand Down
2 changes: 2 additions & 0 deletions backend/onyx/server/query_and_chat/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,8 @@ class ChatSessionDetailResponse(BaseModel):
description: str | None
persona_id: int | None = None
persona_name: str | None
persona_icon_color: str | None
persona_icon_shape: int | None
messages: list[ChatMessageDetail]
time_created: datetime
shared_status: ChatSessionSharedStatus
Expand Down
1 change: 1 addition & 0 deletions web/src/app/chat/ChatPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2105,6 +2105,7 @@ export function ChatPage({
}
/>
)}

{sharingModalVisible && chatSessionIdRef.current !== null && (
<ShareChatSessionModal
message={message}
Expand Down
8 changes: 6 additions & 2 deletions web/src/app/chat/documentSidebar/ChatDocumentDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ interface DocumentDisplayProps {
isSelected: boolean;
handleSelect: (documentId: string) => void;
tokenLimitReached: boolean;
hideSelection?: boolean;
setPresentingDocument: Dispatch<SetStateAction<OnyxDocument | null>>;
}

Expand Down Expand Up @@ -62,6 +63,7 @@ export function ChatDocumentDisplay({
closeSidebar,
document,
modal,
hideSelection,
isSelected,
handleSelect,
tokenLimitReached,
Expand All @@ -76,7 +78,9 @@ export function ChatDocumentDisplay({
const hasMetadata =
document.updated_at || Object.keys(document.metadata).length > 0;
return (
<div className={`opacity-100 ${modal ? "w-[90vw]" : "w-full"}`}>
<div
className={`max-w-[400px] opacity-100 ${modal ? "w-[90vw]" : "w-full"}`}
>
<div
className={`flex relative flex-col gap-0.5 rounded-xl mx-2 my-1 ${
isSelected ? "bg-gray-200" : "hover:bg-background-125"
Expand Down Expand Up @@ -115,7 +119,7 @@ export function ChatDocumentDisplay({
)}
</div>
<div className="absolute top-2 right-2">
{!isInternet && (
{!isInternet && !hideSelection && (
<DocumentSelector
isSelected={isSelected}
handleSelect={() => handleSelect(document.document_id)}
Expand Down
10 changes: 7 additions & 3 deletions web/src/app/chat/documentSidebar/ChatFilters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { SourceSelector } from "../shared_chat_search/SearchFilters";
import { XIcon } from "@/components/icons/icons";

interface ChatFiltersProps {
filterManager: FilterManager;
filterManager?: FilterManager;
closeSidebar: () => void;
selectedMessage: Message | null;
selectedDocuments: OnyxDocument[] | null;
Expand All @@ -27,6 +27,7 @@ interface ChatFiltersProps {
maxTokens: number;
initialWidth: number;
isOpen: boolean;
isSharedChat?: boolean;
modal: boolean;
ccPairs: CCPairBasicInfo[];
tags: Tag[];
Expand All @@ -48,6 +49,7 @@ export const ChatFilters = forwardRef<HTMLDivElement, ChatFiltersProps>(
selectedDocumentTokens,
maxTokens,
initialWidth,
isSharedChat,
isOpen,
ccPairs,
tags,
Expand Down Expand Up @@ -79,13 +81,14 @@ export const ChatFilters = forwardRef<HTMLDivElement, ChatFiltersProps>(
const dedupedDocuments = removeDuplicateDocs(currentDocuments || []);

const tokenLimitReached = selectedDocumentTokens > maxTokens - 75;
console.log("SELECTED MESSAGE is", selectedMessage);

const hasSelectedDocuments = selectedDocumentIds.length > 0;

return (
<div
id="onyx-chat-sidebar"
className={`relative max-w-full ${
className={`relative bg-background max-w-full ${
!modal ? "border-l h-full border-sidebar-border" : ""
}`}
onClick={(e) => {
Expand Down Expand Up @@ -122,10 +125,10 @@ export const ChatFilters = forwardRef<HTMLDivElement, ChatFiltersProps>(
<div className="overflow-y-auto -mx-1 sm:mx-0 flex-grow gap-y-0 default-scrollbar dark-scrollbar flex flex-col">
{showFilters ? (
<SourceSelector
{...filterManager!}
modal={modal}
tagsOnLeft={true}
filtersUntoggled={false}
{...filterManager}
availableDocumentSets={documentSets}
existingSources={ccPairs.map((ccPair) => ccPair.source)}
availableTags={tags}
Expand Down Expand Up @@ -157,6 +160,7 @@ export const ChatFilters = forwardRef<HTMLDivElement, ChatFiltersProps>(
)!
);
}}
hideSelection={isSharedChat}
tokenLimitReached={tokenLimitReached}
/>
</div>
Expand Down
2 changes: 2 additions & 0 deletions web/src/app/chat/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ export interface BackendChatSession {
description: string;
persona_id: number;
persona_name: string;
persona_icon_color: string | null;
persona_icon_shape: number | null;
messages: BackendMessage[];
time_created: string;
shared_status: ChatSessionSharedStatus;
Expand Down
20 changes: 15 additions & 5 deletions web/src/app/chat/message/MemoizedTextComponents.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Citation } from "@/components/search/results/Citation";
import { WebResultIcon } from "@/components/WebResultIcon";
import { LoadedOnyxDocument } from "@/lib/search/interfaces";
import { LoadedOnyxDocument, OnyxDocument } from "@/lib/search/interfaces";
import { getSourceMetadata, SOURCE_METADATA_MAP } from "@/lib/sources";
import { ValidSources } from "@/lib/types";
import React, { memo } from "react";
Expand All @@ -9,7 +9,15 @@ import { SlackIcon } from "@/components/icons/icons";
import { SourceIcon } from "@/components/SourceIcon";

export const MemoizedAnchor = memo(
({ docs, updatePresentingDocument, children }: any) => {
({
docs,
updatePresentingDocument,
children,
}: {
docs?: OnyxDocument[] | null;
updatePresentingDocument: (doc: OnyxDocument) => void;
children: React.ReactNode;
}) => {
const value = children?.toString();
if (value?.startsWith("[") && value?.endsWith("]")) {
const match = value.match(/\[(\d+)\]/);
Expand All @@ -21,9 +29,11 @@ export const MemoizedAnchor = memo(
? new URL(associatedDoc.link).origin + "/favicon.ico"
: "";

const icon = (
<SourceIcon sourceType={associatedDoc?.source_type} iconSize={18} />
);
const icon =
(associatedDoc && (
<SourceIcon sourceType={associatedDoc?.source_type} iconSize={18} />
)) ||
null;

return (
<MemoizedLink
Expand Down
28 changes: 12 additions & 16 deletions web/src/app/chat/message/Messages.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ export const AIMessage = ({
const anchorCallback = useCallback(
(props: any) => (
<MemoizedAnchor
updatePresentingDocument={setPresentingDocument}
updatePresentingDocument={setPresentingDocument!}
docs={docs}
>
{props.children}
Expand Down Expand Up @@ -378,6 +378,7 @@ export const AIMessage = ({
onMessageSelection &&
otherMessagesCanSwitchTo &&
otherMessagesCanSwitchTo.length > 1;

return (
<div
id="onyx-ai-message"
Expand All @@ -402,21 +403,16 @@ export const AIMessage = ({
<div className="max-w-message-max break-words">
{!toolCall || toolCall.tool_name === SEARCH_TOOL_NAME ? (
<>
{query !== undefined &&
handleShowRetrieved !== undefined &&
!retrievalDisabled && (
<div className="mb-1">
<SearchSummary
index={index || 0}
query={query}
finished={toolCall?.tool_result != undefined}
hasDocs={hasDocs || false}
messageId={messageId}
handleShowRetrieved={handleShowRetrieved}
handleSearchQueryEdit={handleSearchQueryEdit}
/>
</div>
)}
{query !== undefined && !retrievalDisabled && (
<div className="mb-1">
<SearchSummary
index={index || 0}
query={query}
finished={toolCall?.tool_result != undefined}
handleSearchQueryEdit={handleSearchQueryEdit}
/>
</div>
)}
{handleForceSearch &&
content &&
query === undefined &&
Expand Down
6 changes: 0 additions & 6 deletions web/src/app/chat/message/SearchSummary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,12 @@ export function ShowHideDocsButton({
export function SearchSummary({
index,
query,
hasDocs,
finished,
messageId,
handleShowRetrieved,
handleSearchQueryEdit,
}: {
index: number;
finished: boolean;
query: string;
hasDocs: boolean;
messageId: number | null;
handleShowRetrieved: (messageId: number | null) => void;
handleSearchQueryEdit?: (query: string) => void;
}) {
const [isEditing, setIsEditing] = useState(false);
Expand Down
27 changes: 12 additions & 15 deletions web/src/app/chat/modal/ShareChatSessionModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ async function generateShareLink(chatSessionId: string) {
return null;
}

async function generateCloneLink(
async function generateSeedLink(
message?: string,
assistantId?: number,
modelOverride?: LlmOverride
Expand Down Expand Up @@ -115,7 +115,7 @@ export function ShareChatSessionModal({
{shareLink ? (
<div>
<Text>
This chat session is currently shared. Anyone at your
This chat session is currently shared. Anyone in your
organization can view the message history using the following
link:
</Text>
Expand Down Expand Up @@ -157,10 +157,8 @@ export function ShareChatSessionModal({
) : (
<div>
<Callout type="warning" title="Warning" className="mb-4">
Ensure that all content in the chat is safe to share with the
whole organization. The content of the retrieved documents
will not be visible, but the names of cited documents as well
as the AI and human messages will be visible.
Please make sure that all content in this chat is safe to
share with the whole organization.
</Callout>
<div className="flex w-full justify-between">
<Button
Expand Down Expand Up @@ -194,10 +192,9 @@ export function ShareChatSessionModal({

<Separator className="my-4" />
<div className="mb-4">
<Callout type="notice" title="Clone Chat">
Generate a link to clone this chat session with the current query.
This allows others to start a new chat with the same initial
message and settings.
<Callout type="notice" title="Seed New Chat">
Generate a link to a new chat session with the same settings as
this chat (including the assistant and model).
</Callout>
</div>
<div className="flex w-full justify-between">
Expand All @@ -207,18 +204,18 @@ export function ShareChatSessionModal({
// NOTE: for "insecure" non-https setup, the `navigator.clipboard.writeText` may fail
// as the browser may not allow the clipboard to be accessed.
try {
const cloneLink = await generateCloneLink(
const seedLink = await generateSeedLink(
message,
assistantId,
modelOverride
);
if (!cloneLink) {
if (!seedLink) {
setPopup({
message: "Failed to generate clone link",
message: "Failed to generate seed link",
type: "error",
});
} else {
navigator.clipboard.writeText(cloneLink);
navigator.clipboard.writeText(seedLink);
setPopup({
message: "Link copied to clipboard!",
type: "success",
Expand All @@ -232,7 +229,7 @@ export function ShareChatSessionModal({
size="sm"
variant="secondary"
>
Generate and Copy Clone Link
Generate and Copy Seed Link
</Button>
</div>
</>
Expand Down
Loading

0 comments on commit 9011b8a

Please sign in to comment.