Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleaner initial chat screen #2528

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 52 additions & 1 deletion backend/danswer/chat/personas.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,19 @@ personas:
icon_color: "#6FB1FF"
display_priority: 1
is_visible: true
starter_messages:
- name: "General Information"
description: "Ask about available information"
message: "Hello! I'm interested in learning more about the information available here. Could you give me an overview of the types of data or documents that might be accessible?"
- name: "Specific Topic Search"
description: "Find information on a particular subject"
message: "Hi there! I'm looking for information on a specific topic. How can I best search for detailed information about [insert your topic of interest]?"
- name: "Recent Updates"
description: "Inquire about latest additions"
message: "Hello! I'm curious about any recent updates or additions to the knowledge base. Can you tell me what new information has been added lately?"
- name: "Cross-referencing Information"
description: "Connect information from different sources"
message: "Hi! I'm working on a project that requires connecting information from multiple sources. How can I effectively cross-reference data across different documents or categories?"

- id: 1
name: "General"
Expand All @@ -57,6 +70,19 @@ personas:
icon_color: "#FF6F6F"
display_priority: 0
is_visible: true
starter_messages:
- name: "Open Discussion"
description: "Start an open-ended conversation"
message: "Hi there! I'm interested in having a discussion about recent advancements in artificial intelligence. What are some key developments you think are worth exploring?"
- name: "Problem Solving"
description: "Get help with a challenge"
message: "Hello! I'm facing a challenge with time management in my daily work. Do you have any strategies or techniques you could suggest to help me improve my productivity?"
- name: "Learn Something New"
description: "Explore a new topic"
message: "Hi! I've been hearing a lot about quantum computing lately, but I don't really understand it. Could you give me an introduction to the basic concepts?"
- name: "Creative Brainstorming"
description: "Generate creative ideas"
message: "Hello! I'm trying to come up with ideas for a new mobile app that helps people reduce their carbon footprint. Do you have any suggestions or innovative features we could consider?"

- id: 2
name: "Paraphrase"
Expand All @@ -73,7 +99,19 @@ personas:
icon_color: "#6FFF8D"
display_priority: 2
is_visible: false

starter_messages:
- name: "Document Search"
description: "Find specific information"
message: "Hi, I'm looking for information about our company's mission statement. Can you find the exact wording from our official documents?"
- name: "Policy Verification"
description: "Check company policies"
message: "Hello! I need to verify our company's policy on remote work. Can you find and quote the specific section that outlines this policy?"
- name: "Technical Specifications"
description: "Retrieve technical details"
message: "Hi there! I need the exact system requirements for our main software product. Can you locate and provide the full list from our technical documentation?"
- name: "Legal Clause Lookup"
description: "Find legal information"
message: "Hello! I'm trying to find the exact wording of our data privacy policy in our terms of service. Can you locate and quote the relevant clause?"

- id: 3
name: "Art"
Expand All @@ -91,3 +129,16 @@ personas:
image_generation: true
display_priority: 3
is_visible: true
starter_messages:
- name: "Landscape"
description: "Generate a landscape image"
message: "Create an image of a serene mountain lake at sunset, with snow-capped peaks reflected in the calm water and a small wooden cabin on the shore."
- name: "Character"
description: "Generate a character image"
message: "Generate an image of a futuristic robot with glowing blue eyes, sleek metallic body, and intricate circuitry visible through transparent panels on its chest and arms."
- name: "Abstract"
description: "Create an abstract image"
message: "Create an abstract image representing the concept of time, using swirling clock hands, fragmented hourglasses, and streaks of light to convey the passage of moments and eras."
- name: "Urban Scene"
description: "Generate an urban landscape"
message: "Generate an image of a bustling futuristic cityscape at night, with towering skyscrapers, flying vehicles, holographic advertisements, and a mix of neon and bioluminescent lighting."
4 changes: 4 additions & 0 deletions web/src/app/admin/assistants/AssistantEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1048,6 +1048,10 @@ export function AssistantEditor({
Starter Messages (Optional){" "}
</div>
</div>
<SubLabel>
Add pre-defined messages to help users get started. Only
the first 4 will be displayed.
</SubLabel>
<FieldArray
name="starter_messages"
render={(
Expand Down
159 changes: 91 additions & 68 deletions web/src/app/chat/ChatIntro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import { Persona } from "../admin/assistants/interfaces";
import { Divider } from "@tremor/react";
import { FiBookmark, FiInfo } from "react-icons/fi";
import { HoverPopup } from "@/components/HoverPopup";
import { AssistantIcon } from "@/components/assistants/AssistantIcon";
import { CustomTooltip } from "@/components/tooltip/CustomTooltip";
import { useState } from "react";
import { DisplayAssistantCard } from "@/components/assistants/AssistantCards";

export function ChatIntro({
availableSources,
Expand All @@ -12,86 +16,105 @@ export function ChatIntro({
availableSources: ValidSources[];
selectedPersona: Persona;
}) {
const [hoveredAssistant, setHoveredAssistant] = useState(false);
const availableSourceMetadata = getSourceMetadataForSources(availableSources);

return (
<>
<div className="flex justify-center items-center h-full">
<div className="mobile:w-[90%] mobile:px-4 w-message-xs 2xl:w-message-sm 3xl:w-message">
<div className="flex">
<div className="mx-auto">
<div className="m-auto text-3xl font-strong font-bold text-strong w-fit">
{selectedPersona?.name || "How can I help you today?"}
<div className="mobile:w-[90%] mobile:px-4 w-message-xs 2xl:w-message-sm 3xl:w-message">
<div className="flex">
<div className="mx-auto flex justify-center items-center flex-col gap-y-4">
<div className="m-auto text-3xl text-text-800 font-base font-semibold text-strong w-fit">
{selectedPersona?.name || "How can I help you today?"}
</div>
<div className="relative">
<div
onMouseEnter={() => setHoveredAssistant(true)}
onMouseLeave={() => setHoveredAssistant(false)}
className="p-4 cursor-pointer border-dashed rounded-full flex border border-border border-2 border-dashed"
style={{
borderStyle: "dashed",
borderWidth: "1.5px",
borderSpacing: "4px",
}}
>
<AssistantIcon
disableToolip
size={"large"}
assistant={selectedPersona}
/>
</div>
<div className="absolute z-10 left-full ml-4 w-[300px] top-0">
{hoveredAssistant && (
<DisplayAssistantCard selectedPersona={selectedPersona} />
)}
</div>
{selectedPersona && (
<div className="mt-1">{selectedPersona.description}</div>
)}
</div>
</div>
</div>

{selectedPersona && selectedPersona.num_chunks !== 0 && (
<>
<Divider />
<div>
{selectedPersona.document_sets.length > 0 && (
<div className="mt-2">
<p className="font-bold mb-1 mt-4 text-emphasis">
Knowledge Sets:{" "}
</p>
<div className="flex flex-wrap gap-2">
{selectedPersona.document_sets.map((documentSet) => (
<div key={documentSet.id} className="w-fit">
<HoverPopup
mainContent={
<span className="flex w-fit p-1 rounded border border-border text-xs font-medium cursor-default">
<div className="mr-1 my-auto">
<FiBookmark />
</div>
{documentSet.name}
</span>
}
popupContent={
<div className="flex py-1 w-96">
<FiInfo className="my-auto mr-2" />
<div className="text-sm">
{documentSet.description}
</div>
{selectedPersona && selectedPersona.num_chunks !== 0 && (
<>
<Divider />
<div>
{selectedPersona.document_sets.length > 0 && (
<div className="mt-2">
<p className="font-bold mb-1 mt-4 text-emphasis">
Knowledge Sets:{" "}
</p>
<div className="flex flex-wrap gap-2">
{selectedPersona.document_sets.map((documentSet) => (
<div key={documentSet.id} className="w-fit">
<HoverPopup
mainContent={
<span className="flex w-fit p-1 rounded border border-border text-xs font-medium cursor-default">
<div className="mr-1 my-auto">
<FiBookmark />
</div>
}
direction="top"
/>
</div>
))}
</div>
{documentSet.name}
</span>
}
popupContent={
<div className="flex py-1 w-96">
<FiInfo className="my-auto mr-2" />
<div className="text-sm">
{documentSet.description}
</div>
</div>
}
direction="top"
/>
</div>
))}
</div>
)}
</div>
)}

{availableSources.length > 0 && (
<div className="mt-1">
<p className="font-bold mb-1 mt-4 text-emphasis">
Connected Sources:{" "}
</p>
<div className={`flex flex-wrap gap-2`}>
{availableSourceMetadata.map((sourceMetadata) => (
<span
key={sourceMetadata.internalName}
className="flex w-fit p-1 rounded border border-border text-xs font-medium cursor-default"
>
<div className="mr-1 my-auto">
{sourceMetadata.icon({})}
</div>
<div className="my-auto">
{sourceMetadata.displayName}
</div>
</span>
))}
</div>
{availableSources.length > 0 && (
<div className="mt-1">
<p className="font-bold mb-1 mt-4 text-emphasis">
Connected Sources:{" "}
</p>
<div className={`flex flex-wrap gap-2`}>
{availableSourceMetadata.map((sourceMetadata) => (
<span
key={sourceMetadata.internalName}
className="flex w-fit p-1 rounded border border-border text-xs font-medium cursor-default"
>
<div className="mr-1 my-auto">
{sourceMetadata.icon({})}
</div>
<div className="my-auto">
{sourceMetadata.displayName}
</div>
</span>
))}
</div>
)}
</div>
</>
)}
</div>
</div>
)}
</div>
</>
)}
</div>
</>
);
Expand Down
85 changes: 41 additions & 44 deletions web/src/app/chat/ChatPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1925,7 +1925,7 @@ export function ChatPage({
{...getRootProps()}
>
<div
className={`w-full h-full flex flex-col overflow-y-auto include-scrollbar overflow-x-hidden relative`}
className={`w-full h-full flex flex-col overflow-y-auto include-scrollbar overflow-x-hidden relative`}
ref={scrollableDivRef}
>
{/* ChatBanner is a custom banner that displays a admin-specified message at
Expand All @@ -1935,11 +1935,47 @@ export function ChatPage({
!isFetchingChatMessages &&
currentSessionChatState == "input" &&
!loadingError && (
<ChatIntro
availableSources={finalAvailableSources}
selectedPersona={liveAssistant}
/>
<div className="h-full flex flex-col justify-center items-center">
<ChatIntro
availableSources={finalAvailableSources}
selectedPersona={liveAssistant}
/>
<div
key={-4}
className={`
mx-auto
px-4
w-full
max-w-[750px]
flex
flex-wrap
justify-center
mt-4
h-40
mb-6`}
>
{currentPersona?.starter_messages &&
currentPersona.starter_messages.length >
0 &&
currentPersona.starter_messages
.slice(0, 4)
.map((starterMessage, i) => (
<div key={i} className="w-1/4">
<StarterMessage
starterMessage={starterMessage}
onClick={() =>
onSubmit({
messageOverride:
starterMessage.message,
})
}
/>
</div>
))}
</div>
</div>
)}

<div
className={
"-ml-4 w-full mx-auto " +
Expand Down Expand Up @@ -2313,45 +2349,6 @@ export function ChatPage({
/>
</div>
)}
{currentPersona &&
currentPersona.starter_messages &&
currentPersona.starter_messages.length > 0 &&
selectedAssistant &&
messageHistory.length === 0 &&
!isFetchingChatMessages && (
<div
key={-4}
className={`
mx-auto
px-4
w-searchbar-xs
2xl:w-searchbar-sm
3xl:w-searchbar
grid
gap-4
grid-cols-1
grid-rows-1
mt-4
md:grid-cols-2
mb-6`}
>
{currentPersona.starter_messages.map(
(starterMessage, i) => (
<div key={i} className="w-full">
<StarterMessage
starterMessage={starterMessage}
onClick={() =>
onSubmit({
messageOverride:
starterMessage.message,
})
}
/>
</div>
)
)}
</div>
)}

{/* Some padding at the bottom so the search bar has space at the bottom to not cover the last message*/}
<div ref={endPaddingRef} className="h-[95px]" />
Expand Down
Loading
Loading